More VGA tests

This commit is contained in:
Jeff Parsons 2015-07-05 11:38:30 -07:00
commit 69d4893ec6
2 changed files with 191 additions and 5 deletions

View file

@ -3589,10 +3589,10 @@ Video.prototype.getCardColors = function(nBitsPerPixel)
if (nBitsPerPixel == 8) {
/*
* The card must be a VGA, and it's using an (8bpp) mode that bypasses the ATC, so we need
* to pull RGB data exclusively from the 256-entry DAC; each entry contains 6-bit red, green,
* and blue values packed into bits 0-5, 6-11, and 12-17, respectively, each of which we
* effectively shift left 2 bits: a crude 6-to-8-bit color conversion.
* The card must be a VGA, and it's using an (8bpp) mode that bypasses the ATC, so we need to pull
* RGB data exclusively from the 256-entry DAC; each entry contains 6-bit red, green, and blue values
* packed into bits 0-5, 6-11, and 12-17, respectively, each of which we effectively shift left 2 bits:
* a crude 6-to-8-bit color conversion.
*/
for (i = 0; i < 256; i++) {
dw = aDAC[i] || 0;
@ -3605,12 +3605,22 @@ Video.prototype.getCardColors = function(nBitsPerPixel)
} else {
/*
* We need to pull RGB data from the ATC; moreover, if the ATC hasn't been initialized yet,
* we go with a default EGA-compatible 16-color palette.
* we go with a default EGA-compatible 16-color palette. We'll also use the DAC if there is one
* (ie, this is actually a VGA) and it appears to be initialized (ie, the VGA BIOS has been run).
*/
var fDAC = (aDAC && aDAC[255]);
aRegs = (card.regATCData[15] != null? card.regATCData : Video.aEGAPalDef);
for (i = 0; i < 16; i++) {
b = aRegs[i] & Card.ATC.PALETTE.MASK;
/*
* If the DAC is valid, we need to supplement the 6 bits of each ATC palette entry with the values
* for bits 6 and 7 from the ATC COLORSEL register (and overwrite bits 4 and 5 if ATC.MODE.COLORSEL_ALL
* is set as well).
*
* The only reason the DAC wouldn't be valid is if 1) we're trying to display an image before the machine
* and its BIOS have had a chance to initialize the DAC (because we don't preset it to anything, although
* perhaps we should), or 2) this is an EGA, which doesn't have a DAC.
*/
if (fDAC) {
b |= (card.regATCData[Card.ATC.COLORSEL.INDX] & (Card.ATC.COLORSEL.DAC_BIT7 | Card.ATC.COLORSEL.DAC_BIT6)) << 4;
if (card.regATCData[Card.ATC.MODE.INDX] & Card.ATC.MODE.COLORSEL_ALL) {

176
tests/pc/vga/L33-1.ASM Normal file
View file

@ -0,0 +1,176 @@
; Program to demonstrate use of the DAC registers by selecting a
; smoothly contiguous set of 256 colors, then filling the screen
; with concentric diamonds in all 256 colors so that they blend
; into one another to form a continuum of color.
;
.model small
.stack 200h
.data
; Table used to set all 256 DAC entries.
;
; Table format:
; Byte 0: DAC register 0 red value
; Byte 1: DAC register 0 green value
; Byte 2: DAC register 0 blue value
; Byte 3: DAC register 1 red value
; Byte 4: DAC register 1 green value
; Byte 5: DAC register 1 blue value
; :
; Byte 765: DAC register 255 red value
; Byte 766: DAC register 255 green value
; Byte 767: DAC register 255 blue value
ColorTable label byte
; The first 64 entries are increasingly dim pure green.
X=0
REPT 64
db 0,63-X,0
X=X+1
ENDM
; The next 64 entries are increasingly strong pure blue.
X=0
REPT 64
db 0,0,X
X=X+1
ENDM
; The next 64 entries fade through violet to red.
X=0
REPT 64
db X,0,63-X
X=X+1
ENDM
; The last 64 entries are increasingly dim pure red.
X=0
REPT 64
db 63-X,0,0
X=X+1
ENDM
.code
Start:
mov ax,0013h ;AH=0 selects set mode function,
; AL=13h selects 320x200 256-color
int 10h ; mode
;load the DAC registers with the
; color settings
mov ax,@data ;point ES to the default
mov es,ax ; data segment
mov dx,offset ColorTable
;point ES:DX to the start of the
; block of RGB three-byte values
; to load into the DAC registers
mov ax,1012h ;AH=10h selects set color function,
; AL=12h selects set block of DAC
; registers subfunction
sub bx,bx ;load the block of registers
; starting at DAC register #0
mov cx,100h ;set all 256 registers
int 10h ;load the DAC registers
;now fill the screen with
; concentric diamonds in all 256
; color attributes
mov ax,0a000h ;point DS to the display memory
mov ds,ax ; segment
;
;draw diagonal lines in the upper
; left quarter of the screen
mov al,2 ;start with color attribute #2
mov ah,-1 ;cycle down through the colors
mov bx,320 ;draw top to bottom (distance from
; one line to the next)
mov dx,160 ;width of rectangle
mov si,100 ;height of rectangle
sub di,di ;start at (0,0)
mov bp,1 ;draw left to right (distance from
; one column to the next)
call FillBlock ;draw it
;
;draw diagonal lines in the upper
; right quarter of the screen
mov al,2 ;start with color attribute #2
mov ah,-1 ;cycle down through the colors
mov bx,320 ;draw top to bottom (distance from
; one line to the next)
mov dx,160 ;width of rectangle
mov si,100 ;height of rectangle
mov di,319 ;start at (319,0)
mov bp,-1 ;draw right to left (distance from
; one column to the next)
call FillBlock ;draw it
;draw diagonal lines in the lower
; left quarter of the screen
mov al,2 ;start with color attribute #2
mov ah,-1 ;cycle down through the colors
mov bx,-320 ;draw bottom to top (distance from
; one line to the next)
mov dx,160 ;width of rectangle
mov si,100 ;height of rectangle
mov di,199*320 ;start at (0,199)
mov bp,1 ;draw left to right (distance from
; one column to the next)
call FillBlock ;draw it
;
;draw diagonal lines in the lower
; right quarter of the screen
mov al,2 ;start with color attribute #2
mov ah,-1 ;cycle down through the colors
mov bx,-320 ;draw bottom to top (distance from
; one line to the next)
mov dx,160 ;width of rectangle
mov si,100 ;height of rectangle
mov di,199*320+319 ;start at (319,199)
mov bp,-1 ;draw right to left (distance from
; one column to the next)
call FillBlock ;draw it
mov ah,1 ;wait for a key
int 21h ;
mov ax,0003h ;return to text mode
int 10h ;
mov ah,4ch ;done--return to DOS
int 21h
; Fills the specified rectangular area of the screen with diagonal
; lines.
;
; Input:
; AL = initial attribute with which to draw
; AH = amount by which to advance the attribute from
; one pixel to the next
; BX = distance to advance from one pixel to the next
; DX = width of rectangle to fill
; SI = height of rectangle to fill
; DS:DN = screen address of first pixel to draw
; BP = offset from the start of one column to the start of
; the next
FillBlock:
FillHorzLoop:
push di ;preserve pointer to top of column
push ax ;preserve initial attribute
mov cx,si ;column height
FillVertLoop:
mov [di],al ;set the pixel
add di,bx ;point to the next row in the column
add al,ah ;advance the attribute
loop FillVertLoop ;
pop ax ;restore initial attribute
add al,ah ;advance to the next attribute to
; start the next column
pop di ;retrieve pointer to top of column
add di,bp ;point to next column
dec dx ;have we done all columns?
jnz FillHorzLoop ;no, do the next column
ret ;
end Start