From 78d06183633c6c3ea042e533ca36081e113e2420 Mon Sep 17 00:00:00 2001 From: pcem-maintainer Date: Sun, 4 Jul 2021 18:32:57 -0300 Subject: [PATCH] Xi 8088: add the UMB dip switch and allow the programming of the BIOS flash memory --- src/mem.c | 21 +++++++++++++--- src/model.c | 2 +- src/pc.c | 4 ++- src/sst39sf010.c | 64 +++++++++++++++++++++++++++++++++++++++++------- src/xi8088.c | 47 ++++++++++++++++++++++++++++++----- 5 files changed, 118 insertions(+), 20 deletions(-) diff --git a/src/mem.c b/src/mem.c index 98dc738..15dc5ee 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1468,7 +1468,22 @@ void mem_alloc() memset(_mem_state, 0, sizeof(_mem_state)); mem_set_mem_state(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL); - mem_set_mem_state(0x0a0000, 0x60000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + if (romset == ROM_XI8088) + { + // Xi 8088 UMBs are selected by DIP Switches + mem_set_mem_state(0x0a0000, 0x20000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + mem_set_mem_state(0x0c0000, 0x08000, model_get_config_int("umb_c0000h_c7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0c8000, 0x08000, model_get_config_int("umb_c8000h_cffff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0d0000, 0x08000, model_get_config_int("umb_d0000h_d7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0d8000, 0x08000, model_get_config_int("umb_d8000h_dffff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0e0000, 0x08000, model_get_config_int("umb_e0000h_e7fff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0e8000, 0x08000, model_get_config_int("umb_e8000h_effff") ? (MEM_READ_INTERNAL | MEM_WRITE_INTERNAL) : (MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL)); + mem_set_mem_state(0x0f0000, 0x10000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } + else + { + mem_set_mem_state(0x0a0000, 0x60000, MEM_READ_EXTERNAL | MEM_WRITE_EXTERNAL); + } mem_mapping_add(&ram_low_mapping, 0x00000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram, MEM_MAPPING_INTERNAL, NULL); if (mem_size > 1024) @@ -1484,8 +1499,8 @@ void mem_alloc() mem_mapping_add(&ram_high_mapping, 0x100000, ((mem_size - 1024) * 1024), mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0x100000, MEM_MAPPING_INTERNAL, NULL); } } - if (mem_size > 768) - mem_mapping_add(&ram_mid_mapping, 0xa0000, 0x60000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); + if (mem_size > 768) // 640k - 768k is graphics RAM + mem_mapping_add(&ram_mid_mapping, 0xa0000, 0x60000, mem_read_ram, mem_read_ramw, mem_read_raml, mem_write_ram, mem_write_ramw, mem_write_raml, ram + 0xa0000, MEM_MAPPING_INTERNAL, NULL); if (romset == ROM_IBMPS1_2011) mem_mapping_add(&romext_mapping, 0xc8000, 0x08000, mem_read_romext, mem_read_romextw, mem_read_romextl, NULL, NULL, NULL, romext, 0, NULL); diff --git a/src/model.c b/src/model.c index 672b110..6b9f71f 100644 --- a/src/model.c +++ b/src/model.c @@ -468,7 +468,6 @@ void xt_zenith_init() /* [8088] Zenith Data Systems SupersPort */ void xt_xi8088_init() { - /* TODO: set UMBs? See if PCem always sets when we have > 640KB ram and avoids conflicts when a peripheral uses the same memory space */ common_init(); mem_add_bios(); keyboard_at_init(); @@ -477,6 +476,7 @@ void xt_xi8088_init() device_add(&nvr_device); pic2_init(); device_add(&gameport_device); + device_add(&sst_39sf010_device); } void at_init() diff --git a/src/pc.c b/src/pc.c index 2e20851..dbe1633 100644 --- a/src/pc.c +++ b/src/pc.c @@ -312,7 +312,9 @@ void initpc(int argc, char *argv[]) initvideo(); mem_init(); loadbios(); - mem_add_bios(); + + // this is now done per-model + //mem_add_bios(); #if defined(__APPLE__) && defined(__aarch64__) pthread_jit_write_protect_np(0); diff --git a/src/sst39sf010.c b/src/sst39sf010.c index 8acb664..b2283f1 100644 --- a/src/sst39sf010.c +++ b/src/sst39sf010.c @@ -3,6 +3,7 @@ #include "device.h" #include "mem.h" #include "sst39sf010.h" +#include "xi8088.h" typedef struct sst_t { @@ -25,6 +26,18 @@ typedef struct sst_t static void set_id_mode(sst_t *sst); static void clear_id_mode(sst_t *sst); +static uint32_t sst_masked_rom_addr(uint32_t addr) +{ + // The flipped MSB of the Xi 8088 is only present in the on-disk files, + // in ram the mapping is as the software sees. This does not cause + // problems with the programming commands because they only use the + // lower 2 bytes. + if (romset == ROM_XI8088 && !xi8088_bios_128kb()) + return addr & 0xffff; + else + return addr & 0x1ffff; +} + static void sst_new_command(sst_t *sst, uint8_t val) { switch (val) @@ -69,11 +82,11 @@ static void sst_new_command(sst_t *sst, uint8_t val) } } -static void sst_sector_erase(sst_t *sst, uint32_t addr) +static void sst_sector_erase(sst_t *sst, uint32_t sst_addr) { -// pclog("SST sector erase %08x\n", addr); - memset(&rom[addr & 0x1f000], 0xff, 4096); - memset(&sst->data[addr & 0x1f000], 0xff, 4096); +// pclog("SST sector erase sst_addr %08x\n", sst_addr); + memset(&rom[sst_addr & 0x1f000], 0xff, 4096); + memset(&sst->data[sst_addr & 0x1f000], 0xff, 4096); sst->dirty = 1; } @@ -117,7 +130,7 @@ static void sst_write(uint32_t addr, uint8_t val, void *p) sst_new_command(sst, val); else if (val == SST_SECTOR_ERASE && sst->erase) { - sst_sector_erase(sst, addr); + sst_sector_erase(sst, sst_masked_rom_addr(addr)); sst->command_state = 0; } else @@ -125,8 +138,8 @@ static void sst_write(uint32_t addr, uint8_t val, void *p) break; case 3: // pclog("Byte program %08x %02x\n", addr, val); - rom[addr & 0x1ffff] = val; - sst->data[addr & 0x1ffff] = val; + rom[sst_masked_rom_addr(addr)] = val; + sst->data[sst_masked_rom_addr(addr)] = val; sst->command_state = 0; sst->dirty = 1; break; @@ -177,9 +190,14 @@ static void *sst_39sf010_init() switch(romset) { + case ROM_XI8088: + strcpy(sst->flash_path, "xi8088/"); + break; + case ROM_FIC_VA503P: strcpy(sst->flash_path, "fic_va503p/"); break; + default: fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); } @@ -187,7 +205,21 @@ static void *sst_39sf010_init() f = romfopen(sst->flash_path, "rb"); if (f) { - fread(rom, 0x20000, 1, f); + switch(romset) + { + case ROM_XI8088: + if (xi8088_bios_128kb()) + fread(rom + 0x10000, 0x10000, 1, f); + fread(rom, 0x10000, 1, f); + break; + + case ROM_FIC_VA503P: + fread(rom, 0x20000, 1, f); + break; + + default: + fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); + } fclose(f); } memcpy(sst->data, rom, 0x20000); @@ -204,7 +236,21 @@ static void sst_39sf010_close(void *p) if (sst->dirty) { FILE *f = romfopen(sst->flash_path, "wb"); - fwrite(sst->data, 0x20000, 1, f); + switch(romset) + { + case ROM_XI8088: + if (xi8088_bios_128kb()) + fwrite(sst->data + 0x10000, 0x10000, 1, f); + fwrite(sst->data, 0x10000, 1, f); + break; + + case ROM_FIC_VA503P: + fwrite(sst->data, 0x20000, 1, f); + break; + + default: + fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); + } fclose(f); } diff --git a/src/xi8088.c b/src/xi8088.c index 6ea95e6..1c5a135 100644 --- a/src/xi8088.c +++ b/src/xi8088.c @@ -28,12 +28,12 @@ void xi8088_turbo_set(uint8_t value) xi8088.turbo = value; if (!value) { - pclog("Xi8088 turbo off\n"); +// pclog("Xi8088 turbo off\n"); cpu_set_turbo(0); } else { - pclog("Xi8088 turbo on\n"); +// pclog("Xi8088 turbo on\n"); cpu_set_turbo(1); } } @@ -45,7 +45,6 @@ int xi8088_bios_128kb() static void *xi8088_init() { - /* even though the bios by default turns the turbo off when controlling by hotkeys, pcem always starts at full speed */ xi8088.turbo = 1; xi8088.turbo_setting = device_get_config_int("turbo_setting"); xi8088.bios_128kb = device_get_config_int("bios_128kb"); @@ -66,7 +65,7 @@ static device_config_t xi8088_config[] = .value = 0 }, { - .description = "Hotkeys (starts off)", + .description = "BIOS setting + Hotkeys (off during POST)", .value = 1 } }, @@ -79,16 +78,52 @@ static device_config_t xi8088_config[] = .selection = { { - .description = "64KB", + .description = "64KB starting from 0xF0000", .value = 0 }, { - .description = "128KB", + .description = "128KB starting from 0xE0000 (address MSB inverted, last 64KB first)", .value = 1 } }, .default_int = 1 }, + { + .name = "umb_c0000h_c7fff", + .description = "Map 0xc0000-0xc7fff as UMB", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "umb_c8000h_cffff", + .description = "Map 0xc8000-0xcffff as UMB", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "umb_d0000h_d7fff", + .description = "Map 0xd0000-0xd7fff as UMB", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "umb_d8000h_dffff", + .description = "Map 0xd8000-0xdffff as UMB", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "umb_e0000h_e7fff", + .description = "Map 0xe0000-0xe7fff as UMB", + .type = CONFIG_BINARY, + .default_int = 0 + }, + { + .name = "umb_e8000h_effff", + .description = "Map 0xe8000-0xeffff as UMB", + .type = CONFIG_BINARY, + .default_int = 0 + }, { .type = -1 }