From: Alan Cox Date: Sat, 11 Apr 2015 14:17:59 +0000 (+0100) Subject: zx128: kick out the experimental betadisk hacks X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=05d14352f7f682cde7d5f722387da8aebe1ae519;p=FUZIX.git zx128: kick out the experimental betadisk hacks They cost us to much in memory layout and hassle and at best will be very brittle. Instead we'll need a Betadisk with suitable rom hooks added (or already present ?) --- diff --git a/Kernel/platform-zx128/betadisk.s b/Kernel/platform-zx128/betadisk.s deleted file mode 100644 index 37de5745..00000000 --- a/Kernel/platform-zx128/betadisk.s +++ /dev/null @@ -1,261 +0,0 @@ -; -; Interface glue for the beta disk. -; -; This is a work in progress. The betadisk is only accessible when the -; built in ROM is mapped. It unmaps itself when we return to RAM. It -; has a sort of "BIOS" type ABI but that assumes we are in ZX Basic -; and also screws around with memory behind the caller. -; -; So we have to do things differently. Instead we treat the TR-DOS 5 -; ROM as a ROP exploit target. -; -; This is a WIP and assumes the TR-DOS v5 ROM -; - - .module betadisk - - .globl _betadev, _betaaddr, _betasector, _betatrack - .globl _betauser, _betacount - - .globl _trdos_init, _trdos_read, _trdos_write - - .globl map_process_save, map_kernel_restore - - .globl outhl - - .area _COMMONDATA -; -; Ordering matters as we load some as pairs -; -_betadev: .db 0 ; disk number -_betaaddr: .dw 0 ; buffer ptr -_betasector: .db 0 ; sector (1 based) -_betatrack: .db 0 ; track (low bit is side) -_betauser: .db 0 ; paging info -_betacount: .db 0 ; count of blocks -_betacmd: .db 0 ; command byte -_betatrackreg: .db 0 ; used to track h/w -saved_sp: .dw 0 ; stack for unwinds -saved_hl: .dw 0 ; HL for trdos entry - - .area _COMMONMEM - -_trdos_read: - ld a, #0x80 - ld (_betacmd), a -trdos_op: - ld bc, (_betasector) - call seekhead - jr nz, error - ld a, (_betauser) - or a - push af - call z, map_process_save - call trdos_doit - pop af - call z, map_kernel_restore - ld h, b - ld c, l - ret -error: - ld hl, #-1 - ret - -_trdos_write: - ld a, #0xA0 - ld (_betacmd), a - jr trdos_op - - -; -; Head is on the right track, density is right, drive is right -; -trdos_doit: - ld hl, (_betaaddr) - ld a, (_betacmd) - cp #0x80 - jr nz, dowrite - call write_cmd_delay - call wait_drq_and_read - call read_status - ret -dowrite: call write_cmd_delay - call wait_drq_and_write - call read_status - ; Check status - ret - - -; -; Hook into the ROM to issue a reset and seek to 0 -; -trdos_reset: - ; Set the frame up for the exception path - push bc - push de - ld (saved_sp), sp - ld hl, #0x3d98 - call trdos_call - xor a - ; We can't easily read the real register so shadow it - ld (_betatrackreg), a - pop de - pop bc - ret - -; -; Drive head and seek management. Assumes track register is -; correctly loaded -; -seekhead: - ld a, (_betadev) - or #0x24 ; MFM, don't reset - ld b, a - ld a, (_betatrack) - or a - rra - jr c, topside - ; bottom - set 3,b -topside: - ld (_betatrack), a - ld a, b - call trdos_outsys ; Select the drive/side - - ; need delays on the various side/disk switches - ; check if need to seek - call trdos_outdata -; call nap - ld a, #0x18 ; head load, 6ms - ld hl, #0x2f57 ; issue command, wait for INT - call trdos_call - call read_status - ; Check status - save new value - ret -; -; Arbitrary code execution in the TRDOS ROM -; -trdos_call: push hl - ld hl, (saved_hl) - jp 0x3D2F - -; -; An entry point that writes A to the command register and returns -; -trdos_outctrl: ld hl, #0x2fc3 - call trdos_call - ret -; -; An entry point that writes A into the track register and returns -; -trdos_outtrk: push hl - ld hl, #0x1e3a - call trdos_call - pop hl - ret -; -; Write A into the interface control register -; -trdos_outsys: push hl - ld hl,#0x1ff3 - call trdos_call - pop hl - ret -; -; Write the other registers via 0x20B8 -; -trdos_outsec: push bc - push de - push hl - ld bc, #0x015F -; -; Write D into register C B times -; -trdos_outit: - ld d, a - ld hl, #0x20B8 - call trdos_call - pop hl - pop de - pop bc - ret - -trdos_outdata: push bc - push de - push hl - ld bc, #0x017F - jr trdos_outit - -; -; Low level I/O routines we can borrow -; - -wait_drq_and_read: - ld (saved_hl), hl - ld hl, #0x3fd5 - call trdos_call - ret - -wait_drq_and_write: - ld (saved_hl), hl - ld hl, #0x3fba - call trdos_call - ret - -write_cmd_delay: - push hl - ld hl, #0x2f57 - call trdos_call - pop hl - ret - -; -; This is a somewhat evil dive into the middle of some code which in -; some cases will attempt to jump back into BASIC. We catch it trying -; to do so on errors and longjmp out of it. -; -read_status: - push bc - push de - ld (saved_sp), sp - ld d, #1 - xor a - ld (0x5d15), a - dec a - ld (0x5d0e), a - ld hl, #0x3f33 - call trdos_call -unwind: - ; b now holds status - ld l, b - ld h, #0 - pop de - pop bc - ret - -; -; TRDOS tried to print an error message. Grab it as it tries to -; go to the BASIC ROM and instead recover our stack and return an -; error -; -_trdos_exception: - pop hl - ld a, l - cp #0x54 ; checking break key - jr z, cbreak - ld sp, (saved_sp) - jr unwind -cbreak: - scf ; no break (make timer based) - ret - - -; -; Interceptor for ROM -; -_trdos_init: - ld a, #0xc3 - ld (0x5cc2), a - ld hl, #_trdos_exception - ld (0x5cc3), hl - ret diff --git a/Kernel/platform-zx128/devbeta.c b/Kernel/platform-zx128/devbeta.c deleted file mode 100644 index 910dbd62..00000000 --- a/Kernel/platform-zx128/devbeta.c +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include -#include -#include - -#define MAX_FD 4 - -static uint8_t lastdisc = 0xFF; - -/* - * First cut at a beta driver. This uses the ROM entry points as the - * beta has a design where you can't access the disk except with the - * ROM paged in. - * - * We treat the ROM as a set of pieces to build a ROP type exploit. - * - * Note: the ROM has 39xx all set to 0xFF which means that we can - * continue to take interrupts with this ROM paged in as we'll read - * 0xFFFF and then take the vector as JR xx (where 0000 is still 0xF3 - * as this rom also starts with a DI). - */ - -static int beta_transfer(uint8_t minor, bool is_read, uint8_t rawflag) -{ - blkno_t block; - uint16_t ret; - - if(rawflag == 2) - goto bad2; - - /* Select the right disc */ - - if (lastdisc != minor) { - betadev = minor; - if (trdos_init()) - goto bad2; - lastdisc = minor; - } - - /* 16 sectors/track, 40 or 80 tracks but the interface expects logical - tracks 0-n alternating sides. 256 bytes/sector always */ - - if (rawflag == 0) { - betaaddr = (uint16_t)udata.u_buf->bf_data; - block = udata.u_buf->bf_blk; - betacount = 2; - } else { - if (((uint16_t)udata.u_offset|udata.u_count) & BLKMASK) - goto bad2; - betaaddr = (uint16_t)udata.u_base; - block = udata.u_offset >> 9; - betacount = udata.u_count >> 8; - } - betasector = ((block >> 5) & 0x0F) + 1; - betatrack = block >> 5; - betauser = rawflag; - betadev = minor; - di(); - if (is_read) - ret = trdos_read(); - else - ret = trdos_write(); - ei(); - if (ret == 0) - return betacount >> 1; - kprintf("bfd%d: error %d\n", ret); -bad2: - udata.u_error = EIO; - return -1; -} - -/* FIXME: how do we detect beta is present sanely ? */ -int beta_open(uint8_t minor, uint16_t flag) -{ - int ret; - - flag; - - if(minor >= MAX_FD) { - udata.u_error = ENODEV; - return -1; - } - betadev = minor; - - /* Stop the TR-DOS code trying to make workspaces and crap into - basic by putting its 'initialized' token into place */ - *(uint8_t *)0x5CB6 = 0xF4; - *(uint8_t *)0x5D16 = 0x00; /*FIXME: syscfg bits */ - - ret = trdos_init(); - - if (ret) { - udata.u_error = EIO; - lastdisc = 0xFF; - return -1; - } - lastdisc = minor; - return 0; -} - -int beta_read(uint8_t minor, uint8_t rawflag, uint8_t flag) -{ - flag; - return beta_transfer(minor, true, rawflag); -} - -int beta_write(uint8_t minor, uint8_t rawflag, uint8_t flag) -{ - flag; - return beta_transfer(minor, false, rawflag); -} diff --git a/Kernel/platform-zx128/fuzix.lnk b/Kernel/platform-zx128/fuzix.lnk index b95607c2..5f6295f2 100644 --- a/Kernel/platform-zx128/fuzix.lnk +++ b/Kernel/platform-zx128/fuzix.lnk @@ -6,7 +6,6 @@ -b _CODE2=0xC000 -b _CODE3=0xDB00 -b _DISCARD=0x8000 --b _DATA=0x5E00 platform-zx128/crt0.rel platform-zx128/commonmem.rel platform-zx128/zx128.rel