Minor changes

This commit is contained in:
Loïc Guégan 2023-12-26 13:17:52 +01:00
parent 3738e41d2d
commit e9ec679450
8 changed files with 87 additions and 38 deletions

View file

@ -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

Binary file not shown.

View file

@ -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;
} }

View file

@ -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
View 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
View file

@ -0,0 +1,8 @@
#include "raylib.h"
#define SPEAKER_AUDIO_FILE "beep.mp3"
void SpeakerInit();
void SpeakerOn();
void SpeakerOff();
void SpeakerFinish();

View file

@ -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(){

View file

@ -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;