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.

Hardware > Game Boy Player & Single-System Multiplayer

#8794 - abilyk - Sun Jul 20, 2003 7:41 am

I read on game news site www.gamerfeed.com about a month ago that when run on the Game Boy Player, Square's upcoming Sword of Mana would allow 2 players to each connect a 'cube controller to the system and play using only the GB Player.

I know that GBA games are able to detect the Player; I've seen it done ("Game Boy Player" splash screen) with the Japanese version of Mario Advance 4. But I can't find any technical information on the Player online... I know that the GBA (SP) only has one keypad input register, but is it possible that N put additional input registers into the GB Player's version of the GBA hardware?

Was Gamerfeed simply misinformed about Mana's multiplayer features, or might there be some validity to this? Anybody?

#8797 - Lord Graga - Sun Jul 20, 2003 12:02 pm

Well, isn't there only one way to find out?
Write a program that listens to different unused registers and upload it to the cube!

#9680 - FluBBa - Wed Aug 13, 2003 6:26 pm

I've just been testing the new Pokemon Pinball and it does indeed support rumble on the Gameboy Player and it even detects that it runs on a GBP, you can't select rumble if it's not run on the GBP. I've been doing some preliminary tests on the GBP but haven't found anything yet. Maybe I should download the source to VBA and make some checks in it.
Anybody else got any good ideas?
_________________
I probably suck, my not is a programmer.

#9712 - sgeos - Thu Aug 14, 2003 6:25 pm

Has anyone dumped the GBP bios yet?

You could also dump the entire I/O area into sram from a GBA (just after it boots), put that in ROM and then compare it the I/O area in the GBP (just after it boots).

-Brendan

#9724 - FluBBa - Fri Aug 15, 2003 8:43 am

I dumped the GBP bios yesterday and it was the same as the normal GBA/SP. I'll try to write a program that dumps/compare the IO area today.
_________________
I probably suck, my not is a programmer.

#9727 - jenswa - Fri Aug 15, 2003 12:23 pm

Isn't it possible that the gbp just emulates 2 player games.
I don't know if emulate is the right word.
Prolly it has a build in option that sees the 2nd GC keypad
as another GBA, something like that i mean.
I just don't have the right words for it.

Just like the super gameboy for the SNES, was able to let you
play with 2 players on one game with 2 SNES pads.
(I played KI with a friend).
_________________
It seems this wasn't lost after all.

#9736 - FluBBa - Fri Aug 15, 2003 4:16 pm

I dumped the IO area and both IWRAM and EWRAM no difference to a normal GBA. I used CowBite to look for unknown reads/writes but nothing came up there either. The last thing I tried now was to look at reads from 0x4000130 (joypad) and Pokemon Pinball seem to check for 0xf0 (up, down, left & right, all at the same time) the first few frames.
_________________
I probably suck, my not is a programmer.

#9737 - tepples - Fri Aug 15, 2003 4:40 pm

Remember that 0x04000130 is active LOW. Do you mean 0x00f0, L+R+A+B+Sel+Start, or do you mean 0x030f, Right+Left+Up+Down?

I'd like to add that Game Boy games communicated with SGB through the joypad register as well.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#9738 - cappeca - Fri Aug 15, 2003 4:46 pm

Is it safe to assume that if there is another input register around, the value when no key is pressed is also 0x03FF?

#9749 - NEiM0D - Sat Aug 16, 2003 1:10 am

I checked with Visualboy Advance SDL and there are no writes/reads to any of the Joybus registers.
There are also no writes/reads to any of the Communication registers (RCNT etc) on boot up of Pokemon Pinball.

#9773 - FluBBa - Sun Aug 17, 2003 6:53 pm

The only thing I've found this far is the address used to store if the game is play on a normal GBA or GBP in Pokemon Pinball, and that is 0x02019C0C.
Set it to 0x01 to be able to turn on rumble in the prefs (3rd row at start menu). I can't guarantee that it will try to use the rumble but it probably does. Maybe it uses a special IRQ only found on the GBP?
Does anyone have any info on the SGB and how access the functions on it?
I read that the 2 highest bits in the Joypad Reg was zero on the SGB and 1's on a normal GB.
_________________
I probably suck, my not is a programmer.

#9784 - Dev - Mon Aug 18, 2003 2:38 am

If you're positive that &02019C0C is the correct address, you could always do a simple patch to VBA to find out when code accesses that location -- or at least narrow it down to a few places where it's being used.

Just a guess here, but detection probably takes place early on, and doesn't occur when the title is actually running -- Sure, it's possible, but it's not like a user can "change" whether or not they're using a GBP while it's running!

Of course, that assumes that detection is something more complicated than just checking a register -- i.e. based on some sort of communication back-and-forth, or somesuch.

I don't think 1.6 source has been posted yet, but since all you're really interested in is the initial detection, it shouldn't matter and 1.5x should suffice...

(I just noticed that NEiMOD was already poking around with VBA -- hopefully he'll see your update about the var address and do a quick test to see what's up!)

If it's checking for &00F0, that could be their "reset your memory card" button sequence -- IIRC, they had a similar sequence in Mario Kart (or one of the multiple Marios out there) that wiped out your saved games if you held those down at startup

Dev.

#9787 - sgeos - Mon Aug 18, 2003 5:31 am

Just a thought: One might be able to detect the GBP by setting a timer, running a bios function and then looking at the value in the timer.

As an aside, can the GBP play regular GB games?

-Brendan

#9800 - FluBBa - Mon Aug 18, 2003 2:22 pm

It seems that Nintendo is trying to be bad boys now...
If there is something wrong with the tiles/tilemap/palette while it display the "Gameboy Player" logo Pokemon Pinball doesn't recognice the GB player.
The game DMA's the tilemap every frame before it reads the Joypad port (0x130).
I haven't checked if it's just crc or a complete check of the logo data.
Don't know if the bldmod/coly regs are important yet.
This probably means you need another Nintendo copyrighted logo to be able to detect/use the specific Gameboy Player features :-(
Booooh!
But I'll keep on digging. (sorry for all the edits)
_________________
I probably suck, my not is a programmer.

#9807 - Dev - Mon Aug 18, 2003 5:05 pm

FluBBa wrote:

If there is something wrong with the tiles/tilemap/palette while it display the "Gameboy Player" logo Pokemon Pinball doesn't recognice the GB player.
The game DMA's the tilemap every frame before it reads the Joypad port (0x130).
I haven't checked if it's just crc or a complete check of the logo data.
Don't know if the bldmod/coly regs are important yet.
This probably means you need another Nintendo copyrighted logo to be able to detect/use the specific Gameboy Player features :-(


So your suspicion is that it requires that particular tileset to be sent to the hardware before checking for &00F0, and if the GBP doesn't see that exact sequence of data in memory (or being DMA'd or somesuch), then it won't send the correct signals?

I take it that you've modified the data being sent down, and observed that the GBP isn't recognized when you change the image? Or was your testing done on an emulator?

Dev.

#9815 - sgeos - Mon Aug 18, 2003 11:06 pm

Has anyone opened up a GBP and looked at the internal hardware? What is it like?

-Brendan

#9876 - arrid - Wed Aug 20, 2003 11:40 pm

http://www.gbadev.org/luna/gbplayer/page3.htm

It looks pretty much like a GBA but with an interface to the GC instead of a screen, buttons, speaker and battery/space for two AAs.

#10152 - FluBBa - Thu Aug 28, 2003 11:06 am

Ok, I think I've got the hang of how a game detects a GameBoy Player.
First thing, the logo.. it must be displayed but you can do it any way you like.
You can have it anywhere in VRAM, it can 256 colors or 16bit.
You can change all the palette entries that are not used.
It seems the GBP can only "see" what is on the LCD.
After this you can read the joypad port to check for it's precense.
The GBP will send 2 frames with normal 0x03FF and one frame with 0x030F as long as the logo is displayed.
I have not found out how to use the rumble and I would very much appreciate if someone could help with debugging this, both Pokemon Pinball and Super Mario Advance 4 supports this.
_________________
I probably suck, my not is a programmer.

#10222 - Dev - Sat Aug 30, 2003 3:34 am

How do you know it can be 16bit -- do you mean Mode 3/5, or do you mean 4bit per pixel, 16 colour?

Also, have you tried changing any of the "used" palette entries, or some of the graphic data itself, and checking if the GBP refuses to acknowledge the graphic?

Dev.

#10225 - FluBBa - Sat Aug 30, 2003 11:58 am

I meant exactly what I said, both 256 color modes and 16bit (not 16color) modes can be used, the GBP only get's the LCD output it seems.
And changing things was the first tests I did (see some posts back) and everything that changes the logo onscreen makes the test fail.
_________________
I probably suck, my not is a programmer.

#10228 - Dev - Sat Aug 30, 2003 5:32 pm

Did you have a particular title that used 16bit, or are you saying that you made a screen that was 16bit from the data that was 8bit?

IOW, you used the same graphics data but in 16bit, and it still worked?

It just seems very strange that they'd be checking for a specific screen display, rather than a set of DMA transfers of specific length/size/etc.

It would take a lot of chip space to check for an entire screen display, so I'm a bit surprised that they do it that way.

Also, in an earlier message, you wrote that it was DMAing the data every frame -- is that still required?

Dev.

#10229 - torne - Sat Aug 30, 2003 5:46 pm

Actually, it wouldn't take any chip space at all. It could trivially be done in software on the Cube. =)

#10230 - Dev - Sat Aug 30, 2003 5:48 pm

True -- I forgot that you need to boot software first -- perhaps that's exactly how it's being done.

Dev.

#10231 - torne - Sat Aug 30, 2003 6:02 pm

Yep, they can pretty much make it arbitrarily complicated, as both sides are software (the player app on the gc, and the game code on the gba)

#10232 - Dev - Sat Aug 30, 2003 6:25 pm

It still seems odd that they'd go to all that trouble instead of, say, requiring a specific code or byte-sequence somewhere in memory, and then using that same memory to pass commands and data.

IOW, if the cube's software has arbitrary access to memory on the GBA side, why not make it fast and simple?

Checking for oscillating bits on the control pad after displaying a startup screen seems quite complex.

Dev.

#10233 - torne - Sat Aug 30, 2003 6:29 pm

Who can say why N do things? It is not for mortals to understand their workings. =)

#10244 - FluBBa - Sun Aug 31, 2003 11:37 am

I just used VBA to take a screenshot off a title that displayed the Game Boy Player logo, then converted it to 15bit raw and used it in PCEAdvance as a splash screen. I changed the code in PCEAdvance to check the joypad port for 0x030F while displaying the splash and it works. No need for DMAing stuff all the time, and no need for a specific screen mode.
Now all I want to know is if there is support for more then one player/joypad, and how to implement it.
_________________
I probably suck, my not is a programmer.

#10249 - sgeos - Sun Aug 31, 2003 5:19 pm

FluBBa wrote:
I just used VBA to take a screenshot off...
Now all I want to know is if there is support for more then one player/joypad, and how to implement it.


I'd also like to *know how* to use the rumble feature. I'd probably never use it, but it would still be neat to know how.

-Brendan

#10470 - Quirky - Sat Sep 06, 2003 12:17 am

FluBBa wrote:
I just used VBA to take a screenshot off a title that displayed the Game Boy Player logo, then converted it to 15bit raw and used it in PCEAdvance as a splash screen. I changed the code in PCEAdvance to check the joypad port for 0x030F while displaying the splash and it works. No need for DMAing stuff all the time, and no need for a specific screen mode.
Now all I want to know is if there is support for more then one player/joypad, and how to implement it.


So if I understand you correctly, the test for Gameboy Player is:


  1. Set the screen to any mode that is not 16-colour tile mode (mode 0-2 256 colour tiles or mode 3-5)
  2. Place the logo in VRAM so it's on screen
  3. Scan the joypad for 0x030F (this being register 0x04000130, right?) while displaying this screen


So I guess you could code it like this, right?

Code:

u8 isGBP = 0; // default not GBP

int main() {
  SetScreen(MODE_3); // or whatever...
  LoadGBPLogo();
  // show logo for 4 seconds (arbitrary time period...)
  int displaying = 240;
  while (displaying) {
    wait_vsync();
    if ( !(KEYS & 0x030F)) {
       // Gameboy Player!!
       isGBP = 1;
    }
    displaying--;
  }
}


And that is it? Then later on you could do ....

Code:

if (isGBP) {
   doRumble();
}


If only we knew what rumble was... I guess that it would be a simple thing like setting some register to some value. Or perhaps a strange bios call? Though that would, I guess, show up in VBA's "unknown swis" code if you forced a game to GBP mode.

#10481 - FluBBa - Sat Sep 06, 2003 10:58 am

That's exactly how to do it.
I've been doing some more test's with pokemon pinball but haven't found anything yet, it takes so much time to go through all the code just for a frames worth of time.
It would have been great if there was an emu which could log everything to a file, every opcode it executes or something like that.
_________________
I probably suck, my not is a programmer.

#10510 - edwdig - Sat Sep 06, 2003 8:09 pm

I first tried saving a screenshot with VisualBoy Advance, converting it to 256 color, and using that. Didn't work. Next I tried taking the .raw logo file off Flubba's site, including that into my code, and using that. Still didn't work. I'm using almost identical code to what Quirky posted.

#10715 - edwdig - Sat Sep 13, 2003 7:37 am

Figured out my problem... Quirky's example showed this:

if ( !(KEYS & 0x030F)) {

That has to be changed to:

if (KEYS == 0x030F) {

#13595 - FluBBa - Wed Dec 17, 2003 11:18 pm

Sorry to drag up this old thread again...
Seems like the GBP can generate serial interrupts all by itself, this makes it quite hard to debug it on emulators as they don't generate any serial interrupts (at all?).
I hacked "Pokemon Pinball" to halt if the serial irq was taken, this resulted in a crash on the GBP but it worked just fine on a normal GBA (it was also hacked to allow GBP features allways, so if I fired of a serial IRQ in the emulator it also crashed there).
Any ideas where to go next?
_________________
I probably suck, my not is a programmer.

#13606 - tepples - Thu Dec 18, 2003 5:50 am

Perhaps the GBP communication is through the same registers as the serial connection. If this is true, we're not going to see GBP support in emulators for a long time, until somebody else hacks serial support into VisualBoyAdvance.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#13613 - FluBBa - Thu Dec 18, 2003 9:37 am

Forgot to mention that if just returned from the serial irq everything worked fine except rumble...
I will try to write a program that communicates with the GBP to see if I can get any response at all from it.
It is probably easier to "emulate" the GBP then serial communication between 2 VBAs as you dont really need emulate it but more simulate what kind of responce you get from it, though we dont know much about that yet.
_________________
I probably suck, my not is a programmer.

#38732 - FluBBa - Thu Mar 31, 2005 1:13 am

Ok, got this baby working.
The GBP software will try to talk to the GBA side if you set up the SIOCNT register correctly (at least 32bit communication), after that you have to go through a quite long conversation with it and after that it seems that you just need to send 0x40000004 to keep the link and then 0x40000026 to turn on rumble.

I will put together an example in C and some docs about it soon.
_________________
I probably suck, my not is a programmer.

#38744 - MumblyJoe - Thu Mar 31, 2005 6:29 am

Good stuff man, thats what I call dedication! Can't wait for more info on this.
_________________
www.hungrydeveloper.com
Version 2.0 now up - guaranteed at least 100% more pleasing!

#38799 - FluBBa - Thu Mar 31, 2005 10:06 pm

I have succesfully implemented it in my upcoming Renegade emulator, so it rumbles when you get hit by the enemies. =)
Still has to clean up the code a bit.
_________________
I probably suck, my not is a programmer.

#39583 - FluBBa - Sun Apr 10, 2005 12:54 pm

Here is the code I use in RumblePong
Code:

#include "gba.h"


u32 SerialIn,DoRumble;
u16 stage,ind;
u16 SerOut0, SerOut1;
char const GBPData[]={"NINTENDO"};

void RumbleInterrupt(void) {
   u32 OutData=0;
   u16 SerIn0, SerIn1;
   u16 *GBPD2 = (u16*)GBPData;
   
   SerialIn = REG_SIODATA32;
   switch(stage) {
      case 0:
         SerIn0 = SerialIn>>16;
         SerIn1 = SerialIn;
         if(SerIn0 == SerOut1){
            if(ind <=3){
               if( SerialIn == ~(SerOut1 | (SerOut0<<16)) ){
                  ind++;
               }
            }else{
               if(SerIn1 == 0x8002){
                  OutData = 0x10000010;
                  stage=1;
                  break;
               }
            }
         }else{
            ind = 0;
         }
         if(ind <=3){
            SerOut0 = GBPD2[ind];
         }else{
            SerOut0 = 0x8000;
         }
         SerOut1 = ~SerIn1;
         OutData = SerOut1 | (SerOut0<<16);
         break;

      case 1:
         if(SerialIn == 0x10000010){
            OutData = 0x20000013;
            stage=2;
         }else{
            stage = 4;
         }
         break;

      case 2:
         if(SerialIn == 0x20000013){
            OutData = 0x40000004;
            stage=3;
         }else{
            stage = 4;
         }
         break;

      case 3:
         if(SerialIn == 0x30000003){
            if(DoRumble){
               DoRumble--;
               OutData = 0x40000026;
            }else{
               OutData = 0x40000004;
            }
         }else{
            stage = 4;
         }
         break;

      case 4:
         SerialIn = 0;
         DoRumble = 0;
         stage = 0;
         ind = 0;
         SerOut0 = 0;
         SerOut1 = 0;
         return;
   }

   REG_SIODATA32 = OutData;
   REG_SIOCNT |= 0x80;
}

void StartRumbleComs(void) {
   if(SerialIn != 0x30000003){
      REG_RCNT = 0x0;
      REG_SIOCNT = 0x1008;
      REG_SIOCNT |= 0x4000;
      REG_SIOCNT &=~1;
      REG_SIOCNT |= 0x0080;
   }
}


StartRumbleComs should probably be called around once a second, then you write number of frames the rumble should be running in DoRumble.
Oh, and remember to show the Gameboy Player logo before you start your game.
This is what I have reverse enginered, I haven't done much experimenting to see if there are more commands that can be used on the Gameboy Player, this is implemented in a Pong clone I made and my upcoming Renegade emulator. The full source for RumblePong can be downloaded from my homepage though it is for ARM SDT. If someone can make a version for GCC I would appreciate it, but it would be even better if someone implements rumble in a completly new game =)
_________________
I probably suck, my not is a programmer.