0100 ; 0110 ; 0120 ; The Mage's Magic Handler 0130 ; Written by Nathan Hartwell 0140 ; Version 2.20 0150 ; 0160 ; 0170 ; 0180 ; 0190 ;Designed for the PSI Upgrade 0200 ; 0210 ; 0220 ; 0230 ; 0240 .OPT NO LIST 0250 .OPT OBJ 0260 ;================================ 0270 ; EQUATES AND VARIABLES 0280 ;================================ 0290 ; 0300 ; GENERAL VALUE EQUATES 0310 ; 0320 ASYNC = $73 ;POKEY MODE 7 0330 PURE = $A0 ;PURE TONE VAL 0340 AUDVAL = $78 ;AUDCTL INIT VAL 0350 ; 0360 ; GENERAL ADDRESS EQUATES 0370 ; 0380 DOSVEC = $0A ;DOS RUN VECTOR 0390 DOSINI = $0C ;DOS INIT VECTOR 0400 RTCLOK = $12 ;JIFFIE COUNTER 0410 IRQVEC = $0216 0420 MEMLO = $02E7 ;SYSTEM MEMLO 0430 DVSTAT = $02EA ;DEVICE STATUS 0440 HATAB = $031A ;HANDLER TABLE 0450 AUDF1 = $D210 ;AUDIO FREQ 1 0460 AUDF2 = $D212 ;AUDIO FREQ 2 0470 AUDF3 = $D214 ;AUDIO FREQ 3 0480 AUDF4 = $D216 ;AUDIO FREQ 4 0490 AUDCTL = $D218 ;AUDIO CONTROL 0500 SERIN = $D21D ;SERIAL INPUT REG 0510 SEROUT = $D21D ;SERIAL OUTPUT REG 0520 IRQEN = $D21E ;INTERUPT ENABLE 0530 IRQST = $D21E ;INTERUPT STATUS 0540 SKCTL = $D21F ;POKEY MODE REG 0550 SKSTAT = $D21F ;POKEY STAT REG 0560 PCCTL = $D312 ;DTR LEAD 0570 PDCTL = $D313 ;I/O CONTROL 0580 PORTF = $D320 0590 ; 0600 ; IOCB RELATED EQUATES 0610 ; 0620 ICDNOZ = $21 ;DEVICE NUMBER 0630 ICCOMZ = $22 ;COMMAND BYTE 0640 ICAX1Z = $2A ;AUX 1 BYTE 0650 ICAX2Z = $2B ;AUX 2 BYTE 0660 ; 0670 ; VARIABLES 0680 ; 0690 *= $4000 ;VAR TABLE ORG 0700 RTS ;EXIT BACK TO DOS 0710 OIRQV .WORD 0 ;OLD IRQ VEC 0720 JIFFIE .BYTE 0 ;JIFFIE COUNT 0730 TMPCHR .BYTE 0 ;TEMP CHR STORAGE 0740 TDNFLG .BYTE 0 ;TRANS DONE FLAG 0750 BAUDRT .WORD 40 ;BAUD IN DEF 19.2K 0760 MODE .BYTE 0 ;OPEN MODE 0770 RDYOUT .BYTE 1 ;READY OUT FLAG 0780 CONFLG .BYTE 0 ;CONC MODE I/O FLAG 0790 SAVFLG .BYTE 0 ;VEC SAVED FLAG 0800 HNDMSK .BYTE 128 ;TYPE HANDSHAKING 0810 IOFLAG .BYTE 0 ;I/O ON/OFF FLAG 0820 HISTRY .BYTE 0 ;STATUS HISTRY 0830 POKMSK .BYTE 0 0840 ;================================ 0850 ; QUEUE HANDLER ROUTINE 0860 ;================================ 0870 ; 0880 ; INITIALIZE QUE 0890 ; 0900 QINIT 0910 LDA #0 ;INITIAL VALUE 0920 STA QHEAD ;INIT QUEUE HEAD 0930 STA QTAIL ;INIT QUEUE TAIL 0940 STA QLEN ;INIT QUEUE LEN 0950 RTS 0960 ; 0970 ; PUT BYTE IN QUEUE 0980 ; 0990 QPUT 1000 LDX QLEN ;CHECK QUEUE LEN 1010 INX ;IF LEN=FF THEN 1020 BNE QP0 ; QUE FULL RET 1030 RTS ;ELSE 1040 QP0 LDX QHEAD ; GET HEAD PSN 1050 STA QORG,X ; PUT BYTE 1060 INC QHEAD ; INC HEAD PSN 1070 INC QLEN ; INC QUEUE LEN 1080 RTS 1090 ; 1100 ; GET BYTE FROM QUEUE 1110 ; 1120 QGET 1130 LDX QLEN ;IF QUEUE EMPTY 1140 BNE QG0 ; RETURN 1150 RTS ;ELSE 1160 QG0 LDX QTAIL ; GET TAIL PSN 1170 LDA QORG,X ; GET BYTE 1180 INC QTAIL ; INC TAIL PSN 1190 DEC QLEN ; DEC QUEUE LEN 1200 RTS 1210 ; 1220 ; GET QUEUE STATUS 1230 ; 1240 QSTAT 1250 LDA QLEN ;GET QUEUE STAT 1260 RTS 1270 ; 1280 ; QUEUE VARIABLES & STORAGE 1290 ; 1300 QHEAD .BYTE 0 ;QUEUE HEAD PSN 1310 QTAIL .BYTE 0 ;QUEUE TAIL PSN 1320 QLEN .BYTE 0 ;QUEUE LENGTH 1330 ;================================ 1340 ; QUEUE HANDLER ROUTINE 1350 ;================================ 1360 ; 1370 ; INITIALIZE QUE 1380 ; 1390 OQINIT 1400 LDA #0 ;INITIAL VALUE 1410 STA OQHEAD ;INIT QUEUE HEAD 1420 STA OQTAIL ;INIT QUEUE TAIL 1430 STA OQLEN ;INIT QUEUE LEN 1440 RTS 1450 ; 1460 ; PUT BYTE IN QUEUE 1470 ; 1480 OQPUT 1490 LDX OQLEN ;CHECK QUEUE LEN 1500 INX ;IF LEN=FF THEN 1510 BNE OQP0 ; QUE FULL RET 1520 RTS ;ELSE 1530 OQP0 LDX OQHEAD ; GET HEAD PSN 1540 STA OQORG,X ; PUT BYTE 1550 INC OQHEAD ; INC HEAD PSN 1560 INC OQLEN ; INC QUEUE LEN 1570 RTS 1580 ; 1590 ; GET BYTE FROM QUEUE 1600 ; 1610 OQGET 1620 LDX OQLEN ;IF QUEUE EMPTY 1630 BNE OQG0 ; RETURN 1640 RTS ;ELSE 1650 OQG0 LDX OQTAIL ; GET TAIL PSN 1660 LDA OQORG,X ; GET BYTE 1670 INC OQTAIL ; INC TAIL PSN 1680 DEC OQLEN ; DEC QUEUE LEN 1690 RTS 1700 ; 1710 ; GET QUEUE STATUS 1720 ; 1730 OQSTAT 1740 LDA OQLEN ;GET QUEUE STAT 1750 RTS 1760 ; 1770 ; QUEUE VARIABLES & STORAGE 1780 ; 1790 OQHEAD .BYTE 0 ;QUEUE HEAD PSN 1800 OQTAIL .BYTE 0 ;QUEUE TAIL PSN 1810 OQLEN .BYTE 0 ;QUEUE LENGTH 1820 ; 1830 ; SAVE OLD DOSINI VECTOR 1840 ; 1850 START LDA #$60 1860 STA START 1870 LDA DOSINI ;OLD DOSINI LO 1880 STA HINIT+1 ;INDIR JUMP LO 1890 LDA DOSINI+1 ;OLD DOSINI HI 1900 STA HINIT+2 ;INDIR JUMP HI 1910 LDA #HINIT&$FF ;NEW DOSINI LO 1920 STA DOSINI ;STORE DOSINI LO 1930 LDA #HINIT/256 ;NEW DOSINI HI 1940 STA DOSINI+1 ;STORE DOSINI HI 1950 JMP SKIPIN 1960 ; 1970 ; SET UP NEW DOSINI & MEMLO 1980 ; 1990 HINIT JSR $FFFF ;IND OLD DOSINI 2000 SKIPIN LDA # MLOW ;GET NEW MEMLO HI 2030 STA MEMLO+1 ;SET NEW MEMLO HI 2040 LDA #0 ;FILE CLOSED VAL 2050 STA MODE ;SET MODE CLOSED 2060 STA CONFLG ;TURN OFF CONC I/O 2070 STA POKMSK 2080 ; 2090 ; INSTALL HANDLER 2100 ; 2110 FINDR LDX #0 ;START 1ST HAND 2120 LDY #16 ;# POS HANDLERS 2130 CHKR LDA HATAB,X ;GET HAND NAME 2140 BEQ FOUND ;IF NAME=0 OR 2150 CMP #'* ;IF NAME=* THEN 2160 BEQ FOUNDIT ; INSTALL NEW ONE 2170 INX ;ELSE INC 2180 INX ; INDEX 2190 INX ; BY 3 2200 DEY ;IF NOT FOUND 2210 BNE CHKR ; TRY AGAIN 2220 RTS 2230 FOUND LDA #'* ;INSTALL *: HAND 2240 STA HATAB,X ; 2250 LDA #RTAB&$FF ;INSTALL ADR LO 2260 STA HATAB+1,X ; 2270 LDA #RTAB/256 ;INSTALL ADR HI 2280 STA HATAB+2,X ; 2290 JSR SAVVEC 2300 RTS 2310 FOUNDIT RTS 2320 ;================================ 2330 ; DRIVER ADDRESS TABLE 2340 ;================================ 2350 ; 2360 ; DRIVER ADDRESS TABLE 2370 ; 2380 RTAB .WORD OPEN-1 ;OPEN ROUTINE 2390 .WORD CLOSE-1 ;CLOSE ROUTINE 2400 .WORD GET-1 ;GET ROUTINE 2410 .WORD PUT-1 ;PUT ROUTINE 2420 .WORD STAT-1 ;STATUS ROUTINE 2430 .WORD XIO-1 ;XIO ROUTINE 2440 JMP INIT 2450 ; 2460 ; OPEN ROUTINE 2470 ; 2480 OPEN LDA MODE ;CHECK MODE 2490 BEQ NOTOPN ;IF MODE<>0 THEN 2500 LDY #129 ; ALREADY OPEN ERR 2510 RTS ; RETURN 2520 NOTOPN LDA ICAX1Z ;GET TYPE OPEN 2530 STA MODE ;SAVE OPEN MODE 2540 JSR QINIT ;INIT QUEUE 2550 JSR OQINIT ;INIT OUT QUEUE 2560 LDY #0 ;OFF VALUE 2570 STY IOFLAG ;SET FLAG OFF 2580 STA DVSTAT+1 ;SET STATUS TO 0 2590 INY ;NO ERROR STATUS 2600 STY RDYOUT ;SET OUPUT RDY 2610 RTS 2620 ; 2630 ; CLOSE ROUTINE 2640 ; 2650 CLOSE LDA #0 ;FALSE FLAG VAL 2660 STA MODE ;RESET MODE VARIABLE 2670 STA CONFLG ;RESET CONCURENT FLG 2680 JSR IOOFF ;TURN CONC I/O OFF 2690 LDY #1 ;NO ERROR STATUS 2700 RTS 2710 ; 2720 ; GET ROUTINE 2730 ; 2740 GET LDA CONFLG ;IF CON I/O OFF THEN 2750 BEQ GETRET ; RETURN 2760 GWT JSR QSTAT ;CHECK QUEUE STAT 2770 BEQ GWT ;WAIT FOR DATA 2780 JSR QGET ;GET BYTE FROM QUEUE 2790 LDY #1 ;NO ERROR STATUS 2800 GETRET RTS 2810 ; 2820 ; PUT ROUTINE 2830 ; 2840 PUT LDY MODE ;CHECK OPEN MODE 2850 BNE PUTCHR ;IF NOT OPEN THEN 2860 LDY #133 ; SET ERROR # 2870 RTS ; RETURN 2880 PUTCHR CMP #155 2890 BNE PC1 2900 LDA #$0A 2910 JSR OQPUT 2920 JMP FLUSH 2930 PC1 STA TMPCHR 2940 LDA CONFLG ;CHECK CONC FLAG 2950 BNE PUTCON ;IF NOT SET THEN 2960 PUTREG LDA TMPCHR ;GET CHR 2970 JSR OQPUT ;PUT IN OUT QUEUE 2980 CHKOLN LDA OQLEN ; GET QUEUE LEN 2990 CMP #255 ; CHECK IF FULL 3000 BNE PRGRET ; IF FULL THEN 3010 FLUSH JSR SNDBLK ; SEND BLOCK 3020 PRGRET LDY #1 ;STATUS GOOD 3030 RTS ;RETURN 3040 PUTCON JSR PWAIT ; WAIT OUTPUT RDY 3050 JSR SNDOUT ; SEND CHARACTER 3060 LDY #1 ; STATUS GOOD 3070 RTS ; RETURN 3080 PWAIT LDA OQLEN ;CHECK QUEUE LEN 3090 CMP #255 ;IF FULL THEN 3100 BEQ PWAIT ; WAIT NOT FULL 3110 RTS ;RETURN 3120 SNDOUT SEI ;DISABLE IRQ 3130 LDA RDYOUT ;IF Q EMPTY THEN 3140 BNE SNDCHR ; SEND CHR ELSE 3150 LDA TMPCHR ;ELSE 3160 JSR OQPUT ; PUT IN QUEUE 3170 CLI ;ENABLE IRQ 3180 RTS 3190 SNDCHR LDA TMPCHR 3200 STA SEROUT ;SEND CHARACTER 3210 LDA #0 ;FLAG FALSE 3220 STA RDYOUT ;OUTPUT NOT READY 3230 CLI ;ENABLE IRQ 3240 RTS ; 3250 WTHAND LDA HNDMSK ;GET HNDSHK REQ 3260 BEQ WTHRET ;IF HNDS REQ THEN 3270 CHKST JSR STAT ; UPDATE STATUS 3280 LDA HNDMSK ; GET HNDS MASK 3290 AND DVSTAT+1 ; CHECK " STATUS 3300 CMP HNDMSK ;IF HANDS NOT GOOD 3310 BNE CHKST ; TRY AGAIN 3320 RTS ;RETURN 3330 WTHRET JSR IOON ;TURN IOON 3340 RTS ;RETURN 3350 ; SEND BLOCK 3360 SNDBLK LDA OQLEN ;GET OUT Q LEN 3370 BEQ SBRET ;IF LEN>0 THEN 3380 JSR WTHAND ; WAIT HNDSHK OK 3390 JSR IOON 3400 LDA #0 ; NOT READY VAL 3410 STA RDYOUT ; RESET FLAG 3420 STA TDNFLG ; RESET FLAG 3430 JSR OQGET ; GET CHR 3440 STA SEROUT ; SEND CHR 3450 WSB1 LDA RDYOUT ; WAIT UNTIL BYTE 3460 BEQ WSB1 ; IN SHIFT REG 3470 LDA POKMSK 3480 ORA #$08 ; SET DON INT BIT 3490 STA POKMSK 3500 STA IRQEN ; SAVE POKEY REG 3510 WSB2 LDA TDNFLG ; WAIT UNTIL 3520 BEQ WSB2 ; SHIFT REG CLEAR 3530 JMP SNDBLK ; SEND NEXT CHR 3540 SBRET JSR IOOFF ; TURN IO OFF 3550 RTS ;RETURN 3560 ; 3570 ; STAT ROUTINE 3580 ; 3590 STAT LDA CONFLG ;CHECK MODE 3600 BEQ CHKCLK ;IF CONC MODE THEN 3610 MOVLEN LDA QLEN ; GET QUEUE LEN 3620 STA DVSTAT+1 ; SAVE LEN LO 3630 LDA #0 ; GET ZERO VAL 3640 STA DVSTAT+2 ; SAVE LEN HI 3650 LDA OQLEN ; GET OUT Q LEN 3660 STA DVSTAT+3 ; SAVE LENGTH 3670 JMP STARET ;ELSE 3680 CHKCLK LDA RTCLOK+2 ; REAL TIME CLOCK 3690 STA JIFFIE ; SAVE JIF COUNT 3700 LDA PORTF ; GET INTER STAT 3710 EOR #$08 3720 STA DVSTAT+1 ; SAVE STATUS 3730 LDA RTCLOK+2 ; CHECK JIFFIES 3740 CMP JIFFIE ; IF CHANGE THEN 3750 BNE CHKCLK ; REPEAT AGAIN 3760 STARET LDA MODE ;ENDIF 3770 STA ICAX1Z ;RESTORE OPEN TYPE 3780 LDY #0 ;NO ERROR STATUS 3790 STY DVSTAT ;SAVE DEVICE STAT 3800 INY ;SET Y TO 1 3810 RTS 3820 ; 3830 ; XIO ROUTINE 3840 ; 3850 XIO LDA CONFLG ;IF CONC=ON THEN 3860 BNE XIORET ; RETURN 3870 LDA ICCOMZ ;GET COMMAND NO. 3880 CMP #32 ;IF CMD=32 THEN 3890 BNE XI0 ; EXEC XIO32 3900 JSR XIO32 ; FORCE SHORT BLK 3910 XI0 CMP #34 ;IF CMD=34 THEN 3920 BNE XI1 ; EXEC XIO34 3930 JSR XIO34 ; DTR/RTS/XMT 3940 XI1 CMP #36 ;IF CMD=36 THEN 3950 BNE XI3 ; EXEC XIO36 3960 JSR XIO36 ; SET BAUD RATE 3970 XI3 CMP #40 ;IF CMD=40 THEN 3980 BNE XIORET ; EXEC XIO40 3990 JSR XIO40 ; START CONC I/O 4000 XIORET LDA MODE ;GET OPEN TYPE 4010 STA ICAX1Z ;RESTORE OPEN TYPE 4020 LDY #1 ;NO ERROR STATUS 4030 RTS 4040 ; 4050 ; INIT ROUTINE 4060 ; 4070 INIT LDY #1 4080 RTS 4090 ;================================ 4100 ; SUBROUTINES 4110 ;================================ 4120 ; 4130 ; FORCE SHORT BLOCK 4140 ; 4150 XIO32 PHA ;SAVE CMD BYTE 4160 JSR SNDBLK ;SEND BLOCK 4170 PLA ;RESTORE CMD BYTE 4180 RTS 4190 ; 4200 ; DTR/RTS/XMT 4210 ; 4220 XIO34 PHA ;SAVE CMD BYTE 4230 LDA ICAX1Z ;GET CONTROL CODE 4240 AND #$C0 ;IGNORE RTS/XMT 4250 CMP #$C0 ;CHECK FOR ON 4260 BNE DTROFF ;NO, GO TO OFF 4270 LDA #$3C ;LOAD VALUE FOR ON 4280 STA PCCTL ;GO STORE IT 4290 BNE XMT0 4300 DTROFF CMP #$80 4310 BNE XMT0 4320 LDA #$34 ;LOAD VALUE FOR OFF 4330 STA PCCTL ;STORE IT 4340 XMT0 LDA ICAX1Z 4350 AND #$03 4360 CMP #$03 4370 BNE XMTOFF 4380 LDA #ASYNC 4390 ORA #$80 4400 STA SKCTL 4410 BNE X34R 4420 XMTOFF CMP #$02 4430 BNE X34R 4440 LDA #ASYNC 4450 STA SKCTL 4460 X34R PLA 4470 RTS 4480 ; 4490 ; SET BAUD RATE, STOP BITS, & HANDSHAK 4500 ; 4510 XIO36 PHA ;SAVE CMD BYTE 4520 LDA ICAX1Z ;GET BAUD OFFSET 4530 AND #$0F ;ASSURE GOOD VAL 4540 ASL A ;MULT BY 2 4550 TAY ;SET INDEX 4560 LDA BAUD,Y ;GET BAUD LO 4570 STA BAUDRT ;SET BAUD LO 4580 LDA BAUD+1,Y ;GET BAUD HI 4590 STA BAUDRT+1 ;SET BAUD HI 4600 LDA ICAX2Z ;GET AUX2 TYP HANDS 4610 AND #$07 ;MASK SIG BITS 4620 TAY 4630 LDA HSMTAB,Y 4640 STA HNDMSK ;SAVE HNDSHK MASK 4650 PLA ;RESTORE CMD BYTE 4660 RTS 4670 HSMTAB .BYTE $00,$08,$10,$18 4680 .BYTE $80,$88,$90,$98 4690 ; 4700 ; DO NOTHING 4710 ; 4720 ; XIO38 RTS ;NULL XIO CALL 4730 ; 4740 ; START CONCURRENT MODE I/O 4750 ; 4760 XIO40 PHA ;SAVE CMD BYTE 4770 LDA MODE ;CHECK OPEN MODE 4780 BNE CHKMOD ;IF NOT OPEN THEN 4790 LDY #133 ; NOT OPEN ERROR 4800 RTS ; RETURN 4810 CHKMOD CMP #8 ;IF MODE=8 THEN 4820 BNE OPENOK ; CONC NOT ALLOWED 4830 LDY #131 ; OUTPUT ONLY ERR 4840 RTS ; RETURN 4850 OPENOK LDA #1 ;TRUE VAL 4860 STA CONFLG ;SET CONC FLAG 4870 JSR QINIT ;CLEAR INPUT Q 4880 JSR OQINIT ;CLEAR INPUT Q 4890 JSR IOON ;START CONC I/O 4900 PLA ;RESTORE CMD BYTE 4910 RTS 4920 ; 4930 ; SET UP BAUD RATE 4940 ; 4950 STBAUD LDA BAUDRT ; 4960 STA AUDF1 ;SET BAUD LO 4970 STA AUDF3 ;SET BAUD LO 4980 LDA BAUDRT+1 ; 4990 STA AUDF2 ;SET BAUD HI 5000 STA AUDF4 ;SET BAUD HI 5010 RTS 5020 ; 5030 ; TURN RS232 I/O ON 5040 ; 5050 IOON LDA IOFLAG ;IF I/O ON THEN 5060 BNE IONRET ; RETURN 5070 JSR SETPOK ;SETUP POKEY 5080 JSR STBAUD ;SETUP BAUD RATE 5090 JSR ENINTR ;ENABLE INTRPTS 5100 LDA #$3C 5110 STA PDCTL 5120 LDY #1 ;ON VALUE 5130 STY IOFLAG ;INDICATE I/O ON 5140 WTON INY ;WAIT TRANSITION 5150 BNE WTON 5160 IONRET RTS 5170 ; 5180 ; TURN RS232 I/O OFF 5190 ; 5200 IOOFF LDA IOFLAG ;CHECK IF I/O OFF 5210 BEQ IOFRET ;IF OFF RETURN 5220 LDA #0 ;OFF VALUE 5230 STA IOFLAG ;SET IOFLAG OFF 5240 LDA #$34 5250 STA PDCTL 5260 JSR DSINTR ;DISABLE INTRPTS 5270 IOFRET RTS 5280 ; 5290 ; SETUP POKEY 5300 ; 5310 SETPOK LDA #AUDVAL ;AUDCTL VALUE 5320 STA AUDCTL ;SET AUDCTL 5330 LDA #ASYNC ;POKEY MODE 7 5340 STA SKCTL ;SET MODE REG 5350 RTS 5360 ; 5370 ; SAVE IMIRQ VEC 5380 ; 5390 IMIRQV .WORD 0 5400 SAVVEC LDA IRQVEC 5410 STA IMIRQV 5420 STA OIRQV 5430 LDA IRQVEC+1 5440 STA IMIRQV+1 5450 STA OIRQV+1 5460 RTS 5470 ; 5480 ; ENABLE INTERUPTS 5490 ; 5500 ENINTR SEI ;GET INTR SHADOW 5510 LDA POKMSK 5520 ORA #$30 5530 STA POKMSK 5540 STA IRQEN ;ENABLE INTRPTS 5550 LDA # DOIRQ+1 5580 STA IRQVEC+1 5590 CLI 5600 RTS 5610 ; 5620 ; DISABLE INTERUPTS 5630 ; 5640 DSINTR SEI ;GET INTR SHADOW 5650 LDA POKMSK 5660 AND #$C7 5670 STA POKMSK 5680 STA IRQEN ;DISABLE INTRPTS 5690 LDA IMIRQV 5700 STA IRQVEC 5710 LDA IMIRQV+1 5720 STA IRQVEC+1 5730 CLI 5740 RTS 5750 ; 5760 ; NEW IMIRQ ROUTINE 5770 ; 5780 IRQT0 .BYTE $20,$10,$08 5790 IRQT1 .WORD INPUT 5800 .WORD OUTPUT 5810 .WORD TDONE 5820 TJMPVEC .WORD 0 5830 DOIRQ PHA 5840 TXA 5850 PHA 5860 LDX #2 5870 D0 LDA IRQT0,X 5880 CPX #2 5890 BNE D1 5900 AND POKMSK 5910 BEQ D2 5920 D1 BIT IRQST 5930 BEQ D3 5940 D2 DEX 5950 BPL D0 5960 JMP XITIRQ 5970 D3 EOR #$FF 5980 STA IRQEN 5990 LDA POKMSK 6000 STA IRQEN 6010 TXA 6020 ASL A 6030 TAX 6040 LDA IRQT1,X 6050 STA TJMPVEC 6060 LDA IRQT1+1,X 6070 STA TJMPVEC+1 6080 PLA 6090 TAX 6100 JMP (TJMPVEC) 6110 XITIRQ PLA 6120 TAX 6130 PLA 6140 JMP (OIRQV) 6150 ;================================ 6160 ; INTERUPT ROUTINES 6170 ;================================ 6180 ; 6190 ; INPUT INTERUPT ROUTINE 6200 ; 6210 INPUT TYA ;SAVE Y REG 6220 PHA ; 6230 TXA ;SAVE X REG 6240 PHA ; 6250 LDA SERIN ;GET INPUT BYTE 6260 JSR QPUT ;PUT CHR IN QUEUE 6270 PLA ; 6280 TAX ;RESTORE X REG 6290 PLA ; 6300 TAY ;RESTORE Y REG 6310 PLA ; 6320 RTI 6330 ; 6340 ; OUTPUT INTERUPT ROUTINE 6350 ; 6360 OUTPUT TYA ;SAVE Y REG 6370 PHA ; 6380 TXA ;SAVE X REG 6390 PHA ; 6400 LDA OQLEN ;GET QUEUE LEN 6410 BEQ SETRDY ;IF NOT EMPTY THEN 6420 LDA CONFLG ; IF BLOCK MODE 6430 BEQ SETRDY ; SET READY 6440 JSR OQGET ; GET BYTE 6450 STA SEROUT ; SEND BYTE 6460 JMP OUTRET ;ELSE 6470 SETRDY LDA #1 ; GET TRUE VALE 6480 STA RDYOUT ; SET OUTRDY FLAG 6490 OUTRET PLA ; 6500 TAX ;RESTORE X REG 6510 PLA ; 6520 TAY ;RESTORE Y REG 6530 PLA ; 6540 RTI 6550 ; 6560 ; TRANS. DONE INTERUPT ROUTINE 6570 ; 6580 TDONE LDA #1 ;TRUE VAL 6590 STA TDNFLG ;SET DONE FLAG 6600 LDA POKMSK 6610 AND #$F7 6620 STA POKMSK 6630 STA IRQEN ;SAVE TO POKEY REG 6640 PLA 6650 RTI 6660 ;================================ 6670 ; DATA TABLES 6680 ;================================ 6690 ; 6700 ; BAUD RATE TABLE 6710 ; 6720 BAUD .WORD 2976 ;0) 300 BAUD 6730 .WORD 23 ;1) MIDI 6740 .WORD 16 ;2) 38400 BAUD 6750 .WORD 9 ;3) 57600 BAUD 6760 .WORD 1 ;4) 115200 BAUD 6770 .WORD 8128 ;5) 110 BAUD 6780 .WORD 6646 ;6) 134.5 BAUD 6790 .WORD 5958 ;7) 150 BAUD 6800 .WORD 2976 ;8) 300 BAUD 6810 .WORD 1484 ;9) 600 BAUD 6820 .WORD 739 ;10) 1200 BAUD 6830 .WORD 490 ;11) 1800 BAUD 6840 .WORD 366 ;12) 2400 BAUD 6850 .WORD 179 ;13) 4800 BAUD 6860 .WORD 86 ;14) 9600 BAUD 6870 .WORD 40 ;15) 19200 BAUD 6880 ; 6890 ; SETUP MEMLO & START ON LOAD 6900 ; 6910 QORG *= *+256 6920 OQORG *= *+256 6930 MLOW = * ;NEW MEMLO 6940 *= $02E2 ;INIT ADR VEC 6950 .WORD START