;*ADFSave
;---------
;Save an ADF/JFD image back to disc as an ADF file
;Entry:
; R0 - pointer to command tail / filename
; R1 - no. of parameters

;Exit:
; R12 - corrupt

.Entry_ADFSave
 STMFD   R13!, {R1-R11, R14}
 ADR     R12, VARS

 LDR     R1, [R12, #ADF_Mounted - VARS]
 TEQ     R1, #0				;is an image mounted?
 ADREQ   R0, Error_Disc_Empty		;NO,
 BEQ     _error				; |+ report an error

 TEQ     R1, #2				;is it an APD
 TEQNE   R1, #3				;is it a JFD?
 BEQ     _use_deflate			;YES, needs to be compressed

 MOV     R1, R0				;filename
 MOV     R2, #O_FileType		;FCE - FileCoreFloppyImage
 LDR     R4, [R12, #DA_address - VARS]	;start address
 LDR     R5, [R12, #ADF_Buffer_Length - VARS]
 ADD     R5, R5, R4			;end address
 MOV     R0, #10			;save block of memory to file and date stamp it
 SWI     XOS_File			;PRM2-35 save file
LDMFD   R13!, {R1-R11, PC}

 ._error
 MOV     R1, #1 << 31
 ADDS    R1, R1, R1
 LDMFD   R13!, {R1-R11, PC}


;Entry:
; R0 - filename pointer

 ._use_deflate
 MOV     R8, R0				;R8=filename
 MOV     R0, #Module_Claim
 MOV     R3, #streamCB.size		;claim space for stream control block
 SWI     XOS_Module			;PRM1-237
 BVS     _error
 MOV     R11, R2			;R11=streamCB

 MOV     R3, #ZLib_BufferSize		;claim space for compression buffer
 SWI     XOS_Module			;PRM1-237
 BVS     _error2
 MOV     R10, R2			;R10=compression buffer

 MOV     R0, #&8F
 MOV     R1, R8				;filename
 SWI     XOS_Find			;create file
 BVS     _error3
 MOV     R9, R0				;R9=file handle

 MOV     R0, #0				;initialise streamCB
 MOV     R1, #streamCB.size
 ._L1
   SUBS    R1, R1, #4
   STR     R0, [R11, R1]
 BNE     _L1
 STR     R10, [R11, #streamCB.next_out]
 MOV     R0, #ZLib_BufferSize
 STR     R0, [R11, #streamCB.avail_out]

 MOV     R0, R11
 MOV     R1, #Z_BEST_COMPRESSION
 MOV     R2, #Z_DEFLATED
 MOV     R3, #15+16
 MOV     R4, #9
 MOV     R5, #Z_DEFAULT_STRATEGY
 ADR     R6, _zlib_version
 MOV     R7, #streamCB.size
 SWI     XZLib_DeflateInit2

 ADR     R0, _JFD_validation		;add the verification header
 MOV     R1, #4
 BL      _deflate

 ADR     R0, JFD_tmp			;buffer address
 LDR     R3, [R0, #JFD_Release]		;update the modified count
 MOV     R2, R3, LSR #20		;R2=Major release
 EOR     R3, R3, R2, LSL #20		;clear major release
 ADD     R3, R3, #1			;increase minor version
 CMP     R3, #&100000			;has it wrapped?
 SUBHI   R3, R3, #1			;YES, cap
 ORR     R3, R3, R2			;put major release back
 STR     R3, [R0, #JFD_Release]

 MOV     R1, #0
 STR     R1, [R0, #JFD_Obey_Length]	;No obey file

 MOV     R1, #module_version
 STR     R1, [R0, #JFD_MinVersion]	;need this version of ADFFS to load

 MOV     R1, #JFD_Header - 4
 BL      _deflate			;compress the header

 LDR     R0, [R12, #DA_address - VARS]	;start address
 LDR     R1, [R12, #ADF_Buffer_Length - VARS]
 BL      _deflate
 BL      _write_final_buffer		;write what's left in the buffer

LDMFD   R13!, {R1-R11, PC}

 ._zlib_version		DCB "1.1.4", 0
 ._JFD_validation	DCB "JFDI"
 ALIGN

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

 STR     R0, [R11, #streamCB.next_in]
 STR     R1, [R11, #streamCB.avail_in]

 ._deflate_L1
   MOV     R0, R11
   MOV     R1, #Z_NO_FLUSH
   SWI     XZLib_Deflate
   TEQ     R0, #Z_OK			;did the deflate partially complete
   TEQNE   R0, #Z_STREAM_END
   ADDNE   R13, R13, #4			;drop return
   BNE     _deflate_error		;NO, must have errored

   LDR     R0, [R11, #streamCB.avail_out]
   TEQ     R0, #0			;is the output buffer full?
   BNE     _no_write			;NO
  
   BL      _write_buffer
   ADDVS   R13, R13, #4			;drop return
   BVS     _error4

   ._no_write
   LDR     R2, [R11, #streamCB.avail_in]
   TEQ     R2, #0			;any data left?
   LDREQ   PC, [R13], #4		;NO

 B       _deflate_L1


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

 ._write_final_buffer_L1
   MOV     R0, R11			;flush the stream
   MOV     R1, #Z_FINISH
   SWI     XZLib_Deflate		;YES
   TEQ     R0, #Z_OK			;did the deflate partially complete
   TEQNE   R0, #Z_STREAM_END		;NO, did it complete?
   ADDNE   R13, R13, #4			;NO, drop return
   BNE     _deflate_error		; |+ must have errored
   MOV     R5, R0			;R5=ZLib status
  
   BL      _write_buffer
   ADDVS   R13, R13, #4			;drop return
   BVS     _error4			;return error
  
   TEQ     R5, #Z_STREAM_END		;did the deflate partially complete
 BNE     _write_final_buffer_L1		;YES

 BL      _close_file

 MOV     R0, #Module_Free		;free claimed space
 MOV     R2, R10
 SWI     XOS_Module			;PRM1-238
 MOV     R2, R11
 SWI     XOS_Module			;PRM1-238

 MOV     R0, #18			;set filetype
 MOV     R1, R8				;filename
 MOV     R2, #O_FileType
 SWI     XOS_File			;PRM2-36
 LDR     PC, [R13], #4



._write_buffer
 LDR     R3, [R11, #streamCB.next_out]
 SUBS    R3, R3, R10			;anything to write?
 MOVEQ   PC, R14			;NO

 STR     R14, [R13, #-4]!
 MOV     R0, #2				;write stream data
 MOV     R1, R9				;file handle
 MOV     R2, R10			;buffer address
 SWI     XOS_GBPB

 STR     R10, [R11, #streamCB.next_out]	;reset output buffer
 MOV     R0, #ZLib_BufferSize
 STR     R0, [R11, #streamCB.avail_out]
 LDR     PC, [R13], #4


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

 MOV     R0, R11
 SWI     XZLib_DeflateEnd		;finalise the stream

 MOV     R0, #0
 MOV     R1, R9				;file handle
 SWI     XOS_Find
 LDR     PC, [R13], #4


 ._deflate_error
 ADR     R0, Error_ZLib
 
 ._error4
 MOV     R4, R0
 BL      _close_file
 MOV     R0, R4

 ._error3
 MOV     R4, R0				;free claimed space
 MOV     R0, #Module_Free
 MOV     R2, R10
 SWI     XOS_Module			;PRM1-238
 B       _error2_P1

 ._error2
 MOV     R4, R0				;free claimed space
 MOV     R0, #Module_Free
 ._error2_P1
 MOV     R2, R11
 SWI     XOS_Module			;PRM1-238
 MOV     R0, R4
 B       _error
