pps41: added mm78 disasm and mm77/mm78 skeleton device

This commit is contained in:
hap 2021-03-08 15:51:52 +01:00
parent e8cdd00685
commit 82461369ff
12 changed files with 326 additions and 22 deletions

View File

@ -2880,6 +2880,7 @@ end
-- Rockwell PPS-4/1
--@src/devices/cpu/pps41/mm75.h,CPUS["PPS41"] = true
--@src/devices/cpu/pps41/mm76.h,CPUS["PPS41"] = true
--@src/devices/cpu/pps41/mm78.h,CPUS["PPS41"] = true
--------------------------------------------------
if CPUS["PPS41"] then
@ -2892,6 +2893,9 @@ if CPUS["PPS41"] then
MAME_DIR .. "src/devices/cpu/pps41/mm76.cpp",
MAME_DIR .. "src/devices/cpu/pps41/mm76.h",
MAME_DIR .. "src/devices/cpu/pps41/mm76op.cpp",
MAME_DIR .. "src/devices/cpu/pps41/mm78.cpp",
MAME_DIR .. "src/devices/cpu/pps41/mm78.h",
MAME_DIR .. "src/devices/cpu/pps41/mm78op.cpp",
}
end

View File

@ -25,7 +25,7 @@ void mm75_device::op_i2c()
}
// slightly different opcodes
// changed opcodes
void mm75_device::op_ibm()
{

View File

@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:hap
// MM76 opcode handlers
// MM76/shared opcode handlers
#include "emu.h"
#include "mm76.h"

View File

@ -0,0 +1,109 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Rockwell MM77/MM78 MCU
*/
#include "emu.h"
#include "mm78.h"
#include "pps41d.h"
DEFINE_DEVICE_TYPE(MM78, mm78_device, "mm78", "Rockwell MM78") // 2KB bytes ROM, 128 nibbles RAM
DEFINE_DEVICE_TYPE(MM78L, mm78l_device, "mm78l", "Rockwell MM78L") // low-power
DEFINE_DEVICE_TYPE(MM77, mm77_device, "mm77", "Rockwell MM77") // 1.3KB ROM, 96 nibbles RAM
DEFINE_DEVICE_TYPE(MM77L, mm77l_device, "mm77l", "Rockwell MM77L") // 1.5KB ROM, low-power
// constructor
mm78_device::mm78_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
mm78_device(mconfig, MM78, tag, owner, clock, 11, address_map_constructor(FUNC(mm78_device::program_2k), this), 7, address_map_constructor(FUNC(mm78_device::data_128x4), this))
{ }
mm78_device::mm78_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) :
mm76_device(mconfig, type, tag, owner, clock, prgwidth, program, datawidth, data)
{ }
mm78l_device::mm78l_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
mm78_device(mconfig, MM78L, tag, owner, clock, 11, address_map_constructor(FUNC(mm78l_device::program_2k), this), 7, address_map_constructor(FUNC(mm78l_device::data_128x4), this))
{ }
mm77_device::mm77_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
mm77_device(mconfig, MM77, tag, owner, clock, 11, address_map_constructor(FUNC(mm77_device::program_1_3k), this), 7, address_map_constructor(FUNC(mm77_device::data_96x4), this))
{ }
mm77_device::mm77_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) :
mm78_device(mconfig, type, tag, owner, clock, prgwidth, program, datawidth, data)
{ }
mm77l_device::mm77l_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
mm77_device(mconfig, MM77L, tag, owner, clock, 11, address_map_constructor(FUNC(mm77l_device::program_1_5k), this), 7, address_map_constructor(FUNC(mm77l_device::data_96x4), this))
{ }
// internal memory maps
void mm78_device::program_2k(address_map &map)
{
map(0x000, 0x7ff).rom();
}
void mm77_device::program_1_3k(address_map &map)
{
map(0x040, 0x1ff).rom();
map(0x240, 0x3ff).rom();
map(0x640, 0x7ff).rom();
}
void mm77l_device::program_1_5k(address_map &map)
{
map(0x000, 0x3ff).rom();
map(0x600, 0x7ff).rom();
}
void mm78_device::data_128x4(address_map &map)
{
map(0x00, 0x7f).ram();
}
void mm77_device::data_96x4(address_map &map)
{
map(0x00, 0x3f).ram();
map(0x40, 0x47).mirror(0x18).ram(); // not to 0x50
map(0x50, 0x57).ram();
map(0x60, 0x67).mirror(0x18).ram(); // not to 0x70
map(0x70, 0x77).ram();
}
// disasm
std::unique_ptr<util::disasm_interface> mm78_device::create_disassembler()
{
return std::make_unique<mm78_disassembler>();
}
// initialize
void mm78_device::device_start()
{
mm76_device::device_start();
m_stack_levels = 2;
state_add(++m_state_count, "X", m_x).formatstr("%01X");
}
void mm78_device::device_reset()
{
mm76_device::device_reset();
}
//-------------------------------------------------
// execute
//-------------------------------------------------
void mm78_device::execute_one()
{
}

View File

@ -0,0 +1,107 @@
// license:BSD-3-Clause
// copyright-holders:hap
/*
Rockwell MM77/MM78 MCU
*/
#ifndef MAME_CPU_PPS41_MM78_H
#define MAME_CPU_PPS41_MM78_H
#pragma once
#include "mm76.h"
// pinout reference
/*
____ ____ ____ ____
BP 1 |* \_/ | 42 DIO9 BP 1 |* \_/ | 40 DIO9
A 2 | | 41 DIO8 A 2 | | 39 DIO8
CLKIN 3 | | 40 DIO7 XTLOUT 3 | | 38 DIO7
EXCLK 4 | | 39 DIO6 XTLIN 4 | | 37 DIO6
VC 5 | | 38 DIO5 VC 5 | | 36 DIO5
Vdd 6 | | 37 DIO4 Vdd 6 | | 35 DIO4
Vss 7 | | 36 DIO3 Vss 7 | | 34 DIO3
N/C 8 | | 35 DIO2 TEST 8 | | 33 DIO2
TEST 9 | | 34 DIO1 PI4 9 | | 32 DIO1
PI4 10 | MM78 | 33 DIO0 PI8 10 | MM78L | 31 DIO0
PI8 11 | MM77 | 32 INT1 PI3 11 | MM77L | 30 INT1
PI3 12 | | 31 INT0 PI7 12 | | 29 INT0
PI7 13 | | 30 DATAI PI6 13 | | 28 DATAI
PI6 14 | | 29 DATAO PI2 14 | | 27 DATAO
PI2 15 | | 28 CLOCK PI5 15 | | 26 CLOCK
PI5 16 | | 27 RIO4 PI1 16 | | 25 RIO4
Vdd 17 | | 26 RIO3 PO 17 | | 24 RIO3
PI1 18 | | 25 RIO2 RIO5 18 | | 23 RIO2
PO 19 | | 24 RIO1 RIO6 19 | | 22 RIO1
RIO5 20 | | 23 RIO8 RIO7 20 |___________| 21 RIO8
RIO6 21 |___________| 22 RIO7
*/
class mm78_device : public mm76_device
{
public:
mm78_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
mm78_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override { ; }
// device_disasm_interface overrides
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
// device_execute_interface overrides
virtual void execute_one() override;
void data_128x4(address_map &map);
void program_2k(address_map &map);
// opcode helpers
virtual bool op_is_eob(u8 op) override { return (op & 0xf8) == 0x08; };
virtual bool op_is_lb(u8 op) override { return (op & 0xf0) == 0x10; };
virtual bool op_is_lai(u8 op) override { return (op & 0xf0) == 0x40; };
// opcode handlers
};
class mm78l_device : public mm78_device
{
public:
mm78l_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
};
class mm77_device : public mm78_device
{
public:
mm77_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
mm77_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
void data_96x4(address_map &map);
void program_1_3k(address_map &map);
};
class mm77l_device : public mm77_device
{
public:
mm77l_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
void program_1_5k(address_map &map);
};
DECLARE_DEVICE_TYPE(MM78, mm78_device)
DECLARE_DEVICE_TYPE(MM78L, mm78l_device)
DECLARE_DEVICE_TYPE(MM77, mm77_device)
DECLARE_DEVICE_TYPE(MM77L, mm77l_device)
#endif // MAME_CPU_PPS41_MM78_H

View File

@ -0,0 +1,14 @@
// license:BSD-3-Clause
// copyright-holders:hap
// MM77/MM78 opcode handlers
#include "emu.h"
#include "mm78.h"
// opcodes
// changed opcodes
// new opcodes

View File

@ -40,7 +40,8 @@ TODO:
flops with SOS/ROS opcodes
- add MCU mask options, there's one for inverting interrupts
- add serial i/o
- add MM78
- add MM78 opcodes
- add MM78LA
*/
@ -69,11 +70,6 @@ pps41_base_device::pps41_base_device(const machine_config &mconfig, device_type
// device_start - device-specific startup
//-------------------------------------------------
enum
{
PPS41_PC=1, PPS41_A, PPS41_C, PPS41_B, PPS41_S
};
void pps41_base_device::device_start()
{
m_program = &space(AS_PROGRAM);
@ -113,6 +109,7 @@ void pps41_base_device::device_start()
m_c_in = 0;
m_c_delay = false;
m_s = 0;
m_x = 0;
m_skip = false;
m_skip_count = 0;
@ -144,6 +141,7 @@ void pps41_base_device::device_start()
save_item(NAME(m_c_in));
save_item(NAME(m_c_delay));
save_item(NAME(m_s));
save_item(NAME(m_x));
save_item(NAME(m_skip));
save_item(NAME(m_skip_count));
@ -155,12 +153,13 @@ void pps41_base_device::device_start()
// register state for debugger
state_add(STATE_GENPC, "GENPC", m_pc).formatstr("%03X").noshow();
state_add(STATE_GENPCBASE, "CURPC", m_prev_pc).formatstr("%03X").noshow();
state_add(PPS41_PC, "PC", m_pc).formatstr("%03X");
state_add(PPS41_A, "A", m_a).formatstr("%01X");
state_add(PPS41_C, "C", m_c_in).formatstr("%01X");
state_add(PPS41_B, "B", m_b).formatstr("%02X");
state_add(PPS41_S, "S", m_s).formatstr("%01X");
m_state_count = 0;
state_add(++m_state_count, "PC", m_pc).formatstr("%03X");
state_add(++m_state_count, "A", m_a).formatstr("%01X");
state_add(++m_state_count, "C", m_c_in).formatstr("%01X");
state_add(++m_state_count, "B", m_b).formatstr("%02X");
state_add(++m_state_count, "S", m_s).formatstr("%01X");
set_icountptr(m_icount);
}
@ -197,8 +196,7 @@ void pps41_base_device::device_reset()
void pps41_base_device::execute_set_input(int line, int state)
{
// negative voltage, Vdd=0, Vss(GND)=1
state = (state) ? 0 : 1;
state = (state) ? 1 : 0;
switch (line)
{

View File

@ -62,6 +62,7 @@ protected:
address_space *m_data;
int m_icount;
int m_state_count;
// fixed settings or mask options
int m_prgwidth; // ROM/RAM address size
@ -100,6 +101,7 @@ protected:
int m_c_in;
bool m_c_delay;
u8 m_s;
u8 m_x;
bool m_skip;
int m_skip_count;

View File

@ -34,6 +34,7 @@ offs_t pps41_common_disassembler::increment_pc(offs_t pc)
const char *const pps41_common_disassembler::s_name[] =
{
// MM76
"?",
"XAB", "LBA", "LB", "EOB",
"SB", "RB", "SKBF",
@ -42,13 +43,19 @@ const char *const pps41_common_disassembler::s_name[] =
"A", "AC", "ACSK", "ASK", "COM", "RC", "SC", "SKNC", "LAI", "AISK",
"RT", "RTSK", "T", "NOP", "TL", "TM", "TML", "TR",
"SKMEA", "SKBEI", "SKAEI",
"SOS", "ROS", "SKISL", "IBM", "OB", "IAM", "OA", "IOS", "I1", "I2C", "INT1H", "DIN1", "INT0L", "DIN0", "SEG1", "SEG2"
"SOS", "ROS", "SKISL", "IBM", "OB", "IAM", "OA", "IOS", "I1", "I2C", "INT1H", "DIN1", "INT0L", "DIN0", "SEG1", "SEG2",
// MM78
"INT0H", "INT1L", "SAG", "EOB", "TAB",
"I1SK", "IX", "OX", "LXA", "XAX", "IOA",
"TLB", "TMLB"
};
// number of bits per opcode parameter
// note: d4 means hex, d5 means inverted, d6 means extended
// note: d4 means hex, d5 means inverted, d6 means extended, d7 means double extended
const u8 pps41_common_disassembler::s_bits[] =
{
// MM76
0,
0, 0, 4, 2,
2, 2, 2,
@ -58,10 +65,16 @@ const u8 pps41_common_disassembler::s_bits[] =
0, 0, 0x36, 0, 0x76, 0x36, 0x76, 0x34,
0, 0x40, 0x60,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// MM78
0, 0, 0, 3, 0,
0, 0, 0, 0, 0, 0,
0xf6, 0xf6
};
const u32 pps41_common_disassembler::s_flags[] =
{
// MM76
0,
0, 0, 0, 0,
0, 0, 0,
@ -71,6 +84,11 @@ const u32 pps41_common_disassembler::s_flags[] =
STEP_OUT, STEP_OUT, 0, 0, 0, STEP_OVER, STEP_OVER, 0,
0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// MM78
0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, STEP_OVER
};
@ -115,7 +133,7 @@ const u8 mm76_disassembler::mm76_opmap[0x100] =
{
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
em_NOP, em_SKNC, em_RT, em_RTSK, em_INT0L,em_INT1H,em_DIN1, em_DIN0, em_SKBF, em_SKBF, em_SKBF, em_SKBF, em_SC, em_RC, em_SEG1, em_SEG2, // 0
em_SB, em_SB, em_SB, em_SB, em_RB, em_RB, em_RB, em_RB, em_OA, em_OB, em_IAM, em_IBM, em_EOB, em_EOB, em_EOB, em_EOB, // 1
em_SB, em_SB, em_SB, em_SB, em_RB, em_RB, em_RB, em_RB, em_OA, em_OB, em_IAM, em_IBM, em_EOB2, em_EOB2, em_EOB2, em_EOB2, // 1
em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, // 2
em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, // 3
@ -139,3 +157,35 @@ offs_t mm76_disassembler::disassemble(std::ostream &stream, offs_t pc, const dat
{
return common_disasm(mm76_opmap, stream, pc, opcodes, params);
}
// MM78 disasm
const u8 mm78_disassembler::mm78_opmap[0x100] =
{
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
em_NOP, em_SKISL,em_SKNC, em_INT0H,em_INT1L,em_RC, em_SC, em_SAG, em_EOB3, em_EOB3, em_EOB3, em_EOB3, em_EOB3, em_EOB3, em_EOB3, em_EOB3, // 0
em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, em_LB, // 1
em_SB, em_SB, em_SB, em_SB, em_RB, em_RB, em_RB, em_RB, em_SKBF, em_SKBF, em_SKBF, em_SKBF, em_TAB, em_IOS, em_RTSK, em_RT, // 2
em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, em_TR, // 3
em_LAI, em_LAI, em_LAI, em_LAI, em_LAI, em_LAI, em_LAI, em_LAI, em_LAI, em_LAI, em_LAI, em_LAI, em_LAI, em_LAI, em_LAI, em_LAI, // 4
em_L, em_L, em_L, em_L, em_XNSK, em_XNSK, em_XNSK, em_XNSK, em_XDSK, em_XDSK, em_XDSK, em_XDSK, em_X, em_X, em_X, em_X, // 5
em_I1SK, em_AISK, em_AISK, em_AISK, em_AISK, em_AISK, em_AISK, em_AISK, em_AISK, em_AISK, em_AISK, em_AISK, em_AISK, em_AISK, em_AISK, em_AISK, // 6
em_SOS, em_ROS, em_IX, em_OX, em_XAS, em_LXA, em_LBA, em_COM, em_I2C, em_XAX, em_XAB, em_IOA, em_AC, em_ACSK, em_A, em_SKMEA,// 7
em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, // 8
em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, // 9
em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, // A
em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, em_TM, // B
em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, // C
em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, // D
em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, // E
em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T, em_T // F
};
offs_t mm78_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
return common_disasm(mm78_opmap, stream, pc, opcodes, params);
}

View File

@ -28,8 +28,9 @@ protected:
// opcode mnemonics
enum e_mnemonics
{
em_ILL,
em_XAB, em_LBA, em_LB, em_EOB,
// MM76/shared
em_ILL /* 0! */,
em_XAB, em_LBA, em_LB, em_EOB2,
em_SB, em_RB, em_SKBF,
em_XAS, em_LSA,
em_L, em_X, em_XDSK, em_XNSK,
@ -37,6 +38,11 @@ protected:
em_RT, em_RTSK, em_T, em_NOP, em_TL, em_TM, em_TML, em_TR,
em_SKMEA, em_SKBEI, em_SKAEI,
em_SOS, em_ROS, em_SKISL, em_IBM, em_OB, em_IAM, em_OA, em_IOS, em_I1, em_I2C, em_INT1H, em_DIN1, em_INT0L, em_DIN0, em_SEG1, em_SEG2,
// MM78 differences
em_INT0H, em_INT1L, em_SAG, em_EOB3, em_TAB,
em_I1SK, em_IX, em_OX, em_LXA, em_XAX, em_IOA,
em_TLB, em_TMLB
};
static const char *const s_name[];
@ -63,4 +69,17 @@ private:
};
class mm78_disassembler : public pps41_common_disassembler
{
public:
mm78_disassembler() = default;
virtual ~mm78_disassembler() = default;
virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params) override;
private:
static const u8 mm78_opmap[0x100];
};
#endif // MAME_CPU_PPS41_PPS41D_H

View File

@ -261,8 +261,8 @@ void memoquiz_state::set_digits()
{
// digits switch is tied to MCU interrupt pins
u8 inp = m_inputs[4]->read();
m_maincpu->set_input_line(0, (inp & 1) ? ASSERT_LINE : CLEAR_LINE);
m_maincpu->set_input_line(1, (inp & 2) ? CLEAR_LINE : ASSERT_LINE);
m_maincpu->set_input_line(0, (inp & 1) ? CLEAR_LINE : ASSERT_LINE);
m_maincpu->set_input_line(1, (inp & 2) ? ASSERT_LINE : CLEAR_LINE);
}
void memoquiz_state::update_display()

View File

@ -502,6 +502,7 @@ static const dasm_table_entry dasm_table[] =
{ "mk1", le, 0, []() -> util::disasm_interface * { return new mk1_disassembler; } },
{ "mm5799", le, 0, []() -> util::disasm_interface * { return new mm5799_disassembler; } },
{ "mm76", le, 0, []() -> util::disasm_interface * { return new mm76_disassembler; } },
{ "mm78", le, 0, []() -> util::disasm_interface * { return new mm78_disassembler; } },
{ "mn10200", le, 0, []() -> util::disasm_interface * { return new mn10200_disassembler; } },
{ "mn1870", be, 0, []() -> util::disasm_interface * { return new mn1870_disassembler; } },
{ "mn1880", be, 0, []() -> util::disasm_interface * { return new mn1880_disassembler; } },