home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 21
/
CD_ASCQ_21_040595.iso
/
dos
/
prg
/
c
/
xlib612
/
source
/
xpbitmap.asm
< prev
next >
Wrap
Assembly Source File
|
1994-07-15
|
25KB
|
603 lines
;-----------------------------------------------------------------------
; 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_flip_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
; If "Orientation" is set then the bitmap is flipped from left to right as
; it is drawn
;
; 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_flip_masked_pbm(X,Y,ScrnOffs,char far * Bitmap, Orientation)
;
;
; LIMITATIONS: No clipping is supported
; Only supports bitmaps with widths which are a multiple of
; 4 pixels
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
_x_flip_masked_pbm proc
ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword,Orientation:word
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
cmp Orientation,0
jz UnFlippedMasked
mov [BMHeight],ah ; Save source bitmap dimensions
xor ah,ah ; LineInc = bytes to the begin.
add 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:
dec 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
ror ah,1 ; Shift mask for next plane
sbb 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_flip_masked_pbm endp
;----------------------------------------------------------------------
; 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
UnFlippedMasked:
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
UnFlipped:
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_flip_pbm - Write a planar bitmap from system ram to video ram
; If "Orientation" is set then the bitmap is flipped from left to right as
; it is drawn
;
; 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_flip_pbm(X,Y,ScrnOffs,char far * Bitmap, WORD orientation)
;
;
; LIMITATIONS: No clipping is supported
; Only supports bitmaps with widths which are a multiple of
; 4 pixels
;
; NOTES: The flipped put function is slower than the standard put function
;
; Written by Themie Gouthas
;----------------------------------------------------------------------
_x_flip_pbm proc
ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword,Orientation:word
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
cmp Orientation,0
jz UnFlipped
mov [BMHeight],ah ; Save source bitmap dimensions
xor ah,ah ; LineInc = bytes to the begin.
add 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
mov es:[di],al
dec di
sub di,2
loop @@ColLoop ; loop if more columns left
@@DoneCol:
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
ror ah,1 ; Shift mask for next plane
sbb 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_flip_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
ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword,Orientation:word
LOCAL Plane:byte,BMHeight:byte,LineInc:word,Columns:byte=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
cmp Orientation,0
jz UnFlipped
mov [BMHeight],ah ; Save source bitmap dimensions
xor ah,ah ; LineInc = bytes to the begin.
add bx,ax ; of bitmaps next row on screen
mov [LineInc],bx
mov [Columns],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 bh,ah
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,bh
out dx,al ; set vga write plane
@@RowLoop:
mov cl,[Columns] ; Reset Column counter cl
shr cx,1
jnc @@ColLoop
lodsb
mov es:[di],al
dec di
@@ColLoop:
lodsw ; Get next source bitmap byte
xchg al,ah
mov es:[di],ax
sub di,2
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
ror bh,1 ; Shift mask for next plane
sbb 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