What's new

Game Boy

Cyberman

Moderator
Moderator
I've noticed a lot of Comp Sci programs have been over emphasizing Java I've noticed. It's rather pathetic since this is mostly due to sheer laziness on the teachers part. They stopped teaching many 'older' languages in favor of 'newer' languages. This is quite flawed especially since the majority of computers today aren't PC's and aren't part of a internet based system. Java may be seen on some platforms with Jazel acceleration or other forms but in general it's not in more common things such as joysticks USB drivers and such (yes those are all computers these days).

Erstwhile looks like you've made progress for 2 days. So .. you don't like Java I take it? Well if anything being able to use it is important for some things. I prefer ye olde C/C++ (although I don't like windows programming admitedly). I'm use to building something from the ground up (like a game boy advance game would be). Having a bios is a bit novel to me even.

So back to the game boy. What do you plan to do with the final results? I wonder if one could make a web based emulator that stored game scores etc in a sort of competition type thing. IE GB tomb raider game etc. :D

Cyb
 

ShizZy

Emulator Developer
I agree... And yes, not a fan of Java haha. I made a few fixes with Big Scroller Demo but am not too motivated to mess around with it too much more... I'll post the source if anyone wants to take a look, Java is soo sloppy haha. Who knows tho.. just really need to work on my other projects :)
 

Stig

New member
Blog of Programming a Gameboy Emulator

Hi I'm developing a Gameboy Emulator and I've started doing a Blog to log all the work. I just wanted to share in case is useful to anyone.

As I read this post I saw a couple of questions that might be answered in my blog. So I'd like to help if possible.

I have some work done already, but I've only created the blog today. I've already posted 5 topics and expect to be very active adding details of the rest that has been done and then I'll continue with regular work logs as I improve the emulator.

It's important to know that this is the first emulator I've ever started from scratch, so many things could be done in better ways. I think, however, that the information could help anyone who is just starting, so they have a place to start and to look for those special details that nobody talks about that keeps you stucked for a while when starting.

The link is: http://emulearn.blogspot.com/

Thanks for reading,

Stig.
 

CodeSlinger

New member
Hi Stig,

I agree that it is incredibly difficult for a newcomer to get to grips with emulator programming. I also had the idea of starting writing development documentation for specific consoles to help with the learning curve.

My site can be found here http://www.codeslinger.co.uk and shows how to emulate the chip8, gameboy and sega master system.

It also goes through sound emulation for the master system. The site isnt finished yet, but shouldnt be too far off. I am by no means an emulation wizard and my site will also have information that could be improved on. Infact as you read the tutorials it can be easily seen how much I have learnt from when I wrote my first one (chip8) to the last (master system).

Hopefully both our sites can help in the emu scene.
 

Stig

New member
Hi CodeSlinger,

Thanks for sharing! It would have been awesome to have that like two weeks ago!! But nevertheless it will help me out with the stuff I still have left to do. Like the sound emulation.. I've never done any program to create sound so I really have no clue as how to do that, yet. But well.. I didn't knew a lot of things a while ago and they are working like a charm now :).

Anyway.. I gave quick look and it seems quite good. A lot more organized than my blog, probably because I didn't want to use my time setting up a site and wanted to start writting right away. I will look at it in more detail other day as I have my final presentation and report for my work as summer student tomorrow (I'm from Chile so it's summer now).

Bye!
 
Last edited:

olejl

New member
Another Gameboy emulator

I'm also writing a Gamboy emulator. Manly to learn about emulators and programming. For now I have only one question.

bug.png


This is from a PD ROM called test.pd. I have compared my output from the output of other emulators, and there is a difference when running the Text Demo. In text line 8 and 9, my emulator shows the numbers 234 and 490. Other emulators show 234 on both lines. Does anyone know what could cause that? Is there a description of this ROM anywhere, which explains what it is testing?
 

srastol

New member
Hey guys, having some trouble here with DAA opcode. The point is, what's the problem with doing something like,

F &= NF;
F |= ( A > 99 )? CF : 0;

if( !( F & NF ) ) // Positive
A = ( ( A / 10 ) % 10 ) << 4 | ( A % 10 );
else
// ...

F |= ( A == 0 )? ZF : 0;

Optimization discussions apart (divisions do not come for free), this seems to do the trick. None of the pieces of code I've seen along this thread seem to work properly at all. For instance, let's take aprentice's one for the case of A being +16 (0001 0000). Here "(regA&0x0F)>9" does not hold, so "regA+=0x06" does not apply. Similarly, "((regA&0xF0)>0x90)" does not hold, so at the end A keeps being 16 (0001 0000), that is, the BCD result turns to be 10, which is obviously wrong.

I'm still missing what the role of H flag is in this process. All implementations for this opcode seem to have it into account, but I cannot understand why. Even more, what would be the result of the process if flag C were set? Would you mind exposing the whole process to the details here?

By the way, does anyone have a copy of the official LR35902 (GBx CPU) datasheet? It seems to have disappeared from the net.. I cannot find a working link on the net..

Thanks!
 
Last edited:

icepir8

Moderator
Hey guys, having some trouble here with DAA opcode. The point is, what's the problem with doing something like,

The DAA opcode can be hard to understand.

Optimization discussions apart (divisions do not come for free), this seems to do the trick. None of the pieces of code I've seen along this thread seem to work properly at all. For instance, let's take aprentice's one for the case of A being +16 (0001 0000). Here "(regA&0x0F)>9" does not hold, so "regA+=0x06" does not apply. Similarly, "((regA&0xF0)>0x90)" does not hold, so at the end A keeps being 16 (0001 0000), that is, the BCD result turns to be 10, which is obviously wrong.

I'm still missing what the role of H flag is in this process. All implementations for this opcode seem to have it into account, but I cannot understand why. Even more, what would be the result of the process if flag C were set? Would you mind exposing the whole process to the details here?

The H flag is the half-carry set/cleared by Addtion or Subtraction operations on the A register.

example: adding 0x09 to 0x06 results in a value of 0x0f and the H flag is clear.
and adding 0x09 to 0x07 results in a value of 0x10 and the H flag set.

Now the DAA operation looks at the H flag and if it is set adds 0x06 to the value.
so the final result is 0x16 instead of 0x10.

I hope this helps.

Cheers!
Icepir8
 

srastol

New member
example: adding 0x09 to 0x06 results in a value of 0x0f and the H flag is clear.
and adding 0x09 to 0x07 results in a value of 0x10 and the H flag set.

Now the DAA operation looks at the H flag and if it is set adds 0x06 to the value.
so the final result is 0x16 instead of 0x10.

Now, if I just load a value into A and immediately after request a DAA to turn it into BCD, being that H has not been changed with the load, would I get proper results?

S.
 

icepir8

Moderator
Now, if I just load a value into A and immediately after request a DAA to turn it into BCD, being that H has not been changed with the load, would I get proper results?

S.

not everytime. only when the value of a is in the range of 0x00 to 0x0f.

the DAA only works correctly after a Addition or Subtraction from A reg.

btw if the C flag is set DAA adds 0x60 to A.
 

srastol

New member
not everytime. only when the value of a is in the range of 0x00 to 0x0f.

the DAA only works correctly after a Addition or Subtraction from A reg.

Huh.. that's weird. If DAA is suposed to turn A into a BCD number, it should do it always, not only under certain conditions. I mean, that's not a serious design..

Just imagine you have a score counter that you must render each frame. You turn that value into BCD, for some reason, and then output it. Now, that value may not change every frame, so for some cases you'll have to do something like,

toBCD( score-1+1 )

to get a proper value. That sounds weird to me, or I'm just missing the purpose of the opcode itself. Is current knowledge about DAA based on official documentation? Or just on test-error testing? Has this behavior been observed and tested on the real thing?

Thanks.

S.
 

icepir8

Moderator
The DAA operation is not to convert the value in A to BCD but to addjust the results so that you can do BCD math. If you didn'r have the DAA opcode you would have to do the math 4bits at a time.
 

srastol

New member
The DAA operation is not to convert the value in A to BCD but to addjust the results so that you can do BCD math. If you didn'r have the DAA opcode you would have to do the math 4bits at a time.

Seen this way it makes sense. I've seen this same observation on a z80 tech site a few minutes ago, so I guess the doubt's been cleared.

Thanks dude!
 

icepir8

Moderator
No Problem

Code:
Detailed info DAA
Instruction Format:
OPCODE                    CYCLES
--------------------------------
  27h                       4


Description:
This instruction conditionally adjusts the accumulator for BCD addition
and subtraction operations. For addition (ADD, ADC, INC) or subtraction
(SUB, SBC, DEC, NEC), the following table indicates the operation performed:

--------------------------------------------------------------------------------
|           | C Flag  | HEX value in | H Flag | HEX value in | Number  | C flag|
| Operation | Before  | upper digit  | Before | lower digit  | added   | After |
|           | DAA     | (bit 7-4)    | DAA    | (bit 3-0)    | to byte | DAA   |
|------------------------------------------------------------------------------|
|           |    0    |     0-9      |   0    |     0-9      |   00    |   0   |
|   ADD     |    0    |     0-8      |   0    |     A-F      |   06    |   0   |
|           |    0    |     0-9      |   1    |     0-3      |   06    |   0   |
|   ADC     |    0    |     A-F      |   0    |     0-9      |   60    |   1   |
|           |    0    |     9-F      |   0    |     A-F      |   66    |   1   |
|   INC     |    0    |     A-F      |   1    |     0-3      |   66    |   1   |
|           |    1    |     0-2      |   0    |     0-9      |   60    |   1   |
|           |    1    |     0-2      |   0    |     A-F      |   66    |   1   |
|           |    1    |     0-3      |   1    |     0-3      |   66    |   1   |
|------------------------------------------------------------------------------|
|   SUB     |    0    |     0-9      |   0    |     0-9      |   00    |   0   |
|   SBC     |    0    |     0-8      |   1    |     6-F      |   FA    |   0   |
|   DEC     |    1    |     7-F      |   0    |     0-9      |   A0    |   1   |
|   NEG     |    1    |     6-F      |   1    |     6-F      |   9A    |   1   |
|------------------------------------------------------------------------------|


Flags:
C:   See instruction.
N:   Unaffected.
P/V: Set if Acc. is even parity after operation, reset otherwise.
H:   See instruction.
Z:   Set if Acc. is Zero after operation, reset otherwise.
S:   Set if most significant bit of Acc. is 1 after operation, reset otherwise.

Example:

If an addition operation is performed between 15 (BCD) and 27 (BCD), simple decimal
arithmetic gives this result:

    15
   +27
   ----
    42

But when the binary representations are added in the Accumulator according to
standard binary arithmetic:

   0001 0101  15
  +0010 0111  27
  ---------------
   0011 1100  3C

The sum is ambiguous. The DAA instruction adjusts this result so that correct
BCD representation is obtained:

   0011 1100  3C result
  +0000 0110  06 +error
  ---------------
   0100 0010  42 Correct BCD!
 

initech

New member
Quick question about the GameBoy CPU manual. I just want to confirm that the "#" parameter is a signed immediate byte. Is that correct?

Also, for operations like ADD which accept a signed value, should the carry flags be set on both borrow and overflow conditions?

I'm currently writing an emulator in C. I have the CPU almost completed (except those signed operations, which will really make things messy). I have cobbled together an interrupt system for the three main interrupts (VBLANK, TIMR and DIV). Most of the ROMs I run through it spin on the higher registers while waiting for the display to become ready (which I haven't programmed yet).
 
Last edited:

icepir8

Moderator
The parity/overflow flag - which has two uses; the parity part we'll see later. In dealing with addition and subtraction an overflow occurs if an operation causes a result larger than can be represented in twos complement, i.e. something less than -128 or more than 127. So 127 + 1 or -128 - 1 would both cause overflows.

In other word if the carry out from bit 7 is not the same as the carry into 7 then the overflow flag is set.

I hope that this helps you understand what the overflow flag does.
 

initech

New member
Thanks icepir8.

I spent a while debugging today only to find out that when a word is pushed to the stack, the most significant byte must be pushed before the least significant. I was doing it the other way around which caused problems. After figuring that out my emulator is showing signs of life:

qz28f8.gif


What ROMs do you suggest for testing and debugging? I am using Tetris, the big scroller, and the PD test ROM.
 
Last edited:

srastol

New member
Hey icepir8

I may be missing something, but I think aprentice's code is still not doing right. Just look at this case, being all flags clear and A=0x0A. According to the table you posted, "numer added to byte" should be 0x06, but for aprentice's code,

Code:
void op0x27() //DAA 
{ 
   if(regF&0x40) //Negative Flag Set 
   { 
      if((regA&0x0F)>0x09 || regF&0x20) 
     { 
        regA-=0x06; //Half borrow: (0-1) = (0xF-0x6) = 9 
        if((regA&0xF0)==0xF0) regF|=0x10; else regF&=~0x10; 
     } 

     if((regA&0xF0)>0x90 || regF&0x10) regA-=0x60; 
   } 
   else 
   { 
       if((regA&0x0F)>9 || regF&0x20) 
       { 
           regA+=0x06; //Half carry: (9+1) = (0xA+0x6) = 10 
           if((regA&0xF0)==0) regF|=0x10; else regF&=~0x10; 
        } 

        if((regA&0xF0)>0x90 || regF&0x10) regA+=0x60; 
    } 

    if(regA==0) regF|=0x80; else regF&=~0x80; 
}

it turns to be 0x66. The problem I see on his code is that flags are being updated while results are still being computed. As far as I understand the opcode, flags should be updated after the amount to be added/substracted has been dedided.

Just wanted to know what you think about that.

By the way, I've got absolutely nothing against aprentice :p I'm just testing his code cause it seems several of you are using it in your emus.

Thanks again.

S.
 

Top