home *** CD-ROM | disk | FTP | other *** search
- /*
- * msdos.cf -- non-ANSI
- *
- * Declares types and functions to be used to make MS-DOS system calls.
- *
- * Copyright (c) 1990, MetaWare Incorporated
- */
-
- #ifndef _MSDOS_CF
- #define _MSDOS_CF
-
- #include <implemen.cf>
- #include <language.cf>
-
- #pragma Global_aliasing_convention(_Private_routine_prefix "%r");
-
- /*
- Use these routines to communicate directly with MS-DOS if the
- routines supplied in the SYSTEM package are insufficient.
- To call MSDOS: Set the Register values the way you want them in
- the global Registers struct.
- Then, call CALLDOS. CALLDOS will load the actual machine
- registers with the values in the register block below.
- Upon return, the Registers will contain the register contents
- when DOS returned. The Flags word contains the contents of the
- 808x flags register after MS-DOS returns.
- As a variation, CALLINT will call an arbitrary interrupt number,
- using the registers in a similar way. E.g., CALLINT(#21) = CALLDOS().
- */
- #pragma data(common,_Private_prefix "dosregs");
- typedef union {
- struct {char L,H;} LH; /* Lower & Upper portions of 16-bit register. */
- unsigned R; /* Entire register. */
- unsigned short W; /* Lower 16 bits portion of 32-bit
- register, for 386. */
- } Register;
- typedef struct {
- Register AX,BX,CX,DX,SI,DI,DS,ES;
- /* The rightmost bit of Flags is the carry bit. MS-DOS usually sets */
- /* carry if an error occurs. */
- /* Thus, if Flags is odd on return, an error occurred; */
- /* ax contains the error number #. */
- unsigned Flags;
- } DOS_communication;
- /*
- Here are the registers to modify. You can either assign into
- these registers directly, or create your own DOS_communication
- block of registers and assign that block into Registers before
- calling CALLDOS.
- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
- >> WARNING!!! The run-time library uses CALLDOS and this Registers <<
- >> variable. So DO NOT expect it to be preserved across calls to <<
- >> the library that require DOS communication (e.g., Professional Pascal <<
- >> "writeln" or High C "printf"). <<
- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
- */
- DOS_communication Registers;
- #pragma data;
-
- #pragma Calling_convention(PASCAL);
- /* Use this for your own direct communication with MS-DOS. */
- extern void calldos();
- extern void callint(int interrupt);
-
- /* This gets the value of the DS register. Use it with small-data */
- /* models to set Registers.DS, since the Adr function returns only */
- /* the 16-bit offset. */
- extern unsigned getds();
-
- #pragma Global_aliasing_convention();
- #pragma Calling_convention();
-
- #if 0
- Here-s an extended example of how to use "calldos":
- #include <msdos.cf>
- int KB_status(char *C) {
- Registers.AX.LH.H = 0xB;
- calldos();
- *C = Registers.AX.LH.L;
- return *C != 0;
- }
- int KB_input_no_echo() {
- Registers.AX.LH.H = 0x8;
- calldos();
- return Registers.AX.LH.L;
- }
- void KB_write_char(char C) {
- Registers.AX.LH.H = 2; Registers.DX.LH.L = C;
- calldos();
- }
- void KB_write_string(char *S) {
- union {void *A; struct {int Offset; short Segment;} Word; } Cheat;
- /* Segment not present in small-data models. */
- Registers.AX.LH.H = 0x9;
- Cheat.A = S;
- Registers.DX.R = Cheat.Word.Offset;
- /* A little tricky here: must set Registers.DS to the segment
- * value for S if non-small-data; otherwise, to the current value of DS.
- * That's the reason for the getds function.
- */
- if (sizeof(S) > sizeof(int)) Registers.DS.R = Cheat.Word.Segment;
- else Registers.DS.R = getds();
- calldos();
- }
- main() {
- int I,J; char C;
- while (!KB_status(&C)) {
- for (I = 1; I <= 3000; I++) J = I;
- KB_write_string("I'm waiting for you to type a character...\r\n$");
- }
- KB_write_string("Thank you for typing the character:$");
- KB_write_char(KB_input_no_echo());
- }
- #endif
- #endif /* _MSDOS_CF */
-