From 917f864a6d1304d9f0c650c107a5fd6576690cb7 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Thu, 5 Mar 2020 15:59:37 -0500 Subject: Optimize the emulator, even more. --- sux.c | 387 +++++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 255 insertions(+), 132 deletions(-) (limited to 'sux.c') 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); -- cgit v1.2.3-13-gbd6f