;----------------------------------------------------------- ; ; MXPI.ASM - Put image ; Copyright (c) 1993,1994 by Alessandro Scotti ; ;----------------------------------------------------------- WARN PRO NOWARN RES INCLUDE MODEX.DEF PUBLIC mxPutImage EXTRN subClipImage : NEAR MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE' ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING EXTRN mx_VideoSegment : WORD EXTRN mx_BytesPerLine : WORD mxTable LABEL WORD ; Raster ops DW subMove DW subAnd DW subOr DW subXor DW subTrans DW subAdd ;----------------------------------------------------------- ; ; Move functions. ; Note: loops unrolled and optimized for CX even, no check for CX = 0. ; subMove PROC NEAR shr cx, 1 ; Make CX even jc @@Odd ; Special case if odd byte @@Loop: movsb add si, 3 movsb add si, 3 dec cx jnz @@Loop @@Exit: ret @@Odd: movsb add si, 3 jcxz @@Exit jmp @@Loop subMove ENDP ; subAnd PROC NEAR shr cx, 1 jc @@Odd @@Loop: mov al, ds:[si] mov ah, ds:[si+4] and es:[di], ax inc di inc di add si, 8 dec cx jnz @@Loop @@Exit: ret @@Odd: lodsb and es:[di], al inc di add si, 3 jcxz @@Exit jmp @@Loop subAnd ENDP ; subOr PROC NEAR shr cx, 1 jc @@Odd @@Loop: mov al, ds:[si] mov ah, ds:[si+4] or es:[di], ax inc di inc di add si, 8 dec cx jnz @@Loop @@Exit: ret @@Odd: lodsb or es:[di], al inc di add si, 3 jcxz @@Exit jmp @@Loop subOr ENDP ; subXor PROC NEAR shr cx, 1 jc @@Odd @@Loop: mov al, ds:[si] mov ah, ds:[si+4] xor es:[di], ax inc di inc di add si, 8 dec cx jnz @@Loop @@Exit: ret @@Odd: lodsb xor es:[di], al inc di add si, 3 jcxz @@Exit jmp @@Loop subXor ENDP ; subTrans PROC NEAR @@Loop: mov al, ds:[si] cmp al, ah je @@Skip mov es:[di], al @@Skip: inc di add si, 4 dec cx jnz @@Loop @@Exit: ret subTrans ENDP ; subAdd PROC NEAR @@Loop: mov al, ds:[si] add es:[di], al inc di add si, 4 dec cx jnz @@Loop ret subAdd ENDP ;----------------------------------------------------------- ; ; Copies a "raw" image from memory to screen. ; ; Input: ; Image = pointer to image ; X, Y = coordinates of destination ; Width = width of image in pixels ; Height = height of image in pixels ; Op = raster op (OP_xxx) ; Output: ; none ; mxPutImage PROC FAR ARG Op:WORD, \ Height:WORD, \ Width:WORD, \ Y:WORD, \ X:WORD, \ Image:DWORD = ARG_SIZE LOCAL PlaneWidth:WORD:4, \ PixelOffset:WORD, \ MoveFunction:WORD, \ Count:BYTE, \ ReadPlane:BYTE, \ OpInfo:BYTE, \ WritePlane:BYTE = AUTO_SIZE ASSUME ds:NOTHING .enter AUTO_SIZE .push ds, si, es, di ; Clip image mov bx, [X] mov ax, [Y] mov cx, [Width] mov dx, [Height] call subClipImage jc @@Exit ; Full clipped mov [Height], dx add WORD PTR Image[0], si ; Skip clipped pixels ; Get pixel address mul [mx_BytesPerLine] mov di, bx shr di, 1 shr di, 1 add di, ax mov [PixelOffset], di mov es, [mx_VideoSegment] ; ES:DI points to pixel and bl, 03h mov [ReadPlane], bl ; Compute extra bytes and width count for each plane mov bx, cx shr bx, 1 shr bx, 1 ; Width for each plane and cl, 03h mov al, 00001000b shr al, cl mov si, 3 SHL 1 @@PatchLoop: mov PlaneWidth[si], bx shr al, 1 adc bx, 0 dec si dec si jge @@PatchLoop ; Setup planes for output to VGA registers mov cl, [ReadPlane] mov al, 00010001b shl al, cl mov [WritePlane], al ; Install move function mov bx, [Op] mov [OpInfo], bh ; Remember additional info if needed xor bh, bh cmp bl, OP_ADD jbe @@SetMoveFunction xor bl, bl @@SetMoveFunction: shl bx, 1 mov ax, mxTable[bx] mov [MoveFunction], ax ; Put image cld mov [Count], 4 ; Four planes lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane mov ds, WORD PTR Image[2] @@PlaneLoop: cmp WORD PTR ss:[bx], 0 ; Exit if nothing more to do je @@Exit ; (also, never try to move zero bytes!) mov si, WORD PTR Image[0] mov ah, [WritePlane] and ah, 0Fh mov al, 02h mov dx, TS out dx, ax ; Select write plane mov ah, [ReadPlane] and ah, 03h mov al, 04h mov dx, GDC out dx, ax ; Select read plane mov dx, [Height] mov di, [PixelOffset] @@Loop: push si push di mov cx, WORD PTR ss:[bx] ; Number of bytes to move mov ah, [OpInfo] ; Transparent color for subTrans call [MoveFunction] pop di pop si add si, [Width] ; Go to next image line add di, [mx_BytesPerLine] ; Go to next screen row dec dx jnz @@Loop ; Repeat for all lines inc bx inc bx ; Select width for next plane inc [ReadPlane] rol [WritePlane], 1 adc [PixelOffset], 0 inc WORD PTR Image[0] dec [Count] jnz @@PlaneLoop ; Repeat for all planes @@Exit: xor ax, ax .pop ds, si, es, di .leave ARG_SIZE mxPutImage ENDP MX_TEXT ENDS END