#include #include #include #include //--- // R61524 driver API //--- /* r61524_clear_surface() - optimal way to clear the draw and render surface */ VINLINE void r61524_clear_surface(struct dshader_surface *surface) { uint32_t *xram = surface->draw; int size = (surface->y1 == 220) ? 792 : 1980; for (int i = 0; i < size; ++i) { xram[i] = 0x00010001; } } /* r61524_frame_start() - prepar the screen and reset surfaces */ int r61524_frame_start(struct dshader_surface *surface) { /* Set the windows size */ r61524_select(horizontal_ram_start); r61524_write(0); r61524_select(horizontal_ram_end); r61524_write(395); r61524_select(vertical_ram_start); r61524_write(0); r61524_select(vertical_ram_end); r61524_write(223); /* Set the RAM position */ r61524_select(ram_address_horizontal); r61524_write(0); r61524_select(ram_address_vertical); r61524_write(0); /* Bind address 0xb4000000 to the data write command */ r61524_select(write_data); /* initialize surface information */ surface->draw = (void*)0xe5007000; surface->frag = (void*)0xe5017000; surface->width = 396; surface->height = 10; surface->x1 = 0; surface->y1 = 0; surface->x2 = 395; surface->y2 = 9; /* reset the two surfaces */ r61524_clear_surface(surface); return (0); } int r61524_frame_frag_next(struct dshader_surface *surface) { surface->y1 += 10; if (surface->y1 >= 224) { surface->y1 -= 10; return (-1); } if (surface->y1 >= 220) surface->height = 4; surface->y2 += surface->height; return (0); } VWEAK int r61524_frame_frag_send(struct dshader_surface *surface) { uint16_t * restrict yram = surface->frag; int size = (surface->y1 == 220) ? 1584 : 3960; for (int i = 0; i < size; ++i) { r61524_write(yram[i]); } return (0); } int r61524_frame_end(struct dshader_surface *surface) { (void)surface; return (0); } //--- // Driver definition //--- /* R61524 display (graphics RAM range) */ struct r61524_ctx { uint16_t HSA; uint16_t HEA; uint16_t VSA; uint16_t VEA; }; static void __r61524_configure(struct r61524_ctx *s) { s->HSA = 0; s->HEA = 395; s->VSA = 0; s->VEA = 223; } static void __r61524_hsave(struct r61524_ctx *s) { r61524_select(horizontal_ram_start); s->HSA = r61524_read(); r61524_select(horizontal_ram_end); s->HEA = r61524_read(); r61524_select(vertical_ram_start); s->VSA = r61524_read(); r61524_select(vertical_ram_end); s->VEA = r61524_read(); } static void __r61524_hrestore(struct r61524_ctx const *s) { r61524_select(horizontal_ram_start); r61524_write(s->HSA); r61524_select(horizontal_ram_end); r61524_write(s->HEA); r61524_select(vertical_ram_start); r61524_write(s->VSA); r61524_select(vertical_ram_end); r61524_write(s->VEA); } struct vhex_driver drv_r61524 = { .name = "R61524", .hsave = (void*)&__r61524_hsave, .hrestore = (void*)&__r61524_hrestore, .configure = (void*)&__r61524_configure, .state_size = sizeof(struct r61524_ctx), .flags = { .DISPLAY = 1, .SHARED = 0, .UNUSED = 0, }, .module_data = &(struct dstack_drv_interface){ .frame_start = &r61524_frame_start, .frame_frag_next = &r61524_frame_frag_next, .frame_frag_send = &r61524_frame_frag_send, .frame_end = &r61524_frame_end, .display_width = 396, .display_height = 224 } }; VHEX_DECLARE_DRIVER(16, drv_r61524);