6502: Fix ZP = 0 assumptions and note further fixes needed
authorAlan Cox <alan@linux.intel.com>
Tue, 3 Oct 2017 22:30:33 +0000 (23:30 +0100)
committerAlan Cox <alan@linux.intel.com>
Tue, 3 Oct 2017 22:30:33 +0000 (23:30 +0100)
The runtime for cc65 assumes it can save to ZP and jump to the same address
via a 16bit index. That fails on our 65C816 build and also on things like the
HuC. Also fix the same offence in ct0.s

Note that we need to save jmpvec+1/2 for re-entry (CC65 forgets to mention this)
and also that we can't just swap zp because unlike a kernel/IRQ switch where
this is valid in Fuzix it's possible to take one signal in another, thus
we must stack the ZP state somewhere (at 20 odd bytes probably the C stack)

Library/libs/crt0_6502.s
Library/libs/crt0nostdio_6502.s

index fcc580c..9da5fff 100644 (file)
 ;      I think therefore that providing we dec sp+1 we are always ok and
 ;      will be somewhere between 0 and 255 bytes of valid
 ;
-;
 __sighandler:
        jsr     stash_zp        ; saves sp etc
        dec     sp+1            ; ensure we are safe C stack wise
        pla
-       sta     ptr1            ; ZP was swapped
+       sta     jmpvec+1        ; ZP was swapped
        pla
-       sta     ptr1+1          ; ptr1 is now the function
+       sta     jmpvec+2        ; ptr1 is now the function
        pla
+
        ldx     #0
        jsr     pushax          ; signal(int sig)
-       jsr     jptr1           ; no jsr (x) so fake it
+       jsr     jmpvec          ; no jsr (x) so fake it
        jsr     stash_zp        ; recovers sp
 initmainargs:                  ; Hardcoded compiler dumbness
        rts                     ; will return via the kernel stub
-                               ; to user space
-jptr1: jmp     (ptr1)
 ;
 ;
 ;      On entry sp/sp+1 have been set up by the kernel (this has to be
@@ -104,6 +102,10 @@ l1:        sta     _environ
 ;      with an IRQ handler one. The commondata is per process and we depend
 ;      upon this to make it all work
 ;
+;      FIXME: we need to save and restore jmpvec+1/2. As we can re-enter
+;      signal handlers we also need to shift to a save/restore of the ZP
+;      values (and jmpvec+1/2) onto the C stack
+;
 ; Swap the C temporaries
 ;
 stash_zp:
@@ -117,6 +119,36 @@ Swap1:  ldx     CTemp,y
         bpl     Swap1
         rts
 
+;
+;      Ensure this version is found before the broken one in cc65 runtime
+;      whichh won't work on 65C816
+
+;
+; Ullrich von Bassewitz, 06.08.1998
+;
+; CC65 runtime: call function via pointer in ax
+; Reworked Alan Cox 2017 to handle cases where ZP != 0
+;
+
+        .export         callax
+       .import         jmpvec
+
+       .macpack        generic
+       .macpack        cpu
+
+callax:
+
+.if (.cpu .bitand ::CPU_ISET_65SC02)
+       phx
+       pha
+       rts
+.else
+       sta     jmpvec+1
+        stx     jmpvec+2
+        jmp     (jmpvec+1)         ; jump there
+.endif
+
+
 
        .bss
 _environ:      .res    2
index b87634d..0162852 100644 (file)
 ;      I think therefore that providing we dec sp+1 we are always ok and
 ;      will be somewhere between 0 and 255 bytes of valid
 ;
-;
 __sighandler:
        jsr     stash_zp        ; saves sp etc
        dec     sp+1            ; ensure we are safe C stack wise
        pla
-       sta     ptr1            ; ZP was swapped
+       sta     jmpvec+1        ; ZP was swapped
        pla
-       sta     ptr1+1          ; ptr1 is now the function
+       sta     jmpvec+2        ; ptr1 is now the function
        pla
+
        ldx     #0
        jsr     pushax          ; signal(int sig)
-       jsr     jptr1           ; no jsr (x) so fake it
+       jsr     jmpvec          ; no jsr (x) so fake it
        jsr     stash_zp        ; recovers sp
 initmainargs:                  ; Hardcoded compiler dumbness
        rts                     ; will return via the kernel stub
-                               ; to user space
-jptr1: jmp     (ptr1)
 ;
 ;
 ;      On entry sp/sp+1 have been set up by the kernel (this has to be
@@ -77,6 +75,8 @@ start:
 ; Need to save the environment ptr. The rest of the stack should be
 ; fine.
 ;
+;
+;      FIXME: sort out some sort of constructor mechanism for this
 ;
        lda     sp
        ldx     sp+1
@@ -101,6 +101,10 @@ l1:        sta     _environ
 ;      with an IRQ handler one. The commondata is per process and we depend
 ;      upon this to make it all work
 ;
+;      FIXME: we need to save and restore jmpvec+1/2. As we can re-enter
+;      signal handlers we also need to shift to a save/restore of the ZP
+;      values (and jmpvec+1/2) onto the C stack
+;
 ; Swap the C temporaries
 ;
 stash_zp:
@@ -114,6 +118,36 @@ Swap1:  ldx     CTemp,y
         bpl     Swap1
         rts
 
+;
+;      Ensure this version is found before the broken one in cc65 runtime
+;      whichh won't work on 65C816
+
+;
+; Ullrich von Bassewitz, 06.08.1998
+;
+; CC65 runtime: call function via pointer in ax
+; Reworked Alan Cox 2017 to handle cases where ZP != 0
+;
+
+        .export         callax
+       .import         jmpvec
+
+       .macpack        generic
+       .macpack        cpu
+
+callax:
+
+.if (.cpu .bitand ::CPU_ISET_65SC02)
+       phx
+       pha
+       rts
+.else
+       sta     jmpvec+1
+        stx     jmpvec+2
+        jmp     (jmpvec+1)         ; jump there
+.endif
+
+
 
        .bss
 _environ:      .res    2