mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +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);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user