home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c329 / 2.img / EXAMPLES / CALLM1.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-06  |  3.4 KB  |  125 lines

  1. /*
  2.  * CALLM1.C
  3.  * Purpose: calls real mode TSR via interrupt
  4.  * Copyright (C) MicroWay, Inc. 1989
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <dos.h>
  9.  
  10. /* The real mode Interrupt Service Routine (ISR) is 
  11.  * table-driven. The calling program invokes the
  12.  * various routines by passing an index into the
  13.  * table via the ax register.
  14.  */
  15. #define INIT_TEST 0
  16. #define FIRST_TEST_MSG 1
  17. #define LAST_TEST_MSG 3
  18. #define SHARE_BUFFER LAST_TEST_MSG+1
  19. #define MSG_LEN 80
  20.  
  21. union REGS inregs, outregs;    /* used by int386() */
  22. int intnum;
  23. short int i;
  24. char *pdb;        /* pointer to real mode data buffer */
  25. extern void blk_mb();
  26. extern void blk_bm();
  27.  
  28. /* This program makes extensive use of Phar Lap's 
  29.  * DOS Extender Function 0x25, subfunction 0x11,
  30.  * Issue Real Mode Interrupt. See the appropriate
  31.  * section of the Phar Lap manual. The struct defined
  32.  * below serves as the parameter block to be passed
  33.  * to that subfunction.
  34.  */
  35. struct PB {
  36.     unsigned short intnum;
  37.     unsigned short ds;
  38.     unsigned short es;
  39.     unsigned short fs;
  40.     unsigned short gs;
  41.     unsigned short ax;
  42.     unsigned short axextended;
  43.     unsigned short dx;
  44.     unsigned short dxextended;
  45. } parm_block = {0,0,0,0,0,0,0,0,0};
  46.  
  47. #define RM_INTNUM 0x48        /* Real Mode Interrupt Number */
  48.  
  49. char out_msg [] = "Hello";
  50. char in_msg [MSG_LEN];
  51.  
  52. void main (argc,argv)
  53. int argc;
  54. char *argv[];
  55.  
  56. {
  57. /* This program uses int386() to issue the Int 0x21,
  58.  * function 0x25. Any calls to real mode code must
  59.  * go through Phar Lap's DOS Extender, i.e., we can
  60.  * not issue a real mode interrupt directly via int386().
  61.  */
  62.     intnum = 0x21;
  63.     inregs.b.cl = RM_INTNUM;
  64. /* Get Real Mode Interrupt Vector  */    
  65.     inregs.w.ax = 0x2503;
  66.     int386 (&intnum,&inregs,&outregs);
  67. /* If vector is zero, definitely an error. However, a non-zero
  68.  * value does not prove everything okay. We could make a more
  69.  * stringent test, but in this example it didn't seem worthwhile
  70.  */
  71.     if (outregs.d.ebx == 0) {
  72.         printf ("Real Mode Interrupt not installed\n\7");
  73.         exit(1);
  74.     }
  75.     
  76.     outregs.w.ax = -1;    /* initialize with error value */
  77.  
  78. /* Call the real mode routine for the first time. If all is
  79.  * okay, it will pass back the address of a real mode buffer.
  80.  * We can access that buffer from protected mode by using
  81.  * segment selector 0x34, which maps to the first megabyte
  82.  * of memory
  83.  */
  84.     parm_block.intnum = RM_INTNUM;
  85.     parm_block.ax = INIT_TEST;
  86.     (struct PB *) inregs.d.edx = &parm_block;    
  87.     inregs.w.ax = 0x2511;
  88.     int386 (&intnum,&inregs,&outregs);
  89.     
  90.     if (outregs.w.ax != 0) {
  91.         printf ("Problem in Real Mode Interrupt\n\7");
  92.     }
  93.     else {
  94.         pdb = (char *) ((outregs.w.cx << 4) + outregs.w.bx);
  95.         printf ("address of data buffer = %x\n",pdb);
  96.     }
  97.  
  98. /*  Call real mode routine to output the test messages */
  99.     for (i = FIRST_TEST_MSG; i <= LAST_TEST_MSG; i++) {
  100.         parm_block.ax = i;
  101.         int386 (&intnum,&inregs,&outregs);
  102.     }
  103.     
  104. /* Move output message defined in the C program
  105.  * into data buffer. Real mode routine will output the
  106.  * message and move a new message which was defined in
  107.  * the real mode program into the shared buffer. Note
  108.  * that the real mode routine expects a null-terminated
  109.  * string.
  110.  */
  111.     blk_bm(out_msg,0x34,pdb,strlen(out_msg)+1);
  112.     parm_block.ax = SHARE_BUFFER;
  113.     int386 (&intnum,&inregs,&outregs);
  114.  
  115. /* Move new message from data buffer into char
  116.  * array and display it, to prove the process
  117.  */    
  118.     blk_mb(in_msg,0x34,pdb,MSG_LEN);
  119.     printf("\n%s\n",in_msg);
  120.  
  121.     exit(0);
  122.  
  123. }
  124.     
  125.