From: Alan Cox Date: Sun, 19 Aug 2018 00:28:32 +0000 (+0100) Subject: sam: more work on the IDE layer X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=a6211fa1a4c33c45240fe1a8c7b440afb5cd6663;p=FUZIX.git sam: more work on the IDE layer I think it probably works for kernel now (user is broken and the split word case is nasty so will need some thinking). Need to update to the 1.1 alpha emulator as SimCoupe 1.0 can't do LBA and has other ATA bugs --- diff --git a/Kernel/platform-sam/Makefile b/Kernel/platform-sam/Makefile index d077d334..3d807314 100644 --- a/Kernel/platform-sam/Makefile +++ b/Kernel/platform-sam/Makefile @@ -1,5 +1,5 @@ -CSRCS = devlpr.c devtty.c devfd.c +CSRCS = devlpr.c devtty.c devfd.c devatom.c CSRCS += devices.c main.c DSRCS = ../dev/devide.c ../dev/mbr.c ../dev/blkdev.c diff --git a/Kernel/platform-sam/atom.s b/Kernel/platform-sam/atom.s index 65e1be14..dff0897a 100644 --- a/Kernel/platform-sam/atom.s +++ b/Kernel/platform-sam/atom.s @@ -100,16 +100,16 @@ ide_w2: ; if bit 0,c on 1st transfer - it's split word ; atomlite_reader: + ld a,#0x30 + out (0xF5),a ; Select data port ld d,b ld e,c - ld bc,#IDE_DATA_R + ld bc,#0xF6 ide_r_loop: - in a,(c) - ld (hl),a - inc hl - dec bc - ld a,b - or c + ini + dec de + ld a,d + or e jr nz,ide_r_loop ret ; @@ -117,42 +117,48 @@ ide_r_loop: ; design ; atomlite_reader_fast: - ld bc,#IDE_DATA_R + ; Select data port + ld a,#0x30 + out (0xF5),a + ld bc,#0xF7 + xor a ; 256 words atomlite_rf_loop: + dec c ini ; Read from F6 for the data high - inc b - inc b ; up to F7 for the data low + inc c + inc b ; so it's one loop of 256 counts ini - dec a jr nz, atomlite_rf_loop ret ; ; This needs optimizing to use as we know C = 0 ; atomlite_writer: + ld a,#0x30 + out (0xF5),a ; Select data port ld d,b ld e,c - ld bc,#IDE_DATA_W + ld bc,#0xF7 ide_w_loop: - ld a,(hl) - out (c),a - inc hl - dec bc - ld a,b - or c + outi + dec de + ld a,d + or e jr nz,ide_w_loop ret ; ; The non split case 512 bytes as fast as we can given the interface -; design +; design. For Atomlite we could just inir ; atomlite_writer_fast: - ld bc,#IDE_DATA_W + ld a,#0x30 + out (0xF5),a ; Select data port + ld bc,#0xF6 atomlite_wf_loop: - ini ; Read from F7 for the data high - ini ; F6 for the data low - inc b - inc b ; back to F7 - dec a - jr nz, atomlite_rf_loop + inc c + outi ; Write F6 + dec c + inc b ; So it's 256 times count + outi ; Then F7 + jr nz, atomlite_wf_loop ret diff --git a/Kernel/platform-sam/devatom.c b/Kernel/platform-sam/devatom.c new file mode 100644 index 00000000..ce45111d --- /dev/null +++ b/Kernel/platform-sam/devatom.c @@ -0,0 +1,22 @@ +#include +#include +#include + +__sfr __at 0xF5 ide_addr; +__sfr __at 0xF6 ide_high; +__sfr __at 0xF7 ide_low; + +uint8_t devide_readb(uint8_t reg) +{ + volatile uint8_t dummy; + ide_addr = reg; + dummy = ide_high; + return ide_low; +} + +void devide_writeb(uint8_t reg, uint8_t value) +{ + ide_addr = reg; + ide_high = 0; + ide_low = value; +} diff --git a/Kernel/platform-sam/fuzix.lnk b/Kernel/platform-sam/fuzix.lnk index 3db9ac70..0201675c 100644 --- a/Kernel/platform-sam/fuzix.lnk +++ b/Kernel/platform-sam/fuzix.lnk @@ -32,6 +32,7 @@ vt.rel devsys.rel platform-sam/atom.rel platform-sam/blkdev.rel +platform-sam/devatom.rel platform-sam/devfd.rel platform-sam/devices.rel platform-sam/devide.rel diff --git a/Kernel/platform-sam/platform_ide.h b/Kernel/platform-sam/platform_ide.h index 5d24fcae..dc55ee37 100644 --- a/Kernel/platform-sam/platform_ide.h +++ b/Kernel/platform-sam/platform_ide.h @@ -1,27 +1,47 @@ #define ide_select(x) #define ide_deselect(x) -/* The numbers here look a bit weird because of the way the - device is mapped to one Z80 port with the address high bits - controlling what is accessed */ +/* + * ATOM attaches the IDE controller to F5 F6 F7 + * + * F5 when written sets the IDE port address to use and other bits + * 7-6: unused 5: !reset 4: !cs3 3: !cs1 2-0: address + * + * CS3 selects ports 3Fx as seen by the IDE chip, CS1 selects 1Fx, both + * are negative logic. Both or neither is undefined + * + * F6 when read causes a transaction fromthe IDE, returns the high bits + * and latches the low. + * + * F7 when read reads the latch + * + * F6 when written writes the latch + * F7 when written causes the 16bit wide transaction to occur using + * the data for the low and latch for high. + * + * The ATOMlite simply makes F6 and F7 the same and requires IDE 8bit mode. + * That needs different handling - and has bizarre consequences for + * byte ordering behaviour compared to Atom + */ -#define IDE_8BIT_ONLY /* Worry about the big Atom later */ +#define IDE_NONSTANDARD_XFER -#define IDE_REG_DATA_R 0x00F6 -#define IDE_REG_DATA IDE_REG_DATA_R -#define IDE_REG_DATA_W 0x00F7 -#define IDE_REG_ERROR 0x01F6 -#define IDE_REG_FEATURES 0x01F7 -#define IDE_REG_SEC_COUNT 0x02F7 -#define IDE_REG_LBA_0 0x03F7 -#define IDE_REG_LBA_1 0x04F7 -#define IDE_REG_LBA_2 0x05F7 -#define IDE_REG_LBA_3 0x06F7 -#define IDE_REG_DEVHEAD 0x06F7 -#define IDE_REG_STATUS 0x07F6 -#define IDE_REG_COMMAND 0x07F7 +#define IDE_REG_INDIRECT -/* 0xF5 bit 5 is a reset pin, setting it low resets, then set back high. We - don't have a way to expose this to the IDE layer yet - FIXME */ +#define IDE_CS1 0x30 +#define IDE_CS3 0x28 -#define IDE_NONSTANDARD_XFER +#define ide_reg_data (IDE_CS1 | 0) +#define ide_reg_error (IDE_CS1 | 1) +#define ide_reg_features (IDE_CS1 | 1) +#define ide_reg_sec_count (IDE_CS1 | 2) +#define ide_reg_lba_0 (IDE_CS1 | 3) +#define ide_reg_lba_1 (IDE_CS1 | 4) +#define ide_reg_lba_2 (IDE_CS1 | 5) +#define ide_reg_lba_3 (IDE_CS1 | 6) +#define ide_reg_devhead (IDE_CS1 | 6) +#define ide_reg_status (IDE_CS1 | 7) +#define ide_reg_command (IDE_CS1 | 7) + +#define ide_reg_altstatus (IDE_CS3 | 6) +#define ide_reg_control (IDE_CS3 | 7)