mirror of https://github.com/inolen/redream.git
fix gdrom GET_TOC response
This commit is contained in:
parent
dc698f8d67
commit
9d0ce3700a
|
@ -67,6 +67,24 @@ static int cdi_read_sector(struct disc *disc, int fad, enum gd_secfmt fmt,
|
|||
return res;
|
||||
}
|
||||
|
||||
static void cdi_get_toc(struct disc *disc, enum gd_area area,
|
||||
struct track **first_track, struct track **last_track,
|
||||
int *leadin_fad, int *leadout_fad) {
|
||||
struct cdi *cdi = (struct cdi *)disc;
|
||||
|
||||
/* cdi's have no high-density area */
|
||||
CHECK_EQ(area, AREA_SINGLE);
|
||||
|
||||
/* the toc on cdi's represents all tracks / sessions */
|
||||
struct session *first_session = &cdi->sessions[0];
|
||||
struct session *last_session = &cdi->sessions[cdi->num_sessions - 1];
|
||||
|
||||
*first_track = &cdi->tracks[0];
|
||||
*last_track = &cdi->tracks[cdi->num_tracks - 1];
|
||||
*leadin_fad = first_session->leadin_fad;
|
||||
*leadout_fad = last_session->leadout_fad;
|
||||
}
|
||||
|
||||
static struct track *cdi_get_track(struct disc *disc, int n) {
|
||||
struct cdi *cdi = (struct cdi *)disc;
|
||||
CHECK_LT(n, cdi->num_tracks);
|
||||
|
@ -183,19 +201,21 @@ static int cdi_parse_track(struct disc *disc, uint32_t version,
|
|||
}
|
||||
|
||||
int sector_size = cdi_sector_sizes[sector_type];
|
||||
enum gd_secfmt sector_fmt = cdi_sector_formats[mode];
|
||||
int data_offset = *track_offset + pregap_length * sector_size;
|
||||
|
||||
track->fad = pregap_length + lba;
|
||||
track->adr = 0; /* no subq channel mode info */
|
||||
track->ctrl = 4; /* data track */
|
||||
track->adr = 0;
|
||||
track->ctrl = sector_fmt == SECTOR_CDDA ? 0 : 4;
|
||||
track->sector_size = sector_size;
|
||||
track->sector_fmt = cdi_sector_formats[mode];
|
||||
track->file_offset = *track_offset + pregap_length * sector_size -
|
||||
track->fad * track->sector_size;
|
||||
track->file_offset = data_offset - track->fad * track->sector_size;
|
||||
|
||||
LOG_INFO("cdi_parse_track track=%d fad=%d mode=%s/%d", track->num, track->fad,
|
||||
cdi_modes[mode], track->sector_size);
|
||||
LOG_INFO("cdi_parse_track track=%d fad=%d off=%d mode=%s/%d", track->num,
|
||||
track->fad, data_offset, cdi_modes[mode], track->sector_size);
|
||||
|
||||
*track_offset += total_length * sector_size;
|
||||
*leadout_fad = track->fad + total_length;
|
||||
*leadout_fad = track->fad + track_length;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -341,6 +361,7 @@ struct disc *cdi_create(const char *filename) {
|
|||
cdi->get_session = &cdi_get_session;
|
||||
cdi->get_num_tracks = &cdi_get_num_tracks;
|
||||
cdi->get_track = &cdi_get_track;
|
||||
cdi->get_toc = &cdi_get_toc;
|
||||
cdi->read_sector = &cdi_read_sector;
|
||||
|
||||
struct disc *disc = (struct disc *)cdi;
|
||||
|
|
|
@ -33,6 +33,12 @@ int disc_read_sector(struct disc *disc, int fad, enum gd_secfmt fmt,
|
|||
return disc->read_sector(disc, fad, fmt, mask, dst);
|
||||
}
|
||||
|
||||
void disc_get_toc(struct disc *disc, enum gd_area area,
|
||||
struct track **first_track, struct track **last_track,
|
||||
int *leadin_fad, int *leadout_fad) {
|
||||
disc->get_toc(disc, area, first_track, last_track, leadin_fad, leadout_fad);
|
||||
}
|
||||
|
||||
struct track *disc_get_track(struct disc *disc, int n) {
|
||||
return disc->get_track(disc, n);
|
||||
}
|
||||
|
|
|
@ -43,11 +43,17 @@ struct disc_meta {
|
|||
|
||||
struct disc {
|
||||
void (*destroy)(struct disc *);
|
||||
|
||||
int (*get_format)(struct disc *);
|
||||
|
||||
int (*get_num_sessions)(struct disc *);
|
||||
struct session *(*get_session)(struct disc *, int);
|
||||
|
||||
int (*get_num_tracks)(struct disc *);
|
||||
struct track *(*get_track)(struct disc *, int);
|
||||
|
||||
void (*get_toc)(struct disc *, enum gd_area, struct track **, struct track **,
|
||||
int *, int *);
|
||||
int (*read_sector)(struct disc *, int, enum gd_secfmt, enum gd_secmask,
|
||||
void *);
|
||||
};
|
||||
|
@ -61,6 +67,9 @@ int disc_get_num_sessions(struct disc *disc);
|
|||
struct session *disc_get_session(struct disc *disc, int n);
|
||||
int disc_get_num_tracks(struct disc *disc);
|
||||
struct track *disc_get_track(struct disc *disc, int n);
|
||||
void disc_get_toc(struct disc *disc, enum gd_area area,
|
||||
struct track **first_track, struct track **last_track,
|
||||
int *leadin_fad, int *leadout_fad);
|
||||
int disc_read_sector(struct disc *disc, int fad, enum gd_secfmt fmt,
|
||||
enum gd_secmask mask, void *dst);
|
||||
struct track *disc_lookup_track(struct disc *disc, int fad);
|
||||
|
|
|
@ -43,6 +43,20 @@ static int gdi_read_sector(struct disc *disc, int fad, enum gd_secfmt fmt,
|
|||
return res;
|
||||
}
|
||||
|
||||
static void gdi_get_toc(struct disc *disc, enum gd_area area,
|
||||
struct track **first_track, struct track **last_track,
|
||||
int *leadin_fad, int *leadout_fad) {
|
||||
struct gdi *gdi = (struct gdi *)disc;
|
||||
|
||||
/* gdi's have one toc per area, and there is one session per area */
|
||||
struct session *session = &gdi->sessions[area];
|
||||
|
||||
*first_track = &gdi->tracks[session->first_track];
|
||||
*last_track = &gdi->tracks[session->last_track];
|
||||
*leadin_fad = session->leadin_fad;
|
||||
*leadout_fad = session->leadout_fad;
|
||||
}
|
||||
|
||||
static struct track *gdi_get_track(struct disc *disc, int n) {
|
||||
struct gdi *gdi = (struct gdi *)disc;
|
||||
CHECK_LT(n, gdi->num_tracks);
|
||||
|
@ -184,6 +198,7 @@ struct disc *gdi_create(const char *filename) {
|
|||
gdi->get_session = &gdi_get_session;
|
||||
gdi->get_num_tracks = &gdi_get_num_tracks;
|
||||
gdi->get_track = &gdi_get_track;
|
||||
gdi->get_toc = &gdi_get_toc;
|
||||
gdi->read_sector = &gdi_read_sector;
|
||||
|
||||
struct disc *disc = (struct disc *)gdi;
|
||||
|
|
|
@ -616,11 +616,12 @@ void gdrom_get_toc(struct gdrom *gd, enum gd_area area, uint8_t *data,
|
|||
------------------------------------------------------
|
||||
407 | lead-out track fad (lsb) */
|
||||
|
||||
int num_sessions = disc_get_num_sessions(gd->disc);
|
||||
struct session *session = disc_get_session(gd->disc, area);
|
||||
struct session *last_session = disc_get_session(gd->disc, num_sessions - 1);
|
||||
struct track *first_track = disc_get_track(gd->disc, session->first_track);
|
||||
struct track *last_track = disc_get_track(gd->disc, session->last_track);
|
||||
struct track *first_track = NULL;
|
||||
struct track *last_track = NULL;
|
||||
int leadin_fad = 0;
|
||||
int leadout_fad = 0;
|
||||
disc_get_toc(gd->disc, area, &first_track, &last_track, &leadin_fad,
|
||||
&leadout_fad);
|
||||
|
||||
/* 0xffffffff represents an invalid track */
|
||||
memset(data, 0xff, SPI_TOC_SIZE);
|
||||
|
@ -630,15 +631,15 @@ void gdrom_get_toc(struct gdrom *gd, enum gd_area area, uint8_t *data,
|
|||
|
||||
for (int i = first_track->num; i <= last_track->num; i++) {
|
||||
struct track *track = disc_get_track(gd->disc, i - 1);
|
||||
*(entry++) = (bswap24(track->fad) << 8) | (track->ctrl << 4) | track->adr;
|
||||
entry[i - 1] = (bswap24(track->fad) << 8) | (track->ctrl << 4) | track->adr;
|
||||
}
|
||||
|
||||
/* write out first, last and lead-out track */
|
||||
*(entry++) =
|
||||
entry[99] =
|
||||
(first_track->num << 8) | (first_track->ctrl << 4) | first_track->adr;
|
||||
*(entry++) =
|
||||
entry[100] =
|
||||
(last_track->num << 8) | (last_track->ctrl << 4) | last_track->adr;
|
||||
*(entry++) = (bswap24(last_session->leadout_fad) << 8);
|
||||
entry[101] = (bswap24(leadout_fad) << 8);
|
||||
}
|
||||
|
||||
void gdrom_get_error(struct gdrom *gd, uint8_t *data, int size) {
|
||||
|
@ -947,13 +948,13 @@ REG_W32(holly_cb, GD_DRVSEL) {
|
|||
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);
|
||||
LOG_GDROM("read GD_STATUS 0x%x", value);
|
||||
holly_clear_interrupt(gd->holly, HOLLY_INT_G1GDINT);
|
||||
return value;
|
||||
}
|
||||
|
||||
REG_W32(holly_cb, GD_STATUS_COMMAND) {
|
||||
struct gdrom *gd = dc->gdrom;
|
||||
LOG_GDROM("write GD_STATUS_COMMAND 0x%x", value);
|
||||
LOG_GDROM("write GD_COMMAND 0x%x", value);
|
||||
gdrom_event(gd, EVENT_ATA_CMD, value);
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ TEST(sh4_x64) {
|
|||
0, 0, 0, \
|
||||
0, \
|
||||
{{0}, {0}}, \
|
||||
0, 0, \
|
||||
0, 0, 0, \
|
||||
{0}, \
|
||||
}
|
||||
#define TEST_SH4(name, buffer, buffer_size, buffer_offset, \
|
||||
|
|
Loading…
Reference in New Issue