;Entry_ADFRemapVideoMemory
;------------------------
;Remaps video memory to <2000000 to fix games hardcoded for <=RO3.1
;Needs to be ARM600+ and RISCOS 3.5+ compatible
;
;Entry:
; R0 - command line in format "<video mode> <memory to reserve>"
;    - only one parameter indicates do not change mode.  ie "WIMP"
;    - =-1 if called from GOARM3JIT
; R1 - number of parameters
; R12 - pointer to module private word or unset if called internally
;
;Exit:
; R0 - error block if V set, corrupt otherwise

.Entry_ADFRemapVideoMemory
 STMFD   R13!, {R1-R9, R12, R14}
 ADR     R12, VARS

 MOV     R8, R0				;R8=commandline
 MOVS    R9, R1				;R9=no. of parameters
 BNE     _changemode			;parameters? YES
 BL      _shutdown			;NO, shutdown
LDMFD   R13!, {R1-R9, R12, PC}


 ._shutdown
 STMFD    R13!, {R14}
 #if compile_RO == 400
   ADR     R2, MEMC_L1PT
   LDR     R0, [R2]
   TEQ     R0, #0				;is there a Section for the old
   LDRNE   R1, L1PT_addr			;..MEMC address range?
   STRNE   R0, [R1, #&3600000 >> (20 - 2)]	;YES, put it back
   MOVNE   R0, #0
   STRNE   R0, [R2]
   ADRNE   R0, MMUControl_ARMop14
   MOVNE   R14, PC
   LDRNE   PC, [R0]				;flush the TLB
 #endif

 LDRB    R0, [R12, #is_screen_remapped - VARS]
 TEQ     R0, #0				;is the screen remapped?
 BLNE    unmap_screen_memory

 MOV     R0, #0
 STRB    R0, [R12, #remapping_video_memory - VARS]
 #if compile_RO == 400
   STR     R0, [R12, #DA2_delta - VARS]	;reset as we're shutting down
 #endif

 LDR     R1, [R12, #emulate_RISCOS - VARS]
 CMP     R1, #&350 << 8
 MOVLO   R1, #&350 << 8			;assume we're now emulating RO3.50
 LDR     R0, jit_code
 TEQ     R0, #0				;is the JIT still running?
 MVNEQ   R1, #0				;NO,
 BLEQ    remove_this_taskID		; |  remove this taskID
 TEQ     R0, #0
 BLEQ    release_DataAbort_Vector	; |+  shut down data abort vector

 STR     R1, [R12, #emulate_RISCOS - VARS]
LDMFD   R13!, {PC}


 ._changemode
 #if compile_RO == 400
   LDR     R1, L1PT_addr			;take a copy of the MEMC1
   LDR     R0, [R1, #&3600000 >> (20 - 2)]	;..address range in L1PT
   AND     R2, R0, #%11
   TEQ     R2, #%10				;is it a Section?
   TEMP    R2
   STREQ   R0, MEMC_L1PT			;YES, take a copy of it
   MOVEQ   R0, #0				; |  blank it
   STREQ   R0, [R1, #&3600000 >> (20 - 2)]	; |  update it
   BLEQ    MMUControl_ARMop14_SA		; |+ flush the TLB
   LOCK    R2
 #endif

 #if JIT_instruction_trace == 1
   BL      Create_Transient_DA		;create transient DA's
 #endif

 BL      get_taskID			;need the task ID so SWI's are handled
 LDR     R0, [R12, #emulate_RISCOS - VARS]
 CMP     R0, #&350 << 8
 MOVHI   R0, #&311 << 8			;assume we're now emulating RO3.11
 STRHI   R0, [R12, #emulate_RISCOS - VARS]
 MVN     R0, #0				;YES
 STRB    R0, [R12, #remapping_video_memory - VARS]

 TEQ     R9, #2				;*ADFRemapVideoMemory WIMP?
 #if use_overlay == 0 AND compile_RO > 311
   STRNE   R0, [R12, #closest_screen_mode - VARS]	;mark current MODE as unknown
 #endif
 BNE     _claim_vectors

 MOV     R1, R8				;command tail
 MOV     R0, #10 + (1<<30)		;base 10 number in range 0-255
 SWI     XOS_ReadUnsigned		;read the value PRM1-460
 LDMVSFD R13!, {R1-R9, R12, PC}		;exit on error
 MOV     R9, R2				;R9=mode

 MOV     R0, #10 + (1<<29)		;base 10 number with restricted range
 MOV     R2, #480			;max memory we can remap
 SWI     XOS_ReadUnsigned		;read the value PRM1-460
 LDMVSFD R13!, {R1-R9, R12, PC}		;exit on error
 MOV     R3, R2, LSL #10		;R3 = size in bytes
 #if compile_RO == 400
   BL      get_DA2_size
   LDRB    R14, [R12, #riscos6 - VARS]
   TEQ     R14, #0
   LDREQ   R14, DA2_size
   SUBEQ   R14, R3, R14
   STREQ   R14, [R12, #DA2_delta - VARS]	;fix RO4/6 SA
 #endif

 #if compile_IOMD == 1
; need to change mode before we claim the Abort vector to ensure DA 2
; can reduce to prevent hangs when DA 2 is currently > 480KB
   MOV     R0, #0
   MOV     R1, R9
   SWI     XOS_ScreenMode

   MOV     R0, #19			;workaround to avoid Red Squirrel
   SWI     XOS_Byte			;crashing when changing MODE directly
   SWI     XOS_Byte			;after altering DA2's size
   SWI     XOS_Byte
   SWI     XOS_Byte
 #endif

; now claim the Abort vector and change mode again so we can set IOMD vars
 BL      Claim_DataAbort_Vector		;claim DataAbort vector
 BVS     _error				;exit on error

 BL      _set_DA_2			;change the DA size
 MOV     R0, #0
 MOV     R1, R9
 SWI     XOS_ScreenMode
 BLVC    _set_DA_2			;change the DA size
 BLVC    get_screen_start		;get the display screen start
 LDMVCFD R13!, {R1-R9, R12, PC}		;exit, all done

._error
 MOV     R9, R0				;an error occurred
 BL      _shutdown
 MOV     R1, #1 << 31
 ADDS    R1, R1, R1			;set V
 MOV     R0, R9
LDMFD   R13!, {R1-R9, R12, PC}


._claim_vectors
 BL      Claim_DataAbort_Vector		;claim DataAbort vector
LDMFD   R13!, {R1-R9, R12, PC}




;_set_DA_2
;---------
;change the size of the Screen DA
;
;Entry:
; R3 - size in bytes
;
;Exit:
; R0 - corrupt or error if V set

._set_DA_2
 STMFD   R13!, {R1-R3, R14}

 MOV     R0, #DA2_magic_number		;read current screen size
 SWI     XOS_ReadDynamicArea		;PRM1-396
 SUBS    R1, R3, R1			;do we need to change the size?
 MOV     R0, #DA2_magic_number		;screen size
 SWINE   XOS_ChangeDynamicArea		;  |+ PRM1-384
 BVS     _set_DA_2_exit			;exit on error

 MOV     R0, #DA2_magic_number
 SWI     XOS_ReadDynamicArea		;did the command succeed? PRM1-396
 CMP     R1, R3				;is there >= what we need?
 MOVLO   R0, #1<<31			;NO
 ADDLOS  R0, R0, R0			;|+ set V
 ._set_DA_2_exit
 ADRVS   R0, Error_ScreenSize		;produce an error
LDMFD   R13!, {R1-R3, PC}
