summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/devices/video/pc_vga_oak.cpp157
-rw-r--r--src/devices/video/pc_vga_oak.h11
2 files changed, 157 insertions, 11 deletions
diff --git a/src/devices/video/pc_vga_oak.cpp b/src/devices/video/pc_vga_oak.cpp
index 00d958d2e10..2167e17aa77 100644
--- a/src/devices/video/pc_vga_oak.cpp
+++ b/src/devices/video/pc_vga_oak.cpp
@@ -4,10 +4,15 @@
#include "emu.h"
#include "pc_vga_oak.h"
+#define LOG_BANK (1U << 2) // extended segment regs
+
#define VERBOSE (LOG_GENERAL)
#include "logmacro.h"
+#define LOGBANK(...) LOGMASKED(LOG_BANK, __VA_ARGS__)
+
+
DEFINE_DEVICE_TYPE(OTI111, oak_oti111_vga_device, "oti111_vga", "Oak Technologies Spitfire 64111")
oak_oti111_vga_device::oak_oti111_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
@@ -44,6 +49,9 @@ void oak_oti111_vga_device::device_reset()
// Spitfire BIOS doesn't explicitly set IOAS at boot
m_ioas = true;
m_memory_size = 0x0a;
+ m_oti_map_select = false;
+ m_oti_aperture_mask = 0x3ffff;
+ m_oak_gfx_mode = false;
}
void oak_oti111_vga_device::io_3bx_3dx_map(address_map &map)
@@ -127,10 +135,29 @@ void oak_oti111_vga_device::oak_map(address_map &map)
//map(0x0f, 0x0f) Power Management Control
//map(0x10, 0x10) Local Bus Control
- //map(0x11, 0x11) (backward-)Compatible Segment
+ map(0x11, 0x11).lrw8(
+ NAME([this] (offs_t offset) {
+ return (svga.bank_w << 4) | (svga.bank_r & 0xf);
+ }),
+ NAME([this] (offs_t offset, u8 data) {
+ LOGBANK("OAK11: (backward-)Compatible Segment %02x\n", data);
+ svga.bank_r = data & 0xf;
+ svga.bank_w = data >> 4;
+ })
+ );
//map(0x13, 0x13) ISA Bus Control
- //map(0x14, 0x14) Video Memory Mapping
- //(bit 0 -> enable linear segment)
+ map(0x14, 0x14).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_oti_map_select << 0) | (m_oti_aperture_select << 2);
+ }),
+ NAME([this] (offs_t offset, u8 data) {
+ // TODO: what this really selects?
+ m_oti_map_select = bool(BIT(data, 0));
+ m_oti_aperture_select = (data & 0x18) >> 2;
+ m_oti_aperture_mask = (1 << (m_oti_aperture_select + 18)) - 1;
+ LOG("OAK14: Video Memory Mapping %02x (aperture mask %08x)\n", data, m_oti_aperture_mask);
+ })
+ );
//map(0x15, 0x15) Memory & MMIO Enable
//(bit 7 -> enable MMIO)
@@ -138,18 +165,43 @@ void oak_oti111_vga_device::oak_map(address_map &map)
//map(0x20, 0x20) Display FIFO Depth
map(0x21, 0x21).lrw8(
NAME([this] (offs_t offset) {
- return svga.rgb8_en << 2;
+ return m_oak_gfx_mode << 2;
}),
NAME([this] (offs_t offset, u8 data) {
LOG("OAK21: Mode Select %02x\n", data);
- svga.rgb8_en = BIT(data, 2);
+ m_oak_gfx_mode = BIT(data, 2);
recompute_params();
})
);
//map(0x22, 0x22) Feature Select
- //map(0x23, 0x23) Extended Read Segment
- //map(0x24, 0x24) Extended Write Segment
- //map(0x25, 0x25) Extended Common R/W Segment
+ map(0x23, 0x23).lrw8(
+ NAME([this] (offs_t offset) {
+ return svga.bank_r & 0x7f;
+ }),
+ NAME([this] (offs_t offset, u8 data) {
+ LOGBANK("OAK23: Extended Read Segment %02x\n", data);
+ svga.bank_r = data & 0x7f;
+ })
+ );
+ map(0x24, 0x24).lrw8(
+ NAME([this] (offs_t offset) {
+ return svga.bank_w & 0x7f;
+ }),
+ NAME([this] (offs_t offset, u8 data) {
+ LOGBANK("OAK24: Extended Read Segment %02x\n", data);
+ svga.bank_w = data & 0x7f;
+ })
+ );
+ map(0x25, 0x25).lrw8(
+ NAME([this] (offs_t offset) {
+ return svga.bank_w & 0x7f;
+ }),
+ NAME([this] (offs_t offset, u8 data) {
+ LOGBANK("OAK25: Extended Common R/W Segment %02x\n", data);
+ svga.bank_r = data & 0x7f;
+ svga.bank_w = data & 0x7f;
+ })
+ );
//map(0x26, 0x26) RASn Control
//map(0x27, 0x27) CASn Control
//map(0x28, 0x28) Refresh Control
@@ -167,7 +219,19 @@ void oak_oti111_vga_device::oak_map(address_map &map)
vga.crtc.no_wrap = BIT(data, 0);
})
);
- //map(0x38, 0x38) Pixel i/f
+ map(0x38, 0x38).lrw8(
+ NAME([this] (offs_t offset) {
+ return (m_pixel_mode & 0xf) | (m_color_swap << 4) | (m_bpp << 5);
+ }),
+ NAME([this] (offs_t offset, u8 data) {
+ LOG("OAK38: Pixel i/f %02x\n", data);
+ m_pixel_mode = data & 0xf;
+ // TODO: swaps R and B guns in 16bpp / 24bpp modes
+ m_color_swap = bool(BIT(data, 4));
+ m_bpp = (data >> 5) & 3;
+ recompute_params();
+ })
+ );
//map(0x39, 0x3a) Extended Overscan Color
//HC = Hardware Cursor
@@ -233,9 +297,80 @@ uint16_t oak_oti111_vga_device::offset()
{
uint16_t off = svga_device::offset();
- if (svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb32_en)
- return vga.crtc.offset << 4; // TODO: there must a register to control this
+ if (m_oak_gfx_mode)
+ return vga.crtc.offset << 4;
else
return off;
}
+u8 oak_oti111_vga_device::mem_r(offs_t offset)
+{
+ if (((offset & 0x10000) == 0) && m_oak_gfx_mode)
+ return svga_device::mem_linear_r((offset + svga.bank_r * 0x10000) & m_oti_aperture_mask);
+ return svga_device::mem_r(offset);
+}
+
+void oak_oti111_vga_device::mem_w(offs_t offset, uint8_t data)
+{
+ if (((offset & 0x10000) == 0) && m_oak_gfx_mode)
+ {
+ svga_device::mem_linear_w((offset + svga.bank_w * 0x10000) & m_oti_aperture_mask, data);
+ return;
+ }
+ svga_device::mem_w(offset, data);
+}
+
+void oak_oti111_vga_device::recompute_params()
+{
+ u8 xtal_select = (vga.miscellaneous_output & 0x0c) >> 2;
+ int xtal;
+
+ svga.rgb8_en = svga.rgb15_en = svga.rgb16_en = svga.rgb24_en = 0;
+
+ if (m_oak_gfx_mode)
+ {
+ switch(m_pixel_mode)
+ {
+ case 0:
+ // VGA mode
+ break;
+ case 2:
+ case 4:
+ svga.rgb8_en = 1;
+ break;
+ case 3:
+ svga.rgb24_en = 1;
+ break;
+ case 5:
+ // TODO: SciTech uses this in both 15 and 16bpp
+ svga.rgb16_en = 1;
+ break;
+ case 7:
+ svga.rgb24_en = 1;
+ break;
+ default:
+ popmessage("pc_vga_oak: unhandled pixel mode %02x", m_pixel_mode);
+ break;
+ }
+ }
+
+ switch(xtal_select & 3)
+ {
+ case 0: xtal = XTAL(25'174'800).value(); break;
+ case 1: xtal = XTAL(28'636'363).value(); break;
+ // TODO: to external PLL (OTI-088 or ATT20C409 / ATT20C499)
+ // gs471 seems to use former
+ case 2:
+ // TODO: Video Clock Reg 2 / Set C
+ xtal = XTAL(25'174'800).value();
+ //xtal = XTAL(50'144'xxx)
+ break;
+ case 3:
+ // TODO: Video Clock Reg 3 / Set D
+ xtal = XTAL(28'636'363).value();
+ //xtal = XTAL(75'170'xxx)
+ break;
+ }
+
+ recompute_params_clock(1, xtal);
+}
diff --git a/src/devices/video/pc_vga_oak.h b/src/devices/video/pc_vga_oak.h
index d5fa2ca50c2..255500ed19f 100644
--- a/src/devices/video/pc_vga_oak.h
+++ b/src/devices/video/pc_vga_oak.h
@@ -20,11 +20,15 @@ public:
void ramdac_mmio_map(address_map &map);
void oak_map(address_map &map);
+ virtual uint8_t mem_r(offs_t offset) override;
+ virtual void mem_w(offs_t offset, uint8_t data) override;
+
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
virtual void device_reset() override;
virtual uint16_t offset() override;
+ virtual void recompute_params() override;
virtual void io_3bx_3dx_map(address_map &map) override;
private:
@@ -39,6 +43,13 @@ private:
u8 m_memory_size = 0;
u8 m_i2c_data = 0;
u8 m_scratchpad[8]{};
+ bool m_oak_gfx_mode = false;
+ bool m_oti_map_select = false;
+ u8 m_oti_aperture_select = 0;
+ u32 m_oti_aperture_mask = 0x3ffff;
+ u8 m_pixel_mode = 0;
+ bool m_color_swap = false;
+ u8 m_bpp = 0;
};
DECLARE_DEVICE_TYPE(OTI111, oak_oti111_vga_device)