NEW
  AUTO 3,1
				.LIST OFF
				.OP	65C02
				.OR	$2000
				.TF lib/libblkdev
*--------------------------------------
				.INB inc/macros.i
				.INB inc/a2osx.i
				.INB inc/mli.i
				.INB inc/mli.e.i
				.INB inc/io.d2.i
*--------------------------------------
* 300rpm = 5rps = 200000us / 4us = 50000 bits MAX
*--------------------------------------
TRACK16.LEN		.EQ 6240
*--------------------------------------
TRACK16.GAP1	.EQ 80								800 bits
* 16 * (
*Address field = D5AA96 + 4x2 + DEAAEB = 14			112 bits
TRACK16.GAP2	.EQ 6								60 bits
*Data field = D5AAAD + 342 + CS + DEAAEB = 349		2792 bits
TRACK16.GAP3	.EQ 16								160 bits
* )
* 80 + 16 * (6 + 14 + 349 + 16) = 6240				800 + 49984 bits
*--------------------------------------
TRACK9.LEN		.EQ 6511
*--------------------------------------
TRACK9.GAP1		.EQ 8+14							220 bits
* 9 * (
*Address field = D5AA96 + 4x2 + DEAAEB = 14			112 bits
TRACK9.GAP2		.EQ 5								50 bits
*Data field = D5AAAD + 342 + 342 + CS  = 688		5504 bits
TRACK9.GAP3		.EQ 14								140 bits
* )
* 9 * (14 + 5 + 688) = 6363							50904 bits (1480 free = 148 sync bytes)
* 22 + 9 * (14 + 5 + 688 + 14) = 6511				52384 bits (6548)
*--------------------------------------
ZPPtr1			.EQ ZPLIB
ZPPtr2			.EQ ZPLIB+2
ZPPtr3			.EQ ZPLIB+4
ZPPtr4			.EQ ZPLIB+6
X.TRkFMT.Z		.EQ ZPLIB+8
*--------------------------------------
*			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 D2.MotorControl
				.DA D2.Recalibrate
				.DA D2.MoveHead
				.DA D2.HeadSelect
				.DA D2.TrkFmt16s
				.DA D2.TrkRead16s
				.DA D2.TrkWrite16s
				.DA D2.TrkReadNIB
				.DA D2.TrkWriteNIB
L.X.BB.PRODOS	.DA X.BB.PRODOS
L.X.BB.SOS		.DA X.BB.SOS
L.X.BB.FXpart1	.DA X.BB.FX2
L.X.BB.FXpart2	.DA X.BB.FX2+512
				.DA 0
*--------------------------------------
LIB.LOAD
LIB.UNLOAD		clc
				rts
*/--------------------------------------
* # GetProDOSCatSize
*  Compute space needed for ProDOS Catalog
* ## C
* int getprodoscatsize (short int options, short int catsize, int devsize );
* ## ASM
*  PUSHW = DevSize (in 512b blocks)
*  PUSHB = Catalog Size (in blocks)
*  PUSHB = Options
* ## RETURN VALUE
*  X=BlockCount (max 22)
*  Y,A=BufSize  (max $4400)
*\--------------------------------------
GetProDOSCatSize
				>PULLB VolDirHdr.Options
				>PULLB VolDirHdr.CatSize
				>PULLW VolDirHdr.TB
GetProDOSCatSize.I
				lda VolDirHdr.TB		Get DevSizeLo
				clc						for now, no partial bitmap blk to add
				tay						DevSize is xxxxxxxx00000000 ?
				beq .1

				sec

.1				lda VolDirHdr.TB+1		Get DevSizeHI
				bit #$0f				DevSize is xxxx000000000000 ?
				beq .2

				sec

.2				php
				lsr
				lsr
				lsr
				lsr
				plp
				inc						+1 (ProDOS)
				inc						+1 (SOS)
				adc VolDirHdr.CatSize	+x (VolDir)
				tax						X = Total blocks needed for header (used)
				asl						A = Total pages needed to build catalog.
				rts
*/--------------------------------------
* # BuildProDOSCat
* ## ASM
*  PUSHW = DevSize (in 512b blocks)
*  PUSHB = Catalog Size (in blocks)
*  PUSHB = Options
*  PUSHW = VolName (PSTR)
*  PUSHW = DstBuf (Zero filled)
*   Blk0 : ProDOS.BootBlk
*   Blk1 : SOS.BootBlk
*   Blk2...n : Volume Directory
*   Blkn+1.. : 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
				>PULLB VolDirHdr.Options
				>PULLB VolDirHdr.CatSize
				inc
				inc
				sta VolDirHdr.BMPtr
				>PULLW VolDirHdr.TB

				ldx #3

.10				lda GP.DATE,x
				sta VolDirHdr.CT,x
				dex
				bpl .10

				bit VolDirHdr.Options
				bmi .11

* Blk 0 : ProDOS Boot Code
				>LDYA L.X.BB.PRODOS
				jsr Add2Pages

* Blk 1 : (SOS boot code)

				>LDYA L.X.BB.SOS
				jsr Add2Pages
				bra .20

.11				>LDYA L.X.BB.FXpart1
				jsr Add2Pages
				
				>LDYA L.X.BB.FXpart2
				jsr Add2Pages

* Blk 2 : First Directory Block

.20				jsr ZeroPtr1

*				ldy #0

*				stz VolDirHdr.Prev
*				stz VolDirHdr.Prev+1	always 0

				lda #3					next block

				ldx VolDirHdr.CatSize
				dex
				bne .30

				txa

.30				sta VolDirHdr.Next
*				stz VolDirHdr.next+1
*				stz VolDirHdr.VER
*				stz VolDirHdr.MVER

.3				lda (ZPPtr2),y
				beq .39

				iny

				cmp #'a'
				bcc .38
				cmp #'z'+1
				bcs .38

				eor #$20

				pha
				cpy #8
				bcs .31

				lda LC.BitMap,y
				tsb VolDirHdr.MVER
				bra .32

.31				lda LC.BitMap-8,y
				tsb VolDirHdr.VER

.32				lda #$80
				tsb VolDirHdr.MVER

				pla

.38				sta VolDirHdr.Name,y

				cpy #15
				bne .3

.39				tya
*				and #$0f				make sure 15 bytes max
				ora #$F0				Volume Directory Header
				sta VolDirHdr.Name
				ldy #VolDirHdr.size-1

.4				lda VolDirHdr,y
				sta (ZPPtr1),y
				dey
				bpl .4

* Blk 3...n : additional Directory Blocks

				lda #3					Actual Block ID
				ldy #2					next blk ptr

.41				inc ZPPtr1+1
				jsr ZeroPtr1

				inc ZPPtr1+1			Next Block
				jsr ZeroPtr1

				dex
				bmi .40

				dec						Previous Blk ID
				sta (ZPPtr1)
				inc
				inc						next blk id
				phx
				plx
				bne .42

				txa

.42				sta (ZPPtr1),y
				bra .41

* BitMap Blocks : 0=Used 1=free

.40
BuildProDOSCat.BM
				jsr GetProDOSCatSize.I	X=blk used for boot/dir/bitmap

				lda VolDirHdr.TB
				eor #$ff
				sta Count

				lda VolDirHdr.TB+1
				eor #$ff
				sta Count+1

				ldy #0

.50				lda #%10000000
.5				dex
				bmi .8

				inc Count
				bne .6
				inc Count+1

.6				lsr
				bne .5
				iny
				bne .50

.7				lda #%10000000

.8				inc Count
				bne .81

				inc Count+1
				bne .81

				clc
				rts

.81				pha
				eor (ZPPtr1),y
				sta (ZPPtr1),y
				pla
				lsr
				bne .8

				iny
				bne .7

				inc ZPPtr1+1
				jsr ZeroPtr1
				bra .7
*--------------------------------------
ZeroPtr1		phy
				pha
				lda #0
				tay

.1				sta (ZPPtr1),y
				iny
				bne .1
				pla
				ply
				rts
*--------------------------------------
Add2Pages		>STYA ZPPtr3

				ldy #0
				ldx #2					2 pages

.1				lda (ZPPtr3),y
				sta (ZPPtr1),y
				iny
				bne .1

				inc ZPPtr3+1
				inc ZPPtr1+1
				dex
				bne .1
				
				rts
*--------------------------------------
				.INB usr/src/lib/libblkdev.s.d2
*--------------------------------------
CS.END
*--------------------------------------
* TrkFormat
* X = Slot Cn
*--------------------------------------
D2.TrkFormat	.PH $200
D2.TrkFormat.Start
				.INB usr/src/shared/x.trkfmt.s
D2.TrkFormat.Size .EQ *-D2.TrkFormat.Start
				.EP
*--------------------------------------
* TrkWriter
* X = Slot Cn
* ZPPtr1 = Ptr To NibbleBuf
*--------------------------------------
D2.TrkWriter	.PH $200

D2.TrkWriter.Start
				lda IO.D2.ReadProt,x
				lda IO.D2.ReadMode,x
				bmi .9					Write protected

				ldy ZPPtr1
				stz ZPPtr1

				lda (ZPPtr1),y

				iny

*				bne .10					no chance this happens because mem blocks are $FFF0 aligned....
*				inc ZPPtr1+1
*.10

				cmp	#$80				if CC, it is a sync byte
				ora #$80				make sure Bit7 high

				sta IO.D2.WriteMode,x	(5) goto write mode
				ora IO.D2.WShift,x		(4)

				nop						(2)

				bra .2					(3)

.1				lda (ZPPtr1),y			(5) as NibbleBuf is page aligned, 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 IO.D2.WLoad,x		(5)
				ora IO.D2.WShift,x		(4) keep C unmodified
				iny						(2)
				bne .2					(2)(3 if nz)

* 32us Byte,next page :	2 (beq failed)+5 +2+2+5+4+2+2 (bne failed) + 5 + 3 (bcs succeeded) = 32
				inc ZPPtr1+1			(5)

				bcs .1					(2)(3 if cs) regular 32us byte

* 40us Byte,next page :	2 (beq failed) +2+2+5+4+2+2 (bne failed) + 5 + 2 (bcs failed) +2+2+2+3 = 40
				nop						(2) Sync 40us byte : add 8 cycles
				nop						(2)
				nop						(2)

				bra .1					(3)

* 32us Byte,same page :	5+2 (beq failed) +2+2+5+4+2+3 (bne succeeded) + 2 +2 + 3 (bcs succeeded) = 32
.2				nop						(2)
				nop						(2)

				bcs .1					(2)(3 if cs) regular 32us byte

* 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
				nop						(2) Sync 40us byte : add 8 cycles
				nop						(2)
				nop						(2)

				bra .1					(3)

.8				pha						(3) make sure 32us elapsed before switching to read mode (beq(3)+pha(3)=beq(2)+cmp(2)+ora(2))
				lda IO.D2.ReadMode,x	close write mode
				lda IO.D2.RData,x
				pla						from pha (3)

				clc
				rts

.9				lda #MLI.E.WRTPROT
				sec
				rts

D2.TrkWriter.Size .EQ *-D2.TrkWriter.Start
				.EP
*--------------------------------------
ADDR.Head		.HS 96AAD5
DATA.Head		.HS ADAAD5
TAIL			.HS EBAADE
*--------------------------------------
Nib2FC			.HS 0004
				.HS FFFF
				.HS 080C
				.HS FF
				.HS 101418
D2.XX000000		.HS 008040C0FFFF		used in fast prenib as lookup for 2-bit quantities.
				.HS 1C20
				.HS FFFFFF
				.HS 24282C3034
				.HS FFFF
				.HS 383C4044484C
				.HS FF
				.HS 5054585C606468
D2.00XX0000		.HS 00201030			used in fast prenib.
endmrks			.HS DEAAEB		  		table using 'unused' nibbles ($C4,$C5,$C6,$C7)
				.HS FFFFFFFF
				.HS 6C
				.HS FF
				.HS 707478
				.HS FFFFFF
				.HS 7C
				.HS FFFF
				.HS 8084
				.HS FF
				.HS 888C9094989CA0
D2.0000XX00		.HS 0008040C			used in fast prenib.
				.HS FF
				.HS A4A8AC
				.HS FF
				.HS B0B4B8BCC0C4C8
				.HS FFFF
				.HS CCD0D4D8DCE0
				.HS FF
				.HS E4E8ECF0F4F8FC
*--------------------------------------
dnibl2			.HS 00
dnibl3			.HS 00
dnibl4			.HS 00
FC2Nib			.HS 96
				.HS 02000097
				.HS 0100009A
				.HS 0300009B
				.HS 0002009D
				.HS 0202009E
				.HS 0102009F
				.HS 030200A6
				.HS 000100A7
				.HS 020100AB
				.HS 010100AC
				.HS 030100AD
				.HS 000300AE
				.HS 020300AF
				.HS 010300B2
				.HS 030300B3
				.HS 000002B4
				.HS 020002B5
				.HS 010002B6
				.HS 030002B7
				.HS 000202B9
				.HS 020202BA
				.HS 010202BB
				.HS 030202BC
				.HS 000102BD
				.HS 020102BE
				.HS 010102BF
				.HS 030102CB
				.HS 000302CD
				.HS 020302CE
				.HS 010302CF
				.HS 030302D3
				.HS 000001D6
				.HS 020001D7
				.HS 010001D9
				.HS 030001DA
				.HS 000201DB
				.HS 020201DC
				.HS 010201DD
				.HS 030201DE
				.HS 000101DF
				.HS 020101E5
				.HS 010101E6
				.HS 030101E7
				.HS 000301E9
				.HS 020301EA
				.HS 010301EB
				.HS 030301EC
				.HS 000003ED
				.HS 020003EE
				.HS 010003EF
				.HS 030003F2
				.HS 000203F3
				.HS 020203F4
				.HS 010203F5
				.HS 030203F6
				.HS 000103F7
				.HS 020103F9
				.HS 010103FA
				.HS 030103FB
				.HS 000303FC
				.HS 020303FD
				.HS 010303FE
				.HS 030303FF
*--------------------------------------
LC.BitMap		.HS 8040201008040201
*--------------------------------------
X.BB.PRODOS		.INB usr/src/shared/x.bb.prodos.s
X.BB.SOS		.INB usr/src/shared/x.bb.sos.s
X.BB.FX2		.INB usr/src/shared/x.bb.fx2.s
*--------------------------------------
* Block 2 : First DIR block
*--------------------------------------
VolDirHdr
VolDirHdr.Prev	.BS 2					pointer to previous block
VolDirHdr.Next	.BS 2					pointer to next block
VolDirHdr.Name	.BS 16
				.HS 00.00.00.00.00.00.00.00
VolDirHdr.CT	.BS 4					Creation time
VolDirHdr.VER	.BS 1
VolDirHdr.MVER	.BS 1
				.HS C3.27.0D			access/EL/EPB
				.DA 0					File Count=0 (only VDH)
VolDirHdr.BMPtr	.BS 2					bitmap pointer (Block 2..n are Volume directory)
VolDirHdr.TB	.BS 2					Total Blocks
VolDirHdr.size	.EQ *-VolDirHdr
*--------------------------------------
VolDirHdr.Options	.BS 1
VolDirHdr.CatSize	.BS 1
*--------------------------------------
DiskII.OFS		.HS 010305FF
DiskII.SIG		.HS 20000300
*--------------------------------------
D2.hTrkBuf		.BS 1

D2.DrvSlt		.BS 1
D2.Slotn0		.BS 1
D2.MotorOn		.BS 1
D2.CurrentQTrack	.BS 1
D2.TargetQTrack	.BS 1

D2.Checksum		.BS 1
D2.SectNum		.BS 1
D2.TrkNum		.BS 1
D2.VolNum		.BS 1

D2.HeadNum		.BS 1

Count			.BS 2
*--------------------------------------
MAN
SAVE usr/src/lib/libblkdev.s
ASM
