sm500 opcode handler placeholders

This commit is contained in:
hap 2016-04-08 12:17:54 +02:00
parent 8022a8285e
commit 75673f2b9f
10 changed files with 253 additions and 11 deletions

View File

@ -9,3 +9,20 @@
#include "sm500.h"
#include "debugger.h"
// MCU types
const device_type KB1013VK12 = &device_creator<kb1013vk12_device>;
// internal memory maps
static ADDRESS_MAP_START(program_2_7k, AS_PROGRAM, 8, sm510_base_device)
AM_RANGE(0x0000, 0x00ff) AM_ROM
ADDRESS_MAP_END
static ADDRESS_MAP_START(data_96_32x4, AS_DATA, 8, sm510_base_device)
AM_RANGE(0x00, 0x1f) AM_RAM
ADDRESS_MAP_END
// device definitions
kb1013vk12_device::kb1013vk12_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: sm500_device(mconfig, KB1013VK12, "KB1013VK1-2", tag, owner, clock, 2 /* stack levels */, 12 /* prg width */, ADDRESS_MAP_NAME(program_2_7k), 7 /* data width */, ADDRESS_MAP_NAME(data_96_32x4), "kb1013vk1-2", __FILE__)
{ }

View File

@ -47,14 +47,43 @@ class sm500_device : public sm510_base_device
{
public:
sm500_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
sm500_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
protected:
virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) override;
virtual void execute_one() override;
virtual void get_opcode_param() override;
// opcode handlers
void op_comcb();
void op_ssr();
void op_trs();
void op_pdtw();
void op_tw();
void op_dtw();
void op_ats();
void op_exksa();
void op_exkfa();
void op_rmf();
void op_smf();
void op_comcn();
void op_ta();
};
class kb1013vk12_device : public sm500_device
{
public:
kb1013vk12_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
};
extern const device_type SM500;
extern const device_type KB1013VK12;
#endif /* _SM500_H_ */

View File

@ -29,6 +29,10 @@ sm500_device::sm500_device(const machine_config &mconfig, const char *tag, devic
: sm510_base_device(mconfig, SM500, "SM500", tag, owner, clock, 2 /* stack levels */, 12 /* prg width */, ADDRESS_MAP_NAME(program_2_7k), 7 /* data width */, ADDRESS_MAP_NAME(data_96_32x4), "sm500", __FILE__)
{ }
sm500_device::sm500_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
: sm510_base_device(mconfig, type, name, tag, owner, clock, stack_levels, prgwidth, program, datawidth, data, shortname, source)
{ }
// disasm
offs_t sm500_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
@ -36,3 +40,111 @@ offs_t sm500_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *op
extern CPU_DISASSEMBLE(sm500);
return CPU_DISASSEMBLE_NAME(sm500)(this, buffer, pc, oprom, opram, options);
}
//-------------------------------------------------
// execute
//-------------------------------------------------
void sm500_device::get_opcode_param()
{
// LBL and prefix opcodes are 2 bytes
if (m_op == 0x5e || m_op == 0x5f)
{
m_icount--;
m_param = m_program->read_byte(m_pc);
increment_pc();
}
}
void sm500_device::execute_one()
{
switch (m_op & 0xf0)
{
case 0x20: op_lax(); break;
case 0x30:
if (m_op == 0x30) op_ats(); // !
else op_adx();
break;
case 0x40: op_lb(); break;
case 0x70: op_ssr(); break;
case 0x80: case 0x90: case 0xa0: case 0xb0:
op_t(); break; // aka tr
case 0xc0: case 0xd0: case 0xe0: case 0xf0:
op_trs(); break;
default:
switch (m_op & 0xfc)
{
case 0x04: op_rm(); break;
case 0x0c: op_sm(); break;
case 0x10: op_exc(); break;
case 0x14: op_exci(); break;
case 0x18: op_lda(); break;
case 0x1c: op_excd(); break;
case 0x54: op_tmi(); break; // aka tm
default:
switch (m_op)
{
case 0x00: op_skip(); break;
case 0x01: op_atr(); break;
case 0x02: op_exksa(); break;
case 0x03: op_atbp(); break;
case 0x08: op_add(); break;
case 0x09: op_add11(); break; // aka addc
case 0x0a: op_coma(); break;
case 0x0b: op_exbla(); break;
case 0x50: op_ta(); break;
case 0x51: op_tb(); break;
case 0x52: op_tc(); break;
case 0x53: op_tam(); break;
case 0x58: op_tis(); break; // aka tg: test gamma
case 0x59: op_ptw(); break;
case 0x5a: op_ta0(); break;
case 0x5b: op_tabl(); break;
case 0x5c: op_tw(); break;
case 0x5d: op_dtw(); break;
case 0x5f: op_lbl(); break;
case 0x60: op_comcn(); break;
case 0x61: op_pdtw(); break;
case 0x62: op_wr(); break;
case 0x63: op_ws(); break;
case 0x64: op_incb(); break;
case 0x65: op_idiv(); break;
case 0x66: op_rc(); break;
case 0x67: op_sc(); break;
case 0x68: op_rmf(); break;
case 0x69: op_smf(); break;
case 0x6a: op_kta(); break;
case 0x6b: op_exkfa(); break;
case 0x6c: op_decb(); break;
case 0x6d: op_comcb(); break;
case 0x6e: op_rtn0(); break; // aka rtn
case 0x6f: op_rtn1(); break; // aka rtns
// extended opcodes
case 0x5e:
m_op = m_op << 8 | m_param;
switch (m_param)
{
case 0x00: op_cend(); break;
case 0x04: op_dta(); break;
default: op_illegal(); break;
}
break; // 0x5e
default: op_illegal(); break;
}
break; // 0xff
}
break; // 0xfc
} // big switch
}

View File

@ -4,3 +4,80 @@
// SM500 opcode handlers
#include "sm500.h"
// instruction set
// RAM address instructions
// ROM address instructions
void sm500_device::op_comcb()
{
}
void sm500_device::op_ssr()
{
}
void sm500_device::op_trs()
{
}
// Arithmetic instructions
// Data transfer instructions
void sm500_device::op_pdtw()
{
}
void sm500_device::op_tw()
{
}
void sm500_device::op_dtw()
{
}
// I/O instructions
void sm500_device::op_ats()
{
}
void sm500_device::op_exksa()
{
}
void sm500_device::op_exkfa()
{
}
// Divider manipulation instructions
// Bit manipulation instructions
void sm500_device::op_rmf()
{
}
void sm500_device::op_smf()
{
}
void sm500_device::op_comcn()
{
}
// Test instructions
void sm500_device::op_ta()
{
}

View File

@ -12,6 +12,7 @@
Sharp SM500 MCU family:
- *SM500: x
- *SM4A: x
- *SM530: x
- *SM531: x
- *KB1013VK1-2: Soviet-era clone of SM500, minor differences
@ -125,6 +126,7 @@ void sm510_base_device::device_reset()
// ACL
m_skip = false;
m_halt = false;
m_sbm = false;
m_op = m_prev_op = 0;
do_branch(3, 7, 0);
m_prev_pc = m_pc;

View File

@ -162,6 +162,7 @@ protected:
UINT8 m_acc;
UINT8 m_bl;
UINT8 m_bm;
bool m_sbm;
UINT8 m_c;
bool m_skip;
UINT8 m_w;

View File

@ -133,4 +133,7 @@ void sm510_device::execute_one()
break; // 0xfc
} // big switch
// BM high bit is only valid for 1 step
m_sbm = (m_op == 0x02);
}

View File

@ -32,7 +32,7 @@ enum e_mnemonics
mADDC, mPDTW, mTW, mDTW,
mATS, mEXKSA, mEXKFA,
mRMF, mSMF, mCOMCN,
mTA, mTG
mTA, mTM2, mTG
// KB1013VK1-2 aliases
};
@ -55,7 +55,7 @@ static const char *const s_mnemonics[] =
"ADDC", "PDTW", "TW", "DTW",
"ATS", "EXKSA", "EXKFA",
"RMF", "SMF", "COMCN",
"TA", "TG"
"TA", "TM", "TG"
};
// number of bits per opcode parameter, 8 or larger means 2-byte opcode
@ -77,7 +77,7 @@ static const UINT8 s_bits[] =
0, 0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0
0, 2, 0
};
#define _OVER DASMFLAG_STEP_OVER
@ -101,7 +101,7 @@ static const UINT32 s_flags[] =
0, 0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0
0, 0, 0
};
// next program counter in sequence (relative)
@ -251,14 +251,13 @@ CPU_DISASSEMBLE(sm511)
static const UINT8 sm500_mnemonic[0x100] =
{
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
mSKIP, mATR, mEXKSA,mATBP, mRM, mRM, mRM, mRM, mADD, mADDC, mCOMA, mEXBLA,mSM, mSM, mSM, mSM, // 0
mEXC, mEXC, mEXC, mEXC, mEXCI, mEXCI, mEXCI, mEXCI, mLDA, mLDA, mLDA, mLDA, mEXCD, mEXCD, mEXCD, mEXCD, // 1
mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, mLAX, // 2
mATS, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, mADX, // 3
mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, mLB, // 4
mTA, mTB, mTC, mTAM, mTM, mTM, mTM, mTM, mTG, mPTW, mTA0, mTABL, mTW, mDTW, mEXT, mLBL, // 5
mTA, mTB, mTC, mTAM, mTM2, mTM2, mTM2, mTM2, mTG, mPTW, mTA0, mTABL, mTW, mDTW, mEXT, mLBL, // 5
mCOMCN,mPDTW, mWR, mWS, mINCB, mIDIV, mRC, mSC, mRMF, mSMF, mKTA, mEXKFA,mDECB, mCOMCB,mRTN, mRTNS, // 6
mSSR, mSSR, mSSR, mSSR, mSSR, mSSR, mSSR, mSSR, mSSR, mSSR, mSSR, mSSR, mSSR, mSSR, mSSR, mSSR, // 7

View File

@ -10,14 +10,14 @@
inline UINT8 sm510_base_device::ram_r()
{
int bmh = (m_prev_op == 0x02) ? (1 << (m_datawidth-1)) : 0; // from SBM
int bmh = (m_sbm) ? (1 << (m_datawidth-1)) : 0; // from SBM
UINT8 address = (bmh | m_bm << 4 | m_bl) & m_datamask;
return m_data->read_byte(address) & 0xf;
}
inline void sm510_base_device::ram_w(UINT8 data)
{
int bmh = (m_prev_op == 0x02) ? (1 << (m_datawidth-1)) : 0; // from SBM
int bmh = (m_sbm) ? (1 << (m_datawidth-1)) : 0; // from SBM
UINT8 address = (bmh | m_bm << 4 | m_bl) & m_datamask;
m_data->write_byte(address, data & 0xf);
}
@ -84,8 +84,7 @@ void sm510_base_device::op_lbl()
void sm510_base_device::op_sbm()
{
// SBM: set BM high bit for next opcode - handled in ram_r/w
assert(m_op == 0x02);
// SBM: set BM high bit for next opcode - handled in execute_one()
}
void sm510_base_device::op_exbla()
@ -459,7 +458,7 @@ void sm510_base_device::op_dr()
void sm510_base_device::op_dta()
{
// DTA: transfer divider low 4 bits to ACC
m_acc = BITSWAP16(m_div,0,0,0,0, 0,0,0,0, 0,0,0,0, 14,13,12,11) & 0xf;
m_acc = m_div >> 11 & 0xf;
}
void sm510_base_device::op_illegal()

View File

@ -159,4 +159,7 @@ void sm511_device::execute_one()
break; // 0xfc
} // big switch
// BM high bit is only valid for 1 step
m_sbm = (m_op == 0x02);
}