; =================== source-file: _gen_numlist.asm ======================
;
; Purpose: Generates integer-lists, given a min_value and a max_value
;
;GLOBAL DOMAINS
; ILIST = INTEGER*
;
;GLOBAL PREDICATES
; ILIST gen_numlist(INTEGER min_val,UNSIGNED num_values) -(i,i) language c
;
; ------------------------------------------------------------------------
IDEAL
P586
MODEL   FLAT
CODESEG
align   4

public  _gen_numlist

    extrn   _MEM_AllocGStack:near

PROC _gen_numlist near
    mov edx,[esp+4] ; set EDX = min (initial) value
    mov eax,[esp+8] ; set EAX = num of elements
    cmp eax,0       ; compare num_of_elements to zero
    jbe @@fx1       ; if  num_elements <= 0, special treatment...
; -------------------------------
    push    edi     ;
    push   ebx     ;
     push  edx     ;
      push eax     ;
       inc eax     ; num_of_elements + 1 (accounting for list_end)
       shl eax,1       ; 2 * num_of_elements
       mov ecx,eax     ; copy to ECX
       shl eax,1       ; 4 * num_of_elements
       add eax,ecx     ; 6 * num_of_elements
       shl eax,1       ; 12 * num_of_elements
       push eax        ;
        call _MEM_AllocGStack  ; allocate new memory for the list
       pop ecx     ;
       mov edi,eax     ; make EDI = list_pointer
      pop  ecx     ; restore num_of_elements, but in ECX
     pop   edx     ; restore minimum value, but in EDX
     push  edi     ; save the list pointer in the stack
      push esi     ;
       mov ebx,1       ; "normal_element_flag" in EBX
       mov esi,4       ;
@@p1:       mov eax,ebx     ;
       stosd       ; write "normal_element_flag"
       mov eax,edx     ; put current value in EAX
       stosd       ; write it
       inc edx     ; increment current_value
       mov eax,edi     ;
       add eax,esi     ;
       stosd       ; write pointer to next_element
       dec ecx     ; decrement element_counter ECX
       jnz @@p1        ; if ECX > 0, repeat this loop...
; -------------------------------
       mov eax,2       ; end_element flag in EAX
       stosd       ;
       xor eax,eax     ;
       stosd       ;
       stosd       ;
      pop  esi     ;
     pop   eax     ; return list_pointer, but into EAX
    pop    ebx     ;
    pop edi     ;
    retn
; ===============================
@@fx1:  mov eax,12      ;
    push    eax     ;
    call _MEM_AllocGStack  ;
    mov    edi,eax     ;
    pop eax     ;
    push    edi     ;
    mov    eax,2       ;
    stosd          ;
    xor    eax,eax     ;
    stosd          ;
    stosd          ;
    pop eax     ;
    retn
ENDP    _gen_numlist

    END

; ============================= VISUAL PROLOG TEST PROGRAM: ===============================
GLOBAL DOMAINS
 ILIST = INTEGER*

GLOBAL PREDICATES
 ILIST gen_numlist(INTEGER min_val,UNSIGNED num_values) -(i,i) language c

GOAL
 repeat, write("give min_value: "), readint(MIN),
 write("how many elements?- "), readint(N),
 ILx = gen_numlist(MIN,N), write(ILx), nl, readchar(C2x), C2x='\27', !.

; ***************  "32-bit Assembly Language Extensions for Visual Prolog" ****************
; Written by George A. Stathis (c) 2005,         E-mail: omadeon@yahoo.com, gstathis@enm.gr
; URL: http://www.omadeon.com/asm     Company: ENB Ltd.     Company site: http://www.enb.gr
; **** Use of this source-code is unrestricted, provided that the author is mentioned. ****