|
|
@ -1,31 +1,157 @@ |
|
|
|
#include "pixelGameEngine.h" |
|
|
|
#include "pixelGameEngine.h" |
|
|
|
#include "Polygon.h" |
|
|
|
#include "Polygon.h" |
|
|
|
|
|
|
|
#include <stack> |
|
|
|
|
|
|
|
|
|
|
|
using namespace olc; |
|
|
|
using namespace olc; |
|
|
|
|
|
|
|
|
|
|
|
#define WIDTH 640 |
|
|
|
#define WIDTH 640 |
|
|
|
#define HEIGHT 480 |
|
|
|
#define HEIGHT 480 |
|
|
|
|
|
|
|
|
|
|
|
class Example : public olc::PixelGameEngine |
|
|
|
class Chip8Emulator : public olc::PixelGameEngine |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
public: |
|
|
|
Example() |
|
|
|
Chip8Emulator() |
|
|
|
{ |
|
|
|
{ |
|
|
|
sAppName = "Example"; |
|
|
|
sAppName = "CHIP-8!"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public: |
|
|
|
public: |
|
|
|
|
|
|
|
std::array<uint8_t,4096>memory={ |
|
|
|
|
|
|
|
0,0,0,0,0,0,0,0,0,0, |
|
|
|
|
|
|
|
0,0,0,0,0,0,0,0,0,0, |
|
|
|
|
|
|
|
0,0,0,0,0,0,0,0,0,0, |
|
|
|
|
|
|
|
0,0,0,0,0,0,0,0,0,0, |
|
|
|
|
|
|
|
0,0,0,0,0,0,0,0,0,0, |
|
|
|
|
|
|
|
0,0,0,0,0,0,0,0,0,0, |
|
|
|
|
|
|
|
0,0,0,0,0,0,0,0,0,0, |
|
|
|
|
|
|
|
0,0,0,0,0,0,0,0,0,0, |
|
|
|
|
|
|
|
0,0,0,0,0,0,0,0,0,0, |
|
|
|
|
|
|
|
//Font starts at 0x50
|
|
|
|
|
|
|
|
0xF0,0x90,0x90,0x90,0xF0, // 0
|
|
|
|
|
|
|
|
0x20,0x60,0x20,0x20,0x70, // 1
|
|
|
|
|
|
|
|
0xF0,0x10,0xF0,0x80,0xF0, // 2
|
|
|
|
|
|
|
|
0xF0,0x10,0xF0,0x10,0xF0, // 3
|
|
|
|
|
|
|
|
0x90,0x90,0xF0,0x10,0x10, // 4
|
|
|
|
|
|
|
|
0xF0,0x80,0xF0,0x10,0xF0, // 5
|
|
|
|
|
|
|
|
0xF0,0x80,0xF0,0x90,0xF0, // 6
|
|
|
|
|
|
|
|
0xF0,0x10,0x20,0x40,0x40, // 7
|
|
|
|
|
|
|
|
0xF0,0x90,0xF0,0x90,0xF0, // 8
|
|
|
|
|
|
|
|
0xF0,0x90,0xF0,0x10,0xF0, // 9
|
|
|
|
|
|
|
|
0xF0,0x90,0xF0,0x90,0x90, // A
|
|
|
|
|
|
|
|
0xE0,0x90,0xE0,0x90,0xE0, // B
|
|
|
|
|
|
|
|
0xF0,0x80,0x80,0x80,0xF0, // C
|
|
|
|
|
|
|
|
0xE0,0x90,0x90,0x90,0xE0, // D
|
|
|
|
|
|
|
|
0xF0,0x80,0xF0,0x80,0xF0, // E
|
|
|
|
|
|
|
|
0xF0,0x80,0xF0,0x80,0x80 // F
|
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
std::array<bool,2048>display; |
|
|
|
|
|
|
|
std::stack<uint8_t>stack; |
|
|
|
|
|
|
|
float pulse=0; |
|
|
|
|
|
|
|
uint8_t delay_timer,sound_timer; |
|
|
|
|
|
|
|
uint16_t pc=0x200; |
|
|
|
|
|
|
|
uint16_t index; //One 16-bit index register called “I” which is used to point at locations in memory
|
|
|
|
|
|
|
|
std::array<uint8_t,16>reg; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool OnUserCreate() override |
|
|
|
bool OnUserCreate() override |
|
|
|
{ |
|
|
|
{ |
|
|
|
Polygon poly{{30,30},{20,20},{-7,6}}; |
|
|
|
//memory[0x200]=0x00;
|
|
|
|
|
|
|
|
//memory[0x201]=0xE0;
|
|
|
|
|
|
|
|
//0x200 program start
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool OnUserUpdate(float fElapsedTime) override |
|
|
|
bool OnUserUpdate(float fElapsedTime) override |
|
|
|
{ |
|
|
|
{ |
|
|
|
Clear(BLACK); |
|
|
|
pulse+=fElapsedTime; |
|
|
|
|
|
|
|
if (pulse>=1/60.f){ |
|
|
|
|
|
|
|
if (delay_timer>0){ |
|
|
|
|
|
|
|
delay_timer--; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (sound_timer>0){ |
|
|
|
|
|
|
|
sound_timer--; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
pulse-=1/60.f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i=0;i<10;i++){ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//FETCH
|
|
|
|
|
|
|
|
uint16_t opcode = memory[pc]<<8|memory[pc+1]; |
|
|
|
|
|
|
|
pc+=2; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//DECODE
|
|
|
|
|
|
|
|
uint8_t nibble1 = opcode>>12; |
|
|
|
|
|
|
|
uint8_t X = reg[opcode>>8&0xF]; |
|
|
|
|
|
|
|
uint8_t Y = reg[opcode>>4&0xF]; |
|
|
|
|
|
|
|
uint8_t N = opcode&0xF; |
|
|
|
|
|
|
|
uint8_t NN = opcode&0x00FF; |
|
|
|
|
|
|
|
uint16_t NNN = opcode&0x0FFF; |
|
|
|
|
|
|
|
switch(nibble1){ |
|
|
|
|
|
|
|
case 0x0:{ |
|
|
|
|
|
|
|
switch (NNN){ |
|
|
|
|
|
|
|
case 0x0E0:{ //Clear screen.
|
|
|
|
|
|
|
|
std::cout<<"Screen has been cleared."<<std::endl; |
|
|
|
|
|
|
|
for (int i=0;i<display.size();i++){ |
|
|
|
|
|
|
|
display[i]=0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0x1:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0x2:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0x3:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0x4:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0x5:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0x6:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0x7:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0x8:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0x9:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0xA:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0xB:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0xC:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0xD:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0xE:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
case 0xF:{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Clear(VERY_DARK_BLUE); |
|
|
|
|
|
|
|
for (int x=0;x<ScreenWidth();x++){ |
|
|
|
|
|
|
|
for (int y=0;y<ScreenHeight();y++){ |
|
|
|
|
|
|
|
Draw({x,y},display[y*ScreenWidth()+x]?WHITE:BLACK); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -34,22 +160,10 @@ public: |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
enum Direction{ |
|
|
|
|
|
|
|
RIGHT, |
|
|
|
|
|
|
|
DOWN, |
|
|
|
|
|
|
|
LEFT, |
|
|
|
|
|
|
|
UP |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct Data{ |
|
|
|
|
|
|
|
int x,y; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main() |
|
|
|
int main() |
|
|
|
{
|
|
|
|
{
|
|
|
|
Example demo; |
|
|
|
Chip8Emulator demo; |
|
|
|
if (demo.Construct(640, 480, 4, 4)) |
|
|
|
if (demo.Construct(64, 32, 10, 10)) |
|
|
|
demo.Start(); |
|
|
|
demo.Start(); |
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|