From 8f04b6b9a43873fea3986e0f35bf0ef1f63a36dd Mon Sep 17 00:00:00 2001 From: SarahW Date: Wed, 31 Jan 2018 21:53:23 +0000 Subject: [PATCH] Added Toshiba T1200 emulation. Patch from John Elliott. --- src/ibm.h | 3 +- src/keyboard_xt.c | 2 +- src/mem.c | 10 ++++++ src/model.c | 2 ++ src/nvr.c | 6 ++++ src/nvr_tc8521.c | 2 ++ src/t1000.c | 77 +++++++++++++++++++++++++++++++++++++++++++++-- src/vid_t1000.c | 4 ++- src/video.c | 1 + 9 files changed, 102 insertions(+), 5 deletions(-) diff --git a/src/ibm.h b/src/ibm.h index 6b10a9e..8873741 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -378,7 +378,7 @@ char discfns[2][256]; int driveempty[2]; #define MDA ((gfxcard==GFX_MDA || gfxcard==GFX_HERCULES || gfxcard==GFX_INCOLOR || gfxcard==GFX_GENIUS) && (romset=ROM_IBMAT)) -#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_WY700 && gfxcard!=GFX_GENIUS && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200 && romset != ROM_T3100E && romset != ROM_T1000) +#define VGA ((gfxcard>=GFX_TVGA || romset==ROM_ACER386) && gfxcard!=GFX_COLORPLUS && gfxcard!=GFX_INCOLOR && gfxcard!=GFX_WY700 && gfxcard!=GFX_GENIUS && romset!=ROM_PC1640 && romset!=ROM_PC1512 && romset!=ROM_TANDY && romset!=ROM_PC200 && romset != ROM_T3100E && romset != ROM_T1000 && romset != ROM_T1200) #define PCJR (romset == ROM_IBMPCJR) #define AMIBIOS (romset==ROM_AMI386SX || romset==ROM_AMI486 || romset == ROM_WIN486) @@ -446,6 +446,7 @@ enum ROM_EPSON_PCAX3, ROM_T3100E, ROM_T1000, + ROM_T1200, ROM_MAX }; diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index 72cbf28..45fd521 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -58,7 +58,7 @@ void keyboard_xt_poll() void keyboard_xt_adddata(uint8_t val) { /* Test for T1000 'Fn' key (Right Alt / Right Ctrl) */ - if (romset == ROM_T1000) + if (romset == ROM_T1000 || romset == ROM_T1200) { if (pcem_key[0xb8] || pcem_key[0x9D]) /* 'Fn' pressed */ { diff --git a/src/mem.c b/src/mem.c index adc4de8..7a03c12 100644 --- a/src/mem.c +++ b/src/mem.c @@ -772,6 +772,16 @@ int loadbios() biosmask = 0x7fff; fclose(f); return 1; + + case ROM_T1200: + loadfont("t1200/t1000font.rom", 2); + f=romfopen("t1200/t1200_019e.ic15.bin","rb"); + if (!f) break; + romfread(rom, 0x8000,1,f); + memcpy(rom + 0x8000, rom, 0x8000); + biosmask = 0x7fff; + fclose(f); + return 1; } printf("Failed to load ROM!\n"); if (f) fclose(f); diff --git a/src/model.c b/src/model.c index 6b9273d..e2504f1 100644 --- a/src/model.c +++ b/src/model.c @@ -92,6 +92,7 @@ void at_endeavor_init(); void xt_laserxt_init(); void at_t3100e_init(); void xt_t1000_init(); +void xt_t1200_init(); int model; int AMSTRAD, AT, PCI, TANDY; @@ -120,6 +121,7 @@ MODEL models[] = {"[8086] Olivetti M24", ROM_OLIM24, "olivetti_m24", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_OLIM24, 128, 640, 128, olim24_init, NULL}, {"[8086] Sinclair PC200", ROM_PC200, "pc200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, MODEL_AMSTRAD, 512, 640, 128, ams_init, NULL}, {"[8086] Tandy 1000 SL/2", ROM_TANDY1000SL2, "tandy1000sl2", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, 0, 512, 768, 128, tandy1ksl2_init, NULL}, + {"[8088] Toshiba 1200", ROM_T1200, "t1200", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 1, 0, 1024,2048,1024, xt_t1200_init, &t1000_device}, {"[8086] VTech Laser XT3", ROM_LXT3, "lxt3", { {"", cpus_8086}, {"", NULL}, {"", NULL}}, 0, 0, 512,1152, 128, xt_laserxt_init, NULL}, {"[286] AMI 286 clone", ROM_AMI286, "ami286", { {"", cpus_286}, {"", NULL}, {"", NULL}}, 0, MODEL_AT|MODEL_HAS_IDE, 512,16384,128, at_neat_init, NULL}, diff --git a/src/nvr.c b/src/nvr.c index 7f4476c..25dd137 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -292,6 +292,9 @@ void loadnvr() t1000_configsys_loadnvr(); t1000_emsboard_loadnvr(); return; + case ROM_T1200: tc8521_loadnvr(); + t1000_emsboard_loadnvr(); + return; default: return; } @@ -369,6 +372,9 @@ void savenvr() t1000_configsys_savenvr(); t1000_emsboard_savenvr(); return; + case ROM_T1200: tc8521_savenvr(); + t1000_emsboard_savenvr(); + return; default: return; } fwrite(nvrram,128,1,f); diff --git a/src/nvr_tc8521.c b/src/nvr_tc8521.c index 6e20c41..f221c00 100644 --- a/src/nvr_tc8521.c +++ b/src/nvr_tc8521.c @@ -58,6 +58,7 @@ void tc8521_loadnvr() switch (romset) { case ROM_T1000: f = nvrfopen("t1000.nvr", "rb"); break; + case ROM_T1200: f = nvrfopen("t1200.nvr", "rb"); break; default: return; } if (!f) @@ -85,6 +86,7 @@ void tc8521_savenvr() switch (oldromset) { case ROM_T1000: f = nvrfopen("t1000.nvr", "wb"); break; + case ROM_T1200: f = nvrfopen("t1200.nvr", "wb"); break; default: return; } fwrite(nvrram,64,1,f); diff --git a/src/t1000.c b/src/t1000.c index 1076489..7dae292 100644 --- a/src/t1000.c +++ b/src/t1000.c @@ -27,7 +27,8 @@ * A ROM drive (128k, 256k or 512k) which acts as a mini hard * drive and contains a copy of DOS 2.11. * 160 bytes of non-volatile RAM for the CONFIG.SYS used when - * booting from the ROM drive. + * booting from the ROM drive. Possibly physically located + * in the keyboard controller RAM. * * An optional memory expansion board can be fitted. This adds 768k of RAM, * which can be used for up to three purposes: @@ -38,7 +39,13 @@ * This means that there are up to three different implementations of * non-volatile RAM in the same computer (52 nibbles in the TC8521, 160 * bytes of CONFIG.SYS, and up to 768k of HardRAM). - * + * + * The T1200 is a slightly upgraded version with a turbo mode (double CPU + * clock, 9.54MHz) and an optional hard drive. The interface for this is + * proprietary both at the physical and programming level. + * + * 01F2h: If hard drive is present, low 4 bits are 0Ch [20Mb] or 0Dh [10Mb]. + * */ void common_init(); @@ -56,6 +63,7 @@ static struct t1000_system /* System control registers */ uint8_t sys_ctl[16]; uint8_t syskeys; + uint8_t turbo; /* NVRAM control */ uint8_t nvr_c0; @@ -375,6 +383,26 @@ static uint8_t read_t1000_ctl(uint16_t addr, void *priv) } } +static void t1200_turbo_set(uint8_t value) +{ + if (value == t1000.turbo) + { + return; + } + t1000.turbo = value; + if (!value) + { + int c = cpu; + cpu = 0; /* 8088/4.77MHz */ + cpu_set(); + cpu = c; + } + else + { + cpu_set(); + } +} + static void write_t1000_ctl(uint16_t addr, uint8_t val, void *priv) { struct t1000_system *sys = (struct t1000_system *)priv; @@ -387,6 +415,10 @@ static void write_t1000_ctl(uint16_t addr, uint8_t val, void *priv) { t1000_video_options_set((val & 0x20) ? 1 : 0); t1000_display_set((val & 0x40) ? 0 : 1); + if (romset == ROM_T1200) + { + t1200_turbo_set((val & 0x80) ? 1 : 0); + } } break; /* EMS control*/ @@ -526,6 +558,7 @@ void xt_t1000_init() int pg; memset(&t1000, 0, sizeof(t1000)); + t1000.turbo = 0xff; t1000.ems_port_index = 7; /* EMS disabled */ /* The ROM drive is optional. If the file is missing, continue to boot; the * BIOS will complain 'No ROM drive' but boot normally from floppy. */ @@ -577,3 +610,43 @@ void xt_t1000_init() nvr_tc8521_init(); /* No gameport, and no provision to fit one device_add(&gameport_device); */ } + + +void xt_t1200_init() +{ + int pg; + + memset(&t1000, 0, sizeof(t1000)); + t1000.ems_port_index = 7; /* EMS disabled */ + + mem_mapping_add(&t1000.rom_mapping, 0xA0000, 0x10000, + t1000_read_rom, t1000_read_romw, t1000_read_roml, + NULL, NULL, NULL, NULL, MEM_MAPPING_INTERNAL, &t1000); + mem_mapping_disable(&t1000.rom_mapping); + + /* Map the EMS page frame */ + for (pg = 0; pg < 4; pg++) + { + mem_mapping_add(&t1000.mapping[pg], + 0xD0000 + (0x4000 * pg), 16384, + ems_read_ram, ems_read_ramw, ems_read_raml, + ems_write_ram, ems_write_ramw, ems_write_raml, + NULL, MEM_MAPPING_EXTERNAL, + &t1000); + /* Start them all off disabled */ + mem_mapping_disable(&t1000.mapping[pg]); + } + + /* System control functions, and add-on memory board */ + io_sethandler(0xE0, 0x10, read_t1000_ctl, NULL, NULL, + write_t1000_ctl, NULL, NULL, &t1000); + + common_init(); + mem_add_bios(); + pit_set_out_func(&pit, 1, pit_refresh_timer_xt); + keyboard_xt_init(); + nmi_init(); + nvr_tc8521_init(); +/* No gameport, and no provision to fit one device_add(&gameport_device); */ +} + diff --git a/src/vid_t1000.c b/src/vid_t1000.c index 69939d8..ce9b310 100644 --- a/src/vid_t1000.c +++ b/src/vid_t1000.c @@ -18,6 +18,7 @@ static uint32_t blue, grey; static uint8_t boldcols[256]; /* Which attributes use the bold font */ static uint32_t blinkcols[256][2]; static uint32_t normcols[256][2]; +static uint8_t language; /* Video options set by the motherboard; they will be picked up by the card * on the next poll. @@ -31,7 +32,7 @@ static uint8_t st_display_internal = -1; void t1000_video_options_set(uint8_t options) { st_video_options = options & 1; - st_video_options |= device_get_config_int("display_language") ? 2 : 0; + st_video_options |= language; } void t1000_display_set(uint8_t internal) @@ -638,6 +639,7 @@ static void *t1000_init() t1000->cga.vram = t1000->vram; t1000->enabled = 1; t1000->video_options = 0x01; + language = device_get_config_int("display_language") ? 2 : 0; return t1000; } diff --git a/src/video.c b/src/video.c index 325361f..1166b75 100644 --- a/src/video.c +++ b/src/video.c @@ -442,6 +442,7 @@ void video_init() return; case ROM_T1000: + case ROM_T1200: device_add(&t1000_device); return; }