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