Use vectors for irq and nmi

This commit is contained in:
Byron Lathi
2023-11-21 18:53:17 -08:00
parent 1714a1e6da
commit 102c4dfe8a
6 changed files with 254 additions and 325 deletions

View File

@@ -6,12 +6,11 @@
;
; Checks for a BRK instruction and returns from all valid interrupts.
.import _handle_irq
.import _cputc, _clrscr
.export _irq_int, _nmi_int
.include "io.inc65"
IRQ_VECTOR = $220
NMI_VECTOR = $222
.segment "CODE"
@@ -20,81 +19,9 @@
; ---------------------------------------------------------------------------
; Non-maskable interrupt (NMI) service routine
_nmi_int: RTI ; Return from all NMI interrupts
_nmi_int: jmp (NMI_VECTOR)
; ---------------------------------------------------------------------------
; Maskable interrupt (IRQ) service routine
_irq_int: PHX ; Save X register contents to stack
TSX ; Transfer stack pointer to X
PHA ; Save accumulator contents to stack
INX ; Increment X so it points to the status
INX ; register value saved on the stack
LDA $100,X ; Load status register contents
AND #$10 ; Isolate B status bit
BNE break ; If B = 1, BRK detected
; ---------------------------------------------------------------------------
; IRQ detected, return
irq: PLA ; Restore accumulator contents
PLX ; Restore X register contents
jsr _handle_irq ; Handle the IRQ
RTI ; Return from all IRQ interrupts
; ---------------------------------------------------------------------------
; BRK detected, stop
break:
pla
plx
jmp (bios_table,x)
bios_table:
.addr _console_clear
.addr _console_read_char
.addr _console_write_char
_console_clear:
jsr _clrscr
rti
_console_read_char:
; not supported
rti
_console_write_char:
jsr _cputc
rti
; What functions do we need?
; UART
; clear
; write character
; read character
; DISK
; init (or should it just init on boot?)
; read sector into memory
; FS
; init (if disk init succeeds, should it always try?)
; find add
; I think that is all we need for now?
; How do we call the functions?
; we have to call `brk` to trigger the interrupt
; in any of the three registers we can have arguments
; or we could have them pushed to the stack, assuming
; the stack is in the same location
; Or you could pass a pointer which points to an array
; of arguments
; for things like clear, read/write character, and init you don't
; need any arguments.
; jump table index needs to be in x, but also needs to be a multiple
; of 2.
_irq_int: jmp (IRQ_VECTOR)

View File

@@ -1,11 +0,0 @@
#include <stdint.h>
#include <conio.h>
#include "devices/interrupt.h"
#include "devices/uart.h"
void handle_irq() {
}

View File

@@ -9,6 +9,8 @@
.export _disable_irq
.export _send_eoi
.import irq_int, nmi_int
IRQ_CMD_ADDR = $effc
IRQ_DAT_ADDR = $effd
@@ -19,11 +21,24 @@ IRQ_CMD_ENABLE = $20
IRQ_CMD_TYPE = $40
IRQ_CMD_EOI = $ff
IRQ_VECTOR = $220
NMI_VECTOR = $222
.code
; void init_irq();
; mask all IRQs, set all type to edge.
.proc _init_interrupt_controller
lda #<irq_int
sta IRQ_VECTOR
lda #>irq_int
sta IRQ_VECTOR+1
lda #<nmi_int
sta NMI_VECTOR
lda #>nmi_int
sta NMI_VECTOR+1
ldx #$20 ; enable
ldy #00
jsr cmd_all

View File

@@ -6,9 +6,6 @@
#define BUTTON (1 << 0)
#define UART (1 << 1)
void irq_int();
void nmi_int();
void register_irq(void* addr, uint8_t irqn);
uint8_t irq_get_status();

View File

@@ -4,7 +4,7 @@
.import _enable_irq
.export _irq_int, _nmi_int
.export irq_int, nmi_int
.export _register_irq
IRQ_CMD_ADDR = $effc
@@ -12,13 +12,14 @@ IRQ_DAT_ADDR = $effd
IRQ_CMD_READIRQ = $00
.proc _nmi_int
.proc nmi_int
rti
.endproc
; _irq_int
.proc _irq_int
; irq_int
.proc irq_int
; Load IRQ number
lda #IRQ_CMD_READIRQ
sta IRQ_CMD_ADDR