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