diff options
Diffstat (limited to 'sux.c')
-rw-r--r-- | sux.c | 821 |
1 files changed, 44 insertions, 777 deletions
@@ -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; |