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.

ASM > How do you do Hard Reset?

#102643 - Kirby - Fri Sep 15, 2006 9:21 pm

How do you do a proper Hard Reset in BIOS? I've tried adding asm("swi 0x26"); to my code, but it just freezes the game.

If you're wondering why I need it, it's because my game uses tileset maps that sometimes get changed, and switches and variables that get flipped. When someone gets a game over, I'd prefer to just Hard Reset the game so everything's new. Otherwise, I'd have to go around turing off EVERY switch and variable, and have Maps taking up twice as much memory, so I can reset maps like that.
_________________
Knock-knock.
Whose there?
Kirby.
Kirby-who?
I told you! Kirby!

#102653 - tepples - Fri Sep 15, 2006 11:08 pm

If you want to jump back to the state at which the BIOS enters your program, I'd say just do a RegisterRamReset followed by a SoftReset.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#102688 - Kirby - Sat Sep 16, 2006 4:04 am

tepples wrote:
If you want to jump back to the state at which the BIOS enters your program, I'd say just do a RegisterRamReset followed by a SoftReset.


I can't get the swi to work. I wrote a short program to test out the reset:

Code:
#include "gba_types.h"
#include "gba_regs.h"
#include "Bg.h"
#include "gba_video.h"
#include "gba_sprites.h"
#include "gba_keys.h"
#include "dispcnt.h"
#include "gba_defines.h"
#include "textsys.h"

int main()
{
   SetMode( MODE_0 | BG0_ENABLE );
   InitText();
   PlotText("Hi",1,1);
   while (1)
   {
      if (!(keyDown(KEY_A))) {break;}
      WaitForVsync();
   }
   while (1)
   {
      if (keyDown(KEY_A)) {break;}
      WaitForVsync();
   }
   PlotText("there",4,1);
   while (1)
   {
      if (!(keyDown(KEY_A))) {break;}
      WaitForVsync();
   }
   while (1)
   {
      if (keyDown(KEY_A)) {break;}
      WaitForVsync();
   }
   asm("swi 01");
   asm("swi 00");
}


gba_**** are just the normal gba_defines things... Textsys is a text system I created, and the program just writes "Hi", then press A, then "there", then press A, then reset to just saying "Hi". But when I test it anywhere, it crashes after the last A!

Basically what I'm trying to say it: What is the correct syntax of exceuting a BIOS function?
_________________
Knock-knock.
Whose there?
Kirby.
Kirby-who?
I told you! Kirby!

#102740 - zzo38computer - Sat Sep 16, 2006 3:40 pm

I think it is different in ARM mode and THUMB mode, you have to be careful!
_________________
Important: Please send messages about FWNITRO to the public forum, not privately to me.

#102748 - tepples - Sat Sep 16, 2006 5:55 pm

You may also have to set up registers before each SWI.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#102777 - Kirby - Sat Sep 16, 2006 10:54 pm

zzo38computer wrote:
I think it is different in ARM mode and THUMB mode, you have to be careful!

I think I am using THUMB mode, does it mean THUMB when I use:
Code:
-mthumb-interwork

Or do I have do do:
Code:
-mthumb -mthumb-interwork

I'm pretty sure the difference is that in THUMB, it's swi 0x01, while in ARM it's swi 0x010000.
tepples wrote:
You may also have to set up registers before each SWI.

What kind of registers? You mean the r0, r1 things? I've been reading up on SWI because I have NO ASM experience, mixed or pure, so even "mov r0,1%" mystifies me.
_________________
Knock-knock.
Whose there?
Kirby.
Kirby-who?
I told you! Kirby!

#102790 - tepples - Sat Sep 16, 2006 11:41 pm

Kirby wrote:
zzo38computer wrote:
I think it is different in ARM mode and THUMB mode, you have to be careful!

I think I am using THUMB mode, does it mean THUMB when I use:
Code:
-mthumb-interwork

This does ARM with interworking.

Quote:
Or do I have do do:
Code:
-mthumb -mthumb-interwork

This does Thumb with interworking.

Quote:
I'm pretty sure the difference is that in THUMB, it's swi 0x01, while in ARM it's swi 0x010000.

Correct.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#102797 - Kirby - Sun Sep 17, 2006 1:26 am

But how do you do the input thing? What, actually, do you have to input for RegisterRamReset and SoftReset if I just want to reset the game?
_________________
Knock-knock.
Whose there?
Kirby.
Kirby-who?
I told you! Kirby!

#102808 - tepples - Sun Sep 17, 2006 3:57 am

How about this? (untested)
Code:
void resetGBA(void) {

  // Set entry point for SoftReset (0: ROM; 1: EWRAM)
  *(volatile char *)0x03007FFA = 0;

  asm volatile (

    // RegisterRamReset:
    // Reset RAM and registers to power on state
    "ldr r0, #0xFF; swi 1;"

    // SoftReset:
    // Reset stack pointer and CPU control registers
    // and jump to the entry point selected by 0300:7FFA
    "swi 0;"
  );
}

_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#102810 - Kirby - Sun Sep 17, 2006 4:48 am

Thanx for your help, but what you said didn't really work. First, I found I WAS using ARM, so I had to change the SWI values. And then I prodded your code a bit... and:
Code:
void resetGBA(u16 para) {

  // Set entry point for SoftReset (0: ROM; 1: EWRAM)
  *(volatile char *)0x03007FFA = 0;

  asm volatile (

    // RegisterRamReset:
    // Reset RAM and registers to power on state
   "swi 0x010000;"

    // SoftReset:
    // Reset stack pointer and CPU control registers
    // and jump to the entry point selected by 0300:7FFA
    "swi 0x000000;"
  );
}

para is set to 255. I don't know if that's doing anything or not, but now, when I test the game, get a gameover, and press A, the game (seems to, at least) reset!
_________________
Knock-knock.
Whose there?
Kirby.
Kirby-who?
I told you! Kirby!

#102812 - tepples - Sun Sep 17, 2006 5:02 am

Kirby wrote:
Thanx for your help, but what you said didn't really work. First, I found I WAS using ARM, so I had to change the SWI values. And then I prodded your code a bit... and:
Code:
void resetGBA(u16 para) {

  // Set entry point for SoftReset (0: ROM; 1: EWRAM)
  *(volatile char *)0x03007FFA = 0;

  asm volatile (

    // RegisterRamReset:
    // Reset RAM and registers to power on state
   "swi 0x010000;"

    // SoftReset:
    // Reset stack pointer and CPU control registers
    // and jump to the entry point selected by 0300:7FFA
    "swi 0x000000;"
  );
}

para is set to 255.

Trouble is that it might not stay that way if GCC overwrites r0 while performing the *(volatile char *)0x03007FFA = 0; . But the RegisterRamReset isn't quite as critical as the SoftReset, so it might work anyway.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.