Anda di halaman 1dari 4

codeslinger.co.

uk
H o mB e a s Zi u c k sM o e g a D r M i a v e s /t G e re n S e y s Cs i ht s ie Bpm l 8 o Gamebo y g

codeslinger.co.uk
Gamebo y - Jo ypad.

Joypad:
The gamebo y has an inbuilt jo ypad with 8 butto ns. There are 4 directio nal butto ns (up, do wn, left and right) and standard butto ns (start,select, A and B). The jo ypad register can be fo und at address 0 xFF0 0 and it is bro ken do wn like so :

Gameboy Emulation:
Getting Started The Hardware Memory Control and Map ROM and RAM Banking The Timers Interupts LCD DMA Transfer Graphic Emulation

Taken fro m pando cs Bit 7 - No t used Bit 6 - No t used Bit 5 - P15 Select Butto n Keys (0 =Select) Bit 4 - P14 Select Directio n Keys (0 =Select) Bit 3 - P13 Input Do wn o r Start (0 =Pressed) (Read Only) Bit 2 - P12 Input Up o r Select (0 =Pressed) (Read Only) Bit 1 - P11 Input Left o r Butto n B (0 =Pressed) (Read Only) Bit 0 - P10 Input Right o r Butto n A (0 =Pressed) (Read Only)

Bits 0 -3 are set by the emulato r to sho w the state o f the jo ypad. As yo u can see the directio nal butto ns and the standard butto ns share this range o f bits so ho w wo uld the game kno w if bit 3 was set whether it was the directio nal do wn butto n o r the stanadrd start butto n? The way this wo rks is that the game sets bit 4 and 5 depending o n whether it wants to check o n the directio nal butto ns o r the standard butto ns.

Joypad Emulation Opcode Examples Finished Product PDFmyURL.com

Finished Product

The way I believe this wo rks in the o riginal gamebo y hardware is the game writes to memo ry 0 xFF0 0 with bit 4 o r 5 set (never bo th). It then reads fro m memo ry 0 xFF0 0 and instead o f reading back what it just wro te what is returned is the state o f the jo ypad based o n whether bit 4 o r bit 5 was set. Fo r example if the game wanted to check which directio nal butto ns was pressed it wo uld set bit 4 to 1 and then it wo uld do a read memo ry o n 0 xFF0 0 . If the up key is pressed then when reading 0 xFF0 0 bit 2 wo uld be set to 0 to signal that the directio nal butto n up is pressed (0 means pressed, 1 unpressed). Ho wever if up was no t pressed but the select butto n was then bit 2 wo uld be left at 1 meaning no thing is pressed, even tho ugh the select butto n is pressed which maps o n to bit 2. The reaso n why bit 2 wo uld be set to 1 signalling it is no t pressed even when it is is because bit 4 was set to 1 meaning the game is o nly interested in the state o f the directio nal butto ns. The way I emulate this is I have a BYTE variabled called m_Jo ypadState where each bit represents the state o f the jo ypad (8 butto ns and 8 bits so it wo rks fine). Whenever a butto n is pressed I set the co rrect bit in m_Jo ypadState to 0 and if it is no t pressed it is set to 1. If a bit in m_Jo ypadState go es fro m 1 to 0 then it means this butto n has just been pressed so a jo ypad interupt is requested. Whenever the game reads fro m 0 xFF0 0 i trap it with ReadMemo ry and call a functio n which lo o ks at memo ry address 0 xFF0 0 to see if the game is interest in directio nal butto ns o r standard butto ns and then I return a byte data which co mbines m_Jo ypadState with 0 xFF0 0 so the game gets the co rrect state o f the jo ypad. While I remember lets add the fo llo wing to ReadMemo ry else if (0xFF00 == address) return GetJoypadState() ;

Befo re I sho w yo u the implementatio n o f GetJo ypadState I'll sho w yo u ho w to set m_Jo ypadState which GetJo ypadState will need. void Emulator::KeyPressed(int key) { bool previouslyUnset = false ; // if setting from 1 to 0 we may have to request an interupt if (TestBit(m_JoypadState, key)==false) previouslyUnset = true ; // remember if a keypressed its bit is 0 not 1 m_JoypadState = BitReset(m_JoypadState, key) ; // button pressed bool button = true ; // is this a standard button or a directional button?
PDFmyURL.com

if (key > 3) button = true ; else // directional button pressed button = false ; BYTE keyReq = m_Rom[0xFF00] ; bool requestInterupt = false ; // only request interupt if the button just pressed is // the style of button the game is interested in if (button && !TestBit(keyReq,5)) requestInterupt = true ; // same as above but for directional button else if (!button && !TestBit(keyReq,4)) requestInterupt = true ; // request interupt if (requestInterupt && !previouslyUnset) RequestInterupt(4) ; }

The functio n thats called when a key is released is much simpler void Emulator::KeyReleased(int key) { m_JoypadState = BitSet(m_JoypadState,key) ; }

The way I call the abo ve functio ns is with SDL_KeyEvents. Whenever a key is pressed I call KeyPressed functio n passing the fo llo wing in as arguments SDLK_a : key = 4 SDLK_s : key = 5 SDLK_RETURN : key = 7 SDLK_SPACE : key = 6 SDLK_RIGHT : key = 0 SDLK_LEFT : key = 1
PDFmyURL.com

SDLK_UP : key = 2 SDLK_DOWN : key = 3

No w we have everything needed to write the GetJo ypadState functio n BYTE Emulator::GetJoypadState() const { BYTE res = m_Rom[0xFF00] ; // flip all the bits res ^= 0xFF ; // are we interested in the standard buttons? if (!TestBit(res, 4)) { BYTE topJoypad = m_JoypadState >> 4 ; topJoypad |= 0xF0 ; // turn the top 4 bits on res &= topJoypad ; // show what buttons are pressed } else if (!TestBit(res,5))//directional buttons { BYTE bottomJoypad = m_JoypadState & 0xF ; bottomJoypad |= 0xF0 ; res &= bottomJoypad ; } return res ; }

If yo u are co nfused why m_Jo ypadState is shifted left 4 times when checking standard butto ns is because the standard butto ns are sto red in the to p nibble o f m_Jo ypadState but then need to be in the lo wer nibble fo r when it gets lo gically o r'd.

Copyright 2008 codeslinger.co.uk

PDFmyURL.com

Anda mungkin juga menyukai