diff --git a/core/hw/maple/maple_devs.cpp b/core/hw/maple/maple_devs.cpp index ece8b904f..a7b290123 100755 --- a/core/hw/maple/maple_devs.cpp +++ b/core/hw/maple/maple_devs.cpp @@ -87,8 +87,6 @@ enum MapleDeviceRV MDRS_JVSReply = 0x87, // JVS I/O }; -#define SWAP32(a) ((((a) & 0xff) << 24) | (((a) & 0xff00) << 8) | (((a) >> 8) & 0xff00) | (((a) >> 24) & 0xff)) - //fill in the info void maple_device::Setup(u32 prt) { @@ -242,6 +240,7 @@ struct maple_sega_controller: maple_base switch (cmd) { case MDC_DeviceRequest: + case MDC_AllStatusReq: //caps //4 w32(MFID_0_Input); @@ -270,7 +269,7 @@ struct maple_sega_controller: maple_base //2 w16(0x01F4); // 50 mA - return MDRS_DeviceStatus; + return cmd == MDC_DeviceRequest ? MDRS_DeviceStatus : MDRS_DeviceStatusAll; //controller condition case MDCF_GetCondition: @@ -307,8 +306,14 @@ struct maple_sega_controller: maple_base return MDRS_DataTransfer; + case MDC_DeviceReset: + return MDRS_DeviceReply; + + case MDC_DeviceKill: + return MDRS_DeviceReply; + default: - //printf("maple_sega_controller UNKOWN MAPLE COMMAND %d\n",cmd); + INFO_LOG(MAPLE, "maple_sega_controller: Unknown maple command %d", cmd); return MDRE_UnknownCmd; } } @@ -542,6 +547,7 @@ struct maple_sega_vmu: maple_base switch (cmd) { case MDC_DeviceRequest: + case MDC_AllStatusReq: //caps //4 w32(MFID_1_Storage | MFID_2_LCD | MFID_3_Clock); @@ -567,7 +573,7 @@ struct maple_sega_vmu: maple_base //2 w16(0x0082); // 13 mA - return MDRS_DeviceStatus; + return cmd == MDC_DeviceRequest ? MDRS_DeviceStatus : MDRS_DeviceStatusAll; //in[0] is function used //out[0] is function used @@ -829,6 +835,11 @@ struct maple_sega_vmu: maple_base } } + case MDC_DeviceReset: + return MDRS_DeviceReply; + + case MDC_DeviceKill: + return MDRS_DeviceReply; default: DEBUG_LOG(MAPLE, "Unknown MAPLE COMMAND %d", cmd); @@ -870,6 +881,7 @@ struct maple_microphone: maple_base switch (cmd) { case MDC_DeviceRequest: + case MDC_AllStatusReq: DEBUG_LOG(MAPLE, "maple_microphone::dma MDC_DeviceRequest"); //this was copied from the controller case with just the id and name replaced! @@ -901,7 +913,7 @@ struct maple_microphone: maple_base //2 w16(0x01F4); // 50 mA - return MDRS_DeviceStatus; + return cmd == MDC_DeviceRequest ? MDRS_DeviceStatus : MDRS_DeviceStatusAll; case MDCF_GetCondition: { @@ -1026,6 +1038,9 @@ struct maple_microphone: maple_base } } + case MDC_DeviceKill: + return MDRS_DeviceReply; + default: INFO_LOG(MAPLE, "maple_microphone::dma UNHANDLED MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; @@ -1063,6 +1078,7 @@ struct maple_sega_purupuru : maple_base switch (cmd) { case MDC_DeviceRequest: + case MDC_AllStatusReq: //caps //4 w32(MFID_8_Vibration); @@ -1091,7 +1107,7 @@ struct maple_sega_purupuru : maple_base //2 w16(0x0640); // 160 mA - return MDRS_DeviceStatus; + return cmd == MDC_DeviceRequest ? MDRS_DeviceStatus : MDRS_DeviceStatusAll; //get last vibration case MDCF_GetCondition: @@ -1161,6 +1177,12 @@ struct maple_sega_purupuru : maple_base return MDRS_DeviceReply; + case MDC_DeviceReset: + return MDRS_DeviceReply; + + case MDC_DeviceKill: + return MDRS_DeviceReply; + default: INFO_LOG(MAPLE, "UNKOWN MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; @@ -1184,6 +1206,7 @@ struct maple_keyboard : maple_base switch (cmd) { case MDC_DeviceRequest: + case MDC_AllStatusReq: //caps //4 w32(MFID_6_Keyboard); @@ -1215,7 +1238,7 @@ struct maple_keyboard : maple_base // Maximum current consumption (2) w16(0x01F5); // 50.1 mA - return MDRS_DeviceStatus; + return cmd == MDC_DeviceRequest ? MDRS_DeviceStatus : MDRS_DeviceStatusAll; case MDCF_GetCondition: w32(MFID_6_Keyboard); @@ -1232,6 +1255,12 @@ struct maple_keyboard : maple_base return MDRS_DataTransfer; + case MDC_DeviceReset: + return MDRS_DeviceReply; + + case MDC_DeviceKill: + return MDRS_DeviceReply; + default: INFO_LOG(MAPLE, "Keyboard: unknown MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; @@ -1278,6 +1307,7 @@ struct maple_mouse : maple_base switch (cmd) { case MDC_DeviceRequest: + case MDC_AllStatusReq: //caps //4 w32(MFID_9_Mouse); @@ -1309,7 +1339,7 @@ struct maple_mouse : maple_base // Maximum current consumption (2) w16(0x0120); // 28.8 mA - return MDRS_DeviceStatus; + return cmd == MDC_DeviceRequest ? MDRS_DeviceStatus : MDRS_DeviceStatusAll; case MDCF_GetCondition: w32(MFID_9_Mouse); @@ -1339,6 +1369,12 @@ struct maple_mouse : maple_base return MDRS_DataTransfer; + case MDC_DeviceReset: + return MDRS_DeviceReply; + + case MDC_DeviceKill: + return MDRS_DeviceReply; + default: INFO_LOG(MAPLE, "Mouse: unknown MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; @@ -1362,6 +1398,7 @@ struct maple_lightgun : maple_base switch (cmd) { case MDC_DeviceRequest: + case MDC_AllStatusReq: //caps //4 w32(MFID_7_LightGun | MFID_0_Input); @@ -1393,7 +1430,7 @@ struct maple_lightgun : maple_base // Maximum current consumption (2) w16(0x0120); // 28.8 mA - return MDRS_DeviceStatus; + return cmd == MDC_DeviceRequest ? MDRS_DeviceStatus : MDRS_DeviceStatusAll; case MDCF_GetCondition: { @@ -1416,9 +1453,14 @@ struct maple_lightgun : maple_base //4 w32(0x80808080); } - return MDRS_DataTransfer; + case MDC_DeviceReset: + return MDRS_DeviceReply; + + case MDC_DeviceKill: + return MDRS_DeviceReply; + default: INFO_LOG(MAPLE, "Light gun: unknown MAPLE COMMAND %d", cmd); return MDRE_UnknownCmd; @@ -2519,15 +2561,21 @@ struct maple_naomi_jamma : maple_sega_controller w8(0x00); w8(0x20); w8(0x00); + break; + case MDC_AllStatusReq: + w8(MDRS_DeviceStatusAll); + w8(0x00); + w8(0x20); + w8(0x00); break; case MDC_DeviceReset: + case MDC_DeviceKill: w8(MDRS_DeviceReply); w8(0x00); w8(0x20); w8(0x00); - break; case MDCF_GetCondition: diff --git a/core/hw/maple/maple_devs.h b/core/hw/maple/maple_devs.h index d1505381f..e95063ca5 100755 --- a/core/hw/maple/maple_devs.h +++ b/core/hw/maple/maple_devs.h @@ -143,3 +143,5 @@ extern s32 mo_y_abs; extern f32 mo_x_delta; extern f32 mo_y_delta; extern f32 mo_wheel_delta; + +#define SWAP32(a) ((((a) & 0xff) << 24) | (((a) & 0xff00) << 8) | (((a) >> 8) & 0xff00) | (((a) >> 24) & 0xff)) diff --git a/core/hw/maple/maple_helper.cpp b/core/hw/maple/maple_helper.cpp index 095dd5fb9..03c509103 100644 --- a/core/hw/maple/maple_helper.cpp +++ b/core/hw/maple/maple_helper.cpp @@ -8,7 +8,7 @@ u32 maple_GetPort(u32 addr) if ((1<> 8) & 0x7f) << 20) | 0x08000000)); + u32 top = std::min(0x0FFFFFE0u, (((SB_MDAPRO & 0x7f) << 20) | 0x080fffff)); + if (((addr >> 29) & 7) == 7 + || (addr & 0x0fffffff) < bottom + || (addr & 0x0fffffff) > top) + { + INFO_LOG(MAPLE, "MAPLE ERROR : Invalid address: %08x. SB_MDAPRO: %x %x", addr, (SB_MDAPRO >> 8) & 0x7f, SB_MDAPRO & 0x7f); + return false; + } + return true; +} + +static void maple_SB_MDSTAR_Write(u32 addr, u32 data) +{ + SB_MDSTAR = data; + if (!check_mdapro(data)) + asic_RaiseInterrupt(holly_MAPLE_ILLADDR); +} bool IsOnSh4Ram(u32 addr) { @@ -114,6 +136,15 @@ static void maple_DoDma() DEBUG_LOG(MAPLE, "Maple: DoMapleDma SB_MDSTAR=%x", SB_MDSTAR); u32 addr = SB_MDSTAR; +#ifdef STRICT_MODE + if (!check_mdapro(addr)) + { + asic_RaiseInterrupt(holly_MAPLE_ILLADDR); + SB_MDST = 0; + return; + } +#endif + const bool swap_msb = (SB_MMSEL == 0); u32 xfer_count=0; bool last = false; while (last != true) @@ -132,14 +163,22 @@ static void maple_DoDma() { case MP_Start: { +#ifdef STRICT_MODE + if (!check_mdapro(header_2) || !check_mdapro(addr + 8 + plen * sizeof(u32) - 1)) + { + asic_RaiseInterrupt(holly_MAPLE_OVERRUN); + SB_MDST = 0; + return; + } +#else if (!IsOnSh4Ram(header_2)) { INFO_LOG(MAPLE, "MAPLE ERROR : DESTINATION NOT ON SH4 RAM 0x%X", header_2); header_2&=0xFFFFFF; header_2|=(3<<26); } +#endif u32* p_out=(u32*)GetMemPtr(header_2,4); - u32 outlen=0; u32* p_data =(u32*) GetMemPtr(addr + 8,(plen)*sizeof(u32)); if (p_data == NULL) @@ -148,30 +187,55 @@ static void maple_DoDma() SB_MDST=0; return; } - + const u32 frame_header = swap_msb ? SWAP32(p_data[0]) : p_data[0]; + //Command code - u32 command=p_data[0] &0xFF; + u32 command = frame_header & 0xFF; //Recipient address - u32 reci=(p_data[0] >> 8) & 0xFF;//0-5; + u32 reci = (frame_header >> 8) & 0xFF;//0-5; + //Sender address + //u32 send = (frame_header >> 16) & 0xFF; + //Number of additional words in frame + u32 inlen = (frame_header >> 24) & 0xFF; + u32 port=maple_GetPort(reci); u32 bus=maple_GetBusId(reci); - //Sender address - u32 send=(p_data[0] >> 16) & 0xFF; - //Number of additional words in frame - u32 inlen=(p_data[0]>>24) & 0xFF; - u32 resp=0; - inlen*=4; if (MapleDevices[bus][5] && MapleDevices[bus][port]) { - u32 outlen = MapleDevices[bus][port]->RawDma(&p_data[0], inlen + 4, &p_out[0]); + if (swap_msb) + { + static u32 maple_in_buf[1024 / 4]; + static u32 maple_out_buf[1024 / 4]; + maple_in_buf[0] = frame_header; + for (u32 i = 1; i < inlen; i++) + maple_in_buf[i] = SWAP32(p_data[i]); + p_data = maple_in_buf; + p_out = maple_out_buf; + } + u32 outlen = MapleDevices[bus][port]->RawDma(&p_data[0], inlen * 4 + 4, &p_out[0]); xfer_count += outlen; +#ifdef STRICT_MODE + if (!check_mdapro(header_2 + outlen - 1)) + { + // TODO: This isn't correct (with SB_MMSEL=1) since the interrupt + // should be raised before the memory is written to + asic_RaiseInterrupt(holly_MAPLE_OVERRUN); + SB_MDST = 0; + return; + } +#endif + if (swap_msb) + { + u32 *final_out = (u32 *)GetMemPtr(header_2, outlen); + for (u32 i = 0; i < outlen / 4; i++) + final_out[i] = SWAP32(p_out[i]); + } } else { if (port != 5 && command != 1) - INFO_LOG(MAPLE, "MAPLE: Unknown device bus %d port %d cmd %d", bus, port, command); - outlen=4; + INFO_LOG(MAPLE, "MAPLE: Unknown device bus %d port %d cmd %d reci %d", bus, port, command, reci); p_out[0]=0xFFFFFFFF; } @@ -234,6 +298,9 @@ void maple_Init() sb_rio_register(SB_MDST_addr,RIO_WF,0,&maple_SB_MDST_Write); sb_rio_register(SB_MDEN_addr,RIO_WF,0,&maple_SB_MDEN_Write); sb_rio_register(SB_MSHTCL_addr,RIO_WF,0,&maple_SB_MSHTCL_Write); +#ifdef STRICT_MODE + sb_rio_register(SB_MDSTAR_addr, RIO_WF, 0, &maple_SB_MDSTAR_Write); +#endif maple_schid=sh4_sched_register(0,&maple_schd); } diff --git a/core/types.h b/core/types.h index 18a7c87c1..033425e98 100644 --- a/core/types.h +++ b/core/types.h @@ -109,22 +109,22 @@ enum HollyInterruptID //bit 0 = RENDER : ISP out of Cache(Buffer over flow) //bit 1 = RENDER : Hazard Processing of Strip Buffer holly_PRIM_NOMEM = holly_err | 0x02, //bit 2 = TA : ISP/TSP Parameter Overflow - holly_MATR_NOMEM = holly_err | 0x03 //bit 3 = TA : Object List Pointer Overflow + holly_MATR_NOMEM = holly_err | 0x03, //bit 3 = TA : Object List Pointer Overflow //bit 4 = TA : Illegal Parameter //bit 5 = TA : FIFO Overflow //bit 6 = PVRIF : Illegal Address set //bit 7 = PVRIF : DMA over run - //bit 8 = MAPLE : Illegal Address set - //bit 9 = MAPLE : DMA over run - //bit 10 = MAPLE : Write FIFO over flow - //bit 11 = MAPLE : Illegal command + holly_MAPLE_ILLADDR = holly_err | 0x08, //bit 8 = MAPLE : Illegal Address set + holly_MAPLE_OVERRUN = holly_err | 0x09, //bit 9 = MAPLE : DMA over run + holly_MAPLE_FIFO = holly_err | 0x0a, //bit 10 = MAPLE : Write FIFO overflow + holly_MAPLE_ILLCMD = holly_err | 0x0b, //bit 11 = MAPLE : Illegal command //bit 12 = G1 : Illegal Address set //bit 13 = G1 : GD-DMA over run //bit 14 = G1 : ROM/FLASH access at GD-DMA - //bit 15 = G2 : AICA-DMA Illegal Address set - //bit 16 = G2 : Ext-DMA1 Illegal Address set - //bit 17 = G2 : Ext-DMA2 Illegal Address set - //bit 18 = G2 : Dev-DMA Illegal Address set + holly_AICA_ILLADDR = holly_err | 0x0f, //bit 15 = G2 : AICA-DMA Illegal Address set + holly_EXT1_ILLADDR = holly_err | 0x10, //bit 16 = G2 : Ext-DMA1 Illegal Address set + holly_EXT2_ILLADDR = holly_err | 0x11, //bit 17 = G2 : Ext-DMA2 Illegal Address set + holly_DEV_ILLADDR = holly_err | 0x12, //bit 18 = G2 : Dev-DMA Illegal Address set //bit 19 = G2 : AICA-DMA over run //bit 20 = G2 : Ext-DMA1 over run //bit 21 = G2 : Ext-DMA2 over run