diff options
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 |
commit | 3e714f3de19e0cb314eaa82f5f473e9c8b30d191 (patch) | |
tree | b8fc31a89884c47ba1d95786543cc2021f625540 | |
parent | b3f0a946a57dd1db3de4fe652a184402a15d5089 (diff) |
video/upd7220.cpp: Updated FIGD to use ead and mask to calculate drawing location. (#8405)
-rw-r--r-- | src/devices/video/upd7220.cpp | 209 | ||||
-rw-r--r-- | src/devices/video/upd7220.h | 9 |
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 |