Skip to content

Instantly share code, notes, and snippets.

@crcx
Created April 27, 2017 15:13
Show Gist options
  • Select an option

  • Save crcx/7b491b8e83bd7e78ce7cc3da4d156ff5 to your computer and use it in GitHub Desktop.

Select an option

Save crcx/7b491b8e83bd7e78ce7cc3da4d156ff5 to your computer and use it in GitHub Desktop.
Muri: An Alternative Assembler for Nga
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define KiB * 1024
#define MAX_NAMES 1024
#define STRING_LEN 64
int32_t target[128 KiB];
int32_t here;
char Labels[MAX_NAMES][STRING_LEN];
int32_t Pointers[MAX_NAMES];
int32_t np;
void save() {
FILE *fp;
if ((fp = fopen("muri.image", "wb")) == NULL) {
printf("Unable to save the image!\n");
exit(2);
}
fwrite(&target, sizeof(int32_t), here, fp);
fclose(fp);
}
int32_t lookup(char *name) {
int32_t slice = -1;
int32_t n = np;
while (n > 0) {
n--;
if (strcmp(Labels[n], name) == 0)
slice = Pointers[n];
}
return slice;
}
void add_label(char *name, int32_t slice) {
if (lookup(name) == -1) {
strcpy(Labels[np], name);
Pointers[np] = slice;
np++;
} else {
printf("Fatal error: %s already defined\n", name);
exit(0);
}
}
void read_line(FILE *file, char *line_buffer) {
if (file == NULL || line_buffer == NULL)
{
printf("Error: file or line buffer pointer is null.");
exit(1);
}
int ch = getc(file);
int count = 0;
while ((ch != '\n') && (ch != EOF)) {
line_buffer[count] = ch;
count++;
ch = getc(file);
}
line_buffer[count] = '\0';
}
char source[16 KiB];
int32_t opcode_for(char *s) {
if (strcmp(s, "..") == 0) return 0; if (strcmp(s, "li") == 0) return 1;
if (strcmp(s, "du") == 0) return 2; if (strcmp(s, "dr") == 0) return 3;
if (strcmp(s, "sw") == 0) return 4; if (strcmp(s, "pu") == 0) return 5;
if (strcmp(s, "po") == 0) return 6; if (strcmp(s, "ju") == 0) return 7;
if (strcmp(s, "ca") == 0) return 8; if (strcmp(s, "cc") == 0) return 9;
if (strcmp(s, "re") == 0) return 10; if (strcmp(s, "eq") == 0) return 11;
if (strcmp(s, "ne") == 0) return 12; if (strcmp(s, "lt") == 0) return 13;
if (strcmp(s, "gt") == 0) return 14; if (strcmp(s, "fe") == 0) return 15;
if (strcmp(s, "st") == 0) return 16; if (strcmp(s, "ad") == 0) return 17;
if (strcmp(s, "su") == 0) return 18; if (strcmp(s, "mu") == 0) return 19;
if (strcmp(s, "di") == 0) return 20; if (strcmp(s, "an") == 0) return 21;
if (strcmp(s, "or") == 0) return 22; if (strcmp(s, "xo") == 0) return 23;
if (strcmp(s, "sh") == 0) return 24; if (strcmp(s, "zr") == 0) return 25;
if (strcmp(s, "en") == 0) return 26;
return 0;
}
void pass1(char *fname) {
char *buffer = (char *)source;
char command;
unsigned int opcode;
char inst[3];
inst[2] = '\0';
FILE *fp;
here = 0;
fp = fopen(fname, "r");
if (fp == NULL)
return;
while (!feof(fp)) {
read_line(fp, buffer);
if (buffer[1] != '\t') {
printf("ERROR: Invalid line\n");
exit(2);
}
command = buffer[0];
opcode = 0;
switch (command) {
case 'i': memcpy(inst, buffer + 8, 2);
opcode = opcode_for(inst);
opcode = opcode << 8;
memcpy(inst, buffer + 6, 2);
opcode += opcode_for(inst);
opcode = opcode << 8;
memcpy(inst, buffer + 4, 2);
opcode += opcode_for(inst);
opcode = opcode << 8;
memcpy(inst, buffer + 2, 2);
opcode += opcode_for(inst);
target[here++] = opcode;
break;
case 'r': target[here++] = 9999;
break;
case 'd': target[here++] = atoi(buffer+2);
break;
case 'c': target[here++] = buffer[2];
break;
case 's': printf("String\n");
break;
case ':': add_label(buffer+2, here);
break;
}
}
fclose(fp);
}
void pass2(char *fname) {
char *buffer = (char *)source;
char command;
FILE *fp;
here = 0;
fp = fopen(fname, "r");
if (fp == NULL)
return;
while (!feof(fp)) {
read_line(fp, buffer);
if (buffer[1] != '\t') {
printf("ERROR: Invalid line\n");
exit(2);
}
command = buffer[0];
switch (command) {
case 'i': here++;
break;
case 'r': target[here++] = lookup(buffer+2);
break;
case 'd': here++;
break;
case 'c': here++;
break;
case 's': break;
case ':': break;
}
}
fclose(fp);
}
int main(int argc, char **argv) {
np = 0;
int i = 1;
if (argc > 1) {
pass1(argv[1]);
pass2(argv[1]);
for(int i = 0; i < here; i++)
printf("%d,", target[i]);
printf("\n");
for(int i = 0; i < np; i++)
printf("%s,", Labels[i]);
printf("\n");
save();
}
else
printf("muri\n(c) 2017 charles childers\n\nTry:\n %s filename\n", argv[0]);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment