Пример #1
0
void k053252_device::res_change()
{
	if(m_hc && m_vc &&
		m_hbp && m_hfp &&
		m_vbp && m_vfp &&
		m_hsw && m_vsw) //safety checks
	{
		rectangle visarea;
		//(HC+1) - HFP - HBP - 8*(HSW+1)
		//VC - VFP - VBP - (VSW+1)
		attoseconds_t refresh = HZ_TO_ATTOSECONDS(clock()) * (m_hc) * m_vc;

		visarea.min_x = m_offsx;
		visarea.min_y = m_offsy;
		visarea.max_x = m_offsx + m_hc - m_hfp - m_hbp - 8*(m_hsw) - 1;
		visarea.max_y = m_offsy + m_vc - m_vfp - m_vbp - (m_vsw) - 1;

		m_screen->configure(m_hc, m_vc, visarea, refresh);

		if (m_slave_screen.found())
			m_slave_screen->configure(m_hc, m_vc, visarea, refresh);

#if 0
		attoseconds_t hsync = HZ_TO_ATTOSECONDS(clock()) * (m_hc);
		printf("H %d HFP %d HSW %d HBP %d\n",m_hc,m_hfp,m_hsw*8,m_hbp);
		printf("V %d VFP %d VSW %d VBP %d\n",m_vc,m_vfp,m_vsw,m_vbp);
		// L stands for Legacy ...
		printf("L %d %d\n",m_offsx,m_offsy);
		printf("Screen params: Clock: %u V-Sync %.2f H-Sync %.f\n",clock(),ATTOSECONDS_TO_HZ(refresh),ATTOSECONDS_TO_HZ(hsync));
		printf("visible screen area: %d x %d\n\n",(visarea.max_x - visarea.min_x) + 1,(visarea.max_y - visarea.min_y) + 1);
#endif
	}
}
Пример #2
0
void gp32_state::s3c240x_lcd_configure()
{
	screen_device *screen = machine().first_screen();
	UINT32 vspw, vbpd, lineval, vfpd, hspw, hbpd, hfpd, hozval, clkval, hclk;
	double framerate, vclk;
	rectangle visarea;
	vspw = BITS( m_s3c240x_lcd_regs[1], 5, 0);
	vbpd = BITS( m_s3c240x_lcd_regs[1], 31, 24);
	lineval = BITS( m_s3c240x_lcd_regs[1], 23, 14);
	vfpd = BITS( m_s3c240x_lcd_regs[1], 13, 6);
	hspw = BITS( m_s3c240x_lcd_regs[3], 7, 0);
	hbpd = BITS( m_s3c240x_lcd_regs[2], 25, 19);
	hfpd = BITS( m_s3c240x_lcd_regs[2], 7, 0);
	hozval = BITS( m_s3c240x_lcd_regs[2], 18, 8);
	clkval = BITS( m_s3c240x_lcd_regs[0], 17, 8);
	hclk = s3c240x_get_hclk(MPLLCON);
	verboselog( machine(), 3, "LCD - vspw %d vbpd %d lineval %d vfpd %d hspw %d hbpd %d hfpd %d hozval %d clkval %d hclk %d\n", vspw, vbpd, lineval, vfpd, hspw, hbpd, hfpd, hozval, clkval, hclk);
	vclk = (double)(hclk / ((clkval + 1) * 2));
	verboselog( machine(), 3, "LCD - vclk %f\n", vclk);
	framerate = vclk / (((vspw + 1) + (vbpd + 1) + (lineval + 1) + (vfpd + 1)) * ((hspw + 1) + (hbpd + 1) + (hfpd + 1) + (hozval + 1)));
	verboselog( machine(), 3, "LCD - framerate %f\n", framerate);
	visarea.set(0, hozval, 0, lineval);
	verboselog( machine(), 3, "LCD - visarea min_x %d min_y %d max_x %d max_y %d\n", visarea.min_x, visarea.min_y, visarea.max_x, visarea.max_y);
	screen->configure(hozval + 1, lineval + 1, visarea, HZ_TO_ATTOSECONDS( framerate));
}
Пример #3
0
void towns_state::towns_crtc_refresh_mode()
{
	unsigned int width,height;

	rectangle scr(0, m_video.towns_crtc_reg[4], 0, m_video.towns_crtc_reg[8] / 2);

	// layer 0
	width = m_video.towns_crtc_reg[10] - m_video.towns_crtc_reg[9];
	height = (m_video.towns_crtc_reg[14] - m_video.towns_crtc_reg[13]) / 2;
	m_video.towns_crtc_layerscr[0].min_x = scr.xcenter() - (width / 2);
	m_video.towns_crtc_layerscr[0].min_y = scr.ycenter() - (height / 2);
	m_video.towns_crtc_layerscr[0].max_x = scr.xcenter() + (width / 2);
	m_video.towns_crtc_layerscr[0].max_y = scr.ycenter() + (height / 2);

	// layer 1
	width = m_video.towns_crtc_reg[12] - m_video.towns_crtc_reg[11];
	height = (m_video.towns_crtc_reg[16] - m_video.towns_crtc_reg[15]) / 2;
	m_video.towns_crtc_layerscr[1].min_x = scr.xcenter() - (width / 2);
	m_video.towns_crtc_layerscr[1].min_y = scr.ycenter() - (height / 2);
	m_video.towns_crtc_layerscr[1].max_x = scr.xcenter() + (width / 2);
	m_video.towns_crtc_layerscr[1].max_y = scr.ycenter() + (height / 2);

	// sanity checks
	if(scr.max_x == 0 || scr.max_y == 0)
		return;
	if(scr.max_x <= scr.min_x || scr.max_y <= scr.min_y)
		return;

	machine().first_screen()->configure(scr.max_x+1,scr.max_y+1,scr,HZ_TO_ATTOSECONDS(60));
}
Пример #4
0
void device_execute_interface::interface_clock_changed()
{
	// a clock of zero disables the device
	if (device().clock() == 0)
	{
		suspend(SUSPEND_REASON_CLOCK, true);
		return;
	}

	// if we were suspended because we had no clock, enable us now
	if (suspended(SUSPEND_REASON_CLOCK))
		resume(SUSPEND_REASON_CLOCK);

	// recompute cps and spc
	m_cycles_per_second = clocks_to_cycles(device().clock());
	m_attoseconds_per_cycle = HZ_TO_ATTOSECONDS(m_cycles_per_second);

	// update the device's divisor
	INT64 attos = m_attoseconds_per_cycle;
	m_divshift = 0;
	while (attos >= (1UL << 31))
	{
		m_divshift++;
		attos >>= 1;
	}
	m_divisor = attos;

	// re-compute the perfect interleave factor
	m_scheduler->compute_perfect_interleave();
}
Пример #5
0
void cloud9_state::machine_start()
{
	rectangle visarea;

	/* initialize globals */
	m_syncprom = memregion("proms")->base() + 0x000;

	/* find the start of VBLANK in the SYNC PROM */
	for (m_vblank_start = 0; m_vblank_start < 256; m_vblank_start++)
		if ((m_syncprom[(m_vblank_start - 1) & 0xff] & 2) != 0 && (m_syncprom[m_vblank_start] & 2) == 0)
			break;
	if (m_vblank_start == 0)
		m_vblank_start = 256;

	/* find the end of VBLANK in the SYNC PROM */
	for (m_vblank_end = 0; m_vblank_end < 256; m_vblank_end++)
		if ((m_syncprom[(m_vblank_end - 1) & 0xff] & 2) == 0 && (m_syncprom[m_vblank_end] & 2) != 0)
			break;

	/* can't handle the wrapping case */
	assert(m_vblank_end < m_vblank_start);

	/* reconfigure the visible area to match */
	visarea.set(0, 255, m_vblank_end + 1, m_vblank_start);
	m_screen->configure(320, 256, visarea, HZ_TO_ATTOSECONDS(PIXEL_CLOCK) * VTOTAL * HTOTAL);

	/* create a timer for IRQs and set up the first callback */
	m_irq_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(cloud9_state::clock_irq),this));
	m_irq_state = 0;
	schedule_next_irq(0-64);

	/* setup for save states */
	save_item(NAME(m_irq_state));
}
Пример #6
0
static void k053252_res_change( device_t *device )
{
	k053252_state *k053252 = k053252_get_safe_token(device);

	if(k053252->screen != NULL)
	{
		if(k053252->hc && k053252->vc &&
		   k053252->hbp && k053252->hfp &&
		   k053252->vbp && k053252->vfp &&
		   k053252->hsw && k053252->vsw) //safety checks
		{
			rectangle visarea;
			//(HC+1) - HFP - HBP - 8*(HSW+1)
			//VC - VFP - VBP - (VSW+1)
			attoseconds_t refresh = HZ_TO_ATTOSECONDS(device->clock()) * (k053252->hc) * k053252->vc;

			//printf("H %d %d %d %d\n",k053252->hc,k053252->hfp,k053252->hbp,k053252->hsw);
			//printf("V %d %d %d %d\n",k053252->vc,k053252->vfp,k053252->vbp,k053252->vsw);

			visarea.min_x = k053252->offsx;
			visarea.min_y = k053252->offsy;
			visarea.max_x = k053252->offsx + k053252->hc - k053252->hfp - k053252->hbp - 8*(k053252->hsw) - 1;
			visarea.max_y = k053252->offsy + k053252->vc - k053252->vfp - k053252->vbp - (k053252->vsw) - 1;

			k053252->screen->configure(k053252->hc, k053252->vc, visarea, refresh);
		}
	}
}
Пример #7
0
void x68k_state::x68k_crtc_refresh_mode()
{
//  rectangle rect;
//  double scantime;
	rectangle scr,visiblescr;
	int length;

	// Calculate data from register values
	m_crtc.vmultiple = 1;
	if((m_crtc.reg[20] & 0x10) != 0 && (m_crtc.reg[20] & 0x0c) == 0)
		m_crtc.vmultiple = 2;  // 31.5kHz + 256 lines = doublescan
	if(m_crtc.interlace != 0)
		m_crtc.vmultiple = 0.5f;  // 31.5kHz + 1024 lines or 15kHz + 512 lines = interlaced
	m_crtc.htotal = (m_crtc.reg[0] + 1) * 8;
	m_crtc.vtotal = (m_crtc.reg[4] + 1) / m_crtc.vmultiple; // default is 567 (568 scanlines)
	m_crtc.hbegin = (m_crtc.reg[2] * 8) + 1;
	m_crtc.hend = (m_crtc.reg[3] * 8);
	m_crtc.vbegin = (m_crtc.reg[6]) / m_crtc.vmultiple;
	m_crtc.vend = (m_crtc.reg[7] - 1) / m_crtc.vmultiple;
	if((m_crtc.vmultiple == 2) && !(m_crtc.reg[7] & 1)) // otherwise if the raster irq line == vblank line, the raster irq fires too late
		m_crtc.vend++;
	m_crtc.hsync_end = (m_crtc.reg[1]) * 8;
	m_crtc.vsync_end = (m_crtc.reg[5]) / m_crtc.vmultiple;
	m_crtc.hsyncadjust = m_crtc.reg[8];
	scr.set(0, m_crtc.htotal - 8, 0, m_crtc.vtotal);
	if(scr.max_y <= m_crtc.vend)
		scr.max_y = m_crtc.vend + 2;
	if(scr.max_x <= m_crtc.hend)
		scr.max_x = m_crtc.hend + 2;
	visiblescr.set(m_crtc.hbegin, m_crtc.hend, m_crtc.vbegin, m_crtc.vend);

	// expand visible area to the size indicated by CRTC reg 20
	length = m_crtc.hend - m_crtc.hbegin;
	if (length < m_crtc.width)
	{
		visiblescr.min_x = m_crtc.hbegin - ((m_crtc.width - length)/2);
		visiblescr.max_x = m_crtc.hend + ((m_crtc.width - length)/2);
	}
	length = m_crtc.vend - m_crtc.vbegin;
	if (length < m_crtc.height)
	{
		visiblescr.min_y = m_crtc.vbegin - ((m_crtc.height - length)/2);
		visiblescr.max_y = m_crtc.vend + ((m_crtc.height - length)/2);
	}
	// bounds check
	if(visiblescr.min_x < 0)
		visiblescr.min_x = 0;
	if(visiblescr.min_y < 0)
		visiblescr.min_y = 0;
	if(visiblescr.max_x >= scr.max_x)
		visiblescr.max_x = scr.max_x - 2;
	if(visiblescr.max_y >= scr.max_y - 1)
		visiblescr.max_y = scr.max_y - 2;

//  logerror("CRTC regs - %i %i %i %i  - %i %i %i %i - %i - %i\n",m_crtc.reg[0],m_crtc.reg[1],m_crtc.reg[2],m_crtc.reg[3],
//      m_crtc.reg[4],m_crtc.reg[5],m_crtc.reg[6],m_crtc.reg[7],m_crtc.reg[8],m_crtc.reg[9]);
	logerror("video_screen_configure(machine.first_screen(),%i,%i,[%i,%i,%i,%i],55.45)\n",scr.max_x,scr.max_y,visiblescr.min_x,visiblescr.min_y,visiblescr.max_x,visiblescr.max_y);
	m_screen->configure(scr.max_x,scr.max_y,visiblescr,HZ_TO_ATTOSECONDS(55.45));
}
Пример #8
0
static void x68k_crtc_refresh_mode(running_machine &machine)
{
    x68k_state *state = machine.driver_data<x68k_state>();
//  rectangle rect;
//  double scantime;
    rectangle scr,visiblescr;
    int length;

    // Calculate data from register values
    state->m_crtc.vmultiple = 1;
    if((state->m_crtc.reg[20] & 0x10) != 0 && (state->m_crtc.reg[20] & 0x0c) == 0)
        state->m_crtc.vmultiple = 2;  // 31.5kHz + 256 lines = doublescan
    if(state->m_crtc.interlace != 0)
        state->m_crtc.vmultiple = 0.5f;  // 31.5kHz + 1024 lines or 15kHz + 512 lines = interlaced
    state->m_crtc.htotal = (state->m_crtc.reg[0] + 1) * 8;
    state->m_crtc.vtotal = (state->m_crtc.reg[4] + 1) / state->m_crtc.vmultiple; // default is 567 (568 scanlines)
    state->m_crtc.hbegin = (state->m_crtc.reg[2] * 8) + 1;
    state->m_crtc.hend = (state->m_crtc.reg[3] * 8);
    state->m_crtc.vbegin = (state->m_crtc.reg[6]) / state->m_crtc.vmultiple;
    state->m_crtc.vend = (state->m_crtc.reg[7] - 1) / state->m_crtc.vmultiple;
    state->m_crtc.hsync_end = (state->m_crtc.reg[1]) * 8;
    state->m_crtc.vsync_end = (state->m_crtc.reg[5]) / state->m_crtc.vmultiple;
    state->m_crtc.hsyncadjust = state->m_crtc.reg[8];
    scr.set(0, state->m_crtc.htotal - 8, 0, state->m_crtc.vtotal);
    if(scr.max_y <= state->m_crtc.vend)
        scr.max_y = state->m_crtc.vend + 2;
    if(scr.max_x <= state->m_crtc.hend)
        scr.max_x = state->m_crtc.hend + 2;
    visiblescr.set(state->m_crtc.hbegin, state->m_crtc.hend, state->m_crtc.vbegin, state->m_crtc.vend);

    // expand visible area to the size indicated by CRTC reg 20
    length = state->m_crtc.hend - state->m_crtc.hbegin;
    if (length < state->m_crtc.width)
    {
        visiblescr.min_x = state->m_crtc.hbegin - ((state->m_crtc.width - length)/2);
        visiblescr.max_x = state->m_crtc.hend + ((state->m_crtc.width - length)/2);
    }
    length = state->m_crtc.vend - state->m_crtc.vbegin;
    if (length < state->m_crtc.height)
    {
        visiblescr.min_y = state->m_crtc.vbegin - ((state->m_crtc.height - length)/2);
        visiblescr.max_y = state->m_crtc.vend + ((state->m_crtc.height - length)/2);
    }
    // bounds check
    if(visiblescr.min_x < 0)
        visiblescr.min_x = 0;
    if(visiblescr.min_y < 0)
        visiblescr.min_y = 0;
    if(visiblescr.max_x >= scr.max_x)
        visiblescr.max_x = scr.max_x - 2;
    if(visiblescr.max_y >= scr.max_y - 1)
        visiblescr.max_y = scr.max_y - 2;

//  logerror("CRTC regs - %i %i %i %i  - %i %i %i %i - %i - %i\n",state->m_crtc.reg[0],state->m_crtc.reg[1],state->m_crtc.reg[2],state->m_crtc.reg[3],
//      state->m_crtc.reg[4],state->m_crtc.reg[5],state->m_crtc.reg[6],state->m_crtc.reg[7],state->m_crtc.reg[8],state->m_crtc.reg[9]);
    logerror("video_screen_configure(machine.primary_screen,%i,%i,[%i,%i,%i,%i],55.45)\n",scr.max_x,scr.max_y,visiblescr.min_x,visiblescr.min_y,visiblescr.max_x,visiblescr.max_y);
    machine.primary_screen->configure(scr.max_x,scr.max_y,visiblescr,HZ_TO_ATTOSECONDS(55.45));
}
Пример #9
0
void sm7238_state::recompute_parameters()
{
	rectangle visarea;
	int horiz_pix_total = m_video.stride * 8;

	visarea.set(0, horiz_pix_total - 1, 0, KSM_DISP_VERT - 1);
	machine().first_screen()->configure(horiz_pix_total, KSM_DISP_VERT, visarea,
		HZ_TO_ATTOSECONDS((m_video.stride == 80) ? 60 : 57.1 ));
}
Пример #10
0
attoseconds_t device_execute_interface::minimum_quantum() const
{
	// if we don't have that information, compute it
	attoseconds_t basetick = m_attoseconds_per_cycle;
	if (basetick == 0)
		basetick = HZ_TO_ATTOSECONDS(clocks_to_cycles(device().clock()));

	// apply the minimum cycle count
	return basetick * min_cycles();
}
Пример #11
0
inline void crt9007_device::recompute_parameters()
{
	// check that necessary registers have been loaded
	if (!HAS_VALID_PARAMETERS) return;

	// screen dimensions
	int horiz_pix_total = CHARACTERS_PER_HORIZONTAL_PERIOD * m_hpixels_per_column;
	int vert_pix_total = SCAN_LINES_PER_FRAME;

	// refresh rate
	attoseconds_t refresh = HZ_TO_ATTOSECONDS(clock()) * horiz_pix_total * vert_pix_total;

	// horizontal sync
	m_hsync_start = 0;
	m_hsync_end = HORIZONTAL_SYNC_WIDTH * m_hpixels_per_column;

	// visible line time
	m_vlt_start = HORIZONTAL_DELAY * m_hpixels_per_column;
	m_vlt_end = (HORIZONTAL_DELAY + CHARACTERS_PER_DATA_ROW) * m_hpixels_per_column;
	m_vlt_bottom = VERTICAL_DELAY + (VISIBLE_DATA_ROWS_PER_FRAME * SCAN_LINES_PER_DATA_ROW) - 1;

	// data row boundary
	m_drb_bottom = VERTICAL_DELAY + (VISIBLE_DATA_ROWS_PER_FRAME * SCAN_LINES_PER_DATA_ROW) - SCAN_LINES_PER_DATA_ROW;

	// vertical sync
	m_vsync_start = 0;
	m_vsync_end = VERTICAL_SYNC_WIDTH;

	// visible area
	rectangle visarea;

	visarea.min_x = m_hsync_end;
	visarea.max_x = horiz_pix_total - 1;

	visarea.min_y = m_vsync_end;
	visarea.max_y = vert_pix_total - 1;

	if (LOG)
	{
		logerror("CRT9007 '%s' Screen: %u x %u @ %f Hz\n", tag(), horiz_pix_total, vert_pix_total, 1 / ATTOSECONDS_TO_DOUBLE(refresh));
		logerror("CRT9007 '%s' Visible Area: (%u, %u) - (%u, %u)\n", tag(), visarea.min_x, visarea.min_y, visarea.max_x, visarea.max_y);
	}

	m_screen->configure(horiz_pix_total, vert_pix_total, visarea, refresh);

	m_hsync_timer->adjust(m_screen->time_until_pos(0, 0));
	m_vsync_timer->adjust(m_screen->time_until_pos(0, 0));
	m_vlt_timer->adjust(m_screen->time_until_pos(0, m_vlt_start), 1);
	m_drb_timer->adjust(m_screen->time_until_pos(0, 0));
}
Пример #12
0
attoseconds_t device_execute_interface::minimum_quantum() const
{
	// if we don't have a clock, return a huge factor
	if (device().clock() == 0)
		return ATTOSECONDS_PER_SECOND - 1;

	// if we don't have the quantum time, compute it
	attoseconds_t basetick = m_attoseconds_per_cycle;
	if (basetick == 0)
		basetick = HZ_TO_ATTOSECONDS(clocks_to_cycles(device().clock()));

	// apply the minimum cycle count
	return basetick * min_cycles();
}
Пример #13
0
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);
		}
	}
}
Пример #14
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);
}
Пример #15
0
void device_execute_interface::interface_clock_changed()
{
	// recompute cps and spc
	m_cycles_per_second = clocks_to_cycles(device().clock());
	m_attoseconds_per_cycle = HZ_TO_ATTOSECONDS(m_cycles_per_second);

	// update the device's divisor
	INT64 attos = m_attoseconds_per_cycle;
	m_divshift = 0;
	while (attos >= (1UL << 31))
	{
		m_divshift++;
		attos >>= 1;
	}
	m_divisor = attos;

	// re-compute the perfect interleave factor
	device().machine().scheduler().compute_perfect_interleave();
}
Пример #16
0
static MACHINE_START( cloud9 )
{
	cloud9_state *state = (cloud9_state *)machine->driver_data;
	rectangle visarea;

	/* initialize globals */
	state->maincpu = machine->device("maincpu");
	state->syncprom = memory_region(machine, "proms") + 0x000;

	/* find the start of VBLANK in the SYNC PROM */
	for (state->vblank_start = 0; state->vblank_start < 256; state->vblank_start++)
		if ((state->syncprom[(state->vblank_start - 1) & 0xff] & 2) != 0 && (state->syncprom[state->vblank_start] & 2) == 0)
			break;
	if (state->vblank_start == 0)
		state->vblank_start = 256;

	/* find the end of VBLANK in the SYNC PROM */
	for (state->vblank_end = 0; state->vblank_end < 256; state->vblank_end++)
		if ((state->syncprom[(state->vblank_end - 1) & 0xff] & 2) == 0 && (state->syncprom[state->vblank_end] & 2) != 0)
			break;

	/* can't handle the wrapping case */
	assert(state->vblank_end < state->vblank_start);

	/* reconfigure the visible area to match */
	visarea.min_x = 0;
	visarea.max_x = 255;
	visarea.min_y = state->vblank_end + 1;
	visarea.max_y = state->vblank_start;
	machine->primary_screen->configure(320, 256, visarea, HZ_TO_ATTOSECONDS(PIXEL_CLOCK) * VTOTAL * HTOTAL);

	/* create a timer for IRQs and set up the first callback */
	state->irq_timer = timer_alloc(machine, clock_irq, NULL);
	state->irq_state = 0;
	schedule_next_irq(machine, 0-64);

	/* allocate backing memory for the NVRAM */
	machine->generic.nvram.u8 = auto_alloc_array(machine, UINT8, machine->generic.nvram_size);

	/* setup for save states */
	state_save_register_global(machine, state->irq_state);
	state_save_register_global_pointer(machine, machine->generic.nvram.u8, machine->generic.nvram_size);
}
Пример #17
0
void tms9927_device::recompute_parameters(int postload)
{
	UINT16 offset_hpix, offset_vpix;
	attoseconds_t refresh;
	rectangle visarea;

	if (m_reset)
		return;

	/* compute the screen sizes */
	m_total_hpix = HCOUNT * m_hpixels_per_column;
	m_total_vpix = SCAN_LINES_PER_FRAME;

	/* determine the visible area, avoid division by 0 */
	m_visible_hpix = CHARS_PER_DATA_ROW * m_hpixels_per_column;
	m_visible_vpix = (LAST_DISP_DATA_ROW + 1) * SCANS_PER_DATA_ROW;

	/* determine the horizontal/vertical offsets */
	offset_hpix = HSYNC_DELAY * m_hpixels_per_column;
	offset_vpix = VERTICAL_DATA_START;

	mame_printf_debug("TMS9937: Total = %dx%d, Visible = %dx%d, Offset=%dx%d, Skew=%d\n", m_total_hpix, m_total_vpix, m_visible_hpix, m_visible_vpix, offset_hpix, offset_vpix, SKEW_BITS);

	/* see if it all makes sense */
	m_valid_config = TRUE;
	if (m_visible_hpix > m_total_hpix || m_visible_vpix > m_total_vpix)
	{
		m_valid_config = FALSE;
		logerror("tms9927: invalid visible size (%dx%d) versus total size (%dx%d)\n", m_visible_hpix, m_visible_vpix, m_total_hpix, m_total_vpix);
	}

	/* update */
	if (!m_valid_config)
		return;

	/* create a visible area */
	/* fix me: how do the offsets fit in here? */
	visarea.set(0, m_visible_hpix - 1, 0, m_visible_vpix - 1);

	refresh = HZ_TO_ATTOSECONDS(m_clock) * m_total_hpix * m_total_vpix;

	m_screen->configure(m_total_hpix, m_total_vpix, visarea, refresh);
}
Пример #18
0
void speaker_sound_device::device_reset()
{
	int i;

	m_level = 0;
	for (i = 0; i < FILTER_LENGTH; i++)
		m_composed_volume[i] = 0;

	m_composed_sample_index = 0;
	m_last_update_time = machine().time();
	m_channel_sample_period = HZ_TO_ATTOSECONDS(machine().sample_rate());
	m_channel_sample_period_secfrac = ATTOSECONDS_TO_DOUBLE(m_channel_sample_period);
	m_interm_sample_period = m_channel_sample_period / RATE_MULTIPLIER;
	m_interm_sample_period_secfrac = ATTOSECONDS_TO_DOUBLE(m_interm_sample_period);
	m_channel_last_sample_time = m_channel->sample_time();
	m_channel_next_sample_time = m_channel_last_sample_time + attotime(0, m_channel_sample_period);
	m_next_interm_sample_time = m_channel_last_sample_time + attotime(0, m_interm_sample_period);
	m_interm_sample_index = 0;
	m_prevx = m_prevy = 0.0;
}
Пример #19
0
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);
}
Пример #20
0
static MACHINE_START( ccastles )
{
	ccastles_state *state = machine.driver_data<ccastles_state>();
	rectangle visarea;

	/* initialize globals */
	state->m_syncprom = state->memregion("proms")->base() + 0x000;

	/* find the start of VBLANK in the SYNC PROM */
	for (state->m_vblank_start = 0; state->m_vblank_start < 256; state->m_vblank_start++)
		if ((state->m_syncprom[(state->m_vblank_start - 1) & 0xff] & 1) == 0 && (state->m_syncprom[state->m_vblank_start] & 1) != 0)
			break;
	if (state->m_vblank_start == 0)
		state->m_vblank_start = 256;

	/* find the end of VBLANK in the SYNC PROM */
	for (state->m_vblank_end = 0; state->m_vblank_end < 256; state->m_vblank_end++)
		if ((state->m_syncprom[(state->m_vblank_end - 1) & 0xff] & 1) != 0 && (state->m_syncprom[state->m_vblank_end] & 1) == 0)
			break;

	/* can't handle the wrapping case */
	assert(state->m_vblank_end < state->m_vblank_start);

	/* reconfigure the visible area to match */
	visarea.set(0, 255, state->m_vblank_end, state->m_vblank_start - 1);
	machine.primary_screen->configure(320, 256, visarea, HZ_TO_ATTOSECONDS(PIXEL_CLOCK) * VTOTAL * HTOTAL);

	/* configure the ROM banking */
	state->membank("bank1")->configure_entries(0, 2, state->memregion("maincpu")->base() + 0xa000, 0x6000);

	/* create a timer for IRQs and set up the first callback */
	state->m_irq_timer = machine.scheduler().timer_alloc(FUNC(clock_irq));
	state->m_irq_state = 0;
	schedule_next_irq(machine, 0);

	/* setup for save states */
	state->save_item(NAME(state->m_irq_state));
	state->save_item(NAME(state->m_nvram_store));
}
Пример #21
0
inline void upd3301_device::recompute_parameters()
{
	int horiz_pix_total = (m_h + m_z) * m_width;
	int vert_pix_total = (m_l + m_v) * m_r;

	attoseconds_t refresh = HZ_TO_ATTOSECONDS(clock()) * horiz_pix_total * vert_pix_total;

	rectangle visarea;

	visarea.set(0, (m_h * m_width) - 1, 0, (m_l * m_r) - 1);

	if (LOG)
	{
		if (LOG) logerror("UPD3301 '%s' Screen: %u x %u @ %f Hz\n", tag(), horiz_pix_total, vert_pix_total, 1 / ATTOSECONDS_TO_DOUBLE(refresh));
		if (LOG) logerror("UPD3301 '%s' Visible Area: (%u, %u) - (%u, %u)\n", tag(), visarea.min_x, visarea.min_y, visarea.max_x, visarea.max_y);
	}

	m_screen->configure(horiz_pix_total, vert_pix_total, visarea, refresh);

	update_hrtc_timer(0);
	update_vrtc_timer(0);
}
Пример #22
0
void k053252_device::res_change()
{
	if(m_hc && m_vc &&
		m_hbp && m_hfp &&
		m_vbp && m_vfp &&
		m_hsw && m_vsw) //safety checks
	{
		rectangle visarea;
		//(HC+1) - HFP - HBP - 8*(HSW+1)
		//VC - VFP - VBP - (VSW+1)
		attoseconds_t refresh = HZ_TO_ATTOSECONDS(clock()) * (m_hc) * m_vc;

		//printf("H %d %d %d %d\n",m_hc,m_hfp,m_hbp,m_hsw);
		//printf("V %d %d %d %d\n",m_vc,m_vfp,m_vbp,m_vsw);

		visarea.min_x = m_offsx;
		visarea.min_y = m_offsy;
		visarea.max_x = m_offsx + m_hc - m_hfp - m_hbp - 8*(m_hsw) - 1;
		visarea.max_y = m_offsy + m_vc - m_vfp - m_vbp - (m_vsw) - 1;

		m_screen->configure(m_hc, m_vc, visarea, refresh);
	}
}
Пример #23
0
void towns_state::towns_crtc_refresh_mode()
{
	rectangle scr(0, m_video.towns_crtc_reg[4] - m_video.towns_crtc_reg[0], 0, m_video.towns_crtc_reg[8] / 2);

	// layer 0
	m_video.towns_crtc_layerscr[0].min_x = m_video.towns_crtc_reg[9] - m_video.towns_crtc_reg[0];
	m_video.towns_crtc_layerscr[0].min_y = (m_video.towns_crtc_reg[13] - m_video.towns_crtc_reg[6]) / 2;
	m_video.towns_crtc_layerscr[0].max_x = m_video.towns_crtc_reg[10] - m_video.towns_crtc_reg[0];
	m_video.towns_crtc_layerscr[0].max_y = ((m_video.towns_crtc_reg[14] - m_video.towns_crtc_reg[6]) / 2) - 1;

	// layer 1
	m_video.towns_crtc_layerscr[1].min_x = m_video.towns_crtc_reg[11] - m_video.towns_crtc_reg[0];
	m_video.towns_crtc_layerscr[1].min_y = (m_video.towns_crtc_reg[15] - m_video.towns_crtc_reg[6]) / 2;
	m_video.towns_crtc_layerscr[1].max_x = m_video.towns_crtc_reg[12] - m_video.towns_crtc_reg[0];
	m_video.towns_crtc_layerscr[1].max_y = ((m_video.towns_crtc_reg[16] - m_video.towns_crtc_reg[6]) / 2) - 1;

	// sanity checks
	if(scr.max_x == 0 || scr.max_y == 0)
		return;
	if(scr.max_x <= scr.min_x || scr.max_y <= scr.min_y)
		return;

	m_screen->configure(scr.max_x+1,scr.max_y+1,scr,HZ_TO_ATTOSECONDS(60));
}
Пример #24
0
void crtc_ega_device::recompute_parameters(bool postload)
{
	UINT16 hsync_on_pos, hsync_off_pos, vsync_on_pos, vsync_off_pos;

	/* compute the screen sizes */
	UINT16 horiz_pix_total = (m_horiz_char_total + 2) * m_hpixels_per_column;
	UINT16 vert_pix_total = m_vert_total + 1;

	/* determine the visible area, avoid division by 0 */
	UINT16 max_visible_x = ( m_horiz_disp + 1 ) * m_hpixels_per_column - 1;
	UINT16 max_visible_y = m_vert_disp_end;

	/* determine the syncing positions */
	int horiz_sync_char_width = ( m_horiz_retr_end + 1 ) - ( m_horiz_retr_start & 0x1f );
	int vert_sync_pix_width = m_vert_retr_end - ( m_vert_retr_start & 0x0f );

	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 = m_horiz_retr_start * m_hpixels_per_column;
	hsync_off_pos = hsync_on_pos + (horiz_sync_char_width * m_hpixels_per_column);
	vsync_on_pos = m_vert_retr_start;       /* + 1 ?? */
	vsync_off_pos = vsync_on_pos + vert_sync_pix_width;

	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;

	if ( vsync_on_pos >= vsync_off_pos )
	{
		vsync_on_pos = vsync_off_pos - 2;
	}

	/* update only if screen parameters changed, unless we are coming here after loading the saved state */
	if (postload ||
		(horiz_pix_total != m_horiz_pix_total) || (vert_pix_total != m_vert_pix_total) ||
		(max_visible_x != m_max_visible_x) || (max_visible_y != m_max_visible_y) ||
		(hsync_on_pos != m_hsync_on_pos) || (vsync_on_pos != m_vsync_on_pos) ||
		(hsync_off_pos != m_hsync_off_pos) || (vsync_off_pos != m_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))
		{
			attoseconds_t refresh = HZ_TO_ATTOSECONDS(m_clock) * (m_horiz_char_total + 2) * vert_pix_total;

			rectangle visarea(0, max_visible_x, 0, max_visible_y);

			if (LOG) logerror("CRTC_EGA 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));

			if ( m_screen != NULL )
				m_screen->configure(horiz_pix_total, vert_pix_total, visarea, refresh);

			m_has_valid_parameters = true;
		}
		else
		{
			m_has_valid_parameters = false;
			if (LOG) logerror("CRTC_EGA bad 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\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);

		}

		m_horiz_pix_total = horiz_pix_total;
		m_vert_pix_total = vert_pix_total;
		m_max_visible_x = max_visible_x;
		m_max_visible_y = max_visible_y;
		m_hsync_on_pos = hsync_on_pos;
		m_hsync_off_pos = hsync_off_pos;
		m_vsync_on_pos = vsync_on_pos;
		m_vsync_off_pos = vsync_off_pos;
	}
}
Пример #25
0
void mc6845_device::recompute_parameters(bool postload)
{
	UINT16 hsync_on_pos, hsync_off_pos, vsync_on_pos, vsync_off_pos;

	UINT16 video_char_height = m_max_ras_addr + 1;   // fix garbage at the bottom of the screen (eg victor9k)
	// Would be useful for 'interlace and video' mode support...
	// UINT16 frame_char_height = (MODE_INTERLACE_AND_VIDEO ? m_max_ras_addr / 2 : m_max_ras_addr) + 1;

	/* compute the screen sizes */
	UINT16 horiz_pix_total = (m_horiz_char_total + 1) * m_hpixels_per_column;
	UINT16 vert_pix_total = (m_vert_char_total + 1) * video_char_height + m_vert_total_adj;

	/* determine the visible area, avoid division by 0 */
	UINT16 max_visible_x = m_horiz_disp * m_hpixels_per_column - 1;
	UINT16 max_visible_y = m_vert_disp * video_char_height - 1;

	/* determine the syncing positions */
	UINT8 horiz_sync_char_width = m_sync_width & 0x0f;
	UINT8 vert_sync_pix_width = m_supports_vert_sync_width ? (m_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;

	/* determine the transparent update cycle time, 1 update every 4 character clocks */
	m_upd_time = attotime::from_hz(m_clock) * (4 * m_hpixels_per_column);

	hsync_on_pos = m_horiz_sync_pos * m_hpixels_per_column;
	hsync_off_pos = hsync_on_pos + (horiz_sync_char_width * m_hpixels_per_column);
	vsync_on_pos = m_vert_sync_pos * video_char_height;
	vsync_off_pos = vsync_on_pos + vert_sync_pix_width;

	// the Commodore PET computers have a non-standard 20kHz monitor which
	// requires a wider HSYNC pulse that extends past the scanline width
	if (hsync_off_pos > horiz_pix_total)
		hsync_off_pos = horiz_pix_total;

	if (vsync_on_pos > vert_pix_total)
		vsync_on_pos = vert_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 != m_horiz_pix_total) || (vert_pix_total != m_vert_pix_total) ||
		(max_visible_x != m_max_visible_x) || (max_visible_y != m_max_visible_y) ||
		(hsync_on_pos != m_hsync_on_pos) || (vsync_on_pos != m_vsync_on_pos) ||
		(hsync_off_pos != m_hsync_off_pos) || (vsync_off_pos != m_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(m_clock) * (m_horiz_char_total + 1) * vert_pix_total;

			// This doubles the vertical resolution, required for 'interlace and video' mode support.
			// Tested and works for super80v, which was designed with this in mind (choose green or monochrome colour in config switches).
			// However it breaks some other drivers (apricot,a6809,victor9k,bbc(mode7)).
			// So, it is commented out for now.
			// Also, the mode-register change needs to be added to the changed-parameter tests above.
			if (MODE_INTERLACE_AND_VIDEO)
			{
				//max_visible_y *= 2;
				//vert_pix_total *= 2;
			}

			if(m_show_border_area)
				visarea.set(0, horiz_pix_total-1, 0, vert_pix_total-1);
			else
				visarea.set(0 + m_visarea_adjust_min_x, max_visible_x + m_visarea_adjust_max_x, 0 + m_visarea_adjust_min_y, max_visible_y + m_visarea_adjust_max_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));

			if ( m_screen != NULL )
				m_screen->configure(horiz_pix_total, vert_pix_total, visarea, refresh);

			if(!m_reconfigure_cb.isnull())
				m_reconfigure_cb(horiz_pix_total, vert_pix_total, visarea, refresh);

			m_has_valid_parameters = true;
		}
		else
			m_has_valid_parameters = false;

		m_horiz_pix_total = horiz_pix_total;
		m_vert_pix_total = vert_pix_total;
		m_max_visible_x = max_visible_x;
		m_max_visible_y = max_visible_y;
		m_hsync_on_pos = hsync_on_pos;
		m_hsync_off_pos = hsync_off_pos;
		m_vsync_on_pos = vsync_on_pos;
		m_vsync_off_pos = vsync_off_pos;
		m_line_counter = 0;
	}
}
Пример #26
0
static DEVICE_START( speaker )
{
	speaker_state *sp = get_safe_token(device);
	const speaker_interface *intf = (const speaker_interface *) device->static_config();
	int i;
	double x;

	sp->channel = device->machine().sound().stream_alloc(*device, 0, 1, device->machine().sample_rate(), sp, speaker_sound_update);

	if (intf != NULL)
	{
		assert(intf->num_level > 1);
		assert(intf->levels != NULL);
		sp->num_levels = intf->num_level;
		sp->levels = intf->levels;
	}
	else
	{
		sp->num_levels = 2;
		sp->levels = default_levels;
	}

	sp->level = 0;
	for (i = 0; i < FILTER_LENGTH; i++)
		sp->composed_volume[i] = 0;
	sp->composed_sample_index = 0;
	sp->last_update_time = device->machine().time();
	sp->channel_sample_period = HZ_TO_ATTOSECONDS(device->machine().sample_rate());
	sp->channel_sample_period_secfrac = ATTOSECONDS_TO_DOUBLE(sp->channel_sample_period);
	sp->interm_sample_period = sp->channel_sample_period / RATE_MULTIPLIER;
	sp->interm_sample_period_secfrac = ATTOSECONDS_TO_DOUBLE(sp->interm_sample_period);
	sp->channel_last_sample_time = sp->channel->sample_time();
	sp->channel_next_sample_time = sp->channel_last_sample_time + attotime(0, sp->channel_sample_period);
	sp->next_interm_sample_time = sp->channel_last_sample_time + attotime(0, sp->interm_sample_period);
	sp->interm_sample_index = 0;
	/* Note: To avoid time drift due to floating point inaccuracies,
     * it is good if the speaker time synchronizes itself with the stream timing regularly.
     */

	/* Compute filter kernel; */
	/* (Done for each device though the data is shared...
     *  No problem really, but should be done as part of system init if I knew how)
     */
#if 1
	/* This is an approximated sinc (a perfect sinc makes an ideal low-pass filter).
     * FILTER_STEP determines the cutoff frequency,
     * which should be below the Nyquist freq, i.e. half the sample rate.
     * Smaller step => kernel extends in time domain => lower cutoff freq
     * In this case, with sinc, filter step PI corresponds to the Nyq. freq.
     * Since we do not get a perfect filter => must lower the cutoff freq some more.
     * For example, step PI/(2*RATE_MULTIPLIER) corresponds to cutoff freq = sample rate / 4;
     *    With -samplerate 48000, cutoff freq is ca 12kHz while the Nyq. freq is 24kHz.
     *    With -samplerate 96000, cutoff freq is ca 24kHz while the Nyq. freq is 48kHz.
     * For a steeper, more efficient filter, increase FILTER_LENGTH at the expense of CPU usage.
     */
	#define FILTER_STEP  (M_PI / 2 / RATE_MULTIPLIER)
	/* Distribute symmetrically on x axis; center has x=0 if length is odd */
	for (i = 0, 			x = (0.5 - FILTER_LENGTH / 2.) * FILTER_STEP;
	     i < FILTER_LENGTH;
		 i++,				x += FILTER_STEP)
	{
		if (x == 0)
			ampl[i] = 1;
		else
			ampl[i] = sin(x) / x;
	}
#else
	/* Trivial average filter with poor frequency cutoff properties;
     * First zero (frequency where amplification=0) = sample rate / filter length
     * Cutoff frequency approx <= first zero / 2
     */
	for (i = 0, i < FILTER_LENGTH; i++)
		ampl[i] = 1;
#endif
}
Пример #27
0
void js_main_loop() {
	attotime stoptime = scheduler->time() + attotime(0,HZ_TO_ATTOSECONDS(60));
	while (scheduler->time() < stoptime) {
		scheduler->timeslice();
	}
}
Пример #28
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;

		/* determine the transparent update cycle time, 1 update every 4 character clocks */
		mc6845->upd_time = attotime::from_hz(mc6845->clock) * (4 * mc6845->hpixels_per_column);

		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));

				if ( mc6845->screen != NULL )
					mc6845->screen->configure(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;
		}
	}
Пример #29
0
static void recompute_parameters(crtc_ega_t *crtc_ega, int postload)
{
	if (crtc_ega->intf != NULL)
	{
		UINT16 hsync_on_pos, hsync_off_pos, vsync_on_pos, vsync_off_pos;

		/* compute the screen sizes */
		UINT16 horiz_pix_total = (crtc_ega->horiz_char_total + 5) * crtc_ega->hpixels_per_column;
		UINT16 vert_pix_total = crtc_ega->vert_total + 1;

		/* determine the visible area, avoid division by 0 */
		UINT16 max_visible_x = ( crtc_ega->horiz_disp + 1 ) * crtc_ega->hpixels_per_column - 1;
		UINT16 max_visible_y = crtc_ega->vert_disp_end;

		/* determine the syncing positions */
		int horiz_sync_char_width = ( crtc_ega->horiz_retr_end + 1 ) - ( crtc_ega->horiz_retr_start & 0x1f );
		int vert_sync_pix_width = crtc_ega->vert_retr_end - ( crtc_ega->vert_retr_start & 0x0f );

		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 = crtc_ega->horiz_retr_start * crtc_ega->hpixels_per_column;
		hsync_off_pos = hsync_on_pos + (horiz_sync_char_width * crtc_ega->hpixels_per_column);
		vsync_on_pos = crtc_ega->vert_retr_start;		/* + 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 != crtc_ega->horiz_pix_total) || (vert_pix_total != crtc_ega->vert_pix_total) ||
			(max_visible_x != crtc_ega->max_visible_x) || (max_visible_y != crtc_ega->max_visible_y) ||
			(hsync_on_pos != crtc_ega->hsync_on_pos) || (vsync_on_pos != crtc_ega->vsync_on_pos) ||
			(hsync_off_pos != crtc_ega->hsync_off_pos) || (vsync_off_pos != crtc_ega->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(crtc_ega->clock) * (crtc_ega->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("CRTC_EGA 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));

				crtc_ega->screen->configure(horiz_pix_total, vert_pix_total, visarea, refresh);

				crtc_ega->has_valid_parameters = TRUE;
			}
			else
				crtc_ega->has_valid_parameters = FALSE;

			crtc_ega->horiz_pix_total = horiz_pix_total;
			crtc_ega->vert_pix_total = vert_pix_total;
			crtc_ega->max_visible_x = max_visible_x;
			crtc_ega->max_visible_y = max_visible_y;
			crtc_ega->hsync_on_pos = hsync_on_pos;
			crtc_ega->hsync_off_pos = hsync_off_pos;
			crtc_ega->vsync_on_pos = vsync_on_pos;
			crtc_ega->vsync_off_pos = vsync_off_pos;

			update_de_changed_timer(crtc_ega);
			update_hsync_changed_timers(crtc_ega);
			update_vsync_changed_timers(crtc_ega);
			update_vblank_changed_timers(crtc_ega);
		}
	}
}
Пример #30
0
void speaker_sound_device::device_start()
{
	int i;
	double x;

	m_channel = machine().sound().stream_alloc(*this, 0, 1, machine().sample_rate(), this);

	m_level = 0;
	for (i = 0; i < FILTER_LENGTH; i++)
		m_composed_volume[i] = 0;

	m_composed_sample_index = 0;
	m_last_update_time = machine().time();
	m_channel_sample_period = HZ_TO_ATTOSECONDS(machine().sample_rate());
	m_channel_sample_period_secfrac = ATTOSECONDS_TO_DOUBLE(m_channel_sample_period);
	m_interm_sample_period = m_channel_sample_period / RATE_MULTIPLIER;
	m_interm_sample_period_secfrac = ATTOSECONDS_TO_DOUBLE(m_interm_sample_period);
	m_channel_last_sample_time = m_channel->sample_time();
	m_channel_next_sample_time = m_channel_last_sample_time + attotime(0, m_channel_sample_period);
	m_next_interm_sample_time = m_channel_last_sample_time + attotime(0, m_interm_sample_period);
	m_interm_sample_index = 0;
	m_prevx = m_prevy = 0.0;

	/* Note: To avoid time drift due to floating point inaccuracies,
	 * it is good if the speaker time synchronizes itself with the stream timing regularly.
	 */

	/* Compute filter kernel; */
	/* (Done for each device though the data is shared...
	 *  No problem really, but should be done as part of system init if I knew how)
	 */
#if 1
	/* This is an approximated sinc (a perfect sinc makes an ideal low-pass filter).
	 * FILTER_STEP determines the cutoff frequency,
	 * which should be below the Nyquist freq, i.e. half the sample rate.
	 * Smaller step => kernel extends in time domain => lower cutoff freq
	 * In this case, with sinc, filter step PI corresponds to the Nyq. freq.
	 * Since we do not get a perfect filter => must lower the cutoff freq some more.
	 * For example, step PI/(2*RATE_MULTIPLIER) corresponds to cutoff freq = sample rate / 4;
	 *    With -samplerate 48000, cutoff freq is ca 12kHz while the Nyq. freq is 24kHz.
	 *    With -samplerate 96000, cutoff freq is ca 24kHz while the Nyq. freq is 48kHz.
	 * For a steeper, more efficient filter, increase FILTER_LENGTH at the expense of CPU usage.
	 */
#define FILTER_STEP  (M_PI / 2 / RATE_MULTIPLIER)
	/* Distribute symmetrically on x axis; center has x=0 if length is odd */
	for (i = 0,             x = (0.5 - FILTER_LENGTH / 2.) * FILTER_STEP;
			i < FILTER_LENGTH;
			i++,                x += FILTER_STEP)
	{
		if (x == 0)
			m_ampl[i] = 1;
		else
			m_ampl[i] = sin(x) / x;
	}
#else
	/* Trivial average filter with poor frequency cutoff properties;
	 * First zero (frequency where amplification=0) = sample rate / filter length
	 * Cutoff frequency approx <= first zero / 2
	 */
	for (i = 0, i < FILTER_LENGTH; i++)
		m_ampl[i] = 1;
#endif

	save_item(NAME(m_level));
	save_item(NAME(m_composed_volume));
	save_item(NAME(m_composed_sample_index));
	save_item(NAME(m_channel_last_sample_time));
	save_item(NAME(m_interm_sample_index));
	save_item(NAME(m_last_update_time));
	save_item(NAME(m_prevx));
	save_item(NAME(m_prevy));

	machine().save().register_postload(save_prepost_delegate(FUNC(speaker_sound_device::speaker_postload), this));
}