A2osX/LIB/LIBBLKDEV.S.BB.txt
2020-11-24 18:49:46 +01:00

581 lines
12 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

NEW
AUTO 3,1
*--------------------------------------
dcmd .EQ $42 disk command (=1 for read)
unit .EQ $43 (16*slot)+(128*(drive-1))
buff .EQ $44 ram address
blok .EQ $46 disk address
dent .EQ $48 device call entry address
idxl .EQ $4a pointer to low page of index block
idxh .EQ $4c pointer to high page of index block
idxp .EQ $4e index byte pointer
iobuff .EQ $60
* the following are for disk ii only
dbuf .EQ $26
BB.Slotn0 .EQ $2b
oddbits .EQ $3c
sector .EQ $3d
BB.RetryCnt .EQ $40
BB.TargetTrk .EQ $41
BB.CurrentQTrack .EQ $50
BB.TargetQTrack .EQ $51
BB.HdrPtr .EQ $52
BB.Hdr .EQ $54
BB.HdrTrk .EQ $55
BB.HdrVol .EQ $56
BB.Hdr96 .EQ $57
nbuf1 .EQ $300
dnib .EQ $2d6
clrscrn .EQ $fc58
scrn .EQ $5b6
sosid .EQ $c00
entlen .EQ sosid+$23
kernel .EQ $2000
*--------------------------------------
.PH $800
xboot .DA #1
sec apple iii enters xboot 'ora $38'
* bcs BB.AppleII branch if not apple iii native mode
bcc *
*--------------------------------------
*BB.AppleIII lda #$9f make apple iii boot using block 1
* pha the return address is $a000
* lda #$ff
* pha
* inc
* tax ldx #0
* inc lda #1 (read block 1)
* jmp $f479
*--------------------------------------
BB.AppleII stx unit save unit number
cmp #$03 for disk ii
php save result, it may be irrelevant
txa find out if disk ii
and #$70 strip drive # if any
lsr
lsr get slot address
lsr
lsr
ora #$c0
sta dent+1
ldy #$ff look at last byte
sty dent
plp restore carry (if disk ii & sect 0&2 read)
iny make y=0
lda (dent),y get device entry addr
bne ndsk2 branch if not disk ii (16 sector)
bcs isdsk2 branch if it is disk ii, but block 0 read
lda #3 make rom read only sector 2
sta xboot to complete block 0
inc sector was = 1
lda dent+1 do rts to re-enter rom
pha
lda #$5b
pha
rts go read sector 2 into $900
*--------------------------------------
isdsk2 sta BB.HdrTrk A=0, make sure previous track =0
sta dent and dent points at beginning of slot
ldy #$63 move code from card to ram
mvboot lda (dent),y
sta zzstart-$5e,y
iny
cpy #$eb have we moved enough?
bne mvboot
ldx #mods.cnt now modify code to handle errors.
modboot ldy mods-1,x
lda chgs-1,x
sta zzstart,y
cpx #8
bcs .1
lda endcode-1,x
sta zzzend-1,x
.1 dex
bne modboot
lda #BB.Hdr
sta BB.HdrPtr
stx BB.HdrPtr+1 X=0
lda /BB.ReadBlock reset device entry
sta dent+1 to point at disk ii routines.
lda #BB.ReadBlock get low addr (must be <$80)
*--------------------------------------
ndsk2 sta dent save low adr of device call entry.
ldy #0
sty iobuff y=0
sty idxl
sty idxh
sty idxp
sty blok+1
iny y=1
sty dcmd set read command.
iny y=2
sty blok to read directory blocks
lda #$c 2-5 at $c00
sta iobuff+1
sta idxl+1
rddir jsr goread call read block routine.
bcs bterr2 give up on error.
inc iobuff+1
inc iobuff+1
inc blok
lda blok have all directory blocks been read?
cmp #6
bcc rddir loop if not.
*--------------------------------------
lda #4 begin look-up with first entry past header.
.HS 2C BIT ABS
nxdent lda idxl
nxdent1 clc
adc entlen bump to next directory entry.
tay save in y for now.
bcc nxdent2 branch if not a page cross.
inc idxl+1
lda idxl+1 check for new block.
lsr if even then new block.
bcs nxdent2
cmp #$a have all file names been compared?
beq booterr branch if no pro.kernel.
ldy #4 else, begin at block beginning.
nxdent2 sty idxl
ldy #6
lookpro lda (idxl),y look for matching name.
cmp BB.ProDOS,y
bne nxdent branch if no match.
dey
bpl lookpro
* ldy #$10 get file type & index block addr.
* lda (idxl),y
* cmp #S.FI.T.SYS is it a system file?
* bne booterr
* iny
ldy #$11
lda (idxl),y
sta blok
iny
lda (idxl),y
sta blok+1
lda #0 now set up to read kernel.
sta idxl
ldy #$1e read index block at $1e00 and
sty idxl+1 kernel at $2000
sty iobuff+1
iny
sty idxh+1
*--------------------------------------
rdkernl jsr goread read index block.
bterr2 bcs booterr
inc iobuff+1
inc iobuff+1
ldy idxp get index pointer
inc idxp bump for next time.
lda (idxl),y
sta blok
lda (idxh),y high disk addr.
sta blok+1
ora (idxl),y if both=0 then done.
bne rdkernl branch if more to read.
jmp kernel go execute kernel code.
*--------------------------------------
booterr jsr clrscrn clear video
ldy #BB.MSG.ERR.Len-1
.1 lda BB.MSG.ERR,y
sta scrn,y
dey
bpl .1
jmp $ff69
*--------------------------------------
goread lda iobuff
sta buff
lda iobuff+1
sta buff+1
jmp (dent)
*--------------------------------------
mods .DA #mod1,#mod2,#mod3,#mod4,#mod5,#mod6,#mod7,#mod8,#mod8+1,#mod9
mods.cnt .EQ *-mods
chgs .DA #chg1,#chg2,#chg3,#chg4,#chg5,#chg6,#chg7,#$91,#BB.HdrPtr,#BB.HdrTrk
endcode ldx BB.Slotn0
clc
rts
jmp BB.Seek
*--------------------------------------
BB.MSG.ERR .AS -"BOOT ERROR"
BB.MSG.ERR.Len .EQ *-BB.MSG.ERR
BB.ProDOS .DA #$26 $20 = storage type + 6 = "PRODOS" len
.AS "PRODOS"
*--------------------------------------
BB.ReadBlock lda blok figure out track & sector.
and #7 strip track for now.
cmp #4
and #3
php
asl
plp
rol now we have the first sector of block.
sta sector
lda blok+1 get high block #
lsr shift hi addr to carry.
lda blok now figure track #
ror
lsr
lsr
sta BB.TargetTrk
lda buff+1
sta dbuf+1
ldx BB.Slotn0
lda IO.D2.DrvOn,x
jsr BB.Seek go read sector.
inc dbuf+1 bump address
inc sector
inc sector and sector #
bcs .9 branch if error.
jsr BB.Seek
.9 ldy IO.D2.DrvOff,x
rts return error status in carry.
*--------------------------------------
BB.Seek lda BB.HdrTrk get track we're on
jsr BB.Trk2Qtrk
sta BB.CurrentQTrack
lda BB.TargetTrk
jsr BB.Trk2Qtrk
sta BB.TargetQTrack
lda BB.CurrentQTrack
cmp BB.TargetQTrack
beq BB.Read
ldx BB.Slotn0 will do a ph0 off
ldy BB.Slotn0
.1 jsr BB.PhasesOff
bcs .2
* Current < Target, must move in
inc
.HS B0 BCS
* Current > Target, must move out
.2 dec
sta BB.CurrentQTrack
pha
and #6
ora BB.Slotn0
tax
pla
bcs .3
* Current < Target, must move in
inc
.HS B0 BCS
* Current > Target, must move out
.3 dec
and #6
ora BB.Slotn0
bcc .4
* move out : invert 2 phases
phx
tax
pla
.4 tay
lda IO.D2.Ph0On,x
nop
nop
lda IO.D2.Ph0On,y
nop
nop
lda #IO.D2.SeekTimeB
jsr BB.Wait
.6 lda BB.CurrentQTrack
cmp BB.TargetQTrack
bne .1
lda #0
jsr BB.Wait
jsr BB.PhasesOff
bra BB.Read
*--------------------------------------
BB.PhasesOff bit IO.D2.Ph0Off,x
nop
nop
ldx IO.D2.Ph0Off,y
nop
nop
rts
*--------------------------------------
BB.Wait phx (3)
.1 ldx BB.Slotn0 (3)
bit IO.D2.RData,x (4)
ldx #18 (2)
.2 dex (2)
bne .2 (3)
dec (2)
bne .1 (3)
plx (4)
rts (6)
*--------------------------------------
BB.Trk2Qtrk asl x2
sta .1+1
bit BB.HdrVol
bpl .1 x4
bvs .1 > $C0 ? (VOL=254)
lsr x3
.1 adc #$ff SELF MODIFIED
BB.Trk2Qtrk.RTS rts
*--------------------------------------
BB.Read ldx BB.Slotn0
stz BB.RetryCnt
php
tryread plp fix stack.
rdhead sec anticipate error.
inc BB.RetryCnt if = 0 then give up!
beq BB.Trk2Qtrk.RTS branch if can't fine/read sector.
clc indicate reading header.
ldy #0 Retry cnt waiting D5
rddata php carry set if reading sector.
rd0 iny
beq tryread
*--------------------------------------
* from zzstart to zzend code is moved from rom and modified to match this code...
*--------------------------------------
zzstart .EQ *
rd1 lda IO.D2.RData,x read a byte from the state machine.
bpl rd1 loop until ready.
.DUMMY
rd1a eor #$d5 mark 1?
mod1 .EQ *-zzstart+1
bne rd0 branch if not.
chg1 .EQ rd0-*
rd2 lda IO.D2.RData,x
bpl rd2
cmp #$aa mark 2?
bne rd1a
nop waste a little time.
rd3 lda IO.D2.RData,x
bpl rd3
cmp #$96 header mark 3?
beq rdhd1 branch if it is.
plp were we looking for data mark 3?
mod2 .EQ *-zzstart+1
bcc rdhead branch if not.
chg2 .EQ rdhead-*
eor #$ad data mark 3?
beq rddt1 go read data field if true...
mod3 .EQ *-zzstart+1
rdhd0 bne rdhead otherwise, start over.
chg3 .EQ rdhead-*
rdhd1 ldy #3 read in trk,sect,&volume #.
mod8 .EQ *-zzstart
rdhd2 sta (BB.HdrPtr),y save last result in .. , BB.HdrTrk , BB.HdrVol , ..
rdhd3 lda IO.D2.RData,x
bpl rdhd3
rol
sta oddbits save odd bits (7,5,3,1)
rdhd4 lda IO.D2.RData,x
bpl rdhd4
and oddbits combine even and odd to form value.
dey
bne rdhd2 read in next pair.
plp
cmp sector last byte formed is sector#
mod4 .EQ *-zzstart+1
bne rdhead branch if target sector not found.
chg4 .EQ rdhead-*
mod9 .EQ *-zzstart+1
lda BB.HdrTrk previous result is track #
cmp BB.TargetTrk is desired track found?
mod5 .EQ *-zzstart+1
bne goseek re-seek if mismatch.
chg5a .EQ *
mod6 .EQ *-zzstart+1
bcs rddata branch if proper track always.
chg6 .EQ rddata-*
*--------------------------------------
rddt1 ldy #$56 read 2 bit groupings first.
rddt1a sty oddbits
rddt2 ldy IO.D2.RData,x
bpl rddt2
eor dnib,y denibblize using table left from boot rom.
ldy oddbits save in nbuf1
dey
sta nbuf1,y
bne rddt1a loop until all 86 groups are read.
rddt3 sty oddbits now count up for 6-bit groups.
rddt4 ldy IO.D2.RData,x
bpl rddt4
eor dnib,y
ldy oddbits save result to specified buffer.
sta (dbuf),y
iny
bne rddt3 loop for 256 bytes.
rdchk ldy IO.D2.RData,x now verify checksum...
bpl rdchk
eor dnib,y must be equal...
mod7 .EQ *-zzstart+1
bne rdhd0 branch if error.
chg7 .EQ rdhd0-*
ldy #0 make y=0
nxttwo ldx #$56 now combine 2-bit group with 6 bit group
twobit dex all done with this group?
bmi nxttwo branch if so.
lda (dbuf),y
lsr nbuf1,x
rol
lsr nbuf1,x
rol
sta (dbuf),y
iny
bne twobit
*--------------------------------------
zzzend ldx BB.Slotn0
clc indicate good read.
rts
chg5 .EQ *-chg5a
goseek jmp BB.Seek
.ED
*--------------------------------------
.LIST ON
BB.End .EQ *
BB.Free .EQ $a00-*
.BS BB.Free
.LIST OFF
.EP
*--------------------------------------
MAN
SAVE usr/src/lib/libblkdev.s.bb
LOAD usr/src/lib/libblkdev.s
ASM