diff --git a/src/devices/video/pc_vga.cpp b/src/devices/video/pc_vga.cpp index 04a4e2730d3..071dcb2989f 100644 --- a/src/devices/video/pc_vga.cpp +++ b/src/devices/video/pc_vga.cpp @@ -369,6 +369,7 @@ void vga_device::io_3cx_map(address_map &map) map(0x00, 0x00).rw(FUNC(vga_device::atc_address_r), FUNC(vga_device::atc_address_data_w)); map(0x01, 0x01).r(FUNC(vga_device::atc_data_r)); map(0x02, 0x02).rw(FUNC(vga_device::input_status_0_r), FUNC(vga_device::miscellaneous_output_w)); +// map(0x03, 0x03).w(FUNC(vga_device::wakeup_w)); map(0x04, 0x04).rw(FUNC(vga_device::sequencer_address_r), FUNC(vga_device::sequencer_address_w)); map(0x05, 0x05).rw(FUNC(vga_device::sequencer_data_r), FUNC(vga_device::sequencer_data_w)); map(0x06, 0x06).rw(FUNC(vga_device::ramdac_mask_r), FUNC(vga_device::ramdac_mask_w)); @@ -1841,6 +1842,33 @@ TIMER_CALLBACK_MEMBER(vga_device::vblank_timer_cb) m_vblank_timer->adjust( screen().time_until_pos(vga.crtc.vert_blank_start + vga.crtc.vert_blank_end) ); } +// ISA bus bindings + +void vga_device::enter_setup_mode() +{ + // ... +} + +/* + * ---x ---- setup mode (only $102 accessible if this is on) + * ---- x--- Enable $03xx I/O and memory accesses + * ---- -xxx BIOS ROM page select for lowest 4 Kbyte range + * + * The generic ISA sequence is: + * $46e8 0x10 (setup mode) + * $0102 0x01 (wakeup core) + * $46e8 0x0e + * + */ +void vga_device::mode_setup_w(offs_t offset, u8 data) +{ + LOG("mode_setup_w %02x\n", data); + if (BIT(data, 4)) + { + enter_setup_mode(); + } +} + /************************************** * * SVGA overrides diff --git a/src/devices/video/pc_vga.h b/src/devices/video/pc_vga.h index 92f60327743..a95642b6e93 100644 --- a/src/devices/video/pc_vga.h +++ b/src/devices/video/pc_vga.h @@ -36,6 +36,11 @@ public: void io_map(address_map &map) ATTR_COLD; + // $46e8, $56e8, $66e8, $76e8 for ISA bus + void mode_setup_w(offs_t offset, uint8_t data); + // $102 / $3c3, MCA bus + //void wakeup_w(offs_t offset, uint8_t data); + virtual uint8_t mem_r(offs_t offset); virtual void mem_w(offs_t offset, uint8_t data); virtual uint8_t mem_linear_r(offs_t offset); @@ -83,6 +88,7 @@ protected: void recompute_params_clock(int divisor, int xtal); virtual void recompute_params(); uint8_t vga_vblank(); + virtual void enter_setup_mode(); virtual space_config_vector memory_space_config() const override; diff --git a/src/devices/video/pc_vga_paradise.cpp b/src/devices/video/pc_vga_paradise.cpp index 0bda31d64ce..b9027b6578b 100644 --- a/src/devices/video/pc_vga_paradise.cpp +++ b/src/devices/video/pc_vga_paradise.cpp @@ -321,14 +321,22 @@ void wd90c00_vga_device::device_reset() m_pr10_scratch = 0; m_ext_crtc_read_unlock = false; m_ext_crtc_write_unlock = false; - // egasw - m_pr11 = (m_cnf15_read_cb() << 7) | (m_cnf14_read_cb() << 6) | m_cnf13_read_cb() << 5 | m_cnf12_read_cb() << 4; m_interlace_start = 0; m_interlace_end = 0; m_interlace_mode = false; m_pr15 = 0; } +// Make sure fetching happens in setup mode +// macpb180c reads then writes 0xf4 to PR11 when waking up from sleep or restart +// (the intention is locking VCLK), assume config refetch happening here. +void wd90c00_vga_device::enter_setup_mode() +{ + vga_device::enter_setup_mode(); + // egasw + m_pr11 = (m_cnf15_read_cb() << 7) | (m_cnf14_read_cb() << 6) | m_cnf13_read_cb() << 5 | m_cnf12_read_cb() << 4; +} + ioport_value wd90c00_vga_device::egasw1_r() { return BIT(m_pr11, 4); } ioport_value wd90c00_vga_device::egasw2_r() { return BIT(m_pr11, 5); } ioport_value wd90c00_vga_device::egasw3_r() { return BIT(m_pr11, 6); } @@ -347,9 +355,12 @@ ioport_constructor wd90c00_vga_device::device_input_ports() const return INPUT_PORTS_NAME(paradise_vga_sense); } +// NOTE: make sure that PR10 just unlocks PR11~PR17 for wd90c26 +// (that has different unlock mechanism for flat panel regs) +// TODO: 'C11 and beyond are unchecked. u8 wd90c00_vga_device::crtc_data_r(offs_t offset) { - if (!m_ext_crtc_read_unlock && vga.crtc.index >= 0x2a && !machine().side_effects_disabled()) + if (!m_ext_crtc_read_unlock && vga.crtc.index >= 0x2a && vga.crtc.index <= 0x30 && !machine().side_effects_disabled()) { LOGLOCKED("Attempt to read ext. CRTC register offset %02x while locked\n", vga.crtc.index); return 0xff; @@ -359,7 +370,7 @@ u8 wd90c00_vga_device::crtc_data_r(offs_t offset) void wd90c00_vga_device::crtc_data_w(offs_t offset, u8 data) { - if (!m_ext_crtc_write_unlock && vga.crtc.index >= 0x2a && !machine().side_effects_disabled()) + if (!m_ext_crtc_write_unlock && vga.crtc.index >= 0x2a && vga.crtc.index <= 0x30 && !machine().side_effects_disabled()) { LOGLOCKED("Attempt to write ext. CRTC register offset [%02x] <- %02x while locked\n", vga.crtc.index, data); return; @@ -426,7 +437,7 @@ void wd90c00_vga_device::ext_crtc_unlock_w(offs_t offset, u8 data) { m_ext_crtc_read_unlock = (data & 0x88) == 0x80; m_ext_crtc_write_unlock = (data & 0x7) == 5; - LOGLOCKED("PR10 read %s write %s state (%02x)\n" + LOGLOCKED("PR10 CRTC read %s write %s state (%02x)\n" , m_ext_crtc_read_unlock ? "unlock" : "lock" , m_ext_crtc_write_unlock ? "unlock" : "lock" , data diff --git a/src/devices/video/pc_vga_paradise.h b/src/devices/video/pc_vga_paradise.h index b4670124b81..c71c2a3b67c 100644 --- a/src/devices/video/pc_vga_paradise.h +++ b/src/devices/video/pc_vga_paradise.h @@ -78,6 +78,8 @@ protected: virtual ioport_constructor device_input_ports() const override ATTR_COLD; + virtual void enter_setup_mode() override; + private: virtual u8 crtc_data_r(offs_t offset) override; virtual void crtc_data_w(offs_t offset, u8 data) override; diff --git a/src/devices/video/wd90c26.cpp b/src/devices/video/wd90c26.cpp index da18dce61bf..c46bd4b8eb8 100644 --- a/src/devices/video/wd90c26.cpp +++ b/src/devices/video/wd90c26.cpp @@ -14,6 +14,11 @@ TODO: #include "emu.h" #include "wd90c26.h" +#define VERBOSE (LOG_GENERAL) +//#define LOG_OUTPUT_FUNC osd_printf_info +#include "logmacro.h" + + DEFINE_DEVICE_TYPE(WD90C26, wd90c26_vga_device, "wd90c26_vga", "Western Digital WD90C26 VGA Controller") wd90c26_vga_device::wd90c26_vga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) @@ -33,15 +38,64 @@ wd90c26_vga_device::wd90c26_vga_device(const machine_config &mconfig, const char void wd90c26_vga_device::crtc_map(address_map &map) { wd90c11a_vga_device::crtc_map(map); -// map(0x31, 0x31) PR18 Flat Panel Status -// map(0x32, 0x33) PR19/PR1A Flat Panel Control -// map(0x34, 0x34) PR1B Flat Panel Unlock + // PR18 Flat Panel Status + map(0x31, 0x31).lrw8( + NAME([this] (offs_t offset) { + LOG("PR18 Flat Panel Status R\n"); + return m_pr18_fp_status; + }), + NAME([this] (offs_t offset, u8 data) { + m_pr18_fp_status = data; + LOG("PR18 Flat Panel Status W %02x\n", data); + }) + ); +// PR19 Flat Panel Control I / PR1A Flat Panel Control II + map(0x32, 0x33).lrw8( + NAME([this] (offs_t offset) { + LOG("PR%02X Flat Panel Control %s R\n", offset + 0x19, offset ? "II" : "I"); + return m_fp_control[offset]; + }), + NAME([this] (offs_t offset, u8 data) { + m_fp_control[offset] = data; + LOG("PR%02X Flat Panel Control %s W %02x\n", offset + 0x19, offset ? "II" : "I", data); + }) + ); +// PR1B Flat Panel Unlock + map(0x34, 0x34).lrw8( + NAME([this] (offs_t offset) { + LOG("PR1B Flat Panel Unlock R\n"); + return m_pr1b_fp_unlock; + }), + NAME([this] (offs_t offset, u8 data) { + m_pr1b_fp_unlock = data; + LOG("PR1B Flat Panel Unlock W %02x\n", data); + }) + ); // map(0x35, 0x35) PR30 Mapping RAM Unlock // map(0x37, 0x37) PR41 Vertical Expansion Initial Value // map(0x38, 0x38) PR33 Mapping RAM Address Counter // map(0x39, 0x39) PR34 Mapping RAM Data -// map(0x3a, 0x3a) PR35 Mapping RAM Control and Power-Down -// map(0x3b, 0x3b) PR36 LCD Panel Height Select + // PR35 Mapping RAM Control and Power-Down + map(0x3a, 0x3a).lrw8( + NAME([this] (offs_t offset) { + LOG("PR35 Mapping RAM Control and Power-Down R\n"); + return m_pr35_powerdown; + }), + NAME([this] (offs_t offset, u8 data) { + m_pr35_powerdown = data; + LOG("PR35 Mapping RAM Control and Power-Down W %02x\n", data); + }) + ); + // PR36 LCD Panel Height Select + map(0x3b, 0x3b).lrw8( + NAME([this] (offs_t offset) { + return m_pr36_lcd_height; + }), + NAME([this] (offs_t offset, u8 data) { + m_pr36_lcd_height = data; + LOG("PR36 LCD Panel Height W %02x\n", data); + }) + ); // map(0x3c, 0x3c) PR37 Flat Panel Blinking Control // map(0x3e, 0x3e) PR39 Color LCD Control // map(0x3f, 0x3f) PR44 Power-Down Memory Refresh Control diff --git a/src/devices/video/wd90c26.h b/src/devices/video/wd90c26.h index 5066113b75e..1001d57ae7e 100644 --- a/src/devices/video/wd90c26.h +++ b/src/devices/video/wd90c26.h @@ -17,6 +17,12 @@ protected: virtual void crtc_map(address_map &map) override ATTR_COLD; virtual void gc_map(address_map &map) override ATTR_COLD; virtual void sequencer_map(address_map &map) override ATTR_COLD; +private: + u8 m_pr18_fp_status; + u8 m_fp_control[2]; + u8 m_pr1b_fp_unlock; + u8 m_pr35_powerdown; + u8 m_pr36_lcd_height; }; DECLARE_DEVICE_TYPE(WD90C26, wd90c26_vga_device) diff --git a/src/mame/apple/macpwrbk030.cpp b/src/mame/apple/macpwrbk030.cpp index 2124c39ad5c..64d3edf97df 100644 --- a/src/mame/apple/macpwrbk030.cpp +++ b/src/mame/apple/macpwrbk030.cpp @@ -595,6 +595,7 @@ u16 macpb030_state::pangola_r() void macpb030_state::pangola_w(u16 data) { m_pangola_data = data; + // TODO: trace pins, 0x13 -> 0x17 -> 0x16 sequence written before waking up VGA core } u8 macpb030_state::pangola_vram_r(offs_t offset) @@ -1257,9 +1258,13 @@ void macpb030_state::macpb165c_map(address_map &map) map(0x50f24000, 0x50f27fff).r(FUNC(macpb030_state::buserror_r)); // bus error here to make sure we aren't mistaken for another decoder map(0x50f80000, 0x50fbffff).rw(FUNC(macpb030_state::niagra_r), FUNC(macpb030_state::niagra_w)); - // on-board color video on 165c/180c + // on-board color video on 165c/180c, presumably under ISA bus map(0xfc000000, 0xfc07ffff).rw(FUNC(macpb030_state::pangola_vram_r), FUNC(macpb030_state::pangola_vram_w)).mirror(0x00380000); +// map(0xfc400102, 0xfc400102).w(wd90c26_vga_device::wakeup_w)); map(0xfc4003b0, 0xfc4003df).m(m_vga, FUNC(wd90c26_vga_device::io_map)); + // TODO: trace $3d0 writes (doesn't belong to WD90C26 core, RAMDAC overlay?) + map(0xfc4046e8, 0xfc4046e8).mirror(0x3000).w(m_vga, FUNC(wd90c26_vga_device::mode_setup_w)); + map(0xfc800000, 0xfc800003).rw(FUNC(macpb030_state::pangola_r), FUNC(macpb030_state::pangola_w)); map(0xfcff8000, 0xfcffffff).rom().region("vrom", 0x0000); @@ -1521,6 +1526,7 @@ void macpb030_state::macpb165c(machine_config &config) m_screen->set_raw(25.175_MHz_XTAL, 800, 0, 640, 524, 0, 480); m_screen->set_screen_update(FUNC(macpb030_state::screen_update_vga)); m_screen->set_no_palette(); + m_screen->set_type(SCREEN_TYPE_LCD); WD90C26(config, m_vga, 0); m_vga->set_screen(m_screen);