void blstroid_scanline_update(const device_config *screen, int scanline) { int offset = (scanline / 8) * 64 + 40; /* check for interrupts */ if (offset < 0x1000) if (atarigen_playfield[offset] & 0x8000) { int width, vpos; attotime period_on; attotime period_off; /* FIXME: - the only thing this IRQ does it tweak the starting MO link */ /* unfortunately, it does it too early for the given MOs! */ /* perhaps it is not actually hooked up on the real PCB... */ return; /* set a timer to turn the interrupt on at HBLANK of the 7th scanline */ /* and another to turn it off one scanline later */ width = video_screen_get_width(screen); vpos = video_screen_get_vpos(screen); period_on = video_screen_get_time_until_pos(screen, vpos + 7, width * 0.9); period_off = video_screen_get_time_until_pos(screen, vpos + 8, width * 0.9); timer_set(period_on, NULL, 0, irq_on); timer_set(period_off, NULL, 0, irq_off); } }
static TIMER_CALLBACK( periodic_callback ) { int scanline = param; cputag_set_input_line(machine, "maincpu", 0, ASSERT_LINE); if (scanline == 0) { UINT8 mask[256]; int i; memset(mask, 0, sizeof mask); mask[input_port_read(machine, "STICK0_X")] |= 0x01; mask[input_port_read(machine, "STICK0_Y")] |= 0x02; mask[input_port_read(machine, "PADDLE0")] |= 0x04; mask[input_port_read(machine, "STICK1_X")] |= 0x08; mask[input_port_read(machine, "STICK1_Y")] |= 0x10; mask[input_port_read(machine, "PADDLE1")] |= 0x20; for (i = 1; i < 256; i++) if (mask[i] != 0) timer_set(machine, video_screen_get_time_until_pos(machine->primary_screen, i, 0), NULL, mask[i], pot_interrupt); pot_state = 0; } scanline += 64; if (scanline >= 262) scanline = 0; timer_set(machine, video_screen_get_time_until_pos(machine->primary_screen, scanline, 0), NULL, scanline, periodic_callback); }
static TIMER_CALLBACK( flyball_quarter_callback ) { int scanline = param; int potsense[64], i; memset(potsense, 0, sizeof potsense); potsense[readinputport(1)] |= 1; potsense[readinputport(2)] |= 2; potsense[readinputport(3)] |= 4; potsense[readinputport(4)] |= 8; for (i = 0; i < 64; i++) { if (potsense[i] != 0) { timer_set(video_screen_get_time_until_pos(0, scanline + i, 0), NULL, potsense[i], flyball_joystick_callback); } } scanline += 0x40; scanline &= 0xff; timer_set(video_screen_get_time_until_pos(0, scanline, 0), NULL, scanline, flyball_quarter_callback); flyball_potsense = 0; flyball_potmask = 0; }
static TIMER_CALLBACK( destroyr_frame_callback ) { destroyr_potsense[0] = 0; destroyr_potsense[1] = 0; /* PCB supports two dials, but cab has only got one */ timer_set(machine, video_screen_get_time_until_pos(machine->primary_screen, input_port_read(machine, "PADDLE"), 0), NULL, 0, destroyr_dial_callback); timer_set(machine, video_screen_get_time_until_pos(machine->primary_screen, 0, 0), NULL, 0, destroyr_frame_callback); }
static TIMER_CALLBACK( vidc_vblank ) { archimedes_request_irq_a(machine, ARCHIMEDES_IRQA_VBL); // set up for next vbl timer_adjust_oneshot(vbl_timer, video_screen_get_time_until_pos(machine->primary_screen, vidc_regs[0xb4], 0), 0); }
static TIMER_CALLBACK( cursor_callback ) { if (lockon_main_inten) cputag_set_input_line_and_vector(machine, "maincpu", 0, HOLD_LINE, 0xff); timer_adjust_oneshot(cursor_timer, video_screen_get_time_until_pos(machine->primary_screen, CURSOR_YPOS, CURSOR_XPOS), 0); }
INLINE void schedule_next_irq(running_machine *machine, int curscanline) { /* IRQ is clocked by /32V, so every 64 scanlines */ curscanline = (curscanline + 64) & 255; /* next one at the start of this scanline */ timer_adjust_oneshot(irq_timer, video_screen_get_time_until_pos(machine->primary_screen, curscanline, 0), curscanline); }
static TIMER_CALLBACK( scanline_callback ) { if (param==interrupt_scanline) { if (out&0x2000) cpunum_set_input_line(0, 1, ASSERT_LINE); timer_adjust(scanline_timer, video_screen_get_time_until_pos(0, param+1, 0), param+1, attotime_zero); interrupt_line_active = 1; } else { if (interrupt_line_active) cpunum_set_input_line(0, 1, CLEAR_LINE); timer_adjust(scanline_timer, video_screen_get_time_until_pos(0, interrupt_scanline, 0), interrupt_scanline, attotime_zero); interrupt_line_active = 0; } }
INLINE void schedule_next_irq(int curscanline) { /* IRQ is clocked by /32V, so every 64 scanlines */ curscanline = (curscanline + 64) & 255; /* next one at the start of this scanline */ mame_timer_adjust(irq_timer, video_screen_get_time_until_pos(0, curscanline, 0), curscanline, time_zero); }
static MACHINE_RESET( videopin ) { timer_set(video_screen_get_time_until_pos(0, 32, 0), NULL, 32, interrupt_callback); /* both output latches are cleared on reset */ videopin_out1_w(0, 0); videopin_out2_w(0, 0); }
static WRITE16_HANDLER( fuuki16_vregs_w ) { UINT16 old_data = fuuki16_vregs[offset]; UINT16 new_data = COMBINE_DATA(&fuuki16_vregs[offset]); if ((offset == 0x1c/2) && old_data != new_data) { timer_adjust(raster_interrupt_timer, video_screen_get_time_until_pos(0, new_data, Machine->screen[0].visarea.max_x + 1), 0, video_screen_get_frame_period(0)); } }
static TIMER_CALLBACK( capbowl_update ) { int scanline = param; video_screen_update_partial(machine->primary_screen, scanline - 1); scanline += 32; if (scanline > 240) scanline = 32; timer_set(machine, video_screen_get_time_until_pos(machine->primary_screen, scanline, 0), NULL, scanline, capbowl_update); }
static MACHINE_RESET( pkscramble) { out = 0; interrupt_line_active=0; scanline_timer = timer_alloc(scanline_callback, NULL); timer_adjust(scanline_timer, video_screen_get_time_until_pos(0, interrupt_scanline, 0), interrupt_scanline, attotime_zero); state_save_register_global(out); state_save_register_global(interrupt_line_active); }
INLINE void schedule_next_irq(int curscanline) { /* scan for a rising edge on the IRQCK signal */ for (curscanline++; ; curscanline = (curscanline + 1) & 0xff) if ((syncprom[(curscanline - 1) & 0xff] & 8) == 0 && (syncprom[curscanline] & 8) != 0) break; /* next one at the start of this scanline */ mame_timer_adjust(irq_timer, video_screen_get_time_until_pos(0, curscanline, 0), curscanline, time_zero); }
static MACHINE_RESET( atetris ) { /* reset the slapstic */ slapstic_reset(); current_bank = slapstic_bank() & 1; reset_bank(); /* start interrupts going (32V clocked by 16V) */ timer_adjust_oneshot(interrupt_timer, video_screen_get_time_until_pos(machine->primary_screen, 48, 0), 48); }
static MACHINE_RESET( videopin ) { const device_config *discrete = devtag_get_device(machine, "discrete"); timer_set(machine, video_screen_get_time_until_pos(machine->primary_screen, 32, 0), NULL, 32, interrupt_callback); /* both output latches are cleared on reset */ videopin_out1_w(discrete, 0, 0); videopin_out2_w(discrete, 0, 0); }
static TIMER_CALLBACK( display_position_vblank_callback ) { if (display_position_interrupt_control & IRQ2CTRL_AUTOLOAD_VBLANK) { if (LOG_VIDEO_SYSTEM) logerror("AUTOLOAD_VBLANK "); adjust_display_position_interrupt_timer(machine); } /* set timer for next screen */ timer_adjust_oneshot(display_position_vblank_timer, video_screen_get_time_until_pos(machine->primary_screen, NEOGEO_VBSTART, NEOGEO_VBLANK_RELOAD_HPOS), 0); }
static TIMER_CALLBACK( update_callback ) { int scanline = param; /* update the previous chunk of scanlines */ starfire_video_update(scanline, SCANLINE_UPDATE_CHUNK); scanline += SCANLINE_UPDATE_CHUNK; if (scanline >= machine->screen[0].height) scanline = 32; timer_set(video_screen_get_time_until_pos(0, scanline + SCANLINE_UPDATE_CHUNK - 1, 0), NULL, scanline, update_callback); }
static WRITE16_HANDLER( fuuki16_vregs_w ) { fuuki16_state *state = (fuuki16_state *)space->machine->driver_data; UINT16 old_data = state->vregs[offset]; UINT16 new_data = COMBINE_DATA(&state->vregs[offset]); if ((offset == 0x1c/2) && old_data != new_data) { const rectangle *visarea = video_screen_get_visible_area(space->machine->primary_screen); attotime period = video_screen_get_frame_period(space->machine->primary_screen); timer_adjust_periodic(state->raster_interrupt_timer, video_screen_get_time_until_pos(space->machine->primary_screen, new_data, visarea->max_x + 1), 0, period); } }
static MACHINE_RESET( magmax ) { timer_adjust_oneshot(interrupt_timer, video_screen_get_time_until_pos(machine->primary_screen, 64, 0), 64); #if 0 { int i; for (i=0; i<9; i++) logerror("SOUND Chan#%i name=%s\n", i, mixer_get_name(i) ); } #endif }
static MACHINE_RESET( magmax ) { timer_adjust(interrupt_timer, video_screen_get_time_until_pos(0, 64, 0), 64, attotime_zero); #if 0 { int i; for (i=0; i<9; i++) logerror("SOUND Chan#%i name=%s\n", i, mixer_get_name(i) ); } #endif }
static MACHINE_RESET( flyball ) { int i; /* address bits 0 through 8 are inverted */ UINT8* ROM = memory_region(REGION_CPU1) + 0x2000; for (i = 0; i < 0x1000; i++) rombase[i] = ROM[i ^ 0x1ff]; timer_set(video_screen_get_time_until_pos(0, 0, 0), NULL, 0, flyball_quarter_callback); }
INLINE void schedule_next_irq(int curv) { /* IRQ = /32V, clocked by /16V ^ flip */ /* When not flipped, clocks on 0, 64, 128, 192 */ /* When flipped, clocks on 16, 80, 144, 208 */ if (flipscreen) curv = ((curv - 32) & 0xff) | 0x10; else curv = ((curv + 32) & 0xff) & ~0x10; /* next one at the start of this scanline */ mame_timer_adjust(irq_timer, video_screen_get_time_until_pos(0, v_to_scanline(curv), 0), curv, time_zero); }
static TIMER_CALLBACK( periodic_callback ) { int scanline = param; cputag_set_input_line(machine, "maincpu", INPUT_LINE_NMI, PULSE_LINE); scanline += 64; if (scanline >= 262) scanline = 0; timer_set(machine, video_screen_get_time_until_pos(machine->primary_screen, scanline, 0), NULL, scanline, periodic_callback); }
static TIMER_CALLBACK( interrupt_gen ) { int scanline = param; /* assert/deassert the interrupt */ cputag_set_input_line(machine, "maincpu", 0, (scanline & 32) ? ASSERT_LINE : CLEAR_LINE); /* set the next timer */ scanline += 32; if (scanline >= 256) scanline -= 256; timer_adjust_oneshot(interrupt_timer, video_screen_get_time_until_pos(machine->primary_screen, scanline, 0), scanline); }
static void update_timer(crtc6845_state *chip) { INT16 next_y; UINT16 next_x; attotime duration; if (chip->has_valid_parameters && (chip->display_enable_changed_timer != 0)) { if (is_display_enabled(chip)) { /* we are in a display region, get the location of the next blanking start */ /* normally, it's at end the current raster line */ next_y = video_screen_get_vpos(chip->intf->scrnum); next_x = chip->last_max_x + 1; /* but if visible width = horiz_total, then we need to go to the beginning of VBLANK */ if (next_x == chip->last_horiz_total) { next_y = chip->last_max_y + 1; next_x = 0; /* abnormal case, no vertical blanking, either */ if (next_y == chip->last_vert_total) next_y = -1; } } else { /* we are in a blanking region, get the location of the next display start */ next_x = 0; next_y = (video_screen_get_vpos(chip->intf->scrnum) + 1) % chip->last_vert_total; /* if we would now fall in the vertical blanking, we need to go to the top of the screen */ if (next_y > chip->last_max_y) next_y = 0; } if (next_y != -1) duration = video_screen_get_time_until_pos(chip->intf->scrnum, next_y, next_x); else duration = attotime_never; timer_adjust(chip->display_enable_changed_timer, duration, 0, attotime_never); } }
static TIMER_CALLBACK( scanline_callback ) { int scanline = param; /* bit 0 goes hi whenever line V6 from video part goes lo->hi */ /* that is when scanline is 64 and 192 accordingly */ if (LS74_clr != 0) LS74_q = 1; scanline += 128; scanline &= 255; timer_adjust(interrupt_timer, video_screen_get_time_until_pos(0, scanline, 0), scanline, attotime_zero); }
static TIMER_CALLBACK( interrupt_timer ) { /* 128V, 64V and 32V go to D */ TTL7474_d_w(0, (param & 0xe0) != 0xe0); /* 16V clocks the flip-flop */ TTL7474_clock_w(0, param & 0x10); param = (param + 0x10) & 0xff; timer_adjust(int_timer, video_screen_get_time_until_pos(0, param, 0), param, attotime_zero); TTL7474_update(0); }
static TIMER_CALLBACK( interrupt_callback ) { /* assume Centipede-style interrupt timing */ int scanline = param; cputag_set_input_line(machine, "maincpu", 0, (scanline & 32) ? ASSERT_LINE : CLEAR_LINE); scanline += 32; if (scanline >= 263) scanline = 16; timer_adjust_oneshot(interrupt_timer, video_screen_get_time_until_pos(machine->primary_screen, scanline, 0), scanline); }
static MACHINE_RESET( flyball ) { int i; /* address bits 0 through 8 are inverted */ UINT8* ROM = memory_region(machine, "maincpu") + 0x2000; for (i = 0; i < 0x1000; i++) rombase[i] = ROM[i ^ 0x1ff]; device_reset(cputag_get_cpu(machine, "maincpu")); timer_set(machine, video_screen_get_time_until_pos(machine->primary_screen, 0, 0), NULL, 0, flyball_quarter_callback); }