;******************************************************** ;* * ;* INTERRUPT SERVICE ROUTINES FOR KEYBOARD * ;* INPUT AND REAL-TIME CLOCK FUNCTIONS * ;* * ;******************************************************** ; ; ; ; KBDST: LD A,(FIFCNT) ;GET INPUT FIFO BYTECOUNT OR A ;TEST IF EQUAL ZERO RET Z ;EXIT WITH A=0 IF QUEUE IS EMPTY LD A,255 RET ;ELSE SET A=255 TO INDICATE DATA READY ; ; ; KBDIN: CALL KBDST JR Z,KBDIN ;LOOP UNTIL KEYBOARD INPUT READY PUSH HL CALL REMOVE ;GET CHARACTER FROM INPUT QUEUE POP HL RET ; ; ; ; ; STASH: LD C,A ;PUT CHARACTER IN C LD A,(FIFSIZ) AND 00111111B LD B,A ;PUT MAX FIFO SIZE IN B LD HL,FIFCNT ;BUMP FIFO CHARACTER COUNT LD A,(HL) INC A CP B RET NC ;EXIT NOW IF FIFO IS FULL LD (HL),A ; ELSE INCREMENT FIFO COUNT LD HL,FIFIN ;POINT HL TO FIFO INPUT OFFSET CALL INDEX LD (HL),C ;STORE CHARACTER IN FIFO @ HL RET ; ; ; ; REMOVE: LD HL,FIFCNT DEC (HL) LD HL,FIFOUT ;POINT HL TO FIFO OUTPUT OFFSET INDEX: LD A,(HL) INC A AND 00111111B ;INCREMENT FIFO POINTER LD (HL),A ; MODULO 64 AND REPLACE LD HL,FIFO Š ADD A,L ;INDEX INTO FIFO BY OFFSET IN A LD L,A LD A,H ADC A,0 ;CARRY ADD OUT TO 16 BITS LD H,A LD A,(HL) RET ; ; ; ; ; ; ; -- INTERRUPT SERVICE ROUTINE FOR PARALLEL KEYBOARD -- ; KEYSRV: LD (IRQSAV),SP ;SAVE USER STACK POINTER AND LD SP,IRQSTK ; SWITCH TO LOCAL STACK PUSH HL PUSH DE PUSH BC PUSH AF ;SAVE MACHINE STATE IN A,(KBD) ;READ KEYBOARD INPUT PORT BIT 7,A JR Z,KEYSRV1 ;USE TABEL IF BIT 7 IS SET LD BC,KEYTABL ;TABLE LENGTH LD HL,KEYTAB ;CONVERSION TABEL CPIR LD A,(HL) KEYSRV1:LD HL,(KBDVEC) CALL DISPATCH POP AF POP BC POP DE POP HL LD SP,(IRQSAV) RETI: EI ;RE-ENABLE INTERRUPTS AND RETURN RETI ; ; ; ; -- INTERRUPT SERVICE ROUTINE FOR ONE MILLISECOND TIMER -- ; MILLISEC: LD (IRQSAV),SP ;SAVE USER STACK POINTER AND LD SP,IRQSTK ; SWITCH TO LOCAL STACK PUSH HL PUSH DE PUSH BC PUSH AF LD HL,(STPVEC) CALL DISPATCH ;CALL MILLISECOND INTERRUPT ROUTINE POP AF POP BC POP DE POP HL Š LD SP,(IRQSAV) EI RETI ; ; ; DISPATCH: JP (HL) ; ; ; ; -- INTERRUPT SERVICE ROUTINE FOR CLOCK TICK INTERRUPT -- ; TIMER: LD (IRQSAV),SP ;SAVE USER STACK POINTER AND LD SP,IRQSTK ; SWITCH TO LOCAL STACK PUSH HL PUSH DE PUSH BC PUSH AF LD HL,(TICKS) INC HL ;BUMP FREE RUNNING CLOCK TICK COUNTER LD (TICKS),HL LD HL,(TIKVEC) CALL DISPATCH ;DO EXTRA CLOCK TICK ACTIVITY LD HL,TIKCNT DEC (HL) ;DECREMENT CLOCK TICK PRE-SCALER JR NZ,TIMER2 ;JUMP IF CURRENT SECOND NOT PASSED LD A,(NTICKS) ;ELSE RELOAD TICK COUNT AND DO LD (HL),A ; VARIOUS ONCE-A-SECOND THINGS CALL CLOCK ;UPDATE TIME-OF-DAY CLOCK CALL DISKTEST ;DO BACKGROUND DISK ACTIVITY MONITOR TIMER2: POP AF POP BC POP DE POP HL LD SP,(IRQSAV) EI ;RE-ENABLE INTERRUPTS AND RETURN RETI ; ; ; -- INTERRUPT SERVICE ROUTINE FOR CRTC VSYNC INTERRUPT -- ; VSYNC: LD (IRQSAV),SP ;SAVE USER STACK POINTER AND LD SP,IRQSTK ; SWITCH TO LOCAL STACK PUSH HL PUSH DE PUSH BC PUSH AF LD A,(DSCOPY) PUSH AF ;SAVE D/S CONTROL BYTE ON STACK LD A,DYSTAT+OFF OUT (PORT0),A ;SWITCH-ON STATIC MEMORY BANK Š; ; This part is almost a dead out copy of the original. I used ; de for my start reference to save a couple of bytes. (vsync2 ; gets it if we take the jump). ; newcrsph: ld a,(scroll) or a ld de,(start) ; both paths need this, so be efficient jr z,vsync2 ; if no scroll requested this time ; ld a,12 out (crtadd),a ; select high start register ld a,d ; new high start out (crtdat),a ld a,13 out (crtadd),a ; select low start register ld a,e out (crtdat),a ld hl,(newlin) add hl,de ; (start)+(newlin) res 3,h ; modulo 2048 ld bc,80 push de ; have to pass (start) to vsync2 this ; path too. call CLRLINE pop de ; recover (start) ; ; This part is new. You can have this mod without re-burning ; a PROM, and thus have your cake and eat it too. ZAPCSR is ; no longer needed, so you can take it out if you re-assemble. ; ; vsync2 receives de = (start) ; vsync2: ld hl,(cursor) ld a,15 ; low order cursor position out (crtadd),a ld a,l out (crtdat),a sub e ; if cursor position is less than ld a,14 ; start, we will bump cursor mod 2048 out (crtadd),a ld a,h ; high order cursor position sbc a,d ld a,h ; tentative high order byte jr nc,cursok ; if start <=curs ; set 3,a ; else bump cursor modulo 2048 ; cursok: out (crtdat),a ; high order LD A,00000011B Š OUT (CTCA3),A ;TURN OFF VSYNC INTERRUPT XOR A LD (SCROLL),A ;RESET SCROLL-REQUEST FLAG LD (MOVECS),A ;RESET CURSOR-MOVE-REQUEST FLAG POP AF ;POP MEMORY CONTROL BYTE OFF STACK OUT (PORT0),A ;SWITCH BACK TO PRE-INTERRUPT CONFIG POP AF POP BC POP DE POP HL LD SP,(IRQSAV) EI ;RE-ENABLE INTERRUPTS AND RETURN RETI ; ; ; ; POLLED MODE I/O ROUTINES FOR SIO CHANEL B ; SIOST: IN A,(SIOCPB) ;GET SIO STATUS REGISTER AND 00000001B RET Z ;ACC=0 IF NO DATA AVAILABLE LD A,255 RET ; ; SIOIN: CALL SIOST ;TEST CONSOLE STATUS JR Z,SIOIN ;LOOP UNTIL DATA IS IN A,(SIODPB) ; READY AT SIO DATA PORT AND 01111111B RET ; ; ; ; -- RX INTERRUPT SERVICE ROUTINE FOR SIO CONSOLE -- ; SIOINT: LD (IRQSAV),SP LD SP,IRQSTK PUSH HL PUSH DE PUSH BC PUSH AF LD HL,SIOADR+1 LD C,(HL) ;LOAD C WITH SIO DATA PORT# IN A,(C) AND 01111111B LD HL,(RDAVEC) CALL DISPATCH ;GO PROCESS SIO INPUT CHARACTER POP AF POP BC POP DE POP HL LD SP,(IRQSAV) Š EI RETI ; ; ; -- RX ERROR INTERRUPT SERVICE ROUTINE FOR SIO CONSOLE -- ; SIOERR: LD (IRQSAV),SP LD SP,IRQSTK PUSH AF PUSH BC LD A,(SIOADR) LD C,A ;LOAD C WITH SIO CONTROL PORT# LD A,00110000B OUT (C),A ;RESET SIO EXTERNAL STATUS/INTERRUPTS LD A,(SIOADR+1) LD C,A ;NOW LOAD C WITH DATA PORT# IN A,(C) ;INPUT AND DISCARD BAD CHARACTER POP BC POP AF EI RETI ; ; ; ; ; SIOOUT: PUSH BC PUSH AF LD A,(SIOADR) LD C,A ;LOAD C WITH SIO STATUS PORT# SIOUT1: IN A,(C) AND 00000100B ;TEST TBE STATUS BIT JR Z,SIOUT1 LD A,(SIOADR+1) LD C,A ;LOAD C WITH SIO DATA PORT# NOW POP AF OUT (C),A ;OUTPUT DATA TO SIO POP BC RET ; ; ; ; ; ; CLOCK: LD DE,TOD ;POINT DE TO START OF TIME-OF-DAY LD HL,TODTAB ;POINT HL TO HH:MM:SS TABLE LD B,4 CLOCK2: LD A,(DE) ADD A,1 ;INCREMENT TIME WITH ADD INSTRUCTION DAA ; SO DECIMAL ADJUST WILL WORK RIGHT CP (HL) ;COMPARE IF HH/MM/SS ROLLED OVER JR C,CLOCK3 Š XOR A ;RESET TO ZERO IF ROLL OVER CLOCK3: LD (DE),A ;STORE UPDATED TIME DATA RET C ;EXIT IF NO MORE NEEDS TO BE DONE INC HL INC DE ;ELSE POINT TO NEXT DATA & CONSTANT DJNZ CLOCK2 CLOCK4: RET TODTAB: DEFB 60H ;60 SECONDS/MINUTE DEFB 60H ;60 MINUTES/HOUR DEFB 24H ;24 HOURS/DAY DEFB 99H ;OVERFLOW TO DAYS ; ; KEYTAB: DB 0C3H,0D ;OLD VALUE - NEW VALUE DB 3FH KEYTABL EQU $-KEYTAB-1 ;CALCULATE LENGHT OF TABLE ;