Sonic Pocket Adventure's Debug Mode
#17
Posted 24 January 2011 - 03:59 AM
if you do it on the real hardware you're just creating an emulator's error by altering the game. that's kind of backwards as far as the issue?
It's not really an emulator error per say. When the emulator authors were reverse engineering games, they saw that 0xFF at 0x1F was needed for the game to load certain content. In Metal Slug 0xFF at 0x1F would enable certain sfx. The content they were seeing was actually debug or prototype data. The emulator authors did not know this and they assumed the extra content was a required part of the game so they forced it on.
With that said, the actual official debug cartridges would have 0xFF at 0x1F to denote they are debug carts or if that was not the case it would then be added in by the development NGPC machine. It's one or the other.
Anyways, I took the NeoPop emulator source code and modified it to do what Nemesis did years ago, and that is to have it generate the assembly as the emulator goes from place to place. I also had it generate a bitmap for every byte in the rom to denote if it is code or data.

The NGPC's Toshiba CPU uses a hideous assembly language.
This post has been edited by SANiK: 24 January 2011 - 04:00 AM
#18
Posted 24 January 2011 - 04:19 AM
The NGPC's Toshiba CPU uses a hideous assembly language.
Looks like an extension of the Z80 assembly language to me, along with "extended" 32-bit registers like XDE and XHL.
Anyways, it's interesting how they used the high byte of the RESET vector to indicate debug vs. production. I remember that many older Macintosh applications used the high byte of addresses for various flags, which caused all sorts of problems when the Macintosh II came out with its 68020 CPU.
#19
Posted 24 January 2011 - 05:31 AM
Now that's the most stupid emulation bug I've ever seen.
Also this reminds me of how Ultimate Mortal Kombat 3 on the Mega Drive uses the highest byte of the vector address to figure out what caused an error.
Also this reminds me of how Ultimate Mortal Kombat 3 on the Mega Drive uses the highest byte of the vector address to figure out what caused an error.
#21
Posted 24 January 2011 - 09:39 AM
I was looking in the debug sound test and noticed something... Where the hell is BGM 0026 MSP_EME used?
#23
Posted 24 January 2011 - 11:44 AM
I ever wanted to get the debug mode enabled. Great find!
For the vgm pack I used this sound test

BGM 0026 MSP_EME is used during the Special Ending.
Listen to 30b - 33 Special Ending (with SFX).vgm at 0:15.
For the vgm pack I used this sound test

BGM 0026 MSP_EME is used during the Special Ending.
Listen to 30b - 33 Special Ending (with SFX).vgm at 0:15.
#24
Posted 25 January 2011 - 09:28 PM
Anyone else getting crashes in NeoPop at the end of the level when you enable debug?
#25
Posted 25 January 2011 - 09:37 PM
I ever wanted to get the debug mode enabled. Great find!
For the vgm pack I used this sound test

BGM 0026 MSP_EME is used during the Special Ending.
Listen to 30b - 33 Special Ending (with SFX).vgm at 0:15.
For the vgm pack I used this sound test

BGM 0026 MSP_EME is used during the Special Ending.
Listen to 30b - 33 Special Ending (with SFX).vgm at 0:15.
How'd you get to that soundtest? My MP3 rip I had to do via a different one.
#28
Posted 26 January 2011 - 01:15 AM
How'd you get to that soundtest? My MP3 rip I had to do via a different one.
I used some guides to collect enough puzzle pieces to complete three puzzles (as the wiki says here).
I did this with NeoPop and copied the battery save into a save state of MESS.
The "eject"-button is used to get out of the menu.
#29
Posted 26 January 2011 - 02:09 AM
Anyone else getting crashes in NeoPop at the end of the level when you enable debug?
If you want the short story:
It's a NeoPop core simulation BIOS bug. NeoPop's core is used in a lot of NGPC emulators, but I have posted the bugfix to the multi-emu Mednafen's boards since it's the most active.
If you want a temporary fix for the bug then open up the Sonic Pocket Adventure rom in a hex editor, and change the 0xF0 at 0x3769C to 0x10.
This should the stop the crashing for that case only.
If you want the long story:
The NGPC has several system functions in the BIOS that can be accessed via the following assembly code:
CODE
LDF 3
LD w, #some function number here#
SWI 1
LD w, #some function number here#
SWI 1
NeoPop simulates the BIOS and SWI call in C once it detects it, and what it does for SWI #1 is that it takes w, multiplies it by 4, and adds it to 0xFFFE00 to get the address of the interrupt to execute. Then it jumps there.
This is the NeoPop code for that in TLCS900h_interpret_single.c
CODE
//===== SWI num
void sngSWI()
{
cycles = 16;
switch(first & 7)
{
//System Call
case 1: push32(pc);
pc = loadL(0xFFFE00 + (rCodeB(0x31) << 2));
break;
case 3: interrupt(0); //SWI 3
break;
case 4: interrupt(1); //SWI 4
break;
case 5: interrupt(2); //SWI 5
break;
case 6: interrupt(3); //SWI 6
break;
default: instruction_error("SWI %d is not valid.", first & 7);
break;
}
}
void sngSWI()
{
cycles = 16;
switch(first & 7)
{
//System Call
case 1: push32(pc);
pc = loadL(0xFFFE00 + (rCodeB(0x31) << 2));
break;
case 3: interrupt(0); //SWI 3
break;
case 4: interrupt(1); //SWI 4
break;
case 5: interrupt(2); //SWI 5
break;
case 6: interrupt(3); //SWI 6
break;
default: instruction_error("SWI %d is not valid.", first & 7);
break;
}
}
The problem area is pc = loadL(0xFFFE00 + (rCodeB(0x31) << 2));
rCodeB(0x31) is NeoPop's way of referring to the 8-bit register w in bank 3.
This is the code that causes the crash in the Sonic Pocket Adventure rom when debug is on:
CODE
0x237693: POP XDE, prevPC: 0xFF6FD8
0x237694: CP RA3,0, prevPC: 0x237693
0x237697: JR NZ,0x237677, prevPC: 0x237694
0x237699: LD RW3,0xF0, prevPC: 0x237697
0x23769D: LD RBC3,0x000C, prevPC: 0x237699
0x2376A2: LD XHL3,XDE, prevPC: 0x23769D
0x2376A5: SWI 1, prevPC: 0x2376A2
CRASH!
//SWI 1 trying to go to address 0x010001C0, CRASH!
0x237694: CP RA3,0, prevPC: 0x237693
0x237697: JR NZ,0x237677, prevPC: 0x237694
0x237699: LD RW3,0xF0, prevPC: 0x237697
0x23769D: LD RBC3,0x000C, prevPC: 0x237699
0x2376A2: LD XHL3,XDE, prevPC: 0x23769D
0x2376A5: SWI 1, prevPC: 0x2376A2
CRASH!
//SWI 1 trying to go to address 0x010001C0, CRASH!
We can see at 0x2376A SWI #1 is called, so why does it crash and why does it try to go to 0x010001C0?
If we look above the SWI #1 instruction to see what w is set to, we see:
LD RW3,0xF0
That loads register w in bank 3 with 0xF0.
What NeoPop does in SWI #1 is that it takes w which is 0xF0, multiplies it by 4 (which is what the << 2 does in the C code), and adds it to 0xFFFE00.
This gives you the bad address 0x010001C0 or 0x1C0 if we ignore the top byte.
I found a homebrew interrupt routine that implements SWI 1 as:
CODE
ldf 3
push XIX
and w,1F
add w,w
add w,w
ld XIX,0x00FFFE00
ld XIX,(XIX+W)
call XIX
pop XIX
reti
push XIX
and w,1F
add w,w
add w,w
ld XIX,0x00FFFE00
ld XIX,(XIX+W)
call XIX
pop XIX
reti
Notice how it Ands w with 0x1F before multiplying it by 4 (via the two adds)? This is something NeoPop does not do.
Obviously this is why NeoPop crashes. NeoPop was using 0xF0 stored in w when it should be doing (w & 0x1F) to get 0x10 instead of 0xF0.
So the reason Debug mode crashes is because it is a NeoPop emulator bug. To fix it, you would have to recompile the emulator and change in the above mentioned function from: pc = loadL(0xFFFE00 + (rCodeB(0x31) << 2)); to pc = loadL(0xFFFE00 + ((rCodeB(0x31) & 0x1F) << 2));
This post has been edited by SANiK: 10 March 2011 - 11:37 PM
#30
Posted 26 January 2011 - 04:26 AM
Anyone else getting crashes in NeoPop at the end of the level when you enable debug?
If you want a temporary fix for the bug then open up the Sonic Pocket Adventure rom in a hex editor, and change the 0xF0 at 0x3769C to 0x10.
This should the stop the crashing for that case only.
I'll give this a try. I'll try option #2 if I encounter anything else.


