home *** CD-ROM | disk | FTP | other *** search
- /*
- * CALLM1.C
- * Purpose: calls real mode TSR via interrupt
- * Copyright (C) MicroWay, Inc. 1989
- */
-
- #include <stdio.h>
- #include <dos.h>
-
- /* The real mode Interrupt Service Routine (ISR) is
- * table-driven. The calling program invokes the
- * various routines by passing an index into the
- * table via the ax register.
- */
- #define INIT_TEST 0
- #define FIRST_TEST_MSG 1
- #define LAST_TEST_MSG 3
- #define SHARE_BUFFER LAST_TEST_MSG+1
- #define MSG_LEN 80
-
- union REGS inregs, outregs; /* used by int386() */
- int intnum;
- short int i;
- char *pdb; /* pointer to real mode data buffer */
- extern void blk_mb();
- extern void blk_bm();
-
- /* This program makes extensive use of Phar Lap's
- * DOS Extender Function 0x25, subfunction 0x11,
- * Issue Real Mode Interrupt. See the appropriate
- * section of the Phar Lap manual. The struct defined
- * below serves as the parameter block to be passed
- * to that subfunction.
- */
- struct PB {
- unsigned short intnum;
- unsigned short ds;
- unsigned short es;
- unsigned short fs;
- unsigned short gs;
- unsigned short ax;
- unsigned short axextended;
- unsigned short dx;
- unsigned short dxextended;
- } parm_block = {0,0,0,0,0,0,0,0,0};
-
- #define RM_INTNUM 0x48 /* Real Mode Interrupt Number */
-
- char out_msg [] = "Hello";
- char in_msg [MSG_LEN];
-
- void main (argc,argv)
- int argc;
- char *argv[];
-
- {
- /* This program uses int386() to issue the Int 0x21,
- * function 0x25. Any calls to real mode code must
- * go through Phar Lap's DOS Extender, i.e., we can
- * not issue a real mode interrupt directly via int386().
- */
- intnum = 0x21;
- inregs.b.cl = RM_INTNUM;
- /* Get Real Mode Interrupt Vector */
- inregs.w.ax = 0x2503;
- int386 (&intnum,&inregs,&outregs);
- /* If vector is zero, definitely an error. However, a non-zero
- * value does not prove everything okay. We could make a more
- * stringent test, but in this example it didn't seem worthwhile
- */
- if (outregs.d.ebx == 0) {
- printf ("Real Mode Interrupt not installed\n\7");
- exit(1);
- }
-
- outregs.w.ax = -1; /* initialize with error value */
-
- /* Call the real mode routine for the first time. If all is
- * okay, it will pass back the address of a real mode buffer.
- * We can access that buffer from protected mode by using
- * segment selector 0x34, which maps to the first megabyte
- * of memory
- */
- parm_block.intnum = RM_INTNUM;
- parm_block.ax = INIT_TEST;
- (struct PB *) inregs.d.edx = &parm_block;
- inregs.w.ax = 0x2511;
- int386 (&intnum,&inregs,&outregs);
-
- if (outregs.w.ax != 0) {
- printf ("Problem in Real Mode Interrupt\n\7");
- }
- else {
- pdb = (char *) ((outregs.w.cx << 4) + outregs.w.bx);
- printf ("address of data buffer = %x\n",pdb);
- }
-
- /* Call real mode routine to output the test messages */
- for (i = FIRST_TEST_MSG; i <= LAST_TEST_MSG; i++) {
- parm_block.ax = i;
- int386 (&intnum,&inregs,&outregs);
- }
-
- /* Move output message defined in the C program
- * into data buffer. Real mode routine will output the
- * message and move a new message which was defined in
- * the real mode program into the shared buffer. Note
- * that the real mode routine expects a null-terminated
- * string.
- */
- blk_bm(out_msg,0x34,pdb,strlen(out_msg)+1);
- parm_block.ax = SHARE_BUFFER;
- int386 (&intnum,&inregs,&outregs);
-
- /* Move new message from data buffer into char
- * array and display it, to prove the process
- */
- blk_mb(in_msg,0x34,pdb,MSG_LEN);
- printf("\n%s\n",in_msg);
-
- exit(0);
-
- }
-
-