Address Error when running a rom on hardware
Moderator: Stef
-
- Interested
- Posts: 33
- Joined: Fri Dec 12, 2014 2:41 am
- Location: USA - Chicago, IL
Address Error when running a rom on hardware
Hi, I've run into an issue with a game I'm developing. I use Kega Fusion as an emulator to test out my rom, and I'm able to load and play through the rom on Kega Fusion. When I try running the rom on hardware (using a Sega Nomad), it immediately gives me an address error. I've tried fixing the checksum, and that did not resolve the issue. I'm unsure as to what could be causing the error. Does anyone have some ideas as to what could cause this issue, or tips on how I can figure this out?
-
- Interested
- Posts: 33
- Joined: Fri Dec 12, 2014 2:41 am
- Location: USA - Chicago, IL
All my code is in C. I do allocate memory for certain objects. I allocate memory for an object struct, sprites, and background images. Could the error be caused from allocating memory? I'm able to run the rom on an emulator, and it looks like the sprites and images are loaded correctly. So I didn't think memory allocation was the issue.
-
- Interested
- Posts: 33
- Joined: Fri Dec 12, 2014 2:41 am
- Location: USA - Chicago, IL
It's very likely that I'm not using Sprites correctly. Here is a general idea of how I'm updating sprites:
Code: Select all
typedef struct Object
{
Sprite* sprite; // Points to the sprite used in the Sprite List passed to SPR_update()
fix32 posX;
fix32 posY;
void (*updateFunction)(struct Object* obj); // USe SPR_updatePosition here to update the sprite position
...
} Object;
Object* CreateObject(Object* obj, Sprite* sprite, fix32 x, fix32 y)
{
if( (obj = MEM_alloc(sizeof(Object))) != NULL)
{
obj->sprite = MEM_alloc(sizeof(Sprite));
obj->sprite = sprite;
obj->posX = x;
obj->posY = y;
obj->updateFunction = myUpdateFunction;
SPR_initSprite(sprite, &mySpriteDef, fix32ToInt(x), fix32ToInt(y), TILE_ATTR(PAL0, TRUE, FALSE, FALSE));
}
return obj;
}
void CreateSpriteList(void)
{
sprList = MEM_alloc(sizeof(Sprite) * NUMOFSPRITES); // sprList is an array of sprites that I pass to SPR_update. Declared in main, and set as extern in a global.h file. So any source file that includes the global.h file can see the sprite array.
u16 i;
for( i = 0; i < NUMOFSPRITES; i++)
{
Sprite sprite;
sprList[i] = sprite;
}
}
void CreateObjectList(void)
{
u16 i;
for(i = 0; i < NUMOFSPRITES; i++)
{
Object* obj;
objList[i] = (Object*) MEM_alloc(sizeof(Object)); // objList is an array of Objects, and is declared in main. It holds objects that are displayed on screen. It is also set as extern in the global.h file.
objList[i] = obj;
}
}
void main(void)
{
Object* objList[NUMOFSPRITES];
Sprite* sprList;
Object* objTest;
CreateSpriteList();
CreateObjectList();
objTest = CreateObject(objTest, &sprList[0], FIX32(0), FIX32(0));
objList[0] = objTest;
while(1)
{
...
UpdateObjects(); // Loops through the objList, use the updateFunction for each object to update their positions, velocities, etc. Also updates visibility depending on if object goes on/off screen.
SPR_update(sprList, NUMOFSPRITES);
...
}
}
Code: Select all
#define new(struktura) MEM_alloc(sizeof(struktura))
#define newm(struktura,daudzums) MEM_alloc(daudzums*sizeof(struktura))
Code: Select all
Object* CreateObject(Sprite* sprite, fix32 x, fix32 y)
{
Object* obj = new(Object);
if(obj != NULL)
{
obj->sprite = sprite;
obj->posX = x;
obj->posY = y;
obj->updateFunction = myUpdateFunction;
SPR_initSprite(sprite, &mySpriteDef, fix32ToInt(x), fix32ToInt(y), TILE_ATTR(PAL0, TRUE, FALSE, FALSE));
}
return obj;
}
Code: Select all
void CreateSpriteList(void)
{
sprList = newm(Sprite, NUMOFSPRITES);
}
Code: Select all
u16 i;
for( i = 0; i < NUMOFSPRITES; i++)
{
Sprite sprite;
sprList[i] = sprite;
}
Code: Select all
void CreateObjectList()
{
u16 i;
for(i = 0; i < NUMOFSPRITES; i++)
{
objList[i] = (Object*) new(Object);
}
}
But overall i dont see why it should make invalid adress error.
-
- Very interested
- Posts: 3131
- Joined: Thu Nov 30, 2006 9:46 pm
- Location: France - Sevres
- Contact:
As Arrovs pointed out, you are copying initialized data in your allocated memory, even worst when you do that :
You actually allocate the object then lost the allocated pointer and replace it with local memory allocated on stack... That will totally screw up your stack at some point and may lead to the address error problem (when returning from function) ! So you definitely need to remove
Also I think your code is a bit over complicated, you are duplicating the position information in your Object structure. By the way if you want to add a specific field to the Sprite struc, you have the free "data" field for that. It's a 32 bits integer field but you can use it for whatever you want (and for instance a function pointer as you have in your object structure) So you don't need to create a new struc to embed the Sprite struc here.
Code: Select all
objList[i] = (Object*) MEM_alloc(sizeof(Object));
objList[i] = obj;
Code: Select all
objList[i] = obj;
Its not so bad to wrap into Object im doing same with almost everything what needs advanced behaviour. One free field is too less for such case. You could remove it at all in most cases for more memory. Only thing what it could be good is for storing flags.
And you are true, using pointers who lead to nowhere can easely raise address errors(objList = obj;) .
And you are true, using pointers who lead to nowhere can easely raise address errors(objList = obj;) .
-
- Interested
- Posts: 33
- Joined: Fri Dec 12, 2014 2:41 am
- Location: USA - Chicago, IL
Thank you for the help. I obviously do not have a good understanding of how memory allocation works. I will go back and fix my code.
In terms of using an Object wrapper around the Sprite. I'm using the Object position X and Y to track where the object is in an area, and the Sprite positions to track the object's position on screen.
In terms of using an Object wrapper around the Sprite. I'm using the Object position X and Y to track where the object is in an area, and the Sprite positions to track the object's position on screen.
-
- Very interested
- Posts: 3131
- Joined: Thu Nov 30, 2006 9:46 pm
- Location: France - Sevres
- Contact:
Arrovs wrote:Its not so bad to wrap into Object im doing same with almost everything what needs advanced behaviour. One free field is too less for such case. You could remove it at all in most cases for more memory. Only thing what it could be good is for storing flags.
And you are true, using pointers who lead to nowhere can easely raise address errors(objList = obj;) .
You can wrap into an object but the single data field is actually enough to point on another structure if you need it (as an Object structure), It's why i dedicated only a single field for that. But you can embed in an Object, why not... at least if you need only a single extra information or just for flags data is here
-
- Interested
- Posts: 33
- Joined: Fri Dec 12, 2014 2:41 am
- Location: USA - Chicago, IL
I was able to resolve the issue. It is unrelated to the area of code I posted above. The issue in my code was with how I was loading the background image for a level. Here is the code:
I think unpacking the image, and also using VDP_drawImageEx was causing the issue. I removed the code to unpack the image, and this resolved the memory issue.
Thank you all for the help and input. I also went back and made updates to allocating memory for my objects.
Stef - I didn't think of using that free data field as a pointer to a struct. I need the Object wrapper to hold flags for my objects, but having all that information on the Sprite struct is what I originally wanted to do. So that free data field will help me do this. Thanks again for the help.
Code: Select all
Image *bgImage = unpackImage(&ImageFile, bgImage);
VDP_drawImageEx(APLAN, &ImageFile, TILE_ATTR_FULL(PAL1, FALSE, FALSE, FALSE, ind), 0, 0,FALSE, TRUE);
Thank you all for the help and input. I also went back and made updates to allocating memory for my objects.
Stef - I didn't think of using that free data field as a pointer to a struct. I need the Object wrapper to hold flags for my objects, but having all that information on the Sprite struct is what I originally wanted to do. So that free data field will help me do this. Thanks again for the help.