Skip to content

Commit

Permalink
Merge pull request #3508 from nanshiki/pc98gdclio
Browse files Browse the repository at this point in the history
PC-98 GDC and LIO drawing support
  • Loading branch information
joncampbell123 authored May 24, 2022
2 parents 73d13e7 + 5050103 commit 9140176
Show file tree
Hide file tree
Showing 13 changed files with 2,292 additions and 55 deletions.
2 changes: 2 additions & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ HQ2X and HQ3X render scaler (ScummVM, Maxim Stepin; GPLv2+) src/gui/render_templ

PC-98 FM board emulation (Neko Project II; BSD 3-clause) src/hardware/snd_pc98/*

PC-98 GDC and LIO drawing support (Neko Project II; BSD 3-clause) src/hardware/vga_pc98_gdc_draw.cpp src/ints/pc98_lio.cpp

QCOW image support (Michael Greger; GPLv2+) src/ints/qcow2_disk.cpp

JEGA and DOS/V support (nanshiki, Wengier; GPLv2+) include/jfont.h src/ints/int_dosv.cpp
Expand Down
55 changes: 54 additions & 1 deletion include/pc98_gdc.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ struct PC98_GDC_state {
void take_reset_sync_parameters(void);
void cursor_advance(void);

void draw_reset(void);
void vectw(unsigned char bi);
void exec(uint8_t command);
void prepare(void);
void draw_dot(uint16_t x, uint16_t y);
void pset(void);
void line(void);
void text(void);
void circle(void);
void box(void);
void set_vectl(int x1, int y1, int x2, int y2);
void set_mode(uint8_t mode);
void set_csrw(uint32_t ead, uint8_t dad);
void set_textw(uint16_t pattern);
void set_textw(uint8_t *tile, uint8_t len);

void begin_frame(void);
void next_line(void);

Expand All @@ -60,13 +76,50 @@ struct PC98_GDC_state {
bool fifo_empty(void);
uint16_t read_fifo(void);

enum {
RT_MULBIT = 15,
RT_TABLEBIT = 12,
RT_TABLEMAX = (1 << RT_TABLEBIT)
};
struct VECTDIR {
int16_t x;
int16_t y;
int16_t x2;
int16_t y2;
};
static const VECTDIR vectdir[16];
static const PhysPt gram_base[4];
static uint16_t gdc_rt[RT_TABLEMAX + 1];

struct GDC_DRAW {
PhysPt base;
uint32_t ead;
uint16_t dc;
uint16_t d;
uint16_t d1;
uint16_t d2;
uint16_t dm;
uint16_t pattern;
uint16_t x;
uint16_t y;
uint8_t tx[8];
uint8_t dad;
uint8_t ope;
uint8_t dir;
uint8_t dgd;
uint8_t wg;
uint8_t dots;
uint8_t mode;
uint8_t zoom;
} draw;

/* NTS:
*
* We're following the Neko Project II method of FIFO emulation BUT
* I wonder if the GDC maintains two FIFOs and allows stacking params
* in one and commands in another....? */

uint8_t cmd_parm_tmp[8]; /* temp storage before accepting params */
uint8_t cmd_parm_tmp[11]; /* temp storage before accepting params */

uint8_t rfifo[PC98_GDC_FIFO_SIZE];
uint8_t rfifo_read,rfifo_write;
Expand Down
10 changes: 10 additions & 0 deletions include/pc98_gdc_const.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,21 @@ enum {
GDC_CMD_RESET = 0x00, // 0 0 0 0 0 0 0 0
GDC_CMD_DISPLAY_BLANK = 0x0C, // 0 0 0 0 1 1 0 DE
GDC_CMD_SYNC = 0x0E, // 0 0 0 0 1 1 1 DE
GDC_CMD_MODE_REPLACE = 0x20, // 0 0 1 0 0 0 0 0
GDC_CMD_MODE_COMPLEMENT = 0x21, // 0 0 1 0 0 0 0 1
GDC_CMD_MODE_CLEAR = 0x22, // 0 0 1 0 0 0 1 0
GDC_CMD_MODE_SET = 0x23, // 0 0 1 0 0 0 1 1
GDC_CMD_CURSOR_POSITION = 0x49, // 0 1 0 0 1 0 0 1
GDC_CMD_CSRW = 0x49, // 0 1 0 0 1 0 0 1
GDC_CMD_CURSOR_CHAR_SETUP = 0x4B, // 0 1 0 0 1 0 1 1
GDC_CMD_ZOOM = 0x46, // 0 1 0 0 0 1 1 0
GDC_CMD_PITCH_SPEC = 0x47, // 0 1 0 0 0 1 1 1
GDC_CMD_VECTW = 0x4C, // 0 1 0 0 1 1 0 0
GDC_CMD_TEXTE = 0x68, // 0 1 1 0 1 0 0 0
GDC_CMD_START_DISPLAY = 0x6B, // 0 1 1 0 1 0 1 1
GDC_CMD_VECTE = 0x6c, // 0 1 1 0 1 1 0 0
GDC_CMD_VERTICAL_SYNC_MODE = 0x6E, // 0 1 1 0 1 1 1 M
GDC_CMD_PARAMETER_RAM_LOAD = 0x70, // 0 1 1 1 S S S S S[3:0] = starting address in parameter RAM
GDC_CMD_TEXTW = 0x78, // 0 1 1 1 1 0 0 0
GDC_CMD_CURSOR_ADDRESS_READ = 0xE0 // 1 1 1 0 0 0 0 0
};
2 changes: 1 addition & 1 deletion src/hardware/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler
vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \
vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp vga_s3.cpp vga_tseng.cpp vga_paradise.cpp \
cmos.cpp disney.cpp gus.cpp mpu401.cpp ipx.cpp ipxserver.cpp ne2000.cpp hardopl.cpp dbopl.cpp innova.cpp dongle.cpp \
voodoo.cpp voodoo_interface.cpp voodoo_emu.cpp ps1_sound.cpp sn76496.h ide.cpp floppy.cpp voodoo_vogl.cpp voodoo_opengl.cpp nukedopl.cpp pc98.cpp vga_pc98_gdc.cpp vga_pc98_dac.cpp vga_pc98_crtc.cpp vga_pc98_cg.cpp vga_pc98_egc.cpp pc98_fm.cpp glide.cpp \
voodoo.cpp voodoo_interface.cpp voodoo_emu.cpp ps1_sound.cpp sn76496.h ide.cpp floppy.cpp voodoo_vogl.cpp voodoo_opengl.cpp nukedopl.cpp pc98.cpp vga_pc98_gdc.cpp vga_pc98_gdc_draw.cpp vga_pc98_dac.cpp vga_pc98_crtc.cpp vga_pc98_cg.cpp vga_pc98_egc.cpp pc98_fm.cpp glide.cpp \
snd_pc98/sound/opngenc.c snd_pc98/sound/opngeng.c snd_pc98/sound/pcm86c.c snd_pc98/sound/pcm86g.c \
snd_pc98/sound/tms3631c.c snd_pc98/sound/tms3631g.c snd_pc98/sound/psggenc.c snd_pc98/sound/psggeng.c \
snd_pc98/common/parts.c snd_pc98/generic/keydisp.c snd_pc98/sound/adpcmc.c snd_pc98/sound/adpcmg.c \
Expand Down
2 changes: 1 addition & 1 deletion src/hardware/vga_memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1706,7 +1706,7 @@ class VGA_PC98_PageHandler : public PageHandler {
* 0 = shifter input is VRAM data */
if (pc98_egc_compare_lead) {
if (!pc98_egc_shiftinput)
return *((AWT*)(pc98_egc_src[pc98_egc_lead_plane&3].b));
return *((AWT*)(pc98_egc_src[pc98_egc_lead_plane&3].b+(vramoff&1)));
else
return *((AWT*)(pc98_pgraph_current_cpu_page+vramoff+((pc98_egc_lead_plane&3)*PC98_VRAM_BITPLANE_SIZE)));
}
Expand Down
2 changes: 1 addition & 1 deletion src/hardware/vga_pc98_crtc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void pc98_crtc_write(Bitu port,Bitu val,Bitu iolen) {
pc98_text_row_scanline_blank_at = (unsigned char)val & 0x1F;
break;
case 0x06:
pc98_text_row_scroll_lines = (unsigned char)val & 0x1F;
pc98_text_row_scroll_lines = (unsigned char)val & 0x0F;
break;
case 0x08:
pc98_text_row_scroll_count_start = (unsigned char)val & 0x1F;
Expand Down
69 changes: 60 additions & 9 deletions src/hardware/vga_pc98_gdc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ PC98_GDC_state::PC98_GDC_state() {
vertical_back_porch_width = 0;
reset_fifo();
reset_rfifo();
draw_reset();
}

size_t PC98_GDC_state::fifo_can_read(void) {
Expand Down Expand Up @@ -247,17 +248,31 @@ void PC98_GDC_state::take_cursor_pos(unsigned char bi) {
* 0 = [3:2] = 0
* EAD(H) = [1:0] = address[17:16] */
if (bi == 1) {
vga.config.cursor_start &= ~(0xFFu << 0u);
vga.config.cursor_start |= cmd_parm_tmp[0] << 0u;
if(master_sync) {
vga.config.cursor_start &= ~(0xFFu << 0u);
vga.config.cursor_start |= cmd_parm_tmp[0] << 0u;
} else {
draw.ead = cmd_parm_tmp[0];
}
}
else if (bi == 2) {
vga.config.cursor_start &= ~(0xFFu << 8u);
vga.config.cursor_start |= (unsigned int)cmd_parm_tmp[1] << 8u;
if(master_sync) {
vga.config.cursor_start &= ~(0xFFu << 8u);
vga.config.cursor_start |= (unsigned int)cmd_parm_tmp[1] << 8u;
} else {
draw.ead |= (uint32_t)cmd_parm_tmp[1] << 8;
}
}
else if (bi == 3) {
vga.config.cursor_start &= ~(0x03u << 16u);
vga.config.cursor_start |= (cmd_parm_tmp[2] & 3u) << 16u;

if(master_sync) {
vga.config.cursor_start &= ~(0x03u << 16u);
vga.config.cursor_start |= (cmd_parm_tmp[2] & 3u) << 16u;
} else {
draw.ead |= (uint32_t)(cmd_parm_tmp[2] & 0x03) << 16;
draw.dad = (uint8_t)(cmd_parm_tmp[2] >> 4);
draw.base = gram_base[(draw.ead >> 14) & 3];
draw.wg = cmd_parm_tmp[2] & 0x08;
}
// TODO: "dot address within the word"
}
}
Expand Down Expand Up @@ -322,6 +337,7 @@ void PC98_GDC_state::idle_proc(void) {
idle = true;
reset_fifo();
reset_rfifo();
draw_reset();
break;
case GDC_CMD_DISPLAY_BLANK: // 0x0C 0 0 0 0 1 1 0 DE
case GDC_CMD_DISPLAY_BLANK+1:// 0x0D DE=display enable
Expand All @@ -334,6 +350,14 @@ void PC98_GDC_state::idle_proc(void) {
current_command &= ~1;
LOG_MSG("GDC: sync");
break;
case GDC_CMD_MODE_REPLACE: // 0x20 0 0 1 0 0 0 0 0
case GDC_CMD_MODE_COMPLEMENT: // 0x21 0 0 1 0 0 0 0 1
case GDC_CMD_MODE_CLEAR: // 0x22 0 0 1 0 0 0 1 0
case GDC_CMD_MODE_SET: // 0x23 0 0 1 0 0 0 1 1
draw.mode = current_command & 0x03;
break;
case GDC_CMD_ZOOM: // 0x46 0 1 0 0 0 1 1 0
break;
case GDC_CMD_PITCH_SPEC: // 0x47 0 1 0 0 0 1 1 1
break;
case GDC_CMD_CURSOR_POSITION: // 0x49 0 1 0 0 1 0 0 1
Expand All @@ -342,6 +366,14 @@ void PC98_GDC_state::idle_proc(void) {
case GDC_CMD_CURSOR_CHAR_SETUP: // 0x4B 0 1 0 0 1 0 1 1
// LOG_MSG("GDC: cursor setup");
break;
case GDC_CMD_VECTW:
break;
case GDC_CMD_TEXTE: // 0x68 0 1 1 0 1 0 0 0
case GDC_CMD_VECTE: // 0x6C 0 1 1 0 1 1 0 0
if(!master_sync) {
exec(current_command);
}
break;
case GDC_CMD_START_DISPLAY: // 0x6B 0 1 1 0 1 0 1 1
display_enable = true;
idle = false;
Expand All @@ -368,8 +400,10 @@ void PC98_GDC_state::idle_proc(void) {
case GDC_CMD_PARAMETER_RAM_LOAD+13:// 0x7D S=starting byte in parameter RAM
case GDC_CMD_PARAMETER_RAM_LOAD+14:// 0x7E S=starting byte in parameter RAM
case GDC_CMD_PARAMETER_RAM_LOAD+15:// 0x7F S=starting byte in parameter RAM
param_ram_wptr = current_command & 0xF;
current_command = GDC_CMD_PARAMETER_RAM_LOAD;
if(master_sync || current_command != GDC_CMD_TEXTW) {
param_ram_wptr = current_command & 0xF;
current_command = GDC_CMD_PARAMETER_RAM_LOAD;
}
break;
case GDC_CMD_CURSOR_ADDRESS_READ: // 0xE0 1 1 1 0 0 0 0 0
write_rfifo((unsigned char)( vga.config.cursor_start & 0xFFu));
Expand All @@ -396,6 +430,12 @@ void PC98_GDC_state::idle_proc(void) {
}
}
break;
case GDC_CMD_ZOOM:
if(proc_step < 1) {
draw.zoom = (uint8_t)(val & 0x0f);
proc_step++;
}
break;
case GDC_CMD_PITCH_SPEC:
if (proc_step < 1)
display_pitch = (val != 0) ? val : 0x100;
Expand All @@ -406,6 +446,17 @@ void PC98_GDC_state::idle_proc(void) {
take_cursor_pos(proc_step);
}
break;
case GDC_CMD_VECTW:
if(proc_step < 11) {
cmd_parm_tmp[proc_step++] = (uint8_t)val;
vectw(proc_step);
}
break;
case GDC_CMD_TEXTW:
if(proc_step < 8) {
draw.tx[proc_step++] = (uint8_t)val;
}
break;
case GDC_CMD_CURSOR_CHAR_SETUP:
if (proc_step < 3) {
cmd_parm_tmp[proc_step++] = (uint8_t)val;
Expand Down
Loading

0 comments on commit 9140176

Please sign in to comment.