home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 21 / CD_ASCQ_21_040595.iso / dos / prg / c / xlib612 / source / xpbmclip.asm < prev    next >
Assembly Source File  |  1994-12-02  |  35KB  |  1,084 lines

  1. ;-----------------------------------------------------------------------
  2. ; MODULE XPBMCLIP
  3. ;
  4. ; Clipped Planar Bitmap functions - System Ram <-> Video Ram
  5. ;
  6. ; Compile with Tasm.
  7. ; C callable.
  8. ;
  9. ;
  10. ; ****** XLIB - Mode X graphics library                ****************
  11. ; ******                                               ****************
  12. ; ****** Written By Themie Gouthas                     ****************
  13. ;
  14. ; egg@dstos3.dsto.gov.au
  15. ; teg@bart.dsto.gov.au
  16. ;-----------------------------------------------------------------------
  17. ;
  18. ; Patch by Lee Perkins (leep@infi.net) on 12/2/94
  19. ;-----------------------------------------------------------------------
  20.  
  21. COMMENT $
  22.  
  23.   This module implements a set of functions to operate on planar bitmaps.
  24.   Planar bitmaps as used by these functions have the following structure:
  25.  
  26.   BYTE 0                 The bitmap width in bytes (4 pixel groups) range 1..255
  27.   BYTE 1                 The bitmap height in rows range 1..255
  28.   BYTE 2..n1             The plane 0 pixels width*height bytes
  29.   BYTE n1..n2            The plane 1 pixels width*height bytes
  30.   BYTE n2..n3            The plane 2 pixels width*height bytes
  31.   BYTE n3..n4            The plane 3 pixels width*height bytes
  32.  
  33.   These functions provide the fastest possible bitmap blts from system ram to
  34.   to video and further, the single bitmap is applicable to all pixel
  35.   allignments. The masked functions do not need separate masks since all non
  36.   zero pixels are considered to be masking pixels, hence if a pixel is 0 the
  37.   corresponding screen destination pixel is left unchanged.
  38.  
  39.  
  40. $
  41. LOCALS
  42. include xlib.inc
  43. include xpbmclip.inc
  44.  
  45.     .code
  46.  
  47. ;----------------------------------------------------------------------
  48. ; x_put_masked_pbm_clipx - mask write a planar bitmap from system ram to video
  49. ;            ram all zero source bitmap bytes indicate destination
  50. ;            byte to be left unchanged.
  51. ;                       Performs clipping in x directions. similar to
  52. ;                "x_put_masked_pbm".
  53. ;
  54. ; See Also:  x_put_masked_pbm, x_put_masked_pbm_clipxy
  55. ;
  56. ; Clipping region variables: LeftClip,RightClip
  57. ;
  58. ; Written by Themie Gouthas
  59. ;
  60. ; This code is a SLOW hack, any better ideas are welcome
  61. ;----------------------------------------------------------------------
  62. _x_put_masked_pbm_clipx  proc
  63. ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
  64. LOCAL   Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc:word=LocalStk
  65.     push  bp
  66.         mov   bp,sp
  67.     sub   sp,LocalStk                 ; Create space for local variables
  68.         push  si
  69.         push  di
  70.         push  ds
  71.     cld
  72.  
  73.     les   si,[Bitmap]                 ; Point ES:SI to start of bitmap
  74.  
  75.     xor   ax,ax                       ; Clear AX
  76.     mov   [CType],ax                  ; Clear Clip type descision var
  77.     mov   al,byte ptr es:[si]         ; AX=width (byte coverted to word)
  78.  
  79.  
  80.     mov   di,[X]                      ; DI = X coordinate of dest
  81.     mov   cx,di                       ; copy to CX
  82.     sar   di,2                        ; convert to offset in row
  83.  
  84.  
  85.     ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  86.  
  87.     mov   dx,[_LeftClip]              ; Is X Coord to the right of
  88.     sub   dx,di                       ; LeftClip ?
  89.     jle   @@NotLeftClip               ; Yes! => no left clipping
  90.     cmp   dx,ax                       ; Is dist of X Coord from
  91.     jnl   @@NotVisible                ; ClipLeft > Width ? yes => the
  92.                       ; bitmap is not visible
  93.     add   di,dx
  94.     mov   [LeftSkip],dx
  95.     mov   [DataInc],dx
  96.     sub   ax,dx
  97.     mov   [CType],1
  98.     jmp   short @@HorizClipDone
  99.  
  100.     ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;
  101.  
  102. @@NotVisible:
  103.     mov   ax,1
  104.     pop   ds                          ; restore data segment
  105.     pop   di                          ; restore registers
  106.     pop   si
  107.     mov   sp,bp                       ; dealloc local variables
  108.     pop   bp
  109.     ret
  110.  
  111.     ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  112.  
  113. @@NotLeftClip:
  114.     mov   dx,[_RightClip]
  115.     sub   dx,di
  116.     js    @@NotVisible
  117.     mov   [LeftSkip],0
  118.     mov   [DataInc],0
  119.     cmp   dx,ax
  120.     jge   @@HorizClipDone       ; was jg
  121.     inc   dx
  122.     sub   ax,dx
  123.     mov   [DataInc],ax
  124.     mov   ax,dx
  125.     mov   [CType],-1
  126.  
  127. @@HorizClipDone:
  128.  
  129.     xor   bh,bh
  130.     mov   bl,byte ptr es:[si+1]       ; BX = height
  131.  
  132.     mov   [Width],ax                  ; Save width and height of clipped
  133.     mov   [Height],bx                 ;  image
  134.  
  135.  
  136.     add   si,2                        ; Skip dimension bytes in source
  137.     add   si,[LeftSkip]               ; Skip pixels in front of row that
  138.                       ;  are clipped
  139.  
  140.  
  141.     mov   bx,[_ScrnLogicalByteWidth]  ; Set BX to Logical Screen Width
  142.     mov   dx,bx                       ; BX - Width of image = No. bytes
  143.     sub   dx,ax                       ;  to first byte of next screen
  144.     mov   [LineInc],dx                ;  row.
  145.  
  146.     mov   ax,[Y]                      ; Calculate screen start row
  147.     mul   bx                          ;  then adding screen offset
  148.     add   di,ax
  149.     add   di,[ScrnOffs]
  150.  
  151.     mov   dx,_SCREEN_SEG              ; Grab _SCREEN_SEG before changing ds
  152.     mov   ax,es                       ; copy ES to DS
  153.     mov   ds,ax
  154.     mov   es,dx                       ; Point ES to VGA segment
  155.  
  156.     and   cx,3
  157.     mov   ah,11h                      ; Set up initial plane mask
  158.     shl   ah,cl
  159.  
  160.     mov   dx,SC_INDEX                 ; Prepare VGA for cpu to video writes
  161.     mov   al,MAP_MASK
  162.     out   dx,al
  163.     inc   dx
  164.     mov   [Plane],4                   ; Set plane counter to 4
  165.     mov   bh,byte ptr [Width]         ; set bh to width for fast looping
  166. @@PlaneLoop:
  167.     push  di               ; Save bitmap's start dest. offset
  168.     mov   bl,byte ptr [Height]        ; Reset row counter (BL)
  169.     mov   al,ah
  170.     out   dx,al                       ; set vga write plane
  171. @@RowLoop:
  172.     mov   cl,bh                       ; Reset Column counter cl
  173.     jcxz  @@NoWidth
  174. @@ColLoop:
  175.     lodsb                          ; Get next source bitmap byte
  176.     or    al,al                       ; If not zero then write to dest.
  177.     jz    @@NoPixel                   ; otherwise skip to next byte
  178.     mov   es:[di],al
  179. @@NoPixel:
  180.     inc   di
  181.     loop @@ColLoop
  182. @@NoWidth:
  183.     add   si,[DataInc]                ; Move to next source row
  184.     add   di,[LineInc]                ; Move to next screen row
  185.     dec   bl                          ; decrement row counter
  186.     jnz   @@RowLoop                   ; Jump if more rows left
  187.     pop   di                          ; Restore bitmaps start dest byte
  188.     rol   ah,1                  ; Shift mask for next plane
  189.  
  190.     ; Plane Transition (A HACK but it works!)
  191.  
  192.     jnb   @@Nocarry                   ; Jump if not plane transition
  193.     mov   bl,ah                       ; Save Plane Mask
  194.     mov   ax,[CType]                  ; set AX to clip type inc variable
  195.     add   bh,al                       ; Update advancing variables
  196.     sub   [DataInc],ax                ;
  197.     sub   [LineInc],ax                ;
  198.     cmp   al,0                        ; What type of clip do we have
  199.     mov   ah,bl                       ;   restore Plane mask
  200.     jg    @@RightAdvance              ; jump on a right clip!
  201.     inc   di                          ; otherwise increment DI
  202.     jmp   @@Nocarry
  203. @@RightAdvance:
  204.     dec si
  205. @@Nocarry:
  206.     dec   [Plane]                     ; Decrement plane counter
  207.     jnz   @@PlaneLoop                 ; Jump if more planes left
  208.  
  209.     xor   ax,ax
  210.     pop   ds                          ; restore data segment
  211.     pop   di                          ; restore registers
  212.     pop   si
  213.     mov   sp,bp                       ; dealloc local variables
  214.     pop   bp
  215.     ret
  216. _x_put_masked_pbm_clipx  endp
  217.  
  218.  
  219. ;----------------------------------------------------------------------
  220. ; x_put_masked_pbm_clipy - mask write a planar bitmap from system ram to video
  221. ;            ram all zero source bitmap bytes indicate destination
  222. ;            byte to be left unchanged.
  223. ;                       Performs clipping in y direction. similar to
  224. ;                "x_put_masked_pbm".
  225. ;
  226. ; See Also:  x_put_masked_pbm, x_put_masked_pbm_clipx, x_put_masked_pbm_clipy
  227. ;
  228. ; Clipping region variables: TopClip,BottomClip
  229. ;
  230. ; Written by Themie Gouthas
  231. ;----------------------------------------------------------------------
  232. _x_put_masked_pbm_clipy  proc
  233. ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
  234. LOCAL   Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk
  235.     push  bp
  236.     mov   bp,sp
  237.     sub   sp,LocalStk                 ; Create space for local variables
  238.     push  si
  239.     push  di
  240.     push  ds
  241.     cld
  242.  
  243.     les   si,[Bitmap]
  244.  
  245.     xor   bh,bh
  246.     mov   bl,byte ptr es:[si+1]       ; BX = height
  247.  
  248.     xor   ah,ah
  249.     mov   al,byte ptr es:[si]         ; AX = width
  250.  
  251.     mov   cx,ax                       ; Save AX
  252.     mul   bx                          ; AX = AX*BX = bytes/plane
  253.     mov   [PlaneInc],ax               ;  save as PlaneInc
  254.     mov   ax,cx                       ; Restore AX
  255.  
  256.     mov   di,[X]
  257.     mov   cx,di
  258.     shr   di,2
  259.  
  260.     ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;
  261.  
  262.     mov   dx,[_TopClip]           ; Compare u.l. Y coord with Top
  263.     sub   dx,[Y]                  ; clipping border
  264.     jle   @@NotTopClip            ; jump if VBM not clipped from above
  265.     cmp   dx,bx
  266.     jnl   @@NotVisible            ; jump if VBM is completely obscured
  267.     mov   [TopRow],dx
  268.     sub   bx,dx
  269.     add   [Y],dx
  270.     jmp   short @@VertClipDone
  271.  
  272.     ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;
  273.  
  274. @@NotVisible:
  275.     mov   ax,1
  276.     pop   ds                          ; restore data segment
  277.     pop   di                          ; restore registers
  278.     pop   si
  279.     mov   sp,bp                       ; dealloc local variables
  280.     pop   bp
  281.     ret
  282.  
  283.     ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  284.  
  285. @@NotTopClip:
  286.     mov   dx,[_BottomClip]
  287.     sub   dx,[Y]
  288.     js    @@NotVisible
  289.     mov   [TopRow],0
  290.     cmp   dx,bx
  291.     jg    @@VertClipDone
  292.     inc   dx
  293.     mov   bx,dx
  294.  
  295. @@VertClipDone:
  296.  
  297.     mov   [Width],ax
  298.     mov   [Height],bx                 ; Calculate relative offset in data
  299.     mul   [TopRow]                    ;  of first visible scanline
  300.     add   ax,2                        ; Skip dimension bytes in source
  301.     add   si,ax                       ; Skip top rows that arent visible
  302.  
  303.  
  304.     mov   ax,[Y]                      ; Calculate screen row
  305.     mov   bx,[_ScrnLogicalByteWidth]  ;  by mult. Y coord by Screen
  306.     mul   bx                          ;  width then adding screen offset
  307.     add   di,ax
  308.     add   di,[ScrnOffs]
  309.     sub   bx,[Width]                  ; calculate difference from end of
  310.     mov   [LineInc],bx                ; b.m. in curr line to beginning of
  311.                       ; b.m. on next scan line
  312.  
  313.     mov   dx,_SCREEN_SEG              ; Grab _SCREEN_SEG before changing ds
  314.     mov   ax,es                       ; copy ES to DS
  315.     mov   ds,ax
  316.     mov   es,dx                       ; Point ES to VGA segment
  317.  
  318.     mov   ah,11h                      ; Set up initial plane mask
  319.     and   cx,3
  320.     shl   ah,cl
  321.  
  322.     mov   dx,SC_INDEX                 ; Prepare VGA for cpu to video writes
  323.     mov   al,MAP_MASK
  324.     out   dx,al
  325.     inc   dx
  326.     mov   bh,4                        ; Set plane counter to 4
  327. @@PlaneLoop:
  328.     push  di               ; Save bitmap's start dest. offset
  329.     push  si                          ; Save Bitmaps data offset
  330.     mov   bl,byte ptr [Height]        ; Reset row counter (BL)
  331.     mov   al,ah
  332.     out   dx,al                       ; set vga write plane
  333. @@RowLoop:
  334.     mov   cl,byte ptr [Width]         ; Reset Column counter cl
  335. @@ColLoop:
  336.     lodsb                             ; Get next source bitmap byte
  337.     or    al,al                       ; If not zero then write to dest.
  338.     jz    @@NoPixel                   ; otherwise skip to next byte
  339.     mov   es:[di],al
  340. @@NoPixel:
  341.     inc   di
  342.     loop  @@ColLoop                   ; loop if more columns left
  343.     add   di,[LineInc]                ; Move to next row
  344.     dec   bl                          ; decrement row counter
  345.     jnz   @@RowLoop                   ; Jump if more rows left
  346.     pop   si                          ; Restore SI and set to offset of
  347.     add   si,[PlaneInc]               ; first vis pixel in next plane data
  348.     pop   di                          ; Restore bitmaps start dest byte
  349.     rol   ah,1                        ; Shift mask for next plane
  350.     adc   di,0                        ; if carry increment screen offset
  351.     dec   bh                          ; Decrement plane counter
  352.     jnz   @@PlaneLoop                 ; Jump if more planes left
  353.  
  354.     xor   ax,ax
  355.     pop   ds                          ; restore data segment
  356.     pop   di                          ; restore registers
  357.     pop   si
  358.     mov   sp,bp                       ; dealloc local variables
  359.     pop   bp
  360.     ret
  361. _x_put_masked_pbm_clipy   endp
  362.  
  363. ;----------------------------------------------------------------------
  364. ; x_put_masked_pbm_clipxy - Write a planar bitmap from system ram to video
  365. ;                    RAM with clipping in x and y directions. similar to
  366. ;             "x_put_masked_pbm".
  367. ;
  368. ; See Also: x_put_masked_pbm, x_put_masked_pbm_clipx, x_put_masked_pbm_clipxy
  369. ;
  370. ; Clipping region variables: LeftClip,RightClip,TopClip,BottomClip
  371. ;
  372. ;
  373. ; Written by Themie Gouthas
  374. ;----------------------------------------------------------------------
  375. _x_put_masked_pbm_clipxy  proc
  376. ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
  377. LOCAL   Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk
  378.     push  bp
  379.     mov   bp,sp
  380.     sub   sp,LocalStk                 ; Create space for local variables
  381.     push  si
  382.     push  di
  383.     push  ds
  384.     cld
  385.  
  386.     les   si,[Bitmap]
  387.  
  388.     xor   ax,ax
  389.     mov   [CType],ax
  390.     mov   al,byte ptr es:[si]         ; AX = width
  391.     xor   bh,bh
  392.     mov   bl,byte ptr es:[si+1]       ; BX = height
  393.  
  394.     mov   cx,ax                       ; Save AX
  395.     mul   bx                          ; AX = AX*BX = bytes/plane
  396.     mov   [PlaneInc],ax               ;  save as PlaneInc
  397.     mov   ax,cx                       ; Restore AX
  398.  
  399.  
  400.     mov   di,[X]                      ; DI = X coordinate of dest.
  401.     mov   cx,di                       ; save in CX
  402.     sar   di,2                        ; convert to address byte
  403.  
  404.  
  405.         ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;
  406.  
  407.     mov   dx,[_TopClip]           ; Compare u.l. Y coord with Top
  408.     sub   dx,[Y]                  ; clipping border
  409.     jle   @@NotTopClip            ; jump if VBM not clipped from above
  410.     cmp   dx,bx
  411.     jnl   @@NotVisible            ; jump if VBM is completely obscured
  412.     mov   [TopRow],dx
  413.     sub   bx,dx
  414.     add   [Y],dx
  415.     jmp   short @@VertClipDone
  416.  
  417.     ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;
  418.  
  419. @@NotVisible:
  420.     mov   ax,1
  421.     pop   ds                          ; restore data segment
  422.     pop   di                          ; restore registers
  423.     pop   si
  424.     mov   sp,bp                       ; dealloc local variables
  425.     pop   bp
  426.     ret
  427.  
  428.     ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  429.  
  430. @@NotTopClip:
  431.     mov   dx,[_BottomClip]
  432.     sub   dx,[Y]
  433.     js    @@NotVisible
  434.     mov   [TopRow],0
  435.     cmp   dx,bx
  436.     jg    @@VertClipDone
  437.     inc   dx
  438.     mov   bx,dx
  439.  
  440. @@VertClipDone:
  441.  
  442.     ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  443.  
  444.     mov   dx,[_LeftClip]
  445.     sub   dx,di
  446.     jle   @@NotLeftClip
  447.     cmp   dx,ax
  448.     jnl   @@NotVisible
  449.  
  450.     add   di,dx
  451.     mov   [LeftSkip],dx
  452.     mov   [DataInc],dx
  453.     sub   ax,dx
  454.     mov   [CType],1
  455.     jmp   short @@HorizClipDone
  456.  
  457.     ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  458.  
  459. @@NotLeftClip:
  460.     mov   dx,[_RightClip]
  461.     sub   dx,di
  462.     js    @@NotVisible
  463.     mov   [LeftSkip],0
  464.     mov   [DataInc],0
  465.     cmp   dx,ax
  466.         jge   @@HorizClipDone       ; was jg
  467.     inc   dx
  468.     sub   ax,dx
  469.     mov   [DataInc],ax
  470.     mov   ax,dx
  471.  
  472.  
  473.     mov   [CType],-1
  474.  
  475. @@HorizClipDone:
  476.  
  477.  
  478.  
  479.     mov   [Width],ax                  ; Save width and height of clipped
  480.     mov   [Height],bx                 ;  image
  481.  
  482.     add   ax,[DataInc]                ; AX = original width of image
  483.     mul   [TopRow]                    ; Calculate bytes in clipped top
  484.     add   si,ax                  ;  rows
  485.     add   si,2                        ; Skip dimension bytes in source
  486.     add   si,[LeftSkip]               ; Skip pixels in front of row that
  487.                       ;  are clipped
  488.  
  489.     mov   bx,[_ScrnLogicalByteWidth]  ; Set BX to Logical Screen Width
  490.     mov   dx,bx                       ; BX - Width of image = No. bytes
  491.     sub   dx,[Width]                  ;  to first byte of next screen
  492.     mov   [LineInc],dx                ;  row.
  493.  
  494.     mov   ax,[Y]                      ; Calculate screen start row
  495.     mul   bx                          ;  then adding screen offset
  496.     add   di,ax
  497.     add   di,[ScrnOffs]
  498.  
  499.     mov   dx,_SCREEN_SEG              ; Grab _SCREEN_SEG before changing ds
  500.     mov   ax,es                       ; copy ES to DS
  501.     mov   ds,ax
  502.     mov   es,dx                       ; Point ES to VGA segment
  503.  
  504.     and   cx,3
  505.     mov   ah,11h                      ; Set up initial plane mask
  506.     shl   ah,cl
  507.  
  508.     mov   dx,SC_INDEX                 ; Prepare VGA for cpu to video writes
  509.     mov   al,MAP_MASK
  510.     out   dx,al
  511.     inc   dx
  512.     mov   [Plane],4                   ; Set plane counter to 4
  513.     mov   bh,byte ptr [Width]         ; set bh to width for fast looping
  514. @@PlaneLoop:
  515.     push  di               ; Save bitmap's start dest. offset
  516.     push  si
  517.     mov   bl,byte ptr [Height]        ; Reset row counter (BL)
  518.     mov   al,ah
  519.     out   dx,al                       ; set vga write plane
  520. @@RowLoop:
  521.     mov   cl,bh                       ; Reset Column counter cl
  522.     jcxz   @@NoWidth
  523. @@ColLoop:
  524.     lodsb                          ; Get next source bitmap byte
  525.     or    al,al                       ; If not zero then write to dest.
  526.     jz    @@NoPixel                   ; otherwise skip to next byte
  527.     mov   es:[di],al
  528. @@NoPixel:
  529.     inc   di
  530.     loop @@ColLoop
  531. @@NoWidth:
  532.     add   si,[DataInc]                ; Move to next source row
  533.     add   di,[LineInc]                ; Move to next screen row
  534.     dec   bl                          ; decrement row counter
  535.     jnz   @@RowLoop                   ; Jump if more rows left
  536.     pop   si                          ; Restore SI and set to offset of
  537.     add   si,[PlaneInc]               ; first vis pixel in next plane data
  538.     pop   di                          ; Restore bitmaps start dest byte
  539.     rol   ah,1                  ; Shift mask for next plane
  540.  
  541.     ; Plane Transition (A HACK but it works!)
  542.  
  543.     jnb   @@Nocarry                   ; Jump if not plane transition
  544.     mov   bl,ah                       ; Save Plane Mask
  545.     mov   ax,[CType]                  ; set AX to clip type inc variable
  546.     add   bh,al                       ; Update advancing variables
  547.     sub   [DataInc],ax                ;
  548.     sub   [LineInc],ax                ;
  549.     cmp   al,0                        ; What type of clip do we have
  550.     mov   ah,bl                       ;   restore Plane mask
  551.     jg    @@RightAdvance              ; jump on a right clip!
  552.     inc   di                          ; otherwise increment DI
  553.     jmp   @@Nocarry
  554. @@RightAdvance:
  555.     dec   si
  556. @@Nocarry:
  557.     dec   [Plane]                     ; Decrement plane counter
  558.     jnz   @@PlaneLoop                 ; Jump if more planes left
  559.  
  560.     xor   ax,ax
  561.     pop   ds                          ; restore data segment
  562.     pop   di                          ; restore registers
  563.     pop   si
  564.     mov   sp,bp                       ; dealloc local variables
  565.     pop   bp
  566.     ret
  567. _x_put_masked_pbm_clipxy  endp
  568.  
  569.  
  570.  
  571.  
  572. ;----------------------------------------------------------------------
  573. ; x_put_pbm_clipx - Write a planar bitmap from system ram to video ram
  574. ;                    with clipping in x and y directions. similar to
  575. ;             "x_put_pbm".
  576. ;
  577. ; See Also:  x_put_pbm_clip
  578. ;
  579. ;
  580. ; See Also:  x_put_pbm,x_put_pbm_clipy,x_put_pbm_clipxy
  581. ;
  582. ; Clipping region variables: LeftClip,RightClip
  583. ;
  584. ; Written by Themie Gouthas
  585. ;
  586. ; This code is a SLOW hack, any better ideas are welcome
  587. ;----------------------------------------------------------------------
  588. _x_put_pbm_clipx  proc
  589. ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
  590. LOCAL   Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc:word=LocalStk
  591.     push  bp
  592.     mov   bp,sp
  593.     sub   sp,LocalStk                 ; Create space for local variables
  594.     push  si
  595.     push  di
  596.     push  ds
  597.     cld
  598.  
  599.     les   si,[Bitmap]
  600.  
  601.     xor   ax,ax
  602.     mov   [CType],ax
  603.     mov   al,byte ptr es:[si]         ; AX = width
  604.  
  605.  
  606.     mov   di,[X]                      ; DI = X coordinate of dest.
  607.     mov   cx,di                       ; save in CX
  608.     sar   di,2                        ; convert to address byte
  609.  
  610.  
  611.  
  612.     ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  613.  
  614.     mov   dx,[_LeftClip]
  615.     sub   dx,di
  616.     jle   @@NotLeftClip
  617.     cmp   dx,ax
  618.     jnl   @@NotVisible
  619.  
  620.     add   di,dx
  621.     mov   [LeftSkip],dx
  622.     mov   [DataInc],dx
  623.     sub   ax,dx
  624.     mov   [CType],1
  625.     jmp   short @@HorizClipDone
  626.  
  627.     ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;
  628.  
  629. @@NotVisible:
  630.     mov   ax,1
  631.     pop   ds                          ; restore data segment
  632.     pop   di                          ; restore registers
  633.     pop   si
  634.     mov   sp,bp                       ; dealloc local variables
  635.     pop   bp
  636.     ret
  637.  
  638.     ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  639.  
  640. @@NotLeftClip:
  641.     mov   dx,[_RightClip]
  642.     sub   dx,di
  643.     js    @@NotVisible
  644.     mov   [LeftSkip],0
  645.     mov   [DataInc],0
  646.     cmp   dx,ax
  647.         jge   @@HorizClipDone       ; was jg
  648.     inc   dx
  649.     sub   ax,dx
  650.     mov   [DataInc],ax
  651.     mov   ax,dx
  652.     mov   [CType],-1
  653.  
  654. @@HorizClipDone:
  655.  
  656.     xor   bh,bh
  657.     mov   bl,byte ptr es:[si+1]       ; BX = height
  658.  
  659.     mov   [Width],ax                  ; Save width and height of clipped
  660.     mov   [Height],bx                 ;  image
  661.  
  662.  
  663.     add   si,2                        ; Skip dimension bytes in source
  664.     add   si,[LeftSkip]               ; Skip pixels in front of row that
  665.                       ;  are clipped
  666.  
  667.  
  668.     mov   bx,[_ScrnLogicalByteWidth]  ; Set BX to Logical Screen Width
  669.     mov   dx,bx                       ; BX - Width of image = No. bytes
  670.     sub   dx,ax                       ;  to first byte of next screen
  671.     mov   [LineInc],dx                ;  row.
  672.  
  673.     mov   ax,[Y]                      ; Calculate screen start row
  674.     mul   bx                          ;  then adding screen offset
  675.     add   di,ax
  676.     add   di,[ScrnOffs]
  677.  
  678.     mov   dx,_SCREEN_SEG              ; Grab _SCREEN_SEG before changing ds
  679.     mov   ax,es                       ; copy ES to DS
  680.     mov   ds,ax
  681.     mov   es,dx                       ; Point ES to VGA segment
  682.  
  683.     and   cx,3
  684.     mov   ah,11h                      ; Set up initial plane mask
  685.     shl   ah,cl
  686.  
  687.     mov   dx,SC_INDEX                 ; Prepare VGA for cpu to video writes
  688.     mov   al,MAP_MASK
  689.     out   dx,al
  690.     inc   dx
  691.     mov   [Plane],4                   ; Set plane counter to 4
  692.     mov   bh,byte ptr [Width]         ; set bh to width for fast looping
  693. @@PlaneLoop:
  694.     push  di               ; Save bitmap's start dest. offset
  695.     mov   bl,byte ptr [Height]        ; Reset row counter (BL)
  696.     mov   al,ah
  697.     out   dx,al                       ; set vga write plane
  698. @@RowLoop:
  699.     mov   cl,bh                       ; Reset Column counter cl
  700.     shr   cl,1
  701.     rep   movsw                       ; Copy a complete row
  702.     adc   cl,0
  703.     rep   movsb
  704.     add   si,[DataInc]                ; Move to next source row
  705.     add   di,[LineInc]                ; Move to next screen row
  706.     dec   bl                          ; decrement row counter
  707.     jnz   @@RowLoop                   ; Jump if more rows left
  708.     pop   di                          ; Restore bitmaps start dest byte
  709.     rol   ah,1                  ; Shift mask for next plane
  710.  
  711.     ; Plane Transition (A HACK but it works!)
  712.  
  713.     jnb   @@Nocarry                   ; Jump if not plane transition
  714.     mov   bl,ah                       ; Save Plane Mask
  715.     mov   ax,[CType]                  ; set AX to clip type inc variable
  716.     add   bh,al                       ; Update advancing variables
  717.     sub   [DataInc],ax                ;
  718.     sub   [LineInc],ax                ;
  719.     cmp   al,0                        ; What type of clip do we have
  720.     mov   ah,bl                       ;   restore Plane mask
  721.     jg    @@RightAdvance              ; jump on a right clip!
  722.     inc   di                          ; otherwise increment DI
  723.     jmp   @@Nocarry
  724. @@RightAdvance:
  725.     dec si
  726. @@Nocarry:
  727.     dec   [Plane]                     ; Decrement plane counter
  728.     jnz   @@PlaneLoop                 ; Jump if more planes left
  729.  
  730.     xor   ax,ax
  731.     pop   ds                          ; restore data segment
  732.     pop   di                          ; restore registers
  733.     pop   si
  734.     mov   sp,bp                       ; dealloc local variables
  735.     pop   bp
  736.     ret
  737. _x_put_pbm_clipx  endp
  738.  
  739.  
  740.  
  741. ;----------------------------------------------------------------------
  742. ; x_put_pbm_clipy - Write a planar bitmap from system ram to video ram
  743. ;                    with clipping in y direction only. similar to
  744. ;             "x_put_pbm".
  745. ;
  746. ; See Also:  x_put_pbm,x_put_pbm_clipx,x_put_pbm_clipxy
  747. ;
  748. ; Clipping region variables: TopClip,BottomClip
  749. ;
  750. ; Written by Themie Gouthas
  751. ;----------------------------------------------------------------------
  752. _x_put_pbm_clipy  proc
  753. ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
  754. LOCAL   Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk
  755.     push  bp
  756.     mov   bp,sp
  757.     sub   sp,LocalStk                 ; Create space for local variables
  758.     push  si
  759.     push  di
  760.     push  ds
  761.     cld
  762.  
  763.     les   si,[Bitmap]
  764.  
  765.     xor   bh,bh
  766.     mov   bl,byte ptr es:[si+1]   ; BX = height
  767.     ;mov   [Height],bx
  768.  
  769.     xor   ah,ah
  770.     mov   al,byte ptr es:[si]     ; AX = width
  771.     mov   [Width],ax
  772.  
  773.     mov   cx,ax                       ; Save AX
  774.     mul   bx                          ; AX = AX*BX = bytes/plane
  775.     mov   [PlaneInc],ax               ;  save as PlaneInc
  776.     mov   ax,cx                       ; Restore AX
  777.  
  778.     mov   di,[X]
  779.     mov   cx,di
  780.     and   cx,3
  781.     shr   di,2
  782.  
  783.     ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;
  784.  
  785.     mov   dx,[_TopClip]           ; Compare u.l. Y coord with Top
  786.     sub   dx,[Y]                  ; clipping border
  787.     jle   @@NotTopClip            ; jump if VBM not clipped from above
  788.     cmp   dx,bx
  789.     jnl   @@NotVisible            ; jump if VBM is completely obscured
  790.     mov   [TopRow],dx
  791.     sub   bx,dx
  792.     add   [Y],dx
  793.     jmp   short @@VertClipDone
  794.  
  795.     ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;
  796.  
  797. @@NotVisible:
  798.     mov   ax,1
  799.     pop   ds                          ; restore data segment
  800.     pop   di                          ; restore registers
  801.     pop   si
  802.     mov   sp,bp                       ; dealloc local variables
  803.     pop   bp
  804.     ret
  805.  
  806.     ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  807.  
  808. @@NotTopClip:
  809.     mov   dx,[_BottomClip]
  810.     sub   dx,[Y]
  811.     js    @@NotVisible
  812.     mov   [TopRow],0
  813.     cmp   dx,bx
  814.     jg    @@VertClipDone
  815.     inc   dx
  816.     mov   bx,dx
  817.  
  818. @@VertClipDone:
  819.  
  820.     mov   [Height],bx                 ; Calculate relative offset in data
  821.     mul   [TopRow]                    ;  of first visible scanline
  822.     add   ax,2                        ; Skip dimension bytes in source
  823.     add   si,ax                       ; Skip top rows that arent visible
  824.  
  825.  
  826.     mov   ax,[Y]                      ; Calculate screen row
  827.     mov   bx,[_ScrnLogicalByteWidth]  ;  by mult. Y coord by Screen
  828.     mul   bx                          ;  width then adding screen offset
  829.     add   di,ax
  830.     add   di,[ScrnOffs]
  831.     sub   bx,[Width]                  ; calculate difference from end of
  832.     mov   [LineInc],bx                ; b.m. in curr line to beginning of
  833.                       ; b.m. on next scan line
  834.  
  835.     mov   dx,_SCREEN_SEG              ; Grab _SCREEN_SEG before changing ds
  836.     mov   ax,es                       ; copy ES to DS
  837.     mov   ds,ax
  838.     mov   es,dx                       ; Point ES to VGA segment
  839.  
  840.     mov   ah,11h                      ; Set up initial plane mask
  841.     shl   ah,cl
  842.  
  843.     mov   dx,SC_INDEX                 ; Prepare VGA for cpu to video writes
  844.     mov   al,MAP_MASK
  845.     out   dx,al
  846.     inc   dx
  847.     mov   bh,4                        ; Set plane counter to 4
  848. @@PlaneLoop:
  849.     push  di               ; Save bitmap's start dest. offset
  850.     push  si                          ; Save Bitmaps data offset
  851.     mov   bl,byte ptr [Height]        ; Reset row counter (BL)
  852.     mov   al,ah
  853.     out   dx,al                       ; set vga write plane
  854. @@RowLoop:
  855.     mov   cl,byte ptr [Width]         ; Reset Column counter cl
  856.     shr   cl,1
  857.     rep   movsw                       ; Copy a complete row
  858.     adc   cl,0
  859.     rep   movsb
  860.  
  861.     add   di,[LineInc]                ; Move to next row
  862.     dec   bl                          ; decrement row counter
  863.     jnz   @@RowLoop                   ; Jump if more rows left
  864.     pop   si                          ; Restore SI and set to offset of
  865.     add   si,[PlaneInc]               ; first vis pixel in next plane data
  866.     pop   di                          ; Restore bitmaps start dest byte
  867.     rol   ah,1                        ; Shift mask for next plane
  868.     adc   di,0                        ; if carry increment screen offset
  869.     dec   bh                          ; Decrement plane counter
  870.     jnz   @@PlaneLoop                 ; Jump if more planes left
  871.  
  872.     xor   ax,ax
  873.     pop   ds                          ; restore data segment
  874.     pop   di                          ; restore registers
  875.     pop   si
  876.     mov   sp,bp                       ; dealloc local variables
  877.     pop   bp
  878.     ret
  879. _x_put_pbm_clipy   endp
  880.  
  881.  
  882. ;----------------------------------------------------------------------
  883. ; x_put_pbm_clipxy - Write a planar bitmap from system ram to video ram
  884. ;                    with clipping in x and y directions. similar to
  885. ;             "x_put_pbm".
  886. ;
  887. ; See Also:  x_put_pbm,x_put_pbm_clipy,x_put_pbm_clipx
  888. ;
  889. ; Clipping region variables: LeftClip,RightClip,TopClip,BottomClip
  890. ;
  891. ; Written by Themie Gouthas
  892. ;----------------------------------------------------------------------
  893. _x_put_pbm_clipxy  proc
  894. ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
  895. LOCAL   Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk
  896.     push  bp
  897.     mov   bp,sp
  898.     sub   sp,LocalStk                 ; Create space for local variables
  899.     push  si
  900.     push  di
  901.     push  ds
  902.     cld
  903.  
  904.     les   si,[Bitmap]
  905.  
  906.     xor   ax,ax
  907.     mov   [CType],ax
  908.     mov   al,byte ptr es:[si]         ; AX = width
  909.     xor   bh,bh
  910.     mov   bl,byte ptr es:[si+1]       ; BX = height
  911.  
  912.     mov   cx,ax                       ; Save AX
  913.     mul   bx                          ; AX = AX*BX = bytes/plane
  914.     mov   [PlaneInc],ax               ;  save as PlaneInc
  915.     mov   ax,cx                       ; Restore AX
  916.  
  917.  
  918.     mov   di,[X]                      ; DI = X coordinate of dest.
  919.     mov   cx,di                       ; save in CX
  920.     sar   di,2                        ; convert to address byte
  921.  
  922.  
  923.         ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;
  924.  
  925.     mov   dx,[_TopClip]           ; Compare u.l. Y coord with Top
  926.     sub   dx,[Y]                  ; clipping border
  927.     jle   @@NotTopClip            ; jump if VBM not clipped from above
  928.     cmp   dx,bx
  929.     jnl   @@NotVisible            ; jump if VBM is completely obscured
  930.     mov   [TopRow],dx
  931.     sub   bx,dx
  932.     add   [Y],dx
  933.     jmp   short @@VertClipDone
  934.  
  935.     ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;
  936.  
  937. @@NotVisible:
  938.     mov   ax,1
  939.     pop   ds                          ; restore data segment
  940.     pop   di                          ; restore registers
  941.     pop   si
  942.     mov   sp,bp                       ; dealloc local variables
  943.     pop   bp
  944.     ret
  945.  
  946.     ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  947.  
  948. @@NotTopClip:
  949.     mov   dx,[_BottomClip]
  950.     sub   dx,[Y]
  951.     js    @@NotVisible
  952.     mov   [TopRow],0
  953.     cmp   dx,bx
  954.     jg    @@VertClipDone
  955.     inc   dx
  956.     mov   bx,dx
  957.  
  958. @@VertClipDone:
  959.  
  960.     ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  961.  
  962.     mov   dx,[_LeftClip]
  963.     sub   dx,di
  964.     jle   @@NotLeftClip
  965.     cmp   dx,ax
  966.     jnl   @@NotVisible
  967.  
  968.     add   di,dx
  969.     mov   [LeftSkip],dx
  970.     mov   [DataInc],dx
  971.     sub   ax,dx
  972.     mov   [CType],1
  973.     jmp   short @@HorizClipDone
  974.  
  975.     ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
  976.  
  977. @@NotLeftClip:
  978.     mov   dx,[_RightClip]
  979.     sub   dx,di
  980.     js    @@NotVisible
  981.     mov   [LeftSkip],0
  982.     mov   [DataInc],0
  983.     cmp   dx,ax
  984.         jge   @@HorizClipDone       ; was jg
  985.     inc   dx
  986.     sub   ax,dx
  987.     mov   [DataInc],ax
  988.     mov   ax,dx
  989.     mov   [CType],-1
  990.  
  991. @@HorizClipDone:
  992.  
  993.  
  994.  
  995.     mov   [Width],ax                  ; Save width and height of clipped
  996.     mov   [Height],bx                 ;  image
  997.  
  998.     add   ax,[DataInc]                ; AX = original width of image
  999.     mul   [TopRow]                    ; Calculate bytes in clipped top
  1000.     add   si,ax                  ;  rows
  1001.     add   si,2                        ; Skip dimension bytes in source
  1002.     add   si,[LeftSkip]               ; Skip pixels in front of row that
  1003.                       ;  are clipped
  1004.  
  1005.     mov   bx,[_ScrnLogicalByteWidth]  ; Set BX to Logical Screen Width
  1006.     mov   dx,bx                       ; BX - Width of image = No. bytes
  1007.     sub   dx,[Width]                  ;  to first byte of next screen
  1008.     mov   [LineInc],dx                ;  row.
  1009.  
  1010.     mov   ax,[Y]                      ; Calculate screen start row
  1011.     mul   bx                          ;  then adding screen offset
  1012.     add   di,ax
  1013.     add   di,[ScrnOffs]
  1014.  
  1015.     mov   dx,_SCREEN_SEG              ; Grab _SCREEN_SEG before changing ds
  1016.     mov   ax,es                       ; copy ES to DS
  1017.     mov   ds,ax
  1018.     mov   es,dx                       ; Point ES to VGA segment
  1019.  
  1020.     and   cx,3
  1021.     mov   ah,11h                      ; Set up initial plane mask
  1022.     shl   ah,cl
  1023.  
  1024.     mov   dx,SC_INDEX                 ; Prepare VGA for cpu to video writes
  1025.     mov   al,MAP_MASK
  1026.     out   dx,al
  1027.     inc   dx
  1028.     mov   [Plane],4                   ; Set plane counter to 4
  1029.     mov   bh,byte ptr [Width]         ; set bh to width for fast looping
  1030. @@PlaneLoop:
  1031.     push  di               ; Save bitmap's start dest. offset
  1032.     push  si
  1033.     mov   bl,byte ptr [Height]        ; Reset row counter (BL)
  1034.     mov   al,ah
  1035.     out   dx,al                       ; set vga write plane
  1036. @@RowLoop:
  1037.     mov   cl,bh                       ; Reset Column counter cl
  1038.     shr   cl,1
  1039.     rep   movsw                       ; Copy a complete row
  1040.     adc   cl,0
  1041.     rep   movsb
  1042.     add   si,[DataInc]                ; Move to next source row
  1043.     add   di,[LineInc]                ; Move to next screen row
  1044.     dec   bl                          ; decrement row counter
  1045.     jnz   @@RowLoop                   ; Jump if more rows left
  1046.     pop   si                          ; Restore SI and set to offset of
  1047.     add   si,[PlaneInc]               ; first vis pixel in next plane data
  1048.     pop   di                          ; Restore bitmaps start dest byte
  1049.     rol   ah,1                  ; Shift mask for next plane
  1050.  
  1051.     ; Plane Transition (A HACK but it works!)
  1052.  
  1053.     jnb   @@Nocarry                   ; Jump if not plane transition
  1054.     mov   bl,ah                       ; Save Plane Mask
  1055.     mov   ax,[CType]                  ; set AX to clip type inc variable
  1056.     add   bh,al                       ; Update advancing variables
  1057.     sub   [DataInc],ax                ;
  1058.     sub   [LineInc],ax                ;
  1059.     cmp   al,0                        ; What type of clip do we have
  1060.     mov   ah,bl                       ;   restore Plane mask
  1061.     jg    @@RightAdvance              ; jump on a right clip!
  1062.     inc   di                          ; otherwise increment DI
  1063.     jmp   @@Nocarry
  1064. @@RightAdvance:
  1065.     dec si
  1066. @@Nocarry:
  1067.     dec   [Plane]                     ; Decrement plane counter
  1068.     jnz   @@PlaneLoop                 ; Jump if more planes left
  1069.  
  1070.     xor   ax,ax
  1071.     pop   ds                          ; restore data segment
  1072.     pop   di                          ; restore registers
  1073.     pop   si
  1074.     mov   sp,bp                       ; dealloc local variables
  1075.     pop   bp
  1076.     ret
  1077. _x_put_pbm_clipxy  endp
  1078.  
  1079.     end
  1080.  
  1081.  
  1082.  
  1083.