s502 assembler
A very simple assembler for the 6502 line of processors written in C
Public Member Functions | Data Fields
Instruction Class Reference

linked list member holding instruction data More...

#include <instructions.h>

Public Member Functions

Instructioninstruction_load (char *fname)
 Load instruction data from CSV file. More...
 
Instructioninstruction_find (Instruction *list, char *mnem)
 find the Instruction entry for a given mnemonic More...
 
void instruction_free (Instruction *list)
 free all memory associated with an Instruction* list More...
 
void instruction_print (Instruction *instr)
 fancy-print one instruction data More...
 
void instruction_print_all (Instruction *list)
 debug-print all instructions in a list More...
 

Data Fields

char mnem [4]
 3-letter mnemonic of an instruction + trailing 0 More...
 
unsigned char opcs [ADRM_COUNT]
 Different combinarions of this instruction. Invalid ones are set to OPC_INVALID. More...
 
struct Instructionnext
 Next instruction pointer on NULL. More...
 

Detailed Description

linked list member holding instruction data

Member of a list which holds data about instructions and opcodes.
This list should be loaded from file using instruction_load()

Definition at line 25 of file instructions.h.

Member Function Documentation

◆ instruction_find()

Instruction * instruction_find ( Instruction list,
char *  mnem 
)

find the Instruction entry for a given mnemonic

Parameters
listlinked list head containing loaded instructions
mnempointer to string to seatch for
Returns
instruction list entry or NULL if not found

Searches the linked list for an instruction entry.
Only checks the first 3 characters, so there is no need to copy the data on the caller side.

Definition at line 111 of file instructions.c.

111  {
112  Instruction* ptr;
113  for (ptr = list; ptr != NULL; ptr = ptr->next) {
114  if (util_match_string(mnem, ptr->mnem, 3) == 0)
115  return ptr;
116  }
117  return NULL;
118 }

Referenced by Token::token_link_instruction().

◆ instruction_free()

void instruction_free ( Instruction list)

free all memory associated with an Instruction* list

Parameters
listlist to free

Frees all memory associated with the instruction data linked list, including the list head.
Invalidates all pointers to any data within the list, so they should be all NULL-ed!

Definition at line 121 of file instructions.c.

121  {
122  if (!list) return;
123  while (list->next != NULL) {
124  Instruction* ptr = list->next;
125  list->next = ptr->next;
126  free(ptr);
127  }
128  free(list);
129 }

Referenced by instruction_load(), and state_free().

◆ instruction_load()

Instruction * instruction_load ( char *  fname)

Load instruction data from CSV file.

Parameters
fnameCSV file name/path to load from
Returns
loaded instructions or NULL on error

Opens the file, parses CSV and returns instruction data.
Checks for simple problems. Prints errors.
Returns NULL on error, and linked list (withut sentinel) otherwise.
Works both on Windows and Linux platforms with the same files.

Definition at line 18 of file instructions.c.

18  {
19  FILE* f = fopen(fname, "r");
20  if (f == NULL) {
21  ERROR("An error occured opening the file %s!\n", fname);
22  ERROR("Error opening file: %s\n", strerror(errno));
23  return NULL;
24  }
25 
26  int rowindex = 0;
27  char buff[16];
28 
29  int ptr = 0;
30  int row = 1;
31  Instruction* list = malloc(sizeof(Instruction));
32 
33  // ignore first line
34  // (Also possibly has BOM for unicode)
35  int x;
36  while (x = fgetc(f), x != '\n' && x != EOF);
37  if (x == EOF) {
38  goto ERR_MALFORMED;
39  }
40  if (list == NULL) goto ERR_MEM;
41  list->next = NULL;
42  Instruction* curr = list;
43 
44 
45  while (x = fgetc(f), x != EOF) {
46  if (x == '\r') continue; // quick and dirty fix for linux opening a windows file
47  if (x == ';' || x == '\n') {
48  // end of column
49  buff[ptr] = 0;
50 
51  // process data
52  if (rowindex == 0) {
53  if (ptr != 3) goto ERR_MALFORMED;
54  memcpy(curr->mnem, buff, 3);
55  curr->mnem[3] = 0;
56  } else {
57  if (ptr != 2 && ptr != 0) goto ERR_MALFORMED;
58  if (ptr)
59  curr->opcs[rowindex - 1] = 16 * number_char_to_digit(buff[0]) + number_char_to_digit(buff[1]);
60  else
61  curr->opcs[rowindex - 1] = OPC_INVALID;
62  }
63  ptr = 0;
64  rowindex++;
65  if (x == '\n') {
66  if (rowindex != 14)
67  goto ERR_MALFORMED;
68  rowindex = 0;
69  row++;
70 
71  curr->next = malloc(sizeof(Instruction));
72  if (curr->next == NULL) goto ERR_MEM;
73  curr->next->next = NULL;
74  curr = curr->next;
75  }
76 
77 
78  continue;
79  }
80  buff[ptr++] = x;
81  }
82 
83  // file might had a trailing newline
84  // in that case the last entry is not valid
85 
86  if (rowindex == 0) {
87  for (curr = list; curr->next != NULL && curr->next->next != NULL; curr = curr->next);
88  free(curr->next);
89  curr->next = NULL;
90  }
91 
92  fclose(f);
93  return list;
94 ERR_MALFORMED:
95  ERROR("Malformed instruction line:column: %d : %d\n", row + 1, rowindex + 1);
96  ERROR("Malformed instructions/opcodes file: %s\n", fname);
97  goto CLEANUP;
98 
99 ERR_MEM:
100  ERROR("Memory allocation error in instruction_load()!\n");
101  goto CLEANUP;
102 
103 CLEANUP:
104  instruction_free(list);
105  fclose(f);
106 
107  return NULL;
108 }

Referenced by state_load_instr().

◆ instruction_print()

void instruction_print ( Instruction instr)

fancy-print one instruction data

Parameters
instrinstruction list entry to print

Fancy-print all data associated with one instruction (mnemonic, address modes and opcodes for them).
Useful for error reporting and debugging.

Definition at line 132 of file instructions.c.

132  {
133  printf("%s", instr->mnem);
134  for (int i = 0; i < ADRM_COUNT; i++)
135  if (instr->opcs[i] != OPC_INVALID) {
136  printf("\t%s:\t%x\n", ADRM_NAMES[i], instr->opcs[i]);
137  }
138  printf("\n");
139 }

Referenced by instruction_print_all(), and pass_one().

◆ instruction_print_all()

void instruction_print_all ( Instruction list)

debug-print all instructions in a list

Parameters
listlist of instructions to print

Fancy-print all instructions from the list using instruction_print()
Useful for debugging

Definition at line 141 of file instructions.c.

141  {
142  for (; list != NULL; list = list->next) {
143  instruction_print(list);
144  }
145 }

Field Documentation

◆ mnem

char Instruction::mnem[4]

3-letter mnemonic of an instruction + trailing 0

Definition at line 27 of file instructions.h.

Referenced by instruction_find(), instruction_load(), and instruction_print().

◆ next

struct Instruction* Instruction::next

Next instruction pointer on NULL.

Definition at line 31 of file instructions.h.

Referenced by instruction_find(), instruction_free(), instruction_load(), and instruction_print_all().

◆ opcs

unsigned char Instruction::opcs[ADRM_COUNT]

Different combinarions of this instruction. Invalid ones are set to OPC_INVALID.

Definition at line 29 of file instructions.h.

Referenced by instruction_load(), and instruction_print().


The documentation for this class was generated from the following file:
ADRM_NAMES
const char * ADRM_NAMES[]
Human-readable names of address modes.
Definition: addressmode.c:16
ADRM_COUNT
@ ADRM_COUNT
Total number of addressing modes.
Definition: addressmode.h:51
Instruction::instruction_free
void instruction_free(Instruction *list)
free all memory associated with an Instruction* list
Definition: instructions.c:121
Instruction::mnem
char mnem[4]
3-letter mnemonic of an instruction + trailing 0
Definition: instructions.h:27
Instruction::next
struct Instruction * next
Next instruction pointer on NULL.
Definition: instructions.h:31
Instruction::instruction_print
void instruction_print(Instruction *instr)
fancy-print one instruction data
Definition: instructions.c:132
util_match_string
int util_match_string(char *first, char *second, int count)
case-insensitive memcmp
Definition: util.c:32
Instruction
linked list member holding instruction data
Definition: instructions.h:25
Instruction::opcs
unsigned char opcs[ADRM_COUNT]
Different combinarions of this instruction. Invalid ones are set to OPC_INVALID.
Definition: instructions.h:29
number_char_to_digit
int number_char_to_digit(char c)
Convert a hex char to a digit.
Definition: number.c:12
OPC_INVALID
@ OPC_INVALID
An invalid opcode to signal invalid / non-existent variations.
Definition: instructions.h:15
ERROR
#define ERROR(...)
Fancy-print an error (cause of faliure). Works like printf.
Definition: logging.h:40