diff --git a/src/device/keyboard_xt.c b/src/device/keyboard_xt.c index d3db6a467..2d0ef9f5e 100644 --- a/src/device/keyboard_xt.c +++ b/src/device/keyboard_xt.c @@ -65,6 +65,7 @@ #define KBD_TYPE_VTECH 7 #define KBD_TYPE_OLIVETTI 8 #define KBD_TYPE_ZENITH 9 +#define KBD_TYPE_PRAVETZ 10 typedef struct { int want_irq; @@ -73,7 +74,7 @@ typedef struct { uint8_t pa, pb, pd; uint8_t key_waiting; - uint8_t type; + uint8_t type, pravetz_flags; pc_timer_t send_delay_timer; } xtkbd_t; @@ -513,6 +514,7 @@ static void kbd_write(uint16_t port, uint8_t val, void *priv) { xtkbd_t *kbd = (xtkbd_t *) priv; + uint8_t bit, set; switch (port) { case 0x61: /* Keyboard Control Register (aka Port B) */ @@ -527,7 +529,8 @@ kbd_write(uint16_t port, uint8_t val, void *priv) timer_process(); - if (((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82)) && (cassette != NULL)) + if (((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) && + (cassette != NULL)) pc_cas_set_motor(cassette, (kbd->pb & 0x08) == 0); speaker_update(); @@ -546,16 +549,25 @@ kbd_write(uint16_t port, uint8_t val, void *priv) } #ifdef ENABLE_KEYBOARD_XT_LOG - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82)) + if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) kbd_log("Cassette motor is %s\n", !(val & 0x08) ? "ON" : "OFF"); #endif break; #ifdef ENABLE_KEYBOARD_XT_LOG case 0x62: /* Switch Register (aka Port C) */ - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82)) + if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) kbd_log("Cassette IN is %i\n", !!(val & 0x10)); break; #endif + + case 0xc0 ... 0xcf: /* Pravetz Flags */ + kbd_log("Port %02X out: %02X\n", port, val); + if (kbd->type == KBD_TYPE_PRAVETZ) { + bit = (port >> 1) & 0x07; + set = (port & 0x01) << bit; + kbd->pravetz_flags = (kbd->pravetz_flags & ~(1 << bit)) | set; + } + break; } } @@ -567,8 +579,8 @@ kbd_read(uint16_t port, void *priv) switch (port) { case 0x60: /* Keyboard Data Register (aka Port A) */ - if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_ZENITH))) { - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82)) + if ((kbd->pb & 0x80) && ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_ZENITH))) { + if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) ret = (kbd->pd & ~0x02) | (hasfpu ? 0x02 : 0x00); else if ((kbd->type == KBD_TYPE_XT82) || (kbd->type == KBD_TYPE_XT86)) ret = 0xff; /* According to Ruud on the PCem forum, this is supposed to return 0xFF on the XT. */ @@ -600,7 +612,7 @@ 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_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) { if (kbd->pb & 0x04) /* PB2 */ switch (mem_size + isa_mem_size) { case 64: @@ -640,7 +652,7 @@ kbd_read(uint16_t port, void *priv) /* This is needed to avoid error 131 (cassette error). This is serial read: bit 5 = clock, bit 4 = data, cassette header is 256 x 0xff. */ - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82)) { + if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || (kbd->type == KBD_TYPE_PRAVETZ)) { if (cassette == NULL) ret |= (ppispeakon ? 0x10 : 0); else @@ -657,6 +669,12 @@ kbd_read(uint16_t port, void *priv) || (kbd->type == KBD_TYPE_TOSHIBA)) ret = kbd->pd; break; + + case 0xc0: /* Pravetz Flags */ + if (kbd->type == KBD_TYPE_PRAVETZ) + ret = kbd->pravetz_flags; + kbd_log("Port %02X in : %02X\n", port, ret); + break; } return (ret); @@ -671,6 +689,7 @@ kbd_reset(void *priv) kbd->blocked = 0; kbd->pa = 0x00; kbd->pb = 0x00; + kbd->pravetz_flags = 0x00; keyboard_scan = 1; @@ -697,16 +716,20 @@ kbd_init(const device_t *info) keyboard_send = kbd_adddata_ex; kbd_reset(kbd); kbd->type = info->local; + if (kbd->type == KBD_TYPE_PRAVETZ) { + pclog("Pravetz keyboard!\n"); + io_sethandler(0x00c0, 16, + kbd_read, NULL, NULL, kbd_write, NULL, NULL, kbd); + } key_queue_start = key_queue_end = 0; video_reset(gfxcard); - if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) - || (kbd->type == KBD_TYPE_XT82) || (kbd->type <= KBD_TYPE_XT86) - || (kbd->type == KBD_TYPE_COMPAQ) - || (kbd->type == KBD_TYPE_TOSHIBA) - || (kbd->type == KBD_TYPE_OLIVETTI)) { + if ((kbd->type == KBD_TYPE_PC81) || (kbd->type == KBD_TYPE_PC82) || + (kbd->type == KBD_TYPE_PRAVETZ) || (kbd->type == KBD_TYPE_XT82) || + (kbd->type <= KBD_TYPE_XT86) || (kbd->type == KBD_TYPE_COMPAQ) || + (kbd->type == KBD_TYPE_TOSHIBA) || (kbd->type == KBD_TYPE_OLIVETTI)) { /* DIP switch readout: bit set = OFF, clear = ON. */ if (kbd->type == KBD_TYPE_OLIVETTI) @@ -894,6 +917,20 @@ const device_t keyboard_pc82_device = { .config = NULL }; +const device_t keyboard_pravetz_device = { + .name = "Pravetz Keyboard", + .internal_name = "keyboard_pravetz", + .flags = 0, + .local = KBD_TYPE_PRAVETZ, + .init = kbd_init, + .close = kbd_close, + .reset = kbd_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_xt_device = { .name = "XT (1982) Keyboard", .internal_name = "keyboard_xt", diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index b4252324a..b310e1553 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -146,6 +146,7 @@ extern int mouse_scan; #ifdef EMU_DEVICE_H extern const device_t keyboard_pc_device; extern const device_t keyboard_pc82_device; +extern const device_t keyboard_pravetz_device; extern const device_t keyboard_xt_device; extern const device_t keyboard_xt86_device; extern const device_t keyboard_xt_compaq_device; diff --git a/src/include/86box/vid_cga.h b/src/include/86box/vid_cga.h index 7f880fc1c..a8cef77fe 100644 --- a/src/include/86box/vid_cga.h +++ b/src/include/86box/vid_cga.h @@ -67,7 +67,9 @@ void cga_poll(void *p); #ifdef EMU_DEVICE_H extern const device_config_t cga_config[]; + extern const device_t cga_device; +extern const device_t cga_pravetz_device; #endif #endif /*VIDEO_CGA_H*/ diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 17229238f..fa7059c88 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -18,6 +18,7 @@ #include <86box/rom.h> #include <86box/machine.h> #include <86box/chipset.h> +#include <86box/port_6x.h> static void machine_xt_common_init(const machine_t *model) @@ -331,15 +332,33 @@ machine_xt_iskra3104_init(const machine_t *model) int machine_xt_pravetz16_imko4_init(const machine_t *model) { - int ret; - + int ret; + ret = bios_load_linear("roms/machines/pravetz16/BIOS_IMKO4_FE00.bin", - 0x000fe000, 8192, 0); + 0x000fe000, 65536, 0); + if (ret) { + ret = bios_load_aux_linear("roms/machines/pravetz16/IMKO4-D34_SGS-M2764ADIP28.BIN", + 0x000f4000, 8192, 0); + + if (ret) { + bios_load_aux_linear("roms/machines/pravetz16/1.bin", + 0x000f6000, 8192, 0); + + bios_load_aux_linear("roms/machines/pravetz16/2.bin", + 0x000fa000, 8192, 0); + + bios_load_aux_linear("roms/machines/pravetz16/5.bin", + 0x000f8000, 8192, 0); + + bios_load_aux_linear("roms/machines/pravetz16/6.bin", + 0x000fc000, 8192, 0); + } + } if (bios_only || !ret) return ret; - device_add(&keyboard_at_device); + device_add(&keyboard_pravetz_device); machine_xt_common_init(model); diff --git a/src/video/vid_cga.c b/src/video/vid_cga.c index ee3987fe0..b68f093e1 100644 --- a/src/video/vid_cga.c +++ b/src/video/vid_cga.c @@ -117,6 +117,22 @@ cga_in(uint16_t addr, void *p) return ret; } +void +cga_pravetz_out(uint16_t addr, uint8_t val, void *p) +{ + cga_t *cga = (cga_t *) p; + + cga->fontbase = (((unsigned int) val) << 8); +} + +uint8_t +cga_pravetz_in(uint16_t addr, void *p) +{ + cga_t *cga = (cga_t *) p; + + return (cga->fontbase >> 8); +} + void cga_waitstates(void *p) { @@ -524,6 +540,21 @@ cga_standalone_init(const device_t *info) return cga; } +void * +cga_pravetz_init(const device_t *info) +{ + cga_t *cga = cga_standalone_init(info); + + loadfont("roms/video/cga/CGA - PRAVETZ.BIN", 10); + + io_removehandler(0x03dd, 0x0001, cga_in, NULL, NULL, cga_out, NULL, NULL, cga); + io_sethandler(0x03dd, 0x0001, cga_pravetz_in, NULL, NULL, cga_pravetz_out, NULL, NULL, cga); + + cga->fontbase = 0x0300; + + return cga; +} + void cga_close(void *p) { @@ -637,3 +668,17 @@ const device_t cga_device = { .force_redraw = NULL, .config = cga_config }; + +const device_t cga_pravetz_device = { + .name = "Pravetz VDC-2", + .internal_name = "cga_pravetz", + .flags = DEVICE_ISA, + .local = 0, + .init = cga_pravetz_init, + .close = cga_close, + .reset = NULL, + { .available = NULL }, + .speed_changed = cga_speed_changed, + .force_redraw = NULL, + .config = cga_config +}; diff --git a/src/video/vid_table.c b/src/video/vid_table.c index ed34e7914..79189cdc0 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -127,6 +127,7 @@ video_cards[] = { { ¶dise_wd90c30_device }, { &colorplus_device }, { &pgc_device }, + { &cga_pravetz_device }, { &radius_svga_multiview_isa_device }, { &realtek_rtg3106_device }, { &s3_diamond_stealth_vram_isa_device }, diff --git a/src/video/video.c b/src/video/video.c index eb4997574..9b07b9e1f 100644 --- a/src/video/video.c +++ b/src/video/video.c @@ -1083,6 +1083,13 @@ loadfont_common(FILE *f, int format) for (c = 0; c < 256; c++) (void) !fread(&fontdat12x18[c][0], 1, 36, f); break; + + case 10: /* Pravetz */ + for (c = 0; c < 1024; c++) /* Allow up to 1024 chars */ + for (d = 0; d < 8; d++) + fontdat[c][d] = fgetc(f) & 0xff; + break; + } (void) fclose(f);