From 3182c7bc242f21a1f91b5921df93a4bb28c51382 Mon Sep 17 00:00:00 2001 From: strzelca Date: Thu, 4 Jan 2024 07:57:23 +0100 Subject: [PATCH] Added _SUB, _MUL, _DIV --- lib/cpu.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- lib/isa.c | 42 ++++++++++++++++++++++++---- lib/isa.h | 5 ++++ main.c | 9 +++++- 4 files changed, 130 insertions(+), 8 deletions(-) diff --git a/lib/cpu.c b/lib/cpu.c index b987c38..8205067 100644 --- a/lib/cpu.c +++ b/lib/cpu.c @@ -25,8 +25,8 @@ void destroy_cpu(cpu_t *cpu) { void print_cpu_status(const cpu_t *cpu) { printf("CPU STATUS\n"); - printf("A -> 0x%04x\n", cpu->A); - printf("B -> 0x%04x\n", cpu->B); + printf("A -> 0x%04x (%hi)\n", cpu->A, cpu->A); + printf("B -> 0x%04x (%d)\n", cpu->B, cpu->B); printf("PC -> 0x%04x\n", cpu->PC); printf("FLAGS -> 0x%08x\n", cpu->flags.flags); } @@ -157,6 +157,84 @@ void fde(cpu_t *cpu, const mem_t *mem) { } _SUB(R1, R2, R3, (uint32_t*) &cpu->flags); break; + case MUL: + // reg, v1, v2 + switch (mem->mem[cpu->PC++]) { + case REGA: + R1 = &cpu->A; + break; + case REGB: + R1 = &cpu->B; + break; + default: + illegal_instruction(cpu, mem); + break; + } + switch (mem->mem[cpu->PC++]) { + case REGA: + R2 = &cpu->A; + break; + case REGB: + R2 = &cpu->B; + break; + default: + V1 = mem->mem[cpu->PC-1]; + R2 = &V1; + break; + } + switch (mem->mem[cpu->PC++]) { + case REGA: + R3 = &cpu->A; + break; + case REGB: + R3 = &cpu->B; + break; + default: + V2 = mem->mem[cpu->PC-1]; + R3 = &V2; + break; + } + _MUL(R1, R2, R3, (uint32_t*) &cpu->flags); + break; + case DIV: + // reg, v1, v2 + switch (mem->mem[cpu->PC++]) { + case REGA: + R1 = &cpu->A; + break; + case REGB: + R1 = &cpu->B; + break; + default: + illegal_instruction(cpu, mem); + break; + } + switch (mem->mem[cpu->PC++]) { + case REGA: + R2 = &cpu->A; + break; + case REGB: + R2 = &cpu->B; + break; + default: + V1 = mem->mem[cpu->PC-1]; + R2 = &V1; + break; + } + switch (mem->mem[cpu->PC++]) { + case REGA: + R3 = &cpu->A; + break; + case REGB: + R3 = &cpu->B; + break; + default: + V2 = mem->mem[cpu->PC-1]; + R3 = &V2; + break; + } + _DIV(R1, R2, R3, (uint32_t*) &cpu->flags); + break; case NUL: illegal_instruction(cpu, mem); break; diff --git a/lib/isa.c b/lib/isa.c index b5850a6..5d85d1d 100644 --- a/lib/isa.c +++ b/lib/isa.c @@ -12,6 +12,7 @@ void _MOV(uint16_t* dst, const uint16_t _n) { } void _ADD(uint16_t* dst, const uint16_t *v1, const uint16_t *v2, uint32_t *flags) { + uint16_t _v1 = *v1; *flags = 0; *flags = *v1 & *v2; *dst = *v1 ^ *v2; @@ -23,15 +24,46 @@ void _ADD(uint16_t* dst, const uint16_t *v1, const uint16_t *v2, uint32_t *flags *dst = *dst ^ carry; } - if (*dst <= *v2 && ~*v2 < *v2 ) *flags ^= 1 << 0x8; - + // detect overflow + if(*dst > 0 && *dst < 0x7FFF && _v1 > 0x7FFF) *flags ^= 1 << 0x8; if (*dst >> 15 == 1) *flags ^= 1 << 0x10; - if (*dst == 0) *flags ^= 1 << 0x18; } +void _INC(uint16_t* dst, uint32_t *flags) { + uint16_t _d = *dst; + *flags = 0; + *flags = *dst & 1; + *dst = *dst ^ 1; + + + while (*flags != 0){ + uint32_t carry = *flags << 1; + *flags = *dst & carry; + *dst = *dst ^ carry; + } + + if (*dst > 0 && *dst < 0x7FFF && _d > 0x7FFF) *flags ^= 1 << 0x8; + if (*dst >> 15) *flags ^= 1 << 0x10; + if (!*dst) *flags ^= 1 << 0x18; +} + void _SUB(uint16_t* dst, const uint16_t *v1, uint16_t *v2, uint32_t *flags) { - *v2 = ~*v2 + 1; - _ADD(dst, v1, v2, flags); + uint16_t _v2 = ~*v2 + 1; + _ADD(dst, v1, &_v2, flags); +} + +void _MUL(uint16_t* dst, const uint16_t *v1, uint16_t *v2, uint32_t *flags) { + while((*v2)--) _ADD(dst, dst, v1, flags); +} + +void _DIV(uint16_t* dst, uint16_t *v1, uint16_t *v2, uint32_t *flags) { + uint32_t _save_flags; + while(*v1 > 0 || ((*flags >> 0x10) & 0x001) == 1 && (*flags >> 0x18) == 1) { + _SUB(v1, v1, v2, flags); + _save_flags = *flags; + _INC(dst, flags); + *flags = _save_flags; + } } \ No newline at end of file diff --git a/lib/isa.h b/lib/isa.h index f129122..58e239c 100644 --- a/lib/isa.h +++ b/lib/isa.h @@ -13,6 +13,8 @@ #define MOV 0x0001 #define ADD 0x0002 #define SUB 0x0003 +#define MUL 0x0004 +#define DIV 0x0005 #define HLT 0xFAFB #define NUL 0x0000 @@ -21,6 +23,9 @@ void _MOV(uint16_t* dst, uint16_t _n); void _ADD(uint16_t* dst, const uint16_t *v1, const uint16_t *v2, uint32_t *flags); void _SUB(uint16_t* dst, const uint16_t *v1, uint16_t *v2, uint32_t *flags); +void _MUL(uint16_t* dst, const uint16_t *v1, uint16_t *v2, uint32_t *flags); +void _DIV(uint16_t* dst, uint16_t *v1, uint16_t *v2, uint32_t *flags); + #endif //ISA_H diff --git a/main.c b/main.c index dfe6c31..ebfba18 100644 --- a/main.c +++ b/main.c @@ -2,6 +2,7 @@ #include "lib/logicb.h" #include "lib/cpu.h" +#include "lib/isa.h" int main() { logic_b_t *logicb = new_logicb(); @@ -9,7 +10,13 @@ int main() { print_logicb(logicb); - const uint16_t prog[] = {0x0001, 0xAFFF, 0x0008, 0x0002, 0xBFFF, 0xAFFF, 0x0008, 0x0003, 0xAFFF, 0xAFFF, 0x0009, 0x0002, 0xAFFF, 0xAFFF, 0x0001, 0xFAFB}; + const uint16_t prog[] = { + ADD, REGA, REGA, 0x0008, + DIV, REGB, REGA, 0x0004, + SUB, REGA, REGA, 0x0004, + ADD, REGA, REGA, 0x0008, + 0xFAFB + }; memcpy(logicb->mem->mem, prog, sizeof(prog));