.386p
.287

; Copyright 1992, Alfred J. Heyman and Spectrum Research, Inc.

PUBLIC comspec
PUBLIC cmdtail
PUBLIC progname               ;Full name and path of ACAD.EXE program.
PUBLIC support                ;Path to "ACAD=" support path.

DGROUP group dseg
dseg segment word public 'DATA'



gdtdata  db 6 dup (0)
idtdata  db 6 dup (0)
ldtdata  dw 0
cmdtail  db 0,0dh,132 dup (0)

comspec  db 90 dup (0)
progname db 90 dup (0)
support  db 256 dup (0);

envstr   db 0,0
acadsup  db "ACAD=",0

cmdpblk:

envpofs  dd ?
envpseg  dw ?
cmdtailo dd ?
cmdtails dw ?

dseg ends
;----------------------------------------------------------------------------
; This protected mode code counts on the following defined segments.
;
; 0x002C: Segment of DOS Environment
; 0x0034: Segment of first megabyte.
;----------------------------------------------------------------------------

?init segment word public 'CODE'
assume  cs:?init ;CGROUP,ds:DGROUP

public  getds,getcs,getes,getss,getfs,getgs
public  sbreak,getgdt,getcr3,getcr0,getldt
public  getefl,click,dosshell,progname
public  get_env,get_progname,get_echar
public  get_bs15,get_cpos

;---------------------------------------------------------------
; This function returns the current cursor position.
;---------------------------------------------------------------
get_cpos proc

                mov  ah,0fh
                int  10h                ;Get active page in BH.

                mov  ah,3               ;Get cursor position.
                int  10h                ;Page is in BH.

                xor  eax,eax
                mov  ax,dx
                ret

get_cpos endp

;---------------------------------------------------------------
get_bs15 proc

                mov  ax,0
                mov  bx,0ffffh
                mov  cx,0ffffh
                int  15h

                cmp  ax,5342h
                jnz  gbsx
                mov  ax,1

     gbsx:      ret

get_bs15 endp

;---------------------------------------------------------------
get_progname proc

                push ds
                push es
                push si
                mov  ax,ds
                mov  es,ax              ;Common segments.
                mov  ax,002ch           ;Dos Extender's Env segment.
                mov  ds,ax
                xor  si,si              ;Clear counter.

    peloop:     mov  al,[si]            ;Get the first byte.
                or   al,al              ;Zero if end of environment.
                jz   peout              ;Jump to cleanup if at end.

    pedo:       call prntstr
                inc  si
                jmp  peloop             ;Loop up for another.

    peout:      add  si,3               ;Jump over terminating bytes.
                call crlf               ;Print CRLF
    pedo2:      call copyprogname       ;DS:SI points to progname X:\ACAD.EXE.
                call prntstr            ;Print the program name.
                pop  si
                pop  es
                pop  ds
                ret
get_progname endp

;----------------------------------------------------------------
get_echar proc

                push ebp
                mov  ebp,esp
                push esi
                push es

                mov  si,002ch
                mov  es,si
                mov  esi,[ebp+8]
                mov  al,byte ptr es:[esi]

                pop  es
                pop  esi
                pop  ebp
                ret

get_echar endp


;---------------------------------------------------------------
; On entry, DS:SI point to the program name.
; This function copies the program name into our progname variable.
;---------------------------------------------------------------
copyprogname proc
                push si
                push di
                lea  di,progname

     cpnmore:   mov  al,[si]
                mov  es:[di],al
                inc  si
                inc  di
                or   al,al
                jnz  cpnmore

                pop  di
                pop  si
                ret
copyprogname endp

;---------------------------------------------------------------
prntstr:        mov  al,[si]            ;Print string.
                or   al,al
                jz   prexit
                mov  dl,al
                call prnt
                inc  si
                jmp  prntstr

  prexit:       call crlf
                ret

;---------------------------------------------------------------
crlf:       ;   mov  ah,2
            ;   mov  dl,0dh
            ;   int  21h
            ;   mov  dl,0ah
prnt:       ;   mov  ah,2
            ;   int  21h
                ret

;---------------------------------------------------------------
dosshell proc
                lea  ebx,envstr
                xor  ebx,ebx
                mov  ds:envpofs,ebx
                mov  ds:envpseg,bx

                lea  ebx,cmdtail
                mov  ds:cmdtailo,ebx
                mov  ds:cmdtails,ds

                mov  ax,4b00h
                lea  edx,comspec
                mov  ebx,offset cmdpblk
                int  21h
                ret

dosshell endp

;---------------------------------------------------------------
click proc
                in   al,61h
                xor  al,2
                out  61h,al
                mov  ah,2
                mov  dl,7
                int  21h
                ret
click endp
;---------------
sbreak proc
                mov  ah,2
                mov  dl,7
                int  21h
                int 3
                ret
sbreak endp
;---------------------------------------------------------------
getds proc
                xor  eax,eax
                mov  ax,ds
                ret
getds endp

getcs proc
                xor  eax,eax
                mov  ax,cs
                ret
getcs endp

getss proc
                xor  eax,eax
                mov  ax,ss
                ret
getss endp

getes proc
                xor  eax,eax
                mov  ax,es
                ret
getes endp

getfs proc
                xor  eax,eax
                mov  ax,fs
                ret
getfs endp

getgs proc
                xor  eax,eax
                mov  ax,gs
                ret
getgs endp



getgdt proc
                int  3
                sgdt fword ptr ds:gdtdata
                sidt fword ptr ds:idtdata
                ret
getgdt endp
;---------------
getldt proc
                sldt ds:ldtdata
                xor  eax,eax
                mov  ax,ds:ldtdata
                ret
getldt endp
;---------------
getcr0 proc
                mov  eax,cr0
                ret
getcr0 endp
;---------------
getcr3 proc
                mov  eax,cr3
                ret
getcr3 endp
;---------------
getefl proc
                pushfd
                pop  eax
                ret
getefl endp

;----------------------------------------------------;
; GET_env returns a pointer to the environment       ;
; var specified if one is found.                     ;
;----------------------------------------------------;
get_env     proc

            push ebp
            mov  ebp,esp
            push ds
            push es
            push esi
            push edi
            push eax
            push ecx

            xor  esi,esi
            mov  esi,[ebp+8]   ;Get pointer to env parm to look for.

            cld                ;Direction foward.
                   
            xor  eax,eax
            mov  ax,ds
            mov  es,ax
            mov  edi,esi

            xor  ecx,ecx
            mov  ecx,0ffffffffh
            mov  al,0
    rp1:    mov  ah,es:[edi]
            inc  edi
            cmp  ah,al
            loopnz rp1
     ;      repnz scasb        ;Find the size of our string
            not  ecx           ;CX has length of our string.
            dec  ecx           ;Dont include ZERO...
                               ;CX now holds our string's length.
            mov  ax,002ch
            mov  es,ax
            xor  edi,edi       ;ES:DI points to dos extender ENV seg.
            cld                ;Direction Forward.

ge_top:     mov  eax,edi              ;Get first env WORD.
            cmp  byte ptr es:[edi],0  ;If 00...
            jz   outout               ; then jump out.

            push ecx
            push esi
            push edi

    rp2:    mov  al,byte ptr [esi]
            mov  ah,byte ptr es:[edi]
            inc  esi
            inc  edi
            cmp  ah,al
            loopz rp2
       ;    repz cmpsb         ;Compare all.

            pop  edi
            pop  esi
            pop  ecx

            pushf
            add  eax,ecx       ;ES:AX Points at env data for string.
            popf
            jz   outgood       ;Jump out if environment searchstring found.

            push ecx           ;Find next search string if not.
            mov  al,0
            mov  ecx,0ffffffffh

 rpnzscasb: mov  ah,es:[edi]
            inc  edi
            cmp  ah,al
            loopnz  rpnzscasb
       ;    repnz scasb         ;Find the end of this string and the

            pop  ecx            ;Start of the next.
            jmp  ge_top         ;Jump up for another.

outgood:    mov  esi,[ebp+12]   ;DS:SI point to storage area.
          ; mov  si,[ebp+12]    ;DS:SI point to storage area.

            add  edi,ecx        ;ES:DI points to ENV data.

  supmore:  mov  al,es:[edi]
            mov  [esi],al
            inc  esi
            inc  edi
            or   al,al
            jnz  supmore

outout:     pop  ecx
            pop  eax
            pop  edi
            pop  esi
            pop  es
            pop  ds
            pop  ebp
            ret

get_env     endp
            

?init ends
end