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