mirror of
https://github.com/holub/mame
synced 2025-05-28 08:33:05 +03:00
-sun4: Added enough ROP support to turbogx to make scrolling work in the sun4_60 boot monitor. [Ryan Holtz]
This commit is contained in:
parent
d1ea76b831
commit
add2f511b8
@ -70,6 +70,8 @@ void sbus_turbogx_device::device_reset()
|
||||
m_palette_g = 0;
|
||||
m_palette_b = 0;
|
||||
m_palette_step = 0;
|
||||
|
||||
memset(&m_fbc, 0, sizeof(m_fbc));
|
||||
}
|
||||
|
||||
void sbus_turbogx_device::install_device()
|
||||
@ -163,6 +165,122 @@ WRITE32_MEMBER(sbus_turbogx_device::palette_w)
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t sbus_turbogx_device::perform_rasterop(uint8_t src, uint8_t dst)
|
||||
{
|
||||
const uint32_t rops[4] = { fbc_rasterop_rop00(), fbc_rasterop_rop01(), fbc_rasterop_rop10(), fbc_rasterop_rop11() };
|
||||
|
||||
uint8_t result = 0;
|
||||
//logerror("src:%02x dst:%02x\n", src, dst);
|
||||
for (int bit = 0; bit < 8; bit++)
|
||||
{
|
||||
const uint8_t mask = (1 << bit);
|
||||
const uint8_t f = BIT(m_fbc.m_fcolor, bit) << 1;
|
||||
const uint8_t b = BIT(m_fbc.m_bcolor, bit);
|
||||
const uint8_t s = src & mask;
|
||||
const uint8_t d = dst & mask;
|
||||
const uint32_t rop = rops[f | b];
|
||||
//logerror("f:%d b:%d s:%02x d:%02x rop:%d\n", f >> 1, b, s, d, rop);
|
||||
|
||||
uint8_t value = 0;
|
||||
switch (rop)
|
||||
{
|
||||
case ROP_CLR: break;
|
||||
case ROP_SRC_NOR_DST: value = ~(s | d); break;
|
||||
case ROP_NSRC_AND_DST: value = ~s & d; break;
|
||||
case ROP_NOT_SRC: value = ~s; break;
|
||||
case ROP_SRC_AND_NDST: value = s & ~d; break;
|
||||
case ROP_NOT_DST: value = ~d; break;
|
||||
case ROP_SRC_XOR_DST: value = s ^ d; break;
|
||||
case ROP_SRC_NAND_DST: value = ~(s & d); break;
|
||||
case ROP_SRC_AND_DST: value = s & d; break;
|
||||
case ROP_SRC_XNOR_DST: value = ~(s ^ d); break;
|
||||
case ROP_DST: value = d; break;
|
||||
case ROP_NSRC_OR_DST: value = ~s | d; break;
|
||||
case ROP_SRC: value = s; break;
|
||||
case ROP_SRC_OR_NDST: value = s | ~d; break;
|
||||
case ROP_SRC_OR_DST: value = s | d; break;
|
||||
case ROP_SET: value = 0xff; break;
|
||||
default: value = 0; break;
|
||||
}
|
||||
result |= value & mask;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: This is basically untested, and probably full of bugs!
|
||||
void sbus_turbogx_device::handle_draw_command()
|
||||
{
|
||||
if (fbc_misc_draw() != FBC_MISC_DRAW_RENDER)
|
||||
{
|
||||
logerror("handle_draw_command: Unsupported draw mode %d, abandoning draw\n", fbc_misc_draw());
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_fbc.m_curr_prim_type != PRIM_RECT)
|
||||
{
|
||||
logerror("handle_draw_command: Unsupported prim type %d, abandoning draw\n", m_fbc.m_curr_prim_type);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_fbc.m_vertex_count < 2)
|
||||
{
|
||||
logerror("handle_draw_command: Insufficient number of vertices queued, abandoning draw\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t *vram = (uint8_t*)&m_vram[0];
|
||||
|
||||
uint32_t vindex = 0;
|
||||
while (vindex < m_fbc.m_vertex_count)
|
||||
{
|
||||
vertex_t &v0 = m_fbc.m_prim_buf[vindex++];
|
||||
vertex_t &v1 = m_fbc.m_prim_buf[vindex++];
|
||||
|
||||
for (uint32_t y = v0.m_absy; y < v1.m_absy; y++)
|
||||
{
|
||||
const uint32_t line = y * (m_fbc.m_clip_maxx + 1);
|
||||
for (uint32_t x = v0.m_absx; x < v1.m_absx; x++)
|
||||
{
|
||||
const uint8_t src = vram[line + x];
|
||||
const uint8_t dst = src;
|
||||
const uint8_t result = perform_rasterop(src, dst);
|
||||
vram[line + x] = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_fbc.m_vertex_count = 0;
|
||||
}
|
||||
|
||||
// NOTE: This is basically untested, and probably full of bugs!
|
||||
void sbus_turbogx_device::handle_blit_command()
|
||||
{
|
||||
uint8_t *vram = (uint8_t*)&m_vram[0];
|
||||
const uint32_t fbw = (m_fbc.m_clip_maxx + 1);
|
||||
logerror("Copying from %d,%d-%d,%d to %d,%d-%d,%d, width %d, height %d\n"
|
||||
, m_fbc.m_x0, m_fbc.m_y0
|
||||
, m_fbc.m_x1, m_fbc.m_y1
|
||||
, m_fbc.m_x2, m_fbc.m_y2
|
||||
, m_fbc.m_x3, m_fbc.m_y3
|
||||
, m_fbc.m_clip_maxx, m_fbc.m_clip_maxy);
|
||||
uint32_t srcy = m_fbc.m_y0;
|
||||
uint32_t dsty = m_fbc.m_y2;
|
||||
for (; srcy < m_fbc.m_y1; srcy++, dsty++)
|
||||
{
|
||||
uint32_t srcy_index = srcy * fbw;
|
||||
uint32_t dsty_index = dsty * fbw;
|
||||
uint32_t srcx = m_fbc.m_x0;
|
||||
uint32_t dstx = m_fbc.m_x2;
|
||||
for (; srcx < m_fbc.m_x1; srcx++, dstx++)
|
||||
{
|
||||
const uint8_t src = vram[srcy_index + srcx];
|
||||
const uint8_t dst = vram[dsty_index + dstx];
|
||||
const uint8_t result = perform_rasterop(src, dst);
|
||||
//logerror("vram[%d] = %02x\n", result);
|
||||
vram[dsty_index + dstx] = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
READ32_MEMBER(sbus_turbogx_device::fbc_r)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
@ -180,9 +298,11 @@ READ32_MEMBER(sbus_turbogx_device::fbc_r)
|
||||
return m_fbc.m_status;
|
||||
case FBC_DRAW_STATUS:
|
||||
logerror("fbc_r: DRAW_STATUS (%08x & %08x)\n", m_fbc.m_draw_status, mem_mask);
|
||||
handle_draw_command();
|
||||
return m_fbc.m_draw_status;
|
||||
case FBC_BLIT_STATUS:
|
||||
logerror("fbc_r: BLIT_STATUS (%08x & %08x)\n", m_fbc.m_blit_status, mem_mask);
|
||||
handle_blit_command();
|
||||
return m_fbc.m_blit_status;
|
||||
case FBC_FONT:
|
||||
logerror("fbc_r: FONT (%08x & %08x)\n", m_fbc.m_font, mem_mask);
|
||||
@ -470,20 +590,40 @@ READ32_MEMBER(sbus_turbogx_device::fbc_r)
|
||||
|
||||
WRITE32_MEMBER(sbus_turbogx_device::fbc_w)
|
||||
{
|
||||
static const char* misc_bdisp_name[4] = { "IGNORE", "0", "1", "ILLEGAL" };
|
||||
static const char* misc_bread_name[4] = { "IGNORE", "0", "1", "ILLEGAL" };
|
||||
static const char* misc_bwrite1_name[4] = { "IGNORE", "ENABLE", "DISABLE", "ILLEGAL" };
|
||||
static const char* misc_bwrite0_name[4] = { "IGNORE", "ENABLE", "DISABLE", "ILLEGAL" };
|
||||
static const char* misc_draw_name[4] = { "IGNORE", "RENDER", "PICK", "ILLEGAL" };
|
||||
static const char* misc_data_name[4] = { "IGNORE", "COLOR8", "COLOR1", "HRMONO" };
|
||||
static const char* misc_blit_name[4] = { "IGNORE", "NOSRC", "SRC", "ILLEGAL" };
|
||||
static const char* rasterop_rop_name[16] =
|
||||
{
|
||||
"CLR", "SRC_NOR_DST", "NSRC_AND_DST", "NOT_SRC", "SRC_AND_NDST", "NOT_DST", "SRC_XOR_DST", "SRC_NAND_DST",
|
||||
"SRC_AND_DST", "SRC_XNOR_DST", "DST", "NSRC_OR_DST", "SRC", "SRC_OR_NDST", "SRC_OR_DST", "SET"
|
||||
};
|
||||
static const char* rasterop_plot_name[2] = { "PLOT", "UNPLOT" };
|
||||
static const char* rasterop_rast_name[2] = { "BOOL", "LINEAR" };
|
||||
static const char* rasterop_attr_name[4] = { "IGNORE", "UNSUPP", "SUPP", "ILLEGAL" };
|
||||
static const char* rasterop_polyg_name[4] = { "IGNORE", "OVERLAP", "NONOVERLAP", "ILLEGAL" };
|
||||
static const char* rasterop_pattern_name[4] = { "IGNORE", "ZEROES", "ONES", "MASK" };
|
||||
static const char* rasterop_pixel_name[4] = { "IGNORE", "ZEROES", "ONES", "MASK" };
|
||||
static const char* rasterop_plane_name[4] = { "IGNORE", "ZEROES", "ONES", "MASK" };
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case FBC_MISC:
|
||||
COMBINE_DATA(&m_fbc.m_misc);
|
||||
logerror("fbc_w: MISC = %08x & %08x\n", data, mem_mask);
|
||||
logerror(" MISC_INDEX = %d\n", fbc_misc_index());
|
||||
logerror(" MISC_INDEX_MOD = %d\n", fbc_misc_index_mod());
|
||||
logerror(" MISC_BDISP = %d\n", fbc_misc_bdisp());
|
||||
logerror(" MISC_BREAD = %d\n", fbc_misc_bread());
|
||||
logerror(" MISC_BWRITE1 = %d\n", fbc_misc_bwrite1());
|
||||
logerror(" MISC_BWRITE0 = %d\n", fbc_misc_bwrite0());
|
||||
logerror(" MISC_DRAW = %d\n", fbc_misc_draw());
|
||||
logerror(" MISC_DATA = %d\n", fbc_misc_data());
|
||||
logerror(" MISC_BLIT = %d\n", fbc_misc_blit());
|
||||
COMBINE_DATA(&m_fbc.m_misc);
|
||||
logerror(" MISC_BDISP = %d (%s)\n", fbc_misc_bdisp(), misc_bdisp_name[fbc_misc_bdisp()]);
|
||||
logerror(" MISC_BREAD = %d (%s)\n", fbc_misc_bread(), misc_bread_name[fbc_misc_bread()]);
|
||||
logerror(" MISC_BWRITE1 = %d (%s)\n", fbc_misc_bwrite1(), misc_bwrite1_name[fbc_misc_bwrite1()]);
|
||||
logerror(" MISC_BWRITE0 = %d (%s)\n", fbc_misc_bwrite0(), misc_bwrite0_name[fbc_misc_bwrite0()]);
|
||||
logerror(" MISC_DRAW = %d (%s)\n", fbc_misc_draw(), misc_draw_name[fbc_misc_draw()]);
|
||||
logerror(" MISC_DATA = %d (%s)\n", fbc_misc_data(), misc_data_name[fbc_misc_data()]);
|
||||
logerror(" MISC_BLIT = %d (%s)\n", fbc_misc_blit(), misc_blit_name[fbc_misc_blit()]);
|
||||
break;
|
||||
case FBC_CLIP_CHECK:
|
||||
logerror("fbc_w: CLIP_CHECK = %08x & %08x\n", data, mem_mask);
|
||||
@ -614,18 +754,19 @@ WRITE32_MEMBER(sbus_turbogx_device::fbc_w)
|
||||
COMBINE_DATA(&m_fbc.m_bcolor);
|
||||
break;
|
||||
case FBC_RASTEROP:
|
||||
logerror("fbc_w: RASTEROP = %08x & %08x\n", data, mem_mask);
|
||||
logerror(" RASTEROP_ROP00 = %d\n", fbc_rasterop_rop00());
|
||||
logerror(" RASTEROP_ROP01 = %d\n", fbc_rasterop_rop01());
|
||||
logerror(" RASTEROP_ROP10 = %d\n", fbc_rasterop_rop10());
|
||||
logerror(" RASTEROP_ROP11 = %d\n", fbc_rasterop_rop11());
|
||||
logerror(" RASTEROP_PLOT = %d\n", fbc_rasterop_plot());
|
||||
logerror(" RASTEROP_RAST = %d\n", fbc_rasterop_rast());
|
||||
logerror(" RASTEROP_POLYG = %d\n", fbc_rasterop_polyg());
|
||||
logerror(" RASTEROP_PATT = %d\n", fbc_rasterop_patt());
|
||||
logerror(" RASTEROP_PIXEL = %d\n", fbc_rasterop_pixel());
|
||||
logerror(" RASTEROP_PLANE = %d\n", fbc_rasterop_plane());
|
||||
COMBINE_DATA(&m_fbc.m_rasterop);
|
||||
logerror("fbc_w: RASTEROP = %08x & %08x\n", data, mem_mask);
|
||||
logerror(" RASTEROP_ROP00 = %d (%s)\n", fbc_rasterop_rop00(), rasterop_rop_name[fbc_rasterop_rop00()]);
|
||||
logerror(" RASTEROP_ROP01 = %d (%s)\n", fbc_rasterop_rop01(), rasterop_rop_name[fbc_rasterop_rop01()]);
|
||||
logerror(" RASTEROP_ROP10 = %d (%s)\n", fbc_rasterop_rop10(), rasterop_rop_name[fbc_rasterop_rop10()]);
|
||||
logerror(" RASTEROP_ROP11 = %d (%s)\n", fbc_rasterop_rop11(), rasterop_rop_name[fbc_rasterop_rop11()]);
|
||||
logerror(" RASTEROP_PLOT = %d (%s)\n", fbc_rasterop_plot(), rasterop_plot_name[fbc_rasterop_plot()]);
|
||||
logerror(" RASTEROP_RAST = %d (%s)\n", fbc_rasterop_rast(), rasterop_rast_name[fbc_rasterop_rast()]);
|
||||
logerror(" RASTEROP_ATTR = %d (%s)\n", fbc_rasterop_attr(), rasterop_attr_name[fbc_rasterop_attr()]);
|
||||
logerror(" RASTEROP_POLYG = %d (%s)\n", fbc_rasterop_polyg(), rasterop_polyg_name[fbc_rasterop_polyg()]);
|
||||
logerror(" RASTEROP_PATT = %d (%s)\n", fbc_rasterop_pattern(), rasterop_pattern_name[fbc_rasterop_pattern()]);
|
||||
logerror(" RASTEROP_PIXEL = %d (%s)\n", fbc_rasterop_pixel(), rasterop_pixel_name[fbc_rasterop_pixel()]);
|
||||
logerror(" RASTEROP_PLANE = %d (%s)\n", fbc_rasterop_plane(), rasterop_plane_name[fbc_rasterop_plane()]);
|
||||
break;
|
||||
case FBC_PLANE_MASK:
|
||||
logerror("fbc_w: PLANE_MASK = %08x & %08x\n", data, mem_mask);
|
||||
@ -839,43 +980,45 @@ WRITE32_MEMBER(sbus_turbogx_device::fbc_w)
|
||||
|
||||
case FBC_IRECT_ABSX:
|
||||
logerror("fbc_w: IRECT_ABSX = %08x & %08x\n", data, mem_mask);
|
||||
COMBINE_DATA(&m_fbc.m_irect_absx);
|
||||
m_fbc.m_prim_buf[m_fbc.m_vertex_count].m_absx = data;
|
||||
m_fbc.m_vertex_count++;
|
||||
m_fbc.m_curr_prim_type = PRIM_RECT;
|
||||
break;
|
||||
case FBC_IRECT_ABSY:
|
||||
logerror("fbc_w: IRECT_ABSY = %08x & %08x\n", data, mem_mask);
|
||||
COMBINE_DATA(&m_fbc.m_irect_absy);
|
||||
m_fbc.m_prim_buf[m_fbc.m_vertex_count].m_absy = data;
|
||||
break;
|
||||
case FBC_IRECT_ABSZ:
|
||||
logerror("fbc_w: IRECT_ABSZ = %08x & %08x\n", data, mem_mask);
|
||||
COMBINE_DATA(&m_fbc.m_irect_absz);
|
||||
m_fbc.m_prim_buf[m_fbc.m_vertex_count].m_absz = data;
|
||||
break;
|
||||
case FBC_IRECT_RELX:
|
||||
logerror("fbc_w: IRECT_RELX = %08x & %08x\n", data, mem_mask);
|
||||
COMBINE_DATA(&m_fbc.m_irect_relx);
|
||||
m_fbc.m_prim_buf[m_fbc.m_vertex_count].m_relx = data;
|
||||
break;
|
||||
case FBC_IRECT_RELY:
|
||||
logerror("fbc_w: IRECT_RELY = %08x & %08x\n", data, mem_mask);
|
||||
COMBINE_DATA(&m_fbc.m_irect_rely);
|
||||
m_fbc.m_prim_buf[m_fbc.m_vertex_count].m_rely = data;
|
||||
break;
|
||||
case FBC_IRECT_RELZ:
|
||||
logerror("fbc_w: IRECT_RELZ = %08x & %08x\n", data, mem_mask);
|
||||
COMBINE_DATA(&m_fbc.m_irect_relz);
|
||||
m_fbc.m_prim_buf[m_fbc.m_vertex_count].m_relz = data;
|
||||
break;
|
||||
case FBC_IRECT_R:
|
||||
logerror("fbc_w: IRECT_R = %08x & %08x\n", data, mem_mask);
|
||||
COMBINE_DATA(&m_fbc.m_irect_r);
|
||||
m_fbc.m_prim_buf[m_fbc.m_vertex_count].m_r = data;
|
||||
break;
|
||||
case FBC_IRECT_G:
|
||||
logerror("fbc_w: IRECT_G = %08x & %08x\n", data, mem_mask);
|
||||
COMBINE_DATA(&m_fbc.m_irect_g);
|
||||
m_fbc.m_prim_buf[m_fbc.m_vertex_count].m_g = data;
|
||||
break;
|
||||
case FBC_IRECT_B:
|
||||
logerror("fbc_w: IRECT_B = %08x & %08x\n", data, mem_mask);
|
||||
COMBINE_DATA(&m_fbc.m_irect_b);
|
||||
m_fbc.m_prim_buf[m_fbc.m_vertex_count].m_b = data;
|
||||
break;
|
||||
case FBC_IRECT_A:
|
||||
logerror("fbc_w: IRECT_A = %08x & %08x\n", data, mem_mask);
|
||||
COMBINE_DATA(&m_fbc.m_irect_a);
|
||||
m_fbc.m_prim_buf[m_fbc.m_vertex_count].m_a = data;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -43,6 +43,9 @@ protected:
|
||||
|
||||
private:
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
uint8_t perform_rasterop(uint8_t src, uint8_t dst);
|
||||
void handle_blit_command();
|
||||
void handle_draw_command();
|
||||
|
||||
void mem_map(address_map &map) override;
|
||||
|
||||
@ -214,7 +217,7 @@ private:
|
||||
inline uint32_t fbc_rasterop_rast() { return (m_fbc.m_rasterop >> FBC_RASTEROP_RAST_SHIFT) & FBC_RASTEROP_RAST_MASK; }
|
||||
inline uint32_t fbc_rasterop_attr() { return (m_fbc.m_rasterop >> FBC_RASTEROP_ATTR_SHIFT) & FBC_RASTEROP_ATTR_MASK; }
|
||||
inline uint32_t fbc_rasterop_polyg() { return (m_fbc.m_rasterop >> FBC_RASTEROP_POLYG_SHIFT) & FBC_RASTEROP_POLYG_MASK; }
|
||||
inline uint32_t fbc_rasterop_patt() { return (m_fbc.m_rasterop >> FBC_RASTEROP_PATT_SHIFT) & FBC_RASTEROP_PATT_MASK; }
|
||||
inline uint32_t fbc_rasterop_pattern() { return (m_fbc.m_rasterop >> FBC_RASTEROP_PATT_SHIFT) & FBC_RASTEROP_PATT_MASK; }
|
||||
inline uint32_t fbc_rasterop_pixel() { return (m_fbc.m_rasterop >> FBC_RASTEROP_PIXEL_SHIFT) & FBC_RASTEROP_PIXEL_MASK; }
|
||||
inline uint32_t fbc_rasterop_plane() { return (m_fbc.m_rasterop >> FBC_RASTEROP_PLANE_SHIFT) & FBC_RASTEROP_PLANE_MASK; }
|
||||
|
||||
@ -326,6 +329,31 @@ private:
|
||||
FBC_IRECT_A = 0x93c/4,
|
||||
};
|
||||
|
||||
struct vertex_t
|
||||
{
|
||||
uint32_t m_absx;
|
||||
uint32_t m_absy;
|
||||
uint32_t m_absz;
|
||||
uint32_t m_relx;
|
||||
uint32_t m_rely;
|
||||
uint32_t m_relz;
|
||||
uint32_t m_r;
|
||||
uint32_t m_g;
|
||||
uint32_t m_b;
|
||||
uint32_t m_a;
|
||||
};
|
||||
|
||||
enum prim_type
|
||||
{
|
||||
PRIM_POINT = 0,
|
||||
PRIM_LINE,
|
||||
PRIM_TRI,
|
||||
PRIM_QUAD,
|
||||
PRIM_RECT,
|
||||
|
||||
PRIM_COUNT
|
||||
};
|
||||
|
||||
struct fbc_t
|
||||
{
|
||||
uint32_t m_misc;
|
||||
@ -429,6 +457,10 @@ private:
|
||||
uint32_t m_irect_g;
|
||||
uint32_t m_irect_b;
|
||||
uint32_t m_irect_a;
|
||||
|
||||
vertex_t m_prim_buf[0x1000]; // unknown size
|
||||
uint32_t m_vertex_count;
|
||||
prim_type m_curr_prim_type;
|
||||
};
|
||||
|
||||
required_memory_region m_rom;
|
||||
@ -441,6 +473,7 @@ private:
|
||||
uint8_t m_palette_g;
|
||||
uint8_t m_palette_b;
|
||||
uint8_t m_palette_step;
|
||||
|
||||
fbc_t m_fbc;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user