The WD177x is a family of chips produced by Western Design Center. They are relatively common in Thomson machines and elsewhere.

Registers

The floppy controller has 4 registers. The programming is done in several phases:

  • Setup phase: configure the settings (track, sector, etc)
  • Command phase: write a command to the command register
  • Data phase (only for some commands): get or send data to the floppy controller.

Thomson machines don't connect the floppy controller interrupt to the CPU in any way, so all the communication must be done by polling the FDC. This may be tricky to get right.

TO AddressMO AddressNameDescription
E7D0 A7D0 STR/CMDRCommand (write) and Status (read)
E7D1 A7D1 TKR Track
E7D2 A7D2 SECTSector
E7D3 A7D3 DR Data
E7D8 A7D8 Extension control

the “Extension control” register is not part of the floppy controller, but is an extra latch in Thomson floppy extension design. It has the following functions:

  • Bit 0: side select
  • Bit 1: drive select 0
  • Bit 2: drive select 1
  • Bit 7: single density mode

Programming samples

All these code snippets assume X points to the floppy controller base address (E7D0 or A7D0).

Waiting for the controller

As the floppy drive is slow, you have to wait for it after sending a command. Here is how to wait for the “ready” bit in the status register.

wready LDA ,X
       BITA #$1
       BNE wready

Seeking to a track

The Track register is not used directly as you might expect. It is used internally by the FDC to keep track of the current track (!), so writing to it would get everything out of sync. Instead, you do this (assuming A register holds the track number to seek to):

seek STA 3,X  ; Load track number in the DATA register
     LDA #$10 ; SEEK command
     STA ,X   ; ... to the command register

For this to work, the TRACK register must be properly initialised. It should hold the current track number. If you don't know the head position, a RESTORE command may be used to reset the head to track 0.

Realigning the drive head

This moves the head to the outside of the disk until the TRK0 signal from the drive is raised. At this point, the head position is known (it's on track 0), so the TRACK register is reset to 0. You can then seek somewhere else.

restore CLRA
        STA ,X ; Command 0 is RESTORE

Reading a sector

U points to the destination buffer, D holds the track number and sector ID. This assumes the Side register was set properly, and the head sent to the right track (the track value in D is used only to match with the on-disk sector ID).

read  STD 1,X    ; Stores both the track and sector in appropriate registers
      LDB #$88   ; Turn motor on and read
      STB ,X
      BSR delay ; Wait for the command to be processed
rloop LDB ,X     ; Read status register
      BITB #$2
      BEQ done   ; The FDC isn't ready to send the next byte yet
      LDA 3,X    ; Get next byte
      STA ,U+    ; Store it in buffer
      BRA rloop
      
done  BITB #$1   ; Is the command done?
      BNE rloop  ; If not, try again and see if the next byte is now available
      RTS
      
delay BSR hop    ; Just waste 35 cycles jumping around
      BSR hop
      BSR hop
      BSR hop
      BSR hop
      RTS

Writing a sector

Input: U points to the data to write, D holds track number and sector ID.

write ORCC #$50 ; Disable interrupts, our timing is critical
      STD 1,X   ; Load track and sector IDs
      LEAY 3,X  ; Point Y to the data register
      LDA #$A8  ; Spin up motor and write
      STA ,X
      BSR delay ; Wait for spinup
      BRA do
load  STA ,Y    ; Write one byte
do    LDA ,U+   ; Get next byte
wai   LDB ,X    ; Read status register
      BITB #2   ; Is the FDC waiting for one byte?
      BNE load  ; If so, send it one
      BITB #1   ; If not, is it busy, or is it done?
      BNE wai   ; It's busy, wait a little...
      
      ANDCC #$AF ; Restore interrupts, we're done with the timing critical stuff
      RTS
documentations/devices/wd177x.txt · Last modified: 2015/02/28 18:08 by 127.0.0.1
CC0 1.0 Universal
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0