Minor changes

This commit is contained in:
Loïc Guégan 2023-12-26 09:06:40 +01:00
parent f1c3a67294
commit 64917e3504
7 changed files with 96 additions and 36 deletions

BIN
roms/games/pong_1player.ch8 Normal file

Binary file not shown.

View file

@ -19,21 +19,19 @@ int map[]={
KEY_V // F
};
int KeypadIsPressed(unsigned char c){
if(c<=0xF){
if(IsKeyPressed(map[c]))
return 1;
int KeypadKeycodeValid(int keycode){
for(int i=0;i<16;i++){
if(map[i]==keycode)
return i;
}
return 0;
return -1;
}
int KeypadGetPressed(){
int keycode=GetKeyPressed();
if(keycode){
for(int i=0;i<16;i++){
if(map[i]==keycode)
return 1;
}
return KeypadKeycodeValid(keycode);
}
return -1;
}

View file

@ -2,6 +2,5 @@
#include "raylib.h"
int KeypadIsPressed(unsigned char c);
int KeypadGetPressed();

View file

@ -1,34 +1,33 @@
#include "screen.h"
#include "mem.h"
#include "vcpu.h"
#include <stdio.h>
#define ROM "../roms/chip8-test-suite/6-keypad.ch8"
//#define ROM "../roms/games/pong_1player.ch8"
int main(int argc, char *argv[])
{
/* unsigned char byte=137; */
/* unsigned char u,t,h; */
/* VCPUDoubleDabble(byte,&u,&t,&h); */
/* printf("%d: %01d%01d%01d\n",byte,h,t,u); */
/* return 0; */
// Initialize
MemInit();
MemLoadROM("../roms/games/paddles.ch8");
MemLoadROM(ROM);
ScreenInit(800,400);
VCPUInit();
// MemDump();
int i=0;
// Set game to run at very high FPS (prevent raylib to interfer with emulator FPS)
SetTargetFPS(VCPU_FREQ*100);
// Emulator main loop
int i=0;
while (!WindowShouldClose()){
for(int i=0;i<30;i++){
VCPUFetch();
VCPUDecode();
VCPUExecute();
}
ScreenUpdate();
VCPUTick();
if(i%600 == 0)
printf("tick\n");
i++;
}
// Close screen
ScreenClose();
return 0;

View file

@ -15,7 +15,6 @@ void ScreenInit(int width, int height){
SetTraceLogLevel(LOG_ERROR); // Disable anoying raylib logs
InitWindow(width, height, "Chip-8 Emulator");
SetTargetFPS(60); // Set game to run at 60 frames-per-second
}
void ScreenClear() {

View file

@ -5,6 +5,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
// Current VCPU state
@ -13,6 +14,9 @@ VCPU_State State;
void VCPUInit(){
State.PC=ADDR_ROM;
State.S=0;
State.dtst_ticks=0;
State.screen_ticks=0;
State.keypress=-1;
srand(time(NULL));
}
@ -204,11 +208,20 @@ void VCPUExecute(){
case 0xE:
if(State.NN==0x9E){ // Skip if keypress in VX
if(KeypadIsPressed(State.V[State.X]&0x0F)){
State.PC+=2;
if(State.keypress >= 0){
if(State.V[State.X]&0x0F == State.keypress&0xF){
State.PC+=2;
}
State.keypress=-1;
}
}else if(State.NN==0xA1){ // Skip if not keypress in VX
if(!KeypadIsPressed(State.V[State.X]&0x0F))
if(State.keypress >=0){
if(State.V[State.X]&0x0F != State.keypress&0xF){
State.PC+=2;
}
State.keypress=-1;
}
else
State.PC+=2;
}
break;
@ -220,13 +233,15 @@ void VCPUExecute(){
break;
case 0x0A:
int key=KeypadGetPressed();
if(key >= 0){
State.V[State.X]=key&0x0F;
if(State.keypress >=0){
State.V[State.X]=State.keypress&0xF;
if(State.V[State.X]&0x0F != State.keypress&0xF){
State.PC+=2;
State.keypress=-1;
}
}
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)
break;
case 0x15: // Set timer
@ -267,6 +282,45 @@ void VCPUExecute(){
}
}
void VCPUTick(){
struct timespec start, stop;
double duration, delay;
// Run and benchmark CPU pipeline
clock_gettime(CLOCK_REALTIME, &start);
VCPUFetch();
VCPUDecode();
VCPUExecute();
State.dtst_ticks++;
State.screen_ticks++;
clock_gettime(CLOCK_REALTIME, &stop);
// Adjust pipeline duration
duration=(stop.tv_sec - start.tv_sec) + (stop.tv_nsec - start.tv_nsec)*1e-9;
delay=1.0/VCPU_FREQ-duration;
if(delay>0){
usleep(delay*1e6);
}
// Update Delay Timer and Sound Timer
if(State.dtst_ticks>=(1.0*VCPU_FREQ/DTST_FREQ)){
State.dtst_ticks=0;
if(State.DT>0)
State.DT--;
}
// Refresh screen
if(State.screen_ticks>=(1.0*VCPU_FREQ/SCREEN_FREQ)){
State.screen_ticks=0;
ScreenUpdate();
}
// Update keypressed
int keypress=KeypadGetPressed();
if(keypress>=0)
State.keypress=keypress;
}
void VCPUDump(){
printf("opcode: 0x%04x\n",State.opcode&0xFFFF);
printf("X: 0x%01x\n",State.X);

View file

@ -1,5 +1,8 @@
#pragma once
#define VCPU_FREQ 600
#define DTST_FREQ 60
#define SCREEN_FREQ 60
#define REG_FLAG 0xF
typedef struct VCPU_State {
@ -30,11 +33,19 @@ typedef struct VCPU_State {
unsigned char N;
unsigned char NN;
unsigned short NNN;
// Keypressed
int keypress;
// Count VCPU ticks
int dtst_ticks;
int screen_ticks;
} VCPU_State;
void VCPUInit();
void VCPUFetch();
void VCPUDecode();
void VCPUExecute();
void VCPUTick();
void VCPUDoubleDabble(unsigned char x, unsigned char *u, unsigned char *t, unsigned char *h);
void VCPUDump();