From: Alan Cox Date: Thu, 18 Dec 2014 21:30:05 +0000 (+0000) Subject: mtx; switch to the shared z80 banking code X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=1389d7c385696debe3d51fe6dcbe9baae6a77009;p=FUZIX.git mtx; switch to the shared z80 banking code --- diff --git a/Kernel/platform-mtx/kernel.def b/Kernel/platform-mtx/kernel.def index 6ab70521..4d1aa3ab 100644 --- a/Kernel/platform-mtx/kernel.def +++ b/Kernel/platform-mtx/kernel.def @@ -5,6 +5,8 @@ U_DATA__TOTALSIZE .equ 0x300 ; 256+256+256 bytes. U_DATA_STASH .equ 0xBD00 ; BD00-BFFF +PROG_BASE .equ 0x0000 + NMOS_Z80 .equ 0 VRAM_CH .equ 3 ; font data 0x1800-1BFF ? diff --git a/Kernel/platform-mtx/tricks.s b/Kernel/platform-mtx/tricks.s index e9359d29..ee50c077 100644 --- a/Kernel/platform-mtx/tricks.s +++ b/Kernel/platform-mtx/tricks.s @@ -1,316 +1,5 @@ -; -; This is heavily based on the Z80Pack platform code. -; - .module tricks - .globl _ptab_alloc - .globl _newproc - .globl _chksigs - .globl _getproc - .globl _trap_monitor - .globl trap_illegal - .globl _inint - .globl _switchout - .globl _switchin - .globl _doexec - .globl _dofork - .globl _runticks - .globl unix_syscall_entry - .globl interrupt_handler - .globl dispatch_process_signal - .globl _swapper + .include "../kernel.def" + .include "kernel.def" - .globl map_kernel - .globl map_process - .globl map_process_a - .globl map_process_always - - ; imported debug symbols - .globl outstring, outde, outhl, outbc, outnewline, outchar, outcharhex - - .include "kernel.def" - .include "../kernel.def" - - .area _COMMONMEM - -; Switchout switches out the current process, finds another that is READY, -; possibly the same process, and switches it in. When a process is -; restarted after calling switchout, it thinks it has just returned -; from switchout(). -; -; This function can have no arguments or auto variables. -_switchout: - di - call _chksigs - ; save machine state - - ld hl, #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: - push hl ; return code - push ix - push iy - ld (U_DATA__U_SP), sp ; this is where the SP is restored in _switchin - - ; set inint to false - xor a - ld (_inint), a - - ; Stash the uarea back into process memory - ld hl, (U_DATA__U_PAGE) - call map_process_always - ld hl, #U_DATA - ld de, #U_DATA_STASH - ld bc, #U_DATA__TOTALSIZE - ldir - call map_kernel - - ; find another process to run (may select this one again) - call _getproc - - push hl - call _switchin - - ; we should never get here - call _trap_monitor - -badswitchmsg: .ascii "_switchin: FAIL" - .db 13, 10, 0 -swapped: .ascii "_switchin: SWAPPED" - .db 13, 10, 0 - -_switchin: - di - pop bc ; return address - pop de ; new process pointer -; -; FIXME: do we actually *need* to restore the stack ! -; - push de ; restore stack - push bc ; restore stack - - call map_kernel - - push de - ld hl, #P_TAB__P_PAGE_OFFSET - add hl, de ; process ptr - pop de - - ld a, (hl) - - or a - jr nz, not_swapped - - ; - ; We are still on the departing processes stack, which is - ; fine for now. - ; - ld sp, #_swapstack - push hl - push de - call _swapper - pop de - pop hl - ld a, (hl) -not_swapped: - ; Pages please ! - call map_process_a - - ; bear in mind that the stack will be switched now, so we can't use it - ; to carry values over this point - - exx ; thank goodness for exx 8) - ld hl, #U_DATA_STASH - ld de, #U_DATA - ld bc, #U_DATA__TOTALSIZE - ldir - exx - - call map_kernel - - ; check u_data->u_ptab matches what we wanted - ld hl, (U_DATA__U_PTAB) ; u_data->u_ptab - or a ; clear carry flag - sbc hl, de ; subtract, result will be zero if DE==IX - jr nz, switchinfail - - ; wants optimising up a bit - ld ix, (U_DATA__U_PTAB) - ; next_process->p_status = P_RUNNING - ld P_TAB__P_STATUS_OFFSET(ix), #P_RUNNING - - ; Fix the moved page pointers - ; Just do one byte as that is all we use on this platform - ld a, P_TAB__P_PAGE_OFFSET(ix) - ld (U_DATA__U_PAGE), a - ; runticks = 0 - ld hl, #0 - ld (_runticks), hl - - ; restore machine state -- note we may be returning from either - ; _switchout or _dofork - ld sp, (U_DATA__U_SP) - - pop iy - pop ix - pop hl ; return code - - ; enable interrupts, if the ISR isn't already running - ld a, (_inint) - or a - ret z ; in ISR, leave interrupts off - ei - ret ; return with interrupts on - -switchinfail: - call outhl - ld hl, #badswitchmsg - call outstring - ; something went wrong and we didn't switch in what we asked for - jp _trap_monitor - -fork_proc_ptr: .dw 0 ; (C type is struct p_tab *) -- address of child process p_tab entry - -; -; Called from _fork. We are in a syscall, the uarea is live as the -; parent uarea. The kernel is the mapped object. -; -_dofork: - ; always disconnect the vehicle battery before performing maintenance - di ; should already be the case ... belt and braces. - - pop de ; return address - pop hl ; new process p_tab* - push hl - push de - - ld (fork_proc_ptr), hl - - ; prepare return value in parent process -- HL = p->p_pid; - ld de, #P_TAB__P_PID_OFFSET - add hl, de - ld a, (hl) - inc hl - ld h, (hl) - ld l, a - - ; Save the stack pointer and critical registers. - ; When this process (the parent) is switched back in, it will be as if - ; it returns with the value of the child's pid. - push hl ; HL still has p->p_pid from above, the return value in the parent - push ix - push iy - - ; 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. - ld (U_DATA__U_SP), sp - - ; now we're in a safe state for _switchin to return in the parent - ; process. - - ; Need to write a new 47.25K bank copy here, then copy the live uarea - ; into the stash of the new process - - ; --------- copy process --------- - - ld hl, (fork_proc_ptr) - ld de, #P_TAB__P_PAGE_OFFSET - add hl, de - ; load p_page - ld c, (hl) - ; load existing page ptr - push af - ld a, c - call outcharhex - pop af - ld a, (U_DATA__U_PAGE) - - call bankfork ; do the bank to bank copy - - ; Copy done - - call map_process_always - - ; We are going to copy the uarea into the parents uarea stash - ; we must not touch the parent uarea after this point, any - ; changes only affect the child - ld hl, #U_DATA ; copy the udata from common into the - ld de, #U_DATA_STASH ; target process - ld bc, #U_DATA__TOTALSIZE - ldir - ; Return to the kernel mapping - call map_kernel - - ; now the copy operation is complete we can get rid of the stuff - ; _switchin will be expecting from our copy of the stack. - pop bc - pop bc - pop bc - - ; Make a new process table entry, etc. - ld hl, (fork_proc_ptr) - push hl - call _newproc - pop bc - - ; runticks = 0; - ld hl, #0 - ld (_runticks), hl - ; in the child process, fork() returns zero. - ; - ; 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(). - ret - -; -; This is related so we will keep it here. Copy the process memory -; for a fork. a is the page base of the parent, c of the child -; -; Assumption - fits into a fixed number of whole 256 byte blocks -; -bankfork: -; ld bc, #(0xC000 - 768) ; 48K minus the uarea stash - - ld b, #0xBD ; C0 x 256 minus 3 sets for the uarea stash - ld hl, #0 ; base of memory to fork (vectors included) -bankfork_1: - push bc ; Save our counter and also child offset - push hl - call map_process_a - ld de, #bouncebuffer - ld bc, #256 - ldir ; copy into the bounce buffer - pop de ; recover source of copy to bounce - ; as destination in new bank - pop bc ; recover child page number - push bc - ld b, a ; save the parent bank id - ld a, c ; switch to the child - call map_process_a - push bc ; save the bank pointers - ld hl, #bouncebuffer - ld bc, #256 - ldir ; copy into the child - pop bc ; recover the bank pointers - ex de, hl ; destination is now source for next bank - ld a, b ; parent bank is wanted in a - pop bc - djnz bankfork_1 ; rinse, repeat - ret - -; -; For the moment -; -bouncebuffer: - .ds 256 -; -; We can keep a stack in common because we will complete our -; use of it before we switch common block. In this case we have -; a true common so it's even easier. This can share with the bounce -; buffer used by bankfork as we won't switchin mid way through the -; banked fork() call. -; -_swapstack: + .include "../lib/z80fixedbank.s"