Vic 20 network - software by Lee Davison |
Without setting about the Vic with a screwdriver there is no way to change the lowest level handling of the Vic interrupts, so some of this code is to deal with the way interrupts are handled by the kernal.
Before the interrupts can be used the three vectors for IRQ, NMI and BRK handling need to be set up. This is done during the initialisation by this loop.
LDX #$05 ; set 6 vector bytes int_loop LDA i_table,X ; get byte from vector table STA IRQ_vec_l,X ; save to vector DEX ; decrement count BPL int_loop ; loop if more to doThese are the vector words that are copied to the vectors.
; ********************************************************************* ; default values for the interrupt vectors i_table .word iIRQ ; IRQ routine address .word iBRK ; BRK routine address .word iNMI ; NMI routine address ; *********************************************************************The NMI routine disables IRQ interrupts and saves any registers used, it could also clear the D flag if needed at this point. The next thing done is to reset the NMI latch, this ensures that longer than the minimum period needed elapses before the NMI line can become active again. After this it reads the status from the network card, the only source of NMI interrupts as set up, and copies any set bits into the interrupt flag byte. Lastly the registers are restored and the routine exits.
; ********************************************************************* ; NMI interrupt routine - the NIC /should/ trigger this iNMI SEI ; disable interrupts PHA ; save A LDA NMI_res ; reset NMI latch LDA com_reg_l ; read status byte AND #$FE ; mask wanted bits ORA IB ; OR with interrupt flag byte STA IB ; save new interrupt flag byte PLA ; restore A RTI ; *********************************************************************This, commented out, code is what goes on in the kernal ROM when either an IRQ or a BRK opcode generate an interrupt. It's included as a reminder of what goes on before code execution gets to our code.
;; ********************************************************************* ;; IRQ interrupt routine - this part is in the kernal ROM and is here ;; only to show what happens before we get to our code. ;; ;;IRQ ;; PHA ; save A ;; TXA ; copy X ;; PHA ; save X ;; TYA ; copy Y ;; PHA ; save Y ;; TSX ; copy stack pointer ;; LDA stack+4,X ; get stacked status register ;; AND #$10 ; mask BRK flag ;; BEQ do_IRQ ; branch if not BRK ;; ;; JMP (BRK_vec_l) ; else do BRK vector (iBRK) ;; ;;do_IRQ ;; JMP (IRQ_vec_l) ; do IRQ vector (iIRQ) ;; ;; *********************************************************************The only IRQ interrupt we expect is the timer implemented with VIA 2's timer 1. If it was timer 1 then a call is made to the countdown routine after which the routine exits. If timer 1 was not the source, or a BRK was the cause of the interrupt, then the routine just exits.
; ********************************************************************* ; IRQ interrupt routine iIRQ LDA VIA_2+IFR ; check VIA 2 interrupt flags BPL IRQexit ; exit if wasn't VIA 2 AND #$40 ; mask timer 1 time-out flagged BEQ IRQexit ; exit if not timer 1 time-out STA VIA_2+IFR ; clear timer 1 time-out flag JSR LAB_12000 ; do timeout countdowns ; ********************************************************************* ; BRK interrupt routine - does nothing at the moment iBRK IRQexit PLA ; pull byte TAY ; restore Y PLA ; pull byte TAX ; restore X PLA ; restore A RTI ; *********************************************************************This is the system timer code and it implements three independant, re-triggerable, single shot count down timers. At present only the TCP timer and one other is used.
; ********************************************************************* ; does the timeout counting down, called on TIMER 1 timeout (1mS) ; decrement the TCP timeout counter if <> 0 LAB_12000 LDA tcp_toc ; test TCP timeout count BEQ LAB_12005 ; skip decrement if zero DEC tcp_toc ; else decrement it LAB_12005 LDA cdtb_l ; get countdown timer b low byte BEQ LAB_12010 ; skip decrement if zero DEC cdtb_l ; else decrement it LAB_12010 LDA cdtf_l ; get countdown timer f low byte BEQ LAB_12015 ; skip decrement if zero DEC cdtf_l ; else decrement it LAB_12015 RTS ; *********************************************************************
Last page update: 29th February, 2004. | e-mail me |