The first released option pack is the "Rumble Pak" (NTR-A-ZV / model NTR-008), which comes bundled with Metroid Prime Pinball. This black cartridge is exactly the same size as a normal GBA game pak, but contains a small actuator made by ALPS to make it rumble.
Grab a demo with source code to use the Rumble Pak here. This is a bad way to do it, as it's just a cleaned up version of a debug app. It'd be much better to set up a timer interrupt and adjust the frequency or enable/disable it.
The rumble pak is pretty simple internally (this info comes from a NTR-A-ZV-USA cart, PCB screened NTR-NRC-01), and only wires up to a few pins on the GBA Cartridge Port:
* VCC
* /WR
* AD1
* IRQ (grounded)
* GND
AD1 runs into a little 8 pin chip, which is probably just a latch on the rising edge of /WR. A line runs from this chip to a transistor that is directly connected to the actuator. The only other chip on the board is a 5 pin jobber, probably a power component.
Using the cartridge is simplicity itself, it just latches bit 1 of any value written to the cartridge and uses that to put the actuator in a particular position.
Code snippet:
#define
P __attribute__
typedef struct
sGBAHeader {
P uint32 entryPoint;
P uint8 logo[156];
P char title[0xC];
P char gamecode[0x4];
P uint16 makercode;
P uint8 is96h;
P uint8 unitcode;
P uint8 devicecode;
P uint8 unused[7];
P uint8 version;
P uint8 complement;
P uint16 checksum;
} tGBAHeader;
#undef
P
#define
GBA_HEADER (*(tGBAHeader *)0x08000000)
#define
GBA_BUS
#define
RUMBLE_PAK (*(vuint16 *)0x08000000)
bool isRumbleInserted(void) {
uint16 four[4];
sysSetCartOwner(true);
// First, check for 0x96 to see if it's a GBA game
if (GBA_HEADER.is96h == 0x96) {
return false;
} else {
// Now check to see if it's true open bus, or if D1 is pulled low
four[0] = GBA_BUS[0] & 0xFF;
four[1] = GBA_BUS[1] & 0xFF;
four[2] = GBA_BUS[2] & 0xFF;
four[3] = GBA_BUS[3] & 0xFF;
return (four[0] == 0x00) && (four[2] == 0x00) && (four[1] == 0x01) && (four[3] == 0x01);
}
}
void setRumble(bool position) {
RUMBLE_PAK = position ? 2 : 0;
}
The actuator doesn't have an on/off setting like a motor, it rumbles when you switch it between the two settings. Switch frequently for a fast rumble, and fairly slowly for more of a 'tick' effect.
I am currently detecting if it is a rumble pak or plain open bus by the fact that the rumble pak seems to pull AD1 low, or at least keep it from mirroring A1 during an open-bus read.
Additional notes:
The firmware can detect the Rumble Pak as an option pak, but it does not provide an enable/disable rumble option in the alarm menu (on v3 firmware). They apparently changed the design between creation of the firmware and creation of the rumble pak. It would be interesting to see if this is different in v4 firmware, although I doubt it will be.
最終更新:2007年12月09日 22:26