From: Alexander Tsidaev Date: Sat, 22 Nov 2014 22:50:08 +0000 (+0500) Subject: zx128: multitasking support X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=0056693558e0ac56e477cabbbf3efa63ba191cc6;p=FUZIX.git zx128: multitasking support --- diff --git a/Kernel/platform-zx128/config.h b/Kernel/platform-zx128/config.h index 68e75dbd..b31f3b59 100644 --- a/Kernel/platform-zx128/config.h +++ b/Kernel/platform-zx128/config.h @@ -5,9 +5,9 @@ /* Profil syscall support (not yet complete) */ #define CONFIG_PROFIL /* Multiple processes in memory at once */ -#undef CONFIG_MULTI +#define CONFIG_MULTI /* Single tasking */ -#define CONFIG_SINGLETASK +#undef CONFIG_SINGLETASK /* CP/M emulation */ #undef CONFIG_CPM_EMU @@ -44,7 +44,7 @@ #define UDATA_BLOCKS 0 /* We swap the stash not the uarea */ #define UDATA_SWAPSIZE 0 -#define BOOT_TTY (512+1) /* Set this to default device for stdio, stderr */ +#define BOOT_TTY (1) /* Set this to default device for stdio, stderr */ /* In this case, the default is the first TTY device */ /* We need a tidier way to do this from the loader */ diff --git a/Kernel/platform-zx128/crt0.s b/Kernel/platform-zx128/crt0.s index daa1335b..181eb0c3 100644 --- a/Kernel/platform-zx128/crt0.s +++ b/Kernel/platform-zx128/crt0.s @@ -7,12 +7,13 @@ ; we don't use them all, because their ordering is set ; when they are first seen. .area _CODE + .area _COMMONMEM + .area _DATA .area _CODE2 .area _VIDEO .area _DISCARD ; not discarded yet .area _CONST .area _FONT - .area _DATA .area _INITIALIZED .area _BSEG .area _BSS @@ -22,7 +23,6 @@ .area _INITIALIZER .area _GSINIT .area _GSFINAL - .area _COMMONMEM ; imported symbols .globl _fuzix_main @@ -43,6 +43,7 @@ ; startup code .area _CODE init: + jp 0x003 ; workaround for lowlevel-z80.s check for C3 at 0000 di ; if any button is pressed during reset - boot BASIC48 @@ -67,7 +68,7 @@ jump_to_basic_start: jump_to_basic_end: ; spacer - .ds 0x0E + .ds 0x0B ; .org 0x0030 ; syscall entry jp unix_syscall_entry @@ -91,11 +92,9 @@ init_continue: ; Configure memory map call init_early - ; move the common memory where it belongs - ld hl, #s__INITIALIZER - ld de, #s__COMMONMEM - ld bc, #l__COMMONMEM - ldir + ; our COMMONMEM is located in main code-data blob, so we + ; do not need to move it manually + ; then zero the data area ld hl, #s__DATA ld de, #s__DATA + 1 diff --git a/Kernel/platform-zx128/kernel.def b/Kernel/platform-zx128/kernel.def index b28696fb..9c1a2049 100644 --- a/Kernel/platform-zx128/kernel.def +++ b/Kernel/platform-zx128/kernel.def @@ -1,6 +1,6 @@ ; UZI mnemonics for memory addresses etc -U_DATA .equ 0xF000 ; (this is struct u_data from kernel.h) +U_DATA .equ 0x5B00 ; (this is struct u_data from kernel.h) U_DATA__TOTALSIZE .equ 0x300 ; 256+256+256 bytes. -U_DATA_STASH .equ 0xED00 ; BD00-BFFF \ No newline at end of file +U_DATA_STASH .equ 0xFD00 ; BD00-BFFF \ No newline at end of file diff --git a/Kernel/platform-zx128/main.c b/Kernel/platform-zx128/main.c index 79c9de0b..08e831fc 100644 --- a/Kernel/platform-zx128/main.c +++ b/Kernel/platform-zx128/main.c @@ -6,12 +6,12 @@ uint16_t ramtop = PROGTOP; - void pagemap_init(void) { - int i; - for (i = 1; i < 8; i++) - pagemap_add(i); + uint8_t pages[] = { 1, 3, 4, 6, 7 }; + uint8_t i; + for (i = 0; i < sizeof(pages); i++) + pagemap_add(i); } /* The uarea is already synched to the stash which is written with the diff --git a/Kernel/platform-zx128/tricks.s b/Kernel/platform-zx128/tricks.s index 72c5537a..c290a27d 100644 --- a/Kernel/platform-zx128/tricks.s +++ b/Kernel/platform-zx128/tricks.s @@ -36,7 +36,6 @@ ; ; This function can have no arguments or auto variables. _switchout: - ret di call _chksigs ; save machine state @@ -56,13 +55,15 @@ _switchout: ; Stash the uarea back into process memory ld hl, (U_DATA__U_PAGE) ld a, l - out (21), a + ld bc, #0x7ffd + out (c), a ld hl, #U_DATA ld de, #U_DATA_STASH ld bc, #U_DATA__TOTALSIZE ldir xor a - out (21), a + ld bc, #0x7ffd + out (c), a ; find another process to run (may select this one again) call _getproc @@ -79,7 +80,6 @@ swapped: .ascii "_switchin: SWAPPED" .db 13, 10, 0 _switchin: - ret di pop bc ; return address pop de ; new process pointer @@ -90,7 +90,8 @@ _switchin: push bc ; restore stack xor a - out (21), a + ld bc, #0x7ffd + out (c), a push de ld hl, #P_TAB__P_PAGE_OFFSET @@ -98,9 +99,8 @@ _switchin: pop de ld a, (hl) - ; Pages please ! - out (21), a + out (c), a ; BC still contains 0x7ffd ; bear in mind that the stack will be switched now, so we can't use it ; to carry values over this point @@ -113,7 +113,7 @@ _switchin: exx xor a - out (21), a + out (c), a ; and again 0x7ffd in BC ; check u_data->u_ptab matches what we wanted ld hl, (U_DATA__U_PTAB) ; u_data->u_ptab @@ -197,7 +197,7 @@ _dofork: ; 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 + ; Need to write a new 16K bank copy here, then copy the live uarea ; into the stash of the new process ; --------- copy process --------- @@ -216,7 +216,8 @@ _dofork: ld hl, (U_DATA__U_PAGE) ; parent memory ld a, l - out (21), a ; Switch context to parent + ld bc, #0x7ffd + out (c), a ; Switch context to parent ; We are going to copy the uarea into the parents uarea stash ; we must not touch the parent uarea after this point, any @@ -225,8 +226,10 @@ _dofork: ld de, #U_DATA_STASH ; target process ld bc, #U_DATA__TOTALSIZE ldir + + ld bc, #0x7ffd xor a - out (21), a + out (c), a ; 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 @@ -265,14 +268,15 @@ _swapstack: ; Assumption - fits into a fixed number of whole 256 byte blocks ; bankfork: -; ld bc, #(0xC000 - 768) ; 48K minus the uarea stash +; ld bc, #(0x4000 - 768) ; 16K 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) + ld b, #0x3D ; 40 x 256 minus 3 sets for the uarea stash + ld hl, #0xC000 ; base of memory to fork (vectors included) bankfork_1: push bc ; Save our counter and also child offset push hl - out (21), a ; switch to parent bank + ld bc, #0x7ffd + out (c), a ; switch to parent bank ld de, #bouncebuffer ld bc, #256 ldir ; copy into the bounce buffer @@ -282,8 +286,9 @@ bankfork_1: push bc ld b, a ; save the parent bank id ld a, c ; switch to the child - out (21), a push bc ; save the bank pointers + ld bc, #0x7ffd + out (c), a ld hl, #bouncebuffer ld bc, #256 ldir ; copy into the child diff --git a/Kernel/platform-zx128/uzi.lnk b/Kernel/platform-zx128/uzi.lnk index 506980d0..fb55a5e9 100644 --- a/Kernel/platform-zx128/uzi.lnk +++ b/Kernel/platform-zx128/uzi.lnk @@ -1,14 +1,14 @@ -mwxuy -i uzi.ihx -b _CODE=0x0000 --b _CODE2=0x5B00 --b _COMMONMEM=0xF000 +-b _COMMONMEM=0x5B00 -l z80 platform-zx128/crt0.rel platform-zx128/commonmem.rel platform-zx128/zx128.rel platform-zx128/zxvideo.rel platform-zx128/main.rel +platform-zx128/devfd.rel start.rel version.rel lowlevel-z80.rel diff --git a/Kernel/platform-zx128/zx128.s b/Kernel/platform-zx128/zx128.s index 766ee4e6..eb45dcd9 100644 --- a/Kernel/platform-zx128/zx128.s +++ b/Kernel/platform-zx128/zx128.s @@ -16,7 +16,6 @@ .globl init_early .globl init_hardware .globl _program_vectors - .globl _system_tick_counter .globl platform_interrupt_all .globl map_kernel @@ -25,9 +24,8 @@ .globl map_save .globl map_restore - .globl _kernel_flag - .globl _fd_bankcmd + .globl _kernel_flag ; exported debugging tools .globl _trap_monitor @@ -91,6 +89,7 @@ _fd_bankcmd: init_early: ld bc, #0x7ffd xor a + ld (current_map), a out (c), a ; set page 0 at 0xC000 ret @@ -105,10 +104,10 @@ init_hardware: ; clear ld hl, #0x4000 ld de, #0x4001 - ld bc, #0x1800 - xor a - ld (hl), a - ldir + ld bc, #0x1800 ; There should be 0x17FF, but we are going + xor a ; to copy additional byte to avoid need of + ld (hl), a ; DE and HL increment before attribute + ldir ; initialization (2 bytes of RAM economy) ; set color attributes ld a, #7 ; black paper, white ink @@ -128,50 +127,73 @@ init_hardware: _program_vectors: ret - ; below is code which was copied from z80pack, so it's useless for zx128 + ; bank switching procedure. On entrance: + ; A - bank number to set +switch_bank: + di ; TODO: we need to call di() instead + ld (current_map), a + ld a, b + ld (place_for_b), a + ld a, c + ld (place_for_c), a + ld bc, #0x7ffd + ld a, (current_map) + out (c), a + ld a, (place_for_b) + ld b, a + ld a, (place_for_c) + ld c, a + ld a, (place_for_a) + ei + ret + map_kernel: - push af + ld (place_for_a), a +map_kernel_nosavea: ; to avoid double reg A saving xor a - ; out (21), a - pop af - ret + jr switch_bank map_process: + ld (place_for_a), a ld a, h or l - jr z, map_kernel + jr z, map_kernel_nosavea ld a, (hl) - ; out (21), a - ret + jr switch_bank map_process_always: - push af + ld (place_for_a), a ld a, (U_DATA__U_PAGE) - ; out (21), a - pop af - ret + jr switch_bank map_save: - push af - in a, (21) + ld (place_for_a), a + ld a, (current_map) ld (map_store), a - pop af + ld a, (place_for_a) ret map_restore: - push af + ld (place_for_a), a ld a, (map_store) - ; out (21), a - pop af - ret + jr switch_bank +current_map: ; place to store current page number. Is needed + .db 0 ; because we have no ability to read 7ffd port + ; to detect what page is mapped currently map_store: .db 0 +place_for_a: ; When change mapping we can not use stack since it is located at the end of banked area. + .db 0 ; Here we store A when needed +place_for_b: ; And BC - here + .db 0 +place_for_c: + .db 0 + ; outchar: TODO: add something here (char in A). Current port #15 is emulator stub outchar: out (#0x15), A ret - _kernel_flag: - .db 1 + .db 1 \ No newline at end of file