|
|
|
@ -53,7 +53,7 @@ public: |
|
|
|
|
}; |
|
|
|
|
std::array<bool,2048>display; |
|
|
|
|
std::array<uint8_t,2048>screen; |
|
|
|
|
std::stack<uint8_t>stack; |
|
|
|
|
std::list<uint8_t>stack; |
|
|
|
|
float pulse=0; |
|
|
|
|
uint8_t delay_timer,sound_timer; |
|
|
|
|
uint16_t pc=0x200; |
|
|
|
@ -65,6 +65,7 @@ public: |
|
|
|
|
std::array<Key,16>keymap{X,K1,K2,K3,Q,W,E,A,S,D,Z,C,K4,R,F,V}; |
|
|
|
|
bool USE_ORIGINAL_CHIP8_SET=true; //True means use the original CHIP-8 spec (COSMAC VIP emulation). Set to false to use CHIP-48 spec.
|
|
|
|
|
bool PAUSED=true; |
|
|
|
|
long instructionCount=0; |
|
|
|
|
|
|
|
|
|
std::string Display8(int number){ |
|
|
|
|
std::bitset<8>numb(number); |
|
|
|
@ -75,6 +76,14 @@ public: |
|
|
|
|
return numb.to_string(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void advanceTimers(){ |
|
|
|
|
if (delay_timer>0){ |
|
|
|
|
delay_timer--; |
|
|
|
|
} |
|
|
|
|
if (sound_timer>0){ |
|
|
|
|
sound_timer--; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool OnUserCreate() override |
|
|
|
|
{ |
|
|
|
@ -112,12 +121,7 @@ public: |
|
|
|
|
if (!USE_DEBUG_DISPLAY||!PAUSED){ |
|
|
|
|
pulse+=fElapsedTime; |
|
|
|
|
if (pulse>=1/60.f){ |
|
|
|
|
if (delay_timer>0){ |
|
|
|
|
delay_timer--; |
|
|
|
|
} |
|
|
|
|
if (sound_timer>0){ |
|
|
|
|
sound_timer--; |
|
|
|
|
} |
|
|
|
|
advanceTimers(); |
|
|
|
|
pulse-=1/60.f; |
|
|
|
|
|
|
|
|
|
for (int i=0;i<10;i++){ |
|
|
|
@ -128,15 +132,31 @@ public: |
|
|
|
|
} else { |
|
|
|
|
if (GetKey(OEM_6).bPressed){ |
|
|
|
|
RunInstruction(); |
|
|
|
|
instructionCount++; |
|
|
|
|
if (instructionCount%10==0){ |
|
|
|
|
advanceTimers(); //After 10 instructions, 1/60th of a second has passed.
|
|
|
|
|
} |
|
|
|
|
DrawDisplay(); |
|
|
|
|
} else |
|
|
|
|
if (GetKey(SPACE).bHeld){ |
|
|
|
|
RunInstruction(); |
|
|
|
|
instructionCount++; |
|
|
|
|
if (instructionCount%10==0){ |
|
|
|
|
advanceTimers(); //After 10 instructions, 1/60th of a second has passed.
|
|
|
|
|
} |
|
|
|
|
DrawDisplay(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
std::stringstream s; |
|
|
|
|
s<<"PC: 0x"<<std::setfill('0')<< std::setw(4)<<std::hex<<pc; |
|
|
|
|
DrawStringDecal(vi2d{8,EMULATOR_PIXEL_SIZE*EMULATOR_SCREEN_HEIGHT+16},s.str()); |
|
|
|
|
std::string ss=s.str(); |
|
|
|
|
std::transform(ss.begin()+6,ss.end(),ss.begin()+6,::toupper); |
|
|
|
|
DrawStringDecal(vi2d{8,EMULATOR_PIXEL_SIZE*EMULATOR_SCREEN_HEIGHT+16},ss); |
|
|
|
|
std::stringstream instruction; |
|
|
|
|
instruction<<"0x"<<std::setfill('0')<< std::setw(2)<<std::hex<<(int)memory[pc]<<std::setw(2)<<(int)memory[pc+1]; |
|
|
|
|
DrawStringDecal(vi2d{12,EMULATOR_PIXEL_SIZE*EMULATOR_SCREEN_HEIGHT+26},instruction.str()); |
|
|
|
|
instruction<<"0x"<<std::setfill('0')<< std::setw(2)<<std::hex<<(int)memory[pc]<<std::setw(2)<<(int)memory[pc+1]<<" "<<GetInstructionDescription(memory[pc]<<8|memory[pc+1]); |
|
|
|
|
ss=instruction.str(); |
|
|
|
|
std::transform(ss.begin()+2,ss.end(),ss.begin()+2,::toupper); |
|
|
|
|
DrawStringDecal(vi2d{12,EMULATOR_PIXEL_SIZE*EMULATOR_SCREEN_HEIGHT+26},ss); |
|
|
|
|
|
|
|
|
|
for (int i=0;i<21;i++){ |
|
|
|
|
uint16_t tmp=pc+(i-10)*2; |
|
|
|
@ -144,11 +164,48 @@ public: |
|
|
|
|
std::stringstream tmp_s; |
|
|
|
|
tmp_s<<"0x"<<std::setfill('0')<< std::setw(4)<<std::hex<<tmp<<" "<<std::setw(2)<<(int)memory[tmp]<<std::setw(2)<<(int)memory[tmp+1]<<" "<<GetInstructionDescription(memory[tmp]<<8|memory[tmp+1]); |
|
|
|
|
std::string ss=tmp_s.str(); |
|
|
|
|
std::transform(ss.begin(),ss.end(),ss.begin(),::toupper); |
|
|
|
|
std::transform(ss.begin()+2,ss.end(),ss.begin()+2,::toupper); |
|
|
|
|
DrawStringDecal(vi2d{14+EMULATOR_PIXEL_SIZE*EMULATOR_SCREEN_WIDTH,8+i*10},ss,(tmp==pc)?YELLOW:WHITE); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
DrawStringDecal(vi2d{8,EMULATOR_PIXEL_SIZE*EMULATOR_SCREEN_HEIGHT+44},"REG"); |
|
|
|
|
for (int i=0;i<16;i++){ |
|
|
|
|
std::stringstream s; |
|
|
|
|
s<<"V"+std::to_string(i)<<std::right<<std::setfill(' ')<<std::setw((i>=10)?3:4)<<(int)reg[i]; |
|
|
|
|
DrawStringDecal(vi2d{12+i/8*64,EMULATOR_PIXEL_SIZE*EMULATOR_SCREEN_HEIGHT+54+i%8*10},s.str()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::stringstream index_s; |
|
|
|
|
index_s<<"0x"<<std::hex<<std::setfill('0')<<std::setw(4)<<index; |
|
|
|
|
DrawStringDecal(vi2d{8,EMULATOR_PIXEL_SIZE*EMULATOR_SCREEN_HEIGHT+64+10*8},"INDEX: "+index_s.str()); |
|
|
|
|
DrawStringDecal(vi2d{8,EMULATOR_PIXEL_SIZE*EMULATOR_SCREEN_HEIGHT+84+10*8},"STACK: "); |
|
|
|
|
|
|
|
|
|
int offsetX=0; |
|
|
|
|
bool first=true; |
|
|
|
|
uint8_t prevVal; |
|
|
|
|
bool firstVal=true; |
|
|
|
|
for (uint8_t&val:stack){ |
|
|
|
|
if (first) { |
|
|
|
|
first=false; |
|
|
|
|
prevVal=val; |
|
|
|
|
} else { |
|
|
|
|
first=true; |
|
|
|
|
std::stringstream hexStack; |
|
|
|
|
hexStack<<"0x"<<std::hex<<std::setfill('0')<<std::setw(4)<<(val<<8|prevVal); |
|
|
|
|
std::string ss=hexStack.str(); |
|
|
|
|
std::transform(ss.begin()+2,ss.end(),ss.begin()+2,::toupper); |
|
|
|
|
DrawStringDecal(vi2d{12+offsetX,EMULATOR_PIXEL_SIZE*EMULATOR_SCREEN_HEIGHT+94+10*8},((!firstVal)?" <- ":"")+ss); |
|
|
|
|
if (firstVal){ |
|
|
|
|
offsetX+=6*8; |
|
|
|
|
} else { |
|
|
|
|
offsetX+=10*8; |
|
|
|
|
} |
|
|
|
|
firstVal=false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -349,10 +406,10 @@ public: |
|
|
|
|
}break; |
|
|
|
|
case 0x0EE:{ //Return from subroutine.
|
|
|
|
|
uint8_t byte1,byte2; |
|
|
|
|
byte1=stack.top(); |
|
|
|
|
stack.pop(); |
|
|
|
|
byte2=stack.top(); |
|
|
|
|
stack.pop(); |
|
|
|
|
byte1=stack.front(); |
|
|
|
|
stack.pop_front(); |
|
|
|
|
byte2=stack.front(); |
|
|
|
|
stack.pop_front(); |
|
|
|
|
pc=byte2<<8|byte1; |
|
|
|
|
//std::cout<<"Exiting subroutine to 0x"<<std::hex<<pc<<std::endl;
|
|
|
|
|
}break; |
|
|
|
@ -362,8 +419,8 @@ public: |
|
|
|
|
pc=NNN; |
|
|
|
|
}break; |
|
|
|
|
case 0x2:{ //calls the subroutine at memory location NNN
|
|
|
|
|
stack.push(pc>>8); |
|
|
|
|
stack.push(pc&0xFF); |
|
|
|
|
stack.push_front(pc>>8); |
|
|
|
|
stack.push_front(pc&0xFF); |
|
|
|
|
//std::cout<<"Pushed 0x"<<std::hex<<pc<<" onto stack"<<std::endl;
|
|
|
|
|
pc=NNN; |
|
|
|
|
//std::cout<<"Entering subroutine @ 0x"<<std::hex<<NNN<<std::endl;
|
|
|
|
|