home *** CD-ROM | disk | FTP | other *** search
- ;----------------------------vga.asm--------------------------------
- ; Modified for CIRRUS bank set and rgb input values 12/30/92
- ;
- ; Title: vga.asm ren vga41.asm ren vga24.asm by Don Lewis
- ; Date: 6/18/92
- ; Author: Randy Buckland (randy@ncsu.edu)
- ;
- ; Description:
- ; This is a VERY basic set of routines to provide high speed SVGA
- ; graphics for IBM-PC compatibiles that have a VGA interface that supports
- ; a VESA driver. These routines assume a 256-color mode and will not work
- ; for any type of mode. The following routines are provided:
- ;
- ; vgainit(int vesa_mode)
- ; vgapoint(int row, int column, int pixel_value)
- ; vgahline(int row, int start_column, int end_column, int pixel_value)
- ; vgaline(int x1, int y1, int x2, int y2, int pixel_value)
- ; vgasetcolor(char *colors, int start, int count)
- ; vgafill(int row, int column, int width, int height, int pixel_value)
- ; vgarect(char *source, int source_width, int row, int column,
- ; int width, int height)
- ;
- ;******** ADDED by Don Lewis, (djlewis@ualr.edu or djlewis@spider.ualr.edu)
- ; This works fine with 8bit VGA. Just pass color in red and rest is ignored.
- ; The original vgafill() was simply modified and vgapoint probably will be to.
- ; These modifications works with 8,15,16 and 24 bit VESA modes.
- ;
- ; vga_point(int,int,uchar r,uchar g,uchar b)
- ; vgapoint_rgb(int row, int column, uchar r, uchar g, uchar b)
- ; vgafill(int,int,int,int,uchar r,uchar g,uchar b)
- ; vgaline(int,int,int,int,uchar r,uchar g,uchar b)
- ;
- .model large,c
- include macros.asm
-
- ;
- ; Global data for the VGA support routines
- ;
- vgadata segment word public 'VGADATA'
-
- Block dw 0 ; Current video memory block accessable
- BlockSz dw 0 ; Size of a video block in K
- BlockShift dw 0 ; Amount to shift bits by
- BlockEnd dw 0 ; Last valid address in block
- BlockMask dw 0 ; Mask used for block/offset operations
-
- WinAddr dw 0 ; Segment addr of window A block
- WinGran dw 0 ; Window Granularity 12/10/92 djl
- ;WinFunc dd 0 ; Far pointer to windowing function
- ScanWidth dw 0 ; Width of a scan line
- BytesPerPixel dw 0 ; BytesPerPixel 12/30/92 djl
- BitsPerPixel dw 0 ; BitsPerPixel value
-
- ShiftMask dw 0 ; pixel shift mask 15 and 16bit modes
- shift dw 0 ; pixel adjustment 15 and 16 bit modes
-
- public screen_width,screen_height
- screen_width dw 640 ; Width of screen
- screen_height dw 480 ; Height of screen
-
- public mouse_x, mouse_y
- mouse_x dw 0
- mouse_y dw 0
-
- public text_height, text_drop
- text_height dw 16
- text_drop dw 4
-
- vgadata ends
-
- vgacode segment word public 'VGACODE'
- assume cs:vgacode,ds:vgadata
-
- ;
- ; Set current video memory block. This procedure assumes that ds already
- ; points to the vgadata segment. This routine will not modify any registers.
- ;
- ; Parameters:
- ; - block number to change to
- ;
- vgablock proc near
- push bp
- mov bp,sp
- push cx ; stay with no register modification. djl
- push dx
-
- mov dx,[bp+4] ; Start of video memory
- cmp dx,Block
- je l1
- ;Window Granularity must be used to adjust bank. djl
- mov cx,WinGran ;BankNum offset adjustment for cards of
- shl dl,cl ;varying window granularity. djl
- mov Block,dx
-
- push ax
- push bx
-
- mov ax,4f05h ; VESA set memory block
- mov bx,0000h ; Set window A
- int 10h
-
- pop bx
- pop ax
- l1:
- pop dx
- pop cx ; stay with no register modification. djl
- mov sp,bp
- pop bp
- ret
- vgablock endp
-
-
-
- ;
- ; Calculate block and offset values for a given row/column. Assumes that ds
- ; points to vgadata. Does NOT preserve registers. Returns block value in
- ; dx and offset in ax.
- ;
- ; Parameters:
- ; - row value
- ; - column value
- ;
- vgaoffset proc near
- push bp
- mov bp,sp
-
- mov ax,[bp+4] ; Get row
- mul ScanWidth ; Get starting block and offset in dx:ax
-
- ; New code for 24bit pixel offset
- push dx
- mov bx,ax ; Save old ax
- xor ax,ax
- mov ax,[bp+6] ; get column
- ; mul word PTR BytesPerPixel
- mul BytesPerPixel
- and ax,7FFFh
- add ax,bx ; Add column offset
- pop dx
-
- ;add ax,[bp+6] ; Add start column offset
- jnc la1
- inc dx ; Just crossed block boundery
- la1:
- mov cx,BlockShift ; Get block size mask
- cmp cx,0 ; Is block size 64K?
- je la2 ; Yes, skip this section
-
- mov bx,ax ; Save old ax
- rol ax,cl
- and ax,BlockMask ; Save high bits
- rol dx,cl
- add dx,ax ; Add high bits to block value.
-
- mov ax,bx
- rol ax,cl
- or ax,BlockMask ; Set undesirable bits
- xor ax,BlockMask ; Clear bad bits
- ror ax,cl
- ;
- ; Set active block to calculated block if needed
- ;
- la2:
- cmp dx,Block
- je la3
- push dx
- call vgablock
- pop dx
- la3:
-
- mov sp,bp
- pop bp
- ret
- vgaoffset endp
-
- ;
- ; Draw a single point in Red, Green, Blue for 15, 16 and 24 bit colour
- ; Added by Don Lewis to work with internal functions
- ; Parameters:
- ; - Row of point
- ; - Column of point
- ; - r,g,b
- ;
- ; 24bit format bit pattern 'bbbbbbbbggggggggrrrrrrrr' 3 bytes
- ; 16bit '00000000bbbbbggggggrrrrr' 2 bytes
- ; 15bit ' 0bbbbbgggggrrrrr' 2 bytes
- ;
- draw_rgb proc near
- Prefix
- push bx
- push cx
- push dx
- ;
- ; Draw point
- ;
- cmp BitsPerPixel,24 ; Is it 24bits per pixel
- jne isit15_16 ; if not goto isit15_16
- mov ax,[bp+8] ; al has blue pixel value
- cld ; clear direction flag to increment
- stosb ; write a byte in al to address in es:di
- mov ax,[bp+6] ; al has green pixel value
- stosb
- mov ax,[bp+4] ; al has red pixel value
- stosb
- jmp fini ; All three bytes written. Finish
- ;
- isit15_16:
- cmp BitsPerPixel,16 ; Is it 16bits per pixel
- mov Shift,3 ; adjust red bits shift factor
- mov ShiftMask,255 ; adjust red/green bits mask
- je drawit ; Go write the color data else its 15bit
- mov Shift,2 ; adjust for 15bits per pixel
- mov ShiftMask,127 ; adjust red/green bit mask
- drawit:
- mov cl,5 ; shift bits up factor
- xor ax,ax ; clear reg
- mov bx,[bp+6] ; get green value
- and bx,00ffh
- shl bx,cl ; shift green up 5bits
- mov ax,[bp+8] ; get blue value
- and ax,00FFh
- add ax,bx ; put portion of green with blue
- cld
- stosb ; write the blue green value
- mov ax,[bp+4] ; get red value
- and ax,00FFh
- mov cx,Shift ; get 15 or 16 bit shift factor
- shl ax,cl ; move red to correct position
- add al,bh ; put remaining green value with red
- and ax,Shiftmask ; mask unwanted bits
- stosb ; write the red green value
- fini:
- pop dx ; Clean house and leave
- pop cx
- pop bx
- Postfix
- draw_rgb endp
-
-
- ;
- ; Initialize the display
- ; Parameters:
- ; Mode value to use
- ;
- public vgainit
- vgainit proc far
- ;
- ; Set up call frame
- ;
- Prefix
- sub sp,256 ; Make local variable space
- ;
- mov ax,vgadata ; Load address of data segment
- mov ds,ax ; Set DS register
-
- ;
- ; Get VGA information and set desired mode
- ;
- mov ax,4f02h ; VESA set mode function
- mov bx,[bp+6] ; Any mode I want !
- int 10h
-
- push ss
- pop es ; Load es with value of ss
- mov di,sp ; Point index at 256 byte temp space
- mov cx,[bp+6]
- mov ax,4f01h ; VESA get Super VGA mode information
- int 10h
-
- mov ax,es:[di+4] ;WinGranularity in k added 12/10/1992 djl
- mov WinGran,ax
- mov ax,es:[di+6] ;WinSize in k
- mov BlockSz,ax
-
- mov ax,es:[di+8]
- mov WinAddr,ax ;WinASegment usually a000h
-
- ; mov ax,es:[di+12] ;was rem ed from here by R.B.
- ; mov word ptr WinFunc,ax ;
-
- ; mov ax,es:[di+14] ;
- ; mov word ptr WinFunc+2,ax ; to here
-
- mov ax,es:[di+16]
- mov ScanWidth,ax ;BytesPerScanLine
-
- mov ax,es:[di+25] ;BitsPerPixel added 12/30/92 djl
- and ax,255 ; djl
- mov BitsPerPixel,ax ; djl
- cmp ax,15 ;is it a 15 bit mode? djl
- jne lb0 ;skip if not 15 bit mode. djl
- inc al ;else force 15 bit modes to 16 bit modes. djl
- lb0: ;
- shr al,3 ;convert BitsPerPixel to BytesPerPixel, djl
- mov BytesPerPixel,ax ;end of addition 12/30/92 djl
- ;
- ; Calculate block shift and end values
- ;
- mov ax,BlockSz ;ax = WinSize
- mov bx,10
- mov cx,03ffh
- lb1:
- sar ax,1 ;divide ax by 2
- inc bx ;bx + 1
- sal cx,1 ;multiply cx by 2
- inc cx ;cx + 1
- cmp ax,1 ;compare ax to 1
- ja lb1 ;jump short if above(CF=0 and ZF=0)
-
- mov ax,16
- sub ax,bx ;ax - bx = ax
- mov BlockShift, ax
- mov BlockEnd, cx
- not cx
- xchg ax,cx
- rol ax,cl
- mov BlockMask,ax
-
- ;
- ; Set to start block
- ;
- xor ax,ax
- push ax
- call vgablock
- pop ax
-
- ;
- ; Remove call frame and exit
- ;
- add sp,256
- Postfix
- vgainit endp
-
- ;
- ; Draw a single point
- ;
- ; Parameters:
- ; - Row of point
- ; - Column of point
- ; - Pixel value to use
- ;
- public vgapoint
- vgapoint proc far
- Prefix
-
- 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] ; Column
- push [bp+6] ; Row
- call vgaoffset
- add sp,4
-
- ;
- ; Draw point in 8bit modes
- ;
- mov di,ax ; Put offset in index regester
- mov ax,[bp+10] ; bl has pixel value
- cld
- stosb
- ;
- Postfix
- vgapoint endp
-
- ;
- ; Draw a single point Red, Green, Blue. BY Don Lewis
- ; to be called from external C routine
- ;
- ; Parameters:
- ; - Row of point
- ; - Column of point
- ; - r,g,b
- ;
- public vgapoint_rgb
- vgapoint_rgb proc far
- Prefix
-
- mov ax,vgadata ; Load address of data segment
- mov ds,ax ; Set DS register
- ;
- ; Load window pointers
- ;
- mov ax,WinAddr ; Get video memory start
- mov es,ax ; Set ES to point to video memory
-
- push [bp+8] ; Column
- push [bp+6] ; Row
- call vgaoffset
- add sp,4
-
- ;
- ; Draw point
- ;
- mov di,ax ; Put offset in index regester
- push [bp+14]
- push [bp+12]
- push [bp+10]
- call draw_rgb
- add sp,6
-
- ; mov di,ax ; Put offset in index regester
- ; cmp BitsPerPixel,24 ; Is it 24bits per pixel
- ; jne dr1516 ; if not goto dr1516
- ; mov ax,[bp+14] ; bl has blue pixel value
- ; cld
- ; stosb
- ; mov ax,[bp+12] ; bl has green pixel value
- ; stosb
- ; mov ax,[bp+10] ; bl has red pixel value
- ; stosb
- ; jmp finish
- ;dr1516:
- ; cmp BitsPerPixel,16 ; Is it 16bits per pixel
- ; mov Shift,3 ; adjust red bits shift factor
- ; mov ShiftMask,255 ; adjust red bits mask
- ; je draw
- ; mov Shift,2 ; adjust for 15bits per pixel
- ; mov ShiftMask,127
- ;draw:
- ; mov cl,5 ; shift up factor
- ; xor ax,ax ; clear reg
- ; mov bx,[bp+12] ; get green value
- ; shl bx,cl ; shift green up 5bits
- ; mov ax,[bp+14] ; get blue value
- ; add ax,bx ; put portion of green with blue
- ; cld
- ; stosb ; write the blue green value
- ; mov ax,[bp+10] ; get red value
- ; mov cx,Shift ; get 15 or 16 bit shift factor
- ; shl ax,cl ; move red to correct position
- ; add al,bh ; put remaining green value with red
- ; and ax,Shiftmask ; mask unwanted bits
- ; stosb ; write the red green value
- finish:
- Postfix
- vgapoint_rgb endp
-
-
-
- ;
- ; Draw a horizontal line. Line is assumed to start on even boundry and
- ; have length be an even value for speed.
- ;
- ; Parameters:
- ; - Row for line
- ; - Start column
- ; - End column
- ; - Pixel value
- ;
- public vgahline
- vgahline proc far
- Prefix
- ;
- 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] ; Beginning Column
- push [bp+6] ; Row
- call vgaoffset
- add sp,4
-
- ;
- ; Setup control parameters for line draw.
- ;
- mov di, ax ; Offset in di
- mov ax,[bp+12] ; Pixel color
- mov ah,al ; ax has duplicated pixel value in bl and bh
-
- mov cx,BlockEnd ; Last point in counter
- sub cx,di ; cx has number of legal bytes-1
-
- mov bx,[bp+10] ; Ending column
- sub bx,[bp+8] ; bx has number to write - 1
-
- cmp bx,cx
- ja lc1
- mov cx,bx ; Won't need a block change
- lc1:
- sub bx,cx ; ax has number of words after block change
- inc cx
- ror cx,1
- ror bx,1
-
- ;
- ; Draw the line
- ;
- even
- lc4:
- cld
- rep stosw
-
- cmp bx,0
- je lc5
-
- ;
- ; Handle block change and continue
- ;
- inc dx
- push dx
- call vgablock
- pop dx
-
- mov cx,bx
- xor bx,bx
- xor di,di
- jmp lc4
-
- ;
- ; Finish up
- ;
- lc5:
- Postfix
- vgahline endp
-
-
-
- ;
- ; Draw a line using bresenham's algorithm.
- ;
- ; Parameters:
- ; - x1
- ; - y1
- ; - x2
- ; - y2
- ; - Pixel value
- ;
- ; Locals:
- ; [bp-10] DX
- ; [bp-12] DY
- ; [bp-14] incr1
- ; [bp-16] incr2
- ;
- public vgaline
- vgaline proc far
- Prefix
- sub sp,8
- ;
- 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
-
- ;
- ; Initialize for line draw
- ;
- mov ax,[bp+8] ; Get x1
- sub ax,[bp+12] ; Sub x2
- jg ld1 ; Skip if positive
- neg ax
- ld1: mov [bp-10],ax ; Save DX
-
- mov ax,[bp+6] ; Get y1
- sub ax,[bp+10] ; sub y2
- jg ld2 ; Skip if positive
- neg ax
- ld2: mov [bp-12],ax ; Save DY
-
- cmp ax,[bp-10] ; See if DY>DX
- jle xline ; Go do X oriented version
- jmp yline ; Go do Y oriented version
-
- ;
- ; X oriented version of draw line. Slope must be between -1 and 1 inclusive
- ;
- xline:
- mov cx, [bp-10] ; cx has increment control
-
- sal ax,1 ; DY*2
- mov [bp-14],ax ; Save incr1
- sub ax,[bp-10] ; 2*dy - dx
- mov bx,ax ; bx has D value
-
- mov ax,[bp-12] ; Get DY
- sub ax,[bp-10] ; (DY-DX)
- sal ax,1 ; 2*(DY-DX)
- 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 ld3
- mov word ptr [bp-10],1 ; Going to right
- ld3:
- mov word ptr [bp-12],0 ; Assume going up
- mov ax,[bp+6] ; Get y1
- sub ax,[bp+10] ; y1-y2
- jg ld5
- mov word ptr [bp-12],1 ; Going down
- ld5:
-
- ;
- ; Main X oriented drawing loop.
- ; ax = pixel value
- ; bx = d
- ; cx = loop control
- ; dx = block number
- ; di = block offset
- ;
- cmp BitsPerPixel,8 ; If 8bit mode continue else goto
- jne drwrgb1 ; draw_rgb routine
- mov ax,[bp+14]
- mov es:[di],al ; Write first pixel
- jmp ldd5
- drwrgb1:
- push [bp+18]
- push [bp+16]
- push [bp+14]
- call draw_rgb
- add sp,6
- ldd5:
- cmp cx,0 ; Check if done
- je xloopend
-
- xloop:
- cmp word ptr [bp-10],0 ; See if going left?
- je ld7
- ; inc di ; going right
- add di,BytesPerPixel
- 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
-