mirror of
https://github.com/86Box/86Box.git
synced 2026-02-22 01:25:33 -07:00
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:
@@ -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);
|
||||
|
||||
149
src/include/86box/vid_pc98x1_disp.h
Normal file
149
src/include/86box/vid_pc98x1_disp.h
Normal 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*/
|
||||
83
src/include/86box/vid_pc98x1_egc.h
Normal file
83
src/include/86box/vid_pc98x1_egc.h
Normal 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*/
|
||||
@@ -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*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
18
src/pic.c
18
src/pic.c
@@ -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
|
||||
|
||||
12
src/pit.c
12
src/pit.c
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user