Added the Tulip PC Compact 2, the Tulip DGA font ROM, and assorted font ROM-related improvements.

This commit is contained in:
OBattler
2025-06-15 02:55:32 +02:00
parent b394480a06
commit 30ae882263
11 changed files with 238 additions and 19 deletions

View File

@@ -69,6 +69,7 @@ enum {
KBD_TYPE_ZENITH,
KBD_TYPE_PRAVETZ,
KBD_TYPE_HYUNDAI,
KBD_TYPE_FE2010,
KBD_TYPE_XTCLONE
};
@@ -80,6 +81,7 @@ typedef struct xtkbd_t {
uint8_t pa;
uint8_t pb;
uint8_t pd;
uint8_t cfg;
uint8_t clock;
uint8_t key_waiting;
uint8_t type;
@@ -832,12 +834,26 @@ kbd_write(uint16_t port, uint8_t val, void *priv)
kbd_log("XTkbd: Cassette motor is %s\n", !(val & 0x08) ? "ON" : "OFF");
#endif
break;
#ifdef ENABLE_KEYBOARD_XT_LOG
case 0x62: /* Switch Register (aka Port C) */
#ifdef ENABLE_KEYBOARD_XT_LOG
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ))
kbd_log("XTkbd: Cassette IN is %i\n", !!(val & 0x10));
break;
#endif
if (kbd->type == KBD_TYPE_FE2010) {
kbd_log("XTkbd: Switch register in is %02X\n", val);
if (!(kbd->cfg & 0x08))
kbd->pd = (kbd->pd & 0x30) | (val & 0xcf);
}
break;
case 0x63:
if (kbd->type == KBD_TYPE_FE2010) {
kbd_log("XTkbd: Configuration register in is %02X\n", val);
if (!(kbd->cfg & 0x08))
kbd->cfg = val;
}
break;
case 0xc0 ... 0xcf: /* Pravetz Flags */
kbd_log("XTkbd: Port %02X out: %02X\n", port, val);
@@ -912,7 +928,12 @@ kbd_read(uint16_t port, void *priv)
break;
case 0x62: /* Switch Register (aka Port C) */
if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
if (kbd->type == KBD_TYPE_FE2010) {
if (kbd->pb & 0x04) /* PB2 */
ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00);
else
ret = kbd->pd >> 4;
} else if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) ||
(kbd->type == KBD_TYPE_PRAVETZ)) {
if (kbd->pb & 0x04) /* PB2 */
switch (mem_size + isa_mem_size) {
@@ -1037,7 +1058,7 @@ kbd_init(const device_t *info)
(kbd->type <= KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) ||
(kbd->type == KBD_TYPE_COMPAQ) || (kbd->type == KBD_TYPE_TOSHIBA) ||
(kbd->type == KBD_TYPE_OLIVETTI) || (kbd->type == KBD_TYPE_HYUNDAI) ||
(kbd->type == KBD_TYPE_VTECH)) {
(kbd->type == KBD_TYPE_VTECH) || (kbd->type == KBD_TYPE_FE2010)) {
/* DIP switch readout: bit set = OFF, clear = ON. */
if (kbd->type == KBD_TYPE_OLIVETTI)
/* Olivetti M19
@@ -1057,7 +1078,7 @@ kbd_init(const device_t *info)
/* Switches 3, 4 - memory size. */
if ((kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_XTCLONE) ||
(kbd->type == KBD_TYPE_HYUNDAI) || (kbd->type == KBD_TYPE_COMPAQ) ||
(kbd->type == KBD_TYPE_TOSHIBA)) {
(kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_FE2010)) {
switch (mem_size) {
case 256:
kbd->pd |= 0x00;
@@ -1356,7 +1377,7 @@ const device_t keyboard_xt_zenith_device = {
const device_t keyboard_xt_hyundai_device = {
.name = "Hyundai XT Keyboard",
.internal_name = "keyboard_x_hyundai",
.internal_name = "keyboard_xt_hyundai",
.flags = 0,
.local = KBD_TYPE_HYUNDAI,
.init = kbd_init,
@@ -1368,6 +1389,20 @@ const device_t keyboard_xt_hyundai_device = {
.config = NULL
};
const device_t keyboard_xt_fe2010_device = {
.name = "Faraday FE2010 XT Keyboard",
.internal_name = "keyboard_xt_fe2010",
.flags = 0,
.local = KBD_TYPE_FE2010,
.init = kbd_init,
.close = kbd_close,
.reset = kbd_reset,
.available = NULL,
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};
const device_t keyboard_xtclone_device = {
.name = "XT (Clone) Keyboard",
.internal_name = "keyboard_xtclone",

View File

@@ -228,6 +228,7 @@ extern const device_t keyboard_xt_lxt3_device;
extern const device_t keyboard_xt_olivetti_device;
extern const device_t keyboard_xt_zenith_device;
extern const device_t keyboard_xt_hyundai_device;
extern const device_t keyboard_xt_fe2010_device;
extern const device_t keyboard_xtclone_device;
extern const device_t keyboard_at_device;
extern const device_t keyboard_at_ami_device;

View File

@@ -980,6 +980,7 @@ extern int machine_xt_kaypropc_init(const machine_t *);
extern int machine_xt_sansx16_init(const machine_t *);
extern int machine_xt_bw230_init(const machine_t *);
extern int machine_xt_pb8810_init(const machine_t *);
extern int machine_xt_tuliptc8_init(const machine_t *);
extern int machine_xt_v20xt_init(const machine_t *);

View File

@@ -75,6 +75,7 @@ enum {
#define FONT_IBM_MDA_437_NORDIC_PATH "roms/video/mda/4733197.bin"
#define FONT_KAM_PATH "roms/video/mda/kam.bin"
#define FONT_KAMCL16_PATH "roms/video/mda/kamcl16.bin"
#define FONT_TULIP_DGA_PATH "roms/video/mda/tulip-dga-bios.bin"
typedef struct video_timings_t {
int type;

View File

@@ -39,6 +39,7 @@
#include <86box/keyboard.h>
#include <86box/rom.h>
#include <86box/machine.h>
#include <86box/nvr.h>
#include <86box/chipset.h>
#include <86box/port_6x.h>
#include <86box/video.h>
@@ -668,6 +669,34 @@ machine_xt_amixt_init(const machine_t *model)
return ret;
}
int
machine_xt_tuliptc8_init(const machine_t *model)
{
int ret;
ret = bios_load_linear("roms/machines/tuliptc8/tulip-bios_xt_compact_2.bin",
0x000fc000, 16384, 0);
if (bios_only || !ret)
return ret;
device_add(&keyboard_xt_fe2010_device);
if (fdc_current[0] == FDC_INTERNAL)
device_add(&fdc_at_device);
machine_common_init(model);
pit_devs[0].set_out_func(pit_devs[0].data, 1, pit_refresh_timer_xt);
nmi_init();
standalone_gameport_type = &gameport_device;
device_add(&amstrad_megapc_nvr_device);
return ret;
}
// TODO
// Onboard EGA Graphics (NSI Logic EVC315-S on early boards STMicroelectronics EGA on later revisions)
// RTC

View File

@@ -2030,6 +2030,45 @@ const machine_t machines[] = {
.snd_device = NULL,
.net_device = NULL
},
{
.name = "[V20] Tulip PC Compact 2",
.internal_name = "tuliptc8",
.type = MACHINE_TYPE_8088,
.chipset = MACHINE_CHIPSET_DISCRETE,
.init = machine_xt_tuliptc8_init,
.p1_handler = NULL,
.gpio_handler = NULL,
.available_flag = MACHINE_AVAILABLE,
.gpio_acpi_handler = NULL,
.cpu = {
.package = CPU_PKG_8088,
.block = CPU_BLOCK(CPU_8088),
.min_bus = 0,
.max_bus = 0,
.min_voltage = 0,
.max_voltage = 0,
.min_multi = 0,
.max_multi = 0
},
.bus_flags = MACHINE_PC,
.flags = MACHINE_FLAGS_NONE,
.ram = {
.min = 64,
.max = 640,
.step = 64
},
.nvrmask = 63,
.kbc_device = &keyboard_xtclone_device,
.kbc_p1 = 0xff,
.gpio = 0xffffffff,
.gpio_acpi = 0xffffffff,
.device = NULL,
.fdc_device = NULL,
.sio_device = NULL,
.vid_device = NULL,
.snd_device = NULL,
.net_device = NULL
},
/* 8086 Machines */
{

View File

@@ -777,6 +777,18 @@ cga_standalone_init(UNUSED(const device_t *info))
}
}
switch(device_get_config_int("font")) {
case 0:
loadfont(FONT_IBM_MDA_437_PATH, 0);
break;
case 1:
loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0);
break;
case 4:
loadfont(FONT_TULIP_DGA_PATH, 0);
break;
}
return cga;
}
@@ -880,6 +892,22 @@ const device_config_t cga_config[] = {
},
.bios = { { 0 } }
},
{
.name = "font",
.description = "Font",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "US (CP 437)", .value = 0 },
{ .description = "IBM Nordic (CP 437-Nordic)", .value = 1 },
{ .description = "Tulip DGA", .value = 4 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "snow_enabled",
.description = "Snow emulation",

View File

@@ -555,6 +555,9 @@ hercules_init(UNUSED(const device_t *info))
case 3:
loadfont(FONT_KAMCL16_PATH, 0);
break;
case 4:
loadfont(FONT_TULIP_DGA_PATH, 0);
break;
}
timer_add(&dev->timer, hercules_poll, dev, 1);
@@ -649,17 +652,6 @@ static const device_config_t hercules_config[] = {
},
.bios = { { 0 } }
},
{
.name = "blend",
.description = "Blend",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 1,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{
.name = "font",
.description = "Font",
@@ -673,10 +665,22 @@ static const device_config_t hercules_config[] = {
{ .description = "IBM Nordic (CP 437-Nordic)", .value = 1 },
{ .description = "Czech Kamenicky (CP 895) #1", .value = 2 },
{ .description = "Czech Kamenicky (CP 895) #2", .value = 3 },
{ .description = "Tulip DGA", .value = 4 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "blend",
.description = "Blend",
.type = CONFIG_BINARY,
.default_string = NULL,
.default_int = 1,
.file_filter = NULL,
.spinner = { 0 },
.selection = { { 0 } },
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};

View File

@@ -992,6 +992,24 @@ incolor_init(UNUSED(const device_t *info))
dev->vram = (uint8_t *) malloc(0x40000); /* 4 planes of 64k */
switch(device_get_config_int("font")) {
case 0:
loadfont(FONT_IBM_MDA_437_PATH, 0);
break;
case 1:
loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0);
break;
case 2:
loadfont(FONT_KAM_PATH, 0);
break;
case 3:
loadfont(FONT_KAMCL16_PATH, 0);
break;
case 4:
loadfont(FONT_TULIP_DGA_PATH, 0);
break;
}
timer_add(&dev->timer, incolor_poll, dev, 1);
mem_mapping_add(&dev->mapping, 0xb0000, 0x08000,
@@ -1044,6 +1062,30 @@ speed_changed(void *priv)
recalc_timings(dev);
}
static const device_config_t incolor_config[] = {
// clang-format off
{
.name = "font",
.description = "Font",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "US (CP 437)", .value = 0 },
{ .description = "IBM Nordic (CP 437-Nordic)", .value = 1 },
{ .description = "Czech Kamenicky (CP 895) #1", .value = 2 },
{ .description = "Czech Kamenicky (CP 895) #2", .value = 3 },
{ .description = "Tulip DGA", .value = 4 },
{ .description = "" }
},
.bios = { { 0 } }
},
{ .name = "", .description = "", .type = CONFIG_END }
// clang-format on
};
const device_t incolor_device = {
.name = "Hercules InColor",
.internal_name = "incolor",
@@ -1055,5 +1097,5 @@ const device_t incolor_device = {
.available = NULL,
.speed_changed = speed_changed,
.force_redraw = NULL,
.config = NULL
.config = incolor_config
};

View File

@@ -629,6 +629,24 @@ herculesplus_init(UNUSED(const device_t *info))
dev->vram = (uint8_t *) malloc(0x10000); /* 64k VRAM */
dev->monitor_index = monitor_index_global;
switch(device_get_config_int("font")) {
case 0:
loadfont(FONT_IBM_MDA_437_PATH, 0);
break;
case 1:
loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0);
break;
case 2:
loadfont(FONT_KAM_PATH, 0);
break;
case 3:
loadfont(FONT_KAMCL16_PATH, 0);
break;
case 4:
loadfont(FONT_TULIP_DGA_PATH, 0);
break;
}
timer_add(&dev->timer, herculesplus_poll, dev, 1);
mem_mapping_add(&dev->mapping, 0xb0000, 0x08000,
@@ -715,6 +733,24 @@ static const device_config_t herculesplus_config[] = {
},
.bios = { { 0 } }
},
{
.name = "font",
.description = "Font",
.type = CONFIG_SELECTION,
.default_string = NULL,
.default_int = 0,
.file_filter = NULL,
.spinner = { 0 },
.selection = {
{ .description = "US (CP 437)", .value = 0 },
{ .description = "IBM Nordic (CP 437-Nordic)", .value = 1 },
{ .description = "Czech Kamenicky (CP 895) #1", .value = 2 },
{ .description = "Czech Kamenicky (CP 895) #2", .value = 3 },
{ .description = "Tulip DGA", .value = 4 },
{ .description = "" }
},
.bios = { { 0 } }
},
{
.name = "blend",
.description = "Blend",

View File

@@ -337,13 +337,15 @@ mda_standalone_init(UNUSED(const device_t *info))
case 1:
loadfont(FONT_IBM_MDA_437_NORDIC_PATH, 0);
break;
case 2:
loadfont(FONT_KAM_PATH, 0);
break;
case 3:
loadfont(FONT_KAMCL16_PATH, 0);
break;
case 4:
loadfont(FONT_TULIP_DGA_PATH, 0);
break;
}
mem_mapping_add(&mda->mapping, 0xb0000, 0x08000,
@@ -419,6 +421,7 @@ static const device_config_t mda_config[] = {
{ .description = "IBM Nordic (CP 437-Nordic)", .value = 1 },
{ .description = "Czech Kamenicky (CP 895) #1", .value = 2 },
{ .description = "Czech Kamenicky (CP 895) #2", .value = 3 },
{ .description = "Tulip DGA", .value = 4 },
{ .description = "" }
},
.bios = { { 0 } }