From 97a5b4136ed32d63b8cc9582a9c43233294f6579 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 10 Jan 2015 18:33:59 +0000 Subject: [PATCH] tgl6502: start fleshing out the 6502 version of tricks.s --- Kernel/platform-tgl6502/tricks.s | 181 ++++++++++++++++++++----------- 1 file changed, 120 insertions(+), 61 deletions(-) diff --git a/Kernel/platform-tgl6502/tricks.s b/Kernel/platform-tgl6502/tricks.s index a43fff23..e46813e9 100644 --- a/Kernel/platform-tgl6502/tricks.s +++ b/Kernel/platform-tgl6502/tricks.s @@ -9,8 +9,16 @@ .import _chksigs .import _trap_monitor + .import _newproc + .import _getproc + .import _runticks + .import _inint + .import outstring + .import outcharhex + .include "kernel.def" .include "../kernel02.def" + .include "zeropage.inc" .segment "COMMONMEM" @@ -33,69 +41,89 @@ _switchout: jsr _chksigs ; -; ; save machine state -; ldd #0 ; return code set here is ignored, but _switchin can -; ; return from either _switchout OR _dofork, so they must both write -; ; U_DATA__U_SP with the following on the stack: -; pshs d -; sts U_DATA__U_SP -; -; ; set inint to false -; lda #0 -; sta _inint +; Put the C stack on the CPU stack, and store that in U_SP ; -; ; find another process to run (may select this one again) returns it -; ; in X -; jsr _getproc + lda #0 ; return code + pha + pha + lda sp ; C stack + pha + lda sp+1 + pha + tsx + stx U_DATA__U_SP ; Save it + + ; set inint to false + lda #0 + sta _inint + + ; find another process to run (may select this one again) returns it + ; in x,a + jsr _getproc jsr _switchin ; we should never get here jsr _trap_monitor badswitchmsg: .asciiz "_switchin: FAIL\r\n" -; new process pointer is in X -_switchin: -; orcc #0x10 ; irq off ; -; ldy P_TAB__P_PAGE_OFFSET+3,x -; ; FIXME: can we skip the usermaps here ? -; stx 0xffa6 ; map the process uarea we want -; adda #1 -; stx 0xffa7 -; stx 0xffaf ; and include the kernel mapping +; Fixme: pull the C argument off into x,a ; +_switchin: + sei + sta ptr1 + stx ptr1+1 + ldy #P_TAB__P_PAGE_OFFSET + lda (ptr1),y + sta $FF8A ; switches zero page, stack memory area + ; ------- No stack ------- + ; check u_data->u_ptab matches what we wanted -; cmpx U_DATA__U_PTAB -; bne switchinfail -; - ; wants optimising up a bit -; lda #P_RUNNING -; sta P_TAB__P_STATUS_OFFSET,x + lda U_DATA__U_PTAB + cmp ptr1 + bne switchinfail + lda U_DATA__U_PTAB+1 + cmp ptr1+1 + bne switchinfail + + lda #P_RUNNING + ldy #P_TAB__P_STATUS_OFFSET + sta (ptr1),y -; lda #0 -; sta _runticks + lda #0 + sta _runticks + sta _runticks+1 ; restore machine state -- note we may be returning from either ; _switchout or _dofork -; lds U_DATA__U_SP - -; puls x ; return code - - ; enable interrupts, if the ISR isn't already running -; lda _inint -; beq swtchdone ; in ISR, leave interrupts off -; andcc #0xef -;swtchdone: -; rts + ldx U_DATA__U_SP + txs + pla + sta sp+1 + pla + sta sp + lda _inint + beq swtchdone ; in ISR, leave interrupts off + cli +swtchdone: + pla ; Return code + tax + pla + rts switchinfail: -; jsr outx -; ldx #badswitchmsg -; jsr outstring -; ; something went wrong and we didn't switch in what we asked for -; jmp _trap_monitor - + lda ptr1 + jsr outcharhex + lda ptr1+1 + jsr outcharhex + lda #badswitchmsg + jsr outstring + ; something went wrong and we didn't switch in what we asked for + jmp _trap_monitor + +; FIXME: put this in ZP ? fork_proc_ptr: .word 0 ; (C type is struct p_tab *) -- address of child process p_tab entry ; @@ -104,23 +132,37 @@ fork_proc_ptr: .word 0 ; (C type is struct p_tab *) -- address of child process ; _dofork: ; ; always disconnect the vehicle battery before performing maintenance -; orcc #0x10 ; should already be the case ... belt and braces. + sei ; should already be the case ... belt and braces. ; new process in X, get parent pid into y -; stx fork_proc_ptr -; ldy P_TAB__P_PID_OFFSET,x + sta fork_proc_ptr + stx fork_proc_ptr+1 + + ldy #P_TAB__P_PID_OFFSET + sta ptr1 + stx ptr1+1 ; Save the stack pointer and critical registers. + ; 6502 at least doesn't have too many of those 8) + ; When this process (the parent) is switched back in, it will be as if ; it returns with the value of the child's pid. -; pshs y ; y has p->p_pid from above, the return value in the parent + lda (ptr1),y + pha + iny + lda (ptr1),y + pha ; save kernel stack pointer -- when it comes back in the parent we'll be in ; _switchin which will immediately return (appearing to be _dofork() - ; returning) and with HL (ie return code) containing the child PID. - ; Hurray. - ; sts U_DATA__U_SP + ; returning) the child PID. + lda sp + pha + lda sp+1 + pha + tsx + stx U_DATA__U_SP ; now we're in a safe state for _switchin to return in the parent ; process. @@ -129,25 +171,42 @@ _dofork: ; jsr fork_copy ; copy 0x000 to udata.u_top and the ; uarea and return on the childs ; common + + + lda U_DATA__U_PAGE + sta $FF8A ; switch to child and child stack + ; and zero page etc + ; We are now in the kernel child context ; now the copy operation is complete we can get rid of the stuff - ; _switchin will be expecting from our copy of the stack. -; puls y - -; ldx fork_proc_ptr -; jsr _newproc + ; _switchin will be expecting from our copy of the stack. + pla + pla + pla + pla + + lda fork_proc_ptr + ldx fork_proc_ptr+1 +; +; FIXME: turn these into a C argument! +; + jsr _newproc ; any calls to map process will now map the childs memory ; runticks = 0; -; clr _runticks + lda #0 + sta _runticks + sta _runticks+1 + ; in the child process, fork() returns zero. - ; + tax + ; And we exit, with the kernel mapped, the child now being deemed ; to be the live uarea. The parent is frozen in time and space as ; if it had done a switchout(). -; rts + rts fork_copy: ; ldd U_DATA__U_TOP -- 2.34.1