From cbf29a595e353e217f30a0de6c50e717e3ae1160 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Apr 2015 22:28:02 +0100 Subject: [PATCH] zx128: initial code for swap on microdrive Wheee... --- Kernel/platform-zx128/config.h | 7 ++++++- Kernel/platform-zx128/devmdv.c | 28 ++++++++++++++++++++++++---- Kernel/platform-zx128/main.c | 4 ++++ Kernel/platform-zx128/microdrive.s | 17 +++++++++++------ Kernel/platform-zx128/zx128.s | 1 + 5 files changed, 46 insertions(+), 11 deletions(-) diff --git a/Kernel/platform-zx128/config.h b/Kernel/platform-zx128/config.h index d13a7231..58f8575b 100644 --- a/Kernel/platform-zx128/config.h +++ b/Kernel/platform-zx128/config.h @@ -65,7 +65,12 @@ #define NUM_DEV_TTY 1 #define TTYDEV BOOT_TTY /* Device used by kernel for messages, panics */ -#undef SWAPDEV /* Do not use swap */ +#define SWAPDEV 2051 /* Microdrive 3 : FIXME - configure and probe */ #define NBUFS 9 /* Number of block buffers */ #define NMOUNTS 4 /* Number of mounts at a time */ #define MAX_BLKDEV 2 /* 2 IDE drives, 1 SD drive */ + +#define SWAPBASE 0x8000 +#define SWAPTOP 0x10000UL +#define SWAP_SIZE 0x40 +#define MAX_SWAPS 3 /* For now */ diff --git a/Kernel/platform-zx128/devmdv.c b/Kernel/platform-zx128/devmdv.c index 17e22cd2..8785a882 100644 --- a/Kernel/platform-zx128/devmdv.c +++ b/Kernel/platform-zx128/devmdv.c @@ -43,22 +43,37 @@ static int mdv_transfer(uint8_t minor, bool is_read, uint8_t rawflag) irqflags_t irq; uint16_t block, nblock; uint8_t on = 0; + uint8_t altbank = 0; /* Using alternate banks ? */ - if (rawflag == 2) - goto bad; if (rawflag == 0) { mdv_buf = udata.u_buf->bf_data; block = udata.u_buf->bf_blk; nblock = 1; mdv_page = 0; - } else { + } else if (rawflag == 1) { /* Direct to user */ if (((uint16_t)udata.u_offset|udata.u_count) & BLKMASK) goto bad; mdv_buf = (uint8_t *)udata.u_base; nblock = udata.u_count >> 9; block = udata.u_offset >> 9; - mdv_page = 1; + mdv_page = udata.u_page; + } else { + /* Microdrive swap awesomeness */ + nblock = swapcnt >> 9; + block = swapblk; + mdv_page = swapproc->p_page; + mdv_buf = swapbase; + + /* Platform specific magic time. We know the swapper + will do I/O to/from "us" (easy) or from the + other process, in which case we need to juggle + banks half way */ + if (swapproc != udata.u_ptab) { + altbank = 1; + mdv_buf = (uint8_t *)0xC000; + mdv_page = 6; /* Switched bank */ + } } irq = di(); @@ -88,6 +103,11 @@ static int mdv_transfer(uint8_t minor, bool is_read, uint8_t rawflag) goto bad; } mdv_buf += 512; + /* Switch bank */ + if (altbank && mdv_buf == 0x0000) { /* Wrapped */ + mdv_page = swapproc->p_page; + mdv_buf = (uint8_t *)0xC000; + } } return 0; bad: diff --git a/Kernel/platform-zx128/main.c b/Kernel/platform-zx128/main.c index ec0c630d..11726950 100644 --- a/Kernel/platform-zx128/main.c +++ b/Kernel/platform-zx128/main.c @@ -12,6 +12,10 @@ void pagemap_init(void) /* The live process also has 2 and the non running one 6 */ pagemap_add(4); pagemap_add(3); + /* Swap */ + swapmap_add(0); + swapmap_add(1); + swapmap_add(2); } /* On idle we spin checking for the terminals. Gives us more responsiveness diff --git a/Kernel/platform-zx128/microdrive.s b/Kernel/platform-zx128/microdrive.s index ffd57732..3e89b85a 100644 --- a/Kernel/platform-zx128/microdrive.s +++ b/Kernel/platform-zx128/microdrive.s @@ -42,6 +42,8 @@ .globl map_process_save .globl map_kernel_restore + .globl current_map + .globl switch_bank .area _COMMONMEM @@ -438,27 +440,30 @@ _mdv_motor_on: pop de ; ZX128. It will break if this ceases to be true. ; _mdv_bread: + ld de, (current_map) ; Current map into e ld a, (_mdv_page) or a + ld a, e ; Save old map push af - call nz, map_process_save - call mdv_fetch + call nz, switch_bank ; Switch if mdv_page set + call mdv_fetch ; Do the I/O mdv_bout: - jr nz, poprete + jr nz, poprete ; Error codes for C xor a poprete: ld l, a xor a ld h, a pop af - call nz, map_kernel_restore + call nz, switch_bank ; Switch bank if needed ret _mdv_bwrite: + ld de, (current_map) ld a, (_mdv_page) or a - push af - call nz, map_process_save + ld a, e + call nz, switch_bank call mdv_store jr mdv_bout diff --git a/Kernel/platform-zx128/zx128.s b/Kernel/platform-zx128/zx128.s index d9328a6a..4aaf070a 100644 --- a/Kernel/platform-zx128/zx128.s +++ b/Kernel/platform-zx128/zx128.s @@ -20,6 +20,7 @@ .globl map_process_save .globl map_kernel_restore .globl current_map + .globl switch_bank .globl _kernel_flag -- 2.34.1