mirror of
https://github.com/A2osX/A2osX.git
synced 2024-11-22 16:31:07 +00:00
580 lines
12 KiB
Plaintext
580 lines
12 KiB
Plaintext
NEW
|
||
AUTO 3,1
|
||
*--------------------------------------
|
||
* 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15
|
||
*
|
||
* $0800 : Block 00 ProDOS (sect 0,2)
|
||
* $0A00 : Block 01 SOS (sect 4,6)
|
||
* $0C00 : Block 02 Cat (sect 8,10)
|
||
* $0E00 : Block 03 Cat (sect 12,14)
|
||
* $1000 : Block 04 Cat (sect 1,3)
|
||
* $1200 : Block 05 Cat (sect 5,7)
|
||
*--------------------------------------
|
||
ROM.D2.DataBuf .EQ $26
|
||
ROM.D2.Slotn0 .EQ $2b
|
||
ROM.D2.oddbits .EQ $3c
|
||
ROM.D2.ReqSect .EQ $3d
|
||
|
||
BB.RetryCnt .EQ $40
|
||
BB.TargetTrk .EQ $41
|
||
|
||
ZP.BLK.CMD .EQ $42
|
||
ZP.BLK.UNIT .EQ $43
|
||
ZP.BLK.BUFPTR .EQ $44
|
||
ZP.BLK.BLKNUM .EQ $46
|
||
|
||
ZP.FX2.GoROM .EQ $48 device call entry address
|
||
ZP.FX2.iBLKLO .EQ $4a pointer to low page of index block
|
||
ZP.FX2.iBLKHI .EQ $4c pointer to high page of index block
|
||
ZP.FX2.iBLKPtr .EQ $4e index byte pointer
|
||
|
||
BB.CurrentQTrack .EQ $50
|
||
BB.TargetQTrack .EQ $51
|
||
BB.tmpTrk .EQ $52
|
||
BB.FX2.AddrField .EQ $53
|
||
BB.FX2.AddrField.S .EQ $54
|
||
BB.FX2.AddrField.T .EQ $55
|
||
BB.FX2.AddrField.V .EQ $56
|
||
*--------------------------------------
|
||
iobuff .EQ $60
|
||
|
||
nbuf1 .EQ $300
|
||
dnib .EQ $2d6
|
||
|
||
clrscrn .EQ $fc58
|
||
|
||
BB.FX2.CATBLK1 .EQ $c00
|
||
*--------------------------------------
|
||
*
|
||
* BLOCK 0
|
||
*
|
||
*--------------------------------------
|
||
.PH $800
|
||
BB.FX2.Boot .DA #1
|
||
sec Apple /// enters $800 'ora $38'
|
||
bcs BB.FX2.Apple2 branch if not apple iii native mode
|
||
*--------------------------------------
|
||
BB.FX2.Apple3 lda #$9f make Apple /// 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.FX2.Apple2 stx ZP.BLK.UNIT save unit number
|
||
cmp #3
|
||
php
|
||
|
||
txa find out if disk ii
|
||
and #$70 strip drive # if any
|
||
lsr
|
||
lsr get slot address
|
||
lsr
|
||
lsr
|
||
ora #$c0
|
||
sta ZP.FX2.GoROM+1
|
||
ldy #0
|
||
sty ZP.FX2.GoROM
|
||
|
||
plp
|
||
|
||
dey Y=#$ff
|
||
lda (ZP.FX2.GoROM),y get device entry addr
|
||
bne BB.FX2.BDEV branch if not disk ii (16 sector)
|
||
|
||
bcs BB.FX2.BDEV 2 sectors read
|
||
|
||
lda #3 make rom read only sector 2
|
||
sta BB.FX2.Boot to complete block 0
|
||
inc ROM.D2.ReqSect was = 1
|
||
|
||
lda ZP.FX2.GoROM+1
|
||
pha
|
||
lda #$5b
|
||
pha
|
||
rts
|
||
*--------------------------------------
|
||
BB.FX2.BDEV sta ZP.FX2.GoROM save low adr of device call entry.
|
||
|
||
ldy #0
|
||
|
||
sty iobuff $0A00
|
||
sty ZP.BLK.BLKNUM+1 $0001
|
||
|
||
sty BB.FX2.AddrField.V tell BB.FX2.SeekReadD2 vol 00
|
||
sty BB.FX2.AddrField.T tell BB.FX2.SeekReadD2 we are on track 0
|
||
|
||
iny Y=1
|
||
sty ZP.BLK.CMD set read command.
|
||
|
||
sty ZP.BLK.BLKNUM to read SOS+directory blocks
|
||
|
||
lda #$0A 1-5 at $A00
|
||
sta iobuff+1 $0A00
|
||
|
||
.1 jsr BB.FX2.ReadBLK
|
||
bcs .9 give up on error.
|
||
|
||
inc ZP.BLK.BLKNUM
|
||
lda ZP.BLK.BLKNUM have all directory blocks been read?
|
||
cmp #6
|
||
bcc .1 loop if not.
|
||
|
||
jmp BB.FX2.ScanCat
|
||
|
||
.9 jmp BB.FX2.BootErr
|
||
*--------------------------------------
|
||
BB.FX2.ReadBLK lda iobuff
|
||
sta ZP.BLK.BUFPTR
|
||
lda iobuff+1
|
||
sta ZP.BLK.BUFPTR+1
|
||
|
||
inc iobuff+1
|
||
inc iobuff+1
|
||
|
||
lda ZP.FX2.GoROM
|
||
beq BB.FX2.ReadD2
|
||
|
||
jmp (ZP.FX2.GoROM)
|
||
*--------------------------------------
|
||
BB.FX2.ReadD2 lda ZP.BLK.BLKNUM 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 ROM.D2.ReqSect
|
||
|
||
lda ZP.BLK.BLKNUM+1 get high block #
|
||
lsr shift hi addr to carry.
|
||
lda ZP.BLK.BLKNUM now figure track #
|
||
ror
|
||
lsr
|
||
lsr
|
||
sta BB.TargetTrk
|
||
*--------------------------------------
|
||
lda ZP.BLK.BUFPTR+1
|
||
sta ROM.D2.DataBuf+1
|
||
|
||
ldx ROM.D2.Slotn0
|
||
lda IO.D2.DrvOn,x
|
||
|
||
jsr BB.FX2.SeekReadD2
|
||
|
||
inc ROM.D2.DataBuf+1 bump address
|
||
inc ROM.D2.ReqSect
|
||
inc ROM.D2.ReqSect and sector #
|
||
bcs .9 branch if error.
|
||
|
||
jsr BB.FX2.ReadSectD2
|
||
|
||
.9 ldx ROM.D2.Slotn0
|
||
ldy IO.D2.DrvOff,x
|
||
rts return error status in carry.
|
||
*--------------------------------------
|
||
BB.FX2.HeadSelect
|
||
lda BB.FX2.AddrField.V
|
||
beq .8 VOL = 00
|
||
|
||
asl
|
||
bcc .8 single sided
|
||
|
||
bmi .8 > 192
|
||
|
||
lda BB.TargetTrk
|
||
and #1
|
||
lsr
|
||
php
|
||
|
||
rol
|
||
rol A = 0/2
|
||
|
||
ora ROM.D2.Slotn0
|
||
tay y = n0/n2
|
||
|
||
lda IO.D2.Ph0On,y
|
||
lda IO.D2.Ph0On+4,y
|
||
|
||
lda #1
|
||
jsr BB.Wait100usecA
|
||
|
||
lda IO.D2.Ph0Off,y
|
||
lda IO.D2.Ph0Off+4,y
|
||
|
||
lsr BB.FX2.AddrField.T
|
||
plp
|
||
rol BB.FX2.AddrField.T
|
||
|
||
.8 rts
|
||
*--------------------------------------
|
||
BB.FX2.Trk2Qtrk
|
||
ldy BB.FX2.AddrField.V
|
||
beq .5
|
||
|
||
cpy #$85
|
||
bcs .5 > 192 ? must be a buggy 254
|
||
|
||
sta BB.tmpTrk
|
||
|
||
tya
|
||
and #%00000111 stepping
|
||
tay
|
||
|
||
lda #0
|
||
clc
|
||
|
||
.2 adc BB.tmpTrk
|
||
dey
|
||
bne .2
|
||
|
||
rts
|
||
|
||
.5 asl X4 standard stepping
|
||
asl
|
||
|
||
BB.Trk2Qtrk.RTS rts
|
||
*--------------------------------------
|
||
BB.FX2.SeekPhOnY
|
||
and #6
|
||
ora ROM.D2.Slotn0
|
||
tay
|
||
lda IO.D2.Ph0On,y
|
||
rts
|
||
*--------------------------------------
|
||
BB.FX2.SeekReadD2
|
||
jsr BB.FX2.HeadSelect
|
||
|
||
lda BB.TargetTrk
|
||
jsr BB.FX2.Trk2Qtrk
|
||
sta BB.TargetQTrack
|
||
|
||
lda BB.FX2.AddrField.T
|
||
jsr BB.FX2.Trk2Qtrk
|
||
sta BB.CurrentQTrack
|
||
|
||
cmp BB.TargetQTrack
|
||
beq BB.FX2.ReadSectD2
|
||
|
||
bit #1 A = Current QT
|
||
beq .2 we are on 0/4 or 2/4 track
|
||
|
||
pha
|
||
|
||
bcc .1 if CC, C < T, must move in
|
||
|
||
inc move out: X = Ph(N+1)
|
||
|
||
.1 jsr BB.FX2.SeekPhOnY move in : X = Ph(N)
|
||
|
||
tya
|
||
tax
|
||
|
||
pla
|
||
|
||
bcs .2 if CS, C > T, must move out
|
||
|
||
inc move in : Y = Ph(N+1)
|
||
|
||
.2 jsr BB.FX2.SeekPhOnY move out: Y = Ph(N)
|
||
|
||
bra .9 Ph ON to go to 0/4 or 2/4, no wait
|
||
*--------------------------------------
|
||
.3 bcs .4 if CS, C > T, must move out
|
||
|
||
inc CC: C < T, ON next PH
|
||
|
||
.HS B0 BCS
|
||
|
||
.4 dec CS: C > T, ON prev PH
|
||
|
||
sta BB.CurrentQTrack
|
||
|
||
bit #1
|
||
bne .5 we must go to 1/4 or 3/4
|
||
|
||
lda IO.D2.Ph0Off,x we must go to 0/4 or 2/4 : Off Prev Ph
|
||
bra .8 go wait....
|
||
|
||
.5 phy we must go on 1/4 or 3/4
|
||
plx Y already ON, -> X for Ph0Off,x
|
||
|
||
bcs .6 if CS, C > T, must move out
|
||
|
||
inc CC: C < T, ON next PH
|
||
|
||
.6 jsr BB.FX2.SeekPhOnY now X and Y on
|
||
|
||
.8 lda #IO.D2.SeekTimeB
|
||
|
||
jsr BB.Wait100usecA ...wait...
|
||
|
||
.9 lda BB.CurrentQTrack
|
||
cmp BB.TargetQTrack
|
||
bne .3
|
||
|
||
lsr CS if X,Y on
|
||
|
||
lda #0
|
||
jsr BB.Wait100usecA
|
||
|
||
lda IO.D2.Ph0Off,y
|
||
|
||
bcc .10
|
||
|
||
clc
|
||
|
||
lda IO.D2.Ph0Off,x
|
||
|
||
.10
|
||
*--------------------------------------
|
||
BB.FX2.ReadSectD2
|
||
ldx ROM.D2.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 DATA.
|
||
|
||
rd0 iny
|
||
beq tryread
|
||
|
||
rd1 lda IO.D2.RData,x read a byte from the state machine.
|
||
bpl rd1 loop until ready.
|
||
|
||
rd1a eor #$d5 mark 1?
|
||
bne rd0 branch if not.
|
||
|
||
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?
|
||
bcc rdhead branch if not.
|
||
|
||
eor #$ad data mark 3?
|
||
beq rddt1 go read data field if true...
|
||
|
||
rdhd0 bne rdhead otherwise, start over.
|
||
|
||
rdhd1 ldy #3 read volume,trk,sect
|
||
|
||
rdhd2 lda IO.D2.RData,x
|
||
bpl rdhd2
|
||
|
||
rol
|
||
sta ROM.D2.oddbits save odd bits (7,5,3,1)
|
||
|
||
rdhd4 lda IO.D2.RData,x
|
||
bpl rdhd4
|
||
|
||
and ROM.D2.oddbits combine even and odd to form value.
|
||
sta BB.FX2.AddrField,y
|
||
dey
|
||
bne rdhd2 ignore Checksum, A=sector
|
||
|
||
plp
|
||
cmp ROM.D2.ReqSect last byte formed is sector#
|
||
bne rdhead branch if target sector not found.
|
||
|
||
lda BB.FX2.AddrField.T previous result is track #
|
||
cmp BB.TargetTrk is desired track found?
|
||
bne goseek re-seek if mismatch.
|
||
|
||
bcs rddata branch if proper track always.
|
||
*--------------------------------------
|
||
rddt1 ldy #$56 read 2 bit groupings first.
|
||
rddt1a sty ROM.D2.oddbits
|
||
|
||
rddt2 ldy IO.D2.RData,x
|
||
bpl rddt2
|
||
|
||
eor dnib,y denibblize using table left from boot rom.
|
||
ldy ROM.D2.oddbits save in nbuf1
|
||
dey
|
||
sta nbuf1,y
|
||
bne rddt1a loop until all 86 groups are read.
|
||
|
||
rddt3 sty ROM.D2.oddbits now count up for 6-bit groups.
|
||
|
||
rddt4 ldy IO.D2.RData,x
|
||
bpl rddt4
|
||
|
||
eor dnib,y
|
||
ldy ROM.D2.oddbits save result to specified buffer.
|
||
sta (ROM.D2.DataBuf),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...
|
||
bne rdhd0 branch if error.
|
||
|
||
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 (ROM.D2.DataBuf),y
|
||
lsr nbuf1,x
|
||
rol
|
||
lsr nbuf1,x
|
||
rol
|
||
sta (ROM.D2.DataBuf),y
|
||
iny
|
||
bne twobit
|
||
|
||
clc
|
||
rts
|
||
*--------------------------------------
|
||
goseek jmp BB.FX2.SeekReadD2
|
||
*--------------------------------------
|
||
BB.Wait100usecA phx (3)
|
||
|
||
.1 ldx #19 (2)
|
||
|
||
.2 dex (2)
|
||
bne .2 (3)
|
||
|
||
dec (2)
|
||
bne .1 (3)
|
||
|
||
plx (4)
|
||
|
||
rts (6)
|
||
*--------------------------------------
|
||
BB.FX2.BootErr jsr clrscrn clear video
|
||
ldy #BB.MSG.ERR.Len-1
|
||
|
||
.1 lda BB.MSG.ERR,y
|
||
sta $5b6,y
|
||
dey
|
||
bpl .1
|
||
|
||
jmp $ff69
|
||
*--------------------------------------
|
||
BB.MSG.ERR .AS -"BOOT ERROR"
|
||
BB.MSG.ERR.Len .EQ *-BB.MSG.ERR
|
||
*--------------------------------------
|
||
*
|
||
* BLOCK 1
|
||
*
|
||
*--------------------------------------
|
||
BB.FX2.ScanCat ldy #0
|
||
sty ZP.FX2.iBLKLO
|
||
sty ZP.FX2.iBLKHI
|
||
sty ZP.FX2.iBLKPtr
|
||
|
||
sta ZP.FX2.iBLKLO+1
|
||
|
||
lda #4 begin look-up with first entry past header.
|
||
.HS 2C BIT ABS
|
||
.1 lda ZP.FX2.iBLKLO
|
||
clc
|
||
adc BB.FX2.CATBLK1+$23 ENTRY_LEN : bump to next directory entry.
|
||
tay save in y for now.
|
||
bcc .2 branch if not a page cross.
|
||
|
||
inc ZP.FX2.iBLKLO+1
|
||
lda ZP.FX2.iBLKLO+1 check for new block.
|
||
lsr if even then new block.
|
||
bcs .2
|
||
|
||
cmp #$a have all file names been compared?
|
||
beq BB.FX2.BootErr branch if no pro.kernel.
|
||
|
||
ldy #4 else, begin at block beginning.
|
||
|
||
.2 sty ZP.FX2.iBLKLO
|
||
|
||
ldy #6
|
||
|
||
.3 lda (ZP.FX2.iBLKLO),y look for matching name.
|
||
cmp BB.FX2.ProDOS,y
|
||
bne .1 branch if no match.
|
||
|
||
dey
|
||
bpl .3
|
||
|
||
* ldy #$10 get file type & index block addr.
|
||
* lda (ZP.FX2.iBLKLO),y
|
||
* cmp #S.FI.T.SYS is it a system file?
|
||
* bne BB.FX2.BootErr
|
||
* iny
|
||
|
||
ldy #$11
|
||
|
||
lda (ZP.FX2.iBLKLO),y
|
||
sta ZP.BLK.BLKNUM
|
||
iny
|
||
lda (ZP.FX2.iBLKLO),y
|
||
sta ZP.BLK.BLKNUM+1
|
||
|
||
stz ZP.FX2.iBLKLO
|
||
stz ZP.FX2.iBLKHI
|
||
|
||
ldy #$1e read index block at $1e00 and
|
||
sty ZP.FX2.iBLKLO+1 kernel at $2000
|
||
sty iobuff+1
|
||
iny
|
||
sty ZP.FX2.iBLKHI+1
|
||
*--------------------------------------
|
||
BB.FX2.LOADSYS jsr BB.FX2.ReadBLK read index block.
|
||
bcs BB.FX2.BootErr
|
||
|
||
ldy ZP.FX2.iBLKPtr get index pointer
|
||
inc ZP.FX2.iBLKPtr bump for next time.
|
||
|
||
lda (ZP.FX2.iBLKLO),y
|
||
sta ZP.BLK.BLKNUM
|
||
lda (ZP.FX2.iBLKHI),y high disk addr.
|
||
sta ZP.BLK.BLKNUM+1
|
||
|
||
ora (ZP.FX2.iBLKLO),y if both=0 then done.
|
||
bne BB.FX2.LOADSYS branch if more to read.
|
||
|
||
jmp $2000 go execute kernel code.
|
||
*--------------------------------------
|
||
BB.FX2.ProDOS .DA #$26 $20 = storage type + 6 = "PRODOS" len
|
||
.AS "PRODOS"
|
||
*--------------------------------------
|
||
.LIST ON
|
||
BB.FX2.Free .EQ $C00-*
|
||
.BS BB.FX2.Free
|
||
.LIST OFF
|
||
.EP
|
||
*--------------------------------------
|
||
MAN
|
||
SAVE usr/src/shared/x.bb.fx2.s
|
||
LOAD usr/src/lib/libblkdev.s
|
||
ASM
|