Skip to content

Commit 8e18f8d

Browse files
committed
Opcodes done
1 parent 9955b63 commit 8e18f8d

File tree

4 files changed

+50
-33
lines changed

4 files changed

+50
-33
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ set(CMAKE_CXX_STANDARD 17)
55

66
add_executable(chip_8 main.cpp chip_8.cc chip_8.hh)
77

8-
target_link_libraries(chip_8 sfml-graphics sfml-system sfml-window)
8+
target_link_libraries(chip_8 sfml-graphics sfml-system sfml-window sfml-audio)

chip_8.cc

+34-25
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ void Chip8::emulate_cycle ()
115115
pc = opcode & 0x0FFF;
116116
printf ("Jump to 0x%X\n", pc);
117117
break;
118+
case 0x2000: // 0x2NNN call subroutine at address NNN
119+
stack[sp] = pc; // store program counter in stack
120+
++sp; // advance stack pointer
121+
pc = opcode & 0x0FFF; // "jump" to subroutine at NNN
122+
printf ("Call subroutine at 0x%X (from 0x%X)\n", pc, stack[sp - 1]);
123+
break;
118124
case 0x3000: // 0x3XNN if(VX == NN) skip next instruction
119125
printf ("Skip one instruction if V[0x%X] == 0x%X\n", (opcode & 0x0F00) >> 8, (opcode & 0x00FF));
120126
if (V[(opcode & 0x0F00) >> 8] == (opcode & 0x00FF))
@@ -141,23 +147,6 @@ void Chip8::emulate_cycle ()
141147
}
142148
pc += 2; // normal advancement in program
143149
break;
144-
case 0x6000: // 0x6XNN set VX to NN
145-
V[(opcode & 0x0F00) >> 8] = opcode & 0x00FF;
146-
printf ("Set V[0x%X] to 0x%X\n", (opcode & 0x0F00) >> 8,
147-
opcode & 0x00FF);
148-
pc += 2;
149-
break;
150-
case 0xA000: // 0xANNN movi: move NNN into I
151-
I = opcode & 0x0FFF; // move last 12 bits into I
152-
printf ("Move 0x%X into I\n", I);
153-
pc += 0x2; // advance by 2 bytes (size of opcode)
154-
break;
155-
case 0x2000: // 0x2NNN call subroutine at address NNN
156-
stack[sp] = pc; // store program counter in stack
157-
++sp; // advance stack pointer
158-
pc = opcode & 0x0FFF; // "jump" to subroutine at NNN
159-
printf ("Call subroutine at 0x%X (from 0x%X)\n", pc, stack[sp - 1]);
160-
break;
161150
case 0x5000: // 0x5XY0 Skips next instruction if VX == VY
162151
printf ("Skip one instruction if V[0x%X] == V[0x%X]\n", (opcode & 0x0F00) >> 8, (opcode & 0x00F0) >> 4);
163152
if (V[(opcode & 0x0F00) >> 8] == V[(opcode & 0x00F0) >> 4])
@@ -171,6 +160,12 @@ void Chip8::emulate_cycle ()
171160
}
172161
pc += 2;
173162
break;
163+
case 0x6000: // 0x6XNN set VX to NN
164+
V[(opcode & 0x0F00) >> 8] = opcode & 0x00FF;
165+
printf ("Set V[0x%X] to 0x%X\n", (opcode & 0x0F00) >> 8,
166+
opcode & 0x00FF);
167+
pc += 2;
168+
break;
174169
case 0x7000: // 0x7XNN Add NN to VX
175170
V[(opcode & 0x0F00) >> 8] += opcode & 0x00FF;
176171
pc += 2;
@@ -277,6 +272,15 @@ void Chip8::emulate_cycle ()
277272
}
278273
pc += 2;
279274
break;
275+
case 0xA000: // 0xANNN move NNN into I
276+
I = opcode & 0x0FFF; // move last 12 bits into I
277+
printf ("Move 0x%X into I\n", I);
278+
pc += 0x2; // advance by 2 bytes (size of opcode)
279+
break;
280+
case 0xB000: // 0xBNNN jump to NNN + V0
281+
pc = (opcode & 0x0FFF) + V[0x0];
282+
printf ("Jump to 0x%X + V[0x0]", opcode & 0x0FFF);
283+
break;
280284
case 0xC000: // 0xCXNN Sets VX to the result of "rand & NN"
281285
V[(opcode & 0x0F00) >> 8] = (rand () % 255) & (opcode & 0x00FF);
282286
pc += 2;
@@ -327,10 +331,10 @@ void Chip8::emulate_cycle ()
327331
case 0xE000: // Multiple instructions
328332
switch (opcode & 0x00FF)
329333
{
330-
case 0x00A1: // 0xEXA1 skip next instruction if key in VX *IS NOT* pressed
334+
case 0x009E: // 0xEX9E skip next instruction if key in VX *IS* pressed
331335
{
332-
printf ("Skip next instruction if key[V[0x%X]] not pressed\n", (opcode & 0x0F00) >> 8);
333-
if (key[V[(opcode & 0x0F00) >> 8]] == 0)
336+
printf ("Skip next instruction if key[V[0x%X]] pressed\n", (opcode & 0x0F00) >> 8);
337+
if (key[V[(opcode & 0x0F00) >> 8]] != 0)
334338
{
335339
printf (" TRUE\n");
336340
pc += 2;
@@ -342,10 +346,10 @@ void Chip8::emulate_cycle ()
342346
pc += 2;
343347
break;
344348
}
345-
case 0x009E: // 0xEX9E skip next instruction if key in VX *IS* pressed
349+
case 0x00A1: // 0xEXA1 skip next instruction if key in VX *IS NOT* pressed
346350
{
347-
printf ("Skip next instruction if key[V[0x%X]] pressed\n", (opcode & 0x0F00) >> 8);
348-
if (key[V[(opcode & 0x0F00) >> 8]] != 0)
351+
printf ("Skip next instruction if key[V[0x%X]] not pressed\n", (opcode & 0x0F00) >> 8);
352+
if (key[V[(opcode & 0x0F00) >> 8]] == 0)
349353
{
350354
printf (" TRUE\n");
351355
pc += 2;
@@ -356,13 +360,14 @@ void Chip8::emulate_cycle ()
356360
}
357361
pc += 2;
358362
break;
359-
}
363+
}
364+
360365
default:
361366
printf ("Unknown opcode / not implemented: 0x%X\n", opcode);
362367
break;
363368
}
364369
break;
365-
case 0xF000:
370+
case 0xF000: // Multiple instructions
366371
switch (opcode & 0x00FF)
367372
{
368373
case 0x0007: // 0xFX07 Sets VX to value of delay_timer
@@ -453,6 +458,10 @@ void Chip8::emulate_cycle ()
453458
{
454459
if (sound_timer == 1)
455460
{
461+
if (beep_fn != nullptr)
462+
{
463+
beep_fn ();
464+
}
456465
printf ("BEEP!\n");
457466
}
458467
--sound_timer;

chip_8.hh

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public:
2121
unsigned short sp; // stack pointer
2222
unsigned char key[16]; // keypad (HEX)
2323
bool draw_flag; // draw flag (redraw needed)
24+
void(*beep_fn)() = nullptr;
2425

2526
void initialize ();
2627
void load_program (const char* program_name);

main.cpp

+14-7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
11
#include <iostream>
22
#include <SFML/Graphics.hpp>
3+
#include <SFML/Audio.hpp>
34
#include <cstring>
45
#include "chip_8.hh"
56

67
Chip8 chip8;
78

9+
void beep ()
10+
{
11+
sf::SoundBuffer buffer;
12+
buffer.loadFromFile("beep.wav");
13+
sf::Sound sound;
14+
sound.setBuffer(buffer);
15+
sound.play();
16+
}
17+
818
int main (int argc, char* argv[])
919
{
1020
chip8.initialize ();
11-
chip8.load_program ("chip8/demos/Maze [David Winter, 199x].ch8");
21+
chip8.beep_fn = beep;
22+
chip8.load_program ("invaders.c8");
1223

1324
sf::RenderWindow* window = new sf::RenderWindow { sf::VideoMode (64*16, 32*16), "CHIP-8" };
1425
sf::Event event;
@@ -23,12 +34,7 @@ int main (int argc, char* argv[])
2334
std::size_t index = 0;
2435

2536
while (window->isOpen ())
26-
{
27-
if (chip8.halt_flag)
28-
{
29-
30-
}
31-
37+
{
3238
chip8.emulate_cycle ();
3339

3440
if (chip8.draw_flag)
@@ -79,6 +85,7 @@ int main (int argc, char* argv[])
7985
{
8086
case sf::Keyboard::Num1:
8187
chip8.key[0x1] = 0x1;
88+
chip8.beep_fn ();
8289
break;
8390
case sf::Keyboard::Num2:
8491
chip8.key[0x2] = 0x1;

0 commit comments

Comments
 (0)