From dd586f890fe329527023a4e1bff326502e5e3288 Mon Sep 17 00:00:00 2001 From: sorgelig Date: Mon, 4 May 2020 00:04:41 +0800 Subject: [PATCH] pcecd: calculate seek time. --- MiSTer.vcxproj | 1 + MiSTer.vcxproj.filters | 3 + support/pcecd/pcecdd.cpp | 21 ++++--- support/pcecd/seektime.cpp | 123 +++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 8 deletions(-) create mode 100644 support/pcecd/seektime.cpp diff --git a/MiSTer.vcxproj b/MiSTer.vcxproj index 9f7bdbc..cc5bd23 100644 --- a/MiSTer.vcxproj +++ b/MiSTer.vcxproj @@ -88,6 +88,7 @@ + diff --git a/MiSTer.vcxproj.filters b/MiSTer.vcxproj.filters index 3a031d7..eede0d6 100644 --- a/MiSTer.vcxproj.filters +++ b/MiSTer.vcxproj.filters @@ -190,6 +190,9 @@ Source Files\support + + Source Files\support + diff --git a/support/pcecd/pcecdd.cpp b/support/pcecd/pcecdd.cpp index b376c8d..9b11c08 100644 --- a/support/pcecd/pcecdd.cpp +++ b/support/pcecd/pcecdd.cpp @@ -11,6 +11,8 @@ #define PCECD_DATA_IO_INDEX 2 +float get_cd_seek_ms(int start_sector, int target_sector); + pcecdd_t pcecdd; pcecdd_t::pcecdd_t() { @@ -304,7 +306,6 @@ void pcecdd_t::Reset() { void pcecdd_t::Update() { if (this->state == PCECD_STATE_READ) { - DISKLED_ON; if (this->latency > 0) { this->latency--; @@ -322,8 +323,7 @@ void pcecdd_t::Update() { this->can_read_next = false; - //if (this->toc.sub) mcd_sub_send(); - + DISKLED_ON; if (this->toc.tracks[this->index].type) { // CD-ROM (Mode 1) @@ -374,7 +374,6 @@ void pcecdd_t::Update() { } else if (this->state == PCECD_STATE_PLAY) { - DISKLED_ON; if (this->latency > 0) { this->latency--; @@ -390,6 +389,7 @@ void pcecdd_t::Update() { if (this->toc.tracks[this->index].type) return; + DISKLED_ON; FileSeek(&this->toc.tracks[index].f, (this->lba * 2352) - this->toc.tracks[index].offset, SEEK_SET); sec_buf[0] = 0x30; @@ -512,9 +512,6 @@ void pcecdd_t::CommandExec() { new_lba = ((comm[1] << 16) | (comm[2] << 8) | comm[3]) & 0x1FFFFF; int cnt_ = comm[4]; - this->lba = new_lba; - this->cnt = cnt_; - int index = GetTrackByLBA(new_lba, &this->toc); this->index = index; @@ -523,6 +520,12 @@ void pcecdd_t::CommandExec() { new_lba = this->toc.tracks[index].start; } + this->latency = (int)(get_cd_seek_ms(this->lba, new_lba)/13.33); + printf("seek time ticks: %d\n", this->latency); + + this->lba = new_lba; + this->cnt = cnt_; + if (this->toc.tracks[index].f.opened()) { int offset = (new_lba * this->toc.tracks[index].sector_size) - this->toc.tracks[index].offset; @@ -577,6 +580,8 @@ void pcecdd_t::CommandExec() { break; } + this->latency = (int)(get_cd_seek_ms(this->lba, new_lba) / 13.33); + printf("seek time ticks: %d\n", this->latency); this->lba = new_lba; int index = GetTrackByLBA(new_lba, &this->toc); @@ -658,7 +663,7 @@ void pcecdd_t::CommandExec() { case PCECD_COMM_READSUBQ: { int lba_rel = this->lba - this->toc.tracks[this->index].start; - + buf[0] = 0x0A; buf[1] = 0 | 0x80; buf[2] = this->state == PCECD_STATE_PAUSE ? 2 : (PCECD_STATE_PLAY ? 0 : 3); diff --git a/support/pcecd/seektime.cpp b/support/pcecd/seektime.cpp new file mode 100644 index 0000000..afe7e4f --- /dev/null +++ b/support/pcecd/seektime.cpp @@ -0,0 +1,123 @@ +/* + ============================================================================ + Name : seektime.c + Author : Dave Shadoff + Version : + Copyright : (C) 2018 Dave Shadoff + Description : Program to determine seek time, based on start and end sector numbers + ============================================================================ + */ + +#include +#include +#include + + +typedef struct sector_group { + int sec_per_revolution; + int sec_start; + int sec_end; + float rotation_ms; + float rotation_vsync; +} sector_group; + +#define NUM_SECTOR_GROUPS 14 + +sector_group sector_list[NUM_SECTOR_GROUPS] = { + { 10, 0, 12572, 133.47, 8.00 }, + { 11, 12573, 30244, 146.82, 8.81 }, // Except for the first and last groups, + { 12, 30245, 49523, 160.17, 9.61 }, // there are 1606.5 tracks in each range + { 13, 49524, 70408, 173.51, 10.41 }, + { 14, 70409, 92900, 186.86, 11.21 }, + { 15, 92901, 116998, 200.21, 12.01 }, + { 16, 116999, 142703, 213.56, 12.81 }, + { 17, 142704, 170014, 226.90, 13.61 }, + { 18, 170015, 198932, 240.25, 14.42 }, + { 19, 198933, 229456, 253.60, 15.22 }, + { 20, 229457, 261587, 266.95, 16.02 }, + { 21, 261588, 295324, 280.29, 16.82 }, + { 22, 295325, 330668, 293.64, 17.62 }, + { 23, 330669, 333012, 306.99, 18.42 } +}; + + +static int find_group(int sector_num) +{ + int i; + int group_index = 0; + + for (i = 0; i < NUM_SECTOR_GROUPS; i++) + { + if ((sector_num >= sector_list[i].sec_start) && (sector_num <= sector_list[i].sec_end)) + { + group_index = i; + break; + } + } + return group_index; +} + +float get_cd_seek_ms(int start_sector, int target_sector) +{ + int start_index; + int target_index; + + float track_difference; + float milliseconds = 0; + + // First, we identify which group the start and end are in + start_index = find_group(start_sector); + target_index = find_group(target_sector); + + // Now we find the track difference + // + // Note: except for the first and last sector groups, all groups are 1606.48 tracks per group. + // + if (target_index == start_index) + { + track_difference = (float)(abs(target_sector - start_sector) / sector_list[target_index].sec_per_revolution); + } + else if (target_index > start_index) + { + track_difference = (sector_list[start_index].sec_end - start_sector) / sector_list[start_index].sec_per_revolution; + track_difference += (target_sector - sector_list[target_index].sec_start) / sector_list[target_index].sec_per_revolution; + track_difference += (1606.48 * (target_index - start_index - 1)); + } + else // start_index > target_index + { + track_difference = (start_sector - sector_list[start_index].sec_start) / sector_list[start_index].sec_per_revolution; + track_difference += (sector_list[target_index].sec_end - target_sector) / sector_list[target_index].sec_per_revolution; + track_difference += (1606.48 * (start_index - target_index - 1)); + } + + // Now, we use the algorithm to determine how long to wait + if (abs(target_sector - start_sector) < 2) + { + milliseconds = (3 * 1000 / 60); + } + if (abs(target_sector - start_sector) < 5) + { + milliseconds = (9 * 1000 / 60) + (float)(sector_list[target_index].rotation_ms / 2); + } + else if (track_difference <= 80) + { + milliseconds = (16 * 1000 / 60) + (float)(sector_list[target_index].rotation_ms / 2); + } + else if (track_difference <= 160) + { + milliseconds = (22 * 1000 / 60) + (float)(sector_list[target_index].rotation_ms / 2); + } + else if (track_difference <= 644) + { + milliseconds = (22 * 1000 / 60) + (float)(sector_list[target_index].rotation_ms / 2) + (float)((track_difference - 161) * 16.66 / 80); + } + else + { + milliseconds = (36 * 1000 / 60) + (float)((track_difference - 644) * 16.66 / 195); + } + + printf("From sector %d to sector %d:\n", start_sector, target_sector); + printf("Time = %.2f milliseconds\n", milliseconds); + + return milliseconds; +}