mirror of
https://github.com/holub/mame
synced 2025-06-05 20:33:45 +03:00
saitek_osa: added sparc module emulation [Ryan Holtz, hap]
This commit is contained in:
parent
4518f0eade
commit
63f8d3da21
@ -132,7 +132,7 @@ void saitekosa_expansion_device::pw_w(int state)
|
||||
|
||||
u32 saitekosa_expansion_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
return (m_module) ? m_module->screen_update(screen, bitmap, cliprect) : UPDATE_HAS_NOT_CHANGED;
|
||||
return (m_module) ? m_module->screen_update(screen, bitmap, cliprect) : 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -113,7 +113,7 @@ public:
|
||||
virtual void ack_w(int state) { }
|
||||
virtual void pw_w(int state) { }
|
||||
|
||||
virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { return UPDATE_HAS_NOT_CHANGED; }
|
||||
virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { return 0; }
|
||||
|
||||
protected:
|
||||
device_saitekosa_expansion_interface(const machine_config &mconfig, device_t &device);
|
||||
|
@ -8,7 +8,7 @@ Saitek OSA Module: Kasparov Sparc (1993)
|
||||
The chess engine is by the Spracklen's. Their last, and also their strongest.
|
||||
|
||||
Hardware notes:
|
||||
- Fujitsu MB86930 SPARClite @ 20MHz
|
||||
- Fujitsu MB86930-20 SPARClite @ 20MHz
|
||||
- 256KB ROM (4*AMD AM27C512)
|
||||
- 1MB DRAM (8*NEC 424256-60), expandable to 4MB
|
||||
|
||||
@ -16,7 +16,8 @@ The module doesn't have its own LCD screen. It has a grill+fan underneath
|
||||
at the front part, and a heatsink on the CPU.
|
||||
|
||||
TODO:
|
||||
- skeleton device, missing SPARClite emulation, maybe only needs the MMU?
|
||||
- runs too slow? opening book moves take around 3 seconds, but on the real
|
||||
device less than 1 second
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
@ -34,15 +35,31 @@ DEFINE_DEVICE_TYPE(OSA_SPARC, saitekosa_sparc_device, "osa_sparc", "Sparc")
|
||||
saitekosa_sparc_device::saitekosa_sparc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
||||
device_t(mconfig, OSA_SPARC, tag, owner, clock),
|
||||
device_saitekosa_expansion_interface(mconfig, *this),
|
||||
m_maincpu(*this, "maincpu")
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_rom(*this, "maincpu"),
|
||||
m_ram(*this, "ram")
|
||||
{ }
|
||||
|
||||
void saitekosa_sparc_device::device_start()
|
||||
{
|
||||
m_rom_mask = m_rom.length() - 1;
|
||||
set_ram_mask(20); // 1MB default
|
||||
|
||||
// register for savestates
|
||||
save_item(NAME(m_data_out));
|
||||
save_item(NAME(m_rom_mask));
|
||||
save_item(NAME(m_ram_mask));
|
||||
save_item(NAME(m_installed));
|
||||
}
|
||||
|
||||
void saitekosa_sparc_device::device_reset()
|
||||
{
|
||||
if (!m_installed)
|
||||
{
|
||||
// MAME doesn't allow reading ioport at device_start
|
||||
set_ram_mask(ioport("RAM")->read() ? 22 : 20);
|
||||
m_installed = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -81,6 +98,23 @@ const tiny_rom_entry *saitekosa_sparc_device::device_rom_region() const
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// input_ports - device-specific input ports
|
||||
//-------------------------------------------------
|
||||
|
||||
static INPUT_PORTS_START( sparc )
|
||||
PORT_START("RAM")
|
||||
PORT_CONFNAME( 0x01, 0x00, "RAM Size" )
|
||||
PORT_CONFSETTING( 0x00, "1MB" )
|
||||
PORT_CONFSETTING( 0x01, "4MB" )
|
||||
INPUT_PORTS_END
|
||||
|
||||
ioport_constructor saitekosa_sparc_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME(sparc);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_add_mconfig - add device configuration
|
||||
//-------------------------------------------------
|
||||
@ -88,11 +122,13 @@ const tiny_rom_entry *saitekosa_sparc_device::device_rom_region() const
|
||||
void saitekosa_sparc_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
// basic machine hardware
|
||||
#if 0
|
||||
SPARCV8(config, m_maincpu, 20_MHz_XTAL);
|
||||
m_maincpu->set_addrmap(0, &saitekosa_sparc_device::main_map);
|
||||
m_maincpu->set_mmu(nullptr);
|
||||
#endif
|
||||
MB86930(config, m_maincpu, 20_MHz_XTAL);
|
||||
m_maincpu->set_addrmap(0x00, &saitekosa_sparc_device::debugger_map);
|
||||
m_maincpu->cs0_read_cb().set(FUNC(saitekosa_sparc_device::rom_r));
|
||||
m_maincpu->cs2_read_cb().set(FUNC(saitekosa_sparc_device::ram_r));
|
||||
m_maincpu->cs2_write_cb().set(FUNC(saitekosa_sparc_device::ram_w));
|
||||
m_maincpu->cs3_read_cb().set(FUNC(saitekosa_sparc_device::host_io_r));
|
||||
m_maincpu->cs3_write_cb().set(FUNC(saitekosa_sparc_device::host_io_w));
|
||||
}
|
||||
|
||||
|
||||
@ -100,8 +136,26 @@ void saitekosa_sparc_device::device_add_mconfig(machine_config &config)
|
||||
// internal i/o
|
||||
//-------------------------------------------------
|
||||
|
||||
void saitekosa_sparc_device::main_map(address_map &map)
|
||||
u32 saitekosa_sparc_device::host_io_r(offs_t offset, u32 mem_mask)
|
||||
{
|
||||
// d0-d7: data input latch, d8: ACK-P
|
||||
return m_expansion->data_state() | (m_expansion->ack_state() ? 0 : 0x100);
|
||||
}
|
||||
|
||||
void saitekosa_sparc_device::host_io_w(offs_t offset, u32 data, u32 mem_mask)
|
||||
{
|
||||
// d0-d7: data output latch, d10: output latch enable
|
||||
COMBINE_DATA(&m_data_out);
|
||||
|
||||
// d8: STB-P, d9: RTS-P
|
||||
m_expansion->stb_w(BIT(m_data_out, 8));
|
||||
m_expansion->rts_w(BIT(~m_data_out, 9));
|
||||
}
|
||||
|
||||
void saitekosa_sparc_device::debugger_map(address_map &map)
|
||||
{
|
||||
map(0x00000000, 0x0003ffff).rom().region("maincpu", 0);
|
||||
map(0x01000000, 0x013fffff).ram().share("ram"); // 4MB
|
||||
}
|
||||
|
||||
|
||||
@ -111,5 +165,16 @@ void saitekosa_sparc_device::main_map(address_map &map)
|
||||
|
||||
u8 saitekosa_sparc_device::data_r()
|
||||
{
|
||||
return 0xff;
|
||||
return (m_data_out & 0x400) ? 0xff : (u8)m_data_out;
|
||||
}
|
||||
|
||||
void saitekosa_sparc_device::nmi_w(int state)
|
||||
{
|
||||
m_maincpu->set_input_line(SPARC_IRQ1, !state ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
void saitekosa_sparc_device::ack_w(int state)
|
||||
{
|
||||
if (state != m_expansion->ack_state())
|
||||
machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(100));
|
||||
}
|
||||
|
@ -24,21 +24,37 @@ public:
|
||||
// construction/destruction
|
||||
saitekosa_sparc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
static constexpr feature_type unemulated_features() { return feature::COMMS; }
|
||||
|
||||
// from host
|
||||
virtual u8 data_r() override;
|
||||
virtual void nmi_w(int state) override;
|
||||
virtual void ack_w(int state) override;
|
||||
|
||||
protected:
|
||||
virtual const tiny_rom_entry *device_rom_region() const override;
|
||||
virtual ioport_constructor device_input_ports() const override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
optional_device<sparcv8_device> m_maincpu;
|
||||
required_device<mb86930_device> m_maincpu;
|
||||
required_region_ptr<u32> m_rom;
|
||||
required_shared_ptr<u32> m_ram;
|
||||
|
||||
void main_map(address_map &map);
|
||||
void debugger_map(address_map &map);
|
||||
|
||||
u32 rom_r(offs_t offset, u32 mem_mask) { return m_rom[offset & m_rom_mask]; }
|
||||
u32 ram_r(offs_t offset, u32 mem_mask) { return m_ram[offset & m_ram_mask]; }
|
||||
void ram_w(offs_t offset, u32 data, u32 mem_mask) { COMBINE_DATA(&m_ram[offset & m_ram_mask]); }
|
||||
u32 host_io_r(offs_t offset, u32 mem_mask = ~0U);
|
||||
void host_io_w(offs_t offset, u32 data, u32 mem_mask = ~0U);
|
||||
|
||||
void set_ram_mask(u8 n) { m_ram_mask = ((1 << n) / 4) - 1; }
|
||||
|
||||
u32 m_data_out = 0;
|
||||
u32 m_rom_mask = 0;
|
||||
u32 m_ram_mask = 0;
|
||||
bool m_installed = false;
|
||||
};
|
||||
|
||||
#endif // MAME_BUS_SAITEKOSA_SPARC_H
|
||||
|
@ -1005,12 +1005,12 @@ void mb86930_device::wait_specifier_w(offs_t offset, uint32_t data, uint32_t mem
|
||||
COMBINE_DATA(&m_wssr[offset]);
|
||||
|
||||
const uint32_t wait_idx = (offset << 1);
|
||||
const bool wait_en0 = BIT(m_wssr[offset], 21) && !BIT(m_wssr[offset], 20);
|
||||
const bool wait_en1 = BIT(m_wssr[offset], 8) && !BIT(m_wssr[offset], 7);
|
||||
m_other_page_waits[wait_idx] = wait_en0 ? (((m_wssr[offset] >> 27) & 0x1f) + 1) : 0;
|
||||
m_same_page_waits[wait_idx] = wait_en0 ? (((m_wssr[offset] >> 22) & 0x1f) + 1) : 0;
|
||||
m_other_page_waits[wait_idx + 1] = wait_en1 ? (((m_wssr[offset] >> 14) & 0x1f) + 1) : 0;
|
||||
m_same_page_waits[wait_idx + 1] = wait_en1 ? (((m_wssr[offset] >> 9) & 0x1f) + 1) : 0;
|
||||
const bool wait_en0 = BIT(m_wssr[offset], 8) && !BIT(m_wssr[offset], 7);
|
||||
const bool wait_en1 = BIT(m_wssr[offset], 21) && !BIT(m_wssr[offset], 20);
|
||||
m_same_page_waits[wait_idx] = wait_en0 ? (((m_wssr[offset] >> 9) & 0x1f) + 1) : 0;
|
||||
m_other_page_waits[wait_idx] = wait_en0 ? (((m_wssr[offset] >> 14) & 0x1f) + 1) : 0;
|
||||
m_same_page_waits[wait_idx + 1] = wait_en1 ? (((m_wssr[offset] >> 22) & 0x1f) + 1) : 0;
|
||||
m_other_page_waits[wait_idx + 1] = wait_en1 ? (((m_wssr[offset] >> 27) & 0x1f) + 1) : 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -176,7 +176,7 @@ void leo_state::unk_w(u8 data)
|
||||
|
||||
void leo_state::exp_rts_w(int state)
|
||||
{
|
||||
// NAND with ACK-P (not used by module)
|
||||
// NAND with ACK-P (not used by chesscomputer?)
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,7 +23,7 @@ so a chessboard display + 7seg info. It's on a small drawer that can be
|
||||
pushed in to hide the chessboard display.
|
||||
|
||||
TODO:
|
||||
- fart noise at boot if maestroa module is inserted
|
||||
- fart noise at boot if maestroa or sparc module is inserted
|
||||
- make it a subdriver of saitek_leonardo.cpp? or too many differences
|
||||
- same TODO list as saitek_leonardo.cpp
|
||||
|
||||
@ -199,7 +199,7 @@ u8 ren_state::control_r()
|
||||
|
||||
void ren_state::exp_rts_w(int state)
|
||||
{
|
||||
// NAND with ACK-P (not used by module)
|
||||
// NAND with ACK-P (not used by chesscomputer?)
|
||||
}
|
||||
|
||||
|
||||
|
@ -561,14 +561,15 @@ static const dasm_table_entry dasm_table[] =
|
||||
{ "sm590", le, 0, []() -> util::disasm_interface * { return new sm590_disassembler; } },
|
||||
{ "sm5a", le, 0, []() -> util::disasm_interface * { return new sm5a_disassembler; } },
|
||||
{ "sm8500", le, 0, []() -> util::disasm_interface * { return new sm8500_disassembler; } },
|
||||
{ "sparcv7", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 7); } },
|
||||
{ "sparcv8", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 8); } },
|
||||
{ "sparcv9", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9); } },
|
||||
{ "sparcv9vis1", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_1); } },
|
||||
{ "sparcv9vis2", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_2); } },
|
||||
{ "sparcv9vis2p", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_2p); } },
|
||||
{ "sparcv9vis3", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_3); } },
|
||||
{ "sparcv9vis3b", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, 9, sparc_disassembler::vis_3b); } },
|
||||
{ "sparclite", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, sparc_disassembler::sparclite); } },
|
||||
{ "sparcv7", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, sparc_disassembler::v7); } },
|
||||
{ "sparcv8", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, sparc_disassembler::v8); } },
|
||||
{ "sparcv9", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, sparc_disassembler::v9); } },
|
||||
{ "sparcv9vis1", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, sparc_disassembler::v9, sparc_disassembler::vis_1); } },
|
||||
{ "sparcv9vis2", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, sparc_disassembler::v9, sparc_disassembler::vis_2); } },
|
||||
{ "sparcv9vis2p", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, sparc_disassembler::v9, sparc_disassembler::vis_2p); } },
|
||||
{ "sparcv9vis3", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, sparc_disassembler::v9, sparc_disassembler::vis_3); } },
|
||||
{ "sparcv9vis3b", be, 0, []() -> util::disasm_interface * { return new sparc_disassembler(nullptr, sparc_disassembler::v9, sparc_disassembler::vis_3b); } },
|
||||
{ "spc700", le, 0, []() -> util::disasm_interface * { return new spc700_disassembler; } },
|
||||
{ "ssem", le, 0, []() -> util::disasm_interface * { return new ssem_disassembler; } },
|
||||
{ "ssp1601", be, -1, []() -> util::disasm_interface * { return new ssp1601_disassembler; } },
|
||||
|
Loading…
Reference in New Issue
Block a user