in the beginning, there was darkness

This commit is contained in:
Ghostie 2025-02-08 17:46:53 -05:00
commit 9880e3b52c
5 changed files with 433 additions and 0 deletions

274
.clang-format Normal file
View File

@ -0,0 +1,274 @@
---
Language: Cpp
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveShortCaseStatements:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCaseArrows: false
AlignCaseColons: false
AlignConsecutiveTableGenBreakingDAGArgColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenCondOperatorColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignConsecutiveTableGenDefinitionColons:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
AlignFunctionPointers: false
PadOperators: false
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowBreakBeforeNoexceptSpecifier: Never
AllowShortBlocksOnASingleLine: Never
AllowShortCaseExpressionOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortCompoundRequirementOnASingleLine: true
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: All
AlwaysBreakBeforeMultilineStrings: false
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BitFieldColonSpacing: Both
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: Always
AfterEnum: true
AfterExternBlock: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: false
BeforeWhile: true
IndentBraces: true
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAdjacentStringLiterals: true
BreakAfterAttributes: Leave
BreakAfterJavaFieldAnnotations: false
BreakAfterReturnType: AllDefinitions
BreakArrays: true
BreakBeforeBinaryOperators: All
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: GNU
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakFunctionDefinitionParameters: false
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
BreakTemplateDeclarations: MultiLine
ColumnLimit: 79
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: false
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLines:
AtEndOfFile: false
AtStartOfBlock: true
AtStartOfFile: true
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MainIncludeChar: Quote
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PackConstructorInitializers: BinPack
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakScopeResolution: 500
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
PPIndentWidth: -1
QualifierAlignment: Leave
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SkipMacroDefinitionBody: false
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: Always
SpaceBeforeParensOptions:
AfterControlStatements: false
AfterForeachMacros: false
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: false
AfterOverloadedOperator: false
AfterPlacementOperator: true
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
ExceptDoubleParentheses: false
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
Other: false
SpacesInSquareBrackets: false
Standard: c++03
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TableGenBreakInsideDAGArg: DontBreak
TabWidth: 8
UseTab: Never
VerilogBreakBetweenInstancePorts: true
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
...

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.o
*.out

24
Makefile Normal file
View File

@ -0,0 +1,24 @@
CC=gcc
ECHO=echo -e
CFLAGS=-Wall -Werror -std=gnu99 -O0 -g -Iinclude
LIBS=-lSDL2
FILES=build/main.o
OUT=bin/chip8.out
all: $(FILES)
@$(ECHO) "CC\t\t"$(FILES)
@$(CC) $(CFLAGS) $(FILES) -o $(OUT) $(LIBS)
build/main.o: src/main.c
@$(ECHO) "CC\t\t"$<
@$(CC) $(CFLAGS) $< -c -o $@ $(LIBS)
run: all
@$(ECHO) "Runing the Chip8 compiler"
@$(OUT)
clean:
@$(ECHO) "Cleaning files..."
@rm -f $(FILES) $(OUT)
@$(ECHO) "Cleaning complete..."

95
Notes.org Normal file
View File

@ -0,0 +1,95 @@
* Chip8 Emulator
** The memory Layout
The Chip8 has 4095 bytes of memory:
#+begin_src artist
+-----------------------+
| | 0xFFF - End of Memory
+-----------------------+
| |
| |
| |
| 0x200/0xFFF |
| ProgramData |
| |
| |
+-----------------------+ 0x200 - Start of Chip8 programs
| |
| 0x00/0x1FF |
| Reserved for Chip8 |
| |
+-----------------------+ 0x00 - Start of Chip8 RAM
#+end_src
Chip-8 has a stack that is an array of 16 16-bit values, used to store the
addresses that the Chip8 should return to when returning from a subroutine,
meaning there can be 16 levels of nested subroutines.
** Registers
Chip8 has 16 8-bit data registers, each can hold 1 byte of information.
| Data Registers |
|----------------|
| V0 |
| V1 |
| V2 |
| V3 |
| V4 |
| V5 |
| V6 |
| V7 |
| V8 |
| V9 |
| VA |
| VB |
| VC |
| VD |
| VE |
| VF |
That means that the registers should be implemented as an array with a size of
16:
| V0 | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | ... |
The Chip 8 also has some extra registers:
- *I* - used to store memory addresses.
- *PC* - points to the address oft he current instruction being executed. All the
instructions are 2 bytes in size, so this should be incremented by 2 per
instruction executed.
- *SP* - 8-bit stack pointer, points to a location in the stack.
- *Sound Timer*:
- Chip8 plays a beep when the sound timer is not zero
- Decrements at a rate of 70hz
- When zero no sound is played
- *Delay Timer*:
- Chip8 stops executing instructions when the delay timer is greater than
zero.
- This is also decremented at a rate of 60hz.
- When the delay timer is zero, the program execution resumes.
** The Display
The size of the display is 64x32 pixels, and it's monocrome. Drawing to the
display is done with sprites, not pixels. If a sprite overflows the screen, it
wraps it back to the other side. The sprites can be a maximum of 8 bits of
width, and up to 15 bytes in length.
** The Keyboard
The Chip-8 keyboard has 16 keys: from 0 to F.
This is how the keyboard looks:
| 1 | 2 | 3 | C |
| 4 | 5 | 6 | D |
| 7 | 8 | 9 | E |
| A | 0 | B | F |
** Instruction Set
The Chip-8 instruction set has 36 different insturctions. These instructions can
be for mathematical operations, drawing and more.

38
src/main.c Normal file
View File

@ -0,0 +1,38 @@
#include <SDL2/SDL.h>
#include <stdio.h>
int
main (int argc, char **argv)
{
SDL_Init (SDL_INIT_EVERYTHING);
SDL_Window *window
= SDL_CreateWindow ("Chip8", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 640, 320, SDL_WINDOW_SHOWN);
SDL_Renderer *renderer
= SDL_CreateRenderer (window, -1, SDL_TEXTUREACCESS_TARGET);
while (1)
{
SDL_Event event;
while (SDL_PollEvent (&event))
{
if (event.type == SDL_QUIT)
{
goto out;
}
}
SDL_SetRenderDrawColor (renderer, 0, 0, 0, 0);
SDL_RenderClear (renderer);
SDL_SetRenderDrawColor (renderer, 255, 255, 255, 0);
SDL_Rect r = { 0, 0, 40, 40 };
SDL_RenderFillRect (renderer, &r);
SDL_RenderPresent (renderer);
}
out:
SDL_DestroyWindow (window);
return 0;
}