Homebrew Emulation GameYob, a gameboy emulator for DS

Kouen Hasuki

Coffee Addict
Member
Joined
Jan 9, 2013
Messages
1,387
Trophies
1
Age
40
Location
Behind you
XP
681
Country
Norway
Posted a few more game compatibility notes, I'm putting a new thread per game to save mix up and ease of reply to the situation of fixing the release to make sure no one misunderstands what fix is for what
 

Coto

-
Member
Joined
Jun 4, 2010
Messages
2,979
Trophies
2
XP
2,565
Country
Chile
I don't totally understand. I can't really interpret the output of a guru meditation error, just a few lines. Correct me if I'm wrong but aren't guru meditation errors about crashes on arm9, not arm7? I know there are potential issues with arm9 and arm7 communication, relating to sound. But can you explain how you interpreted the error screen? (in fact, which error screen?)
[the screenie]
gyoberror.jpg


[now how to figure out a guru error]

http://www.console-dev.de/2009/09/20/guru-meditation-error-data-abort-exception/
[/end]

There a guy explains everything related to (and where the guru meditation error comes from), and how to interpret a memory leak. there's even a exe program that converts the guru adresses on where the system crashed and it's translated into the main.c (where you've built the elf) plus the line where the leak ocurred.

Optionally[ala old school], based off the link register (LR) (on ARM architectures) handles the last main address the program should jump to after a function ends. In this case FFFF0290, so this is the last well known main offset (32-bit) before gameyob died.

PC is halted at 0100029C, so program counter hangs at 16777864 cicles. While writing to address 00000000. how many times did it write 00000000? well this may be innacurate. but PC halted at 0100029C, AND begun writing zeros at 01000294, so C-4= 8 times written zeroes.

The stack pointer (the current top temp physical memory) is at B003DE8.

the numbers below [last 80 bytes, jumping from 8 bytes each] show a memory dump starting from 0B003DE8 [TOP stack address].

if you look closely on the (dump) offset 0B00:3DF8 the stack frame carrying the value 04000000() (ARM7 I/O access) seemed to die there. (now this is PURE and vague suspicion , but a memory leak of this kind could mean the current sound carry flag was busy, meaning the return value of the "sound" carry register [flag] wasn't properly checked)

that's why I said it could be an ARM7 issue, but i've just started to get guru errors (along with assembly).

edit:

NDS9 Memory Map
00000000h Instruction TCM (32KB) (not moveable) (mirror-able to 1000000h)
0xxxx000h Data TCM (16KB) (moveable)
02000000h Main Memory (4MB)
03000000h Shared WRAM (0KB, 16KB, or 32KB can be allocated to ARM9)
04000000h ARM9-I/O Ports
05000000h Standard Palettes (2KB) (Engine A BG/OBJ, Engine B BG/OBJ)
06000000h VRAM - Engine A, BG VRAM (max 512KB)
06200000h VRAM - Engine B, BG VRAM (max 128KB)
06400000h VRAM - Engine A, OBJ VRAM (max 256KB)
06600000h VRAM - Engine B, OBJ VRAM (max 128KB)
06800000h VRAM - "LCDC"-allocated (max 656KB)
07000000h OAM (2KB) (Engine A, Engine B)
08000000h GBA Slot ROM (max. 32MB)
0A000000h GBA Slot RAM (max. 64KB)
FFFF0000h ARM9-BIOS (32KB) (only 3K used)
The ARM9 Exception Vectors are located at FFFF0000h. The IRQ handler redirects to [DTCM+3FFCh].

NDS7 Memory Map
00000000h ARM7-BIOS (16KB)
02000000h Main Memory (4MB)
03000000h Shared WRAM (0KB, 16KB, or 32KB can be allocated to ARM7)
03800000h ARM7-WRAM (64KB)
04000000h ARM7-I/O Ports
04800000h Wireless Communications Wait State 0 (8KB RAM at 4804000h)
04808000h Wireless Communications Wait State 1 (I/O Ports at 4808000h)
06000000h VRAM allocated as Work RAM to ARM7 (max. 256K)
08000000h GBA Slot ROM (max. 32MB)
0A000000h GBA Slot RAM (max. 64KB)
The ARM7 Exception Vectors are located at 00000000h. The IRQ handler redirects to [3FFFFFCh aka 380FFFCh].

Further Memory (not mapped to ARM9/ARM7 bus)
3D Engine Polygon RAM (52KBx2)
3D Engine Vertex RAM (72KBx2)
Firmware (256KB) (built-in serial flash memory)
GBA-BIOS (16KB) (not used in NDS mode)
NDS Slot ROM (serial 8bit-bus, max. 4GB with default protocol)
NDS Slot FLASH/EEPROM/FRAM (serial 1bit-bus)

Shared-RAM
Even though Shared WRAM begins at 3000000h, programs are commonly using mirrors at 37F8000h (both ARM9 and ARM7). At the ARM7-side, this allows to use 32K Shared WRAM and 64K ARM7-WRAM as a continous 96K RAM block.

Undefined I/O Ports
On the NDS (at the ARM9-side at least) undefined I/O ports are always zero.

according to http://nocash.emubase.de/gbatek.htm#dsmemorymaps
those are hardware fixed offsets so ARM7 and ARM9 must be accessed separately

edit2:

but... but... i know what you'll say:

how the stack frame can transfer 32-bit values, and if the 04000000 was pure coincidence? well, if we were to check the first 4bits of those 32-bits values, we'd figure that, in fact [by checking the address map i've posted before], the real 32 bits values [and it's hardware flags] are referring to a physical area on the general DS I/O map, and based off the very register, we could denote if hardware at that area, was expecting a certain flag.. or not, against the flag sent on the stack frame.
 

Deleted member 319809

MAH BOI/GURL
Member
Joined
Dec 22, 2012
Messages
900
Trophies
0
XP
461
Country
Canada
To fully interpret the PC register of a Guru Meditation, you need to get the addresses of the instructions in your program's address space.

To do this, first disassemble the ARM9 and ARM7 parts:
Code:
cd wherever/GameYob/is
"$DEVKITARM"/bin/arm-none-eabi-objdump -d arm9/gameyob.elf > gameyob-arm9.dump
"$DEVKITARM"/bin/arm-none-eabi-objdump -d arm7/gameyob.elf > gameyob-arm7.dump

Then search in these files:
Code:
less gameyob-arm9.dump
Use the character / at the less prompt, then type the address at PC, in lower case and without its leading zeroes, followed by a colon (:), then Return. For example, if PC is 0100029C, type /100029c: Return.

As Coto said, the program counter may have been updated to point to the next instruction already, so look 4 bytes earlier for the cause of the Guru Meditation.

In this example, taking my latest compiled GameYob, 0100029C is here:
Code:
Disassembly of section .itcm:

01000100 <_Z9updateLCDi>:
[...]
 1000298:       eaffffbd        b       1000194 <_Z9updateLCDi+0x94>
 100029c:       e594c040        ldr     ip, [r4, #64]   ; 0x40
 

Coto

-
Member
Joined
Jun 4, 2010
Messages
2,979
Trophies
2
XP
2,565
Country
Chile
To fully interpret the PC register of a Guru Meditation, you need to get the addresses of the instructions in your program's address space.

To do this, first disassemble the ARM9 and ARM7 parts:
Code:
cd wherever/GameYob/is
"$DEVKITARM"/bin/arm-none-eabi-objdump -d arm9/gameyob.elf > gameyob-arm9.dump
"$DEVKITARM"/bin/arm-none-eabi-objdump -d arm7/gameyob.elf > gameyob-arm7.dump

Then search in these files:
Code:
less gameyob-arm9.dump
Use the character / at the less prompt, then type the address at PC, in lower case and without its leading zeroes, followed by a colon (:), then Return. For example, if PC is 0100029C, type /100029c: Return.

As Coto said, the program counter may have been updated to point to the next instruction already, so look 4 bytes earlier for the cause of the Guru Meditation.

In this example, taking my latest compiled GameYob, 0100029C is here:
Code:
Disassembly of section .itcm:
 
01000100 <_Z9updateLCDi>:
[...]
1000298:      eaffffbd        b      1000194 <_Z9updateLCDi+0x94>
100029c:      e594c040        ldr    ip, [r4, #64]  ; 0x40

what does r4? carries sound data? ..

ip means instruction pointer right? isn't that one from x86? and shouldn't be link register instead??
 

Deleted member 319809

MAH BOI/GURL
Member
Joined
Dec 22, 2012
Messages
900
Trophies
0
XP
461
Country
Canada
It's used to carry the value of a local variable in the function updateLCD, as assigned by the compiler. None of the registers "carry" anything persistent in this emulator, because it's not in pure ARM ASM. :)
 

avenir

Well-Known Member
Member
Joined
Dec 8, 2010
Messages
375
Trophies
0
XP
93
Country
United States
Oh I didn't know there comes this nice stuff. Let me start to compile git ^^

1. DSTwo launcher
https://sourceforge.net/p/nesds/cod...366f783/tree/arm9/source/romloader_frontend.c
This code supports BAGplug/iMenu/moonshell2 [edit] and menudo as well as usual ARGV.
If you don't have sf.net account, use: git clone git://git.code.sf.net/p/nesds/code nesds-code
2. soft reset
What is called soft reset recently relies on hbmenu.
http://devkitpro.org/wiki/Homebrew_Menu#Exit_to_Menu_Protocol
so, to exit safely, 0x02ff4000-0x03000000 memory region must not be written.
By the way, if bootstub isn't loaded, you can return to DSi menu, using this code:
https://sourceforge.net/p/nesds/cod...3a754f0fb607b3366f783/tree/arm7/source/arm7.c (sys_exit())
 

LWares87

Well-Known Member
Member
Joined
Oct 19, 2008
Messages
1,706
Trophies
0
Location
Colchester, England
XP
565
Country
United Kingdom
I've had this since it's first ever release and I'm quite impressed with out this has turned out so far (especailly with NiFi support being added).

So, anyway for now... keep up the good work! :)
 

Drenn

Well-Known Member
OP
Member
Joined
Feb 22, 2013
Messages
574
Trophies
0
XP
696
Country
Canada
[the screenie]
--

[now how to figure out a guru error]

http://www.console-dev.de/2009/09/20/guru-meditation-error-data-abort-exception/
[/end]

There a guy explains everything related to (and where the guru meditation error comes from), and how to interpret a memory leak. there's even a exe program that converts the guru adresses on where the system crashed and it's translated into the main.c (where you've built the elf) plus the line where the leak ocurred.

Optionally[ala old school], based off the link register (LR) (on ARM architectures) handles the last main address the program should jump to after a function ends. In this case FFFF0290, so this is the last well known main offset (32-bit) before gameyob died.

PC is halted at 0100029C, so program counter hangs at 16777864 cicles. While writing to address 00000000. how many times did it write 00000000? well this may be innacurate. but PC halted at 0100029C, AND begun writing zeros at 01000294, so C-4= 8 times written zeroes.

The stack pointer (the current top temp physical memory) is at B003DE8.

the numbers below [last 80 bytes, jumping from 8 bytes each] show a memory dump starting from 0B003DE8 [TOP stack address].

if you look closely on the (dump) offset 0B00:3DF8 the stack frame carrying the value 04000000() (ARM7 I/O access) seemed to die there. (now this is PURE and vague suspicion , but a memory leak of this kind could mean the current sound carry flag was busy, meaning the return value of the "sound" carry register [flag] wasn't properly checked)

that's why I said it could be an ARM7 issue, but i've just started to get guru errors (along with assembly).

edit:



according to http://nocash.emubase.de/gbatek.htm#dsmemorymaps
those are hardware fixed offsets so ARM7 and ARM9 must be accessed separately

edit2:

but... but... i know what you'll say:

how the stack frame can transfer 32-bit values, and if the 04000000 was pure coincidence? well, if we were to check the first 4bits of those 32-bits values, we'd figure that, in fact [by checking the address map i've posted before], the real 32 bits values [and it's hardware flags] are referring to a physical area on the general DS I/O map, and based off the very register, we could denote if hardware at that area, was expecting a certain flag.. or not, against the flag sent on the stack frame.
Well, if this is all from the arm9 side, 4000000 is arm9 i/o... specifically the DISPCNT register according to gbatek. I think it's just a coincidence. But thanks for the link, it's really helpful to pinpoint the exact line of code it crashes on.
Oh I didn't know there comes this nice stuff. Let me start to compile git ^^

1. DSTwo launcher
https://sourceforge.net/p/nesds/cod...366f783/tree/arm9/source/romloader_frontend.c
This code supports BAGplug/iMenu/moonshell2 [edit] and menudo as well as usual ARGV.
If you don't have sf.net account, use: git clone git://git.code.sf.net/p/nesds/code nesds-code
2. soft reset
What is called soft reset recently relies on hbmenu.
http://devkitpro.org/wiki/Homebrew_Menu#Exit_to_Menu_Protocol
so, to exit safely, 0x02ff4000-0x03000000 memory region must not be written.
By the way, if bootstub isn't loaded, you can return to DSi menu, using this code:
https://sourceforge.net/p/nesds/cod...3a754f0fb607b3366f783/tree/arm7/source/arm7.c (sys_exit())
I finally tried hbmenu. GameYob's soft reset seems to work just fine with it, on my Acekard 2i...
As for all those other launchers... I don't see why I'd need more code, if argv is working. The way I see it the launchers just need to be configured to open gameboy games with gameyob. Yes?
 

BassAceGold

Testicles
Member
Joined
Aug 14, 2006
Messages
496
Trophies
1
XP
441
Country
Canada
The DSTwo menus pass standard ARGV to nds binaries. The plgargs.dat and loadfile.dat (which should be deleted when the plgargs.dat file is created) are used for Supercard plugin binaries which do not use standard ARGV.

So if anything of the above code, the extlink.dat support would be handy for people that would like to use moonshell to launch gameboy games.
 
  • Like
Reactions: Boriar and Drenn

Boriar

Well-Known Member
Member
Joined
Sep 22, 2008
Messages
316
Trophies
1
Age
52
Location
Spain
XP
695
Country
The DSTwo menus pass standard ARGV to nds binaries. The plgargs.dat and loadfile.dat (which should be deleted when the plgargs.dat file is created) are used for Supercard plugin binaries which do not use standard ARGV.

So if anything of the above code, the extlink.dat support would be handy for people that would like to use moonshell to launch gameboy games.

Yes, please. If there's some way to support extlink, please implement it.:rolleyes:
 

Deleted member 319809

MAH BOI/GURL
Member
Joined
Dec 22, 2012
Messages
900
Trophies
0
XP
461
Country
Canada
I just implemented save states. It was easier than I would have thought.
One of the things to keep in mind about saved states is that usually they're tied to the emulation state very tightly, and if they aren't, you need to recalculate values derived from the saved state. Do you expect the current saved state format to be permanent? Also, does the sound properly start again and continue where it left off?
 

Drenn

Well-Known Member
OP
Member
Joined
Feb 22, 2013
Messages
574
Trophies
0
XP
696
Country
Canada
One of the things to keep in mind about saved states is that usually they're tied to the emulation state very tightly, and if they aren't, you need to recalculate values derived from the saved state. Do you expect the current saved state format to be permanent? Also, does the sound properly start again and continue where it left off?
The state format could easily change later on, which is why the state files have a version number. They won't load if that number doesn't match the current "state version". What I do with sound is, when a state is loaded I call "handleSoundRegister" for each sound register. It's not perfect, for instance it would reset the length and sweep counters. The gameboy color bios does show some of these bugs when loading a state into it. But all the games I've tried sound fine after resuming.
 

Deleted member 319809

MAH BOI/GURL
Member
Joined
Dec 22, 2012
Messages
900
Trophies
0
XP
461
Country
Canada
The state format could easily change later on, which is why the state files have a version number. They won't load if that number doesn't match the current "state version".
Then I advise that whoever doesn't want to lose their game doesn't use saved states. That behavior is, frankly, horrible.
 

Drenn

Well-Known Member
OP
Member
Joined
Feb 22, 2013
Messages
574
Trophies
0
XP
696
Country
Canada
Then I advise that whoever doesn't want to lose their game doesn't use saved states. That behavior is, frankly, horrible.
There's nothing stopping you from saving regularly, when you download a new version - I'll obviously warn people if compatibility breaks. Myself, I usually only use save states when saving by any other method isn't possible.

But, I guess I'll just have to see how it goes if I need to change the state format. It'll probably be possible to preserve backward-compatibility by checking the version number.
 

windwakr

Well-Known Member
Member
Joined
Sep 13, 2009
Messages
502
Trophies
1
Website
windwakr.github.io
XP
1,792
Country
United States
Then I advise that whoever doesn't want to lose their game doesn't use saved states. That behavior is, frankly, horrible.

Or they could just load their save state, make a hard save, then update and make a new save state? Many emulators have incompatible save states between versions. It's not uncommon, and it would be difficult for the authors to continue supporting older states, especially when large portions of the emulator are rewritten.
 

Deleted member 319809

MAH BOI/GURL
Member
Joined
Dec 22, 2012
Messages
900
Trophies
0
XP
461
Country
Canada
Or they could just load their save state, make a hard save, then update and make a new save state? Many emulators have incompatible save states between versions. It's not uncommon, and it would be difficult for the authors to continue supporting older states, especially when large portions of the emulator are rewritten.
Without wanting to start a full-fledged flame war here, it's cumbersome for users who play multiple games that can't arbitrarily save to SRAM, if they have to load and SRAM-save their saved states for all of those games. For "immature" emulators (I use the term loosely here, those emulators that are still undergoing massive core changes are what I call immature), it's OK, but for mature emulators, an incompatible saved state change is, IMO, inexcusable. The emulator author is simply lazy if s/he doesn't introduce a way to recalculate the new information from an old saved state in a new version if there are no massive core changes. The fact that it's apparently common doesn't make it any better.

I'll examine the saved state stuff later, though :) Thanks Drenn!
 
  • Like
Reactions: Coto

Drenn

Well-Known Member
OP
Member
Joined
Feb 22, 2013
Messages
574
Trophies
0
XP
696
Country
Canada
I probably wasn't thinking that far into the future when I wrote the save state code, I just wanted to get it working. It occurred to me that it could be difficult to append extra information to states with that setup, so I changed it a bit. It should be easier to add in more miscellaneous variables without disturbing older states. It may not seem like a good start - I've broken old states already - but you can consider everything experimental when using the latest build. Hopefully I won't need to disturb the balance again.
 
  • Like
Reactions: Geren

Deleted member 319809

MAH BOI/GURL
Member
Joined
Dec 22, 2012
Messages
900
Trophies
0
XP
461
Country
Canada
I probably wasn't thinking that far into the future when I wrote the save state code, I just wanted to get it working. It occurred to me that it could be difficult to append extra information to states with that setup, so I changed it a bit. It should be easier to add in more miscellaneous variables without disturbing older states. It may not seem like a good start - I've broken old states already - but you can consider everything experimental when using the latest build. Hopefully I won't need to disturb the balance again.
That's cool, because saved states haven't been in a public release yet and you're still working with the format. If states break, so be it, you might be missing variables or something.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    BakerMan @ BakerMan: this one