diff --git a/src/cdrom/cdrom_image.c b/src/cdrom/cdrom_image.c index 44f45bdc4..816a563d8 100644 --- a/src/cdrom/cdrom_image.c +++ b/src/cdrom/cdrom_image.c @@ -1975,7 +1975,8 @@ image_load_mds(cd_image_t *img, const char *mdsfile) success = 2; fseek(fp, 0, SEEK_SET); - fread(&mds_hdr, 1, sizeof(mds_hdr_t), fp); + if (fread(&mds_hdr, 1, sizeof(mds_hdr_t), fp) != sizeof(mds_hdr_t)) + return 0; if (memcmp(mds_hdr.file_sig, "MEDIA DESCRIPTOR", 16)) { #ifdef ENABLE_IMAGE_LOG @@ -2004,12 +2005,14 @@ image_load_mds(cd_image_t *img, const char *mdsfile) if (img->is_dvd) { if (mds_hdr.disc_struct_offs != 0x00) { fseek(fp, mds_hdr.disc_struct_offs, SEEK_SET); - fread(&(img->dstruct.layers[0]), 1, sizeof(layer_t), fp); + if (fread(&(img->dstruct.layers[0]), 1, sizeof(layer_t), fp) != sizeof(layer_t)) + return 0; img->has_dstruct = 1; if (((img->dstruct.layers[0].f0[2] & 0x60) >> 4) == 0x01) { fseek(fp, mds_hdr.disc_struct_offs, SEEK_SET); - fread(&(img->dstruct.layers[1]), 1, sizeof(layer_t), fp); + if (fread(&(img->dstruct.layers[1]), 1, sizeof(layer_t), fp) != sizeof(layer_t)) + return 0; img->has_dstruct++; } } @@ -2043,14 +2046,17 @@ image_load_mds(cd_image_t *img, const char *mdsfile) if (mds_hdr.dpm_blocks_offs != 0x00) { fseek(fp, mds_hdr.dpm_blocks_offs, SEEK_SET); - fread(&mds_dpm_blocks_num, 1, sizeof(uint32_t), fp); + if (fread(&mds_dpm_blocks_num, 1, sizeof(uint32_t), fp) != sizeof(uint32_t)) + return 0; if (mds_dpm_blocks_num > 0) for (int b = 0; b < mds_dpm_blocks_num; b++) { fseek(fp, mds_hdr.dpm_blocks_offs + 4 + (b * 4), SEEK_SET); - fread(&mds_dpm_block_offs, 1, sizeof(uint32_t), fp); + if (fread(&mds_dpm_block_offs, 1, sizeof(uint32_t), fp) != sizeof(uint32_t)) + return 0; fseek(fp, mds_dpm_block_offs, SEEK_SET); - fread(&mds_dpm_block, 1, sizeof(mds_dpm_block_t), fp); + if (fread(&mds_dpm_block, 1, sizeof(mds_dpm_block_t), fp) != sizeof(mds_dpm_block_t)) + return 0; /* We currently only support the bad sectors block and not (yet) actual DPM. */ if (mds_dpm_block.type == 0x00000002) { @@ -2058,7 +2064,9 @@ image_load_mds(cd_image_t *img, const char *mdsfile) img->bad_sectors_num = mds_dpm_block.entries; img->bad_sectors = (uint32_t *) malloc(img->bad_sectors_num * sizeof(uint32_t)); fseek(fp, mds_dpm_block_offs + sizeof(mds_dpm_block_t), SEEK_SET); - fread(img->bad_sectors, 1, img->bad_sectors_num * sizeof(uint32_t), fp); + int read_size = img->bad_sectors_num * sizeof(uint32_t); + if (fread(img->bad_sectors, 1, read_size, fp) != read_size) + return 0; break; } } @@ -2066,11 +2074,13 @@ image_load_mds(cd_image_t *img, const char *mdsfile) for (int s = 0; s < mds_hdr.sess_num; s++) { fseek(fp, mds_hdr.sess_blocks_offs + (s * sizeof(mds_sess_block_t)), SEEK_SET); - fread(&mds_sess_block, 1, sizeof(mds_sess_block_t), fp); + if (fread(&mds_sess_block, 1, sizeof(mds_sess_block_t), fp) != sizeof(mds_sess_block_t)) + return 0; for (int t = 0; t < mds_sess_block.all_blocks_num; t++) { fseek(fp, mds_sess_block.trk_blocks_offs + (t * sizeof(mds_trk_block_t)), SEEK_SET); - fread(&mds_trk_block, 1, sizeof(mds_trk_block_t), fp); + if (fread(&mds_trk_block, 1, sizeof(mds_trk_block_t), fp) != sizeof(mds_trk_block_t)) + return 0; if (last_t != -1) { /* @@ -2097,7 +2107,8 @@ image_load_mds(cd_image_t *img, const char *mdsfile) mds_trk_ex_block.trk_sectors = mds_trk_block.ex_offs; } else if (mds_trk_block.ex_offs != 0ULL) { fseek(fp, mds_trk_block.ex_offs, SEEK_SET); - fread(&mds_trk_ex_block, 1, sizeof(mds_trk_ex_block), fp); + if (fread(&mds_trk_ex_block, 1, sizeof(mds_trk_ex_block), fp) != sizeof(mds_trk_ex_block)) + return 0; } uint32_t astart = mds_trk_block.start_sect - mds_trk_ex_block.pregap; @@ -2107,20 +2118,23 @@ image_load_mds(cd_image_t *img, const char *mdsfile) if (mds_trk_block.footer_offs != 0ULL) for (uint32_t ff = 0; ff < mds_trk_block.files_num; ff++) { fseek(fp, mds_trk_block.footer_offs + (ff * sizeof(mds_footer_t)), SEEK_SET); - fread(&mds_footer, 1, sizeof(mds_footer_t), fp); + if (fread(&mds_footer, 1, sizeof(mds_footer_t), fp) != sizeof(mds_footer_t)) + return 0; uint16_t wfn[2048] = { 0 }; char fn[2048] = { 0 }; fseek(fp, mds_footer.fn_offs, SEEK_SET); if (mds_footer.fn_is_wide) { for (int i = 0; i < 256; i++) { - fread(&(wfn[i]), 1, 2, fp); + if (fread(&(wfn[i]), 1, 2, fp) != 2) + return 0; if (wfn[i] == 0x0000) break; } (void) utf16_to_utf8(wfn, 2048, (uint8_t *) fn, 2048); } else for (int i = 0; i < 512; i++) { - fread(&fn[i], 1, 1, fp); + if (fread(&fn[i], 1, 1, fp) != 1) + return 0; if (fn[i] == 0x00) break; } diff --git a/src/config.c b/src/config.c index 43757d6a4..d3bc0c2de 100644 --- a/src/config.c +++ b/src/config.c @@ -211,6 +211,8 @@ load_general(void) rctrl_is_lalt = ini_section_get_int(cat, "rctrl_is_lalt", 0); update_icons = ini_section_get_int(cat, "update_icons", 1); + start_in_fullscreen |= ini_section_get_int(cat, "start_in_fullscreen", 0); + window_remember = ini_section_get_int(cat, "window_remember", 0); if (!window_remember && !(vid_resize & 2)) @@ -884,6 +886,10 @@ load_ports(void) if (!has_jumpers || (jumpered_internal_ecp_dma == def_jumper)) ini_section_delete_var(cat, "jumpered_internal_ecp_dma"); + else if (has_jumpers && !(machine_has_jumpered_ecp_dma(machine, jumpered_internal_ecp_dma))) { + jumpered_internal_ecp_dma = def_jumper; + ini_section_delete_var(cat, "jumpered_internal_ecp_dma"); + } for (int c = 0; c < (SERIAL_MAX - 1); c++) { sprintf(temp, "serial%d_enabled", c + 1); @@ -2406,6 +2412,11 @@ save_general(void) else ini_section_delete_var(cat, "window_remember"); + if (video_fullscreen) + ini_section_set_int(cat, "start_in_fullscreen", video_fullscreen); + else + ini_section_delete_var(cat, "start_in_fullscreen"); + if (vid_resize & 2) { sprintf(temp, "%ix%i", fixed_size_x, fixed_size_y); ini_section_set_string(cat, "window_fixed_res", temp); @@ -2908,7 +2919,10 @@ save_ports(void) if (!has_jumpers || (jumpered_internal_ecp_dma == def_jumper)) ini_section_delete_var(cat, "jumpered_internal_ecp_dma"); - else + else if (has_jumpers && !(machine_has_jumpered_ecp_dma(machine, jumpered_internal_ecp_dma))) { + jumpered_internal_ecp_dma = def_jumper; + ini_section_set_int(cat, "jumpered_internal_ecp_dma", jumpered_internal_ecp_dma); + } else ini_section_set_int(cat, "jumpered_internal_ecp_dma", jumpered_internal_ecp_dma); for (int c = 0; c < (SERIAL_MAX - 1); c++) { diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index ec026d95e..ff806297e 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1080,6 +1080,9 @@ cpu_set(void) timing_jmp_rm = 12; timing_jmp_pm = 27; timing_jmp_pm_gate = 45; + + if (cpu_s->cpu_type == CPU_386DX) + cpu_cache_ext_enabled = 1; break; case CPU_486SLC: @@ -1161,6 +1164,8 @@ cpu_set(void) timing_jmp_pm_gate = 37; timing_misaligned = 3; + + cpu_cache_ext_enabled = 1; break; case CPU_i486SX_SLENH: @@ -4473,13 +4478,6 @@ cpu_update_waitstates(void) if (cpu_cache_int_enabled) { /* Disable prefetch emulation */ cpu_prefetch_cycles = 0; - } else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX)) { - /* Waitstates override */ - cpu_prefetch_cycles = cpu_waitstates + 1; - cpu_cycles_read = cpu_waitstates + 1; - cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); - cpu_cycles_write = cpu_waitstates + 1; - cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); } else if (cpu_cache_ext_enabled) { /* Use cache timings */ cpu_prefetch_cycles = cpu_s->cache_read_cycles; @@ -4487,6 +4485,13 @@ cpu_update_waitstates(void) cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_read_cycles; cpu_cycles_write = cpu_s->cache_write_cycles; cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * cpu_s->cache_write_cycles; + } else if (cpu_waitstates && (cpu_s->cpu_type >= CPU_286 && cpu_s->cpu_type <= CPU_386DX)) { + /* Waitstates override */ + cpu_prefetch_cycles = cpu_waitstates + 1; + cpu_cycles_read = cpu_waitstates + 1; + cpu_cycles_read_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); + cpu_cycles_write = cpu_waitstates + 1; + cpu_cycles_write_l = (cpu_16bitbus ? 2 : 1) * (cpu_waitstates + 1); } else { /* Use memory timings */ cpu_prefetch_cycles = cpu_s->mem_read_cycles; diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index db8c89ebb..3adbc7202 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -1367,8 +1367,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 3, .mem_write_cycles = 3, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 2 }, { @@ -1384,8 +1384,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1401,8 +1401,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1418,8 +1418,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 6, .mem_write_cycles = 6, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 4 }, { @@ -1435,8 +1435,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 7, .mem_write_cycles = 7, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 5 }, { .name = "", 0 } @@ -1461,8 +1461,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 3, .mem_write_cycles = 3, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 2 }, { @@ -1478,8 +1478,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1495,8 +1495,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { .name = "", 0 } @@ -1521,8 +1521,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = CPU_SUPPORTS_DYNAREC, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1538,8 +1538,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = CPU_SUPPORTS_DYNAREC, .mem_read_cycles = 6, .mem_write_cycles = 6, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 4 }, { @@ -1555,8 +1555,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = CPU_SUPPORTS_DYNAREC, .mem_read_cycles = 7, .mem_write_cycles = 7, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 5 }, { .name = "", 0 } @@ -1581,8 +1581,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 3 }, { @@ -1598,8 +1598,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 6, .mem_write_cycles = 6, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 4 }, { @@ -1615,8 +1615,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 7, .mem_write_cycles = 7, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 5 }, { .name = "", 0 } @@ -2096,7 +2096,7 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 4, .mem_write_cycles = 4, - .cache_read_cycles = 3, + .cache_read_cycles = 2, .cache_write_cycles = 3, .atclk_div = 3 }, @@ -2113,8 +2113,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 6, .mem_write_cycles = 6, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 4 }, { @@ -2130,8 +2130,8 @@ const cpu_family_t cpu_families[] = { .cpu_flags = 0, .mem_read_cycles = 7, .mem_write_cycles = 7, - .cache_read_cycles = 3, - .cache_write_cycles = 3, + .cache_read_cycles = 2, + .cache_write_cycles = 2, .atclk_div = 5 }, { .name = "", 0 } diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 4c0ea4155..186804e22 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -975,7 +975,7 @@ write_cmd_data_ami(void *priv, uint8_t val) return 0; case 0xc1: - kbc_at_log("ATkbc: AMI MegaKey - write %02X to P1\n", val); + kbc_at_log("ATkbc: AMI - write %02X to P1\n", val); dev->p1 = val; return 0; @@ -1160,11 +1160,14 @@ write_cmd_ami(void *priv, uint8_t val) case 0xaf: /* set extended controller RAM */ if ((kbc_ven != KBC_VEN_SIEMENS) && (kbc_ven != KBC_VEN_ALI)) { - kbc_at_log("ATkbc: set extended controller RAM\n"); - dev->wantdata = 1; - dev->state = STATE_KBC_PARAM; - dev->command_phase = 1; - ret = 0; + if (((kbc_ami_revision >= 'H') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + kbc_at_log("ATkbc: set extended controller RAM\n"); + dev->wantdata = 1; + dev->state = STATE_KBC_PARAM; + dev->command_phase = 1; + ret = 0; + } } break; @@ -1214,27 +1217,33 @@ write_cmd_ami(void *priv, uint8_t val) break; case 0xc1: /* write P1 */ - kbc_at_log("ATkbc: AMI MegaKey - write P1\n"); + kbc_at_log("ATkbc: AMI - write P1\n"); dev->wantdata = 1; dev->state = STATE_KBC_PARAM; ret = 0; break; case 0xc4: - /* set KBC line P14 low */ - kbc_at_log("ATkbc: set KBC line P14 (P1 bit 4) low\n"); - dev->p1 &= 0xef; - kbc_delay_to_ob(dev, dev->ob, 0, 0x00); - dev->pending++; - ret = 0; + if (((kbc_ami_revision >= 'P') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + /* set KBC line P14 low */ + kbc_at_log("ATkbc: set KBC line P14 (P1 bit 4) low\n"); + dev->p1 &= 0xef; + kbc_delay_to_ob(dev, dev->ob, 0, 0x00); + dev->pending++; + ret = 0; + } break; case 0xc5: - /* set KBC line P15 low */ - kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) low\n"); - dev->p1 &= 0xdf; - kbc_delay_to_ob(dev, dev->ob, 0, 0x00); - dev->pending++; - ret = 0; + if (((kbc_ami_revision >= 'P') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + /* set KBC line P15 low */ + kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) low\n"); + dev->p1 &= 0xdf; + kbc_delay_to_ob(dev, dev->ob, 0, 0x00); + dev->pending++; + ret = 0; + } break; case 0xc8: @@ -1271,20 +1280,26 @@ write_cmd_ami(void *priv, uint8_t val) break; case 0xcc: - /* set KBC line P14 high */ - kbc_at_log("ATkbc: set KBC line P14 (P1 bit 4) high\n"); - dev->p1 |= 0x10; - kbc_delay_to_ob(dev, dev->ob, 0, 0x00); - dev->pending++; - ret = 0; + if (((kbc_ami_revision >= 'P') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + /* set KBC line P14 high */ + kbc_at_log("ATkbc: set KBC line P14 (P1 bit 4) high\n"); + dev->p1 |= 0x10; + kbc_delay_to_ob(dev, dev->ob, 0, 0x00); + dev->pending++; + ret = 0; + } break; case 0xcd: /* set KBC line P15 high */ - kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) high\n"); - dev->p1 |= 0x20; - kbc_delay_to_ob(dev, dev->ob, 0, 0x00); - dev->pending++; - ret = 0; + if (((kbc_ami_revision >= 'P') && (kbc_ami_revision < 'X')) || + (kbc_ami_revision = '5')) { + kbc_at_log("ATkbc: set KBC line P15 (P1 bit 5) high\n"); + dev->p1 |= 0x20; + kbc_delay_to_ob(dev, dev->ob, 0, 0x00); + dev->pending++; + ret = 0; + } break; case 0xef: /* ??? - sent by AMI486 */ diff --git a/src/device/lpt.c b/src/device/lpt.c index 29689d2de..f7cc6eda0 100644 --- a/src/device/lpt.c +++ b/src/device/lpt.c @@ -236,7 +236,7 @@ lpt_fifo_out_callback(void *priv) { lpt_t *dev = (lpt_t *) priv; - switch (dev->state) { + if ((dev->ecr & 0xe0) != 0xc0) switch (dev->state) { default: break; @@ -281,7 +281,7 @@ lpt_fifo_out_callback(void *priv) } } - if (dev->ecr & 0x08) { + if (((dev->ecr & 0xe0) != 0xc0) && (dev->ecr & 0x08)) { if (fifo_get_empty(dev->fifo)) { if (dev->dma_stat) { /* Now actually set the external flag. */ @@ -319,7 +319,8 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv) switch (port & mask) { case 0x0000: if (dev->ecp) { - if ((dev->ecr & 0xe0) == 0x60) + if (((dev->ecr & 0xe0) == 0x40) || ((dev->ecr & 0xe0) == 0x60) || + ((dev->ecr & 0xe0) == 0xc0)) /* AFIFO */ lpt_write_fifo(dev, val, 0x00); else if (!(dev->ecr & 0xc0) && (!(dev->ecr & 0x20) || !(lpt_get_ctrl_raw(dev) & 0x20)) && @@ -398,18 +399,13 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv) switch (dev->ecr >> 5) { default: break; - case 2: + case 2: case 6: lpt_write_fifo(dev, val, 0x01); break; case 3: if (!(lpt_get_ctrl_raw(dev) & 0x20)) lpt_write_fifo(dev, val, 0x01); break; - case 6: - /* TFIFO */ - if (!fifo_get_full(dev->fifo)) - fifo_write_evt(val, dev->fifo); - break; } break; @@ -424,7 +420,8 @@ lpt_write(const uint16_t port, const uint8_t val, void *priv) timer_set_delay_u64(&dev->fifo_out_timer, (uint64_t) ((1000000.0 / 2500000.0) * (double) TIMER_USEC)); } else { dev->state = LPT_STATE_WRITE_FIFO; - if (lpt_get_ctrl_raw(dev) & 0x20) + if (((dev->ecr & 0xe0) == 0x40) || ((dev->ecr & 0xe0) == 0xc0) || + (lpt_get_ctrl_raw(dev) & 0x20)) dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x04 : 0x00; else dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x00 : 0x04; @@ -463,7 +460,8 @@ lpt_fifo_d_ready_evt(void *priv) lpt_t *dev = (lpt_t *) priv; if (!(dev->ecr & 0x08)) { - if (lpt_get_ctrl_raw(dev) & 0x20) + if (((dev->ecr & 0xe0) == 0xc0) || ((dev->ecr & 0xe0) == 0x40) || + (lpt_get_ctrl_raw(dev) & 0x20)) dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x04 : 0x00; else dev->fifo_stat = fifo_get_ready(dev->fifo) ? 0x00 : 0x04; @@ -480,11 +478,15 @@ lpt_write_to_fifo(void *priv, const uint8_t val) if (dev->ecp) { if (((dev->ecr & 0xe0) == 0x20) && (lpt_get_ctrl_raw(dev) & 0x20)) dev->dat = val; + else if (((dev->ecr & 0xe0) == 0x40) && !fifo_get_full(dev->fifo)) + fifo_write_evt_tagged(0x01, val, dev->fifo); + else if (((dev->ecr & 0xe0) == 0xc0) && !fifo_get_full(dev->fifo)) + fifo_write_evt_tagged(0x01, val, dev->fifo); else if (((dev->ecr & 0xe0) == 0x60) && (lpt_get_ctrl_raw(dev) & 0x20) && !fifo_get_full(dev->fifo)) fifo_write_evt_tagged(0x01, val, dev->fifo); - if (((dev->ecr & 0x0c) == 0x08) && (dev->dma != 0xff)) { + if (((dev->ecr & 0xe0) != 0xc0) && ((dev->ecr & 0x0c) == 0x08) && (dev->dma != 0xff)) { const int ret = dma_channel_write(dev->dma, val); if (ret & DMA_OVER) @@ -563,7 +565,16 @@ lpt_read(const uint16_t port, void *priv) switch (port & mask) { case 0x0000: if (dev->ecp) { - if (!(dev->ecr & 0xc0)) + if (dev->ecr & 0xc0) { + if (((dev->ecr & 0xe0) == 0xc0) && !fifo_get_empty(dev->fifo)) { + uint8_t tag = 0x00; + ret = fifo_read_evt_tagged(&tag, dev->fifo); + } else if (((dev->ecr & 0xe0) == 0x60) && !(lpt_get_ctrl_raw(dev) & 0x20) && + !fifo_get_empty(dev->fifo)) { + uint8_t tag = 0x00; + ret = fifo_read_evt_tagged(&tag, dev->fifo); + } + } else ret = dev->dat; } else { /* DTR */ diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index ef8803812..7ab675a6c 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1046,6 +1046,9 @@ extern int machine_at_via809ds_init(const machine_t *); /* SiS 5571 */ extern int machine_at_cb52xsi_init(const machine_t *); extern int machine_at_ms5146_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t r534f_device; +#endif extern int machine_at_r534f_init(const machine_t *); /* SiS 5581 */ diff --git a/src/include/86box/network.h b/src/include/86box/network.h index 01454c6f9..5a6651b5b 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -105,6 +105,7 @@ typedef struct netcard_conf_t { extern netcard_conf_t net_cards_conf[NET_CARD_MAX]; extern uint16_t net_card_current; +extern int slirp_card_num; typedef int (*NETRXCB)(void *, uint8_t *, int); typedef int (*NETSETLINKSTATE)(void *, uint32_t link_state); diff --git a/src/include/86box/net_eeprom_nmc93cxx.h b/src/include/86box/nmc93cxx.h similarity index 100% rename from src/include/86box/net_eeprom_nmc93cxx.h rename to src/include/86box/nmc93cxx.h diff --git a/src/include/86box/scsi_disk.h b/src/include/86box/scsi_disk.h index 293cc35e6..2d2371172 100644 --- a/src/include/86box/scsi_disk.h +++ b/src/include/86box/scsi_disk.h @@ -29,6 +29,7 @@ typedef struct scsi_disk_t { void * log; uint8_t * temp_buffer; + size_t temp_buffer_sz; uint8_t atapi_cdb[16]; uint8_t current_cdb[16]; uint8_t sense[256]; diff --git a/src/include/86box/vid_ddc.h b/src/include/86box/vid_ddc.h index 8d68d0adf..32c8e88c5 100644 --- a/src/include/86box/vid_ddc.h +++ b/src/include/86box/vid_ddc.h @@ -20,8 +20,9 @@ #ifndef EMU_VID_DDC_H #define EMU_VID_DDC_H -extern void *ddc_init(void *i2c); -extern void ddc_close(void *eeprom); -extern void *ddc_create_default_edid(ssize_t* size_out); +extern void *ddc_init(void *i2c); +extern void ddc_close(void *eeprom); +extern size_t ddc_create_default_edid(uint8_t **size_out); +extern size_t ddc_load_edid(char *path, uint8_t *buf, size_t size); #endif /*EMU_VID_DDC_H*/ diff --git a/src/machine/m_at_socket3.c b/src/machine/m_at_socket3.c index 32cb77973..2d6ea9730 100644 --- a/src/machine/m_at_socket3.c +++ b/src/machine/m_at_socket3.c @@ -178,11 +178,11 @@ static const device_config_t j403tg_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "AMI 060692", .internal_name = "403tg", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.50G", .internal_name = "403tg", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/403tg/403TG.BIN", "" } }, - { .name = "AMI 060692", .internal_name = "403tg_d", .bios_type = BIOS_NORMAL, + { .name = "AMI WinBIOS (121593)", .internal_name = "403tg_d", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/403tg/J403TGRevD.BIN", "" } }, - { .name = "AMI 060692", .internal_name = "403tg_d_mr", .bios_type = BIOS_NORMAL, + { .name = "MR BIOS V2.02", .internal_name = "403tg_d_mr", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 65536, .files = { "roms/machines/403tg/MRBiosOPT895.bin", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_socket3_pci.c b/src/machine/m_at_socket3_pci.c index 451d791ca..c122caa2d 100644 --- a/src/machine/m_at_socket3_pci.c +++ b/src/machine/m_at_socket3_pci.c @@ -291,17 +291,17 @@ static const device_config_t pc330_6573_config[] = { // clang-format off { .name = "bios", - .description = "BIOS Version", + .description = "BIOS Language", .type = CONFIG_BIOS, .default_string = "pc330_6573", .default_int = 0, .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "IBM Aptiva 510/710/Vision", .internal_name = "aptiva510", .bios_type = BIOS_NORMAL, - .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pc330_6573/aptiva510_$IMAGES.USF", "" } }, - { .name = "IBM PC 330 (type 6573)", .internal_name = "pc330_6573", .bios_type = BIOS_NORMAL, + { .name = "English (PC 330, type 6573)", .internal_name = "pc330_6573", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pc330_6573/$IMAGES.USF", "" } }, + { .name = "Japanese (Aptiva 510/710/Vision)", .internal_name = "aptiva510", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/pc330_6573/aptiva510_$IMAGES.USF", "" } }, { .files_no = 0 } }, }, @@ -1354,7 +1354,7 @@ static const device_config_t hot433a_config[] = { .bios = { { .name = "AMIBIOS 5 (101094) - Revision 433AUS33", .internal_name = "hot433a", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/hot433/433AUS33.ROM", "" } }, - { .name = "AwardBIOS v4.51PG - Revision 2.5 (by eSupport)", .internal_name = "hot433a_v451pg", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 2.5 (by eSupport)", .internal_name = "hot433a_v451pg", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/hot433/2A4X5H21.BIN", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_socket4.c b/src/machine/m_at_socket4.c index d1f9c637f..5e1bf533f 100644 --- a/src/machine/m_at_socket4.c +++ b/src/machine/m_at_socket4.c @@ -288,11 +288,11 @@ static const device_config_t batman_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "AMBRA DP60 PCI", .internal_name = "ambradp60", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/batman/1004AF1P.BIO", "roms/machines/batman/1004AF1P.BI1", "" } }, - { .name = "Dell Dimension XPS P60", .internal_name = "dellxp60", .bios_type = BIOS_NORMAL, + { .name = "AMIBIOS 111192 - Revision A08 (Dell Dimension XPS P60)", .internal_name = "dellxp60", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/batman/XP60-A08.ROM", "" } }, - { .name = "Intel Premiere/PCI (Batman)", .internal_name = "batman", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.04.AF1P (AMBRA DP60 PCI)", .internal_name = "ambradp60", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/batman/1004AF1P.BIO", "roms/machines/batman/1004AF1P.BI1", "" } }, + { .name = "Intel AMIBIOS - Revision 1.00.08.AF1", .internal_name = "batman", .bios_type = BIOS_NORMAL, .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/batman/1008AF1_.BIO", "roms/machines/batman/1008AF1_.BI1", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_socket5.c b/src/machine/m_at_socket5.c index a55e2bc2d..cb3803e0d 100644 --- a/src/machine/m_at_socket5.c +++ b/src/machine/m_at_socket5.c @@ -100,12 +100,12 @@ static const device_config_t plato_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "AMBRA DP90 PCI", .internal_name = "ambradp90", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.02.AX1P (AMBRA DP90 PCI)", .internal_name = "ambradp90", .bios_type = BIOS_NORMAL, .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/plato/1002AX1P.BIO", "roms/machines/plato/1002AX1P.BI1", "" } }, - { .name = "Dell Dimension XPS Pxxx", .internal_name = "dellplato", .bios_type = BIOS_NORMAL, - .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/plato/1016AX1J.BIO", "roms/machines/plato/1016AX1J.BI1", "" } }, - { .name = "Intel Premiere/PCI II (Plato)", .internal_name = "plato", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.16.AX1", .internal_name = "plato", .bios_type = BIOS_NORMAL, .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/plato/1016ax1_.bio", "roms/machines/plato/1016ax1_.bi1", "" } }, + { .name = "Intel AMIBIOS - Revision 1.00.16.AX1J (Dell Dimension XPS P___)", .internal_name = "dellplato", .bios_type = BIOS_NORMAL, + .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/plato/1016AX1J.BIO", "roms/machines/plato/1016AX1J.BI1", "" } }, { .files_no = 0 } }, }, diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index cbc5ec05f..b0651a8af 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -151,14 +151,14 @@ static const device_config_t cu430hx_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Intel CU430HX (Cumberland)", .internal_name = "cu430hx", .bios_type = BIOS_NORMAL, - .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1006DK0_.BIO", "roms/machines/cu430hx/1006DK0_.BI1", - "roms/machines/cu430hx/1006DK0_.BI2", "roms/machines/cu430hx/1006DK0_.BI3", - "roms/machines/cu430hx/1006DK0_.RCV", "" } }, - { .name = "Toshiba Equium 5200D", .internal_name = "equium5200", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.03.DK08 (Toshiba Equium 5200D)", .internal_name = "equium5200", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1003DK08.BIO", "roms/machines/cu430hx/1003DK08.BI1", "roms/machines/cu430hx/1003DK08.BI2", "roms/machines/cu430hx/1003DK08.BI3", "roms/machines/cu430hx/1003DK08.RCV", "" } }, + { .name = "Intel AMIBIOS - Revision 1.00.06.DK0", .internal_name = "cu430hx", .bios_type = BIOS_NORMAL, + .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/cu430hx/1006DK0_.BIO", "roms/machines/cu430hx/1006DK0_.BI1", + "roms/machines/cu430hx/1006DK0_.BI2", "roms/machines/cu430hx/1006DK0_.BI3", + "roms/machines/cu430hx/1006DK0_.RCV", "" } }, { .files_no = 0 } }, }, @@ -262,11 +262,11 @@ static const device_config_t tc430hx_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Intel TC430HX (Tucson)", .internal_name = "tc430hx", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.07.DH0", .internal_name = "tc430hx", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/tc430hx/1007DH0_.BIO", "roms/machines/tc430hx/1007DH0_.BI1", "roms/machines/tc430hx/1007DH0_.BI2", "roms/machines/tc430hx/1007DH0_.BI3", "roms/machines/tc430hx/1007DH0_.RCV", "" } }, - { .name = "Toshiba Infinia 7201", .internal_name = "infinia7200", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.08.DH08 (Toshiba Infinia 7201)", .internal_name = "infinia7200", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/tc430hx/1008DH08.BIO", "roms/machines/tc430hx/1008DH08.BI1", "roms/machines/tc430hx/1008DH08.BI2", "roms/machines/tc430hx/1008DH08.BI3", "roms/machines/tc430hx/1008DH08.RCV", "" } }, @@ -830,9 +830,9 @@ static const device_config_t lgibmx52_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "08/21/97", .internal_name = "lgibmx52_082197", .bios_type = BIOS_NORMAL, + { .name = "PhoenixBIOS 4.05 - Revision 08/21/97", .internal_name = "lgibmx52_082197", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/lgibmx52/BIOS.ROM", "" } }, - { .name = "03/26/99", .internal_name = "lgibmx52", .bios_type = BIOS_NORMAL, + { .name = "PhoenixBIOS 4.05 - Revision 03/26/99", .internal_name = "lgibmx52", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/lgibmx52/MS5136 LG IBM OEM.ROM", "" } }, { .files_no = 0 } }, @@ -1590,17 +1590,57 @@ machine_at_ms5146_init(const machine_t *model) return ret; } +static const device_config_t r534f_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "r534f_1998", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .bios = { + { .name = "Award Modular BIOS v4.51PG - Revision 06/12/1998", .internal_name = "r534f_1998", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/r534f/r534f008-1998.bin", "" } }, + { .name = "Award Modular BIOS v4.51PG - Revision 03/13/2000 (by Unicore Software)", .internal_name = "r534f", .bios_type = BIOS_NORMAL, + .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/r534f/r534f008.bin", "" } }, + { .files_no = 0 } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t r534f_device = { + .name = "Rise R534F", + .internal_name = "r534f_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = r534f_config +}; + int machine_at_r534f_init(const machine_t *model) { - int ret; + int ret = 0; + const char* fn; - ret = bios_load_linear("roms/machines/r534f/r534f008.bin", - 0x000e0000, 131072, 0); - - if (bios_only || !ret) + /* No ROMs available */ + if (!device_available(model->device)) return ret; + device_context(model->device); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + machine_at_common_init_ex(model, 2); pci_init(PCI_CONFIG_TYPE_1 | FLAG_TRC_CONTROLS_CPURST); @@ -1713,9 +1753,9 @@ static const device_config_t m5ata_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "12/23/97", .internal_name = "m5ata", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 12/23/97", .internal_name = "m5ata", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/m5ata/ATA1223.BIN", "" } }, - { .name = "05/27/98", .internal_name = "m5ata_0527b", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 05/27/98", .internal_name = "m5ata_0527b", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/m5ata/ATA0527B.BIN", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_socket7_3v.c b/src/machine/m_at_socket7_3v.c index 64d8a0fd5..f289b2275 100644 --- a/src/machine/m_at_socket7_3v.c +++ b/src/machine/m_at_socket7_3v.c @@ -53,7 +53,7 @@ static const device_config_t p54tp4xe_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Award BIOS v4.51PG", .internal_name = "p54tp4xe", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 0302", .internal_name = "p54tp4xe", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/p54tp4xe/t15i0302.awd", "" } }, { .name = "MR BIOS V3.30", .internal_name = "p54tp4xe_mr", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/p54tp4xe/TRITON.BIO", "" } }, @@ -183,11 +183,11 @@ static const device_config_t thor_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Gateway 2000 (AMIBIOS)", .internal_name = "gw2katx", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.03.CN0T (Gateway 2000)", .internal_name = "gw2katx", .bios_type = BIOS_NORMAL, .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/thor/1003CN0T.BIO", "roms/machines/thor/1003CN0T.BI1", "" } }, - { .name = "Intel (AMIBIOS)", .internal_name = "thor", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.06.CN0", .internal_name = "thor", .bios_type = BIOS_NORMAL, .files_no = 2, .local = 0, .size = 131072, .files = { "roms/machines/thor/1006cn0_.bio", "roms/machines/thor/1006cn0_.bi1", "" } }, - { .name = "Intel (MR BIOS)", .internal_name = "mrthor", .bios_type = BIOS_NORMAL, + { .name = "MR BIOS V3.28", .internal_name = "mrthor", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/thor/mr_atx.bio", "" } }, { .files_no = 0 } }, @@ -798,11 +798,11 @@ static const device_config_t c5sbm2_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "AwardBIOS v4.50GP - Revision 07/17/1995", .internal_name = "5sbm2_v450gp", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.50GP - Revision 07/17/1995", .internal_name = "5sbm2_v450gp", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/5SBM0717.BIN", "" } }, - { .name = "AwardBIOS v4.50PG - Revision 03/26/1996", .internal_name = "5sbm2", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.50PG - Revision 03/26/1996", .internal_name = "5sbm2", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/5SBM0326.BIN", "" } }, - { .name = "AwardBIOS v4.51PG - Revision 2.2 (by Unicore Software)", .internal_name = "5sbm2_451pg", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision 2.2 (by Unicore Software)", .internal_name = "5sbm2_451pg", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/5sbm2/2A5ICC3A.BIN", "" } }, { .files_no = 0 } }, @@ -901,11 +901,11 @@ static const device_config_t ap5s_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "AwardBIOS v4.50PG - Revision R1.20", .internal_name = "ap5s_450pg", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.50PG - Revision R1.20", .internal_name = "ap5s_450pg", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/ap5s/ap5s120.bin", "" } }, - { .name = "AwardBIOS v4.51PG - Revision R1.50", .internal_name = "ap5s_r150", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision R1.50", .internal_name = "ap5s_r150", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/ap5s/AP5S150.BIN", "" } }, - { .name = "AwardBIOS v4.51PG - Revision R1.60", .internal_name = "ap5s", .bios_type = BIOS_NORMAL, + { .name = "Award Modular BIOS v4.51PG - Revision R1.60", .internal_name = "ap5s", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 131072, .files = { "roms/machines/ap5s/ap5s160.bin", "" } }, { .files_no = 0 } }, diff --git a/src/machine/m_at_socket8.c b/src/machine/m_at_socket8.c index e7975f601..3d5f4787e 100644 --- a/src/machine/m_at_socket8.c +++ b/src/machine/m_at_socket8.c @@ -331,15 +331,15 @@ static const device_config_t vs440fx_config[] = { .file_filter = "", .spinner = { 0 }, .bios = { - { .name = "Dell Dimension XPS Pro___n", .internal_name = "dellvenus", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.06.CS1J (Dell Dimension XPS Pro___n)", .internal_name = "dellvenus", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/vs440fx/1006CS1J.BIO", "roms/machines/vs440fx/1006CS1J.BI1", "roms/machines/vs440fx/1006CS1J.BI2", "roms/machines/vs440fx/1006CS1J.BI3", "roms/machines/vs440fx/1006CS1J.RCV", "" } }, - { .name = "Gateway 2000 Venus", .internal_name = "gw2kvenus", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.11.CS1T (Gateway 2000)", .internal_name = "gw2kvenus", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/vs440fx/1011CS1T.BIO", "roms/machines/vs440fx/1011CS1T.BI1", "roms/machines/vs440fx/1011CS1T.BI2", "roms/machines/vs440fx/1011CS1T.BI3", "roms/machines/vs440fx/1011CS1T.RCV", "" } }, - { .name = "Intel VS440FX (Venus)", .internal_name = "vs440fx", .bios_type = BIOS_NORMAL, + { .name = "Intel AMIBIOS - Revision 1.00.18.CS1", .internal_name = "vs440fx", .bios_type = BIOS_NORMAL, .files_no = 5, .local = 0, .size = 262144, .files = { "roms/machines/vs440fx/1018CS1_.BIO", "roms/machines/vs440fx/1018CS1_.BI1", "roms/machines/vs440fx/1018CS1_.BI2", "roms/machines/vs440fx/1018CS1_.BI3", "roms/machines/vs440fx/1018CS1_.RCV", "" } }, diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 30b859544..7891bb3db 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -15595,7 +15595,7 @@ const machine_t machines[] = { .kbc_p1 = 0x00000cf0, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &r534f_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, diff --git a/src/mem/CMakeLists.txt b/src/mem/CMakeLists.txt index 0e52beb4e..3984c2d02 100644 --- a/src/mem/CMakeLists.txt +++ b/src/mem/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(mem OBJECT intel_flash.c mem.c mmu_2386.c + nmc93cxx.c rom.c row.c smram.c diff --git a/src/network/net_eeprom_nmc93cxx.c b/src/mem/nmc93cxx.c similarity index 97% rename from src/network/net_eeprom_nmc93cxx.c rename to src/mem/nmc93cxx.c index 05fd43ed0..50905bae2 100644 --- a/src/network/net_eeprom_nmc93cxx.c +++ b/src/mem/nmc93cxx.c @@ -28,7 +28,7 @@ #include <86box/device.h> #include <86box/timer.h> #include <86box/nvr.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/plat_unused.h> #ifdef ENABLE_NMC93CXX_EEPROM_LOG @@ -256,7 +256,12 @@ static void nmc93cxx_eeprom_close(void *priv) { nmc93cxx_eeprom_t *eeprom = (nmc93cxx_eeprom_t *) priv; - free(eeprom); + FILE *fp = nvr_fopen(eeprom->filename, "wb"); + if (fp) { + fwrite(eeprom->dev.data, 2, eeprom->size, fp); + fclose(fp); + } + free(priv); } uint16_t * diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index 3f7ba427c..0943a9258 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -28,7 +28,6 @@ list(APPEND net_sources net_plip.c net_event.c net_null.c - net_eeprom_nmc93cxx.c net_tulip.c net_rtl8139.c net_l80225.c diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index f1e531deb..41ce86f6b 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -43,7 +43,7 @@ #include <86box/device.h> #include <86box/thread.h> #include <86box/network.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/nvr.h> #include "cpu.h" #include <86box/plat_unused.h> diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index e8cfd6cd7..9bf1f63d4 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -470,13 +470,13 @@ net_slirp_thread(void *priv) } #endif -static int slirp_card_num = 2; +int slirp_card_num = 2; /* Initialize SLiRP for use. */ void * net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv), char *netdrv_errbuf) { - slirp_log("SLiRP: initializing...\n"); + slirp_log("SLiRP: initializing with range %d...\n", slirp_card_num); net_slirp_t *slirp = calloc(1, sizeof(net_slirp_t)); memcpy(slirp->mac_addr, mac_addr, sizeof(slirp->mac_addr)); slirp->card = (netcard_t *) card; @@ -639,7 +639,6 @@ net_slirp_close(void *priv) } free(slirp->pkt.data); free(slirp); - slirp_card_num--; } const netdrv_t net_slirp_drv = { diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 883ba53ad..cbf3b704e 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -31,7 +31,7 @@ #include <86box/device.h> #include <86box/thread.h> #include <86box/network.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/plat_fallthrough.h> #include <86box/plat_unused.h> #include <86box/bswap.h> diff --git a/src/network/network.c b/src/network/network.c index 9b56515e8..661da7250 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -608,6 +608,7 @@ network_reset(void) ui_sb_update_icon(SB_NETWORK, 0); ui_sb_update_icon_write(SB_NETWORK, 0); + slirp_card_num = 2; #ifdef ENABLE_NETWORK_LOG network_dump_mutex = thread_create_mutex(); #endif diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 6af374fba..8fb6a1059 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -401,7 +401,7 @@ timeout_timer(void *priv) if (dev->page->dirty) new_page(dev, 1, 1); - timer_disable(&dev->timeout_timer); + timer_stop(&dev->timeout_timer); } static void @@ -483,7 +483,7 @@ reset_printer_hard(escp_t *dev) { dev->ack = 0; timer_disable(&dev->pulse_timer); - timer_disable(&dev->timeout_timer); + timer_stop(&dev->timeout_timer); reset_printer(dev); } @@ -1898,8 +1898,8 @@ strobe(uint8_t old, uint8_t val, void *priv) /* Process incoming character. */ handle_char(dev, dev->data); - if (timer_is_enabled(&dev->timeout_timer)) { - timer_disable(&dev->timeout_timer); + if (timer_is_on(&dev->timeout_timer)) { + timer_stop(&dev->timeout_timer); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); @@ -1909,7 +1909,7 @@ strobe(uint8_t old, uint8_t val, void *priv) dev->ack = 1; timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + timer_on_auto(&dev->timeout_timer, 5000000.0); } } @@ -1939,8 +1939,8 @@ write_ctrl(uint8_t val, void *priv) /* Process incoming character. */ handle_char(dev, dev->data); - if (timer_is_enabled(&dev->timeout_timer)) { - timer_disable(&dev->timeout_timer); + if (timer_is_on(&dev->timeout_timer)) { + timer_stop(&dev->timeout_timer); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); @@ -1950,7 +1950,7 @@ write_ctrl(uint8_t val, void *priv) dev->ack = 1; timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + timer_on_auto(&dev->timeout_timer, 5000000.0); } dev->ctrl = val; diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index c07ad475a..9c54dccab 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -136,7 +136,7 @@ reset_ps(ps_t *dev) dev->buffer_pos = 0; timer_disable(&dev->pulse_timer); - timer_disable(&dev->timeout_timer); + timer_stop(&dev->timeout_timer); } static void @@ -253,7 +253,7 @@ timeout_timer(void *priv) write_buffer(dev, true); - timer_disable(&dev->timeout_timer); + timer_stop(&dev->timeout_timer); } static void @@ -333,8 +333,8 @@ ps_strobe(uint8_t old, uint8_t val, void *priv) if (!(val & 0x01) && (old & 0x01)) { process_data(dev); - if (timer_is_enabled(&dev->timeout_timer)) { - timer_disable(&dev->timeout_timer); + if (timer_is_on(&dev->timeout_timer)) { + timer_stop(&dev->timeout_timer); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); @@ -344,7 +344,7 @@ ps_strobe(uint8_t old, uint8_t val, void *priv) dev->ack = true; timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + timer_on_auto(&dev->timeout_timer, 5000000.0); } } @@ -371,8 +371,8 @@ ps_write_ctrl(uint8_t val, void *priv) if (!(val & 0x01) && (dev->ctrl & 0x01)) { process_data(dev); - if (timer_is_enabled(&dev->timeout_timer)) { - timer_disable(&dev->timeout_timer); + if (timer_is_on(&dev->timeout_timer)) { + timer_stop(&dev->timeout_timer); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); @@ -382,7 +382,7 @@ ps_write_ctrl(uint8_t val, void *priv) dev->ack = true; timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + timer_on_auto(&dev->timeout_timer, 5000000.0); } dev->ctrl = val; diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index eb951de08..41d3737d1 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -214,7 +214,7 @@ timeout_timer(void *priv) if (dev->page->dirty) new_page(dev); - timer_disable(&dev->timeout_timer); + timer_stop(&dev->timeout_timer); } static void @@ -244,7 +244,7 @@ reset_printer(prnt_t *dev) plat_tempfile(dev->filename, NULL, ".txt"); timer_disable(&dev->pulse_timer); - timer_disable(&dev->timeout_timer); + timer_stop(&dev->timeout_timer); } static int @@ -381,8 +381,8 @@ strobe(uint8_t old, uint8_t val, void *priv) /* Process incoming character. */ handle_char(dev); - if (timer_is_enabled(&dev->timeout_timer)) { - timer_disable(&dev->timeout_timer); + if (timer_is_on(&dev->timeout_timer)) { + timer_stop(&dev->timeout_timer); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); @@ -393,7 +393,7 @@ strobe(uint8_t old, uint8_t val, void *priv) dev->ack = 1; timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + timer_on_auto(&dev->timeout_timer, 5000000.0); } } @@ -427,8 +427,8 @@ write_ctrl(uint8_t val, void *priv) /* ACK it, will be read on next READ STATUS. */ dev->ack = 1; - if (timer_is_enabled(&dev->timeout_timer)) { - timer_disable(&dev->timeout_timer); + if (timer_is_on(&dev->timeout_timer)) { + timer_stop(&dev->timeout_timer); #ifdef USE_DYNAREC if (cpu_use_dynarec) update_tsc(); @@ -436,7 +436,7 @@ write_ctrl(uint8_t val, void *priv) } timer_set_delay_u64(&dev->pulse_timer, ISACONST); - timer_set_delay_u64(&dev->timeout_timer, 5000000 * TIMER_USEC); + timer_on_auto(&dev->timeout_timer, 5000000.0); } dev->ctrl = val; diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index b03930806..ed9ba220c 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -23,6 +23,8 @@ #include #include +#include + extern "C" { #include <86box/86box.h> #include <86box/device.h> @@ -46,7 +48,7 @@ SettingsDisplay::SettingsDisplay(QWidget *parent) for (uint8_t i = 0; i < GFXCARD_MAX; i ++) videoCard[i] = gfxcard[i]; - ui->lineEdit->setFilter(tr("EDID") % util::DlgFilter({ "bin", "dat", "edid" }) % tr("All files") % util::DlgFilter({ "*" }, true)); + ui->lineEdit->setFilter(tr("EDID") % util::DlgFilter({ "bin", "dat", "edid", "txt" }) % tr("All files") % util::DlgFilter({ "*" }, true)); onCurrentMachineChanged(machine); } @@ -343,11 +345,10 @@ void SettingsDisplay::on_pushButtonExportDefault_clicked() if (!str.isEmpty()) { QFile file(str); if (file.open(QFile::WriteOnly)) { - ssize_t size = 0; - auto bytes = ddc_create_default_edid(&size); + uint8_t *bytes = nullptr; + auto size = ddc_create_default_edid(&bytes); file.write((char*)bytes, size); file.close(); } } } - diff --git a/src/qt/qt_settingsmachine.cpp b/src/qt/qt_settingsmachine.cpp index 0063ac727..e52553196 100644 --- a/src/qt/qt_settingsmachine.cpp +++ b/src/qt/qt_settingsmachine.cpp @@ -281,7 +281,7 @@ SettingsMachine::on_comboBoxSpeed_currentIndexChanged(int index) int cpuId = ui->comboBoxSpeed->currentData().toInt(); uint cpuType = cpuFamily->cpus[cpuId].cpu_type; - if ((cpuType >= CPU_286) && (cpuType <= CPU_386DX)) { + if ((cpuType >= CPU_286) && (cpuType < CPU_386DX)) { ui->comboBoxWaitStates->setEnabled(true); ui->comboBoxWaitStates->setCurrentIndex(cpu_waitstates); } else { diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index e53e2e407..cc3904e97 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -351,7 +351,7 @@ illegal_chars: } }); - connect(vm_model, &VMManagerModel::globalConfigurationChanged, this, [this] () { + connect(vm_model, &VMManagerModel::globalConfigurationChanged, this, [] () { vmm_main_window->updateSettings(); }); diff --git a/src/qt/qt_vmmanager_mainwindow.cpp b/src/qt/qt_vmmanager_mainwindow.cpp index 55e980ec9..f698f1ccd 100644 --- a/src/qt/qt_vmmanager_mainwindow.cpp +++ b/src/qt/qt_vmmanager_mainwindow.cpp @@ -130,7 +130,7 @@ VMManagerMainWindow(QWidget *parent) connect(this, &VMManagerMainWindow::languageUpdated, vmm, &VMManagerMain::onLanguageUpdated); #ifdef Q_OS_WINDOWS connect(this, &VMManagerMainWindow::darkModeUpdated, vmm, &VMManagerMain::onDarkModeUpdated); - connect(this, &VMManagerMainWindow::preferencesUpdated, [this] () { vmm_dark_mode_filter->reselectDarkMode(); }); + connect(this, &VMManagerMainWindow::preferencesUpdated, [] () { vmm_dark_mode_filter->reselectDarkMode(); }); #endif { diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index 8c09a30a1..bfa8b42cf 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -623,8 +623,15 @@ static void scsi_disk_buf_alloc(scsi_disk_t *dev, uint32_t len) { scsi_disk_log(dev->log, "Allocated buffer length: %i\n", len); - if (dev->temp_buffer == NULL) + if (dev->temp_buffer == NULL) { dev->temp_buffer = (uint8_t *) malloc(len); + dev->temp_buffer_sz = len; + } + if (len > dev->temp_buffer_sz) { + uint8_t *buf = (uint8_t *) realloc(dev->temp_buffer, len); + dev->temp_buffer = buf; + dev->temp_buffer_sz = len; + } } static void diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index f91eef683..04c188705 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -40,11 +40,11 @@ #include <86box/pci.h> #include <86box/device.h> #include <86box/nvr.h> +#include <86box/nmc93cxx.h> #include <86box/plat.h> #include <86box/scsi.h> #include <86box/scsi_device.h> #include <86box/scsi_pcscsi.h> -#include <86box/vid_ati_eeprom.h> #include <86box/fifo8.h> #include "cpu.h" @@ -179,7 +179,6 @@ typedef struct esp_t { int BIOSBase; int MMIOBase; rom_t bios; - ati_eeprom_t eeprom; int PCIBase; uint8_t rregs[ESP_REGS]; @@ -223,9 +222,14 @@ typedef struct esp_t { uint8_t irq_state; uint8_t pos_regs[8]; + + uint8_t eeprom_inst; + uint8_t eeprom_data[128]; + + nmc93cxx_eeprom_t *eeprom; } esp_t; -static esp_t reset_state = { 0 }; +static esp_t *reset_state = NULL; #define READ_FROM_DEVICE 1 #define WRITE_TO_DEVICE 0 @@ -1534,19 +1538,19 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) break; case CMD_BUSRESET: esp_log("ESP Bus Reset val=%02x.\n", (dev->rregs[ESP_CFG1] & CFG1_RESREPT)); - if (dev->mca) { - esp_lower_irq(dev); - esp_hard_reset(dev); - } else - esp_pci_soft_reset(dev); - - for (uint8_t i = 0; i < 16; i++) { + for (uint8_t i = 0; i < 16; i++) scsi_device_reset(&scsi_devices[dev->bus][i]); - } + if (!(dev->rregs[ESP_CFG1] & CFG1_RESREPT)) { dev->rregs[ESP_RINTR] |= INTR_RST; esp_log("ESP Bus Reset with IRQ\n"); esp_raise_irq(dev); + } else { + if (dev->mca) { + esp_lower_irq(dev); + esp_hard_reset(dev); + } else + esp_pci_soft_reset(dev); } break; case CMD_TI: @@ -1994,180 +1998,6 @@ esp_bios_disable(esp_t *dev) #define EE_ADAPT_OPTION_INT13 0x04 #define EE_ADAPT_OPTION_SCAM_SUPPORT 0x08 -/*To do: make this separate from the SCSI card*/ -static void -dc390_save_eeprom(esp_t *dev) -{ - FILE *fp = nvr_fopen(dev->nvr_path, "wb"); - if (!fp) - return; - fwrite(dev->eeprom.data, 1, 128, fp); - fclose(fp); -} - -static void -dc390_write_eeprom(esp_t *dev, int ena, int clk, int dat) -{ - /*Actual EEPROM is the same as the one used by the ATI cards, the 93cxx series.*/ - ati_eeprom_t *eeprom = &dev->eeprom; - uint8_t tick = eeprom->count; - uint8_t eedo = eeprom->out; - uint16_t address = eeprom->address; - uint8_t command = eeprom->opcode; - - esp_log("EEPROM CS=%02x,SK=%02x,DI=%02x,DO=%02x,tick=%d\n", - ena, clk, dat, eedo, tick); - - if (!eeprom->oldena && ena) { - esp_log("EEPROM Start chip select cycle\n"); - tick = 0; - command = 0; - address = 0; - } else if (eeprom->oldena && !ena) { - if (!eeprom->wp) { - uint8_t subcommand = address >> 4; - if (command == 0 && subcommand == 2) { - esp_log("EEPROM Erase All\n"); - for (address = 0; address < 64; address++) - eeprom->data[address] = 0xffff; - dc390_save_eeprom(dev); - } else if (command == 3) { - esp_log("EEPROM Erase Word\n"); - eeprom->data[address] = 0xffff; - dc390_save_eeprom(dev); - } else if (tick >= 26) { - if (command == 1) { - esp_log("EEPROM Write Word\n"); - eeprom->data[address] &= eeprom->dat; - dc390_save_eeprom(dev); - } else if (command == 0 && subcommand == 1) { - esp_log("EEPROM Write All\n"); - for (address = 0; address < 64; address++) - eeprom->data[address] &= eeprom->dat; - dc390_save_eeprom(dev); - } - } - } - eedo = 1; - esp_log("EEPROM DO read\n"); - } else if (ena && !eeprom->oldclk && clk) { - if (tick == 0) { - if (dat == 0) { - esp_log("EEPROM Got correct 1st start bit, waiting for 2nd start bit (1)\n"); - tick++; - } else { - esp_log("EEPROM Wrong 1st start bit (is 1, should be 0)\n"); - tick = 2; - } - } else if (tick == 1) { - if (dat != 0) { - esp_log("EEPROM Got correct 2nd start bit, getting command + address\n"); - tick++; - } else { - esp_log("EEPROM 1st start bit is longer than needed\n"); - } - } else if (tick < 4) { - tick++; - command <<= 1; - if (dat) - command += 1; - } else if (tick < 10) { - tick++; - address = (address << 1) | dat; - if (tick == 10) { - esp_log("EEPROM command = %02x, address = %02x (val = %04x)\n", command, - address, eeprom->data[address]); - if (command == 2) - eedo = 0; - address = address % 64; - if (command == 0) { - switch (address >> 4) { - case 0: - esp_log("EEPROM Write disable command\n"); - eeprom->wp = 1; - break; - case 1: - esp_log("EEPROM Write all command\n"); - break; - case 2: - esp_log("EEPROM Erase all command\n"); - break; - case 3: - esp_log("EEPROM Write enable command\n"); - eeprom->wp = 0; - break; - - default: - break; - } - } else { - esp_log("EEPROM Read, write or erase word\n"); - eeprom->dat = eeprom->data[address]; - } - } - } else if (tick < 26) { - tick++; - if (command == 2) { - esp_log("EEPROM Read Word\n"); - eedo = ((eeprom->dat & 0x8000) != 0); - } - eeprom->dat <<= 1; - eeprom->dat += dat; - } else { - esp_log("EEPROM Additional unneeded tick, not processed\n"); - } - } - - eeprom->count = tick; - eeprom->oldena = ena; - eeprom->oldclk = clk; - eeprom->out = eedo; - eeprom->address = address; - eeprom->opcode = command; - esp_log("EEPROM EEDO = %d\n", eeprom->out); -} - -static void -dc390_load_eeprom(esp_t *dev) -{ - ati_eeprom_t *eeprom = &dev->eeprom; - uint8_t *nvr = (uint8_t *) eeprom->data; - int i; - uint16_t checksum = 0; - FILE *fp; - - eeprom->out = 1; - - fp = nvr_fopen(dev->nvr_path, "rb"); - if (fp) { - esp_log("EEPROM Load\n"); - if (fread(nvr, 1, 128, fp) != 128) - fatal("dc390_eeprom_load(): Error reading data\n"); - fclose(fp); - } else { - for (i = 0; i < 16; i++) { - nvr[i * 2] = 0x57; - nvr[i * 2 + 1] = 0x00; - } - - esp_log("EEPROM Defaults\n"); - - nvr[EE_ADAPT_SCSI_ID] = 7; - nvr[EE_MODE2] = 0x0f; - nvr[EE_TAG_CMD_NUM] = 0x04; - nvr[EE_ADAPT_OPTIONS] = EE_ADAPT_OPTION_F6_F8_AT_BOOT | EE_ADAPT_OPTION_BOOT_FROM_CDROM | EE_ADAPT_OPTION_INT13; - for (i = 0; i < EE_CHKSUM1; i += 2) { - checksum += ((nvr[i] & 0xff) | (nvr[i + 1] << 8)); - esp_log("Checksum calc = %04x, nvr = %02x\n", checksum, nvr[i]); - } - - checksum = 0x1234 - checksum; - nvr[EE_CHKSUM1] = checksum & 0xff; - nvr[EE_CHKSUM2] = checksum >> 8; - esp_log("EEPROM Checksum = %04x\n", checksum); - } -} - static uint8_t esp_pci_read(UNUSED(int func), int addr, void *priv) { @@ -2181,10 +2011,10 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) if (!dev->has_bios || dev->local) return 0x22; else { - if (dev->eeprom.out) + if (nmc93cxx_eeprom_read(dev->eeprom)) return 0x22; else { - dev->eeprom.out = 1; + dev->eeprom->dev.out = 1; return 2; } } @@ -2270,9 +2100,9 @@ esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) if (addr == 0x80) { eesk = val & 0x80 ? 1 : 0; eedi = val & 0x40 ? 1 : 0; - dc390_write_eeprom(dev, 1, eesk, eedi); + nmc93cxx_eeprom_write(dev->eeprom, 1, eesk, eedi); } else if (addr == 0xc0) - dc390_write_eeprom(dev, 0, 0, 0); + nmc93cxx_eeprom_write(dev->eeprom, 0, 0, 0); // esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); return; } @@ -2371,26 +2201,35 @@ esp_pci_reset(void *priv) { esp_t *dev = (esp_t *) priv; - timer_disable(&dev->timer); + if (reset_state != NULL) { + esp_io_remove(dev, dev->PCIBase, 0x80); + esp_bios_disable(dev); + timer_stop(&dev->timer); - reset_state.bios.mapping = dev->bios.mapping; + reset_state->bios.mapping = dev->bios.mapping; + reset_state->timer = dev->timer; + reset_state->pci_slot = dev->pci_slot; - reset_state.timer = dev->timer; + *dev = *reset_state; - reset_state.pci_slot = dev->pci_slot; - - memcpy(dev, &reset_state, sizeof(esp_t)); - - esp_pci_soft_reset(dev); + esp_pci_soft_reset(dev); + esp_log("PCI Reset.\n"); + } } static void * dc390_init(const device_t *info) { esp_t *dev = calloc(1, sizeof(esp_t)); + reset_state = calloc(1, sizeof(esp_t)); const char *bios_rev = NULL; uint32_t mask = 0; uint32_t size = 0x8000; + nmc93cxx_eeprom_params_t params; + char eeprom_filename[1024] = { 0 }; + char filename[1024] = { 0 }; + uint16_t checksum = 0x0000; + uint8_t i; dev->bus = scsi_get_bus(); @@ -2434,10 +2273,40 @@ dc390_init(const device_t *info) esp_bios_disable(dev); if (!dev->local) { - sprintf(dev->nvr_path, "dc390_%i.nvr", device_get_instance()); + dev->eeprom_inst = device_get_instance(); + + snprintf(eeprom_filename, sizeof(eeprom_filename), "dc390_%d.nvr", dev->eeprom_inst); /* Load the serial EEPROM. */ - dc390_load_eeprom(dev); + for (i = 0; i < 16; i++) { + dev->eeprom_data[i * 2] = 0x57; + dev->eeprom_data[i * 2 + 1] = 0x00; + } + + esp_log("EEPROM Defaults\n"); + + dev->eeprom_data[EE_ADAPT_SCSI_ID] = 7; + dev->eeprom_data[EE_MODE2] = 0x0f; + dev->eeprom_data[EE_TAG_CMD_NUM] = 0x04; + dev->eeprom_data[EE_ADAPT_OPTIONS] = EE_ADAPT_OPTION_F6_F8_AT_BOOT | EE_ADAPT_OPTION_BOOT_FROM_CDROM | EE_ADAPT_OPTION_INT13; + for (i = 0; i < EE_CHKSUM1; i += 2) { + checksum += ((dev->eeprom_data[i] & 0xff) | (dev->eeprom_data[i + 1] << 8)); + esp_log("Checksum calc = %04x, nvr = %02x\n", checksum, dev->eeprom_data[i]); + } + + checksum = 0x1234 - checksum; + dev->eeprom_data[EE_CHKSUM1] = checksum & 0xff; + dev->eeprom_data[EE_CHKSUM2] = checksum >> 8; + + params.nwords = 64; + params.default_content = (uint16_t *) dev->eeprom_data; + params.filename = filename; + snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, dev->eeprom_inst); + dev->eeprom = device_add_inst_params(&nmc93cxx_device, dev->eeprom_inst, ¶ms); + if (dev->eeprom == NULL) { + free(dev); + return NULL; + } } esp_pci_hard_reset(dev); @@ -2449,7 +2318,7 @@ dc390_init(const device_t *info) scsi_bus_set_speed(dev->bus, 10000000.0); - memcpy(&reset_state, dev, sizeof(esp_t)); + *reset_state = *dev; return dev; } @@ -2622,7 +2491,7 @@ ncr53c9x_mca_init(const device_t *info) fifo8_create(&dev->fifo, ESP_FIFO_SZ); fifo8_create(&dev->cmdfifo, ESP_CMDFIFO_SZ); - dev->pos_regs[0] = 0x4f; /* MCA board ID */ + dev->pos_regs[0] = 0x4d; /* MCA board ID */ dev->pos_regs[1] = 0x7f; mca_add(ncr53c9x_mca_read, ncr53c9x_mca_write, ncr53c9x_mca_feedb, NULL, dev); @@ -2646,6 +2515,11 @@ esp_close(void *priv) fifo8_destroy(&dev->fifo); fifo8_destroy(&dev->cmdfifo); + if (reset_state != NULL) { + free(reset_state); + reset_state = NULL; + } + free(dev); dev = NULL; } diff --git a/src/sio/sio_pc87306.c b/src/sio/sio_pc87306.c index e95292fbb..f3c635dc8 100644 --- a/src/sio/sio_pc87306.c +++ b/src/sio/sio_pc87306.c @@ -174,7 +174,8 @@ lpt_handler(pc87306_t *dev) lpt_port_irq(dev->lpt, lpt_irq); - if ((dev->regs[0x18] & 0x06) != 0x00) + if (((jumpered_internal_ecp_dma < 0) || (jumpered_internal_ecp_dma == 4)) && + ((dev->regs[0x18] & 0x06) != 0x00)) lpt_port_dma(dev->lpt, (dev->regs[0x18] & 0x08) ? 3 : 1); } diff --git a/src/sio/sio_w83877.c b/src/sio/sio_w83877.c index 32e7a4bc8..a7a2b4ea2 100644 --- a/src/sio/sio_w83877.c +++ b/src/sio/sio_w83877.c @@ -202,7 +202,7 @@ w83877_lpt_handler(w83877_t *dev) lpt_port_irq(dev->lpt, lpt_irq); lpt_port_dma(dev->lpt, dev->dma_map[dev->regs[0x26] & 0x03]); - lpt_set_cnfgb_readout(dev->lpt, ((dev->regs[0x26] & 0xe0) >> 2) | 0x07); + lpt_set_cnfgb_readout(dev->lpt, ((dev->regs[0x27] & 0xe0) >> 2) | 0x07); } static void diff --git a/src/unix/unix.c b/src/unix/unix.c index b4d6daa17..de35f4e93 100644 --- a/src/unix/unix.c +++ b/src/unix/unix.c @@ -290,6 +290,8 @@ plat_get_string(int i) return L"Hardware not available"; case STRING_MONITOR_SLEEP: return L"Monitor in sleep mode"; + case STRING_EDID_TOO_LARGE: + return "EDID file \"%ls\" is too large."; } return L""; } diff --git a/src/utils/ini.c b/src/utils/ini.c index b267f38b5..47e792594 100644 --- a/src/utils/ini.c +++ b/src/utils/ini.c @@ -316,7 +316,7 @@ ini_close(ini_t ini) free(list); } -static int +int ini_detect_bom(const char *fn) { FILE *fp; diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index a3e86ff7c..41ff22447 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -44,6 +44,7 @@ add_library(vid OBJECT # DDC / monitor identification stuff vid_ddc.c + vid_ddc_edid_custom.c # CARDS start here diff --git a/src/video/vid_ddc.c b/src/video/vid_ddc.c index d6c9095ef..ba6ac2a6d 100644 --- a/src/video/vid_ddc.c +++ b/src/video/vid_ddc.c @@ -129,8 +129,8 @@ typedef struct { uint8_t padding[15], checksum2; } edid_t; -void* -ddc_create_default_edid(ssize_t* size_out) +size_t +ddc_create_default_edid(uint8_t **out) { edid_t *edid = malloc(sizeof(edid_t)); memset(edid, 0, sizeof(edid_t)); @@ -225,96 +225,79 @@ ddc_create_default_edid(ssize_t* size_out) edid->checksum2 += edid_bytes[c]; edid->checksum2 = 256 - edid->checksum2; - if (size_out) - *size_out = sizeof(edid_t); - - return edid; + if (out) { + *out = edid_bytes; + } + + return sizeof(edid_t); +} + +void * +ddc_init_with_custom_edid(char *edid_path, void *i2c) +{ + uint8_t buffer[384] = { 0 }; + size_t size = ddc_load_edid(edid_path, buffer, sizeof(buffer)); + + if (size > 256) { + wchar_t errmsg[2048] = { 0 }; + wchar_t path[2048] = { 0 }; + +#ifdef _WIN32 + mbstoc16s(path, monitor_edid_path, sizeof_w(path)); +#else + mbstowcs(path, monitor_edid_path, sizeof_w(path)); +#endif + swprintf(errmsg, sizeof_w(errmsg), plat_get_string(STRING_EDID_TOO_LARGE), path); + ui_msgbox_header(MBX_ERROR, L"EDID", errmsg); + + return NULL; + } else if (size == 0) { + return NULL; + } else if (size < 128) { + size = 128; + } else if (size < 256) { + size = 256; + } + + int checksum = 0; + for (int i = 0; i < 127; i++) { + checksum += buffer[i]; + } + + buffer[127] = 256 - checksum; + + if (size == 256) { + checksum = 0; + + for (int i = 128; i < 255; i++) { + checksum += buffer[i]; + } + buffer[255] = 256 - checksum; + } + + uint8_t *edid_bytes = malloc(size); + memcpy(edid_bytes, buffer, size); + + return i2c_eeprom_init(i2c, 0x50, edid_bytes, size, 0); } void * ddc_init(void *i2c) { - ssize_t edid_size = 0; - uint8_t* edid_bytes = NULL; - if (monitor_edid == 1 && monitor_edid_path[0]) { - FILE* file = plat_fopen(monitor_edid_path, "rb"); + if (monitor_edid && monitor_edid_path[0]) { + void *ret = ddc_init_with_custom_edid(monitor_edid_path, i2c); - if (!file) - goto default_init; - - if (fseek(file, 0, SEEK_END) == -1) { - fclose(file); - goto default_init; + if (ret) { + return ret; } - - edid_size = ftell(file); - fseek(file, 0, SEEK_SET); - - if (edid_size <= 0) { - fclose(file); - goto default_init; - } - - if (edid_size > 256) { - wchar_t errmsg[2048] = { 0 }; - wchar_t path[2048] = { 0 }; - -#ifdef _WIN32 - mbstoc16s(path, monitor_edid_path, sizeof_w(path)); -#else - mbstowcs(path, monitor_edid_path, sizeof_w(path)); -#endif - swprintf(errmsg, sizeof_w(errmsg), plat_get_string(STRING_EDID_TOO_LARGE), path); - ui_msgbox_header(MBX_ERROR, L"EDID", errmsg); - fclose(file); - goto default_init; - } - - edid_bytes = calloc(1, edid_size); - if (!edid_bytes) { - fclose(file); - goto default_init; - } - - if (fread(edid_bytes, edid_size, 1, file) <= 0) { - free(edid_bytes); - fclose(file); - goto default_init; - } - - if (edid_size < 128) { - edid_bytes = realloc(edid_bytes, 128); - edid_size = 128; - } else if (edid_size < 256) { - edid_bytes = realloc(edid_bytes, 256); - edid_size = 256; - } - - { - int checksum = 0; - for (uint8_t c = 0; c < 127; c++) - checksum += edid_bytes[c]; - edid_bytes[127] = 256 - checksum; - - if (edid_size == 256) { - checksum = 0; - - for (uint8_t c = 128; c < 255; c++) { - checksum += edid_bytes[c]; - } - edid_bytes[255] = 256 - checksum; - } - } - - fclose(file); - return i2c_eeprom_init(i2c, 0x50, edid_bytes, edid_size, 0); } -default_init: - edid_size = sizeof(edid_t); - edid_bytes = ddc_create_default_edid(&edid_size); + + uint8_t *edid_bytes; + size_t edid_size = ddc_create_default_edid(&edid_bytes); return i2c_eeprom_init(i2c, 0x50, edid_bytes, edid_size, 0); } + void ddc_close(void *eeprom) { diff --git a/src/video/vid_ddc_edid_custom.c b/src/video/vid_ddc_edid_custom.c new file mode 100644 index 000000000..2febde67e --- /dev/null +++ b/src/video/vid_ddc_edid_custom.c @@ -0,0 +1,137 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Custom monitor EDID file loader. + * + * + * + * Authors: Cacodemon345, + * David Hrdlička, + * + * Copyright 2025 Cacodemon. + * Copyright 2025 David Hrdlička. + */ + +#include +#include +#include +#include +#include + +#define EDID_BLOCK_SIZE 128 +#define EDID_HEADER 0x00FFFFFFFFFFFF00 +#define EDID_DECODE_HEADER "edid-decode (hex):" + +static size_t +read_block(FILE *fp, uint8_t *buf) +{ + char temp[64]; + size_t read = 0; + + for (int i = 0; i < 8; i++) { + if (!fgets(temp, sizeof(temp), fp)) { + return 0; + } + + char *tok = strtok(temp, " \t\r\n"); + + for (int j = 0; j < 16; j++) { + if (!tok) { + return 0; + } + + buf[read++] = strtoul(tok, NULL, 16); + tok = strtok(NULL, " \t\r\n"); + } + } + + return read; +} + +size_t +ddc_load_edid(char *path, uint8_t *buf, size_t size) +{ + FILE *fp = fopen(path, "rb"); + size_t offset = 0; + char temp[64]; + long pos; + + if (!fp) { + return 0; + } + + // Check the beginning of the file for the EDID header. + uint64_t header; + fread(&header, sizeof(header), 1, fp); + + if (header == EDID_HEADER) { + // Binary format. Read as is + fseek(fp, 0, SEEK_SET); + offset = fread(buf, 1, size, fp); + + fclose(fp); + return offset; + } + + // Reopen in text mode. + fclose(fp); + fp = fopen(path, "rt"); + + if (!fp) { + return 0; + } + +#ifdef _WIN32 + // Disable buffering on Windows because of a UCRT bug. + // https://developercommunity.visualstudio.com/t/fseek-ftell-fail-in-text-mode-for-unix-style-text/425878 + setvbuf(fp, NULL, _IONBF, 0); +#endif + + // Skip the UTF-8 BOM, if any. + if (fread(temp, 1, 3, fp) != 3) { + fclose(fp); + return 0; + }; + + if ((uint8_t) temp[0] != 0xEF || (uint8_t) temp[1] != 0xBB || (uint8_t) temp[2] != 0xBF) { + rewind(fp); + } + + // Find the `edid-decode (hex):` header. + do { + if (!fgets(temp, sizeof(temp), fp)) { + fclose(fp); + return 0; + } + } while (strncmp(temp, EDID_DECODE_HEADER, sizeof(EDID_DECODE_HEADER) - 1)); + + while (offset + EDID_BLOCK_SIZE <= size) { + // Skip any whitespace before the next block. + do { + pos = ftell(fp); + if (!fgets(temp, sizeof(temp), fp)) { + fclose(fp); + return offset; + } + } while (strspn(temp, " \t\r\n") == strlen(temp)); + + fseek(fp, pos, SEEK_SET); + + // Read the block. + size_t block = read_block(fp, buf + offset); + + if (block != EDID_BLOCK_SIZE) { + break; + } + + offset += block; + } + + fclose(fp); + return offset; +} diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index eded49cf6..7fdc04e9e 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -424,9 +424,9 @@ enum { }; enum { - DMA_STATE_IDLE = 0, - DMA_STATE_PRI, - DMA_STATE_SEC + MGA_DMA_STATE_IDLE = 0, + MGA_DMA_STATE_PRI, + MGA_DMA_STATE_SEC }; typedef struct { @@ -1600,7 +1600,7 @@ mystique_ctrl_read_b(uint32_t addr, void *priv) case REG_STATUS + 2: ret = (mystique->status >> 16) & 0xff; if (mystique->busy || ((mystique->blitter_submit_refcount + mystique->blitter_submit_dma_refcount) != mystique->blitter_complete_refcount) || !FIFO_EMPTY - || mystique->dma.state != DMA_STATE_IDLE || mystique->softrap_pending || mystique->endprdmasts_pending) + || mystique->dma.state != MGA_DMA_STATE_IDLE || mystique->softrap_pending || mystique->endprdmasts_pending) ret |= (STATUS_DWGENGSTS >> 16); break; case REG_STATUS + 3: @@ -2179,7 +2179,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) case REG_OPMODE: thread_wait_mutex(mystique->dma.lock); - mystique->dma.state = DMA_STATE_IDLE; /* Interrupt DMA. */ + mystique->dma.state = MGA_DMA_STATE_IDLE; /* Interrupt DMA. */ thread_release_mutex(mystique->dma.lock); mystique->dmamod = (val >> 2) & 3; mystique_queue(mystique, addr & 0x3fff, val, FIFO_WRITE_CTRL_BYTE); @@ -2200,10 +2200,10 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) thread_wait_mutex(mystique->dma.lock); WRITE8(addr, mystique->dma.primaddress, val); mystique->dma.pri_state = 0; - if (mystique->dma.state == DMA_STATE_IDLE && !(mystique->softrap_pending || mystique->endprdmasts_pending || !mystique->softrap_status_read)) { + if (mystique->dma.state == MGA_DMA_STATE_IDLE && !(mystique->softrap_pending || mystique->endprdmasts_pending || !mystique->softrap_status_read)) { mystique->dma.words_expected = 0; } - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; thread_release_mutex(mystique->dma.lock); break; @@ -2240,7 +2240,7 @@ mystique_ctrl_write_b(uint32_t addr, uint8_t val, void *priv) thread_wait_mutex(mystique->dma.lock); mystique->dma.pri_state = 0; mystique->dma.sec_state = 0; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.words_expected = 0; thread_release_mutex(mystique->dma.lock); break; @@ -2599,12 +2599,12 @@ mystique_accel_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) case REG_SECEND: mystique->dma.secend = val; - if (mystique->dma.state != DMA_STATE_SEC && (mystique->dma.secaddress & DMA_ADDR_MASK) != (mystique->dma.secend & DMA_ADDR_MASK)) - mystique->dma.state = DMA_STATE_SEC; + if (mystique->dma.state != MGA_DMA_STATE_SEC && (mystique->dma.secaddress & DMA_ADDR_MASK) != (mystique->dma.secend & DMA_ADDR_MASK)) + mystique->dma.state = MGA_DMA_STATE_SEC; break; case REG_SOFTRAP: - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; mystique->endprdmasts_pending = 1; @@ -2683,11 +2683,11 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) thread_wait_mutex(mystique->dma.lock); mystique->dma.primend = val; //pclog("PRIMADDRESS = 0x%08X, PRIMEND = 0x%08X\n", mystique->dma.primaddress, mystique->dma.primend); - if (mystique->dma.state == DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { + if (mystique->dma.state == MGA_DMA_STATE_IDLE && (mystique->dma.primaddress & DMA_ADDR_MASK) != (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 0; mystique->status &= ~STATUS_ENDPRDMASTS; - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; //mystique->dma.pri_state = 0; wake_fifo_thread(mystique); } @@ -2699,7 +2699,7 @@ mystique_ctrl_write_l(uint32_t addr, uint32_t val, void *priv) { mystique->dma.primaddress = mystique->dma.primend; mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; } thread_release_mutex(mystique->dma.lock); break; @@ -2935,7 +2935,7 @@ run_dma(mystique_t *mystique) return; } - if (mystique->dma.state == DMA_STATE_IDLE) { + if (mystique->dma.state == MGA_DMA_STATE_IDLE) { if (!(mystique->status & STATUS_ENDPRDMASTS)) { /* Force this to appear. */ @@ -2945,14 +2945,14 @@ run_dma(mystique_t *mystique) return; } - while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != DMA_STATE_IDLE) { + while (words_transferred < DMA_MAX_WORDS && mystique->dma.state != MGA_DMA_STATE_IDLE) { switch (atomic_load(&mystique->dma.state)) { - case DMA_STATE_PRI: + case MGA_DMA_STATE_PRI: switch (mystique->dma.primaddress & DMA_MODE_MASK) { case DMA_MODE_REG: if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; break; } if (mystique->dma.pri_state == 0 && !mystique->dma.words_expected) { @@ -2965,7 +2965,7 @@ run_dma(mystique_t *mystique) if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; break; } @@ -3000,31 +3000,31 @@ run_dma(mystique_t *mystique) mystique->dma.pri_header >>= 8; mystique->dma.pri_state = (mystique->dma.pri_state + 1) & 3; - if (mystique->dma.state == DMA_STATE_SEC) { + if (mystique->dma.state == MGA_DMA_STATE_SEC) { mystique->dma.sec_state = 0; } else if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; } break; default: - fatal("DMA_STATE_PRI: mode %i\n", mystique->dma.primaddress & DMA_MODE_MASK); + fatal("MGA_DMA_STATE_PRI: mode %i\n", mystique->dma.primaddress & DMA_MODE_MASK); } break; - case DMA_STATE_SEC: + case MGA_DMA_STATE_SEC: switch (mystique->dma.secaddress & DMA_MODE_MASK) { case DMA_MODE_REG: if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3039,11 +3039,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3073,11 +3073,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.pri_state = 0; mystique->dma.words_expected = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3090,11 +3090,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3110,11 +3110,11 @@ run_dma(mystique_t *mystique) if ((mystique->dma.secaddress & DMA_ADDR_MASK) >= (mystique->dma.secend & DMA_ADDR_MASK)) { if ((mystique->dma.primaddress & DMA_ADDR_MASK) == (mystique->dma.primend & DMA_ADDR_MASK)) { mystique->endprdmasts_pending = 1; - mystique->dma.state = DMA_STATE_IDLE; + mystique->dma.state = MGA_DMA_STATE_IDLE; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } else { - mystique->dma.state = DMA_STATE_PRI; + mystique->dma.state = MGA_DMA_STATE_PRI; mystique->dma.words_expected = 0; mystique->dma.pri_state = 0; } @@ -3123,7 +3123,7 @@ run_dma(mystique_t *mystique) break; default: - fatal("DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); + fatal("MGA_DMA_STATE_SEC: mode %i\n", mystique->dma.secaddress & DMA_MODE_MASK); } break; @@ -3145,7 +3145,7 @@ fifo_thread(void *priv) thread_wait_event(mystique->wake_fifo_thread, -1); thread_reset_event(mystique->wake_fifo_thread); - while (!FIFO_EMPTY || mystique->dma.state != DMA_STATE_IDLE) { + while (!FIFO_EMPTY || mystique->dma.state != MGA_DMA_STATE_IDLE) { int words_transferred = 0; while (!FIFO_EMPTY && words_transferred < 100) { diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index a0f074e70..fbf329e84 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -33,7 +33,7 @@ #include <86box/mem.h> #include <86box/pci.h> #include <86box/rom.h> -#include <86box/net_eeprom_nmc93cxx.h> +#include <86box/nmc93cxx.h> #include <86box/nvr.h> #include <86box/plat.h> #include <86box/thread.h> @@ -2953,13 +2953,11 @@ s3_out(uint16_t addr, uint8_t val, void *priv) switch (addr) { case 0x3c2: - if (s3->chip == S3_VISION964) { - if (s3->card_type != S3_ELSAWIN2KPROX_964) { + if (svga->getclock == icd2061_getclock) { if (((val >> 2) & 3) != 3) icd2061_write(svga->clock_gen, (val >> 2) & 3); } - } - break; + break; case 0x3c5: if (s3->chip == S3_TRIO64V2) { @@ -3167,8 +3165,6 @@ s3_out(uint16_t addr, uint8_t val, void *priv) svga->hwcursor.x /= 3; else if ((s3->chip <= S3_86C805) && s3->color_16bit) svga->hwcursor.x >>= 1; - else if ((s3->chip == S3_TRIO32) && ((svga->bpp == 15) || (svga->bpp == 16))) - svga->hwcursor.x >>= 1; break; case 0x4a: @@ -3231,11 +3227,9 @@ s3_out(uint16_t addr, uint8_t val, void *priv) if (((svga->miscout >> 2) & 3) == 3) s3_log("[%04X:%08X]: Write CRTC%02x=%02x.\n", CS, cpu_state.pc, svga->crtcreg, svga->crtc[svga->crtcreg]); - if (s3->chip == S3_VISION964) { - if (s3->card_type != S3_ELSAWIN2KPROX_964) { - if (((svga->miscout >> 2) & 3) == 3) - icd2061_write(svga->clock_gen, svga->crtc[0x42] & 0x0f); - } + if (svga->getclock == icd2061_getclock) { + if (((svga->miscout >> 2) & 3) == 3) + icd2061_write(svga->clock_gen, val & 0x0f); } break; @@ -3350,8 +3344,6 @@ s3_in(uint16_t addr, void *priv) case 0x3c7: case 0x3c8: case 0x3c9: - case 0x3ca: /*0x3c6 alias*/ - case 0x3cb: /*0x3c7 alias*/ rs2 = (svga->crtc[0x55] & 0x01) || !!(svga->crtc[0x43] & 2); if (s3->chip >= S3_TRIO32) return svga_in(addr, svga); @@ -3414,6 +3406,11 @@ s3_in(uint16_t addr, void *priv) temp |= svga->crtc[0x42] & 0x0f; else temp |= ((svga->miscout >> 2) & 3); + if (s3->elsa_eeprom) { + temp &= 0xaf; + if ((svga->crtc[0x5c] & 0x10) && nmc93cxx_eeprom_read(s3->eeprom)) + temp |= 0x10; + } return temp; case 0x69: return s3->ma_ext; @@ -3637,6 +3634,7 @@ s3_recalctimings(svga_t *svga) svga->split++; if (s3->accel.advfunc_cntl & 0x01) svga->split = 0x7fff; + s3_log("SPLIT=%d, crtc5e bit 6=%02x, advfunccntl bit 0=%x.\n", svga->split, svga->crtc[0x5e] & 0x40, s3->accel.advfunc_cntl & 0x01); if (svga->crtc[0x51] & 0x30) svga->rowoffset |= (svga->crtc[0x51] & 0x30) << 4; else if (svga->crtc[0x43] & 0x04) @@ -3649,6 +3647,7 @@ s3_recalctimings(svga_t *svga) if ((((svga->miscout >> 2) & 3) == 3) && (s3->chip < S3_TRIO32)) clk_sel = svga->crtc[0x42] & 0x0f; + svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); if ((s3->chip == S3_VISION964) || (s3->chip == S3_86C928)) { @@ -3855,12 +3854,26 @@ s3_recalctimings(svga_t *svga) svga->hdisp -= 32; break; case S3_ELSAWIN2KPROX: + s3_log("S3 width 8bpp=%d, hdisp=%d.\n", s3->width, svga->hdisp); switch (s3->width) { case 1280: case 1600: svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -3983,6 +3996,19 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -4030,6 +4056,19 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -4165,6 +4204,19 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -4199,6 +4251,19 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -4338,6 +4403,19 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -4371,6 +4449,19 @@ s3_recalctimings(svga_t *svga) svga->hdisp <<= 1; svga->dots_per_clock <<= 1; break; + case 2048: + if (!svga->interlace) { + if (svga->dispend >= 1024) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } else { + if (svga->dispend >= 512) { + svga->hdisp <<= 1; + svga->dots_per_clock <<= 1; + } + } + break; default: break; } @@ -4451,7 +4542,7 @@ s3_trio64v_recalctimings(svga_t *svga) svga->vblankstart |= 0x400; if (svga->crtc[0x5e] & 0x10) svga->vsyncstart |= 0x400; - svga->split = svga->crtc[0x18]; + svga->split = svga->crtc[0x18]; if (svga->crtc[7] & 0x10) svga->split |= 0x100; if (svga->crtc[9] & 0x40) @@ -4459,6 +4550,7 @@ s3_trio64v_recalctimings(svga_t *svga) if (svga->crtc[0x5e] & 0x40) svga->split |= 0x400; svga->split++; + svga->interlace = svga->crtc[0x42] & 0x20; svga->clock = (cpuclock * (double) (1ULL << 32)) / svga->getclock(clk_sel, svga->clock_gen); @@ -4715,10 +4807,10 @@ s3_updatemapping(s3_t *s3) break; } s3->linear_base &= ~(s3->linear_size - 1); - if (s3->linear_base == 0xa0000) { + if ((s3->linear_base == 0xa0000) || (s3->linear_size == 0x10000)) { mem_mapping_disable(&s3->linear_mapping); if (!(svga->crtc[0x53] & 0x10)) { - mem_mapping_set_addr(&svga->mapping, s3->linear_base, 0x10000); + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; } } else { @@ -4979,6 +5071,7 @@ s3_accel_in(uint16_t port, void *priv) if (FIFO_FULL) temp = 0xff; } + s3_log("Read port=%04x, val=%02x.\n", port, temp); return temp; case 0x8119: case 0x9949: @@ -5035,7 +5128,7 @@ s3_accel_in(uint16_t port, void *priv) s3->data_available = 0; } } - s3_log("FIFO Status Temp=%02x.\n", temp); + s3_log("Read port=%04x, val=%02x.\n", port, temp); return temp; case 0x9d48: @@ -6132,6 +6225,7 @@ s3_accel_write_w(uint32_t addr, uint16_t val, void *priv) } else { switch (addr & (addr_mask - 1)) { case 0x83c8: + case 0x83ca: case 0x83d4: s3_accel_write(addr, val, s3); s3_accel_write(addr + 1, val >> 8, s3); @@ -6326,54 +6420,7 @@ s3_accel_read(uint32_t addr, void *priv) if ((addr >= 0x08000) && (addr <= 0x0803f)) return s3_pci_read(0, addr & 0xff, s3); switch (addr & 0x1ffff) { - case 0x83b0: - case 0x83b1: - case 0x83b2: - case 0x83b3: - case 0x83b4: - case 0x83b5: - case 0x83b6: - case 0x83b7: - case 0x83b8: - case 0x83b9: - case 0x83ba: - case 0x83bb: - case 0x83bc: - case 0x83bd: - case 0x83be: - case 0x83bf: - case 0x83c0: - case 0x83c1: - case 0x83c2: - case 0x83c3: - case 0x83c4: - case 0x83c5: - case 0x83c6: - case 0x83c7: - case 0x83c8: - case 0x83c9: - case 0x83ca: - case 0x83cb: - case 0x83cc: - case 0x83cd: - case 0x83ce: - case 0x83cf: - case 0x83d0: - case 0x83d1: - case 0x83d2: - case 0x83d3: - case 0x83d4: - case 0x83d5: - case 0x83d6: - case 0x83d7: - case 0x83d8: - case 0x83d9: - case 0x83da: - case 0x83db: - case 0x83dc: - case 0x83dd: - case 0x83de: - case 0x83df: + case 0x83b0 ... 0x83df: return s3_in(addr & 0x3ff, s3); case 0x8504: return s3->subsys_stat; @@ -9598,6 +9645,14 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } else update = 1; + if (s3->bpp == 2) { + src_dat &= 0xff; + pat_dat &= 0xff; + } else if (s3->bpp == 1) { + src_dat &= 0xffff; + pat_dat &= 0xffff; + } + if (update) { READ(s3->accel.dest + s3->accel.dx, dest_dat); @@ -9656,6 +9711,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi if (cpu_input /* && (s3->accel.multifunc[0xa] & 0xc0) == 0x80*/) return; if (s3->accel.sy < 0) { + s3->accel.destx_distp = s3->accel.dx; + s3->accel.desty_axstp = s3->accel.dy; return; } } @@ -10489,10 +10546,8 @@ s3_init(const device_t *info) svga->ramdac = device_add(&att491_ramdac_device); svga->clock_gen = device_add(&av9194_device); svga->getclock = av9194_getclock; - if (info->local == S3_WINNER1000_805) { + if (info->local == S3_WINNER1000_805) s3->elsa_eeprom = 1; - sprintf(s3->nvr_path, "s3_elsa_1k_805_%i.nvr", device_get_instance()); - } break; case S3_86C805_ONBOARD: @@ -10749,14 +10804,20 @@ s3_init(const device_t *info) switch (s3->card_type) { case S3_WINNER1000_805: s3->eeprom_data[0x02] = 0x091a; + s3->eeprom_data[0x07] = 0x83d6; + s3->eeprom_data[0x08] = 0x83d6; snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_1k_805_%d.nvr", s3->eeprom_inst); break; case S3_ELSAWIN2KPROX: s3->eeprom_data[0x02] = 0x094a; + s3->eeprom_data[0x07] = 0xf424; + s3->eeprom_data[0x08] = 0xf424; snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_2k_pro_x8_968_%d.nvr", s3->eeprom_inst); break; case S3_ELSAWIN2KPROX_964: s3->eeprom_data[0x02] = 0x094a; + s3->eeprom_data[0x07] = 0xf424; + s3->eeprom_data[0x08] = 0xf424; snprintf(eeprom_filename, sizeof(eeprom_filename), "eeprom_s3_winner_2k_pro_x8_964_%d.nvr", s3->eeprom_inst); break; default: @@ -10764,16 +10825,9 @@ s3_init(const device_t *info) } s3->eeprom_data[0x05] = 0x0040; - s3->eeprom_data[0x07] = 0xf424; - s3->eeprom_data[0x08] = 0xf424; - // s3->eeprom_data[0x09] = 0x0500; - // s3->eeprom_data[0x0b] = 0x0640; - // s3->eeprom_data[0x0c] = 0x04b0; s3->eeprom_data[0x0b] = 0x0c80; s3->eeprom_data[0x0c] = 0x0a00; s3->eeprom_data[0x0d] = 0x0001; - for (uint8_t i = 0; i < 0x32; i++) - s3->eeprom_data[0x0e + i] = 0xffff; checksum = s3_calc_crc16(64, s3->eeprom_data);