Almost done; this is the result of my CRU analysis.
0 Controller INT line
1 Motor spinning (monoflop 1)
2 Timeout for disk operations (monoflop 2)
4 Drive 0 cylinder count (0=40, 1=77)
5 Drive 1 cylinder count
6 Drive 2 cylinder count
7 Drive 3 cylinder count
3 Step direction (1=inwards)
4 When 1, assert DACK* (DMA acknowledge) to clear a pending DRQ
5 Step pulse (up)
6 Trigger timeout monoflop (2)
7 RESET* the controller (put state machine in idle state, i.e. stop working with disk)
8 Drive select drive 0 (DSK1)
9 Drive select drive 1 (DSK2)
10 Drive select drive 2 (DSK3)
11 Drive select drive 3 (DSK4)
12 Separate Motor line for internal drive (not used)
13 Unknown, obviously not connected on the board but used before sector I/O, format track, reset drives; turned off once when reporting status
14 Arm READY circuit
15 Unknown, possibly in test mode only, not connected
The last discoveries were the meanings of CRU bits 4 and 6, both of which are pulsed (SBO/SBZ) at a few locations.
CRU bit 4 leads to the DACK* input of the controller. This is pretty interesting and unexpected, but now I seem to understand. You can see it on the attached picture.
The purpose could be to clear a pending DRQ before starting the sector access. With an asserted DRQ, the READY line would be high, which would cause a miss of the first byte. I was wondering about the reason to do this, but it probably makes sense when we consider that a previous sector access may have timed out, and since this is detected by the circuitry on the board, not by the controller, the DRQ may still be high on the next attempt.
The DMA access is done in an interesting way. Instead of getting access to the RAM circuits, the controller talks to the 9995 CPU which pretends to be the DMA controller. It works like this: First, the CPU must be halted; this is done by leading a 0 to the READY line; this can be done by accessing a particular address, which (via the PAL) leads to an AND circuit. Then the controller collects the incoming bits from the floppy and raises the DRQ line. This unlocks the CPU, which proceeds to the next command. This command is a MOVB instruction, picking up the value from a special address, which is decoded by the PAL to assert the DACK* line. When it does this, the controller puts the value on the data bus, so it will be received by the CPU and then written to a location in RAM. Then the loop continues by locking the CPU again.
In the case that the read operation fails (because the sector header is not readable), the CPU will stay locked in that loop, and hence it cannot free itself. For that reason, the monoflop 2 must be triggered before the operation. When it drops to low, it will raise READY and thus unlock the CPU. After that loop (with 256 iterations for all bytes in the sector), the CRU bit 2 is checked, which reflects the monoflop state. When it is 0, the monoflop has expired, so the loop was left because of a timeout. When it is still 1, all 256 bytes were read.
Taking a look at the code
226A: SBO 14
226C: BL *R9 (R9=F090)
F090: CLR @>F7EC
F094: MOVB @>F7E2,*R2+
F098: DEC R6
F09A: JNE >F090
F090: CLR @>F7EC
F094: MOVB *R2+,@>F7EA
F09A: DEC R6
F09C: JNE >F090
226E: LI R9,>EFC0
2272: SBZ 14
2274: TB 2
2276: JEQ >2282
2278: BL @>271C
227C: BL @>2764
2280: DATA >6400
226A: Arm the READY circuit
226C: Branch to the routine in on-chip RAM which must have been copied there (read or write)
F090: Connect DRQ to READY; DRQ must be 0 at this point. The PAL is to decode that address. The monoflop must have been triggered before and DACK* must have been pulsed (not shown)
F094: When we reach this position, the controller has obviously raised DRQ and unlocked the CPU. The address in this MOVB operation must cause DACK* to become asserted (0), again achieved by the PAL. The CPU reads the data bus which expects the data byte to be made available by the controller. Then, the value is written to a RAM location pointed to by R2. The assertion of DACK* makes DRQ return to 0, which must have been disconnected from READY by these operations.
F098/9A: While there are more bytes (initially 256), continue
226E: Reset R9 to the usual value (was 8300 in the TI FDC)
2272: Unarm the READY trap
2274: Check the monoflop state. When 0, we are here because a timeout occured.
2278: Try a different density or stepping (single/double). Repeat, if not already done.
227C: No luck, report error >6400
Next things are to understand the Hexbus protocol, then I can start implementing it.
When I am done with it, I will publish the disassembled ROM listing on my website or on Ninerpedia and send a copy to Thierry.