.ADFFS_Title
.ADFFS_SWI_Names
 DCB "ADFFS", 0			;SWI suffix

 DCB "Info", 0			;0
 DCB "Mount", 0			;1
 DCB "Save", 0			;2
 DCB "BootOnWIMPShutdown", 0	;3
 DCB "VIDCCR", 0		;4
 DCB "DoNothing", 0		;5
 DCB "KeyDebounce", 0		;6
 DCB "DiscOp", 0		;7
 DCB "MiscOp", 0		;8
 DCB "Action", 0		;9
 #if compile_RO > 311
   DCB "Module", 0		;10
 #else
   DCB "10", 0
 #endif
 DCB "Wait", 0			;11
 #if compile_RO > 311
   DCB "ShutdownThisTask", 0	;12
 #endif
 DCB 0
 ALIGN


.ADFFS_SWI
 CMP     R11, #(_SWI_jump_table_end - _SWI_jump_table - 4) / 4
 LDR     R12, [R12, #0]			;get our VARS address
 ADDLS   PC, PC, R11, LSL #2
B       ADFFS_SWI_exit

 ._SWI_jump_table
 B       swi_ADFFS_Info			;0
 B       Entry_ADFMount			;1
 B       Entry_ADFSave			;2
 B       swi_ADFFS_BootOnWIMPShutdown	;3
 B       swi_ADFFS_VIDCCR		;4
 B       ADFFS_SWI_exit			;5 ADFFS_DoNothing
 B       swi_ADFFS_KeyDebounce		;6 pauses until all keys are released
 B       swi_ADFFS_DiscOp		;7
 B       swi_ADFFS_MiscOp		;8
 B       swi_ADFFS_Action		;9
 #if compile_RO > 311
   B       swi_ADFFS_Module		;10
 #else
   B       ADFFS_SWI_exit		;10
 #endif
 B       swi_ADFFS_Wait			;11
 #if compile_RO > 311
   B       swi_ADFFS_ShutdownThisTask	;12
 #endif
 ._SWI_jump_table_end




;swi_ADFFS_Action
;----------------
;Allocate memory for the floppy buffer

.swi_ADFFS_Action
 CMP     R0, #(_ADFFS_Action_jump_table_end - _ADFFS_Action_jump_table - 4) / 4
 ADDLS   PC, PC, R0, LSL #2
B       ADFFS_SWI_exit

._ADFFS_Action_jump_table
 B       ADFFS_Action_0			;allocate buffer (ie DA size)
 B       ADFFS_Action_1			;mark mounted/unmounted
 B       ZIP_extract			;extract a file
 B       ADFFS_Action_3			;suspend/resume adding missing sectors
._ADFFS_Action_jump_table_end


.ADFFS_Action_0				;allocate buffer
 STMFD   R13!, {R4, R14}
 MOV     R4, R1
 BL      MemAlloc
 LDMFD   R13!, {R4, R14}
B       ADFFS_SWI_exit


.ADFFS_Action_1				;mark mounted/unmounted
 STRB    R1, [R12, #Type_Mounted - VARS]
B       ADFFS_SWI_exit


.ADFFS_Action_3				;suspend/resume adding missing sectors
 STRB    R1, [R12, #suspend_adding_sectors - VARS]
B       ADFFS_SWI_exit




;swi_ADFFS_MiscOp
;----------------
;Temporarily unmounts an image and performs a MiscOp

.swi_ADFFS_MiscOp
 STMFD   R13!, {R7, R14}
 LDRB    R7, [R12, #Type_Mounted - VARS]
 MOV     R14, #Type_None
 STRB    R14, [R12, #Type_Mounted - VARS]

 SWI     XADFS_MiscOp
 STRB    R7, [R12, #Type_Mounted - VARS]
 LDMFD   R13!, {R7, R14}
B       ADFFS_SWI_exit




;swi_ADFFS_DiscOp
;----------------
;Temporarily unmounts an image and performs a DiscOp

.swi_ADFFS_DiscOp
 STMFD   R13!, {R0, R7, R8, R14}
 LDRB    R7, [R12, #Type_Mounted - VARS]
 MOV     R14, #Type_None
 STRB    R14, [R12, #Type_Mounted - VARS]

 AND     R8, R1, #%1111			;get command
 TEQ     R8, #1				;read data?
 BNE     _dont_blank			;NO
 BIC     R4, R4, #3			;ensure size is word aligned
 SUB     R0, R4, #4			;blank the memory range
 ._L1
   STR     R14, [R3, R0]
   SUBS    R0, R0, #4
 BPL     _L1

 ._dont_blank
 LDR     R0, [R13], #4
 SWI     XADFS_DiscOp
 STRB    R7, [R12, #Type_Mounted - VARS]
 LDMFD   R13!, {R7, R8, R14}
B       ADFFS_SWI_exit




;ADFFS_KeyDebounce
;-----------------
;Pauses until all keys and mouse buttons are released

.swi_ADFFS_KeyDebounce
 STMFD   R13!, {R0-R2, R14}
 ._L1
   MOV     R0, #121			;PRM1-892
   MOV     R1, #0
   SWI     XOS_Byte
   TEQ     R1, #255			;all keys released?
   LDMEQFD R13!, {R0-R2, R14}		;YES
   BEQ     ADFFS_SWI_exit		; |+ exit

   MOV     R0, #19
   SWI     XOS_Byte			;pause
 B       _L1




;ADFFS_BootOnWIMPShutdown
;------------------------
;Triggers a floppy boot to happen after the WIMP shuts down

.swi_ADFFS_BootOnWIMPShutdown
 STRB    R11, [R12, #BootFloppyRequested - VARS]

.ADFFS_SWI_exit
#if compile_RO <= 400
  MOVS    PC, R14
#else
  MOV     PC, R14
#endif




;ADFFS_VIDCCR
;------------
;Returns the current VIDC1 CR

.swi_ADFFS_VIDCCR
#if compile_RO == 311
  MOV     R0, #0
#endif
#if compile_RO > 311
  LDR     R0, [R12, #VIDC1_CR - VARS]
#endif
B      ADFFS_SWI_exit




;ADFFS_Info
;----------
;Returns information about the state of ADFFS

.swi_ADFFS_Info
 CMP     R0, #(_ADFFS_Info_jump_table_end - _ADFFS_Info_jump_table - 4) / 4
 ADDLS   PC, PC, R0, LSL #2
B       ADFFS_SWI_exit

 ._ADFFS_Info_jump_table
 B       ADFFS_Info_0			;size of buffer (ie DA size)
 B       ADFFS_Info_1			;size of data in buffer
 B       ADFFS_Info_2			;floppy mounted
 B       ADFFS_Info_3			;mounted file
 B       ADFFS_Info_4			;file type
 B       ADFFS_Info_5			;floppy format
 B       ADFFS_Info_6			;JFD header
 B       ADFFS_Info_7			;OS version
 B       ADFFS_Info_8			;VIDC1 to 20 translation enabled
 B       ADFFS_Info_9			;bit flags
 B       ADFFS_Info_10			;R0=0 if a physical floppy exists
 ._ADFFS_Info_jump_table_end

;R0 = total memory used by ADFFS in it's DA
;R1 = address of buffer
.ADFFS_Info_0				;0=Memory in use
 LDR     R0, [R12, #DA_size - VARS]
 LDR     R1, [R12, #ADF_Buffer_Address - VARS]
B       ADFFS_SWI_exit


;R0 = size of data in buffer
.ADFFS_Info_1				;1=Minimum size allowed
 LDR     R0, [R12, #ADF_Buffer_Length - VARS]
B       ADFFS_SWI_exit


;R0 <> 0 if a floppy is mounted
.ADFFS_Info_2				;2=Floppy mounted if <> 0
 LDRB    R0, [R12, #Type_Mounted - VARS]
B       ADFFS_SWI_exit


;R0 = pointer to filename of mounted disc
.ADFFS_Info_3				;3=Mounted filename
 LDR     R0, [R12, #Current_File_Mounted - VARS]
B       ADFFS_SWI_exit


; R0 = pointer to file type: ADF, JFD, APD, HFEv1/2/3 
.ADFFS_Info_4				;4=Filetype loaded
 ADD     R0, R12, #FileType_Loaded - VARS
B       ADFFS_SWI_exit


; R0 = Disc type: 0 - none, 1 - L, 2 - D, 3 - E, 4 - F, 5 - DOS 1440K
;		: 6 - DOS 720K, 7 - Atari 720K, 8 - Atari 360K
.ADFFS_Info_5				;5=Disc format
 STMFD   R13!, {R1, R14}
 LDRB    R0, [R12, #Type_Mounted - VARS]
 MOV     R1, #ASC("?")
 TEQ     R0, #0
 BLNE    Identify_Disc

 MOV     R0, #0
 TEQ     R1, #ASC("L")
 MOVEQ   R0, #1
 TEQ     R1, #ASC("D")
 MOVEQ   R0, #2
 TEQ     R1, #ASC("E")
 MOVEQ   R0, #3
 TEQ     R1, #ASC("F")
 MOVEQ   R0, #4
 TEQ     R1, #ASC("0")
 MOVEQ   R0, #5
 TEQ     R1, #ASC("1")
 MOVEQ   R0, #6
 TEQ     R1, #ASC("7")
 MOVEQ   R0, #7
 TEQ     R1, #ASC("8")
 MOVEQ   R0, #8

 LDMFD   R13!, {R1, R14}		;clear down stack
B       ADFFS_SWI_exit


; R0 = pointer to JFD header or 0 for ADF or APD
.ADFFS_Info_6				;6=JFD header
 LDRB    R0, [R12, #Type_Mounted - VARS]
 TEQ     R0, #3				;JFD mounted?
 MOVNE   R0, #0				;NO
 ADDEQ   R0, R12, #JFD_tmp - VARS	;YES
B       ADFFS_SWI_exit


.ADFFS_Info_7				;7=OS version
 LDR     R0, [R12, #os_version - VARS]
B       ADFFS_SWI_exit


.ADFFS_Info_8				;8=VIDC1 translation enabled
#if compile_RO == 311
 MOV     R0, #0
#else
 LDRB    R0, [R12, #is_screen_remapped - VARS]	;R0=0 if disabled
#endif
B       ADFFS_SWI_exit


.ADFFS_Info_9				;9=bit flags
LDR     R0, [R12, #JFD_tmp - VARS + JFD_Bit_Flags]
B       ADFFS_SWI_exit


.ADFFS_Info_10
LDRB    R0, [R12, #No_Floppy_Support - VARS]
B       ADFFS_SWI_exit




;ADFFS_Wait
;----------
;Pause for n ms
;
;Entry:
; R0 - ms to wait

.swi_ADFFS_Wait
 STMFD   R13!, {R0-R1, R14}

 MOV     R1, R0
 SWI     XOS_ReadMonotonicTime
 ADD     R1, R1, R0
 ._L1
   SWI     XOS_ReadMonotonicTime
   CMP     R0, R1
 BLO     _L1
 LDMFD   R13!, {R0-R1, R14}
B       ADFFS_SWI_exit


#if compile_RO > 311
;ADFFS_Module
;------------
;Allows BASIC26 to bypass the hypervised OS_Module

.swi_ADFFS_Module
 STMFD   R13!, {R14}
 SWI     XOS_Module
 LDMFD   R13!, {R14}
B       ADFFS_SWI_exit




;ADFFS_ShutdownThisTask
;----------------------
;cleans up when a task abnormally terminates

;Exit:
; all registers corrupt
; stack may be collapsed

.swi_ADFFS_ShutdownThisTask
 MOV     R2, R14
 BL      check_JIT_and_taskID		;is the task supported?
 BNE     _exit				;NO
 MOV     R1, #0				;shutdown JIT
 BL      Entry_GOARM3JIT
 MOV     R1, #0
 BL      Entry_ADFRemapVideoMemory
 ._exit
 MOV     R14, R2
B       ADFFS_SWI_exit
#endif
