Merge branch '86Box:master' into master

This commit is contained in:
starfrost
2025-09-06 15:44:39 +01:00
committed by GitHub
44 changed files with 752 additions and 582 deletions

View File

@@ -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;
}

View File

@@ -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++) {

View File

@@ -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;

View File

@@ -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 }

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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];

View File

@@ -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*/

View File

@@ -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 }
},

View File

@@ -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 }
},

View File

@@ -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 }
},

View File

@@ -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 }
},
},

View File

@@ -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 }
},

View File

@@ -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 }
},

View File

@@ -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", "" } },

View File

@@ -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,

View File

@@ -21,6 +21,7 @@ add_library(mem OBJECT
intel_flash.c
mem.c
mmu_2386.c
nmc93cxx.c
rom.c
row.c
smram.c

View File

@@ -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 *

View File

@@ -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

View File

@@ -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>

View File

@@ -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 = {

View File

@@ -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>

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -23,6 +23,8 @@
#include <QFileDialog>
#include <QStringBuilder>
#include <cstdint>
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();
}
}
}

View File

@@ -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 {

View File

@@ -351,7 +351,7 @@ illegal_chars:
}
});
connect(vm_model, &VMManagerModel::globalConfigurationChanged, this, [this] () {
connect(vm_model, &VMManagerModel::globalConfigurationChanged, this, [] () {
vmm_main_window->updateSettings();
});

View File

@@ -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
{

View File

@@ -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

View File

@@ -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, &params);
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;
}

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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"";
}

View File

@@ -316,7 +316,7 @@ ini_close(ini_t ini)
free(list);
}
static int
int
ini_detect_bom(const char *fn)
{
FILE *fp;

View File

@@ -44,6 +44,7 @@ add_library(vid OBJECT
# DDC / monitor identification stuff
vid_ddc.c
vid_ddc_edid_custom.c
# CARDS start here

View File

@@ -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)
{

View File

@@ -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, <hrdlickadavid@outlook.com>
*
* Copyright 2025 Cacodemon.
* Copyright 2025 David Hrdlička.
*/
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

View File

@@ -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) {

View File

@@ -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);