diff options
Diffstat (limited to 'src/devices/bus/gio/newport.cpp')
-rw-r--r-- | src/devices/bus/gio/newport.cpp | 946 |
1 files changed, 666 insertions, 280 deletions
diff --git a/src/devices/bus/gio/newport.cpp b/src/devices/bus/gio/newport.cpp index cd0c23a58da..07d1be903c8 100644 --- a/src/devices/bus/gio/newport.cpp +++ b/src/devices/bus/gio/newport.cpp @@ -40,7 +40,7 @@ #define LOG_REJECTS (1 << 8) #define LOG_ALL (LOG_UNKNOWN | LOG_VC2 | LOG_CMAP0 | LOG_CMAP1 | LOG_XMAP0 | LOG_XMAP1 | LOG_REX3 | LOG_COMMANDS | LOG_REJECTS) -#define VERBOSE (0)//(LOG_UNKNOWN | LOG_REX3 | LOG_COMMANDS | LOG_REJECTS) +#define VERBOSE (0)//(LOG_UNKNOWN | LOG_REX3 | LOG_COMMANDS) #include "logmacro.h" DEFINE_DEVICE_TYPE(GIO_XL8, gio_xl8_device, "gio_xl8", "SGI 8-bit XL board") @@ -135,6 +135,10 @@ void newport_base_device::device_start() save_item(NAME(m_rex3.m_y_start)); save_item(NAME(m_rex3.m_x_end)); save_item(NAME(m_rex3.m_y_end)); + save_item(NAME(m_rex3.m_x_start_frac)); + save_item(NAME(m_rex3.m_y_start_frac)); + save_item(NAME(m_rex3.m_x_end_frac)); + save_item(NAME(m_rex3.m_y_end_frac)); save_item(NAME(m_rex3.m_x_save)); save_item(NAME(m_rex3.m_xy_move)); @@ -184,7 +188,10 @@ void newport_base_device::device_start() save_item(NAME(m_rex3.m_config)); save_item(NAME(m_rex3.m_status)); save_item(NAME(m_rex3.m_xfer_width)); - save_item(NAME(m_rex3.m_read_active)); + save_item(NAME(m_rex3.m_store_shift)); + save_item(NAME(m_rex3.m_logic_op)); + save_item(NAME(m_rex3.m_src_blend)); + save_item(NAME(m_rex3.m_dst_blend)); save_item(NAME(m_cmap0.m_palette_idx)); save_item(NAME(m_cmap0.m_palette)); @@ -299,6 +306,7 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32 { uint32_t *src_ci = &m_rgbci[1344 * y]; uint32_t *src_pup = &m_pup[1344 * y]; + uint32_t *src_olay = &m_pup[1344 * y]; uint32_t *dest = &bitmap.pix32(y, cliprect.min_x); m_vc2.m_did_frame_ptr = m_vc2.m_did_entry + (uint16_t)y; @@ -307,6 +315,10 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32 // Fetch the initial DID entry uint16_t curr_did_entry = m_vc2.m_ram[m_vc2.m_did_line_ptr]; uint32_t table_entry = m_xmap0.m_mode_table[curr_did_entry & 0x1f]; + uint8_t pix_mode = (table_entry >> 8) & 3; + uint8_t pix_size = (table_entry >> 10) & 3; + uint8_t aux_pix_mode = (table_entry >> 16) & 7; + uint16_t aux_msb = (table_entry >> 11) & 0x1f00; uint16_t ci_msb = 0; switch ((table_entry >> 8) & 3) { @@ -326,6 +338,10 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32 if ((uint16_t)x == (curr_did_entry >> 5)) { table_entry = m_xmap0.m_mode_table[curr_did_entry & 0x1f]; + pix_mode = (table_entry >> 8) & 3; + pix_size = (table_entry >> 10) & 3; + aux_pix_mode = (table_entry >> 16) & 7; + aux_msb = (table_entry >> 11) & 0x1f00; switch ((table_entry >> 8) & 3) { case 0: ci_msb = (m_xmap0.m_mode_table[curr_did_entry & 0x1f] & 0xf8) << 5; break; @@ -342,21 +358,114 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32 cursor_pixel = get_cursor_pixel(x - ((int)m_vc2.m_cursor_x - 31), y - ((int)m_vc2.m_cursor_y - 31)); } + bool pixel_replaced = false; if (cursor_pixel) { *dest++ = m_cmap0.m_palette[cursor_msb | cursor_pixel]; + pixel_replaced = true; } else if (*src_pup) { const uint32_t src = (*src_pup >> 2) & 3; *dest++ = m_cmap0.m_palette[popup_msb | src]; + pixel_replaced = true; } - else + else if (aux_pix_mode != 0) + { + if (BIT(m_xmap0.m_config, 2)) + { + switch (aux_pix_mode) + { + case 1: // 2-Bit Underlay + *dest++ = m_cmap0.m_palette[aux_msb | ((*src_olay >> 8) & 3)]; + pixel_replaced = true; + continue; + case 2: // 2-Bit Overlay + { + const uint32_t pix_in = (*src_olay >> 8) & 3; + if (pix_in) + { + *dest++ = m_cmap0.m_palette[aux_msb | pix_in]; + pixel_replaced = true; + } + break; + } + case 6: // 1-Bit Overlay + { + const uint32_t shift = BIT(table_entry, 1) ? 9 : 8; + const uint32_t pix_in = (*src_olay >> shift) & 1; + if (pix_in) + { + *dest++ = m_cmap0.m_palette[aux_msb | pix_in]; + pixel_replaced = true; + } + break; + } + case 7: // 1-Bit Overlay, 1-Bit Underlay + { + const uint32_t pix_in = (*src_olay >> 8) & 1; + if (pix_in) + *dest++ = m_cmap0.m_palette[aux_msb | pix_in]; + else + *dest++ = m_cmap0.m_palette[aux_msb | ((*src_olay >> 9) & 1)]; + pixel_replaced = true; + break; + } + default: + break; + } + } + else + { + switch (aux_pix_mode) + { + case 1: // 8-Bit Underlay + *dest++ = m_cmap0.m_palette[aux_msb | ((*src_olay >> 8) & 0xff)]; + pixel_replaced = true; + break; + case 2: // 8-Bit Overlay + { + const uint32_t pix_in = (*src_olay >> 8) & 0xff; + if (pix_in) + { + *dest++ = m_cmap0.m_palette[aux_msb | pix_in]; + pixel_replaced = true; + } + break; + } + case 6: // 4-Bit Overlay + { + const uint32_t shift = BIT(table_entry, 1) ? 12 : 8; + const uint32_t pix_in = (*src_olay >> shift) & 0xf; + if (pix_in) + { + *dest++ = m_cmap0.m_palette[aux_msb | pix_in]; + pixel_replaced = true; + } + break; + } + case 7: // 4-Bit Overlay, 4-Bit Underlay + { + const uint32_t pix_in = (*src_pup >> 8) & 0xf; + if (pix_in) + *dest++ = m_cmap0.m_palette[aux_msb | pix_in]; + else + *dest++ = m_cmap0.m_palette[aux_msb | ((*src_pup >> 12) & 0xf)]; + pixel_replaced = true; + break; + } + default: + break; + } + } + } + + if (!pixel_replaced) { - switch ((table_entry >> 8) & 3) + switch (pix_mode) { case 0: // CI - switch ((table_entry >> 10) & 3) + switch (pix_size) { case 0: // 4bpp { @@ -368,13 +477,20 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32 case 1: // 8bpp *dest++ = m_cmap0.m_palette[ci_msb | (uint8_t)*src_ci]; break; - case 2: // 12bpp (not yet supported) + case 2: // 12bpp + { + const uint8_t shift = BIT(table_entry, 0) ? 12 : 0; + const uint32_t pix_in = (*src_ci >> shift) & 0x00000fff; + *dest++ = m_cmap0.m_palette[(ci_msb & 0x1000) | pix_in]; + break; + } case 3: // 24bpp (not yet supported) + dest++; break; } break; case 1: // RGB Map0 - switch ((table_entry >> 10) & 3) + switch (pix_size) { case 0: // 4bpp { @@ -428,6 +544,7 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32 src_ci++; src_pup++; + src_olay++; } } @@ -1477,46 +1594,197 @@ bool newport_base_device::pixel_clip_pass(int16_t x, int16_t y) void newport_base_device::store_pixel(uint32_t *dest_buf, uint32_t src) { - if (BIT(m_rex3.m_draw_mode1, 5)) + const uint32_t write_mask = m_rex3.m_write_mask & m_global_mask; + const uint32_t dst = *dest_buf; + *dest_buf &= ~write_mask; + + + if (BIT(m_rex3.m_draw_mode1, 18)) // Blending { - switch ((m_rex3.m_draw_mode1 >> 3) & 3) + float sa = 0.0f; + float sb = 0.0f; + float sg = 0.0f; + float sr = 0.0f; + + float db = 0.0f; + float dg = 0.0f; + float dr = 0.0f; + + float sbb = 0.0f; + float sgb = 0.0f; + float srb = 0.0f; + + float dbb = 0.0f; + float dgb = 0.0f; + float drb = 0.0f; + + switch (m_rex3.m_plane_depth) { - case 0: // 4bpp - src <<= 4; - break; - case 2: // 12bpp - src <<= 12; - break; - case 1: // 8bpp - case 3: // 24bpp - // Can't double-buffer - break; + case 0: // 4bpp (not supported) + case 1: // 8bpp (not supported) + break; + case 2: // 12bpp + sa = (((src >> 12) & 15) * 0x11) / 255.0f; + sr = (((src >> 8) & 15) * 0x11) / 255.0f; + sg = (((src >> 4) & 15) * 0x11) / 255.0f; + sb = (((src >> 0) & 15) * 0x11) / 255.0f; + + if (BIT(m_rex3.m_draw_mode1, 25)) + { + db = (uint8_t)(m_rex3.m_color_back >> 16) / 255.0f; + dg = (uint8_t)(m_rex3.m_color_back >> 8) / 255.0f; + dr = (uint8_t)(m_rex3.m_color_back >> 0) / 255.0f; + } + else + { + const uint32_t dstc = (dst >> m_rex3.m_store_shift) & 0xfff; + dr = (((dstc >> 8) & 15) * 0x11) / 255.0f; + dg = (((dstc >> 4) & 15) * 0x11) / 255.0f; + db = (((dstc >> 0) & 15) * 0x11) / 255.0f; + } + break; + case 3: // 24bpp + sa = (uint8_t)(src >> 24) / 255.0f; + sr = (uint8_t)(src >> 16) / 255.0f; + sg = (uint8_t)(src >> 8) / 255.0f; + sb = (uint8_t)(src >> 0) / 255.0f; + + if (BIT(m_rex3.m_draw_mode1, 25)) + { + db = (uint8_t)(m_rex3.m_color_back >> 16) / 255.0f; + dg = (uint8_t)(m_rex3.m_color_back >> 8) / 255.0f; + dr = (uint8_t)(m_rex3.m_color_back >> 0) / 255.0f; + } + else + { + const uint32_t dstc = dst; + dr = (uint8_t)(dstc >> 16) / 255.0f; + dg = (uint8_t)(dstc >> 8) / 255.0f; + db = (uint8_t)(dstc >> 0) / 255.0f; + } + break; } - } - const uint32_t dst = *dest_buf; - *dest_buf &= ~m_rex3.m_write_mask; + switch (m_rex3.m_src_blend) + { + case 0: // 0 + default: + break; + case 1: // 1 + sbb = sb; + sgb = sg; + srb = sr; + break; + case 2: // dstc + sbb = sb * db; + sgb = sg * dg; + srb = sr * dr; + break; + case 3: // 1 - dstc + sbb = sb * (1.0f - db); + sgb = sg * (1.0f - dg); + srb = sr * (1.0f - dr); + break; + case 4: // srca + if (BIT(m_rex3.m_draw_mode1, 27)) + { + sbb = sb * sa; + sgb = sg * sa; + srb = sr * sa; + } + else + { + sbb = sb; + sgb = sg; + srb = sr; + } + break; + case 5: // 1 - srca + if (BIT(m_rex3.m_draw_mode1, 27)) + { + sbb = sb * (1.0f - sa); + sgb = sg * (1.0f - sa); + srb = sr * (1.0f - sa); + } + break; + } - const uint32_t write_mask = m_rex3.m_write_mask & m_global_mask; + switch (m_rex3.m_dst_blend) + { + case 0: // 0 + default: + break; + case 1: // 1 + dbb = db; + dgb = dg; + drb = dr; + break; + case 2: // srcc + dbb = db * sb; + dgb = dg * sg; + drb = dr * sr; + break; + case 3: // 1 - srcc + dbb = db * (1.0f - sb); + dgb = dg * (1.0f - sg); + drb = dr * (1.0f - sr); + break; + case 4: // srca + dbb = db * sa; + dgb = dg * sa; + drb = dr * sa; + break; + case 5: // 1 - srca + dbb = db * (1.0f - sa); + dgb = dg * (1.0f - sa); + drb = dr * (1.0f - sa); + break; + } - switch ((m_rex3.m_draw_mode1 >> 28) & 15) + const float b_blend = sbb + dbb; + const float g_blend = sgb + dgb; + const float r_blend = srb + drb; + + const uint8_t b_blend_i = b_blend > 1.0f ? 255 : (b_blend < 0.0f ? 0 : (uint8_t)(b_blend * 255.0f)); + const uint8_t g_blend_i = g_blend > 1.0f ? 255 : (g_blend < 0.0f ? 0 : (uint8_t)(g_blend * 255.0f)); + const uint8_t r_blend_i = r_blend > 1.0f ? 255 : (r_blend < 0.0f ? 0 : (uint8_t)(r_blend * 255.0f)); + + switch (m_rex3.m_plane_depth) + { + case 0: // 4bpp (not supported) + case 1: // 8bpp (not supported) + break; + case 2: // 12bpp + *dest_buf |= ((((r_blend_i & 0xf0) << 4) | (g_blend_i & 0xf0) | ((b_blend_i & 0xf0) >> 4)) << m_rex3.m_store_shift) & write_mask; + break; + case 3: // 24bpp + *dest_buf |= ((r_blend_i << 16) | (g_blend_i << 8) | b_blend_i) & write_mask; + break; + } + } + else { - case 0: break; - case 1: *dest_buf |= (src & dst) & write_mask; break; - case 2: *dest_buf |= (src & ~dst) & write_mask; break; - case 3: *dest_buf |= (src) & write_mask; break; - case 4: *dest_buf |= (~src & dst) & write_mask; break; - case 5: *dest_buf |= (dst) & write_mask; break; - case 6: *dest_buf |= (src ^ dst) & write_mask; break; - case 7: *dest_buf |= (src | dst) & write_mask; break; - case 8: *dest_buf |= ~(src | dst) & write_mask; break; - case 9: *dest_buf |= ~(src ^ dst) & write_mask; break; - case 10: *dest_buf |= ~(dst) & write_mask; break; - case 11: *dest_buf |= (src | ~dst) & write_mask; break; - case 12: *dest_buf |= ~(src) & write_mask; break; - case 13: *dest_buf |= (~src | dst) & write_mask; break; - case 14: *dest_buf |= ~(src & dst) & write_mask; break; - case 15: *dest_buf |= 0xffffff & write_mask; break; + src <<= m_rex3.m_store_shift; + + switch (m_rex3.m_logic_op) + { + case 0: break; + case 1: *dest_buf |= (src & dst) & write_mask; break; + case 2: *dest_buf |= (src & ~dst) & write_mask; break; + case 3: *dest_buf |= (src) & write_mask; break; + case 4: *dest_buf |= (~src & dst) & write_mask; break; + case 5: *dest_buf |= (dst) & write_mask; break; + case 6: *dest_buf |= (src ^ dst) & write_mask; break; + case 7: *dest_buf |= (src | dst) & write_mask; break; + case 8: *dest_buf |= ~(src | dst) & write_mask; break; + case 9: *dest_buf |= ~(src ^ dst) & write_mask; break; + case 10: *dest_buf |= ~(dst) & write_mask; break; + case 11: *dest_buf |= (src | ~dst) & write_mask; break; + case 12: *dest_buf |= ~(src) & write_mask; break; + case 13: *dest_buf |= (~src | dst) & write_mask; break; + case 14: *dest_buf |= ~(src & dst) & write_mask; break; + case 15: *dest_buf |= 0xffffff & write_mask; break; + } } } @@ -1532,7 +1800,7 @@ void newport_base_device::write_pixel(int16_t x, int16_t y, uint32_t color) x -= 0x1000; y -= 0x1000; - switch (m_rex3.m_draw_mode1 & 7) + switch (m_rex3.m_plane_enable) { case 1: // RGB/CI planes store_pixel(&m_rgbci[y * (1280 + 64) + x], color); @@ -1567,7 +1835,7 @@ uint32_t newport_base_device::get_rgb_color(int16_t x, int16_t y) if (BIT(m_rex3.m_draw_mode1, 16)) // Dithering { - switch ((m_rex3.m_draw_mode1 >> 3) & 3) + switch (m_rex3.m_plane_depth) { case 0: // 4bpp { @@ -1641,7 +1909,7 @@ uint32_t newport_base_device::get_rgb_color(int16_t x, int16_t y) } else { - switch ((m_rex3.m_draw_mode1 >> 3) & 3) + switch (m_rex3.m_plane_depth) { case 0: // 4bpp return (BIT(blue, 7) << 3) | ((green & 0xc0) >> 5) | BIT(red, 7); @@ -1657,224 +1925,342 @@ uint32_t newport_base_device::get_rgb_color(int16_t x, int16_t y) } } -void newport_base_device::do_v_iline(uint32_t color) +uint8_t newport_base_device::get_octant(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t dx, int16_t dy) { - const int16_t x1 = m_rex3.m_x_start_i; - int16_t y1 = m_rex3.m_y_start_i; - const int16_t y2 = m_rex3.m_y_end_i; - - const int16_t incy = (y2 < y1) ? -1 : 1; - - const bool iterate_one = (m_rex3.m_draw_mode0 & 0x300) == 0; - const bool skip_last = BIT(m_rex3.m_draw_mode0, 11); - const bool shade = BIT(m_rex3.m_draw_mode0, 18); - const bool rgbmode = BIT(m_rex3.m_draw_mode1, 15); - - do - { - if (shade || rgbmode) - write_pixel(x1, y1, get_rgb_color(x1, y1)); - else - write_pixel(x1, y1, color); - - y1 += incy; - - if (shade) - iterate_shade(); - } while (y1 != y2 && !iterate_one); - - if (!skip_last && !iterate_one) - { - if (shade || rgbmode) - write_pixel(x1, y1, get_rgb_color(x1, y1)); - else - write_pixel(x1, y1, color); - - if (shade) - iterate_shade(); - } - - write_x_start(x1 << 11); - write_y_start(y1 << 11); + if (x1 < x2) + { + if (y2 < y1) + return (dx > dy) ? 0 : 1; + else + return (dx > dy) ? 7 : 6; + } + else + { + if (y2 < y1) + return (dx > dy) ? 3 : 2; + else + return (dx > dy) ? 4 : 5; + } } -void newport_base_device::do_h_iline(uint32_t color) +void newport_base_device::do_fline(uint32_t color) { - int16_t x1 = m_rex3.m_x_start_i; - const int16_t y1 = m_rex3.m_y_start_i; - const int16_t x2 = m_rex3.m_x_end_i; - - const int16_t incx = (x2 < x1) ? -1 : 1; - - const bool iterate_one = (m_rex3.m_draw_mode0 & 0x300) == 0; - const bool skip_last = BIT(m_rex3.m_draw_mode0, 11); - const bool shade = BIT(m_rex3.m_draw_mode0, 18); - const bool rgbmode = BIT(m_rex3.m_draw_mode1, 15); - - do - { - if (shade || rgbmode) - write_pixel(x1, y1, get_rgb_color(x1, y1)); - else - write_pixel(x1, y1, color); - - x1 += incx; - - if (shade) - iterate_shade(); - } while (x1 != x2 && !iterate_one); - - if (!skip_last && !iterate_one) - { - if (shade || rgbmode) - write_pixel(x1, y1, get_rgb_color(x1, y1)); - else - write_pixel(x1, y1, color); - - if (shade) - iterate_shade(); - } - - write_x_start(x1 << 11); - write_y_start(y1 << 11); + const int32_t x1 = m_rex3.m_x_start >> 7; + const int32_t y1 = m_rex3.m_y_start >> 7; + const int32_t x2 = m_rex3.m_x_end >> 7; + const int32_t y2 = m_rex3.m_y_end >> 7; + + const int16_t x10 = x1 & ~0xf; + const int16_t y10 = y1 & ~0xf; + const int16_t x20 = x2 & ~0xf; + const int16_t y20 = y2 & ~0xf; + + const bool iterate_one = (m_rex3.m_draw_mode0 & 0x300) == 0; + const bool skip_first = BIT(m_rex3.m_draw_mode0, 10); + const bool skip_last = BIT(m_rex3.m_draw_mode0, 11); + const bool shade = BIT(m_rex3.m_draw_mode0, 18); + const bool rgbmode = BIT(m_rex3.m_draw_mode1, 15); + + int16_t x = x10; + int16_t y = y10; + + int16_t x1_fract = m_rex3.m_x_start_frac; + int16_t y1_fract = m_rex3.m_y_start_frac; + + int32_t dx = abs(x1 - x2); + int32_t dy = abs(y1 - y2); + + const int16_t dx_i = abs(x10 - x20) - 1; + const int16_t dy_i = abs(y10 - y20) - 1; + + static const bresenham_octant_info_t s_bresenham_infos[8] = + { + { 1, 1, 0, 1, 0 }, + { 0, 1, 1, 1, 1 }, + { 0, -1, 1, 1, 1 }, + { -1, -1, 0, 1, 0 }, + { -1, -1, 0, -1, 0 }, + { 0, -1, -1, -1, 1 }, + { 0, 1, -1, -1, 1 }, + { 1, 1, 0, -1, 0 } + }; + + const uint8_t octant = get_octant(x1, y1, x2, y2, dx, dy); + const int16_t incrx1 = s_bresenham_infos[octant].incrx1; + const int16_t incrx2 = s_bresenham_infos[octant].incrx2; + const int16_t incry1 = s_bresenham_infos[octant].incry1; + const int16_t incry2 = s_bresenham_infos[octant].incry2; + int16_t loop = s_bresenham_infos[octant].loop ? dy_i : dx_i; + if (BIT(m_rex3.m_draw_mode0, 15) && loop > 32) + loop = 32; + const int16_t x_major = 1 - s_bresenham_infos[octant].loop; + + const int32_t incr1 = s_bresenham_infos[octant].loop ? (2 * dx) : (2 * dy); + const int32_t incr2 = s_bresenham_infos[octant].loop ? (2 * (dx - dy)) : (2 * (dy - dx)); + int32_t d = s_bresenham_infos[octant].loop ? (3 * dx - 2 * dy) : (3 * dy - 2 * dx); + + switch (octant) + { + case 0: + // Nothing special needed + break; + case 1: + { + const int16_t temp_fract = x1_fract; + x1_fract = y1_fract; + y1_fract = temp_fract; + const int32_t temp_d = dx; + dx = dy; + dy = temp_d; + break; + } + case 2: + { + const int16_t temp_fract = 0x10 - x1_fract; + x1_fract = y1_fract; + y1_fract = temp_fract; + const int32_t temp_d = dx; + dx = dy; + dy = temp_d; + break; + } + case 3: + x1_fract = 0x10 - x1_fract; + break; + case 4: + x1_fract = 0x10 - x1_fract; + y1_fract = 0x10 - y1_fract; + break; + case 5: + { + const int16_t temp_fract = 0x10 - x1_fract; + x1_fract = 0x10 - y1_fract; + y1_fract = temp_fract; + const int32_t temp_d = dx; + dx = dy; + dy = temp_d; + break; + } + case 6: + { + const int16_t temp_fract = 0x10 - y1_fract; + y1_fract = x1_fract; + x1_fract = temp_fract; + const int32_t temp_d = dx; + dx = dy; + dy = temp_d; + break; + } + case 7: + y1_fract = 0x10 - y1_fract; + break; + } + + d += 2 * (((dx * y1_fract) >> 4) - ((dy * x1_fract) >> 4)); // Adjust d due to fractional endpoints + const int32_t E = d - 2 * dx; // Variable used for adjusting the start point up one pixel + if (E > 0) + { + d = E; + x += incrx2 * (1 - x_major); + y += incry2 * x_major; + } + + if (!skip_first || iterate_one) + { + if (shade || rgbmode) + write_pixel(x >> 4, y >> 4, get_rgb_color(x >> 4, y >> 4)); + else + write_pixel(x >> 4, y >> 4, color); + + if (shade) + iterate_shade(); + + if (d < 0) + { + x += incrx1; + y -= incry1; + d += incr1; + } + else + { + x += incrx2; + y -= incry2; + d += incr2; + } + + if (iterate_one) + { + write_x_start(x << 7); + write_y_start(y << 7); + return; + } + } + + for (int16_t i = 1; i < loop; i++) + { + if (shade || rgbmode) + write_pixel(x >> 4, y >> 4, get_rgb_color(x >> 4, y >> 4)); + else + write_pixel(x >> 4, y >> 4, color); + + if (shade) + iterate_shade(); + + if (d < 0) + { + x += incrx1; + y -= incry1; + d += incr1; + } + else + { + x += incrx2; + y -= incry2; + d += incr2; + } + } + + if (!skip_last) + { + if (shade || rgbmode) + write_pixel(x2 >> 4, y2 >> 4, get_rgb_color(x2 >> 4, y2 >> 4)); + else + write_pixel(x2 >> 4, y2 >> 4, color); + + if (shade) + iterate_shade(); + + write_x_start(x2); + write_y_start(y2); + } + else + { + write_x_start(x << 7); + write_y_start(y << 7); + } } void newport_base_device::do_iline(uint32_t color) { - int16_t x1 = m_rex3.m_x_start_i; - int16_t y1 = m_rex3.m_y_start_i; - int16_t x2 = m_rex3.m_x_end_i; - int16_t y2 = m_rex3.m_y_end_i; - - unsigned char c1 = 0; - int16_t incy = 1; - - int16_t dx = abs(x2 - x1); - int16_t dy = abs(y2 - y1); - - const bool iterate_one = (m_rex3.m_draw_mode0 & 0x300) == 0; - const bool skip_last = BIT(m_rex3.m_draw_mode0, 11); - const bool shade = BIT(m_rex3.m_draw_mode0, 18); - const bool rgbmode = BIT(m_rex3.m_draw_mode1, 15); - - if (dy > dx) - { - int16_t t = y2; - y2 = x2; - x2 = t; - - t = y1; - y1 = x1; - x1 = t; - - t = dx; - dx = dy; - dy = t; - - c1 = 1; - } - - if (x1 > x2) - { - int16_t t = y2; - y2 = y1; - y1 = t; - - t = x1; - x1 = x2; - x2 = t; - } - - int16_t length_limit = x1 + (BIT(m_rex3.m_draw_mode0, 15) ? 32 : 0); - - int horiz = dy << 1; - int diago = (dy - dx) << 1; - int e = (dy << 1) - dx; - - if (y1 <= y2) - incy = 1; - else - incy = -1; - - if (c1) - { - do - { - if (shade || rgbmode) - write_pixel(y1, x1, get_rgb_color(x1, y1)); - else - write_pixel(y1, x1, color); - - if (e > 0) - { - y1 += incy; - e = e + diago; - } - else - { - e = e + horiz; - } - - x1++; - if (shade) - iterate_shade(); - } while (x1 != x2 && x1 != length_limit && !iterate_one); - - if (!skip_last && !iterate_one) - { - if (shade || rgbmode) - write_pixel(y1, x1, get_rgb_color(y1, x1)); - else - write_pixel(y1, x1, color); - - if (shade) - iterate_shade(); - } - } - else - { - do - { - if (shade || rgbmode) - write_pixel(x1, y1, get_rgb_color(x1, y1)); - else - write_pixel(x1, y1, color); - - if (e > 0) - { - y1 += incy; - e = e + diago; - } - else - { - e = e + horiz; - } - - x1++; - if (shade) - iterate_shade(); - } while (x1 != x2 && x1 != length_limit && !iterate_one); - - if (!skip_last && !iterate_one) - { - if (shade || rgbmode) - write_pixel(x1, y1, get_rgb_color(x1, y1)); - else - write_pixel(x1, y1, color); - - if (shade) - iterate_shade(); - } + int16_t x1 = m_rex3.m_x_start_i; + int16_t y1 = m_rex3.m_y_start_i; + int16_t x2 = m_rex3.m_x_end_i; + int16_t y2 = m_rex3.m_y_end_i; + + const bool iterate_one = (m_rex3.m_draw_mode0 & 0x300) == 0; + const bool skip_first = BIT(m_rex3.m_draw_mode0, 10); + const bool skip_last = BIT(m_rex3.m_draw_mode0, 11); + const bool shade = BIT(m_rex3.m_draw_mode0, 18); + const bool rgbmode = BIT(m_rex3.m_draw_mode1, 15); + + int16_t x = x1; + int16_t y = y1; + int16_t dx = abs(x1 - x2); + int16_t dy = abs(y1 - y2); + //const uint8_t coverage = 1; + + static const bresenham_octant_info_t s_bresenham_infos[8] = + { + { 1, 1, 0, 1, 0 }, + { 0, 1, 1, 1, 1 }, + { 0, -1, 1, 1, 1 }, + { -1, -1, 0, 1, 0 }, + { -1, -1, 0, -1, 0 }, + { 0, -1, -1, -1, 1 }, + { 0, 1, -1, -1, 1 }, + { 1, 1, 0, -1, 0 } + }; + + const uint8_t octant = get_octant(x1, y1, x2, y2, dx, dy); + const int16_t incrx1 = s_bresenham_infos[octant].incrx1; + const int16_t incrx2 = s_bresenham_infos[octant].incrx2; + const int16_t incry1 = s_bresenham_infos[octant].incry1; + const int16_t incry2 = s_bresenham_infos[octant].incry2; + int16_t loop = s_bresenham_infos[octant].loop ? dy : dx; + if (BIT(m_rex3.m_draw_mode0, 15) && loop > 32) + loop = 32; + + const int16_t incr1 = 2 * (s_bresenham_infos[octant].loop ? dx : dy); + const int16_t incr2 = 2 * (s_bresenham_infos[octant].loop ? (dx - dy) : (dy - dx)); + int16_t d = incr1 - (s_bresenham_infos[octant].loop ? dy : dx); + + if (!skip_first || iterate_one) + { + if (shade || rgbmode) + write_pixel(x, y, get_rgb_color(x, y)); + else + write_pixel(x, y, color); + + if (shade) + iterate_shade(); + + if (d < 0) + { + x += incrx1; + y -= incry1; + d += incr1; + } + else + { + x += incrx2; + y -= incry2; + d += incr2; + } + + if (iterate_one) + { + write_x_start(x << 11); + write_y_start(y << 11); + return; + } + } + + for (int16_t i = 1; i < loop; i++) + { + if (shade || rgbmode) + write_pixel(x, y, get_rgb_color(x, y)); + else + write_pixel(x, y, color); + + if (shade) + iterate_shade(); + + if (d < 0) + { + x += incrx1; + y -= incry1; + d += incr1; + } + else + { + x += incrx2; + y -= incry2; + d += incr2; + } + } + + if (!skip_last) + { + if (shade || rgbmode) + write_pixel(x2, y2, get_rgb_color(x2, y2)); + else + write_pixel(x2, y2, color); + + if (shade) + iterate_shade(); + + write_x_start(x2 << 11); + write_y_start(y2 << 11); + } + else + { + write_x_start(x << 11); + write_y_start(y << 11); } - - write_x_start(x1 << 11); - write_y_start(y1 << 11); } uint32_t newport_base_device::do_pixel_read() { - if (m_rex3.m_xy_start_i == m_rex3.m_xy_end_i) - m_rex3.m_read_active = false; m_rex3.m_bres_octant_inc1 = 0; const uint32_t ret = m_rgbci[m_rex3.m_y_start_i * (1280 + 64) + m_rex3.m_x_start_i]; LOGMASKED(LOG_COMMANDS, "Read %08x from %04x, %04x\n", ret, m_rex3.m_x_start_i, m_rex3.m_y_start_i); @@ -2106,7 +2492,6 @@ void newport_base_device::do_rex3_command() case 0x00000045: // ColorHost, Block, Read case 0x00000065: // ColorHost, Block, Read { - m_rex3.m_read_active = true; break; } case 0x00000022: // DoSetup, Span, Draw @@ -2126,8 +2511,8 @@ void newport_base_device::do_rex3_command() end_x += dx; - if (BIT(mode0, 15) && abs(end_x - start_x) >= 32) - end_x = start_x + 31 * dx; + if (BIT(mode0, 15) && abs(end_x - start_x) > 32) + end_x = start_x + 32 * dx; const bool opaque = BIT(mode0, 16) || BIT(mode0, 17); const uint32_t pattern = BIT(mode0, 12) ? m_rex3.m_z_pattern : (BIT(mode0, 13) ? m_rex3.m_ls_pattern : 0xffffffff); @@ -2156,10 +2541,8 @@ void newport_base_device::do_rex3_command() bit = (bit - 1) & 0x1f; } - start_y += dy; write_x_start(start_x << 11); - write_y_start(start_y << 11); break; } case 0x00000326: // StopOnX, StopOnY, DoSetup, Block, Draw @@ -2170,7 +2553,7 @@ void newport_base_device::do_rex3_command() uint32_t color = m_rex3.m_color_i; if (BIT(mode1, 17)) { - switch ((mode1 >> 3) & 3) + switch (m_rex3.m_plane_depth) { case 0: // 4bpp color = m_rex3.m_color_vram & 0xf; @@ -2243,28 +2626,19 @@ void newport_base_device::do_rex3_command() case 0x00000b2a: // SkipLast, StopOnX, StopOnY, DoSetup, I_Line, Draw case 0x0000232e: // EnLSPattern, StopOnX, StopOnY, DoSetup, F_Line, Draw case 0x0000930e: // Length32, EnZPattern, StopOnX, StopOnY, F_Line, Draw + case 0x0004930e: // Shade, Length32, EnZPattern, StopOnX, StopOnY, F_Line, Draw case 0x0004232e: // Shade, EnLSPattern, StopOnX, StopOnY, DoSetup, F_Line, Draw case 0x00200b2e: // CIClamp, SkipLast, StopOnX, StopOnY, DoSetup, F_Line, Draw case 0x00442332: // EndFilter, Shade, EnLSPattern, StopOnX, StopOnY, DoSetp, A_Line, Draw { - LOGMASKED(LOG_COMMANDS, "%cLine: %04x, %04x to %04x, %04x = %08x\n", (mode0 & 0x1c) == 3 ? 'F' : 'I', + LOGMASKED(LOG_COMMANDS, "%cLine: %04x, %04x to %04x, %04x = %08x\n", ((mode0 & 0x1c) >> 2) == 3 ? 'F' : 'I', start_x, start_y, end_x, end_y, m_rex3.m_color_i); if (start_x == end_x && start_y == end_y) - { write_pixel(m_rex3.m_color_i); - } - else if (start_x == end_x) - { - do_v_iline(m_rex3.m_color_i); - } - else if (start_y == end_y) - { - do_h_iline(m_rex3.m_color_i); - } + else if (((mode0 & 0x1c) >> 2) == 3) + do_fline(m_rex3.m_color_i); else - { do_iline(m_rex3.m_color_i); - } break; } case 0x00001106: // EnZPattern, StopOnX, Block, Draw @@ -2286,7 +2660,7 @@ void newport_base_device::do_rex3_command() end_x += dx; if (BIT(mode0, 15) && (end_x - start_x) >= 32) - end_x = start_x + dx * 31; + end_x = start_x + 32 * dx; uint32_t bit = 31; for (; start_x != end_x; start_x += dx) @@ -2324,6 +2698,7 @@ void newport_base_device::do_rex3_command() void newport_base_device::write_x_start(int32_t val) { m_rex3.m_x_start = val & 0x07ffff80; + m_rex3.m_x_start_frac = (val >> 7) & 0xf; m_rex3.m_x_start_i = (int16_t)(val >> 11); m_rex3.m_x_start_f = (uint32_t)val & 0x007fff80; m_rex3.m_xy_start_i = (m_rex3.m_xy_start_i & 0x0000ffff) | (m_rex3.m_x_start_i << 16); @@ -2332,6 +2707,7 @@ void newport_base_device::write_x_start(int32_t val) void newport_base_device::write_y_start(int32_t val) { m_rex3.m_y_start = val & 0x07ffff80; + m_rex3.m_y_start_frac = (val >> 7) & 0xf; m_rex3.m_y_start_i = (int16_t)(val >> 11); m_rex3.m_y_start_f = (uint32_t)val & 0x007fff80; m_rex3.m_xy_start_i = (m_rex3.m_xy_start_i & 0xffff0000) | (uint16_t)m_rex3.m_y_start_i; @@ -2340,6 +2716,7 @@ void newport_base_device::write_y_start(int32_t val) void newport_base_device::write_x_end(int32_t val) { m_rex3.m_x_end = val & 0x07ffff80; + m_rex3.m_x_end_frac = (val >> 7) & 0xf; m_rex3.m_x_end_i = (int16_t)(val >> 11); m_rex3.m_x_end_f = (uint32_t)val & 0x007fff80; m_rex3.m_xy_end_i = (m_rex3.m_xy_end_i & 0x0000ffff) | (m_rex3.m_x_end_i << 16); @@ -2348,6 +2725,7 @@ void newport_base_device::write_x_end(int32_t val) void newport_base_device::write_y_end(int32_t val) { m_rex3.m_y_end = val & 0x07ffff80; + m_rex3.m_y_end_frac = (val >> 7) & 0xf; m_rex3.m_y_end_i = (int16_t)(val >> 11); m_rex3.m_y_end_f = (uint32_t)val & 0x007fff80; m_rex3.m_xy_end_i = (m_rex3.m_xy_end_i & 0xffff0000) | (uint16_t)m_rex3.m_y_end_i; @@ -2449,7 +2827,7 @@ WRITE64_MEMBER(newport_base_device::rex3_w) LOGMASKED(LOG_REX3, " Enable Dithering: %d\n", BIT(data32, 16)); LOGMASKED(LOG_REX3, " Enable Fast Clear: %d\n", BIT(data32, 17)); LOGMASKED(LOG_REX3, " Enable Blending: %d\n", BIT(data32, 18)); - switch ((data32 & 0x00380000) >> 19) + switch ((data32 >> 19) & 7) { case 0x00: LOGMASKED(LOG_REX3, " Src Blend Factor: 0\n"); @@ -2458,22 +2836,22 @@ WRITE64_MEMBER(newport_base_device::rex3_w) LOGMASKED(LOG_REX3, " Src Blend Factor: 1\n"); break; case 0x02: - LOGMASKED(LOG_REX3, " Src Blend Factor: Normalized Dest (or COLORBACK)\n"); + LOGMASKED(LOG_REX3, " Src Blend Factor: Normalized Dest Color (or COLORBACK)\n"); break; case 0x03: - LOGMASKED(LOG_REX3, " Src Blend Factor: 1 - Normalized Dest (or COLORBACK)\n"); + LOGMASKED(LOG_REX3, " Src Blend Factor: 1 - Normalized Dest Color (or COLORBACK)\n"); break; case 0x04: - LOGMASKED(LOG_REX3, " Src Blend Factor: Normalized Src\n"); + LOGMASKED(LOG_REX3, " Src Blend Factor: Normalized Src Alpha\n"); break; case 0x05: - LOGMASKED(LOG_REX3, " Src Blend Factor: 1 - Normalized Src\n"); + LOGMASKED(LOG_REX3, " Src Blend Factor: 1 - Normalized Src Alpha\n"); break; default: - LOGMASKED(LOG_REX3 | LOG_UNKNOWN, " Unknown Src Blend Factor: %02x\n", (data32 & 0x00380000) >> 19); + LOGMASKED(LOG_REX3 | LOG_UNKNOWN, " Unknown Src Blend Factor: %02x\n", (data32 >> 19) & 7); break; } - switch ((data32 & 0x01c00000) >> 22) + switch ((data32 >> 22) & 7) { case 0x00: LOGMASKED(LOG_REX3, " Dest Blend Factor: 0\n"); @@ -2482,16 +2860,16 @@ WRITE64_MEMBER(newport_base_device::rex3_w) LOGMASKED(LOG_REX3, " Dest Blend Factor: 1\n"); break; case 0x02: - LOGMASKED(LOG_REX3, " Dest Blend Factor: Normalized Dest (or COLORBACK)\n"); + LOGMASKED(LOG_REX3, " Dest Blend Factor: Normalized Src Color\n"); break; case 0x03: - LOGMASKED(LOG_REX3, " Dest Blend Factor: 1 - Normalized Dest (or COLORBACK)\n"); + LOGMASKED(LOG_REX3, " Dest Blend Factor: 1 - Normalized Src Color\n"); break; case 0x04: - LOGMASKED(LOG_REX3, " Dest Blend Factor: Normalized Src\n"); + LOGMASKED(LOG_REX3, " Dest Blend Factor: Normalized Src Alpha\n"); break; case 0x05: - LOGMASKED(LOG_REX3, " Dest Blend Factor: 1 - Normalized Src\n"); + LOGMASKED(LOG_REX3, " Dest Blend Factor: 1 - Normalized Src Alpha\n"); break; default: LOGMASKED(LOG_REX3 | LOG_UNKNOWN, " Unknown Src Blend Factor: %02x\n", (data32 & 0x00380000) >> 19); @@ -2500,7 +2878,7 @@ WRITE64_MEMBER(newport_base_device::rex3_w) LOGMASKED(LOG_REX3, " COLORBACK Dest Blend: %d\n", BIT(data32, 25)); LOGMASKED(LOG_REX3, " Enable Pxl Prefetch: %d\n", BIT(data32, 26)); LOGMASKED(LOG_REX3, " SFACTOR Src Alpha: %d\n", BIT(data32, 27)); - switch ((data32 & 0xf0000000) >> 28) + switch ((data32 >> 28) & 15) { case 0x00: LOGMASKED(LOG_REX3, " Logical Op. Type: 0\n"); @@ -2552,6 +2930,14 @@ WRITE64_MEMBER(newport_base_device::rex3_w) break; } m_rex3.m_draw_mode1 = data32; + + static const uint32_t s_store_shift[4] = { 4, 0, 12, 0 }; + m_rex3.m_plane_enable = m_rex3.m_draw_mode1 & 7; + m_rex3.m_plane_depth = (m_rex3.m_draw_mode1 >> 3) & 3; + m_rex3.m_store_shift = BIT(m_rex3.m_draw_mode1, 5) ? s_store_shift[m_rex3.m_plane_depth] : 0; + m_rex3.m_logic_op = (m_rex3.m_draw_mode1 >> 28) & 15; + m_rex3.m_src_blend = (m_rex3.m_draw_mode1 >> 19) & 7; + m_rex3.m_dst_blend = (m_rex3.m_draw_mode1 >> 22) & 7; } if (ACCESSING_BITS_0_31) { |