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