+#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
uint8_t params[3];
} instruction_default = {false, 0, 0, 0, 0};
-void parse_line(FILE** input_file)
+struct label_t
{
- char line_buffer[256];
+ char* label_name;
+ uint16_t addr;
+};
+
+struct inst_t parse_line(char* line_buffer, struct label_t* labels, unsigned int* labels_len)
+{
+ static unsigned int labels_index = 0;
+ static uint16_t current_addr = 0;
int token_count = 0;
char* token;
struct inst_t inst = instruction_default;
- fgets(line_buffer, 256, *input_file);
-
if(line_buffer[0] == ';')
{
- return;
+ return inst;
+ }
+ else if(line_buffer[0] == '$')
+ {
+ struct label_t label;
+
+ int i = 0;
+ while(i < 256)
+ {
+ if(isspace(line_buffer[i]))
+ {
+ line_buffer[i] = '\0';
+ }
+ i++;
+ }
+
+ label.label_name = malloc(256);
+ strcpy(label.label_name, line_buffer);
+ label.addr = current_addr;
+ if(labels_index + 1 == labels_len)
+ {
+ *labels_len = *labels_len + 16;
+ labels = realloc(labels, (*labels_len) * sizeof(struct label_t));
+ }
+ labels[labels_index] = label;
+ labels_index++;
+ return inst;
}
else
{
uint8_t i = 0;
while(i < N_INSTRUCTIONS - 1)
{
+ int token_len = strlen(token);
+ if(token_len != 3)
+ {
+ int i = 0;
+ while(i < token_len)
+ {
+ if(isspace(token[i]))
+ {
+ token[i] = '\0';
+ }
+ i++;
+ }
+ }
if(strcmp(token, opcodes_strings[i]) == 0)
{
inst.instruction_code = i;
break;
case 2:
// current token is second parameter
- uint16_t token_int = atoi(token);
- inst.params[1] = token_int;
+ if(token[0] == '$')
+ {
+ int i = 0;
+ int token_len = strlen(token);
+ while(i < token_len)
+ {
+ if(isspace(token[i]))
+ {
+ token[i] = '\0';
+ }
+ i++;
+ }
+
+ int j = 0;
+ bool label_known = false;
+ while(j < labels_index)
+ {
+ if(strcmp(labels[j].label_name, token) == 0)
+ {
+ inst.params[1] = (uint8_t)(labels[j].addr >> 8);
+ inst.params[2] = (uint8_t)(labels[j].addr);
+ label_known = true;
+ break;
+ }
+ j++;
+ }
+ if(!label_known)
+ {
+ perror("Unknown identifier\n");
+ exit(1);
+ }
+ break;
+ }
+ else
+ {
+ uint16_t token_int = atoi(token);
+ inst.params[1] = (uint8_t)(token_int >> 8);
+ inst.params[2] = (uint8_t)(token_int);
+ break;
+ }
break;
case 3:
// current token is third parameter
token_count++;
token = strtok(NULL, " ");
}
+ current_addr = current_addr + 4;
+ return inst;
+}
+
+void write_instruction(FILE** output_file, struct inst_t inst)
+{
+ if(inst.contains_instruction)
+ {
+ fwrite(&inst.instruction_code, sizeof(uint8_t), 4, *output_file);
+ }
}
int main(int argc, char *argv[])
{
+ unsigned int labels_len = 10;
+ struct label_t* labels = malloc(labels_len * sizeof(struct label_t));
if(argc <= 2 || argc >= 4)
{
return 1;
}
- FILE* output_file = fopen(argv[2], "w");
+ FILE* output_file = fopen(argv[2], "wb");
if(!output_file)
{
perror("Cannot open output file for writing\n");
return 1;
}
- while(!feof(input_file))
+
+ unsigned int line_num = 0;
+ char line_buffer[256];
+ while(fgets(line_buffer, 256, input_file))
{
- parse_line(&input_file);
+ line_num++;
+ write_instruction(&output_file, parse_line(line_buffer, labels, &labels_len));
}
}