s502 assembler
A very simple assembler for the 6502 line of processors written in C
Functions
instructions.c File Reference

Implement funtions defined in instructions.h. More...

#include "debugmalloc.h"
#include <stdio.h>
#include <errno.h>
#include "logging.h"
#include "number.h"
#include "addressmode.h"
#include "instructions.h"
#include "util.h"

Go to the source code of this file.

Functions

Instructioninstruction_load (char *fname)
 
Instructioninstruction_find (Instruction *list, char *mnem)
 
void instruction_free (Instruction *list)
 
void instruction_print (Instruction *instr)
 
void instruction_print_all (Instruction *list)
 

Detailed Description

Implement funtions defined in instructions.h.

Definition in file instructions.c.

Function Documentation

◆ instruction_find()

Instruction* instruction_find ( Instruction list,
char *  mnem 
)

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 }

References Instruction::mnem, Instruction::next, and util_match_string().

◆ instruction_free()

void instruction_free ( Instruction list)

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 }

References Instruction::next.

◆ instruction_load()

Instruction* instruction_load ( char *  fname)

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 }

References ERROR, Instruction::instruction_free(), Instruction::mnem, Instruction::next, number_char_to_digit(), OPC_INVALID, and Instruction::opcs.

◆ instruction_print()

void instruction_print ( Instruction instr)

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 }

References ADRM_COUNT, ADRM_NAMES, Instruction::mnem, OPC_INVALID, and Instruction::opcs.

◆ instruction_print_all()

void instruction_print_all ( Instruction list)

Definition at line 141 of file instructions.c.

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

References Instruction::instruction_print(), and Instruction::next.

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