maple: msb selection, implement/fake reset, kill and allreq commands
overrun and illegal address ints in strict mode
This commit is contained in:
parent
5cfed1e482
commit
8192eea387
|
@ -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:
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -8,7 +8,7 @@ u32 maple_GetPort(u32 addr)
|
|||
if ((1<<i)&addr)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
return 5;
|
||||
}
|
||||
u32 maple_GetAttachedDevices(u32 bus)
|
||||
{
|
||||
|
|
|
@ -66,12 +66,14 @@ void maple_vblank()
|
|||
if (settings.platform.system == DC_PLATFORM_DREAMCAST)
|
||||
maple_handle_reconnect();
|
||||
}
|
||||
void maple_SB_MSHTCL_Write(u32 addr, u32 data)
|
||||
|
||||
static void maple_SB_MSHTCL_Write(u32 addr, u32 data)
|
||||
{
|
||||
if (data&1)
|
||||
maple_ddt_pending_reset=false;
|
||||
}
|
||||
void maple_SB_MDST_Write(u32 addr, u32 data)
|
||||
|
||||
static void maple_SB_MDST_Write(u32 addr, u32 data)
|
||||
{
|
||||
if (data & 0x1)
|
||||
{
|
||||
|
@ -83,7 +85,7 @@ void maple_SB_MDST_Write(u32 addr, u32 data)
|
|||
}
|
||||
}
|
||||
|
||||
void maple_SB_MDEN_Write(u32 addr, u32 data)
|
||||
static void maple_SB_MDEN_Write(u32 addr, u32 data)
|
||||
{
|
||||
SB_MDEN=data&1;
|
||||
|
||||
|
@ -93,6 +95,26 @@ void maple_SB_MDEN_Write(u32 addr, u32 data)
|
|||
}
|
||||
}
|
||||
|
||||
static bool check_mdapro(u32 addr)
|
||||
{
|
||||
u32 bottom = std::max(0x0C000000u, ((((SB_MDAPRO >> 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);
|
||||
}
|
||||
|
|
18
core/types.h
18
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
|
||||
|
|
Loading…
Reference in New Issue