video/upd7220.cpp: Updated FIGD to use ead and mask to calculate drawing location. (#8405)

This commit is contained in:
Brian Johnson 2021-08-12 12:55:20 -04:00 committed by GitHub
parent b3f0a946a5
commit 3e714f3de1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 66 additions and 156 deletions

View File

@ -28,8 +28,6 @@
- honor visible area
- wide mode (32-bit access)
- light pen
- dad and mask are the same, in figd dad is shifted every step and when msb or lsb are 1 ead is advanced in x dir
*/
#include "emu.h"
@ -424,9 +422,9 @@ inline void upd7220_device::reset_figs_param()
{
m_figs.m_dc = 0x0000;
m_figs.m_d = 0x0008;
m_figs.m_d1 = 0x0008;
m_figs.m_d2 = 0x0000;
m_figs.m_dm = 0x0000;
m_figs.m_d1 = 0xffff;
m_figs.m_d2 = 0x0008;
m_figs.m_dm = 0xffff;
m_figs.m_gd = 0;
}
@ -612,7 +610,6 @@ upd7220_device::upd7220_device(const machine_config &mconfig, const char *tag, d
m_mask(0),
m_pitch(0),
m_ead(0),
m_dad(0),
m_lad(0),
m_ra_addr(0),
m_sr(UPD7220_SR_FIFO_EMPTY),
@ -700,7 +697,6 @@ void upd7220_device::device_start()
save_item(NAME(m_ctop));
save_item(NAME(m_cbot));
save_item(NAME(m_ead));
save_item(NAME(m_dad));
save_item(NAME(m_lad));
save_item(NAME(m_disp));
save_item(NAME(m_gchr));
@ -797,28 +793,16 @@ void upd7220_device::device_timer(emu_timer &timer, device_timer_id id, int para
// draw_pixel -
//-------------------------------------------------
void upd7220_device::draw_pixel(int x, int y, int xi, uint16_t tile_data)
void upd7220_device::draw_pixel()
{
uint32_t addr = (((y * (m_pitch >> m_figs.m_gd)) + (x >> 4))) & 0x3ffff;
uint16_t data = readword(addr);
uint16_t new_pixel = (tile_data & (1 << (xi & 0xf))) ? (1 << (x & 0xf)) : 0;
LOG("uPD7220 dot check: %08x %04x %02x %02x %d\n", m_ead, m_mask, m_bitmap_mod, m_figs.m_dir, m_figs.m_dc);
switch(m_bitmap_mod)
for(int i = 0; i <= m_figs.m_dc; ++i)
{
case 0: //replace
data = (data & ~(1 << (x & 0xf))) | new_pixel;
break;
case 1: //complement
data = data ^ new_pixel;
break;
case 2: //reset
data = data & ~new_pixel;
break;
case 3: //set
data = data | new_pixel;
break;
const uint16_t pattern = get_pattern(i & 0xf);
write_vram(0, m_bitmap_mod, pattern, m_mask);
next_pixel(m_figs.m_dir);
}
writeword(addr, data);
}
@ -826,158 +810,89 @@ void upd7220_device::draw_pixel(int x, int y, int xi, uint16_t tile_data)
// draw_line -
//-------------------------------------------------
void upd7220_device::draw_line(int x, int y)
void upd7220_device::draw_line()
{
int xi, yi;
int d = (m_figs.m_d & 0x2000) ? (int16_t)(m_figs.m_d | 0xe000) : m_figs.m_d;
int d1 = (m_figs.m_d1 & 0x2000) ? (int16_t)(m_figs.m_d1 | 0xe000) : m_figs.m_d1;
int d2 = (m_figs.m_d2 & 0x2000) ? (int16_t)(m_figs.m_d2 | 0xe000) : m_figs.m_d2;
uint16_t pattern = (m_ra[8]) | (m_ra[9]<<8);
const int dot_dir[4] = {1, -1, -1, 1};
const uint8_t octant = m_figs.m_dir;
LOG("uPD7220 line check: %d %d %02x %08x %d %d %d\n",x,y,m_figs.m_dir,m_ead,d1,m_figs.m_dc,m_bitmap_mod);
LOG("uPD7220 line check: %08x %04x %02x %02x %d %d %d %d\n", m_ead, m_mask, m_bitmap_mod, m_figs.m_dir, m_figs.m_dc, d, d1, d2);
for(yi = xi = 0; yi <= m_figs.m_dc; yi++)
for(int i = 0; i <= m_figs.m_dc; ++i)
{
switch(m_figs.m_dir & 3)
const uint16_t pattern = get_pattern(i & 0xf);
write_vram(0, m_bitmap_mod, pattern, m_mask);
if (octant & 1)
{
case 1:
case 2:
draw_pixel(yi * dot_dir[((m_figs.m_dir >> 1) + 3) & 3] + x, xi * dot_dir[m_figs.m_dir >> 1] + y, yi, pattern);
break;
default:
draw_pixel(xi * dot_dir[((m_figs.m_dir >> 1) + 3) & 3] + x, yi * dot_dir[m_figs.m_dir >> 1] + y, yi, pattern);
break;
}
if(d > 0)
{
xi++;
d += d2;
m_figs.m_dir = (d < 0) ? (octant + 1) & 7 : octant;
}
else
d += d1;
{
m_figs.m_dir = (d < 0) ? octant : (octant + 1) & 7;
}
d += ((d < 0 ) ? d1 : d2);
next_pixel(m_figs.m_dir);
}
switch(m_figs.m_dir & 3)
{
case 1:
case 2:
x += yi * dot_dir[((m_figs.m_dir >> 1) + 3) & 3];
y += xi * dot_dir[m_figs.m_dir >> 1];
break;
default:
x += xi * dot_dir[((m_figs.m_dir >> 1) + 3) & 3];
y += yi * dot_dir[m_figs.m_dir >> 1];
break;
}
m_ead = (x >> 4) + (y * (m_pitch >> m_figs.m_gd));
m_dad = x & 0x0f;
}
//-------------------------------------------------
// draw_arc -
//-------------------------------------------------
void upd7220_device::draw_arc(int x, int y)
void upd7220_device::draw_arc()
{
int xi = 0, err = -m_figs.m_d, d = m_figs.m_d + 1;
uint16_t pattern = (m_ra[8]) | (m_ra[9]<<8);
const int dot_dir[4] = {1, -1, -1, 1};
int err = -m_figs.m_d, d = m_figs.m_d + 1;
LOG("uPD7220 arc check: %d %d %02x %08x %d %d %d\n",x,y,m_figs.m_dir,m_ead,m_figs.m_dm,m_figs.m_dc,m_figs.m_d);
const uint16_t octant = m_figs.m_dir;
for(int yi = 0; yi <= m_figs.m_dc; yi++)
LOG("uPD7220 arc check: %08x %04x %02x %02x %d %d %d %d\n", m_ead, m_mask, m_bitmap_mod, m_figs.m_dir, m_figs.m_dc, m_figs.m_d, m_figs.m_d2, m_figs.m_dm);
for (int i = 0; i <= m_figs.m_dc; ++i)
{
if(yi >= m_figs.m_dm)
const uint16_t pattern = get_pattern(i % 0xf);
if (i >= m_figs.m_dm)
{
switch(m_figs.m_dir & 3)
{
case 1:
case 2:
draw_pixel(yi * dot_dir[((m_figs.m_dir >> 1) + 3) & 3] + x, xi * dot_dir[m_figs.m_dir >> 1] + y, yi, pattern);
break;
default:
draw_pixel(xi * dot_dir[((m_figs.m_dir >> 1) + 3) & 3] + x, yi * dot_dir[m_figs.m_dir >> 1] + y, yi, pattern);
break;
}
write_vram(0, m_bitmap_mod, pattern, m_mask);
}
if (err < 0)
{
m_figs.m_dir = (octant & 1) ? (octant + 1) & 7 : octant;
}
if(err < 0)
err += (yi + 1) << 1;
else
{
xi++;
d--;
err += (yi - d + 1) << 1;
m_figs.m_dir = (octant & 1) ? octant : (octant + 1) & 7;
}
err += (err < 0) ? ((i + 1) << 1) : ((i - --d + 1) << 1);
next_pixel(m_figs.m_dir);
}
switch(m_figs.m_dir & 3)
{
case 1:
case 2:
x += (m_figs.m_dc + 1) * dot_dir[((m_figs.m_dir >> 1) + 3) & 3];
break;
default:
y += (m_figs.m_dc + 1) * dot_dir[m_figs.m_dir >> 1];
break;
}
m_ead = (x >> 4) + (y * (m_pitch >> m_figs.m_gd));
m_dad = x & 0x0f;
}
//-------------------------------------------------
// draw_rectangle -
//-------------------------------------------------
void upd7220_device::draw_rectangle(int x, int y)
void upd7220_device::draw_rectangle()
{
const int rect_x_dir[8] = { 0, 1, 0,-1, 1, 1,-1,-1 };
const int rect_y_dir[8] = { 1, 0,-1, 0, 1,-1,-1, 1 };
uint8_t rect_type,rect_dir;
uint16_t pattern = (m_ra[8]) | (m_ra[9]<<8);
assert(m_figs.m_dc == 3);
LOG("uPD7220 rectangle check: %d %d %02x %08x\n",x,y,m_figs.m_dir,m_ead);
LOG("uPD7220 rectangle check: %08x %04x %02x %02x %d %d %d\n",m_ead, m_mask, m_bitmap_mod, m_figs.m_dir, m_figs.m_dc, m_figs.m_d, m_figs.m_d2);
rect_type = (m_figs.m_dir & 1) << 2;
rect_dir = rect_type | (((m_figs.m_dir >> 1) + 0) & 3);
for(int i = 0; i < m_figs.m_d; i++)
for (int i = 0; i <= m_figs.m_dc; ++i)
{
draw_pixel(x,y,i,pattern);
x+=rect_x_dir[rect_dir];
y+=rect_y_dir[rect_dir];
const uint16_t dist = (i & 1 ? m_figs.m_d2 : m_figs.m_d);
for (int j = 0; j < dist; ++j)
{
const uint16_t pattern = get_pattern(j & 0xf);
write_vram(0, m_bitmap_mod, pattern, m_mask);
if (i > 0 && j == 0)
m_figs.m_dir = (m_figs.m_dir + 2) & 7;
next_pixel(m_figs.m_dir);
}
}
rect_dir = rect_type | (((m_figs.m_dir >> 1) + 1) & 3);
for(int i = 0; i < m_figs.m_d2; i++)
{
draw_pixel(x,y,i,pattern);
x+=rect_x_dir[rect_dir];
y+=rect_y_dir[rect_dir];
}
rect_dir = rect_type | (((m_figs.m_dir >> 1) + 2) & 3);
for(int i = 0; i < m_figs.m_d; i++)
{
draw_pixel(x,y,i,pattern);
x+=rect_x_dir[rect_dir];
y+=rect_y_dir[rect_dir];
}
rect_dir = rect_type | (((m_figs.m_dir >> 1) + 3) & 3);
for(int i = 0; i < m_figs.m_d2; i++)
{
draw_pixel(x,y,i,pattern);
x+=rect_x_dir[rect_dir];
y+=rect_y_dir[rect_dir];
}
m_ead = (x >> 4) + (y * (m_pitch >> m_figs.m_gd));
m_dad = x & 0x0f;
}
@ -1190,7 +1105,6 @@ void upd7220_device::process_fifo()
{
uint8_t data;
int flag;
uint16_t eff_pitch = m_pitch >> m_figs.m_gd;
int cr;
dequeue(&data, &flag);
@ -1232,7 +1146,6 @@ void upd7220_device::process_fifo()
m_ra[0] = m_ra[1] = m_ra[2] = 0;
m_ra[3] = 0x19;
m_ead = 0;
m_dad = 0;
m_mask = 0;
break;
@ -1371,9 +1284,7 @@ void upd7220_device::process_fifo()
if(m_param_ptr == 4)
{
m_dad = (m_pr[3] >> 4) & 0x0f;;
m_mask = 1 << m_dad;
LOG("uPD7220 DAD: %01x\n", m_dad);
m_mask = 1 << ((m_pr[3] >> 4) & 0x0f);
LOG("uPD7220 MASK: %04x\n", m_mask);
}
}
@ -1466,14 +1377,15 @@ void upd7220_device::process_fifo()
break;
case COMMAND_FIGD: /* figure draw start */
m_pattern = (m_ra[8]) | (m_ra[9]<<8);
if(m_figs.m_figure_type == 0)
draw_pixel(((m_ead % eff_pitch) << 4) | (m_dad & 0xf),(m_ead / eff_pitch),m_dad,(m_ra[8]) | (m_ra[9]<<8));
draw_pixel();
else if(m_figs.m_figure_type == 1)
draw_line(((m_ead % eff_pitch) << 4) | (m_dad & 0xf),(m_ead / eff_pitch));
draw_line();
else if(m_figs.m_figure_type == 4)
draw_arc(((m_ead % eff_pitch) << 4) | (m_dad & 0xf),(m_ead / eff_pitch));
draw_arc();
else if(m_figs.m_figure_type == 8)
draw_rectangle(((m_ead % eff_pitch) << 4) | (m_dad & 0xf),(m_ead / eff_pitch));
draw_rectangle();
else
logerror("uPD7220 Unimplemented command FIGD %02x\n", m_figs.m_figure_type);
@ -1501,14 +1413,13 @@ void upd7220_device::process_fifo()
case COMMAND_CURD: /* cursor address read */
{
uint16_t dad = 1 << m_dad;
fifo_set_direction(FIFO_READ);
queue(m_ead & 0xff, 0);
queue((m_ead >> 8) & 0xff, 0);
queue(m_ead >> 16, 0);
queue(dad & 0xff, 0);
queue(dad >> 8, 0);
queue(m_mask & 0xff, 0);
queue(m_mask >> 8, 0);
m_sr |= UPD7220_SR_DATA_READY;
break;

View File

@ -122,10 +122,10 @@ private:
uint16_t get_pitch();
uint16_t get_pattern(uint8_t cycle);
void next_pixel(int direction);
void draw_pixel(int x, int y, int xi, uint16_t tile_data);
void draw_line(int x, int y);
void draw_rectangle(int x, int y);
void draw_arc(int x, int y);
void draw_pixel();
void draw_line();
void draw_rectangle();
void draw_arc();
void draw_char();
int translate_command(uint8_t data);
void process_fifo();
@ -154,7 +154,6 @@ private:
uint16_t m_mask; // mask register
uint8_t m_pitch; // number of word addresses in display memory in the horizontal direction
uint32_t m_ead; // execute word address
uint16_t m_dad; // dot address within the word
uint32_t m_lad; // light pen address
uint8_t m_ra[16]; // parameter RAM