Metropoli BBS
VIEWER: pmccex2.c MODE: TEXT (CP437)
/*
   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;
}

[ RETURN TO DIRECTORY ]