diff --git a/menu.cpp b/menu.cpp index 90c115e..20605ce 100644 --- a/menu.cpp +++ b/menu.cpp @@ -1700,20 +1700,6 @@ void HandleUI(void) user_io_file_mount(SelectedPath, ioctl_index); } - if (is_neogeo_core()) - { - // ElectronAsh. - strcpy(SelectedPath + strlen(SelectedPath) - 3, "CUE"); - printf("Checking for presence of CUE file %s\n", SelectedPath); - if (user_io_file_mount(SelectedPath, 2)) - { - printf("CUE file found and mounted.\n"); - parse_cue_file(); - char str[2] = ""; - neogeo_romset_tx(str); - } - } - menustate = SelectedPath[0] ? MENU_NONE1 : MENU_8BIT_MAIN1; recent_update(SelectedDir, SelectedPath, SelectedLabel, ioctl_index + 500); diff --git a/user_io.cpp b/user_io.cpp index 7f24e91..d1bddef 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -12,7 +12,6 @@ #include #include "lib/lodepng/lodepng.h" -#include "md5.h" #include "hardware.h" #include "osd.h" @@ -75,63 +74,6 @@ static bool scrl_status = 0; static uint16_t sdram_cfg = 0; -typedef struct -{ - bool track_active; - bool pregap_present; - uint8_t pre_m; // Actual "PREGAP". - uint8_t pre_s; - uint8_t pre_f; - bool ind0_present; - uint8_t ind0_m; // "Pregap" INDEX 00 - uint8_t ind0_s; - uint8_t ind0_f; - uint8_t ind1_m; // "Track Start" INDEX 01 - uint8_t ind1_s; - uint8_t ind1_f; - uint8_t type; // 0==AUDIO. 4==DATA. - int bytes_per_sec; -} cd_track_t; - -// Track 1-99, so entry zero is unused / ignored. -cd_track_t cd_trackinfo[100]; - -uint8_t cd_first_track; -uint8_t cd_last_track; - -static inline uint32_t msf_to_lba(uint8_t m, uint8_t s, uint8_t f) -{ - return (m*60*75) + (s*75) + f; -} - -uint32_t dec_2_bcd(uint32_t a) -{ - uint32_t result = 0; - int shift = 0; - - while (a != 0) - { - result |= (a % 10) << shift; - a /= 10; - shift += 4; - } - return result; -} - -uint32_t bcd_2_dec(uint32_t a) -{ - uint32_t result = 0; - uint32_t scale = 1; - - while (a != 0) - { - result += (a & 0x0f) * scale; - a >>= 4; - scale *= 10; - } - return result; -} - static char last_filename[1024] = {}; void user_io_store_filename(char *filename) { @@ -173,11 +115,6 @@ unsigned char user_io_core_type() return core_type; } -char is_sharpmz() -{ - return(core_type == CORE_TYPE_SHARPMZ); -} - char* user_io_create_config_name() { static char str[40]; @@ -313,6 +250,11 @@ char is_gba_core() return (is_gba_type == 1); } +char is_sharpmz() +{ + return(core_type == CORE_TYPE_SHARPMZ); +} + static int is_no_type = 0; static int disable_osd = 0; char has_menu() @@ -2103,225 +2045,6 @@ static int coldreset_req = 0; static uint32_t res_timer = 0; -uint8_t cd_lba_to_track(uint32_t req_lba) { - uint8_t track=1; - for (track=1; track<=cd_last_track; track++) { - uint32_t toc_lba = msf_to_lba(cd_trackinfo[track].ind1_m, cd_trackinfo[track].ind1_s, cd_trackinfo[track].ind1_f); // Convert track MSF to LBA. - //printf("TOC Track LBA: %08d\n", toc_lba); - if (req_lba > toc_lba) continue; // See if the TOC LBA is > the requested LBA. - else break; - } - return track-1; // The start LBA of the PREVIOUS track checked was lower than our requested LBA. -} - -int cue_pt = 0; -char cue_getch() -{ - static uint8_t buf[512]; - if (!(cue_pt & 0x1ff)) FileReadSec(&sd_image[2], buf); - if (cue_pt >= sd_image[2].size) return 0; - return buf[(cue_pt++) & 0x1ff]; -} - -char cue_readline(char *buffer) -{ - char my_char = 0; - bool ret = 0; - int char_count = 0; - - for (int i=0; i<1024; i++) { - ret = ( my_char = cue_getch() ); - if (my_char!=0x20) { // Ditch the spaces. - buffer[char_count] = my_char; - if (ret==0 || my_char==0x0A) { - buffer[char_count+1] = 0x00; // Null terminator. - break; - } - else char_count++; - } - } - return ret; -} - -void parse_cue_file(void) -{ - int i_num, i_min, i_sec, i_frame, bytes_per_sec = 0; - - // Clear the trackinfo before starting. - for (int i=0;i<=99;i++) - { - cd_trackinfo[i].track_active = 0; - cd_trackinfo[i].pregap_present = 0; - cd_trackinfo[i].pre_m = 0; - cd_trackinfo[i].pre_s = 0; - cd_trackinfo[i].pre_f = 0; - cd_trackinfo[i].ind0_present = 0; - cd_trackinfo[i].ind0_m = 0; - cd_trackinfo[i].ind0_s = 0; - cd_trackinfo[i].ind0_f = 0; - cd_trackinfo[i].ind1_m = 0; - cd_trackinfo[i].ind1_s = 0; - cd_trackinfo[i].ind1_f = 0; - cd_trackinfo[i].type = 0; - cd_trackinfo[i].bytes_per_sec = 0; - } - - size_t i_tracks = 0; - char str[1024]; - char type[5]; - - cue_pt = 0; // Set cue file index to zero. - - int track_num = 0; - bool first_track_done = 0; - - // Note: strncmp==0 means a MATCH! Because reasons. - - while( i_tracks < 99 ) - { - if ( !cue_readline(str) ) break; // Read in a whole line from the CUE file (until the end of the file). - - if ( strncmp(str, "TRACK", 5)==0 ) { // Is this a track? - sscanf( str, "%*5s%2u%5s%*1s%4u", &track_num, type, &bytes_per_sec); - if (!first_track_done) { - first_track_done = 1; - cd_first_track = track_num; - } - } - - if ( strncmp(str, "PREGAP", 6)==0 ) - { - sscanf( str, "%*6s%2u:%2u:%2u", &i_min, &i_sec, &i_frame ); - cd_trackinfo[track_num].pregap_present = 1; - cd_trackinfo[track_num].pre_m = i_min; - cd_trackinfo[track_num].pre_s = i_sec; - cd_trackinfo[track_num].pre_f = i_frame; - } - - if ( strncmp(str, "INDEX", 5)==0 ) // Is this an Index? - { - sscanf( str, "%*5s%2u%2u:%2u:%2u", &i_num, &i_min, &i_sec, &i_frame ); - - cd_trackinfo[track_num].track_active = 1; - if ( strcmp(type, "AUDIO")==0 ) { - cd_trackinfo[track_num].type = 0; - bytes_per_sec = 2352; // Audio tracks assume 2352 bytes per sector, so it's not listed in the CUE file. - } - else if ( strcmp(type, "MODE1")==0 ) { - cd_trackinfo[track_num].type = 4; - } - cd_trackinfo[track_num].bytes_per_sec = bytes_per_sec; - - /* - if (i_num==0) { // "Pregap" index, sort of. - printf("Track:%02d Pregap:%d M:%02d S:%02d F:%02d Type:%s TOCtype:%d BPS:%04d\n", track_num, cd_trackinfo[track_num].pregap_present, i_min, i_sec, i_frame, type, cd_trackinfo[track_num].type, bytes_per_sec); - cd_trackinfo[track_num].ind0_m = i_min; - cd_trackinfo[track_num].ind0_s = i_sec; - cd_trackinfo[track_num].ind0_f = i_frame; - } - */ - - if (i_num==1) { // "Track Start" index. - printf("Track:%02d Pregap:%d M:%02d S:%02d F:%02d Type:%s TOCtype:%d BPS:%04d\n", track_num, cd_trackinfo[track_num].pregap_present, i_min, i_sec, i_frame, type, cd_trackinfo[track_num].type, bytes_per_sec); - cd_trackinfo[track_num].ind1_m = i_min; - cd_trackinfo[track_num].ind1_s = i_sec; - cd_trackinfo[track_num].ind1_f = i_frame; - } - } - i_tracks++; - } - cd_last_track = track_num; -} - -void cd_generate_toc(uint16_t req_type, uint8_t *buffer) -{ - uint8_t m,s,f; - uint32_t lba; - - switch ( (req_type&0xFF00)>>8 ) { - case 0xD0: { // Request First Track and Last Track (BCD). - //buffer[0] = 0x01; // Rondo - First track (BCD). - //buffer[1] = 0x22; // Rondo - Last track (BCD). - buffer[0] = dec_2_bcd( cd_first_track ); - buffer[1] = dec_2_bcd( cd_last_track ); - buffer[2] = 0x00; // Padding. - buffer[3] = 0x00; // Padding. - printf("Core requesting CD TOC0. First Track:%02X. Last Track:%02X (BCD)\n", buffer[0], buffer[1]); - }; break; - - case 0xD1: { // Request Total Disk Size (MSF, in BCD). - //buffer[0] = 0x49; // Rondo - Minutes = 0x49 (73). - //buffer[1] = 0x09; // Rondo - Seconds = 0x09 (9). - //buffer[2] = 0x12; // Rondo - Frames = 0x12 (18). - - // ADD the PREGAP (if present). - /* - if (buffer[3]==4 && cd_trackinfo[track].pregap_present) { - m = cd_trackinfo[cd_last_track].ind1_m + cd_trackinfo[cd_last_track].pre_m; - s = cd_trackinfo[cd_last_track].ind1_s + cd_trackinfo[cd_last_track].pre_s; - f = cd_trackinfo[cd_last_track].ind1_f + cd_trackinfo[cd_last_track].pre_f; - // Not sure if audio tracks need the 2-second lead-in offset added? ElectronAsh. - uint32_t lba = msf_to_lba(m, s, f); // Convert to LBA, so we can add the 2-second lead-in. - //lba += 2*75; // Standard lead-in is 2 seconds (75 sectors per second, so 150). - // Convert back from LBA to MSF... - m = lba / (60 * 75); - lba -= m * (60 * 75); - s = lba / 75; - f = lba % 75; - - buffer[0] = dec_2_bcd( m ); - buffer[1] = dec_2_bcd( s ); - buffer[2] = dec_2_bcd( f ); - } - else - {*/ - buffer[0] = dec_2_bcd( cd_trackinfo[cd_last_track].ind1_m ); - buffer[1] = dec_2_bcd( cd_trackinfo[cd_last_track].ind1_s ); - buffer[2] = dec_2_bcd( cd_trackinfo[cd_last_track].ind1_f ); - //} - buffer[3] = 0x00; // Padding. - - printf("Core requesting CD TOC1. Total Disk Size:M:%02X S:%02X F:%02X (BCD)\n", buffer[0], buffer[1], buffer[2]); - }; break; - - case 0xD2: { // Request Track Info (Start MSF in BCD, and track type). - uint8_t track = bcd_2_dec(req_type&0xFF); // Track number from req_type upper byte is in BCD! - - // If a DATA track, check for a pregap, and ADD it (if present). - if (cd_trackinfo[track].type==4 && cd_trackinfo[track].pregap_present) { - m = cd_trackinfo[track].ind1_m + cd_trackinfo[track].pre_m; - s = cd_trackinfo[track].ind1_s + cd_trackinfo[track].pre_s; - f = cd_trackinfo[track].ind1_f + cd_trackinfo[track].pre_f; - - lba = msf_to_lba(m, s, f); // Convert to LBA, so we can add the 2-second lead-in. - lba += 2*75; // Standard lead-in is 2 seconds (75 sectors per second, so 150). - - // Convert back from LBA to MSF... - m = lba / (60 * 75); - lba -= m * (60 * 75); - s = lba / 75; - f = lba % 75; - - buffer[0] = dec_2_bcd( m ); - buffer[1] = dec_2_bcd( s ); - buffer[2] = dec_2_bcd( f ); - } - else - { - buffer[0] = dec_2_bcd( cd_trackinfo[track].ind1_m ); - buffer[1] = dec_2_bcd( cd_trackinfo[track].ind1_s ); - buffer[2] = dec_2_bcd( cd_trackinfo[track].ind1_f ); - } - buffer[3] = cd_trackinfo[track].type; - - printf("Core requesting CD TOC2. Track:%02d. M:%02X S:%02X F:%02X (BCD). Type:", track, buffer[0], buffer[1], buffer[2]); - if (buffer[3]==0x00) printf("AUDIO\n"); - else if (buffer[3]==0x04) printf("DATA\n"); - else printf("UNKNOWN!\n"); - }; break; - } -} - void user_io_poll() { if ((core_type != CORE_TYPE_MIST) && @@ -2563,8 +2286,7 @@ void user_io_poll() if (!done) buffer_lba[disk] = -1; } } - else - if (c & 0x0701) + else if (c & 0x0701) { int disk = 3; if (c & 0x0001) disk = 0; @@ -2574,182 +2296,13 @@ void user_io_poll() //printf("SD RD %d on %d, WIDE=%d\n", lba, disk, fio_size); int done = 0; - if (disk && is_neogeo_core()) - { - uint32_t offset = 0; + if (buffer_lba[disk] != lba) + { if (sd_image[disk].size) { diskled_on(); - printf("req_type: 0x%04X ", req_type); - switch ((req_type & 0xFF00) >> 8) - { - case 0xD0:case 0xD1:case 0xD2: - { - cd_generate_toc(req_type, buffer[disk]); - done = 1; - }; - break; - - case 0x48: - { - // Added this, Neo CD always requests by MSF (furrtek) - if ((req_type & 0xFF) == 0x01) - { - printf("Neo CD requested raw lba value (MSF): 0x%08X\n", lba); - uint8_t m = bcd_2_dec((lba & 0xFF0000) >> 16); - uint8_t s = bcd_2_dec((lba & 0xFF00) >> 8); - uint8_t f = bcd_2_dec((lba & 0xFF) >> 0); - lba = msf_to_lba(m, s, f); - lba -= (2 * 75); // Remove 2 second pregap - } - - uint8_t track = cd_lba_to_track(lba); - uint16_t bps = cd_trackinfo[track].bytes_per_sec; - uint32_t pregap = 0; - - if (cd_trackinfo[track].pregap_present) - { - pregap = msf_to_lba(cd_trackinfo[track].pre_m, cd_trackinfo[track].pre_s, cd_trackinfo[track].pre_f); - } - - if (bps == 2352) offset = 16 + ((lba - pregap) * 2352); // Rondo etc. - else if (bps == 2048) offset = ((lba - pregap) * 2048); // Homebrew, etc. - else printf("Data track %02d has unhandled bytes-per-sec of %d !\n", track, bps); - - if (FileSeek(&sd_image[disk], offset, SEEK_SET)) - { - if (FileReadAdv(&sd_image[disk], buffer[disk], 2048)) done = 1; - } - printf("Core requesting 2048-byte CD sector, from LBA: 0x%08X TRACK: %02d BPS: %04d OFFSET: 0x%08X \n", lba, track, bps, offset); - }; - break; - - case 0x52: - { - switch (req_type & 0xFF) - { - // "lba" holds the LBA. Dun do nothing. (no conversion needed). - case 0x00: - break; - - // "lba" holds the MSF (BCD). Convert to LBA. - case 0x01: - { - uint8_t m = bcd_2_dec((lba & 0xFF0000) >> 16); - uint8_t s = bcd_2_dec((lba & 0xFF00) >> 8); - uint8_t f = bcd_2_dec((lba & 0xFF) >> 0); - lba = msf_to_lba(m, s, f); - }; - break; - - // "lba" holds the TRACK number (BCD?). Grab the track start MSF from the TOC, then convert to LBA. - case 0x02: - { - uint8_t track = bcd_2_dec(lba); - lba = msf_to_lba(cd_trackinfo[track].ind1_m, cd_trackinfo[track].ind1_s, cd_trackinfo[track].ind1_f); - }; - break; - } - - uint8_t track = cd_lba_to_track(lba); - - if (cd_trackinfo[track].type != 0x00) - { - printf("Error: Core is trying to play back non-audio track as CDDA!\n"); - memset(buffer[disk], 0, sizeof(buffer[disk])); - } - else - { - if (FileSeek(&sd_image[disk], (lba - 525) * 2352, SEEK_SET)) - { - if (FileReadAdv(&sd_image[disk], buffer[disk], 2352)) done = 1; - } - } - printf("Core requesting a raw 2352-byte CD sector, from LBA: 0x%08X TRACK: %02d\n", lba, track); - }; - break; - - default: - { - if (FileSeekLBA(&sd_image[disk], lba)) - { - if (FileReadSec(&sd_image[disk], buffer[disk])) done = 1; - } - printf("Core requesting a 512-byte SD / VHD sector, from LBA: 0x%08X\n", lba); - }; - break; - } - } - - //Even after error we have to provide the block to the core - //Give an empty block. - if (!done) memset(buffer[disk], 0, sizeof(buffer[disk])); - buffer_lba[disk] = lba; - - spi_uio_cmd_cont(UIO_SECTOR_RD); - if ((req_type & 0xF000) == 0xD000) spi_write(buffer[disk], 4, fio_size); // TOC. (4 bytes, including padding). - else if ((req_type & 0xFF00) == 0x4800) spi_write(buffer[disk], 2048, fio_size); // 2048-byte CD sector. - else if ((req_type & 0xFF00) == 0x5200) spi_write(buffer[disk], 2352, fio_size); // 2352-byte CD sector. - else spi_write(buffer[disk], 512, fio_size); // Standard 512-byte SD / VHD sector. - DisableIO(); - } - else - { - if (buffer_lba[disk] != lba) - { - if (sd_image[disk].size) - { - diskled_on(); - if (FileSeekLBA(&sd_image[disk], lba)) - { - if (FileReadSec(&sd_image[disk], buffer[disk])) - { - done = 1; - } - } - } - - //Even after error we have to provide the block to the core - //Give an empty block. - if (!done) - { - if (sd_image[disk].type == 2) - { - if (is_megacd_core()) - { - mcd_fill_blanksave(buffer[disk], lba); - } - else - { - memset(buffer[disk], -1, sizeof(buffer[disk])); - } - } - else - { - memset(buffer[disk], 0, sizeof(buffer[disk])); - } - } - buffer_lba[disk] = lba; - } - - if (buffer_lba[disk] == lba) - { - //hexdump(buffer, 32, 0); - - // data is now stored in buffer. send it to fpga - spi_uio_cmd_cont(UIO_SECTOR_RD); - spi_block_write(buffer[disk], fio_size); - DisableIO(); - } - - // just load the next sector now, so it may be prefetched - // for the next request already - done = 0; - if (sd_image[disk].size) - { - diskled_on(); - if (FileSeekLBA(&sd_image[disk], lba + 1)) + if (FileSeekLBA(&sd_image[disk], lba)) { if (FileReadSec(&sd_image[disk], buffer[disk])) { @@ -2757,12 +2310,59 @@ void user_io_poll() } } } - if (done) buffer_lba[disk] = lba + 1; - if (sd_image[disk].type == 2) + //Even after error we have to provide the block to the core + //Give an empty block. + if (!done) { - buffer_lba[disk] = -1; + if (sd_image[disk].type == 2) + { + if (is_megacd_core()) + { + mcd_fill_blanksave(buffer[disk], lba); + } + else + { + memset(buffer[disk], -1, sizeof(buffer[disk])); + } + } + else + { + memset(buffer[disk], 0, sizeof(buffer[disk])); + } } + buffer_lba[disk] = lba; + } + + if (buffer_lba[disk] == lba) + { + //hexdump(buffer, 32, 0); + + // data is now stored in buffer. send it to fpga + spi_uio_cmd_cont(UIO_SECTOR_RD); + spi_block_write(buffer[disk], fio_size); + DisableIO(); + } + + // just load the next sector now, so it may be prefetched + // for the next request already + done = 0; + if (sd_image[disk].size) + { + diskled_on(); + if (FileSeekLBA(&sd_image[disk], lba + 1)) + { + if (FileReadSec(&sd_image[disk], buffer[disk])) + { + done = 1; + } + } + } + if (done) buffer_lba[disk] = lba + 1; + + if (sd_image[disk].type == 2) + { + buffer_lba[disk] = -1; } } } diff --git a/user_io.h b/user_io.h index ed7726a..20227ee 100644 --- a/user_io.h +++ b/user_io.h @@ -277,8 +277,6 @@ void diskled_on(); #define DISKLED_ON diskled_on() #define DISKLED_OFF void() -void parse_cue_file(void); - char is_minimig(); char is_sharpmz(); char is_menu_core();