]> git.sur5r.net Git - cc65/commitdiff
Allow _sys() to call ROM routines.
authorOliver Schmidt <ol.sc@web.de>
Fri, 25 Mar 2016 20:57:06 +0000 (21:57 +0100)
committerOliver Schmidt <ol.sc@web.de>
Fri, 25 Mar 2016 20:57:06 +0000 (21:57 +0100)
_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 [new file with mode: 0644]

diff --git a/libsrc/apple2/_sys.s b/libsrc/apple2/_sys.s
new file mode 100644 (file)
index 0000000..ae4ea81
--- /dev/null
@@ -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