;*Format
;Format the ADF as a blank floppy
;Entry:
; R0 = pointer to command tail
; R1 = no. of parameters
; R12 = ADFS private word

.Entry_Format
 STMFD   R13!, {R1-R11, R14}
 ADR     R12, VARS

 MOV     R10, R0			;preserve command tail
 MOV     R11, R1			;preserve no. of parameters

 BL      Entry_ADFEject			;Dismount current disc

 CMP     R11, #1			;is <format> specified?
 MOVEQ   R2, #ASC("E")			;NO, presume E
 STREQB  R2, [R12, #Format_Requested - VARS]	; |  store for "OS_ServiceCall" later
 ADREQ   R1, Disc_Record_E		; |
 BEQ     _P1				; |+ and skip optional parameters

 MOV     R0, #10 + (%101 << 29)		;set max value
 MOV     R2, #0				;...as drive 0
 MOV     R1, R10			;command tail
 SWI     XOS_ReadUnsigned		;read the drive PRM1-460
 LDMVSFD R13!, {R1-R11, PC}		;exit on error
 ADD     R10, R1, #1			;new command tail

 ._L3
   LDRB    R2, [R10], #1		;read character
   TEQ     R2, #ASC(" ")		;is it SPACE?
 BEQ     _L3				;YES, loop

 BIC     R2, R2, #%00100000		;convert to uppercase
 STRB    R2, [R12, #Format_Requested - VARS]	;store for "OS_ServiceCall" later

 TEQ     R2, #ASC("F")
 ADREQ   R1, Disc_Record_F		;F - 1.6MB floppy, new map
 BEQ     _P1

 TEQ     R2, #ASC("E")
 ADREQ   R1, Disc_Record_E		;E - 800KB floppy, new map
 BEQ     _P1

 TEQ     R2, #ASC("D")
 ADREQ   R1, Disc_Record_D		;D - 800KB floppy, old map
 BEQ     _P1

 TEQ     R2, #ASC("L")
 ADREQ   R1, Disc_Record_L		;L - 640KB floppy, old map
 BEQ     _P1

 MOV     R0, #&80000000			;set V
 ADDS    R0, R0, R0			;  |
 ADR     R0, Error_Format_Unknown	;  |
 B       _exit				;  +- exit and generate error

 ._P1
 MOV     R4, #Type_None
 STRB    R4, [R12, #Type_Mounted - VARS]	;no longer mounted
 BL      release_filename_current

 LDR     R4, [R1, #16]			;how much memory do we need?
 BL      MemAlloc			;allocate memory
 BVS     _exit				;exit if MemAlloc fails

 LDR     R2, [R12, #DA_address - VARS]	;our buffer
 STR     R2, [R12, #ADF_Buffer_Address - VARS]
 LDR     R0, _A5A5A5A5			;floppies get formatted with A5
 ._MFM_erase
   SUBS    R4, R4, #4
   STR     R0, [R2, R4]
 BNE     _MFM_erase

 STRB    R1, [R12, #Format_In_Progress - VARS]	;notify MiscOp 0 that a format is in progress
 ADD     R2, R12, #Floppy_Title - VARS		;pointer to store disc name

 CMP     R11, #3			;does the command line include a disc name
 BLO     _DateTitle			;no, work out a date title

 ._L1
   LDRB    R3, [R10], #1		;load one byte from command line
   TEQ     R3, #ASC(" ")		;is it a space?
 BEQ     _L1				;YES, loop

 MOV     R4, #10			;max length of disc name
 ._L2					;check the floppy name is valid
   CMP     R3, #ASC("@")		;check if its an invalid char
   CMPNE   R3, #ASC("#")
   CMPNE   R3, #ASC("$")
   CMPNE   R3, #ASC("%")
   CMPNE   R3, #ASC("^")
   CMPNE   R3, #ASC("&")
   CMPNE   R3, #ASC("*")
   CMPNE   R3, #ASC("\")
   CMPNE   R3, #ASC(":")
   CMPNE   R3, #ASC("""")
   CMPNE   R3, #ASC(".")
   BEQ     _DiscName_Error		;report an error if an invalid character
   TEQ     R3, #13			;see if we've hit the end of the command line
   MOVEQ   R3, #0			;terminate disc name
   STRB    R3, [R2], #1			;store byte in disc sig
   BEQ     _L2_exit			;exit loop if we've hit a CR

   SUBS    R4, R4, #1			;check if we've hit the 10 character limit
   LDRNEB  R3, [R10], #1		;copy one byte from command line
 BNE _L2				;loop if not

 ._L2_exit
 MOV     R2, #Type_ADF
 BL      floppy_type_changed
					;*****************************************
 ADD     R0, R12, #Format_Requested - VARS	;request the parameters to format the disc
 MOV     R1, #Service_IdentifyFormat	;PRM2-281
 SWI     XOS_ServiceCall		;PRM1-254 returns SWI to call in R4
 BVS     _exit				;exit on error

 MOV     R0, #&CF			;open disc as a file, ready to layout structure
 ADR     R1, ADFFS_Filer_Name		;our disc name
 SWI     XOS_Find			;PRM2-78
 BVS     _exit				;exit on error

 MOV     R3, R0				;file handle of disc, now put structure on it
 MOV     R0, R5				;R5 is pointer to disc sig,
					;.. from OS_ServiceCall above
 ADR     R1, _Format_Bad_Blocks		;blank bad block list
 ADD     R2, R12, #Floppy_Title - VARS	;disc name
 MOV     R10, R4			;indirectly call XFileCore_LayoutStructure (in R4)
 SWI     XOS_CallASWI			;see URL below for documentation:
 ;www.riscopen.org/wiki/documentation/show/OS_CallASWI

 MOV     R0, #0				;close the disc
 MOV     R1, R3				;file handle
 SWI     XOS_Find			;PRM2-78
 BVS     _exit				;exit on error
					;*****************************************

 MOV     R2, #1				;mark ADF FS as having changed, post format
 STRB    R2, [R12, #Floppy_Changed - VARS]	;...to avoid FileCore read errors

 MOV     R0, #37			;Get the disc name (needed for filer window)
 ADR     R1, ADFFS_Filer_Name		;...using convert path to canonicalised name
 ADD     R2, R12, #ADFFS_Current_DiscName - VARS
 MOV     R3, #0
 MOV     R4, #0
 MOV     R5, #32
 SWI     XOS_FSControl			;PRM2-117
 MOVVS   R5, #32			;if there's an error, blank the disc name

 CMP     R5, #0
 MOVMI   R5, #32			;if the disc name is too long, blank it

 RSB     R5, R5, #32
 MOV     R0, #0
 STRB    R0, [R2, R5]			;terminate the discname

 SUBS    R0, R0, R0			;clear V
B       _exit


 ._DateTitle				;no disc name, so create one using date
 MOV     R4, R1				;store R1 for return
 ADD     R1, R12, #date_5byte_format - VARS	;buffer to read the time
 MOV     R0, #3
 STRB    R0, [R1]
 MOV     R0, #14			;OS_Word 14,3
 SWI     XOS_Word			;PRM3-439
 BVS     _exit				;exit on error

 MOV     R0, R1				;pointer to 5 byte time
 MOV     R1, R2				;buffer for resulting string
 MOV     R2, #10			;length
 ADR     R3, _date_format_string	;format of date
 SWI     XOS_ConvertDateAndTime		;PRM1-459
 BVS     _exit				;exit on error

 MOV     R1, R4				;restore R1
B       _L2_exit



 ._DiscName_Error
 MOV     R0, #&80000000			;set V
 ADDS    R0, R0, R0			;  |
 ADR     R0, Error_Format_DiscName	;  |
					;  +- exit and generate error
 ._exit
 MOV     R2, #0
 STRB    R2, [R12, #Format_In_Progress - VARS]	;MiscOp 0 needs to resume normal disc detection
LDMFD   R13!, {R1-R11, PC}



 ._A5A5A5A5		DCD &A5A5A5A5
 ._Format_Bad_Blocks	DCD -1		;blank bad block list
 ._date_format_string			;format of the date string
 DCB    "%W3_%DY_%YR", 0		;PRM1-412
 ALIGN
