From 55a294ad37eb3ecd8f28aa78c0f11094a4adb70d Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 May 2017 04:54:17 +0200 Subject: [PATCH 1/2] Fixed serial (and serial mouse) operation on boards with Super I/O chips; A few video bug fixes per patches from the mainline PCem forum; Added CUE/BIN image support per patches from the mainline PCem forum. --- src/86Box.rc | 10 +- src/Makefile.mingw | 2 +- src/VIDEO/vid_cga.c | 2 +- src/VIDEO/vid_colorplus.c | 2 +- src/VIDEO/vid_ega.c | 6 +- src/VIDEO/vid_genius.c | 2 +- src/VIDEO/vid_hercules.c | 2 +- src/VIDEO/vid_herculesplus.c | 2 +- src/VIDEO/vid_incolor.c | 2 +- src/VIDEO/vid_mda.c | 2 +- src/VIDEO/vid_s3.c | 69 ++-- src/VIDEO/vid_svga.c | 6 +- src/VIDEO/vid_wy700.c | 2 +- src/cdrom-ioctl.c | 1 - src/cdrom-iso.c | 632 ----------------------------------- src/cdrom-iso.h | 15 - src/cdrom-null.c | 31 +- src/cdrom.c | 3 +- src/cdrom.h | 34 +- src/config.c | 446 ++++++++++++++++++++++++ src/config.h | 12 + src/fdc37c932fr.c | 2 + src/ibm.h | 2 - src/network.c | 3 + src/network.h | 3 + src/pc.c | 451 +------------------------ src/resource.h | 8 +- src/serial.c | 24 +- src/win.c | 50 ++- 29 files changed, 610 insertions(+), 1216 deletions(-) delete mode 100644 src/cdrom-iso.c delete mode 100644 src/cdrom-iso.h diff --git a/src/86Box.rc b/src/86Box.rc index 8bc4756d9..f0e8fb74e 100644 --- a/src/86Box.rc +++ b/src/86Box.rc @@ -63,7 +63,7 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_1_EMPTY MENUITEM "&Reload previous disc", IDM_CDROM_1_RELOAD MENUITEM SEPARATOR - MENUITEM "&ISO...", IDM_CDROM_1_ISO + MENUITEM "&Image...", IDM_CDROM_1_IMAGE END POPUP "CD-ROM 2" BEGIN @@ -72,7 +72,7 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_2_EMPTY MENUITEM "&Reload previous disc", IDM_CDROM_2_RELOAD MENUITEM SEPARATOR - MENUITEM "&ISO...", IDM_CDROM_2_ISO + MENUITEM "&Image...", IDM_CDROM_2_IMAGE END POPUP "CD-ROM 3" BEGIN @@ -81,7 +81,7 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_3_EMPTY MENUITEM "&Reload previous disc", IDM_CDROM_3_RELOAD MENUITEM SEPARATOR - MENUITEM "&ISO...", IDM_CDROM_3_ISO + MENUITEM "&Image...", IDM_CDROM_3_IMAGE END POPUP "CD-ROM 4" BEGIN @@ -90,7 +90,7 @@ BEGIN MENUITEM "E&mpty", IDM_CDROM_4_EMPTY MENUITEM "&Reload previous disc", IDM_CDROM_4_RELOAD MENUITEM SEPARATOR - MENUITEM "&ISO...", IDM_CDROM_4_ISO + MENUITEM "&Image...", IDM_CDROM_4_IMAGE END END @@ -808,7 +808,7 @@ BEGIN 2172 "Hard disk images (*.HDI;*.HDX;*.IMA;*.IMG)\0*.HDI;*.HDX;*.IMA;*.IMG\0All files (*.*)\0*.*\0" 2173 "All floppy images (*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.86F;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMD;*.IMG;*.TD0;*.VFD;*.XDF\0Advanced sector-based images (*.IMD;*.TD0)\0*.IMD;*.TD0\0Basic sector-based images (*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF)\0*.0??;*.12;*.144;*.360;*.720;*.BIN;*.CQ;*.CQM;*.DSK;*.FDI;*.FDF;*.FLP;*.HDM;*.IMA;*.IMG;*.VFD;*.XDF\0Flux images (*.FDI)\0*.FDI\0Surface-based images (*.86F)\0*.86F\0All files (*.*)\0*.*\0" 2174 "Configuration files (*.CFG)\0*.CFG\0All files (*.*)\0*.*\0" - 2175 "CD-ROM image (*.ISO)\0*.ISO\0All files (*.*)\0*.*\0" + 2175 "CD-ROM image (*.ISO;*.CUE)\0*.ISO;*.CUE\0All files (*.*)\0*.*\0" 2176 "Use CTRL + ALT + PAGE DOWN to return to windowed mode" 2177 "Olivetti M24 mouse" 2178 "" diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 71ce8e4e7..93196a298 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -128,7 +128,7 @@ DEVOBJ = bugger.o lpt.o serial.o \ disc.o \ disc_86f.o disc_fdi.o disc_imd.o disc_img.o \ disc_random.o disc_td0.o \ - cdrom.o cdrom-ioctl.o cdrom-iso.o cdrom-null.o + cdrom.o cdrom-dosbox.o cdrom-image.o cdrom-ioctl.o cdrom-null.o USBOBJ = usb.o NETOBJ = network.o net_ne2000.o SCSIOBJ = scsi.o scsi_disk.o scsi_buslogic.o scsi_aha154x.o diff --git a/src/VIDEO/vid_cga.c b/src/VIDEO/vid_cga.c index 646ba51e9..41553f671 100644 --- a/src/VIDEO/vid_cga.c +++ b/src/VIDEO/vid_cga.c @@ -469,7 +469,7 @@ void *cga_standalone_init() cga_comp_init(cga->revision); timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga); - mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga); + mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, cga); io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); overscan_x = overscan_y = 16; diff --git a/src/VIDEO/vid_colorplus.c b/src/VIDEO/vid_colorplus.c index 25ceb71dc..ab07127f7 100644 --- a/src/VIDEO/vid_colorplus.c +++ b/src/VIDEO/vid_colorplus.c @@ -379,7 +379,7 @@ void *colorplus_standalone_init() cga_comp_init(1); timer_add(colorplus_poll, &colorplus->cga.vidtime, TIMER_ALWAYS_ENABLED, colorplus); - mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, 0, colorplus); + mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, colorplus); io_sethandler(0x03d0, 0x0010, colorplus_in, NULL, NULL, colorplus_out, NULL, NULL, colorplus); return colorplus; diff --git a/src/VIDEO/vid_ega.c b/src/VIDEO/vid_ega.c index 9243c825f..d97f13ba1 100644 --- a/src/VIDEO/vid_ega.c +++ b/src/VIDEO/vid_ega.c @@ -925,7 +925,7 @@ void *ega_standalone_init() ega_common_defaults(ega); - mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); return ega; @@ -961,7 +961,7 @@ void *cpqega_standalone_init() ega_common_defaults(ega); - mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); return ega; @@ -997,7 +997,7 @@ void *sega_standalone_init() ega_common_defaults(ega); - mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, 0, ega); + mem_mapping_add(&ega->mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, ega); timer_add(ega_poll, &ega->vidtime, TIMER_ALWAYS_ENABLED, ega); io_sethandler(0x03c0, 0x0020, ega_in, NULL, NULL, ega_out, NULL, NULL, ega); return ega; diff --git a/src/VIDEO/vid_genius.c b/src/VIDEO/vid_genius.c index a0053cc93..35db8905f 100644 --- a/src/VIDEO/vid_genius.c +++ b/src/VIDEO/vid_genius.c @@ -562,7 +562,7 @@ void *genius_init() /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in * high-resolution modes) */ - mem_mapping_add(&genius->mapping, 0xb0000, 0x10000, genius_read, NULL, NULL, genius_write, NULL, NULL, NULL, 0, genius); + mem_mapping_add(&genius->mapping, 0xb0000, 0x10000, genius_read, NULL, NULL, genius_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, genius); /* Respond to both MDA and CGA I/O ports */ io_sethandler(0x03b0, 0x000C, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); io_sethandler(0x03d0, 0x0010, genius_in, NULL, NULL, genius_out, NULL, NULL, genius); diff --git a/src/VIDEO/vid_hercules.c b/src/VIDEO/vid_hercules.c index 8eefb409f..a7c5ab73a 100644 --- a/src/VIDEO/vid_hercules.c +++ b/src/VIDEO/vid_hercules.c @@ -320,7 +320,7 @@ void *hercules_init() hercules->vram = malloc(0x10000); timer_add(hercules_poll, &hercules->vidtime, TIMER_ALWAYS_ENABLED, hercules); - mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL, 0, hercules); + mem_mapping_add(&hercules->mapping, 0xb0000, 0x08000, hercules_read, NULL, NULL, hercules_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, hercules); io_sethandler(0x03b0, 0x0010, hercules_in, NULL, NULL, hercules_out, NULL, NULL, hercules); for (c = 0; c < 256; c++) diff --git a/src/VIDEO/vid_herculesplus.c b/src/VIDEO/vid_herculesplus.c index a2a004312..459107d03 100644 --- a/src/VIDEO/vid_herculesplus.c +++ b/src/VIDEO/vid_herculesplus.c @@ -667,7 +667,7 @@ void *herculesplus_init() herculesplus->vram = malloc(0x10000); /* 64k VRAM */ timer_add(herculesplus_poll, &herculesplus->vidtime, TIMER_ALWAYS_ENABLED, herculesplus); - mem_mapping_add(&herculesplus->mapping, 0xb0000, 0x10000, herculesplus_read, NULL, NULL, herculesplus_write, NULL, NULL, NULL, 0, herculesplus); + mem_mapping_add(&herculesplus->mapping, 0xb0000, 0x10000, herculesplus_read, NULL, NULL, herculesplus_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, herculesplus); io_sethandler(0x03b0, 0x0010, herculesplus_in, NULL, NULL, herculesplus_out, NULL, NULL, herculesplus); for (c = 0; c < 256; c++) diff --git a/src/VIDEO/vid_incolor.c b/src/VIDEO/vid_incolor.c index 45cf15d41..636697c1a 100644 --- a/src/VIDEO/vid_incolor.c +++ b/src/VIDEO/vid_incolor.c @@ -1014,7 +1014,7 @@ void *incolor_init() incolor->vram = malloc(0x40000); /* 4 planes of 64k */ timer_add(incolor_poll, &incolor->vidtime, TIMER_ALWAYS_ENABLED, incolor); - mem_mapping_add(&incolor->mapping, 0xb0000, 0x08000, incolor_read, NULL, NULL, incolor_write, NULL, NULL, NULL, 0, incolor); + mem_mapping_add(&incolor->mapping, 0xb0000, 0x08000, incolor_read, NULL, NULL, incolor_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, incolor); io_sethandler(0x03b0, 0x0010, incolor_in, NULL, NULL, incolor_out, NULL, NULL, incolor); for (c = 0; c < 64; c++) diff --git a/src/VIDEO/vid_mda.c b/src/VIDEO/vid_mda.c index 689cc56ab..7180a4921 100644 --- a/src/VIDEO/vid_mda.c +++ b/src/VIDEO/vid_mda.c @@ -269,7 +269,7 @@ void *mda_init() mda->vram = malloc(0x1000); timer_add(mda_poll, &mda->vidtime, TIMER_ALWAYS_ENABLED, mda); - mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, 0, mda); + mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda); io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda); for (c = 0; c < 256; c++) diff --git a/src/VIDEO/vid_s3.c b/src/VIDEO/vid_s3.c index a597cbad8..ae5c8c701 100644 --- a/src/VIDEO/vid_s3.c +++ b/src/VIDEO/vid_s3.c @@ -736,8 +736,10 @@ void s3_out(uint16_t addr, uint8_t val, void *p) } if (svga->seqaddr == 4) /*Chain-4 - update banking*/ { - if (val & 8) svga->write_bank = svga->read_bank = s3->bank << 16; - else svga->write_bank = svga->read_bank = s3->bank << 14; + if (val & 8 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; } break; @@ -767,6 +769,10 @@ void s3_out(uint16_t addr, uint8_t val, void *p) { case 0x31: s3->ma_ext = (s3->ma_ext & 0x1c) | ((val & 0x30) >> 4); + if (svga->chain4 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; break; case 0x32: svga->vrammask = (val & 0x40) ? 0x3ffff : s3->vram_mask; @@ -790,19 +796,25 @@ void s3_out(uint16_t addr, uint8_t val, void *p) case 0x35: s3->bank = (s3->bank & 0x70) | (val & 0xf); - if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; - else svga->write_bank = svga->read_bank = s3->bank << 14; + if (svga->chain4 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; break; case 0x51: s3->bank = (s3->bank & 0x4f) | ((val & 0xc) << 2); - if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; - else svga->write_bank = svga->read_bank = s3->bank << 14; + if (svga->chain4 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; s3->ma_ext = (s3->ma_ext & ~0xc) | ((val & 3) << 2); break; case 0x6a: s3->bank = val; - if (svga->chain4) svga->write_bank = svga->read_bank = s3->bank << 16; - else svga->write_bank = svga->read_bank = s3->bank << 14; + if (svga->chain4 || (svga->crtc[0x31] & 8)) + svga->write_bank = svga->read_bank = s3->bank << 16; + else + svga->write_bank = svga->read_bank = s3->bank << 14; break; case 0x3a: @@ -981,7 +993,12 @@ void s3_updatemapping(s3_t *s3) return; } - switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ + if (svga->crtc[0x31] & 0x08) + { + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + } + else switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/ { case 0x0: /*128k at A0000*/ mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); @@ -1646,9 +1663,9 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.dx >= clip_l && s3->accel.dx <= clip_r && s3->accel.dy >= clip_t && s3->accel.dy <= clip_b) { - READ(s3->accel.src + s3->accel.cx, src_dat); - - dest_dat = src_dat; + READ(s3->accel.src + s3->accel.cx, dest_dat); + + MIX WRITE(s3->accel.dest + s3->accel.dx); } @@ -1672,8 +1689,6 @@ void s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (s3->accel.sy < 0) { - s3->accel.cur_x = s3->accel.cx; - s3->accel.cur_y = s3->accel.cy; return; } } @@ -2183,19 +2198,9 @@ int s3_phoenix_trio32_available() void *s3_trio64_init(wchar_t *bios_fn) { - int card_id = 0; s3_t *s3 = s3_init(bios_fn, S3_TRIO64); - card_id = device_get_config_int("card_id"); - - if (card_id) - { - s3->id = 0xc1; /*Vision864P*/ - } - else - { - s3->id = 0xe1; /*Trio64*/ - } + s3->id = 0xe1; /*Trio64*/ s3->id_ext = s3->id_ext_pci = 0x11; s3->packed_mmio = 1; @@ -2390,20 +2395,6 @@ static device_config_t s3_phoenix_trio64_config[] = } } }, - { - "card_id", "Card ID", CONFIG_SELECTION, "", 0, - { - { - "S3 Trio64", 0 - }, - { - "S3 Vision864", 1 - }, - { - "" - } - } - }, { "", "", -1 } diff --git a/src/VIDEO/vid_svga.c b/src/VIDEO/vid_svga.c index 80d5983cc..6da19608d 100644 --- a/src/VIDEO/vid_svga.c +++ b/src/VIDEO/vid_svga.c @@ -971,7 +971,7 @@ int svga_init(svga_t *svga, void *p, int memsize, svga->hwcursor_draw = hwcursor_draw; svga->overlay_draw = overlay_draw; - mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, 0, svga); + mem_mapping_add(&svga->mapping, 0xa0000, 0x20000, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel, NULL, MEM_MAPPING_EXTERNAL, svga); memset(svga->vgapal, 0, sizeof(PALETTE)); @@ -1236,7 +1236,7 @@ uint8_t svga_read(uint32_t addr, void *p) if (svga->chain4 || svga->fb_only) { if (addr >= svga->vram_limit) - return 0xff; + return 0x00; return svga->vram[svga_mask_addr(addr, svga)]; } else if (svga->chain2_read) @@ -1254,7 +1254,7 @@ uint8_t svga_read(uint32_t addr, void *p) addr<<=2; if (addr >= svga->vram_limit) - return 0xff; + return 0x00; addr = svga_mask_addr(addr, svga); diff --git a/src/VIDEO/vid_wy700.c b/src/VIDEO/vid_wy700.c index a7b612e09..0091ba534 100644 --- a/src/VIDEO/vid_wy700.c +++ b/src/VIDEO/vid_wy700.c @@ -884,7 +884,7 @@ void *wy700_init() /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in * high-resolution modes) */ - mem_mapping_add(&wy700->mapping, 0xb0000, 0x10000, wy700_read, NULL, NULL, wy700_write, NULL, NULL, NULL, 0, wy700); + mem_mapping_add(&wy700->mapping, 0xb0000, 0x10000, wy700_read, NULL, NULL, wy700_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, wy700); /* Respond to both MDA and CGA I/O ports */ io_sethandler(0x03b0, 0x000C, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); io_sethandler(0x03d0, 0x0010, wy700_in, NULL, NULL, wy700_out, NULL, NULL, wy700); diff --git a/src/cdrom-ioctl.c b/src/cdrom-ioctl.c index 5ab4d09a3..c81bd7f14 100644 --- a/src/cdrom-ioctl.c +++ b/src/cdrom-ioctl.c @@ -1050,7 +1050,6 @@ static CDROM ioctl_cdrom= NULL, ioctl_getcurrentsubchannel, ioctl_pass_through, - ioctl_sector_data_type, NULL, ioctl_playaudio, ioctl_load, diff --git a/src/cdrom-iso.c b/src/cdrom-iso.c deleted file mode 100644 index 2247baccb..000000000 --- a/src/cdrom-iso.c +++ /dev/null @@ -1,632 +0,0 @@ -/* Copyright holders: RichardG867, Tenshi - see COPYING for more details -*/ -/*ISO CD-ROM support*/ - -#include - -#include "ibm.h" -#include "cdrom.h" -#include "cdrom-iso.h" - -#define __USE_LARGEFILE64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE - -#include - -static CDROM iso_cdrom; - -int cdrom_iso_do_log = 0; - -void cdrom_iso_log(const char *format, ...) -{ -#ifdef ENABLE_CDROM_ISO_LOG - if (cdrom_iso_do_log) - { - va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } -#endif -} - -void iso_close(uint8_t id); - -void iso_audio_callback(uint8_t id, int16_t *output, int len) -{ - memset(output, 0, len * 2); - return; -} - -void iso_audio_stop(uint8_t id) -{ - return; -} - -static int iso_ready(uint8_t id) -{ - if (wcslen(cdrom_iso[id].iso_path) == 0) - { - return 0; - } - if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) - { - return 1; - } - - if (cdrom_iso[id].iso_changed) - { - cdrom_iso[id].iso_changed = 0; - return 1; - } - - return 1; -} - -static int iso_medium_changed(uint8_t id) -{ - if (wcslen(cdrom_iso[id].iso_path) == 0) - { - return 0; - } - - if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) - { - cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; - return 1; - } - - if (cdrom_iso[id].iso_changed) - { - cdrom_iso[id].iso_changed = 0; - return 1; - } - - 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 uint8_t iso_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) -{ - int pos=0; - int32_t temp; - if (wcslen(cdrom_iso[id].iso_path) == 0) - { - return 0; - } - - b[pos++]=0; - b[pos++]=0; - b[pos++]=0; - - temp = cdrom[id].seek_pos; - if (msf) - { - memset(&(b[pos]), 0, 8); - lba_to_msf(&(b[pos]), temp); - pos += 4; - lba_to_msf(&(b[pos]), temp); - pos += 4; - } - else - { - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - b[pos++] = temp >> 24; - b[pos++] = temp >> 16; - b[pos++] = temp >> 8; - b[pos++] = temp; - } - - return 0x15; -} - -static void iso_eject(uint8_t id) -{ - return; -} - -static void iso_load(uint8_t id) -{ - return; -} - -static int iso_sector_data_type(uint8_t id, int sector, int ismsf) -{ - return 2; /* Always Mode 1 */ -} - -static void iso_readsector(uint8_t id, uint8_t *b, int sector) -{ - uint64_t file_pos = sector; - if (!cdrom_drives[id].host_drive) - { - return; - } - file_pos <<= 11; - memset(b, 0, 2856); - cdrom_iso[id].iso_image = _wfopen(cdrom_iso[id].iso_path, L"rb"); - fseeko64(cdrom_iso[id].iso_image, file_pos, SEEK_SET); - fread(b + 16, 2048, 1, cdrom_iso[id].iso_image); - fclose(cdrom_iso[id].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); - b += 288; - memset(b, 0, 392); -} - -typedef struct __attribute__((__packed__)) -{ - uint8_t user_data[2048]; - uint8_t ecc[288]; -} m1_data_t; - -typedef struct __attribute__((__packed__)) -{ - uint8_t sub_header[8]; - uint8_t user_data[2328]; -} m2_data_t; - -typedef union __attribute__((__packed__)) -{ - m1_data_t m1_data; - m2_data_t m2_data; - uint8_t raw_data[2352]; -} sector_data_t; - -typedef struct __attribute__((__packed__)) -{ - uint8_t sync[12]; - uint8_t header[4]; - sector_data_t data; - uint8_t c2[296]; - uint8_t subchannel_raw[96]; - uint8_t subchannel_q[16]; - uint8_t subchannel_rw[96]; -} cdrom_sector_t; - -typedef union __attribute__((__packed__)) -{ - cdrom_sector_t cdrom_sector; - uint8_t buffer[2856]; -} sector_buffer_t; - -sector_buffer_t cdrom_sector_buffer; - -int cdrom_sector_size; - -static int iso_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) -{ - uint8_t *b; - uint8_t *temp_b; - int real_pos; - - b = temp_b = buffer; - - *len = 0; - - if (ismsf) - { - real_pos = cdrom_lba_to_msf_accurate(sector); - } - else - { - real_pos = sector; - } - - memset(cdrom_sector_buffer.buffer, 0, 2856); - - if ((cdrom_sector_type == 1) || (cdrom_sector_type > 2)) - { - if (cdrom_sector_type == 1) - { - cdrom_iso_log("CD-ROM %i: Attempting to read an audio sector from an ISO\n", id); - } - if (cdrom_sector_type >= 2) - { - cdrom_iso_log("CD-ROM %i: Attempting to read a non-mode 1 data sector from an ISO\n", id); - } - return 0; - } - - if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ - { - cdrom_iso_log("CD-ROM %i: 0x00 and 0x08 are illegal modes\n", id); - return 0; - } - - if ((cdrom_sector_flags & 0x06) == 0x06) - { - cdrom_iso_log("CD-ROM %i: Invalid error flags\n", id); - return 0; - } - - if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) - { - cdrom_iso_log("CD-ROM %i: Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); - return 0; - } - - if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ - { - cdrom_iso_log("CD-ROM %i: EDC/ECC without user data is an illegal mode\n", id); - return 0; - } - - iso_readsector(id, cdrom_sector_buffer.buffer, real_pos); - - cdrom_sector_size = 0; - - if (cdrom_sector_flags & 0x80) /* Sync */ - { - cdrom_iso_log("CD-ROM %i: Sync\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.sync, 12); - cdrom_sector_size += 12; - temp_b += 12; - } - if (cdrom_sector_flags & 0x20) /* Header */ - { - cdrom_iso_log("CD-ROM %i: Header\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.header, 4); - cdrom_sector_size += 4; - temp_b += 4; - } - - /* Mode 1 sector, expected type is 1 type. */ - if (cdrom_sector_flags & 0x40) /* Sub-header */ - { - if (!(cdrom_sector_flags & 0x10)) /* No user data */ - { - cdrom_iso_log("CD-ROM %i: Sub-header\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 8); - cdrom_sector_size += 8; - temp_b += 8; - } - } - if (cdrom_sector_flags & 0x10) /* User data */ - { - cdrom_iso_log("CD-ROM %i: User data\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.user_data, 2048); - cdrom_sector_size += 2048; - temp_b += 2048; - } - if (cdrom_sector_flags & 0x08) /* EDC/ECC */ - { - cdrom_iso_log("CD-ROM %i: EDC/ECC\n", id); - memcpy(temp_b, cdrom_sector_buffer.cdrom_sector.data.m1_data.ecc, 288); - cdrom_sector_size += 288; - temp_b += 288; - } - - if ((cdrom_sector_flags & 0x06) == 0x02) - { - /* Add error flags. */ - cdrom_iso_log("CD-ROM %i: Error flags\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 294); - cdrom_sector_size += 294; - } - else if ((cdrom_sector_flags & 0x06) == 0x04) - { - /* Add error flags. */ - cdrom_iso_log("CD-ROM %i: Full error flags\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.c2, 296); - cdrom_sector_size += 296; - } - - if ((cdrom_sector_flags & 0x700) == 0x100) - { - cdrom_iso_log("CD-ROM %i: Raw subchannel data\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_raw, 96); - cdrom_sector_size += 96; - } - else if ((cdrom_sector_flags & 0x700) == 0x200) - { - cdrom_iso_log("CD-ROM %i: Q subchannel data\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_q, 16); - cdrom_sector_size += 16; - } - else if ((cdrom_sector_flags & 0x700) == 0x400) - { - cdrom_iso_log("CD-ROM %i: R/W subchannel data\n", id); - memcpy(b + cdrom_sector_size, cdrom_sector_buffer.cdrom_sector.subchannel_rw, 96); - cdrom_sector_size += 96; - } - - *len = cdrom_sector_size; - - return 1; -} - -static int iso_readtoc(uint8_t id, 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 */ - cdrom_iso[id].last_block = cdrom_iso[id].image_size >> 11; - if (msf) { - *q++ = 0; /* reserved */ - lba_to_msf(q, cdrom_iso[id].last_block); - q += 3; - } else { - *q++ = cdrom_iso[id].last_block >> 24; - *q++ = cdrom_iso[id].last_block >> 16; - *q++ = cdrom_iso[id].last_block >> 8; - *q++ = cdrom_iso[id].last_block; - } - len = q - buf; - if (len > maxlen) - { - len = maxlen; - } - buf[0] = (uint8_t)(((len-2) >> 8) & 0xff); - buf[1] = (uint8_t)((len-2) & 0xff); - return len; -} - -static int iso_readtoc_session(uint8_t id, 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; - - if (maxlen < 12) - { - return maxlen; - } - return 12; -} - -static int iso_readtoc_raw(uint8_t id, unsigned char *buf, int msf, 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 */ - cdrom_iso[id].last_block = cdrom_iso[id].image_size >> 11; - /* this is raw, must be msf */ - if (msf) - { - *q++ = 0; /* reserved */ - lba_to_msf(q, cdrom_iso[id].last_block); - q += 3; - } - else - { - *q++ = (cdrom_iso[id].last_block >> 24) & 0xff; - *q++ = (cdrom_iso[id].last_block >> 16) & 0xff; - *q++ = (cdrom_iso[id].last_block >> 8) & 0xff; - *q++ = cdrom_iso[id].last_block & 0xff; - } - - *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 */ - if (msf) - { - *q++ = 0; /* reserved */ - lba_to_msf(q, 0); - q += 3; - } - else - { - *q++ = 0; - *q++ = 0; - *q++ = 0; - *q++ = 0; - } - - len = q - buf; - if (len > maxlen) - { - len = maxlen; - } - buf[0] = (uint8_t)(((len-2) >> 8) & 0xff); - buf[1] = (uint8_t)((len-2) & 0xff); - return len; -} - -static uint32_t iso_size(uint8_t id) -{ - uint64_t iso_size; - - cdrom_iso[id].iso_image = _wfopen(cdrom_iso[id].iso_path, L"rb"); - fseeko64(cdrom_iso[id].iso_image, 0, SEEK_END); - iso_size = ftello64(cdrom_iso[id].iso_image); - iso_size >>= 11; - fclose(cdrom_iso[id].iso_image); - - return (uint32_t) (iso_size); -} - -static int iso_status(uint8_t id) -{ - if (!(iso_ready(id)) && (cdrom_drives[id].host_drive != 200)) return CD_STATUS_EMPTY; - - return CD_STATUS_DATA_ONLY; -} - -void iso_reset(uint8_t id) -{ -} - -int iso_open(uint8_t id, wchar_t *fn) -{ - FILE *f; - - if (wcscmp(fn, cdrom_iso[id].iso_path) != 0) - { - cdrom_iso[id].iso_changed = 1; - } - /* Make sure iso_changed stays when changing from ISO to another ISO. */ - if (!cdrom_iso[id].iso_inited && (cdrom_drives[id].host_drive != 200)) cdrom_iso[id].iso_changed = 0; - if (!cdrom_iso[id].iso_inited || cdrom_iso[id].iso_changed) - { - _swprintf(cdrom_iso[id].iso_path, L"%ws", fn); - } - cdrom_iso[id].iso_image = _wfopen(cdrom_iso[id].iso_path, L"rb"); - cdrom_drives[id].handler = &iso_cdrom; - if (!cdrom_iso[id].iso_inited || cdrom_iso[id].iso_changed) - { - if (!cdrom_iso[id].iso_inited) cdrom_iso[id].iso_inited = 1; - fclose(cdrom_iso[id].iso_image); - } - - f = _wfopen(cdrom_iso[id].iso_path, L"rb"); - fseeko64(f, 0, SEEK_END); - cdrom_iso[id].image_size = ftello64(f); - fclose(f); - - return 0; -} - -void iso_close(uint8_t id) -{ - if (cdrom_iso[id].iso_image) fclose(cdrom_iso[id].iso_image); - memset(cdrom_iso[id].iso_path, 0, 1024); -} - -static void iso_exit(uint8_t id) -{ - cdrom_iso[id].iso_inited = 0; -} - -static int iso_is_track_audio(uint8_t id, uint32_t pos, int ismsf) -{ - return 0; -} - -static int iso_media_type_id(uint8_t id) -{ - if (iso_size(id) <= 405000) - { - return 1; /* Data CD. */ - } - else - { - return 65; /* DVD. */ - } -} - -static CDROM iso_cdrom = -{ - iso_ready, - iso_medium_changed, - iso_media_type_id, - NULL, - NULL, - iso_readtoc, - iso_readtoc_session, - iso_readtoc_raw, - iso_getcurrentsubchannel, - NULL, - iso_sector_data_type, - iso_readsector_raw, - NULL, - iso_load, - iso_eject, - NULL, - NULL, - iso_size, - iso_status, - iso_is_track_audio, - NULL, - iso_exit -}; diff --git a/src/cdrom-iso.h b/src/cdrom-iso.h deleted file mode 100644 index fa7b734fa..000000000 --- a/src/cdrom-iso.h +++ /dev/null @@ -1,15 +0,0 @@ -/* Copyright holders: RichardG867, Tenshi - see COPYING for more details -*/ -#ifndef CDROM_ISO_H -#define CDROM_ISO_H - -/* this header file lists the functions provided by - various platform specific cdrom-ioctl files */ - -extern int iso_open(uint8_t id, wchar_t *fn); -extern void iso_reset(uint8_t id); - -extern void iso_close(uint8_t id); - -#endif /* ! CDROM_ISO_H */ diff --git a/src/cdrom-null.c b/src/cdrom-null.c index 9c52cc848..e5a8caf2d 100644 --- a/src/cdrom-null.c +++ b/src/cdrom-null.c @@ -31,11 +31,6 @@ static void null_load(uint8_t id) { } -static int null_sector_data_type(uint8_t id, int sector, int ismsf) -{ - return 0; -} - static int null_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) { *len = 0; @@ -100,28 +95,34 @@ static int null_media_type_id(uint8_t id) return 0x70; } +void cdrom_set_null_handler(uint8_t id) +{ + cdrom_drives[id].handler = &null_cdrom; + cdrom_drives[id].host_drive = 0; + update_status_bar_icon_state(0x10 | id, 1); +} + static CDROM null_cdrom = { - null_ready, - null_medium_changed, - null_media_type_id, - NULL, - NULL, + null_ready, + null_medium_changed, + null_media_type_id, + NULL, + NULL, null_readtoc, null_readtoc_session, - null_readtoc_raw, + null_readtoc_raw, null_getcurrentsubchannel, null_pass_through, - null_sector_data_type, - null_readsector_raw, + null_readsector_raw, NULL, null_load, null_eject, NULL, NULL, null_size, - null_status, - null_is_track_audio, + null_status, + null_is_track_audio, NULL, null_exit }; diff --git a/src/cdrom.c b/src/cdrom.c index 09f55ac4d..bb286451f 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -2893,8 +2893,7 @@ void cdrom_command(uint8_t id, uint8_t *cdb) break; } - if ((cdrom_drive < 1) || (cdrom_drive == CDROM_ISO) || (cdrom[id].cd_status <= CD_STATUS_DATA_ONLY) || - !cdrom_drives[id].handler->is_track_audio(id, pos, msf)) + if ((cdrom_drive < 1) || (cdrom[id].cd_status <= CD_STATUS_DATA_ONLY) || !cdrom_drives[id].handler->is_track_audio(id, pos, msf)) { cdrom_illegal_mode(id); break; diff --git a/src/cdrom.h b/src/cdrom.h index 85f03a4b0..678b64086 100644 --- a/src/cdrom.h +++ b/src/cdrom.h @@ -15,7 +15,7 @@ #define BUF_SIZE 32768 -#define CDROM_ISO 200 +#define CDROM_IMAGE 200 #define IDE_TIME (5 * 100 * (1 << TIMER_SHIFT)) #define CDROM_TIME (5 * 100 * (1 << TIMER_SHIFT)) @@ -32,7 +32,6 @@ typedef struct CDROM int (*readtoc_raw)(uint8_t id, uint8_t *b, int msf, int maxlen); uint8_t (*getcurrentsubchannel)(uint8_t id, uint8_t *b, int msf); int (*pass_through)(uint8_t id, uint8_t *in_cdb, uint8_t *b, uint32_t *len); - int (*sector_data_type)(uint8_t id, int sector, int ismsf); int (*readsector_raw)(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len); void (*playaudio)(uint8_t id, uint32_t pos, uint32_t len, int ismsf); void (*load)(uint8_t id); @@ -170,18 +169,23 @@ extern void (*ide_bus_master_set_irq)(int channel); typedef struct { - uint32_t last_block; - uint64_t image_size; - int iso_inited; - wchar_t iso_path[1024]; - FILE* iso_image; - int iso_changed; + int image_is_iso; + uint32_t last_block; + uint32_t cdrom_capacity; + int image_inited; + wchar_t image_path[1024]; + FILE* image; + int image_changed; + + int cd_state; uint32_t cd_pos; uint32_t cd_end; -} cdrom_iso_t; + int16_t cd_buffer[BUF_SIZE]; + int cd_buflen; +} cdrom_image_t; -cdrom_iso_t cdrom_iso[CDROM_NUM]; +cdrom_image_t cdrom_image[CDROM_NUM]; typedef struct { @@ -211,7 +215,17 @@ void cdrom_command(uint8_t id, uint8_t *cdb); void cdrom_phase_callback(uint8_t id); uint32_t cdrom_read(uint8_t channel, int length); void cdrom_write(uint8_t channel, uint32_t val, int length); + +#ifdef __cplusplus +extern "C" { +#endif + int cdrom_lba_to_msf_accurate(int lba); + +#ifdef __cplusplus +} +#endif + void cdrom_reset(uint8_t id); void cdrom_set_signature(int id); void cdrom_request_sense_for_scsi(uint8_t id, uint8_t *buffer, uint8_t alloc_length); diff --git a/src/config.c b/src/config.c index c72de4da8..f52cfd978 100644 --- a/src/config.c +++ b/src/config.c @@ -2,11 +2,33 @@ see COPYING for more details */ #include +#include #include #include #include + +#include "cdrom.h" #include "config.h" +#include "device.h" +#include "disc.h" +#include "fdc.h" +#include "fdd.h" #include "ibm.h" +#include "cpu/cpu.h" +#include "gameport.h" +#include "ide.h" +#include "hdd.h" +#include "model.h" +#include "mouse.h" +#include "network.h" +#include "net_ne2000.h" +#include "nvr.h" +#include "plat-joystick.h" +#include "scsi.h" +#include "sound/snd_dbopl.h" +#include "sound/snd_opl.h" +#include "sound/sound.h" +#include "video/video.h" wchar_t config_file_default[256]; @@ -495,3 +517,427 @@ void config_save(wchar_t *fn) fclose(f); } +void loadconfig(wchar_t *fn) +{ + int c, d; + char s[512]; + char *p; + wchar_t *wp, *wq; + char temps[512]; + + if (!fn) + config_load(config_file_default); + else + config_load(fn); + + GAMEBLASTER = config_get_int(NULL, "gameblaster", 0); + GUS = config_get_int(NULL, "gus", 0); + SSI2001 = config_get_int(NULL, "ssi2001", 0); + voodoo_enabled = config_get_int(NULL, "voodoo", 0); + + /* SCSI */ + p = (char *)config_get_string(NULL, "scsicard", ""); + if (p) + scsi_card_current = scsi_card_get_from_internal_name(p); + else + scsi_card_current = 0; + + /* network */ + ethif = config_get_int(NULL, "netinterface", 1); + if (ethif >= inum) + inum = ethif + 1; + p = (char *)config_get_string(NULL, "netcard", ""); + if (p) + network_card_current = network_card_get_from_internal_name(p); + else + network_card_current = 0; + ne2000_generate_maclocal(config_get_int(NULL, "maclocal", -1)); + ne2000_generate_maclocal_pci(config_get_int(NULL, "maclocal_pci", -1)); + + p = (char *)config_get_string(NULL, "model", ""); + if (p) + model = model_get_model_from_internal_name(p); + else + model = 0; + + if (model >= model_count()) + model = model_count() - 1; + + romset = model_getromset(); + cpu_manufacturer = config_get_int(NULL, "cpu_manufacturer", 0); + cpu = config_get_int(NULL, "cpu", 0); + cpu_use_dynarec = config_get_int(NULL, "cpu_use_dynarec", 0); + + cpu_waitstates = config_get_int(NULL, "cpu_waitstates", 0); + + p = (char *)config_get_string(NULL, "gfxcard", ""); + if (p) + gfxcard = video_get_video_from_internal_name(p); + else + gfxcard = 0; + video_speed = config_get_int(NULL, "video_speed", 3); + p = (char *)config_get_string(NULL, "sndcard", ""); + if (p) + sound_card_current = sound_card_get_from_internal_name(p); + else + sound_card_current = 0; + + mem_size = config_get_int(NULL, "mem_size", 4096); + if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) + mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); + + for (c = 0; c < FDD_NUM; c++) + { + sprintf(temps, "fdd_%02i_type", c + 1); + p = (char *)config_get_string(NULL, temps, (c < 2) ? "525_2dd" : "none"); + if (p) + fdd_set_type(c, fdd_get_from_internal_name(p)); + else + fdd_set_type(c, (c < 2) ? 2 : 0); + + sprintf(temps, "fdd_%02i_fn", c + 1); + wp = (wchar_t *)config_get_wstring(NULL, temps, L""); + if (wp) memcpy(discfns[c], wp, 512); + else { + memcpy(discfns[c], L"", 2); + discfns[c][0] = L'\0'; + } + printf("Floppy: %ws\n", discfns[c]); + sprintf(temps, "fdd_%02i_writeprot", c + 1); + ui_writeprot[c] = config_get_int(NULL, temps, 0); + } + + p = (char *)config_get_string(NULL, "hdd_controller", ""); + if (p) + strncpy(hdd_controller_name, p, sizeof(hdd_controller_name)-1); + else + strncpy(hdd_controller_name, "none", sizeof(hdd_controller_name)-1); + + memset(temps, 0, 512); + for (c = 2; c < 4; c++) + { + sprintf(temps, "ide_%02i_enable", c + 1); + ide_enable[c] = config_get_int(NULL, temps, 0); + sprintf(temps, "ide_%02i_irq", c + 1); + ide_irq[c] = config_get_int(NULL, temps, 8 + c); + } + + memset(temps, 0, 512); + for (c = 0; c < HDC_NUM; c++) + { + sprintf(temps, "hdd_%02i_sectors", c + 1); + hdc[c].spt = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_heads", c + 1); + hdc[c].hpc = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_cylinders", c + 1); + hdc[c].tracks = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_bus_type", c + 1); + hdc[c].bus = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_mfm_channel", c + 1); + hdc[c].mfm_channel = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_ide_channel", c + 1); + hdc[c].ide_channel = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); + hdc[c].scsi_id = config_get_int(NULL, temps, (c < 7) ? c : ((c < 15) ? (c + 1) : 15)); + sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); + hdc[c].scsi_lun = config_get_int(NULL, temps, 0); + sprintf(temps, "hdd_%02i_fn", c + 1); + wp = (wchar_t *)config_get_wstring(NULL, temps, L""); + if (wp) memcpy(hdd_fn[c], wp, 512); + else { + memcpy(hdd_fn[c], L"", 2); + hdd_fn[c][0] = L'\0'; + } + } + + memset(temps, 0, 512); + for (c = 0; c < CDROM_NUM; c++) + { + sprintf(temps, "cdrom_%02i_host_drive", c + 1); + cdrom_drives[c].host_drive = config_get_int(NULL, temps, 0); + cdrom_drives[c].prev_host_drive = cdrom_drives[c].host_drive; + sprintf(temps, "cdrom_%02i_enabled", c + 1); + cdrom_drives[c].enabled = config_get_int(NULL, temps, 0); + sprintf(temps, "cdrom_%02i_sound_on", c + 1); + cdrom_drives[c].sound_on = config_get_int(NULL, temps, 1); + sprintf(temps, "cdrom_%02i_bus_type", c + 1); + cdrom_drives[c].bus_type = config_get_int(NULL, temps, 0); + sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); + cdrom_drives[c].atapi_dma = config_get_int(NULL, temps, 0); + sprintf(temps, "cdrom_%02i_ide_channel", c + 1); + cdrom_drives[c].ide_channel = config_get_int(NULL, temps, 2); + sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); + cdrom_drives[c].scsi_device_id = config_get_int(NULL, temps, c + 2); + sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); + cdrom_drives[c].scsi_device_lun = config_get_int(NULL, temps, 0); + + sprintf(temps, "cdrom_%02i_image_path", c + 1); + wp = (wchar_t *)config_get_wstring(NULL, temps, L""); + if (wp) memcpy(cdrom_image[c].image_path, wp, 512); + else { + memcpy(cdrom_image[c].image_path, L"", 2); + cdrom_image[c].image_path[0] = L'\0'; + } + } + + vid_resize = config_get_int(NULL, "vid_resize", 0); + vid_api = config_get_int(NULL, "vid_api", 0); + video_fullscreen_scale = config_get_int(NULL, "video_fullscreen_scale", 0); + video_fullscreen_first = config_get_int(NULL, "video_fullscreen_first", 1); + + force_43 = config_get_int(NULL, "force_43", 0); + scale = config_get_int(NULL, "scale", 1); + enable_overscan = config_get_int(NULL, "enable_overscan", 0); + + enable_sync = config_get_int(NULL, "enable_sync", 1); + opl3_type = config_get_int(NULL, "opl3_type", 1); + + window_w = config_get_int(NULL, "window_w", 0); + window_h = config_get_int(NULL, "window_h", 0); + window_x = config_get_int(NULL, "window_x", 0); + window_y = config_get_int(NULL, "window_y", 0); + window_remember = config_get_int(NULL, "window_remember", 0); + + joystick_type = config_get_int(NULL, "joystick_type", 0); + p = (char *)config_get_string(NULL, "mouse_type", ""); + if (p) + mouse_type = mouse_get_from_internal_name(p); + else + mouse_type = 0; + + enable_xtide = config_get_int(NULL, "enable_xtide", 1); + enable_external_fpu = config_get_int(NULL, "enable_external_fpu", 0); + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + sprintf(s, "joystick_%i_nr", c); + joystick_state[c].plat_joystick_nr = config_get_int("Joysticks", s, 0); + + if (joystick_state[c].plat_joystick_nr) + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_axis_%i", c, d); + joystick_state[c].axis_mapping[d] = config_get_int("Joysticks", s, d); + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_button_%i", c, d); + joystick_state[c].button_mapping[d] = config_get_int("Joysticks", s, d); + } + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_pov_%i_x", c, d); + joystick_state[c].pov_mapping[d][0] = config_get_int("Joysticks", s, d); + sprintf(s, "joystick_%i_pov_%i_y", c, d); + joystick_state[c].pov_mapping[d][1] = config_get_int("Joysticks", s, d); + } + } + } + + memset(nvr_path, 0, 2048); + wp = (wchar_t *)config_get_wstring(NULL, "nvr_path", L""); + if (wp) { + if (wcslen(wp) && (wcslen(wp) <= 992)) wcscpy(nvr_path, wp); + else + { + append_filename_w(nvr_path, pcempath, L"nvr", 511); + } + } + else append_filename_w(nvr_path, pcempath, L"nvr", 511); + + if (nvr_path[wcslen(nvr_path) - 1] != L'/') + { + if (nvr_path[wcslen(nvr_path) - 1] != L'\\') + { + nvr_path[wcslen(nvr_path)] = L'/'; + nvr_path[wcslen(nvr_path) + 1] = L'\0'; + } + } + + path_len = wcslen(nvr_path); + + serial_enabled[0] = config_get_int(NULL, "serial1_enabled", 1); + serial_enabled[1] = config_get_int(NULL, "serial2_enabled", 1); + lpt_enabled = config_get_int(NULL, "lpt_enabled", 1); + bugger_enabled = config_get_int(NULL, "bugger_enabled", 0); +} + +wchar_t temp_nvr_path[1024]; + +wchar_t *nvr_concat(wchar_t *to_concat) +{ + char *p; + + memset(temp_nvr_path, 0, 2048); + wcscpy(temp_nvr_path, nvr_path); + + p = (char *) temp_nvr_path; + p += (path_len * 2); + wchar_t *wp = (wchar_t *) p; + + wcscpy(wp, to_concat); + return temp_nvr_path; +} + +void saveconfig(void) +{ + int c, d; + + char temps[512]; + + config_set_int(NULL, "gameblaster", GAMEBLASTER); + config_set_int(NULL, "gus", GUS); + config_set_int(NULL, "ssi2001", SSI2001); + config_set_int(NULL, "voodoo", voodoo_enabled); + + config_set_string(NULL, "scsicard", scsi_card_get_internal_name(scsi_card_current)); + + config_set_int(NULL, "netinterface", ethif); + config_set_string(NULL, "netcard", network_card_get_internal_name(network_card_current)); + config_set_int(NULL, "maclocal", net2000_get_maclocal()); + config_set_int(NULL, "maclocal_pci", net2000_get_maclocal_pci()); + + config_set_string(NULL, "model", model_get_internal_name()); + config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer); + config_set_int(NULL, "cpu", cpu); + config_set_int(NULL, "cpu_use_dynarec", cpu_use_dynarec); + config_set_int(NULL, "cpu_waitstates", cpu_waitstates); + + config_set_string(NULL, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); + config_set_int(NULL, "video_speed", video_speed); + config_set_string(NULL, "sndcard", sound_card_get_internal_name(sound_card_current)); + config_set_int(NULL, "cpu_speed", cpuspeed); + config_set_int(NULL, "has_fpu", hasfpu); + + config_set_int(NULL, "mem_size", mem_size); + + memset(temps, 0, 512); + for (c = 0; c < FDD_NUM; c++) + { + sprintf(temps, "fdd_%02i_type", c + 1); + config_set_string(NULL, temps, fdd_get_internal_name(fdd_get_type(c))); + sprintf(temps, "fdd_%02i_fn", c + 1); + config_set_wstring(NULL, temps, discfns[c]); + sprintf(temps, "fdd_%02i_writeprot", c + 1); + config_set_int(NULL, temps, ui_writeprot[c]); + } + + config_set_string(NULL, "hdd_controller", hdd_controller_name); + + memset(temps, 0, 512); + for (c = 2; c < 4; c++) + { + sprintf(temps, "ide_%02i_enable", c + 1); + config_set_int(NULL, temps, ide_enable[c]); + sprintf(temps, "ide_%02i_irq", c + 1); + config_set_int(NULL, temps, ide_irq[c]); + } + + memset(temps, 0, 512); + for (c = 0; c < HDC_NUM; c++) + { + sprintf(temps, "hdd_%02i_sectors", c + 1); + config_set_int(NULL, temps, hdc[c].spt); + sprintf(temps, "hdd_%02i_heads", c + 1); + config_set_int(NULL, temps, hdc[c].hpc); + sprintf(temps, "hdd_%02i_cylinders", c + 1); + config_set_int(NULL, temps, hdc[c].tracks); + sprintf(temps, "hdd_%02i_bus_type", c + 1); + config_set_int(NULL, temps, hdc[c].bus); + sprintf(temps, "hdd_%02i_mfm_channel", c + 1); + config_set_int(NULL, temps, hdc[c].mfm_channel); + sprintf(temps, "hdd_%02i_ide_channel", c + 1); + config_set_int(NULL, temps, hdc[c].ide_channel); + sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); + config_set_int(NULL, temps, hdc[c].scsi_id); + sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); + config_set_int(NULL, temps, hdc[c].scsi_lun); + sprintf(temps, "hdd_%02i_fn", c + 1); + config_set_wstring(NULL, temps, hdd_fn[c]); + } + + memset(temps, 0, 512); + for (c = 0; c < CDROM_NUM; c++) + { + sprintf(temps, "cdrom_%02i_host_drive", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].host_drive); + sprintf(temps, "cdrom_%02i_enabled", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].enabled); + sprintf(temps, "cdrom_%02i_sound_on", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].sound_on); + sprintf(temps, "cdrom_%02i_bus_type", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].bus_type); + sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].atapi_dma); + sprintf(temps, "cdrom_%02i_ide_channel", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].ide_channel); + sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].scsi_device_id); + sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); + config_set_int(NULL, temps, cdrom_drives[c].scsi_device_lun); + + sprintf(temps, "cdrom_%02i_image_path", c + 1); + config_set_wstring(NULL, temps, cdrom_image[c].image_path); + } + + config_set_int(NULL, "vid_resize", vid_resize); + config_set_int(NULL, "vid_api", vid_api); + config_set_int(NULL, "video_fullscreen_scale", video_fullscreen_scale); + config_set_int(NULL, "video_fullscreen_first", video_fullscreen_first); + + config_set_int(NULL, "force_43", force_43); + config_set_int(NULL, "scale", scale); + config_set_int(NULL, "enable_overscan", enable_overscan); + + config_set_int(NULL, "enable_sync", enable_sync); + config_set_int(NULL, "opl3_type", opl3_type); + + config_set_int(NULL, "joystick_type", joystick_type); + config_set_string(NULL, "mouse_type", mouse_get_internal_name(mouse_type)); + + config_set_int(NULL, "enable_xtide", enable_xtide); + config_set_int(NULL, "enable_external_fpu", enable_external_fpu); + + for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) + { + char s[80]; + + sprintf(s, "joystick_%i_nr", c); + config_set_int("Joysticks", s, joystick_state[c].plat_joystick_nr); + + if (joystick_state[c].plat_joystick_nr) + { + for (d = 0; d < joystick_get_axis_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_axis_%i", c, d); + config_set_int("Joysticks", s, joystick_state[c].axis_mapping[d]); + } + for (d = 0; d < joystick_get_button_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_button_%i", c, d); + config_set_int("Joysticks", s, joystick_state[c].button_mapping[d]); + } + for (d = 0; d < joystick_get_pov_count(joystick_type); d++) + { + sprintf(s, "joystick_%i_pov_%i_x", c, d); + config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][0]); + sprintf(s, "joystick_%i_pov_%i_y", c, d); + config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][1]); + } + } + } + + config_set_int(NULL, "window_w", window_w); + config_set_int(NULL, "window_h", window_h); + config_set_int(NULL, "window_x", window_x); + config_set_int(NULL, "window_y", window_y); + config_set_int(NULL, "window_remember", window_remember); + + config_set_int(NULL, "serial1_enabled", serial_enabled[0]); + config_set_int(NULL, "serial2_enabled", serial_enabled[1]); + config_set_int(NULL, "lpt_enabled", lpt_enabled); + config_set_int(NULL, "bugger_enabled", bugger_enabled); + + config_save(config_file_default); +} diff --git a/src/config.h b/src/config.h index feab20d60..766257f37 100644 --- a/src/config.h +++ b/src/config.h @@ -15,11 +15,23 @@ void append_filename_w(wchar_t *dest, wchar_t *s1, wchar_t *s2, int size); void put_backslash(char *s); void put_backslash_w(wchar_t *s); char *get_extension(char *s); + +#ifdef __cplusplus +extern "C" { +#endif + wchar_t *get_extension_w(wchar_t *s); +#ifdef __cplusplus +} +#endif + void config_load(wchar_t *fn); void config_save(wchar_t *fn); void config_dump(void); void config_free(void); extern wchar_t config_file_default[256]; + +void loadconfig(wchar_t *fn); +void saveconfig(void); diff --git a/src/fdc37c932fr.c b/src/fdc37c932fr.c index 96469ef5b..5b4057d1e 100644 --- a/src/fdc37c932fr.c +++ b/src/fdc37c932fr.c @@ -443,6 +443,7 @@ void fdc37c932fr_reset(void) fdc37c932fr_ld_regs[4][0x61] = 0xf8; fdc37c932fr_ld_regs[4][0x70] = 4; fdc37c932fr_ld_regs[4][0xF0] = 3; + serial_setup(1, 0x3f8, fdc37c932fr_ld_regs[4][0x70]); /* Logical device 5: Serial Port 2 */ fdc37c932fr_ld_regs[5][0x30] = 1; @@ -452,6 +453,7 @@ void fdc37c932fr_reset(void) fdc37c932fr_ld_regs[5][0x74] = 4; fdc37c932fr_ld_regs[5][0xF1] = 2; fdc37c932fr_ld_regs[5][0xF2] = 3; + serial_setup(2, 0x2f8, fdc37c932fr_ld_regs[5][0x70]); /* Logical device 6: RTC */ fdc37c932fr_ld_regs[6][0x63] = 0x70; diff --git a/src/ibm.h b/src/ibm.h index c163e5f15..668462244 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -676,8 +676,6 @@ uint64_t timer_read(); extern uint64_t timer_freq; -void loadconfig(wchar_t *fn); - extern int infocus; void onesec(); diff --git a/src/network.c b/src/network.c index 5f4a3f95e..861a09ded 100644 --- a/src/network.c +++ b/src/network.c @@ -39,6 +39,9 @@ static NETCARD net_cards[] = { int network_card_current = 0; +uint8_t ethif; +int inum; + static void net_poll(void *priv) diff --git a/src/network.h b/src/network.h index 59c379a64..559be9e34 100644 --- a/src/network.h +++ b/src/network.h @@ -12,6 +12,9 @@ extern int network_card_current; +extern uint8_t ethif; +extern int inum; + extern void network_init(void); extern void network_reset(void); diff --git a/src/pc.c b/src/pc.c index b2a2c7a82..67a088d2e 100644 --- a/src/pc.c +++ b/src/pc.c @@ -36,7 +36,7 @@ #include "hdd.h" #include "ide.h" #include "cdrom.h" -#include "cdrom-iso.h" +#include "cdrom-image.h" #include "cdrom-null.h" #include "scsi.h" #include "keyboard.h" @@ -70,9 +70,6 @@ #endif -uint8_t ethif; -int inum; - wchar_t nvr_path[1024]; int path_len; @@ -373,17 +370,7 @@ void initpc(int argc, wchar_t *argv[]) { if (cdrom_drives[i].host_drive == 200) { - ff = _wfopen(cdrom_iso[i].iso_path, L"rb"); - if (ff) - { - fclose(ff); - iso_open(i, cdrom_iso[i].iso_path); - } - else - { - cdrom_drives[i].host_drive = 0; - cdrom_null_open(i, cdrom_drives[i].host_drive); - } + image_open(i, cdrom_image[i].image_path); } else { @@ -422,7 +409,7 @@ void initpc(int argc, wchar_t *argv[]) { if (cdrom_drives[i].host_drive == 200) { - iso_reset(i); + image_reset(i); } else { @@ -485,7 +472,6 @@ void resetpchard(void) disc_reset(); model_init(); - mouse_emu_init(); video_init(); speaker_init(); @@ -526,6 +512,7 @@ void resetpchard(void) device_add(&voodoo_device); hdd_controller_init(hdd_controller_name); pc_reset(); + mouse_emu_init(); loadnvr(); @@ -542,7 +529,7 @@ void resetpchard(void) { if (cdrom_drives[i].host_drive == 200) { - iso_reset(i); + image_reset(i); } else { @@ -700,431 +687,3 @@ void closepc(void) device_close_all(); midi_close(); } - - -void loadconfig(wchar_t *fn) -{ - int c, d; - char s[512]; - char *p; - wchar_t *wp, *wq; - char temps[512]; - - if (!fn) - config_load(config_file_default); - else - config_load(fn); - - GAMEBLASTER = config_get_int(NULL, "gameblaster", 0); - GUS = config_get_int(NULL, "gus", 0); - SSI2001 = config_get_int(NULL, "ssi2001", 0); - voodoo_enabled = config_get_int(NULL, "voodoo", 0); - - /* SCSI */ - p = (char *)config_get_string(NULL, "scsicard", ""); - if (p) - scsi_card_current = scsi_card_get_from_internal_name(p); - else - scsi_card_current = 0; - - /* network */ - ethif = config_get_int(NULL, "netinterface", 1); - if (ethif >= inum) - inum = ethif + 1; - p = (char *)config_get_string(NULL, "netcard", ""); - if (p) - network_card_current = network_card_get_from_internal_name(p); - else - network_card_current = 0; - ne2000_generate_maclocal(config_get_int(NULL, "maclocal", -1)); - ne2000_generate_maclocal_pci(config_get_int(NULL, "maclocal_pci", -1)); - - p = (char *)config_get_string(NULL, "model", ""); - if (p) - model = model_get_model_from_internal_name(p); - else - model = 0; - - if (model >= model_count()) - model = model_count() - 1; - - romset = model_getromset(); - cpu_manufacturer = config_get_int(NULL, "cpu_manufacturer", 0); - cpu = config_get_int(NULL, "cpu", 0); - cpu_use_dynarec = config_get_int(NULL, "cpu_use_dynarec", 0); - - cpu_waitstates = config_get_int(NULL, "cpu_waitstates", 0); - - p = (char *)config_get_string(NULL, "gfxcard", ""); - if (p) - gfxcard = video_get_video_from_internal_name(p); - else - gfxcard = 0; - video_speed = config_get_int(NULL, "video_speed", 3); - p = (char *)config_get_string(NULL, "sndcard", ""); - if (p) - sound_card_current = sound_card_get_from_internal_name(p); - else - sound_card_current = 0; - - mem_size = config_get_int(NULL, "mem_size", 4096); - if (mem_size < ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram)) - mem_size = ((models[model].flags & MODEL_AT) ? models[model].min_ram*1024 : models[model].min_ram); - - for (c = 0; c < FDD_NUM; c++) - { - sprintf(temps, "fdd_%02i_type", c + 1); - p = (char *)config_get_string(NULL, temps, (c < 2) ? "525_2dd" : "none"); - if (p) - fdd_set_type(c, fdd_get_from_internal_name(p)); - else - fdd_set_type(c, (c < 2) ? 2 : 0); - - sprintf(temps, "fdd_%02i_fn", c + 1); - wp = (WCHAR *)config_get_wstring(NULL, temps, L""); - if (wp) memcpy(discfns[c], wp, 512); - else { - memcpy(discfns[c], L"", 2); - discfns[c][0] = L'\0'; - } - printf("Floppy: %ws\n", discfns[c]); - sprintf(temps, "fdd_%02i_writeprot", c + 1); - ui_writeprot[c] = config_get_int(NULL, temps, 0); - } - - p = (char *)config_get_string(NULL, "hdd_controller", ""); - if (p) - strncpy(hdd_controller_name, p, sizeof(hdd_controller_name)-1); - else - strncpy(hdd_controller_name, "none", sizeof(hdd_controller_name)-1); - - memset(temps, 0, 512); - for (c = 2; c < 4; c++) - { - sprintf(temps, "ide_%02i_enable", c + 1); - ide_enable[c] = config_get_int(NULL, temps, 0); - sprintf(temps, "ide_%02i_irq", c + 1); - ide_irq[c] = config_get_int(NULL, temps, 8 + c); - } - - memset(temps, 0, 512); - for (c = 0; c < HDC_NUM; c++) - { - sprintf(temps, "hdd_%02i_sectors", c + 1); - hdc[c].spt = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_heads", c + 1); - hdc[c].hpc = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_cylinders", c + 1); - hdc[c].tracks = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_bus_type", c + 1); - hdc[c].bus = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - hdc[c].mfm_channel = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_ide_channel", c + 1); - hdc[c].ide_channel = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); - hdc[c].scsi_id = config_get_int(NULL, temps, (c < 7) ? c : ((c < 15) ? (c + 1) : 15)); - sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); - hdc[c].scsi_lun = config_get_int(NULL, temps, 0); - sprintf(temps, "hdd_%02i_fn", c + 1); - wp = (WCHAR *)config_get_wstring(NULL, temps, L""); - if (wp) memcpy(hdd_fn[c], wp, 512); - else { - memcpy(hdd_fn[c], L"", 2); - hdd_fn[c][0] = L'\0'; - } - } - - memset(temps, 0, 512); - for (c = 0; c < CDROM_NUM; c++) - { - sprintf(temps, "cdrom_%02i_host_drive", c + 1); - cdrom_drives[c].host_drive = config_get_int(NULL, temps, 0); - cdrom_drives[c].prev_host_drive = cdrom_drives[c].host_drive; - sprintf(temps, "cdrom_%02i_enabled", c + 1); - cdrom_drives[c].enabled = config_get_int(NULL, temps, 0); - sprintf(temps, "cdrom_%02i_sound_on", c + 1); - cdrom_drives[c].sound_on = config_get_int(NULL, temps, 1); - sprintf(temps, "cdrom_%02i_bus_type", c + 1); - cdrom_drives[c].bus_type = config_get_int(NULL, temps, 0); - sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); - cdrom_drives[c].atapi_dma = config_get_int(NULL, temps, 0); - sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - cdrom_drives[c].ide_channel = config_get_int(NULL, temps, 2); - sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); - cdrom_drives[c].scsi_device_id = config_get_int(NULL, temps, c + 2); - sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); - cdrom_drives[c].scsi_device_lun = config_get_int(NULL, temps, 0); - - sprintf(temps, "cdrom_%02i_iso_path", c + 1); - wp = (WCHAR *)config_get_wstring(NULL, temps, L""); - if (wp) memcpy(cdrom_iso[c].iso_path, wp, 512); - else { - memcpy(cdrom_iso[c].iso_path, L"", 2); - cdrom_iso[c].iso_path[0] = L'\0'; - } - } - - vid_resize = config_get_int(NULL, "vid_resize", 0); - vid_api = config_get_int(NULL, "vid_api", 0); - video_fullscreen_scale = config_get_int(NULL, "video_fullscreen_scale", 0); - video_fullscreen_first = config_get_int(NULL, "video_fullscreen_first", 1); - - force_43 = config_get_int(NULL, "force_43", 0); - scale = config_get_int(NULL, "scale", 1); - enable_overscan = config_get_int(NULL, "enable_overscan", 0); - enable_flash = config_get_int(NULL, "enable_flash", 1); - - enable_sync = config_get_int(NULL, "enable_sync", 1); - opl3_type = config_get_int(NULL, "opl3_type", 1); - - window_w = config_get_int(NULL, "window_w", 0); - window_h = config_get_int(NULL, "window_h", 0); - window_x = config_get_int(NULL, "window_x", 0); - window_y = config_get_int(NULL, "window_y", 0); - window_remember = config_get_int(NULL, "window_remember", 0); - - joystick_type = config_get_int(NULL, "joystick_type", 0); - p = (char *)config_get_string(NULL, "mouse_type", ""); - if (p) - mouse_type = mouse_get_from_internal_name(p); - else - mouse_type = 0; - - enable_xtide = config_get_int(NULL, "enable_xtide", 1); - enable_external_fpu = config_get_int(NULL, "enable_external_fpu", 0); - - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - sprintf(s, "joystick_%i_nr", c); - joystick_state[c].plat_joystick_nr = config_get_int("Joysticks", s, 0); - - if (joystick_state[c].plat_joystick_nr) - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_axis_%i", c, d); - joystick_state[c].axis_mapping[d] = config_get_int("Joysticks", s, d); - } - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_button_%i", c, d); - joystick_state[c].button_mapping[d] = config_get_int("Joysticks", s, d); - } - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_pov_%i_x", c, d); - joystick_state[c].pov_mapping[d][0] = config_get_int("Joysticks", s, d); - sprintf(s, "joystick_%i_pov_%i_y", c, d); - joystick_state[c].pov_mapping[d][1] = config_get_int("Joysticks", s, d); - } - } - } - - memset(nvr_path, 0, 2048); - wp = (wchar_t *)config_get_wstring(NULL, "nvr_path", L""); - if (wp) { - if (wcslen(wp) && (wcslen(wp) <= 992)) wcscpy(nvr_path, wp); - else - { - append_filename_w(nvr_path, pcempath, L"nvr", 511); - } - } - else append_filename_w(nvr_path, pcempath, L"nvr", 511); - - if (nvr_path[wcslen(nvr_path) - 1] != L'/') - { - if (nvr_path[wcslen(nvr_path) - 1] != L'\\') - { - nvr_path[wcslen(nvr_path)] = L'/'; - nvr_path[wcslen(nvr_path) + 1] = L'\0'; - } - } - - path_len = wcslen(nvr_path); - - serial_enabled[0] = config_get_int(NULL, "serial1_enabled", 1); - serial_enabled[1] = config_get_int(NULL, "serial2_enabled", 1); - lpt_enabled = config_get_int(NULL, "lpt_enabled", 1); - bugger_enabled = config_get_int(NULL, "bugger_enabled", 0); -} - -wchar_t temp_nvr_path[1024]; - -wchar_t *nvr_concat(wchar_t *to_concat) -{ - char *p; - - memset(temp_nvr_path, 0, 2048); - wcscpy(temp_nvr_path, nvr_path); - - p = (char *) temp_nvr_path; - p += (path_len * 2); - wchar_t *wp = (wchar_t *) p; - - wcscpy(wp, to_concat); - return temp_nvr_path; -} - -void saveconfig(void) -{ - int c, d; - - char temps[512]; - - config_set_int(NULL, "gameblaster", GAMEBLASTER); - config_set_int(NULL, "gus", GUS); - config_set_int(NULL, "ssi2001", SSI2001); - config_set_int(NULL, "voodoo", voodoo_enabled); - - config_set_string(NULL, "scsicard", scsi_card_get_internal_name(scsi_card_current)); - - config_set_int(NULL, "netinterface", ethif); - config_set_string(NULL, "netcard", network_card_get_internal_name(network_card_current)); - config_set_int(NULL, "maclocal", net2000_get_maclocal()); - config_set_int(NULL, "maclocal_pci", net2000_get_maclocal_pci()); - - config_set_string(NULL, "model", model_get_internal_name()); - config_set_int(NULL, "cpu_manufacturer", cpu_manufacturer); - config_set_int(NULL, "cpu", cpu); - config_set_int(NULL, "cpu_use_dynarec", cpu_use_dynarec); - config_set_int(NULL, "cpu_waitstates", cpu_waitstates); - - config_set_string(NULL, "gfxcard", video_get_internal_name(video_old_to_new(gfxcard))); - config_set_int(NULL, "video_speed", video_speed); - config_set_string(NULL, "sndcard", sound_card_get_internal_name(sound_card_current)); - config_set_int(NULL, "cpu_speed", cpuspeed); - config_set_int(NULL, "has_fpu", hasfpu); - - config_set_int(NULL, "mem_size", mem_size); - - memset(temps, 0, 512); - for (c = 0; c < FDD_NUM; c++) - { - sprintf(temps, "fdd_%02i_type", c + 1); - config_set_string(NULL, temps, fdd_get_internal_name(fdd_get_type(c))); - sprintf(temps, "fdd_%02i_fn", c + 1); - config_set_wstring(NULL, temps, discfns[c]); - sprintf(temps, "fdd_%02i_writeprot", c + 1); - config_set_int(NULL, temps, ui_writeprot[c]); - } - - config_set_string(NULL, "hdd_controller", hdd_controller_name); - - memset(temps, 0, 512); - for (c = 2; c < 4; c++) - { - sprintf(temps, "ide_%02i_enable", c + 1); - config_set_int(NULL, temps, ide_enable[c]); - sprintf(temps, "ide_%02i_irq", c + 1); - config_set_int(NULL, temps, ide_irq[c]); - } - - memset(temps, 0, 512); - for (c = 0; c < HDC_NUM; c++) - { - sprintf(temps, "hdd_%02i_sectors", c + 1); - config_set_int(NULL, temps, hdc[c].spt); - sprintf(temps, "hdd_%02i_heads", c + 1); - config_set_int(NULL, temps, hdc[c].hpc); - sprintf(temps, "hdd_%02i_cylinders", c + 1); - config_set_int(NULL, temps, hdc[c].tracks); - sprintf(temps, "hdd_%02i_bus_type", c + 1); - config_set_int(NULL, temps, hdc[c].bus); - sprintf(temps, "hdd_%02i_mfm_channel", c + 1); - config_set_int(NULL, temps, hdc[c].mfm_channel); - sprintf(temps, "hdd_%02i_ide_channel", c + 1); - config_set_int(NULL, temps, hdc[c].ide_channel); - sprintf(temps, "hdd_%02i_scsi_device_id", c + 1); - config_set_int(NULL, temps, hdc[c].scsi_id); - sprintf(temps, "hdd_%02i_scsi_device_lun", c + 1); - config_set_int(NULL, temps, hdc[c].scsi_lun); - sprintf(temps, "hdd_%02i_fn", c + 1); - config_set_wstring(NULL, temps, hdd_fn[c]); - } - - memset(temps, 0, 512); - for (c = 0; c < CDROM_NUM; c++) - { - sprintf(temps, "cdrom_%02i_host_drive", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].host_drive); - sprintf(temps, "cdrom_%02i_enabled", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].enabled); - sprintf(temps, "cdrom_%02i_sound_on", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].sound_on); - sprintf(temps, "cdrom_%02i_bus_type", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].bus_type); - sprintf(temps, "cdrom_%02i_atapi_dma", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].atapi_dma); - sprintf(temps, "cdrom_%02i_ide_channel", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].ide_channel); - sprintf(temps, "cdrom_%02i_scsi_device_id", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].scsi_device_id); - sprintf(temps, "cdrom_%02i_scsi_device_lun", c + 1); - config_set_int(NULL, temps, cdrom_drives[c].scsi_device_lun); - - sprintf(temps, "cdrom_%02i_iso_path", c + 1); - config_set_wstring(NULL, temps, cdrom_iso[c].iso_path); - } - - config_set_int(NULL, "vid_resize", vid_resize); - config_set_int(NULL, "vid_api", vid_api); - config_set_int(NULL, "video_fullscreen_scale", video_fullscreen_scale); - config_set_int(NULL, "video_fullscreen_first", video_fullscreen_first); - - config_set_int(NULL, "force_43", force_43); - config_set_int(NULL, "scale", scale); - config_set_int(NULL, "enable_overscan", enable_overscan); - config_set_int(NULL, "enable_flash", enable_flash); - - config_set_int(NULL, "enable_sync", enable_sync); - config_set_int(NULL, "opl3_type", opl3_type); - - config_set_int(NULL, "joystick_type", joystick_type); - config_set_string(NULL, "mouse_type", mouse_get_internal_name(mouse_type)); - - config_set_int(NULL, "enable_xtide", enable_xtide); - config_set_int(NULL, "enable_external_fpu", enable_external_fpu); - - for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) - { - char s[80]; - - sprintf(s, "joystick_%i_nr", c); - config_set_int("Joysticks", s, joystick_state[c].plat_joystick_nr); - - if (joystick_state[c].plat_joystick_nr) - { - for (d = 0; d < joystick_get_axis_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_axis_%i", c, d); - config_set_int("Joysticks", s, joystick_state[c].axis_mapping[d]); - } - for (d = 0; d < joystick_get_button_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_button_%i", c, d); - config_set_int("Joysticks", s, joystick_state[c].button_mapping[d]); - } - for (d = 0; d < joystick_get_pov_count(joystick_type); d++) - { - sprintf(s, "joystick_%i_pov_%i_x", c, d); - config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][0]); - sprintf(s, "joystick_%i_pov_%i_y", c, d); - config_set_int("Joysticks", s, joystick_state[c].pov_mapping[d][1]); - } - } - } - - config_set_int(NULL, "window_w", window_w); - config_set_int(NULL, "window_h", window_h); - config_set_int(NULL, "window_x", window_x); - config_set_int(NULL, "window_y", window_y); - config_set_int(NULL, "window_remember", window_remember); - - config_set_int(NULL, "serial1_enabled", serial_enabled[0]); - config_set_int(NULL, "serial2_enabled", serial_enabled[1]); - config_set_int(NULL, "lpt_enabled", lpt_enabled); - config_set_int(NULL, "bugger_enabled", bugger_enabled); - - config_save(config_file_default); -} diff --git a/src/resource.h b/src/resource.h index 2fffe255d..bc0d8da03 100644 --- a/src/resource.h +++ b/src/resource.h @@ -158,22 +158,22 @@ #define IDM_VID_INVERT 40079 #define IDM_CDROM_1_MUTE 40128 -#define IDM_CDROM_1_ISO 40144 +#define IDM_CDROM_1_IMAGE 40144 #define IDM_CDROM_1_RELOAD 40160 #define IDM_CDROM_1_EMPTY 40176 #define IDM_CDROM_1_REAL 40192 #define IDM_CDROM_2_MUTE 40129 -#define IDM_CDROM_2_ISO 40145 +#define IDM_CDROM_2_IMAGE 40145 #define IDM_CDROM_2_RELOAD 40161 #define IDM_CDROM_2_EMPTY 40177 #define IDM_CDROM_2_REAL 40193 #define IDM_CDROM_3_MUTE 40130 -#define IDM_CDROM_3_ISO 40146 +#define IDM_CDROM_3_IMAGE 40146 #define IDM_CDROM_3_RELOAD 40162 #define IDM_CDROM_3_EMPTY 40178 #define IDM_CDROM_3_REAL 40194 #define IDM_CDROM_4_MUTE 40131 -#define IDM_CDROM_4_ISO 40147 +#define IDM_CDROM_4_IMAGE 40147 #define IDM_CDROM_4_RELOAD 40163 #define IDM_CDROM_4_EMPTY 40179 #define IDM_CDROM_4_REAL 40195 diff --git a/src/serial.c b/src/serial.c index 1d401ad00..60b7ba3a3 100644 --- a/src/serial.c +++ b/src/serial.c @@ -505,8 +505,7 @@ serial_setup(int port, uint16_t addr, int irq) serial_read, NULL, NULL, serial_write, NULL, NULL, sp); - /* No DTR/RTS callback for now. */ - sp->rts_callback = NULL; + pclog("Serial%d: RTSCallback=%08X\n", port, sp->rts_callback); } @@ -519,13 +518,16 @@ serial_remove(int port) /* Grab the desired port block. */ sp = (port == 2) ? &serial2 : &serial1; + pclog("Serial%d: Remove I/O=%04x, IRQ=%d\n", port, sp->addr, sp->irq); + // FIXME: stop timer, if enabled! /* Remove any callbacks. */ - sp->rts_callback = NULL; + /* Commented out by Kotori: This messes with the Super I/O chip. */ + /* sp->rts_callback = NULL; */ /* Close the host device. */ - (void)serial_link(port, NULL); + /* (void)serial_link(port, NULL); */ /* Release our I/O range. */ if (sp->addr != 0x0000) { @@ -535,6 +537,8 @@ serial_remove(int port) } sp->addr = 0x0000; sp->irq = 0; + + pclog("Serial%d: RTSCallback=%08X\n", port, sp->rts_callback); } @@ -542,13 +546,19 @@ serial_remove(int port) void serial_init(void) { + pclog("serial_init()\n"); + memset(&serial1, 0x00, sizeof(SERIAL)); serial1.port = 1; serial_setup(1, SERIAL1_ADDR, SERIAL1_IRQ); + /* No DTR/RTS callback for now. */ + serial1.rts_callback = NULL; memset(&serial2, 0x00, sizeof(SERIAL)); serial2.port = 2; serial_setup(2, SERIAL2_ADDR, SERIAL2_IRQ); + /* No DTR/RTS callback for now. */ + serial2.rts_callback = NULL; } @@ -560,11 +570,17 @@ serial_init(void) void serial_reset(void) { + pclog("serial_reset()\n"); + serial1.iir = serial1.ier = serial1.lcr = serial1.mctrl = 0; serial1.fifo_read = serial1.fifo_write = 0; + /* No DTR/RTS callback for now. */ + serial1.rts_callback = NULL; serial2.iir = serial2.ier = serial2.lcr = serial2.mctrl = 0; serial2.fifo_read = serial2.fifo_write = 0; + /* No DTR/RTS callback for now. */ + serial2.rts_callback = NULL; } diff --git a/src/win.c b/src/win.c index faf311758..ef37362d3 100644 --- a/src/win.c +++ b/src/win.c @@ -33,7 +33,7 @@ #include "cdrom.h" #include "cdrom-null.h" #include "cdrom-ioctl.h" -#include "cdrom-iso.h" +#include "cdrom-image.h" #include "video/video.h" #include "video/vid_ega.h" #include "plat-keyboard.h" @@ -760,7 +760,7 @@ void update_status_bar_icon_state(int tag, int state) discfns[tag & 0x0f][0] = L'\0'; break; case 0x10: - cdrom_iso[tag & 0x0f].iso_path[0] = L'\0'; + cdrom_image[tag & 0x0f].image_path[0] = L'\0'; break; } } @@ -807,13 +807,13 @@ void create_cdrom_tip(int part) if (cdrom_drives[drive].host_drive == 200) { - if (wcslen(cdrom_iso[drive].iso_path) == 0) + if (wcslen(cdrom_image[drive].image_path) == 0) { _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, win_language_get_string_from_id(2185)); } else { - _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, cdrom_iso[drive].iso_path); + _swprintf(sbTips[part], win_language_get_string_from_id(2180), drive + 1, cdrom_image[drive].image_path); } } else if (cdrom_drives[drive].host_drive < 0x41) @@ -885,7 +885,7 @@ static int get_cd_state(int id) { if (cdrom_drives[id].host_drive == 0x200) { - return (wcslen(cdrom_iso[id].iso_path) == 0) ? 1 : 0; + return (wcslen(cdrom_image[id].image_path) == 0) ? 1 : 0; } else { @@ -983,7 +983,7 @@ void update_status_bar_panes(HWND hwnds) { if (cdrom_drives[id].host_drive == 0x200) { - sb_icon_flags[i] = (wcslen(cdrom_iso[id].iso_path) == 0) ? 256 : 0; + sb_icon_flags[i] = (wcslen(cdrom_image[id].image_path) == 0) ? 256 : 0; } else { @@ -1216,7 +1216,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, if (cdrom_drives[e].host_drive == 200) { - CheckMenuItem(smenu, IDM_CDROM_1_ISO + e, MF_CHECKED); + CheckMenuItem(smenu, IDM_CDROM_1_IMAGE + e, MF_CHECKED); } else if (cdrom_drives[e].host_drive >= 65) { @@ -1411,9 +1411,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, TerminateThread(mainthreadh,0); savenvr(); saveconfig(); - if (save_window_pos && window_remember) - saveconfig(); - closepc(); + closepc(); vid_apis[video_fullscreen][vid_api].close(); @@ -1464,7 +1462,7 @@ void cdrom_close(uint8_t id) ioctl_close(id); break; case 200: - iso_close(id); + image_close(id); break; } } @@ -1547,7 +1545,7 @@ void win_cdrom_eject(uint8_t id) } if (cdrom_drives[id].host_drive == 200) { - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + id, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_UNCHECKED); } else { @@ -1574,7 +1572,7 @@ void win_cdrom_reload(uint8_t id) cdrom_close(id); if (cdrom_drives[id].prev_host_drive == 200) { - iso_open(id, cdrom_iso[id].iso_path); + image_open(id, cdrom_image[id].image_path); if (cdrom_drives[id].enabled) { /* Signal disc change to the emulated machine. */ @@ -1582,7 +1580,7 @@ void win_cdrom_reload(uint8_t id) } CheckMenuItem(hmenu, IDM_CDROM_1_EMPTY + id, MF_UNCHECKED); cdrom_drives[id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + id, MF_CHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + id, MF_CHECKED); } else { @@ -2144,7 +2142,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR RECT rc; POINT pt; - WCHAR temp_iso_path[1024]; + WCHAR temp_image_path[1024]; int new_cdrom_drive; int cdrom_id = 0; int menu_sub_param = 0; @@ -2261,24 +2259,24 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR win_cdrom_reload(cdrom_id); break; - case IDM_CDROM_1_ISO: - case IDM_CDROM_2_ISO: - case IDM_CDROM_3_ISO: - case IDM_CDROM_4_ISO: + case IDM_CDROM_1_IMAGE: + case IDM_CDROM_2_IMAGE: + case IDM_CDROM_3_IMAGE: + case IDM_CDROM_4_IMAGE: cdrom_id = LOWORD(wParam) & 3; hmenu = GetSubMenu(smenu, cdrom_id + 4); - if (!file_dlg_w_st(hwnd, 2175, cdrom_iso[cdrom_id].iso_path, 0)) + if (!file_dlg_w_st(hwnd, 2175, cdrom_image[cdrom_id].image_path, 0)) { cdrom_drives[cdrom_id].prev_host_drive = cdrom_drives[cdrom_id].host_drive; - wcscpy(temp_iso_path, wopenfilestring); - if ((wcscmp(cdrom_iso[cdrom_id].iso_path, temp_iso_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) + wcscpy(temp_image_path, wopenfilestring); + if ((wcscmp(cdrom_image[cdrom_id].image_path, temp_image_path) == 0) && (cdrom_drives[cdrom_id].host_drive == 200)) { - /* Switching from ISO to the same ISO. Do nothing. */ + /* Switching from image to the same image. Do nothing. */ break; } cdrom_drives[cdrom_id].handler->exit(cdrom_id); cdrom_close(cdrom_id); - iso_open(cdrom_id, temp_iso_path); + image_open(cdrom_id, temp_image_path); if (cdrom_drives[cdrom_id].enabled) { /* Signal disc change to the emulated machine. */ @@ -2290,7 +2288,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); } cdrom_drives[cdrom_id].host_drive = 200; - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + cdrom_id, MF_CHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_CHECKED); update_status_bar_icon_state(0x10 | cdrom_id, get_cd_state(cdrom_id)); update_tip(0x10 | cdrom_id); saveconfig(); @@ -2324,7 +2322,7 @@ LRESULT CALLBACK StatusBarProcedure(HWND hwnd, UINT message, WPARAM wParam, LPAR { CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_UNCHECKED); } - CheckMenuItem(hmenu, IDM_CDROM_1_ISO + cdrom_id, MF_UNCHECKED); + CheckMenuItem(hmenu, IDM_CDROM_1_IMAGE + cdrom_id, MF_UNCHECKED); cdrom_drives[cdrom_id].host_drive = new_cdrom_drive; CheckMenuItem(hmenu, IDM_CDROM_1_REAL + cdrom_id + (cdrom_drives[cdrom_id].host_drive << 2), MF_CHECKED); update_status_bar_icon_state(0x10 | cdrom_id, get_cd_state(cdrom_id)); From adfbf25391723bbc73cad0c1cfe552220d1ac3e5 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 8 May 2017 05:15:04 +0200 Subject: [PATCH 2/2] Committed 4 files I forgot to commit earlier. --- src/cdrom-dosbox.cpp | 560 +++++++++++++++++++++++ src/cdrom-dosbox.h | 173 +++++++ src/cdrom-image.cc | 1018 ++++++++++++++++++++++++++++++++++++++++++ src/cdrom-image.h | 25 ++ 4 files changed, 1776 insertions(+) create mode 100644 src/cdrom-dosbox.cpp create mode 100644 src/cdrom-dosbox.h create mode 100644 src/cdrom-image.cc create mode 100644 src/cdrom-image.h diff --git a/src/cdrom-dosbox.cpp b/src/cdrom-dosbox.cpp new file mode 100644 index 000000000..86f09e8c8 --- /dev/null +++ b/src/cdrom-dosbox.cpp @@ -0,0 +1,560 @@ +/* + * 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-dosbox.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::IsMode2(unsigned long sector) +{ + int track = GetTrack(sector) - 1; + if (track < 0) return false; + + if (tracks[track].mode2) + { + return true; + } + else + { + return false; + } +} + +bool CDROM_Interface_Image::LoadIsoFile(char* filename) +{ + tracks.clear(); + + // data track + Track track = {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.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, 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/cdrom-dosbox.h b/src/cdrom-dosbox.h new file mode 100644 index 000000000..39ed79bed --- /dev/null +++ b/src/cdrom-dosbox.h @@ -0,0 +1,173 @@ +/* + * 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 IsMode2 (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/cdrom-image.cc b/src/cdrom-image.cc new file mode 100644 index 000000000..47c494291 --- /dev/null +++ b/src/cdrom-image.cc @@ -0,0 +1,1018 @@ +/* Copyright holders: RichardG867, Tenshi, bit + see COPYING for more details +*/ +/*CD-ROM image support*/ + +#include + +// #include "ibm.h" +#include "config.h" +#include "cdrom-dosbox.h" +#include "cdrom.h" +#include "cdrom-image.h" +#include "cdrom-null.h" + +#define __USE_LARGEFILE64 +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE + +#include + +#define CD_STATUS_EMPTY 0 +#define CD_STATUS_DATA_ONLY 1 +#define CD_STATUS_PLAYING 2 +#define CD_STATUS_PAUSED 3 +#define CD_STATUS_STOPPED 4 + +/* The addresses sent from the guest are absolute, ie. a LBA of 0 corresponds to a MSF of 00:00:00. Otherwise, the counter displayed by the guest is wrong: + there is a seeming 2 seconds in which audio plays but counter does not move, while a data track before audio jumps to 2 seconds before the actual start + of the audio while audio still plays. With an absolute conversion, the counter is fine. */ +#define MSFtoLBA(m,s,f) ((((m*60)+s)*75)+f) + +extern CDROM image_cdrom; + +enum +{ + CD_STOPPED = 0, + CD_PLAYING, + CD_PAUSED +}; + +int cdrom_image_do_log = 1; + +CDROM_Interface_Image* cdimg[CDROM_NUM] = { NULL, NULL, NULL, NULL }; + +void cdrom_image_log(const char *format, ...) +{ +// #ifdef ENABLE_CDROM_IMAGE_LOG + if (cdrom_image_do_log) + { + va_list ap; + va_start(ap, format); + vprintf(format, ap); + va_end(ap); + fflush(stdout); + } +// #endif +} + +void image_close(uint8_t id); + +void image_audio_callback(uint8_t id, int16_t *output, int len) +{ + if ((cdrom_image[id].cd_state != CD_PLAYING) || (cdrom_image[id].image_is_iso)) + { + memset(output, 0, len * 2); + return; + } + while (cdrom_image[id].cd_buflen < len) + { + if (cdrom[id].seek_pos < cdrom_image[id].cd_end) + { + if (!cdimg[id]->ReadSector((unsigned char*)&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], true, cdrom[id].seek_pos - 150)) + { + memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + cdrom_image[id].cd_state = CD_STOPPED; + cdrom_image[id].cd_buflen = len; + } + else + { + cdrom[id].seek_pos++; + cdrom_image[id].cd_buflen += (RAW_SECTOR_SIZE / 2); + } + } + else + { + memset(&cdrom_image[id].cd_buffer[cdrom_image[id].cd_buflen], 0, (BUF_SIZE - cdrom_image[id].cd_buflen) * 2); + cdrom_image[id].cd_state = CD_STOPPED; + cdrom_image[id].cd_buflen = len; + } + } + memcpy(output, cdrom_image[id].cd_buffer, len * 2); + memmove(cdrom_image[id].cd_buffer, &cdrom_image[id].cd_buffer[len], (BUF_SIZE - len) * 2); + cdrom_image[id].cd_buflen -= len; +} + +void image_audio_stop(uint8_t id) +{ + cdrom_image[id].cd_state = CD_STOPPED; +} + +static void image_playaudio(uint8_t id, uint32_t pos, uint32_t len, int ismsf) +{ + if (!cdimg[id]) return; + int number; + unsigned char attr; + TMSF tmsf; + int m = 0, s = 0, f = 0; + uint32_t start_msf = 0, end_msf = 0; + cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); + if (attr == DATA_TRACK) + { + cdrom_image_log("Can't play data track\n"); + cdrom[id].seek_pos = 0; + cdrom_image[id].cd_state = CD_STOPPED; + return; + } + cdrom_image_log("Play audio - %08X %08X %i\n", pos, len, ismsf); + if (ismsf == 2) + { + cdimg[id]->GetAudioTrackInfo(pos, number, tmsf, attr); + pos = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + cdimg[id]->GetAudioTrackInfo(len, number, tmsf, attr); + len = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + } + else if (ismsf == 1) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + + if (pos == 0xffffff) + { + cdrom_image_log("Playing from current position (MSF)\n"); + pos = cdrom[id].seek_pos; + } + else + { + pos = MSFtoLBA(m, s, f); + } + + m = (len >> 16) & 0xff; + s = (len >> 8) & 0xff; + f = len & 0xff; + len = MSFtoLBA(m, s, f); + + cdrom_image_log("MSF - pos = %08X len = %08X\n", pos, len); + } + else if (ismsf == 0) + { + if (pos == 0xffffffff) + { + cdrom_image_log("Playing from current position\n"); + pos = cdrom[id].seek_pos; + } + len += pos; + } + cdrom[id].seek_pos = pos; + cdrom_image[id].cd_end = len; + cdrom_image[id].cd_state = CD_PLAYING; + if (cdrom[id].seek_pos < 150) + cdrom[id].seek_pos = 150; + cdrom_image[id].cd_buflen = 0; +} + +static void image_pause(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + if (cdrom_image[id].cd_state == CD_PLAYING) + cdrom_image[id].cd_state = CD_PAUSED; +} + +static void image_resume(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + if (cdrom_image[id].cd_state == CD_PAUSED) + cdrom_image[id].cd_state = CD_PLAYING; +} + +static void image_stop(uint8_t id) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + cdrom_image[id].cd_state = CD_STOPPED; +} + +static void image_seek(uint8_t id, uint32_t pos) +{ + if (!cdimg[id] || cdrom_image[id].image_is_iso) return; + cdrom_image[id].cd_pos = pos; + cdrom_image[id].cd_state = CD_STOPPED; +} + +static int image_ready(uint8_t id) +{ + if (!cdimg[id]) + return 0; + + if (wcslen(cdrom_image[id].image_path) == 0) + return 0; + + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) + { + return 1; + } + + if (cdrom_image[id].image_changed) + { + cdrom_image[id].image_changed = 0; + return 1; + } + + return 1; +} + +static int image_get_last_block(uint8_t id, uint8_t starttrack, int msf, int maxlen, int single) +{ + int c; + uint32_t lb=0; + + if (!cdimg[id]) return 0; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + for (c = 0; c <= last_track; c++) + { + uint32_t address; + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + address = MSFtoLBA(tmsf.min, tmsf.sec, tmsf.fr); + if (address > lb) + lb = address; + } + return lb; +} + +static int image_medium_changed(uint8_t id) +{ + if (!cdimg[id]) + return 0; + + if (wcslen(cdrom_image[id].image_path) == 0) + { + return 0; + } + + if (cdrom_drives[id].prev_host_drive != cdrom_drives[id].host_drive) + { + cdrom_drives[id].prev_host_drive = cdrom_drives[id].host_drive; + return 1; + } + + if (cdrom_image[id].image_changed) + { + cdrom_image[id].image_changed = 0; + return 1; + } + + return 0; +} + +static uint8_t image_getcurrentsubchannel(uint8_t id, uint8_t *b, int msf) +{ + if (!cdimg[id]) return 0; + uint8_t ret; + int pos=0; + + uint32_t cdpos = cdrom[id].seek_pos; + if (cdpos >= 150) cdpos -= 150; + TMSF relPos, absPos; + unsigned char attr, track, index; + cdimg[id]->GetAudioSub(cdpos, attr, track, index, relPos, absPos); + + if (cdrom_image[id].image_is_iso) + { + ret = 0x15; + } + else + { + if (cdrom_image[id].cd_state == CD_PLAYING) + ret = 0x11; + else if (cdrom_image[id].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(uint8_t id) +{ + return; +} + +static void image_load(uint8_t id) +{ + return; +} + +static int image_is_track_audio(uint8_t id, uint32_t pos, int ismsf) +{ + int m, s, f; + unsigned char attr; + TMSF tmsf; + int number; + + if (!cdimg[id] || cdrom_image[id].image_is_iso) return 0; + + if (ismsf) + { + m = (pos >> 16) & 0xff; + s = (pos >> 8) & 0xff; + f = pos & 0xff; + pos = MSFtoLBA(m, s, f); + } + else + { + pos += 150; + } + + cdimg[id]->GetAudioTrackInfo(cdimg[id]->GetTrack(pos), number, tmsf, attr); + + return attr == AUDIO_TRACK; +} + +typedef struct __attribute__((__packed__)) +{ + uint8_t user_data[2048]; + uint8_t ecc[288]; +} m1_data_t; + +typedef struct __attribute__((__packed__)) +{ + uint8_t sub_header[8]; + uint8_t user_data[2328]; +} m2_data_t; + +typedef union __attribute__((__packed__)) +{ + m1_data_t m1_data; + m2_data_t m2_data; + uint8_t raw_data[2336]; +} sector_data_t; + +typedef struct __attribute__((__packed__)) +{ + uint8_t sync[12]; + uint8_t header[4]; + sector_data_t data; +} sector_raw_data_t; + +typedef union __attribute__((__packed__)) +{ + sector_raw_data_t sector_data; + uint8_t raw_data[2352]; +} sector_t; + +typedef struct __attribute__((__packed__)) +{ + sector_t sector; + uint8_t c2[296]; + uint8_t subchannel_raw[96]; + uint8_t subchannel_q[16]; + uint8_t subchannel_rw[96]; +} cdrom_sector_t; + +typedef union __attribute__((__packed__)) +{ + cdrom_sector_t cdrom_sector; + uint8_t buffer[2856]; +} sector_buffer_t; + +sector_buffer_t cdrom_sector_buffer; + +int cdrom_sector_size; +uint8_t raw_buffer[2352]; +uint8_t extra_buffer[296]; + +static int image_readsector_raw(uint8_t id, uint8_t *buffer, int sector, int ismsf, int cdrom_sector_type, int cdrom_sector_flags, int *len) +{ + uint8_t *b; + uint8_t *temp_b; + int real_pos; + int audio; + int mode2; + + if (!cdimg[id]) + { + return 0; + } + + if (!cdrom_drives[id].host_drive) + { + return 0; + } + + b = temp_b = buffer; + + *len = 0; + + if (ismsf) + { + real_pos = cdrom_lba_to_msf_accurate(sector); + } + else + { + real_pos = sector; + } + + if (cdrom_image[id].image_is_iso) + { + audio = 0; + mode2 = 0; + } + else + { + audio = image_is_track_audio(id, real_pos, 1); + mode2 = cdimg[id]->IsMode2(real_pos) ? 1 : 0; + } + + memset(raw_buffer, 0, 2352); + memset(extra_buffer, 0, 296); + + if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] 0x00 and 0x08 are illegal modes\n", id); + return 0; + } + + if ((cdrom_sector_type == 3) || (cdrom_sector_type > 4)) + { + if (cdrom_sector_type == 3) + { + cdrom_image_log("CD-ROM %i: Attempting to read a Yellowbook Mode 2 data sector from an image\n", id); + } + if (cdrom_sector_type > 4) + { + cdrom_image_log("CD-ROM %i: Attempting to read a XA Mode 2 Form 2 data sector from an image\n", id); + } + return 0; + } + else if (cdrom_sector_type == 1) + { + if (!audio || cdrom_image[id].image_is_iso) + { + cdrom_image_log("CD-ROM %i: [Audio] Attempting to read an audio sector from a data image\n", id); + return 0; + } + +read_audio: + cdimg[id]->ReadSector(raw_buffer, true, real_pos); + memcpy(temp_b, raw_buffer, 2352); + } + else if (cdrom_sector_type == 2) + { + if (audio || mode2) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Attempting to read a non-Mode 1 sector from an audio track\n", id); + return 0; + } + +read_mode1: + if ((cdrom_sector_flags & 0x06) == 0x06) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Invalid error flags\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) + { + cdrom_image_log("CD-ROM %i: [Mode 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); + return 0; + } + + if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC without user data is an illegal mode\n", id); + return 0; + } + + if (cdrom_image[id].image_is_iso) + { + cdimg[id]->ReadSector(raw_buffer + 16, false, real_pos); + + uint8_t *bb = raw_buffer; + + /* sync bytes */ + bb[0] = 0; + memset(bb + 1, 0xff, 10); + bb[11] = 0; + bb += 12; + + bb[0] = (real_pos >> 16) & 0xff; + bb[1] = (real_pos >> 8) & 0xff; + bb[2] = real_pos & 0xff; + + bb[3] = 1; /* mode 1 data */ + bb += 4; + bb += 2048; + memset(bb, 0, 288); + } + else + { + cdimg[id]->ReadSector(raw_buffer, true, real_pos); + } + + cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) /* Sync */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Sync\n", id); + memcpy(temp_b, raw_buffer, 12); + cdrom_sector_size += 12; + temp_b += 12; + } + + if (cdrom_sector_flags & 0x20) /* Header */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Header\n", id); + memcpy(temp_b, raw_buffer + 12, 4); + cdrom_sector_size += 4; + temp_b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) /* Sub-header */ + { + if (!(cdrom_sector_flags & 0x10)) /* No user data */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] Sub-header\n", id); + memcpy(temp_b, raw_buffer + 16, 8); + cdrom_sector_size += 8; + temp_b += 8; + } + } + + if (cdrom_sector_flags & 0x10) /* User data */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] User data\n", id); + memcpy(temp_b, raw_buffer + 16, 2048); + cdrom_sector_size += 2048; + temp_b += 2048; + } + + if (cdrom_sector_flags & 0x08) /* EDC/ECC */ + { + cdrom_image_log("CD-ROM %i: [Mode 1] EDC/ECC\n", id); + memcpy(temp_b, raw_buffer + 2064, 288); + cdrom_sector_size += 288; + temp_b += 288; + } + } + else if (cdrom_sector_type == 4) + { + if (audio || !mode2 || cdrom_image[id].image_is_iso) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Attempting to read a non-XA Mode 2 Form 1 sector from an audio track\n", id); + return 0; + } + +read_mode2: + if (!(cdrom_sector_flags & 0xf0)) /* 0x00 and 0x08 are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0x00 and 0x08 are illegal modes\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0xf0) == 0xb0) || ((cdrom_sector_flags & 0xf0) == 0xd0)) /* 0xBx and 0xDx are illegal modes */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] 0xBx and 0xDx are illegal modes\n", id); + return 0; + } + + if ((cdrom_sector_flags & 0x06) == 0x06) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid error flags\n", id); + return 0; + } + + if (((cdrom_sector_flags & 0x700) == 0x300) || ((cdrom_sector_flags & 0x700) > 0x400)) + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Invalid subchannel data flags (%02X)\n", id, cdrom_sector_flags & 0x700); + return 0; + } + + if ((cdrom_sector_flags & 0x18) == 0x08) /* EDC/ECC without user data is an illegal mode */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC without user data is an illegal mode\n", id); + return 0; + } + + cdimg[id]->ReadSector(cdrom_sector_buffer.buffer, true, real_pos); + + cdrom_sector_size = 0; + + if (cdrom_sector_flags & 0x80) /* Sync */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sync\n", id); + memcpy(temp_b, raw_buffer, 12); + cdrom_sector_size += 12; + temp_b += 12; + } + + if (cdrom_sector_flags & 0x20) /* Header */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Header\n", id); + memcpy(temp_b, raw_buffer + 12, 4); + cdrom_sector_size += 4; + temp_b += 4; + } + + /* Mode 1 sector, expected type is 1 type. */ + if (cdrom_sector_flags & 0x40) /* Sub-header */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] Sub-header\n", id); + memcpy(temp_b, raw_buffer + 16, 8); + cdrom_sector_size += 8; + temp_b += 8; + } + + if (cdrom_sector_flags & 0x10) /* User data */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] User data\n", id); + memcpy(temp_b, raw_buffer + 24, 2048); + cdrom_sector_size += 2048; + temp_b += 2048; + } + + if (cdrom_sector_flags & 0x08) /* EDC/ECC */ + { + cdrom_image_log("CD-ROM %i: [XA Mode 2 Form 1] EDC/ECC\n", id); + memcpy(temp_b, raw_buffer + 2072, 280); + cdrom_sector_size += 280; + temp_b += 280; + } + } + else + { + if (mode2) + { + goto read_mode2; + } + else + { + if (audio) + { + goto read_audio; + } + else + { + goto read_mode1; + } + } + } + + if ((cdrom_sector_flags & 0x06) == 0x02) + { + /* Add error flags. */ + cdrom_image_log("CD-ROM %i: Error flags\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 294); + cdrom_sector_size += 294; + } + else if ((cdrom_sector_flags & 0x06) == 0x04) + { + /* Add error flags. */ + cdrom_image_log("CD-ROM %i: Full error flags\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 296); + cdrom_sector_size += 296; + } + + if ((cdrom_sector_flags & 0x700) == 0x100) + { + cdrom_image_log("CD-ROM %i: Raw subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 96); + cdrom_sector_size += 96; + } + else if ((cdrom_sector_flags & 0x700) == 0x200) + { + cdrom_image_log("CD-ROM %i: Q subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 16); + cdrom_sector_size += 16; + } + else if ((cdrom_sector_flags & 0x700) == 0x400) + { + cdrom_image_log("CD-ROM %i: R/W subchannel data\n", id); + memcpy(b + cdrom_sector_size, extra_buffer, 96); + cdrom_sector_size += 96; + } + + *len = cdrom_sector_size; + + return 1; +} + + +static int image_readtoc(uint8_t id, unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) +{ + if (!cdimg[id]) return 0; + int len=4; + int c,d; + uint32_t temp; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->GetAudioTracks(first_track, last_track, tmsf); + + b[2] = first_track; + b[3] = last_track; + + d = 0; + for (c = 0; c <= last_track; c++) + { + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + if (number >= starttrack) + { + d=c; + break; + } + } + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + b[2] = number; + + for (c = d; c <= last_track; c++) + { + if ((len + 8) > maxlen) + break; + cdimg[id]->GetAudioTrackInfo(c+1, number, tmsf, attr); + + 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); + 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); + return len; +} + +static int image_readtoc_session(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + if (!cdimg[id]) return 0; + int len = 4; + + int number; + TMSF tmsf; + unsigned char attr; + cdimg[id]->GetAudioTrackInfo(1, number, tmsf, attr); + + 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); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + + return len; +} + +static int image_readtoc_raw(uint8_t id, unsigned char *b, int msf, int maxlen) +{ + if (!cdimg[id]) return 0; + + int track; + int len = 4; + + int first_track; + int last_track; + int number; + unsigned char attr; + TMSF tmsf; + cdimg[id]->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) + { + cdrom_image_log("image_readtocraw: This iteration would fill the buffer beyond the bounds, aborting...\n"); + return len; + } + + cdimg[id]->GetAudioTrackInfo(track, number, tmsf, attr); + + b[len++] = track; + b[len++]= attr; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + b[len++]=0; + 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); + b[len++] = temp >> 24; + b[len++] = temp >> 16; + b[len++] = temp >> 8; + b[len++] = temp; + } + } + return len; +} + +static uint32_t image_size(uint8_t id) +{ + return cdrom_image[id].cdrom_capacity; +} + +static int image_status(uint8_t id) +{ + if (!cdimg[id]) return CD_STATUS_EMPTY; + if (cdrom_image[id].image_is_iso) return CD_STATUS_DATA_ONLY; + if (cdimg[id]->HasAudioTracks()) + { + switch(cdrom_image[id].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(uint8_t id) +{ +} + +void image_close(uint8_t id) +{ + cdrom_image[id].cd_state = CD_STOPPED; + if (cdimg[id]) + { + delete cdimg[id]; + cdimg[id] = NULL; + } + memset(cdrom_image[id].image_path, 0, 2048); +} + +static char afn[1024]; + +int image_open(uint8_t id, wchar_t *fn) +{ + if (wcscmp(fn, cdrom_image[id].image_path) != 0) + { + cdrom_image[id].image_changed = 1; + } + + /* Make sure image_changed stays when changing from an image to another image. */ + if (!cdrom_image[id].image_inited && (cdrom_drives[id].host_drive != 200)) cdrom_image[id].image_changed = 0; + + if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + { + _swprintf(cdrom_image[id].image_path, L"%ws", fn); + } + + if (!wcsicmp(get_extension_w(fn), L"ISO")) + { + cdrom_image[id].image_is_iso = 1; + } + else + { + cdrom_image[id].image_is_iso = 0; + } + + cdimg[id] = new CDROM_Interface_Image(); + wcstombs(afn, fn, (wcslen(fn) << 1) + 2); + if (!cdimg[id]->SetDevice(afn, false)) + { + image_close(id); + cdrom_set_null_handler(id); + return 1; + } + cdrom_image[id].cd_state = CD_STOPPED; + cdrom[id].seek_pos = 0; + cdrom_image[id].cd_buflen = 0; + cdrom_image[id].cdrom_capacity = image_get_last_block(id, 0, 0, 4096, 0); + cdrom_drives[id].handler = &image_cdrom; + + if (!cdrom_image[id].image_inited || cdrom_image[id].image_changed) + { + if (!cdrom_image[id].image_inited) + cdrom_image[id].image_inited = 1; + } + return 0; +} + +static void image_exit(uint8_t id) +{ + cdrom_image[id].image_inited = 0; +} + +/* TODO: Check for what data type a mixed CD is. */ +static int image_media_type_id(uint8_t id) +{ + if (!cdrom_image[id].image_is_iso) + { + return 3; /* Mixed mode CD. */ + } + + if (image_size(id) <= 405000) + { + return 1; /* Data CD. */ + } + else + { + return 65; /* DVD. */ + } +} + +CDROM image_cdrom = +{ + image_ready, + image_medium_changed, + image_media_type_id, + image_audio_callback, + image_audio_stop, + image_readtoc, + image_readtoc_session, + image_readtoc_raw, + image_getcurrentsubchannel, + NULL, + image_readsector_raw, + image_playaudio, + 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 000000000..3a49226a3 --- /dev/null +++ b/src/cdrom-image.h @@ -0,0 +1,25 @@ +/* Copyright holders: RichardG867, Tenshi + see COPYING for more details +*/ +#ifndef CDROM_IMAGE_H +#define CDROM_IMAGE_H + +/* this header file lists the functions provided by + various platform specific cdrom-ioctl files */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int image_open(uint8_t id, wchar_t *fn); +extern void image_reset(uint8_t id); + +extern void image_close(uint8_t id); + +extern void cdrom_set_null_handler(uint8_t id); + +#ifdef __cplusplus +} +#endif + +#endif /* ! CDROM_IMAGE_H */