BillO wrote:
floobydust wrote:
BillO wrote:
I've used software to manage multiple interrupts.
I took a brief look at your BIOS code, but I'm guessing it will take a lot more digging to interpret than the 10 minutes I've spent. So without some hardware, how do you determine which device requested the interrupt? Do you just poll them?
Yes, there is a core set of routines... one that handles each hardware device. They are linked through a vector table in page $03, so you can insert and change the sequence easily. Here's basic polling routine for the UART. Depending on what caused the interrupt, it branches to the routine that handles that.... if the UART did not trigger the interrupt, it exits quickly to the next handler, etc.
Code:
;IRQ Vector defaults to here, which is the Start of Interrupt handler.
; NOTE: 25 clock cycles to get to this routine
; NOTE: If this ISR is after the IDE ISR, it will take 33 additional clock cycles
;
INTERUPT0 ;Interrupt 0 to handle the SCC2691 UART
LDA UART_ISR ;Get the UART Interrupt Status Register (4)
CMP #%00100000 ;Check for no active IRQ source (2)
BEQ REGEXT0 ;If no bits are set, exit handler (2/3)
;
BIT #%00001000 ;Test for Delta Break (2)
BNE UART_BRK ;If yes, Reset the UART receiver (2/3)
BIT #%00000100 ;Test for RHR having data (2)
BNE UART_RCV ;If yes, put the data in the buffer (2/3)
BIT #%00000001 ;Test for THR ready to receive data (2)
BNE UART_XMT ;If yes, get data from buffer (2/3)
BIT #%00010000 ;Test for Counter ready (RTC) (2)
BNE UART_RTC ;If yes, go increment RTC variables (2/3)
;
IRQEXT0 STA UART_IRT ;Else, save the 2691 IRT for later use (4)
LDA UART_STATUS ;Get 2691 Status Register (4)
BUFF_ERR STA UART_SRT ;Save 2691 Status Register for later use (4)
REGEXT0 JMP (IRQRTVEC0) ;Return to Exit/ROM IRQ handler (6)
UART_BRK JMP UART_BRK0 ;Gotta JUMP to the routine
;
The REGEXT0 does an indirect JMP to a vector located on Page $03, which can point to the next interrupt handler or the exit routine in ROM which restores registers, etc. and exits via RTI. Also note that the IRQ get handled in BIOS to determine BRK or IRQ and does an indirect JMP to a vector in Page $03 to the appropriate handler.
Code:
;
IRQ_VECTOR ;This is the ROM start for the BRK/IRQ handler
PHA ;Save A Reg (3)
PHX ;Save X Reg (3)
PHY ;Save Y Reg (3)
TSX ;Get Stack pointer (2)
LDA $0100+4,X ;Get Status Register (4)
AND #$10 ;Mask for BRK bit set (2)
BNE DO_BRK ;If set, handle BRK (2/3)
JMP (IRQVEC0) ;Jump to Soft vectored IRQ Handler (6)
DO_BRK JMP (BRKVEC0) ;Jump to Soft vectored BRK Handler (6)
NMI_ROM JMP (NMIVEC0) ;Jump to Soft vectored NMI handler (6)
;
;This is the standard return for the IRQ/BRK handler routines
;
IRQ_EXIT0 PLY ;Restore Y Reg (4)
PLX ;Restore X Reg (4)
PLA ;Restore A Reg (4)
RTI ;Return from IRQ/BRK routine (6)
;