From: Alan Cox Date: Tue, 2 Jan 2018 21:03:23 +0000 (+0000) Subject: 65c816: Fixes for non bank 0 X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=3f9d24482c9f3434de95d85f25a29b8098366678;p=FUZIX.git 65c816: Fixes for non bank 0 With this fixed the large mode seems to work (not heavily tested) and an 8MB boot works to a shell prompt and some test commands at least. --- diff --git a/Kernel/lib/65c816.s b/Kernel/lib/65c816.s index e11d3946..4f12020b 100644 --- a/Kernel/lib/65c816.s +++ b/Kernel/lib/65c816.s @@ -21,6 +21,7 @@ .import _runticks .import outcharhex .import outstring + .import kstack_base .code @@ -80,6 +81,9 @@ slow_path: .a8 lda U_DATA__U_PAGE sta f:KERNEL_CODE_FAR+switch_patch_1+1 ; target bank of save +.if ( KERNEL_BANK ) + sta f:KERNEL_CODE_FAR+switch_patch_2+1 ; target bank of save +.endif rep #$30 .i16 .a16 @@ -89,6 +93,20 @@ slow_path: phb switch_patch_1: mvn 0,KERNEL_BANK ; save stack and udata + +.if ( KERNEL_BANK ) + ; + ; Big (non bank 0) kernels by necessity split off the + ; kstack into bank 0. + ; + ; FIXME: some day split the user ZP to be half ZP half Kstack + ; + lda #$FF + ldx #kstack_base +switch_patch_2: + mvn 0,0 + +.endif plb sep #$30 stz _inint @@ -115,7 +133,10 @@ _switchin: ; If this is zero we need swapping so the swapper checks go here ; FIXME - sta f:KERNEL_CODE_FAR+switch_patch_2+2 ; source bank of retrieve + sta f:KERNEL_CODE_FAR+switch_patch_3+2 ; source bank of retrieve +.if ( KERNEL_BANK ) + sta f:KERNEL_CODE_FAR+switch_patch_4+2 ; source bank of retrieve +.endif rep #$30 .i16 .a16 @@ -125,19 +146,41 @@ _switchin: ldx #U_DATA_STASH ldy #U_DATA lda #U_DATA__TOTALSIZE-1 -switch_patch_2: +switch_patch_3: mvn KERNEL_BANK,0 - ; after the MVN our data bank is KERNEL_DATA + +.if ( KERNEL_BANK ) + ; + ; Big kernel - recover kstack into bank 0 + ; + ldy #kstack_base + lda #$FF +switch_patch_4: + mvn 0,0 + +.endif + + ; Bank may be invalid but we don't have a stack we can use + ; so force a far access + ; after this our data bank is KERNEL_DATA ; Our stack is now valid and we may use it again, our UDATA ; is for the new process - ldx U_DATA__U_SP ; correct stack pointer + lda f:KERNEL_FAR+U_DATA__U_SP ; correct stack pointer + tax txs + ; Now our stack is valid fix the bank register + + sep #$20 + .a8 + lda #KERNEL_BANK + pha + plb + ldx U_DATA__U_PTAB cpx ptr1 bne switchinfail ; wrong process !! stz _runticks - sep #$20 - .a8 + lda #P_RUNNING sta a:P_TAB__P_STATUS_OFFSET,x ; This will only be needed once we swap, and we will need to @@ -181,6 +224,9 @@ _dofork: lda U_DATA__U_PAGE sta f:KERNEL_CODE_FAR+fork_patch+2 ; source bank (parent) sta f:KERNEL_CODE_FAR+fork_patch_2+1 ; destination udata stash +.if ( KERNEL_BANK ) + sta f:KERNEL_CODE_FAR+fork_patch_3+1 ; destination udata stash +.endif asl a adc #STACK_BANKOFF sta ptr2+1 ; source for S and DP @@ -210,7 +256,7 @@ _dofork: ; Our context is now a valid stack frame so we can save stuff ldx #0 txy - lda #MAP_SIZE ; 64K - udata shadow + lda #MAP_SIZE-1 ; 64K - udata shadow phb fork_patch: mvn 0,0 ; copy the entire bank below the save @@ -219,12 +265,25 @@ fork_patch: lda #U_DATA__TOTALSIZE-1 fork_patch_2: mvn 0,KERNEL_BANK - plb ; back to kernel bank - - ldx ptr2 - ldy ptr3 +.if ( KERNEL_BANK ) + ; + ; For big kernels copy the kstack separately as it's in + ; bank 0 but the C stack and udata are in kernel data. + ; + ldx #kstack_base + lda #$FF +fork_patch_3: + mvn 0,0 +.endif + ; + ; Clone DP and stack between parent and child + ; + ldx ptr2 ; in DP + ldy ptr3 ; in DP lda #$01FF ; DP and stack + mvn 0,0 + plb ; back to corect bank register ; ; Final hairy detail - the child S value needs to be shifted diff --git a/Kernel/platform-v65c816-big/README b/Kernel/platform-v65c816-big/README index cecbb9a8..2bfbee1e 100644 --- a/Kernel/platform-v65c816-big/README +++ b/Kernel/platform-v65c816-big/README @@ -49,13 +49,6 @@ make TODO ---- -- Fix task switching: on big model our udata is in bank 2 and our kstack - ring 0 so we can't save them as single 512 byte xfer but as we know we - won't be using nearly all the 512 bytes of C stack we can save udata and - most of C stack just fine. - See 65c816 port for general notes - Save jmpvec+1/2 in seg 2 on IRQ entry and restore on exit -Optimisations We Need To Do --------------------------------------------------------------- -- Only copy the needed memory when forking, not 64K ? diff --git a/Kernel/platform-v65c816-big/commonmem.s b/Kernel/platform-v65c816-big/commonmem.s index 1fcdcb41..1f25fc48 100644 --- a/Kernel/platform-v65c816-big/commonmem.s +++ b/Kernel/platform-v65c816-big/commonmem.s @@ -6,6 +6,7 @@ .export _ub .export _udata .export kstack_top + .export kstack_base .export kstackc_top .export istack_top .export istackc_top @@ -23,8 +24,8 @@ ; stack and a small CPU stack in the banking ; ; Our current layout is -; [udata][C stack] 256 bytes -; [C stack] 256 +; [udata] ~256 bytes (279 with L2) +; [C stack] 256 (or thereabouts) ; ; There is a separate IRQ DP, stack and C stack. ; @@ -33,6 +34,7 @@ _udata: kstackc_base: .res 512,0 kstackc_top: + ; and our saved area follows this by a copy of kstack ; ; We have a single istack so we can stuff that anywhere we like diff --git a/Kernel/platform-v65c816-big/config.h b/Kernel/platform-v65c816-big/config.h index e64dde5a..48e2c001 100644 --- a/Kernel/platform-v65c816-big/config.h +++ b/Kernel/platform-v65c816-big/config.h @@ -26,8 +26,8 @@ */ #define CONFIG_BANK_65C816 #define KERNEL_BANK 2 -#define MAX_MAPS 125 -#define MAP_SIZE 0xFC00 /* 0-FBFF */ +#define MAX_MAPS 125 +#define MAP_SIZE 0xFB00 /* 0-FAFF */ /* 0xEE because our first bank is 1 and 0xEE + 2 * 1 = 0xF0 */ #define STACK_BANKOFF 0x00 /* 0400-FDFF */ @@ -36,7 +36,7 @@ #define MAPBASE 0x0000 /* We map from 0 */ #define PROGBASE 0x0100 /* also data base */ #define PROGLOAD 0x0100 -#define PROGTOP 0xFC00 /* Top of program. If we fixed a few things we +#define PROGTOP 0xFB00 /* Top of program. If we fixed a few things we could go to FE00 */ #define BOOT_TTY 513 /* Set this to default device for stdio, stderr */ diff --git a/Kernel/platform-v65c816-big/kernel.def b/Kernel/platform-v65c816-big/kernel.def index 338eaa22..b657e536 100644 --- a/Kernel/platform-v65c816-big/kernel.def +++ b/Kernel/platform-v65c816-big/kernel.def @@ -4,7 +4,7 @@ U_DATA .set $0100 ; avoid ZP ; 256+256 (U, kstack copy, k C stack copy) U_DATA__TOTALSIZE .set $0200 -U_DATA_STASH .set $FC00 ; leaves FFxx for vectors and stubs +U_DATA_STASH .set $FB00 ; leaves FFxx for vectors and stubs PROGLOAD .set $0100 ZPBASE .set $0 @@ -21,6 +21,6 @@ STACK_BANKOFF .set $FE ; 0400-FDFF IRQ_DP .set $FF80 ; FF80-FFBF KERNEL_DP .set $00 ; We use the real ZP for kernel DP -MAP_SIZE .set $FC00 +MAP_SIZE .set $FB00 PROGBASE .set $0100 diff --git a/Kernel/platform-v65c816/README b/Kernel/platform-v65c816/README index 2ba03d85..3be44e5c 100644 --- a/Kernel/platform-v65c816/README +++ b/Kernel/platform-v65c816/README @@ -36,7 +36,6 @@ the emulator. TODO ---- -- Test revized brk() checking - Add swap logic - Relocatable binaries - cc65 stubs optimized for 65c816 @@ -48,3 +47,10 @@ TODO Optimisations We Need To Do -------------------------------------------------------------- - Only copy the needed memory when forking, not 64K ? +- Can we keep udata in kernel ZP (at least for level 1). Would need to + audit that we don't take pointers to ZP but might be faster and we + need to do the same audit for some cases with 68K etc anyway +- Can we put the kernel per process CPU stack (kstack) into the upper half + of ZP for each process. We don't need 256 bytes of ZP per process +- Can we trim down to say 64 bytes ZP + 256 stack per process so we can go + above 8MB - do we care ??