savestates works

git-svn-id: file:///home/notaz/opt/svn/PicoDrive@26 be3aeb3a-fb24-0410-a615-afba39da0efa
This commit is contained in:
notaz 2007-01-29 23:39:15 +00:00
parent 51a902ae25
commit 7573607016
16 changed files with 219 additions and 161 deletions

View file

@ -22,9 +22,10 @@ struct PicoArea { void *data; int len; char *name; };
// taking an address of fread or fwrite causes "application could't be started" error
// on startup randomly depending on binary layout of executable file.
arearw *areaRead = (arearw *) 0; // fread; // read and write function pointers for
arearw *areaWrite = (arearw *) 0; // fwrite; // gzip save state ability
areaeof *areaEof = (areaeof *) 0;
arearw *areaRead = (arearw *) 0; // fread; // read and write function pointers for
arearw *areaWrite = (arearw *) 0; // fwrite; // gzip save state ability
areaeof *areaEof = (areaeof *) 0;
areaseek *areaSeek = (areaseek *) 0;
// Scan one variable and callback
@ -161,7 +162,7 @@ int PmovState(int PmovAction, void *PmovFile)
int minimum=0;
unsigned char head[32];
// testing
if (PicoMCD & 1)
{
if (PmovAction&1) return PicoCdSaveState(PmovFile);
if (PmovAction&2) return PicoCdLoadState(PmovFile);

View file

@ -19,9 +19,10 @@
extern "C" {
#endif
// external
int mp3_get_bitrate(FILE *f, int size);
// external funcs for Sega/Mega CD
int mp3_get_bitrate(FILE *f, int size);
void mp3_start_play(FILE *f, int pos);
int mp3_get_offset(void); // 0-1023
// Pico.c
@ -47,11 +48,13 @@ int PicoFrameMCD(void);
// Area.c
typedef size_t (arearw)(void *p, size_t _size, size_t _n, void *file);
typedef size_t (areaeof)(void *file);
typedef int (areaseek)(void *file, long offset, int whence);
// Save or load the state from PmovFile:
int PmovState(int PmovAction, void *PmovFile); // &1=for reading &2=for writing &4=volatile &8=non-volatile
extern arearw *areaRead; // external read and write function pointers for
extern arearw *areaWrite; // gzip save state ability
extern areaeof *areaEof;
extern areaseek *areaSeek;
// Cart.c
int PicoCartLoad(FILE *f,unsigned char **prom,unsigned int *psize);

View file

@ -171,7 +171,10 @@ struct mcd_misc
unsigned char s68k_pend_ints;
unsigned int state_flags; // emu state: reset_pending,
unsigned int counter75hz;
unsigned short audio_offset; // for savestates: play pointer offset (0-1023)
unsigned char audio_track; // playing audio track # (zero based)
char pad1;
int pad[12];
};
typedef struct
@ -184,6 +187,7 @@ typedef struct
unsigned char word_ram[0x40000]; // 256K
unsigned char bram[0x2000]; // 8K
unsigned char s68k_regs[0x200];
_scd_toc TOC; // not to be saved
CDD cdd;
CDC cdc;
_scd scd;

View file

@ -20,14 +20,24 @@ typedef enum {
CHUNK_RAM,
CHUNK_VRAM,
CHUNK_ZRAM,
CHUNK_CRAM,
CHUNK_CRAM, // 5
CHUNK_VSRAM,
CHUNK_MISC,
CHUNK_VIDEO,
CHUNK_Z80,
CHUNK_PSG,
CHUNK_PSG, // 10
CHUNK_FM,
// CD stuff
CHUNK_S68K,
CHUNK_PRG_RAM,
CHUNK_WORD_RAM,
CHUNK_BRAM, // 15
CHUNK_GA_REGS,
CHUNK_CDC,
CHUNK_CDD,
CHUNK_SCD,
CHUNK_RC, // 20
CHUNK_MISC_CD,
} chunk_name_e;
@ -77,25 +87,44 @@ int PicoCdSaveState(void *file)
CHECKED_WRITE(CHUNK_FM, 0x200+4, ym2612_regs);
// TODO: cd stuff
if (PicoMCD & 1)
{
Pico_mcd->m.audio_offset = mp3_get_offset();
memset(buff, 0, sizeof(buff));
PicoAreaPackCpu(buff, 1);
CHECKED_WRITE_BUFF(CHUNK_S68K, buff);
CHECKED_WRITE_BUFF(CHUNK_PRG_RAM, Pico_mcd->prg_ram);
CHECKED_WRITE_BUFF(CHUNK_WORD_RAM, Pico_mcd->word_ram); // in 2M format
CHECKED_WRITE_BUFF(CHUNK_BRAM, Pico_mcd->bram);
CHECKED_WRITE_BUFF(CHUNK_GA_REGS, Pico_mcd->s68k_regs);
CHECKED_WRITE_BUFF(CHUNK_CDD, Pico_mcd->cdd);
CHECKED_WRITE_BUFF(CHUNK_CDC, Pico_mcd->cdc);
CHECKED_WRITE_BUFF(CHUNK_SCD, Pico_mcd->scd);
CHECKED_WRITE_BUFF(CHUNK_RC, Pico_mcd->rot_comp);
CHECKED_WRITE_BUFF(CHUNK_MISC_CD, Pico_mcd->m);
}
return 0;
}
static int g_read_offs = 0;
#define CHECKED_READ(len,data) \
if (areaRead(data, 1, len, file) != len) { \
g_read_offs += len; \
printf("areaRead: premature EOF\n"); \
return 0; \
}
#define R_ERROR_RETURN(error) \
{ \
printf("PicoCdLoadState @ %x: " error "\n", g_read_offs); \
return 1; \
}
// when is eof really set?
#define CHECKED_READ(len,data) \
if (areaRead(data, 1, len, file) != len) { \
if (len == 1 && areaEof(file)) return 0; \
R_ERROR_RETURN("areaRead: premature EOF\n"); \
return 1; \
} \
g_read_offs += len;
#define CHECKED_READ2(len2,data) \
if (len2 != len) R_ERROR_RETURN("unexpected len, wanted " #len2); \
CHECKED_READ(len2, data)
@ -117,7 +146,7 @@ int PicoCdLoadState(void *file)
{
CHECKED_READ(1, buff);
CHECKED_READ(4, &len);
if (len < 0 || len > 1024*256) R_ERROR_RETURN("bad length");
if (len < 0 || len > 1024*512) R_ERROR_RETURN("bad length");
switch (buff[0])
{
@ -143,6 +172,31 @@ int PicoCdLoadState(void *file)
CHECKED_READ2(0x200+4, ym2612_regs);
YM2612PicoStateLoad();
break;
// cd stuff
case CHUNK_S68K:
CHECKED_READ_BUFF(buff);
PicoAreaUnpackCpu(buff, 1);
break;
case CHUNK_PRG_RAM: CHECKED_READ_BUFF(Pico_mcd->prg_ram); break;
case CHUNK_WORD_RAM: CHECKED_READ_BUFF(Pico_mcd->word_ram); break;
case CHUNK_BRAM: CHECKED_READ_BUFF(Pico_mcd->bram); break;
case CHUNK_GA_REGS: CHECKED_READ_BUFF(Pico_mcd->s68k_regs); break;
case CHUNK_CDD: CHECKED_READ_BUFF(Pico_mcd->cdd); break;
case CHUNK_CDC: CHECKED_READ_BUFF(Pico_mcd->cdc); break;
case CHUNK_SCD: CHECKED_READ_BUFF(Pico_mcd->scd); break;
case CHUNK_RC: CHECKED_READ_BUFF(Pico_mcd->rot_comp); break;
case CHUNK_MISC_CD:
CHECKED_READ_BUFF(Pico_mcd->m);
mp3_start_play(Pico_mcd->TOC.Tracks[Pico_mcd->m.audio_track].F, Pico_mcd->m.audio_offset);
break;
default:
printf("skipping unknown chunk %i of size %i\n", buff[0], len);
areaSeek(file, len, SEEK_CUR);
break;
}
}

View file

@ -53,7 +53,7 @@ static void CDC_Reset(void)
Pico_mcd->cdc.IFCTRL = 0;
Pico_mcd->cdc.CTRL.N = 0;
Pico_mcd->cdd.CDC_Decode_Reg_Read = 0;
Pico_mcd->cdc.Decode_Reg_Read = 0;
Pico_mcd->scd.Status_CDC &= ~0x08;
}
@ -257,7 +257,7 @@ unsigned char CDC_Read_Reg(void)
case 0x1: // IFSTAT
cdprintf("CDC read reg 01 = %.2X", Pico_mcd->cdc.IFSTAT);
Pico_mcd->cdd.CDC_Decode_Reg_Read |= (1 << 1); // Reg 1 (decoding)
Pico_mcd->cdc.Decode_Reg_Read |= (1 << 1); // Reg 1 (decoding)
Pico_mcd->s68k_regs[5] = 0x2;
return Pico_mcd->cdc.IFSTAT;
@ -276,42 +276,42 @@ unsigned char CDC_Read_Reg(void)
case 0x4: // HEAD0
cdprintf("CDC read reg 04 = %.2X", Pico_mcd->cdc.HEAD.B.B0);
Pico_mcd->cdd.CDC_Decode_Reg_Read |= (1 << 4); // Reg 4 (decoding)
Pico_mcd->cdc.Decode_Reg_Read |= (1 << 4); // Reg 4 (decoding)
Pico_mcd->s68k_regs[5] = 0x5;
return Pico_mcd->cdc.HEAD.B.B0;
case 0x5: // HEAD1
cdprintf("CDC read reg 05 = %.2X", Pico_mcd->cdc.HEAD.B.B1);
Pico_mcd->cdd.CDC_Decode_Reg_Read |= (1 << 5); // Reg 5 (decoding)
Pico_mcd->cdc.Decode_Reg_Read |= (1 << 5); // Reg 5 (decoding)
Pico_mcd->s68k_regs[5] = 0x6;
return Pico_mcd->cdc.HEAD.B.B1;
case 0x6: // HEAD2
cdprintf("CDC read reg 06 = %.2X", Pico_mcd->cdc.HEAD.B.B2);
Pico_mcd->cdd.CDC_Decode_Reg_Read |= (1 << 6); // Reg 6 (decoding)
Pico_mcd->cdc.Decode_Reg_Read |= (1 << 6); // Reg 6 (decoding)
Pico_mcd->s68k_regs[5] = 0x7;
return Pico_mcd->cdc.HEAD.B.B2;
case 0x7: // HEAD3
cdprintf("CDC read reg 07 = %.2X", Pico_mcd->cdc.HEAD.B.B3);
Pico_mcd->cdd.CDC_Decode_Reg_Read |= (1 << 7); // Reg 7 (decoding)
Pico_mcd->cdc.Decode_Reg_Read |= (1 << 7); // Reg 7 (decoding)
Pico_mcd->s68k_regs[5] = 0x8;
return Pico_mcd->cdc.HEAD.B.B3;
case 0x8: // PTL
cdprintf("CDC read reg 08 = %.2X", Pico_mcd->cdc.PT.B.L);
Pico_mcd->cdd.CDC_Decode_Reg_Read |= (1 << 8); // Reg 8 (decoding)
Pico_mcd->cdc.Decode_Reg_Read |= (1 << 8); // Reg 8 (decoding)
Pico_mcd->s68k_regs[5] = 0x9;
return Pico_mcd->cdc.PT.B.L;
case 0x9: // PTH
cdprintf("CDC read reg 09 = %.2X", Pico_mcd->cdc.PT.B.H);
Pico_mcd->cdd.CDC_Decode_Reg_Read |= (1 << 9); // Reg 9 (decoding)
Pico_mcd->cdc.Decode_Reg_Read |= (1 << 9); // Reg 9 (decoding)
Pico_mcd->s68k_regs[5] = 0xA;
return Pico_mcd->cdc.PT.B.H;
@ -330,21 +330,21 @@ unsigned char CDC_Read_Reg(void)
case 0xC: // STAT0
cdprintf("CDC read reg 12 = %.2X", Pico_mcd->cdc.STAT.B.B0);
Pico_mcd->cdd.CDC_Decode_Reg_Read |= (1 << 12); // Reg 12 (decoding)
Pico_mcd->cdc.Decode_Reg_Read |= (1 << 12); // Reg 12 (decoding)
Pico_mcd->s68k_regs[5] = 0xD;
return Pico_mcd->cdc.STAT.B.B0;
case 0xD: // STAT1
cdprintf("CDC read reg 13 = %.2X", Pico_mcd->cdc.STAT.B.B1);
Pico_mcd->cdd.CDC_Decode_Reg_Read |= (1 << 13); // Reg 13 (decoding)
Pico_mcd->cdc.Decode_Reg_Read |= (1 << 13); // Reg 13 (decoding)
Pico_mcd->s68k_regs[5] = 0xE;
return Pico_mcd->cdc.STAT.B.B1;
case 0xE: // STAT2
cdprintf("CDC read reg 14 = %.2X", Pico_mcd->cdc.STAT.B.B2);
Pico_mcd->cdd.CDC_Decode_Reg_Read |= (1 << 14); // Reg 14 (decoding)
Pico_mcd->cdc.Decode_Reg_Read |= (1 << 14); // Reg 14 (decoding)
Pico_mcd->s68k_regs[5] = 0xF;
return Pico_mcd->cdc.STAT.B.B2;
@ -355,7 +355,7 @@ unsigned char CDC_Read_Reg(void)
Pico_mcd->cdc.IFSTAT |= 0x20; // decoding interrupt flag cleared
if ((Pico_mcd->cdc.CTRL.B.B0 & 0x80) && (Pico_mcd->cdc.IFCTRL & 0x20))
{
if ((Pico_mcd->cdd.CDC_Decode_Reg_Read & 0x73F2) == 0x73F2)
if ((Pico_mcd->cdc.Decode_Reg_Read & 0x73F2) == 0x73F2)
Pico_mcd->cdc.STAT.B.B3 = 0x80;
}
return ret;

View file

@ -88,7 +88,7 @@ typedef struct
} B;
unsigned int N;
} CTRL;
unsigned int CDC_Decode_Reg_Read;
unsigned int Decode_Reg_Read;
} CDC;
typedef struct

View file

@ -29,8 +29,6 @@ typedef unsigned int u32;
// -----------------------------------------------------------------
// extern m68ki_cpu_core m68ki_cpu;
static u32 m68k_reg_read16(u32 a)
{

View file

@ -7,19 +7,6 @@
//#define cdprintf(x...)
#define DEBUG_CD
// TODO: check refs, move 2 context
struct _file_track Tracks[100];
char Track_Played;
int FILE_Init(void)
{
// MP3_Init(); // TODO
Unload_ISO();
return 0;
}
void FILE_End(void)
{
@ -31,7 +18,7 @@ int Load_ISO(const char *iso_name, int is_bin)
{
struct stat file_stat;
int i, j, num_track, Cur_LBA, index, ret, iso_name_len;
_scd_track *SCD_TOC_Tracks = Pico_mcd->scd.TOC.Tracks;
_scd_track *Tracks = Pico_mcd->TOC.Tracks;
FILE *tmp_file;
char tmp_name[1024], tmp_ext[10];
static char *exts[] = {
@ -44,42 +31,36 @@ int Load_ISO(const char *iso_name, int is_bin)
Unload_ISO();
Tracks[0].Type = is_bin ? TYPE_BIN : TYPE_ISO;
Tracks[0].ftype = is_bin ? TYPE_BIN : TYPE_ISO;
ret = stat(iso_name, &file_stat);
if (ret != 0) return -1;
Tracks[0].Length = file_stat.st_size;
if (Tracks[0].Type == TYPE_ISO) Tracks[0].Length >>= 11; // size in sectors
if (Tracks[0].ftype == TYPE_ISO) Tracks[0].Length >>= 11; // size in sectors
else Tracks[0].Length /= 2352; // size in sectors
Tracks[0].F = fopen(iso_name, "rb");
if (Tracks[0].F == NULL)
{
Tracks[0].Type = 0;
Tracks[0].ftype = 0;
Tracks[0].Length = 0;
return -1;
}
if (Tracks[0].Type == TYPE_ISO) fseek(Tracks[0].F, 0x100, SEEK_SET);
if (Tracks[0].ftype == TYPE_ISO) fseek(Tracks[0].F, 0x100, SEEK_SET);
else fseek(Tracks[0].F, 0x110, SEEK_SET);
// fread(buf, 1, 0x200, Tracks[0].F);
fseek(Tracks[0].F, 0, SEEK_SET);
Pico_mcd->scd.TOC.First_Track = 1;
Tracks[0].MSF.M = 0; // minutes
Tracks[0].MSF.S = 2; // seconds
Tracks[0].MSF.F = 0; // frames
SCD_TOC_Tracks[0].Num = 1;
SCD_TOC_Tracks[0].Type = 1; // DATA
SCD_TOC_Tracks[0].MSF.M = 0; // minutes
SCD_TOC_Tracks[0].MSF.S = 2; // seconds
SCD_TOC_Tracks[0].MSF.F = 0; // frames
cdprintf("Track 0 - %02d:%02d:%02d %s", SCD_TOC_Tracks[0].MSF.M, SCD_TOC_Tracks[0].MSF.S, SCD_TOC_Tracks[0].MSF.F,
SCD_TOC_Tracks[0].Type ? "DATA" : "AUDIO");
cdprintf("Track 0 - %02d:%02d:%02d DATA", Tracks[0].MSF.M, Tracks[0].MSF.S, Tracks[0].MSF.F);
Cur_LBA = Tracks[0].Length; // Size in sectors
@ -109,7 +90,7 @@ int Load_ISO(const char *iso_name, int is_bin)
{
// float fs;
int fs;
index = num_track - Pico_mcd->scd.TOC.First_Track;
index = num_track - 1;
ret = stat(tmp_name, &file_stat);
fs = file_stat.st_size; // used to calculate lenght
@ -125,21 +106,17 @@ int Load_ISO(const char *iso_name, int is_bin)
Tracks[index].F = tmp_file;
SCD_TOC_Tracks[index].Num = num_track;
SCD_TOC_Tracks[index].Type = 0; // AUDIO
LBA_to_MSF(Cur_LBA, &(SCD_TOC_Tracks[index].MSF));
LBA_to_MSF(Cur_LBA, &Tracks[index].MSF);
// MP3 File
Tracks[index].Type = TYPE_MP3;
Tracks[index].ftype = TYPE_MP3;
fs *= 75;
fs /= Tracks[index].KBtps * 1000;
Tracks[index].Length = fs;
Cur_LBA += Tracks[index].Length;
cdprintf("Track %i: %s - %02d:%02d:%02d len=%i %s", index, tmp_name, SCD_TOC_Tracks[index].MSF.M,
SCD_TOC_Tracks[index].MSF.S, SCD_TOC_Tracks[index].MSF.F, fs,
SCD_TOC_Tracks[index].Type ? "DATA" : "AUDIO");
cdprintf("Track %i: %s - %02d:%02d:%02d len=%i AUDIO", index, tmp_name, Tracks[index].MSF.M,
Tracks[index].MSF.S, Tracks[index].MSF.F, fs);
num_track++;
break;
@ -147,16 +124,14 @@ int Load_ISO(const char *iso_name, int is_bin)
}
}
Pico_mcd->scd.TOC.Last_Track = num_track - 1;
Pico_mcd->TOC.Last_Track = num_track - 1;
index = num_track - Pico_mcd->scd.TOC.First_Track;
SCD_TOC_Tracks[index].Num = num_track;
SCD_TOC_Tracks[index].Type = 0;
index = num_track - 1;
LBA_to_MSF(Cur_LBA, &(SCD_TOC_Tracks[index].MSF));
LBA_to_MSF(Cur_LBA, &Tracks[index].MSF);
cdprintf("End CD - %02d:%02d:%02d\n\n", SCD_TOC_Tracks[index].MSF.M,
SCD_TOC_Tracks[index].MSF.S, SCD_TOC_Tracks[index].MSF.F);
cdprintf("End CD - %02d:%02d:%02d\n\n", Tracks[index].MSF.M,
Tracks[index].MSF.S, Tracks[index].MSF.F);
return 0;
}
@ -166,36 +141,39 @@ void Unload_ISO(void)
{
int i;
Track_Played = 99;
if (Pico_mcd == NULL) return;
for(i = 0; i < 100; i++)
{
if (Tracks[i].F) fclose(Tracks[i].F);
Tracks[i].F = NULL;
Tracks[i].Length = 0;
Tracks[i].Type = 0;
if (Pico_mcd->TOC.Tracks[i].F) fclose(Pico_mcd->TOC.Tracks[i].F);
Pico_mcd->TOC.Tracks[i].F = NULL;
Pico_mcd->TOC.Tracks[i].Length = 0;
Pico_mcd->TOC.Tracks[i].ftype = 0;
}
}
int FILE_Read_One_LBA_CDC(void)
{
int where_read;
static char cp_buf[2560];
int where_read = 0;
// static char cp_buf[2560];
if (Pico_mcd->s68k_regs[0x36] & 1) // DATA
{
if (Tracks[0].F == NULL) return -1;
if (Pico_mcd->TOC.Tracks[0].F == NULL) return -1;
if (Pico_mcd->scd.Cur_LBA < 0) where_read = 0;
else if (Pico_mcd->scd.Cur_LBA >= Tracks[0].Length) where_read = Tracks[0].Length - 1;
if (Pico_mcd->scd.Cur_LBA < 0)
where_read = 0;
else if (Pico_mcd->scd.Cur_LBA >= Pico_mcd->TOC.Tracks[0].Length)
where_read = Pico_mcd->TOC.Tracks[0].Length - 1;
else where_read = Pico_mcd->scd.Cur_LBA;
if (Tracks[0].Type == TYPE_ISO) where_read <<= 11;
if (Pico_mcd->TOC.Tracks[0].ftype == TYPE_ISO) where_read <<= 11;
else where_read = (where_read * 2352 + 16);
fseek(Tracks[0].F, where_read, SEEK_SET);
fread(cp_buf, 1, 2048, Tracks[0].F);
// moved below..
//fseek(Pico_mcd->TOC.Tracks[0].F, where_read, SEEK_SET);
//fread(cp_buf, 1, 2048, Pico_mcd->TOC.Tracks[0].F);
cdprintf("Read file CDC 1 data sector :\n");
}
@ -203,7 +181,7 @@ int FILE_Read_One_LBA_CDC(void)
{
// int rate, channel;
if (Tracks[Pico_mcd->scd.Cur_Track - Pico_mcd->scd.TOC.First_Track].Type == TYPE_MP3)
if (Pico_mcd->TOC.Tracks[Pico_mcd->scd.Cur_Track - 1].ftype == TYPE_MP3)
{
// TODO
// MP3_Update(cp_buf, &rate, &channel, 0);
@ -230,8 +208,11 @@ int FILE_Read_One_LBA_CDC(void)
Pico_mcd->cdc.WA.N = (Pico_mcd->cdc.WA.N + 2352) & 0x7FFF; // add one sector to WA
Pico_mcd->cdc.PT.N = (Pico_mcd->cdc.PT.N + 2352) & 0x7FFF;
memcpy(&Pico_mcd->cdc.Buffer[Pico_mcd->cdc.PT.N + 4], cp_buf, 2048);
memcpy(&Pico_mcd->cdc.Buffer[Pico_mcd->cdc.PT.N], &Pico_mcd->cdc.HEAD, 4);
//memcpy(&Pico_mcd->cdc.Buffer[Pico_mcd->cdc.PT.N + 4], cp_buf, 2048);
fseek(Pico_mcd->TOC.Tracks[0].F, where_read, SEEK_SET);
fread(Pico_mcd->cdc.Buffer + Pico_mcd->cdc.PT.N + 4, 1, 2048, Pico_mcd->TOC.Tracks[0].F);
#ifdef DEBUG_CD
cdprintf("Read -> WA = %d Buffer[%d] =", Pico_mcd->cdc.WA.N, Pico_mcd->cdc.PT.N & 0x3FFF);
@ -262,7 +243,7 @@ int FILE_Read_One_LBA_CDC(void)
{
// CAUTION : lookahead bit not implemented
memcpy(&Pico_mcd->cdc.Buffer[Pico_mcd->cdc.PT.N], cp_buf, 2352);
//memcpy(&Pico_mcd->cdc.Buffer[Pico_mcd->cdc.PT.N], cp_buf, 2352);
}
}
}
@ -291,8 +272,8 @@ int FILE_Read_One_LBA_CDC(void)
SekInterruptS68k(5);
}
Pico_mcd->cdc.IFSTAT &= ~0x20; // DEC interrupt happen
CDC_Decode_Reg_Read = 0; // Reset read after DEC int
Pico_mcd->cdc.IFSTAT &= ~0x20; // DEC interrupt happen
Pico_mcd->cdc.Decode_Reg_Read = 0; // Reset read after DEC int
}
}
@ -303,24 +284,25 @@ int FILE_Read_One_LBA_CDC(void)
int FILE_Play_CD_LBA(void)
{
int index = Pico_mcd->scd.Cur_Track - Pico_mcd->scd.TOC.First_Track;
int index = Pico_mcd->scd.Cur_Track - 1;
Pico_mcd->m.audio_track = index;
cdprintf("Play FILE Comp");
cdprintf("Play track #%i", Pico_mcd->scd.Cur_Track);
if (Tracks[index].F == NULL)
if (Pico_mcd->TOC.Tracks[index].F == NULL)
{
return 1;
}
if (Tracks[index].Type == TYPE_MP3)
if (Pico_mcd->TOC.Tracks[index].ftype == TYPE_MP3)
{
int pos1000 = 0;
int pos1024 = 0;
int Track_LBA_Pos = Pico_mcd->scd.Cur_LBA - Track_to_LBA(Pico_mcd->scd.Cur_Track);
if (Track_LBA_Pos < 0) Track_LBA_Pos = 0;
if (Track_LBA_Pos)
pos1000 = Track_LBA_Pos * 1024 / Tracks[index].Length;
pos1024 = Track_LBA_Pos * 1024 / Pico_mcd->TOC.Tracks[index].Length;
mp3_start_play(Tracks[index].F, pos1000);
mp3_start_play(Pico_mcd->TOC.Tracks[index].F, pos1024);
}
else
{

View file

@ -1,8 +1,6 @@
#ifndef _CD_FILE_H
#define _CD_FILE_H
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -13,18 +11,7 @@ extern "C" {
//#define TYPE_WAV 4
struct _file_track {
FILE *F;
int Length;
short Type; // can be char
short KBtps; // bytes per sec for mp3s (bitrate / 8)
};
extern struct _file_track Tracks[100];
extern char Track_Played;
int FILE_Init(void);
void FILE_End(void);
int Load_ISO(const char *iso_name, int is_bin);
void Unload_ISO(void);

View file

@ -101,19 +101,19 @@ static unsigned int MSF_to_Track(_msf *MSF)
Start = (MSF->M << 16) + (MSF->S << 8) + MSF->F;
for(i = Pico_mcd->scd.TOC.First_Track; i <= (Pico_mcd->scd.TOC.Last_Track + 1); i++)
for(i = 1; i <= (Pico_mcd->TOC.Last_Track + 1); i++)
{
Cur = Pico_mcd->scd.TOC.Tracks[i - Pico_mcd->scd.TOC.First_Track].MSF.M << 16;
Cur += Pico_mcd->scd.TOC.Tracks[i - Pico_mcd->scd.TOC.First_Track].MSF.S << 8;
Cur += Pico_mcd->scd.TOC.Tracks[i - Pico_mcd->scd.TOC.First_Track].MSF.F;
Cur = Pico_mcd->TOC.Tracks[i - 1].MSF.M << 16;
Cur += Pico_mcd->TOC.Tracks[i - 1].MSF.S << 8;
Cur += Pico_mcd->TOC.Tracks[i - 1].MSF.F;
if (Cur > Start) break;
}
--i;
if (i > Pico_mcd->scd.TOC.Last_Track) return 100;
if (i < Pico_mcd->scd.TOC.First_Track) i = Pico_mcd->scd.TOC.First_Track;
if (i > Pico_mcd->TOC.Last_Track) return 100;
else if (i < 1) i = 1;
return (unsigned) i;
}
@ -130,12 +130,12 @@ static unsigned int LBA_to_Track(int lba)
static void Track_to_MSF(int track, _msf *MSF)
{
if (track < Pico_mcd->scd.TOC.First_Track) track = Pico_mcd->scd.TOC.First_Track;
else if (track > Pico_mcd->scd.TOC.Last_Track) track = Pico_mcd->scd.TOC.Last_Track;
if (track < 1) track = 1;
else if (track > Pico_mcd->TOC.Last_Track) track = Pico_mcd->TOC.Last_Track;
MSF->M = Pico_mcd->scd.TOC.Tracks[track - Pico_mcd->scd.TOC.First_Track].MSF.M;
MSF->S = Pico_mcd->scd.TOC.Tracks[track - Pico_mcd->scd.TOC.First_Track].MSF.S;
MSF->F = Pico_mcd->scd.TOC.Tracks[track - Pico_mcd->scd.TOC.First_Track].MSF.F;
MSF->M = Pico_mcd->TOC.Tracks[track - 1].MSF.M;
MSF->S = Pico_mcd->TOC.Tracks[track - 1].MSF.S;
MSF->F = Pico_mcd->TOC.Tracks[track - 1].MSF.F;
}
@ -168,7 +168,7 @@ void Check_CD_Command(void)
cdprintf("Got a read command");
// DATA ?
if (Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.Cur_Track - Pico_mcd->scd.TOC.First_Track].Type)
if (Pico_mcd->scd.Cur_Track == 1)
Pico_mcd->s68k_regs[0x36] |= 0x01;
else Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO
@ -196,8 +196,6 @@ void Check_CD_Command(void)
int Init_CD_Driver(void)
{
FILE_Init();
return 0;
}
@ -400,17 +398,11 @@ int Get_Total_Lenght_CDD_c23(void)
// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.TOC.Last_Track -
Pico_mcd->scd.TOC.First_Track + 1].MSF.M);
Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.TOC.Last_Track -
Pico_mcd->scd.TOC.First_Track + 1].MSF.S);
Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.TOC.Last_Track -
Pico_mcd->scd.TOC.First_Track + 1].MSF.F);
Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.M);
Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.S);
Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->TOC.Tracks[Pico_mcd->TOC.Last_Track].MSF.F);
Pico_mcd->cdd.Ext = 0;
// FIXME: remove
//Pico_mcd->cdd.Seconde = 2;
Pico_mcd->scd.CDD_Complete = 1;
return 0;
@ -429,14 +421,11 @@ int Get_First_Last_Track_CDD_c24(void)
// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.TOC.First_Track);
Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->scd.TOC.Last_Track);
Pico_mcd->cdd.Minute = INT_TO_BCDW(1);
Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Last_Track);
Pico_mcd->cdd.Frame = 0;
Pico_mcd->cdd.Ext = 0;
// FIXME: remove
//Pico_mcd->cdd.Minute = Pico_mcd->cdd.Seconde = 1;
Pico_mcd->scd.CDD_Complete = 1;
return 0;
@ -462,15 +451,15 @@ int Get_Track_Adr_CDD_c25(void)
// else if (!(CDC.CTRL.B.B0 & 0x80)) Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
Pico_mcd->cdd.Status |= Pico_mcd->scd.Status_CDD;
if (track_number > Pico_mcd->scd.TOC.Last_Track) track_number = Pico_mcd->scd.TOC.Last_Track;
else if (track_number < Pico_mcd->scd.TOC.First_Track) track_number = Pico_mcd->scd.TOC.First_Track;
if (track_number > Pico_mcd->TOC.Last_Track) track_number = Pico_mcd->TOC.Last_Track;
else if (track_number < 1) track_number = 1;
Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->scd.TOC.Tracks[track_number - Pico_mcd->scd.TOC.First_Track].MSF.M);
Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->scd.TOC.Tracks[track_number - Pico_mcd->scd.TOC.First_Track].MSF.S);
Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->scd.TOC.Tracks[track_number - Pico_mcd->scd.TOC.First_Track].MSF.F);
Pico_mcd->cdd.Minute = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.M);
Pico_mcd->cdd.Seconde = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.S);
Pico_mcd->cdd.Frame = INT_TO_BCDW(Pico_mcd->TOC.Tracks[track_number - 1].MSF.F);
Pico_mcd->cdd.Ext = track_number % 10;
if (Pico_mcd->scd.TOC.Tracks[track_number - Pico_mcd->scd.TOC.First_Track].Type) Pico_mcd->cdd.Frame |= 0x0800;
if (track_number == 1) Pico_mcd->cdd.Frame |= 0x0800; // data track
Pico_mcd->scd.CDD_Complete = 1;
return 0;
@ -511,7 +500,7 @@ int Play_CDD_c3(void)
if (Pico_mcd->scd.File_Add_Delay == 0) Pico_mcd->scd.File_Add_Delay = delay;
if (Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.Cur_Track - Pico_mcd->scd.TOC.First_Track].Type)
if (Pico_mcd->scd.Cur_Track == 1)
{
Pico_mcd->s68k_regs[0x36] |= 0x01; // DATA
}
@ -558,7 +547,7 @@ int Seek_CDD_c4(void)
Pico_mcd->cdd.Status = 0x0200;
// DATA ?
if (Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.Cur_Track - Pico_mcd->scd.TOC.First_Track].Type)
if (Pico_mcd->scd.Cur_Track == 1)
Pico_mcd->s68k_regs[0x36] |= 0x01;
else Pico_mcd->s68k_regs[0x36] &= ~0x01; // AUDIO
@ -614,7 +603,7 @@ int Resume_CDD_c7(void)
Pico_mcd->scd.Status_CDD = PLAYING;
Pico_mcd->cdd.Status = 0x0102;
if (Pico_mcd->scd.TOC.Tracks[Pico_mcd->scd.Cur_Track - Pico_mcd->scd.TOC.First_Track].Type)
if (Pico_mcd->scd.Cur_Track == 1)
{
Pico_mcd->s68k_regs[0x36] |= 0x01; // DATA
}

View file

@ -1,6 +1,10 @@
#ifndef _CD_SYS_H
#define _CD_SYS_H
#include "cd_file.h"
#include <stdio.h> // FILE
#ifdef __cplusplus
extern "C" {
#endif
@ -28,26 +32,32 @@ typedef struct
typedef struct
{
unsigned char Type;
unsigned char Num;
// unsigned char Type; // always 1 (data) for 1st track, 0 (audio) for others
// unsigned char Num; // unused
_msf MSF;
//
char ftype; // TYPE_ISO, TYPE_BIN, TYPE_MP3
FILE *F;
int Length;
short KBtps; // kbytes per sec for mp3s (bitrate / 1000 / 8)
short pad;
} _scd_track;
typedef struct
{
unsigned char First_Track;
unsigned char Last_Track;
// unsigned char First_Track; // always 1
_scd_track Tracks[100];
unsigned int Last_Track;
} _scd_toc;
typedef struct {
unsigned int Status_CDD;
unsigned int Status_CDC;
_scd_toc TOC;
int Cur_LBA;
unsigned int Cur_Track;
int File_Add_Delay;
char CDD_Complete;
int pad[6];
} _scd;

View file

@ -5,7 +5,7 @@
#define rot_comp Pico_mcd->rot_comp
static int Table_Rot_Time[] =
static const int Table_Rot_Time[] =
{
0x00054000, 0x00048000, 0x00040000, 0x00036000, //; 008-032 ; briefing - sprite
0x0002E000, 0x00028000, 0x00024000, 0x00022000, //; 036-064 ; arbre souvent

View file

@ -28,6 +28,8 @@ typedef struct
unsigned int YD;
unsigned int XD_Mul;
unsigned int H_Dot;
int pad[2];
} Rot_Comp;