;vector_handler_disc_swap
;------------------------
;Called from SWI vector when certain keys are pressed, to load a disc image
;Actions a disc image change request

; R11 - pointer to VARS

.vector_handler_disc_swap
 LDRB    R14, [R11, #vectorHandler_swapdisc - VARS]	;are we dealing with the request?
 TEQ     R14, #0
 BNE     vector_handler_exit		;YES

 LDRB    R14, [R11, #Type_Mounted - VARS]	;do we have an image mounted?
 TEQ     R14, #Type_None
 STREQB  R14, [R11, #disk_swap_pending - VARS]	;NO, don't try to swap again
 BEQ     vector_handler_exit		; |+ exit

 LDR     R14, IRQsema			;check IRQsema
 LDR     R14, [R14, #0]
 TEQ     R14, #0			;called from an IRQ?
 #if compile_RO == 311
   LDREQ   R14, [R13, #SWI_stack.R14]	;get PC from stack
   TSTEQ   R14, #1 << 27		;are IRQ's are enabled?
 #else
   MRSEQ   R14, SPSR			;32bit, use SPSR
   TSTEQ   R14, #1 << 7			;are IRQ's are enabled?
 #endif
 BNE     vector_handler_exit		;NO, don't change disc yet

 STRB    R14, [R11, #vectorHandler_swapdisc - VARS]	;pending disc change
 ADD     R12, R13, #SWI_stack.size	;R12=address for state
 STMFD   R13!, {R0-R3, R7-R8}		;R7=address of the  digit to change
 MVN     R8, #0				;R8=disc number

 #if compile_RO == 311
   MOV     R0, PC			;26bit CPU
   STR     R0, [R12, #SWI_veneer.CPSR]	;store CPSR
   BIC     R0, R0, #%11 << 26		;clear IRQ/FIQ bits
   ORR     R0, R0, #%11			;SVC
   TEQP    R0, #0
 #else
   MRS     R0, CPSR			;32bit CPU
   STR     R0, [R12, #SWI_veneer.CPSR]	;store CPSR
   STR     R14, [R12, #SWI_veneer.SPSR]	;store SPSR
   BIC     R0, R14, #%11001111		;clear mode bits
   ORR     R0, R0, #%00000011		;SVC, enable interrupts
   MSR     CPSR_c, R0
 #endif
 #if compile_RO < 500
   NOP					;now in correct SVC mode
 #endif

 STR     R14, [R13, #-4]!		;preserve SVC R14

 LDRB    R1, [R11, #disk_swap_pending - VARS]
 LDR     R0, [R11, #Current_File_Mounted - VARS]	;now we need to load the correct disc
 MOV     R7, R0
 ._L1					;find end of filename
   LDRB    R3, [R7], #1
   TEQ     R3, #0
 BNE     _L1

 ._L2
   LDRB  R3, [R7, #-1]!			;get the previous char
   TEQ   R3, #ASC(".")			;have we hit the directory?
   TEQNE R7, R0				;have we hit the start of the file?
   BEQ   _unknown_disc

   CMP   R3, #ASC("0")			;is it a digit?
   BLO   _L2				;NO
   CMP   R3, #ASC("9")			;0..9?
 BHI   _L2				;NO
 MOV   R8, R1				;R8=next disc

 ._unknown_disc
 MOV     R3, R0				;preserve R0
					;write the DiscOp info to file
 LDR     R0, [R11, #recording_addr - VARS]	;file handle
 TEQ     R0, #0
 MVNNE   R0, #0
 ADDNE   R2, R11, #recordStack - VARS		;address of data
 STRNE   R0, [R2, #0*4]
 STRNE   R0, [R2, #1*4]
 STRNE   R0, [R2, #2*4]
 STRNE   R0, [R2, #3*4]
 STRNE   R0, [R2, #4*4]
 BLNE    record_discop

 CMN     R8, #1				;do we know the next disc number?
 BEQ     _exit				;NO, we can't swap discs

 BL      resetVectors			;reset key vectors
 STMFD   R13!, {R3-R6}
 MOV     R0, #17			;read file information
 MOV     R1, R3				;pointer to filename
 LDRB    R6, [R7, #0]			;get current disc number
 STRB    R8, [R7, #0]			;next disc number
 SWI     XOS_File			;PRM2-38
 STRB    R6, [R7, #0]			;put original disc number back
 LDMFD   R13!, {R3-R6}
 TEQ     R0, #1				;does the file exist?
 BNE     _next_disc_not_found		;NO

 STMFD   R13!, {R12}
 ADR     R12, VARS
 MOV     R1, #2				;notify ADFFlush it's an internal call
 BL      Entry_ADFFlush			;flush before we change the filename
 STRB    R8, [R7, #0]			;next disc number
 MOV     R0, R3				;pointer to filename
 BL      Entry_ADFMount			;mount the disc
 LDMFD   R13!, {R12}

 ._next_disc_not_found
 BL      resetVectors			;reset key vectors

 ._exit
 LDR     R14, [R13], #4			;preserve R14
 LDR     R0, [R12, #SWI_veneer.CPSR]	;original CPU mode
 #if compile_RO == 311
   TEQP    R0, #0			;26bit, use PC flags
   NOP					;now back in original CPU mode
 #else
   MSR     CPSR_all, R0
   NOP
   LDR     R0, [R12, #SWI_veneer.SPSR]	;restore SPSR
   MSR     SPSR_all, R0
 #endif

 MOV     R14, #0
 STRB    R14, [R11, #vectorHandler_swapdisc - VARS]	;allow disc swaps
 STRB    R14, [R11, #disk_swap_pending - VARS]	;allow key traps again
 LDMFD   R13!, {R0-R3, R7-R8}
B       vector_handler_exit
