;*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, #0
 STR     R4, [R12, #ADF_Mounted - VARS]	;ADF no longer mounted
 STRB    R4, [R12, #Current_File_Mounted - VARS]
 STR     R4, [R12, #FileType_Loaded - VARS]

 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
 LDR     R0, _A5A5A5A5			;floppies get formatted with A5
 ._MFM_erase
   SUBS    R4, R4, #4
   STR     R0, [R2, R4]
 BNE     _MFM_erase

 STR     R1, [R12, #Format_In_Progress - VARS]	;notify MiscOp 0 that a format is in progress
 ADR     R2, Floppy_Title		;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, #1
 STR     R2, [R12, #ADF_Mounted - VARS]	;mark ADF FS as being mounted
 STR     R2, [R12, #ADF_Changed - VARS]	;..and changed
 LDR     R2, _FileType_ADF		;set type as ADF
 STR     R2, [R12, #FileType_Loaded - VARS]

					;*****************************************
 ADR     R0, Format_Requested		;request the parameters to format the disc
 MOV     R1, #Service_IdentifyFormat	;PRM2-281
 SWI     XOS_ServiceCall		;PRM1-254
 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
 ADR     R2, Floppy_Title		;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
 STR     R2, [R12, #ADF_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
 ADR     R2, ADFFS_Current_DiscName
 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

 ._date_format_string			;format of the date string
 DCB    "%W3_%DY_%YR", 0		;PRM1-412
 ALIGN

 ._DateTitle				;no disc name, so create one using date
 MOV     R4, R1				;store R1 for return
 ADR     R1, date_5byte_format		;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
 LDRVC   R2, _FileType_ADF		;set type as ADF
 STRVC   R2, [R12, #FileType_Loaded - VARS]
 MOV     R2, #0
 STR     R2, [R12, #Format_In_Progress - VARS]	;MiscOp 0 needs to resume normal disc detection
LDMFD   R13!, {R1-R11, PC}

 ._A5A5A5A5	DCD &A5A5A5A5
 ._FileType_ADF	DCB "ADF", 0
