;----------------------------------------------------------- ; ; MXFB.ASM - Fill box function ; Copyright (c) 1993,1994 by Alessandro Scotti ; ;----------------------------------------------------------- WARN PRO NOWARN RES INCLUDE MODEX.DEF PUBLIC mxFillBox MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING EXTRN mx_BytesPerLine : WORD EXTRN mx_VideoSegment : WORD EXTRN subClipBox : NEAR EXTRN subHorizontalLineInfo : NEAR ;----------------------------------------------------------- ; ; Raster op functions. Raster op is limited to OP_MOVE, ; OP_AND, OP_OR and OP_XOR. The VGA hardware is used to ; perform the selected logical functions on up to four ; pixel at a time. ; subRepFill PROC NEAR mov ah, al shr cx, 1 rep stosw rcl cx, 1 rep stosb ret subRepFill ENDP ; subFill PROC NEAR @@Loop: mov ds:[bx], al add bx, dx loop @@Loop ret subFill ENDP ; subRepMove PROC NEAR mov si, di @@Loop: mov ah, ds:[si] ; Dummy read to latch the data mov ds:[si], al inc si loop @@Loop ret subRepMove ENDP ; subMove PROC NEAR @@Loop: mov ah, ds:[bx] ; Dummy read to latch the data mov ds:[bx], al add bx, dx loop @@Loop ret subMove ENDP ;----------------------------------------------------------- ; ; Fills a rectangle with a specified color. ; ; Input: ; X, Y = X, Y coordinates of rectangle ; Width = width of rectangle ; Height = height of rectangle ; Color = fill color ; Op = raster operator ; Output: ; none ; ; Note: raster op is limited to OP_MOVE, OP_AND, OP_OR and OP_XOR. ; mxFillBox PROC FAR ARG Op:WORD, \ Color:BYTE:2, \ Height:WORD, \ Width:WORD, \ Y:WORD, \ X:WORD = ARG_SIZE LOCAL LeftMask:BYTE, \ RightMask:BYTE, \ FillFunction:WORD, \ RepFillFunction:WORD = AUTO_SIZE .enter AUTO_SIZE .push ds, si, es, di ASSUME ds:NOTHING ; Clip rectangle mov bx, [X] mov ax, [Y] mov cx, [Width] mov dx, [Height] call subClipBox jc @@Exit ; Full clipped mov [Height], dx ; Save clipped height call subHorizontalLineInfo ; Get additional info, init DI mov [Width], cx mov [LeftMask], al mov [RightMask], ah ; Initialize segments mov ax, [mx_VideoSegment] mov es, ax ; ES:DI points to pixel mov ds, ax cld ; Clear direction flag ; Select fill functions mov [FillFunction], OFFSET subFill mov [RepFillFunction], OFFSET subRepFill mov ax, [Op] ; Get raster op cmp al, OP_XOR ja @@1 ; Assume it's a fill cmp al, OP_MOVE je @@1 .shl al, 3 mov ah, al mov al, 03h mov dx, GDC out dx, ax ; Set GDC logical function mov [FillFunction], OFFSET subMove mov [RepFillFunction], OFFSET subRepMove @@1: ; Fill left block @@L0: mov ah, [LeftMask] or ah, ah jz @@C0 ; Nothing to do, go to center block mov dx, TS mov al, 02h out dx, ax ; Set write plane mask mov dx, [mx_BytesPerLine] mov cx, [Height] mov bx, di mov al, [Color] call [FillFunction] ; Fill this column inc di ; Update starting video offset ; Fill center block @@C0: mov cx, [Width] jcxz @@R0 ; Nothing to do, go to right block mov dx, TS mov ax, 0F02h out dx, ax ; Write to all planes mov al, [Color] mov bx, di mov dx, [Height] push di ; Save pixel address @@C1: mov di, bx ; Update video offset call [RepFillFunction] ; Fill current scan line mov cx, [Width] ; Restore byte count add bx, [mx_BytesPerLine] ; Bump to next scan line dec dx ; Done all lines? jnz @@C1 ; No, continue pop di ; Restore pixel address add di, [Width] ; Go to right block ; Fill right block @@R0: mov ah, [RightMask] or ah, ah jz @@Done ; Nothing to do, exit mov dx, TS mov al, 02h out dx, ax ; Set write plane mask mov dx, [mx_BytesPerLine] mov cx, [Height] mov bx, di mov al, [Color] call [FillFunction] ; Fill this column ; Restore VGA registers @@Done: mov dx, GDC mov ax, 0003h out dx, ax ; Set logical function to "move" @@Exit: xor ax, ax .pop ds, si, es, di .leave ARG_SIZE mxFillBox ENDP MX_TEXT ENDS END