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.
       }