Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Classic Chat / Tier 1 Gameboy Emulator

Author
Message
Jack
20
Years of Service
User Offline
Joined: 4th Oct 2004
Location: [Germany]
Posted: 20th Jul 2021 22:47 Edited at: 21st Jul 2021 17:58
My previous and first emulation project was a Chip8 that run quite well based
on the unclear instruction set that a chip8 has. It was actually quite fun,
and teached me the basics of emulation. Seeing games come to life on an own
emulator was a powerful experience.

If you do not know where to start, check out this wonderful AppGameKit Chip8 emulator made by Cliff Mellangard:
https://forum.thegamecreators.com/thread/217664



This project is a chance to get a deeper glimpse into emulation.



Project Idea:
- It has to be fun
- Creating a working and portable gameboy emulator in AppGameKit Tier 1
- Audio Processing would be nice to have

Project Paradigms:
- single main.agc file only
- no external media (besides cartridge bytecode)
- keep it as near as possible to the original hardware (pixel rendering is okay but no tile to agk sprite draw call improvements)
- No Plugins, it should run out of the box
- Implement aquired knowlege first, thoughts second

Sources:
https://mattbruv.github.io/gameboy-crust/
http://bgb.bircd.org/pandocs.htm
https://www.linkedin.com/pulse/creating-gameboy-emulator-part-1-bruno-croci/
https://bgb.bircd.org/pandocs.htm#lcdcontrolregister
https://github.com/bouk/gameboy-emu/blob/master/lr35902/lr35902.go
https://www.huderlem.com/demos/gameboy2bpp.html





Version 0.1:



comment on the code:
The first code sets a basic structure based on the gameboy specifications, aswell
as some early screen buffer rendering stages. I have aswell implemented a 2bpp renderer labeled as "tile", "tileset 1" and "tileset 2"
There are three screen buttons in order to control the cpu (reset; run/stop) and a button to load the default cartridge from the /media/ folder.
There is a lot of debug code and there might be some wrong values in the tileset.
But all in all a basic emulation layout even with some basic opcode examples.
I do not expect this project to get way bigger, as we can already read and write 8 or 16 bytes to or from memory abd chunks of memory can already be drawn to a screen buffer, even if I don't have a clue right now how the screen update works on the gameboy exactly.

I've used a file called "Tetris.gb" inside the /media/ folder, representing a backup copy of the Tetris cardrige, but there are some fun public domain games, that may be used in later development stages.



Errors/ WIP:
- Gameboy has a screen size of 160x144 pixel but a virtual draw buffer of 256x256 pixel. The screen buffer of 160x144 should be a chunk of the 256x256 pixel buffer, and this can be used as a virtual camera offset aswell.
- Actually no real opcodes are implemented right now, as there might be a change in the "CPU registers" functionality. It may be even smart to create a memblock for this registers, as opcodes require a decision, no work was done on this side.
- A random tile is selected and drawn multiple times on screen in order to demonstrate rendering 2bpp 8x8 pixel gameboy tile system




Any help is appreciated as I am learning aswell

Attachments

Login to view attachments
Jack
20
Years of Service
User Offline
Joined: 4th Oct 2004
Location: [Germany]
Posted: 21st Jul 2021 11:59 Edited at: 21st Jul 2021 12:07


Version 0.2:


notes on code:
I have unified the buffer creation process to a single function and added a simple Interface for all gameboy buttons.
Some functions where renamed.
The biggest change is the new 256x256 pixel full screen buffer as mentioned in the gameboy specifications and
the change from tileset buffers to the actual complete bank (0) and bank (X) of the cardrige, including tilesets.
As I thought, per pixel control of a 256x256 pixel buffer will drop the fps under 60. But this is right now no problem at all. the gameboy has no per pixel control just something like a primitive fullscreen shader.
This version is a good base to start any 8 bit emulator project, as it has all common implementations like input / output and processing.

Attachments

Login to view attachments
Jack
20
Years of Service
User Offline
Joined: 4th Oct 2004
Location: [Germany]
Posted: 25th Jul 2021 14:18 Edited at: 25th Jul 2021 19:46
0xCB Opcode Table

After implementing the first opcodes, I realized the huge problem of implementing about 512 opcodes - it would take some time.
So I thought there may be a logical algorythm that can sort out the opcodes faster and reduce them to some single functions.

In order to move on, I decided to test this idea on the second 256 opcode table the gameboy has, (that can be accessed by a 0xCB byte Prefix, and can be used on any opcode)

You can see this opcode table on this image:

Or: Check out the second table on this side, the Prefix CB table in cyan:
https://www.pastraiser.com/cpu/gameboy/gameboy_opcodes.html


This table consists of 256 opcodes that are based on just eleven operations, but with diffrent registers, that are repeated in an uniform order. ( B C D E H L (HL) A - two times in a row)
By careful inspection, there is some fun thing to notice. After x7, the function type changes. It looks like there is a x0 - x7 function "left" side and a x8 - xF function "right" side.

So Ive split the opcode (0x13 for example) in two nibbles.

1. the operation nibble 0x1 (represents function RL, when operand bigger than 0x7 it would represent RRC)
2. the operand nibble 0x3 ( represents register E)




I've made a seperate program shell to demonstrate the simple, yet time saving algorithm:
It does even display the operation and operand as a human readable string, in order to understand quicker.



Be aware, that CPU timing is not represented at all and the
resulting cpu instruction per function structure will require a function that sets a value to a register based on "n"

There may be better approaches, as some functions are mirrored (left shift / right shift) but this method is capable of solving 256 opcodes in about 256 lines of code, so I am fine with the result,
but I am thankful for each suggestion in order to recude some line of codes, as long as it is not using out of "basic" scope commands



Default Opcode Table

Once I did this to the 0xCB opcode table, it was time to look for a similar solution for the default z80 opcode table. The approach to just select/case all 256 opcodes, as I've done in the beginning, is too bare bone.
After some time spend for research, I found this, it was what I've been looking for:


Source: http://goldencrystal.free.fr/GBZ80Opcodes.pdf

The information presented in this list allowed us to reduce 256 opcodes to just 57 CPU functions
Well at least I am way better off implementing all 57 functions and fenching / parsing them like the 0xCB ones.

Attachments

Login to view attachments
rudyardcatling
7
Years of Service
User Offline
Joined: 3rd Nov 2017
Location:
Posted: 22nd Aug 2021 03:51


this is way beyond light afternoon tea coding for which i feel AppGameKit is extremely well suited on days with excessive sunlight, but hella-cool . I always felt like it would be awesome to come up with a virtual maching like a pico8, grant it a virtual circuitboard, memory limit, cpu with specially designed set of opcodes and then allow cartridges of set sizes to be entered to see how far people can push it. C64 nostalgia ... getting to the doing is another thing, this is awesome

Login to post a reply

Server time is: 2024-11-21 18:08:22
Your offset time is: 2024-11-21 18:08:22