summaryrefslogtreecommitdiff
path: root/opcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'opcode.c')
-rw-r--r--opcode.c241
1 files changed, 152 insertions, 89 deletions
diff --git a/opcode.c b/opcode.c
index 32f4e9d..0bee207 100644
--- a/opcode.c
+++ b/opcode.c
@@ -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;
}