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/libblkdev.i
*--------------------------------------
				.DUMMY
				.OR ZPBIN
ZS.START
ZPPtr1			.BS 2
ZPPtrFD			.BS 2
ZPPtrDevName	.BS 2
hDevID			.BS 1
hCatBuf			.BS 1

ArgIndex		.BS 1
hTrackBuf		.BS 1
DSSS0000 		.BS 1
CurTrack		.BS 1
CurQTrack		.BS 1
TCounter		.BS 1
CurHead			.BS 1
HCounter		.BS 1

BlkCnt			.BS 2
TrkCnt			.BS 1
Stepping		.BS 1
VolNum			.BS 1
bAltBB			.BS 1
HeadCnt			.BS 1

CatSize			.BS 1
CatBlkCnt		.BS 1
bLL				.BS 1
bVerify			.BS 1
bCustomBlkSize	.BS 1

TimeOut			.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 #S.PS.F.EVENT
				.DA #0
				.DA CS.END-CS.START		Code Size (without Constants)
				.DA DS.END-DS.START		Data SegmentSize
				.DA #64					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
J.Opts			.DA CS.RUN.OptA
				.DA CS.RUN.OptB
				.DA CS.RUN.OptD
				.DA CS.RUN.OptL
				.DA CS.RUN.OptS
				.DA CS.RUN.OptT
				.DA CS.RUN.OptV
				.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

				ldx #6

.10				lda Disk2.Default,x
				sta BlkCnt,x
				dex
				bpl .10

.1				jsr CS.RUN.NextArg
				bcs .8

				>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
				bra .1

.2				jsr CS.RUN.CheckOpt
				bcs .99

				bra .1

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

				jsr CS.RUN.GetDev
				bcc .1
				
				rts

.5				jsr CS.RUN.GetVolName
				bcc .1
				
				rts

.99				>LDYA L.MSG.USAGE1
				>SYSCALL PutS
				>LDYA L.MSG.USAGE2
				>SYSCALL PutS

				lda #E.SYN
				sec
.9				rts

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

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

				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
				bcs .9

				>LDYA L.MSG.OK
				>SYSCALL PutS
				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.CheckOpt	ldy #1
				lda (ZPPtr1),y

				ldx #OptionList.Cnt-1

.2				cmp OptionList,x
				beq .3

				dex
				bpl .2

				sec
				rts

.3				txa
				and #$fe
				tax
				jmp (J.Opts,x)
*--------------------------------------
CS.RUN.OptA		sec
				ror	bAltBB

				clc
				rts
*--------------------------------------
CS.RUN.OptB		jsr CS.RUN.NextArg
				bcs .9

				>SYSCALL AToI
				>STYA BlkCnt

				sec
				ror bCustomBlkSize

				clc

.9				rts
*--------------------------------------
CS.RUN.OptD		lda #2
				sta HeadCnt

				lda #$80
				tsb VolNum

				clc
				rts
*--------------------------------------
CS.RUN.OptV		sec
				ror bVerify
*--------------------------------------
CS.RUN.OptL		sec
				ror	bLL

				clc
				rts
*--------------------------------------
CS.RUN.OptS		jsr CS.RUN.NextArg
				bcs .99

				>SYSCALL AToI
				tax
				bne .9
				
				tya
				beq .9
				
				cmp #5
				bcs .99
				
				sta Stepping
				cmp #4
				beq .8
				
				tsb VolNum
				
				sec
				ror bAltBB
	
.8				clc
				rts
	
.9				sec
	
.99				rts
*--------------------------------------
CS.RUN.OptT		jsr CS.RUN.NextArg
				bcs .99

				>SYSCALL AToI
				tax
				bne .9
				
				tya
				beq .9
				
				sta TrkCnt
				
				clc
				rts
				
.9				sec
	
.99				rts				
*--------------------------------------
CS.RUN.NextArg	inc ArgIndex
				lda ArgIndex
				>SYSCALL ArgV
				rts
*--------------------------------------		
CS.RUN.GetDev	>LDYA ZPPtr1
				>SYSCALL GetDevByName
				bcs .9

				stx hDevID
				>STYA ZPPtrFD

				>LDYA ZPPtr1
				>STYA ZPPtrDevName
				
.9				rts
*--------------------------------------
CS.RUN.GetVolName
				lda (pData)
				bne .9

				lda (ZPPtr1)
				jsr CS.RUN.IsL
				bcs .9

				sta (pData)				VolName

				ldy #0

.1				iny
				lda (ZPPtr1),y
				sta (pData),y
*				clc
				beq .8					\0
				
				jsr CS.RUN.IsDOrL
				bcs .9

				cpy #16
				bcc .1					VolName too long ?

.9				lda #E.SYN

				sec

.8				rts
*--------------------------------------
CS.RUN.GetDevDIB
				>LEA.G DIB
				>STYA.G IOCTL+S.IOCTL.BUFPTR

				lda #S.IOCTL.S.GETDIB
				>STA.G IOCTL+S.IOCTL.S

				>PUSHB hDevID
				>PUSHBI IOCTL.STATUS
				>PUSHEA.G IOCTL
				>SYSCALL IOCTL
				bcs .9

				lda bCustomBlkSize
				bmi .8

				>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		>PUSHW L.MSG.LL
				>PUSHW BlkCnt
				>PUSHBI 2
				>SYSCALL PrintF
				bcs .9

				>LDA.G DIB+S.DIB.T
				cmp #S.DIB.T.D2
				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
				jsr CS.RUN.MotorOn
				bcs CS.RUN.LL.RTS

				lda #20
				jsr CS.RUN.Wait
				bcs CS.RUN.LL.RTS

				>PUSHB DSSS0000
				>LIBCALL hLIBBLKDEV,LIBBLKDEV.D2Recalibrate

				lda #20
				jsr CS.RUN.Wait
				bcs CS.RUN.LL.RTS

				stz CurTrack
				stz CurQTrack

				lda TrkCnt
				sta TCounter

.1				lda HeadCnt
				sta HCounter

				stz CurHead

.2				jsr CS.RUN.CheckCtrlC
				bcs .9

				jsr CS.RUN.LL.DISKII.P
				bcs .9

				jsr CS.RUN.LL.DISKII.FT
				bcs .9

				inc CurTrack

				inc CurHead
				dec HCounter
				beq .3

				>PUSHB DSSS0000
				>PUSHBI 1
				>LIBCALL hLIBBLKDEV,LIBBLKDEV.D2HeadSelect
				bcs .9

				jsr CS.RUN.LL.DISKII.FT
				bcs .9

				>PUSHB DSSS0000
				>PUSHBI 0
				>LIBCALL hLIBBLKDEV,LIBBLKDEV.D2HeadSelect
				bcs .9

				inc CurTrack

.3				dec TCounter
				beq .8

				lda CurQTrack
*				clc
				adc Stepping
				tax

				jsr CS.RUN.SeekToX
				jmp .1

.9				pha
				jsr CS.RUN.MotorOff
				pla
				sec
.99				rts

.8				ldx #0
				jsr CS.RUN.SeekToX
				
				>PUSHW L.MSG.CRLF
				>PUSHBI 0
				>SYSCALL PrintF
				bcs .9

				jsr CS.RUN.CheckCtrlC
				bcs .9
				
				bit bVerify
				bpl .80

				jsr CS.RUN.LL.DISKII.V
				bcs .99

.80				rts
*--------------------------------------
CS.RUN.LL.DISKII.P
				>PUSHW L.MSG.LLDISK2
				>PUSHB CurHead
				>PUSHB CurTrack
				inc
				>PUSHA
				>PUSHB TrkCnt
				>PUSHBI 4
				>SYSCALL PrintF
				rts
*--------------------------------------
CS.RUN.LL.DISKII.FT
				>PUSHB DSSS0000
				>PUSHB VolNum
				>PUSHB CurTrack
				>LIBCALL hLIBBLKDEV,LIBBLKDEV.D2TrkFmt16s
				rts
*--------------------------------------
CS.RUN.LL.DISKII.V
				lda hTrackBuf
				bne .10

				>LDYAI 512
				>SYSCALL GetMem
				bcs .99

				stx hTrackBuf
				bra .11

.10				>SYSCALL GetMemPtr
.11				>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 TCounter

.12				lda HeadCnt
				sta HCounter

				stz CurHead

.1				ldx #0

.2				jsr CS.RUN.CheckCtrlC
				bcs .9

				jsr CS.RUN.LL.DISKII.VBLK
.99				bcs .9

				>INCW.G IOCTL+S.IOCTL.BLKNUM

				inx
				cpx #8
				bne .2

				inc CurHead
				dec HCounter
				bne .1

				inc CurTrack
				dec TCounter
				bne .12

				lda TrkCnt
				sta TCounter

.13				lda HeadCnt
				sta HCounter

				stz CurHead

.3				ldx #7

				dec CurTrack

.4				jsr CS.RUN.CheckCtrlC
				bcs .9

				>DECW.G IOCTL+S.IOCTL.BLKNUM

				jsr CS.RUN.LL.DISKII.VBLK
				bcs .9

				dex
				bpl .4

				inc CurHead
				dec HCounter
				bne .3
				
				dec TCounter
				bne .13

				>LDYA L.MSG.OK
				>SYSCALL PutS

.9				rts
*--------------------------------------
CS.RUN.LL.DISKII.VBLK
				phx
				>PUSHW L.MSG.VERIFY
				>PUSHB CurHead
				>PUSHB CurTrack
				pla
				pha
				>PUSHA

				>PUSHW.G IOCTL+S.IOCTL.BLKNUM
				>PUSHBI 5
				>SYSCALL PrintF

				>PUSHB hDevID
				>PUSHBI IOCTL.READBLOCK
				>PUSHEA.G IOCTL
				>SYSCALL IOCTL
				bcc .8

				pha
				>PUSHW L.MSG.ERR
				pla

				>PUSHA
				>PUSHBI 1
				>SYSCALL PrintF

.8				plx
				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	lda ZPPtr1+1
				pha

				lda #0
				tay

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

				inc ZPPtr1+1
				dex
				bne .1

				pla
				sta ZPPtr1+1

				rts
*--------------------------------------
CS.RUN.InitCat	lda CatSize
				bne .1

				lda #4
				sta CatSize

.1				lda (pData)				>LDA.G VolName
				bne .8					Volume name ok

				>PUSHW pData			>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

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

.7				>PUSHW BlkCnt
				>PUSHB CatSize
				>PUSHB bAltBB
				rts
*--------------------------------------
CS.RUN.WriteCat	>PUSHW L.MSG.WRITECAT
				>PUSHBI 0
				>SYSCALL PrintF
				bcs .9

				>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		lda (pEvent)
				bpl .9					is it a TIMER event?

				lda TimeOut
				beq .9

				dec TimeOut
.9				sec						do not discard TIMER event
				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.Wait		sta TimeOut

.1				jsr CS.RUN.CheckCtrlC
				bcs .9
				
				lda TimeOut
				bne .1
				
.9				rts				
*--------------------------------------
CS.RUN.CheckCtrlC
				phx
				phy

				>SLEEP

				ldy #S.PS.hStdIn
				lda (pPS),y
				>SYSCALL FEOF
				bcs .9
				tay
				bne .9					CC

				>SYSCALL GetChar
				bcs .9

				cmp #$03				Ctrl-C
				beq .9					CS

				clc

.9				ply
				plx
				rts
*--------------------------------------
CS.RUN.IsDOrL	cmp #'0'
				bcc CS.RUN.IsL
				
				cmp #'9'+1
				bcc CS.RUN.IsL.RTS

CS.RUN.IsL		cmp #'_'
				clc
				beq CS.RUN.IsL.RTS
				
				cmp #'.'
				clc
				beq CS.RUN.IsL.RTS
				
				cmp #'A'
				bcc CS.RUN.IsL.9
				
				cmp #'Z'+1
				bcc CS.RUN.IsL.RTS
				
				cmp #'a'
				bcc CS.RUN.IsL.9

				cmp #'z'+1

CS.RUN.IsL.RTS	rts

CS.RUN.IsL.9	sec
				rts
*--------------------------------------
CS.END
*--------------------------------------
LIBBLKDEV		.AZ "libblkdev"
hLIBBLKDEV		.BS 1
*--------------------------------------
MSG.USAGE1		.CS "Usage : FORMAT <BLOCKDEV> [VOL.NAME]\r\n"
				.CS "   -L : Low-Level Format\r\n"
				.CS "   -V : Verify After LLF\r\n"
				.CS "   -B xxxx : Volume size (blocks)\r\n"
				.CZ " -1-9 : Catalog Size (blocks)"
MSG.USAGE2		.CS "------- ProDOS.FX only ------\r\n"
				.CS "   -A : Alternate boot block\r\n"
				.CS "   -D : Dual sided\r\n"
				.CS "   -S x : Quarter track stepping\r\n"
				.CZ "   -T xxx : Track count\r\n"
*--------------------------------------
MSG.OK			.CZ "[OK]"
MSG.ERR			.CS "[%h]"
MSG.CRLF		.CZ "\r\n"
MSG.NOSIZE		.CZ "Unable to get media size."
MSG.INIT		.CZ "Formatting %s, Volname:%s\r\n"
MSG.LL			.CZ "Low Level Format %D Blks\r\n"
MSG.LLDISK2		.CZ "\rWriting Head %d/Track %02d (%02d/%02d)..."
MSG.VERIFY		.CZ "\rVerifying Head %d/Track %02d/Block %d (%05D)..."
MSG.WRITECAT	.CZ "Writing Catalog..."
FMT.BLANK		.CZ "BLANK%H%H"
*--------------------------------------
OptionList		.AS "AaBbDdLlSsTtVv"
OptionList.cnt	.EQ *-OptionList
*--------------------------------------
Disk2.Default	.DA 280					BlkCnt
				.DA #35					TrkCnt
				.DA #4					Stepping
				.DA #$00				VolNum
				.DA #0					bAltBB
				.DA #1					HeadCnt
*--------------------------------------
				.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
