Category : Miscellaneous Language Source Code
Archive   : MTD.ZIP
Filename : FILLMEM.ASM

 
Output of file : FILLMEM.ASM contained in archive : MTD.ZIP
%TITLE "Fill-memory module. TASM 2.0 Ideal mode"

;** File: fillmem.asm (WITH BUGS!)
;** Author: (c) 1990 by Tom Swan.

IDEAL
MODEL small
CODESEG
PUBLIC CalcDistance, FillMemory, Normalize

;---------------------------------------------------------------
; CalcDistance Calculate distance between two pointers
;---------------------------------------------------------------
; Input:
; es:di = normalized pointer number 1
; ds:si = normalized pointer number 2
; Output:
; dx:ax = 32-bit unsigned result. If es:di = ds:si, the
; result = 1. If es:di < ds:si, the result is undefined.
; Registers:
; ax, dx
;---------------------------------------------------------------
PROC CalcDistance
push bx cx di si ; Save modified registers
mov ax, si ; Copy si to ax for subtraction
sub ax, di ; ax <- si - di (signed)
cwd ; Convert to 32-bit ax:dx
mov si, ds ; Copy ds to si, es to di--can't
mov di, es ; subtract segment registers.
sub si, di ; si <- ds - es (# paragraphs)
xor di, di ; Zero high order 32-bit result
mov cx, 4 ; Assign loop count
@@10:
shl si, 1 ; Multiply segment value by 16
rcl di, 1 ; over 32-bit result si:di
loop @@10 ; Loop on cx
add ax, si ; Add offset value to
adc dx, di ; 32-bit result in dx:ax
pop si di cx bx ; Restore saved registers
ret ; Return to caller
ENDP CalcDistance

;---------------------------------------------------------------
; FillBytes Fill number of bytes at any address
;---------------------------------------------------------------
; Input:
; cx = number of bytes to fill (must be <= 0fff0h)
; dl = byte value to use for fill
; es:di = normalized starting address for fill
; Output:
; none
; Registers:
; ax, cx, di, es
;---------------------------------------------------------------
PROC FillBytes
jcxz @@10 ; Exit if count = 0
cld ; Clear direction flag
repnz stosb ; Fill cx bytes at es:di
@@10:

; ---- Fall through to Normalize pointer in es:di

ENDP FillBytes

;---------------------------------------------------------------
; Normalize Normalize pointer in es:di
;---------------------------------------------------------------
; Input:
; es:di = any 32-bit address value
; Output:
; es:di normalized so that offset in di is in
; the range 0000 to 000Fh. Formula is
; segment = (segment + (offset / 16))
; offset = (offset % 16) (% = "modulo")
; Registers:
; ax, es, di
;---------------------------------------------------------------
PROC Normalize
push bx cx ; Save registers
mov ax, di ; Copy di (offset) to ax
mov cl, 4 ; Calculate offset / 16
shr ax, cl ; by shifting right x 4
mov bx, es ; Copy es to bx
add ax, bx ; ax = ax + bx
mov es, ax ; Copy result back to es
and di, 0fh ; Calculate offset % 16
pop cx bx ; Restore registers
ret ; Return to caller
ENDP Normalize

;---------------------------------------------------------------
; FillMemory Fill memory with any byte value
;---------------------------------------------------------------
; Input:
; dl = byte value to use for fill
; es:di = starting address for fill
; ds:si = ending address for fill
; Output:
; Area from es:di up to and including ds:si filled
; with dl bytes. If ds:si = es:di, 1 byte is filled.
; If ds:si < es:di, no filling occurs.
; After, es:di = address of byte after ds:si
; Registers:
; ax
;---------------------------------------------------------------
PROC FillMemory
push bx cx dx di si es ; Save most registers

; ---- Normalize the two addresses in es:di and ds:si, so that
; their offset values are in the range 0000 to 000Fh.

push es ds ; Save es, push ds
pop es ; Set es <- ds
xchg di, si ; Swap di and si
call Normalize ; Normalize ds:si in es:di
push es ; Push result in es
pop ds ; Set ds <- es
xchg di, si ; Swap di and si back
pop es ; Restore es
call Normalize ; Normalize es:di

; ---- Fill as many almost full segments as possible. The
; division keeps the program running fast, while
; simplifying the logic that would be required to fill
; full 65,536-byte segments when the starting offset
; might not be zero.

push dx ; Save fill value on stack
call CalcDistance ; dx:ax <- count of bytes to fill
mov bx, 0fff0h ; bx <- fill-loop maximum count
div bx ; ax <- dx:ax div 0fff0h
mov bx, dx ; Assign remainder to bx
pop dx ; Restore fill value to dl
mov cx, ax ; Assign fill-loop count to cx
jcxz @@20 ; Skip loop if count = 0
@@10:
push cx ; Save count for next loop
mov cx, 0fff0h ; Set count to maximum
call FillBytes ; Fill cx bytes at es:di
pop cx ; Restore loop count
loop @@10 ; Repeat until cx = 0
@@20:
mov cx, bx ; Assign remainder in bx to cx
call FillBytes ; Fill remaining bytes
pop es si di dx cx bx ; Restore registers
ret ; Return to caller
ENDP FillMemory

END ; End of fillmem.asm text


  3 Responses to “Category : Miscellaneous Language Source Code
Archive   : MTD.ZIP
Filename : FILLMEM.ASM

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/