graphics: trivial optimization of old-style graphic mode
authorH. Peter Anvin <hpa@zytor.com>
Fri, 31 Jul 2009 00:44:12 +0000 (17:44 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Fri, 31 Jul 2009 00:44:12 +0000 (17:44 -0700)
Trivially optimize the old-style graphics by using another level of
temporary buffering in bitplane format, thereby enabling the use of
rep movsd to write the contents to the screen.  This can speed things
up substantially in virtualization environments.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
core/graphics.inc

index 3ba5146..884776e 100644 (file)
@@ -75,22 +75,26 @@ vgadisplayfile:
                mov di,VGARowBuffer
                ; Pre-clear the row buffer
                push di
+               push di
                mov cx,640/4
                xor eax,eax
                rep stosd
                pop di
-               push di
                mov cx,[GraphXSize]
                call rledecode                  ; Decode one row
                pop si
+               mov di,VGAPlaneBuffer
+               push di
+               mov bp,640
+               call packedpixel2vga
+               pop si
                push es
                mov di,0A000h                   ; VGA segment
                mov es,di
                mov di,[VGAPos]
-               mov bp,640
-               call packedpixel2vga
-               add word [VGAPos],80
+               call outputvga
                pop es
+               add word [VGAPos],640/8
                pop cx
                loop .drawpixelrow
 
@@ -160,38 +164,56 @@ rledecode:
 ;
 ; DS:SI -> packed pixel string
 ; BP    -> pixel count (multiple of 8)
-; ES:DI -> output
+; DS:DI -> output (four planes)
 ;
 packedpixel2vga:
-               mov dx,3C4h     ; VGA Sequencer Register select port
-               mov al,2        ; Sequencer mask
-               out dx,al       ; Select the sequencer mask
-               inc dx          ; VGA Sequencer Register data port
-               mov al,1
-               mov bl,al
+               xor cx,cx
 .planeloop:
-               pusha
-               out dx,al
+               inc cx
+               push si
+               push bp
 .loop1:
-               mov cx,8
+               mov bx,8
 .loop2:
-               xchg cx,bx
                lodsb
                shr al,cl
-               rcl ch,1        ; VGA is bigendian.  Sigh.
-               xchg cx,bx
-               loop .loop2
-               mov al,bh
-               stosb
+               rcl dl,1                ; VGA is bigendian.  Sigh.
+               dec bx
+               jnz .loop2
+               mov [di],dl
+               inc di
                sub bp,byte 8
                ja .loop1
-               popa
-               inc bl
-               shl al,1
-               cmp bl,4
+               pop bp
+               pop si
+               cmp cl,3
                jbe .planeloop
                ret
 
+;
+; outputvga:
+;      Output four subsequent lines of VGA data
+;
+; DS:SI        -> four planes @ 640/8=80 bytes
+; ES:DI        -> pointer into VGA memory
+;
+outputvga:
+               mov dx,3C4h     ; VGA Sequencer Register select port
+               mov al,2        ; Sequencer mask
+               out dx,al       ; Select the sequencer mask
+               inc dx          ; VGA Sequencer Register data port
+               dec ax          ; AL <- 1
+.loop1:
+               out dx,al       ; Select the bit plane to write
+               push di
+               mov cx,640/8
+               rep movsb
+               pop di
+               add ax,ax
+               cmp al,8
+               jbe .loop1
+               ret
+
 ;
 ; vgasetmode:
 ;      Enable VGA graphics, if possible; return ZF=1 on success
@@ -328,3 +350,4 @@ VGAFileMBuf resb FILENAME_MAX       ; Mangled VGA image name
 
                alignb 4
 VGARowBuffer   resb 640+80             ; Decompression buffer
+VGAPlaneBuffer resb (640/8)*4          ; Plane buffers