windows-nt/Source/XPSP1/NT/base/mvdm/wow16/user/winstr.asm
2020-09-26 16:20:57 +08:00

350 lines
8.3 KiB
NASM

;++
;
; WOW v1.0
;
; Copyright (c) 1991, Microsoft Corporation
;
; WINSTR.ASM
; Win16 string services
;
; History:
;
; Created 18-Jun-1991 by Jeff Parsons (jeffpar)
; Copied from WIN31 and edited (as little as possible) for WOW16
;--
;****************************************************************************
;* *
;* WinStr.ASM - *
;* *
;* String related API calls to support different lanuages *
;* *
;****************************************************************************
TITLE WinStr.ASM
ifdef WOW
NOEXTERNS equ 1
endif
NOTEXT = 1
.xlist
include user.inc
.list
sBegin DATA
sEnd
createSeg _TEXT, CODE, WORD, PUBLIC, CODE
sBegin CODE
assumes CS,CODE
assumes DS,DATA
ExternNP Loc_IsConvertibleToUpperCase
ExternNP Loc_Upper
ExternFP IAnsiUpper
ExternFP IAnsiLower
ExternFP Ilstrcmpi
ifdef FE_SB
ExternFP IsDBCSLeadByte
endif
; Function codes for all the string functions in USER
;
ANSINEXT_ID equ 1
ANSIPREV_ID equ 2
ANSIUPPER_ID equ 3
ANSILOWER_ID equ 4
;--------------------------------------------------------------------------
; The order of entries in the following table can not be changed
; unless the *_ID codes are also changed in KERNEL also.
; ((FunctionCode - 1) << 1) is used as the index into this table
;
; Function Codes:
;
; NOTE: If you change the entries in this table, kindly update the
; *_ID statements above and also lString.asm of KERNEL.
;
;--------------------------------------------------------------------------
LabelW StringFuncTable
dw codeOFFSET IAnsiNext
dw codeOFFSET IAnsiPrev
dw codeOFFSET IAnsiUpper
dw codeOFFSET IAnsiLower
;*----------------------------------------------------------------------*
;* StringFunc() *
;* The string manipulation functions in kernel have been moved *
;* into USER. *
;* This is the common entry point in USER for all the string *
;* manipulation functions Kernel wants to call. Kernel jumps to *
;* this function with the function code in CX *
;* *
;* Input Parameters: *
;* [CX] contains the Function code. *
;* [sp] contains the FAR return address of the original caller of *
;* the string manipulation functions in Kernel *
;*----------------------------------------------------------------------*
cProc StringFunc, <FAR, PUBLIC>
cBegin nogen
xchg bx,cx ; move function code to BX
dec bx
shl bx, 1
jmp StringFuncTable[bx]
; Control does not comeback here. It returns directly
; to the caller
cEnd nogen
;*----------------------------------------------------------------------*
;* *
;* AnsiPrev() *
;* *
;*----------------------------------------------------------------------*
ifdef FE_SB
cProc IAnsiPrev,<PUBLIC,FAR>
; parmD pFirst ; [bx+10] es:di
; parmD pStr ; [bx+6] ds:si
cBegin nogen
push bp
mov bp,sp
push ds
push si
push di
lds si,[bp+6]
les di,[bp+10]
regptr dssi,ds,si
regptr esdi,es,di
cld
cmp si,di ; pointer to first char?
jz ap5 ; yes, just quit
dec si ; backup once
cmp si,di ; pointer to first char?
jz ap5 ; yse, just quit
ap1:
dec si ; backup once
mov al, [si] ; fetch a character
cCall IsDBCSLeadByte,<ax> ; DBCS lead byte candidate?
test ax,ax ;
jz ap2 ; jump if not.
cmp si,di ; backword exhausted?
jz ap3 ; jump if so
jmp ap1 ; repeat if not
ap2:
inc si ; adjust pointer correctly
ap3:
mov bx, [bp+6] ;
mov di, bx ; result in DI
dec di ;
sub bx, si ; how many characters backworded
test bx, 1 ; see even or odd...
jnz ap4 ; odd - previous char is SBCS
dec di ; make DI for DBCS
ap4:
mov si, di ; final result in SI
ap5:
mov ax,si
mov dx,ds
pop di
pop si
pop ds
pop bp
ret 8
cEnd nogen
else
cProc IAnsiPrev,<PUBLIC,FAR>
; parmD pFirst ; [bx+8] es:di
; parmD pStr ; [bx+4] ds:si
cBegin nogen
mov bx,sp
push ds
push si
push di
lds si,ss:[bx+4]
les di,ss:[bx+8]
regptr dssi,ds,si
regptr esdi,es,di
cld
cmp si,di ; pointer to first char?
jz ap3 ; yes, just quit
;;ifdef FE_SB
;; xchg si,di
;;ap1: mov dx,si
;; lodsb ; get a char
;; cCall IsDBCSLeadByte,<ax> ; is it kanji?
;; cmp al,0
;; je ap2 ; no, get next char
;; inc si ; yes, inc past second part
;;ap2: cmp si,di ; have we at or past end?
;; jb ap1 ; no, keep going
;; mov si,dx ; return previous pointer
;;else
dec si ; assume easy case...
;;endif ; FE_SB
ap3: mov ax,si
mov dx,ds
pop di
pop si
pop ds
ret 8
cEnd nogen
endif
;*----------------------------------------------------------------------*
;* *
;* AnsiNext() *
;* *
;*----------------------------------------------------------------------*
cProc IAnsiNext,<PUBLIC,FAR>
; parmD pStr
cBegin nogen
mov bx,sp
push di
les di,ss:[bx+4]
mov al,es:[di]
or al,al
jz an1
inc di
ifdef FE_SB
cCall IsDBCSLeadByte,<ax>
cmp al,0
je an1
inc di
endif ; FE_SB
an1: mov ax,di
mov dx,es
pop di
ret 4
cEnd nogen
;-----------------------------------------------------------------------
; MyAnsiUpper()
; convert string at es:di to upper case
;-----------------------------------------------------------------------
public MyAnsiUpper
MyAnsiUpper:
cld
mov si,di
mau1: lods byte ptr es:[si]
ifdef FE_SB
push ax
cCall IsDBCSLeadByte,<ax>
cmp ax,0
pop ax
je mau2
inc si
inc di
inc di
jmp short mau1
endif
mau2: call MyUpper
stosb
or al,al
jnz mau1
ret
;-----------------------------------------------------------------------
; MyAnsiLower()
; convert string at es:di to lower case
;-----------------------------------------------------------------------
public MyAnsiLower
MyAnsiLower:
cld
mov si,di
mal1: lods byte ptr es:[si]
ifdef FE_SB
push ax
cCall IsDBCSLeadByte,<ax> ; first byte of double byte?
cmp ax,0
pop ax
je mal2 ; no just do normal stuff
inc si ; skip the two bytes
inc di
inc di
jmp short mal1
endif
mal2: call MyLower
stosb
or al,al
jnz mal1
ret
;-------------------------------------------------------------------------
; MyUpper()
; convert lower case to upper, must preserve es,di,cx
;-------------------------------------------------------------------------
public MyUpper
MyUpper:
call Loc_IsConvertibleToUpperCase ; Check if it is a lower case char
; that has an uppercase equivalent
jnc myu1 ;
sub al,'a'-'A'
myu1: ret
ifdef KANJI
#################### KANJI ###############################################
; convert upper case to lower, must preserve es,di,cx
public MyLower
MyLower:
cmp al,'A'
jb myl2
cmp al,'Z'
jbe myl1
push ds
SetKernelDS
cmp [fFarEast],1 ; this is a far east kbd 1/12/87 linsh
pop ds
UnSetKernelDS
jge myl2 ; yes do nothing to the 0C0H - 0DEH range
cmp al,0C0H ; this is lower case a with a back slash
jb myl2
cmp al,0DEH
ja myl2
myl1: add al,'a'-'A'
myl2: ret
#################### KANJI ###############################################
endif
;--------------------------------------------------------------------------
; MyLower()
; convert upper case to lower, must preserve es,di,cx
;--------------------------------------------------------------------------
public MyLower
MyLower:
call Loc_Upper
jnc myl1
add al, 'a'-'A'
myl1:
ret
sEnd CODE
end