mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
video/pc_vga_matrox.cpp: preliminary HW cursor, add a debug VRAM viewer
This commit is contained in:
parent
2fe44733e5
commit
5d4b71f4b6
@ -4,6 +4,8 @@
|
||||
#include "emu.h"
|
||||
#include "pc_vga_matrox.h"
|
||||
|
||||
#define DEBUG_VRAM_VIEWER 0
|
||||
|
||||
DEFINE_DEVICE_TYPE(MATROX_VGA, matrox_vga_device, "matrox_vga", "Matrox MGA2064W VGA")
|
||||
|
||||
matrox_vga_device::matrox_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
@ -32,7 +34,10 @@ void matrox_vga_device::device_start()
|
||||
save_item(NAME(m_cursor_read_index));
|
||||
save_item(NAME(m_cursor_write_index));
|
||||
save_item(NAME(m_cursor_index_state));
|
||||
save_item(NAME(m_cursor_ccr));
|
||||
save_item(NAME(m_cursor_dcc));
|
||||
save_pointer(NAME(m_cursor_color), 12);
|
||||
save_pointer(NAME(m_cursor_ram), 0x400);
|
||||
}
|
||||
|
||||
void matrox_vga_device::device_reset()
|
||||
@ -48,6 +53,10 @@ void matrox_vga_device::device_reset()
|
||||
m_interlace_mode = false;
|
||||
|
||||
m_cursor_read_index = m_cursor_write_index = m_cursor_index_state = 0;
|
||||
m_cursor_ccr = 0;
|
||||
m_cursor_x = 0;
|
||||
m_cursor_y = 0;
|
||||
|
||||
m_truecolor_ctrl = 0x80;
|
||||
m_multiplex_ctrl = 0x98;
|
||||
}
|
||||
@ -224,10 +233,55 @@ void matrox_vga_device::ramdac_ext_map(address_map &map)
|
||||
map(0x04, 0x04).rw(FUNC(matrox_vga_device::cursor_write_index_r), FUNC(matrox_vga_device::cursor_write_index_w));
|
||||
map(0x05, 0x05).rw(FUNC(matrox_vga_device::cursor_data_r), FUNC(matrox_vga_device::cursor_data_w));
|
||||
map(0x07, 0x07).rw(FUNC(matrox_vga_device::cursor_read_index_r), FUNC(matrox_vga_device::cursor_read_index_w));
|
||||
// map(0x09, 0x09) Direct Cursor control
|
||||
// DDC Direct Cursor control
|
||||
map(0x09, 0x09).lrw8(
|
||||
NAME([this] (offs_t offset) {
|
||||
return m_cursor_dcc & 3;
|
||||
}),
|
||||
NAME([this] (offs_t offset, u8 data) {
|
||||
// compatible alias to setup cursor mode
|
||||
m_cursor_dcc = (data & 3);
|
||||
})
|
||||
);
|
||||
map(0x0a, 0x0a).rw(FUNC(matrox_vga_device::ramdac_ext_indexed_r), FUNC(matrox_vga_device::ramdac_ext_indexed_w));
|
||||
// map(0x0b, 0x0b) Cursor RAM data
|
||||
// map(0x0c, 0x0f) Cursor X/Y positions
|
||||
map(0x0b, 0x0b).lrw8(
|
||||
NAME([this] (offs_t offset) {
|
||||
u16 cursor_address = vga.dac.read_index | ((m_cursor_ccr & 0xc) >> 2) << 8;
|
||||
u8 res = m_cursor_ram[cursor_address++];
|
||||
cursor_address &= 0x3ff;
|
||||
vga.dac.read_index = cursor_address & 0xff;
|
||||
m_cursor_ccr = (((cursor_address & 0x300) >> 8) << 2) | (m_cursor_ccr & 0xf3);
|
||||
return res;
|
||||
}),
|
||||
NAME([this] (offs_t offset, u8 data) {
|
||||
u16 cursor_address = vga.dac.write_index | ((m_cursor_ccr & 0xc) >> 2) << 8;
|
||||
m_cursor_ram[cursor_address++] = data;
|
||||
cursor_address &= 0x3ff;
|
||||
vga.dac.write_index = cursor_address & 0xff;
|
||||
m_cursor_ccr = (((cursor_address & 0x300) >> 8) << 2) | (m_cursor_ccr & 0xf3);
|
||||
})
|
||||
);
|
||||
map(0x0c, 0x0d).lrw8(
|
||||
NAME([this] (offs_t offset) {
|
||||
return m_cursor_x >> (offset * 8);
|
||||
}),
|
||||
NAME([this] (offs_t offset, u8 data) {
|
||||
const u8 shift_mask = 0xff00 >> (offset * 8);
|
||||
m_cursor_x = (data << (offset * 8)) | (m_cursor_x & shift_mask);
|
||||
m_cursor_x &= 0xfff;
|
||||
})
|
||||
);
|
||||
map(0x0e, 0x0f).lrw8(
|
||||
NAME([this] (offs_t offset) {
|
||||
return m_cursor_y >> (offset * 8);
|
||||
}),
|
||||
NAME([this] (offs_t offset, u8 data) {
|
||||
const u8 shift_mask = 0xff00 >> (offset * 8);
|
||||
m_cursor_y = (data << (offset * 8)) | (m_cursor_y & shift_mask);
|
||||
m_cursor_y &= 0xfff;
|
||||
})
|
||||
);
|
||||
// map(0x10, 0x1f) <reserved>
|
||||
}
|
||||
|
||||
@ -254,7 +308,7 @@ void matrox_vga_device::cursor_write_index_w(offs_t offset, u8 data)
|
||||
m_cursor_write_index = data & 3;
|
||||
m_cursor_index_state = 0;
|
||||
if (data & 0xfc)
|
||||
logerror("RAMDAC cursor write index > 3");
|
||||
logerror("RAMDAC cursor_write_index_w > 3 -> %02x\n", data);
|
||||
}
|
||||
|
||||
u8 matrox_vga_device::cursor_read_index_r()
|
||||
@ -267,7 +321,7 @@ void matrox_vga_device::cursor_read_index_w(offs_t offset, u8 data)
|
||||
m_cursor_read_index = data & 3;
|
||||
m_cursor_index_state = 0;
|
||||
if (data & 0xfc)
|
||||
logerror("RAMDAC cursor read index > 3");
|
||||
logerror("RAMDAC cursor_read_index_w > 3 -> %02x\n", data);
|
||||
}
|
||||
|
||||
u8 matrox_vga_device::cursor_data_r()
|
||||
@ -292,7 +346,7 @@ void matrox_vga_device::cursor_data_w(offs_t offset, u8 data)
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
m_cursor_index_state ++;
|
||||
if (m_cursor_write_index > 2)
|
||||
if (m_cursor_index_state > 2)
|
||||
{
|
||||
m_cursor_index_state = 0;
|
||||
m_cursor_write_index ++;
|
||||
@ -307,7 +361,15 @@ void matrox_vga_device::ramdac_indexed_map(address_map &map)
|
||||
map(0x01, 0x01).lr8(
|
||||
NAME([] (offs_t offset) { return 0x00; })
|
||||
);
|
||||
// map(0x06, 0x06) CCR indirect cursor control
|
||||
// CCR indirect cursor control
|
||||
map(0x06, 0x06).lrw8(
|
||||
NAME([this] (offs_t offset) {
|
||||
return m_cursor_ccr;
|
||||
}),
|
||||
NAME([this] (offs_t offset, u8 data) {
|
||||
m_cursor_ccr = data;
|
||||
})
|
||||
);
|
||||
// map(0x0f, 0x0f) LCR latch control
|
||||
|
||||
map(0x18, 0x18).rw(FUNC(matrox_vga_device::truecolor_ctrl_r), FUNC(matrox_vga_device::truecolor_ctrl_w));
|
||||
@ -382,7 +444,8 @@ void matrox_vga_device::flush_true_color_mode()
|
||||
{
|
||||
// [0x41, 0x42, 0x43, 0x44] for normal
|
||||
// [0x61, 0x62, 0x63, 0x64] for nibble swapped
|
||||
popmessage("TVP3026: Unemulated 4-bit %s with multiplex: %02x"
|
||||
// Used a lot on intermediate states between VGA and Power Modes ...
|
||||
logerror("TVP3026: Unemulated 4-bit %s with multiplex: %02x\n"
|
||||
, m_multiplex_ctrl & 0x20 ? "normal" : "nibble swapped"
|
||||
, m_multiplex_ctrl
|
||||
);
|
||||
@ -511,3 +574,98 @@ u16 matrox_vga_device::line_compare_mask()
|
||||
{
|
||||
return m_mgamode ? 0x7ff : 0x3ff;
|
||||
}
|
||||
|
||||
uint32_t matrox_vga_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
svga_device::screen_update(screen, bitmap, cliprect);
|
||||
// HW cursor
|
||||
const u8 cursor_mode = (BIT(m_cursor_ccr, 7) ? m_cursor_dcc : m_cursor_ccr) & 3;
|
||||
|
||||
if (cursor_mode)
|
||||
{
|
||||
// partial XGA mode only for now (Win 3.1), others TBD
|
||||
// mode 1: 3 color mode -> transparent/color 0-1-2
|
||||
// mode 2: xga mode -> color 0-1/transparent/complement
|
||||
// mode 3: x-window mode -> transparent/transparent/color 0-1
|
||||
const u8 transparent_pen = 2;
|
||||
for (int y = 0; y < 64; y ++)
|
||||
{
|
||||
int res_y = y + m_cursor_y - 64;
|
||||
for (int x = 0; x < 64; x++)
|
||||
{
|
||||
int res_x = x + m_cursor_x - 64;
|
||||
if (!cliprect.contains(res_x, res_y))
|
||||
continue;
|
||||
const u16 cursor_address = (x >> 3) + y * 8;
|
||||
const int xi = 7 - (x & 7);
|
||||
u8 cursor_gfx = (m_cursor_ram[cursor_address] >> (xi) & 1) | ((m_cursor_ram[cursor_address + 0x200] >> (xi)) & 1) << 1;
|
||||
if (cursor_gfx == transparent_pen)
|
||||
continue;
|
||||
// FIXME: Win 3.1 writes to clut 2 for white, may be wrong
|
||||
cursor_gfx ++;
|
||||
cursor_gfx &= 3;
|
||||
const u8 r = m_cursor_color[3 * cursor_gfx + 0];
|
||||
const u8 g = m_cursor_color[3 * cursor_gfx + 1];
|
||||
const u8 b = m_cursor_color[3 * cursor_gfx + 2];
|
||||
|
||||
bitmap.pix(res_y, res_x) = r << 16 | g << 8 | b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG_VRAM_VIEWER
|
||||
static int m_test_x = 640, m_start_offs;
|
||||
static int m_test_trigger = 1;
|
||||
const int m_test_y = cliprect.max_y;
|
||||
|
||||
if(machine().input().code_pressed(JOYCODE_X_RIGHT_SWITCH))
|
||||
m_test_x += 1 << (machine().input().code_pressed(JOYCODE_BUTTON2) ? 4 : 0);;
|
||||
|
||||
if(machine().input().code_pressed(JOYCODE_X_LEFT_SWITCH))
|
||||
m_test_x -= 1 << (machine().input().code_pressed(JOYCODE_BUTTON2) ? 4 : 0);;
|
||||
|
||||
//if(machine().input().code_pressed(JOYCODE_Y_DOWN_SWITCH))
|
||||
// m_test_y++;
|
||||
|
||||
//if(machine().input().code_pressed(JOYCODE_Y_UP_SWITCH))
|
||||
// m_test_y--;
|
||||
|
||||
if(machine().input().code_pressed(JOYCODE_Y_DOWN_SWITCH))
|
||||
m_start_offs+= 0x100 << (machine().input().code_pressed(JOYCODE_BUTTON2) ? 8 : 0);
|
||||
|
||||
if(machine().input().code_pressed(JOYCODE_Y_UP_SWITCH))
|
||||
m_start_offs-= 0x100 << (machine().input().code_pressed(JOYCODE_BUTTON2) ? 8 : 0);
|
||||
|
||||
m_start_offs %= vga.svga_intf.vram_size;
|
||||
|
||||
if(machine().input().code_pressed_once(JOYCODE_BUTTON1))
|
||||
m_test_trigger ^= 1;
|
||||
|
||||
if (!m_test_trigger)
|
||||
return 0;
|
||||
|
||||
popmessage("%d %d %04x", m_test_x, m_test_y, m_start_offs);
|
||||
|
||||
bitmap.fill(0, cliprect);
|
||||
|
||||
int count = m_start_offs;
|
||||
|
||||
for(int y = 0; y < m_test_y; y++)
|
||||
{
|
||||
for(int x = 0; x < m_test_x; x ++)
|
||||
{
|
||||
u8 color = vga.memory[count % vga.svga_intf.vram_size];
|
||||
|
||||
if(cliprect.contains(x, y))
|
||||
{
|
||||
//bitmap.pix(y, x) = pal565(color, 11, 5, 0);
|
||||
bitmap.pix(y, x) = pen(color);
|
||||
}
|
||||
|
||||
count ++;
|
||||
// count += 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -24,6 +24,18 @@ public:
|
||||
bool vsync_status() { return vga_vblank(); }
|
||||
u32 vcount_r() { return screen().vpos() & 0xfff; }
|
||||
|
||||
u8 read_memory(u32 address)
|
||||
{
|
||||
return vga.memory[address % vga.svga_intf.vram_size];
|
||||
}
|
||||
|
||||
void write_memory(u32 address, u8 data)
|
||||
{
|
||||
vga.memory[address % vga.svga_intf.vram_size] = data;
|
||||
}
|
||||
|
||||
virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override;
|
||||
|
||||
protected:
|
||||
virtual void io_3bx_3dx_map(address_map &map) override;
|
||||
|
||||
@ -77,6 +89,9 @@ private:
|
||||
u8 m_cursor_read_index = 0;
|
||||
u8 m_cursor_index_state = 0;
|
||||
u8 m_cursor_color[12]{};
|
||||
u8 m_cursor_ram[0x400]{};
|
||||
u8 m_cursor_ccr = 0, m_cursor_dcc = 0;
|
||||
u16 m_cursor_x = 0, m_cursor_y = 0;
|
||||
|
||||
u8 truecolor_ctrl_r();
|
||||
void truecolor_ctrl_w(offs_t offset, u8 data);
|
||||
|
Loading…
Reference in New Issue
Block a user