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:
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* ATI 18800 emulation (VGA Edge-16)
|
||||
*
|
||||
* Version: @(#)vid_ati18800.c 1.0.10 2019/02/10
|
||||
* Version: @(#)vid_ati18800.c 1.0.11 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -49,7 +49,7 @@
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_svga_render.h"
|
||||
#include "vid_ati_eeprom.h"
|
||||
#include "vid_ati.h"
|
||||
|
||||
|
||||
# define BIOS_ROM_PATH_WONDER L"video/ati/ati18800/vga_wonder_v3-1.02.bin"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* ATI 28800 emulation (VGA Charger and Korean VGA)
|
||||
*
|
||||
* Version: @(#)vid_ati28800.c 1.0.16 2019/02/10
|
||||
* Version: @(#)vid_ati28800.c 1.0.18 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -47,11 +47,12 @@
|
||||
#include "../../mem.h"
|
||||
#include "../../rom.h"
|
||||
#include "../../device.h"
|
||||
#include "../../plat.h"
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_svga_render.h"
|
||||
#include "vid_sc1502x_ramdac.h"
|
||||
#include "vid_ati_eeprom.h"
|
||||
#include "vid_ati.h"
|
||||
|
||||
|
||||
enum {
|
||||
@@ -220,7 +221,7 @@ ati28800k_out(uint16_t port, uint8_t val, void *priv)
|
||||
dev->in_get_korean_font_kind_set = 0;
|
||||
if (dev->get_korean_font_enabled) {
|
||||
if ((dev->get_korean_font_base & 0x7F) > 0x20 && (dev->get_korean_font_base & 0x7F) < 0x7F)
|
||||
fontdatksc5601_user[(dev->get_korean_font_kind & 4) * 24 + (dev->get_korean_font_base & 0x7F) - 0x20].chr[dev->get_korean_font_index] = val;
|
||||
fontdatk_user[(dev->get_korean_font_kind & 4) * 24 + (dev->get_korean_font_base & 0x7F) - 0x20].chr[dev->get_korean_font_index] = val;
|
||||
dev->get_korean_font_index++;
|
||||
dev->get_korean_font_index &= 0x1F;
|
||||
} else {
|
||||
@@ -337,12 +338,12 @@ ati28800k_in(uint16_t port, void *priv)
|
||||
if (dev->get_korean_font_enabled) {
|
||||
switch(dev->get_korean_font_kind >> 8) {
|
||||
case 4: /* ROM font */
|
||||
ret = fontdatksc5601[dev->get_korean_font_base].chr[dev->get_korean_font_index++];
|
||||
ret = fontdatk[dev->get_korean_font_base].chr[dev->get_korean_font_index++];
|
||||
break;
|
||||
|
||||
case 2: /* User defined font */
|
||||
if ((dev->get_korean_font_base & 0x7F) > 0x20 && (dev->get_korean_font_base & 0x7F) < 0x7F)
|
||||
ret = fontdatksc5601_user[(dev->get_korean_font_kind & 4) * 24 + (dev->get_korean_font_base & 0x7F) - 0x20].chr[dev->get_korean_font_index];
|
||||
ret = fontdatk_user[(dev->get_korean_font_kind & 4) * 24 + (dev->get_korean_font_base & 0x7F) - 0x20].chr[dev->get_korean_font_index];
|
||||
else
|
||||
ret = 0xff;
|
||||
dev->get_korean_font_index++;
|
||||
@@ -443,6 +444,44 @@ ati28800k_recalctimings(svga_t *svga)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Also used by the Korean ET4000AX.
|
||||
*
|
||||
* This will eventually need the 'svga' pointer to store
|
||||
* the font data in to, which is global data right now.
|
||||
*/
|
||||
int
|
||||
ati28800k_load_font(svga_t *svga, const wchar_t *fn)
|
||||
{
|
||||
FILE *fp;
|
||||
int c, d;
|
||||
|
||||
fp = plat_fopen(rom_path(fn), L"rb");
|
||||
if (fp == NULL) {
|
||||
ERRLOG("ATI28800K: cannot load font '%ls'\n", fn);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (fontdatk == NULL)
|
||||
fontdatk = (dbcs_font_t *)mem_alloc(16384 * sizeof(dbcs_font_t));
|
||||
|
||||
if (fontdatk_user == NULL) {
|
||||
c = 192 * sizeof(dbcs_font_t);
|
||||
fontdatk_user = (dbcs_font_t *)mem_alloc(c);
|
||||
memset(fontdatk_user, 0x00, c);
|
||||
}
|
||||
|
||||
for (c = 0; c < 16384; c++) {
|
||||
for (d = 0; d < 32; d++)
|
||||
fontdatk[c].chr[d] = fgetc(fp);
|
||||
}
|
||||
|
||||
(void)fclose(fp);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ati28800_init(const device_t *info)
|
||||
{
|
||||
@@ -494,8 +533,6 @@ ati28800_init(const device_t *info)
|
||||
dev->in_get_korean_font_kind_set = 0;
|
||||
dev->ksc5601_mode_enabled = 0;
|
||||
|
||||
video_load_font(FONT_ATIKOR_PATH, 6);
|
||||
|
||||
rom_init(&dev->bios_rom, BIOS_ATIKOR_PATH,
|
||||
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
ati_eeprom_load(&dev->eeprom, L"atikorvga.nvr", 0);
|
||||
@@ -533,6 +570,14 @@ ati28800_init(const device_t *info)
|
||||
|
||||
dev->svga.miscout = 1;
|
||||
|
||||
if (info->local == VID_ATIKOREANVGA) {
|
||||
if (! ati28800k_load_font(&dev->svga, FONT_ATIKOR_PATH)) {
|
||||
svga_close(&dev->svga);
|
||||
free(dev);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
video_inform(VID_TYPE_SPEC,
|
||||
(const video_timings_t *)info->vid_timing);
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
*
|
||||
* Emulation of the EEPROM on select ATI cards.
|
||||
*
|
||||
* Version: @(#)vid_ati_eeprom.c 1.0.4 2018/09/04
|
||||
* Version: @(#)vid_ati_eeprom.c 1.0.5 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
*
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
*
|
||||
@@ -44,215 +44,208 @@
|
||||
#include "../../mem.h"
|
||||
#include "../../nvr.h"
|
||||
#include "../../plat.h"
|
||||
#include "vid_ati_eeprom.h"
|
||||
#include "vid_ati.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
EEPROM_IDLE,
|
||||
EEPROM_WAIT,
|
||||
EEPROM_OPCODE,
|
||||
EEPROM_INPUT,
|
||||
EEPROM_OUTPUT
|
||||
enum {
|
||||
EEPROM_IDLE,
|
||||
EEPROM_WAIT,
|
||||
EEPROM_OPCODE,
|
||||
EEPROM_INPUT,
|
||||
EEPROM_OUTPUT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EEPROM_OP_EW = 4,
|
||||
EEPROM_OP_WRITE = 5,
|
||||
EEPROM_OP_READ = 6,
|
||||
EEPROM_OP_ERASE = 7,
|
||||
enum {
|
||||
EEPROM_OP_EW = 4,
|
||||
EEPROM_OP_WRITE = 5,
|
||||
EEPROM_OP_READ = 6,
|
||||
EEPROM_OP_ERASE = 7,
|
||||
|
||||
EEPROM_OP_WRALMAIN = -1
|
||||
EEPROM_OP_WRALMAIN = -1
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EEPROM_OP_EWDS = 0,
|
||||
EEPROM_OP_WRAL = 1,
|
||||
EEPROM_OP_ERAL = 2,
|
||||
EEPROM_OP_EWEN = 3
|
||||
enum {
|
||||
EEPROM_OP_EWDS = 0,
|
||||
EEPROM_OP_WRAL = 1,
|
||||
EEPROM_OP_ERAL = 2,
|
||||
EEPROM_OP_EWEN = 3
|
||||
};
|
||||
|
||||
void ati_eeprom_load(ati_eeprom_t *eeprom, wchar_t *fn, int type)
|
||||
|
||||
void
|
||||
ati_eeprom_load(ati_eeprom_t *dev, wchar_t *fn, int type)
|
||||
{
|
||||
FILE *f;
|
||||
FILE *fp;
|
||||
|
||||
eeprom->type = type;
|
||||
memset(eeprom->data, 0, eeprom->type ? 512 : 128);
|
||||
dev->type = type;
|
||||
memset(dev->data, 0, dev->type ? 512 : 128);
|
||||
|
||||
wcscpy(eeprom->fn, fn);
|
||||
f = plat_fopen(nvr_path(eeprom->fn), L"rb");
|
||||
if (f != NULL)
|
||||
{
|
||||
(void)fread(eeprom->data, 1, eeprom->type ? 512 : 128, f);
|
||||
fclose(f);
|
||||
}
|
||||
wcscpy(dev->fn, fn);
|
||||
fp = plat_fopen(nvr_path(dev->fn), L"rb");
|
||||
if (fp != NULL) {
|
||||
(void)fread(dev->data, 1, dev->type ? 512 : 128, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void ati_eeprom_save(ati_eeprom_t *eeprom)
|
||||
{
|
||||
FILE *f = plat_fopen(nvr_path(eeprom->fn), L"wb");
|
||||
|
||||
if (f != NULL) {
|
||||
(void)fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f);
|
||||
fclose(f);
|
||||
void
|
||||
ati_eeprom_save(ati_eeprom_t *dev)
|
||||
{
|
||||
FILE *fp = plat_fopen(nvr_path(dev->fn), L"wb");
|
||||
|
||||
if (fp != NULL) {
|
||||
(void)fwrite(dev->data, 1, dev->type ? 512 : 128, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ati_eeprom_write(ati_eeprom_t *dev, int ena, int clk, int dat)
|
||||
{
|
||||
int c;
|
||||
|
||||
if (! ena)
|
||||
dev->out = 1;
|
||||
|
||||
if (clk && !dev->oldclk) {
|
||||
if (ena && !dev->oldena) {
|
||||
dev->state = EEPROM_WAIT;
|
||||
dev->opcode = 0;
|
||||
dev->count = 3;
|
||||
dev->out = 1;
|
||||
} else if (ena) {
|
||||
switch (dev->state) {
|
||||
case EEPROM_WAIT:
|
||||
if (! dat)
|
||||
break;
|
||||
dev->state = EEPROM_OPCODE;
|
||||
/*FALLTHROUGH*/
|
||||
|
||||
case EEPROM_OPCODE:
|
||||
dev->opcode = (dev->opcode << 1) | (dat ? 1 : 0);
|
||||
dev->count--;
|
||||
if (! dev->count) {
|
||||
switch (dev->opcode) {
|
||||
case EEPROM_OP_WRITE:
|
||||
dev->count = dev->type ? 24 : 22;
|
||||
dev->state = EEPROM_INPUT;
|
||||
dev->dat = 0;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_READ:
|
||||
dev->count = dev->type ? 8 : 6;
|
||||
dev->state = EEPROM_INPUT;
|
||||
dev->dat = 0;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_EW:
|
||||
dev->count = 2;
|
||||
dev->state = EEPROM_INPUT;
|
||||
dev->dat = 0;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_ERASE:
|
||||
dev->count = dev->type ? 8 : 6;
|
||||
dev->state = EEPROM_INPUT;
|
||||
dev->dat = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EEPROM_INPUT:
|
||||
dev->dat = (dev->dat << 1) | (dat ? 1 : 0);
|
||||
dev->count--;
|
||||
if (! dev->count) {
|
||||
switch (dev->opcode) {
|
||||
case EEPROM_OP_WRITE:
|
||||
if (! dev->wp) {
|
||||
dev->data[(dev->dat >> 16) & (dev->type ? 255 : 63)] = dev->dat & 0xffff;
|
||||
ati_eeprom_save(dev);
|
||||
}
|
||||
dev->state = EEPROM_IDLE;
|
||||
dev->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_READ:
|
||||
dev->count = 17;
|
||||
dev->state = EEPROM_OUTPUT;
|
||||
dev->dat = dev->data[dev->dat];
|
||||
break;
|
||||
|
||||
case EEPROM_OP_EW:
|
||||
switch (dev->dat) {
|
||||
case EEPROM_OP_EWDS:
|
||||
dev->wp = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_WRAL:
|
||||
dev->opcode = EEPROM_OP_WRALMAIN;
|
||||
dev->count = 20;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_ERAL:
|
||||
if (! dev->wp) {
|
||||
memset(dev->data, 0xff, 128);
|
||||
ati_eeprom_save(dev);
|
||||
}
|
||||
break;
|
||||
|
||||
case EEPROM_OP_EWEN:
|
||||
dev->wp = 0;
|
||||
break;
|
||||
}
|
||||
dev->state = EEPROM_IDLE;
|
||||
dev->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_ERASE:
|
||||
if (! dev->wp) {
|
||||
dev->data[dev->dat] = 0xffff;
|
||||
ati_eeprom_save(dev);
|
||||
}
|
||||
dev->state = EEPROM_IDLE;
|
||||
dev->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_WRALMAIN:
|
||||
if (! dev->wp) {
|
||||
for (c = 0; c < 256; c++)
|
||||
dev->data[c] = dev->dat;
|
||||
ati_eeprom_save(dev);
|
||||
}
|
||||
dev->state = EEPROM_IDLE;
|
||||
dev->out = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
dev->oldena = ena;
|
||||
} else if (!clk && dev->oldclk) {
|
||||
if (ena) {
|
||||
switch (dev->state) {
|
||||
case EEPROM_OUTPUT:
|
||||
dev->out = (dev->dat & 0x10000) ? 1 : 0;
|
||||
dev->dat <<= 1;
|
||||
dev->count--;
|
||||
if (! dev->count) {
|
||||
dev->state = EEPROM_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dev->oldclk = clk;
|
||||
}
|
||||
|
||||
void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat)
|
||||
|
||||
int
|
||||
ati_eeprom_read(ati_eeprom_t *dev)
|
||||
{
|
||||
int c;
|
||||
if (!ena)
|
||||
{
|
||||
eeprom->out = 1;
|
||||
}
|
||||
if (clk && !eeprom->oldclk)
|
||||
{
|
||||
if (ena && !eeprom->oldena)
|
||||
{
|
||||
eeprom->state = EEPROM_WAIT;
|
||||
eeprom->opcode = 0;
|
||||
eeprom->count = 3;
|
||||
eeprom->out = 1;
|
||||
}
|
||||
else if (ena)
|
||||
{
|
||||
switch (eeprom->state)
|
||||
{
|
||||
case EEPROM_WAIT:
|
||||
if (!dat)
|
||||
break;
|
||||
eeprom->state = EEPROM_OPCODE;
|
||||
/* fall through */
|
||||
case EEPROM_OPCODE:
|
||||
eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0);
|
||||
eeprom->count--;
|
||||
if (!eeprom->count)
|
||||
{
|
||||
switch (eeprom->opcode)
|
||||
{
|
||||
case EEPROM_OP_WRITE:
|
||||
eeprom->count = eeprom->type ? 24 : 22;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
case EEPROM_OP_READ:
|
||||
eeprom->count = eeprom->type ? 8 : 6;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
case EEPROM_OP_EW:
|
||||
eeprom->count = 2;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
case EEPROM_OP_ERASE:
|
||||
eeprom->count = eeprom->type ? 8 : 6;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EEPROM_INPUT:
|
||||
eeprom->dat = (eeprom->dat << 1) | (dat ? 1 : 0);
|
||||
eeprom->count--;
|
||||
if (!eeprom->count)
|
||||
{
|
||||
switch (eeprom->opcode)
|
||||
{
|
||||
case EEPROM_OP_WRITE:
|
||||
if (!eeprom->wp)
|
||||
{
|
||||
eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = eeprom->dat & 0xffff;
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_READ:
|
||||
eeprom->count = 17;
|
||||
eeprom->state = EEPROM_OUTPUT;
|
||||
eeprom->dat = eeprom->data[eeprom->dat];
|
||||
break;
|
||||
case EEPROM_OP_EW:
|
||||
switch (eeprom->dat)
|
||||
{
|
||||
case EEPROM_OP_EWDS:
|
||||
eeprom->wp = 1;
|
||||
break;
|
||||
case EEPROM_OP_WRAL:
|
||||
eeprom->opcode = EEPROM_OP_WRALMAIN;
|
||||
eeprom->count = 20;
|
||||
break;
|
||||
case EEPROM_OP_ERAL:
|
||||
if (!eeprom->wp)
|
||||
{
|
||||
memset(eeprom->data, 0xff, 128);
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
break;
|
||||
case EEPROM_OP_EWEN:
|
||||
eeprom->wp = 0;
|
||||
break;
|
||||
}
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_ERASE:
|
||||
if (!eeprom->wp)
|
||||
{
|
||||
eeprom->data[eeprom->dat] = 0xffff;
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_WRALMAIN:
|
||||
if (!eeprom->wp)
|
||||
{
|
||||
for (c = 0; c < 256; c++)
|
||||
eeprom->data[c] = eeprom->dat;
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
eeprom->oldena = ena;
|
||||
}
|
||||
else if (!clk && eeprom->oldclk)
|
||||
{
|
||||
if (ena)
|
||||
{
|
||||
switch (eeprom->state)
|
||||
{
|
||||
case EEPROM_OUTPUT:
|
||||
eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0;
|
||||
eeprom->dat <<= 1;
|
||||
eeprom->count--;
|
||||
if (!eeprom->count)
|
||||
{
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
eeprom->oldclk = clk;
|
||||
return dev->out;
|
||||
}
|
||||
|
||||
int ati_eeprom_read(ati_eeprom_t *eeprom)
|
||||
{
|
||||
return eeprom->out;
|
||||
}
|
||||
|
||||
|
||||
@@ -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*/
|
||||
@@ -8,13 +8,13 @@
|
||||
*
|
||||
* ATi Mach64 graphics card emulation.
|
||||
*
|
||||
* Version: @(#)vid_ati_mach64.c 1.0.14 2018/10/08
|
||||
* Version: @(#)vid_ati_mach64.c 1.0.15 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
*
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
*
|
||||
@@ -51,7 +51,7 @@
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_svga_render.h"
|
||||
#include "vid_ati_eeprom.h"
|
||||
#include "vid_ati.h"
|
||||
#include "vid_ati68860_ramdac.h"
|
||||
#include "vid_ics2595.h"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Emulation of the old and new IBM CGA graphics cards.
|
||||
*
|
||||
* Version: @(#)vid_cga.c 1.0.11 2019/01/01
|
||||
* Version: @(#)vid_cga.c 1.0.12 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -649,7 +649,7 @@ cga_standalone_init(const device_t *info)
|
||||
cga_palette = (dev->rgb_type << 1);
|
||||
cgapal_rebuild();
|
||||
|
||||
video_load_font(CGA_FONT_ROM_PATH, (dev->font_type) ? 8 : 2);
|
||||
video_load_font(CGA_FONT_ROM_PATH, (dev->font_type) ? 2 : 1);
|
||||
|
||||
video_inform(VID_TYPE_CGA, info->vid_timing);
|
||||
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
*
|
||||
* Emulation of the Tseng Labs ET4000.
|
||||
*
|
||||
* Version: @(#)vid_et4000.c 1.0.13 2018/10/08
|
||||
* Version: @(#)vid_et4000.c 1.0.14 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* GreatPsycho, <greatpsycho@yahoo.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
*
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
*
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "video.h"
|
||||
#include "vid_svga.h"
|
||||
#include "vid_svga_render.h"
|
||||
#include "vid_ati.h" /* for the font loader */
|
||||
#include "vid_sc1502x_ramdac.h"
|
||||
|
||||
|
||||
@@ -155,7 +156,7 @@ et4000k_in(uint16_t addr, void *priv)
|
||||
switch(dev->get_korean_font_enabled) {
|
||||
case 3:
|
||||
if ((dev->port_32cb_val & 0x30) == 0x30) {
|
||||
val = fontdatksc5601[dev->get_korean_font_base].chr[dev->get_korean_font_index++];
|
||||
val = fontdatk[dev->get_korean_font_base].chr[dev->get_korean_font_index++];
|
||||
dev->get_korean_font_index &= 0x1f;
|
||||
} else
|
||||
if ((dev->port_32cb_val & 0x30) == 0x20 &&
|
||||
@@ -164,18 +165,18 @@ et4000k_in(uint16_t addr, void *priv)
|
||||
switch(dev->get_korean_font_base & 0x3f80) {
|
||||
case 0x2480:
|
||||
if (dev->get_korean_font_index < 16)
|
||||
val = fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index];
|
||||
val = fontdatk_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index];
|
||||
else
|
||||
if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40)
|
||||
val = fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8];
|
||||
val = fontdatk_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8];
|
||||
break;
|
||||
|
||||
case 0x3f00:
|
||||
if (dev->get_korean_font_index < 16)
|
||||
val = fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index];
|
||||
val = fontdatk_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index];
|
||||
else
|
||||
if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40)
|
||||
val = fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8];
|
||||
val = fontdatk_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8];
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -358,18 +359,18 @@ et4000k_out(uint16_t addr, uint8_t val, void *priv)
|
||||
switch (dev->get_korean_font_base & 0x3f80) {
|
||||
case 0x2480:
|
||||
if (dev->get_korean_font_index < 16)
|
||||
fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index] = val;
|
||||
fontdatk_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index] = val;
|
||||
else
|
||||
if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40)
|
||||
fontdatksc5601_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8] = val;
|
||||
fontdatk_user[(dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8] = val;
|
||||
break;
|
||||
|
||||
case 0x3f00:
|
||||
if (dev->get_korean_font_index < 16)
|
||||
fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index] = val;
|
||||
fontdatk_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index] = val;
|
||||
else
|
||||
if (dev->get_korean_font_index >= 24 && dev->get_korean_font_index < 40)
|
||||
fontdatksc5601_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8] = val;
|
||||
fontdatk_user[96 + (dev->get_korean_font_base & 0x7f) - 0x20].chr[dev->get_korean_font_index - 8] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -487,9 +488,11 @@ et4000_init(const device_t *info)
|
||||
switch(dev->type) {
|
||||
case 0: /* ISA ET4000AX */
|
||||
dev->vram_size = device_get_config_int("memory") << 10;
|
||||
|
||||
svga_init(&dev->svga, dev, dev->vram_size,
|
||||
et4000_recalctimings, et4000_in, et4000_out,
|
||||
NULL, NULL);
|
||||
|
||||
io_sethandler(0x03c0, 32,
|
||||
et4000_in,NULL,NULL, et4000_out,NULL,NULL, dev);
|
||||
break;
|
||||
@@ -497,11 +500,14 @@ et4000_init(const device_t *info)
|
||||
case 1: /* MCA ET4000AX */
|
||||
dev->is_mca = 1;
|
||||
dev->vram_size = 1024 << 10;
|
||||
|
||||
svga_init(&dev->svga, dev, dev->vram_size,
|
||||
et4000_recalctimings, et4000_in, et4000_out,
|
||||
NULL, NULL);
|
||||
|
||||
io_sethandler(0x03c0, 32,
|
||||
et4000_in,NULL,NULL, et4000_out,NULL,NULL, dev);
|
||||
|
||||
dev->pos_regs[0] = 0xf2; /* ET4000 MCA board ID */
|
||||
dev->pos_regs[1] = 0x80;
|
||||
mca_add(et4000_mca_read, et4000_mca_write, dev);
|
||||
@@ -513,9 +519,17 @@ et4000_init(const device_t *info)
|
||||
dev->port_22cb_val = 0x60;
|
||||
dev->port_32cb_val = 0;
|
||||
dev->svga.ksc5601_sbyte_mask = 0x80;
|
||||
|
||||
svga_init(&dev->svga, dev, dev->vram_size,
|
||||
et4000_recalctimings, et4000k_in, et4000k_out,
|
||||
NULL, NULL);
|
||||
|
||||
if (! ati28800k_load_font(&dev->svga, KOREAN_FONT_ROM_PATH)) {
|
||||
svga_close(&dev->svga);
|
||||
free(dev);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
io_sethandler(0x03c0, 32,
|
||||
et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev);
|
||||
io_sethandler(0x22cb, 1,
|
||||
@@ -524,7 +538,6 @@ et4000_init(const device_t *info)
|
||||
et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev);
|
||||
io_sethandler(0x32cb, 1,
|
||||
et4000k_in,NULL,NULL, et4000k_out,NULL,NULL, dev);
|
||||
video_load_font(KOREAN_FONT_ROM_PATH, 6);
|
||||
fn = KOREAN_BIOS_ROM_PATH;
|
||||
break;
|
||||
}
|
||||
@@ -536,7 +549,7 @@ et4000_init(const device_t *info)
|
||||
rom_init(&dev->bios_rom, fn,
|
||||
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
DEBUG("VIDEO: %s (vram=%dKB)\n", dev->name, dev->vram_size>>10);
|
||||
DEBUG("VIDEO: %s (vram=%iKB)\n", dev->name, dev->vram_size>>10);
|
||||
|
||||
video_inform(VID_TYPE_SPEC,
|
||||
(const video_timings_t *)info->vid_timing);
|
||||
|
||||
@@ -63,13 +63,13 @@
|
||||
* reducing the height of characters so they fit in an 8x12 cell
|
||||
* if necessary.
|
||||
*
|
||||
* Version: @(#)vid_genius.c 1.0.8 2018/10/24
|
||||
* Version: @(#)vid_genius.c 1.0.9 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* John Elliott, <jce@seasip.info>
|
||||
*
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2016-2018 John Elliott.
|
||||
*
|
||||
@@ -107,7 +107,7 @@
|
||||
#include "video.h"
|
||||
|
||||
|
||||
#define BIOS_ROM_PATH L"video/mdsi/genius/8x12.bin"
|
||||
#define FONT_ROM_PATH L"video/mdsi/genius/8x12.bin"
|
||||
|
||||
|
||||
#define GENIUS_XSIZE 728
|
||||
@@ -115,6 +115,8 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
|
||||
mem_map_t mapping;
|
||||
|
||||
uint8_t mda_crtc[32]; /* The 'CRTC' as the host PC sees it */
|
||||
@@ -154,6 +156,8 @@ typedef struct {
|
||||
|
||||
int cols[256][2][2];
|
||||
|
||||
uint8_t fontdat[256][16];
|
||||
|
||||
uint8_t *vram;
|
||||
} genius_t;
|
||||
|
||||
@@ -369,7 +373,7 @@ text_line(genius_t *dev, uint8_t background)
|
||||
}
|
||||
} else {
|
||||
/* Draw 8 pixels of character */
|
||||
bitmap[0] = fontdat8x12[chr][sc];
|
||||
bitmap[0] = dev->fontdat[chr][sc];
|
||||
for (c = 0; c < 8; c++) {
|
||||
col = dev->cols[attr][blink][(bitmap[0] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if (!(dev->enabled) || !(dev->mda_ctrl & 8))
|
||||
@@ -559,6 +563,27 @@ genius_poll(void *priv)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
load_font(genius_t *dev, const wchar_t *s)
|
||||
{
|
||||
FILE *fp;
|
||||
int c;
|
||||
|
||||
fp = plat_fopen(rom_path(s), L"rb");
|
||||
if (fp == NULL) {
|
||||
ERRLOG("%s: cannot load font '%ls'\n", dev->name, s);
|
||||
return(0);
|
||||
}
|
||||
|
||||
for (c = 0; c < 256; c++)
|
||||
(void)fread(&dev->fontdat[c][0], 1, 16, fp);
|
||||
|
||||
(void)fclose(fp);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
genius_init(const device_t *info)
|
||||
{
|
||||
@@ -567,12 +592,16 @@ genius_init(const device_t *info)
|
||||
|
||||
dev = (genius_t *)mem_alloc(sizeof(genius_t));
|
||||
memset(dev, 0x00, sizeof(genius_t));
|
||||
dev->name = info->name;
|
||||
|
||||
if (! load_font(dev, FONT_ROM_PATH)) {
|
||||
free(dev);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* 160k video RAM */
|
||||
dev->vram = (uint8_t *)mem_alloc(0x28000);
|
||||
|
||||
video_load_font(BIOS_ROM_PATH, 4);
|
||||
|
||||
timer_add(genius_poll, &dev->vidtime, TIMER_ALWAYS_ENABLED, dev);
|
||||
|
||||
/* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in
|
||||
@@ -645,7 +674,7 @@ genius_close(void *priv)
|
||||
static int
|
||||
genius_available(void)
|
||||
{
|
||||
return rom_present(BIOS_ROM_PATH);
|
||||
return rom_present(FONT_ROM_PATH);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
* This is implemented by holding a FIFO of unlimited depth in
|
||||
* the IM1024 to receive the data.
|
||||
*
|
||||
* Version: @(#)vid_im1024.c 1.0.2 2019/03/02
|
||||
* Version: @(#)vid_im1024.c 1.0.3 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* John Elliott, <jce@seasip.info>
|
||||
@@ -99,16 +99,14 @@ typedef struct {
|
||||
static void
|
||||
fifo_write(im1024_t *dev, uint8_t val)
|
||||
{
|
||||
#if 0
|
||||
DEBUG(("IM1024: fifo_write: %02x [rd=%04x wr=%04x]\n",
|
||||
val, dev->fifo_rdptr, dev->fifo_wrptr));
|
||||
#endif
|
||||
DBGLOG(1, "IM1024: fifo_write: %02x [rd=%04x wr=%04x]\n",
|
||||
val, dev->fifo_rdptr, dev->fifo_wrptr);
|
||||
|
||||
if (((dev->fifo_wrptr + 1) % dev->fifo_len) == dev->fifo_rdptr) {
|
||||
/* FIFO is full. Double its size. */
|
||||
uint8_t *buf;
|
||||
|
||||
DEBUG("IM1024: fifo_resize: %i to %i\n",
|
||||
DBGLOG(1, "IM1024: fifo_resize: %i to %i\n",
|
||||
dev->fifo_len, 2 * dev->fifo_len);
|
||||
|
||||
buf = realloc(dev->fifo, 2 * dev->fifo_len);
|
||||
@@ -121,10 +119,10 @@ fifo_write(im1024_t *dev, uint8_t val)
|
||||
dev->fifo_len *= 2;
|
||||
}
|
||||
|
||||
/* Append to the queue */
|
||||
/* Append to the queue. */
|
||||
dev->fifo[dev->fifo_wrptr++] = val;
|
||||
|
||||
/* Wrap if end of buffer reached */
|
||||
/* Wrap if end of buffer reached. */
|
||||
if (dev->fifo_wrptr >= dev->fifo_len)
|
||||
dev->fifo_wrptr = 0;
|
||||
}
|
||||
@@ -148,15 +146,18 @@ fifo_read(im1024_t *dev)
|
||||
}
|
||||
|
||||
|
||||
/* Where a normal PGC would just read from the ring buffer at 0xC6300, the
|
||||
* IM-1024 can read either from this or from its internal FIFO. The internal
|
||||
* FIFO has priority. */
|
||||
/*
|
||||
* Where a normal PGC would just read from the ring buffer at 0xC6300,
|
||||
* the IM-1024 can read from either this or from its internal FIFO.
|
||||
*
|
||||
* The internal FIFO has priority.
|
||||
*/
|
||||
static int
|
||||
input_byte(pgc_t *pgc, uint8_t *result)
|
||||
{
|
||||
im1024_t *dev = (im1024_t *)pgc;
|
||||
|
||||
/* If input buffer empty, wait for it to fill */
|
||||
/* If input buffer empty, wait for it to fill. */
|
||||
while ((dev->fifo_wrptr == dev->fifo_rdptr) &&
|
||||
(pgc->mapram[0x300] == pgc->mapram[0x301])) {
|
||||
pgc->waiting_input_fifo = 1;
|
||||
@@ -179,7 +180,7 @@ input_byte(pgc_t *pgc, uint8_t *result)
|
||||
}
|
||||
|
||||
|
||||
/* Macros to disable clipping and save clip state */
|
||||
/* Macros to disable clipping and save clip state. */
|
||||
#define PUSHCLIP { \
|
||||
uint16_t vp_x1, vp_x2, vp_y1, vp_y2; \
|
||||
vp_x1 = pgc->vp_x1; \
|
||||
@@ -206,7 +207,7 @@ im1024_read(uint32_t addr, void *priv)
|
||||
{
|
||||
im1024_t *dev = (im1024_t *)priv;
|
||||
|
||||
if (addr == 0xC6331 && dev->pgc.mapram[0x330] == 1) {
|
||||
if (addr == 0xc6331 && dev->pgc.mapram[0x330] == 1) {
|
||||
/* Hardcode that there are 128 bytes free. */
|
||||
return(0x80);
|
||||
}
|
||||
@@ -221,9 +222,11 @@ im1024_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
im1024_t *dev = (im1024_t *)priv;
|
||||
|
||||
/* If we are in 'fast' input mode, send all writes to the internal
|
||||
* FIFO */
|
||||
if (addr >= 0xC6000 && addr < 0xC6100 && dev->pgc.mapram[0x330] == 1) {
|
||||
/*
|
||||
* If we are in 'fast' input mode, send all
|
||||
* writes to the internal FIFO.
|
||||
*/
|
||||
if (addr >= 0xc6000 && addr < 0xc6100 && dev->pgc.mapram[0x330] == 1) {
|
||||
fifo_write(dev, val);
|
||||
|
||||
DBGLOG(1, "IM1024: write(%02x)\n", val);
|
||||
@@ -239,8 +242,10 @@ im1024_write(uint32_t addr, uint8_t val, void *priv)
|
||||
}
|
||||
|
||||
|
||||
/* I don't know what the IMGSIZ command does, only that the Windows driver
|
||||
* issues it. So just parse and ignore it */
|
||||
/*
|
||||
* I don't know what the IMGSIZ command does, only that the
|
||||
* Windows driver issues it. So just parse and ignore it.
|
||||
*/
|
||||
static void
|
||||
hndl_imgsiz(pgc_t *pgc)
|
||||
{
|
||||
@@ -259,8 +264,10 @@ hndl_imgsiz(pgc_t *pgc)
|
||||
}
|
||||
|
||||
|
||||
/* I don't know what the IPREC command does, only that the Windows driver
|
||||
* issues it. So just parse and ignore it */
|
||||
/*
|
||||
* I don't know what the IPREC command does, only that the
|
||||
* Windows driver issues it. So just parse and ignore it.
|
||||
*/
|
||||
static void
|
||||
hndl_iprec(pgc_t *pgc)
|
||||
{
|
||||
@@ -298,8 +305,10 @@ hndl_linfun(pgc_t *pgc)
|
||||
}
|
||||
|
||||
|
||||
/* I think PAN controls which part of the 1024x1024 framebuffer is displayed
|
||||
* in the 1024x800 visible screen. */
|
||||
/*
|
||||
* I think PAN controls which part of the 1024x1024 framebuffer
|
||||
* is displayed in the 1024x800 visible screen.
|
||||
*/
|
||||
static void
|
||||
hndl_pan(pgc_t *pgc)
|
||||
{
|
||||
@@ -315,7 +324,7 @@ hndl_pan(pgc_t *pgc)
|
||||
}
|
||||
|
||||
|
||||
/* PLINE draws a non-filled polyline at a fixed position */
|
||||
/* PLINE draws a non-filled polyline at a fixed position. */
|
||||
static void
|
||||
hndl_pline(pgc_t *pgc)
|
||||
{
|
||||
@@ -340,9 +349,12 @@ hndl_pline(pgc_t *pgc)
|
||||
}
|
||||
|
||||
|
||||
/* Blit a single row of pixels from one location to another. To avoid
|
||||
* difficulties if the two overlap, read both rows into memory, process them
|
||||
* there, and write the result back. */
|
||||
/*
|
||||
* Blit a single row of pixels from one location to another.
|
||||
*
|
||||
* To avoid difficulties if the two overlap, read both rows
|
||||
* into memory, process them there, and write the result back.
|
||||
*/
|
||||
static void
|
||||
blkmov_row(pgc_t *pgc, int16_t x0, int16_t x1, int16_t x2, int16_t sy, int16_t ty)
|
||||
{
|
||||
@@ -355,37 +367,35 @@ blkmov_row(pgc_t *pgc, int16_t x0, int16_t x1, int16_t x2, int16_t sy, int16_t t
|
||||
dst[x - x0] = pgc_read_pixel(pgc, x - x0 + x2, ty);
|
||||
}
|
||||
|
||||
for (x = x0; x <= x1; x++) {
|
||||
switch (pgc->draw_mode) {
|
||||
default:
|
||||
case 0:
|
||||
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0]);
|
||||
break;
|
||||
for (x = x0; x <= x1; x++) switch (pgc->draw_mode) {
|
||||
default:
|
||||
case 0:
|
||||
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
pgc_write_pixel(pgc, (x - x0 + x2), ty, dst[x - x0] ^ 0xFF);
|
||||
break;
|
||||
case 1:
|
||||
pgc_write_pixel(pgc, (x - x0 + x2), ty, dst[x - x0] ^ 0xff);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] ^ dst[x - x0]);
|
||||
break;
|
||||
case 2:
|
||||
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] ^ dst[x - x0]);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] & dst[x - x0]);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
pgc_write_pixel(pgc, (x - x0 + x2), ty, src[x - x0] & dst[x - x0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* BLKMOV blits a rectangular area from one location to another, with no
|
||||
* clipping. */
|
||||
/*
|
||||
* BLKMOV blits a rectangular area from one location to another.
|
||||
*
|
||||
* Clipping is disabled.
|
||||
*/
|
||||
static void
|
||||
hndl_blkmov(pgc_t *pgc)
|
||||
{
|
||||
#if 0
|
||||
im1024_t *dev = (im1024_t *)pgc;
|
||||
#endif
|
||||
int16_t x0, y0;
|
||||
int16_t x1, y1;
|
||||
int16_t x2, y2;
|
||||
@@ -398,13 +408,15 @@ hndl_blkmov(pgc_t *pgc)
|
||||
if (! pgc_param_word(pgc, &x2)) return;
|
||||
if (! pgc_param_word(pgc, &y2)) return;
|
||||
|
||||
DEBUG("IM1024: BLKMOV %i,%i,%i,%i,%i,%i\n", x0, y0, x1, y1, x2, y2);
|
||||
DEBUG("IM1024: BLKMOV %i,%i,%i,%i,%i,%i\n", x0,y0,x1,y1,x2,y2);
|
||||
|
||||
/* Disable clipping. */
|
||||
PUSHCLIP
|
||||
|
||||
/* Either go down from the top, or up from the bottom, depending
|
||||
* whether areas might overlap */
|
||||
/*
|
||||
* Either go down from the top, or up from the bottom,
|
||||
* depending whether areas might overlap.
|
||||
*/
|
||||
if (y2 <= y0) {
|
||||
for (y = y0; y <= y1; y++)
|
||||
blkmov_row(pgc, x0, x1, x2, y, y - y0 + y2);
|
||||
@@ -418,8 +430,10 @@ hndl_blkmov(pgc_t *pgc)
|
||||
}
|
||||
|
||||
|
||||
/* This overrides the PGC ELIPSE command to parse its parameters as words
|
||||
* rather than coordinates */
|
||||
/*
|
||||
* Override the PGC ELIPSE command to parse its
|
||||
* parameters as words rather than coordinates.
|
||||
*/
|
||||
static void
|
||||
hndl_ellipse(pgc_t *pgc)
|
||||
{
|
||||
@@ -435,8 +449,10 @@ hndl_ellipse(pgc_t *pgc)
|
||||
}
|
||||
|
||||
|
||||
/* This overrides the PGC MOVE command to parse its parameters as words
|
||||
* rather than coordinates */
|
||||
/*
|
||||
* Override the PGC MOVE command to parse its
|
||||
* parameters as words rather than coordinates.
|
||||
*/
|
||||
static void
|
||||
hndl_move(pgc_t *pgc)
|
||||
{
|
||||
@@ -445,15 +461,17 @@ hndl_move(pgc_t *pgc)
|
||||
if (! pgc_param_word(pgc, &x)) return;
|
||||
if (! pgc_param_word(pgc, &y)) return;
|
||||
|
||||
DEBUG("IM1024: MOVE %i,%i\n", x, y);
|
||||
|
||||
pgc->x = x << 16;
|
||||
pgc->y = y << 16;
|
||||
|
||||
DEBUG("IM1024: MOVE %i,%i\n", x, y);
|
||||
}
|
||||
|
||||
|
||||
/* This overrides the PGC DRAW command to parse its parameters as words
|
||||
* rather than coordinates */
|
||||
/*
|
||||
* Override the PGC DRAW command to parse its
|
||||
* parameters as words rather than coordinates.
|
||||
*/
|
||||
static void
|
||||
hndl_draw(pgc_t *pgc)
|
||||
{
|
||||
@@ -465,13 +483,16 @@ hndl_draw(pgc_t *pgc)
|
||||
DEBUG("IM1024: DRAW %i,%i to %i,%i\n", pgc->x >> 16, pgc->y >> 16, x, y);
|
||||
|
||||
pgc_draw_line(pgc, pgc->x, pgc->y, x << 16, y << 16, pgc->line_pattern);
|
||||
|
||||
pgc->x = x << 16;
|
||||
pgc->y = y << 16;
|
||||
}
|
||||
|
||||
|
||||
/* This overrides the PGC POLY command to parse its parameters as words
|
||||
* rather than coordinates */
|
||||
/*
|
||||
* Override the PGC POLY command to parse its
|
||||
* parameters as words rather than coordinates.
|
||||
*/
|
||||
static void
|
||||
hndl_poly(pgc_t *pgc)
|
||||
{
|
||||
@@ -484,7 +505,6 @@ hndl_poly(pgc_t *pgc)
|
||||
|
||||
x = (int32_t *)mem_alloc(as * sizeof(int32_t));
|
||||
y = (int32_t *)mem_alloc(as * sizeof(int32_t));
|
||||
|
||||
if (!x || !y) {
|
||||
DEBUG("IM1024: POLY: out of memory\n");
|
||||
return;
|
||||
@@ -519,9 +539,11 @@ hndl_poly(pgc_t *pgc)
|
||||
realcount++;
|
||||
}
|
||||
|
||||
/* If we are in a command list, peek ahead to see if the next
|
||||
/*
|
||||
* If we are in a command list, peek ahead to see if the next
|
||||
* command is also POLY. If so, that's a continuation of this
|
||||
* polygon! */
|
||||
* polygon!
|
||||
*/
|
||||
parsing = 0;
|
||||
if (pgc->clcur && (pgc->clcur->rdptr+1) < pgc->clcur->wrptr &&
|
||||
pgc->clcur->list[pgc->clcur->rdptr] == 0x30) {
|
||||
@@ -573,8 +595,10 @@ parse_poly(pgc_t *pgc, pgc_cl_t *cl, int c)
|
||||
}
|
||||
|
||||
|
||||
/* This overrides the PGC RECT command to parse its parameters as words
|
||||
* rather than coordinates */
|
||||
/*
|
||||
* Override the PGC RECT command to parse its
|
||||
* parameters as words rather than coordinates.
|
||||
*/
|
||||
static void
|
||||
hndl_rect(pgc_t *pgc)
|
||||
{
|
||||
@@ -586,7 +610,7 @@ hndl_rect(pgc_t *pgc)
|
||||
if (! pgc_param_word(pgc, &x1)) return;
|
||||
if (! pgc_param_word(pgc, &y1)) return;
|
||||
|
||||
/* Convert to raster coords */
|
||||
/* Convert to raster coords. */
|
||||
pgc_sto_raster(pgc, &x0, &y0);
|
||||
pgc_sto_raster(pgc, &x1, &y1);
|
||||
|
||||
@@ -608,8 +632,13 @@ hndl_rect(pgc_t *pgc)
|
||||
}
|
||||
|
||||
|
||||
/* TODO: Text drawing should probably be implemented in vid_pgc.c rather
|
||||
* than vid_im1024.c */
|
||||
/*
|
||||
* FIXME:
|
||||
* Define a font character.
|
||||
*
|
||||
* Text drawing should probably be implemented in
|
||||
* vid_pgc.c rather than here..
|
||||
*/
|
||||
static void
|
||||
hndl_tdefin(pgc_t *pgc)
|
||||
{
|
||||
@@ -619,8 +648,8 @@ hndl_tdefin(pgc_t *pgc)
|
||||
unsigned len, n;
|
||||
|
||||
if (! pgc_param_byte(pgc, &ch)) return;
|
||||
if (! pgc_param_byte(pgc, &rows)) return;
|
||||
if (! pgc_param_byte(pgc, &cols)) return;
|
||||
if (! pgc_param_byte(pgc, &rows)) return;
|
||||
|
||||
DEBUG("IM1024: TDEFIN (%i,%i,%i) 0x%02x 0x%02x\n",
|
||||
ch, rows, cols, pgc->mapram[0x300], pgc->mapram[0x301]);
|
||||
@@ -633,15 +662,27 @@ hndl_tdefin(pgc_t *pgc)
|
||||
dev->font[ch][n] = bt;
|
||||
}
|
||||
|
||||
dev->fontx[ch] = rows;
|
||||
dev->fonty[ch] = cols;
|
||||
dev->fontx[ch] = cols;
|
||||
dev->fonty[ch] = rows;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hndl_tsize(pgc_t *pgc)
|
||||
{
|
||||
int16_t size;
|
||||
|
||||
if (!pgc_param_word(pgc, &size)) return;
|
||||
DEBUG("IM1024: TSIZE(%i)\n", size);
|
||||
|
||||
pgc->tsize = size << 16;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hndl_twrite(pgc_t *pgc)
|
||||
{
|
||||
uint8_t buf[256], rbuf[256];
|
||||
uint8_t buf[256];
|
||||
im1024_t *dev = (im1024_t *)pgc;
|
||||
uint8_t count, mask, *row;
|
||||
int x, y, wb, n;
|
||||
@@ -652,30 +693,21 @@ hndl_twrite(pgc_t *pgc)
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
if (! pgc_param_byte(pgc, &buf[n])) return;
|
||||
|
||||
buf[count] = 0;
|
||||
for (n = 0; n <= count; n++) {
|
||||
if (isprint(buf[n]) || 0 == buf[n])
|
||||
rbuf[n] = buf[n];
|
||||
else
|
||||
rbuf[n] = '?';
|
||||
}
|
||||
|
||||
pgc_sto_raster(pgc, &x0, &y0);
|
||||
|
||||
DEBUG("IM1024: TWRITE (%i,%-*.*s) x0=%i y0=%i\n",
|
||||
count, count, count, rbuf, x0, y0);
|
||||
DEBUG("IM1024: TWRITE (%i) x0=%i y0=%i\n", count, x0, y0);
|
||||
|
||||
for (n = 0; n < count; n++) {
|
||||
wb = (dev->fontx[buf[n]] + 7) / 8;
|
||||
DEBUG("IM1024: ch=0x%02x w=%d h=%i wb=%i\n",
|
||||
DEBUG("IM1024: ch=0x%02x w=%i h=%i wb=%i\n",
|
||||
buf[n], dev->fontx[buf[n]], dev->fonty[buf[n]], wb);
|
||||
|
||||
for (y = 0; y < dev->fonty[buf[n]]; y++) {
|
||||
mask = 0x80;
|
||||
row = &dev->font[buf[n]][y * wb];
|
||||
for (x = 0; x < dev->fontx[buf[n]]; x++) {
|
||||
rbuf[x] = (row[0] & mask) ? '#' : '-';
|
||||
if (row[0] & mask)
|
||||
pgc_plot(pgc, x + x0, y0 - y);
|
||||
mask = mask >> 1;
|
||||
@@ -684,8 +716,50 @@ hndl_twrite(pgc_t *pgc)
|
||||
row++;
|
||||
}
|
||||
}
|
||||
rbuf[x++] = '\n';
|
||||
rbuf[x++] = 0;
|
||||
}
|
||||
|
||||
x0 += dev->fontx[buf[n]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hndl_txt88(pgc_t *pgc)
|
||||
{
|
||||
uint8_t buf[256];
|
||||
im1024_t *dev = (im1024_t *)pgc;
|
||||
uint8_t count, mask, *row;
|
||||
int16_t x0 = pgc->x >> 16;
|
||||
int16_t y0 = pgc->y >> 16;
|
||||
unsigned n;
|
||||
int x, y, wb;
|
||||
|
||||
if (! pgc_param_byte(pgc, &count)) return;
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
if (! pgc_param_byte(pgc, &buf[n])) return;
|
||||
buf[count] = 0;
|
||||
|
||||
pgc_sto_raster(pgc, &x0, &y0);
|
||||
|
||||
DEBUG("IM204: TWRITE (%i) x0=%i y0=%i\n", count, x0, y0);
|
||||
|
||||
for (n = 0; n < count; n++) {
|
||||
wb = (dev->fontx[buf[n]] + 7) / 8;
|
||||
DEBUG("IM1024: ch=0x%02x w=%i h=%i wb=%i\n",
|
||||
buf[n], dev->fontx[buf[n]], dev->fonty[buf[n]], wb);
|
||||
|
||||
for (y = 0; y < dev->fonty[buf[n]]; y++) {
|
||||
mask = 0x80;
|
||||
row = &dev->font[buf[n]][y * wb];
|
||||
for (x = 0; x < dev->fontx[buf[n]]; x++) {
|
||||
if (row[0] & mask) pgc_plot(pgc, x + x0, y0 - y);
|
||||
mask = mask >> 1;
|
||||
if (mask == 0) {
|
||||
mask = 0x80;
|
||||
row++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x0 += dev->fontx[buf[n]];
|
||||
@@ -704,8 +778,7 @@ hndl_imagew(pgc_t *pgc)
|
||||
if (! pgc_param_word(pgc, &col1)) return;
|
||||
if (! pgc_param_word(pgc, &col2)) return;
|
||||
|
||||
/* IMAGEW already uses raster coordinates so there is no need to
|
||||
* convert it */
|
||||
/* Already using raster coordinates, no need to convert. */
|
||||
DEBUG("IM1024: IMAGEW (row=%i,col1=%i,col2=%i)\n", row1, col1, col2);
|
||||
|
||||
vp_x1 = pgc->vp_x1;
|
||||
@@ -728,34 +801,32 @@ hndl_imagew(pgc_t *pgc)
|
||||
pgc_write_pixel(pgc, col1, row1, v1);
|
||||
col1++;
|
||||
}
|
||||
} else {
|
||||
/* In hex mode, it's RLE compressed. */
|
||||
while (col1 <= col2) {
|
||||
if (! pgc_param_byte(pgc, &v1)) return;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* In hex mode, it's RLE compressed. */
|
||||
while (col1 <= col2) {
|
||||
if (! pgc_param_byte(pgc, &v1)) return;
|
||||
|
||||
if (v1 & 0x80) {
|
||||
/* Literal run. */
|
||||
v1 -= 0x7f;
|
||||
while (col1 <= col2 && v1 != 0) {
|
||||
if (v1 & 0x80) {
|
||||
/* Literal run. */
|
||||
v1 -= 0x7f;
|
||||
while (col1 <= col2 && v1 != 0) {
|
||||
if (! pgc_param_byte(pgc, &v2)) return;
|
||||
pgc_write_pixel(pgc, col1, row1, v2);
|
||||
col1++;
|
||||
v1--;
|
||||
}
|
||||
} else {
|
||||
/* Repeated run. */
|
||||
if (! pgc_param_byte(pgc, &v2)) return;
|
||||
pgc_write_pixel(pgc, col1, row1, v2);
|
||||
col1++;
|
||||
v1--;
|
||||
}
|
||||
} else {
|
||||
/* Repeated run. */
|
||||
if (! pgc_param_byte(pgc, &v2)) return;
|
||||
|
||||
v1++;
|
||||
while (col1 <= col2 && v1 != 0) {
|
||||
pgc_write_pixel(pgc, col1, row1, v2);
|
||||
col1++;
|
||||
v1--;
|
||||
}
|
||||
}
|
||||
v1++;
|
||||
while (col1 <= col2 && v1 != 0) {
|
||||
pgc_write_pixel(pgc, col1, row1, v2);
|
||||
col1++;
|
||||
v1--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore clipping. */
|
||||
@@ -774,7 +845,8 @@ hndl_imagew(pgc_t *pgc)
|
||||
static void
|
||||
hndl_dot(pgc_t *pgc)
|
||||
{
|
||||
int16_t x = pgc->x >> 16, y = pgc->y >> 16;
|
||||
int16_t x = pgc->x >> 16,
|
||||
y = pgc->y >> 16;
|
||||
|
||||
pgc_sto_raster(pgc, &x, &y);
|
||||
|
||||
@@ -785,10 +857,12 @@ hndl_dot(pgc_t *pgc)
|
||||
}
|
||||
|
||||
|
||||
/* This command (which I have called IMAGEX, since I don't know its real
|
||||
/*
|
||||
* This command (which I have called IMAGEX, since I don't know its real
|
||||
* name) is a screen-to-memory blit. It reads a rectangle of bytes, rather
|
||||
* than the single row read by IMAGER, and does not attempt to compress
|
||||
* the result */
|
||||
* the result.
|
||||
*/
|
||||
static void
|
||||
hndl_imagex(pgc_t *pgc)
|
||||
{
|
||||
@@ -800,7 +874,7 @@ hndl_imagex(pgc_t *pgc)
|
||||
if (! pgc_param_word(pgc, &x1)) return;
|
||||
if (! pgc_param_word(pgc, &y1)) return;
|
||||
|
||||
/* IMAGEX already uses raster coordinates so don't convert */
|
||||
/* Already using raster coordinates, no need to convert. */
|
||||
DEBUG("IM1024: IMAGEX (%i,%i,%i,%i)\n", x0,y0,x1,y1);
|
||||
|
||||
for (p = y0; p <= y1; p++) {
|
||||
@@ -812,7 +886,8 @@ hndl_imagex(pgc_t *pgc)
|
||||
}
|
||||
|
||||
|
||||
/* Commands implemented by the IM-1024.
|
||||
/*
|
||||
* Commands implemented by the IM-1024.
|
||||
*
|
||||
* TODO: A lot of commands need commandlist parsers.
|
||||
* TODO: The IM-1024 has a lot more commands that are not included here
|
||||
@@ -827,19 +902,22 @@ static const pgc_cmd_t im1024_commands[] = {
|
||||
{ "ELIPSE", 0x39, hndl_ellipse, pgc_parse_words, 2 },
|
||||
{ "EL", 0x39, hndl_ellipse, pgc_parse_words, 2 },
|
||||
{ "IMAGEW", 0xd9, hndl_imagew, NULL, 0 },
|
||||
{ "IW", 0xd9, hndl_imagew, NULL, 0 },
|
||||
{ "IMAGEX", 0xda, hndl_imagex, NULL, 0 },
|
||||
{ "TWRITE", 0x8b, hndl_twrite, NULL, 0 },
|
||||
{ "TDEFIN", 0x84, hndl_tdefin, NULL, 0 },
|
||||
{ "TD", 0x84, hndl_tdefin, NULL, 0 },
|
||||
{ "IPREC", 0xe4, hndl_iprec, NULL, 0 },
|
||||
{ "IMGSIZ", 0x4e, hndl_imgsiz, NULL, 0 },
|
||||
{ "LUT8", 0xe6, pgc_hndl_lut8, NULL, 0 },
|
||||
{ "IPREC", 0xe4, hndl_iprec, NULL, 0 },
|
||||
{ "IW", 0xd9, hndl_imagew, NULL, 0 },
|
||||
{ "L8", 0xe6, pgc_hndl_lut8, NULL, 0 },
|
||||
{ "LINFUN", 0xeb, hndl_linfun, pgc_parse_bytes, 1 },
|
||||
{ "LF", 0xeb, hndl_linfun, pgc_parse_bytes, 1 },
|
||||
{ "LINFUN", 0xeb, hndl_linfun, pgc_parse_bytes, 1 },
|
||||
{ "LUT8", 0xe6, pgc_hndl_lut8, NULL, 0 },
|
||||
{ "LUT8RD", 0x53, pgc_hndl_lut8rd,NULL, 0 },
|
||||
{ "L8RD", 0x53, pgc_hndl_lut8rd,NULL, 0 },
|
||||
{ "TDEFIN", 0x84, hndl_tdefin, NULL, 0 },
|
||||
{ "TD", 0x84, hndl_tdefin, NULL, 0 },
|
||||
{ "TSIZE", 0x81, hndl_tsize, NULL, 0 },
|
||||
{ "TS", 0x81, hndl_tsize, NULL, 0 },
|
||||
{ "TWRITE", 0x8b, hndl_twrite, NULL, 0 },
|
||||
{ "TXT88", 0x88, hndl_txt88, NULL, 0 },
|
||||
{ "PAN", 0xb7, hndl_pan, NULL, 0 },
|
||||
{ "POLY", 0x30, hndl_poly, parse_poly, 0 },
|
||||
{ "P", 0x30, hndl_poly, parse_poly, 0 },
|
||||
@@ -861,8 +939,8 @@ im1024_init(const device_t *info)
|
||||
dev = (im1024_t *)mem_alloc(sizeof(im1024_t));
|
||||
memset(dev, 0x00, sizeof(im1024_t));
|
||||
|
||||
dev->fifo = (uint8_t *)mem_alloc(4096);
|
||||
dev->fifo_len = 4096;
|
||||
dev->fifo = (uint8_t *)mem_alloc(dev->fifo_len);
|
||||
dev->fifo_wrptr = 0;
|
||||
dev->fifo_rdptr = 0;
|
||||
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
* instructions left there for it. We simulate this behavior
|
||||
* with a separate thread.
|
||||
*
|
||||
* **NOTE** This driver does not yet work, pending (proper) conversion
|
||||
* to the video backend, which is different from PCem's:
|
||||
* **NOTE** This driver is not finished yet:
|
||||
*
|
||||
* - cursor will blink at very high speed if used on a machine
|
||||
* with clock greater than 4.77MHz. We should "scale down"
|
||||
@@ -43,10 +42,9 @@
|
||||
*
|
||||
* - test it with the Windows 1.x driver?
|
||||
*
|
||||
* Until these are fixed, both the PGC as well as the IM1024
|
||||
* will remain in DevBranch mode.
|
||||
* This is expected to be done shortly.
|
||||
*
|
||||
* Version: @(#)vid_pgc.c 1.0.2 2019/03/02
|
||||
* Version: @(#)vid_pgc.c 1.0.2 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* John Elliott, <jce@seasip.info>
|
||||
@@ -357,7 +355,7 @@ static void
|
||||
hndl_clbeg(pgc_t *dev)
|
||||
{
|
||||
const pgc_cmd_t *cmd;
|
||||
uint8_t param;
|
||||
uint8_t param = 0;
|
||||
pgc_cl_t cl;
|
||||
|
||||
if (! pgc_param_byte(dev, ¶m)) return;
|
||||
@@ -409,7 +407,7 @@ static void
|
||||
hndl_clrun(pgc_t *dev)
|
||||
{
|
||||
pgc_cl_t *clprev = dev->clcur;
|
||||
uint8_t param;
|
||||
uint8_t param = 0;
|
||||
|
||||
if (! pgc_param_byte(dev, ¶m)) return;
|
||||
|
||||
@@ -425,8 +423,8 @@ static void
|
||||
hndl_cloop(pgc_t *dev)
|
||||
{
|
||||
pgc_cl_t *clprev = dev->clcur;
|
||||
uint8_t param;
|
||||
int16_t repeat;
|
||||
uint8_t param = 0;
|
||||
int16_t repeat = 0;
|
||||
|
||||
if (! pgc_param_byte(dev, ¶m)) return;
|
||||
if (! pgc_param_word(dev, &repeat)) return;
|
||||
@@ -442,7 +440,7 @@ hndl_cloop(pgc_t *dev)
|
||||
static void
|
||||
hndl_clread(pgc_t *dev)
|
||||
{
|
||||
uint8_t param;
|
||||
uint8_t param = 0;
|
||||
uint32_t n;
|
||||
|
||||
if (! pgc_param_byte(dev, ¶m)) return;
|
||||
@@ -458,7 +456,7 @@ hndl_clread(pgc_t *dev)
|
||||
static void
|
||||
hndl_cldel(pgc_t *dev)
|
||||
{
|
||||
uint8_t param;
|
||||
uint8_t param = 0;
|
||||
|
||||
if (! pgc_param_byte(dev, ¶m)) return;
|
||||
|
||||
@@ -470,7 +468,7 @@ hndl_cldel(pgc_t *dev)
|
||||
static void
|
||||
hndl_clears(pgc_t *dev)
|
||||
{
|
||||
uint8_t param;
|
||||
uint8_t param = 0;
|
||||
uint32_t y;
|
||||
|
||||
if (! pgc_param_byte(dev, ¶m)) return;
|
||||
@@ -484,7 +482,7 @@ hndl_clears(pgc_t *dev)
|
||||
static void
|
||||
hndl_color(pgc_t *dev)
|
||||
{
|
||||
uint8_t param;
|
||||
uint8_t param = 0;
|
||||
|
||||
if (! pgc_param_byte(dev, ¶m)) return;
|
||||
|
||||
@@ -502,7 +500,7 @@ hndl_color(pgc_t *dev)
|
||||
static void
|
||||
hndl_linfun(pgc_t *dev)
|
||||
{
|
||||
uint8_t param;
|
||||
uint8_t param = 0;
|
||||
|
||||
if (! pgc_param_byte(dev, ¶m)) return;
|
||||
|
||||
@@ -518,7 +516,7 @@ hndl_linfun(pgc_t *dev)
|
||||
static void
|
||||
hndl_linpat(pgc_t *dev)
|
||||
{
|
||||
uint16_t param;
|
||||
uint16_t param = 0;
|
||||
|
||||
if (! pgc_param_word(dev, (int16_t *)¶m)) return;
|
||||
|
||||
@@ -531,7 +529,7 @@ hndl_linpat(pgc_t *dev)
|
||||
static void
|
||||
hndl_prmfil(pgc_t *dev)
|
||||
{
|
||||
uint8_t param;
|
||||
uint8_t param = 0;
|
||||
|
||||
if (! pgc_param_byte(dev, ¶m)) return;
|
||||
|
||||
@@ -547,7 +545,7 @@ hndl_prmfil(pgc_t *dev)
|
||||
static void
|
||||
hndl_move(pgc_t *dev)
|
||||
{
|
||||
int32_t x, y;
|
||||
int32_t x = 0, y = 0;
|
||||
|
||||
if (! pgc_param_coord(dev, &x)) return;
|
||||
if (! pgc_param_coord(dev, &y)) return;
|
||||
@@ -563,7 +561,7 @@ hndl_move(pgc_t *dev)
|
||||
static void
|
||||
hndl_move3(pgc_t *dev)
|
||||
{
|
||||
int32_t x, y, z;
|
||||
int32_t x = 0, y = 0, z = 0;
|
||||
|
||||
if (! pgc_param_coord(dev, &x)) return;
|
||||
if (! pgc_param_coord(dev, &y)) return;
|
||||
@@ -579,7 +577,7 @@ hndl_move3(pgc_t *dev)
|
||||
static void
|
||||
hndl_mover(pgc_t *dev)
|
||||
{
|
||||
int32_t x, y;
|
||||
int32_t x = 0, y = 0;
|
||||
|
||||
if (! pgc_param_coord(dev, &x)) return;
|
||||
if (! pgc_param_coord(dev, &y)) return;
|
||||
@@ -593,7 +591,7 @@ hndl_mover(pgc_t *dev)
|
||||
static void
|
||||
hndl_mover3(pgc_t *dev)
|
||||
{
|
||||
int32_t x, y, z;
|
||||
int32_t x = 0, y = 0, z = 0;
|
||||
|
||||
if (! pgc_param_coord(dev, &x)) return;
|
||||
if (! pgc_param_coord(dev, &y)) return;
|
||||
@@ -952,7 +950,7 @@ pgc_draw_ellipse(pgc_t *dev, int32_t x, int32_t y)
|
||||
static void
|
||||
hndl_ellipse(pgc_t *dev)
|
||||
{
|
||||
int32_t x, y;
|
||||
int32_t x = 0, y = 0;
|
||||
|
||||
if (! pgc_param_coord(dev, &x)) return;
|
||||
if (! pgc_param_coord(dev, &y)) return;
|
||||
@@ -1008,6 +1006,8 @@ hndl_display(pgc_t *dev)
|
||||
|
||||
if (! pgc_param_byte(dev, ¶m)) return;
|
||||
|
||||
DEBUG("PGC: DISPLAY(%i)\n", param);
|
||||
|
||||
if (param > 1)
|
||||
pgc_error(dev, PGC_ERROR_RANGE);
|
||||
else
|
||||
@@ -1253,6 +1253,19 @@ hndl_tjust(pgc_t *dev)
|
||||
}
|
||||
|
||||
|
||||
/* TSIZE controls text horizontal spacing. */
|
||||
static void
|
||||
hndl_tsize(pgc_t *pgc)
|
||||
{
|
||||
int32_t param;
|
||||
|
||||
if (! pgc_param_coord(pgc, ¶m)) return;
|
||||
|
||||
DEBUG("PGC: TSIZE %i\n", param);
|
||||
pgc->tsize = param;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* VWPORT sets up the viewport (roughly, the clip rectangle) in
|
||||
* raster coordinates, measured from the bottom left of the screen.
|
||||
@@ -1369,6 +1382,8 @@ static const pgc_cmd_t pgc_commands[] = {
|
||||
{ "RF", 0x04, hndl_resetf, NULL, 0 },
|
||||
{ "TJUST", 0x85, hndl_tjust, pgc_parse_bytes, 2 },
|
||||
{ "TJ", 0x85, hndl_tjust, pgc_parse_bytes, 2 },
|
||||
{ "TSIZE", 0x81, hndl_tsize, pgc_parse_coords, 1 },
|
||||
{ "TS", 0x81, hndl_tsize, pgc_parse_coords, 1 },
|
||||
{ "VWPORT", 0xb2, hndl_vwport, pgc_parse_words, 4 },
|
||||
{ "VWP", 0xb2, hndl_vwport, pgc_parse_words, 4 },
|
||||
{ "WINDOW", 0xb3, hndl_window, pgc_parse_words, 4 },
|
||||
@@ -1508,6 +1523,8 @@ pgc_reset(pgc_t *dev)
|
||||
|
||||
/* The 'CGA disable' jumper is not currently implemented. */
|
||||
dev->mapram[0x30b] = dev->cga_enabled = 1;
|
||||
dev->mapram[0x30c] = dev->cga_enabled;
|
||||
dev->mapram[0x30d] = dev->cga_enabled;
|
||||
|
||||
dev->mapram[0x3f8] = 0x03; /* minor version */
|
||||
dev->mapram[0x3f9] = 0x01; /* minor version */
|
||||
@@ -1556,6 +1573,9 @@ pgc_reset(pgc_t *dev)
|
||||
void
|
||||
pgc_setdisplay(pgc_t *dev, int cga)
|
||||
{
|
||||
DEBUG("PGC: setdisplay(%i): cga_selected=%i cga_enabled=%i\n",
|
||||
cga, dev->cga_selected, dev->cga_enabled);
|
||||
|
||||
if (dev->cga_selected != (dev->cga_enabled && cga)) {
|
||||
dev->cga_selected = (dev->cga_enabled && cga);
|
||||
|
||||
@@ -1626,7 +1646,10 @@ pgc_clist_byte(pgc_t *dev, uint8_t *val)
|
||||
{
|
||||
if (dev->clcur == NULL) return 0;
|
||||
|
||||
*val = dev->clcur->list[dev->clcur->rdptr++];
|
||||
if (dev->clcur->rdptr < dev->clcur->wrptr)
|
||||
*val = dev->clcur->list[dev->clcur->rdptr++];
|
||||
else
|
||||
*val = 0;
|
||||
|
||||
/* If we've reached the end, reset to the beginning and
|
||||
* (if repeating) run the repeat */
|
||||
@@ -2139,6 +2162,7 @@ pgc_write(uint32_t addr, uint8_t val, void *priv)
|
||||
|
||||
if (dev->mapram[addr] != val) {
|
||||
dev->mapram[addr] = val;
|
||||
|
||||
switch (addr) {
|
||||
case 0x300: /* input write pointer */
|
||||
if (dev->waiting_input_fifo &&
|
||||
@@ -2174,7 +2198,7 @@ pgc_write(uint32_t addr, uint8_t val, void *priv)
|
||||
dev->mapram[0x30d] = dev->mapram[0x30c];
|
||||
break;
|
||||
|
||||
case 0x3ff: /* reboot the PGC */
|
||||
case 0x3ff: /* reboot the PGC */
|
||||
pgc_wake(dev);
|
||||
break;
|
||||
}
|
||||
@@ -2226,9 +2250,8 @@ pgc_cga_text(pgc_t *dev, int w)
|
||||
ma += (dev->displine / pitch) * w;
|
||||
|
||||
for (x = 0; x < w; x++) {
|
||||
chr = addr[0];
|
||||
attr = addr[1];
|
||||
addr += 2;
|
||||
chr = *addr++;
|
||||
attr = *addr++;
|
||||
|
||||
/* Cursor enabled? */
|
||||
if (ma == ca && (dev->cgablink & 8) &&
|
||||
@@ -2239,13 +2262,13 @@ pgc_cga_text(pgc_t *dev, int w)
|
||||
drawcursor = 0;
|
||||
|
||||
if (dev->mapram[0x3d8] & 0x20) {
|
||||
cols[1] = attr & 15;
|
||||
cols[0] = (attr >> 4) & 7;
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((dev->cgablink & 8) && (attr & 0x80) && !drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
cols[1] = attr & 15;
|
||||
cols[0] = attr >> 4;
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
|
||||
for (c = 0; c < cw; c++) {
|
||||
@@ -2272,8 +2295,8 @@ pgc_cga_gfx40(pgc_t *dev)
|
||||
uint8_t *addr;
|
||||
uint16_t dat;
|
||||
|
||||
cols[0] = dev->mapram[0x3d9] & 15;
|
||||
col = (dev->mapram[0x3d9] & 16) ? 8 : 0;
|
||||
cols[0] = (dev->mapram[0x3d9] & 15) + 16;
|
||||
col = ((dev->mapram[0x3d9] & 16) ? 8 : 0) + 16;
|
||||
|
||||
if (dev->mapram[0x3d8] & 4) {
|
||||
cols[1] = col | 3;
|
||||
@@ -2312,8 +2335,8 @@ pgc_cga_gfx80(pgc_t *dev)
|
||||
uint8_t *addr;
|
||||
uint16_t dat;
|
||||
|
||||
cols[0] = 0;
|
||||
cols[1] = dev->mapram[0x3d9] & 15;
|
||||
cols[0] = 16;
|
||||
cols[1] = (dev->mapram[0x3d9] & 15) + 16;
|
||||
|
||||
for (x = 0; x < 40; x++) {
|
||||
addr = &dev->cga_vram[(ma + 2 * x + 80 * (dev->displine >> 2) + 0x2000 * ((dev->displine >> 1) & 1)) & 0x3fff];
|
||||
@@ -2332,7 +2355,6 @@ void
|
||||
pgc_cga_poll(pgc_t *dev)
|
||||
{
|
||||
uint32_t cols[2];
|
||||
int c;
|
||||
|
||||
if (! dev->linepos) {
|
||||
dev->vidtime += dev->dispofftime;
|
||||
@@ -2352,13 +2374,10 @@ pgc_cga_poll(pgc_t *dev)
|
||||
else
|
||||
pgc_cga_text(dev, 40);
|
||||
} else {
|
||||
cols[0] = ((dev->mapram[0x03d8] & 0x12) == 0x12) ? 0 : (dev->mapram[0x03d9] & 15);
|
||||
cols[0] = ((dev->mapram[0x03d8] & 0x12) == 0x12) ? 0 : ((dev->mapram[0x03d9] & 15) + 16);
|
||||
cga_hline(buffer, 0, dev->displine, PGC_CGA_WIDTH, cols[0]);
|
||||
}
|
||||
|
||||
for (c = 0; c < PGC_CGA_WIDTH; c++)
|
||||
((uint32_t *)buffer32->line[dev->displine])[c] = *((uint32_t *)&cgapal[buffer->line[dev->displine][c] & 0x0f]);
|
||||
|
||||
if (++dev->displine == PGC_CGA_HEIGHT) {
|
||||
dev->mapram[0x3da] |= 8;
|
||||
dev->cgadispon = 0;
|
||||
@@ -2383,7 +2402,7 @@ pgc_cga_poll(pgc_t *dev)
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
video_blit_memtoscreen(0, 0, 0, ysize, xsize, ysize);
|
||||
video_blit_memtoscreen_8(0, 0, 0, ysize, xsize, ysize);
|
||||
frames++;
|
||||
|
||||
/* We have a fixed 640x400 screen for CGA modes. */
|
||||
@@ -2434,14 +2453,13 @@ pgc_poll(void *priv)
|
||||
* 224. */
|
||||
y = dev->displine - 2 * dev->pan_y;
|
||||
for (x = 0; x < dev->screenw; x++) {
|
||||
if (x + dev->pan_x < dev->maxw) {
|
||||
buffer->line[dev->displine][x] = dev->palette[dev->vram[y * dev->maxw + x]];
|
||||
} else {
|
||||
buffer->line[dev->displine][x] = dev->palette[0];
|
||||
}
|
||||
if (x + dev->pan_x < dev->maxw)
|
||||
((uint32_t *)buffer32->line[dev->displine])[x] = dev->palette[dev->vram[y * dev->maxw + x]];
|
||||
else
|
||||
((uint32_t *)buffer32->line[dev->displine])[x] = dev->palette[0];
|
||||
}
|
||||
} else {
|
||||
cga_hline(buffer, 0, dev->displine, dev->screenw, dev->palette[0]);
|
||||
cga_hline(buffer32, 0, dev->displine, dev->screenw, dev->palette[0]);
|
||||
}
|
||||
|
||||
if (++dev->displine == dev->screenh) {
|
||||
@@ -2557,7 +2575,6 @@ pgc_init(pgc_t *dev, int maxw, int maxh, int visw, int vish,
|
||||
dev->pgc_wake_thread = thread_create_event();
|
||||
dev->pgc_thread = thread_create(pgc_thread, dev);
|
||||
|
||||
pclog_repeat(0);
|
||||
timer_add(pgc_poll, &dev->vidtime, TIMER_ALWAYS_ENABLED, dev);
|
||||
|
||||
timer_add(wake_timer, &dev->wake_timer, &dev->wake_timer, (void *)dev);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the PGC driver.
|
||||
*
|
||||
* Version: @(#)vid_pgc.h 1.0.2 2019/03/02
|
||||
* Version: @(#)vid_pgc.h 1.0.2 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* John Elliott, <jce@seasip.info>
|
||||
@@ -101,6 +101,7 @@ typedef struct pgc {
|
||||
uint8_t color;
|
||||
uint8_t tjust_h; /* hor alignment 1=left 2=ctr 3=right*/
|
||||
uint8_t tjust_v; /* vert alignment 1=bottom 2=ctr 3=top*/
|
||||
int32_t tsize; /* horizontal spacing */
|
||||
|
||||
int32_t x, y, z; /* drawing position */
|
||||
|
||||
@@ -126,8 +127,9 @@ typedef struct pgc {
|
||||
uint16_t ma, maback;
|
||||
int oddeven;
|
||||
|
||||
int dispontime, dispofftime;
|
||||
int64_t vidtime;
|
||||
int64_t dispontime,
|
||||
dispofftime,
|
||||
vidtime;
|
||||
|
||||
int drawcursor;
|
||||
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
* even-numbered columns, so the top bit of the control register
|
||||
* at 0x2D9 is used to adjust the position.
|
||||
*
|
||||
* Version: @(#)vid_sigma.c 1.0.2 2018/11/03
|
||||
* Version: @(#)vid_sigma.c 1.0.3 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* John Elliott, <jce@seasip.info>
|
||||
*
|
||||
* Copyright 2018 Fred N. van Kempen.
|
||||
* Copyright 2018,2019 Fred N. van Kempen.
|
||||
* Copyright 2018 Miran Grca.
|
||||
* Copyright 2018 John Elliott.
|
||||
*
|
||||
@@ -165,6 +165,8 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
|
||||
mem_map_t mapping,
|
||||
bios_ram;
|
||||
|
||||
@@ -213,6 +215,8 @@ typedef struct {
|
||||
int64_t vidtime;
|
||||
|
||||
uint8_t *vram;
|
||||
uint8_t fontdat[256][8]; /* 8x8 font */
|
||||
uint8_t fontdat16[256][16]; /* 8x16 font */
|
||||
uint8_t bram[2048];
|
||||
uint8_t palette[16];
|
||||
} sigma_t;
|
||||
@@ -485,16 +489,16 @@ sigma_text80(sigma_t *dev)
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
if (dev->sigmamode & MODE_FONT16)
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(dev->fontdat16[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
|
||||
else
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(fontdat[chr][dev->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(dev->fontdat[chr][dev->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
if (dev->sigmamode & MODE_FONT16)
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(dev->fontdat16[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
else
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(fontdat[chr][dev->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer->line[dev->displine][(x << 3) + c + 8] = cols[(dev->fontdat[chr][dev->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
++ma;
|
||||
@@ -540,12 +544,12 @@ sigma_text40(sigma_t *dev)
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer->line[dev->displine][(x << 4) + 2*c + 8] =
|
||||
buffer->line[dev->displine][(x << 4) + 2*c + 9] = cols[(fontdatm[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
|
||||
buffer->line[dev->displine][(x << 4) + 2*c + 9] = cols[(dev->fontdat16[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 0x0f;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer->line[dev->displine][(x << 4) + 2*c + 8] =
|
||||
buffer->line[dev->displine][(x << 4) + 2*c + 9] = cols[(fontdatm[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer->line[dev->displine][(x << 4) + 2*c + 9] = cols[(dev->fontdat16[chr][dev->sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
ma++;
|
||||
@@ -836,11 +840,47 @@ sigma_poll(void *priv)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
load_font(sigma_t *dev, const wchar_t *s)
|
||||
{
|
||||
FILE *fp;
|
||||
int c;
|
||||
|
||||
fp = plat_fopen(rom_path(s), L"rb");
|
||||
if (fp == NULL) {
|
||||
ERRLOG("%s: cannot load font '%ls'\n", dev->name, s);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* The first 4K of the character ROM holds an 8x8 font. */
|
||||
for (c = 0; c < 256; c++) {
|
||||
(void)fread(&dev->fontdat[c][0], 1, 8, fp);
|
||||
(void)fseek(fp, 8, SEEK_CUR);
|
||||
}
|
||||
|
||||
/* The second 4K holds an 8x16 font. */
|
||||
for (c = 0; c < 256; c++)
|
||||
(void)fread(&dev->fontdat16[c][0], 1, 16, fp);
|
||||
|
||||
(void)fclose(fp);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
sigma_init(const device_t *info)
|
||||
{
|
||||
sigma_t *dev = malloc(sizeof(sigma_t));
|
||||
memset(dev, 0, sizeof(sigma_t));
|
||||
sigma_t *dev;
|
||||
|
||||
dev = (sigma_t *)mem_alloc(sizeof(sigma_t));
|
||||
memset(dev, 0x00, sizeof(sigma_t));
|
||||
dev->name = info->name;
|
||||
|
||||
if (! load_font(dev, FONT_ROM_PATH)) {
|
||||
free(dev);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
dev->enable_nmi = device_get_config_int("enable_nmi");
|
||||
|
||||
@@ -855,8 +895,6 @@ sigma_init(const device_t *info)
|
||||
sigma_read,NULL,NULL, sigma_write,NULL,NULL,
|
||||
NULL, MEM_MAPPING_EXTERNAL, dev);
|
||||
|
||||
video_load_font(FONT_ROM_PATH, 7);
|
||||
|
||||
rom_init(&dev->bios_rom, BIOS_ROM_PATH,
|
||||
0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
*
|
||||
* SVGA renderers.
|
||||
*
|
||||
* Version: @(#)vid_svga_render.c 1.0.13 2018/10/22
|
||||
* Version: @(#)vid_svga_render.c 1.0.14 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
*
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
*
|
||||
@@ -246,9 +246,9 @@ svga_render_text_80_ksc5601(svga_t *svga)
|
||||
|
||||
if(x + xinc < svga->hdisp && (chr & (nextchr | svga->ksc5601_sbyte_mask) & 0x80)) {
|
||||
if ((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff))
|
||||
dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc];
|
||||
dat = fontdatk_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc];
|
||||
else if (nextchr & 0x80)
|
||||
dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc];
|
||||
dat = fontdatk[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc];
|
||||
else
|
||||
dat = 0xff;
|
||||
} else {
|
||||
@@ -292,9 +292,9 @@ svga_render_text_80_ksc5601(svga_t *svga)
|
||||
}
|
||||
|
||||
if ((chr == 0xc9 || chr == 0xfe) && (nextchr > 0xa0 && nextchr < 0xff))
|
||||
dat = fontdatksc5601_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc + 16];
|
||||
dat = fontdatk_user[(chr == 0xfe ? 96 : 0) + (nextchr & 0x7F) - 0x20].chr[svga->sc + 16];
|
||||
else if (nextchr & 0x80)
|
||||
dat = fontdatksc5601[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16];
|
||||
dat = fontdatk[((chr & 0x7F) << 7) | (nextchr & 0x7F)].chr[svga->sc + 16];
|
||||
else
|
||||
dat = 0xff;
|
||||
|
||||
|
||||
@@ -53,13 +53,13 @@
|
||||
* What doesn't work, is untested or not well understood:
|
||||
* - Cursor detach (commands 4 and 5)
|
||||
*
|
||||
* Version: @(#)vid_wy700.c 1.0.5 2018/09/22
|
||||
* Version: @(#)vid_wy700.c 1.0.6 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
*
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
*
|
||||
@@ -93,13 +93,14 @@
|
||||
#include "../../timer.h"
|
||||
#include "../../device.h"
|
||||
#include "../system/pit.h"
|
||||
#include "../../plat.h"
|
||||
#include "video.h"
|
||||
|
||||
|
||||
#define WY700_XSIZE 1280
|
||||
#define WY700_YSIZE 800
|
||||
|
||||
#define BIOS_ROM_PATH L"video/wyse/wyse700/wy700.rom"
|
||||
#define FONT_ROM_PATH L"video/wyse/wyse700/wy700.rom"
|
||||
|
||||
|
||||
/* The microcontroller sets up the real CRTC with one of five fixed mode
|
||||
@@ -186,11 +187,9 @@ static const uint8_t mode_40x24[] = {
|
||||
};
|
||||
|
||||
|
||||
/* Font ROM: Two fonts, each containing 256 characters, 16x16 pixels */
|
||||
extern uint8_t fontdatw[512][32];
|
||||
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
|
||||
mem_map_t mapping;
|
||||
|
||||
/* The microcontroller works by watching four ports:
|
||||
@@ -239,6 +238,9 @@ typedef struct {
|
||||
/* ... and MDA emulation. */
|
||||
int mdacols[256][2][2];
|
||||
|
||||
/* Font ROM: Two fonts, each containing 256 characters, 16x16 pixels */
|
||||
uint8_t fontdat[512][32];
|
||||
|
||||
uint8_t *vram;
|
||||
} wy700_t;
|
||||
|
||||
@@ -528,14 +530,13 @@ text_line(wy700_t *dev)
|
||||
int cw = (dev->wy700_mode == 0) ? 32 : 16;
|
||||
uint8_t chr, attr;
|
||||
uint8_t bitmap[2];
|
||||
uint8_t *fontbase = &fontdatw[0][0];
|
||||
uint8_t *fontbase = &dev->fontdat[0][0];
|
||||
int blink, c;
|
||||
int drawcursor, cursorline;
|
||||
int mda = 0;
|
||||
uint16_t addr;
|
||||
uint8_t sc;
|
||||
|
||||
|
||||
/* The fake CRTC character height register selects whether MDA or CGA
|
||||
* attributes are used */
|
||||
if (dev->cga_crtc[9] == 0 || dev->cga_crtc[9] == 13) {
|
||||
@@ -854,6 +855,27 @@ wy700_poll(void *priv)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
load_font(wy700_t *dev, const wchar_t *s)
|
||||
{
|
||||
FILE *fp;
|
||||
int c;
|
||||
|
||||
fp = plat_fopen(rom_path(s), L"rb");
|
||||
if (fp == NULL) {
|
||||
ERRLOG("%s: cannot load font '%ls'\n", dev->name, s);
|
||||
return(0);
|
||||
}
|
||||
|
||||
for (c = 0; c < 512; c++)
|
||||
(void)fread(&dev->fontdat[c][0], 1, 32, fp);
|
||||
|
||||
(void)fclose(fp);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
wy700_init(const device_t *info)
|
||||
{
|
||||
@@ -862,12 +884,16 @@ wy700_init(const device_t *info)
|
||||
|
||||
dev = (wy700_t *)mem_alloc(sizeof(wy700_t));
|
||||
memset(dev, 0x00, sizeof(wy700_t));
|
||||
dev->name = info->name;
|
||||
|
||||
/* 128k video RAM */
|
||||
if (! load_font(dev, FONT_ROM_PATH)) {
|
||||
free(dev);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* 128K video RAM */
|
||||
dev->vram = (uint8_t *)mem_alloc(0x20000);
|
||||
|
||||
video_load_font(BIOS_ROM_PATH, 3);
|
||||
|
||||
timer_add(wy700_poll, &dev->vidtime, TIMER_ALWAYS_ENABLED, dev);
|
||||
|
||||
/* Occupy memory between 0xB0000 and 0xBFFFF (moves to 0xA0000 in
|
||||
@@ -979,7 +1005,7 @@ wy700_close(void *priv)
|
||||
static int
|
||||
wy700_available(void)
|
||||
{
|
||||
return rom_present(BIOS_ROM_PATH);
|
||||
return rom_present(FONT_ROM_PATH);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
* W = 3 bus clocks
|
||||
* L = 4 bus clocks
|
||||
*
|
||||
* Version: @(#)video.c 1.0.25 2019/03/02
|
||||
* Version: @(#)video.c 1.0.25 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -91,14 +91,15 @@
|
||||
#ifdef ENABLE_VIDEO_LOG
|
||||
int video_do_log = ENABLE_VIDEO_LOG;
|
||||
#endif
|
||||
|
||||
/* These will go away soon. */
|
||||
uint8_t fontdat[256][8]; /* IBM CGA font */
|
||||
uint8_t fontdatm[256][16]; /* IBM MDA font */
|
||||
dbcs_font_t *fontdatk = NULL, /* Korean KSC-5601 font */
|
||||
*fontdatk_user = NULL; /* Korean KSC-5601 font (user)*/
|
||||
|
||||
bitmap_t *buffer = NULL,
|
||||
*buffer32 = NULL;
|
||||
uint8_t fontdat[2048][8]; /* IBM CGA font */
|
||||
uint8_t fontdatm[2048][16]; /* IBM MDA font */
|
||||
uint8_t fontdatw[512][32]; /* Wyse700 font */
|
||||
uint8_t fontdat8x12[256][16]; /* MDSI Genius font */
|
||||
dbcs_font_t *fontdatksc5601 = NULL, /* Korean KSC-5601 font */
|
||||
*fontdatksc5601_user = NULL; /* Korean KSC-5601 font (user)*/
|
||||
uint32_t pal_lookup[256];
|
||||
int xsize = 1,
|
||||
ysize = 1;
|
||||
@@ -884,14 +885,14 @@ video_type(void)
|
||||
void
|
||||
video_reset_font(void)
|
||||
{
|
||||
if (fontdatksc5601 != NULL) {
|
||||
free(fontdatksc5601);
|
||||
fontdatksc5601 = NULL;
|
||||
if (fontdatk != NULL) {
|
||||
free(fontdatk);
|
||||
fontdatk = NULL;
|
||||
}
|
||||
|
||||
if (fontdatksc5601_user != NULL) {
|
||||
free(fontdatksc5601_user);
|
||||
fontdatksc5601_user = NULL;
|
||||
if (fontdatk_user != NULL) {
|
||||
free(fontdatk_user);
|
||||
fontdatk_user = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -901,11 +902,11 @@ void
|
||||
video_load_font(const wchar_t *s, int format)
|
||||
{
|
||||
FILE *fp;
|
||||
int c, d;
|
||||
int c;
|
||||
|
||||
fp = plat_fopen(rom_path(s), L"rb");
|
||||
if (fp == NULL) {
|
||||
ERRLOG("VIDEO: cannot load font '%ls', fmt=%d\n", s, format);
|
||||
ERRLOG("VIDEO: cannot load font '%ls', fmt=%i\n", s, format);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -917,81 +918,15 @@ video_load_font(const wchar_t *s, int format)
|
||||
(void)fread(&fontdatm[c][8], 1, 8, fp);
|
||||
break;
|
||||
|
||||
case 1: /* PC200 */
|
||||
for (c = 0; c < 256; c++)
|
||||
(void)fread(&fontdatm[c][0], 1, 8, fp);
|
||||
for (c = 0; c < 256; c++)
|
||||
(void)fread(&fontdatm[c][8], 1, 8, fp);
|
||||
(void)fseek(fp, 4096, SEEK_SET);
|
||||
for (c = 0; c < 256; c++) {
|
||||
(void)fread(&fontdat[c][0], 1, 8, fp);
|
||||
for (d = 0; d < 8; d++)
|
||||
(void)fgetc(fp);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* CGA, thin font */
|
||||
case 8: /* CGA, thick font */
|
||||
if (format == 8) {
|
||||
case 1: /* CGA, thin font */
|
||||
case 2: /* CGA, thick font */
|
||||
if (format == 2) {
|
||||
/* Use the second ("thick") font in the ROM. */
|
||||
(void)fseek(fp, 2048, SEEK_SET);
|
||||
}
|
||||
for (c = 0; c < 256; c++)
|
||||
(void)fread(&fontdat[c][0], 1, 8, fp);
|
||||
break;
|
||||
|
||||
case 3: /* Wyse 700 */
|
||||
for (c = 0; c < 512; c++)
|
||||
(void)fread(&fontdatw[c][0], 1, 32, fp);
|
||||
break;
|
||||
|
||||
case 4: /* MDSI Genius */
|
||||
for (c = 0; c < 256; c++)
|
||||
(void)fread(&fontdat8x12[c][0], 1, 16, fp);
|
||||
break;
|
||||
|
||||
case 5: /* Toshiba 3100e */
|
||||
for (d = 0; d < 2048; d += 512) { /* Four languages... */
|
||||
for (c = d; c < d+256; c++)
|
||||
(void)fread(&fontdatm[c][8], 1, 8, fp);
|
||||
for (c = d+256; c < d+512; c++)
|
||||
(void)fread(&fontdatm[c][8], 1, 8, fp);
|
||||
for (c = d; c < d+256; c++)
|
||||
(void)fread(&fontdatm[c][0], 1, 8, fp);
|
||||
for (c = d+256; c < d+512; c++)
|
||||
(void)fread(&fontdatm[c][0], 1, 8, fp);
|
||||
(void)fseek(fp, 4096, SEEK_CUR); /* Skip blank section */
|
||||
for (c = d; c < d+256; c++)
|
||||
(void)fread(&fontdat[c][0], 1, 8, fp);
|
||||
for (c = d+256; c < d+512; c++)
|
||||
(void)fread(&fontdat[c][0], 1, 8, fp);
|
||||
}
|
||||
break;
|
||||
|
||||
case 6: /* Korean KSC-5601 */
|
||||
if (fontdatksc5601 == NULL)
|
||||
fontdatksc5601 = (dbcs_font_t *)mem_alloc(16384 * sizeof(dbcs_font_t));
|
||||
|
||||
if (fontdatksc5601_user == NULL)
|
||||
fontdatksc5601_user = (dbcs_font_t *)mem_alloc(192 * sizeof(dbcs_font_t));
|
||||
|
||||
for (c = 0; c < 16384; c++) {
|
||||
for (d = 0; d < 32; d++)
|
||||
fontdatksc5601[c].chr[d] = fgetc(fp);
|
||||
}
|
||||
break;
|
||||
|
||||
case 7: /* Sigma Color 400 */
|
||||
/* The first 4K of the character ROM holds an 8x8 font. */
|
||||
for (c = 0; c < 256; c++) {
|
||||
(void)fread(&fontdat[c][0], 1, 8, fp);
|
||||
(void)fseek(fp, 8, SEEK_CUR);
|
||||
}
|
||||
|
||||
/* The second 4K holds an 8x16 font. */
|
||||
for (c = 0; c < 256; c++)
|
||||
(void)fread(&fontdatm[c][0], 1, 16, fp);
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG("VIDEO: font #%i loaded\n", format);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Definitions for the video controller module.
|
||||
*
|
||||
* Version: @(#)video.h 1.0.26 2019/03/01
|
||||
* Version: @(#)video.h 1.0.27 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -113,16 +113,17 @@ typedef rgb_t PALETTE[256];
|
||||
|
||||
extern int changeframecount;
|
||||
|
||||
/* These will go away soon. */
|
||||
extern uint8_t fontdat[256][8];
|
||||
extern uint8_t fontdatm[256][16];
|
||||
extern dbcs_font_t *fontdatk,
|
||||
*fontdatk_user;
|
||||
|
||||
extern bitmap_t *buffer,
|
||||
*buffer32;
|
||||
extern PALETTE cgapal,
|
||||
cgapal_mono[6];
|
||||
extern uint32_t pal_lookup[256];
|
||||
extern uint8_t fontdat[2048][8];
|
||||
extern uint8_t fontdatm[2048][16];
|
||||
extern uint8_t fontdat8x12[256][16];
|
||||
extern dbcs_font_t *fontdatksc5601,
|
||||
*fontdatksc5601_user;
|
||||
extern uint32_t *video_6to8,
|
||||
*video_15to32,
|
||||
*video_16to32;
|
||||
@@ -335,6 +336,10 @@ extern void video_wait_for_buffer(void);
|
||||
|
||||
extern void cgapal_rebuild(void);
|
||||
|
||||
#ifdef VIDEO_SVGA_H
|
||||
extern int ati28800k_load_font(svga_t *, const wchar_t *);
|
||||
#endif
|
||||
|
||||
extern void video_log(int level, const char *fmt, ...);
|
||||
extern void video_init(void);
|
||||
extern void video_close(void);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* "extern" reference to its device into the video.h file,
|
||||
* and add an entry for it into the table here.
|
||||
*
|
||||
* Version: @(#)video_dev.c 1.0.32 2019/03/02
|
||||
* Version: @(#)video_dev.c 1.0.32 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -68,9 +68,7 @@ static const struct {
|
||||
/* Standard video controllers. */
|
||||
{ "mda", &mda_device },
|
||||
{ "cga", &cga_device },
|
||||
#if defined(DEV_BRANCH)
|
||||
{ "pgc", &pgc_device },
|
||||
#endif
|
||||
{ "ega", &ega_device },
|
||||
{ "vga", &vga_device },
|
||||
{ "hercules", &hercules_device },
|
||||
@@ -105,9 +103,7 @@ static const struct {
|
||||
{ "hercules_plus", &herculesplus_device },
|
||||
{ "incolor", &incolor_device },
|
||||
{ "genius", &genius_device },
|
||||
#if defined(DEV_BRANCH)
|
||||
{ "im1024", &im1024_device },
|
||||
#endif
|
||||
{ "oti037c", &oti037c_device },
|
||||
{ "oti067", &oti067_device },
|
||||
{ "oti077", &oti077_device },
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
* BIOSES: I need to re-do the bios.txt format so we can load non-BIOS
|
||||
* ROM files for a given machine, such as font roms here..
|
||||
*
|
||||
* Version: @(#)m_amstrad.c 1.0.21 2019/02/16
|
||||
* Version: @(#)m_amstrad.c 1.0.22 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -88,6 +88,7 @@
|
||||
#include "../devices/video/video.h"
|
||||
#include "../devices/video/vid_cga.h"
|
||||
#include "../devices/video/vid_ega.h"
|
||||
#include "../plat.h"
|
||||
#include "machine.h"
|
||||
|
||||
|
||||
@@ -132,6 +133,7 @@ typedef struct {
|
||||
int firstline,
|
||||
lastline;
|
||||
uint8_t *vram;
|
||||
uint8_t fontdat[256][8]; /* 1512/200 */
|
||||
} amsvid_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -346,10 +348,10 @@ vid_poll_1512(void *priv)
|
||||
}
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[vid->displine][(x << 3) + c + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
buffer->line[vid->displine][(x << 3) + c + 8] = cols[(vid->fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[vid->displine][(x << 3) + c + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer->line[vid->displine][(x << 3) + c + 8] = cols[(vid->fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
vid->ma++;
|
||||
}
|
||||
@@ -371,11 +373,11 @@ vid_poll_1512(void *priv)
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[vid->displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(vid->fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer->line[vid->displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
buffer->line[vid->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(vid->fontdat[chr][vid->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
} else if (! (vid->cgamode & 16)) {
|
||||
@@ -533,14 +535,31 @@ vid_poll_1512(void *priv)
|
||||
|
||||
|
||||
static void
|
||||
vid_init_1512(amstrad_t *ams)
|
||||
vid_init_1512(amstrad_t *ams, const wchar_t *fn, int num)
|
||||
{
|
||||
amsvid_t *vid;
|
||||
FILE *fp;
|
||||
int c;
|
||||
|
||||
/* Allocate a video controller block. */
|
||||
vid = (amsvid_t *)mem_alloc(sizeof(amsvid_t));
|
||||
memset(vid, 0x00, sizeof(amsvid_t));
|
||||
|
||||
/* Load the PC1512 CGA Character Set ROM. */
|
||||
fp = plat_fopen(rom_path(fn), L"rb");
|
||||
if (fp != NULL) {
|
||||
if (num == 8) {
|
||||
/* Use the second ("thick") font in the ROM. */
|
||||
(void)fseek(fp, 2048, SEEK_SET);
|
||||
}
|
||||
for (c = 0; c < 256; c++)
|
||||
(void)fread(&vid->fontdat[c][0], 1, 8, fp);
|
||||
(void)fclose(fp);
|
||||
} else {
|
||||
ERRLOG("AMSTRAD: cannot load font '%ls'\n", fn);
|
||||
return;
|
||||
}
|
||||
|
||||
vid->vram = (uint8_t *)mem_alloc(0x10000);
|
||||
vid->cgacol = 7;
|
||||
vid->cgamode = 0x12;
|
||||
@@ -581,8 +600,7 @@ vid_speed_change_1512(void *priv)
|
||||
|
||||
static const device_t vid_1512_device = {
|
||||
"Amstrad PC1512 (video)",
|
||||
0,
|
||||
0,
|
||||
0, 0,
|
||||
NULL, vid_close_1512, NULL,
|
||||
NULL,
|
||||
vid_speed_change_1512,
|
||||
@@ -752,8 +770,7 @@ vid_speed_changed_1640(void *priv)
|
||||
|
||||
static const device_t vid_1640_device = {
|
||||
"Amstrad PC1640 (video)",
|
||||
0,
|
||||
0,
|
||||
0, 0,
|
||||
NULL, vid_close_1640, NULL,
|
||||
NULL,
|
||||
vid_speed_changed_1640,
|
||||
@@ -841,15 +858,40 @@ vid_in_200(uint16_t addr, void *priv)
|
||||
|
||||
|
||||
static void
|
||||
vid_init_200(amstrad_t *ams)
|
||||
vid_init_200(amstrad_t *ams, const wchar_t *fn)
|
||||
{
|
||||
amsvid_t *vid;
|
||||
cga_t *cga;
|
||||
FILE *fp;
|
||||
int c, d;
|
||||
|
||||
/* Allocate a video controller block. */
|
||||
vid = (amsvid_t *)mem_alloc(sizeof(amsvid_t));
|
||||
memset(vid, 0x00, sizeof(amsvid_t));
|
||||
|
||||
/* Load the PC200 CGA Character Set ROM. */
|
||||
fp = plat_fopen(rom_path(fn), L"rb");
|
||||
if (fp != NULL) {
|
||||
for (c = 0; c < 256; c++)
|
||||
(void)fread(&fontdatm[c][0], 1, 8, fp);
|
||||
for (c = 0; c < 256; c++)
|
||||
(void)fread(&fontdatm[c][8], 1, 8, fp);
|
||||
|
||||
(void)fseek(fp, 4096, SEEK_SET);
|
||||
|
||||
for (c = 0; c < 256; c++) {
|
||||
(void)fread(&fontdat[c][0], 1, 8, fp);
|
||||
|
||||
for (d = 0; d < 8; d++)
|
||||
(void)fgetc(fp);
|
||||
}
|
||||
|
||||
(void)fclose(fp);
|
||||
} else {
|
||||
ERRLOG("AMSTRAD: cannot load font '%ls'\n", fn);
|
||||
return;
|
||||
}
|
||||
|
||||
cga = &vid->cga;
|
||||
cga->vram = (uint8_t *)mem_alloc(0x4000);
|
||||
cga_init(cga);
|
||||
@@ -891,8 +933,7 @@ vid_speed_changed_200(void *priv)
|
||||
|
||||
static const device_t vid_200_device = {
|
||||
"Amstrad PC200 (video)",
|
||||
0,
|
||||
0,
|
||||
0, 0,
|
||||
NULL, vid_close_200, NULL,
|
||||
NULL,
|
||||
vid_speed_changed_200,
|
||||
@@ -1219,6 +1260,59 @@ amstrad_common_init(const machine_t *model, void *arg, int type)
|
||||
machine_common_init(model, arg);
|
||||
|
||||
nmi_init();
|
||||
|
||||
switch(ams->type) {
|
||||
case 0: /* 1512 */
|
||||
device_add(&fdc_xt_device);
|
||||
if (video_card == VID_INTERNAL) {
|
||||
/* Initialize the internal CGA controller. */
|
||||
vid_init_1512(ams, roms->fontfn, roms->fontnum);
|
||||
device_add_ex(&vid_1512_device, ams->vid);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* 1640 */
|
||||
device_add(&fdc_xt_device);
|
||||
if (video_card == VID_INTERNAL) {
|
||||
/* Initialize the internal CGA/EGA controller. */
|
||||
vid_init_1640(ams, roms->vidfn, roms->vidsz);
|
||||
device_add_ex(&vid_1640_device, ams->vid);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* PC200 */
|
||||
device_add(&fdc_xt_device);
|
||||
if (video_card == VID_INTERNAL) {
|
||||
/* Initialize the internal CGA controller. */
|
||||
vid_init_200(ams, roms->fontfn);
|
||||
device_add_ex(&vid_200_device, ams->vid);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /* PC2086 */
|
||||
device_add(&fdc_at_actlow_device);
|
||||
if (video_card == VID_INTERNAL) {
|
||||
device_add(¶dise_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(¶dise_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(¶dise_wd90c11_megapc_device);
|
||||
video_inform(VID_TYPE_SPEC, &wd90c11_timing);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
device_add(&amstrad_nvr_device);
|
||||
|
||||
@@ -1235,64 +1329,6 @@ amstrad_common_init(const machine_t *model, void *arg, int type)
|
||||
|
||||
io_sethandler(0xdead, 1,
|
||||
ams_read, NULL, NULL, ams_write, NULL, NULL, ams);
|
||||
|
||||
switch(ams->type) {
|
||||
case 0:
|
||||
device_add(&fdc_xt_device);
|
||||
if (video_card == VID_INTERNAL) {
|
||||
/* Load the PC1512 CGA Character Set ROM. */
|
||||
video_load_font(roms->fontfn, roms->fontnum);
|
||||
|
||||
/* Initialize the internal CGA controller. */
|
||||
vid_init_1512(ams);
|
||||
device_add_ex(&vid_1512_device, ams->vid);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
device_add(&fdc_xt_device);
|
||||
if (video_card == VID_INTERNAL) {
|
||||
/* Load the BIOS for the internal CGA/EGA. */
|
||||
vid_init_1640(ams, roms->vidfn, roms->vidsz);
|
||||
device_add_ex(&vid_1640_device, ams->vid);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
device_add(&fdc_xt_device);
|
||||
if (video_card == VID_INTERNAL) {
|
||||
/* Load the PC200 CGA Character Set ROM. */
|
||||
video_load_font(roms->fontfn, roms->fontnum);
|
||||
|
||||
vid_init_200(ams);
|
||||
device_add_ex(&vid_200_device, ams->vid);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
device_add(&fdc_at_actlow_device);
|
||||
if (video_card == VID_INTERNAL) {
|
||||
device_add(¶dise_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(¶dise_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(¶dise_wd90c11_megapc_device);
|
||||
video_inform(VID_TYPE_SPEC, &wd90c11_timing);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Initialize the (custom) keyboard/mouse interface. */
|
||||
ams->wantirq = 0;
|
||||
|
||||
@@ -22,13 +22,13 @@
|
||||
* 61 50 52 0F 19 06 19 19 02 0D 0B 0C MONO
|
||||
* 2D 28 22 0A 67 00 64 67 02 03 06 07 640x400
|
||||
*
|
||||
* Version: @(#)m_at_t3100e_vid.c 1.0.6 2018/09/22
|
||||
* Version: @(#)m_at_t3100e_vid.c 1.0.7 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
* Sarah Walker, <tommowalker@tommowalker.co.uk>
|
||||
*
|
||||
* Copyright 2017,2018 Fred N. van Kempen.
|
||||
* Copyright 2017-2019 Fred N. van Kempen.
|
||||
* Copyright 2016-2018 Miran Grca.
|
||||
* Copyright 2008-2018 Sarah Walker.
|
||||
*
|
||||
@@ -59,15 +59,18 @@
|
||||
#include "../cpu/cpu.h"
|
||||
#include "../io.h"
|
||||
#include "../mem.h"
|
||||
#include "../rom.h"
|
||||
#include "../timer.h"
|
||||
#include "../device.h"
|
||||
#include "../devices/video/video.h"
|
||||
#include "../devices/video/vid_cga.h"
|
||||
#include "../plat.h"
|
||||
#include "m_at_t3100e.h"
|
||||
|
||||
|
||||
#define T3100E_XSIZE 640
|
||||
#define T3100E_YSIZE 400
|
||||
#define FONT_ROM_PATH L"machines/toshiba/t3100e/t3100e_font.bin"
|
||||
#define T3100E_XSIZE 640
|
||||
#define T3100E_YSIZE 400
|
||||
|
||||
|
||||
/* Mapping of attributes to colours */
|
||||
@@ -108,6 +111,9 @@ typedef struct {
|
||||
uint8_t video_options;
|
||||
|
||||
uint8_t *vram;
|
||||
|
||||
uint8_t fontdat[2048][8];
|
||||
uint8_t fontdatm[2048][16];
|
||||
} t3100e_t;
|
||||
|
||||
|
||||
@@ -363,11 +369,11 @@ text_row80(t3100e_t *dev)
|
||||
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
((uint32_t *)buffer32->line[dev->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
((uint32_t *)buffer32->line[dev->displine])[(x << 3) + c] = cols[(dev->fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
((uint32_t *)buffer32->line[dev->displine])[(x << 3) + c] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
((uint32_t *)buffer32->line[dev->displine])[(x << 3) + c] = cols[(dev->fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
++ma;
|
||||
}
|
||||
@@ -427,11 +433,11 @@ text_row40(t3100e_t *dev)
|
||||
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2] = ((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2 + 1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2] = ((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2 + 1] = cols[(dev->fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black);
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2] = ((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2+1] = cols[(fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2] = ((uint32_t *)buffer32->line[dev->displine])[(x << 4) + c*2+1] = cols[(dev->fontdatm[bold][sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
++ma;
|
||||
@@ -640,6 +646,44 @@ t3100e_poll(void *priv)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
load_font(t3100e_t *dev, const wchar_t *s)
|
||||
{
|
||||
FILE *fp;
|
||||
int c, d;
|
||||
|
||||
fp = plat_fopen(rom_path(s), L"rb");
|
||||
if (fp == NULL) {
|
||||
ERRLOG("T3100e: cannot load font '%ls'\n", s);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Fonts for 4 languages... */
|
||||
for (d = 0; d < 2048; d += 512) {
|
||||
for (c = d; c < d+256; c++)
|
||||
(void)fread(&dev->fontdatm[c][8], 1, 8, fp);
|
||||
for (c = d+256; c < d+512; c++)
|
||||
(void)fread(&dev->fontdatm[c][8], 1, 8, fp);
|
||||
for (c = d; c < d+256; c++)
|
||||
(void)fread(&dev->fontdatm[c][0], 1, 8, fp);
|
||||
for (c = d+256; c < d+512; c++)
|
||||
(void)fread(&dev->fontdatm[c][0], 1, 8, fp);
|
||||
|
||||
/* Skip blank section. */
|
||||
(void)fseek(fp, 4096, SEEK_CUR);
|
||||
|
||||
for (c = d; c < d+256; c++)
|
||||
(void)fread(&dev->fontdat[c][0], 1, 8, fp);
|
||||
for (c = d+256; c < d+512; c++)
|
||||
(void)fread(&dev->fontdat[c][0], 1, 8, fp);
|
||||
}
|
||||
|
||||
(void)fclose(fp);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
t3100e_init(const device_t *info)
|
||||
{
|
||||
@@ -648,6 +692,11 @@ t3100e_init(const device_t *info)
|
||||
dev = (t3100e_t *)mem_alloc(sizeof(t3100e_t));
|
||||
memset(dev, 0x00, sizeof(t3100e_t));
|
||||
|
||||
if (! load_font(dev, FONT_ROM_PATH)) {
|
||||
free(dev);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
cga_init(&dev->cga);
|
||||
|
||||
dev->internal = 1;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*
|
||||
* Handling of the emulated machines.
|
||||
*
|
||||
* Version: @(#)machine_table.c 1.0.34 2019/02/16
|
||||
* Version: @(#)machine_table.c 1.0.35 2019/03/03
|
||||
*
|
||||
* Authors: Fred N. van Kempen, <decwiz@yahoo.com>
|
||||
* Miran Grca, <mgrca8@gmail.com>
|
||||
@@ -115,7 +115,7 @@ const machine_t machines[] = {
|
||||
{ "[286 ISA] Hyundai Super-286TR", "hyundai_super286tr", L"hyundai/super286tr", 8, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 128, m_at_scat_init, NULL, NULL },
|
||||
{ "[286 ISA] Samsung SPC-4200P", "samsung_spc4200p", L"samsung/spc4200p", 8, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 512, 2048, 128, 128, m_at_scat_init, NULL, NULL },
|
||||
{ "[286 ISA] Samsung SPC-4216P", "samsung_spc4216p", L"samsung/spc4216p", 8, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT | MACHINE_PS2, 1, 5, 1, 128, m_at_scat_spc4216p_init, NULL, NULL },
|
||||
{ "[286 ISA] Toshiba T3100e", "toshiba_t3100e", L"toshiba/t3100e", 8, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 1024, 5120, 256, 64, m_at_t3100e_init, NULL, NULL },
|
||||
{ "[286 ISA] Toshiba T3100e", "toshiba_t3100e", L"toshiba/t3100e", 8, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 1, MACHINE_ISA | MACHINE_AT | MACHINE_VIDEO | MACHINE_HDC, 1024, 5120, 256, 64, m_at_t3100e_init, NULL, NULL },
|
||||
{ "[286 ISA] Trigem 286M", "tg286m", L"trigem/tg286m", 8, {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 128, m_at_tg286m_init, NULL, NULL },
|
||||
|
||||
{ "[286 MCA] IBM PS/2 model 50", "ibm_ps2_m50", L"ibm/ps2_m50", -1, {{"", cpus_ps2_m30_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, 0, MACHINE_MCA | MACHINE_AT | MACHINE_PS2 | MACHINE_VIDEO | MACHINE_HDC_PS2, 1, 10, 1, 64, m_ps2_model_50_init, NULL, NULL },
|
||||
|
||||
Reference in New Issue
Block a user