void video_screen_set_visarea(int scrnum, int min_x, int max_x, int min_y, int max_y) { screen_state *state = &Machine->screen[scrnum]; rectangle visarea; visarea.min_x = min_x; visarea.max_x = max_x; visarea.min_y = min_y; visarea.max_y = max_y; video_screen_configure(scrnum, state->width, state->height, &visarea, state->refresh); }
static void TMS9928A_start (running_machine *machine, const TMS9928a_interface *intf) { assert_always(((intf->vram == 0x1000) || (intf->vram == 0x2000) || (intf->vram == 0x4000)), "4, 8 or 16 kB vram please"); tms.model = intf->model; tms.top_border = TMS_50HZ ? TOP_BORDER_50HZ : TOP_BORDER_60HZ; tms.bottom_border = TMS_50HZ ? BOTTOM_BORDER_50HZ : BOTTOM_BORDER_60HZ; tms.INTCallback = intf->int_callback; /* determine the visible area */ tms.visarea.min_x = LEFT_BORDER - MIN(intf->borderx, LEFT_BORDER); tms.visarea.max_x = LEFT_BORDER + 32*8 - 1 + MIN(intf->borderx, RIGHT_BORDER); tms.visarea.min_y = tms.top_border - MIN(intf->bordery, tms.top_border); tms.visarea.max_y = tms.top_border + 24*8 - 1 + MIN(intf->bordery, tms.bottom_border); /* configure the screen if we weren't overridden */ if (video_screen_get_width(machine->primary_screen) == LEFT_BORDER+32*8+RIGHT_BORDER && video_screen_get_height(machine->primary_screen) == TOP_BORDER_60HZ+24*8+BOTTOM_BORDER_60HZ) video_screen_configure(machine->primary_screen, LEFT_BORDER + 32*8 + RIGHT_BORDER, tms.top_border + 24*8 + tms.bottom_border, &tms.visarea, video_screen_get_frame_period(machine->primary_screen).attoseconds); /* Video RAM */ tms.vramsize = intf->vram; tms.vMem = auto_alloc_array_clear(machine, UINT8, intf->vram); /* Sprite back buffer */ tms.dBackMem = auto_alloc_array(machine, UINT8, IMAGE_SIZE); /* back bitmap */ tms.tmpbmp = auto_bitmap_alloc (machine, 256, 192, video_screen_get_format(machine->primary_screen)); TMS9928A_reset (); tms.LimitSprites = 1; state_save_register_item(machine, "tms9928a", NULL, 0, tms.Regs[0]); state_save_register_item(machine, "tms9928a", NULL, 0, tms.Regs[1]); state_save_register_item(machine, "tms9928a", NULL, 0, tms.Regs[2]); state_save_register_item(machine, "tms9928a", NULL, 0, tms.Regs[3]); state_save_register_item(machine, "tms9928a", NULL, 0, tms.Regs[4]); state_save_register_item(machine, "tms9928a", NULL, 0, tms.Regs[5]); state_save_register_item(machine, "tms9928a", NULL, 0, tms.Regs[6]); state_save_register_item(machine, "tms9928a", NULL, 0, tms.Regs[7]); state_save_register_item(machine, "tms9928a", NULL, 0, tms.StatusReg); state_save_register_item(machine, "tms9928a", NULL, 0, tms.ReadAhead); state_save_register_item(machine, "tms9928a", NULL, 0, tms.FirstByte); state_save_register_item(machine, "tms9928a", NULL, 0, tms.latch); state_save_register_item(machine, "tms9928a", NULL, 0, tms.Addr); state_save_register_item(machine, "tms9928a", NULL, 0, tms.INT); state_save_register_item_pointer(machine, "tms9928a", NULL, 0, tms.vMem, intf->vram); }
static void configure_screen(crtc6845_state *chip, int postload) { if (chip->intf) { /* compute the screen sizes */ UINT16 horiz_total = (chip->horiz_total + 1) * chip->intf->hpixels_per_column; UINT16 vert_total = (chip->vert_total + 1) * (chip->max_ras_addr + 1) + chip->vert_total_adj; /* determine the visible area, avoid division by 0 */ UINT16 max_x = chip->horiz_disp * chip->intf->hpixels_per_column - 1; UINT16 max_y = chip->vert_disp * (chip->max_ras_addr + 1) - 1; /* update only if screen parameters changed, unless we are coming here after loading the saved state */ if (postload || (horiz_total != chip->last_horiz_total) || (vert_total != chip->last_vert_total) || (max_x != chip->last_max_x) || (max_y != chip->last_max_y)) { /* update the screen only if we have valid data */ if ((chip->horiz_total > 0) && (max_x < horiz_total) && (chip->vert_total > 0) && (max_y < vert_total)) { rectangle visarea; attoseconds_t refresh = HZ_TO_ATTOSECONDS(chip->intf->clock) * (chip->horiz_total + 1) * vert_total; visarea.min_x = 0; visarea.min_y = 0; visarea.max_x = max_x; visarea.max_y = max_y; if (LOG) logerror("CRTC6845 config screen: HTOTAL: %x VTOTAL: %x MAX_X: %x MAX_Y: %x FPS: %f\n", horiz_total, vert_total, max_x, max_y, 1 / ATTOSECONDS_TO_DOUBLE(refresh)); video_screen_configure(chip->intf->scrnum, horiz_total, vert_total, &visarea, refresh); chip->has_valid_parameters = TRUE; } else chip->has_valid_parameters = FALSE; chip->last_horiz_total = horiz_total; chip->last_vert_total = vert_total; chip->last_max_x = max_x; chip->last_max_y = max_y; update_timer(chip); } } }
static MACHINE_START( ccastles ) { rectangle visarea; /* initialize globals */ syncprom = memory_region(REGION_PROMS) + 0x000; /* find the start of VBLANK in the SYNC PROM */ for (ccastles_vblank_start = 0; ccastles_vblank_start < 256; ccastles_vblank_start++) if ((syncprom[(ccastles_vblank_start - 1) & 0xff] & 1) == 0 && (syncprom[ccastles_vblank_start] & 1) != 0) break; if (ccastles_vblank_start == 0) ccastles_vblank_start = 256; /* find the end of VBLANK in the SYNC PROM */ for (ccastles_vblank_end = 0; ccastles_vblank_end < 256; ccastles_vblank_end++) if ((syncprom[(ccastles_vblank_end - 1) & 0xff] & 1) != 0 && (syncprom[ccastles_vblank_end] & 1) == 0) break; /* can't handle the wrapping case */ assert(ccastles_vblank_end < ccastles_vblank_start); /* reconfigure the visible area to match */ visarea.min_x = 0; visarea.max_x = 255; visarea.min_y = ccastles_vblank_end; visarea.max_y = ccastles_vblank_start - 1; video_screen_configure(0, 320, 256, &visarea, (float)PIXEL_CLOCK / (float)VTOTAL / (float)HTOTAL); /* configure the ROM banking */ memory_configure_bank(1, 0, 2, memory_region(REGION_CPU1) + 0xa000, 0x6000); /* create a timer for IRQs and set up the first callback */ irq_timer = timer_alloc(clock_irq); irq_state = 0; schedule_next_irq(0); /* allocate backing memory for the NVRAM */ generic_nvram = auto_malloc(generic_nvram_size); /* setup for save states */ state_save_register_global(irq_state); state_save_register_global_array(nvram_store); state_save_register_global_pointer(generic_nvram, generic_nvram_size); return 0; }
static void recompute_parameters(tms9927_state *tms, int postload) { UINT16 offset_hpix, offset_vpix; attoseconds_t refresh; rectangle visarea; if (tms->intf == NULL || tms->reset) return; /* compute the screen sizes */ tms->total_hpix = HCOUNT(tms) * tms->hpixels_per_column; tms->total_vpix = SCAN_LINES_PER_FRAME(tms); /* determine the visible area, avoid division by 0 */ tms->visible_hpix = CHARS_PER_DATA_ROW(tms) * tms->hpixels_per_column; tms->visible_vpix = (LAST_DISP_DATA_ROW(tms) + 1) * SCANS_PER_DATA_ROW(tms); /* determine the horizontal/vertical offsets */ offset_hpix = HSYNC_DELAY(tms) * tms->hpixels_per_column; offset_vpix = VERTICAL_DATA_START(tms); mame_printf_debug("TMS9937: Total = %dx%d, Visible = %dx%d, Offset=%dx%d, Skew=%d\n", tms->total_hpix, tms->total_vpix, tms->visible_hpix, tms->visible_vpix, offset_hpix, offset_vpix, SKEW_BITS(tms)); /* see if it all makes sense */ tms->valid_config = TRUE; if (tms->visible_hpix > tms->total_hpix || tms->visible_vpix > tms->total_vpix) { tms->valid_config = FALSE; logerror("tms9927: invalid visible size (%dx%d) versus total size (%dx%d)\n", tms->visible_hpix, tms->visible_vpix, tms->total_hpix, tms->total_vpix); } /* update */ if (!tms->valid_config) return; /* create a visible area */ /* fix me: how do the offsets fit in here? */ visarea.min_x = 0; visarea.max_x = tms->visible_hpix - 1; visarea.min_y = 0; visarea.max_y = tms->visible_vpix - 1; refresh = HZ_TO_ATTOSECONDS(tms->clock) * tms->total_hpix * tms->total_vpix; video_screen_configure(tms->screen, tms->total_hpix, tms->total_vpix, &visarea, refresh); }
static MACHINE_START( cloud9 ) { rectangle visarea; /* initialize globals */ syncprom = memory_region(REGION_PROMS) + 0x000; /* find the start of VBLANK in the SYNC PROM */ for (cloud9_vblank_start = 0; cloud9_vblank_start < 256; cloud9_vblank_start++) if ((syncprom[(cloud9_vblank_start - 1) & 0xff] & 2) != 0 && (syncprom[cloud9_vblank_start] & 2) == 0) break; if (cloud9_vblank_start == 0) cloud9_vblank_start = 256; /* find the end of VBLANK in the SYNC PROM */ for (cloud9_vblank_end = 0; cloud9_vblank_end < 256; cloud9_vblank_end++) if ((syncprom[(cloud9_vblank_end - 1) & 0xff] & 2) == 0 && (syncprom[cloud9_vblank_end] & 2) != 0) break; /* can't handle the wrapping case */ assert(cloud9_vblank_end < cloud9_vblank_start); /* reconfigure the visible area to match */ visarea.min_x = 0; visarea.max_x = 255; visarea.min_y = cloud9_vblank_end + 1; visarea.max_y = cloud9_vblank_start; video_screen_configure(machine->primary_screen, 320, 256, &visarea, HZ_TO_ATTOSECONDS(PIXEL_CLOCK) * VTOTAL * HTOTAL); /* create a timer for IRQs and set up the first callback */ irq_timer = timer_alloc(clock_irq, NULL); irq_state = 0; schedule_next_irq(machine, 0-64); /* allocate backing memory for the NVRAM */ generic_nvram = auto_malloc(generic_nvram_size); /* setup for save states */ state_save_register_global(irq_state); state_save_register_global_pointer(generic_nvram, generic_nvram_size); }
int video_init(running_machine *machine) { int scrnum; add_exit_callback(machine, video_exit); /* reset globals */ memset(scrinfo, 0, sizeof(scrinfo)); /* configure all of the screens */ for (scrnum = 0; scrnum < MAX_SCREENS; scrnum++) if (machine->drv->screen[scrnum].tag != NULL) { internal_screen_info *info = &scrinfo[scrnum]; screen_state *state = &machine->screen[scrnum]; /* configure the screen with the default parameters */ video_screen_configure(scrnum, state->width, state->height, &state->visarea, state->refresh); /* reset VBLANK timing */ info->vblank_time = sub_mame_times(time_zero, double_to_mame_time(Machine->screen[0].vblank)); /* register for save states */ state_save_register_item("video", scrnum, info->vblank_time.seconds); state_save_register_item("video", scrnum, info->vblank_time.subseconds); } /* create spriteram buffers if necessary */ if (machine->drv->video_attributes & VIDEO_BUFFERS_SPRITERAM) init_buffered_spriteram(); /* convert the gfx ROMs into character sets. This is done BEFORE calling the driver's */ /* palette_init() routine because it might need to check the machine->gfx[] data */ if (machine->drv->gfxdecodeinfo != NULL) allocate_graphics(machine->drv->gfxdecodeinfo); /* configure the palette */ palette_config(machine); /* actually decode the graphics */ if (machine->drv->gfxdecodeinfo != NULL) decode_graphics(machine->drv->gfxdecodeinfo); /* reset performance data */ last_fps_time = osd_ticks(); rendered_frames_since_last_fps = frames_since_last_fps = 0; performance.game_speed_percent = 100; performance.frames_per_second = machine->screen[0].refresh; performance.vector_updates_last_second = 0; /* reset video statics and get out of here */ pdrawgfx_shadow_lowpri = 0; leds_status = 0; /* initialize tilemaps */ if (tilemap_init(machine) != 0) fatalerror("tilemap_init failed"); /* create a render target for snapshots */ if (Machine->drv->screen[0].tag != NULL) { snap_bitmap = NULL; snap_target = render_target_alloc(layout_snap, RENDER_CREATE_SINGLE_FILE | RENDER_CREATE_HIDDEN); assert(snap_target != NULL); if (snap_target == NULL) return 1; render_target_set_layer_config(snap_target, 0); } /* create crosshairs */ crosshair_init(); return 0; }
static int TMS9928A_start (const TMS9928a_interface *intf) { /* 4, 8 or 16 kB vram please */ if (! ((intf->vram == 0x1000) || (intf->vram == 0x2000) || (intf->vram == 0x4000)) ) return 1; tms.model = intf->model; tms.top_border = TMS_50HZ ? TOP_BORDER_50HZ : TOP_BORDER_60HZ; tms.bottom_border = TMS_50HZ ? BOTTOM_BORDER_50HZ : BOTTOM_BORDER_60HZ; tms.INTCallback = intf->int_callback; /* determine the visible area */ tms.visarea.min_x = LEFT_BORDER - MIN(intf->borderx, LEFT_BORDER); tms.visarea.max_x = LEFT_BORDER + 32*8 - 1 + MIN(intf->borderx, RIGHT_BORDER); tms.visarea.min_y = tms.top_border - MIN(intf->bordery, tms.top_border); tms.visarea.max_y = tms.top_border + 24*8 - 1 + MIN(intf->bordery, tms.bottom_border); /* configure the screen if we weren't overridden */ if (Machine->screen[0].width == LEFT_BORDER+32*8+RIGHT_BORDER && Machine->screen[0].height == TOP_BORDER_60HZ+24*8+BOTTOM_BORDER_60HZ) video_screen_configure(0, LEFT_BORDER + 32*8 + RIGHT_BORDER, tms.top_border + 24*8 + tms.bottom_border, &tms.visarea, Machine->screen[0].refresh); /* Video RAM */ tms.vramsize = intf->vram; tms.vMem = (UINT8*) auto_malloc (intf->vram); memset (tms.vMem, 0, intf->vram); /* Sprite back buffer */ tms.dBackMem = (UINT8*)auto_malloc (IMAGE_SIZE); /* dirty buffers */ tms.DirtyName = (char*)auto_malloc (MAX_DIRTY_NAME); tms.DirtyPattern = (char*)auto_malloc (MAX_DIRTY_PATTERN); tms.DirtyColour = (char*)auto_malloc (MAX_DIRTY_COLOUR); /* back bitmap */ tms.tmpbmp = auto_bitmap_alloc (256, 192); TMS9928A_reset (); tms.LimitSprites = 1; state_save_register_item("tms9928a", 0, tms.Regs[0]); state_save_register_item("tms9928a", 0, tms.Regs[1]); state_save_register_item("tms9928a", 0, tms.Regs[2]); state_save_register_item("tms9928a", 0, tms.Regs[3]); state_save_register_item("tms9928a", 0, tms.Regs[4]); state_save_register_item("tms9928a", 0, tms.Regs[5]); state_save_register_item("tms9928a", 0, tms.Regs[6]); state_save_register_item("tms9928a", 0, tms.Regs[7]); state_save_register_item("tms9928a", 0, tms.StatusReg); state_save_register_item("tms9928a", 0, tms.ReadAhead); state_save_register_item("tms9928a", 0, tms.FirstByte); state_save_register_item("tms9928a", 0, tms.latch); state_save_register_item("tms9928a", 0, tms.Addr); state_save_register_item("tms9928a", 0, tms.INT); state_save_register_item_pointer("tms9928a", 0, tms.vMem, intf->vram); return 0; }
static void recompute_parameters(mc6845_t *mc6845, int postload) { if (mc6845->intf != NULL) { UINT16 hsync_on_pos, hsync_off_pos, vsync_on_pos, vsync_off_pos; /* compute the screen sizes */ UINT16 horiz_pix_total = (mc6845->horiz_char_total + 1) * mc6845->hpixels_per_column; UINT16 vert_pix_total = (mc6845->vert_char_total + 1) * (mc6845->max_ras_addr + 1) + mc6845->vert_total_adj; /* determine the visible area, avoid division by 0 */ UINT16 max_visible_x = mc6845->horiz_disp * mc6845->hpixels_per_column - 1; UINT16 max_visible_y = mc6845->vert_disp * (mc6845->max_ras_addr + 1) - 1; /* determine the syncing positions */ UINT8 horiz_sync_char_width = mc6845->sync_width & 0x0f; UINT8 vert_sync_pix_width = supports_vert_sync_width[mc6845->device_type] ? (mc6845->sync_width >> 4) & 0x0f : 0x10; if (horiz_sync_char_width == 0) horiz_sync_char_width = 0x10; if (vert_sync_pix_width == 0) vert_sync_pix_width = 0x10; hsync_on_pos = mc6845->horiz_sync_pos * mc6845->hpixels_per_column; hsync_off_pos = hsync_on_pos + (horiz_sync_char_width * mc6845->hpixels_per_column); vsync_on_pos = mc6845->vert_sync_pos * (mc6845->max_ras_addr + 1); vsync_off_pos = vsync_on_pos + vert_sync_pix_width; /* the Commodore PET computers program a horizontal synch pulse that extends past the scanline width. I assume that the real device will clamp it */ if (hsync_off_pos > horiz_pix_total) hsync_off_pos = horiz_pix_total; if (vsync_off_pos > vert_pix_total) vsync_off_pos = vert_pix_total; /* update only if screen parameters changed, unless we are coming here after loading the saved state */ if (postload || (horiz_pix_total != mc6845->horiz_pix_total) || (vert_pix_total != mc6845->vert_pix_total) || (max_visible_x != mc6845->max_visible_x) || (max_visible_y != mc6845->max_visible_y) || (hsync_on_pos != mc6845->hsync_on_pos) || (vsync_on_pos != mc6845->vsync_on_pos) || (hsync_off_pos != mc6845->hsync_off_pos) || (vsync_off_pos != mc6845->vsync_off_pos)) { /* update the screen if we have valid data */ if ((horiz_pix_total > 0) && (max_visible_x < horiz_pix_total) && (vert_pix_total > 0) && (max_visible_y < vert_pix_total) && (hsync_on_pos <= horiz_pix_total) && (vsync_on_pos <= vert_pix_total) && (hsync_on_pos != hsync_off_pos)) { rectangle visarea; attoseconds_t refresh = HZ_TO_ATTOSECONDS(mc6845->clock) * (mc6845->horiz_char_total + 1) * vert_pix_total; visarea.min_x = 0; visarea.min_y = 0; visarea.max_x = max_visible_x; visarea.max_y = max_visible_y; if (LOG) logerror("M6845 config screen: HTOTAL: 0x%x VTOTAL: 0x%x MAX_X: 0x%x MAX_Y: 0x%x HSYNC: 0x%x-0x%x VSYNC: 0x%x-0x%x Freq: %ffps\n", horiz_pix_total, vert_pix_total, max_visible_x, max_visible_y, hsync_on_pos, hsync_off_pos - 1, vsync_on_pos, vsync_off_pos - 1, 1 / ATTOSECONDS_TO_DOUBLE(refresh)); video_screen_configure(mc6845->screen, horiz_pix_total, vert_pix_total, &visarea, refresh); mc6845->has_valid_parameters = TRUE; } else mc6845->has_valid_parameters = FALSE; mc6845->horiz_pix_total = horiz_pix_total; mc6845->vert_pix_total = vert_pix_total; mc6845->max_visible_x = max_visible_x; mc6845->max_visible_y = max_visible_y; mc6845->hsync_on_pos = hsync_on_pos; mc6845->hsync_off_pos = hsync_off_pos; mc6845->vsync_on_pos = vsync_on_pos; mc6845->vsync_off_pos = vsync_off_pos; update_de_changed_timer(mc6845); update_hsync_changed_timers(mc6845); update_vsync_changed_timers(mc6845); } }