From 2371657828b84b7643159fd456708f747b94366b Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Tue, 9 May 2017 13:42:45 -0400 Subject: [PATCH] set gdrom status to paused after 0x71 check note, I have no idea what this check actually does, however Cannon Spike expected this to be set afterwards and failed to boot otherwise. setting this doesn't seem to negatively impact other games, so I believe this is the correct thing to do for now --- src/hw/gdrom/gdrom.c | 68 ++++++++++++++++++++++++++----------- src/hw/holly/holly_regs.inc | 11 +++--- 2 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/hw/gdrom/gdrom.c b/src/hw/gdrom/gdrom.c index 6f6a315f..9dee49cf 100644 --- a/src/hw/gdrom/gdrom.c +++ b/src/hw/gdrom/gdrom.c @@ -318,11 +318,15 @@ static void gdrom_spi_cmd(struct gdrom *gd, uint8_t *data) { gdrom_event(gd, EV_SPI_CMD_DONE, 0, 0); break; + /* 0x70 and 0x71 appear to be a part of some kind of security check that has + yet to be properly reverse engineered. be a lemming and reply / set state + as expected by various games */ case SPI_UNKNOWN_70: gdrom_event(gd, EV_SPI_CMD_DONE, 0, 0); break; case SPI_UNKNOWN_71: + gd->sectnum.status = DST_PAUSE; gdrom_event(gd, EV_SPI_WRITE_START, (intptr_t)reply_71, sizeof(reply_71)); break; @@ -590,25 +594,34 @@ REG_R32(holly_cb, GD_ALTSTAT_DEVCTRL) { struct gdrom *gd = dc->gdrom; /* this register is the same as the status register, but it does not clear DMA status information when it is accessed */ - return gd->status.full; + uint16_t value = gd->status.full; + LOG_GDROM("read GD_ALTSTAT 0x%x", value); + return value; } REG_W32(holly_cb, GD_ALTSTAT_DEVCTRL) { - LOG_GDROM("GD_DEVCTRL 0x%x", (uint32_t)value); + LOG_GDROM("write GD_DEVCTRL 0x%x [unimplemented]", value); } REG_R32(holly_cb, GD_DATA) { struct gdrom *gd = dc->gdrom; - uint16_t v = *(uint16_t *)&gd->pio_buffer[gd->pio_head]; + uint16_t value = *(uint16_t *)&gd->pio_buffer[gd->pio_head]; + + LOG_GDROM("read GD_DATA 0x%x", value); + gd->pio_head += 2; if (gd->pio_head == gd->pio_size) { gdrom_event(gd, EV_SPI_WRITE_END, 0, 0); } - return v; + + return value; } REG_W32(holly_cb, GD_DATA) { struct gdrom *gd = dc->gdrom; + + LOG_GDROM("write GD_DATA 0x%x", value); + *(uint16_t *)&gd->pio_buffer[gd->pio_head] = (uint16_t)(value & 0xffff); gd->pio_head += 2; @@ -620,68 +633,85 @@ REG_W32(holly_cb, GD_DATA) { } REG_R32(holly_cb, GD_ERROR_FEATURES) { - LOG_GDROM("GD_ERROR"); - return 0; + uint16_t value = 0; + LOG_GDROM("read GD_ERROR 0x%x [unimplemented]", value); + return value; } REG_W32(holly_cb, GD_ERROR_FEATURES) { struct gdrom *gd = dc->gdrom; + LOG_GDROM("write GD_FEATURES 0x%x", value); gd->features.full = value; } -REG_R32(holly_cb, GD_INTREASON_SECTCNT) { +REG_R32(holly_cb, GD_INTREASON) { struct gdrom *gd = dc->gdrom; - return gd->ireason.full; + uint16_t value = gd->ireason.full; + LOG_GDROM("read GD_INTREASON 0x%x", value); + return value; } -REG_W32(holly_cb, GD_INTREASON_SECTCNT) { - struct gdrom *gd = dc->gdrom; - gd->ireason.full = value; +REG_W32(holly_cb, GD_INTREASON) { + LOG_FATAL("invalid write to GD_INTREASON"); } REG_R32(holly_cb, GD_SECTNUM) { struct gdrom *gd = dc->gdrom; - return gd->sectnum.full; + uint16_t value = gd->sectnum.full; + LOG_GDROM("read GD_SECTNUM 0x%x", value); + return value; } REG_W32(holly_cb, GD_SECTNUM) { - struct gdrom *gd = dc->gdrom; - gd->sectnum.full = value; + LOG_FATAL("invalid write to GD_SECTNUM"); } REG_R32(holly_cb, GD_BYCTLLO) { struct gdrom *gd = dc->gdrom; - return gd->byte_count.lo; + uint16_t value = gd->byte_count.lo; + LOG_GDROM("read GD_BYCTLLO 0x%x", value); + return value; } REG_W32(holly_cb, GD_BYCTLLO) { struct gdrom *gd = dc->gdrom; + LOG_GDROM("write GD_BYCTLLO 0x%x", value); gd->byte_count.lo = value; } REG_R32(holly_cb, GD_BYCTLHI) { struct gdrom *gd = dc->gdrom; - return gd->byte_count.hi; + uint16_t value = gd->byte_count.hi; + LOG_GDROM("read GD_BYCTLHI 0x%x", value); + return value; } REG_W32(holly_cb, GD_BYCTLHI) { struct gdrom *gd = dc->gdrom; + LOG_GDROM("write GD_BYCTLHI 0x%x", value); gd->byte_count.hi = value; } REG_R32(holly_cb, GD_DRVSEL) { - return 0; + uint16_t value = 0; + LOG_GDROM("read GD_DRVSEL 0x%x [unimplemented]", value); + return value; } -REG_W32(holly_cb, GD_DRVSEL) {} +REG_W32(holly_cb, GD_DRVSEL) { + LOG_GDROM("write GD_DRVSEL 0x%x [unimplemented]", value); +} REG_R32(holly_cb, GD_STATUS_COMMAND) { struct gdrom *gd = dc->gdrom; + uint16_t value = gd->status.full; + LOG_GDROM("read GD_STATUS_COMMAND 0x%x", value); holly_clear_interrupt(gd->holly, HOLLY_INTC_G1GDINT); - return gd->status.full; + return value; } REG_W32(holly_cb, GD_STATUS_COMMAND) { struct gdrom *gd = dc->gdrom; + LOG_GDROM("write GD_STATUS_COMMAND 0x%x", value); gdrom_ata_cmd(gd, (enum gd_ata_cmd)value); } diff --git a/src/hw/holly/holly_regs.inc b/src/hw/holly/holly_regs.inc index 477c4559..45da8c55 100644 --- a/src/hw/holly/holly_regs.inc +++ b/src/hw/holly/holly_regs.inc @@ -33,7 +33,7 @@ HOLLY_REG(0x005f6940, SB_PDTNRM, 0x00000000, uint32_t) HOLLY_REG(0x005f6944, SB_PDTEXT, 0x00000000, uint32_t) HOLLY_REG(0x005f6950, SB_G2DTNRM, 0x00000000, uint32_t) HOLLY_REG(0x005f6954, SB_G2DTEXT, 0x00000000, uint32_t) -// maple +/* maple */ HOLLY_REG(0x005f6c04, SB_MDSTAR, 0x00000000, uint32_t) HOLLY_REG(0x005f6c10, SB_MDTSEL, 0x00000000, uint32_t) HOLLY_REG(0x005f6c14, SB_MDEN, 0x00000000, uint32_t) @@ -46,17 +46,18 @@ HOLLY_REG(0x005f6ce8, SB_MMSEL, 0x00000001, uint32_t) HOLLY_REG(0x005f6cf4, SB_MTXDAD, 0x00000000, uint32_t) HOLLY_REG(0x005f6cf8, SB_MRXDAD, 0x00000000, uint32_t) HOLLY_REG(0x005f6cfc, SB_MRXDBD, 0x00000000, uint32_t) -// gdrom +/* gdrom. note, some of these registers have multiple names as they serve two + different purposes based on if they're being read from or written to */ HOLLY_REG(0x005f7018, GD_ALTSTAT_DEVCTRL, 0x00000000, uint32_t) HOLLY_REG(0x005f7080, GD_DATA, 0x00000000, uint32_t) HOLLY_REG(0x005f7084, GD_ERROR_FEATURES, 0x00000000, uint32_t) -HOLLY_REG(0x005f7088, GD_INTREASON_SECTCNT, 0x00000000, uint32_t) +HOLLY_REG(0x005f7088, GD_INTREASON, 0x00000000, uint32_t) HOLLY_REG(0x005f708c, GD_SECTNUM, 0x00000000, uint32_t) HOLLY_REG(0x005f7090, GD_BYCTLLO, 0x00000000, uint32_t) HOLLY_REG(0x005f7094, GD_BYCTLHI, 0x00000000, uint32_t) HOLLY_REG(0x005f7098, GD_DRVSEL, 0x00000000, uint32_t) HOLLY_REG(0x005f709c, GD_STATUS_COMMAND, 0x00000000, uint32_t) -// G1 bus +/* g1 bus */ HOLLY_REG(0x005f7404, SB_GDSTAR, 0x00000000, uint32_t) HOLLY_REG(0x005f7408, SB_GDLEN, 0x00000000, uint32_t) HOLLY_REG(0x005f740c, SB_GDDIR, 0x00000000, uint32_t) @@ -75,7 +76,7 @@ HOLLY_REG(0x005f74b4, SB_G1CRDYC, 0x00000001, uint32_t) HOLLY_REG(0x005f74b8, SB_GDAPRO, 0x00007f00, uint32_t) HOLLY_REG(0x005f74f4, SB_GDSTARD, 0x00000000, uint32_t) HOLLY_REG(0x005f74f8, SB_GDLEND, 0x00000000, uint32_t) -// G2 bus +/* g2 bus */ HOLLY_REG(0x005f7800, SB_ADSTAG, 0x00000000, uint32_t) HOLLY_REG(0x005f7804, SB_ADSTAR, 0x00000000, uint32_t) HOLLY_REG(0x005f7808, SB_ADLEN, 0x00000000, uint32_t)