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) * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -49,7 +49,7 @@
#include "video.h" #include "video.h"
#include "vid_svga.h" #include "vid_svga.h"
#include "vid_svga_render.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" # 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) * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -47,11 +47,12 @@
#include "../../mem.h" #include "../../mem.h"
#include "../../rom.h" #include "../../rom.h"
#include "../../device.h" #include "../../device.h"
#include "../../plat.h"
#include "video.h" #include "video.h"
#include "vid_svga.h" #include "vid_svga.h"
#include "vid_svga_render.h" #include "vid_svga_render.h"
#include "vid_sc1502x_ramdac.h" #include "vid_sc1502x_ramdac.h"
#include "vid_ati_eeprom.h" #include "vid_ati.h"
enum { enum {
@@ -220,7 +221,7 @@ ati28800k_out(uint16_t port, uint8_t val, void *priv)
dev->in_get_korean_font_kind_set = 0; dev->in_get_korean_font_kind_set = 0;
if (dev->get_korean_font_enabled) { if (dev->get_korean_font_enabled) {
if ((dev->get_korean_font_base & 0x7F) > 0x20 && (dev->get_korean_font_base & 0x7F) < 0x7F) 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++;
dev->get_korean_font_index &= 0x1F; dev->get_korean_font_index &= 0x1F;
} else { } else {
@@ -337,12 +338,12 @@ ati28800k_in(uint16_t port, void *priv)
if (dev->get_korean_font_enabled) { if (dev->get_korean_font_enabled) {
switch(dev->get_korean_font_kind >> 8) { switch(dev->get_korean_font_kind >> 8) {
case 4: /* ROM font */ 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; break;
case 2: /* User defined font */ case 2: /* User defined font */
if ((dev->get_korean_font_base & 0x7F) > 0x20 && (dev->get_korean_font_base & 0x7F) < 0x7F) 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 else
ret = 0xff; ret = 0xff;
dev->get_korean_font_index++; 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 * static void *
ati28800_init(const device_t *info) 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->in_get_korean_font_kind_set = 0;
dev->ksc5601_mode_enabled = 0; dev->ksc5601_mode_enabled = 0;
video_load_font(FONT_ATIKOR_PATH, 6);
rom_init(&dev->bios_rom, BIOS_ATIKOR_PATH, rom_init(&dev->bios_rom, BIOS_ATIKOR_PATH,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
ati_eeprom_load(&dev->eeprom, L"atikorvga.nvr", 0); ati_eeprom_load(&dev->eeprom, L"atikorvga.nvr", 0);
@@ -533,6 +570,14 @@ ati28800_init(const device_t *info)
dev->svga.miscout = 1; 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, video_inform(VID_TYPE_SPEC,
(const video_timings_t *)info->vid_timing); (const video_timings_t *)info->vid_timing);

View File

@@ -8,13 +8,13 @@
* *
* Emulation of the EEPROM on select ATI cards. * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk> * 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 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker. * Copyright 2008-2018 Sarah Walker.
* *
@@ -44,215 +44,208 @@
#include "../../mem.h" #include "../../mem.h"
#include "../../nvr.h" #include "../../nvr.h"
#include "../../plat.h" #include "../../plat.h"
#include "vid_ati_eeprom.h" #include "vid_ati.h"
enum enum {
{ EEPROM_IDLE,
EEPROM_IDLE, EEPROM_WAIT,
EEPROM_WAIT, EEPROM_OPCODE,
EEPROM_OPCODE, EEPROM_INPUT,
EEPROM_INPUT, EEPROM_OUTPUT
EEPROM_OUTPUT
}; };
enum enum {
{ EEPROM_OP_EW = 4,
EEPROM_OP_EW = 4, EEPROM_OP_WRITE = 5,
EEPROM_OP_WRITE = 5, EEPROM_OP_READ = 6,
EEPROM_OP_READ = 6, EEPROM_OP_ERASE = 7,
EEPROM_OP_ERASE = 7,
EEPROM_OP_WRALMAIN = -1 EEPROM_OP_WRALMAIN = -1
}; };
enum enum {
{ EEPROM_OP_EWDS = 0,
EEPROM_OP_EWDS = 0, EEPROM_OP_WRAL = 1,
EEPROM_OP_WRAL = 1, EEPROM_OP_ERAL = 2,
EEPROM_OP_ERAL = 2, EEPROM_OP_EWEN = 3
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; dev->type = type;
memset(eeprom->data, 0, eeprom->type ? 512 : 128); memset(dev->data, 0, dev->type ? 512 : 128);
wcscpy(eeprom->fn, fn); wcscpy(dev->fn, fn);
f = plat_fopen(nvr_path(eeprom->fn), L"rb"); fp = plat_fopen(nvr_path(dev->fn), L"rb");
if (f != NULL) if (fp != NULL) {
{ (void)fread(dev->data, 1, dev->type ? 512 : 128, fp);
(void)fread(eeprom->data, 1, eeprom->type ? 512 : 128, f); fclose(fp);
fclose(f); }
}
} }
void ati_eeprom_save(ati_eeprom_t *eeprom)
{
FILE *f = plat_fopen(nvr_path(eeprom->fn), L"wb");
if (f != NULL) { void
(void)fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f); ati_eeprom_save(ati_eeprom_t *dev)
fclose(f); {
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; return dev->out;
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;
} }
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. * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk> * 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 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker. * Copyright 2008-2018 Sarah Walker.
* *
@@ -51,7 +51,7 @@
#include "video.h" #include "video.h"
#include "vid_svga.h" #include "vid_svga.h"
#include "vid_svga_render.h" #include "vid_svga_render.h"
#include "vid_ati_eeprom.h" #include "vid_ati.h"
#include "vid_ati68860_ramdac.h" #include "vid_ati68860_ramdac.h"
#include "vid_ics2595.h" #include "vid_ics2595.h"

View File

@@ -8,7 +8,7 @@
* *
* Emulation of the old and new IBM CGA graphics cards. * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -649,7 +649,7 @@ cga_standalone_init(const device_t *info)
cga_palette = (dev->rgb_type << 1); cga_palette = (dev->rgb_type << 1);
cgapal_rebuild(); 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); video_inform(VID_TYPE_CGA, info->vid_timing);

View File

@@ -8,14 +8,14 @@
* *
* Emulation of the Tseng Labs ET4000. * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* GreatPsycho, <greatpsycho@yahoo.com> * GreatPsycho, <greatpsycho@yahoo.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk> * 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 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker. * Copyright 2008-2018 Sarah Walker.
* *
@@ -51,6 +51,7 @@
#include "video.h" #include "video.h"
#include "vid_svga.h" #include "vid_svga.h"
#include "vid_svga_render.h" #include "vid_svga_render.h"
#include "vid_ati.h" /* for the font loader */
#include "vid_sc1502x_ramdac.h" #include "vid_sc1502x_ramdac.h"
@@ -155,7 +156,7 @@ et4000k_in(uint16_t addr, void *priv)
switch(dev->get_korean_font_enabled) { switch(dev->get_korean_font_enabled) {
case 3: case 3:
if ((dev->port_32cb_val & 0x30) == 0x30) { 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; dev->get_korean_font_index &= 0x1f;
} else } else
if ((dev->port_32cb_val & 0x30) == 0x20 && 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) { switch(dev->get_korean_font_base & 0x3f80) {
case 0x2480: case 0x2480:
if (dev->get_korean_font_index < 16) 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 else
if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40) 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; break;
case 0x3f00: case 0x3f00:
if (dev->get_korean_font_index < 16) 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 else
if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40) 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; break;
default: default:
@@ -358,18 +359,18 @@ et4000k_out(uint16_t addr, uint8_t val, void *priv)
switch (dev->get_korean_font_base & 0x3f80) { switch (dev->get_korean_font_base & 0x3f80) {
case 0x2480: case 0x2480:
if (dev->get_korean_font_index < 16) 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 else
if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40) 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; break;
case 0x3f00: case 0x3f00:
if (dev->get_korean_font_index < 16) 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 else
if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40) 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; break;
default: default:
@@ -487,9 +488,11 @@ et4000_init(const device_t *info)
switch(dev->type) { switch(dev->type) {
case 0: /* ISA ET4000AX */ case 0: /* ISA ET4000AX */
dev->vram_size = device_get_config_int("memory") << 10; dev->vram_size = device_get_config_int("memory") << 10;
svga_init(&dev->svga, dev, dev->vram_size, svga_init(&dev->svga, dev, dev->vram_size,
et4000_recalctimings, et4000_in, et4000_out, et4000_recalctimings, et4000_in, et4000_out,
NULL, NULL); NULL, NULL);
io_sethandler(0x03c0, 32, io_sethandler(0x03c0, 32,
et4000_in,NULL,NULL, et4000_out,NULL,NULL, dev); et4000_in,NULL,NULL, et4000_out,NULL,NULL, dev);
break; break;
@@ -497,11 +500,14 @@ et4000_init(const device_t *info)
case 1: /* MCA ET4000AX */ case 1: /* MCA ET4000AX */
dev->is_mca = 1; dev->is_mca = 1;
dev->vram_size = 1024 << 10; dev->vram_size = 1024 << 10;
svga_init(&dev->svga, dev, dev->vram_size, svga_init(&dev->svga, dev, dev->vram_size,
et4000_recalctimings, et4000_in, et4000_out, et4000_recalctimings, et4000_in, et4000_out,
NULL, NULL); NULL, NULL);
io_sethandler(0x03c0, 32, io_sethandler(0x03c0, 32,
et4000_in,NULL,NULL, et4000_out,NULL,NULL, dev); et4000_in,NULL,NULL, et4000_out,NULL,NULL, dev);
dev->pos_regs[0] = 0xf2; /* ET4000 MCA board ID */ dev->pos_regs[0] = 0xf2; /* ET4000 MCA board ID */
dev->pos_regs[1] = 0x80; dev->pos_regs[1] = 0x80;
mca_add(et4000_mca_read, et4000_mca_write, dev); 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_22cb_val = 0x60;
dev->port_32cb_val = 0; dev->port_32cb_val = 0;
dev->svga.ksc5601_sbyte_mask = 0x80; dev->svga.ksc5601_sbyte_mask = 0x80;
svga_init(&dev->svga, dev, dev->vram_size, svga_init(&dev->svga, dev, dev->vram_size,
et4000_recalctimings, et4000k_in, et4000k_out, et4000_recalctimings, et4000k_in, et4000k_out,
NULL, NULL); NULL, NULL);
if (! ati28800k_load_font(&dev->svga, KOREAN_FONT_ROM_PATH)) {
svga_close(&dev->svga);
free(dev);
return(NULL);
}
io_sethandler(0x03c0, 32, io_sethandler(0x03c0, 32,
et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev); et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev);
io_sethandler(0x22cb, 1, io_sethandler(0x22cb, 1,
@@ -524,7 +538,6 @@ et4000_init(const device_t *info)
et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev); et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev);
io_sethandler(0x32cb, 1, io_sethandler(0x32cb, 1,
et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev); et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev);
video_load_font(KOREAN_FONT_ROM_PATH, 6);
fn = KOREAN_BIOS_ROM_PATH; fn = KOREAN_BIOS_ROM_PATH;
break; break;
} }
@@ -536,7 +549,7 @@ et4000_init(const device_t *info)
rom_init(&dev->bios_rom, fn, rom_init(&dev->bios_rom, fn,
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); 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, video_inform(VID_TYPE_SPEC,
(const video_timings_t *)info->vid_timing); (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 * reducing the height of characters so they fit in an 8x12 cell
* if necessary. * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* John Elliott, <jce@seasip.info> * 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 Miran Grca.
* Copyright 2016-2018 John Elliott. * Copyright 2016-2018 John Elliott.
* *
@@ -107,7 +107,7 @@
#include "video.h" #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 #define GENIUS_XSIZE 728
@@ -115,6 +115,8 @@
typedef struct { typedef struct {
const char *name;
mem_map_t mapping; mem_map_t mapping;
uint8_t mda_crtc[32]; /* The 'CRTC' as the host PC sees it */ uint8_t mda_crtc[32]; /* The 'CRTC' as the host PC sees it */
@@ -154,6 +156,8 @@ typedef struct {
int cols[256][2][2]; int cols[256][2][2];
uint8_t fontdat[256][16];
uint8_t *vram; uint8_t *vram;
} genius_t; } genius_t;
@@ -369,7 +373,7 @@ text_line(genius_t *dev, uint8_t background)
} }
} else { } else {
/* Draw 8 pixels of character */ /* Draw 8 pixels of character */
bitmap[0] = fontdat8x12[chr][sc]; bitmap[0] = dev->fontdat[chr][sc];
for (c = 0; c < 8; c++) { for (c = 0; c < 8; c++) {
col = dev->cols[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0]; col = dev->cols[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0];
if (!(dev->enabled) || !(dev->mda_ctrl & 8)) 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 * static void *
genius_init(const device_t *info) genius_init(const device_t *info)
{ {
@@ -567,12 +592,16 @@ genius_init(const device_t *info)
dev = (genius_t *)mem_alloc(sizeof(genius_t)); dev = (genius_t *)mem_alloc(sizeof(genius_t));
memset(dev, 0x00, 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 */ /* 160k video RAM */
dev->vram = (uint8_t *)mem_alloc(0x28000); dev->vram = (uint8_t *)mem_alloc(0x28000);
video_load_font(BIOS_ROM_PATH, 4);
timer_add(genius_poll, &dev->vidtime, TIMER_ALWAYS_ENABLED, dev); timer_add(genius_poll, &dev->vidtime, TIMER_ALWAYS_ENABLED, dev);
/* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in
@@ -645,7 +674,7 @@ genius_close(void *priv)
static int static int
genius_available(void) 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 * This is implemented by holding a FIFO of unlimited depth in
* the IM1024 to receive the data. * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* John Elliott, <jce@seasip.info> * John Elliott, <jce@seasip.info>
@@ -99,16 +99,14 @@ typedef struct {
static void static void
fifo_write(im1024_t *dev, uint8_t val) fifo_write(im1024_t *dev, uint8_t val)
{ {
#if 0 DBGLOG(1, "IM1024: fifo_write: %02x [rd=%04x wr=%04x]\n",
DEBUG(("IM1024: fifo_write: %02x [rd=%04x wr=%04x]\n", val, dev->fifo_rdptr, dev->fifo_wrptr);
val, dev->fifo_rdptr, dev->fifo_wrptr));
#endif
if (((dev->fifo_wrptr + 1) % dev->fifo_len) == dev->fifo_rdptr) { if (((dev->fifo_wrptr + 1) % dev->fifo_len) == dev->fifo_rdptr) {
/* FIFO is full. Double its size. */ /* FIFO is full. Double its size. */
uint8_t *buf; 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); dev->fifo_len, 2 * dev->fifo_len);
buf = realloc(dev->fifo, 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; dev->fifo_len *= 2;
} }
/* Append to the queue */ /* Append to the queue. */
dev->fifo[dev->fifo_wrptr++] = val; 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) if (dev->fifo_wrptr >= dev->fifo_len)
dev->fifo_wrptr = 0; 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 * Where a normal PGC would just read from the ring buffer at 0xC6300,
* FIFO has priority. */ * the IM-1024 can read from either this or from its internal FIFO.
*
* The internal FIFO has priority.
*/
static int static int
input_byte(pgc_t *pgc, uint8_t *result) input_byte(pgc_t *pgc, uint8_t *result)
{ {
im1024_t *dev = (im1024_t *)pgc; 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) && while ((dev->fifo_wrptr == dev->fifo_rdptr) &&
(pgc->mapram[0x300] == pgc->mapram[0x301])) { (pgc->mapram[0x300] == pgc->mapram[0x301])) {
pgc->waiting_input_fifo = 1; 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 { \ #define PUSHCLIP { \
uint16_t vp_x1, vp_x2, vp_y1, vp_y2; \ uint16_t vp_x1, vp_x2, vp_y1, vp_y2; \
vp_x1 = pgc->vp_x1; \ vp_x1 = pgc->vp_x1; \
@@ -206,7 +207,7 @@ im1024_read(uint32_t addr, void *priv)
{ {
im1024_t *dev = (im1024_t *)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. */ /* Hardcode that there are 128 bytes free. */
return(0x80); return(0x80);
} }
@@ -221,9 +222,11 @@ im1024_write(uint32_t addr, uint8_t val, void *priv)
{ {
im1024_t *dev = (im1024_t *)priv; im1024_t *dev = (im1024_t *)priv;
/* If we are in 'fast' input mode, send all writes to the internal /*
* FIFO */ * If we are in 'fast' input mode, send all
if (addr >= 0xC6000 && addr < 0xC6100 && dev->pgc.mapram[0x330] == 1) { * writes to the internal FIFO.
*/
if (addr >= 0xc6000 && addr < 0xc6100 && dev->pgc.mapram[0x330] == 1) {
fifo_write(dev, val); fifo_write(dev, val);
DBGLOG(1, "IM1024: write(%02x)\n", 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 static void
hndl_imgsiz(pgc_t *pgc) 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 static void
hndl_iprec(pgc_t *pgc) 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 static void
hndl_pan(pgc_t *pgc) 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 static void
hndl_pline(pgc_t *pgc) 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 * Blit a single row of pixels from one location to another.
* there, and write the result back. */ *
* To avoid difficulties if the two overlap, read both rows
* into memory, process them there, and write the result back.
*/
static void static void
blkmov_row(pgc_t *pgc, int16_t x0, int16_t x1, int16_t x2, int16_t sy, int16_t ty) 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); dst[x - x0] = pgc_read_pixel(pgc, x - x0 + x2, ty);
} }
for (x = x0; x <= x1; x++) { for (x = x0; x <= x1; x++) switch (pgc->draw_mode) {
switch (pgc->draw_mode) { default:
default: case 0:
case 0: pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0]);
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0]); break;
break;
case 1: case 1:
pgc_write_pixel(pgc, (x - x0 + x2), ty, dst[x - x0] ^ 0xFF); pgc_write_pixel(pgc, (x - x0 + x2), ty, dst[x - x0] ^ 0xff);
break; break;
case 2: case 2:
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] ^ dst[x - x0]); pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] ^ dst[x - x0]);
break; break;
case 3: case 3:
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] & dst[x - x0]); pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] & dst[x - x0]);
break; 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 static void
hndl_blkmov(pgc_t *pgc) hndl_blkmov(pgc_t *pgc)
{ {
#if 0
im1024_t *dev = (im1024_t *)pgc;
#endif
int16_t x0, y0; int16_t x0, y0;
int16_t x1, y1; int16_t x1, y1;
int16_t x2, y2; 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, &x2)) return;
if (! pgc_param_word(pgc, &y2)) 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. */ /* Disable clipping. */
PUSHCLIP 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) { if (y2 <= y0) {
for (y = y0; y <= y1; y++) for (y = y0; y <= y1; y++)
blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2); 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 static void
hndl_ellipse(pgc_t *pgc) 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 static void
hndl_move(pgc_t *pgc) 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, &x)) return;
if (! pgc_param_word(pgc, &y)) return; if (! pgc_param_word(pgc, &y)) return;
DEBUG("IM1024: MOVE %i,%i\n", x, y);
pgc->x = x << 16; pgc->x = x << 16;
pgc->y = y << 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 static void
hndl_draw(pgc_t *pgc) 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); 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_draw_line(pgc, pgc->x, pgc->y, x << 16, y << 16, pgc->line_pattern);
pgc->x = x << 16; pgc->x = x << 16;
pgc->y = y << 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 static void
hndl_poly(pgc_t *pgc) hndl_poly(pgc_t *pgc)
{ {
@@ -484,7 +505,6 @@ hndl_poly(pgc_t *pgc)
x = (int32_t *)mem_alloc(as * sizeof(int32_t)); x = (int32_t *)mem_alloc(as * sizeof(int32_t));
y = (int32_t *)mem_alloc(as * sizeof(int32_t)); y = (int32_t *)mem_alloc(as * sizeof(int32_t));
if (!x || !y) { if (!x || !y) {
DEBUG("IM1024: POLY: out of memory\n"); DEBUG("IM1024: POLY: out of memory\n");
return; return;
@@ -519,9 +539,11 @@ hndl_poly(pgc_t *pgc)
realcount++; 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 * command is also POLY. If so, that's a continuation of this
* polygon! */ * polygon!
*/
parsing = 0; parsing = 0;
if (pgc->clcur && (pgc->clcur->rdptr+1) < pgc->clcur->wrptr && if (pgc->clcur && (pgc->clcur->rdptr+1) < pgc->clcur->wrptr &&
pgc->clcur->list[pgc->clcur->rdptr] == 0x30) { 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 static void
hndl_rect(pgc_t *pgc) 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, &x1)) return;
if (! pgc_param_word(pgc, &y1)) 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, &x0, &y0);
pgc_sto_raster(pgc, &x1, &y1); 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 static void
hndl_tdefin(pgc_t *pgc) hndl_tdefin(pgc_t *pgc)
{ {
@@ -619,8 +648,8 @@ hndl_tdefin(pgc_t *pgc)
unsigned len, n; unsigned len, n;
if (! pgc_param_byte(pgc, &ch)) return; 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, &cols)) return;
if (! pgc_param_byte(pgc, &rows)) return;
DEBUG("IM1024: TDEFIN (%i,%i,%i) 0x%02x 0x%02x\n", DEBUG("IM1024: TDEFIN (%i,%i,%i) 0x%02x 0x%02x\n",
ch, rows, cols, pgc->mapram[0x300], pgc->mapram[0x301]); ch, rows, cols, pgc->mapram[0x300], pgc->mapram[0x301]);
@@ -633,15 +662,27 @@ hndl_tdefin(pgc_t *pgc)
dev->font[ch][n] = bt; dev->font[ch][n] = bt;
} }
dev->fontx[ch] = rows; dev->fontx[ch] = cols;
dev->fonty[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 static void
hndl_twrite(pgc_t *pgc) hndl_twrite(pgc_t *pgc)
{ {
uint8_t buf[256], rbuf[256]; uint8_t buf[256];
im1024_t *dev = (im1024_t *)pgc; im1024_t *dev = (im1024_t *)pgc;
uint8_t count, mask, *row; uint8_t count, mask, *row;
int x, y, wb, n; int x, y, wb, n;
@@ -652,30 +693,21 @@ hndl_twrite(pgc_t *pgc)
for (n = 0; n < count; n++) for (n = 0; n < count; n++)
if (! pgc_param_byte(pgc, &buf[n])) return; if (! pgc_param_byte(pgc, &buf[n])) return;
buf[count] = 0; 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); pgc_sto_raster(pgc, &x0, &y0);
DEBUG("IM1024: TWRITE (%i,%-*.*s) x0=%i y0=%i\n", DEBUG("IM1024: TWRITE (%i) x0=%i y0=%i\n", count, x0, y0);
count, count, count, rbuf, x0, y0);
for (n = 0; n < count; n++) { for (n = 0; n < count; n++) {
wb = (dev->fontx[buf[n]] + 7) / 8; 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); buf[n], dev->fontx[buf[n]], dev->fonty[buf[n]], wb);
for (y = 0; y < dev->fonty[buf[n]]; y++) { for (y = 0; y < dev->fonty[buf[n]]; y++) {
mask = 0x80; mask = 0x80;
row = &dev->font[buf[n]][y * wb]; row = &dev->font[buf[n]][y * wb];
for (x = 0; x < dev->fontx[buf[n]]; x++) { for (x = 0; x < dev->fontx[buf[n]]; x++) {
rbuf[x] = (row[0] & mask) ? '#' : '-';
if (row[0] & mask) if (row[0] & mask)
pgc_plot(pgc, x + x0, y0 - y); pgc_plot(pgc, x + x0, y0 - y);
mask = mask >> 1; mask = mask >> 1;
@@ -684,8 +716,50 @@ hndl_twrite(pgc_t *pgc)
row++; 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]]; 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, &col1)) return;
if (! pgc_param_word(pgc, &col2)) return; if (! pgc_param_word(pgc, &col2)) return;
/* IMAGEW already uses raster coordinates so there is no need to /* Already using raster coordinates, no need to convert. */
* convert it */
DEBUG("IM1024: IMAGEW (row=%i,col1=%i,col2=%i)\n", row1, col1, col2); DEBUG("IM1024: IMAGEW (row=%i,col1=%i,col2=%i)\n", row1, col1, col2);
vp_x1 = pgc->vp_x1; vp_x1 = pgc->vp_x1;
@@ -728,34 +801,32 @@ hndl_imagew(pgc_t *pgc)
pgc_write_pixel(pgc, col1, row1, v1); pgc_write_pixel(pgc, col1, row1, v1);
col1++; col1++;
} }
} else {
/* In hex mode, it's RLE compressed. */
while (col1 <= col2) {
if (! pgc_param_byte(pgc, &v1)) return;
return; if (v1 & 0x80) {
} /* Literal run. */
v1 -= 0x7f;
/* In hex mode, it's RLE compressed. */ while (col1 <= col2 && v1 != 0) {
while (col1 <= col2) { if (! pgc_param_byte(pgc, &v2)) return;
if (! pgc_param_byte(pgc, &v1)) return; pgc_write_pixel(pgc, col1, row1, v2);
col1++;
if (v1 & 0x80) { v1--;
/* Literal run. */ }
v1 -= 0x7f; } else {
while (col1 <= col2 && v1 != 0) { /* Repeated run. */
if (! pgc_param_byte(pgc, &v2)) return; 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++; v1++;
while (col1 <= col2 && v1 != 0) { while (col1 <= col2 && v1 != 0) {
pgc_write_pixel(pgc, col1, row1, v2); pgc_write_pixel(pgc, col1, row1, v2);
col1++; col1++;
v1--; v1--;
} }
} }
}
} }
/* Restore clipping. */ /* Restore clipping. */
@@ -774,7 +845,8 @@ hndl_imagew(pgc_t *pgc)
static void static void
hndl_dot(pgc_t *pgc) 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); 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 * 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 * than the single row read by IMAGER, and does not attempt to compress
* the result */ * the result.
*/
static void static void
hndl_imagex(pgc_t *pgc) 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, &x1)) return;
if (! pgc_param_word(pgc, &y1)) 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); DEBUG("IM1024: IMAGEX (%i,%i,%i,%i)\n", x0,y0,x1,y1);
for (p = y0; p <= y1; p++) { 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: A lot of commands need commandlist parsers.
* TODO: The IM-1024 has a lot more commands that are not included here * 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 }, { "ELIPSE", 0x39, hndl_ellipse, pgc_parse_words, 2 },
{ "EL", 0x39, hndl_ellipse, pgc_parse_words, 2 }, { "EL", 0x39, hndl_ellipse, pgc_parse_words, 2 },
{ "IMAGEW", 0xd9, hndl_imagew, NULL, 0 }, { "IMAGEW", 0xd9, hndl_imagew, NULL, 0 },
{ "IW", 0xd9, hndl_imagew, NULL, 0 },
{ "IMAGEX", 0xda, hndl_imagex, 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 }, { "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 }, { "L8", 0xe6, pgc_hndl_lut8, NULL, 0 },
{ "LINFUN", 0xeb, hndl_linfun, pgc_parse_bytes, 1 },
{ "LF", 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 }, { "LUT8RD", 0x53, pgc_hndl_lut8rd,NULL, 0 },
{ "L8RD", 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 }, { "PAN", 0xb7, hndl_pan, NULL, 0 },
{ "POLY", 0x30, hndl_poly, parse_poly, 0 }, { "POLY", 0x30, hndl_poly, parse_poly, 0 },
{ "P", 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)); dev = (im1024_t *)mem_alloc(sizeof(im1024_t));
memset(dev, 0x00, sizeof(im1024_t)); memset(dev, 0x00, sizeof(im1024_t));
dev->fifo = (uint8_t *)mem_alloc(4096);
dev->fifo_len = 4096; dev->fifo_len = 4096;
dev->fifo = (uint8_t *)mem_alloc(dev->fifo_len);
dev->fifo_wrptr = 0; dev->fifo_wrptr = 0;
dev->fifo_rdptr = 0; dev->fifo_rdptr = 0;

View File

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

View File

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

View File

@@ -41,13 +41,13 @@
* even-numbered columns, so the top bit of the control register * even-numbered columns, so the top bit of the control register
* at 0x2D9 is used to adjust the position. * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* John Elliott, <jce@seasip.info> * John Elliott, <jce@seasip.info>
* *
* Copyright 2018 Fred N. van Kempen. * Copyright 2018,2019 Fred N. van Kempen.
* Copyright 2018 Miran Grca. * Copyright 2018 Miran Grca.
* Copyright 2018 John Elliott. * Copyright 2018 John Elliott.
* *
@@ -165,6 +165,8 @@
typedef struct { typedef struct {
const char *name;
mem_map_t mapping, mem_map_t mapping,
bios_ram; bios_ram;
@@ -213,6 +215,8 @@ typedef struct {
int64_t vidtime; int64_t vidtime;
uint8_t *vram; uint8_t *vram;
uint8_t fontdat[256][8]; /* 8x8 font */
uint8_t fontdat16[256][16]; /* 8x16 font */
uint8_t bram[2048]; uint8_t bram[2048];
uint8_t palette[16]; uint8_t palette[16];
} sigma_t; } sigma_t;
@@ -485,16 +489,16 @@ sigma_text80(sigma_t *dev)
if (drawcursor) { if (drawcursor) {
for (c = 0; c < 8; c++) { for (c = 0; c < 8; c++) {
if (dev->sigmamode & MODE_FONT16) 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 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 { } else {
for (c = 0; c < 8; c++) { for (c = 0; c < 8; c++) {
if (dev->sigmamode & MODE_FONT16) 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 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; ++ma;
@@ -540,12 +544,12 @@ sigma_text40(sigma_t *dev)
if (drawcursor) { if (drawcursor) {
for (c = 0; c < 8; c++) { for (c = 0; c < 8; c++) {
buffer->line[dev->displine][(x << 4) + 2*c + 8] = 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 { } else {
for (c = 0; c < 8; c++) { for (c = 0; c < 8; c++) {
buffer->line[dev->displine][(x << 4) + 2*c + 8] = 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++; 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 * static void *
sigma_init(const device_t *info) sigma_init(const device_t *info)
{ {
sigma_t *dev = malloc(sizeof(sigma_t)); sigma_t *dev;
memset(dev, 0, sizeof(sigma_t));
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"); 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, sigma_read,NULL,NULL, sigma_write,NULL,NULL,
NULL, MEM_MAPPING_EXTERNAL, dev); NULL, MEM_MAPPING_EXTERNAL, dev);
video_load_font(FONT_ROM_PATH, 7);
rom_init(&dev->bios_rom, BIOS_ROM_PATH, rom_init(&dev->bios_rom, BIOS_ROM_PATH,
0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); 0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);

View File

@@ -8,13 +8,13 @@
* *
* SVGA renderers. * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk> * 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 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker. * 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(x + xinc < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) {
if ((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) 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) 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 else
dat = 0xff; dat = 0xff;
} else { } else {
@@ -292,9 +292,9 @@ svga_render_text_80_ksc5601(svga_t *svga)
} }
if ((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff)) 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) 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 else
dat = 0xff; dat = 0xff;

View File

@@ -53,13 +53,13 @@
* What doesn't work, is untested or not well understood: * What doesn't work, is untested or not well understood:
* - Cursor detach (commands 4 and 5) * - 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk> * 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 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker. * Copyright 2008-2018 Sarah Walker.
* *
@@ -93,13 +93,14 @@
#include "../../timer.h" #include "../../timer.h"
#include "../../device.h" #include "../../device.h"
#include "../system/pit.h" #include "../system/pit.h"
#include "../../plat.h"
#include "video.h" #include "video.h"
#define WY700_XSIZE 1280 #define WY700_XSIZE 1280
#define WY700_YSIZE 800 #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 /* 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 { typedef struct {
const char *name;
mem_map_t mapping; mem_map_t mapping;
/* The microcontroller works by watching four ports: /* The microcontroller works by watching four ports:
@@ -239,6 +238,9 @@ typedef struct {
/* ... and MDA emulation. */ /* ... and MDA emulation. */
int mdacols[256][2][2]; int mdacols[256][2][2];
/* Font ROM: Two fonts, each containing 256 characters, 16x16 pixels */
uint8_t fontdat[512][32];
uint8_t *vram; uint8_t *vram;
} wy700_t; } wy700_t;
@@ -528,14 +530,13 @@ text_line(wy700_t *dev)
int cw = (dev->wy700_mode == 0) ? 32 : 16; int cw = (dev->wy700_mode == 0) ? 32 : 16;
uint8_t chr, attr; uint8_t chr, attr;
uint8_t bitmap[2]; uint8_t bitmap[2];
uint8_t *fontbase = &fontdatw[0][0]; uint8_t *fontbase = &dev->fontdat[0][0];
int blink, c; int blink, c;
int drawcursor, cursorline; int drawcursor, cursorline;
int mda = 0; int mda = 0;
uint16_t addr; uint16_t addr;
uint8_t sc; uint8_t sc;
/* The fake CRTC character height register selects whether MDA or CGA /* The fake CRTC character height register selects whether MDA or CGA
* attributes are used */ * attributes are used */
if (dev->cga_crtc[9] == 0 || dev->cga_crtc[9] == 13) { 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 * static void *
wy700_init(const device_t *info) wy700_init(const device_t *info)
{ {
@@ -862,12 +884,16 @@ wy700_init(const device_t *info)
dev = (wy700_t *)mem_alloc(sizeof(wy700_t)); dev = (wy700_t *)mem_alloc(sizeof(wy700_t));
memset(dev, 0x00, 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); dev->vram = (uint8_t *)mem_alloc(0x20000);
video_load_font(BIOS_ROM_PATH, 3);
timer_add(wy700_poll, &dev->vidtime, TIMER_ALWAYS_ENABLED, dev); timer_add(wy700_poll, &dev->vidtime, TIMER_ALWAYS_ENABLED, dev);
/* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in /* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in
@@ -979,7 +1005,7 @@ wy700_close(void *priv)
static int static int
wy700_available(void) 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 * W = 3 bus clocks
* L = 4 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -91,14 +91,15 @@
#ifdef ENABLE_VIDEO_LOG #ifdef ENABLE_VIDEO_LOG
int video_do_log = ENABLE_VIDEO_LOG; int video_do_log = ENABLE_VIDEO_LOG;
#endif #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, bitmap_t *buffer = NULL,
*buffer32 = 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]; uint32_t pal_lookup[256];
int xsize = 1, int xsize = 1,
ysize = 1; ysize = 1;
@@ -884,14 +885,14 @@ video_type(void)
void void
video_reset_font(void) video_reset_font(void)
{ {
if (fontdatksc5601 != NULL) { if (fontdatk != NULL) {
free(fontdatksc5601); free(fontdatk);
fontdatksc5601 = NULL; fontdatk = NULL;
} }
if (fontdatksc5601_user != NULL) { if (fontdatk_user != NULL) {
free(fontdatksc5601_user); free(fontdatk_user);
fontdatksc5601_user = NULL; fontdatk_user = NULL;
} }
} }
@@ -901,11 +902,11 @@ void
video_load_font(const wchar_t *s, int format) video_load_font(const wchar_t *s, int format)
{ {
FILE *fp; FILE *fp;
int c, d; int c;
fp = plat_fopen(rom_path(s), L"rb"); fp = plat_fopen(rom_path(s), L"rb");
if (fp == NULL) { 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; return;
} }
@@ -917,81 +918,15 @@ video_load_font(const wchar_t *s, int format)
(void)fread(&fontdatm[c][8], 1, 8, fp); (void)fread(&fontdatm[c][8], 1, 8, fp);
break; break;
case 1: /* PC200 */ case 1: /* CGA, thin font */
for (c = 0; c < 256; c++) case 2: /* CGA, thick font */
(void)fread(&fontdatm[c][0], 1, 8, fp); if (format == 2) {
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) {
/* Use the second ("thick") font in the ROM. */ /* Use the second ("thick") font in the ROM. */
(void)fseek(fp, 2048, SEEK_SET); (void)fseek(fp, 2048, SEEK_SET);
} }
for (c = 0; c < 256; c++) for (c = 0; c < 256; c++)
(void)fread(&fontdat[c][0], 1, 8, fp); (void)fread(&fontdat[c][0], 1, 8, fp);
break; 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); DEBUG("VIDEO: font #%i loaded\n", format);

View File

@@ -8,7 +8,7 @@
* *
* Definitions for the video controller module. * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -113,16 +113,17 @@ typedef rgb_t PALETTE[256];
extern int changeframecount; 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, extern bitmap_t *buffer,
*buffer32; *buffer32;
extern PALETTE cgapal, extern PALETTE cgapal,
cgapal_mono[6]; cgapal_mono[6];
extern uint32_t pal_lookup[256]; 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, extern uint32_t *video_6to8,
*video_15to32, *video_15to32,
*video_16to32; *video_16to32;
@@ -335,6 +336,10 @@ extern void video_wait_for_buffer(void);
extern void cgapal_rebuild(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_log(int level, const char *fmt, ...);
extern void video_init(void); extern void video_init(void);
extern void video_close(void); extern void video_close(void);

View File

@@ -12,7 +12,7 @@
* "extern" reference to its device into the video.h file, * "extern" reference to its device into the video.h file,
* and add an entry for it into the table here. * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -68,9 +68,7 @@ static const struct {
/* Standard video controllers. */ /* Standard video controllers. */
{ "mda", &mda_device }, { "mda", &mda_device },
{ "cga", &cga_device }, { "cga", &cga_device },
#if defined(DEV_BRANCH)
{ "pgc", &pgc_device }, { "pgc", &pgc_device },
#endif
{ "ega", &ega_device }, { "ega", &ega_device },
{ "vga", &vga_device }, { "vga", &vga_device },
{ "hercules", &hercules_device }, { "hercules", &hercules_device },
@@ -105,9 +103,7 @@ static const struct {
{ "hercules_plus", &herculesplus_device }, { "hercules_plus", &herculesplus_device },
{ "incolor", &incolor_device }, { "incolor", &incolor_device },
{ "genius", &genius_device }, { "genius", &genius_device },
#if defined(DEV_BRANCH)
{ "im1024", &im1024_device }, { "im1024", &im1024_device },
#endif
{ "oti037c", &oti037c_device }, { "oti037c", &oti037c_device },
{ "oti067", &oti067_device }, { "oti067", &oti067_device },
{ "oti077", &oti077_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 * 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.. * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
@@ -88,6 +88,7 @@
#include "../devices/video/video.h" #include "../devices/video/video.h"
#include "../devices/video/vid_cga.h" #include "../devices/video/vid_cga.h"
#include "../devices/video/vid_ega.h" #include "../devices/video/vid_ega.h"
#include "../plat.h"
#include "machine.h" #include "machine.h"
@@ -132,6 +133,7 @@ typedef struct {
int firstline, int firstline,
lastline; lastline;
uint8_t *vram; uint8_t *vram;
uint8_t fontdat[256][8]; /* 1512/200 */
} amsvid_t; } amsvid_t;
typedef struct { typedef struct {
@@ -346,10 +348,10 @@ vid_poll_1512(void *priv)
} }
if (drawcursor) { if (drawcursor) {
for (c = 0; c < 8; c++) 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 { } else {
for (c = 0; c < 8; c++) 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++; vid->ma++;
} }
@@ -371,11 +373,11 @@ vid_poll_1512(void *priv)
if (drawcursor) { if (drawcursor) {
for (c = 0; c < 8; c++) for (c = 0; c < 8; c++)
buffer->line[vid->displine][(x << 4) + (c << 1) + 8] = 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 { } else {
for (c = 0; c < 8; c++) for (c = 0; c < 8; c++)
buffer->line[vid->displine][(x << 4) + (c << 1) + 8] = 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)) { } else if (! (vid->cgamode & 16)) {
@@ -533,14 +535,31 @@ vid_poll_1512(void *priv)
static void static void
vid_init_1512(amstrad_t *ams) vid_init_1512(amstrad_t *ams, const wchar_t *fn, int num)
{ {
amsvid_t *vid; amsvid_t *vid;
FILE *fp;
int c;
/* Allocate a video controller block. */ /* Allocate a video controller block. */
vid = (amsvid_t *)mem_alloc(sizeof(amsvid_t)); vid = (amsvid_t *)mem_alloc(sizeof(amsvid_t));
memset(vid, 0x00, 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->vram = (uint8_t *)mem_alloc(0x10000);
vid->cgacol = 7; vid->cgacol = 7;
vid->cgamode = 0x12; vid->cgamode = 0x12;
@@ -581,8 +600,7 @@ vid_speed_change_1512(void *priv)
static const device_t vid_1512_device = { static const device_t vid_1512_device = {
"Amstrad PC1512 (video)", "Amstrad PC1512 (video)",
0, 0, 0,
0,
NULL, vid_close_1512, NULL, NULL, vid_close_1512, NULL,
NULL, NULL,
vid_speed_change_1512, vid_speed_change_1512,
@@ -752,8 +770,7 @@ vid_speed_changed_1640(void *priv)
static const device_t vid_1640_device = { static const device_t vid_1640_device = {
"Amstrad PC1640 (video)", "Amstrad PC1640 (video)",
0, 0, 0,
0,
NULL, vid_close_1640, NULL, NULL, vid_close_1640, NULL,
NULL, NULL,
vid_speed_changed_1640, vid_speed_changed_1640,
@@ -841,15 +858,40 @@ vid_in_200(uint16_t addr, void *priv)
static void static void
vid_init_200(amstrad_t *ams) vid_init_200(amstrad_t *ams, const wchar_t *fn)
{ {
amsvid_t *vid; amsvid_t *vid;
cga_t *cga; cga_t *cga;
FILE *fp;
int c, d;
/* Allocate a video controller block. */ /* Allocate a video controller block. */
vid = (amsvid_t *)mem_alloc(sizeof(amsvid_t)); vid = (amsvid_t *)mem_alloc(sizeof(amsvid_t));
memset(vid, 0x00, 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 = &vid->cga;
cga->vram = (uint8_t *)mem_alloc(0x4000); cga->vram = (uint8_t *)mem_alloc(0x4000);
cga_init(cga); cga_init(cga);
@@ -891,8 +933,7 @@ vid_speed_changed_200(void *priv)
static const device_t vid_200_device = { static const device_t vid_200_device = {
"Amstrad PC200 (video)", "Amstrad PC200 (video)",
0, 0, 0,
0,
NULL, vid_close_200, NULL, NULL, vid_close_200, NULL,
NULL, NULL,
vid_speed_changed_200, vid_speed_changed_200,
@@ -1219,6 +1260,59 @@ amstrad_common_init(const machine_t *model, void *arg, int type)
machine_common_init(model, arg); machine_common_init(model, arg);
nmi_init(); 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); device_add(&amstrad_nvr_device);
@@ -1235,64 +1329,6 @@ amstrad_common_init(const machine_t *model, void *arg, int type)
io_sethandler(0xdead, 1, io_sethandler(0xdead, 1,
ams_read, NULL, NULL, ams_write, NULL, NULL, ams); 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. */ /* Initialize the (custom) keyboard/mouse interface. */
ams->wantirq = 0; ams->wantirq = 0;

View File

@@ -22,13 +22,13 @@
* 61 50 52 0F 19 06 19 19 02 0D 0B 0C MONO * 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 * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.com> * Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <tommowalker@tommowalker.co.uk> * 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 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker. * Copyright 2008-2018 Sarah Walker.
* *
@@ -59,15 +59,18 @@
#include "../cpu/cpu.h" #include "../cpu/cpu.h"
#include "../io.h" #include "../io.h"
#include "../mem.h" #include "../mem.h"
#include "../rom.h"
#include "../timer.h" #include "../timer.h"
#include "../device.h" #include "../device.h"
#include "../devices/video/video.h" #include "../devices/video/video.h"
#include "../devices/video/vid_cga.h" #include "../devices/video/vid_cga.h"
#include "../plat.h"
#include "m_at_t3100e.h" #include "m_at_t3100e.h"
#define T3100E_XSIZE 640 #define FONT_ROM_PATH L"machines/toshiba/t3100e/t3100e_font.bin"
#define T3100E_YSIZE 400 #define T3100E_XSIZE 640
#define T3100E_YSIZE 400
/* Mapping of attributes to colours */ /* Mapping of attributes to colours */
@@ -108,6 +111,9 @@ typedef struct {
uint8_t video_options; uint8_t video_options;
uint8_t *vram; uint8_t *vram;
uint8_t fontdat[2048][8];
uint8_t fontdatm[2048][16];
} t3100e_t; } t3100e_t;
@@ -363,11 +369,11 @@ text_row80(t3100e_t *dev)
if (drawcursor) { if (drawcursor) {
for (c = 0; c < 8; c++) { 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 { } else {
for (c = 0; c < 8; c++) 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; ++ma;
} }
@@ -427,11 +433,11 @@ text_row40(t3100e_t *dev)
if (drawcursor) { if (drawcursor) {
for (c = 0; c < 8; c++) { 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 { } else {
for (c = 0; c < 8; c++) { 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; ++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 * static void *
t3100e_init(const device_t *info) t3100e_init(const device_t *info)
{ {
@@ -648,6 +692,11 @@ t3100e_init(const device_t *info)
dev = (t3100e_t *)mem_alloc(sizeof(t3100e_t)); dev = (t3100e_t *)mem_alloc(sizeof(t3100e_t));
memset(dev, 0x00, sizeof(t3100e_t)); memset(dev, 0x00, sizeof(t3100e_t));
if (! load_font(dev, FONT_ROM_PATH)) {
free(dev);
return(NULL);
}
cga_init(&dev->cga); cga_init(&dev->cga);
dev->internal = 1; dev->internal = 1;

View File

@@ -8,7 +8,7 @@
* *
* Handling of the emulated machines. * 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> * Authors: Fred N. van Kempen, <decwiz@yahoo.com>
* Miran Grca, <mgrca8@gmail.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] 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-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] 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 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 }, { "[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 },