6502: first attempt at a proper push/pop signal stacking handler
authorAlan Cox <alan@linux.intel.com>
Tue, 10 Apr 2018 21:50:32 +0000 (22:50 +0100)
committerAlan Cox <alan@linux.intel.com>
Tue, 10 Apr 2018 21:50:32 +0000 (22:50 +0100)
Library/libs/crt0_6502.s
Library/libs/crt0nostdio_6502.s

index c36a660..e48838f 100644 (file)
@@ -13,6 +13,8 @@
        .import         _main
        .import         popax, pushax
        .import         ___stdio_init_vars
+       .import         decsp8, incsp8, decsp2, incsp2
+       .import         jmpvec
 
        .export __STARTUP__ : absolute = 1;
 
@@ -45,18 +47,39 @@ head:
 ;      I think therefore that providing we dec sp+1 we are always ok and
 ;      will be somewhere between 0 and 255 bytes of valid
 ;
+;      We save only the minimal scratch variables. The logic here is that
+;      this routine will not touch the 'register' variables in ZP, but
+;      any C function it calls will treat them as callee save so will do
+;      any needed save/restore for us. So we need to save ptr1-4, tmp1-4
+;      and jmpvec
+;
 __sighandler:
-       jsr     stash_zp        ; saves sp etc
        dec     sp+1            ; ensure we are safe C stack wise
+       lda     jmpvec+1
+       pha
+       lda     jmpvec+2
+       pha
+       jsr     decsp8
+       jsr     decsp8
+       jsr     decsp2
+       jsr     stash_zp        ; saves sp etc
        pla
-       sta     jmpvec+1        ; ZP was swapped
+       sta     jmpvec+1        ; ZP was swapped (as was jmpvec)
        pla
-       sta     jmpvec+2        ; ptr1 is now the function
+       sta     jmpvec+2        ; Patch jmpvec
        pla
 
        ldx     #0              ; signal(sig)
        jsr     jmpvec          ; no jsr (x) so fake it
-       jsr     stash_zp        ; recovers sp
+       jsr     stash_zp        ; recovers everything
+       jsr     incsp2
+       jsr     incsp8
+       jsr     incsp8
+       inc     sp+1            ; back to old stack
+       pla
+       sta     jmpvec+2
+       pla
+       sta     jmpvec+1
 initmainargs:                  ; Hardcoded compiler dumbness
        rts                     ; will return via the kernel stub
 ;
@@ -97,27 +120,24 @@ l1:        sta     _environ
                                ; for a fastcall return to nowhere.
 
 ;
-;      The following is taken from the debugger example as referenced in
-;      the compiler documentation. We swap a stashed ZP in our commondata
-;      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
+; Swap the C temporaries - smaller tha separate save/loaders
 ;
 stash_zp:
-        ldy     #zpsavespace-1
-Swap1:  ldx     CTemp,y
-        lda     <sp,y
-        sta     CTemp,y
-        txa
-        sta     sp,y
-        dey
-        bpl     Swap1
-        rts
+       ldy     #0
+stash_loop:
+       lda     (sp),y          ; swap stack offset
+       pha
+       ldx     sp+2,y          ; and ZP variable
+       txa
+       sta     (sp+2),y
+       pla
+       tax
+       stx     sp,y
+       iny
+       cpy     #zpsavespace - 2        ; 18 bytes
+       bne     stash_loop
+       rts
+
 
 ;
 ;      Ensure this version is found before the broken one in cc65 runtime
@@ -146,7 +166,3 @@ callax:
        .bss
 _environ:      .res    2
 oldsp:         .res    2
-CTemp:
-               .res    2               ; sp
-               .res    2               ; sreg
-               .res    (zpsavespace-4) ; Other stuff
index 4a1fb42..8852c20 100644 (file)
@@ -12,7 +12,8 @@
        .export         initmainargs
        .import         _main
        .import         popax, pushax
-       .import         ___stdio_init_vars
+       .import         decsp8, incsp8, decsp2, incsp2
+       .import         jmpvec
 
        .export __STARTUP__ : absolute = 1;
 
@@ -45,18 +46,39 @@ head:
 ;      I think therefore that providing we dec sp+1 we are always ok and
 ;      will be somewhere between 0 and 255 bytes of valid
 ;
+;      We save only the minimal scratch variables. The logic here is that
+;      this routine will not touch the 'register' variables in ZP, but
+;      any C function it calls will treat them as callee save so will do
+;      any needed save/restore for us. So we need to save ptr1-4, tmp1-4
+;      and jmpvec
+;
 __sighandler:
-       jsr     stash_zp        ; saves sp etc
        dec     sp+1            ; ensure we are safe C stack wise
+       lda     jmpvec+1
+       pha
+       lda     jmpvec+2
+       pha
+       jsr     decsp8
+       jsr     decsp8
+       jsr     decsp2
+       jsr     stash_zp        ; saves sp etc
        pla
-       sta     jmpvec+1        ; ZP was swapped
+       sta     jmpvec+1        ; ZP was swapped (as was jmpvec)
        pla
-       sta     jmpvec+2        ; ptr1 is now the function
+       sta     jmpvec+2        ; Patch jmpvec
        pla
 
-       ldx     #0              ; signal(int sig)
+       ldx     #0              ; signal(sig)
        jsr     jmpvec          ; no jsr (x) so fake it
-       jsr     stash_zp        ; recovers sp
+       jsr     stash_zp        ; recovers everything
+       jsr     incsp2
+       jsr     incsp8
+       jsr     incsp8
+       inc     sp+1            ; back to old stack
+       pla
+       sta     jmpvec+2
+       pla
+       sta     jmpvec+1
 initmainargs:                  ; Hardcoded compiler dumbness
        rts                     ; will return via the kernel stub
 ;
@@ -74,9 +96,6 @@ 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
@@ -96,27 +115,24 @@ l1:        sta     _environ
                                ; for a fastcall return to nowhere.
 
 ;
-;      The following is taken from the debugger example as referenced in
-;      the compiler documentation. We swap a stashed ZP in our commondata
-;      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
+; Swap the C temporaries - smaller tha separate save/loaders
 ;
 stash_zp:
-        ldy     #zpsavespace-1
-Swap1:  ldx     CTemp,y
-        lda     <sp,y
-        sta     CTemp,y
-        txa
-        sta     sp,y
-        dey
-        bpl     Swap1
-        rts
+       ldy     #0
+stash_loop:
+       lda     (sp),y          ; swap stack offset
+       pha
+       ldx     sp+2,y          ; and ZP variable
+       txa
+       sta     (sp+2),y
+       pla
+       tax
+       stx     sp,y
+       iny
+       cpy     #zpsavespace - 2        ; 18 bytes
+       bne     stash_loop
+       rts
+
 
 ;
 ;      Ensure this version is found before the broken one in cc65 runtime
@@ -136,23 +152,12 @@ Swap1:  ldx     CTemp,y
        .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
 oldsp:         .res    2
-CTemp:
-               .res    2               ; sp
-               .res    2               ; sreg
-               .res    (zpsavespace-4) ; Other stuff