{ Segmented 16 & Flat 32 compatible the name 'Seg16' should be defined in 16bit segment mode } {$O+,F+} Unit StrScn32; INTERFACE function ScanBytes(bts:string; var str; slen:word; forward:boolean):word; {$IfNdef Seg16} register; {$EndIf} function ScanBytesFwd(bts:string; var str; slen:word):word; {$IfNdef Seg16} register; {$EndIf} function ScanBytesBwd(bts:string; var str; slen:word):word; {$IfNdef Seg16} register; {$EndIf} function ScanChars(chars,str:string; beg:byte; forward:boolean):byte; function ScanCharsFwd(chars,str:string; beg:byte):byte; function ScanCharsBwd(chars,str:string; beg:byte):byte; function ScanByteFwd(beg:pointer; b:Byte; size:word):word; function ScanByteBwd(beg:pointer; b:Byte; size:word):word; function ScanNthFwd(b:Byte; nth:word; beg:pointer; size:word):word; function ScanNthBwd(b:Byte; nth:word; beg:pointer; size:word):word; function ScanWordFwd(beg:pointer; w:word; size:word):word; function ScanWordBwd(beg:pointer; w:word; size:word):word; IMPLEMENTATION USES cpu286; { Scan any one of some bytes ------------------------------------------------} function ScanAny:word; {in Forward or Backward direction } {$IfDef seg16} near; assembler; asm { DF=0 - forward; DF=1 - backward; ES:DI -> bytes to scan; BL:= number of bytes; DX:SI -> where scan (last byte for DF=1); CX:= length of string; Return: AX:= offset of found first byte (0 if any one not found) } xor ax,ax jcxz @End; or bl,bl; jz @End push ds; push bp; push cx mov ds,dx; mov dx,cx; mov bp,di; xor bh,bh pushf; pop ax; and ah,(1 shl (bDirection-8)); jz @Loop add bp,bx; dec bp @Loop: mov cx,bx; mov di,bp lodsb; repne scasb; je @Found dec dx jnz @loop pop ax; xor ax,ax; jmp @NotFound @Found: pop ax; dec dx; sub ax,dx @NotFound: pop bp; pop ds @End: end; {$Else} assembler; asm { DF=0 - forward; DF=1 - backward; EDI -> bytes to scan; BL:= number of bytes; ESI -> where scan (last byte for DF=1); ECX:= length of string; Return: AX:= offset of found first byte (0 if any one not found) } xor ax,ax jecxz @End; or bl,bl; jz @End push ebp; push ecx mov dl,bl; xor ebx,ebx; mov bl,dl mov edx,ecx; mov ebp,edi; pushf; pop ax; and ah,(1 shl (bDirection-8)); jz @Loop add ebp,ebx; dec ebp @Loop: mov ecx,ebx; mov edi,ebp lodsb; repne scasb; je @Found dec edx jnz @loop pop eax; xor ax,ax; jmp @NotFound @Found: pop eax; dec edx; sub eax,edx @NotFound: pop ebp; @End: end; {$EndIf} function ScanBytes(bts:string; var str; slen:word; forward:boolean):word; {$IfDef seg16} assembler; asm cld mov cx,slen; les di,str; mov dx,es les si,bts; SEGES lodsb; mov bl,al; xchg si,di cmp forward,TRUE; je @Cont std @Cont: call ScanAny end; {$Else} assembler; asm {EAX=bts; [EDX]=str; ECX=slen; [Frame]=forward} push ebx; push edi; push esi; cld mov edi,str; mov esi,bts; lodsb; mov bl,al; xchg esi,edi cmp forward,TRUE; je @Cont std @Cont: call ScanAny pop esi; pop edi; pop ebx; end; {$EndIf} function ScanBytesFwd(bts:string; var str; slen:word):word; {$IfDef seg16} assembler; asm {$IFOPT G+} leave {$ELSE} pop bp {$ENDIF} pop ax; pop bx {$IFOPT G+} push TRUE {$ELSE} mov dx,TRUE; push dx {$ENDIF} push bx; push ax jmp near(ScanBytes) end; {$Else} assembler; asm push ebx; push edi; push esi; cld mov cx,slen; les di,str; mov dx,es les si,bts; SEGES lodsb; mov bl,al; xchg si,di call ScanAny pop esi; pop edi; pop ebx; end; {$EndIf} function ScanBytesBwd(bts:string; var str; slen:word):word; assembler; asm {$IfDef seg16} {$IFOPT G+} leave {$ELSE} pop bp {$ENDIF} pop ax; pop bx {$IFOPT G+} push FALSE {$ELSE} mov dx,FALSE; push dx {$ENDIF} push bx; push ax jmp near(ScanBytes) {$Else} push ebx; push edi; push esi; cld mov edi,str; mov esi,bts; lodsb; mov bl,al; xchg esi,edi std call ScanAny pop esi; pop edi; pop ebx; {$EndIf} end; function ScanChars(chars,str:string; beg:byte; forward:boolean):byte; assembler; asm {$IfDef seg16} cld xor ah,ah les si,str; SEGES lodsb; mov cx,ax; mov dx,es; mov di,si les si,chars; SEGES lodsb; mov bx,ax mov al,beg; or al,al; jz @End; cmp cx,ax; jnb @Cont mov cx,ax @Cont: xchg di,si; dec ax; add si,ax; sub cx,ax cmp forward,FALSE; jne @Cont1 std; mov cx,ax; inc cx @Cont1: call ScanAny @End: {$Else} cld xor eax,eax mov esi,str; lodsb; mov cx,ax; mov edi,esi mov esi,chars; lodsb; mov bx,ax mov al,beg; or al,al; jz @End; cmp cx,ax; jnb @Cont mov cx,ax @Cont: xchg edi,esi; dec ax; add esi,eax; sub ecx,eax cmp forward,FALSE; jne @Cont1 std; mov ecx,eax; inc ecx @Cont1: call ScanAny @End: {$EndIf} end; function ScanCharsFwd(chars,str:string; beg:byte):byte; assembler; asm {$IfDef seg16} {$IFOPT G+} leave {$ELSE} pop bp {$ENDIF} pop ax; pop bx {$IFOPT G+} push TRUE {$ELSE} mov dx,TRUE; push dx {$ENDIF} push bx; push ax jmp near(ScanChars) {$Else} leave pop eax; pop ebx push TRUE push ebx; push eax jmp near(ScanChars) {$EndIf} end; function ScanCharsBwd(chars,str:string; beg:byte):byte; assembler; asm {$IfDef seg16} {$IFOPT G+} leave {$ELSE} pop bp {$ENDIF} pop ax; pop bx {$IFOPT G+} push FALSE {$ELSE} mov dx,FALSE; push dx {$ENDIF} push bx; push ax jmp near(ScanChars) {$Else} leave pop eax; pop ebx push FALSE push ebx; push eax jmp near(ScanChars) {$EndIf} end; { Scan single byte ----------------------------------------------------------} function ScanNth:word; near; {in Forward or Backward direction N-th byte} assembler; asm {$IfDef seg16} { DF=0 - forward; DF=1 - backward; AL:=byte to scan; BX:=N-th byte to find; ES:DI -> where scan (last byte for DF=1); CX:= length of string (if CX=0 then length=$FFFF-DI is used); Return: AX:= offset of found byte (0 if not found) } or cx,cx; jnz @Cont mov cx,di; not cx @Cont: mov dx,cx or bx,bx; jz @NotFound @Loop: repne scasb; jne @NotFound dec bx jnz @Loop @Found: mov ax,dx; sub ax,cx; jmp @End @NotFound: xor ax,ax @End: {$Else} { DF=0 - forward; DF=1 - backward; AL:=byte to scan; EBX:=N-th byte to find; EDI -> where scan (last byte for DF=1); ECX:= length of string (if ECX=0 then length=$FFFFFFFF-EDI is used); Return: EAX:= offset of found byte (0 if not found) } or ecx,ecx; jnz @Cont mov ecx,edi; not ecx @Cont: mov edx,ecx or ebx,ebx; jz @NotFound @Loop: repne scasb; jne @NotFound dec ebx jnz @Loop @Found: mov eax,edx; sub eax,ecx; jmp @End @NotFound: xor eax,eax @End: {$EndIf} end; function Scan:word; near; {in Forward or Backward direction } assembler; asm {$IfDef seg16} { DF=0 - forward; DF=1 - backward; AL:=byte to scan; ES:DI -> where scan (last byte for DF=1); CX:= length of string (if CX=0 then length=$FFFF-DI is used); Return: AX:= offset of found byte (0 if not found) } mov bx,1; jmp ScanNth {$Else} mov ebx,1; jmp ScanNth {$EndIf} end; function ScanByteFwd(beg:pointer; b:Byte; size:word):word; assembler; asm {$IfDef seg16} cld les di,beg; mov al,b; mov cx,size call Scan {$Else} cld mov edi,beg; mov al,b; xor ecx,ecx; mov cx,size call Scan {$EndIf} end; function ScanByteBwd(beg:pointer; b:Byte; size:word):word; assembler; asm {$IfDef seg16} std les di,beg; mov al,b; mov cx,size call Scan {$Else} std mov edi,beg; mov al,b; xor ecx,ecx; mov cx,size call Scan {$EndIf} end; function ScanNthFwd(b:Byte; nth:word; beg:pointer; size:word):word; assembler; asm {$IfDef seg16} cld les di,beg; mov al,b; mov cx,size; mov bx,nth call ScanNth {$Else} cld mov di,beg; mov al,b; xor ecx,ecx; mov cx,size; xor ebx,ebx; mov bx,nth; call ScanNth {$EndIf} end; function ScanNthBwd(b:Byte; nth:word; beg:pointer; size:word):word; assembler; asm {$IfDef seg16} std les di,beg; mov al,b; mov cx,size; mov bx,nth call ScanNth {$Else} std mov di,beg; mov al,b; xor ecx,ecx; mov cx,size; xor ebx,ebx; mov bx,nth; call ScanNth {$EndIf} end; {---------------------------------------------------------------------------} { Scan single word ---------------------------------------------------------} function ScanW:word; near; {in Forward or Backward direction } assembler; asm {$IfDef seg16} { DF=0 - forward; DF=1 - backward; AL:=byte to scan; ES:DI -> where scan (last byte for DF=1); CX:= length of string (if CX=0 then length=(($FFFF-DI) div 2) is used); Return: AX:= offset of found byte (0 if not found) } jcxz @MaxLength; jmp @Cont @MaxLength: mov cx,di; not cx; shr cx,1 @Cont: mov dx,cx repne scasw; je @Found @NotFound: xor ax,ax; jmp @End @Found: mov ax,dx; sub ax,cx @End: {$Else} { DF=0 - forward; DF=1 - backward; AL:=byte to scan; EDI -> where scan (last byte for DF=1); ECX:= length of string (if ECX=0 then length=(($FFFFFFFF-EDI) div 2) is used); Return: EAX:= offset of found byte (0 if not found) } jecxz @MaxLength; jmp @Cont @MaxLength: mov ecx,edi; not ecx; shr ecx,1 @Cont: mov edx,ecx repne scasw; je @Found @NotFound: xor eax,eax; jmp @End @Found: mov eax,edx; sub eax,ecx @End: {$EndIf} end; function ScanWordFwd(beg:pointer; w:word; size:word):word; assembler; asm {$IfDef seg16} cld les di,beg; mov ax,w; mov cx,size call Scan {$Else} cld xor eax,eax; xor ecx,ecx mov edi,beg; mov ax,w; mov cx,size call Scan {$EndIf} end; function ScanWordBwd(beg:pointer; w:word; size:word):word; assembler; asm {$IfDef seg16} std les di,beg; mov ax,w; mov cx,size call Scan {$Else} std xor eax,eax; xor ecx,ecx mov edi,beg; mov ax,w; mov cx,size call Scan {$EndIf} end; {---------------------------------------------------------------------------} END.