mirror of
https://github.com/buserror/mii_emu.git
synced 2024-11-25 20:33:52 +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.h"
|
||||||
#include "mii_bank.h"
|
#include "mii_bank.h"
|
||||||
#include "mii_sw.h"
|
#include "mii_sw.h"
|
||||||
|
#include "mii_thread.h"
|
||||||
|
|
||||||
#define NK_INCLUDE_FIXED_TYPES
|
#define NK_INCLUDE_FIXED_TYPES
|
||||||
#define NK_INCLUDE_STANDARD_IO
|
#define NK_INCLUDE_STANDARD_IO
|
||||||
@ -67,139 +68,6 @@ static GLuint screen_texture;
|
|||||||
static struct nk_image screen_nk;
|
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;
|
extern struct nk_font *nk_main_font;
|
||||||
struct nk_font *nk_mono_font = NULL;
|
struct nk_font *nk_mono_font = NULL;
|
||||||
|
|
||||||
@ -255,8 +123,8 @@ mii_nuklear_init(
|
|||||||
screen_texture, MII_VRAM_WIDTH, MII_VRAM_HEIGHT,
|
screen_texture, MII_VRAM_WIDTH, MII_VRAM_HEIGHT,
|
||||||
nk_rect(0, 0, MII_VIDEO_WIDTH, MII_VIDEO_HEIGHT));
|
nk_rect(0, 0, MII_VIDEO_WIDTH, MII_VIDEO_HEIGHT));
|
||||||
|
|
||||||
/* start the thread */
|
/* start the CPU/emulator thread */
|
||||||
pthread_create(&mii_thread, NULL, mii_thread_func, mii);
|
mii_thread_start(mii);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +139,8 @@ mii_nuklear_handle_input(
|
|||||||
{
|
{
|
||||||
struct nk_input *in = &ctx->input;
|
struct nk_input *in = &ctx->input;
|
||||||
if (in->keyboard.text_len) {
|
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) {
|
if (in->keyboard.text_len < 4) {
|
||||||
mii_keypress(mii, in->keyboard.text[0]);
|
mii_keypress(mii, in->keyboard.text[0]);
|
||||||
} else if (in->keyboard.text_len > 1) {
|
} else if (in->keyboard.text_len > 1) {
|
||||||
@ -283,35 +152,35 @@ mii_nuklear_handle_input(
|
|||||||
if (down) {
|
if (down) {
|
||||||
if (key == 0xffc9) { // F12
|
if (key == 0xffc9) { // F12
|
||||||
if (nk_input_is_key_down(in, NK_KEY_CTRL)) {
|
if (nk_input_is_key_down(in, NK_KEY_CTRL)) {
|
||||||
signal_t sig = {
|
mii_th_signal_t sig = {
|
||||||
.cmd = SIGNAL_RESET,
|
.cmd = SIGNAL_RESET,
|
||||||
.data = nk_input_is_key_down(in, NK_KEY_SHIFT)
|
.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");
|
printf("RESET\n");
|
||||||
}
|
}
|
||||||
} else if (key == 0xffc8) { // F11
|
} else if (key == 0xffc8) { // F11
|
||||||
if (nk_input_is_key_down(in, NK_KEY_CTRL)) {
|
if (nk_input_is_key_down(in, NK_KEY_CTRL)) {
|
||||||
signal_t sig = {
|
mii_th_signal_t sig = {
|
||||||
.cmd = SIGNAL_STOP,
|
.cmd = SIGNAL_STOP,
|
||||||
};
|
};
|
||||||
signal_fifo_write(&signal_fifo, sig);
|
mii_th_fifo_write(mii_thread_get_fifo(mii), sig);
|
||||||
printf("STOP\n");
|
printf("STOP\n");
|
||||||
}
|
}
|
||||||
} else if (key == 0xffc7) { // F10
|
} else if (key == 0xffc7) { // F10
|
||||||
if (nk_input_is_key_down(in, NK_KEY_CTRL)) {
|
if (nk_input_is_key_down(in, NK_KEY_CTRL)) {
|
||||||
signal_t sig = {
|
mii_th_signal_t sig = {
|
||||||
.cmd = SIGNAL_STEP,
|
.cmd = SIGNAL_STEP,
|
||||||
};
|
};
|
||||||
signal_fifo_write(&signal_fifo, sig);
|
mii_th_fifo_write(mii_thread_get_fifo(mii), sig);
|
||||||
printf("STEP\n");
|
printf("STEP\n");
|
||||||
}
|
}
|
||||||
} else if (key == 0xffc6) { // F9
|
} else if (key == 0xffc6) { // F9
|
||||||
if (nk_input_is_key_down(in, NK_KEY_CTRL)) {
|
if (nk_input_is_key_down(in, NK_KEY_CTRL)) {
|
||||||
signal_t sig = {
|
mii_th_signal_t sig = {
|
||||||
.cmd = SIGNAL_RUN,
|
.cmd = SIGNAL_RUN,
|
||||||
};
|
};
|
||||||
signal_fifo_write(&signal_fifo, sig);
|
mii_th_fifo_write(mii_thread_get_fifo(mii), sig);
|
||||||
printf("RUN\n");
|
printf("RUN\n");
|
||||||
}
|
}
|
||||||
} else if (key == 0xffc2) { // F5
|
} else if (key == 0xffc2) { // F5
|
||||||
@ -336,7 +205,7 @@ mii_nuklear_handle_input(
|
|||||||
}
|
}
|
||||||
in->keyboard.text_len = 0;
|
in->keyboard.text_len = 0;
|
||||||
} else {
|
} else {
|
||||||
signal_t sig = {.cmd = -1 };
|
mii_th_signal_t sig = {.cmd = -1 };
|
||||||
if (nk_input_is_key_pressed(in, NK_KEY_ENTER))
|
if (nk_input_is_key_pressed(in, NK_KEY_ENTER))
|
||||||
sig.data = 0x0d;
|
sig.data = 0x0d;
|
||||||
else if (nk_input_is_key_pressed(in, NK_KEY_BACKSPACE))
|
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))
|
else if (nk_input_is_key_pressed(in, NK_KEY_ESCAPE))
|
||||||
sig.data = 0x1b;
|
sig.data = 0x1b;
|
||||||
if (sig.data) {
|
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);
|
// printf("Key %d\n", sig.data);
|
||||||
mii_keypress(mii, sig.data);
|
mii_keypress(mii, sig.data);
|
||||||
}
|
}
|
||||||
@ -585,13 +454,13 @@ mii_nuklear(
|
|||||||
nk_layout_row_static(ctx, 30, 30, 3);
|
nk_layout_row_static(ctx, 30, 30, 3);
|
||||||
|
|
||||||
if (nk_button_symbol(ctx, NK_SYMBOL_RECT_SOLID)) {
|
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)) {
|
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)) {
|
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);
|
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