From: Oliver Schmidt
Date: Fri, 25 Mar 2016 20:57:06 +0000 (+0100)
Subject: Allow _sys() to call ROM routines.
X-Git-Tag: V2.16~154
X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=29d1400340f803d0df1ca2b6b2f85a3e3baca9a3;p=cc65
Allow _sys() to call ROM routines.
_sys() is supposed to be (primarily) intended to call ROM routines. Leveraging the "file overlay" mechanism of the cc65 build system allows to provide a Apple II specific _sys() implementation that temporarily switches in the ROM.
---
diff --git a/libsrc/apple2/_sys.s b/libsrc/apple2/_sys.s
new file mode 100644
index 000000000..ae4ea81d2
--- /dev/null
+++ b/libsrc/apple2/_sys.s
@@ -0,0 +1,81 @@
+;
+; void __fastcall__ _sys (struct regs* r);
+;
+
+ .export __sys
+ .import jmpvec
+
+ .include "zeropage.inc"
+
+ .segment "LOWCODE"
+
+__sys: sta ptr1
+ stx ptr1+1 ; Save the pointer to r
+
+ ; Fetch the PC and store it into the jump vector
+ ldy #5
+ lda (ptr1),y
+ sta jmpvec+2
+ dey
+ lda (ptr1),y
+ sta jmpvec+1
+
+ ; Remember the flags so we can restore them to a known state after calling the
+ ; routine
+ php
+
+ ; Get the flags, keep the state of bit 4 and 5 using the other flags from
+ ; the flags value passed by the caller. Push the new flags and push A.
+ dey
+ php
+ pla ; Current flags -> A
+ eor (ptr1),y
+ and #%00110000
+ eor (ptr1),y
+ pha ; Push new flags value
+ ldy #0
+ lda (ptr1),y
+ pha
+
+ ; Get and assign X and Y
+ iny
+ lda (ptr1),y
+ tax
+ iny
+ lda (ptr1),y
+ tay
+
+ ; Switch in ROM
+ bit $C082
+
+ ; Set A and the flags, call the machine code routine
+ pla
+ plp
+ jsr jmpvec
+
+ ; Back from the routine. Save the flags and A.
+ php
+ pha
+
+ ; Switch in LC bank 2 for R/O
+ bit $C080
+
+ ; Put the register values into the regs structure
+ tya
+ ldy #2
+ sta (ptr1),y
+ dey
+ txa
+ sta (ptr1),y
+ dey
+ pla
+ sta (ptr1),y
+ ldy #3
+ pla
+ sta (ptr1),y
+
+ ; Restore the old flags value
+ plp
+
+ ; Done
+ rts