From 1264da89c8ff46f575ecb3d61d3c9eef05eaea09 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 14 Feb 2015 16:43:58 +0000 Subject: [PATCH] disciple: sector wrap, notes on +D --- Kernel/platform-zx128/devfd.c | 23 +++++++++++-------- Kernel/platform-zx128/disciple.s | 39 ++++++++++---------------------- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/Kernel/platform-zx128/devfd.c b/Kernel/platform-zx128/devfd.c index 45ab1c19..a4407a0d 100644 --- a/Kernel/platform-zx128/devfd.c +++ b/Kernel/platform-zx128/devfd.c @@ -10,8 +10,7 @@ #define OPDIR_WRITE 2 #define FD_READ 0x80 -#define FD_WRITE 0xA0 -#define FD_WRITE_PCOMP 0xA4 +#define FD_WRITE 0xA2 /* * TODO: @@ -19,8 +18,6 @@ * - detect SS v DS */ -static uint8_t motorct; - /* We are a bit rude with this as we just bash it without sharing */ __sfr __at 0x1F control; @@ -39,6 +36,7 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag) uint8_t *driveptr = fd_tab + minor; uint8_t nblock; uint8_t cval; + uint8_t sec; if(rawflag == 2) goto bad2; @@ -60,7 +58,7 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag) fd_cmd[0] = is_read ? FD_READ : FD_WRITE; fd_cmd[1] = block / 20; - fd_cmd[2] = (block % 20) + 1; + sec = (block % 20) + 1; fd_cmd[3] = is_read ? OPDIR_READ: OPDIR_WRITE; fd_cmd[4] = dptr & 0xFF; fd_cmd[5] = dptr >> 8; @@ -72,10 +70,13 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag) while (ct < nblock) { - if (fd_cmd[2] > 10) + if (sec > 10) { control = cval | 2; - else + fd_cmd[2] = sec - 10; + } else { control = cval; + fd_cmd[2] = sec; + } if (!is_read && fd_cmd[1] > 64) fd_cmd[0] |= 4; /* Write precompensation on */ @@ -89,9 +90,13 @@ static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag) /* FIXME: need to do SD v DD detection */ if (tries == 4) goto bad; - /* FIXME: this doesn't work for a big raw read that changes track */ fd_cmd[5]+= 2; /* Move on 512 bytes in the buffer */ - fd_cmd[2]++; /* Next sector */ + sec++; + /* Step a track */ + if (sec > 20) { + sec = 1; + fd_cmd[1]++; + } ct++; } return 1; diff --git a/Kernel/platform-zx128/disciple.s b/Kernel/platform-zx128/disciple.s index 6b10b0e7..2a7dc40a 100644 --- a/Kernel/platform-zx128/disciple.s +++ b/Kernel/platform-zx128/disciple.s @@ -35,12 +35,22 @@ ; 0x58 - step in ; 0xA0 - write + 0x02 for spin up etc, + 0x08? for precomp ; 0xD0 - reset (then wait about 1mS) +; +; +; This code ought to work on the Plus-D as well with a few changes +; +; The +D uses ports +; 0xE3 status/cmd +; 0xEB track +; 0xF3 sector +; 0xFB data +; 0xEF control +; bits 0-1: drive select +; bit 7: side select ; .globl _fd_reset .globl _fd_operation - .globl _fd_motor_on - .globl _fd_motor_off .globl _fd_selected .globl _fd_tab .globl _fd_cmd @@ -335,35 +345,10 @@ _fd_operation: ld h, #0 pop ix ret -; -; C interface fd_motor_on(uint16_t drivesel) -; -; Selects this drive and turns on the motors. Also pass in the -; choice of density -; -; 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) -; -; -_fd_motor_on: - ret - -; -; C interface fd_motor_off(void) -; -; Turns off the drive motors, deselects all drives -; -_fd_motor_off: - ret .area _COMMONDATA curdrive: .db 0xff -motor_running: - .db 0 fdcctrl: .db 0 fdc_active: -- 2.34.1