A2osX/ProDOS.203/ProDOS.S.XRW.txt

884 lines
26 KiB
Plaintext
Raw Normal View History

2019-04-29 20:36:58 +00:00
NEW
AUTO 3,1
* disk ii driver. object code = xrw_0
* $5300-5A00 moved to language card bank 1 at $D000
2019-09-13 20:48:05 +00:00
*--------------------------------------
blockio cld $D8 to flag language card bank 1 (main)
2019-09-10 20:53:18 +00:00
jsr rsetphse
lda q7l,x turn off write enable
2019-04-29 20:36:58 +00:00
nop
nop
2019-09-10 20:53:18 +00:00
jsr docheck
bcs L5334 branch if block # is out of range
ldy #$05
2019-09-13 20:48:05 +00:00
L5310 asl
2019-04-29 20:36:58 +00:00
rol ibtrk
dey
2019-09-10 20:53:18 +00:00
bne L5310
2019-04-29 20:36:58 +00:00
asl
2019-09-10 20:53:18 +00:00
bcc L531C
2019-09-13 20:48:05 +00:00
ora #$10 adjust for upper 4 bits of track
L531C lsr
2019-04-29 20:36:58 +00:00
lsr
lsr
lsr
2019-09-13 20:48:05 +00:00
pha save sector # across call
2019-09-10 20:53:18 +00:00
jsr regrwts
2019-04-29 20:36:58 +00:00
pla
2019-09-13 20:48:05 +00:00
bcs L5330 if error
2019-09-10 20:53:18 +00:00
inc buf+1
adc #$02
2019-09-13 20:48:05 +00:00
jsr regrwts get 2nd half of block
2019-09-10 20:53:18 +00:00
dec buf+1
2019-09-13 20:48:05 +00:00
L5330 lda ibstat
2019-04-29 20:36:58 +00:00
rts
2019-09-13 20:48:05 +00:00
L5334 lda #$27 i/o error
2019-04-29 20:36:58 +00:00
sec
rts
* read/write a track/sector
2019-09-16 06:06:02 +00:00
regrwts ldy #$01 retry count
2019-09-13 20:48:05 +00:00
sty seekcnt only one recalibrate per call
2019-09-10 20:53:18 +00:00
sta ibsect
2019-09-13 20:48:05 +00:00
lda unitnum get slot # for this operation
2019-09-10 20:53:18 +00:00
and #$70
sta A2L
2019-04-29 20:36:58 +00:00
* make sure other drives in other slots are stopped
2019-09-10 20:53:18 +00:00
jsr chkprev
2019-04-29 20:36:58 +00:00
* now check if the motor is on, then start it
2019-09-10 20:53:18 +00:00
jsr chkdrv
2019-09-13 20:48:05 +00:00
php save test results
2019-09-10 20:53:18 +00:00
lda #$E8
sta montimeh
2019-09-13 20:48:05 +00:00
lda unitnum determine drive 1 or 2.
cmp iobpdn same drive used before ?
sta iobpdn save it for next time.
php keep results of compare.
asl get drive # into carry.
lda motoron,x turn on the drive.
bcc L5362 branch if drive 1 selected.
inx select drive 2.
L5362 lda drv0en,x
plp was it the same drive ?
beq L5372 yes.
plp indicate drive off by setting z-flag.
ldy #$07 150ms delay before stepping.
L536B jsr mswait
2019-04-29 20:36:58 +00:00
dey
2019-09-10 20:53:18 +00:00
bne L536B
2019-09-13 20:48:05 +00:00
php now zero flag set.
L5372 lda A4L make sure this command needs seeking.
beq L537C branch if status check.
lda ibtrk get destination track
jsr myseek and go to it.
2019-04-29 20:36:58 +00:00
* now at desired track. was the motor already on ?
2019-09-13 20:48:05 +00:00
L537C plp was motor on ?
bne L538E if so, don't wait.
2019-04-29 20:36:58 +00:00
* motor was off, wait for it to speed up
2019-09-13 20:48:05 +00:00
L537F lda #$01 wait 100us for each count in montime
2019-09-10 20:53:18 +00:00
jsr mswait
lda montimeh
2019-09-13 20:48:05 +00:00
bmi L537F count up to 0000
2019-04-29 20:36:58 +00:00
* motor should be up to speed,
* if it looks stopped then the drive is not present
2019-09-13 20:48:05 +00:00
jsr chkdrv is drive present ?
beq hndlerr branch if no drive
2019-04-29 20:36:58 +00:00
* now check: if it is not the format disk command,
* locate the correct sector for this operation
2019-09-13 20:48:05 +00:00
L538E lda A4L get command #
beq L53FD if 0 then status command
lsr set carry = 1 for read, 0 for write.
bcs L5398 must prenibblize for write
2019-09-10 20:53:18 +00:00
jsr prenib16
2019-09-13 20:48:05 +00:00
L5398 ldy #$40 64 retries
2019-09-10 20:53:18 +00:00
sty retrycnt
2019-09-13 20:48:05 +00:00
L539D ldx A2L get slot #.
jsr rdadr16 read next address field.
bcc L53BE branch if read ok.
L53A4 dec retrycnt one less chance.
bpl L539D branch to retry.
lda #$27 anticipate a bad drive error.
dec seekcnt can only recalibrate once.
2019-09-10 20:53:18 +00:00
bne hndlerr
lda curtrk
2019-09-13 20:48:05 +00:00
pha save track
2019-04-29 20:36:58 +00:00
asl
2019-09-13 20:48:05 +00:00
adc #$10 pretend track is 8 > curtrk
2019-09-10 20:53:18 +00:00
ldy #$40
2019-09-13 20:48:05 +00:00
sty retrycnt reset retries to 64 max.
bne L53CC always.
2019-04-29 20:36:58 +00:00
* have now read an address field. make sure this is
* the correct track, sector and volume.
2019-09-13 20:48:05 +00:00
L53BE ldy track check track
2019-09-10 20:53:18 +00:00
cpy curtrk
2019-09-13 20:48:05 +00:00
beq L53D5 ok
2019-04-29 20:36:58 +00:00
* recalibrating from this track
2019-09-13 20:48:05 +00:00
lda curtrk preserve destination track
2019-04-29 20:36:58 +00:00
pha
tya
2019-09-10 20:53:18 +00:00
asl
2019-09-13 20:48:05 +00:00
L53CC jsr settrk
2019-04-29 20:36:58 +00:00
pla
2019-09-10 20:53:18 +00:00
jsr myseek
2019-09-13 20:48:05 +00:00
bcc L539D always taken, go recalibrate
2019-04-29 20:36:58 +00:00
* drive is on right track, check volume mismatch
2019-09-13 20:48:05 +00:00
L53D5 lda sect is this the right sector ?
2019-09-10 20:53:18 +00:00
cmp ibsect
2019-09-13 20:48:05 +00:00
bne L53A4 no, try another sector.
lda A4L read or write ?
lsr the carry will tell.
bcc L53F4 branch if write
2019-09-10 20:53:18 +00:00
jsr read16
2019-09-13 20:48:05 +00:00
bcs L53A4 if bad read
2019-04-29 20:36:58 +00:00
2019-09-13 20:48:05 +00:00
L53E7 lda #$00
.HS D0 bne branch never taken (skip 1 byte)
2019-09-10 15:46:56 +00:00
hndlerr sec
2019-09-13 20:48:05 +00:00
sta ibstat error #
ldx A2L slot offset
lda motoroff,x turn off
2019-09-10 15:46:56 +00:00
rts
2019-09-13 20:48:05 +00:00
L53F4 jsr write16 write nibbles
2019-09-16 06:06:02 +00:00
statdne bcc L53E7 if no errors.
2019-09-13 20:48:05 +00:00
lda #$2B disk write protected.
bne hndlerr always
L53FD ldx A2L
lda q6h,x test for write protected
2019-09-10 20:53:18 +00:00
lda q7l,x
2019-09-13 20:48:05 +00:00
rol write protect-->carry-->bit 0=1
lda q6l,x keep in read mode
2019-09-10 20:53:18 +00:00
jmp statdne
2019-09-16 06:06:02 +00:00
myseek asl assume two phase stepper
2019-09-13 20:48:05 +00:00
sta track save destination track * 2
jsr alloff turn all phases off to be sure.
jsr drvindx get index to previous track
lda iobpdn,x for current drive.
sta curtrk current position.
lda track where to go next.
2019-09-10 20:53:18 +00:00
sta iobpdn,x
2019-09-13 20:48:05 +00:00
jsr seek move head there
2019-09-16 06:06:02 +00:00
alloff ldy #$03 turn off all phases before returning.
2019-09-13 20:48:05 +00:00
L5427 tya (send phase in acc)
2019-09-10 20:53:18 +00:00
jsr clrphase carry clear, phases should be turned off
2019-09-10 15:46:56 +00:00
dey
2019-09-10 20:53:18 +00:00
bpl L5427
2019-09-13 20:48:05 +00:00
lsr curtrk divide back down
2019-09-10 15:46:56 +00:00
clc
rts
2019-04-29 20:36:58 +00:00
* fast seek subroutine
*
* on entry:
2019-09-10 20:53:18 +00:00
* x = slot# times $10
* acc = desired half-track (single phase)
* curtrk = current halftrack
2019-04-29 20:36:58 +00:00
*
* on exit:
2019-09-10 20:53:18 +00:00
* a,y = uncertain
* x = undisturbed
* curtrk & trkn = final halftrack.
* prior = prior halftrack if seek was required.
* montimel,h are incremented by the # of 100us quantums required by
* seek for motor on time overlap.
2019-04-29 20:36:58 +00:00
*
* variables used: curtrk, trkn, countn, prior, A2L, montimel, montimeh
2019-09-16 06:06:02 +00:00
seek sta trkn save target track.
2019-09-13 20:48:05 +00:00
cmp curtrk on desired track ?
2019-09-16 06:06:02 +00:00
beq setphase yes, energize phase and return
2019-09-10 20:53:18 +00:00
lda #$00
2019-09-13 20:48:05 +00:00
sta trkcnt half track count.
L5440 lda curtrk save curtrk for delayed turnoff
2019-09-10 20:53:18 +00:00
sta prior
2019-09-10 15:46:56 +00:00
sec
2019-09-13 20:48:05 +00:00
sbc trkn delta-tracks.
beq L5483 branch if curtrk = destination
bcs mvout move out, not in.
eor #$FF calculate tracks to go.
inc curtrk increment current track (in).
bcc L545A always taken.
mvout adc #$FE calculate tracks to go.
dec curtrk decrement current track (out).
L545A cmp trkcnt
bcc L5462 and 'tracks moved'
2019-09-10 20:53:18 +00:00
lda trkcnt
2019-09-13 20:48:05 +00:00
L5462 cmp #$09
bcs L5468 if trkcnt > 8 then leave y alone (y=8)
tay else set acceleration index in y
2019-09-10 15:46:56 +00:00
sec
2019-09-13 20:48:05 +00:00
L5468 jsr setphase
lda ontable,y for 'ontime'
jsr mswait (100us intervals)
2019-09-10 20:53:18 +00:00
lda prior
2019-09-13 20:48:05 +00:00
clc for phaseoff
jsr clrphase turn off prior phase
lda offtable,y then wait 'offtime'
jsr mswait (100us intervals)
inc trkcnt count of 'tracks moved'
bne L5440 always taken
L5483 jsr mswait settle 25 msec
2019-09-16 06:06:02 +00:00
2019-09-13 20:48:05 +00:00
clc set for phase off
2019-09-16 06:06:02 +00:00
setphase lda curtrk get current track
clrphase and #$03 mask for 1 of 4 phases
2019-09-13 20:48:05 +00:00
rol double for phaseon/off index
2019-09-10 20:53:18 +00:00
ora A2L
2019-09-10 15:46:56 +00:00
tax
2019-09-13 20:48:05 +00:00
lda phaseoff,x turn on/off one phase
ldx A2L restore x reg
rts and return
2019-04-29 20:36:58 +00:00
* 7-bit to 6-bit 'deniblize' table (16-sector format)
*
* valid codes are $96 to $FF only. codes with more than one pair of
* adjacent zeroes or with no adjacent ones (except bit 7) are excluded.
*
* nibles in the ranges of $A0-$A3, $C0-$C7, $E0-$E3 are used for
* other tables since no valid nibles are in these ranges.
2019-09-16 06:06:02 +00:00
dnibl .HS 0004FFFF080CFF10 aligned to page boundary minus $96
2019-09-13 20:48:05 +00:00
.HS 1418
2019-09-16 06:06:02 +00:00
twobit3 .HS 008040C0FFFF used in fast prenib as lookup for 2-bit quantities.
2019-09-13 20:48:05 +00:00
.HS 1C20FFFFFF24282C
.HS 3034FFFF383C4044
.HS 484CFF5054585C60
.HS 6468
2019-09-16 06:06:02 +00:00
twobit2 .HS 00201030 used in fast prenib.
endmrks .HS DEAAEBFF table using 'unused' nibbles ($C4,$C5,$C6,$C7)
2019-09-13 20:48:05 +00:00
.HS FFFFFF6CFF70
.HS 7478FFFFFF7CFFFF
.HS 8084FF888C909498
.HS 9CA0
2019-09-16 06:06:02 +00:00
twobit1 .HS 0008040CFFA4 used in fast prenib.
2019-09-13 20:48:05 +00:00
.HS A8ACFFB0B4B8BCC0
.HS C4C8FFFFCCD0D4D8
.HS DCE0FFE4E8ECF0F4
.HS F8FC
2019-04-29 20:36:58 +00:00
* 6-bit to 2-bit conversion tables:
*
* dnibl2 abcdef-->0000FE
* dnibl3 abcdef-->0000DC
* dnibl4 abcdef-->0000BA
* origin = $D200 (page boundary)
* page align the following tables:
2019-09-16 06:06:02 +00:00
dnibl2 .HS 00
dnibl3 .HS 00
dnibl4 .HS 00
2019-04-29 20:36:58 +00:00
* 6-bit to 7-bit nibl conversion table
*
* codes with more than one pair of adjacent zeroes
* or with no adjacent ones (except B7) are excluded.
2019-09-16 06:06:02 +00:00
nibl .HS 960200
2019-09-13 20:48:05 +00:00
.HS 00970100009A0300
.HS 009B0002009D0202
.HS 009E0102009F0302
.HS 00A6000100A70201
.HS 00AB010100AC0301
.HS 00AD000300AE0203
.HS 00AF010300B20303
.HS 00B3000002B40200
.HS 02B5010002B60300
.HS 02B7000202B90202
.HS 02BA010202BB0302
.HS 02BC000102BD0201
.HS 02BE010102BF0301
.HS 02CB000302CD0203
.HS 02CE010302CF0303
.HS 02D3000001D60200
.HS 01D7010001D90300
.HS 01DA000201DB0202
.HS 01DC010201DD0302
.HS 01DE000101DF0201
.HS 01E5010101E60301
.HS 01E7000301E90203
.HS 01EA010301EB0303
.HS 01EC000003ED0200
.HS 03EE010003EF0300
.HS 03F2000203F30202
.HS 03F4010203F50302
.HS 03F6000103F70201
.HS 03F9010103FA0301
.HS 03FB000303FC0203
.HS 03FD010303FE0303
.HS 03FF
2019-04-29 20:36:58 +00:00
* nibl buffer 'nbuf2' must be on a page boundary !!!
2019-09-16 06:06:02 +00:00
nbuf2 .BS 86 nibl buffer for read/write of low 2-bits of each byte.
ibtrk .HS 00
ibsect .HS 00
ibstat .HS 00
iobpdn .HS 00
curtrk .HS 00
2019-09-13 20:48:05 +00:00
.HS 00000000000000 for slots 1 thru 7
.HS 00000000000000 drives 1 & 2
2019-09-16 06:06:02 +00:00
retrycnt .HS 00
seekcnt .HS 00
trkcnt .EQ * halftracks moved count.
countn .EQ * 'must find' count.
last .HS 00 'odd bit' nibls.
csum .HS 00 used for address header cksum
csstv .HS 00
sect .HS 00
track .EQ *
montimel .HS 00
montimeh .HS 00 also 'volume'
prior .HS 00
trkn .HS 00
2019-04-29 20:36:58 +00:00
* phase on, off time tables
* in 100 usec intervals (seek)
2019-09-16 06:06:02 +00:00
ontable .HS 013028
2019-09-13 20:48:05 +00:00
.HS 24201E1D1C1C
2019-09-16 06:06:02 +00:00
offtable .HS 702C
2019-09-13 20:48:05 +00:00
.HS 26221F1E1D1C1C
2019-04-29 20:36:58 +00:00
* mswait subroutine
*
* delays a specified number of 100 usec intervals for motor timing.
* on entry: acc holds number of 100 usec intervals to delay.
* on exit: acc = 0, x = 0, y = unchanged, carry set.
* montimel, montimeh are incremented once per 100 usec interval
* for motor on timing.
2019-09-16 06:06:02 +00:00
mswait ldx #$11 delay 86 usec
.1 dex
bne .1
2019-09-10 20:53:18 +00:00
inc montimel
2019-09-16 06:06:02 +00:00
bne .2
2019-09-10 20:53:18 +00:00
inc montimeh
2019-09-16 06:06:02 +00:00
.2 sec
2019-09-10 20:53:18 +00:00
sbc #$01
2019-09-16 06:06:02 +00:00
bne mswait
2019-09-10 15:46:56 +00:00
rts
2019-04-29 20:36:58 +00:00
* read address field subroutine (16-sector format)
*
* reads volume, track and sector.
* on entry: x = slot# times $10, read mode (q6l,q7l)
* on exit: carry set if error, else if no error:
2019-09-10 20:53:18 +00:00
* acc=$AA, y=0, x=unchanged, carry clear,
* ccstv contains chksum,sector,track & volume read.
2019-04-29 20:36:58 +00:00
* uses temps: count,last,csum & 4 bytes at ccstv
* expects: original 10-sector normal density nibls (4-bit) odd bits then even.
* observe 'no page cross' warnings on some branches !!!
2019-09-16 06:06:02 +00:00
rdadr16 ldy #$FC
2019-09-13 20:48:05 +00:00
sty countn 'must find' count
L569D iny
bne L56A5 low order of count.
inc countn (2k nibles to find address mark
beq rderr else error)
L56A5 lda q6l,x read nibl
bpl L56A5 *** no page cross ***
L56AA cmp #$D5 address mark 1 ?
2019-09-10 20:53:18 +00:00
bne L569D
2019-09-13 20:48:05 +00:00
nop nibl delay
L56AF lda q6l,x
bpl L56AF *** no page cross ***
cmp #$AA address mark 2 ?
bne L56AA if not, is it address mark 1 ?
ldy #$03 index for 4 byte read
L56BA lda q6l,x
bpl L56BA *** no page cross ***
cmp #$96 address mark 3 ?
bne L56AA if not, is it address mark 1
sei no interrupts until address is tested.
lda #$00 init checksum
L56C6 sta csum
L56C9 lda q6l,x read 'odd bit' nibl
bpl L56C9 *** no page cross ***
rol align odd bits, '1' into lsb.
sta last save them.
L56D2 lda q6l,x read 'even bit' nibl
bpl L56D2 *** no page cross ***
and last merge odd and even bits.
sta csstv,y store data byte.
2019-09-10 20:53:18 +00:00
eor csum
2019-09-10 15:46:56 +00:00
dey
2019-09-13 20:48:05 +00:00
bpl L56C6 loop on 4 data bytes.
tay if final checksum non-zero,
bne rderr then error.
L56E6 lda q6l,x first bit-slip nibl
bpl L56E6 *** no page cross ***
2019-09-10 20:53:18 +00:00
cmp #$DE
bne rderr
2019-09-13 20:48:05 +00:00
nop delay
L56F0 lda q6l,x second bit-slip nible
bpl L56F0 *** no page cross ***
2019-09-10 20:53:18 +00:00
cmp #$AA
bne rderr
2019-09-13 20:48:05 +00:00
clc normal read ok
2019-09-10 15:46:56 +00:00
rts
2019-09-13 20:48:05 +00:00
rderr sec
2019-09-10 15:46:56 +00:00
rts
2019-04-29 20:36:58 +00:00
* read subroutine (16-sector format)
*
* reads encoded bytes into nbuf1 and nbuf2.
* first reads nbuf2 high to low, then nbuf1 low to high.
* on entry: x=slot# times $10, read mode (q6l,q7l)
* on exit: carry set if error, else if no error:
2019-09-10 20:53:18 +00:00
* acc=$AA, x=unchanged, y=0, carry clear.
2019-04-29 20:36:58 +00:00
* observe 'no page cross' on some branches !!
2019-09-16 06:06:02 +00:00
read16 txa get slot #
2019-09-13 20:48:05 +00:00
ora #$8C prepare mods to read routine.
sta rd4+1 warning: the read routine is
sta rd5+1 self modified !!
2019-09-10 20:53:18 +00:00
sta rd6+1
sta rd7+1
sta rd8+1
2019-09-13 20:48:05 +00:00
lda buf modify storage addresses also
2019-09-10 20:53:18 +00:00
ldy buf+1
sta ref3+1
sty ref3+2
2019-09-10 15:46:56 +00:00
sec
2019-09-10 20:53:18 +00:00
sbc #$54
2019-09-13 20:48:05 +00:00
bcs L571F branch if no borrow
2019-09-10 15:46:56 +00:00
dey
2019-09-13 20:48:05 +00:00
L571F sta ref2+1
2019-09-10 20:53:18 +00:00
sty ref2+2
2019-09-10 15:46:56 +00:00
sec
2019-09-10 20:53:18 +00:00
sbc #$57
2019-09-13 20:48:05 +00:00
bcs L572B branch if no borrow
2019-09-10 15:46:56 +00:00
dey
2019-09-13 20:48:05 +00:00
L572B sta ref1+1
2019-09-10 20:53:18 +00:00
sty ref1+2
2019-09-13 20:48:05 +00:00
ldy #$20 32 tries to find
L5733 dey
beq L576D branch if can't find data header marks
L5736 lda q6l,x
2019-09-10 20:53:18 +00:00
bpl L5736
2019-09-13 20:48:05 +00:00
L573B eor #$D5 1st data mark
2019-09-10 20:53:18 +00:00
bne L5733
2019-09-13 20:48:05 +00:00
nop delay
L5740 lda q6l,x
2019-09-10 20:53:18 +00:00
bpl L5740
2019-09-13 20:48:05 +00:00
cmp #$AA 2nd data mark.
bne L573B if not, check for 1st again
2019-09-10 15:46:56 +00:00
nop
2019-09-13 20:48:05 +00:00
L574A lda q6l,x
2019-09-10 20:53:18 +00:00
bpl L574A
2019-09-13 20:48:05 +00:00
cmp #$AD 3rd data mark
bne L573B if not, check for data mark 1 again
2019-09-10 20:53:18 +00:00
ldy #$AA
lda #$00
2019-09-13 20:48:05 +00:00
L5757 sta pcl use z-page for keeping checksum
2019-09-16 06:06:02 +00:00
rd4 ldx q6l+$60 warning: self modified
bpl rd4
2019-09-10 20:53:18 +00:00
lda dnibl-$96,x
2019-09-13 20:48:05 +00:00
sta nbuf2-$AA,y save the two-bit groups in nbuf.
eor pcl update checksum.
iny next position in nbuf.
bne L5757 loop for all $56 two-bit groups.
ldy #$AA now read directly into user buffer.
2019-09-16 06:06:02 +00:00
bne rd5 always taken.
2019-09-13 20:48:05 +00:00
L576D sec error
2019-09-10 15:46:56 +00:00
rts
2019-09-16 06:06:02 +00:00
ref1 sta $1000,y warning: self modified
rd5 ldx q6l+$60 warning: self modified
bpl rd5
2019-09-13 20:48:05 +00:00
eor dnibl-$96,x get actual 6-bit data from dnib table.
ldx nbuf2-$AA,y get associated two-bit pattern
eor dnibl2,x and combine to form whole byte.
2019-09-10 15:46:56 +00:00
iny
2019-09-16 06:06:02 +00:00
bne ref1 loop for $56 bytes.
2019-09-13 20:48:05 +00:00
pha save for now, no time to store...
and #$FC strip low bits.
ldy #$AA prepare for next $56 bytes
2019-09-16 06:06:02 +00:00
rd6 ldx q6l+$60 warning: self modified
bpl rd6
2019-09-10 20:53:18 +00:00
eor dnibl-$96,x
ldx nbuf2-$AA,y
eor dnibl3,x
2019-09-16 06:06:02 +00:00
ref2 sta $1000,y warning: self modified
2019-09-10 15:46:56 +00:00
iny
2019-09-16 06:06:02 +00:00
bne rd6 loop unil this group of $56 read
rd7 ldx q6l+$60 warning: self modified
bpl rd7
2019-09-10 20:53:18 +00:00
and #$FC
2019-09-13 20:48:05 +00:00
ldy #$AC last group is $54 long
L57A5 eor dnibl-$96,x
2019-09-10 20:53:18 +00:00
ldx nbuf2-$AC,y
2019-09-13 20:48:05 +00:00
eor dnibl4,x combine to form full byte
2019-09-16 06:06:02 +00:00
ref3 sta $1000,y warning: self modified
rd8 ldx q6l+$60 warning: self modified
bpl rd8
2019-09-10 15:46:56 +00:00
iny
2019-09-10 20:53:18 +00:00
bne L57A5
and #$FC
2019-09-13 20:48:05 +00:00
eor dnibl-$96,x checksum ok ?
bne L57CC error if not.
ldx A2L test end marks.
L57C2 lda q6l,x
2019-09-10 20:53:18 +00:00
bpl L57C2
cmp #$DE
2019-09-10 15:46:56 +00:00
clc
2019-09-13 20:48:05 +00:00
beq L57CD branch if good trailer
L57CC sec
L57CD pla place last byte into user buffer
2019-09-10 20:53:18 +00:00
ldy #$55
sta (buf),y
2019-09-10 15:46:56 +00:00
rts
2019-04-29 20:36:58 +00:00
* set the slot dependent track location
2019-09-16 06:06:02 +00:00
settrk jsr drvindx get index to drive #
2019-09-10 20:53:18 +00:00
sta iobpdn,x
2019-09-10 15:46:56 +00:00
rts
2019-04-29 20:36:58 +00:00
* determine if motor is stopped
*
* if stopped, controller's shift register will not be changing.
* return y = 0 and zero flag set if it is stopped.
2019-09-16 06:06:02 +00:00
chkdrv ldx A2L
chkdrv0 ldy #$00 init loop counter.
.1 lda q6l,x read the shift register.
2019-09-13 20:48:05 +00:00
jsr ckdrts delay
2019-09-10 15:46:56 +00:00
pha
2019-09-13 20:48:05 +00:00
pla more delay.
cmp q6l,x has shift reg changed ?
2019-09-16 06:06:02 +00:00
bne ckdrts yes, motor is moving.
2019-09-13 20:48:05 +00:00
lda #$28 anticipate error.
dey no, dec retry counter
2019-09-16 06:06:02 +00:00
bne .1 and try 256 times.
ckdrts rts
drvindx pha preserve acc across call
2019-09-10 20:53:18 +00:00
lda A4L+1
2019-09-11 15:53:33 +00:00
lsr
lsr
lsr
lsr
2019-09-10 20:53:18 +00:00
cmp #$08
and #$07
2019-09-11 15:53:33 +00:00
rol
2019-09-13 20:48:05 +00:00
tax index to table.
pla restore acc
2019-09-10 15:46:56 +00:00
rts
2019-04-29 20:36:58 +00:00
* write subroutine (16 sector format)
*
* writes data from nbuf1 and buf. first nbuf2, high to low then direct
* from (buf), low to high. assumes 1 usec cycle time. self modified code !!
*
* on entry: x = slotnum times 16
*
* on exit: carry set if error (write protect violation).
2019-09-10 20:53:18 +00:00
* if no error, acc=uncertain, x=unchanged, y=0, carry clear.
2019-04-29 20:36:58 +00:00
2019-09-16 06:06:02 +00:00
write16 sec anticipate write protect error
2019-09-10 20:53:18 +00:00
lda q6h,x
2019-09-13 20:48:05 +00:00
lda q7l,x sense write protect flag
2019-09-10 20:53:18 +00:00
bpl L580C
2019-09-13 20:48:05 +00:00
jmp wexit exit if write protected
2019-04-29 20:36:58 +00:00
* timing is critical. a one micro-second cycle time is assumed.
* number in () is how many micro-seconds per instruction or subroutine
2019-09-13 20:48:05 +00:00
L580C lda nbuf2
2019-09-10 20:53:18 +00:00
sta pcl
2019-09-13 20:48:05 +00:00
lda #$FF sync data.
sta q7h,x (5) goto write mode
ora q6l,x (4)
ldy #$04 (2) for five nibls
nop (2)
pha (3)
pla (4)
wsync pha (3) exact timing.
pla (4) exact timing.
jsr wnibl7 (13,9,6) write sync.
dey (2)
bne wsync (3-) must not cross page !
lda #$D5 (2) 1st data mark
jsr wnibl9 (15,9,6)
lda #$AA (2) 2nd data mark
jsr wnibl9 (15,9,6)
lda #$AD (2) 3rd data mark
jsr wnibl9 (15,9,6)
tya (2) zero checksum
ldy #$56 (2) nbuf2 index
bne L583D (3) branch always
2019-04-29 20:36:58 +00:00
* total time in this write byte loop must = 32us !!!
2019-09-13 20:48:05 +00:00
L583A lda nbuf2,y (4) prior 6-bit nibl
L583D eor nbuf2-1,y (5) xor with current
tax (2) index to 7-bit nibl
lda nibl,x (4) must not cross page boundary
ldx A2L (3) restore slot index
sta q6h,x (5) store encoded byte
lda q6l,x (4) handshake
dey (2)
bne L583A (3-) must not cross page boundary
2019-04-29 20:36:58 +00:00
* end of write byte loop
2019-09-13 20:48:05 +00:00
lda pcl (3) get prior nibl (from nbuf2)
2019-09-16 06:06:02 +00:00
wrefd1 ldy #$00 (2) warning: load value modified by prenib.
wrefa1 eor $1000,y (4) warning: address modified by prenib.
2019-09-13 20:48:05 +00:00
and #$FC (2) strip low 2 bits
tax (2) index to nibl table
lda nibl,x (4)
2019-09-16 06:06:02 +00:00
wrefd2 ldx #$60 (2) warning: value modified by prenib.
2019-09-13 20:48:05 +00:00
sta q6h,x (5) write nibl
lda q6l,x (4) handshake
2019-09-16 06:06:02 +00:00
wrefa2 lda $1000,y (4) prior nibl. warning: address modified by prenib.
2019-09-13 20:48:05 +00:00
iny (2) all done with this page ?
2019-09-16 06:06:02 +00:00
bne wrefa1 (3-) loop until page end.
2019-09-13 20:48:05 +00:00
lda pch (3) get next (precalculated & translated) nibl.
beq L58C0 (2+) branch if code written was page aligned.
lda A2H (3) get byte address of last byte to be written.
beq L58B3 (2+) branch if only 1 byte left to write.
2019-09-12 06:39:47 +00:00
lsr (2) test for odd or even last byte (carry set/clear)
2019-09-13 20:48:05 +00:00
lda pch (3) restore nibl to acc.
sta q6h,x (5)
lda q6l,x (4)
lda A1L (3) = byte 0 of 2nd page xor'd with byte 1 if
nop (2) above test set carry.
iny (2) y=1
bcs L5899 (2+) branch if last byte to be odd.
2019-09-16 06:06:02 +00:00
wrefa3 eor $1100,y (4) warning: address modified by prenib.
2019-09-13 20:48:05 +00:00
and #$FC (2) strip low 2 bits.
tax (2) index to nibl table
lda nibl,x (4) get nibl
2019-09-16 06:06:02 +00:00
wrefd3 ldx #$60 (2) restore slot index. warning: modified by prenib
2019-09-13 20:48:05 +00:00
sta q6h,x (5)
lda q6l,x (4)
2019-09-16 06:06:02 +00:00
wrefa4 lda $1100,y (4) warning: modified by prenib
2019-09-13 20:48:05 +00:00
iny (2) got prior nibl, point to next
2019-09-16 06:06:02 +00:00
wrefa5 eor $1100,y (4) warning: modified by prenib
2019-09-13 20:48:05 +00:00
L5899 cpy A2H (3) set carry if this is the last nibl
and #$FC (2) strip low 2 bits
tax (2)
lda nibl,x (4)
2019-09-16 06:06:02 +00:00
wrefd4 ldx #$60 (2) restore slot. warning: modified by prenib
2019-09-13 20:48:05 +00:00
sta q6h,x (5)
lda q6l,x (4)
2019-09-16 06:06:02 +00:00
wrefa6 lda $1100,y (4) get prior nibl. warning: modified by prenib
2019-09-13 20:48:05 +00:00
iny (2)
2019-09-16 06:06:02 +00:00
bcc wrefa3 (3-) branch if not the last.
2019-09-13 20:48:05 +00:00
bcs L58B1 (3) waste 3 cycles, branch always.
L58B1 bcs L58C0 (3) branch always.
L58B3 lda >pch (4) absolute reference to zero page
sta q6h,x (5)
lda q6l,x (4)
pha (3) waste 14 micro-seconds total
pla (4)
pha (3)
pla (4)
L58C0 ldx A1H (3) use last nibl (anded with $FC) for checksum
lda nibl,x (4)
2019-09-16 06:06:02 +00:00
wrefd5 ldx #$60 (2) restore slot. warning: modified by prenib
2019-09-13 20:48:05 +00:00
sta q6h,x (5)
lda q6l,x (4)
ldy #$00 (2) set y = index end mark table.
pha (3) waste another 11 micro-seconds
pla (4)
nop (2)
nop (2)
L58D3 lda endmrks,y (4) dm4, dm5, dm6 and turn off byte.
jsr wnibl (15,6) write it
iny (2)
cpy #$04 (2) have all end marks been written ?
bne L58D3 (3) if not.
clc (2,9)
2019-09-16 06:06:02 +00:00
wexit lda q7l,x out of write mode
2019-09-13 20:48:05 +00:00
lda q6l,x to read mode.
rts return from write.
2019-04-29 20:36:58 +00:00
* 7-bit nibl write subroutines
2019-09-16 06:06:02 +00:00
wnibl9 clc (2) 9 cycles, then write.
wnibl7 pha (3) 7 cycles, then write.
2019-09-13 20:48:05 +00:00
pla (4)
2019-09-16 06:06:02 +00:00
wnibl sta q6h,x (5) nibl write
2019-09-13 20:48:05 +00:00
ora q6l,x (4) clobbers acc, not carry
rts (6)
2019-04-29 20:36:58 +00:00
* preniblize subroutine (16 sector format)
*
* converts 256 bytes of user data in (buf) into 6 bit nibls in nbuf2.
* high 6 bits are translated directly by the write routines.
*
* on entry: buf is 2-byte pointer to 256 bytes of user data.
*
* on exit: a,x,y undefined. write routine modified to do direct conversion
2019-09-10 20:53:18 +00:00
* of high 6 bits of user's buffer data.
2019-04-29 20:36:58 +00:00
2019-09-16 06:06:02 +00:00
prenib16 lda buf self-modify the addresses because of
2019-09-13 20:48:05 +00:00
ldy buf+1 the fast timing required.
clc all offsets are minus $AA.
adc #$02 the highest set is buf+$AC.
bcc L58FA branch if no carry,
iny otherwise add carry to high address.
L58FA sta prn3+1 self mod 3
2019-09-10 20:53:18 +00:00
sty prn3+2
2019-09-10 15:46:56 +00:00
sec
2019-09-13 20:48:05 +00:00
sbc #$56 middle set is buf+$56.
bcs L5906 branch if no borrow,
dey otherwise deduct from high.
L5906 sta prn2+1 self mod 2
2019-09-10 20:53:18 +00:00
sty prn2+2
2019-09-10 15:46:56 +00:00
sec
2019-09-13 20:48:05 +00:00
sbc #$56 low set is exactly buf
2019-09-10 20:53:18 +00:00
bcs L5912
2019-09-10 15:46:56 +00:00
dey
2019-09-13 20:48:05 +00:00
L5912 sta prn1+1 self mod 1
2019-09-10 20:53:18 +00:00
sty prn1+2
2019-09-13 20:48:05 +00:00
ldy #$AA count up to 0.
2019-09-16 06:06:02 +00:00
prn1 lda $1000,y warning: self modified. get byte from lowest group.
2019-09-13 20:48:05 +00:00
and #$03 strip high 6 bits.
tax index to 2 bit equivalent.
2019-09-10 20:53:18 +00:00
lda twobit1,x
2019-09-13 20:48:05 +00:00
pha save pattern
2019-09-16 06:06:02 +00:00
prn2 lda $1056,y warning: self modified. get byte from middle group.
2019-09-10 20:53:18 +00:00
and #$03
2019-09-10 15:46:56 +00:00
tax
2019-09-13 20:48:05 +00:00
pla restore pattern.
ora twobit2,x combine 2nd group with 1st.
pha save new pattern.
2019-09-16 06:06:02 +00:00
prn3 lda $10AC,y warning: self modified. get byte from highest group.
2019-09-10 20:53:18 +00:00
and #$03
2019-09-10 15:46:56 +00:00
tax
2019-09-13 20:48:05 +00:00
pla restore new pattern
ora twobit3,x and form final nibl.
2019-09-10 15:46:56 +00:00
pha
tya
2019-09-10 20:53:18 +00:00
eor #$FF
2019-09-10 15:46:56 +00:00
tax
pla
2019-09-13 20:48:05 +00:00
sta nbuf2,x save in nibl buffer.
iny inc to next set.
2019-09-16 06:06:02 +00:00
bne prn1 loop until all $56 nibls formed.
2019-09-13 20:48:05 +00:00
ldy buf now prepare data bytes for write16 subr.
dey prepare end address.
2019-09-10 20:53:18 +00:00
sty A2H
lda buf
sta wrefd1+1 warning: the following storage addresses
2019-09-13 20:48:05 +00:00
beq L595F starting with 'wref' are refs into code
eor #$FF space, changed by this routine.
tay index to last byte of page in (buf).
lda (buf),y pre-niblize the last byte of the page
iny with the first byte of the next page.
2019-09-10 20:53:18 +00:00
eor (buf),y
and #$FC
2019-09-10 15:46:56 +00:00
tax
2019-09-13 20:48:05 +00:00
lda nibl,x get disk 7-bit nible equivalent.
L595F sta pch
beq L596F branch if data to be written is page
lda A2H aligned. check if last byte is even
lsr or odd address. shift even/odd -> carry.
lda (buf),y if even, then leave intact.
bcc L596D branch if odd.
iny if even, then pre-xor with byte 1.
2019-09-10 20:53:18 +00:00
eor (buf),y
2019-09-13 20:48:05 +00:00
L596D sta A1L save result for write routine.
L596F ldy #$FF index to last byte of data to write.
lda (buf),y to be used as a checksum.
and #$FC strip extra bits
sta A1H and save it.
ldy buf+1 now modify address references to
sty wrefa1+2 user data.
2019-09-10 20:53:18 +00:00
sty wrefa2+2
2019-09-10 15:46:56 +00:00
iny
2019-09-10 20:53:18 +00:00
sty wrefa3+2
sty wrefa4+2
sty wrefa5+2
sty wrefa6+2
2019-09-13 20:48:05 +00:00
ldx A2L and lastly, index references to
stx wrefd2+1 controller.
2019-09-10 20:53:18 +00:00
stx wrefd3+1
stx wrefd4+1
stx wrefd5+1
2019-09-10 15:46:56 +00:00
rts
2019-09-16 06:06:02 +00:00
chkprev eor iobpdn same slot as last ?
2019-09-10 20:53:18 +00:00
asl
beq L59BD
lda #$01
sta montimeh
2019-09-13 20:48:05 +00:00
L59A6 lda iobpdn
2019-09-10 20:53:18 +00:00
and #$70
2019-09-10 15:46:56 +00:00
tax
2019-09-13 20:48:05 +00:00
beq L59BD branch if no previous ever (boot only).
jsr chkdrv0 check if previous drive running.
beq L59BD branch if stopped.
lda #$01 delay
2019-09-10 20:53:18 +00:00
jsr mswait
lda montimeh
bne L59A6
2019-09-13 20:48:05 +00:00
L59BD rts
2019-09-16 06:06:02 +00:00
rsetphse lda unitnum get unit number.
2019-09-14 19:13:22 +00:00
and #$7F mask off high bit.
2019-09-10 15:46:56 +00:00
tax
2019-04-29 20:36:58 +00:00
* clear all the phases and force read mode
2019-09-10 20:53:18 +00:00
lda phaseoff+0,x make sure all motor phases are off.
lda phaseoff+2,x
lda phaseoff+4,x
lda phaseoff+6,x
2019-09-10 15:46:56 +00:00
rts
2019-09-16 06:06:02 +00:00
docheck lda A4L command #.
2019-09-13 20:48:05 +00:00
cmp #$04 is the command allowed ?
bcs L59E6 if not.
2019-09-10 20:53:18 +00:00
lda bloknml
ldx bloknml+1
2019-09-13 20:48:05 +00:00
stx ibtrk calculate block's track and sector.
beq L59E8 branch if block # is in range,
dex else test further.
bne L59E6 taken if bad range.
cmp #$18 must be < $118
bcc L59E8 then ok.
L59E6 sec error.
2019-09-10 15:46:56 +00:00
rts
2019-09-13 20:48:05 +00:00
L59E8 clc
rts end of obj xrw_0
2019-09-10 15:46:56 +00:00
2019-09-13 20:48:05 +00:00
.HS 0000 pad bytes to $D6EC (pathbuf-$14)
2019-04-29 20:36:58 +00:00
* variables used by mli for smartport interface
2019-09-16 06:06:02 +00:00
spstatlist .HS 00000000 ref pathbuf-$14 smartport status list buffer
spunit .HS 0000000000000000 ref pathbuf-$10smartport unit numbers
2019-09-14 19:13:22 +00:00
.HS 0000000000000000
2019-04-29 20:36:58 +00:00
* pathname buffer starts at this page boundary (pathbuf = $D700)
2019-09-13 20:48:05 +00:00
*--------------------------------------
2019-04-29 20:36:58 +00:00
MAN
SAVE usr/src/prodos.203/prodos.s.xrw
LOAD usr/src/prodos.203/prodos.s
2019-04-29 20:36:58 +00:00
ASM