More VGA tests
This commit is contained in:
parent
7fa7f53cd0
commit
fed558c8d4
3 changed files with 737 additions and 0 deletions
218
tests/pc/vga/L27-1.ASM
Normal file
218
tests/pc/vga/L27-1.ASM
Normal file
|
|
@ -0,0 +1,218 @@
|
||||||
|
; Program to illustrate one use of write mode 2 of the VGA and EGA by
|
||||||
|
; animating the image of an "A" drawn by copying it from a chunky
|
||||||
|
; bit-map in system memory to a planar bit-map in VGA or EGA memory.
|
||||||
|
;
|
||||||
|
; Assemble with MASM or TASM
|
||||||
|
;
|
||||||
|
; By Michael Abrash
|
||||||
|
;
|
||||||
|
Stack segment para stack 'STACK'
|
||||||
|
db 512 dup(0)
|
||||||
|
Stack ends
|
||||||
|
|
||||||
|
SCREEN_WIDTH_IN_BYTES equ 80
|
||||||
|
DISPLAY_MEMORY_SEGMENT equ 0a000h
|
||||||
|
|
||||||
|
SC_INDEX equ 3c4h ;Sequence Controller Index register
|
||||||
|
MAP_MASK equ 2 ;index of Map Mask register
|
||||||
|
GC_INDEX equ 03ceh ;Graphics Controller Index reg
|
||||||
|
GRAPHICS_MODE equ 5 ;index of Graphics Mode reg
|
||||||
|
BIT_MASK equ 8 ;index of Bit Mask reg
|
||||||
|
|
||||||
|
Data segment para common 'DATA'
|
||||||
|
;
|
||||||
|
; Current location of "A" as it is animated across the screen.
|
||||||
|
;
|
||||||
|
CurrentX dw ?
|
||||||
|
CurrentY dw ?
|
||||||
|
RemainingLength dw ?
|
||||||
|
;
|
||||||
|
; Chunky bit-map image of a yellow "A" on a bright blue background
|
||||||
|
;
|
||||||
|
AImage label byte
|
||||||
|
dw 13, 13 ;width, height in pixels
|
||||||
|
db 000h, 000h, 000h, 000h, 000h, 000h, 000h
|
||||||
|
db 009h, 099h, 099h, 099h, 099h, 099h, 000h
|
||||||
|
db 009h, 099h, 099h, 099h, 099h, 099h, 000h
|
||||||
|
db 009h, 099h, 099h, 0e9h, 099h, 099h, 000h
|
||||||
|
db 009h, 099h, 09eh, 0eeh, 099h, 099h, 000h
|
||||||
|
db 009h, 099h, 0eeh, 09eh, 0e9h, 099h, 000h
|
||||||
|
db 009h, 09eh, 0e9h, 099h, 0eeh, 099h, 000h
|
||||||
|
db 009h, 09eh, 0eeh, 0eeh, 0eeh, 099h, 000h
|
||||||
|
db 009h, 09eh, 0e9h, 099h, 0eeh, 099h, 000h
|
||||||
|
db 009h, 09eh, 0e9h, 099h, 0eeh, 099h, 000h
|
||||||
|
db 009h, 099h, 099h, 099h, 099h, 099h, 000h
|
||||||
|
db 009h, 099h, 099h, 099h, 099h, 099h, 000h
|
||||||
|
db 000h, 000h, 000h, 000h, 000h, 000h, 000h
|
||||||
|
Data ends
|
||||||
|
|
||||||
|
Code segment para public 'CODE'
|
||||||
|
assume cs:Code, ds:Data
|
||||||
|
Start proc near
|
||||||
|
mov ax,Data
|
||||||
|
mov ds,ax
|
||||||
|
mov ax,10h
|
||||||
|
int 10h ;select video mode 10h (640x350)
|
||||||
|
;
|
||||||
|
; Prepare for animation.
|
||||||
|
;
|
||||||
|
mov [CurrentX],0
|
||||||
|
mov [CurrentY],200
|
||||||
|
mov [RemainingLength],600 ;move 600 times
|
||||||
|
;
|
||||||
|
; Animate, repeating RemainingLength times. It's unnecessary to erase
|
||||||
|
; the old image, since the one pixel of blank fringe around the image
|
||||||
|
; erases the part of the old image not overlapped by the new image.
|
||||||
|
;
|
||||||
|
AnimationLoop:
|
||||||
|
mov bx,[CurrentX]
|
||||||
|
mov cx,[CurrentY]
|
||||||
|
mov si,offset AImage
|
||||||
|
call DrawFromChunkyBitmap ;draw the "A" image
|
||||||
|
inc [CurrentX] ;move one pixel to the right
|
||||||
|
|
||||||
|
mov cx,0 ;delay so we don't move the
|
||||||
|
DelayLoop: ; image too fast; adjust as
|
||||||
|
; needed
|
||||||
|
loop DelayLoop
|
||||||
|
|
||||||
|
dec [RemainingLength]
|
||||||
|
jnz AnimationLoop
|
||||||
|
;
|
||||||
|
; Wait for a key before returning to text mode and ending.
|
||||||
|
;
|
||||||
|
mov ah,01h
|
||||||
|
int 21h
|
||||||
|
mov ax,03h
|
||||||
|
int 10h
|
||||||
|
mov ah,4ch
|
||||||
|
int 21h
|
||||||
|
Start endp
|
||||||
|
;
|
||||||
|
; Draw an image stored in a chunky-bit map into planar VGA/EGA memory
|
||||||
|
; at the specified location.
|
||||||
|
;
|
||||||
|
; Input:
|
||||||
|
; BX = X screen location at which to draw the upper-left corner
|
||||||
|
; of the image
|
||||||
|
; CX = Y screen location at which to draw the upper-left corner
|
||||||
|
; of the image
|
||||||
|
; DS:SI = pointer to chunky image to draw, as follows:
|
||||||
|
; word at 0: width of image, in pixels
|
||||||
|
; word at 2: height of image, in pixels
|
||||||
|
; byte at 4: msb/lsb = first & second chunky pixels,
|
||||||
|
; repeating for the remainder of the scan line
|
||||||
|
; of the image, then for all scan lines. Images
|
||||||
|
; with odd widths have an unused null nibble
|
||||||
|
; padding each scan line out to a byte width
|
||||||
|
;
|
||||||
|
; AX, BX, CX, DX, SI, DI, ES destroyed.
|
||||||
|
;
|
||||||
|
DrawFromChunkyBitmap proc near
|
||||||
|
cld
|
||||||
|
;
|
||||||
|
; Select write mode 2.
|
||||||
|
;
|
||||||
|
mov dx,GC_INDEX
|
||||||
|
mov al,GRAPHICS_MODE
|
||||||
|
out dx,al
|
||||||
|
inc dx
|
||||||
|
mov al,02h
|
||||||
|
out dx,al
|
||||||
|
;
|
||||||
|
; Enable writes to all 4 planes.
|
||||||
|
;
|
||||||
|
mov dx,SC_INDEX
|
||||||
|
mov al,MAP_MASK
|
||||||
|
out dx,al
|
||||||
|
inc dx
|
||||||
|
mov al,0fh
|
||||||
|
out dx,al
|
||||||
|
;
|
||||||
|
; Point ES:DI to the display memory byte in which the first pixel
|
||||||
|
; of the image goes, with AH set up as the bit mask to access that
|
||||||
|
; pixel within the addressed byte.
|
||||||
|
;
|
||||||
|
mov ax,SCREEN_WIDTH_IN_BYTES
|
||||||
|
mul cx ;offset of start of top scan line
|
||||||
|
mov di,ax
|
||||||
|
mov cl,bl
|
||||||
|
and cl,111b
|
||||||
|
mov ah,80h ;set AH to the bit mask for the
|
||||||
|
shr ah,cl ; initial pixel
|
||||||
|
shr bx,1
|
||||||
|
shr bx,1
|
||||||
|
shr bx,1 ;X in bytes
|
||||||
|
add di,bx ;offset of upper-left byte of image
|
||||||
|
mov bx,DISPLAY_MEMORY_SEGMENT
|
||||||
|
mov es,bx ;ES:DI points to the byte at which the
|
||||||
|
; upper left of the image goes
|
||||||
|
;
|
||||||
|
; Get the width and height of the image.
|
||||||
|
;
|
||||||
|
mov cx,[si] ;get the width
|
||||||
|
inc si
|
||||||
|
inc si
|
||||||
|
mov bx,[si] ;get the height
|
||||||
|
inc si
|
||||||
|
inc si
|
||||||
|
mov dx,GC_INDEX
|
||||||
|
mov al,BIT_MASK
|
||||||
|
out dx,al ;leave the GC Index register pointing
|
||||||
|
inc dx ; to the Bit Mask register
|
||||||
|
RowLoop:
|
||||||
|
|
||||||
|
push ax ;preserve the left column's bit mask
|
||||||
|
push cx ;preserve the width
|
||||||
|
push di ;preserve the destination offset
|
||||||
|
|
||||||
|
ColumnLoop:
|
||||||
|
mov al,ah
|
||||||
|
out dx,al ;set the bit mask to draw this pixel
|
||||||
|
mov al,es:[di] ;load the latches
|
||||||
|
mov al,[si] ;get the next two chunky pixels
|
||||||
|
shr al,1
|
||||||
|
shr al,1
|
||||||
|
shr al,1
|
||||||
|
shr al,1 ;move the first pixel into the lsb
|
||||||
|
stosb ;draw the first pixel
|
||||||
|
ror ah,1 ;move mask to next pixel position
|
||||||
|
jc CheckMorePixels ;is next pixel in the adjacent byte?
|
||||||
|
dec di ;no
|
||||||
|
|
||||||
|
CheckMorePixels:
|
||||||
|
dec cx ;see if there are any more pixels
|
||||||
|
jz AdvanceToNextScanLine ; across in image
|
||||||
|
mov al,ah
|
||||||
|
out dx,al ;set the bit mask to draw this pixel
|
||||||
|
mov al,es:[di] ;load the latches
|
||||||
|
lodsb ;get the same two chunky pixels again
|
||||||
|
; and advance pointer to the next
|
||||||
|
; two pixels
|
||||||
|
stosb ;draw the second of the two pixels
|
||||||
|
ror ah,1 ;move mask to next pixel position
|
||||||
|
jc CheckMorePixels2;is next pixel in the adjacent byte?
|
||||||
|
dec di ;no
|
||||||
|
|
||||||
|
CheckMorePixels2:
|
||||||
|
loop ColumnLoop ;see if there are any more pixels
|
||||||
|
; across in the image
|
||||||
|
jmp short CheckMoreScanLines
|
||||||
|
|
||||||
|
AdvanceToNextScanLine:
|
||||||
|
inc si ;advance to the start of the next
|
||||||
|
; scan line in the image
|
||||||
|
|
||||||
|
CheckMoreScanLines:
|
||||||
|
pop di ;get back the destination offset
|
||||||
|
pop cx ;get back the width
|
||||||
|
pop ax ;get back the left column's bit mask
|
||||||
|
add di,SCREEN_WIDTH_IN_BYTES
|
||||||
|
;point to the start of the next scan
|
||||||
|
; line of the image
|
||||||
|
dec bx ;see if there are any more scan lines
|
||||||
|
jnz RowLoop ; in the image
|
||||||
|
ret
|
||||||
|
DrawFromChunkyBitmap endp
|
||||||
|
Code ends
|
||||||
|
end Start
|
||||||
327
tests/pc/vga/L27-2.ASM
Normal file
327
tests/pc/vga/L27-2.ASM
Normal file
|
|
@ -0,0 +1,327 @@
|
||||||
|
; Program to illustrate one use of write mode 2 of the VGA and EGA by
|
||||||
|
; drawing lines in color patterns.
|
||||||
|
;
|
||||||
|
; Assemble with MASM or TASM
|
||||||
|
;
|
||||||
|
; By Michael Abrash
|
||||||
|
;
|
||||||
|
Stack segment para stack 'STACK'
|
||||||
|
db 512 dup(0)
|
||||||
|
Stack ends
|
||||||
|
|
||||||
|
SCREEN_WIDTH_IN_BYTES equ 80
|
||||||
|
GRAPHICS_SEGMENT equ 0a000h ;mode 10 bit-map segment
|
||||||
|
|
||||||
|
SC_INDEX equ 3c4h ;Sequence Controller Index register
|
||||||
|
MAP_MASK equ 2 ;index of Map Mask register
|
||||||
|
GC_INDEX equ 03ceh ;Graphics Controller Index reg
|
||||||
|
GRAPHICS_MODE equ 5 ;index of Graphics Mode reg
|
||||||
|
BIT_MASK equ 8 ;index of Bit Mask reg
|
||||||
|
|
||||||
|
Data segment para common 'DATA'
|
||||||
|
Pattern0 db 16
|
||||||
|
db 0, 1, 2, 3, 4, 5, 6, 7, 8
|
||||||
|
db 9, 10, 11, 12, 13, 14, 15
|
||||||
|
Pattern1 db 6
|
||||||
|
db 2, 2, 2, 10, 10, 10
|
||||||
|
Pattern2 db 8
|
||||||
|
db 15, 15, 15, 0, 0, 15, 0, 0
|
||||||
|
Pattern3 db 9
|
||||||
|
db 1, 1, 1, 2, 2, 2, 4, 4, 4
|
||||||
|
Data ends
|
||||||
|
|
||||||
|
Code segment para public 'CODE'
|
||||||
|
assume cs:Code, ds:Data
|
||||||
|
Start proc near
|
||||||
|
mov ax,Data
|
||||||
|
mov ds,ax
|
||||||
|
mov ax,10h
|
||||||
|
int 10h ;select video mode 10h (640x350)
|
||||||
|
;
|
||||||
|
; Draw 8 radial lines in upper-left quadrant in pattern 0.
|
||||||
|
;
|
||||||
|
mov bx,0
|
||||||
|
mov cx,0
|
||||||
|
mov si,offset Pattern0
|
||||||
|
call QuadrantUp
|
||||||
|
;
|
||||||
|
; Draw 8 radial lines in upper-right quadrant in pattern 1.
|
||||||
|
;
|
||||||
|
mov bx,320
|
||||||
|
mov cx,0
|
||||||
|
mov si,offset Pattern1
|
||||||
|
call QuadrantUp
|
||||||
|
;
|
||||||
|
; Draw 8 radial lines in lower-left quadrant in pattern 2.
|
||||||
|
;
|
||||||
|
mov bx,0
|
||||||
|
mov cx,175
|
||||||
|
mov si,offset Pattern2
|
||||||
|
call QuadrantUp
|
||||||
|
;
|
||||||
|
; Draw 8 radial lines in lower-right quadrant in pattern 3.
|
||||||
|
;
|
||||||
|
mov bx,320
|
||||||
|
mov cx,175
|
||||||
|
mov si,offset Pattern3
|
||||||
|
call QuadrantUp
|
||||||
|
;
|
||||||
|
; Wait for a key before returning to text mode and ending.
|
||||||
|
;
|
||||||
|
mov ah,01h
|
||||||
|
int 21h
|
||||||
|
mov ax,03h
|
||||||
|
int 10h
|
||||||
|
mov ah,4ch
|
||||||
|
int 21h
|
||||||
|
;
|
||||||
|
; Draws 8 radial lines with specified pattern in specified mode 10h
|
||||||
|
; quadrant.
|
||||||
|
;
|
||||||
|
; Input:
|
||||||
|
; BX = X coordinate of upper left corner of quadrant
|
||||||
|
; CX = Y coordinate of upper left corner of quadrant
|
||||||
|
; SI = pointer to pattern, in following form:
|
||||||
|
; Byte 0: Length of pattern
|
||||||
|
; Byte 1: Start of pattern, one color per byte
|
||||||
|
;
|
||||||
|
; AX, BX, CX, DX destroyed
|
||||||
|
;
|
||||||
|
QuadrantUp proc near
|
||||||
|
add bx,160
|
||||||
|
add cx,87 ;point to the center of the quadrant
|
||||||
|
mov ax,0
|
||||||
|
mov dx,160
|
||||||
|
call LineUp ;draw horizontal line to right edge
|
||||||
|
mov ax,1
|
||||||
|
mov dx,88
|
||||||
|
call LineUp ;draw diagonal line to upper right
|
||||||
|
mov ax,2
|
||||||
|
mov dx,88
|
||||||
|
call LineUp ;draw vertical line to top edge
|
||||||
|
mov ax,3
|
||||||
|
mov dx,88
|
||||||
|
call LineUp ;draw diagonal line to upper left
|
||||||
|
mov ax,4
|
||||||
|
mov dx,161
|
||||||
|
call LineUp ;draw horizontal line to left edge
|
||||||
|
mov ax,5
|
||||||
|
mov dx,88
|
||||||
|
call LineUp ;draw diagonal line to lower left
|
||||||
|
mov ax,6
|
||||||
|
mov dx,88
|
||||||
|
call LineUp ;draw vertical line to bottom edge
|
||||||
|
mov ax,7
|
||||||
|
mov dx,88
|
||||||
|
call LineUp ;draw diagonal line to bottom right
|
||||||
|
ret
|
||||||
|
QuadrantUp endp
|
||||||
|
;
|
||||||
|
; Draws a horizontal, vertical, or diagonal line (one of the eight
|
||||||
|
; possible radial lines) of the specified length from the specified
|
||||||
|
; starting point.
|
||||||
|
;
|
||||||
|
; Input:
|
||||||
|
; AX = line direction, as follows:
|
||||||
|
; 3 2 1
|
||||||
|
; 4 * 0
|
||||||
|
; 5 6 7
|
||||||
|
; BX = X coordinate of starting point
|
||||||
|
; CX = Y coordinate of starting point
|
||||||
|
; DX = length of line (number of pixels drawn)
|
||||||
|
;
|
||||||
|
; All registers preserved.
|
||||||
|
;
|
||||||
|
; Table of vectors to routines for each of the 8 possible lines.
|
||||||
|
;
|
||||||
|
LineUpVectors label word
|
||||||
|
dw LineUp0, LineUp1, LineUp2, LineUp3
|
||||||
|
dw LineUp4, LineUp5, LineUp6, LineUp7
|
||||||
|
|
||||||
|
;
|
||||||
|
; Macro to draw horizontal, vertical, or diagonal line.
|
||||||
|
;
|
||||||
|
; Input:
|
||||||
|
; XParm = 1 to draw right, -1 to draw left, 0 to not move horz.
|
||||||
|
; YParm = 1 to draw up, -1 to draw down, 0 to not move vert.
|
||||||
|
; BX = X start location
|
||||||
|
; CX = Y start location
|
||||||
|
; DX = number of pixels to draw
|
||||||
|
; DS:SI = line pattern
|
||||||
|
;
|
||||||
|
MLineUp macro XParm, YParm
|
||||||
|
local LineUpLoop, CheckMoreLine
|
||||||
|
mov di,si ;set aside start offset of pattern
|
||||||
|
lodsb ;get length of pattern
|
||||||
|
mov ah,al
|
||||||
|
|
||||||
|
LineUpLoop:
|
||||||
|
lodsb ;get color of this pixel...
|
||||||
|
call DotUpInColor ;...and draw it
|
||||||
|
if XParm EQ 1
|
||||||
|
inc bx
|
||||||
|
endif
|
||||||
|
if XParm EQ -1
|
||||||
|
dec bx
|
||||||
|
endif
|
||||||
|
if YParm EQ 1
|
||||||
|
inc cx
|
||||||
|
endif
|
||||||
|
if YParm EQ -1
|
||||||
|
dec cx
|
||||||
|
endif
|
||||||
|
dec ah ;at end of pattern?
|
||||||
|
jnz CheckMoreLine
|
||||||
|
mov si,di ;get back start of pattern
|
||||||
|
lodsb
|
||||||
|
mov ah,al ;reset pattern count
|
||||||
|
|
||||||
|
CheckMoreLine:
|
||||||
|
dec dx
|
||||||
|
jnz LineUpLoop
|
||||||
|
jmp LineUpEnd
|
||||||
|
endm
|
||||||
|
|
||||||
|
LineUp proc near
|
||||||
|
push ax
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push si
|
||||||
|
push di
|
||||||
|
push es
|
||||||
|
|
||||||
|
mov di,ax
|
||||||
|
|
||||||
|
mov ax,GRAPHICS_SEGMENT
|
||||||
|
mov es,ax
|
||||||
|
|
||||||
|
push dx ;save line length
|
||||||
|
;
|
||||||
|
; Enable writes to all planes.
|
||||||
|
;
|
||||||
|
mov dx,SC_INDEX
|
||||||
|
mov al,MAP_MASK
|
||||||
|
out dx,al
|
||||||
|
inc dx
|
||||||
|
mov al,0fh
|
||||||
|
out dx,al
|
||||||
|
;
|
||||||
|
; Select write mode 2.
|
||||||
|
;
|
||||||
|
mov dx,GC_INDEX
|
||||||
|
mov al,GRAPHICS_MODE
|
||||||
|
out dx,al
|
||||||
|
inc dx
|
||||||
|
mov al,02h
|
||||||
|
out dx,al
|
||||||
|
;
|
||||||
|
; Vector to proper routine.
|
||||||
|
;
|
||||||
|
pop dx ;get back line length
|
||||||
|
|
||||||
|
shl di,1
|
||||||
|
jmp cs:[LineUpVectors+di]
|
||||||
|
;
|
||||||
|
; Horizontal line to right.
|
||||||
|
;
|
||||||
|
LineUp0:
|
||||||
|
MLineUp 1, 0
|
||||||
|
;
|
||||||
|
; Diagonal line to upper right.
|
||||||
|
;
|
||||||
|
LineUp1:
|
||||||
|
MLineUp 1, -1
|
||||||
|
;
|
||||||
|
; Vertical line to top.
|
||||||
|
;
|
||||||
|
LineUp2:
|
||||||
|
MLineUp 0, -1
|
||||||
|
;
|
||||||
|
; Diagonal line to upper left.
|
||||||
|
;
|
||||||
|
LineUp3:
|
||||||
|
MLineUp -1, -1
|
||||||
|
;
|
||||||
|
; Horizontal line to left.
|
||||||
|
;
|
||||||
|
LineUp4:
|
||||||
|
MLineUp -1, 0
|
||||||
|
;
|
||||||
|
; Diagonal line to bottom left.
|
||||||
|
;
|
||||||
|
LineUp5:
|
||||||
|
MLineUp -1, 1
|
||||||
|
;
|
||||||
|
; Vertical line to bottom.
|
||||||
|
;
|
||||||
|
LineUp6:
|
||||||
|
MLineUp 0, 1
|
||||||
|
;
|
||||||
|
; Diagonal line to bottom right.
|
||||||
|
;
|
||||||
|
LineUp7:
|
||||||
|
MLineUp 1, 1
|
||||||
|
|
||||||
|
LineUpEnd:
|
||||||
|
pop es
|
||||||
|
pop di
|
||||||
|
pop si
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
pop ax
|
||||||
|
ret
|
||||||
|
LineUp endp
|
||||||
|
;
|
||||||
|
; Draws a dot in the specified color at the specified location.
|
||||||
|
; Assumes that the VGA is in write mode 2 with writes to all planes
|
||||||
|
; enabled and that ES points to display memory.
|
||||||
|
;
|
||||||
|
; Input:
|
||||||
|
; AL = dot color
|
||||||
|
; BX = X coordinate of dot
|
||||||
|
; CX = Y coordinate of dot
|
||||||
|
; ES = display memory segment
|
||||||
|
;
|
||||||
|
; All registers preserved.
|
||||||
|
;
|
||||||
|
DotUpInColor proc near
|
||||||
|
push bx
|
||||||
|
push cx
|
||||||
|
push dx
|
||||||
|
push di
|
||||||
|
;
|
||||||
|
; Point ES:DI to the display memory byte in which the pixel goes, with
|
||||||
|
; the bit mask set up to access that pixel within the addressed byte.
|
||||||
|
;
|
||||||
|
push ax ;preserve dot color
|
||||||
|
mov ax,SCREEN_WIDTH_IN_BYTES
|
||||||
|
mul cx ;offset of start of top scan line
|
||||||
|
mov di,ax
|
||||||
|
mov cl,bl
|
||||||
|
and cl,111b
|
||||||
|
mov dx,GC_INDEX
|
||||||
|
mov al,BIT_MASK
|
||||||
|
out dx,al
|
||||||
|
inc dx
|
||||||
|
mov al,80h
|
||||||
|
shr al,cl
|
||||||
|
out dx,al ;set the bit mask for the pixel
|
||||||
|
shr bx,1
|
||||||
|
shr bx,1
|
||||||
|
shr bx,1 ;X in bytes
|
||||||
|
add di,bx ;offset of byte pixel is in
|
||||||
|
mov al,es:[di] ;load latches
|
||||||
|
pop ax ;get back dot color
|
||||||
|
stosb ;write dot in desired color
|
||||||
|
|
||||||
|
pop di
|
||||||
|
pop dx
|
||||||
|
pop cx
|
||||||
|
pop bx
|
||||||
|
ret
|
||||||
|
DotUpInColor endp
|
||||||
|
Start endp
|
||||||
|
Code ends
|
||||||
|
end Start
|
||||||
192
tests/pc/vga/L27-3.ASM
Normal file
192
tests/pc/vga/L27-3.ASM
Normal file
|
|
@ -0,0 +1,192 @@
|
||||||
|
; Program to illustrate flipping from bit-mapped graphics mode to
|
||||||
|
; text mode and back without losing any of the graphics bit-map.
|
||||||
|
;
|
||||||
|
; Assemble with MASM or TASM
|
||||||
|
;
|
||||||
|
; By Michael Abrash
|
||||||
|
;
|
||||||
|
Stack segment para stack 'STACK'
|
||||||
|
db 512 dup(0)
|
||||||
|
Stack ends
|
||||||
|
|
||||||
|
GRAPHICS_SEGMENT equ 0a000h ;mode 10 bit-map segment
|
||||||
|
TEXT_SEGMENT equ 0b800h ;mode 3 bit-map segment
|
||||||
|
|
||||||
|
SC_INDEX equ 3c4h ;Sequence Controller Index register
|
||||||
|
MAP_MASK equ 2 ;index of Map Mask register
|
||||||
|
GC_INDEX equ 3ceh ;Graphics Controller Index register
|
||||||
|
READ_MAP equ 4 ;index of Read Map register
|
||||||
|
|
||||||
|
Data segment para common 'DATA'
|
||||||
|
|
||||||
|
GStrikeAnyKeyMsg0 label byte
|
||||||
|
db 0dh, 0ah, 'Graphics mode', 0dh, 0ah
|
||||||
|
db 'Strike any key to continue...', 0dh, 0ah, '$'
|
||||||
|
|
||||||
|
GStrikeAnyKeyMsg1 label byte
|
||||||
|
db 0dh, 0ah, 'Graphics mode again', 0dh, 0ah
|
||||||
|
db 'Strike any key to continue...', 0dh, 0ah, '$'
|
||||||
|
|
||||||
|
TStrikeAnyKeyMsg label byte
|
||||||
|
db 0dh, 0ah, 'Text mode', 0dh, 0ah
|
||||||
|
db 'Strike any key to continue...', 0dh, 0ah, '$'
|
||||||
|
|
||||||
|
Plane2Save db 2000h dup (?) ;save area for plane 2 data
|
||||||
|
; where font gets loaded
|
||||||
|
CharAttSave db 4000 dup (?) ;save area for memory wiped
|
||||||
|
; out by character/attribute
|
||||||
|
; data in text mode
|
||||||
|
Data ends
|
||||||
|
|
||||||
|
Code segment para public 'CODE'
|
||||||
|
assume cs:Code, ds:Data
|
||||||
|
Start proc near
|
||||||
|
mov ax,10h
|
||||||
|
int 10h ;select video mode 10h (640x350)
|
||||||
|
;
|
||||||
|
; Fill the graphics bit-map with a colored pattern.
|
||||||
|
;
|
||||||
|
cld
|
||||||
|
mov ax,GRAPHICS_SEGMENT
|
||||||
|
mov es,ax
|
||||||
|
mov ah,3 ;initial fill pattern
|
||||||
|
mov cx,4 ;four planes to fill
|
||||||
|
mov dx,SC_INDEX
|
||||||
|
mov al,MAP_MASK
|
||||||
|
out dx,al ;leave the SC Index pointing to the
|
||||||
|
inc dx ; Map Mask register
|
||||||
|
|
||||||
|
FillBitMap:
|
||||||
|
mov al,10h
|
||||||
|
shr al,cl ;generate map mask for this plane
|
||||||
|
out dx,al ;set map mask for this plane
|
||||||
|
sub di,di ;start at offset 0
|
||||||
|
mov al,ah ;get the fill pattern
|
||||||
|
push cx ;preserve plane count
|
||||||
|
mov cx,8000h ;fill 32K words
|
||||||
|
rep stosw ;do fill for this plane
|
||||||
|
pop cx ;get back plane count
|
||||||
|
shl ah,1
|
||||||
|
shl ah,1
|
||||||
|
loop FillBitMap
|
||||||
|
;
|
||||||
|
; Put up "strike any key" message.
|
||||||
|
;
|
||||||
|
mov ax,Data
|
||||||
|
mov ds,ax
|
||||||
|
mov dx,offset GStrikeAnyKeyMsg0
|
||||||
|
mov ah,9
|
||||||
|
int 21h
|
||||||
|
;
|
||||||
|
; Wait for a key.
|
||||||
|
;
|
||||||
|
mov ah,01h
|
||||||
|
int 21h
|
||||||
|
;
|
||||||
|
; Save the 8K of plane 2 that will be used by the font.
|
||||||
|
;
|
||||||
|
mov dx,GC_INDEX
|
||||||
|
mov al,READ_MAP
|
||||||
|
out dx,al
|
||||||
|
inc dx
|
||||||
|
mov al,2
|
||||||
|
out dx,al ;set up to read from plane 2
|
||||||
|
mov ax,Data
|
||||||
|
mov es,ax
|
||||||
|
mov ax,GRAPHICS_SEGMENT
|
||||||
|
mov ds,ax
|
||||||
|
sub si,si
|
||||||
|
mov di,offset Plane2Save
|
||||||
|
mov cx,2000h/2 ;save 8K (length of default font)
|
||||||
|
rep movsw
|
||||||
|
;
|
||||||
|
; Go to text mode without clearing display memory.
|
||||||
|
;
|
||||||
|
mov ax,083h
|
||||||
|
int 10h
|
||||||
|
;
|
||||||
|
; Save the text mode bit-map.
|
||||||
|
;
|
||||||
|
mov ax,Data
|
||||||
|
mov es,ax
|
||||||
|
mov ax,TEXT_SEGMENT
|
||||||
|
mov ds,ax
|
||||||
|
sub si,si
|
||||||
|
mov di,offset CharAttSave
|
||||||
|
mov cx,4000/2 ;length of one text screen in words
|
||||||
|
rep movsw
|
||||||
|
;
|
||||||
|
; Fill the text mode screen with dots and put up "strike any key"
|
||||||
|
; message.
|
||||||
|
;
|
||||||
|
mov ax,TEXT_SEGMENT
|
||||||
|
mov es,ax
|
||||||
|
sub di,di
|
||||||
|
mov al,'.' ;fill character
|
||||||
|
mov ah,7 ;fill attribute
|
||||||
|
mov cx,4000/2 ;length of one text screen in words
|
||||||
|
rep stosw
|
||||||
|
mov ax,Data
|
||||||
|
mov ds,ax
|
||||||
|
mov dx,offset TStrikeAnyKeyMsg
|
||||||
|
mov ah,9
|
||||||
|
int 21h
|
||||||
|
;
|
||||||
|
; Wait for a key.
|
||||||
|
;
|
||||||
|
mov ah,01h
|
||||||
|
int 21h
|
||||||
|
;
|
||||||
|
; Restore the text mode screen to the state it was in on entering
|
||||||
|
; text mode.
|
||||||
|
;
|
||||||
|
mov ax,Data
|
||||||
|
mov ds,ax
|
||||||
|
mov ax,TEXT_SEGMENT
|
||||||
|
mov es,ax
|
||||||
|
mov si,offset CharAttSave
|
||||||
|
sub di,di
|
||||||
|
mov cx,4000/2 ;length of one text screen in words
|
||||||
|
rep movsw
|
||||||
|
;
|
||||||
|
; Return to mode 10h without clearing display memory.
|
||||||
|
;
|
||||||
|
mov ax,90h
|
||||||
|
int 10h
|
||||||
|
;
|
||||||
|
; Restore the portion of plane 2 that was wiped out by the font.
|
||||||
|
;
|
||||||
|
mov dx,SC_INDEX
|
||||||
|
mov al,MAP_MASK
|
||||||
|
out dx,al
|
||||||
|
inc dx
|
||||||
|
mov al,4
|
||||||
|
out dx,al ;set up to write to plane 2
|
||||||
|
mov ax,Data
|
||||||
|
mov ds,ax
|
||||||
|
mov ax,GRAPHICS_SEGMENT
|
||||||
|
mov es,ax
|
||||||
|
mov si,offset Plane2Save
|
||||||
|
sub di,di
|
||||||
|
mov cx,2000h/2 ;restore 8K (length of default font)
|
||||||
|
rep movsw
|
||||||
|
;
|
||||||
|
; Put up "strike any key" message.
|
||||||
|
;
|
||||||
|
mov ax,Data
|
||||||
|
mov ds,ax
|
||||||
|
mov dx,offset GStrikeAnyKeyMsg1
|
||||||
|
mov ah,9
|
||||||
|
int 21h
|
||||||
|
;
|
||||||
|
; Wait for a key before returning to text mode and ending.
|
||||||
|
;
|
||||||
|
mov ah,01h
|
||||||
|
int 21h
|
||||||
|
mov ax,03h
|
||||||
|
int 10h
|
||||||
|
mov ah,4ch
|
||||||
|
int 21h
|
||||||
|
Start endp
|
||||||
|
Code ends
|
||||||
|
end Start
|
||||||
Loading…
Reference in a new issue