Skip to content
Snippets Groups Projects
Select Git revision
  • develop default
  • master protected
  • v2.3.4 protected
3 results

psp_board.c

Blame
  • 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");
    }