sm500: added lcd opcodes (nw)

This commit is contained in:
hap 2017-06-23 21:14:02 +02:00
parent a8bde85010
commit 1a82ca71ba
4 changed files with 95 additions and 19 deletions

View File

@ -76,12 +76,21 @@ public:
sm500_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
sm500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
sm500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_mask, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override;
virtual void execute_one() override;
virtual void get_opcode_param() override;
int m_o_mask; // number of 4-bit O pins minus 1
u8 m_ox[9]; // W' latch, max 9
u8 m_o[9]; // W latch(O outputs)
u8 m_cn; // Cn(digit select)
u8 m_mx; // m'(digit DP select)
void shift_w();
u8 get_digit();
// opcode handlers
virtual void op_lb() override;
virtual void op_incb() override;
@ -92,9 +101,13 @@ protected:
virtual void op_ssr();
virtual void op_trs();
virtual void op_pdtw();
virtual void op_atbp() override;
virtual void op_ptw() override;
virtual void op_tw();
virtual void op_pdtw();
virtual void op_dtw();
virtual void op_wr() override;
virtual void op_ws() override;
virtual void op_ats();
virtual void op_exksa();
@ -112,7 +125,7 @@ public:
sm5a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
sm5a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
sm5a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_mask, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data);
virtual offs_t disasm_disassemble(std::ostream &stream, offs_t pc, const u8 *oprom, const u8 *opram, u32 options) override;
virtual void execute_one() override;

View File

@ -30,12 +30,13 @@ ADDRESS_MAP_END
// device definitions
sm500_device::sm500_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: sm500_device(mconfig, SM500, tag, owner, clock, 1 /* stack levels */, 11 /* prg width */, ADDRESS_MAP_NAME(program_1_2k), 6 /* data width */, ADDRESS_MAP_NAME(data_4x10x4))
: sm500_device(mconfig, SM500, tag, owner, clock, 1 /* stack levels */, 6 /* o mask */, 11 /* prg width */, ADDRESS_MAP_NAME(program_1_2k), 6 /* data width */, ADDRESS_MAP_NAME(data_4x10x4))
{
}
sm500_device::sm500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data)
: sm510_base_device(mconfig, type, tag, owner, clock, stack_levels, prgwidth, program, datawidth, data)
sm500_device::sm500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_mask, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data)
: sm510_base_device(mconfig, type, tag, owner, clock, stack_levels, prgwidth, program, datawidth, data),
m_o_mask(o_mask)
{
}

View File

@ -7,6 +7,29 @@
#include "sm500.h"
// internal helpers
void sm500_device::shift_w()
{
// shifts internal W' latches
for (int i = 0; i < m_o_mask; i++)
m_ox[i] = m_ox[i + 1];
}
u8 sm500_device::get_digit()
{
// default digit segments PLA
static const u8 lut_digits[0x20] =
{
0xe, 0x0, 0xc, 0x8, 0x2, 0xa, 0xe, 0x2, 0xe, 0xa, 0x0, 0x0, 0x2, 0xa, 0x2, 0x2,
0xb, 0x9, 0x7, 0xf, 0xd, 0xe, 0xe, 0xb, 0xf, 0xf, 0x4, 0x0, 0xd, 0xe, 0x4, 0x0
};
return lut_digits[m_cn << 4 | m_acc] | (~m_cn & m_mx);
}
// instruction set
// RAM address instructions
@ -21,8 +44,8 @@ void sm500_device::op_lb()
void sm500_device::op_incb()
{
// INCB: increment BL, skip next on overflow, of 3rd bit!
m_bl = (m_bl + 1) & 0xf;
// INCB: same as SM510, but overflow on 3rd bit!
sm510_base_device::op_incb();
m_skip = (m_bl == 8);
}
@ -54,21 +77,55 @@ void sm500_device::op_trs()
}
// Arithmetic instructions
// Data transfer instructions
void sm500_device::op_pdtw()
void sm500_device::op_atbp()
{
// ATBP: same as SM510, and set Cn with ACC3
sm510_base_device::op_atbp();
m_cn = m_acc >> 3 & 1;
}
void sm500_device::op_ptw()
{
// PTW: partial transfer W' to W
m_o[m_o_mask] = m_ox[m_o_mask];
m_o[m_o_mask-1] = m_ox[m_o_mask-1];
}
void sm500_device::op_tw()
{
// TW: transfer W' to W
for (int i = 0; i <= m_o_mask; i++)
m_o[i] = m_ox[i];
}
void sm500_device::op_pdtw()
{
// PDTW: partial shift digit into W'
m_ox[m_o_mask-1] = m_ox[m_o_mask];
m_ox[m_o_mask] = get_digit();
}
void sm500_device::op_dtw()
{
// DTW: shift digit into W'
shift_w();
m_ox[m_o_mask] = get_digit();
}
void sm500_device::op_wr()
{
// WR: shift ACC into W', reset last bit
shift_w();
m_ox[m_o_mask] = m_acc & 7;
}
void sm500_device::op_ws()
{
// WR: shift ACC into W', set last bit
shift_w();
m_ox[m_o_mask] = m_acc | 8;
}
@ -94,14 +151,19 @@ void sm500_device::op_exkfa()
void sm500_device::op_rmf()
{
// RMF: reset m' flag, also clears ACC
m_mx = 0;
m_acc = 0;
}
void sm500_device::op_smf()
{
// SMF: set m' flag
m_mx = 1;
}
void sm500_device::op_comcn()
{
// COMCN: complement Cn flag
m_cn ^= 1;
}
// Test instructions

View File

@ -34,22 +34,22 @@ ADDRESS_MAP_END
// device definitions
sm5a_device::sm5a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: sm5a_device(mconfig, SM5A, tag, owner, clock, 1 /* stack levels */, 11 /* prg width */, ADDRESS_MAP_NAME(program_1_8k), 7 /* data width */, ADDRESS_MAP_NAME(data_5x13x4))
: sm5a_device(mconfig, SM5A, tag, owner, clock, 1 /* stack levels */, 8 /* o mask */, 11 /* prg width */, ADDRESS_MAP_NAME(program_1_8k), 7 /* data width */, ADDRESS_MAP_NAME(data_5x13x4))
{
}
sm5a_device::sm5a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data)
: sm500_device(mconfig, type, tag, owner, clock, stack_levels, prgwidth, program, datawidth, data)
sm5a_device::sm5a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_mask, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data)
: sm500_device(mconfig, type, tag, owner, clock, stack_levels, o_mask, prgwidth, program, datawidth, data)
{
}
sm5l_device::sm5l_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: sm5a_device(mconfig, SM5L, tag, owner, clock, 1, 11, ADDRESS_MAP_NAME(program_1_8k), 7, ADDRESS_MAP_NAME(data_5x13x4))
: sm5a_device(mconfig, SM5L, tag, owner, clock, 1, 8, 11, ADDRESS_MAP_NAME(program_1_8k), 7, ADDRESS_MAP_NAME(data_5x13x4))
{
}
kb1013vk12_device::kb1013vk12_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: sm5a_device(mconfig, KB1013VK12, tag, owner, clock, 1, 11, ADDRESS_MAP_NAME(program_1_8k), 7, ADDRESS_MAP_NAME(data_5x13x4))
: sm5a_device(mconfig, KB1013VK12, tag, owner, clock, 1, 8, 11, ADDRESS_MAP_NAME(program_1_8k), 7, ADDRESS_MAP_NAME(data_5x13x4))
{
}