summaryrefslogtreecommitdiff
path: root/sux.c
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2020-04-09 02:06:50 -0400
committermrb0nk500 <b0nk@b0nk.xyz>2020-04-09 02:06:50 -0400
commitc5150ee31f07208422f1435de9b35a0d0168cbb5 (patch)
tree78150bf0339cf81401c00973f96c94a3c231015e /sux.c
parent59dc46ca8fe1eb6f98abb98fe8579aeaedd2ff15 (diff)
Completely changed the assembler.
It now has a lexer/tokenizer, along with a parser. I have also made the emulator even smaller.
Diffstat (limited to 'sux.c')
-rw-r--r--sux.c568
1 files changed, 205 insertions, 363 deletions
diff --git a/sux.c b/sux.c
index 164ca4a..6c9442f 100644
--- a/sux.c
+++ b/sux.c
@@ -4,8 +4,8 @@
#include <string.h>
#include <pthread.h>
#define bench 0
-#define debug 1
-#define IO 0
+#define debug 0
+#define IO 1
#define keypoll 0
#if bench
#include <sys/time.h>
@@ -30,10 +30,11 @@ uint64_t inst[THREADS];
uint64_t inss;
uint8_t threads_done = 0;
uint8_t kbd_rdy = 0;
-uint8_t kbd_ln = 0;
uint8_t wai = 0;
uint8_t step = 0;
uint8_t irq = 0;
+
+
#if !bench
WINDOW *scr;
#endif
@@ -41,10 +42,12 @@ 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;
+
struct suxthr {
struct sux sx;
uint8_t th;
};
+
#if bench
double ipc;
struct timeval str[THREADS], en[THREADS];
@@ -177,7 +180,6 @@ void *run(void *args) {
switch (opcode) {
case TXS:
break;
-
case PHB:
case PHP:
case PHA:
@@ -207,23 +209,31 @@ void *run(void *args) {
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 (addrsize) {
case 2:
address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;
address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;
- cpu->pc[thread]+=2;
+ tmp+=2;
case 3:
address |= addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=1;
+ tmp+=1;
case 1:
address |= addr[cpu->pc[thread]+2] << 16;
address |= addr[cpu->pc[thread]+1] << 8;
- cpu->pc[thread]+=2;
+ tmp+=2;
case 0:
- cpu->pc[thread]+=1;
+ tmp+=1;
}
+ cpu->pc[thread]+=tmp;
tmpaddr = address;
+ iclk++;
+ reg = 0;
switch (optype[opcode]) {
case ZMX:
address += cpu->x[thread];
@@ -233,75 +243,64 @@ void *run(void *args) {
address += cpu->y[thread];
iclk++;
break;
+ case INDX:
+ address += cpu->x[thread];
+ iclk++;
+ /* 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. */
+ iclk++;
+ }
+ /* 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;
+ iclk++;
+ value += reg;
+ address = value;
+ value = 0;
+ reg = 0;
+ break;
}
- iclk++;
- break;
- case IND:
- case INDX:
- case INDY:
- address = addr[cpu->pc[thread]];
- switch (addrsize) {
- case 2:
- address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;
- address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;
- cpu->pc[thread]+=2;
- case 3:
- address |= addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=1;
- case 1:
- address |= addr[cpu->pc[thread]+2] << 16;
- address |= addr[cpu->pc[thread]+1] << 8;
- cpu->pc[thread]+=2;
- case 0:
- cpu->pc[thread]+=1;
- }
- iclk++;
- tmpaddr = address;
- if (optype[opcode] == INDX) {
- address += cpu->x[thread];
- 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++;
break;
case ABS:
+ tmp = 0;
address = addr[cpu->pc[thread]];
+ /* Unroll Loop by implementing Duff's Device. */
switch (addrsize) {
case 3:
address |= (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=1;
+ tmp+=1;
case 2:
address |= (uint64_t)addr[cpu->pc[thread]+6] << 48;
address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;
- cpu->pc[thread]+=2;
+ tmp+=2;
iclk++;
case 1:
address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;
address |= addr[cpu->pc[thread]+3] << 24;
address |= addr[cpu->pc[thread]+2] << 16;
- cpu->pc[thread]+=3;
+ tmp+=3;
case 0:
address |= addr[cpu->pc[thread]+1] << 8;
- cpu->pc[thread]+=2;
+ tmp+=2;
}
+ cpu->pc[thread]+=tmp;
break;
}
value = addr[address];
+ /* Unroll Loop by implementing Duff's Device. */
switch (regsize) {
case 8:
value |= (uint64_t)addr[address+7] << 56;
@@ -324,19 +323,11 @@ void *run(void *args) {
op[1] = opname[opcode][1];
op[2] = opname[opcode][2];
op[3] = '\0';
- if (regsize == 1) {
- postfix[0] = '\0';
- postfix[1] = '\0';
- postfix[2] = '\0';
- } else {
- postfix[0] = '.';
- if (regsize == 2)
- postfix[1] = 'W';
- else if (regsize == 4)
- postfix[1] = 'D';
- else if (regsize == 8)
- postfix[1] = 'Q';
- postfix[2] = '\0';
+ switch(regsize) {
+ 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;
@@ -351,10 +342,10 @@ void *run(void *args) {
case ZM:
case ZMX:
case ZMY:
- if (optype[opcode] == ZMX)
- tmpaddr = address - cpu->x[thread];
- else if (optype[opcode] == ZMY)
- tmpaddr = address - cpu->y[thread];
+ switch (optype[opcode]) {
+ case ZMX: tmpaddr = address - cpu->x[thread]; break;
+ case ZMY: tmpaddr = address - cpu->y[thread]; break;
+ }
switch (addrsize) {
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 $%014llX%s\r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y")); break;
@@ -444,17 +435,16 @@ void *run(void *args) {
case CPS: /* Clear Processor Status. */
cpu->ps &= 0;
break;
- case ADC: /* ADC Immediate. */
case AAB: /* Add Accumulator with carry by B register. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case ADC: /* ADC Immediate. */
case ADC_AB: /* ADC Absolute. */
case ADC_Z: /* ADC Zero Matrix. */
- if (opcode == AAB)
- value = cpu->b[thread];
sum = cpu->a[thread]+value+getflag(C);
cpu->a[thread] = sum;
setflag(sum == 0, Z);
setflag((sum >> 63), N);
- setflag(((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000), V);
+ setflag(((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
setflag((sum < value), C);
break;
case PHB: /* PusH B register to stack. */
@@ -472,6 +462,7 @@ void *run(void *args) {
}
if (tmp > 7)
tmp = 7;
+ /* Unroll Loop by implementing Duff's Device. */
switch (tmp) {
case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (7<<3);
case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = reg >> (6<<3);
@@ -494,20 +485,15 @@ void *run(void *args) {
case TBA: /* Transfer B to Accumulator. */
case TXS: /* Transfer X to Stack pointer. */
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];
- setflag(cpu->b[thread] == 0, Z);
- setflag(cpu->b[thread] >> 63, N);
- 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 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;
@@ -516,41 +502,23 @@ void *run(void *args) {
}
break;
}
- switch (opcode) {
- case TYA:
- case TXA:
- case TBA:
- setflag(cpu->a[thread] == 0, Z);
- setflag(cpu->a[thread] >> 63, N);
- break;
- case TAY:
- case TXY:
- setflag(cpu->y[thread] == 0, Z);
- setflag(cpu->y[thread] >> 63, N);
- break;
- case TAX:
- case TYX:
- setflag(cpu->x[thread] == 0, Z);
- setflag(cpu->x[thread] >> 63, N);
- break;
- }
+ setflag(reg == 0, Z);
+ setflag(reg >> 63, N);
break;
case JMP: /* JMP Absolute. */
case JMP_Z: /* JMP Zero Matrix. */
case JMP_IN: /* JMP Indirect. */
cpu->pc[thread] = address;
break;
- case SBC: /* SBC Immediate. */
case SAB: /* Subtract Accumulator with carry by B register. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case SBC: /* SBC Immediate. */
case SBC_AB: /* SBC Absolute. */
case SBC_Z: /* SBC Zero Matrix. */
- if (opcode == SAB) {
- value = cpu->b[thread];
- }
sum = cpu->a[thread]-value-!getflag(C);
setflag(sum == 0, Z);
setflag(sum >> 63, N);
- setflag(((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000), V);
+ setflag(((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
setflag((sum > value), C);
cpu->a[thread] = sum;
break;
@@ -571,6 +539,7 @@ void *run(void *args) {
tmp = 7;
tmp2 = 0;
cpu->sp[thread]++;reg = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF;tmp--;
+ /* Unroll Loop by implementing Duff's Device. */
switch (tmp) {
case 6: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 5: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
@@ -580,26 +549,18 @@ void *run(void *args) {
case 1: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 0: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
}
- if (opcode == PLB) {
- cpu->b[thread] = reg;
- } else if (opcode == PLP) {
- cpu->ps = reg;
- } else if (opcode == PLA) {
- cpu->a[thread] = reg;
- } else if (opcode == PLY) {
- cpu->y[thread] = reg;
- } else if (opcode == PLX) {
- cpu->x[thread] = reg;
+ 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;
}
break;
case JSR_IN: /* JSR Indirect. */
case JSR: /* Jump to SubRoutine. */
- switch (addrsize) {
- case 3: stksize = 3; break;
- case 2: stksize = 5; break;
- case 1: stksize = 2; break;
- case 0: stksize = 0; break;
- }
+ stksize = adrsize[addrsize];
+ /* Unroll Loop by implementing Duff's Device. */
switch (stksize) {
case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (7<<3);
case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]--] = (uint64_t)cpu->pc[thread] >> (6<<3);
@@ -612,13 +573,11 @@ void *run(void *args) {
}
cpu->pc[thread] = address;
break;
- case AND: /* AND Immediate. */
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. */
- if (opcode == ABA) {
- value = cpu->b[thread];
- }
cpu->a[thread] &= value;
setflag(value == 0, Z);
setflag(value >> 63, N);
@@ -644,13 +603,11 @@ void *run(void *args) {
if (!getflag(N))
cpu->pc[thread] = address;
break;
- case ORA: /* ORA Immediate. */
case OAB: /* bitwise Or with Accumulator, and B register. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case ORA: /* ORA Immediate. */
case ORA_AB: /* ORA Absolute. */
case ORA_Z: /* ORA Zero Matrix. */
- if (opcode == OAB) {
- value = cpu->b[thread];
- }
cpu->a[thread] |= value;
setflag(value == 0, Z);
setflag(value >> 63, N);
@@ -663,13 +620,11 @@ void *run(void *args) {
if (getflag(N))
cpu->pc[thread] = address;
break;
- case XOR: /* XOR Immediate. */
case XAB: /* bitwise Xor with Accumulator, and B register. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case XOR: /* XOR Immediate. */
case XOR_AB: /* XOR Absolute. */
case XOR_Z: /* XOR Zero Matrix. */
- if (opcode == XAB) {
- value = cpu->b[thread];
- }
cpu->a[thread] ^= value;
setflag(value == 0, Z);
setflag(value >> 63, N);
@@ -682,13 +637,11 @@ void *run(void *args) {
if (getflag(C))
cpu->pc[thread] = address;
break;
- case LSL: /* LSL Immediate. */
case LLB: /* Logical shift Left accumulator by B. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case LSL: /* LSL Immediate. */
case LSL_AB: /* LSL Absolute. */
case LSL_Z: /* LSL Zero Matrix. */
- if (opcode == LLB) {
- value = cpu->b[thread];
- }
sum = (value < 64) ? cpu->a[thread] << value : 0;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
@@ -754,35 +707,43 @@ void *run(void *args) {
break;
}
addr[address] = value & 0xFF;
- #if IO
+ #if (IO || debug) && !branch
if (address == TX_ADDR) {
#if keypoll
pthread_mutex_lock(&mutex);
#endif
if (esc) {
- switch(addr[address]) {
+ 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':
@@ -796,8 +757,14 @@ void *run(void *args) {
} else {
x = ((bcd[1]*10) + bcd[0]);
}
- idx = 3;
+ #if !debug
wmove(scr, y, x);
+ #else
+ updt = 1;
+ 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;
@@ -805,11 +772,15 @@ void *run(void *args) {
esc = 0;
break;
case 'S':
+ #if !debug
wscrl(scr, -1);
+ #endif
esc = 0;
break;
case 'T':
+ #if !debug
wscrl(scr, 1);
+ #endif
esc = 0;
break;
case '0':
@@ -829,122 +800,58 @@ void *run(void *args) {
break;
}
} else {
- if (addr[address] == 0xC) {
- x=0,y=0;
- wclear(scr);
- wmove(scr, y, x);
- } else if (addr[address] == 0x15) {
- x=0;
- wclrtoeol(scr);
- wmove(scr, y, x);
- } else if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') {
- if (x > 0) {
- x--;
+ switch (addr[TX_ADDR]) {
+ case 0xC:
+ x=0,y=0;
+ #if !debug
+ wclear(scr);
wmove(scr, y, x);
- }
- wdelch(scr);
- } else if (addr[address] == '\033') {
- esc = 1;
- } else {
- wmove(scr, y, x);
- waddch(scr, addr[address]);
- if (addr[address] == '\n') {
- x = 0;
- y+=1;
- } else {
- x+=1;
- }
- }
- }
- #if keypoll
- pthread_mutex_unlock(&mutex);
- #endif
- }
- #else
- #if !bench
- if (address == TX_ADDR) {
- if (esc) {
- switch(addr[address]) {
- case 'A':
- if (y > 0)
- y--;
- esc = 0;
- break;
- case 'B':
- if (y < getmaxy(scr))
- y++;
- esc = 0;
+ #endif
break;
- case 'C':
- if (x < getmaxx(scr))
- x++;
- esc = 0;
- break;
- case 'D':
- if (x > 0)
+ case CURSES_BACKSPACE:
+ case '\b':
+ if (x > 0) {
x--;
- 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]);
- 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]);
+ #if !debug
+ wmove(scr, y, x);
+ #endif
+ }
+ #if !debug
+ wdelch(scr);
+ #else
updt = 1;
- idx = 3;
- bcd[0] = 0;
- bcd[1] = 0;
- bcd[2] = 0;
- bcd[3] = 0;
- esc = 0;
- break;
- case 'S':
- case 'T':
- esc = 0;
+ #endif
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] == ';');
+ case '\033':
+ esc = 1;
break;
- }
- } else {
- if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') {
- updt = 1;
- if (x > 0) {
- x--;
- }
- } else if (addr[address] == '\033') {
- esc = 1;
- } else {
- updt = (!addr[0x16]);
- if (addr[address] == '\n') {
+ case '\n':
+ #if !debug
+ wmove(scr, y, x);
+ waddch(scr, addr[address]);
+ #else
+ updt = (!addr[0x16]);
+ #endif
x = 0;
y+=1;
- } else {
+ break;
+ default:
+ #if !debug
+ wmove(scr, y, x);
+ waddch(scr, addr[address]);
+ #else
+ updt = (!addr[0x16]);
+ #endif
x+=1;
- }
+ break;
}
}
+ #if keypoll
+ pthread_mutex_unlock(&mutex);
+ #endif
}
#endif
- #endif
+ /* Unroll Loop by implementing Duff's Device. */
switch (regsize) {
case 8:
addr[address+7] = value >> 56;
@@ -963,26 +870,23 @@ void *run(void *args) {
if (!getflag(C))
cpu->pc[thread] = address;
break;
- case LSR: /* LSR Immediate. */
case LRB: /* Logical shift Right accumulator by B. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case LSR: /* LSR Immediate. */
case LSR_AB: /* LSR Absolute. */
case LSR_Z: /* LSR Zero Matrix. */
- if (opcode == LRB) {
- value = cpu->b[thread];
- }
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;
break;
- case ASR: /* ASR Immediate. */
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. */
- if (opcode == ARB)
- value = cpu->b[thread];
- sign = cpu->a[thread] & 0x8000000000000000;
+ sign = cpu->a[thread] >> 63;
sum = (value < 64) ? (cpu->a[thread] >> value) | sign : 0;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
@@ -1031,6 +935,7 @@ void *run(void *args) {
kbd_rdy = 0;
}
value = addr[address];
+ /* Unroll Loop by implementing Duff's Device. */
switch (regsize) {
case 8:
value |= (uint64_t)addr[address+7] << 56;
@@ -1088,13 +993,11 @@ void *run(void *args) {
if (getflag(Z))
cpu->pc[thread] = address;
break;
- case ROL: /* ROL Immediate. */
case RLB: /* Rotate Left accumulator by B. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case ROL: /* ROL Immediate. */
case ROL_AB: /* ROL Absolute. */
case ROL_Z: /* ROL Zero Matrix. */
- if (opcode == RLB) {
- value = cpu->b[thread];
- }
sum = cpu->a[thread] << value;
sum |= getflag(C);
setflag(sum == 0, Z);
@@ -1107,13 +1010,11 @@ void *run(void *args) {
if (!getflag(Z))
cpu->pc[thread] = address;
break;
- case ROR: /* ROR Immediate. */
case RRB: /* Rotate Right accumulator by B. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case ROR: /* ROR Immediate. */
case ROR_AB: /* ROR Absolute. */
case ROR_Z: /* ROR Zero Matrix. */
- if (opcode == RRB) {
- value = cpu->b[thread];
- }
sum = cpu->a[thread] >> value;
sum |= (uint64_t)getflag(C) << (uint64_t)64-value;
setflag(sum == 0, Z);
@@ -1126,18 +1027,16 @@ void *run(void *args) {
if (getflag(V))
cpu->pc[thread] = address;
break;
- case MUL: /* MUL Immediate. */
case MAB: /* Multiply Accumulator by B. */
+ value = cpu->b[thread]; /* Falls Through. */
+ case MUL: /* MUL Immediate. */
case MUL_AB: /* MUL Absolute. */
case MUL_Z: /* MUL Zero Matrix. */
- if (opcode == MAB) {
- value = cpu->b[thread];
- }
sum = cpu->a[thread]*value+getflag(C);
cpu->a[thread] = sum;
setflag(sum == 0, Z);
setflag(sum >> 63, N);
- setflag(!((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000), V);
+ setflag(!((cpu->a[thread]^value) >> 63) && ((cpu->a[thread]^sum) >> 63), V);
setflag((!((cpu->a[thread]^sum) && (cpu->a[thread]^value)) && (cpu->a[thread] >= ((uint64_t)1 << 32) && value >= ((uint64_t)1 << 32))), C);
break;
case BVC: /* BVC Absolute. */
@@ -1165,13 +1064,9 @@ void *run(void *args) {
break;
case RTS: /* ReTurn from Subroutine. */
tmp2 = 0;
- switch (addrsize) {
- case 3: stksize = 3; break;
- case 2: stksize = 5; break;
- case 1: stksize = 2; break;
- case 0: stksize = 0; break;
- }
+ stksize = adrsize[addrsize];
cpu->sp[thread]++;reg = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] & 0xFF;stksize--;
+ /* Unroll Loop by implementing Duff's Device. */
switch (stksize) {
case 4: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 3: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
@@ -1180,9 +1075,10 @@ void *run(void *args) {
case 0: cpu->sp[thread]++;tmp2++;reg += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
}
break;
+ case CAB: /* Compare Accumulator, and B. */
+ value = cpu->b[thread]; /* Falls Through. */
case CPB: /* CPB Immediate. */
case CMP: /* CMP Immediate. */
- case CAB: /* Compare Accumulator, and B. */
case CPY: /* CPY Immediate. */
case CPX: /* CPX Immediate. */
case CPY_AB: /* CPY Absolute. */
@@ -1201,9 +1097,6 @@ void *run(void *args) {
case CPB_IX: /* CPB Indexed Indirect. */
case CMP_IY: /* CMP Indirect Indexed. */
case CPB_IY: /* CPB Indirect Indexed. */
- if (opcode == CAB) {
- value = cpu->b[thread];
- }
switch (opcode) {
case CPB:
case CPB_AB:
@@ -1238,7 +1131,7 @@ void *run(void *args) {
}
sum = reg-value;
setflag(sum >> 63, N);
- setflag(((reg^value) & 0x8000000000000000) && ((reg^sum) & 0x8000000000000000), V);
+ setflag(((reg^value) >> 63) && ((reg^sum) >> 63), V);
setflag(sum == 0, Z);
setflag(reg >= value, C);
break;
@@ -1265,62 +1158,30 @@ void *run(void *args) {
case INY:
case INX:
switch (opcode) {
- case INC:
- cpu->a[thread]+=1;
- setflag(cpu->a[thread] == 0, Z);
- setflag((cpu->a[thread] >> 63), N);
- break;
- case INB:
- cpu->b[thread]+=1;
- setflag(cpu->b[thread] == 0, Z);
- setflag((cpu->b[thread] >> 63), N);
- break;
- case INY:
- cpu->y[thread]+=1;
- setflag(cpu->y[thread] == 0, Z);
- setflag((cpu->y[thread] >> 63), N);
- break;
- case INX:
- cpu->x[thread]+=1;
- setflag(cpu->x[thread] == 0, Z);
- setflag((cpu->x[thread] >> 63), N);
- break;
+ 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);
break;
case DEC: /* DEC Accumulator. */
case DEB:
case DEY:
case DEX:
switch (opcode) {
- case DEC:
- cpu->a[thread]-=1;
- setflag(cpu->a[thread] == 0, Z);
- setflag((cpu->a[thread] >> 63), N);
- break;
- case DEB:
- cpu->b[thread]-=1;
- setflag(cpu->b[thread] == 0, Z);
- setflag((cpu->b[thread] >> 63), N);
- break;
- case DEY:
- cpu->y[thread]-=1;
- setflag(cpu->y[thread] == 0, Z);
- setflag((cpu->y[thread] >> 63), N);
- break;
- case DEX:
- cpu->x[thread]-=1;
- setflag(cpu->x[thread] == 0, Z);
- setflag((cpu->x[thread] >> 63), N);
- break;
+ 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);
break;
case JSL: /* Jump to Subroutine Long. */
- switch (addrsize) {
- case 3: stksize = 7; break;
- case 2: stksize = 6; break;
- case 1: stksize = 4; break;
- case 0: stksize = 1; break;
- }
+ stksize = adrsize[addrsize+4];
+ /* Unroll Loop by implementing Duff's Device. */
switch (stksize) {
case 7: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (7<<3);cpu->sp[thread]--;
case 6: addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> (6<<3);cpu->sp[thread]--;
@@ -1343,16 +1204,12 @@ void *run(void *args) {
break;
case RTL: /* ReTurn from subroutine Long. */
tmp2 = 1;
- switch (addrsize) {
- case 3: stksize = 7; break;
- case 2: stksize = 6; break;
- case 1: stksize = 4; break;
- case 0: stksize = 0; break;
- }
+ stksize = adrsize[addrsize+4];
cpu->sp[thread] += 2;
stksize -= 2;
cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+(cpu->sp[thread]-1)] & 0xFF;
cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << 8;
+ /* Unroll Loop by implementing Duff's Device. */
switch (stksize) {
case 5: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
case 4: cpu->sp[thread]++;tmp2++;cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << (tmp2<<3);
@@ -1404,6 +1261,7 @@ void *run(void *args) {
}
ins++;
step = addr[STEP_ADDR];
+ #if !bench
if (step) {
pthread_mutex_lock(&main_mutex);
pthread_cond_signal(&main_cond);
@@ -1411,16 +1269,12 @@ void *run(void *args) {
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
- #if debug && !bench
+ #if debug
wrefresh(scr);
#endif
}
- if (!addr[CTRL_ADDR])
- kbd_ln = 0;
- else
- kbd_ln = 1;
-
- #if debug && !bench
+ #endif
+ #if debug && !bench
#if keypoll
pthread_mutex_lock(&mutex);
#endif
@@ -1431,8 +1285,7 @@ void *run(void *args) {
#if keypoll
pthread_mutex_unlock(&mutex);
#endif
- #endif
- #if bench
+ #elif bench
if (ins >= BENCH_INST) {
end = 1;
pthread_mutex_lock(&main_mutex);
@@ -1443,7 +1296,7 @@ void *run(void *args) {
pthread_mutex_unlock(&main_mutex);
gettimeofday(&en[thread], 0);
}
- #endif
+ #endif
}
free(s);
}
@@ -1466,7 +1319,7 @@ int main(int argc, char **argv) {
sprintf(tmp, "\033[2J\033[H");
fwrite(tmp, sizeof(char), strlen(tmp), stdout);
fflush(stdout);
-#if !bench
+ #if !bench
if(!scr)
scr = initscr();
nodelay(stdscr, 0);
@@ -1476,13 +1329,15 @@ int main(int argc, char **argv) {
curs_set(1);
werase(scr);
scrollok(scr, 1);
- wrefresh(scr);
start_color();
use_default_colors();
init_pair(1, COLOR_WHITE, -1);
attron(COLOR_PAIR(1) | A_BOLD);
wmove(scr, 0, 0);
-#endif
+ wrefresh(scr);
+ #endif
+ pthread_t therads[THREADS];
+ int result;
for (int i = 0; i < THREADS; i++) {
thr[i].sx.sp[i] = 0xFFFF;
thr[i].sx.stk_st[i] = i+1;
@@ -1514,13 +1369,7 @@ int main(int argc, char **argv) {
| (uint64_t)addr[0xFFC7] << 56;
}
thr[i].th = i;
- }
- pthread_t therads[THREADS];
- int result;
- for (int i = 0; i < THREADS; i++) {
inst[i] = 0;
- }
- for (int i = 0; i < THREADS; i++) {
result = pthread_create(&therads[i], NULL, run, &thr[i]);
assert(!result);
}
@@ -1531,7 +1380,7 @@ int main(int argc, char **argv) {
#endif
while (threads_done < THREADS) {
#if !bench
- int x, y, i = 0;
+ int x, y;
if ((step_key && step && !kbd_rdy) || !step || kbd_rdy) {
if ((c != EOF && c !=-1)) {
pthread_mutex_lock(&main_mutex);
@@ -1542,7 +1391,6 @@ int main(int argc, char **argv) {
c = 0;
step_key = 0;
addr[CTRL_ADDR] = 0;
- kbd_ln = 0;
#if !debug
wrefresh(scr);
#endif
@@ -1562,10 +1410,6 @@ int main(int argc, char **argv) {
switch (c) {
case ERR:
addr[CTRL_ADDR] = 0;
- wmove(scr, getmaxy(scr)-1, 0);
- wprintw(scr, "c: %i, x: %i, y: %i, i: %i.", c, x, y, i++);
- wmove(scr, y, x);
- wrefresh(scr);
break;
default:
if (kbd_rdy && c < 0x100) {
@@ -1573,13 +1417,11 @@ int main(int argc, char **argv) {
addr[CTRL_ADDR] = 1;
#if debug && !bench
wmove(scr, getmaxy(scr)-1, 0);
- wprintw(scr, "c: %i, x: %i, y: %i, i: %i.", c, x, y, i++);
+ wprintw(scr, "c: %i, x: %i, y: %i", c, x, y);
wmove(scr, y, x);
wrefresh(scr);
#endif
}
- if (c == '\n')
- kbd_ln = 1;
#if !keypoll
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);