diff options
Diffstat (limited to 'opcode.c')
-rw-r--r-- | opcode.c | 241 |
1 files changed, 152 insertions, 89 deletions
@@ -9,15 +9,21 @@ void setps(struct sux *cpu, uint8_t thread) { (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); } -void adc(struct sux *cpu, uint64_t adr, uint8_t thread) { - uint64_t value = (uint64_t)addr[adr] - | (uint64_t)addr[adr+1] << 8 - | (uint64_t)addr[adr+2] << 16 - | (uint64_t)addr[adr+3] << 24 - | (uint64_t)addr[adr+4] << 32 - | (uint64_t)addr[adr+5] << 40 - | (uint64_t)addr[adr+6] << 48 - | (uint64_t)addr[adr+7] << 56; +void adc(struct sux *cpu, uint64_t adr, uint8_t thread, uint8_t regsize) { + uint64_t value; + value = (uint64_t)addr[adr]; + if (regsize >= 2) + value += (uint64_t)addr[adr+1] << 8; + if (regsize >= 4) { + value += (uint64_t)addr[adr+2] << 16; + value += (uint64_t)addr[adr+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[adr+4] << 32; + value += (uint64_t)addr[adr+5] << 40; + value += (uint64_t)addr[adr+6] << 48; + value += (uint64_t)addr[adr+7] << 56; + } uint64_t sum = cpu->a[thread]+value+cpu->c[thread]; cpu->z[thread] = (sum == 0); cpu->n[thread] = (sum >> 63); @@ -27,15 +33,21 @@ void adc(struct sux *cpu, uint64_t adr, uint8_t thread) { setps(cpu, thread); } -void sbc(struct sux *cpu, uint64_t adr, uint8_t thread) { - uint64_t value = (uint64_t)addr[adr] - | (uint64_t)addr[adr+1] << 8 - | (uint64_t)addr[adr+2] << 16 - | (uint64_t)addr[adr+3] << 24 - | (uint64_t)addr[adr+4] << 32 - | (uint64_t)addr[adr+5] << 40 - | (uint64_t)addr[adr+6] << 48 - | (uint64_t)addr[adr+7] << 56; +void sbc(struct sux *cpu, uint64_t adr, uint8_t thread, uint8_t regsize) { + uint64_t value; + value = (uint64_t)addr[adr]; + if (regsize >= 2) + value += (uint64_t)addr[adr+1] << 8; + if (regsize >= 4) { + value += (uint64_t)addr[adr+2] << 16; + value += (uint64_t)addr[adr+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[adr+4] << 32; + value += (uint64_t)addr[adr+5] << 40; + value += (uint64_t)addr[adr+6] << 48; + value += (uint64_t)addr[adr+7] << 56; + } uint64_t sum = cpu->a[thread]-value-!cpu->c[thread]; cpu->z[thread] = (sum == 0); cpu->n[thread] = (sum >> 63); @@ -45,15 +57,21 @@ void sbc(struct sux *cpu, uint64_t adr, uint8_t thread) { setps(cpu, thread); } -void mul(struct sux *cpu, uint64_t adr, uint8_t thread) { - uint64_t value = (uint64_t)addr[adr] - | (uint64_t)addr[adr+1] << 8 - | (uint64_t)addr[adr+2] << 16 - | (uint64_t)addr[adr+3] << 24 - | (uint64_t)addr[adr+4] << 32 - | (uint64_t)addr[adr+5] << 40 - | (uint64_t)addr[adr+6] << 48 - | (uint64_t)addr[adr+7] << 56; +void mul(struct sux *cpu, uint64_t adr, uint8_t thread, uint8_t regsize) { + uint64_t value; + value = (uint64_t)addr[adr]; + if (regsize >= 2) + value += (uint64_t)addr[adr+1] << 8; + if (regsize >= 4) { + value += (uint64_t)addr[adr+2] << 16; + value += (uint64_t)addr[adr+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[adr+4] << 32; + value += (uint64_t)addr[adr+5] << 40; + value += (uint64_t)addr[adr+6] << 48; + value += (uint64_t)addr[adr+7] << 56; + } uint64_t sum = cpu->a[thread]*value+cpu->c[thread]; cpu->z[thread] = (sum == 0); cpu->n[thread] = (sum >> 63); @@ -63,15 +81,21 @@ void mul(struct sux *cpu, uint64_t adr, uint8_t thread) { setps(cpu, thread); } -void divd(struct sux *cpu, uint64_t adr, uint8_t thread) { - uint64_t value = (uint64_t)addr[adr] - | (uint64_t)addr[adr+1] << 8 - | (uint64_t)addr[adr+2] << 16 - | (uint64_t)addr[adr+3] << 24 - | (uint64_t)addr[adr+4] << 32 - | (uint64_t)addr[adr+5] << 40 - | (uint64_t)addr[adr+6] << 48 - | (uint64_t)addr[adr+7] << 56; +void divd(struct sux *cpu, uint64_t adr, uint8_t thread, uint8_t regsize) { + uint64_t value; + value = (uint64_t)addr[adr]; + if (regsize >= 2) + value += (uint64_t)addr[adr+1] << 8; + if (regsize >= 4) { + value += (uint64_t)addr[adr+2] << 16; + value += (uint64_t)addr[adr+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[adr+4] << 32; + value += (uint64_t)addr[adr+5] << 40; + value += (uint64_t)addr[adr+6] << 48; + value += (uint64_t)addr[adr+7] << 56; + } uint64_t sum = cpu->a[thread]/value; cpu->z[thread] = (sum == 0); cpu->v[thread] = !((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000); @@ -88,15 +112,21 @@ uint64_t and(struct sux *cpu, uint64_t value, uint8_t thread) { return sum; } -void and_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread) { - uint64_t value = (uint64_t)addr[adr] - | (uint64_t)addr[adr+1] << 8 - | (uint64_t)addr[adr+2] << 16 - | (uint64_t)addr[adr+3] << 24 - | (uint64_t)addr[adr+4] << 32 - | (uint64_t)addr[adr+5] << 40 - | (uint64_t)addr[adr+6] << 48 - | (uint64_t)addr[adr+7] << 56; +void and_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread, uint8_t regsize) { + uint64_t value; + value = (uint64_t)addr[adr]; + if (regsize >= 2) + value += (uint64_t)addr[adr+1] << 8; + if (regsize >= 4) { + value += (uint64_t)addr[adr+2] << 16; + value += (uint64_t)addr[adr+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[adr+4] << 32; + value += (uint64_t)addr[adr+5] << 40; + value += (uint64_t)addr[adr+6] << 48; + value += (uint64_t)addr[adr+7] << 56; + } *reg &= value; cpu->z[thread] = (*reg == 0); cpu->n[thread] = (*reg >> 63); @@ -112,15 +142,21 @@ uint64_t or(struct sux *cpu, uint64_t value, uint8_t thread) { return sum; } -void or_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread) { - uint64_t value = (uint64_t)addr[adr] - | (uint64_t)addr[adr+1] << 8 - | (uint64_t)addr[adr+2] << 16 - | (uint64_t)addr[adr+3] << 24 - | (uint64_t)addr[adr+4] << 32 - | (uint64_t)addr[adr+5] << 40 - | (uint64_t)addr[adr+6] << 48 - | (uint64_t)addr[adr+7] << 56; +void or_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread, uint8_t regsize) { + uint64_t value; + value = (uint64_t)addr[adr]; + if (regsize >= 2) + value += (uint64_t)addr[adr+1] << 8; + if (regsize >= 4) { + value += (uint64_t)addr[adr+2] << 16; + value += (uint64_t)addr[adr+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[adr+4] << 32; + value += (uint64_t)addr[adr+5] << 40; + value += (uint64_t)addr[adr+6] << 48; + value += (uint64_t)addr[adr+7] << 56; + } *reg |= value; cpu->z[thread] = (*reg == 0); cpu->n[thread] = (*reg >> 63); @@ -136,15 +172,21 @@ uint64_t xor(struct sux *cpu, uint64_t value, uint8_t thread) { return sum; } -void xor_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread) { - uint64_t value = (uint64_t)addr[adr] - | (uint64_t)addr[adr+1] << 8 - | (uint64_t)addr[adr+2] << 16 - | (uint64_t)addr[adr+3] << 24 - | (uint64_t)addr[adr+4] << 32 - | (uint64_t)addr[adr+5] << 40 - | (uint64_t)addr[adr+6] << 48 - | (uint64_t)addr[adr+7] << 56; +void xor_addr(struct sux *cpu, uint64_t* const reg, uint64_t adr, uint8_t thread, uint8_t regsize) { + uint64_t value; + value = (uint64_t)addr[adr]; + if (regsize >= 2) + value += (uint64_t)addr[adr+1] << 8; + if (regsize >= 4) { + value += (uint64_t)addr[adr+2] << 16; + value += (uint64_t)addr[adr+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[adr+4] << 32; + value += (uint64_t)addr[adr+5] << 40; + value += (uint64_t)addr[adr+6] << 48; + value += (uint64_t)addr[adr+7] << 56; + } *reg ^= value; cpu->z[thread] = (*reg == 0); cpu->n[thread] = (*reg >> 63); @@ -235,29 +277,39 @@ void ent(struct sux *cpu, uint8_t value) { cpu->pc[i+1] = cpu->pc[0]+(i+1); } -void ld(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread) { - *reg = (uint64_t)addr[adr] - | (uint64_t)addr[adr+1] << 8 - | (uint64_t)addr[adr+2] << 16 - | (uint64_t)addr[adr+3] << 24 - | (uint64_t)addr[adr+4] << 32 - | (uint64_t)addr[adr+5] << 40 - | (uint64_t)addr[adr+6] << 48 - | (uint64_t)addr[adr+7] << 56; +void ld(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread, uint8_t regsize) { + *reg = (uint64_t)addr[adr]; + if (regsize >= 2) + *reg += (uint64_t)addr[adr+1] << 8; + if (regsize >= 4) { + *reg += (uint64_t)addr[adr+2] << 16; + *reg += (uint64_t)addr[adr+3] << 24; + } + if (regsize >= 8) { + *reg += (uint64_t)addr[adr+4] << 32; + *reg += (uint64_t)addr[adr+5] << 40; + *reg += (uint64_t)addr[adr+6] << 48; + *reg += (uint64_t)addr[adr+7] << 56; + } cpu->z[thread] = (*reg == 0); cpu->n[thread] = (*reg >> 63); setps(cpu, thread); } -void st(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread) { +void st(struct sux *cpu, uint64_t *reg, uint64_t adr, uint8_t thread, uint8_t regsize) { addr[adr] = *reg & 0xFF; - addr[adr+1] = *reg >> 8; - addr[adr+2] = *reg >> 16; - addr[adr+3] = *reg >> 24; - addr[adr+4] = *reg >> 32; - addr[adr+5] = *reg >> 40; - addr[adr+6] = *reg >> 48; - addr[adr+7] = *reg >> 56; + if (regsize >= 2) + addr[adr+1] = *reg >> 8; + if (regsize >= 4) { + addr[adr+2] = *reg >> 16; + addr[adr+3] = *reg >> 24; + } + if (regsize >= 8) { + addr[adr+4] = *reg >> 32; + addr[adr+5] = *reg >> 40; + addr[adr+6] = *reg >> 48; + addr[adr+7] = *reg >> 56; + } } void push(struct sux *cpu, uint8_t value) { @@ -274,15 +326,21 @@ uint8_t pull(struct sux *cpu) { return addr[STK_STADDR+cpu->sp]; } -void cmp_addr(struct sux *cpu, uint64_t reg, uint64_t adr, uint8_t thread) { - uint64_t value = (uint64_t)addr[adr] - | (uint64_t)addr[adr+1] << 8 - | (uint64_t)addr[adr+2] << 16 - | (uint64_t)addr[adr+3] << 24 - | (uint64_t)addr[adr+4] << 32 - | (uint64_t)addr[adr+5] << 40 - | (uint64_t)addr[adr+6] << 48 - | (uint64_t)addr[adr+7] << 56; +void cmp_addr(struct sux *cpu, uint64_t reg, uint64_t adr, uint8_t thread, uint8_t regsize) { + uint64_t value; + value = (uint64_t)addr[adr]; + if (regsize >= 2) + value += (uint64_t)addr[adr+1] << 8; + if (regsize >= 4) { + value += (uint64_t)addr[adr+2] << 16; + value += (uint64_t)addr[adr+3] << 24; + } + if (regsize >= 8) { + value += (uint64_t)addr[adr+4] << 32; + value += (uint64_t)addr[adr+5] << 40; + value += (uint64_t)addr[adr+6] << 48; + value += (uint64_t)addr[adr+7] << 56; + } uint64_t sum = reg-value; cpu->n[thread] = (sum & 0x8000000000000000) ? 1 : 0; cpu->z[thread] = (sum == 0) ? 1 : 0; @@ -313,6 +371,7 @@ void bfc(struct sux *cpu, uint8_t flag, uint64_t adr, uint8_t thread) { uint64_t immaddr(struct sux *cpu, uint8_t thread, uint8_t size) { uint64_t adr = cpu->pc[thread]; cpu->pc[thread]+=size; + clk+=size; return adr; } @@ -326,6 +385,7 @@ uint64_t absaddr(struct sux *cpu, uint8_t thread) { | (uint64_t)addr[cpu->pc[thread]+6] << 48 | (uint64_t)addr[cpu->pc[thread]+7] << 56; cpu->pc[thread]+=8; + clk++; return adr; } @@ -335,6 +395,7 @@ uint32_t zeromtx(struct sux *cpu, uint8_t thread) { | (uint32_t)addr[cpu->pc[thread]+2] << 16 | (uint32_t)addr[cpu->pc[thread]+3] << 24; cpu->pc[thread]+=4; + clk++; return adr; } @@ -345,6 +406,7 @@ uint32_t zeromx(struct sux *cpu, uint8_t thread) { | (uint32_t)addr[cpu->pc[thread]+3] << 24; adr += cpu->x[thread]; cpu->pc[thread]+=4; + clk++; return adr; } @@ -355,5 +417,6 @@ uint32_t zeromy(struct sux *cpu, uint8_t thread) { | (uint32_t)addr[cpu->pc[thread]+3] << 24; adr += cpu->y[thread]; cpu->pc[thread]+=4; + clk++; return adr; } |