video/pc_vga_tseng: preliminary HW cursor

This commit is contained in:
angelosa 2024-11-17 19:01:56 +01:00
parent 2950b39bc7
commit 9a85ba3a75
3 changed files with 136 additions and 6 deletions

View File

@ -176,7 +176,7 @@ void isa16_svga_et4k_w32i_device::device_add_mconfig(machine_config &config)
{
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_raw(25.175_MHz_XTAL, 800, 0, 640, 524, 0, 480);
screen.set_screen_update(m_vga, FUNC(tseng_vga_device::screen_update));
screen.set_screen_update(m_vga, FUNC(et4kw32i_vga_device::screen_update));
ET4KW32I_VGA(config, m_vga, 0);
m_vga->set_screen("screen");

View File

@ -384,6 +384,7 @@ et4kw32i_vga_device::et4kw32i_vga_device(const machine_config &mconfig, const ch
m_mmu_space_config = address_space_config("mmu_regs", ENDIANNESS_LITTLE, 8, 15, 0, address_map_constructor(FUNC(et4kw32i_vga_device::mmu_map), this));
m_acl_idx = 0;
m_ima.control = 0;
}
device_memory_interface::space_config_vector et4kw32i_vga_device::memory_space_config() const
@ -394,6 +395,19 @@ device_memory_interface::space_config_vector et4kw32i_vga_device::memory_space_c
return r;
}
void et4kw32i_vga_device::device_start()
{
tseng_vga_device::device_start();
save_item(NAME(m_acl_idx));
save_item(NAME(m_crtcb.xpos));
save_item(NAME(m_crtcb.ypos));
save_item(NAME(m_crtcb.address));
save_item(NAME(m_ima.control));
}
void et4kw32i_vga_device::crtc_map(address_map &map)
{
tseng_vga_device::crtc_map(map);
@ -467,11 +481,7 @@ void et4kw32i_vga_device::acl_data_w(offs_t offset, u8 data)
space(EXT_REG).write_byte(m_acl_idx, data);
}
void et4kw32i_vga_device::acl_map(address_map &map)
{
}
// TODO: sketchy, essentially stacks MMU on top of normally mirrored VGA memory
uint8_t et4kw32i_vga_device::mem_r(offs_t offset)
{
if(svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb24_en)
@ -517,3 +527,110 @@ void et4kw32i_vga_device::mem_w(offs_t offset, uint8_t data)
void et4kw32i_vga_device::mmu_map(address_map &map)
{
}
void et4kw32i_vga_device::acl_map(address_map &map)
{
map(0xe0, 0xe1).lrw8(
NAME([this] (offs_t offset) {
return m_crtcb.xpos >> (offset * 8);
}),
NAME([this] (offs_t offset, u8 data) {
if (offset)
{
m_crtcb.xpos &= 0xff;
m_crtcb.xpos |= (data & 7) << 8;
}
else
{
m_crtcb.xpos &= 0x700;
m_crtcb.xpos |= (data & 0xff);
}
})
);
map(0xe4, 0xe5).lrw8(
NAME([this] (offs_t offset) {
return m_crtcb.ypos >> (offset * 8);
}),
NAME([this] (offs_t offset, u8 data) {
if (offset)
{
m_crtcb.ypos &= 0xff;
m_crtcb.ypos |= (data & 7) << 8;
}
else
{
m_crtcb.ypos &= 0x700;
m_crtcb.ypos |= (data & 0xff);
}
})
);
map(0xe8, 0xea).lrw8(
NAME([this] (offs_t offset) {
return m_crtcb.address >> (offset * 8);
}),
NAME([this] (offs_t offset, u8 data) {
const u8 shift = offset * 8;
const u32 mask = ~(0xff << shift);
m_crtcb.address &= mask;
m_crtcb.address |= (data << shift);
m_crtcb.address &= 0xfffff;
})
);
/*
* x--- ---- CRTCB enable
* -x-- ---- Token outputs/External Sprite enable
* --xx xx-- <reserved>, always 1000
* ---- --x- Interlace Image Port address
* ---- ---x Image Port enable
*/
map(0xf7, 0xf7).lrw8(
NAME([this] (offs_t offset) {
return m_ima.control;
}),
NAME([this] (offs_t offset, u8 data) {
m_ima.control = data;
if (data & 0x5f)
popmessage("pc_vga_tseng.cpp: IMA $f7 write %02x", data);
})
);
}
uint32_t et4kw32i_vga_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
svga_device::screen_update(screen, bitmap, cliprect);
// HW cursor
// TODO: enough for Win95 in 8bpp and not much else
if (BIT(m_ima.control, 7))
{
const u32 base_offs = (m_crtcb.address << 2) + 0x3f0;
const u8 transparent_pen = 2;
for (int y = 0; y < 32; y ++)
{
int res_y = y + m_crtcb.ypos;
for (int x = 0; x < 32; x++)
{
int res_x = x + m_crtcb.xpos;
if (!cliprect.contains(res_x, res_y))
continue;
// TODO: odd bytes
const u32 cursor_address = (((x >> 2) + y * 16) << 1) + base_offs;
const int xi = (x & 3) * 2;
u8 cursor_gfx = (vga.memory[(cursor_address) % vga.svga_intf.vram_size] >> xi) & 3;
// TODO: pen 3 really RMW with a xor
if (cursor_gfx == transparent_pen)
continue;
bitmap.pix(res_y, res_x) = cursor_gfx & 1 ? 0xffffff : 0x000000;
}
}
}
return 0;
}

View File

@ -77,10 +77,14 @@ public:
virtual uint8_t mem_r(offs_t offset) override;
virtual void mem_w(offs_t offset, uint8_t data) override;
virtual uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override;
protected:
virtual void crtc_map(address_map &map) override ATTR_COLD;
virtual void io_3cx_map(address_map &map) override ATTR_COLD;
virtual void device_start() override ATTR_COLD;
private:
virtual space_config_vector memory_space_config() const override;
@ -91,6 +95,15 @@ private:
void mmu_map(address_map &map) ATTR_COLD;
u8 m_acl_idx;
struct {
u16 xpos, ypos;
u32 address;
}m_crtcb;
struct {
u8 control;
}m_ima;
};