From 9b4761e35cc95f9b58c4e25c132ad506d2ff473f Mon Sep 17 00:00:00 2001 From: Jeff Parsons Date: Thu, 25 Jun 2015 09:00:25 -0700 Subject: [PATCH] More VGA tests --- tests/pc/vga/L24-1.ASM | 251 +++++++++++++++++++++++++++++++++++++++++ tests/pc/vga/README.md | 4 +- 2 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 tests/pc/vga/L24-1.ASM diff --git a/tests/pc/vga/L24-1.ASM b/tests/pc/vga/L24-1.ASM new file mode 100644 index 000000000..83d37a49b --- /dev/null +++ b/tests/pc/vga/L24-1.ASM @@ -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 diff --git a/tests/pc/vga/README.md b/tests/pc/vga/README.md index ac7f2d04a..1093d0fc1 100644 --- a/tests/pc/vga/README.md +++ b/tests/pc/vga/README.md @@ -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) ---