home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c221 / 5.ddi / MWHC.005 / E1 < prev    next >
Encoding:
Text File  |  1992-01-07  |  4.1 KB  |  116 lines

  1. /*
  2.  *   msdos.cf -- non-ANSI 
  3.  *
  4.  *   Declares types and functions to be used to make MS-DOS system calls. 
  5.  *
  6.  *           Copyright (c) 1990, MetaWare Incorporated
  7.  */
  8.  
  9. #ifndef _MSDOS_CF
  10. #define _MSDOS_CF
  11.  
  12. #include <implemen.cf>
  13. #include <language.cf>
  14.  
  15. #pragma Global_aliasing_convention(_Private_routine_prefix "%r");
  16.  
  17. /*
  18.    Use these routines to communicate directly with MS-DOS if the
  19.    routines supplied in the SYSTEM package are insufficient.
  20.    To call MSDOS:  Set the Register values the way you want them in
  21.    the global Registers struct.
  22.    Then, call CALLDOS.    CALLDOS will load the actual machine
  23.    registers with the values in the register block below.
  24.    Upon return, the Registers will contain the register contents
  25.    when DOS returned.  The Flags word contains the contents of the
  26.    808x flags register after MS-DOS returns.
  27.    As a variation, CALLINT will call an arbitrary interrupt number,
  28.    using the registers in a similar way.  E.g., CALLINT(#21) = CALLDOS().
  29. */
  30.    #pragma data(common,_Private_prefix "dosregs");
  31.    typedef union {
  32.      struct {char L,H;} LH;   /* Lower & Upper portions of 16-bit register. */
  33.      unsigned R;          /* Entire register. */
  34.      unsigned short W;        /* Lower 16 bits portion of 32-bit 
  35.                       register, for 386. */
  36.      } Register;
  37.    typedef struct {
  38.       Register AX,BX,CX,DX,SI,DI,DS,ES;
  39.       /* The rightmost bit of Flags is the carry bit.  MS-DOS usually sets */
  40.       /* carry if an error occurs.                       */
  41.       /* Thus, if Flags is odd on return, an error occurred;           */
  42.       /* ax contains the error number #.                   */
  43.       unsigned Flags;
  44.       } DOS_communication;
  45. /*
  46.    Here are the registers to modify.  You can either assign into
  47.    these registers directly, or create your own DOS_communication
  48.    block of registers and assign that block into Registers before
  49.    calling CALLDOS.
  50. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  51. >> WARNING!!!  The run-time library uses CALLDOS and this Registers      <<
  52. >> variable.  So DO NOT expect it to be preserved across calls to        <<
  53. >> the library that require DOS communication (e.g., Professional Pascal <<
  54. >> "writeln" or High C "printf").                                        <<
  55. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  56. */
  57.    DOS_communication Registers;
  58.    #pragma data;
  59.  
  60. #pragma Calling_convention(PASCAL);
  61.    /* Use this for your own direct communication with MS-DOS. */
  62.    extern void calldos();
  63.    extern void callint(int interrupt);
  64.    
  65.    /* This gets the value of the DS register.  Use it with small-data */
  66.    /* models to set Registers.DS, since the Adr function returns only */
  67.    /* the 16-bit offset. */
  68.    extern unsigned getds();
  69.  
  70. #pragma Global_aliasing_convention();
  71. #pragma Calling_convention();
  72.  
  73. #if 0
  74. Here-s an extended example of how to use "calldos":
  75. #include <msdos.cf>
  76. int KB_status(char *C) {
  77.    Registers.AX.LH.H = 0xB;
  78.    calldos();
  79.    *C = Registers.AX.LH.L;
  80.    return *C != 0;
  81.    }
  82. int KB_input_no_echo() {
  83.    Registers.AX.LH.H = 0x8;
  84.    calldos();
  85.    return Registers.AX.LH.L;
  86.    }
  87. void KB_write_char(char C) {
  88.    Registers.AX.LH.H = 2; Registers.DX.LH.L = C;
  89.    calldos();
  90.    }
  91. void KB_write_string(char *S) {
  92.    union {void *A; struct {int Offset; short Segment;} Word; } Cheat;
  93.       /* Segment not present in small-data models. */
  94.    Registers.AX.LH.H = 0x9;
  95.    Cheat.A = S;
  96.    Registers.DX.R = Cheat.Word.Offset;
  97.    /* A little tricky here:  must set Registers.DS to the segment
  98.     * value for S if non-small-data; otherwise, to the current value of DS.
  99.     * That's the reason for the getds function.
  100.     */
  101.    if (sizeof(S) > sizeof(int)) Registers.DS.R = Cheat.Word.Segment;
  102.    else Registers.DS.R = getds();
  103.    calldos(); 
  104.    }
  105. main() {
  106.    int I,J; char C;
  107.    while (!KB_status(&C)) {
  108.       for (I = 1; I <= 3000; I++) J = I;
  109.       KB_write_string("I'm waiting for you to type a character...\r\n$");
  110.       }
  111.    KB_write_string("Thank you for typing the character:$");
  112.    KB_write_char(KB_input_no_echo());
  113.    }
  114. #endif
  115. #endif /* _MSDOS_CF */
  116.