summaryrefslogtreecommitdiff
path: root/asmmon.c
diff options
context:
space:
mode:
Diffstat (limited to 'asmmon.c')
-rw-r--r--asmmon.c209
1 files changed, 166 insertions, 43 deletions
diff --git a/asmmon.c b/asmmon.c
index 5b30fdc..43811f7 100644
--- a/asmmon.c
+++ b/asmmon.c
@@ -4,7 +4,7 @@
#define debug 1
-#define OPNUM 87
+#define OPNUM 88
#define SETOP(num, _mne, _IMM, _ZM, _ZMX, _ZMY, _ABS, _IMPL) \
{opcodes[num].mnemonic[3] = '\0'; strncpy(opcodes[num].mnemonic, _mne, 3); \
opcodes[num].imm = _IMM; \
@@ -24,6 +24,7 @@ struct label {
uint8_t def;
char name[1];
};
+static char tstr[2048];
struct label *labels = 0;
struct fixup *fixups = 0;
uint8_t defined = 0;
@@ -190,28 +191,29 @@ int asmmon() {
SETOP(62, "BVC", 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00);
SETOP(63, "DIV", 0xA1, 0xA5, 0x00, 0x00, 0xA3, 0x00);
SETOP(64, "CLV", 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8);
- SETOP(65, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0);
- SETOP(66, "CMP", 0xB1, 0xF5, 0x00, 0x00, 0xE5, 0x00);
- SETOP(67, "CPY", 0xB2, 0xF2, 0x00, 0x00, 0xE2, 0x00);
- SETOP(68, "CAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB3);
- SETOP(69, "CPX", 0xB4, 0xF4, 0x00, 0x00, 0xE4, 0x00);
- SETOP(70, "CAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5);
- SETOP(71, "ENT", 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(72, "RTI", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0);
- SETOP(73, "INC", 0x00, 0xE3, 0x00, 0x00, 0xE1, 0xC1);
- SETOP(74, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2);
- SETOP(75, "IAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3);
- SETOP(76, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4);
- SETOP(77, "IAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC5);
- SETOP(78, "DEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1);
- SETOP(79, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2);
- SETOP(80, "DAY", 0x00, 0xF3, 0x00, 0x00, 0xF1, 0xD3);
- SETOP(81, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4);
- SETOP(82, "DAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5);
- SETOP(83, "JSL", 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00);
- SETOP(84, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8);
- SETOP(85, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0);
- SETOP(86, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8);
+ SETOP(65, "ASR", 0xA9, 0xAD, 0x00, 0x00, 0xAB, 0x00);
+ SETOP(66, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0);
+ SETOP(67, "CMP", 0xB1, 0xF5, 0x00, 0x00, 0xE5, 0x00);
+ SETOP(68, "CPY", 0xB2, 0xF2, 0x00, 0x00, 0xE2, 0x00);
+ SETOP(69, "CAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB3);
+ SETOP(70, "CPX", 0xB4, 0xF4, 0x00, 0x00, 0xE4, 0x00);
+ SETOP(71, "CAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5);
+ SETOP(72, "ENT", 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(73, "RTI", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0);
+ SETOP(74, "INC", 0x00, 0xE3, 0x00, 0x00, 0xE1, 0xC1);
+ SETOP(75, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2);
+ SETOP(76, "IAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3);
+ SETOP(77, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4);
+ SETOP(78, "IAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC5);
+ SETOP(79, "DEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1);
+ SETOP(80, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2);
+ SETOP(81, "DAY", 0x00, 0xF3, 0x00, 0x00, 0xF1, 0xD3);
+ SETOP(82, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4);
+ SETOP(83, "DAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5);
+ SETOP(84, "JSL", 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00);
+ SETOP(85, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8);
+ SETOP(86, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0);
+ SETOP(87, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8);
uint8_t done = 0;
uint64_t address = 0x0000;
while (!(done & 1)) {
@@ -224,6 +226,8 @@ int asmmon() {
uint64_t value = 0;
char *oprand;
char *cmd;
+ char ir[2] = ""; /* Index register. */
+ int a = 0;
char *tmp = malloc(sizeof(char *)*128);
size_t size;
done &= ~0x1F;
@@ -235,8 +239,29 @@ int asmmon() {
} else {
ins = strtok(buf, "\t\n ");
if (ins != NULL) {
- oprand = strtok(NULL, "\t\n ");
+ oprand = strtok(NULL, "\t\n");
strtok_r(ins, ".", &postfix);
+ if (oprand != NULL) {
+ for (int i = 0; i < strlen(oprand); i++) {
+ if (oprand[i] == '"')
+ break;
+ if (oprand[i] == 'x' || oprand[i] == 'X') {
+ ir[0] = 'x';
+ ir[1] = '\0';
+ break;
+ }
+ if (oprand[i] == 'y' || oprand[i] == 'Y') {
+ ir[0] = 'y';
+ ir[1] = '\0';
+ break;
+ }
+ if (oprand[i] == ',' || oprand[i] == ';') {
+ a = i;
+ }
+ }
+ if (a)
+ oprand[a] = '\0';
+ }
}
if (strcasecmp(cmd, "quit") == 0 || strcasecmp(cmd, "q") == 0) {
return 2;
@@ -277,23 +302,86 @@ int asmmon() {
}
if (strcasecmp(ins, ".byte") == 0 || strcasecmp(ins, ".word") == 0 || strcasecmp(ins, ".dword") == 0 || strcasecmp(ins, ".qword") == 0) {
done |= 6;
+ uint8_t qstr = 0;
+ uint64_t staddr = address;
+ uint16_t slen = 0;
+ char *tmpstr = tstr;
+ char c;
for (int i = 0; i < strlen(oprand); i++) {
- if (oprand[i] == '$') {
- oprand = strtok(oprand, "$");
- value = strtoull(oprand, NULL, 16);
- break;
- }
- if (oprand[i] == ';') {
- done |= 16;
- break;
- }
- if (isalnum(oprand[i]) || oprand[i] == '_') {
- use_label(oprand, address);
- sprintf(oprand, "%llx", value);
- break;
+ if (!qstr) {
+ if ((isalnum(oprand[i]) || oprand[i] == '_') && oprand[i] != '"') {
+ qstr = 0;
+ value = use_label(oprand, address);
+ sprintf(oprand, "%llx", value);
+ break;
+ }
+ if (oprand[i] == '"' && !strcasecmp(ins, ".byte")) {
+ qstr = 1;
+ continue;
+ }
+ if (oprand[i] == '$') {
+ qstr = 0;
+ oprand = strtok(oprand, "$");
+ value = strtoull(oprand, NULL, 16);
+ break;
+ }
+ if (oprand[i] == ';') {
+ qstr = 0;
+ done |= 16;
+ break;
+ }
+ } else if (qstr == 1) {
+ switch (oprand[i]) {
+ case 0:
+ puts("oof, unterminated string.");
+ qstr = 2;
+ break;
+ case '"':
+ value = '\0';
+ c = '\0';
+ tmpstr[slen++] = '\0';
+ qstr = 3;
+ break;
+ case '\\':
+ switch (oprand[i+1]) {
+ case 'n':
+ value = '\n';
+ c = '\n';
+ tmpstr[slen++] = '\\';
+ tmpstr[slen++] = 'n';
+ break;
+ case 't':
+ value = '\t';
+ c = '\t';
+ tmpstr[slen++] = '\\';
+ tmpstr[slen++] = 't';
+ break;
+ case 'r':
+ value = '\r';
+ c = '\r';
+ tmpstr[slen++] = '\\';
+ tmpstr[slen++] = 'r';
+ break;
+ case '0':
+ break;
+ default:
+ value = oprand[i];
+ tmpstr[slen++] = '\\';
+ tmpstr[slen++] = oprand[i];
+ break;
+ }
+ i++;
+ break;
+ default:
+ value = oprand[i];
+ c = oprand[i];
+ tmpstr[slen++] = c;
+ break;
+ }
+ addr[address++] = value & 0xFF;
}
}
- if (strcasecmp(ins, ".byte") == 0)
+ if (strcasecmp(ins, ".byte") == 0 && !qstr)
addr[address++] = value & 0xFF;
if (strcasecmp(ins, ".word") == 0) {
addr[address] = value & 0xFF;
@@ -319,7 +407,19 @@ int asmmon() {
address+=8;
}
#if debug
- printf("The value $%llx was placed at address $%llx.\n", value, address);
+ if (!qstr) {
+ printf("The value $%llx was placed at address%s ", value, (staddr != address-1) ? "es" : "");
+ if (staddr == address-1)
+ printf("$%llx.\n", staddr);
+ else
+ printf("$%llx-$%llx.\n", staddr, address-1);
+ } else {
+ printf("The string \"%s\", was placed at address%s ", tmpstr, (staddr != address-1) ? "es" : "");
+ if (staddr == address-1)
+ printf("$%llx.\n", staddr);
+ else
+ printf("$%llx-$%llx.\n", staddr, address-1);
+ }
#endif
}
}
@@ -362,6 +462,16 @@ int asmmon() {
} else if (value & 0xFFFFFFFF00000000) {
addrmode = 5;
}
+ if (addrmode == 2 && ir != NULL) {
+ switch (ir[0]) {
+ case 'x':
+ addrmode = 3;
+ break;
+ case 'y':
+ addrmode = 4;
+ break;
+ }
+ }
}
} else {
for (int i = 0; i < strlen(oprand); i++) {
@@ -369,7 +479,7 @@ int asmmon() {
done |= 16;
break;
}
- if (isalnum(oprand[i]) || oprand[i] == '_') {
+ if ((isalnum(oprand[i]) || oprand[i] == '_') && oprand[i] != '"') {
value = use_label(oprand, address);
if (value == 0)
addrmode = 2;
@@ -383,10 +493,19 @@ int asmmon() {
addrmode = 2;
}
}
-
} else if (value & 0xFFFFFFFF00000000) {
addrmode = 5;
}
+ if (addrmode == 2 && ir != NULL) {
+ switch (ir[0]) {
+ case 'x':
+ addrmode = 3;
+ break;
+ case 'y':
+ addrmode = 4;
+ break;
+ }
+ }
sprintf(oprand, "%llx", value);
break;
}
@@ -415,6 +534,7 @@ int asmmon() {
case LSR:
case ROL:
case ROR:
+ case ASR:
case ENT:
done |= 8;
break;
@@ -495,6 +615,7 @@ int asmmon() {
case LSR:
case ROL:
case ROR:
+ case ASR:
case ENT:
addr[address++] = value & 0xFF;
break;
@@ -541,7 +662,7 @@ int asmmon() {
break;
case 3:
if (op.zmx) {
- addr[address++] = op.zmy;
+ addr[address++] = op.zmx;
addr[address] = value & 0xFF;
addr[address+1] = value >> 8;
addr[address+2] = value >> 16;
@@ -591,7 +712,9 @@ int asmmon() {
#else
printf("Postfix: %s, ", (postfix[0] != '\0') ? postfix : "none");
#endif
- printf("Operand: %s, Address: $%llx\n", (oprand != NULL && !(done & 16)) ? oprand : "none", address);
+ printf("Operand: %s, ", (oprand != NULL && !(done & 16)) ? oprand : "none");
+ printf("Index Register: %s, ", (ir != NULL) ? ir : "none");
+ printf("Address: $%llx\n", address);
}
#endif
}