Classic Computer Magazine Archive PROGRAM LISTING: 83-07/POKEYINT.ASM


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 


Back to previous page