trunk/src/emu/cpu/ucom4/ucom4.c
| r243425 | r243426 | |
| 7 | 7 | reference: 1981 NEC Microcomputers Catalog (later editions may have errors!) |
| 8 | 8 | also looked at asterick's JavaScript D553 emulator for verification, with permission |
| 9 | 9 | |
| 10 | TODO: |
| 11 | - what happens with uCOM-43 opcodes on an uCOM-44/45 MCU? |
| 12 | |
| 10 | 13 | */ |
| 11 | 14 | |
| 15 | enum |
| 16 | { |
| 17 | NEC_UCOM43 = 0, |
| 18 | NEC_UCOM44, |
| 19 | NEC_UCOM45 |
| 20 | }; |
| 21 | |
| 12 | 22 | #include "ucom4.h" |
| 13 | 23 | #include "debugger.h" |
| 14 | 24 | |
| 15 | 25 | #include "ucom4op.inc" |
| 16 | 26 | |
| 17 | 27 | |
| 18 | | // uCOM-43 products |
| 19 | | const device_type NEC_D553 = &device_creator<upd553_cpu_device>; // 42-pin PMOS, 35 pins for I/O, Open Drain output, 2000x8 ROM, 96x4 RAM |
| 20 | | const device_type NEC_D650 = &device_creator<upd650_cpu_device>; // 42-pin CMOS, 35 pins for I/O, push-pull output, 2000x8 ROM, 96x4 RAM |
| 28 | // uCOM-43 products: 2000x8 ROM, RAM size custom, supports full instruction set |
| 29 | const device_type NEC_D553 = &device_creator<upd553_cpu_device>; // 42-pin PMOS, 35 pins for I/O, Open Drain output, 96x4 RAM |
| 30 | const device_type NEC_D650 = &device_creator<upd650_cpu_device>; // 42-pin CMOS, 35 pins for I/O, push-pull output, 96x4 RAM |
| 21 | 31 | |
| 22 | | // uCOM-44 products |
| 23 | | const device_type NEC_D552 = &device_creator<upd552_cpu_device>; // 42-pin PMOS, 35 pins for I/O, Open Drain output, 1000x8 ROM, 64x4 RAM |
| 32 | // uCOM-44 products: 1000x8 ROM, 64x4 RAM, does not support external interrupt |
| 33 | const device_type NEC_D552 = &device_creator<upd552_cpu_device>; // 42-pin PMOS, 35 pins for I/O, Open Drain output |
| 24 | 34 | |
| 35 | // uCOM-45 products: ROM size custom, 32x4 RAM |
| 36 | //.. |
| 37 | |
| 38 | |
| 25 | 39 | // internal memory maps |
| 26 | 40 | static ADDRESS_MAP_START(program_1k, AS_PROGRAM, 8, ucom4_cpu_device) |
| 27 | 41 | AM_RANGE(0x0000, 0x03ff) AM_ROM |
| r243425 | r243426 | |
| 44 | 58 | |
| 45 | 59 | // device definitions |
| 46 | 60 | upd553_cpu_device::upd553_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 47 | | : ucom4_cpu_device(mconfig, NEC_D553, "uPD553", tag, owner, clock, 3, 11, ADDRESS_MAP_NAME(program_2k), 7, ADDRESS_MAP_NAME(data_96x4), "upd553", __FILE__) |
| 61 | : ucom4_cpu_device(mconfig, NEC_D553, "uPD553", tag, owner, clock, NEC_UCOM43, 3, 11, ADDRESS_MAP_NAME(program_2k), 7, ADDRESS_MAP_NAME(data_96x4), "upd553", __FILE__) |
| 48 | 62 | { } |
| 49 | 63 | |
| 50 | 64 | upd650_cpu_device::upd650_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 51 | | : ucom4_cpu_device(mconfig, NEC_D650, "uPD650", tag, owner, clock, 3, 11, ADDRESS_MAP_NAME(program_2k), 7, ADDRESS_MAP_NAME(data_96x4), "upd650", __FILE__) |
| 65 | : ucom4_cpu_device(mconfig, NEC_D650, "uPD650", tag, owner, clock, NEC_UCOM43, 3, 11, ADDRESS_MAP_NAME(program_2k), 7, ADDRESS_MAP_NAME(data_96x4), "upd650", __FILE__) |
| 52 | 66 | { } |
| 53 | 67 | |
| 54 | 68 | upd552_cpu_device::upd552_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 55 | | : ucom4_cpu_device(mconfig, NEC_D552, "uPD552", tag, owner, clock, 1, 10, ADDRESS_MAP_NAME(program_1k), 6, ADDRESS_MAP_NAME(data_64x4), "upd552", __FILE__) |
| 69 | : ucom4_cpu_device(mconfig, NEC_D552, "uPD552", tag, owner, clock, NEC_UCOM44, 1, 10, ADDRESS_MAP_NAME(program_1k), 6, ADDRESS_MAP_NAME(data_64x4), "upd552", __FILE__) |
| 56 | 70 | { } |
| 57 | 71 | |
| 58 | 72 | |
| r243425 | r243426 | |
| 64 | 78 | // obviously not from a single flags register |
| 65 | 79 | case STATE_GENFLAGS: |
| 66 | 80 | string.printf("%c%c%c%c%c", |
| 67 | | m_inte_f ? 'E':'e', |
| 68 | | m_int_f ? 'I':'i', |
| 69 | | m_timer_f ? 'T':'t', |
| 70 | | m_carry_s ? 'S':'s', |
| 71 | | m_carry_f ? 'C':'c' |
| 81 | m_inte_f ? 'E':'e', |
| 82 | m_int_f ? 'I':'i', |
| 83 | m_timer_f ? 'T':'t', |
| 84 | m_carry_s_f ? 'S':'s', |
| 85 | m_carry_f ? 'C':'c' |
| 72 | 86 | ); |
| 73 | 87 | break; |
| 74 | 88 | |
| r243425 | r243426 | |
| 118 | 132 | memset(m_stack, 0, sizeof(m_stack)); |
| 119 | 133 | m_op = 0; |
| 120 | 134 | m_prev_op = 0; |
| 135 | m_arg = 0; |
| 136 | m_skip = false; |
| 121 | 137 | m_pc = 0; |
| 122 | 138 | m_acc = 0; |
| 123 | 139 | m_dpl = 0; |
| 124 | 140 | m_dph = 0; |
| 125 | 141 | m_carry_f = 0; |
| 126 | | m_carry_s = 0; |
| 142 | m_carry_s_f = 0; |
| 127 | 143 | m_timer_f = 0; |
| 128 | 144 | m_int_f = 0; |
| 129 | 145 | m_inte_f = 0; |
| r243425 | r243426 | |
| 132 | 148 | save_item(NAME(m_stack)); |
| 133 | 149 | save_item(NAME(m_op)); |
| 134 | 150 | save_item(NAME(m_prev_op)); |
| 151 | save_item(NAME(m_arg)); |
| 152 | save_item(NAME(m_skip)); |
| 135 | 153 | save_item(NAME(m_pc)); |
| 136 | 154 | save_item(NAME(m_acc)); |
| 137 | 155 | save_item(NAME(m_dpl)); |
| 138 | 156 | save_item(NAME(m_dph)); |
| 139 | 157 | save_item(NAME(m_carry_f)); |
| 140 | | save_item(NAME(m_carry_s)); |
| 158 | save_item(NAME(m_carry_s_f)); |
| 141 | 159 | save_item(NAME(m_timer_f)); |
| 142 | 160 | save_item(NAME(m_int_f)); |
| 143 | 161 | save_item(NAME(m_inte_f)); |
| r243425 | r243426 | |
| 165 | 183 | m_inte_f = 1; |
| 166 | 184 | m_pc = 0; |
| 167 | 185 | m_op = 0; |
| 186 | m_skip = false; |
| 168 | 187 | } |
| 169 | 188 | |
| 170 | 189 | |
| r243425 | r243426 | |
| 173 | 192 | // execute |
| 174 | 193 | //------------------------------------------------- |
| 175 | 194 | |
| 195 | void ucom4_cpu_device::fetch_arg() |
| 196 | { |
| 197 | // 2-byte opcodes: STM/LDI/CLI/CI, JMP/CAL, OCD |
| 198 | if ((m_op & 0xfc) == 0x14 || (m_op & 0xf0) == 0xa0 || m_op == 0x1e) |
| 199 | { |
| 200 | m_icount--; |
| 201 | m_arg = m_program->read_byte(m_pc); |
| 202 | m_pc = (m_pc + 1) & m_prgmask; |
| 203 | } |
| 204 | } |
| 205 | |
| 176 | 206 | void ucom4_cpu_device::execute_run() |
| 177 | 207 | { |
| 178 | 208 | while (m_icount > 0) |
| 179 | 209 | { |
| 180 | 210 | m_icount--; |
| 181 | | |
| 211 | |
| 182 | 212 | // remember previous opcode |
| 183 | 213 | m_prev_op = m_op; |
| 184 | 214 | |
| 185 | 215 | debugger_instruction_hook(this, m_pc); |
| 186 | 216 | m_op = m_program->read_byte(m_pc); |
| 187 | 217 | m_pc = (m_pc + 1) & m_prgmask; |
| 218 | fetch_arg(); |
| 219 | |
| 220 | if (m_skip) |
| 221 | { |
| 222 | m_skip = false; |
| 223 | continue; |
| 224 | } |
| 225 | |
| 226 | switch (m_op & 0xf0) |
| 227 | { |
| 228 | case 0x80: op_ldz(); break; |
| 229 | case 0x90: op_li(); break; |
| 230 | case 0xa0: op_jmpcal(); break; |
| 231 | case 0xb0: op_czp(); break; |
| 232 | |
| 233 | case 0xc0: case 0xd0: case 0xe0: case 0xf0: op_jcp(); break; |
| 234 | |
| 235 | default: |
| 236 | switch (m_op) |
| 237 | { |
| 238 | case 0x00: op_nop(); break; |
| 239 | case 0x01: op_di(); break; |
| 240 | case 0x02: op_s(); break; |
| 241 | case 0x03: op_tit(); break; |
| 242 | case 0x04: op_tc(); break; |
| 243 | case 0x05: op_ttm(); break; |
| 244 | case 0x06: op_daa(); break; |
| 245 | case 0x07: op_tal(); break; |
| 246 | case 0x08: op_ad(); break; |
| 247 | case 0x09: op_ads(); break; |
| 248 | case 0x0a: op_das(); break; |
| 249 | case 0x0b: op_clc(); break; |
| 250 | case 0x0c: op_cm(); break; |
| 251 | case 0x0d: op_inc(); break; |
| 252 | case 0x0e: op_op(); break; |
| 253 | case 0x0f: op_dec(); break; |
| 254 | case 0x10: op_cma(); break; |
| 255 | case 0x11: op_cia(); break; |
| 256 | case 0x12: op_tla(); break; |
| 257 | case 0x13: op_ded(); break; |
| 258 | case 0x14: op_stm(); break; |
| 259 | case 0x15: op_ldi(); break; |
| 260 | case 0x16: op_cli(); break; |
| 261 | case 0x17: op_ci(); break; |
| 262 | case 0x18: op_exl(); break; |
| 263 | case 0x19: op_adc(); break; |
| 264 | case 0x1a: op_xc(); break; |
| 265 | case 0x1b: op_stc(); break; |
| 266 | case 0x1c: op_illegal(); break; |
| 267 | case 0x1d: op_inm(); break; |
| 268 | case 0x1e: op_ocd(); break; |
| 269 | case 0x1f: op_dem(); break; |
| 270 | |
| 271 | case 0x30: op_rar(); break; |
| 272 | case 0x31: op_ei(); break; |
| 273 | case 0x32: op_ip(); break; |
| 274 | case 0x33: op_ind(); break; |
| 275 | |
| 276 | case 0x40: op_ia(); break; |
| 277 | case 0x41: op_jpa(); break; |
| 278 | case 0x42: op_taz(); break; |
| 279 | case 0x43: op_taw(); break; |
| 280 | case 0x44: op_oe(); break; |
| 281 | case 0x45: op_illegal(); break; |
| 282 | case 0x46: op_tly(); break; |
| 283 | case 0x47: op_thx(); break; |
| 284 | case 0x48: op_rt(); break; |
| 285 | case 0x49: op_rts(); break; |
| 286 | case 0x4a: op_xaz(); break; |
| 287 | case 0x4b: op_xaw(); break; |
| 288 | case 0x4c: op_xls(); break; |
| 289 | case 0x4d: op_xhr(); break; |
| 290 | case 0x4e: op_xly(); break; |
| 291 | case 0x4f: op_xhx(); break; |
| 292 | |
| 293 | default: |
| 294 | switch (m_op & 0xfc) |
| 295 | { |
| 296 | case 0x20: op_fbf(); break; |
| 297 | case 0x24: op_tab(); break; |
| 298 | case 0x28: op_xm(); break; |
| 299 | case 0x2c: op_xmd(); break; |
| 300 | |
| 301 | case 0x34: op_cmb(); break; |
| 302 | case 0x38: op_lm(); break; |
| 303 | case 0x3c: op_xmi(); break; |
| 304 | |
| 305 | case 0x50: op_tpb(); break; |
| 306 | case 0x54: op_tpa(); break; |
| 307 | case 0x58: op_tmb(); break; |
| 308 | case 0x5c: op_fbt(); break; |
| 309 | case 0x60: op_rpb(); break; |
| 310 | case 0x64: op_reb(); break; |
| 311 | case 0x68: op_rmb(); break; |
| 312 | case 0x6c: op_rfb(); break; |
| 313 | case 0x70: op_spb(); break; |
| 314 | case 0x74: op_seb(); break; |
| 315 | case 0x78: op_smb(); break; |
| 316 | case 0x7c: op_sfb(); break; |
| 317 | } |
| 318 | break; // 0xfc |
| 319 | |
| 320 | } |
| 321 | break; // 0xff |
| 322 | |
| 323 | } // big switch |
| 188 | 324 | } |
| 189 | 325 | } |
trunk/src/emu/cpu/ucom4/ucom4.h
| r243425 | r243426 | |
| 50 | 50 | { |
| 51 | 51 | public: |
| 52 | 52 | // construction/destruction |
| 53 | | ucom4_cpu_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) |
| 53 | ucom4_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, int family, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source) |
| 54 | 54 | : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source) |
| 55 | 55 | , m_program_config("program", ENDIANNESS_BIG, 8, prgwidth, 0, program) |
| 56 | 56 | , m_data_config("data", ENDIANNESS_BIG, 8, datawidth, 0, data) |
| 57 | 57 | , m_prgwidth(prgwidth) |
| 58 | 58 | , m_datawidth(datawidth) |
| 59 | , m_family(family) |
| 59 | 60 | , m_stack_levels(stack_levels) |
| 60 | 61 | , m_read_a(*this) |
| 61 | 62 | , m_read_b(*this) |
| r243425 | r243426 | |
| 94 | 95 | virtual UINT32 execute_max_cycles() const { return 2; } |
| 95 | 96 | virtual UINT32 execute_input_lines() const { return 1; } |
| 96 | 97 | virtual void execute_run(); |
| 98 | |
| 99 | void fetch_arg(); |
| 97 | 100 | |
| 98 | 101 | // device_memory_interface overrides |
| 99 | 102 | virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return(spacenum == AS_PROGRAM) ? &m_program_config :((spacenum == AS_DATA) ? &m_data_config : NULL); } |
| r243425 | r243426 | |
| 102 | 105 | virtual UINT32 disasm_min_opcode_bytes() const { return 1; } |
| 103 | 106 | virtual UINT32 disasm_max_opcode_bytes() const { return 2; } |
| 104 | 107 | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); |
| 108 | |
| 105 | 109 | void state_string_export(const device_state_entry &entry, astring &string); |
| 106 | 110 | |
| 107 | 111 | address_space_config m_program_config; |
| r243425 | r243426 | |
| 113 | 117 | int m_datawidth; |
| 114 | 118 | int m_prgmask; |
| 115 | 119 | int m_datamask; |
| 120 | int m_family; // MCU family (43/44/45) |
| 116 | 121 | int m_stack_levels; // number of callstack levels |
| 117 | 122 | UINT16 m_stack[3]; // max 3 |
| 118 | | |
| 119 | 123 | UINT8 m_op; |
| 120 | | UINT8 m_prev_op; |
| 124 | UINT8 m_prev_op; // previous opcode |
| 125 | UINT8 m_arg; // opcode argument for 2-byte opcodes |
| 126 | bool m_skip; // skip next opcode |
| 121 | 127 | int m_icount; |
| 122 | 128 | |
| 123 | 129 | UINT16 m_pc; // program counter |
| r243425 | r243426 | |
| 125 | 131 | UINT8 m_dpl; // 4-bit data pointer low (RAM x) |
| 126 | 132 | UINT8 m_dph; // 1/2/3-bit data pointer high (RAM y) |
| 127 | 133 | UINT8 m_carry_f; // carry flag |
| 128 | | UINT8 m_carry_s; // carry save |
| 134 | UINT8 m_carry_s_f; // carry save flag |
| 129 | 135 | UINT8 m_timer_f; // timer out flag |
| 130 | 136 | UINT8 m_int_f; // interrupt flag |
| 131 | 137 | UINT8 m_inte_f; // interrupt enable flag |
| r243425 | r243426 | |
| 143 | 149 | devcb_write8 m_write_g; |
| 144 | 150 | devcb_write8 m_write_h; |
| 145 | 151 | devcb_write8 m_write_i; |
| 152 | |
| 153 | // opcode handlers |
| 154 | void op_illegal(); |
| 155 | bool check_op_43(); |
| 156 | |
| 157 | void op_li(); |
| 158 | void op_lm(); |
| 159 | void op_ldi(); |
| 160 | void op_ldz(); |
| 161 | void op_s(); |
| 162 | void op_tal(); |
| 163 | void op_tla(); |
| 164 | |
| 165 | void op_xm(); |
| 166 | void op_xmi(); |
| 167 | void op_xmd(); |
| 168 | void op_ad(); |
| 169 | void op_adc(); |
| 170 | void op_ads(); |
| 171 | void op_daa(); |
| 172 | void op_das(); |
| 173 | |
| 174 | void op_exl(); |
| 175 | void op_cma(); |
| 176 | void op_cia(); |
| 177 | void op_clc(); |
| 178 | void op_stc(); |
| 179 | void op_tc(); |
| 180 | void op_inc(); |
| 181 | void op_dec(); |
| 182 | void op_ind(); |
| 183 | void op_ded(); |
| 184 | |
| 185 | void op_rmb(); |
| 186 | void op_smb(); |
| 187 | void op_reb(); |
| 188 | void op_seb(); |
| 189 | void op_rpb(); |
| 190 | void op_spb(); |
| 191 | void op_jmpcal(); |
| 192 | void op_jcp(); |
| 193 | void op_jpa(); |
| 194 | void op_czp(); |
| 195 | void op_rt(); |
| 196 | void op_rts(); |
| 197 | |
| 198 | void op_ci(); |
| 199 | void op_cm(); |
| 200 | void op_cmb(); |
| 201 | void op_tab(); |
| 202 | void op_cli(); |
| 203 | void op_tmb(); |
| 204 | void op_tpa(); |
| 205 | void op_tpb(); |
| 206 | |
| 207 | void op_tit(); |
| 208 | void op_ia(); |
| 209 | void op_ip(); |
| 210 | void op_oe(); |
| 211 | void op_op(); |
| 212 | void op_ocd(); |
| 213 | void op_nop(); |
| 214 | |
| 215 | void op_taw(); |
| 216 | void op_taz(); |
| 217 | void op_thx(); |
| 218 | void op_tly(); |
| 219 | void op_xaw(); |
| 220 | void op_xaz(); |
| 221 | void op_xhr(); |
| 222 | void op_xhx(); |
| 223 | void op_xls(); |
| 224 | void op_xly(); |
| 225 | void op_xc(); |
| 226 | |
| 227 | void op_sfb(); |
| 228 | void op_rfb(); |
| 229 | void op_fbt(); |
| 230 | void op_fbf(); |
| 231 | void op_rar(); |
| 232 | void op_inm(); |
| 233 | void op_dem(); |
| 234 | void op_stm(); |
| 235 | void op_ttm(); |
| 236 | void op_ei(); |
| 237 | void op_di(); |
| 146 | 238 | }; |
| 147 | 239 | |
| 148 | 240 | |
trunk/src/emu/cpu/ucom4/ucom4op.inc
| r243425 | r243426 | |
| 1 | | // uCOM4 opcode handlers |
| 1 | // uCOM-4 opcode handlers |
| 2 | |
| 3 | // internal helpers |
| 4 | |
| 5 | void ucom4_cpu_device::op_illegal() |
| 6 | { |
| 7 | logerror("%s unknown opcode $%02X at $%03X\n", tag(), m_op, m_pc); |
| 8 | } |
| 9 | |
| 10 | |
| 11 | |
| 12 | // basic instruction set |
| 13 | |
| 14 | // Load |
| 15 | |
| 16 | void ucom4_cpu_device::op_li() |
| 17 | { |
| 18 | // LI X: Load ACC with X |
| 19 | // note: only execute the first one in a sequence of LAI |
| 20 | if ((m_prev_op & 0xf0) != (m_op & 0xf0)) |
| 21 | m_acc = m_op & 0x0f; |
| 22 | } |
| 23 | |
| 24 | void ucom4_cpu_device::op_lm() |
| 25 | { |
| 26 | // LM X: Load ACC with RAM, xor DPh with X |
| 27 | op_illegal(); |
| 28 | } |
| 29 | |
| 30 | void ucom4_cpu_device::op_ldi() |
| 31 | { |
| 32 | // LDI X: Load DP with X |
| 33 | op_illegal(); |
| 34 | } |
| 35 | |
| 36 | void ucom4_cpu_device::op_ldz() |
| 37 | { |
| 38 | // LDZ X: Load DPh with 0, Load DPl with X |
| 39 | op_illegal(); |
| 40 | } |
| 41 | |
| 42 | |
| 43 | // Store |
| 44 | |
| 45 | void ucom4_cpu_device::op_s() |
| 46 | { |
| 47 | // S: Store ACC into RAM |
| 48 | op_illegal(); |
| 49 | } |
| 50 | |
| 51 | |
| 52 | // Transfer |
| 53 | |
| 54 | void ucom4_cpu_device::op_tal() |
| 55 | { |
| 56 | // TAL: Transfer ACC to DPl |
| 57 | op_illegal(); |
| 58 | } |
| 59 | |
| 60 | void ucom4_cpu_device::op_tla() |
| 61 | { |
| 62 | // TLA: Transfer |
| 63 | op_illegal(); |
| 64 | } |
| 65 | |
| 66 | |
| 67 | // Exchange |
| 68 | |
| 69 | void ucom4_cpu_device::op_xm() |
| 70 | { |
| 71 | // XM X: Exchange ACC with RAM, xor DPh with X |
| 72 | op_illegal(); |
| 73 | } |
| 74 | |
| 75 | void ucom4_cpu_device::op_xmi() |
| 76 | { |
| 77 | // XMI X: Exchange ACC with RAM, xor DPh with X, Increment DPl, skip next on carry |
| 78 | op_illegal(); |
| 79 | } |
| 80 | |
| 81 | void ucom4_cpu_device::op_xmd() |
| 82 | { |
| 83 | // XMD X: Exchange ACC with RAM, xor DPh with X, Decrement DPl, skip next on carry |
| 84 | op_illegal(); |
| 85 | } |
| 86 | |
| 87 | |
| 88 | // Arithmetic |
| 89 | |
| 90 | void ucom4_cpu_device::op_ad() |
| 91 | { |
| 92 | // AD: Add RAM to Acc, skip next on carry |
| 93 | op_illegal(); |
| 94 | } |
| 95 | |
| 96 | void ucom4_cpu_device::op_adc() |
| 97 | { |
| 98 | // ADC: Add RAM and carry to Acc, store Carry F/F |
| 99 | op_illegal(); |
| 100 | } |
| 101 | |
| 102 | void ucom4_cpu_device::op_ads() |
| 103 | { |
| 104 | // ADS: Add RAM and carry to Acc, store Carry F/F, skip next on carry |
| 105 | op_illegal(); |
| 106 | } |
| 107 | |
| 108 | void ucom4_cpu_device::op_daa() |
| 109 | { |
| 110 | // DAA: Add 6 to ACC to adjust decimal for BCD Addition |
| 111 | op_illegal(); |
| 112 | } |
| 113 | |
| 114 | void ucom4_cpu_device::op_das() |
| 115 | { |
| 116 | // DAS: Add 10 to ACC to adjust decimal for BCD Subtraction |
| 117 | op_illegal(); |
| 118 | } |
| 119 | |
| 120 | |
| 121 | // Logical |
| 122 | |
| 123 | void ucom4_cpu_device::op_exl() |
| 124 | { |
| 125 | // EXL: Xor ACC with RAM |
| 126 | op_illegal(); |
| 127 | } |
| 128 | |
| 129 | |
| 130 | // Accumulator |
| 131 | |
| 132 | void ucom4_cpu_device::op_cma() |
| 133 | { |
| 134 | // CMA: Complement ACC |
| 135 | op_illegal(); |
| 136 | } |
| 137 | |
| 138 | void ucom4_cpu_device::op_cia() |
| 139 | { |
| 140 | // CIA: Complement ACC, Increment ACC |
| 141 | op_illegal(); |
| 142 | } |
| 143 | |
| 144 | |
| 145 | // Carry Flag |
| 146 | |
| 147 | void ucom4_cpu_device::op_clc() |
| 148 | { |
| 149 | // CLC: Reset Carry F/F |
| 150 | op_illegal(); |
| 151 | } |
| 152 | |
| 153 | void ucom4_cpu_device::op_stc() |
| 154 | { |
| 155 | // STC: Set Carry F/F |
| 156 | op_illegal(); |
| 157 | } |
| 158 | |
| 159 | void ucom4_cpu_device::op_tc() |
| 160 | { |
| 161 | // TC: skip next on Carry F/F |
| 162 | op_illegal(); |
| 163 | } |
| 164 | |
| 165 | |
| 166 | // Increment and Decrement |
| 167 | |
| 168 | void ucom4_cpu_device::op_inc() |
| 169 | { |
| 170 | // INC: Increment ACC, skip next on carry |
| 171 | op_illegal(); |
| 172 | } |
| 173 | |
| 174 | void ucom4_cpu_device::op_dec() |
| 175 | { |
| 176 | // DEC: Decrement ACC, skip next on carry |
| 177 | op_illegal(); |
| 178 | } |
| 179 | |
| 180 | void ucom4_cpu_device::op_ind() |
| 181 | { |
| 182 | // IND: Increment DPl, skip next on carry |
| 183 | op_illegal(); |
| 184 | } |
| 185 | |
| 186 | void ucom4_cpu_device::op_ded() |
| 187 | { |
| 188 | // DED: Decrement DPl, skip next on carry |
| 189 | op_illegal(); |
| 190 | } |
| 191 | |
| 192 | |
| 193 | // Bit Manipulation |
| 194 | |
| 195 | void ucom4_cpu_device::op_rmb() |
| 196 | { |
| 197 | // RMB B: Reset a single bit of RAM |
| 198 | op_illegal(); |
| 199 | } |
| 200 | |
| 201 | void ucom4_cpu_device::op_smb() |
| 202 | { |
| 203 | // SMB B: Set a single bit of RAM |
| 204 | op_illegal(); |
| 205 | } |
| 206 | |
| 207 | void ucom4_cpu_device::op_reb() |
| 208 | { |
| 209 | // REB B: Reset a single bit of output port E |
| 210 | op_illegal(); |
| 211 | } |
| 212 | |
| 213 | void ucom4_cpu_device::op_seb() |
| 214 | { |
| 215 | // SEB B: Set a single bit of output port E |
| 216 | op_illegal(); |
| 217 | } |
| 218 | |
| 219 | void ucom4_cpu_device::op_rpb() |
| 220 | { |
| 221 | // RPB B: Reset a single bit of output port (DPl) |
| 222 | op_illegal(); |
| 223 | } |
| 224 | |
| 225 | void ucom4_cpu_device::op_spb() |
| 226 | { |
| 227 | // SPB B: Set a single bit of output port (DPl) |
| 228 | op_illegal(); |
| 229 | } |
| 230 | |
| 231 | |
| 232 | // Jump, Call and Return |
| 233 | |
| 234 | void ucom4_cpu_device::op_jmpcal() |
| 235 | { |
| 236 | // JMP A: Jump to Address / CAL A: Call Address |
| 237 | op_illegal(); |
| 238 | } |
| 239 | |
| 240 | void ucom4_cpu_device::op_jcp() |
| 241 | { |
| 242 | // JCP A: Jump to Address in current page |
| 243 | op_illegal(); |
| 244 | } |
| 245 | |
| 246 | void ucom4_cpu_device::op_jpa() |
| 247 | { |
| 248 | // JPA: Jump to (ACC) |
| 249 | op_illegal(); |
| 250 | } |
| 251 | |
| 252 | void ucom4_cpu_device::op_czp() |
| 253 | { |
| 254 | // CZP A: Call (Address) |
| 255 | op_illegal(); |
| 256 | } |
| 257 | |
| 258 | void ucom4_cpu_device::op_rt() |
| 259 | { |
| 260 | // RT: Return from subroutine |
| 261 | op_illegal(); |
| 262 | } |
| 263 | |
| 264 | void ucom4_cpu_device::op_rts() |
| 265 | { |
| 266 | // RTS: Return from subroutine, skip next |
| 267 | op_rt(); |
| 268 | m_skip = true; |
| 269 | } |
| 270 | |
| 271 | |
| 272 | // Skip |
| 273 | |
| 274 | void ucom4_cpu_device::op_ci() |
| 275 | { |
| 276 | // CI X: skip next on ACC equals X |
| 277 | op_illegal(); |
| 278 | } |
| 279 | |
| 280 | void ucom4_cpu_device::op_cm() |
| 281 | { |
| 282 | // CM: skip next on ACC equals RAM |
| 283 | op_illegal(); |
| 284 | } |
| 285 | |
| 286 | void ucom4_cpu_device::op_cmb() |
| 287 | { |
| 288 | // CMB B: skip next on bit(ACC) equals bit(RAM) |
| 289 | op_illegal(); |
| 290 | } |
| 291 | |
| 292 | void ucom4_cpu_device::op_tab() |
| 293 | { |
| 294 | // TAB B: skip next on bit(ACC) |
| 295 | op_illegal(); |
| 296 | } |
| 297 | |
| 298 | void ucom4_cpu_device::op_cli() |
| 299 | { |
| 300 | // CLI X: skip next on DPl equals X |
| 301 | op_illegal(); |
| 302 | } |
| 303 | |
| 304 | void ucom4_cpu_device::op_tmb() |
| 305 | { |
| 306 | // TMB B: skip next on bit(RAM) |
| 307 | op_illegal(); |
| 308 | } |
| 309 | |
| 310 | void ucom4_cpu_device::op_tpa() |
| 311 | { |
| 312 | // TPA B: skip next on bit(input port A) |
| 313 | op_illegal(); |
| 314 | } |
| 315 | |
| 316 | void ucom4_cpu_device::op_tpb() |
| 317 | { |
| 318 | // TPB B: skip next on bit(input port (DPl)) |
| 319 | op_illegal(); |
| 320 | } |
| 321 | |
| 322 | |
| 323 | // Interrupt |
| 324 | |
| 325 | void ucom4_cpu_device::op_tit() |
| 326 | { |
| 327 | // TIT: skip next on Interrupt F/F, reset Interrupt F/F |
| 328 | op_illegal(); |
| 329 | } |
| 330 | |
| 331 | |
| 332 | // Parallel I/O |
| 333 | |
| 334 | void ucom4_cpu_device::op_ia() |
| 335 | { |
| 336 | // IA: x |
| 337 | op_illegal(); |
| 338 | } |
| 339 | |
| 340 | void ucom4_cpu_device::op_ip() |
| 341 | { |
| 342 | // IP: x |
| 343 | op_illegal(); |
| 344 | } |
| 345 | |
| 346 | void ucom4_cpu_device::op_oe() |
| 347 | { |
| 348 | // OE: x |
| 349 | op_illegal(); |
| 350 | } |
| 351 | |
| 352 | void ucom4_cpu_device::op_op() |
| 353 | { |
| 354 | // OP: x |
| 355 | op_illegal(); |
| 356 | } |
| 357 | |
| 358 | void ucom4_cpu_device::op_ocd() |
| 359 | { |
| 360 | // OCD X: x |
| 361 | op_illegal(); |
| 362 | } |
| 363 | |
| 364 | |
| 365 | // CPU Control |
| 366 | |
| 367 | void ucom4_cpu_device::op_nop() |
| 368 | { |
| 369 | // NOP: No Operation |
| 370 | } |
| 371 | |
| 372 | |
| 373 | |
| 374 | // uCOM-43 extended instructions |
| 375 | |
| 376 | inline bool ucom4_cpu_device::check_op_43() |
| 377 | { |
| 378 | // these opcodes are officially only supported on uCOM-43 |
| 379 | if (m_family != NEC_UCOM43) |
| 380 | logerror("%s using uCOM-43 opcode $%02X at $%03X\n", tag(), m_op, m_pc); |
| 381 | |
| 382 | return (m_family == NEC_UCOM43); |
| 383 | } |
| 384 | |
| 385 | // Transfer |
| 386 | |
| 387 | void ucom4_cpu_device::op_taw() |
| 388 | { |
| 389 | if (!check_op_43()) return; |
| 390 | |
| 391 | // TAW: Transfer ACC to W |
| 392 | op_illegal(); |
| 393 | } |
| 394 | |
| 395 | void ucom4_cpu_device::op_taz() |
| 396 | { |
| 397 | if (!check_op_43()) return; |
| 398 | |
| 399 | // TAZ: Transfer ACC to Z |
| 400 | op_illegal(); |
| 401 | } |
| 402 | |
| 403 | void ucom4_cpu_device::op_thx() |
| 404 | { |
| 405 | if (!check_op_43()) return; |
| 406 | |
| 407 | // THX: Transfer DPh to X |
| 408 | op_illegal(); |
| 409 | } |
| 410 | |
| 411 | void ucom4_cpu_device::op_tly() |
| 412 | { |
| 413 | if (!check_op_43()) return; |
| 414 | |
| 415 | // TLY: Transfer DPl to Y |
| 416 | op_illegal(); |
| 417 | } |
| 418 | |
| 419 | |
| 420 | // Exchange |
| 421 | |
| 422 | void ucom4_cpu_device::op_xaw() |
| 423 | { |
| 424 | if (!check_op_43()) return; |
| 425 | |
| 426 | // XAW: Exchange ACC with W |
| 427 | op_illegal(); |
| 428 | } |
| 429 | |
| 430 | void ucom4_cpu_device::op_xaz() |
| 431 | { |
| 432 | if (!check_op_43()) return; |
| 433 | |
| 434 | // XAZ: Exchange ACC with Z |
| 435 | op_illegal(); |
| 436 | } |
| 437 | |
| 438 | void ucom4_cpu_device::op_xhr() |
| 439 | { |
| 440 | if (!check_op_43()) return; |
| 441 | |
| 442 | // XHR: Exchange DPh with R |
| 443 | op_illegal(); |
| 444 | } |
| 445 | |
| 446 | void ucom4_cpu_device::op_xhx() |
| 447 | { |
| 448 | if (!check_op_43()) return; |
| 449 | |
| 450 | // XHX: Exchange DPh with X |
| 451 | op_illegal(); |
| 452 | } |
| 453 | |
| 454 | void ucom4_cpu_device::op_xls() |
| 455 | { |
| 456 | if (!check_op_43()) return; |
| 457 | |
| 458 | // XLS: Exchange DPl with S |
| 459 | op_illegal(); |
| 460 | } |
| 461 | |
| 462 | void ucom4_cpu_device::op_xly() |
| 463 | { |
| 464 | if (!check_op_43()) return; |
| 465 | |
| 466 | // XLY: Exchange DPl with Y |
| 467 | op_illegal(); |
| 468 | } |
| 469 | |
| 470 | void ucom4_cpu_device::op_xc() |
| 471 | { |
| 472 | if (!check_op_43()) return; |
| 473 | |
| 474 | // XC: Exchange Carry F/F with Carry Save F/F |
| 475 | op_illegal(); |
| 476 | } |
| 477 | |
| 478 | |
| 479 | // Flag |
| 480 | |
| 481 | void ucom4_cpu_device::op_sfb() |
| 482 | { |
| 483 | if (!check_op_43()) return; |
| 484 | |
| 485 | // SFB B: Set a single bit of FLAG |
| 486 | op_illegal(); |
| 487 | } |
| 488 | |
| 489 | void ucom4_cpu_device::op_rfb() |
| 490 | { |
| 491 | if (!check_op_43()) return; |
| 492 | |
| 493 | // RFB B: Reset a single bit of FLAG |
| 494 | op_illegal(); |
| 495 | } |
| 496 | |
| 497 | void ucom4_cpu_device::op_fbt() |
| 498 | { |
| 499 | if (!check_op_43()) return; |
| 500 | |
| 501 | // FBT B: skip next on bit(FLAG) |
| 502 | op_illegal(); |
| 503 | } |
| 504 | |
| 505 | void ucom4_cpu_device::op_fbf() |
| 506 | { |
| 507 | if (!check_op_43()) return; |
| 508 | |
| 509 | // FBF B: skip next on not bit(FLAG) |
| 510 | op_illegal(); |
| 511 | } |
| 512 | |
| 513 | |
| 514 | // Accumulator |
| 515 | |
| 516 | void ucom4_cpu_device::op_rar() |
| 517 | { |
| 518 | if (!check_op_43()) return; |
| 519 | |
| 520 | // RAR: Rotate ACC Right through Carry F/F |
| 521 | op_illegal(); |
| 522 | } |
| 523 | |
| 524 | |
| 525 | // Increment and Decrement |
| 526 | |
| 527 | void ucom4_cpu_device::op_inm() |
| 528 | { |
| 529 | if (!check_op_43()) return; |
| 530 | |
| 531 | // INM: Increment RAM, skip next on carry |
| 532 | op_illegal(); |
| 533 | } |
| 534 | |
| 535 | void ucom4_cpu_device::op_dem() |
| 536 | { |
| 537 | if (!check_op_43()) return; |
| 538 | |
| 539 | // DEM: Decrement RAM, skip next on carry |
| 540 | op_illegal(); |
| 541 | } |
| 542 | |
| 543 | |
| 544 | // Timer |
| 545 | |
| 546 | void ucom4_cpu_device::op_stm() |
| 547 | { |
| 548 | if (!check_op_43()) return; |
| 549 | |
| 550 | // STM X: Reset Timer F/F, Start Timer with X |
| 551 | op_illegal(); |
| 552 | } |
| 553 | |
| 554 | void ucom4_cpu_device::op_ttm() |
| 555 | { |
| 556 | if (!check_op_43()) return; |
| 557 | |
| 558 | // TTM: skip next on Timer F/F |
| 559 | op_illegal(); |
| 560 | } |
| 561 | |
| 562 | |
| 563 | // Interrupt |
| 564 | |
| 565 | void ucom4_cpu_device::op_ei() |
| 566 | { |
| 567 | if (!check_op_43()) return; |
| 568 | |
| 569 | // EI: Set Interrupt Enable F/F |
| 570 | op_illegal(); |
| 571 | } |
| 572 | |
| 573 | void ucom4_cpu_device::op_di() |
| 574 | { |
| 575 | if (!check_op_43()) return; |
| 576 | |
| 577 | // DI: Reset Interrupt Enable F/F |
| 578 | op_illegal(); |
| 579 | } |