From 620d4708399f87ab207b3e115ae5778c84273b23 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 13 Feb 2015 21:34:51 +0000 Subject: [PATCH] zx128: update the microdrive code Move it to device 8 so we can put real floppy controllers at zero. This is still read only, and still somewhat silly but who cares. --- Kernel/platform-zx128/devices.c | 13 ++-- Kernel/platform-zx128/devmdv.c | 40 +++++++--- Kernel/platform-zx128/microdrive.s | 115 ++++------------------------- 3 files changed, 53 insertions(+), 115 deletions(-) diff --git a/Kernel/platform-zx128/devices.c b/Kernel/platform-zx128/devices.c index 8194867b..ed4d9643 100644 --- a/Kernel/platform-zx128/devices.c +++ b/Kernel/platform-zx128/devices.c @@ -10,12 +10,8 @@ struct devsw dev_tab[] = /* The device driver switch table */ { -#ifdef CONFIG_MDV - /* 0: /dev/fd Floppy disc block devices, or microdrive etc */ - { mdv_open, mdv_close, mdv_read, mdv_write, no_ioctl }, -#else + /* 0: /dev/fd Floppy disc block devices */ { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, -#endif #ifdef CONFIG_IDE /* 1: /dev/hd Hard disc block devices */ { blkdev_open, no_close, blkdev_read, blkdev_write, blkdev_ioctl }, @@ -28,7 +24,12 @@ struct devsw dev_tab[] = /* The device driver switch table */ { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, /* 4: /dev/mem etc System devices (one offs) */ { no_open, no_close, sys_read, sys_write, sys_ioctl }, - /* Pack to 7 with nxio if adding private devices and start at 8 */ + /* 5: Pack to 7 with nxio if adding private devices and start at 8 */ + { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + { no_open, no_close, no_rdwr, no_rdwr, no_ioctl }, + /* 8: /dev/mdv Microdrive */ + { mdv_open, mdv_close, mdv_read, mdv_write, no_ioctl }, }; bool validdev(uint16_t dev) diff --git a/Kernel/platform-zx128/devmdv.c b/Kernel/platform-zx128/devmdv.c index c94f0896..73533c45 100644 --- a/Kernel/platform-zx128/devmdv.c +++ b/Kernel/platform-zx128/devmdv.c @@ -21,26 +21,44 @@ uint8_t mdv_sector; uint8_t *mdv_buf; uint8_t mdv_hdr_buf[15]; uint16_t mdv_len; +uint8_t mdv_page; static int mdv_transfer(uint8_t minor, bool is_read, uint8_t rawflag) { int err; irqflags_t irq; + uint16_t block, nblock; - if (rawflag) + 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 { + /* Direct to user */ + if ((udata.u_offset|udata.u_count) & 0x1FF) + goto bad; + mdv_buf = (uint8_t *)udata.u_buf->bf_blk; + nblock = udata.u_count >> 9; + block = udata.u_offset >> 9; + mdv_page = 1; + } mdv_motor_on(minor + 1); - /* FIXME: support swap ? */ - mdv_sector = mdvmap[minor][udata.u_buf->bf_blk]; - mdv_buf = udata.u_buf->bf_data; - irq = di(); - if (is_read) - err = mdv_bread(); - else - err = mdv_bwrite(); - irqrestore(irq); + while(nblock--) { + mdv_sector = mdvmap[minor][block++]; + irq = di(); + if (is_read) + err = mdv_bread(); + else + err = mdv_bwrite(); + irqrestore(irq); + mdv_buf += 512; + } + /* Should be timer based for the motor */ mdv_motor_off(); return 0; bad: @@ -75,6 +93,7 @@ int mdv_open(uint8_t minor, uint16_t flag) t = tmpbuf(); mdv_buf = t; mdv_sector = 1; + mdv_page = 0; err = mdv_bread(); if (err) { mdv_sector = 128; @@ -87,6 +106,7 @@ int mdv_open(uint8_t minor, uint16_t flag) } kprintf("mdv_open: had to use secondary map\n"); } + memcpy(mdvmap[minor], t, 256); brelse(t); mdv_valid |= 1 << minor; mdv_motor_off(); diff --git a/Kernel/platform-zx128/microdrive.s b/Kernel/platform-zx128/microdrive.s index 462c240e..edaed41e 100644 --- a/Kernel/platform-zx128/microdrive.s +++ b/Kernel/platform-zx128/microdrive.s @@ -26,25 +26,22 @@ .globl _mdv_motor_off .globl _mdv_bread .globl _mdv_bwrite - .globl mdv_boot ; imports .globl _mdv_sector .globl _mdv_buf .globl _mdv_hdr_buf .globl _mdv_len + .globl _mdv_page + .globl map_process_save + .globl map_kernel_restore -; -; Temporary 512 byte buffer used during boot only -; -MDV_BOOT_BUF .equ 0xB000 + .area _COMMONMEM SECTORID .equ 0x08 ; FIXME - set real format up! CSUM .equ 0x0E ; FIXME ditto - .area _CODE - nap_1ms: push de ld de, #87 jr napl @@ -223,7 +220,6 @@ mdv_find_hdr_bad: jr nz, mdv_find_hdr_next or a ; will be > 0 ret ; NZ - ; ; Load the data for a microdrive block. It's assumed you just found ; the right header then called this @@ -344,22 +340,33 @@ ret0: ; ; int mdv_motor_on(uint8_t drive) ; -_mdv_motor_on: pop hl +_mdv_motor_on: pop de + pop hl pop af push af push hl + push de call mdv_motor jr ret0 ; ; int mdv_read(void) ; mdv_sector and mdv_buf have been set up ready ; +; This relies on the fact data is effectively common space on the +; ZX128. It will break if this ceases to be true. +; _mdv_bread: + ld a, (_mdv_page) + or a + push af + call z, map_process_save call mdv_fetch jr z, ret0 ld l, a xor a ld h, a + pop af + call z, map_kernel_restore ret _mdv_bwrite: @@ -367,93 +374,3 @@ _mdv_bwrite: ret -; -; Bootstrap logic. This is used when the cartridge powers up -; in order to load the rest of the kernel from the boot microdrive -; Interrupts are off, stack is valid. We don't check if the tape -; causes a stack overwrite, that's operator error! - -mdv_boot: -; -; Spin up the boot volume -; - ld hl, #MDV_BOOT_BUF - ld (_mdv_buf), hl - ld a, #1 - out (0xfe), a ; blue - call mdv_motor - ld hl, #1024 ; 4 trips round the tape -mdv_boot_loop: - push hl -; -; Each loop we fetch a block and if its an 'FK' block then we -; load it into RAM at the given offset for 512 bytes. We assume that -; the mdv is created with sufficient interleave we can keep pulling -; the next block ok -; - call mdv_get_hdr - jr nz, mdv_bad - call mdv_get_blk - jr nz, mdv_bad - ld ix, #_mdv_hdr_buf - ld a, #'F' ; magic for kernel blocks - cp 4(ix) - jr nz, not_fk - ld a, #'K' - cp 5(ix) - jr nz, not_fk - ld hl, #0x5800 ; attribute memory - ld d, #0 - ld e, 1(ix) - add hl, de - ld (hl), #0x1f - inc hl - ld (hl), #0x1f -; -; We may ldir over _mdv_hdr_buf so do the attributes then -; follow up with the block copy -; - ld a, 1(ix) - out (0xfe), a ; loading stripes - ld d, a ; high byte of address - ld e, #0 - ld hl, #MDV_BOOT_BUF - ld bc, #512 - ldir - call done_all ; check if we are complete - jr z, mdv_boot_done - ld hl, #MDV_BOOT_BUF ; we may have reloaded over this - ld (_mdv_buf), hl -not_fk: pop hl - dec hl - ld a, h - or l - jr nz, mdv_boot_loop -mdv_fail: ld a, #2 - out (0xfe), a ; red border -failed: jr failed - -mdv_bad: cp #3 - jr z, mdv_fail ; give up return - jr not_fk - -mdv_boot_done: - xor a - out (0xFE), a - ret - -done_all: ld hl, #0x585B ; check data is loaded - ld b, #0x44 - ld a, #0x1f -done_1: cp (hl) - ret nz - inc hl - djnz done_1 - ld hl, #0x58C0 ; and code - ld b, #0x3f -done_2: cp (hl) - ret nz - inc hl - djnz done_2 - ret ; Z - -- 2.34.1