What's new

Game Boy

zenogais

New member
refraction said:
doin a good job guys :) i wish i was as far as some of you! but my emulator ive not even started doing cpu ops yet! but i did give zenogais a bit of a hand the other night, most of it was pretty easy to understand but some are quite baffling!

isnt it fun doing opcodes from 0x40ish to about 0x60? :p

meh, you're as bad a linuzappz I swear, I had to go through a run cleanup after you sent me what you had last night :p But thanks! :)

I've now worked through to about 0x7F.
 
Last edited:

aprentice

Moderator
refraction said:
doin a good job guys :) i wish i was as far as some of you! but my emulator ive not even started doing cpu ops yet! but i did give zenogais a bit of a hand the other night, most of it was pretty easy to understand but some are quite baffling!

isnt it fun doing opcodes from 0x40ish to about 0x60? :p

The load opcodes are the easiest, just lots of copy and pasting :p

edit: Just finished emulating the battery pack, works like a charm
edit2: Just added save/load states, took only 5 mins, so damn easy :p
 
Last edited:

bcrew1375

New member
Man, you're really kicking my arse :p.

Edit: Dooooooooooooooooooooooooooooohhhhhhhhhhhhhhhhhhhhhhhhhhh!!!!!!!!!!!!!!!!!!!! I figured out my sprite problem. After trying everything else, I noticed I hadn't implemented the DMA register -_-.
 
Last edited:

aprentice

Moderator
bcrew1375 said:
Man, you're really kicking my arse :p.

Edit: Dooooooooooooooooooooooooooooohhhhhhhhhhhhhhhhhhhhhhhhhhh!!!!!!!!!!!!!!!!!!!! I figured out my sprite problem. After trying everything else, I noticed I hadn't implemented the DMA register -_-.

Hehe, good luck on your sprites problem, if you have any questions, im here :p

Also, on the side note, does your zelda go in game? When i try leaving the house (starting point), the game freezes. I dunno if its a bug in mbc1 or interrupts, everytime i mess with both of these factors, compat increases, but im running out of ideas :p
 
Last edited:

bcrew1375

New member
I used to be able to go out of the house and walk around the town with distorted graphics, but now that I've repaired some opcodes, I can't get past name registration. I have a feeling that's it's not the MBC, but some minor bugs in the CPU core.

Edit: Well, Tetris now works flawlessly, except I still haven't implemented the DAA instruction. Would you be so kind as to to tell me the formula you used, aprentice :blush:?

Edit 2: Another thing. Is there any purpose at all to the H and N flags? I haven't seen a single thing that makes use of them.
 
Last edited:

refraction

PCSX2 Coder
i dont know if people have noticed or not but ill just give this as a warning

The gameboy has 2 sets of general purpose registers, one basically an alternate set of the other, like if you look at this opcode

LD C, C' <-- the C register is one of the main ones and C' is the alternate set, as i looked at that and thought it was a pointless cpu op but it does make sense if you have the alternate registers!!!

altho im not sure if its just mirrored after every cpu operation or what.
 

aprentice

Moderator
bcrew1375 said:
I used to be able to go out of the house and walk around the town with distorted graphics, but now that I've repaired some opcodes, I can't get past name registration. I have a feeling that's it's not the MBC, but some minor bugs in the CPU core.

Edit: Well, Tetris now works flawlessly, except I still haven't implemented the DAA instruction. Would you be so kind as to to tell me the formula you used, aprentice :blush:?

Edit 2: Another thing. Is there any purpose at all to the H and N flags? I haven't seen a single thing that makes use of them.

H and N are used when the AF register is used in opcodes :p

This is what i used for DAA, but I dont know if its correct, its probably wrong :p

int hi=(regA>>4)&0x0F;
int lo=(regA)&0x0F;
regA=(hi*10)+lo;

Do you emulate the HALT instruction? I dont have it emulated and I'm not exactly sure how to "correctly" approach it.
 
Last edited:

zenogais

New member
aprentice said:
H and N are used when the AF register is used in opcodes :p

This is what i used for DAA, but I dont know if its correct, its probably wrong :p

int hi=(regA>>4)&0x0F;
int lo=(regA)&0x0F;
regA=(hi*10)+lo;

Do you emulate the HALT instruction? I dont have it emulated and I'm not exactly sure how to "correctly" approach it.

Well, right now what I'm doing is throwing an exception, and then later down the line the exception is caught and the body of the exception handling code loops until an interrupt occurs. I'm not sure quite sure how this'll work, I'll tell you when I have a completed CPU core.
 
Last edited:

bcrew1375

New member
I've basically got two variables called 'halted' and 'stopped', which I turn on when either command is executed. I then stop executing opcodes until a interrupt occurs for halted, or a button is pressed for stopped.
 

aprentice

Moderator
bcrew1375 said:
I've basically got two variables called 'halted' and 'stopped', which I turn on when either command is executed. I then stop executing opcodes until a interrupt occurs for halted, or a button is pressed for stopped.

how are you making the cpu idle until an interrupt occurs?
 
Last edited:

bcrew1375

New member
Basically, doing "if (!halted) { *execute opcode* } I'm still using the giant switch statement, so before I get an opcode, I check to see if the CPU is halted or stopped.
 

zenogais

New member
Hmm, how are you guys detecting carry's and half-carry's, because I dunno, doesn't seem like I'm doing this right.

EDIT: Whoops. Basically this is what I'm doing now:

Code:
void GBProcessorZ80::INC_R()
{
	byte value = 0;

	switch( opcode )
	{
	case 0x34:
		{
			value = readMemory8( registers[0].wds.HL ) + 1;
			writeMemory8(registers[0].wds.HL, value);
		}
		break;
	default:
		{
			opcode >>= 3;
			*(registers8[opcode])++;
		
			value = *registers8[opcode];
		}
		break;
	}

	if((value&0xF) == 0)
		SET_FLAG   ( GAMEBOY_FLAG_H );
	CLR_FLAG       ( GAMEBOY_FLAG_N );
	CHECK_ZERO_FLAG( value );
}

void GBProcessorZ80::DEC_R()
{
	byte value = 0;

	switch( opcode )
	{
	case 0x35:
		{
			value = readMemory8( registers[0].wds.HL ) - 1;
			writeMemory8(registers[0].wds.HL, value);
		}
		break;
	default:
		{
			opcode >>= 3;
			*(registers8[opcode])--;

			value = *registers8[opcode];
		}
		break;
	}

	if((value&0x0F) == 0x07)
		SET_FLAG   ( GAMEBOY_FLAG_H );
	CLR_FLAG       ( GAMEBOY_FLAG_N );
	CHECK_ZERO_FLAG( value );
}
 
Last edited:

aprentice

Moderator
Basically HALF CARRY is set when bit 3 carries into bit4, and CARRY is set when bit 7 carries into bit 8.

Half carry if value > 15
Carry if value > 255

So for INC it would basically be:

if ((reg&0xF)+1) > 15 set half carry

Since op INC wraps, carry flag isnt affected.

Edit: your code looks like it works, I didn't take the time to actually look at it when I originally posted.
 
Last edited:

aprentice

Moderator
I can't seem to get interrupts working right, has anyone had any success with them? If i attempt to execute interrupts on a per op basis it breaks some games, if I attempt to execute interrupts on a per frame basis more games work, but the compat still sucks. If anyone has a method they'd like to share, please do ;P
 

aprentice

Moderator
sethmcdoogle said:
Check gnuboy's source? It's an open-source GB emulator. Maybe look how they handle it? http://gnuboy.unix-fu.org/

Source code doesn't help if you dont know where the source is comming from and if you consider the interrupt system being a large portion of the system, it's not easy to follow in other emulators source codes. It would mean more to me if someone explained it :p
 

bcrew1375

New member
I've been generating interrupts based on the number of cycles executed. I have a counter for the H-Blank and the Timer that holds the number of cycles it takes for a H-Blank or Timer update to occur. Everytime an instruction is executed, I subtract the number of cycles it used from the counter. When the counter hits <= 0, I call a function that updates the I/O registers. Then I reset the counters. When LY hits 144, I generate a V-Blank interrupt. I can't be sure, but I don't seem to be having any trouble with mine.
 

aprentice

Moderator
bcrew1375 said:
I've been generating interrupts based on the number of cycles executed. I have a counter for the H-Blank and the Timer that holds the number of cycles it takes for a H-Blank or Timer update to occur. Everytime an instruction is executed, I subtract the number of cycles it used from the counter. When the counter hits <= 0, I call a function that updates the I/O registers. Then I reset the counters. When LY hits 144, I generate a V-Blank interrupt. I can't be sure, but I don't seem to be having any trouble with mine.

so the compat in your emu is generally good?
 

bcrew1375

New member
Well, I get some kind of result from just about any game(even though they're not always good. :p). I can't tell you if it's the best way. It's just the way I'm doing it.
 

Top