; ********************** APD loader variables *************************
#set Max_Track_Count	= 166			; max tracks on an APD disc
#set Max_Sector_Count	= Max_Track_Count * 16	; max sectors - a guess
#set APD_Track_Buffer	= (Max_Track_Count * 4) + (Max_Sector_Count * 8)




;Entry:
; R12 - pointer to VARS

.Entry_ADFMount_APD			;read APD
 MOV     R4, #64 * 1024			;start with a 64KB buffer, extend as required
 BL      MemAlloc			;Allocate memory
 BLVC    init_crc_ccitt
 MOVVS   R2, #0				;if an error occurred, zero address
 MOVVS   R4, #0

 LDRVC   R2, [R12, #DA_address - VARS]	;increase start of buffer
 MOVVC   R3, #APD_Track_Buffer
 ADDVC   R1, R2, R3			;by size of APD track buffer
 STRVC   R1, [R12, #ADF_Buffer_Address - VARS]
 ADDVC   R4, R2, #Max_Track_Count * 4
 STR     R2, [R12, #JFD_Tracks - VARS]
 STR     R4, [R12, #JFD_Sectors - VARS]
 BVS     Entry_ADFMount_Exit		;exit on error

 BL      clear_track_sector_table

 LDR     R0, [R12, #File_Handle - VARS]	;file handle
 MOV     R1, #0
 MOV     R2, #0
 SWI     XZLib_GZSeek			;go back to beginning of file

 BL      APD_Read_File
 BVS     Entry_ADFMount_Exit		;exit on error

 ADD     R1, R12, #JFD_tmp - VARS	;buffer address
 LDR     R2, [R12, #DA_address - VARS]
 LDR     R3, [R12, #JFD_Tracks - VARS]
 SUB     R0, R3, R2			;offset to Track table
 ADD     R0, R0, #JFD_Header
 STR     R0, [R1, #JFD_Track_Table]
 LDR     R3, [R12, #JFD_Sectors - VARS]
 SUB     R5, R3, R2
 ADD     R5, R5, #JFD_Header
 STR     R5, [R1, #JFD_Sector_Table]	;offset to Sector table
 MOV     R4, #APD_Track_Buffer
 ADD     R4, R4, #JFD_Header
 STR     R4, [R1, #JFD_Data]		;offset to data
 LDR     R5, [R12, #DA_size - VARS]
 STR     R5, [R1, #JFD_Size]		;memory required to load
 SUB     R0, R4, R0			;R7 = size of Track+Sector table
 STR     R0, [R12, #JFD_TrackSector_size - VARS]	;store so we can expand if required

 MOV     R2, #Type_APD
 BL      floppy_type_changed

 MOV     R0, #0				;no error
B       Entry_ADFMount_mounted




;APD_Read_File
;-------------
;Read APD file read only
;
;Entry:
; R0 - pointer to filename
; R12 - pointer to VARS

.APD_Read_File
 STMFD   R13!, {R1-R5, R11, R14}

 MOV     R0, #Module_Claim		;claim space for APD header
 MOV     R3, #8 + (166*12)		;amount to claim
 SWI     XOS_Module			;PRM1-237
;### needs error code
 LDMVSFD R13!, {R1-R5, R11, PC}
 STR     R2, [R12, #tmp_Header - VARS]	;store address

 LDR     R0, [R12, #File_Handle - VARS]	;zlib file handle
 MOV     R1, R2				;buffer address
 MOV     R2, R3				;bytes to read
 SWI     XZLib_GZRead			;read the APD header
;### needs error code, R0<>Z_OK on error
 LDMVSFD R13!, {R1-R5, R11, PC}

 MOV     R0, #0
 STR     R0, [R12, #tmp_Header_Pos - VARS]	;position in header file

 LDR     R_buffer, [R12, #ADF_Buffer_Address - VARS]	;address we're writing too
 LDR     R_sectorinfo, [R12, #JFD_Sectors - VARS]	;sector table

 BL      APD_Read_Word			;read APDX string
 BL      APD_Read_Word			;read APD version
;### validate its okay

 MOV     R2, #8 + (166*12)		;start of track data
 MOV     R5, #0				;tracks counter
 MOV     R3, #8				;position of track length being read
 ._L1
   MOV     R0, R5, LSR #1
   ADD     R0, R0, R5, LSR #3		;R0 = 100/160 * R5
   BL      hourglass_percentage

   LDR     R0, [R12, #JFD_Tracks - VARS]	;pointer to track table
   LDR     R14, [R12, #JFD_Sectors - VARS]	;sector table
   SUB     R14, R_sectorinfo, R14	;ptr to start of track in sector table
   STR     R14, [R0, R5, LSL #2]	;store track start pointer

					;*****************************
   MOV     R0, R3			;SD track info pointer
   BL      APD_Read_Word_ABS		;read track length
   ADD     R3, R3, #4			;increase track info pointer
   MOVS    R_bitsleft, R0
   BEQ     _SD_Unformatted		;if length is 0, its unformatted

   ADD     R0, R0, #7
   MOV     R0, R0, LSR #3		;size of track data in bytes
   BL      APD_Read_Track
   ADD     R2, R2, R0			;increase file pointer

   MOV     R1, #1			;FileCore for SD
   BL      decodeFM			;decode FM data
   ._SD_Unformatted
					;*****************************

					;*****************************
   MOV     R0, R3			;DD track info pointer
   BL      APD_Read_Word_ABS		;read track length
   ADD     R3, R3, #4			;increase track info pointer
   MOVS    R_bitsleft, R0
   BEQ     _DD_Unformatted		;if length is 0, its unformatted

   ADD     R0, R0, #7
   MOV     R0, R0, LSR #3		;size of track data in bytes
   BL      APD_Read_Track
   ADD     R2, R2, R0			;increase file pointer

   MOV     R1, #2			;FileCore for DD
   BL      decodeMFM		;decode MFM data
   ._DD_Unformatted
					;*****************************

					;*****************************
   MOV     R0, R3			;QD track info pointer
   BL      APD_Read_Word_ABS		;read track length
   ADD     R3, R3, #4			;increase track info pointer
   MOVS    R_bitsleft, R0
   BEQ     _QD_Unformatted		;if length is 0, its unformatted

   ADD     R0, R0, #7
   MOV     R0, R0, LSR #3		;size of track data in bytes
   BL      APD_Read_Track
   ADD     R2, R2, R0			;increase file pointer

   MOV     R1, #4			;FileCore for QD
   BL      decodeMFM		;decode MFM data
   ._QD_Unformatted
					;*****************************

   LDR     R0, [R12, #JFD_Sectors - VARS]	;sector table
   SUB     R14, R_sectorinfo, R0	;get offset within table
   LDR     R0, [R12, #JFD_Tracks - VARS]	;track table
   LDR     R1, [R0, R5, LSL #2]		;load sector pointer of current track
   SUBS    R14, R14, R1			;did we find any sectors?
   MVN     R14, #0
   STREQ   R14, [R0, R5, LSL #2]	;NO, mark track as unformatted
   STRNE   R14, [R_sectorinfo], #4	;YES, terminate sector info
					;.. for this track

   ADD     R5, R5, #1			;increase track counter
   TEQ     R5, #Max_Track_Count
 BNE     _L1

 BL      Reduce_DynamicArea		;hand back any unused memory
 BL      free_temp_track
LDMFD   R13!, {R1-R5, R11, PC}




;APD_Read_Track
;--------------
;Read one track into memory and pre-read the first two words
;
;Entry:
; R2 - file position pointer
; R0 - number of bytes to read
; R12 - pointer to VARS
;
;Exit:
; R_curbit  - 1st word of track
; R_nextbit - 2nd word of track
; R_bitrot  - 32

.APD_Read_Track
 STMFD   R13!, {R0-R4, R14}

 BL      allocate_temp_track		;R4=file position pointer
 STRVS   R0, [R13, #0]
 LDMVSFD R13!, {R0-R4, PC}
					;R2=buffer address
					;R3=stream size
					;R4=file position pointer

 LDR     R0, [R12, #File_Handle - VARS]	;zlib file handle
 MOV     R1, R4				;position in decompressed data
 MOV     R2, #0				;read absolute
 SWI     XZLib_GZSeek			;go to the start of the track
;### needs error code

 LDR     R0, [R12, #File_Handle - VARS]	;zlib file handle
 LDR     R1, [R12, #tmp_Track - VARS]	;buffer
 MOV     R2, R3				;bytes to read
 SWI     XZLib_GZRead			;read the track in
;### needs error code

 LDR     R2, [R12, #MFM_Stream_Pos - VARS]	;position in track
 LDR     R0, [R2], #4			;load the first word
 BL      little_endian
 MOV     R_curbit, R0
 LDR     R0, [R2], #4			;load the next word
 BL      little_endian
 MOV     R_nextbit, R0
 STR     R2, [R12, #MFM_Stream_Pos - VARS]	;store updated pointer back

 MOV     R_bitrot, #32			;bits remaining in next word
LDMFD   R13!, {R0-R4, PC}





;APD_Read_Word_ABS
;-----------------
;Read one 32 bit word from file at an absolute address
;
;Entry:
; R0 - position pointer
; R12 - pointer to VARS
;
;Exit:
; R0 - word

.APD_Read_Word_ABS
 STMFD   R13!, {R1, R14}
.APD_Read_Word2
 ADD     R1, R0, #4			;update position pointer
 STR     R1, [R12, #tmp_Header_Pos - VARS]

 LDR     R1, [R12, #tmp_Header - VARS]	;address of buffer
 LDR     R0, [R1, R0]			;load word
LDMFD   R13!, {R1, PC}




;APD_Read_Word
;-------------
;Read one 32 bit word from file
;
;Entry:
; R12 - pointer to VARS
;Exit:
; R0 - word

.APD_Read_Word
 STMFD   R13!, {R1, R14}

 LDR     R0, [R12, #tmp_Header_Pos - VARS]	;get current position pointer
 B       APD_Read_Word2
