;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

 #if compile_RO == 400
   LDR     R0, [R12, #riscos6 - VARS]
   TEQ     R0, #0			;RISC OS 6?
   LDMNEFD R13!, {R1-R9, R12, PC}	;YES, exit silently
   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]
 #endif

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

 MOV     R0, #0
 STR     R0, [R12, #remapping_video_memory - VARS]

 LDR     R1, [R12, #emulate_RISCOS - VARS]
 CMP     R1, #&350 << 8
 MOVLO   R1, #&350 << 8			;assume we're now emulating RO3.11

 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!, {R1-R9, R12, PC}


 ._changemode
 #if compile_RO == 400
   LDR     R0, [R12, #riscos6 - VARS]
   TEQ     R0, #0			;RISC OS 6?
   BEQ     _not_riscos6			;NO

   MOV     R0, #1 << 31
   ADDS    R0, R0, R0			;set V
   ADR     R0, Error_RISCOS6
   LDMFD   R13!, {R1-R9, R12, PC}	;report error

   ._not_riscos6
 #endif

 #if compile_RO == 400
 ;@@@ need to claim this legally
   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)]	; |+ and update it
   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]
 STR     R0, [R12, #remapping_video_memory - VARS]

 TEQ     R9, #2				;*ADFRemapVideoMemory WIMP?
 MVNNE   R0, #0				;YES
 STRNE   R0, [R12, #closest_screen_mode - VARS]	;mark current MODE as unknown
 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_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
   BL      _set_DA_2			;change the DA size
   
   MOV     R0, R9
   SWI     XOS_WriteI + 22		;VDU 22 PRM1-594
   SWI     XOS_WriteC			;VDU 22, <video mode>
 #endif
; now claim the Abort vector and change mode again so we can set IOMD vars

 BL      Claim_DataAbort_Vector		;claim DataAbort vector
 LDMVSFD R13!, {R1-R9, R12, PC}		;exit on error

 BL      _set_DA_2			;change the DA size

 MOV     R0, R9
 SWI     XOS_WriteI + 22		;VDU 22 PRM1-594
 SWI     XOS_WriteC			;VDU 22, <video mode>

 BL      _set_DA_2			;change the DA size
 BL      get_screen_start		;get the display screen start
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}
 #if compile_RO == 400
   LDR     R14, os_version
   AND     R14, R14, #&FF00 << 8
   CMP     R14, #&400 << 8		;RO4?
   LDREQ   R14, cpu_id
   TEQEQ   R14, #CPUID_StrongARM	;YES, StrongARM?
   LDMEQFD R13!, {R1-R3, PC}		;exit if RO4/SA, DA size will be wrong
 #endif

 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}
