libc8
CHIP-8 utility library
|
#include <stdint.h>
#include <stdlib.h>
Go to the source code of this file.
Data Structures | |
struct | instruction_format_t |
Represents a valid instruction format. More... | |
struct | instruction_t |
Represents an instruction. More... | |
struct | label_t |
Represents a label. More... | |
struct | label_list_t |
Represents a list of labels. More... | |
struct | symbol_t |
Represents a symbol with a type, value, and line number. More... | |
struct | symbol_list_t |
Represents a symbol with a type, value, and line number. More... | |
Macros | |
#define | INSTRUCTION_COUNT 64 |
#define | LABEL_CEILING 64 |
#define | LABEL_IDENTIFIER_SIZE 20 |
#define | SYMBOL_CEILING 64 |
#define | S_CLS "CLS" |
#define | S_RET "RET" |
#define | S_JP "JP" |
#define | S_CALL "CALL" |
#define | S_SE "SE" |
#define | S_SNE "SNE" |
#define | S_LD "LD" |
#define | S_ADD "ADD" |
#define | S_OR "OR" |
#define | S_AND "AND" |
#define | S_SUB "SUB" |
#define | S_SHR "SHR" |
#define | S_SUBN "SUBN" |
#define | S_SHL "SHL" |
#define | S_RND "RND" |
#define | S_DRW "DRW" |
#define | S_SKP "SKP" |
#define | S_SKNP "SKNP" |
#define | S_XOR "XOR" |
#define | S_SCD "SCD" |
#define | S_SCR "SCR" |
#define | S_SCL "SCL" |
#define | S_EXIT "EXIT" |
#define | S_LOW "LOW" |
#define | S_HIGH "HIGH" |
#define | S_JP_V0 "JP V0," |
#define | S_K "K" |
#define | S_F "F" |
#define | S_B "B" |
#define | S_DT "DT" |
#define | S_ST "ST" |
#define | S_I "I" |
#define | S_IP "[I]" |
#define | S_DB ".DB" |
#define | S_DW ".DW" |
#define | S_DS ".DS" |
#define | S_HF "HF" |
#define | S_R "R" |
Enumerations | |
enum | Instruction { I_NULL = -1 , I_CLS , I_RET , I_JP , I_CALL , I_SE , I_SNE , I_LD , I_ADD , I_OR , I_AND , I_SUB , I_SHR , I_SUBN , I_SHL , I_RND , I_DRW , I_SKP , I_SKNP , I_XOR , I_SCD , I_SCR , I_SCL , I_EXIT , I_LOW , I_HIGH , I_JP_V0 } |
Represents instruction types. More... | |
enum | Symbol { SYM_NULL , SYM_DT , SYM_ST , SYM_I , SYM_IP , SYM_K , SYM_F , SYM_B , SYM_DB , SYM_DW , SYM_DS , SYM_HF , SYM_R , SYM_LABEL , SYM_INT , SYM_INT4 , SYM_INT8 , SYM_INT12 , SYM_STRING , SYM_V , SYM_INSTRUCTION , SYM_LABEL_DEFINITION } |
Represents symbol types. More... | |
Functions | |
int | build_instruction (instruction_t *, symbol_list_t *, int) |
Build an instruction from symbols beginning at idx. | |
int | is_comment (const char *) |
Check if the given string is a comment. | |
int | is_db (const char *) |
Check if given string is a DB identifier. | |
int | is_ds (const char *) |
Check if given string is a DS identifier. | |
int | is_dw (const char *) |
Check if given string is a DW identifier. | |
int | is_instruction (const char *) |
Check if the given string is an instruction. | |
int | is_label_definition (const char *) |
Check if the given string is a label definition. | |
int | is_label (const char *, const label_list_t *) |
Check if given string is a label reference. | |
int | is_register (const char *) |
Check if the given string represents a V register. | |
int | is_reserved_identifier (const char *) |
Check if given string is a reserved identifier. | |
symbol_t * | next_symbol (symbol_list_t *) |
Get the next symbol. | |
int | populate_labels (label_list_t *) |
Populate label list from lines. | |
int | resolve_labels (symbol_list_t *, label_list_t *) |
Get byte indexes of label definitions from completed symbol table. | |
int | shift (uint16_t) |
Find the bits needed to shift to OR a parameter into an instruction. | |
int | substitute_labels (symbol_list_t *, label_list_t *) |
Substitute label symbols with their corresponding int value. | |
Variables | |
const char * | c8_instructionStrings [] |
const char * | c8_identifierStrings [] |
instruction_format_t | formats [] |
Stuff for parsing symbols and instructions for encoding CHIP-8 "assembly".
#define INSTRUCTION_COUNT 64 |
#define LABEL_CEILING 64 |
#define LABEL_IDENTIFIER_SIZE 20 |
#define S_ADD "ADD" |
#define S_AND "AND" |
#define S_B "B" |
#define S_CALL "CALL" |
#define S_CLS "CLS" |
#define S_DB ".DB" |
#define S_DRW "DRW" |
#define S_DS ".DS" |
#define S_DT "DT" |
#define S_DW ".DW" |
#define S_EXIT "EXIT" |
#define S_F "F" |
#define S_HF "HF" |
#define S_HIGH "HIGH" |
#define S_I "I" |
#define S_IP "[I]" |
#define S_JP "JP" |
#define S_JP_V0 "JP V0," |
#define S_K "K" |
#define S_LD "LD" |
#define S_LOW "LOW" |
#define S_OR "OR" |
#define S_R "R" |
#define S_RET "RET" |
#define S_RND "RND" |
#define S_SCD "SCD" |
#define S_SCL "SCL" |
#define S_SCR "SCR" |
#define S_SE "SE" |
#define S_SHL "SHL" |
#define S_SHR "SHR" |
#define S_SKNP "SKNP" |
#define S_SKP "SKP" |
#define S_SNE "SNE" |
#define S_ST "ST" |
#define S_SUB "SUB" |
#define S_SUBN "SUBN" |
#define S_XOR "XOR" |
#define SYMBOL_CEILING 64 |
enum Instruction |
Represents instruction types.
This enumeration defines all possible CHIP-8 instructions.
NOTE: values to be kept in same order as instructionStrings
Enumerator | |
---|---|
I_NULL | |
I_CLS | |
I_RET | |
I_JP | |
I_CALL | |
I_SE | |
I_SNE | |
I_LD | |
I_ADD | |
I_OR | |
I_AND | |
I_SUB | |
I_SHR | |
I_SUBN | |
I_SHL | |
I_RND | |
I_DRW | |
I_SKP | |
I_SKNP | |
I_XOR | |
I_SCD | |
I_SCR | |
I_SCL | |
I_EXIT | |
I_LOW | |
I_HIGH | |
I_JP_V0 |
enum Symbol |
Represents symbol types.
This enumeration defines all symbol types found during the first assembler pass.
NOTE: values before label need to be kept in same order as identifierStrings
Enumerator | |
---|---|
SYM_NULL | |
SYM_DT | |
SYM_ST | |
SYM_I | |
SYM_IP | |
SYM_K | |
SYM_F | |
SYM_B | |
SYM_DB | |
SYM_DW | |
SYM_DS | |
SYM_HF | |
SYM_R | |
SYM_LABEL | |
SYM_INT | |
SYM_INT4 | |
SYM_INT8 | |
SYM_INT12 | |
SYM_STRING | |
SYM_V | |
SYM_INSTRUCTION | |
SYM_LABEL_DEFINITION |
int build_instruction | ( | instruction_t * | ins, |
symbol_list_t * | symbols, | ||
int | idx | ||
) |
Build an instruction from symbols beginning at idx.
This function builds an instruction from a completely parsed set of symbols (with labels expanded).
ins | instruction_t to store instruction contents |
symbols | symbol list |
idx | symbols index of start of instruction |
int is_comment | ( | const char * | s | ) |
Check if the given string is a comment.
s | the string to check |
int is_db | ( | const char * | s | ) |
Check if given string is a DB identifier.
int is_ds | ( | const char * | s | ) |
Check if given string is a DS identifier.
int is_dw | ( | const char * | s | ) |
Check if given string is a DW identifier.
int is_instruction | ( | const char * | s | ) |
Check if the given string is an instruction.
s | the string to check |
int is_label | ( | const char * | s, |
const label_list_t * | labels | ||
) |
Check if given string is a label reference.
This function checks if the given string is a label reference by comparing it against the label list. It returns the index of the label in the label list if it is found, or -1 if it is not.
This function assumes that the label list has been populated (e.g. populate_labels()
has been called).
s | string to check |
labels | label list to check from |
int is_label_definition | ( | const char * | s | ) |
Check if the given string is a label definition.
s | the string to check |
int is_register | ( | const char * | s | ) |
Check if the given string represents a V register.
This function checks if the given string starts with 'V' or 'v' and is followed by a valid hexadecimal digit (0-9, A-F, a-f). It returns the register number if it is a valid V register, or -1 if it is not.
s | string to check |
int is_reserved_identifier | ( | const char * | s | ) |
Check if given string is a reserved identifier.
This function checks if the given string is one of the reserved identifiers defined in c8_identifierStrings
. It returns the index of the identifier if it is found, or -1 if it is not.
s | string to check |
symbol_t * next_symbol | ( | symbol_list_t * | symbols | ) |
Get the next symbol.
This function retrieves the next available symbol in the symbol list. If the symbol list is empty, it initializes the first symbol. If the symbol list is full, it reallocates the symbol list to accommodate more symbols.
If symbols is NULL
or the symbol list is NULL
, it returns NULL
.
symbols | symbol list to get next symbol from |
int populate_labels | ( | label_list_t * | labels | ) |
Populate label list from lines.
This function scans through the lines of code and identifies label definitions. It checks each line for a label definition (ending with a colon) and adds it to the label list.
If a duplicate label definition is found, it throws a DUPLICATE_LABEL_EXCEPTION
.
If too many labels are defined, it throws a TOO_MANY_LABELS_EXCEPTION
.
lines | lines to search |
lineCount | number of lines to search |
labels | label list to populate |
int resolve_labels | ( | symbol_list_t * | symbols, |
label_list_t * | labels | ||
) |
Get byte indexes of label definitions from completed symbol table.
This function resolves label definitions in the symbol list and populates the label list with the byte index of each label definition. It iterates through the symbols, keeping track of the current byte position in the program. When it encounters a label definition, it records the current byte position in the label list. It also increments the byte position based on the type of symbol encountered (e.g., SYM_DB
increments by 1, SYM_INSTRUCTION
and SYM_DW
increment by 2).
This function assumes that the symbol list has been populated and that the symbols have been parsed correctly. It also assumes that the label list has been initialized.
This function will return 1 if all labels were resolved successfully, or 0 if there was a failure (e.g., if the label list is not fully populated).
This function will throw a NULL_ARGUMENT_EXCEPTION if either symbols
or labels
is NULL.
symbols | list of symbols |
labels | list of labels |
int shift | ( | uint16_t | fmt | ) |
Find the bits needed to shift to OR a parameter into an instruction.
This function finds the bits needed to shift to OR a parameter into an instruction. It is used to determine the position of parameters in the instruction bytecode.
This is a workaround for the fact that the instruction formats are not defined in a way that allows for easy bit manipulation.
fmt | instruction_format_t pformat to check |
int substitute_labels | ( | symbol_list_t * | symbols, |
label_list_t * | labels | ||
) |
Substitute label symbols with their corresponding int value.
This function replaces all symbols of type SYM_LABEL
in the symbol list with their corresponding byte value from the label list. It checks if the label exists and throws an INVALID_SYMBOL_EXCEPTION
if it does not.
This function assumes that the label list has been populated and that their byte values have been set correctly.
symbols | symbols to search |
labels | labels to search |
|
extern |
Reserved identifier strings. Has to match Symbol
.
|
extern |
Instruction strings. Has to match Instruction
.
|
extern |
All valid instruction formats