diff --git a/src/config.c b/src/config.c index 3551439..49e936e 100644 --- a/src/config.c +++ b/src/config.c @@ -12,7 +12,7 @@ * it on Windows XP, and possibly also Vista. Use the * -DANSI_CFG for use on these systems. * - * Version: @(#)config.c 1.0.32 2018/08/27 + * Version: @(#)config.c 1.0.33 2018/09/03 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -411,11 +411,9 @@ load_machine(const char *cat) cpu_waitstates = config_get_int(cat, "cpu_waitstates", 0); mem_size = config_get_int(cat, "mem_size", 4096); -#if 0 if (mem_size < (((machines[machine].flags & MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram)) mem_size = (((machines[machine].flags & MACHINE_AT) && (machines[machine].ram_granularity < 128)) ? machines[machine].min_ram*1024 : machines[machine].min_ram); -#endif if (mem_size > 1048576) mem_size = 1048576; diff --git a/src/devices/floppy/fdd_86f.c b/src/devices/floppy/fdd_86f.c index c8519b8..ccd6585 100644 --- a/src/devices/floppy/fdd_86f.c +++ b/src/devices/floppy/fdd_86f.c @@ -10,7 +10,7 @@ * data in the form of FM/MFM-encoded transitions) which also * forms the core of the emulator's floppy disk emulation. * - * Version: @(#)fdd_86f.c 1.0.11 2018/06/25 + * Version: @(#)fdd_86f.c 1.0.12 2018/09/03 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1076,7 +1076,12 @@ d86f_get_bit(int drive, int side) encoded_data |= (d86f_handler[drive].encoded_data(drive, side)[track_word] >> 8); } - if (d86f_has_surface_desc(drive)) { + /* + * In some cases, misindentification occurs so we need + * to make sure the surface data array is not not NULL. + */ + if (d86f_has_surface_desc(drive) && + dev->track_surface_data && dev->track_surface_data[side]) { if (d86f_reverse_bytes(drive)) { surface_data = dev->track_surface_data[side][track_word] & 0xFF; } else { @@ -1088,7 +1093,8 @@ d86f_get_bit(int drive, int side) current_bit = (encoded_data >> track_bit) & 1; dev->last_word[side] <<= 1; - if (d86f_has_surface_desc(drive)) { + if (d86f_has_surface_desc(drive) && + dev->track_surface_data && dev->track_surface_data[side]) { surface_bit = (surface_data >> track_bit) & 1; if (! surface_bit) { if (! current_bit) { diff --git a/src/devices/sound/snd_mpu401.c b/src/devices/sound/snd_mpu401.c index 2c9ce80..98dec7c 100644 --- a/src/devices/sound/snd_mpu401.c +++ b/src/devices/sound/snd_mpu401.c @@ -8,7 +8,7 @@ * * Roland MPU-401 emulation. * - * Version: @(#)snd_mpu401.c 1.0.8 2018/05/06 + * Version: @(#)snd_mpu401.c 1.0.9 2018/09/03 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -51,6 +51,7 @@ #include "../../timer.h" #include "../../device.h" #include "../system/pic.h" +#include "../system/mca.h" #include "sound.h" #include "snd_mpu401.h" #include "midi.h" @@ -67,13 +68,15 @@ int sound_mpu401_do_log = ENABLE_SOUND_MPU401_LOG; #endif -static int64_t mpu401_event_callback = 0LL; -static int64_t mpu401_eoi_callback = 0LL; -static int64_t mpu401_reset_callback = 0LL; +int mca_version = 0; + +static int64_t mpu401_event_callback = 0LL; +static int64_t mpu401_eoi_callback = 0LL; +static int64_t mpu401_reset_callback = 0LL; -static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val); -static void MPU401_EOIHandlerDispatch(void *p); +static void MPU401_WriteCommand(mpu_t *mpu, uint8_t val); +static void MPU401_EOIHandlerDispatch(void *p); static void @@ -816,30 +819,32 @@ MPU401_Event(void *priv) pclog("MPU-401 event callback\n"); - if (mpu->mode==M_UART) { + if (mpu->mode == M_UART) { mpu401_event_callback = 0LL; return; } if (mpu->state.irq_pending) goto next_event; - for (i=0;i<8;i++) { /* Decrease counters */ - if (mpu->state.amask&(1<state.amask & (1 << i)) { mpu->playbuf[i].counter--; - if (mpu->playbuf[i].counter<=0) UpdateTrack(mpu, i); + if (mpu->playbuf[i].counter <= 0) + UpdateTrack(mpu, i); } } if (mpu->state.conductor) { mpu->condbuf.counter--; - if (mpu->condbuf.counter<=0) UpdateConductor(mpu); + if (mpu->condbuf.counter <= 0) + UpdateConductor(mpu); } if (mpu->clock.clock_to_host) { mpu->clock.cth_counter++; if (mpu->clock.cth_counter >= mpu->clock.cth_rate) { - mpu->clock.cth_counter=0; - mpu->state.req_mask|=(1<<13); + mpu->clock.cth_counter = 0; + mpu->state.req_mask |= (1 << 13); } } @@ -903,34 +908,88 @@ mpu401_device_add(void) n = sound_card_get_internal_name(sound_card); if (n != NULL) { - if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) return; + if (! strcmp(n, "ncraudio")) + mca_version = 1; + else + mca_version = 0; + + if (!strcmp(n, "sb16") || + !strcmp(n, "sbawe32") || + !strcmp(n, "replysb16")) return; } - device_add(&mpu401_device); + if (mca_version) + device_add(&mpu401_mca_device); + else + device_add(&mpu401_device); +} + + +static uint8_t +mpu401_mca_read(int port, void *priv) +{ + mpu_t *dev = (mpu_t *)priv; + + return dev->pos_regs[port & 7]; +} + + +static void +mpu401_mca_write(int port, uint8_t val, void *priv) +{ + mpu_t *dev = (mpu_t *)priv; + uint16_t addr; + + if (port < 0x102) return; + + addr = (dev->pos_regs[2] & 2) ? 0x0330 : 0x1330; + + io_removehandler(addr, 2, + mpu401_read,NULL,NULL, mpu401_write,NULL,NULL, dev); + io_removehandler(0x2a20, 16, + NULL,NULL,NULL, imf_write,NULL,NULL, dev); + + dev->pos_regs[port & 7] = val; + + if (dev->pos_regs[2] & 1) { + addr = (dev->pos_regs[2] & 2) ? 0x0330 : 0x1330; + + mpu401_init(dev, addr, + device_get_config_int("irq"), + device_get_config_int("mode")); + } } static void * mpu401_standalone_init(const device_t *info) { - mpu_t *mpu; + mpu_t *dev; - mpu = malloc(sizeof(mpu_t)); - memset(mpu, 0, sizeof(mpu_t)); + dev = malloc(sizeof(mpu_t)); + memset(dev, 0x00, sizeof(mpu_t)); - pclog("mpu_init\n"); - mpu401_init(mpu, device_get_config_hex16("base"), device_get_config_int("irq"), device_get_config_int("mode")); + if (info->flags & DEVICE_MCA) { + mca_add(mpu401_mca_read, mpu401_mca_write, dev); + dev->pos_regs[0] = 0x0F; + dev->pos_regs[1] = 0x6C; + } else { + mpu401_init(dev, + device_get_config_hex16("base"), + device_get_config_int("irq"), + device_get_config_int("mode")); + } - return(mpu); + return(dev); } static void mpu401_standalone_close(void *priv) { - mpu_t *mpu = (mpu_t *)priv; + mpu_t *dev = (mpu_t *)priv; - free(mpu); + free(dev); } @@ -995,10 +1054,10 @@ static const device_config_t mpu401_standalone_config[] = } }; - const device_t mpu401_device = { "MPU-401 (Standalone)", - 0, 0, + DEVICE_ISA, + 0, mpu401_standalone_init, mpu401_standalone_close, NULL, NULL, NULL, @@ -1006,3 +1065,63 @@ const device_t mpu401_device = { NULL, mpu401_standalone_config }; + + +static const device_config_t mpu401_mca_standalone_config[] = +{ + { + "irq", "MPU-401 IRQ", CONFIG_SELECTION, "", 9, + { + { + "IRQ 9", 9 + }, + { + "IRQ 3", 3 + }, + { + "IRQ 4", 4 + }, + { + "IRQ 5", 5 + }, + { + "IRQ 7", 7 + }, + { + "IRQ 10", 10 + }, + { + "" + } + } + }, + { + "mode", "Mode", CONFIG_SELECTION, "", 1, + { + { + "UART", M_UART + }, + { + "Intelligent", M_INTELLIGENT + }, + { + "" + } + } + }, + { + "", "", -1 + } +}; + +const device_t mpu401_mca_device = { + "MPU-401 MCA (Standalone)", + DEVICE_MCA, + 0, + mpu401_standalone_init, mpu401_standalone_close, NULL, + NULL, + NULL, + NULL, + NULL, + mpu401_mca_standalone_config +}; diff --git a/src/devices/sound/snd_mpu401.h b/src/devices/sound/snd_mpu401.h index 46cdf6c..39c802f 100644 --- a/src/devices/sound/snd_mpu401.h +++ b/src/devices/sound/snd_mpu401.h @@ -8,7 +8,7 @@ * * Roland MPU-401 emulation. * - * Version: @(#)snd_mpu401.h 1.0.3 2018/04/08 + * Version: @(#)snd_mpu401.h 1.0.4 2018/09/03 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -120,10 +120,14 @@ typedef struct { uint8_t cth_rate,cth_counter; int clock_to_host,cth_active; } clock; + + uint8_t pos_regs[8]; } mpu_t; -extern const device_t mpu401_device; +extern int mca_version; +extern const device_t mpu401_device; +extern const device_t mpu401_mca_device; extern uint8_t MPU401_ReadData(mpu_t *mpu); diff --git a/src/devices/video/vid_ati28800.c b/src/devices/video/vid_ati28800.c index ae554fc..d21d86f 100644 --- a/src/devices/video/vid_ati28800.c +++ b/src/devices/video/vid_ati28800.c @@ -8,7 +8,7 @@ * * ATI 28800 emulation (VGA Charger and Korean VGA) * - * Version: @(#)vid_ati28800.c 1.0.14 2018/06/11 + * Version: @(#)vid_ati28800.c 1.0.15 2018/09/03 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -53,6 +53,7 @@ #include "video.h" #include "vid_svga.h" #include "vid_svga_render.h" +#include "vid_sc1502x_ramdac.h" #include "vid_ati_eeprom.h" @@ -79,6 +80,9 @@ typedef struct { int index; uint32_t memory; + uint8_t id; + + sc1502x_ramdac_t ramdac; uint8_t port_03dd_val; uint16_t get_korean_font_kind; @@ -106,21 +110,37 @@ ati28800_out(uint16_t addr, uint8_t val, void *p) addr ^= 0x60; switch (addr) { - case 0x1ce: + case 0x1CE: ati->index = val; break; - case 0x1cf: + case 0x1CF: old = ati->regs[ati->index]; ati->regs[ati->index] = val; +#if 0 + pclog("ATI write reg=%02x\n", ati->index); +#endif switch (ati->index) { case 0xb2: + case 0xbd: case 0xbe: if (ati->regs[0xbe] & 8) /*Read/write bank mode*/ { - svga->read_bank = ((ati->regs[0xb2] >> 5) & 7) * 0x10000; - svga->write_bank = ((ati->regs[0xb2] >> 1) & 7) * 0x10000; - } else /*Single bank mode*/ - svga->read_bank = svga->write_bank = ((ati->regs[0xb2] >> 1) & 7) * 0x10000; + if (ati->regs[0xbd] & 4) { + svga->read_bank = (((ati->regs[0xb2] >> 5) & 7) * 0x20000); + svga->write_bank = (((ati->regs[0xb2] >> 1) & 7) * 0x20000); + } else { + svga->read_bank = (((ati->regs[0xb2] >> 5) & 7) * 0x10000); + svga->write_bank = (((ati->regs[0xb2] >> 1) & 7) * 0x10000); + } + } else { /*Single bank mode*/ + if (ati->regs[0xbd] & 4) { + svga->read_bank = (((ati->regs[0xb2] >> 1) & 7) * 0x20000); + svga->write_bank = (((ati->regs[0xb2] >> 1) & 7) * 0x20000); + } else { + svga->read_bank = (((ati->regs[0xb2] >> 1) & 7) * 0x10000); + svga->write_bank = (((ati->regs[0xb2] >> 1) & 7) * 0x10000); + } + } break; case 0xb3: @@ -143,6 +163,13 @@ ati28800_out(uint16_t addr, uint8_t val, void *p) } break; + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + sc1502x_ramdac_out(addr, val, &ati->ramdac, svga); + return; + case 0x3D4: svga->crtcreg = val & 0x3f; return; @@ -162,6 +189,7 @@ ati28800_out(uint16_t addr, uint8_t val, void *p) } break; } + svga_out(addr, val, svga); } @@ -245,19 +273,24 @@ ati28800_in(uint16_t addr, void *p) (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60; switch (addr) { - case 0x1ce: + case 0x1CE: temp = ati->index; break; - case 0x1cf: + case 0x1CF: switch (ati->index) { + case 0xaa: + temp = ati->id; + break; + case 0xb0: - if (ati->memory == 256) - return 0x08; + if (ati->memory == 1024) + temp = 0x08; else if (ati->memory == 512) - return 0x10; + temp = 0x10; else - return 0x18; + temp = 0x00; + ati->regs[0xb0] |= temp; break; case 0xb7: @@ -272,13 +305,19 @@ ati28800_in(uint16_t addr, void *p) } break; - case 0x3c2: + case 0x3C2: if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50) temp = 0; else temp = 0x10; break; + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + return sc1502x_ramdac_in(addr, &ati->ramdac, svga); + case 0x3D4: temp = svga->crtcreg; break; @@ -390,10 +429,20 @@ ati28800_recalctimings(svga_t *svga) if (!svga->scrblank && (ati->regs[0xb0] & 0x20)) { /* Extended 256 color modes. */ - svga->render = svga_render_8bpp_highres; - svga->bpp = 8; - svga->rowoffset <<= 1; - svga->ma <<= 1; + switch (svga->bpp) { + case 8: + svga->render = svga_render_8bpp_highres; + svga->rowoffset <<= 1; + svga->ma <<= 1; + break; + + case 15: + svga->render = svga_render_15bpp_highres; + svga->hdisp >>= 1; + svga->rowoffset <<= 1; + svga->ma <<= 1; + break; + } } } @@ -410,6 +459,7 @@ ati28800_init(const device_t *info) switch(info->local) { case VID_VGAWONDERXL: + ati->id = 6; rom_init_interleaved(&ati->bios_rom, BIOS_VGAXL_EVEN_PATH, BIOS_VGAXL_ODD_PATH, @@ -419,6 +469,7 @@ ati28800_init(const device_t *info) #if defined(DEV_BRANCH) && defined(USE_XL24) case VID_VGAWONDERXL24: + ati->id = 6; rom_init_interleaved(&ati->bios_rom, BIOS_XL24_EVEN_PATH, BIOS_XL24_ODD_PATH, @@ -428,6 +479,7 @@ ati28800_init(const device_t *info) #endif default: + ati->id = 5; rom_init(&ati->bios_rom, BIOS_ROM_PATH, 0xc0000, 0x8000, 0x7fff, diff --git a/src/devices/video/video_dev.c b/src/devices/video/video_dev.c index a76eebf..75283c0 100644 --- a/src/devices/video/video_dev.c +++ b/src/devices/video/video_dev.c @@ -12,7 +12,7 @@ * an "extern" reference to its device into this file, and * add an entry for it into the table. * - * Version: @(#)video_dev.c 1.0.20 2018/08/25 + * Version: @(#)video_dev.c 1.0.21 2018/09/03 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -265,7 +265,7 @@ static vidcard_t video_cards[] = { {"[ISA] Trigem Korean VGA (ET4000AX)", "tgkorvga", &et4000k_isa_device, VID_TGKOREANVGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 3, 3, 6, 5, 5, 10}}, {"[ISA] VGA", "vga", &vga_device, VID_VGA, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, {"[ISA] Wyse 700", "wy700", &wy700_device, VID_WY700, VIDEO_FLAG_TYPE_CGA, {VIDEO_ISA, 8, 16, 32, 8, 16, 32}}, - {"[MCA] Tseng ET4000AX", "et4000ax_mca", &et4000_mca_device, VID_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_MCA, 3, 3, 6, 5, 5, 10}}, + {"[MCA] Tseng ET4000AX", "et4000ax_mca", &et4000_mca_device, VID_ET4000, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_MCA, 4, 5, 10, 5, 5, 10}}, {"[PCI] ATI Graphics Pro Turbo (Mach64 GX)", "mach64gx_pci", &mach64gx_pci_device, VID_MACH64GX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"[PCI] ATI Video Xpression (Mach64 VT2)", "mach64vt2", &mach64vt2_device, VID_MACH64VT2, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 2, 2, 1, 20, 20, 21}}, {"[PCI] Cardex Tseng ET4000/w32p", "et4000w32p_pci", &et4000w32p_cardex_pci_device, VID_ET4000W32_CARDEX_PCI, VIDEO_FLAG_TYPE_SPECIAL, {VIDEO_BUS, 4, 4, 4, 10, 10, 10}}, diff --git a/src/mem.c b/src/mem.c index e6c9031..c0669b8 100644 --- a/src/mem.c +++ b/src/mem.c @@ -12,7 +12,7 @@ * the DYNAMIC_TABLES=1 enables this. Will eventually go * away, either way... * - * Version: @(#)mem.c 1.0.19 2018/08/25 + * Version: @(#)mem.c 1.0.20 2018/09/03 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1337,6 +1337,7 @@ mem_mapping_recalc(uint64_t base, uint64_t size) _mem_read_b[c >> 14] = NULL; _mem_read_w[c >> 14] = NULL; _mem_read_l[c >> 14] = NULL; + _mem_exec[c >> 14] = NULL; _mem_priv_r[c >> 14] = NULL; _mem_mapping_r[c >> 14] = NULL; _mem_write_b[c >> 14] = NULL; @@ -1845,7 +1846,8 @@ mem_remap_top(int kb) uint32_t start = (mem_size >= 1024) ? mem_size : 1024; int size = mem_size - 640; -pclog("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); + pclog("MEM: remapping top %iKB (mem=%i)\n", kb, mem_size); + if (mem_size <= 640) return; if (kb == 0) { diff --git a/src/pc.c b/src/pc.c index 44860ba..f6d701d 100644 --- a/src/pc.c +++ b/src/pc.c @@ -8,7 +8,7 @@ * * Main emulator module where most things are controlled. * - * Version: @(#)pc.c 1.0.52 2018/08/27 + * Version: @(#)pc.c 1.0.53 2018/09/03 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -109,7 +109,7 @@ int config_ro = 0; /* (O) dont modify cfg file */ wchar_t log_path[1024] = { L'\0'}; /* (O) full path of logfile */ /* Configuration values. */ -int lang_id = 0; /* (C) language ID */ +int lang_id = 0x0409; /* (C) language ID */ int window_w, window_h, /* (C) window size and */ window_x, window_y, /* position info */ window_remember; diff --git a/src/win/win_settings_disk.h b/src/win/win_settings_disk.h index 4df6bad..bfa7a3b 100644 --- a/src/win/win_settings_disk.h +++ b/src/win/win_settings_disk.h @@ -8,7 +8,7 @@ * * Implementation of the Settings dialog. * - * Version: @(#)win_settings_disk.h 1.0.12 2018/05/27 + * Version: @(#)win_settings_disk.h 1.0.13 2018/09/03 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -1744,7 +1744,7 @@ hd_bus_skip: return FALSE; case IDC_BUTTON_HDD_REMOVE: - memcpy(temp_hdd[hdlv_current_sel].fn, L"", 4); + wcscpy(temp_hdd[hdlv_current_sel].fn, L""); disk_untrack(hdlv_current_sel); temp_hdd[hdlv_current_sel].bus = HDD_BUS_DISABLED; /* Only set the bus to zero, the list normalize code below will take care of turning this entire entry to a complete zero. */ disk_normalize_list(); /* Normalize the hard disks so that non-disabled hard disks start from index 0, and so they are contiguous. */ diff --git a/src/win/win_settings_sound.h b/src/win/win_settings_sound.h index f2a9fd1..3bfe222 100644 --- a/src/win/win_settings_sound.h +++ b/src/win/win_settings_sound.h @@ -8,7 +8,7 @@ * * Implementation of the Settings dialog. * - * Version: @(#)win_settings_sound.h 1.0.9 2018/05/21 + * Version: @(#)win_settings_sound.h 1.0.10 2018/09/03 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -57,8 +57,9 @@ mpu401_present(void) stransi = sound_card_get_internal_name(temp_sound_card); if (stransi != NULL) { - if (!strcmp(stransi, "sb16") || !strcmp(stransi, "sbawe32")) - return 1; + if (!strcmp(stransi, "sb16") || + !strcmp(stransi, "sbawe32") || + !strcmp(stransi, "replysb16")) return 1; } return temp_mpu401 ? 1 : 0; @@ -73,8 +74,9 @@ mpu401_standalone_allow(void) n = sound_card_get_internal_name(temp_sound_card); md = midi_device_get_internal_name(temp_midi_device); if (n != NULL) { - if (!strcmp(n, "sb16") || !strcmp(n, "sbawe32")) - return 0; + if (!strcmp(n, "sb16") || + !strcmp(n, "sbawe32") || + !strcmp(n, "replysb16")) return 0; } if (md != NULL) { @@ -235,7 +237,15 @@ sound_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) break; case IDC_CONFIGURE_MPU401: - temp_deviceconfig |= dlg_devconf(hdlg, (void *)&mpu401_device); + stransi = sound_card_get_internal_name(temp_sound_card); + if (stransi != NULL) { + if (! strcmp(stransi, "ncraudio")) + mca_version = 1; + else + mca_version = 0; + } + + temp_deviceconfig |= dlg_devconf(hdlg, mca_version ? (void *)&mpu401_mca_device : (void *)&mpu401_device); break; } return FALSE;