예제 #1
0
파일: lcd.c 프로젝트: MajoraBora/CoolBoy
void updateGraphicsTest(struct gameboy * gameboy)
{
	//fill a frame buffer with some simple pixel data and see if it draws correctly
	setLCDStatus(gameboy);
	uint8_t previousMode = getCurrentMode(gameboy);
	requestAnyNewModeInterrupts(gameboy, previousMode);
	if (isLCDEnabled(gameboy)){
		gameboy->screen.scanlineCounter += gameboy->cpu.previousInstruction.cycles;
	}
	else {
		return;
	}
	
	if (gameboy->screen.scanlineCounter >= SCANLINE_CYCLE_TIME){
		gameboy->screen.currentScanline++;
		gameboy->screen.scanlineCounter = 0;
		if (gameboy->screen.currentScanline == Y){
			requestInterrupt(gameboy, int_vblank);
			//printf("start vblank\n");
		}
		else if (gameboy->screen.currentScanline > (Y + NO_OF_INVISIBLE_SCANLINES)){
			gameboy->screen.currentScanline = 0;
			//printf("resetting scanline\n");
		}
		else if (gameboy->screen.currentScanline < Y){
//			printf("drawing scanline %d\n", gameboy->screen.currentScanline);
			drawScanline(gameboy);
		}
		else {
			//printf("In vblank\n");
		}
	}
	
}
예제 #2
0
파일: Video.cpp 프로젝트: PZerua/GameVoid
void Video::updateGraphics(const int &cycles, CPU &cpuTemp)
{
	setLCDStatus(cpuTemp);

	if (isLCDEnabled())
		_scanLineCounter -= cycles;
	else
		return;

	if (_scanLineCounter <= 0)
	{
		// time to move onto next scanline
		_memory->directModification(LY, _memory->read(LY) + 1);
		BYTE currentline = _memory->read(LY);

		_scanLineCounter = 456;

		// we have entered vertical blank period
		if (currentline == 144)
			cpuTemp.requestInterrupt(VBlank);

		// if gone past scanline 153 reset to 0
		else if (currentline > 153)
			_memory->directModification(LY, 0x00);

		// draw the current scanline 
		else if (currentline < 144)
			drawScanLine();
	}
}
예제 #3
0
파일: lcd.c 프로젝트: MajoraBora/CoolBoy
void updateGraphics(struct gameboy * gameboy)
{
	int cycles = gameboy->cpu.previousInstruction.cycles;
	uint8_t previousMode = getCurrentMode(gameboy);
	setLCDStatus(gameboy);
	requestAnyNewModeInterrupts(gameboy, previousMode);
	doCoincidenceFlag(gameboy);
	if (isLCDEnabled(gameboy)){
		gameboy->screen.scanlineCounter += cycles;
		doScanline(gameboy);
	}
}
예제 #4
0
파일: lcd.c 프로젝트: MajoraBora/CoolBoy
void setLCDStatus(struct gameboy * gameboy)
{
	//it take 456 clock cycles to draw 1 scanline
	//LCD status is in mode 2 for the first 80 (search sprite attrs)
	//Mode 3 is set for the next 172 (transfer to LCD driver)
	//The remaining 204 are for mode 0 (hBlank)

	//When the status mode is changed to 0, 1 or 2, an interrupt request occurs
	//Check bit 3, 4, or 5 to see if mode interrupt 0, 1 or 2 is enabled
	//when the lcd mode is disabled, the status mode must be set to 1
	if (!isLCDEnabled(gameboy)){
		//starting a new scan line sets the lcd status to 2
		//printf("LCD isn't enabled - starting new scanline\n");
		startNewScanline(gameboy);
	}
	else {
	//	printf("LCD is enabled\n");
		if (isInVBlankBounds(gameboy)){
			//printf("Handle vblank\n");
			handleVBlank(gameboy);
		}
		else if (isInSpriteAttributeBounds(gameboy)){
			//printf("Handle OAM\n");
			handleSpriteSearch(gameboy);
		}
		else if (isInDriverTransferBounds(gameboy)){
			//printf("handle transfer\n");
			handleTransferToLCDDriver(gameboy);
		}
		else {
			//printf("handle hblank\n");
			handleHBlank(gameboy);
		}
		
	}

}
예제 #5
0
파일: Video.cpp 프로젝트: PZerua/GameVoid
void Video::setLCDStatus(CPU &cpuTemp)
{
	BYTE status = _memory->read(0xFF41);
	if (!isLCDEnabled())
	{
		// set the mode to 1 during lcd disabled and reset scanline
		_scanLineCounter = 456;
		_memory->directModification(LY, 0x00);
		status &= 0xFC;
		status = bitSet(status, 0);
		_memory->write(0xFF41, status);
		return;
	}

	BYTE currentline = _memory->read(LY);
	BYTE currentmode = status & 0x03;

	BYTE mode = 0x00;
	bool reqInt = false;

	// If is greater we are in VBLank period
	if (currentline >= 144)
	{
		mode = 0x01;
		status = bitSet(status, 0);
		status = bitReset(status, 1);
		reqInt = testBit(status, 4);
	}
	// Else, we are drawing scanlines in panel
	else
	{
		int mode2bounds = 456 - 80;
		int mode3bounds = mode2bounds - 172;

		// mode 2
		if (_scanLineCounter >= mode2bounds)
		{
			mode = 0x02;
			status = bitSet(status, 1);
			status = bitReset(status, 0);
			reqInt = testBit(status, 5);
		}
		// mode 3
		else if (_scanLineCounter >= mode3bounds)
		{
			mode = 0x03;
			status = bitSet(status, 1);
			status = bitSet(status, 0);
		}
		// mode 0
		else
		{
			mode = 0x00;
			status = bitReset(status, 1);
			status = bitReset(status, 0);
			reqInt = testBit(status, 3);
		}
	}

	// just entered a new mode so request interupt
	if (reqInt && (mode != currentmode))
		cpuTemp.requestInterrupt(LCD);

	// check the conincidence flag
	if (_memory->read(LY) == _memory->read(LYC))
	{
		status = bitSet(status, 2);
		if (testBit(status, 6))
			cpuTemp.requestInterrupt(LCD);
	}
	else
	{
		status = bitReset(status, 2);
	}
	_memory->write(0xFF41, status);
}