From c5150ee31f07208422f1435de9b35a0d0168cbb5 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Thu, 9 Apr 2020 02:06:50 -0400 Subject: Completely changed the assembler. It now has a lexer/tokenizer, along with a parser. I have also made the emulator even smaller. --- sux.c | 568 ++++++++++++++++++++++++------------------------------------------ 1 file changed, 205 insertions(+), 363 deletions(-) (limited to 'sux.c') diff --git a/sux.c b/sux.c index 164ca4a..6c9442f 100644 --- a/sux.c +++ b/sux.c @@ -4,8 +4,8 @@ #include #include #define bench 0 -#define debug 1 -#define IO 0 +#define debug 0 +#define IO 1 #define keypoll 0 #if bench #include @@ -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); -- cgit v1.2.3-13-gbd6f