#set JFD_Sector_Expansion = 10 * 5 * 8	;10 tracks worth of sectors
#set JFD_Supports_Autoflush = 286	;min JFD version that supports auto-flush



;Entry:
; R11 - command tail
;Exit:
; R0-R10 - corrupt
; R11, R12 - preserved

.Entry_ADFMount_JFD
 ADD     R1, R12, #JFD_tmp - VARS	;buffer address
 MOV     R2, #JFD_Track_Table + 4	;bytes to read
 LDR     R0, [R12, #File_Handle - VARS]	;file handle
 SWI     XZLib_GZRead			;read the header

 LDR     R2, [R1, #JFD_Track_Table]	;get length of header
 CMP     R2, #JFD_Header		;cap at the max size we support
 MOVHI   R2, #JFD_Header
 SUB     R2, R2, #JFD_Track_Table + 8	;take off what we've already read
 ADD     R1, R1, #JFD_Track_Table + 4	;move to correct location
 LDR     R0, [R12, #File_Handle - VARS]	;file handle
 SWI     XZLib_GZRead			;read remainder of header
 SUB     R1, R1, #JFD_Track_Table + 4	;correct location

 MOV     R10, #module_version
 LDR     R2, [R1, #JFD_MinVersion]	;check if we support this version
 CMP     R2, R10			;is it less than our module version no.?
 ADRHI   R0, Error_ADFFS_Version	;NO
 BHI     Entry_ADFMount_Exit		; |+ exit on error

 LDR     R6, [R1, #JFD_Size]		;R6 = size of file
 LDR     R9, [R1, #JFD_Track_Table]	;R9 = offset to track table
 LDR     R10, [R1, #JFD_Sector_Table]	;R10 = offset to sector table
 LDR     R5, [R1, #JFD_Data]		;R5 = offset to data table
 SUB     R4, R6, R5			;R4 = size of data table with obey
 SUB     R7, R5, R9			;R7 = size of Track+Sector table
 STR     R7, [R12, #JFD_TrackSector_size - VARS]	;store so we can expand if required
 ;update the pointers, in case it's an older JFD structure
 SUB     R6, R6, R9			;size without header
 MOV     R0, #JFD_Header
 ADD     R14, R6, R0			;new size
 STR     R0, [R1, #JFD_Track_Table]
 STR     R14, [R1, #JFD_Size]
 SUB     R2, R10, R9			;size of Track table
 ADD     R2, R0, R2
 STR     R2, [R1, #JFD_Sector_Table]
 ADD     R2, R0, R7
 STR     R2, [R1, #JFD_Data]

 LDR     R2, [R12, #File_Size_Limit - VARS]
 CMP     R6, R2				;is filesize above our limit?
 MOVHI   R0, #1<<31			;YES, set V
 ADDHIS  R0, R0, R0			;  |
 ADRVS   R0, Error_File_Size		;  |
 SUBVC   R3, R5, R9			;R3 = size of Track and Sector tables
 ADDVC   R3, R3, #JFD_Sector_Expansion	;increase so we have an expansion area for new sectors
 ADDVC   R4, R4, R3			;final size required
 BLVC    MemAlloc			;allocate memory for JFD
 BVS     Entry_ADFMount_Exit		;  |+ exit on error

 SUB     R4, R4, R3			;correct R4 to be size of data + Obey

 LDR     R7, [R12, #DA_address - VARS]	;increase start of buffer
 ADD     R1, R7, R3
 ADD     R8, R7, R10
 SUB     R8, R8, R9
 STR     R7, [R12, #JFD_Tracks - VARS]		;Track table address
 STR     R8, [R12, #JFD_Sectors - VARS]		;Sector table address
 STR     R1, [R12, #ADF_Buffer_Address - VARS]	;Data address
 
 LDR     R0, [R12, #File_Handle - VARS]	;go to Track table
 MOV     R1, R9
 MOV     R2, #0
 SWI     XZLib_GZSeek

 LDR     R0, [R12, #File_Handle - VARS]
 MOV     R1, R7				;address to load
 SUB     R2, R5, R9			;bytes to read
 SWI     XZLib_GZRead			;read Track and Sector table in one go

 LDR     R1, [R12, #JFD_TrackSector_size - VARS]
 SUB     R1, R1, #4			;check and correct for <2.86 having an extra
 LDR     R14, [R7, R1]			;word at the end of the sector table
 CMN     R14, #1			;should be FFFFFFFF
 BEQ     _sector_table_ok

#if debug_Delta == 1	;Old structure
STMFD R13!, {R1}
MOV R1, R14
BL outputHexTruncated
SWI &100+ASC(" ")
LDMFD R13!, {R1}
BL outputHexTruncated
SWI &100+ASC(" ")
SWI XOS_WriteS
DCB "Old structure",0
ALIGN
SWI XOS_NewLine
#endif
					;<2.86 so correct data offset and sizes
 STR     R1, [R12, #JFD_TrackSector_size - VARS]
 LDR     R1, [R12, #JFD_tmp - VARS + JFD_Data]
 SUB     R1, R1, #4
 STR     R1, [R12, #JFD_tmp - VARS + JFD_Data]
 LDR     R1, [R12, #ADF_Buffer_Address - VARS]
 SUB     R1, R1, #4
 STR     R1, [R12, #ADF_Buffer_Address - VARS]
 LDR     R1, [R12, #JFD_tmp - VARS + JFD_Size]
 SUB     R1, R1, #4
 STR     R1, [R12, #JFD_tmp - VARS + JFD_Size]
; LDR     R1, [R12, #JFD_tmp - VARS + JFD_MinVersion]
; SUBS    R1, R1, #JFD_Supports_Autoflush	;2.86 beta?
; MOVEQ   R1, #285			;YES, ensure we perform a full save
; STREQ   R1, [R12, #JFD_tmp - VARS + JFD_MinVersion]
 ._sector_table_ok
#if debug_Delta == 1	;Data=
SWI XOS_WriteS
DCB "Data=",0
ALIGN
LDR   R1, [R12, #JFD_tmp - VARS + JFD_Data]
BL outputHexTruncated
SWI XOS_NewLine
#endif

 LDR     R0, [R12, #File_Handle - VARS]	;go to Data table
 MOV     R1, R5
 MOV     R2, #0
 SWI     XZLib_GZSeek

 ADD     R0, R4, #3
 BIC     R0, R0, #%11			;align where delta sectors will go
 STR     R0, [R12, #JFD_delta_offset - VARS]

 LDR     R0, [R12, #JFD_tmp - VARS + JFD_Obey_Length]	;length of obey file
 TEQ     R0, #0				;is there an obey file?
 SUBNE   R0, R4, R0			;YES, R0=offset in buffer to Obey file
 STR     R0, [R12, #obey_file_offset - VARS]

 LDR     R0, [R12, #File_Handle - VARS]	;read data
 LDR     R1, [R12, #ADF_Buffer_Address - VARS]	;address to load
 MOV     R2, R4				;bytes to read
 SWI     XZLib_GZRead			;read Data

 ; if JFD_Track_Delta, JFD_Sector_Delta, JFD_Data_Delta offsets are set {
 LDR     R2, [R12, #JFD_tmp - VARS + JFD_Track_Delta]
 TEQ     R2, #0
 BLNE    _read_delta_tables

 MOV     R2, #Type_JFD
 BL      floppy_type_changed
					;*****************************
					;check if the WIMP is running
 MOV     R0, #WimpSysInfo_ActiveTasks	;get number of WIMP tasks
 SWI     XWimp_ReadSysInfo		;PRM3-216
 TEQ     R0, #0				;R0>0 if WIMP is active
 BEQ     Entry_ADFMount_mounted		;NO, exit
					;*****************************

					;WIMP is running, prevent bad !Boot
					;via override if one exists

 LDR     R0, [R12, #JFD_tmp - VARS + JFD_ID]		;JFD Fxxxxxx
 ADR     R1, _jfd_number		;buffer address
 MOV     R2, #7				;length of buffer
 SWI     XOS_ConvertCardinal4		;PRM1-483

 LDR     R0, [R12, #JFD_tmp - VARS + JFD_Sequence]	;JFD floppy no
 AND     R0, R0, #&FF			;mask down to <99
 CMP     R0, #10
 MOVLT   R2, #ASC("0")			;pad with 0 if necessary
 STRLTB  R2, [R1], #1
 MOV     R2, #2				;length of buffer
 SWI     XOS_ConvertCardinal1

 ADR     R1, _filename			;filename
 MOV     R0, #17			;no path
 SWI     XOS_File			;PRM2-46
 TEQ     R0, #2				;does an override exist?
 BNE     Entry_ADFMount_mounted		;NO, exit

 MOV     R0, #9				;find first !Application
 ADR     R2, _leaf
 MOV     R3, #1
 MOV     R4, #0
 MOV     R5, #_size - _leaf
 ADR     R6, _pling
 SWI     XOS_GBPB			;PRM2-73

 TEQ     R3, #0				;did we find a !Application
 BEQ     Entry_ADFMount_mounted		;NO, exit

 MOV     R0, #ASC(".")			;add folder path
 STRB    R0, _terminator		;remove terminator

 MOV     R0, #200			;create a temporary WIMP task
 LDR     R1, _task
 ADR     R2, _task
 MOV     R3, #0
 SWI     XWimp_Initialise		;PRM3-85
 STMFD   R13!, {R1-R12}			;preserve R11, R12 and our task ID

 ADR     R0, _filer_boot
 SWI     XOS_CLI			;execute Filer_Boot

 LDMFD   R13!, {R0,R2-R12}		;preserve registers
 LDR     R1, _task			;close task
 SWI     XWimp_CloseDown		;PRM3-172
B       Entry_ADFMount_mounted




;_read_delta_tables
;------------------
;reads the delta tables and merges any sector data into the loaded image

;Exit:
;R0-R11 - corrupt

._read_delta_tables
 STMFD   R13!, {R14}
#if debug_Delta == 1	;Load Delta table
SWI XOS_WriteS
DCB "Delta table exists",0
ALIGN
SWI XOS_NewLine
#endif

 LDR     R1, [R12, #JFD_tmp - VARS + JFD_Sector_Delta]
 LDR     R0, [R12, #JFD_tmp - VARS + JFD_Data_Delta]
 SUB     R8, R1, R2				;R8=offset to delta sector table
 SUB     R2, R0, R2				;R2=size of delta track/sector tables
 STR     R2, [R12, #JFD_TrackSector_size - VARS]

 LDR     R0, [R12, #JFD_Tracks - VARS]
 LDR     R1, [R12, #ADF_Buffer_Address - VARS]
 SUB     R1, R1, R0				;R2=space we have for track/sector tables
 CMP     R2, R1					;do the delta tables fit?
 BLS     _can_load_delta_track_sector_table

;not enough room, increase the DA size and move sector data up
#if debug_Delta == 1	;doesn't fit
SWI XOS_WriteS
DCB "Delta Track/Sector table doesn't fit",0
ALIGN
SWI XOS_NewLine
#endif
 LDR     R5, [R12, #DA_size - VARS]
 ADD     R4, R5, R2
 SUB     R4, R4, R1				;R4=new size required
 BL      MemAlloc
 BVS     Entry_ADFMount_Exit

 LDR     R0, [R12, #ADF_Buffer_Address - VARS]	;NO, need to move the data
 ADD     R1, R2, #JFD_Sector_Expansion
 LDR     R14, [R12, #DA_address - VARS]
 ADD     R5, R5, R14				;R5=end of DA
 ADD     R1, R0, R1				;new start of sector data
 STR     R1, [R12, #ADF_Buffer_Address - VARS]
 SUB     R2, R5, R1				;R2=size to move (DA size-new track/sector size)
#if debug_Delta == 1	;moving
STMFD R13!, {R1}
SWI XOS_WriteS
DCB "Moving ",0
ALIGN
MOV R1, R0
BL outputHexTruncated
SWI XOS_WriteS
DCB " to ",0
ALIGN
LDR R1, [R13]
BL outputHexTruncated
SWI XOS_WriteS
DCB " size ",0
ALIGN
MOV R1, R2
BL outputHexTruncated
LDMFD R13!, {R1}
#endif
 BL      MemMove

 ._can_load_delta_track_sector_table
 LDR     R0, [R12, #JFD_Tracks - VARS]
 ADD     R8, R0, R8
 STR     R8, [R12, #JFD_Sectors - VARS]		;Sector table address
#if debug_Delta == 1	;DA:
SWI XOS_WriteS
DCB "DA: ",0
ALIGN
LDR R1, [R12, #DA_address - VARS]
BL outputHexTruncated
SWI &100+ASC("-")
LDR R14, [R12, #DA_size - VARS]
ADD R1, R1, R14
BL outputHexTruncated
SWI XOS_WriteS
DCB " sectors: ",0
ALIGN
MOV R1, R8
BL outputHexTruncated
SWI XOS_WriteS
DCB " data: ",0
ALIGN
LDR R1, [R12, #ADF_Buffer_Address - VARS]
BL outputHexTruncated
SWI XOS_NewLine
#endif
 LDR     R0, [R12, #File_Handle - VARS]	;read Track and Sector table in one go
 MOV     R1, R7					;address to load
 LDR     R2, [R12, #JFD_TrackSector_size - VARS]	;bytes to read
 SWI     XZLib_GZRead				;read delta tracks/sectors

 MOV     R10, R7				;track info pointer

 ._read_delta_tables_tracks
   LDR     R0, [R10], #4			;R0=offset into Sector table
   CMN     R0, #1				;does sector info exist for this track?
   BEQ     _next_track				;NO

   ADD     R6, R8, R0				;R6=pointer to sector info
   ._read_delta_tables_sectors
     LDR     R3, [R6], #8
     CMN     R3, #1				;last sector?
     BEQ     _next_track			; |+  go to next track

     TST     R3, #bit_delta_write		;is this sector a delta change?
     BEQ     _read_delta_tables_sectors		;NO

#if debug_Delta == 1	;Delta
SWI XOS_WriteS
DCB "Delta ", 0
SUB R1, R10, R7
MOV R1, R1, LSR #2
BL outputDecimal
SWI &100+ASC(".")
AND R1, R3, #&FF00
MOV R1, R1, LSR #8
BL outputDecimal
SWI XOS_NewLine
#endif

     AND     R14, R3, #%1111			;sector size bits
     ADD     R14, R14, #7
     MOV     R2, #1
     MOV     R2, R2, LSL R14			;R2=size
     LDR     R0, [R12, #ADF_Buffer_Address - VARS]
     LDR     R1, [R6, #-4]			;R1=offset to data
     ADD     R3, R1, R2
     STR     R3, [R12, #JFD_delta_offset - VARS]	;next free space
     ADD     R1, R1, R0				;R1=start of buffer

     ADD     R3, R1, R2				;R3=offset to end of sector
     LDR     R0, [R12, #DA_address - VARS]
     SUB     R4, R3, R0				;R4=offset in DA of end of sector
     LDR     R3, [R12, #DA_size - VARS]
     CMP     R4, R3				;do we need to expand the DA?
#if debug_Delta == 1	;Increase DA size
BLS _skip6
STMFD R13!, {R1}
SWI XOS_WriteS
DCB "Increasing DA size from ",0
ALIGN
MOV R1, R3
BL outputHexTruncated
SWI XOS_WriteS
DCB " to ",0
ALIGN
MOV R1, R4
BL outputHexTruncated
SWI XOS_NewLine
LDMFD R13!, {R1}
CMP R4, R3
#endif
._skip6
     BLHI    MemAlloc				;YES
     BVS     Entry_ADFMount_Exit

     LDR     R0, [R12, #File_Handle - VARS]
     SWI     XZLib_GZRead			;read delta
   B       _read_delta_tables_sectors

   ._next_track
   CMP     R10, R8				;last track?
 BNE     _read_delta_tables_tracks
LDMFD   R13!, {PC}


 ._task		DCB "TASK"
 ._pling        DCB "!*", 0
 ._filer_boot	DCB "Filer_Boot "
 ._filename	DCB "ADFFS:override.F"
 ._jfd_number	DCB "1111122"
 ._terminator	DCB "."
 ._leaf		DBB 32
 ._size
 ALIGN
