summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/devices/video/pc_vga.cpp30
-rw-r--r--src/devices/video/pc_vga.h4
2 files changed, 28 insertions, 6 deletions
diff --git a/src/devices/video/pc_vga.cpp b/src/devices/video/pc_vga.cpp
index 071dcb2989f..465798da8d5 100644
--- a/src/devices/video/pc_vga.cpp
+++ b/src/devices/video/pc_vga.cpp
@@ -60,7 +60,7 @@
#define LOG_DSW (1U << 3) // Input sense at $3c2
#define LOG_CRTC (1U << 4) // CRTC setups with monitor geometry
-#define VERBOSE (LOG_GENERAL | LOG_WARN | LOG_DSW)
+#define VERBOSE (LOG_GENERAL | LOG_WARN)
//#define LOG_OUTPUT_FUNC osd_printf_info
#include "logmacro.h"
@@ -117,6 +117,7 @@ vga_device::vga_device(const machine_config &mconfig, device_type type, const ch
, device_memory_interface(mconfig, *this)
, vga(*this)
, m_input_sense(*this, "VGA_SENSE")
+ , m_vsync_cb(*this)
{
m_main_if_space_config = address_space_config("io_regs", ENDIANNESS_LITTLE, 8, 4, 0, address_map_constructor(FUNC(vga_device::io_3bx_3dx_map), this));
m_crtc_space_config = address_space_config("crtc_regs", ENDIANNESS_LITTLE, 8, 8, 0, address_map_constructor(FUNC(vga_device::crtc_map), this));
@@ -223,6 +224,7 @@ void vga_device::device_start()
save_item(NAME(vga.crtc.map13));
save_item(NAME(vga.crtc.irq_clear));
save_item(NAME(vga.crtc.irq_disable));
+ save_item(NAME(vga.crtc.irq_latch));
save_item(NAME(vga.crtc.no_wrap));
save_item(NAME(vga.gc.index));
@@ -498,6 +500,7 @@ u8 vga_device::input_status_0_r(offs_t offset)
LOGDSW("Reading sense bit %d\n", sense_bit);
if(BIT(m_input_sense->read(), sense_bit))
res |= 0x10;
+ res |= vga.crtc.irq_latch << 7;
return res;
}
@@ -905,12 +908,20 @@ void vga_device::crtc_map(address_map &map)
return res;
}),
NAME([this](offs_t offset, u8 data) {
- vga.crtc.protect_enable = (data & 0x80) >> 7;
- vga.crtc.bandwidth = (data & 0x40) >> 6;
+ vga.crtc.protect_enable = BIT(data, 7);
+ vga.crtc.bandwidth = BIT(data, 6);
+ // IRQ: Original VGA only supports this for PS/2, but clone cards may supports this on ISA too
+ // see https://scalibq.wordpress.com/2022/12/06/the-myth-of-the-vertical-retrace-interrupt/
+ vga.crtc.irq_disable = BIT(data, 5);
+ vga.crtc.irq_clear = BIT(data, 4);
vga.crtc.vert_retrace_end = (vga.crtc.vert_retrace_end & ~0xf) | (data & 0x0f);
- // TODO: these two doesn't seem part of the spec
- vga.crtc.irq_clear = (data & 0x10) >> 4;
- vga.crtc.irq_disable = (data & 0x20) >> 5;
+
+ if (vga.crtc.irq_clear == 0)
+ {
+ vga.crtc.irq_latch = 0;
+ m_vsync_cb(0);
+ }
+
LOGCRTC("CR11 V retrace end %02x -> %02d protect enable %d bandwidth %d irq %02x\n"
, data
, vga.crtc.vert_retrace_end
@@ -1839,6 +1850,13 @@ TIMER_CALLBACK_MEMBER(vga_device::vblank_timer_cb)
{
vga.crtc.start_addr = latch_start_addr();
vga.attribute.pel_shift = vga.attribute.pel_shift_latch;
+
+ if (vga.crtc.irq_latch == 0 && vga.crtc.irq_disable == 0)
+ {
+ vga.crtc.irq_latch = 1;
+ m_vsync_cb(1);
+ }
+
m_vblank_timer->adjust( screen().time_until_pos(vga.crtc.vert_blank_start + vga.crtc.vert_blank_end) );
}
diff --git a/src/devices/video/pc_vga.h b/src/devices/video/pc_vga.h
index d982163bbb0..4bcef44fd9f 100644
--- a/src/devices/video/pc_vga.h
+++ b/src/devices/video/pc_vga.h
@@ -48,6 +48,7 @@ public:
void set_offset(uint16_t val) { vga.crtc.offset = val; }
void set_vram_size(size_t vram_size) { vga.svga_intf.vram_size = vram_size; }
+ auto vsync_cb() { return m_vsync_cb.bind(); }
// FIXME: should be protected, but virge_pci.cpp violates this
inline uint16_t get_crtc_port() { return BIT(vga.miscellaneous_output, 0) ? 0x3d0 : 0x3b0; }
@@ -235,6 +236,7 @@ protected:
/**/ uint8_t map13;
/**/ uint8_t irq_clear;
/**/ uint8_t irq_disable;
+ uint8_t irq_latch;
uint8_t no_wrap;
} crtc;
@@ -305,6 +307,8 @@ protected:
address_space_config m_atc_space_config;
bool m_ioas = false;
+
+ devcb_write_line m_vsync_cb;
private:
uint32_t start_addr();
};