Jump to content
  • entries
    334
  • comments
    900
  • views
    258,317

Apple ][ Disk ][ Read Sequencer


EricBall

366 views

One of Woz's design decisions for the Disk ][ was to force the MSB of each byte read to be 1. Although this restricted the number of values each byte could take, this was already restricted by the number of sequential zero bits i.e the time between changes in magnetic field; initally 1 (DOS 3.2), later 2 (DOS 3.3). But the restriction on the MSB had several positive side effects:

1. The MSB could be used as an easy "data ready" flag by the CPU.

2. The read sequencer could hold the completed byte even after the MSB of the next byte was received. This gave the CPU extra time to read the completed byte.

3. Extra zero bits between bytes could be ignored, which allowed the read sequencer to automatically synch to a series of FF bytes separated by 1 or 2 zeros.

 

One alternative would have been to store each set of 8 bits in a FIFO which the CPU could read. But then the CPU would need to perform the synchronization - determining the start & end of each byte.

 

The following is a decode of the state machine for the DOS 3.3 Read Sequencer. For each state (n the left there)are four possible commands+next states depending on whether the MSB of the shift register is 1 or zero and whether a read pulse (change in magnetic field=1 bit) was received from the disk. Note: The command takes effect as part of the state change.

	MSB=0,RP=0  MSB=0,RP=1  MSB=1,RP=0  MSB=1,RP=1
0	NOP	1	NOP	1	NOP	1	NOP	1
1	SL1	2	SL1	2	NOP	3	NOP	3
2	NOP	3	NOP	D	NOP	2*	NOP	0
3	NOP	4	NOP	D	NOP	4	NOP	4
4	NOP	5	NOP	D	NOP	5	NOP	D
5	NOP	6	NOP	D	NOP	6	NOP	D
6	NOP	7	NOP	D	NOP	7	NOP	D
7	NOP	8	NOP	D	NOP	8	NOP	D
8	NOP	9	NOP	D	NOP	9	NOP	D
9	SL0	2	NOP	D	NOP	A	NOP	D
A	SL1	B	SL1	C	NOP	B	NOP	D
B	SL0	5	SL0	D	NOP	C	NOP	D
C	SL0	D	SL0	D	CLR	A	NOP	D
D	NOP	0	NOP	D	NOP	E	NOP	E
E	SL1	F	SL1	F	NOP	F	NOP	F
F	SL1	4	SL1	D	CLR	E	CLR	E

One important note is the "code" won't read the first byte correctly when entering read mode from "sense write protect" mode, which leaves the system in state 0 with the MSB in an unknown state. Maybe it was felt programs would typically leave the Disk ][ in read mode and there was no need to try to read the first byte after a mode switch correctly. Thus, the logical point to start figuring out the behaviour of the sequencer is to start with the "Hold" state which occurs when a byte has been completely read - state 2 with the MSB set, marked with a *.

 

What this simple command+state does is ignores any zero bits between bytes. Once a read pulse is received it starts with state 0 (MSB=1) and continues down, ignoring any read pulses for the next 4 cycles, then waiting for the next read pulse or another 8 cycles. (It acutally waits up to 13 cycles total for a read pulse before deciding the bit is a zero.) If a read pulse is received then it jumps to state D (MSB=1), waits for another few cycles, then clears the shift register and shifts in the first bits. (The CLR naturally forces the MSB=0 for the next state.)

 

This is all about holding onto the completed byte as long as possible as the CPU needs the data to be at least 7 CPU=14 state machine cycles (for RLOOP LDA $C08A,X + BPL RLOOP), even though there is only 4 CPU=8 state machine cycles between bits.

 

On the MSB=0 the logic is fairly simple - wait for a read pulse. When RP=1 jump to state D, wait for RP=0, then jump back to state 0, wait one cycle, then shift in a 1. If no read pulse is recieved after 11 cycles then shift in a zero (it only waits 8 cycles for the second zero). The only trick is after the shift it jumps to state 2, which kicks over to the "Hold" state when the MSB=1 after the shift.

 

One interesting item is how the "code" tries to mask unstable read pulses. In some cases the state transitions after a read pulse is received ignore futher read pulses for several, but in other cases (such as state D MSB=0) the code loops indefinitely waiting for the read pulses to stop. This is done because the the magnetic transition might "ring" (in either the magnetic or electrical domain) causing extra pulses (hopefully an even number); so it makes sense to somehow ignore them.

 

Waiting for the read pulses is more efficient, but this affects zero bit detection. In theory bits would occur every 8 state machine cycles, since that is the timing of the write sequencer. However, that assumes the disk is rotating at exactly the same speed as it was written (and there is no jitter in the clock supplied to the state machine, which I believe there is). Thus the read sequencer needs to allow for some variation - both fast & slow. Where problems can arrise is with two quick zero bits, or where there is 3 * ( 8 - ? ) - 1 cyles between one bits. The read pulse masking could reduce that number of cycles futher, which could cause the second zero bit to be lost since the state machine has to wait 2 * ( 8 + ? ) cycles to decode the zero bits.

 

Coming up with alternate state machines is an interesting exercise. The real limitation is there are only 16 MSB=0 states which have to handle stuffing the first two bits into the byte and then detecting the other six bits.

0 Comments


Recommended Comments

There are no comments to display.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...