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
AltBB			.BS 1
HeadCnt			.BS 1

TimeOut			.BS 1
				
CatSize			.BS 1
CatBlkCnt		.BS 1
bLL				.BS 1
bCustomBlkSize 	.BS 1
bHighDensity	.BS 1
bExtraTrack		.BS 1
bDS				.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 #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
				.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 ArgIndex
				lda ArgIndex
				>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 ArgIndex
				lda ArgIndex
				>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
				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				bit bDS
				bpl .12
				
				ora #32

.12				tay
				ldx #0

.13				lda Disk2.Default,y
				sta BlkCnt,x
				iny
				inx
				cpx #7
				bne .13

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

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

				>PUSHB DSSS0000
				>PUSHB VolNum
				>PUSHB CurHead
				>PUSHB CurTrack
				>PUSHWI 0				Empty track
				>LIBCALL hLIBBLKDEV,LIBBLKDEV.D2TrkWrite16s
				bcs .9

				inc CurHead
				dec HCounter
				bne .2

				dec TCounter
				beq .8

				inc CurTrack

				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
				
*				jsr CS.RUN.MotorOn

*				lda #20
*				jsr CS.RUN.Wait

.80
*				>PUSHB DSSS0000
*				>LIBCALL hLIBBLKDEV,LIBBLKDEV.D2Recalibrate

*				lda #20
*				jsr CS.RUN.Wait

				clc
				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.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		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.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.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.END
*--------------------------------------
LIBBLKDEV		.AZ "libblkdev"
hLIBBLKDEV		.BS 1
*--------------------------------------
MSG.USAGE1		.AS "Usage : FORMAT <BLOCKDEV> [VOL.NAME]\r\n"
				.AS "   -L : Low-Level Format\r\n"
				.AS "-L -V : Verify After LLF\r\n"
				.AS "   -B xxxx : Smrtprt, Override Device block size\r\n"
				.AZ " -1-9 : Catalog Size (Blocks)\r\n"
MSG.USAGE2		.AS "------- ProDOS.FX only ------\r\n"
				.AS "   -H : 35trk drives, High Density: 48 tracks, 384 Blocks\r\n"
				.AS "   -X : 40trk drives, 320 Blocks\r\n"
				.AS "-H -X : 40trk drives, 432 Blocks\r\n"
				.AS "   -D : Rana Elite II 640 Blocks, 2 Sides\r\n"
				.AZ "-H -D : Rana Elite III 1280 Blocks, 2 Sides\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 Head %d/Track %02d (%02d/%02d)..."
MSG.VERIFY		.AZ "\rVerifying Head %d/Track %02d/Block %d (%05D)..."
MSG.WRITECAT	.AZ "Writing Catalog..."
FMT.BLANK		.AZ "BLANK%H%H"
*--------------------------------------
OptionList		.AS "LlBbHhXxDdVv"
OptionVars		.DA #bLL,#bLL,#bCustomBlkSize,#bCustomBlkSize
				.DA #bHighDensity,#bHighDensity,#bExtraTrack,#bExtraTrack
				.DA #bDS,#bDS
				.DA #bVerify,#bVerify
*--------------------------------------
Disk2.Default	.DA 280					BlkCnt
				.DA #35					TrkCnt
				.DA #4					Stepping
				.DA #1					VolNum
				.DA #0					AltBB
				.DA #1					HeadCnt
				.BS 1
*--------------------------------------
Disk2.X			.DA 320					BlkCnt
				.DA #40					TrkCnt
				.DA #4					Stepping
				.DA #2					VolNum
				.DA #0					AltBB
				.DA #1					HeadCnt
				.BS 1
*--------------------------------------
Disk2.H			.DA 384					BlkCnt
				.DA #48					TrkCnt
				.DA #3					Stepping
				.DA #129				VolNum
				.DA #$80				AltBB
				.DA #1					HeadCnt
				.BS 1
*--------------------------------------
Disk2.HX		.DA 432					BlkCnt
				.DA #54					TrkCnt
				.DA #3					Stepping
				.DA #130				VolNum
				.DA #$80				AltBB
				.DA #1					HeadCnt
				.BS 1
*--------------------------------------	RANA Elite 2
Disk2.DefaultD	.DA 640					BlkCnt
				.DA #40					TrkCnt
				.DA #4					Stepping
				.DA #192				VolNum
				.DA #$80				AltBB
				.DA #2					HeadCnt
				.BS 1
*--------------------------------------
Disk2.XD		.DA 640					BlkCnt
				.DA #40					TrkCnt
				.DA #4					Stepping
				.DA #192				VolNum
				.DA #$80				AltBB
				.DA #2					HeadCnt
				.BS 1
*-------------------------------------- RANA Elite 3
Disk2.HD		.DA 1280				BlkCnt
				.DA #80					TrkCnt
				.DA #2					Stepping
				.DA #193				VolNum
				.DA #$80				AltBB
				.DA #2					HeadCnt
				.BS 1
*--------------------------------------
Disk2.HXD		.DA 1280				BlkCnt
				.DA #80					TrkCnt
				.DA #2					Stepping
				.DA #193				VolNum
				.DA #$80				AltBB
				.DA #2					HeadCnt
				.BS 1
*--------------------------------------
				.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
