diff options
Diffstat (limited to 'private/mvdm/wow16/user/winstr.asm')
-rw-r--r-- | private/mvdm/wow16/user/winstr.asm | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/private/mvdm/wow16/user/winstr.asm b/private/mvdm/wow16/user/winstr.asm new file mode 100644 index 000000000..12de6d83b --- /dev/null +++ b/private/mvdm/wow16/user/winstr.asm @@ -0,0 +1,349 @@ +;++ +; +; 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 DBCS +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 DBCS + +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 DBCS +;; 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 ; DBCS +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 DBCS + cCall IsDBCSLeadByte,<ax> + cmp al,0 + je an1 + inc di +endif ; DBCS +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 DBCS + 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 DBCS + 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 |