mn1880: Add preliminary CPU emulation

This commit is contained in:
AJR 2021-04-27 14:06:19 -04:00
parent 6b42021033
commit e9e66e0224
6 changed files with 2474 additions and 61 deletions

File diff suppressed because it is too large Load Diff

View File

@ -12,19 +12,30 @@ public:
mn1880_device(const machine_config &config, const char *tag, device_t *owner, u32 clock);
enum {
MN1880_IP, MN1880_FS,
MN1880_XP, MN1880_YP,
MN1880_XPL, MN1880_XPH, MN1880_YPL, MN1880_YPH,
MN1880_SP, MN1880_LP
MN1880_IP, MN1880_IPA, MN1880_IPB,
MN1880_IR, MN1880_IRA, MN1880_IRB,
MN1880_FS, MN1880_FSA, MN1880_FSB,
MN1880_XP, MN1880_XPA, MN1880_XPB,
MN1880_YP, MN1880_YPA, MN1880_YPB,
MN1880_XPL, MN1880_XPH,
MN1880_YPL, MN1880_YPH,
MN1880_SP, MN1880_SPA, MN1880_SPB,
MN1880_LP, MN1880_LPA, MN1880_LPB,
MN1880_DIVIDER1, MN1880_DIVIDER2,
MN1880_CPUM
};
protected:
mn1880_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor data_map);
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// device_execute_interface overrides
virtual void execute_run() override;
virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override { return (clocks + 4 - 1) / 4; }
virtual uint64_t execute_cycles_to_clocks(uint64_t cycles) const noexcept override { return (cycles * 4); }
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
@ -36,6 +47,142 @@ protected:
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
private:
struct cpu_registers
{
cpu_registers() : ip(0), irp(0), ir(0), fs(0), xp(0), yp(0), sp(0), lp(0), wait(0) { }
u8 addcz(u8 data1, u8 data2, bool carry, bool holdz);
u8 adddcz(u8 data1, u8 data2, bool carry);
u8 subcz(u8 data1, u8 data2, bool carry, bool holdz);
u8 subdcz(u8 data1, u8 data2, bool carry);
u8 rolc(u8 data);
u8 rorc(u8 data);
u8 asrc(u8 data);
void branch(u16 label);
u16 ip;
u16 irp;
u8 ir;
u8 fs;
u16 xp;
u16 yp;
u16 sp;
u16 lp;
u16 wait;
};
enum class microstate : u8 {
NEXT,
NOP_1,
REP_1,
CLRSET_1,
T1B_1,
MOVL31_1, MOVL31_2,
MOVL34_1, MOVL34_2, MOVL34_3, MOVL34_4,
MOVL35_1, MOVL35_2, MOVL35_3, MOVL35_4,
MOV36_1, MOV36_2,
MOV37_1,
MOVL38_1, MOVL38_2, MOVL38_3,
MOVL39_1, MOVL39_2, MOVL39_3,
ASL_1, ASL_2,
ASR_1, ASR_2,
DEC40_1,
NOT_1,
CMPM44_1, CMPM44_2, CMPM44_3,
CMPM45_1, CMPM45_2,
XCH4_1, XCH4_2,
INC48_1,
CLR4A_1,
ROL_1, ROL_2,
ROR_1, ROR_2,
CMPM50_1, CMPM50_2, CMPM50_3,
CMPM52_1, CMPM52_2,
DIV51_1, DIV51_2, DIV51_3, DIV51_4, DIV51_5, DIV51_6, DIV51_7, DIV51_8, DIV51_9, DIV51_10,
MOVDA_1, MOVDA_2, MOVDA_3,
MOV54_1,
MOV55_1,
MOV56_1, MOV56_2,
XCH58_1, XCH58_2, XCH58_3, XCH58_4,
MUL59_1, MUL59_2, MUL59_3, MUL59_4, MUL59_5, MUL59_6, MUL59_7, MUL59_8,
MOVL5C_1, MOVL5C_2, MOVL5C_3,
MOVL5D_1, MOVL5D_2,
MOVL5E_1, MOVL5E_2, MOVL5E_3, MOVL5E_4,
MOVL5F_1, MOVL5F_2,
CMP_1, CMP_2, CMP_3,
AND_1, AND_2, AND_3,
XOR_1, XOR_2, XOR_3,
OR_1, OR_2, OR_3,
SUBC_1, SUBC_2, SUBC_3,
SUBD_1, SUBD_2, SUBD_3, SUBD_4,
ADDC_1, ADDC_2, ADDC_3,
ADDD_1, ADDD_2, ADDD_3, ADDD_4,
BR80_1, BR88_1,
CMPL_1, CMPL_2, CMPL_3, CMPL_4, CMPL_5,
CLRFS_1, SETFS_1,
CALL90_1, CALL90_2,
BRA0_1,
POPFS_1, POPFS_2,
POPB4_1, POPB4_2, POPB4_3,
POPB5_1, POPB5_2,
POPB7_1,
PUSHFS_1,
PUSHBC_1, PUSHBC_2, PUSHBC_3,
PUSHBD_1, PUSHBD_2, PUSHBD_3,
PUSHBF_1,
SUBCL_1, SUBCL_2, SUBCL_3, SUBCL_4, SUBCL_5, SUBCL_6,
DIVC1_1, DIVC1_2,
XCHC4_1, XCHC4_2,
XCHC5_1, XCHC5_2,
ADDCL_1, ADDCL_2, ADDCL_3, ADDCL_4, ADDCL_5, ADDCL_6,
MULC9_1, MULC9_2, MULC9_3,
MOVCC_1,
MOVCD_1, MOVCD_2,
CMPD0_1, CMPD0_2,
CMPD1_1, CMPD1_2,
XCHD4_1, XCHD4_2,
XCHD7_1,
MOVD8_1,
MOVD9_1,
MOVDC_1,
MOVDD_1,
LOOP_1, LOOP_2,
DECE4_1,
INCE5_1,
ADDRE8_1, ADDRE8_2, ADDRE8_3,
ADDRE9_1, ADDRE9_2, ADDRE9_3,
ADDREC_1,
ADDRED_1,
CMPBF0_1,
CMPBF1_1, CMPBF1_2, CMPBF1_3,
MOV1_1, MOV1_2, MOV1_3, MOV1_4, MOV1N_4,
WAIT_1, WAIT_2,
RET_1, RET_2, RET_3,
RETI_1, RETI_2, RETI_3, RETI_4, RETI_5,
BR_1, BR_2,
CALL_1, CALL_2, CALL_3,
PUSHFB_1,
BRFC_1,
CALLFD_1,
RDTBL_1, RDTBL_2, RDTBL_3,
PI_1,
UNKNOWN
};
static void setl(u16 &pr, u8 data) { pr = (pr & 0xff00) | data; }
static void seth(u16 &pr, u8 data) { pr = (pr & 0x00ff) | (data << 8); }
u8 cpum_r();
void cpum_w(u8 data);
void internal_data_map(address_map &map);
void swap_cpus();
void next_instruction(u8 input);
static const microstate s_decode_map[256];
static const u16 s_input_queue_map[16];
static const u8 s_branch_fs[4];
// address spaces
address_space_config m_program_config;
address_space_config m_data_config;
@ -43,12 +190,14 @@ private:
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_data;
// internal state
u16 m_ip;
u8 m_fs;
u16 m_xp;
u16 m_yp;
u16 m_sp;
u16 m_lp;
cpu_registers m_cpu[2];
bool m_cpu_select;
u8 m_cpum;
microstate m_ustate;
u16 m_da;
u16 m_tmp1;
u16 m_tmp2;
bool m_output_queued;
s32 m_icount;
};

View File

@ -8,7 +8,7 @@
#include "emu.h"
#include "cpu/mn1880/mn1880.h"
//#include "machine/eeprompar.h"
#include "machine/eeprompar.h"
class basssta_state : public driver_device
{
@ -44,10 +44,34 @@ void basssta_state::sbasssta_prog(address_map &map)
void basssta_state::bassstr_data(address_map &map)
{
map(0x0001, 0x0001).noprw();
map(0x0003, 0x0003).noprw();
map(0x000f, 0x000f).noprw();
map(0x0015, 0x0015).noprw();
map(0x001f, 0x001f).noprw();
map(0x0060, 0x03cf).ram();
map(0x8000, 0x87ff).rw("eeprom", FUNC(eeprom_parallel_28xx_device::read), FUNC(eeprom_parallel_28xx_device::write));
}
void basssta_state::sbasssta_data(address_map &map)
{
map(0x0000, 0x0003).nopr();
map(0x0001, 0x0001).nopw();
map(0x0003, 0x0003).nopw();
map(0x000f, 0x000f).noprw();
map(0x0012, 0x0015).noprw();
map(0x001c, 0x001c).nopr();
map(0x001e, 0x001e).nopw();
map(0x001f, 0x001f).noprw();
map(0x0030, 0x0030).nopw();
map(0x0032, 0x0032).nopw();
map(0x0034, 0x0034).nopw();
map(0x0036, 0x0036).nopw();
map(0x005d, 0x005d).noprw();
map(0x0060, 0x07ff).ram(); // TODO: probably internal to CPU
map(0x6000, 0x7fff).rw("eeprom", FUNC(eeprom_parallel_28xx_device::read), FUNC(eeprom_parallel_28xx_device::write));
map(0x8001, 0x8004).nopw();
map(0xc000, 0xc000).nopr();
}
@ -56,9 +80,11 @@ INPUT_PORTS_END
void basssta_state::bassstr(machine_config &config)
{
MN1880(config, m_maincpu, 8000000); // type and clock unknown (custom silkscreen)
MN1880(config, m_maincpu, 8000000); // type and clock unknown (custom silkscreen; might be MN18P83220)
m_maincpu->set_addrmap(AS_PROGRAM, &basssta_state::bassstr_prog);
m_maincpu->set_addrmap(AS_DATA, &basssta_state::bassstr_data);
EEPROM_2816(config, "eeprom");
}
void basssta_state::sbasssta(machine_config &config)
@ -67,7 +93,7 @@ void basssta_state::sbasssta(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &basssta_state::sbasssta_prog);
m_maincpu->set_addrmap(AS_DATA, &basssta_state::sbasssta_data);
// TODO: Microchip 28C64AF EEPROM
EEPROM_2864(config, "eeprom"); // Microchip 28C64AF-15I/L
}
ROM_START(bassstr)

View File

@ -9,7 +9,7 @@
#include "emu.h"
#include "cpu/adsp2100/adsp2100.h"
#include "cpu/mn1880/mn1880.h"
//#include "machine/eeprompar.h"
#include "machine/eeprompar.h"
class drumsta_state : public driver_device
{
@ -39,6 +39,12 @@ void drumsta_state::drumsta_prog(address_map &map)
void drumsta_state::drumsta_data(address_map &map)
{
map(0x0001, 0x0001).noprw();
map(0x0003, 0x0003).noprw();
map(0x000e, 0x000f).noprw();
map(0x0015, 0x0015).noprw();
map(0x0060, 0x031f).ram();
map(0xb000, 0xb7ff).rw("eeprom", FUNC(eeprom_parallel_28xx_device::read), FUNC(eeprom_parallel_28xx_device::write));
}
@ -53,7 +59,7 @@ void drumsta_state::drumsta(machine_config &config)
ADSP2181(config, m_dsp, 16000000).set_disable(); // clock unknown
// TODO: Atmel AT28C64 EEPROM
EEPROM_2864(config, "eeprom"); // Atmel AT28C64
}
ROM_START(drumsta)

View File

@ -87,6 +87,29 @@ void macpci_state::cdmcu_mem(address_map &map)
map(0x0000, 0xffff).rom().region("cdrom", 0);
}
void macpci_state::cdmcu_data(address_map &map)
{
map(0x0000, 0x0001).noprw();
map(0x0003, 0x0003).noprw();
map(0x0004, 0x0008).nopw();
map(0x0008, 0x0008).nopr();
map(0x0009, 0x0009).noprw();
map(0x000f, 0x000f).noprw();
map(0x0012, 0x0013).ram();
map(0x0015, 0x0015).noprw();
map(0x001f, 0x0021).nopw();
map(0x0031, 0x0031).noprw();
map(0x0033, 0x0033).nopw();
map(0x0036, 0x0036).noprw();
map(0x0060, 0x031f).ram();
map(0x802a, 0x802a).nopw();
map(0x802f, 0x8034).nopw();
map(0x8032, 0x8032).nopr();
map(0x8035, 0x8035).lr8(NAME([]() { return 0x40; }));
map(0x8037, 0x8037).noprw();
map(0x8038, 0x8039).nopw();
}
/* Input ports */
static INPUT_PORTS_START( pippin )
INPUT_PORTS_END
@ -149,6 +172,7 @@ void macpci_state::pippin(machine_config &config)
mn1880_device &cdmcu(MN1880(config, "cdmcu", 8388608)); // type and clock unknown
cdmcu.set_addrmap(AS_PROGRAM, &macpci_state::cdmcu_mem);
cdmcu.set_addrmap(AS_DATA, &macpci_state::cdmcu_data);
}
/* ROM definition */

View File

@ -146,6 +146,7 @@ private:
void init_pippin();
void pippin_mem(address_map &map);
void cdmcu_mem(address_map &map);
void cdmcu_data(address_map &map);
// wait states for accessing the VIA
int m_via_cycles;