From efe27ea77ef91b36965bd86e6e09828e2b7dbb76 Mon Sep 17 00:00:00 2001 From: zakk4223 Date: Sun, 20 Feb 2022 10:12:06 -0500 Subject: [PATCH] Add CHD image support for PSX (#549) --- support/chd/mister_chd.cpp | 2 + support/psx/psx.cpp | 109 +++++++++++++++++++++++++++++++++---- 2 files changed, 99 insertions(+), 12 deletions(-) diff --git a/support/chd/mister_chd.cpp b/support/chd/mister_chd.cpp index cc38489..e9a0a1c 100644 --- a/support/chd/mister_chd.cpp +++ b/support/chd/mister_chd.cpp @@ -86,6 +86,7 @@ chd_error mister_load_chd(const char *filename, toc_t *cd_toc) cd_toc->tracks[cd_toc->last].start += pregap; } + cd_toc->tracks[cd_toc->last].index1 = pregap; } else { if (pregap_valid) { @@ -93,6 +94,7 @@ chd_error mister_load_chd(const char *filename, toc_t *cd_toc) } else { cd_toc->tracks[cd_toc->last].start = 0; } + cd_toc->tracks[cd_toc->last].index1 = pregap; } if (!pregap_valid) diff --git a/support/psx/psx.cpp b/support/psx/psx.cpp index ea110c6..6a05245 100644 --- a/support/psx/psx.cpp +++ b/support/psx/psx.cpp @@ -12,8 +12,13 @@ #include "psx.h" #include "mcdheader.h" #include "../../cd.h" +#include "../chd/mister_chd.h" +#include static char buf[1024]; +static uint8_t chd_hunkbuf[CD_FRAME_SIZE * CD_FRAMES_PER_HUNK]; +static int chd_hunknum; + static int sgets(char *out, int sz, char **in) { @@ -98,6 +103,19 @@ static uint16_t libCryptMask(const char *sbifile) return mask; } +static void unload_chd(toc_t *table) +{ + if (table->chd_f) + { + chd_close(table->chd_f); + } + memset(chd_hunkbuf, 0, sizeof(chd_hunkbuf)); + memset(table, 0, sizeof(toc_t)); + chd_hunknum = -1; + +} + + static void unload_cue(toc_t *table) { for (int i = 0; i < table->last; i++) @@ -107,6 +125,37 @@ static void unload_cue(toc_t *table) memset(table, 0, sizeof(toc_t)); } +static int load_chd(const char *filename, toc_t *table) +{ + + unload_chd(table); + chd_error err = mister_load_chd(filename, table); + if (err != CHDERR_NONE) + { + return 0; + } + + for(int i = 0; i < table->last; i++) + { + if (i == 0) //First track fakes a pregap even if it doesn't exist + { + table->tracks[i].index1 = 150; + table->tracks[i].start = 150; + } + table->tracks[i].end += (table->tracks[i].index1 - 1); + } + table->end = table->tracks[table->last-1].end+1; + + memset(chd_hunkbuf, 0, sizeof(chd_hunkbuf)); + chd_hunknum = -1; + + return 1; + + //Need to store hunkbuf, hunknum and chd_f + + + +} static int load_cue(const char* filename, toc_t *table) { static char fname[1024 + 10]; @@ -284,6 +333,23 @@ static int load_cue(const char* filename, toc_t *table) return 1; } +static int load_cd_image(const char *filename, toc_t *table) +{ + + const char *ext = strrchr(filename, '.'); + if (!ext) return 0; + + if (!strncasecmp(".chd", ext, 4)) + { + return load_chd(filename, table); + } else if (!strncasecmp(".cue", ext, 4)) { + return load_cue(filename,table); + } + + return 0; +} + + struct track_t { uint32_t start_lba; @@ -328,8 +394,6 @@ void send_cue(toc_t *table) user_io_set_download(1); user_io_file_tx_data((uint8_t *)disk, sizeof(disk_t)); user_io_set_download(0); - - hexdump(disk, 256); delete(disk); } } @@ -387,17 +451,37 @@ void psx_read_cd(uint8_t *buffer, int lba, int cnt) { if (lba >= toc.tracks[i].start && lba <= toc.tracks[i].end) { - if(toc.tracks[i].offset) - FileSeek(&toc.tracks[0].f, ((lba * CD_SECTOR_LEN) - toc.tracks[i].offset), SEEK_SET); - else - FileSeek(&toc.tracks[i].f, (lba - toc.tracks[i].start) * CD_SECTOR_LEN, SEEK_SET); - + if (!toc.chd_f) + { + if(toc.tracks[i].offset) + FileSeek(&toc.tracks[0].f, ((lba * CD_SECTOR_LEN) - toc.tracks[i].offset), SEEK_SET); + else + FileSeek(&toc.tracks[i].f, (lba - toc.tracks[i].start) * CD_SECTOR_LEN, SEEK_SET); + } while (cnt) { - if (toc.tracks[i].offset) - FileReadAdv(&toc.tracks[0].f, buffer, CD_SECTOR_LEN); - else - FileReadAdv(&toc.tracks[i].f, buffer, CD_SECTOR_LEN); + if (toc.chd_f) + { + if (mister_chd_read_sector(toc.chd_f, (lba - toc.tracks[i].index1) + toc.tracks[i].offset, 0, 0, CD_SECTOR_LEN, buffer, chd_hunkbuf, &chd_hunknum) == CHDERR_NONE) + { + if (!toc.tracks[i].type) //CHD requires byteswap of audio data + { + for (int swapidx = 0; swapidx < CD_SECTOR_LEN; swapidx += 2) + { + uint8_t temp = buffer[swapidx]; + buffer[swapidx] = buffer[swapidx+1]; + buffer[swapidx+1] = temp; + } + } + } else { + printf("\x1b[32mPSX: CHD read error: %d\n\x1b[0m", lba); + } + } else { + if (toc.tracks[i].offset) + FileReadAdv(&toc.tracks[0].f, buffer, CD_SECTOR_LEN); + else + FileReadAdv(&toc.tracks[i].f, buffer, CD_SECTOR_LEN); + } if ((lba + 1) > toc.tracks[i].end) break; buffer += CD_SECTOR_LEN; cnt--; @@ -438,7 +522,7 @@ void psx_mount_cd(int f_index, int s_index, const char *filename) if (strlen(filename)) { - if (load_cue(filename, &toc) && toc.last) + if (load_cd_image(filename, &toc) && toc.last) { int name_len = strlen(filename); @@ -511,6 +595,7 @@ void psx_mount_cd(int f_index, int s_index, const char *filename) { printf("Unmount CD\n"); unload_cue(&toc); + unload_chd(&toc); mount_cd(0, s_index); } }