From 044a9f6a67cf1b03202d8cc242140861ebf0bb46 Mon Sep 17 00:00:00 2001 From: Anthony Pesch Date: Thu, 15 Jun 2017 00:31:43 -0400 Subject: [PATCH] made the SPI_CD_* commands set the correct GD-ROM state --- src/guest/bios/bios.c | 2 ++ src/guest/bios/syscalls.c | 5 ++-- src/guest/gdrom/gdrom.c | 46 +++++++++++++++++++++++++++++------ src/guest/gdrom/gdrom_types.h | 7 ++++++ 4 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/guest/bios/bios.c b/src/guest/bios/bios.c index e8b82405..417e2063 100644 --- a/src/guest/bios/bios.c +++ b/src/guest/bios/bios.c @@ -388,6 +388,8 @@ int bios_invalid_instr(struct bios *bios) { struct sh4_context *ctx = &dc->sh4->ctx; uint32_t pc = ctx->pc & 0x1cffffff; + /* if an actual boot rom wasn't loaded into memory, a valid instruction won't + exist at 0x0, causing an immediate trap on start */ if (pc == 0x0) { return bios_boot(bios); } diff --git a/src/guest/bios/syscalls.c b/src/guest/bios/syscalls.c index 3f67d115..b028f455 100644 --- a/src/guest/bios/syscalls.c +++ b/src/guest/bios/syscalls.c @@ -141,8 +141,8 @@ static void bios_gdrom_mainloop(struct bios *bios) { enum gd_secfmt fmt = SECTOR_ANY; enum gd_secmask mask = MASK_DATA; - LOG_SYSCALL("GDC_DMAREAD fad=0x%x n=0x%x dst=0x%x unknown=0x%x", - fad, n, dst, unknown); + LOG_SYSCALL("GDC_DMAREAD fad=0x%x n=0x%x dst=0x%x unknown=0x%x", fad, n, + dst, unknown); /* dma read functionality changes somehow when this in non-zero */ CHECK_EQ(unknown, 0); @@ -253,6 +253,7 @@ static void bios_gdrom_mainloop(struct bios *bios) { case GDC_STOP: { LOG_FATAL("GDC_STOP"); + /* TODO same as SPI_CD_SEEK with parameter type = stop playback */ } break; case GDC_GET_SCD: { diff --git a/src/guest/gdrom/gdrom.c b/src/guest/gdrom/gdrom.c index e6443c73..3d0c5331 100644 --- a/src/guest/gdrom/gdrom.c +++ b/src/guest/gdrom/gdrom.c @@ -324,20 +324,50 @@ static void gdrom_spi_cmd(struct gdrom *gd, int arg) { gdrom_spi_end(gd); } break; - case SPI_CD_OPEN: - case SPI_CD_PLAY: - case SPI_CD_SEEK: + case SPI_CD_OPEN: { + LOG_FATAL("SPI_CD_OPEN"); + } break; + + case SPI_CD_PLAY: { + LOG_WARNING("ignoring SPI_CD_PLAY"); + + gd->sectnum.status = DST_PAUSE; + + gdrom_spi_end(gd); + } break; + + case SPI_CD_SEEK: { + enum gd_seek_type param_type = (enum gd_seek_type)(data[1] & 0xf); + + LOG_WARNING("ignoring SPI_CD_SEEK"); + + switch (param_type) { + case SEEK_FAD: + case SEEK_MSF: + case SEEK_PAUSE: + gd->sectnum.status = DST_PAUSE; + break; + case SEEK_STOP: + gd->sectnum.status = DST_STANDBY; + break; + } + + gdrom_spi_end(gd); + } break; + case SPI_CD_SCAN: { + LOG_WARNING("ignoring SPI_CD_SCAN"); + + gd->sectnum.status = DST_PAUSE; + gdrom_spi_end(gd); } break; /* SPI_CHK_SECU / SPI_REQ_SECU are part of an undocumented security check that has yet to be fully reverse engineered. the check doesn't seem to - have any side effects other than setting the drive to the PAUSE state, - and a valid, canned response is sent when the results are requested */ + have any side effects, a canned response is sent when the results are + requested */ case SPI_CHK_SECU: { - gd->sectnum.status = DST_PAUSE; - gdrom_spi_end(gd); } break; @@ -783,7 +813,7 @@ void gdrom_set_disc(struct gdrom *gd, struct disc *disc) { gd->sectnum.full = 0; if (gd->disc) { - gd->sectnum.status = DST_STANDBY; + gd->sectnum.status = DST_PAUSE; gd->sectnum.format = disc_get_format(disc); } else { gd->sectnum.status = DST_NODISC; diff --git a/src/guest/gdrom/gdrom_types.h b/src/guest/gdrom/gdrom_types.h index 9ca6172a..1de2e378 100644 --- a/src/guest/gdrom/gdrom_types.h +++ b/src/guest/gdrom/gdrom_types.h @@ -95,6 +95,13 @@ enum gd_secfmt { SECTOR_M2_NOXA, }; +enum gd_seek_type { + SEEK_FAD = 0x1, + SEEK_MSF = 0x2, + SEEK_STOP = 0x3, + SEEK_PAUSE = 0x4, +}; + /* internal registers accessed through holly */ union gd_error { uint32_t full;