diff --git a/nemu/src/device/vga.cc b/nemu/src/device/vga.cc index 66445841d2b6d50cda986da93c74f0740338f649..906196dce1de028da1ac361e1adda43a6e141341 100644 --- a/nemu/src/device/vga.cc +++ b/nemu/src/device/vga.cc @@ -18,16 +18,15 @@ static SDL_Texture *texture; static uint32_t (*vmem) [SCREEN_W]; static uint32_t *screensize_port_base; -void update_screen() { - SDL_UpdateTexture(texture, NULL, vmem, SCREEN_W * sizeof(vmem[0][0])); - SDL_RenderClear(renderer); - SDL_RenderCopy(renderer, texture, NULL, NULL); - SDL_RenderPresent(renderer); +inline void SDL_ErrorCheck(int ret) { + if(ret != 0) { + rlib::println("SDL_Error: ret=", ret, ", GETERR=", SDL_GetError()); + } } -void init_vga() { - SDL_Init(SDL_INIT_VIDEO); - SDL_CreateWindowAndRenderer(SCREEN_W * 2, SCREEN_H * 2, 0, &window, &renderer); +static void init_vga_impl() { + SDL_ErrorCheck(SDL_Init(SDL_INIT_VIDEO)); + SDL_ErrorCheck(SDL_CreateWindowAndRenderer(SCREEN_W * 2, SCREEN_H * 2, 0, &window, &renderer)); SDL_SetWindowTitle(window, "NEMU"); texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, SCREEN_W, SCREEN_H); @@ -36,4 +35,18 @@ void init_vga() { *screensize_port_base = ((SCREEN_W) << 16) | (SCREEN_H); vmem = reinterpret_cast<decltype(vmem)>(add_mmio_map(VMEM, 0x80000, nullptr)); } + +void update_screen() { + if(window == nullptr) init_vga_impl(); + SDL_ErrorCheck(SDL_UpdateTexture(texture, NULL, vmem, SCREEN_W * sizeof(vmem[0][0]))); + SDL_ErrorCheck(SDL_RenderClear(renderer)); + SDL_ErrorCheck(SDL_RenderCopy(renderer, texture, NULL, NULL)); + SDL_RenderPresent(renderer); +} + +void init_vga() { + // Because of fucking SDL design, vga_init should be done in updating thread. + // Do nothing in main thread. +} + #endif /* HAS_IOE */ diff --git a/nexus-am/am/arch/x86-nemu/src/devices/video.c b/nexus-am/am/arch/x86-nemu/src/devices/video.c index 00cb3ab36ee163a673c9df420ddff6f4203e97f6..2baa1f5d5b7c616a550e9e1ac7c18b68f69781b3 100644 --- a/nexus-am/am/arch/x86-nemu/src/devices/video.c +++ b/nexus-am/am/arch/x86-nemu/src/devices/video.c @@ -23,13 +23,9 @@ size_t video_write(uintptr_t reg, void *buf, size_t size) { switch (reg) { case _DEVREG_VIDEO_FBCTL: { _FBCtlReg *ctl = (_FBCtlReg *)buf; -int i; -int size = screen_width() * screen_height(); -for (i = 0; i < size; i ++) fb[i] = i; -// for(int i = 0; i < ctl->h; ++i) -// { -// memcpy(fb+(ctl->y+i)*screen_width()+ctl->x,ctl->pixels+i*ctl->w,ctl->w*4); -// } + for(int i = 0; i < ctl->h; ++i) { + memcpy(fb+(ctl->y+i)*screen_width()+ctl->x,ctl->pixels+i*ctl->w,ctl->w*4); + } if (ctl->sync) { // do nothing, hardware syncs. }