summaryrefslogtreecommitdiff
path: root/chip8.c
diff options
context:
space:
mode:
authorDaniel Jones <admin@danieljon.es>2020-08-19 16:29:58 +0930
committerDaniel Jones <admin@danieljon.es>2020-08-19 16:30:13 +0930
commit26653bc8ac93cb748b46dae933b60fa755e400b1 (patch)
tree0820482c21f76c8db44899f3e742ad4ddd8582d7 /chip8.c
parentd64874fc4e50f22ecb5aa669abfe5d5a7931255a (diff)
downloadchip8-26653bc8ac93cb748b46dae933b60fa755e400b1.tar.gz
chip8-26653bc8ac93cb748b46dae933b60fa755e400b1.zip
instructions and debugging features
added some more instructions, particularly calling and returning from subroutines using the stack. also added stepping through the program using the '.' key to advance one cycle
Diffstat (limited to 'chip8.c')
-rw-r--r--chip8.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/chip8.c b/chip8.c
index 1d8de29..f005de8 100644
--- a/chip8.c
+++ b/chip8.c
@@ -133,7 +133,7 @@ chip8_beep()
void
unknown_opcode(uint16_t bad_opcode)
{
- fprintf(stderr, "unknown opcode: 0x%02X at 0x%02X\n", bad_opcode, PC);
+ fprintf(stderr, "unknown opcode: 0x%02X at 0x%02X\n", bad_opcode, PC-2); // minus 2 because we increment PC by 2 at the start of decoding
}
void
chip8_cycle()
@@ -145,7 +145,7 @@ chip8_cycle()
/*
* the opcode is a 2 byte value, while our memory is 1 byte
* so to get our opcode we need to combine 2 bytes located at PC and PC+1
- * we right shift the first byte by 8 (1 byte) to place it in the high byte
+ * we left shift the first byte by 8 (1 byte) to place it in the high byte
* and we store the second byte in the lower byte
*/
opcode = (memory[PC] << 8) | memory[PC+1];
@@ -155,7 +155,8 @@ chip8_cycle()
uint8_t x = (opcode >> 8) & 0x000F; // lower 4 bits of the high byte, we discard the low byte by right shifting it out
uint8_t y = (opcode >> 4) & 0x000F; // upper 4 bits of the low byte, so we need to discard the lower 4 bits
uint8_t kk = opcode & 0x00FF; // lowest 8 bits
-
+ printf("parsing at 0x%03X\n", PC);
+ PC += 2; // TODO: remove
switch (opcode & 0xF000)
{
/*
@@ -172,17 +173,32 @@ chip8_cycle()
draw_flag = 1;
break;
case 0x00EE: /* ret (return from subroutine) */
+ // TODO: test, check for out of bounds?
+ PC = stack[--SP];
break;
default: unknown_opcode(opcode);
}
break;
}
+ case 0x1000: /*JP addr (jump to memory address nnn) */
+ 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 0x6000: /* LD Vx, byte (load byte in register x) */
{
V[x] = kk;
break;
}
-
+ 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;
default: unknown_opcode(opcode);
}
@@ -194,5 +210,4 @@ chip8_cycle()
chip8_beep();
sound_timer--;
}
- PC += 2;
}