Skip to content
Merged

v1.0 #17

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/scopes/Chisel_8.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
# ![ICON](pictures/icon.png) chisel8
<p align="center">
<img width="512" alt="title" src="pictures/title.png" style="width: 100%; max-width: 512px;">
</p>

Compact Hexadecimal Interpretive Programming – 8-bit (Chip-8 Interpreter), written in C with use of the [Raylib](https://github.com/raysan5/raylib) and [Raygui](https://github.com/raysan5/raygui) libraries.
Special thanks to everyone in the [EmuDev Discord Server](https://discord.com/invite/7nuaqZ2) that helped out with fixing some issues and handling undefined behaviour, as well as
the test ROMS from [Timendus's Chip8 test suite](https://github.com/Timendus/chip8-test-suite).

### Pictures
<div style="display: flex; flex-wrap: wrap; gap: 10px;">
<img width="1392" alt="Menu" src="pictures/menu.png" style="width: 30%; max-width: 200px;">
<img width="1392" alt="settings" src="pictures/settings.png" style="width: 30%; max-width: 200px;">
<img width="1392" alt="IBM LOGO" src="pictures/ibm.png" style="width: 30%; max-width: 200px;">
<img width="1392" alt="Chip-8 TTS LOGO" src="pictures/chip8-logo.png" style="width: 30%; max-width: 200px;">
<img width="1392" alt="corax+" src="pictures/corax+.png" style="width: 30%; max-width: 200px;">
<img width="1392" alt="flags" src="pictures/flags.png" style="width: 30%; max-width: 200px;">
<img width="1392" alt="settings" src="pictures/settings.png" style="width: 30%; max-width: 200px;">
<img width="1392" alt="quirks" src="pictures/quirks.png" style="width: 30%; max-width: 200px;">
</div>

---
Expand All @@ -21,15 +25,10 @@ Currently, all opcodes are implemented and all of them except for a few work as
- [X] MacOS, Linux and Windows platform support. (See: [raylib: supported platforms](https://www.raylib.com/#supported-platforms))
- [X] Loading of .ch8 ROM files
- [X] Supports all opcodes for the original [Chip-8](https://emu.gulrak.net/reference/opcodes/) system
- [X] Settings.txt to change background and pixel color values as well as the display scaling
- [X] Settings to change background and pixel color values as well as the beep volume
- [X] Chip-8 Audio emulation (it's just a beep...)
- [X] Correct keypad input
- [X] Settings panel to change color, display scale and debug/FPS info in the application
- [ ] Loading previous ROM files for quick access via "Load ROM"
- [ ] Custom Font support (via external binary file or other means)


**Scrapped**: ~~External Debug window to show RAM contents, fetched/executed opcodes etc.~~

```
Please report any bugs via GitHub on the issue page. Thank you!
Expand Down Expand Up @@ -63,11 +62,15 @@ You will now need to provide the ANGLE dylibs in `external/angle-lib/`:
```
File tree:

root/
chisel8/
|-- external/
|-- angle-lib/
|-- libEGL.dylib
|-- libGLESv2.dylib

|-- raylib-stable/
|-- raygui-stable/
...
```
Without these libraries, ANGLE won't be able to be loaded & compiled against.
If both of these are in their respective directory, you can continue as follows:
Expand Down
1 change: 1 addition & 0 deletions include/core/emu_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@
#include "core/emu_definition.h"
#include "gui/options_window.h"

int32_t undefined(int32_t instruct);
int32_t fetch(emu *chip8);
int32_t decode_exec(emu *chip, options_config *config);
2 changes: 1 addition & 1 deletion include/core/emu_definition.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
#define DISPLAY_WIDTH 64
#define DISPLAY_HEIGHT 32
#define REFRESH_RATE 60
#define CLOCK_RATE 700
#define CLOCK_RATE 600

// FONT
static uint8_t FONT[FONT_SIZE] = {
Expand Down
5 changes: 3 additions & 2 deletions include/gui/options_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
Expand All @@ -45,6 +46,8 @@ typedef struct Options_config{
typedef struct Interface_scaling{
int32_t window_width;
int32_t window_height;
int32_t emu_width;
int32_t emu_height;

float button_width;
float button_height;
Expand All @@ -53,7 +56,5 @@ typedef struct Interface_scaling{
int32_t font_size;
} ui_scale;

void create_config(options_config *config);
void load_settings(options_config *config);
int32_t write_settings(options_config *config);
int32_t options_window(options_config *config, ui_scale *scale);
Binary file modified pictures/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified pictures/menu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pictures/quirks.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified pictures/settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pictures/title.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added pictures/title.xcf
Binary file not shown.
28 changes: 13 additions & 15 deletions src/core/emu_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@

#include "core/emu_core.h"

int32_t undefined(void) { // Handles undefined behaviour
TraceLog(LOG_ERROR, "EMU_CORE -> COULD NOT DECODE INSTRUCTION!");
int32_t undefined(int32_t opcode) { // Handles undefined behaviour
TraceLog(LOG_ERROR, "EMU_CORE -> COULD NOT DECODE INSTRUCTION %04x!", opcode);
return -1;
}

Expand All @@ -36,7 +36,7 @@ int32_t fetch(emu *chip8) { // Fetches instruction
chip8->opcode <<= 8;
chip8->opcode += chip8->ram[chip8->pc++];
if (chip8->opcode == 0x0000) {
return undefined();
return undefined(0x000);
}
return 0;
}
Expand Down Expand Up @@ -65,7 +65,7 @@ int32_t decode_exec(emu *chip8, options_config *config) {
chip8->i_stack -= 1;

} else {
return undefined();
return undefined(chip8->opcode);
}
break;

Expand All @@ -92,13 +92,13 @@ int32_t decode_exec(emu *chip8, options_config *config) {
break;

case (0x5):
if (chip8->reg[X] == chip8->reg[Y]) {
if (chip8->reg[X] == chip8->reg[Y] && N1 == 0) {
chip8->pc += 2;
}
break;

case (0x9):
if (chip8->reg[X] != chip8->reg[Y]) {
if (chip8->reg[X] != chip8->reg[Y] && N1 == 0) {
chip8->pc += 2;
}
break;
Expand Down Expand Up @@ -184,7 +184,7 @@ int32_t decode_exec(emu *chip8, options_config *config) {
break;

default:
return undefined();
return undefined(chip8->opcode);
}
break;

Expand All @@ -205,17 +205,15 @@ int32_t decode_exec(emu *chip8, options_config *config) {
if (N2 == 0x9e) {
if (chip8->key == chip8->reg[X]) {
chip8->pc += 2;
chip8->key = -1;
}

} else if (N2 == 0xa1) {
if (chip8->key != chip8->reg[X]) {
chip8->pc += 2;
chip8->key = -1;
}

} else {
return undefined();
return undefined(chip8->opcode);
}
break;

Expand Down Expand Up @@ -245,10 +243,10 @@ int32_t decode_exec(emu *chip8, options_config *config) {
break;

case (0x0a):
if (chip8->key != -1) {
chip8->reg[X] = chip8->key;
} else {
if (chip8->key == -1) {
chip8->pc -= 2;
} else {
chip8->reg[X] = chip8->key;
}
break;

Expand Down Expand Up @@ -276,7 +274,7 @@ int32_t decode_exec(emu *chip8, options_config *config) {
break;

default:
return undefined();
return undefined(chip8->opcode);
}
break;

Expand Down Expand Up @@ -315,7 +313,7 @@ int32_t decode_exec(emu *chip8, options_config *config) {
break;

default:
return undefined();
return undefined(0x0000);
}
return 0;
}
44 changes: 30 additions & 14 deletions src/core/emu_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,6 @@ void check_input(emu *chip8) { // I'm sorry, I tried it with a switch but
chip8->key = 0xb;
} else if (IsKeyDown(KEY_V)) {
chip8->key = 0xf;
} else {
chip8->key = -1;
}
}

Expand Down Expand Up @@ -152,12 +150,27 @@ int32_t emu_main(options_config *config, ui_scale *scale) {
BeginDrawing();
ClearBackground(BLACK);

if (IsKeyPressed(KEY_F11)) {
if (!IsWindowFullscreen()) {
SetWindowSize(GetMonitorWidth(GetCurrentMonitor()), GetMonitorHeight(GetCurrentMonitor()));
ToggleFullscreen();
} else {
ToggleFullscreen();
SetWindowSize(scale->window_width, scale->window_height);
}
}

if (IsWindowResized()) { // Magic to enable dynamic scaling
config->display_scaling = (uint32_t) fminf(GetScreenWidth() / (float) DISPLAY_WIDTH,
GetScreenHeight() / (float) DISPLAY_HEIGHT);

scale->window_width = DISPLAY_WIDTH * config->display_scaling;
scale->window_height = DISPLAY_HEIGHT * config->display_scaling;
if (!IsWindowFullscreen()) {
scale->window_width = GetScreenWidth();
scale->window_height = GetScreenHeight();
}

scale->emu_width = DISPLAY_WIDTH * config->display_scaling;
scale->emu_height = DISPLAY_HEIGHT * config->display_scaling;

scale->button_width = (float) (GetScreenWidth() / 4.8);
scale->button_height = (float) ((float) GetScreenHeight() / 16);
Expand All @@ -172,33 +185,36 @@ int32_t emu_main(options_config *config, ui_scale *scale) {

// Draw Pixels from virtual Texture
DrawTexturePro(chip8.display, (Rectangle) {0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT},
(Rectangle) {(GetScreenWidth() - scale->window_width) / 2,
(GetScreenHeight() - scale->window_height) / 2, scale->window_width,
scale->window_height}, (Vector2) {0, 0}, 0, WHITE);
(Rectangle) {(GetScreenWidth() - scale->emu_width) / 2,
(GetScreenHeight() - scale->emu_height) / 2,
scale->emu_width,
scale->emu_height}, (Vector2) {0, 0}, 0, WHITE);

DrawRectangleLines(((GetScreenWidth() - scale->window_width) / 2) - 1,
(((GetScreenHeight() - scale->window_height) / 2)) - 1, scale->window_width + 2,
scale->window_height + 2, DARKGRAY);
DrawRectangleLines(((GetScreenWidth() - scale->emu_width) / 2) - 1,
(((GetScreenHeight() - scale->emu_height) / 2)) - 1,
scale->emu_width + 2,
scale->emu_height + 2, DARKGRAY);

if (config->show_fps) {
DrawText(TextFormat("%dhz", GetFPS() + 1), (int32_t) config->display_scaling,
DrawText(TextFormat("%dhz", GetFPS()), (int32_t) config->display_scaling,
(int32_t) config->display_scaling / 2,
(int32_t) (scale->font_size / 1.8), DARKGREEN);
}

check_input(&chip8);
for (int32_t i = 0; i < (int32_t) (CLOCK_RATE / REFRESH_RATE); ++i) {
check_input(&chip8);
if (!undefined && fetch(&chip8) == -1) {
undefined = true;
TraceLog(LOG_INFO, "EMU_MAIN -> Pausing emulation!");
TraceLog(LOG_WARNING, "EMU_MAIN -> Stopping further cycles!");
continue;
}
if (!undefined && decode_exec(&chip8, config) == -1) {
undefined = true;
TraceLog(LOG_INFO, "EMU_MAIN -> Pausing emulation!");
TraceLog(LOG_WARNING, "EMU_MAIN -> Stopping further cycles!");
continue;
}
}
chip8.key = -1;

if (chip8.delay > 0) {
chip8.delay -= REFRESH_RATE;
Expand Down
Loading