Category : Files from Magazines
Archive   : ISSUE-38.ZIP
Filename : CING-38.FIG
/**************************************************************************/
Figure 1 - In-Line Assembly Code for exec() Function
#pragma inline
/**************/
exec(char *program, char *argument) /* new ANSI way of declaring args */
{
/* The rules of this game are rather too involved to explain here. See
Ray Duncan's Advanced MSDOS
of the MSDOS's ``exec'' function. This is done in the ``large'' model so
pointers will all be 4 bytes long and coding will be straightforward.*/
char comline[30]; /* to construct command line */
struct{ /* structure needed by DOS 0x4b service */
unsigned envseg;
char *command,*fcb1,*fcb2;
} paramblock,*pbptr;
paramblock.envseg=0; /* keep the old environment */
comline[0] = strlen(argument); /* first char: length of line */
strcpy(comline+1,argument);
strcat(comline,"\r"); /* terminate with 0xd */
paramblock.command = comline;
paramblock.fcb1=paramblock.fcb2=(char *)0xffffffff; /* Ignore fcb's */
pbptr = ¶mblock;
asm push ds /* DS & BP must be saved. Turbo saves SI & DI */
asm push bp
/* The next two routines work because this is the LARGE model and
pointers are 32-bit entities and work with lds & les. Cute, no? */
asm lds dx,program /* DS:DX pointed to program path */
asm les bx,pbptr /* ES:BX pointed to parameter structure */
asm mov word ptr cs:fill[0],ss /* save SS & SP */
asm mov word ptr cs:fill[2],sp
asm jmp next
asm fill dw 0,0 /* store SS & SP in code segment */
next:
asm mov al,0
asm mov ah,4bh
asm int 21h /* do exec call */
asm cli
asm mov ss,cs:fill[0] /* restore SS & SP */
asm mov sp,cs:fill[2]
asm sti
asm pop bp
asm pop ds
}
/*******************************************************************/
/*Figure 2 - Getting Rid of Resident Programs*/
/* LARGE MODEL USED SO POINTERS ARE 32 BITS.
This compiles to 5.6K, which supports Borland's claim to
relatively tight code. Incidentally, I can do the same in 2.3K in DeSmet C
and about 1K in assembler. Neither coding is half so simple, however.
This sort of direct manipulation of MSDOS allocation headers
is an example of ill-behaved programming at its most incorrigible. But don't
long C pointers make crime EASY??*/
#include
#include
#define RSHIFT 1 /* corresponding bits on shift state byte @ 00:417H */
#define LSHIFT 2
#define ALT 8
#define TESTIT (RSHIFT | LSHIFT | ALT)
#define TICKINT 8
#define NEWTICK 0x80
#define FINI 0x5a
char intable[0x400],*shiftptr=(char *) 0x417L;
typedef struct { /* MSDOS allocation header format */
char flag; /* Either 5Ah for end or 4Dh for not end */
unsigned nextpsp,paragraphs;
} HEAD;
HEAD *header;
extern unsigned _psp;
unsigned meminstall; /* how much memory is installed in PC? */
/******************/
void interrupt tickhandler()
{ /* check shift state for three shifts depressed */
if( (*shiftptr & TESTIT) == TESTIT) deallocate();
geninterrupt(NEWTICK); /* chain the interrupt */
}
/***************/
deallocate()
{
HEAD *nextheader;
/* _AX is a "pseudovariable" which can be used to get or change
the value stored in AX. The possibilities are mind-boggling. */
_AX=0xe00+7; /* just a beep to show something happened */
geninterrupt(0x10);
memcpy(NULL,intable,0x400); /* restore old int table */
nextheader = MK_FP(_psp + header->paragraphs,0);
nextheader->flag = FINI; /* tell MSDOS that everything's free above */
nextheader->nextpsp = 0;
nextheader->paragraphs = meminstall - 1 - _psp - header->paragraphs;
}
/*********************/
main()
{
char **newtick,**oldtick; /*just so it's 32 bits. char * is a convenience. */
header = MK_FP(_psp - 1, 0); /* point to TSR's allocation header */
newtick = MK_FP(0,4*NEWTICK); /* swap interrupt vectors */
oldtick = MK_FP(0,4*TICKINT);
disable(); /* stop hardware */
*newtick = *oldtick;
*oldtick = (char *) tickhandler; /* put interrupt address into table */
enable();
memcpy(intable,NULL,0x400); /* save old interrupt table */
geninterrupt(0x12); /*how much memory installed? */
meminstall = _AX*0x40; /* store amount in paragraphs */
/* Note that TurboC concatenates strings for you. */
puts("\nDEINSTALLATION PROGRAM INSTALLED\n"
" Press Alt-Leftshift-Rightshift\n"
"to deinstall subsequent resident programs.\n" );
keep(0,_SS - _psp +1); /* lop off stack, terminate & stay...*/
}/* keep(0,n) uses DOS function 31h to set aside n paragraphs of memory */
/********************/
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/