Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include "raylib.h"
- #include <fstream>
- const unsigned char FONT[80] = {
- 0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
- 0x20, 0x60, 0x20, 0x20, 0x70, // 1
- 0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
- 0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
- 0x90, 0x90, 0xF0, 0x10, 0x10, // 4
- 0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
- 0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
- 0xF0, 0x10, 0x20, 0x40, 0x40, // 7
- 0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
- 0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
- 0xF0, 0x90, 0xF0, 0x90, 0x90, // A
- 0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
- 0xF0, 0x80, 0x80, 0x80, 0xF0, // C
- 0xE0, 0x90, 0x90, 0x90, 0xE0, // D
- 0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
- 0xF0, 0x80, 0xF0, 0x80, 0x80 // F
- };
- bool IsBitSet(unsigned char byte,unsigned char bit) {
- return (byte >> bit) & 1;
- }
- class Chip8 {
- public:
- unsigned char RAM[4096];
- bool Display[64][32];
- int WindowScale = 8;
- unsigned short PC = 512;
- unsigned short IndexRegister = 0;
- unsigned short Stack[128];
- unsigned char DelayTimer = 0;
- unsigned char Sound = 0;
- unsigned char VariableRegisters[16];
- void Init() {
- SetTraceLogLevel(LOG_INFO | LOG_WARNING | LOG_ERROR | LOG_FATAL);
- InitWindow(64 * WindowScale, 32 * WindowScale, "chip8");
- SetTargetFPS(60);
- for (int i = 0; i < 5*16; i++) {
- int address = i + 0x50;
- RAM[address] = FONT[i];
- }
- }
- bool LoadROM(std::string filename) {
- std::ifstream romfile;
- romfile.open(filename);
- if (!romfile)
- return false;
- int index = 0;
- while (!romfile.eof()) {
- RAM[index + 512] = romfile.get();
- //printf("%02X ",RAM[index]);
- index += 1;
- }
- romfile.close();
- return true;
- }
- void FetchDecodeExecute() {
- unsigned char fb = RAM[PC]; // first byte
- unsigned char KIND = ((fb >> 4) & 0xF);
- unsigned char X = ((fb >> 0) & 0xF);
- unsigned char NN = RAM[PC + 1]; // second byte
- unsigned char Y = ((NN >> 4) & 0xF);
- unsigned char N = ((NN >> 0) & 0xF);
- unsigned short instruction = (((unsigned short)fb) << 8) | NN; // opcode
- unsigned short NNN = instruction & 0xFFF;
- std::cout << std::hex << PC;
- std::cout << " (" << std::to_string(PC) << ")";
- std::cout << " | ";
- std::cout << std::hex << IndexRegister;
- std::cout << " (" << std::to_string(IndexRegister) << ")";
- std::cout << " | ";
- std::cout << std::hex << instruction;
- std::cout << " ";
- std::cout << std::hex << (ushort)KIND;
- std::cout << std::hex << (ushort)X;
- std::cout << std::hex << (ushort)Y;
- std::cout << std::hex << (ushort)N;
- std::cout << " ";
- std::cout << std::hex << (ushort)NN;
- std::cout << " ";
- std::cout << std::hex << (ushort)NNN;
- std::cout << std::endl;
- PC += 2;
- if (instruction == 0x00E0) {
- std::cout << "CLEAR GONE 0x00E0" << std::endl;
- for (int i = 0; i < 64; i++) {
- for (int j = 0; j < 32; j++) {
- Display[i][j] = false;
- }
- }
- DrawScreen();
- } else if (KIND == 0x1) {
- PC = NNN;
- } else if (KIND == 0x6) {
- VariableRegisters[X] = NN;
- } else if (KIND == 0x7) {
- VariableRegisters[X] += NN;
- } else if (KIND == 0xA) {
- IndexRegister = NNN;
- } else if (KIND == 0xD) {
- unsigned char x = VariableRegisters[X] & 63;
- unsigned char y = VariableRegisters[Y] & 31;
- VariableRegisters[X] = x;
- VariableRegisters[Y] = y;
- VariableRegisters[0xF] = 0;
- for (ushort i = 0; i < N; i++) {
- x = VariableRegisters[X];
- unsigned char row = RAM[IndexRegister + i];
- std::cout << "row ";
- for (int j = 0; j < 8; j++) {
- if (IsBitSet(row,j)) {
- std::cout << "1";
- if (Display[x][y]) {
- Display[x][y] = false;
- VariableRegisters[0xF] = 1;
- } else {
- Display[x][y] = true;
- }
- } else {
- std::cout << "0";
- }
- x += 1;
- if (x == 63)
- break;
- }
- std::cout << std::endl;
- y += 1;
- if (y == 31)
- break;
- }
- DrawScreen();
- std::cin.get();
- } else if (KIND == 0x3) {
- if (VariableRegisters[X] == NN) {
- PC += 2;
- }
- } else if (KIND == 0x4) {
- if (VariableRegisters[X] != NN) {
- PC += 2;
- }
- } else if (KIND == 0x5) {
- if (VariableRegisters[X] == VariableRegisters[Y]) {
- PC += 2;
- }
- } else if (KIND == 0x9) {
- if (VariableRegisters[X] != VariableRegisters[Y]) {
- PC += 2;
- }
- } else {
- std::cout << "INVALID!!!" << std::endl;
- }
- }
- void DrawScreen() {
- BeginDrawing();
- ClearBackground(BLACK);
- for (int i = 0; i < 64; i++) {
- for (int j = 0; j < 32; j++) {
- if (Display[i][j]) {
- DrawRectangle(i * WindowScale,j * WindowScale,WindowScale,WindowScale,WHITE);
- }
- }
- }
- EndDrawing();
- }
- bool Update() {
- FetchDecodeExecute();
- BeginDrawing();
- EndDrawing();
- return !WindowShouldClose();
- }
- ~Chip8() {
- CloseWindow();
- }
- };
- int main() {
- std::cout << std::endl;
- std::cout << "CHIP 8 Emulator" << std::endl;
- Chip8* chip = new Chip8();
- chip->Init();
- chip->LoadROM("bin/IBM Logo.ch8");
- while (chip->Update()) {
- }
- std::cout << std::endl;
- std::cout << "Stopping" << std::endl;
- delete chip;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement