From 29d1400340f803d0df1ca2b6b2f85a3e3baca9a3 Mon Sep 17 00:00:00 2001
From: Oliver Schmidt
Date: Fri, 25 Mar 2016 21:57:06 +0100
Subject: [PATCH] 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.
---
libsrc/apple2/_sys.s | 81 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
create mode 100644 libsrc/apple2/_sys.s
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
--
2.39.5