More VGA tests
This commit is contained in:
parent
e14a202918
commit
9b4761e35c
2 changed files with 254 additions and 1 deletions
251
tests/pc/vga/L24-1.ASM
Normal file
251
tests/pc/vga/L24-1.ASM
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
; Program to illustrate operation of ALUs and latches of the VGA's
|
||||
; Graphics Controller. Draws a variety of patterns against
|
||||
; a horizontally striped background, using each of the 4 available
|
||||
; logical functions (data unmodified, AND, OR, XOR) in turn to combine
|
||||
; the images with the background.
|
||||
; By Michael Abrash.
|
||||
;
|
||||
stack segment para stack ‘STACK'
|
||||
db 512 dup(?)
|
||||
stack ends
|
||||
;
|
||||
VGA_VIDEO_SEGMENT equ 0a000h ;VGA display memory segment
|
||||
SCREEN_HEIGHT equ 350
|
||||
SCREEN_WIDTH_IN_BYTES equ 80
|
||||
DEMO_AREA_HEIGHT equ 336 ;# of scan lines in area
|
||||
; logical function operation
|
||||
; is demonstrated in
|
||||
DEMO_AREA_WIDTH_IN_BYTES equ 40 ;width in bytes of area
|
||||
; logical function operation
|
||||
; is demonstrated in
|
||||
VERTICAL_BOX_WIDTH_IN_BYTES equ 10 ;width in bytes of the box used to
|
||||
; demonstrate each logical function
|
||||
;
|
||||
; VGA register equates.
|
||||
;
|
||||
GC_INDEX equ 3ceh ;GC index register
|
||||
GC_ROTATE equ 3 ;GC data rotate/logical function
|
||||
; register index
|
||||
GC_MODE equ 5 ;GC mode register index
|
||||
;
|
||||
dseg segment para common ‘DATA'
|
||||
;
|
||||
; String used to label logical functions.
|
||||
;
|
||||
LabelString label byte
|
||||
db ‘UNMODIFIED AND OR XOR '
|
||||
LABEL_STRING_LENGTH equ $-LabelString
|
||||
;
|
||||
; Strings used to label fill patterns.
|
||||
;
|
||||
FillPatternFF db ‘Fill Pattern: 0FFh'
|
||||
FILL_PATTERN_FF_LENGTH equ $ - FillPatternFF
|
||||
FillPattern00 db ‘Fill Pattern: 000h'
|
||||
FILL_PATTERN_00_LENGTH equ $ - FillPattern00
|
||||
FillPatternVert db ‘Fill Pattern: Vertical Bar'
|
||||
FILL_PATTERN_VERT_LENGTH equ $ - FillPatternVert
|
||||
FillPatternHorz db ‘Fill Pattern: Horizontal Bar'
|
||||
FILL_PATTERN_HORZ_LENGTH equ $ - FillPatternHorz
|
||||
;
|
||||
dseg ends
|
||||
;
|
||||
; Macro to set indexed register INDEX of GC chip to SETTING.
|
||||
;
|
||||
SETGC macro INDEX, SETTING
|
||||
mov dx,GC_INDEX
|
||||
mov ax,(SETTING SHL 8) OR INDEX
|
||||
out dx,ax
|
||||
endm
|
||||
;
|
||||
;
|
||||
; Macro to call BIOS write string function to display text string
|
||||
; TEXT_STRING, of length TEXT_LENGTH, at location ROW,COLUMN.
|
||||
;
|
||||
TEXT_UP macro TEXT_STRING, TEXT_LENGTH, ROW, COLUMN
|
||||
mov ah,13h ;BIOS write string function
|
||||
mov bp,offset TEXT_STRING ;ES:BP points to string
|
||||
mov cx,TEXT_LENGTH
|
||||
mov dx,(ROW SHL 8) OR COLUMN ;position
|
||||
sub al,al ;string is chars only, cursor not moved
|
||||
mov bl,7 ;text attribute is white (light gray)
|
||||
int 10h
|
||||
endm
|
||||
;
|
||||
cseg segment para public ‘CODE'
|
||||
assume cs:cseg, ds:dseg
|
||||
start proc near
|
||||
mov ax,dseg
|
||||
mov ds,ax
|
||||
;
|
||||
; Select 640x350 graphics mode.
|
||||
;
|
||||
mov ax,010h
|
||||
int 10h
|
||||
;
|
||||
; ES points to VGA memory.
|
||||
;
|
||||
mov ax,VGA_VIDEO_SEGMENT
|
||||
mov es,ax
|
||||
;
|
||||
; Draw background of horizontal bars.
|
||||
;
|
||||
mov dx,SCREEN_HEIGHT/4
|
||||
;# of bars to draw (each 4 pixels high)
|
||||
sub di,di ;start at offset 0 in display memory
|
||||
mov ax,0ffffh ;fill pattern for light areas of bars
|
||||
mov bx,DEMO_AREA_WIDTH_IN_BYTES / 2 ;length of each bar
|
||||
mov si,SCREEN_WIDTH_IN_BYTES - DEMO_AREA_WIDTH_IN_BYTES
|
||||
mov bp,(SCREEN_WIDTH_IN_BYTES * 3) - DEMO_AREA_WIDTH_IN_BYTES
|
||||
BackgroundLoop:
|
||||
mov cx,bx ;length of bar
|
||||
rep stosw ;draw top half of bar
|
||||
add di,si ;point to start of bottom half of bar
|
||||
mov cx,bx ;length of bar
|
||||
rep stosw ;draw bottom half of bar
|
||||
add di,bp ;point to start of top of next bar
|
||||
dec dx
|
||||
jnz BackgroundLoop
|
||||
;
|
||||
; Draw vertical boxes filled with a variety of fill patterns
|
||||
; using each of the 4 logical functions in turn.
|
||||
;
|
||||
SETGC GC_ROTATE, 0 ;select data unmodified
|
||||
; logical function...
|
||||
mov di,0
|
||||
call DrawVerticalBox ;...and draw box
|
||||
;
|
||||
SETGC GC_ROTATE, 08h ;select AND logical function...
|
||||
mov di,10
|
||||
call DrawVerticalBox ;...and draw box
|
||||
;
|
||||
SETGC GC_ROTATE, 10h ;select OR logical function...
|
||||
mov di,20
|
||||
call DrawVerticalBox ;...and draw box
|
||||
;
|
||||
SETGC GC_ROTATE, 18h ;select XOR logical function...
|
||||
mov di,30
|
||||
call DrawVerticalBox ;...and draw box
|
||||
;
|
||||
; Reset the logical function to data unmodified, the default state.
|
||||
;
|
||||
SETGC GC_ROTATE, 0
|
||||
;
|
||||
; Label the screen.
|
||||
;
|
||||
push ds
|
||||
pop es ;strings we'll display are passed to BIOS
|
||||
; by pointing ES:BP to them
|
||||
;
|
||||
; Label the logical functions, using the VGA BIOS's
|
||||
; write string function.
|
||||
;
|
||||
TEXT_UP LabelString, LABEL_STRING_LENGTH, 24, 0
|
||||
;
|
||||
; Label the fill patterns, using the VGA BIOS's
|
||||
; write string function.
|
||||
;
|
||||
TEXT_UP FillPatternFF, FILL_PATTERN_FF_LENGTH, 3, 42
|
||||
TEXT_UP FillPattern00, FILL_PATTERN_00_LENGTH, 9, 42
|
||||
TEXT_UP FillPatternVert, FILL_PATTERN_VERT_LENGTH, 15, 42
|
||||
TEXT_UP FillPatternHorz, FILL_PATTERN_HORZ_LENGTH, 21, 42
|
||||
;
|
||||
; Wait until a key's been hit to reset screen mode & exit.
|
||||
;
|
||||
WaitForKey:
|
||||
mov ah,1
|
||||
int 16h
|
||||
jz WaitForKey
|
||||
;
|
||||
; Finished. Clear key, reset screen mode and exit.
|
||||
;
|
||||
Done:
|
||||
mov ah,0 ;clear key that we just detected
|
||||
int 16h
|
||||
;
|
||||
mov ax,3 ;reset to text mode
|
||||
int 10h
|
||||
;
|
||||
mov ah,4ch ;exit to DOS
|
||||
int 21h
|
||||
;
|
||||
start endp
|
||||
;
|
||||
; Subroutine to draw a box 80x336 in size, using currently selected
|
||||
; logical function, with upper left corner at the display memory offset
|
||||
; in DI. Box is filled with four patterns. Top quarter of area is
|
||||
; filled with 0FFh (solid) pattern, next quarter is filled with 00h
|
||||
; (empty) pattern, next quarter is filled with 33h (double pixel wide
|
||||
; vertical bar) pattern, and bottom quarter is filled with double pixel
|
||||
; high horizontal bar pattern.
|
||||
;
|
||||
; Macro to draw a column of the specified width in bytes, one-quarter
|
||||
; of the height of the box, with the specified fill pattern.
|
||||
;
|
||||
DRAW_BOX_QUARTER macro FILL, WIDTH
|
||||
local RowLoop, ColumnLoop
|
||||
mov al,FILL ;fill pattern
|
||||
mov dx,DEMO_AREA_HEIGHT / 4 ;1/4 of the full box height
|
||||
RowLoop:
|
||||
mov cx,WIDTH
|
||||
ColumnLoop:
|
||||
mov ah,es:[di] ;load display memory contents into
|
||||
; GC latches (we don't actually care
|
||||
; about value read into AH)
|
||||
stosb ;write pattern, which is logically
|
||||
; combined with latch contents for each
|
||||
; plane and then written to display
|
||||
; memory
|
||||
loop ColumnLoop
|
||||
add di,SCREEN_WIDTH_IN_BYTES - WIDTH
|
||||
;point to start of next line down in box
|
||||
dec dx
|
||||
jnz RowLoop
|
||||
endm
|
||||
;
|
||||
DrawVerticalBox proc near
|
||||
DRAW_BOX_QUARTER 0ffh, VERTICAL_BOX_WIDTH_IN_BYTES
|
||||
;first fill pattern: solid fill
|
||||
DRAW_BOX_QUARTER 0, VERTICAL_BOX_WIDTH_IN_BYTES
|
||||
;second fill pattern: empty fill
|
||||
DRAW_BOX_QUARTER 033h, VERTICAL_BOX_WIDTH_IN_BYTES
|
||||
;third fill pattern: double-pixel
|
||||
; wide vertical bars
|
||||
mov dx,DEMO_AREA_HEIGHT / 4 / 4
|
||||
;fourth fill pattern: horizontal bars in
|
||||
; sets of 4 scan lines
|
||||
sub ax,ax
|
||||
mov si,VERTICAL_BOX_WIDTH_IN_BYTES ;width of fill area
|
||||
HorzBarLoop:
|
||||
dec ax ;0ffh fill (smaller to do word than byte DEC)
|
||||
mov cx,si ;width to fill
|
||||
HBLoop1:
|
||||
mov bl,es:[di] ;load latches (don't care about value)
|
||||
stosb ;write solid pattern, through ALUs
|
||||
loop HBLoop1
|
||||
add di,SCREEN_WIDTH_IN_BYTES - VERTICAL_BOX_WIDTH_IN_BYTES
|
||||
mov cx,si ;width to fill
|
||||
HBLoop2:
|
||||
mov bl,es:[di] ;load latches
|
||||
stosb ;write solid pattern, through ALUs
|
||||
loop HBLoop2
|
||||
add di,SCREEN_WIDTH_IN_BYTES - VERTICAL_BOX_WIDTH_IN_BYTES
|
||||
inc ax ;0 fill (smaller to do word than byte DEC)
|
||||
mov cx,si ;width to fill
|
||||
HBLoop3:
|
||||
mov bl,es:[di] ;load latches
|
||||
stosb ;write empty pattern, through ALUs
|
||||
loop HBLoop3
|
||||
add di,SCREEN_WIDTH_IN_BYTES - VERTICAL_BOX_WIDTH_IN_BYTES
|
||||
mov cx,si ;width to fill
|
||||
HBLoop4:
|
||||
mov bl,es:[di] ;load latches
|
||||
stosb ;write empty pattern, through ALUs
|
||||
loop HBLoop4
|
||||
add di,SCREEN_WIDTH_IN_BYTES - VERTICAL_BOX_WIDTH_IN_BYTES
|
||||
dec dx
|
||||
jnz HorzBarLoop
|
||||
;
|
||||
ret
|
||||
DrawVerticalBox endp
|
||||
cseg ends
|
||||
end start
|
||||
|
|
@ -26,7 +26,9 @@ Development of PCjs VGA support has just begun (June 2015), so don't expect *any
|
|||
List of VGA Samples from [Michael Abrash's Graphics Programming Black Book](https://github.com/jeffpar/abrash-black-book):
|
||||
|
||||
* [Chapter 23](https://github.com/jeffpar/abrash-black-book/blob/master/src/chapter-23.md)
|
||||
* [L23-1.ASM](https://github.com/jeffpar/abrash-black-book/blob/master/code/L23-1.ASM)
|
||||
* [L23-1.ASM](L23-1.ASM)
|
||||
* [Chapter 24](https://github.com/jeffpar/abrash-black-book/blob/master/src/chapter-24.md)
|
||||
* [L24-1.ASM](L24-1.ASM)
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue