mirror of
https://github.com/holub/mame
synced 2025-06-26 06:14:12 +03:00
cosmac: add very preliminary 1804/5/6 (nw)
This commit is contained in:
parent
ceebc3ef28
commit
dda7d43069
@ -4,6 +4,13 @@
|
|||||||
|
|
||||||
RCA COSMAC CPU emulation
|
RCA COSMAC CPU emulation
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
- is it useful to emulate I and N registers or can they just be defined as (m_op >> x & 0xf)?
|
||||||
|
- 1804/5/6: extended opcode timing is wrong, multiple execute states
|
||||||
|
- 1804/5/6: add more extended opcodes (05/06 supports more than 04)
|
||||||
|
- 1804/5/6: add counter/timer
|
||||||
|
- 1804/5: add internal address map (ram/rom)
|
||||||
|
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
@ -150,9 +157,9 @@ const cosmac_device::ophandler cdp1801_device::s_opcodetable[256] =
|
|||||||
&cdp1801_device::adi, &cdp1801_device::sdi, &cdp1801_device::und, &cdp1801_device::smi
|
&cdp1801_device::adi, &cdp1801_device::sdi, &cdp1801_device::und, &cdp1801_device::smi
|
||||||
};
|
};
|
||||||
|
|
||||||
cosmac_device::ophandler cdp1801_device::get_ophandler(uint8_t opcode) const
|
cosmac_device::ophandler cdp1801_device::get_ophandler(uint16_t opcode) const
|
||||||
{
|
{
|
||||||
return s_opcodetable[opcode];
|
return s_opcodetable[opcode & 0xff];
|
||||||
}
|
}
|
||||||
|
|
||||||
const cosmac_device::ophandler cdp1802_device::s_opcodetable[256] =
|
const cosmac_device::ophandler cdp1802_device::s_opcodetable[256] =
|
||||||
@ -238,9 +245,100 @@ const cosmac_device::ophandler cdp1802_device::s_opcodetable[256] =
|
|||||||
&cdp1802_device::adi, &cdp1802_device::sdi, &cdp1802_device::shl, &cdp1802_device::smi
|
&cdp1802_device::adi, &cdp1802_device::sdi, &cdp1802_device::shl, &cdp1802_device::smi
|
||||||
};
|
};
|
||||||
|
|
||||||
cosmac_device::ophandler cdp1802_device::get_ophandler(uint8_t opcode) const
|
cosmac_device::ophandler cdp1802_device::get_ophandler(uint16_t opcode) const
|
||||||
{
|
{
|
||||||
return s_opcodetable[opcode];
|
return s_opcodetable[opcode & 0xff];
|
||||||
|
}
|
||||||
|
|
||||||
|
const cosmac_device::ophandler cdp1804_device::s_opcodetable_ex[256] =
|
||||||
|
{
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::ldc, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::gec, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::bci, &cdp1804_device::bxi,
|
||||||
|
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
|
||||||
|
&cdp1804_device::rlxa, &cdp1804_device::rlxa, &cdp1804_device::rlxa, &cdp1804_device::rlxa,
|
||||||
|
&cdp1804_device::rlxa, &cdp1804_device::rlxa, &cdp1804_device::rlxa, &cdp1804_device::rlxa,
|
||||||
|
&cdp1804_device::rlxa, &cdp1804_device::rlxa, &cdp1804_device::rlxa, &cdp1804_device::rlxa,
|
||||||
|
&cdp1804_device::rlxa, &cdp1804_device::rlxa, &cdp1804_device::rlxa, &cdp1804_device::rlxa,
|
||||||
|
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
|
||||||
|
&cdp1804_device::rsxd, &cdp1804_device::rsxd, &cdp1804_device::rsxd, &cdp1804_device::rsxd,
|
||||||
|
&cdp1804_device::rsxd, &cdp1804_device::rsxd, &cdp1804_device::rsxd, &cdp1804_device::rsxd,
|
||||||
|
&cdp1804_device::rsxd, &cdp1804_device::rsxd, &cdp1804_device::rsxd, &cdp1804_device::rsxd,
|
||||||
|
&cdp1804_device::rsxd, &cdp1804_device::rsxd, &cdp1804_device::rsxd, &cdp1804_device::rsxd,
|
||||||
|
|
||||||
|
&cdp1804_device::rnx, &cdp1804_device::rnx, &cdp1804_device::rnx, &cdp1804_device::rnx,
|
||||||
|
&cdp1804_device::rnx, &cdp1804_device::rnx, &cdp1804_device::rnx, &cdp1804_device::rnx,
|
||||||
|
&cdp1804_device::rnx, &cdp1804_device::rnx, &cdp1804_device::rnx, &cdp1804_device::rnx,
|
||||||
|
&cdp1804_device::rnx, &cdp1804_device::rnx, &cdp1804_device::rnx, &cdp1804_device::rnx,
|
||||||
|
|
||||||
|
&cdp1804_device::rldi, &cdp1804_device::rldi, &cdp1804_device::rldi, &cdp1804_device::rldi,
|
||||||
|
&cdp1804_device::rldi, &cdp1804_device::rldi, &cdp1804_device::rldi, &cdp1804_device::rldi,
|
||||||
|
&cdp1804_device::rldi, &cdp1804_device::rldi, &cdp1804_device::rldi, &cdp1804_device::rldi,
|
||||||
|
&cdp1804_device::rldi, &cdp1804_device::rldi, &cdp1804_device::rldi, &cdp1804_device::rldi,
|
||||||
|
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
&cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und, &cdp1804_device::und,
|
||||||
|
};
|
||||||
|
|
||||||
|
cosmac_device::ophandler cdp1804_device::get_ophandler(uint16_t opcode) const
|
||||||
|
{
|
||||||
|
if ((opcode & 0xff00) == 0x6800)
|
||||||
|
return s_opcodetable_ex[opcode & 0xff];
|
||||||
|
else
|
||||||
|
return cdp1802_device::get_ophandler(opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -252,6 +350,9 @@ cosmac_device::ophandler cdp1802_device::get_ophandler(uint8_t opcode) const
|
|||||||
// device type definition
|
// device type definition
|
||||||
DEFINE_DEVICE_TYPE(CDP1801, cdp1801_device, "cdp1801", "RCA CDP1801")
|
DEFINE_DEVICE_TYPE(CDP1801, cdp1801_device, "cdp1801", "RCA CDP1801")
|
||||||
DEFINE_DEVICE_TYPE(CDP1802, cdp1802_device, "cdp1802", "RCA CDP1802")
|
DEFINE_DEVICE_TYPE(CDP1802, cdp1802_device, "cdp1802", "RCA CDP1802")
|
||||||
|
DEFINE_DEVICE_TYPE(CDP1804, cdp1804_device, "cdp1804", "RCA CDP1804")
|
||||||
|
DEFINE_DEVICE_TYPE(CDP1805, cdp1805_device, "cdp1805", "RCA CDP1805")
|
||||||
|
DEFINE_DEVICE_TYPE(CDP1806, cdp1806_device, "cdp1806", "RCA CDP1806")
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
@ -294,20 +395,57 @@ cosmac_device::cosmac_device(const machine_config &mconfig, device_type type, co
|
|||||||
// cdp1801_device - constructor
|
// cdp1801_device - constructor
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
cdp1801_device::cdp1801_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
cdp1801_device::cdp1801_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||||
: cosmac_device(mconfig, CDP1801, tag, owner, clock)
|
cosmac_device(mconfig, CDP1801, tag, owner, clock)
|
||||||
{
|
{ }
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// cdp1802_device - constructor
|
// cdp1802_device - constructor
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
cdp1802_device::cdp1802_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
cdp1802_device::cdp1802_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||||
: cosmac_device(mconfig, CDP1802, tag, owner, clock)
|
cdp1802_device(mconfig, CDP1802, tag, owner, clock)
|
||||||
{
|
{ }
|
||||||
}
|
|
||||||
|
cdp1802_device::cdp1802_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||||
|
cosmac_device(mconfig, type, tag, owner, clock)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// cdp1804_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
cdp1804_device::cdp1804_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||||
|
cdp1804_device(mconfig, CDP1804, tag, owner, clock)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
cdp1804_device::cdp1804_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||||
|
cdp1802_device(mconfig, type, tag, owner, clock)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// cdp1805_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
cdp1805_device::cdp1805_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||||
|
cdp1805_device(mconfig, CDP1805, tag, owner, clock)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
cdp1805_device::cdp1805_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||||
|
cdp1804_device(mconfig, type, tag, owner, clock)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// cdp1806_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
cdp1806_device::cdp1806_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||||
|
cdp1805_device(mconfig, CDP1806, tag, owner, clock)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
@ -717,6 +855,9 @@ inline void cosmac_device::run_state()
|
|||||||
switch (m_state)
|
switch (m_state)
|
||||||
{
|
{
|
||||||
case cosmac_state::STATE_0_FETCH:
|
case cosmac_state::STATE_0_FETCH:
|
||||||
|
m_op = 0;
|
||||||
|
|
||||||
|
case cosmac_state::STATE_0_FETCH_2ND:
|
||||||
fetch_instruction();
|
fetch_instruction();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -795,7 +936,7 @@ inline void cosmac_device::sample_ef_lines()
|
|||||||
|
|
||||||
inline void cosmac_device::output_state_code()
|
inline void cosmac_device::output_state_code()
|
||||||
{
|
{
|
||||||
if (m_state == cosmac_state::STATE_0_FETCH)
|
if (m_state == cosmac_state::STATE_0_FETCH || m_state == cosmac_state::STATE_0_FETCH_2ND)
|
||||||
{
|
{
|
||||||
// S0 fetch
|
// S0 fetch
|
||||||
m_write_sc(0, COSMAC_STATE_CODE_S0_FETCH);
|
m_write_sc(0, COSMAC_STATE_CODE_S0_FETCH);
|
||||||
@ -813,13 +954,13 @@ inline void cosmac_device::output_state_code()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// S1 execute
|
// S1 execute
|
||||||
m_write_sc(I == 0x6 ? (N & 7) : 0, COSMAC_STATE_CODE_S1_EXECUTE);
|
m_write_sc((m_op >> 4) == 0x6 ? (N & 7) : 0, COSMAC_STATE_CODE_S1_EXECUTE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdp1801_device::output_state_code()
|
void cdp1801_device::output_state_code()
|
||||||
{
|
{
|
||||||
if (m_state == cosmac_state::STATE_0_FETCH)
|
if (m_state == cosmac_state::STATE_0_FETCH || m_state == cosmac_state::STATE_0_FETCH_2ND)
|
||||||
{
|
{
|
||||||
// S0 fetch
|
// S0 fetch
|
||||||
m_write_sc(0, 4);
|
m_write_sc(0, 4);
|
||||||
@ -834,7 +975,7 @@ void cdp1801_device::output_state_code()
|
|||||||
// S3 interrupt
|
// S3 interrupt
|
||||||
m_write_sc(0, 3);
|
m_write_sc(0, 3);
|
||||||
}
|
}
|
||||||
else if (I == 0x6)
|
else if ((m_op >> 4) == 0x6)
|
||||||
{
|
{
|
||||||
// S1 execute (I/O)
|
// S1 execute (I/O)
|
||||||
m_write_sc(N, 1);
|
m_write_sc(N, 1);
|
||||||
@ -889,14 +1030,18 @@ inline void cosmac_device::fetch_instruction()
|
|||||||
// instruction fetch
|
// instruction fetch
|
||||||
offs_t addr = R[P]++;
|
offs_t addr = R[P]++;
|
||||||
m_write_tpb(1);
|
m_write_tpb(1);
|
||||||
m_op = read_opcode(addr);
|
m_op = m_op << 8 | read_opcode(addr);
|
||||||
m_write_tpb(0);
|
m_write_tpb(0);
|
||||||
|
|
||||||
I = m_op >> 4;
|
I = m_op >> 4 & 0x0f;
|
||||||
N = m_op & 0x0f;
|
N = m_op & 0x0f;
|
||||||
|
|
||||||
m_icount -= CLOCKS_FETCH;
|
m_icount -= CLOCKS_FETCH;
|
||||||
|
|
||||||
|
// CDP1804 and up: 0x68 for extended opcodes
|
||||||
|
if (m_op == 0x68 && has_extended_opcodes())
|
||||||
|
m_state = cosmac_state::STATE_0_FETCH_2ND;
|
||||||
|
else
|
||||||
m_state = cosmac_state::STATE_1_EXECUTE;
|
m_state = cosmac_state::STATE_1_EXECUTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -963,7 +1108,7 @@ inline void cosmac_device::execute_instruction()
|
|||||||
|
|
||||||
m_icount -= CLOCKS_EXECUTE;
|
m_icount -= CLOCKS_EXECUTE;
|
||||||
|
|
||||||
if (I == 0xc && m_state == cosmac_state::STATE_1_EXECUTE)
|
if (m_state == cosmac_state::STATE_1_EXECUTE && (m_op >> 4) == 0xc) // "long" opcodes
|
||||||
{
|
{
|
||||||
m_state = cosmac_state::STATE_1_EXECUTE_2ND;
|
m_state = cosmac_state::STATE_1_EXECUTE_2ND;
|
||||||
}
|
}
|
||||||
@ -979,7 +1124,7 @@ inline void cosmac_device::execute_instruction()
|
|||||||
{
|
{
|
||||||
m_state = cosmac_state::STATE_3_INT;
|
m_state = cosmac_state::STATE_3_INT;
|
||||||
}
|
}
|
||||||
else if ((I > 0) || (N > 0)) // not idling
|
else if (m_op != 0) // not idling
|
||||||
{
|
{
|
||||||
m_state = cosmac_state::STATE_0_FETCH;
|
m_state = cosmac_state::STATE_0_FETCH;
|
||||||
}
|
}
|
||||||
@ -1298,3 +1443,16 @@ void cosmac_device::out() { IO_W(N, RAM_R(R[X])); R[X]++; }
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
void cosmac_device::inp() { D = IO_R(N & 0x07); RAM_W(R[X], D); }
|
void cosmac_device::inp() { D = IO_R(N & 0x07); RAM_W(R[X], D); }
|
||||||
|
|
||||||
|
// CDP1804(and up) extended opcodes
|
||||||
|
void cosmac_device::rldi() { put_high_reg(N, RAM_R(R[P])); R[P]++; put_low_reg(N, RAM_R(R[P])); R[P]++; }
|
||||||
|
void cosmac_device::rlxa() { put_high_reg(N, RAM_R(R[X])); R[X]++; put_low_reg(N, RAM_R(R[X])); R[X]++; }
|
||||||
|
void cosmac_device::rsxd() { RAM_W(R[X], R[N] >> 0 & 0xff); R[X]--; RAM_W(R[X], R[N] >> 8 & 0xff); R[X]--; }
|
||||||
|
|
||||||
|
void cosmac_device::rnx() { R[X] = R[N]; }
|
||||||
|
|
||||||
|
void cosmac_device::bci() { short_branch(1); } // wrong! tests CI flag
|
||||||
|
void cosmac_device::bxi() { short_branch(0); } // wrong! tests XI flag
|
||||||
|
|
||||||
|
void cosmac_device::ldc() { /* logerror("LDC counter set: %X\n", D); */ }
|
||||||
|
void cosmac_device::gec() { D = machine().rand() & 0xf; } // wrong!
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
Type Internal ROM Internal RAM Timer Pin 16 (*)
|
Type Internal ROM Internal RAM Timer Pin 16 (*)
|
||||||
------------------------------------------------------------------
|
------------------------------------------------------------------
|
||||||
CDP1802 none none no Vcc
|
CDP1802 none none no Vcc
|
||||||
CDP1803 ? ? ? ?
|
CDP1803 ? ? ? ? does not exist?
|
||||||
CDP1804 2 KB 64 bytes yes ?
|
CDP1804 2 KB 64 bytes yes ?
|
||||||
CDP1805 none 64 bytes yes _ME
|
CDP1805 none 64 bytes yes _ME
|
||||||
CDP1806 none none yes Vdd
|
CDP1806 none none yes Vdd
|
||||||
@ -333,6 +333,16 @@ protected:
|
|||||||
void out();
|
void out();
|
||||||
void inp();
|
void inp();
|
||||||
|
|
||||||
|
// extended opcodes
|
||||||
|
void rldi();
|
||||||
|
void rlxa();
|
||||||
|
void rsxd();
|
||||||
|
void rnx();
|
||||||
|
void bci();
|
||||||
|
void bxi();
|
||||||
|
void ldc();
|
||||||
|
void gec();
|
||||||
|
|
||||||
const address_space_config m_program_config;
|
const address_space_config m_program_config;
|
||||||
const address_space_config m_io_config;
|
const address_space_config m_io_config;
|
||||||
|
|
||||||
@ -359,6 +369,7 @@ protected:
|
|||||||
enum class cosmac_state : u8
|
enum class cosmac_state : u8
|
||||||
{
|
{
|
||||||
STATE_0_FETCH = 0,
|
STATE_0_FETCH = 0,
|
||||||
|
STATE_0_FETCH_2ND,
|
||||||
STATE_1_INIT,
|
STATE_1_INIT,
|
||||||
STATE_1_EXECUTE,
|
STATE_1_EXECUTE,
|
||||||
STATE_1_EXECUTE_2ND,
|
STATE_1_EXECUTE_2ND,
|
||||||
@ -369,7 +380,7 @@ protected:
|
|||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
uint16_t m_pc; // fake program counter
|
uint16_t m_pc; // fake program counter
|
||||||
uint8_t m_op; // current opcode
|
uint16_t m_op; // current opcode
|
||||||
uint8_t m_flagsio; // flags storage for state saving
|
uint8_t m_flagsio; // flags storage for state saving
|
||||||
cosmac_state m_state; // state
|
cosmac_state m_state; // state
|
||||||
cosmac_mode m_mode; // control mode
|
cosmac_mode m_mode; // control mode
|
||||||
@ -405,7 +416,8 @@ protected:
|
|||||||
|
|
||||||
// opcode/condition tables
|
// opcode/condition tables
|
||||||
typedef void (cosmac_device::*ophandler)();
|
typedef void (cosmac_device::*ophandler)();
|
||||||
virtual cosmac_device::ophandler get_ophandler(uint8_t opcode) const = 0;
|
virtual cosmac_device::ophandler get_ophandler(uint16_t opcode) const = 0;
|
||||||
|
virtual bool has_extended_opcodes() { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -421,10 +433,11 @@ protected:
|
|||||||
// device_disasm_interface overrides
|
// device_disasm_interface overrides
|
||||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||||
|
|
||||||
virtual cosmac_device::ophandler get_ophandler(uint8_t opcode) const override;
|
virtual cosmac_device::ophandler get_ophandler(uint16_t opcode) const override;
|
||||||
|
|
||||||
virtual void output_state_code() override;
|
virtual void output_state_code() override;
|
||||||
|
|
||||||
|
private:
|
||||||
static const ophandler s_opcodetable[256];
|
static const ophandler s_opcodetable[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -438,18 +451,66 @@ public:
|
|||||||
cdp1802_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
cdp1802_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
cdp1802_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
// device_disasm_interface overrides
|
// device_disasm_interface overrides
|
||||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||||
|
|
||||||
virtual cosmac_device::ophandler get_ophandler(uint8_t opcode) const override;
|
virtual cosmac_device::ophandler get_ophandler(uint16_t opcode) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
static const ophandler s_opcodetable[256];
|
static const ophandler s_opcodetable[256];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> cdp1804_device
|
||||||
|
|
||||||
|
class cdp1804_device : public cdp1802_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
cdp1804_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
cdp1804_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
virtual cosmac_device::ophandler get_ophandler(uint16_t opcode) const override;
|
||||||
|
virtual bool has_extended_opcodes() override { return true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const ophandler s_opcodetable_ex[256];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> cdp1805_device
|
||||||
|
|
||||||
|
class cdp1805_device : public cdp1804_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
cdp1805_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
cdp1805_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> cdp1806_device
|
||||||
|
|
||||||
|
class cdp1806_device : public cdp1805_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
cdp1806_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// device type definition
|
// device type definition
|
||||||
DECLARE_DEVICE_TYPE(CDP1801, cdp1801_device)
|
DECLARE_DEVICE_TYPE(CDP1801, cdp1801_device)
|
||||||
DECLARE_DEVICE_TYPE(CDP1802, cdp1802_device)
|
DECLARE_DEVICE_TYPE(CDP1802, cdp1802_device)
|
||||||
|
DECLARE_DEVICE_TYPE(CDP1804, cdp1804_device)
|
||||||
|
DECLARE_DEVICE_TYPE(CDP1805, cdp1805_device)
|
||||||
|
DECLARE_DEVICE_TYPE(CDP1806, cdp1806_device)
|
||||||
|
|
||||||
|
|
||||||
#endif // MAME_CPU_COSMAC_COSMAC_H
|
#endif // MAME_CPU_COSMAC_COSMAC_H
|
||||||
|
@ -28,9 +28,9 @@ expensive wooden chessboards like Modular Exclusive or Muenchen, as long as it
|
|||||||
supports the higher voltage.
|
supports the higher voltage.
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- doesn't work, MAME doesn't emulate 1806 CPU (it uses RLDI, RLXA, RSXD, and
|
- remove external interrupt hack when timer interrupt is added to CDP1806 device
|
||||||
counter interrupt opcodes)
|
|
||||||
- mmirage unknown_w
|
- mmirage unknown_w
|
||||||
|
- mm1 unknown expansion rom at $c000?
|
||||||
- add mm1 opening book
|
- add mm1 opening book
|
||||||
- add mm1 STP/ON buttons? (they're off/on, with RAM chips remaining powered)
|
- add mm1 STP/ON buttons? (they're off/on, with RAM chips remaining powered)
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// devices/pointers
|
// devices/pointers
|
||||||
required_device<cdp1802_device> m_maincpu;
|
required_device<cdp1806_device> m_maincpu;
|
||||||
required_device<sensorboard_device> m_board;
|
required_device<sensorboard_device> m_board;
|
||||||
required_device<pwm_display_device> m_display;
|
required_device<pwm_display_device> m_display;
|
||||||
required_device<dac_bit_interface> m_dac;
|
required_device<dac_bit_interface> m_dac;
|
||||||
@ -256,7 +256,8 @@ void mm1_state::mirage_map(address_map &map)
|
|||||||
void mm1_state::mm1_map(address_map &map)
|
void mm1_state::mm1_map(address_map &map)
|
||||||
{
|
{
|
||||||
mirage_map(map);
|
mirage_map(map);
|
||||||
map(0xc000, 0xcfff).unmapr(); // bookrom?
|
map(0x8000, 0xbfff).unmapr(); // bookrom?
|
||||||
|
map(0xc000, 0xc000).nopr(); // looks for $c0, jumps to $c003 if true
|
||||||
}
|
}
|
||||||
|
|
||||||
void mm1_state::mm1_io(address_map &map)
|
void mm1_state::mm1_io(address_map &map)
|
||||||
@ -345,8 +346,8 @@ static INPUT_PORTS_START( mirage )
|
|||||||
|
|
||||||
PORT_START("FAKE") // module came with buttons sensorboard by default
|
PORT_START("FAKE") // module came with buttons sensorboard by default
|
||||||
PORT_CONFNAME( 0x01, 0x00, "Board Sensors" ) PORT_CHANGED_MEMBER(DEVICE_SELF, mm1_state, mirage_switch_sensor_type, nullptr)
|
PORT_CONFNAME( 0x01, 0x00, "Board Sensors" ) PORT_CHANGED_MEMBER(DEVICE_SELF, mm1_state, mirage_switch_sensor_type, nullptr)
|
||||||
PORT_CONFSETTING( 0x00, "Buttons" )
|
PORT_CONFSETTING( 0x00, "Buttons (Mirage)" )
|
||||||
PORT_CONFSETTING( 0x01, "Magnets" )
|
PORT_CONFSETTING( 0x01, "Magnets (Modular)" )
|
||||||
INPUT_PORTS_END
|
INPUT_PORTS_END
|
||||||
|
|
||||||
INPUT_CHANGED_MEMBER(mm1_state::mirage_switch_sensor_type)
|
INPUT_CHANGED_MEMBER(mm1_state::mirage_switch_sensor_type)
|
||||||
@ -363,7 +364,7 @@ INPUT_CHANGED_MEMBER(mm1_state::mirage_switch_sensor_type)
|
|||||||
void mm1_state::mirage(machine_config &config)
|
void mm1_state::mirage(machine_config &config)
|
||||||
{
|
{
|
||||||
/* basic machine hardware */
|
/* basic machine hardware */
|
||||||
CDP1802(config, m_maincpu, 8_MHz_XTAL);
|
CDP1806(config, m_maincpu, 8_MHz_XTAL);
|
||||||
m_maincpu->set_addrmap(AS_PROGRAM, &mm1_state::mirage_map);
|
m_maincpu->set_addrmap(AS_PROGRAM, &mm1_state::mirage_map);
|
||||||
m_maincpu->set_addrmap(AS_IO, &mm1_state::mm1_io);
|
m_maincpu->set_addrmap(AS_IO, &mm1_state::mm1_io);
|
||||||
m_maincpu->clear_cb().set(FUNC(mm1_state::clear_r));
|
m_maincpu->clear_cb().set(FUNC(mm1_state::clear_r));
|
||||||
@ -371,7 +372,9 @@ void mm1_state::mirage(machine_config &config)
|
|||||||
m_maincpu->ef3_cb().set(FUNC(mm1_state::keypad_r<0>));
|
m_maincpu->ef3_cb().set(FUNC(mm1_state::keypad_r<0>));
|
||||||
m_maincpu->ef4_cb().set(FUNC(mm1_state::keypad_r<1>));
|
m_maincpu->ef4_cb().set(FUNC(mm1_state::keypad_r<1>));
|
||||||
|
|
||||||
m_maincpu->set_periodic_int(FUNC(mm1_state::interrupt), attotime::from_hz(150)); // fake
|
// wrong! uses internal timer interrupt
|
||||||
|
const attotime irq_period = attotime::from_ticks(8 * 32 * 0x71, 8_MHz_XTAL); // LDC = 0x71
|
||||||
|
m_maincpu->set_periodic_int(FUNC(mm1_state::interrupt), irq_period);
|
||||||
|
|
||||||
SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS);
|
SENSORBOARD(config, m_board).set_type(sensorboard_device::BUTTONS);
|
||||||
m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
|
m_board->init_cb().set(m_board, FUNC(sensorboard_device::preset_chess));
|
||||||
@ -396,6 +399,10 @@ void mm1_state::mm1(machine_config &config)
|
|||||||
m_maincpu->set_addrmap(AS_PROGRAM, &mm1_state::mm1_map);
|
m_maincpu->set_addrmap(AS_PROGRAM, &mm1_state::mm1_map);
|
||||||
m_maincpu->q_cb().set(FUNC(mm1_state::q_w));
|
m_maincpu->q_cb().set(FUNC(mm1_state::q_w));
|
||||||
|
|
||||||
|
// wrong! uses internal timer interrupt
|
||||||
|
const attotime irq_period = attotime::from_ticks(8 * 32 * 0xfa, 8_MHz_XTAL); // LDC = 0xFA
|
||||||
|
m_maincpu->set_periodic_int(FUNC(mm1_state::interrupt), irq_period);
|
||||||
|
|
||||||
m_board->set_type(sensorboard_device::MAGNETS);
|
m_board->set_type(sensorboard_device::MAGNETS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user