From fe45331e7a474e51a09580d313f30fefcb4775d9 Mon Sep 17 00:00:00 2001 From: Byron Lathi Date: Mon, 14 Mar 2022 11:54:43 -0500 Subject: [PATCH] Add interrupt handlers and redo vector locations Most of these are taken from https://cc65.github.io/doc/customizing.html, but modified to suit this setup. --- sw/boot.s | 8 +------- sw/interrupt.s | 46 ++++++++++++++++++++++++++++++++++++++++++++++ sw/irq.c | 7 +++++++ sw/vectors.s | 14 ++++++++++++++ 4 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 sw/interrupt.s create mode 100644 sw/irq.c create mode 100644 sw/vectors.s diff --git a/sw/boot.s b/sw/boot.s index 269c5fd..67e7b15 100644 --- a/sw/boot.s +++ b/sw/boot.s @@ -14,12 +14,6 @@ .include "zeropage.inc" -.segment "VECTORS" - -.addr _init -.addr _init -.addr _init - ; --------------------------------------------------------------------------- ; Place the startup code in a special segment @@ -49,7 +43,7 @@ _init: LDX #$FF ; Initialize stack pointer to $01FF ; --------------------------------------------------------------------------- ; Call main() - + cli JSR _main ; --------------------------------------------------------------------------- diff --git a/sw/interrupt.s b/sw/interrupt.s new file mode 100644 index 0000000..c269e33 --- /dev/null +++ b/sw/interrupt.s @@ -0,0 +1,46 @@ +; --------------------------------------------------------------------------- +; interrupt.s +; --------------------------------------------------------------------------- +; +; Interrupt handler. +; +; Checks for a BRK instruction and returns from all valid interrupts. + +.import _handle_irq + +.export _irq_int, _nmi_int + +.segment "CODE" + +.PC02 ; Force 65C02 assembly mode + +; --------------------------------------------------------------------------- +; Non-maskable interrupt (NMI) service routine + +_nmi_int: RTI ; Return from all NMI interrupts + +; --------------------------------------------------------------------------- +; 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: JMP break ; If BRK is detected, something very bad + ; has happened, so stop running \ No newline at end of file diff --git a/sw/irq.c b/sw/irq.c new file mode 100644 index 0000000..0d51cc0 --- /dev/null +++ b/sw/irq.c @@ -0,0 +1,7 @@ + +// This is defined in main.c +void puts(const char* s); + +void handle_irq() { + puts("Interrupt Detected!\n"); +} \ No newline at end of file diff --git a/sw/vectors.s b/sw/vectors.s new file mode 100644 index 0000000..81ae6e0 --- /dev/null +++ b/sw/vectors.s @@ -0,0 +1,14 @@ +; --------------------------------------------------------------------------- +; vectors.s +; --------------------------------------------------------------------------- +; +; Defines the interrupt vector table. + +.import _init +.import _nmi_int, _irq_int + +.segment "VECTORS" + +.addr _nmi_int ; NMI vector +.addr _init ; Reset vector +.addr _irq_int ; IRQ/BRK vector \ No newline at end of file