/*
This program just hooks INT 16h and increments a byte on the screen every
time INT 16h is called in real mode. It executes COMMAND.COM, when you exit
that, the program terminates.
*/
/*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
INTERFACE
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒*/
#include "pmc.h"
// Minimize memory used.
int _extheapmax = 0;
int _lowbuflen = 1024;
int _PMrmstacks = 1;
int _PMpmstacks = 1;
int _pmcrmstacklen = 0;
int _rmcpmstacklen = 0;
int _pmcrmstacks = 0;
int _rmcpmstacks = 0;
REGSTRUCT *__pascal cint16 (REGSTRUCT *r);
/*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
DATA
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒*/
REGSTRUCT rs2;
SEGOFF ormiv, cb;
/*▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
CODE
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒*/
//════════════════════════════════════════════════════════════════════════════
void __cdecl PMmain (void)
{
PTR p0, p1;
// Set up DPMI callback C function.
p0 = setcb (&cb, NULL, &rs2, cint16);
// Get old INT 16h address and set new to callback just allocated.
iv_rmget (0x16, &ormiv);
iv_rmset (0x16, cb.off, cb.seg);
// Execute command shell (COMMAND.COM). Can't use the value from the getenv
// function directly because it is int the low memory buffer area which is
// used by the fileexec function.
fileexec (p1 = strdup (getenv ("COMSPEC")), NULL);
// Reset old INT 16h handler.
iv_rmset (0x16, ormiv.off, ormiv.seg);
// Free DPMI callback and duplicated string.
free (p1);
resetcb (SEGOFFtoDWORD (cb), p0);
}
/*░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
INT 16h protected mode handler.
In:
REGSTRUCT *r = register structure containing real mode register values
Out:
REGSTRUCT * = register structure containing real mode register values
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░*/
REGSTRUCT *__pascal cint16 (REGSTRUCT *r)
{
(*(BYTE *)rlp (0xb8000)) ++;
// Set real mode resume address to old real mode INT 16h handler.
r->d.CSIP = SEGOFFtoDWORD (ormiv);
return r;
}