trunk/src/emu/cpu/m6502/m6502.c
| r32158 | r32159 | |
| 129 | 129 | inst_substate = 0; |
| 130 | 130 | inst_state_base = 0; |
| 131 | 131 | sync = false; |
| 132 | | end_cycles = 0; |
| 133 | 132 | inhibit_interrupts = false; |
| 134 | 133 | } |
| 135 | 134 | |
| r32158 | r32159 | |
| 143 | 142 | apu_irq_state = false; |
| 144 | 143 | irq_taken = false; |
| 145 | 144 | v_state = false; |
| 146 | | end_cycles = 0; |
| 147 | 145 | sync = false; |
| 148 | 146 | sync_w(CLEAR_LINE); |
| 149 | 147 | inhibit_interrupts = false; |
| r32158 | r32159 | |
| 400 | 398 | return v; |
| 401 | 399 | } |
| 402 | 400 | |
| 403 | | UINT64 m6502_device::get_cycle() |
| 404 | | { |
| 405 | | return end_cycles == 0 || icount <= 0 ? machine().time().as_ticks(clock()) : end_cycles - icount; |
| 406 | | } |
| 407 | | |
| 408 | 401 | void m6502_device::execute_run() |
| 409 | 402 | { |
| 410 | | // get_cycle() is currently unused, and this precalculation |
| 411 | | // enormously slows down drivers with high interleave |
| 412 | | #if 0 |
| 413 | | end_cycles = machine().time().as_ticks(clock()) + icount; |
| 414 | | #endif |
| 415 | 403 | if(inst_substate) |
| 416 | 404 | do_exec_partial(); |
| 417 | 405 | |
| r32158 | r32159 | |
| 424 | 412 | } |
| 425 | 413 | do_exec_full(); |
| 426 | 414 | } |
| 427 | | end_cycles = 0; |
| 428 | 415 | } |
| 429 | 416 | |
| 430 | 417 | void m6502_device::execute_set_input(int inputnum, int state) |
trunk/src/emu/cpu/m6502/m6502.h
| r32158 | r32159 | |
| 61 | 61 | DECLARE_WRITE_LINE_MEMBER( irq_line ); |
| 62 | 62 | DECLARE_WRITE_LINE_MEMBER( nmi_line ); |
| 63 | 63 | |
| 64 | | UINT64 get_cycle(); |
| 65 | 64 | bool get_sync() const { return sync; } |
| 66 | 65 | void disable_direct() { direct_disabled = true; } |
| 67 | 66 | |
| r32158 | r32159 | |
| 201 | 200 | int icount; |
| 202 | 201 | bool nmi_state, irq_state, apu_irq_state, v_state; |
| 203 | 202 | bool irq_taken, sync, direct_disabled, inhibit_interrupts; |
| 204 | | UINT64 end_cycles; |
| 205 | 203 | |
| 206 | 204 | static const disasm_entry disasm_entries[0x100]; |
| 207 | 205 | |
trunk/src/emu/cpu/h8/h8_timer16.c
| r32158 | r32159 | |
| 199 | 199 | return; |
| 200 | 200 | |
| 201 | 201 | if(!cur_time) |
| 202 | | cur_time = cpu->get_cycle(); |
| 202 | cur_time = cpu->total_cycles(); |
| 203 | 203 | |
| 204 | 204 | if(!channel_active) { |
| 205 | 205 | last_clock_update = cur_time; |
| r32158 | r32159 | |
| 257 | 257 | } |
| 258 | 258 | |
| 259 | 259 | if(!cur_time) |
| 260 | | cur_time = cpu->get_cycle(); |
| 260 | cur_time = cpu->total_cycles(); |
| 261 | 261 | |
| 262 | 262 | if(counter_incrementing) { |
| 263 | 263 | UINT32 event_delay = 0xffffffff; |
| r32158 | r32159 | |
| 297 | 297 | event_time = 0; |
| 298 | 298 | |
| 299 | 299 | if(event_time && 0) |
| 300 | | logerror("%s: next event in %d cycles (%ld)\n", tag(), int(event_time - cpu->get_cycle()), long(event_time)); |
| 300 | logerror("%s: next event in %d cycles (%ld)\n", tag(), int(event_time - cpu->total_cycles()), long(event_time)); |
| 301 | 301 | |
| 302 | 302 | } else { |
| 303 | 303 | logerror("decrementing counter\n"); |
trunk/src/emu/cpu/h8/h8.c
| r32158 | r32159 | |
| 130 | 130 | MACF = 0; |
| 131 | 131 | inst_state = STATE_RESET; |
| 132 | 132 | inst_substate = 0; |
| 133 | | end_cycles = 0; |
| 134 | 133 | } |
| 135 | 134 | |
| 136 | 135 | void h8_device::device_reset() |
| 137 | 136 | { |
| 138 | 137 | inst_state = STATE_RESET; |
| 139 | 138 | inst_substate = 0; |
| 140 | | end_cycles = 0; |
| 141 | 139 | |
| 142 | 140 | irq_vector = 0; |
| 143 | 141 | irq_level = -1; |
| r32158 | r32159 | |
| 162 | 160 | return 0; |
| 163 | 161 | } |
| 164 | 162 | |
| 165 | | UINT64 h8_device::get_cycle() |
| 166 | | { |
| 167 | | return end_cycles == 0 || icount <= 0 ? machine().time().as_ticks(clock()) : end_cycles - icount; |
| 168 | | } |
| 169 | | |
| 170 | 163 | void h8_device::recompute_bcount(UINT64 event_time) |
| 171 | 164 | { |
| 172 | | if(!event_time || event_time >= end_cycles) { |
| 165 | if(!event_time || event_time >= total_cycles() + icount) { |
| 173 | 166 | bcount = 0; |
| 174 | 167 | return; |
| 175 | 168 | } |
| 176 | | bcount = end_cycles - event_time; |
| 169 | bcount = total_cycles() - event_time; |
| 177 | 170 | } |
| 178 | 171 | |
| 179 | 172 | void h8_device::execute_run() |
| 180 | 173 | { |
| 181 | | start_cycles = machine().time().as_ticks(clock()); |
| 182 | | end_cycles = start_cycles + icount; |
| 174 | internal_update(total_cycles()); |
| 183 | 175 | |
| 184 | | internal_update(start_cycles); |
| 185 | | |
| 186 | 176 | if(inst_substate) |
| 187 | 177 | do_exec_partial(); |
| 188 | 178 | |
| r32158 | r32159 | |
| 196 | 186 | do_exec_full(); |
| 197 | 187 | } |
| 198 | 188 | while(bcount && icount && icount <= bcount) |
| 199 | | internal_update(end_cycles - bcount); |
| 189 | internal_update(total_cycles() + icount - bcount); |
| 200 | 190 | if(inst_substate) |
| 201 | 191 | do_exec_partial(); |
| 202 | 192 | } |
| 203 | | end_cycles = 0; |
| 204 | 193 | } |
| 205 | 194 | |
| 206 | 195 | void h8_device::add_event(UINT64 &event_time, UINT64 new_event) |
| r32158 | r32159 | |
| 213 | 202 | |
| 214 | 203 | void h8_device::internal_update() |
| 215 | 204 | { |
| 216 | | internal_update(get_cycle()); |
| 205 | internal_update(total_cycles()); |
| 217 | 206 | } |
| 218 | 207 | |
| 219 | 208 | const address_space_config *h8_device::memory_space_config(address_spacenum spacenum) const |
trunk/src/emu/cpu/h8/h8.h
| r32158 | r32159 | |
| 76 | 76 | |
| 77 | 77 | h8_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source, bool mode_a16, address_map_delegate map_delegate); |
| 78 | 78 | |
| 79 | | UINT64 get_cycle(); |
| 80 | 79 | void internal_update(); |
| 81 | 80 | |
| 82 | 81 | void set_irq(int irq_vector, int irq_level, bool irq_nmi); |
| r32158 | r32159 | |
| 214 | 213 | |
| 215 | 214 | int inst_state, inst_substate; |
| 216 | 215 | int icount, bcount; |
| 217 | | UINT64 start_cycles, end_cycles; |
| 218 | 216 | int irq_vector, taken_irq_vector; |
| 219 | 217 | int irq_level, taken_irq_level; |
| 220 | 218 | bool irq_required, irq_nmi; |
trunk/src/emu/cpu/h8/h8_sci.c
| r32158 | r32159 | |
| 461 | 461 | case CLKM_INTERNAL_ASYNC_OUT: |
| 462 | 462 | case CLKM_INTERNAL_SYNC_OUT: |
| 463 | 463 | logerror("%s: Starting internal clock\n", tag()); |
| 464 | | clock_base = cpu->get_cycle(); |
| 464 | clock_base = cpu->total_cycles(); |
| 465 | 465 | cpu->internal_update(); |
| 466 | 466 | break; |
| 467 | 467 | |
| 468 | 468 | case CLKM_EXTERNAL_RATE_ASYNC: |
| 469 | 469 | logerror("%s: Simulating external clock async\n", tag()); |
| 470 | | clock_base = UINT64(cpu->get_cycle()*internal_to_external_ratio); |
| 470 | clock_base = UINT64(cpu->total_cycles()*internal_to_external_ratio); |
| 471 | 471 | cpu->internal_update(); |
| 472 | 472 | break; |
| 473 | 473 | |
| 474 | 474 | case CLKM_EXTERNAL_RATE_SYNC: |
| 475 | 475 | logerror("%s: Simulating external clock sync\n", tag()); |
| 476 | | clock_base = UINT64(cpu->get_cycle()*2*internal_to_external_ratio); |
| 476 | clock_base = UINT64(cpu->total_cycles()*2*internal_to_external_ratio); |
| 477 | 477 | cpu->internal_update(); |
| 478 | 478 | break; |
| 479 | 479 | |
trunk/src/emu/cpu/mcs96/mcs96.c
| r32158 | r32159 | |
| 94 | 94 | return 1; |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | | UINT64 mcs96_device::get_cycle() |
| 98 | | { |
| 99 | | return end_cycles == 0 || icount <= 0 ? machine().time().as_ticks(clock()) : end_cycles - icount; |
| 100 | | } |
| 101 | | |
| 102 | 97 | void mcs96_device::recompute_bcount(UINT64 event_time) |
| 103 | 98 | { |
| 104 | | if(!event_time || event_time >= end_cycles) { |
| 99 | if(!event_time || event_time >= total_cycles()+icount) { |
| 105 | 100 | bcount = 0; |
| 106 | 101 | return; |
| 107 | 102 | } |
| 108 | | bcount = end_cycles - event_time; |
| 103 | bcount = total_cycles() - event_time; |
| 109 | 104 | } |
| 110 | 105 | |
| 111 | 106 | void mcs96_device::check_irq() |
| r32158 | r32159 | |
| 115 | 110 | |
| 116 | 111 | void mcs96_device::execute_run() |
| 117 | 112 | { |
| 118 | | UINT64 start_cycles = machine().time().as_ticks(clock()); |
| 119 | | end_cycles = start_cycles + icount; |
| 113 | internal_update(total_cycles()); |
| 120 | 114 | |
| 121 | | internal_update(start_cycles); |
| 115 | // if(inst_substate) |
| 116 | // do_exec_partial(); |
| 122 | 117 | |
| 123 | | if(/*inst_substate*/ 0) |
| 124 | | do_exec_partial(); |
| 125 | | |
| 126 | 118 | while(icount > 0) { |
| 127 | 119 | while(icount > bcount) { |
| 128 | 120 | int picount = inst_state >= 0x200 ? -1 : icount; |
| r32158 | r32159 | |
| 132 | 124 | } |
| 133 | 125 | } |
| 134 | 126 | while(bcount && icount <= bcount) |
| 135 | | internal_update(end_cycles - bcount); |
| 127 | internal_update(total_cycles() + icount - bcount); |
| 128 | // if(inst_substate) |
| 129 | // do_exec_partial(); |
| 136 | 130 | } |
| 137 | | end_cycles = 0; |
| 138 | 131 | } |
| 139 | 132 | |
| 140 | 133 | void mcs96_device::execute_set_input(int inputnum, int state) |
trunk/src/emu/cpu/mcs96/i8x9x.c
| r32158 | r32159 | |
| 87 | 87 | hso_info[i].active = true; |
| 88 | 88 | hso_info[i].command = hso_command; |
| 89 | 89 | hso_info[i].time = hso_time; |
| 90 | | internal_update(get_cycle()); |
| 90 | internal_update(total_cycles()); |
| 91 | 91 | return; |
| 92 | 92 | } |
| 93 | 93 | hso_cam_hold.active = true; |
| r32158 | r32159 | |
| 105 | 105 | void i8x9x_device::serial_send(UINT8 data) |
| 106 | 106 | { |
| 107 | 107 | serial_send_buf = data; |
| 108 | | serial_send_timer = get_cycle() + 9600; |
| 108 | serial_send_timer = total_cycles() + 9600; |
| 109 | 109 | } |
| 110 | 110 | |
| 111 | 111 | void i8x9x_device::serial_send_done() |
| r32158 | r32159 | |
| 123 | 123 | case 0x02: |
| 124 | 124 | ad_command = data; |
| 125 | 125 | if(ad_command & 8) |
| 126 | | ad_start(get_cycle()); |
| 126 | ad_start(total_cycles()); |
| 127 | 127 | break; |
| 128 | 128 | case 0x03: |
| 129 | 129 | logerror("%s: hsi_mode %02x (%04x)\n", tag(), data, PPC); |
| r32158 | r32159 | |
| 229 | 229 | return pending_irq; |
| 230 | 230 | case 0x0a: |
| 231 | 231 | logerror("%s: read timer1 l (%04x)\n", tag(), PPC); |
| 232 | | return timer_value(1, get_cycle()); |
| 232 | return timer_value(1, total_cycles()); |
| 233 | 233 | case 0x0b: |
| 234 | 234 | logerror("%s: read timer1 h (%04x)\n", tag(), PPC); |
| 235 | | return timer_value(1, get_cycle()) >> 8; |
| 235 | return timer_value(1, total_cycles()) >> 8; |
| 236 | 236 | case 0x0c: |
| 237 | 237 | logerror("%s: read timer2 l (%04x)\n", tag(), PPC); |
| 238 | | return timer_value(2, get_cycle()); |
| 238 | return timer_value(2, total_cycles()); |
| 239 | 239 | case 0x0d: |
| 240 | 240 | logerror("%s: read timer2 h (%04x)\n", tag(), PPC); |
| 241 | | return timer_value(2, get_cycle()) >> 8; |
| 241 | return timer_value(2, total_cycles()) >> 8; |
| 242 | 242 | case 0x0e: { |
| 243 | 243 | static int last = -1; |
| 244 | 244 | if(io->read_word(P0*2) != last) { |
| r32158 | r32159 | |
| 282 | 282 | logerror("%s: read hsi time (%04x)\n", tag(), PPC); |
| 283 | 283 | return 0x0000; |
| 284 | 284 | case 0x0a: |
| 285 | | return timer_value(1, get_cycle()); |
| 285 | return timer_value(1, total_cycles()); |
| 286 | 286 | case 0x0c: |
| 287 | 287 | logerror("%s: read timer2 (%04x)\n", tag(), PPC); |
| 288 | | return timer_value(2, get_cycle()); |
| 288 | return timer_value(2, total_cycles()); |
| 289 | 289 | default: |
| 290 | 290 | return io_r8(adr) | (io_r8(adr+1) << 8); |
| 291 | 291 | } |
trunk/docs/m6502.txt
| r32158 | r32159 | |
| 95 | 95 | of the sync line is given by the cpu method get_sync(), making |
| 96 | 96 | implementing the decryption in the handler possible. |
| 97 | 97 | |
| 98 | | In a final addition, the cpu method get_cycle() gives the current time |
| 99 | | in cycles since the start of the machine from the point of view of the |
| 100 | | cpu. Or, in other words, what is usually called the cycle number for |
| 101 | | the cpu when somebody talks about bus contention or wait states. The |
| 102 | | call is designed to be fast (no system-wide sync, usually no call to |
| 103 | | machine.time()) and is precise. Cycle number for every access is |
| 104 | | exact at the sub-instruction level. |
| 98 | Also, as for every executable device, the cpu method total_cycles() |
| 99 | gives the current time in cycles since the start of the machine from |
| 100 | the point of view of the cpu. Or, in other words, what is usually |
| 101 | called the cycle number for the cpu when somebody talks about bus |
| 102 | contention or wait states. The call is designed to be fast (no |
| 103 | system-wide sync, no call to machine.time()) and is precise. Cycle |
| 104 | number for every access is exact at the sub-instruction level. |
| 105 | 105 | |
| 106 | 106 | The 4510 special nomap line is accessible through get_nomap(). |
| 107 | 107 | |