diff --git a/Changes.txt b/Changes.txt index 479bac355..68f330237 100644 --- a/Changes.txt +++ b/Changes.txt @@ -24,6 +24,9 @@ have only one 2600-daptor and want to use it as a left port normally, but as a right port for Star Raiders, etc). + * Added CompuMate bankswitching/controller support; the CompuMate + NTSC and PAL ROMs now work correctly. + * Fixed bug in BoosterGrip controller emulation; the functionality of the booster and trigger buttons was reversed. Related to this, renamed these actions in the Event Mapping dialog to be more clear. diff --git a/src/common/StellaKeys.hxx b/src/common/StellaKeys.hxx index 46bf4d3e3..84bc87921 100644 --- a/src/common/StellaKeys.hxx +++ b/src/common/StellaKeys.hxx @@ -20,6 +20,8 @@ #ifndef STELLA_KEYS_HXX #define STELLA_KEYS_HXX +#include + /** This class implements a thin wrapper around the SDL keysym enumerations, such that SDL-specific code doesn't have to go into the internal parts of @@ -310,4 +312,12 @@ typedef enum { // The underlying code doesn't need to know how it's implemented typedef int StellaMod; +// Wrapper around the SDL_GetKeyState function +// This can be used as-is since KBDK keys and SDL keys are the same +class StellaKeys +{ + public: + static uInt8* GetKeyState() { return SDL_GetKeyState(NULL); } +}; + #endif /* StellaKeys */ diff --git a/src/emucore/CartCM.cxx b/src/emucore/CartCM.cxx index 19178d3aa..be837084e 100644 --- a/src/emucore/CartCM.cxx +++ b/src/emucore/CartCM.cxx @@ -83,8 +83,7 @@ uInt8 CartridgeCM::peek(uInt16 address) { // NOTE: This does not handle accessing cart ROM/RAM, however, this function // should never be called for ROM/RAM because of the way page accessing - // has been setup - // It will only ever be called for RIOT reads + // has been setup (it will only ever be called for RIOT reads) return mySystem->m6532().peek(address); } @@ -118,8 +117,8 @@ bool CartridgeCM::bank(uInt16 bank) uInt16 offset = myCurrentBank << 12; uInt16 shift = mySystem->pageShift(); - // Although this scheme contains four 4K banks and one 2K bank, it's easier - // to think of things in terms of 2K slices, as follows: + // Although this scheme contains four 4K ROM banks and one 2K RAM bank, + // it's easier to think of things in terms of 2K slices, as follows: // // The lower 2K of cart address space always points to the lower 2K of the // current ROM bank diff --git a/src/emucore/CartCM.hxx b/src/emucore/CartCM.hxx index b64be7e03..3353088aa 100644 --- a/src/emucore/CartCM.hxx +++ b/src/emucore/CartCM.hxx @@ -108,8 +108,6 @@ class System; */ class CartridgeCM : public Cartridge { - friend class CompuMate; - public: /** Create a new cartridge using the specified image @@ -213,6 +211,13 @@ class CartridgeCM : public Cartridge */ bool poke(uInt16 address, uInt8 value); + /** + Get the current keybord column + + @return The column referenced by SWCHA D6 and D5 + */ + uInt8 column() const { return myColumn; } + private: // Indicates which bank is currently active uInt16 myCurrentBank; diff --git a/src/emucore/CompuMate.cxx b/src/emucore/CompuMate.cxx index f20aa6316..2fe25f929 100644 --- a/src/emucore/CompuMate.cxx +++ b/src/emucore/CompuMate.cxx @@ -19,6 +19,7 @@ #include "Control.hxx" #include "System.hxx" +#include "StellaKeys.hxx" #include "CompuMate.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -29,11 +30,15 @@ CompuMate::CompuMate(CartridgeCM& cart, const Event& event, mySystem(system), myLeftController(0), myRightController(0), - myCycleAtLastUpdate(0), - myColumn(0) + myCycleAtLastUpdate(0) { myLeftController = new CMControl(*this, Controller::Left, event, system); myRightController = new CMControl(*this, Controller::Right, event, system); + + myLeftController->myAnalogPinValue[Controller::Nine] = Controller::maximumResistance; + myLeftController->myAnalogPinValue[Controller::Five] = Controller::minimumResistance; + myRightController->myAnalogPinValue[Controller::Nine] = Controller::minimumResistance; + myRightController->myAnalogPinValue[Controller::Five] = Controller::maximumResistance; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -52,92 +57,85 @@ void CompuMate::update() // Handle SWCHA changes - the following comes almost directly from z26 Controller& lp = *myLeftController; Controller& rp = *myRightController; - uInt8 IOPortA = (lp.read() << 4) | rp.read(); + uInt8* KeyTable = StellaKeys::GetKeyState(); lp.myAnalogPinValue[Controller::Nine] = Controller::maximumResistance; lp.myAnalogPinValue[Controller::Five] = Controller::minimumResistance; lp.myDigitalPinState[Controller::Six] = true; - rp.myAnalogPinValue[Controller::Nine] = Controller::minimumResistance; rp.myAnalogPinValue[Controller::Five] = Controller::maximumResistance; rp.myDigitalPinState[Controller::Six] = true; + rp.myDigitalPinState[Controller::Three] = true; + rp.myDigitalPinState[Controller::Four] = true; - uInt8& column = myCart.myColumn; - if(IOPortA & 0x20) column = 0; - if(IOPortA & 0x40) column = (column + 1) % 10; + if (KeyTable[KBDK_LSHIFT]) + rp.myAnalogPinValue[Controller::Five] = Controller::minimumResistance; + if (KeyTable[KBDK_LCTRL]) + lp.myAnalogPinValue[Controller::Nine] = Controller::minimumResistance; - IOPortA = IOPortA | (0x0c & 0x7f); - -#if 0 - switch(column) + switch(myCart.column()) { case 0: - if (KeyTable[Key7]) lp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyU]) IOPortA = IOPortA & 0xfb; - if (KeyTable[KeyJ]) rp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyM]) IOPortA = IOPortA & 0xf7; + if (KeyTable[KBDK_7]) lp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_u]) rp.myDigitalPinState[Controller::Three] = false; + if (KeyTable[KBDK_j]) rp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_m]) rp.myDigitalPinState[Controller::Four] = false; break; case 1: - if (KeyTable[Key6]) lp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyY]) IOPortA = IOPortA & 0xfb; - if (KeyTable[KeyH]) rp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyN]) IOPortA = IOPortA & 0xf7; + if (KeyTable[KBDK_6]) lp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_y]) rp.myDigitalPinState[Controller::Three] = false; + if (KeyTable[KBDK_h]) rp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_n]) rp.myDigitalPinState[Controller::Four] = false; break; case 2: - if (KeyTable[Key8]) lp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyI]) IOPortA = IOPortA & 0xfb; - if (KeyTable[KeyK]) rp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyComma]) IOPortA = IOPortA & 0xf7; + if (KeyTable[KBDK_8]) lp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_i]) rp.myDigitalPinState[Controller::Three] = false; + if (KeyTable[KBDK_k]) rp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_COMMA]) rp.myDigitalPinState[Controller::Four] = false; break; case 3: - if (KeyTable[Key2]) lp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyW]) IOPortA = IOPortA & 0xfb; - if (KeyTable[KeyS]) rp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyX]) IOPortA = IOPortA & 0xf7; + if (KeyTable[KBDK_2]) lp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_w]) rp.myDigitalPinState[Controller::Three] = false; + if (KeyTable[KBDK_s]) rp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_x]) rp.myDigitalPinState[Controller::Four] = false; break; case 4: - if (KeyTable[Key3]) lp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyE]) IOPortA = IOPortA & 0xfb; - if (KeyTable[KeyD]) rp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyC]) IOPortA = IOPortA & 0xf7; + if (KeyTable[KBDK_3]) lp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_e]) rp.myDigitalPinState[Controller::Three] = false; + if (KeyTable[KBDK_d]) rp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_c]) rp.myDigitalPinState[Controller::Four] = false; break; case 5: - if (KeyTable[Key0]) lp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyP]) IOPortA = IOPortA & 0xfb; - if (KeyTable[KeyColon]) rp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeySlash]) IOPortA = IOPortA & 0xf7; + if (KeyTable[KBDK_0]) lp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_p]) rp.myDigitalPinState[Controller::Three] = false; + if (KeyTable[KBDK_COLON]) rp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_SLASH]) rp.myDigitalPinState[Controller::Four] = false; break; case 6: - if (KeyTable[Key9]) lp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyO]) IOPortA = IOPortA & 0xfb; - if (KeyTable[KeyL]) rp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyDot]) IOPortA = IOPortA & 0xf7; + if (KeyTable[KBDK_9]) lp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_o]) rp.myDigitalPinState[Controller::Three] = false; + if (KeyTable[KBDK_l]) rp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_PERIOD]) rp.myDigitalPinState[Controller::Four] = false; break; case 7: - if (KeyTable[Key5]) lp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyT]) IOPortA = IOPortA & 0xfb; - if (KeyTable[KeyG]) rp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyB]) IOPortA = IOPortA & 0xf7; + if (KeyTable[KBDK_5]) lp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_t]) rp.myDigitalPinState[Controller::Three] = false; + if (KeyTable[KBDK_g]) rp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_b]) rp.myDigitalPinState[Controller::Four] = false; break; case 8: - if (KeyTable[Key1]) lp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyQ]) IOPortA = IOPortA & 0xfb; - if (KeyTable[KeyA]) rp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyZ]) IOPortA = IOPortA & 0xf7; + if (KeyTable[KBDK_1]) lp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_q]) rp.myDigitalPinState[Controller::Three] = false; + if (KeyTable[KBDK_a]) rp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_z]) rp.myDigitalPinState[Controller::Four] = false; break; case 9: - if (KeyTable[Key4]) lp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyR]) IOPortA = IOPortA & 0xfb; - if (KeyTable[KeyF]) rp.myDigitalPinState[Controller::Six] = false; - if (KeyTable[KeyV]) IOPortA = IOPortA & 0xf7; + if (KeyTable[KBDK_4]) lp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_r]) rp.myDigitalPinState[Controller::Three] = false; + if (KeyTable[KBDK_f]) rp.myDigitalPinState[Controller::Six] = false; + if (KeyTable[KBDK_v]) rp.myDigitalPinState[Controller::Four] = false; break; default: break; } -#endif - // Convert back to digital pins - rp.myDigitalPinState[Controller::One] = IOPortA & 0x01; - rp.myDigitalPinState[Controller::Two] = IOPortA & 0x02; - rp.myDigitalPinState[Controller::Three] = IOPortA & 0x04; - rp.myDigitalPinState[Controller::Four] = IOPortA & 0x08; } diff --git a/src/emucore/CompuMate.hxx b/src/emucore/CompuMate.hxx index 49db2282a..6f70b4fb8 100644 --- a/src/emucore/CompuMate.hxx +++ b/src/emucore/CompuMate.hxx @@ -89,18 +89,7 @@ class CompuMate const System& system) : Controller(jack, event, system, Controller::CompuMate), myHandler(handler) - { - if(myJack == Left) - { - myAnalogPinValue[Five] = minimumResistance; - myAnalogPinValue[Nine] = maximumResistance; - } - else - { - myAnalogPinValue[Five] = maximumResistance; - myAnalogPinValue[Nine] = minimumResistance; - } - } + { } /** Destructor @@ -135,9 +124,6 @@ class CompuMate // System cycle at which the update() method is called // Multiple calls at the same cycle should be ignored uInt32 myCycleAtLastUpdate; - - // Column currently active - uInt8 myColumn; }; #endif