home *** CD-ROM | disk | FTP | other *** search
- ;-----------------------------------------------------------------------
- ; MODULE XPBITMAP
- ;
- ; Planar Bitmap functions - System Ram <-> Video Ram
- ;
- ; Compile with Tasm.
- ; C callable.
- ;
- ;
- ; ****** XLIB - Mode X graphics library ****************
- ; ****** ****************
- ; ****** Written By Themie Gouthas ****************
- ;
- ; egg@dstos3.dsto.gov.au
- ; teg@bart.dsto.gov.au
- ;-----------------------------------------------------------------------
-
-
- COMMENT $
-
- This module implements a set of functions to operate on planar bitmaps.
- Planar bitmaps as used by these functions have the following structure:
-
- BYTE 0 The bitmap width in bytes (4 pixel groups) range 1..255
- BYTE 1 The bitmap height in rows range 1..255
- BYTE 2..n1 The plane 0 pixels width*height bytes
- BYTE n1..n2 The plane 1 pixels width*height bytes
- BYTE n2..n3 The plane 2 pixels width*height bytes
- BYTE n3..n4 The plane 3 pixels width*height bytes
-
- These functions provide the fastest possible bitmap blts from system ram to
- to video and further, the single bitmap is applicable to all pixel
- allignments. The masked functions do not need separate masks since all non
- zero pixels are considered to be masking pixels, hence if a pixel is 0 the
- corresponding screen destination pixel is left unchanged.
-
-
- $
-
- include xlib.inc
- include xpbitmap.inc
- LOCALS
- .code
-
- ;----------------------------------------------------------------------
- ; x_put_masked_pbm - mask write a planar bitmap from system ram to video ram
- ; all zero source bitmap bytes indicate destination byte to be left unchanged
- ;
- ; Source Bitmap structure:
- ;
- ; Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
- ; Bitmap data (plane 2)..,Bitmap data (plane 3)..
- ;
- ; note width is in bytes ie lots of 4 pixels
- ;
- ; x_put_masked_pbm(X,Y,ScrnOffs,char far * Bitmap)
- ;
- ;
- ; LIMITATIONS: No clipping is supported
- ; Only supports bitmaps with widths which are a multiple of
- ; 4 pixels
- ;
- ; Written by Themie Gouthas
- ;----------------------------------------------------------------------
- _x_put_masked_pbm proc
- ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
- LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk
- push bp
- mov bp,sp
- sub sp,LocalStk ; Create space for local variables
- push si
- push di
- push ds
- cld
- mov ax,SCREEN_SEG
- mov es,ax
- mov ax,[Y] ; Calculate dest screen row
- mov bx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen
- mul bx ; width then adding screen offset
- mov di,[ScrnOffs] ; store result in DI
- add di,ax
- mov cx,[X] ; Load X coord into CX and make a
- mov dx,cx ; copy in DX
- shr dx,2 ; Find starting byte in dest row
- add di,dx ; add to DI giving screen offset of
- ; first pixel's byte
- lds si,[Bitmap] ; DS:SI -> Bitmap data
- lodsw ; Al = B.M. width (bytes) AH = B.M.
- ; height
- mov [BMHeight],ah ; Save source bitmap dimensions
- xor ah,ah ; LineInc = bytes to the begin.
- sub bx,ax ; of bitmaps next row on screen
- mov [LineInc],bx
- mov bh,al ; Use bh as column loop count
- and cx,0003h ; mask X coord giving plane of 1st
- ; bitmap pixel(zero CH coincidentally)
- mov ah,11h ; Init. mask for VGA plane selection
- shl ah,cl ; Shift for starting pixel plane
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes
- mov al,MAP_MASK
- out dx,al
- inc dx
- mov [Plane],4 ; Set plane counter to 4
- @@PlaneLoop:
- push di ; Save bitmap's start dest. offset
- mov bl,[BMHeight] ; Reset row counter (BL)
- mov al,ah
- out dx,al ; set vga write plane
- @@RowLoop:
- mov cl,bh ; Reset Column counter cl
- @@ColLoop:
- lodsb ; Get next source bitmap byte
- or al,al ; If not zero then write to dest.
- jz @@NoPixel ; otherwise skip to next byte
- mov es:[di],al
- @@NoPixel:
- inc di
- loop @@ColLoop ; loop if more columns left
- add di,[LineInc] ; Move to next row
- dec bl ; decrement row counter
- jnz @@RowLoop ; Jump if more rows left
- pop di ; Restore bitmaps start dest byte
- rol ah,1 ; Shift mask for next plane
- adc di,0 ; If wrapped increment dest address
- dec [Plane] ; Decrement plane counter
- jnz @@PlaneLoop ; Jump if more planes left
-
- pop ds ; restore data segment
- pop di ; restore registers
- pop si
- mov sp,bp ; dealloc local variables
- pop bp
- ret
- _x_put_masked_pbm endp
-
-
- ;----------------------------------------------------------------------
- ; x_put_pbm - Write a planar bitmap from system ram to video ram
- ;
- ; Source Bitmap structure:
- ;
- ; Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
- ; Bitmap data (plane 2)..,Bitmap data (plane 3)..
- ;
- ; note width is in bytes ie lots of 4 pixels
- ;
- ; x_put_pbm(X,Y,ScrnOffs,char far * Bitmap)
- ;
- ;
- ; LIMITATIONS: No clipping is supported
- ; Only supports bitmaps with widths which are a multiple of
- ; 4 pixels
- ; FEATURES : Automatically selects REP MOVSB or REP MOVSW depending on
- ; source bitmap width, by modifying opcode ;-).
- ;
- ; Written by Themie Gouthas
- ;----------------------------------------------------------------------
- _x_put_pbm proc
- ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
- LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk
- push bp
- mov bp,sp
- sub sp,LocalStk ; Create space for local variables
- push si
- push di
- push ds
- cld
- mov ax,SCREEN_SEG
- mov es,ax
- mov ax,[Y] ; Calculate dest screen row
- mov bx,[_ScrnLogicalByteWidth] ; by mult. dest Y coord by Screen
- mul bx ; width then adding screen offset
- mov di,[ScrnOffs] ; store result in DI
- add di,ax
- mov cx,[X] ; Load X coord into CX and make a
- mov dx,cx ; copy in DX
- shr dx,2 ; Find starting byte in dest row
- add di,dx ; add to DI giving screen offset of
- ; first pixel's byte
- lds si,[Bitmap] ; DS:SI -> Bitmap data
- lodsw ; Al = B.M. width (bytes) AH = B.M.
- ; height
- mov [BMHeight],ah ; Save source bitmap dimensions
- xor ah,ah ; LineInc = bytes to the begin.
- sub bx,ax ; of bitmaps next row on screen
- mov [LineInc],bx
- mov bh,al
- ; Self Modifying, Shame, shame shame..
- and cx,0003h ; mask X coord giving plane of 1st
- ; bitmap pixel(zero CH coincidentally)
- mov ah,11h ; Init. mask for VGA plane selection
- shl ah,cl ; Shift for starting pixel plane
- mov dx,SC_INDEX ; Prepare VGA for cpu to video writes
- mov al,MAP_MASK
- out dx,al
- inc dx
- mov [Plane],4 ; Set plane counter to 4
- @@PlaneLoop:
- push di
- mov bl,[BMHeight]
- mov al,ah
- out dx,al
- @@RowLoop:
- mov cl,bh
- shr cl,1
- rep movsw ; Copy a complete row for curr plane
- adc cl,0
- rep movsb
- add di,[LineInc] ; Move to next row
- dec bl ; decrement row counter
- jnz @@RowLoop ; Jump if more rows left
- pop di ; Restore bitmaps start dest byte
- rol ah,1 ; Shift mask for next plane
- adc di,0 ; If wrapped increment dest address
- dec [Plane] ; Decrement plane counter
- jnz @@PlaneLoop ; Jump if more planes left
-
- pop ds ; restore data segment
- pop di ; restore registers
- pop si
- mov sp,bp ; dealloc local variables
- pop bp
- ret
- _x_put_pbm endp
-
- ;----------------------------------------------------------------------
- ; x_get_pbm - Read a planar bitmap to system ram from video ram
- ;
- ; Source Bitmap structure:
- ;
- ; Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
- ; Bitmap data (plane 2)..,Bitmap data (plane 3)..
- ;
- ; note width is in bytes ie lots of 4 pixels
- ;
- ; x_get_pbm(X,Y,BMwidth,BMheight,ScrnOffs,char far * Bitmap)
- ;
- ;
- ; LIMITATIONS: No clipping is supported
- ; Only supports bitmaps with widths which are a multiple of
- ; 4 pixels
- ; FEATURES : Automatically selects REP MOVSB or REP MOVSW depending on
- ; source bitmap width, by modifying opcode ;-).
- ;
- ; Written by Themie Gouthas
- ;----------------------------------------------------------------------
- _x_get_pbm proc
- ARG X:word,Y:word,SrcWidth:byte,SrcHeight:byte,ScrnOffs:word,Bitmap:dword
- LOCAL Plane:byte,LineInc:word=LocalStk
- push bp
- mov bp,sp
- sub sp,LocalStk ; Create space for local variables
- push si
- push di
- push ds
- cld
-
- mov ax,[Y] ; Calculate screen row
- mov bx,[_ScrnLogicalByteWidth] ; by mult. Y coord by Screen
- mul bx ; width then adding screen offset
- mov si,[ScrnOffs] ; store result in SI
- add si,ax
- mov cx,[X] ; Load X coord into CX and make a
- mov dx,cx ; copy in DX
- shr dx,2 ; Find starting byte in screen row
- add si,dx ; add to SI giving screen offset of
- ; first pixel's byte
- mov ax,SCREEN_SEG
- mov ds,ax
- les di,[Bitmap] ; ES:DI -> Bitmap data
- mov al,[SrcWidth]
- mov ah,[SrcHeight]
- stosw ; Al = B.M. width (bytes) AH = B.M.
- ; height
- xor ah,ah ; LineInc = bytes to the begin.
- sub bx,ax ; of bitmaps next row on screen
- mov [LineInc],bx
- mov bh,al
- ; Self Modifying, Shame, shame shame..
- and cx,0003h ; mask X coord giving plane of 1st
- ; bitmap pixel(zero CH coincidentally)
- mov ah,11h ; Init. mask for VGA plane selection
- shl ah,cl ; Shift for starting pixel plane
- mov dx,GC_INDEX ; Prepare VGA for cpu to video reads
- mov al,READ_MAP
- out dx,al
- inc dx
- mov [Plane],4 ; Set plane counter (BH) to 4
- mov al,cl
- @@PlaneLoop:
- push si
- mov bl,[SrcHeight]
- out dx,al
- @@RowLoop:
- mov cl,bh
- shr cl,1
- rep movsw ; Copy a complete row for curr plane
- adc cl,0
- rep movsb
- add si,[LineInc] ; Move to next row
- dec bl ; decrement row counter
- jnz @@RowLoop ; Jump if more rows left
- pop si ; Restore bitmaps start dest byte
-
- inc al ; Select next plane to read from
- and al,3 ;
-
- rol ah,1 ; Shift mask for next plane
- adc si,0 ; If wrapped increment dest address
- dec [Plane] ; Decrement plane counter
- jnz @@PlaneLoop ; Jump if more planes left
-
- pop ds ; restore data segment
- pop di ; restore registers
- pop si
- mov sp,bp ; dealloc local variables
- pop bp
- ret
- _x_get_pbm endp
-
-
-
-
- end
-
-
-