#include "asmmon.h"
uint16_t linenum = 10;
uint16_t lineidx = 0;
uint16_t stridx = 0;
uint16_t comidx = 0;
uint16_t inc_file = 0;
uint8_t defined = 0;
uint8_t isfixup = 0;
char lexeme[MAX_TOK];
char *string[MAX_TOK];
char *comment[MAX_TOK];
uint16_t incl[MAX_TOK];
struct line tokline[MAX_TOK];
struct line tln[MAX_TOK];
struct symbol *symbols[MAX_TOK];
struct fixup *fixups[MAX_TOK];
static char tstr[2048];
void viewmem(uint64_t address) {
putchar('\n');
printf("\t\t\t");
for (uint8_t ind = 0; ind < 0x10; ind++) {
printf("%02X", ind);
if (ind < 0x0F) {
putchar(' ');
}
}
puts("\n");
for (uint8_t hi = 0; hi < 0x10; hi++) {
printf("$%016"PRIX64":\t", (address & ~0xF)+(hi << 4));
for (uint8_t lo = 0; lo < 0x10; lo++) {
printf("%02X", addr[(address & ~0xF)+lo+(hi << 4)]);
if (lo < 0x0F) {
putchar(' ');
}
}
putchar('\n');
}
}
void usage() {
puts("SuBAsm for CISC-0.2");
puts("Commands:");
puts("\tasm, a\t\t\tAssembles the currently written program.");
puts("\tinst, i [inst]\t\tGet a descriptions of that instruction.");
puts("\t\t\t\tIf no argument is specified, or the");
puts("\t\t\t\targument specified is \"all\", list all");
puts("\t\t\t\tinstructions, along with a description");
puts("\t\t\t\tfor each of them.");
puts("\tlist, l [$%][start][-][$%][end] [d[ebug], l[inenum], a[ddress]]]");
puts("\t\t\t\tLists the currently written program.");
puts("\tviewmem, v\t\tGet the contents of memory");
puts("\t\t\t\t(Displays 256 bytes of memory");
puts("\t\t\t\t starting from where the program counter");
puts("\t\t\t\t currently is).");
puts("\tquit, q\t\t\tQuit the emulator.");
puts("\thelp, h\t\t\tDisplays this mesage.");
}
void instinfo(const char *inst) {
for(int i = 0; i < OPNUM; i++) {
if (inst[0] == mne[i][0]) {
if (!strcasecmp(inst, mne[i])) {
printf("%s\t%s\n", mne[i], instdesc[i]);
break;
}
} else if (inst[0] == 'a') {
if (!strcasecmp(inst, "all")) {
printf("%s\t%s\n", mne[i], instdesc[i]);
}
}
}
}
char *showbits(uint64_t value, uint8_t bitnum, uint8_t dbg) {
if (dbg) {
printf("showbits(): ");
}
char *bits = malloc((sizeof(uint64_t) << 3)+1);
char bit = 0;
uint8_t i;
uint8_t j = 0;
if (bitnum > 63) {
bitnum = (sizeof(uint64_t) << 3) - 1;
}
if (!bitnum) {
i = (sizeof(uint64_t) << 3) - 1;
} else {
i = bitnum;
}
for (; (value > 0 && !bitnum) || (j <= bitnum && bitnum); j++) {
if (value > 0 && !bitnum) {
bits[j] = (value & 1) ? '1' : '0';
value>>=1;
} else {
bits[j] = (value & ((uint64_t)1 << i)) ? '1' : '0';
i--;
}
}
bits[j] = '\0';
if (dbg) {
printf("bits: %s\n", bits);
}
return bits;
}
void list(struct line *l, uint16_t start, uint16_t end, uint8_t all, uint8_t ln, uint8_t addr, uint8_t dbg) {
uint16_t i = start;
uint8_t j = 0;
uint8_t flags = 0;
uint8_t isstr;
uint8_t iscom;
uint8_t iscm = 0;
uint8_t fall = 0;
uint8_t bitnum;
uint8_t opsize = 0;
uint8_t spaces;
uint8_t tabs;
char mne_lower[4];
char ch[6];
if (all) {
end = lineidx;
}
for (; i < end; i++) {
flags = 0;
flags |= (l[i].dir != 0x00FF) << 0;
flags |= (l[i].mne != 0x00FF) << 1;
flags |= (l[i].rs != 0x00FF) << 2;
flags |= (l[i].am != 0x00FF) << 3;
flags |= (l[i].opbase != 0x00FF) << 4;
flags |= (l[i].sym != 0xFFFF) << 5;
flags |= (l[i].rs != 0x00FF) << 6;
flags |= (l[i].am != 0x00FF) << 7;
iscm = l[i].cm != 0xFF;
isstr = l[i].str != 0xFFFF;
iscom = l[i].com != 0xFFFF;
if (dbg) {
printf("list(): ");
}
if (ln) {
printf("%u\t", l[i].linenum);
} else if (addr) {
printf("$%"PRIX64":\t", l[i].addr);
}
spaces = l[i].sspace;
tabs = l[i].stab;
while (spaces || tabs) {
if (spaces) {
putchar(' ');
spaces--;
}
if (tabs) {
putchar('\t');
tabs--;
}
}
if (flags & 0x01) {
printf(".%s ", dir_t[l[i].dir]);
if (isstr) {
printf("\"%s\"", string[l[i].str]);
}
}
if (flags & 0x02) {
for (; j < 3; j++) {
mne_lower[j] = tolower(mne[l[i].mne][j]);
}
mne_lower[j] = '\0';
j = 0;
printf("%s", mne_lower);
}
if (flags & 0x04) {
printf("%s ", rs_t[l[i].rs]);
} else if (flags & 0x02) {
printf(" ");
}
if (flags & 0x7F) {
switch (l[i].am) {
case IMM:
putchar('#');
break;
case INDX:
case INDY:
case IND:
putchar('(');
break;
}
}
if (flags & 0x20) {
printf("%s", symbols[l[i].sym]->name);
if (l[i].islabel) {
printf(": ");
} else if (l[i].issym) {
printf(" = ");
}
}
if (flags & 0x10) {
if (flags & 0x04) {
bitnum = (l[i].rs << 3);
} else {
opsize += (l[i].op <= 0x000000FF) + 0;
opsize += (l[i].op > 0x000000FF) + 1;
opsize += (l[i].op > 0x0000FFFF) + 2;
opsize += (l[i].op > 0xFFFFFFFF) + 3;
if (opsize) {
bitnum = bitsize[opsize-1];
}
}
j = 0;
if (l[i].opbase == BASE_CHAR) {
switch (l[i].op) {
default : ch[j++] = l[i].op; break;
case '\n': ch[j++] = '\\'; ch[j++] = 'n' ; break;
case '\r': ch[j++] = '\\'; ch[j++] = 'r' ; break;
case '\b': ch[j++] = '\\'; ch[j++] = 'b' ; break;
case '\\': ch[j++] = '\\'; ch[j++] = '\\'; break;
case '\'': ch[j++] = '\\'; ch[j++] = '\''; break;
case '\"': ch[j++] = '\\'; ch[j++] = '\"'; break;
}
}
ch[j] = '\0';
j = 0;
switch (l[i].opbase) {
case BASE_HEX: printf("$%"PRIX64, l[i].op); break;
case BASE_DEC: printf("%"PRIu64, l[i].op); break;
case BASE_BIN: printf("%%%s", showbits(l[i].op, bitnum, dbg)); break;
case BASE_CHAR: printf("\'%s\'", ch); break;
}
bitnum = 0;
opsize = 0;
}
if (iscm) {
switch (l[i].cm) {
case 0:
putchar('+');
break;
case 1:
putchar ('-');
break;
}
opsize += (l[i].aop <= 0x000000FF) + 0;
opsize += (l[i].aop > 0x000000FF) + 1;
opsize += (l[i].aop > 0x0000FFFF) + 2;
opsize += (l[i].aop > 0xFFFFFFFF) + 3;
if (opsize) {
bitnum = bitsize[opsize-1];
}
j = 0;
if (l[i].aopbase == BASE_CHAR) {
switch (l[i].aop) {
default : ch[j++] = l[i].aop; break;
case '\n': ch[j++] = '\\'; ch[j++] = 'n' ; break;
case '\r': ch[j++] = '\\'; ch[j++] = 'r' ; break;
case '\b': ch[j++] = '\\'; ch[j++] = 'b' ; break;
case '\\': ch[j++] = '\\'; ch[j++] = '\\'; break;
case '\'': ch[j++] = '\\'; ch[j++] = '\''; break;
case '\"': ch[j++] = '\\'; ch[j++] = '\"'; break;
}
}
ch[j] = '\0';
j = 0;
switch (l[i].aopbase) {
case BASE_HEX : printf("$%"PRIX64, l[i].aop); break;
case BASE_DEC : printf("%"PRIu64, l[i].aop); break;
case BASE_BIN : printf("%%%s", showbits(l[i].aop, bitnum, dbg)); break;
case BASE_CHAR: printf("\'%s\'", ch); break;
}
bitnum = 0;
opsize = 0;
}
if (flags & 0x7F) {
if (fall) {
fall = 0;
}
switch (l[i].am) {
case INDX:
case ZMX:
printf(", x");
if (l[i].am == ZMX) {
break;
}
fall = 1;
case INDY:
fall = !fall;
case IND:
putchar(')');
if (!fall) {
break;
}
case ZMY:
printf(", y");
break;
}
}
spaces = l[i].espace;
tabs = l[i].etab;
while (spaces || tabs) {
if (spaces) {
putchar(' ');
spaces--;
}
if (tabs) {
putchar('\t');
tabs--;
}
}
if (iscom) {
printf(";%s", comment[l[i].com]);
}
puts("");
}
}
void assemble(struct line *line, bytecount *bc, uint8_t dbg) {
bc->progsize = 0;
bc->datasize = 0;
uint64_t tmpaddr;
uint64_t value;
uint16_t flags = 0;
uint16_t i = 0;
uint16_t k = 0;
uint16_t tmp;
uint8_t c = 0;
uint8_t prefix = 0;
uint8_t opsize = 0;
uint8_t skip = 0;
uint64_t address;
uint64_t op;
uint64_t aop;
uint16_t symid;
uint16_t str;
uint16_t com;
uint8_t islabel;
uint8_t opbase;
uint8_t aopbase;
uint8_t dir;
uint8_t am;
uint8_t cm;
uint8_t rs;
uint8_t ins;
for (; i < lineidx; i++) {
if (dbg) {
printf("assemble(): i: $%X\n", i);
}
address = line[i].addr;
tmpaddr = address;
op = line[i].op;
aop = line[i].aop;
symid = line[i].sym;
str = line[i].str;
com = line[i].com;
islabel = line[i].islabel;
opbase = line[i].opbase;
aopbase = line[i].aopbase;
dir = line[i].dir;
am = line[i].am;
cm = line[i].cm;
rs = line[i].rs;
ins = line[i].mne;
flags = 0;
flags |= (dir != 0x00FF) << 0x00;
flags |= (ins != 0x00FF) << 0x01;
flags |= (rs != 0x00FF) << 0x02;
flags |= (am != 0x00FF) << 0x03;
flags |= (opbase != 0x00FF) << 0x04;
flags |= (aopbase != 0x00FF) << 0x05;
flags |= (symid != 0xFFFF) << 0x06;
flags |= (islabel ) << 0x07;
flags |= (am != 0x00FF) << 0x08;
flags |= (cm != 0x00FF) << 0x09;
flags |= (str != 0xFFFF) << 0x0A;
if (dbg) {
printf("assemble(): ");
putchar('%');
printf("%u", str != 0xFFFF);
printf("%u", cm != 0x00FF);
printf("%u", am != 0x00FF);
printf("%u", islabel );
printf("%u", symid != 0xFFFF);
printf("%u", aopbase != 0x00FF);
printf("%u", opbase != 0x00FF);
printf("%u", am != 0x00FF);
printf("%u", rs != 0x00FF);
printf("%u", ins != 0x00FF);
printf("%u", dir != 0x00FF);
putchar('\n');
printf("assemble(): ");
printf("flags: $%04X\n", flags);
}
if (!flags) {
if (dbg) {
printf("assemble(): ");
puts("This line only contains a comment, so skip it.");
}
continue;
}
opsize = 0;
skip = 0;
if ((flags & 0x53) == 0x42 || (flags & 0x51) == 0x41) {
value = symbols[symid]->val;
} else {
value = op;
}
if (flags & 0x220) {
switch (cm) {
case 0: value += aop; break;
case 1: value -= aop; break;
}
}
if (dbg) {
printf("assemble(): value: $%"PRIX64"\n", value);
}
switch (dir) {
case DIR_ORG:
tmpaddr = value;
if (dbg) {
printf("assemble(): ");
printf("The Program Counter's origin is now at, $%"PRIX64".\n", value);
}
skip = 1;
break;
case DIR_BYTE:
if (flags & 0x400) {
for (k = 0; string[str][k] != '\0'; k++) {
switch (string[str][k]) {
case '\\':
switch (string[str][k+1]) {
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case '0': c = '\0'; break;
}
k++;
break;
default:
c = string[str][k];
break;
}
bc->datasize++;
addr[tmpaddr++] = c;
}
addr[tmpaddr] = '\0';
if (dbg) {
printf("assemble(): ");
printf("Placed string \"%s\"", string[str]);
printf(", at address(es) $%"PRIX64"-$%"PRIX64".\n", address, tmpaddr);
}
} else {
bc->datasize++;
addr[tmpaddr++] = value & 0xFF;
}
break;
case DIR_QWORD:
addr[tmpaddr+7] = value >> 0x38;
addr[tmpaddr+6] = value >> 0x30;
addr[tmpaddr+5] = value >> 0x28;
addr[tmpaddr+4] = value >> 0x20;
tmp+=4;
bc->datasize+=4;
case DIR_DWORD:
addr[tmpaddr+3] = value >> 0x18;
addr[tmpaddr+2] = value >> 0x10;
tmp+=2;
bc->datasize+=2;
case DIR_WORD:
addr[tmpaddr+1] = value >> 0x08;
addr[tmpaddr ] = value & 0xFF;
tmp+=2;
bc->datasize+=2;
break;
}
tmpaddr += tmp;
tmp = 0;
if (skip | (flags & 0x80) | (flags == 0x108)) {
if (dbg) {
printf("assemble(): The address that this line starts at is, $%"PRIX64".\n", address);
printf("assemble(): The address that this line ends on is, $%"PRIX64".\n", tmpaddr);
}
continue;
}
if (flags & 0x04) {
prefix = (rs << 4) | 3;
} else {
rs = 0;
}
if (flags & 0x102) {
if (ins == 80) {
if (flags & 0x10) {
am = IMM;
prefix |= 0x13;
} else {
am = IMPL;
addr[tmpaddr++] = opcodes[ins][IMM];
bc->progsize++;
if (dbg) {
printf("assemble(): The instruction that is being used is, %s.\n", mne[ins]);
printf("assemble(): The addressing mode that this instruction is using is, %s.\n", adrmode[IMM]);
printf("assemble(): The opcode for this instruction, and addressing mode is, $%02X.\n", opcodes[ins][IMM]);
}
}
}
opsize = 0;
if (am != IMM && am != IMPL) {
opsize = (value <= 0x00000000000000FF) ? 1 : opsize;
opsize = (value > 0x00000000000000FF) ? 2 : opsize;
opsize = (value > 0x000000000000FFFF) ? 3 : opsize;
opsize = (value > 0x0000000000FFFFFF) ? 4 : opsize;
opsize = (value > 0x00000000FFFFFFFF) ? 5 : opsize;
opsize = (value > 0x000000FFFFFFFFFF) ? 6 : opsize;
opsize = (value > 0x0000FFFFFFFFFFFF) ? 7 : opsize;
opsize = (value > 0x00FFFFFFFFFFFFFF) ? 8 : opsize;
if (opsize) {
opsize--;
prefix |= amp[opsize];
}
}
if (prefix) {
if (dbg) {
printf("assemble(): ");
puts("Prefix byte detected.");
}
addr[tmpaddr++] = prefix;
bc->progsize++;
if (dbg) {
uint8_t addrsize = (prefix & 0x0C) >> 2;
uint8_t regsize = (prefix & 0x30) >> 4;
printf("assemble(): ");
printf("The values of the prefix bits are");
printf(", AM: %u, RS: %u\n", addrsize, regsize);
}
prefix = 0;
}
if (opcodes[ins][am] != 0xFF) {
addr[tmpaddr++] = opcodes[ins][am];
bc->progsize++;
if (dbg) {
printf("assemble(): The instruction that is being used is, %s.\n", mne[ins]);
printf("assemble(): The addressing mode that this instruction is using is, %s.\n", adrmode[am]);
printf("assemble(): The opcode for this instruction, and addressing mode is, $%02X.\n", opcodes[ins][am]);
}
switch (am) {
case IMM:
switch (rs) {
case 3:
addr[tmpaddr+7] = value >> 0x38;
addr[tmpaddr+6] = value >> 0x30;
addr[tmpaddr+5] = value >> 0x28;
addr[tmpaddr+4] = value >> 0x20;
tmp+=4;
case 2:
addr[tmpaddr+3] = value >> 0x18;
addr[tmpaddr+2] = value >> 0x10;
tmp+=2;
case 1:
addr[tmpaddr+1] = value >> 0x08;
tmp+=1;
case 0:
addr[tmpaddr ] = value & 0xFF;
tmp+=1;
}
break;
case ABS:
case ZM:
case ZMX:
case ZMY:
case IND:
case INDX:
case INDY:
switch (opsize) {
case 7: addr[tmpaddr+7] = value >> 0x38; tmp++;
case 6: addr[tmpaddr+6] = value >> 0x30; tmp++;
case 5: addr[tmpaddr+5] = value >> 0x28; tmp++;
case 4: addr[tmpaddr+4] = value >> 0x20; tmp++;
case 3: addr[tmpaddr+3] = value >> 0x18; tmp++;
case 2: addr[tmpaddr+2] = value >> 0x10; tmp++;
case 1: addr[tmpaddr+1] = value >> 0x08; tmp++;
case 0: addr[tmpaddr ] = value & 0xFF; tmp++;
}
break;
}
tmpaddr += tmp;
bc->progsize += tmp;
tmp = 0;
}
}
if (dbg) {
printf("assemble(): The address that this line starts at is, $%"PRIX64".\n", address);
printf("assemble(): The address that this line ends on is, $%"PRIX64".\n", tmpaddr);
printf("assemble(): The program size is now at");
printf(", %"PRIu64" bytes in decimal", bc->progsize);
printf(", and $%"PRIX64" bytes in hex.\n", bc->progsize);
printf("assemble(): The data size is now at");
printf(", %"PRIu64" bytes in decimal", bc->datasize);
printf(", and $%"PRIX64" bytes in hex.\n", bc->datasize);
}
}
}
int asmmon(const char *fn) {
FILE *fp = NULL;
FILE *fp2 = NULL;
char *path = malloc(0x400);
if (strcasecmp(fn, "stdin")) {
uint16_t i = 0;
uint8_t dir = 0;
for (; fn[i] != '\0'; i++) dir = (fn[i] == '/') ? i : dir;
if (dir) {
memcpy(path, fn, dir);
path[dir] = '\0';
} else {
path[0] = '.';
path[1] = '\0';
}
fp = fopen(fn, "r");
if (fp == NULL) {
free(path);
return 2;
}
}
uint8_t done = 0;
uint8_t use_lexer = 1;
uint64_t address = 0;
bytecount bc;
uint64_t progsize = 0;
uint64_t datasize = 0;
uint8_t dbg = 0;
uint8_t isinclude = 0;
uint16_t tmp_lineidx = 0;
uint8_t inc_count = 0;
init_symbol();
while (!done) {
char *cmd;
char *arg = malloc(sizeof(char *)*128);
char *tmp = malloc(sizeof(char *)*128);
char lex_line[0x1000];
uint16_t size = 0;
uint8_t cmds = 0;
uint8_t isshcmd = 0;
if (!isinclude) {
fgets(lex_line, sizeof(lex_line), (!strcasecmp(fn, "stdin")) ? stdin : fp);
} else {
if (fp2 != NULL) {
if (fgets(lex_line, sizeof(lex_line), fp2) == NULL && feof(fp2)) {
lex_line[0] = 'a' ;
lex_line[1] = '\n';
lex_line[2] = '\0';
}
}
}
size = strlen(lex_line)+1;
cmd = malloc(size);
memcpy(cmd, lex_line, size);
cmd = strtok_r(cmd, " \t\n", &tmp);
if (cmd != NULL) {
isshcmd = (cmd[1] == '\0' || cmd[1] == ' ');
switch (cmd[0]) {
case 'q': cmds = (isshcmd || !strcasecmp(cmd, "quit" )) << 0; break;
case 'v': cmds = (isshcmd || !strcasecmp(cmd, "viewmem")) << 1; break;
case 'l': cmds = (isshcmd || !strcasecmp(cmd, "list" )) << 2; break;
case 'a': cmds = (isshcmd || !strcasecmp(cmd, "asm" )) << 3; break;
case 'h': cmds = (isshcmd || !strcasecmp(cmd, "help" )) << 4; break;
case 'i': cmds = (isshcmd || !strcasecmp(cmd, "inst" )) << 5; break;
case 'd': cmds = (isshcmd || !strcasecmp(cmd, "done" )) << 6; break;
case 's': cmds = (isshcmd || !strcasecmp(cmd, "set" )) << 7; break;
case ' ':
case '\t':
cmds = 0xFF;
break;
}
switch (cmds) {
case 0x01:
free(path);
if (fp != NULL) {
fclose(fp);
}
if (fp2 != NULL) {
fclose(fp2);
}
return 2;
case 0x02:
viewmem(address);
break;
case 0x04:
if (tmp != NULL) {
uint16_t i = 0;
uint16_t j = 0;
uint16_t start = 0;
uint16_t end = 0;
uint16_t value = 0;
uint8_t base = 0xFF;
uint8_t isflag = 0;
uint8_t isstart = 1;
uint8_t isdebug = 0;
uint8_t islinenum = 0;
uint8_t isaddr = 0;
while (tmp[i] != '\0') {
if (isspace(tmp[i])) {
for (; isspace(tmp[i]); i++);
}
switch (tmp[i]) {
case '$': base = BASE_HEX; i++; break;
case '%': base = BASE_BIN; i++; break;
default:
j = i;
for (; isdigit(tmp[j]); j++, isflag++);
base = (isflag) ? BASE_DEC : 0xFF;
isflag = 0;
j = 0;
break;
}
for (; !isspace(tmp[i]) && tmp[i] != '-' && tmp[i] != '\0' && tmp[i] != '\n'; arg[j++] = tmp[i++]);
arg[j] = '\0';
j = 0;
if (base != 0xFF) {
switch (base) {
case BASE_HEX: value = strtol(arg, NULL, 16); break;
case BASE_BIN: value = strtol(arg, NULL, 2); break;
case BASE_DEC: value = strtol(arg, NULL, 10); break;
}
base = 0xFF;
(isstart) ? (start = value) : (end = value);
if (isstart) {
isstart = (tmp[i] != '-');
}
} else {
for (; isalpha(arg[j]); j++, isflag++);
j = 0;
if (isflag) {
isdebug = (arg[j] == 'd' || !strcasecmp(arg, "debug" ));
islinenum = (arg[j] == 'l' || !strcasecmp(arg, "linenum"));
if (!islinenum) {
isaddr = (arg[j] == 'a' || !strcasecmp(arg, "address"));
}
}
isflag = 0;
}
i++;
}
list(tokline, start, end, isstart, islinenum, isaddr, isdebug);
} else {
list(tokline, 0, 0, 1, 0, 0, 0);
}
break;
case 0x08:
if (!inc_file) {
printf("Assembling %s\n", (strcasecmp(fn, "stdin")) ? fn : "typed in program.");
assemble(tokline, &bc, dbg);
progsize = bc.progsize;
datasize = bc.datasize;
printf("Finished assembling %s\n", (strcasecmp(fn, "stdin")) ? fn : "typed in program.");
printf("%"PRIu64"/$%"PRIX64" bytes of program code.\n", progsize, progsize);
printf("%"PRIu64"/$%"PRIX64" bytes of data.\n", datasize, datasize);
putchar('\n');
}
isinclude = (inc_file != 0);
if (inc_file) {
size = strlen(path)+strlen(string[incl[inc_count]])+1;
char *fn2 = malloc(size+1);
sprintf(fn2, "%s/%s", path, string[incl[inc_count]]);
isinclude = (inc_file != 0);
inc_file--;
inc_count++;
if (inc_file && fp2 != NULL) {
fclose(fp2);
}
fp2 = fopen(fn2, "r");
if (fp2 == NULL) {
free(path);
fclose(fp);
return 2;
}
}
if (!isinclude) {
puts("Finished assembling.");
printf("Total Assembled Program Size: %"PRIu64"/$%"PRIX64" bytes.\n", progsize, progsize);
printf("Total Assembled Data Size: %"PRIu64"/$%"PRIX64" bytes.\n", datasize, datasize);
}
break;
case 0x10:
usage();
break;
case 0x20:
if (tmp != NULL) {
instinfo(tmp);
} else {
instinfo("all");
}
break;
case 0x40:
done = 1;
break;
case 0x80:
if (tmp != NULL) {
uint16_t i = 0;
uint16_t j = 0;
uint8_t isdebug = 0;
while (tmp[i] != '\0') {
if (isspace(tmp[i])) {
for (; isspace(tmp[i]); i++);
}
for (; !isspace(tmp[i]) && tmp[i] != '\0' && tmp[i] != '\n'; arg[j++] = tmp[i++]);
arg[j] = '\0';
j = 0;
isdebug = (arg[j] == 'd' || !strcasecmp(arg, "debug"));
if (isdebug) {
dbg = !dbg;
if (dbg) {
puts("Debug mode has been enabled.");
} else {
puts("Debug mode has been disabled.");
}
}
i++;
}
}
break;
case 0xFF:
break;
default:
address = lex(lex_line, tokline, address, dbg);
break;
}
}
}
free(path);
if (fp != NULL) {
fclose(fp);
}
if (fp2 != NULL) {
fclose(fp2);
}
return 0;
}