windows-nt/Source/XPSP1/NT/base/mvdm/wow16/user/wsphelp.asm

141 lines
2.8 KiB
NASM
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
;++
;
; WOW v1.0
;
; Copyright (c) 1991, Microsoft Corporation
;
; WSPHELP.ASM
; Win16 wsprintf/wvsprintf helper services
;
; History:
;
; Created 28-May-1991 by Jeff Parsons (jeffpar)
; Copied from WIN31 and edited (as little as possible) for WOW16
;--
;
; WSPHELP.ASM
;
; Assembly language helper functions for wvsprintf(), primarily for
; space optimization.
;
; History:
; 2/15/89 craigc Initial
;
memS=1
?PLM=1
?WIN=1
ifdef WOW
SEGNAME equ <TEXT>
endif
.xlist
include cmacros.inc
.list
createSeg _%SEGNAME,%SEGNAME,WORD,public,CODE
sBegin %SEGNAME
assumes cs,%SEGNAME
;
; SP_PutNumber
;
; Takes an unsigned long integer and places it into a buffer, respecting
; a buffer limit, a radix, and a case select (upper or lower, for hex).
;
cProc SP_PutNumber, <NEAR,PUBLIC>, <si,di>
parmD lpb
parmD n
parmW limit
parmW radix
parmW case
cBegin
mov al,'a'-'0'-10 ; figure out conversion offset
cmp case,0
jz pn_lower
mov al,'A'-'0'-10
pn_lower:
mov byte ptr case,al
mov bx,word ptr n[0] ; bx:dx=number
mov dx,word ptr n[2]
mov cx,radix ; cx=radix
les di,lpb ; es:di->string
mov si,limit ; cchLimit
;
; following adapted from fultoa.asm
;
; dx:bx = unsigned number, cx = radix, es:di->output
;
divdown:
xchg ax,dx ; divide hi
xor dx,dx
or ax,ax
jz nohigh ; save a divide
div cx ; dx = rem, ax = hi div
nohigh:
xchg ax,bx ; ax = lo, bx = hi div
div cx ; dx = rem, bx:ax = div
xchg ax,dx ; ax = rem, bx:dx = div
xchg dx,bx ; ax = rem, dx:bx = div (tight!!!!)
add al,'0'
cmp al,'9'
jbe isadig ; is a digit already
add al,byte ptr case ; convert to letter
isadig:
dec si ; decrement cchLimit
jz pn_exit ; go away if end of string
stosb ; stick it in
mov ax,dx
or ax,bx
jnz divdown ; crack out next digit
pn_exit:
mov ax,di
sub ax,word ptr lpb[0] ; find number of chars output
cEnd
;
; SP_Reverse
;
; Reverses a string in place
;
cProc SP_Reverse,<NEAR,PUBLIC>,<si,di>
parmD lpFirst
parmD lpLast
cBegin
push ds
lds si,lpFirst
les di,lpLast
mov cx,di ; number of character difference
sub cx,si
inc cx
shr cx,1 ; number of swaps required
jcxz spr_boring ; nuthin' to do
spr100:
mov ah,es:[di]
mov al,[si] ; load the two characters
mov [si],ah
mov es:[di],al ; swap them
inc si
dec di ; adjust the pointers
loop spr100 ; ...until we've done 'em all
spr_boring:
pop ds
cEnd
sEnd %SEGNAME
end