mirror of
https://github.com/holub/mame
synced 2025-06-06 21:03:47 +03:00
mn1880: Add preliminary CPU emulation
This commit is contained in:
parent
6b42021033
commit
e9e66e0224
File diff suppressed because it is too large
Load Diff
@ -12,19 +12,30 @@ public:
|
|||||||
mn1880_device(const machine_config &config, const char *tag, device_t *owner, u32 clock);
|
mn1880_device(const machine_config &config, const char *tag, device_t *owner, u32 clock);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MN1880_IP, MN1880_FS,
|
MN1880_IP, MN1880_IPA, MN1880_IPB,
|
||||||
MN1880_XP, MN1880_YP,
|
MN1880_IR, MN1880_IRA, MN1880_IRB,
|
||||||
MN1880_XPL, MN1880_XPH, MN1880_YPL, MN1880_YPH,
|
MN1880_FS, MN1880_FSA, MN1880_FSB,
|
||||||
MN1880_SP, MN1880_LP
|
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:
|
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
|
// device-level overrides
|
||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
virtual void device_reset() override;
|
virtual void device_reset() override;
|
||||||
|
|
||||||
// device_execute_interface overrides
|
// device_execute_interface overrides
|
||||||
virtual void execute_run() override;
|
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
|
// device_disasm_interface overrides
|
||||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
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;
|
virtual void state_string_export(const device_state_entry &entry, std::string &str) const override;
|
||||||
|
|
||||||
private:
|
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 spaces
|
||||||
address_space_config m_program_config;
|
address_space_config m_program_config;
|
||||||
address_space_config m_data_config;
|
address_space_config m_data_config;
|
||||||
@ -43,12 +190,14 @@ private:
|
|||||||
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_data;
|
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_data;
|
||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
u16 m_ip;
|
cpu_registers m_cpu[2];
|
||||||
u8 m_fs;
|
bool m_cpu_select;
|
||||||
u16 m_xp;
|
u8 m_cpum;
|
||||||
u16 m_yp;
|
microstate m_ustate;
|
||||||
u16 m_sp;
|
u16 m_da;
|
||||||
u16 m_lp;
|
u16 m_tmp1;
|
||||||
|
u16 m_tmp2;
|
||||||
|
bool m_output_queued;
|
||||||
s32 m_icount;
|
s32 m_icount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "cpu/mn1880/mn1880.h"
|
#include "cpu/mn1880/mn1880.h"
|
||||||
//#include "machine/eeprompar.h"
|
#include "machine/eeprompar.h"
|
||||||
|
|
||||||
class basssta_state : public driver_device
|
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)
|
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)
|
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)
|
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_PROGRAM, &basssta_state::bassstr_prog);
|
||||||
m_maincpu->set_addrmap(AS_DATA, &basssta_state::bassstr_data);
|
m_maincpu->set_addrmap(AS_DATA, &basssta_state::bassstr_data);
|
||||||
|
|
||||||
|
EEPROM_2816(config, "eeprom");
|
||||||
}
|
}
|
||||||
|
|
||||||
void basssta_state::sbasssta(machine_config &config)
|
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_PROGRAM, &basssta_state::sbasssta_prog);
|
||||||
m_maincpu->set_addrmap(AS_DATA, &basssta_state::sbasssta_data);
|
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)
|
ROM_START(bassstr)
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "cpu/adsp2100/adsp2100.h"
|
#include "cpu/adsp2100/adsp2100.h"
|
||||||
#include "cpu/mn1880/mn1880.h"
|
#include "cpu/mn1880/mn1880.h"
|
||||||
//#include "machine/eeprompar.h"
|
#include "machine/eeprompar.h"
|
||||||
|
|
||||||
class drumsta_state : public driver_device
|
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)
|
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
|
ADSP2181(config, m_dsp, 16000000).set_disable(); // clock unknown
|
||||||
|
|
||||||
// TODO: Atmel AT28C64 EEPROM
|
EEPROM_2864(config, "eeprom"); // Atmel AT28C64
|
||||||
}
|
}
|
||||||
|
|
||||||
ROM_START(drumsta)
|
ROM_START(drumsta)
|
||||||
|
@ -87,6 +87,29 @@ void macpci_state::cdmcu_mem(address_map &map)
|
|||||||
map(0x0000, 0xffff).rom().region("cdrom", 0);
|
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 */
|
/* Input ports */
|
||||||
static INPUT_PORTS_START( pippin )
|
static INPUT_PORTS_START( pippin )
|
||||||
INPUT_PORTS_END
|
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
|
mn1880_device &cdmcu(MN1880(config, "cdmcu", 8388608)); // type and clock unknown
|
||||||
cdmcu.set_addrmap(AS_PROGRAM, &macpci_state::cdmcu_mem);
|
cdmcu.set_addrmap(AS_PROGRAM, &macpci_state::cdmcu_mem);
|
||||||
|
cdmcu.set_addrmap(AS_DATA, &macpci_state::cdmcu_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ROM definition */
|
/* ROM definition */
|
||||||
|
@ -146,6 +146,7 @@ private:
|
|||||||
void init_pippin();
|
void init_pippin();
|
||||||
void pippin_mem(address_map &map);
|
void pippin_mem(address_map &map);
|
||||||
void cdmcu_mem(address_map &map);
|
void cdmcu_mem(address_map &map);
|
||||||
|
void cdmcu_data(address_map &map);
|
||||||
// wait states for accessing the VIA
|
// wait states for accessing the VIA
|
||||||
int m_via_cycles;
|
int m_via_cycles;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user