Example #1
0
File: lcdc.c Project: Jakz/ohboy
/* lcdc_trans()
	Main LCDC emulation routine
*/
void lcdc_trans()
{
	if (R_LCDC & 0x80)
	{
		/* LCDC operation enabled */
		while (C <= 0)
		{
			/* Update current state */
			switch ((byte)(R_STAT & 3))
			{
				case 0: /* after hblank */
					/* FIXME: first line of first frame will be skipped
					each time LCDC is started */
					if (++R_LY <= 143)
					{
						stat_change(2); /* -> search */
					}
					else
					{
						stat_change(1); /* -> vblank */
						/* See "NOTE A" above */
						/*if (cpu.halt)
						{
							hw_interrupt(IF_VBLANK, IF_VBLANK);
							C += 228;
						}
						else
						{
							C += 10;
							continue;
						}*/
						break;
					}
					break;
				case 2:  /* after search */
					stat_change(3); /* -> transfer */
					break;
				case 3:  /* after transfer */
					stat_change(0); /* -> hblank */
					break;
				case 1: /* after (in) vblank */
					if (R_LY == 0)
					{
						stat_change(2); /* -> search */
					}
					break;
			}
			
			/* Handle current state */
			switch ((byte)(R_STAT & 3))
			{
				case 2:  /* search */
					if (R_LY == 0)
					{
						lcd_begin();
					}
					C += 40;
					break;
				case 3:  /* transfer */
					lcd_refreshline();
					C += 86;
					break;
				case 0: /* hblank */
					if (hw.hdma & 0x80) {
						hw_hdma();
					}
					C += 102;
					break;
				case 1: /* vblank */
					if (!(hw.ilines & IF_VBLANK))
					{
						C += 228; /*C += 218; See "NOTE A" above */
						hw_interrupt(IF_VBLANK, IF_VBLANK);
					}
					else
					{
						R_LY++;
						if (R_LY < 153)
						{
							C += 228;
						}
						else if (R_LY == 153)
						{
							/* Handling special case on the last line
							part 1; see docs/HACKING */
							C += 28;
						}
						else
						{
							/* Handling special case on the last line
							part 2; see docs/HACKING */
							R_LY = 0;
							C += 200;
						}
						stat_trigger();
					}
					break;
			} /* switch(state) */
		} /* while (C <= 0) */
	} /* if (R_LCDC & 0x80) */
	else
	{
		/* LCDC operation disabled (short route) */
		if (C <= 0) /* Original code does in fact return after each pass, there is no loop here */
		{
			switch ((byte)(R_STAT & 3))
			{
			case 2: /* after search */
				stat_change(3);
				C += 86;
				break;
			case 3: /* after transfer */
				stat_change(0);
				C += 102;
				break;
			case 0: /* after hblank */
				stat_change(2);
				R_LY++;
				C += 40;
				break;
			case 1: /* after (in) vblank */
				stat_change(2);
				C += 40;
				break;
			}
		}
	}
}
Example #2
0
void lcdc_trans()
{
	if (!(R_LCDC & 0x80))
	{
		while (C <= 0)
		{
			switch ((byte)(R_STAT & 3))
			{
			case 0:
			case 1:
				stat_change(2);
				C += 40;
				break;
			case 2:
				stat_change(3);
				C += 86;
				break;
			case 3:
				stat_change(0);
				if (hw.hdma & 0x80)
					hw_hdma();
				else
					C += 102;
				break;
			}
			return;
		}
	}
	while (C <= 0)
	{
		switch ((byte)(R_STAT & 3))
		{
		case 1:
			if (!(hw.ilines & IF_VBLANK))
			{
				C += 218;
				hw_interrupt(IF_VBLANK, IF_VBLANK);
				break;
			}
			if (R_LY == 0)
			{
				lcd_begin();
				stat_change(2);
				C += 40;
				break;
			}
			else if (R_LY < 152)
				C += 228;
			else if (R_LY == 152)
				C += 28;
			else
			{
				R_LY = -1;
				C += 200;
			}
			R_LY++;
			stat_trigger();
			break;
		case 2:
			lcd_refreshline();
			stat_change(3);
			C += 86;
			break;
		case 3:
			stat_change(0);
			if (hw.hdma & 0x80)
				hw_hdma();
			/* FIXME -- how much of the hblank does hdma use?? */
			/* else */
			C += 102;
			break;
		case 0:
			if (++R_LY >= 144)
			{
				if (cpu.halt)
				{
					hw_interrupt(IF_VBLANK, IF_VBLANK);
					C += 228;
				}
				else C += 10;
				stat_change(1);
				break;
			}
			stat_change(2);
			C += 40;
			break;
		}
	}
}