What's new

Chip 8

Danny

Programmer | Moderator
I have worked real hard over the last week with the emulator.

The controls now work great with every game that was tried.

There have been various other bugfixes too.

More roms now work, tetris being one.

Source code is released under the gpl licence (i think) and is included in the zip file.

Next release will see a filebrowser and a speed up and some games are running a bit slow.

Thanks :)

Comments appricated ;)
 

Danny

Programmer | Moderator
yeah i need to speed up the drawing routine as its not full speed on the psp yet :p
 

Danny

Programmer | Moderator
Dreamchip v4.0 for linux

I just changed my os to ubuntu linux (edgy) v6.11 so i decided to apply the opimisations i made for the psp version (faster drawing) and make it for linux :)

Ive included the binary and source, need to implement a frame limiter into the linux version. psp version is running at around 65% speed.

enjoy :p i hope this can bring some life back into this thread ;)
 

Kronox!

New member
I hope that too. Once again i got hooked into emulation and coding, now i'm back with a little more understanding on the lang and currently writing a chip8 emu. I undertand the basic layout for the CPU and currently have all the opcodes necessary to emulate the Chip8 [Schip not yet]. But i feel a little dumb 'cause i'm looking at Aprentice's source from time to time [and i feel like a cheater xD] but that's not the point.. the point is.. I really don't understand how i can get the CPU loop running and more important i don't know how to do graphics routines so.. even if i understand what the opcodes do, i can't get my emu to show anything..

Is there any simple way to achieve graphics?
how do i set the CPU loop? I mean to read the opcodes and do the decoding process...

^^ Like you see i'm a newby [not only in coding, but in eglish writing as well] can you can give me a hand or push me in the right direction please?

thanks.. I now emulation it's not a simple task but i wanted a challenge[and i got one xD] [Btw Logical operators, pointers,shifting and all the stuff for opcodes are not issues atm][but not knowing how to set a drawing routine is really dissapointing..

Thanks in advance

Kronox
 
Last edited:

Garstyciuks

New member
To get your emulation loop running, you need to load a chip8 ROM into your RAM, starting at adress 0x0200 (first 512 bytes are reserved for interpreters, and they are generally unused by emulators. I personally use some of those bytes for storing font data). Then you should start executing the ROM at adress 0x0200. If you think that your drawing code is OK, then do a little debuging and test out if all the arguments for the drawing opcode are alright, check out what image data I register points to. When I first was programming my emulator, I had forgotten to redraw my emulation screen and I didn't get any video data from my emulator. So you should also check your interface code :) I have attempted to explain the drawing opcode here. The code there isn't really good, I have reprogrammed my emulator, but haven't posted the code anywhere yet. The explanations might help you in some way. I'm using 128x64 vram array (I set 2x2 rectangles for chip8 pixels in chip8 video mode), to keep compatibility with schip games.
 
Last edited:

Kronox!

New member
Thanks for the quick answer.
Even if i understand what you said about the starting adress and rom loading, i still can't figure how i can write it in code.

As for the drawing routine, thanks... the answer was exactly the same you gave me the last time xD but now i'm a little more mature in coding and i understand how to implement it with my own variables now^^ [thanks 'bout that]

If you can show me an example to set up
A) the main loop --> dunno if i have to use Do, For or other ciclic task operator..
and B) memory set up in 0x0200 T_T --> sorry if i'm asking newby questions, but i don't know what else to do..

Thanks for your time once again

Kronox
 

Garstyciuks

New member
This is my LoadRom function:

Code:
FILE *pFile;
pFile = fopen(rom,"rb");
int size;
fseek(pFile, 0, SEEK_END);
size = ftell(pFile);
fseek(pFile, 0, SEEK_SET);
fread(&mem.memory[rom_base], size, 1, pFile);
fclose(pFile);

cpu.flags |= CPU_FLAGROMLOADED;

rom is a const char *, it is the file name of the rom, given to the function as a parameter. rom_base is initialized to 0x200 when the application is initialized. cpu is a class for emulating all the opcodes. The flags part is only used inside my emulator, to specify specific states of my emulator. And this is my "main loop", it's in idle event of wxWidgets:

Code:
for ( int i = 0; i < 30; i++ ) chip8.Step();

if ( chip8.ShouldRedraw() )
{
	SDL_Rect rt;

	rt.x = 0;
	rt.y = 0;
	rt.w = 128 * iSize;
	rt.h = 64 * iSize;
	SDL_FillRect( screen, &rt, 0x00000000 ); //clear the screen

	rt.w = iSize;
	rt.h = iSize;
	for ( int j = 0; j < 64; j++ )
	{
		for ( int i = 0; i < 128; i++ )
		{
			rt.x = i*iSize;
			rt.y = j*iSize;
			if ( chip8.mem.vram[ j ][ i ] ) SDL_FillRect( screen, &rt, 0x00FFFFFF );
		}
	}
}

iSize is an integer, which stores the setting of pixel size. It can either be 1, 2, 3 or 4. chip8.Step() function executes 1 opcode. chip8.ShouldRedraw() returns true if a draw sprite opcode (0xDXYN) was executed since ShouldRedraw() was last called. This helps to save some of the CPU usage from having to redraw every time. And in for ( int i = 0; i < 30; i++ ), 30 is a number that I came up with. The emulation is too slow if you execute 1 opcode per one idle event, so I execute 30 opcodes per idle event. This is a big hack, but I haven't come up with any better way of timing using wxWidgets. If anyone knows a better way to do timing with wxWidgets, then I would be glad to hear about it. :)
 

smcd

Active member
Mine looks something like this:
Code:
int main()
{
	initcpu();
	loadRom("pong.ch8");
	while(1)
	{
		cpu_cycle();
		Sleep(250); // this is a really really bad way to do things
	}
	return 0;
}
 

Exophase

Emulator Developer
And in for ( int i = 0; i < 30; i++ ), 30 is a number that I came up with. The emulation is too slow if you execute 1 opcode per one idle event, so I execute 30 opcodes per idle event. This is a big hack, but I haven't come up with any better way of timing using wxWidgets. If anyone knows a better way to do timing with wxWidgets, then I would be glad to hear about it. :)

I haven't used wxWidgets, but I looked into it some..

From what I could find on the idle events there's nothing to indicate that it's ran at a fixed interval of time. It could very well depend on where it's being ran, and you don't want that. Actually, what appears to be happening is that the idle event is being called constantly so long as there are no other events, which you also don't want to base timing off of.

Looking further I found this:

http://www.wxwidgets.org/manuals/stable/wx_wxupdateuievent.html

It appears you can setup an event which does go off at a given interval, which is exactly what you want.

30 is a pretty arbitrary number indeed, and in this case, a pretty small one. What you should do is pick a frame rate then set the timer around that. Something around 16 or 32Hz would be good, then you'd have say, 31-33ms intervals for the timer event. Here you would run N instructions - whatever N is will determine the clock speed. Chip8 doesn't have an actual clock speed, but something around 512KHz or higher should be far more than sufficient (especially considering it'd be executing one instruction per clock cycle, which was unheard of for processors of that day). For 32Hz updates, that'd mean 16384 instructions processed per screen update. You could use lower values, of course, but too low and the emulation will become slower or fail outright.

As far as I remember from chip8, the timing is more regulated by input than by video, so actual timing "accuracy" is probably not that important, but even vast inconsistency in screen updates might end up being noticeable.

By the way, since this thread is on the topic of timing again, I wanted to address something that I meant to almost a year ago but never did:

What bcrew1375 said is wrong, because: say that your PC is able to execute two times faster than your desired intructions per second, and as soon as the emulator finishes executing your desired instructions/sec, it will halt and wait until that second is passed, which will cause a desynchronization on timing.(The emulator will execute the instructions/sec under half of the second, which will cause the emulator to double the desired speed on by half a second, but the other half will just wait until the other second, and that's not what you want).

Secondly, 100 instructions per second is too slow, try 500~800.


Let's say you want to execute 1,000 instructions per second, then, after EACH instruction, you will have to wait until 1 millisecond has passed before executing the next instruction.


Time should be checked on every instruction(if you want it to be as accurate as specified), not every second.

I'm quoting this now because looking over things (including the most recent example) I see a lot of people falling into this dangerous line of thinking.

First, you really can't synchronize per instruction, for anything with realistic operating speeds. Precision and accuracy for timers is just too low, and the overhead to calling the timers alone would give you a big additional cost.

Second, there's no reason at all to do so. When emulating a machine, what's most important is first and foremost keeping the virtual time of the machine in order. What this means is that internal events should occur in the correct order relative to each other; everything is synchronized properly to an internal clock. For Chip8 this doesn't really apply because there aren't internal events (least of all interrupt causing ones), but for almost any real platform it would. Keeping virtual time consistent has nothing to do with keeping consistency with real time.

When it comes to emulating a machine, the only way a user can determine if it's running at correct speed or not is by observing that machine's external output. All machines are limited in how much external output they can display per unit time: by refresh rate (maybe per scanline), audio frequency, and so forth. Audio in particular is timed correctly by the hardware of the platform you emulate on, so the only thing that becomes an issue is minimizing latency, where you have a much bigger window than frequency (which is why audio buffers are larger than one sample). These operating intervals are on the order of Hz, not the KHz or MHz ranges that internal intervals may run at.

And even if the device's output rate wasn't the limiting factor human perception would be. As humans we certainly do not perceive things higher than in the Hz ranges, change something too rapidly and it blurs together (hence interleaving on displays and why pulse width modulation works for audio output), change timing slightly and people won't even be able to notice. So long as it catches up in the end (global time consistency) it really doesn't matter much.
 
Last edited:

Kronox!

New member
thanks as well. This weekend (when i have some time to spare) i'm going to work on my emu. Thanks for all the help guys... see you around

Kronox
 

givemeachance

New member
Hi all ! , im a new member , so dont bite me :)!

Im new into this subject(emulation) , and i have some questions to ask! , please
answer some of them when you find some time.

...ready? .. lets go !


1)I really wanna know , how does an emulator works!
I mean , when you load a rom into memory , then what checks you do?


2)How can i read a command set from a memory location?
and how can i edit it?


3)How do you load a rom file into memory?
and what's in the file ? commands ? i dont get it!


4)In the main loop what checks you do ????



I've programmed 2 mini games in c++ and opengl , so , i'll program the emulator in c++ , and
opengl as graphic api.


Waiting for your support!


thanks!
 

Doomulation

?????????????????????????
1)I really wanna know , how does an emulator works!
I mean , when you load a rom into memory , then what checks you do?
What checks do you do? That's really up to you. If it's a game, then it contains instructions (and possibly, in case of others systems, a header, but chip8 does not).

2)How can i read a command set from a memory location?
and how can i edit it?
Just read the entire file and fill it up in an array of memory set to the amount of bytes the chip8 memory consists of. Then, should you want to read/edit/do whatever at local 0x?, then just read/do whatever at your array at position 0x?.

3)How do you load a rom file into memory?
and what's in the file ? commands ? i dont get it!
Just dump the contents of the file into memory. All of it. Read every byte and put it into the emulator's memory - the image consists of instructions, data specific to the game, and optionally (though not on chip8), a header.
Nevertheless, it's all loaded into memory - the entire file.

4)In the main loop what checks you do ????
In the main loop, you'll read 2 bytes, interpret the instruction and execute it, optionally redraw the screen (can also be done after a draw command), check delay timers and beep if 0, store key input and repeat.
That's what I can remember on top of my head anyway.

If you really have no idea how it works, then there's many open source chip8 emulator out there that you can study to get the idea.
 

d0u6

New member
I'm finishing my chip8 emu (Dchip8). I did the graphical interface in Opengl, and the code compiles in Linux and Windows. Only the sound is still missing.
My code is very simple. Even a kid can understand.

Until the weekend i'll post here.

[]'s
 

Danny

Programmer | Moderator
I'm finishing my chip8 emu (Dchip8). I did the graphical interface in Opengl, and the code compiles in Linux and Windows. Only the sound is still missing.
My code is very simple. Even a kid can understand.

Until the weekend i'll post here.

[]'s


Nice work :)

Post it here when your done :D
 

givemeachance

New member
I'm finishing my chip8 emu (Dchip8). I did the graphical interface in Opengl, and the code compiles in Linux and Windows. Only the sound is still missing.
My code is very simple. Even a kid can understand.

Until the weekend i'll post here.

[]'s

Nice!!
When you're ready , can you please post the source?
I really wanna see how your app works :D


edit:
By the way , can you tell me how you render the tiles?
With resized quads? or with another way?:
 

Garstyciuks

New member
I used quads for each pixel. My chip8 emulator has 4 zoom modes, so you can choose from 1x1, 2x2, 4x4 and 16x16 sized quads.
 

Top