NEW
  AUTO 3,1
				.LIST OFF
				.OP	65C02
				.OR	$2000
				.TF bin/format
*--------------------------------------
				.INB inc/macros.i
				.INB inc/a2osx.i
				.INB inc/mli.e.i
				.INB inc/kernel.i
				.INB inc/libblkdev.i
*--------------------------------------
				.DUMMY
				.OR ZPBIN
ZS.START
ZPPtr1			.BS 2
ZPPtr2			.BS 2
ZPPtrFD			.BS 2
ZPPtrDevName	.BS 2

Index			.BS 1
hDevID			.BS 1
hCatBuf			.BS 1
hTrackBuf		.BS 1
DSSS0000 		.BS 1
CurTrack		.BS 1
CurQTrack		.BS 1
Counter			.BS 1

BlkCnt			.BS 2
TrkCnt			.BS 1
Stepping		.BS 1
VolNum			.BS 1
AltBB			.BS 1

CatSize			.BS 1
CatBlkCnt		.BS 1

bLL				.BS 1
bCustomBlkSize 	.BS 1
bHighDensity	.BS 1
bExtraTrack		.BS 1
bVerify			.BS 1
ZS.END
				.ED
*--------------------------------------
*			File Header (16 Bytes)
*--------------------------------------
CS.START		cld
				jmp (.1,x)
				.DA #$61				6502,Level 1 (65c02)
				.DA #1					BIN Layout Version 1
				.DA #0					S.PS.F.EVENT
				.DA #0
				.DA CS.END-CS.START		Code Size (without Constants)
				.DA DS.END-DS.START		Data SegmentSize
				.DA #32					Stack Size
				.DA #ZS.END-ZS.START	Zero Page Size
				.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
.1				.DA CS.INIT
				.DA CS.RUN
				.DA CS.DOEVENT
				.DA	CS.QUIT
L.LIBBLKDEV		.DA LIBBLKDEV
L.MSG.USAGE1	.DA MSG.USAGE1
L.MSG.USAGE2	.DA MSG.USAGE2
L.MSG.OK		.DA MSG.OK
L.MSG.ERR		.DA MSG.ERR
L.MSG.CRLF		.DA MSG.CRLF
L.MSG.NOSIZE	.DA MSG.NOSIZE
L.MSG.INIT		.DA MSG.INIT
L.MSG.LL		.DA MSG.LL
L.MSG.LLDISK2	.DA MSG.LLDISK2
L.MSG.VERIFY	.DA MSG.VERIFY
L.MSG.WRITECAT	.DA MSG.WRITECAT
L.FMT.BLANK		.DA FMT.BLANK
				.DA 0
*--------------------------------------
CS.INIT			>LDYA L.LIBBLKDEV
				>SYSCALL LoadLib
				bcs .9
				sta hLIBBLKDEV

.9				rts
*--------------------------------------
CS.RUN			ldy #S.PS.ARGC
				lda (pPS),y
				beq .99

.1				inc Index
				lda Index
				>SYSCALL ArgV
				bcc .11
				
				jmp .8

.11				>STYA ZPPtr1
				lda (ZPPtr1)
				cmp #'-'
				bne .4

				ldy #1 
				lda (ZPPtr1),y
				beq .99

				cmp #'0'
				bcc .2
				cmp #'9'+1
				bcs .2
				and #$0F
				sta CatSize
.10				bra .1

.2				jsr CS.RUN.CheckOpt
				bcs .99
				
				cpy #bCustomBlkSize
				bne .1
				
				inc Index
				lda Index
				>SYSCALL ArgV
				bcs .99
				
				>SYSCALL atoi
				>STYA BlkCnt
				bra .1
				
.99				>PUSHW L.MSG.USAGE1
				>PUSHBI 0
				>SYSCALL PrintF
				>PUSHW L.MSG.USAGE2
				>PUSHBI 0
				>SYSCALL PrintF
				lda #E.SYN
				sec
.9				rts			

.4				lda hDevID
				bne .5					Already have a dev...go get VolName

				>LDYA ZPPtr1
				>SYSCALL GetDevByName
				bcs .9

				stx hDevID
				>STYA ZPPtrFD
				
				>LDYA ZPPtr1
				>STYA ZPPtrDevName
				bra .10

.5				ldy #$ff

.6				iny
				lda (ZPPtr1),y
				sta (pData),y			VolName
				beq .10

				cpy #16
				bcc .6
				bra .99					VolName too long

.8				lda hDevID
				beq .99
*--------------------------------------
CS.RUN.Format	jsr CS.RUN.GetDevStatus
				bcs .99

				>PUSHW L.MSG.INIT
				>PUSHW ZPPtrDevName
				>PUSHEA.G VolName
				>PUSHBI 4
				>SYSCALL PrintF
				bcs .99

				jsr CS.RUN.GET.DSSS0000

				bit bLL
				bpl .1
				
				jsr CS.RUN.LL
				bcs .9

.1				jsr CS.RUN.InitCat
				bcs .9

				jsr CS.RUN.BuildCat
				bcs .9

				jsr CS.RUN.WriteCat
.99				bcs .9

				>LDYA L.MSG.OK
				>SYSCALL PutS

				bit bVerify
				bpl .8
				
				jsr CS.RUN.LL.DISKII.V
				bcs .9

.8				>PUSHB DSSS0000
				>PUSHW pData
				>SYSCALL Online
				bcs .9
				
				lda #0
				sec
				rts

.9				pha
				>PUSHW L.MSG.ERR
				pla
				pha
				>PUSHA
				>PUSHBI 1
				>SYSCALL PrintF
				pla
				sec
				rts
*--------------------------------------
CS.RUN.GetDevStatus
				lda bCustomBlkSize
				bmi .8
				
				>PUSHB hDevID
				>PUSHEA.G DIB
				
				>SYSCALL GetDevStatus
				bcs .9

				>LDA.G DIB+S.DIB.SIZE
				tax
				iny
				ora (pData),y
				beq .9
				
				lda (pData),y
				sta BlkCnt+1
				stx BlkCnt

.8				clc
				rts

.9				>LDYA L.MSG.NOSIZE
				>SYSCALL PutS
				lda #MLI.E.IO
				sec
				rts
*--------------------------------------
CS.RUN.GET.DSSS0000
				ldy #S.FD.DEV.BUSID
				lda (ZPPtrFD),y			00000SSS
				
				lsr
				ror
				ror
				ror
				pha						SSS00000
				
				iny 					S.FD.DEV.DEVID

				lda (ZPPtrFD),y
				dec						0/1
				ror						in C
				pla
				ror 
				sta DSSS0000

				rts
*--------------------------------------
CS.RUN.LL		>LDA.G DIB+S.DIB.T
				cmp #S.DIB.T.DISKII
				bne .1

				lda #0
				bit bExtraTrack
				bpl .10
				
				ora #8
				
.10				bit bHighDensity
				bpl .11
				
				ora #16
				
.11				tay		
				ldx #0

.12				lda Disk2.Default,y
				sta BlkCnt,x
				iny
				inx
				cpx #6
				bne .12
				
.1				>PUSHW L.MSG.LL
				>PUSHW BlkCnt
				>PUSHBI 2
				>SYSCALL PrintF
				bcs .9
				
				>LDA.G DIB+S.DIB.T
				cmp #S.DIB.T.DISKII
				beq CS.RUN.LL.DISKII
				
				>PUSHB hDevID
				>PUSHBI IOCTL.FORMAT
				>PUSHEA.G IOCTL
				
				>SYSCALL IOCTL
				
.9
CS.RUN.LL.RTS	rts
*--------------------------------------
CS.RUN.LL.DISKII
				>LDYAI 4096
				>SYSCALL GetMem
				bcs CS.RUN.LL.RTS

				stx hTrackBuf
				>STYA ZPPtr1
				
				jsr CS.RUN.MotorOn
				bcs CS.RUN.LL.RTS
				
				>SLEEP
				
				>PUSHB DSSS0000
				>LIBCALL hLIBBLKDEV,LIBBLKDEV.D2Recalibrate
				bcs CS.RUN.LL.RTS
				
				>SLEEP
				
				ldx #16
				jsr CS.RUN.ZeroPtr1		16 sectors filled with 0, give some time to spin up
				
				stz CurTrack
				
				lda TrkCnt
				sta Counter
				
				ldx #0
				
.1				jsr CS.RUN.SeekToX
				bcs .9

				>SLEEP

				>PUSHW L.MSG.LLDISK2
				>PUSHB CurTrack
				inc
				>PUSHA
				>PUSHB TrkCnt
				>PUSHBI 3
				>SYSCALL PrintF
				bcs .9

				>PUSHB DSSS0000
				>PUSHB VolNum
				>PUSHB CurTrack
				>PUSHW ZPPtr1
				>LIBCALL hLIBBLKDEV,LIBBLKDEV.D2TrkWrite16s
				bcs .9

				dec Counter
				beq .8
				
				inc CurTrack
				
				lda CurQTrack
*				clc
				adc Stepping

				tax
				
				bra .1

.9				pha
				jsr CS.RUN.MotorOff
				pla
				sec
				rts
				
.8				>PUSHW L.MSG.CRLF
				>PUSHBI 0
				>SYSCALL PrintF
				bcs .9
				
				bit bVerify
				bpl .80
				
				jsr CS.RUN.LL.DISKII.V
				bcs .9

.80				jmp CS.RUN.MotorOff
*--------------------------------------
CS.RUN.LL.DISKII.V
				>PUSHW L.MSG.VERIFY
				>PUSHBI 0
				>SYSCALL PrintF
				
				lda hTrackBuf
				>SYSCALL GetMemPtr
				>STYA.G IOCTL+S.IOCTL.BUFPTR

				>LDYA BlkCnt
				>STYA.G IOCTL+S.IOCTL.BLKNUM
				
				>STZ.G IOCTL+S.IOCTL.BLKNUM
				iny
				sta (pData),y
				
				stz CurTrack
				
				lda TrkCnt
				sta Counter

.1				ldx #8

.2				phx
				jsr CS.RUN.LL.DISKII.VP
				plx
				bcs .9
				
				phx
				jsr CS.RUN.LL.DISKII.VR
				plx
				bcs .9

				>INCW.G IOCTL+S.IOCTL.BLKNUM
				
				dex
				bne .2
				
				inc CurTrack
				dec Counter
				bne .1

				lda TrkCnt
				sta Counter

.3				ldx #8

				dec CurTrack

.4				>DECW.G IOCTL+S.IOCTL.BLKNUM
				
				phx
				jsr CS.RUN.LL.DISKII.VP
				plx
				bcs .9
				
				phx
				jsr CS.RUN.LL.DISKII.VR
				plx
				bcs .9

				dex
				bne .4
				
				dec Counter
				bne .3
				
				>PUSHW L.MSG.CRLF
				>PUSHBI 0
				>SYSCALL PrintF
				
.9				rts
*--------------------------------------
CS.RUN.LL.DISKII.VP
				>PUSHW L.MSG.VERIFY
				>PUSHB CurTrack
				>PUSHW.G IOCTL+S.IOCTL.BLKNUM
				>PUSHBI 3
				>SYSCALL PrintF
				rts
*--------------------------------------
CS.RUN.LL.DISKII.VR
				>PUSHB hDevID
				>PUSHBI IOCTL.READBLOCK
				>PUSHEA.G IOCTL
				>SYSCALL IOCTL
				bcc .8
				
				pha
				>PUSHW L.MSG.ERR
				pla

				>PUSHA
				>PUSHBI 1
				>SYSCALL PrintF
				
.8				rts
*--------------------------------------
CS.RUN.MotorOn	sec
				.HS 90					BCC
CS.RUN.MotorOff	clc
				>PUSHB DSSS0000
				ror
				>PUSHA
				>LIBCALL hLIBBLKDEV,LIBBLKDEV.D2MotorControl
				rts
*--------------------------------------
CS.RUN.SeekToX	>PUSHB DSSS0000
				>PUSHB CurQTrack
				txa
				sta CurQTrack
				>PUSHA
				>LIBCALL hLIBBLKDEV,LIBBLKDEV.D2MoveHead
				rts
*--------------------------------------
CS.RUN.ZeroPtr1	>LDYA ZPPtr1
				>STYA ZPPtr2
				
				lda #$AA
				tay
				
.10				sta (ZPPtr2),y
				iny
				bne .10
				
				inc ZPPtr2+1
				dex
				bne .10
				
				rts
*--------------------------------------
CS.RUN.InitCat	lda CatSize
				bne .1

				lda #4
				sta CatSize

.1				>LDA.G VolName
				bne .8					Volume name ok

				>PUSHEA.G VolName
				>PUSHW L.FMT.BLANK
				>PUSHW A2osX.TIMER16
				>PUSHW A2osX.RANDOM16
				>PUSHBI 4
				>SYSCALL sprintf
				rts

.8				clc
				rts
*--------------------------------------
CS.RUN.BuildCat	jsr .7

				>LIBCALL hLIBBLKDEV,LIBBLKDEV.GetProDOSCatSize			
				bcs .9

				stx CatBlkCnt

				>SYSCALL GetMem			BufferSize
				bcs .9

				>STYA ZPPtr1

				>STYA.G IOCTL+S.IOCTL.BUFPTR
				stx hCatBuf

				lda CatBlkCnt
				asl
				tax

				lda #0
				tay

.1				sta (ZPPtr1),y
				iny
				bne .1
				inc ZPPtr1+1
				dex
				bne .1

				jsr .7

				>PUSHEA.G VolName
				>PUSHW.G IOCTL+S.IOCTL.BUFPTR
				>LIBCALL hLIBBLKDEV,LIBBLKDEV.BuildProDOSCat
.9				rts

.7				>PUSHW BlkCnt
				>PUSHB CatSize
				>PUSHB AltBB
				rts
*--------------------------------------
CS.RUN.WriteCat	>PUSHW L.MSG.WRITECAT
				>PUSHBI 0
				>SYSCALL PrintF
				
				>STZ.G IOCTL+S.IOCTL.BLKNUM
				iny
				sta (pData),y

.1				>PUSHB hDevID
				>PUSHBI IOCTL.WRITEBLOCK
				>PUSHEA.G IOCTL
				
				>SYSCALL IOCTL
				bcs .9

				lda #'.'
				>SYSCALL PutChar
				bcs .9

				>LDA.G IOCTL+S.IOCTL.BUFPTR+1
				inc
				inc
				sta (pData),y
				>INC.G IOCTL+S.IOCTL.BLKNUM
				>SLEEP
				dec CatBlkCnt
				bne .1

				clc
.9				rts
*--------------------------------------
CS.DOEVENT		sec
				rts
*--------------------------------------
CS.QUIT			lda hCatBuf
				beq .1
				
				>SYSCALL FreeMem
				
.1				lda hTrackBuf
				beq .2
				
				>SYSCALL FreeMem
				
.2				lda hLIBBLKDEV
				beq .8
				
				>SYSCALL UnloadLib
.8				clc
				rts
*--------------------------------------
CS.RUN.CheckOpt	ldy #1 
				lda (ZPPtr1),y

				ldx #OptionVars-OptionList-1

.2				cmp OptionList,x
				beq .3
				dex
				bpl .2

				sec
				rts

.3				ldy OptionVars,x
				ldx #$ff
				stx 0,y
				clc
				rts
*--------------------------------------
CS.END
*--------------------------------------
LIBBLKDEV		.AZ "libblkdev"
hLIBBLKDEV		.BS 1
*--------------------------------------
MSG.USAGE1		.AS "Usage : FORMAT <BLOCKDEV> [VOL.NAME]\r\n"
				.AS "   -L : Low-Level Format\r\n"
				.AZ "   -H : 35trk drives, High Density: 47 tracks, 376 Blocks\r\n"
MSG.USAGE2		.AS "   -X : 40trk drives, 320 Blocks, combined with -H, 432 Blocks\r\n"
				.AS "   -V : Verify\r\n"
				.AS "   -B xxxx : Smrtprt, Override Device block size\r\n"
				.AZ " -1-9 : Catalog Size (Blocks)\r\n"
MSG.OK			.AZ "[OK]"
MSG.ERR			.AS "[%h]"
MSG.CRLF		.AZ "\r\n"
MSG.NOSIZE		.AZ "Unable to get media size."
MSG.INIT		.AZ "Formatting %s, Volname:%s\r\n"
MSG.LL			.AZ "Low Level Format %D Blks\r\n"
MSG.LLDISK2		.AZ "\rWriting Track %02d (%02d/%02d)..."
MSG.VERIFY		.AZ "\rVerifying Track %02d, Block %05D..."
MSG.WRITECAT	.AZ "Writing Catalog..."
FMT.BLANK		.AZ "BLANK%H%H"
*--------------------------------------
OptionList		.AS "LlBbHhXxVv"
OptionVars		.DA #bLL,#bLL,#bCustomBlkSize,#bCustomBlkSize
				.DA #bHighDensity,#bHighDensity,#bExtraTrack,#bExtraTrack
				.DA #bVerify,#bVerify
*--------------------------------------
Disk2.Default	.DA 280					BlkCnt
				.DA #35					TrkCnt
				.DA #4					Stepping
				.DA #1					VolNum
*				.DA #140				QTrkCnt
				.DA #0					AltBB
				.BS 2
*--------------------------------------
Disk2.X			.DA 320					BlkCnt
				.DA #40					TrkCnt
				.DA #4					Stepping
				.DA #2					VolNum
*				.DA #160				QTrkCnt
				.DA #0					AltBB
				.BS 2
*--------------------------------------
Disk2.H			.DA 376					BlkCnt
				.DA #47					TrkCnt
				.DA #3					Stepping
				.DA #129				VolNum
*				.DA #141				QTrkCnt
				.DA #$80				AltBB
				.BS 2
*--------------------------------------
Disk2.HX		.DA 432					BlkCnt
				.DA #54					TrkCnt
				.DA #3					Stepping
				.DA #130				VolNum
*				.DA #162				QTrkCnt
				.DA #$80				AltBB
				.BS 2
*--------------------------------------
				.DUMMY
				.OR 0
DS.START
VolName			.BS 16

IOCTL			.BS S.IOCTL
DIB				.BS S.DIB
DS.END			.ED
*--------------------------------------
MAN
SAVE usr/src/bin/format.s
ASM
