diff --git a/board/sdl2/board.toml b/board/sdl2/board.toml index 731cda7..32cbb96 100644 --- a/board/sdl2/board.toml +++ b/board/sdl2/board.toml @@ -7,7 +7,9 @@ modules = [ 'display', 'hypervisor', 'timer', - 'keyboard' + 'keyboard', + 'dma', + 'rtc' ] [drivers] diff --git a/board/sdl2/initialize.c b/board/sdl2/initialize.c index c9235eb..ce2b559 100644 --- a/board/sdl2/initialize.c +++ b/board/sdl2/initialize.c @@ -5,15 +5,10 @@ extern void kinit(void); -__attribute__((constructor)) +__attribute__((constructor(101))) int _initialize(void) { - printf("early kernel initialisation..."); - - /* initialize drivers and modules */ + printf("early kernel initialisation...\n"); kinit(); - - printf("OK\n"); - return 0; } diff --git a/src/driver/mpu/sh/sh7305/keysc/keycache.c b/src/driver/mpu/sh/sh7305/keysc/keycache.c index 00805d7..159d66d 100644 --- a/src/driver/mpu/sh/sh7305/keysc/keycache.c +++ b/src/driver/mpu/sh/sh7305/keysc/keycache.c @@ -86,6 +86,9 @@ int sh7305_keycache_keydown(vkey_t key) /* sh7305_keycache_event_push() : push event on the keycache */ int sh7305_keycache_event_push(vkey_event_t *event) { + if (event == NULL) + return -1; + cpu_atomic_start(); keyinfo.queue.idx += 1; @@ -114,13 +117,17 @@ int sh7305_keycache_event_pop(vkey_event_t *event) cpu_atomic_start(); if (keyinfo.queue.idx < 0) { - event->key = VKEY_NONE; - event->type = VKEYEV_NONE; + if (event != NULL) { + event->key = VKEY_NONE; + event->type = VKEYEV_NONE; + } ret = 0; } else { - event->time = keyinfo.queue.list[0].time; - event->type = keyinfo.queue.list[0].type; - event->key = keyinfo.queue.list[0].key; + if (event != NULL) { + event->time = keyinfo.queue.list[0].time; + event->type = keyinfo.queue.list[0].type; + event->key = keyinfo.queue.list[0].key; + } memcpy( &keyinfo.queue.list[0], @@ -137,14 +144,16 @@ int sh7305_keycache_event_pop(vkey_event_t *event) } /* sh7305_keycache_event_wait() : wait event or timeout != 0 */ -int sh7305_keycache_event_wait(vkey_event_t *e, volatile int *timeout) +int sh7305_keycache_event_wait(vkey_event_t *event, volatile int *timeout) { do { - if (sh7305_keycache_event_pop(e)) + if (sh7305_keycache_event_pop(event)) return 1; if (timeout != NULL && timeout != 0) { - e->type = VKEYEV_NONE; - e->key = VKEY_NONE; + if (event != NULL) { + event->type = VKEYEV_NONE; + event->key = VKEY_NONE; + } return 0; } __asm__("sleep"); diff --git a/src/driver/mpu/sh/sh7305/rtc/rtc.c b/src/driver/mpu/sh/sh7305/rtc/rtc.c index a8cadb7..57ba5e7 100644 --- a/src/driver/mpu/sh/sh7305/rtc/rtc.c +++ b/src/driver/mpu/sh/sh7305/rtc/rtc.c @@ -56,6 +56,75 @@ void sh7305_rtc_periodic_disable(void) SH7305_RTC.RCR2.PES = RTC_NONE; } + + +//--- +// User API +//--- + +/* int8(), int16(): Convert BCD to integer */ +static int int8(uint8_t bcd) +{ + return (bcd & 0x0f) + 10 * (bcd >> 4); +} +static int int16(uint16_t bcd) +{ + return (bcd & 0xf) + 10 * ((bcd >> 4) & 0xf) + 100 * ((bcd >> 8) & 0xf) + + 1000 * (bcd >> 12); +} + +/* bcd8(), bcd16(): Convert integer to BCD */ +static uint8_t bcd8(int integer) +{ + integer %= 100; + return ((integer / 10) << 4) | (integer % 10); +} +static uint16_t bcd16(int integer) +{ + integer %= 10000; + return (bcd8(integer / 100) << 8) | bcd8(integer % 100); +} + +/* sh7305_rtc_get_time(): Read the current time from the RTC */ +int sh7305_rtc_get_time(rtc_time_t *time) +{ + do { + SH7305_RTC.RCR1.CF = 0; + + time->ticks = SH7305_RTC.R64CNT; + time->seconds = int8(SH7305_RTC.RSECCNT.byte); + time->minutes = int8(SH7305_RTC.RMINCNT.byte); + time->hours = int8(SH7305_RTC.RHRCNT.byte); + time->month_day = int8(SH7305_RTC.RDAYCNT.byte); + time->month = int8(SH7305_RTC.RMONCNT.byte); + time->year = int16(SH7305_RTC.RYRCNT.word); + time->week_day = SH7305_RTC.RWKCNT; + + } while(SH7305_RTC.RCR1.CF != 0); + return 0; +} + +/* sh7305_rtc_set_time(): Set current time in the RTC */ +int sh7305_rtc_set_time(rtc_time_t const *time) +{ + int wday = time->week_day; + if(wday >= 7) wday = 0; + + do { + SH7305_RTC.RCR1.CF = 0; + + SH7305_RTC.RSECCNT.byte = bcd8(time->seconds); + SH7305_RTC.RMINCNT.byte = bcd8(time->minutes); + SH7305_RTC.RHRCNT.byte = bcd8(time->hours); + SH7305_RTC.RDAYCNT.byte = bcd8(time->month_day); + SH7305_RTC.RMONCNT.byte = bcd8(time->month); + SH7305_RTC.RYRCNT.word = bcd16(time->year); + SH7305_RTC.RWKCNT = wday; + + } while(SH7305_RTC.RCR1.CF != 0); + return 0; +} + //--- // Define driver information //--- @@ -151,77 +220,6 @@ static void __rtc_hrestore(struct rtc_ctx *state) SH7305_RTC.RCR2.START = state->rtc.RCR2.START; } -//--- -// User API -//--- - -/* int8(), int16(): Convert BCD to integer */ -static int int8(uint8_t bcd) -{ - return (bcd & 0x0f) + 10 * (bcd >> 4); -} -static int int16(uint16_t bcd) -{ - return (bcd & 0xf) + 10 * ((bcd >> 4) & 0xf) + 100 * ((bcd >> 8) & 0xf) - + 1000 * (bcd >> 12); -} - -/* bcd8(), bcd16(): Convert integer to BCD */ -static uint8_t bcd8(int integer) -{ - integer %= 100; - return ((integer / 10) << 4) | (integer % 10); -} -static uint16_t bcd16(int integer) -{ - integer %= 10000; - return (bcd8(integer / 100) << 8) | bcd8(integer % 100); -} - -/* sh7305_rtc_get_time(): Read the current time from the RTC */ -int sh7305_rtc_get_time(rtc_time_t *time) -{ - do { - SH7305_RTC.RCR1.CF = 0; - - time->ticks = SH7305_RTC.R64CNT; - time->seconds = int8(SH7305_RTC.RSECCNT.byte); - time->minutes = int8(SH7305_RTC.RMINCNT.byte); - time->hours = int8(SH7305_RTC.RHRCNT.byte); - time->month_day = int8(SH7305_RTC.RDAYCNT.byte); - time->month = int8(SH7305_RTC.RMONCNT.byte); - time->year = int16(SH7305_RTC.RYRCNT.word); - time->week_day = SH7305_RTC.RWKCNT; - - } while(SH7305_RTC.RCR1.CF != 0); - return 0; -} - -/* sh7305_rtc_set_time(): Set current time in the RTC */ -int sh7305_rtc_set_time(rtc_time_t const *time) -{ - int wday = time->week_day; - if(wday >= 7) wday = 0; - - do { - SH7305_RTC.RCR1.CF = 0; - - SH7305_RTC.RSECCNT.byte = bcd8(time->seconds); - SH7305_RTC.RMINCNT.byte = bcd8(time->minutes); - SH7305_RTC.RHRCNT.byte = bcd8(time->hours); - SH7305_RTC.RDAYCNT.byte = bcd8(time->month_day); - SH7305_RTC.RMONCNT.byte = bcd8(time->month); - SH7305_RTC.RYRCNT.word = bcd16(time->year); - SH7305_RTC.RWKCNT = wday; - - } while(SH7305_RTC.RCR1.CF != 0); - return 0; -} - -//--- -// Declare driver -//--- - struct vhex_driver drv_rtc = { .name = "RTC", .hpowered = (void*)&__rtc_hpowered, diff --git a/src/driver/mpu/x86/sdl2/dma.c b/src/driver/mpu/x86/sdl2/dma.c new file mode 100644 index 0000000..2020743 --- /dev/null +++ b/src/driver/mpu/x86/sdl2/dma.c @@ -0,0 +1,76 @@ +#include +#include +#include + +#include +#include + +/* dma_memcpy() : memcpy using DMA */ +dma_id_t sdl_dma_memcpy(void * restrict dst, void * restrict src, size_t sz) +{ + memcpy(dst, src, sz); + return 0; +} + +/* dma_memset() : memset using the DMA */ +dma_id_t sdl_dma_memset(void *dst, int c, size_t sz) +{ + memset(dst, c, sz); + return 0; +} + +/* dma_wait() : wait the end of the DMA channel transfer */ +int sdl_dma_wait(dma_id_t id) +{ + (void)id; + return 0; +} + +/* dma_wait() : wait the end of the DMA channel transfer without interruption */ +int sdl_dma_spinwait(dma_id_t id) +{ + (void)id; + return 0; +} + +//--- +// Fake driver definition +//--- + +static void __dma_configure(void) +{ + // Nothing to do, this is a fake driver + printf("[drv] DMA: fake driver initialized\n"); +} + +static void __dma_hsave(void) +{ + // Nothing to do, this is a fake driver + ; +} + +static void __dma_hrestore(void) +{ + // Nothing to do, this is a fake driver + ; +} + +struct vhex_driver drv_dma = { + .name = "SDL2 DMA", + .hsave = (void*)&__dma_hsave, + .hrestore = (void*)&__dma_hrestore, + .configure = (void*)&__dma_configure, + .state_size = 4, + .flags = { + .DMA = 1, + .SHARED = 0, + .UNUSED = 0, + }, + .module_data = &(struct dma_drv_interface){ + .dma_memcpy = &sdl_dma_memcpy, + .dma_memset = &sdl_dma_memset, + .dma_wait = &sdl_dma_wait, + .dma_spinwait = &sdl_dma_spinwait + } +}; +VHEX_DECLARE_DRIVER(05, drv_dma); diff --git a/src/driver/mpu/x86/sdl2/keyboard.c b/src/driver/mpu/x86/sdl2/keyboard.c index 9ca67be..34d4395 100644 --- a/src/driver/mpu/x86/sdl2/keyboard.c +++ b/src/driver/mpu/x86/sdl2/keyboard.c @@ -20,24 +20,74 @@ static struct { static struct { int sdl2_id; + char const * const sdl2_name; int vhex_id; + char const * const vhex_name; } key_translation[16] = { - { .sdl2_id = 49, .vhex_id = VKEY_F1 }, // 1 - { .sdl2_id = 50, .vhex_id = VKEY_F2 }, // 2 - { .sdl2_id = 51, .vhex_id = VKEY_F3 }, // 3 - { .sdl2_id = 52, .vhex_id = VKEY_F4 }, // 4 - { .sdl2_id = 53, .vhex_id = VKEY_F5 }, // 5 - { .sdl2_id = 54, .vhex_id = VKEY_F6 }, // 6 - { .sdl2_id = 0x4000004f, .vhex_id = VKEY_RIGHT }, // right arrow - { .sdl2_id = 0x40000050, .vhex_id = VKEY_LEFT }, // left arrow - { .sdl2_id = 0x40000051, .vhex_id = VKEY_DOWN }, // down arrow - { .sdl2_id = 0x40000052, .vhex_id = VKEY_UP }, // up arrow - { .sdl2_id = 13, .vhex_id = VKEY_EXE }, // enter - { .sdl2_id = 0x400000e0, .vhex_id = VKEY_ALPHA }, // shift - { .sdl2_id = 0x400000e1, .vhex_id = VKEY_SHIFT }, // ctrl - { .sdl2_id = 27, .vhex_id = VKEY_EXIT }, // echap - { .sdl2_id = 8, .vhex_id = VKEY_DEL }, // backspace - { .sdl2_id = 9, .vhex_id = VKEY_MENU }, // tab + { + .sdl2_id = 49, .sdl2_name = "1", + .vhex_id = VKEY_F1, .vhex_name = "F1" + }, + { + .sdl2_id = 50, .sdl2_name = "2", + .vhex_id = VKEY_F2, .vhex_name = "F2" + }, + { + .sdl2_id = 51, .sdl2_name = "3", + .vhex_id = VKEY_F3, .vhex_name = "F3" + }, + { + .sdl2_id = 52, .sdl2_name = "4", + .vhex_id = VKEY_F4, .vhex_name = "F4" + }, + { + .sdl2_id = 53, .sdl2_name = "5", + .vhex_id = VKEY_F5, .vhex_name = "F5" + }, + { + .sdl2_id = 54, .sdl2_name = "6", + .vhex_id = VKEY_F6, .vhex_name = "F6" + }, + { + .sdl2_id = 0x4000004f, .sdl2_name = "right arrow", + .vhex_id = VKEY_RIGHT, .vhex_name = "right arrow" + }, + { + .sdl2_id = 0x40000050, .sdl2_name = "left arrow", + .vhex_id = VKEY_LEFT, .vhex_name = "left arrow" + }, + { + .sdl2_id = 0x40000051, .sdl2_name = "down arrow", + .vhex_id = VKEY_DOWN, .vhex_name = "down arrow" + }, + { + .sdl2_id = 0x40000052, .sdl2_name = "up arrow", + .vhex_id = VKEY_UP, .vhex_name = "up arrow" + }, + { + .sdl2_id = 13, .sdl2_name = "enter", + .vhex_id = VKEY_EXE, .vhex_name = "EXE" + }, + { + .sdl2_id = 0x400000e0, .sdl2_name = "shift", + .vhex_id = VKEY_ALPHA, .vhex_name = "ALPHA" + }, + { + .sdl2_id = 0x400000e1, .sdl2_name = "ctrl", + .vhex_id = VKEY_SHIFT, .vhex_name = "SHIFT" + }, + { + .sdl2_id = 27, .sdl2_name = "echap", + .vhex_id = VKEY_EXIT, .vhex_name = "EXIT" + }, + { + .sdl2_id = 8, .sdl2_name = "backspace", + .vhex_id = VKEY_DEL, .vhex_name = "DEL" + }, + { + .sdl2_id = 9, .sdl2_name = "tab", + .vhex_id = VKEY_MENU, .vhex_name = "MENU" + }, }; @@ -52,14 +102,14 @@ static int sdl_keycache_event_pop(vkey_event_t *event) SDL_Event evt; int ret; - if (event == NULL) - return -1; - while (1) { ret = SDL_PollEvent(&evt); if (ret == 0) { - event->key = VKEY_NONE; + if (event != NULL) { + event->key = VKEY_NONE; + event->type = VKEYEV_NONE; + } return 0; } @@ -72,9 +122,13 @@ static int sdl_keycache_event_pop(vkey_event_t *event) if (evt.key.keysym.sym != key_translation[i].sdl2_id) continue; - event->time = 0; - event->type = (evt.type == SDL_KEYDOWN) ? VKEYEV_DOWN : VKEYEV_UP; - event->key = key_translation[i].vhex_id; + if (event != NULL) { + event->time = 0; + event->key = key_translation[i].vhex_id; + event->type = VKEYEV_DOWN; + if (evt.type == SDL_KEYDOWN) + event->type = VKEYEV_UP; + } return 1; } } @@ -88,8 +142,18 @@ static int sdl_keycache_event_pop(vkey_event_t *event) /* __keysc_configure() : configure the keyboard module */ static void __keysc_configure(void) { - // Nothing to do, this is a fake driver - ; + printf("[drv] keyboard: keymap notes:\n"); + printf(" +-------------+-------------+\n"); + printf(" | OS | Vhex |\n"); + printf(" +-------------+-------------+\n"); + for (int i = 0; i < __SDL2_KEYCODE_SUPPORTED; ++i) { + printf( + " | %-11s | %-11s |\n", + key_translation[i].sdl2_name, + key_translation[i].vhex_name + ); + } + printf(" +-------------+-------------+\n"); } /* __keysc_hsave() : save hardware information */ diff --git a/src/driver/mpu/x86/sdl2/rtc.c b/src/driver/mpu/x86/sdl2/rtc.c new file mode 100644 index 0000000..b274040 --- /dev/null +++ b/src/driver/mpu/x86/sdl2/rtc.c @@ -0,0 +1,72 @@ +#include +#include +#include + +#include +#include + +/* sdl_rtc_get_time(): Read the current time from the RTC */ +int sdl_rtc_get_time(rtc_time_t *rtc) +{ + time_t rtime; + struct tm *tinfo; + + if (rtc == NULL) + return -1; + + time(&rtime); + tinfo = localtime(&rtime); + + rtc->ticks = 0; + rtc->seconds = tinfo->tm_sec; + rtc->minutes = tinfo->tm_min; + rtc->hours = tinfo->tm_hour; + rtc->month_day = tinfo->tm_mday; + rtc->month = tinfo->tm_mon; + rtc->year = tinfo->tm_year + 1900; + rtc->week_day = tinfo->tm_wday; + return 0; +} + +//--- +// Fake driver definition +//--- + +/* __rtc_configure() : configure the RTC */ +static void __rtc_configure(void) +{ + // Nothing to do, this is a fake driver + printf("[drv] RTC: fake driver initialized\n"); +} + +/* __rtc_hsave() : save hardware information */ +static void __rtc_hsave(void) +{ + // Nothing to do, this is a fake driver + ; +} + +/* __rtc_hrestore() : restore hardware information */ +static void __rtc_hrestore(void) +{ + // Nothing to do, this is a fake driver + ; +} + +struct vhex_driver drv_rtc = { + .name = "SDL2 RTC", + .hsave = (void*)&__rtc_hsave, + .hrestore = (void*)&__rtc_hrestore, + .configure = (void*)&__rtc_configure, + .state_size = 4, + .flags = { + .RTC = 1, + .SHARED = 0, + .UNUSED = 0, + }, + .module_data = &(struct rtc_drv_interface){ + .rtc_get_time = &sdl_rtc_get_time, + .rtc_set_time = NULL, + } +}; +VHEX_DECLARE_DRIVER(06, drv_rtc); diff --git a/src/driver/mpu/x86/sdl2/timer.c b/src/driver/mpu/x86/sdl2/timer.c index 87faabc..0fa1466 100644 --- a/src/driver/mpu/x86/sdl2/timer.c +++ b/src/driver/mpu/x86/sdl2/timer.c @@ -222,6 +222,7 @@ void sdl_tmu_fps_quit(fps_t *fps) static void __tmu_configure(void) { + printf("[drv] TMU: fake driver initialized\n"); for (int i = 0; i < 9; ++i) { timer_cache[i].used = false; timer_cache[i].id = 0; diff --git a/src/driver/mpu/x86/sdl2/window.c b/src/driver/mpu/x86/sdl2/window.c index 18e5bc2..248827e 100644 --- a/src/driver/mpu/x86/sdl2/window.c +++ b/src/driver/mpu/x86/sdl2/window.c @@ -37,18 +37,37 @@ int sdl_frame_frag_next(dsurface_t *surface) int sdl_frame_frag_send(dsurface_t *surface) { - SDL_SetWindowSize(__sdl_window, 396, 224); + SDL_SetWindowSize(__sdl_window, 396 * 2, 224 * 2); SDL_Surface *src = SDL_CreateRGBSurface( - 0, 396, 224, 24, + 0, 396 * 2, 224 * 2, 24, 0x000000ff, 0x0000ff00, 0x0000ff00, 0 ); uint16_t *vram = surface->vram; - uint8_t *display = src->pixels; - for (int i = 0; i < 396 * 224; ++i){ - display[(i * 3) + 0] = (((vram[i] & 0xf800) >> 11) * 255) / 31; - display[(i * 3) + 1] = (((vram[i] & 0x07e0) >> 5) * 255) / 63; - display[(i * 3) + 2] = (((vram[i] & 0x001f) >> 0) * 255) / 31; + uint8_t *disp = src->pixels; + + int r; + int g; + int b; + + off_t yoff = 0; + for (int y = 0 ; y < 224; ++y) { + for (int x = 0; x < 396 ; ++x) { + r = (((vram[(y * 396) + x] & 0xf800) >> 11) * 255) / 31; + g = (((vram[(y * 396) + x] & 0x07e0) >> 5) * 255) / 63; + b = (((vram[(y * 396) + x] & 0x001f) >> 0) * 255) / 31; + + disp[yoff + (x * 6) + 0] = r; + disp[yoff + (x * 6) + 1] = g; + disp[yoff + (x * 6) + 2] = b; + + disp[yoff + (x * 6) + 3] = r; + disp[yoff + (x * 6) + 4] = g; + disp[yoff + (x * 6) + 5] = b; + } + memcpy(&disp[yoff + (396 * 6)], &disp[yoff], 396 * 6); + yoff += 396 * 6; + yoff += 396 * 6; } SDL_Surface *dst = SDL_GetWindowSurface(__sdl_window); @@ -72,13 +91,13 @@ int sdl_frame_end(dsurface_t *surface) static int __sdl_configure(void) { - + printf("[drv] LCD: fake driver initialized\n"); __sdl_window = SDL_CreateWindow( "vxKernel", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - 396, - 224, + 396 * 2, + 224 * 2, 0 ); return 0;