A2osX/LIB/LIBBLKDEV.S.txt

512 lines
11 KiB
Plaintext
Raw Normal View History

PR#3
PREFIX /A2OSX.SRC
NEW
INC 1
AUTO 6
.LIST OFF
.OP 65C02
.OR $2000
.TF /A2OSX.BOOT/LIB/LIBBLKDEV.O
*--------------------------------------
.INB /A2OSX.DEV/INC/MACROS.I
.INB /A2OSX.DEV/INC/A2OSX.I
.INB /A2OSX.DEV/INC/PRODOS.I
.INB /A2OSX.DEV/INC/LIBBLKDEV.I
*--------------------------------------
* NIBBLE track len = $1A00 (6656) bytes:
*
*--------------------------------------
GAP1 .EQ 48
GAP2 .EQ 6
GAP3 .EQ 27
*--------------------------------------
Status.PrvDrvOff .EQ $80 Waiting old drive stop spining
Status.DrvOn .EQ $81 Waiting target drive spin
Status.seek .EQ $82 targetdrive seeking
*--------------------------------------
D2Ph0Off .EQ $C080
D2Ph0On .EQ $C081
D2Ph1Off .EQ $C082
D2Ph1On .EQ $C083
D2Ph2Off .EQ $C084
D2Ph2On .EQ $C085
D2Ph3Off .EQ $C086
D2Ph3On .EQ $C087
D2DrvOff .EQ $C088
D2DrvOn .EQ $C089
D2DrvSel1 .EQ $C08A
D2DrvSel2 .EQ $C08B
D2WShift .EQ $C08C W
D2WLoad .EQ $C08D W
D2RData .EQ $C08C R
D2ReadProt .EQ $C08D R
D2ReadMode .EQ $C08E R
D2WriteMode .EQ $C08F W
*--------------------------------------
ZPPtr1 .EQ ZPLIB
ZPPtr2 .EQ ZPLIB+2
ZPPtr3 .EQ ZPLIB+4
*--------------------------------------
* File Header (16 Bytes)
*--------------------------------------
CS.START cld
jmp (.1,x)
.DA #$61 6502,Level 1 (65c02)
.DA #1 BIN Layout Version 1
.DA 0
.DA CS.END-CS.START
.DA 0
.DA 0
.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
.1 .DA LIB.LOAD
.DA LIB.UNLOAD
.DA GetProDOSCatSize
.DA BuildProDOSCat
.DA D2TrkR16s
.DA D2TrkRNIB
.DA D2TrkW16s
.DA D2TrkWNIB
L.TrkWriter .DA TrkWriter
L.ProDOS.Boot .DA ProDOS.Boot
.DA 0
*/--------------------------------------
* #GetProDOSCatSize
* Compute space needed for ProDOS Catalog
* ##In :
* PUSHW = DevSize (in 512b blocks)
* ##Out :
* X=BlockCount (max 22)
* A=PageCount (max 44)
*\--------------------------------------
GetProDOSCatSize
>PULLAX A=DevSizeLo
GetProDOSCatSizeAX
clc for now, no partial bitmap blk to add
tay DevSize is xxxxxxxx00000000 ?
beq .1
sec
.1 txa Get DevSizeHI
bit #$0f DevSize is xxxx000000000000 ?
beq .2
sec
.2 php
lsr
lsr
lsr
lsr
plp
adc #6 at least, 1(ProDOS)+1(SOS)+4(VolDir)
tax X = Total blocks needed for header (used)
asl A = Total pages needed to build catalog.
rts
*/--------------------------------------
* #BuildProDOSCat
* ##In :
* PUSHW = DevSize (in 512b blocks)
* PUSHW = VolName (PSTR)
* PUSHW = DstBuf (Zero filled)
* Blk0 : ProDOS.BootBlk
* Blk1 : SOS.BootBlk
* Blk2,3,4,5 : Volume Directory
* Blk6.... : Volume Bitmap (4096/Blk)
* max devSize = 65535 -> max 16 Bitmap Blk
* absolute MAX DstBuf size=
* 7 for Disk II(280blk),3.5(1600),3.5HD(2880)
* 22 for 32mb Hardisk...
*\--------------------------------------
BuildProDOSCat >PULLW ZPPtr1 DstBuf
>PULLW ZPPtr2 VolName
>PULLW VolDirHdr.TB
ldx #3
.10 lda DATELO,x
sta VolDirHdr.CT,x
dex
bpl .10
* Boot Code
>LDYA L.ProDOS.Boot
>STYA ZPPtr3
ldy #0
.1 lda (ZPPtr3),y
sta (ZPPtr1),y
iny
bne .1
inc ZPPtr3
inc ZPPtr1
.2 lda (ZPPtr3),y
sta (ZPPtr1),y
iny
bne .2
inc ZPPtr1 Blk 1
inc ZPPtr1
inc ZPPtr1 Blk 2
* Directory Blocks
lda (ZPPtr2) VolName Len
and #$0f make sure 15 bytes max
tay
ora #$F0 Volume Directory Header
sta VolDirHdr.Name
.3 lda (ZPPtr2),y
sta VolDirHdr.Name,y
dey
bpl .3
ldy #VolDirHdr.size
.4 lda VolDirHdr,y
sta (ZPPtr1),y
dey
bpl .4
inc ZPPtr1
inc ZPPtr1 Blk 3
lda #2
sta (ZPPtr1)
lda #4
ldy #2
sta (ZPPtr1),y
inc ZPPtr1
inc ZPPtr1 Blk 4
lda #3
sta (ZPPtr1)
lda #5
ldy #2
sta (ZPPtr1),y
inc ZPPtr1
inc ZPPtr1 Blk 5
lda #4
sta (ZPPtr1)
inc ZPPtr1
inc ZPPtr1 Blk 6
* BitMap Blocks : 0=Used 1=free
>LDAX VolDirHdr.TB+1
jsr GetProDOSCatSizeAX X=blk used for boot/dir/bitmap
lda VolDirHdr.TB
eor #$ff
sta Count
lda VolDirHdr.TB+1
eor #$ff
sta Count+1
txa
clc
adc VolDirHdr.TB
sta VolDirHdr.TB
bcc .51
inc Count+1
.51 ldy #0
.5 lda #%10000000
.6 dex
bmi .8
asl
bne .6
iny
bne .5
.7 lda #%10000000
.8 inc Count
bne .81
inc Count+1
beq .88
.81 pha
eor (ZPPtr1),y
sta (ZPPtr1),y
pla
asl
bne .8
iny
bne .7
inc ZPPtr1+1
bra .7
.88 rts
*/--------------------------------------
*\--------------------------------------
D2TrkRNIB
*/--------------------------------------
*\--------------------------------------
D2TrkR16s
*/--------------------------------------
* #TrkW16s
* Write a track (16 sectors)
* ##In:
* PUSHW = Ptr to 16*256 buffer
* PUSHB = TrackNum * 4 : 0->140+
* PUSHB = DSSS0000
* ##Out:
* CC : success
* CS : A = Error
* A=0, currently starting/seeking...
*\--------------------------------------
D2TrkW16s
clc
rts
*/--------------------------------------
* #TrkWNIB
* Write a track (NIBBLE)
* ##In:
* PUSHW = Ptr to NIBBLE buffer (0 ended)
* PUSHB = TrackNum * 4 : 0->140+
* PUSHB = DSSS0000
* ##Out:
* CC : success
* CS : A = Error
* A=0, currently starting/seeking...
*\--------------------------------------
D2TrkWNIB >PULLB DrvSlt
>PULLB TrkNum
>PULLW ZPPtr1
lda Status Lib is busy....?
beq .10
lda DrvSlt
cmp DrvSltInUse resume previous access ?
.10 lda DEVNUM last drive accessed by ProDOS
and #$F0 only DSSS
pha
jsr CheckDiskII was it a DISK II ?
bcs .1 no, no need to check if spinning
pla
pha
jsr DrvSpinCheck
bcc .1 not spinning....continue
pla
sta D2DrvOff,x
lda #Status.PrvDrvOff
jmp SetStatusAndExit
.1 pla
cmp DrvSlt
* beq
lda DrvSlt
jsr DrvTrkSelect
bcs .9
ldy #TrkWriter.Size
.7 lda TrkWriter,y
sta UsrBuf256,y
dey
bne .7
jmp UsrBuf256
clc
.9 rts
*--------------------------------------
SetStatusAndExit
sta Status
ldy DrvSlt
sty DrvSltInUse
clc
rts
*--------------------------------------
LIB.LOAD
LIB.UNLOAD clc
rts
*--------------------------------------
* A=DSSS0000
* Y=target Track Number * 4
*--------------------------------------
DrvTrkSelect jsr DrvSelect
*--------------------------------------
* A=DSSS0000
*--------------------------------------
CheckDiskII and #$70 only 0SSS
lsr
lsr
lsr
ora #$C0 make Cn
sta .2+2
ldx #3 4 bytes to check
.1 ldy DiskII.OFS,x
.2 lda $C000,y Self Modified
cmp DiskII.SIG,x
bne .9
dex
bpl .1
clc all bytes match, Disk II
rts
.9 sec
rts
*--------------------------------------
* A=DSSS0000
*--------------------------------------
DrvSpinCheck jsr DrvSelect
ldy #0
lda D2RData,x
.1 cmp D2RData,x
bne .8 spinning
dey
bne .1
clc CC:not spinning
rts
.8 sec
rts
*--------------------------------------
* A=DSSS0000
*--------------------------------------
DrvSelect pha
and #$70
tax
pla
asl
adc #D2DrvSel1
sta .1+1
.1 lda D2DrvSel1,x Drv 1/2 select
lda D2ReadMode,x Make sure readmode
rts
*--------------------------------------
CS.END
DiskII.OFS .HS 010305FF
DiskII.SIG .HS 20000300
DrvSlt .BS 1
TrkNum .BS 1
*--------------------------------------
Status .BS 1
DrvSltInUse .BS 1
Count .BS 2
*--------------------------------------
* TrkWriter
* X = Slot Cn
* ZPPtr1 = Ptr To NibbleBuf
*--------------------------------------
TrkWriter .PH $200
TrkWriter.Start lda D2ReadMode,x
lda D2ReadProt,x
bmi .9 Write protected
php
sei
ldy #0
.1 lda (ZPPtr1),y (5) as NibbleBuf is page alligned, no page crossing
beq .8 (2)(3 if Z) END OF TRACK
* nobody will never try to write 00000000, right?
cmp #$80 (2) if CC, it is a sync byte
ora #$80 (2) make sure Bit7 high
sta D2WriteMode,x (5)
ora D2WShift,x (4) keep C unmodified
iny (2)
bne .2 (2)(3 if nz)
inc ZPPtr1+1 (5)
bcs .1 (2)(3 if cs) regular 32us byte
* 32us Byte,next page : 5+2 (beq failed) +2+2+5+4+2+2 (bne failed) + 5 + 3 (bcs succeeded) = 32
nop (2) Sync 40us byte : add 8 cycles
nop (2)
nop (2)
bra .1 (3)
* 40us Byte,next page : 5+2 (beq failed) +2+2+5+4+2+2 (bne failed) + 5 + 2 (bcs failed) +2+2+2+3 = 40
.2 nop (2)
nop (2)
bcs .1 (2)(3 if cs) regular 32us byte
* 32us Byte,same page : 5+2 (beq failed) +2+2+5+4+2+3 (bne succeeded) + 2 +2 + 3 (bcs succeeded) = 32
nop (2) Sync 40us byte : add 8 cycles
nop (2)
nop (2)
bra .1 (3)
* 40us Byte,same page : 5+2 (beq failed) +2+2+5+4+2+2 (bne failed) + 5 + 2 (bcs failed) +2+2+2+3 = 40
.8 pha (3) make sure 32us elapsed before switching to read mode (beq(3)+pha(3)=beq(2)+cmp(2)+ora(2))
lda D2ReadMode,x close write mode
lda D2RData,x
pla from pha (3)
plp
clc
rts
.9 lda #$2B Write Protected
sec
rts
TrkWriter.Size .EQ *-TrkWriter.Start
.EP
*--------------------------------------
ProDOS.Boot .BS 512
*--------------------------------------
VolDirHdr .DA 0 pointer to previous block
.DA 3 pointer to next block
VolDirHdr.Name .BS 16
.HS 0000000000000000
VolDirHdr.CT .BS 4 Creation time
.HS 0100C3270D version/min version/access/EL/EPB
.DA 0 File Count
.DA 6 bitmap pointer (Block 2..5 are Volume directory)
VolDirHdr.TB .BS 2 Total Blocks
VolDirHdr.size .EQ *-VolDirHdr
*--------------------------------------
MAN
SAVE LIB/LIBBLKDEV.S
ASM