diff options
author | mrb0nk500 <b0nk@b0nk.xyz> | 2019-12-06 17:25:13 -0500 |
---|---|---|
committer | mrb0nk500 <b0nk@b0nk.xyz> | 2019-12-06 17:28:03 -0500 |
commit | 8d0f46d4e62af5d66ff3cce872256163a41b54bf (patch) | |
tree | afe1b4a1b7de11db68e7329237cffb44bf1c5661 | |
parent | b4f547ecb600729e0e1b980c27c154b2a99bbca1 (diff) |
Delete opcode.c, since I added all the functions
from it into sux.c.
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | opcode.c | 242 | ||||
-rw-r--r-- | sux.c | 579 | ||||
-rw-r--r-- | test/test-stack.s | 7 |
4 files changed, 459 insertions, 373 deletions
@@ -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; -} @@ -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 + |