Xi 8088: add the UMB dip switch and allow the programming of the BIOS flash memory
Some checks failed
C/C++ CI / Ubuntu 64bit (gcc) (push) Has been cancelled
C/C++ CI / Windows 32bits (MSYS2) (push) Has been cancelled
C/C++ CI / Windows 64bits (MSYS2) (push) Has been cancelled

This commit is contained in:
pcem-maintainer 2021-07-04 18:32:57 -03:00
commit 78d0618363
5 changed files with 118 additions and 20 deletions

View file

@ -1468,7 +1468,22 @@ void mem_alloc()
memset(_mem_state, 0, sizeof(_mem_state)); 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(0x000000, (mem_size > 640) ? 0xa0000 : mem_size * 1024, MEM_READ_INTERNAL | MEM_WRITE_INTERNAL);
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_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); 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) if (mem_size > 1024)
@ -1484,7 +1499,7 @@ 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); 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) 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); 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) if (romset == ROM_IBMPS1_2011)

View file

@ -468,7 +468,6 @@ void xt_zenith_init() /* [8088] Zenith Data Systems SupersPort */
void xt_xi8088_init() 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(); common_init();
mem_add_bios(); mem_add_bios();
keyboard_at_init(); keyboard_at_init();
@ -477,6 +476,7 @@ void xt_xi8088_init()
device_add(&nvr_device); device_add(&nvr_device);
pic2_init(); pic2_init();
device_add(&gameport_device); device_add(&gameport_device);
device_add(&sst_39sf010_device);
} }
void at_init() void at_init()

View file

@ -312,7 +312,9 @@ void initpc(int argc, char *argv[])
initvideo(); initvideo();
mem_init(); mem_init();
loadbios(); loadbios();
mem_add_bios();
// this is now done per-model
//mem_add_bios();
#if defined(__APPLE__) && defined(__aarch64__) #if defined(__APPLE__) && defined(__aarch64__)
pthread_jit_write_protect_np(0); pthread_jit_write_protect_np(0);

View file

@ -3,6 +3,7 @@
#include "device.h" #include "device.h"
#include "mem.h" #include "mem.h"
#include "sst39sf010.h" #include "sst39sf010.h"
#include "xi8088.h"
typedef struct sst_t typedef struct sst_t
{ {
@ -25,6 +26,18 @@ typedef struct sst_t
static void set_id_mode(sst_t *sst); static void set_id_mode(sst_t *sst);
static void clear_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) static void sst_new_command(sst_t *sst, uint8_t val)
{ {
switch (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); // pclog("SST sector erase sst_addr %08x\n", sst_addr);
memset(&rom[addr & 0x1f000], 0xff, 4096); memset(&rom[sst_addr & 0x1f000], 0xff, 4096);
memset(&sst->data[addr & 0x1f000], 0xff, 4096); memset(&sst->data[sst_addr & 0x1f000], 0xff, 4096);
sst->dirty = 1; sst->dirty = 1;
} }
@ -117,7 +130,7 @@ static void sst_write(uint32_t addr, uint8_t val, void *p)
sst_new_command(sst, val); sst_new_command(sst, val);
else if (val == SST_SECTOR_ERASE && sst->erase) 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; sst->command_state = 0;
} }
else else
@ -125,8 +138,8 @@ static void sst_write(uint32_t addr, uint8_t val, void *p)
break; break;
case 3: case 3:
// pclog("Byte program %08x %02x\n", addr, val); // pclog("Byte program %08x %02x\n", addr, val);
rom[addr & 0x1ffff] = val; rom[sst_masked_rom_addr(addr)] = val;
sst->data[addr & 0x1ffff] = val; sst->data[sst_masked_rom_addr(addr)] = val;
sst->command_state = 0; sst->command_state = 0;
sst->dirty = 1; sst->dirty = 1;
break; break;
@ -177,9 +190,14 @@ static void *sst_39sf010_init()
switch(romset) switch(romset)
{ {
case ROM_XI8088:
strcpy(sst->flash_path, "xi8088/");
break;
case ROM_FIC_VA503P: case ROM_FIC_VA503P:
strcpy(sst->flash_path, "fic_va503p/"); strcpy(sst->flash_path, "fic_va503p/");
break; break;
default: default:
fatal("sst_39sf010_init on unsupported ROM set %i\n", romset); 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"); f = romfopen(sst->flash_path, "rb");
if (f) if (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); fread(rom, 0x20000, 1, f);
break;
default:
fatal("sst_39sf010_init on unsupported ROM set %i\n", romset);
}
fclose(f); fclose(f);
} }
memcpy(sst->data, rom, 0x20000); memcpy(sst->data, rom, 0x20000);
@ -204,7 +236,21 @@ static void sst_39sf010_close(void *p)
if (sst->dirty) if (sst->dirty)
{ {
FILE *f = romfopen(sst->flash_path, "wb"); FILE *f = romfopen(sst->flash_path, "wb");
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); fwrite(sst->data, 0x20000, 1, f);
break;
default:
fatal("sst_39sf010_init on unsupported ROM set %i\n", romset);
}
fclose(f); fclose(f);
} }

View file

@ -28,12 +28,12 @@ void xi8088_turbo_set(uint8_t value)
xi8088.turbo = value; xi8088.turbo = value;
if (!value) if (!value)
{ {
pclog("Xi8088 turbo off\n"); // pclog("Xi8088 turbo off\n");
cpu_set_turbo(0); cpu_set_turbo(0);
} }
else else
{ {
pclog("Xi8088 turbo on\n"); // pclog("Xi8088 turbo on\n");
cpu_set_turbo(1); cpu_set_turbo(1);
} }
} }
@ -45,7 +45,6 @@ int xi8088_bios_128kb()
static void *xi8088_init() 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 = 1;
xi8088.turbo_setting = device_get_config_int("turbo_setting"); xi8088.turbo_setting = device_get_config_int("turbo_setting");
xi8088.bios_128kb = device_get_config_int("bios_128kb"); xi8088.bios_128kb = device_get_config_int("bios_128kb");
@ -66,7 +65,7 @@ static device_config_t xi8088_config[] =
.value = 0 .value = 0
}, },
{ {
.description = "Hotkeys (starts off)", .description = "BIOS setting + Hotkeys (off during POST)",
.value = 1 .value = 1
} }
}, },
@ -79,16 +78,52 @@ static device_config_t xi8088_config[] =
.selection = .selection =
{ {
{ {
.description = "64KB", .description = "64KB starting from 0xF0000",
.value = 0 .value = 0
}, },
{ {
.description = "128KB", .description = "128KB starting from 0xE0000 (address MSB inverted, last 64KB first)",
.value = 1 .value = 1
} }
}, },
.default_int = 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 .type = -1
} }