Minor changes
This commit is contained in:
parent
3738e41d2d
commit
e9ec679450
8 changed files with 87 additions and 38 deletions
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
EXEC=chip-8
|
EXEC=chip-8
|
||||||
|
|
||||||
$(EXEC): main.c screen.c mem.c vcpu.c keypad.c
|
$(EXEC): main.c screen.c mem.c vcpu.c keypad.c speaker.c
|
||||||
gcc -lraylib $^ -o $@
|
gcc -lraylib $^ -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
|
|
BIN
src/beep.mp3
Normal file
BIN
src/beep.mp3
Normal file
Binary file not shown.
|
@ -19,7 +19,7 @@ int map[]={
|
||||||
KEY_V // F
|
KEY_V // F
|
||||||
};
|
};
|
||||||
|
|
||||||
int KeypadKeycodeValid(int keycode){
|
int KeypadGetKey(int keycode){
|
||||||
for(int i=0;i<16;i++){
|
for(int i=0;i<16;i++){
|
||||||
if(map[i]==keycode)
|
if(map[i]==keycode)
|
||||||
return i;
|
return i;
|
||||||
|
@ -29,9 +29,9 @@ int KeypadKeycodeValid(int keycode){
|
||||||
|
|
||||||
|
|
||||||
int KeypadGetPressed(){
|
int KeypadGetPressed(){
|
||||||
int keycode=GetKeyPressed();
|
for(int i=0;i<16;i++){
|
||||||
if(keycode){
|
if(IsKeyDown(map[i]))
|
||||||
return KeypadKeycodeValid(keycode);
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
16
src/main.c
16
src/main.c
|
@ -1,10 +1,14 @@
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "vcpu.h"
|
#include "vcpu.h"
|
||||||
|
#include "speaker.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define ROM "../roms/chip8-test-suite/5-quirks.ch8"
|
//#define ROM "../roms/chip8-test-suite/5-quirks.ch8"
|
||||||
//#define ROM "../roms/games/pong_1player.ch8"
|
//#define ROM "../roms/chip8-test-suite/8-scrolling.ch8"
|
||||||
|
#define ROM "../roms/games/pong_1player.ch8"
|
||||||
|
//#define ROM "../roms/ibm.ch8"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -14,8 +18,9 @@ int main(int argc, char *argv[])
|
||||||
MemLoadROM(ROM);
|
MemLoadROM(ROM);
|
||||||
ScreenInit(800,400);
|
ScreenInit(800,400);
|
||||||
VCPUInit();
|
VCPUInit();
|
||||||
|
SpeakerInit();
|
||||||
|
|
||||||
// Set game to run at very high FPS (prevent raylib to interfer with emulator FPS)
|
// Set game to run at very high FPS (prevent raylib to interfer with emulator CPU frequency)
|
||||||
SetTargetFPS(VCPU_FREQ*100);
|
SetTargetFPS(VCPU_FREQ*100);
|
||||||
|
|
||||||
// Emulator main loop
|
// Emulator main loop
|
||||||
|
@ -27,8 +32,9 @@ int main(int argc, char *argv[])
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close screen
|
// Finish
|
||||||
|
SpeakerFinish();
|
||||||
ScreenClose();
|
ScreenClose();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
20
src/speaker.c
Normal file
20
src/speaker.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#include "speaker.h"
|
||||||
|
|
||||||
|
Sound s;
|
||||||
|
|
||||||
|
void SpeakerInit(){
|
||||||
|
InitAudioDevice(); // Initialize audio device
|
||||||
|
s=LoadSound(SPEAKER_AUDIO_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpeakerOn(){
|
||||||
|
PlaySound(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpeakerOff(){
|
||||||
|
StopSound(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpeakerFinish(){
|
||||||
|
CloseAudioDevice();
|
||||||
|
}
|
8
src/speaker.h
Normal file
8
src/speaker.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#define SPEAKER_AUDIO_FILE "beep.mp3"
|
||||||
|
|
||||||
|
void SpeakerInit();
|
||||||
|
void SpeakerOn();
|
||||||
|
void SpeakerOff();
|
||||||
|
void SpeakerFinish();
|
65
src/vcpu.c
65
src/vcpu.c
|
@ -2,6 +2,7 @@
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "keypad.h"
|
#include "keypad.h"
|
||||||
|
#include "speaker.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -14,9 +15,10 @@ VCPU_State State;
|
||||||
void VCPUInit(){
|
void VCPUInit(){
|
||||||
State.PC=ADDR_ROM;
|
State.PC=ADDR_ROM;
|
||||||
State.S=0;
|
State.S=0;
|
||||||
State.dtst_ticks=0;
|
State.dt_ticks=0;
|
||||||
|
State.st_ticks=0;
|
||||||
State.screen_ticks=0;
|
State.screen_ticks=0;
|
||||||
State.keypress=-1;
|
State.keypressed=0;
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,19 +210,16 @@ void VCPUExecute(){
|
||||||
|
|
||||||
case 0xE:
|
case 0xE:
|
||||||
if(State.NN==0x9E){ // Skip if keypress in VX
|
if(State.NN==0x9E){ // Skip if keypress in VX
|
||||||
if(State.keypress >= 0){
|
if(State.keypressed){
|
||||||
if(State.V[State.X]&0x0F == State.keypress&0xF){
|
if(State.V[State.X] == State.key)
|
||||||
State.PC+=2;
|
State.PC+=2;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
State.keypress=-1;
|
|
||||||
}else if(State.NN==0xA1){ // Skip if not keypress in VX
|
}else if(State.NN==0xA1){ // Skip if not keypress in VX
|
||||||
State.PC+=2; // First skip
|
State.PC+=2;
|
||||||
if(State.keypress >=0){
|
if(State.keypressed){
|
||||||
if(State.V[State.X]&0x0F == State.keypress&0x0F)
|
if(State.V[State.X] == State.key)
|
||||||
State.PC+=2; // Ignore skip if pressed
|
State.PC+=4;
|
||||||
}
|
}
|
||||||
State.keypress=-1;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -231,12 +230,8 @@ void VCPUExecute(){
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0A:
|
case 0x0A:
|
||||||
if(State.keypress >=0){
|
if(State.keypressed){
|
||||||
State.V[State.X]=State.keypress&0xF;
|
State.V[State.X]=State.key;
|
||||||
if(State.V[State.X]&0x0F != State.keypress&0xF){
|
|
||||||
State.PC+=2;
|
|
||||||
}
|
|
||||||
State.keypress=-1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
State.PC-=2; // Go back to last instruction (loop until key is pressed)
|
State.PC-=2; // Go back to last instruction (loop until key is pressed)
|
||||||
|
@ -284,12 +279,23 @@ void VCPUTick(){
|
||||||
struct timespec start, stop;
|
struct timespec start, stop;
|
||||||
double duration, delay;
|
double duration, delay;
|
||||||
|
|
||||||
|
// Update keypressed
|
||||||
|
int key=KeypadGetPressed();
|
||||||
|
if(key>=0){
|
||||||
|
State.keypressed=1;
|
||||||
|
State.key=key&0xF;
|
||||||
|
//printf("Keypressed: %x\n",State.key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
State.keypressed=0;
|
||||||
|
|
||||||
// Run and benchmark CPU pipeline
|
// Run and benchmark CPU pipeline
|
||||||
clock_gettime(CLOCK_REALTIME, &start);
|
clock_gettime(CLOCK_REALTIME, &start);
|
||||||
VCPUFetch();
|
VCPUFetch();
|
||||||
VCPUDecode();
|
VCPUDecode();
|
||||||
VCPUExecute();
|
VCPUExecute();
|
||||||
State.dtst_ticks++;
|
State.dt_ticks++;
|
||||||
|
State.st_ticks++;
|
||||||
State.screen_ticks++;
|
State.screen_ticks++;
|
||||||
clock_gettime(CLOCK_REALTIME, &stop);
|
clock_gettime(CLOCK_REALTIME, &stop);
|
||||||
|
|
||||||
|
@ -300,23 +306,30 @@ void VCPUTick(){
|
||||||
usleep(delay*1e6);
|
usleep(delay*1e6);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Delay Timer and Sound Timer
|
// Update Delay Timer
|
||||||
if(State.dtst_ticks>=(1.0*VCPU_FREQ/DTST_FREQ)){
|
if(State.dt_ticks>=(1.0*VCPU_FREQ/DTST_FREQ)){
|
||||||
State.dtst_ticks=0;
|
State.dt_ticks=0;
|
||||||
if(State.DT>0)
|
if(State.DT>0)
|
||||||
State.DT--;
|
State.DT--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update Sound Timer
|
||||||
|
if(State.st_ticks>=(1.0*VCPU_FREQ/DTST_FREQ)){
|
||||||
|
State.st_ticks=0;
|
||||||
|
if(State.ST>0)
|
||||||
|
State.ST--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Play sound
|
||||||
|
if(State.ST>0)
|
||||||
|
SpeakerOn();
|
||||||
|
|
||||||
// Refresh screen
|
// Refresh screen
|
||||||
if(State.screen_ticks>=(1.0*VCPU_FREQ/SCREEN_FREQ)){
|
if(State.screen_ticks>=(1.0*VCPU_FREQ/SCREEN_FREQ)){
|
||||||
State.screen_ticks=0;
|
State.screen_ticks=0;
|
||||||
ScreenUpdate();
|
ScreenUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update keypressed
|
|
||||||
int keypress=KeypadGetPressed();
|
|
||||||
if(keypress>=0)
|
|
||||||
State.keypress=keypress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCPUDump(){
|
void VCPUDump(){
|
||||||
|
|
|
@ -35,10 +35,12 @@ typedef struct VCPU_State {
|
||||||
unsigned short NNN;
|
unsigned short NNN;
|
||||||
|
|
||||||
// Keypressed
|
// Keypressed
|
||||||
int keypress;
|
int keypressed; // Not 0 if a key was pressed
|
||||||
|
unsigned char key;
|
||||||
|
|
||||||
// Count VCPU ticks
|
// Count VCPU ticks
|
||||||
int dtst_ticks;
|
int dt_ticks;
|
||||||
|
int st_ticks;
|
||||||
int screen_ticks;
|
int screen_ticks;
|
||||||
} VCPU_State;
|
} VCPU_State;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue