diff --git a/VKernel/Kernel/services/desktop.vp b/VKernel/Kernel/services/desktop.vp index f0c0478..50367c3 100644 --- a/VKernel/Kernel/services/desktop.vp +++ b/VKernel/Kernel/services/desktop.vp @@ -1306,9 +1306,15 @@ def _render(): t0: uint64 = timer.timer_get_ticks() row_bytes: int = w * 4 + # 行界夹取:_dirty_y_min/_dirty_y_max 若被写坏成异常值,会退化成死循环并越界写 + # 到帧缓冲之外的 MMIO(实测把宿主 QEMU 写崩)。这里夹到 [0, h-1]。 + _dymin_bg: int = _dirty_y_min + if _dymin_bg < 0: _dymin_bg = 0 + _dymax_bg: int = _dirty_y_max + if _dymax_bg > h - 1: _dymax_bg = h - 1 if _bg_row_buf and _dirty_count > 0: - py_bg: int = _dirty_y_min - while py_bg <= _dirty_y_max: + py_bg: int = _dymin_bg + while py_bg <= _dymax_bg: if _dirty_rows[py_bg]: string.memcpy(rawptr(uint64(back) + py_bg * row_bytes), _bg_row_buf, row_bytes) py_bg += 1 @@ -1351,11 +1357,11 @@ def _render(): _wait_vblank() serial.puts("[rc] vblank done\n") if _dirty_count > 0: - py_fb: int = _dirty_y_min - while py_fb <= _dirty_y_max: + py_fb: int = _dymin_bg + while py_fb <= _dymax_bg: if _dirty_rows[py_fb]: run_start: int = py_fb - while py_fb <= _dirty_y_max and _dirty_rows[py_fb]: + while py_fb <= _dymax_bg and _dirty_rows[py_fb]: py_fb += 1 run_bytes: int = (py_fb - run_start) * row_bytes string.memcpy(rawptr(uint64(_fb) + run_start * pitch), rawptr(uint64(back) + run_start * row_bytes), run_bytes)