sam: more work on the IDE layer
authorAlan Cox <alan@linux.intel.com>
Sun, 19 Aug 2018 00:28:32 +0000 (01:28 +0100)
committerAlan Cox <alan@linux.intel.com>
Sun, 19 Aug 2018 00:28:32 +0000 (01:28 +0100)
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

Kernel/platform-sam/Makefile
Kernel/platform-sam/atom.s
Kernel/platform-sam/devatom.c [new file with mode: 0644]
Kernel/platform-sam/fuzix.lnk
Kernel/platform-sam/platform_ide.h

index d077d33..3d80731 100644 (file)
@@ -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
index 65e1be1..dff0897 100644 (file)
@@ -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 (file)
index 0000000..ce45111
--- /dev/null
@@ -0,0 +1,22 @@
+#include <kernel.h>
+#include <kdata.h>
+#include <devide.h>
+
+__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;
+}
index 3db9ac7..0201675 100644 (file)
@@ -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
index 5d24fca..dc55ee3 100644 (file)
@@ -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)