// this only supports 2048 byte sectors static int command_read (int unitnum, uae_u8 *data, int sector, int numsectors) { struct cdunit *cdu = unitisopen (unitnum); if (!cdu) return 0; struct cdtoc *t = findtoc (cdu, §or); if (!t) return 0; cdda_stop (cdu); if (t->size == 2048) { while (numsectors-- > 0) { do_read (cdu, t, data, sector, 0, 2048); data += 2048; sector++; } } else { while (numsectors-- > 0) { if (t->size == 2352) { uae_u8 b = 0; do_read (cdu, t, &b, sector, 15, 1); // 2 = MODE2 do_read (cdu, t, data, sector, b == 2 ? 24 : 16, 2048); } else { do_read (cdu, t, data, sector, 16, 2048); } data += 2048; sector++; } } cdu->cd_last_pos = sector; return 1; }
void handle_sdcard() { DEBUG_PUTS("[Card inserted]\n"); if (sd_init()) if (fatfs_mount()) if (find_imgfile()) if (imgfile_init()) { set_disk_type(imgheader.disk_type); PORTA = fatfs_filenumber; fatfs_next_filename(); } else { fatfs_reset_filename(); PORTA = ~0; } while (SDCARD_INSERTED) { service_ide(); service_cdda(); } DEBUG_PUTS("[Card extracted]\n"); cdda_stop(); set_disk_type(0xff); }
static int command_stop (int unitnum) { struct cdunit *cdu = unitisopen (unitnum); if (!cdu) return 0; cdda_stop (cdu); return 1; }
/* stop CD audio */ static int ioctl_command_stop (int unitnum) { struct dev_info_ioctl *ciw = unitisopen (unitnum); if (!ciw) return 0; cdda_stop (ciw); return 1; }
/* close device handle */ static void sys_cddev_close (struct dev_info_ioctl *ciw, int unitnum) { if (ciw->open == false) return; cdda_stop (ciw); close_createfile (ciw); VirtualFree (ciw->tempbuffer, 0, MEM_RELEASE); ciw->tempbuffer = NULL; uae_sem_destroy (&ciw->sub_sem); uae_sem_destroy (&ciw->sub_sem2); ciw->open = false; write_log (_T("IOCTL: device '%s' closed\n"), ciw->devname, unitnum); }
void PortWrite (UINT16 PortNo, UINT8 data) { switch (PortNo & 0xff) { case 0x4: YM2610_control_port_0_A_w (0, data); break; case 0x5: YM2610_data_port_0_A_w (0, data); break; case 0x6: YM2610_control_port_0_B_w (0, data); break; case 0x7: YM2610_data_port_0_B_w (0, data); break; case 0x8: /* NMI enable / acknowledge? (the data written doesn't matter) */ break; case 0xc: result_code = data; break; case 0x18: /* NMI disable? (the data written doesn't matter) */ break; case 0x80: cdda_stop (); break; default: //printf("Unimplemented Z80 Write Port: %x data: %x\n",PortNo&0xff,data); break; } }
static int eject (int unitnum, bool eject) { DWORD len; struct dev_info_ioctl *ciw = unitisopen (unitnum); if (!ciw) return 0; if (!unitisopen (unitnum)) return 0; cdda_stop (ciw); if (!open_createfile (ciw, 0)) return 0; int ret = 0; seterrormode (ciw); if (!DeviceIoControl (ciw->h, eject ? IOCTL_STORAGE_EJECT_MEDIA : IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, &len, NULL)) { ret = 1; } reseterrormode (ciw); return ret; }
static int command_rawread (int unitnum, uae_u8 *data, int sector, int size, int sectorsize, uae_u32 extra) { int ret = 0; struct cdunit *cdu = unitisopen (unitnum); if (!cdu) return 0; int asector = sector; struct cdtoc *t = findtoc (cdu, §or); int ssize = t->size + t->skipsize; if (!t) goto end; cdda_stop (cdu); if (sectorsize > 0) { if (sectorsize == 2352 && t->size == 2048) { // 2048 -> 2352 while (size-- > 0) { memset (data, 0, 16); do_read (cdu, t, data + 16, sector, 0, 2048); encode_l2 (data, sector + 150); sector++; asector++; data += sectorsize; ret += sectorsize; } } else if (sectorsize == 2048 && t->size == 2352) { // 2352 -> 2048 while (size-- > 0) { uae_u8 b = 0; do_read (cdu, t, &b, sector, 15, 1); do_read (cdu, t, data, sector, b == 2 ? 24 : 16, sectorsize); sector++; asector++; data += sectorsize; ret += sectorsize; } } else if (sectorsize == 2336 && t->size == 2352) { // 2352 -> 2336 while (size-- > 0) { uae_u8 b = 0; do_read (cdu, t, &b, sector, 15, 1); if (b != 2 && b != 0) // MODE0 or MODE2 only allowed return 0; do_read (cdu, t, data, sector, 16, sectorsize); sector++; asector++; data += sectorsize; ret += sectorsize; } } else if (sectorsize == t->size) { // no change while (size -- > 0) { do_read (cdu, t, data, sector, 0, sectorsize); sector++; asector++; data += sectorsize; ret++; } } cdu->cd_last_pos = asector; } else { uae_u8 sectortype = extra >> 16; uae_u8 cmd9 = extra >> 8; int sync = (cmd9 >> 7) & 1; int headercodes = (cmd9 >> 5) & 3; int userdata = (cmd9 >> 4) & 1; int edcecc = (cmd9 >> 3) & 1; int errorfield = (cmd9 >> 1) & 3; uae_u8 subs = extra & 7; if (subs != 0 && subs != 1 && subs != 2 && subs != 4) { ret = -1; goto end; } if (isaudiotrack (&cdu->di.toc, sector)) { if (sectortype != 0 && sectortype != 1) { ret = -2; goto end; } if (t->size != 2352) { ret = -1; goto end; } for (int i = 0; i < size; i++) { do_read (cdu, t, data, sector, 0, t->size); uae_u8 *p = data + t->size; if (subs) { uae_u8 subdata[SUB_CHANNEL_SIZE]; getsub_deinterleaved (subdata, cdu, t, sector); if (subs == 4) { // all, de-interleaved memcpy (p, subdata, SUB_CHANNEL_SIZE); p += SUB_CHANNEL_SIZE; } else if (subs == 2) { // q-only memcpy (p, subdata + SUB_ENTRY_SIZE, SUB_ENTRY_SIZE); p += SUB_ENTRY_SIZE; } else if (subs == 1) { // all, interleaved sub_to_interleaved (subdata, p); p += SUB_CHANNEL_SIZE; } } ret += p - data; data = p; sector++; } } } end: return ret; }
static int ioctl_command_readwrite (int unitnum, int sector, int size, int write, uae_u8 *data) { struct dev_info_ioctl *ciw = unitisopen (unitnum); if (!ciw) return 0; if (ciw->usesptiread) return ioctl_command_rawread (unitnum, data, sector, size, 2048, 0); cdda_stop (ciw); DWORD dtotal; int cnt = 3; uae_u8 *p = ciw->tempbuffer; int blocksize = ciw->di.bytespersector; if (!open_createfile (ciw, 0)) return 0; ciw->cd_last_pos = sector; while (cnt-- > 0) { LARGE_INTEGER offset; gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE); seterrormode (ciw); offset.QuadPart = (uae_u64)sector * ciw->di.bytespersector; if (SetFilePointer (ciw->h, offset.LowPart, &offset.HighPart, FILE_BEGIN) == INVALID_SET_FILE_POINTER && GetLastError () != NO_ERROR) { reseterrormode (ciw); if (win32_error (ciw, unitnum, _T("SetFilePointer")) < 0) continue; return 0; } reseterrormode (ciw); break; } while (size-- > 0) { gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE); seterrormode (ciw); if (write) { if (data) { memcpy (p, data, blocksize); data += blocksize; } if (!WriteFile (ciw->h, p, blocksize, &dtotal, 0)) { int err; reseterrormode (ciw); err = win32_error (ciw, unitnum, _T("WriteFile")); if (err < 0) continue; if (err == ERROR_WRITE_PROTECT) return -1; return 0; } } else { dtotal = 0; if (!ReadFile (ciw->h, p, blocksize, &dtotal, 0)) { reseterrormode (ciw); if (win32_error (ciw, unitnum, _T("ReadFile")) < 0) continue; return 0; } if (dtotal == 0) { static int reported; /* ESS Mega (CDTV) "fake" data area returns zero bytes and no error.. */ spti_read (ciw, unitnum, data, sector, 2048); if (reported++ < 100) write_log (_T("IOCTL unit %d, sector %d: ReadFile()==0. SPTI=%d\n"), unitnum, sector, GetLastError ()); return 1; } if (data) { memcpy (data, p, blocksize); data += blocksize; } } reseterrormode (ciw); gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE); } return 1; }
static int ioctl_command_rawread (int unitnum, uae_u8 *data, int sector, int size, int sectorsize, uae_u32 extra) { struct dev_info_ioctl *ciw = unitisopen (unitnum); if (!ciw) return 0; uae_u8 *p = ciw->tempbuffer; int ret = 0; if (log_scsi) write_log (_T("IOCTL rawread unit=%d sector=%d blocksize=%d\n"), unitnum, sector, sectorsize); cdda_stop (ciw); gui_flicker_led (LED_CD, unitnum, LED_CD_ACTIVE); if (sectorsize > 0) { if (sectorsize != 2336 && sectorsize != 2352 && sectorsize != 2048 && sectorsize != 2336 + 96 && sectorsize != 2352 + 96 && sectorsize != 2048 + 96) return 0; while (size-- > 0) { if (!read_block (ciw, unitnum, data, sector, 1, sectorsize)) break; ciw->cd_last_pos = sector; data += sectorsize; ret += sectorsize; sector++; } } else { uae_u8 sectortype = extra >> 16; uae_u8 cmd9 = extra >> 8; int sync = (cmd9 >> 7) & 1; int headercodes = (cmd9 >> 5) & 3; int userdata = (cmd9 >> 4) & 1; int edcecc = (cmd9 >> 3) & 1; int errorfield = (cmd9 >> 1) & 3; uae_u8 subs = extra & 7; if (subs != 0 && subs != 1 && subs != 2 && subs != 4) return -1; if (errorfield >= 3) return -1; uae_u8 *d = data; if (isaudiotrack (&ciw->di.toc, sector)) { if (sectortype != 0 && sectortype != 1) return -2; for (int i = 0; i < size; i++) { uae_u8 *odata = data; int blocksize = errorfield == 0 ? 2352 : (errorfield == 1 ? 2352 + 294 : 2352 + 296); int readblocksize = errorfield == 0 ? 2352 : 2352 + 296; if (!read_block (ciw, unitnum, NULL, sector, 1, readblocksize)) { reseterrormode (ciw); return ret; } ciw->cd_last_pos = sector; if (subs == 0) { memcpy (data, p, blocksize); data += blocksize; } else if (subs == 4) { // all, de-interleaved memcpy (data, p, blocksize); data += blocksize; sub_to_deinterleaved (p + readblocksize, data); data += SUB_CHANNEL_SIZE; } else if (subs == 2) { // q-only memcpy (data, p, blocksize); data += blocksize; uae_u8 subdata[SUB_CHANNEL_SIZE]; sub_to_deinterleaved (p + readblocksize, subdata); memcpy (data, subdata + SUB_ENTRY_SIZE, SUB_ENTRY_SIZE); p += SUB_ENTRY_SIZE; } else if (subs == 1) { // all, interleaved memcpy (data, p, blocksize); memcpy (data + blocksize, p + readblocksize, SUB_CHANNEL_SIZE); data += blocksize + SUB_CHANNEL_SIZE; } ret += data - odata; sector++; } } } return ret; }