home *** CD-ROM | disk | FTP | other *** search
-
- ;************************************************************************
- ; solid_box(x0,y0,x1,y1,color) fill a rectangle defined by *
- ; upper-left 'x0,y0', and lower-right 'x1,y1' *
- ; with the specified color 'Color'. *
- ;************************************************************************
- ; large model parms
- px0 EQU [BP+6]
- py0 EQU [BP+8]
- px1 EQU [BP+10]
- py1 EQU [BP+12]
- pColor EQU [BP+14]
-
- ; small model parms
- ;px0 EQU [BP+4]
- ;py0 EQU [BP+6]
- ;px1 EQU [BP+8]
- ;py1 EQU [BP+10]
- ;pColor EQU [BP+12]
-
- byte_rng equ word ptr [bp-2]
- depth equ word ptr [bp-4]
- lBwide equ word ptr [bp-6]
-
- PUBLIC _solid_box
-
- _solid_box proc far
- push bp
- mov bp,sp
- sub sp,8 ;protect local storage
- pushf
- cld
- push di
- push si
- push ds
- push es
-
- ; We want the definition arranged so that [0] is the top-left
- ; corner, and [1] is the bottom right
-
- mov ax,py1
- mov bx,py0
- cmp ax,bx
- jge y_in_order
-
- mov py0,ax ;swap y coordinates
- mov py1,bx
- y_in_order:
- mov ax,px1 ; make px0 < px1
- mov bx,px0
- cmp ax,bx
- jge x_in_order
-
- mov px0,ax ;swap x coordinates
- mov px1,bx
- x_in_order:
-
- ; determine the distance spanned by the rectangle. Possible cases
- ; are 0) both ends in one byte
- ; 1) each end in adjacent bytes
- ; >1) end in different bytes with full bytes in between
-
- mov cl,3 ;divide by 8 - find byte addr
- mov ax,px0
- shr ax,cl ;byte value is left
- mov bx,px1
- shr bx,cl ;byte value is left
- sub bx,ax ;difference
- dec bx ;moves range to -1,0,>0
- ;
- ; Shift it down by one for easier testing
- ; -1) both ends in one byte
- ; 0) each end in adjacent bytes
- ; >0) end in different bytes with full bytes in between
- ;
- mov byte_rng,bx
-
- ; Compute the byte offset in the video memory for the
- ; top left corner
-
- mov cx,px0
- mov bx,py0
- call emapxy
-
- ;
- ; enable set/reset mode
- ; then load reset register
- ;
- mov dx,GRAPHIC12
- mov al,SETRESET ;set SET/RESET register
- out dx,al
- inc dx ;now data register
-
- mov al,pCOLOR ;what color was requested?
- out dx,al ;Set the active (set) bits
- ; that loaded the color into the SETRESET reg.
- dec dx ;now back to control register
-
- mov al,ENABLERESET ;defines which planes will be modified
- ; from the SETRESET register
- out dx,al ;
- inc dx ;and back to data register
-
- mov al,0ffh ;work with all 4 planes
- out dx,al ;0ffh should activate all planes
- dec dx ;back to control
- ;
- mov ax,_bytes_per_line
- mov lBwide,ax ; save befor we destroy DS
-
- mov dx,_curr_vid_seg
- mov es,dx
- mov ds,dx ; so that 'rep stosb' will work
-
- ;------------------- FILL LEADING PARTIAL BYTES ------------------------
- ; in this section first strip of the rectangle is drawn
-
- mov cx,px0 ;determine the bit position of the top left
- and cx,07h ;corner within the video byte
-
- mov ax,px0 ;reset rectangle to be at next byte aligned x val
- add ax,8 ;advance to next byte
- sub ax,cx ;subtract bit count in leading partial byte
- mov px0,ax ;save for next phase
-
- mov bx,0ffh ;build a bit map for new partial
- shr bx,cl ;shift down to start of block
-
- cmp byte_rng,0 ;does it stop in this byte
- jge full_left ;spans beyond this simple byte
-
- ; Full rectangle in this single byte
- ; set the right end of the mask as well
-
- mov cx,px1
- and cx,07h ;last bit position
- sub cx,7
- neg cx ;number of bits empty to the right
- shr bx,cl
- shl bx,cl
-
- full_left:
- GR12_BITMASK bl ; set the mask for the first strip
-
- mov cx,py1 ;compute # of rasters lines to fill
- sub cx,py0
- inc cx ;CX = (y1 - y0) + 1
- mov depth,cx ;save the depth of the box
- mov bx,lBwide ;constant to go to next raster
- push di ;save the starting video byte
- loop1:
- mov ah,[di] ;fetch the video byte
- mov [di],al ;store new color through bit mask, saving old
- add di,bx ;move on to next raster line
- loop loop1 ;loop while CX >=0
-
- pop di ;restore starting video byte addr
- inc di ;move to next byte, one after what we filled
-
-
- ; Here we work with only full bytes that are in the middle of the
- ; the raster line
- ;
- cmp byte_rng,0 ;are there any middle bytes?
- jl end_process ;everything in lead byte - all done
- jz right_mask ;just bits in trailing mask byte
-
- ;middle full bytes
-
- mov cx,byte_rng ;count of middle bytes
-
- GR12_BITMASK 0ffh ; set the mask for full bytes
-
- mov bx,depth
- mov dx,lBwide ;constant to go to next raster
- push di ;save the starting video byte
- loop2:
- push cx ;save # of bytes to fill
- push di ;save starting address
-
- rep stosb ; set CX bytes in this raster
-
- pop di ;get base addr back
- add di,dx ;addr of next raster start
- pop cx ;reset the byte count per line
- dec bx ;one raster in depth
- jg loop2 ;more rasters to fill
-
- pop di ;base addressfor full rectangle
- add di,cx ;add full bytes to start position
-
-
- ;------------------- FILL TRAILING PARTIAL BYTES -----------------------
- right_mask:
-
- mov cx,px1 ;ending pixel
- not cx ;invert bits
- and cx,07h ;keep low 3 bits
-
- mov bx,00ffh ;figure right bit mask
- rol bx,cl ;move mask to top of bl
-
-
- GR12_BITMASK bl
-
- mov cx,depth
- mov bx,lBwide ;constant to go to next raster
- loop3:
- mov al,[di] ;latch data - save beyong end of rect
- mov [di],al ;set color through bitmask
- add di,bx ;move to next raster
- loop loop3 ;while CX >0
-
- ;--- Restore PLANE ENABLE and BIT MASK registers
-
- end_process:
- GR12_BITMASK 0ffh ;open all planes
-
- dec dx ;turn off SET/RESET
- mov al,1
- out dx,al
- inc dx
- xor ax,ax
- out dx,al
-
- ;------------- CLEAN UP AND EXIT ------------------------------------------
-
- pop es
- pop ds
- pop si
- pop di
- popf
- mov sp,bp
- pop bp
- ret
- _solid_box endp
-