home *** CD-ROM | disk | FTP | other *** search
- ;************************ BLT.ASM ****************************************
- ; BLock Transfer functions. These routines provide basic block transfer
- ; functions at a byte (really word) level. They are optimised to do word
- ; aligned 16 bit transfers to the destination to take any advantage
- ; possible performance increase a 16 bit bus might give (if it is
- ; available). This should not affect 8 bit adapters and buses
- ; significantly.
- ; Note that the word alignment is on the destination of the transfer
- ; operation. This is based on the assumption that the video adapter will
- ; usually be the destination rather than the source and since there are
- ; (almost always) more wait states for accessing the video memory there is
- ; a greater penalty for misaligned access to it.
- ;
- ; V 1.00 17/04/90 R. Adsett Original
- ; V 1.01 23/04/90 R. Adsett Remove header dependancies
- ; V 1.02 15/06/90 R. Adsett Eliminate DOSSEG ordering.
- ;
- ; (C) Robert Adsett 1989, 1990
- ;*************************************************************************
-
- ideal
- model tiny
-
- codeseg
-
- public _copy_mem ;Copy using a wrap on the source.
- public _xor_mem ;Xor the source with the destination using
- ; a wrap on the source.
- public _or_mem ;Or the source with the destination using
- ; a wrap on the source.
- public _and_mem ;And the source with the destination using
- ; a wrap on the source.
- public _neg_mem ;Copy the negated source using a wrap on
- ; the source.
- public _set_mem ;Set area to this value. Note that it
- ; treats 0 as 64K!!!!
-
- ;********************** COPY_MEM *****************************************
- ; Copy source to destination, wrapping the source as necessary to fill
- ; the destination.
- ; Prototype:
- ; void copy_mem(
- ; void far *source, /* Source image. */
- ; unsigned src_size, /* Number of bytes in source. */
- ; void far *destination, /* Destination image. */
- ; unsigned dest_size /* Number of bytes in the */
- ; /* destination. */
- ; );
- ;*************************************************************************
-
- proc _copy_mem
- arg source:dword, src_size:word, destination:dword, dest_size:word
-
-
- push bp
- mov bp,sp ;Standard entry.
-
- push ds ;We're using all of these so save
- push si ; them.
- push di
-
- cld ;Let's go forward.
- les di, [destination] ;Load destination address.
- mov ax, [src_size] ;Load size of source.
- mov bx, [dest_size] ;Load size of destination.
-
- copy_loop_top: ;Top of copy loop.
- lds si, [source] ;Load source address.
- cmp ax, bx ;Compare source and destination
- ; sizes.
- jl small_src ;Is source smaller?
-
- mov cx, bx ;Destination is smaller, copy
- ; only that many bytes.
- jmp copy
-
- small_src:
- mov cx, ax ;Copy all of the source.
-
- copy:
- test di, 1 ;Is destination on a word
- ; boundary?
- jz copy_word ;Yes.
-
- movsb ;Let's get aligned. Copy a single
- ; byte.
- dec cx ;One less in loop.
- dec bx ;One less in total to copy.
-
- copy_word: ;Word aligned copy.
- mov dx, cx ;Save copy of loop variable so we
- ; can check for trailing bytes.
- shr cx, 1 ;How many words?
- rep movsw ;Copy away.
-
- test dx, 1 ;One last byte to copy?
- jz loop_end_test ;Nope.
-
- movsb ;Copy last byte.
-
- loop_end_test:
- sub bx, dx ;Copied all these bytes.
- cmp bx, 0 ;Is that all?
- jne copy_loop_top ;Nope, restart at source's
- ; beginning.
-
- pop di ;Restore important registers.
- pop si
- pop ds
-
- pop bp ;Standard exit.
- ret
- endp
-
- ;*********************** XOR_MEM *****************************************
- ; Xor the source with the destination, wrapping the source as necessary
- ; to fill the destination.
- ; Prototype:
- ; void xor_mem(
- ; void far *source, /* Source image. */
- ; unsigned src_size, /* Number of bytes in source. */
- ; void far *destination, /* Destination image. */
- ; unsigned dest_size /* Number of bytes in the */
- ; /* destination. */
- ; );
- ;*************************************************************************
-
- proc _xor_mem
- arg source:dword, src_size:word, destination:dword, dest_size:word
-
-
- push bp
- mov bp,sp ;Standard entry.
-
- push ds ;We're using all of these so save
- push si ; them.
- push di
-
- cld ;Let's go forward.
- les di, [destination] ;Load destination address.
- mov bx, [dest_size] ;Load size of destination.
-
- cp_xor_loop_top: ;Top of xor loop.
- mov ax, [src_size] ;Load size of source. This
- ; register gets reused.
- lds si, [source] ;Load source address.
- cmp ax, bx ;Compare source and destination
- ; sizes.
- jl cp_xor_small_src ;Is source smaller?
-
- mov cx, bx ;Destination is smaller, xor
- ; only that many bytes.
- jmp cp_xor
-
- cp_xor_small_src:
- mov cx, ax ;Xor all of the source.
-
- cp_xor:
- test di, 1 ;Is destination on a word
- ; boundary?
- jz cp_xor_word ;Yes.
-
- ;Let's get aligned. Xor a single byte.
-
- mov al, [byte ptr ds:si] ;Read single byte of source.
- xor [byte ptr es:di], al ;Xor into destination.
- inc si ;Next source byte.
- inc di ;Next destination byte.
- dec cx ;One less in loop.
- dec bx ;One less in total to xor.
-
- cp_xor_word: ;Word aligned xor.
- mov dx, cx ;Save copy of loop variable so we
- ; can check for trailing bytes.
- shr cx, 1 ;How many words?
-
- xor_loop: ;Xor away.
- mov ax, [word ptr ds:si] ;Read source word.
- xor [word ptr es:di], ax ;Xor into destination.
- inc si ;Next source word.
- inc si
- inc di ;Next destination word.
- inc di
- loop xor_loop ;Next word.
-
- test dx, 1 ;One last byte to xor.
- jz cp_xor_loop_end_test ;Nope.
-
- mov al, [byte ptr ds:si] ;Load and xor last byte.
- xor [byte ptr es:di], al
- inc si
- inc di
-
- cp_xor_loop_end_test:
- sub bx, dx ;Xor'd all these bytes.
- cmp bx, 0 ;Is that all?
- jne cp_xor_loop_top ;Nope, restart at source's
- ; beginning.
-
- pop di ;Restore important registers.
- pop si
- pop ds
-
- pop bp ;Standard exit.
- ret
- endp
-
- ;************************ OR_MEM *****************************************
- ; Or the source with the destination, wrapping the source as necessary
- ; to fill the destination.
- ; Prototype:
- ; void or_mem(
- ; void far *source, /* Source image. */
- ; unsigned src_size, /* Number of bytes in source. */
- ; void far *destination, /* Destination image. */
- ; unsigned dest_size /* Number of bytes in the */
- ; /* destination. */
- ; );
- ;*************************************************************************
-
- proc _or_mem
- arg source:dword, src_size:word, destination:dword, dest_size:word
-
-
- push bp
- mov bp,sp ;Standard entry.
-
- push ds ;We're using all of these so save
- push si ; them.
- push di
-
- cld ;Let's go forward.
- les di, [destination] ;Load destination address.
- mov bx, [dest_size] ;Load size of destination.
-
- cp_or_loop_top: ;Top of or loop.
- mov ax, [src_size] ;Load size of source. This
- ; register gets reused.
- lds si, [source] ;Load source address.
- cmp ax, bx ;Compare source and destination
- ; sizes.
- jl cp_or_small_src ;Is source smaller?
-
- mov cx, bx ;Destination is smaller, or
- ; only that many bytes.
- jmp cp_or
-
- cp_or_small_src:
- mov cx, ax ;Or all of the source.
-
- cp_or:
- test di, 1 ;Is destination on a word
- ; boundary?
- jz cp_or_word ;Yes.
-
- ;Let's get aligned. Or a single byte.
-
- mov al, [byte ptr ds:si] ;Read single byte of source.
- or [byte ptr es:di], al ;Or into destination.
- inc si ;Next source byte.
- inc di ;Next destination byte.
- dec cx ;One less in loop.
- dec bx ;One less in total to or.
-
- cp_or_word: ;Word aligned or.
- mov dx, cx ;Save copy of loop variable so we
- ; can check for trailing bytes.
- shr cx, 1 ;How many words?
-
- or_loop: ;Or away.
- mov ax, [word ptr ds:si] ;Read source word.
- or [word ptr es:di], ax ;Or into destination.
- inc si ;Next source word.
- inc si
- inc di ;Next destination word.
- inc di
- loop or_loop ;Next word.
-
- test dx, 1 ;One last byte to or.
- jz cp_or_loop_end_test ;Nope.
-
- mov al, [byte ptr ds:si] ;Load and or last byte.
- or [byte ptr es:di], al
- inc si
- inc di
-
- cp_or_loop_end_test:
- sub bx, dx ;Or'd all these bytes.
- cmp bx, 0 ;Is that all?
- jne cp_or_loop_top ;Nope, restart at source's
- ; beginning.
-
- pop di ;Restore important registers.
- pop si
- pop ds
-
- pop bp ;Standard exit.
- ret
- endp
-
- ;************************ AND_MEM ****************************************
- ; And the source with the destination, wrapping the source as necessary
- ; to fill the destination.
- ; Prototype:
- ; void and_mem(
- ; void far *source, /* Source image. */
- ; unsigned src_size, /* Number of bytes in source. */
- ; void far *destination, /* Destination image. */
- ; unsigned dest_size /* Number of bytes in the */
- ; /* destination. */
- ; );
- ;*************************************************************************
-
- proc _and_mem
- arg source:dword, src_size:word, destination:dword, dest_size:word
-
-
- push bp
- mov bp,sp ;Standard entry.
-
- push ds ;We're using all of these so save
- push si ; them.
- push di
-
- cld ;Let's go forward.
- les di, [destination] ;Load destination address.
- mov bx, [dest_size] ;Load size of destination.
-
- cp_and_loop_top: ;Top of and loop.
- mov ax, [src_size] ;Load size of source. This
- ; register gets reused.
- lds si, [source] ;Load source address.
- cmp ax, bx ;Compare source and destination
- ; sizes.
- jl cp_and_small_src ;Is source smaller?
-
- mov cx, bx ;Destination is smaller, and
- ; only that many bytes.
- jmp cp_and
-
- cp_and_small_src:
- mov cx, ax ;And all of the source.
-
- cp_and:
- test di, 1 ;Is destination on a word
- ; boundary?
- jz cp_and_word ;Yes.
-
- ;Let's get aligned. And a single byte.
-
- mov al, [byte ptr ds:si] ;Read single byte of source.
- and [byte ptr es:di], al ;And into destination.
- inc si ;Next source byte.
- inc di ;Next destination byte.
- dec cx ;One less in loop.
- dec bx ;One less in total to and.
-
- cp_and_word: ;Word aligned and.
- mov dx, cx ;Save copy of loop variable so we
- ; can check for trailing bytes.
- shr cx, 1 ;How many words?
-
- and_loop: ;And away.
- mov ax, [word ptr ds:si] ;Read source word.
- and [word ptr es:di], ax ;And into destination.
- inc si ;Next source word.
- inc si
- inc di ;Next destination word.
- inc di
- loop and_loop ;Next word.
-
- test dx, 1 ;One last byte to and.
- jz cp_and_loop_end_test ;Nope.
-
- mov al, [byte ptr ds:si] ;Load and and last byte.
- and [byte ptr es:di], al
- inc si
- inc di
-
- cp_and_loop_end_test:
- sub bx, dx ;And'd all these bytes.
- cmp bx, 0 ;Is that all?
- jne cp_and_loop_top ;Nope, restart at source's
- ; beginning.
-
- pop di ;Restore important registers.
- pop si
- pop ds
-
- pop bp ;Standard exit.
- ret
- endp
-
- ;************************ NEG_MEM ****************************************
- ; Binary invert source and copy to the destination, wrapping the source
- ; as necessary to fill the destination. Does not actually modify the
- ; source, so that the calling routine does not have to protect the source.
- ; Prototype:
- ; void neg_mem(
- ; void far *source, /* Source image. */
- ; unsigned src_size, /* Number of bytes in source. */
- ; void far *destination, /* Destination image. */
- ; unsigned dest_size /* Number of bytes in the */
- ; /* destination. */
- ; );
- ;*************************************************************************
-
- proc _neg_mem
- arg source:dword, src_size:word, destination:dword, dest_size:word
-
-
- push bp
- mov bp,sp ;Standard entry.
-
- push ds ;We're using all of these so save
- push si ; them.
- push di
-
- cld ;Let's go forward.
- les di, [destination] ;Load destination address.
- mov bx, [dest_size] ;Load size of destination.
-
- cp_neg_loop_top: ;Top of neg loop.
- mov ax, [src_size] ;Load size of source. This
- ; register gets reused.
- lds si, [source] ;Load source address.
- cmp ax, bx ;Compare source neg destination
- ; sizes.
- jl cp_neg_small_src ;Is source smaller?
-
- mov cx, bx ;Destination is smaller, neg
- ; only that many bytes.
- jmp cp_neg
-
- cp_neg_small_src:
- mov cx, ax ;Neg all of the source.
-
- cp_neg:
- test di, 1 ;Is destination on a word
- ; boundary?
- jz cp_neg_word ;Yes.
-
- ;Let's get aligned. Neg a single byte.
-
- mov al, [byte ptr ds:si] ;Read single byte of source.
- neg al ;Negate the byte.
- mov [byte ptr es:di], al ;Copy to destination.
- inc si ;Next source byte.
- inc di ;Next destination byte.
- dec cx ;One less in loop.
- dec bx ;One less in total to neg.
-
- cp_neg_word: ;Word aligned neg.
- mov dx, cx ;Save copy of loop variable so we
- ; can check for trailing bytes.
- shr cx, 1 ;How many words?
-
- neg_loop: ;Neg away.
- mov ax, [word ptr ds:si] ;Read source word.
- neg ax ;Negate word.
- mov [word ptr es:di], ax ;Copy to destination.
- inc si ;Next source word.
- inc si
- inc di ;Next destination word.
- inc di
- loop neg_loop ;Next word.
-
- test dx, 1 ;One last byte to neg.
- jz cp_neg_loop_end_test ;Nope.
-
- mov al, [byte ptr ds:si] ;Load neg and last byte.
- neg al
- mov [byte ptr es:di], al
- inc si
- inc di
-
- cp_neg_loop_end_test:
- sub bx, dx ;Neg'd all these bytes.
- cmp bx, 0 ;Is that all?
- jne cp_neg_loop_top ;Nope, restart at source's
- ; beginning.
-
- pop di ;Restore important registers.
- pop si
- pop ds
-
- pop bp ;Standard exit.
- ret
- endp
-
- ;************************ SET_MEM ****************************************
- ; Set memory to value. Assumes lower byte is mapped into higher byte.
- ; NOTE:!!!!!!! If the number of bytes to set is zero, then 64K will be
- ; set. This is NOT intutive but it is the only way the string
- ; instructions will modify 64K. This is also the only 'blt' instruction
- ; for which this matters. None of the others should ever need to deal
- ; with a block that large.
- ; Prototype:
- ; void set_mem(
- ; void far *destination, /* Destination image. */
- ; unsigned dest_size, /* Number of bytes in the */
- ; /* destination. */
- ; unsigned value /* Value to set words/bytes to. */
- ; );
- ;*************************************************************************
-
- proc _set_mem
- arg destination:dword, dest_size:word, value:word
-
-
- push bp
- mov bp,sp ;Standard entry.
- push di ;Save this register, we're using
- ; it.
-
- cld ;Let's go forward.
- mov ax, [word value] ;Value to set memory to.
- les di, [destination] ;Load destination address.
- mov cx, [dest_size] ;Load size of destination.
-
- loop set_first_byte ;Prepare to set first byte. If
- ; cx is 0, it will be set to
- ; 0xffff so that a full 64K will
- ; be set. Sheesh, the lengths
- ; we go to ;)
-
- set_first_byte:
- stosb ;Set first byte to value.
-
- test di, 1 ;Is the remaining word aligned?
- jz set_word
-
- loop set_second_byte ;Nope, make it so.
-
- set_second_byte:
- stosb ;Set second byte to value.
-
- set_word: ;Set word aligned.
- mov dx, cx ;Save count to identify trailing
- ; bytes.
- shr cx, 1 ;Number of words to set.
-
- rep stosw ;Set them all.
-
- test dx, 1 ;One byte left?
- jz set_end ;Nope
-
- stosb ;Set last byte.
-
- set_end:
- pop di ;Restore register.
-
- pop bp ;Standard exit.
- ret
- endp
-
- end
-