Discussion:
Disk II experiments
(too old to reply)
Jorge
2017-06-27 08:50:29 UTC
Permalink
Hi,

There's a track every 2 steps of the head stepper, but the stepper can be moved to any track +/- 0, 0.25, 0.50 and 0.75.

So my question is this: can data be reliably saved and read back at track widths of 0.75 ? That's 1 and a half steps (or 0.75 track widths) instead of the usual two. Or about 46 tracks instead of the usual 35, or 188416 bytes per disk instead of 143360.

I guess the answer is no, but I thought better to ask before trying it.

Another question: if I were to put an avr insde the Disk II to modulate the spindle speed as a function of the current track, it should in theory be possible to put more than 16 sectors on the outer tracks, right? But how many more do you think?
--
Jorge.
Jorge
2017-06-27 10:58:57 UTC
Permalink
Post by Jorge
Hi,
There's a track every 2 steps of the head stepper, but the stepper can be moved to any track +/- 0, 0.25, 0.50 and 0.75.
So my question is this: can data be reliably saved and read back at track widths of 0.75 ? That's 1 and a half steps (or 0.75 track widths) instead of the usual two. Or about 46 tracks instead of the usual 35, or 188416 bytes per disk instead of 143360.
I guess the answer is no, but I thought better to ask before trying it.
Another question: if I were to put an avr insde the Disk II to modulate the spindle speed as a function of the current track, it should in theory be possible to put more than 16 sectors on the outer tracks, right? But how many more do you think?
--
Jorge.
Doing some math I think the outer track could hold 26 sectors instead of 16 at the same bit density as the inner track ($22), because it's IIANM, 1.64x times longer => 16*1,64 ~= 26. To achieve that the spindle ought to spin proportionally slower. The idea is to have the disk surface moving over the RW head at the same linear speed no matter what the track is.

Does it make sense?
--
Jorge.
Michael J. Mahon
2017-06-27 16:54:09 UTC
Permalink
Post by Jorge
Post by Jorge
Hi,
There's a track every 2 steps of the head stepper, but the stepper can
be moved to any track +/- 0, 0.25, 0.50 and 0.75.
So my question is this: can data be reliably saved and read back at
track widths of 0.75 ? That's 1 and a half steps (or 0.75 track widths)
instead of the usual two. Or about 46 tracks instead of the usual 35, or
188416 bytes per disk instead of 143360.
I guess the answer is no, but I thought better to ask before trying it.
Another question: if I were to put an avr insde the Disk II to modulate
the spindle speed as a function of the current track, it should in
theory be possible to put more than 16 sectors on the outer tracks,
right? But how many more do you think?
--
Jorge.
Doing some math I think the outer track could hold 26 sectors instead of
16 at the same bit density as the inner track ($22), because it's IIANM,
1.64x times longer => 16*1,64 ~= 26. To achieve that the spindle ought to
spin proportionally slower. The idea is to have the disk surface moving
over the RW head at the same linear speed no matter what the track is.
Does it make sense?
Yes, and it would work.

But note that seek times would be extended by the amount of time required
for the "new" speed to stabilize.

For this reason, so-called "zone recording" is sometimes used, which,
instead of changing the disk speed for each track, establishes ranges of
tracks ("zones") with different speeds.

This obtains most of the benefits of constant linear velocity, but with
many fewer speed changes. The Apple 3.5" 800kB disks are a good example of
zone recording with four speed zones.
--
-michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com
Jorge
2017-06-28 09:27:18 UTC
Permalink
Post by Michael J. Mahon
Post by Jorge
Doing some math I think the outer track could hold 26 sectors instead of
16 at the same bit density as the inner track ($22), because it's IIANM,
1.64x times longer => 16*1,64 ~= 26. To achieve that the spindle ought to
spin proportionally slower. The idea is to have the disk surface moving
over the RW head at the same linear speed no matter what the track is.
Does it make sense?
Yes, and it would work.
But note that seek times would be extended by the amount of time required
for the "new" speed to stabilize.
For this reason, so-called "zone recording" is sometimes used, which,
instead of changing the disk speed for each track, establishes ranges of
tracks ("zones") with different speeds.
This obtains most of the benefits of constant linear velocity, but with
many fewer speed changes. The Apple 3.5" 800kB disks are a good example of
zone recording with four speed zones.
And what do you think of the 0.75 track width, would that work too? Or will one tracks' data step onto the next/previous?
--
Jorge
John Brooks
2017-06-28 15:56:44 UTC
Permalink
Post by Jorge
Post by Michael J. Mahon
Post by Jorge
Doing some math I think the outer track could hold 26 sectors instead of
16 at the same bit density as the inner track ($22), because it's IIANM,
1.64x times longer => 16*1,64 ~= 26. To achieve that the spindle ought to
spin proportionally slower. The idea is to have the disk surface moving
over the RW head at the same linear speed no matter what the track is.
Does it make sense?
Yes, and it would work.
But note that seek times would be extended by the amount of time required
for the "new" speed to stabilize.
For this reason, so-called "zone recording" is sometimes used, which,
instead of changing the disk speed for each track, establishes ranges of
tracks ("zones") with different speeds.
This obtains most of the benefits of constant linear velocity, but with
many fewer speed changes. The Apple 3.5" 800kB disks are a good example of
zone recording with four speed zones.
And what do you think of the 0.75 track width, would that work too? Or will one tracks' data step onto the next/previous?
--
Jorge
0.75 track width (and smaller) can be read, but re-writing will erase/corrupt the adjacent 0.75 tracks.

I've been able to get 66 tracks (0.55 track width) via micro-stepping the head and writing all tracks in sequence from the outer track to the inner track. Each track when written partially overlaps the previously written neighbor to the outside. Think overlapped shingles on a roof.

This is an 'entire disk' single-pass write. To change any data, all 66 tracks on the disk must be rewritten from outer to inner.

The 300 RPM disk speed matches the floppy media bit density spec at track 40 (IIRC). Since the Disk][ does not detect and control the disk speed, the last 5 tracks are unused so that writing on a 5% slower drive (285 RPM) does not exceed the media bit density at the innermost track.


The disk encoding can also be improved. The disk controller allows 81 valid nibbles, of which 66 are normally used (64 for 6&2 encoding + $D5 + $AA). Encoding using all 81 nibbles gives 5% more data (6.33 data bits per disk nibble).

Note that the limiting factor on the Disk ][ is usually reading rather than writing. If a slow drive writes a higher-density floppy which is then read on a normal or fast drive, the nibbles can come in so fast that the LDA $C0EC, BPL *-5 disk read loop will start missing nibbles.

This is why Apple's spec is for 300 RPM +/- 5%. The read loop works up to 10% faster bit rates which correspond to a 315 RPM drive reading data written at 285 RPM.

-JB
@JBrooksBSI
Jorge
2017-07-03 20:47:41 UTC
Permalink
Post by John Brooks
Post by Jorge
Post by Michael J. Mahon
Post by Jorge
Doing some math I think the outer track could hold 26 sectors instead of
16 at the same bit density as the inner track ($22), because it's IIANM,
1.64x times longer => 16*1,64 ~= 26. To achieve that the spindle ought to
spin proportionally slower. The idea is to have the disk surface moving
over the RW head at the same linear speed no matter what the track is.
Does it make sense?
Yes, and it would work.
But note that seek times would be extended by the amount of time required
for the "new" speed to stabilize.
For this reason, so-called "zone recording" is sometimes used, which,
instead of changing the disk speed for each track, establishes ranges of
tracks ("zones") with different speeds.
This obtains most of the benefits of constant linear velocity, but with
many fewer speed changes. The Apple 3.5" 800kB disks are a good example of
zone recording with four speed zones.
And what do you think of the 0.75 track width, would that work too? Or will one tracks' data step onto the next/previous?
--
Jorge
0.75 track width (and smaller) can be read, but re-writing will erase/corrupt the adjacent 0.75 tracks.
I've been able to get 66 tracks (0.55 track width) via micro-stepping the head and writing all tracks in sequence from the outer track to the inner track. Each track when written partially overlaps the previously written neighbor to the outside. Think overlapped shingles on a roof.
This is an 'entire disk' single-pass write. To change any data, all 66 tracks on the disk must be rewritten from outer to inner.
The 300 RPM disk speed matches the floppy media bit density spec at track 40 (IIRC). Since the Disk][ does not detect and control the disk speed, the last 5 tracks are unused so that writing on a 5% slower drive (285 RPM) does not exceed the media bit density at the innermost track.
The disk encoding can also be improved. The disk controller allows 81 valid nibbles, of which 66 are normally used (64 for 6&2 encoding + $D5 + $AA). Encoding using all 81 nibbles gives 5% more data (6.33 data bits per disk nibble).
Note that the limiting factor on the Disk ][ is usually reading rather than writing. If a slow drive writes a higher-density floppy which is then read on a normal or fast drive, the nibbles can come in so fast that the LDA $C0EC, BPL *-5 disk read loop will start missing nibbles.
This is why Apple's spec is for 300 RPM +/- 5%. The read loop works up to 10% faster bit rates which correspond to a 315 RPM drive reading data written at 285 RPM.
-JB
@JBrooksBSI
Wow, thanks John, that's much moar and much better info than I would have ever dreamed.

So the take-home message for me is the disk II erase head is too wide for 0.75. Right? It's a pity!

I wonder what did you use / how did you do the microstepping? Don't you need a variable voltage for the phases for that to work? The disk II interface bd can't do that!

Thanks,
--
Jorge.
John Brooks
2017-07-03 21:22:52 UTC
Permalink
Post by Jorge
Post by John Brooks
Post by Jorge
Post by Michael J. Mahon
Post by Jorge
Doing some math I think the outer track could hold 26 sectors instead of
16 at the same bit density as the inner track ($22), because it's IIANM,
1.64x times longer => 16*1,64 ~= 26. To achieve that the spindle ought to
spin proportionally slower. The idea is to have the disk surface moving
over the RW head at the same linear speed no matter what the track is.
Does it make sense?
Yes, and it would work.
But note that seek times would be extended by the amount of time required
for the "new" speed to stabilize.
For this reason, so-called "zone recording" is sometimes used, which,
instead of changing the disk speed for each track, establishes ranges of
tracks ("zones") with different speeds.
This obtains most of the benefits of constant linear velocity, but with
many fewer speed changes. The Apple 3.5" 800kB disks are a good example of
zone recording with four speed zones.
And what do you think of the 0.75 track width, would that work too? Or will one tracks' data step onto the next/previous?
--
Jorge
0.75 track width (and smaller) can be read, but re-writing will erase/corrupt the adjacent 0.75 tracks.
I've been able to get 66 tracks (0.55 track width) via micro-stepping the head and writing all tracks in sequence from the outer track to the inner track. Each track when written partially overlaps the previously written neighbor to the outside. Think overlapped shingles on a roof.
This is an 'entire disk' single-pass write. To change any data, all 66 tracks on the disk must be rewritten from outer to inner.
The 300 RPM disk speed matches the floppy media bit density spec at track 40 (IIRC). Since the Disk][ does not detect and control the disk speed, the last 5 tracks are unused so that writing on a 5% slower drive (285 RPM) does not exceed the media bit density at the innermost track.
The disk encoding can also be improved. The disk controller allows 81 valid nibbles, of which 66 are normally used (64 for 6&2 encoding + $D5 + $AA). Encoding using all 81 nibbles gives 5% more data (6.33 data bits per disk nibble).
Note that the limiting factor on the Disk ][ is usually reading rather than writing. If a slow drive writes a higher-density floppy which is then read on a normal or fast drive, the nibbles can come in so fast that the LDA $C0EC, BPL *-5 disk read loop will start missing nibbles.
This is why Apple's spec is for 300 RPM +/- 5%. The read loop works up to 10% faster bit rates which correspond to a 315 RPM drive reading data written at 285 RPM.
-JB
@JBrooksBSI
Wow, thanks John, that's much moar and much better info than I would have ever dreamed.
So the take-home message for me is the disk II erase head is too wide for 0.75. Right? It's a pity!
I wonder what did you use / how did you do the microstepping? Don't you need a variable voltage for the phases for that to work? The disk II interface bd can't do that!
Thanks,
--
Jorge.
So the take-home message for me is the disk II erase head is too wide for 0.75. Right? It's a pity!

Yes, my experiments indicate that the erase head is approximately 0.85 tracks wide and the minimum readable track width using overlapped tracks is 0.55 of a track.

This results in a max track count of 36.5/0.55 = 66 overlapped tracks.
Post by Jorge
I wonder what did you use / how did you do the microstepping?
Micro-stepping is done by using a shortened CPU delay when the head stepper phases are enabled - ie, stopping the head-step before the head reaches the next track.

-JB
@JBrooksBSI
Jorge
2017-07-04 07:55:41 UTC
Permalink
Post by John Brooks
Post by Jorge
I wonder what did you use / how did you do the microstepping?
Micro-stepping is done by using a shortened CPU delay when the head stepper phases are enabled - ie, stopping the head-step before the head reaches the next track.
I always thought (erroneously?) that the driver left the phase on while reading/writing to hold/lock the head in place. I do the 0.25 and 0.75 steps by turning on (and leaving them on) two phases at once, but with pulse length modulation you can't do that and must turn it off at the exact right moment.

Amazing, that's cool!

Thanks,
--
Jorge.
Michael J. Mahon
2017-07-04 16:29:11 UTC
Permalink
Post by Jorge
Post by John Brooks
Post by Jorge
I wonder what did you use / how did you do the microstepping?
Micro-stepping is done by using a shortened CPU delay when the head
stepper phases are enabled - ie, stopping the head-step before the head
reaches the next track.
I always thought (erroneously?) that the driver left the phase on while
reading/writing to hold/lock the head in place. I do the 0.25 and 0.75
steps by turning on (and leaving them on) two phases at once, but with
pulse length modulation you can't do that and must turn it off at the exact right moment.
Amazing, that's cool!
Thanks,
And, in fact, writing is disabled at the drive if one of the phases is left
on (I'd have to check which phase).
--
-michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com
Michael 'AppleWin Debugger Dev'
2017-07-04 21:52:15 UTC
Permalink
Post by John Brooks
Micro-stepping is done by using a shortened CPU delay when the head stepper phases are enabled - ie, stopping the head-step before the head reaches the next track.
Speaking of delays:

* What timing delay are you using? Also,
* What is the bare minimum delay for (proper) 1/4 track stepping?

For the latter, I noticed the PROM ($C600) firmware on both my //e and //c uses a timing value of $56 calling WAIT (FCA8).

Apple //e
C64A: LDA #$56
C64C: JSR WAIT

Apple //c
C62C: LDA #$56
C62E: JSR WAIT

Fantavision uses a delay of $28 with WAIT. What's a bare minimum value to wait?
(It probably wouldn't hurt to review the microseconds WAIT delays.)

The otherwise excellent "Beneath Apple DOS" is completely rubbish in this case.
It hand-waves by giving this total crap excuse on Page 6-3:

"The timing between accesses to these locations is critical, making this a non-trivial exercise."

To which I respond "No Shit, Sherlock -- but what is the _formula_ or timing that is recommend, or even the minimum to make sure the head has arrived ?"

IIRC either DOS3.3 RTWTS or ProDOS recommends waiting 150 ms when turning the motor on, but I don't recall the time between phases.

I finally got around to writing a SeekTrack routine this weekend and am using this code:

; Seek Zero-Page Vars
PrevTrack2 = $FD ; Track * 2
NextTrack2 = $FE ; Track * 2
WantTrack2 = $FF ; Track * 2


; P5A ROM Firmware
P5_Buffer = $26 ; 16-bit pointer
P5_SlotX16 = $2B
P5_SectorWant = $3D
P5_TrackHave = $40 ; $C685: STA P5_TrackHave -- last read track
P5_TrackWant = $41 ;

; Drive
DRIVE_PHASE_MASK = $3
DRIVE_PHASE_0_OFF = $C080
DRIVE_PHASE_0_ON = $C081
DRIVE_PHASE_1_OFF = $C082
DRIVE_PHASE_1_ON = $C083
DRIVE_PHASE_2_OFF = $C084
DRIVE_PHASE_2_ON = $C085
DRIVE_PHASE_3_OFF = $C086
DRIVE_PHASE_3_ON = $C087
DRIVE_MOTOR_OFF = $C088

; F800 ROM
WAIT = $FCA8


i.e.
; --------------------
; INPUT: A = Track to Seek
; P5_SlotX16 = Slot * 16
; OUTPUT:
; Track to Seek -> P5_TrackWant
; NOTE: Drive must already be on!
; --------------------
SeekTrack
STA P5_TrackWant ; Needed for $C65C ReadSector
ASL
STA WantTrack2

SeekLoop
LDA NextTrack2
STA PrevTrack2
CMP WantTrack2 ; A=TrackWant == TrackHave ?
BEQ SeekDone
BCC SeekIn ; Q. Have < Want?
SeekOut ; No
DEC NextTrack2
DEC NextTrack2
SeekIn ; Yes
INC NextTrack2
SeekMove ; Move IN to Trk $22 |
LDA NextTrack2 ; C0E3 Phase 1 On |
SEC ; C0E0 Phase 0 Off |
JSR SeekPhase ; C0E5 Phase 2 On |
; C0E2 Phase 1 Off |
LDA PrevTrack2 ; C0E7 Phase 3 On |
CLC ; C0E4 Phase 2 Off |
JSR SeekPhase ; C0E1 Phase 0 On |
; C0E6 Phase 3 Off |
BEQ SeekLoop ; A=0, Always
SeekDone
RTS

SeekPhase
PHP ; Save carry
AND #DRIVE_PHASE_MASK ;
ASL ;
ORA P5_SlotX16 ;X=$60
PLP ; C=1 Phase On
ADC #0 ; C=0 Phase Off
TAX ;
LDA DRIVE_PHASE_0_OFF,X ; $Cx8c
DiskWait
LDA #$28 ; P(5A)ROM delay = $56, Fantavision = $28
JMP WAIT
Jorge
2017-07-04 22:23:57 UTC
Permalink
Post by Michael 'AppleWin Debugger Dev'
Post by John Brooks
Micro-stepping is done by using a shortened CPU delay when the head stepper phases are enabled - ie, stopping the head-step before the head reaches the next track.
* What timing delay are you using? Also,
* What is the bare minimum delay for (proper) 1/4 track stepping?
For the latter, I noticed the PROM ($C600) firmware on both my //e and //c uses a timing value of $56 calling WAIT (FCA8).
Apple //e
C64A: LDA #$56
C64C: JSR WAIT
Apple //c
C62C: LDA #$56
C62E: JSR WAIT
Fantavision uses a delay of $28 with WAIT. What's a bare minimum value to wait?
(It probably wouldn't hurt to review the microseconds WAIT delays.)
The otherwise excellent "Beneath Apple DOS" is completely rubbish in this case.
"The timing between accesses to these locations is critical, making this a non-trivial exercise."
To which I respond "No Shit, Sherlock -- but what is the _formula_ or timing that is recommend, or even the minimum to make sure the head has arrived ?"
IIRC either DOS3.3 RTWTS or ProDOS recommends waiting 150 ms when turning the motor on, but I don't recall the time between phases.
; Seek Zero-Page Vars
PrevTrack2 = $FD ; Track * 2
NextTrack2 = $FE ; Track * 2
WantTrack2 = $FF ; Track * 2
; P5A ROM Firmware
P5_Buffer = $26 ; 16-bit pointer
P5_SlotX16 = $2B
P5_SectorWant = $3D
P5_TrackHave = $40 ; $C685: STA P5_TrackHave -- last read track
P5_TrackWant = $41 ;
; Drive
DRIVE_PHASE_MASK = $3
DRIVE_PHASE_0_OFF = $C080
DRIVE_PHASE_0_ON = $C081
DRIVE_PHASE_1_OFF = $C082
DRIVE_PHASE_1_ON = $C083
DRIVE_PHASE_2_OFF = $C084
DRIVE_PHASE_2_ON = $C085
DRIVE_PHASE_3_OFF = $C086
DRIVE_PHASE_3_ON = $C087
DRIVE_MOTOR_OFF = $C088
; F800 ROM
WAIT = $FCA8
i.e.
; --------------------
; INPUT: A = Track to Seek
; P5_SlotX16 = Slot * 16
; Track to Seek -> P5_TrackWant
; NOTE: Drive must already be on!
; --------------------
SeekTrack
STA P5_TrackWant ; Needed for $C65C ReadSector
ASL
STA WantTrack2
SeekLoop
LDA NextTrack2
STA PrevTrack2
CMP WantTrack2 ; A=TrackWant == TrackHave ?
BEQ SeekDone
BCC SeekIn ; Q. Have < Want?
SeekOut ; No
DEC NextTrack2
DEC NextTrack2
SeekIn ; Yes
INC NextTrack2
SeekMove ; Move IN to Trk $22 |
LDA NextTrack2 ; C0E3 Phase 1 On |
SEC ; C0E0 Phase 0 Off |
JSR SeekPhase ; C0E5 Phase 2 On |
; C0E2 Phase 1 Off |
LDA PrevTrack2 ; C0E7 Phase 3 On |
CLC ; C0E4 Phase 2 Off |
JSR SeekPhase ; C0E1 Phase 0 On |
; C0E6 Phase 3 Off |
BEQ SeekLoop ; A=0, Always
SeekDone
RTS
SeekPhase
PHP ; Save carry
AND #DRIVE_PHASE_MASK ;
ASL ;
ORA P5_SlotX16 ;X=$60
PLP ; C=1 Phase On
ADC #0 ; C=0 Phase Off
TAX ;
LDA DRIVE_PHASE_0_OFF,X ; $Cx8c
DiskWait
LDA #$28 ; P(5A)ROM delay = $56, Fantavision = $28
JMP WAIT
LOL I did the same but in Applesoft. My "wait" is a for n= 0 to 2 : next n, wahaha, and it works! I have to try turning the next phase on before turning the pevious one off, perhaps the movement is smoother and with more torque/oomph => faster seeks (?), idk.
Michael J. Mahon
2017-07-05 07:20:38 UTC
Permalink
Post by Jorge
Post by Michael 'AppleWin Debugger Dev'
Post by John Brooks
Micro-stepping is done by using a shortened CPU delay when the head
stepper phases are enabled - ie, stopping the head-step before the head
reaches the next track.
* What timing delay are you using? Also,
* What is the bare minimum delay for (proper) 1/4 track stepping?
For the latter, I noticed the PROM ($C600) firmware on both my //e and
//c uses a timing value of $56 calling WAIT (FCA8).
Apple //e
C64A: LDA #$56
C64C: JSR WAIT
Apple //c
C62C: LDA #$56
C62E: JSR WAIT
Fantavision uses a delay of $28 with WAIT. What's a bare minimum value to wait?
(It probably wouldn't hurt to review the microseconds WAIT delays.)
The otherwise excellent "Beneath Apple DOS" is completely rubbish in this case.
"The timing between accesses to these locations is critical, making this
a non-trivial exercise."
To which I respond "No Shit, Sherlock -- but what is the _formula_ or
timing that is recommend, or even the minimum to make sure the head has arrived ?"
IIRC either DOS3.3 RTWTS or ProDOS recommends waiting 150 ms when
turning the motor on, but I don't recall the time between phases.
; Seek Zero-Page Vars
PrevTrack2 = $FD ; Track * 2
NextTrack2 = $FE ; Track * 2
WantTrack2 = $FF ; Track * 2
; P5A ROM Firmware
P5_Buffer = $26 ; 16-bit pointer
P5_SlotX16 = $2B
P5_SectorWant = $3D
P5_TrackHave = $40 ; $C685: STA P5_TrackHave -- last read track
P5_TrackWant = $41 ;
; Drive
DRIVE_PHASE_MASK = $3
DRIVE_PHASE_0_OFF = $C080
DRIVE_PHASE_0_ON = $C081
DRIVE_PHASE_1_OFF = $C082
DRIVE_PHASE_1_ON = $C083
DRIVE_PHASE_2_OFF = $C084
DRIVE_PHASE_2_ON = $C085
DRIVE_PHASE_3_OFF = $C086
DRIVE_PHASE_3_ON = $C087
DRIVE_MOTOR_OFF = $C088
; F800 ROM
WAIT = $FCA8
i.e.
; --------------------
; INPUT: A = Track to Seek
; P5_SlotX16 = Slot * 16
; Track to Seek -> P5_TrackWant
; NOTE: Drive must already be on!
; --------------------
SeekTrack
STA P5_TrackWant ; Needed for $C65C ReadSector
ASL
STA WantTrack2
SeekLoop
LDA NextTrack2
STA PrevTrack2
CMP WantTrack2 ; A=TrackWant == TrackHave ?
BEQ SeekDone
BCC SeekIn ; Q. Have < Want?
SeekOut ; No
DEC NextTrack2
DEC NextTrack2
SeekIn ; Yes
INC NextTrack2
SeekMove ; Move IN to Trk $22 |
LDA NextTrack2 ; C0E3 Phase 1 On |
SEC ; C0E0 Phase 0 Off |
JSR SeekPhase ; C0E5 Phase 2 On |
; C0E2 Phase 1 Off |
LDA PrevTrack2 ; C0E7 Phase 3 On |
CLC ; C0E4 Phase 2 Off |
JSR SeekPhase ; C0E1 Phase 0 On |
; C0E6 Phase 3 Off |
BEQ SeekLoop ; A=0, Always
SeekDone
RTS
SeekPhase
PHP ; Save carry
AND #DRIVE_PHASE_MASK ;
ASL ;
ORA P5_SlotX16 ;X=$60
PLP ; C=1 Phase On
ADC #0 ; C=0 Phase Off
TAX ;
LDA DRIVE_PHASE_0_OFF,X ; $Cx8c
DiskWait
LDA #$28 ; P(5A)ROM delay = $56, Fantavision = $28
JMP WAIT
LOL I did the same but in Applesoft. My "wait" is a for n= 0 to 2 : next
n, wahaha, and it works! I have to try turning the next phase on before
turning the pevious one off, perhaps the movement is smoother and with
more torque/oomph => faster seeks (?), idk.
Yes, that's the recommended sequence for stepping.

The wait time between phases is not constant, since all Apple RWTSs use a
table to accelerate and then decelerate during a seek. This is why drives
for Apple II's seek faster than the same manufacturers drive on non-Apple
systems.
--
-michael - NadaNet 3.1 and AppleCrate II: http://michaeljmahon.com
Michael 'AppleWin Debugger Dev'
2017-07-05 14:05:32 UTC
Permalink
Post by Michael J. Mahon
all Apple RWTSs use a
table to accelerate and then decelerate during a seek.

Not to question Woz's code but does any one have any seek timings:

a) with, and
b) without

the acceleration table?

I'm just wondering how much of a benefit (timewise) given the increase code space and complexity.

I noticed Roland Gustafsson uses it in his RWTS18 code as well so I'm assuming it must be noticeable?
IIRC he mentioned he just copied these from DOS. :-/

https://github.com/Michaelangel007/apple2_rwts18/blob/master/rwts18_merlin.s

:3 SEC
JSR SEEKTOG1
LDA SEEKTBL1,Y
JSR SEEKDELY
LDA TMP1
CLC
JSR SEEKTOGL
LDA SEEKTBL2,Y
JSR SEEKDELY
INC TMP0
BNE SEEKLOOP
SEEKTOG2 JSR SEEKDELY
CLC
SEEKTOG1 LDA LASTRACK
;
SEEKTOGL AND #$03
ROL
ORA SLOT
TAX
LDA $C080,X
SEEKDONE LDX SLOT
RTS
;
SEEKDELY LDX #$13
:0 DEX
BNE :0
SEC
SBC #1
BNE SEEKDELY
RTS
;
; Acceleration/deceleration tables
;
SEEKTBL1 HEX 01302824201E1D1C1C1C1C1C
SEEKTBL2 HEX 702C26221F1E1D1C1C1C1C1C
qkumba
2017-07-05 17:43:29 UTC
Permalink
Post by Michael 'AppleWin Debugger Dev'
I noticed Roland Gustafsson uses it in his RWTS18 code as well so I'm assuming it must be noticeable?
IIRC he mentioned he just copied these from DOS. :-/
Yes, he copied the DOS code, as did most people.
I wrote a smaller for 0boot with fixed timing, and one with variable timing for qboot and Directi-DOS, among others (but also based on the DOS timing, though my table is half of the size).

The wait-after-drive-on is critical, either by polling or just waiting long enough. Otherwise, depending on the drive, the drive head won't land where you expect.
Michael 'AppleWin Debugger Dev'
2017-07-05 18:28:28 UTC
Permalink
Post by qkumba
I wrote a smaller for 0boot with fixed timing
Guess I probably should go study your source :-)
https://github.com/peterferrie/0boot/blob/master/0BOOT.S

Ah, this code ...

wait = $fca8

seek ;requires carry set on entry
inc <(curtrk+1) ;phase on
curtrk
ldy #$3f ;constant used in table init, self-mod later
lda #4
jsr delay
dey ;phase off
adc #$41 ;clear carry while setting #$42
delay
sta <(setdelay+1)
tya
and #3
rol
tax
slotpatch6
lda $c0d1, x
setdelay
lda #$d1
jmp wait


BTW, gratz on joining the Nox Archaist team!
http://www.6502workshop.com/2017/06/new-6502-workshop-team-members-qkumba.html
Michael 'AppleWin Debugger Dev'
2017-07-05 18:45:28 UTC
Permalink
For completeness, relevant seek code and phase timing code from ProRWTS
https://github.com/peterferrie/prorwts/blob/master/PRORWTS.S

seekret rts

;no tricks here, just the regular stuff

seek sty step
asl phase
txa
asl
copy_cur tax
sta tmptrk
sec
sbc phase
beq +++
bcs +
eor #$ff
inx
bcc ++
+ sbc #1
dex
++ cmp step
bcc +
lda step
+ cmp #8
bcs +
tay
sec
+ txa
pha
ldx step1, y
+++ php
bne +
--- clc
lda tmptrk
ldx step2, y
+ stx tmpsec
and #3
rol
tax
lsr
unrseek=unrelocdsk+(*-reloc)
lda PHASEOFF, x
-- ldx #$13
- dex
bne -
dec tmpsec
bne --
bcs ---
plp
beq seekret
pla
inc step
bne copy_cur

step1 !byte 1, $30, $28, $24, $20, $1e, $1d, $1c
step2 !byte $70, $2c, $26, $22, $1f, $1e, $1d, $1c

Michael 'AppleWin Debugger Dev'
2017-07-05 17:44:20 UTC
Permalink
Seek timing code from DOS 3.3 source, Page 97
Exactly how time is this code saving over the naive seek using LDA #$28, JST WAIT ?

3A00:A2 11 031 MSWAIT LDX #$11
3A02:CA 032 MSW1 DEX DELAY 86 USEC.
3A03:D0 FD 033 BNE MSW1
3A05:E6 46 034 INC MONTIMEL
3A07:D0 02 035 BNE MSW2 ; DOUBLE-BYTE
3A09:E6 47 036 INC MONTIMEH INCREMENT.
3A0B:38 037 MSW2 SEC
3A0C:E9 01 038 SBC #$1 DONE 'N' INTERVALS?
3A0E:D0 F0 039 BNE MSWAIT (A-REG COUNTS)
3A10:60 040 RTS
041 AEC1 EQU * ;TELL RELOCATOR WHERE CORE ENDS
042 **************************
043 * PHASE ON-, OFF-TIME *
044 * TABLES IN 100-USEC *
045 * INTERVALS. (SEEK) *
046 **************************
3A11:01 30 28 047 ONTABLE DFB 1,$30,$28
3A14:24 20 1E 048 DFB $24,$20,$1E
3A17:1D 1C 1C 049 DFB $1D,$1C,$1C
3A1A:1C 1C 1C 050 DFB $1C,$1C,$1C
3A1D:70 2C 26 051 OFFTABLE DFB $70,$2C,$26
3A20:22 1F 1E 052 DFB $22,$1F,$1E
3A23:1D 1C 1C 053 DFB $1D,$1C,$1C
3A26:1C 1C 1C 054 DFB $1C,$1C,$1C
055 SBTL '16-SECTOR NYBBLE TABLES'

Called from Page 108

39A0:86 2B 151 SEEK STX SLOTTEMP ;SAVE X-REG
39A2:85 2A 152 STA TRKN ;SAVE TARGET TRACK
39A4:CD 78 04 153 CMP CURTRK ON DESIRED TRACK?
39A7:F0 53 154 BEQ SEEKRTS ;YES, RETURN
39A9:A9 00 155 LDA #$0
39AB:85 26 156 STA TRKCNT ;HALFTRACK COUNT.
39AD:AD 78 04 157 SEEK2 LDA CURTRK ;SAVE CURTRK FOR
39B0:85 27 158 STA PRIOR ; DELAYED TURNOFF.
39B2:38 159 SEC
39B3:E5 2A 160 SBC TRKN ;DELTA-TRACKS.
39B5:F0 33 161 BEQ SEEKEND ;BR IF CURTRK=DESTINATION
39B7:B0 07 162 BCS OUT (MOVE OUT, NOT IN)
39B9:49 FF 163 EOR #$FF CALC TRKS TO GO
39BB:EE 78 04 164 INC CURTRK INCR CURRENT TRACK (IN).
39BE:90 05 165 BCC MINTST (ALWAYS TAKEN)
39C0:69 FE 166 OUT ADC #$FE CALC TRKS TO GO.
39C2:CE 78 04 167 DEC CURTRK DECR CURRENT TRACK (OUT).
39C7:C5 26 168 MINTST CMP TRKCNT
39C7:90 02 169 BCC MAXTST AND 'TRKS MOVED'.
39C9:A5 26 170 LDA TRKCNT
39CB:C9 0C 171 MAXTST CMP #$C
39CD:BB 01 172 BCS STEP2 ;IF TRKCNT>$B LEAVE Y ALONE (Y=$B).
39CF:A8 173 STEP TAY ;ELSE SET ACCELERATION INDEX IN Y
174 STEP2 EQU *
39D0:38 175 SEC ;CARRY SET=PHASE ON
39D1:20 EE 39 176 JSR SETPHASE ;PHASE ON
39D4:B9 11 3A 177 LDA ONTABLE,Y FOR 'ONTIME'.
39D7:20 00 3A 178 JSR MSWAIT (100 USEC INTERVALS)
179 *
39DA:A5 27 180 LDA PRIOR
39DC:18 181 CLC ;CARRY CLEAR=PHASE OFF
39DD:20 F1 39 182 JSR CLRPHASE ;PHASE OFF
39E0:BD 1D 3A 183 LDA OFFTABLE,Y THEN WAIT 'OFFTIME'.
39E3:20 00 3A 184 JSR MSWAIT (100 USEC INTERVALS)
39E6:E6 26 185 INC TRKCNT 'TRACKS MOVED' COUNT.
39E8:D0 C3 186 BNE SEEK2 (ALWAYS TAKEN)
187 *
188 SEEKEND EQU *
39EA:20 00 3A 189 JSR MSWAIT ;A=0: WAIT 25 MS SETTLE
39ED:18 190 CLC
Michael 'AppleWin Debugger Dev'
2017-07-05 18:16:08 UTC
Permalink
Looks like the phase timing tables got trimmed by 4 entries for ProDOS?

Corresponding ProDOS seek source from Page 285

seek sta trkn
cmp curtrk
beq setphase
lda #0
sta trkcnt
seek2 lda curtrk
sta prior
sec
sbc trkn
beq seekend
bcs out
eor #$ff
inc curtrk
bcc mintst
out adc #$fe
dec curtrk
mintst cmp trkcnt
bcc maxtst
lda trkcnt
maxtst cmp #$9
bcs step2 ;if trkcnt>$8 leave y alone (y=$8)
tay ;else set acceleration index in y
sec
step2 jsr setphase
lda ontable,y ;for 'ontime'.
jsr mswait ;(100 usec intervals)
lda prior
clc
jsr clrphase
lda offtable,y
jsr mswait
inc trkcnt
bne seek2
seekend jsr mswait ;settle 25 msec
clc
setphase lda curtrk
clrphase and #3
rol a
ora slotz
tax
lda phaseoff,x
ldx slotz
rts


The phase on/off delay tables are on Page 288

**************************
* *
* phase on-, off-time *
* tables in 100-usec *
* intervals. (seek) *
* *
**************************
ontable dfb 1,$30,$28
dfb $24,$20,$1e
dfb $1d,$1c,$1c
offtable dfb $70,$2c,$26
dfb $22,$1f,$1e
dfb $1d,$1c,$1c


mswait ldx #$11
msw1 dex delay 86 usec.
bne msw1
inc montimel
bne msw2 double-byte
inc montimeh increment.
msw2 sec
sbc #$1 done 'n' intervals?
bne mswait (a-reg counts)
rts
John Brooks
2017-07-04 22:57:31 UTC
Permalink
Post by Michael 'AppleWin Debugger Dev'
Post by John Brooks
Micro-stepping is done by using a shortened CPU delay when the head stepper phases are enabled - ie, stopping the head-step before the head reaches the next track.
* What timing delay are you using? Also,
* What is the bare minimum delay for (proper) 1/4 track stepping?
For the latter, I noticed the PROM ($C600) firmware on both my //e and //c uses a timing value of $56 calling WAIT (FCA8).
Apple //e
C64A: LDA #$56
C64C: JSR WAIT
Apple //c
C62C: LDA #$56
C62E: JSR WAIT
Fantavision uses a delay of $28 with WAIT. What's a bare minimum value to wait?
(It probably wouldn't hurt to review the microseconds WAIT delays.)
The otherwise excellent "Beneath Apple DOS" is completely rubbish in this case.
"The timing between accesses to these locations is critical, making this a non-trivial exercise."
To which I respond "No Shit, Sherlock -- but what is the _formula_ or timing that is recommend, or even the minimum to make sure the head has arrived ?"
IIRC either DOS3.3 RTWTS or ProDOS recommends waiting 150 ms when turning the motor on, but I don't recall the time between phases.
; Seek Zero-Page Vars
PrevTrack2 = $FD ; Track * 2
NextTrack2 = $FE ; Track * 2
WantTrack2 = $FF ; Track * 2
; P5A ROM Firmware
P5_Buffer = $26 ; 16-bit pointer
P5_SlotX16 = $2B
P5_SectorWant = $3D
P5_TrackHave = $40 ; $C685: STA P5_TrackHave -- last read track
P5_TrackWant = $41 ;
; Drive
DRIVE_PHASE_MASK = $3
DRIVE_PHASE_0_OFF = $C080
DRIVE_PHASE_0_ON = $C081
DRIVE_PHASE_1_OFF = $C082
DRIVE_PHASE_1_ON = $C083
DRIVE_PHASE_2_OFF = $C084
DRIVE_PHASE_2_ON = $C085
DRIVE_PHASE_3_OFF = $C086
DRIVE_PHASE_3_ON = $C087
DRIVE_MOTOR_OFF = $C088
; F800 ROM
WAIT = $FCA8
i.e.
; --------------------
; INPUT: A = Track to Seek
; P5_SlotX16 = Slot * 16
; Track to Seek -> P5_TrackWant
; NOTE: Drive must already be on!
; --------------------
SeekTrack
STA P5_TrackWant ; Needed for $C65C ReadSector
ASL
STA WantTrack2
SeekLoop
LDA NextTrack2
STA PrevTrack2
CMP WantTrack2 ; A=TrackWant == TrackHave ?
BEQ SeekDone
BCC SeekIn ; Q. Have < Want?
SeekOut ; No
DEC NextTrack2
DEC NextTrack2
SeekIn ; Yes
INC NextTrack2
SeekMove ; Move IN to Trk $22 |
LDA NextTrack2 ; C0E3 Phase 1 On |
SEC ; C0E0 Phase 0 Off |
JSR SeekPhase ; C0E5 Phase 2 On |
; C0E2 Phase 1 Off |
LDA PrevTrack2 ; C0E7 Phase 3 On |
CLC ; C0E4 Phase 2 Off |
JSR SeekPhase ; C0E1 Phase 0 On |
; C0E6 Phase 3 Off |
BEQ SeekLoop ; A=0, Always
SeekDone
RTS
SeekPhase
PHP ; Save carry
AND #DRIVE_PHASE_MASK ;
ASL ;
ORA P5_SlotX16 ;X=$60
PLP ; C=1 Phase On
ADC #0 ; C=0 Phase Off
TAX ;
LDA DRIVE_PHASE_0_OFF,X ; $Cx8c
DiskWait
LDA #$28 ; P(5A)ROM delay = $56, Fantavision = $28
JMP WAIT
* What timing delay are you using?

I'm not at my physical IIGS today to look at code, but the head-step speed and timing depends on the individual drive and likely the Apple II power supply. It also depends on where the head is starting (1/4 tracks are closer to the phase magnet than 1/2 or whole tracks).

* What is the bare minimum delay for (proper) 1/4 track stepping?

Again it's drive specific. I only use fixed 1/4 step delays when writing, and there I use conservative (ie slow) wait times for safety. For reading I just leave both phases enabled and early-out when the head reads a valid sector header. This gives minimum step delay for the specific drive+PSU.
Post by Michael 'AppleWin Debugger Dev'
IIRC either DOS3.3 RTWTS or ProDOS recommends waiting 150 ms when turning the motor on, but I don't recall the time between phases.
Instead of waiting for spindle spin-up via a fixed 150ms mswait delay, I early-out when an $FF nibble is read by the head. Reading an $FF requires flux changes at least every 5.7usec which means the drive is at least 210 RPM and able to differentiate between %11 and %10 data bits.

During spin-up, at ~50RPM $FF,$FF reads as $92,$92 (%10010010[sync0]), then at ~100RPM reads as $AA(%10101010).

IIRC, a 35-track floppy reads in about 8.5 seconds using these minimal-delay techniques.

-JB
@JBrooksBSI
Nick Westgate
2017-07-05 04:33:23 UTC
Permalink
Post by Michael 'AppleWin Debugger Dev'
The otherwise excellent "Beneath Apple DOS" is completely rubbish in this case.
"The timing between accesses to these locations is critical, making this a non-trivial exercise."
To which I respond "No Shit, Sherlock -- but what is the _formula_ or timing that is recommend, or even the minimum to make sure the head has arrived ?"
It makes sense as John says that it's drive (model at least) specific.

Even Sather doesn't document these values, though in his quoted conversation with Woz (on the way to the airport) Woz says he wrote the stepping code and worked out those value, though he doesn't say how.

Cheers,
Nick.
Tom Greene
2017-06-27 17:31:21 UTC
Permalink
Post by Jorge
Hi,
There's a track every 2 steps of the head stepper, but the stepper can be moved to any track +/- 0, 0.25, 0.50 and 0.75.
So my question is this: can data be reliably saved and read back at track widths of 0.75 ? That's 1 and a half steps (or 0.75 track widths) instead of the usual two. Or about 46 tracks instead of the usual 35, or 188416 bytes per disk instead of 143360.
I guess the answer is no, but I thought better to ask before trying it.
Another question: if I were to put an avr insde the Disk II to modulate the spindle speed as a function of the current track, it should in theory be possible to put more than 16 sectors on the outer tracks, right? But how many more do you think?
--
Jorge.
There was a thread some time back where John Brooks mentioned he had a technique for writing tracks closer together, but I don't think it was as simple as just stepping at 1.5-step intervals.

I'd imagine if it were that easy it would have been done long ago... 40KB of extra space would have been hard to pass up!

Tom
Jorge
2017-06-28 09:22:48 UTC
Permalink
Post by Tom Greene
Post by Jorge
Hi,
There's a track every 2 steps of the head stepper, but the stepper can be moved to any track +/- 0, 0.25, 0.50 and 0.75.
So my question is this: can data be reliably saved and read back at track widths of 0.75 ? That's 1 and a half steps (or 0.75 track widths) instead of the usual two. Or about 46 tracks instead of the usual 35, or 188416 bytes per disk instead of 143360.
I guess the answer is no, but I thought better to ask before trying it.
Another question: if I were to put an avr insde the Disk II to modulate the spindle speed as a function of the current track, it should in theory be possible to put more than 16 sectors on the outer tracks, right? But how many more do you think?
--
Jorge.
There was a thread some time back where John Brooks mentioned he had a technique for writing tracks closer together, but I don't think it was as simple as just stepping at 1.5-step intervals.
I'd imagine if it were that easy it would have been done long ago... 40KB of extra space would have been hard to pass up!
Exactly, that's exactly what I think too, if it were so easy somebody would have done it already. OTOH, if it works, that + rwts18 would mean (36/0.75) [tracks] * 18 [sectors] * 256 [bytes] = 223184 bytes per disk. Yeahhh !

And that + the avr/constant linear velocity even more yet, wahaha !
--
Jorge.
Nick Westgate
2017-06-28 10:57:37 UTC
Permalink
Post by Jorge
Another question: if I were to put an avr insde the Disk II to modulate the spindle speed as a function of the current track, it should in theory be possible to put more than 16 sectors on the outer tracks, right? But how many more do you think?
Measured using a simple nibble count I managed to get $2000 nibbles onto track 0 with the drive speed slowed to around 230 RPM. It was to answer this question:
https://retrocomputing.stackexchange.com/q/503/71

My code to write the track and do the count and all the results are there in my answer.

Cheers,
Nick.
James Davis
2017-06-28 19:25:00 UTC
Permalink
Post by Jorge
Hi,
There's a track every 2 steps of the head stepper, but the stepper can be moved to any track +/- 0, 0.25, 0.50 and 0.75.
So my question is this: can data be reliably saved and read back at track widths of 0.75 ? That's 1 and a half steps (or 0.75 track widths) instead of the usual two. Or about 46 tracks instead of the usual 35, or 188416 bytes per disk instead of 143360.
I guess the answer is no, but I thought better to ask before trying it.
Another question: if I were to put an avr insde the Disk II to modulate the spindle speed as a function of the current track, it should in theory be possible to put more than 16 sectors on the outer tracks, right? But how many more do you think?
--
Jorge.
Back in the day, I remember reading a whole treatise on this. I think it was in Jim Sather's, "Understanding the Apple IIe" or in the "Copy II Plus Manual" or in "Beneath Apple ProDOS" or in "Inside Apple's ProDOS" or somewhere! Also, I think Copy II Plus actually reads the half tracks to overcome some of the copy protection schemes used back in the day.
Loading...