summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip8.c25
-rw-r--r--main.c46
2 files changed, 59 insertions, 12 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;
}
diff --git a/main.c b/main.c
index f58edf7..3b8183e 100644
--- a/main.c
+++ b/main.c
@@ -10,9 +10,11 @@
* http://mattmik.com/files/chip8/mastering/chip8.html (lots of info)
* http://devernay.free.fr/hacks/chip8/C8TECH10.HTM#0.1
* http://www.emulator101.com/chip-8-sprites.html
+ * https://slack-files.com/T3CH37TNX-F3RKEUKL4-b05ab4930d?nojsmode=1
*/
#define VIDEO_SCALE 5
+#define STEPPING 1 // set to 1 to step manually through program
SDL_Window *window;
SDL_Renderer *renderer;
@@ -29,6 +31,8 @@ void handle_key_up(int keycode);
uint8_t get_chip8_key(int keycode);
void print_registers();
+int step_cycle = 0;
+
extern uint32_t video[WIDTH*HEIGHT];
extern int draw_flag;
extern uint8_t key[KEY_SIZE];
@@ -38,6 +42,7 @@ extern uint16_t PC;
extern int8_t SP;
extern uint8_t delay_timer;
extern uint8_t sound_timer;
+extern uint16_t stack[STACK_SIZE];
void
usage(char *program)
@@ -86,13 +91,21 @@ toggle_pixel(int x, int y)
void
print_registers()
{
- puts("REGISTER DUMP");
+ puts("DUMP");
puts("--------------------------");
for (int reg = 0; reg < REGISTER_COUNT; reg++)
{
printf("V[0x%01X] = 0x%02X\n", reg, V[reg]);
}
- printf("PC = 0x%03X\nI = 0x%03X\nSP = 0x%02X\ndelay_timer = 0x%02X\nsound_timer = 0x%02X\n", PC, I, SP, delay_timer, sound_timer);
+ // minus 2 on PC because we increment PC by 2 at the start of decoding
+ printf("PC = 0x%03X\nI = 0x%03X\nSP = 0x%02X\ndelay_timer = 0x%02X\nsound_timer = 0x%02X\n", PC-2, I, SP, delay_timer, sound_timer);
+ puts("STACK:");
+ for (int i = 0; i < 16; i++)
+ {
+ printf("[%d] = 0x%03X", i, stack[i]);
+ if (i == 7) puts("");
+ }
+ puts("");
puts("--------------------------");
}
@@ -103,6 +116,7 @@ handle_key_down(int keycode)
{
/* detect interpreter debug keys */
case SDLK_p: print_registers(); break;
+ case SDLK_PERIOD: step_cycle = 1; break;
default: break;
}
@@ -191,7 +205,7 @@ int main(int argc, char *argv[])
init_video();
- const int fps = 2;
+ const int fps = 1;
const int frame_delay = 1000/fps;
uint32_t frame_start;
uint32_t frame_time;
@@ -232,12 +246,30 @@ int main(int argc, char *argv[])
// logic
do_quit = handle_sdl_events();
- chip8_cycle();
+ if (STEPPING)
+ {
+ if (step_cycle == 1)
+ {
+ chip8_cycle();
+
+ if (draw_flag)
+ {
+ update_video();
+ draw_flag = 0;
+ }
- if (draw_flag)
+ step_cycle = 0;
+ }
+ }
+ else
{
- update_video();
- draw_flag = 0;
+ chip8_cycle();
+
+ if (draw_flag)
+ {
+ update_video();
+ draw_flag = 0;
+ }
}
frame_time = SDL_GetTicks() - frame_start;