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