From 545d70c6b1831c2625aaa7fca6ebea1fd36de3af Mon Sep 17 00:00:00 2001 From: Vinicius Silva Date: Wed, 28 Feb 2024 21:36:17 -0300 Subject: [PATCH] Basic chip8 structure implemented --- CMakeLists.txt | 24 +++++ include/chip8.h | 50 ++++++++++ include/instructions.h | 41 ++++++++ src/chip8.c | 214 +++++++++++++++++++++++++++++++++++++++++ src/instructions.c | 179 ++++++++++++++++++++++++++++++++++ src/main.c | 0 6 files changed, 508 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 include/chip8.h create mode 100644 include/instructions.h create mode 100644 src/chip8.c create mode 100644 src/instructions.c create mode 100644 src/main.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5dfa10c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.10) +project(MeuProjetoC C) + +# Definir versão C padrão (opcional) +set(CMAKE_C_STANDARD 11) + +# Configuração do projeto +set(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) +set(INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) + +# Adicionar diretório de includes +include_directories(${INCLUDE_DIR}) + +# Obter todos os arquivos fonte do diretório src +file(GLOB SOURCES ${SOURCE_DIR}/*.c) + +# Executável de saída +add_executable(MeuPrograma ${SOURCES}) + +# Configurações de otimização e outras opções de compilação +if (CMAKE_COMPILER_IS_GNUCC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -pedantic -O3") +endif() diff --git a/include/chip8.h b/include/chip8.h new file mode 100644 index 0000000..f5e984f --- /dev/null +++ b/include/chip8.h @@ -0,0 +1,50 @@ +#ifndef __CHIP8_H__ + +#include +#include + +#define panic(x) printf("%d",x); exit(1); +#define MEM_SIZE 4096 +#define DISPLAY_WIDTH 64 +#define DISPLAY_HEIGHT 32 +#define F 0xF +#define PROGRAM_ADDRESS 0x200 +#define SPRITE_SIZE 8 +#define FONT_SIZE 16 +#define REG_SIZE 16 +#define STACK_SIZE 16 + +int font[FONT_SIZE][SPRITE_SIZE] = { + {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 +}; + +typedef uint16_t* stack; + +typedef struct Chip8{ + uint8_t RAM[MEM_SIZE]; + uint8_t V[REG_SIZE]; + uint8_t display[DISPLAY_HEIGHT][DISPLAY_WIDTH]; + uint8_t delay_timer; + uint8_t sound_timer; + uint16_t I; + uint16_t PC; + uint16_t SP; + stack chip8_stack; +}Chip8; + +#endif // __CHIP8_H__ \ No newline at end of file diff --git a/include/instructions.h b/include/instructions.h new file mode 100644 index 0000000..c5786fc --- /dev/null +++ b/include/instructions.h @@ -0,0 +1,41 @@ +#ifndef __INSTRUCTIONS_H__ + + #include "chip8.h" + #include + + extern void __00E0(Chip8 *chip8); + extern void __00EE(Chip8 *chip8); + extern void __1NNN(Chip8 *chip8, uint8_t nnn); + extern void __2NNN(Chip8 *chip8, uint8_t nnn); + extern void __3XNN(Chip8 *chip8, uint8_t x, uint8_t nn); + extern void __4XNN(Chip8 *chip8, uint8_t x, uint8_t nn); + extern void __5XY0(Chip8 *chip8, uint8_t x, uint8_t y); + extern void __6XNN(Chip8 *chip8, uint8_t x, uint8_t nn); + extern void __7XNN(Chip8 *chip8, uint8_t x, uint8_t nn); + extern void __8XY0(Chip8 *chip8, uint8_t x, uint8_t y); + extern void __8XY1(Chip8 *chip8, uint8_t x, uint8_t y); + extern void __8XY2(Chip8 *chip8, uint8_t x, uint8_t y); + extern void __8XY3(Chip8 *chip8, uint8_t x, uint8_t y); + extern void __8XY4(Chip8 *chip8, uint8_t x, uint8_t y); + extern void __8XY5(Chip8 *chip8, uint8_t x, uint8_t y); + extern void __8XY6(Chip8 *chip8, uint8_t x, uint8_t y); + extern void __8XY7(Chip8 *chip8, uint8_t x, uint8_t y); + extern void __8XYE(Chip8 *chip8, uint8_t x, uint8_t y); + extern void __9XY0(Chip8 *chip8, uint8_t x, uint8_t y); + extern void __ANNN(Chip8 *chip8, uint8_t nnn); + extern void __BNNN(Chip8 *chip8, uint8_t nnn); + extern void __CXNN(Chip8 *chip8, uint8_t nn); + extern void __DXYN(Chip8 *chip8, uint8_t x, uint8_t y, uint8_t n); + extern void __EX9E(Chip8 *chip8, uint8_t x); + extern void __EXA1(Chip8 *chip8, uint8_t x); + extern void __FX07(Chip8 *chip8, uint8_t x); + extern void __FX0A(Chip8 *chip8, uint8_t x); + extern void __FX15(Chip8 *chip8, uint8_t x); + extern void __FX18(Chip8 *chip8, uint8_t x); + extern void __FX1E(Chip8 *chip8, uint8_t x); + extern void __FX29(Chip8 *chip8, uint8_t x); + extern void __FX33(Chip8 *chip8, uint8_t x); + extern void __FX55(Chip8 *chip8, uint8_t x); + extern void __FX65(Chip8 *chip8, uint8_t x); + +#endif // __INSTRUCTIONS_H__ \ No newline at end of file diff --git a/src/chip8.c b/src/chip8.c new file mode 100644 index 0000000..640c4b1 --- /dev/null +++ b/src/chip8.c @@ -0,0 +1,214 @@ +#include "../include/chip8.h" +#include +#include + +Chip8 *init_cpu() +{ + Chip8 *chip8 = (Chip8*)malloc(sizeof(Chip8)); + + chip8->I = 0x00; + chip8->SP = 0x00; + chip8->delay_timer = 0x00; + chip8->sound_timer = 0x00; + chip8->PC = PROGRAM_ADDRESS; + + chip8->chip8_stack = (stack)malloc(STACK_SIZE*sizeof(stack)); + + return chip8; +} + +void start_cpu(Chip8 *chip8, uint8_t instructions[], int size) +{ + int ram_index = 0; + + // insert sprites on the memory + for(int i = 0; i < FONT_SIZE; i++) + { + for(int j = 0; j < SPRITE_SIZE; j++) + { + chip8->RAM[ram_index++] = font[i][j]; + } + } + + // insert instructions on the memory + for(int i = 0; i < size; i++) + { + chip8->RAM[PROGRAM_ADDRESS + i] = instructions[i]; + } +} + +uint16_t fetch(Chip8 *chip8) +{ + + uint16_t instruction; + + uint8_t msb_instruction = chip8->RAM[chip8->PC]; + uint8_t lsb_instruction = chip8->RAM[chip8->PC + 1]; + + instruction = ((instruction | msb_instruction) << 8) | lsb_instruction; + return instruction; +} + + +void run(Chip8 *chip8, uint16_t instruction) +{ + uint8_t nn, nnn, n, x, y = 0x00; + + switch (instruction & 0xF000) { + + case 0x0000: + + switch (instruction & 0x00FF) { + + case 0xE0: + + break; + + case 0xEE: + break; + + default: + panic("Invalid Instruction!"); + break; + } + + break; + + + case 0x1000: + + break; + + case 0x2000: + + break; + + case 0x3000: + + break; + + case 0x4000: + + break; + + case 0x5000: + + break; + + case 0x6000: + + break; + + case 0x7000: + + break; + + case 0x8000: + + switch (instruction & 0x000F) { + + case 0x0: + break; + + case 0x1: + break; + + case 0x2: + break; + + case 0x3: + break; + + case 0x4: + break; + + case 0x5: + break; + + case 0x6: + break; + + case 0x7: + break; + + case 0xE: + break; + + default: + panic("Invalid Instruction!"); + break; + } + + break; + + case 0x9000: + break; + + case 0xA000: + break; + + case 0xB000: + break; + + case 0xC000: + break; + + case 0xD000: + break; + + case 0xE000: + + switch (instruction & 0x00FF) { + + case 0x9E: + break; + + case 0xA1: + break; + + default: + panic("Invalid Instruction!"); + break; + } + + break; + + case 0xF000: + + switch (instruction & 0x00FF) { + case 0x07: + break; + + case 0x0A: + break; + + case 0x15: + break; + + case 0x18: + break; + + case 0x1E: + break; + + case 0x29: + break; + + case 0x33: + break; + + case 0x55: + break; + + case 0x65: + break; + + default: + panic("Invalid Instruction!") + break; + } + + break; + } + +} \ No newline at end of file diff --git a/src/instructions.c b/src/instructions.c new file mode 100644 index 0000000..7ff3831 --- /dev/null +++ b/src/instructions.c @@ -0,0 +1,179 @@ +#include "../include/instructions.h" + +void __00E0(Chip8 *chip8) +{ + for(int y = 0; y < DISPLAY_HEIGHT; y++) + { + for(int x = 0; x < DISPLAY_WIDTH; x++) + { + chip8->display[y][x] = 0x00; + } + } +} + +void __00EE(Chip8 *chip8) +{ + +} + +void __1NNN(Chip8 *chip8, uint8_t nnn) +{ + +} + +void __2NNN(Chip8 *chip8, uint8_t nnn) +{ + +} + +void __3XNN(Chip8 *chip8, uint8_t x, uint8_t nn) +{ + +} + +void __4XNN(Chip8 *chip8, uint8_t x, uint8_t nn) +{ + +} + +void __5XY0(Chip8 *chip8, uint8_t x, uint8_t y) +{ + +} + +void __6XNN(Chip8 *chip8, uint8_t x, uint8_t nn) +{ + +} + +void __7XNN(Chip8 *chip8, uint8_t x, uint8_t nn) +{ + +} + +void __8XY0(Chip8 *chip8, uint8_t x, uint8_t y) +{ + +} + +void __8XY1(Chip8 *chip8, uint8_t x, uint8_t y) +{ + +} + +void __8XY2(Chip8 *chip8, uint8_t x, uint8_t y) +{ + +} + +void __8XY3(Chip8 *chip8, uint8_t x, uint8_t y) +{ + +} + +void __8XY4(Chip8 *chip8, uint8_t x, uint8_t y) +{ + +} + +void __8XY5(Chip8 *chip8, uint8_t x, uint8_t y) +{ + +} + +void __8XY6(Chip8 *chip8, uint8_t x, uint8_t y) +{ + +} + +void __8XY7(Chip8 *chip8, uint8_t x, uint8_t y) +{ + +} + +void __8XYE(Chip8 *chip8, uint8_t x, uint8_t y) +{ + +} + +void __9XY0(Chip8 *chip8, uint8_t x, uint8_t y) +{ + +} + +void __ANNN(Chip8 *chip8, uint8_t nnn) +{ + +} + +void __BNNN(Chip8 *chip8, uint8_t nnn) +{ + +} + +void __CXNN(Chip8 *chip8, uint8_t nn) +{ + +} + +void __DXYN(Chip8 *chip8, uint8_t x, uint8_t y, uint8_t n) +{ + +} + +void __EX9E(Chip8 *chip8, uint8_t x) +{ + +} + +void __EXA1(Chip8 *chip8, uint8_t x) +{ + +} + +void __FX07(Chip8 *chip8, uint8_t x) +{ + +} + +void __FX0A(Chip8 *chip8, uint8_t x) +{ + +} + +void __FX15(Chip8 *chip8, uint8_t x) +{ + +} + +void __FX18(Chip8 *chip8, uint8_t x) +{ + +} + +void __FX1E(Chip8 *chip8, uint8_t x) +{ + +} + +void __FX29(Chip8 *chip8, uint8_t x) +{ + +} + +void __FX33(Chip8 *chip8, uint8_t x) +{ + +} + +void __FX55(Chip8 *chip8, uint8_t x) +{ + +} + +void __FX65(Chip8 *chip8, uint8_t x) +{ + +} + + diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..e69de29