Fixed the PGC, IM204 and added more fixes from John Elliott.

Started cleaning up some of the mess in the video layer.
This commit is contained in:
waltje
2019-03-03 21:35:52 -05:00
parent a26e0094d0
commit ba7e2e2d69
20 changed files with 873 additions and 672 deletions

View File

@@ -8,7 +8,7 @@
*
* ATI 18800 emulation (VGA Edge-16)
*
* Version: @(#)vid_ati18800.c 1.0.10 2019/02/10
* Version: @(#)vid_ati18800.c 1.0.11 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -49,7 +49,7 @@
#include "video.h"
#include "vid_svga.h"
#include "vid_svga_render.h"
#include "vid_ati_eeprom.h"
#include "vid_ati.h"
# define BIOS_ROM_PATH_WONDER L"video/ati/ati18800/vga_wonder_v3-1.02.bin"

View File

@@ -8,7 +8,7 @@
*
* ATI 28800 emulation (VGA Charger and Korean VGA)
*
* Version: @(#)vid_ati28800.c 1.0.16 2019/02/10
* Version: @(#)vid_ati28800.c 1.0.18 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -47,11 +47,12 @@
#include "../../mem.h"
#include "../../rom.h"
#include "../../device.h"
#include "../../plat.h"
#include "video.h"
#include "vid_svga.h"
#include "vid_svga_render.h"
#include "vid_sc1502x_ramdac.h"
#include "vid_ati_eeprom.h"
#include "vid_ati.h"
enum {
@@ -220,7 +221,7 @@ ati28800k_out(uint16_t port, uint8_t val, void *priv)
dev->in_get_korean_font_kind_set = 0;
if (dev->get_korean_font_enabled) {
if ((dev->get_korean_font_base & 0x7F) > 0x20 && (dev->get_korean_font_base & 0x7F) < 0x7F)
fontdatksc5601_user[(dev->get_korean_font_kind & 4) * 24 + (dev->get_korean_font_base & 0x7F) - 0x20].chr[dev->get_korean_font_index] = val;
fontdatk_user[(dev->get_korean_font_kind & 4) * 24 + (dev->get_korean_font_base & 0x7F) - 0x20].chr[dev->get_korean_font_index] = val;
dev->get_korean_font_index++;
dev->get_korean_font_index &= 0x1F;
} else {
@@ -337,12 +338,12 @@ ati28800k_in(uint16_t port, void *priv)
if (dev->get_korean_font_enabled) {
switch(dev->get_korean_font_kind >> 8) {
case 4: /* ROM font */
ret = fontdatksc5601[dev->get_korean_font_base].chr[dev->get_korean_font_index++];
ret = fontdatk[dev->get_korean_font_base].chr[dev->get_korean_font_index++];
break;
case 2: /* User defined font */
if ((dev->get_korean_font_base & 0x7F) > 0x20 && (dev->get_korean_font_base & 0x7F) < 0x7F)
ret = fontdatksc5601_user[(dev->get_korean_font_kind & 4) * 24 + (dev->get_korean_font_base & 0x7F) - 0x20].chr[dev->get_korean_font_index];
ret = fontdatk_user[(dev->get_korean_font_kind & 4) * 24 + (dev->get_korean_font_base & 0x7F) - 0x20].chr[dev->get_korean_font_index];
else
ret = 0xff;
dev->get_korean_font_index++;
@@ -443,6 +444,44 @@ ati28800k_recalctimings(svga_t *svga)
}
/*
* Also used by the Korean ET4000AX.
*
* This will eventually need the 'svga' pointer to store
* the font data in to, which is global data right now.
*/
int
ati28800k_load_font(svga_t *svga, const wchar_t *fn)
{
FILE *fp;
int c, d;
fp = plat_fopen(rom_path(fn), L"rb");
if (fp == NULL) {
ERRLOG("ATI28800K: cannot load font '%ls'\n", fn);
return(0);
}
if (fontdatk == NULL)
fontdatk = (dbcs_font_t *)mem_alloc(16384 * sizeof(dbcs_font_t));
if (fontdatk_user == NULL) {
c = 192 * sizeof(dbcs_font_t);
fontdatk_user = (dbcs_font_t *)mem_alloc(c);
memset(fontdatk_user, 0x00, c);
}
for (c = 0; c < 16384; c++) {
for (d = 0; d < 32; d++)
fontdatk[c].chr[d] = fgetc(fp);
}
(void)fclose(fp);
return(1);
}
static void *
ati28800_init(const device_t *info)
{
@@ -494,8 +533,6 @@ ati28800_init(const device_t *info)
dev->in_get_korean_font_kind_set = 0;
dev->ksc5601_mode_enabled = 0;
video_load_font(FONT_ATIKOR_PATH, 6);
rom_init(&dev->bios_rom, BIOS_ATIKOR_PATH,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
ati_eeprom_load(&dev->eeprom, L"atikorvga.nvr", 0);
@@ -533,6 +570,14 @@ ati28800_init(const device_t *info)
dev->svga.miscout = 1;
if (info->local == VID_ATIKOREANVGA) {
if (! ati28800k_load_font(&dev->svga, FONT_ATIKOR_PATH)) {
svga_close(&dev->svga);
free(dev);
return(NULL);
}
}
video_inform(VID_TYPE_SPEC,
(const video_timings_t *)info->vid_timing);

View File

@@ -8,13 +8,13 @@
*
* Emulation of the EEPROM on select ATI cards.
*
* Version: @(#)vid_ati_eeprom.c 1.0.4 2018/09/04
* Version: @(#)vid_ati_eeprom.c 1.0.5 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
@@ -44,215 +44,208 @@
#include "../../mem.h"
#include "../../nvr.h"
#include "../../plat.h"
#include "vid_ati_eeprom.h"
#include "vid_ati.h"
enum
{
EEPROM_IDLE,
EEPROM_WAIT,
EEPROM_OPCODE,
EEPROM_INPUT,
EEPROM_OUTPUT
enum {
EEPROM_IDLE,
EEPROM_WAIT,
EEPROM_OPCODE,
EEPROM_INPUT,
EEPROM_OUTPUT
};
enum
{
EEPROM_OP_EW = 4,
EEPROM_OP_WRITE = 5,
EEPROM_OP_READ = 6,
EEPROM_OP_ERASE = 7,
enum {
EEPROM_OP_EW = 4,
EEPROM_OP_WRITE = 5,
EEPROM_OP_READ = 6,
EEPROM_OP_ERASE = 7,
EEPROM_OP_WRALMAIN = -1
EEPROM_OP_WRALMAIN = -1
};
enum
{
EEPROM_OP_EWDS = 0,
EEPROM_OP_WRAL = 1,
EEPROM_OP_ERAL = 2,
EEPROM_OP_EWEN = 3
enum {
EEPROM_OP_EWDS = 0,
EEPROM_OP_WRAL = 1,
EEPROM_OP_ERAL = 2,
EEPROM_OP_EWEN = 3
};
void ati_eeprom_load(ati_eeprom_t *eeprom, wchar_t *fn, int type)
void
ati_eeprom_load(ati_eeprom_t *dev, wchar_t *fn, int type)
{
FILE *f;
FILE *fp;
eeprom->type = type;
memset(eeprom->data, 0, eeprom->type ? 512 : 128);
dev->type = type;
memset(dev->data, 0, dev->type ? 512 : 128);
wcscpy(eeprom->fn, fn);
f = plat_fopen(nvr_path(eeprom->fn), L"rb");
if (f != NULL)
{
(void)fread(eeprom->data, 1, eeprom->type ? 512 : 128, f);
fclose(f);
}
wcscpy(dev->fn, fn);
fp = plat_fopen(nvr_path(dev->fn), L"rb");
if (fp != NULL) {
(void)fread(dev->data, 1, dev->type ? 512 : 128, fp);
fclose(fp);
}
}
void ati_eeprom_save(ati_eeprom_t *eeprom)
{
FILE *f = plat_fopen(nvr_path(eeprom->fn), L"wb");
if (f != NULL) {
(void)fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f);
fclose(f);
void
ati_eeprom_save(ati_eeprom_t *dev)
{
FILE *fp = plat_fopen(nvr_path(dev->fn), L"wb");
if (fp != NULL) {
(void)fwrite(dev->data, 1, dev->type ? 512 : 128, fp);
fclose(fp);
}
}
void
ati_eeprom_write(ati_eeprom_t *dev, int ena, int clk, int dat)
{
int c;
if (! ena)
dev->out = 1;
if (clk && !dev->oldclk) {
if (ena && !dev->oldena) {
dev->state = EEPROM_WAIT;
dev->opcode = 0;
dev->count = 3;
dev->out = 1;
} else if (ena) {
switch (dev->state) {
case EEPROM_WAIT:
if (! dat)
break;
dev->state = EEPROM_OPCODE;
/*FALLTHROUGH*/
case EEPROM_OPCODE:
dev->opcode = (dev->opcode << 1) | (dat ? 1 : 0);
dev->count--;
if (! dev->count) {
switch (dev->opcode) {
case EEPROM_OP_WRITE:
dev->count = dev->type ? 24 : 22;
dev->state = EEPROM_INPUT;
dev->dat = 0;
break;
case EEPROM_OP_READ:
dev->count = dev->type ? 8 : 6;
dev->state = EEPROM_INPUT;
dev->dat = 0;
break;
case EEPROM_OP_EW:
dev->count = 2;
dev->state = EEPROM_INPUT;
dev->dat = 0;
break;
case EEPROM_OP_ERASE:
dev->count = dev->type ? 8 : 6;
dev->state = EEPROM_INPUT;
dev->dat = 0;
break;
}
}
break;
case EEPROM_INPUT:
dev->dat = (dev->dat << 1) | (dat ? 1 : 0);
dev->count--;
if (! dev->count) {
switch (dev->opcode) {
case EEPROM_OP_WRITE:
if (! dev->wp) {
dev->data[(dev->dat >> 16) & (dev->type ? 255 : 63)] = dev->dat & 0xffff;
ati_eeprom_save(dev);
}
dev->state = EEPROM_IDLE;
dev->out = 1;
break;
case EEPROM_OP_READ:
dev->count = 17;
dev->state = EEPROM_OUTPUT;
dev->dat = dev->data[dev->dat];
break;
case EEPROM_OP_EW:
switch (dev->dat) {
case EEPROM_OP_EWDS:
dev->wp = 1;
break;
case EEPROM_OP_WRAL:
dev->opcode = EEPROM_OP_WRALMAIN;
dev->count = 20;
break;
case EEPROM_OP_ERAL:
if (! dev->wp) {
memset(dev->data, 0xff, 128);
ati_eeprom_save(dev);
}
break;
case EEPROM_OP_EWEN:
dev->wp = 0;
break;
}
dev->state = EEPROM_IDLE;
dev->out = 1;
break;
case EEPROM_OP_ERASE:
if (! dev->wp) {
dev->data[dev->dat] = 0xffff;
ati_eeprom_save(dev);
}
dev->state = EEPROM_IDLE;
dev->out = 1;
break;
case EEPROM_OP_WRALMAIN:
if (! dev->wp) {
for (c = 0; c < 256; c++)
dev->data[c] = dev->dat;
ati_eeprom_save(dev);
}
dev->state = EEPROM_IDLE;
dev->out = 1;
break;
}
}
break;
}
}
dev->oldena = ena;
} else if (!clk && dev->oldclk) {
if (ena) {
switch (dev->state) {
case EEPROM_OUTPUT:
dev->out = (dev->dat & 0x10000) ? 1 : 0;
dev->dat <<= 1;
dev->count--;
if (! dev->count) {
dev->state = EEPROM_IDLE;
}
break;
}
}
}
dev->oldclk = clk;
}
void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat)
int
ati_eeprom_read(ati_eeprom_t *dev)
{
int c;
if (!ena)
{
eeprom->out = 1;
}
if (clk && !eeprom->oldclk)
{
if (ena && !eeprom->oldena)
{
eeprom->state = EEPROM_WAIT;
eeprom->opcode = 0;
eeprom->count = 3;
eeprom->out = 1;
}
else if (ena)
{
switch (eeprom->state)
{
case EEPROM_WAIT:
if (!dat)
break;
eeprom->state = EEPROM_OPCODE;
/* fall through */
case EEPROM_OPCODE:
eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0);
eeprom->count--;
if (!eeprom->count)
{
switch (eeprom->opcode)
{
case EEPROM_OP_WRITE:
eeprom->count = eeprom->type ? 24 : 22;
eeprom->state = EEPROM_INPUT;
eeprom->dat = 0;
break;
case EEPROM_OP_READ:
eeprom->count = eeprom->type ? 8 : 6;
eeprom->state = EEPROM_INPUT;
eeprom->dat = 0;
break;
case EEPROM_OP_EW:
eeprom->count = 2;
eeprom->state = EEPROM_INPUT;
eeprom->dat = 0;
break;
case EEPROM_OP_ERASE:
eeprom->count = eeprom->type ? 8 : 6;
eeprom->state = EEPROM_INPUT;
eeprom->dat = 0;
break;
}
}
break;
case EEPROM_INPUT:
eeprom->dat = (eeprom->dat << 1) | (dat ? 1 : 0);
eeprom->count--;
if (!eeprom->count)
{
switch (eeprom->opcode)
{
case EEPROM_OP_WRITE:
if (!eeprom->wp)
{
eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = eeprom->dat & 0xffff;
ati_eeprom_save(eeprom);
}
eeprom->state = EEPROM_IDLE;
eeprom->out = 1;
break;
case EEPROM_OP_READ:
eeprom->count = 17;
eeprom->state = EEPROM_OUTPUT;
eeprom->dat = eeprom->data[eeprom->dat];
break;
case EEPROM_OP_EW:
switch (eeprom->dat)
{
case EEPROM_OP_EWDS:
eeprom->wp = 1;
break;
case EEPROM_OP_WRAL:
eeprom->opcode = EEPROM_OP_WRALMAIN;
eeprom->count = 20;
break;
case EEPROM_OP_ERAL:
if (!eeprom->wp)
{
memset(eeprom->data, 0xff, 128);
ati_eeprom_save(eeprom);
}
break;
case EEPROM_OP_EWEN:
eeprom->wp = 0;
break;
}
eeprom->state = EEPROM_IDLE;
eeprom->out = 1;
break;
case EEPROM_OP_ERASE:
if (!eeprom->wp)
{
eeprom->data[eeprom->dat] = 0xffff;
ati_eeprom_save(eeprom);
}
eeprom->state = EEPROM_IDLE;
eeprom->out = 1;
break;
case EEPROM_OP_WRALMAIN:
if (!eeprom->wp)
{
for (c = 0; c < 256; c++)
eeprom->data[c] = eeprom->dat;
ati_eeprom_save(eeprom);
}
eeprom->state = EEPROM_IDLE;
eeprom->out = 1;
break;
}
}
break;
}
}
eeprom->oldena = ena;
}
else if (!clk && eeprom->oldclk)
{
if (ena)
{
switch (eeprom->state)
{
case EEPROM_OUTPUT:
eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0;
eeprom->dat <<= 1;
eeprom->count--;
if (!eeprom->count)
{
eeprom->state = EEPROM_IDLE;
}
break;
}
}
}
eeprom->oldclk = clk;
return dev->out;
}
int ati_eeprom_read(ati_eeprom_t *eeprom)
{
return eeprom->out;
}

View File

@@ -1,61 +0,0 @@
/*
* VARCem Virtual ARchaeological Computer EMulator.
* An emulator of (mostly) x86-based PC systems and devices,
* using the ISA,EISA,VLB,MCA and PCI system buses, roughly
* spanning the era between 1981 and 1995.
*
* This file is part of the VARCem Project.
*
* Definitions for the ATI EEPROM driver.
*
* Version: @(#)vid_ati_eeprom.h 1.0.1 2018/02/14
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#ifndef VIDEO_ATI_EEPROM_H
# define VIDEO_ATI_EEPROM_H
typedef struct ati_eeprom_t
{
uint16_t data[256];
int oldclk, oldena;
int opcode, state, count, out;
int wp;
uint32_t dat;
int type;
wchar_t fn[256];
} ati_eeprom_t;
void ati_eeprom_load(ati_eeprom_t *eeprom, wchar_t *fn, int type);
void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat);
int ati_eeprom_read(ati_eeprom_t *eeprom);
#endif /*VIDEO_ATI_EEPROM_H*/

View File

@@ -8,13 +8,13 @@
*
* ATi Mach64 graphics card emulation.
*
* Version: @(#)vid_ati_mach64.c 1.0.14 2018/10/08
* Version: @(#)vid_ati_mach64.c 1.0.15 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
@@ -51,7 +51,7 @@
#include "video.h"
#include "vid_svga.h"
#include "vid_svga_render.h"
#include "vid_ati_eeprom.h"
#include "vid_ati.h"
#include "vid_ati68860_ramdac.h"
#include "vid_ics2595.h"

View File

@@ -8,7 +8,7 @@
*
* Emulation of the old and new IBM CGA graphics cards.
*
* Version: @(#)vid_cga.c 1.0.11 2019/01/01
* Version: @(#)vid_cga.c 1.0.12 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -649,7 +649,7 @@ cga_standalone_init(const device_t *info)
cga_palette = (dev->rgb_type << 1);
cgapal_rebuild();
video_load_font(CGA_FONT_ROM_PATH, (dev->font_type) ? 8 : 2);
video_load_font(CGA_FONT_ROM_PATH, (dev->font_type) ? 2 : 1);
video_inform(VID_TYPE_CGA, info->vid_timing);

View File

@@ -8,14 +8,14 @@
*
* Emulation of the Tseng Labs ET4000.
*
* Version: @(#)vid_et4000.c 1.0.13 2018/10/08
* Version: @(#)vid_et4000.c 1.0.14 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* GreatPsycho, <greatpsycho@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
@@ -51,6 +51,7 @@
#include "video.h"
#include "vid_svga.h"
#include "vid_svga_render.h"
#include "vid_ati.h" /* for the font loader */
#include "vid_sc1502x_ramdac.h"
@@ -155,7 +156,7 @@ et4000k_in(uint16_t addr, void *priv)
switch(dev->get_korean_font_enabled) {
case 3:
if ((dev->port_32cb_val & 0x30) == 0x30) {
val = fontdatksc5601[dev->get_korean_font_base].chr[dev->get_korean_font_index++];
val = fontdatk[dev->get_korean_font_base].chr[dev->get_korean_font_index++];
dev->get_korean_font_index &= 0x1f;
} else
if ((dev->port_32cb_val & 0x30) == 0x20 &&
@@ -164,18 +165,18 @@ et4000k_in(uint16_t addr, void *priv)
switch(dev->get_korean_font_base & 0x3f80) {
case 0x2480:
if (dev->get_korean_font_index < 16)
val = fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index];
val = fontdatk_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index];
else
if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40)
val = fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8];
val = fontdatk_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8];
break;
case 0x3f00:
if (dev->get_korean_font_index < 16)
val = fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index];
val = fontdatk_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index];
else
if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40)
val = fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8];
val = fontdatk_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8];
break;
default:
@@ -358,18 +359,18 @@ et4000k_out(uint16_t addr, uint8_t val, void *priv)
switch (dev->get_korean_font_base & 0x3f80) {
case 0x2480:
if (dev->get_korean_font_index < 16)
fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index] = val;
fontdatk_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index] = val;
else
if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40)
fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8] = val;
fontdatk_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8] = val;
break;
case 0x3f00:
if (dev->get_korean_font_index < 16)
fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index] = val;
fontdatk_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index] = val;
else
if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40)
fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8] = val;
fontdatk_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8] = val;
break;
default:
@@ -487,9 +488,11 @@ et4000_init(const device_t *info)
switch(dev->type) {
case 0: /* ISA ET4000AX */
dev->vram_size = device_get_config_int("memory") << 10;
svga_init(&dev->svga, dev, dev->vram_size,
et4000_recalctimings, et4000_in, et4000_out,
NULL, NULL);
io_sethandler(0x03c0, 32,
et4000_in,NULL,NULL, et4000_out,NULL,NULL, dev);
break;
@@ -497,11 +500,14 @@ et4000_init(const device_t *info)
case 1: /* MCA ET4000AX */
dev->is_mca = 1;
dev->vram_size = 1024 << 10;
svga_init(&dev->svga, dev, dev->vram_size,
et4000_recalctimings, et4000_in, et4000_out,
NULL, NULL);
io_sethandler(0x03c0, 32,
et4000_in,NULL,NULL, et4000_out,NULL,NULL, dev);
dev->pos_regs[0] = 0xf2; /* ET4000 MCA board ID */
dev->pos_regs[1] = 0x80;
mca_add(et4000_mca_read, et4000_mca_write, dev);
@@ -513,9 +519,17 @@ et4000_init(const device_t *info)
dev->port_22cb_val = 0x60;
dev->port_32cb_val = 0;
dev->svga.ksc5601_sbyte_mask = 0x80;
svga_init(&dev->svga, dev, dev->vram_size,
et4000_recalctimings, et4000k_in, et4000k_out,
NULL, NULL);
if (! ati28800k_load_font(&dev->svga, KOREAN_FONT_ROM_PATH)) {
svga_close(&dev->svga);
free(dev);
return(NULL);
}
io_sethandler(0x03c0, 32,
et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev);
io_sethandler(0x22cb, 1,
@@ -524,7 +538,6 @@ et4000_init(const device_t *info)
et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev);
io_sethandler(0x32cb, 1,
et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev);
video_load_font(KOREAN_FONT_ROM_PATH, 6);
fn = KOREAN_BIOS_ROM_PATH;
break;
}
@@ -536,7 +549,7 @@ et4000_init(const device_t *info)
rom_init(&dev->bios_rom, fn,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
DEBUG("VIDEO: %s (vram=%dKB)\n", dev->name, dev->vram_size>>10);
DEBUG("VIDEO: %s (vram=%iKB)\n", dev->name, dev->vram_size>>10);
video_inform(VID_TYPE_SPEC,
(const video_timings_t *)info->vid_timing);

View File

@@ -63,13 +63,13 @@
* reducing the height of characters so they fit in an 8x12 cell
* if necessary.
*
* Version: @(#)vid_genius.c 1.0.8 2018/10/24
* Version: @(#)vid_genius.c 1.0.9 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* John Elliott, <jce@seasip.info>
*
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2016-2018 John Elliott.
*
@@ -107,7 +107,7 @@
#include "video.h"
#define BIOS_ROM_PATH L"video/mdsi/genius/8x12.bin"
#define FONT_ROM_PATH L"video/mdsi/genius/8x12.bin"
#define GENIUS_XSIZE 728
@@ -115,6 +115,8 @@
typedef struct {
const char *name;
mem_map_t mapping;
uint8_t mda_crtc[32]; /* The 'CRTC' as the host PC sees it */
@@ -154,6 +156,8 @@ typedef struct {
int cols[256][2][2];
uint8_t fontdat[256][16];
uint8_t *vram;
} genius_t;
@@ -369,7 +373,7 @@ text_line(genius_t *dev, uint8_t background)
}
} else {
/* Draw 8 pixels of character */
bitmap[0] = fontdat8x12[chr][sc];
bitmap[0] = dev->fontdat[chr][sc];
for (c = 0; c < 8; c++) {
col = dev->cols[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0];
if (!(dev->enabled) || !(dev->mda_ctrl & 8))
@@ -559,6 +563,27 @@ genius_poll(void *priv)
}
static int
load_font(genius_t *dev, const wchar_t *s)
{
FILE *fp;
int c;
fp = plat_fopen(rom_path(s), L"rb");
if (fp == NULL) {
ERRLOG("%s: cannot load font '%ls'\n", dev->name, s);
return(0);
}
for (c = 0; c < 256; c++)
(void)fread(&dev->fontdat[c][0], 1, 16, fp);
(void)fclose(fp);
return(1);
}
static void *
genius_init(const device_t *info)
{
@@ -567,12 +592,16 @@ genius_init(const device_t *info)
dev = (genius_t *)mem_alloc(sizeof(genius_t));
memset(dev, 0x00, sizeof(genius_t));
dev->name = info->name;
if (! load_font(dev, FONT_ROM_PATH)) {
free(dev);
return(NULL);
}
/* 160k video RAM */
dev->vram = (uint8_t *)mem_alloc(0x28000);
video_load_font(BIOS_ROM_PATH, 4);
timer_add(genius_poll, &dev->vidtime, TIMER_ALWAYS_ENABLED, dev);
/* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in
@@ -645,7 +674,7 @@ genius_close(void *priv)
static int
genius_available(void)
{
return rom_present(BIOS_ROM_PATH);
return rom_present(FONT_ROM_PATH);
}

View File

@@ -38,7 +38,7 @@
* This is implemented by holding a FIFO of unlimited depth in
* the IM1024 to receive the data.
*
* Version: @(#)vid_im1024.c 1.0.2 2019/03/02
* Version: @(#)vid_im1024.c 1.0.3 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* John Elliott, <jce@seasip.info>
@@ -99,16 +99,14 @@ typedef struct {
static void
fifo_write(im1024_t *dev, uint8_t val)
{
#if 0
DEBUG(("IM1024: fifo_write: %02x [rd=%04x wr=%04x]\n",
val, dev->fifo_rdptr, dev->fifo_wrptr));
#endif
DBGLOG(1, "IM1024: fifo_write: %02x [rd=%04x wr=%04x]\n",
val, dev->fifo_rdptr, dev->fifo_wrptr);
if (((dev->fifo_wrptr + 1) % dev->fifo_len) == dev->fifo_rdptr) {
/* FIFO is full. Double its size. */
uint8_t *buf;
DEBUG("IM1024: fifo_resize: %i to %i\n",
DBGLOG(1, "IM1024: fifo_resize: %i to %i\n",
dev->fifo_len, 2 * dev->fifo_len);
buf = realloc(dev->fifo, 2 * dev->fifo_len);
@@ -121,10 +119,10 @@ fifo_write(im1024_t *dev, uint8_t val)
dev->fifo_len *= 2;
}
/* Append to the queue */
/* Append to the queue. */
dev->fifo[dev->fifo_wrptr++] = val;
/* Wrap if end of buffer reached */
/* Wrap if end of buffer reached. */
if (dev->fifo_wrptr >= dev->fifo_len)
dev->fifo_wrptr = 0;
}
@@ -148,15 +146,18 @@ fifo_read(im1024_t *dev)
}
/* Where a normal PGC would just read from the ring buffer at 0xC6300, the
* IM-1024 can read either from this or from its internal FIFO. The internal
* FIFO has priority. */
/*
* Where a normal PGC would just read from the ring buffer at 0xC6300,
* the IM-1024 can read from either this or from its internal FIFO.
*
* The internal FIFO has priority.
*/
static int
input_byte(pgc_t *pgc, uint8_t *result)
{
im1024_t *dev = (im1024_t *)pgc;
/* If input buffer empty, wait for it to fill */
/* If input buffer empty, wait for it to fill. */
while ((dev->fifo_wrptr == dev->fifo_rdptr) &&
(pgc->mapram[0x300] == pgc->mapram[0x301])) {
pgc->waiting_input_fifo = 1;
@@ -179,7 +180,7 @@ input_byte(pgc_t *pgc, uint8_t *result)
}
/* Macros to disable clipping and save clip state */
/* Macros to disable clipping and save clip state. */
#define PUSHCLIP { \
uint16_t vp_x1, vp_x2, vp_y1, vp_y2; \
vp_x1 = pgc->vp_x1; \
@@ -206,7 +207,7 @@ im1024_read(uint32_t addr, void *priv)
{
im1024_t *dev = (im1024_t *)priv;
if (addr == 0xC6331 && dev->pgc.mapram[0x330] == 1) {
if (addr == 0xc6331 && dev->pgc.mapram[0x330] == 1) {
/* Hardcode that there are 128 bytes free. */
return(0x80);
}
@@ -221,9 +222,11 @@ im1024_write(uint32_t addr, uint8_t val, void *priv)
{
im1024_t *dev = (im1024_t *)priv;
/* If we are in 'fast' input mode, send all writes to the internal
* FIFO */
if (addr >= 0xC6000 && addr < 0xC6100 && dev->pgc.mapram[0x330] == 1) {
/*
* If we are in 'fast' input mode, send all
* writes to the internal FIFO.
*/
if (addr >= 0xc6000 && addr < 0xc6100 && dev->pgc.mapram[0x330] == 1) {
fifo_write(dev, val);
DBGLOG(1, "IM1024: write(%02x)\n", val);
@@ -239,8 +242,10 @@ im1024_write(uint32_t addr, uint8_t val, void *priv)
}
/* I don't know what the IMGSIZ command does, only that the Windows driver
* issues it. So just parse and ignore it */
/*
* I don't know what the IMGSIZ command does, only that the
* Windows driver issues it. So just parse and ignore it.
*/
static void
hndl_imgsiz(pgc_t *pgc)
{
@@ -259,8 +264,10 @@ hndl_imgsiz(pgc_t *pgc)
}
/* I don't know what the IPREC command does, only that the Windows driver
* issues it. So just parse and ignore it */
/*
* I don't know what the IPREC command does, only that the
* Windows driver issues it. So just parse and ignore it.
*/
static void
hndl_iprec(pgc_t *pgc)
{
@@ -298,8 +305,10 @@ hndl_linfun(pgc_t *pgc)
}
/* I think PAN controls which part of the 1024x1024 framebuffer is displayed
* in the 1024x800 visible screen. */
/*
* I think PAN controls which part of the 1024x1024 framebuffer
* is displayed in the 1024x800 visible screen.
*/
static void
hndl_pan(pgc_t *pgc)
{
@@ -315,7 +324,7 @@ hndl_pan(pgc_t *pgc)
}
/* PLINE draws a non-filled polyline at a fixed position */
/* PLINE draws a non-filled polyline at a fixed position. */
static void
hndl_pline(pgc_t *pgc)
{
@@ -340,9 +349,12 @@ hndl_pline(pgc_t *pgc)
}
/* Blit a single row of pixels from one location to another. To avoid
* difficulties if the two overlap, read both rows into memory, process them
* there, and write the result back. */
/*
* Blit a single row of pixels from one location to another.
*
* To avoid difficulties if the two overlap, read both rows
* into memory, process them there, and write the result back.
*/
static void
blkmov_row(pgc_t *pgc, int16_t x0, int16_t x1, int16_t x2, int16_t sy, int16_t ty)
{
@@ -355,37 +367,35 @@ blkmov_row(pgc_t *pgc, int16_t x0, int16_t x1, int16_t x2, int16_t sy, int16_t t
dst[x - x0] = pgc_read_pixel(pgc, x - x0 + x2, ty);
}
for (x = x0; x <= x1; x++) {
switch (pgc->draw_mode) {
default:
case 0:
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0]);
break;
for (x = x0; x <= x1; x++) switch (pgc->draw_mode) {
default:
case 0:
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0]);
break;
case 1:
pgc_write_pixel(pgc, (x - x0 + x2), ty, dst[x - x0] ^ 0xFF);
break;
case 1:
pgc_write_pixel(pgc, (x - x0 + x2), ty, dst[x - x0] ^ 0xff);
break;
case 2:
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] ^ dst[x - x0]);
break;
case 2:
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] ^ dst[x - x0]);
break;
case 3:
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] & dst[x - x0]);
break;
}
case 3:
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] & dst[x - x0]);
break;
}
}
/* BLKMOV blits a rectangular area from one location to another, with no
* clipping. */
/*
* BLKMOV blits a rectangular area from one location to another.
*
* Clipping is disabled.
*/
static void
hndl_blkmov(pgc_t *pgc)
{
#if 0
im1024_t *dev = (im1024_t *)pgc;
#endif
int16_t x0, y0;
int16_t x1, y1;
int16_t x2, y2;
@@ -398,13 +408,15 @@ hndl_blkmov(pgc_t *pgc)
if (! pgc_param_word(pgc, &x2)) return;
if (! pgc_param_word(pgc, &y2)) return;
DEBUG("IM1024: BLKMOV %i,%i,%i,%i,%i,%i\n", x0, y0, x1, y1, x2, y2);
DEBUG("IM1024: BLKMOV %i,%i,%i,%i,%i,%i\n", x0,y0,x1,y1,x2,y2);
/* Disable clipping. */
PUSHCLIP
/* Either go down from the top, or up from the bottom, depending
* whether areas might overlap */
/*
* Either go down from the top, or up from the bottom,
* depending whether areas might overlap.
*/
if (y2 <= y0) {
for (y = y0; y <= y1; y++)
blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2);
@@ -418,8 +430,10 @@ hndl_blkmov(pgc_t *pgc)
}
/* This overrides the PGC ELIPSE command to parse its parameters as words
* rather than coordinates */
/*
* Override the PGC ELIPSE command to parse its
* parameters as words rather than coordinates.
*/
static void
hndl_ellipse(pgc_t *pgc)
{
@@ -435,8 +449,10 @@ hndl_ellipse(pgc_t *pgc)
}
/* This overrides the PGC MOVE command to parse its parameters as words
* rather than coordinates */
/*
* Override the PGC MOVE command to parse its
* parameters as words rather than coordinates.
*/
static void
hndl_move(pgc_t *pgc)
{
@@ -445,15 +461,17 @@ hndl_move(pgc_t *pgc)
if (! pgc_param_word(pgc, &x)) return;
if (! pgc_param_word(pgc, &y)) return;
DEBUG("IM1024: MOVE %i,%i\n", x, y);
pgc->x = x << 16;
pgc->y = y << 16;
DEBUG("IM1024: MOVE %i,%i\n", x, y);
}
/* This overrides the PGC DRAW command to parse its parameters as words
* rather than coordinates */
/*
* Override the PGC DRAW command to parse its
* parameters as words rather than coordinates.
*/
static void
hndl_draw(pgc_t *pgc)
{
@@ -465,13 +483,16 @@ hndl_draw(pgc_t *pgc)
DEBUG("IM1024: DRAW %i,%i to %i,%i\n", pgc->x >> 16, pgc->y >> 16, x, y);
pgc_draw_line(pgc, pgc->x, pgc->y, x << 16, y << 16, pgc->line_pattern);
pgc->x = x << 16;
pgc->y = y << 16;
}
/* This overrides the PGC POLY command to parse its parameters as words
* rather than coordinates */
/*
* Override the PGC POLY command to parse its
* parameters as words rather than coordinates.
*/
static void
hndl_poly(pgc_t *pgc)
{
@@ -484,7 +505,6 @@ hndl_poly(pgc_t *pgc)
x = (int32_t *)mem_alloc(as * sizeof(int32_t));
y = (int32_t *)mem_alloc(as * sizeof(int32_t));
if (!x || !y) {
DEBUG("IM1024: POLY: out of memory\n");
return;
@@ -519,9 +539,11 @@ hndl_poly(pgc_t *pgc)
realcount++;
}
/* If we are in a command list, peek ahead to see if the next
/*
* If we are in a command list, peek ahead to see if the next
* command is also POLY. If so, that's a continuation of this
* polygon! */
* polygon!
*/
parsing = 0;
if (pgc->clcur && (pgc->clcur->rdptr+1) < pgc->clcur->wrptr &&
pgc->clcur->list[pgc->clcur->rdptr] == 0x30) {
@@ -573,8 +595,10 @@ parse_poly(pgc_t *pgc, pgc_cl_t *cl, int c)
}
/* This overrides the PGC RECT command to parse its parameters as words
* rather than coordinates */
/*
* Override the PGC RECT command to parse its
* parameters as words rather than coordinates.
*/
static void
hndl_rect(pgc_t *pgc)
{
@@ -586,7 +610,7 @@ hndl_rect(pgc_t *pgc)
if (! pgc_param_word(pgc, &x1)) return;
if (! pgc_param_word(pgc, &y1)) return;
/* Convert to raster coords */
/* Convert to raster coords. */
pgc_sto_raster(pgc, &x0, &y0);
pgc_sto_raster(pgc, &x1, &y1);
@@ -608,8 +632,13 @@ hndl_rect(pgc_t *pgc)
}
/* TODO: Text drawing should probably be implemented in vid_pgc.c rather
* than vid_im1024.c */
/*
* FIXME:
* Define a font character.
*
* Text drawing should probably be implemented in
* vid_pgc.c rather than here..
*/
static void
hndl_tdefin(pgc_t *pgc)
{
@@ -619,8 +648,8 @@ hndl_tdefin(pgc_t *pgc)
unsigned len, n;
if (! pgc_param_byte(pgc, &ch)) return;
if (! pgc_param_byte(pgc, &rows)) return;
if (! pgc_param_byte(pgc, &cols)) return;
if (! pgc_param_byte(pgc, &rows)) return;
DEBUG("IM1024: TDEFIN (%i,%i,%i) 0x%02x 0x%02x\n",
ch, rows, cols, pgc->mapram[0x300], pgc->mapram[0x301]);
@@ -633,15 +662,27 @@ hndl_tdefin(pgc_t *pgc)
dev->font[ch][n] = bt;
}
dev->fontx[ch] = rows;
dev->fonty[ch] = cols;
dev->fontx[ch] = cols;
dev->fonty[ch] = rows;
}
static void
hndl_tsize(pgc_t *pgc)
{
int16_t size;
if (!pgc_param_word(pgc, &size)) return;
DEBUG("IM1024: TSIZE(%i)\n", size);
pgc->tsize = size << 16;
}
static void
hndl_twrite(pgc_t *pgc)
{
uint8_t buf[256], rbuf[256];
uint8_t buf[256];
im1024_t *dev = (im1024_t *)pgc;
uint8_t count, mask, *row;
int x, y, wb, n;
@@ -652,30 +693,21 @@ hndl_twrite(pgc_t *pgc)
for (n = 0; n < count; n++)
if (! pgc_param_byte(pgc, &buf[n])) return;
buf[count] = 0;
for (n = 0; n <= count; n++) {
if (isprint(buf[n]) || 0 == buf[n])
rbuf[n] = buf[n];
else
rbuf[n] = '?';
}
pgc_sto_raster(pgc, &x0, &y0);
DEBUG("IM1024: TWRITE (%i,%-*.*s) x0=%i y0=%i\n",
count, count, count, rbuf, x0, y0);
DEBUG("IM1024: TWRITE (%i) x0=%i y0=%i\n", count, x0, y0);
for (n = 0; n < count; n++) {
wb = (dev->fontx[buf[n]] + 7) / 8;
DEBUG("IM1024: ch=0x%02x w=%d h=%i wb=%i\n",
DEBUG("IM1024: ch=0x%02x w=%i h=%i wb=%i\n",
buf[n], dev->fontx[buf[n]], dev->fonty[buf[n]], wb);
for (y = 0; y < dev->fonty[buf[n]]; y++) {
mask = 0x80;
row = &dev->font[buf[n]][y * wb];
for (x = 0; x < dev->fontx[buf[n]]; x++) {
rbuf[x] = (row[0] & mask) ? '#' : '-';
if (row[0] & mask)
pgc_plot(pgc, x + x0, y0 - y);
mask = mask >> 1;
@@ -684,8 +716,50 @@ hndl_twrite(pgc_t *pgc)
row++;
}
}
rbuf[x++] = '\n';
rbuf[x++] = 0;
}
x0 += dev->fontx[buf[n]];
}
}
static void
hndl_txt88(pgc_t *pgc)
{
uint8_t buf[256];
im1024_t *dev = (im1024_t *)pgc;
uint8_t count, mask, *row;
int16_t x0 = pgc->x >> 16;
int16_t y0 = pgc->y >> 16;
unsigned n;
int x, y, wb;
if (! pgc_param_byte(pgc, &count)) return;
for (n = 0; n < count; n++)
if (! pgc_param_byte(pgc, &buf[n])) return;
buf[count] = 0;
pgc_sto_raster(pgc, &x0, &y0);
DEBUG("IM204: TWRITE (%i) x0=%i y0=%i\n", count, x0, y0);
for (n = 0; n < count; n++) {
wb = (dev->fontx[buf[n]] + 7) / 8;
DEBUG("IM1024: ch=0x%02x w=%i h=%i wb=%i\n",
buf[n], dev->fontx[buf[n]], dev->fonty[buf[n]], wb);
for (y = 0; y < dev->fonty[buf[n]]; y++) {
mask = 0x80;
row = &dev->font[buf[n]][y * wb];
for (x = 0; x < dev->fontx[buf[n]]; x++) {
if (row[0] & mask) pgc_plot(pgc, x + x0, y0 - y);
mask = mask >> 1;
if (mask == 0) {
mask = 0x80;
row++;
}
}
}
x0 += dev->fontx[buf[n]];
@@ -704,8 +778,7 @@ hndl_imagew(pgc_t *pgc)
if (! pgc_param_word(pgc, &col1)) return;
if (! pgc_param_word(pgc, &col2)) return;
/* IMAGEW already uses raster coordinates so there is no need to
* convert it */
/* Already using raster coordinates, no need to convert. */
DEBUG("IM1024: IMAGEW (row=%i,col1=%i,col2=%i)\n", row1, col1, col2);
vp_x1 = pgc->vp_x1;
@@ -728,34 +801,32 @@ hndl_imagew(pgc_t *pgc)
pgc_write_pixel(pgc, col1, row1, v1);
col1++;
}
} else {
/* In hex mode, it's RLE compressed. */
while (col1 <= col2) {
if (! pgc_param_byte(pgc, &v1)) return;
return;
}
/* In hex mode, it's RLE compressed. */
while (col1 <= col2) {
if (! pgc_param_byte(pgc, &v1)) return;
if (v1 & 0x80) {
/* Literal run. */
v1 -= 0x7f;
while (col1 <= col2 && v1 != 0) {
if (v1 & 0x80) {
/* Literal run. */
v1 -= 0x7f;
while (col1 <= col2 && v1 != 0) {
if (! pgc_param_byte(pgc, &v2)) return;
pgc_write_pixel(pgc, col1, row1, v2);
col1++;
v1--;
}
} else {
/* Repeated run. */
if (! pgc_param_byte(pgc, &v2)) return;
pgc_write_pixel(pgc, col1, row1, v2);
col1++;
v1--;
}
} else {
/* Repeated run. */
if (! pgc_param_byte(pgc, &v2)) return;
v1++;
while (col1 <= col2 && v1 != 0) {
pgc_write_pixel(pgc, col1, row1, v2);
col1++;
v1--;
}
}
v1++;
while (col1 <= col2 && v1 != 0) {
pgc_write_pixel(pgc, col1, row1, v2);
col1++;
v1--;
}
}
}
}
/* Restore clipping. */
@@ -774,7 +845,8 @@ hndl_imagew(pgc_t *pgc)
static void
hndl_dot(pgc_t *pgc)
{
int16_t x = pgc->x >> 16, y = pgc->y >> 16;
int16_t x = pgc->x >> 16,
y = pgc->y >> 16;
pgc_sto_raster(pgc, &x, &y);
@@ -785,10 +857,12 @@ hndl_dot(pgc_t *pgc)
}
/* This command (which I have called IMAGEX, since I don't know its real
/*
* This command (which I have called IMAGEX, since I don't know its real
* name) is a screen-to-memory blit. It reads a rectangle of bytes, rather
* than the single row read by IMAGER, and does not attempt to compress
* the result */
* the result.
*/
static void
hndl_imagex(pgc_t *pgc)
{
@@ -800,7 +874,7 @@ hndl_imagex(pgc_t *pgc)
if (! pgc_param_word(pgc, &x1)) return;
if (! pgc_param_word(pgc, &y1)) return;
/* IMAGEX already uses raster coordinates so don't convert */
/* Already using raster coordinates, no need to convert. */
DEBUG("IM1024: IMAGEX (%i,%i,%i,%i)\n", x0,y0,x1,y1);
for (p = y0; p <= y1; p++) {
@@ -812,7 +886,8 @@ hndl_imagex(pgc_t *pgc)
}
/* Commands implemented by the IM-1024.
/*
* Commands implemented by the IM-1024.
*
* TODO: A lot of commands need commandlist parsers.
* TODO: The IM-1024 has a lot more commands that are not included here
@@ -827,19 +902,22 @@ static const pgc_cmd_t im1024_commands[] = {
{ "ELIPSE", 0x39, hndl_ellipse, pgc_parse_words, 2 },
{ "EL", 0x39, hndl_ellipse, pgc_parse_words, 2 },
{ "IMAGEW", 0xd9, hndl_imagew, NULL, 0 },
{ "IW", 0xd9, hndl_imagew, NULL, 0 },
{ "IMAGEX", 0xda, hndl_imagex, NULL, 0 },
{ "TWRITE", 0x8b, hndl_twrite, NULL, 0 },
{ "TDEFIN", 0x84, hndl_tdefin, NULL, 0 },
{ "TD", 0x84, hndl_tdefin, NULL, 0 },
{ "IPREC", 0xe4, hndl_iprec, NULL, 0 },
{ "IMGSIZ", 0x4e, hndl_imgsiz, NULL, 0 },
{ "LUT8", 0xe6, pgc_hndl_lut8, NULL, 0 },
{ "IPREC", 0xe4, hndl_iprec, NULL, 0 },
{ "IW", 0xd9, hndl_imagew, NULL, 0 },
{ "L8", 0xe6, pgc_hndl_lut8, NULL, 0 },
{ "LINFUN", 0xeb, hndl_linfun, pgc_parse_bytes, 1 },
{ "LF", 0xeb, hndl_linfun, pgc_parse_bytes, 1 },
{ "LINFUN", 0xeb, hndl_linfun, pgc_parse_bytes, 1 },
{ "LUT8", 0xe6, pgc_hndl_lut8, NULL, 0 },
{ "LUT8RD", 0x53, pgc_hndl_lut8rd,NULL, 0 },
{ "L8RD", 0x53, pgc_hndl_lut8rd,NULL, 0 },
{ "TDEFIN", 0x84, hndl_tdefin, NULL, 0 },
{ "TD", 0x84, hndl_tdefin, NULL, 0 },
{ "TSIZE", 0x81, hndl_tsize, NULL, 0 },
{ "TS", 0x81, hndl_tsize, NULL, 0 },
{ "TWRITE", 0x8b, hndl_twrite, NULL, 0 },
{ "TXT88", 0x88, hndl_txt88, NULL, 0 },
{ "PAN", 0xb7, hndl_pan, NULL, 0 },
{ "POLY", 0x30, hndl_poly, parse_poly, 0 },
{ "P", 0x30, hndl_poly, parse_poly, 0 },
@@ -861,8 +939,8 @@ im1024_init(const device_t *info)
dev = (im1024_t *)mem_alloc(sizeof(im1024_t));
memset(dev, 0x00, sizeof(im1024_t));
dev->fifo = (uint8_t *)mem_alloc(4096);
dev->fifo_len = 4096;
dev->fifo = (uint8_t *)mem_alloc(dev->fifo_len);
dev->fifo_wrptr = 0;
dev->fifo_rdptr = 0;

View File

@@ -31,8 +31,7 @@
* instructions left there for it. We simulate this behavior
* with a separate thread.
*
* **NOTE** This driver does not yet work, pending (proper) conversion
* to the video backend, which is different from PCem's:
* **NOTE** This driver is not finished yet:
*
* - cursor will blink at very high speed if used on a machine
* with clock greater than 4.77MHz. We should "scale down"
@@ -43,10 +42,9 @@
*
* - test it with the Windows 1.x driver?
*
* Until these are fixed, both the PGC as well as the IM1024
* will remain in DevBranch mode.
* This is expected to be done shortly.
*
* Version: @(#)vid_pgc.c 1.0.2 2019/03/02
* Version: @(#)vid_pgc.c 1.0.2 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* John Elliott, <jce@seasip.info>
@@ -357,7 +355,7 @@ static void
hndl_clbeg(pgc_t *dev)
{
const pgc_cmd_t *cmd;
uint8_t param;
uint8_t param = 0;
pgc_cl_t cl;
if (! pgc_param_byte(dev, &param)) return;
@@ -409,7 +407,7 @@ static void
hndl_clrun(pgc_t *dev)
{
pgc_cl_t *clprev = dev->clcur;
uint8_t param;
uint8_t param = 0;
if (! pgc_param_byte(dev, &param)) return;
@@ -425,8 +423,8 @@ static void
hndl_cloop(pgc_t *dev)
{
pgc_cl_t *clprev = dev->clcur;
uint8_t param;
int16_t repeat;
uint8_t param = 0;
int16_t repeat = 0;
if (! pgc_param_byte(dev, &param)) return;
if (! pgc_param_word(dev, &repeat)) return;
@@ -442,7 +440,7 @@ hndl_cloop(pgc_t *dev)
static void
hndl_clread(pgc_t *dev)
{
uint8_t param;
uint8_t param = 0;
uint32_t n;
if (! pgc_param_byte(dev, &param)) return;
@@ -458,7 +456,7 @@ hndl_clread(pgc_t *dev)
static void
hndl_cldel(pgc_t *dev)
{
uint8_t param;
uint8_t param = 0;
if (! pgc_param_byte(dev, &param)) return;
@@ -470,7 +468,7 @@ hndl_cldel(pgc_t *dev)
static void
hndl_clears(pgc_t *dev)
{
uint8_t param;
uint8_t param = 0;
uint32_t y;
if (! pgc_param_byte(dev, &param)) return;
@@ -484,7 +482,7 @@ hndl_clears(pgc_t *dev)
static void
hndl_color(pgc_t *dev)
{
uint8_t param;
uint8_t param = 0;
if (! pgc_param_byte(dev, &param)) return;
@@ -502,7 +500,7 @@ hndl_color(pgc_t *dev)
static void
hndl_linfun(pgc_t *dev)
{
uint8_t param;
uint8_t param = 0;
if (! pgc_param_byte(dev, &param)) return;
@@ -518,7 +516,7 @@ hndl_linfun(pgc_t *dev)
static void
hndl_linpat(pgc_t *dev)
{
uint16_t param;
uint16_t param = 0;
if (! pgc_param_word(dev, (int16_t *)&param)) return;
@@ -531,7 +529,7 @@ hndl_linpat(pgc_t *dev)
static void
hndl_prmfil(pgc_t *dev)
{
uint8_t param;
uint8_t param = 0;
if (! pgc_param_byte(dev, &param)) return;
@@ -547,7 +545,7 @@ hndl_prmfil(pgc_t *dev)
static void
hndl_move(pgc_t *dev)
{
int32_t x, y;
int32_t x = 0, y = 0;
if (! pgc_param_coord(dev, &x)) return;
if (! pgc_param_coord(dev, &y)) return;
@@ -563,7 +561,7 @@ hndl_move(pgc_t *dev)
static void
hndl_move3(pgc_t *dev)
{
int32_t x, y, z;
int32_t x = 0, y = 0, z = 0;
if (! pgc_param_coord(dev, &x)) return;
if (! pgc_param_coord(dev, &y)) return;
@@ -579,7 +577,7 @@ hndl_move3(pgc_t *dev)
static void
hndl_mover(pgc_t *dev)
{
int32_t x, y;
int32_t x = 0, y = 0;
if (! pgc_param_coord(dev, &x)) return;
if (! pgc_param_coord(dev, &y)) return;
@@ -593,7 +591,7 @@ hndl_mover(pgc_t *dev)
static void
hndl_mover3(pgc_t *dev)
{
int32_t x, y, z;
int32_t x = 0, y = 0, z = 0;
if (! pgc_param_coord(dev, &x)) return;
if (! pgc_param_coord(dev, &y)) return;
@@ -952,7 +950,7 @@ pgc_draw_ellipse(pgc_t *dev, int32_t x, int32_t y)
static void
hndl_ellipse(pgc_t *dev)
{
int32_t x, y;
int32_t x = 0, y = 0;
if (! pgc_param_coord(dev, &x)) return;
if (! pgc_param_coord(dev, &y)) return;
@@ -1008,6 +1006,8 @@ hndl_display(pgc_t *dev)
if (! pgc_param_byte(dev, &param)) return;
DEBUG("PGC: DISPLAY(%i)\n", param);
if (param > 1)
pgc_error(dev, PGC_ERROR_RANGE);
else
@@ -1253,6 +1253,19 @@ hndl_tjust(pgc_t *dev)
}
/* TSIZE controls text horizontal spacing. */
static void
hndl_tsize(pgc_t *pgc)
{
int32_t param;
if (! pgc_param_coord(pgc, &param)) return;
DEBUG("PGC: TSIZE %i\n", param);
pgc->tsize = param;
}
/*
* VWPORT sets up the viewport (roughly, the clip rectangle) in
* raster coordinates, measured from the bottom left of the screen.
@@ -1369,6 +1382,8 @@ static const pgc_cmd_t pgc_commands[] = {
{ "RF", 0x04, hndl_resetf, NULL, 0 },
{ "TJUST", 0x85, hndl_tjust, pgc_parse_bytes, 2 },
{ "TJ", 0x85, hndl_tjust, pgc_parse_bytes, 2 },
{ "TSIZE", 0x81, hndl_tsize, pgc_parse_coords, 1 },
{ "TS", 0x81, hndl_tsize, pgc_parse_coords, 1 },
{ "VWPORT", 0xb2, hndl_vwport, pgc_parse_words, 4 },
{ "VWP", 0xb2, hndl_vwport, pgc_parse_words, 4 },
{ "WINDOW", 0xb3, hndl_window, pgc_parse_words, 4 },
@@ -1508,6 +1523,8 @@ pgc_reset(pgc_t *dev)
/* The 'CGA disable' jumper is not currently implemented. */
dev->mapram[0x30b] = dev->cga_enabled = 1;
dev->mapram[0x30c] = dev->cga_enabled;
dev->mapram[0x30d] = dev->cga_enabled;
dev->mapram[0x3f8] = 0x03; /* minor version */
dev->mapram[0x3f9] = 0x01; /* minor version */
@@ -1556,6 +1573,9 @@ pgc_reset(pgc_t *dev)
void
pgc_setdisplay(pgc_t *dev, int cga)
{
DEBUG("PGC: setdisplay(%i): cga_selected=%i cga_enabled=%i\n",
cga, dev->cga_selected, dev->cga_enabled);
if (dev->cga_selected != (dev->cga_enabled && cga)) {
dev->cga_selected = (dev->cga_enabled && cga);
@@ -1626,7 +1646,10 @@ pgc_clist_byte(pgc_t *dev, uint8_t *val)
{
if (dev->clcur == NULL) return 0;
*val = dev->clcur->list[dev->clcur->rdptr++];
if (dev->clcur->rdptr < dev->clcur->wrptr)
*val = dev->clcur->list[dev->clcur->rdptr++];
else
*val = 0;
/* If we've reached the end, reset to the beginning and
* (if repeating) run the repeat */
@@ -2139,6 +2162,7 @@ pgc_write(uint32_t addr, uint8_t val, void *priv)
if (dev->mapram[addr] != val) {
dev->mapram[addr] = val;
switch (addr) {
case 0x300: /* input write pointer */
if (dev->waiting_input_fifo &&
@@ -2174,7 +2198,7 @@ pgc_write(uint32_t addr, uint8_t val, void *priv)
dev->mapram[0x30d] = dev->mapram[0x30c];
break;
case 0x3ff: /* reboot the PGC */
case 0x3ff: /* reboot the PGC */
pgc_wake(dev);
break;
}
@@ -2226,9 +2250,8 @@ pgc_cga_text(pgc_t *dev, int w)
ma += (dev->displine / pitch) * w;
for (x = 0; x < w; x++) {
chr = addr[0];
attr = addr[1];
addr += 2;
chr = *addr++;
attr = *addr++;
/* Cursor enabled? */
if (ma == ca && (dev->cgablink & 8) &&
@@ -2239,13 +2262,13 @@ pgc_cga_text(pgc_t *dev, int w)
drawcursor = 0;
if (dev->mapram[0x3d8] & 0x20) {
cols[1] = attr & 15;
cols[0] = (attr >> 4) & 7;
cols[1] = (attr & 15) + 16;
cols[0] = ((attr >> 4) & 7) + 16;
if ((dev->cgablink & 8) && (attr & 0x80) && !drawcursor)
cols[1] = cols[0];
} else {
cols[1] = attr & 15;
cols[0] = attr >> 4;
cols[1] = (attr & 15) + 16;
cols[0] = (attr >> 4) + 16;
}
for (c = 0; c < cw; c++) {
@@ -2272,8 +2295,8 @@ pgc_cga_gfx40(pgc_t *dev)
uint8_t *addr;
uint16_t dat;
cols[0] = dev->mapram[0x3d9] & 15;
col = (dev->mapram[0x3d9] & 16) ? 8 : 0;
cols[0] = (dev->mapram[0x3d9] & 15) + 16;
col = ((dev->mapram[0x3d9] & 16) ? 8 : 0) + 16;
if (dev->mapram[0x3d8] & 4) {
cols[1] = col | 3;
@@ -2312,8 +2335,8 @@ pgc_cga_gfx80(pgc_t *dev)
uint8_t *addr;
uint16_t dat;
cols[0] = 0;
cols[1] = dev->mapram[0x3d9] & 15;
cols[0] = 16;
cols[1] = (dev->mapram[0x3d9] & 15) + 16;
for (x = 0; x < 40; x++) {
addr = &dev->cga_vram[(ma + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff];
@@ -2332,7 +2355,6 @@ void
pgc_cga_poll(pgc_t *dev)
{
uint32_t cols[2];
int c;
if (! dev->linepos) {
dev->vidtime += dev->dispofftime;
@@ -2352,13 +2374,10 @@ pgc_cga_poll(pgc_t *dev)
else
pgc_cga_text(dev, 40);
} else {
cols[0] = ((dev->mapram[0x03d8] & 0x12) == 0x12) ? 0 : (dev->mapram[0x03d9] & 15);
cols[0] = ((dev->mapram[0x03d8] & 0x12) == 0x12) ? 0 : ((dev->mapram[0x03d9] & 15) + 16);
cga_hline(buffer, 0, dev->displine, PGC_CGA_WIDTH, cols[0]);
}
for (c = 0; c < PGC_CGA_WIDTH; c++)
((uint32_t *)buffer32->line[dev->displine])[c] = *((uint32_t *)&cgapal[buffer->line[dev->displine][c] & 0x0f]);
if (++dev->displine == PGC_CGA_HEIGHT) {
dev->mapram[0x3da] |= 8;
dev->cgadispon = 0;
@@ -2383,7 +2402,7 @@ pgc_cga_poll(pgc_t *dev)
if (video_force_resize_get())
video_force_resize_set(0);
}
video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize);
video_blit_memtoscreen_8(0, 0, 0, ysize, xsize, ysize);
frames++;
/* We have a fixed 640x400 screen for CGA modes. */
@@ -2434,14 +2453,13 @@ pgc_poll(void *priv)
* 224. */
y = dev->displine - 2 * dev->pan_y;
for (x = 0; x < dev->screenw; x++) {
if (x + dev->pan_x < dev->maxw) {
buffer->line[dev->displine][x] = dev->palette[dev->vram[y * dev->maxw + x]];
} else {
buffer->line[dev->displine][x] = dev->palette[0];
}
if (x + dev->pan_x < dev->maxw)
((uint32_t *)buffer32->line[dev->displine])[x] = dev->palette[dev->vram[y * dev->maxw + x]];
else
((uint32_t *)buffer32->line[dev->displine])[x] = dev->palette[0];
}
} else {
cga_hline(buffer, 0, dev->displine, dev->screenw, dev->palette[0]);
cga_hline(buffer32, 0, dev->displine, dev->screenw, dev->palette[0]);
}
if (++dev->displine == dev->screenh) {
@@ -2557,7 +2575,6 @@ pgc_init(pgc_t *dev, int maxw, int maxh, int visw, int vish,
dev->pgc_wake_thread = thread_create_event();
dev->pgc_thread = thread_create(pgc_thread, dev);
pclog_repeat(0);
timer_add(pgc_poll, &dev->vidtime, TIMER_ALWAYS_ENABLED, dev);
timer_add(wake_timer, &dev->wake_timer, &dev->wake_timer, (void *)dev);

View File

@@ -8,7 +8,7 @@
*
* Definitions for the PGC driver.
*
* Version: @(#)vid_pgc.h 1.0.2 2019/03/02
* Version: @(#)vid_pgc.h 1.0.2 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* John Elliott, <jce@seasip.info>
@@ -101,6 +101,7 @@ typedef struct pgc {
uint8_t color;
uint8_t tjust_h; /* hor alignment 1=left 2=ctr 3=right*/
uint8_t tjust_v; /* vert alignment 1=bottom 2=ctr 3=top*/
int32_t tsize; /* horizontal spacing */
int32_t x, y, z; /* drawing position */
@@ -126,8 +127,9 @@ typedef struct pgc {
uint16_t ma, maback;
int oddeven;
int dispontime, dispofftime;
int64_t vidtime;
int64_t dispontime,
dispofftime,
vidtime;
int drawcursor;

View File

@@ -41,13 +41,13 @@
* even-numbered columns, so the top bit of the control register
* at 0x2D9 is used to adjust the position.
*
* Version: @(#)vid_sigma.c 1.0.2 2018/11/03
* Version: @(#)vid_sigma.c 1.0.3 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* John Elliott, <jce@seasip.info>
*
* Copyright 2018 Fred N. van Kempen.
* Copyright 2018,2019 Fred N. van Kempen.
* Copyright 2018 Miran Grca.
* Copyright 2018 John Elliott.
*
@@ -165,6 +165,8 @@
typedef struct {
const char *name;
mem_map_t mapping,
bios_ram;
@@ -213,6 +215,8 @@ typedef struct {
int64_t vidtime;
uint8_t *vram;
uint8_t fontdat[256][8]; /* 8x8 font */
uint8_t fontdat16[256][16]; /* 8x16 font */
uint8_t bram[2048];
uint8_t palette[16];
} sigma_t;
@@ -485,16 +489,16 @@ sigma_text80(sigma_t *dev)
if (drawcursor) {
for (c = 0; c < 8; c++) {
if (dev->sigmamode & MODE_FONT16)
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(dev->fontdat16[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
else
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(fontdat[chr][dev->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(dev->fontdat[chr][dev->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
}
} else {
for (c = 0; c < 8; c++) {
if (dev->sigmamode & MODE_FONT16)
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(dev->fontdat16[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
else
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(fontdat[chr][dev->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(dev->fontdat[chr][dev->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
}
++ma;
@@ -540,12 +544,12 @@ sigma_text40(sigma_t *dev)
if (drawcursor) {
for (c = 0; c < 8; c++) {
buffer->line[dev->displine][(x << 4) + 2*c + 8] =
buffer->line[dev->displine][(x << 4) + 2*c + 9] = cols[(fontdatm[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
buffer->line[dev->displine][(x << 4) + 2*c + 9] = cols[(dev->fontdat16[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
}
} else {
for (c = 0; c < 8; c++) {
buffer->line[dev->displine][(x << 4) + 2*c + 8] =
buffer->line[dev->displine][(x << 4) + 2*c + 9] = cols[(fontdatm[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
buffer->line[dev->displine][(x << 4) + 2*c + 9] = cols[(dev->fontdat16[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
}
}
ma++;
@@ -836,11 +840,47 @@ sigma_poll(void *priv)
}
static int
load_font(sigma_t *dev, const wchar_t *s)
{
FILE *fp;
int c;
fp = plat_fopen(rom_path(s), L"rb");
if (fp == NULL) {
ERRLOG("%s: cannot load font '%ls'\n", dev->name, s);
return(0);
}
/* The first 4K of the character ROM holds an 8x8 font. */
for (c = 0; c < 256; c++) {
(void)fread(&dev->fontdat[c][0], 1, 8, fp);
(void)fseek(fp, 8, SEEK_CUR);
}
/* The second 4K holds an 8x16 font. */
for (c = 0; c < 256; c++)
(void)fread(&dev->fontdat16[c][0], 1, 16, fp);
(void)fclose(fp);
return(1);
}
static void *
sigma_init(const device_t *info)
{
sigma_t *dev = malloc(sizeof(sigma_t));
memset(dev, 0, sizeof(sigma_t));
sigma_t *dev;
dev = (sigma_t *)mem_alloc(sizeof(sigma_t));
memset(dev, 0x00, sizeof(sigma_t));
dev->name = info->name;
if (! load_font(dev, FONT_ROM_PATH)) {
free(dev);
return(NULL);
}
dev->enable_nmi = device_get_config_int("enable_nmi");
@@ -855,8 +895,6 @@ sigma_init(const device_t *info)
sigma_read,NULL,NULL, sigma_write,NULL,NULL,
NULL, MEM_MAPPING_EXTERNAL, dev);
video_load_font(FONT_ROM_PATH, 7);
rom_init(&dev->bios_rom, BIOS_ROM_PATH,
0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);

View File

@@ -8,13 +8,13 @@
*
* SVGA renderers.
*
* Version: @(#)vid_svga_render.c 1.0.13 2018/10/22
* Version: @(#)vid_svga_render.c 1.0.14 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
@@ -246,9 +246,9 @@ svga_render_text_80_ksc5601(svga_t *svga)
if(x + xinc < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) {
if ((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff))
dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc];
dat = fontdatk_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc];
else if (nextchr & 0x80)
dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc];
dat = fontdatk[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc];
else
dat = 0xff;
} else {
@@ -292,9 +292,9 @@ svga_render_text_80_ksc5601(svga_t *svga)
}
if ((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff))
dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc + 16];
dat = fontdatk_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc + 16];
else if (nextchr & 0x80)
dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16];
dat = fontdatk[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16];
else
dat = 0xff;

View File

@@ -53,13 +53,13 @@
* What doesn't work, is untested or not well understood:
* - Cursor detach (commands 4 and 5)
*
* Version: @(#)vid_wy700.c 1.0.5 2018/09/22
* Version: @(#)vid_wy700.c 1.0.6 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
@@ -93,13 +93,14 @@
#include "../../timer.h"
#include "../../device.h"
#include "../system/pit.h"
#include "../../plat.h"
#include "video.h"
#define WY700_XSIZE 1280
#define WY700_YSIZE 800
#define BIOS_ROM_PATH L"video/wyse/wyse700/wy700.rom"
#define FONT_ROM_PATH L"video/wyse/wyse700/wy700.rom"
/* The microcontroller sets up the real CRTC with one of five fixed mode
@@ -186,11 +187,9 @@ static const uint8_t mode_40x24[] = {
};
/* Font ROM: Two fonts, each containing 256 characters, 16x16 pixels */
extern uint8_t fontdatw[512][32];
typedef struct {
const char *name;
mem_map_t mapping;
/* The microcontroller works by watching four ports:
@@ -239,6 +238,9 @@ typedef struct {
/* ... and MDA emulation. */
int mdacols[256][2][2];
/* Font ROM: Two fonts, each containing 256 characters, 16x16 pixels */
uint8_t fontdat[512][32];
uint8_t *vram;
} wy700_t;
@@ -528,14 +530,13 @@ text_line(wy700_t *dev)
int cw = (dev->wy700_mode == 0) ? 32 : 16;
uint8_t chr, attr;
uint8_t bitmap[2];
uint8_t *fontbase = &fontdatw[0][0];
uint8_t *fontbase = &dev->fontdat[0][0];
int blink, c;
int drawcursor, cursorline;
int mda = 0;
uint16_t addr;
uint8_t sc;
/* The fake CRTC character height register selects whether MDA or CGA
* attributes are used */
if (dev->cga_crtc[9] == 0 || dev->cga_crtc[9] == 13) {
@@ -854,6 +855,27 @@ wy700_poll(void *priv)
}
static int
load_font(wy700_t *dev, const wchar_t *s)
{
FILE *fp;
int c;
fp = plat_fopen(rom_path(s), L"rb");
if (fp == NULL) {
ERRLOG("%s: cannot load font '%ls'\n", dev->name, s);
return(0);
}
for (c = 0; c < 512; c++)
(void)fread(&dev->fontdat[c][0], 1, 32, fp);
(void)fclose(fp);
return(1);
}
static void *
wy700_init(const device_t *info)
{
@@ -862,12 +884,16 @@ wy700_init(const device_t *info)
dev = (wy700_t *)mem_alloc(sizeof(wy700_t));
memset(dev, 0x00, sizeof(wy700_t));
dev->name = info->name;
/* 128k video RAM */
if (! load_font(dev, FONT_ROM_PATH)) {
free(dev);
return(NULL);
}
/* 128K video RAM */
dev->vram = (uint8_t *)mem_alloc(0x20000);
video_load_font(BIOS_ROM_PATH, 3);
timer_add(wy700_poll, &dev->vidtime, TIMER_ALWAYS_ENABLED, dev);
/* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in
@@ -979,7 +1005,7 @@ wy700_close(void *priv)
static int
wy700_available(void)
{
return rom_present(BIOS_ROM_PATH);
return rom_present(FONT_ROM_PATH);
}

View File

@@ -40,7 +40,7 @@
* W = 3 bus clocks
* L = 4 bus clocks
*
* Version: @(#)video.c 1.0.25 2019/03/02
* Version: @(#)video.c 1.0.25 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -91,14 +91,15 @@
#ifdef ENABLE_VIDEO_LOG
int video_do_log = ENABLE_VIDEO_LOG;
#endif
/* These will go away soon. */
uint8_t fontdat[256][8]; /* IBM CGA font */
uint8_t fontdatm[256][16]; /* IBM MDA font */
dbcs_font_t *fontdatk = NULL, /* Korean KSC-5601 font */
*fontdatk_user = NULL; /* Korean KSC-5601 font (user)*/
bitmap_t *buffer = NULL,
*buffer32 = NULL;
uint8_t fontdat[2048][8]; /* IBM CGA font */
uint8_t fontdatm[2048][16]; /* IBM MDA font */
uint8_t fontdatw[512][32]; /* Wyse700 font */
uint8_t fontdat8x12[256][16]; /* MDSI Genius font */
dbcs_font_t *fontdatksc5601 = NULL, /* Korean KSC-5601 font */
*fontdatksc5601_user = NULL; /* Korean KSC-5601 font (user)*/
uint32_t pal_lookup[256];
int xsize = 1,
ysize = 1;
@@ -884,14 +885,14 @@ video_type(void)
void
video_reset_font(void)
{
if (fontdatksc5601 != NULL) {
free(fontdatksc5601);
fontdatksc5601 = NULL;
if (fontdatk != NULL) {
free(fontdatk);
fontdatk = NULL;
}
if (fontdatksc5601_user != NULL) {
free(fontdatksc5601_user);
fontdatksc5601_user = NULL;
if (fontdatk_user != NULL) {
free(fontdatk_user);
fontdatk_user = NULL;
}
}
@@ -901,11 +902,11 @@ void
video_load_font(const wchar_t *s, int format)
{
FILE *fp;
int c, d;
int c;
fp = plat_fopen(rom_path(s), L"rb");
if (fp == NULL) {
ERRLOG("VIDEO: cannot load font '%ls', fmt=%d\n", s, format);
ERRLOG("VIDEO: cannot load font '%ls', fmt=%i\n", s, format);
return;
}
@@ -917,81 +918,15 @@ video_load_font(const wchar_t *s, int format)
(void)fread(&fontdatm[c][8], 1, 8, fp);
break;
case 1: /* PC200 */
for (c = 0; c < 256; c++)
(void)fread(&fontdatm[c][0], 1, 8, fp);
for (c = 0; c < 256; c++)
(void)fread(&fontdatm[c][8], 1, 8, fp);
(void)fseek(fp, 4096, SEEK_SET);
for (c = 0; c < 256; c++) {
(void)fread(&fontdat[c][0], 1, 8, fp);
for (d = 0; d < 8; d++)
(void)fgetc(fp);
}
break;
case 2: /* CGA, thin font */
case 8: /* CGA, thick font */
if (format == 8) {
case 1: /* CGA, thin font */
case 2: /* CGA, thick font */
if (format == 2) {
/* Use the second ("thick") font in the ROM. */
(void)fseek(fp, 2048, SEEK_SET);
}
for (c = 0; c < 256; c++)
(void)fread(&fontdat[c][0], 1, 8, fp);
break;
case 3: /* Wyse 700 */
for (c = 0; c < 512; c++)
(void)fread(&fontdatw[c][0], 1, 32, fp);
break;
case 4: /* MDSI Genius */
for (c = 0; c < 256; c++)
(void)fread(&fontdat8x12[c][0], 1, 16, fp);
break;
case 5: /* Toshiba 3100e */
for (d = 0; d < 2048; d += 512) { /* Four languages... */
for (c = d; c < d+256; c++)
(void)fread(&fontdatm[c][8], 1, 8, fp);
for (c = d+256; c < d+512; c++)
(void)fread(&fontdatm[c][8], 1, 8, fp);
for (c = d; c < d+256; c++)
(void)fread(&fontdatm[c][0], 1, 8, fp);
for (c = d+256; c < d+512; c++)
(void)fread(&fontdatm[c][0], 1, 8, fp);
(void)fseek(fp, 4096, SEEK_CUR); /* Skip blank section */
for (c = d; c < d+256; c++)
(void)fread(&fontdat[c][0], 1, 8, fp);
for (c = d+256; c < d+512; c++)
(void)fread(&fontdat[c][0], 1, 8, fp);
}
break;
case 6: /* Korean KSC-5601 */
if (fontdatksc5601 == NULL)
fontdatksc5601 = (dbcs_font_t *)mem_alloc(16384 * sizeof(dbcs_font_t));
if (fontdatksc5601_user == NULL)
fontdatksc5601_user = (dbcs_font_t *)mem_alloc(192 * sizeof(dbcs_font_t));
for (c = 0; c < 16384; c++) {
for (d = 0; d < 32; d++)
fontdatksc5601[c].chr[d] = fgetc(fp);
}
break;
case 7: /* Sigma Color 400 */
/* The first 4K of the character ROM holds an 8x8 font. */
for (c = 0; c < 256; c++) {
(void)fread(&fontdat[c][0], 1, 8, fp);
(void)fseek(fp, 8, SEEK_CUR);
}
/* The second 4K holds an 8x16 font. */
for (c = 0; c < 256; c++)
(void)fread(&fontdatm[c][0], 1, 16, fp);
break;
}
DEBUG("VIDEO: font #%i loaded\n", format);

View File

@@ -8,7 +8,7 @@
*
* Definitions for the video controller module.
*
* Version: @(#)video.h 1.0.26 2019/03/01
* Version: @(#)video.h 1.0.27 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -113,16 +113,17 @@ typedef rgb_t PALETTE[256];
extern int changeframecount;
/* These will go away soon. */
extern uint8_t fontdat[256][8];
extern uint8_t fontdatm[256][16];
extern dbcs_font_t *fontdatk,
*fontdatk_user;
extern bitmap_t *buffer,
*buffer32;
extern PALETTE cgapal,
cgapal_mono[6];
extern uint32_t pal_lookup[256];
extern uint8_t fontdat[2048][8];
extern uint8_t fontdatm[2048][16];
extern uint8_t fontdat8x12[256][16];
extern dbcs_font_t *fontdatksc5601,
*fontdatksc5601_user;
extern uint32_t *video_6to8,
*video_15to32,
*video_16to32;
@@ -335,6 +336,10 @@ extern void video_wait_for_buffer(void);
extern void cgapal_rebuild(void);
#ifdef VIDEO_SVGA_H
extern int ati28800k_load_font(svga_t *, const wchar_t *);
#endif
extern void video_log(int level, const char *fmt, ...);
extern void video_init(void);
extern void video_close(void);

View File

@@ -12,7 +12,7 @@
* "extern" reference to its device into the video.h file,
* and add an entry for it into the table here.
*
* Version: @(#)video_dev.c 1.0.32 2019/03/02
* Version: @(#)video_dev.c 1.0.32 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -68,9 +68,7 @@ static const struct {
/* Standard video controllers. */
{ "mda", &mda_device },
{ "cga", &cga_device },
#if defined(DEV_BRANCH)
{ "pgc", &pgc_device },
#endif
{ "ega", &ega_device },
{ "vga", &vga_device },
{ "hercules", &hercules_device },
@@ -105,9 +103,7 @@ static const struct {
{ "hercules_plus", &herculesplus_device },
{ "incolor", &incolor_device },
{ "genius", &genius_device },
#if defined(DEV_BRANCH)
{ "im1024", &im1024_device },
#endif
{ "oti037c", &oti037c_device },
{ "oti067", &oti067_device },
{ "oti077", &oti077_device },

View File

@@ -32,7 +32,7 @@
* BIOSES: I need to re-do the bios.txt format so we can load non-BIOS
* ROM files for a given machine, such as font roms here..
*
* Version: @(#)m_amstrad.c 1.0.21 2019/02/16
* Version: @(#)m_amstrad.c 1.0.22 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -88,6 +88,7 @@
#include "../devices/video/video.h"
#include "../devices/video/vid_cga.h"
#include "../devices/video/vid_ega.h"
#include "../plat.h"
#include "machine.h"
@@ -132,6 +133,7 @@ typedef struct {
int firstline,
lastline;
uint8_t *vram;
uint8_t fontdat[256][8]; /* 1512/200 */
} amsvid_t;
typedef struct {
@@ -346,10 +348,10 @@ vid_poll_1512(void *priv)
}
if (drawcursor) {
for (c = 0; c < 8; c++)
buffer->line[vid->displine][(x << 3) + c + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
buffer->line[vid->displine][(x << 3) + c + 8] = cols[(vid->fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
} else {
for (c = 0; c < 8; c++)
buffer->line[vid->displine][(x << 3) + c + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
buffer->line[vid->displine][(x << 3) + c + 8] = cols[(vid->fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
vid->ma++;
}
@@ -371,11 +373,11 @@ vid_poll_1512(void *priv)
if (drawcursor) {
for (c = 0; c < 8; c++)
buffer->line[vid->displine][(x << 4) + (c << 1) + 8] =
buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(vid->fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
} else {
for (c = 0; c < 8; c++)
buffer->line[vid->displine][(x << 4) + (c << 1) + 8] =
buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(vid->fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
}
}
} else if (! (vid->cgamode & 16)) {
@@ -533,14 +535,31 @@ vid_poll_1512(void *priv)
static void
vid_init_1512(amstrad_t *ams)
vid_init_1512(amstrad_t *ams, const wchar_t *fn, int num)
{
amsvid_t *vid;
FILE *fp;
int c;
/* Allocate a video controller block. */
vid = (amsvid_t *)mem_alloc(sizeof(amsvid_t));
memset(vid, 0x00, sizeof(amsvid_t));
/* Load the PC1512 CGA Character Set ROM. */
fp = plat_fopen(rom_path(fn), L"rb");
if (fp != NULL) {
if (num == 8) {
/* Use the second ("thick") font in the ROM. */
(void)fseek(fp, 2048, SEEK_SET);
}
for (c = 0; c < 256; c++)
(void)fread(&vid->fontdat[c][0], 1, 8, fp);
(void)fclose(fp);
} else {
ERRLOG("AMSTRAD: cannot load font '%ls'\n", fn);
return;
}
vid->vram = (uint8_t *)mem_alloc(0x10000);
vid->cgacol = 7;
vid->cgamode = 0x12;
@@ -581,8 +600,7 @@ vid_speed_change_1512(void *priv)
static const device_t vid_1512_device = {
"Amstrad PC1512 (video)",
0,
0,
0, 0,
NULL, vid_close_1512, NULL,
NULL,
vid_speed_change_1512,
@@ -752,8 +770,7 @@ vid_speed_changed_1640(void *priv)
static const device_t vid_1640_device = {
"Amstrad PC1640 (video)",
0,
0,
0, 0,
NULL, vid_close_1640, NULL,
NULL,
vid_speed_changed_1640,
@@ -841,15 +858,40 @@ vid_in_200(uint16_t addr, void *priv)
static void
vid_init_200(amstrad_t *ams)
vid_init_200(amstrad_t *ams, const wchar_t *fn)
{
amsvid_t *vid;
cga_t *cga;
FILE *fp;
int c, d;
/* Allocate a video controller block. */
vid = (amsvid_t *)mem_alloc(sizeof(amsvid_t));
memset(vid, 0x00, sizeof(amsvid_t));
/* Load the PC200 CGA Character Set ROM. */
fp = plat_fopen(rom_path(fn), L"rb");
if (fp != NULL) {
for (c = 0; c < 256; c++)
(void)fread(&fontdatm[c][0], 1, 8, fp);
for (c = 0; c < 256; c++)
(void)fread(&fontdatm[c][8], 1, 8, fp);
(void)fseek(fp, 4096, SEEK_SET);
for (c = 0; c < 256; c++) {
(void)fread(&fontdat[c][0], 1, 8, fp);
for (d = 0; d < 8; d++)
(void)fgetc(fp);
}
(void)fclose(fp);
} else {
ERRLOG("AMSTRAD: cannot load font '%ls'\n", fn);
return;
}
cga = &vid->cga;
cga->vram = (uint8_t *)mem_alloc(0x4000);
cga_init(cga);
@@ -891,8 +933,7 @@ vid_speed_changed_200(void *priv)
static const device_t vid_200_device = {
"Amstrad PC200 (video)",
0,
0,
0, 0,
NULL, vid_close_200, NULL,
NULL,
vid_speed_changed_200,
@@ -1219,6 +1260,59 @@ amstrad_common_init(const machine_t *model, void *arg, int type)
machine_common_init(model, arg);
nmi_init();
switch(ams->type) {
case 0: /* 1512 */
device_add(&fdc_xt_device);
if (video_card == VID_INTERNAL) {
/* Initialize the internal CGA controller. */
vid_init_1512(ams, roms->fontfn, roms->fontnum);
device_add_ex(&vid_1512_device, ams->vid);
}
break;
case 1: /* 1640 */
device_add(&fdc_xt_device);
if (video_card == VID_INTERNAL) {
/* Initialize the internal CGA/EGA controller. */
vid_init_1640(ams, roms->vidfn, roms->vidsz);
device_add_ex(&vid_1640_device, ams->vid);
}
break;
case 2: /* PC200 */
device_add(&fdc_xt_device);
if (video_card == VID_INTERNAL) {
/* Initialize the internal CGA controller. */
vid_init_200(ams, roms->fontfn);
device_add_ex(&vid_200_device, ams->vid);
}
break;
case 3: /* PC2086 */
device_add(&fdc_at_actlow_device);
if (video_card == VID_INTERNAL) {
device_add(&paradise_pvga1a_pc2086_device);
video_inform(VID_TYPE_SPEC, &pvga1a_timing);
}
break;
case 4: /* PC3086 */
device_add(&fdc_at_actlow_device);
if (video_card == VID_INTERNAL) {
device_add(&paradise_pvga1a_pc3086_device);
video_inform(VID_TYPE_SPEC, &pvga1a_timing);
}
break;
case 5: /* MEGAPC */
device_add(&fdc_at_actlow_device);
if (video_card == VID_INTERNAL) {
device_add(&paradise_wd90c11_megapc_device);
video_inform(VID_TYPE_SPEC, &wd90c11_timing);
}
break;
}
device_add(&amstrad_nvr_device);
@@ -1235,64 +1329,6 @@ amstrad_common_init(const machine_t *model, void *arg, int type)
io_sethandler(0xdead, 1,
ams_read, NULL, NULL, ams_write, NULL, NULL, ams);
switch(ams->type) {
case 0:
device_add(&fdc_xt_device);
if (video_card == VID_INTERNAL) {
/* Load the PC1512 CGA Character Set ROM. */
video_load_font(roms->fontfn, roms->fontnum);
/* Initialize the internal CGA controller. */
vid_init_1512(ams);
device_add_ex(&vid_1512_device, ams->vid);
}
break;
case 1:
device_add(&fdc_xt_device);
if (video_card == VID_INTERNAL) {
/* Load the BIOS for the internal CGA/EGA. */
vid_init_1640(ams, roms->vidfn, roms->vidsz);
device_add_ex(&vid_1640_device, ams->vid);
}
break;
case 2:
device_add(&fdc_xt_device);
if (video_card == VID_INTERNAL) {
/* Load the PC200 CGA Character Set ROM. */
video_load_font(roms->fontfn, roms->fontnum);
vid_init_200(ams);
device_add_ex(&vid_200_device, ams->vid);
}
break;
case 3:
device_add(&fdc_at_actlow_device);
if (video_card == VID_INTERNAL) {
device_add(&paradise_pvga1a_pc2086_device);
video_inform(VID_TYPE_SPEC, &pvga1a_timing);
}
break;
case 4:
device_add(&fdc_at_actlow_device);
if (video_card == VID_INTERNAL) {
device_add(&paradise_pvga1a_pc3086_device);
video_inform(VID_TYPE_SPEC, &pvga1a_timing);
}
break;
case 5:
device_add(&fdc_at_actlow_device);
if (video_card == VID_INTERNAL) {
device_add(&paradise_wd90c11_megapc_device);
video_inform(VID_TYPE_SPEC, &wd90c11_timing);
}
break;
}
/* Initialize the (custom) keyboard/mouse interface. */
ams->wantirq = 0;

View File

@@ -22,13 +22,13 @@
* 61 50 52 0F 19 06 19 19 02 0D 0B 0C MONO
* 2D 28 22 0A 67 00 64 67 02 03 06 07 640x400
*
* Version: @(#)m_at_t3100e_vid.c 1.0.6 2018/09/22
* Version: @(#)m_at_t3100e_vid.c 1.0.7 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk>
*
* Copyright 2017,2018 Fred N. van Kempen.
* Copyright 2017-2019 Fred N. van Kempen.
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
@@ -59,15 +59,18 @@
#include "../cpu/cpu.h"
#include "../io.h"
#include "../mem.h"
#include "../rom.h"
#include "../timer.h"
#include "../device.h"
#include "../devices/video/video.h"
#include "../devices/video/vid_cga.h"
#include "../plat.h"
#include "m_at_t3100e.h"
#define T3100E_XSIZE 640
#define T3100E_YSIZE 400
#define FONT_ROM_PATH L"machines/toshiba/t3100e/t3100e_font.bin"
#define T3100E_XSIZE 640
#define T3100E_YSIZE 400
/* Mapping of attributes to colours */
@@ -108,6 +111,9 @@ typedef struct {
uint8_t video_options;
uint8_t *vram;
uint8_t fontdat[2048][8];
uint8_t fontdatm[2048][16];
} t3100e_t;
@@ -363,11 +369,11 @@ text_row80(t3100e_t *dev)
if (drawcursor) {
for (c = 0; c < 8; c++) {
((uint32_t *)buffer32->line[dev->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
((uint32_t *)buffer32->line[dev->displine])[(x << 3) + c] = cols[(dev->fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
}
} else {
for (c = 0; c < 8; c++)
((uint32_t *)buffer32->line[dev->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
((uint32_t *)buffer32->line[dev->displine])[(x << 3) + c] = cols[(dev->fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
}
++ma;
}
@@ -427,11 +433,11 @@ text_row40(t3100e_t *dev)
if (drawcursor) {
for (c = 0; c < 8; c++) {
((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2] = ((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2 + 1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2] = ((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2 + 1] = cols[(dev->fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
}
} else {
for (c = 0; c < 8; c++) {
((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2] = ((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2+1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2] = ((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2+1] = cols[(dev->fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
}
}
++ma;
@@ -640,6 +646,44 @@ t3100e_poll(void *priv)
}
static int
load_font(t3100e_t *dev, const wchar_t *s)
{
FILE *fp;
int c, d;
fp = plat_fopen(rom_path(s), L"rb");
if (fp == NULL) {
ERRLOG("T3100e: cannot load font '%ls'\n", s);
return(0);
}
/* Fonts for 4 languages... */
for (d = 0; d < 2048; d += 512) {
for (c = d; c < d+256; c++)
(void)fread(&dev->fontdatm[c][8], 1, 8, fp);
for (c = d+256; c < d+512; c++)
(void)fread(&dev->fontdatm[c][8], 1, 8, fp);
for (c = d; c < d+256; c++)
(void)fread(&dev->fontdatm[c][0], 1, 8, fp);
for (c = d+256; c < d+512; c++)
(void)fread(&dev->fontdatm[c][0], 1, 8, fp);
/* Skip blank section. */
(void)fseek(fp, 4096, SEEK_CUR);
for (c = d; c < d+256; c++)
(void)fread(&dev->fontdat[c][0], 1, 8, fp);
for (c = d+256; c < d+512; c++)
(void)fread(&dev->fontdat[c][0], 1, 8, fp);
}
(void)fclose(fp);
return(1);
}
static void *
t3100e_init(const device_t *info)
{
@@ -648,6 +692,11 @@ t3100e_init(const device_t *info)
dev = (t3100e_t *)mem_alloc(sizeof(t3100e_t));
memset(dev, 0x00, sizeof(t3100e_t));
if (! load_font(dev, FONT_ROM_PATH)) {
free(dev);
return(NULL);
}
cga_init(&dev->cga);
dev->internal = 1;

View File

@@ -8,7 +8,7 @@
*
* Handling of the emulated machines.
*
* Version: @(#)machine_table.c 1.0.34 2019/02/16
* Version: @(#)machine_table.c 1.0.35 2019/03/03
*
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com>
@@ -115,7 +115,7 @@ const machine_t machines[] = {
{ "[286 ISA] Hyundai Super-286TR", "hyundai_super286tr", L"hyundai/super286tr", 8, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 128, m_at_scat_init, NULL, NULL },
{ "[286 ISA] Samsung SPC-4200P", "samsung_spc4200p", L"samsung/spc4200p", 8, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 512, 2048, 128, 128, m_at_scat_init, NULL, NULL },
{ "[286 ISA] Samsung SPC-4216P", "samsung_spc4216p", L"samsung/spc4216p", 8, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 1, 5, 1, 128, m_at_scat_spc4216p_init, NULL, NULL },
{ "[286 ISA] Toshiba T3100e", "toshiba_t3100e", L"toshiba/t3100e", 8, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1024, 5120, 256, 64, m_at_t3100e_init, NULL, NULL },
{ "[286 ISA] Toshiba T3100e", "toshiba_t3100e", L"toshiba/t3100e", 8, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_HDC, 1024, 5120, 256, 64, m_at_t3100e_init, NULL, NULL },
{ "[286 ISA] Trigem 286M", "tg286m", L"trigem/tg286m", 8, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 128, m_at_tg286m_init, NULL, NULL },
{ "[286 MCA] IBM PS/2 model 50", "ibm_ps2_m50", L"ibm/ps2_m50", -1, {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC_PS2, 1, 10, 1, 64, m_ps2_model_50_init, NULL, NULL },