1 ;-----------------------------------------------------------------------
\r
4 ; Clipped Planar Bitmap functions - System Ram <-> Video Ram
\r
10 ; ****** XLIB - Mode X graphics library ****************
\r
11 ; ****** ****************
\r
12 ; ****** Written By Themie Gouthas ****************
\r
14 ; egg@dstos3.dsto.gov.au
\r
15 ; teg@bart.dsto.gov.au
\r
16 ;-----------------------------------------------------------------------
\r
21 This module implements a set of functions to operate on planar bitmaps.
\r
22 Planar bitmaps as used by these functions have the following structure:
\r
24 BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255
\r
25 BYTE 1 The bitmap height in rows range 1..255
\r
26 BYTE 2..n1 The plane 0 pixels width*height bytes
\r
27 BYTE n1..n2 The plane 1 pixels width*height bytes
\r
28 BYTE n2..n3 The plane 2 pixels width*height bytes
\r
29 BYTE n3..n4 The plane 3 pixels width*height bytes
\r
31 These functions provide the fastest possible bitmap blts from system ram to
\r
32 to video and further, the single bitmap is applicable to all pixel
\r
33 allignments. The masked functions do not need separate masks since all non
\r
34 zero pixels are considered to be masking pixels, hence if a pixel is 0 the
\r
35 corresponding screen destination pixel is left unchanged.
\r
41 include xpbmclip.inc
\r
45 ;----------------------------------------------------------------------
\r
46 ; x_put_masked_pbm_clipx - mask write a planar bitmap from system ram to video
\r
47 ; ram all zero source bitmap bytes indicate destination
\r
48 ; byte to be left unchanged.
\r
49 ; Performs clipping in x directions. similar to
\r
50 ; "x_put_masked_pbm".
\r
52 ; See Also: x_put_masked_pbm, x_put_masked_pbm_clipxy
\r
54 ; Clipping region variables: LeftClip,RightClip
\r
56 ; Written by Themie Gouthas
\r
58 ; This code is a SLOW hack, any better ideas are welcome
\r
59 ;----------------------------------------------------------------------
\r
60 _x_put_masked_pbm_clipx proc
\r
61 ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
\r
62 LOCAL Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc:word=LocalStk
\r
65 sub sp,LocalStk ; Create space for local variables
\r
71 les si,[Bitmap] ; Point ES:SI to start of bitmap
\r
73 xor ax,ax ; Clear AX
\r
74 mov [CType],ax ; Clear Clip type descision var
\r
75 mov al,byte ptr es:[si] ; AX=width (byte coverted to word)
\r
78 mov di,[X] ; DI = X coordinate of dest
\r
79 mov cx,di ; copy to CX
\r
80 sar di,2 ; convert to offset in row
\r
83 ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
\r
85 mov dx,[_LeftClip] ; Is X Coord to the right of
\r
86 sub dx,di ; LeftClip ?
\r
87 jle @@NotLeftClip ; Yes! => no left clipping
\r
88 cmp dx,ax ; Is dist of X Coord from
\r
89 jnl @@NotVisible ; ClipLeft > Width ? yes => the
\r
90 ; bitmap is not visible
\r
96 jmp short @@HorizClipDone
\r
98 ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;
\r
102 pop ds ; restore data segment
\r
103 pop di ; restore registers
\r
105 mov sp,bp ; dealloc local variables
\r
109 ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
\r
112 mov dx,[_RightClip]
\r
118 jge @@HorizClipDone ; was jg
\r
128 mov bl,byte ptr es:[si+1] ; BX = height
\r
130 mov [Width],ax ; Save width and height of clipped
\r
131 mov [Height],bx ; image
\r
134 add si,2 ; Skip dimension bytes in source
\r
135 add si,[LeftSkip] ; Skip pixels in front of row that
\r
139 mov bx,[_ScrnLogicalByteWidth] ; Set BX to Logical Screen Width
\r
140 mov dx,bx ; BX - Width of image = No. bytes
\r
141 sub dx,ax ; to first byte of next screen
\r
142 mov [LineInc],dx ; row.
\r
144 mov ax,[Y] ; Calculate screen start row
\r
145 mul bx ; then adding screen offset
\r
148 mov ax,es ; copy ES to DS
\r
150 mov ax,SCREEN_SEG ; Point ES to VGA segment
\r
154 mov ah,11h ; Set up initial plane mask
\r
157 mov dx,SC_INDEX ; Prepare VGA for cpu to video writes
\r
161 mov [Plane],4 ; Set plane counter to 4
\r
162 mov bh,byte ptr [Width] ; set bh to width for fast looping
\r
164 push di ; Save bitmap's start dest. offset
\r
165 mov bl,byte ptr [Height] ; Reset row counter (BL)
\r
167 out dx,al ; set vga write plane
\r
169 mov cl,bh ; Reset Column counter cl
\r
172 lodsb ; Get next source bitmap byte
\r
173 or al,al ; If not zero then write to dest.
\r
174 jz @@NoPixel ; otherwise skip to next byte
\r
180 add si,[DataInc] ; Move to next source row
\r
181 add di,[LineInc] ; Move to next screen row
\r
182 dec bl ; decrement row counter
\r
183 jnz @@RowLoop ; Jump if more rows left
\r
184 pop di ; Restore bitmaps start dest byte
\r
185 rol ah,1 ; Shift mask for next plane
\r
187 ; Plane Transition (A HACK but it works!)
\r
189 jnb @@Nocarry ; Jump if not plane transition
\r
190 mov bl,ah ; Save Plane Mask
\r
191 mov ax,[CType] ; set AX to clip type inc variable
\r
192 add bh,al ; Update advancing variables
\r
195 cmp al,0 ; What type of clip do we have
\r
196 mov ah,bl ; restore Plane mask
\r
197 jg @@RightAdvance ; jump on a right clip!
\r
198 inc di ; otherwise increment DI
\r
203 dec [Plane] ; Decrement plane counter
\r
204 jnz @@PlaneLoop ; Jump if more planes left
\r
207 pop ds ; restore data segment
\r
208 pop di ; restore registers
\r
210 mov sp,bp ; dealloc local variables
\r
213 _x_put_masked_pbm_clipx endp
\r
216 ;----------------------------------------------------------------------
\r
217 ; x_put_masked_pbm_clipy - mask write a planar bitmap from system ram to video
\r
218 ; ram all zero source bitmap bytes indicate destination
\r
219 ; byte to be left unchanged.
\r
220 ; Performs clipping in y direction. similar to
\r
221 ; "x_put_masked_pbm".
\r
223 ; See Also: x_put_masked_pbm, x_put_masked_pbm_clipx, x_put_masked_pbm_clipy
\r
225 ; Clipping region variables: TopClip,BottomClip
\r
227 ; Written by Themie Gouthas
\r
228 ;----------------------------------------------------------------------
\r
229 _x_put_masked_pbm_clipy proc
\r
230 ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
\r
231 LOCAL Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk
\r
234 sub sp,LocalStk ; Create space for local variables
\r
243 mov bl,byte ptr es:[si+1] ; BX = height
\r
246 mov al,byte ptr es:[si] ; AX = width
\r
248 mov cx,ax ; Save AX
\r
249 mul bx ; AX = AX*BX = bytes/plane
\r
250 mov [PlaneInc],ax ; save as PlaneInc
\r
251 mov ax,cx ; Restore AX
\r
257 ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;
\r
259 mov dx,[_TopClip] ; Compare u.l. Y coord with Top
\r
260 sub dx,[Y] ; clipping border
\r
261 jle @@NotTopClip ; jump if VBM not clipped from above
\r
263 jnl @@NotVisible ; jump if VBM is completely obscured
\r
267 jmp short @@VertClipDone
\r
269 ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;
\r
273 pop ds ; restore data segment
\r
274 pop di ; restore registers
\r
276 mov sp,bp ; dealloc local variables
\r
280 ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;
\r
283 mov dx,[_BottomClip]
\r
295 mov [Height],bx ; Calculate relative offset in data
\r
296 mul [TopRow] ; of first visible scanline
\r
297 add ax,2 ; Skip dimension bytes in source
\r
298 add si,ax ; Skip top rows that arent visible
\r
301 mov ax,[Y] ; Calculate screen row
\r
302 mov bx,[_ScrnLogicalByteWidth] ; by mult. Y coord by Screen
\r
303 mul bx ; width then adding screen offset
\r
306 sub bx,[Width] ; calculate difference from end of
\r
307 mov [LineInc],bx ; b.m. in curr line to beginning of
\r
308 ; b.m. on next scan line
\r
309 mov ax,es ; copy ES to DS
\r
311 mov ax,SCREEN_SEG ; Point ES to VGA segment
\r
314 mov ah,11h ; Set up initial plane mask
\r
318 mov dx,SC_INDEX ; Prepare VGA for cpu to video writes
\r
322 mov bh,4 ; Set plane counter to 4
\r
324 push di ; Save bitmap's start dest. offset
\r
325 push si ; Save Bitmaps data offset
\r
326 mov bl,byte ptr [Height] ; Reset row counter (BL)
\r
328 out dx,al ; set vga write plane
\r
330 mov cl,byte ptr [Width] ; Reset Column counter cl
\r
332 lodsb ; Get next source bitmap byte
\r
333 or al,al ; If not zero then write to dest.
\r
334 jz @@NoPixel ; otherwise skip to next byte
\r
338 loop @@ColLoop ; loop if more columns left
\r
339 add di,[LineInc] ; Move to next row
\r
340 dec bl ; decrement row counter
\r
341 jnz @@RowLoop ; Jump if more rows left
\r
342 pop si ; Restore SI and set to offset of
\r
343 add si,[PlaneInc] ; first vis pixel in next plane data
\r
344 pop di ; Restore bitmaps start dest byte
\r
345 rol ah,1 ; Shift mask for next plane
\r
346 adc di,0 ; if carry increment screen offset
\r
347 dec bh ; Decrement plane counter
\r
348 jnz @@PlaneLoop ; Jump if more planes left
\r
351 pop ds ; restore data segment
\r
352 pop di ; restore registers
\r
354 mov sp,bp ; dealloc local variables
\r
357 _x_put_masked_pbm_clipy endp
\r
359 ;----------------------------------------------------------------------
\r
360 ; x_put_masked_pbm_clipxy - Write a planar bitmap from system ram to video
\r
361 ; RAM with clipping in x and y directions. similar to
\r
362 ; "x_put_masked_pbm".
\r
364 ; See Also: x_put_masked_pbm, x_put_masked_pbm_clipx, x_put_masked_pbm_clipxy
\r
366 ; Clipping region variables: LeftClip,RightClip,TopClip,BottomClip
\r
369 ; Written by Themie Gouthas
\r
370 ;----------------------------------------------------------------------
\r
371 _x_put_masked_pbm_clipxy proc
\r
372 ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
\r
373 LOCAL Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk
\r
376 sub sp,LocalStk ; Create space for local variables
\r
386 mov al,byte ptr es:[si] ; AX = width
\r
388 mov bl,byte ptr es:[si+1] ; BX = height
\r
390 mov cx,ax ; Save AX
\r
391 mul bx ; AX = AX*BX = bytes/plane
\r
392 mov [PlaneInc],ax ; save as PlaneInc
\r
393 mov ax,cx ; Restore AX
\r
396 mov di,[X] ; DI = X coordinate of dest.
\r
397 mov cx,di ; save in CX
\r
398 sar di,2 ; convert to address byte
\r
401 ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;
\r
403 mov dx,[_TopClip] ; Compare u.l. Y coord with Top
\r
404 sub dx,[Y] ; clipping border
\r
405 jle @@NotTopClip ; jump if VBM not clipped from above
\r
407 jnl @@NotVisible ; jump if VBM is completely obscured
\r
411 jmp short @@VertClipDone
\r
413 ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;
\r
417 pop ds ; restore data segment
\r
418 pop di ; restore registers
\r
420 mov sp,bp ; dealloc local variables
\r
424 ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;
\r
427 mov dx,[_BottomClip]
\r
438 ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
\r
451 jmp short @@HorizClipDone
\r
453 ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
\r
456 mov dx,[_RightClip]
\r
462 jge @@HorizClipDone ; was jg
\r
475 mov [Width],ax ; Save width and height of clipped
\r
476 mov [Height],bx ; image
\r
478 add ax,[DataInc] ; AX = original width of image
\r
479 mul [TopRow] ; Calculate bytes in clipped top
\r
481 add si,2 ; Skip dimension bytes in source
\r
482 add si,[LeftSkip] ; Skip pixels in front of row that
\r
485 mov bx,[_ScrnLogicalByteWidth] ; Set BX to Logical Screen Width
\r
486 mov dx,bx ; BX - Width of image = No. bytes
\r
487 sub dx,[Width] ; to first byte of next screen
\r
488 mov [LineInc],dx ; row.
\r
490 mov ax,[Y] ; Calculate screen start row
\r
491 mul bx ; then adding screen offset
\r
494 mov ax,es ; copy ES to DS
\r
496 mov ax,SCREEN_SEG ; Point ES to VGA segment
\r
502 mov ah,11h ; Set up initial plane mask
\r
505 mov dx,SC_INDEX ; Prepare VGA for cpu to video writes
\r
509 mov [Plane],4 ; Set plane counter to 4
\r
510 mov bh,byte ptr [Width] ; set bh to width for fast looping
\r
512 push di ; Save bitmap's start dest. offset
\r
514 mov bl,byte ptr [Height] ; Reset row counter (BL)
\r
516 out dx,al ; set vga write plane
\r
518 mov cl,bh ; Reset Column counter cl
\r
521 lodsb ; Get next source bitmap byte
\r
522 or al,al ; If not zero then write to dest.
\r
523 jz @@NoPixel ; otherwise skip to next byte
\r
529 add si,[DataInc] ; Move to next source row
\r
530 add di,[LineInc] ; Move to next screen row
\r
531 dec bl ; decrement row counter
\r
532 jnz @@RowLoop ; Jump if more rows left
\r
533 pop si ; Restore SI and set to offset of
\r
534 add si,[PlaneInc] ; first vis pixel in next plane data
\r
535 pop di ; Restore bitmaps start dest byte
\r
536 rol ah,1 ; Shift mask for next plane
\r
538 ; Plane Transition (A HACK but it works!)
\r
540 jnb @@Nocarry ; Jump if not plane transition
\r
541 mov bl,ah ; Save Plane Mask
\r
542 mov ax,[CType] ; set AX to clip type inc variable
\r
543 add bh,al ; Update advancing variables
\r
546 cmp al,0 ; What type of clip do we have
\r
547 mov ah,bl ; restore Plane mask
\r
548 jg @@RightAdvance ; jump on a right clip!
\r
549 inc di ; otherwise increment DI
\r
554 dec [Plane] ; Decrement plane counter
\r
555 jnz @@PlaneLoop ; Jump if more planes left
\r
558 pop ds ; restore data segment
\r
559 pop di ; restore registers
\r
561 mov sp,bp ; dealloc local variables
\r
564 _x_put_masked_pbm_clipxy endp
\r
569 ;----------------------------------------------------------------------
\r
570 ; x_put_pbm_clipx - Write a planar bitmap from system ram to video ram
\r
571 ; with clipping in x and y directions. similar to
\r
574 ; See Also: x_put_pbm_clip
\r
577 ; See Also: x_put_pbm,x_put_pbm_clipy,x_put_pbm_clipxy
\r
579 ; Clipping region variables: LeftClip,RightClip
\r
581 ; Written by Themie Gouthas
\r
583 ; This code is a SLOW hack, any better ideas are welcome
\r
584 ;----------------------------------------------------------------------
\r
585 _x_put_pbm_clipx proc
\r
586 ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
\r
587 LOCAL Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc:word=LocalStk
\r
590 sub sp,LocalStk ; Create space for local variables
\r
600 mov al,byte ptr es:[si] ; AX = width
\r
603 mov di,[X] ; DI = X coordinate of dest.
\r
604 mov cx,di ; save in CX
\r
605 sar di,2 ; convert to address byte
\r
609 ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
\r
622 jmp short @@HorizClipDone
\r
624 ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;
\r
628 pop ds ; restore data segment
\r
629 pop di ; restore registers
\r
631 mov sp,bp ; dealloc local variables
\r
635 ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
\r
638 mov dx,[_RightClip]
\r
644 jge @@HorizClipDone ; was jg
\r
654 mov bl,byte ptr es:[si+1] ; BX = height
\r
656 mov [Width],ax ; Save width and height of clipped
\r
657 mov [Height],bx ; image
\r
660 add si,2 ; Skip dimension bytes in source
\r
661 add si,[LeftSkip] ; Skip pixels in front of row that
\r
665 mov bx,[_ScrnLogicalByteWidth] ; Set BX to Logical Screen Width
\r
666 mov dx,bx ; BX - Width of image = No. bytes
\r
667 sub dx,ax ; to first byte of next screen
\r
668 mov [LineInc],dx ; row.
\r
670 mov ax,[Y] ; Calculate screen start row
\r
671 mul bx ; then adding screen offset
\r
674 mov ax,es ; copy ES to DS
\r
676 mov ax,SCREEN_SEG ; Point ES to VGA segment
\r
680 mov ah,11h ; Set up initial plane mask
\r
683 mov dx,SC_INDEX ; Prepare VGA for cpu to video writes
\r
687 mov [Plane],4 ; Set plane counter to 4
\r
688 mov bh,byte ptr [Width] ; set bh to width for fast looping
\r
690 push di ; Save bitmap's start dest. offset
\r
691 mov bl,byte ptr [Height] ; Reset row counter (BL)
\r
693 out dx,al ; set vga write plane
\r
695 mov cl,bh ; Reset Column counter cl
\r
697 rep movsw ; Copy a complete row
\r
700 add si,[DataInc] ; Move to next source row
\r
701 add di,[LineInc] ; Move to next screen row
\r
702 dec bl ; decrement row counter
\r
703 jnz @@RowLoop ; Jump if more rows left
\r
704 pop di ; Restore bitmaps start dest byte
\r
705 rol ah,1 ; Shift mask for next plane
\r
707 ; Plane Transition (A HACK but it works!)
\r
709 jnb @@Nocarry ; Jump if not plane transition
\r
710 mov bl,ah ; Save Plane Mask
\r
711 mov ax,[CType] ; set AX to clip type inc variable
\r
712 add bh,al ; Update advancing variables
\r
715 cmp al,0 ; What type of clip do we have
\r
716 mov ah,bl ; restore Plane mask
\r
717 jg @@RightAdvance ; jump on a right clip!
\r
718 inc di ; otherwise increment DI
\r
723 dec [Plane] ; Decrement plane counter
\r
724 jnz @@PlaneLoop ; Jump if more planes left
\r
727 pop ds ; restore data segment
\r
728 pop di ; restore registers
\r
730 mov sp,bp ; dealloc local variables
\r
733 _x_put_pbm_clipx endp
\r
737 ;----------------------------------------------------------------------
\r
738 ; x_put_pbm_clipy - Write a planar bitmap from system ram to video ram
\r
739 ; with clipping in y direction only. similar to
\r
742 ; See Also: x_put_pbm,x_put_pbm_clipx,x_put_pbm_clipxy
\r
744 ; Clipping region variables: TopClip,BottomClip
\r
746 ; Written by Themie Gouthas
\r
747 ;----------------------------------------------------------------------
\r
748 _x_put_pbm_clipy proc
\r
749 ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
\r
750 LOCAL Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk
\r
753 sub sp,LocalStk ; Create space for local variables
\r
762 mov bl,byte ptr es:[si+1] ; BX = height
\r
766 mov al,byte ptr es:[si] ; AX = width
\r
769 mov cx,ax ; Save AX
\r
770 mul bx ; AX = AX*BX = bytes/plane
\r
771 mov [PlaneInc],ax ; save as PlaneInc
\r
772 mov ax,cx ; Restore AX
\r
779 ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;
\r
781 mov dx,[_TopClip] ; Compare u.l. Y coord with Top
\r
782 sub dx,[Y] ; clipping border
\r
783 jle @@NotTopClip ; jump if VBM not clipped from above
\r
785 jnl @@NotVisible ; jump if VBM is completely obscured
\r
789 jmp short @@VertClipDone
\r
791 ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;
\r
795 pop ds ; restore data segment
\r
796 pop di ; restore registers
\r
798 mov sp,bp ; dealloc local variables
\r
802 ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;
\r
805 mov dx,[_BottomClip]
\r
816 mov [Height],bx ; Calculate relative offset in data
\r
817 mul [TopRow] ; of first visible scanline
\r
818 add ax,2 ; Skip dimension bytes in source
\r
819 add si,ax ; Skip top rows that arent visible
\r
822 mov ax,[Y] ; Calculate screen row
\r
823 mov bx,[_ScrnLogicalByteWidth] ; by mult. Y coord by Screen
\r
824 mul bx ; width then adding screen offset
\r
827 sub bx,[Width] ; calculate difference from end of
\r
828 mov [LineInc],bx ; b.m. in curr line to beginning of
\r
829 ; b.m. on next scan line
\r
830 mov ax,es ; copy ES to DS
\r
832 mov ax,SCREEN_SEG ; Point ES to VGA segment
\r
835 mov ah,11h ; Set up initial plane mask
\r
838 mov dx,SC_INDEX ; Prepare VGA for cpu to video writes
\r
842 mov bh,4 ; Set plane counter to 4
\r
844 push di ; Save bitmap's start dest. offset
\r
845 push si ; Save Bitmaps data offset
\r
846 mov bl,byte ptr [Height] ; Reset row counter (BL)
\r
848 out dx,al ; set vga write plane
\r
850 mov cl,byte ptr [Width] ; Reset Column counter cl
\r
852 rep movsw ; Copy a complete row
\r
856 add di,[LineInc] ; Move to next row
\r
857 dec bl ; decrement row counter
\r
858 jnz @@RowLoop ; Jump if more rows left
\r
859 pop si ; Restore SI and set to offset of
\r
860 add si,[PlaneInc] ; first vis pixel in next plane data
\r
861 pop di ; Restore bitmaps start dest byte
\r
862 rol ah,1 ; Shift mask for next plane
\r
863 adc di,0 ; if carry increment screen offset
\r
864 dec bh ; Decrement plane counter
\r
865 jnz @@PlaneLoop ; Jump if more planes left
\r
868 pop ds ; restore data segment
\r
869 pop di ; restore registers
\r
871 mov sp,bp ; dealloc local variables
\r
874 _x_put_pbm_clipy endp
\r
877 ;----------------------------------------------------------------------
\r
878 ; x_put_pbm_clipxy - Write a planar bitmap from system ram to video ram
\r
879 ; with clipping in x and y directions. similar to
\r
882 ; See Also: x_put_pbm,x_put_pbm_clipy,x_put_pbm_clipx
\r
884 ; Clipping region variables: LeftClip,RightClip,TopClip,BottomClip
\r
886 ; Written by Themie Gouthas
\r
887 ;----------------------------------------------------------------------
\r
888 _x_put_pbm_clipxy proc
\r
889 ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
\r
890 LOCAL Plane:byte,CType,LeftSkip,DataInc,Width,Height,TopRow,LineInc,PlaneInc:word=LocalStk
\r
893 sub sp,LocalStk ; Create space for local variables
\r
903 mov al,byte ptr es:[si] ; AX = width
\r
905 mov bl,byte ptr es:[si+1] ; BX = height
\r
907 mov cx,ax ; Save AX
\r
908 mul bx ; AX = AX*BX = bytes/plane
\r
909 mov [PlaneInc],ax ; save as PlaneInc
\r
910 mov ax,cx ; Restore AX
\r
913 mov di,[X] ; DI = X coordinate of dest.
\r
914 mov cx,di ; save in CX
\r
915 sar di,2 ; convert to address byte
\r
918 ;;;;; CLIP PROCESSING FOR TOP CLIP BORDER ;;;;;;;;;;;;;;;;;;;;;
\r
920 mov dx,[_TopClip] ; Compare u.l. Y coord with Top
\r
921 sub dx,[Y] ; clipping border
\r
922 jle @@NotTopClip ; jump if VBM not clipped from above
\r
924 jnl @@NotVisible ; jump if VBM is completely obscured
\r
928 jmp short @@VertClipDone
\r
930 ;;;; EXIT FOR COMPLETELY OBSCURED P.B.M's ;;;;;;;;;;;;;;;;;;;;;;
\r
934 pop ds ; restore data segment
\r
935 pop di ; restore registers
\r
937 mov sp,bp ; dealloc local variables
\r
941 ;;;;; CLIP PROCESSING FOR BOTTOM CLIP BORDER ;;;;;;;;;;;;;;;;;;;
\r
944 mov dx,[_BottomClip]
\r
955 ;;;;; CLIP PROCESSING FOR LEFT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
\r
968 jmp short @@HorizClipDone
\r
970 ;;;;; CLIP PROCESSING FOR RIGHT CLIP BORDER ;;;;;;;;;;;;;;;;;;;
\r
973 mov dx,[_RightClip]
\r
979 jge @@HorizClipDone ; was jg
\r
990 mov [Width],ax ; Save width and height of clipped
\r
991 mov [Height],bx ; image
\r
993 add ax,[DataInc] ; AX = original width of image
\r
994 mul [TopRow] ; Calculate bytes in clipped top
\r
996 add si,2 ; Skip dimension bytes in source
\r
997 add si,[LeftSkip] ; Skip pixels in front of row that
\r
1000 mov bx,[_ScrnLogicalByteWidth] ; Set BX to Logical Screen Width
\r
1001 mov dx,bx ; BX - Width of image = No. bytes
\r
1002 sub dx,[Width] ; to first byte of next screen
\r
1003 mov [LineInc],dx ; row.
\r
1005 mov ax,[Y] ; Calculate screen start row
\r
1006 mul bx ; then adding screen offset
\r
1009 mov ax,es ; copy ES to DS
\r
1011 mov ax,SCREEN_SEG ; Point ES to VGA segment
\r
1017 mov ah,11h ; Set up initial plane mask
\r
1020 mov dx,SC_INDEX ; Prepare VGA for cpu to video writes
\r
1024 mov [Plane],4 ; Set plane counter to 4
\r
1025 mov bh,byte ptr [Width] ; set bh to width for fast looping
\r
1027 push di ; Save bitmap's start dest. offset
\r
1029 mov bl,byte ptr [Height] ; Reset row counter (BL)
\r
1031 out dx,al ; set vga write plane
\r
1033 mov cl,bh ; Reset Column counter cl
\r
1035 rep movsw ; Copy a complete row
\r
1038 add si,[DataInc] ; Move to next source row
\r
1039 add di,[LineInc] ; Move to next screen row
\r
1040 dec bl ; decrement row counter
\r
1041 jnz @@RowLoop ; Jump if more rows left
\r
1042 pop si ; Restore SI and set to offset of
\r
1043 add si,[PlaneInc] ; first vis pixel in next plane data
\r
1044 pop di ; Restore bitmaps start dest byte
\r
1045 rol ah,1 ; Shift mask for next plane
\r
1047 ; Plane Transition (A HACK but it works!)
\r
1049 jnb @@Nocarry ; Jump if not plane transition
\r
1050 mov bl,ah ; Save Plane Mask
\r
1051 mov ax,[CType] ; set AX to clip type inc variable
\r
1052 add bh,al ; Update advancing variables
\r
1053 sub [DataInc],ax ;
\r
1054 sub [LineInc],ax ;
\r
1055 cmp al,0 ; What type of clip do we have
\r
1056 mov ah,bl ; restore Plane mask
\r
1057 jg @@RightAdvance ; jump on a right clip!
\r
1058 inc di ; otherwise increment DI
\r
1063 dec [Plane] ; Decrement plane counter
\r
1064 jnz @@PlaneLoop ; Jump if more planes left
\r
1067 pop ds ; restore data segment
\r
1068 pop di ; restore registers
\r
1070 mov sp,bp ; dealloc local variables
\r
1073 _x_put_pbm_clipxy endp
\r