Skip to content

Commit 512c04c

Browse files
authored
Add OKI if386AX emulation (#7)
* add a machine oki if386ax * if386AX: still in debug * Revert "if386AX: still in debug" This reverts commit ade401b. * if386ax: added I/O 6xh * if386ax: remove comment * formatting, sorting, change filename * change mono color palette
1 parent c5efce6 commit 512c04c

File tree

6 files changed

+211
-23
lines changed

6 files changed

+211
-23
lines changed

src/include/86box/machine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,7 @@ extern int machine_at_adi386sx_init(const machine_t *);
483483
extern int machine_at_cmdsl386sx16_init(const machine_t *);
484484
extern int machine_at_cmdsl386sx25_init(const machine_t *);
485485
extern int machine_at_dataexpert386sx_init(const machine_t *);
486+
extern int machine_at_if386sx_init(const machine_t *);
486487
extern int machine_at_spc6033p_init(const machine_t *);
487488
extern int machine_at_wd76c10_init(const machine_t *);
488489
extern int machine_at_arb1374_init(const machine_t *);

src/include/86box/video.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,9 @@ extern const device_t millennium_ii_device;
456456
extern const device_t productiva_g100_device;
457457
#endif /* USE_G100 */
458458

459+
/* JEGA */
460+
extern const device_t if386jega_device;
461+
459462
/* Oak OTI-0x7 */
460463
extern const device_t oti037c_device;
461464
extern const device_t oti067_device;

src/machine/m_at_286_386sx.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,31 @@ machine_at_cmdsl386sx16_init(const machine_t *model)
641641
return ret;
642642
}
643643

644+
int
645+
machine_at_if386sx_init(const machine_t *model)
646+
{
647+
int ret;
648+
649+
ret = bios_load_interleaved("roms/machines/if386sx/OKI_IF386SX_odd.bin",
650+
"roms/machines/if386sx/OKI_IF386SX_even.bin",
651+
0x000f0000, 65536, 0);
652+
653+
if (bios_only || !ret)
654+
return ret;
655+
656+
machine_at_common_init(model);
657+
device_add(&keyboard_at_device);
658+
659+
device_add(&neat_device);
660+
661+
if (gfxcard[0] == VID_INTERNAL)
662+
device_add(&if386jega_device);
663+
if (fdc_current[0] == FDC_INTERNAL)
664+
device_add(&fdc_at_device);
665+
666+
return ret;
667+
}
668+
644669
static void
645670
machine_at_scamp_common_init(const machine_t *model, int is_ps2)
646671
{

src/machine/machine_table.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4746,6 +4746,44 @@ const machine_t machines[] = {
47464746
.snd_device = NULL,
47474747
.net_device = NULL
47484748
},
4749+
{ .name = "[NEAT] OKI if386AX30L",
4750+
.internal_name = "if386sx",
4751+
.type = MACHINE_TYPE_386SX,
4752+
.chipset = MACHINE_CHIPSET_NEAT,
4753+
.init = machine_at_if386sx_init,
4754+
.p1_handler = NULL,
4755+
.gpio_handler = NULL,
4756+
.available_flag = MACHINE_AVAILABLE,
4757+
.gpio_acpi_handler = NULL,
4758+
.cpu = {
4759+
.package = CPU_PKG_386SX,
4760+
.block = CPU_BLOCK_NONE,
4761+
.min_bus = 0,
4762+
.max_bus = 0,
4763+
.min_voltage = 0,
4764+
.max_voltage = 0,
4765+
.min_multi = 0,
4766+
.max_multi = 0
4767+
},
4768+
.bus_flags = MACHINE_AT,
4769+
.flags = MACHINE_VIDEO,
4770+
.ram = {
4771+
.min = 1024,
4772+
.max = 4096,
4773+
.step = 1024
4774+
},
4775+
.nvrmask = 127,
4776+
.kbc_device = NULL,
4777+
.kbc_p1 = 0xff,
4778+
.gpio = 0xffffffff,
4779+
.gpio_acpi = 0xffffffff,
4780+
.device = NULL,
4781+
.fdc_device = NULL,
4782+
.sio_device = NULL,
4783+
.vid_device = NULL,
4784+
.snd_device = NULL,
4785+
.net_device = NULL
4786+
},
47494787
/* Has IBM AT KBC firmware. */
47504788
{
47514789
.name = "[OPTi 291] DTK PPM-3333P",

src/video/vid_ega.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ void ega_doblit(int wx, int wy, ega_t *ega);
4747

4848
static video_timings_t timing_ega = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
4949
static uint8_t ega_rotate[8][256];
50-
static int active = 0;
51-
static uint32_t pallook16[256];
52-
static uint32_t pallook64[256];
50+
static int active = 0;
51+
uint32_t pallook16[256];
52+
uint32_t pallook64[256];
5353
static int ega_type = EGA_TYPE_IBM;
5454
static int old_overscan_color = 0;
5555

src/video/vid_jega.c

Lines changed: 141 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#define RINVALID_INDEX 0x30
6161

6262
#define JEGA_PATH_BIOS "roms/video/jega/JEGABIOS.BIN"
63+
#define IF386_PATH_VBIOS "roms/video/jega/OKI_IF386SX_VBIOS.bin"
6364
#define JEGA_PATH_FONTDBCS "roms/video/jega/JPNZN16X.FNT"
6465
#define SBCS19_FILESIZE (256 * 19 * 2) /* 8 x 19 x 256 chr x 2 pages */
6566
#define DBCS16_CHARS 0x2c10
@@ -137,7 +138,8 @@ typedef struct {
137138
uint16_t end;
138139
} fontx_tbl;
139140

140-
static uint32_t pallook64[256];
141+
extern uint32_t pallook16[256];
142+
extern uint32_t pallook64[256];
141143
static bool is_SJIS_1(uint8_t chr) { return (chr >= 0x81 && chr <= 0x9f) || (chr >= 0xe0 && chr <= 0xfc); }
142144
static bool is_SJIS_2(uint8_t chr) { return (chr >= 0x40 && chr <= 0x7e) || (chr >= 0x80 && chr <= 0xfc); }
143145

@@ -615,30 +617,35 @@ LoadFontxFile(const char *fn, void *priv)
615617
return 0;
616618
}
617619

618-
static void *
619-
jega_init(const device_t *info)
620+
static void
621+
jega_commoninit(void *priv)
620622
{
621-
jega_t *jega = calloc(1, sizeof(jega_t));
622-
623-
rom_init(&jega->bios_rom, JEGA_PATH_BIOS, 0xc0000, 0x8000, 0x7fff, 0, 0);
624-
memset(&jega->jfont_dbcs_16, 0, DBCS16_FILESIZE);
625-
LoadFontxFile(JEGA_PATH_FONTDBCS, jega);
626-
623+
jega_t *jega = (jega_t *) priv;
627624
for (int c = 0; c < 256; c++) {
628625
pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa);
629626
pallook64[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55);
630627
}
631-
632628
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ega);
633629
jega->pallook = pallook64;
634630
ega_init(&jega->ega, 9, 0);
635631
ega_set_type(&jega->ega, EGA_SUPEREGA);
636632
jega->ega.priv_parent = jega;
637633
mem_mapping_add(&jega->ega.mapping, 0xa0000, 0x20000, ega_read, NULL, NULL, ega_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, &jega->ega);
634+
/* I/O 3DD and 3DE are used by Oki if386 */
635+
io_sethandler(0x03b0, 0x002c, jega_in, NULL, NULL, jega_out, NULL, NULL, jega);
636+
jega->regs[RMOD1] = 0x48;
637+
}
638638

639-
io_sethandler(0x03b0, 0x0030, jega_in, NULL, NULL, jega_out, NULL, NULL, jega);
639+
static void *
640+
jega_standalone_init(const device_t *info)
641+
{
642+
jega_t *jega = calloc(1, sizeof(jega_t));
640643

641-
jega->regs[RMOD1] = 0x48;
644+
rom_init(&jega->bios_rom, JEGA_PATH_BIOS, 0xc0000, 0x8000, 0x7fff, 0, 0);
645+
memset(&jega->jfont_dbcs_16, 0, DBCS16_FILESIZE);
646+
LoadFontxFile(JEGA_PATH_FONTDBCS, jega);
647+
648+
jega_commoninit(jega);
642649

643650
return jega;
644651
}
@@ -665,10 +672,10 @@ jega_close(void *priv)
665672
fprintf(f, "Regs %02X: %4X\n", i, jega->regs[i]);
666673
for (int i = 0; i < 32; i++)
667674
fprintf(f, "Attr %02X: %4X\n", i, jega->attrregs[i]);
668-
for (int i = 0; i < 16; i++)
669-
fprintf(f, "JEGAPal %02X: %4X\n", i, jega->egapal[i]);
670-
for (int i = 0; i < 16; i++)
671-
fprintf(f, "EGAPal %02X: %4X\n", i, jega->ega.egapal[i]);
675+
for (int i = 0; i < 16; i++)
676+
fprintf(f, "JEGAPal %02X: %4X\n", i, jega->egapal[i]);
677+
for (int i = 0; i < 16; i++)
678+
fprintf(f, "EGAPal %02X: %4X\n", i, jega->ega.egapal[i]);
672679
for (int i = 0; i < 64; i++)
673680
fprintf(f, "RealPal %02X: %4X\n", i, jega->pallook[i]);
674681
fclose(f);
@@ -683,7 +690,7 @@ jega_close(void *priv)
683690
fwrite(&ram[0x0], 0x500, 1, f);
684691
fclose(f);
685692
}
686-
// jega_log("jeclosed %04X:%04X DS %04X\n", cs >> 4, cpu_state.pc, DS);
693+
pclog("jeclosed %04X:%04X DS %04X\n", cs >> 4, cpu_state.pc, DS);
687694
#endif
688695
if (jega->ega.eeprom)
689696
free(jega->ega.eeprom);
@@ -706,7 +713,7 @@ jega_speed_changed(void *priv)
706713
}
707714

708715
static int
709-
jega_available(void)
716+
jega_standalone_available(void)
710717
{
711718
return (rom_present(JEGA_PATH_BIOS) && rom_present(JEGA_PATH_FONTDBCS));
712719
}
@@ -716,10 +723,124 @@ const device_t jega_device = {
716723
.internal_name = "jega",
717724
.flags = DEVICE_ISA,
718725
.local = 0,
719-
.init = jega_init,
726+
.init = jega_standalone_init,
727+
.close = jega_close,
728+
.reset = NULL,
729+
.available = jega_standalone_available,
730+
.speed_changed = jega_speed_changed,
731+
.force_redraw = NULL,
732+
.config = NULL
733+
};
734+
735+
static uint8_t p65idx = 0;
736+
static uint8_t p3de_idx = 0;
737+
static uint8_t p65[6];
738+
static uint8_t p3de[0x30];
739+
740+
741+
static uint8_t
742+
if386_p6x_read(uint16_t port, void *priv)
743+
{
744+
uint8_t ret = INVALIDACCESS8;
745+
if (port == 0x63) {
746+
ret = p65idx;
747+
} else if (port == 0x65) {
748+
ret = p65[p65idx];
749+
}
750+
// pclog("p%x_r: [%04x:%04x] [%02x]%02x\n", port, cs >> 4, cpu_state.pc , p65idx, ret);
751+
return ret;
752+
}
753+
754+
/*
755+
OKi if386AX/SX Power management and Miscellaneous
756+
I/O 63h: Index 0-5, I/O 65h: Data
757+
Index 2:
758+
Bit 3: Caps Lock enabled
759+
Bit 2: Num Lock enabled
760+
Bit 1: Scrl Lock enabled
761+
Bit 0: Kana Lock enabled
762+
Index 3
763+
Bit 2: External monitor output enabled
764+
Bit 1: Floppy drive 1 active
765+
Bit 0: Floppy drive 0 active
766+
Index 5
767+
Bit 8: ? (1=Disabled, 0=Enabled)
768+
Bit 7: Screen Off? (enabled by Ctrl + Alt + [1] and disabled by any key)
769+
Bit 4: Shutdown? (caused by POST rebooting and POWER OFF command in DOS 3.21)
770+
Bit 3: ?
771+
*/
772+
static void
773+
if386_p6x_write(uint16_t port, uint8_t val, void *priv)
774+
{
775+
jega_t *jega = (jega_t *) priv;
776+
// pclog("p%x_w: [%04x:%04x] val=%02x\n", port, cs >> 4, cpu_state.pc, val);
777+
if (port == 0x63 && val < 6)
778+
p65idx = val;
779+
if (port == 0x65) {
780+
// pclog("p65_w: [%04x:%04x] idx=%02x, val=%02x\n", cs >> 4, cpu_state.pc, p65idx, val);
781+
p65[p65idx] = val;
782+
if (p65idx == 0x03) {
783+
if (val & 0x04) { /* Color monitor */
784+
for (int c = 0; c < 256; c++) {
785+
pallook64[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa);
786+
pallook64[c] += makecol32(((c >> 5) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 3) & 1) * 0x55);
787+
pallook16[c] = makecol32(((c >> 2) & 1) * 0xaa, ((c >> 1) & 1) * 0xaa, (c & 1) * 0xaa);
788+
pallook16[c] += makecol32(((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55, ((c >> 4) & 1) * 0x55);
789+
if ((c & 0x17) == 6)
790+
pallook16[c] = makecol32(0xaa, 0x55, 0);
791+
}
792+
} else { /* Monochrome LCD */
793+
for (int c = 0; c < 256; c++) {
794+
int cval = 0;
795+
if (c & 0x0f)
796+
cval = ((c & 0x0e) * 0x10) + 0x1f;
797+
pallook64[c] = makecol32(cval, cval, cval);
798+
pallook16[c] = makecol32(cval, cval, cval);
799+
}
800+
}
801+
jega_recalctimings(jega);
802+
} else if (p65idx == 0x05) {
803+
if (val & 0x10) { /* Power off (instead this call hardware reset here) */
804+
resetx86();
805+
}
806+
}
807+
}
808+
return;
809+
}
810+
811+
static void *
812+
if386jega_init(const device_t *info)
813+
{
814+
jega_t *jega = calloc(1, sizeof(jega_t));
815+
816+
rom_init(&jega->bios_rom, IF386_PATH_VBIOS, 0xc0000, 0x8000, 0x7fff, 0, 0);
817+
memset(&jega->jfont_dbcs_16, 0, DBCS16_FILESIZE);
818+
LoadFontxFile(JEGA_PATH_FONTDBCS, jega);
819+
820+
jega_commoninit(jega);
821+
822+
io_sethandler(0x0063, 1, if386_p6x_read, NULL, NULL, if386_p6x_write, NULL, NULL, jega);
823+
io_sethandler(0x0065, 1, if386_p6x_read, NULL, NULL, if386_p6x_write, NULL, NULL, jega);
824+
// io_sethandler(0x03dd, 2, if386_p6x_read, NULL, NULL, if386_p6x_write, NULL, NULL, jega);
825+
826+
return jega;
827+
}
828+
829+
static int
830+
if386jega_available(void)
831+
{
832+
return (rom_present(IF386_PATH_VBIOS) && rom_present(JEGA_PATH_FONTDBCS));
833+
}
834+
835+
const device_t if386jega_device = {
836+
.name = "JEGA (if386AX)",
837+
.internal_name = "if386jega",
838+
.flags = DEVICE_ISA,
839+
.local = 0,
840+
.init = if386jega_init,
720841
.close = jega_close,
721842
.reset = NULL,
722-
.available = jega_available,
843+
.available = if386jega_available,
723844
.speed_changed = jega_speed_changed,
724845
.force_redraw = NULL,
725846
.config = NULL

0 commit comments

Comments
 (0)