#set Icon_Shaded = 1<<22			;PRM3-96
#set Window_Info = 0
#set Window_About = 1
#set Window_SaveAs = 2
#set Window_Confirm = 3
#set Window_BootFloppy = 4
#set Window_ImageISO = 5
#set Window_Max = 5				;maximum windows ID in use
#set Menu_VPosition = 96+(44*9)			;vertical position of Filer menu
#set template_buffer_size = 4096		;size of Templates file
#set template_indirect_buffer_size = 4096	;indirect Sprite text data
#set maxPath = 255				;max path length


STRUCT VARS
{
 .menu_main			DCD 0
 .drag_in_progress		DCD 0
 .drag_bounding_box		DCD 0, 0, 0, 0
 .WIMP_Poll_Block		DBB 256
 .template_buffer		DBB template_buffer_size
 .template_indirect_buffer	DBB template_indirect_buffer_size
 .window_handles		DBD Window_Max + 1
 .window_indirects		DBD Window_Max + 1
 .open_window_block					;used for menu / window opening
 DCD    0						;window handle
 DCD    0						;visible min x
 DCD    0						;visible min y
 DCD    0						;visible max x
 DCD    0						;visible max y
 DCD    0						;scroll x offset
 DCD    0						;scroll y offset
 DCD    0						;open on top
 DBB    256						;256 bytes extra padding for Wimp_SendMessage
 DBD    256
 .stack
 .Open_Filer_Window		DCB "Filer_OpenDir "
 .ADFFS_Current_DiscName	DCB "12345678901234567890123456789012", 0
 .setIconState			DBD 4
 .size
}

#set icon_validation_length = 3
STRUCT About			;About Window indirect offsets
{
 .windows_title		DCB "About this floppy image", 0
 .type			DBB 10 + icon_validation_length
 .format		DBB 20 + icon_validation_length
 .id			DBB 8 + icon_validation_length
 .current_disc		DBB 3 + icon_validation_length
 .total_discs		DBB 3 + icon_validation_length
 .release		DBB 5 + icon_validation_length
 .modified		DBB 8 + icon_validation_length
 .title			DBB 256 + icon_validation_length
 .fps			DBB 16 + icon_validation_length
 .write_protect		DBB 2 + icon_validation_length
 .os_compatibility	DBB 7 * (2 + icon_validation_length)
 .cpu_compatibility	DBB 6 * (2 + icon_validation_length)
 .auto_flush		DBB 2 + icon_validation_length
}


MACRO oDIV res:R, top:R, bot:R, t:TR	;res=top DIV bot  top=top MOD bot
{
 MOVS    t, bot			; Put divisor in t
 MOV     res, #0		; Initialize quotient
 BEQ     _divide_by_zero
 CMP     t, top, LSR #1		; double it until
 ._div_loop1
   MOVLS   t, t, LSL #1		; 2 * t>top
   CMP     t, top, LSR #1
 BLS     _div_loop1

 ._div_loop2
   CMP     top, t		; Can we subtract t?
   SUBCS   top, top, t		; YES
   ADC     res, res, res	; Double res
   MOV     t, t, LSR #1		; Halve t
   CMP     t, bot		; and loop until
 BHS     _div_loop2		; less than divisor
 ._divide_by_zero
}




 DCD     Entry_start			;start
 DCD     Entry_init			;initialisation
 DCD     Entry_kill			;finalisation
 DCD     Entry_service			;service call handler
 DCD     ADFFS_Title			;title
 DCD     ADFFS_Help			;help
 DCD     ADFFS_Commands			;command table
 DCD     0				;SWI_Base
 DCD     0				;SWI Entry
 DCD     0				;SWI Names
 DCD     0				;SWI name decoding code
 DCD     0				;?
 DCD     ADFFS_ModFlags			;module flags



 .ADFFS_Commands
 DCB     "Desktop_ADFFSFiler", 0
 ALIGN
 DCD     Entry_ADFFSFiler		;Entry point
 DCD     &00000000			;Information word PRM1-218
 DCD     ADF_Command_Syntax		;syntax message
 DCD     ADF_Command_Help		;help text

 DCB     0
 ALIGN

 .ADFFS_ModFlags
 DCD     1				;32-bit compatible


 .ADFFS_Title
 DCB     "ADFFSFiler", 0

 .ADFFS_Help
 DCB     "ADFFSFiler", 9, version_string, 0

 .ADF_Command_Help	DCB "*Desktop_ADFFSFiler opens the ADFFS Filer", 13
 .ADF_Command_Syntax	DCB "Syntax: *Desktop_ADFFSFiler", 0
			ALIGN


 .WIMP_Task		DCB "TASK"
 .WIMP_Task_Title	DCB "ADFFS Filer", 0
			ALIGN

;@@@ MOVE TO VARS
 .WIMP_Icon_Block
 DCD     -5					;Icon bar position
 DCD     0					;Minimum x of icon
 DCD     -16					;Minimum y of icon
 DCD     96					;Maximum x of icon
 DCD     20					;Maximum y of icon
 DCD     &1700310B				;Icon flags
 .WIMP_Icon_Text_ptr
 DCD     0					;pointer to text
 .WIMP_Icon_Validation_ptr
 DCD     0					;pointer to validation string
 DCD     WIMP_Icon_Text_end - WIMP_Icon_Text	;length of text buffer


;@@@ MOVE TO VARS
 .spoof_message
 DCD 24
 .WIMP_Task_Handle  DCD 0
 DCD 0
 DCD 0
 DCD WIMP_Message_SlotSize
 .current_slotsize  DCD -1
 DCD 0


 .WIMP_Icon_Validation
 DCB	"S"
 .WIMP_Icon_Icon_Name
 DCB	"!"
 .WIMP_Icon_Text
 .ADFFS_FS_Title
 DCB	"ADFFS"
 .WIMP_Icon_Text_end
 DCB	0

 .WIMP_Template_File
 DCB	"ADFFS:Templates", 0
 ALIGN





;Entry_init
;----------
;Module initialisation code
;
;Entry:
; R12 - private word

.Entry_init
 STMFD   R13!, {R1-R11, R14}
 MOV     R0, #Module_Claim
 MOV     R3, #VARS.size
 SWI     XOS_Module			;PRM1-237
 LDMVSFD R13!, {R1-R11, PC}
 STR     R2, [R12, #0]			;our VARS space

 ADR     R0, Open_Filer_Unknown
 LDMIA   R0, {R3-R6}
 ADD     R0, R2, #VARS.Open_Filer_Window
 STMIA   R0, {R3-R6}
LDMFD   R13!, {R1-R11, PC}




;Entry_service
;-------------
;Respond to Service_StartFiler
;
;Entry:
; R0 - Filer's task handle
; R1 - reason code

 ._service_table	DCD 0				;set R1 to service no.
			DCD Entry_service + 4		;entry for services
			DCD Service_Reset		;27
			DCD Service_StartFiler		;4B
			DCD Service_StartedFiler	;4C
			DCD 0
 DCD     _service_table
.Entry_service
 MOV     R0, R0				;magic word for RO4+
 STR     R14, [R13, #-4]!
        
 TEQ     R1, #Service_StartedFiler
 BEQ     _P1
        
 TEQ     R1, #Service_Reset
 BEQ     _P2
        
 TEQ     R1, #Service_StartFiler	;PRM2-500
 LDRNE   PC, [R13], #4
        
 LDR     R14, WIMP_Task_Handle		;is our filer running?
 TEQ     R14, #0
 ADREQ   R0, ADFFS_Commands		;NO, ptr to *command
 MOVEQ   R1, #0				;|+  claim call
LDR    PC, [R13], #4

 ._P1
 LDR    R14, WIMP_Task_Handle
 CMN    R14, #1

 ._P2
 MOVEQ  R14, #0
 STREQ  R14, WIMP_Task_Handle
LDR    PC, [R13], #4




;Entry_start
;-----------
;Module start code *RMRun
;
;Entry:
; R12 - private word

.Entry_start
 LDR     R12, [R12, #0]			;check if this is a 2nd instance
 TEQ     R12, #0			;Don't allow re-init
 SWIEQ   XOS_Exit			;PRM1-303

 ADD     R13, R12, #VARS.stack		;setup stack pointer

 MOV     R0, #WimpSysInfo_ActiveTasks	;get number of WIMP tasks
 SWI     XWimp_ReadSysInfo		;PRM3-216
 TEQ     R0, #0				;is WIMP active?
 SWIEQ   XOS_Exit			;NO, exit

 LDR     R0, WIMP_Task_Handle		;kill the WIMP task if it's running
 TEQ     R0, #0
 LDRNE   R1, WIMP_Task
 SWINE   XWimp_CloseDown		;PRM3-172
 MOV     R0, #0
 STR     R0, WIMP_Task_Handle		;mark as inactive, in case of error

 MOV     R0, #WIMP_Version		;create WIMP task
 LDR     R1, WIMP_Task
 ADR     R2, WIMP_Task_Title
 SWI     XWimp_Initialise		;PRM3-85
 BVS     Exit_Module

 STR     R1, WIMP_Task_Handle		;store WIMP handle for later

 MOV     R0, #SpriteOp_ReadSpriteInfo	;get size of icon bar
 ADR     R2, WIMP_Icon_Icon_Name
 SWI     XWimp_SpriteOp			;PRM1-818
 BVS     Exit_Module

 MOV     R0, R6
 MOV     R1, #5				;ModeVariable_YEig
 SWI     XOS_ReadModeVariable		;PRM1-736
 BVS     Exit_Module

 MOV     R0, #20			;Maximum y of icon
 ADD     R0, R0, R4, LSL R2		;add sprite height to icon bounding box
 STR     R0, WIMP_Icon_Block+16

 ADR     R2, WIMP_Icon_Text		;update the pointer to our Icon text
 STR     R2, WIMP_Icon_Text_ptr
 ADR     R2, WIMP_Icon_Validation	;update the pointer to out Icon validation string
 STR     R2, WIMP_Icon_Validation_ptr

 MOV     R0, #&00000000			;create the icon on the icon bar
 ADR     R1, WIMP_Icon_Block
 SWI     XWimp_CreateIcon		;PRM3-93
 BVS     Exit_Module
					;************************************
					;read window templates

 ADR     R1, WIMP_Template_File		;load our template file
 SWI     XWimp_OpenTemplate		;PRM3-165
 BVS     Exit_Module

					;initiate registers for template load
 ADD     R9, R12, #VARS.window_handles
 ADD     R11, R12, #VARS.window_indirects
 ADD     R1, R12, #VARS.template_buffer
 ADD     R2, R12, #VARS.template_indirect_buffer
 ADD     R3, R2, #template_indirect_buffer_size
 MVN     R4, #0
 FNload_template Window_About
 FNload_template Window_Info
 FNload_template Window_SaveAs
 FNload_template Window_Confirm
 FNload_template Window_BootFloppy
 FNload_template Window_ImageISO
 SWI     XWimp_CloseTemplate		;PRM3-166
					;************************************

 BL      fix_relative_addresses		;correct relative addresses

					;************************************
					;Main WIMP polling loop

.poll_loop
 SWI     XOS_ReadMonotonicTime		;PRM1-446
 ADD     R2, R0, #1000			;poll every 10 seconds, or on event
 MOV     R0, #WIMP_Poll_Mask
 ADD     R1, R12, #VARS.WIMP_Poll_Block
 SWI     XWimp_PollIdle			;PRM3-181
 BVS     Exit_Module

 TEQ     R0, #1				;PRM3-116
 BEQ     WIMP_redraw_window		;redraw window

 TEQ     R0, #2				;PRM3-116
 BEQ     WIMP_open_window		;open window (eg drag action)

 TEQ     R0, #3				;PRM3-116
 BEQ     WIMP_close_window		;close window

 TEQ     R0, #9				;PRM3-120
 BEQ     WIMP_menu_selection		;menu selection

 TEQ     R0, #6				;PRM3-117
 BEQ     WIMP_mouse_click		;mouse click

 TEQ     R0, #7				;PRM3-118
 BEQ     WIMP_drag_end			;drag ended

 TEQ     R0, #17			;message?
 TEQNE   R0, #18
 BEQ     WIMP_user_message

.poll_loop_exit
 MOV     R0, #7				;get OS version
 SWI     XADFFS_Info
 CMP     R0, #&350<<8			;below RO 3.5?
 BHS     poll_loop			;NO, don't display allocation bar

 MOV     R0, #0				;get ADFFS' memory allocation
 SWI     XADFFS_Info
 BVC     WIMP_update_slot

B       poll_loop




;Entry_kill
;----------
;RMKill module entry point

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

 LDR     R0, WIMP_Task_Handle		;is the filer running?
 TEQ     R0, #0
 LDRNE   R1, WIMP_Task			;yes, close it down
 SWINE   XWimp_CloseDown		;PRM3-172

 MOV     R0, #0
 STR     R0, WIMP_Task_Handle

 MOV     R0, #Module_Free		;release our VARS space
 LDR     R2, [R12]
 SWI     XOS_Module			;PRM1-238
LDMFD   R13!, {R0-R1, PC}




;WIMP_exit
;---------
;Exit cleanly when the desktop shuts down

.WIMP_exit
 LDR     R0, WIMP_Task_Handle		;is the filer running?
 TEQ     R0, #0
 LDRNE   R1, WIMP_Task			;yes, close it down
 SWINE   XWimp_CloseDown		;PRM3-172

 MOV     R0, #0
 STR     R0, WIMP_Task_Handle
 TEQ     R0, #WIMP_Message_Quit
SWI   XOS_Exit




;Exit_Module
;-----------
;Close down WIMP task and exit to the OS
;
;Entry:
; R10 - error if V set

.Exit_Module
 MOV     R10, #0
 MOVVS   R10, R0			;V is set it we were passed an error

 LDR     R0, WIMP_Task_Handle		;is the filer running?
 TEQ     R0, #0
 MOVNE   R3, #0				;YES
 STRNE   R3, WIMP_Task_Handle		; |  mark as inactive
 LDRNE   R1, WIMP_Task			; |  close it down
 SWINE   XWimp_CloseDown		; |+ PRM3-172

 MOVS    R0, R10			;report any errors
 SWINE   OS_GenerateError

 MOV     R1, #0				;if no error, exit and self terminate
 MOV     R2, #0
 ADR     R3, ADFFS_Title
SWI     OS_ExitAndDie			;PRM1-323




;WIMP_drag_end
;-------------
;WIMP notifying that a drag has ended

.WIMP_drag_end
 ADD     R1, R12, #VARS.open_window_block
 SWI     XWimp_GetPointerInfo		;PRM3-140

 SWI     XDragASprite_Stop		;PRM3-300

 LDR     R2, [R1, #12]			;destination window handle
 STR     R2, [R1, #20]
 LDR     R0, [R1, #16]			;destination icon handle
 STR     R0, [R1, #24]
 LDR     R0, [R1, #0]			;destination x
 STR     R0, [R1, #28]
 LDR     R0, [R1, #4]			;destination y
 STR     R0, [R1, #32]
 MOV     R0, #0
 STR     R0, [R1, #12]			;your_ref
 MOV     R0, #WIMP_Message_Save
 STR     R0, [R1, #16]

 ADD     R4, R12, #VARS.window_indirects	;get our window handles
 LDR     R0, [R12, #VARS.drag_in_progress]	;name of icon to show
 ADR     R3, drag_icon
 TEQ     R0, R3				;SaveAs?
 LDREQ   R4, [R4, #Window_SaveAs << 2]	;YES, get the indirected address of the window contents
 LDRNE   R4, [R4, #Window_ImageISO << 2]

 MOV     R3, R4				;start of filename
 ._L1					;find the filename
   LDRB    R0, [R4], #1

   TEQ     R0, #ASC(".")
   MOVEQ   R3, R4			;start of filename

   TEQ     R0, #0
 BNE     _L1

 SUB     R5, R4, R3			;length of filename
 ADD     R0, R5, #3
 BIC     R0, R0, #3			;align length
 ADD     R0, R0, #44
 STR     R0, [R1, #0]			;length of data
 MOV     R0, #1
 SWI     XADFFS_Info			;get size of file
 STR     R0, [R1, #36]			;estimated size

 ADD     R7, R1, #44			;address to store filename
 ._L2
   LDRB    R0, [R3], #1			;copy the filename
   STRB    R0, [R7], #1

   SUBS    R5, R5, #1
 BPL     _L2

 MOV     R0, #18
 SWI     XWimp_SendMessage		;PRM3-193

B       poll_loop_exit




;WIMP_redraw_window
;------------------
;WIMP issued a redraw window request

.WIMP_redraw_window
 SWI     XWimp_RedrawWindow		;PRM3-126
B       poll_loop_exit




;WIMP_open_window
;----------------
;WIMP issued an open window request

.WIMP_open_window
 SWI     XWimp_OpenWindow		;PRM3-109
B       poll_loop_exit




;WIMP_close_window
;-----------------
;WIMP issued a close window request

.WIMP_close_window
 SWI     XWimp_CloseWindow		;PRM3-111
B       poll_loop_exit




;WIMP_user_message
;-----------------
;WIMP issued a message, PRM3-124
;
;Entry:
; R1 + 0  - size of block in bytes
; R1 + 4  - task handle of message sender
; R1 + 8  - my_ref - the senders reference
; R1 + 12 - your_ref - set to my_ref on return, or 0 if not replying
; R1 + 16 - Message action code
; R1 + 20 - message data

.WIMP_user_message
 LDR     R0, [R1, #16]
 TEQ     R0, #WIMP_Message_Quit
 BEQ     WIMP_exit			;WIMP requested end process

 TEQ     R0, #WIMP_Message_Load
 BEQ     file_dropped			;user dropped a file on us

 TEQ     R0, #WIMP_Message_DataSaveAck
 BEQ     data_save_ack			;save being acknowledged

B       poll_loop_exit




;WIMP_allow_slot_slider  PRM3-239
;----------------------
;Give us a configurable slider in the WIMP task manager

.WIMP_allow_slot_slider
 LDR     R2, WIMP_Task_Handle		;our handle
 LDR     R3, [R1, #24]			;the task this request is for
 TEQ     R3, R2				;is it our task?
 BNE     poll_loop			;NO

 LDR     R0, [R1, #8]			;acknowledge the request
 STR     R0, [R1, #12]

 LDR     R3, [R1, #20]			;get the new size
 CMN     R3, #1				;are we being initialized?
 BEQ     poll_loop			;YES, exit

 MOV     R0, #1
 SWI     XADFFS_Info			;get the size of the mounted floppy
 BVS     poll_loop			;exit on error

 CMP     R3, R0				;is the slot size big enough?
 MOVGT   R0, R3				;YES, allow the change

 .WIMP_update_slot
 LDR     R3, current_slotsize		;current slotsize
 TEQ     R0, R3				;is the new size different?
 BEQ     poll_loop			;NO, exit

 CMN     R3, #1				;skip the first call to prevent
 STR     R0, current_slotsize		;..earlier WindowManager modules
 BEQ     poll_loop			;..from hanging

 MOV     R5, R1				;preserve R1
 MOV     R0, #17			;user message
 ADR     R1, spoof_message		;PRM3-239
 MOV     R2, #0				;broadcast message
 SWI     XWimp_SendMessage		;PRM3-193
 MOV     R1, R5				;preserve R1
B       poll_loop




;data_save_ack  PRM3-250
;-------------
;Another task has acknowledged a save request
;
;Entry:
; R1 + 44 - full filename

.data_save_ack
 ADD     R2, R12, #VARS.window_indirects	;get our window handles
 LDR     R7, [R12, #VARS.drag_in_progress]	;name of icon to show
 ADR     R8, drag_icon
 TEQ     R7, R8				;SaveAs?
 LDREQ   R2, [R2, #Window_SaveAs << 2]	;get the indirected address of the window contents
					;offset in indirected filename is 0
 LDRNE   R2, [R2, #Window_ImageISO << 2]

 ADD     R1, R1, #44			;full pathname
 MOV     R3, #maxPath			;max length we can handle
 ._L1
   LDRB    R0, [R1], #1
   STRB    R0, [R2], #1

   SUBS    R3, R3, #1			;have we reached our limit
   TEQNE   R0, #0			;did we hit the end
 BNE     _L1

 TEQ     R7, R8				;SaveAs?
 BEQ     save_as_immediate		;YES
 B       save_as_immediateISO




;file_dropped
;------------
;WIMP asking us to load a file
;
;Entry:
; R1+20 - Destination window handle
; R1+24 - Destination icon handle
; R1+28 - Destination x
; R1+32 - Destination y
; R1+40 - Filetype
; R1+44 - Path to filename

.supported_filetypes
 DCD    &FCE				;Filecore floppy disc image
 DCD    &FC8				;DOS disc image
 DCD    &FE3				;Atari disc image
 DCD    -1

.file_dropped
 LDR    R0, [R1, #40]			;file type inbound

 ADR    R3, supported_filetypes
 ._L1
   LDR    R2, [R3], #4
   CMN    R2, #1			;last filetype?
   BEQ    poll_loop_exit		;YES, ignore the file
   TEQ    R0, R2			;do we support this filetype?
 BNE    _L1				;NO

 ADD    R0, R1, #44			;pointer to filename

 BL     Entry_ADFOpen			;load the file

;strictly speaking we should send
;an ACK back.  We're not going too
;as the sender doesnt need to act
;on our actions

B       poll_loop_exit




;WIMP_mouse_click
;----------------
;WIMP detected a mouse click, we have to figure out which
;window / menu it was on and what to do.
;
;Entry:
; R1 + 12 - window handle

.WIMP_mouse_click
 ADD     R9, R12, #VARS.window_handles
 LDR     R0, [R1, #12]			;get the window handle

 LDR     R2, [R9, #Window_About << 2]
 TEQ     R0, R2				;About window
 BEQ     poll_loop_exit

 LDR     R2, [R9, #Window_Info << 2]
 TEQ     R0, R2				;Info window
 BEQ     poll_loop_exit

 LDR     R2, [R9, #Window_Confirm << 2]
 TEQ     R0, R2				;Flush confirm window
 BEQ     flush_confirm

 LDR     R2, [R9, #Window_SaveAs << 2]
 TEQ     R0, R2				;Save as window
 BEQ     save_as

 LDR     R2, [R9, #Window_ImageISO << 2]
 TEQ     R0, R2				;Save as window
 BEQ     imageISO

 LDR     R2, [R9, #Window_BootFloppy << 2]
 TEQ     R0, R2				;Soft reset confirm window
 BEQ     BootFloppy_confirm

					;if we got here, it's a menu
 LDR     R0, [R1, #8]			;which button
 TST     R0, #%010			;select or adjust?
 BNE     display_menu			;NO, menu button then

 BL      get_current_discname		;is ADFFS mounted?
 BVS     Open_Filer_Error		;report a blank disc if not

 ADD     R0, R12, #VARS.Open_Filer_Window	;Filer_OpenDir CLI command
 SWI     XOS_CLI			;PRM1-961 open the filer window

B       poll_loop_exit


.Open_Filer_Error
 ADR     R0, Open_Filer_Unknown
 SWI     XOS_CLI			;PRM1-961
B       poll_loop_exit




;flush_confirm
;-------------
;Mouse click in flush confirm window
;
;Entry:
; R1 + 8  - mouse buttons
; R1 + 12 - window handle
; R1 + 16 - button ID, -1 for background


.flush_confirm
 LDR     R2, [R1, #16]			;see which button was pressed

 ADD     R1, R1, #12			;window handle pointer
 SWI     XWimp_CloseWindow		;PRM3-111  close the window we clicked in

 TEQ     R2, #1				;YES, pressed?
 BNE     poll_loop_exit
 ADR     R0, _Command_ADFFlush		;...it was, so run *ADFFlush
 SWI     XOS_CLI			;PRM1-961
 BLVS    report_error
B       poll_loop_exit

 ._Command_ADFFlush	DCB "ADFFlush", 0
			ALIGN


.report_error
;            %9876543210
; MOV     R1, #%1010101101		;flags: non-blocking / OK
; ADR     R2, ADFFS_Title		;error title
; SWI     Wimp_ReportError		;PRM3-176
 SUBS    R0, R0, R0			;clear V
MOV     PC, R14




;BootFloppy_confirm
;-----------------
;Mouse click in BootFloppy confirm window
;
;Entry:
; R1 + 8  - mouse buttons
; R1 + 12 - window handle
; R1 + 16 - button ID, -1 for background

.BootFloppy_confirm
 LDR     R2, [R1, #16]			;see which button was pressed

 ADD     R1, R1, #12			;window handle pointer
 SWI     XWimp_CloseWindow		;PRM3-111  close the window we clicked in

 TEQ     R2, #1				;YES, pressed?
 BNE     poll_loop_exit			;NO, exit

 MOV     R0, #202
 MOV     R1, #0
 MOV     R2, #&FF			;Read keyboard status
 SWI     XOS_Byte			;PRM1-914
 TST     R1, #1<<6			;was CTRL key pressed?
 BEQ     boot_in_wimp			;NO, remain in the WIMP

 SWI     XADFFS_BootOnWIMPShutdown	;notify ADFFS to capture
					;..Service_ShutdownComplete

 MOV     R0, #%11001			;Shutdown the Wimp
 SWI     XTaskManager_Shutdown		;PRM3-315

 MOV     R0, #138			;YES, need to workaround Shutdown not
 MOV     R1, #0				; | triggering post RISC OS 3.1
 MOV     R2, #ASC(" ")			; | insert a key into the keybuffer
 SWI     XOS_Byte			;PRM1-172

B       poll_loop_exit

.boot_in_wimp
 ADR     R0, boot_floppy
 SWI     XWimp_StartTask

B       poll_loop_exit

 .boot_floppy	DCB "ADFBootFloppy", 0
		ALIGN




;imageISO
;Mouse click in save as window
;
;Entry:
; R1 + 8  - buttons
; R1 + 12 - window handle
; R1 + 16 - button ID, -1 for background

.imageISO
 LDR     R2, [R1, #16]			;icon pressed

 TEQ     R2, #2				;file icon, used for drag save
 ADREQ   R0, drag_icon2
 BEQ     drag_save			;possible drag save

 ADD     R1, R1, #12			;window handle pointer
 SWI     XWimp_CloseWindow		;PRM3-111  close the window
 BL      closeMenus

 CMP     R2, #1				;did user press enter
 BNE     poll_loop_exit			;NO, don't do anything

.save_as_immediateISO
 BL      closeMenus

 ADD     R1, R12, #VARS.window_indirects	;get our window handles
 LDR     R1, [R1, #Window_ImageISO << 2]	;get the indirected address of the window contents
					;offset in indirected filename is 0
 MOV     R2, R1				;R2=R1=string
 MOV     R3, #maxPath			;max length
 ._find_length
   LDRB    R0, [R2], #1
   SUBS    R3, R3, #1			;have we reached our limit
   TEQNE   R0, #0			;did we hit the end
 BNE     _find_length

 SUBS    R2, R2, R1			;length
 SUBNES  R2, R2, #1			;correct length
 ADR     R0, ISOvarname			;var name
 MOV     R3, #0				;context
 MOV     R4, #4				;type (literal string)
 SWI     XOS_SetVarVal			;set the variable

 ADR     R0, _run_imageISO
 SWI     XWimp_StartTask		;run !imageISO
B       poll_loop_exit

 ._run_imageISO DCB "Obey ADFFS:!imageISO", 0
 .ISOvarname	DCB "ADFFS$ISO", 0
		ALIGN



;save_as
;Mouse click in save as window
;
;Entry:
; R1 + 8  - buttons
; R1 + 12 - window handle
; R1 + 16 - button ID, -1 for background

.save_as
 LDR     R2, [R1, #16]			;icon pressed

 TEQ     R2, #2				;file icon, used for drag save
 ADREQ   R0, drag_icon
 BEQ     drag_save			;possible drag save

 ADD     R1, R1, #12			;window handle pointer
 SWI     XWimp_CloseWindow		;PRM3-111  close the window
 BL      closeMenus

 CMP     R2, #1				;did user press enter
 BNE     poll_loop_exit			;NO, don't do anything

.save_as_immediate
 BL      closeMenus

 ADD     R1, R12, #VARS.window_indirects	;get our window handles
 LDR     R0, [R1, #Window_SaveAs << 2]	;get the indirected address of the window contents
					;offset in indirected filename is 0
 SWI     XADFFS_Save

B       poll_loop_exit


.checkFloppyMounted
 STMFD   R13!, {R0, R14}
 MOV     R0, #2
 SWI     XADFFS_Info
 TEQ     R0, #0
LDMFD   R13!, {R0, PC}


.closeMenus
 MVN     R1, #0				;close menu
 SWI     XWimp_CreateMenu		;PRM3-153
MOV     PC, R14




;drag_save
;---------
;Used initiated a drag from the save as window
;
;Entry:
; R0      - icon to drag
; R1 + 8  - buttons
; R1 + 12 - window handle

.drag_save
 STR     R0, [R12, #VARS.drag_in_progress]	;icon to drag
 LDR     R0, [R1, #8]			;check for drag condition
 TST     R0, #%1010000			;mouse buttons << 4
 BEQ     poll_loop_exit			;not a drag?  exit

 LDR     R3, [R1, #12]			;window handle requesting drag

					;******************************
 MVN     R0, #0				;read current screen resolution
 MOV     R1, #11			;screen width - 1
 SWI     XOS_ReadModeVariable		;PRM1-736
 MOV     R10, R2			;store in R10 for later

 MOV     R1, #12			;screen height - 1
 SWI     XOS_ReadModeVariable		;PRM1-736
 MOV     R11, R2			;store in R11 for later
					;******************************

 ADD     R1, R12, #VARS.open_window_block	;buffer to get window state

 STR     R10, [R1, #32]			;screen max x
 STR     R11, [R1, #36]			;screen max y

 STR     R3, [R1, #0]			;get the window coordinates
 SWI     XWimp_GetWindowState		;PRM3-132

 LDR     R4, [R1, #4]			;visible min x
 LDR     R0, [R1, #20]			;scroll x offset
 SUB     R4, R4, R0
 LDR     R5, [R1, #16]			;visible max y
 LDR     R0, [R1, #24]			;scroll y offset
 SUB     R5, R5, R0

 MOV     R0, #2				;get the icon state
 STR     R0, [R1, #4]			;the icon ID we're going to drag
 SWI     XWimp_GetIconState		;PRM3-138

 LDR     R0, [R1, #8]			;min x
 ADD     R2, R4, R0			; =window x + icon x
 LDR     R0, [R1, #12]			;min y
 ADD     R3, R5, R0			; =window y + icon y
 LDR     R0, [R1, #16]			;max x
 ADD     R4, R4, R0			; =window x + icon x
 LDR     R0, [R1, #20]			;max y
 ADD     R5, R5, R0			; =window y + icon y


 MOV     R0, #5				;initiate drag
 STR     R0, [R1, #4]			;drag type
 STR     R2, [R1, #8]			;min x
 STR     R3, [R1, #12]			;min y
 STR     R4, [R1, #16]			;max x
 STR     R5, [R1, #20]			;max y
 MOV     R0, #0
 STR     R0, [R1, #24]			;screen min x
 STR     R0, [R1, #28]			;screen min y

 STR     R2, [R12, #VARS.drag_bounding_box + 0]		;icon drag min x
 STR     R3, [R12, #VARS.drag_bounding_box + 4]		;icon drag min y
 STR     R4, [R12, #VARS.drag_bounding_box + 8]		;icon drag max x
 STR     R5, [R12, #VARS.drag_bounding_box + 12]	;icon drag max y

 MOV     R6, R1				;preserve R1
 MOV     R0, #161			;read the user preferences for icon drags
 MOV     R1, #28			;FileSwitch options
 SWI     XOS_Byte			;PRM1-369
 MOV     R1, R6				;preserve R1

 ANDS    R2, R2, #%10			;DragASprite PRM1-363
 BEQ     _DragASprite_unavailable	;if DragASprite disabled, show box instead

 MOV     R0, #%11000101			;dropshadow, sprite centred
 MOV     R1, #1				;sprite is in WIMP sprite area
 LDR     R2, [R12, #VARS.drag_in_progress]	;name of icon to show
 ADD     R3, R12, #VARS.drag_bounding_box	;pointer to box

 SWI     XDragASprite_Start		;PRM3-298
B       poll_loop_exit


 ._DragASprite_unavailable
 SWI     XWimp_DragBox			;PRM3-142
B       poll_loop_exit


 .drag_icon		DCB "file_fce", 0
 .drag_icon2		DCB "file_df6", 0
			ALIGN




;Entry_ADFOpen
;-------------
;Mount an ADF image and open a filer window

;Entry:
; R0 = pointer to command tail
; R1 = no. of parameters
; R12 = point to module private word
;
;Exit:
; R0 - corrupt or error pointer
; V set on error

.Entry_ADFOpen
 SWI     XADFFS_Mount
MOV     PC, R14




;get_current_discname
;--------------------
;Get the current ADF disc name
;
;Exit:
; R0, R1, R4, R5 corrupt
; R2 - disc name pointer
; V set on error

.get_current_discname
 MOV     R0, #37			;Get the disc name
 ADR     R1, ADFFS_Filer_Name		;...using convert path to canonicalised name
 ADD     R2, R12, #VARS.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
 MOVVS   R0, #1<<31			;get ready to set V on exit
 MOVVC   R0, #0

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

 MOV     R1, #0
 STRB    R1, [R2, R5]			;terminate the discname
 ADDVC   R2, R2, #6			;it starts at byte 6

 ADDS    R0, R0, R0			;set / clear V
MOV     PC, R14

 .Open_Filer_Unknown	DCB "Filer_OpenDir "
 .ADFFS_Filer_Name	DCB "ADFS::0", 0
 ALIGN

 .disc_formats
 DCD disc_format_unknown - disc_formats
 DCD disc_format_L - disc_formats
 DCD disc_format_D - disc_formats
 DCD disc_format_E - disc_formats
 DCD disc_format_F - disc_formats
 DCD disc_format_DOS1440 - disc_formats
 DCD disc_format_DOS720 - disc_formats
 DCD disc_format_Atari720 - disc_formats
 DCD disc_format_Atari360 - disc_formats

 .disc_format_unknown	DCB "Unknown format", 0
 .disc_format_L		DCB "ADFS 640K (L)", 0
 .disc_format_D		DCB "ADFS 800K (D)", 0
 .disc_format_E		DCB "ADFS 800K (E)", 0
 .disc_format_F		DCB "ADFS 1600K (F)", 0
 .disc_format_DOS1440	DCB "DOS 1440K", 0
 .disc_format_DOS720	DCB "DOS 720K", 0
 .disc_format_Atari720	DCB "Atari 720K", 0
 .disc_format_Atari360	DCB "Atari 360K", 0
 ALIGN



;copy_string
;-----------
;copy a zero terminated string
;
;Entry:
; R0 - source
; R1 - destination
;
;Exit:
; R0-R2 - corrupt

.copy_string
 LDRB    R2, [R0], #1
 STRB    R2, [R1], #1
 TEQ     R2, #0
 BNE     copy_string
MOV     PC, R14

;get_current_discformat
;----------------------
;Get the current ADF disc format
;
;Exit:
; R0-R6, R9, R11 corrupt

.get_current_discformat
 MOV     R9, R14

 ADD     R6, R12, #VARS.window_indirects
 LDR     R11, [R6, #Window_About << 2]	;get the indirected address of the window contents
 
 MOV     R0, #4				;file type
 SWI     XADFFS_Info
 ADD     R1, R11, #About.type
 BL      copy_string

 MOV     R0, #6				;JFD header
 SWI     XADFFS_Info
 MOVS    R3, R0				;R3=JFD header
 BEQ     skip_file_version

 MOV     R0, #ASC("v")
 STRB    R0, [R11, #About.type + 4]
 LDR     R4, [R3, #JFD_MinVersion]
 MOV     R2, #100
 TEMP    R14
 oDIV    R0, R4, R2			;R0=R1 DIV R2  R1=R1 MOD R2
 LOCK    R14
 ADD     R1, R11, #About.type + 5
 MOV     R2, #2
 BL      display_decimal
 MOV     R0, #ASC(".")
 STRB    R0, [R11, #About.type + 6]

 MOV     R0, R4
 ADD     R1, R11, #About.type + 7
 MOV     R2, #3
 BL      display_decimal

 .skip_file_version
 MOV     R0, #5				;disc format
 SWI     XADFFS_Info
 ADR     R2, disc_formats
 LDR     R0, [R2, R0, LSL #2]		;load the string pointer
 ADD     R0, R2, R0			;convert from indirect to a fixed address
 ADD     R1, R11, #About.format
 BL      copy_string

 MOV     R0, #3				;filename
 SWI     XADFFS_Info
 LDR     R1, [R6, #Window_SaveAs << 2]	;get the indirected address of the window contents
 TEQ     R0, #0
 STREQB  R0, [R1]			;blank if no filename
 BLNE    copy_string			;offset in indirected filename is 0

 TEQ     R3, #0				;is a JFD mounted?
 LDRNE   R0, [R3, #JFD_ID]		;YES, get ID
 ADD     R1, R11, #About.id
 MOV     R2, #7				;buffer length
 BL      display_decimal

 TEQ     R3, #0				;is a JFD mounted?
 LDRNE   R4, [R3, #JFD_Sequence]	;YES, get SSSSnnnn
 MOVNE   R0, R4, LSL #16		; |
 MOVNE   R0, R0, LSR #16		; |+ nnnn
 ADD     R1, R11, #About.current_disc
 MOV     R2, #2				;buffer length
 BL      display_decimal
 
 MOV     R0, R4, LSR #16		;SSSS
 MOV     R2, #2				;buffer length
 ADD     R1, R11, #About.total_discs
 BL      display_decimal

 TEQ     R3, #0				;is a JFD mounted?
 LDRNE   R4, [R3, #JFD_Release]		;YES, get VVVwwwww
 MOVNE   R0, R4, LSR #20		; |+ VVV
 MOV     R2, #4				;buffer length
 ADD     R1, R11, #About.release
 BL      display_decimal

 MOV     R0, R4, LSL #12
 MOV     R0, R0, LSR #12		;nnnn
 MOV     R2, #7				;buffer length
 ADD     R1, R11, #About.modified
 BL      display_decimal

 TEQ     R3, #0				;is a JFD mounted?
 MOVEQ   R2, #1				;NO
 MOVEQ   R0, #ASC("?")			; |
 STREQB  R0, [R11, #About.title]	; |
 STREQB  R3, [R11, #About.title+1]	; |+ mark unknown
 ADDNE   R0, R3, #JFD_Title		;Disc title
 ADDNE   R1, R11, #About.title
 BLNE    copy_string

 MOV     R1, #ASC("Y")
 MOV     R4, #ASC(" ")

 MOV     R0, #9
 SWI     XADFFS_Info			;R0=bit flags
 STMFD   R13!, {R0}
 TST     R0, #JFD_BF_WriteProtect
 STRNEB  R1, [R11, #About.write_protect]
 STREQB  R4, [R11, #About.write_protect]
 TST     R0, #JFD_BF_AutoFlush		;auto flush
 MOV     R2, #ASC(" ")
 STRNEB  R1, [R11, #About.auto_flush]
 STREQB  R2, [R11, #About.auto_flush]

 ADD     R1, R11, #About.fps
 TEQ     R3, #0				;is a JFD mounted?
 LDRNE   R2, [R3, #JFD_MinVersion]	;YES
 MOVEQ   R2, #0
 CMP     R2, #206			;does it support these values?
 MOVLO   R4, #ASC("?")			;NO
 ADRLO   R0, _unknown_self_reg
 BLO     _unknown_FPS

 TEQ     R3, #0				;is a JFD mounted?
 LDRNEB  R2, [R3, #JFD_FPS]
 MOVEQ   R2, #0
 MOVS    R0, R2, LSR #1
 MOV     R2, #15			;buffer length
 BEQ     _self_regulating
 BL      display_decimal
 B       _compatibility

 ._self_regulating
 ADR     R0, _self_reg_text
 ._unknown_FPS
 BL      copy_string

 ._compatibility
 LDMFD   R13!, {R0}
 ADD     R11, R11, #About.os_compatibility
 MOV     R1, #ASC("Y")

 MOV     R5, #1 << 16		;first bit
 MOV     R2, #1 << 23		;last bit
 BL      _set_flags
 MOV     R5, #1 << 8
 MOV     R2, #1 << 14
 BL      _set_flags
MOV      PC, R9

 ._set_flags
   TST     R0, R5
   STRNEB  R1, [R11], #2 + icon_validation_length
   STREQB  R4, [R11], #2 + icon_validation_length
   MOV     R5, R5, LSL #1
   TEQ     R5, R2
 BNE     _set_flags
 MOV     PC, R14


 ._self_reg_text    DCB "Self regulating", 0
 ._unknown_self_reg DCB "Unknown        ", 0
 ALIGN




;display_decimal
;---------------
;convert R0 to a terminated decimal string stored at R1
;
;Entry:
; R0 - value
; R1 - buffer
; R2 - buffer length
; R3 - JFD header pointer
;
;Exit:
; R0-R2 - corrupt

.display_decimal
 TEQ     R3, #0				;is a JFD mounted?
 MOVEQ   R2, #1				;NO
 MOVEQ   R0, #ASC("?")			; |
 STREQB  R0, [R1, #0]			; |
 STREQB  R3, [R1, #1]			; |+ mark unknown
 MOVEQ   PC, R14

 SWI     XOS_BinaryToDecimal		;PRM1-468
 MOV     R0, #0
 STRB    R0, [R1, R2]			;terminate string
MOV    PC, R14




;display_menu
;------------
;Displays the main menu
;
;Entry:
; R1 - pointer to WIMP block (PRM3-112)

.display_menu
 MOV     R10, R1

 BL      get_current_discformat		;fill in About window icon redirects

 LDR     R2, [R10, #0]			;mouse x
 SUB     R2, R2, #64			;move menu left
 MOV     R3,     #Menu_VPosition	;fixed y
 LDR     R1, [R12, #VARS.menu_main]	;our menu block

 BL      checkFloppyMounted		;is a floppy mounted?
 STMFD   R13!, {R2-R3}
 MOVEQ   R2, #Icon_Shaded		;NO
 MOVNE   R2, #0				;YES

 MOV     R0, #1				;Eject
 BL      WIMP_shade_menu_item
 MOV     R0, #5				;Flush
 BL      WIMP_shade_menu_item
 MOV     R0, #6				;Boot floppy
 BL      WIMP_shade_menu_item
 MOV     R0, #7				;SaveAs
 BL      WIMP_shade_menu_item
 MOV     R0, #&20000			;Format\Current format
 BL      WIMP_shade_menu_item

 MOV     R0, #10
 SWI     XADFFS_Info
 TEQ     R0, #0				;do we have a physical floppy drive?
 TEQEQ   R2, #0				;YES, is a floppy image mounted?
 MOVNE   R0, #&40002			;NO, Image floppy menu\Write to ADFS::0
 BLNE    WIMP_shade_menu_item

 SWI     XCDFS_GetNumberOfDrives
 MOVVS   R0, #0				;CDFS not supported
 CMP     R0, #0				;are there any CDROM's?
 MOVEQ   R2, #Icon_Shaded		;NO
 MOVNE   R2, #0				;YES
 MOV     R0, #3				;Image CD
 BL      WIMP_shade_menu_item

 LDMFD   R13!, {R2-R3}

 SWI     XWimp_CreateMenu		;PRM3-153
B       poll_loop_exit




;WIMP_shade_menu_item
;--------------------
;Sets the shaded state of a menu item
;
;Entry:
; R1 - menu pointer
; R0 - icon handle
; R2 - shaded state

.WIMP_shade_menu_item
 STMFD   R13!, {R0-R1, R14}
 MOVS    R14, R0, LSR #16		;R14>0 = submenu
 ADDNE   R1, R1, R14, LSL #4
 ADDNE   R1, R1, R14, LSL #3		;R1+=R2*24
 LDRNE   R1, [R1, #28+4]		;R1=[R1, #28+n*24+4]
 AND     R0, R0, #&FF

 MOV     R14, #24
 MLA     R14, R0, R14, R1		;R14=icon flags pointer

 LDR     R0, [R14, #28+8]		;get icon flags
 BIC     R0, R0, #Icon_Shaded
 ORR     R0, R0, R2
 STR     R0, [R14, #28+8]
LDMFD   R13!, {R0-R1, PC}




;WIMP_menu_select
;----------------
;WIMP notify a menu select has occured
;
;Entry:
; R1 - pointer to WIMP block (PRM3-120)

.WIMP_menu_selection
 LDR     R0, [R1, #0]			;menu entry pressed
 LDR     R2, [R1, #4]			;submenu entry pressed

 TEQ     R0, #1				;Eject
 BEQ     Menu_Selected_Eject

 TEQ     R0, #2				;Format
 BEQ     Menu_Format_Selected

 TEQ     R0, #4				;Image floppy
 BEQ     Menu_Image_Selected

 TEQ     R0, #5				;Flush
 BEQ     Menu_Selected_Flush

 TEQ     R0, #6				;Boot Floppy
 BEQ     Menu_Selected_BootFloppy

 TEQ     R0, #8				;Quit
 BEQ     Menu_Selected_Quit
B       poll_loop_exit




; "Eject" menu entry
;
; *ADFEject

.Menu_Selected_Eject
 ADR     R0, _Command_ADFEject		;*ADFEject
 SWI     XOS_CLI			;PRM1-961
B       poll_loop_exit

 ._Command_ADFEject	DCB "ADFEject", 0
			ALIGN




;"Format" menu entry
;-------------------
;Perform a *Format 0 <L/D/E/F>
;
;Entry:
;  R2 - submenu entry, 1 is F, 2 is E, 3 is D

.Menu_Format_Selected
 BL      Format_floppy
B       poll_loop_exit


.Format_floppy
 STR     R14, [R13, #-4]!
 MOV     R1, #0				;catch for unknowns

 TEQ     R2, #1
 MOVEQ   R1, #ASC("F")			;Format to F

 TEQ     R2, #2
 MOVEQ   R1, #ASC("E")			;Format to E

 TEQ     R2, #3
 MOVEQ   R1, #ASC("D")			;Format to D

 TEQ     R2, #4
 MOVEQ   R1, #ASC("L")			;Format to L

 TEQ     R1, #0				;catch unknowns
 LDREQ   PC, [R13], #4			;exit if unset

 ADD     R8, R12, #VARS.window_indirects	;get our window handles
 LDR     R8, [R8, #Window_SaveAs << 2]	;get the indirected address of the window contents
					;offset in indirected filename is 0
 MOV     R0, #0
 STRB    R0, [R8]			;blank save as indirect

 LDR     R0, Format_CLI + 12		;CLI string
 ORR     R0, R0, R1, LSL #16
 STR     R0, [R13, #-4]!		;store the format
 LDR     R0, Format_CLI + 8
 STR     R0, [R13, #-4]!
 LDR     R0, Format_CLI + 4
 STR     R0, [R13, #-4]!
 LDR     R0, Format_CLI + 0
 STR     R0, [R13, #-4]!
 MOV     R0, R13
 SWI     XOS_CLI			;PRM1-961  *ADFFormat
 ADD     R13, R13, #16			;drop string from stack

 BL      get_current_discname		;read the formatted disc name
 LDRVS   PC, [R13], #4			;skip name copy on error

 ADD     R1, R12, #VARS.window_indirects	;get our window handles
 LDR     R1, [R1, #Window_SaveAs << 2]	;get the indirected address of the window contents
					;offset in indirected filename is 0
 ._L1
   LDRB    R0, [R2], #1			;copy disc name to save as window
   TEQ     R0, #ASC(".")
   TEQNE   R0, #0
   MOVEQ   R0, #0			;change "." to a zero terminator
   MOVEQ   R5, #1			;exit loop

   SUBS    R5, R5, #1
   STRPLB  R0, [R1], #1
 BPL     _L1

LDR     PC, [R13], #4

			;    0123456789ABCD   E  F
 .Format_CLI		DCB "adfs:Format 0 ", 0, 0	;CLI for format command





;"Image floppy" menu entry
;-------------------------
;Allocate 640/800/1600K as appropriate and image floppy
;
;Entry:
;  R2 - submenu entry, 1 is F, 2 is E, 3 is D

.Menu_Image_Selected
 TEQ     R2, #0
 BEQ     _image_ADF

 TEQ     R2, #1
 BEQ     _image_JFD

 TEQ     R2, #2
 BEQ     _image_to_floppy
 B       poll_loop_exit

 ._image_to_floppy
 ADR     R0, _run_imageP
 B       _start_task

 ._image_JFD
 ADR     R0, _run_imageJFD
 B       _start_task

 ._image_ADF
 ADR     R0, _run_imageADF

 ._start_task
 SWI     XWimp_StartTask
B       poll_loop_exit

 ._run_imageADF	DCB "Obey ADFFS:!imageADF", 0
 ._run_imageJFD	DCB "Obey ADFFS:!imageJFD", 0
 ._run_imageP	DCB "Obey ADFFS:!imageP", 0
 ALIGN




; "Flush"
;
; *ADFFlush

.Menu_Selected_Flush
 FNopen_window Window_Confirm		;open the confirm window
B        poll_loop_exit




; "Boot floppy"
;
; *ADFBootFloppy

.Menu_Selected_BootFloppy
 FNopen_window Window_BootFloppy	;open the confirm window
B        poll_loop_exit




;"Quit" menu entry
;------------------
;Quit FS and/or Filer
;
;Entry:
; R2 - menu option selected

.Menu_Selected_Quit
 ADR     R0, _ADFUnprotectModules	;allow modules to be removed
 SWI     XOS_CLI

 TEQ     R2, #1				;quit ADFFS as well?
 MOVEQ   R0, #Module_Delete		;YES, kill ADFFS
 ADREQ   R1, ADFFS_FS_Title
 SWIEQ   XOS_Module			;PRM1-235

 SUBS    R0, R0, R0			;clear V
B       Exit_Module

 ._ADFUnprotectModules	DCB "ADFUnprotectModules", 0
			ALIGN




;*Desktop_ADFFSFiler
;-------------------
;Start the ADFFS filer
;
;Entry:
; R0  - pointer to command tail
; R1  - no. of parameters
; R12 - point to module private word

.Entry_ADFFSFiler
 STR     R14, [R13, #-4]!

 MOV     R2, R0
 ADR     R1, ADFFS_Title
 MOV     R0, #Module_Enter		;start the filer
 SWI     XOS_Module			;PRM1-233
LDR     PC, [R13], #4




;convert the relative address to fixed addresses
;Exit:
; R0-R4 corrupt

.fix_relative_addresses
 ADR     R0, address_fixlist		;the list of address to switch from relative to fixed
 MOV     R1, R0				;our code base
 ADD     R4, R12, #VARS.window_handles	;list of window handles
 SUB     R4, R4, #1 << 2		;the window ID is offset by 1

 ._loop
   LDMIA   R0!, {R2, R3}		;load the address pair
					;R2 is the offset from code base, to update
					;R3 is the relative address to store there
   CMP     R3, #0			;if R3 is 0, we've hit the end of the list
   BEQ     _exit			;exit if we hit the end of the list

   ADDPL   R3, R3, R1			;if its +, its an address within menu block
   RSBMI   R3, R3, #0			;if its -, its a window pointer
   LDRMI   R3, [R4, R3, LSL #2]		;...load the window handle

   STR     R3, [R1, R2]			;store the fixed address
 B       _loop

 ._exit
 STR     R0, [R12, #VARS.menu_main]	;update pointer to main menu
MOV     PC, R14




 .address_fixlist
 INCBIN "<Tmp$Dir>.ADFFSFiler.Menus"






; load_template
; -------------
; Loads a template window
;
; Entry:
;   R1-R4, R9, R11 must be initiated
;   R9  - Window handle table
;   R11 - Indirected data workspace
; Exit:
;   R0 - Window ID
;   R1 - preserved
;   R2 - pointer to next free indirect memory location
;   R3 - preserved
;   R4 - preserved
;   R5 - pointer to actual window name
;   R6 - pointer to next entry in Template file

MACRO FNload_template window_ID:I
{
  STR     R2, [R11, #window_ID << 2]	;store the indirected data address
  MOV     R6, #window_ID + ASC("0")
  STR     R6, [R13, #-12]!
  MOV     R6, #0			;position to search from in template
  STR     R6, [R13, #4]
  STR     R6, [R13, #8]
  MOV     R5, R13			;window name to load
  SWI     XWimp_LoadTemplate		;PRM3-167
  ADD     R13, R13, #12			;drop name from stack

  SWIVC   XWimp_CreateWindow		;PRM3-87
  BVS     Exit_Module
  STR     R0, [R9, #window_ID << 2]	;store the window handle
}



; open_window
; -----------
; Open a window
;
; Entry:
;   Window ID

MACRO FNopen_window window_ID:I
{
  ADD     R1, R12, #VARS.window_handles	;get our handle list
  LDR     R0, [R1, #window_ID << 2]	;load the Wimp window handle

  ADD     R1, R12, #VARS.open_window_block	;get the window block
  STR     R0, [R1]			;store the id we want

  SWI     XWimp_GetWindowState		;PRM3-132
  SWI     XWimp_OpenWindow		;PRM3-109
}