trunk/src/devices/cpu/z80/z80.cpp
| r253188 | r253189 | |
| 113 | 113 | |
| 114 | 114 | #define VERBOSE 0 |
| 115 | 115 | |
| 116 | /* Debug purpose: set to 1 to test /WAIT pin behaviour. |
| 117 | */ |
| 118 | #define STALLS_ON_WAIT_ASSERT 0 |
| 119 | |
| 116 | 120 | /* On an NMOS Z80, if LD A,I or LD A,R is interrupted, P/V flag gets reset, |
| 117 | 121 | even if IFF2 was set before this instruction. This issue was fixed on |
| 118 | 122 | the CMOS Z80, so until knowing (most) Z80 types on hardware, it's disabled */ |
| r253188 | r253189 | |
| 3478 | 3482 | ****************************************************************************/ |
| 3479 | 3483 | void z80_device::execute_run() |
| 3480 | 3484 | { |
| 3485 | |
| 3481 | 3486 | /* check for NMIs on the way in; they can only be set externally */ |
| 3482 | 3487 | /* via timers, and can't be dynamically enabled, so it is safe */ |
| 3483 | 3488 | /* to just check here */ |
| r253188 | r253189 | |
| 3518 | 3523 | PRVPC = PCD; |
| 3519 | 3524 | debugger_instruction_hook(this, PCD); |
| 3520 | 3525 | m_r++; |
| 3526 | #if STALLS_ON_WAIT_ASSERT |
| 3527 | static int test_cycles; |
| 3528 | |
| 3529 | if(m_wait_state == ASSERT_LINE) |
| 3530 | { |
| 3531 | m_icount --; |
| 3532 | test_cycles ++; |
| 3533 | } |
| 3534 | else |
| 3535 | { |
| 3536 | if(test_cycles != 0) |
| 3537 | printf("stalls for %d z80 cycles\n",test_cycles); |
| 3538 | test_cycles = 0; |
| 3539 | EXEC(op,rop()); |
| 3540 | } |
| 3541 | #else |
| 3521 | 3542 | EXEC(op,rop()); |
| 3543 | #endif |
| 3522 | 3544 | } while (m_icount > 0); |
| 3523 | 3545 | } |
| 3524 | 3546 | |
trunk/src/mame/drivers/nightgal.cpp
| r253188 | r253189 | |
| 120 | 120 | required_ioport m_io_dswb; |
| 121 | 121 | required_ioport m_io_dswc; |
| 122 | 122 | required_device<palette_device> m_palette; |
| 123 | | |
| 123 | void z80_wait_assert_cb(); |
| 124 | TIMER_CALLBACK_MEMBER( z80_wait_ack_cb ); |
| 125 | |
| 124 | 126 | UINT8 nightgal_gfx_nibble( int niboffset ); |
| 125 | 127 | void plot_nightgal_gfx_pixel( UINT8 pix, int x, int y ); |
| 126 | 128 | }; |
| r253188 | r253189 | |
| 420 | 422 | return m_blit_raw_data[offset]; |
| 421 | 423 | } |
| 422 | 424 | |
| 425 | TIMER_CALLBACK_MEMBER(nightgal_state::z80_wait_ack_cb) |
| 426 | { |
| 427 | m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, CLEAR_LINE); |
| 428 | } |
| 429 | |
| 430 | void nightgal_state::z80_wait_assert_cb() |
| 431 | { |
| 432 | m_maincpu->set_input_line(Z80_INPUT_LINE_WAIT, ASSERT_LINE); |
| 433 | |
| 434 | // Note: cycles_to_attotime requires z80 context to work, calling for example m_subcpu as context gives a x4 cycle boost in z80 terms (reads execute_cycles_to_clocks() from NCS?) even if they runs at same speed basically. |
| 435 | // TODO: needs a getter that tells a given CPU how many cycles requires an executing opcode for the r/w operation, which stacks with wait state penalty for accessing this specific area. |
| 436 | machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(4), timer_expired_delegate(FUNC(nightgal_state::z80_wait_ack_cb),this)); |
| 437 | } |
| 438 | |
| 423 | 439 | READ8_MEMBER(nightgal_state::royalqn_comm_r) |
| 424 | 440 | { |
| 441 | z80_wait_assert_cb(); |
| 425 | 442 | return (m_comms_ram[offset] & 0x80) | (0x7f); //bits 6-0 are undefined, presumably open bus |
| 426 | 443 | } |
| 427 | 444 | |
| 428 | 445 | WRITE8_MEMBER(nightgal_state::royalqn_comm_w) |
| 429 | 446 | { |
| 447 | z80_wait_assert_cb(); |
| 430 | 448 | m_comms_ram[offset] = data & 0x80; |
| 431 | 449 | } |
| 432 | 450 | |
| r253188 | r253189 | |
| 893 | 911 | |
| 894 | 912 | MCFG_QUANTUM_PERFECT_CPU("maincpu") |
| 895 | 913 | |
| 896 | | |
| 897 | 914 | /* video hardware */ |
| 898 | 915 | /* TODO: blitter clock is MASTER_CLOCK / 4, 320 x 264 pixels, 256 x 224 of visible area */ |
| 899 | 916 | MCFG_SCREEN_ADD("screen", RASTER) |