;**********************************************************
;*                                                        *
;*              Root APL module                           *
;*                                                        *
;* Function:  It's a monitor of transaction programs.     *
;*            Depends on value of status field and        *
;*            rc field will be started "aplmain" or       *
;*            transaction program.                        *
;* Input:     None.                                       *
;* Output:    None.                                       *
;*                                                        *
;* Last modification: 93-02-05 16:26.                     *
;*                                                        *
;*                                                        *
;*  CopyRight 1995. Nicholas Poljakov all rights reserved.*
;*                                                        *
;**********************************************************
.DOSSEG
.MODEL SMALL

include c:\m61\include\dos.inc
include c:\m61\include\bios.inc
include c:\m61\include\macros.inc
include parms.inc
include crtp.inc

PUBLIC  err1, str1, AplCall, LnSiz, CurPath, PathLt, ExCom, AplNm
PUBLIC  AplVars, S_AplNm, DosPrmt, InBuff, Apl, NextP, MainCycl, TestDS
PUBLIC  StTrans, EndTrans, RunDS, InCycl, CallSys, CmExit, AplExit, TpE
PUBLIC  AplParm, LuParm, DosCom, ComSeek, CsFound, SetDosCom, SetEnd, SetDC

EXTRN    SysCm    :PROC
EXTRN    GetDcWD  :PROC
EXTRN    UpStr    :PROC

LU_P_PTR EQU  17	; offset to field which hold pointer to LuParm
PARM_SZ  EQU  24	; size of a LU parameters area

.STACK   100h

.DATA

Sign	 DD    ?
	 ORG   Sign
	 DB    'LU62'
AplParm  APL_PARM <>
LuParm   LU_PARM  <>
PARM_SIZ EQU $ - AplParm

err1	 DB    13,10,"Must have DOS 2.0 or higher",13,10,"$"
err2	 DB    'The LU6.2 module was not installed!',13,10,'$'

str1     DB    'Type ''Exit'' to return into APL.',10,13,'$'

AplCall  DB 80 DUP(0)   ; "<full path name>aplmain 0"
LnSiz    DW    0        ; size of AplCall field
CurPath  DB    13,10
         DB 60 DUP(0)   ; full path name into current directory
PathLt   DW    0        ; length of CurPath field
ExCom    DB    'EXIT'
AplNm    DB    'aplmain.exe '
AplVars  DB    0
S_AplNm  EQU   $ - AplNm

DosPrmt  DB 60 DUP(0)   ; Dos prompt field
PspSeg   DW    0        ; segment address of PSP
DosCom   DB    'c:\command.com',0   ; COMSPEC=... line
         DB 60 DUP(0)   ;
ComSp    DB    'COMSPEC='
LT_CS    EQU   $ - ComSp
InBuff   DB    0,0      ; Buffer for input command line
         DB 80 DUP(0)

.CODE

Apl      PROC

         mov   ax, _DATA
         mov   ds, ax

;        cli                         ; Turn off interrupts
;        mov   ss,ax                 ; Make SS and
;        mov   sp, OFFSET STACK      ;   SP relative to DGROUP
;        sti

         mov   ax, es
         mov   PspSeg, ax            ; save segment address of PSP

; Adjust memory	allocation

         @GetVer                     ; Get DOS version
         cmp    al,3                 ; Requires DOS 3.0
         jge    NextP
         @ShowStr err1               ; else error and quit
         jmp   AplExit

NextP:

         mov   bx,sp                 ; Convert stack pointer to paragraphs
         mov   cl,4                  ;   to get stack size
         shr   bx,cl
         mov   ax, ss
         add   ax,bx                 ; Add SS to get end of program
         mov   bx,es                 ; Get start of program
         sub   ax,bx                 ; Subtract start from end
         @ModBlock ax                ; Release memory after program

;*
;* Set parm. area to zero
;*
         mov   ax, ds
         mov   es, ax
         mov   di, OFFSET AplParm
         xor   al, al
         mov   cx, SIZE AplParm
         cld
         rep   stosb

;*
;* Set pointers in LU parm area to structures APL_PARM and LU_PARM
;*

         mov   ax, 10h
         mov   bx, 0a0h
         mov   es, ax
         les   bx, DWORD PTR es:[bx] ; pointer to LU parm. table

;* Test if LU 6.2 module is active

	 mov   ax, WORD PTR es:[bx+PARM_SZ+5]
	 cmp   ax, WORD PTR Sign
	 jne   ErrExit

	 mov   ax, WORD PTR es:[bx+PARM_SZ+5+2]
	 cmp   ax, WORD PTR Sign+2
	 je    @F
ErrExit:
	 @ShowStr err2
	 @Exit
@@:
	 add   bx, LU_P_PTR
         mov   si, OFFSET AplParm
         mov   WORD PTR es:[bx], si
         mov   ax, ds
         mov   WORD PTR es:[bx + 2], ax

         add   bx, 4    ; offset to the field wich will hold
                        ; pointer to LuParm structure
         mov   si, OFFSET LuParm
         mov   WORD PTR es:[bx], si
         mov   WORD PTR es:[bx + 2], ax

;*
;*  Prepare initial AplParm values
;*
         mov   ax, ds
         mov   es, ax
         mov   si, OFFSET AplNm
         lea   di, AplParm.CmLine
         mov   cx, S_AplNm
         cld
         rep   movsb    ; move "aplmain 0" into the command line

;* Set current_directory_name variable

         lea   si, AplParm.Dir
         call  GetDcWD
         mov   AplParm.DirLen, ax

;*  Set AplCall field

         mov   cx, ax   ; length of full path name
         lea   si, AplParm.Dir
         mov   di, OFFSET AplCall
         rep   movsb
         mov   al, '\'
         stosb
         mov   si, OFFSET AplNm
         mov   cx, S_AplNm
         rep   movsb
         mov   ax, AplParm.DirLen
         add   ax, S_AplNm
         inc   ax       ; extra char to form ASCIIZ string
         mov   LnSiz, ax

;*  Set address of Program_exit for incoming FMH5

         mov   ax, OFFSET TpE
         mov   WORD PTR AplParm.Tpe, ax
         mov   ax, cs
         mov   WORD PTR AplParm.Tpe + 2, ax

;*  Set DosCom field
SetDC:
         mov   ax, PspSeg
         mov   es, ax
         mov   ax, WORD PTR es:[2ch]
         mov   es, ax   ; DOS envirounment field
         xor   di, di
         xor   ax, ax
         mov   cx, 32000
         mov   dx, cx
         cld
         repne scasw    ; seek end of DOS env. field
         sub   dx, cx
         mov   cx, dx   ; length of DOS envirounment
         shl   cx, 1
         xor   di, di
ComSeek:
         mov   al, 'C'
         repne scasb    ; seek first 'C' letter
         and   cx, cx
         jz    MainCycl ; not found...
         mov   dx, di
         dec   di
         mov   si, OFFSET ComSp
         push  cx
         mov   cx, LT_CS
         repe  cmpsb
         pop   cx
         jz    CsFound
         mov   di, dx
         jmp   short ComSeek

CsFound:
         push  ds
         mov   ax, es
         mov   ds, ax
         pop   es

         mov   si, di
         mov   bx, OFFSET DosCom

SetDosCom:
         lodsb
         and   al, al
         jz    SetEnd
         mov   BYTE PTR es:[bx], al
         inc   bx
         jmp   short SetDosCom

SetEnd:
         inc   bx
         mov   BYTE PTR es:[bx], 0
         mov   ax, es
         mov   ds, ax   ; restore DS

;*
;*  Begin main cycle to proceeding of transactions.
;*

MainCycl:
         mov   ax, ds
         mov   es, ax   ; set ES = DS
         lea   si, AplParm.CmLine
         xor   ax, ax
         call  SysCm

         mov   ax, AplParm.RetCd  ; completed process defined by this
                                  ; return code

         and   ax, ax   ; terminate ?
         jnz   NexTest
         jmp   AplExit
NexTest:
         dec   ax
         and   ax, ax   ; start transaction ?
         jnz   TestDS
         jmp   StTrans
TestDS:
         dec   ax
         and   ax, ax   ; DOS shell ?
         jz    RunDS
         dec   ax
         and   ax, ax   ; remote Command ?
         jz    RemCom
         jmp   AplExit

;*
;* Start and End Transaction processing
;*

StTrans:
         mov   ax, AplParm.Status
         and   ax, ax   ; is it Start Transaction request ?
         jz    EndTrans ; no... processing of End Transaction

         mov   AplParm.Status, 0
         jmp   MainCycl

EndTrans:
         lea   di, AplParm.CmLine
         mov   si, OFFSET AplCall
         mov   cx, LnSiz
         cld
         rep   movsb

         jmp   MainCycl

;*
;*  Executing remote command
;*

RemCom:
         lea   si, AplParm.Args
         mov   ax, 1
         call  SysCm

         lea   di, AplParm.CmLine
         mov   si, OFFSET AplCall
         mov   cx, LnSiz
         cld
         rep   movsb

         jmp   MainCycl

;*
;*  Accepting and executing commands from keyboard.
;*  (DOS shell)
;*
RunDS:
         @ShowStr str1

InCycl:
         mov   si, OFFSET CurPath + 2
         call  GetDcWD  ; get current full path name
         mov   PathLt, ax
         add   si, ax   ; pointer to end of CurPath
         mov   BYTE PTR [si], '\'
         mov   BYTE PTR [si + 1], '>'
         mov   BYTE PTR [si + 2], '$'
         @ShowStr CurPath    ; display standart DOS prompt

         @GetStr  InBuff, 0, 60
         cmp   InBuff + 1, 4
         je    CmExit   ; test if it's "Exit" command ?
CallSys:
         mov   si, OFFSET InBuff + 1
         mov   ax, 1
         call  SysCm
         jmp   short InCycl

CmExit:
         mov   si, OFFSET InBuff + 2
         call  UpStr
         mov   di, OFFSET ExCom
         mov   cx, 4
         cld
         repne cmpsb
         jnz   CallSys

;*
;*  Processing of "Exit" command
;*

         jmp   MainCycl

AplExit:
         @Exit

Apl      ENDP

;*
;*  Incoming FMH5 handler
;*
TpE      PROC
         @SaveRegs ax,cx,bx,si,di,ds,dx,es,bp
         mov   bp, sp

         mov   bx, _DATA
         mov   es, bx   ; restore initial DS value

         lds   si, DWORD PTR [bp + 4] ; DS:SI points to CREATE_TP record
         mov   bx, OFFSET LuParm

         cld

;*  LuParm.TpId = CRTP.TpID

         mov   cx, 8
         lea   di, es:[bx].TpId
         push  si
         lea   si, ds:[si].TpID
         rep   movsb
         pop   si

;*  LuParm.LuId = CRTP.LuID

         mov   cx, 8
         lea   di, es:[bx].LuId
         push  si
         lea   si, ds:[si].LuID
         rep   movsb
         pop   si

;* Copy Transaction Program Name

         mov   cx, 40
         lea   di, es:[bx].TpNm
         push  si
         lea   si, ds:[si].Tpn
         rep   movsb
         pop   si

;*  Copy ConvID

         mov   ax, WORD PTR ds:[si].ConvID
         mov   WORD PTR es:[bx], ax
         mov   ax, WORD PTR ds:[si].ConvID + 2
         mov   WORD PTR es:[bx + 2], ax

;*  AplParm.PgmSt = 1;

         mov   bx, OFFSET AplParm
         mov   es:[bx].PgmSt, 1

         @RestoreRegs
         iret
TpE      ENDP

         END   Apl
