home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mega CD-ROM 1
/
megacd_rom_1.zip
/
megacd_rom_1
/
DESQVIEW
/
DVGLU101.ZIP
/
TVJNEW.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-08-13
|
6KB
|
182 lines
/*=======================================================*/
/* TVJNEW.C */
/* */
/* (c) Copyright 1988 Ralf Brown All Rights Reserved */
/* May be freely copied for noncommercial use, so long */
/* as this copyright notice remains intact, and any */
/* changes are marked in the comment blocks preceding */
/* functions. */
/*=======================================================*/
#pragma inline
#include <string.h>
#include "tvapi.h"
static int _TV_newapp_mutex_ = 0 ;
static void far (*entry_point)(void) ;
/*======================================================*/
struct EXEC_block {
int env ; /* segment of environment */
char far *cmdline ;
struct fcb far *fcb_1 ;
struct fcb far *fcb_2 ;
void far *stack ;
void far (*entry_pt)(void) ;
} ;
/*======================================================*/
/*======================================================*/
static void far terminate(void)
{
TVtask_free(NIL) ; /* kill task for terminated program */
geninterrupt(0x20) ; /* insurance */
}
/*======================================================*/
/* do final cleanup before jumping to program's entry */
/* point */
/*======================================================*/
static void far launch_app(int parent)
{
(void) parent ;
setvect(0x22,(void interrupt (*)(void)) terminate) ;
asm xor ax,ax
asm push ax /* for programs expecting a 0 on top of the stack */
asm push word ptr entry_point+2
asm push word ptr entry_point
asm mov ah,62h /* get PSP segment */
asm int 21h
asm mov es,bx /* DS = ES = PSP */
asm mov word ptr es:[0Ah],offset terminate
asm mov word ptr es:[0Ch],cs
asm mov word ptr es:[16h],bx /* turn PSP into a parent PSP */
_TV_newapp_mutex_ = 0 ; /* allow another call to TVspawn... */
asm mov ds,bx /* set up segment registers for program */
asm ret /* and jump to entry point */
}
/*======================================================*/
/* TVspawnve create new application in current process */
/* Ralf Brown 5/10/88 */
/* Ralf Brown 8/6/88 made it use vararg list, and */
/* renamed to TVspawnve. TVapp_new now */
/* calls this function */
/* Ralf Brown 8/12/88 complete overhaul to hopefully */
/* cure random crashing (not done yet) */
/*======================================================*/
OBJECT pascal TVspawnve(OBJECT win,int row,int col,int rows,int cols,
int switch_menu,char *program,va_list args,int env)
{
OBJECT new_app ;
register char *arg ;
register int cmd_len = 0 ;
struct EXEC_block exec_block ;
char cmd_line[128] ;
struct fcb fcb1 ;
struct fcb fcb2 ;
char far *new_program = (char far *)program ;
/* set up the exec parameter block */
exec_block.env = env ;
exec_block.cmdline = (char far *)cmd_line ;
exec_block.fcb_1 = (struct fcb far *)&fcb1 ;
exec_block.fcb_2 = (struct fcb far *)&fcb2 ;
/* then concatenate the args to form the commandline */
(void) va_arg( args, char * ) ; /* skip argv[0] */
while ((arg = va_arg(args, char *)) != NULL)
{
if (cmd_len >= 126)
{
cmd_len = 126 ;
break ;
}
else
cmd_line[++cmd_len] = ' ' ; /* separate args by blanks */
while (*arg && cmd_len < 126)
cmd_line[++cmd_len] = *arg++ ;
}
cmd_line[cmd_len+1] = '\r' ;
cmd_line[0] = cmd_len ;
/* now set up the FCBs */
arg = parsfnm( cmd_line+1, &fcb1, 1 ) ; /* 1=ignore leading separators */
if (arg) /* was first parse successful? */
(void) parsfnm( arg, &fcb2, 1 ) ;
/* load the program, but don't execute it yet */
_doserrno = 0 ; /* assume no error */
asm push ds
asm lds dx,new_program
asm mov bx,ss
asm mov es,bx
asm lea bx,exec_block
asm mov ax,4b01h /* load but don't execute, DOS 3.x/DESQview version */
asm int 21h /* 4b02h on DOS 2.x, but DV takes it over and uses 4b01 */
asm pop ds
asm jnc no_error
_doserrno = _AX ;
return NIL ;
no_error:
/* we'll be overwriting static vars, so can only have one copy here at a time */
busy_wait:
asm mov ax,1
asm lock xchg ax,_TV_newapp_mutex_
asm or ax,ax
asm jz wait_done
TVpause() ;
asm jmp busy_wait
wait_done:
entry_point = exec_block.entry_pt ;
/* and launch the program if load was successful */
new_app = TVtask_new(win,NULL,row,col,rows,cols,exec_block.stack,0,
launch_app,switch_menu) ;
if (new_app)
{
while (_TV_newapp_mutex_)
TVpause() ;
TVtask_post(new_app) ; /* make sure the task is running */
}
#if 0
_AH = 0x50 ; /* need to restore our PSP segment */
_BX = _psp ; /* as known to DOS */
geninterrupt(0x21) ;
#endif 0
return new_app ;
}
/*======================================================*/
/* TVapp_new create new application in current process */
/* Ralf Brown 5/10/88 */
/*======================================================*/
OBJECT cdecl TVapp_new(OBJECT win,int row,int col,int rows,int cols,
int switch_menu,char *program, ...)
{
return TVspawnve(win,row,col,rows,cols,switch_menu,program,_va_ptr,0) ;
}
/*======================================================*/
/*======================================================*/
OBJECT cdecl TVspawnle(OBJECT win,int row,int col,int rows,int cols,
int switch_menu,char **env,char *program, ...)
{
int env_seg ;
env_seg = 0 ; /* until I figure out how to set it */
return TVspawnve(win,row,col,rows,cols,switch_menu,program,_va_ptr,env_seg) ;
}
/* End of TVJNEW.C */