mirror of
https://github.com/buserror/mii_emu.git
synced 2024-11-25 05:32:20 +00:00
Split the CPU regulator thread to it's own file
Removed it fron the Nuklear file, as it's actually not doign anything UI based. Also cleanup up type names etc Signed-off-by: Michel Pollet <buserror@gmail.com>
This commit is contained in:
parent
938be1724e
commit
af6ff70155
@ -16,6 +16,7 @@
|
||||
#include "mii.h"
|
||||
#include "mii_bank.h"
|
||||
#include "mii_sw.h"
|
||||
#include "mii_thread.h"
|
||||
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
@ -67,139 +68,6 @@ static GLuint screen_texture;
|
||||
static struct nk_image screen_nk;
|
||||
|
||||
|
||||
#include <time.h>
|
||||
|
||||
typedef uint64_t mii_time_t;
|
||||
enum {
|
||||
MII_TIME_RES = 1,
|
||||
MII_TIME_SECOND = 1000000,
|
||||
MII_TIME_MS = (MII_TIME_SECOND/1000),
|
||||
};
|
||||
mii_time_t
|
||||
mii_get_time()
|
||||
{
|
||||
struct timespec tim;
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &tim);
|
||||
uint64_t time = ((uint64_t)tim.tv_sec) * (1000000 / MII_TIME_RES) +
|
||||
tim.tv_nsec / (1000 * MII_TIME_RES);
|
||||
return time;
|
||||
}
|
||||
|
||||
#include <pthread.h>
|
||||
#include "fifo_declare.h"
|
||||
|
||||
static pthread_t mii_thread;
|
||||
static bool mii_thread_running = false;
|
||||
//static mii_trace_t mii_trace = {};
|
||||
float default_fps = 60;
|
||||
|
||||
enum {
|
||||
SIGNAL_RESET,
|
||||
SIGNAL_STOP,
|
||||
SIGNAL_STEP,
|
||||
SIGNAL_RUN,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t cmd;
|
||||
uint8_t data;
|
||||
} signal_t;
|
||||
|
||||
DECLARE_FIFO(signal_t, signal_fifo, 16);
|
||||
DEFINE_FIFO(signal_t, signal_fifo);
|
||||
|
||||
signal_fifo_t signal_fifo;
|
||||
|
||||
static void *mii_thread_func(void *arg)
|
||||
{
|
||||
mii_t *mii = (mii_t *) arg;
|
||||
mii_thread_running = true;
|
||||
__uint128_t last_cycles = mii->cycles;
|
||||
uint32_t running = 1;
|
||||
unsigned long target_fps_us = 1000000 / default_fps;
|
||||
long sleep_time = target_fps_us;
|
||||
|
||||
//mii_time_t base = mii_get_time(NULL);
|
||||
uint32_t last_frame = mii->video.frame_count;
|
||||
mii_time_t last_frame_stamp = mii_get_time();
|
||||
while (mii_thread_running) {
|
||||
signal_t sig;
|
||||
while (!signal_fifo_isempty(&signal_fifo)) {
|
||||
sig = signal_fifo_read(&signal_fifo);
|
||||
switch (sig.cmd) {
|
||||
case SIGNAL_RESET:
|
||||
mii_reset(mii, sig.data);
|
||||
break;
|
||||
case SIGNAL_STOP:
|
||||
mii_dump_run_trace(mii);
|
||||
mii_dump_trace_state(mii);
|
||||
mii->state = MII_STOPPED;
|
||||
break;
|
||||
case SIGNAL_STEP:
|
||||
mii->state = MII_STEP;
|
||||
running = 1;
|
||||
break;
|
||||
case SIGNAL_RUN:
|
||||
mii->state = MII_RUNNING;
|
||||
last_frame_stamp = mii_get_time();
|
||||
running = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mii->state != MII_STOPPED)
|
||||
mii_run(mii);
|
||||
|
||||
switch (mii->state) {
|
||||
case MII_STOPPED:
|
||||
usleep(1000);
|
||||
break;
|
||||
case MII_STEP:
|
||||
if (running) {
|
||||
running--;
|
||||
mii_dump_trace_state(mii);
|
||||
usleep(1000);
|
||||
running = 1;
|
||||
if (mii->trace.step_inst)
|
||||
mii->trace.step_inst--;
|
||||
if (mii->trace.step_inst == 0)
|
||||
mii->state = MII_STOPPED;
|
||||
}
|
||||
break;
|
||||
case MII_RUNNING:
|
||||
break;
|
||||
case MII_TERMINATE:
|
||||
mii_thread_running = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mii->video.frame_count != last_frame) {
|
||||
sleep_time = target_fps_us;
|
||||
mii_time_t now = mii_get_time();
|
||||
if (mii->state == MII_RUNNING) {
|
||||
mii_time_t delta = now - last_frame_stamp;
|
||||
// printf("frame time %d/%d sleep time %d\n",
|
||||
// (int)delta, (int)target_fps_us,
|
||||
// (int)target_fps_us - delta);
|
||||
sleep_time = target_fps_us - delta;
|
||||
if (sleep_time < 0)
|
||||
sleep_time = 0;
|
||||
last_frame = mii->video.frame_count;
|
||||
while (last_frame_stamp <= now)
|
||||
last_frame_stamp += target_fps_us;
|
||||
|
||||
// calculate the MHz
|
||||
__uint128_t cycles = mii->cycles;
|
||||
__uint128_t delta_cycles = cycles - last_cycles;
|
||||
last_cycles = cycles;
|
||||
mii->speed_current = delta_cycles / (float)target_fps_us;
|
||||
}
|
||||
usleep(sleep_time);
|
||||
}
|
||||
}
|
||||
mii_dispose(mii);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern struct nk_font *nk_main_font;
|
||||
struct nk_font *nk_mono_font = NULL;
|
||||
|
||||
@ -255,8 +123,8 @@ mii_nuklear_init(
|
||||
screen_texture, MII_VRAM_WIDTH, MII_VRAM_HEIGHT,
|
||||
nk_rect(0, 0, MII_VIDEO_WIDTH, MII_VIDEO_HEIGHT));
|
||||
|
||||
/* start the thread */
|
||||
pthread_create(&mii_thread, NULL, mii_thread_func, mii);
|
||||
/* start the CPU/emulator thread */
|
||||
mii_thread_start(mii);
|
||||
|
||||
}
|
||||
|
||||
@ -271,7 +139,8 @@ mii_nuklear_handle_input(
|
||||
{
|
||||
struct nk_input *in = &ctx->input;
|
||||
if (in->keyboard.text_len) {
|
||||
// printf("INPUT %d %s\n", in->keyboard.text_len, in->keyboard.text);
|
||||
// printf("INPUT %d %02x %s\n",
|
||||
// in->keyboard.text_len, in->keyboard.text[0], in->keyboard.text);
|
||||
if (in->keyboard.text_len < 4) {
|
||||
mii_keypress(mii, in->keyboard.text[0]);
|
||||
} else if (in->keyboard.text_len > 1) {
|
||||
@ -283,35 +152,35 @@ mii_nuklear_handle_input(
|
||||
if (down) {
|
||||
if (key == 0xffc9) { // F12
|
||||
if (nk_input_is_key_down(in, NK_KEY_CTRL)) {
|
||||
signal_t sig = {
|
||||
mii_th_signal_t sig = {
|
||||
.cmd = SIGNAL_RESET,
|
||||
.data = nk_input_is_key_down(in, NK_KEY_SHIFT)
|
||||
};
|
||||
signal_fifo_write(&signal_fifo, sig);
|
||||
mii_th_fifo_write(mii_thread_get_fifo(mii), sig);
|
||||
printf("RESET\n");
|
||||
}
|
||||
} else if (key == 0xffc8) { // F11
|
||||
if (nk_input_is_key_down(in, NK_KEY_CTRL)) {
|
||||
signal_t sig = {
|
||||
mii_th_signal_t sig = {
|
||||
.cmd = SIGNAL_STOP,
|
||||
};
|
||||
signal_fifo_write(&signal_fifo, sig);
|
||||
mii_th_fifo_write(mii_thread_get_fifo(mii), sig);
|
||||
printf("STOP\n");
|
||||
}
|
||||
} else if (key == 0xffc7) { // F10
|
||||
if (nk_input_is_key_down(in, NK_KEY_CTRL)) {
|
||||
signal_t sig = {
|
||||
mii_th_signal_t sig = {
|
||||
.cmd = SIGNAL_STEP,
|
||||
};
|
||||
signal_fifo_write(&signal_fifo, sig);
|
||||
mii_th_fifo_write(mii_thread_get_fifo(mii), sig);
|
||||
printf("STEP\n");
|
||||
}
|
||||
} else if (key == 0xffc6) { // F9
|
||||
if (nk_input_is_key_down(in, NK_KEY_CTRL)) {
|
||||
signal_t sig = {
|
||||
mii_th_signal_t sig = {
|
||||
.cmd = SIGNAL_RUN,
|
||||
};
|
||||
signal_fifo_write(&signal_fifo, sig);
|
||||
mii_th_fifo_write(mii_thread_get_fifo(mii), sig);
|
||||
printf("RUN\n");
|
||||
}
|
||||
} else if (key == 0xffc2) { // F5
|
||||
@ -336,7 +205,7 @@ mii_nuklear_handle_input(
|
||||
}
|
||||
in->keyboard.text_len = 0;
|
||||
} else {
|
||||
signal_t sig = {.cmd = -1 };
|
||||
mii_th_signal_t sig = {.cmd = -1 };
|
||||
if (nk_input_is_key_pressed(in, NK_KEY_ENTER))
|
||||
sig.data = 0x0d;
|
||||
else if (nk_input_is_key_pressed(in, NK_KEY_BACKSPACE))
|
||||
@ -354,7 +223,7 @@ mii_nuklear_handle_input(
|
||||
else if (nk_input_is_key_pressed(in, NK_KEY_ESCAPE))
|
||||
sig.data = 0x1b;
|
||||
if (sig.data) {
|
||||
// signal_fifo_write(&signal_fifo, sig);
|
||||
// mii_th_fifo_write(mii_thread_get_fifo(mii), sig);
|
||||
// printf("Key %d\n", sig.data);
|
||||
mii_keypress(mii, sig.data);
|
||||
}
|
||||
@ -585,13 +454,13 @@ mii_nuklear(
|
||||
nk_layout_row_static(ctx, 30, 30, 3);
|
||||
|
||||
if (nk_button_symbol(ctx, NK_SYMBOL_RECT_SOLID)) {
|
||||
signal_fifo_write(&signal_fifo, (signal_t){.cmd = SIGNAL_STOP});
|
||||
mii_th_fifo_write(mii_thread_get_fifo(mii), (mii_th_signal_t){.cmd = SIGNAL_STOP});
|
||||
}
|
||||
if (nk_button_symbol(ctx, NK_SYMBOL_PLUS)) {
|
||||
signal_fifo_write(&signal_fifo, (signal_t){.cmd = SIGNAL_STEP});
|
||||
mii_th_fifo_write(mii_thread_get_fifo(mii), (mii_th_signal_t){.cmd = SIGNAL_STEP});
|
||||
}
|
||||
if (nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_RIGHT)) {
|
||||
signal_fifo_write(&signal_fifo, (signal_t){.cmd = SIGNAL_RUN});
|
||||
mii_th_fifo_write(mii_thread_get_fifo(mii), (mii_th_signal_t){.cmd = SIGNAL_RUN});
|
||||
}
|
||||
nk_layout_row_dynamic(ctx, 20, 3);
|
||||
{
|
||||
|
146
nuklear/mii_thread.c
Normal file
146
nuklear/mii_thread.c
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* mii_thread.c
|
||||
*
|
||||
* Copyright (C) 2023 Michel Pollet <buserror@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "mii.h"
|
||||
#include "mii_thread.h"
|
||||
|
||||
typedef uint64_t mii_time_t;
|
||||
enum {
|
||||
MII_TIME_RES = 1,
|
||||
MII_TIME_SECOND = 1000000,
|
||||
MII_TIME_MS = (MII_TIME_SECOND/1000),
|
||||
};
|
||||
mii_time_t
|
||||
mii_get_time()
|
||||
{
|
||||
struct timespec tim;
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &tim);
|
||||
uint64_t time = ((uint64_t)tim.tv_sec) * (1000000 / MII_TIME_RES) +
|
||||
tim.tv_nsec / (1000 * MII_TIME_RES);
|
||||
return time;
|
||||
}
|
||||
|
||||
|
||||
static pthread_t mii_thread;
|
||||
static bool mii_thread_running = false;
|
||||
static float default_fps = 60;
|
||||
mii_th_fifo_t signal_fifo;
|
||||
|
||||
static void *
|
||||
mii_thread_func(
|
||||
void *arg)
|
||||
{
|
||||
mii_t *mii = (mii_t *) arg;
|
||||
mii_thread_running = true;
|
||||
__uint128_t last_cycles = mii->cycles;
|
||||
uint32_t running = 1;
|
||||
unsigned long target_fps_us = 1000000 / default_fps;
|
||||
long sleep_time = target_fps_us;
|
||||
|
||||
//mii_time_t base = mii_get_time(NULL);
|
||||
uint32_t last_frame = mii->video.frame_count;
|
||||
mii_time_t last_frame_stamp = mii_get_time();
|
||||
while (mii_thread_running) {
|
||||
mii_th_signal_t sig;
|
||||
while (!mii_th_fifo_isempty(&signal_fifo)) {
|
||||
sig = mii_th_fifo_read(&signal_fifo);
|
||||
switch (sig.cmd) {
|
||||
case SIGNAL_RESET:
|
||||
mii_reset(mii, sig.data);
|
||||
break;
|
||||
case SIGNAL_STOP:
|
||||
mii_dump_run_trace(mii);
|
||||
mii_dump_trace_state(mii);
|
||||
mii->state = MII_STOPPED;
|
||||
break;
|
||||
case SIGNAL_STEP:
|
||||
mii->state = MII_STEP;
|
||||
running = 1;
|
||||
break;
|
||||
case SIGNAL_RUN:
|
||||
mii->state = MII_RUNNING;
|
||||
last_frame_stamp = mii_get_time();
|
||||
running = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mii->state != MII_STOPPED)
|
||||
mii_run(mii);
|
||||
|
||||
switch (mii->state) {
|
||||
case MII_STOPPED:
|
||||
usleep(1000);
|
||||
break;
|
||||
case MII_STEP:
|
||||
if (running) {
|
||||
running--;
|
||||
mii_dump_trace_state(mii);
|
||||
usleep(1000);
|
||||
running = 1;
|
||||
if (mii->trace.step_inst)
|
||||
mii->trace.step_inst--;
|
||||
if (mii->trace.step_inst == 0)
|
||||
mii->state = MII_STOPPED;
|
||||
}
|
||||
break;
|
||||
case MII_RUNNING:
|
||||
break;
|
||||
case MII_TERMINATE:
|
||||
mii_thread_running = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (mii->video.frame_count != last_frame) {
|
||||
sleep_time = target_fps_us;
|
||||
mii_time_t now = mii_get_time();
|
||||
if (mii->state == MII_RUNNING) {
|
||||
mii_time_t delta = now - last_frame_stamp;
|
||||
// printf("frame time %d/%d sleep time %d\n",
|
||||
// (int)delta, (int)target_fps_us,
|
||||
// (int)target_fps_us - delta);
|
||||
sleep_time = target_fps_us - delta;
|
||||
if (sleep_time < 0)
|
||||
sleep_time = 0;
|
||||
last_frame = mii->video.frame_count;
|
||||
while (last_frame_stamp <= now)
|
||||
last_frame_stamp += target_fps_us;
|
||||
|
||||
// calculate the MHz
|
||||
__uint128_t cycles = mii->cycles;
|
||||
__uint128_t delta_cycles = cycles - last_cycles;
|
||||
last_cycles = cycles;
|
||||
mii->speed_current = delta_cycles / (float)target_fps_us;
|
||||
}
|
||||
usleep(sleep_time);
|
||||
}
|
||||
}
|
||||
mii_dispose(mii);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
mii_thread_start(
|
||||
mii_t *mii)
|
||||
{
|
||||
const mii_th_fifo_t zero = {};
|
||||
signal_fifo = zero;
|
||||
pthread_create(&mii_thread, NULL, mii_thread_func, mii);
|
||||
}
|
||||
|
||||
struct mii_th_fifo_t*
|
||||
mii_thread_get_fifo(
|
||||
struct mii_t *mii)
|
||||
{
|
||||
return &signal_fifo;
|
||||
}
|
36
nuklear/mii_thread.h
Normal file
36
nuklear/mii_thread.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* mii_thread.h
|
||||
*
|
||||
* Copyright (C) 2023 Michel Pollet <buserror@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "fifo_declare.h"
|
||||
|
||||
enum {
|
||||
SIGNAL_RESET,
|
||||
SIGNAL_STOP,
|
||||
SIGNAL_STEP,
|
||||
SIGNAL_RUN,
|
||||
};
|
||||
|
||||
typedef struct mii_th_signal_t {
|
||||
uint8_t cmd;
|
||||
uint8_t data;
|
||||
} mii_th_signal_t;
|
||||
|
||||
DECLARE_FIFO(mii_th_signal_t, mii_th_fifo, 16);
|
||||
DEFINE_FIFO(mii_th_signal_t, mii_th_fifo);
|
||||
|
||||
struct mii_t;
|
||||
|
||||
void
|
||||
mii_thread_start(
|
||||
struct mii_t *mii);
|
||||
struct mii_th_fifo_t*
|
||||
mii_thread_get_fifo(
|
||||
struct mii_t *mii);
|
Loading…
Reference in New Issue
Block a user