trunk/src/emu/cpu/ucom4/ucom4.c
| r243569 | r243570 | |
| 10 | 10 | I've also looked at asterick's JavaScript D553 emulator for verification, with permission. |
| 11 | 11 | |
| 12 | 12 | TODO: |
| 13 | | - add external interrupt |
| 14 | 13 | - what happens with uCOM-43 opcodes on an uCOM-44/45 MCU? |
| 15 | 14 | - what's the data after the ROM data for? (eg. 2000-2047, official ROM size is 2000) |
| 16 | 15 | |
| r243569 | r243570 | |
| 153 | 152 | m_timer_f = 0; |
| 154 | 153 | m_int_f = 0; |
| 155 | 154 | m_inte_f = 0; |
| 155 | m_int_line = CLEAR_LINE; |
| 156 | 156 | |
| 157 | 157 | // register for savestates |
| 158 | 158 | save_item(NAME(m_stack)); |
| r243569 | r243570 | |
| 168 | 168 | save_item(NAME(m_carry_s_f)); |
| 169 | 169 | save_item(NAME(m_timer_f)); |
| 170 | 170 | save_item(NAME(m_int_f)); |
| 171 | | save_item(NAME(m_inte_f)); |
| 171 | save_item(NAME(m_int_line)); |
| 172 | 172 | |
| 173 | 173 | // register state for debugger |
| 174 | 174 | state_add(UCOM4_PC, "PC", m_pc).formatstr("%04X"); |
| r243569 | r243570 | |
| 195 | 195 | m_skip = false; |
| 196 | 196 | |
| 197 | 197 | m_timer->adjust(attotime::never); |
| 198 | | |
| 198 | |
| 199 | // clear interrupt |
| 200 | m_int_line = CLEAR_LINE; |
| 201 | m_int_f = 0; |
| 202 | m_inte_f = (m_family == NEC_UCOM43) ? 0 : 1; |
| 203 | |
| 199 | 204 | // clear i/o |
| 200 | 205 | for (int i = NEC_UCOM4_PORTC; i <= NEC_UCOM4_PORTI; i++) |
| 201 | 206 | output_w(i, 0xf); |
| r243569 | r243570 | |
| 207 | 212 | // execute |
| 208 | 213 | //------------------------------------------------- |
| 209 | 214 | |
| 215 | void ucom4_cpu_device::execute_set_input(int line, int state) |
| 216 | { |
| 217 | switch (line) |
| 218 | { |
| 219 | case 0: |
| 220 | // edge triggered |
| 221 | if (m_int_line == CLEAR_LINE && state) |
| 222 | m_int_f = 1; |
| 223 | m_int_line = state; |
| 224 | |
| 225 | break; |
| 226 | |
| 227 | default: |
| 228 | break; |
| 229 | } |
| 230 | } |
| 231 | |
| 210 | 232 | inline void ucom4_cpu_device::increment_pc() |
| 211 | 233 | { |
| 212 | 234 | // upper bits (field register) don't auto-increment |
| r243569 | r243570 | |
| 233 | 255 | // remember previous opcode |
| 234 | 256 | m_prev_op = m_op; |
| 235 | 257 | |
| 258 | // handle interrupt - it not accepted during LI($9x) or EI($31), or while skipping |
| 259 | if (m_int_f && m_inte_f && (m_prev_op & 0xf0) != 0x90 && m_prev_op != 0x31 && !m_skip) |
| 260 | { |
| 261 | m_icount--; |
| 262 | push_stack(); |
| 263 | m_pc = 0xf << 2; |
| 264 | m_int_f = 0; |
| 265 | m_inte_f = (m_family == NEC_UCOM43) ? 0 : 1; |
| 266 | |
| 267 | standard_irq_callback(0); |
| 268 | } |
| 269 | |
| 270 | // fetch next opcode |
| 236 | 271 | debugger_instruction_hook(this, m_pc); |
| 237 | 272 | m_op = m_program->read_byte(m_pc); |
| 238 | 273 | m_bitmask = 1 << (m_op & 0x03); |
| r243569 | r243570 | |
| 245 | 280 | m_op = 0; // nop |
| 246 | 281 | } |
| 247 | 282 | |
| 283 | // handle opcode |
| 248 | 284 | switch (m_op & 0xf0) |
| 249 | 285 | { |
| 250 | 286 | case 0x80: op_ldz(); break; |
trunk/src/emu/cpu/ucom4/ucom4.h
| r243569 | r243570 | |
| 110 | 110 | virtual UINT32 execute_min_cycles() const { return 1; } |
| 111 | 111 | virtual UINT32 execute_max_cycles() const { return 2; } |
| 112 | 112 | virtual UINT32 execute_input_lines() const { return 1; } |
| 113 | virtual void execute_set_input(int line, int state); |
| 113 | 114 | virtual void execute_run(); |
| 114 | | |
| 115 | |
| 115 | 116 | // device_memory_interface overrides |
| 116 | 117 | 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); } |
| 117 | 118 | |
| r243569 | r243570 | |
| 153 | 154 | UINT8 m_timer_f; // timer out flag |
| 154 | 155 | UINT8 m_int_f; // interrupt flag |
| 155 | 156 | UINT8 m_inte_f; // interrupt enable flag |
| 157 | int m_int_line; // interrupt pin state |
| 156 | 158 | |
| 157 | 159 | // i/o handlers |
| 158 | 160 | devcb_read8 m_read_a; |