From 5df392ff14180b87df886fef1b2fdca6c951f3fc Mon Sep 17 00:00:00 2001 From: "ol.sc" Date: Thu, 19 Jan 2012 00:24:13 +0000 Subject: [PATCH] Added wrapper for C level irq handling. git-svn-id: svn://svn.cc65.org/cc65/trunk@5408 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- include/6502.h | 18 +++++-- libsrc/common/Makefile | 1 + libsrc/common/interrupt.s | 102 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 libsrc/common/interrupt.s diff --git a/include/6502.h b/include/6502.h index 08b826800..e0f161f92 100644 --- a/include/6502.h +++ b/include/6502.h @@ -100,15 +100,27 @@ typedef void (*brk_handler) (void); /* Type of the break handler */ void __fastcall__ set_brk (brk_handler f); -/* Set the break vector to the given address, return the old address */ +/* Set the break vector to the given address */ void reset_brk (void); /* Reset the break vector to the original value */ -/* End of 6502.h */ -#endif +/* Possible returns for irq_handler() */ +#define IRQ_NOT_HANDLED 0 +#define IRQ_HANDLED 1 + +typedef unsigned (*irq_handler) (void); +/* Type of the C level interrupt request handler */ + +void __fastcall__ set_irq (irq_handler f, void *stack_addr, size_t stack_size); +/* Set the C level interrupt request vector to the given address */ +void reset_irq (void); +/* Reset the C level interrupt request vector */ + +/* End of 6502.h */ +#endif diff --git a/libsrc/common/Makefile b/libsrc/common/Makefile index 77a77e990..83966a004 100644 --- a/libsrc/common/Makefile +++ b/libsrc/common/Makefile @@ -123,6 +123,7 @@ S_OBJS = _cwd.o \ getcpu.o \ getcwd.o \ getenv.o \ + interrupt.o \ isalnum.o \ isalpha.o \ isblank.o \ diff --git a/libsrc/common/interrupt.s b/libsrc/common/interrupt.s new file mode 100644 index 000000000..0b05ed820 --- /dev/null +++ b/libsrc/common/interrupt.s @@ -0,0 +1,102 @@ +; +; Oliver Schmidt, 2012-01-18 +; +; void __fastcall__ set_irq (irq_handler f, void *stack_addr, size_t stack_size); +; void reset_irq (void); +; + + .export _set_irq, _reset_irq + .interruptor clevel_irq, 1 ; Export as low priority IRQ handler + .import popax + + .include "zeropage.inc" + + .macpack generic + + +.proc _set_irq + + ; Keep clevel_irq from being called right now + sei + + ; Set irq stack pointer to stack_addr + stack_size + sta irqsp + stx irqsp+1 + jsr popax + add irqsp + sta irqsp + txa + adc irqsp+1 + sta irqsp+1 + + ; Set irq vector to irq_handler + jsr popax + sta irqvec+1 + stx irqvec+2 ; Set the user vector + + ; Restore interrupt requests and return + cli + rts + +.endproc + + +.proc _reset_irq + + lda #$00 + sta irqvec+3 ; High byte is enough + rts + +.endproc + + +.proc clevel_irq + + ; Is C level interrupt request vector set? + lda irqvec+3 ; High byte is enough + bne @L1 + clc ; Interrupt not handled + rts + + ; Save our zero page locations +@L1: ldx #zpspace-1 +@L2: lda sp,x + sta zpsave,x + dex + bpl @L2 + + ; Set C level interrupt stack + lda irqsp + ldx irqsp+1 + sta sp + stx sp+1 + + ; Call C level interrupt request handler + jsr irqvec + + ; Copy back our zero page content + ldx #zpspace-1 +@L3: ldy zpsave,x + sty sp,x + dex + bpl @L3 + + ; Mark interrupt handled / not handled and return + lsr + rts + +.endproc + +; --------------------------------------------------------------------------- + +.data + +irqvec: jmp $00FF ; Patched at runtime + +; --------------------------------------------------------------------------- + +.bss + +irqsp: .res 2 + +zpsave: .res zpspace -- 2.39.5