mirror of
https://github.com/holub/mame
synced 2025-04-20 15:32:45 +03:00
ti99_2: Emulate the expansion port and a 32K expansion module.
This commit is contained in:
parent
4c0cfc7860
commit
dc91091959
@ -7,7 +7,12 @@
|
||||
This component implements the custom video controller and interface chip
|
||||
from the TI-99/2 console.
|
||||
|
||||
Also, we emulate the expansion port at the backside of the console; there
|
||||
are no known expansions except for a RAM expansion that is mentioned
|
||||
in the specifications.
|
||||
|
||||
May 2018
|
||||
June 2020
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
@ -20,8 +25,9 @@
|
||||
#define LOG_HEXBUS (1U<<4) // Hexbus logging
|
||||
#define LOG_BANK (1U<<5) // Change ROM banks
|
||||
#define LOG_KEYBOARD (1U<<6) // Keyboard operation
|
||||
#define LOG_EXPRAM (1U<<7) // Expansion RAM
|
||||
|
||||
#define VERBOSE ( LOG_WARN )
|
||||
#define VERBOSE ( LOG_GENERAL | LOG_WARN )
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
@ -128,6 +134,8 @@ DEFINE_DEVICE_TYPE_NS(VIDEO99232, bus::ti99::internal, video992_32_device, "vide
|
||||
DEFINE_DEVICE_TYPE_NS(IO99224, bus::ti99::internal, io992_24_device, "io992_24", "TI-99/2 I/O controller 24K version")
|
||||
DEFINE_DEVICE_TYPE_NS(IO99232, bus::ti99::internal, io992_32_device, "io992_32", "TI-99/2 I/O controller 32K version")
|
||||
|
||||
DEFINE_DEVICE_TYPE_NS(TI992_EXPPORT, bus::ti99::internal, ti992_expport_device, "ti992_expport", "TI-99/2 Expansion Port")
|
||||
DEFINE_DEVICE_TYPE_NS(TI992_RAM32K, bus::ti99::internal, ti992_expram_device, "ti992_ram32k", "TI-99/2 RAM Expansion 32K")
|
||||
|
||||
namespace bus { namespace ti99 { namespace internal {
|
||||
|
||||
@ -596,6 +604,82 @@ ioport_constructor io992_device::device_input_ports() const
|
||||
return INPUT_PORTS_NAME( keys992 );
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Expansion port
|
||||
********************************************************************/
|
||||
|
||||
ti992_expport_device::ti992_expport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, TI992_EXPPORT, tag, owner, clock),
|
||||
device_slot_interface(mconfig, *this),
|
||||
m_connected(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void ti992_expport_device::readz(offs_t offset, uint8_t *value)
|
||||
{
|
||||
if (m_connected != nullptr)
|
||||
m_connected->readz(offset, value);
|
||||
}
|
||||
|
||||
void ti992_expport_device::write(offs_t offset, uint8_t data)
|
||||
{
|
||||
if (m_connected != nullptr)
|
||||
m_connected->write(offset, data);
|
||||
}
|
||||
|
||||
void ti992_expport_device::device_config_complete()
|
||||
{
|
||||
m_connected = static_cast<ti992_expport_attached_device*>(subdevices().first());
|
||||
}
|
||||
|
||||
/*
|
||||
32K Expansion cartridge
|
||||
Maps at 6000 - DFFF
|
||||
This is the only known expansion device
|
||||
*/
|
||||
ti992_expram_device::ti992_expram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
ti992_expport_attached_device(mconfig, TI992_RAM32K, tag, owner, clock),
|
||||
m_ram(*this, "ram32k")
|
||||
{
|
||||
}
|
||||
|
||||
void ti992_expram_device::readz(offs_t offset, uint8_t *value)
|
||||
{
|
||||
// 000 -> 100 100 -> 000
|
||||
// 001 -> 101 101 -> 001
|
||||
// 010 -> 110 110 -> 010
|
||||
// 011 -> 011 111 -> 111
|
||||
offs_t address = offset;
|
||||
if ((offset & 0x6000) != 0x6000) address ^= 0x8000;
|
||||
if ((address & 0x8000)==0)
|
||||
{
|
||||
*value = m_ram->read(address);
|
||||
LOGMASKED(LOG_EXPRAM, "expram %04x -> %02x\n", offset, *value);
|
||||
}
|
||||
}
|
||||
|
||||
void ti992_expram_device::write(offs_t offset, uint8_t value)
|
||||
{
|
||||
offs_t address = offset;
|
||||
if ((offset & 0x6000) != 0x6000) address ^= 0x8000;
|
||||
if ((address & 0x8000)==0)
|
||||
{
|
||||
m_ram->write(address, value);
|
||||
LOGMASKED(LOG_EXPRAM, "expram %04x <- %02x\n", offset, value);
|
||||
}
|
||||
}
|
||||
|
||||
void ti992_expram_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
RAM(config, m_ram, 0);
|
||||
m_ram->set_default_size("32k");
|
||||
m_ram->set_default_value(0);
|
||||
}
|
||||
|
||||
} } }
|
||||
|
||||
void ti992_expport_options(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("ram32k", TI992_RAM32K);
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "screen.h"
|
||||
#include "bus/hexbus/hexbus.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "machine/ram.h"
|
||||
|
||||
#define TI992_CASSETTE "cassette"
|
||||
#define TI992_VDC_TAG "vdc"
|
||||
@ -149,11 +150,87 @@ public:
|
||||
io992_32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
/********************************************************************
|
||||
|
||||
Expansion port
|
||||
This is modeled after the ioport connector of the TI-99/4A
|
||||
|
||||
However, since there are basically no expansion cards available,
|
||||
and only the memory expansion was described in the specs, we
|
||||
only include the necessary connections.
|
||||
|
||||
********************************************************************/
|
||||
#define TI992_EXPPORT_TAG "expport"
|
||||
|
||||
class ti992_expport_attached_device : public device_t
|
||||
{
|
||||
public:
|
||||
ti992_expport_attached_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, type, tag, owner, clock)
|
||||
{ }
|
||||
|
||||
// Methods called from the console
|
||||
virtual void readz(offs_t offset, uint8_t *value) { }
|
||||
virtual void write(offs_t offset, uint8_t data) { }
|
||||
};
|
||||
|
||||
class ti992_expport_device : public device_t, public device_slot_interface
|
||||
{
|
||||
friend class expport_attached_device;
|
||||
|
||||
public:
|
||||
template <typename U>
|
||||
ti992_expport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, U &&opts, const char *dflt)
|
||||
: ti992_expport_device(mconfig, tag, owner, clock)
|
||||
{
|
||||
option_reset();
|
||||
opts(*this);
|
||||
set_default_option(dflt);
|
||||
set_fixed(false);
|
||||
}
|
||||
|
||||
ti992_expport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// Methods called from the console
|
||||
// More methods should be added, once we can find further 99/2 cartridges
|
||||
void readz(offs_t offset, uint8_t *value);
|
||||
void write(offs_t offset, uint8_t data);
|
||||
|
||||
protected:
|
||||
void device_start() override { };
|
||||
void device_config_complete() override;
|
||||
|
||||
private:
|
||||
ti992_expport_attached_device* m_connected;
|
||||
};
|
||||
|
||||
// RAM expansion
|
||||
|
||||
class ti992_expram_device : public ti992_expport_attached_device
|
||||
{
|
||||
public:
|
||||
ti992_expram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
void readz(offs_t offset, uint8_t *value) override;
|
||||
void write(offs_t offset, uint8_t data) override;
|
||||
|
||||
private:
|
||||
void device_start() override {};
|
||||
void device_add_mconfig(machine_config &config) override;
|
||||
required_device<ram_device> m_ram;
|
||||
};
|
||||
|
||||
|
||||
} } } // end namespace bus::ti99::internal
|
||||
|
||||
DECLARE_DEVICE_TYPE_NS(TI992_EXPPORT, bus::ti99::internal, ti992_expport_device)
|
||||
|
||||
void ti992_expport_options(device_slot_interface &device);
|
||||
|
||||
DECLARE_DEVICE_TYPE_NS(VIDEO99224, bus::ti99::internal, video992_24_device)
|
||||
DECLARE_DEVICE_TYPE_NS(VIDEO99232, bus::ti99::internal, video992_32_device)
|
||||
DECLARE_DEVICE_TYPE_NS(IO99224, bus::ti99::internal, io992_24_device)
|
||||
DECLARE_DEVICE_TYPE_NS(IO99232, bus::ti99::internal, io992_32_device)
|
||||
|
||||
DECLARE_DEVICE_TYPE_NS(TI992_RAM32K, bus::ti99::internal, ti992_expram_device)
|
||||
|
||||
#endif // MAME_BUS_TI99_INTERNAL_992BOARD_H
|
||||
|
@ -193,6 +193,7 @@ public:
|
||||
m_io992(*this, TI992_IO_TAG),
|
||||
m_cassette(*this, TI992_CASSETTE),
|
||||
m_ram(*this, TI992_RAM_TAG),
|
||||
m_expport(*this, TI992_EXPPORT_TAG),
|
||||
m_otherbank(false),
|
||||
m_rom(nullptr),
|
||||
m_ram_start(0xf000),
|
||||
@ -230,6 +231,8 @@ private:
|
||||
required_device<cassette_image_device> m_cassette;
|
||||
required_device<ram_device> m_ram;
|
||||
|
||||
required_device<bus::ti99::internal::ti992_expport_device> m_expport;
|
||||
|
||||
bool m_otherbank;
|
||||
|
||||
uint8_t* m_rom;
|
||||
@ -322,6 +325,7 @@ void ti99_2_state::intflag_write(offs_t offset, uint8_t data)
|
||||
*/
|
||||
uint8_t ti99_2_state::mem_read(offs_t offset)
|
||||
{
|
||||
uint8_t value = 0;
|
||||
if (m_maincpu->is_onchip(offset)) return m_maincpu->debug_read_onchip_memory(offset&0xff);
|
||||
|
||||
int page = offset >> 12;
|
||||
@ -329,22 +333,23 @@ uint8_t ti99_2_state::mem_read(offs_t offset)
|
||||
if (page>=0 && page<4)
|
||||
{
|
||||
// ROM, unbanked
|
||||
return m_rom[offset];
|
||||
value = m_rom[offset];
|
||||
}
|
||||
if (page>=4 && page<6)
|
||||
{
|
||||
// ROM, banked on 32K version
|
||||
if (m_otherbank) offset = (offset & 0x1fff) | 0x10000;
|
||||
return m_rom[offset];
|
||||
value = m_rom[offset];
|
||||
}
|
||||
|
||||
if ((page >= m_first_ram_page) && (page < 15))
|
||||
{
|
||||
return m_ram->pointer()[offset - m_ram_start];
|
||||
value = m_ram->pointer()[offset - m_ram_start];
|
||||
}
|
||||
|
||||
LOGMASKED(LOG_WARN, "Unmapped read access at %04x\n", offset);
|
||||
return 0;
|
||||
m_expport->readz(offset, &value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void ti99_2_state::mem_write(offs_t offset, uint8_t data)
|
||||
@ -370,7 +375,7 @@ void ti99_2_state::mem_write(offs_t offset, uint8_t data)
|
||||
return;
|
||||
}
|
||||
|
||||
LOGMASKED(LOG_WARN, "Unmapped write access at %04x\n", offset);
|
||||
m_expport->write(offset, data);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -470,6 +475,9 @@ void ti99_2_state::ti99_2(machine_config& config)
|
||||
|
||||
// Hexbus
|
||||
HEXBUS(config, TI992_HEXBUS_TAG, 0, hexbus_options, nullptr);
|
||||
|
||||
// Expansion port (backside)
|
||||
TI992_EXPPORT(config, m_expport, 0, ti992_expport_options, nullptr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user