mirror of
https://github.com/holub/mame
synced 2025-05-18 03:35:03 +03:00
395 lines
13 KiB
C
395 lines
13 KiB
C
/*********************************************************************
|
|
|
|
kcexp.c
|
|
|
|
KC85_2/3/4/5 expansion slot emulation
|
|
|
|
**********************************************************************
|
|
|
|
GND 1 30 GND
|
|
GND 2 31 GND
|
|
NC 3 32 NC
|
|
DB7 4 33 DB6
|
|
DB5 5 34 DB4
|
|
DB3 6 35 DB2
|
|
DB1 7 36 DB0
|
|
/WR 8 37 /RD
|
|
/WREQ 9 38 /IORQ
|
|
IEO 10 39 NC
|
|
AB14 11 40 AB15
|
|
AB12 12 41 AB13
|
|
AB10 13 42 AB11
|
|
AB8 14 43 AB9
|
|
/WAIT 15 44 /RFSH
|
|
AB6 16 45 AB7
|
|
AB4 17 46 AB5
|
|
AB2 18 47 AB3
|
|
AB0 19 48 AB1
|
|
/RESET 20 49 /BUSRQ
|
|
TATK 21 50 GND
|
|
/M1 22 51 /HALT
|
|
/NMI 23 52 /INT
|
|
MEO 24 53 MEI
|
|
/ZI 25 54 /BI
|
|
/NC 26 55 /HELL
|
|
/BUSAK 27 56 NC
|
|
VCC 28 57 NC
|
|
NC 29 58 NC
|
|
|
|
Slots are organized into a chain (MEI -> MEO) , the first module that
|
|
decode the address on bus, clear the MEO line for disable other modules
|
|
with less priority.
|
|
|
|
************************************************************************
|
|
|
|
Known KC85 modules
|
|
|
|
Name ID Control Emulated Description
|
|
|
|
M001 EF ---- ---M no Digital IN/OUT
|
|
M002 DA ---- ---M no PIO 3
|
|
M003 EE ---- ---M no V.24
|
|
M005 ---- ---- no User
|
|
M006 FC AA-- ---M yes BASIC for KC85/2 (16KB ROM)
|
|
M007 ---- ---- no Adapter
|
|
M008 ---- ---- no Joystick
|
|
M009 ED ---- ---M no TLCM Spracheingabe/Datenkompr
|
|
M010 E7 ---- ---M no ADU 1 (4 analog inputs)
|
|
M011 F6 AA-- --WM yes 64KB RAM
|
|
M012 FB AAA- ---M yes Texor (8KB ROM)
|
|
M021 ---- ---- no Joystick + Centronics
|
|
M022 F4 AA-- --WM yes 16KB RAM
|
|
M024 F5 AA-- --WM no 32KB RAM
|
|
M025 F7 AAA- ---M no User PROM 8KB
|
|
M026 FB AAA- ---M yes FORTH (8KB ROM)
|
|
M027 FB AAA- ---M yes Development (8KB ROM)
|
|
M028 FB AA-- ---M no 16KB EPROM(2x U2764)
|
|
M029 E3 ---- ---M no DAU 1 (2 analog outputs)
|
|
M030 DB AAA- ---M no EPROMER 8KB EPROM
|
|
M032 79 A-SS SSWM yes 256KB segmented RAM (16 segments of 16KB)
|
|
M033 01 AA0S ---M yes Typestar (8KB x 2 ROM)
|
|
M034 7A ASSS SSWM yes 512KB segmented RAM (32 segments of 16KB)
|
|
M035 7B SSSS SSWM yes 1MB segmented RAM (64 segments of 16KB)
|
|
M036 78 A--S SSWM yes 128KB segmented RAM (8 segments of 16KB)
|
|
M040 F8 AA-- ---M no User PROM 8/16KB
|
|
M045 70 AASS ---M no User 32KB segmented ROM (4 segments of 8KB)
|
|
M046 71 AASS -S-M no User 64KB segmented ROM (8 segments of 8KB)
|
|
M047 72 AASS SS-M no User 128KB segmented ROM (16 segments of 8KB)
|
|
M048 73 SSSS SS-M no User 256KB segmented ROM (16 segments of 16KB)
|
|
M051 EC ---- ---- no Scanner Module
|
|
M052 FD ---- ---- no USB + NET (TCP/IP)
|
|
M053 EE ---- ---M no RS-232
|
|
M061 ---- ---- no 3x E/A-Modul
|
|
M120 F0 AAA- --WM no 8KB CMOS-RAM
|
|
M122 F1 AA-- --WM no 16KB CMOS-RAM
|
|
M124 F2 AA-- --WM no 32KB CMOS-RAM
|
|
|
|
D001 ---- ---- yes Basis Device
|
|
D002 ---- ---- yes Bus driver expansion
|
|
D003 ---- ---- no PROM programmer for KC-PROM Module
|
|
D004 A7 --A- -K-M yes Floppy Disk Interface
|
|
D005 ---- ---- no Komfort-Tastatur for KC85/4
|
|
|
|
|
|
Control byte ID byte
|
|
A - Base Address 01 - Autostart modules
|
|
K - Power on/off 7x - Segmented memory
|
|
S - Active segment Dx/Ex - IN/OUT modules
|
|
W - Write enabled Fx - memory modules
|
|
M - Module enabled
|
|
|
|
Info taken from: http://www.mpm-kc85.de/html/ModulListe.htm
|
|
|
|
*********************************************************************/
|
|
|
|
#include "emu.h"
|
|
#include "kcexp.h"
|
|
#include "emuopts.h"
|
|
|
|
#define LOG 0
|
|
|
|
|
|
/***************************************************************************
|
|
PARAMETERS
|
|
***************************************************************************/
|
|
|
|
//**************************************************************************
|
|
// GLOBAL VARIABLES
|
|
//**************************************************************************
|
|
|
|
const device_type KCEXP_SLOT = &device_creator<kcexp_slot_device>;
|
|
const device_type KCCART_SLOT = &device_creator<kccart_slot_device>;
|
|
|
|
|
|
//**************************************************************************
|
|
// KC85 Expansion Interface
|
|
//**************************************************************************
|
|
|
|
//-------------------------------------------------
|
|
// device_kcexp_interface - constructor
|
|
//-------------------------------------------------
|
|
|
|
device_kcexp_interface::device_kcexp_interface(const machine_config &mconfig, device_t &device)
|
|
: device_slot_card_interface(mconfig, device)
|
|
{
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// ~device_kcexp_interface - destructor
|
|
//-------------------------------------------------
|
|
|
|
device_kcexp_interface::~device_kcexp_interface()
|
|
{
|
|
}
|
|
|
|
|
|
//**************************************************************************
|
|
// LIVE DEVICE
|
|
//**************************************************************************
|
|
|
|
//-------------------------------------------------
|
|
// kcexp_slot_device - constructor
|
|
//-------------------------------------------------
|
|
kcexp_slot_device::kcexp_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
|
device_t(mconfig, KCEXP_SLOT, "KC85 Expansion Slot", tag, owner, clock),
|
|
device_slot_interface(mconfig, *this)
|
|
{
|
|
}
|
|
|
|
kcexp_slot_device::kcexp_slot_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) :
|
|
device_t(mconfig, type, name, tag, owner, clock),
|
|
device_slot_interface(mconfig, *this)
|
|
{
|
|
}
|
|
|
|
void kcexp_slot_device::static_set_next_slot(device_t &device, const char *next_slot_tag)
|
|
{
|
|
kcexp_slot_device &kc_slot = dynamic_cast<kcexp_slot_device &>(device);
|
|
|
|
kc_slot.m_next_slot_tag = next_slot_tag;
|
|
}
|
|
|
|
//-------------------------------------------------
|
|
// kcexp_slot_device - destructor
|
|
//-------------------------------------------------
|
|
|
|
kcexp_slot_device::~kcexp_slot_device()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------
|
|
// device_start - device-specific startup
|
|
//-------------------------------------------------
|
|
|
|
void kcexp_slot_device::device_start()
|
|
{
|
|
m_cart = dynamic_cast<device_kcexp_interface *>(get_card_device());
|
|
m_next_slot = m_next_slot_tag ? owner()->subdevice<kcexp_slot_device>(m_next_slot_tag) : NULL;
|
|
|
|
// resolve callbacks
|
|
m_out_irq_func.resolve(m_out_irq_cb, *this);
|
|
m_out_nmi_func.resolve(m_out_nmi_cb, *this);
|
|
m_out_halt_func.resolve(m_out_halt_cb, *this);
|
|
}
|
|
|
|
//-------------------------------------------------
|
|
// device_config_complete - perform any
|
|
// operations now that the configuration is
|
|
// complete
|
|
//-------------------------------------------------
|
|
|
|
void kcexp_slot_device::device_config_complete()
|
|
{
|
|
// inherit a copy of the static data
|
|
const kcexp_interface *intf = reinterpret_cast<const kcexp_interface *>(static_config());
|
|
if (intf != NULL)
|
|
{
|
|
*static_cast<kcexp_interface *>(this) = *intf;
|
|
}
|
|
|
|
// or initialize to defaults if none provided
|
|
else
|
|
{
|
|
memset(&m_out_irq_cb, 0, sizeof(m_out_irq_cb));
|
|
memset(&m_out_nmi_cb, 0, sizeof(m_out_nmi_cb));
|
|
memset(&m_out_halt_cb, 0, sizeof(m_out_halt_cb));
|
|
}
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
module id read
|
|
-------------------------------------------------*/
|
|
|
|
UINT8 kcexp_slot_device::module_id_r()
|
|
{
|
|
UINT8 result = 0xff;
|
|
|
|
if (m_cart)
|
|
result = m_cart->module_id_r();
|
|
|
|
return result;
|
|
}
|
|
|
|
/*-------------------------------------------------
|
|
module control write
|
|
-------------------------------------------------*/
|
|
void kcexp_slot_device::control_w(UINT8 data)
|
|
{
|
|
if (m_cart)
|
|
m_cart->control_w(data);
|
|
}
|
|
|
|
/*-------------------------------------------------
|
|
read
|
|
-------------------------------------------------*/
|
|
|
|
void kcexp_slot_device::read(offs_t offset, UINT8 &data)
|
|
{
|
|
if (m_cart)
|
|
m_cart->read(offset, data);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
write
|
|
-------------------------------------------------*/
|
|
|
|
void kcexp_slot_device::write(offs_t offset, UINT8 data)
|
|
{
|
|
if (m_cart)
|
|
m_cart->write(offset, data);
|
|
}
|
|
|
|
/*-------------------------------------------------
|
|
IO read
|
|
-------------------------------------------------*/
|
|
|
|
void kcexp_slot_device::io_read(offs_t offset, UINT8 &data)
|
|
{
|
|
if (m_cart)
|
|
m_cart->io_read(offset, data);
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------
|
|
IO write
|
|
-------------------------------------------------*/
|
|
|
|
void kcexp_slot_device::io_write(offs_t offset, UINT8 data)
|
|
{
|
|
if (m_cart)
|
|
m_cart->io_write(offset, data);
|
|
}
|
|
|
|
/*-------------------------------------------------
|
|
MEI line write
|
|
-------------------------------------------------*/
|
|
|
|
WRITE_LINE_MEMBER( kcexp_slot_device::mei_w )
|
|
{
|
|
if (LOG) logerror("KCEXP '%s': %s MEI line\n", tag(), state != CLEAR_LINE ? "ASSERT": "CLEAR");
|
|
|
|
if (m_cart)
|
|
m_cart->mei_w(state);
|
|
}
|
|
|
|
/*-------------------------------------------------
|
|
MEO line write
|
|
-------------------------------------------------*/
|
|
|
|
WRITE_LINE_MEMBER( kcexp_slot_device::meo_w )
|
|
{
|
|
if (LOG) logerror("KCEXP '%s': %s MEO line\n", tag(), state != CLEAR_LINE ? "ASSERT": "CLEAR");
|
|
|
|
if (m_next_slot)
|
|
m_next_slot->mei_w(state);
|
|
}
|
|
|
|
|
|
//**************************************************************************
|
|
// KC85 Cartridges Interface
|
|
//**************************************************************************
|
|
|
|
//-------------------------------------------------
|
|
// kccart_slot_device - constructor
|
|
//-------------------------------------------------
|
|
kccart_slot_device::kccart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
|
kcexp_slot_device(mconfig, KCCART_SLOT, "KC85 Cartridge Slot", tag, owner, clock),
|
|
device_image_interface(mconfig, *this)
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------
|
|
// kccart_slot_device - destructor
|
|
//-------------------------------------------------
|
|
|
|
kccart_slot_device::~kccart_slot_device()
|
|
{
|
|
}
|
|
|
|
//-------------------------------------------------
|
|
// device_config_complete - perform any
|
|
// operations now that the configuration is
|
|
// complete
|
|
//-------------------------------------------------
|
|
|
|
void kccart_slot_device::device_config_complete()
|
|
{
|
|
kcexp_slot_device::device_config_complete();
|
|
|
|
// set brief and instance name
|
|
update_names();
|
|
}
|
|
|
|
/*-------------------------------------------------
|
|
call load
|
|
-------------------------------------------------*/
|
|
|
|
bool kccart_slot_device::call_load()
|
|
{
|
|
if (m_cart)
|
|
{
|
|
offs_t read_length = 0;
|
|
UINT8 *cart_base = m_cart->get_cart_base();
|
|
|
|
if (cart_base != NULL)
|
|
{
|
|
if (software_entry() == NULL)
|
|
{
|
|
read_length = length();
|
|
fread(m_cart->get_cart_base(), read_length);
|
|
}
|
|
else
|
|
{
|
|
read_length = get_software_region_length("rom");
|
|
memcpy(m_cart->get_cart_base(), get_software_region("rom"), read_length);
|
|
}
|
|
}
|
|
else
|
|
return IMAGE_INIT_FAIL;
|
|
}
|
|
|
|
return IMAGE_INIT_PASS;
|
|
}
|
|
|
|
/*-------------------------------------------------
|
|
call softlist load
|
|
-------------------------------------------------*/
|
|
|
|
bool kccart_slot_device::call_softlist_load(char *swlist, char *swname, rom_entry *start_entry)
|
|
{
|
|
load_software_part_region(this, swlist, swname, start_entry );
|
|
return TRUE;
|
|
}
|
|
|
|
/*-------------------------------------------------
|
|
get default card software
|
|
-------------------------------------------------*/
|
|
|
|
const char * kccart_slot_device::get_default_card_software(const machine_config &config, emu_options &options)
|
|
{
|
|
return software_get_default_slot(config, options, this, "standard");
|
|
}
|