From d096f430a5eeb90c006237ae7e73e0879490b5fd Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 21 Dec 2014 21:58:01 +0000 Subject: [PATCH] ubee: Further floppy driver bashing 512 bytes/sector, double sided Also set the step to 6ms --- Kernel/platform-ubee/devfd.c | 42 ++++++------- Kernel/platform-ubee/floppy.s | 113 +++++++++++++++------------------- 2 files changed, 67 insertions(+), 88 deletions(-) diff --git a/Kernel/platform-ubee/devfd.c b/Kernel/platform-ubee/devfd.c index 37d94c89..3eba9ae8 100644 --- a/Kernel/platform-ubee/devfd.c +++ b/Kernel/platform-ubee/devfd.c @@ -9,8 +9,8 @@ #define OPDIR_READ 1 #define OPDIR_WRITE 2 -#define FD_READ 0x80 /* 2797 needs 0x88, 1797 needs 0x80 */ -#define FD_WRITE 0xA0 /* Likewise A8 v A0 */ +#define FD_READ 0x80 +#define FD_WRITE 0xA0 __sfr __at 0x58 fdc_devsel; @@ -24,9 +24,9 @@ static uint8_t fd_tab[MAX_FD] = { 0xFF, 0xFF, 0xFF, 0xFF }; */ /* Standard FDC */ -static uint8_t selmap[4] = { 0x01, 0x02, 0x03, 0x04 }; -#define FDC_SIDE1 0x08 -#define FDC_DOUBLE 0x10 +static uint8_t selmap[4] = { 0x00, 0x01, 0x02, 0x03 }; +#define FDC_SIDE1 0x04 +#define FDC_DOUBLE 0x08 #define FDC_SINGLE 0x00 /* DreamDisc FDC */ @@ -64,30 +64,24 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag) dptr = (uint16_t)udata.u_buf->bf_data; block = udata.u_buf->bf_blk; - /* Q: should we go with 512 bytes/sector format ? */ cmd[0] = is_read ? FD_READ : FD_WRITE; - cmd[1] = block / 9; /* 2 sectors per block */ - cmd[2] = ((block % 9) << 1) + 1; /*eww.. */ + /* Double sided assumed FIXME */ + cmd[1] = block / 20; + /* floppy.s will sort the side out */ + cmd[2] = ((block % 20) << 1) + 1; cmd[3] = is_read ? OPDIR_READ: OPDIR_WRITE; cmd[4] = dptr & 0xFF; cmd[5] = dptr >> 8; - while (ct < 2) { - for (tries = 0; tries < 4 ; tries++) { - err = fd_operation(cmd, driveptr); - if (err == 0) - break; - if (tries > 1) - fd_reset(driveptr); - } - /* FIXME: should we try the other half and then bale out ? */ - if (tries == 4) - goto bad; - cmd[5]++; /* Move on 256 bytes in the buffer */ - cmd[2]++; /* Next sector for 2nd block */ - ct++; - } - return 1; + for (tries = 0; tries < 4 ; tries++) { + err = fd_operation(cmd, driveptr); + if (err == 0) + break; + if (tries > 1) + fd_reset(driveptr); + } + if (tries != 4) + return 1; bad: kprintf("fd%d: error %x\n", minor, err); bad2: diff --git a/Kernel/platform-ubee/floppy.s b/Kernel/platform-ubee/floppy.s index 9c61c030..835a78dc 100644 --- a/Kernel/platform-ubee/floppy.s +++ b/Kernel/platform-ubee/floppy.s @@ -2,26 +2,22 @@ ; Core floppy routines for the TRS80 1791 FDC ; Based on the 6809 code ; -; FIXME: better drive spin up wait ; FIXME: double sided media ; FIXME: correct step rates (per drive ?) ; FIXME: precompensation -; - not on single density -; - track dependant for double density based on trsdos dir pos -; +; FIXME: density, size etc ; .globl _fd_reset .globl _fd_operation .globl _fd_motor_on - .globl _fd_motor_off .globl fd_nmi_handler -FDCREG .equ 0xF0 -FDCTRK .equ 0xF1 -FDCSEC .equ 0xF2 -FDCDATA .equ 0xF3 -FDCCTRL .equ 0xF4 -FDCINT .equ 0xE4 +FDCREG .equ 0x40 +FDCTRK .equ 0x41 +FDCSEC .equ 0x42 +FDCDATA .equ 0x43 +FDCCTRL .equ 0x48 + ; ; interrupt register reports 0x80 for interrut, 0x40 for drq ; (0x20 is the unrelated reset button) @@ -54,7 +50,7 @@ nap: dec bc jr nz, nap ret ; -; The motor off logic is driven from hardware +; NMI logic for DreamDisc ; fd_nmi_handler: push af @@ -62,10 +58,6 @@ fd_nmi_handler: ld a, (fdc_active) or a jr z, boring_nmi - xor a - out (FDCINT), a - ld bc, #100 - call nap pop bc pop af pop af ; discard return address @@ -113,6 +105,30 @@ waitdisk_l: ; DE points to the track reg copy ; fdsetup: +; +; Are we on side 0 or side 1 ? +; + ld a, SECTOR(ix) + cp #11 + jr c, side0 +; +; Set up for side 1 access +; + sub #10 + ld SECTOR(ix), a + ld a, (fdcctrl) + set 2, a ; correct for standard FDC not DreamDisc + jr side1 +side0: + ld a, (fdcctrl) + res 2, a +side1: +; +; FIXME: do we need to precompensation ? +; + ld (fdcctrl), a + out (FDCCTRL), a + ld a, (de) out (FDCTRK), a cp TRACK(ix) @@ -128,7 +144,8 @@ fdsetup: ; ; Need to seek the disk ; - ld a, #0x18 ; seek + ld a, #0x19 ; seek at 6ms steps. Slightly conservative + ; to allow for older drives out (FDCREG), a ld b, #100 seekwt: djnz seekwt @@ -147,15 +164,7 @@ setuptimeout: ; NE = bad fdiosetup: ld a, TRACK(ix) ld (de), a ; save track -; cmp #22 ; FIXME -; jr nc, noprecomp -; ld a, (fdcctrl) -; or #0x10 ; Precomp on -; jr precomp1 -;noprecomp: - ld a, (fdcctrl) -;precomp1: - out (FDCCTRL), a + ld a, SECTOR(ix) out (FDCSEC), a in a, (FDCREG) ; Clear any pending status @@ -196,7 +205,7 @@ fdxferdone2: ; fdio_in: ld e, #0x16 ; bits to check - ld bc, #FDCDATA ; 256 bytes/sector, c is our port + ld bc, #FDCDATA ; 512 bytes/sector, c is our port fdio_inl: in a, (FDCREG) and e @@ -208,6 +217,10 @@ fdio_inbyte: out (FDCCTRL), a ; stalls ini jr nz, fdio_inbyte +fdio_inbyte2: + out (FDCCTRL), a ; stalls + ini + jr nz, fdio_inbyte2 jr fdxferdone ; @@ -226,10 +239,6 @@ fdio_outl: in a, (FDCREG) ; No longer busy ?? rra jr nc, fdxferbad ; Bugger... - ld a, #0xC0 ; Turn on magic floppy NMI interface - out (FDCINT), a - ld b, #50 ; Spin for it -spin1: djnz spin1 ld b, (hl) ; Next byte inc hl fdio_waitlock: @@ -278,7 +287,7 @@ _fd_reset: out (FDCSEC), a xor a out (FDCTRK), a - ld a, #0x0C + ld a, #0x0D ; use 6ms stepping out (FDCREG), a ; restore ld a, #0xFF ld (hl), a ; Zap track pointer @@ -320,13 +329,12 @@ _fd_operation: ; C interface fd_motor_on(uint16_t drivesel) ; ; Selects this drive and turns on the motors. Also pass in the -; choice of density +; choice of density. For the standard uBee disk that is ; -; bits 0-3: select that drive -; bit 4: side (must rewrite each drive change) -; bit 5: precompensation (not set here but in the I/O ops) -; bit 6: synchronize I/O by stalling the CPU (don't set this) -; bit 7: set for double density (MFM) +; bits 0-1: select drive +; bit 2: side (must rewrite each drive change) +; (handled elsewhere) +; bit 3: density (set = DD) ; ; _fd_motor_on: @@ -335,14 +343,10 @@ _fd_motor_on: push hl push de ; - ; Select drive B, turn on motor if needed + ; Select drive B ; - ld a,(motor_running) ; nothing selected - or a - jr z, notsel - cp l - jr z, motor_was_on + jr z, was_selected ; ; Select our drive ; @@ -359,31 +363,12 @@ notsel: ; ; All is actually good ; -motor_was_on: +was_selected: ld hl, #0 ret -; -; C interface fd_motor_off(void) -; -; Turns off the drive motors, deselects all drives -; -_fd_motor_off: - ld a, (motor_running) - or a - ret z - ; Should we seek to track 0 ? - in a, (FDCCTRL) - and #0xF0 ; clear drive bits - out (FDCCTRL), a - xor a - ld (motor_running), a - ret - curdrive: .db 0xff -motor_running: - .db 0 fdcctrl: .db 0 fdc_active: -- 2.34.1