summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sux.c387
1 files changed, 255 insertions, 132 deletions
diff --git a/sux.c b/sux.c
index c4c83ee..5764807 100644
--- a/sux.c
+++ b/sux.c
@@ -22,6 +22,14 @@
#define CURSES_BACKSPACE 0x7F
#define setflag(flag, bit) (flag) ? (cpu->ps |= (bit << (thread << 3))) : (cpu->ps &= ~(bit << (thread << 3)))
+#define clearflags(thread) {\
+ cpu->c[thread] = 0;\
+ cpu->z[thread] = 0;\
+ cpu->i[thread] = 0;\
+ cpu->s[thread] = 0;\
+ cpu->v[thread] = 0;\
+ cpu->n[thread] = 0;\
+}
uint64_t clk[THREADS]; /* Per Thread Clock cycles. */
uint64_t tclk; /* Total Clock cycles. */
@@ -65,6 +73,10 @@ void *run(void *args) {
uint64_t iclk = 0;
uint64_t ins = 0;
uint64_t sign = 0;
+ uint8_t addrsize;
+ uint8_t rs;
+ uint8_t regsize;
+ uint8_t tmp;
char *s = malloc(2048);
#if !bench
uint8_t lines = (6*thread)+2;
@@ -130,10 +142,9 @@ void *run(void *args) {
#endif
#endif
- uint8_t addrsize = (prefix & 8) == 8;
- uint8_t rs = (prefix & 0x30) >> 4;
- uint8_t regsize = (1 << rs);
- uint8_t tmp;
+ addrsize = (prefix & 8) == 8;
+ rs = (prefix & 0x30) >> 4;
+ regsize = (1 << rs);
address = cpu->pc[thread];
cpu->pc[thread]++;
iclk++;
@@ -184,10 +195,17 @@ void *run(void *args) {
cpu->pc[thread]+=1;
}
tmpaddr = address;
- if (optype[opcode] == ZMX)
- address += cpu->x[thread];
- if (optype[opcode] == ZMY)
- address += cpu->y[thread];
+ switch (optype[opcode]) {
+ case ZMX:
+ address += cpu->x[thread];
+ iclk++;
+ break;
+ case ZMY:
+ address += cpu->y[thread];
+ iclk++;
+ break;
+ }
+ iclk++;
break;
case IND:
case INDX:
@@ -201,19 +219,25 @@ void *run(void *args) {
} else {
cpu->pc[thread]+=1;
}
+ iclk++;
tmpaddr = address;
- if (optype[opcode] == INDX)
+ if (optype[opcode] == INDX) {
address += cpu->x[thread];
- value = (uint64_t)addr[address]
- | (uint64_t)addr[address+1] << 8
- | (uint64_t)addr[address+2] << 16
- | (uint64_t)addr[address+3] << 24
- | (uint64_t)addr[address+4] << 32
- | (uint64_t)addr[address+5] << 40
- | (uint64_t)addr[address+6] << 48
- | (uint64_t)addr[address+7] << 56;
- if (optype[opcode] == INDY)
+ iclk++;
+ }
+ 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;
+ iclk++;
+ if (optype[opcode] == INDY) {
value += cpu->y[thread];
+ iclk++;
+ }
address = value;
value = 0;
iclk++;
@@ -222,8 +246,8 @@ void *run(void *args) {
address = addr[cpu->pc[thread]];
address |= addr[cpu->pc[thread]+1] << 8;
if (addrsize) {
- address |= (uint64_t)addr[cpu->pc[thread]+2] << 16;
- address |= (uint64_t)addr[cpu->pc[thread]+3] << 24;
+ address |= addr[cpu->pc[thread]+2] << 16;
+ address |= addr[cpu->pc[thread]+3] << 24;
address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;
address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;
address |= (uint64_t)addr[cpu->pc[thread]+6] << 48;
@@ -233,7 +257,7 @@ void *run(void *args) {
} else {
cpu->pc[thread]+=2;
}
-
+ iclk++;
break;
}
@@ -243,12 +267,13 @@ void *run(void *args) {
if (regsize >= 4) {
value |= addr[address+2] << 16;
value |= addr[address+3] << 24;
- }
- if (regsize >= 8) {
- 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 (regsize >= 8) {
+ 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 debug && !bench
@@ -271,9 +296,9 @@ void *run(void *args) {
postfix[0] = '.';
if (regsize == 2)
postfix[1] = 'W';
- if (regsize == 4)
+ else if (regsize == 4)
postfix[1] = 'D';
- if (regsize == 8)
+ else if (regsize == 8)
postfix[1] = 'Q';
postfix[2] = '\0';
}
@@ -284,14 +309,11 @@ void *run(void *args) {
case IMM:
if (regsize == 1) {
mvwprintw(scr, lines, col, "%s #$%02x \r" , op, value);
- }
- if (regsize == 2) {
+ } else if (regsize == 2) {
mvwprintw(scr, lines, col, "%s%s #$%04x \r" , op, postfix, value);
- }
- if (regsize == 4) {
+ } else if (regsize == 4) {
mvwprintw(scr, lines, col, "%s%s #$%08x \r" , op, postfix, value);
- }
- if (regsize == 8) {
+ } else if (regsize == 8) {
mvwprintw(scr, lines, col, "%s%s #$%016llx\r" , op, postfix, value);
}
break;
@@ -300,7 +322,7 @@ void *run(void *args) {
case ZMY:
if (optype[opcode] == ZMX)
tmpaddr = address - cpu->x[thread];
- if (optype[opcode] == ZMY)
+ else if (optype[opcode] == ZMY)
tmpaddr = address - cpu->y[thread];
if (addrsize)
mvwprintw(scr, lines, col, "%s%s $%08x%s \r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y"));
@@ -370,14 +392,14 @@ void *run(void *args) {
#endif
switch(opcode) {
case CPS: /* Clear Processor Status. */
- for (uint8_t i = 0; i < 8; i++) {
- cpu->c[i] = 0;
- cpu->z[i] = 0;
- cpu->i[i] = 0;
- cpu->s[i] = 0;
- cpu->v[i] = 0;
- cpu->n[i] = 0;
- }
+ clearflags(0);
+ clearflags(1);
+ clearflags(2);
+ clearflags(3);
+ clearflags(4);
+ clearflags(5);
+ clearflags(6);
+ clearflags(7);
cpu->ps &= 0;
break;
case ADC: /* ADC Immediate. */
@@ -436,48 +458,63 @@ void *run(void *args) {
case TSX: /* Transfer Stack pointer to X. */
case TBA: /* Transfer B to Accumulator. */
case TXS: /* Transfer X to Stack pointer. */
- if (opcode == TAY)
- cpu->y[thread] = cpu->a[thread];
- else if (opcode == TAX)
- cpu->x[thread] = cpu->a[thread];
- else if (opcode == TYX)
- cpu->x[thread] = cpu->y[thread];
- else if (opcode == TYA)
- cpu->a[thread] = cpu->y[thread];
- else if (opcode == TXA)
- cpu->a[thread] = cpu->x[thread];
- else if (opcode == TXY)
- cpu->y[thread] = cpu->x[thread];
- else if (opcode == TAB) {
- cpu->b[thread] = cpu->a[thread];
- cpu->z[thread] = (cpu->b[thread] == 0);
- cpu->n[thread] = (cpu->b[thread] >> 63);
- }
- else if (opcode == TSX) {
- cpu->x[thread] = cpu->sp[thread] & 0xFFFF;
- cpu->x[thread] = cpu->stk_st[thread] << 16;
- }
- else if (opcode == TBA)
- cpu->a[thread] = cpu->b[thread];
- else if (opcode == TXS) {
- cpu->sp[thread] = cpu->x[thread];
- if (prefix == 0x17 && (value == thread+1 || value > 8)) {
- cpu->stk_st[thread] = value & 0xFF;
- cpu->stk_st[thread] += value << 16;
- cpu->pc[thread]+=2;
- }
- }
- if (opcode == TYA || opcode == TXA || opcode == TBA) {
- cpu->z[thread] = (cpu->a[thread] == 0);
- cpu->n[thread] = (cpu->a[thread] >> 63);
- }
- else if (opcode == TAY || opcode == TXY) {
- cpu->z[thread] = (cpu->y[thread] == 0);
- cpu->n[thread] = (cpu->y[thread] >> 63);
+ switch (opcode) {
+ case TAY:
+ cpu->y[thread] = cpu->a[thread];
+ break;
+ case TAX:
+ cpu->x[thread] = cpu->a[thread];
+ break;
+ case TYX:
+ cpu->x[thread] = cpu->y[thread];
+ break;
+ case TYA:
+ cpu->a[thread] = cpu->y[thread];
+ break;
+ case TXA:
+ cpu->a[thread] = cpu->x[thread];
+ break;
+ case TXY:
+ cpu->y[thread] = cpu->x[thread];
+ break;
+ case TAB:
+ cpu->b[thread] = cpu->a[thread];
+ cpu->z[thread] = (cpu->b[thread] == 0);
+ cpu->n[thread] = (cpu->b[thread] >> 63);
+ break;
+ case TSX:
+ cpu->x[thread] = cpu->sp[thread] & 0xFFFF;
+ cpu->x[thread] = cpu->stk_st[thread] << 16;
+ break;
+ case TBA:
+ cpu->a[thread] = cpu->b[thread];
+ break;
+ case TXS:
+ cpu->sp[thread] = cpu->x[thread];
+ if (prefix == 0x17 && (value == thread+1 || value > 8)) {
+ cpu->stk_st[thread] = value & 0xFF;
+ cpu->stk_st[thread] += value << 16;
+ cpu->pc[thread]+=2;
+ }
+ break;
}
- else if (opcode == TAX || opcode == TYX) {
- cpu->z[thread] = (cpu->x[thread] == 0);
- cpu->n[thread] = (cpu->x[thread] >> 63);
+ switch (opcode) {
+ case TYA:
+ case TXA:
+ case TBA:
+ cpu->z[thread] = (cpu->a[thread] == 0);
+ cpu->n[thread] = (cpu->a[thread] >> 63);
+ break;
+ case TAY:
+ case TXY:
+ cpu->z[thread] = (cpu->y[thread] == 0);
+ cpu->n[thread] = (cpu->y[thread] >> 63);
+ break;
+ case TAX:
+ case TYX:
+ cpu->z[thread] = (cpu->x[thread] == 0);
+ cpu->n[thread] = (cpu->x[thread] >> 63);
+ break;
}
setflag(cpu->z[thread], Z);
setflag(cpu->n[thread], N);
@@ -680,14 +717,41 @@ void *run(void *args) {
case 0xCE: /* STB Indexed Indirect. */
case 0xE9: /* STA Indirect Indexed. */
case 0xEE: /* STB Indirect Indexed. */
- if (opcode == STA || opcode == 0x49 || opcode == 0x69 || opcode == 0x89 || opcode == 0xA9 || opcode == 0xC9 || opcode == 0xE9)
- value = cpu->a[thread];
- if (opcode == STY || opcode == 0x4A || opcode == 0x6A || opcode == 0x8A || opcode == 0xAA)
- value = cpu->y[thread];
- if (opcode == STY || opcode == 0x4B || opcode == 0x6B || opcode == 0x8B || opcode == 0xAB)
- value = cpu->x[thread];
- if (opcode == STB || opcode == 0x4E || opcode == 0x6E || opcode == 0x8E || opcode == 0xAE || opcode == 0xCE || opcode == 0xEE)
- value = cpu->b[thread];
+ switch (opcode) {
+ case STB:
+ case 0x4E:
+ case 0x6E:
+ case 0x8E:
+ case 0xAE:
+ case 0xCE:
+ case 0xEE:
+ value = cpu->b[thread];
+ break;
+ case STA:
+ case 0x49:
+ case 0x69:
+ case 0x89:
+ case 0xA9:
+ case 0xC9:
+ case 0xE9:
+ value = cpu->a[thread];
+ break;
+ case STY:
+ case 0x4A:
+ case 0x6A:
+ case 0x8A:
+ case 0xAA:
+ value = cpu->y[thread];
+ break;
+
+ case STX:
+ case 0x4B:
+ case 0x6B:
+ case 0x8B:
+ case 0xAB:
+ value = cpu->x[thread];
+ break;
+ }
addr[address] = value & 0xFF;
if (address == STEP_ADDR) {
step = addr[address];
@@ -877,17 +941,18 @@ void *run(void *args) {
}
#endif
#endif
- if (regsize >= 2)
+ if (regsize >= 2) {
addr[address+1] = value >> 8;
- if (regsize >= 4) {
- addr[address+2] = value >> 16;
- addr[address+3] = value >> 24;
- }
- if (regsize >= 8) {
- addr[address+4] = value >> 32;
- addr[address+5] = value >> 40;
- addr[address+6] = value >> 48;
- addr[address+7] = value >> 56;
+ if (regsize >= 4) {
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ if (regsize >= 8) {
+ addr[address+4] = value >> 32;
+ addr[address+5] = value >> 40;
+ addr[address+6] = value >> 48;
+ addr[address+7] = value >> 56;
+ }
+ }
}
break;
case BCC: /* BCC Absolute. */
@@ -972,26 +1037,58 @@ void *run(void *args) {
kbd_rdy = 0;
}
value = addr[address];
- if (regsize >= 2)
+ if (regsize >= 2) {
value += addr[address+1] << 8;
- if (regsize >= 4) {
- value += addr[address+2] << 16;
- value += addr[address+3] << 24;
+ if (regsize >= 4) {
+ value += addr[address+2] << 16;
+ value += addr[address+3] << 24;
+ if (regsize >= 8) {
+ 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 (regsize >= 8) {
- 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;
+ switch (opcode) {
+ case LDB:
+ case 0x1E:
+ case 0x3E:
+ case 0x5E:
+ case 0x7E:
+ case 0x9E:
+ case 0xBE:
+ case 0xDE:
+ cpu->b[thread] = value;
+ break;
+ case LDA:
+ case 0x19:
+ case 0x39:
+ case 0x59:
+ case 0x79:
+ case 0x99:
+ case 0xB9:
+ case 0xD9:
+ cpu->a[thread] = value;
+ break;
+ case LDY:
+ case 0x1A:
+ case 0x3A:
+ case 0x5A:
+ case 0x7A:
+ case 0x9A:
+ cpu->y[thread] = value;
+ break;
+
+ case LDX:
+ case 0x1B:
+ case 0x3B:
+ case 0x5B:
+ case 0x7B:
+ case 0x9B:
+ cpu->x[thread] = value;
+ break;
}
- if (opcode == LDB || opcode == 0x1E || opcode == 0x3E || opcode == 0x5E || opcode == 0x7E || opcode == 0x9E || opcode == 0xBE || opcode == 0xDE)
- cpu->b[thread] = value;
- if (opcode == LDA || opcode == 0x19 || opcode == 0x39 || opcode == 0x59 || opcode == 0x79 || opcode == 0x99 || opcode == 0xB9 || opcode == 0xD9)
- cpu->a[thread] = value;
- if (opcode == LDY || opcode == 0x1A || opcode == 0x3A || opcode == 0x5A || opcode == 0x7A || opcode == 0x9A)
- cpu->y[thread] = value;
- if (opcode == LDX || opcode == 0x1B || opcode == 0x3B || opcode == 0x5B || opcode == 0x7B || opcode == 0x9B)
- cpu->x[thread] = value;
cpu->z[thread] = (value == 0);
cpu->n[thread] = (value >> 63);
setflag(cpu->z[thread], Z);
@@ -1141,14 +1238,40 @@ void *run(void *args) {
if (opcode == CAB) {
value = cpu->b[thread];
}
- if (opcode == CPB || opcode == 0x36 || opcode == 0x46 || opcode == 0x56 || opcode == 0x66 || opcode == 0x76)
- reg = cpu->b[thread];
- if (opcode == CMP || opcode == CAB || opcode == 0xB3 || opcode == 0xB5 || opcode == 0xF1 || opcode == 0xF3 || opcode == 0xF5)
- reg = cpu->a[thread];
- if (opcode == CPY || opcode == 0xCA || opcode == 0xDA || opcode == 0xEA || opcode == 0xFA)
- reg = cpu->y[thread];
- if (opcode == CPX || opcode == 0xCB || opcode == 0xDB || opcode == 0xEB || opcode == 0xFB)
- reg = cpu->x[thread];
+ switch (opcode) {
+ case CPB:
+ case 0x36:
+ case 0x46:
+ case 0x56:
+ case 0x66:
+ case 0x76:
+ reg = cpu->b[thread];
+ break;
+ case CMP:
+ case CAB:
+ case 0xB3:
+ case 0xB5:
+ case 0xF1:
+ case 0xF3:
+ case 0xF5:
+ reg = cpu->a[thread];
+ break;
+ case CPY:
+ case 0xCA:
+ case 0xDA:
+ case 0xEA:
+ case 0xFA:
+ reg = cpu->y[thread];
+ break;
+
+ case LDX:
+ case 0xCB:
+ case 0xDB:
+ case 0xEB:
+ case 0xFB:
+ reg = cpu->x[thread];
+ break;
+ }
sum = reg-value;
cpu->n[thread] = (sum & 0x8000000000000000);
cpu->v[thread] = ((reg^value) & 0x8000000000000000) && ((reg^sum) & 0x8000000000000000);
@@ -1187,12 +1310,12 @@ void *run(void *args) {
cpu->z[thread] = (cpu->a[thread] == 0);
cpu->n[thread] = (cpu->a[thread] >> 63);
}
- if (opcode == INY) {
+ else if (opcode == INY) {
cpu->y[thread]+=1;
cpu->z[thread] = (cpu->y[thread] == 0);
cpu->n[thread] = (cpu->y[thread] >> 63);
}
- if (opcode == INX) {
+ else if (opcode == INX) {
cpu->x[thread]+=1;
cpu->z[thread] = (cpu->x[thread] == 0);
cpu->n[thread] = (cpu->x[thread] >> 63);
@@ -1218,12 +1341,12 @@ void *run(void *args) {
cpu->z[thread] = (cpu->a[thread] == 0);
cpu->n[thread] = (cpu->a[thread] >> 63);
}
- if (opcode == DEY) {
+ else if (opcode == DEY) {
cpu->y[thread]-=1;
cpu->z[thread] = (cpu->y[thread] == 0);
cpu->n[thread] = (cpu->y[thread] >> 63);
}
- if (opcode == DEX) {
+ else if (opcode == DEX) {
cpu->x[thread]-=1;
cpu->z[thread] = (cpu->x[thread] == 0);
cpu->n[thread] = (cpu->x[thread] >> 63);