Use vectors for irq and nmi
This commit is contained in:
@@ -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)
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <conio.h>
|
||||
|
||||
#include "devices/interrupt.h"
|
||||
#include "devices/uart.h"
|
||||
|
||||
|
||||
|
||||
void handle_irq() {
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user