/* ---------------------------------------------------------------------- */
/* Online Commander v0.3.Test                       2:5045/37.18@Fidonet  */
/* Copyright (c)1998-99 by Alex Carcass                  carcass@chat.ru  */
/* ---------------------------------------------------------------------- */

? print "þ External processes support...\n"

void PROCESS_FAR_CALL()       // AX = #internal_proc
{ CSWORD[#wVar1] = AX;
  AX><BX; BX><CX; CX><DX; DX><DI; DI><SI;
$ CALL NEAR CSWORD[#wVar1]
$ RETF
}

byte PROCESS_MSG_HANDLE()     // AL = msg; BX = .....
{
$ PUSH DS; DS = PSeg;
$ NOP; $ NOP
$ CALL FAR CSDWORD[#PAddr]
$ POP  DS
  PFlag = AL;
$ OR   AL,AL
$ JNZ  QT
  MSG_SEND(PID); $ XOR AL,AL
QT:
}

void process_update()
{ AL = buf[0]; $ CMP AL,'%'; $ JE QT
  AX = DS; BX = #buf;
$ PUSHA;   GETLPART(,,#s); $ POPA
  CX = BX; GETRPART();
  AL = s[0];   $ CMP  AL,0;  $ JE QT
  STRLEN(#s);
$ PUSH AX;      AX><CX;    MOVE(DS,#s,,xpr_head,wVar1);
$ POP  AX;      wVar1+=AX; SETMEMBYTE(xpr_head,wVar1,' '); wVar1++;
  STRLEN(#buf); AX++;
$ PUSH AX;      AX><CX;    MOVE(DS,#buf,,xpr_head,wVar1);
$ POP  AX;      wVar1+=AX;
QT:
$ CLC
}

byte PROCESS_INIT()
{ PSeg = GETMEM(,0x3FFF);    // 16k-limit
$ PUSH ES
$ MOV  ES,AX
$ XOR  DI,DI
$ MOV  AX,0xFDE8
$ STOSW
$ MOV  AX,0xCB00
$ STOSW
//--------------------
//API+Data access:
//--------------------
$ MOV  AX,DS                 // PSeg:0004 = DS
$ STOSW
$ MOV  AX,#PROCESS_FAR_CALL  // PSeg:0006 = #farcall_proc
$ STOSW
$ MOV  AX,CS                 // PSeg:0008 = CS
$ STOSW
$ MOV  AX,lng_seg            // PSeg:000A = dataseg (16k)
$ STOSW
$ MOV  AX,#usr_info          // PSeg:000C = user_info
$ STOSW
$ MOV  AX,#ComPort           // PSeg:000E = Variables offset
$ STOSW
//--------------------
//Published functions:
//--------------------
$ MOV  DI,0x10
$ MOV  AX,#OUT_SZ            // OUT_SZ(#str)
$ STOSW
$ MOV  AX,#DISPLAY_ANS_FILE  // DISPLAY_ANS_FILE(#buf,#fname)
$ STOSW
$ MOV  AX,#WAITKEY           // word WAITKEY()
$ STOSW
$ MOV  AX,#BATCH_ADD         // BATCH_ADD(#buf)
$ STOSW
$ MOV  AX,#GET_PROMPT        // GET_PROMPT(#buf,idx)
$ STOSW
$ MOV  AX,#DOOR_SPAWN        // DOOR_SPAWN(#commandline)
$ STOSW
$ POP  ES
//-----------------------------------
// External processes/functions init:
//-----------------------------------
  AX = #buf;
$ PUSHA; GET_PROMPT(,CFG_XPROC); wVar1 = 0;
$ POPA;  DX = AX; FREADTEXT(,#process_update,80);
  PFlag = 0; AX = xpr_head;
}

void PROCESS_DONE()
{ IF(PFlag!=0) PROCESS_MSG_HANDLE(M_DONE);
  FREEMEM(PSeg); PFlag = 0;
}

byte PROCESS_LOAD()           // AX = #processname
{ AX><DX;
@_21H(FileOpenRO); AX><BX;    // Read process
  IF(NOTCARRYFLAG)
  { $ PUSH DS
      DS = PSeg;
    @_21H(FileRead,,0x3F00,0x100);      // 16k-limit
    $ POP  DS
    @_21H(FileClose); SI = #buf;
M1: $ LODSB; $ OR  AL,AL; $ JNZ  M1
      SI--;  DSBYTE[SI]=0x0D;
      MOVE(DS,#buf,0x7F,PSeg,0x81);
      PROCESS_MSG_HANDLE(byte M_INIT);
  } ELSE AL = 0;
    PFlag = AL;
}

byte PROCESS_TRY()              // buf ="<alias> [<parametres>]"
{ GETLPART(DS,#buf,#s);                // alias
  GETRPART(DS,#buf,#buf); wVar1 = 0;   // parametres
M1:
  GETMEMWORD(xpr_head,wVar1);   $ DEC  AX; $ JNS  M2; return(1);
M2:
  GETLPART(xpr_head,wVar1,#s1);
  STRCMP(DS,#s,#s1);            $ DEC  AL; $ JS   M3    // process found
  do{ GETMEMBYTE(xpr_head,wVar1); wVar1++;
    } while(AL!=0);
$ JMP  M1
M3:
  GETRPART(xpr_head,wVar1,#s1); PROCESS_LOAD(#s1);
$ XOR  AX,AX
}