diff --git a/src/i82335.c b/src/i82335.c index 75a593484..981ea8f55 100644 --- a/src/i82335.c +++ b/src/i82335.c @@ -19,27 +19,87 @@ void i82335_write(uint16_t addr, uint8_t val, void *priv) { int i = 0; + int mem_write = 0; + + // pclog("i82335_write(%04X, %02X)\n", addr, val); + switch (addr) { case 0x22: + if ((val ^ i82335.reg_22) & 1) + { + if (val & 1) + { + for (i = 0; i < 8; i++) + { + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + shadowbios = 1; + } + } + else + { + for (i = 0; i < 8; i++) + { + mem_set_mem_state(0xe0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + shadowbios = 0; + } + } + + flushmmucache(); + } + i82335.reg_22 = val | 0xd8; - if (val & 1) - { - for (i = 0; i < 8; i++) - { - mem_mapping_enable(&bios_mapping[i]); - } - } - else - { - for (i = 0; i < 8; i++) - { - mem_mapping_disable(&bios_mapping[i]); - } - } break; case 0x23: - i82335.reg_23 = val | 0xd8; + i82335.reg_23 = val; + + if ((val ^ i82335.reg_22) & 2) + { + if (val & 2) + { + for (i = 0; i < 8; i++) + { + mem_set_mem_state(0xc0000, 0x20000, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); + shadowbios = 1; + } + } + else + { + for (i = 0; i < 8; i++) + { + mem_set_mem_state(0xc0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + shadowbios = 0; + } + } + } + + if ((val ^ i82335.reg_22) & 0xc) + { + if (val & 2) + { + for (i = 0; i < 8; i++) + { + mem_write = (val & 8) ? MEM_WRITE_DISABLED : MEM_WRITE_INTERNAL; + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_INTERNAL | mem_write); + shadowbios = 1; + } + } + else + { + for (i = 0; i < 8; i++) + { + mem_write = (val & 8) ? MEM_WRITE_DISABLED : MEM_WRITE_EXTERNAL; + mem_set_mem_state(0xa0000, 0x20000, MEM_READ_EXTERNAL | mem_write); + shadowbios = 0; + } + } + } + + if ((val ^ i82335.reg_22) & 0xe) + { + flushmmucache(); + } + if (val & 0x80) { io_removehandler(0x0022, 0x0001, i82335_read, NULL, NULL, i82335_write, NULL, NULL, NULL); @@ -50,6 +110,7 @@ void i82335_write(uint16_t addr, uint8_t val, void *priv) uint8_t i82335_read(uint16_t addr, void *priv) { + // pclog("i82335_read(%04X)\n", addr); if (addr == 0x22) { return i82335.reg_22; @@ -58,13 +119,17 @@ uint8_t i82335_read(uint16_t addr, void *priv) { return i82335.reg_23; } + else + { + return 0; + } } void i82335_init() { memset(&i82335, 0, sizeof(i82335_t)); - i82335.reg_22 = 0xd9; + i82335.reg_22 = 0xd8; io_sethandler(0x0022, 0x0014, i82335_read, NULL, NULL, i82335_write, NULL, NULL, NULL); } diff --git a/src/ibm.h b/src/ibm.h index d68e9ede6..dd77bec81 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -422,6 +422,8 @@ enum ROM_IBMPS1_2121_ISA,/*IBM PS/1 Model 2121 with ISA expansion bus*/ ROM_SPC4200P, /*Samsung SPC-4200P / SCAT / Phoenix BIOS*/ + ROM_SUPER286TR, /*Hyundai Super-286TR / SCAT / Award BIOS*/ + ROM_MEGAPCDX, /*386DX mdoel of the Mega PC - Note by Tohka: The documentation (that I have in German) clearly says such a model exists.*/ ROM_MAX @@ -474,7 +476,8 @@ enum GFX_RIVATNT2, GFX_TRIGEM_UNK, - GFX_CHIPS_VGA, + GFX_OTI037, /*Oak OTI-037*/ + GFX_MAX }; diff --git a/src/mem.c b/src/mem.c index c1e6a101b..733bf0980 100644 --- a/src/mem.c +++ b/src/mem.c @@ -592,6 +592,7 @@ int loadbios() return 1; case ROM_IBMPS1_2121: + case ROM_IBMPS1_2121_ISA: f = romfopen("roms/ibmps1_2121/fc0000.bin", "rb"); if (!f) break; fseek(f, 0x20000, SEEK_SET); @@ -655,6 +656,13 @@ int loadbios() fclose(f); return 1; + case ROM_SUPER286TR: /*Hyundai Super-286TR*/ + f = romfopen("roms/super286tr/hyundai_award286.bin", "rb"); + if (!f) break; + fread(rom, 65536, 1, f); + fclose(f); + return 1; + case ROM_PX386: /*Phoenix 80386 BIOS*/ f=romfopen("roms/px386/3iip001l.bin","rb"); ff=romfopen("roms/px386/3iip001h.bin","rb"); diff --git a/src/model.c b/src/model.c index 3e15c8018..72e3011b7 100644 --- a/src/model.c +++ b/src/model.c @@ -150,6 +150,7 @@ MODEL models[] = {"AMI 286 clone", ROM_AMI286, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_neat_init, NULL}, {"Award 286 clone", ROM_AWARD286, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, {"DELL System 200", ROM_DELL200, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_init, NULL}, + {"Hyundai Super-286TR", ROM_SUPER286TR, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, {"Samsung SPC-4200P", ROM_SPC4200P, { "", cpus_286, "", NULL, "", NULL}, 0, MODEL_AT, 1, 16, 1, at_scat_init, NULL}, {"IBM PS/1 model 2011", ROM_IBMPS1_2011, { "", cpus_ps1_m2011,"", NULL, "", NULL}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2011_init, NULL}, {"IBM PS/1 model 2121", ROM_IBMPS1_2121, { "Intel", cpus_i386SX, "AMD", cpus_Am386SX, "Cyrix", cpus_486SLC}, 1, MODEL_AT|MODEL_PS2, 1, 16, 1, ps1_m2121_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 7c3844d5c..abecfe029 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -214,6 +214,7 @@ void loadnvr() case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "rb"); nvrmask = 127; break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "rb"); nvrmask = 127; break; case ROM_DELL200: f = romfopen(nvr_concat("dell200.nvr"), "rb"); nvrmask = 127; break; + case ROM_SUPER286TR: f = romfopen(nvr_concat("super286tr.nvr"), "rb"); nvrmask = 127; break; case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "rb"); nvrmask = 127; break; case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "rb"); nvrmask = 127; break; case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "rb"); break; @@ -297,6 +298,7 @@ void savenvr() case ROM_AMI286: f = romfopen(nvr_concat("ami286.nvr"), "wb"); break; case ROM_AWARD286: f = romfopen(nvr_concat("award286.nvr"), "wb"); break; case ROM_DELL200: f = romfopen(nvr_concat("dell200.nvr"), "wb"); break; + case ROM_SUPER286TR: f = romfopen(nvr_concat("super286tr.nvr"), "wb"); break; case ROM_SPC4200P: f = romfopen(nvr_concat("spc4200p.nvr"), "wb"); break; case ROM_IBMAT386: f = romfopen(nvr_concat("at386.nvr"), "wb"); break; case ROM_DESKPRO_386: f = romfopen(nvr_concat("deskpro386.nvr"), "wb"); break; diff --git a/src/vid_cga.c b/src/vid_cga.c index e5a9de837..aeb0d3e73 100644 --- a/src/vid_cga.c +++ b/src/vid_cga.c @@ -58,15 +58,18 @@ void cga_out(uint16_t addr, uint8_t val, void *p) cga->cgamode = val; update_cga16_color(cga->cgamode); } - cga->cgamode = val; #ifndef __unix - cga_palette = (cga->rgb_type << 1); - if (!(cga->cgamode & 1) && (cga_palette > 0) && (cga_palette < 8)) + if ((cga->cgamode ^ val) & 1) { - cga_palette--; + cga_palette = (cga->rgb_type << 1); + if (!(val & 1) && (cga_palette > 0) && (cga_palette < 8)) + { + cga_palette--; + } cgapal_rebuild(); } #endif + cga->cgamode = val; return; case 0x3D9: cga->cgacol = val; @@ -94,6 +97,10 @@ void cga_write(uint32_t addr, uint8_t val, void *p) { cga_t *cga = (cga_t *)p; // pclog("CGA_WRITE %04X %02X\n", addr, val); + /* Horrible hack, I know, but it's the only way to fix the 440FX BIOS filling the VRAM with garbage until Tom fixes the memory emulation. */ + if ((cs == 0xE0000) && (cpu_state.pc == 0xBF2F) && (romset == ROM_440FX)) return; + if ((cs == 0xE0000) && (cpu_state.pc == 0xBF77) && (romset == ROM_440FX)) return; + cga->vram[addr & 0x3fff] = val; if (cga->snow_enabled) { diff --git a/src/vid_oti067.c b/src/vid_oti067.c index 6ded38b35..202da0466 100644 --- a/src/vid_oti067.c +++ b/src/vid_oti067.c @@ -189,6 +189,12 @@ void *oti067_common_init(char *bios_fn, int vram_size, int chip_id) return oti067; } +/* void *oti037_init() +{ + int vram_size = device_get_config_int("memory"); + return oti067_common_init("roms/hyundai_oti037c.bin", vram_size, 0); +} */ + void *oti067_init() { int vram_size = device_get_config_int("memory"); @@ -205,12 +211,17 @@ void *oti067_acer386_init() { oti067_t *oti067 = oti067_common_init("roms/acer386/oti067.bin", 512, 2); - if (oti067) - oti067->bios_rom.rom[0x5d] = 0x74; + /* if (oti067) + oti067->bios_rom.rom[0x5d] = 0x74; */ return oti067; } +/* static int oti037_available() +{ + return rom_present("roms/hyundai_oti037c.bin"); +} */ + static int oti067_available() { return rom_present("roms/oti067/bios.bin"); @@ -309,6 +320,18 @@ static device_config_t oti077_config[] = } }; +/* device_t oti037_device = +{ + "Oak OTI-037", + 0, + oti037_init, + oti067_close, + oti037_available, + oti067_speed_changed, + oti067_force_redraw, + oti067_add_status_info, + oti067_config +}; */ device_t oti067_device = { "Oak OTI-067", diff --git a/src/vid_oti067.h b/src/vid_oti067.h index 4ac802657..b9ac2dfcb 100644 --- a/src/vid_oti067.h +++ b/src/vid_oti067.h @@ -1,6 +1,7 @@ /* Copyright holders: Sarah Walker, Tenshi see COPYING for more details */ +extern device_t oti037_device; extern device_t oti067_device; extern device_t oti067_acer386_device; extern device_t oti077_device; diff --git a/src/video.c b/src/video.c index 1764b8739..6c3c00ab8 100644 --- a/src/video.c +++ b/src/video.c @@ -88,6 +88,7 @@ static VIDEO_CARD video_cards[] = {"nVidia RIVA TNT (Experimental)", &rivatnt_device, GFX_RIVATNT}, {"nVidia TNT2 (Experimental)", &rivatnt2_device, GFX_RIVATNT2}, + /* {"OAK OTI-037", &oti037_device, GFX_OTI037}, */ {"OAK OTI-067", &oti067_device, GFX_OTI067}, {"OAK OTI-077", &oti077_device, GFX_OTI077}, {"Paradise Bahamas 64 (S3 Vision864)", &s3_bahamas64_device, GFX_BAHAMAS64}, diff --git a/src/x86_ops_i686.h b/src/x86_ops_i686.h index 74f8a7810..0b6bec4de 100644 --- a/src/x86_ops_i686.h +++ b/src/x86_ops_i686.h @@ -33,16 +33,20 @@ static int opSYSENTER(uint32_t fetchdat) uint16_t sysenter_cs_seg_data[4]; uint16_t sysenter_ss_seg_data[4]; +#ifdef SYSENTER_LOG pclog("SYSENTER called\n"); +#endif if (!(cr0 & 1)) return internal_illegal("SYSENTER: CPU not in protected mode"); if (!(cs_msr & 0xFFFC)) return internal_illegal("SYSENTER: CS MSR is zero"); +#ifdef SYSENTER_LOG pclog("SYSENTER started:\n"); pclog("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked); pclog("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked); pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr); pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, eflags, flags, use32, stack32); +#endif if (cpu_state.abrt) return 1; @@ -72,11 +76,13 @@ static int opSYSENTER(uint32_t fetchdat) CPU_BLOCK_END(); +#ifdef SYSENTER_LOG pclog("SYSENTER completed:\n"); pclog("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked); pclog("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked); pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr); pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i\n", cpu_state.pc, ESP, eflags, flags, use32, stack32); +#endif return 0; } @@ -86,17 +92,21 @@ static int opSYSEXIT(uint32_t fetchdat) uint16_t sysexit_cs_seg_data[4]; uint16_t sysexit_ss_seg_data[4]; +#ifdef SYSEXIT_LOG pclog("SYSEXIT called\n"); +#endif if (!(cs_msr & 0xFFFC)) return internal_illegal("SYSEXIT: CS MSR is zero"); if (!(cr0 & 1)) return internal_illegal("SYSEXIT: CPU not in protected mode"); if (CS & 3) return internal_illegal("SYSEXIT: CPL not 0"); +#ifdef SYSEXIT_LOG pclog("SYSEXIT start:\n"); pclog("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked); pclog("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked); pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr); pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, eflags, flags, use32, stack32, ECX, EDX); +#endif if (cpu_state.abrt) return 1; @@ -124,11 +134,13 @@ static int opSYSEXIT(uint32_t fetchdat) CPU_BLOCK_END(); +#ifdef SYSEXIT_LOG pclog("SYSEXIT completed:\n"); pclog("CS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", CS, _cs.base, _cs.limit, _cs.access, _cs.seg, _cs.limit_low, _cs.limit_high, _cs.checked); pclog("SS (%04X): base=%08X, limit=%08X, access=%02X, seg=%04X, limit_low=%08X, limit_high=%08X, checked=%i\n", SS, _ss.base, _ss.limit, _ss.access, _ss.seg, _ss.limit_low, _ss.limit_high, _ss.checked); pclog("Model specific registers: cs_msr=%04X, esp_msr=%08X, eip_msr=%08X\n", cs_msr, esp_msr, eip_msr); pclog("Other information: eip=%08X esp=%08X eflags=%04X flags=%04X use32=%04X stack32=%i ECX=%08X EDX=%08X\n", cpu_state.pc, ESP, eflags, flags, use32, stack32, ECX, EDX); +#endif return 0; }