6502: save the zero page magic bits on interrupt, other minor fixups
authorAlan Cox <alan@linux.intel.com>
Sat, 10 Jan 2015 21:46:50 +0000 (21:46 +0000)
committerAlan Cox <alan@linux.intel.com>
Sat, 10 Jan 2015 21:46:50 +0000 (21:46 +0000)
Kernel/cpu-6809/cpu.h
Kernel/cpu-z80/cpu.h
Kernel/include/kernel.h
Kernel/lowlevel-6502.s
Kernel/platform-tgl6502/commonmem.s
Kernel/platform-tgl6502/ld65.cfg
Kernel/platform-tgl6502/tgl6502.s
Kernel/platform-tgl6502/tricks.s
Kernel/process.c

index 6b1ff9e..8ec0e33 100644 (file)
@@ -47,6 +47,9 @@ typedef union {            /* this structure is endian dependent */
 #define cpu_to_le16(x) swab(x)
 #define le16_to_cpu(x) swab(x)
 
+/* 6809 gcc already uses register calling whenever it can */
+#define __fastcall__
+
 #ifdef CONFIG_BANKED
 #define CODE1  __attribute__((far("1")))
 #define CODE2   __attribute__((far("2")))
index 437d4a2..7ed070d 100644 (file)
@@ -55,6 +55,9 @@ typedef union {            /* this structure is endian dependent */
 #define VIDEO
 #define DISCARD
 
+/* No fastcall in SDCC */
+#define __fastcall__
+
 #define cpu_to_le16(x) (x)
 #define le16_to_cpu(x) (x)
 #define cpu_to_le32(x) (x)
index 30c8df3..ff4388a 100644 (file)
@@ -573,9 +573,9 @@ COMMON int _uzero(uint8_t *user, usize_t count);
 
 /* platform/tricks.s */
 COMMON void switchout(void);
-COMMON void doexec(uint16_t start_addr);
-COMMON void switchin(ptptr process);
-COMMON int16_t dofork(ptptr child);
+COMMON void __fastcall__ doexec(uint16_t start_addr);
+COMMON void __fastcall__ switchin(ptptr process);
+COMMON int16_t __fastcall__ dofork(ptptr child);
 
 /* devio.c */
 CODE1 uint8_t *bread (uint16_t dev, blkno_t blk, bool rewrite);
@@ -667,12 +667,12 @@ CODE2 unsigned int ugetsys(unsigned char *to, unsigned int size);
 CODE2 void psleep(void *event);
 CODE2 void wakeup(void *event);
 CODE2 void pwake(ptptr p);
-CODE2 ptptr getproc(void);
-CODE2 void newproc(ptptr p);
+CODE2 ptptr __fastcall__ getproc(void);
+CODE2 void __fastcall__ newproc(ptptr p);
 CODE2 ptptr ptab_alloc(void);
 CODE2 void ssig(ptptr proc, uint16_t sig);
 CODE2 void chksigs(void);
-COMMON void program_vectors(uint16_t *pageptr);
+COMMON void __fastcall__ program_vectors(uint16_t *pageptr);
 CODE2 void sgrpsig(uint16_t pgrp, uint16_t sig);
 CODE2 void unix_syscall(void);
 CODE2 void timer_interrupt(void);
index 6e6d4ea..c48feae 100644 (file)
@@ -21,6 +21,7 @@
        .import _platform_interrupt_i
        .import platform_doexec
        .import _inint
+       .import CTemp
 
        .include "platform/zeropage.inc"
        .include "platform/kernel.def"
@@ -60,11 +61,12 @@ unix_sig_exit:
 ;
 ;      doexec is a special case syscall exit path. As we may have no
 ;      common we have to hand the last bits off to the platform code
+;      x,a holds the target address
 ;
 _doexec:
        sei
-       lda #0
-       sta _kernel_flag
+       ldy #0
+       sty _kernel_flag
        jsr map_process_always
        jmp platform_doexec
 
@@ -76,7 +78,11 @@ _doexec:
 ;      Caller on the exit side is responsible for stack switches and
 ;      checking for signals
 ;
+;      The C world here is fairly ugly. We have to stash various bits of
+;      zero page magic because its not re-entrant.
+;
 interrupt_handler:
+       jsr stash_zp                    ; Save zero page bits
        jsr map_save
        jsr map_kernel
        lda #1
@@ -91,10 +97,32 @@ interrupt_handler:
 interrupt_k:
        jsr map_restore
 int_switch:
+       jsr stash_zp                    ; Zero page stuff reverse
        lda #0
        sta _inint
        rts
 
+;
+;      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
+;
+; Swap the C temporaries
+;
+stash_zp:
+        ldy     #zpsavespace-1
+Swap1:  ldx     CTemp,y
+        lda     <sp,y
+        sta     CTemp,y
+        txa
+        sta     sp,y
+        dey
+        bpl     Swap1
+        rts
+
+
+
 nmi_handler:
        ldx #>nmi_trap
        lda #<nmi_trap
index a061d8a..2a64624 100644 (file)
@@ -8,8 +8,10 @@
         .export kstack_top
         .export istack_top
         .export istack_switched_sp
+       .export CTemp
 
         .segment "COMMONDATA"
+       .include "zeropage.inc"
 
 ;
 ;      In 6502 land these are the C stacks, we will need to handle the
@@ -28,3 +30,12 @@ istack_base:
        .res 254,0
 istack_top:
 istack_switched_sp: .word 0
+;
+;      Finally we tack the ZP save area for interrupts on the end
+;
+; Swap space for the the C temporaries (FIXME - we stash sp twice right now)
+;
+CTemp:
+       .res    2               ; sp
+       .res    2               ; sreg
+        .res    (zpsavespace-4) ; Other stuff
index 527be4b..6957a5d 100644 (file)
@@ -6,7 +6,7 @@ MEMORY {
 }
 
 SEGMENTS {
-       ZEROPAGE: load = RAMZ, type = zp;
+       ZEROPAGE: load = RAMZ, type = zp, define = yes;
        CODE:   load = ROM0, type = ro;
        RODATA: load = ROM0, type = ro;
        DATA:   load = ROM0, run = RAM1, type = rw, define = yes;
index 1e72ecc..f9e56e5 100644 (file)
@@ -437,7 +437,9 @@ copy_args:  lda (ptr1),y    ; copy the arguments from current bank
 
 
 platform_doexec:
-           jmp $2000           ; FIXME: should jump to argument really
+           stx ptr1+1
+           sta ptr1
+           jmp (ptr1)          ; 0x2000 usually
 
 ;
 ;      Straight jumps no funny banking issues
@@ -447,6 +449,3 @@ _unix_syscall_i:
 _platform_interrupt_i:
            jmp _platform_interrupt
 
-           .segment "ZEROPAGE"
-
-zp_intvec:     .byte 0
index 1043d03..d3561a1 100644 (file)
@@ -69,7 +69,7 @@ _switchout:
 badswitchmsg: .asciiz "_switchin: FAIL\r\n"
 
 ;
-;      Fixme: pull the C argument off into x,a
+;      On entry x,a holds the process to switch in
 ;
 _switchin:
        sei
index 1bf022b..46aa312 100644 (file)
@@ -96,7 +96,7 @@ ptptr getproc_nextp = &ptab[0];
 
 #ifndef CONFIG_SINGLETASK
 
-ptptr getproc(void)
+ptptr __fastcall__ getproc(void)
 {
        ptptr haltafter;
 #ifdef DEBUG
@@ -146,7 +146,7 @@ ptptr getproc(void)
  *     be blissfully unaware of its cut down environment.
  */
 
-ptptr getproc(void)
+ptptr __fastcall__ getproc(void)
 {
        ptptr p = udata.u_ptab;
 
@@ -189,7 +189,7 @@ ptptr getproc(void)
  * Call in the processes context!
  * This process MUST be run immediately (since it sets status P_RUNNING)
  */
-void newproc(ptptr p)
+void __fastcall__ newproc(ptptr p)
 {                              /* Passed New process table entry */
        uint8_t *j;
        irqflags_t irq;