From 02326aab063553d9b32f19ea59502fe745456178 Mon Sep 17 00:00:00 2001 From: Daniel Jones Date: Wed, 19 Aug 2020 23:08:29 +0930 Subject: implemented more instructions these instructions are mostly untested at the moment, i need to test them --- chip8.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/chip8.c b/chip8.c index f005de8..32803bb 100644 --- a/chip8.c +++ b/chip8.c @@ -173,7 +173,7 @@ chip8_cycle() draw_flag = 1; break; case 0x00EE: /* ret (return from subroutine) */ - // TODO: test, check for out of bounds? + stack[SP] = 0x0; PC = stack[--SP]; break; default: unknown_opcode(opcode); @@ -184,10 +184,24 @@ chip8_cycle() PC = nnn; break; case 0x2000: /* CALL addr (call subroutine at addr, increment SP and put current PC on top of stack, set PC to nnn) */ - // TODO: test, bounds check? stack[SP++] = PC; PC = nnn; break; + case 0x3000: /* SE Vx, byte (skip next instruction if Vx = kk) */ + // TODO: not tested + if (V[x] == kk) + PC += 2; + break; + case 0x4000: /* SN Vx, byte (skip next instruction if Vx != kk) */ + // TODO: not tested + if (V[x] != kk) + PC += 2; + break; + case 0x5000: /* SE Vx, Vy (skip next instruction if Vx == Vy) */ + // TODO: not tested + if (V[x] == V[y]) + PC += 2; + break; case 0x6000: /* LD Vx, byte (load byte in register x) */ { V[x] = kk; @@ -196,9 +210,61 @@ chip8_cycle() case 0x7000: /* ADD Vx, byte (add byte to Vx and store result in Vx) */ V[x] = V[x] + kk; break; - case 0x8000: /* LD Vx, Vy (load Vy into Vx register) */ - V[x] = V[y]; - break; + case 0x8000: /* math */ + { + switch (n) + { + case 0x00: /* LD Vx, Vy (load Vy into Vx register) */ + // TODO: not tested + V[x] = V[y]; + break; + case 0x01: /* OR Vx, Vy (XOR Vx with Vy and store the result in Vx) */ + // TODO: not tested + V[x] |= V[y]; + break; + case 0x02: /* AND Vx, Vy (AND Vx with Vy and store the result in Vx) */ + // TODO: not tested + V[x] &= V[y]; + break; + case 0x03: /* XOR Vx, Vy (XOR Vx with Vy and store the result in Vx) */ + // TODO: not tested + V[x] ^= V[y]; + break; + case 0x04: /* ADD Vx, Vy (add Vx to Vy, store in Vx, if > 255 set V[F] 1, otherwise 0, Vx = lower 4 bits) */ + // TODO: not tested + { + V[0xF] = 0; + uint16_t res = V[x] + V[y]; + if (res > 0xFF) + { + res &= 0xFF; + V[0xF] = 1; + } + V[x] = res; + break; + } + case 0x05: /* SUB Vx, Vy (subtract Vx from Vy, store in Vx, if Vx > Vy set V[F] 1, otherwise 0 */ + // TODO: not tested + V[0xF] = (V[x] > V[y]) ? 1 : 0; + V[x] -= V[y]; + break; + case 0x06: /* SHR Vx (if the least significant bit of Vx is 1, V[F] set to 1, otherwise 0, then Vx is divided by 2 */ + // TODO: not tested + V[0xF] = V[x] & 0x01; + V[x] >>= 1; + break; + case 0x07: /* SUBN Vx, Vy (if Vy > Vx then set V[F] 1 otherwise 0, then Vx is subtracted from Vy, result stored in Vx */ + V[0xF] = (V[y] > V[x]) ? 1 : 0; + V[x] = V[y] - V[x]; + break; + case 0x0E: /* SHL Vx (if the most significant bit of Vx is 1, V[F] set to 1, otherwise 0, then Vx is multiplied by 2 */ + // TODO: not tested + V[0xF] = (V[x] >> 7) & 0x01; + V[x] <<= 1; + break; + default: unknown_opcode(opcode); + } + } default: unknown_opcode(opcode); } -- cgit v1.2.3