--- np2/cbus/atapicmd.c 2005/03/05 16:35:48 1.5 +++ np2/cbus/atapicmd.c 2005/04/05 20:37:07 1.8 @@ -17,9 +17,24 @@ #include "atapicmd.h" #include "sxsi.h" +#define YUIDEBUG + // INQUIRY static const UINT8 cdrom_inquiry[] = { +#ifdef YUIDEBUG + // うちのドライブの奴 NECCDは Product Level 3.00以上で modesense10のコードがちげー + 0x05, // CD-ROM + 0x80, // bit7: Removable Medium Bit, other: Reserved + 0x00, // version [7-6: ISO, ECMA: 5-3, 2-0: ANSI(00)] + 0x21, // 7-4: ATAPI version, 3-0: Response Data Format + 0x1f, // Additional length + 0x00,0x00,0x00, // Reserved + 'N', 'E', 'C', ' ', ' ', ' ', ' ', ' ', // Vendor ID + 'C', 'D', '-', 'R', 'O', 'M', ' ', 'D', // Product ID + 'R', 'I', 'V', 'E', ':', '2', '5', '1', // Product ID + '4', '.', '0', '9' // Product Revision Level +#else 0x05, // CD-ROM 0x80, // bit7: Removable Medium Bit, other: Reserved 0x00, // version [7-6: ISO, ECMA: 5-3, 2-0: ANSI(00)] @@ -30,6 +45,7 @@ static const UINT8 cdrom_inquiry[] = { 'C', 'D', '-', 'R', 'O', 'M', ' ', 'D', // Product ID 'R', 'I', 'V', 'E', ' ', ' ', ' ', ' ', // Product ID '1', '.', '0', ' ' // Product Revision Level +#endif }; static void senddata(IDEDRV drv, UINT size, UINT limit) { @@ -99,7 +115,10 @@ static void atapi_cmd_read_capacity(IDED static void atapi_cmd_read(IDEDRV drv, UINT32 lba, UINT32 leng); static void atapi_cmd_mode_select(IDEDRV drv); static void atapi_cmd_mode_sense(IDEDRV drv); +static void atapi_cmd_readsubch(IDEDRV drv); static void atapi_cmd_readtoc(IDEDRV drv); +static void atapi_cmd_playaudiomsf(IDEDRV drv); +static void atapi_cmd_pauseresume(IDEDRV drv); void atapicmd_a0(IDEDRV drv) { @@ -178,11 +197,26 @@ void atapicmd_a0(IDEDRV drv) { atapi_cmd_mode_sense(drv); break; + case 0x42: + TRACEOUT(("atapicmd: read sub channel")); + atapi_cmd_readsubch(drv); + break; + case 0x43: // read TOC TRACEOUT(("atapicmd: read TOC")); atapi_cmd_readtoc(drv); break; + case 0x47: // Play Audio MSF + TRACEOUT(("atapicmd: Play Audio MSF")); + atapi_cmd_playaudiomsf(drv); + break; + + case 0x4b: + TRACEOUT(("atapicmd: pause resume")); + atapi_cmd_pauseresume(drv); + break; + default: TRACEOUT(("atapicmd: unknown command = %.2x", cmd)); sendabort(drv); @@ -318,10 +352,17 @@ static const BYTE defval_pagecode_0e[PC_ 0x0e, 0x0e, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x01, 0xff, 0x02, 0xff, 0x00, 0x00, 0x00, 0x00, }; + static const BYTE defval_pagecode_2a[PC_2A_SIZE] = { +#ifdef YUIDEBUG + 0x2a, 0x12, 0x00, 0x00, 0x71, 0x65, 0x89, 0x07, + 0x02, 0xc2, 0x00, 0xff, 0x00, 0x80, 0x02, 0xc2, + 0x00, 0x00, 0x00, 0x00, +#else 0x2a, 0x12, 0x00, 0x00, 0x00, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +#endif }; // 0x55: MODE SELECT @@ -479,21 +520,120 @@ length_exceeded: senddata(drv, cnt, leng); } + +// ---- Audio + +static void storemsf(UINT8 *ptr, UINT32 pos) { + + UINT f; + UINT m; + + f = pos % 75; + pos = pos / 75; + m = pos % 60; + pos = pos / 60; + ptr[0] = 0; + ptr[1] = (UINT8)pos; + ptr[2] = (UINT8)m; + ptr[3] = (UINT8)f; +} + + +// 0x43: READ SUB CHANNEL +static void atapi_cmd_readsubch(IDEDRV drv) { + + SXSIDEV sxsi; + UINT leng; + CDTRK trk; + UINT tracks; + UINT r; + UINT32 pos; + + sxsi = sxsi_getptr(drv->sxsidrv); + if ((sxsi == NULL) || (sxsi->devtype != SXSIDEV_CDROM) || + (!(sxsi->flag & SXSIFLAG_READY))) { + senderror(drv); + return; + } + trk = sxsicd_gettrk(sxsi, &tracks); + leng = (drv->buf[7] << 8) + drv->buf[8]; + switch(drv->buf[3]) { + case 0x01: // CD-ROM current pos + ZeroMemory(drv->buf, 16); + drv->buf[4] = 0x01; + pos = drv->dacurpos + (rand() & 7); + r = tracks; + while(r) { + r--; + if (trk[r].pos <= pos) { + break; + } + } + drv->buf[5] = trk[r].type; + drv->buf[6] = trk[r].track; + drv->buf[7] = 1; + storemsf(drv->buf + 8, pos + 150); + storemsf(drv->buf + 12, pos - trk[r].pos); + senddata(drv, 16, leng); + break; + + default: + senderror(drv); + break; + } +} + +// 0x43: READ TOC static void atapi_cmd_readtoc(IDEDRV drv) { + SXSIDEV sxsi; UINT leng; UINT format; + CDTRK trk; + UINT tracks; + UINT datasize; + UINT8 *ptr; + UINT i; + + sxsi = sxsi_getptr(drv->sxsidrv); + if ((sxsi == NULL) || (sxsi->devtype != SXSIDEV_CDROM) || + (!(sxsi->flag & SXSIFLAG_READY))) { + senderror(drv); + return; + } + trk = sxsicd_gettrk(sxsi, &tracks); leng = (drv->buf[7] << 8) + drv->buf[8]; format = (drv->buf[9] >> 6); TRACEOUT(("atapi_cmd_readtoc fmt=%d leng=%d", format, leng)); switch (format) { + case 0: // track info + datasize = (tracks * 8) + 10; + drv->buf[0] = (UINT8)(datasize >> 8); + drv->buf[1] = (UINT8)(datasize >> 0); + drv->buf[2] = 1; + drv->buf[3] = (UINT8)tracks; + ptr = drv->buf + 4; + for (i=0; i<=tracks; i++) { + ptr[0] = 0; + ptr[1] = trk[i].type; + ptr[2] = trk[i].track; + ptr[3] = 0; + storemsf(ptr + 4, trk[i].pos + 150); + ptr += 8; + } + senddata(drv, (tracks * 8) + 12, leng); + break; + case 1: // multi session ZeroMemory(drv->buf, 12); drv->buf[1] = 0x0a; drv->buf[2] = 0x01; drv->buf[3] = 0x01; + drv->buf[5] = 0x14; + drv->buf[6] = 0x01; + drv->buf[10] = 0x02; senddata(drv, 12, leng); break; @@ -503,4 +643,28 @@ static void atapi_cmd_readtoc(IDEDRV drv } } +// 0x47: Play Audio MSF +static void atapi_cmd_playaudiomsf(IDEDRV drv) { + + UINT32 pos; + + pos = (((drv->buf[6] * 60) + drv->buf[7]) * 75) + drv->buf[8]; + if (pos >= 150) { + pos -= 150; + } + else { + pos = 0; + } + drv->daendpos = pos; + drv->dacurpos = pos; // 終了したことにする。 + cmddone(drv); +} + +// 0x4B: PAUSE RESUME +static void atapi_cmd_pauseresume(IDEDRV drv) { + + cmddone(drv); +} + #endif /* SUPPORT_IDEIO */ +