From f7b1fedfb43f7c4b702bf22b32cbc9aa722f3c8e Mon Sep 17 00:00:00 2001 From: Loic Guegan Date: Tue, 26 Dec 2023 19:27:23 +0100 Subject: [PATCH] Cleaning code --- src/main.c | 13 ++++++------- src/mem.c | 11 ++++++++++- src/vcpu.c | 45 ++++++++++++++++++++++++++++++--------------- src/vcpu.h | 8 +++++++- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/src/main.c b/src/main.c index de3ae0d..2f2f9d0 100644 --- a/src/main.c +++ b/src/main.c @@ -5,6 +5,9 @@ #include +#define SCREEN_WIDTH 1000 +#define SCREEN_HEIGHT 500 + int main(int argc, char *argv[]) { // Parse argument @@ -17,11 +20,8 @@ int main(int argc, char *argv[]) } // Initialize - MemInit(); - MemLoadROM(argv[1]); - ScreenInit(1000,500); - VCPUInit(); - SpeakerInit(); + VCPUInit(SCREEN_WIDTH, SCREEN_HEIGHT); + MemLoadROM(argv[1]); // Load ROM into main memory // Set game to run at very high FPS (prevent raylib to interfer with emulator CPU frequency) SetTargetFPS(VCPU_FREQ*100); @@ -32,8 +32,7 @@ int main(int argc, char *argv[]) } // Finish - SpeakerFinish(); - ScreenClose(); + VCPUFinish(); return 0; } diff --git a/src/mem.c b/src/mem.c index ec34750..aba34fc 100644 --- a/src/mem.c +++ b/src/mem.c @@ -16,13 +16,22 @@ void MemSet(int addr, unsigned char value, int size){ } void MemStore(unsigned char *data, int size, int addr){ - for(int i=0;i4096){ + printf("Illegal memory access (store): addr=%d\n",addr+i); + return; + } memory[addr+i]=data[i]; + } } void MemLoad(unsigned char *data, int size, int addr){ int location=addr; for(int i=0;i4096){ + printf("Illegal memory access (load): addr=%d\n",addr+i); + return; + } data[i]=memory[addr+i]; } } diff --git a/src/vcpu.c b/src/vcpu.c index 4bfd86b..fb73eeb 100644 --- a/src/vcpu.c +++ b/src/vcpu.c @@ -12,7 +12,11 @@ // Current VCPU state VCPU_State State; -void VCPUInit(){ +void VCPUInit(int width, int height){ + MemInit(); + ScreenInit(width,height); + SpeakerInit(); + State.PC=ADDR_ROM; State.S=0; State.dt_ticks=0; @@ -22,6 +26,11 @@ void VCPUInit(){ srand(time(NULL)); } +void VCPUFinish(){ + SpeakerFinish(); + ScreenClose(); +} + void VCPUFetch(){ unsigned char byte[2]; 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(){ - // VCPUDump(); + // Very big switch case... Thinking about it, ifelse would have been cleaner for the reader switch(State.opcode >> 12){ case 0x0: // Clear screen or return from subroutine if(State.N == 0x0){ // Clear screen @@ -259,7 +268,7 @@ void VCPUExecute(){ MemStore(&hundreds,1,State.I); MemStore(&tens,1,State.I+1); MemStore(&units,1,State.I+2); - //printf("hundreds:%d tens:%d units:%d byte:%d\n",hundreds,tens,units,State.V[State.X]); + // printf("hundreds:%d tens:%d units:%d byte:%d\n",hundreds,tens,units,State.V[State.X]); break; case 0x55: @@ -279,32 +288,29 @@ void VCPUTick(){ struct timespec start, stop; double duration, delay; + // Start CPU pipeline instrumentation + clock_gettime(CLOCK_REALTIME, &start); + // Update keypressed int key=KeypadGetPressed(); if(key>=0){ State.keypressed=1; State.key=key&0xF; - //printf("Keypressed: %x\n",State.key); + // printf("Keypressed: %x\n",State.key); } - else + else{ State.keypressed=0; + } - // Run and benchmark CPU pipeline - clock_gettime(CLOCK_REALTIME, &start); + // Execute next instruction VCPUFetch(); VCPUDecode(); VCPUExecute(); + + // Update ticks State.dt_ticks++; State.st_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 if(State.dt_ticks>=(1.0*VCPU_FREQ/DTST_FREQ)){ @@ -330,6 +336,15 @@ void VCPUTick(){ 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(){ diff --git a/src/vcpu.h b/src/vcpu.h index 4266ac4..09bfd4e 100644 --- a/src/vcpu.h +++ b/src/vcpu.h @@ -51,7 +51,7 @@ typedef struct VCPU_State { * @brief Must be called first! * */ -void VCPUInit(); +void VCPUInit(int width, int height); /** * @brief Fetch instruction from memory @@ -92,3 +92,9 @@ void VCPUDoubleDabble(unsigned char x, unsigned char *u, unsigned char *t, unsig * */ void VCPUDump(); + +/** + * @brief To call before terminating the application + * + */ +void VCPUFinish();