Browse Source

Added stuff

master
dionisis 5 years ago
parent
commit
d38e51646c
  1. 234
      .cproject
  2. 3
      .directory
  3. 26
      .project
  4. 48
      .settings/language.settings.xml
  5. BIN
      Debug/CHIP8-EMU
  6. 43
      Debug/makefile
  7. 8
      Debug/objects.mk
  8. 17
      Debug/sources.mk
  9. 3
      Debug/src/chip8.d
  10. BIN
      Debug/src/chip8.o
  11. 3
      Debug/src/main.d
  12. BIN
      Debug/src/main.o
  13. 27
      Debug/src/subdir.mk
  14. 21
      README.md
  15. BIN
      roms/15PUZZLE
  16. BIN
      roms/BLINKY
  17. BIN
      roms/BLITZ
  18. BIN
      roms/BRIX
  19. BIN
      roms/CONNECT4
  20. BIN
      roms/GUESS
  21. BIN
      roms/HIDDEN
  22. BIN
      roms/INVADERS
  23. BIN
      roms/KALEID
  24. BIN
      roms/MAZE
  25. BIN
      roms/MERLIN
  26. BIN
      roms/MISSILE
  27. BIN
      roms/PONG
  28. BIN
      roms/PONG2
  29. BIN
      roms/PUZZLE
  30. BIN
      roms/SYZYGY
  31. BIN
      roms/TANK
  32. BIN
      roms/TETRIS
  33. BIN
      roms/TICTAC
  34. BIN
      roms/UFO
  35. BIN
      roms/VBRIX
  36. BIN
      roms/VERS
  37. BIN
      roms/WIPEOFF
  38. BIN
      roms/rom.bin
  39. 388
      src/chip8.c
  40. 28
      src/include/chip8.h
  41. 144
      src/main.c

234
.cproject

@ -0,0 +1,234 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.599513494">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.599513494" moduleId="org.eclipse.cdt.core.settings" name="Debug">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.599513494" name="Debug" optionalBuildProperties="org.eclipse.cdt.docker.launcher.containerbuild.property.volumes=,org.eclipse.cdt.docker.launcher.containerbuild.property.selectedvolumes=" parent="cdt.managedbuild.config.gnu.exe.debug">
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.599513494." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.7622590" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.1231950085" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
<builder buildPath="${workspace_loc:/CHIP8-EMU}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.1055171339" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.202929379" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1517432998" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.910590472" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option defaultValue="gnu.cpp.compiler.debugging.level.max" id="gnu.cpp.compiler.exe.debug.option.debugging.level.1152220657" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" valueType="enumerated"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.1322141571" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.145623867" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
<option defaultValue="gnu.c.debugging.level.max" id="gnu.c.compiler.exe.debug.option.debugging.level.1368577640" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" useByScannerDiscovery="false" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.529004637" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1750100457" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.link.option.libs.1836007051" superClass="gnu.c.link.option.libs" useByScannerDiscovery="false" valueType="libs">
<listOptionValue builtIn="false" value="ncurses"/>
</option>
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.2030809384" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.534586887" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"/>
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.978846116" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1908435550" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.1766441669">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.1766441669" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.1766441669" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.1766441669." name="/" resourcePath="">
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.1101205221" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.469678818" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
<builder buildPath="${workspace_loc:/CHIP8-EMU}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.915576039" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
<tool id="cdt.managedbuild.tool.gnu.archiver.base.360365550" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.1484554830" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.1897730674" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
<option defaultValue="gnu.cpp.compiler.debugging.level.none" id="gnu.cpp.compiler.exe.release.option.debugging.level.1026390807" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" valueType="enumerated"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.1130383754" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.698187861" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" useByScannerDiscovery="false" valueType="enumerated"/>
<option defaultValue="gnu.c.debugging.level.none" id="gnu.c.compiler.exe.release.option.debugging.level.209013399" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" useByScannerDiscovery="false" valueType="enumerated"/>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1915938375" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.1255590961" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release">
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1439159639" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1660300390" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release"/>
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.899994999" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1372135666" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="CHIP8-EMU.cdt.managedbuild.target.gnu.exe.511522714" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.599513494;cdt.managedbuild.config.gnu.exe.debug.599513494.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.1322141571;cdt.managedbuild.tool.gnu.c.compiler.input.529004637">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.1766441669;cdt.managedbuild.config.gnu.exe.release.1766441669.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.1130383754;cdt.managedbuild.tool.gnu.c.compiler.input.1915938375">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="Debug">
<resource resourceType="PROJECT" workspacePath="/CHIP8-EMU"/>
</configuration>
<configuration configurationName="Release">
<resource resourceType="PROJECT" workspacePath="/CHIP8-EMU"/>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cproject>

3
.directory

@ -0,0 +1,3 @@
[Dolphin]
Timestamp=2019,11,27,21,50,31
Version=4

26
.project

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>CHIP8-EMU</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

48
.settings/language.settings.xml

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="cdt.managedbuild.config.gnu.exe.debug.599513494" name="Debug">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="531660544521815154" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
<configuration id="cdt.managedbuild.config.gnu.exe.release.1766441669" name="Release">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="531660544521815154" id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>

BIN
Debug/CHIP8-EMU

Binary file not shown.

43
Debug/makefile

@ -0,0 +1,43 @@
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
-include ../makefile.init
RM := rm -rf
# All of the sources participating in the build are defined here
-include sources.mk
-include src/subdir.mk
-include subdir.mk
-include objects.mk
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif
endif
-include ../makefile.defs
# Add inputs and outputs from these tool invocations to the build variables
# All Target
all: CHIP8-EMU
# Tool invocations
CHIP8-EMU: $(OBJS) $(USER_OBJS)
@echo 'Building target: $@'
@echo 'Invoking: GCC C Linker'
gcc -o "CHIP8-EMU" $(OBJS) $(USER_OBJS) $(LIBS)
@echo 'Finished building target: $@'
@echo ' '
# Other Targets
clean:
-$(RM) $(EXECUTABLES)$(OBJS)$(C_DEPS) CHIP8-EMU
-@echo ' '
.PHONY: all clean dependents
-include ../makefile.targets

8
Debug/objects.mk

@ -0,0 +1,8 @@
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
USER_OBJS :=
LIBS := -lncurses

17
Debug/sources.mk

@ -0,0 +1,17 @@
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
OBJ_SRCS :=
ASM_SRCS :=
C_SRCS :=
O_SRCS :=
S_UPPER_SRCS :=
EXECUTABLES :=
OBJS :=
C_DEPS :=
# Every subdirectory with source files must be described here
SUBDIRS := \
src \

3
Debug/src/chip8.d

@ -0,0 +1,3 @@
src/chip8.o: ../src/chip8.c ../src/include/chip8.h
../src/include/chip8.h:

BIN
Debug/src/chip8.o

Binary file not shown.

3
Debug/src/main.d

@ -0,0 +1,3 @@
src/main.o: ../src/main.c ../src/include/chip8.h
../src/include/chip8.h:

BIN
Debug/src/main.o

Binary file not shown.

27
Debug/src/subdir.mk

@ -0,0 +1,27 @@
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS += \
../src/chip8.c \
../src/main.c
OBJS += \
./src/chip8.o \
./src/main.o
C_DEPS += \
./src/chip8.d \
./src/main.d
# Each subdirectory must supply rules for building sources it contributes
src/%.o: ../src/%.c
@echo 'Building file: $<'
@echo 'Invoking: GCC C Compiler'
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<"
@echo 'Finished building: $<'
@echo ' '

21
README.md

@ -1,3 +1,22 @@
# CHIP8-EMU
A CHIP8 emulator written in C.
A CHIP8 emulator written in C.
## Eclipse IDE import:
> File > Import > Existing Code as Makefile project
## Building:
Eclispe IDE:
> Right click project > Build Project.
Terminal:
> cd Debug
> make
## Running:
> ./CHIP8-EMU \<ROM FILE>
## Known issues:
- [] Implement key pad

BIN
roms/15PUZZLE

Binary file not shown.

BIN
roms/BLINKY

Binary file not shown.

BIN
roms/BLITZ

Binary file not shown.

BIN
roms/BRIX

Binary file not shown.

BIN
roms/CONNECT4

Binary file not shown.

BIN
roms/GUESS

Binary file not shown.

BIN
roms/HIDDEN

Binary file not shown.

BIN
roms/INVADERS

Binary file not shown.

BIN
roms/KALEID

Binary file not shown.

BIN
roms/MAZE

Binary file not shown.

BIN
roms/MERLIN

Binary file not shown.

BIN
roms/MISSILE

Binary file not shown.

BIN
roms/PONG

Binary file not shown.

BIN
roms/PONG2

Binary file not shown.

BIN
roms/PUZZLE

Binary file not shown.

BIN
roms/SYZYGY

Binary file not shown.

BIN
roms/TANK

Binary file not shown.

BIN
roms/TETRIS

Binary file not shown.

BIN
roms/TICTAC

Binary file not shown.

BIN
roms/UFO

Binary file not shown.

BIN
roms/VBRIX

Binary file not shown.

BIN
roms/VERS

Binary file not shown.

BIN
roms/WIPEOFF

Binary file not shown.

BIN
roms/rom.bin

Binary file not shown.

388
src/chip8.c

@ -0,0 +1,388 @@
#include "include/chip8.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
int chip8_dump(chip8_t *chip, const char *filename) {
if (chip == NULL)
return -1;
if (filename == NULL)
return -2;
FILE *file = fopen(filename, "w");
if (file == NULL)
return -3;
uint16_t i;
fprintf(file, "CHIP8 DUMP FILE\n\n");
fprintf(file, "REGISTERS:\n V: ");
for (i = 0; i < 16; i++) {
fprintf(file, "%02x", chip->cpu.V[i]);
if (i < 15)
fprintf(file, " ");
else
fprintf(file, "\n");
}
fprintf(file, " SP: %02x\n", chip->cpu.SP);
fprintf(file, " TS: %02x\n", chip->cpu.TS);
fprintf(file, " TD: %02x\n", chip->cpu.TD);
fprintf(file, " PC: %04x\n", chip->cpu.PC);
fprintf(file, " I: %04x\n\n", chip->cpu.I);
fprintf(file, "MEMORY:\n RAM: ");
for (i = 0; i < 4096; i++) {
fprintf(file, "%02x", chip->mem.RAM[i]);
if (i % 64 < 63) {
if (i == chip->cpu.PC - 1)
fprintf(file, "[");
else if (i == chip->cpu.PC + 1)
fprintf(file, "]");
else if (i == chip->cpu.I)
fprintf(file, "-");
else
fprintf(file, " ");
} else {
fprintf(file, " %04x | %04x\n", i - 63, i);
if (i < 4095)
fprintf(file, " ");
}
}
fprintf(file, " STK: ");
for (i = 0; i < 24; i++) {
fprintf(file, "%04x", chip->mem.STK[i]);
if (i < 23)
fprintf(file, " ");
else
fprintf(file, "\n");
}
fprintf(file, "\nIO:\n KEYS: ");
for (i = 0; i < 24; i++) {
fprintf(file, "%02x", chip->io.KEYS[i]);
if (i < 23)
fprintf(file, " ");
else
fprintf(file, "\n");
}
fprintf(file, " DSP: ");
for (i = 0; i < 2048; i++) {
fprintf(file, "%s", chip->io.DSP[i] ? "XX" : "..");
if (i % 64 == 63) {
fprintf(file, "\n");
if (i < 2047)
fprintf(file, " ");
}
}
fclose(file);
return 0;
}
int chip8_init(chip8_t *chip) {
if (chip == NULL)
return -1;
uint16_t i;
for (i = 0; i < 16; i++)
chip->cpu.V[i] = 0x00;
chip->cpu.SP = 0x00;
chip->cpu.TS = 0x00;
chip->cpu.TD = 0x00;
chip->cpu.PC = 0x0200;
chip->cpu.I = 0x0000;
for (i = 0; i < 4096; i++)
chip->mem.RAM[i] = 0x00;
for (i = 0; i < 24; i++)
chip->mem.STK[i] = 0x00;
//font "0"
chip->mem.RAM[0] = 0b11110000;
chip->mem.RAM[1] = 0b10010000;
chip->mem.RAM[2] = 0b10010000;
chip->mem.RAM[3] = 0b10010000;
chip->mem.RAM[4] = 0b11110000;
//font "1"
chip->mem.RAM[5] = 0b00100000;
chip->mem.RAM[6] = 0b01100000;
chip->mem.RAM[7] = 0b00100000;
chip->mem.RAM[8] = 0b00100000;
chip->mem.RAM[9] = 0b01110000;
//font "2"
chip->mem.RAM[10] = 0b11110000;
chip->mem.RAM[11] = 0b00010000;
chip->mem.RAM[12] = 0b11110000;
chip->mem.RAM[13] = 0b10000000;
chip->mem.RAM[14] = 0b11110000;
//font "3"
chip->mem.RAM[15] = 0b11110000;
chip->mem.RAM[16] = 0b00010000;
chip->mem.RAM[17] = 0b11110000;
chip->mem.RAM[18] = 0b00010000;
chip->mem.RAM[19] = 0b11110000;
//font "4"
chip->mem.RAM[20] = 0b10010000;
chip->mem.RAM[21] = 0b10010000;
chip->mem.RAM[22] = 0b11110000;
chip->mem.RAM[23] = 0b00010000;
chip->mem.RAM[24] = 0b00010000;
//font "5"
chip->mem.RAM[25] = 0b11110000;
chip->mem.RAM[26] = 0b10000000;
chip->mem.RAM[27] = 0b11110000;
chip->mem.RAM[28] = 0b00010000;
chip->mem.RAM[29] = 0b11110000;
//font "6"
chip->mem.RAM[30] = 0b11110000;
chip->mem.RAM[31] = 0b10000000;
chip->mem.RAM[32] = 0b11110000;
chip->mem.RAM[33] = 0b10010000;
chip->mem.RAM[34] = 0b11110000;
//font "7"
chip->mem.RAM[35] = 0b11110000;
chip->mem.RAM[36] = 0b00010000;
chip->mem.RAM[37] = 0b00100000;
chip->mem.RAM[38] = 0b01000000;
chip->mem.RAM[39] = 0b01000000;
//font "8"
chip->mem.RAM[40] = 0b11110000;
chip->mem.RAM[41] = 0b10010000;
chip->mem.RAM[42] = 0b11110000;
chip->mem.RAM[43] = 0b10010000;
chip->mem.RAM[44] = 0b11110000;
//font "9"
chip->mem.RAM[45] = 0b11110000;
chip->mem.RAM[46] = 0b10010000;
chip->mem.RAM[47] = 0b11110000;
chip->mem.RAM[48] = 0b00010000;
chip->mem.RAM[49] = 0b11110000;
//font "A"
chip->mem.RAM[50] = 0b11110000;
chip->mem.RAM[51] = 0b10010000;
chip->mem.RAM[52] = 0b11110000;
chip->mem.RAM[53] = 0b10010000;
chip->mem.RAM[54] = 0b10010000;
//font "B"
chip->mem.RAM[55] = 0b11100000;
chip->mem.RAM[56] = 0b10010000;
chip->mem.RAM[57] = 0b11100000;
chip->mem.RAM[58] = 0b10010000;
chip->mem.RAM[59] = 0b11100000;
//font "C"
chip->mem.RAM[60] = 0b11110000;
chip->mem.RAM[61] = 0b10000000;
chip->mem.RAM[62] = 0b10000000;
chip->mem.RAM[63] = 0b10000000;
chip->mem.RAM[64] = 0b11110000;
//font "D"
chip->mem.RAM[65] = 0b11100000;
chip->mem.RAM[66] = 0b10010000;
chip->mem.RAM[67] = 0b10010000;
chip->mem.RAM[68] = 0b10010000;
chip->mem.RAM[69] = 0b11100000;
//font "E"
chip->mem.RAM[70] = 0b11110000;
chip->mem.RAM[71] = 0b10000000;
chip->mem.RAM[72] = 0b11110000;
chip->mem.RAM[73] = 0b10000000;
chip->mem.RAM[74] = 0b11110000;
//font "F"
chip->mem.RAM[75] = 0b11110000;
chip->mem.RAM[76] = 0b10000000;
chip->mem.RAM[77] = 0b11110000;
chip->mem.RAM[78] = 0b10000000;
chip->mem.RAM[79] = 0b10000000;
for (i = 0; i < 16; i++)
chip->io.KEYS[i] = 0x00;
for (i = 0; i < 2048; i++)
chip->io.DSP[i] = 0x00;
chip->flags.draw = 0x00;
return 0;
}
int chip8_load(chip8_t *chip, const char *filename) {
if (chip == NULL)
return -1;
if (filename == NULL)
return -2;
FILE *file = fopen(filename, "rb");
if (file == NULL)
return -3;
fseek(file, 0L, SEEK_END);
long size = ftell(file);
if (size < 1L) {
fclose(file);
return -4;
}
fseek(file, 0L, SEEK_SET);
if (fread(chip->mem.RAM + 0x200, 1, size, file) < size) {
fclose(file);
return -5;
}
fclose(file);
return 0;
}
int chip8_cycle(chip8_t *chip) {
uint16_t opcode = (chip->mem.RAM[chip->cpu.PC] << 8) | chip->mem.RAM[chip->cpu.PC + 1];
uint8_t nibble[4] = { opcode >> 12, (opcode >> 8) & 0x000F, (opcode >> 4) & 0x000F, opcode & 0x000F };
uint16_t i;
if (opcode == 0x00E0) {
for (i = 0; i < 2048; i++)
chip->io.DSP[i] = 0x00;
chip->flags.draw = 0x01;
chip->cpu.PC += 2;
} else if (opcode == 0x00EE) {
chip->cpu.SP--;
chip->cpu.PC = chip->mem.STK[chip->cpu.SP] + 2;
} else if (nibble[0] == 0x01) {
chip->cpu.PC = opcode & 0x0FFF;
} else if (nibble[0] == 0x02) {
chip->mem.STK[chip->cpu.SP] = chip->cpu.PC;
chip->cpu.SP++;
chip->cpu.PC = opcode & 0x0FFF;
} else if (nibble[0] == 0x03) {
if (chip->cpu.V[nibble[1]] == (opcode & 0x00FF))
chip->cpu.PC += 2;
chip->cpu.PC += 2;
} else if (nibble[0] == 0x04) {
if (chip->cpu.V[nibble[1]] != (opcode & 0x00FF))
chip->cpu.PC += 2;
chip->cpu.PC += 2;
} else if ((opcode & 0xF00F) == 0x5000) {
if (chip->cpu.V[nibble[1]] == chip->cpu.V[nibble[2]])
chip->cpu.PC += 2;
chip->cpu.PC += 2;
} else if (nibble[0] == 0x06) {
chip->cpu.V[nibble[1]] = opcode & 0x00FF;
chip->cpu.PC += 2;
} else if (nibble[0] == 0x07) {
chip->cpu.V[nibble[1]] += opcode & 0x00FF;
chip->cpu.PC += 2;
} else if ((opcode & 0xF00F) == 0x8000) {
chip->cpu.V[nibble[1]] = chip->cpu.V[nibble[2]];
chip->cpu.PC += 2;
} else if ((opcode & 0xF00F) == 0x8001) {
chip->cpu.V[nibble[1]] |= chip->cpu.V[nibble[2]];
chip->cpu.PC += 2;
} else if ((opcode & 0xF00F) == 0x8002) {
chip->cpu.V[nibble[1]] &= chip->cpu.V[nibble[2]];
chip->cpu.PC += 2;
} else if ((opcode & 0xF00F) == 0x8003) {
chip->cpu.V[nibble[1]] ^= chip->cpu.V[nibble[2]];
chip->cpu.PC += 2;
} else if ((opcode & 0xF00F) == 0x8004) {
if ((uint16_t) chip->cpu.V[nibble[1]] + (uint16_t) chip->cpu.V[nibble[2]] > 0x00FF)
chip->cpu.V[0xF] = 0x01;
else
chip->cpu.V[0xF] = 0x00;
chip->cpu.V[nibble[1]] += chip->cpu.V[nibble[2]];
chip->cpu.PC += 2;
} else if ((opcode & 0xF00F) == 0x8005) {
if (chip->cpu.V[nibble[1]] > chip->cpu.V[nibble[2]])
chip->cpu.V[0xF] = 0x01;
else
chip->cpu.V[0xF] = 0x00;
chip->cpu.V[nibble[1]] -= chip->cpu.V[nibble[2]];
chip->cpu.PC += 2;
} else if ((opcode & 0xF00F) == 0x8006) {
chip->cpu.V[0x0F] = chip->cpu.V[nibble[1]] & 0x01;
chip->cpu.V[nibble[1]] >>= 1;
chip->cpu.PC += 2;
} else if ((opcode & 0xF00F) == 0x8007) {
if (chip->cpu.V[nibble[2]] > chip->cpu.V[nibble[1]])
chip->cpu.V[0xF] = 0x01;
else
chip->cpu.V[0xF] = 0x00;
chip->cpu.V[nibble[1]] = chip->cpu.V[nibble[2]] - chip->cpu.V[nibble[1]];
chip->cpu.PC += 2;
} else if ((opcode & 0xF00F) == 0x800E) {
chip->cpu.V[0x0F] = chip->cpu.V[nibble[1]] & 0x80;
chip->cpu.V[nibble[1]] <<= 1;
chip->cpu.PC += 2;
} else if ((opcode & 0xF00F) == 0x9000) {
if (chip->cpu.V[nibble[1]] != chip->cpu.V[nibble[2]])
chip->cpu.PC += 2;
chip->cpu.PC += 2;
} else if (nibble[0] == 0x0A) {
chip->cpu.I = opcode & 0x0FFF;
chip->cpu.PC += 2;
} else if (nibble[0] == 0x0B) {
chip->cpu.PC = (opcode & 0x0FFF) + chip->cpu.V[0x00];
} else if (nibble[0] == 0x0C) {
chip->cpu.V[nibble[1]] = (rand() % 256) & (opcode & 0x00FF);
chip->cpu.PC += 2;
} else if (nibble[0] == 0x0D) {
uint8_t j, last, x = chip->cpu.V[nibble[1]], y = chip->cpu.V[nibble[2]];
chip->cpu.V[0x0F] = 0x00;
for (i = 0; i < nibble[3]; i++) {
for (j = 0; j < 8; j++) {
last = chip->io.DSP[(y + i) * 64 + x + j];
chip->io.DSP[(y + i) * 64 + x + j] ^= (chip->mem.RAM[chip->cpu.I + i] >> (7 - j)) & 0x01;
if (!chip->io.DSP[(y + i) * 64 + x + j] && last)
chip->cpu.V[0x0F] = 0x01;
}
}
chip->flags.draw = 0x01;
chip->cpu.PC += 2;
} else if ((opcode & 0xF0FF) == 0xE09E) {
if (chip->io.KEYS[nibble[1]])
chip->cpu.PC += 2;
chip->cpu.PC += 2;
} else if ((opcode & 0xF0FF) == 0xE0A1) {
if (!(chip->io.KEYS[nibble[1]]))
chip->cpu.PC += 2;
chip->cpu.PC += 2;
} else if ((opcode & 0xF0FF) == 0xF007) {
chip->cpu.V[nibble[1]] = chip->cpu.TD;
chip->cpu.PC += 2;
} else if ((opcode & 0xF0FF) == 0xF00A) {
for (i = 0; i < 16; i++)
if (chip->io.KEYS[i]) {
chip->cpu.PC += 2;
break;
}
} else if ((opcode & 0xF0FF) == 0xF015) {
chip->cpu.TD = chip->cpu.V[nibble[1]];
chip->cpu.PC += 2;
} else if ((opcode & 0xF0FF) == 0xF018) {
chip->cpu.TS = chip->cpu.V[nibble[1]];
chip->cpu.PC += 2;
} else if ((opcode & 0xF0FF) == 0xF01E) {
chip->cpu.V[0x0F] = chip->cpu.I + (uint16_t) chip->cpu.V[nibble[1]] > 0x0FFF;
chip->cpu.I += chip->cpu.V[nibble[1]];
chip->cpu.PC += 2;
} else if ((opcode & 0xF0FF) == 0xF029) {
chip->cpu.I = nibble[1] * 5;
chip->cpu.PC += 2;
} else if ((opcode & 0xF0FF) == 0xF033) {
chip->mem.RAM[chip->cpu.I] = chip->cpu.V[nibble[1]] / 100;
chip->mem.RAM[chip->cpu.I + 1] = (chip->cpu.V[nibble[1]] / 10) % 10;
chip->mem.RAM[chip->cpu.I + 2] = chip->cpu.V[nibble[1]] % 10;
chip->cpu.PC += 2;
} else if ((opcode & 0xF0FF) == 0xF055) {
for (i = 0; i < nibble[1]; i++) {
chip->mem.RAM[chip->cpu.I] = chip->cpu.V[i];
chip->cpu.I++;
}
chip->cpu.PC += 2;
} else if ((opcode & 0xF0FF) == 0xF065) {
for (i = 0; i < nibble[1]; i++) {
chip->cpu.V[i] = chip->mem.RAM[chip->cpu.I];
chip->cpu.I++;
}
chip->cpu.PC += 2;
} else {
return -1;
}
return 0;
}

28
src/include/chip8.h

@ -0,0 +1,28 @@
#ifndef SRC_INCLUDE_CHIP8_H_
#define SRC_INCLUDE_CHIP8_H_
#include <inttypes.h>
typedef struct {
struct {
uint8_t V[16], SP, TS, TD;
uint16_t PC, I;
} cpu;
struct {
uint8_t RAM[4096];
uint16_t STK[24];
} mem;
struct {
uint8_t KEYS[16], DSP[2048];
} io;
struct {
uint8_t draw;
} flags;
} chip8_t;
int chip8_dump(chip8_t *, const char *);
int chip8_init(chip8_t *);
int chip8_load(chip8_t *, const char *);
int chip8_cycle(chip8_t *);
#endif

144
src/main.c

@ -0,0 +1,144 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ncurses.h>
#include "include/chip8.h"
void chip8_keys_clear(chip8_t *chip) {
for (uint8_t i = 0; i < 16; i++)
chip->io.KEYS[i] = 0x00;
}
int main(int argc, char **argv) {
if (argc < 2) {
printf("No ROM files specified!\n");
return -1;
}
chip8_t chip;
chip8_init(&chip);
srand(time(NULL));
chip8_load(&chip, argv[1]);
struct timespec ts = { .tv_nsec = 2000000, .tv_sec = 0 };
float timer_delay = 0.0F, timer_sound = 0.0F;
noecho();
cbreak();
timeout(0);
int ch;
while (1) {
for (int i = 0; i < 16; i++)
chip.io.KEYS[i] = 0x01;
ch = getch();
chip8_keys_clear(&chip);
switch (ch) {
case '1':
chip.io.KEYS[0x1] = 0x01;
break;
case '2':
chip.io.KEYS[0x2] = 0x01;
break;
case '3':
chip.io.KEYS[0x3] = 0x01;
break;
case '4':
chip.io.KEYS[0xC] = 0x01;
break;
case 'q':
chip.io.KEYS[0x4] = 0x01;
break;
case 'w':
chip.io.KEYS[0x5] = 0x01;
break;
case 'e':
chip.io.KEYS[0x6] = 0x01;
break;
case 'r':
chip.io.KEYS[0xD] = 0x01;
break;
case 'a':
chip.io.KEYS[0x7] = 0x01;
break;
case 's':
chip.io.KEYS[0x8] = 0x01;
break;
case 'd':
chip.io.KEYS[0x9] = 0x01;
break;
case 'f':
chip.io.KEYS[0xE] = 0x01;
break;
case 'z':
chip.io.KEYS[0xA] = 0x01;
break;
case 'x':
chip.io.KEYS[0x0] = 0x01;
break;
case 'c':
chip.io.KEYS[0xB] = 0x01;
break;
case 'v':
chip.io.KEYS[0xF] = 0x01;
break;
default:
break;
}
if (chip.cpu.TD) {
timer_delay += 2.0F;
if (timer_delay >= 1000.0F / 60.0F) {
timer_delay -= 1000.0F / 60.0F;
chip.cpu.TD--;
if (chip.cpu.TD == 0)
timer_delay = 0.0F;
}
}
if (chip.cpu.TS) {
timer_sound += 2.0F;
if (timer_sound >= 1000.0F / 60.0F) {
timer_sound -= 1000.0F / 60.0F;
chip.cpu.TS--;
if (chip.cpu.TS == 0)
timer_sound = 0.0F;
}
}
if (chip.flags.draw) {
chip.flags.draw = 0x00;
printf("\033[0;0H");
for (int x = 0; x < 66; x++)
printf("##");
printf("\n");
for (int y = 0; y < 32; y++) {
printf("##");
for (int x = 0; x < 64; x++) {
if (chip.io.DSP[y * 64 + x])
printf("██");
else
printf(" ");
}
printf("##\n");
}
for (int x = 0; x < 66; x++)
printf("##");
printf("\n");
}
if (chip8_cycle(&chip)) {
printf("Invalid opcode 0x%04x!\n", (chip.mem.RAM[chip.cpu.PC] << 8) | chip.mem.RAM[chip.cpu.PC + 1]);
return -2;
}
nanosleep(&ts, &ts);
ts.tv_nsec = 2000000;
ts.tv_sec = 0;
}
return 0;
}
Loading…
Cancel
Save