From 1c77f6f1d5db48a69452297f65624ea37991140e Mon Sep 17 00:00:00 2001 From: oliverschmidt Date: Fri, 10 Aug 2007 10:45:35 +0000 Subject: [PATCH] - The cc65 assembler variable 'ptr1' (a general zero page pointer) is actually part of the cc65 zero page area so it's a bad idea (tm) to use it in swapping that very area. - The cc65 assembler variable 'sp' (the pointer to the C stack) is actually part of the cc65 zero page area so there's no need to manage it explicitly. Furthermore it is known to reside at the very start of the area so it can be initialized there for new threads. --- cpu/6502/mtarch-asm.S | 182 ++++++++++++++++++++++++------------------ cpu/6502/mtarch.c | 23 +++--- cpu/6502/mtarch.h | 5 +- 3 files changed, 120 insertions(+), 90 deletions(-) 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];