// license: BSD-3-Clause // copyright-holders: Angelo Salese /************************************************************************************************** Intel 440BX 82443BX Host section TODO: - better subclassing leap, we currently use i82339hx base for convenience **************************************************************************************************/ #include "emu.h" #include "i82443bx_host.h" #define LOG_IO (1U << 1) // log PCI register accesses #define LOG_TODO (1U << 2) // log unimplemented registers #define LOG_MAP (1U << 3) // log full remaps #define VERBOSE (LOG_GENERAL | LOG_IO | LOG_TODO | LOG_MAP) //#define LOG_OUTPUT_FUNC osd_printf_warning #include "logmacro.h" #define LOGIO(...) LOGMASKED(LOG_IO, __VA_ARGS__) #define LOGMAP(...) LOGMASKED(LOG_MAP, __VA_ARGS__) #define LOGTODO(...) LOGMASKED(LOG_TODO, __VA_ARGS__) DEFINE_DEVICE_TYPE(I82443BX_HOST, i82443bx_host_device, "i82443bx_host", "Intel 82443BX PAC Host to PCI northbridge") DEFINE_DEVICE_TYPE(I82443LX_HOST, i82443lx_host_device, "i82443lx_host", "Intel 82443LX PAC Host to PCI northbridge") i82443bx_host_device::i82443bx_host_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : i82439hx_host_device(mconfig, type, tag, owner, clock) { } i82443bx_host_device::i82443bx_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : i82443bx_host_device(mconfig, I82443BX_HOST, tag, owner, clock) { // TODO: Device ID (DID) is 0x7192 when AGP_DIS is '1' // rev 0x02 82443BX B-1 set_ids_host(0x80867190, 0x02, 0x00000000); } i82443lx_host_device::i82443lx_host_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : i82443bx_host_device(mconfig, I82443LX_HOST, tag, owner, clock) { set_ids_host(0x80867180, 0x00, 0x00000000); } void i82443bx_host_device::config_map(address_map &map) { i82439hx_host_device::config_map(map); // override first BAR slot for gfx window base address map(0x10, 0x13).rw(FUNC(pci_device::address_base_r), FUNC(pci_device::address_base_w)); map(0x34, 0x34).r(FUNC(i82443bx_host_device::capptr_r)); // map(0x50, 0x53).lr32(NAME([this] () { return machine().rand(); })); // TODO: no DRT, moved as DRTC / DWTC in dword format to $e0/$e8 map(0x68, 0x68).rw(FUNC(i82443bx_host_device::fdhc_r), FUNC(i82443bx_host_device::fdhc_w)); // TODO: midqslvr.cpp r/ws the AGPCTRL register but don't seem to match what's in datasheet // I also haven't yet enabled CAPPTR lolwut? //map(0xb0, 0xb3) map(0xd0, 0xd7).rw(FUNC(i82443bx_host_device::bspad_r), FUNC(i82443bx_host_device::bspad_w)); } void i82443bx_host_device::apbase_map(address_map &map) { // ... } void i82443bx_host_device::device_start() { i82439hx_host_device::device_start(); // TODO: size add_map(8*1024*1024, M_MEM, FUNC(i82443bx_host_device::apbase_map)); save_item(NAME(m_fdhc)); save_pointer(NAME(m_bspad), 8); } void i82443bx_host_device::device_reset() { i82439hx_host_device::device_reset(); m_fdhc = 0; for (int i = 0; i < 8; i++) m_bspad[i] = 0; } u8 i82443bx_host_device::capptr_r() { return 0xa0; } // Register is different wrt i82439hx std::tuple i82443bx_host_device::read_memory_holes() { const bool lower_hole = (m_fdhc & 0xc0) == 0x40; // TODO: 11 is "reserved" const bool upper_hole = (m_fdhc & 0xc0) != 0x80; return std::make_tuple(lower_hole, upper_hole); } u8 i82443bx_host_device::fdhc_r() { return m_fdhc; } void i82443bx_host_device::fdhc_w(u8 data) { m_fdhc = data; LOGIO("FDHC = %02x\n", data); remap_cb(); } /* * BSPAD - BIOS Scratch Pad Register * 8 bytes of pseudo-RAM */ u8 i82443bx_host_device::bspad_r(offs_t offset) { LOGIO("BSPAD[%d] R\n", offset); return m_bspad[offset]; } void i82443bx_host_device::bspad_w(offs_t offset, u8 data) { LOGIO("BSPAD[%d] = %02x\n", offset, data); m_bspad[offset] = data; } /***************************** * * Virtual PCI-to-PCI bridge implementation * ****************************/ DEFINE_DEVICE_TYPE(I82443BX_BRIDGE, i82443bx_bridge_device, "i82443bx_bridge", "Intel 82443BX Virtual PCI-to-PCI bridge") DEFINE_DEVICE_TYPE(I82443LX_BRIDGE, i82443lx_bridge_device, "i82443lx_bridge", "Intel 82443LX Virtual PCI-to-PCI bridge") i82443bx_bridge_device::i82443bx_bridge_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : pci_bridge_device(mconfig, type, tag, owner, clock) // , m_vga(*this, finder_base::DUMMY_TAG) { } i82443bx_bridge_device::i82443bx_bridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : i82443bx_bridge_device(mconfig, I82443BX_BRIDGE, tag, owner, clock) // , m_vga(*this, finder_base::DUMMY_TAG) { set_ids_bridge(0x80867191, 0x00); } i82443lx_bridge_device::i82443lx_bridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : i82443bx_bridge_device(mconfig, I82443LX_BRIDGE, tag, owner, clock) { set_ids_bridge(0x80867181, 0x00); } void i82443bx_bridge_device::map_extra( uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space, uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space ) { if (BIT(bridge_control, 3)) { //memory_space->install_device(0, 0xfffff, *m_vga, &sis630_gui_device::legacy_memory_map); //io_space->install_device(0, 0x0fff, *m_vga, &sis630_gui_device::legacy_io_map); } } void i82443bx_bridge_device::bridge_control_w(offs_t offset, uint16_t data, uint16_t mem_mask) { pci_bridge_device::bridge_control_w(offset, data, mem_mask); LOGMAP("- %s VGA control\n", bridge_control & 8 ? "Enable" : "Disable"); remap_cb(); } void i82443bx_bridge_device::device_start() { pci_bridge_device::device_start(); } void i82443bx_bridge_device::device_reset() { pci_bridge_device::device_reset(); }