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.

DS development > Chishm, can you explain some MP code? [Renamed]

#75003 - swzte - Thu Mar 09, 2006 9:56 am

Chism, I have read the MP code written by you!
ARM7 execute the follow code:

*((vu32*)0x027FFE04) = (u32)0xE59FF018; // ldr pc, 0x027FFE24
*((vu32*)0x027FFE24) = (u32)0x027FFE04; // Set ARM9 Loop address
__asm volatile("bx %0" : : "r" (0x027FFE04) );


Can ARM9 enter a loop? 0xE59FF018 is disasemblled as
ldr pc,.+0x20 Here, ldr pc,0x027ffe24

However, [0x027ffe24]=0x027ffe04?

Can you explain?
Thanks a lot!

#75007 - chishm - Thu Mar 09, 2006 10:21 am

What that code does is load the 32 bit value from 0x20 bytes ahead into the program counter (if you don't understand ASM). This basically jumps to whatever address is stored at 0x027FFE24. Since the instruction is located at 0x027FFE04 and it keeps jumping to 0x027FFE04, it will stay in a loop. However, as soon as another number is written to 0x027FFE24, it will jump to that address, breaking out of the loop.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com

#75009 - swzte - Thu Mar 09, 2006 11:27 am

Thank you for you explanation,chishm!
0xE59FF018 is disambled as ldr pc, 0x027ffe24
After this instruction is executed, pc=[0x027ffe24],not pc=0x027ffe24?
Thanks!
I have another question:
in loadBinary_ARM7,in the end, you copy ndsHeader(from CF) to NDSHEADER(0x027ffe00). Before the copy,[0x027ffe04]=0xe59ff018.
After the copy, the value at 0x027ffe04 may be changged.

However, in startBinary_ARM7

((u32*)NDS_HEAD)[0x24>>2] = TEMP_ARM9_START_ADDRESS;

The physical address of NDS_HEAD[0x24] is 0x027ffe24.You want the PC of ARM9 to jump to [0x027ffe24](Here,[address] means the vaue at address). If the value at 0x027ffe04 is 0xE59FF018 ,
it can do. But the value at 0x027ffe04 is not 0xE59FF018 again because of the copy ahead. Can you the PC(ARM9) jump to ARM9 entry?

Chishm, can you give an explanation?

#75012 - chishm - Thu Mar 09, 2006 12:35 pm

Well in C, ldr pc, 0x027ffe24 would be pc = *(vu32*)0x027ffe24

Also, when loading the file, the ARM9 is put into a new wait loop in a function not inside the NDS header. It waits for the ARM9 start address to become non-zero. The file loader stores the ARM9 start address in TEMP_ARM9_START_ADDRESS and sets the value in the header to 0, so that the ARM9 will continue to wait for the ARM7. This is to allow the ARM7 to finish doing what it needs to do. It then exectutes:

((u32*)NDS_HEAD)[0x24>>2] = TEMP_ARM9_START_ADDRESS;

to make the ARM9 jump to the loaded binary.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com

#75014 - swzte - Thu Mar 09, 2006 1:06 pm

Chishm! Look here.
In the end of loadBinary_ARM7 function,you write as follows

dmaCopyWords(3, (void*)ndsHeader, (void*)NDS_HEAD, 0x170);

After this dma transfer, the value at 0x027ffe04 is changed and the value at 0x027ffe24 is also changed. Is ARM9 still in loop.

I'm not clear here.

Can you give an explanation? Thanks!

#75017 - chishm - Thu Mar 09, 2006 2:33 pm

Yes, the ARM9 is still in a loop, because it has already changed where it loops.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com

#75088 - swzte - Fri Mar 10, 2006 1:44 am

Thanks,Chishm!
Can you show me your purpose of the follow code?

WAIT_CR = 0xE880;

(*(vu32*)0x027FFE24) = 0;

while(DISP_Y!=191);
while(DISP_Y==191);
while ( (*(vu32*)0x027FFE24) == 0 );

while(DISP_Y!=191);
while(DISP_Y==191);

__asm volatile("bx %0" : : "r" (*(vu32*)0x027FFE24));

#75098 - natrium42 - Fri Mar 10, 2006 2:54 am

This looks like synchronization on blanks (between CPU cores).
_________________
www.natrium42.com

#75102 - HyperHacker - Fri Mar 10, 2006 3:31 am

swzte wrote:
while(DISP_Y!=191);
while(DISP_Y==191);

Why do so many programs use this? It appears to just wait for line 192... why not while(DISP_Y != 192); then?

#75112 - swzte - Fri Mar 10, 2006 4:18 am

natrium42 ,you say it intends for synchronization on blanks.

When is the value of DISP_Y changed?
Is it changed in the vblank interrupt routine?

Can you give an explanation?

I havn't the vblank interrupt code , so I don'n know how it works!

#75114 - natrium42 - Fri Mar 10, 2006 5:29 am

swzte wrote:

When is the value of DISP_Y changed?
Is it changed in the vblank interrupt routine?

It's a register that is changed by the hardware on each HBlank as the GPU draws horizontal lines.

The screen is 256x192 and a wait for that register to become 191 is essentialy a "busy-wait VSync".
_________________
www.natrium42.com

#75117 - gladius - Fri Mar 10, 2006 6:01 am

HyperHacker wrote:
swzte wrote:
while(DISP_Y!=191);
while(DISP_Y==191);

Why do so many programs use this? It appears to just wait for line 192... why not while(DISP_Y != 192); then?

If your program is fast enough that it finishes while the scanline is still 192, then you'll fall right out of != 192 again. The other method ensures you'll wait a full frame.

#75127 - chishm - Fri Mar 10, 2006 9:24 am

That code is used in the GBAMP firmware replacement, and is based on Darkain's MultiNDS loader.
This code:
Code:
while(DISP_Y!=191);
while(DISP_Y==191);

is used by both CPUs for syncronisation so that they start at the same time.
It is used instead of SwiVBlankIntrWait because interrupts are disabled for the loader.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com