summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-05-03 15:51:57 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2020-05-03 15:51:57 -0400
commit1c622005c289ef1cd9feea277bd0ff46b19d15f0 (patch)
treeb5258bd461ac2070c39e0eb437da676a10e295c3
parented88644ded82008577804c590bec7188ef0da011 (diff)
Put the instruction, and I/O routines into separate
functions. I did this to make it more readable, while still making it fast, due to inlining it.
-rw-r--r--Makefile57
-rw-r--r--asmmon.c2
-rw-r--r--disasm.c136
-rw-r--r--disasm.h187
-rw-r--r--io.c181
-rw-r--r--opcode.c25
-rw-r--r--opcode.h193
-rw-r--r--sux.c821
-rw-r--r--sux.h554
9 files changed, 1168 insertions, 988 deletions
diff --git a/Makefile b/Makefile
index d8ca322..ae5be06 100644
--- a/Makefile
+++ b/Makefile
@@ -7,30 +7,53 @@ else
PCC_CFLAGS=
endif
-CFLAGS = $(PCC_CFLAGS) $(CFLAGS_EXTRA)
-OBJS = sux.o asmmon.o lexer.o
+IO=1
+
+ifdef BENCH
+BENCH_CFLAGS=-Dbench=1
+IO=
+else
+BENCH_CFLAGS=-Dbench=0
+IO=1
+endif
+
+ifdef DEBUG
+DBG_CFLAGS=-Ddebug=1
+IO=
+DBG_OBJ=disasm.o
+else
+ifdef IO
+IO=1
+endif
+DBG_CFLAGS=-Ddebug=0
+DBG_OBJ=
+endif
+
+ifdef IO
+IO_CFLAGS=-DIO=1
+else
+IO_CFLAGS=-DIO=0
+endif
+
+
+OBJS = sux.o opcode.o io.o $(DBG_OBJ) asmmon.o lexer.o
+
+CFLAGS = $(PCC_CFLAGS) $(DBG_CFLAGS) $(IO_CFLAGS) $(BENCH_CFLAGS) $(CFLAGS_EXTRA)
OBJS2 = subasm.o subeditor.o
OBJ_NAME = cisc-0.2
OBJ_NAME2 = subeditor-c
-all : clean clean_subeditor $(OBJ_NAME)
-subeditor : clean_subeditor $(OBJS2)
+
+all : clean $(OBJ_NAME)
+
+subeditor : clean $(OBJS2)
$(CC) $(OBJS2) $(CFLAGS) -lcurses -ltinfo -o $(OBJ_NAME2)
cisc-0.2: $(OBJS)
$(CC) $(OBJS) $(CFLAGS) -lpthread -lcurses -ltinfo -o $(OBJ_NAME)
-sux.o :
- $(CC) sux.c -c $(CFLAGS) -o sux.o
-asmmon.o :
- $(CC) asmmon.c -c $(CFLAGS) -o asmmon.o
-lexer.o :
- $(CC) lexer.c -c $(CFLAGS) -o lexer.o
-subasm.o :
- $(CC) programs/c-ports/subasm.c -c $(CFLAGS) -o subasm.o
-subeditor.o :
- $(CC) programs/c-ports/subeditor.c -c $(CFLAGS) -o subeditor.o
+
+%.o : %.c
+ $(CC) -c $< -o $@ $(CFLAGS)
clean :
- rm -f $(OBJ_NAME) $(OBJ_NAME2) $(OBJS) $(OBJS2)
-clean_subeditor :
- rm -f $(OBJ_NAME2) $(OBJS2)
+ rm -f $(OBJ_NAME) $(OBJ_NAME2) *.o
install :
install -D -m755 $(OBJ_NAME) $(BIN_DIR)/$(OBJ_NAME)
uninstall :
diff --git a/asmmon.c b/asmmon.c
index 9df2bac..453ff3c 100644
--- a/asmmon.c
+++ b/asmmon.c
@@ -576,7 +576,7 @@ uint64_t assemble(struct line *line, uint8_t dbg) {
int asmmon(const char *fn) {
FILE *fp;
- FILE *fp2;
+ FILE *fp2 = NULL;
char *path = malloc(0x400);
if (strcasecmp(fn, "stdin")) {
uint16_t i = 0;
diff --git a/disasm.c b/disasm.c
new file mode 100644
index 0000000..c055d07
--- /dev/null
+++ b/disasm.c
@@ -0,0 +1,136 @@
+#include "sux.h"
+#include "disasm.h"
+
+void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, uint8_t prefix, uint8_t thread) {
+ uint64_t value = operands[0];
+ uint64_t address = operands[1];
+ uint64_t tmpaddr = operands[2];
+ char postfix[3];
+ char op[4];
+ op[0] = opname[opcode][0];
+ op[1] = opname[opcode][1];
+ op[2] = opname[opcode][2];
+ op[3] = '\0';
+ switch(1 << (prefix >> 4)) {
+ case 1: postfix[0] = 0; postfix[1] = 0; postfix[2] = 0; break;
+ case 2: postfix[0] = '.'; postfix[1] = 'W'; postfix[2] = 0; break;
+ case 4: postfix[0] = '.'; postfix[1] = 'D'; postfix[2] = 0; break;
+ case 8: postfix[0] = '.'; postfix[1] = 'Q'; postfix[2] = 0; break;
+ }
+ switch (optype[opcode]) {
+ case IMPL: wprintw(scr, "%s\r" , opname[opcode]); break;
+ case IMM:
+ switch(1 << (prefix >> 4)) {
+ case 1: wprintw(scr, "%s #$%02X\r" , op, value); break;
+ case 2: wprintw(scr, "%s%s #$%04X\r" , op, postfix, value); break;
+ case 4: wprintw(scr, "%s%s #$%08X\r" , op, postfix, value); break;
+ case 8: wprintw(scr, "%s%s #$%016"PRIX64"\r" , op, postfix, value); break;
+ }
+ break;
+ case ZM:
+ case ZMX:
+ case ZMY:
+ switch (optype[opcode]) {
+ case ZMX: tmpaddr = address - cpu->x[thread]; break;
+ case ZMY: tmpaddr = address - cpu->y[thread]; break;
+ }
+ switch ((prefix & 0x0C) >> 2) {
+ case 3: wprintw(scr, "%s%s $%08X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
+ case 2: wprintw(scr, "%s%s $%014"PRIX64"%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
+ case 1: wprintw(scr, "%s%s $%06X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
+ case 0: wprintw(scr, "%s%s $%02X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
+ }
+ break;
+ case IND:
+ case INDX:
+ case INDY:
+ switch ((prefix & 0x0C) >> 2) {
+ case 3: wprintw(scr, "%s%s ($%08X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
+ case 2: wprintw(scr, "%s%s ($%012"PRIX64"%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
+ case 1: wprintw(scr, "%s%s ($%06X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
+ case 0: wprintw(scr, "%s%s ($%02X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
+ }
+ break;
+ case ABS:
+ tmpaddr = address;
+ switch ((prefix & 0x0C) >> 2) {
+ case 3: wprintw(scr, "%s%s $%016"PRIX64"\r" , op, postfix, tmpaddr); break;
+ case 2: wprintw(scr, "%s%s $%014"PRIX64"\r" , op, postfix, tmpaddr); break;
+ case 1: wprintw(scr, "%s%s $%010"PRIX64"\r" , op, postfix, tmpaddr); break;
+ case 0: wprintw(scr, "%s%s $%04" PRIX64"\r" , op, postfix, tmpaddr); break;
+ }
+ break;
+ }
+
+ if (address == TX_ADDR || address == RX_ADDR) {
+ wmove(scr, 27, 0);
+ wprintw(scr, "TX_ADDR: $%02X, RX_ADDR: $%02X", addr[TX_ADDR], addr[RX_ADDR]);
+ }
+ if (subdbg) {
+ uint8_t ln = 33;
+ uint16_t line_idx = 0;
+ uint16_t tmpad = 0x2000;
+ int row, col;
+ uint8_t iscursor = 0;
+ uint64_t ptr;
+ uint8_t adr;
+ wmove(scr, 30, 0);
+ adr = 0x1F;
+ ptr = (uint64_t)addr[adr+0] << 0x00 | (uint64_t)addr[adr+1] << 0x08 | (uint64_t)addr[adr+2] << 0x10 | (uint64_t)addr[adr+3] << 0x18 |
+ (uint64_t)addr[adr+4] << 0x20 | (uint64_t)addr[adr+5] << 0x28 | (uint64_t)addr[adr+6] << 0x30 | (uint64_t)addr[adr+7] << 0x38;
+ wprintw(scr, "ptr1: $%04"PRIX64, ptr);
+ adr = 0x27;
+ ptr = (uint64_t)addr[adr+0] << 0x00 | (uint64_t)addr[adr+1] << 0x08 | (uint64_t)addr[adr+2] << 0x10 | (uint64_t)addr[adr+3] << 0x18 |
+ (uint64_t)addr[adr+4] << 0x20 | (uint64_t)addr[adr+5] << 0x28 | (uint64_t)addr[adr+6] << 0x30 | (uint64_t)addr[adr+7] << 0x38;
+ wprintw(scr, ", ptr2: $%04"PRIX64, ptr);
+ adr = 0x2F;
+ ptr = (uint64_t)addr[adr+0] << 0x00 | (uint64_t)addr[adr+1] << 0x08 | (uint64_t)addr[adr+2] << 0x10 | (uint64_t)addr[adr+3] << 0x18 |
+ (uint64_t)addr[adr+4] << 0x20 | (uint64_t)addr[adr+5] << 0x28 | (uint64_t)addr[adr+6] << 0x30 | (uint64_t)addr[adr+7] << 0x38;
+ wprintw(scr, ", ptr3: $%04"PRIX64, ptr);
+ if (address == CTRL_ADDR || addr[STEP_ADDR]) {
+ mvwprintw(scr, 29, 0, "address: $%04"PRIX64", scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x1C], addr[0x1D]);
+ mvwprintw(scr, 32, 0, "bitabl: %02X%02X%02X%02X%02X%02X%02X%02X"
+ "%02X%02X%02X%02X%02X%02X%02X%02X"
+ , addr[0x1000], addr[0x1001], addr[0x1002], addr[0x1003], addr[0x1004], addr[0x1005], addr[0x1006], addr[0x1007]
+ , addr[0x1008], addr[0x1009], addr[0x100A], addr[0x100B], addr[0x100C], addr[0x100D], addr[0x100E], addr[0x100F]);
+ mvwprintw(scr, ln++, 0, "buffer:\r");
+ wmove(scr, ln++, 0);
+ for (uint8_t i = 0; i < 10; i++) {
+ line_idx = (i << 6) + (i << 4);
+ for (uint8_t j = 0; j < 0x50; j++) {
+ wprintw(scr, "%02X", addr[tmpad+j+line_idx]);
+ if ((addr[0]+addr[0x1C]) == i && addr[1] == j) {
+ iscursor=1;
+ getyx(scr,row, col);
+ wmove(scr, ln++, 0);
+ wclrtoeol(scr);
+ wmove(scr, row+1, col-2);
+ wprintw(scr, "/\\\r");
+ wmove(scr, row, col);
+ }
+ }
+ wprintw(scr, ", i: %02X", i);
+ if (!iscursor) {
+ wmove(scr, ln, 0);
+ wclrtoeol(scr);
+ }
+ iscursor = 0;
+ wmove(scr, ln++, 0);
+ }
+ }
+ /*if (address == 0x4000 || tmpaddr == 0x4000 || addr[STEP_ADDR]) {
+ ln = 46;
+ tmpad = 0x4000;
+ line_idx = 0;
+ mvwprintw(scr, ln++, 0, "cmd_buf:");
+ for (uint8_t i = 0; i < 5; i++) {
+ wmove(scr, ln++, 0);
+ line_idx = (i << 4)+(i << 6);
+ for (uint8_t j = 0; j < 0x50; j++) {
+ wprintw(scr, "%02X", addr[tmpad+j+line_idx]);
+ }
+ wprintw(scr, ", i: %02X", i);
+ }
+ }*/
+ }
+}
diff --git a/disasm.h b/disasm.h
new file mode 100644
index 0000000..8fe2b4c
--- /dev/null
+++ b/disasm.h
@@ -0,0 +1,187 @@
+static const char *opname[0x100] = {
+ [0x00] = "CPS",
+ [0x01] = "ADC #",
+ [0x02] = "AAB",
+ [0x04] = "ADC a",
+ [0x05] = "LDA ind",
+ [0x06] = "ADC zm",
+ [0x08] = "PHP #",
+ [0x09] = "CPB #",
+ [0x0A] = "PHB #",
+ [0x0C] = "DEC a",
+ [0x0D] = "DEC zm",
+ [0x0E] = "JMP zm",
+ [0x10] = "JMP a",
+ [0x11] = "SBC #",
+ [0x12] = "SAB",
+ [0x14] = "SBC a",
+ [0x15] = "STA ind",
+ [0x16] = "SBC zm",
+ [0x18] = "ENT #",
+ [0x19] = "CPY #",
+ [0x1A] = "PLB #",
+ [0x1C] = "INC a",
+ [0x1D] = "INC zm",
+ [0x1E] = "JSR zm",
+ [0x20] = "JSL a",
+ [0x21] = "AND #",
+ [0x22] = "ABA",
+ [0x24] = "AND a",
+ [0x25] = "CMP ind",
+ [0x26] = "AND zm",
+ [0x28] = "PLP #",
+ [0x29] = "CPX #",
+ [0x2A] = "PHY #",
+ [0x2C] = "CPB a",
+ [0x2D] = "CPB zm",
+ [0x2E] = "BPO zm",
+ [0x30] = "BPO a",
+ [0x31] = "ORA #",
+ [0x32] = "OAB",
+ [0x34] = "ORA a",
+ [0x35] = "LDB ind",
+ [0x36] = "ORA zm",
+ [0x38] = "STT #",
+ [0x39] = "LDA zmy",
+ [0x3A] = "PLY #",
+ [0x3C] = "CPX a",
+ [0x3D] = "CPY zm",
+ [0x3E] = "BNG zm",
+ [0x40] = "BNG a",
+ [0x41] = "XOR #",
+ [0x42] = "XAB",
+ [0x44] = "XOR a",
+ [0x45] = "STB ind",
+ [0x46] = "XOR zm",
+ [0x48] = "PHA #",
+ [0x49] = "STA zmy",
+ [0x4A] = "PHX #",
+ [0x4C] = "CPY a",
+ [0x4D] = "CPX zm",
+ [0x4E] = "BCS zm",
+ [0x50] = "BCS a",
+ [0x51] = "LSL #",
+ [0x52] = "LLB",
+ [0x54] = "LSL a",
+ [0x55] = "CPB ind",
+ [0x56] = "LSL zm",
+ [0x58] = "CLC",
+ [0x59] = "LDB zmy",
+ [0x5A] = "PLX #",
+ [0x5C] = "LDA iny",
+ [0x5D] = "LDA inx",
+ [0x5E] = "BCC zm",
+ [0x60] = "BCC a",
+ [0x61] = "LSR #",
+ [0x62] = "LRB",
+ [0x64] = "LSR a",
+ [0x65] = "LDY ind",
+ [0x66] = "LSR zm",
+ [0x68] = "PLA #",
+ [0x69] = "STB zmy",
+ [0x6A] = "TAB",
+ [0x6C] = "STA iny",
+ [0x6D] = "STA inx",
+ [0x6E] = "BEQ zm",
+ [0x70] = "BEQ a",
+ [0x71] = "ROL #",
+ [0x72] = "RLB",
+ [0x74] = "ROL a",
+ [0x75] = "STY ind",
+ [0x76] = "ROL zm",
+ [0x78] = "SEC",
+ [0x79] = "LDA zmx",
+ [0x7A] = "TBA",
+ [0x7C] = "CMP iny",
+ [0x7D] = "CMP inx",
+ [0x7E] = "BNE zm",
+ [0x80] = "BNE a",
+ [0x81] = "ROR #",
+ [0x82] = "RRB",
+ [0x84] = "ROR a",
+ [0x85] = "CPY ind",
+ [0x86] = "ROR zm",
+ [0x88] = "DEY",
+ [0x89] = "STA zmx",
+ [0x8A] = "TAY",
+ [0x8C] = "LDB iny",
+ [0x8D] = "LDB inx",
+ [0x8E] = "BVS zm",
+ [0x90] = "BVS a",
+ [0x91] = "MUL #",
+ [0x92] = "MAB",
+ [0x94] = "MUL a",
+ [0x95] = "LDX ind",
+ [0x96] = "MUL zm",
+ [0x98] = "CLI",
+ [0x99] = "LDB zmx",
+ [0x9A] = "TYA",
+ [0x9C] = "STB iny",
+ [0x9D] = "STB inx",
+ [0x9E] = "BVC zm",
+ [0xA0] = "BVC a",
+ [0xA1] = "DIV #",
+ [0xA2] = "DAB",
+ [0xA4] = "DIV a",
+ [0xA5] = "STX ind",
+ [0xA6] = "DIV zm",
+ [0xA8] = "INY",
+ [0xA9] = "STB zmx",
+ [0xAA] = "TAX",
+ [0xAC] = "CPB iny",
+ [0xAD] = "CPB inx",
+ [0xAE] = "RTS",
+ [0xB0] = "RTL",
+ [0xB1] = "CMP #",
+ [0xB2] = "CAB",
+ [0xB4] = "CMP a",
+ [0xB5] = "CPX ind",
+ [0xB6] = "CMP zm",
+ [0xB8] = "SEI",
+ [0xB9] = "LDX #",
+ [0xBA] = "TXA",
+ [0xBC] = "LDX a",
+ [0xBD] = "LDX zm",
+ [0xBE] = "JSR ind",
+ [0xC0] = "RTI",
+ [0xC1] = "LDA #",
+ [0xC4] = "LDA a",
+ [0xC5] = "DEX",
+ [0xC6] = "LDA zm",
+ [0xC8] = "CLV",
+ [0xC9] = "LDX zmy",
+ [0xCA] = "TYX",
+ [0xCC] = "STA a",
+ [0xCD] = "STA zm",
+ [0xCE] = "JMP ind",
+ [0xD0] = "TSX",
+ [0xD1] = "LDB #",
+ [0xD4] = "LDB a",
+ [0xD5] = "INX",
+ [0xD6] = "LDB zm",
+ [0xD8] = "WAI",
+ [0xD9] = "STX zmy",
+ [0xDA] = "TXY",
+ [0xDC] = "STB a",
+ [0xDD] = "STB zm",
+ [0xE0] = "TXS #",
+ [0xE1] = "LDY #",
+ [0xE4] = "LDY a",
+ [0xE5] = "DEC A",
+ [0xE6] = "LDY zm",
+ [0xE8] = "BRK",
+ [0xE9] = "LDY zmx",
+ [0xEA] = "NOP",
+ [0xEC] = "STY a",
+ [0xED] = "STY zm",
+ [0xEE] = "DEB",
+ [0xF1] = "ASR #",
+ [0xF2] = "ARB",
+ [0xF4] = "ASR a",
+ [0xF5] = "INC A",
+ [0xF6] = "ASR zm",
+ [0xF9] = "STY zmx",
+ [0xFC] = "STX a",
+ [0xFD] = "STX zm",
+ [0xFE] = "INB"
+};
diff --git a/io.c b/io.c
new file mode 100644
index 0000000..fcef5d9
--- /dev/null
+++ b/io.c
@@ -0,0 +1,181 @@
+#include "sux.h"
+
+uint8_t iscol;
+uint8_t idx = 3;
+uint8_t bcd[4];
+
+void io(uint64_t address, uint8_t *esc) {
+ int x, y;
+ uint16_t scr_col = 0;
+ switch (address) {
+ case CTRL_ADDR:
+ kbd_rdy = 1;
+ pthread_mutex_lock(&main_mutex);
+ pthread_cond_signal(&main_cond);
+ pthread_mutex_unlock(&main_mutex);
+ #if !keypoll
+ pthread_mutex_lock(&mutex);
+ pthread_cond_wait(&cond, &mutex);
+ pthread_mutex_unlock(&mutex);
+ #endif
+ kbd_rdy = 0;
+ break;
+ case TX_ADDR:
+ #if debug
+ if (!subdbg) {
+ scr_col = (addr[TX_ADDR] != 0x0C && addr[TX_ADDR] != '\n' && scr_col < 160) ? (addr[1] << 1)-2 : 0;
+ wmove(scr, 28, scr_col);
+ }
+ #endif
+ if (*esc) {
+ #if debug
+ if (!subdbg && addr[RX_ADDR] == '\n') {
+ wclrtoeol(scr);
+ }
+ #endif
+ switch (addr[TX_ADDR]) {
+ case 'A':
+ if (y > 0)
+ y--;
+ #if !debug
+ wmove(scr, y, x);
+ #endif
+ *esc = 0;
+ break;
+ case 'B':
+ if (y < getmaxy(scr))
+ y++;
+ #if !debug
+ wmove(scr, y, x);
+ #endif
+ *esc = 0;
+ break;
+ case 'C':
+ if (x < getmaxx(scr))
+ x++;
+ #if !debug
+ wmove(scr, y, x);
+ #endif
+ *esc = 0;
+ break;
+ case 'D':
+ if (x > 0)
+ x--;
+ #if !debug
+ wmove(scr, y, x);
+ #endif
+ *esc = 0;
+ break;
+ case 'H':
+ if (!bcd[2] && !bcd[3]) {
+ y = 0;
+ } else {
+ y = ((bcd[3]*10) + bcd[2]);
+ }
+ if (!bcd[0] && !bcd[1]) {
+ x = 0;
+ } else {
+ x = ((bcd[1]*10) + bcd[0]);
+ }
+ #if !debug
+ wmove(scr, y, x);
+ #else
+ mvwprintw(scr, 30, 0, "x: %i, y: %i ", x, y);
+ /*mvwprintw(scr, 31, 0, "bcd[3-2]: {%u, %u}, bcd[1-0]: {%u, %u}", bcd[3], bcd[2], bcd[1], bcd[0]);*/
+ #endif
+ idx = 3;
+ bcd[0] = 0;
+ bcd[1] = 0;
+ bcd[2] = 0;
+ bcd[3] = 0;
+ *esc = 0;
+ break;
+ case 'S':
+ #if !debug
+ wscrl(scr, -1);
+ #else
+ #endif
+ *esc = 0;
+ break;
+ case 'T':
+ #if !debug
+ wscrl(scr, 1);
+ #else
+ #endif
+ *esc = 0;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ bcd[idx--] = (addr[address] - '0');
+ break;
+ default:
+ iscol = (addr[address] == ';');
+ break;
+ }
+ } else {
+ switch (addr[TX_ADDR]) {
+ case 0xC:
+ x=0,y=0;
+ #if !debug
+ wclear(scr);
+ wmove(scr, y, x);
+ #endif
+ break;
+ case CURSES_BACKSPACE:
+ case '\b':
+ if (x > 0) {
+ x--;
+ #if !debug
+ wmove(scr, y, x);
+ #endif
+ }
+ #if !debug
+ wdelch(scr);
+ #else
+ if (!subdbg) {
+ scr_col++;
+ wmove(scr, 28, scr_col--);
+ wdelch(scr);
+ wmove(scr, 28, scr_col);
+ wdelch(scr);
+ }
+ #endif
+ break;
+ case '\033':
+ *esc = 1;
+ break;
+ case '\n':
+ x = 0;
+ y+=1;
+ #if !debug
+ wmove(scr, y, x);
+ #endif
+ break;
+ default:
+ #if !debug
+ /*wmove(scr, y, x);*/
+ waddch(scr, addr[address]);
+ #else
+ if (!subdbg && scr_col < 160) {
+ if (addr[address] != ' ') {
+ wprintw(scr, "%02X", addr[address]);
+ } else {
+ wprintw(scr, " ");
+ }
+ }
+ #endif
+ x+=1;
+ break;
+ }
+ }
+ break;
+ }
+}
diff --git a/opcode.c b/opcode.c
new file mode 100644
index 0000000..423da28
--- /dev/null
+++ b/opcode.c
@@ -0,0 +1,25 @@
+#include "sux.h"
+
+static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opcode, uint8_t prefix, uint8_t thread);
+extern inline void adc(struct sux *cpu, uint64_t value, uint8_t thread);
+extern inline void sbc(struct sux *cpu, uint64_t value, uint8_t thread);
+extern inline void transfer(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t prefix, uint8_t thread);
+extern inline void push(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread);
+extern inline void pull(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread);
+extern inline void and(struct sux *cpu, uint64_t value, uint8_t thread);
+extern inline void or(struct sux *cpu, uint64_t value, uint8_t thread);
+extern inline void xor(struct sux *cpu, uint64_t value, uint8_t thread);
+extern inline void lsl(struct sux *cpu, uint64_t value, uint8_t thread);
+extern inline void lsr(struct sux *cpu, uint64_t value, uint8_t thread);
+extern inline void asr(struct sux *cpu, uint64_t value, uint8_t thread);
+extern inline void rol(struct sux *cpu, uint64_t value, uint8_t thread);
+extern inline void ror(struct sux *cpu, uint64_t value, uint8_t thread);
+extern inline void mul(struct sux *cpu, uint64_t value, uint8_t thread);
+extern inline void divd(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread);
+extern inline void cmp(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread);
+extern inline void incr(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread);
+extern inline void decr(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread);
+extern inline void incm(struct sux *cpu, uint64_t address, uint8_t thread);
+extern inline void decm(struct sux *cpu, uint64_t address, uint8_t thread);
+extern inline void load(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcode, uint8_t prefix, uint8_t thread);
+extern inline void store(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcode, uint8_t prefix, uint8_t thread);
diff --git a/opcode.h b/opcode.h
index 67ba5f5..81bffa4 100644
--- a/opcode.h
+++ b/opcode.h
@@ -4,9 +4,6 @@
#include <stdlib.h>
#include <unistd.h>
-#define bench 0
-#define debug 0
-#define IO 1
#define getclk 0
#define keypoll 0
@@ -405,194 +402,4 @@ static const uint8_t optype[0x100] = {
[0xFE] = IMPL
};
-#if debug
-static const char *opname[0x100] = {
- [0x00] = "CPS",
- [0x01] = "ADC #",
- [0x02] = "AAB",
- [0x04] = "ADC a",
- [0x05] = "LDA ind",
- [0x06] = "ADC zm",
- [0x08] = "PHP #",
- [0x09] = "CPB #",
- [0x0A] = "PHB #",
- [0x0C] = "DEC a",
- [0x0D] = "DEC zm",
- [0x0E] = "JMP zm",
- [0x10] = "JMP a",
- [0x11] = "SBC #",
- [0x12] = "SAB",
- [0x14] = "SBC a",
- [0x15] = "STA ind",
- [0x16] = "SBC zm",
- [0x18] = "ENT #",
- [0x19] = "CPY #",
- [0x1A] = "PLB #",
- [0x1C] = "INC a",
- [0x1D] = "INC zm",
- [0x1E] = "JSR zm",
- [0x20] = "JSL a",
- [0x21] = "AND #",
- [0x22] = "ABA",
- [0x24] = "AND a",
- [0x25] = "CMP ind",
- [0x26] = "AND zm",
- [0x28] = "PLP #",
- [0x29] = "CPX #",
- [0x2A] = "PHY #",
- [0x2C] = "CPB a",
- [0x2D] = "CPB zm",
- [0x2E] = "BPO zm",
- [0x30] = "BPO a",
- [0x31] = "ORA #",
- [0x32] = "OAB",
- [0x34] = "ORA a",
- [0x35] = "LDB ind",
- [0x36] = "ORA zm",
- [0x38] = "STT #",
- [0x39] = "LDA zmy",
- [0x3A] = "PLY #",
- [0x3C] = "CPX a",
- [0x3D] = "CPY zm",
- [0x3E] = "BNG zm",
- [0x40] = "BNG a",
- [0x41] = "XOR #",
- [0x42] = "XAB",
- [0x44] = "XOR a",
- [0x45] = "STB ind",
- [0x46] = "XOR zm",
- [0x48] = "PHA #",
- [0x49] = "STA zmy",
- [0x4A] = "PHX #",
- [0x4C] = "CPY a",
- [0x4D] = "CPX zm",
- [0x4E] = "BCS zm",
- [0x50] = "BCS a",
- [0x51] = "LSL #",
- [0x52] = "LLB",
- [0x54] = "LSL a",
- [0x55] = "CPB ind",
- [0x56] = "LSL zm",
- [0x58] = "CLC",
- [0x59] = "LDB zmy",
- [0x5A] = "PLX #",
- [0x5C] = "LDA iny",
- [0x5D] = "LDA inx",
- [0x5E] = "BCC zm",
- [0x60] = "BCC a",
- [0x61] = "LSR #",
- [0x62] = "LRB",
- [0x64] = "LSR a",
- [0x65] = "LDY ind",
- [0x66] = "LSR zm",
- [0x68] = "PLA #",
- [0x69] = "STB zmy",
- [0x6A] = "TAB",
- [0x6C] = "STA iny",
- [0x6D] = "STA inx",
- [0x6E] = "BEQ zm",
- [0x70] = "BEQ a",
- [0x71] = "ROL #",
- [0x72] = "RLB",
- [0x74] = "ROL a",
- [0x75] = "STY ind",
- [0x76] = "ROL zm",
- [0x78] = "SEC",
- [0x79] = "LDA zmx",
- [0x7A] = "TBA",
- [0x7C] = "CMP iny",
- [0x7D] = "CMP inx",
- [0x7E] = "BNE zm",
- [0x80] = "BNE a",
- [0x81] = "ROR #",
- [0x82] = "RRB",
- [0x84] = "ROR a",
- [0x85] = "CPY ind",
- [0x86] = "ROR zm",
- [0x88] = "DEY",
- [0x89] = "STA zmx",
- [0x8A] = "TAY",
- [0x8C] = "LDB iny",
- [0x8D] = "LDB inx",
- [0x8E] = "BVS zm",
- [0x90] = "BVS a",
- [0x91] = "MUL #",
- [0x92] = "MAB",
- [0x94] = "MUL a",
- [0x95] = "LDX ind",
- [0x96] = "MUL zm",
- [0x98] = "CLI",
- [0x99] = "LDB zmx",
- [0x9A] = "TYA",
- [0x9C] = "STB iny",
- [0x9D] = "STB inx",
- [0x9E] = "BVC zm",
- [0xA0] = "BVC a",
- [0xA1] = "DIV #",
- [0xA2] = "DAB",
- [0xA4] = "DIV a",
- [0xA5] = "STX ind",
- [0xA6] = "DIV zm",
- [0xA8] = "INY",
- [0xA9] = "STB zmx",
- [0xAA] = "TAX",
- [0xAC] = "CPB iny",
- [0xAD] = "CPB inx",
- [0xAE] = "RTS",
- [0xB0] = "RTL",
- [0xB1] = "CMP #",
- [0xB2] = "CAB",
- [0xB4] = "CMP a",
- [0xB5] = "CPX ind",
- [0xB6] = "CMP zm",
- [0xB8] = "SEI",
- [0xB9] = "LDX #",
- [0xBA] = "TXA",
- [0xBC] = "LDX a",
- [0xBD] = "LDX zm",
- [0xBE] = "JSR ind",
- [0xC0] = "RTI",
- [0xC1] = "LDA #",
- [0xC4] = "LDA a",
- [0xC5] = "DEX",
- [0xC6] = "LDA zm",
- [0xC8] = "CLV",
- [0xC9] = "LDX zmy",
- [0xCA] = "TYX",
- [0xCC] = "STA a",
- [0xCD] = "STA zm",
- [0xCE] = "JMP ind",
- [0xD0] = "TSX",
- [0xD1] = "LDB #",
- [0xD4] = "LDB a",
- [0xD5] = "INX",
- [0xD6] = "LDB zm",
- [0xD8] = "WAI",
- [0xD9] = "STX zmy",
- [0xDA] = "TXY",
- [0xDC] = "STB a",
- [0xDD] = "STB zm",
- [0xE0] = "TXS #",
- [0xE1] = "LDY #",
- [0xE4] = "LDY a",
- [0xE5] = "DEC A",
- [0xE6] = "LDY zm",
- [0xE8] = "BRK",
- [0xE9] = "LDY zmx",
- [0xEA] = "NOP",
- [0xEC] = "STY a",
- [0xED] = "STY zm",
- [0xEE] = "DEB",
- [0xF1] = "ASR #",
- [0xF2] = "ARB",
- [0xF4] = "ASR a",
- [0xF5] = "INC A",
- [0xF6] = "ASR zm",
- [0xF9] = "STY zmx",
- [0xFC] = "STX a",
- [0xFD] = "STX zm",
- [0xFE] = "INB"
-};
-#endif
-
extern int asmmon();
diff --git a/sux.c b/sux.c
index fe90728..1743fc0 100644
--- a/sux.c
+++ b/sux.c
@@ -1,25 +1,7 @@
-#include "opcode.h"
+#include "sux.h"
#include <assert.h>
#include <ctype.h>
#include <string.h>
-#include <pthread.h>
-
-#if bench
-#include <sys/time.h>
-#else
-#include <curses.h>
-#endif
-
-#define THREADS 1
-#define BENCH_INST 100000000 << (THREADS-1)
-#define CTRL_ADDR 0xC000
-#define TX_ADDR 0xC001
-#define RX_ADDR 0xC002
-#define STEP_ADDR 0xC010
-#define CURSES_BACKSPACE 0x7F
-
-#define setflag(flag, bit) ((flag)) ? (cpu->ps |= (bit << (thread << 3))) : (cpu->ps &= ~(bit << (thread << 3)))
-#define getflag(bit) (cpu->ps & (bit << (thread << 3)))
#if getclk
uint64_t clk[THREADS]; /* Per Thread Clock cycles. */
@@ -32,28 +14,18 @@ const uint16_t tv = 0xFF50; /* Starting address of the Thread Vectors. */
uint64_t inst[THREADS];
#endif
-#if debug
-uint8_t subdbg = 0;
-#endif
-
#if bench
uint64_t inss;
#endif
-uint8_t threads_done = 0;
-uint8_t kbd_rdy = 0;
-uint8_t step = 0;
-
-
-#if !bench
-WINDOW *scr;
-#endif
-
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t main_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t main_cond = PTHREAD_COND_INITIALIZER;
+uint8_t threads_done = 0;
+uint8_t step = 0;
+
struct suxthr {
struct sux sx;
uint8_t th;
@@ -71,31 +43,18 @@ void *run(void *args) {
uint64_t address = 0;
uint8_t prefix = 0;
uint8_t opcode = 0;
- uint64_t sum = 0;
+ uint8_t esc = 0;
uint64_t value = 0;
- uint64_t reg = 0;
#if getclk
uint64_t iclk = 0;
#endif
#if !IO
uint64_t ins = 0;
#endif
- uint8_t sign = 0;
- uint8_t tmp;
- uint8_t tmp2;
#if !bench
uint8_t lines = (6*thread)+2;
- uint8_t bcd[4];
- uint8_t idx = 3, iscol = 0;
- int x = 0, y = 0;
- uint8_t esc = 0;
-#endif
-#if bench
- gettimeofday(&str[thread], 0);
#endif
#if debug && !bench
- uint64_t tmpaddr = 0;
- uint16_t scr_col = 0;
if (!subdbg) {
addr[STEP_ADDR] = 1;
step = 1;
@@ -108,6 +67,10 @@ void *run(void *args) {
pthread_mutex_unlock(&mutex);
#endif
#endif
+ uint64_t tmpaddr = 0;
+#if bench
+ gettimeofday(&str[thread], 0);
+#endif
for (;;) {
address = 0;
prefix = addr[cpu->pc[thread]];
@@ -151,141 +114,7 @@ void *run(void *args) {
#if getclk
++iclk;
#endif
- switch (optype[opcode]) {
- case IMPL:
- break;
- case IMM:
- switch (opcode) {
- case TXS:
- break;
- case PHB:
- case PHP:
- case PHA:
- case PHY:
- case PHX:
- case PLB:
- case PLP:
- case PLA:
- case PLY:
- case PLX:
- case STT:
- case LSL:
- case LSR:
- case ROL:
- case ROR:
- case ASR:
- case ENT:
- address = cpu->pc[thread];
- ++cpu->pc[thread];
- break;
- default:
- address = cpu->pc[thread];
- cpu->pc[thread]+=(1 << (prefix >> 4));
- break;
- }
- break;
- case ZM:
- case ZMX:
- case ZMY:
- case IND:
- case INDX:
- case INDY:
- tmp = 0;
- address = addr[cpu->pc[thread]];
- /* Unroll Loop by implementing Duff's Device. */
- switch ((prefix & 0x0C) >> 2) {
- case 2:
- address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;++tmp;
- address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;++tmp;
- case 3:
- address |= (uint64_t)addr[cpu->pc[thread]+3] << 24;++tmp;
- case 1:
- address |= (uint64_t)addr[cpu->pc[thread]+2] << 16;++tmp;
- address |= (uint64_t)addr[cpu->pc[thread]+1] << 8;++tmp;
- case 0:
- ++tmp;
- }
- cpu->pc[thread]+=tmp;
- #if debug && !bench
- tmpaddr = address;
- #endif
- #if getclk
- iclk++;
- #endif
- reg = 0;
- switch (optype[opcode]) {
- case ZMX:
- address += cpu->x[thread];
- #if getclk
- iclk++;
- #endif
- break;
- case ZMY:
- address += cpu->y[thread];
- #if getclk
- iclk++;
- #endif
- break;
- case INDX:
- address += cpu->x[thread];
- #if getclk
- iclk++;
- #endif
- /* Falls Through. */
- case INDY:
- /* Did we fall through? */
- if (optype[opcode] == INDX) {
- reg = 0; /* Yes, so set reg back to zero. */
- } else {
- reg = cpu->y[thread]; /* No, so set reg to Y. */
- #if getclk
- iclk++;
- #endif
- }
- /* Falls Through. */
- case IND:
- value = (uint64_t)addr[address];
- value += (uint64_t)addr[address+1] << 8;
- value += (uint64_t)addr[address+2] << 16;
- value += (uint64_t)addr[address+3] << 24;
- value += (uint64_t)addr[address+4] << 32;
- value += (uint64_t)addr[address+5] << 40;
- value += (uint64_t)addr[address+6] << 48;
- value += (uint64_t)addr[address+7] << 56;
- #if getclk
- iclk++;
- #endif
- value += reg;
- address = value;
- value = 0;
- reg = 0;
- break;
- }
- break;
- case ABS:
- tmp = 0;
- address = addr[cpu->pc[thread]];++tmp;
- /* Unroll Loop by implementing Duff's Device. */
- switch ((prefix & 0x0C) >> 2) {
- case 3:
- address |= (uint64_t)addr[cpu->pc[thread]+7] << 56;++tmp;
- case 2:
- address |= (uint64_t)addr[cpu->pc[thread]+6] << 48;++tmp;
- address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;++tmp;
- #if getclk
- iclk++;
- #endif
- case 1:
- address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;++tmp;
- address |= (uint64_t)addr[cpu->pc[thread]+3] << 24;++tmp;
- address |= (uint64_t)addr[cpu->pc[thread]+2] << 16;++tmp;
- case 0:
- address |= (uint64_t)addr[cpu->pc[thread]+1] << 8;++tmp;
- }
- cpu->pc[thread]+=tmp;
- break;
-
- }
+ address = get_addr(cpu, &tmpaddr, opcode, prefix, thread);
value = addr[address];
/* Unroll Loop by implementing Duff's Device. */
switch (1 << (prefix >> 4)) {
@@ -304,138 +133,15 @@ void *run(void *args) {
#if keypoll
pthread_mutex_lock(&mutex);
#endif
- char postfix[3];
- char op[4];
- op[0] = opname[opcode][0];
- op[1] = opname[opcode][1];
- op[2] = opname[opcode][2];
- op[3] = '\0';
- switch(1 << (prefix >> 4)) {
- case 1: postfix[0] = 0; postfix[1] = 0; postfix[2] = 0; break;
- case 2: postfix[0] = '.'; postfix[1] = 'W'; postfix[2] = 0; break;
- case 4: postfix[0] = '.'; postfix[1] = 'D'; postfix[2] = 0; break;
- case 8: postfix[0] = '.'; postfix[1] = 'Q'; postfix[2] = 0; break;
- }
- switch (optype[opcode]) {
- case IMPL: wprintw(scr, "%s\r" , opname[opcode]); break;
- case IMM:
- switch(1 << (prefix >> 4)) {
- case 1: wprintw(scr, "%s #$%02X\r" , op, value); break;
- case 2: wprintw(scr, "%s%s #$%04X\r" , op, postfix, value); break;
- case 4: wprintw(scr, "%s%s #$%08X\r" , op, postfix, value); break;
- case 8: wprintw(scr, "%s%s #$%016"PRIX64"\r" , op, postfix, value); break;
- }
- break;
- case ZM:
- case ZMX:
- case ZMY:
- switch (optype[opcode]) {
- case ZMX: tmpaddr = address - cpu->x[thread]; break;
- case ZMY: tmpaddr = address - cpu->y[thread]; break;
- }
- switch ((prefix & 0x0C) >> 2) {
- case 3: wprintw(scr, "%s%s $%08X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
- case 2: wprintw(scr, "%s%s $%014"PRIX64"%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
- case 1: wprintw(scr, "%s%s $%06X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
- case 0: wprintw(scr, "%s%s $%02X%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
- }
- break;
- case IND:
- case INDX:
- case INDY:
- switch ((prefix & 0x0C) >> 2) {
- case 3: wprintw(scr, "%s%s ($%08X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
- case 2: wprintw(scr, "%s%s ($%012"PRIX64"%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
- case 1: wprintw(scr, "%s%s ($%06X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
- case 0: wprintw(scr, "%s%s ($%02X%s\r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y")); break;
- }
- break;
- case ABS:
- tmpaddr = address;
- switch ((prefix & 0x0C) >> 2) {
- case 3: wprintw(scr, "%s%s $%016"PRIX64"\r" , op, postfix, tmpaddr); break;
- case 2: wprintw(scr, "%s%s $%014"PRIX64"\r" , op, postfix, tmpaddr); break;
- case 1: wprintw(scr, "%s%s $%010"PRIX64"\r" , op, postfix, tmpaddr); break;
- case 0: wprintw(scr, "%s%s $%04" PRIX64"\r" , op, postfix, tmpaddr); break;
- }
- break;
- }
-
- if (address == TX_ADDR || address == RX_ADDR) {
- wmove(scr, 27, 0);
- wprintw(scr, "TX_ADDR: $%02X, RX_ADDR: $%02X", addr[TX_ADDR], addr[RX_ADDR]);
- }
- if (subdbg) {
- uint8_t ln = 33;
- uint16_t line_idx = 0;
- uint16_t tmpad = 0x2000;
- int row, col;
- uint8_t iscursor = 0;
- uint64_t ptr;
- uint8_t adr;
- wmove(scr, 30, 0);
- adr = 0x1F;
- ptr = (uint64_t)addr[adr+0] << 0x00 | (uint64_t)addr[adr+1] << 0x08 | (uint64_t)addr[adr+2] << 0x10 | (uint64_t)addr[adr+3] << 0x18 |
- (uint64_t)addr[adr+4] << 0x20 | (uint64_t)addr[adr+5] << 0x28 | (uint64_t)addr[adr+6] << 0x30 | (uint64_t)addr[adr+7] << 0x38;
- wprintw(scr, "ptr1: $%04"PRIX64, ptr);
- adr = 0x27;
- ptr = (uint64_t)addr[adr+0] << 0x00 | (uint64_t)addr[adr+1] << 0x08 | (uint64_t)addr[adr+2] << 0x10 | (uint64_t)addr[adr+3] << 0x18 |
- (uint64_t)addr[adr+4] << 0x20 | (uint64_t)addr[adr+5] << 0x28 | (uint64_t)addr[adr+6] << 0x30 | (uint64_t)addr[adr+7] << 0x38;
- wprintw(scr, ", ptr2: $%04"PRIX64, ptr);
- adr = 0x2F;
- ptr = (uint64_t)addr[adr+0] << 0x00 | (uint64_t)addr[adr+1] << 0x08 | (uint64_t)addr[adr+2] << 0x10 | (uint64_t)addr[adr+3] << 0x18 |
- (uint64_t)addr[adr+4] << 0x20 | (uint64_t)addr[adr+5] << 0x28 | (uint64_t)addr[adr+6] << 0x30 | (uint64_t)addr[adr+7] << 0x38;
- wprintw(scr, ", ptr3: $%04"PRIX64, ptr);
- if (address == CTRL_ADDR || addr[STEP_ADDR]) {
- mvwprintw(scr, 29, 0, "address: $%04"PRIX64", scr_row: %02u, scr_col: %02u, scr_str: %02u, scr_end: %02u\r", address, addr[0], addr[1], addr[0x1C], addr[0x1D]);
- mvwprintw(scr, 32, 0, "bitabl: %02X%02X%02X%02X%02X%02X%02X%02X"
- "%02X%02X%02X%02X%02X%02X%02X%02X"
- , addr[0x1000], addr[0x1001], addr[0x1002], addr[0x1003], addr[0x1004], addr[0x1005], addr[0x1006], addr[0x1007]
- , addr[0x1008], addr[0x1009], addr[0x100A], addr[0x100B], addr[0x100C], addr[0x100D], addr[0x100E], addr[0x100F]);
- mvwprintw(scr, ln++, 0, "buffer:\r");
- wmove(scr, ln++, 0);
- for (uint8_t i = 0; i < 10; i++) {
- line_idx = (i << 6) + (i << 4);
- for (uint8_t j = 0; j < 0x50; j++) {
- wprintw(scr, "%02X", addr[tmpad+j+line_idx]);
- if ((addr[0]+addr[0x1C]) == i && addr[1] == j) {
- iscursor=1;
- getyx(scr,row, col);
- wmove(scr, ln++, 0);
- wclrtoeol(scr);
- wmove(scr, row+1, col-2);
- wprintw(scr, "/\\\r");
- wmove(scr, row, col);
- }
- }
- wprintw(scr, ", i: %02X", i);
- if (!iscursor) {
- wmove(scr, ln, 0);
- wclrtoeol(scr);
- }
- iscursor = 0;
- wmove(scr, ln++, 0);
- }
- }
- /*if (address == 0x4000 || tmpaddr == 0x4000 || addr[STEP_ADDR]) {
- ln = 46;
- tmpad = 0x4000;
- line_idx = 0;
- mvwprintw(scr, ln++, 0, "cmd_buf:");
- for (uint8_t i = 0; i < 5; i++) {
- wmove(scr, ln++, 0);
- line_idx = (i << 4)+(i << 6);
- for (uint8_t j = 0; j < 0x50; j++) {
- wprintw(scr, "%02X", addr[tmpad+j+line_idx]);
- }
- wprintw(scr, ", i: %02X", i);
- }
- }*/
- }
+ uint64_t operands[3];
+ operands[0] = value;
+ operands[1] = address;
+ operands[2] = tmpaddr;
+ disasm(cpu, operands, lines, opcode, prefix, thread);
+ lines+=1;
#if keypoll
pthread_mutex_unlock(&mutex);
#endif
- lines+=1;
#endif
switch(opcode) {
case CPS: /* Clear Processor Status. */
@@ -446,37 +152,14 @@ void *run(void *args) {
case ADC: /* ADC Immediate. */
case ADC_AB: /* ADC Absolute. */
case ADC_Z: /* ADC Zero Matrix. */
- sum = cpu->a[thread]+value+getflag(C);
- cpu->a[thread] = sum;
- setflag(sum == 0, Z);
- setflag((sum >> 63), N);
- setflag(((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
- setflag((sum < value), C);
+ adc(cpu, value, thread);
break;
case PHB: /* PusH B register to stack. */
case PHP: /* PusH Processor status to stack. */
case PHA: /* PusH Accumulator to stack. */
case PHY: /* PusH Y register to stack. */
case PHX: /* PusH X register to stack. */
- tmp = (value <= 7) ? value : 7;
- switch (opcode) {
- case PHA: reg = cpu->a[thread]; break;
- case PHB: reg = cpu->b[thread]; break;
- case PHX: reg = cpu->x[thread]; break;
- case PHY: reg = cpu->y[thread]; break;
- case PHP: reg = cpu->ps; break;
- }
- /* Unroll Loop by implementing Duff's Device. */
- switch (tmp) {
- case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (7<<3);cpu->sp[thread]--;
- case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (6<<3);cpu->sp[thread]--;
- case 5: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (5<<3);cpu->sp[thread]--;
- case 4: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (4<<3);cpu->sp[thread]--;
- case 3: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (3<<3);cpu->sp[thread]--;
- case 2: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (2<<3);cpu->sp[thread]--;
- case 1: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg >> (1<<3);cpu->sp[thread]--;
- case 0: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = reg & (0xFF);cpu->sp[thread]--;
- }
+ push(cpu, value, opcode, thread);
break;
case TAY: /* Transfer Accumulator to Y. */
case TAX: /* Transfer Accumulator to Y. */
@@ -488,26 +171,7 @@ void *run(void *args) {
case TSX: /* Transfer Stack pointer to X. */
case TBA: /* Transfer B to Accumulator. */
case TXS: /* Transfer X to Stack pointer. */
- switch (opcode) {
- case TBA: cpu->a[thread] = cpu->b[thread]; reg = cpu->a[thread]; break;
- case TXA: cpu->a[thread] = cpu->x[thread]; reg = cpu->a[thread]; break;
- case TYA: cpu->a[thread] = cpu->y[thread]; reg = cpu->a[thread]; break;
- case TAB: cpu->b[thread] = cpu->a[thread]; reg = cpu->b[thread]; break;
- case TAY: cpu->y[thread] = cpu->a[thread]; reg = cpu->y[thread]; break;
- case TXY: cpu->y[thread] = cpu->x[thread]; reg = cpu->y[thread]; break;
- case TAX: cpu->x[thread] = cpu->a[thread]; reg = cpu->x[thread]; break;
- case TYX: cpu->x[thread] = cpu->y[thread]; reg = cpu->x[thread]; break;
- case TSX: cpu->x[thread] = cpu->sp[thread] & 0xFFFF; cpu->x[thread] = cpu->stk_st[thread] << 16; break;
- case TXS: cpu->sp[thread] = cpu->x[thread];
- if (prefix == 0x13 && (value == thread+1 || value > 8)) {
- cpu->stk_st[thread] = value & 0xFF;
- cpu->stk_st[thread] += value << 16;
- cpu->pc[thread]+=2;
- }
- break;
- }
- setflag(reg == 0, Z);
- setflag(reg >> 63, N);
+ transfer(cpu, value, opcode, prefix, thread);
break;
case JMP: /* JMP Absolute. */
case JMP_Z: /* JMP Zero Matrix. */
@@ -519,48 +183,21 @@ void *run(void *args) {
case SBC: /* SBC Immediate. */
case SBC_AB: /* SBC Absolute. */
case SBC_Z: /* SBC Zero Matrix. */
- sum = cpu->a[thread]-value-!getflag(C);
- setflag(sum == 0, Z);
- setflag(sum >> 63, N);
- setflag(((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
- setflag((sum > value), C);
- cpu->a[thread] = sum;
+ sbc(cpu, value, thread);
break;
case PLB: /* PuLl B register from stack. */
case PLP: /* PuLl Processor status from stack. */
case PLA: /* PuLl Accumulator from stack. */
case PLY: /* PuLl Y register from stack. */
case PLX: /* PuLl X register from stack. */
- tmp = (value <= 7) ? value : 7;
- reg = 0;
- tmp2 = 0;
- cpu->sp[thread]++;reg = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF;
- /* Unroll Loop by implementing Duff's Device. */
- switch (tmp) {
- case 7: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
- case 6: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
- case 5: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
- case 4: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
- case 3: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
- case 2: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
- case 1: cpu->sp[thread]++;tmp2++;reg += (uint64_t)addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
- }
- switch (opcode) {
- case PLA: cpu->a[thread] = reg; break;
- case PLB: cpu->b[thread] = reg; break;
- case PLX: cpu->x[thread] = reg; break;
- case PLY: cpu->y[thread] = reg; break;
- case PLP: cpu->ps = reg; break;
- }
+ pull(cpu, value, opcode, thread);
break;
case ABA: /* bitwise And with Accumulator, and B register. */
value = cpu->b[thread]; /* Falls Through. */
case AND: /* AND Immediate. */
case AND_AB: /* AND Absolute. */
case AND_Z: /* AND Zero Matrix. */
- cpu->a[thread] &= value;
- setflag(cpu->a[thread] == 0, Z);
- setflag(cpu->a[thread] >> 63, N);
+ and(cpu, value, thread);
break;
case STT: /* STart Thread. */
cpu->crt |= value;
@@ -589,9 +226,7 @@ void *run(void *args) {
case ORA: /* ORA Immediate. */
case ORA_AB: /* ORA Absolute. */
case ORA_Z: /* ORA Zero Matrix. */
- cpu->a[thread] |= value;
- setflag(cpu->a[thread] == 0, Z);
- setflag(cpu->a[thread] >> 63, N);
+ or(cpu, value, thread);
break;
case SEI: /* SEt Interrupt. */
setflag(1, I);
@@ -607,9 +242,7 @@ void *run(void *args) {
case XOR: /* XOR Immediate. */
case XOR_AB: /* XOR Absolute. */
case XOR_Z: /* XOR Zero Matrix. */
- cpu->a[thread] ^= value;
- setflag(cpu->a[thread] == 0, Z);
- setflag(cpu->a[thread] >> 63, N);
+ xor(cpu, value, thread);
break;
case CLI: /* CLear Interrupt. */
setflag(0, I);
@@ -625,11 +258,7 @@ void *run(void *args) {
case LSL: /* LSL Immediate. */
case LSL_AB: /* LSL Absolute. */
case LSL_Z: /* LSL Zero Matrix. */
- sum = (value < 64) ? cpu->a[thread] << value : 0;
- setflag(sum == 0, Z);
- setflag(sum >> 63, N);
- setflag(cpu->a[thread] >> (64-value), C);
- cpu->a[thread] = sum;
+ lsl(cpu, value, thread);
break;
case SEC: /* SEt Carry flag.*/
setflag(1, C);
@@ -656,219 +285,7 @@ void *run(void *args) {
case STB_IX: /* STB Indexed Indirect. */
case STA_IY: /* STA Indirect Indexed. */
case STB_IY: /* STB Indirect Indexed. */
- switch (opcode) {
- case STB:
- case STB_Z:
- case STB_ZX:
- case STB_ZY:
- case STB_IN:
- case STB_IX:
- case STB_IY:
- value = cpu->b[thread];
- break;
- case STA:
- case STA_Z:
- case STA_ZX:
- case STA_ZY:
- case STA_IN:
- case STA_IX:
- case STA_IY:
- value = cpu->a[thread];
- break;
- case STY:
- case STY_Z:
- case STY_ZX:
- case STY_IN:
- value = cpu->y[thread];
- break;
-
- case STX:
- case STX_Z:
- case STX_ZY:
- case STX_IN:
- value = cpu->x[thread];
- break;
- }
- addr[address] = value & 0xFF;
- #if (IO || debug) && !branch
- if (address == TX_ADDR) {
- #if keypoll
- pthread_mutex_lock(&mutex);
- #endif
- #if debug
- if (!subdbg) {
- scr_col = (addr[TX_ADDR] != 0x0C && addr[TX_ADDR] != '\n' && scr_col < 160) ? (addr[1] << 1)-2 : 0;
- wmove(scr, 28, scr_col);
- }
- #endif
- if (esc) {
- #if debug
- if (!subdbg && addr[RX_ADDR] == '\n') {
- wclrtoeol(scr);
- }
- #endif
- switch (addr[TX_ADDR]) {
- case 'A':
- if (y > 0)
- y--;
- #if !debug
- wmove(scr, y, x);
- #endif
- esc = 0;
- break;
- case 'B':
- if (y < getmaxy(scr))
- y++;
- #if !debug
- wmove(scr, y, x);
- #endif
- esc = 0;
- break;
- case 'C':
- if (x < getmaxx(scr))
- x++;
- #if !debug
- wmove(scr, y, x);
- #endif
- esc = 0;
- break;
- case 'D':
- if (x > 0)
- x--;
- #if !debug
- wmove(scr, y, x);
- #endif
- esc = 0;
- break;
- case 'H':
- if (!bcd[2] && !bcd[3]) {
- y = 0;
- } else {
- y = ((bcd[3]*10) + bcd[2]);
- }
- if (!bcd[0] && !bcd[1]) {
- x = 0;
- } else {
- x = ((bcd[1]*10) + bcd[0]);
- }
- #if !debug
- wmove(scr, y, x);
- #else
- mvwprintw(scr, 30, 0, "x: %i, y: %i ", x, y);
- /*mvwprintw(scr, 31, 0, "bcd[3-2]: {%u, %u}, bcd[1-0]: {%u, %u}", bcd[3], bcd[2], bcd[1], bcd[0]);*/
- #endif
- idx = 3;
- bcd[0] = 0;
- bcd[1] = 0;
- bcd[2] = 0;
- bcd[3] = 0;
- esc = 0;
- break;
- case 'S':
- #if !debug
- wscrl(scr, -1);
- #else
- #endif
- esc = 0;
- break;
- case 'T':
- #if !debug
- wscrl(scr, 1);
- #else
- #endif
- esc = 0;
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- bcd[idx--] = (addr[address] - '0');
- break;
- default:
- iscol = (addr[address] == ';');
- break;
- }
- } else {
- switch (addr[TX_ADDR]) {
- case 0xC:
- x=0,y=0;
- #if !debug
- wclear(scr);
- wmove(scr, y, x);
- #endif
- break;
- case CURSES_BACKSPACE:
- case '\b':
- if (x > 0) {
- x--;
- #if !debug
- wmove(scr, y, x);
- #endif
- }
- #if !debug
- wdelch(scr);
- #else
- if (!subdbg) {
- scr_col++;
- wmove(scr, 28, scr_col--);
- wdelch(scr);
- wmove(scr, 28, scr_col);
- wdelch(scr);
- }
- #endif
- break;
- case '\033':
- esc = 1;
- break;
- case '\n':
- #if !debug
- wmove(scr, y, x);
- waddch(scr, addr[address]);
- #endif
- x = 0;
- y+=1;
- break;
- default:
- #if !debug
- wmove(scr, y, x);
- waddch(scr, addr[address]);
- #else
- if (!subdbg && scr_col < 160) {
- if (addr[address] != ' ') {
- wprintw(scr, "%02X", addr[address]);
- } else {
- wprintw(scr, " ");
- }
- }
- #endif
- x+=1;
- break;
- }
- }
- #if keypoll
- pthread_mutex_unlock(&mutex);
- #endif
- }
- #endif
- /* Unroll Loop by implementing Duff's Device. */
- switch (1 << (prefix >> 4)) {
- case 8:
- addr[address+7] = value >> 56;
- addr[address+6] = value >> 48;
- addr[address+5] = value >> 40;
- addr[address+4] = value >> 32;
- case 4:
- addr[address+3] = value >> 24;
- addr[address+2] = value >> 16;
- case 2:
- addr[address+1] = value >> 8;
- }
+ store(cpu, address, &esc, opcode, prefix, thread);
step = addr[STEP_ADDR] || cpu->pc[thread] == CTRL_ADDR;
break;
case BCC: /* BCC Absolute. */
@@ -882,23 +299,14 @@ void *run(void *args) {
case LSR: /* LSR Immediate. */
case LSR_AB: /* LSR Absolute. */
case LSR_Z: /* LSR Zero Matrix. */
- sum = (value < 64) ? cpu->a[thread] >> value : 0;
- setflag(sum == 0, Z);
- setflag(sum >> 63, N);
- setflag(cpu->a[thread] & 1, C);
- cpu->a[thread] = sum;
+ lsr(cpu, value, thread);
break;
case ARB: /* Arithmetic shift Right accumulator by B. */
value = cpu->b[thread]; /* Falls Through. */
case ASR: /* ASR Immediate. */
case ASR_AB: /* ASR Absolute. */
case ASR_Z: /* ASR Zero Matrix. */
- sign = cpu->a[thread] >> 63;
- sum = (value < 64) ? (cpu->a[thread] >> value) | ((uint64_t)sign << 63) : 0;
- setflag(sum == 0, Z);
- setflag(sum >> 63, N);
- setflag(cpu->a[thread] & 1, C);
- cpu->a[thread] = sum;
+ asr(cpu, value, thread);
break;
case CLC: /* CLear Carry flag. */
setflag(0, C);
@@ -929,71 +337,7 @@ void *run(void *args) {
case LDA_IX: /* LDA Indexed Indirect. */
case LDB_IY: /* LDB Indirect Indexed. */
case LDA_IY: /* LDA Indirect Indexed. */
- if (address == CTRL_ADDR) {
- kbd_rdy = 1;
- pthread_mutex_lock(&main_mutex);
- pthread_cond_signal(&main_cond);
- pthread_mutex_unlock(&main_mutex);
- #if !keypoll
- pthread_mutex_lock(&mutex);
- pthread_cond_wait(&cond, &mutex);
- pthread_mutex_unlock(&mutex);
- #endif
- kbd_rdy = 0;
- }
- value = addr[address];
- /* Unroll Loop by implementing Duff's Device. */
- switch (1 << (prefix >> 4)) {
- case 8:
- value |= (uint64_t)addr[address+7] << 56;
- value |= (uint64_t)addr[address+6] << 48;
- value |= (uint64_t)addr[address+5] << 40;
- value |= (uint64_t)addr[address+4] << 32;
- case 4:
- value |= (uint64_t)addr[address+3] << 24;
- value |= (uint64_t)addr[address+2] << 16;
- case 2:
- value |= (uint64_t)addr[address+1] << 8;
- }
- switch (opcode) {
- case LDB:
- case LDB_AB:
- case LDB_Z:
- case LDB_ZX:
- case LDB_ZY:
- case LDB_IN:
- case LDB_IX:
- case LDB_IY:
- cpu->b[thread] = value;
- break;
- case LDA:
- case LDA_AB:
- case LDA_Z:
- case LDA_ZX:
- case LDA_ZY:
- case LDA_IN:
- case LDA_IX:
- case LDA_IY:
- cpu->a[thread] = value;
- break;
- case LDY:
- case LDY_AB:
- case LDY_Z:
- case LDY_ZX:
- case LDY_IN:
- cpu->y[thread] = value;
- break;
-
- case LDX:
- case LDX_AB:
- case LDX_Z:
- case LDX_ZY:
- case LDX_IN:
- cpu->x[thread] = value;
- break;
- }
- setflag(value == 0, Z);
- setflag(value >> 63, N);
+ load(cpu, address, &esc, opcode, prefix, thread);
break;
case BEQ: /* BEQ Absolute. */
case BEQ_Z: /* BEQ Zero Matrix. */
@@ -1006,12 +350,7 @@ void *run(void *args) {
case ROL: /* ROL Immediate. */
case ROL_AB: /* ROL Absolute. */
case ROL_Z: /* ROL Zero Matrix. */
- sum = cpu->a[thread] << value;
- sum |= getflag(C);
- setflag(sum == 0, Z);
- setflag(sum >> 63, N);
- setflag(cpu->a[thread] >> (uint64_t)(64-value), C);
- cpu->a[thread] = sum;
+ rol(cpu, value, thread);
break;
case BNE: /* BNE Absolute. */
case BNE_Z: /* BNE Zero Matrix. */
@@ -1024,12 +363,7 @@ void *run(void *args) {
case ROR: /* ROR Immediate. */
case ROR_AB: /* ROR Absolute. */
case ROR_Z: /* ROR Zero Matrix. */
- sum = cpu->a[thread] >> value;
- sum |= (uint64_t)getflag(C) << (uint64_t)(64-value);
- setflag(sum == 0, Z);
- setflag(sum >> 63, N);
- setflag(cpu->a[thread] & 1, C);
- cpu->a[thread] = sum;
+ ror(cpu, value, thread);
break;
case BVS: /* BVS Absolute. */
case BVS_Z: /* BVS Zero Matrix. */
@@ -1042,11 +376,7 @@ void *run(void *args) {
case MUL: /* MUL Immediate. */
case MUL_AB: /* MUL Absolute. */
case MUL_Z: /* MUL Zero Matrix. */
- sum = cpu->a[thread]*value;
- cpu->a[thread] = sum;
- setflag(sum == 0, Z);
- setflag(sum >> 63, N);
- setflag(!((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
+ mul(cpu, value, thread);
break;
case BVC: /* BVC Absolute. */
case BVC_Z: /* BVC Zero Matrix. */
@@ -1058,16 +388,7 @@ void *run(void *args) {
case DAB: /* Divide Accumulator by B. */
case DIV_AB: /* DIV Absolute. */
case DIV_Z: /* DIV Zero Matrix. */
- sum = cpu->a[thread]/value;
- if (opcode != DAB) {
- cpu->b[thread] = cpu->a[thread] % value;
- } else {
- value = cpu->b[thread];
- cpu->x[thread] = cpu->a[thread] % value;
- }
- cpu->a[thread] = sum;
- setflag(sum == 0, Z);
- setflag((sum >> 63), N);
+ divd(cpu, value, opcode, thread);
break;
case CLV: /* CLear oVerflow flag. */
setflag(0, V);
@@ -1094,43 +415,7 @@ void *run(void *args) {
case CPB_IX: /* CPB Indexed Indirect. */
case CMP_IY: /* CMP Indirect Indexed. */
case CPB_IY: /* CPB Indirect Indexed. */
- switch (opcode) {
- case CPB:
- case CPB_AB:
- case CPB_Z:
- case CPB_IN:
- case CPB_IX:
- case CPB_IY:
- reg = cpu->b[thread];
- break;
- case CMP:
- case CAB:
- case CMP_AB:
- case CMP_Z:
- case CMP_IN:
- case CMP_IX:
- case CMP_IY:
- reg = cpu->a[thread];
- break;
- case CPY:
- case CPY_AB:
- case CPY_Z:
- case CPY_IN:
- reg = cpu->y[thread];
- break;
-
- case CPX:
- case CPX_AB:
- case CPX_Z:
- case CPX_IN:
- reg = cpu->x[thread];
- break;
- }
- sum = reg-value;
- setflag(sum >> 63, N);
- setflag(((reg^value) >> 63) && ((reg^sum) >> 63), V);
- setflag(sum == 0, Z);
- setflag(reg >= value, C);
+ cmp(cpu, value, opcode, thread);
break;
case ENT: /* ENd Thread. */
cpu->crt &= ~value;
@@ -1154,27 +439,13 @@ void *run(void *args) {
case INB:
case INY:
case INX:
- switch (opcode) {
- case INC: cpu->a[thread]+=1; reg = cpu->a[thread]; break;
- case INB: cpu->b[thread]+=1; reg = cpu->b[thread]; break;
- case INY: cpu->y[thread]+=1; reg = cpu->y[thread]; break;
- case INX: cpu->x[thread]+=1; reg = cpu->x[thread]; break;
- }
- setflag(reg == 0, Z);
- setflag(reg >> 63, N);
+ incr(cpu, value, opcode, thread);
break;
case DEC: /* DEC Accumulator. */
case DEB:
case DEY:
case DEX:
- switch (opcode) {
- case DEC: cpu->a[thread]-=1; reg = cpu->a[thread]; break;
- case DEB: cpu->b[thread]-=1; reg = cpu->b[thread]; break;
- case DEY: cpu->y[thread]-=1; reg = cpu->y[thread]; break;
- case DEX: cpu->x[thread]-=1; reg = cpu->x[thread]; break;
- }
- setflag(reg == 0, Z);
- setflag(reg >> 63, N);
+ decr(cpu, value, opcode, thread);
break;
case JSR_IN: /* JSR Indirect. */
case JSR: /* Jump to SubRoutine. */
@@ -1192,9 +463,7 @@ void *run(void *args) {
break;
case INC_AB: /* INC Absolute. */
case INC_Z: /* INC Zero Matrix. */
- addr[address]++;
- setflag(addr[address] == 0, Z);
- setflag(addr[address] >> 7, N);
+ incm(cpu, address, thread);
step = addr[STEP_ADDR] || cpu->pc[thread] == CTRL_ADDR;
break;
case NOP: /* No OPeration. */
@@ -1213,9 +482,7 @@ void *run(void *args) {
break;
case DEC_AB: /* DEC Absolute. */
case DEC_Z: /* DEC Zero Matrix. */
- addr[address]--;
- setflag(addr[address] == 0, Z);
- setflag(addr[address] >> 7, N);
+ decm(cpu, address, thread);
step = addr[STEP_ADDR] || cpu->pc[thread] == CTRL_ADDR;
break;
case BRK: /* BReaK. */
@@ -1335,7 +602,6 @@ int main(int argc, char **argv) {
sprintf(tmp, "\033[2J\033[H");
fwrite(tmp, sizeof(char), strlen(tmp), stdout);
fflush(stdout);
- #if !bench
if(!scr) {
scr = initscr();
}
@@ -1352,7 +618,6 @@ int main(int argc, char **argv) {
attron(COLOR_PAIR(1) | A_BOLD);
wmove(scr, 0, 0);
wrefresh(scr);
- #endif
pthread_t therads[THREADS];
int result;
uint16_t vec = 0xFFC0;
@@ -1384,10 +649,9 @@ int main(int argc, char **argv) {
}
int c = 0;
uint8_t step_key = 0;
-#if !bench
+ uint8_t end = 0;
werase(scr);
-#endif
- while (threads_done < THREADS) {
+ while (threads_done < THREADS && !end) {
#if !bench
int x, y;
if ((step_key && step && !kbd_rdy) || !step || kbd_rdy) {
@@ -1411,13 +675,15 @@ int main(int argc, char **argv) {
#if keypoll
pthread_mutex_lock(&mutex);
#endif
- getyx(scr, y, x);
c = wgetch(scr);
if (c == 19) {
if (kbd_rdy) {
c = wgetch(scr);
}
step = 1;
+ } else if (c == 0x11) {
+ end = 1;
+ continue;
}
if (kbd_rdy) {
switch (c) {
@@ -1453,6 +719,7 @@ int main(int argc, char **argv) {
pthread_mutex_unlock(&main_mutex);
#endif
}
+ endwin();
#if bench
if (threads_done == THREADS) {
double tm_sec, tm_usec, tm[THREADS], ttm;
diff --git a/sux.h b/sux.h
new file mode 100644
index 0000000..9996ba6
--- /dev/null
+++ b/sux.h
@@ -0,0 +1,554 @@
+#include "opcode.h"
+#include <pthread.h>
+
+#if bench
+#include <sys/time.h>
+#endif
+#include <curses.h>
+
+#define THREADS 1
+#define BENCH_INST 100000000 << (THREADS-1)
+#define CTRL_ADDR 0xC000
+#define TX_ADDR 0xC001
+#define RX_ADDR 0xC002
+#define STEP_ADDR 0xC010
+#define CURSES_BACKSPACE 0x7F
+
+uint8_t kbd_rdy;
+
+#if debug
+uint8_t subdbg;
+#endif
+
+WINDOW *scr;
+
+#define setflag(flag, bit) ((flag)) ? (cpu->ps |= (bit << (thread << 3))) : (cpu->ps &= ~(bit << (thread << 3)))
+#define getflag(bit) (cpu->ps & (bit << (thread << 3)))
+
+extern pthread_mutex_t mutex;
+extern pthread_mutex_t main_mutex;
+extern pthread_cond_t cond;
+extern pthread_cond_t main_cond;
+
+#if debug
+extern void disasm(struct sux *cpu, uint64_t *operands, uint8_t lines, uint8_t opcode, uint8_t prefix, uint8_t thread);
+#endif
+
+extern void io(uint64_t address, uint8_t *esc);
+
+static inline uint64_t get_addr(struct sux *cpu, uint64_t *tmpaddr, uint8_t opcode, uint8_t prefix, uint8_t thread) {
+ uint64_t address = 0;
+ uint64_t value = 0;
+ uint8_t tmp = 0;
+ switch (optype[opcode]) {
+ case IMPL:
+ break;
+ case IMM:
+ switch (opcode) {
+ case TXS:
+ break;
+ case PHB:
+ case PHP:
+ case PHA:
+ case PHY:
+ case PHX:
+ case PLB:
+ case PLP:
+ case PLA:
+ case PLY:
+ case PLX:
+ case STT:
+ case LSL:
+ case LSR:
+ case ROL:
+ case ROR:
+ case ASR:
+ case ENT:
+ address = cpu->pc[thread];
+ ++cpu->pc[thread];
+ break;
+ default:
+ address = cpu->pc[thread];
+ cpu->pc[thread]+=(1 << (prefix >> 4));
+ break;
+ }
+ break;
+ case ZM:
+ case ZMX:
+ case ZMY:
+ case IND:
+ case INDX:
+ case INDY:
+ tmp = 0;
+ address = addr[cpu->pc[thread]];
+ /* Unroll Loop by implementing Duff's Device. */
+ switch ((prefix & 0x0C) >> 2) {
+ case 2:
+ address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;++tmp;
+ address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;++tmp;
+ case 3:
+ address |= addr[cpu->pc[thread]+3] << 24;++tmp;
+ case 1:
+ address |= addr[cpu->pc[thread]+2] << 16;++tmp;
+ address |= addr[cpu->pc[thread]+1] << 8;++tmp;
+ case 0:
+ ++tmp;
+ }
+ cpu->pc[thread]+=tmp;
+ #if debug && !bench
+ *tmpaddr = address;
+ #endif
+ #if getclk
+ iclk++;
+ #endif
+ uint64_t reg = 0;
+ switch (optype[opcode]) {
+ case ZMX:
+ address += cpu->x[thread];
+ #if getclk
+ iclk++;
+ #endif
+ break;
+ case ZMY:
+ address += cpu->y[thread];
+ #if getclk
+ iclk++;
+ #endif
+ break;
+ case INDX:
+ address += cpu->x[thread];
+ #if getclk
+ iclk++;
+ #endif
+ /* Falls Through. */
+ case INDY:
+ /* Did we fall through? */
+ if (optype[opcode] == INDX) {
+ reg = 0; /* Yes, so set reg back to zero. */
+ } else {
+ reg = cpu->y[thread]; /* No, so set reg to Y. */
+ #if getclk
+ iclk++;
+ #endif
+ }
+ /* Falls Through. */
+ case IND:
+ value = addr[address];
+ value |= addr[address+1] << 8;
+ value |= addr[address+2] << 16;
+ value |= addr[address+3] << 24;
+ value |= (uint64_t)addr[address+4] << 32;
+ value |= (uint64_t)addr[address+5] << 40;
+ value |= (uint64_t)addr[address+6] << 48;
+ value |= (uint64_t)addr[address+7] << 56;
+ #if getclk
+ iclk++;
+ #endif
+ value += reg;
+ address = value;
+ value = 0;
+ reg = 0;
+ break;
+ }
+ break;
+ case ABS:
+ tmp = 0;
+ address = addr[cpu->pc[thread]];++tmp;
+ /* Unroll Loop by implementing Duff's Device. */
+ switch ((prefix & 0x0C) >> 2) {
+ case 3:
+ address |= (uint64_t)addr[cpu->pc[thread]+7] << 56;++tmp;
+ case 2:
+ address |= (uint64_t)addr[cpu->pc[thread]+6] << 48;++tmp;
+ address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;++tmp;
+ #if getclk
+ iclk++;
+ #endif
+ case 1:
+ address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;++tmp;
+ address |= addr[cpu->pc[thread]+3] << 24;++tmp;
+ address |= addr[cpu->pc[thread]+2] << 16;++tmp;
+ case 0:
+ address |= addr[cpu->pc[thread]+1] << 8;++tmp;
+ }
+ cpu->pc[thread]+=tmp;
+ break;
+
+ }
+ return address;
+}
+
+inline void adc(struct sux *cpu, uint64_t value, uint8_t thread) {
+ uint64_t sum = cpu->a[thread]+value+getflag(C);
+ setflag(sum == 0, Z);
+ setflag((sum >> 63), N);
+ setflag(((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
+ setflag((sum < value), C);
+ cpu->a[thread] = sum;
+}
+inline void sbc(struct sux *cpu, uint64_t value, uint8_t thread) {
+ uint64_t sum = cpu->a[thread]-value-!getflag(C);
+ setflag(sum == 0, Z);
+ setflag(sum >> 63, N);
+ setflag(((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
+ setflag((sum > value), C);
+ cpu->a[thread] = sum;
+}
+
+inline void transfer(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t prefix, uint8_t thread) {
+ uint64_t reg;
+ switch (opcode) {
+ case TBA: cpu->a[thread] = cpu->b[thread]; reg = cpu->a[thread]; break;
+ case TXA: cpu->a[thread] = cpu->x[thread]; reg = cpu->a[thread]; break;
+ case TYA: cpu->a[thread] = cpu->y[thread]; reg = cpu->a[thread]; break;
+ case TAB: cpu->b[thread] = cpu->a[thread]; reg = cpu->b[thread]; break;
+ case TAY: cpu->y[thread] = cpu->a[thread]; reg = cpu->y[thread]; break;
+ case TXY: cpu->y[thread] = cpu->x[thread]; reg = cpu->y[thread]; break;
+ case TAX: cpu->x[thread] = cpu->a[thread]; reg = cpu->x[thread]; break;
+ case TYX: cpu->x[thread] = cpu->y[thread]; reg = cpu->x[thread]; break;
+ case TSX: cpu->x[thread] = cpu->sp[thread] & 0xFFFF; cpu->x[thread] = cpu->stk_st[thread] << 16; break;
+ case TXS: cpu->sp[thread] = cpu->x[thread];
+ if (prefix == 0x13 && (value == thread+1 || value > 8)) {
+ cpu->stk_st[thread] = value & 0xFF;
+ cpu->stk_st[thread] += value << 16;
+ cpu->pc[thread]+=2;
+ }
+ break;
+ }
+ setflag(reg == 0, Z);
+ setflag(reg >> 63, N);
+}
+
+inline void push(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) {
+ union {
+ uint64_t reg;
+ uint8_t byte[8];
+ } r;
+ r.reg = 0;
+ uint8_t size = ((int8_t)value >= 0) ? value-1 : 0;
+ uint8_t tmp = (size <= 7) ? size : 7;
+ switch (opcode) {
+ case PHA: r.reg = cpu->a[thread]; break;
+ case PHB: r.reg = cpu->b[thread]; break;
+ case PHX: r.reg = cpu->x[thread]; break;
+ case PHY: r.reg = cpu->y[thread]; break;
+ case PHP: r.reg = cpu->ps; break;
+ }
+ /* Unroll Loop by implementing Duff's Device. */
+ switch (tmp) {
+ case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = r.byte[7];cpu->sp[thread]--;
+ case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = r.byte[6];cpu->sp[thread]--;
+ case 5: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = r.byte[5];cpu->sp[thread]--;
+ case 4: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = r.byte[4];cpu->sp[thread]--;
+ case 3: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = r.byte[3];cpu->sp[thread]--;
+ case 2: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = r.byte[2];cpu->sp[thread]--;
+ case 1: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = r.byte[1];cpu->sp[thread]--;
+ case 0: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = r.byte[0];cpu->sp[thread]--;
+ }
+}
+
+inline void pull(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) {
+ union {
+ uint64_t reg;
+ uint8_t byte[8];
+ } r;
+ r.reg = 0;
+ uint8_t size = ((int8_t)value >= 0) ? value-1 : 0;
+ uint8_t tmp = (size <= 7) ? size : 7;
+ uint8_t tmp2 = 0;
+ /* Unroll Loop by implementing Duff's Device. */
+ cpu->sp[thread]++;r.byte[tmp2] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]];
+ switch (tmp) {
+ case 7: cpu->sp[thread]++;tmp2++;r.byte[tmp2] |= addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]];
+ case 6: cpu->sp[thread]++;tmp2++;r.byte[tmp2] |= addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]];
+ case 5: cpu->sp[thread]++;tmp2++;r.byte[tmp2] |= addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]];
+ case 4: cpu->sp[thread]++;tmp2++;r.byte[tmp2] |= addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]];
+ case 3: cpu->sp[thread]++;tmp2++;r.byte[tmp2] |= addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]];
+ case 2: cpu->sp[thread]++;tmp2++;r.byte[tmp2] |= addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]];
+ case 1: cpu->sp[thread]++;tmp2++;r.byte[tmp2] |= addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]];
+ }
+ switch (opcode) {
+ case PLA: cpu->a[thread] = r.reg; break;
+ case PLB: cpu->b[thread] = r.reg; break;
+ case PLX: cpu->x[thread] = r.reg; break;
+ case PLY: cpu->y[thread] = r.reg; break;
+ case PLP: cpu->ps = r.reg; break;
+ }
+}
+
+inline void and(struct sux *cpu, uint64_t value, uint8_t thread) {
+ cpu->a[thread] &= value;
+ setflag(cpu->a[thread] == 0, Z);
+ setflag(cpu->a[thread] >> 63, N);
+}
+inline void or(struct sux *cpu, uint64_t value, uint8_t thread) {
+ cpu->a[thread] |= value;
+ setflag(cpu->a[thread] == 0, Z);
+ setflag(cpu->a[thread] >> 63, N);
+}
+inline void xor(struct sux *cpu, uint64_t value, uint8_t thread) {
+ cpu->a[thread] ^= value;
+ setflag(cpu->a[thread] == 0, Z);
+ setflag(cpu->a[thread] >> 63, N);
+}
+
+inline void lsl(struct sux *cpu, uint64_t value, uint8_t thread) {
+ uint64_t sum = (value < 64) ? cpu->a[thread] << value : 0;
+ setflag(sum == 0, Z);
+ setflag(sum >> 63, N);
+ setflag(cpu->a[thread] >> (64-value), C);
+ cpu->a[thread] = sum;
+}
+
+inline void lsr(struct sux *cpu, uint64_t value, uint8_t thread) {
+ uint64_t sum = (value < 64) ? cpu->a[thread] >> value : 0;
+ setflag(sum == 0, Z);
+ setflag(sum >> 63, N);
+ setflag(cpu->a[thread] & 1, C);
+ cpu->a[thread] = sum;
+}
+
+inline void asr(struct sux *cpu, uint64_t value, uint8_t thread) {
+ uint8_t sign = cpu->a[thread] >> 63;
+ uint64_t sum = (value < 64) ? (cpu->a[thread] >> value) | ((uint64_t)sign << 63) : 0;
+ setflag(sum == 0, Z);
+ setflag(sum >> 63, N);
+ setflag(cpu->a[thread] & 1, C);
+ cpu->a[thread] = sum;
+}
+
+inline void rol(struct sux *cpu, uint64_t value, uint8_t thread) {
+ uint64_t sum = cpu->a[thread] << value;
+ sum |= getflag(C);
+ setflag(sum == 0, Z);
+ setflag(sum >> 63, N);
+ setflag(cpu->a[thread] >> (uint64_t)(64-value), C);
+ cpu->a[thread] = sum;
+}
+
+inline void ror(struct sux *cpu, uint64_t value, uint8_t thread) {
+ uint64_t sum = cpu->a[thread] >> value;
+ sum |= (uint64_t)getflag(C) << (uint64_t)(64-value);
+ setflag(sum == 0, Z);
+ setflag(sum >> 63, N);
+ setflag(cpu->a[thread] & 1, C);
+ cpu->a[thread] = sum;
+}
+inline void mul(struct sux *cpu, uint64_t value, uint8_t thread) {
+ uint64_t sum = cpu->a[thread]*value;
+ cpu->a[thread] = sum;
+ setflag(sum == 0, Z);
+ setflag(sum >> 63, N);
+ setflag(!((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
+}
+
+inline void divd(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) {
+ uint64_t sum = cpu->a[thread]/value;
+ if (opcode != DAB) {
+ cpu->b[thread] = cpu->a[thread] % value;
+ } else {
+ value = cpu->b[thread];
+ cpu->x[thread] = cpu->a[thread] % value;
+ }
+ cpu->a[thread] = sum;
+ setflag(sum == 0, Z);
+ setflag((sum >> 63), N);
+}
+inline void cmp(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) {
+ uint64_t reg;
+ switch (opcode) {
+ case CPB:
+ case CPB_AB:
+ case CPB_Z:
+ case CPB_IN:
+ case CPB_IX:
+ case CPB_IY:
+ reg = cpu->b[thread];
+ break;
+ case CMP:
+ case CAB:
+ case CMP_AB:
+ case CMP_Z:
+ case CMP_IN:
+ case CMP_IX:
+ case CMP_IY:
+ reg = cpu->a[thread];
+ break;
+ case CPY:
+ case CPY_AB:
+ case CPY_Z:
+ case CPY_IN:
+ reg = cpu->y[thread];
+ break;
+
+ case CPX:
+ case CPX_AB:
+ case CPX_Z:
+ case CPX_IN:
+ reg = cpu->x[thread];
+ break;
+ }
+ uint64_t sum = reg-value;
+ setflag(sum >> 63, N);
+ setflag(((reg^value) >> 63) && ((reg^sum) >> 63), V);
+ setflag(sum == 0, Z);
+ setflag(reg >= value, C);
+}
+
+inline void incr(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) {
+ uint64_t reg;
+ switch (opcode) {
+ case INC: cpu->a[thread]+=1; reg = cpu->a[thread]; break;
+ case INB: cpu->b[thread]+=1; reg = cpu->b[thread]; break;
+ case INY: cpu->y[thread]+=1; reg = cpu->y[thread]; break;
+ case INX: cpu->x[thread]+=1; reg = cpu->x[thread]; break;
+ }
+ setflag(reg == 0, Z);
+ setflag(reg >> 63, N);
+}
+
+inline void decr(struct sux *cpu, uint64_t value, uint8_t opcode, uint8_t thread) {
+ uint64_t reg;
+ switch (opcode) {
+ case DEC: cpu->a[thread]-=1; reg = cpu->a[thread]; break;
+ case DEB: cpu->b[thread]-=1; reg = cpu->b[thread]; break;
+ case DEY: cpu->y[thread]-=1; reg = cpu->y[thread]; break;
+ case DEX: cpu->x[thread]-=1; reg = cpu->x[thread]; break;
+ }
+ setflag(reg == 0, Z);
+ setflag(reg >> 63, N);
+}
+
+inline void incm(struct sux *cpu, uint64_t address, uint8_t thread) {
+ addr[address]++;
+ setflag(addr[address] == 0, Z);
+ setflag(addr[address] >> 7, N);
+}
+
+inline void decm(struct sux *cpu, uint64_t address, uint8_t thread) {
+ addr[address]--;
+ setflag(addr[address] == 0, Z);
+ setflag(addr[address] >> 7, N);
+}
+
+inline void load(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcode, uint8_t prefix, uint8_t thread) {
+ if (address == CTRL_ADDR) {
+ io(address, esc);
+ }
+ uint64_t value = addr[address];
+ /* Unroll Loop by implementing Duff's Device. */
+ switch (1 << (prefix >> 4)) {
+ case 8:
+ value |= (uint64_t)addr[address+7] << 56;
+ value |= (uint64_t)addr[address+6] << 48;
+ value |= (uint64_t)addr[address+5] << 40;
+ value |= (uint64_t)addr[address+4] << 32;
+ case 4:
+ value |= addr[address+3] << 24;
+ value |= addr[address+2] << 16;
+ case 2:
+ value |= addr[address+1] << 8;
+ }
+ switch (opcode) {
+ case LDB:
+ case LDB_AB:
+ case LDB_Z:
+ case LDB_ZX:
+ case LDB_ZY:
+ case LDB_IN:
+ case LDB_IX:
+ case LDB_IY:
+ cpu->b[thread] = value;
+ break;
+ case LDA:
+ case LDA_AB:
+ case LDA_Z:
+ case LDA_ZX:
+ case LDA_ZY:
+ case LDA_IN:
+ case LDA_IX:
+ case LDA_IY:
+ cpu->a[thread] = value;
+ break;
+ case LDY:
+ case LDY_AB:
+ case LDY_Z:
+ case LDY_ZX:
+ case LDY_IN:
+ cpu->y[thread] = value;
+ break;
+
+ case LDX:
+ case LDX_AB:
+ case LDX_Z:
+ case LDX_ZY:
+ case LDX_IN:
+ cpu->x[thread] = value;
+ break;
+ }
+ setflag(value == 0, Z);
+ setflag(value >> 63, N);
+}
+
+inline void store(struct sux *cpu, uint64_t address, uint8_t *esc, uint8_t opcode, uint8_t prefix, uint8_t thread) {
+ uint64_t value;
+ switch (opcode) {
+ case STB:
+ case STB_Z:
+ case STB_ZX:
+ case STB_ZY:
+ case STB_IN:
+ case STB_IX:
+ case STB_IY:
+ value = cpu->b[thread];
+ break;
+ case STA:
+ case STA_Z:
+ case STA_ZX:
+ case STA_ZY:
+ case STA_IN:
+ case STA_IX:
+ case STA_IY:
+ value = cpu->a[thread];
+ break;
+ case STY:
+ case STY_Z:
+ case STY_ZX:
+ case STY_IN:
+ value = cpu->y[thread];
+ break;
+
+ case STX:
+ case STX_Z:
+ case STX_ZY:
+ case STX_IN:
+ value = cpu->x[thread];
+ break;
+ }
+ addr[address] = value & 0xFF;
+ #if (IO || debug) && !branch
+ #if keypoll
+ pthread_mutex_lock(&mutex);
+ #endif
+ if (address != CTRL_ADDR && address == TX_ADDR) {
+ io(address, esc);
+ }
+ #if keypoll
+ pthread_mutex_unlock(&mutex);
+ #endif
+ #endif
+ /* Unroll Loop by implementing Duff's Device. */
+ switch (1 << (prefix >> 4)) {
+ case 8:
+ addr[address+7] = value >> 56;
+ addr[address+6] = value >> 48;
+ addr[address+5] = value >> 40;
+ addr[address+4] = value >> 32;
+ case 4:
+ addr[address+3] = value >> 24;
+ addr[address+2] = value >> 16;
+ case 2:
+ addr[address+1] = value >> 8;
+ }
+}
+