p112: Floppy disk driver (devfd) support for rawflag=1
authorWill Sowerbutts <will@sowerbutts.com>
Mon, 2 Feb 2015 21:06:41 +0000 (21:06 +0000)
committerWill Sowerbutts <will@sowerbutts.com>
Mon, 2 Feb 2015 21:08:51 +0000 (21:08 +0000)
Kernel/platform-p112/devfd.c
Kernel/platform-p112/devfd2.s

index 2d376cc..3479858 100644 (file)
@@ -6,6 +6,7 @@
        Portions Copyright (C) 1995 by Stefan Nitschke
 ****************************************************************/
 /* 2015-01-17 Will Sowerbutts: Ported from UZI-180 to Fuzix */
+/* Assumes 512-byte sectors, 3.5" 1.44 MB formatted disks   */
 
 #include <kernel.h>
 #include <kdata.h>
@@ -18,21 +19,44 @@ extern int devfd_read(uint8_t minor);
 extern int devfd_write(uint8_t minor);
 
 /* variables in devfd2.s */
-extern uint8_t devfd_track, devfd_sector, devfd_error;
+extern uint8_t devfd_track, devfd_sector, devfd_error, devfd_userbuf;
 extern char *devfd_buffer;
 
-extern struct {
-       uint8_t logged;
-       uint8_t cbyte0;
-       uint8_t cbyte1;
-       uint8_t gap3;
-       uint8_t spt;
-       uint8_t sector1;
-       uint8_t format;
-       uint8_t spinup;
-       uint8_t curtrk;
-       uint8_t ncyl;
-} devfd_dtbl[4];
+/* D D D D D D D D               Format Byte
+   7 6 5 4 3 2 1 0
+   | | | | | | +-+----- Sector Size: 000=128, 001=256, 010=512, 011=1024 bytes
+   | | | | +-+--------- Disk Size: 00=fixed disk, 01=8", 10=5.25", 11=3.5"
+   | | | +------------- 0 = Normal 300 RPM MFM,    1 = "High-Density" Drive
+   | | +--------------- 0 = Single-Sided,          1 = Double-Sided
+   | +----------------- 0 = Double-Density,        1 = Single-Density
+   +------------------- 0 = 250 kbps (normal MFM), 1 = 500 kbps (Hi-Density) */
+
+#define IBMPC3  0xAE    /* 10101110B HD,  DD, DS, 3.5",   512-byte Sctrs (1.44 MB) */
+#define UZIHD3  0xAF    /* 10101111B HD,  DD, DS, 3.5",  1024-byte Sctrs (1.76 MB) */
+#define IBMPC5  0xAA    /* 10101010B HD,  DD, DS, 5.25",  512-byte Sctrs (1.2 MB)  */
+#define UZIHD5  0xAB    /* 10101011B HD,  DD, DS, 5.25", 1024-byte Sctrs (1.44 MB) */
+#define DSQD3   0x2F    /* 00101111B MFM, DD, DS, 3.5",  1024-byte Sctrs (800 KB)  */
+#define DSDD3   0x2E    /* 00101110B MFM, DD, DS, 3.5",   512-byte Sctrs (800 KB)  */
+#define DSQD5   0x2B    /* 00101011B MFM, DD, DS, 5.25", 1024-byte Sctrs (800 KB)  */
+#define DSDD5   0x2A    /* 00101010B MFM, DD, DS, 5.25",  512-byte Sctrs (800 KB)  */
+
+struct {
+       uint8_t logged;     /* logged (0xff), unlogged (0) */
+       uint8_t cbyte0;     /* bits 7-4: step rate (4ms), bits 3-0: HUT (240ms) */
+       uint8_t cbyte1;     /* head load time in 4ms steps (0=infinite) */
+       uint8_t gap3;       /* gap3 (size 512 = 27, 1024 = 13) */
+       uint8_t spt;        /* physical sectors per track */
+       uint8_t sector1;    /* first sector number */
+       uint8_t format;     /* format byte */
+       uint8_t spinup;     /* spinup (1/20-secs) */
+       uint8_t curtrk;     /* current tranck number */
+       uint8_t ncyl;       /* number of cylinders x heads */
+} devfd_dtbl[4] = {
+    { 0, 0xCF, 1, 27, 18, 1, IBMPC3, 10, 0, 160 },
+    { 0, 0xCF, 1, 27, 18, 1, IBMPC3, 10, 0, 160 },
+    { 0, 0xCF, 1, 27, 18, 1, IBMPC3, 10, 0, 160 },
+    { 0, 0xCF, 1, 27, 18, 1, IBMPC3, 10, 0, 160 },
+};
 
 static int fd_transfer(bool rwflag, uint8_t minor, uint8_t rawflag)
 {
@@ -45,17 +69,20 @@ static int fd_transfer(bool rwflag, uint8_t minor, uint8_t rawflag)
                case 0:
                        nblocks = 1;
                        devfd_buffer = udata.u_buf->bf_data;
+                       devfd_userbuf = 0;
                        firstblk = udata.u_buf->bf_blk;
                        break;
                case 1:
-                       nblocks = udata.u_count >> 9;
+                       nblocks = udata.u_count >> BLKSHIFT;
                        devfd_buffer = udata.u_base;
+                       devfd_userbuf = 0xFF;
                        firstblk = udata.u_offset >> BLKSHIFT;
                        break;
 #ifdef SWAPDEV
                case 2:
                        nblocks = swapcnt >> 9;
                        devfd_buffer = swapbase;
+                       devfd_userbuf = 0xFF;
                        firstblk = swapblk;
                        break;
 #endif
index 87fd885..03b7769 100644 (file)
@@ -8,6 +8,8 @@
         .z180
 
         ; imported symbols
+        .globl map_kernel
+        .globl map_process_always
         .globl _devfd_dtbl
 
         ; exported sybols
@@ -18,6 +20,7 @@
         .globl _devfd_sector
         .globl _devfd_error
         .globl _devfd_buffer
+        .globl _devfd_userbuf
         .globl _fd_tick
 
         .include "kernel.def"
@@ -69,16 +72,18 @@ DRR     .equ    FDCBAS+7        ; Data Rate Register/Disk Changed Bit in B7
 
 MONTIM  .equ    250             ; Motor On time (Seconds * TICKSPERSEC)
 
-; Offsets in Drive Data Table (defined at end of this module)
-oFLG    .equ    0               ; 0 = Not Logged, 1 = Drive Logged
-oPRM1   .equ    1               ; Step Rate (B7-4), HUT (3-0)
-oPRM2   .equ    2               ; Hd Load in 4mS steps (0=infinite)
-oGAP3   .equ    3               ; Gap 3 Length for Read
-oSPT    .equ    4               ; Sectors-per-Track
-oSEC1   .equ    5               ; First Sector Number
-oFMT    .equ    6               ; Bit-mapped Format byte
-oSPIN   .equ    7               ; Spinup delay (1/20-secs)
-oTRK    .equ    8               ; Current Head Position (Track)
+; Offsets into _devfd_dtbl
+oFLG    .equ    0               ; logged:  0 = Not Logged, 1 = Drive Logged
+oPRM1   .equ    1               ; cbyte0:  Step Rate (B7-4), HUT (3-0)
+oPRM2   .equ    2               ; cbyte1:  Hd Load in 4mS steps (0=infinite)
+oGAP3   .equ    3               ; gap3:    Gap 3 Length for Read
+oSPT    .equ    4               ; spt:     Sectors-per-Track
+oSEC1   .equ    5               ; sector1: First Sector Number
+oFMT    .equ    6               ; format:  Bit-mapped Format byte
+oSPIN   .equ    7               ; spinup:  Spinup delay (1/20-secs)
+oTRK    .equ    8               ; curtrk:  Current Head Position (Track)
+oNCYL   .equ    9               ; ncyl:    Number of cylinders
+TBLSIZ  .equ    10              ; sizeof() entry in _devfd_dtbl
 
 ;-------------------------------------------------------------
 ; Determine if the controller exists and a drive is attached
@@ -403,49 +408,6 @@ SEEKX:  POP     BC              ; Restore Regs
         POP     HL
         RET
 
-;-------------------------------------------------------------
-; FDCMD - Send Command to DP-8473 FDC
-; Enter:  B = # of Bytes in Command, C = Command Byte
-;        HL -> Buffer for Read/Write Data (If Needed)
-; Exit : AF = Status byte
-; Uses : AF.  All other registers preserved/unused
-
-FdCmd:  PUSH    HL              ; Save regs (for Exit)
-        PUSH    BC
-        PUSH    HL              ;   save pointer for possible Transfer
-        CALL    Motor           ; Ensure motors are On
-        LD      HL,#comnd       ; Point to Command Block
-        LD      (HL),C          ;  command passed in C
-        LD      C,#DR           ;   DP8473 Data Port
-OtLoop: CALL    WRdy            ; Wait for RQM (hoping DIO is Low) (No Ints)
-        OUTI                    ; Output Command bytes to FDC
-        JR      NZ,OtLoop       ; ..loop til all bytes sent
-
-        POP     HL              ; Restore Possible Transfer Addr
-FdCi1:  CALL    WRdy
-        BIT     5,A             ; In Execution Phase?
-        JR      Z,FdcRes        ; ..jump if Not to check result
-        BIT     6,A             ; Write?
-        JR      NZ,FdCi2        ; ..jump if Not to Read
-        OUTI                    ; Else Write a Byte from (HL) to (C)
-        JR      FdCi1           ;   and check for next
-
-FdCi2:  INI                     ; Read a byte from (C) to (HL)
-        JR      FdCi1           ;   and check for next
-
-FdcRes: LD      HL,#st0         ; Point to Status Result area
-IsGo:   CALL    WRdy
-;;---   CALL    _ei             ;  (Ints Ok now)
-        BIT     4,A             ; End of Status/Result?
-        JR      Z,FdcXit        ; ..exit if So
-        BIT     6,A             ; Another byte Ready?
-        JR      Z,FdcXit        ; ..exit if Not
-        INI                     ; Else Read Result/Status Byte
-        JR      IsGo            ; ..loop for next
-
-FdcXit: POP     BC              ; Restore Regs
-        POP     HL
-        RET
 
 ;-------------------------------------------------------------
 ; Check for Proper Termination of Seek/Recalibrate Actions by
@@ -524,21 +486,6 @@ WRdyT0: DEC     BC
         RET     NZ              ; ..return Ok if Yes
         JR      WRdyT0          ;  ..else loop to try again
  
-;-------------------------------------------------------------
-; Wait for FDC RQM to become Ready, return DIO status in
-; Zero Flag.  Pause before reading status port (~12 mS
-; specified, some assumed in code).
-
-WRdy:   ;DI                     ; No Ints while we are doing I/O
-                                ;  (entry to avoid Disabling Ints)
-WRdy1:  LD      A,(dlyCnt)      ; Get delay count
-WRdy0:  DEC     A               ;  count down
-        JR      NZ,WRdy0        ;   for ~6 uS Delay
-WRdyL:  IN      A,(MSR)         ; Read Main Status Register
-        BIT     7,A             ; Interrupt Present?
-        RET     NZ              ;  Return if So
-        JR      WRdyL           ;   Else Loop
-
 ;-------------------------------------------------------------
 ; Return Pointer to Parameters of selected Drive
 ; Enter: A = Drive (0..3)
@@ -595,66 +542,101 @@ ActivA: LD      (active),A      ;    save
         OUT     (DCR),A         ;     and Command!
         RET
 
-;------------------- Data Storage Area -----------------------
-; Disk and Drive parameters are dictated by table entries.  While
-; not all parameters are implemented in this module, they may be
-; added as desired.  A bit-mapped byte is used defined as:
-
-; D D D D D D D D               Format Byte
-; 7 6 5 4 3 2 1 0
-; | | | | | | +-+----- Sector Size: 000=128, 001=256, 010=512, 011=1024 bytes
-; | | | | +-+--------- Disk Size: 00=fixed disk, 01=8", 10=5.25", 11=3.5"
-; | | | +------------- 0 = Normal 300 RPM MFM,    1 = "High-Density" Drive
-; | | +--------------- 0 = Single-Sided,          1 = Double-Sided
-; | +----------------- 0 = Double-Density,        1 = Single-Density
-; +------------------- 0 = 250 kbps (normal MFM), 1 = 500 kbps (Hi-Density)
-
-IBMPC3  .equ    0xAE    ; 10101110B     ; HD,  DD, DS, 3.5",   512-byte Sctrs (1.44 MB)
-UZIHD3  .equ    0xAF    ; 10101111B     ; HD,  DD, DS, 3.5",  1024-byte Sctrs (1.76 MB)
-IBMPC5  .equ    0xAA    ; 10101010B     ; HD,  DD, DS, 5.25",  512-byte Sctrs (1.2 MB)
-UZIHD5  .equ    0xAB    ; 10101011B     ; HD,  DD, DS, 5.25", 1024-byte Sctrs (1.44 MB)
-DSQD3   .equ    0x2F    ; 00101111B     ; MFM, DD, DS, 3.5",  1024-byte Sctrs (800 KB)
-DSDD3   .equ    0x2E    ; 00101110B     ; MFM, DD, DS, 3.5",   512-byte Sctrs (800 KB)
-DSQD5   .equ    0x2B    ; 00101011B     ; MFM, DD, DS, 5.25", 1024-byte Sctrs (800 KB)
-DSDD5   .equ    0x2A    ; 00101010B     ; MFM, DD, DS, 5.25",  512-byte Sctrs (800 KB)
-
-_devfd_dtbl:                            ; Drive Param Table.  1 Entry Per Drive.
-        .db 0, 0xCF,   1,  27, 18,  1, IBMPC3, 10, 0, 160
-        ;   |     |    |    |   |   |    |      |  |    +- Number of Cylinders
-        ;   |     |    |    |   |   |    |      |  +- Current Track Number
-        ;   |     |    |    |   |   |    |      +- Spinup (1/20-secs)
-        ;   |     |    |    |   |   |    +-- Format Byte (See above)
-        ;   |     |    |    |   |   +------- First Sector Number
-        ;   |     |    |    |   +------- Physical Sectors-Per-Track
-        ;   |     |    |    +----------- Gap3 (Size 512=27, 1024=13)
-        ;   |     |    +---------------- Hd Load in 4mS steps (0=inf)
-        ;   |     +--------------------- Step Rate (B7-4) = 4mS (2's compl)
-        ;                                   HUT (B3-0) = 240 mS
-        ;   +--------------------------- Drive Logged (FF), Unlogged (0)
-TBLSIZ   .equ  . - _devfd_dtbl
-        .db 0, 0xCF,   1,  27,  18, 1, IBMPC3, 10, 0, 160
-        .db 0, 0xCF,   1,  27,  18, 1, IBMPC3, 10, 0, 160
-        .db 0, 0xCF,   1,  27,  18, 1, IBMPC3, 10, 0, 160
+;-------------------------------------------------------------
+; FDCMD - Send Command to DP-8473 FDC
+; Enter:  B = # of Bytes in Command, C = Command Byte
+;        HL -> Buffer for Read/Write Data (If Needed)
+; Exit : AF = Status byte
+; Uses : AF.  All other registers preserved/unused
 
-; -->>> NOTE: Do NOT move these next two variables out of sequence !!! <<<--
-motim:  .db     0               ; Motor On Time Counter
-mtm:    .db     0               ; Floppy Spinup Time down-counter
+FdCmd:  PUSH    HL              ; Save regs (for Exit)
+        PUSH    BC
+        PUSH    DE
+
+        PUSH    HL              ; save pointer for possible Transfer
+        CALL    Motor           ; Ensure motors are On
+        LD      HL,#comnd       ; Point to Command Block
+        LD      (HL),C          ;  command passed in C
+        LD      C,#DR           ;   DP8473 Data Port
+        LD      A,(_devfd_userbuf)
+        LD      D,A             ; store userbuf flag in D
+OtLoop: CALL    WRdy            ; Wait for RQM (hoping DIO is Low) (No Ints)
+        OUTI                    ; Output Command bytes to FDC
+        JR      NZ,OtLoop       ; ..loop til all bytes sent
+        POP     HL              ; Restore Possible Transfer Addr
+
+        CALL    FdCmdXfer       ; Do the data transfer (using code in _COMMONMEM)
+
+        LD      HL,#st0         ; Point to Status Result area
+IsGo:   CALL    WRdy
+        BIT     4,A             ; End of Status/Result?
+        JR      Z,FdcXit        ; ..exit if So
+        BIT     6,A             ; Another byte Ready?
+        JR      Z,FdcXit        ; ..exit if Not
+        INI                     ; Else Read Result/Status Byte
+        JR      IsGo            ; ..loop for next
+FdcXit: 
+        POP     DE              ; Restore Regs
+        POP     BC
+        POP     HL
+        RET
+
+;------------------------------------------------------------
+; COMMON MEMORY
+;------------------------------------------------------------
+        .area _COMMONMEM
+
+; inner section of FdCmd routine, has to touch buffers etc
+FdCmdXfer:
+        BIT     0,D             ; Buffer in user memory?
+        CALL    NZ, map_process_always
+
+FdCi1:  CALL    WRdy
+        BIT     5,A             ; In Execution Phase?
+        JR      Z,FdCmdXferDone ; ... tidy up and return if not
+        BIT     6,A             ; Write?
+        JR      NZ,FdCi2        ; ... jump if Not to Read
+        OUTI                    ; Write a Byte from (HL) to (C)
+        JR      FdCi1           ; check for next byte
+FdCi2:  INI                     ; Read a byte from (C) to (HL)
+        JR      FdCi1           ; check for next byte
+FdCmdXferDone:
+        BIT     0,D             ; Buffer in user memory?
+        RET     Z               ; done if not
+        JP      map_kernel      ; else remap kernel and return
+
+;-------------------------------------------------------------
+; Wait for FDC RQM to become Ready, return DIO status in
+; Zero Flag.  Pause before reading status port (~12 mS
+; specified, some assumed in code).
+
+WRdy:
+WRdy1:  LD      A,(dlyCnt)      ; Get delay count
+WRdy0:  DEC     A               ;  count down
+        JR      NZ,WRdy0        ;   for ~6 uS Delay
+
+WRdyL:  IN      A,(MSR)         ; Read Main Status Register
+        BIT     7,A             ; Interrupt Present?
+        RET     NZ              ;  Return if So
+        JR      WRdyL           ;   Else Loop
 
 dlyCnt: .db     (CPU_CLOCK_KHZ/1000)    ; Delay to avoid over-sampling status register
 
-;------------------------------------------------------------------------------
+;------------------------------------------------------------
+; DATA MEMORY
+;------------------------------------------------------------
          .area _DATA
 
 drive:  .ds     1               ; (minor) Currently Selected Drive
 active: .ds     1               ; Current bits written to Dev Contr Reg (DCR)
-;;--block:      DEFS    1               ; Index in Buffer for desired 512-byte block
-;;--buffer:     DEFS    1024            ; Physical Sector Buffer.  Max Possible Size
 
 _devfd_sector:  .ds     1
 _devfd_track:   .ds     1               ; LSB used as Head # in DS formats
 _devfd_error:   .ds     1
 _devfd_buffer:  .ds     2
+_devfd_userbuf: .ds     1
 
+; DISK Subsystem Variable Storage
 comnd:  .ds     1               ; Storage for Command in execution
 hdr:    .ds     1               ; Head (B2), Drive (B0,1)
 trk:    .ds     1               ; Track (t)
@@ -666,7 +648,6 @@ gpl:    .ds     1               ; Gap Length
 dtl:    .ds     1               ; Data Length
 
 ; FDC Operation Result Storage Area
-
 st0:    .ds     1               ; Status Byte 0
 st1:    .ds     1               ; Status Byte 1 (can also be PCN)
         .ds     1               ; ST2 - Status Byte 2
@@ -675,9 +656,9 @@ st1:    .ds     1               ; Status Byte 1 (can also be PCN)
         .ds     1               ; RR - Sector #
         .ds     1               ; RN - Sector Size
 
-actDma: .ds     2               ; 16-bit DMA Address
-
-; DISK Subsystem Variable Storage
+; -->>> NOTE: Do NOT move these next two variables out of sequence !!! <<<--
+motim:  .ds     1               ; Motor On Time Counter
+mtm:    .ds     1               ; Floppy Spinup Time down-counter
 
 rdOp:   .ds     1               ; Read/write flag
 retrys: .ds     1               ; Number of times to try Opns