Do some stuff
This commit is contained in:
131
main.c
131
main.c
@@ -61,29 +61,11 @@ void msleep(unsigned int milliseconds) {
|
||||
|
||||
void *cpu_loop(void *arg) {
|
||||
uint64_t last_tick = SDL_GetTicks64();
|
||||
uint64_t last_speed_check = last_tick;;
|
||||
uint64_t step_count = 0;
|
||||
struct timespec start, end, sleep_time;
|
||||
while (running) {
|
||||
pthread_mutex_lock(&cpu_mutex);
|
||||
|
||||
if (!(cpu.mode & (CPU_MODE_PAUSED | CPU_MODE_HALTED | CPU_MODE_ERROR))) {
|
||||
clock_gettime(CLOCK_MONOTONIC, &start); // Get start time
|
||||
step(&cpu);
|
||||
clock_gettime(CLOCK_MONOTONIC, &end); // Get end time
|
||||
// Compute step duration in nanoseconds
|
||||
uint64_t step_duration_ns = (end.tv_sec - start.tv_sec) * 1000000000ULL +
|
||||
(end.tv_nsec - start.tv_nsec);
|
||||
|
||||
// Compute remaining time to maintain 64 kHz
|
||||
if (step_duration_ns < TARGET_CYCLE_TIME_NS) {
|
||||
uint64_t remaining_ns = TARGET_CYCLE_TIME_NS - step_duration_ns;
|
||||
sleep_time.tv_sec = 0;
|
||||
sleep_time.tv_nsec = remaining_ns;
|
||||
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &sleep_time, NULL);
|
||||
}
|
||||
|
||||
step_count++;
|
||||
} else {
|
||||
pthread_mutex_unlock(&cpu_mutex);
|
||||
msleep(10);
|
||||
@@ -102,13 +84,6 @@ void *cpu_loop(void *arg) {
|
||||
}
|
||||
last_tick = SDL_GetTicks64();
|
||||
}
|
||||
// Print speed every second
|
||||
uint64_t now = SDL_GetTicks64();
|
||||
if (now - last_speed_check >= 1000) {
|
||||
printf("CPU Max Speed: %lu Hz\n", step_count);
|
||||
step_count = 0;
|
||||
last_speed_check = now;
|
||||
}
|
||||
pthread_mutex_unlock(&cpu_mutex);
|
||||
}
|
||||
return NULL;
|
||||
@@ -189,6 +164,16 @@ int init() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create OpenGL context
|
||||
SDL_GLContext glContext = SDL_GL_CreateContext(window);
|
||||
if (!glContext) {
|
||||
fprintf(stderr, "SDL_GL_CreateContext failed: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Use OpenGL context
|
||||
SDL_GL_MakeCurrent(window, glContext); // Make sure OpenGL context is current before any OpenGL rendering
|
||||
|
||||
memset(&audioData, 0, sizeof(AudioData));
|
||||
|
||||
SDL_AudioSpec spec = {0};
|
||||
@@ -207,6 +192,30 @@ int init() {
|
||||
|
||||
SDL_PauseAudioDevice(dev, 0);
|
||||
|
||||
init_seven_segment(&displayA, renderer, 480, 240, 60, 120);
|
||||
init_seven_segment(&displayB, renderer, 545, 240, 60, 120);
|
||||
init_seven_segment(&displayC, renderer, 610, 240, 60, 120);
|
||||
init_seven_segment(&displayD, renderer, 675, 240, 60, 120);
|
||||
|
||||
init_seven_segment(&displayE, renderer, 480, 375, 60, 120);
|
||||
init_seven_segment(&displayF, renderer, 545, 375, 60, 120);
|
||||
init_seven_segment(&displayG, renderer, 610, 375, 60, 120);
|
||||
init_seven_segment(&displayH, renderer, 675, 375, 60, 120);
|
||||
|
||||
init_switches(&switchesA, renderer, 500, 500, 100, 100);
|
||||
init_switches(&switchesB, renderer, 625, 500, 100, 100);
|
||||
init_switches(&switchesC, renderer, 500, 610, 100, 100);
|
||||
init_switches(&switchesD, renderer, 625, 610, 100, 100);
|
||||
|
||||
|
||||
gpuSurf = SDL_CreateRGBSurfaceWithFormat(0, 160, 160, 32, SDL_PIXELFORMAT_RGBA8888);
|
||||
gpuTex = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 160, 160);
|
||||
|
||||
SDL_SetRenderTarget(renderer, gpuTex);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_SetRenderTarget(renderer, NULL);
|
||||
|
||||
SDL_Rect viewport = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
|
||||
SDL_RenderSetViewport(renderer, &viewport);
|
||||
|
||||
@@ -220,7 +229,7 @@ int init() {
|
||||
for (int i = 0; i < editorCount; i++) {
|
||||
generate_string_display(&codeEditor, renderer);
|
||||
}
|
||||
init_cpu(&cpu);
|
||||
init_cpu(&cpu, renderer);
|
||||
compile(true);
|
||||
|
||||
return 0;
|
||||
@@ -257,6 +266,37 @@ int render() {
|
||||
SDL_RenderCopy(renderer, cpuStateTexture, NULL, &rect2);
|
||||
}
|
||||
|
||||
rect2.x = 530;
|
||||
rect2.y = 50;
|
||||
rect2.w = 0;
|
||||
rect2.h = 0;
|
||||
|
||||
if (gpuSurfDirty) {
|
||||
SDL_UpdateTexture(gpuTex, NULL, gpuSurf->pixels, gpuSurf->pitch);
|
||||
gpuSurfDirty = false;
|
||||
}
|
||||
|
||||
if (gpuTex) {
|
||||
SDL_QueryTexture(gpuTex, NULL, NULL, &rect2.w, &rect2.h);
|
||||
|
||||
SDL_RenderCopy(renderer, gpuTex, NULL, &rect2);
|
||||
}
|
||||
|
||||
render_seven_segment(&displayA, renderer);
|
||||
render_seven_segment(&displayB, renderer);
|
||||
render_seven_segment(&displayC, renderer);
|
||||
render_seven_segment(&displayD, renderer);
|
||||
|
||||
render_seven_segment(&displayE, renderer);
|
||||
render_seven_segment(&displayF, renderer);
|
||||
render_seven_segment(&displayG, renderer);
|
||||
render_seven_segment(&displayH, renderer);
|
||||
|
||||
render_switches_segment(&switchesA, renderer);
|
||||
render_switches_segment(&switchesB, renderer);
|
||||
render_switches_segment(&switchesC, renderer);
|
||||
render_switches_segment(&switchesD, renderer);
|
||||
|
||||
SDL_RenderPresent(renderer);
|
||||
frames++;
|
||||
if (!(frames % 60)) {
|
||||
@@ -440,6 +480,17 @@ int processEvent(SDL_Event e) {
|
||||
move_cursor(&activeEditor, activeEditor.cursor_line, lineLen, false, renderer);
|
||||
moved = true;
|
||||
break;
|
||||
case SDLK_d:
|
||||
if (keyMod & KMOD_CTRL && !activeEditor.readOnly) {
|
||||
insert_line_rel(&activeEditor, renderer);
|
||||
memset(activeEditor.lines[activeEditor.cursor_line].text, 0, activeEditor.max_line_width);
|
||||
strcpy(activeEditor.lines[activeEditor.cursor_line].text,
|
||||
activeEditor.lines[activeEditor.cursor_line - 1].text);
|
||||
activeEditor.lines[activeEditor.cursor_line].active = 1;
|
||||
move_cursor_relative(&activeEditor, 0, activeEditor.max_line_width, false, renderer);
|
||||
generate_string_display(&activeEditor, renderer);
|
||||
}
|
||||
break;
|
||||
case SDLK_F9:
|
||||
cpu.mode ^= CPU_MODE_LOOP;
|
||||
updateState(false);
|
||||
@@ -452,8 +503,9 @@ int processEvent(SDL_Event e) {
|
||||
cpu.mode &= ~CPU_MODE_SECOND;
|
||||
cpu.mode |= CPU_MODE_FRAME;
|
||||
} else if (cpu.mode & CPU_MODE_FRAME) {
|
||||
cpu.mode &= ~CPU_MODE_FRAME;
|
||||
//cpu.mode &= ~CPU_MODE_FRAME;
|
||||
// No specific mode set, defaults to none
|
||||
cpu.mode |= CPU_MODE_STEP; // Restart cycle
|
||||
} else {
|
||||
cpu.mode |= CPU_MODE_STEP; // Restart cycle
|
||||
}
|
||||
@@ -474,6 +526,7 @@ int processEvent(SDL_Event e) {
|
||||
if (keyMod & (KMOD_CTRL | KMOD_SHIFT)) {
|
||||
cpu.mode |= CPU_MODE_HALTED;
|
||||
cpu.pc = 0;
|
||||
init_cpu(&cpu, renderer);
|
||||
}
|
||||
updateState(false);
|
||||
break;
|
||||
@@ -566,6 +619,15 @@ int processEvent(SDL_Event e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (e.type == SDL_MOUSEBUTTONDOWN) {
|
||||
SDL_Rect mouse;
|
||||
mouse.w = 1;
|
||||
mouse.h = 1;
|
||||
SDL_GetMouseState(&mouse.x, &mouse.y);
|
||||
toggle_switch(mouse, &switchesA);
|
||||
toggle_switch(mouse, &switchesB);
|
||||
toggle_switch(mouse, &switchesC);
|
||||
toggle_switch(mouse, &switchesD);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -630,6 +692,21 @@ int main(__attribute__((unused)) int argc, __attribute__((unused)) char *args[])
|
||||
if (cpuStatsTexture) SDL_DestroyTexture(cpuStatsTexture);
|
||||
if (cpuStateTexture) SDL_DestroyTexture(cpuStateTexture);
|
||||
|
||||
destroy_switches_segment(&switchesA);
|
||||
destroy_switches_segment(&switchesB);
|
||||
destroy_switches_segment(&switchesC);
|
||||
destroy_switches_segment(&switchesD);
|
||||
|
||||
destroy_seven_segment(&displayA);
|
||||
destroy_seven_segment(&displayB);
|
||||
destroy_seven_segment(&displayC);
|
||||
destroy_seven_segment(&displayD);
|
||||
|
||||
destroy_seven_segment(&displayE);
|
||||
destroy_seven_segment(&displayF);
|
||||
destroy_seven_segment(&displayG);
|
||||
destroy_seven_segment(&displayH);
|
||||
|
||||
pthread_join(cpu_thread, NULL);
|
||||
if (renderer) SDL_DestroyRenderer(renderer);
|
||||
if (window) SDL_DestroyWindow(window);
|
||||
|
Reference in New Issue
Block a user