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
;
; 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
; DS must be set to the base segment; ES is set to DS.
alignb 4
VGARowBuffer resb 640+80 ; Decompression buffer
+VGAPlaneBuffer resb (640/8)*4 ; Plane buffers