Select Git revision
psp_board.c
-
Jonas Broeckmann authoredJonas Broeckmann authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
psp_board.c 9.21 KiB
#include "board_impl.h"
#include "../components/lcd.h"
#include "../components/sram_23LC1024.h"
#include "../components/button.h"
#include "../components/led.h"
#include "../components/lcd_gl.h"
#include "../components/led_gl.h"
#include "../components/memvis_gl.h"
typedef struct {
lcd_t lcd;
sram_23LC1024_t extSRAM;
button_t btn1; // Enter
button_t btn2; // Down
button_t btn3; // Up
button_t btn4; // Esc
led_t led1; // Enter
led_t led4; // Down
led_t led3; // Up
led_t led2; // Esc
memvis_gl_t intSRAM_vis;
memvis_gl_t extSRAM_vis;
} psp_board_t;
#define psp_board_get(b, board) psp_board_t *b = (psp_board_t *) (board)->custom
//static lcd_t lcd;
//static sram_23LC1024_t extSRAM;
//static button_t btn1; // Enter
//static button_t btn2; // Down
//static button_t btn3; // Up
//static button_t btn4; // Esc
//static led_t led1; // Enter
//static led_t led4; // Down
//static led_t led3; // Up
//static led_t led2; // Esc
static float spacer = 2.0f;
static int lcdColorTheme = 0;
static lcd_gl_colors_t colors[] = {
{.bg = 0x00AA00FF, .char_bg = 0x00000033, .shadow = 0x00330077, .text = 0x001100FF}, // 0: green
{.bg = 0x5555FFFF, .char_bg = 0x0000AA11, .shadow = 0xFFFFFF22, .text = 0xFFFFFFBB}, // 1: blue
{.bg = 0x000000FF, .char_bg = 0xCCCCCC22, .shadow = 0xFFFFFF55, .text = 0xFFFFFFFF}, // 2: dark white
{.bg = 0x000000FF, .char_bg = 0xCC000022, .shadow = 0xFF000055, .text = 0xFF0000FF}, // 3: dark red
{.bg = 0x002200FF, .char_bg = 0x00CC0044, .shadow = 0x00FF0055, .text = 0x00FF00FF}, // 4: dark green
};
//static memvis_gl_t intSRAM_vis = {
// .cols = 256,
// .cell = {.width = 0.39f, .height = 0.35f}
//};
//static memvis_gl_t extSRAM_vis = {
// .mem = extSRAM.memory,
// .mem_size = 0x10000, // not SRAM_23LC1024_SIZE
// .cols = 256,
// .cell = {.width = 0.39f, .height = 0.35f}
//};
//static void irq_hook(struct avr_irq_t *irq, uint32_t value, void *param) {
// printf("IRQ: %s (0x%x)\n", (char *) param, value);
//}
static BOARD_FUNC_AVR_INIT(board_avr_init, board, avr) {
psp_board_get(b, board);
// Fake an external pull-up so lcd reads can be detected (see https://github.com/buserror/simavr/issues/204)
avr_ioport_external_t exA = {.name = 'A', .mask = 0xFF, .value = 0};
avr_ioctl(avr, AVR_IOCTL_IOPORT_SET_EXTERNAL(exA.name), &exA);
lcd_init(&b->lcd, avr, 16, 2);
lcd_connect4(&b->lcd,
IRQ_IOPORT(avr, 'A', 0),
IRQ_IOPORT(avr, 'A', 1),
IRQ_IOPORT(avr, 'A', 2),
IRQ_IOPORT(avr, 'A', 3),
IRQ_IOPORT(avr, 'A', 4),
IRQ_IOPORT(avr, 'A', 5),
IRQ_IOPORT(avr, 'A', 6));
sram_23LC1024_init(&b->extSRAM, avr);
#if SPI_SLAVE_BITBANG
sram_23LC1024_connect_spi(&b->extSRAM,
IRQ_IOPORT(avr, 'B', 4),
IRQ_IOPORT(avr, 'B', 6),
IRQ_IOPORT(avr, 'B', 7),
IRQ_IOPORT(avr, 'B', 5));
#else
sram_23LC1024_connect_spi(&b->extSRAM,
IRQ_IOPORT(avr, 'B', 4),
IRQ_SPI(avr, 0, SPI_IRQ_OUTPUT),
IRQ_SPI(avr, 0, SPI_IRQ_INPUT));
#endif
// not useful here for some weird reason
// avr_ioport_external_t exC = { .name = 'C', .mask = 0xC3, .value = 0 };
// avr_ioctl(avr, AVR_IOCTL_IOPORT_SET_EXTERNAL(exC.name), &exC);
button_init(&b->btn1, avr); // Enter
button_init(&b->btn2, avr); // Down
button_init(&b->btn3, avr); // Up
button_init(&b->btn4, avr); // Esc
button_connect(&b->btn1, IRQ_IOPORT(avr, 'C', 0));
button_connect(&b->btn2, IRQ_IOPORT(avr, 'C', 1));
button_connect(&b->btn3, IRQ_IOPORT(avr, 'C', 6));
button_connect(&b->btn4, IRQ_IOPORT(avr, 'C', 7));
led_init(&b->led1, avr, false); // Enter
led_init(&b->led2, avr, false); // Down
led_init(&b->led3, avr, false); // Up
led_init(&b->led4, avr, false); // Esc
led_connect(&b->led1, IRQ_IOPORT(avr, 'C', 0));
led_connect(&b->led2, IRQ_IOPORT(avr, 'C', 1));
led_connect(&b->led3, IRQ_IOPORT(avr, 'C', 6));
led_connect(&b->led4, IRQ_IOPORT(avr, 'C', 7));
L_INFO("PSP board initialized");
}
static BOARD_FUNC_GUI_INIT(board_gui_init, board) {
psp_board_get(b, board);
lcd_doPrint = false;
lcd_gl_init();
b->intSRAM_vis = (memvis_gl_t) {
.mem = board->s->sim->avr->data,
.mem_size = board->s->sim->avr->ramend,
.cols = 256,
.cell = {.width = 0.39f, .height = 0.35f}
};
memvis_gl_genColors(&b->intSRAM_vis.colors, MVGL_C_GRAD_SPECTRUM);
memvis_gl_init(&b->intSRAM_vis);
b->extSRAM_vis = (memvis_gl_t) {
.mem = b->extSRAM.memory,
.mem_size = 0x10000, // not SRAM_23LC1024_SIZE
.cols = 256,
.cell = {.width = 0.39f, .height = 0.35f}
};
memvis_gl_genColors(&b->extSRAM_vis.colors, MVGL_C_GRAD_SPECTRUM);
memvis_gl_init(&b->extSRAM_vis);
}
static void board_gui_layout(board_t *board) {
psp_board_get(b, board);
glLSetFont(board->s->gui->fonts.monospace);
glFontSetSizeFactor(glLGetFont(), 1.8f);
glLBeginVertical();
{
// LCD
glLSimpleObject(lcd_gl_draw(&b->lcd, colors[lcdColorTheme]), lcd_gl_getSize(&b->lcd));
glLSpacer(spacer);
// LEDs
glLBeginHorizontal();
{
glLSpacer(spacer);
glLSimpleObject(led_gl_draw(&b->led1, 0x00FF00FF), led_gl_getSize());
glLSpacer(spacer);
glLSimpleObject(led_gl_draw(&b->led4, 0xFF0000FF), led_gl_getSize());
glLSpacer(spacer);
glLSimpleObject(led_gl_draw(&b->led3, 0xFFFFFFFF), led_gl_getSize());
glLSpacer(spacer);
glLSimpleObject(led_gl_draw(&b->led2, 0xFFFFFFFF), led_gl_getSize());
glLSpacer(2 * spacer);
char *avrState;
switch (board->s->sim->avr->state) {
case cpu_Limbo: avrState = nameof(cpu_Limbo); break;
case cpu_Stopped: avrState = nameof(cpu_Stopped); break;
case cpu_Running: avrState = nameof(cpu_Running); break;
case cpu_Sleeping: avrState = nameof(cpu_Sleeping); break;
case cpu_Step: avrState = nameof(cpu_Step); break;
case cpu_StepDone: avrState = nameof(cpu_StepDone); break;
case cpu_Done: avrState = nameof(cpu_Done); break;
case cpu_Crashed: avrState = nameof(cpu_Crashed); break;
default: avrState = "unknown"; break;
}
glLTextF("S: %s C: %llu\nT(s): %.4lfs CT: %6.3lfus/%.3lfus (x%.3lf)\nT(f): %.4lfs FPS: %.2lf",
avrState, board->s->sim->avr->cycle,
fmod(((double) (board->s->sim->currentTime - board->s->sim->startTime) / 1000.0 / 1000.0 / 1000.0), 3600.0),
(double) board->s->sim->lastCycleDelta / 1000.0, (double) board->s->sim->targetCycleDelta / 1000.0,
(double) board->s->sim->targetCycleDelta / (double) board->s->sim->lastCycleDelta,
board->s->gui->currentFrameTime,
board->s->gui->framesPerSecond);
glLSpacer(spacer);
}
glLEndHorizontal();
glLSpacer(spacer);
// Internal SRAM
glLSimpleObject(memvis_gl_draw(&b->intSRAM_vis), memvis_gl_getSize(&b->intSRAM_vis));
glLSpacer(spacer);
// External SRAM
glLSimpleObject(memvis_gl_draw(&b->extSRAM_vis), memvis_gl_getSize(&b->extSRAM_vis));
}
glLEndVertical();
}
static BOARD_FUNC_GUI_GETSIZE(board_gui_getSize, board) {
glLBeginMeasure();
board_gui_layout(board);
return glLEndMeasure();
}
static BOARD_FUNC_GUI_DRAW(board_gui_draw, board) {
glLBeginDraw();
board_gui_layout(board);
glLEndDraw();
// uncomment this for PARTY TIME!
// static time_t lastThemeChange;
// time_t now;
// if (lastThemeChange + 1 <= time(&now)) {
// lcdColorTheme++;
// lcdColorTheme %= 4;
// lastThemeChange = now;
// }
}
#define board_button_key(b, a) do { if (a == GLFW_PRESS) button_hold(b); else if (a == GLFW_RELEASE) button_release(b); } while (0)
static BOARD_FUNC_GUI_ONKEY(board_gui_onKey, board, key, scancode, action, mods) {
psp_board_get(b, board);
switch (key) {
case GLFW_KEY_ENTER : board_button_key(&b->btn1, action); break;
case GLFW_KEY_DOWN : board_button_key(&b->btn2, action); break;
case GLFW_KEY_UP : board_button_key(&b->btn3, action); break;
case GLFW_KEY_ESCAPE: board_button_key(&b->btn4, action); break;
default: break;
}
}
static BOARD_FUNC_CLOSE(board_close, board) {
free(board->custom);
}
BOARD_LOAD_F(board, argc, argv) {
board_configure_log(board);
if (argc > 1) L_WARNING("psp_board: Unused arguments");
board->avr.init = board_avr_init;
board->gui.init = board_gui_init;
board->gui.getSize = board_gui_getSize;
board->gui.draw = board_gui_draw;
board->gui.onKey = board_gui_onKey;
board->close = board_close;
board->custom = calloc(1, sizeof(psp_board_t));
L_INFO("PSP board loaded");
}