summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Brian Johnson <brijohn@gmail.com>2021-08-12 12:55:20 -0400
committer GitHub <noreply@github.com>2021-08-13 02:55:20 +1000
commit3e714f3de19e0cb314eaa82f5f473e9c8b30d191 (patch)
treeb8fc31a89884c47ba1d95786543cc2021f625540
parentb3f0a946a57dd1db3de4fe652a184402a15d5089 (diff)
video/upd7220.cpp: Updated FIGD to use ead and mask to calculate drawing location. (#8405)
-rw-r--r--src/devices/video/upd7220.cpp209
-rw-r--r--src/devices/video/upd7220.h9
2 files changed, 64 insertions, 154 deletions
diff --git a/src/devices/video/upd7220.cpp b/src/devices/video/upd7220.cpp
index d3c0e007b12..da804b7f286 100644
--- a/src/devices/video/upd7220.cpp
+++ b/src/devices/video/upd7220.cpp
@@ -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;
+ m_figs.m_dir = (d < 0) ? (octant + 1) & 7 : octant;
}
- if(d > 0)
+ else
{
- xi++;
- d += d2;
+ m_figs.m_dir = (d < 0) ? octant : (octant + 1) & 7;
}
- else
- d += d1;
- }
-
- 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;
+ d += ((d < 0 ) ? d1 : d2);
+ next_pixel(m_figs.m_dir);
}
-
- 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;
+
+ const uint16_t octant = m_figs.m_dir;
- 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);
+ 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 yi = 0; yi <= m_figs.m_dc; yi++)
+ 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);
-
- LOG("uPD7220 rectangle check: %d %d %02x %08x\n",x,y,m_figs.m_dir,m_ead);
+ assert(m_figs.m_dc == 3);
- rect_type = (m_figs.m_dir & 1) << 2;
- rect_dir = rect_type | (((m_figs.m_dir >> 1) + 0) & 3);
+ 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);
- 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];
- }
-
- 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);
+ 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);
+ }
- 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;
diff --git a/src/devices/video/upd7220.h b/src/devices/video/upd7220.h
index c43a265544f..31ac30f4dac 100644
--- a/src/devices/video/upd7220.h
+++ b/src/devices/video/upd7220.h
@@ -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