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