; ======================= source-file :_nd_search.asm =========================
;
; Purpose: non-deterministic search for a character, sub-string or sub-binary, inside
;      a string or a binary.
;      Produces all the positions where a certain character or  sub-string or sub-
;      binary is found, inside a string or a binary, at each non-deterministic call.
;      Then it fails, after all positions have been found.
;
; NOTE: Can be called with "findall/3", to find ALL the positions where a char,
;   sub-string, or sub-binary is located, inside a string or a binary.

    IDEAL
P586
    MODEL   FLAT

    DATASEG
ALIGN 4
    extrn   ctb:dword

    CODESEG
ALIGN 4
; ======= first two variants deal with strings only (most common):
    public _nd_search_0 ;(STRING,CHAR,posx)
    public _nd_search_1 ;(STRING,STRING,posx)

; ======= next three variants deal with binaries:
    public _nd_search_2 ;(BINARY,CHAR,posx)
    public _nd_search_3 ;(BINARY,STRING,posx)
    public _nd_search_4 ;(BINARY,BINARY,posx)

; ======= next two variants accept an "initial position"(arg 3):
    public _nd_search_5 ;(STRING,CHAR,inpos,posx)
    public _nd_search_6 ;(STRING,STRING,inpos,posx)

; ======= next three variants deal with binaries, accepting "initial position"(arg 3):
    public _nd_search_7 ;(BINARY,CHAR,inpos,posx)
    public _nd_search_8 ;(BINARY,STRING,inpos,posx)
    public _nd_search_9 ;(BINARY,BINARY,inpos,posx)

; ======= next two variants take a "case char-table"(arg 4), and init_pos(arg 3):
    public _nd_search_10    ;(STRING,CHAR,inpos,case,posx)
    public _nd_search_11    ;(STRING,STRING,inpos,case,posx)

; ======= next 3 variants take "case" and "initial position" but deal with binaries:
    public _nd_search_12    ;(BINARY,CHAR,inpos,case,posx)
    public _nd_search_13    ;(BINARY,STRING,inpos,case,posx)
    public _nd_search_14    ;(BINARY,BINARY,inpos,case,posx)
   
Macro pushx3   
    push    esi
    push    edi
    push    ebx
    endm

Macro popx3 
    pop ebx
    pop edi
    pop esi
    ret
    endm

    extrn   _MEM_AllocGStack:near
    extrn   _MEM_AdjustGStackAlloc:near
    extrn   _RUN_Fail:near
    extrn   _RUN_JmpReturn:near
    extrn   _RUN_StackBTrack:near
    extrn   _RUN_JmpReturn1:near
    extrn   _MEM_MakeBinaryGStack:near


PROC _nd_search_0 near      ; (STRING,CHAR,UNSIGNED) -(i,i,o)
ENTER   12,0            ;
ARG strg1:dword,char1:byte,outpx:dword
    pushx3
    mov esi,[strg1]     ; string input.............. ARG-1(input)
    mov [ebp-8], esi    ;
    mov ah,[char1]      ; char ..................... ARG-2(input)
    mov [ebp-4], eax    ;
; -------------------------------
@@LP0:  mov eax,[ebp-4] ;
@@LP0a: lodsb           ;
    cmp al,ah       ;
    jz  @@ok1       ;
    or  al,al       ;
    jz  @@XZ1       ; if zero, fail at end of string
    jmp @@LP0a      ; else repeat THIS loop
; ===============================
@@ok1:  mov [ebp-8],esi ; store it
    call _RUN_StackBTrack   ; stack a 'backtrack point' in Visual Prolog
    mov esi,[ebp-8] ; recover ESI
    or  eax,eax     ; is the result (of StackBTrack) zero?
    jne @@LP0       ; if not, read more...
; -------------------------------
    mov eax,esi     ; return right_hand_side string (after the char)
    mov ecx,eax     ;
    mov ebx,[strg1]     ; string input.............. ARG-1(input)
    sub ecx,ebx     ;
    mov edx,[outpx]     ; give Position of Char .... ARG-3(output)
    mov [edx],ecx   ;
    call _RUN_JmpReturn1    ; call Visual Prolog function "_RUN_JmpReturn1"
    mov esi,[ebp-8] ;
    jmp @@LP0       ; repeat big loop
; ===============================
@@XZ1:  call _RUN_Fail      ; FAIL
    popx3
LEAVE
ENDP _nd_search_0


PROC _nd_search_1 near  ;  (STRING,STRING,POSITION) -(i,i,o)
ENTER   16,0    ;
ARG strg1:dword,substr:dword,outpx:dword
    pushx3
    mov edi,[substr]    ; substring................ ARG-2(input)
    cmp [byte ptr edi],0    ; special case of substr=""?
    jnz @@Laa       ; if not so, normal processing
; -------------------------------
    jmp @@XZ1       ; else, fail
    mov edi,[strg1] ;
    xor eax,eax     ;
    mov ecx,eax     ;
    not ecx     ;
    repne   scasb       ;
    not ecx     ;
    mov     edx,[outpx] ; give Position of substring.... ARG-3(output)
    mov [edx],ecx   ;
    jmp @@XZ2       ;
; ===============================
@@Laa:  mov esi,[strg1]     ; string input..............ARG-1(input)
    mov [ebp-8], esi    ;
    mov [ebp-4], edi    ;
@@LP0:  mov edi,[ebp-4] ;
    mov ah,[byte ptr edi]   ; first char of substring in AH
@@LP0a: lodsb           ;
    cmp al,ah       ;
    jz  @@ok1       ;
    or  al,al       ;
    jz  @@XZ1       ; if zero, fail at end of string
    jmp @@LP0a      ; else repeat THIS loop
; ===============================
@@ok1:  push    esi     ;
@@ok2:  inc    edi     ;
    lodsb          ;
    cmp    al,[byte ptr edi]
    jz @@ok2       ;
    mov    al,[byte ptr edi]
    or al,al       ;
    jz @@ok3       ;
    pop esi     ;
    jmp @@LP0       ;
@@ok3:  mov    ebx,esi     ;
    pop esi     ;
    mov [ebp-8],esi ; store esi
    mov [ebp-12],ebx    ; store right_hand_string after the substring
    call _RUN_StackBTrack   ; stack a 'backtrack point' in Visual Prolog
    mov esi,[ebp-8] ; recover ESI
    or  eax,eax     ; is the result (of StackBTrack) zero?
    jne @@LP0       ; if not, read more...
; -------------------------------
@@ZZ:   mov eax,[ebp-12]    ; return right_hand_side string (after the char)
    mov ecx,esi     ;
    mov ebx,[strg1]     ; string input.................. ARG-1(input)
    sub ecx,ebx     ;
    mov edx,[outpx]     ; give Position of substring.... ARG-3(output)
    mov [edx],ecx   ;
    call _RUN_JmpReturn1    ; call Visual Prolog function "_RUN_JmpReturn1"
    mov esi,[ebp-8] ;
    jmp @@LP0       ; repeat big loop
; ===============================
@@XZ1:  call _RUN_Fail      ; FAIL
@@XZ2:  popx3
LEAVE
ENDP _nd_search_1


PROC _nd_search_2 near      ; (BINARY,CHAR,UNSIGNED) -(i,i,o)
ENTER   16,0            ;
ARG binary:dword,char1:byte,outpx:dword
    pushx3
    mov esi,[binary]    ; binary input.............. ARG-1(input)
    mov ecx,[dword ptr esi-4]   ;
    dec ecx     ;
    dec ecx     ;
    dec ecx     ;
    dec ecx     ;
    mov [ebp-8], esi    ;
    mov ah,[char1]      ; char ..................... ARG-2(input)
    mov [ebp-4], eax    ;
    mov [ebp-12],ecx    ;
@@LP0:  mov eax,[ebp-4] ;
    mov ecx,[ebp-12]    ;
@@LP0a: lodsb           ;
    cmp al,ah       ;
    jz  @@ok1       ;
    or  al,al       ;
    jz  @@XZ1       ; if zero, fail at end of string
    jmp @@LP0a      ; else repeat THIS loop
; ===============================
@@ok1:  mov [ebp-8],esi ; store it
    mov [ebp-12],ecx    ;
    call _RUN_StackBTrack   ; stack a 'backtrack point' in Visual Prolog
    mov esi,[ebp-8] ; recover ESI
    or  eax,eax     ; is the result (of StackBTrack) zero?
    jne @@LP0       ; if not, read more...
; -------------------------------
    mov eax,esi     ; return right_hand_side string (after the char)
    mov ecx,eax     ;
    mov ebx,[binary]        ; string input.............. ARG-1(input)
    sub ecx,ebx     ;
    dec ecx     ; binaries start at zero   
    mov edx,[outpx]     ; give Position of Char .... ARG-3(output)
    mov [edx],ecx   ;
    call _RUN_JmpReturn1    ; call Visual Prolog function "_RUN_JmpReturn1"
    mov esi,[ebp-8] ;
    jmp @@LP0       ; repeat big loop
; ===============================
@@XZ1:  call _RUN_Fail      ; FAIL
    popx3
LEAVE
ENDP _nd_search_2


PROC _nd_search_3 near      ; (BINARY,STRING,POSITION) -(i,i,o)
ENTER   20,0    ;
ARG strg1:dword,substr:dword,outpx:dword
    pushx3
    mov edi,[substr]    ; substring................ ARG-2(input)
    mov esi,[strg1]     ; BINARY input..............ARG-1(input)
    mov [ebp-8], esi    ;
    mov [ebp-4], edi    ;
    mov ecx,[dword ptr esi-4]   ;
    dec ecx
    dec ecx
    dec ecx
    mov [ebp-16],ecx    ; length of binary in local variable

@@LP0:  mov edi,[ebp-4] ;
    mov ah,[byte ptr edi]   ; first char of substring in AH
@@LP0a: lodsb           ;
    cmp al,ah       ;
    jz  @@ok1       ;
;or al,al       ;
;jz @@XZ1       ; if zero, fail at end of string
    dec ecx     ;
    or  ecx,ecx     ;
    jz  @@XZ1       ;
    jmp @@LP0a      ; else repeat THIS loop
; ===============================
@@ok1: 
    dec ecx     ;
    or  ecx,ecx     ;
    jz  @@XZ1       ;
    mov [ebp-16],ecx    ;
    push    esi     ;
@@ok2:  inc    edi     ;
    lodsb          ;
    cmp    al,[byte ptr edi]
    jz @@ok2       ;
    mov    al,[byte ptr edi]
    or al,al       ;
    jz @@ok3       ;
    pop esi     ;
    jmp @@LP0       ;
; ===============================
@@ok3:  mov    ebx,esi     ;
    pop esi     ;
    mov [ebp-8],esi ; store esi
    mov [ebp-12],ebx    ; store right_hand_string after the substring
    mov [ebp-16],ecx    ; remaining length recovered
    call _RUN_StackBTrack   ; stack a 'backtrack point' in Visual Prolog
    mov ecx,[ebp-16]    ; remaining length recovered
    mov esi,[ebp-8] ; recover ESI
    or  eax,eax     ; is the result (of StackBTrack) zero?
    jne @@LP0       ; if not, read more...
; -------------------------------
@@ZZ:   mov eax,[ebp-12]    ; return right_hand_side string (after the char)
    mov ecx,esi     ;
    mov ebx,[strg1]     ; string input.................. ARG-1(input)
    sub ecx,ebx     ;
    mov edx,[outpx]     ; give Position of substring.... ARG-3(output)
    dec ecx     ; binaries start at zero   
    mov [edx],ecx   ;
    call _RUN_JmpReturn1    ; call Visual Prolog function "_RUN_JmpReturn1"
    mov esi,[ebp-8] ;
    mov ecx,[ebp-16]    ; remaining length recovered
    jmp @@LP0       ; repeat big loop
; ===============================
@@XZ1:  mov [ebp-16],ecx    ;
    call _RUN_Fail      ; FAIL
@@XZ2:  popx3
LEAVE
ENDP _nd_search_3



PROC _nd_search_4 near  ; (BINARY,BINARY,POSITION) -(i,i,o)
ENTER   24,0
ARG binary:dword,subbin:dword,outpx:dword
    pushx3
    mov edi,[subbin]    ; sub-binary............... ARG-2(input)
    mov ecx,[dword ptr edi-4] ; "true length" of sub-binary in ECX
    dec ecx     ;
    dec ecx     ;
    dec ecx     ;
    dec ecx     ; length of sub_binary_array in ECX
    dec ecx     ; minus 1
    mov [ebp-20],ecx    ; store length of sub-binary-1 in local variable
    mov edx,ecx     ; copy it also to EDX
    mov esi,[binary]    ; binary input..............ARG-1(input)
    mov ecx,[dword ptr esi-4] ; "true length" of binary in ECX
    dec ecx     ;
    dec ecx     ;
    dec ecx     ;
    dec ecx     ; length of binary_array in ECX
    dec ecx     ;
    mov [ebp-8], esi    ;
    sub ecx,edx     ; subtrack sub_bin_length from binary length!
    dec ecx
    mov [ebp-16],ecx    ; store length of binary in local variable
    mov [ebp-4], edi    ;
@@LP0: 
;;or    ecx,ecx     ;
;;jz    @@XZ1       ;
    mov edi,[ebp-4] ;
    or  ecx,ecx     ;
    jz  @@XZ1       ;
    mov ah,[byte ptr edi]   ; first char of subbinary in AH
@@LP0a: lodsb           ;
    cmp al,ah       ;
    jz  @@ok1       ;
    loop    @@LP0a      ;
    jmp @@XZ1       ; if exhausted, fail
; ===============================
@@ok1:  dec ecx     ;
    or  ecx,ecx     ;
    jz  @@XZ1       ;
    push    esi     ;
    push   ecx     ;
     mov   ecx,[ebp-20]    ; length of subbinary recovered from local var.
     jmp   @@ok2       ;
@@ok2a:   dec   ecx     ;
     jz    @@ok3       ;
@@ok2:   inc   edi     ;
     lodsb         ;
     cmp al,[byte ptr edi] ;
     jz    @@ok2a      ;
    pop    ecx     ;
    pop esi     ;
    jmp @@LP0       ;
; ===============================
@@ok3:   mov   ebx,esi     ;
    pop    ecx     ;
    pop esi     ;
    or  ecx,ecx     ;
    jz  @@XZ1       ;
    mov [ebp-8],esi ; store esi
    mov [ebp-12],ebx    ; store right_hand_string after the substring
    mov [ebp-16],ecx    ; store length in local variable
;or ecx,ecx     ;
;jz @@XZ1       ;
    call _RUN_StackBTrack   ; stack a 'backtrack point' in Visual Prolog
    mov ecx,[ebp-16]    ; store length in local variable
    mov esi,[ebp-8] ; recover ESI
    or  eax,eax     ; is the result (of StackBTrack) zero?
    jne @@LP0       ; if not, read more...
; -------------------------------
    mov eax,[ebp-12]    ; return right_hand_side string (after the sub-bin)
    mov ecx,esi     ;
    mov ebx,[binary]    ; binary input.................. ARG-1(input)
    sub ecx,ebx     ;
    dec ecx     ; binaries start at zero   
    mov edx,[outpx]     ; give Position of substring.... ARG-3(output)
    mov [edx],ecx   ;
    call _RUN_JmpReturn1    ; call Visual Prolog function "_RUN_JmpReturn1"
    mov esi,[ebp-8] ;
    mov ecx,[ebp-16]    ; recover length from local variable
    jmp @@LP0       ; repeat big loop
; ===============================
@@XZ1:  call _RUN_Fail      ; FAIL
    popx3
LEAVE
ENDP _nd_search_4


PROC _nd_search_5 near  ; (STRING,CHAR,inpos,posx) -(i,i,i,o)
ENTER   12,0            ;
ARG strg1:dword,char1:byte,inpos:dword,outpx:dword
    pushx3
    mov esi,[strg1] ; string input.............. ARG-1(input)
    mov eax,[inpos] ; initial position.......... ARG-2(input)
    dec eax     ; minus one, because Prolog strings start at 1
    add esi,eax     ; add the position to the string pointer
    mov [ebp-8], esi    ;
    mov ah,[char1]      ; char ..................... ARG-3(input)
    mov [ebp-4], eax    ;
; -------------------------------
@@LP0:  mov eax,[ebp-4] ;
@@LP0a: lodsb              ;
    cmp al,ah       ;
    jz  @@ok1       ;
    or  al,al       ;
    jz  @@XZ1       ; if zero, fail at end of string
    jmp @@LP0a      ; else repeat THIS loop
; ===============================
@@ok1:  mov [ebp-8],esi ; store it
    call _RUN_StackBTrack   ; stack a 'backtrack point' in Visual Prolog
    mov esi,[ebp-8] ; recover ESI
    or  eax,eax     ; is the result (of StackBTrack) zero?
    jne @@LP0          ; if not, read more...
; -------------------------------
    mov eax,esi     ; return right_hand_side string (after the char)
    mov ecx,eax     ;
    mov ebx,[strg1] ; string input.............. ARG-1(input)
    sub ecx,ebx     ;
    mov edx,[outpx] ; give Position of Char .... ARG-3(output)
    mov [edx],ecx       ;
    call _RUN_JmpReturn1    ; call Visual Prolog function "_RUN_JmpReturn1"
    mov esi,[ebp-8] ;
    jmp @@LP0       ; repeat big loop
; ===============================
@@XZ1:  call _RUN_Fail      ; FAIL
    popx3
LEAVE
ENDP _nd_search_5


PROC _nd_search_6 near  ;  (STRING,STRING,INIPOS,POSITION) -(i,i,i,o)
ENTER   16,0    ;
ARG strg1:dword,substr:dword,inpos:dword,outpx:dword
    pushx3
    mov esi,[strg1]     ; string input..............ARG-1 (input)
    mov [ebp-8], esi    ;
    mov edi,[substr]    ; substring................ ARG-2 (input)
    mov eax,[inpos] ; initial position......... ARG-3 (input)
    dec eax     ; minus 1, since Prolog strings start with 1
    add esi,eax     ; add initial position to the string
    mov [ebp-4], edi    ;
@@LP0:  mov edi,[ebp-4] ;
    mov ah,[byte ptr edi]   ; first char of substring in AH
@@LP0a: lodsb       ;
    cmp al,ah       ;
    jz  @@ok1       ;
    or  al,al       ;
    jz  @@XZ1       ; if zero, fail at end of string
    jmp @@LP0a      ; else repeat THIS loop
; ===============================
@@ok1:  push    esi     ;
@@ok2:  inc    edi     ;
    lodsb             ;
    cmp al,[byte ptr edi]  ;
    jz @@ok2          ;
    mov al,[byte ptr edi]  ;
    or al,al       ;
    jz @@ok3       ;
    pop esi        ;
    jmp @@LP0       ;
@@ok3: 
    mov ebx,esi ;
    pop esi        ;
    mov [ebp-8],esi ; store esi
    mov [ebp-12],ebx    ; store right_hand_string after the substring
    call _RUN_StackBTrack   ; stack a 'backtrack point' in Visual Prolog
    mov esi,[ebp-8] ; recover ESI
    or  eax,eax     ; is the result (of StackBTrack) zero?
    jne @@LP0          ; if not, read more...
; -----------------------
    mov eax,[ebp-12]    ; return right_hand_side string (after the char)
    mov ecx,esi     ;
    mov ebx,[strg1] ; string input.................. ARG-1(input)
    sub ecx,ebx     ;
    mov edx,[outpx] ; give Position of substring.... ARG-3(output)
    mov [edx],ecx       ;
    call _RUN_JmpReturn1    ; call Visual Prolog function "_RUN_JmpReturn1"
    mov esi,[ebp-8] ;
    jmp @@LP0          ; repeat big loop
; ===============================
@@XZ1:  call _RUN_Fail  ; FAIL
    popx3
LEAVE
ENDP _nd_search_6


PROC _nd_search_7 near      ; (BINARY,CHAR,inpos,posx) -(i,i,i,o)
ENTER   16,0            ;
ARG binary:dword,char1:byte,inpos:dword,outpx:dword
    pushx3
    mov esi,[binary]    ; binary input.............. ARG-1(input)
    mov ecx,[dword ptr esi-4]   ;
    dec ecx     ;
    dec ecx     ;
    dec ecx     ;
    dec ecx     ;
    mov eax,[inpos] ; initial position.......... ARG-2(input)
    add esi,eax     ; add initial position to binary pointer
    sub ecx,eax     ; subtract init_pos from binary length
    mov [ebp-8], esi    ;
    mov ah,[char1]      ; char ..................... ARG-3(input)
    mov [ebp-4], eax    ;
    mov [ebp-12],ecx    ;
@@LP0:  mov eax,[ebp-4] ;
    mov ecx,[ebp-12]    ;
@@LP0a: lodsb           ;
    cmp al,ah       ;
    jz  @@ok1       ;
    or  al,al       ;
    jz  @@XZ1       ; if zero, fail at end of string
    jmp @@LP0a      ; else repeat THIS loop
; ===========================
@@ok1:  mov [ebp-8],esi ; store it
    mov [ebp-12],ecx       ;
    call _RUN_StackBTrack   ; stack a 'backtrack point' in Visual Prolog
    mov esi,[ebp-8] ; recover ESI
    or  eax,eax     ; is the result (of StackBTrack) zero?
    jne @@LP0          ; if not, read more...
; -----------------------
    mov eax,esi     ; return right_hand_side string (after the char)
    mov ecx,eax     ;
    mov ebx,[strg1] ; string input.............. ARG-1(input)
    sub ecx,ebx     ;
    dec ecx            ; binaries start at zero   
    mov edx,[outpx] ; give Position of Char .... ARG-3(output)
    mov [edx],ecx       ;
    call _RUN_JmpReturn1    ; call Visual Prolog function "_RUN_JmpReturn1"
    mov esi,[ebp-8] ;
    jmp @@LP0          ; repeat big loop
; =======================
@@XZ1:  call _RUN_Fail      ; FAIL
    popx3
LEAVE
ENDP _nd_search_7


PROC _nd_search_8 near  ;  (BINARY,STRING,INIPOS,POSITION) -(i,i,i,o)
ENTER   20,0    ;
ARG binary:dword,substr:dword,inpos:dword,outpx:dword
    pushx3
    mov esi,[binary]    ; binary input..............ARG-1 (input)
    mov ecx,[dword ptr esi-4]   ;
    dec ecx     ;
    dec ecx     ;
    dec ecx     ;
    dec ecx     ; ecx is now length of binary
    mov [ebp-8], esi    ;
    mov edi,[substr]    ; substring................ ARG-2 (input)
    mov eax,[inpos] ; initial position......... ARG-3 (input)
    add esi,eax     ; add initial position to the string
    sub ecx,eax     ; subtract it from the length
    mov [ebp-4], edi    ;
    mov [ebp-16],ecx    ; store the length as a local variable
@@LP0:  mov edi,[ebp-4] ;
    mov ecx,[ebp-16]       ; restore the length from local variable
    mov ah,[byte ptr edi]   ; first char of substring in AH
@@LP0a: lodsb       ;
    cmp al,ah       ;
    jz  @@ok1       ;
    dec ecx        ;
    jz  @@XZ1       ; if at the end, fail
    jmp @@LP0a      ; else repeat THIS loop
; ===============================
@@ok1:  push    esi     ;
@@ok2:  inc    edi     ;
    lodsb             ;
    cmp al,[byte ptr edi]  ;
    jz @@ok2          ;
    mov al,[byte ptr edi]  ;
    or al,al          ;
    jz @@ok3          ;
    pop esi            ;
    jmp @@LP0          ;
@@ok3:  mov ebx,esi ;
    pop esi            ;
    mov [ebp-8],esi ; store esi
    mov [ebp-12],ebx    ; store right_hand_string after the substring
    mov [ebp-16],ecx    ; store length remaining
    call _RUN_StackBTrack   ; stack a 'backtrack point' in Visual Prolog
    mov esi,[ebp-8] ; recover ESI
    or  eax,eax     ; is the result (of StackBTrack) zero?
    jne @@LP0          ; if not, read more...
; -----------------------
    mov eax,[ebp-12]    ; return right_hand_side string (after the char)
    mov ecx,esi     ;
    mov ebx,[strg1] ; string input.................. ARG-1(input)
    sub ecx,ebx     ;
    mov edx,[outpx] ; give Position of substring.... ARG-3(output)
    mov [edx],ecx       ;
    call _RUN_JmpReturn1    ; call Visual Prolog function "_RUN_JmpReturn1"
    mov esi,[ebp-8] ;
    jmp @@LP0          ; repeat big loop
; =======================
@@XZ1:  call _RUN_Fail      ; FAIL
    popx3
LEAVE
ENDP _nd_search_8


PROC _nd_search_9 near  ;  (BINARY,BINARY,INIPOS,POSITION) -(i,i,i,o)
ENTER   24,0    ;
ARG binary:dword,substr:dword,inpos:dword,outpx:dword
    pushx3
    mov esi,[binary]    ; binary input..............ARG-1 (input)
    mov ecx,[dword ptr esi-4]   ;
    dec ecx     ;
    dec ecx     ;
    dec ecx     ;
    dec ecx     ; ecx is now length of binary
    mov [ebp-8], esi    ;
    mov edi,[substr]    ; substring................ ARG-2 (input)
    mov edx,[dword ptr edi-4]   ;
    mov eax,[inpos] ; initial position......... ARG-3 (input)
    add esi,eax     ; add initial position to the string
    sub ecx,eax     ; subtract it from the length
    mov [ebp-4], edi    ;
    mov [ebp-16],ecx    ; store the length as a local variable
@@LP0:  mov edi,[ebp-4] ;
    mov ecx,[ebp-16]    ; restore the length from local variable
    mov ah,[byte ptr edi]   ; first char of substring in AH
@@LP0a: lodsb           ;
    cmp al,ah       ;
    jz  @@ok1       ;
    dec ecx        ;
    jz  @@XZ1       ; if at the end, fail
    jmp @@LP0a      ; else repeat THIS loop
; ===============================
@@ok1:  push    esi     ;
@@ok2:  inc    edi     ;
    lodsb          ;
    cmp al,[byte ptr edi]  ;
    jz @@ok2       ;
    mov al,[byte ptr edi]  ;
    or al,al       ;
    jz @@ok3       ;
    pop esi        ;
    jmp @@LP0       ;
@@ok3:  mov ebx,esi     ;
    pop esi     ;
    mov [ebp-8],esi ; store esi
    mov [ebp-12],ebx    ; store right_hand_string after the substring
    mov [ebp-16],ecx    ; store length remaining
    call _RUN_StackBTrack   ; stack a 'backtrack point' in Visual Prolog
    mov esi,[ebp-8] ; recover ESI
    or  eax,eax     ; is the result (of StackBTrack) zero?
    jne @@LP0       ; if not, read more...
; -----------------------
    mov eax,[ebp-12]    ; return right_hand_side string (after the char)
    mov ecx,esi     ;
    mov ebx,[strg1] ; string input.................. ARG-1(input)
    sub ecx,ebx     ;
    mov edx,[outpx] ; give Position of substring.... ARG-3(output)
    mov [edx],ecx       ;
    call _RUN_JmpReturn1    ; call Visual Prolog function "_RUN_JmpReturn1"
    mov esi,[ebp-8] ;
    jmp @@LP0          ; repeat big loop
; ===============================
@@XZ1:  call _RUN_Fail  ; FAIL
    popx3
LEAVE
ENDP _nd_search_9


PROC _nd_search_10 near     ; (STRING,CHAR,inpos,case_table,posx) -(i,i,i,i,o)
ENTER   16,0            ;
ARG strg1:dword,char1:byte,inpos:dword,case:dword,outpx:dword
    pushx3
    mov esi,[strg1]     ; string input................... ARG-1(input)
    mov eax,[inpos] ; initial position............... ARG-3(input)
    dec eax     ; minus one, because Prolog strings start at 1
    add esi,eax     ; add the position to the string pointer
    mov edx,[case]  ; case_table_number in EDX....... ARG-4(input)
;;or    edx,edx     ; is it zero?
;;jnz   @@ci        ; if not so, case-sensitive search
    dec edx         ;
    shl edx,1           ;
    shl edx,1           ;
    mov ebx,[dword ptr ctb+edx] ; ebx is now the Nth char_table
    mov [ebp-12],ebx    ; put char_table in local variable
@@ci:   mov [ebp-8], esi    ;
    mov al,[char1]      ; char .......................... ARG-2(input)
    xlat    [EBX]       ; translate
    mov ah,al       ; store as AH
    mov [ebp-4], eax    ;
; -------------------------------
@@LP0:  mov eax,[ebp-4] ;
    mov ebx,[ebp-12]    ; restore case_table from local variable
@@LP0a: lodsb       ;
    xlat    [EBX]   ; translate
    cmp al,ah       ;
    jz  @@ok1       ;
    or  al,al       ;
    jz  @@XZ1       ; if zero, fail at end of string
    jmp @@LP0a      ; else repeat THIS loop
; ===============================
@@ok1:  mov [ebp-8],esi ; store it
    call _RUN_StackBTrack   ; stack a 'backtrack point' in Visual Prolog
    mov esi,[ebp-8] ; recover ESI
    or  eax,eax     ; is the result (of StackBTrack) zero?
    jne @@LP0          ; if not, read more...
; -----------------------
    mov eax,esi     ; return right_hand_side string (after the char)
    mov ecx,eax     ;
    mov edx,[strg1] ; string input.............. ARG-1(input)
    sub ecx,edx     ;
    mov edx,[outpx] ; give Position of Char .... ARG-3(output)
    mov [edx],ecx       ;
    call _RUN_JmpReturn1    ; call Visual Prolog function "_RUN_JmpReturn1"
    mov esi,[ebp-8] ;
    jmp @@LP0          ; repeat big loop
; =======================
@@XZ1:  call _RUN_Fail  ; FAIL
    popx3
LEAVE
ENDP _nd_search_10


PROC _nd_search_11 near ;  (STRING,STRING,INIPOS,case_table,POSITION) -(i,i,i,i,o)
ENTER   24,0    ;
ARG strg1:dword,substr:dword,inpos:dword,case:dword,outpx:dword
    pushx3
    mov esi,[strg1]     ; string input................. ARG-1(input)
    mov [ebp-8], esi    ;
    mov edi,[substr]    ; substring.................... ARG-2(input)
    mov eax,[inpos] ; initial position............. ARG-3(input)
    dec eax     ; minus 1, since Prolog strings start with 1
    add esi,eax ; add initial position to the string
    mov edx,[case]  ; case_table_number in EDX..... ARG-4(input)
    dec edx        ;
    shl edx,1       ;
    shl edx,1       ;
    mov ebx,[dword ptr ctb+edx] ; ebx is now the Nth char_table
    mov [ebp-20],ebx    ; put char_table in local variable
    mov [ebp-4], edi    ;
    mov al,[byte ptr edi]   ; first char of substring in AL
    xlat    [EBX]       ; translate
    mov ah,al          ; store as AH
    mov [ebp-16],eax    ; store in local variable
@@LP0:  mov edi,[ebp-4] ;
    mov ebx,[ebp-20]    ; restore char_table from local variable
    mov eax,[ebp-16]    ; restore AH (eax) from local variable
@@LP0a: lodsb           ;
    or  al,al       ;
    jz  @@XZ1       ; if zero, fail at end of string
    xlat    [ebx]   ; translate
    cmp al,ah       ; compare
    jz  @@ok1       ;
    jmp @@LP0a      ; else repeat THIS loop
; ===============================
@@ok1:  push    esi     ;
@@ok2:  inc    edi     ;
    lodsb             ;
    xlat   [ebx]       ; translate
    mov    DL,AL       ; store in DL
    mov al,[byte ptr edi]  ; get a byte from substring
    or al,al          ;
    jz @@ok3          ;
    xlat   [ebx]       ; translate
    cmp    al,dl       ; compare
    jz @@ok2          ; if translations are the same, continue loop
    pop esi            ;
    jmp @@LP0          ;
@@ok3:  mov    [ebp-16],eax    ;
    mov    eax,esi         ;
    pop esi     ;
    mov [ebp-8],esi ; store esi
    mov [ebp-12],eax    ; store right_hand_string after the substring
    call _RUN_StackBTrack   ; stack a 'backtrack point' in Visual Prolog
    mov esi,[ebp-8] ; recover ESI
    or  eax,eax     ; is the result (of StackBTrack) zero?
    jne @@LP0       ; if not, read more...
; -------------------------------
    mov eax,[ebp-12]    ; return right_hand_side string (after the char)
    mov ecx,esi     ;
    mov edx,[strg1]     ; string input.................. ARG-1(input)
    sub ecx,edx     ;
    mov edx,[outpx]     ; give Position of substring.... ARG-3(output)
    mov [edx],ecx   ;
    call _RUN_JmpReturn1    ; call Visual Prolog function "_RUN_JmpReturn1"
    mov esi,[ebp-8] ;
    jmp @@LP0       ; repeat big loop
; ===============================
@@XZ1:  call _RUN_Fail      ; FAIL
    popx3
LEAVE
ENDP _nd_search_11


PROC _nd_search_12 near     ; (BINARY,CHAR,inpos,case_table,posx) -(i,i,i,i,o)
ENTER   20,0            ;
ARG binary:dword,char1:byte,inpos:dword,case:dword,outpx:dword
    pushx3
    mov esi,[binary]        ; binary input................... ARG-1(input)
    mov ecx,[dword ptr esi-4]   ; "true size" of binary in ECX
    dec ecx     ;
    dec ecx     ;
    dec ecx     ;
    dec ecx     ;
    mov [ebp-16],ecx    ; store length in local variable
    mov eax,[inpos] ; initial position............... ARG-3(input)
    add esi,eax ; add the position to the binary pointer
    mov edx,[case]  ; case_table_number in EDX....... ARG-4(input)
    dec edx        ;
    shl edx,1       ;
    shl edx,1       ;
    mov ebx,[dword ptr ctb+edx] ; ebx is now the Nth char_table
    mov [ebp-12],ebx    ; put char_table in local variable
    mov [ebp-8], esi    ;
    mov al,[char1]      ; char .......................... ARG-2(input)
    xlat    [EBX]       ; translate
    mov ah,al          ; store as AH
    mov [ebp-4], eax    ;
; -----------------------
@@LP0:
    mov eax,[ebp-4] ;
    mov ebx,[ebp-12]    ; restore case_table from local variable
    mov ecx,[ebp-16]    ; restore length from local variable
@@LP0a: lodsb       ;
    dec ecx        ;
    jz  @@XZ1       ; if at the end of bin