From a2f44b8ea77bc98878db76db8ebd58685946e99e Mon Sep 17 00:00:00 2001 From: SarahW Date: Mon, 29 May 2017 13:56:19 +0100 Subject: [PATCH] Add support for BIN/CUE images. Patch from bit, BIN/CUE handling from DOSBox. --- src/Makefile.am | 4 +- src/Makefile.linux32 | 4 +- src/Makefile.linux64 | 4 +- src/Makefile.mingw | 4 +- src/Makefile.mingw64 | 4 +- src/allegro-gui.c | 16 +- src/cdrom-image.cc | 551 +++++++++++++++++++++++++++++++++++++ src/cdrom-image.h | 23 ++ src/cdrom-ioctl.c | 3 - src/cdrom-iso.c | 356 ------------------------ src/cdrom-iso.h | 13 - src/dosbox/cdrom.h | 172 ++++++++++++ src/dosbox/cdrom_image.cpp | 546 ++++++++++++++++++++++++++++++++++++ src/ibm.h | 2 +- src/ide.c | 2 +- src/ide.h | 2 +- src/pc.c | 38 ++- src/pc.rc | 2 +- src/resources.h | 2 +- src/sound.c | 4 + src/win.c | 34 +-- 21 files changed, 1363 insertions(+), 423 deletions(-) create mode 100644 src/cdrom-image.cc create mode 100644 src/cdrom-image.h delete mode 100644 src/cdrom-iso.c delete mode 100644 src/cdrom-iso.h create mode 100644 src/dosbox/cdrom.h create mode 100644 src/dosbox/cdrom_image.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 2e02c2f..babad39 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,7 +16,7 @@ pcem_LDADD = $(allegro_LIBS) -lopenal pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c acer386sx.c ali1429.c allegro-gui.c \ allegro-gui-config-sel.c allegro-gui-configure.c allegro-gui-deviceconfig.c allegro-gui-hdconf.c allegro-joystick.c allegro-keyboard.c allegro-main.c \ -allegro-midi.c allegro-mouse.c allegro-video.c amstrad.c cdrom-ioctl-linux.c cdrom-iso.c cdrom-null.c \ +allegro-midi.c allegro-mouse.c allegro-video.c amstrad.c cdrom-ioctl-linux.c cdrom-image.c cdrom-null.c \ codegen.c codegen_ops.c codegen_timing_486.c codegen_timing_686.c codegen_timing_pentium.c codegen_timing_winchip.c compaq.c config.c cpu.c \ dac.c dells200.c device.c disc.c disc_fdi.c disc_img.c disc_sector.c dma.c fdc.c fdc37c665.c fdd.c fdi2raw.c gameport.c \ hdd.c hdd_esdi.c headland.c i430lx.c i430fx.c i430vx.c ide.c intel.c intel_flash.c io.c jim.c joystick_ch_flightstick_pro.c joystick_standard.c joystick_sw_pad.c \ @@ -32,7 +32,7 @@ vid_icd2061.c vid_ics2595.c vid_incolor.c vid_mda.c vid_olivetti_m24.c vid_oti06 vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_sdac_ramdac.c \ vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \ vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c video.c wd76c10.c vid_wy700.c \ -x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/dbopl.cpp \ +x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/cdrom_image.cpp dosbox/dbopl.cpp \ dosbox/vid_cga_comp.c resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc \ resid-fp/extfilt.cc resid-fp/filter.cc resid-fp/pot.cc resid-fp/sid.cc \ resid-fp/voice.cc resid-fp/wave6581_PS_.cc resid-fp/wave6581_PST.cc \ diff --git a/src/Makefile.linux32 b/src/Makefile.linux32 index ef20a09..69c1330 100644 --- a/src/Makefile.linux32 +++ b/src/Makefile.linux32 @@ -5,7 +5,7 @@ CFLAGS = -O3 -fomit-frame-pointer -msse2 -m32 LDFLAGS = -m32 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ -allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-iso.o cdrom-null.o \ +allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ @@ -22,7 +22,7 @@ vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \ vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_wy700.o vid_voodoo.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o -DBOBJ = dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o diff --git a/src/Makefile.linux64 b/src/Makefile.linux64 index 52fe554..70ea9d7 100644 --- a/src/Makefile.linux64 +++ b/src/Makefile.linux64 @@ -4,7 +4,7 @@ CC = gcc CFLAGS = -O3 -fomit-frame-pointer -msse2 -m64 OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o allegro-gui.o \ allegro-gui-configure.o allegro-gui-config-sel.o allegro-gui-deviceconfig.o allegro-gui-hdconf.o allegro-joystick.o allegro-keyboard.o allegro-main.o \ -allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-iso.o cdrom-null.o \ +allegro-midi.o allegro-mouse.o allegro-video.o amstrad.o cdrom-ioctl-linux.o cdrom-image.o cdrom-null.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.c compaq.o config.o cpu.o \ dac.o dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o \ hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o \ @@ -21,7 +21,7 @@ vid_pc1512.o vid_pc1640.o vid_pcjr.o vid_ps1_svga.o vid_s3.o vid_s3_virge.o vid_ vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tandysl.o vid_tgui9440.o \ vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o \ x86seg.o x87.o xtide.o sound_dbopl.o sound_resid.o -DBOBJ = dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 95c34a8..68e24e5 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -3,7 +3,7 @@ CPP = g++.exe CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -march=i686 -fomit-frame-pointer -msse2 -mstackrealign -Wall -Werror -fno-strict-aliasing -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86.o compaq.o config.o cpu.o dac.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ @@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ win-status.o win-video.o x86seg.o x87.o xtide.o pc.res -DBOBJ = dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o diff --git a/src/Makefile.mingw64 b/src/Makefile.mingw64 index bd4194a..b210a22 100644 --- a/src/Makefile.mingw64 +++ b/src/Makefile.mingw64 @@ -3,7 +3,7 @@ CPP = g++.exe CC = gcc.exe WINDRES = windres.exe CFLAGS = -O3 -fomit-frame-pointer -msse2 -Wall -Werror -fno-strict-aliasing -OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-iso.o \ +OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o cdrom-image.o \ codegen.o codegen_ops.o codegen_timing_486.o codegen_timing_686.o codegen_timing_pentium.o codegen_timing_winchip.o codegen_x86-64.o compaq.o config.o cpu.o dac.o \ dells200.o device.o disc.o disc_fdi.o disc_img.o disc_sector.o dma.o fdc.o fdc37c665.o fdd.o fdi2raw.o gameport.o hdd.o hdd_esdi.o headland.o i430lx.o i430fx.o \ i430vx.o ide.o intel.o intel_flash.o io.o jim.o joystick_ch_flightstick_pro.o joystick_standard.o joystick_sw_pad.o joystick_tm_fcs.o keyboard.o keyboard_amstrad.o keyboard_at.o \ @@ -21,7 +21,7 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad vid_vga.o vid_voodoo.o vid_wy700.o video.o wd76c10.o win.o win-config.o win-config_sel.o win-d3d.o win-d3d-fs.o win-ddraw.o \ win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \ win-status.o win-video.o x86seg.o x87.o xtide.o pc.res -DBOBJ = dbopl.o vid_cga_comp.o +DBOBJ = cdrom_image.o dbopl.o vid_cga_comp.o SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o diff --git a/src/allegro-gui.c b/src/allegro-gui.c index 43914e6..427c226 100644 --- a/src/allegro-gui.c +++ b/src/allegro-gui.c @@ -5,7 +5,7 @@ #include "disc.h" #include "ide.h" #include "cdrom-ioctl.h" -#include "cdrom-iso.h" +#include "cdrom-image.h" #include "cdrom-null.h" void warning(const char *format, ...) @@ -128,7 +128,7 @@ static void cdrom_update() case -1: cdrom_menu[1].flags = D_SELECTED; break; - case CDROM_ISO: + case CDROM_IMAGE: cdrom_menu[3].flags = D_SELECTED; break; default: @@ -200,14 +200,14 @@ static int cdrom_dev() return D_O_K; } -static int cdrom_iso() +static int cdrom_image() { char fn[260]; int ret; int xsize = SCREEN_W - 32, ysize = SCREEN_H - 64; - strcpy(fn, iso_path); - ret = file_select_ex("Please choose an ISO image", fn, "ISO", 260, xsize, ysize); + strcpy(fn, image_path); + ret = file_select_ex("Please choose an image image", fn, "ISO;CUE", 260, xsize, ysize); if (ret) { if (!cdrom_enabled) @@ -220,8 +220,8 @@ static int cdrom_iso() atapi->exit(); } - cdrom_drive = CDROM_ISO; - iso_open(fn); + cdrom_drive = CDROM_IMAGE; + image_open(fn); if (!cdrom_enabled) { cdrom_enabled = 1; @@ -238,7 +238,7 @@ static MENU cdrom_menu[] = {"&Disabled", cdrom_disabled, NULL, 0, NULL}, {"&Empty", cdrom_empty, NULL, 0, NULL}, {"/dev/cdrom", cdrom_dev, NULL, 0, NULL}, - {"&ISO image...", cdrom_iso, NULL, 0, NULL}, + {"&Image...", cdrom_image, NULL, 0, NULL}, {NULL,NULL,NULL,0,NULL} }; diff --git a/src/cdrom-image.cc b/src/cdrom-image.cc new file mode 100644 index 0000000..464adf3 --- /dev/null +++ b/src/cdrom-image.cc @@ -0,0 +1,551 @@ +#include +#include "cdrom-image.h" +#include "dosbox/cdrom.h" + +extern "C" +{ +#include "ibm.h" +#include "ide.h" + +int cdrom_drive; +int old_cdrom_drive; +} + +char image_path[1024]; +static int image_changed = 0; + +extern ATAPI image_atapi; + +CDROM_Interface_Image *cdrom = NULL; + +#define MSFtoLBA(m,s,f) (((((m*60)+s)*75)+f)) + +static uint32_t cdrom_capacity = 0; + +enum +{ + CD_STOPPED = 0, + CD_PLAYING, + CD_PAUSED +}; + +static int image_cd_state = CD_STOPPED; +static uint32_t image_cd_pos = 0, image_cd_end = 0; + +#define BUF_SIZE 32768 +static int16_t cd_buffer[BUF_SIZE]; +static int cd_buflen = 0; + +void image_audio_callback(int16_t *output, int len) +{ + if (image_cd_state != CD_PLAYING) + return; + while (cd_buflen < len) + { + if (image_cd_pos < image_cd_end) + { +// pclog("Read to %i\n", cd_buflen); + if (!cdrom->ReadSector((unsigned char *)&cd_buffer[cd_buflen], true, image_cd_pos - 150)) + { +// pclog("DeviceIoControl returned false\n"); + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + image_cd_state = CD_STOPPED; + cd_buflen = len; + } + else + { +// pclog("DeviceIoControl returned true\n"); + image_cd_pos++; + cd_buflen += (RAW_SECTOR_SIZE / 2); + } + } + else + { + memset(&cd_buffer[cd_buflen], 0, (BUF_SIZE - cd_buflen) * 2); + image_cd_state = CD_STOPPED; + cd_buflen = len; + } + } + memcpy(output, cd_buffer, len * 2); + memmove(cd_buffer, &cd_buffer[len], (BUF_SIZE - len) * 2); + cd_buflen -= len; +} + +void image_audio_stop() +{ + image_cd_state = CD_STOPPED; +} + +static int image_is_track_audio(uint32_t pos, int ismsf) +{ + if (!cdrom) return 0; + if (ismsf) + { + int m = (pos >> 16) & 0xff; + int s = (pos >> 8) & 0xff; + int f = pos & 0xff; + pos = MSF_TO_FRAMES(m, s, f); + } + + unsigned char attr; + TMSF tmsf; + int number; + cdrom->GetAudioTrackInfo(cdrom->GetTrack(pos), number, tmsf, attr); + + return attr == AUDIO_TRACK; +} + +static void image_playaudio(uint32_t pos, uint32_t len, int ismsf) +{ + if (!cdrom) return; + int number; + unsigned char attr; + TMSF tmsf; + cdrom->GetAudioTrackInfo(cdrom->GetTrack(pos), number, tmsf, attr); + if (attr == DATA_TRACK) + { + pclog("Can't play data track\n"); + image_cd_pos = 0; + image_cd_state = CD_STOPPED; + return; + } + pclog("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf) + { + int m, s, f; + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + len = MSFtoLBA(m, s, f); + + pclog("MSF - pos = %08X len = %08X\n", pos, len); + } + else + len += pos; + image_cd_pos = pos;// + 150; + image_cd_end = len;// + 150; + image_cd_state = CD_PLAYING; + if (image_cd_pos < 150) + image_cd_pos = 150; + cd_buflen = 0; + pclog("Audio start %08X %08X %i %i %i\n", image_cd_pos, image_cd_end, image_cd_state, cd_buflen, len); +} + +static void image_pause(void) +{ + if (!cdrom) return; + if (image_cd_state == CD_PLAYING) + image_cd_state = CD_PAUSED; +} + +static void image_resume(void) +{ + if (!cdrom) return; + if (image_cd_state == CD_PAUSED) + image_cd_state = CD_PLAYING; +} + +static void image_stop(void) +{ + if (!cdrom) return; + image_cd_state = CD_STOPPED; +} + +static void image_seek(uint32_t pos) +{ + if (!cdrom) return; + image_cd_pos = pos; + image_cd_state = CD_STOPPED; +} + +static int image_ready(void) +{ + if (!cdrom) + return 0; + + if (strlen(image_path) == 0) + return 0; + + if (image_changed) + image_changed = 0; + + return 1; +} + +static int image_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) +{ + int c; + uint32_t lb=0; + + if (!cdrom) return 0; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdrom->GetAudioTracks(first_track, last_track, tmsf); + + for (c = 0; c <= last_track; c++) + { + uint32_t address; + cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr); + address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; + if (address > lb) + lb = address; + } + return lb; +} + +static int image_medium_changed(void) +{ + if (!cdrom) + return 0; + + if (strlen(image_path) == 0) + return 0; + + if (old_cdrom_drive != cdrom_drive) + { + old_cdrom_drive = cdrom_drive; + return 1; + } + + if (image_changed) + { + image_changed = 0; + return 1; + } + return 0; +} + +static uint8_t image_getcurrentsubchannel(uint8_t *b, int msf) +{ + if (!cdrom) return 0; + uint8_t ret; + int pos=0; + + uint32_t cdpos = image_cd_pos; + if (cdpos >= 150) cdpos -= 150; + TMSF relPos, absPos; + unsigned char attr, track, index; + cdrom->GetAudioSub(cdpos, attr, track, index, relPos, absPos); + + if (image_cd_state == CD_PLAYING) + ret = 0x11; + else if (image_cd_state == CD_PAUSED) + ret = 0x12; + else + ret = 0x13; + + b[pos++] = attr; + b[pos++] = track; + b[pos++] = index; + + if (msf) + { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; + b[pos + 1] = (uint8_t)dat; + b[pos] = 0; + pos += 4; + } + else + { + uint32_t dat = MSFtoLBA(absPos.min, absPos.sec, absPos.fr); + b[pos++] = (dat >> 24) & 0xff; + b[pos++] = (dat >> 16) & 0xff; + b[pos++] = (dat >> 8) & 0xff; + b[pos++] = dat & 0xff; + dat = MSFtoLBA(relPos.min, relPos.sec, relPos.fr); + b[pos++] = (dat >> 24) & 0xff; + b[pos++] = (dat >> 16) & 0xff; + b[pos++] = (dat >> 8) & 0xff; + b[pos++] = dat & 0xff; + } + + return ret; +} + +static void image_eject(void) +{ +} + +static void image_load(void) +{ +} + +static int image_readsector(uint8_t *b, int sector) +{ + if (!cdrom) return -1; + return !cdrom->ReadSector(b, false, sector); +} + +static void image_readsector_raw(uint8_t *b, int sector) +{ + if (!cdrom) return; + cdrom->ReadSector(b, true, sector); +} + +static int image_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + if (!cdrom) return 0; + int len=4; + int c,d; + uint32_t temp; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdrom->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + d = 0; + for (c = 0; c <= last_track; c++) + { + cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr); + if (number >= starttrack) + { + d=c; + break; + } + } + cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr); + b[2] = number; + + for (c = d; c <= last_track; c++) + { + if ((len + 8) > maxlen) + break; + cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr); + +// pclog("Len %i max %i Track %02X - %02X %02X %02i:%02i:%02i %08X\n",len,maxlen,toc[c].cdte_track,toc[c].cdte_adr,toc[c].cdte_ctrl,toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame,MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame)); + b[len++] = 0; /* reserved */ + b[len++] = attr; + b[len++] = number; /* track number */ + b[len++] = 0; /* reserved */ + + if (msf) + { + b[len++] = 0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + if (single) + break; + } + b[0] = (uint8_t)(((len-2) >> 8) & 0xff); + b[1] = (uint8_t)((len-2) & 0xff); + /* + pclog("Table of Contents:\n"); + pclog("First track - %02X\n", first_track); + pclog("Last track - %02X\n", last_track); + for (c = 0; c <= last_track; c++) + { + cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr); + pclog("Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", c, number, attr, 0, 0, tmsf.min, tmsf.sec, tmsf.fr); + } + for (c = 0;c <= last_track; c++) { + cdrom->GetAudioTrackInfo(c+1, number, tmsf, attr); + pclog("Track %02X - number %02X control %02X adr %02X address %06X\n", c, number, attr, 0, MSF_TO_FRAMES(tmsf.min, tmsf.sec, tmsf.fr)); + } + */ + return len; +} + +static int image_readtoc_session(unsigned char *b, int msf, int maxlen) +{ + if (!cdrom) return 0; + int len = 4; + + int number; + TMSF tmsf; + unsigned char attr; + cdrom->GetAudioTrackInfo(1, number, tmsf, attr); + +// pclog("Read TOC session - %i %02X %02X %i %i %02X %02X %02X\n",0, 0, 0,1,1,attr,0,number); + + b[2] = 1; + b[3] = 1; + b[len++] = 0; /* reserved */ + b[len++] = attr; + b[len++] = number; /* track number */ + b[len++] = 0; /* reserved */ + if (msf) + { + b[len++] = 0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + else + { + uint32_t temp = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr) - 150; + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + + return len; +} + +static int image_readtoc_raw(unsigned char *b, int maxlen) +{ + if (!cdrom) return 0; + + int track; + int len = 4; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdrom->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + for (track = first_track; track <= last_track; track++) + { + if ((len + 11) > maxlen) + { + pclog("image_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + return len; + } + + cdrom->GetAudioTrackInfo(track, number, tmsf, attr); + +// pclog("read_toc: Track %02X - number %02X control %02X adr %02X address %02X %02X %02X %02X\n", track, toc[track].cdte_track, toc[track].cdte_ctrl, toc[track].cdte_adr, 0, toc[track].cdte_addr.msf.minute, toc[track].cdte_addr.msf.second, toc[track].cdte_addr.msf.frame); + + b[len++] = track; + b[len++]= attr; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++] = tmsf.min; + b[len++] = tmsf.sec; + b[len++] = tmsf.fr; + } + return len; +} + +static uint32_t image_size() +{ + return cdrom_capacity; +} + +static int image_status() +{ + if (!cdrom) return CD_STATUS_EMPTY; + if (cdrom->HasAudioTracks()) + { + switch(image_cd_state) + { + case CD_PLAYING: + return CD_STATUS_PLAYING; + case CD_PAUSED: + return CD_STATUS_PAUSED; + case CD_STOPPED: + default: + return CD_STATUS_STOPPED; + } + } + return CD_STATUS_DATA_ONLY; +} +void image_reset() +{ +} + +void image_close(void) +{ + image_cd_state = CD_STOPPED; + if (cdrom) + { + delete cdrom; + cdrom = NULL; + } +// memset(image_path, 0, 1024); +} + +int image_open(char *fn) +{ + if (strcmp(fn, image_path) != 0) + image_changed = 1; + + /* Make sure image_changed stays when changing from an image to another image. */ + if (cdrom_drive != CDROM_IMAGE) + image_changed = 1; + /* strcpy fails on OSX if both parameters are pointing to the same address */ + if (image_path != fn) + strcpy(image_path, fn); + + cdrom = new CDROM_Interface_Image(); + if (!cdrom->SetDevice(fn, false)) + { + image_close(); + return 1; + } + image_cd_state = CD_STOPPED; + image_cd_pos = 0; + cd_buflen = 0; + cdrom_capacity = image_get_last_block(0, 0, 4096, 0) + 1; + atapi = &image_atapi; + return 0; +} + +static void image_exit(void) +{ +} + +ATAPI image_atapi= +{ + image_ready, + image_medium_changed, + image_readtoc, + image_readtoc_session, + image_readtoc_raw, + image_getcurrentsubchannel, + image_readsector, + image_readsector_raw, + image_playaudio, + image_seek, + image_load, + image_eject, + image_pause, + image_resume, + image_size, + image_status, + image_is_track_audio, + image_stop, + image_exit +}; diff --git a/src/cdrom-image.h b/src/cdrom-image.h new file mode 100644 index 0000000..c0a7e44 --- /dev/null +++ b/src/cdrom-image.h @@ -0,0 +1,23 @@ +#ifndef CDROM_ISO_H +#define CDROM_ISO_H + +#include + +extern char image_path[1024]; + +#ifdef __cplusplus +extern "C" { +#endif + +int image_open(char *fn); +void image_reset(); +void image_close(); + +void image_audio_callback(int16_t *output, int len); +void image_audio_stop(); + +#ifdef __cplusplus +} +#endif + +#endif /* ! CDROM_ISO_H */ diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index ef10004..f1b133c 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -58,10 +58,7 @@ void ioctl_audio_callback(int16_t *output, int len) // return; // pclog("Audio callback %08X %08X %i %i %i %04X %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, cd_buflen, len, cd_buffer[4], GetTickCount()); if (ioctl_cd_state != CD_PLAYING) - { - memset(output, 0, len * 2); return; - } while (cd_buflen < len) { if (ioctl_cd_pos < ioctl_cd_end) diff --git a/src/cdrom-iso.c b/src/cdrom-iso.c deleted file mode 100644 index 220b073..0000000 --- a/src/cdrom-iso.c +++ /dev/null @@ -1,356 +0,0 @@ -/*ISO CD-ROM support*/ - -#include "ibm.h" -#include "ide.h" -#include "cdrom-iso.h" -#include - -static ATAPI iso_atapi; - -static uint32_t last_block = 0; -static uint64_t image_size = 0; -static int iso_inited = 0; -char iso_path[1024]; -void iso_close(void); -static FILE *iso_image = NULL; -static int iso_changed = 0; - -void iso_audio_callback(int16_t *output, int len) -{ - memset(output, 0, len * 2); - return; -} - -void iso_audio_stop() -{ - pclog("iso_audio_stop stub\n"); -} - -static void iso_playaudio(uint32_t pos, uint32_t len, int ismsf) -{ - pclog("iso_playaudio stub\n"); - return; -} - -static void iso_pause(void) -{ - pclog("iso_pause stub\n"); - return; -} - -static void iso_resume(void) -{ - pclog("iso_resume stub\n"); - return; -} - -static void iso_stop(void) -{ - pclog("iso_stop stub\n"); - return; -} - -static void iso_seek(uint32_t pos) -{ - pclog("iso_seek stub\n"); - return; -} - -static int iso_ready(void) -{ - if (strlen(iso_path) == 0) - return 0; - - if (old_cdrom_drive != cdrom_drive) - return 1; - - iso_changed = 0; - return 1; -} - -/* Always return 0, because there is no way to change the ISO without unmounting and remounting it. */ -static int iso_medium_changed(void) -{ - iso_changed = 0; - return 0; -} - -static uint8_t iso_getcurrentsubchannel(uint8_t *b, int msf) -{ - pclog("iso_getcurrentsubchannel stub\n"); - return 0; -} - -static void iso_eject(void) -{ - pclog("iso_eject stub\n"); -} - -static void iso_load(void) -{ - pclog("iso_load stub\n"); -} - -static int iso_readsector(uint8_t *b, int sector) -{ - if (!cdrom_drive) - return -1; - fseek(iso_image,sector*2048,SEEK_SET); - fread(b,2048,1,iso_image); - return 0; -} - -static void lba_to_msf(uint8_t *buf, int lba) -{ - lba += 150; - buf[0] = (lba / 75) / 60; - buf[1] = (lba / 75) % 60; - buf[2] = lba % 75; -} - -static void iso_readsector_raw(uint8_t *b, int sector) -{ - if (!cdrom_drive) return; - fseek(iso_image, sector*2048, SEEK_SET); - fread(b+16, 2048, 1, iso_image); - - /* sync bytes */ - b[0] = 0; - memset(b + 1, 0xff, 10); - b[11] = 0; - b += 12; - lba_to_msf(b, sector); - b[3] = 1; /* mode 1 data */ - b += 4; - b += 2048; - memset(b, 0, 288); -} - -static int iso_readtoc(unsigned char *buf, unsigned char start_track, int msf, int maxlen, int single) -{ - uint8_t *q; - int len; - - if (start_track > 1 && start_track != 0xaa) - return -1; - q = buf + 2; - *q++ = 1; /* first session */ - *q++ = 1; /* last session */ - if (start_track <= 1) - { - *q++ = 0; /* reserved */ - *q++ = 0x14; /* ADR, control */ - *q++ = 1; /* track number */ - *q++ = 0; /* reserved */ - if (msf) - { - *q++ = 0; /* reserved */ - lba_to_msf(q, 0); - q += 3; - } - else - { - /* sector 0 */ - *q++ = 0; - *q++ = 0; - *q++ = 0; - *q++ = 0; - } - } - /* lead out track */ - *q++ = 0; /* reserved */ - *q++ = 0x16; /* ADR, control */ - *q++ = 0xaa; /* track number */ - *q++ = 0; /* reserved */ - last_block = image_size >> 11; - if (msf) - { - *q++ = 0; /* reserved */ - lba_to_msf(q, last_block); - q += 3; - } - else - { - *q++ = last_block >> 24; - *q++ = last_block >> 16; - *q++ = last_block >> 8; - *q++ = last_block; - } - len = q - buf; - buf[0] = (uint8_t)(((len-2) >> 8) & 0xff); - buf[1] = (uint8_t)((len-2) & 0xff); - return len; -} - -static int iso_readtoc_session(unsigned char *buf, int msf, int maxlen) -{ - uint8_t *q; - - q = buf + 2; - *q++ = 1; /* first session */ - *q++ = 1; /* last session */ - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa0; /* lead-in */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - *q++ = 0; - - return 12; -} - -static int iso_readtoc_raw(unsigned char *buf, int maxlen) -{ - uint8_t *q; - int len; - - q = buf + 2; - *q++ = 1; /* first session */ - *q++ = 1; /* last session */ - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa0; /* lead-in */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - *q++ = 0; - *q++ = 1; /* first track */ - *q++ = 0x00; /* disk type */ - *q++ = 0x00; - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa1; - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - *q++ = 0; - *q++ = 1; /* last track */ - *q++ = 0x00; - *q++ = 0x00; - - *q++ = 1; /* session number */ - *q++ = 0x14; /* data track */ - *q++ = 0; /* track number */ - *q++ = 0xa2; /* lead-out */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - last_block = image_size >> 11; - /* this is raw, must be msf */ - *q++ = 0; /* reserved */ - lba_to_msf(q, last_block); - q += 3; - - *q++ = 1; /* session number */ - *q++ = 0x14; /* ADR, control */ - *q++ = 0; /* track number */ - *q++ = 1; /* point */ - *q++ = 0; /* min */ - *q++ = 0; /* sec */ - *q++ = 0; /* frame */ - /* same here */ - *q++ = 0; - *q++ = 0; - *q++ = 0; - *q++ = 0; - - len = q - buf; - buf[0] = (uint8_t)(((len-2) >> 8) & 0xff); - buf[1] = (uint8_t)((len-2) & 0xff); - return len; -} - -static uint32_t iso_size() -{ - unsigned char b[4096]; - - atapi->readtoc(b, 0, 0, 4096, 0); - - return last_block; -} - -static int iso_status() -{ - if (!(iso_ready()) && (cdrom_drive != 200)) - return CD_STATUS_EMPTY; - - return CD_STATUS_DATA_ONLY; -} - -void iso_reset() -{ -} - -int iso_open(char *fn) -{ - struct stat st; - - if (iso_image) - fclose(iso_image); - - if (strcmp(fn, iso_path) != 0) - iso_changed = 1; - - /* Make sure iso_changed stays when changing from ISO to another ISO. */ - if (cdrom_drive != CDROM_ISO) - iso_changed = 1; - strcpy(iso_path, fn); - - iso_image = fopen(iso_path, "rb"); - atapi = &iso_atapi; - - stat(iso_path, &st); - image_size = st.st_size; - - return 0; -} - -void iso_close(void) -{ - if (iso_image) - { - fclose(iso_image); - iso_image = NULL; - } - memset(iso_path, 0, 1024); -} - -static void iso_exit(void) -{ - iso_inited = 0; -} - -static int iso_is_track_audio(uint32_t pos, int ismsf) -{ - return 0; -} - -static ATAPI iso_atapi = -{ - iso_ready, - iso_medium_changed, - iso_readtoc, - iso_readtoc_session, - iso_readtoc_raw, - iso_getcurrentsubchannel, - iso_readsector, - iso_readsector_raw, - iso_playaudio, - iso_seek, - iso_load, - iso_eject, - iso_pause, - iso_resume, - iso_size, - iso_status, - iso_is_track_audio, - iso_stop, - iso_exit -}; diff --git a/src/cdrom-iso.h b/src/cdrom-iso.h deleted file mode 100644 index d4efd06..0000000 --- a/src/cdrom-iso.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef CDROM_ISO_H -#define CDROM_ISO_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ - -extern char iso_path[1024]; - -extern int iso_open(char *fn); -extern void iso_reset(); -extern void iso_close(); - -#endif /* ! CDROM_ISO_H */ diff --git a/src/dosbox/cdrom.h b/src/dosbox/cdrom.h new file mode 100644 index 0000000..603deb7 --- /dev/null +++ b/src/dosbox/cdrom.h @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Modified for use with PCem by bit */ + +#ifndef __CDROM_INTERFACE__ +#define __CDROM_INTERFACE__ + +#include +#include +#include +#include +#include +#include +//#include "dosbox.h" +//#include "mem.h" +//#include "mixer.h" +//#include "SDL.h" +//#include "SDL_thread.h" + +#include +typedef signed int Bits; +typedef unsigned int Bitu; +typedef int8_t Bit8s; +typedef uint8_t Bit8u; +typedef int16_t Bit16s; +typedef uint16_t Bit16u; +typedef int32_t Bit32s; +typedef uint32_t Bit32u; + +typedef size_t PhysPt; + +#define RAW_SECTOR_SIZE 2352 +#define COOKED_SECTOR_SIZE 2048 + +#define DATA_TRACK 0x14 +#define AUDIO_TRACK 0x10 + +#define CD_FPS 75 +#define FRAMES_TO_MSF(f, M,S,F) { \ + int value = f; \ + *(F) = value%CD_FPS; \ + value /= CD_FPS; \ + *(S) = value%60; \ + value /= 60; \ + *(M) = value; \ +} +#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) + + +typedef struct SMSF { + unsigned char min; + unsigned char sec; + unsigned char fr; +} TMSF; + +typedef struct SCtrl { + Bit8u out[4]; // output channel + Bit8u vol[4]; // channel volume +} TCtrl; + +extern int CDROM_GetMountType(char* path, int force); + +class CDROM_Interface +{ +public: +// CDROM_Interface (void); + virtual ~CDROM_Interface (void) {}; + + virtual bool SetDevice (char* path, int forceCD) = 0; + + virtual bool GetUPC (unsigned char& attr, char* upc) = 0; + + virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0; + virtual bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr) = 0; + virtual bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0; + virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0; + + virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0; + + virtual bool LoadUnloadMedia (bool unload) = 0; + + virtual void InitNewMedia (void) {}; +}; + +class CDROM_Interface_Image : public CDROM_Interface +{ +private: + class TrackFile { + public: + virtual bool read(Bit8u *buffer, int seek, int count) = 0; + virtual int getLength() = 0; + virtual ~TrackFile() { }; + }; + + class BinaryFile : public TrackFile { + public: + BinaryFile(const char *filename, bool &error); + ~BinaryFile(); + bool read(Bit8u *buffer, int seek, int count); + int getLength(); + private: + BinaryFile(); + std::ifstream *file; + }; + + struct Track { + int number; + int track_number; + int attr; + int start; + int length; + int skip; + int sectorSize; + bool mode2; + TrackFile *file; + }; + +public: + CDROM_Interface_Image (); + virtual ~CDROM_Interface_Image (void); + void InitNewMedia (void); + bool SetDevice (char* path, int forceCD); + bool GetUPC (unsigned char& attr, char* upc); + bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut); + bool GetAudioTrackInfo (int track, int& number, TMSF& start, unsigned char& attr); + bool GetAudioSub (int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos); + bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen); + bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num); + bool LoadUnloadMedia (bool unload); + bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector); + bool HasDataTrack (void); + bool HasAudioTracks (void); + + int GetTrack (int sector); + +private: + // player +static void CDAudioCallBack(Bitu len); + + void ClearTracks(); + bool LoadIsoFile(char *filename); + bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2); + // cue sheet processing + bool LoadCueSheet(char *cuefile); + bool GetRealFileName(std::string& filename, std::string& pathname); + bool GetCueKeyword(std::string &keyword, std::istream &in); + bool GetCueFrame(int &frames, std::istream &in); + bool GetCueString(std::string &str, std::istream &in); + bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap); + + std::vector tracks; +typedef std::vector::iterator track_it; + std::string mcn; +}; + +#endif /* __CDROM_INTERFACE__ */ diff --git a/src/dosbox/cdrom_image.cpp b/src/dosbox/cdrom_image.cpp new file mode 100644 index 0000000..096777c --- /dev/null +++ b/src/dosbox/cdrom_image.cpp @@ -0,0 +1,546 @@ +/* + * Copyright (C) 2002-2015 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Modified for use with PCem by bit */ + +#include +#include +#include +#include +#include +#include +#include //GCC 2.95 +#include +#include +#include +#include "cdrom.h" + +#if !defined(WIN32) +#include +#else +#include +#endif + +using namespace std; + +#define MAX_LINE_LENGTH 512 +#define MAX_FILENAME_LENGTH 256 +#define CROSS_LEN 512 + +#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0) + +CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) +{ + file = new ifstream(filename, ios::in | ios::binary); + error = (file == NULL) || (file->fail()); +} + +CDROM_Interface_Image::BinaryFile::~BinaryFile() +{ + delete file; +} + +bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) +{ + file->seekg(seek, ios::beg); + file->read((char*)buffer, count); + return !(file->fail()); +} + +int CDROM_Interface_Image::BinaryFile::getLength() +{ + file->seekg(0, ios::end); + int length = (int)file->tellg(); + if (file->fail()) return -1; + return length; +} + +CDROM_Interface_Image::CDROM_Interface_Image() +{ +} + +CDROM_Interface_Image::~CDROM_Interface_Image() +{ + ClearTracks(); +} + +void CDROM_Interface_Image::InitNewMedia() +{ +} + +bool CDROM_Interface_Image::SetDevice(char* path, int forceCD) +{ + if (LoadCueSheet(path)) return true; + if (LoadIsoFile(path)) return true; + + // print error message on dosbox console + //printf("Could not load image file: %s\n", path); + return false; +} + +bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc) +{ + attr = 0; + strcpy(upc, this->mcn.c_str()); + return true; +} + +bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut) +{ + stTrack = 1; + end = (int)(tracks.size() - 1); + FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr); + return true; +} + +bool CDROM_Interface_Image::GetAudioTrackInfo(int track, int& track_number, TMSF& start, unsigned char& attr) +{ + if (track < 1 || track > (int)tracks.size()) return false; + FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr); + track_number = tracks[track - 1].track_number; + attr = tracks[track - 1].attr; + return true; +} + +bool CDROM_Interface_Image::GetAudioSub(int sector, unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) +{ + int cur_track = GetTrack(sector); + if (cur_track < 1) return false; + track = (unsigned char)cur_track; + attr = tracks[track - 1].attr; + index = 1; + FRAMES_TO_MSF(sector + 150, &absPos.min, &absPos.sec, &absPos.fr); + FRAMES_TO_MSF(sector - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr); + return true; +} + +bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen) +{ + mediaPresent = true; + mediaChanged = false; + trayOpen = false; + return true; +} + +bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num) +{ + int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE; + Bitu buflen = num * sectorSize; + Bit8u* buf = new Bit8u[buflen]; + + bool success = true; //Gobliiins reads 0 sectors + for(unsigned long i = 0; i < num; i++) { + success = ReadSector(&buf[i * sectorSize], raw, sector + i); + if (!success) break; + } + + memcpy((void*)buffer, buf, buflen); + delete[] buf; + + return success; +} + +bool CDROM_Interface_Image::LoadUnloadMedia(bool unload) +{ + return true; +} + +int CDROM_Interface_Image::GetTrack(int sector) +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end() - 1; + + while(i != end) { + Track &curr = *i; + Track &next = *(i + 1); + if (curr.start <= sector && sector < next.start) return curr.number; + i++; + } + return -1; +} + +bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector) +{ + int track = GetTrack(sector) - 1; + if (track < 0) return false; + + int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize; + int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE); + if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false; + if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16; + if (tracks[track].mode2 && !raw) seek += 24; + + return tracks[track].file->read(buffer, seek, length); +} + +bool CDROM_Interface_Image::LoadIsoFile(char* filename) +{ + tracks.clear(); + + // data track + Track track = {0, 0, 0, 0, 0, 0, 0, false, NULL}; + bool error; + track.file = new BinaryFile(filename, error); + if (error) { + delete track.file; + return false; + } + track.number = 1; + track.track_number = 1; + track.attr = DATA_TRACK;//data + + // try to detect iso type + if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) { + track.sectorSize = COOKED_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = false; + } else if (CanReadPVD(track.file, 2336, true)) { + track.sectorSize = 2336; + track.mode2 = true; + } else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) { + track.sectorSize = RAW_SECTOR_SIZE; + track.mode2 = true; + } else return false; + + track.length = track.file->getLength() / track.sectorSize; + tracks.push_back(track); + + // leadout track + track.number = 2; + track.track_number = 0xAA; + track.attr = 0; + track.start = track.length; + track.length = 0; + track.file = NULL; + tracks.push_back(track); + + return true; +} + +bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2) +{ + Bit8u pvd[COOKED_SECTOR_SIZE]; + int seek = 16 * sectorSize; // first vd is located at sector 16 + if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16; + if (mode2) seek += 24; + file->read(pvd, seek, COOKED_SECTOR_SIZE); + // pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version (+8 for High Sierra) + return ((pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1) || + (pvd[8] == 1 && !strncmp((char*)(&pvd[9]), "CDROM", 5) && pvd[14] == 1)); +} + +#if defined(WIN32) +static string dirname(char * file) { + char * sep = strrchr(file, '\\'); + if (sep == NULL) + sep = strrchr(file, '/'); + if (sep == NULL) + return ""; + else { + int len = (int)(sep - file); + char tmp[MAX_FILENAME_LENGTH]; + safe_strncpy(tmp, file, len+1); + return tmp; + } +} +#endif + +bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) +{ + Track track = {0, 0, 0, 0, 0, 0, 0, false, NULL}; + tracks.clear(); + int shift = 0; + int currPregap = 0; + int totalPregap = 0; + int prestart = 0; + bool success; + bool canAddTrack = false; + char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument + safe_strncpy(tmp, cuefile, MAX_FILENAME_LENGTH); + string pathname(dirname(tmp)); + ifstream in; + in.open(cuefile, ios::in); + if (in.fail()) return false; + + while(!in.eof()) { + // get next line + char buf[MAX_LINE_LENGTH]; + in.getline(buf, MAX_LINE_LENGTH); + if (in.fail() && !in.eof()) return false; // probably a binary file + istringstream line(buf); + + string command; + GetCueKeyword(command, line); + + if (command == "TRACK") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + + track.start = 0; + track.skip = 0; + currPregap = 0; + prestart = 0; + + line >> track.number; + track.track_number = track.number; + string type; + GetCueKeyword(type, line); + + if (type == "AUDIO") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = AUDIO_TRACK; + track.mode2 = false; + } else if (type == "MODE1/2048") { + track.sectorSize = COOKED_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = false; + } else if (type == "MODE1/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = false; + } else if (type == "MODE2/2336") { + track.sectorSize = 2336; + track.attr = DATA_TRACK; + track.mode2 = true; + } else if (type == "MODE2/2352") { + track.sectorSize = RAW_SECTOR_SIZE; + track.attr = DATA_TRACK; + track.mode2 = true; + } else success = false; + + canAddTrack = true; + } + else if (command == "INDEX") { + int index; + line >> index; + int frame; + success = GetCueFrame(frame, line); + + if (index == 1) track.start = frame; + else if (index == 0) prestart = frame; + // ignore other indices + } + else if (command == "FILE") { + if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap); + else success = true; + canAddTrack = false; + + string filename; + GetCueString(filename, line); + GetRealFileName(filename, pathname); + string type; + GetCueKeyword(type, line); + + track.file = NULL; + bool error = true; + if (type == "BINARY") { + track.file = new BinaryFile(filename.c_str(), error); + } + if (error) { + delete track.file; + success = false; + } + } + else if (command == "PREGAP") success = GetCueFrame(currPregap, line); + else if (command == "CATALOG") success = GetCueString(mcn, line); + // ignored commands + else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC" + || command == "PERFORMER" || command == "POSTGAP" || command == "REM" + || command == "SONGWRITER" || command == "TITLE" || command == "") success = true; + // failure + else success = false; + + if (!success) return false; + } + // add last track + if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false; + + // add leadout track + track.number++; + track.track_number = 0xAA; + track.attr = 0;//sync with load iso + track.start = 0; + track.length = 0; + track.file = NULL; + if(!AddTrack(track, shift, 0, totalPregap, 0)) return false; + + return true; +} + +bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap) +{ + // frames between index 0(prestart) and 1(curr.start) must be skipped + int skip; + if (prestart > 0) { + if (prestart > curr.start) return false; + skip = curr.start - prestart; + } else skip = 0; + + // first track (track number must be 1) + if (tracks.empty()) { + if (curr.number != 1) return false; + curr.skip = skip * curr.sectorSize; + curr.start += currPregap; + totalPregap = currPregap; + tracks.push_back(curr); + return true; + } + + Track &prev = *(tracks.end() - 1); + + // current track consumes data from the same file as the previous + if (prev.file == curr.file) { + curr.start += shift; + prev.length = curr.start + totalPregap - prev.start - skip; + curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize; + totalPregap += currPregap; + curr.start += totalPregap; + // current track uses a different file as the previous track + } else { + int tmp = prev.file->getLength() - prev.skip; + prev.length = tmp / prev.sectorSize; + if (tmp % prev.sectorSize != 0) prev.length++; // padding + + curr.start += prev.start + prev.length + currPregap; + curr.skip = skip * curr.sectorSize; + shift += prev.start + prev.length; + totalPregap = currPregap; + } + + // error checks + if (curr.number <= 1) return false; + if (prev.number + 1 != curr.number) return false; + if (curr.start < prev.start + prev.length) return false; + if (curr.length < 0) return false; + + tracks.push_back(curr); + return true; +} + +bool CDROM_Interface_Image::HasDataTrack(void) +{ + //Data track has attribute 0x14 + for(track_it it = tracks.begin(); it != tracks.end(); it++) { + if ((*it).attr == DATA_TRACK) return true; + } + return false; +} + +bool CDROM_Interface_Image::HasAudioTracks(void) +{ + for(track_it it = tracks.begin(); it != tracks.end(); it++) { + if ((*it).attr == AUDIO_TRACK) return true; + } + return false; +} + + +bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname) +{ + // check if file exists + struct stat test; + if (stat(filename.c_str(), &test) == 0) return true; + + // check if file with path relative to cue file exists + string tmpstr(pathname + "/" + filename); + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } +#if defined (WIN32) || defined(OS2) + //Nothing +#else + //Consider the possibility that the filename has a windows directory seperator (inside the CUE file) + //which is common for some commercial rereleases of DOS games using DOSBox + + string copy = filename; + size_t l = copy.size(); + for (size_t i = 0; i < l;i++) { + if(copy[i] == '\\') copy[i] = '/'; + } + + if (stat(copy.c_str(), &test) == 0) { + filename = copy; + return true; + } + + tmpstr = pathname + "/" + copy; + if (stat(tmpstr.c_str(), &test) == 0) { + filename = tmpstr; + return true; + } + +#endif + return false; +} + +bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in) +{ + in >> keyword; + for(Bitu i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]); + + return true; +} + +bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in) +{ + string msf; + in >> msf; + int min, sec, fr; + bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3; + frames = MSF_TO_FRAMES(min, sec, fr); + + return success; +} + +bool CDROM_Interface_Image::GetCueString(string &str, istream &in) +{ + int pos = (int)in.tellg(); + in >> str; + if (str[0] == '\"') { + if (str[str.size() - 1] == '\"') { + str.assign(str, 1, str.size() - 2); + } else { + in.seekg(pos, ios::beg); + char buffer[MAX_FILENAME_LENGTH]; + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip + in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); + str = buffer; + } + } + return true; +} + +void CDROM_Interface_Image::ClearTracks() +{ + vector::iterator i = tracks.begin(); + vector::iterator end = tracks.end(); + + TrackFile* last = NULL; + while(i != end) { + Track &curr = *i; + if (curr.file != last) { + delete curr.file; + last = curr.file; + } + i++; + } + tracks.clear(); +} diff --git a/src/ibm.h b/src/ibm.h index 5120aef..82bb8bd 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -167,7 +167,7 @@ struct #define cycles cpu_state._cycles -uint32_t cpu_cur_status; +extern uint32_t cpu_cur_status; #define CPU_STATUS_USE32 (1 << 0) #define CPU_STATUS_STACK32 (1 << 1) diff --git a/src/ide.c b/src/ide.c index 766a683..a4e3fda 100644 --- a/src/ide.c +++ b/src/ide.c @@ -2415,7 +2415,7 @@ static void atapicommand(int ide_board) } - if ((cdrom_drive < 1) || (cdrom_drive == CDROM_ISO) || (cd_status <= CD_STATUS_DATA_ONLY) || + if ((cdrom_drive < 1) || (cd_status <= CD_STATUS_DATA_ONLY) || !atapi->is_track_audio(pos, (idebufferb[0] == GPCMD_PLAY_AUDIO_MSF) ? 1 : 0)) { ide->atastat = READY_STAT | ERR_STAT; /*CHECK CONDITION*/ diff --git a/src/ide.h b/src/ide.h index ae1ab63..4c4e0b6 100644 --- a/src/ide.h +++ b/src/ide.h @@ -56,6 +56,6 @@ extern int cdrom_channel; uint32_t atapi_get_cd_channel(int channel); uint32_t atapi_get_cd_volume(int channel); -#define CDROM_ISO 200 +#define CDROM_IMAGE 200 #endif //__IDE__ diff --git a/src/pc.c b/src/pc.c index 3438590..1420253 100644 --- a/src/pc.c +++ b/src/pc.c @@ -6,7 +6,7 @@ #include "ali1429.h" #include "cdrom-ioctl.h" -#include "cdrom-iso.h" +#include "cdrom-image.h" #include "disc.h" #include "disc_img.h" #include "mem.h" @@ -281,13 +281,13 @@ void initpc(int argc, char *argv[]) else #endif { - if (cdrom_drive == CDROM_ISO) + if (cdrom_drive == CDROM_IMAGE) { - FILE *ff = fopen(iso_path, "rb"); + FILE *ff = fopen(image_path, "rb"); if (ff) { fclose(ff); - iso_open(iso_path); + image_open(image_path); } else { @@ -318,9 +318,9 @@ void initpc(int argc, char *argv[]) else #endif { - if (cdrom_drive == CDROM_ISO) + if (cdrom_drive == CDROM_IMAGE) { - iso_reset(); + image_reset(); } else { @@ -398,15 +398,31 @@ void resetpchard() // output=3; + image_close(); #if __unix if (cdrom_drive == -1) cdrom_null_reset(); else #endif { - if (cdrom_drive == CDROM_ISO) + if (cdrom_drive == CDROM_IMAGE) { - iso_reset(); + FILE *ff = fopen(image_path, "rb"); + if (ff) + { + fclose(ff); + image_open(image_path); + } + else + { +#if __unix + cdrom_drive = -1; + cdrom_null_open(cdrom_drive); +#else + cdrom_drive = 0; + ioctl_set_drive(cdrom_drive); +#endif + } } else { @@ -655,8 +671,8 @@ void loadconfig(char *fn) cdrom_channel = config_get_int(CFG_MACHINE, NULL, "cdrom_channel", 2); p = (char *)config_get_string(CFG_MACHINE, NULL, "cdrom_path", ""); - if (p) strcpy(iso_path, p); - else strcpy(iso_path, ""); + if (p) strcpy(image_path, p); + else strcpy(image_path, ""); hdc[0].spt = config_get_int(CFG_MACHINE, NULL, "hdc_sectors", 0); hdc[0].hpc = config_get_int(CFG_MACHINE, NULL, "hdc_heads", 0); @@ -764,7 +780,7 @@ void saveconfig(char *fn) config_set_int(CFG_MACHINE, NULL, "cdrom_drive", cdrom_drive); config_set_int(CFG_MACHINE, NULL, "cdrom_enabled", cdrom_enabled); config_set_int(CFG_MACHINE, NULL, "cdrom_channel", cdrom_channel); - config_set_string(CFG_MACHINE, NULL, "cdrom_path", iso_path); + config_set_string(CFG_MACHINE, NULL, "cdrom_path", image_path); config_set_int(CFG_MACHINE, NULL, "hdc_sectors", hdc[0].spt); config_set_int(CFG_MACHINE, NULL, "hdc_heads", hdc[0].hpc); diff --git a/src/pc.rc b/src/pc.rc index 0c3ab71..2f1900d 100644 --- a/src/pc.rc +++ b/src/pc.rc @@ -31,7 +31,7 @@ BEGIN BEGIN MENUITEM "&Disabled", IDM_CDROM_DISABLED MENUITEM "&Empty",IDM_CDROM_EMPTY - MENUITEM "&ISO...",IDM_CDROM_ISO + MENUITEM "&Image...",IDM_CDROM_IMAGE END POPUP "&Video" BEGIN diff --git a/src/resources.h b/src/resources.h index 932eda4..af0bac4 100644 --- a/src/resources.h +++ b/src/resources.h @@ -24,7 +24,7 @@ #define IDM_CDROM_EMPTY 40100 #define IDM_CDROM_REAL 40100 #define IDM_CDROM_DISABLED 40200 -#define IDM_CDROM_ISO 40201 +#define IDM_CDROM_IMAGE 40201 #define IDC_COMBO1 1000 #define IDC_COMBOVID 1001 diff --git a/src/sound.c b/src/sound.c index a092bc2..26a93a2 100644 --- a/src/sound.c +++ b/src/sound.c @@ -4,6 +4,7 @@ #include "device.h" #include "cdrom-ioctl.h" +#include "cdrom-image.h" #include "ide.h" #include "filters.h" @@ -134,7 +135,9 @@ static void sound_cd_thread(void *param) int c; thread_wait_event(sound_cd_event, -1); + memset(cd_buffer, 0, CD_BUFLEN*2 * 2); ioctl_audio_callback(cd_buffer, CD_BUFLEN*2); + image_audio_callback(cd_buffer, CD_BUFLEN*2); if (soundon) { int32_t atapi_vol_l = atapi_get_cd_volume(0); @@ -259,4 +262,5 @@ void sound_reset() sound_set_cd_volume(65535, 65535); ioctl_audio_stop(); + image_audio_stop(); } diff --git a/src/win.c b/src/win.c index f88b5ee..c9d2093 100644 --- a/src/win.c +++ b/src/win.c @@ -15,7 +15,7 @@ #include #include "ibm.h" #include "cdrom-ioctl.h" -#include "cdrom-iso.h" +#include "cdrom-image.h" #include "config.h" #include "cpu.h" #include "device.h" @@ -632,8 +632,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance, CheckMenuItem(menu, IDM_CDROM_DISABLED, MF_CHECKED); else { - if (cdrom_drive == CDROM_ISO) - CheckMenuItem(menu, IDM_CDROM_ISO, MF_CHECKED); + if (cdrom_drive == CDROM_IMAGE) + CheckMenuItem(menu, IDM_CDROM_IMAGE, MF_CHECKED); else CheckMenuItem(menu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED); } @@ -885,8 +885,8 @@ void atapi_close(void) { switch (cdrom_drive) { - case CDROM_ISO: - iso_close(); + case CDROM_IMAGE: + image_close(); break; default: ioctl_close(); @@ -898,7 +898,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM { HMENU hmenu; RECT rect; - char temp_iso_path[1024]; + char temp_image_path[1024]; int new_cdrom_drive; // pclog("Message %i %08X\n",message,message); switch (message) @@ -1067,7 +1067,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM ioctl_set_drive(0); CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_CHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED); old_cdrom_drive = cdrom_drive; cdrom_drive=0; CheckMenuItem(hmenu, IDM_CDROM_EMPTY, MF_UNCHECKED); @@ -1103,7 +1103,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM } CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED); old_cdrom_drive = cdrom_drive; cdrom_drive=0; CheckMenuItem(hmenu, IDM_CDROM_EMPTY, MF_CHECKED); @@ -1119,8 +1119,8 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM } break; - case IDM_CDROM_ISO: - if (!getfile(hwnd,"CD-ROM image (*.ISO)\0*.ISO\0All files (*.*)\0*.*\0",iso_path)) + case IDM_CDROM_IMAGE: + if (!getfile(hwnd,"CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0",image_path)) { if (!cdrom_enabled) { @@ -1128,15 +1128,15 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM break; } old_cdrom_drive = cdrom_drive; - strcpy(temp_iso_path, openfilestring); - if ((strcmp(iso_path, temp_iso_path) == 0) && (cdrom_drive == CDROM_ISO) && cdrom_enabled) + strcpy(temp_image_path, openfilestring); + if ((strcmp(image_path, temp_image_path) == 0) && (cdrom_drive == CDROM_IMAGE) && cdrom_enabled) { /* Switching from ISO to the same ISO. Do nothing. */ break; } atapi->exit(); atapi_close(); - iso_open(temp_iso_path); + image_open(temp_image_path); if (cdrom_enabled) { /* Signal disc change to the emulated machine. */ @@ -1144,9 +1144,9 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM } CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); - cdrom_drive = CDROM_ISO; - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_CHECKED); + CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED); + cdrom_drive = CDROM_IMAGE; + CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_CHECKED); saveconfig(NULL); if (!cdrom_enabled) { @@ -1185,7 +1185,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM } CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_UNCHECKED); CheckMenuItem(hmenu, IDM_CDROM_DISABLED, MF_UNCHECKED); - CheckMenuItem(hmenu, IDM_CDROM_ISO, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_IMAGE, MF_UNCHECKED); cdrom_drive = new_cdrom_drive; CheckMenuItem(hmenu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED); saveconfig(NULL);