gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Code to make EZ4 go back to menu

#178756 - Sterophonick - Sat Aug 05, 2017 3:24 am

Does anybody know how to make the EZ-Flash IV go back to the menu without using the GSS Patch, where you have a key combination to make it happen?

to clarify, I mean some code in the compiled ROM to make the GBA stop running the game code, and start running the ez4 loader code. I tried this using a system call, and it didn't work.

Thank

#178764 - Dwedit - Mon Aug 21, 2017 2:20 pm

I think the write sequence might be this:
Make sure the code that performs these writes is running from RAM, not ROM.

0x9FE0000 = 0xD200
0x8000000 = 0x1500
0x8020000 = 0xD200
0x8040000 = 0x1500
0x9880000 = 0x8000
0x9FC0000 = 0x1500

#178765 - Sterophonick - Tue Aug 22, 2017 12:07 am

How do I make them run from RAM, and can you make some C code for that or naw?

#178766 - Dwedit - Wed Aug 23, 2017 4:23 pm

There's an implementation in PocketNES of resetting EZ, Visoly, M3, G6, and Supercard. Source Code Link
It's in ASM rather than C, but not that hard to integrate.

Snippet from IO.S that calls the code: (The actual code is in Visoly.s)
This piece is simple enough to convert to C code.

Code: Select all

doReset:
	mov r1,#REG_BASE
	mov r0,#0
	strh r0,[r1,#REG_DM0CNT_H]	@stop all DMA
	strh r0,[r1,#REG_DM1CNT_H]
	strh r0,[r1,#REG_DM2CNT_H]
	strh r0,[r1,#REG_DM3CNT_H]
	add r1,r1,#0x200
	str r0,[r1,#8]		@interrupts off

	@copy code to EWRAM and execute it	
	ldr r0,=0x02000000		@Pick some address in EWRAM that you're not using
	ldr r1,=VISOLY_START	@source address
	ldr r2,=VISOLY_END	@end
	sub r2,r2,r1		@subtract to get size
	mov lr,r0
	ldr r12,=memcpy
	bx r12

#178767 - Sterophonick - Thu Aug 24, 2017 11:41 pm

I tested this, while compiling with DevKitPro, and nothing happens.

Code: Select all

REG_BASE		= 0x4000000
 REG_DISPCNT		= 0x00
 REG_DISPSTAT	= 0x04
 REG_VCOUNT		= 0x06
 REG_BG0CNT		= 0x08
 REG_BG1CNT		= 0x0A
 REG_BG2CNT		= 0x0C
 REG_BG3CNT		= 0x0E
 REG_BG0HOFS		= 0x10
 REG_BG0VOFS		= 0x12
 REG_BG1HOFS		= 0x14
 REG_BG1VOFS		= 0x16
 REG_BG2HOFS		= 0x18
 REG_BG2VOFS		= 0x1A
 REG_BG3HOFS		= 0x1C
 REG_BG3VOFS		= 0x1E
 REG_WIN0H		= 0x40
 REG_WIN1H		= 0x42
 REG_WIN0V		= 0x44
 REG_WIN1V		= 0x46
 REG_WININ		= 0x48
 REG_WINOUT		= 0x4A
 REG_BLDCNT		= 0x50
 REG_BLDALPHA	= 0x52
 REG_BLDY		= 0x54
 REG_SG1CNT_L	= 0x60
 REG_SG1CNT_H	= 0x62
 REG_SG1CNT_X	= 0x64
 REG_SG2CNT_L	= 0x68
 REG_SG2CNT_H	= 0x6C
 REG_SG3CNT_L	= 0x70
 REG_SG3CNT_H	= 0x72
 REG_SG3CNT_X	= 0x74
 REG_SG4CNT_L	= 0x78
 REG_SG4CNT_H	= 0x7c
 REG_SGCNT_L		= 0x80
 REG_SGCNT_H		= 0x82
 REG_SGCNT_X		= 0x84
 REG_SGBIAS		= 0x88
 REG_SGWR0_L		= 0x90

 REG_SOUND1CNT_L	= 0x60
 REG_SOUND1CNT_H	= 0x62
 REG_SOUND1CNT_X	= 0x64
 REG_SOUND2CNT_L	= 0x68
 REG_SOUND2CNT_H	= 0x6C
 REG_SOUND3CNT_L	= 0x70
 REG_SOUND3CNT_H	= 0x72
 REG_SOUND3CNT_X	= 0x74
 REG_SOUND4CNT_L	= 0x78
 REG_SOUND4CNT_H	= 0x7c
 REG_SOUNDCNT_L	= 0x80
 REG_SOUNDCNT_H	= 0x82
 REG_SOUNDCNT_X	= 0x84
 REG_SOUNDBIAS	= 0x88
 REG_SOUNDWR0_L	= 0x90

 REG_FIFO_A_L	= 0xA0
 REG_FIFO_A_H	= 0xA2
 REG_FIFO_B_L	= 0xA4
 REG_FIFO_B_H	= 0xA6
 REG_DM0SAD		= 0xB0
 REG_DM0DAD		= 0xB4
 REG_DM0CNT_L	= 0xB8
 REG_DM0CNT_H	= 0xBA
 REG_DM1SAD		= 0xBC
 REG_DM1DAD		= 0xC0
 REG_DM1CNT_L	= 0xC4
 REG_DM1CNT_H	= 0xC6
 REG_DM2SAD		= 0xC8
 REG_DM2DAD		= 0xCC
 REG_DM2CNT_L	= 0xD0
 REG_DM2CNT_H	= 0xD2
 REG_DM3SAD		= 0xD4
 REG_DM3DAD		= 0xD8
 REG_DM3CNT_L	= 0xDC
 REG_DM3CNT_H	= 0xDE

 REG_DMA0SAD	= 0xB0
 REG_DMA0DAD	= 0xB4
 REG_DMA0CNT_L	= 0xB8
 REG_DMA0CNT_H	= 0xBA
 REG_DMA1SAD	= 0xBC
 REG_DMA1DAD	= 0xC0
 REG_DMA1CNT_L	= 0xC4
 REG_DMA1CNT_H	= 0xC6
 REG_DMA2SAD	= 0xC8
 REG_DMA2DAD	= 0xCC
 REG_DMA2CNT_L	= 0xD0
 REG_DMA2CNT_H	= 0xD2
 REG_DMA3SAD	= 0xD4
 REG_DMA3DAD	= 0xD8
 REG_DMA3CNT_L	= 0xDC
 REG_DMA3CNT_H	= 0xDE

 REG_TM0CNT_L	= 0x100
 REG_TM0CNT_H	= 0x102
 REG_TM1CNT_L	= 0x104
 REG_TM1CNT_H	= 0x106
 REG_TM2CNT_L	= 0x108
 REG_TM2CNT_H	= 0x10A
 REG_TM3CNT_L	= 0x10C
 REG_TM3CNT_H	= 0x10E
 REG_IE			= 0x200
 REG_IME			= 0x208
 REG_IF			= 0x4000202
 REG_P1			= 0x4000130
 REG_P1CNT		= 0x132
 REG_WAITCNT		= 0x4000204

 REG_SIOMULTI0	= 0x20 @+100
 REG_SIOMULTI1	= 0x22 @+100
 REG_SIOMULTI2	= 0x24 @+100
 REG_SIOMULTI3	= 0x26 @+100
 REG_SIOCNT		= 0x28 @+100
 REG_SIOMLT_SEND	= 0x2a @+100
 REG_RCNT		= 0x34 @+100
.arm
.text
.global main
get_word:
	movs r4,r4			@any left in the run?  jump ahead
	bne 1f
	ldr r12,[r2],#4		@read address
	movs r12,r12		@if address == 0, or address > 65536, it's a legitimate address.
	bxeq lr
	cmp r12,#0x00010000	@otherwise, it's a RLE length
	bxgt lr
	sub r4,r12,#1		@process first word
	ldr r12,[r2],#4
	bx lr
1:
	ldr r12,[r2,#-4]	@read old word again
	sub r4,r4,#1		@decrease remaining count
	bx lr
	get_hword:
	movs r5,r5			@any left in the run?  jump ahead
	bne 1f
	ldrh r0,[r3],#2		@read data
	movs r0,r0			@if data == 0, or data > 512, it's a proper data word
	bxeq lr
	cmp r0,#0x0200		@otherwise it's a RLE length
	bxgt lr
	sub r5,r0,#1		@process first halfword
	ldrh r0,[r3],#2
	bx lr
1:
	ldrh r0,[r3,#-2]	@read old halfword again
	sub r5,r5,#1		@decrease remaining count
	bx lr
do_reads:
	stmfd sp!,{lr}
0:
	bl get_word			@Get the address to read from
	ldrh r0,[r12]		@perform the read
	subs r1,r1,#1		@decrease remaining
	bne 0b				@repeat for the next address

	ldmfd sp!,{pc}

do_writes:
	stmfd sp!,{lr}
0:
	bl get_word			@Get the address to write to
	bl get_hword		@Get the value to write
	strh r0,[r12]		@perform the write
	subs r1,r1,#1		@decrease remaining
	bne 0b				@repeat for the next address and value
	
	ldmfd sp!,{pc}
rom_addresses:
	@ez flash
	.word 0x9FE0000
	.word 0x8000000
	.word 0x8020000
	.word 0x8040000
	.word 0x9880000
	.word 0x9FC0000

	@SC
	.word 4
	.word 0x09FFFFFE

	@Visoly
	.word   (0x00987654 * 2) + 0x08000000
	.word   1001
	.word   (0x00012345 * 2) + 0x08000000
	.word   (0x00987654 * 2) + 0x08000000
	.word   (0x00012345 * 2) + 0x08000000
	.word   (0x00765400 * 2) + 0x08000000
	.word   (0x00013450 * 2) + 0x08000000
	.word   500
	.word   (0x00012345 * 2) + 0x08000000
	.word   (0x00987654 * 2) + 0x08000000
	.word	0x096B592E

	@M3  (reads)
	.word 0x08E00002
	.word 0x0800000E
	.word 0x08801FFC
	.word 0x0800104A
	.word 0x08800612
	.word 0x08000000
	.word 0x08801B66
	.word 0x08800008
	.word 0x0800080E
	.word 0x08000000
	.word 0x080001E4
	.word 0x080001E4
	.word 0x08000188
	.word 0x08000188
    
	@G6  (reads)
	.word 0x09000000
	.word 0x09FFFFE0
	.word 3
	.word 0x09FFFFEC
	.word 3
	.word 0x09FFFFFC
	.word 3
	.word 0x09FFFF4A
	.word 0x09200000
	.word 0x09FFFFF0
	.word 0x09FFFFE8	
	data_values:
	@ez_flash
	.hword 0xD200
	.hword 0x1500
	.hword 0xD200
	.hword 0x1500
	.hword 0x8000
	.hword 0x1500

	@SC	
	.hword 0xA55A
	.hword 0xA55A
	.hword 0
	.hword 0

	@visoly
	.hword 0x5354
	.hword 500
	.hword 0x1234
	.hword 0x5354
	.hword 500
	.hword 0x5678
	.hword 0x5354
	.hword 0x5354
	.hword 0x5678
	.hword 0x1234
	.hword 500
	.hword 0xABCD
	.hword 0x5354
	.hword 0

	.pool

VISOLY_START:
	adr r2,rom_addresses	@the addresses to write to/read from  (or special numbers indicating a run)
	adr r3,data_values		@the 16-bit data values to write (or special numbers indicating a run)
	mov r4,#0	@r4 = number of same address in a run (address values smaller than 65536 indicate this)
	mov r5,#0	@r5 = number of same 16-bit values to write (data values smaller than 512 indicate this)
	
	@ reset EZ FLASH, SC, Visoly
	ldr r1,=6+4+8+1500	@6 writes for EZ, 4 writes for supercard, 1508 writes for Visoly, total is 1518
	bl do_writes
	
	@ reset M3, G6
	mov r1,#14+14	@14 reads for M3, 14 reads for G6
	bl do_reads
	
	mov		r0, #0
	ldr		r1,=0x3007ffa	@must be 0 before swi 0x00 is run, otherwise it tries to start from 0x02000000.
	strh		r0,[r1]

	mov		r0, #8		@VRAM clear
	swi		0x010000
	@Reboot
	swi		0x000000


@	ldmfd sp!,{lr,r4,r5}
@	bx lr
VISOLY_END:

		.pool
        @.enda
main:
  mov r1,#REG_BASE 
   mov r0,#0 
   strh r0,[r1,#REG_DM0CNT_H]   @stop all DMA 
   strh r0,[r1,#REG_DM1CNT_H] 
   strh r0,[r1,#REG_DM2CNT_H] 
   strh r0,[r1,#REG_DM3CNT_H] 
   add r1,r1,#0x200 
   str r0,[r1,#8]      @interrupts off 

   @copy code to EWRAM and execute it    
   ldr r0,=0x02000000      @Pick some address in EWRAM that you're not using 
   ldr r1,=VISOLY_START   @source address 
   ldr r2,=VISOLY_END   @end 
   sub r2,r2,r1      @subtract to get size 
   mov lr,r0 
   ldr r12,=memcpy 
   bx r12