#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;
*/
/* 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 */
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:
; 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)
jr nz, nap
ret
;
-; The motor off logic is driven from hardware
+; NMI logic for DreamDisc
;
fd_nmi_handler:
push af
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
; 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)
;
; 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
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
;
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
out (FDCCTRL), a ; stalls
ini
jr nz, fdio_inbyte
+fdio_inbyte2:
+ out (FDCCTRL), a ; stalls
+ ini
+ jr nz, fdio_inbyte2
jr fdxferdone
;
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:
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
; 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:
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
;
;
; 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: