Hi, as I thought it was a problem with the crt0.s not being saving the contents of the registries at the moment of calling the interrupt, and as you pointed DogP, the reti instruction is which restores PSW, and the interrupt handler in the new crt0 wasn’t executing it. I will send David the crt0.s I fixed so he can put it in the gccvb source :-).
Thanks again for your help DogP.
jorgeche
Now, the old crt0.s does have at the end of the interrupt handler a reti instruction that the new one does not… maybe there is the key… I will experiment tonight, thanks DogP.
I will try to manually restore PSW from the EIPSW. as you say tonight. It is very weird. Indeed, the asm statement is mandatory, otherwise the program restores the wrong call record from the stack on handler’s return. I be tried these:
asm(“add 4,r3”);
asm(“reti”);
return;
but nothing changes, I am begging to believe that there is something wrong with the linker, maybe linking multiples object files or with the ctr0.o file, because the clock demo works either with the new compiler, and with the new vb.ld script, but fails with the new ctr0.
Now, when I try to compile my project with the new compiler, new vb.ld script and old ctr0.o, it again doesn’t work.
Hi, it definitively has to do with the new ctr0.s and vb.ld script, I have compiled the demo clock included in the old gccvb under the new one, using the ctr0.o, vb.ld and vb.hdr that came with the old gccvb and it works. the problem is that I think the old scripts and headers does not support multiple o files which my project is divided into.
If I compile the same clock demo, using the new script and crt0, the interrupts don’t get fired.
Shouldn’t the setIntLevel function clear the PSW status?
ok… here is how it goes:
first activate interrupts
//setup interrupts
VIP_REGS[INTCLR] = VIP_REGS[INTPND];
VIP_REGS[INTENB] = 0x0000;
setIntLevel(0);
INT_ENABLE;
//setup timer
timerFreq(TIMER_100US);
timerSet(TIME_MS(10));
timerClearStat();
timerInt(1);
timerEnable(1);
then the interrupt handler
void tim_vector() {
timerInt(0);
VIP_REGS[INTCLR] = VIP_REGS[INTPND];
timerEnable(0);
timerClearStat();
timerEnable(1);
count++; //global variable
timerInt(1);
setIntLevel(0);
asm(“add 4,r3”); //if not put, the sp will point to other call record
}
and in the machine code I get:
07002c02 <_tim_vector>:
7002c02: 5f 01 mov lp, r10
7002c04: 00 ac 68 82 jal 700ae6c <__save_r31>
7002c08: c0 40 mov 0, r6
.
.
.
.
7002c4a: 64 44 add 4, sp
7002c4c: 00 a8 2c 82 jr 700ae78 <__return_r31>
and for the interrupt vector:
0703fe00 <_int_table>:
703fe00: 7c 44 add -4, sp
703fe02: 23 dc 00 00 st.w r1, 0[sp]
703fe06: 20 bc 01 07 movhi 1793, r0, r1
703fe0a: 21 a0 8a 89 movea -30326, r1, r1
703fe0e: 01 18 jmp [r1]
703fe10: 7c 44 add -4, sp
703fe12: 23 dc 00 00 st.w r1, 0[sp]
703fe16: 20 bc 00 07 movhi 1792, r0, r1
703fe1a: 21 a0 02 2c movea 11266, r1, r1
703fe1e: 01 18 jmp [r1]
.
.
.
.
So, I guess I’m not getting the EP bit in the PSW be cleared?…
Later I used a code from Lameboyadvance wich includes a reti instruction:
asm(”
di /* Disable interrupts */
add 4, r3 /* Set sp back to previous value */
ei /* Re-enable interrrupts */
reti /* Return from interrupt */
“);
return;
but I get the same result:
VIP_REGS[INTPND] = 0x601E always
Thanks for your support
Hi, that would be great… why don’t you write Krisse about it, I think he would be really interested. He and I had begun to develop a game for the VB and certainly need more people involved.
jorgeche
Hi, you need a game to boot the VB, it doesn’t show anything when powered without a cart. But if you listen carefully, you can hear a bzzzz when turning it on, it is because of the oscilating mirrors, at least you can know if it is working.
jorgeche
Hi, great to see someone else interested in VB development, I will release the code of the engine I have been working on September, maybe you can join Krisse and I to develop the game we are creating.
jorgeche
In an strange turn around it worked again!… now I see that the problem was not memory related, I don’t know why, but I’ve managed to make the ROM work again by calling this function in the game’s main loop:
void verify(int i){
//turn on the display
vbDisplayOn();
//setup column table
vbSetColTable();
//this just puts WRLD_ON on layer 31
vbActivateWorldShow();
//set brigth
vbFXFadeIn(FADEDELAY);
}
//game’s main loop
while(true){
GameEngine_handleInput(&gameEngine);
GameEngine_update(&gameEngine);
GameEngine_render(&gameEngine);
//this is the function
verify();
}
I can’t figure it out why that exact combination makes it work, and why if I put the call before the infinite loop it doesn’t.
Now, all those functions are called in the gameEngine’s initialization, and after loading a game world.
Thanks again for your support.
Running out of ideas… declared this:
int global;
void main();{
.
.
.
}
global has and address 0x0500008… and no change of its value… never…
I will check those outputs from RD tonight, thanks for all your help DogP.
No, indeed, I have avoided recursion, I just tried it almost 6 months ago and remember that it didn’t link, but now it links… just made a test, I was forced to drop any recursion in the design stage… and better I did. :-). I will check that in RD tonight. Wrote to David to see if he has an idea.
Just for the shake of posting… just kidding, I’m pretty sure now that the stack grows down…
void main(){
int i;
int j;
}
i’s address: 0x0500FFA4
j’s address: 0x0500FFA0
Still more difficult to know how much the stack grows… 🙁
All willl try, thanks for your help… I think I should ask David Tucker about recorsion, because I remeber the last time I tried to use it, it didn’t compile, but now recursion works… If recursion works… I don’t what to believe I have allocated the 64KB of RAM available… but I don’t have the knowledge to measure it, I have tried to pass to functions as much pointers as I can, and made sure that the big memory usage is all condensed in one single object (my gameEngine)… and visible in he BSS now.
Will keep trying… thanks a lot.
Hi, yesterday I read a lot about object file’s sections, memory distribution, etc., and learned that all the calls to functions, parameters passing and local variables are located in the stack. Now, I don’t now were the stack starts, and from there which way it grows (up or down).. I suppose it grows up and starts were the bss ends (because the address of gameEngine).
I made some tests yesterday and reduced my gameEngine object to 12000 bytes, put it in the bss section, and checked the addresses of some local variables to see were in the stack are created, well the max address was in:
0x0500FF40
I couldn’t find one with a greater address, but it was the same address before and after shrinking the size of the classes and remove some function calls.
Let me clean it:
#define HEAPSIZE1024 2048
#define HEAPSIZE256 2560
#define HEAPSIZE128 4120
#define HEAPSIZE32 3200
//each block size
#define BLOCK1024 1024
#define BLOCK256 256
#define BLOCK128 128
#define BLOCK32 32
typedef struct Heap{
//dynamic memory
BYTE mem1024[HEAPSIZE1024];
BYTE mem256[HEAPSIZE256];
BYTE mem128[HEAPSIZE128];
BYTE mem32[HEAPSIZE32];
//allocated objects
void *allocObject1024[HEAPSIZE1024/BLOCK1024];
void *allocObject256[HEAPSIZE256/BLOCK256];
void *allocObject128[HEAPSIZE128/BLOCK128];
void *allocObject32[HEAPSIZE32/BLOCK32];
}Heap;
Indeed:
#define HEAPSIZE1024 2048 //10
#define HEAPSIZE256 2560 //30
#define HEAPSIZE128 4120 //15
#define HEAPSIZE32 3200 //100
//each block size
#define BLOCK1024 1024
#define BLOCK256 256
#define BLOCK128 128
#define BLOCK32 32
typedef struct Heap{
//dynamic memory
//BYTE *mem1024; //uses object memory
BYTE mem1024[HEAPSIZE1024];
//BYTE *mem256; //uses object memory
BYTE mem256[HEAPSIZE256];
BYTE mem128[HEAPSIZE128];
//BYTE *mem128; //uses object memory
BYTE mem32[HEAPSIZE32];
//BYTE *mem32; //uses object memory
//allocated objects
void *allocObject1024[HEAPSIZE1024/BLOCK1024];
void *allocObject256[HEAPSIZE256/BLOCK256];
void *allocObject128[HEAPSIZE128/BLOCK128];
void *allocObject32[HEAPSIZE32/BLOCK32];
}Heap;
and my main class: GameEngine has a total size of 19668 bytes which doesn’t appear in those outputs… strange…
I have defined a global array: int global[10000]; and my bss goes up to 40108…
Now, I’m defining my gameEngine object inside the main() function… should I put it in the global scope?… that way my bss grows up to 19766 bytes.
Should not the linker complain if I exceeded the working ram area? If I declare a global array: int arrayG[100000]; I get:
/usr/local/v810/bin/ld: region ram is full (output/object.elf section .bss)
collect2: ld returned 1 exit status
make: *** [object.elf] Error 1
If I declare the same array inside main(), it links without errors.
and the size of the bss goes back to 108…
How can I know how much RAM it takes all the calls and local variables?…
Thanks DogP, so I did as you said and obtained the following results:
From all my .o files I got the following sizes:
.data 0x90
.bss 0x00
Now, from object.efl which is the file in wich I link all my object files I got:
.data 0x00000142
.bss 0x0000006c
Which is far from FFFF… so, the problem could not be about work RAM usage?… And if it was memory usage, should’n’t the emulators complain about it too?.
Thanks for your help… I have not checked yet controlling the background color… hope to have sometime today
Thankd DogP, I will try the VIP_REGS[BKCOL] = 3; tonight.
I got this from object.elf
Contents of section .text:
Contents of section .rodata:
Contents of section .data:
5000000 00000000 00000000 00000000 00000000 …………….
5000010 00000000 00000000 00000000 00000000 …………….
5000020 00000000 00000000 00001027 00000000 ………..’….
5000030 00000000 00000000 00000000 000000ff …………….
5000040 00000000 00000000 01000000 00000000 …………….
5000050 00000000 00000000 00000000 00000000 …………….
5000060 00000000 00000000 00000000 00000000 …………….
5000070 00000000 00000000 00000000 00000000 …………….
5000080 00000000 00000000 00000000 00000000 …………….
5000090 00000000 00000000 00000000 00000000 …………….
50000a0 0000ff00 00000000 00000000 00000000 …………….
50000b0 00000000 00000000 0c490107 1c490107 ………I…I..
50000c0 22490107 2a490107 30490107 37490107 “I..*I..0I..7I..
50000d0 3c490107 44490107 49490107 52490107
I get this:
object.elf: file format elf32-v810
Contents of section .text:
7000000 80bc0207 84a030b9 a0bc0005 a5a04201 ……0…….B.
7000010 c0bc0005 c6a00000 00a81000 e4c00000 …………….
7000020 e6d00000 8144c144 c50cf28d 80bc0105 …..D.D……..
7000030 00a80a00 05d40000 a244a40c f88d0570 ………D…..p
.
.
.
700ffa8 88008e00 94009a00 a000a600 ac00b200 …………….
700ffb8 b800be00 c300c900 cf00d500 da00e000 …………….
700ffc8 e600eb00 f100f600 fc000101 07010c01 …………….
700ffd8 11011701 1c012101 26012b01 30013601 ……!.&.+.0.6.
700ffe8 3a013f01 44014901 4e015301 57015c01 :.?.D.I.N.S.W.\.
700fff8 61016501 6a016e01 72017701 7b017f01 a.e.j.n.r.w.{…
7010008 83018701 8b018f01 93019701 9b019e01 …………….
7010018 a201a601 a901ad01 b001b301 b701ba01 …………….
.
.
.
7023e94 28342c33 3429002e 2e2f2e2e 2f2e2e2f (4,34)…/../../
7023ea4 2e2e2f2e 2e2f6e65 776c6962 2d312e31 ../../newlib-1.1
7023eb4 302e302f 6e65776c 69622f6c 6962632f 0.0/newlib/libc/
7023ec4 73747269 6e672f73 74726c65 6e2e6300 string/strlen.c.
7023ed4 7374726c 656e3a46 28362c31 29007374 strlen:F(6,1).st
7023ee4 723a5028 342c3334 29007374 6172743a r:P(4,34).start:
7023ef4 7228342c 33342900 r(4,34).
END
Could you tell me please if you see someting wrong? As long as I understand what the output says, is that the max address FFFF has been reached and surpassed by a long shot.
Thanks a lot!.