summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormrb0nk500 <b0nk@b0nk.xyz>2019-12-06 17:25:13 -0500
committermrb0nk500 <b0nk@b0nk.xyz>2019-12-06 17:28:03 -0500
commit8d0f46d4e62af5d66ff3cce872256163a41b54bf (patch)
treeafe1b4a1b7de11db68e7329237cffb44bf1c5661
parentb4f547ecb600729e0e1b980c27c154b2a99bbca1 (diff)
Delete opcode.c, since I added all the functions
from it into sux.c.
-rw-r--r--Makefile4
-rw-r--r--opcode.c242
-rw-r--r--sux.c579
-rw-r--r--test/test-stack.s7
4 files changed, 459 insertions, 373 deletions
diff --git a/Makefile b/Makefile
index e4d801a..d2764cd 100644
--- a/Makefile
+++ b/Makefile
@@ -8,14 +8,12 @@ PCC_CFLAGS=
endif
CFLAGS = $(PCC_CFLAGS) $(CFLAGS_EXTRA)
-OBJS = asmmon.o opcode.o sux.o
+OBJS = asmmon.o sux.o
OBJ_NAME = cisc-0.2
all : $(OBJS)
$(CC) $(OBJS) $(CFLAGS) -lpthread -o $(OBJ_NAME)
sux.o :
$(CC) sux.c -c $(CFLAGS) -o sux.o
-opcode.o :
- $(CC) opcode.c -c $(CFLAGS) -o opcode.o
asmmon.o :
$(CC) asmmon.c -c $(CFLAGS) -o asmmon.o
clean :
diff --git a/opcode.c b/opcode.c
deleted file mode 100644
index 847ff80..0000000
--- a/opcode.c
+++ /dev/null
@@ -1,242 +0,0 @@
-#include "opcode.h"
-
-void setps(struct sux *cpu, uint8_t thread) {
- (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread));
- (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread));
- (cpu->i[thread]) ? (cpu->ps |= (I << 8*thread)) : (cpu->ps &= ~(I << 8*thread));
- (cpu->s[thread]) ? (cpu->ps |= (S << 8*thread)) : (cpu->ps &= ~(S << 8*thread));
- (cpu->v[thread]) ? (cpu->ps |= (V << 8*thread)) : (cpu->ps &= ~(V << 8*thread));
- (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
-}
-
-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);
- cpu->v[thread] = !((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000);
- cpu->c[thread] = (!((cpu->a[thread]^sum) && (cpu->a[thread]^value)) && (cpu->a[thread] >= ((uint64_t)1 << 32) && value >= ((uint64_t)1 << 32)));
- cpu->a[thread] = sum;
- setps(cpu, thread);
-}
-
-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);
- cpu->a[thread] = sum;
- setps(cpu, thread);
-}
-
-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);
- setps(cpu, thread);
-}
-
-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);
- setps(cpu, thread);
-}
-
-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);
- setps(cpu, thread);
-}
-
-void stt(struct sux* const cpu, uint8_t value) {
- uint16_t tv = 0xFF50; /* Thread Vector. */
- uint8_t t = addr[value];
- cpu->crt |= t;
- for (uint8_t i = 0; i < 7; i++)
- if ((t >> i) & 1) {
- uint64_t adr = (uint64_t)addr[tv+(8*i)]
- | (uint64_t)addr[tv+1+(8*i)] << 8
- | (uint64_t)addr[tv+2+(8*i)] << 16
- | (uint64_t)addr[tv+3+(8*i)] << 24
- | (uint64_t)addr[tv+4+(8*i)] << 32
- | (uint64_t)addr[tv+5+(8*i)] << 40
- | (uint64_t)addr[tv+6+(8*i)] << 48
- | (uint64_t)addr[tv+7+(8*i)] << 56;
- cpu->pc[i+1] = adr;
- }
-}
-
-void ent(struct sux *cpu, uint8_t value) {
- uint8_t t = addr[value];
- cpu->crt &= ~t;
- for (uint8_t i = 0; i < 7; i++)
- if ((t >> i) & 1)
- cpu->pc[i+1] = cpu->pc[0]+(i+1);
-}
-
-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, uint8_t regsize) {
- addr[adr] = *reg & 0xFF;
- 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) {
- addr[STK_STADDR+cpu->sp] = value;
- cpu->sp--;
- addr[0xFF90] = cpu->sp & 0xFF;
- addr[0xFF91] = cpu->sp >> 8;
-}
-
-uint8_t pull(struct sux *cpu) {
- cpu->sp++;
- addr[0xFF90] = cpu->sp & 0xFF;
- addr[0xFF91] = cpu->sp >> 8;
- return addr[STK_STADDR+cpu->sp];
-}
-
-uint64_t immaddr(struct sux *cpu, uint8_t thread, uint8_t size) {
- uint64_t adr = cpu->pc[thread];
- cpu->pc[thread]+=size;
- return adr;
-}
-
-uint64_t absaddr(struct sux *cpu, uint8_t thread) {
- uint64_t adr = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- return adr;
-}
-
-uint32_t zeromtx(struct sux *cpu, uint8_t thread) {
- uint32_t adr = (uint32_t)addr[cpu->pc[thread]]
- | (uint32_t)addr[cpu->pc[thread]+1] << 8
- | (uint32_t)addr[cpu->pc[thread]+2] << 16
- | (uint32_t)addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- return adr;
-}
-
-uint32_t zeromx(struct sux *cpu, uint8_t thread) {
- uint32_t adr = (uint32_t)addr[cpu->pc[thread]]
- | (uint32_t)addr[cpu->pc[thread]+1] << 8
- | (uint32_t)addr[cpu->pc[thread]+2] << 16
- | (uint32_t)addr[cpu->pc[thread]+3] << 24;
- adr += cpu->x[thread];
- cpu->pc[thread]+=4;
- return adr;
-}
-
-uint32_t zeromy(struct sux *cpu, uint8_t thread) {
- uint32_t adr = (uint32_t)addr[cpu->pc[thread]]
- | (uint32_t)addr[cpu->pc[thread]+1] << 8
- | (uint32_t)addr[cpu->pc[thread]+2] << 16
- | (uint32_t)addr[cpu->pc[thread]+3] << 24;
- adr += cpu->y[thread];
- cpu->pc[thread]+=4;
- return adr;
-}
diff --git a/sux.c b/sux.c
index 2f1461a..4df60cb 100644
--- a/sux.c
+++ b/sux.c
@@ -39,7 +39,7 @@ void *run(void *args) {
uint64_t value = 0;
uint64_t iclk = 0;
uint64_t ins = 0;
- /*pthread_mutex_lock(&mutex);*/
+ uint16_t tv = 0xFF50; /* Thread Vector. */
#if bench
gettimeofday(&str[thread], 0);
#endif
@@ -137,37 +137,57 @@ void *run(void *args) {
tmp = addr[cpu->pc[thread]++];
if (tmp > 7)
tmp = 7;
- for (int8_t i = 8*tmp; i > 0; i-=8) {
- push(cpu, cpu->ps >> i);
+ for (int8_t i = tmp*8; i >= 0; i-=8) {
+ if (i)
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->ps >> i;
+ else
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->ps & 0xFF;
+ cpu->sp--;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
}
- push(cpu, cpu->ps & 0xFF);
break;
case PHA: /* PusH Accumulator to stack. */
tmp = addr[cpu->pc[thread]++];
if (tmp > 7)
tmp = 7;
- for (int8_t i = 8*tmp; i > 0; i-=8) {
- push(cpu, cpu->a[thread] >> i);
+ for (int8_t i = tmp*8; i >= 0; i-=8) {
+ if (i)
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->a[thread] >> i;
+ else
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->a[thread] & 0xFF;
+ cpu->sp--;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
}
- push(cpu, cpu->a[thread] & 0xFF);
break;
case PHY: /* PusH Y register to stack. */
tmp = addr[cpu->pc[thread]++];
if (tmp > 7)
tmp = 7;
- for (int8_t i = 8*tmp; i > 0; i-=8) {
- push(cpu, cpu->y[thread] >> i);
+ for (int8_t i = tmp*8; i >= 0; i-=8) {
+ if (i)
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->y[thread] >> i;
+ else
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->y[thread] & 0xFF;
+ cpu->sp--;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
}
- push(cpu, cpu->y[thread] & 0xFF);
break;
case PHX: /* PusH X register to stack. */
tmp = addr[cpu->pc[thread]++];
if (tmp > 7)
tmp = 7;
- for (int8_t i = 8*tmp; i > 0; i-=8) {
- push(cpu, cpu->x[thread] >> i);
+ for (int8_t i = tmp*8; i >= 0; i-=8) {
+ if (i)
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->x[thread] >> i;
+ else
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->x[thread] & 0xFF;
+ cpu->sp--;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
}
- push(cpu, cpu->x[thread] & 0xFF);
break;
case JMP: /* JMP Absolute. */
address = (uint64_t)addr[cpu->pc[thread]]
@@ -238,44 +258,56 @@ void *run(void *args) {
tmp = addr[cpu->pc[thread]++];
if (tmp > 7)
tmp = 7;
- for (uint8_t i = 0; i <= 8*tmp; i+=8) {
- if (!i)
- cpu->ps = (uint64_t)pull(cpu);
+ for (uint8_t i = 0; i < (tmp+1)*8; i+=8) {
+ cpu->sp++;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
+ if (i)
+ cpu->ps += (uint64_t)addr[STK_STADDR+cpu->sp] << i;
else
- cpu->ps += (uint64_t)pull(cpu) << i;
+ cpu->ps = (uint64_t)addr[STK_STADDR+cpu->sp] & 0xFF;
}
break;
case PLA: /* PuLl Accumulator from stack. */
tmp = addr[cpu->pc[thread]++];
if (tmp > 7)
tmp = 7;
- for (uint8_t i = 0; i <= 8*tmp; i+=8) {
- if (!i)
- cpu->a[thread] = (uint64_t)pull(cpu);
+ for (uint8_t i = 0; i < (tmp+1)*8; i+=8) {
+ cpu->sp++;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
+ if (i)
+ cpu->a[thread] += (uint64_t)addr[STK_STADDR+cpu->sp] << i;
else
- cpu->a[thread] += (uint64_t)pull(cpu) << i;
+ cpu->a[thread] = (uint64_t)addr[STK_STADDR+cpu->sp] & 0xFF;
}
break;
case PLY: /* PuLl Y register from stack. */
tmp = addr[cpu->pc[thread]++];
if (tmp > 7)
tmp = 7;
- for (uint8_t i = 0; i <= 8*tmp; i+=8) {
- if (!i)
- cpu->y[thread] = (uint64_t)pull(cpu);
+ for (uint8_t i = 0; i < (tmp+1)*8; i+=8) {
+ cpu->sp++;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
+ if (i)
+ cpu->y[thread] += (uint64_t)addr[STK_STADDR+cpu->sp] << i;
else
- cpu->y[thread] += (uint64_t)pull(cpu) << i;
+ cpu->y[thread] = (uint64_t)addr[STK_STADDR+cpu->sp] & 0xFF;
}
break;
case PLX: /* PuLl X register from stack. */
tmp = addr[cpu->pc[thread]++];
if (tmp > 7)
tmp = 7;
- for (uint8_t i = 0; i <= 8*tmp; i+=8) {
- if (!i)
- cpu->x[thread] = (uint64_t)pull(cpu);
+ for (uint8_t i = 0; i < (tmp+1)*8; i+=8) {
+ cpu->sp++;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
+ if (i)
+ cpu->x[thread] += (uint64_t)addr[STK_STADDR+cpu->sp] << i;
else
- cpu->x[thread] += (uint64_t)pull(cpu) << i;
+ cpu->x[thread] = (uint64_t)addr[STK_STADDR+cpu->sp] & 0xFF;
}
break;
case JSR: /* Jump to SubRoutine. */
@@ -284,14 +316,74 @@ void *run(void *args) {
| (uint64_t)addr[cpu->pc[thread]+2] << 16
| (uint64_t)addr[cpu->pc[thread]+3] << 24;
cpu->pc[thread]+=4;
- push(cpu, (uint64_t)cpu->pc[thread] >> 24);
- push(cpu, (uint64_t)cpu->pc[thread] >> 16);
- push(cpu, (uint64_t)cpu->pc[thread] >> 8);
- push(cpu, (uint64_t)cpu->pc[thread] & 0xFF);
+ for (int8_t i = 24; i >= 0; i-=8) {
+ if (i)
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->pc[thread] >> i;
+ else
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->pc[thread] & 0xFF;
+ cpu->sp--;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
+ }
cpu->pc[thread] = address;
break;
- case AND: and_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* AND Immediate. */
- case ANY: and_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ANY Immediate. */
+ case AND: /* AND Immediate. */
+ case 0x29: /* AND Absolute. */
+ case 0x2B: /* AND Zero Matrix. */
+ case ANY: /* ANY Immediate. */
+ case 0x52: /* ANY Absolute. */
+ case 0x82: /* ANY Zero Matrix. */
+ case ANX: /* ANX Immediate. */
+ case 0x54: /* ANX Absolute. */
+ case 0x84: /* ANX Zero Matrix. */
+ if (opcode == AND || opcode == ANY || opcode == ANX) {
+ address = cpu->pc[thread];
+ cpu->pc[thread]+=regsize;
+ }
+ if (opcode == 0x29 || opcode == 0x52 || opcode == 0x54) {
+ address = (uint64_t)addr[cpu->pc[thread]]
+ | (uint64_t)addr[cpu->pc[thread]+1] << 8
+ | (uint64_t)addr[cpu->pc[thread]+2] << 16
+ | (uint64_t)addr[cpu->pc[thread]+3] << 24
+ | (uint64_t)addr[cpu->pc[thread]+4] << 32
+ | (uint64_t)addr[cpu->pc[thread]+5] << 40
+ | (uint64_t)addr[cpu->pc[thread]+6] << 48
+ | (uint64_t)addr[cpu->pc[thread]+7] << 56;
+ cpu->pc[thread]+=8;
+ iclk++;
+ }
+ if (opcode == 0x2B || opcode == 0x82 || opcode == 0x84) {
+ address = addr[cpu->pc[thread]]
+ | addr[cpu->pc[thread]+1] << 8
+ | addr[cpu->pc[thread]+2] << 16
+ | addr[cpu->pc[thread]+3] << 24;
+ cpu->pc[thread]+=4;
+ iclk++;
+ }
+ value = (uint64_t)addr[address];
+ if (regsize >= 2)
+ value += (uint64_t)addr[address+1] << 8;
+ if (regsize >= 4) {
+ value += (uint64_t)addr[address+2] << 16;
+ value += (uint64_t)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 (opcode == AND || opcode == 0x29 || opcode == 0x2B)
+ cpu->a[thread] &= value;
+ if (opcode == ANY || opcode == 0x52 || opcode == 0x82)
+ cpu->y[thread] &= value;
+ if (opcode == ANX || opcode == 0x54 || opcode == 0x84)
+ cpu->x[thread] &= value;
+ cpu->z[thread] = (value == 0);
+ cpu->n[thread] = (value >> 63);
+ (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread));
+ (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
+ break;
case AAY:
case AAX:
if (opcode == AAY)
@@ -303,10 +395,25 @@ void *run(void *args) {
(cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread));
(cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
break;
- case ANX: and_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ANX Immediate. */
- case STT: stt(cpu, immaddr(cpu, thread, 1)); break; /* STart Thread. */
- case 0x29: and_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* AND Absolute. */
- case 0x2B: and_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* AND Zero Matrix. */
+ case STT: /* STart Thread. */
+ address = cpu->pc[thread];
+ cpu->pc[thread]++;
+ value = addr[address];
+ cpu->crt |= value;
+ for (uint8_t i = 0; i < 7; i++) {
+ if ((value >> i) & 1) {
+ address = (uint64_t)addr[tv+(8*i)]
+ | (uint64_t)addr[tv+1+(8*i)] << 8
+ | (uint64_t)addr[tv+2+(8*i)] << 16
+ | (uint64_t)addr[tv+3+(8*i)] << 24
+ | (uint64_t)addr[tv+4+(8*i)] << 32
+ | (uint64_t)addr[tv+5+(8*i)] << 40
+ | (uint64_t)addr[tv+6+(8*i)] << 48
+ | (uint64_t)addr[tv+7+(8*i)] << 56;
+ cpu->pc[i+1] = address;
+ }
+ }
+ break;
case BPO: /* Branch if POsitive. */
address = (uint64_t)addr[cpu->pc[thread]]
| (uint64_t)addr[cpu->pc[thread]+1] << 8
@@ -321,9 +428,63 @@ void *run(void *args) {
if (cpu->n[thread])
cpu->pc[thread] = address;
break;
- case ORA: or_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ORA Immediate. */
- case ORY: or_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ORY Immediate. */
- case ORX: or_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* ORX Immediate. */
+ case ORA: /* ORA Immediate. */
+ case 0x39: /* ORA Absolute. */
+ case 0x3B: /* ORA Zero Matrix. */
+ case ORY: /* ORY Immediate. */
+ case 0x62: /* ORY Absolute. */
+ case 0x92: /* ORY Zero Matrix. */
+ case ORX: /* ORX Immediate. */
+ case 0x64: /* ORX Absolute. */
+ case 0x94: /* ORX Zero Matrix. */
+ if (opcode == ORA || opcode == ORY || opcode == ORX) {
+ address = cpu->pc[thread];
+ cpu->pc[thread]+=regsize;
+ }
+ if (opcode == 0x39 || opcode == 0x62 || opcode == 0x64) {
+ address = (uint64_t)addr[cpu->pc[thread]]
+ | (uint64_t)addr[cpu->pc[thread]+1] << 8
+ | (uint64_t)addr[cpu->pc[thread]+2] << 16
+ | (uint64_t)addr[cpu->pc[thread]+3] << 24
+ | (uint64_t)addr[cpu->pc[thread]+4] << 32
+ | (uint64_t)addr[cpu->pc[thread]+5] << 40
+ | (uint64_t)addr[cpu->pc[thread]+6] << 48
+ | (uint64_t)addr[cpu->pc[thread]+7] << 56;
+ cpu->pc[thread]+=8;
+ iclk++;
+ }
+ if (opcode == 0x3B || opcode == 0x92 || opcode == 0x94) {
+ address = addr[cpu->pc[thread]]
+ | addr[cpu->pc[thread]+1] << 8
+ | addr[cpu->pc[thread]+2] << 16
+ | addr[cpu->pc[thread]+3] << 24;
+ cpu->pc[thread]+=4;
+ iclk++;
+ }
+ value = (uint64_t)addr[address];
+ if (regsize >= 2)
+ value += (uint64_t)addr[address+1] << 8;
+ if (regsize >= 4) {
+ value += (uint64_t)addr[address+2] << 16;
+ value += (uint64_t)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 (opcode == ORA || opcode == 0x39 || opcode == 0x3B)
+ cpu->a[thread] |= value;
+ if (opcode == ORY || opcode == 0x62 || opcode == 0x92)
+ cpu->y[thread] |= value;
+ if (opcode == ORX || opcode == 0x64 || opcode == 0x94)
+ cpu->x[thread] |= value;
+ cpu->z[thread] = (value == 0);
+ cpu->n[thread] = (value >> 63);
+ (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread));
+ (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
+ break;
case OAY:
case OAX:
if (opcode == OAY)
@@ -339,8 +500,6 @@ void *run(void *args) {
cpu->i[thread] = 1;
(cpu->ps |= (I << 8*thread));
break;
- case 0x39: or_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* ORA Absolute. */
- case 0x3B: or_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* ORA Zero Matrix. */
case BNG: /* Branch if NeGative. */
address = (uint64_t)addr[cpu->pc[thread]]
| (uint64_t)addr[cpu->pc[thread]+1] << 8
@@ -355,8 +514,63 @@ void *run(void *args) {
if (!cpu->n[thread])
cpu->pc[thread] = address;
break;
- case XOR: xor_addr(cpu, &cpu->a[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* XOR Immediate. */
- case XRY: xor_addr(cpu, &cpu->y[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* XRY Immediate. */
+ case XOR: /* XOR Immediate. */
+ case 0x49: /* XOR Absolute. */
+ case 0x4B: /* XOR Zero Matrix. */
+ case XRY: /* XRY Immediate. */
+ case 0x72: /* XRY Absolute. */
+ case 0xA2: /* XRY Zero Matrix. */
+ case XRX: /* XRX Immediate. */
+ case 0x74: /* XRX Absolute. */
+ case 0xA4: /* XRX Zero Matrix. */
+ if (opcode == XOR || opcode == XRY || opcode == XRX) {
+ address = cpu->pc[thread];
+ cpu->pc[thread]+=regsize;
+ }
+ if (opcode == 0x49 || opcode == 0x72 || opcode == 0x74) {
+ address = (uint64_t)addr[cpu->pc[thread]]
+ | (uint64_t)addr[cpu->pc[thread]+1] << 8
+ | (uint64_t)addr[cpu->pc[thread]+2] << 16
+ | (uint64_t)addr[cpu->pc[thread]+3] << 24
+ | (uint64_t)addr[cpu->pc[thread]+4] << 32
+ | (uint64_t)addr[cpu->pc[thread]+5] << 40
+ | (uint64_t)addr[cpu->pc[thread]+6] << 48
+ | (uint64_t)addr[cpu->pc[thread]+7] << 56;
+ cpu->pc[thread]+=8;
+ iclk++;
+ }
+ if (opcode == 0x4B || opcode == 0xA2 || opcode == 0xA4) {
+ address = addr[cpu->pc[thread]]
+ | addr[cpu->pc[thread]+1] << 8
+ | addr[cpu->pc[thread]+2] << 16
+ | addr[cpu->pc[thread]+3] << 24;
+ cpu->pc[thread]+=4;
+ iclk++;
+ }
+ value = (uint64_t)addr[address];
+ if (regsize >= 2)
+ value += (uint64_t)addr[address+1] << 8;
+ if (regsize >= 4) {
+ value += (uint64_t)addr[address+2] << 16;
+ value += (uint64_t)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 (opcode == XOR || opcode == 0x49 || opcode == 0x4B)
+ cpu->a[thread] ^= value;
+ if (opcode == ORY || opcode == 0x72 || opcode == 0xA2)
+ cpu->y[thread] ^= value;
+ if (opcode == ORX || opcode == 0x74 || opcode == 0xA4)
+ cpu->x[thread] ^= value;
+ cpu->z[thread] = (value == 0);
+ cpu->n[thread] = (value >> 63);
+ (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread));
+ (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
+ break;
case XAY:
case XAX:
if (opcode == XAY)
@@ -368,13 +582,10 @@ void *run(void *args) {
(cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread));
(cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
break;
- case XRX: xor_addr(cpu, &cpu->x[thread], immaddr(cpu, thread, regsize), thread, regsize); break; /* XRX Immediate. */
case CLI: /* CLear Interrupt. */
cpu->i[thread] = 0;
(cpu->ps &= ~(I << 8*thread));
break;
- case 0x49: xor_addr(cpu, &cpu->a[thread], absaddr(cpu, thread), thread, regsize); break; /* XOR Absolute. */
- case 0x4B: xor_addr(cpu, &cpu->a[thread], zeromtx(cpu, thread), thread, regsize); break; /* XOR Zero Matrix. */
case BCS: /* Branch if Carry Set. */
address = (uint64_t)addr[cpu->pc[thread]]
| (uint64_t)addr[cpu->pc[thread]+1] << 8
@@ -427,8 +638,6 @@ void *run(void *args) {
(cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
(cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread));
break;
- case 0x52: and_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* ANY Absolute. */
- case 0x54: and_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* ANX Absolute. */
case SEC: /* SEt Carry flag.*/
cpu->c[thread] = 1;
(cpu->ps |= (C << 8*thread));
@@ -439,6 +648,10 @@ void *run(void *args) {
case 0x7B: /* STA Zero Matrix. */
case 0x7D: /* STY Zero Matrix. */
case 0x7E: /* STX Zero Matrix. */
+ case 0x8B: /* STA Zero Matrix, Indexed with X. */
+ case 0x8D: /* STY Zero Matrix, Indexed with X. */
+ case 0x9B: /* STA Zero Matrix, Indexed with Y. */
+ case 0x9E: /* STX Zero Matrix, Indexed with Y. */
if (opcode == STA || opcode == STY || opcode == STX) {
address = (uint64_t)addr[cpu->pc[thread]]
| (uint64_t)addr[cpu->pc[thread]+1] << 8
@@ -451,11 +664,15 @@ void *run(void *args) {
cpu->pc[thread]+=8;
iclk++;
}
- if (opcode == 0x7B || opcode == 0x7D || opcode == 0x7E) {
+ if (opcode == 0x7B || opcode == 0x7D || opcode == 0x7E || opcode == 0x8B || opcode == 0x8D || opcode == 0x9B || opcode == 0x9E) {
address = addr[cpu->pc[thread]]
| addr[cpu->pc[thread]+1] << 8
| addr[cpu->pc[thread]+2] << 16
| addr[cpu->pc[thread]+3] << 24;
+ if (opcode == 0x8B || opcode == 0x8D)
+ address += cpu->x[thread];
+ if (opcode == 0x9B || opcode == 0x9E)
+ address += cpu->y[thread];
cpu->pc[thread]+=4;
iclk++;
}
@@ -531,8 +748,6 @@ void *run(void *args) {
(cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
(cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread));
break;
- case 0x62: or_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* ORY Absolute. */
- case 0x64: or_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* ORX Absolute. */
case CLC: /* CLear Carry flag. */
cpu->c[thread] = 0;
(cpu->ps &= ~(C << 8*thread));
@@ -546,6 +761,10 @@ void *run(void *args) {
case 0x79: /* LDA Zero Matrix. */
case 0x7A: /* LDY Zero Matrix. */
case 0x7C: /* LDX Zero Matrix. */
+ case 0x89: /* LDA Zero Matrix, Indexed with X. */
+ case 0x8A: /* LDY Zero Matrix, Indexed with X. */
+ case 0x99: /* LDA Zero Matrix, Indexed with Y. */
+ case 0x9C: /* LDX Zero Matrix, Indexed with Y. */
if (opcode == LDA || opcode == LDY || opcode == LDX) {
address = cpu->pc[thread];
cpu->pc[thread]+=regsize;
@@ -562,11 +781,15 @@ void *run(void *args) {
cpu->pc[thread]+=8;
iclk++;
}
- if (opcode == 0x79 || opcode == 0x7A || opcode == 0x7C) {
+ if (opcode == 0x79 || opcode == 0x7A || opcode == 0x7C || opcode == 0x89 || opcode == 0x8A || opcode == 0x99 || opcode == 0x9C) {
address = addr[cpu->pc[thread]]
| addr[cpu->pc[thread]+1] << 8
| addr[cpu->pc[thread]+2] << 16
| addr[cpu->pc[thread]+3] << 24;
+ if (opcode == 0x89 || opcode == 0x8A)
+ address += cpu->x[thread];
+ if (opcode == 0x99 || opcode == 0x9C)
+ address += cpu->y[thread];
cpu->pc[thread]+=4;
iclk++;
}
@@ -646,8 +869,6 @@ void *run(void *args) {
(cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
(cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread));
break;
- case 0x72: xor_addr(cpu, &cpu->y[thread], absaddr(cpu, thread), thread, regsize); break; /* XRY Absolute. */
- case 0x74: xor_addr(cpu, &cpu->x[thread], absaddr(cpu, thread), thread, regsize); break; /* XRX Absolute. */
case SSP: /* Set Stack Protection flag. */
cpu->s[thread] = 1;
(cpu->ps |= (S << 8*thread));
@@ -704,16 +925,10 @@ void *run(void *args) {
(cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
(cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread));
break;
- case 0x82: and_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* ANY Zero Matrix. */
- case 0x84: and_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* ANX Zero Matrix. */
case CSP: /* Clear Stack Protection flag. */
cpu->s[thread] = 0;
(cpu->ps &= ~(S << 8*thread));
break;
- case 0x89: ld(cpu, &cpu->a[thread], zeromx(cpu, thread), thread, regsize); break; /* LDA Zero Matrix, Indexed with X. */
- case 0x8A: ld(cpu, &cpu->y[thread], zeromx(cpu, thread), thread, regsize); break; /* LDY Zero Matrix, Indexed with X. */
- case 0x8B: st(cpu, &cpu->a[thread], zeromx(cpu, thread), thread, regsize); break; /* STA Zero Matrix, Indexed with X. */
- case 0x8D: st(cpu, &cpu->y[thread], zeromx(cpu, thread), thread, regsize); break; /* STY Zero Matrix, Indexed with X. */
case BVS: /* Branch if oVerflow Set. */
address = (uint64_t)addr[cpu->pc[thread]]
| (uint64_t)addr[cpu->pc[thread]+1] << 8
@@ -728,19 +943,62 @@ void *run(void *args) {
if (cpu->v[thread])
cpu->pc[thread] = address;
break;
- case MUL: mul(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* MUL Immediate. */
- case 0x92: or_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* ORY Zero Matrix. */
- case 0x93: mul(cpu, absaddr(cpu, thread), thread, regsize); break; /* MUL Absolute. */
- case 0x94: or_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* ORX Zero Matrix. */
- case 0x95: mul(cpu, zeromtx(cpu, thread), thread, regsize); break; /* MUL Zero Matrix. */
+ case MUL: /* MUL Immediate. */
+ case 0x93: /* MUL Absolute. */
+ case 0x95: /* MUL Zero Matrix. */
+ if (opcode == MUL) {
+ address = cpu->pc[thread];
+ cpu->pc[thread]++;
+ }
+ if (opcode == 0x93) {
+ address = (uint64_t)addr[cpu->pc[thread]]
+ | (uint64_t)addr[cpu->pc[thread]+1] << 8
+ | (uint64_t)addr[cpu->pc[thread]+2] << 16
+ | (uint64_t)addr[cpu->pc[thread]+3] << 24
+ | (uint64_t)addr[cpu->pc[thread]+4] << 32
+ | (uint64_t)addr[cpu->pc[thread]+5] << 40
+ | (uint64_t)addr[cpu->pc[thread]+6] << 48
+ | (uint64_t)addr[cpu->pc[thread]+7] << 56;
+ cpu->pc[thread]+=8;
+ iclk++;
+ }
+ if (opcode == 0x95) {
+ address = addr[cpu->pc[thread]]
+ | addr[cpu->pc[thread]+1] << 8
+ | addr[cpu->pc[thread]+2] << 16
+ | addr[cpu->pc[thread]+3] << 24;
+ cpu->pc[thread]+=4;
+ iclk++;
+ }
+ value = addr[address];
+ if (regsize >= 2) {
+ value += (uint64_t)addr[address+1] << 8;
+ }
+ if (regsize >= 4) {
+ value += (uint64_t)addr[address+2] << 16;
+ value += (uint64_t)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;
+ }
+ sum = cpu->a[thread]*value+cpu->c[thread];
+ cpu->a[thread] = sum;
+ cpu->z[thread] = (sum == 0);
+ cpu->n[thread] = (sum >> 63);
+ cpu->v[thread] = !((cpu->a[thread]^value) & 0x8000000000000000) && ((cpu->a[thread]^sum) & 0x8000000000000000);
+ cpu->c[thread] = (!((cpu->a[thread]^sum) && (cpu->a[thread]^value)) && (cpu->a[thread] >= ((uint64_t)1 << 32) && value >= ((uint64_t)1 << 32)));
+ (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread));
+ (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
+ (cpu->v[thread]) ? (cpu->ps |= (V << 8*thread)) : (cpu->ps &= ~(V << 8*thread));
+ (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread));
+ break;
case SEV: /* SEt oVerflow flag. */
cpu->v[thread] = 1;
(cpu->ps |= (V << 8*thread));
break;
- case 0x99: ld(cpu, &cpu->a[thread], zeromy(cpu, thread), thread, regsize); break; /* LDA Zero Matrix, Indexed with Y. */
- case 0x9B: ld(cpu, &cpu->x[thread], zeromy(cpu, thread), thread, regsize); break; /* STA Zero Matrix, Indexed with Y. */
- case 0x9C: st(cpu, &cpu->a[thread], zeromy(cpu, thread), thread, regsize); break; /* LDX Zero Matrix, Indexed with Y. */
- case 0x9E: st(cpu, &cpu->x[thread], zeromy(cpu, thread), thread, regsize); break; /* STX Zero Matrix, Indexed with Y. */
case BVC: /* Branch if oVerflow Clear. */
address = (uint64_t)addr[cpu->pc[thread]]
| (uint64_t)addr[cpu->pc[thread]+1] << 8
@@ -755,20 +1013,70 @@ void *run(void *args) {
if (!cpu->v[thread])
cpu->pc[thread] = address;
break;
- case DIV: divd(cpu, immaddr(cpu, thread, regsize), thread, regsize); break; /* DIV Immediate. */
- case 0xA2: xor_addr(cpu, &cpu->y[thread], zeromtx(cpu, thread), thread, regsize); break; /* XRY Zero Matrix. */
- case 0xA3: divd(cpu, absaddr(cpu, thread), thread, regsize); break; /* DIV Absolute. */
- case 0xA4: xor_addr(cpu, &cpu->x[thread], zeromtx(cpu, thread), thread, regsize); break; /* XRX Zero Matrix. */
- case 0xA5: divd(cpu, zeromtx(cpu, thread), thread, regsize); break; /* DIV Zero Matrix. */
+ case DIV: /* DIV Immediate. */
+ case 0xA3: /* DIV Absolute. */
+ case 0xA5: /* DIV Zero Matrix. */
+ if (opcode == DIV) {
+ address = cpu->pc[thread];
+ cpu->pc[thread]++;
+ }
+ if (opcode == 0xA3) {
+ address = (uint64_t)addr[cpu->pc[thread]]
+ | (uint64_t)addr[cpu->pc[thread]+1] << 8
+ | (uint64_t)addr[cpu->pc[thread]+2] << 16
+ | (uint64_t)addr[cpu->pc[thread]+3] << 24
+ | (uint64_t)addr[cpu->pc[thread]+4] << 32
+ | (uint64_t)addr[cpu->pc[thread]+5] << 40
+ | (uint64_t)addr[cpu->pc[thread]+6] << 48
+ | (uint64_t)addr[cpu->pc[thread]+7] << 56;
+ cpu->pc[thread]+=8;
+ iclk++;
+ }
+ if (opcode == 0xA5) {
+ address = addr[cpu->pc[thread]]
+ | addr[cpu->pc[thread]+1] << 8
+ | addr[cpu->pc[thread]+2] << 16
+ | addr[cpu->pc[thread]+3] << 24;
+ cpu->pc[thread]+=4;
+ iclk++;
+ }
+ value = addr[address];
+ if (regsize >= 2) {
+ value += (uint64_t)addr[address+1] << 8;
+ }
+ if (regsize >= 4) {
+ value += (uint64_t)addr[address+2] << 16;
+ value += (uint64_t)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;
+ }
+ sum = cpu->a[thread]/value;
+ cpu->a[thread] = sum;
+ cpu->z[thread] = (sum == 0);
+ cpu->n[thread] = (sum >> 63);
+ (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread));
+ (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
+ break;
case CLV: /* CLear oVerflow flag. */
cpu->v[thread] = 0;
(cpu->ps &= ~(V << 8*thread));
break;
case RTS: /* ReTurn from Subroutine. */
- cpu->pc[thread] = (uint64_t)pull(cpu);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 8);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 16);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 24) + 1;
+ for (uint8_t i = 0; i < 32; i+=8) {
+ cpu->sp++;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
+ if (i < 24)
+ cpu->pc[thread] += addr[STK_STADDR+cpu->sp] << i;
+ else if (i == 24)
+ cpu->pc[thread] += addr[STK_STADDR+cpu->sp] << i +1;
+ else
+ cpu->pc[thread] = addr[STK_STADDR+cpu->sp];
+ }
break;
case CMP: /* CMP Immediate. */
case CPY: /* CPY Immediate. */
@@ -779,8 +1087,10 @@ void *run(void *args) {
case 0xF2: /* CPY Zero Matrix. */
case 0xF4: /* CPX Zero Matrix. */
case 0xF5: /* CMP Zero Matrix. */
- if (opcode == CMP || opcode == CPY || opcode == CPX)
- address = immaddr(cpu, thread, regsize);
+ if (opcode == CMP || opcode == CPY || opcode == CPX) {
+ address = cpu->pc[thread];
+ cpu->pc[thread]++;
+ }
if (opcode == 0xE5 || opcode == 0xE2 || opcode == 0xE4) {
address = (uint64_t)addr[cpu->pc[thread]]
| (uint64_t)addr[cpu->pc[thread]+1] << 8
@@ -843,17 +1153,29 @@ void *run(void *args) {
(cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
(cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread));
break;
- case ENT: ent(cpu, immaddr(cpu, thread, 1)); break; /* ENd Thread. */
+ case ENT: /* ENd Thread. */
+ value = addr[address];
+ cpu->crt &= ~value;
+ for (uint8_t i = 0; i < 7; i++)
+ if ((value >> i) & 1)
+ cpu->pc[i+1] = cpu->pc[0]+(i+1);
+ break;
case RTI: /* ReTurn from Interupt routine. */
- cpu->ps = ((uint64_t)pull(cpu) << 8*thread);
- cpu->pc[thread] = (uint64_t)pull(cpu);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 8);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 16);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 24);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 32);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 40);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 48);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 56);
+ cpu->sp++;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
+ cpu->ps = addr[STK_STADDR+cpu->sp] << 8*thread;
+ for (uint8_t i = 0; i < 64; i+=8) {
+ cpu->sp++;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
+ if (i < 56)
+ cpu->pc[thread] += addr[STK_STADDR+cpu->sp] << i;
+ else if (i == 56)
+ cpu->pc[thread] += addr[STK_STADDR+cpu->sp] << i +1;
+ else
+ cpu->pc[thread] = addr[STK_STADDR+cpu->sp];
+ }
break;
case INC: /* INC Accumulator. */
case INY:
@@ -921,14 +1243,15 @@ void *run(void *args) {
| (uint64_t)addr[cpu->pc[thread]+6] << 48
| (uint64_t)addr[cpu->pc[thread]+7] << 56;
cpu->pc[thread]+=8;
- push(cpu, (uint64_t)cpu->pc[thread] >> 56);
- push(cpu, (uint64_t)cpu->pc[thread] >> 48);
- push(cpu, (uint64_t)cpu->pc[thread] >> 40);
- push(cpu, (uint64_t)cpu->pc[thread] >> 32);
- push(cpu, (uint64_t)cpu->pc[thread] >> 24);
- push(cpu, (uint64_t)cpu->pc[thread] >> 16);
- push(cpu, (uint64_t)cpu->pc[thread] >> 8);
- push(cpu, (uint64_t)cpu->pc[thread] & 0xFF);
+ for (int8_t i = 56; i >= 0; i-=8) {
+ if (i)
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->pc[thread] >> i;
+ else
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->pc[thread] & 0xFF;
+ cpu->sp--;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
+ }
cpu->pc[thread] = address;
break;
case 0xE1: /* INC Absolute. */
@@ -955,16 +1278,20 @@ void *run(void *args) {
}
addr[address]++;
break;
- case NOP: break; /* No OPeration. */
+ case NOP: /* No OPeration. */
+ break;
case RTL: /* ReTurn from subroutine Long. */
- cpu->pc[thread] = (uint64_t)pull(cpu);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 8);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 16);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 24);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 32);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 40);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 48);
- cpu->pc[thread] += ((uint64_t)pull(cpu) << 56) + 1;
+ for (uint8_t i = 0; i < 64; i+=8) {
+ cpu->sp++;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
+ if (i < 56)
+ cpu->pc[thread] = addr[STK_STADDR+cpu->sp] << i;
+ else if (i == 56)
+ cpu->pc[thread] = addr[STK_STADDR+cpu->sp] << i + 1;
+ else
+ cpu->pc[thread] = addr[STK_STADDR+cpu->sp];
+ }
break;
case 0xF1: /* DEC Absolute. */
case 0xF3: /* DEC Zero Matrix. */
@@ -991,15 +1318,19 @@ void *run(void *args) {
addr[address]--;
break;
case BRK: /* BReaK. */
- push(cpu, (uint64_t)cpu->pc[thread]-1 >> 56);
- push(cpu, (uint64_t)cpu->pc[thread]-1 >> 48);
- push(cpu, (uint64_t)cpu->pc[thread]-1 >> 40);
- push(cpu, (uint64_t)cpu->pc[thread]-1 >> 32);
- push(cpu, (uint64_t)cpu->pc[thread]-1 >> 24);
- push(cpu, (uint64_t)cpu->pc[thread]-1 >> 16);
- push(cpu, (uint64_t)cpu->pc[thread]-1 >> 8);
- push(cpu, (uint64_t)cpu->pc[thread]-1 & 0xFF);
- push(cpu, (uint64_t)cpu->ps >> 8*thread);
+ for (uint8_t i = 56; i >= 0; i-=8) {
+ if (i)
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->pc[thread]-1 >> i;
+ else
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->pc[thread]-1 & 0xFF;
+ cpu->sp--;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
+ }
+ addr[STK_STADDR+cpu->sp] = (uint64_t)cpu->ps >> 8*thread;
+ cpu->sp--;
+ addr[0xFF90] = cpu->sp & 0xFF;
+ addr[0xFF91] = cpu->sp >> 8;
cpu->i[thread] = 1;
setps(cpu, thread);
cpu->pc[thread] = (uint64_t)addr[0xFFE0]
@@ -1010,6 +1341,7 @@ void *run(void *args) {
| (uint64_t)addr[0xFFE5] << 40
| (uint64_t)addr[0xFFE6] << 48
| (uint64_t)addr[0xFFE7] << 56;
+ break;
default:
if(opcode != BRK) {
printf("Cool, you inputed a non existent opcode, which means\n"
@@ -1019,13 +1351,6 @@ void *run(void *args) {
break;
}
ins++;
- /*if (ins % 50000000 == 0) {
- int r = pthread_barrier_wait(&bar);
- if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) {
- printf("oof, throds not sinking.\n");
- exit(-1);
- }
- }*/
#if !bench
printf("\033[%uHInstructions executed: %llu, Clock cycles: %llu\n", (6*thread)+1, ins, iclk);
fflush(stdout);
@@ -1043,7 +1368,6 @@ void *run(void *args) {
#endif
}
}
- /*return 1;*/
}
int main(int argc, char **argv) {
@@ -1131,7 +1455,6 @@ int main(int argc, char **argv) {
}
clkspd = (ttm/1000000)*1000000/tclk;
mhz = 1000000.0/clkspd/1000000;
- /*printf("\033[2J");*/
printf("Total Instructions executed: %llu, Total Instructions per Second in MIPS: %f, Clock cycles: %llu, Clock Speed in MHz: %f, tm: %f\n", inss, ipst, tclk, mhz, ttm/1000000);
}
#endif
diff --git a/test/test-stack.s b/test/test-stack.s
new file mode 100644
index 0000000..e31e343
--- /dev/null
+++ b/test/test-stack.s
@@ -0,0 +1,7 @@
+cps
+iax
+pha #$8
+ply #$8
+jmp $1
+done
+