bool JoystickInfo::Init(int id) { Destroy(); _id = id; joy = SDL_JoystickOpen(id); if (joy == NULL) { PAD_LOG("failed to open joystick %d\n", id); return false; } numaxes = SDL_JoystickNumAxes(joy); numbuttons = SDL_JoystickNumButtons(joy); numhats = SDL_JoystickNumHats(joy); #if SDL_MAJOR_VERSION >= 2 devname = SDL_JoystickName(joy); #else devname = SDL_JoystickName(id); #endif vaxisstate.resize(numaxes); vbuttonstate.resize(numbuttons); vhatstate.resize(numhats); // Sixaxis, dualshock3 hack // Most buttons are actually axes due to analog pressure support. Only the first 4 buttons // are digital (select, start, l3, r3). To avoid conflict just forget the others. // Keep the 4 hat buttons too (usb driver). (left pressure does not work with recent kernel). Moreover the pressure // work sometime on half axis neg others time in fulll axis. So better keep them as button for the moment u32 found_hack = devname.find(string("PLAYSTATION(R)3")); if (found_hack != string::npos && numaxes > 4) { numbuttons = 4; // (select, start, l3, r3) // Enable this hack in bluetooth too. It avoid to restart the onepad gui numbuttons += 4; // the 4 hat buttons } #if SDL_MAJOR_VERSION >= 2 if ( haptic == NULL ) { if (!SDL_JoystickIsHaptic(joy)) { PAD_LOG("Haptic devices not supported!\n"); } else { haptic = SDL_HapticOpenFromJoystick(joy); // upload some default effect InitHapticEffect(); } } #endif //PAD_LOG("There are %d buttons, %d axises, and %d hats.\n", numbuttons, numaxes, numhats); return true; }
s32 CALLBACK PADinit(u32 flags) { #ifdef PAD_LOG if (padLog == NULL) { padLog = fopen("logs/padLog.txt", "w"); if (padLog) setvbuf(padLog, NULL, _IONBF, 0); } PAD_LOG("PADinit\n"); #endif pads|= flags; status[0] = 0xffff; status[1] = 0xffff; #ifdef __LINUX__ char strcurdir[256]; getcwd(strcurdir, 256); s_strIniPath = strcurdir; s_strIniPath += "/inis/zeropad.ini"; #endif LoadConfig(); PADsetMode(0, 0); PADsetMode(1, 0); pressure = 100; for(int i = 0; i < 2; ++i) { g_ranalog[i].x = 0x80; g_ranalog[i].y = 0x80; g_lanalog[i].x = 0x80; g_lanalog[i].y = 0x80; } return 0; }
void sioInterrupt() { #ifdef PAD_LOG PAD_LOG("Sio Interrupt (CP0.Status = %x)\n", psxRegs.CP0.n.Status); #endif // SysPrintf("Sio Interrupt\n"); StatReg|= IRQ; psxHu32ref(0x1070)|= SWAPu32(0x80); }
u32 sio2_getRecv3() { if(sio2.packet.recvVal3 == 0x8C || sio2.packet.recvVal3 == 0x8b || sio2.packet.recvVal3 == 0x83) { PAD_LOG("Reading Recv3 = %x",sio2.packet.recvVal3); sio.packetsize = sio2.packet.recvVal3; sio2.packet.recvVal3 = 0; // Reset return sio.packetsize; } else { PAD_LOG("Reading Recv3 = %x",sio.packetsize << 16); return sio.packetsize << 16; } }
void sioInterrupt() { #ifdef PAD_LOG PAD_LOG("Sio Interrupt (CP0.Status = %x)\n", psxRegs.CP0.n.Status); #endif if (!(StatReg & IRQ)) { StatReg |= IRQ; psxHu32ref(0x1070) |= SWAPu32(0x80); } }
u8 CALLBACK PADstartPoll(int pad) { #ifdef PAD_LOG PAD_LOG("PADstartPoll: %d\n", pad); #endif curPad = pad-1; curByte = 0; return 0xff; }
const char* PlatformKeysymToString(int keysym) { //const char* ret = SDL_GetScancodeName((SDL_Scancode)keysym); const char* ret = SDL_GetKeyName(keysym); if (keysym >= 0x61 && keysym <= 0x7A) { PAD_LOG("The character %s code %i is lowercase!\n", ret, keysym); } return ret; }
bool JoystickInfo::PollAxes(u32 &pkey) { for (int i = 0; i < GetNumAxes(); ++i) { // Sixaxis, dualshock3 hack u32 found_hack = devname.find(string("PLAYSTATION(R)3")); if (found_hack != string::npos) { // The analog mode of the hat button is quite erratic. Values can be in half- axis // or full axis... So better keep them as button for the moment -- gregory if (i >= 8 && i <= 11 && (conf->pad_options[pad].sixaxis_usb)) continue; // Disable accelerometer if ((i >= 4 && i <= 6)) continue; } s32 value = SDL_JoystickGetAxis(GetJoy(), i); s32 old_value = GetAxisState(i); if (abs(value - old_value) < 0x1000) continue; if (value != old_value) { PAD_LOG("Change in joystick %d: %d.\n", i, value); // There are several kinds of axes // Half+: 0 (release) -> 32768 // Half-: 0 (release) -> -32768 // Full (like dualshock 3): -32768 (release) ->32768 const s32 full_axis_ceil = -0x6FFF; const s32 half_axis_ceil = 0x1FFF; // Normally, old_value contains the release state so it can be used to detect the types of axis. bool is_full_axis = (old_value < full_axis_ceil) ? true : false; if ((!is_full_axis && abs(value) <= half_axis_ceil) || (is_full_axis && value <= full_axis_ceil)) // we don't want this { continue; } if ((!is_full_axis && abs(value) > half_axis_ceil) || (is_full_axis && value > full_axis_ceil)) { bool sign = (value < 0); pkey = axis_to_key(is_full_axis, sign, i); return true; } } } return false; }
void sio2_setSend3(u32 index, u32 value) { // int i; sio2.packet.sendArray3[index]=value; // if (index==15){ // for (i=0; i<4; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray1[i]);}PAD_LOG("\n"); // for (i=0; i<4; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray2[i]);}PAD_LOG("\n"); // for (i=0; i<8; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray3[i]);}PAD_LOG("\n"); // for ( ; i<16; i++){PAD_LOG("0x%08X ", sio2.packet.sendArray3[i]);}PAD_LOG("\n"); PAD_LOG("[%d] : 0x%08X", index,sio2.packet.sendArray3[index]); // } } //0->15
void sioWriteCtrl16(unsigned short value) { #ifdef PAD_LOG PAD_LOG("sio ctrlwrite16 %x (PAR:%x PAD:%x MCD:%x)\n", value, parp, padst, mcdst); #endif CtrlReg = value & ~RESET_ERR; if (value & RESET_ERR) StatReg &= ~IRQ; if ((CtrlReg & SIO_RESET) || (!CtrlReg)) { padst = 0; mcdst = 0; parp = 0; StatReg = TX_RDY | TX_EMPTY; psxRegs.interrupt &= ~(1 << PSXINT_SIO); } }
s32 _PADopen(void *pDsp) { SPININIT(mutex_KeyEvent); mutex_WasInit = true; GSdsp = reinterpret_cast<GSdspTPtr>(static_cast<uptr*>(pDsp)[0]); GSwin = reinterpret_cast<GSwinTPtr>(static_cast<uptr*>(pDsp)[1]); PAD_LOG("Got Display/Window handle %p/%p\n", GSdsp, GSwin); SetAutoRepeat(false); return 0; }
void config_key(int pad, int key) { bool captured = false; u32 key_pressed = 0; // save the joystick states UpdateJoysticks(); while (!captured) { vector<JoystickInfo*>::iterator itjoy; if (PollX11KeyboardMouseEvent(key_pressed)) { // special case for keyboard/mouse to handle multiple keys // Note: key_pressed == 0 when ESC is hit to abort the capture if (key_pressed > 0) set_keyboad_key(pad, key_pressed, key); captured = true; break; } SDL_JoystickUpdate(); itjoy = s_vjoysticks.begin(); while ((itjoy != s_vjoysticks.end()) && (!captured)) { if ((*itjoy)->PollButtons(key_pressed)) { set_key(pad, key, key_pressed); captured = true; break; } if ((*itjoy)->PollAxes(key_pressed)) { set_key(pad, key, key_pressed); captured = true; break; } if ((*itjoy)->PollHats(key_pressed)) { set_key(pad, key, key_pressed); captured = true; break; } itjoy++; } } PAD_LOG("%s\n", KeyName(pad, key).c_str()); }
void initLogging() { #ifdef PAD_LOG if (padLog) return; const std::string LogFile(s_strLogPath + "padLog.txt"); padLog = fopen(LogFile.c_str(), "w"); if (padLog) setvbuf(padLog, NULL, _IONBF, 0); PAD_LOG("PADinit\n"); #endif }
void sioInterrupt() { #ifdef PAD_LOG PAD_LOG("Sio Interrupt (CP0.Status = %x)\n", psxRegs.CP0.n.Status); #endif // SysPrintf("Sio Interrupt\n"); StatReg |= IRQ; psxHu32ref(0x1070) |= SWAPu32(0x80); #if 0 // Rhapsody: fixes input problems // Twisted Metal 2: breaks intro StatReg |= TX_RDY; StatReg |= RX_RDY; #endif }
unsigned char sioRead8() { unsigned char ret = 0; if ((StatReg & RX_RDY)/* && (CtrlReg & RX_PERM)*/) { // StatReg &= ~RX_OVERRUN; ret = buf[parp]; if (parp == bufcount) { StatReg &= ~RX_RDY; // Receive is not Ready now if (mcdst == 5) { mcdst = 0; if (rdwr == 2) { switch (CtrlReg & 0x2002) { case 0x0002: memcpy(Mcd1Data + (adrL | (adrH << 8)) * 128, &buf[1], 128); SaveMcd(Config.Mcd1, Mcd1Data, (adrL | (adrH << 8)) * 128, 128); break; case 0x2002: memcpy(Mcd2Data + (adrL | (adrH << 8)) * 128, &buf[1], 128); SaveMcd(Config.Mcd2, Mcd2Data, (adrL | (adrH << 8)) * 128, 128); break; } } } if (padst == 2) padst = 0; if (mcdst == 1) { mcdst = 2; StatReg|= RX_RDY; } } } #ifdef PAD_LOG PAD_LOG("sio read8 ;ret = %x (I:%x ST:%x BUF:(%x %x %x))\n", ret, parp, StatReg, buf[parp>0?parp-1:0], buf[parp], buf[parp<BUFFER_SIZE-1?parp+1:BUFFER_SIZE-1]); #endif return ret; }
bool PollKeyboardMouseEvent(u32 &pkey) { // Cancel? if (wxGetKeyState(WXK_ESCAPE)) { pkey = 0; return true; } // Keyboard key states for (u32 i = WXK_NONE; i != WXK_SPECIAL20; i++) { if (wxGetKeyState(static_cast<wxKeyCode>(i))) { PAD_LOG("State %i\n", i); pkey = i; return true; } } // Mouse button states u32 initial = -1; wxMouseState state = wxGetMouseState(); if (state.LeftIsDown()) { initial = pkey = 1; } else if (state.MiddleIsDown()) { initial = pkey = 2; } else if (state.RightIsDown()) { initial = pkey = 3; } else if (state.Aux1IsDown()) { initial = pkey = 4; } else if (state.Aux2IsDown()) { initial = pkey = 5; } return (initial!=-1); }
u8 sioRead8() { u8 ret = 0; if ((StatReg & RX_RDY)/* && (CtrlReg & RX_PERM)*/) { // StatReg &= ~RX_OVERRUN; ret = buf[parp]; if (parp == bufcount) { StatReg &= ~RX_RDY; // Receive is not Ready now if (mcdst == 5) { mcdst = 0; if (rdwr == 2) { switch (CtrlReg & 0x2002) { case 0x0002: memcpy(psxMcd1.memory + (adrL | (adrH << 8)) * 128, &buf[1], 128); psxMcd1.write((adrL | (adrH << 8)) * 128, 128); break; case 0x2002: memcpy(psxMcd2.memory + (adrL | (adrH << 8)) * 128, &buf[1], 128); psxMcd2.write((adrL | (adrH << 8)) * 128, 128); break; } } } if (padst == 2) padst = 0; if (mcdst == 1) { mcdst = 2; StatReg|= RX_RDY; } } } #ifdef PAD_LOG PAD_LOG("sio read8 ;ret = %x\n", ret); #endif return ret; }
bool JoystickInfo::PollHats(u32 &pkey) { for (int i = 0; i < GetNumHats(); ++i) { int value = SDL_JoystickGetHat(GetJoy(), i); if ((value != GetHatState(i)) && (value != SDL_HAT_CENTERED)) { switch (value) { case SDL_HAT_UP: case SDL_HAT_RIGHT: case SDL_HAT_DOWN: case SDL_HAT_LEFT: pkey = hat_to_key(value, i); PAD_LOG("Hat Pressed!"); return true; default: break; } } } return false; }
void sioWrite8(unsigned char value) { #ifdef PAD_LOG PAD_LOG("sio write8 %x\n", value); #endif switch (padst) { case 1: SIO_INT(); if ((value&0x40) == 0x40) { padst = 2; parp = 1; if (!Config.UseNet) { switch (CtrlReg&0x2002) { case 0x0002: buf[parp] = PAD1_poll(value); break; case 0x2002: buf[parp] = PAD2_poll(value); break; } }/* else { // SysPrintf("%x: %x, %x, %x, %x\n", CtrlReg&0x2002, buf[2], buf[3], buf[4], buf[5]); }*/ if (!(buf[parp] & 0x0f)) { bufcount = 2 + 32; } else { bufcount = 2 + (buf[parp] & 0x0f) * 2; } if (buf[parp] == 0x41) { switch (value) { case 0x43: buf[1] = 0x43; break; case 0x45: buf[1] = 0xf3; break; } } } else padst = 0; return; case 2: parp++; /* if (buf[1] == 0x45) { buf[parp] = 0; SIO_INT(); return; }*/ if (!Config.UseNet) { switch (CtrlReg&0x2002) { case 0x0002: buf[parp] = PAD1_poll(value); break; case 0x2002: buf[parp] = PAD2_poll(value); break; } } if (parp == bufcount) { padst = 0; return; } SIO_INT(); return; } switch (mcdst) { case 1: SIO_INT(); if (rdwr) { parp++; return; } parp = 1; switch (value) { case 0x52: rdwr = 1; break; case 0x57: rdwr = 2; break; default: mcdst = 0; } return; case 2: // address H SIO_INT(); adrH = value; *buf = 0; parp = 0; bufcount = 1; mcdst = 3; return; case 3: // address L SIO_INT(); adrL = value; *buf = adrH; parp = 0; bufcount = 1; mcdst = 4; return; case 4: SIO_INT(); parp = 0; switch (rdwr) { case 1: // read buf[0] = 0x5c; buf[1] = 0x5d; buf[2] = adrH; buf[3] = adrL; switch (CtrlReg&0x2002) { case 0x0002: memcpy(&buf[4], Mcd1Data + (adrL | (adrH << 8)) * 128, 128); break; case 0x2002: memcpy(&buf[4], Mcd2Data + (adrL | (adrH << 8)) * 128, 128); break; } { char xor = 0; int i; for (i=2;i<128+4;i++) xor^=buf[i]; buf[132] = xor; } buf[133] = 0x47; bufcount = 133; break; case 2: // write buf[0] = adrL; buf[1] = value; buf[129] = 0x5c; buf[130] = 0x5d; buf[131] = 0x47; bufcount = 131; break; } mcdst = 5; return; case 5: parp++; if (rdwr == 2) { if (parp < 128) buf[parp+1] = value; } SIO_INT(); return; } switch (value) { case 0x01: // start pad StatReg |= RX_RDY; // Transfer is Ready if (!Config.UseNet) { switch (CtrlReg&0x2002) { case 0x0002: buf[0] = PAD1_startPoll(1); break; case 0x2002: buf[0] = PAD2_startPoll(2); break; } } else { if ((CtrlReg & 0x2002) == 0x0002) { int i, j; PAD1_startPoll(1); buf[0] = 0; buf[1] = PAD1_poll(0x42); if (!(buf[1] & 0x0f)) { bufcount = 32; } else { bufcount = (buf[1] & 0x0f) * 2; } buf[2] = PAD1_poll(0); i = 3; j = bufcount; while (j--) { buf[i++] = PAD1_poll(0); } bufcount+= 3; if (NET_sendPadData(buf, bufcount) == -1) netError(); if (NET_recvPadData(buf, 1) == -1) netError(); if (NET_recvPadData(buf+128, 2) == -1) netError(); } else { memcpy(buf, buf+128, 32); } } bufcount = 2; parp = 0; padst = 1; SIO_INT(); return; case 0x81: // start memcard StatReg |= RX_RDY; memcpy(buf, cardh, 4); parp = 0; bufcount = 3; mcdst = 1; rdwr = 0; SIO_INT(); return; } }
u16 psxHwRead16(u32 add) { unsigned short hard; switch (add) { #ifdef PSXHW_LOG case 0x1f801070: PSXHW_LOG("IREG 16bit read %x\n", psxHu16(0x1070)); return psxHu16(0x1070); #endif #ifdef PSXHW_LOG case 0x1f801074: PSXHW_LOG("IMASK 16bit read %x\n", psxHu16(0x1074)); return psxHu16(0x1074); #endif case 0x1f801040: hard = sioRead8(); hard|= sioRead8() << 8; #ifdef PAD_LOG PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard); #endif return hard; case 0x1f801044: hard = sioReadStat16(); #ifdef PAD_LOG PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard); #endif return hard; case 0x1f801048: hard = sioReadMode16(); #ifdef PAD_LOG PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard); #endif return hard; case 0x1f80104a: hard = sioReadCtrl16(); #ifdef PAD_LOG PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard); #endif return hard; case 0x1f80104e: hard = sioReadBaud16(); #ifdef PAD_LOG PAD_LOG("sio read16 %x; ret = %x\n", add&0xf, hard); #endif return hard; #ifdef ENABLE_SIO1API case 0x1f801050: hard = SIO1_readData16(); return hard; case 0x1f801054: hard = SIO1_readStat16(); return hard; case 0x1f80105a: hard = SIO1_readCtrl16(); return hard; case 0x1f80105e: hard = SIO1_readBaud16(); return hard; #endif case 0x1f801100: hard = psxRcntRcount(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 count read16: %x\n", hard); #endif return hard; case 0x1f801104: hard = psxRcntRmode(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 mode read16: %x\n", hard); #endif return hard; case 0x1f801108: hard = psxRcntRtarget(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 target read16: %x\n", hard); #endif return hard; case 0x1f801110: hard = psxRcntRcount(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 count read16: %x\n", hard); #endif return hard; case 0x1f801114: hard = psxRcntRmode(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 mode read16: %x\n", hard); #endif return hard; case 0x1f801118: hard = psxRcntRtarget(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 target read16: %x\n", hard); #endif return hard; case 0x1f801120: hard = psxRcntRcount(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 count read16: %x\n", hard); #endif return hard; case 0x1f801124: hard = psxRcntRmode(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 mode read16: %x\n", hard); #endif return hard; case 0x1f801128: hard = psxRcntRtarget(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 target read16: %x\n", hard); #endif return hard; //case 0x1f802030: hard = //int_2000???? //case 0x1f802040: hard =//dip switches...?? default: if (add >= 0x1f801c00 && add < 0x1f801e00) { hard = SPU_readRegister(add); } else { hard = psxHu16(add); #ifdef PSXHW_LOG PSXHW_LOG("*Unkwnown 16bit read at address %x\n", add); #endif } return hard; } #ifdef PSXHW_LOG PSXHW_LOG("*Known 16bit read at address %x value %x\n", add, hard); #endif return hard; }
void psxHwWrite32(u32 add, u32 value) { switch (add) { case 0x1f801040: sioWrite8((unsigned char)value); sioWrite8((unsigned char)((value&0xff) >> 8)); sioWrite8((unsigned char)((value&0xff) >> 16)); sioWrite8((unsigned char)((value&0xff) >> 24)); #ifdef PAD_LOG PAD_LOG("sio write32 %x\n", value); #endif return; #ifdef ENABLE_SIO1API case 0x1f801050: SIO1_writeData32(value); return; #endif #ifdef PSXHW_LOG case 0x1f801060: PSXHW_LOG("RAM size write %x\n", value); psxHu32ref(add) = SWAPu32(value); return; // Ram size #endif case 0x1f801070: #ifdef PSXHW_LOG PSXHW_LOG("IREG 32bit write %x\n", value); #endif if (Config.Sio) psxHu32ref(0x1070) |= SWAPu32(0x80); if (Config.SpuIrq) psxHu32ref(0x1070) |= SWAPu32(0x200); psxHu32ref(0x1070) &= SWAPu32((psxHu32(0x1074) & value)); return; case 0x1f801074: #ifdef PSXHW_LOG PSXHW_LOG("IMASK 32bit write %x\n", value); #endif psxHu32ref(0x1074) = SWAPu32(value); if (psxHu32ref(0x1070) & value) new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1); return; #ifdef PSXHW_LOG case 0x1f801080: PSXHW_LOG("DMA0 MADR 32bit write %x\n", value); HW_DMA0_MADR = SWAPu32(value); return; // DMA0 madr case 0x1f801084: PSXHW_LOG("DMA0 BCR 32bit write %x\n", value); HW_DMA0_BCR = SWAPu32(value); return; // DMA0 bcr #endif case 0x1f801088: #ifdef PSXHW_LOG PSXHW_LOG("DMA0 CHCR 32bit write %x\n", value); #endif DmaExec(0); // DMA0 chcr (MDEC in DMA) return; #ifdef PSXHW_LOG case 0x1f801090: PSXHW_LOG("DMA1 MADR 32bit write %x\n", value); HW_DMA1_MADR = SWAPu32(value); return; // DMA1 madr case 0x1f801094: PSXHW_LOG("DMA1 BCR 32bit write %x\n", value); HW_DMA1_BCR = SWAPu32(value); return; // DMA1 bcr #endif case 0x1f801098: #ifdef PSXHW_LOG PSXHW_LOG("DMA1 CHCR 32bit write %x\n", value); #endif DmaExec(1); // DMA1 chcr (MDEC out DMA) return; #ifdef PSXHW_LOG case 0x1f8010a0: PSXHW_LOG("DMA2 MADR 32bit write %x\n", value); HW_DMA2_MADR = SWAPu32(value); return; // DMA2 madr case 0x1f8010a4: PSXHW_LOG("DMA2 BCR 32bit write %x\n", value); HW_DMA2_BCR = SWAPu32(value); return; // DMA2 bcr #endif case 0x1f8010a8: #ifdef PSXHW_LOG PSXHW_LOG("DMA2 CHCR 32bit write %x\n", value); #endif DmaExec(2); // DMA2 chcr (GPU DMA) return; #ifdef PSXHW_LOG case 0x1f8010b0: PSXHW_LOG("DMA3 MADR 32bit write %x\n", value); HW_DMA3_MADR = SWAPu32(value); return; // DMA3 madr case 0x1f8010b4: PSXHW_LOG("DMA3 BCR 32bit write %x\n", value); HW_DMA3_BCR = SWAPu32(value); return; // DMA3 bcr #endif case 0x1f8010b8: #ifdef PSXHW_LOG PSXHW_LOG("DMA3 CHCR 32bit write %x\n", value); #endif DmaExec(3); // DMA3 chcr (CDROM DMA) return; #ifdef PSXHW_LOG case 0x1f8010c0: PSXHW_LOG("DMA4 MADR 32bit write %x\n", value); HW_DMA4_MADR = SWAPu32(value); return; // DMA4 madr case 0x1f8010c4: PSXHW_LOG("DMA4 BCR 32bit write %x\n", value); HW_DMA4_BCR = SWAPu32(value); return; // DMA4 bcr #endif case 0x1f8010c8: #ifdef PSXHW_LOG PSXHW_LOG("DMA4 CHCR 32bit write %x\n", value); #endif DmaExec(4); // DMA4 chcr (SPU DMA) return; #if 0 case 0x1f8010d0: break; //DMA5write_madr(); case 0x1f8010d4: break; //DMA5write_bcr(); case 0x1f8010d8: break; //DMA5write_chcr(); // Not needed #endif #ifdef PSXHW_LOG case 0x1f8010e0: PSXHW_LOG("DMA6 MADR 32bit write %x\n", value); HW_DMA6_MADR = SWAPu32(value); return; // DMA6 bcr case 0x1f8010e4: PSXHW_LOG("DMA6 BCR 32bit write %x\n", value); HW_DMA6_BCR = SWAPu32(value); return; // DMA6 bcr #endif case 0x1f8010e8: #ifdef PSXHW_LOG PSXHW_LOG("DMA6 CHCR 32bit write %x\n", value); #endif DmaExec(6); // DMA6 chcr (OT clear) return; #ifdef PSXHW_LOG case 0x1f8010f0: PSXHW_LOG("DMA PCR 32bit write %x\n", value); HW_DMA_PCR = SWAPu32(value); return; #endif case 0x1f8010f4: #ifdef PSXHW_LOG PSXHW_LOG("DMA ICR 32bit write %x\n", value); #endif { u32 tmp = value & 0x00ff803f; tmp |= (SWAPu32(HW_DMA_ICR) & ~value) & 0x7f000000; if ((tmp & HW_DMA_ICR_GLOBAL_ENABLE && tmp & 0x7f000000) || tmp & HW_DMA_ICR_BUS_ERROR) { if (!(SWAPu32(HW_DMA_ICR) & HW_DMA_ICR_IRQ_SENT)) psxHu32ref(0x1070) |= SWAP32(8); tmp |= HW_DMA_ICR_IRQ_SENT; } HW_DMA_ICR = SWAPu32(tmp); return; } case 0x1f801810: #ifdef PSXHW_LOG PSXHW_LOG("GPU DATA 32bit write %x\n", value); #endif GPU_writeData(value); return; case 0x1f801814: #ifdef PSXHW_LOG PSXHW_LOG("GPU STATUS 32bit write %x\n", value); #endif GPU_writeStatus(value); gpuSyncPluginSR(); return; case 0x1f801820: mdecWrite0(value); break; case 0x1f801824: mdecWrite1(value); break; case 0x1f801100: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 COUNT 32bit write %x\n", value); #endif psxRcntWcount(0, value & 0xffff); return; case 0x1f801104: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 MODE 32bit write %x\n", value); #endif psxRcntWmode(0, value); return; case 0x1f801108: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 TARGET 32bit write %x\n", value); #endif psxRcntWtarget(0, value & 0xffff); return; // HW_DMA_ICR&= SWAP32((~value)&0xff000000); case 0x1f801110: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 COUNT 32bit write %x\n", value); #endif psxRcntWcount(1, value & 0xffff); return; case 0x1f801114: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 MODE 32bit write %x\n", value); #endif psxRcntWmode(1, value); return; case 0x1f801118: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 TARGET 32bit write %x\n", value); #endif psxRcntWtarget(1, value & 0xffff); return; case 0x1f801120: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 COUNT 32bit write %x\n", value); #endif psxRcntWcount(2, value & 0xffff); return; case 0x1f801124: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 MODE 32bit write %x\n", value); #endif psxRcntWmode(2, value); return; case 0x1f801128: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 TARGET 32bit write %x\n", value); #endif psxRcntWtarget(2, value & 0xffff); return; default: // Dukes of Hazard 2 - car engine noise if (add>=0x1f801c00 && add<0x1f801e00) { SPU_writeRegister(add, value&0xffff); SPU_writeRegister(add + 2, value>>16); return; } psxHu32ref(add) = SWAPu32(value); #ifdef PSXHW_LOG PSXHW_LOG("*Unknown 32bit write at address %x value %x\n", add, value); #endif return; }
u32 sio2_getRecv1() { PAD_LOG("Reading Recv1 = %x",sio2.packet.recvVal1); return sio2.packet.recvVal1; }
u32 psxHwRead32(u32 add) { u32 hard; switch (add) { case 0x1f801040: hard = sioRead8(); hard |= sioRead8() << 8; hard |= sioRead8() << 16; hard |= sioRead8() << 24; #ifdef PAD_LOG PAD_LOG("sio read32 ;ret = %x\n", hard); #endif return hard; #ifdef ENABLE_SIO1API case 0x1f801050: hard = SIO1_readData32(); return hard; #endif #ifdef PSXHW_LOG case 0x1f801060: PSXHW_LOG("RAM size read %x\n", psxHu32(0x1060)); return psxHu32(0x1060); #endif #ifdef PSXHW_LOG case 0x1f801070: PSXHW_LOG("IREG 32bit read %x\n", psxHu32(0x1070)); return psxHu32(0x1070); #endif #ifdef PSXHW_LOG case 0x1f801074: PSXHW_LOG("IMASK 32bit read %x\n", psxHu32(0x1074)); return psxHu32(0x1074); #endif case 0x1f801810: hard = GPU_readData(); #ifdef PSXHW_LOG PSXHW_LOG("GPU DATA 32bit read %x\n", hard); #endif return hard; case 0x1f801814: gpuSyncPluginSR(); hard = HW_GPU_STATUS; if (hSyncCount < 240 && (HW_GPU_STATUS & PSXGPU_ILACE_BITS) != PSXGPU_ILACE_BITS) hard |= PSXGPU_LCF & (psxRegs.cycle << 20); #ifdef PSXHW_LOG PSXHW_LOG("GPU STATUS 32bit read %x\n", hard); #endif return hard; case 0x1f801820: hard = mdecRead0(); break; case 0x1f801824: hard = mdecRead1(); break; #ifdef PSXHW_LOG case 0x1f8010a0: PSXHW_LOG("DMA2 MADR 32bit read %x\n", psxHu32(0x10a0)); return SWAPu32(HW_DMA2_MADR); case 0x1f8010a4: PSXHW_LOG("DMA2 BCR 32bit read %x\n", psxHu32(0x10a4)); return SWAPu32(HW_DMA2_BCR); case 0x1f8010a8: PSXHW_LOG("DMA2 CHCR 32bit read %x\n", psxHu32(0x10a8)); return SWAPu32(HW_DMA2_CHCR); #endif #ifdef PSXHW_LOG case 0x1f8010b0: PSXHW_LOG("DMA3 MADR 32bit read %x\n", psxHu32(0x10b0)); return SWAPu32(HW_DMA3_MADR); case 0x1f8010b4: PSXHW_LOG("DMA3 BCR 32bit read %x\n", psxHu32(0x10b4)); return SWAPu32(HW_DMA3_BCR); case 0x1f8010b8: PSXHW_LOG("DMA3 CHCR 32bit read %x\n", psxHu32(0x10b8)); return SWAPu32(HW_DMA3_CHCR); #endif #ifdef PSXHW_LOG /* case 0x1f8010f0: PSXHW_LOG("DMA PCR 32bit read %x\n", psxHu32(0x10f0)); return SWAPu32(HW_DMA_PCR); // dma rest channel case 0x1f8010f4: PSXHW_LOG("DMA ICR 32bit read %x\n", psxHu32(0x10f4)); return SWAPu32(HW_DMA_ICR); // interrupt enabler?*/ #endif // time for rootcounters :) case 0x1f801100: hard = psxRcntRcount(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 count read32: %x\n", hard); #endif return hard; case 0x1f801104: hard = psxRcntRmode(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 mode read32: %x\n", hard); #endif return hard; case 0x1f801108: hard = psxRcntRtarget(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 target read32: %x\n", hard); #endif return hard; case 0x1f801110: hard = psxRcntRcount(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 count read32: %x\n", hard); #endif return hard; case 0x1f801114: hard = psxRcntRmode(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 mode read32: %x\n", hard); #endif return hard; case 0x1f801118: hard = psxRcntRtarget(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 target read32: %x\n", hard); #endif return hard; case 0x1f801120: hard = psxRcntRcount(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 count read32: %x\n", hard); #endif return hard; case 0x1f801124: hard = psxRcntRmode(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 mode read32: %x\n", hard); #endif return hard; case 0x1f801128: hard = psxRcntRtarget(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 target read32: %x\n", hard); #endif return hard; default: hard = psxHu32(add); #ifdef PSXHW_LOG PSXHW_LOG("*Unkwnown 32bit read at address %x\n", add); #endif return hard; } #ifdef PSXHW_LOG PSXHW_LOG("*Known 32bit read at address %x\n", add); #endif return hard; }
u8 _PADpoll(u8 value) { u8 button_check = 0, button_check2 = 0; if (curByte == 0) { curByte++; #ifdef PAD_LOG PAD_LOG("PADpoll: cmd: %x\n", value); #endif curCmd = value; switch (value) { case 0x40: // DUALSHOCK2 ENABLER cmdLen = 8; buf = cmd40[curPad]; return 0xf3; case 0x41: // QUERY_DS2_ANALOG_MODE cmdLen = 8; buf = cmd41[curPad]; return 0xf3; case 0x42: // READ_DATA _PADupdate(curPad); stdpar[curPad][2] = status[curPad] >> 8; stdpar[curPad][3] = status[curPad] & 0xff; stdpar[curPad][4] = g_ranalog[curPad].x; stdpar[curPad][5] = g_ranalog[curPad].y; stdpar[curPad][6] = g_lanalog[curPad].x; stdpar[curPad][7] = g_lanalog[curPad].y; if (padMode[curPad] == 1) cmdLen = 20; else cmdLen = 4; button_check2 = stdpar[curPad][2] >> 4; switch(stdpar[curPad][3]) { case 0xBF: // X stdpar[curPad][14] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][16])); break; case 0xDF: // Circle stdpar[curPad][13] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][17])); break; case 0xEF: // Triangle stdpar[curPad][12] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][19])); break; case 0x7F: // Square stdpar[curPad][15] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][18])); break; case 0xFB: // L1 stdpar[curPad][16] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][26])); break; case 0xF7: // R1 stdpar[curPad][17] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][28])); break; case 0xFE: // L2 stdpar[curPad][18] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][27])); break; case 0xFD: // R2 stdpar[curPad][19] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][29])); break; default: stdpar[curPad][14] = 0x00; // Not pressed stdpar[curPad][13] = 0x00; // Not pressed stdpar[curPad][12] = 0x00; // Not pressed stdpar[curPad][15] = 0x00; // Not pressed stdpar[curPad][16] = 0x00; // Not pressed stdpar[curPad][17] = 0x00; // Not pressed stdpar[curPad][18] = 0x00; // Not pressed stdpar[curPad][19] = 0x00; // Not pressed break; } switch(button_check2) { case 0xE: // UP stdpar[curPad][10] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][21])); break; case 0xB: // DOWN stdpar[curPad][11] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][22])); break; case 0x7: // LEFT stdpar[curPad][9] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][23])); break; case 0xD: // RIGHT stdpar[curPad][8] = (pressure*255)/100; //0xff/(100/(100-conf.keys[curPad][24])); break; default: stdpar[curPad][8] = 0x00; // Not pressed stdpar[curPad][9] = 0x00; // Not pressed stdpar[curPad][10] = 0x00; // Not pressed stdpar[curPad][11] = 0x00; // Not pressed break; } buf = stdpar[curPad]; return padID[curPad]; case 0x43: // CONFIG_MODE cmdLen = 8; buf = stdcfg[curPad]; if (stdcfg[curPad][3] == 0xff) return 0xf3; else return padID[curPad]; case 0x44: // SET_MODE_AND_LOCK cmdLen = 8; buf = stdmode[curPad]; return 0xf3; case 0x45: // QUERY_MODEL_AND_MODE cmdLen = 8; buf = stdmodel[curPad]; buf[4] = padMode[curPad]; return 0xf3; case 0x46: // ?? cmdLen = 8; buf = unk46[curPad]; return 0xf3; case 0x47: // ?? cmdLen = 8; buf = unk47[curPad]; return 0xf3; case 0x4c: // QUERY_MODE ?? cmdLen = 8; buf = unk4c[curPad]; return 0xf3; case 0x4d: cmdLen = 8; buf = unk4d[curPad]; return 0xf3; case 0x4f: // SET_DS2_NATIVE_MODE cmdLen = 8; padID[curPad] = 0x79; // setting ds2 mode ds2mode = 1; // Set DS2 Mode buf = cmd4f[curPad]; return 0xf3; default: #ifdef PAD_LOG PAD_LOG("*PADpoll*: unknown cmd %x\n", value); #endif break; } }
void SIO_CommandWrite(u8 value,int way) { PAD_LOG("sio write8 %x", value); // PAD COMMANDS switch (sio.padst) { case 1: SIO_INT(); if ((value&0x40) == 0x40) { sio.padst = 2; sio.parp = 1; switch (sio.CtrlReg&0x2002) { case 0x0002: sio.packetsize ++; // Total packet size sent sio.buf[sio.parp] = PADpoll(value); break; case 0x2002: sio.packetsize ++; // Total packet size sent sio.buf[sio.parp] = PADpoll(value); break; } if (!(sio.buf[sio.parp] & 0x0f)) { sio.bufcount = 2 + 32; } else { sio.bufcount = 2 + (sio.buf[sio.parp] & 0x0f) * 2; } } else sio.padst = 0; return; case 2: sio.parp++; switch (sio.CtrlReg&0x2002) { case 0x0002: sio.packetsize ++; sio.buf[sio.parp] = PADpoll(value); break; case 0x2002: sio.packetsize ++; sio.buf[sio.parp] = PADpoll(value); break; } if (sio.parp == sio.bufcount) { sio.padst = 0; return; } SIO_INT(); return; case 3: // No pad connected. sio.parp++; if (sio.parp == sio.bufcount) { sio.padst = 0; return; } SIO_INT(); return; } // MEMORY CARD COMMANDS switch (sio.mcdst) { case 1: { sio.packetsize++; SIO_INT(); if (sio.rdwr) { sio.parp++; return; } sio.parp = 1; const char* log_cmdname = ""; switch (value) { case 0x11: // RESET log_cmdname = "Reset1"; sio.bufcount = 8; memset8<0xff>(sio.buf); sio.buf[3] = sio.terminator; sio.buf[2] = '+'; sio.mcdst = 99; sio2.packet.recvVal3 = 0x8c; break; // FIXME : Why are there two identical cases for resetting the // memorycard(s)? there doesn't appear to be anything dealing with // card slots here. --air case 0x12: // RESET log_cmdname = "Reset2"; sio.bufcount = 8; memset8<0xff>(sio.buf); sio.buf[3] = sio.terminator; sio.buf[2] = '+'; sio.mcdst = 99; sio2.packet.recvVal3 = 0x8c; break; case 0x81: // COMMIT log_cmdname = "Commit"; sio.bufcount = 8; memset8<0xff>(sio.buf); sio.mcdst = 99; sio.buf[3] = sio.terminator; sio.buf[2] = '+'; sio2.packet.recvVal3 = 0x8c; if(value == 0x81) { if(sio.mc_command==0x42) sio2.packet.recvVal1 = 0x1600; // Writing else if(sio.mc_command==0x43) sio2.packet.recvVal1 = 0x1700; // Reading } break; case 0x21: case 0x22: case 0x23: // SECTOR SET log_cmdname = "SetSector"; sio.bufcount = 8; sio.mcdst = 99; sio.sector=0; sio.k=0; memset8<0xff>(sio.buf); sio2.packet.recvVal3 = 0x8c; sio.buf[8]=sio.terminator; sio.buf[7]='+'; break; case 0x24: break; case 0x25: break; case 0x26: { log_cmdname = "GetInfo"; const uint port = sio.GetMemcardIndex(); const uint slot = sio.activeMemcardSlot[port]; mc_command_0x26_tag cmd = mc_sizeinfo_8mb; PS2E_McdSizeInfo info; info.SectorSize = cmd.sectorSize; info.EraseBlockSizeInSectors = cmd.eraseBlocks; info.McdSizeInSectors = cmd.mcdSizeInSectors; SysPlugins.McdGetSizeInfo( port, slot, info ); pxAssumeDev( cmd.mcdSizeInSectors >= mc_sizeinfo_8mb.mcdSizeInSectors, "Mcd plugin returned an invalid memorycard size: Cards smaller than 8MB are not supported." ); cmd.sectorSize = info.SectorSize; cmd.eraseBlocks = info.EraseBlockSizeInSectors; cmd.mcdSizeInSectors = info.McdSizeInSectors; // Recalculate the xor summation // This uses a trick of removing the known xor values for a default 8mb memorycard (for which the XOR // was calculated), and replacing it with our new values. apply_xor( cmd.mc_xor, mc_sizeinfo_8mb.sectorSize ); apply_xor( cmd.mc_xor, mc_sizeinfo_8mb.eraseBlocks ); apply_xor( cmd.mc_xor, mc_sizeinfo_8mb.mcdSizeInSectors ); apply_xor( cmd.mc_xor, cmd.sectorSize ); apply_xor( cmd.mc_xor, cmd.eraseBlocks ); apply_xor( cmd.mc_xor, cmd.mcdSizeInSectors ); sio.bufcount = 12; sio.mcdst = 99; sio2.packet.recvVal3 = 0x83; memset8<0xff>(sio.buf); memcpy_fast(&sio.buf[2], &cmd, sizeof(cmd)); sio.buf[12]=sio.terminator; } break; case 0x27: case 0x28: case 0xBF: log_cmdname = "NotSure"; // FIXME !! sio.bufcount = 4; sio.mcdst = 99; sio2.packet.recvVal3 = 0x8b; memset8<0xff>(sio.buf); sio.buf[4]=sio.terminator; sio.buf[3]='+'; break; // FIXME ? // sio.lastsector and sio.mode are unused. case 0x42: // WRITE log_cmdname = "Write"; //sio.mode = 0; goto __doReadWrite; case 0x43: // READ log_cmdname = "Read"; //sio.lastsector = sio.sector; // Reading goto __doReadWrite; case 0x82: log_cmdname = "Read(?)"; // FIXME !! //if(sio.lastsector==sio.sector) sio.mode = 2; __doReadWrite: sio.bufcount =133; sio.mcdst = 99; memset8<0xff>(sio.buf); sio.buf[133]=sio.terminator; sio.buf[132]='+'; break; case 0xf0: case 0xf1: case 0xf2: log_cmdname = "NoClue"; // FIXME !! sio.mcdst = 99; break; case 0xf3: case 0xf7: log_cmdname = "NoClueHereEither"; // FIXME !! sio.bufcount = 4; sio.mcdst = 99; memset8<0xff>(sio.buf); sio.buf[4]=sio.terminator; sio.buf[3]='+'; break; case 0x52: log_cmdname = "FixMe"; // FIXME !! sio.rdwr = 1; memset8<0xff>(sio.buf); sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+'; break; case 0x57: log_cmdname = "FixMe"; // FIXME !! sio.rdwr = 2; memset8<0xff>(sio.buf); sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+'; break; default: log_cmdname = "Unknown"; sio.mcdst = 0; memset8<0xff>(sio.buf); sio.buf[sio.bufcount]=sio.terminator; sio.buf[sio.bufcount-1]='+'; } MEMCARDS_LOG("MC(%d) command 0x%02X [%s]", sio.GetMemcardIndex()+1, value, log_cmdname); sio.mc_command = value; } return; // END CASE 1. // FURTHER PROCESSING OF THE MEMORY CARD COMMANDS case 99: { sio.packetsize++; sio.parp++; switch(sio.mc_command) { // SET_ERASE_PAGE; the next erase commands will *clear* data starting with the page set here case 0x21: // SET_WRITE_PAGE; the next write commands will commit data starting with the page set here case 0x22: // SET_READ_PAGE; the next read commands will return data starting with the page set here case 0x23: if (sio.parp==2)sio.sector|=(value & 0xFF)<< 0; if (sio.parp==3)sio.sector|=(value & 0xFF)<< 8; if (sio.parp==4)sio.sector|=(value & 0xFF)<<16; if (sio.parp==5)sio.sector|=(value & 0xFF)<<24; if (sio.parp==6) { if (sio_xor((u8 *)&sio.sector, 4) == value) MEMCARDS_LOG("MC(%d) SET PAGE sio.sector, sector=0x%04X", sio.GetMemcardIndex()+1, sio.sector); else MEMCARDS_LOG("MC(%d) SET PAGE XOR value ERROR 0x%02X != ^0x%02X", sio.GetMemcardIndex()+1, value, sio_xor((u8 *)&sio.sector, 4)); } break; // SET_TERMINATOR; reads the new terminator code case 0x27: if(sio.parp==2) { sio.terminator = value; sio.buf[4] = value; MEMCARDS_LOG("MC(%d) SET TERMINATOR command, value=0x%02X", sio.GetMemcardIndex()+1, value); } break; // GET_TERMINATOR; puts in position 3 the current terminator code and in 4 the default one // depending on the param case 0x28: if(sio.parp == 2) { sio.buf[2] = '+'; sio.buf[3] = sio.terminator; //if(value == 0) sio.buf[4] = 0xFF; sio.buf[4] = 0x55; MEMCARDS_LOG("MC(%d) GET TERMINATOR command, value=0x%02X", sio.GetMemcardIndex()+1, value); } break; // WRITE DATA case 0x42: if (sio.parp==2) { sio.bufcount=5+value; memset8<0xff>(sio.buf); sio.buf[sio.bufcount-1]='+'; sio.buf[sio.bufcount]=sio.terminator; MEMCARDS_LOG("MC(%d) WRITE command, size=0x%02X", sio.GetMemcardIndex()+1, value); } else if ((sio.parp>2) && (sio.parp<sio.bufcount-2)) { sio.buf[sio.parp]=value; //MEMCARDS_LOG("MC(%d) WRITING 0x%02X", sio.GetMemcardIndex()+1, value); } else if (sio.parp==sio.bufcount-2) { if (sio_xor(&sio.buf[3], sio.bufcount-5)==value) { _SaveMcd(&sio.buf[3], (512+16)*sio.sector+sio.k, sio.bufcount-5); sio.buf[sio.bufcount-1]=value; sio.k+=sio.bufcount-5; } else { MEMCARDS_LOG("MC(%d) write XOR value error 0x%02X != ^0x%02X", sio.GetMemcardIndex()+1, value, sio_xor(&sio.buf[3], sio.bufcount-5)); } } break; // READ DATA case 0x43: if (sio.parp==2) { //int i; sio.bufcount=value+5; sio.buf[3]='+'; MEMCARDS_LOG("MC(%d) READ command, size=0x%02X", sio.GetMemcardIndex()+1, value); _ReadMcd(&sio.buf[4], (512+16)*sio.sector+sio.k, value); /*if(sio.mode==2) { int j; for(j=0; j < value; j++) sio.buf[4+j] = ~sio.buf[4+j]; }*/ sio.k+=value; sio.buf[sio.bufcount-1]=sio_xor(&sio.buf[4], value); sio.buf[sio.bufcount]=sio.terminator; } break; // INTERNAL ERASE case 0x82: if(sio.parp==2) { sio.buf[2]='+'; sio.buf[3]=sio.terminator; //if (sio.k != 0 || (sio.sector & 0xf) != 0) // Console.Warning("saving : odd position for erase."); _EraseMCDBlock((512+16)*(sio.sector&~0xf)); /* memset(sio.buf, -1, 256); _SaveMcd(sio.buf, (512+16)*sio.sector, 256); _SaveMcd(sio.buf, (512+16)*sio.sector+256, 256); _SaveMcd(sio.buf, (512+16)*sio.sector+512, 16); sio.buf[2]='+'; sio.buf[3]=sio.terminator;*/ //sio.buf[sio.bufcount] = sio.terminator; MEMCARDS_LOG("MC(%d) INTERNAL ERASE command 0x%02X", sio.GetMemcardIndex()+1, value); } break; // CARD AUTHENTICATION CHECKS case 0xF0: if (sio.parp==2) { MEMCARDS_LOG("MC(%d) CARD AUTH :0x%02X", sio.GetMemcardIndex()+1, value); switch(value){ case 1: case 2: case 4: case 15: case 17: case 19: sio.bufcount=13; memset8<0xff>(sio.buf); sio.buf[12] = 0; // Xor value of data from index 4 to 11 sio.buf[3]='+'; sio.buf[13] = sio.terminator; break; case 6: case 7: case 11: sio.bufcount=13; memset8<0xff>(sio.buf); sio.buf[12]='+'; sio.buf[13] = sio.terminator; break; default: sio.bufcount=4; memset8<0xff>(sio.buf); sio.buf[3]='+'; sio.buf[4] = sio.terminator; } } break; } if (sio.bufcount<=sio.parp) sio.mcdst = 0; } return; // END CASE 99. } switch (sio.mtapst) { case 0x1: sio.packetsize++; sio.parp = 1; SIO_INT(); switch(value) { case 0x12: // Query number of pads supported. sio.buf[3] = 4; sio.mtapst = 2; sio.bufcount = 5; break; case 0x13: // Query number of memcards supported. sio.buf[3] = 4; sio.mtapst = 2; sio.bufcount = 5; break; case 0x21: // Set pad slot. sio.mtapst = value; sio.bufcount = 6; // No idea why this is 6, saved from old code. break; case 0x22: // Set memcard slot. sio.mtapst = value; sio.bufcount = 6; // No idea why this is 6, saved from old code. break; } // Commented out values are from original code. They break multitap in bios. sio.buf[sio.bufcount-1]=0;//'+'; sio.buf[sio.bufcount]=0;//'Z'; return; case 0x2: sio.packetsize++; sio.parp++; if (sio.bufcount<=sio.parp) sio.mcdst = 0; SIO_INT(); return; case 0x21: // Set pad slot. sio.packetsize++; sio.parp++; sio.mtapst = 2; if (sio.CtrlReg & 2) { int port = sio.GetMultitapPort(); if (IsMtapPresent(port)) sio.activePadSlot[port] = value; } SIO_INT(); return; case 0x22: // Set memcard slot. sio.packetsize++; sio.parp++; sio.mtapst = 2; if (sio.CtrlReg & 2) { int port = sio.GetMultitapPort(); if (IsMtapPresent(port)) sio.activeMemcardSlot[port] = value; } SIO_INT(); return; } if(sio.count == 1 || way == 0) InitializeSIO(value); }
EXPORT_C_(void) PADupdate(int pad) { // Poll keyboard. PollForKeyboardInput(pad); // joystick info SDL_JoystickUpdate(); for (int i = 0; i < MAX_KEYS; i++) { int cpad = PadEnum[pad][0]; if (JoystickIdWithinBounds(key_to_joystick_id(cpad, i))) { JoystickInfo* pjoy = s_vjoysticks[key_to_joystick_id(cpad, i)]; int pad = (pjoy)->GetPAD(); switch (type_of_key(cpad, i)) { case PAD_JOYBUTTONS: { int value = SDL_JoystickGetButton((pjoy)->GetJoy(), key_to_button(cpad, i)); if (value) clear_bit(status[pad], i); // released else set_bit(status[pad], i); // pressed break; } case PAD_HAT: { int value = SDL_JoystickGetHat((pjoy)->GetJoy(), key_to_axis(cpad, i)); if (key_to_hat_dir(cpad, i) == value) { clear_bit(status[pad], i); //PAD_LOG("Registered %s\n", HatName(value), i); //PAD_LOG("%s\n", KeyName(cpad, i).c_str()); } else { set_bit(status[pad], i); } break; } case PAD_POV: { int value = pjoy->GetAxisFromKey(cpad, i); PAD_LOG("%s: %d (%d)\n", KeyName(cpad, i).c_str(), value, key_to_pov_sign(cpad, i)); if (key_to_pov_sign(cpad, i) && (value < -2048)) { //PAD_LOG("%s Released+.\n", KeyName(cpad, i).c_str()); clear_bit(status[pad], i); } else if (!key_to_pov_sign(cpad, i) && (value > 2048)) { //PAD_LOG("%s Released-\n", KeyName(cpad, i).c_str()); clear_bit(status[pad], i); } else { //PAD_LOG("%s Pressed.\n", KeyName(cpad, i).c_str()); set_bit(status[pad], i); } break; } case PAD_JOYSTICK: { int value = pjoy->GetAxisFromKey(cpad, i); switch (i) { case PAD_LX: case PAD_LY: case PAD_RX: case PAD_RY: if (abs(value) > (pjoy)->GetDeadzone(value)) Analog::ConfigurePad(pad, i, value); else Analog::ResetPad(pad, i); break; } break; } default: break; } } } }
u32 psxHwRead32(u32 add) { u32 hard; switch (add) { case 0x1f801040: hard = sioRead8(); hard |= sioRead8() << 8; hard |= sioRead8() << 16; hard |= sioRead8() << 24; #ifdef PAD_LOG PAD_LOG("sio read32 ;ret = %x\n", hard); #endif return hard; #ifdef ENABLE_SIO1API case 0x1f801050: hard = SIO1_readData32(); #ifdef SIO1_LOG SIO1_LOG("sio1 read32 ;ret = %x\n", hard); #endif return hard; #endif #ifdef PSXHW_LOG case 0x1f801060: PSXHW_LOG("RAM size read %x\n", psxHu32(0x1060)); return psxHu32(0x1060); #endif #ifdef PSXHW_LOG case 0x1f801070: PSXHW_LOG("IREG 32bit read %x\n", psxHu32(0x1070)); return psxHu32(0x1070); #endif #ifdef PSXHW_LOG case 0x1f801074: PSXHW_LOG("IMASK 32bit read %x\n", psxHu32(0x1074)); return psxHu32(0x1074); #endif case 0x1f801810: hard = GPU_readData(); #ifdef PSXHW_LOG PSXHW_LOG("GPU DATA 32bit read %x\n", hard); #endif return hard; case 0x1f801814: hard = gpuReadStatus(); #ifdef PSXHW_LOG PSXHW_LOG("GPU STATUS 32bit read %x\n", hard); #endif return hard; case 0x1f801820: hard = mdecRead0(); break; case 0x1f801824: hard = mdecRead1(); break; #ifdef PSXHW_LOG case 0x1f8010a0: PSXHW_LOG("DMA2 MADR 32bit read %x\n", psxHu32(0x10a0)); return SWAPu32(HW_DMA2_MADR); case 0x1f8010a4: PSXHW_LOG("DMA2 BCR 32bit read %x\n", psxHu32(0x10a4)); return SWAPu32(HW_DMA2_BCR); case 0x1f8010a8: PSXHW_LOG("DMA2 CHCR 32bit read %x\n", psxHu32(0x10a8)); return SWAPu32(HW_DMA2_CHCR); #endif #ifdef PSXHW_LOG case 0x1f8010b0: PSXHW_LOG("DMA3 MADR 32bit read %x\n", psxHu32(0x10b0)); return SWAPu32(HW_DMA3_MADR); case 0x1f8010b4: PSXHW_LOG("DMA3 BCR 32bit read %x\n", psxHu32(0x10b4)); return SWAPu32(HW_DMA3_BCR); case 0x1f8010b8: PSXHW_LOG("DMA3 CHCR 32bit read %x\n", psxHu32(0x10b8)); return SWAPu32(HW_DMA3_CHCR); #endif #ifdef PSXHW_LOG case 0x1f8010f0: PSXHW_LOG("DMA PCR 32bit read %x\n", HW_DMA_PCR); return SWAPu32(HW_DMA_PCR); // DMA control register case 0x1f8010f4: PSXHW_LOG("DMA ICR 32bit read %x\n", HW_DMA_ICR); return SWAPu32(HW_DMA_ICR); // DMA interrupt register (enable/ack) #endif // time for rootcounters :) case 0x1f801100: hard = psxRcntRcount(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 count read32: %x\n", hard); #endif return hard; case 0x1f801104: hard = psxRcntRmode(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 mode read32: %x\n", hard); #endif return hard; case 0x1f801108: hard = psxRcntRtarget(0); #ifdef PSXHW_LOG PSXHW_LOG("T0 target read32: %x\n", hard); #endif return hard; case 0x1f801110: hard = psxRcntRcount(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 count read32: %x\n", hard); #endif return hard; case 0x1f801114: hard = psxRcntRmode(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 mode read32: %x\n", hard); #endif return hard; case 0x1f801118: hard = psxRcntRtarget(1); #ifdef PSXHW_LOG PSXHW_LOG("T1 target read32: %x\n", hard); #endif return hard; case 0x1f801120: hard = psxRcntRcount(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 count read32: %x\n", hard); #endif return hard; case 0x1f801124: hard = psxRcntRmode(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 mode read32: %x\n", hard); #endif return hard; case 0x1f801128: hard = psxRcntRtarget(2); #ifdef PSXHW_LOG PSXHW_LOG("T2 target read32: %x\n", hard); #endif return hard; case 0x1f801014: hard = psxHu32(add); #ifdef PSXHW_LOG PSXHW_LOG("SPU delay [0x1014] read32: %8.8lx\n", hard); #endif return hard; default: hard = psxHu32(add); #ifdef PSXHW_LOG PSXHW_LOG("*Unknown 32bit read at address %x (0x%8.8lx)\n", add, hard); #endif return hard; } #ifdef PSXHW_LOG PSXHW_LOG("*Known 32bit read at address %x\n", add); #endif return hard; }
u32 sio2_getRecv2() { PAD_LOG("Reading Recv2 = %x",0xF); return 0xf; }//0, 0x10, 0x20, 0x10 | 0x20; bits 4 & 5
void psxHwWrite16(u32 add, u16 value) { switch (add) { case 0x1f801040: sioWrite8((unsigned char)value); sioWrite8((unsigned char)(value>>8)); #ifdef PAD_LOG PAD_LOG ("sio write16 %x, %x\n", add&0xf, value); #endif return; case 0x1f801044: sioWriteStat16(value); #ifdef PAD_LOG PAD_LOG ("sio write16 %x, %x\n", add&0xf, value); #endif return; case 0x1f801048: sioWriteMode16(value); #ifdef PAD_LOG PAD_LOG ("sio write16 %x, %x\n", add&0xf, value); #endif return; case 0x1f80104a: // control register sioWriteCtrl16(value); #ifdef PAD_LOG PAD_LOG ("sio write16 %x, %x\n", add&0xf, value); #endif return; case 0x1f80104e: // baudrate register sioWriteBaud16(value); #ifdef PAD_LOG PAD_LOG ("sio write16 %x, %x\n", add&0xf, value); #endif return; #ifdef ENABLE_SIO1API case 0x1f801050: SIO1_writeData16(value); return; case 0x1f801054: SIO1_writeStat16(value); return; case 0x1f80105a: SIO1_writeCtrl16(value); return; case 0x1f80105e: SIO1_writeBaud16(value); return; #endif case 0x1f801070: #ifdef PSXHW_LOG PSXHW_LOG("IREG 16bit write %x\n", value); #endif if (Config.Sio) psxHu16ref(0x1070) |= SWAPu16(0x80); if (Config.SpuIrq) psxHu16ref(0x1070) |= SWAPu16(0x200); psxHu16ref(0x1070) &= SWAPu16((psxHu16(0x1074) & value)); return; case 0x1f801074: #ifdef PSXHW_LOG PSXHW_LOG("IMASK 16bit write %x\n", value); #endif psxHu16ref(0x1074) = SWAPu16(value); if (psxHu16ref(0x1070) & value) new_dyna_set_event(PSXINT_NEWDRC_CHECK, 1); return; case 0x1f801100: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 COUNT 16bit write %x\n", value); #endif psxRcntWcount(0, value); return; case 0x1f801104: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 MODE 16bit write %x\n", value); #endif psxRcntWmode(0, value); return; case 0x1f801108: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 TARGET 16bit write %x\n", value); #endif psxRcntWtarget(0, value); return; case 0x1f801110: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 COUNT 16bit write %x\n", value); #endif psxRcntWcount(1, value); return; case 0x1f801114: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 MODE 16bit write %x\n", value); #endif psxRcntWmode(1, value); return; case 0x1f801118: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 TARGET 16bit write %x\n", value); #endif psxRcntWtarget(1, value); return; case 0x1f801120: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 COUNT 16bit write %x\n", value); #endif psxRcntWcount(2, value); return; case 0x1f801124: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 MODE 16bit write %x\n", value); #endif psxRcntWmode(2, value); return; case 0x1f801128: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 TARGET 16bit write %x\n", value); #endif psxRcntWtarget(2, value); return; default: if (add>=0x1f801c00 && add<0x1f801e00) { SPU_writeRegister(add, value); return; } psxHu16ref(add) = SWAPu16(value); #ifdef PSXHW_LOG PSXHW_LOG("*Unknown 16bit write at address %x value %x\n", add, value); #endif return; } psxHu16ref(add) = SWAPu16(value); #ifdef PSXHW_LOG PSXHW_LOG("*Known 16bit write at address %x value %x\n", add, value); #endif }
void psxHwWrite32(u32 add, u32 value) { switch (add) { case 0x1f801040: sioWrite8((unsigned char)value); sioWrite8((unsigned char)((value&0xff) >> 8)); sioWrite8((unsigned char)((value&0xff) >> 16)); sioWrite8((unsigned char)((value&0xff) >> 24)); #ifdef PAD_LOG PAD_LOG("sio write32 %x\n", value); #endif return; #ifdef ENABLE_SIO1API case 0x1f801050: SIO1_writeData32(value); #ifdef SIO1_LOG SIO1_LOG("sio1 write32 %x\n", value); #endif return; #endif #ifdef PSXHW_LOG case 0x1f801060: PSXHW_LOG("RAM size write %x\n", value); psxHu32ref(add) = SWAPu32(value); return; // Ram size #endif case 0x1f801070: #ifdef PSXHW_LOG PSXHW_LOG("IREG 32bit write %x\n", value); #endif if (Config.SioIrq) psxHu32ref(0x1070) |= SWAPu32(0x80); if (Config.SpuIrq) psxHu32ref(0x1070) |= SWAPu32(0x200); psxHu32ref(0x1070) &= SWAPu32(value); return; case 0x1f801074: #ifdef PSXHW_LOG PSXHW_LOG("IMASK 32bit write %x\n", value); #endif psxHu32ref(0x1074) = SWAPu32(value); return; #ifdef PSXHW_LOG case 0x1f801080: PSXHW_LOG("DMA0 MADR 32bit write %x\n", value); HW_DMA0_MADR = SWAPu32(value); return; // DMA0 madr case 0x1f801084: PSXHW_LOG("DMA0 BCR 32bit write %x\n", value); HW_DMA0_BCR = SWAPu32(value); return; // DMA0 bcr #endif case 0x1f801088: #ifdef PSXHW_LOG PSXHW_LOG("DMA0 CHCR 32bit write %x\n", value); #endif DmaExec(0); // DMA0 chcr (MDEC in DMA) return; #ifdef PSXHW_LOG case 0x1f801090: PSXHW_LOG("DMA1 MADR 32bit write %x\n", value); HW_DMA1_MADR = SWAPu32(value); return; // DMA1 madr case 0x1f801094: PSXHW_LOG("DMA1 BCR 32bit write %x\n", value); HW_DMA1_BCR = SWAPu32(value); return; // DMA1 bcr #endif case 0x1f801098: #ifdef PSXHW_LOG PSXHW_LOG("DMA1 CHCR 32bit write %x\n", value); #endif DmaExec(1); // DMA1 chcr (MDEC out DMA) return; #ifdef PSXHW_LOG case 0x1f8010a0: PSXHW_LOG("DMA2 MADR 32bit write %x\n", value); HW_DMA2_MADR = SWAPu32(value); return; // DMA2 madr case 0x1f8010a4: PSXHW_LOG("DMA2 BCR 32bit write %x\n", value); HW_DMA2_BCR = SWAPu32(value); return; // DMA2 bcr #endif case 0x1f8010a8: #ifdef PSXHW_LOG PSXHW_LOG("DMA2 CHCR 32bit write %x\n", value); #endif /* A hack that makes Vampire Hunter D title screen visible, /* but makes Tomb Raider II water effect to stay opaque /* Root cause for this problem is that when DMA2 is issued /* it is incompletele and still beign built by the game. /* Maybe it is ready when some signal comes in or within given delay? */ if (dmaGpuListHackEn && value == 0x00000401 && HW_DMA2_BCR == 0x0) { psxDma2(SWAPu32(HW_DMA2_MADR), SWAPu32(HW_DMA2_BCR), SWAPu32(value)); return; } DmaExec(2); // DMA2 chcr (GPU DMA) if (HW_DMA2_CHCR == 0x1000401) dmaGpuListHackEn=TRUE; return; #ifdef PSXHW_LOG case 0x1f8010b0: PSXHW_LOG("DMA3 MADR 32bit write %x\n", value); HW_DMA3_MADR = SWAPu32(value); return; // DMA3 madr case 0x1f8010b4: PSXHW_LOG("DMA3 BCR 32bit write %x\n", value); HW_DMA3_BCR = SWAPu32(value); return; // DMA3 bcr #endif case 0x1f8010b8: #ifdef PSXHW_LOG PSXHW_LOG("DMA3 CHCR 32bit write %x\n", value); #endif DmaExec(3); // DMA3 chcr (CDROM DMA) return; #ifdef PSXHW_LOG case 0x1f8010c0: PSXHW_LOG("DMA4 MADR 32bit write %x\n", value); HW_DMA4_MADR = SWAPu32(value); return; // DMA4 madr case 0x1f8010c4: PSXHW_LOG("DMA4 BCR 32bit write %x\n", value); HW_DMA4_BCR = SWAPu32(value); return; // DMA4 bcr #endif case 0x1f8010c8: #ifdef PSXHW_LOG PSXHW_LOG("DMA4 CHCR 32bit write %x\n", value); #endif DmaExec(4); // DMA4 chcr (SPU DMA) return; #if 0 case 0x1f8010d0: break; //DMA5write_madr(); case 0x1f8010d4: break; //DMA5write_bcr(); case 0x1f8010d8: break; //DMA5write_chcr(); // Not needed #endif #ifdef PSXHW_LOG case 0x1f8010e0: PSXHW_LOG("DMA6 MADR 32bit write %x\n", value); HW_DMA6_MADR = SWAPu32(value); return; // DMA6 bcr case 0x1f8010e4: PSXHW_LOG("DMA6 BCR 32bit write %x\n", value); HW_DMA6_BCR = SWAPu32(value); return; // DMA6 bcr #endif case 0x1f8010e8: #ifdef PSXHW_LOG PSXHW_LOG("DMA6 CHCR 32bit write %x\n", value); #endif DmaExec(6); // DMA6 chcr (OT clear) return; #ifdef PSXHW_LOG case 0x1f8010f0: PSXHW_LOG("DMA PCR 32bit write %x\n", value); HW_DMA_PCR = SWAPu32(value); return; #endif case 0x1f8010f4: #ifdef PSXHW_LOG PSXHW_LOG("DMA ICR 32bit write %x\n", value); #endif { u32 tmp = (~value) & SWAPu32(HW_DMA_ICR); HW_DMA_ICR = SWAPu32(((tmp ^ value) & 0xffffff) ^ tmp); return; } case 0x1f801014: #ifdef PSXHW_LOG PSXHW_LOG("SPU delay [0x1014] write32: %8.8lx\n", value); #endif psxHu32ref(add) = SWAPu32(value); return; case 0x1f801810: #ifdef PSXHW_LOG PSXHW_LOG("GPU DATA 32bit write %x\n", value); #endif GPU_writeData(value); return; case 0x1f801814: #ifdef PSXHW_LOG PSXHW_LOG("GPU STATUS 32bit write %x\n", value); #endif if (value & 0x8000000) dmaGpuListHackEn=FALSE; GPU_writeStatus(value); return; case 0x1f801820: mdecWrite0(value); break; case 0x1f801824: mdecWrite1(value); break; case 0x1f801100: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 COUNT 32bit write %x\n", value); #endif psxRcntWcount(0, value & 0xffff); return; case 0x1f801104: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 MODE 32bit write %x\n", value); #endif psxRcntWmode(0, value); return; case 0x1f801108: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 0 TARGET 32bit write %x\n", value); #endif psxRcntWtarget(0, value & 0xffff); return; // HW_DMA_ICR&= SWAP32((~value)&0xff000000); case 0x1f801110: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 COUNT 32bit write %x\n", value); #endif psxRcntWcount(1, value & 0xffff); return; case 0x1f801114: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 MODE 32bit write %x\n", value); #endif psxRcntWmode(1, value); return; case 0x1f801118: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 1 TARGET 32bit write %x\n", value); #endif psxRcntWtarget(1, value & 0xffff); return; case 0x1f801120: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 COUNT 32bit write %x\n", value); #endif psxRcntWcount(2, value & 0xffff); return; case 0x1f801124: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 MODE 32bit write %x\n", value); #endif psxRcntWmode(2, value); return; case 0x1f801128: #ifdef PSXHW_LOG PSXHW_LOG("COUNTER 2 TARGET 32bit write %x\n", value); #endif psxRcntWtarget(2, value & 0xffff); return; default: // Dukes of Hazard 2 - car engine noise if (add>=0x1f801c00 && add<0x1f801e00) { SPU_writeRegister(add, value&0xffff); add += 2; value >>= 16; if (add>=0x1f801c00 && add<0x1f801e00) SPU_writeRegister(add, value&0xffff); return; } psxHu32ref(add) = SWAPu32(value); #ifdef PSXHW_LOG PSXHW_LOG("*Unknown 32bit write at address %x value %x\n", add, value); #endif return; }