📄 vga24_2.asm
字号:
jnc ld8
inc dx
push dx
call vgablock
pop dx
jmp ld8
ld7:
; dec di ; going left
sub di,BytesPerPixel
jnc ld8
dec dx
push dx
call vgablock
pop dx
ld8:
cmp bx,0 ; test d<0
jge ld9
add bx,[bp-14] ; d = d + incr1
jmp ld11
ld9:
add bx,[bp-16] ; d = d + incr2
cmp word ptr [bp-12],0 ; See if going up
je ld10
add di,ScanWidth ; Go to next line
jnc ld11
inc dx
push dx
call vgablock
pop dx
jmp ld11
ld10:
sub di,ScanWidth ; Go to previous line
jnc ld11
dec dx
push dx
call vgablock
pop dx
ld11:
cmp BitsPerPixel,8 ; If 8bit continue else
jne drwrgb2 ; call draw_rgb
mov es:[di],al ; Write next pixel
jmp ldd11
drwrgb2:
push [bp+18]
push [bp+16]
push [bp+14]
call draw_rgb
add sp,6
ldd11:
loop xloop
xloopend:
jmp done
;
; Y oriented version of draw line. Slope must be outside -1 and 1 inclusive
;
yline:
mov cx, [bp-12] ; cx has increment control
mov ax, [bp-10]
sal ax,1 ; DX*2
mov [bp-14],ax ; Save incr1
sub ax,[bp-12] ; 2*dx - dy
mov bx,ax ; bx has D value
mov ax,[bp-10] ; Get DX
sub ax,[bp-12] ; (DX-DY)
sal ax,1 ; 2*(DX-DY)
mov [bp-16],ax ; Save incr2
mov word ptr [bp-10],0 ; Assume going to left
mov ax,[bp+8] ; Get x1
sub ax,[bp+12] ; x1-x2
jg ld12
mov word ptr [bp-10],1 ; Going to right
ld12:
mov word ptr [bp-12],0 ; Assume going up
mov ax,[bp+6] ; Get y1
sub ax,[bp+10] ; y1-y2
jg ld13
mov word ptr [bp-12],1 ; Going down
ld13:
;
; Main Y oriented drawing loop.
; ax = pixel value
; bx = d
; cx = loop control
; dx = block number
; di = block offset
;
cmp BitsPerPixel,8 ; Is it 8bit mode
jne drwrgb3 ; no. call draw_rgb
mov ax,[bp+14]
mov es:[di],al ; Write first pixel
jmp ldd13
drwrgb3:
push [bp+18]
push [bp+16]
push [bp+14]
call draw_rgb
add sp,6
ldd13: cmp cx,0 ; Check if done
je yloopend
yloop:
cmp word ptr [bp-12],0 ; See if going up?
je ld14
add di,ScanWidth ; going down
jnc ld15
inc dx
push dx
call vgablock
pop dx
jmp ld15
ld14:
sub di,ScanWidth ; going up
jnc ld15
dec dx
push dx
call vgablock
pop dx
ld15:
cmp bx,0 ; test d<0
jge ld16
add bx,[bp-14] ; d = d + incr1
jmp ld18
ld16:
add bx,[bp-16] ; d = d + incr2
cmp word ptr [bp-10],0 ; See if going left
je ld17
; inc di ; Go right
add di,BytesPerPixel
jnc ld18
inc dx
push dx
call vgablock
pop dx
jmp ld18
ld17:
; dec di ; Go left
sub di,BytesPerPixel
jnc ld18
dec dx
push dx
call vgablock
pop dx
ld18:
cmp BitsPerPixel,8 ; Is it 8bit mode
jne drwrgb4
mov es:[di],al ; Write next pixel
jmp ld18
drwrgb4:
push [bp+18]
push [bp+16]
push [bp+14]
call draw_rgb
add sp,6
ldd18:
loop yloop
yloopend:
;
; Clear stack and exit
;
done:
add sp,8
Postfix
vgaline endp
;
; Set colors from an array of rgb values.
;
; Parameters:
; - Array of colors
; - Start index
; - Number of colors
;
public vgasetcolor
vgasetcolor proc far
Prefix
les dx,[bp+6] ; Get address of colormap
mov bx,[bp+10] ; Get first color index
mov cx,[bp+12] ; Get Number of indexes
mov ax,1012h ; Set block of color registers function
int 10h
Postfix
vgasetcolor endp
;
; Fill a rectangular region with a given pixel value. Region is assumed to
; start on a even address and be an even width. Width and height values
; must be positive. Width and height values get modified.
;
; Parameters:
; - Row for upper left corner
; - Column for upper left corner
; - Width of rectangle
; - Height of rectangle
; - Pixel value
;
; Locals
; [bp-10] LineSkip
;
public vgafill
vgafill proc far
Prefix
sub sp,2
;
mov ax,vgadata ; Load address of data segment
mov ds,ax ; Set DS register
;
; Load window pointers
;
mov ax,WinAddr
mov es,ax ; Set ES to point to video memory
push [bp+8]
push [bp+6]
call vgaoffset
add sp,4
mov di, ax ; Offset in di
;
; Setup control parameters for line draw.
;
mov bx,ScanWidth ; Get BytesPerScanLine
;
push dx ; save for later
; added 1/2/92, djl, Adjust line offset value
mov ax,[bp+10] ; added to adjust for 15 16 or 24bit modes
mul BytesPerPixel ; columns times BytesPerPixel, djl
sub bx,ax
;
mov [bp-10], bx ; Amount to skip to get to next line
mov ax,[bp+14] ; Get 8bit pixel value
mov ah,al ; ax has duplicated pixel value in al and ah
pop dx
even
linestart:
mov cx,BlockEnd ; Last point in counter
sub cx,di ; cx has number of bytes till block change
;
mov bx,[bp+10] ; bx has number of bytes in line
cmp BitsPerPixel,8 ; If 8bit mode skip counter adjustment, djl
je lee1 ; skip if 8bit, djl
shl bx,1 ; else multiply width of fill by two, djl
lee1:
dec bx ;
cmp bx,cx ;
ja le1
mov cx,bx ; Wont need a block change
le1:
sub bx,cx ; ax has number of words after block change
inc cx
ror cx,1
ror bx,1
;
; Draw the line
;
even
le4:
cmp BitsPerPixel,8
jne drwit
cld
rep stosw
jmp lee4
drwit:
; mov cx,[bp+10]
loopit:
push [bp+18]
push [bp+16]
push [bp+14]
call draw_rgb
add sp,6
add di,BytesPerPixel
loop loopit
lee4:
cmp di,0 ; Check for exact alignment
je le5
cmp bx,0
je le6
;
; Handle block change and continue
;
le5:
inc dx
push dx
call vgablock
pop dx
cmp bx,0
je le6
mov cx,bx
xor bx,bx
xor di,di
jmp le4
;
; Set up for next line
;
le6:
dec word ptr [bp+12]
je le7
add di,[bp-10] ; Go to start of next line
jnc linestart
inc dx ; Bump block pointer
push dx
call vgablock
pop dx
jmp linestart
;
; Finish up
;
le7:
add sp,2
Postfix
vgafill endp
;
; Copy a given rectangle into display memory at the specified address.
; All pixels from the source rectangle are copied with no masking.
; Coordinates are assumed to be correct and wraparound accounted for by
; the calling routine. The start address and rectangle width are assumed
; to be even values to permit faster copy. The passed values may be modified
; and should not be retained by the calling routine.
;
; Parameters:
; - Far pointer to source rectangle
; - Total width of source memory
; - Row for upper left corner
; - Column for upper left corner
; - Width of rectangle
; - Height of rectangle
;
; Locals
; [bp-10] LineSkip
;
public vgarect
vgarect proc far
Prefix
sub sp,2
;
mov ax,vgadata ; Load address of data segment
mov ds,ax ; Set DS register
;
; Load window pointers
;
mov ax,WinAddr
mov es,ax ; Set ES to point to video memory
push [bp+14]
push [bp+12]
call vgaoffset
add sp,4
;
; Setup control parameters for line draw.
;
mov di, ax ; Offset for output memory in di
mov bx,ScanWidth
sub bx,[bp+16]
mov [bp-10], bx ; Amount to skip to get to next line on output
mov bx,[bp+10]
sub bx,[bp+16]
mov [bp+10], bx ; Amount to go to next line on input data
mov si, [bp+6] ; Offset for input memory
even
flinestart:
mov cx,BlockEnd ; Last point in counter
sub cx,di ; cx has number of bytes till block change
mov bx,[bp+16] ; bx has number of bytes in line
dec bx
cmp bx,cx
ja lf1
mov cx,bx ; Won't need a block change
lf1:
sub bx,cx ; bx has number of words after block change
inc cx
ror cx,1
ror bx,1
;
; Draw the line
;
even
lf4:
push ds ; Save segment for vgadata
mov ax, [bp+8]
mov ds,ax ; Set segment for source rectangle
cld
rep movsw
pop ds ; Get segment for vgadata
cmp di,0 ; Check for exact alignment
je lf5
cmp bx,0
je lf6
;
; Handle block change and continue
;
lf5:
inc dx
push dx
call vgablock
pop dx
cmp bx,0
je lf6
mov cx,bx
xor bx,bx
xor di,di
jmp lf4
;
; Set up for next line
;
lf6:
dec word ptr [bp+18]
je lf7
add si,[bp+10] ; Goto next line in input
add di,[bp-10] ; Go to start of next line on output
jnc flinestart
inc dx ; Bump block pointer
push dx
call vgablock
pop dx
jmp flinestart
;
; Finish up
;
lf7:
add sp,2
Postfix
vgarect endp
;
; Copy a given rectangle into display memory at the specified address.
; All pixels from the source rectangle are copied unless they have the
; value 0. Coordinates are assumed to be correct and wraparound accounted
; for by the calling routine. The passed values may be modified
; and should not be retained by the calling routine.
;
; Parameters:
; - Far pointer to source rectangle
; - Total width of source memory
; - Row for upper left corner
; - Column for upper left corner
; - Width of rectangle
; - Height of rectangle
;
; Locals
; [bp-10] LineSkip
;
public vgarect2
vgarect2 proc far
Prefix
sub sp,2
;
mov ax,vgadata ; Load address of data segment
mov ds,ax ; Set DS register
;
; Load window pointers
;
mov ax,WinAddr
mov es,ax ; Set ES to point to video memory
push [bp+14]
push [bp+12]
call vgaoffset
add sp,4
;
; Setup control parameters for line draw.
;
mov di, ax ; Offset for output memory in di
mov bx,ScanWidth
sub bx,[bp+16]
mov [bp-10], bx ; Amount to skip to get to next line on output
mov bx,[bp+10]
sub bx,[bp+16]
mov [bp+10], bx ; Amount to go to next line on input data
mov si, [bp+6] ; Offset for input memory
even
glinestart:
mov cx,BlockEnd ; Last point in counter
sub cx,di ; cx has number of bytes till block change
mov bx,[bp+16] ; bx has number of bytes in line
dec bx
cmp bx,cx
ja lg1
mov cx,bx ; Won't need a block change
lg1:
sub bx,cx ; bx has number of bytes after block change
inc cx
;
; Draw the line
;
even
lg4:
push ds ; Save segment for vgadata
mov ax, [bp+8]
mov ds,ax ; Set segment for source rectangle
cld
lg8: lodsb
or al,al ; Test for 0
jz lg9
stosb
jmp lg10
lg9: inc di
lg10: loop lg8
pop ds ; Get segment for vgadata
cmp di,0 ; Check for exact alignment
je lg5
cmp bx,0
je lg6
;
; Handle block change and continue
;
lg5:
inc dx
push dx
call vgablock
pop dx
cmp bx,0
je lg6
mov cx,bx
xor bx,bx
xor di,di
jmp lg4
;
; Set up for next line
;
lg6:
dec word ptr [bp+18]
je lg7
add si,[bp+10] ; Goto next line in input
add di,[bp-10] ; Go to start of next line on output
jnc glinestart
inc dx ; Bump block pointer
push dx
call vgablock
pop dx
jmp glinestart
;
; Finish up
;
lg7:
add sp,2
Postfix
vgarect2 endp
;
; Handle mouse and keyboard I/O
; If a keyboard key or mouse button is pressed, return a value indicating
; what was pressed. Also, maintain the mouse position values for external
; reference.
;
vgagetbutton proc far
mov ah,0
int 16h
xor ah,ah ; Don't want scan code
ret
vgagetbutton endp
;
; Display a text string at a given location
;
; Parameters:
; - row
; - column
; - character string
; - pixel value for foreground
;
vgatext proc far
ret
vgatext endp
vgacode ends
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -