mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
(MESS) New machines added as GAME_NOT_WORKING
--------------------------------------------- Besta-88 [shattered]
This commit is contained in:
parent
1446309913
commit
e6a5048598
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -5878,6 +5878,7 @@ src/mess/drivers/bbcbc.c svneol=native#text/plain
|
||||
src/mess/drivers/bcs3.c svneol=native#text/plain
|
||||
src/mess/drivers/bebox.c svneol=native#text/plain
|
||||
src/mess/drivers/beehive.c svneol=native#text/plain
|
||||
src/mess/drivers/besta.c svneol=native#text/plain
|
||||
src/mess/drivers/beta.c svneol=native#text/plain
|
||||
src/mess/drivers/bigbord2.c svneol=native#text/plain
|
||||
src/mess/drivers/binbug.c svneol=native#text/plain
|
||||
@ -6668,6 +6669,8 @@ src/mess/machine/3c505.c svneol=native#text/plain
|
||||
src/mess/machine/3c505.h svneol=native#text/plain
|
||||
src/mess/machine/64h156.c svneol=native#text/plain
|
||||
src/mess/machine/64h156.h svneol=native#text/plain
|
||||
src/mess/machine/68561mpcc.c svneol=native#text/plain
|
||||
src/mess/machine/68561mpcc.h svneol=native#text/plain
|
||||
src/mess/machine/6883sam.c svneol=native#text/plain
|
||||
src/mess/machine/6883sam.h svneol=native#text/plain
|
||||
src/mess/machine/74145.c svneol=native#text/plain
|
||||
|
163
src/mess/drivers/besta.c
Normal file
163
src/mess/drivers/besta.c
Normal file
@ -0,0 +1,163 @@
|
||||
/***************************************************************************
|
||||
|
||||
Besta-88 and Besta-90 engineering workstations.
|
||||
|
||||
Derived (OEMd?) from Force Computers' SYS68K series.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "machine/terminal.h"
|
||||
#if 0
|
||||
#include "machine/68561mpcc.h"
|
||||
#endif
|
||||
|
||||
#define VERBOSE_DBG 1 /* general debug messages */
|
||||
|
||||
#define DBG_LOG(N,M,A) \
|
||||
do { \
|
||||
if(VERBOSE_DBG>=N) \
|
||||
{ \
|
||||
if( M ) \
|
||||
logerror("%11.6f: %-24s",machine.time().as_double(),(char*)M ); \
|
||||
logerror A; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
class besta_state : public driver_device
|
||||
{
|
||||
public:
|
||||
besta_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_terminal(*this, TERMINAL_TAG)
|
||||
, m_p_ram(*this, "p_ram")
|
||||
{
|
||||
}
|
||||
|
||||
DECLARE_READ8_MEMBER( mpcc_reg_r );
|
||||
DECLARE_WRITE8_MEMBER( mpcc_reg_w );
|
||||
DECLARE_WRITE8_MEMBER( kbd_put );
|
||||
UINT8 m_term_data;
|
||||
UINT8 m_mpcc_regs[32];
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
virtual void machine_reset();
|
||||
|
||||
required_device<generic_terminal_device> m_terminal;
|
||||
required_shared_ptr<UINT32> m_p_ram;
|
||||
};
|
||||
|
||||
#if 1
|
||||
READ8_MEMBER( besta_state::mpcc_reg_r )
|
||||
{
|
||||
running_machine &machine = space.machine();
|
||||
UINT8 ret;
|
||||
|
||||
if (!(offset == 0 && !m_mpcc_regs[0])) {
|
||||
DBG_LOG(1,"mpcc_reg_r",("(%d) = %02X at %s\n", offset,
|
||||
(offset > 31 ? -1 : m_mpcc_regs[offset]), machine.describe_context()));
|
||||
}
|
||||
|
||||
switch (offset) {
|
||||
case 0: /* r_stat aka ... */
|
||||
return (m_term_data) ? 0x80 : 0;
|
||||
case 2: /* r_data aka ... */
|
||||
ret = m_term_data;
|
||||
m_term_data = 0;
|
||||
return ret;
|
||||
default:
|
||||
return m_mpcc_regs[offset];
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( besta_state::mpcc_reg_w )
|
||||
{
|
||||
running_machine &machine = space.machine();
|
||||
device_t *devconf = space.machine().device(TERMINAL_TAG);
|
||||
|
||||
DBG_LOG(1,"mpcc_reg_w",("(%d) <- %02X at %s\n", offset, data, machine.describe_context()));
|
||||
|
||||
switch (offset) {
|
||||
case 2:
|
||||
m_term_data = data;
|
||||
case 10:
|
||||
dynamic_cast<generic_terminal_device *>(devconf)->write(*devconf->machine().memory().first_space(), 0, data);
|
||||
default:
|
||||
m_mpcc_regs[offset] = data; break;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( besta_state::kbd_put )
|
||||
{
|
||||
mpcc_reg_w(space, (offs_t)2, data, mem_mask);
|
||||
}
|
||||
#endif
|
||||
|
||||
static ADDRESS_MAP_START(besta_mem, AS_PROGRAM, 32, besta_state)
|
||||
AM_RANGE(0x00000000, 0x001fffff) AM_RAM AM_SHARE("p_ram") // local bus DRAM, 4MB
|
||||
// AM_RANGE(0x08010000, 0x08011fff) AM_RAM // unknown -- accessed by cp31dssp
|
||||
AM_RANGE(0xff000000, 0xff00ffff) AM_ROM AM_REGION("user1",0) // actual mapping is up to 0xff03ffff
|
||||
AM_RANGE(0xff040000, 0xff07ffff) AM_RAM // onboard SRAM
|
||||
// 68561 MPCC (console)
|
||||
// AM_RANGE(0xff800000, 0xff80001f) AM_DEVREADWRITE8("mpcc", mpcc68561_t, reg_r, reg_w, 0xffffffff)
|
||||
AM_RANGE(0xff800000, 0xff80001f) AM_READWRITE8(mpcc_reg_r, mpcc_reg_w, 0xffffffff)
|
||||
// AM_RANGE(0xff800200, 0xff800xxx) // 68230 PIT2
|
||||
// AM_RANGE(0xff800400, 0xff800xxx) // ??? -- shows up in cp31dssp log
|
||||
// AM_RANGE(0xff800800, 0xff800xxx) // BIM
|
||||
// AM_RANGE(0xff800a00, 0xff800xxx) // 62421 RTC
|
||||
// AM_RANGE(0xff800c00, 0xff800xxx) // 68230 PIT
|
||||
ADDRESS_MAP_END
|
||||
|
||||
/* Input ports */
|
||||
static INPUT_PORTS_START( besta )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
void besta_state::machine_reset()
|
||||
{
|
||||
UINT8* user1 = memregion("user1")->base();
|
||||
|
||||
memcpy((UINT8*)m_p_ram.target(),user1,0x10000); // not really what happens but...
|
||||
memset(m_mpcc_regs, sizeof(m_mpcc_regs), 0); // should initialize to defined values
|
||||
m_mpcc_regs[8] = 0x80; // always ready to transmit
|
||||
|
||||
machine().device("maincpu")->reset();
|
||||
}
|
||||
|
||||
static GENERIC_TERMINAL_INTERFACE( terminal_intf )
|
||||
{
|
||||
DEVCB_DRIVER_MEMBER(besta_state, kbd_put)
|
||||
};
|
||||
|
||||
|
||||
/* CP31 processor board */
|
||||
static MACHINE_CONFIG_START( besta, besta_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu", M68030, 2*16670000)
|
||||
MCFG_CPU_PROGRAM_MAP(besta_mem)
|
||||
|
||||
#if 0
|
||||
MCFG_MPCC68561_ADD("mpcc", XTAL_25MHz, line_cb_t()); // confirm internal oscillator frequency
|
||||
#endif
|
||||
MCFG_GENERIC_TERMINAL_ADD(TERMINAL_TAG, terminal_intf)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
/* ROM definition */
|
||||
|
||||
ROM_START( besta88 )
|
||||
ROM_REGION32_BE( 0x10000, "user1", ROMREGION_ERASEFF )
|
||||
|
||||
ROM_SYSTEM_BIOS(0, "cp31dbg", "CP31 Debug")
|
||||
ROMX_LOAD( "cp31dbgboot.27c512", 0x0000, 0x10000, CRC(9bf057de) SHA1(b13cb16042e4c6ca63ae26058a78259c0849d0b6), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS(1, "cp31dssp", "CP31 DSSP")
|
||||
ROMX_LOAD( "cp31dsspboot.27c512", 0x0000, 0x10000, CRC(607a0a55) SHA1(c257a88672ab39d2f3fad681d22e062182b0236d), ROM_BIOS(2))
|
||||
ROM_SYSTEM_BIOS(2, "cp31os9", "CP31 OS9")
|
||||
ROMX_LOAD( "cp31os9.27c512", 0x0000, 0x10000, CRC(607a0a55) SHA1(c257a88672ab39d2f3fad681d22e062182b0236d), ROM_BIOS(3))
|
||||
ROM_END
|
||||
|
||||
/* Driver */
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
|
||||
COMP( 1988, besta88, 0, 0, besta, besta, driver_device, 0, "Sapsan", "Besta-88", GAME_NOT_WORKING | GAME_NO_SOUND)
|
486
src/mess/machine/68561mpcc.c
Normal file
486
src/mess/machine/68561mpcc.c
Normal file
@ -0,0 +1,486 @@
|
||||
/*********************************************************************
|
||||
|
||||
68561mpcc.c
|
||||
|
||||
Rockwell 68561 MPCC (Multi Protocol Communications Controller)
|
||||
|
||||
skeleton driver, just enough for besta.c console to work
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "68561mpcc.h"
|
||||
|
||||
const device_type MPCC68561 = &device_creator<mpcc68561_t>;
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
PARAMETERS
|
||||
***************************************************************************/
|
||||
|
||||
#define LOG_MPCC (1)
|
||||
|
||||
#if 0 // future
|
||||
|
||||
/***************************************************************************
|
||||
IMPLEMENTATION
|
||||
***************************************************************************/
|
||||
|
||||
mpcc68561_t::mpcc68561_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, MPCC68561, "Rockwell 68561 MPCC", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void mpcc68561_t::set_intrq_cb(line_cb_t cb)
|
||||
{
|
||||
intrq_cb = cb;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mpcc_updateirqs
|
||||
-------------------------------------------------*/
|
||||
|
||||
void mpcc68561_t::updateirqs()
|
||||
{
|
||||
int irqstat;
|
||||
|
||||
irqstat = 0;
|
||||
if (MasterIRQEnable)
|
||||
{
|
||||
if ((channel[0].txIRQEnable) && (channel[0].txIRQPending))
|
||||
{
|
||||
IRQType = IRQ_B_TX;
|
||||
irqstat = 1;
|
||||
}
|
||||
else if ((channel[1].txIRQEnable) && (channel[1].txIRQPending))
|
||||
{
|
||||
IRQType = IRQ_A_TX;
|
||||
irqstat = 1;
|
||||
}
|
||||
else if ((channel[0].extIRQEnable) && (channel[0].extIRQPending))
|
||||
{
|
||||
IRQType = IRQ_B_EXT;
|
||||
irqstat = 1;
|
||||
}
|
||||
else if ((channel[1].extIRQEnable) && (channel[1].extIRQPending))
|
||||
{
|
||||
IRQType = IRQ_A_EXT;
|
||||
irqstat = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IRQType = IRQ_NONE;
|
||||
}
|
||||
|
||||
// printf("mpcc: irqstat %d, last %d\n", irqstat, lastIRQStat);
|
||||
// printf("ch0: en %d pd %d ch1: en %d pd %d\n", channel[0].txIRQEnable, channel[0].txIRQPending, channel[1].txIRQEnable, channel[1].txIRQPending);
|
||||
|
||||
// don't spam the driver with unnecessary transitions
|
||||
if (irqstat != lastIRQStat)
|
||||
{
|
||||
lastIRQStat = irqstat;
|
||||
|
||||
// tell the driver the new IRQ line status if possible
|
||||
#if LOG_MPCC
|
||||
printf("mpcc68561 IRQ status => %d\n", irqstat);
|
||||
#endif
|
||||
if(!intrq_cb.isnull())
|
||||
intrq_cb(irqstat);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mpcc_initchannel
|
||||
-------------------------------------------------*/
|
||||
void mpcc68561_t::initchannel(int ch)
|
||||
{
|
||||
channel[ch].syncHunt = 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mpcc_resetchannel
|
||||
-------------------------------------------------*/
|
||||
void mpcc68561_t::resetchannel(int ch)
|
||||
{
|
||||
emu_timer *timersave = channel[ch].baudtimer;
|
||||
|
||||
memset(&channel[ch], 0, sizeof(Chan));
|
||||
|
||||
channel[ch].txUnderrun = 1;
|
||||
channel[ch].baudtimer = timersave;
|
||||
|
||||
channel[ch].baudtimer->adjust(attotime::never, ch);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mpcc68561_baud_expire - baud rate timer expiry
|
||||
-------------------------------------------------*/
|
||||
|
||||
void mpcc68561_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
Chan *pChan = &channel[id];
|
||||
int brconst = pChan->reg_val[13]<<8 | pChan->reg_val[14];
|
||||
int rate;
|
||||
|
||||
if (brconst)
|
||||
{
|
||||
rate = clock() / brconst;
|
||||
}
|
||||
else
|
||||
{
|
||||
rate = 0;
|
||||
}
|
||||
|
||||
// is baud counter IRQ enabled on this channel?
|
||||
// always flag pending in case it's enabled after this
|
||||
pChan->baudIRQPending = 1;
|
||||
if (pChan->baudIRQEnable)
|
||||
{
|
||||
if (pChan->extIRQEnable)
|
||||
{
|
||||
pChan->extIRQPending = 1;
|
||||
pChan->baudIRQPending = 0;
|
||||
updateirqs();
|
||||
}
|
||||
}
|
||||
|
||||
// reset timer according to current register values
|
||||
if (rate)
|
||||
{
|
||||
timer.adjust(attotime::from_hz(rate), 0, attotime::from_hz(rate));
|
||||
}
|
||||
else
|
||||
{
|
||||
timer.adjust(attotime::never, 0, attotime::never);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_START( mpcc68561 )
|
||||
-------------------------------------------------*/
|
||||
|
||||
void mpcc68561_t::device_start()
|
||||
{
|
||||
memset(channel, 0, sizeof(channel));
|
||||
|
||||
mode = 0;
|
||||
reg = 0;
|
||||
status = 0;
|
||||
IRQV = 0;
|
||||
MasterIRQEnable = 0;
|
||||
lastIRQStat = 0;
|
||||
IRQType = IRQ_NONE;
|
||||
|
||||
channel[0].baudtimer = timer_alloc(0);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
DEVICE_RESET( mpcc68561 )
|
||||
-------------------------------------------------*/
|
||||
void mpcc68561_t::device_reset()
|
||||
{
|
||||
IRQType = IRQ_NONE;
|
||||
MasterIRQEnable = 0;
|
||||
IRQV = 0;
|
||||
|
||||
initchannel(0);
|
||||
resetchannel(0);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mpcc_set_status
|
||||
-------------------------------------------------*/
|
||||
|
||||
void mpcc68561_t::set_status(int _status)
|
||||
{
|
||||
status = _status;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mpcc_acknowledge
|
||||
-------------------------------------------------*/
|
||||
|
||||
void mpcc68561_t::acknowledge()
|
||||
{
|
||||
if(!intrq_cb.isnull())
|
||||
intrq_cb(0);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mpcc_getreg
|
||||
-------------------------------------------------*/
|
||||
|
||||
UINT8 mpcc68561_t::getreg()
|
||||
{
|
||||
/* Not yet implemented */
|
||||
#if LOG_MPCC
|
||||
printf("mpcc: port A reg %d read 0x%02x\n", reg, channel[0].reg_val[reg]);
|
||||
#endif
|
||||
|
||||
if (reg == 0)
|
||||
{
|
||||
UINT8 rv = 0;
|
||||
|
||||
Chan *ourCh = &channel[0];
|
||||
|
||||
rv |= (ourCh->txUnderrun) ? 0x40 : 0;
|
||||
rv |= (ourCh->syncHunt) ? 0x10 : 0;
|
||||
rv |= channel[0].reg_val[0] & 0x05; // pick up TXBE and RXBF bits
|
||||
|
||||
return rv;
|
||||
}
|
||||
else if (reg == 10)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return channel[0].reg_val[reg];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mpcc_putreg
|
||||
-------------------------------------------------*/
|
||||
|
||||
void mpcc68561_t::putreg(int ch, UINT8 data)
|
||||
{
|
||||
Chan *pChan = &channel[ch];
|
||||
|
||||
channel[ch].reg_val[reg] = data;
|
||||
#if LOG_MPCC
|
||||
printf("mpcc: port %c reg %d write 0x%02x\n", 'A'+ch, reg, data);
|
||||
#endif
|
||||
|
||||
switch (reg)
|
||||
{
|
||||
case 0: // command register
|
||||
switch ((data >> 3) & 7)
|
||||
{
|
||||
case 1: // select high registers (handled elsewhere)
|
||||
break;
|
||||
|
||||
case 2: // reset external and status IRQs
|
||||
pChan->syncHunt = 0;
|
||||
break;
|
||||
|
||||
case 5: // ack Tx IRQ
|
||||
pChan->txIRQPending = 0;
|
||||
updateirqs();
|
||||
break;
|
||||
|
||||
case 0: // nothing
|
||||
case 3: // send SDLC abort
|
||||
case 4: // enable IRQ on next Rx byte
|
||||
case 6: // reset errors
|
||||
case 7: // reset highest IUS
|
||||
// we don't handle these yet
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // Tx/Rx IRQ and data transfer mode defintion
|
||||
pChan->extIRQEnable = (data & 1);
|
||||
pChan->txIRQEnable = (data & 2) ? 1 : 0;
|
||||
pChan->rxIRQEnable = (data >> 3) & 3;
|
||||
updateirqs();
|
||||
break;
|
||||
|
||||
case 2: // IRQ vector
|
||||
IRQV = data;
|
||||
break;
|
||||
|
||||
case 3: // Rx parameters and controls
|
||||
pChan->rxEnable = (data & 1);
|
||||
pChan->syncHunt = (data & 0x10) ? 1 : 0;
|
||||
break;
|
||||
|
||||
case 5: // Tx parameters and controls
|
||||
// printf("ch %d TxEnable = %d [%02x]\n", ch, data & 8, data);
|
||||
pChan->txEnable = data & 8;
|
||||
|
||||
if (pChan->txEnable)
|
||||
{
|
||||
pChan->reg_val[0] |= 0x04; // Tx empty
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // Tx/Rx misc parameters and modes
|
||||
case 6: // sync chars/SDLC address field
|
||||
case 7: // sync char/SDLC flag
|
||||
break;
|
||||
|
||||
case 9: // master IRQ control
|
||||
MasterIRQEnable = (data & 8) ? 1 : 0;
|
||||
updateirqs();
|
||||
|
||||
// channel reset command
|
||||
switch ((data>>6) & 3)
|
||||
{
|
||||
case 0: // do nothing
|
||||
break;
|
||||
|
||||
case 1: // reset channel B
|
||||
resetchannel(0);
|
||||
break;
|
||||
|
||||
case 3: // force h/w reset (entire chip)
|
||||
IRQType = IRQ_NONE;
|
||||
MasterIRQEnable = 0;
|
||||
IRQV = 0;
|
||||
|
||||
initchannel(0);
|
||||
resetchannel(0);
|
||||
|
||||
// make sure we stop yanking the IRQ line if we were
|
||||
updateirqs();
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 10: // misc transmitter/receiver control bits
|
||||
case 11: // clock mode control
|
||||
case 12: // lower byte of baud rate gen
|
||||
case 13: // upper byte of baud rate gen
|
||||
break;
|
||||
|
||||
case 14: // misc control bits
|
||||
if (data & 0x01) // baud rate generator enable?
|
||||
{
|
||||
int brconst = pChan->reg_val[13]<<8 | pChan->reg_val[14];
|
||||
int rate = clock() / brconst;
|
||||
|
||||
pChan->baudtimer->adjust(attotime::from_hz(rate), 0, attotime::from_hz(rate));
|
||||
}
|
||||
break;
|
||||
|
||||
case 15: // external/status interrupt control
|
||||
pChan->baudIRQEnable = (data & 2) ? 1 : 0;
|
||||
pChan->DCDEnable = (data & 8) ? 1 : 0;
|
||||
pChan->CTSEnable = (data & 0x20) ? 1 : 0;
|
||||
pChan->txUnderrunEnable = (data & 0x40) ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mpcc68561_get_reg_a
|
||||
-------------------------------------------------*/
|
||||
|
||||
UINT8 mpcc68561_t::get_reg_a(int reg)
|
||||
{
|
||||
return channel[0].reg_val[reg];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mpcc68561_set_reg_a
|
||||
-------------------------------------------------*/
|
||||
|
||||
void mpcc68561_t::set_reg_a(int reg, UINT8 data)
|
||||
{
|
||||
channel[0].reg_val[reg] = data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mpcc68561_r
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER( mpcc68561_t::reg_r)
|
||||
{
|
||||
UINT8 result = 0;
|
||||
|
||||
offset %= 4;
|
||||
|
||||
switch(offset)
|
||||
{
|
||||
case 1:
|
||||
/* Channel A (Modem Port) Control */
|
||||
if (mode == 1)
|
||||
mode = 0;
|
||||
else
|
||||
reg = 0;
|
||||
|
||||
result = getreg();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* Channel A (Modem Port) Data */
|
||||
return channel[0].rxData;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mpcc68561_w
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_MEMBER( mpcc68561_t::reg_w )
|
||||
{
|
||||
Chan *pChan;
|
||||
|
||||
offset &= 3;
|
||||
|
||||
// printf(" mode %d data %x offset %d \n", mode, data, offset);
|
||||
|
||||
switch(offset)
|
||||
{
|
||||
case 1:
|
||||
/* Channel A (Modem Port) Control */
|
||||
if (mode == 0)
|
||||
{
|
||||
if((data & 0xf0) == 0) // not a reset command
|
||||
{
|
||||
mode = 1;
|
||||
reg = data & 0x0f;
|
||||
// putareg(data & 0xf0);
|
||||
}
|
||||
else if (data == 0x10)
|
||||
{
|
||||
pChan = &channel[0];
|
||||
// clear ext. interrupts
|
||||
pChan->extIRQPending = 0;
|
||||
pChan->baudIRQPending = 0;
|
||||
updateirqs();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = 0;
|
||||
putreg(0, data);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* Channel A (Modem Port) Data */
|
||||
pChan = &channel[0];
|
||||
|
||||
if (pChan->txEnable)
|
||||
{
|
||||
pChan->txData = data;
|
||||
// local loopback?
|
||||
if (pChan->reg_val[14] & 0x10)
|
||||
{
|
||||
pChan->rxData = data;
|
||||
pChan->reg_val[0] |= 0x01; // Rx character available
|
||||
}
|
||||
pChan->reg_val[1] |= 0x01; // All sent
|
||||
pChan->reg_val[0] |= 0x04; // Tx empty
|
||||
pChan->txUnderrun = 1;
|
||||
pChan->txIRQPending = 1;
|
||||
updateirqs();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#endif
|
100
src/mess/machine/68561mpcc.h
Normal file
100
src/mess/machine/68561mpcc.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*********************************************************************
|
||||
|
||||
68561mpcc.h
|
||||
|
||||
Rockwell 68561 MPCC (Multi Protocol Communications Controller)
|
||||
|
||||
skeleton driver
|
||||
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef __68561MPCC_H__
|
||||
#define __68561MPCC_H__
|
||||
|
||||
#define MCFG_MPCC68561_ADD(_tag, _clock, _intrq_cb) \
|
||||
MCFG_DEVICE_ADD(_tag, MPCC68561, _clock) \
|
||||
downcast<mpcc68561_t *>(device)->set_intrq_cb(_intrq_cb);
|
||||
|
||||
class mpcc68561_t : public device_t
|
||||
{
|
||||
public:
|
||||
enum IRQType_t {
|
||||
IRQ_NONE,
|
||||
IRQ_A_RX,
|
||||
IRQ_A_RX_SPECIAL,
|
||||
IRQ_B_RX,
|
||||
IRQ_B_RX_SPECIAL,
|
||||
IRQ_A_TX,
|
||||
IRQ_B_TX,
|
||||
IRQ_A_EXT,
|
||||
IRQ_B_EXT,
|
||||
};
|
||||
|
||||
mpcc68561_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
void set_intrq_cb(line_cb_t cb);
|
||||
|
||||
UINT8 get_reg_a(int reg);
|
||||
void set_reg_a(int reg, UINT8 data);
|
||||
|
||||
void set_status(int status);
|
||||
|
||||
DECLARE_READ8_MEMBER(reg_r);
|
||||
DECLARE_WRITE8_MEMBER(reg_w);
|
||||
|
||||
protected:
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||
|
||||
private:
|
||||
struct Chan {
|
||||
bool txIRQEnable;
|
||||
bool rxIRQEnable;
|
||||
bool extIRQEnable;
|
||||
bool baudIRQEnable;
|
||||
bool txIRQPending;
|
||||
bool rxIRQPending;
|
||||
bool extIRQPending;
|
||||
bool baudIRQPending;
|
||||
bool txEnable;
|
||||
bool rxEnable;
|
||||
bool txUnderrun;
|
||||
bool txUnderrunEnable;
|
||||
bool syncHunt;
|
||||
bool DCDEnable;
|
||||
bool CTSEnable;
|
||||
UINT8 rxData;
|
||||
UINT8 txData;
|
||||
|
||||
emu_timer *baudtimer;
|
||||
|
||||
UINT8 reg_val[22];
|
||||
};
|
||||
|
||||
int mode;
|
||||
int reg;
|
||||
int status;
|
||||
int IRQV;
|
||||
int MasterIRQEnable;
|
||||
int lastIRQStat;
|
||||
IRQType_t IRQType;
|
||||
|
||||
Chan channel[1];
|
||||
|
||||
line_cb_t intrq_cb;
|
||||
|
||||
void updateirqs();
|
||||
void initchannel(int ch);
|
||||
void resetchannel(int ch);
|
||||
void acknowledge();
|
||||
UINT8 getreg();
|
||||
void putreg(int ch, UINT8 data);
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
MACROS
|
||||
***************************************************************************/
|
||||
|
||||
extern const device_type MPCC68561;
|
||||
|
||||
#endif /* __68561MPCC_H__ */
|
@ -175,6 +175,7 @@ d6800 // Dream 6800
|
||||
// Ensoniq
|
||||
enmirage // 1985 Mirage Digital Multi-Sampler
|
||||
esq1 // 1986 ESQ-1 Digital Wave Synthesizer
|
||||
esqm // 1986 ESQ-M rack-mount ESQ-1
|
||||
sq80 // 1988 SQ-80 Digital Wave Synthesizer
|
||||
eps // 1988 EPS
|
||||
vfx // 1989 VFX
|
||||
@ -2208,3 +2209,5 @@ nectk85
|
||||
nd80z
|
||||
binbug
|
||||
dg680
|
||||
besta88
|
||||
|
||||
|
@ -507,6 +507,7 @@ $(MESSOBJ)/shared.a: \
|
||||
$(MESS_AUDIO)/spchroms.o \
|
||||
$(MESS_MACHINE)/microdrv.o \
|
||||
$(MESS_MACHINE)/74145.o \
|
||||
$(MESS_MACHINE)/68561mpcc.o \
|
||||
$(MESS_MACHINE)/8530scc.o \
|
||||
$(MESS_MACHINE)/at45dbxx.o \
|
||||
$(MESS_MACHINE)/ay31015.o \
|
||||
@ -2030,6 +2031,7 @@ $(MESSOBJ)/skeleton.a: \
|
||||
$(MESS_DRIVERS)/babbage.o \
|
||||
$(MESS_DRIVERS)/beehive.o \
|
||||
$(MESS_DRIVERS)/binbug.o \
|
||||
$(MESS_DRIVERS)/besta.o \
|
||||
$(MESS_DRIVERS)/bob85.o \
|
||||
$(MESS_DRIVERS)/br8641.o \
|
||||
$(MESS_DRIVERS)/busicom.o \
|
||||
|
Loading…
Reference in New Issue
Block a user