home *** CD-ROM | disk | FTP | other *** search
- /*
- cdrom.c by BERO
- modified by LDChen
- info from psx.rules.org / doomed@c64.org
- */
-
- #include "fpse.h"
-
- #define RAMADDR(addr) ((void*)&ram[(addr)&0x1fffff])
-
- #define CACHE_ENABLE 1
- #define CACHE_SIZE 256
- #define CACHE_PRE_READ 16
- #define CACHE_SLOT_SIZE (2048+512) // easy calculation
-
- #define INT2BCD(a) ((a/10)*16+(a%10))
- #define BCD2INT(a) ((a>>4)*10+(a&0xf))
-
- #define CON_OUTPUT 0
-
- enum {
- CdlSync, CdlNop, CdlSetloc, CdlPlay, // 00-03 ; 00-03
- CdlForward, CdlBackword, CdlReadN, CdlStandby, // 04-07 ; 04-07
- CdlStop, CdlPause, CdlInit, CdlMute, // 08-11 ; 08-0B
- CdlDemute, CdlSetfilter, CdlSetmode, CdlGetparam, // 12-15 ; 0C-0F
- CdlGetlocL, CdlGetlocP, Cdl18, CdlGetTN, // 16-19 ; 10-13
- CdlGetTD, CdlSeekL, CdlSeekP, Cdl23, // 20-23 ; 14-17
- Cdl24, CdlTest, CdlCheckID, CdlReadS, // 24-27 ; 18-1B
- CdlReset, Cdl29, CdlReadTOC // 28-30 ; 1C-1E
- };
-
- enum {
- ModeSpeed = 0x80, /* 0: normal speed 1: double speed */
- ModeRT = 0x40, /* 0: ADPCM off 1: ADPCM on */
- ModeSize1 = 0x20, /* 0: 2048 byte 1: 2340 byte */
- ModeSize0 = 0x10, /* 0: - 1: 2328 byte */
- ModeSF = 0x08, /* 0: Channel off 1: Channel on */
- ModeRept = 0x04, /* 0: Report off 1: Report on */
- ModeAP = 0x02, /* 0: AutoPause off 1: AutoPause on */
- ModeDA = 0x01 /* 0: CD-DA off 1: CD-DA on */
- };
-
- enum {
- StatPlay = 0x80, /* playing CD-DA */
- StatSeek = 0x40, /* seeking */
- StatRead = 0x20, /* reading data frames */
- StatShellOpen = 0x10, /* once shell open */
- StatSeekError = 0x04, /* seek error detected */
- StatStandby = 0x02, /* spindle motor rotating */
- StatError = 0x01 /* command error detected */
- };
-
- enum {
- NoIntr = 0x00, /* No interrupt */
- DataReady = 0x01, /* Data Ready */
- Acknowledge = 0x02, /* Acknowledge */
- Complete = 0x03, /* Command Complete */
- DataEnd = 0x04, /* End of Data Detected */
- DiskError = 0x05 /* Error Detected */
- };
-
- typedef struct {
- UINT8 minute;
- UINT8 second;
- UINT8 frame;
- UINT8 pad;
- } CDLoc;
-
- static struct {
- // Registers
- UINT8 stat;
- UINT8 ctrl;
- UINT8 mode;
- UINT8 Status;
-
- // Param
- UINT8 param[8];
- int paramptr;
-
- // Result
- UINT8 result[8];
- int resultptr;
- int resultsize;
- int resultready;
-
- // CDR Locations
- CDLoc Loc;
- CDLoc SeekLoc;
-
- // Async Related
- UINT8 NextStat;
- UINT8 DmaReady;
- UINT8 Reset;
- UINT8 AsyncCause;
- UINT32 NextSize;
- UINT8 NextParam[8];
-
- // Buffers
- UINT8 *SectorBuf;
- UINT32 SectorSize;
- UINT8 LastReadInfo[8];
-
- UINT8 file;
- UINT8 chan;
- UINT8 moderead;
- UINT8 storedmoderead;
- int retries;
- } cd;
-
- #ifdef MSB_FIRST
- #define MAKEID(a,b,c,d) ( d + (c << 8) + (b << 16) + (a << 24) )
- #else
- #define MAKEID(a,b,c,d) ( a + (b << 8) + (c << 16) + (d << 24) )
- #endif
-
- // PSX_COUNTRY == USE_EUROPE_PSX
- static UINT8 EU_Cmd25P22[8]={ 0x66,0x6F,0x72,0x20,0x55,0x2F,0x43,0x00 }; // "for U/C"
- static UINT8 EU_Cmd25P23[8]={ 0x43,0x58,0x44,0x32,0x35,0x34,0x35,0x51 }; // "CXD2545Q"
- static UINT8 EU_Cmd25P24[8]={ 0x43,0x58,0x44,0x32,0x35,0x34,0x35,0x51 }; // "CXD2545Q"
- static UINT8 EU_Cmd25P25[8]={ 0x43,0x58,0x44,0x31,0x38,0x31,0x35,0x51 }; // "CXD1815Q"
- static UINT8 EU_SCEx[6] = { 0x09, 0xA9, 0x3D, 0x2B, 0xA5, 0x74 }; // SCEE European
- static UINT32 EU_SCExID = MAKEID('S','C','E','E');
-
- // PSX_COUNTRY == USE_AMERICAN_PSX
- static UINT8 US_Cmd25P22[8]={ 0x66,0x6F,0x72,0x20,0x55,0x53,0x2F,0x41 }; // "for US/A"
- static UINT8 US_Cmd25P23[8]={ 0x43,0x58,0x44,0x31,0x37,0x38,0x32,0x42 }; // "CXD1782B"
- static UINT8 US_Cmd25P24[8]={ 0x43,0x58,0x44,0x32,0x35,0x31,0x36,0x51 }; // "CXD2516Q"
- static UINT8 US_Cmd25P25[8]={ 0x43,0x58,0x44,0x31,0x31,0x39,0x39,0x42 }; // "CXD1199B"
- static UINT8 US_SCEx[6] = { 0x09, 0xA9, 0x3D, 0x2B, 0xA5, 0xF4 }; // SCEA U.S.
- static UINT32 US_SCExID = MAKEID('S','C','E','A');
-
- // PSX_COUNTRY == USE_JAPAN_PSX
- static UINT8 JP_Cmd25P22[8]={ 0x66,0x6F,0x72,0x20,0x4A,0x61,0x70,0x61 }; // "for Japa"
- static UINT8 JP_Cmd25P23[8]={ 0x43,0x58,0x44,0x32,0x35,0x34,0x35,0x51 }; // "CXD2545Q"
- static UINT8 JP_Cmd25P24[8]={ 0x43,0x58,0x44,0x32,0x35,0x34,0x35,0x51 }; // "CXD2545Q"
- static UINT8 JP_Cmd25P25[8]={ 0x43,0x58,0x44,0x31,0x38,0x31,0x35,0x51 }; // "CXD1815Q"
- static UINT8 JP_SCEx[6] = { 0x09, 0xA9, 0x3D, 0x2B, 0xA5, 0x74 }; // SCEI Japanese
- static UINT32 JP_SCExID = MAKEID('S','C','E','I');
-
- static UINT8 Cmd25P22[8];
- static UINT8 Cmd25P23[8];
- static UINT8 Cmd25P24[8];
- static UINT8 Cmd25P25[8];
- static UINT8 SCEx[6];
- static UINT32 SCExID;
-
- #if CACHE_ENABLE==0
- static UINT8 SectorBuf[CACHE_SLOT_SIZE];
- #else
- static UINT8 SectorBuf[CACHE_SLOT_SIZE*CACHE_SIZE];
- static CDLoc CacheAddress[CACHE_SIZE];
- static int CacheIdx = 0;
-
- static void init_cd_cache(void)
- {
- memset(CacheAddress,0,CACHE_SIZE*sizeof(CDLoc));
- }
-
- static UINT8 *get_cd_cache(CDLoc *loc)
- {
- int x;
- UINT8 *sect,*ret;
- CDLoc l;
-
- // Search in the cache
- for (x=0; x<CACHE_SIZE; x++)
- if (*(UINT32 *)loc == *(UINT32 *)(CacheAddress+x))
- return &SectorBuf[x*CACHE_SLOT_SIZE];
-
- // Save position for return
- ret = &SectorBuf[CacheIdx*CACHE_SLOT_SIZE];
- l = *loc;
- // Read 'CACHE_PRE_READ' sectors per time instead of one (more speed)
- for (x=0; x<CACHE_PRE_READ; x++)
- {
- CacheAddress[CacheIdx] = l; // Set active address
- sect = CD_Read((UINT8 *)&l); // read the sector
- CD_Wait(); // wait end-of-read
- memcpy(&SectorBuf[CacheIdx*CACHE_SLOT_SIZE],
- sect,2352); // copy sector in cache
-
- if (++l.frame >= 75) // Advance CD pointer
- {
- l.frame = 0;
- if (++l.second >= 60)
- {
- l.second=0;
- l.minute++;
- }
- }
-
- if (++CacheIdx >= CACHE_SIZE) CacheIdx = 0; // Go to next slot
- }
-
- return ret;
- }
- #endif
-
- #define EVENT_SETUP(n,irq,s) VSync_Register |= 0x80000000 | (1<<INT_CD); \
- Event_List[INT_CD] = n; \
- cd.NextStat = irq; cd.NextSize = s
-
- /*
- result[0]
-
- 0x80 CD-DA Play
- 0x02 working?
- */
-
- static int get_sector_size()
- {
- switch( cd.mode & 0x30 ) {
- case 0x00: return 2048;
- case 0x10: return 2328;
- case 0x20: return 2352;
- }
- return 2352;
- }
-
- static int UpdateSeekPosition()
- {
- /*
- if ((cd.mode & ModeRept) &&
- (cd.Status & StatPlay))
- {
- CD_GetSeek((UINT8*)&cd.SeekLoc);
- return 1;
- }
- */
- if (++cd.SeekLoc.frame >= 75)
- {
- cd.SeekLoc.frame = 0;
- if (++cd.SeekLoc.second >= 60)
- {
- cd.SeekLoc.second=0;
- cd.SeekLoc.minute++;
- }
- }
- return 0;
- }
-
- #if CON_OUTPUT
- static int cnt = 0;
- #endif
-
- static int cdrom_async()
- {
- #if CON_OUTPUT
- printf("ASync=%d - ctrl=%x\n",cd.AsyncCause,cd.ctrl);
- #endif
-
- /*
- if (cd.ctrl & 0x40)
- {
- if (cnt<10)
- {
- PRINTF("Forward CDIRQ\n");
- cnt++;
- VSync_Register |= 0x80000000 | (1<<INT_CD);
- Event_List[INT_CD] = 100;
- return;
- }
- cnt = 0;
- cd.ctrl &= ~0x40;
- }
- */
- if (hwarea[0x1070] && (1<<INT_CD)) // cd.stat == 1)
- {
- if (cd.retries<10)
- {
- //if (cd.NextStat != 3) {
- #if CON_OUTPUT
- PRINTF("%3d) Forward CDIRQ\n",cnt);
- cnt++;
- #endif
- //}
- cd.retries++;
- VSync_Register |= 0x80000000 | (1<<INT_CD);
- Event_List[INT_CD] = 50;
- return 0;
- }
- }
- cd.retries = 0;
-
- //cnt = 0;
- #if CON_OUTPUT
- printf("Setup CDIRQ %d\n",cd.NextStat);
- #endif
-
- if (CD_Wait() != FPSE_OK)
- {
- #if CON_OUTPUT
- printf("CDIRQ error detected\n");
- #endif
- cd.NextParam[0] |= StatError;
- cd.NextStat = DiskError;
- cd.NextSize = 1;
- cd.DmaReady = 0;
- }
-
- cd.stat = cd.NextStat;
- cd.resultsize = cd.NextSize;
- cd.resultptr = 0;
- cd.resultready = 1;
- cd.ctrl &= ~(0x80|0x40);
- cd.ctrl |= cd.DmaReady;
- cd.DmaReady = 0;
- memcpy(cd.result,cd.NextParam,8);
-
- if (cd.stat == DiskError) return 1;
-
- switch (cd.AsyncCause) {
- case 1: // Read
- #if CACHE_ENABLE==1
- if (cdusecache) cd.SectorBuf = get_cd_cache(&cd.SeekLoc);
- else
- #endif
- cd.SectorBuf = CD_Read((UINT8 *)&cd.SeekLoc);
-
- cd.SectorSize = get_sector_size();
- cd.NextParam[0] = cd.Status;
- cd.AsyncCause = 5;
- cd.DmaReady = 0x40;
- EVENT_SETUP(100,1,1);
- break;
- case 2: // Pause
- cd.AsyncCause = 0;
- cd.NextParam[0] = cd.Status;
- cd.ctrl |= 0x80; // (cd.ctrl | 0x80) & ~0x40;
- EVENT_SETUP(100,2,1);
- break;
- case 3: // Play
- cd.SectorSize = get_sector_size();
- cd.AsyncCause = 4;
- cd.NextParam[0] = 0;
- UpdateSeekPosition();
- EVENT_SETUP(400,3,1);
- break;
- case 4:
- cd.AsyncCause = 3;
-
- cd.NextParam[0] = cd.Status;
- if (cd.mode & ModeRept)
- {
- cd.NextParam[1] = 1;
- cd.NextParam[2] = 0x80;
- cd.NextParam[3] = INT2BCD(cd.SeekLoc.minute);
- cd.NextParam[4] = INT2BCD(cd.SeekLoc.second) | 0x80;
- cd.NextParam[5] = INT2BCD(cd.SeekLoc.frame);
- EVENT_SETUP(400,1,8);
- } else EVENT_SETUP(400,1,1);
- break;
- case 5:
- if (cd.SectorBuf != NULL) {
- memcpy(SectorBuf,cd.SectorBuf,2352);
- memcpy(cd.LastReadInfo,cd.SectorBuf,8);
- }
- cd.SectorBuf = SectorBuf;
- UpdateSeekPosition();
- switch ((cd.moderead = cd.storedmoderead)) {
- case 0:
- cd.SectorBuf += 12; break;
- }
- cd.AsyncCause = 1;
-
- cd.NextParam[0] = cd.Status | StatRead;
- EVENT_SETUP(100,3,1);
- break;
- case 6: // CdlSync
- cd.AsyncCause = 2;
- cd.NextParam[0] = cd.Status;
- cd.ctrl |= 0x80;
- EVENT_SETUP(100,4,1);
- break;
-
- case 7: // ReadS
- #if CACHE_ENABLE==1
- if (cdusecache) cd.SectorBuf = get_cd_cache(&cd.SeekLoc);
- else
- #endif
- cd.SectorBuf = CD_Read((UINT8 *)&cd.SeekLoc);
-
- cd.SectorSize = get_sector_size();
- cd.NextParam[0] = cd.Status;
- cd.AsyncCause = 8;
- cd.DmaReady = 0x40;
- EVENT_SETUP(140,1,1);
- break;
-
- case 8:
- if (cd.SectorBuf != NULL) {
- memcpy(SectorBuf,cd.SectorBuf,2352);
- memcpy(cd.LastReadInfo,cd.SectorBuf,8);
- }
- cd.SectorBuf = SectorBuf;
- UpdateSeekPosition();
- switch ((cd.moderead = cd.storedmoderead)) {
- case 0:
- cd.SectorBuf += 12; break;
- }
- cd.AsyncCause = 7;
-
- cd.NextParam[0] = cd.Status | StatRead;
- EVENT_SETUP(25,3,1);
- break;
-
- default:
- cd.AsyncCause = 0;
- break;
- }
-
- return 1;
- }
-
- void cd_initvar()
- {
- memset(&cd,0,sizeof(cd));
- VSyncCallBack[INT_CD] = cdrom_async;
- #if CACHE_ENABLE==1
- init_cd_cache();
- #endif
-
- switch (psx_country)
- {
- case USE_AMERICAN_PSX:
- memcpy(Cmd25P22,US_Cmd25P22,sizeof(Cmd25P22));
- memcpy(Cmd25P23,US_Cmd25P23,sizeof(Cmd25P23));
- memcpy(Cmd25P24,US_Cmd25P24,sizeof(Cmd25P24));
- memcpy(Cmd25P25,US_Cmd25P25,sizeof(Cmd25P25));
- memcpy(SCEx,US_SCEx,sizeof(SCEx));
- SCExID = US_SCExID;
- printf("SCEA zone selected.\n");
- break;
- case USE_EUROPE_PSX:
- memcpy(Cmd25P22,EU_Cmd25P22,sizeof(Cmd25P22));
- memcpy(Cmd25P23,EU_Cmd25P23,sizeof(Cmd25P23));
- memcpy(Cmd25P24,EU_Cmd25P24,sizeof(Cmd25P24));
- memcpy(Cmd25P25,EU_Cmd25P25,sizeof(Cmd25P25));
- memcpy(SCEx,EU_SCEx,sizeof(SCEx));
- SCExID = EU_SCExID;
- printf("SCEE zone selected.\n");
- break;
- case USE_JAPAN_PSX:
- memcpy(Cmd25P22,JP_Cmd25P22,sizeof(Cmd25P22));
- memcpy(Cmd25P23,JP_Cmd25P23,sizeof(Cmd25P23));
- memcpy(Cmd25P24,JP_Cmd25P24,sizeof(Cmd25P24));
- memcpy(Cmd25P25,JP_Cmd25P25,sizeof(Cmd25P25));
- memcpy(SCEx,JP_SCEx,sizeof(SCEx));
- SCExID = JP_SCExID;
- printf("SCEI zone selected.\n");
- break;
- }
- }
-
- int cd0_read(void)
- {
- int ret = cd.ctrl;
- if (cd.resultsize && cd.resultready) ret|=0x20; else ret&=~0x20;
- // printf("read cd0 %x\n",ret|0x18);
- return ret|0x18;
- }
-
- int cd1_read(void)
- {
- int ret=0;
-
- if (cd.resultsize) {
- ret = cd.result[cd.resultptr++];
- if (cd.resultptr>=cd.resultsize) {
- cd.resultptr = cd.resultsize = 0;
- cd.resultready = 0;
- }
- }
-
- // printf("read cd1 %x\n",ret);
- return ret;
- }
-
- int cd2_read(void)
- {
- // printf("read cd2 ,0\n");
- return 0;
- }
-
- int cd3_read(void)
- {
- // printf("read cd3 %x\n",cd.stat);
-
- return cd.stat;
- }
-
- #define RESULT(n) cd.result[0] = n; cd.resultsize = 1
- #define SRESULT cd.result[0] = cd.Status; cd.resultsize = 1
-
- void cd0_write(int data)
- {
- /* write 0??
- write read & 3?
- */
- // printf("write cd0 %x\n",data);
- // cd.ctrl = data;
- if (data==0) {
- cd.paramptr = 0;
- cd.resultready = 0;
- }
- if (data&1) cd.resultready = 1;
- if (data==1) cd.Reset = 1;
- }
-
- void cd2_write(int data)
- {
- // printf("write cd2 %x\n",data);
- if (cd.Reset==2 && data==7) {
- cd.paramptr = 0;
- cd.resultready = 1;
- cd.Reset = 0;
- cd.stat = 0;
- cd.ctrl = cd.ctrl & ~3; // 0;
- return;
- }
- cd.Reset = 0;
- if (cd.paramptr<8)
- cd.param[cd.paramptr++] = data;
- }
-
- void cd3_write(int data)
- {
- // cd.stat = data;
- // printf("write cd3 %x\n",data);
- if (data==7 && cd.Reset==1) cd.Reset=2;
- else cd.Reset=0;
- if (cd.resultready && data==7) {
- cd.resultsize = cd.resultptr = 0;
- cd.stat = 0;
- }
- }
-
- #if CON_OUTPUT
- #define PRINTRESULT \
- printf(" Resultsize=%2d - %02x %02x %02x %02x %02x %02x %02x %02x\n", \
- cd.resultsize, \
- cd.result[0], cd.result[1], cd.result[2], cd.result[3], \
- cd.result[4], cd.result[5], cd.result[6], cd.result[7]);
- #else
- #define PRINTRESULT
- #endif
-
- void cd1_write(int data)
- {
- static char *cmdname[]= {
- "CdlSync", "CdlNop", "CdlSetloc", "CdlPlay",
- "CdlForward", "CdlBackword", "CdlReadN", "CdlStandby",
- "CdlStop", "CdlPause", "CdlReset", "CdlMute",
- "CdlDemute", "CdlSetfilter", "CdlSetmode", "CdlGetparam",
- "CdlGetlocL", "CdlGetlocP", "Cdl18", "CdlGetTN",
- "CdlGetTD", "CdlSeekL", "CdlSeekP", "Cdl23",
- "Cdl24", "CdlTest", "CdlCheckID", "CdlReadS"
- };
-
- if (data<28) {
- PRINTF("%s\n",cmdname[data]);
- }
-
- #if CON_OUTPUT
- printf("Command %x - Code %02x %02x %02x %02x %02x %02x %02x %02x\n",
- data,
- cd.param[0], cd.param[1], cd.param[2], cd.param[3],
- cd.param[4], cd.param[5], cd.param[6], cd.param[7]);
- #endif
-
- cd.stat = 2;
- switch(data){
- case CdlSync:
- cd.NextParam[0] = cd.Status;
- cd.AsyncCause = 6;
- EVENT_SETUP(100,3,1);
- cd.ctrl |= 0x80;
- cd.stat = 3;
- PRINTRESULT
- return;
-
- case CdlNop:
- cd.stat = 3;
- SRESULT;
- break;
-
- case CdlSetloc:
- if (!(cd.param[0] | cd.param[1] | cd.param[2]))
- {
- cd.Loc = cd.SeekLoc;
- } else {
- cd.Loc.minute = BCD2INT(cd.param[0]);
- cd.Loc.second = BCD2INT(cd.param[1]);
- cd.Loc.frame = BCD2INT(cd.param[2]);
- }
- cd.Status |= StatStandby;
- cd.NextParam[0] = cd.Status;
- cd.AsyncCause = 0;
- EVENT_SETUP(100,3,1);
- cd.ctrl |= 0x80;
- PRINTRESULT
- return;
- /*
- SRESULT;
- break;
- */
- case CdlPlay:
- CD_Play((UINT8 *)&cd.SeekLoc);
- cd.Status |= (StatPlay | StatStandby);
- cd.NextParam[0] = cd.Status;
- cd.AsyncCause = 4;
- EVENT_SETUP(400,3,1);
- cd.DmaReady = 0x40;
- cd.ctrl |= 0x80;
- PRINTRESULT
- return;
-
- case CdlForward:
- case CdlBackword:
- cd.stat = 2;
- SRESULT;
- break;
-
- case CdlReadS:
- cd.AsyncCause = 7;
- goto ContinueRead;
- case CdlReadN:
- cd.AsyncCause = 1;
- ContinueRead:
- cd.Status |= StatStandby;
- if (memcmp(&cd.SeekLoc,&cd.Loc,sizeof(CDLoc)))
- cd.SeekLoc = cd.Loc;
- cd.NextParam[0] = cd.Status;
- EVENT_SETUP(100,3,1);
- // cd.SectorBuf = cd_read((UINT8 *)&cd.SeekLoc);
- // cd.SectorSize = get_sector_size();
- cd.ctrl |= 0x80;
- PRINTRESULT
- return;
-
- case CdlInit:
- cd.mode = 0;
- case CdlReset:
- case CdlStandby:
- cd.stat = 2;
- cd.Status = (cd.Status & ~StatPlay) | StatStandby;
- SRESULT;
- break;
-
- case CdlStop:
- cd.stat = 2;
- if (cd.Status & StatPlay)
- CD_Stop();
- cd.Status &= ~(StatPlay | StatStandby);
- SRESULT;
- break;
-
- case CdlPause:
- // if (++cnt>=17) FPSE_Flags |= VERBOSE | DISASMFLG;
-
- if (cd.Status & StatPlay) CD_Stop();
- cd.Status = (cd.Status & ~StatPlay) | StatStandby;
- cd.AsyncCause = 2;
- cd.NextParam[0] = cd.Status;
- // cd.stat = 4;
- EVENT_SETUP(10,4,1); // 4,2,1);
- cd.DmaReady = 0x40;
- cd.ctrl |= 0x80; // (cd.ctrl | 0x80) & ~0x40;
- PRINTRESULT
- return;
-
- case CdlMute:
- case CdlDemute:
- cd.stat = 2;
- SRESULT;
- break;
-
- case CdlSetfilter:
- cd.stat = 2;
- cd.file = cd.param[0];
- cd.chan = cd.param[1];
- SRESULT;
- break;
-
- case CdlSetmode:
- cd.mode = cd.param[0];
- cd.storedmoderead = (cd.mode & 0x30) >> 4;
- cd.Status |= StatStandby;
- cd.NextParam[0] = cd.Status;
- cd.AsyncCause = 0;
- EVENT_SETUP(100,3,1);
- cd.ctrl |= 0x80;
- PRINTRESULT
- return;
-
- SRESULT;
- break;
-
- case CdlGetparam:
- cd.stat = 2;
- cd.result[0] = cd.Status; /* status */
- cd.result[1] = cd.mode;
- cd.result[2] = cd.file; /* file */
- cd.result[3] = cd.chan; /* channel */
- cd.result[4] = 0;
- cd.result[5] = 0;
- cd.resultsize = 6;
- break;
-
- case CdlGetlocL:
- cd.stat = 2;
- /*
- cd.result[0] = INT2BCD(cd.SeekLoc.minute); // min
- cd.result[1] = INT2BCD(cd.SeekLoc.second); // sec
- cd.result[2] = INT2BCD(cd.SeekLoc.frame); // frame
- cd.result[3] = cd.mode; // mode
- cd.result[4] = cd.file; // file
- cd.result[5] = cd.chan; // channel
- cd.resultsize = 6;
- */
- memcpy(cd.result,cd.LastReadInfo,8);
- cd.resultsize = 8;
- break;
-
- case CdlGetlocP:
- cd.stat = 2;
- cd.result[0] = 1; /* track */
- cd.result[1] = 0; /* index */
- cd.result[2] = cd.LastReadInfo[0]; /* min */
- cd.result[3] = cd.LastReadInfo[1]; /* sec */
- cd.result[4] = cd.LastReadInfo[2]; /* frame */
- cd.result[5] = cd.LastReadInfo[0]; /* Amin */
- cd.result[6] = cd.LastReadInfo[1]; /* Asec */
- cd.result[7] = cd.LastReadInfo[2]; /* Aframe */
- cd.resultsize = 8;
- break;
-
- case CdlGetTN:
- cd.stat = 2;
- CD_GetTN(cd.result);
- cd.result[0] = cd.Status; /* status */
- cd.result[1] = INT2BCD(cd.result[1]); /* first track */
- cd.result[2] = INT2BCD(cd.result[2]); /* total track */
- cd.resultsize = 3;
- break;
-
- case CdlGetTD:
- cd.stat = 2;
- CD_GetTD(cd.result,cd.param[0]);
- cd.result[0] = cd.Status; /* status */
- cd.result[1] = INT2BCD(cd.result[1]); /* min */
- cd.result[2] = INT2BCD(cd.result[2]); /* sec */
- cd.resultsize = 3;
- break;
-
- case CdlSeekL:
- case CdlSeekP:
- cd.SeekLoc = cd.Loc;
- #if CON_OUTPUT
- printf("%02x:%02x:%02x\n",
- cd.SeekLoc.minute,cd.SeekLoc.second,cd.SeekLoc.frame);
- #endif
- cd.Status |= StatStandby;
- cd.NextParam[0] = cd.Status;
- cd.AsyncCause = 0;
- EVENT_SETUP(100,2,1);
- cd.ctrl |= 0x80;
- PRINTRESULT
- return;
-
- cd.Status |= StatStandby;
- SRESULT;
- break;
-
- case CdlTest:
- cd.Status |= StatStandby;
- switch (cd.param[0]) {
- case 0x20:
- cd.result[0] = 0x94; // BIOS Timestamps
- cd.result[1] = 0x09;
- cd.result[2] = 0x19;
- cd.result[3] = 0xC0;
- break;
- case 0x22:
- memcpy(cd.result,Cmd25P22,8);
- break;
- case 0x23:
- memcpy(cd.result,Cmd25P23,8);
- break;
- case 0x24:
- memcpy(cd.result,Cmd25P24,8);
- break;
- case 0x25:
- memcpy(cd.result,Cmd25P25,8);
- break;
- }
- cd.resultsize = 8;
- cd.stat = 3;
- break;
-
- case CdlCheckID:
- cd.result[0] = 0x08; // 0x10=Audio CD 0x08=Data Tracks
- // 0x00=Don't Known
- cd.result[1] = 0x00; // 0x80=Copied CD else Original
- cd.result[2] = 0x00;
- cd.result[3] = 0;
- *(UINT32 *)(cd.result + 4) = SCExID;
-
- cd.resultsize = 8;
- cd.stat = 2;
- break;
- /*
- case CdlReadS:
- cd.Status |= StatStandby;
- SRESULT;
- cd.stat = 2;
- break;
- */
- default:
- printf("unknown cd command %d - %xh\n",data,data);
- cd.stat = 2;
- }
-
- PRINTRESULT
- // VSync_Register = 0;
- cd.resultptr = 0;
- cd.resultready = 1;
-
- /* cd_interrupt happen */
- Irq_Pulse |= (1<<INT_CD);
- }
-
- void dma3_exec(UINT32 adr,UINT32 bcr,UINT32 chcr)
- {
- int size;
-
- #if CON_OUTPUT
- printf("cdma called: %08x %08x %08x\n",(int)adr,(int)bcr,(int)chcr);
- #endif
-
- // get the size in bytes
- size = (bcr>>16)*(bcr&0xffff)*4;
- if (!size) size = bcr*4;
-
- CompileFlush(adr,adr+size);
-
- // check the dma_chcr
- switch(chcr) {
- case 0x11000000:
- if (cd.SectorBuf != NULL)
- {
- switch (cd.moderead) {
- case 2:
- memcpy(RAMADDR(adr),SectorBuf,size);
- cd.SectorSize = 2048;
- cd.SectorBuf += 12;
- cd.moderead = 0;
- break;
- case 1:
- case 0:
- memcpy(RAMADDR(adr),cd.SectorBuf,size);
- cd.SectorBuf += size;
- if ((cd.SectorSize-=size) <= 0)
- cd.ctrl &= ~0x40;
- break;
- }
- /*
-
- if (size <= 12) memcpy(RAMADDR(adr),cd.SectorBuf,size);
- else {
- memcpy(RAMADDR(adr),SectorBuf+12,size);
- cd.ctrl &= ~0x40;
- }
- */
- } else {
- memset(RAMADDR(adr),0,size);
- cd.ctrl &= ~0x40;
- }
-
- break;
- }
- }