1 //////////////////////////////////////////////////////////////////////////////////////// 2 // 3 // Nestopia - NES/Famicom emulator written in C++ 4 // 5 // Copyright (C) 2003-2008 Martin Freij 6 // 7 // This file is part of Nestopia. 8 // 9 // Nestopia is free software; you can redistribute it and/or modify 10 // it under the terms of the GNU General Public License as published by 11 // the Free Software Foundation; either version 2 of the License, or 12 // (at your option) any later version. 13 // 14 // Nestopia is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with Nestopia; if not, write to the Free Software 21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 // 23 //////////////////////////////////////////////////////////////////////////////////////// 24 25 #include "NstInpDevice.hpp" 26 #include "NstInpPachinko.hpp" 27 28 namespace Nes 29 { 30 namespace Core 31 { 32 namespace Input 33 { 34 #ifdef NST_MSVC_OPTIMIZE 35 #pragma optimize("s", on) 36 #endif 37 Pachinko(const Cpu & c)38 Pachinko::Pachinko(const Cpu& c) 39 : Device(c,Api::Input::PACHINKO) 40 { 41 Pachinko::Reset(); 42 } 43 Reset()44 void Pachinko::Reset() 45 { 46 strobe = 0; 47 stream = 0; 48 state = 0xFF0000; 49 } 50 SaveState(State::Saver & saver,const byte id) const51 void Pachinko::SaveState(State::Saver& saver,const byte id) const 52 { 53 saver.Begin( AsciiId<'P','A'>::R(0,0,id) ).Write8( strobe ).Write32( stream ).End(); 54 } 55 LoadState(State::Loader & loader,const dword id)56 void Pachinko::LoadState(State::Loader& loader,const dword id) 57 { 58 if (id == AsciiId<'P','A'>::V) 59 { 60 strobe = loader.Read8() & 0x1; 61 stream = loader.Read32(); 62 } 63 } 64 65 #ifdef NST_MSVC_OPTIMIZE 66 #pragma optimize("", on) 67 #endif 68 Peek(uint port)69 uint Pachinko::Peek(uint port) 70 { 71 if (port == 0) 72 { 73 port = stream; 74 stream >>= 1; 75 return port & 0x2; 76 } 77 else 78 { 79 return 0; 80 } 81 } 82 Poke(uint data)83 void Pachinko::Poke(uint data) 84 { 85 const uint prev = strobe; 86 strobe = data & 0x1; 87 88 if (prev > strobe) 89 { 90 if (input) 91 { 92 Controllers::Pachinko& pachinko = input->pachinko; 93 input = NULL; 94 95 if (Controllers::Pachinko::callback( pachinko )) 96 { 97 uint throttle = Clamp<-64,+63>(pachinko.throttle) + 192; 98 99 throttle = 100 ( 101 (throttle >> 7 & 0x01) | 102 (throttle >> 5 & 0x02) | 103 (throttle >> 3 & 0x04) | 104 (throttle >> 1 & 0x08) | 105 (throttle << 1 & 0x10) | 106 (throttle << 3 & 0x20) | 107 (throttle << 5 & 0x40) | 108 (throttle << 7 & 0x80) 109 ); 110 111 state = ((pachinko.buttons & 0xFF) | (throttle << 8) | 0xFF0000UL) << 1; 112 } 113 } 114 115 stream = state; 116 } 117 } 118 } 119 } 120 } 121