Cleaning code

This commit is contained in:
Loïc Guégan 2023-12-26 19:27:23 +01:00
parent c3b9b472bf
commit f7b1fedfb4
4 changed files with 53 additions and 24 deletions

View file

@ -5,6 +5,9 @@
#include <stdio.h> #include <stdio.h>
#define SCREEN_WIDTH 1000
#define SCREEN_HEIGHT 500
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// Parse argument // Parse argument
@ -17,11 +20,8 @@ int main(int argc, char *argv[])
} }
// Initialize // Initialize
MemInit(); VCPUInit(SCREEN_WIDTH, SCREEN_HEIGHT);
MemLoadROM(argv[1]); MemLoadROM(argv[1]); // Load ROM into main memory
ScreenInit(1000,500);
VCPUInit();
SpeakerInit();
// Set game to run at very high FPS (prevent raylib to interfer with emulator CPU frequency) // Set game to run at very high FPS (prevent raylib to interfer with emulator CPU frequency)
SetTargetFPS(VCPU_FREQ*100); SetTargetFPS(VCPU_FREQ*100);
@ -32,8 +32,7 @@ int main(int argc, char *argv[])
} }
// Finish // Finish
SpeakerFinish(); VCPUFinish();
ScreenClose();
return 0; return 0;
} }

View file

@ -16,13 +16,22 @@ void MemSet(int addr, unsigned char value, int size){
} }
void MemStore(unsigned char *data, int size, int addr){ void MemStore(unsigned char *data, int size, int addr){
for(int i=0;i<size;i++) for(int i=0;i<size;i++){
if(addr+i>4096){
printf("Illegal memory access (store): addr=%d\n",addr+i);
return;
}
memory[addr+i]=data[i]; memory[addr+i]=data[i];
} }
}
void MemLoad(unsigned char *data, int size, int addr){ void MemLoad(unsigned char *data, int size, int addr){
int location=addr; int location=addr;
for(int i=0;i<size;i++){ for(int i=0;i<size;i++){
if(addr+i>4096){
printf("Illegal memory access (load): addr=%d\n",addr+i);
return;
}
data[i]=memory[addr+i]; data[i]=memory[addr+i];
} }
} }

View file

@ -12,7 +12,11 @@
// Current VCPU state // Current VCPU state
VCPU_State State; VCPU_State State;
void VCPUInit(){ void VCPUInit(int width, int height){
MemInit();
ScreenInit(width,height);
SpeakerInit();
State.PC=ADDR_ROM; State.PC=ADDR_ROM;
State.S=0; State.S=0;
State.dt_ticks=0; State.dt_ticks=0;
@ -22,6 +26,11 @@ void VCPUInit(){
srand(time(NULL)); srand(time(NULL));
} }
void VCPUFinish(){
SpeakerFinish();
ScreenClose();
}
void VCPUFetch(){ void VCPUFetch(){
unsigned char byte[2]; unsigned char byte[2];
MemLoad(byte,2,State.PC); // Little indian to -1 no +1 MemLoad(byte,2,State.PC); // Little indian to -1 no +1
@ -64,7 +73,7 @@ void VCPUDoubleDabble(unsigned char x, unsigned char *u, unsigned char *t, unsig
} }
void VCPUExecute(){ void VCPUExecute(){
// VCPUDump(); // Very big switch case... Thinking about it, ifelse would have been cleaner for the reader
switch(State.opcode >> 12){ switch(State.opcode >> 12){
case 0x0: // Clear screen or return from subroutine case 0x0: // Clear screen or return from subroutine
if(State.N == 0x0){ // Clear screen if(State.N == 0x0){ // Clear screen
@ -279,6 +288,9 @@ void VCPUTick(){
struct timespec start, stop; struct timespec start, stop;
double duration, delay; double duration, delay;
// Start CPU pipeline instrumentation
clock_gettime(CLOCK_REALTIME, &start);
// Update keypressed // Update keypressed
int key=KeypadGetPressed(); int key=KeypadGetPressed();
if(key>=0){ if(key>=0){
@ -286,25 +298,19 @@ void VCPUTick(){
State.key=key&0xF; State.key=key&0xF;
// printf("Keypressed: %x\n",State.key); // printf("Keypressed: %x\n",State.key);
} }
else else{
State.keypressed=0; State.keypressed=0;
}
// Run and benchmark CPU pipeline // Execute next instruction
clock_gettime(CLOCK_REALTIME, &start);
VCPUFetch(); VCPUFetch();
VCPUDecode(); VCPUDecode();
VCPUExecute(); VCPUExecute();
// Update ticks
State.dt_ticks++; State.dt_ticks++;
State.st_ticks++; State.st_ticks++;
State.screen_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 // Update Delay Timer
if(State.dt_ticks>=(1.0*VCPU_FREQ/DTST_FREQ)){ if(State.dt_ticks>=(1.0*VCPU_FREQ/DTST_FREQ)){
@ -330,6 +336,15 @@ void VCPUTick(){
ScreenUpdate(); ScreenUpdate();
} }
// End instrumentation
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);
}
} }
void VCPUDump(){ void VCPUDump(){

View file

@ -51,7 +51,7 @@ typedef struct VCPU_State {
* @brief Must be called first! * @brief Must be called first!
* *
*/ */
void VCPUInit(); void VCPUInit(int width, int height);
/** /**
* @brief Fetch instruction from memory * @brief Fetch instruction from memory
@ -92,3 +92,9 @@ void VCPUDoubleDabble(unsigned char x, unsigned char *u, unsigned char *t, unsig
* *
*/ */
void VCPUDump(); void VCPUDump();
/**
* @brief To call before terminating the application
*
*/
void VCPUFinish();