diff options
Diffstat (limited to 'src/devices/bus/gio64/newport.cpp')
-rw-r--r-- | src/devices/bus/gio64/newport.cpp | 194 |
1 files changed, 114 insertions, 80 deletions
diff --git a/src/devices/bus/gio64/newport.cpp b/src/devices/bus/gio64/newport.cpp index e017708a2c2..9a644c89c6c 100644 --- a/src/devices/bus/gio64/newport.cpp +++ b/src/devices/bus/gio64/newport.cpp @@ -37,14 +37,14 @@ #include "emu.h" #include "newport.h" -#define LOG_UNKNOWN (1 << 0) -#define LOG_VC2 (1 << 1) -#define LOG_CMAP (1 << 2) -#define LOG_XMAP (1 << 4) -#define LOG_REX3 (1 << 6) -#define LOG_RAMDAC (1 << 7) -#define LOG_COMMANDS (1 << 8) -#define LOG_REJECTS (1 << 9) +#define LOG_UNKNOWN (1U << 1) +#define LOG_VC2 (1U << 2) +#define LOG_CMAP (1U << 3) +#define LOG_XMAP (1U << 4) +#define LOG_REX3 (1U << 5) +#define LOG_RAMDAC (1U << 6) +#define LOG_COMMANDS (1U << 7) +#define LOG_REJECTS (1U << 8) #define LOG_ALL (LOG_UNKNOWN | LOG_VC2 | LOG_CMAP | LOG_XMAP | LOG_REX3 | LOG_RAMDAC | LOG_COMMANDS | LOG_REJECTS) #define VERBOSE (0) @@ -306,9 +306,6 @@ vc2_device::vc2_device(const machine_config &mconfig, const char *tag, device_t void vc2_device::device_start() { - m_vert_int.resolve_safe(); - m_screen_timing_changed.resolve_safe(); - m_ram = std::make_unique<uint16_t[]>(RAM_SIZE); m_vt_table = make_unique_clear<uint32_t[]>(2048 * 2048); @@ -816,7 +813,7 @@ uint8_t vc2_device::get_cursor_pixel(int x, int y) } } -WRITE_LINE_MEMBER(vc2_device::vblank_w) +void vc2_device::vblank_w(int state) { if (state) { @@ -913,7 +910,8 @@ void rb2_device::deserialize(FILE *file) uint32_t rb2_device::expand_to_all_lanes(uint32_t src) { - switch (m_draw_depth) { + switch (m_draw_depth) + { case 0: src |= src << 4; src |= src << 8; @@ -1091,7 +1089,7 @@ newport_base_device::newport_base_device(const machine_config &mconfig, device_t , m_draw_flags_w(*this) , m_set_address(*this) , m_write_pixel(*this) - , m_read_pixel(*this) + , m_read_pixel(*this, 0) { } @@ -1111,7 +1109,7 @@ gio64_xl24_device::gio64_xl24_device(const machine_config &mconfig, const char * void newport_base_device::device_start() { - m_dcb_timeout_timer = timer_alloc(DCB_TIMEOUT); + m_dcb_timeout_timer = timer_alloc(FUNC(newport_base_device::dcb_timeout_tick), this); save_item(NAME(m_rex3.m_draw_mode0)); save_item(NAME(m_rex3.m_color_host)); @@ -1202,12 +1200,6 @@ void newport_base_device::device_start() save_item(NAME(m_ramdac_lut_g)); save_item(NAME(m_ramdac_lut_b)); save_item(NAME(m_ramdac_lut_index)); - - m_write_mask_w.resolve_safe(); - m_draw_flags_w.resolve_safe(); - m_set_address.resolve_safe(); - m_write_pixel.resolve_safe(); - m_read_pixel.resolve_safe(0); } //------------------------------------------------- @@ -1282,12 +1274,9 @@ void newport_base_device::stop_logging() } #endif -void newport_base_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +TIMER_CALLBACK_MEMBER(newport_base_device::dcb_timeout_tick) { - if (id == DCB_TIMEOUT) - { - m_rex3.m_status &= ~STATUS_BACKBUSY; - } + m_rex3.m_status &= ~STATUS_BACKBUSY; } uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect) @@ -1708,7 +1697,7 @@ void newport_base_device::ramdac_write(uint32_t data) } } -WRITE_LINE_MEMBER(newport_base_device::vrint_w) +void newport_base_device::vrint_w(int state) { if (state) { @@ -1718,7 +1707,7 @@ WRITE_LINE_MEMBER(newport_base_device::vrint_w) } // TOOD: Figure out a better way of doing this -WRITE_LINE_MEMBER(newport_base_device::update_screen_size) +void newport_base_device::update_screen_size(int state) { const int x_start = m_vc2->readout_x0(); const int y_start = m_vc2->readout_y0(); @@ -2703,28 +2692,58 @@ uint32_t newport_base_device::get_rgb_color(int16_t x, int16_t y) uint8_t newport_base_device::get_octant(int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t dx, int32_t dy) { - 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; - } + uint8_t octant = 0; + + // Octant format: {MSB, 2nd, LSB} = {XMAJOR, XDEC, YDEC} + // Mapping of hardware octant to peseudocode octant in manual + // | Pseudocode | hardware | hardware(dec) | + // | 1 | 3'b101 | 5 | + // | 2 | 3'b001 | 1 | + // | 3 | 3'b011 | 3 | + // | 4 | 3'b111 | 7 | + // | 5 | 3'b110 | 6 | + // | 6 | 3'b010 | 2 | + // | 7 | 3'b000 | 0 | + // | 8 | 3'b100 | 4 | + + /* YDEC */ + if (y1 > y2) + octant |= (1 << 0); // Bit 0 + + /* XDEC */ + if (x1 > x2) + octant |= (1 << 1); // Bit 1 + + /* XMAJOR */ + if (dx > dy) + octant |= (1 << 2); // Bit 2 + + return octant; +} + +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); + + /* octant for line and block, span */ + const uint8_t octant = get_octant(x1, y1, x2, y2, dx, dy); + m_rex3.m_bres_octant_inc1 &= ~(0x7 << 24); + m_rex3.m_bres_octant_inc1 |= (uint32_t)octant << 24; + /* FIXME: error terms (incr1, incr2) and Bresenham terms (d) */ + LOGMASKED(LOG_REX3, "do_setup: octant = %d, x1 = %d, y1 = %d, x2 = %d, y2 = %d, dx = %d, dy = %d\n", octant, x1, y1, x2, y2, dx, dy); } void newport_base_device::do_fline(uint32_t color) { - const int32_t x1 = (int32_t)((m_rex3.m_x_start >> 7) << 12) >> 12; - const int32_t y1 = (int32_t)((m_rex3.m_y_start >> 7) << 12) >> 12; - const int32_t x2 = (int32_t)((m_rex3.m_x_end >> 7) << 12) >> 12; - const int32_t y2 = (int32_t)((m_rex3.m_y_end >> 7) << 12) >> 12; + 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 x10 = x1 & ~0xf; const int32_t y10 = y1 & ~0xf; @@ -2751,17 +2770,17 @@ void newport_base_device::do_fline(uint32_t color) 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 } + { 0, 1, -1, -1, 1 }, // Pseudo 7 + { 0, 1, 1, 1, 1 }, // Pseudo 2 + { 0, -1, -1, -1, 1 }, // Pseudo 6 + { 0, -1, 1, 1, 1 }, // Pseudo 3 + { 1, 1, 0, -1, 0 }, // Pseudo 8 + { 1, 1, 0, 1, 0 }, // Pseudo 1 + { -1, -1, 0, -1, 0 }, // Pseudo 5 + { -1, -1, 0, 1, 0 } // Pseudo 4 }; - 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; @@ -2777,10 +2796,10 @@ void newport_base_device::do_fline(uint32_t color) switch (octant) { - case 0: + case 5: // Pseudo 1 // Nothing special needed break; - case 1: + case 1: // Pseudo 2 { const int16_t temp_fract = x1_fract; x1_fract = y1_fract; @@ -2790,7 +2809,7 @@ void newport_base_device::do_fline(uint32_t color) dy = temp_d; break; } - case 2: + case 3: // Pseudo 3 { const int16_t temp_fract = 0x10 - x1_fract; x1_fract = y1_fract; @@ -2800,14 +2819,14 @@ void newport_base_device::do_fline(uint32_t color) dy = temp_d; break; } - case 3: + case 7: // Pseudo 4 x1_fract = 0x10 - x1_fract; break; - case 4: + case 6: // Pseudo 5 x1_fract = 0x10 - x1_fract; y1_fract = 0x10 - y1_fract; break; - case 5: + case 2: // Pseudo 6 { const int16_t temp_fract = 0x10 - x1_fract; x1_fract = 0x10 - y1_fract; @@ -2817,7 +2836,7 @@ void newport_base_device::do_fline(uint32_t color) dy = temp_d; break; } - case 6: + case 0: // Pseudo 7 { const int16_t temp_fract = 0x10 - y1_fract; y1_fract = x1_fract; @@ -2827,7 +2846,7 @@ void newport_base_device::do_fline(uint32_t color) dy = temp_d; break; } - case 7: + case 4: // Pseudo 8 y1_fract = 0x10 - y1_fract; break; } @@ -2942,17 +2961,17 @@ void newport_base_device::do_iline(uint32_t color) 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 } + { 0, 1, -1, -1, 1 }, // Pseudo 7 + { 0, 1, 1, 1, 1 }, // Pseudo 2 + { 0, -1, -1, -1, 1 }, // Pseudo 6 + { 0, -1, 1, 1, 1 }, // Pseudo 3 + { 1, 1, 0, -1, 0 }, // Pseudo 8 + { 1, 1, 0, 1, 0 }, // Pseudo 1 + { -1, -1, 0, -1, 0 }, // Pseudo 5 + { -1, -1, 0, 1, 0 } // Pseudo 4 }; - 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; @@ -3051,7 +3070,6 @@ void newport_base_device::do_iline(uint32_t color) uint32_t newport_base_device::do_pixel_read() { - m_rex3.m_bres_octant_inc1 = 0; const int16_t src_x = m_rex3.m_x_start_i + m_rex3.m_x_window - 0x1000; const int16_t src_y = m_rex3.m_y_start_i + m_rex3.m_y_window - 0x1000; uint32_t ret = 0; @@ -3194,13 +3212,13 @@ uint64_t newport_base_device::do_pixel_word_read() void newport_base_device::iterate_shade() { if (m_rex3.m_slope_red & 0x7fffff) - m_rex3.m_curr_color_red += (m_rex3.m_slope_red << 8) >> 8; + m_rex3.m_curr_color_red += util::sext(m_rex3.m_slope_red, 24); if (m_rex3.m_slope_green & 0x7ffff) - m_rex3.m_curr_color_green += (m_rex3.m_slope_green << 12) >> 12; + m_rex3.m_curr_color_green += util::sext(m_rex3.m_slope_green, 20); if (m_rex3.m_slope_blue & 0x7ffff) - m_rex3.m_curr_color_blue += (m_rex3.m_slope_blue << 12) >> 12; + m_rex3.m_curr_color_blue += util::sext(m_rex3.m_slope_blue, 20); if (m_rex3.m_slope_alpha & 0x7ffff) - m_rex3.m_curr_color_alpha += (m_rex3.m_slope_alpha << 12) >> 12; + m_rex3.m_curr_color_alpha += util::sext(m_rex3.m_slope_alpha, 20); if (BIT(m_rex3.m_draw_mode0, 21)) // CIClamp { @@ -3300,10 +3318,10 @@ 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; + int8_t octant; - LOGMASKED(LOG_COMMANDS, "REX3 Command: %08x|%08x - %s %s\n", mode0, mode1, s_opcode_str[mode0 & 3], s_adrmode_str[(mode0 >> 2) & 7]); + LOGMASKED(LOG_COMMANDS, "REX3 Command: %08x|%08x - %s %s %s\n", mode0, mode1, s_opcode_str[mode0 & 3], s_adrmode_str[(mode0 >> 2) & 7], BIT(mode0, 5) ? "Setup" : "NoSetup"); const uint8_t opcode = mode0 & 3; const uint8_t adrmode = (mode0 >> 2) & 7; @@ -3313,9 +3331,18 @@ void newport_base_device::do_rex3_command() case 0: // NoOp break; case 1: // Read + if (BIT(mode0, 5)) + do_setup(); + // Our do_pixel_word_read does not use octant, but seems like hardware is still updating it m_rex3.m_host_dataport = do_pixel_word_read(); break; case 2: // Draw + if (BIT(mode0, 5)) + do_setup(); + octant = (m_rex3.m_bres_octant_inc1 >> 24) & 0x7; + dx = BIT(octant, 1) ? -1 : 1; + dy = BIT(octant, 0) ? -1 : 1; + switch (adrmode) { case 0: // Span @@ -3486,6 +3513,12 @@ void newport_base_device::do_rex3_command() const bool stop_on_x = BIT(mode0, 8); const bool stop_on_y = BIT(mode0, 9); + if (BIT(mode0, 5)) + do_setup(); + octant = (m_rex3.m_bres_octant_inc1 >> 24) & 0x7; + dx = BIT(octant, 1) ? -1 : 1; + dy = BIT(octant, 0) ? -1 : 1; + end_x += dx; end_y += dy; @@ -3901,6 +3934,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) { |