A2osX/SHARED/X.BB.FX2.S.txt
2023-06-02 22:31:09 +02:00

586 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
*--------------------------------------
* 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
ldy ROM.D2.Slotn0
lda IO.D2.Ph0Off,y
lda IO.D2.Ph0Off+2,y
lda IO.D2.Ph0Off+4,y
lda IO.D2.Ph0Off+6,y
* 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