More updates for the NEC PC-98x1 series.

Still preliminary, but I hope it's a good start to work with.
This commit is contained in:
TC1995
2024-02-12 20:58:06 +01:00
parent dad0b8c899
commit b36c0cb697
10 changed files with 2097 additions and 157 deletions

View File

@@ -336,6 +336,15 @@ typedef struct _machine_ {
#endif
} machine_t;
/*ToDo: preliminary, to improve.*/
typedef struct _machine_pc98_ {
char *font_rom;
char *hdd_rom;
char *pci_rom;
char *sound_rom;
int init;
} machine_pc98_t;
/* Global variables. */
extern const machine_filter_t machine_types[];
extern const machine_filter_t machine_chipsets[];
@@ -343,6 +352,7 @@ extern const machine_t machines[];
extern int bios_only;
extern int machine;
extern void * machine_snd;
extern machine_pc98_t machine_pc98;
/* Core functions. */
extern int machine_count(void);

View File

@@ -0,0 +1,149 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the EGC graphics processor used by
* the NEC PC-98x1 series of computers.
*
*
*
* Authors: TAKEDA toshiya,
* yui/Neko Project II
*
* Copyright 2009-2023 TAKEDA, toshiya.
* Copyright 2008-2023 yui/Neko Project II.
*/
#ifndef VIDEO_PC98X1_DISP_H
# define VIDEO_PC98X1_DISP_H
#define TVRAM_SIZE 0x4000
#define VRAM16_SIZE 0x40000
#define VRAM256_SIZE 0x80000
#define EMS_SIZE 0x10000
enum {
MODE1_ATRSEL = 0x00,
MODE1_GRAPHIC = 0x01,
MODE1_COLUMN = 0x02,
MODE1_FONTSEL = 0x03,
MODE1_200LINE = 0x04,
MODE1_KAC = 0x05,
MODE1_MEMSW = 0x06,
MODE1_DISP = 0x07,
};
enum {
MODE2_16COLOR = 0x00,
MODE2_EGC = 0x02,
MODE2_WRITE_MASK = 0x03,
MODE2_256COLOR = 0x10,
MODE2_480LINE = 0x34,
};
enum {
MODE3_WRITE_MASK = 0x01,
MODE3_LINE_COLOR = 0x09,
MODE3_NPC_COLOR = 0x0b,
MODE3_LINE_CONNECT = 0x0f,
};
enum {
GRCG_PLANE_0 = 0x01,
GRCG_PLANE_1 = 0x02,
GRCG_PLANE_2 = 0x04,
GRCG_PLANE_3 = 0x08,
GRCG_PLANE_SEL = 0x30,
GRCG_RW_MODE = 0x40,
GRCG_CG_MODE = 0x80,
};
typedef struct pc98x1_vid_t {
/* vga */
uint8_t tvram_buffer[480 * 640];
uint8_t vram0_buffer[480 * 640];
uint8_t vram1_buffer[480 * 640];
uint8_t null_buffer[480 * 640];
int width;
int height;
int last_width;
int last_height;
uint8_t dirty;
uint8_t blink;
uint32_t palette_chr[8];
uint32_t palette_gfx[256];
uint8_t font[0x84000];
uint8_t tvram[TVRAM_SIZE];
uint8_t vram16[VRAM16_SIZE];
uint8_t vram256[VRAM256_SIZE];
uint8_t ems[EMS_SIZE];
uint8_t *vram16_disp_b;
uint8_t *vram16_disp_r;
uint8_t *vram16_disp_g;
uint8_t *vram16_disp_e;
uint8_t *vram16_draw_b;
uint8_t *vram16_draw_r;
uint8_t *vram16_draw_g;
uint8_t *vram16_draw_e;
uint8_t *vram256_disp;
uint8_t *vram256_draw_0;
uint8_t *vram256_draw_1;
GDCState gdc_chr;
GDCState gdc_gfx;
EGCState egc;
uint8_t grcg_mode;
uint8_t grcg_tile_cnt;
uint8_t grcg_tile_b[4];
uint16_t grcg_tile_w[4];
uint8_t crtv;
uint8_t pl;
uint8_t bl;
uint8_t cl;
uint8_t ssl;
uint8_t sur;
uint8_t sdr;
uint8_t mode1[8];
uint8_t mode2[128];
uint8_t mode3[128];
uint8_t mode_select;
uint8_t digipal[4];
uint8_t anapal[3][256];
uint8_t anapal_select;
uint8_t bank_draw;
uint8_t bank_disp;
uint8_t bank256_draw_0;
uint8_t bank256_draw_1;
uint16_t vram256_bank_0;
uint16_t vram256_bank_1;
uint8_t ems_selected;
uint16_t font_code;
uint8_t font_line;
uint32_t cgwindow_addr_low;
uint32_t cgwindow_addr_high;
int htotal;
int hblank;
uint64_t dispontime;
uint64_t dispofftime;
pc_timer_t timer;
double clock;
} pc98x1_vid_t;
# ifdef EMU_DEVICE_H
extern const device_t pc98x1_vid_device;
# endif // EMU_DEVICE_H
#endif /*VIDEO_PC98X1_EGC_H*/

View File

@@ -0,0 +1,83 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Emulation of the EGC graphics processor used by
* the NEC PC-98x1 series of computers.
*
*
*
* Authors: TAKEDA toshiya,
* yui/Neko Project II
*
* Copyright 2009-2024 TAKEDA, toshiya.
* Copyright 2008-2024 yui/Neko Project II.
*/
#ifndef VIDEO_PC98X1_EGC_H
# define VIDEO_PC98X1_EGC_H
typedef union {
uint8_t b[2];
uint16_t w;
} egcword_t;
typedef union {
uint8_t b[4][2];
uint16_t w[4];
uint32_t d[2];
uint64_t q;
} egcquad_t;
typedef struct egc_t {
void *priv;
uint16_t access;
uint16_t fgbg;
uint16_t ope;
uint16_t fg;
egcword_t mask;
uint16_t bg;
uint16_t sft;
uint16_t leng;
egcquad_t lastvram;
egcquad_t patreg;
egcquad_t fgc;
egcquad_t bgc;
int func;
uint32_t remain;
uint32_t stack;
uint8_t *inptr;
int inptr_vmstate;
uint8_t *outptr;
int outptr_vmstate;
egcword_t mask2;
egcword_t srcmask;
uint8_t srcbit;
uint8_t dstbit;
uint8_t sft8bitl;
uint8_t sft8bitr;
uint8_t buf[528]; /* 4096/8 + 4*4 */
/* vram */
uint8_t *vram_ptr;
uint8_t *vram_b;
uint8_t *vram_r;
uint8_t *vram_g;
uint8_t *vram_e;
egcquad_t vram_src;
egcquad_t vram_data;
} egc_t;
extern void egc_mem_writeb(egc_t *dev, uint32_t addr1, uint8_t value);
extern void egc_mem_writew(egc_t *dev, uint32_t addr1, uint16_t value);
extern uint8_t egc_mem_readb(egc_t *dev, uint32_t addr1);
extern uint16_t egc_mem_readw(egc_t *dev, uint32_t addr1);
extern void egc_set_vram(egc_t *dev, uint8_t *vram_ptr);
extern void egc_reset(egc_t *dev);
extern void egc_init(egc_t *dev, void *priv);
#endif /*VIDEO_PC98X1_EGC_H*/

View File

@@ -19,17 +19,63 @@
#ifndef VIDEO_UPD7220_H
# define VIDEO_UPD7220_H
#define TVRAM_SIZE 0x4000
#define VRAM16_SIZE 0x40000
#define VRAM256_SIZE 0x80000
#define EMS_SIZE 0x10000
#define GDC_BUFFERS 1024
#define GDC_TABLEMAX 0x1000
enum {
GDC_CMD_RESET = 0x00,
GDC_CMD_SYNC = 0x0e,
GDC_CMD_SLAVE = 0x6e,
GDC_CMD_MASTER = 0x6f,
GDC_CMD_START = 0x6b,
GDC_CMD_BCTRL = 0x0c,
GDC_CMD_ZOOM = 0x46,
GDC_CMD_SCROLL = 0x70,
GDC_CMD_CSRFORM = 0x4b,
GDC_CMD_PITCH = 0x47,
GDC_CMD_LPEN = 0xc0,
GDC_CMD_VECTW = 0x4c,
GDC_CMD_VECTE = 0x6c,
GDC_CMD_TEXTW = 0x78,
GDC_CMD_TEXTE = 0x68,
GDC_CMD_CSRW = 0x49,
GDC_CMD_CSRR = 0xe0,
GDC_CMD_MASK = 0x4a,
GDC_CMD_WRITE = 0x20,
GDC_CMD_READ = 0xa0,
GDC_CMD_DMAR = 0xa4,
GDC_CMD_DMAW = 0x24,
/* unknown command (3 params) */
GDC_CMD_UNK_5A = 0x5a,
};
enum {
GDC_STAT_DRDY = 0x01,
GDC_STAT_FULL = 0x02,
GDC_STAT_EMPTY = 0x04,
GDC_STAT_DRAW = 0x08,
GDC_STAT_DMA = 0x10,
GDC_STAT_VSYNC = 0x20,
GDC_STAT_HBLANK = 0x40,
GDC_STAT_LPEN = 0x80,
};
enum {
GDC_DIRTY_VRAM = 0x01,
GDC_DIRTY_START = 0x02,
GDC_DIRTY_SCROLL = 0x04,
GDC_DIRTY_CURSOR = 0x08,
GDC_DIRTY_GFX = GDC_DIRTY_VRAM | GDC_DIRTY_SCROLL,
GDC_DIRTY_CHR = GDC_DIRTY_GFX | GDC_DIRTY_CURSOR,
};
#define GDC_VTICKS 18
#define GDC_VSTICKS 2
#define GDC_MULBIT 15
#define GDC_TABLEBIT 12
typedef struct upd7220_t {
void *priv;
@@ -71,49 +117,15 @@ typedef struct upd7220_t {
uint16_t pattern;
} upd7220_t;
extern void upd7220_init(upd7220_t *dev, void *priv,
uint8_t (*vram_read)(uint32_t addr, void *priv),
void (*vram_write)(uint32_t addr, uint8_t val, void *priv));
extern void upd7220_init(upd7220_t *dev, void *priv,
uint8_t (*vram_read)(uint32_t addr, void *priv),
void (*vram_write)(uint32_t addr, uint8_t val, void *priv));
void upd7220_param_write(uint16_t addr, uint8_t value, void *priv);
uint8_t upd7220_statreg_read(uint16_t addr, void *priv);
void upd7220_cmdreg_write(uint16_t addr, uint8_t value, void *priv);
uint8_t upd7220_data_read(uint16_t addr, void *priv);
void upd7220_reset(upd7220_t *dev);
# ifdef EMU_DEVICE_H
extern const device_t ati68860_ramdac_device;
extern const device_t ati68875_ramdac_device;
extern const device_t att490_ramdac_device;
extern const device_t att491_ramdac_device;
extern const device_t att492_ramdac_device;
extern const device_t att498_ramdac_device;
extern const device_t av9194_device;
extern const device_t bt484_ramdac_device;
extern const device_t att20c504_ramdac_device;
extern const device_t bt485_ramdac_device;
extern const device_t att20c505_ramdac_device;
extern const device_t bt485a_ramdac_device;
extern const device_t gendac_ramdac_device;
extern const device_t ibm_rgb528_ramdac_device;
extern const device_t ics2494an_305_device;
extern const device_t ati18810_device;
extern const device_t ati18811_0_device;
extern const device_t ati18811_1_device;
extern const device_t ics2595_device;
extern const device_t icd2061_device;
extern const device_t ics9161_device;
extern const device_t sc11483_ramdac_device;
extern const device_t sc11487_ramdac_device;
extern const device_t sc11486_ramdac_device;
extern const device_t sc11484_nors2_ramdac_device;
extern const device_t sc1502x_ramdac_device;
extern const device_t sdac_ramdac_device;
extern const device_t stg_ramdac_device;
extern const device_t tkd8001_ramdac_device;
extern const device_t tseng_ics5301_ramdac_device;
extern const device_t tseng_ics5341_ramdac_device;
extern const device_t tvp3026_ramdac_device;
# endif
extern void upd7220_recalctimings(upd7220_t *dev);
extern void upd7220_param_write(uint16_t addr, uint8_t value, void *priv);
extern uint8_t upd7220_statreg_read(uint16_t addr, void *priv);
extern void upd7220_cmdreg_write(uint16_t addr, uint8_t value, void *priv);
extern uint8_t upd7220_data_read(uint16_t addr, void *priv);
extern void upd7220_reset(upd7220_t *dev);
#endif /*VIDEO_UPD7220_H*/

View File

@@ -80,6 +80,7 @@ machine_init_ex(int m)
machine_snd = NULL;
is_vpc = 0;
machine_pc98.init = 0;
standalone_gameport_type = NULL;
gameport_instance_id = 0;

View File

@@ -233,7 +233,7 @@ pic_update_pending_at(void)
{
if (!(pic.interrupt & 0x20)) {
pic2.int_pending = (find_best_interrupt(&pic2) != -1);
if (pic2.int_pending)
pic.irr |= (1 << pic2.icw3);
else
@@ -643,7 +643,11 @@ pic_init(void)
pic_reset_hard();
shadow = 0;
io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic);
if (machine_pc98.init) {
io_sethandler_interleaved(0x0000, 0x0001, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic);
io_sethandler_interleaved(0x0002, 0x0001, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic);
} else
io_sethandler(0x0020, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic);
}
void
@@ -658,8 +662,14 @@ pic_init_pcjr(void)
void
pic2_init(void)
{
io_sethandler(0x00a0, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2);
pic.slaves[2] = &pic2;
if (machine_pc98.init) {
io_sethandler_interleaved(0x0008, 0x0001, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2);
io_sethandler_interleaved(0x000a, 0x0001, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2);
pic.slaves[7] = &pic2;
} else {
io_sethandler(0x00a0, 0x0002, pic_read, NULL, NULL, pic_write, NULL, NULL, &pic2);
pic.slaves[2] = &pic2;
}
}
void

View File

@@ -1048,7 +1048,11 @@ pit_set_clock(uint32_t clock)
else
cpuclock = (double) clock;
PITCONSTD = (cpuclock / 1193182.0);
if (machine_pc98.init)
PITCONSTD = (cpuclock / 2457600.0);
else
PITCONSTD = (cpuclock / 1193182.0);
PITCONST = (uint64_t) (PITCONSTD * (double) (1ULL << 32));
#ifdef IMPRECISE_CGACONST
CGACONST = (uint64_t) ((cpuclock / (19687503.0 / 11.0)) * (double) (1ULL << 32));
@@ -1102,7 +1106,11 @@ pit_set_clock(uint32_t clock)
PITCONST = (24ULL << 32LL);
CGACONST = (16ULL << 32LL);
} else if (cpuclock != 14318184.0) {
PITCONSTD = (cpuclock / 1193182.0);
if (machine_pc98.init)
PITCONSTD = (cpuclock / 2457600.0);
else
PITCONSTD = (cpuclock / 1193182.0);
PITCONST = (uint64_t) (PITCONSTD * (double) (1ULL << 32));
#ifdef IMPRECISE_CGACONST
CGACONST = (uint64_t) ((cpuclock / (19687503.0 / 11.0)) * (double) (1ULL << 32));

File diff suppressed because it is too large Load Diff

View File

@@ -32,6 +32,7 @@
#include <86box/device.h>
#include <86box/video.h>
#include <86box/vid_pc98x1_egc.h>
#include <86box/vid_pc98x1_disp.h>
#include <86box/plat_unused.h>
/***********************************************************/
@@ -956,6 +957,82 @@ static const uint16_t egc_maskword[16][4] = {
{0x0000, 0xffff, 0xffff, 0xffff}, {0xffff, 0xffff, 0xffff, 0xffff}
};
void
egc_mem_writeb(egc_t *dev, uint32_t addr1, uint8_t value)
{
uint32_t addr = addr1 & 0x7fff;
uint32_t ext = addr1 & 1;
egcquad_t data;
if ((dev->ope & 0x0300) == 0x0200) {
dev->patreg.b[0][ext] = dev->vram_b[addr];
dev->patreg.b[1][ext] = dev->vram_r[addr];
dev->patreg.b[2][ext] = dev->vram_g[addr];
dev->patreg.b[3][ext] = dev->vram_e[addr];
}
data.q = egc_opeb(dev, addr, value);
if (dev->mask2.b[ext]) {
if (!(dev->access & 1)) {
dev->vram_b[addr] &= ~dev->mask2.b[ext];
dev->vram_b[addr] |= data.b[0][ext] & dev->mask2.b[ext];
}
if (!(dev->access & 2)) {
dev->vram_r[addr] &= ~dev->mask2.b[ext];
dev->vram_r[addr] |= data.b[1][ext] & dev->mask2.b[ext];
}
if (!(dev->access & 4)) {
dev->vram_g[addr] &= ~dev->mask2.b[ext];
dev->vram_g[addr] |= data.b[2][ext] & dev->mask2.b[ext];
}
if (!(dev->access & 8)) {
dev->vram_e[addr] &= ~dev->mask2.b[ext];
dev->vram_e[addr] |= data.b[3][ext] & dev->mask2.b[ext];
}
}
}
void
egc_mem_writew(egc_t *dev, uint32_t addr1, uint16_t value)
{
uint32_t addr = addr1 & 0x7fff;
egcquad_t data;
if (!(addr & 1)) {
if ((dev->ope & 0x0300) == 0x0200) {
dev->patreg.w[0] = *(uint16_t *)(&dev->vram_b[addr]);
dev->patreg.w[1] = *(uint16_t *)(&dev->vram_r[addr]);
dev->patreg.w[2] = *(uint16_t *)(&dev->vram_g[addr]);
dev->patreg.w[3] = *(uint16_t *)(&dev->vram_e[addr]);
}
data.q = egc_opew(dev, addr, value);
if (dev->mask2.w) {
if (!(dev->access & 1)) {
*(uint16_t *)(&dev->vram_b[addr]) &= ~dev->mask2.w;
*(uint16_t *)(&dev->vram_b[addr]) |= data.w[0] & dev->mask2.w;
}
if (!(dev->access & 2)) {
*(uint16_t *)(&dev->vram_r[addr]) &= ~dev->mask2.w;
*(uint16_t *)(&dev->vram_r[addr]) |= data.w[1] & dev->mask2.w;
}
if (!(dev->access & 4)) {
*(uint16_t *)(&dev->vram_g[addr]) &= ~dev->mask2.w;
*(uint16_t *)(&dev->vram_g[addr]) |= data.w[2] & dev->mask2.w;
}
if (!(dev->access & 8)) {
*(uint16_t *)(&dev->vram_e[addr]) &= ~dev->mask2.w;
*(uint16_t *)(&dev->vram_e[addr]) |= data.w[3] & dev->mask2.w;
}
}
} else if (!(dev->sft & 0x1000)) {
egc_mem_writeb(s, addr1, value & 0xff);
egc_mem_writeb(s, addr1 + 1, (value >> 8) & 0xff);
} else {
egc_mem_writeb(s, addr1, (value >> 8) & 0xff);
egc_mem_writeb(s, addr1 + 1, value & 0xff);
}
}
uint8_t
egc_mem_readb(egc_t *dev, uint32_t addr1)
{
@@ -1048,81 +1125,6 @@ egc_mem_readw(egc_t *dev, uint32_t addr1)
}
}
void
egc_mem_writeb(egc_t *dev, uint32_t addr1, uint8_t value)
{
uint32_t addr = addr1 & 0x7fff;
uint32_t ext = addr1 & 1;
egcquad_t data;
if ((dev->ope & 0x0300) == 0x0200) {
dev->patreg.b[0][ext] = dev->vram_b[addr];
dev->patreg.b[1][ext] = dev->vram_r[addr];
dev->patreg.b[2][ext] = dev->vram_g[addr];
dev->patreg.b[3][ext] = dev->vram_e[addr];
}
data.q = egc_opeb(dev, addr, value);
if (dev->mask2.b[ext]) {
if (!(dev->access & 1)) {
dev->vram_b[addr] &= ~dev->mask2.b[ext];
dev->vram_b[addr] |= data.b[0][ext] & dev->mask2.b[ext];
}
if (!(dev->access & 2)) {
dev->vram_r[addr] &= ~dev->mask2.b[ext];
dev->vram_r[addr] |= data.b[1][ext] & dev->mask2.b[ext];
}
if (!(dev->access & 4)) {
dev->vram_g[addr] &= ~dev->mask2.b[ext];
dev->vram_g[addr] |= data.b[2][ext] & dev->mask2.b[ext];
}
if (!(dev->access & 8)) {
dev->vram_e[addr] &= ~dev->mask2.b[ext];
dev->vram_e[addr] |= data.b[3][ext] & dev->mask2.b[ext];
}
}
}
void
egc_mem_writew(egc_t *dev, uint32_t addr1, uint16_t value)
{
uint32_t addr = addr1 & 0x7fff;
egcquad_t data;
if (!(addr & 1)) {
if ((dev->ope & 0x0300) == 0x0200) {
dev->patreg.w[0] = *(uint16_t *)(&dev->vram_b[addr]);
dev->patreg.w[1] = *(uint16_t *)(&dev->vram_r[addr]);
dev->patreg.w[2] = *(uint16_t *)(&dev->vram_g[addr]);
dev->patreg.w[3] = *(uint16_t *)(&dev->vram_e[addr]);
}
data.q = egc_opew(dev, addr, value);
if (dev->mask2.w) {
if (!(dev->access & 1)) {
*(uint16_t *)(&dev->vram_b[addr]) &= ~dev->mask2.w;
*(uint16_t *)(&dev->vram_b[addr]) |= data.w[0] & dev->mask2.w;
}
if (!(dev->access & 2)) {
*(uint16_t *)(&dev->vram_r[addr]) &= ~dev->mask2.w;
*(uint16_t *)(&dev->vram_r[addr]) |= data.w[1] & dev->mask2.w;
}
if (!(dev->access & 4)) {
*(uint16_t *)(&dev->vram_g[addr]) &= ~dev->mask2.w;
*(uint16_t *)(&dev->vram_g[addr]) |= data.w[2] & dev->mask2.w;
}
if (!(dev->access & 8)) {
*(uint16_t *)(&dev->vram_e[addr]) &= ~dev->mask2.w;
*(uint16_t *)(&dev->vram_e[addr]) |= data.w[3] & dev->mask2.w;
}
}
} else if (!(dev->sft & 0x1000)) {
egc_mem_writeb(s, addr1, value & 0xff);
egc_mem_writeb(s, addr1 + 1, (value >> 8) & 0xff);
} else {
egc_mem_writeb(s, addr1, (value >> 8) & 0xff);
egc_mem_writeb(s, addr1 + 1, value & 0xff);
}
}
/* i/o */
void
@@ -1130,7 +1132,7 @@ egc_ioport_writeb(uint16_t addr, uint8_t value, void *priv)
{
/* ioport 0x4a0 - 0x4af */
egc_t *dev = (egc_t *)priv;
pc98x1_vid_t *vid = (pc98x1_vid_t *)dev->vid;
pc98x1_vid_t *vid = (pc98x1_vid_t *)dev->priv;
if (!((vid->grcg_mode & GRCG_CG_MODE) && vid->mode2[MODE2_EGC]))
return;
@@ -1220,7 +1222,7 @@ egc_ioport_writew(uint16_t addr, uint16_t value, void *priv)
{
/* ioport 0x4a0 - 0x4af */
egc_t *dev = (egc_t *)priv;
pc98x1_vid_t *vid = (pc98x1_vid_t *)dev->vid;
pc98x1_vid_t *vid = (pc98x1_vid_t *)dev->priv;
if (!((vid->grcg_mode & GRCG_CG_MODE) && vid->mode2[MODE2_EGC]))
return;
@@ -1277,10 +1279,6 @@ egc_set_vram(egc_t *dev, uint8_t *vram_ptr)
void
egc_reset(egc_t *dev)
{
pc98x1_vid_t *vid = (pc98x1_vid_t *)dev->vid;
memset(dev, 0, sizeof(egc_t));
dev->priv = vid;
dev->access = 0xfff0;
dev->fgbg = 0x00ff;
dev->mask.w = 0xffff;

View File

@@ -31,10 +31,9 @@
#include <86box/device.h>
#include <86box/video.h>
#include <86box/vid_upd7220.h>
#include <86box/vid_pc98x1_disp.h>
#include <86box/plat_unused.h>
static video_timings_t timing_upd7220 = { .type = 0, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
/***********************************************************/
/* NEC uPD7220 GDC (based on Neko Project 2) */
@@ -54,11 +53,45 @@ static const int gdc_vectdir[16][4] = {
{ 0,-1,-1,-1}, {-1,-1,-1, 0}, {-1, 0,-1, 1}, {-1, 1, 0, 1}
};
void
upd7220_recalctimings(upd7220_t *dev)
{
pc98x1_vid_t *vid = (pc98x1_vid_t *) dev->priv;
double crtcconst;
double _dispontime;
double _dispofftime;
if (vid->mode2[MODE2_256COLOR] && vid->mode2[MODE2_480LINE])
vid->clock = (uint64_t)(cpuclock / 25175000.0 * (double) (1ULL << 32));
else
vid->clock = (uint64_t)(cpuclock / 21052600.0 * (double) (1ULL << 32));
vid->width = MIN(96, dev->sync[1] + 2);
vid->height = MIN(512, ((dev->sync[7] & 0x03) << 8) | (dev->sync[6]));
vid->hblank = ((dev->sync[2] & 0x1f) + (dev->sync[4] & 0x3f) + 2) * 8;
vid->htotal = ((dev->sync[3] >> 2) + 1) * 8;
crtcconst = vid->clock * 8.0;
_dispontime = vid->htotal - vid->hblank;
_dispofftime = vid->hblank;
_dispontime *= crtcconst;
_dispofftime *= crtcconst;
vid->dispontime = (uint64_t) (_dispontime);
vid->dispofftime = (uint64_t) (_dispofftime);
if (vid->dispontime < TIMER_USEC)
vid->dispontime = TIMER_USEC;
if (vid->dispofftime < TIMER_USEC)
vid->dispofftime = TIMER_USEC;
}
static void
upd7220_draw_pset(upd7220_t *dev, int x, int y)
{
uint16_t dot = dev->pattern & 1;
uint32_t addr = y * 80 + (x >> 3) + 0x8000;
uint32_t addr = (y * 80) + (x >> 3) + 0x8000;
uint8_t bit = 0x80 >> (x & 7);
uint8_t cur = dev->vram_read(dev->priv, addr);
@@ -444,6 +477,7 @@ upd7220_cmd_reset(upd7220_t *dev)
dev->statreg = 0;
dev->cmdreg = -1;
dev->dirty = 0xff;
upd7220_recalctimings(dev);
}
static void
@@ -455,6 +489,7 @@ upd7220_cmd_sync(upd7220_t *dev)
dev->sync[i] = dev->params[i];
dev->cmdreg = -1;
upd7220_recalctimings(dev);
}
static void
@@ -981,7 +1016,7 @@ upd7220_statreg_read(uint16_t addr, void *priv)
{
/* ioport 0x60(chr), 0xa0(gfx) */
upd7220_t *dev = (upd7220_t *) priv;
pc98x1_vid_t *vid = (pc98x1_vid_t *)dev->vid;
pc98x1_vid_t *vid = (pc98x1_vid_t *) dev->priv;
uint8_t value = dev->statreg | vid->vsync;
#if 0