From 0b513144cbe45330659dae245acc09b2ba7dd368 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Mon, 14 Nov 2022 16:19:27 +0000 Subject: newport: Split out iterator setup stage (#10546) In REX3, iterator setup should be a dedicated operation that is only execuated if a). A Draw command is execuated with DoSetup at DRAWMODE0 set or b). A host write is issued to SETUP register At setup stage REX3 will calcuate quadrant for a block or span drawcall or octant together with some Bresenham parameters for a line drawcall. Linux newport_con driver is rely on this behavior to use quadrant calculated by previous draw call to render characters. Fixes: #9667 Signed-off-by: Jiaxun Yang Signed-off-by: Jiaxun Yang --- src/devices/bus/gio64/newport.cpp | 70 ++++++++++++++++++++++++++++++++++++--- src/devices/bus/gio64/newport.h | 1 + 2 files changed, 67 insertions(+), 4 deletions(-) diff --git a/src/devices/bus/gio64/newport.cpp b/src/devices/bus/gio64/newport.cpp index 12cba5ef611..e72e4639677 100644 --- a/src/devices/bus/gio64/newport.cpp +++ b/src/devices/bus/gio64/newport.cpp @@ -2716,6 +2716,46 @@ uint8_t newport_base_device::get_octant(int32_t x1, int32_t y1, int32_t x2, int3 } } +void newport_base_device::do_setup(void) +{ + const int32_t x1 = util::sext(m_rex3.m_x_start >> 7, 20); + const int32_t y1 = util::sext(m_rex3.m_y_start >> 7, 20); + const int32_t x2 = util::sext(m_rex3.m_x_end >> 7, 20); + const int32_t y2 = util::sext(m_rex3.m_y_end >> 7, 20); + const int32_t dx = abs(x1 - x2); + const int32_t dy = abs(y1 - y2); + const uint8_t adrmode = (m_rex3.m_draw_mode0 >> 2) & 7; + + if (adrmode >= 0 && adrmode <= 1) { + /* quadrant for block or span */ + uint8_t quadrant = 0; + /* This is purely guessed */ + if (x1 > x2) + { + if (y1 > y2) + quadrant = 3; + else + quadrant = 2; + } + else + { + if (y1 > y2) + quadrant = 1; + else + quadrant = 0; + } + m_rex3.m_bres_octant_inc1 &= ~(0x7 << 24); + m_rex3.m_bres_octant_inc1 |= quadrant << 24; + } else if (adrmode >= 2 && adrmode <= 4) { + uint8_t octant; + /* octant for line */ + /* FIXME: error terms and Bresenham terms */ + octant = get_octant(x1, y1, x2, y2, dx, dy); + m_rex3.m_bres_octant_inc1 &= ~(0x7 << 24); + m_rex3.m_bres_octant_inc1 |= octant << 24; + } +} + void newport_base_device::do_fline(uint32_t color) { const int32_t x1 = util::sext(m_rex3.m_x_start >> 7, 20); @@ -2758,7 +2798,7 @@ void newport_base_device::do_fline(uint32_t color) { 1, 1, 0, -1, 0 } }; - const uint8_t octant = get_octant(x1, y1, x2, y2, dx, dy); + const uint8_t octant = (m_rex3.m_bres_octant_inc1 >> 24) & 0x7; const int32_t incrx1 = s_bresenham_infos[octant].incrx1; const int32_t incrx2 = s_bresenham_infos[octant].incrx2; const int32_t incry1 = s_bresenham_infos[octant].incry1; @@ -2949,7 +2989,7 @@ void newport_base_device::do_iline(uint32_t color) { 1, 1, 0, -1, 0 } }; - const uint8_t octant = get_octant(x1, y1, x2, y2, dx, dy); + const uint8_t octant = (m_rex3.m_bres_octant_inc1 >> 24) & 0x7; const int32_t incrx1 = s_bresenham_infos[octant].incrx1; const int32_t incrx2 = s_bresenham_infos[octant].incrx2; const int32_t incry1 = s_bresenham_infos[octant].incry1; @@ -3297,8 +3337,7 @@ void newport_base_device::do_rex3_command() int16_t start_y = m_rex3.m_y_start_i; int16_t end_x = m_rex3.m_x_end_i; int16_t end_y = m_rex3.m_y_end_i; - int16_t dx = start_x > end_x ? -1 : 1; - int16_t dy = start_y > end_y ? -1 : 1; + int16_t dx = 1, dy = 1; LOGMASKED(LOG_COMMANDS, "REX3 Command: %08x|%08x - %s %s\n", mode0, mode1, s_opcode_str[mode0 & 3], s_adrmode_str[(mode0 >> 2) & 7]); @@ -3313,6 +3352,28 @@ void newport_base_device::do_rex3_command() m_rex3.m_host_dataport = do_pixel_word_read(); break; case 2: // Draw + if (BIT(mode0, 5)) + do_setup(); + + switch ((m_rex3.m_bres_octant_inc1 >> 24) & 0x3) + { + case 0: + dx = 1; + dy = 1; + break; + case 1: + dx = 1; + dy = -1; + break; + case 2: + dx = -1; + dy = 1; + break; + case 3: + dx = -1; + dy = -1; + break; + } switch (adrmode) { case 0: // Span @@ -3898,6 +3959,7 @@ void newport_base_device::rex3_w(offs_t offset, uint64_t data, uint64_t mem_mask { LOGMASKED(LOG_REX3, "REX3 Line/Span Setup Write: %08x\n", (uint32_t)(data >> 32)); m_rex3.m_setup = (uint32_t)(data >> 32); + do_setup(); } if (ACCESSING_BITS_0_31) { diff --git a/src/devices/bus/gio64/newport.h b/src/devices/bus/gio64/newport.h index 00a6e36e22d..611372c5f4f 100644 --- a/src/devices/bus/gio64/newport.h +++ b/src/devices/bus/gio64/newport.h @@ -484,6 +484,7 @@ protected: uint8_t loop; }; uint8_t get_octant(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t dx, int32_t dy); + void do_setup(); void do_fline(uint32_t color); void do_iline(uint32_t color); -- cgit v1.2.3