mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
ti99: Added CorComp disk controller cards.
This commit is contained in:
parent
a1546a423b
commit
91b633c363
@ -3142,6 +3142,8 @@ if (BUSES["TI99"]~=null) then
|
||||
MAME_DIR .. "src/devices/bus/ti99/peb/peribox.h",
|
||||
MAME_DIR .. "src/devices/bus/ti99/peb/bwg.cpp",
|
||||
MAME_DIR .. "src/devices/bus/ti99/peb/bwg.h",
|
||||
MAME_DIR .. "src/devices/bus/ti99/peb/cc_fdc.cpp",
|
||||
MAME_DIR .. "src/devices/bus/ti99/peb/cc_fdc.h",
|
||||
MAME_DIR .. "src/devices/bus/ti99/peb/evpc.cpp",
|
||||
MAME_DIR .. "src/devices/bus/ti99/peb/evpc.h",
|
||||
MAME_DIR .. "src/devices/bus/ti99/peb/hfdc.cpp",
|
||||
|
@ -25,7 +25,7 @@
|
||||
#define LOG_GROM (1U<<8) // GROM access
|
||||
#define LOG_RPK (1U<<9) // RPK handler
|
||||
|
||||
#define VERBOSE ( LOG_WARN )
|
||||
#define VERBOSE ( LOG_GENERAL | LOG_WARN )
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE_NS(TI99_CART, bus::ti99::gromport, ti99_cartridge_device, "ti99cart", "TI-99 cartridge")
|
||||
@ -634,7 +634,7 @@ void ti99_paged12k_cartridge::write(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_rom_page = (offset >> 1) & 1;
|
||||
if ((offset & 1)==0)
|
||||
LOGMASKED(LOG_WARN, "Set ROM page = %d (writing to %04x)\n", m_rom_page, (offset | 0x6000));
|
||||
LOGMASKED(LOG_BANKSWITCH, "Set ROM page = %d (writing to %04x)\n", m_rom_page, (offset | 0x6000));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -429,7 +429,7 @@
|
||||
#define LOG_MAPPER (1U<<16)
|
||||
|
||||
// Minimum log should be warnings
|
||||
#define VERBOSE ( LOG_GENERAL | LOG_SETTING | LOG_WARN )
|
||||
#define VERBOSE ( LOG_GENERAL | LOG_WARN )
|
||||
|
||||
#include "genboard.h"
|
||||
#include "logmacro.h"
|
||||
@ -527,7 +527,7 @@ WRITE8_MEMBER( geneve_gate_array_device::cru_ctrl_write )
|
||||
m_cartridge7_writable = (data!=0);
|
||||
break;
|
||||
case 15:
|
||||
LOGMASKED(LOG_SETTING, "Extra wait states %s\n", (data==0)? "enabled" : "disabled");
|
||||
LOGMASKED(LOG_CRU, "Extra wait states %s\n", (data==0)? "enabled" : "disabled");
|
||||
m_enable_extra_waitstates = (data==0);
|
||||
break;
|
||||
default:
|
||||
|
829
src/devices/bus/ti99/peb/cc_fdc.cpp
Normal file
829
src/devices/bus/ti99/peb/cc_fdc.cpp
Normal file
@ -0,0 +1,829 @@
|
||||
// license:LGPL-2.1+
|
||||
// copyright-holders:Michael Zapf
|
||||
/*******************************************************************************
|
||||
CorComp Disk Controller
|
||||
Based on WD2793/WD1773
|
||||
Double Density, Double-sided
|
||||
|
||||
Two flavors:
|
||||
|
||||
* Original controller
|
||||
Named "PEB-DCC"
|
||||
Single 16K EPROM or two 8K EPROMs (selectable by jumper; only 2x8K emulated)
|
||||
Two PALs
|
||||
WD2793
|
||||
|
||||
* Modified controller with redesigned PCB
|
||||
Named "CorComp FDC Rev A"
|
||||
Two 8K EPROMs (by Millers Graphics, 3rd party HW/SW contributor)
|
||||
Two PALs
|
||||
WD1773
|
||||
|
||||
Michael Zapf
|
||||
March 2020
|
||||
|
||||
*******************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cc_fdc.h"
|
||||
#include "formats/ti99_dsk.h"
|
||||
#include "machine/rescap.h"
|
||||
|
||||
// ----------------------------------
|
||||
// Flags for debugging
|
||||
|
||||
#define LOG_WARN (1U<<1) // Warnings
|
||||
#define LOG_CONFIG (1U<<2) // Configuration
|
||||
#define LOG_EPROM (1U<<3) // Access to EPROM
|
||||
#define LOG_CONTR (1U<<4) // Access to controller
|
||||
#define LOG_RAM (1U<<5) // Access to SRAM
|
||||
#define LOG_READY (1U<<6) // READY line
|
||||
#define LOG_SIGNALS (1U<<7) // IRQ and HLD lines
|
||||
#define LOG_DRQ (1U<<8) // DRQ line (too noisy in SIGNALS)
|
||||
#define LOG_DRIVE (1U<<9) // Drive operations
|
||||
#define LOG_CRU (1U<<10) // CRU operations
|
||||
|
||||
#define VERBOSE ( LOG_GENERAL | LOG_WARN | LOG_CONFIG )
|
||||
#include "logmacro.h"
|
||||
|
||||
#define CCDCC_TAG "ti99_ccdcc"
|
||||
#define CCFDC_TAG "ti99_ccfdc"
|
||||
#define WDC_TAG "wdfdc"
|
||||
#define MOTORMF_TAG "motor_mf"
|
||||
#define TMS9901_TAG "tms9901"
|
||||
|
||||
#define CCDCC_PALU2_TAG "palu2"
|
||||
#define CCDCC_PALU1_TAG "palu1"
|
||||
#define CCFDC_PALU12_TAG "palu12"
|
||||
#define CCFDC_PALU6_TAG "palu6"
|
||||
|
||||
#define BUFFER "ram"
|
||||
|
||||
DEFINE_DEVICE_TYPE_NS(TI99_CCDCC, bus::ti99::peb, corcomp_dcc_device, CCDCC_TAG, "CorComp Disk Controller Card")
|
||||
DEFINE_DEVICE_TYPE_NS(TI99_CCFDC, bus::ti99::peb, corcomp_fdca_device, CCFDC_TAG, "CorComp Floppy Disk Controller Card Rev A")
|
||||
|
||||
DEFINE_DEVICE_TYPE_NS(CCDCC_PALU2, bus::ti99::peb, ccdcc_palu2_device, CCDCC_PALU2_TAG, "CorComp DCC PAL u2")
|
||||
DEFINE_DEVICE_TYPE_NS(CCDCC_PALU1, bus::ti99::peb, ccdcc_palu1_device, CCDCC_PALU1_TAG, "CorComp DCC PAL u1")
|
||||
|
||||
DEFINE_DEVICE_TYPE_NS(CCFDC_PALU12, bus::ti99::peb, ccfdc_palu12_device, CCFDC_PALU12_TAG, "CorComp FDC PAL u12")
|
||||
DEFINE_DEVICE_TYPE_NS(CCFDC_PALU6, bus::ti99::peb, ccfdc_palu6_device, CCFDC_PALU6_TAG, "CorComp FDC PAL u6")
|
||||
|
||||
namespace bus { namespace ti99 { namespace peb {
|
||||
|
||||
// ----------------------------------
|
||||
|
||||
corcomp_fdc_device::corcomp_fdc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock):
|
||||
device_t(mconfig, type, tag, owner, clock),
|
||||
device_ti99_peribox_card_interface(mconfig, *this),
|
||||
m_wdc(*this, WDC_TAG),
|
||||
m_decpal(nullptr),
|
||||
m_ctrlpal(nullptr),
|
||||
m_motormf(*this, MOTORMF_TAG),
|
||||
m_tms9901(*this, TMS9901_TAG),
|
||||
m_buffer_ram(*this, BUFFER),
|
||||
m_dsrrom(nullptr),
|
||||
m_cardsel(false),
|
||||
m_banksel(false),
|
||||
m_selected_drive(0),
|
||||
m_address(0),
|
||||
m_writing(false)
|
||||
{
|
||||
}
|
||||
|
||||
SETADDRESS_DBIN_MEMBER( corcomp_fdc_device::setaddress_dbin )
|
||||
{
|
||||
// Do not allow setaddress for debugger
|
||||
if (machine().side_effects_disabled()) return;
|
||||
m_address = offset;
|
||||
m_writing = (state==CLEAR_LINE);
|
||||
operate_ready_line();
|
||||
}
|
||||
|
||||
/*
|
||||
Provides the current address to the PALs.
|
||||
*/
|
||||
uint16_t corcomp_fdc_device::get_address()
|
||||
{
|
||||
return m_address;
|
||||
}
|
||||
|
||||
/*
|
||||
Before the 9901 configures the P11 pin as output, it delivers Z output,
|
||||
which is pulled down by R10 on the board. We implement this by using a
|
||||
variable.
|
||||
*/
|
||||
bool corcomp_fdc_device::upper_bank()
|
||||
{
|
||||
return m_banksel;
|
||||
}
|
||||
|
||||
bool corcomp_fdc_device::card_selected()
|
||||
{
|
||||
return m_cardsel;
|
||||
}
|
||||
|
||||
bool corcomp_fdc_device::write_access()
|
||||
{
|
||||
return m_writing;
|
||||
}
|
||||
|
||||
/*
|
||||
The Debugging access must not have any side effect on the controller.
|
||||
We only allow access to the EPROM and RAM.
|
||||
*/
|
||||
void corcomp_fdc_device::debug_read(offs_t offset, uint8_t* value)
|
||||
{
|
||||
uint16_t saveaddress = m_address;
|
||||
|
||||
m_address = offset;
|
||||
*value = 0x00;
|
||||
|
||||
if (m_ctrlpal->selectram())
|
||||
{
|
||||
// SRAM selected
|
||||
*value = m_buffer_ram->pointer()[m_address & 0x7f] & 0xf0; // only the first 4 bits
|
||||
}
|
||||
|
||||
if (m_ctrlpal->selectdsr())
|
||||
{
|
||||
// EPROM selected
|
||||
uint16_t base = m_banksel? 0x2000 : 0;
|
||||
uint8_t* rom = &m_dsrrom[base | (m_address & 0x1fff)];
|
||||
*value = *rom;
|
||||
}
|
||||
m_address = saveaddress;
|
||||
}
|
||||
|
||||
void corcomp_fdc_device::debug_write(offs_t offset, uint8_t data)
|
||||
{
|
||||
uint16_t saveaddress = m_address;
|
||||
m_address = offset;
|
||||
if (m_ctrlpal->selectram())
|
||||
{
|
||||
m_buffer_ram->pointer()[m_address & 0x7f] = data & 0xf0; // only the first 4 bits
|
||||
}
|
||||
m_address = saveaddress;
|
||||
}
|
||||
|
||||
/*
|
||||
Operate the wait state logic.
|
||||
*/
|
||||
void corcomp_fdc_device::operate_ready_line()
|
||||
{
|
||||
line_state ready = (line_state)m_ctrlpal->ready_out();
|
||||
m_slot->set_ready(ready);
|
||||
}
|
||||
|
||||
/*
|
||||
Callbacks from the WDC chip
|
||||
*/
|
||||
WRITE_LINE_MEMBER( corcomp_fdc_device::fdc_irq_w )
|
||||
{
|
||||
LOGMASKED(LOG_SIGNALS, "INTRQ callback = %d\n", state);
|
||||
operate_ready_line();
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( corcomp_fdc_device::fdc_drq_w )
|
||||
{
|
||||
LOGMASKED(LOG_DRQ, "DRQ callback = %d\n", state);
|
||||
operate_ready_line();
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( corcomp_fdc_device::fdc_hld_w )
|
||||
{
|
||||
LOGMASKED(LOG_SIGNALS, "HLD callback = %d\n", state);
|
||||
}
|
||||
|
||||
READ8Z_MEMBER(corcomp_fdc_device::readz)
|
||||
{
|
||||
if (machine().side_effects_disabled())
|
||||
{
|
||||
debug_read(offset, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ctrlpal->selectram())
|
||||
{
|
||||
// SRAM selected
|
||||
*value = m_buffer_ram->pointer()[m_address & 0x7f] & 0xf0; // only the first 4 bits
|
||||
LOGMASKED(LOG_RAM, "Read RAM: %04x -> %02x\n", m_address & 0xffff, *value);
|
||||
}
|
||||
|
||||
if (m_ctrlpal->selectwdc())
|
||||
{
|
||||
// WDC selected
|
||||
*value = m_wdc->read((m_address >> 1)&0x03);
|
||||
LOGMASKED(LOG_CONTR, "Read FDC: %04x -> %02x\n", m_address & 0xffff, *value);
|
||||
}
|
||||
|
||||
if (m_ctrlpal->selectdsr())
|
||||
{
|
||||
// EPROM selected
|
||||
uint16_t base = m_banksel? 0x2000 : 0;
|
||||
uint8_t* rom = &m_dsrrom[base | (m_address & 0x1fff)];
|
||||
*value = *rom;
|
||||
|
||||
if (WORD_ALIGNED(m_address))
|
||||
{
|
||||
uint16_t val = (*rom << 8) | (*(rom+1));
|
||||
LOGMASKED(LOG_EPROM, "Read DSR: %04x (page %d)-> %04x\n", m_address & 0xffff, base>>13, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void corcomp_fdc_device::write(offs_t offset, uint8_t data)
|
||||
{
|
||||
if (machine().side_effects_disabled())
|
||||
{
|
||||
debug_write(offset, data);
|
||||
return;
|
||||
}
|
||||
if (m_ctrlpal->selectram())
|
||||
{
|
||||
// SRAM selected
|
||||
LOGMASKED(LOG_RAM, "Write RAM: %04x <- %02x\n", m_address & 0xffff, data&0xf0);
|
||||
m_buffer_ram->pointer()[m_address & 0x7f] = data & 0xf0; // only the first 4 bits
|
||||
}
|
||||
|
||||
if (m_ctrlpal->selectwdc())
|
||||
{
|
||||
// WDC selected
|
||||
LOGMASKED(LOG_CONTR, "Write FDC: %04x <- %02x\n", m_address & 0xffff, data);
|
||||
m_wdc->write((m_address >> 1)&0x03, data);
|
||||
}
|
||||
}
|
||||
|
||||
READ8Z_MEMBER( corcomp_fdc_device::crureadz )
|
||||
{
|
||||
m_address = offset; // Copy the CRU address on the address variable
|
||||
if (m_decpal->address9901())
|
||||
{
|
||||
// The S0 select line is inverted, which means that
|
||||
// a CRU address of 0x1120 is actually address 0x00 for the 9901,
|
||||
// while the CRU address 0x1100 is 0x20 for the 9901.
|
||||
// This trick is necessary to relocate the P0 line to the
|
||||
// first CRU address, which by convention turns on the EPROM
|
||||
// of the card.
|
||||
int bitno = ((offset & 0x3e)^0x20)>>1;
|
||||
*value = m_tms9901->read_bit(bitno)? 0x01 : 0x00;
|
||||
LOGMASKED(LOG_CRU, "cru %04x (bit %d) -> %d\n", offset, bitno, *value);
|
||||
}
|
||||
}
|
||||
|
||||
void corcomp_fdc_device::cruwrite(offs_t offset, uint8_t data)
|
||||
{
|
||||
m_address = offset; // Copy the CRU address on the address variable
|
||||
if (m_decpal->address9901())
|
||||
{
|
||||
int bitno = ((offset & 0x3e)^0x20)>>1;
|
||||
LOGMASKED(LOG_CRU, "cru %04x (bit %d) <- %d\n", offset, bitno, data);
|
||||
m_tms9901->write_bit(bitno, data!=0);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( corcomp_fdc_device::clock_in )
|
||||
{
|
||||
m_tms9901->phi_line(state);
|
||||
}
|
||||
|
||||
READ8_MEMBER( corcomp_fdc_device::tms9901_input )
|
||||
{
|
||||
// Inputs
|
||||
// INT1: Switch 8
|
||||
// INT2: Switch 1
|
||||
// INT3: Switch 7
|
||||
// INT4: Switch 5
|
||||
// INT5: Switch 3
|
||||
// INT6: Switch 2
|
||||
// INT7: Switch 4
|
||||
// INT8: Switch 6
|
||||
// INT9: -
|
||||
// P9: MotorMF
|
||||
// P12: WDCu11.28 (HLD)
|
||||
const uint8_t dipswitch[] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case tms9901_device::INT1:
|
||||
return ((ioport("HEADSTEP")->read() & dipswitch[8])!=0)? 0:1;
|
||||
case tms9901_device::INT2:
|
||||
return ((ioport("HEADSTEP")->read() & dipswitch[1])!=0)? 0:1;
|
||||
case tms9901_device::INT3:
|
||||
return ((ioport("HEADSTEP")->read() & dipswitch[7])!=0)? 0:1;
|
||||
case tms9901_device::INT4:
|
||||
return ((ioport("HEADSTEP")->read() & dipswitch[5])!=0)? 0:1;
|
||||
case tms9901_device::INT5:
|
||||
return ((ioport("HEADSTEP")->read() & dipswitch[3])!=0)? 0:1;
|
||||
case tms9901_device::INT6:
|
||||
return ((ioport("HEADSTEP")->read() & dipswitch[2])!=0)? 0:1;
|
||||
case tms9901_device::INT7_P15:
|
||||
return ((ioport("HEADSTEP")->read() & dipswitch[4])!=0)? 0:1;
|
||||
case tms9901_device::INT8_P14:
|
||||
return ((ioport("HEADSTEP")->read() & dipswitch[6])!=0)? 0:1;
|
||||
case tms9901_device::INT10_P12:
|
||||
return (m_wdc->hld_r()==ASSERT_LINE)? 1:0;
|
||||
case tms9901_device::INT13_P9:
|
||||
return (m_motormf->q_r()==0)? 1:0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( corcomp_fdc_device::select_dsk )
|
||||
{
|
||||
if (state == CLEAR_LINE)
|
||||
{
|
||||
if ( (!m_tms9901->read_bit(tms9901_device::P4))
|
||||
&& (!m_tms9901->read_bit(tms9901_device::P5))
|
||||
&& (!m_tms9901->read_bit(tms9901_device::P6))
|
||||
&& (!m_tms9901->read_bit(tms9901_device::INT14_P8)))
|
||||
{
|
||||
LOGMASKED(LOG_DRIVE, "Unselect all drives\n");
|
||||
m_wdc->set_floppy(nullptr);
|
||||
m_selected_drive = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_tms9901->read_bit(tms9901_device::P4))
|
||||
{
|
||||
m_selected_drive = 1;
|
||||
}
|
||||
else if (m_tms9901->read_bit(tms9901_device::P5))
|
||||
{
|
||||
m_selected_drive = 2;
|
||||
}
|
||||
else if (m_tms9901->read_bit(tms9901_device::P6))
|
||||
{
|
||||
m_selected_drive = 3;
|
||||
}
|
||||
else if (m_tms9901->read_bit(tms9901_device::INT14_P8))
|
||||
{
|
||||
m_selected_drive = 4;
|
||||
}
|
||||
LOGMASKED(LOG_DRIVE, "Select drive DSK%d\n", m_selected_drive);
|
||||
|
||||
if (m_floppy[m_selected_drive-1] != nullptr)
|
||||
{
|
||||
m_wdc->set_floppy(m_floppy[m_selected_drive-1]);
|
||||
m_floppy[m_selected_drive-1]->ss_w(m_tms9901->read_bit(tms9901_device::INT15_P7));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( corcomp_fdc_device::side_select )
|
||||
{
|
||||
// Select side of disk (bit 7)
|
||||
if (m_selected_drive != 0)
|
||||
{
|
||||
LOGMASKED(LOG_DRIVE, "Set side (bit 7) = %d on DSK%d\n", state, m_selected_drive);
|
||||
m_floppy[m_selected_drive-1]->ss_w(state);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
All floppy motors are operated by the same line.
|
||||
*/
|
||||
WRITE_LINE_MEMBER( corcomp_fdc_device::motor_w )
|
||||
{
|
||||
LOGMASKED(LOG_DRIVE, "Motor %s\n", state? "on" : "off");
|
||||
m_wdc->set_force_ready(state==ASSERT_LINE);
|
||||
|
||||
// Set all motors
|
||||
for (auto & elem : m_floppy)
|
||||
if (elem != nullptr) elem->mon_w((state==ASSERT_LINE)? 0 : 1);
|
||||
operate_ready_line();
|
||||
}
|
||||
|
||||
/*
|
||||
Push the P11 state to the variable.
|
||||
*/
|
||||
WRITE_LINE_MEMBER( corcomp_fdc_device::select_bank )
|
||||
{
|
||||
LOGMASKED(LOG_CRU, "Set bank %d\n", state);
|
||||
m_banksel = (state==ASSERT_LINE);
|
||||
operate_ready_line();
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( corcomp_fdc_device::select_card )
|
||||
{
|
||||
LOGMASKED(LOG_CRU, "Select card = %d\n", state);
|
||||
m_cardsel = (state==ASSERT_LINE);
|
||||
operate_ready_line();
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
|
||||
void corcomp_fdc_device::device_start()
|
||||
{
|
||||
m_dsrrom = memregion(TI99_DSRROM)->base();
|
||||
save_item(NAME(m_address));
|
||||
save_item(NAME(m_writing));
|
||||
save_item(NAME(m_cardsel));
|
||||
save_item(NAME(m_banksel));
|
||||
save_item(NAME(m_selected_drive));
|
||||
}
|
||||
|
||||
void corcomp_fdc_device::device_reset()
|
||||
{
|
||||
for (int i=0; i < 4; i++)
|
||||
{
|
||||
if (m_floppy[i] != nullptr)
|
||||
LOGMASKED(LOG_CONFIG, "Connector %d with %s\n", i, m_floppy[i]->name());
|
||||
else
|
||||
LOGMASKED(LOG_CONFIG, "Connector %d has no floppy attached\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
void corcomp_fdc_device::connect_drives()
|
||||
{
|
||||
for (auto & elem : m_floppy)
|
||||
elem = nullptr;
|
||||
|
||||
if (subdevice("0")!=nullptr) m_floppy[0] = static_cast<floppy_image_device*>(subdevice("0")->subdevices().first());
|
||||
if (subdevice("1")!=nullptr) m_floppy[1] = static_cast<floppy_image_device*>(subdevice("1")->subdevices().first());
|
||||
if (subdevice("2")!=nullptr) m_floppy[2] = static_cast<floppy_image_device*>(subdevice("2")->subdevices().first());
|
||||
if (subdevice("3")!=nullptr) m_floppy[3] = static_cast<floppy_image_device*>(subdevice("3")->subdevices().first());
|
||||
}
|
||||
|
||||
INPUT_PORTS_START( cc_fdc )
|
||||
PORT_START( "HEADSTEP" )
|
||||
PORT_DIPNAME( 0x03, 0x00, "DSK1 head step time" )
|
||||
PORT_DIPSETTING( 0x00, "15 ms")
|
||||
PORT_DIPSETTING( 0x01, "10 ms")
|
||||
PORT_DIPSETTING( 0x02, "6 ms")
|
||||
PORT_DIPSETTING( 0x03, "3 ms")
|
||||
PORT_DIPNAME( 0x0c, 0x00, "DSK2 head step time" )
|
||||
PORT_DIPSETTING( 0x00, "15 ms")
|
||||
PORT_DIPSETTING( 0x04, "10 ms")
|
||||
PORT_DIPSETTING( 0x08, "6 ms")
|
||||
PORT_DIPSETTING( 0x0c, "3 ms")
|
||||
PORT_DIPNAME( 0x30, 0x00, "DSK3 head step time" )
|
||||
PORT_DIPSETTING( 0x00, "15 ms")
|
||||
PORT_DIPSETTING( 0x10, "10 ms")
|
||||
PORT_DIPSETTING( 0x20, "6 ms")
|
||||
PORT_DIPSETTING( 0x30, "3 ms")
|
||||
PORT_DIPNAME( 0xc0, 0x00, "DSK4 head step time" )
|
||||
PORT_DIPSETTING( 0x00, "15 ms")
|
||||
PORT_DIPSETTING( 0x40, "10 ms")
|
||||
PORT_DIPSETTING( 0x80, "6 ms")
|
||||
PORT_DIPSETTING( 0xc0, "3 ms")
|
||||
INPUT_PORTS_END
|
||||
|
||||
FLOPPY_FORMATS_MEMBER(corcomp_fdc_device::floppy_formats)
|
||||
FLOPPY_TI99_SDF_FORMAT,
|
||||
FLOPPY_TI99_TDF_FORMAT
|
||||
FLOPPY_FORMATS_END
|
||||
|
||||
static void ccfdc_floppies(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("525dd", FLOPPY_525_DD); // 40 tracks
|
||||
device.option_add("525qd", FLOPPY_525_QD); // 80 tracks
|
||||
device.option_add("35dd", FLOPPY_35_DD); // 80 tracks
|
||||
}
|
||||
|
||||
void corcomp_fdc_device::common_config(machine_config& config)
|
||||
{
|
||||
m_wdc->intrq_wr_callback().set(FUNC(corcomp_fdc_device::fdc_irq_w));
|
||||
m_wdc->drq_wr_callback().set(FUNC(corcomp_fdc_device::fdc_drq_w));
|
||||
m_wdc->hld_wr_callback().set(FUNC(corcomp_fdc_device::fdc_hld_w));
|
||||
|
||||
TMS9901(config, m_tms9901, 0);
|
||||
m_tms9901->read_cb().set(FUNC(corcomp_fdc_device::tms9901_input));
|
||||
|
||||
// Outputs
|
||||
// P0: LED (DSR?), PALu2.1
|
||||
// P1: MFu6.clk (Motor)
|
||||
// P2: PALu1.5 (WATEN)
|
||||
// P3: WDCu11.50 (HLT)
|
||||
// P4: DSK1 select
|
||||
// P5: DSK2 select
|
||||
// P6: DSK3 select
|
||||
// P7: SIDSEL
|
||||
// P8: DSK4 select
|
||||
// P10: WDCu11.37 (DDEN)
|
||||
// P11: ROMBNK
|
||||
// P13: -
|
||||
// P14: -
|
||||
// P15: -
|
||||
m_tms9901->p_out_cb(0).set(FUNC(corcomp_fdc_device::select_card));
|
||||
m_tms9901->p_out_cb(1).set(MOTORMF_TAG, FUNC(ttl74123_device::b_w));
|
||||
m_tms9901->p_out_cb(4).set(FUNC(corcomp_fdc_device::select_dsk));
|
||||
m_tms9901->p_out_cb(5).set(FUNC(corcomp_fdc_device::select_dsk));
|
||||
m_tms9901->p_out_cb(6).set(FUNC(corcomp_fdc_device::select_dsk));
|
||||
m_tms9901->p_out_cb(7).set(FUNC(corcomp_fdc_device::side_select));
|
||||
m_tms9901->p_out_cb(8).set(FUNC(corcomp_fdc_device::select_dsk));
|
||||
m_tms9901->p_out_cb(10).set(WDC_TAG, FUNC(wd_fdc_device_base::dden_w));
|
||||
m_tms9901->p_out_cb(11).set(FUNC(corcomp_fdc_device::select_bank));
|
||||
|
||||
// Motor monoflop
|
||||
TTL74123(config, m_motormf, 0);
|
||||
m_motormf->set_connection_type(TTL74123_NOT_GROUNDED_NO_DIODE);
|
||||
m_motormf->set_resistor_value(RES_K(100));
|
||||
m_motormf->set_capacitor_value(CAP_U(47));
|
||||
m_motormf->set_a_pin_value(0);
|
||||
m_motormf->set_b_pin_value(1);
|
||||
m_motormf->set_clear_pin_value(1);
|
||||
m_motormf->out_cb().set(FUNC(corcomp_fdc_device::motor_w));
|
||||
|
||||
FLOPPY_CONNECTOR(config, "0", ccfdc_floppies, "525dd", corcomp_fdc_device::floppy_formats).enable_sound(true);
|
||||
FLOPPY_CONNECTOR(config, "1", ccfdc_floppies, "525dd", corcomp_fdc_device::floppy_formats).enable_sound(true);
|
||||
FLOPPY_CONNECTOR(config, "2", ccfdc_floppies, nullptr, corcomp_fdc_device::floppy_formats).enable_sound(true);
|
||||
FLOPPY_CONNECTOR(config, "3", ccfdc_floppies, nullptr, corcomp_fdc_device::floppy_formats).enable_sound(true);
|
||||
|
||||
// SRAM 2114 1Kx4
|
||||
RAM(config, BUFFER).set_default_size("1k").set_default_value(0);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Original CorComp Disk Controller Card (PEB-DCC)
|
||||
// ============================================================================
|
||||
|
||||
corcomp_dcc_device::corcomp_dcc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock):
|
||||
corcomp_fdc_device(mconfig, TI99_CCDCC, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void corcomp_dcc_device::device_add_mconfig(machine_config& config)
|
||||
{
|
||||
WD2793(config, m_wdc, 4_MHz_XTAL / 4);
|
||||
common_config(config);
|
||||
|
||||
// For the 2793, attach the HLT line
|
||||
m_tms9901->p_out_cb(3).set(WDC_TAG, FUNC(wd_fdc_device_base::hlt_w));
|
||||
|
||||
// PAL circuits are connected in device_config_complete
|
||||
CCDCC_PALU2(config, CCDCC_PALU2_TAG, 0);
|
||||
CCDCC_PALU1(config, CCDCC_PALU1_TAG, 0);
|
||||
}
|
||||
|
||||
ROM_START( cc_dcc )
|
||||
ROM_REGION(0x4000, TI99_DSRROM, 0)
|
||||
ROM_LOAD("ccdcc_v89.u3", 0x0000, 0x2000, CRC(de3f9476) SHA1(b88aea1141769dad4e4bea5f93ac4f63a627cc82)) /* 8K single ROM bank 1*/
|
||||
ROM_LOAD("ccdcc_v89.u4", 0x2000, 0x2000, CRC(9c4e5c08) SHA1(26f8096ae60f3839902b4e8764c5fde283ad4ba2)) /* 8K single ROM bank 2*/
|
||||
ROM_END
|
||||
|
||||
void corcomp_dcc_device::device_config_complete()
|
||||
{
|
||||
m_decpal = static_cast<ccfdc_dec_pal_device*>(subdevice(CCDCC_PALU2_TAG));
|
||||
m_ctrlpal = static_cast<ccfdc_sel_pal_device*>(subdevice(CCDCC_PALU1_TAG));
|
||||
connect_drives();
|
||||
}
|
||||
|
||||
ioport_constructor corcomp_fdc_device::device_input_ports() const
|
||||
{
|
||||
return INPUT_PORTS_NAME( cc_fdc );
|
||||
}
|
||||
|
||||
const tiny_rom_entry *corcomp_dcc_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME( cc_dcc );
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// PAL circuits on the CorComp board
|
||||
// ========================================================================
|
||||
|
||||
ccfdc_dec_pal_device::ccfdc_dec_pal_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, type, tag, owner, clock),
|
||||
m_board(nullptr),
|
||||
m_tms9901(*owner, TMS9901_TAG)
|
||||
{
|
||||
}
|
||||
|
||||
ccfdc_sel_pal_device::ccfdc_sel_pal_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, type, tag, owner, clock),
|
||||
m_board(nullptr),
|
||||
m_decpal(nullptr),
|
||||
m_motormf(*owner, MOTORMF_TAG),
|
||||
m_tms9901(*owner, TMS9901_TAG),
|
||||
m_wdc(*owner, WDC_TAG)
|
||||
{
|
||||
}
|
||||
|
||||
void ccfdc_dec_pal_device::device_config_complete()
|
||||
{
|
||||
m_board = static_cast<corcomp_fdc_device*>(owner());
|
||||
}
|
||||
|
||||
/*
|
||||
Indicates 9901 addressing.
|
||||
*/
|
||||
READ_LINE_MEMBER( ccfdc_dec_pal_device::address9901 )
|
||||
{
|
||||
return ((m_board->get_address() & 0xff80)==0x1100)? ASSERT_LINE : CLEAR_LINE;
|
||||
}
|
||||
|
||||
/*
|
||||
Indicates SRAM addressing.
|
||||
*/
|
||||
READ_LINE_MEMBER( ccfdc_dec_pal_device::addressram )
|
||||
{
|
||||
return ((m_board->card_selected()) &&
|
||||
(m_board->get_address() & 0xff80)==0x4000)? ASSERT_LINE : CLEAR_LINE;
|
||||
}
|
||||
|
||||
/*
|
||||
Indicates WDC addressing.
|
||||
*/
|
||||
READ_LINE_MEMBER( ccfdc_dec_pal_device::addresswdc )
|
||||
{
|
||||
return ((m_board->card_selected()) &&
|
||||
(m_board->get_address() & 0xff80)==0x5f80)? ASSERT_LINE : CLEAR_LINE;
|
||||
}
|
||||
|
||||
/*
|
||||
Indicates DSR addressing.
|
||||
*/
|
||||
READ_LINE_MEMBER( ccfdc_dec_pal_device::address4 )
|
||||
{
|
||||
return ((m_board->card_selected()) &&
|
||||
(m_board->get_address() & 0xe000)==0x4000)? ASSERT_LINE : CLEAR_LINE;
|
||||
}
|
||||
|
||||
/*
|
||||
Indicates SRAM selection.
|
||||
*/
|
||||
READ_LINE_MEMBER( ccfdc_sel_pal_device::selectram )
|
||||
{
|
||||
return (m_decpal->addressram() && (m_board->upper_bank()))
|
||||
? ASSERT_LINE : CLEAR_LINE;
|
||||
}
|
||||
|
||||
/*
|
||||
Indicates WDC selection.
|
||||
*/
|
||||
READ_LINE_MEMBER( ccfdc_sel_pal_device::selectwdc )
|
||||
{
|
||||
return (m_decpal->addresswdc() && ((m_board->get_address()&1)==0))? ASSERT_LINE : CLEAR_LINE;
|
||||
}
|
||||
|
||||
/*
|
||||
Indicates EPROM selection.
|
||||
*/
|
||||
READ_LINE_MEMBER( ccfdc_sel_pal_device::selectdsr )
|
||||
{
|
||||
return (m_decpal->address4()
|
||||
&& !m_decpal->addresswdc()
|
||||
&& !(m_decpal->addressram() && (m_board->upper_bank())))
|
||||
? ASSERT_LINE : CLEAR_LINE;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// PAL circuits on the original CorComp board
|
||||
// PAL u2 is the address decoder, delivering its results to the
|
||||
// selector PAL u1.
|
||||
// ========================================================================
|
||||
|
||||
ccdcc_palu2_device::ccdcc_palu2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ccfdc_dec_pal_device(mconfig, CCDCC_PALU2, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
ccdcc_palu1_device::ccdcc_palu1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ccfdc_sel_pal_device(mconfig, CCDCC_PALU1, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
Wait state logic
|
||||
*/
|
||||
READ_LINE_MEMBER( ccdcc_palu1_device::ready_out )
|
||||
{
|
||||
bool wdc = m_decpal->addresswdc(); // Addressing the WDC
|
||||
bool lastdig = (m_board->get_address()&7)==6; // Address ends with 6 or e (5ff6, 5ffe)
|
||||
bool trap = m_tms9901->read_bit(tms9901_device::P2); // Wait state generation is active (SBO 2)
|
||||
bool waitbyte = m_wdc->drq_r()==CLEAR_LINE; // We are waiting for a byte
|
||||
bool noterm = m_wdc->intrq_r()==CLEAR_LINE; // There is no interrupt yet
|
||||
bool motor = (m_motormf->q_r()==1); // The disk is spinning
|
||||
|
||||
line_state ready = (wdc && lastdig && trap && waitbyte && noterm && motor)? CLEAR_LINE : ASSERT_LINE; // then clear READY and thus trigger wait states
|
||||
|
||||
LOGMASKED(LOG_READY, "READY = %d (%d,%d,%d,%d,%d,%d)\n", ready, wdc, lastdig, trap, waitbyte, noterm, motor);
|
||||
return ready;
|
||||
}
|
||||
|
||||
void ccdcc_palu1_device::device_config_complete()
|
||||
{
|
||||
m_board = static_cast<corcomp_fdc_device*>(owner());
|
||||
m_decpal = static_cast<ccfdc_dec_pal_device*>(owner()->subdevice(CCDCC_PALU2_TAG));
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Revised CorComp floppy disk controller card REV A
|
||||
// ============================================================================
|
||||
|
||||
corcomp_fdca_device::corcomp_fdca_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock):
|
||||
corcomp_fdc_device(mconfig, TI99_CCFDC, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void corcomp_fdca_device::device_add_mconfig(machine_config& config)
|
||||
{
|
||||
WD1773(config, m_wdc, 8_MHz_XTAL);
|
||||
common_config(config);
|
||||
|
||||
// PAL circuits are connected in device_config_complete
|
||||
CCFDC_PALU12(config, CCFDC_PALU12_TAG, 0);
|
||||
CCFDC_PALU6(config, CCFDC_PALU6_TAG, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
READY trap circuitry on the revised board (U10)
|
||||
*/
|
||||
bool corcomp_fdca_device::ready_trap_active()
|
||||
{
|
||||
return m_tms9901->read_bit(tms9901_device::P2)
|
||||
&& ((m_address & 6)==6)
|
||||
&& (m_motormf->q_r()==1);
|
||||
}
|
||||
|
||||
ROM_START( cc_fdcmg )
|
||||
ROM_REGION(0x8000, TI99_DSRROM, 0)
|
||||
ROM_LOAD("ccfdc_v89mg.u1", 0x0000, 0x2000, CRC(f010e273) SHA1(bd30103d80c43d4b35e0669145cef7b5c6b9813b)) /* 16K single ROM */
|
||||
ROM_LOAD("ccfdc_v89mg.u2", 0x2000, 0x2000, CRC(0cad8f5b) SHA1(7744f777b51eedf614f766576bbc3f8c2c2e0042)) /* 16K single ROM */
|
||||
ROM_END
|
||||
|
||||
void corcomp_fdca_device::device_config_complete()
|
||||
{
|
||||
m_decpal = static_cast<ccfdc_dec_pal_device*>(subdevice(CCFDC_PALU12_TAG));
|
||||
m_ctrlpal = static_cast<ccfdc_sel_pal_device*>(subdevice(CCFDC_PALU6_TAG));
|
||||
connect_drives();
|
||||
}
|
||||
|
||||
const tiny_rom_entry *corcomp_fdca_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME( cc_fdcmg );
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// PAL circuits on the revised CorComp board
|
||||
// PAL u12 is the address decoder, delivering its results to the
|
||||
// selector PAL u6.
|
||||
// ========================================================================
|
||||
|
||||
ccfdc_palu12_device::ccfdc_palu12_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ccfdc_dec_pal_device(mconfig, CCFDC_PALU12, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
Indicates 9901 addressing. In this PAL version, the A9 address line is
|
||||
also used.
|
||||
*/
|
||||
READ_LINE_MEMBER( ccfdc_palu12_device::address9901 )
|
||||
{
|
||||
return ((m_board->get_address() & 0xffc0)==0x1100)? ASSERT_LINE : CLEAR_LINE;
|
||||
}
|
||||
|
||||
ccfdc_palu6_device::ccfdc_palu6_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: ccfdc_sel_pal_device(mconfig, CCFDC_PALU6, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
Indicates WDC selection. Also checks whether A12 and /WE match.
|
||||
That is, when writing (/WE=0), A12 must be 1 (addresses 5ff8..e),
|
||||
otherwise (/WE=1), A12 must be 0 (addresses 5ff0..6)
|
||||
*/
|
||||
READ_LINE_MEMBER( ccfdc_palu6_device::selectwdc )
|
||||
{
|
||||
return (m_decpal->addresswdc()
|
||||
&& ((m_board->get_address()&1)==0)
|
||||
&& (((m_board->get_address()&8)!=0)==(m_board->write_access())))? ASSERT_LINE : CLEAR_LINE;
|
||||
}
|
||||
|
||||
/*
|
||||
Indicates EPROM selection. The Rev A selector PAL leads back some of
|
||||
its outputs for this calculation.
|
||||
*/
|
||||
READ_LINE_MEMBER( ccfdc_palu6_device::selectdsr )
|
||||
{
|
||||
return (m_decpal->address4() && !selectwdc() && !selectram())? ASSERT_LINE : CLEAR_LINE;
|
||||
}
|
||||
|
||||
/*
|
||||
Wait state logic. The Rev A selector relies on an AND circuit on the
|
||||
board which evaluates whether the trap is active.
|
||||
*/
|
||||
|
||||
READ_LINE_MEMBER( ccfdc_palu6_device::ready_out )
|
||||
{
|
||||
bool wdc = m_decpal->addresswdc(); // Addressing the WDC
|
||||
bool even = (m_board->get_address()&1)==0; // A15 = 0
|
||||
bool trap = static_cast<corcomp_fdca_device*>(m_board)->ready_trap_active(); // READY trap active
|
||||
bool waitbyte = m_wdc->drq_r()==CLEAR_LINE; // We are waiting for a byte
|
||||
bool noterm = m_wdc->intrq_r()==CLEAR_LINE; // There is no interrupt yet
|
||||
|
||||
line_state ready = (wdc && even && trap && waitbyte && noterm)? CLEAR_LINE : ASSERT_LINE; // then clear READY and thus trigger wait states
|
||||
|
||||
LOGMASKED(LOG_READY, "READY = %d (%d,%d,%d,%d,%d)\n", ready, wdc, even, trap, waitbyte, noterm);
|
||||
return ready;
|
||||
}
|
||||
|
||||
void ccfdc_palu6_device::device_config_complete()
|
||||
{
|
||||
m_board = static_cast<corcomp_fdca_device*>(owner());
|
||||
m_decpal = static_cast<ccfdc_dec_pal_device*>(owner()->subdevice(CCFDC_PALU12_TAG));
|
||||
}
|
||||
} } } // end namespace bus::ti99::peb
|
252
src/devices/bus/ti99/peb/cc_fdc.h
Normal file
252
src/devices/bus/ti99/peb/cc_fdc.h
Normal file
@ -0,0 +1,252 @@
|
||||
// license:LGPL-2.1+
|
||||
// copyright-holders:Michael Zapf
|
||||
/****************************************************************************
|
||||
|
||||
Corcomp Disk Controller
|
||||
Based on WD2793/WD1773
|
||||
Double Density, Double-sided
|
||||
|
||||
Michael Zapf, March 2020
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAME_BUS_TI99_PEB_CORCOMP_H
|
||||
#define MAME_BUS_TI99_PEB_CORCOMP_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "peribox.h"
|
||||
#include "imagedev/floppy.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
#include "machine/74123.h"
|
||||
#include "machine/tms9901.h"
|
||||
#include "machine/ram.h"
|
||||
|
||||
namespace bus { namespace ti99 { namespace peb {
|
||||
|
||||
class ccfdc_dec_pal_device;
|
||||
class ccfdc_sel_pal_device;
|
||||
class ccfdc_palu12_device;
|
||||
class ccfdc_palu6_device;
|
||||
|
||||
class corcomp_fdc_device : public device_t, public device_ti99_peribox_card_interface
|
||||
{
|
||||
friend class ccfdc_dec_pal_device;
|
||||
friend class ccfdc_sel_pal_device;
|
||||
friend class ccdcc_palu1_device;
|
||||
friend class ccfdc_palu6_device;
|
||||
friend class ccfdc_palu12_device;
|
||||
|
||||
public:
|
||||
DECLARE_READ8Z_MEMBER(readz) override;
|
||||
void write(offs_t offset, uint8_t data) override;
|
||||
DECLARE_SETADDRESS_DBIN_MEMBER(setaddress_dbin) override;
|
||||
|
||||
DECLARE_READ8Z_MEMBER(crureadz) override;
|
||||
void cruwrite(offs_t offset, uint8_t data) override;
|
||||
DECLARE_WRITE_LINE_MEMBER(clock_in) override;
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( fdc_irq_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( fdc_drq_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( fdc_hld_w );
|
||||
DECLARE_READ8_MEMBER( tms9901_input );
|
||||
DECLARE_WRITE_LINE_MEMBER( select_dsk );
|
||||
DECLARE_WRITE_LINE_MEMBER( side_select );
|
||||
DECLARE_WRITE_LINE_MEMBER( motor_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( select_card );
|
||||
DECLARE_WRITE_LINE_MEMBER( select_bank );
|
||||
|
||||
protected:
|
||||
corcomp_fdc_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void device_start() override;
|
||||
void device_reset() override;
|
||||
void connect_drives();
|
||||
|
||||
virtual void device_add_mconfig(machine_config &config) override =0;
|
||||
ioport_constructor device_input_ports() const override;
|
||||
|
||||
void common_config(machine_config& config);
|
||||
|
||||
DECLARE_FLOPPY_FORMATS( floppy_formats );
|
||||
|
||||
// Link to the WD controller on the board.
|
||||
required_device<wd_fdc_device_base> m_wdc;
|
||||
|
||||
// PALs
|
||||
ccfdc_dec_pal_device* m_decpal;
|
||||
ccfdc_sel_pal_device* m_ctrlpal;
|
||||
|
||||
// Lines that are polled by the PAL chips
|
||||
bool card_selected();
|
||||
bool upper_bank();
|
||||
bool write_access();
|
||||
bool ready_trap_active();
|
||||
|
||||
// Deliver the current state of the address bus
|
||||
uint16_t get_address();
|
||||
|
||||
// Wait state logic
|
||||
void operate_ready_line();
|
||||
|
||||
// Link to the attached floppy drives
|
||||
floppy_image_device* m_floppy[4];
|
||||
|
||||
// Motor monoflop
|
||||
required_device<ttl74123_device> m_motormf;
|
||||
|
||||
// Interface chip
|
||||
required_device<tms9901_device> m_tms9901;
|
||||
|
||||
// Debugger accessors
|
||||
void debug_read(offs_t offset, uint8_t* value);
|
||||
void debug_write(offs_t offset, uint8_t data);
|
||||
|
||||
// Buffer RAM
|
||||
required_device<ram_device> m_buffer_ram;
|
||||
|
||||
// DSR ROM
|
||||
uint8_t* m_dsrrom;
|
||||
|
||||
// State of the bank select line. Pulled down initially.
|
||||
bool m_cardsel;
|
||||
bool m_banksel;
|
||||
|
||||
// Selected drive
|
||||
int m_selected_drive;
|
||||
|
||||
// Recent address
|
||||
int m_address;
|
||||
|
||||
// Write access
|
||||
bool m_writing;
|
||||
};
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// Original CorComp disk controller card
|
||||
// ============================================================================
|
||||
|
||||
class corcomp_dcc_device : public corcomp_fdc_device
|
||||
{
|
||||
public:
|
||||
corcomp_dcc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
private:
|
||||
void device_add_mconfig(machine_config &config) override;
|
||||
void device_config_complete() override;
|
||||
const tiny_rom_entry *device_rom_region() const override;
|
||||
};
|
||||
|
||||
// =========== Decoder PAL circuit ================
|
||||
class ccfdc_dec_pal_device : public device_t
|
||||
{
|
||||
public:
|
||||
DECLARE_READ_LINE_MEMBER(addresswdc);
|
||||
DECLARE_READ_LINE_MEMBER(address4);
|
||||
DECLARE_READ_LINE_MEMBER(addressram);
|
||||
virtual DECLARE_READ_LINE_MEMBER(address9901);
|
||||
|
||||
protected:
|
||||
ccfdc_dec_pal_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void device_start() override { };
|
||||
void device_config_complete() override;
|
||||
|
||||
corcomp_fdc_device* m_board;
|
||||
required_device<tms9901_device> m_tms9901;
|
||||
};
|
||||
|
||||
// =========== Selector PAL circuit ================
|
||||
|
||||
class ccfdc_sel_pal_device : public device_t
|
||||
{
|
||||
public:
|
||||
DECLARE_READ_LINE_MEMBER(selectram);
|
||||
virtual DECLARE_READ_LINE_MEMBER(selectwdc);
|
||||
virtual DECLARE_READ_LINE_MEMBER(selectdsr);
|
||||
virtual DECLARE_READ_LINE_MEMBER(ready_out) =0;
|
||||
|
||||
protected:
|
||||
ccfdc_sel_pal_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
void device_start() override { };
|
||||
virtual void device_config_complete() override =0;
|
||||
|
||||
corcomp_fdc_device* m_board;
|
||||
ccfdc_dec_pal_device* m_decpal;
|
||||
required_device<ttl74123_device> m_motormf;
|
||||
required_device<tms9901_device> m_tms9901;
|
||||
required_device<wd_fdc_device_base> m_wdc;
|
||||
};
|
||||
|
||||
// =========== Specific decoder PAL circuit of the CCDCC ================
|
||||
|
||||
class ccdcc_palu2_device : public ccfdc_dec_pal_device
|
||||
{
|
||||
public:
|
||||
ccdcc_palu2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
// =========== Specific selector PAL circuit of the CCDCC ================
|
||||
|
||||
class ccdcc_palu1_device : public ccfdc_sel_pal_device
|
||||
{
|
||||
public:
|
||||
ccdcc_palu1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
DECLARE_READ_LINE_MEMBER(ready_out) override;
|
||||
|
||||
private:
|
||||
void device_config_complete() override;
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Revised CorComp floppy disk controller card rev a
|
||||
// ============================================================================
|
||||
|
||||
class corcomp_fdca_device : public corcomp_fdc_device
|
||||
{
|
||||
friend class ccfdc_palu6_device;
|
||||
|
||||
public:
|
||||
corcomp_fdca_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
private:
|
||||
void device_add_mconfig(machine_config &config) override;
|
||||
void device_config_complete() override;
|
||||
const tiny_rom_entry *device_rom_region() const override;
|
||||
bool ready_trap_active();
|
||||
};
|
||||
|
||||
// =========== Specific decoder PAL circuit of the CCFDC ================
|
||||
|
||||
class ccfdc_palu12_device : public ccfdc_dec_pal_device
|
||||
{
|
||||
public:
|
||||
ccfdc_palu12_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
DECLARE_READ_LINE_MEMBER(address9901) override;
|
||||
};
|
||||
|
||||
// =========== Specific selector PAL circuit of the CCFDC ================
|
||||
|
||||
class ccfdc_palu6_device : public ccfdc_sel_pal_device
|
||||
{
|
||||
public:
|
||||
ccfdc_palu6_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
DECLARE_READ_LINE_MEMBER(selectwdc) override;
|
||||
DECLARE_READ_LINE_MEMBER(selectdsr) override;
|
||||
|
||||
DECLARE_READ_LINE_MEMBER(ready_out) override;
|
||||
|
||||
private:
|
||||
void device_config_complete() override;
|
||||
};
|
||||
|
||||
} } } // end namespace bus::ti99::peb
|
||||
|
||||
DECLARE_DEVICE_TYPE_NS(TI99_CCDCC, bus::ti99::peb, corcomp_dcc_device)
|
||||
DECLARE_DEVICE_TYPE_NS(TI99_CCFDC, bus::ti99::peb, corcomp_fdca_device)
|
||||
DECLARE_DEVICE_TYPE_NS(CCDCC_PALU2, bus::ti99::peb, ccdcc_palu2_device)
|
||||
DECLARE_DEVICE_TYPE_NS(CCDCC_PALU1, bus::ti99::peb, ccdcc_palu1_device)
|
||||
DECLARE_DEVICE_TYPE_NS(CCFDC_PALU12, bus::ti99::peb, ccfdc_palu12_device)
|
||||
DECLARE_DEVICE_TYPE_NS(CCFDC_PALU6, bus::ti99::peb, ccfdc_palu6_device)
|
||||
|
||||
#endif // MAME_BUS_TI99_PEB_CORCOMP_H
|
@ -182,6 +182,7 @@ CRUCLK* 51||52 DBIN
|
||||
#include "ti_fdc.h"
|
||||
#include "bwg.h"
|
||||
#include "hfdc.h"
|
||||
#include "cc_fdc.h"
|
||||
#include "pcode.h"
|
||||
#include "myarcmem.h"
|
||||
#include "samsmem.h"
|
||||
@ -490,6 +491,8 @@ void ti99_peribox_slot_standard(device_slot_interface &device)
|
||||
device.option_add("bwg", TI99_BWG);
|
||||
device.option_add("hfdc", TI99_HFDC);
|
||||
device.option_add("tifdc", TI99_FDC);
|
||||
device.option_add("ccdcc", TI99_CCDCC);
|
||||
device.option_add("ccfdc", TI99_CCFDC);
|
||||
}
|
||||
|
||||
void peribox_device::device_add_mconfig(machine_config &config)
|
||||
@ -529,6 +532,8 @@ void ti99_peribox_slot_evpc(device_slot_interface &device)
|
||||
device.option_add("bwg", TI99_BWG);
|
||||
device.option_add("hfdc", TI99_HFDC);
|
||||
device.option_add("tifdc", TI99_FDC);
|
||||
device.option_add("ccdcc", TI99_CCDCC);
|
||||
device.option_add("ccfdc", TI99_CCFDC);
|
||||
}
|
||||
|
||||
void peribox_ev_device::device_add_mconfig(machine_config &config)
|
||||
@ -578,6 +583,8 @@ void ti99_peribox_slot_geneve(device_slot_interface &device)
|
||||
device.option_add("usbsm", TI99_USBSM);
|
||||
device.option_add("hfdc", TI99_HFDC);
|
||||
device.option_add("tifdc", TI99_FDC);
|
||||
device.option_add("ccdcc", TI99_CCDCC);
|
||||
device.option_add("ccfdc", TI99_CCFDC);
|
||||
}
|
||||
|
||||
void peribox_gen_device::device_add_mconfig(machine_config &config)
|
||||
@ -629,6 +636,8 @@ void ti99_peribox_slot_sgcpu(device_slot_interface &device)
|
||||
device.option_add("bwg", TI99_BWG);
|
||||
device.option_add("hfdc", TI99_HFDC);
|
||||
device.option_add("tifdc", TI99_FDC);
|
||||
device.option_add("ccdcc", TI99_CCDCC);
|
||||
device.option_add("ccfdc", TI99_CCFDC);
|
||||
}
|
||||
|
||||
void peribox_sg_device::device_add_mconfig(machine_config &config)
|
||||
|
@ -316,10 +316,15 @@ void tms9901_device::set_int_line(int n, int state)
|
||||
*/
|
||||
READ8_MEMBER( tms9901_device::read )
|
||||
{
|
||||
int crubit = offset & 0x01f;
|
||||
return read_bit(offset)? 0x01 : 0x00;
|
||||
}
|
||||
|
||||
bool tms9901_device::read_bit(int bit)
|
||||
{
|
||||
int crubit = bit & 0x01f;
|
||||
|
||||
if (crubit == 0)
|
||||
return m_clock_mode? 1 : 0;
|
||||
return m_clock_mode;
|
||||
|
||||
if (crubit > 15)
|
||||
{
|
||||
@ -329,8 +334,8 @@ READ8_MEMBER( tms9901_device::read )
|
||||
else
|
||||
{
|
||||
// Positive logic; should be 0 if there is no connection.
|
||||
if (m_read_port.isnull()) return 0;
|
||||
return m_read_port((crubit<=P6)? crubit : P6+P0-crubit);
|
||||
if (m_read_port.isnull()) return false;
|
||||
return m_read_port((crubit<=P6)? crubit : P6+P0-crubit)!=0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -338,9 +343,9 @@ READ8_MEMBER( tms9901_device::read )
|
||||
if (m_clock_mode)
|
||||
{
|
||||
if (crubit == 15) // bit 15 in clock mode = /INTREQ
|
||||
return (m_int_pending)? 0 : 1;
|
||||
return !m_int_pending;
|
||||
|
||||
return BIT(m_clock_read_register, crubit-1);
|
||||
return BIT(m_clock_read_register, crubit-1)!=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -352,7 +357,7 @@ READ8_MEMBER( tms9901_device::read )
|
||||
if (crubit>INT6 && is_output(22-crubit))
|
||||
return output_value(22-crubit);
|
||||
else
|
||||
return m_read_port.isnull()? 1 : m_read_port(crubit);
|
||||
return m_read_port.isnull()? true : (m_read_port(crubit)!=0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,7 +374,11 @@ READ8_MEMBER( tms9901_device::read )
|
||||
*/
|
||||
WRITE8_MEMBER( tms9901_device::write )
|
||||
{
|
||||
data &= 1; // clear extra bits
|
||||
write_bit(offset, data!=0);
|
||||
}
|
||||
|
||||
void tms9901_device::write_bit(int offset, bool data)
|
||||
{
|
||||
int crubit = offset & 0x001f;
|
||||
|
||||
if (crubit >= 16)
|
||||
|
@ -68,6 +68,9 @@ public:
|
||||
DECLARE_READ8_MEMBER( read );
|
||||
DECLARE_WRITE8_MEMBER( write );
|
||||
|
||||
bool read_bit(int bit);
|
||||
void write_bit(int bit, bool set);
|
||||
|
||||
auto p_out_cb(int n) { return m_write_p[n].bind(); }
|
||||
auto read_cb() { return m_read_port.bind(); }
|
||||
auto intreq_cb() { return m_interrupt.bind(); }
|
||||
|
Loading…
Reference in New Issue
Block a user