trunk/src/emu/cpu/ucom4/ucom4.c
| r243429 | r243430 | |
| 116 | 116 | m_datamask = (1 << m_datawidth) - 1; |
| 117 | 117 | m_dph_mask = m_datamask >> 4; |
| 118 | 118 | |
| 119 | | m_read_a.resolve_safe(0); |
| 120 | | m_read_b.resolve_safe(0); |
| 121 | | m_read_c.resolve_safe(0); |
| 122 | | m_read_d.resolve_safe(0); |
| 119 | m_read_a.resolve_safe(0xf); |
| 120 | m_read_b.resolve_safe(0xf); |
| 121 | m_read_c.resolve_safe(0xf); |
| 122 | m_read_d.resolve_safe(0xf); |
| 123 | 123 | |
| 124 | 124 | m_write_c.resolve_safe(); |
| 125 | 125 | m_write_d.resolve_safe(); |
| r243429 | r243430 | |
| 131 | 131 | |
| 132 | 132 | // zerofill |
| 133 | 133 | memset(m_stack, 0, sizeof(m_stack)); |
| 134 | memset(m_port_out, 0, sizeof(m_port_out)); |
| 134 | 135 | m_op = 0; |
| 135 | 136 | m_prev_op = 0; |
| 136 | | m_arg = 0; |
| 137 | 137 | m_skip = false; |
| 138 | 138 | m_pc = 0; |
| 139 | 139 | m_acc = 0; |
| r243429 | r243430 | |
| 147 | 147 | |
| 148 | 148 | // register for savestates |
| 149 | 149 | save_item(NAME(m_stack)); |
| 150 | save_item(NAME(m_port_out)); |
| 150 | 151 | save_item(NAME(m_op)); |
| 151 | 152 | save_item(NAME(m_prev_op)); |
| 152 | | save_item(NAME(m_arg)); |
| 153 | 153 | save_item(NAME(m_skip)); |
| 154 | 154 | save_item(NAME(m_pc)); |
| 155 | 155 | save_item(NAME(m_acc)); |
| r243429 | r243430 | |
| 185 | 185 | m_pc = 0; |
| 186 | 186 | m_op = 0; |
| 187 | 187 | m_skip = false; |
| 188 | |
| 189 | // clear i/o |
| 190 | for (int i = NEC_UCOM4_PORTC; i <= NEC_UCOM4_PORTI; i++) |
| 191 | output_w(i, 0xf); |
| 188 | 192 | } |
| 189 | 193 | |
| 190 | 194 | |
| r243429 | r243430 | |
| 215 | 219 | |
| 216 | 220 | debugger_instruction_hook(this, m_pc); |
| 217 | 221 | m_op = m_program->read_byte(m_pc); |
| 222 | m_bitmask = 1 << (m_op & 0x03); |
| 218 | 223 | m_pc = (m_pc + 1) & m_prgmask; |
| 219 | 224 | fetch_arg(); |
| 220 | 225 | |
trunk/src/emu/cpu/ucom4/ucom4.h
| r243429 | r243430 | |
| 45 | 45 | ucom4_cpu_device::set_write_i_callback(*device, DEVCB_##_devcb); |
| 46 | 46 | |
| 47 | 47 | |
| 48 | enum |
| 49 | { |
| 50 | NEC_UCOM4_PORTA = 0, |
| 51 | NEC_UCOM4_PORTB, |
| 52 | NEC_UCOM4_PORTC, |
| 53 | NEC_UCOM4_PORTD, |
| 54 | NEC_UCOM4_PORTE, |
| 55 | NEC_UCOM4_PORTF, |
| 56 | NEC_UCOM4_PORTG, |
| 57 | NEC_UCOM4_PORTH, |
| 58 | NEC_UCOM4_PORTI |
| 59 | }; |
| 48 | 60 | |
| 61 | |
| 62 | |
| 49 | 63 | class ucom4_cpu_device : public cpu_device |
| 50 | 64 | { |
| 51 | 65 | public: |
| r243429 | r243430 | |
| 117 | 131 | int m_datawidth; |
| 118 | 132 | int m_prgmask; |
| 119 | 133 | int m_datamask; |
| 120 | | int m_family; // MCU family (43/44/45) |
| 121 | | int m_stack_levels; // number of callstack levels |
| 122 | | UINT16 m_stack[3+1]; // max 3 |
| 134 | int m_family; // MCU family (43/44/45) |
| 135 | int m_stack_levels; // number of callstack levels |
| 136 | UINT16 m_stack[3+1]; // max 3 |
| 137 | UINT8 m_port_out[0x10]; // last value written to output port |
| 123 | 138 | UINT8 m_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 |
| 139 | UINT8 m_prev_op; // previous opcode |
| 140 | UINT8 m_arg; // opcode argument for 2-byte opcodes |
| 141 | UINT8 m_bitmask; // opcode bit argument |
| 142 | bool m_skip; // skip next opcode |
| 127 | 143 | int m_icount; |
| 128 | 144 | |
| 129 | | UINT16 m_pc; // program counter |
| 130 | | UINT8 m_acc; // 4-bit accumulator |
| 131 | | UINT8 m_dpl; // 4-bit data pointer low (RAM x) |
| 132 | | UINT8 m_dph; // 4-bit(?) data pointer high (RAM y) |
| 145 | UINT16 m_pc; // program counter |
| 146 | UINT8 m_acc; // 4-bit accumulator |
| 147 | UINT8 m_dpl; // 4-bit data pointer low (RAM x) |
| 148 | UINT8 m_dph; // 4-bit(?) data pointer high (RAM y) |
| 133 | 149 | UINT8 m_dph_mask; |
| 134 | | UINT8 m_carry_f; // carry flag |
| 135 | | UINT8 m_carry_s_f; // carry save flag |
| 136 | | UINT8 m_timer_f; // timer out flag |
| 137 | | UINT8 m_int_f; // interrupt flag |
| 138 | | UINT8 m_inte_f; // interrupt enable flag |
| 150 | UINT8 m_carry_f; // carry flag |
| 151 | UINT8 m_carry_s_f; // carry save flag |
| 152 | UINT8 m_timer_f; // timer out flag |
| 153 | UINT8 m_int_f; // interrupt flag |
| 154 | UINT8 m_inte_f; // interrupt enable flag |
| 139 | 155 | |
| 140 | 156 | // i/o handlers |
| 141 | 157 | devcb_read8 m_read_a; |
| r243429 | r243430 | |
| 156 | 172 | void ram_w(UINT8 data); |
| 157 | 173 | void pop_stack(); |
| 158 | 174 | void push_stack(); |
| 175 | UINT8 input_r(int index); |
| 176 | void output_w(int index, UINT8 data); |
| 159 | 177 | void op_illegal(); |
| 160 | 178 | bool check_op_43(); |
| 161 | 179 | |
trunk/src/emu/cpu/ucom4/ucom4op.inc
| r243429 | r243430 | |
| 31 | 31 | m_stack[0] = m_pc; |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | UINT8 ucom4_cpu_device::input_r(int index) |
| 35 | { |
| 36 | index &= 0xf; |
| 37 | UINT8 inp = 0xf; |
| 38 | |
| 39 | switch (index) |
| 40 | { |
| 41 | case NEC_UCOM4_PORTA: inp = m_read_a(index, 0xff) & 0xf; break; |
| 42 | case NEC_UCOM4_PORTB: inp = m_read_b(index, 0xff) & 0xf; break; |
| 43 | case NEC_UCOM4_PORTC: inp = m_read_c(index, 0xff) & 0xf; break; |
| 44 | case NEC_UCOM4_PORTD: inp = m_read_d(index, 0xff) & 0xf; break; |
| 45 | |
| 46 | default: |
| 47 | logerror("%s read from unknown port %c at $%03X\n", tag(), 'A' + index, m_pc); |
| 48 | break; |
| 49 | } |
| 50 | |
| 51 | return inp; |
| 52 | } |
| 53 | |
| 54 | void ucom4_cpu_device::output_w(int index, UINT8 data) |
| 55 | { |
| 56 | index &= 0xf; |
| 57 | data &= 0xf; |
| 58 | |
| 59 | switch (index) |
| 60 | { |
| 61 | case NEC_UCOM4_PORTC: m_write_c(index, data, 0xff); break; |
| 62 | case NEC_UCOM4_PORTD: m_write_d(index, data, 0xff); break; |
| 63 | case NEC_UCOM4_PORTE: m_write_e(index, data, 0xff); break; |
| 64 | case NEC_UCOM4_PORTF: m_write_f(index, data, 0xff); break; |
| 65 | case NEC_UCOM4_PORTG: m_write_g(index, data, 0xff); break; |
| 66 | case NEC_UCOM4_PORTH: m_write_h(index, data, 0xff); break; |
| 67 | case NEC_UCOM4_PORTI: m_write_i(index, data & 7, 0xff); break; |
| 68 | |
| 69 | default: |
| 70 | logerror("%s write to unknown port %c = $%X at $%03X\n", tag(), 'A' + index, data & 0xf, m_pc); |
| 71 | break; |
| 72 | } |
| 73 | |
| 74 | m_port_out[index] = data; |
| 75 | } |
| 76 | |
| 34 | 77 | void ucom4_cpu_device::op_illegal() |
| 35 | 78 | { |
| 36 | 79 | logerror("%s unknown opcode $%02X at $%03X\n", tag(), m_op, m_pc); |
| r243429 | r243430 | |
| 240 | 283 | void ucom4_cpu_device::op_rmb() |
| 241 | 284 | { |
| 242 | 285 | // RMB B: Reset a single bit of RAM |
| 243 | | ram_w(ram_r() & ~(1 << (m_op & 0x03))); |
| 286 | ram_w(ram_r() & ~m_bitmask); |
| 244 | 287 | } |
| 245 | 288 | |
| 246 | 289 | void ucom4_cpu_device::op_smb() |
| 247 | 290 | { |
| 248 | 291 | // SMB B: Set a single bit of RAM |
| 249 | | ram_w(ram_r() | (1 << (m_op & 0x03))); |
| 292 | ram_w(ram_r() | m_bitmask); |
| 250 | 293 | } |
| 251 | 294 | |
| 252 | 295 | void ucom4_cpu_device::op_reb() |
| 253 | 296 | { |
| 254 | 297 | // REB B: Reset a single bit of output port E |
| 255 | 298 | m_icount--; |
| 256 | | op_illegal(); |
| 299 | output_w(NEC_UCOM4_PORTE, m_port_out[NEC_UCOM4_PORTE] & ~m_bitmask); |
| 257 | 300 | } |
| 258 | 301 | |
| 259 | 302 | void ucom4_cpu_device::op_seb() |
| 260 | 303 | { |
| 261 | 304 | // SEB B: Set a single bit of output port E |
| 262 | 305 | m_icount--; |
| 263 | | op_illegal(); |
| 306 | output_w(NEC_UCOM4_PORTE, m_port_out[NEC_UCOM4_PORTE] | m_bitmask); |
| 264 | 307 | } |
| 265 | 308 | |
| 266 | 309 | void ucom4_cpu_device::op_rpb() |
| 267 | 310 | { |
| 268 | 311 | // RPB B: Reset a single bit of output port (DPl) |
| 269 | | op_illegal(); |
| 312 | output_w(m_dpl, m_port_out[m_dpl] & ~m_bitmask); |
| 270 | 313 | } |
| 271 | 314 | |
| 272 | 315 | void ucom4_cpu_device::op_spb() |
| 273 | 316 | { |
| 274 | 317 | // SPB B: Set a single bit of output port (DPl) |
| 275 | | op_illegal(); |
| 318 | output_w(m_dpl, m_port_out[m_dpl] | m_bitmask); |
| 276 | 319 | } |
| 277 | 320 | |
| 278 | 321 | |
| r243429 | r243430 | |
| 340 | 383 | void ucom4_cpu_device::op_cmb() |
| 341 | 384 | { |
| 342 | 385 | // CMB B: skip next on bit(ACC) equals bit(RAM) |
| 343 | | UINT8 mask = 1 << (m_op & 0x03); |
| 344 | | m_skip = ((m_acc & mask) == (ram_r() & mask)); |
| 386 | m_skip = ((m_acc & m_bitmask) == (ram_r() & m_bitmask)); |
| 345 | 387 | } |
| 346 | 388 | |
| 347 | 389 | void ucom4_cpu_device::op_tab() |
| 348 | 390 | { |
| 349 | 391 | // TAB B: skip next on bit(ACC) |
| 350 | | m_skip = ((m_acc & (1 << (m_op & 0x03))) != 0); |
| 392 | m_skip = ((m_acc & m_bitmask) != 0); |
| 351 | 393 | } |
| 352 | 394 | |
| 353 | 395 | void ucom4_cpu_device::op_cli() |
| r243429 | r243430 | |
| 362 | 404 | void ucom4_cpu_device::op_tmb() |
| 363 | 405 | { |
| 364 | 406 | // TMB B: skip next on bit(RAM) |
| 365 | | m_skip = ((ram_r() & (1 << (m_op & 0x03))) != 0); |
| 407 | m_skip = ((ram_r() & m_bitmask) != 0); |
| 366 | 408 | } |
| 367 | 409 | |
| 368 | 410 | void ucom4_cpu_device::op_tpa() |
| 369 | 411 | { |
| 370 | 412 | // TPA B: skip next on bit(input port A) |
| 371 | | op_illegal(); |
| 413 | m_skip = ((input_r(NEC_UCOM4_PORTA) & m_bitmask) != 0); |
| 372 | 414 | } |
| 373 | 415 | |
| 374 | 416 | void ucom4_cpu_device::op_tpb() |
| 375 | 417 | { |
| 376 | 418 | // TPB B: skip next on bit(input port (DPl)) |
| 377 | | op_illegal(); |
| 419 | m_skip = ((input_r(m_dpl) & m_bitmask) != 0); |
| 378 | 420 | } |
| 379 | 421 | |
| 380 | 422 | |
| r243429 | r243430 | |
| 392 | 434 | void ucom4_cpu_device::op_ia() |
| 393 | 435 | { |
| 394 | 436 | // IA: Input port A to ACC |
| 395 | | op_illegal(); |
| 437 | m_acc = input_r(NEC_UCOM4_PORTA); |
| 396 | 438 | } |
| 397 | 439 | |
| 398 | 440 | void ucom4_cpu_device::op_ip() |
| 399 | 441 | { |
| 400 | 442 | // IP: Input port (DPl) to ACC |
| 401 | | op_illegal(); |
| 443 | m_acc = input_r(m_dpl); |
| 402 | 444 | } |
| 403 | 445 | |
| 404 | 446 | void ucom4_cpu_device::op_oe() |
| 405 | 447 | { |
| 406 | 448 | // OE: Output ACC to port E |
| 407 | | m_write_e(0, m_acc, 0xff); |
| 449 | output_w(NEC_UCOM4_PORTE, m_acc); |
| 408 | 450 | } |
| 409 | 451 | |
| 410 | 452 | void ucom4_cpu_device::op_op() |
| 411 | 453 | { |
| 412 | 454 | // OP: Output ACC to port (DPl) |
| 413 | | op_illegal(); |
| 455 | output_w(m_dpl, m_acc); |
| 414 | 456 | } |
| 415 | 457 | |
| 416 | 458 | void ucom4_cpu_device::op_ocd() |
| 417 | 459 | { |
| 418 | 460 | // OCD X: Output X to ports C and D |
| 419 | | op_illegal(); |
| 461 | output_w(NEC_UCOM4_PORTD, m_arg >> 4); |
| 462 | output_w(NEC_UCOM4_PORTC, m_arg & 0xf); |
| 420 | 463 | } |
| 421 | 464 | |
| 422 | 465 | |