video/pc_vga_sis: placeholder for extended clock modes, reformat sequencer logging, extend QA notes

This commit is contained in:
angelosa 2024-02-10 03:01:19 +01:00
parent a17ea8387c
commit 0def9d44cc
4 changed files with 127 additions and 30 deletions

View File

@ -1,15 +1,16 @@
// license:BSD-3-Clause
// copyright-holders: Angelo Salese
/***************************************************************************
/**************************************************************************************************
Winbond W83977TF
TODO:
- PoC for a generic (LPC) Super I/O type, to be merged with fdc37c93x;
- savquest (in pciagp) fails keyboard self test (PC=e140c reads bit 0 high
from port $64?)
- savquest (in pciagp) fails keyboard self test
\- bp e140c,1,{eax&=~1;g} bit 0 stuck high from port $64, "receives" while essentially reading
status only three times (and port $61 is claimed by PIIX4 for PCI SERR# read only)
***************************************************************************/
**************************************************************************************************/
#include "emu.h"
#include "machine/w83977tf.h"
@ -373,7 +374,7 @@ void w83977tf_device::mouse_irq_w(offs_t offset, u8 data)
u8 w83977tf_device::keybc_status_r(offs_t offset)
{
return (m_kbdc->data_r(4) & 0xfb) | 0x10; // bios needs bit 2 to be 0 as powerup and bit 4 to be 1
return (m_kbdc->data_r(4) & 0xff);
}
void w83977tf_device::keybc_command_w(offs_t offset, u8 data)

View File

@ -544,7 +544,7 @@ void cirrus_gd5428_device::sequencer_map(address_map &map)
NAME([this] (offs_t offset, u8 data) {
// TODO: bebox startup enables this
if((data & 0xf0) != 0)
popmessage("1MB framebuffer window enabled at %iMB (%02x)",data >> 4,data);
popmessage("pc_vga_cirrus: 1MB framebuffer window enabled at %iMB (%02x)",data >> 4,data);
vga.sequencer.data[0x07] = data;
cirrus_define_video_mode();
})
@ -812,7 +812,7 @@ void cirrus_gd5428_device::cirrus_define_video_mode()
{
// TODO: needs subclassing, earlier chips don't have all of these modes
if (BIT(m_hidden_dac_mode, 4))
popmessage("Cirrus: Unsupported mixed 5-5-5 / 8bpp mode selected");
popmessage("pc_vga_cirrus: Unsupported mixed 5-5-5 / 8bpp mode selected");
switch(m_hidden_dac_mode & 0x4f)
{
case 0x00:
@ -827,23 +827,24 @@ void cirrus_gd5428_device::cirrus_define_video_mode()
case 0x44: // YUV411 8-bit
case 0x4a: // 16bpp + YUV422 overlay
case 0x4b: // 16bpp + YUV411 overlay
popmessage("Cirrus: CL-GD545 YUV mode selected %02x", m_hidden_dac_mode);
popmessage("pc_vga_cirrus: CL-GD545 YUV mode selected %02x", m_hidden_dac_mode);
break;
case 0x45:
svga.rgb24_en = 1;
break;
case 0x46:
case 0x47:
popmessage("Cirrus: CL-GD545+ DAC power down selected %02x", m_hidden_dac_mode);
popmessage("pc_vga_cirrus: CL-GD545+ DAC power down selected %02x", m_hidden_dac_mode);
break;
case 0x48:
popmessage("Cirrus: CL-GD545+ 8-bit grayscale selected");
popmessage("pc_vga_cirrus: CL-GD545+ 8-bit grayscale selected");
break;
case 0x49:
svga.rgb8_en = 1;
break;
default:
popmessage("Cirrus: reserved mode selected %02x", m_hidden_dac_mode);
// TODO: 0xff in pciagp (alias for a DAC power down?)
popmessage("pc_vga_cirrus: reserved mode selected %02x", m_hidden_dac_mode);
break;
}
}
@ -1118,7 +1119,7 @@ void cirrus_gd5428_device::copy_pixel(uint8_t src, uint8_t dst)
res = src ^ dst;
break;
default:
popmessage("CL: Unsupported BitBLT ROP mode %02x",m_blt_rop);
popmessage("pc_vga_cirrus: Unsupported BitBLT ROP mode %02x",m_blt_rop);
}
// handle transparency compare
@ -1146,11 +1147,11 @@ uint8_t cirrus_gd5428_device::vga_latch_write(int offs, uint8_t data)
break;
case 4:
res = vga.gc.latch[offs];
popmessage("CL: Unimplemented VGA write mode 4 enabled");
popmessage("pc_vga_cirrus: Unimplemented VGA write mode 4 enabled");
break;
case 5:
res = vga.gc.latch[offs];
popmessage("CL: Unimplemented VGA write mode 5 enabled");
popmessage("pc_vga_cirrus: Unimplemented VGA write mode 5 enabled");
break;
}

View File

@ -2,11 +2,23 @@
// copyright-holders:Angelo Salese
/**************************************************************************************************
Implementation of SiS family (S)VGA chipset
Implementation of SiS family (S)VGA chipset (SiS630)
VBE 3.0, Multi Buffering & Virtual Scrolling available
TODO:
- interlace (cfr. xubuntu 6.10 splash screen on 1024x768x32);
- backport to earlier variants;
- Refresh rate for extended modes;
- interlace;
- linear addressing;
- HW cursor;
- Output scaling, cfr. xubuntu 6.10 splash screen at 1024x768x32;
- Interrupts;
- Dual segment;
- AGP/HostBus/Turbo Queue i/f;
- 2D/3D pipeline;
- DDC;
- Bridge with a secondary TV out (SiS301);
- Verify matches with other SiS PCI cards, backport;
**************************************************************************************************/
@ -17,6 +29,7 @@ TODO:
#define VERBOSE (LOG_GENERAL)
//#define LOG_OUTPUT_FUNC osd_printf_info
#include "logmacro.h"
// TODO: later variant of 5598
@ -90,17 +103,19 @@ void sis630_svga_device::crtc_map(address_map &map)
map(0x26, 0x26).lr8(
NAME([this] (offs_t offset) { return vga.attribute.index; })
);
// TODO: very preliminary, undocumented stuff
// TODO: very preliminary, this section is undocumented in '630 doc
map(0x30, 0xff).lrw8(
NAME([this] (offs_t offset) {
return vga.crtc.data[offset];
}),
NAME([this] (offs_t offset, u8 data) {
// TODO: if one of these is 0xff then it enables a single port transfer to $b8000
// Older style MMIO?
vga.crtc.data[offset] = data;
})
);
// make sure '301 CRT2 is not enabled for now
// TODO: BeMAME (0.36b5) under BeOS 5.0 detects a secondary monitor by default anyway
map(0x30, 0x30).lr8(
NAME([] (offs_t offset) { return 0; })
);
@ -123,7 +138,7 @@ void sis630_svga_device::sequencer_map(address_map &map)
NAME([this] (offs_t offset, u8 data) {
// TODO: reimplement me thru memory_view or direct handler override
m_unlock_reg = (data == 0x86);
LOG("Unlock register write %02x (%s)\n", data, m_unlock_reg ? "unlocked" : "locked");
//LOG("SR5: Unlock register write %02x (%s)\n", data, m_unlock_reg ? "unlocked" : "locked");
})
);
/*
@ -142,7 +157,7 @@ void sis630_svga_device::sequencer_map(address_map &map)
}),
NAME([this] (offs_t offset, u8 data) {
m_ramdac_mode = data;
LOG("RAMDAC mode %02x\n", data);
LOG("SR06: RAMDAC mode %02x\n", data);
if (!BIT(data, 1))
{
@ -163,17 +178,18 @@ void sis630_svga_device::sequencer_map(address_map &map)
return m_ext_misc_ctrl_0;
}),
NAME([this] (offs_t offset, u8 data) {
LOG("Extended Misc. Control register 0 SR07 %02x\n", data);
LOG("SR07: Extended Misc. Control 0 %02x\n", data);
m_ext_misc_ctrl_0 = data;
std::tie(svga.rgb24_en, svga.rgb32_en) = flush_true_color_mode();
})
);
//map(0x08, 0x09) CRT threshold
map(0x0a, 0x0a).lrw8(
NAME([this] (offs_t offset) {
return m_ext_vert_overflow;
}),
NAME([this] (offs_t offset, u8 data) {
LOG("Extended vertical Overflow register SR0A %02x\n", data);
LOG("SR0A: Extended Vertical Overflow %02x\n", data);
m_ext_vert_overflow = data;
vga.crtc.vert_retrace_end = (vga.crtc.vert_retrace_end & 0xf) | ((data & 0x20) >> 1);
vga.crtc.vert_blank_end = (vga.crtc.vert_blank_end & 0x00ff) | ((data & 0x10) << 4);
@ -192,7 +208,7 @@ void sis630_svga_device::sequencer_map(address_map &map)
map(0x0b, 0x0b).lw8(
NAME([this] (offs_t offset, u8 data) {
//m_dual_seg_mode = bool(BIT(data, 3));
LOG("Extended horizontal Overflow 1 SR0B %02x\n", data);
LOG("SR0B: Extended Horizontal Overflow 1 %02x\n", data);
m_ext_horz_overflow[0] = data;
vga.crtc.horz_retrace_start = (vga.crtc.horz_retrace_start & 0x00ff) | ((data & 0xc0) << 2);
@ -205,7 +221,7 @@ void sis630_svga_device::sequencer_map(address_map &map)
);
map(0x0c, 0x0c).lw8(
NAME([this] (offs_t offset, u8 data) {
LOG("Extended horizontal Overflow 2 SR0C %02x\n", data);
LOG("SR0C: Extended Horizontal Overflow 2 %02x\n", data);
m_ext_horz_overflow[1] = data;
vga.crtc.horz_retrace_end = (vga.crtc.horz_retrace_end & 0x001f) | ((data & 0x04) << 3);
@ -218,18 +234,21 @@ void sis630_svga_device::sequencer_map(address_map &map)
return vga.crtc.start_addr_latch >> 16;
}),
NAME([this] (offs_t offset, u8 data) {
LOG("Extended starting address register SR0D %02x\n", data);
LOG("SR0D: Extended Starting Address %02x\n", data);
vga.crtc.start_addr_latch &= ~0xff0000;
vga.crtc.start_addr_latch |= data << 16;
})
);
map(0x0e, 0x0e).lw8(
NAME([this] (offs_t offset, u8 data) {
LOG("Extended pitch register SR0E %02x\n", data);
LOG("SR0E: Extended pitch register %02x\n", data);
// sis_main.c implicitly sets this with bits 0-3 granularity, assume being right
vga.crtc.offset = (vga.crtc.offset & 0x00ff) | ((data & 0x0f) << 8);
})
);
//map(0x0f, 0x0f) CRT misc. control
//map(0x10, 0x10) Display line width register
//map(0x11, 0x11) DDC register
map(0x14, 0x14).lrw8(
NAME([this] (offs_t offset) {
// sis_main.c calculates VRAM size in two ways:
@ -242,21 +261,80 @@ void sis630_svga_device::sequencer_map(address_map &map)
return (m_bus_width) | ((vga.svga_intf.vram_size / (1024 * 1024) - 1) & 0x3f);
}),
NAME([this] (offs_t offset, u8 data) {
LOG("SR14: <unknown> %02x\n", data);
m_bus_width = data & 0xc0;
})
);
//map(0x1d, 0x1d) Segment Selection Overflow
map(0x1e, 0x1e).lw8(
NAME([this] (offs_t offset, u8 data) {
if (BIT(data, 6))
popmessage("Warning: enable 2d engine");
popmessage("pc_vga_sis: enable 2d engine");
})
);
//map(0x1f, 0x1f) Power management
map(0x20, 0x20).lw8(
NAME([this] (offs_t offset, u8 data) {
// GUI address decoder setting
if (data & 0x81)
popmessage("Warning: %s %s", BIT(data, 7) ? "PCI address enabled" : "", BIT(data, 0) ? "memory map I/O enable" : "");
popmessage("pc_vga_sis: SR20 %s %s", BIT(data, 7) ? "PCI address enabled" : "", BIT(data, 0) ? "memory map I/O enable" : "");
})
);
//map(0x21, 0x21) GUI HostBus state machine setting
//map(0x22, 0x22) GUI HostBus controller timing
//map(0x23, 0x23) GUI HostBus timer
//map(0x26, 0x26) Turbo Queue base address
//map(0x27, 0x27) Turbo Queue control
map(0x2b, 0x2d).lrw8(
NAME([this] (offs_t offset) {
return m_ext_dclk[offset];
}),
NAME([this] (offs_t offset, u8 data) {
LOG("SR%02X: Extended DCLK %02x\n", offset + 0x2b, data);
m_ext_dclk[offset] = data;
recompute_params();
})
);
map(0x2e, 0x30).lrw8(
NAME([this] (offs_t offset) {
return m_ext_eclk[offset];
}),
NAME([this] (offs_t offset, u8 data) {
LOG("SR%02X: Extended ECLK %02x\n", offset + 0x2e, data);
m_ext_eclk[offset] = data;
recompute_params();
})
);
map(0x31, 0x31).lrw8(
NAME([this] (offs_t offset) {
return m_ext_clock_gen;
}),
NAME([this] (offs_t offset, u8 data) {
LOG("SR31: Extended clock generator misc. %02x\n", data);
m_ext_clock_gen = data;
recompute_params();
})
);
map(0x32, 0x32).lrw8(
NAME([this] (offs_t offset) {
return m_ext_clock_source_select;
}),
NAME([this] (offs_t offset, u8 data) {
LOG("SR32: Extended clock source selection %02x\n", data);
m_ext_clock_source_select = data;
recompute_params();
})
);
//map(0x34, 0x34) Interrupt status
//map(0x35, 0x35) Interrupt enable
//map(0x36, 0x36) Interrupt reset
//map(0x38, 0x3a) Power on trapping
//map(0x3c, 0x3c) Synchronous reset
//map(0x3d, 0x3d) Test enable
}
std::tuple<u8, u8> sis630_svga_device::flush_true_color_mode()
@ -272,8 +350,21 @@ std::tuple<u8, u8> sis630_svga_device::flush_true_color_mode()
void sis630_svga_device::recompute_params()
{
// TODO: ext clock
recompute_params_clock(1, XTAL(25'174'800).value());
u8 xtal_select = (vga.miscellaneous_output & 0x0c) >> 2;
int xtal;
switch(xtal_select & 3)
{
case 0: xtal = XTAL(25'174'800).value(); break;
case 1: xtal = XTAL(28'636'363).value(); break;
// TODO: stub, barely enough to make BeOS 5 to set ~60 Hz for 640x480x16
case 2:
default:
xtal = XTAL(25'174'800).value();
break;
}
recompute_params_clock(1, xtal);
}
uint16_t sis630_svga_device::offset()

View File

@ -33,6 +33,10 @@ protected:
u8 m_ext_vert_overflow = 0;
u8 m_ext_horz_overflow[2]{};
u8 m_bus_width = 0;
u8 m_ext_dclk[3]{};
u8 m_ext_eclk[3]{};
u8 m_ext_clock_gen = 0;
u8 m_ext_clock_source_select = 0;
bool m_unlock_reg = false;
std::tuple<u8, u8> flush_true_color_mode();