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 > SWI 4 - IntrWait

#10503 - sgeos - Sat Sep 06, 2003 6:02 pm

Do interrupts have to be enabled to take advantage of SWI 4 (IntrWait)?

Does the v-blank interrupt need to be enabled to take advantage of SWI 5 (VBlankIntrWait)?

-Brendan Sechter

#10504 - sajiimori - Sat Sep 06, 2003 6:47 pm

Yes on both counts. Make sure you acknowledge the vblank interrupt to the BIOS when using SWI 5, or it will lock up.

#10505 - sgeos - Sat Sep 06, 2003 7:19 pm

Something like this?

Code:
(unsigned short *)0x04000202 |= VAULE;  /* IF */
(unsigned short *)0x03007FF8 |= VALUE;  /* Bios */


-Brendan Sechter

#10507 - tepples - Sat Sep 06, 2003 7:32 pm

Strictly, when you write back to IF it should be | (because it's a register with, essentially, OR logic), and when you write back to BIOS's mirror of IF it should be |= (because it's plain memory, which has REPLACE logic).
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#10509 - sgeos - Sat Sep 06, 2003 7:45 pm

Do I want to do this instead?
Code:
(unsigned short *)0x04000202 |  VAULE;  /* IF */
(unsigned short *)0x03007FF8 |= VALUE;  /* Bios */


-Brendan Sechter

#10514 - tepples - Sat Sep 06, 2003 9:53 pm

sgeos wrote:
Do I want to do this instead?
Code:
(unsigned short *)0x04000202 |  VAULE;  /* IF */

Right idea, but you made three little typos, corrected as follows:
Code:
(volatile unsigned short *)0x04000202  = VALUE;  /* IF */

1. You confused which operator of the pair does the ORing and which does the assigning.
2. You misspelled "VALUE".
3. You forgot to mark a memory-mapped register as volatile.

And I'd define register names rather than scattering "magic numbers" throughout the code:
Code:
#define REG_IF ((volatile unsigned short *)0x04000202)
#define BIOS_IF ((volatile unsigned short *)0x03fffff8)
#define ACK_INTS(ints) (BIOS_IF |= ints, REG_IF = ints)

Then you can ACK_INTS(saved_if_value) at the end.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#10516 - sgeos - Sat Sep 06, 2003 10:25 pm

tepples wrote:
sgeos wrote:
Do I want to do this instead?
Code:
(unsigned short *)0x04000202 |  VAULE;  /* IF */

Right idea, but you made three little typos, corrected as follows:
Code:
(volatile unsigned short *)0x04000202  = VALUE;  /* IF */

1. You confused which operator of the pair does the ORing and which does the assigning.


I'll amit that an | with no = looked odd. I don't think that would compile. I'll also admit that did not know that = ORed a register.

Quote:
2. You misspelled "VALUE".


Excellent. (I guess I did not copy paste...)

Quote:
3. You forgot to mark a memory-mapped register as volatile.


Should all memory-mapped registers be declared volatile? I did overlook REG_IF. Hardware does change the value of that location.

Quote:
And I'd define register names rather than scattering "magic numbers" throughout the code:


Are there standard names or headers that I should be using? Registers, I'm assuming, REG_ followed by whatever is listed in GBAtek. What about the bits set in the registers?

Quote:
Code:
#define REG_IF ((volatile unsigned short *)0x04000202)
#define BIOS_IF ((volatile unsigned short *)0x03fffff8)
#define ACK_INTS(ints) (BIOS_IF |= ints, REG_IF = ints)

Then you can ACK_INTS(saved_if_value) at the end.


Why ACK_INTS? Oh, acknowldege interrupts.

-Brendan Sechter

#10518 - tepples - Sat Sep 06, 2003 10:57 pm

sgeos wrote:
I'll amit that an | with no = looked odd. I don't think that would compile. I'll also admit that did not know that = ORed a register.

It would compile, but you'd probably get a warning about a 'statement with no effect'. And strictly, the = operator doesn't OR a register in the general case, but acknowledge-interrupt registers on most architectures (including the GBA) typically have logic built into them that looks quite like OR.

Quote:
Should all memory-mapped registers be declared volatile?

Always.

Quote:
Are there standard names or headers that I should be using? Registers, I'm assuming, REG_ followed by whatever is listed in GBAtek.

That's what I've seen most people using, but I use a completely different set of names that 1. have no chance of matching a Nintendo trade secret and 2. make more sense to me.

Quote:
What about the bits set in the registers?

Name those however you want, but please be consistent.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#10520 - sgeos - Sat Sep 06, 2003 11:12 pm

tepples wrote:
sgeos wrote:
I'll amit that an | with no = looked odd. I don't think that would compile. I'll also admit that did not know that = ORed a register.

It would compile, but you'd probably get a warning about a 'statement with no effect'. And strictly, the = operator doesn't OR a register in the general case, but acknowledge-interrupt registers on most architectures (including the GBA) typically have logic built into them that looks quite like OR.


What other registers on the GBA operate like this?

Quote:
Quote:
Should all memory-mapped registers be declared volatile?

Always.


Specifically what is a memory-mapped register? Why should it always be declared volatile?

Quote:
Quote:
What about the bits set in the registers?

Name those however you want, but please be consistent.


Fair enough.

Quote:
Quote:
Are there standard names or headers that I should be using? Registers, I'm assuming, REG_ followed by whatever is listed in GBAtek.

That's what I've seen most people using, but I use a completely different set of names that 1. have no chance of matching a Nintendo trade secret and 2. make more sense to me.


In your opinion, would it be appropriate to also name other things whatever one wants as long as one is consistent?

How badly ought one want to avoid matching a Nintendo trade secret?

-Brendan Sechter

#10523 - tepples - Sun Sep 07, 2003 4:07 am

sgeos wrote:
tepples wrote:
acknowledge-interrupt registers on most architectures (including the GBA) typically have logic built into them that looks quite like OR.

What other registers on the GBA operate like this?

I can think of no others right now. There may be some in serial communication, but I haven't ventured far into that realm.

Quote:
Specifically what is a memory-mapped register?

A memory-mapped register is an I/O port mapped into a processor's memory address space rather than into a separate I/O address space a la x86. On the GBA, these ports are mapped into address range 0x04000000-0x040003ff.

Quote:
In your opinion, would it be appropriate to also name other things whatever one wants as long as one is consistent?

Correct. A main reason for writing business logic in C or in C++ instead of in assembly language is to keep the code easily readable by a trained human being, because human beings will ultimately have to find defects and correct them. Picking register names that make sense (e.g. I use INTACK instead of IF, INTMASK instead of IE, and INTENABLE instead of IME) helps readability in the same way.

Quote:
How badly ought one want to avoid matching a Nintendo trade secret?

Depends on how much money you have for a legal defense.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.