20 ;ATARI EQUATES›30 CIOV = $E456 CIO ENTRY POINT›40 FASC = $D8E6 FP-->ASC CONV RTN›50 IFP = $D9AA INT-->FP CONV RTN›60 FMOVE = $DDB6 FP MOVE RTN›70 FLDOR = $DD89 FP RTN›80 FDIV = $DB28 FP DIVIDE RTN›90 FMUL = $DADB FP MULT RTN›0100 ;IOCB COMMANDS›0110 OPEN = 3›0120 PUTREC = 9›0130 PUTCHR = $0B›0140 CLOSE = $0C›0150 POKMSK = $10›0160 ;DEVICE NAMES›0170 PRINTR = 'P›0180 CR = $9B CARRIAGE RETURN›0190 CLS = $7D CLEAR SCREEN›0200 ;RAM ASSIGNMENTS›0210 RTCLOCK = $12 3 BYTE CLOCK›0220 FR0 = $D4 FP REG ZERO›0230 INBUFF = $F3 INBUFFER FOR FP›0240 INTABS = $0200 RAM INTERUPT VECTS›0250 VTIMR2 = $0212 POKEY TMR INT VECT›0260 ATACHR = $02FB ASCII KEY›0270 CH = $02FC KEY›0280 IOCB = $0340 IOCBS›0290 ICHID = $0340 HANDLER INDEX NO.›0300 ICDNO = $0341 DEVICE NUM›0310 ICCOM = $0342 COMMAND CODE›0320 ICSTA = $0343 STATUS›0330 ICBAL = $0344 BUFFER LOW ADR›0340 ICBAH = $0345 HI ADR›0350 ICPTL = $0346 PUT BYTE RTN-1›0360 ICPTH = $0347 "›0370 ICBLL = $0348 BUFFER LEN LOW›0380 ICBLH = $0349 BUFFER LEN HI›0390 ICAX1 = $034A AUX INFO 1›0400 LBUFF = $0580 FP BUFFER›0410 ; OTHER EQUATES›0420 LOW = $FF USE TO GET LOW ADDR›0430 HIGH = $0100 USE TO GET HIGH ADDR›0440 *= $02E0›0450 EP .WORD LOAD›0460 ;START THE PROGRAM›0470 LOAD = $6000›0480 *= LOAD›0810 LDA #0 INITIAL SETTING›0820 STA $D202 FOR AUDF2›0830 M10 JSR CNT GO COUNT INTERRUPTS›0840 JSR CONV CONVERT RESULTS›0850 INC AUDF1 GET NEXT HIER NUMBER›0860 INC AUDF1 ADD ONE TO IT›0870 BNE M10 CONT WITH THIS CTL›0880 INC AUDF2 ADD ONE TO HI BYTE›0890 INC AUDF2 ADD ONE TO HI BYTE›0900 BEQ M15 DONE WITH ALL OF THEM›0910 LDA AUDF2 GET NEW VALUE›0920 STA $D202 STORE NEW FREQENCY›0930 JMP M10 AND CONTINUE›0940 M15›0950 ;GOTO 16K CLOCK TIMING›0960 LDA #'1›0970 STA AUDCTM+1 SAVE MSG›0980 LDA #$11 AUDCTL SETTING›0990 STA AUDCTLS SAVE IN MEMORY›1000 LDY #0›1010 M20 LDA FIN16K,Y GET BYTE›1020 STA FIN,Y SAVE IT›1030 INY ›1040 CPY #6 ?ALL BYTES YET›1050 BNE M20 NO›1060 LDA AUDFI START COUNT›1070 STA AUDF1 SAVE VALUE›1080 LDA #0 INITIAL›1090 STA $D202 VALUE FOR AUDF2›1100 M30 JSR CNT GO COUNT INTERRUPTS›1110 JSR CONV CONVERT RESULTS›1120 INC AUDF1 GET NEXT HIER NUMBER›1130 INC AUDF1 ADD ONE TO IT›1140 BNE M30 CONTINUE ALL SETTINGS›1150 INC AUDF2 ADD ONE TO HI BYTE›1160 INC AUDF2 ADD ONE TO HI BYTE›1170 BEQ M35 DONE WITH ALL OF THEM›1180 LDA AUDF2 GET NEW VALUE›1190 STA $D202 STORE NEW FREQENCY›1200 JMP M30 AND CONTINUE›1210 M35›1220 EOJ JMP EOJ FINISHED›1230 ;SUBROUTINE TO OUTPUT MSG›1240 ; ENTRY: A=LEN, X=HI, Y=LO›1250 ; EXIT: NO INFO›1260 MSGOUT STX MGOUT1+2 SAVE HIGH›1270 STY MGOUT1+1 SAVE LOW›1280 STA MGOUT2+1 SAVE LENGTH›1290 LDX #0›1300 MSA1 STX SAVCNT›1310 MGOUT1 LDA $1000,X GET CHAR›1320 PHA SAVE A›1330 LDX #$00 IOCB #0›1340 LDA #PUTCHR›1350 STA ICCOM,X SAY PUT CHR›1352 LDA #0›1354 STA ICBLL,X›1356 STA ICBLH,X›1360 PLA RESTORE A›1370 JSR CIOV GO PUT TO SCREEN›1460 MGO2 LDX SAVCNT›1470 INX ›1480 MGOUT2 CPX #0 COMPARE LENGTH›1490 BNE MSA1›1500 RTS ›1520 SAVCNT .BYTE 0›1550 AUDF2 .BYTE $00›1552 AUDFI .BYTE $30 INIT AUDF1 SET›1560 AUDF1 .BYTE $30 AUDF1 SETTING›1570 AUDCTLS .BYTE $10 AUDCTL SETTING›1580 ;FIN = 63.9210 KHZ›1590 FIN64K .BYTE $43,$63,$92,$10,0,0›1600 ;FIN = 15.6999 KHZ›1610 FIN16K .BYTE $43,$15,$69,$69,0,0›1620 ;64K TO START›1630 FIN .BYTE $43,$63,$92,$10,0,0›1640 AUDMSG .BYTE "AUDCTL="›1650 AUDCTM .BYTE "10"," "›1660 .BYTE "AUDF="›1670 AUDFM .BYTE 0,0,0,0," "›1680 IFREQ .BYTE "IFREQ="›1690 IFREQM .BYTE " ",CR,CR›1720 MSGE = *-AUDMSG LENGTH OF MSG›1730 ;INTERRUPT TIMER SUBROUTINE›1740 CNT LDA #EXIT&LOW SAVE›1750 STA VTIMR2 VECTOR›1760 LDA #EXIT/HIGH ADDRESS›1770 STA VTIMR2+1 FOR INTERRUPT›1780 LDA #$A8›1790 STA $D203 SET VOLUME›1800 LDA #0 ZERO THE REAL TIME CLOCK›1810 STA RTCLOCK›1820 STA RTCLOCK+1›1830 STA RTCLOCK+2›1840 STA POKE1 ZERO COUNTERS›1850 STA POKE1+1›1860 STA POKE1+2›1870 LDA POKMSK GET IRQ MASK›1880 ORA #$02 ENABLE TIMER 2›1890 STA POKMSK SAVE MASK›1900 STA $D20E TELL HARDWARE›1910 LDA AUDCTLS GET AUDCTL SETTING›1920 STA $D208 SET AUDCTL›1930 LDA AUDF1 GET SETTING TO USE›1940 STA $D200 SET AUDF1 TO VALUE›1950 STA $D209 START TIMER›1960 ;WAIT FOR 2 REAL TIME SECONDS›1970 ;SO IT WILL BE EASY TO GET THE›1980 ;NUMBER OF INTERRUPTS PER SEC›1990 ;BY SHIFTING RIGHT 1 BIT. THE›2000 ;VALUE OF RTCLOCK IS 120 AFTER›2010 ;2 SECONDS REAL TIME.›2020 M1 LDA RTCLOCK+2›2030 CMP #120 ?WAS IT 2 SEC›2040 BNE M1›2050 INC SW TURN ON SWITCH TO STOP›2060 M2 LDA SW WAIT TILL ZERO›2070 BNE M2 TO KNOW IT FINISHED›2080 RTS RETURN NOW›2090 ;POKEY INTERRUPT EXIT GETS›2100 ;CONTROL WHEN AUDIO REGISTER›2110 ;COUNTS DOWN TO ZERO. THE›2120 ;INTERRUPT IS RESTARTED UNTIL›2130 ;2 SEC HAVE TRANSPIRED AND WE›2140 ;ARE STOPPED COLD.›2150 EXIT INC POKE1›2160 BNE EX1›2170 INC POKE1+1›2180 BNE EX1›2190 INC POKE1+2›2200 EX1 LDA SW›2210 BNE EX3›2220 STA $D209 START IT UP AGAIN›2230 PLA ›2240 RTI ›2250 EX3 LDA POKMSK›2260 AND #$FD TURN OFF POKEY TIMER 2›2270 STA POKMSK›2280 STA $D20E›2290 DEC SW RESET TO ZERO›2300 PLA ›2310 RTI ›2320 ;HIGH-MED-LOW ORDER›2330 POKE1 .BYTE 0,0,0›2340 SW .BYTE 0›2350 NBITS .BYTE 0 WORK BYTE›2360 LENGTH .BYTE 3 FOR HEX CONV RTN›2370 PTR = $80 FOR HEX CONV RTN›2380 ;CONVERT INTERRUPT COUNT DATA›2390 ;TO ASCII AND PUT TO SCREEN›2410 CONV LDA AUDF2 GET VALUE›2420 TAX SAVE A›2430 AND #$F0 HIGH NIBBLE›2440 LSR A›2450 LSR A›2460 LSR A›2470 LSR A SHIFT DOWN›2480 JSR NASCII CONVERT IT›2490 STA AUDFM SAVE IT›2500 TXA RESTORE A›2510 AND #$0F GET LOW NIBBLE›2520 JSR NASCII CONVERT TO HEX›2530 STA AUDFM+1 SAVE IT›2540 LDA AUDF1 GET VALUE›2550 TAX SAVE A›2560 AND #$F0 HIGH NIBBLE›2570 LSR A›2580 LSR A›2590 LSR A›2600 LSR A SHIFT DOWN›2610 JSR NASCII CONVERT IT›2620 STA AUDFM+2 SAVE IT›2630 TXA RESTORE A›2640 AND #$0F GET LOW NIBBLE›2650 JSR NASCII CONVERT TO HEX›2660 STA AUDFM+3 SAVE IT›2670 LDY #9 LOOP COUNT›2680 LDA #' GET A BLANK›2690 CONV1 STA IFREQM,Y CLEAR›2710 DEY ›2720 BNE CONV1 CONTINUE›2730 ;DIVIDE INTR COUNT BY 2 TO GET›2740 ;COUNT OF INTERRUPTS PER SEC›2750 ;DO THIS BY USING A 1 BIT SHIFT›2760 LDA #1 SAY 1 BIT›2770 STA NBITS SAVE IT›2780 LDA #POKE1&LOW›2790 STA PTR›2800 LDA #POKE1/HIGH›2810 STA PTR+1 SAVE ADDR OF FIELD›2820 LDA PTR›2830 BNE MPLSR1›2840 DEC PTR+1›2850 MPLSR1 DEC PTR›2860 LSRLP LDY LENGTH›2870 CLC ›2880 LOOP LDA (PTR),Y GET A BYTE›2890 ROR A›2900 STA (PTR),Y›2910 DEY ›2920 BNE LOOP DO ALL BYTES›2930 DEC NBITS›2940 BNE LSRLP DO ALL BITS›2950 ;CONVERT ANSWER TO FP›2960 LDA POKE1›2970 STA FR0›2980 LDA POKE1+1›2990 STA FR0+1›3000 JSR IFP INT-->FP CONVERSION›3010 JSR FASC FP-->ASC CONVERSION›3020 LDY #$FF START INDEX VALUE›3030 FBI INY ›3040 LDA (INBUFF),Y GET ASCII›3050 STA IFREQM,Y SAVE IT›3060 BPL FBI CONTINUE›3070 AND #$7F FIX HI BIT›3080 STA IFREQM,Y RESTORE LAST ONE›3370 LDA #MSGE LENGTH OF MESSAGE›3380 LDY #AUDMSG&LOW›3390 LDX #AUDMSG/HIGH›3400 JSR MSGOUT PUT IT OUT›3410 RTS ›3420 ;BIN-->ASCII HEX SUBRTN›3430 NASCII CMP #10›3440 BCC NAS1›3450 CLC ›3460 ADC #7›3470 NAS1 ADC #'0›3480 RTS ››