diff --git a/cpu/6502/mtarch-asm.S b/cpu/6502/mtarch-asm.S index a90ed1495..34a6666c6 100644 --- a/cpu/6502/mtarch-asm.S +++ b/cpu/6502/mtarch-asm.S @@ -30,15 +30,12 @@ ; ; Author: Adam Dunkels ; -; $Id: mtarch-asm.S,v 1.1 2007/04/21 22:15:45 oliverschmidt Exp $ +; $Id: mtarch-asm.S,v 1.2 2007/08/10 10:45:35 oliverschmidt Exp $ ; ;--------------------------------------------------------------------- - .importzp ptr1 - .importzp sp .import __ZP_START__ .import _mtarch_asm_threadspreg - .import _mtarch_asm_threadsp .import _mtarch_asm_threadzp .import _mtarch_asm_threadstack @@ -48,68 +45,77 @@ ;--------------------------------------------------------------------- .bss -kernelsp: .res 2 -kernelspreg: .res 1 +kernelspreg: .res 1 +zpsave: .res 2 -zpsize = 32 +zpspace = 26 ; see /asminc/zeropage.inc ;--------------------------------------------------------------------- .code -; Switch to thread defined by threadsp, threadstack and threadspreg. -; The kernel stack is swapped onto the threadstack, and the -; sp and spreg are saved to the local variables "kernelsp" and -; "kernelspreg". Also, the zeropage variables are saved. +; Switch to thread defined by threadzp, threadstack and threadspreg. +; The kernel CPU stack is swapped onto the threadstack, and the +; CPU stack pointer is saved to the local variable "kernelspreg". +; Also, the zeropage variables are saved. _mtarch_asm_exec: sei - ; Save current stack pointer - lda sp - sta kernelsp - lda sp+1 - sta kernelsp+1 + ; Save kernel CPU stack pointer tsx stx kernelspreg - - lda _mtarch_asm_threadzp - sta ptr1 - lda _mtarch_asm_threadzp+1 - sta ptr1+1 + ; Save zp locations FE/FF + lda $FE + sta zpsave + lda $FF + sta zpsave+1 + + ; Get zero page buffer addr + lda _mtarch_asm_threadzp + sta $FE + lda _mtarch_asm_threadzp+1 + sta $FF + + ; Swap zero page content with buffer content ldy #0 : lda <__ZP_START__,y tax - lda (ptr1),y + lda ($FE),y sta <__ZP_START__,y txa - sta (ptr1),y + sta ($FE),y iny - cpy #zpsize + cpy #zpspace bne :- + ; Get CPU stack buffer addr lda _mtarch_asm_threadstack - sta ptr1 + sta $FE lda _mtarch_asm_threadstack+1 - sta ptr1+1 + sta $FF + ; Get CPU stack size ldy kernelspreg ; Determine the smallest of the two stack pointers, cpy _mtarch_asm_threadspreg ; as we only need to swap the used part of the stack. bcc :+ ldy _mtarch_asm_threadspreg + ; Swap CPU stack content with buffer content : lda $0100,y tax - lda (ptr1),y + lda ($FE),y sta $0100,y txa - sta (ptr1),y + sta ($FE),y iny bne :- - lda _mtarch_asm_threadsp - sta sp - lda _mtarch_asm_threadsp+1 - sta sp+1 - + ; Restore zp locations FE/FF + lda zpsave + sta $FE + lda zpsave+1 + sta $FF + + ; Set thread CPU stack pointer ldx _mtarch_asm_threadspreg txs @@ -121,10 +127,10 @@ _mtarch_asm_exec: rti ;--------------------------------------------------------------------- -; Switch from thread defined by threadsp, threadstack and threadspreg. -; The kernel stack is swapped back from the threadstack, and the -; sp and spreg are restored from the local variables "kernelsp" and -; "kernelspreg". +; Switch from thread defined by threadzp, threadstack and threadspreg. +; The kernel CPU stack is swapped back from the threadstack, and the +; CPU stack pointer is restored from the local variable "kernelspreg". +; Also, the zeropage variables are restored. _mtarch_asm_yield: php pha @@ -144,54 +150,63 @@ _mtarch_asm_yield: adc #0 sta $0106,x - lda sp - sta _mtarch_asm_threadsp - lda sp+1 - sta _mtarch_asm_threadsp+1 - + ; Save thread CPU stack pointer tsx stx _mtarch_asm_threadspreg - lda _mtarch_asm_threadzp - sta ptr1 - lda _mtarch_asm_threadzp+1 - sta ptr1+1 + ; Save zp locations FE/FF + lda $FE + sta zpsave + lda $FF + sta zpsave+1 + ; Get zero page buffer addr + lda _mtarch_asm_threadzp + sta $FE + lda _mtarch_asm_threadzp+1 + sta $FF + + ; Swap zero page content with buffer content + ldy #0 +: lda <__ZP_START__,y + tax + lda ($FE),y + sta <__ZP_START__,y + txa + sta ($FE),y + iny + cpy #zpspace + bne :- + + ; Get CPU stack buffer addr + lda _mtarch_asm_threadstack + sta $FE + lda _mtarch_asm_threadstack+1 + sta $FF + + ; Get CPU stack size ldy kernelspreg ; Determine the smallest of the two stack pointers, cpy _mtarch_asm_threadspreg ; as we only need to swap the used part of the stack. bcc :+ ldy _mtarch_asm_threadspreg -: lda <__ZP_START__,y - tax - lda (ptr1),y - sta <__ZP_START__,y - txa - sta (ptr1),y - iny - cpy #zpsize - bne :- - - lda _mtarch_asm_threadstack - sta ptr1 - lda _mtarch_asm_threadstack+1 - sta ptr1+1 - - ldy #0 + ; Swap CPU stack content with buffer content : lda $0100,y tax - lda (ptr1),y + lda ($FE),y sta $0100,y txa - sta (ptr1),y + sta ($FE),y iny bne :- - lda kernelsp - sta sp - lda kernelsp+1 - sta sp+1 - + ; Restore zp locations FE/FF + lda zpsave + sta $FE + lda zpsave+1 + sta $FF + + ; Set kernel CPU stack pointer ldx kernelspreg txs @@ -199,16 +214,31 @@ _mtarch_asm_yield: rts ;--------------------------------------------------------------------- _mtarch_asm_start: - lda _mtarch_asm_threadzp - sta ptr1 - lda _mtarch_asm_threadzp+1 - sta ptr1+1 + ; Save zp locations FE/FF + lda $FE + sta zpsave + lda $FF + sta zpsave+1 - ldy #0 + ; Get zero page buffer addr + lda _mtarch_asm_threadzp + sta $FE + lda _mtarch_asm_threadzp+1 + sta $FF + + ; Copy zero page content to buffer + ldy #$00 : lda <__ZP_START__,y - sta (ptr1),y + sta ($FE),y iny - cpy #zpsize + cpy #zpspace bne :- + + ; Restore zp locations FE/FF + lda zpsave + sta $FE + lda zpsave+1 + sta $FF + rts ;--------------------------------------------------------------------- diff --git a/cpu/6502/mtarch.c b/cpu/6502/mtarch.c index bd0306c28..a1deb3b95 100644 --- a/cpu/6502/mtarch.c +++ b/cpu/6502/mtarch.c @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: mtarch.c,v 1.1 2007/04/21 22:15:45 oliverschmidt Exp $ + * $Id: mtarch.c,v 1.2 2007/08/10 10:45:35 oliverschmidt Exp $ */ #include @@ -38,7 +38,6 @@ #include "mtarch.h" unsigned char mtarch_asm_threadspreg; -unsigned char *mtarch_asm_threadsp; unsigned char *mtarch_asm_threadzp; unsigned char *mtarch_asm_threadstack; @@ -65,6 +64,10 @@ mtarch_start(struct mtarch_thread *thread, memset(thread->cpustack, 0, sizeof(thread->cpustack)); memset(thread->cstack, 0, sizeof(thread->cstack)); + /* Copy current zero page content as template. */ + mtarch_asm_threadzp = &(thread->zp); + mtarch_asm_start(); + /* Create a CPU stack frame with the appropriate values. */ thread->cpustack[MTARCH_CPUSTACKSIZE - 2] = ((unsigned short)function) / 0x100; /* high byte of return address */ thread->cpustack[MTARCH_CPUSTACKSIZE - 3] = ((unsigned short)function) % 0x100; /* low byte of return address */ @@ -75,12 +78,12 @@ mtarch_start(struct mtarch_thread *thread, thread->spreg = MTARCH_CPUSTACKSIZE - 8; /* Setup the C stack with the data pointer. */ - thread->cstack[MTARCH_CPUSTACKSIZE - 2] = ((unsigned short)data) / 0x100; /* high byte of data pointer */ - thread->cstack[MTARCH_CPUSTACKSIZE - 3] = ((unsigned short)data) % 0x100; /* low byte of data pointer */ - thread->sp = &thread->cstack[MTARCH_CSTACKSIZE - 3]; + thread->cstack[MTARCH_CSTACKSIZE - 2] = ((unsigned short)data) / 0x100; /* high byte of data pointer */ + thread->cstack[MTARCH_CSTACKSIZE - 3] = ((unsigned short)data) % 0x100; /* low byte of data pointer */ - mtarch_asm_threadzp = &(thread->zp); - mtarch_asm_start(); + /* Setup the C stack pointer. */ + thread->zp[1] = ((size_t)&thread->cstack[MTARCH_CSTACKSIZE - 3]) / 0x100; /* high byte of C stack pointer */ + thread->zp[0] = ((size_t)&thread->cstack[MTARCH_CSTACKSIZE - 3]) % 0x100; /* low byte of C stack pointer */ } /*--------------------------------------------------------------------------*/ void @@ -95,14 +98,12 @@ mtarch_exec(struct mtarch_thread *thread) /* Switch processor stack. The call to mtarch_asm_switch() will not return until the process that we switch to calls yield(). */ mtarch_asm_threadspreg = thread->spreg; - mtarch_asm_threadsp = thread->sp; - mtarch_asm_threadstack = &(thread->cpustack[0]); - mtarch_asm_threadzp = &(thread->zp[0]); + mtarch_asm_threadstack = thread->cpustack; + mtarch_asm_threadzp = thread->zp; mtarch_asm_exec(); - thread->sp = mtarch_asm_threadsp; thread->spreg = mtarch_asm_threadspreg; } /*--------------------------------------------------------------------------*/ diff --git a/cpu/6502/mtarch.h b/cpu/6502/mtarch.h index 939db50a8..063a601f4 100644 --- a/cpu/6502/mtarch.h +++ b/cpu/6502/mtarch.h @@ -30,7 +30,7 @@ * * Author: Adam Dunkels * - * $Id: mtarch.h,v 1.2 2007/04/21 22:15:45 oliverschmidt Exp $ + * $Id: mtarch.h,v 1.3 2007/08/10 10:45:35 oliverschmidt Exp $ */ #ifndef __MTARCH_H__ @@ -38,11 +38,10 @@ #define MTARCH_CPUSTACKSIZE 256 #define MTARCH_CSTACKSIZE 256 -#define MTARCH_ZPSIZE 32 +#define MTARCH_ZPSIZE 26 // see /asminc/zeropage.inc struct mtarch_thread { unsigned char spreg; - unsigned char *sp; unsigned char cpustack[MTARCH_CPUSTACKSIZE]; unsigned char cstack [MTARCH_CSTACKSIZE]; unsigned char zp [MTARCH_ZPSIZE];