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 > Demo not working!!

#140315 - Ruben - Sat Sep 15, 2007 6:53 am

I was recently adding the 'big map' thing a magig which I got working successfully but after I changed ALL the maps... MY DEMO STOPPED WORKING!! When I check the disassembly, I notice 2 weird things:
1) It's mainly ARM code, even though my compiler flags include '-mthumb -mthumb-interwork'
2) It's practically doing nothing ('mov r0, #0x800000' amongst others)
I don't know what could be going on there as all I did was change my map sizes from 1024 to 4096. Thanks in advance.

#140345 - Cearn - Sat Sep 15, 2007 2:22 pm

If you're using function pointer somewhere, it's possible you called a NULL function which make the code jump into neverneverland. If you see lots of repeated instructions, it's actually possible you're executing data rather than code. Look at the addresses and check the mapfile and find what those addresses are a part of. IWRAM overflow might be another problem: if you're creating a large local array, you might swamp the rest of IWRAM including the stack, causing everything after it go horribly wrong. If there's something more 'interesting' going on, we may need either the code or the binary to figure it out.

#140352 - Ruben - Sat Sep 15, 2007 3:39 pm

Hi Cearn. I really don't know what's going on but I thought I'd disassemble it in VBA and these are the results:
Code:
000000b8 ea000006 b $00000020
00000020 e3a00302 mov r0, #0x8000000
00000024 e1a0f000 mov pc, r0
08000024 ea00002e b $080000c0
080000c0 ea000000 b $000000c8
080000c8 e3a00012 mov r0, #0x12
080000cc e129f000 msr cpsr_fc, r0
080000d0 e59fd09c ldr sp, [$08000174] (=$03007fa0)
00000018 ea000088 b $00000240
00000240 e92d500f stmfd sp!, {r0-r3,r12,lr}
00000244 e3a00301 mov r0, #0x4000000
00000248 e1a0e00f mov lr, pc
0000024c e510f004 ldr pc, [r0, -#0x4]

And it just repeats that over and over again... I don't know what might be causing it though... hm... I've uploaded the binary here (it's in ELF format so you can debug it) and the disassembly here.

#140355 - Cearn - Sat Sep 15, 2007 4:28 pm

Code:
00000020 e3a00302 mov r0, #0x8000000
00000024 e1a0f000 mov pc, r0

08000024 ea00002e b $080000c0
080000c0 ea000000 b $000000c8
080000c8 e3a00012 mov r0, #0x12
080000cc e129f000 msr cpsr_fc, r0
080000d0 e59fd09c ldr sp, [$08000174] (=$03007fa0)

That's part of the boot-code. (note: early ROM addresses)

Code:

00000018 ea000088 b $00000240

00000240 e92d500f stmfd sp!, {r0-r3,r12,lr}
00000244 e3a00301 mov r0, #0x4000000
00000248 e1a0e00f mov lr, pc
0000024c e510f004 ldr pc, [r0, -#0x4]

This is part of the interrupt process. (note: 0000:xxxx means BIOS). 0400:0000-4 is a pointer to the master interrupt service routine. This address appears to be empty in your binary, so it just jumps back to 0000:0000 again (like I said, beware of calling NULL functions :P ). You need to set up an interrupt routine before enabling any interrupts.

ETA:
On further inspection, the master ISR is actually set (in the boot code, around 0800:00E8). However, it's cleared again when you hit this part later:
Code:
    08000102 (T)  ldr     r1,=__data_lma            ; (0809:D274)
    08000104 (T)  ldr     r2,=__bss_end             ; (0300:541C)
    08000106 (T)  ldr     r4,=__iwram_overlay_end   ; (0300:EC28)
    08000108 (T)  bl      CopyMemChk

I can't find the name '__iwram_overlay_end' in any custom ctr0.S files I have here, but it looks like this is supposed to be copying the data section (initialized global variables) into place. The range it's copying into is from 0300:541C to 0300:EC28 ; if you ever see IWRAM addresses over 0300:8000, that's bad. If you must have the large arrays in RAM (rather than ROM), put them into EWRAM using __attribute((section(".ewram")))

#140395 - Ruben - Sun Sep 16, 2007 2:25 am

OK. That's just WEIRD. This is my 'Main.cpp' file:
Code:
/*
 +-----------------------------------------+
 | FINAL FANTASY IV - THE RETURN OF GOLBEZ |
 +-----------------------------------------+
 |     ORIGINAL MADE BY SQUARE IN 1991     |
 +-----------------------------------------+
 | ALL WORK IS COPYRIGHTED BY THEIR OWNERS |
 +-----------------------------------------+
*/

//Includes
#include "Includes.H"

//The Interrupt Table
void (*IntrTable[])() = {
 &vblFunc, //V-Blank Interrupt
 0, //H-Blank Interrupt
 0, //VCOUNT Interrupt
 0, //TM0 Interrupt
 &kradInterrupt, //TM1 Interrupt
 0, //TM2 Interrupt
 0, //TM3 Interrupt
 0, //Serial Interrupt
 0, //DMA0 Interrupt
 0, //DMA1 Interrupt
 0, //DMA2 Interrupt
 0, //DMA3 Interrupt
 0, //DMA4 Interrupt
 0, //Cart-Remove Interrupt
};

//Entry Point
char __EH_FRAME_BEGIN__[] = {};
int main(void) {
 int i;
 
 //Enable Interrupts
 REG_IME = 1;
 
 //Cart-Remove-Interrupt and V-Blank Interrupt
 REG_IE |= (1 << 13) | 1;
 
 //Setup the V-Blank Interrupt
 REG_DISPSTAT |= (1 << 3);
 
 //Setup ROM-Timing
 REG_WSCNT = (5 << 2) | (1 << 14);
 
 //Set the Window Parameters
 REG_WININ = 0x003F;
 REG_WIN0H = 0x00F0;
 
 //Reset OAM Data
 ClearOAM();
 
 //Show the Introduction
 ShowIntro();
 
 //Set to Mode 0, Enable Sprites, 1D Mapping and Enable Window 0
 REG_DISPCNT = MODE_0;
 REG_DISPCNT |= OBJ_ENABLE;
 REG_DISPCNT |= OBJ_MAP_1D;
 REG_DISPCNT |= WIN0_ENABLE;
 
 //Enable Camera Updating on BG2 and BG 3
 CameraBG2Update = true;
 CameraBG3Update = true;
 
 //Define BG0
 Background0.number = 0;
 Background0.charBaseBlock = 1;
 Background0.screenBaseBlock = 2;
 Background0.colorMode = BG_COLOR_16;
 Background0.size = BG_SIZE_256x256;
 Background0.mosaic = 0;
 Background0.x_scroll = 0;
 Background0.y_scroll = 0;
 Background0.priority = 0;
 
 //Define BG1
 Background1.number = 1;
 Background1.charBaseBlock = 2;
 Background1.screenBaseBlock = 3;
 Background1.colorMode = BG_COLOR_16;
 Background1.size = BG_SIZE_256x256;
 Background1.mosaic = 0;
 Background1.x_scroll = 0;
 Background1.y_scroll = 0;
 Background1.priority = 0;
 
 //Define BG2
 Background2.number = 2;
 Background2.charBaseBlock = 0;
 Background2.screenBaseBlock = 4;
 Background2.colorMode = BG_COLOR_256;
 Background2.size = BG_SIZE_256x256;
 Background2.mosaic = 0;
 Background2.priority = 1;
 
 //Define BG3
 Background3.number = 3;
 Background3.charBaseBlock = 0;
 Background3.screenBaseBlock = 5;
 Background3.colorMode = BG_COLOR_256;
 Background3.size = BG_SIZE_256x256;
 Background3.mosaic = 0;
 Background3.priority = 0;
 
 //Enable Backgrounds 2 and 3
 EnableBackground(&Background2); //Background
 EnableBackground(&Background3); //Foreground
 
 //Load OAM Palette into Memory
 for(i=0;i<16;i++) OBJPaletteMem[i] = OAMPalettes[PlayerCurrent][i];
 
 //Clear the VRAM
 ClearVRAM();
 
 //Initialize the Text System
 TextInit();
 
 //Write Map into Memory
 PlayerCurrentX = 6;
 PlayerCurrentY = 5;
 
 //Write the New Map Information
 CurrentEvents = BaronCastleEastTower1FEvents;
 CurrentObstruction = BaronCastleEastTower1FObstructions;
 CurrentTileData = BaronCastleEastTower1FTileData;
 UpdateMapDataViaCamera(
 BaronCastleEastTower1FBackgroundData,
 BaronCastleEastTower1FForegroundData,
 BaronCastleEastTower1FTileImage,
 BaronCastleEastTower1FTilePalette,
 64);
 
 //Setup the Player's OAMs
 Sprites[0].attribute0 = WIDE | PlayerScreenLocationY;
 Sprites[0].attribute1 = PlayerScreenLocationX;
 Sprites[0].attribute2 = PRIORITY(1);
 Sprites[1].attribute0 = WIDE | PlayerScreenLocationY+8;
 Sprites[1].attribute1 = PlayerScreenLocationX;
 Sprites[1].attribute2 = PRIORITY(1) | 2;
 
 //Play a Module
 krapPlay(&mod_KingdomBaron, KRAP_MODE_LOOP, 0);
 
 //Write the OAM Image and Transition In
 u16* NewImage = (u16*)SpriteData;
 for(i=0;i<64;i++) OAMData[i] = NewImage[i];
 OpenTransition();
 
 //Enable Input
 PlayerInputAllowed = true;
 
 //Loop
 while(1) {
  UpdateInputPlayer();
  UpdateKeys();
  WaitForVSync();
 }
}

And this is my V-Blank interrupt function:
Code:
//This is Called Every V-Blank
void vblFunc() {
 GlobalFrameCount++;
 kramWorker();
 UpdateCamera();
 CopyAllOAM();
 if(!(GlobalFrameCount % 8)) UpdateMapEngine();
}

None of these functions are NULL and all my map data is 'const u8' so I don't know what could be happening there...

#141200 - Ruben - Sun Sep 23, 2007 4:25 am

OK... this is just going to freak EVERYONE out... when I tested the game again... I thought I'd see all the registers, palettes, etc... and when I saw the OAM palette... I realized that the OAM palette IS written! And when I tested with the introduction on, it wrote BOTH palettes!

#141298 - Cearn - Sun Sep 23, 2007 9:49 pm

DevkitArm comes with a utility called arm-eabi-nm.exe, which allows you to see the memory allocation for elf-files. (use `arm-eabi-nm -n -S filename > foo.txt' to dump it to 'foo.txt'. Note that the original filename doesn't work for some reason, probably because it's too long.) This is part of what I get for yours
Quote:

030021e4 0000018c B PlayerCommandQueue
03002370 00000800 B CurrentObstruction
03002b70 00000800 B CurrentTileData
03003370 00000004 B CurrentBGMapData
03003374 00000004 B CurrentFGMapData
03003378 00000001 B CurrentMapSize
0300337c 00002000 B CurrentEvents
0300537c 0000001c B Background0

...

03005488 00000800 D BaronCastleEastTower1FObstructions
03005c88 00002000 D BaronCastleEastTower1FEvents
03007c00 A __iheap_end
03007c88 00000800 D BaronCastleEastTower1FTileData HAHA stack I keel you!!!
03007f00 A __sp_usr
03007fa0 A __sp_irq
03007ffc A __intr_vector_buf
03008488 00000800 D BaronCastleEastTower2FObstructions
03008c88 00002000 D BaronCastleEastTower2FEvents
0300ac88 00000800 D BaronCastleEastTower2FTileData
0300b488 00000800 D BaronCastleEastTower3FObstructions
0300bc88 00002000 D BaronCastleEastTower3FEvents
0300dc88 00000800 D BaronCastleEastTower3FTileData
0300e488 00000004 D LastFrame
0300e48c 00000004 D MapFrameCount

Basically, you have too much stuff in IWRAM. You should try to move the bigger stuff to EWRAM (or ROM if it's actually constant data). The 'Current' and 'Baron' stuff you see here would be good places to start. Why are the Currentfoo items so large anyway? wouldn't it be easier to just point to the stuff in ROM ?

I would also strongly suggest using devkitpro instead of devkitAdvance. Compilers have advances a little in the last 4 years; for one it would have warned you about overrunning RAM limits. It also comes with basic library code that is likely to be superior to what you find in most tutorials.

#141327 - Ruben - Mon Sep 24, 2007 3:28 am

Cool. I'll do that right away. I thought I should've used devKitPro but I wasn't sure I'd be able to do it properly as I program on another PC but it seems I can actually keep the files... lol... and I forgot to post my updated version of the code... everything is a pointer now...anyways... thanks!