1 /* ***********************************************************
 2    *                                                         *
 3    * Copyright, (C) Honeywell Bull Inc., 1987                *
 4    *                                                         *
 5    * Copyright, (C) Honeywell Information Systems Inc., 1986 *
 6    *                                                         *
 7    *********************************************************** */
 8 
 9 /* HISTORY COMMENTS:
10   1) change(86-05-09,Lee), approve(87-07-13,MCR7580), audit(87-07-13,Leskiw),
11      install(87-08-07,MR12.1-1072):
12      Created.
13   2) change(86-05-20,Westcott), approve(87-07-13,MCR7580),
14      audit(87-07-13,Leskiw), install(87-08-07,MR12.1-1072):
15      Provided a return code mechanism.
16                                                    END HISTORY COMMENTS */
17 
18 /* : PROCEDURE FUNCTION (call_mowse_int)
19 
20 Calls one of the MOWSE's interrupt handlers, passing it a parameter
21 structure containing all the required data; all data in the parameter
22 structure is input data as this structure is copied into MOWSE's space
23 (i.e. passing the structure by value).  It is up to the caller to ensure
24 that the structure passed is the same as the structure expected by the
25 interrupt handler.  This provides a general parameter passing mechanism
26 between applications and MOWSE interrupt handlers.
27 */
28 
29 /* : NOTES
30 
31 This is the first inklink of MOWSE that the application sees.
32 */
33 
34 #include <dos.h>
35 #include <ws.h>
36 #include <ws_error.h>
37 
38 #define INTRPT_VECTOR_TABLE   1023     /* Where DOS interrupt vectors live */
39 #define INTRPT_ADDRESS_SIZE   4        /* Number of bytes to the transfer vector */
40 #define SIGNATURE_SIZE        8        /* Size of signature */
41 #define SIGNATURE_ID_OFFSET   4        /* Offset into signature of MOWSE id */
42 
43 int USER_INTERRUPT = 0;                /* user interrupt number (/I to mowse) */
44                                        /*    must be set here at "process" init */
45 int local_system;                      /* system id for local system */
46 
47 call_mowse_int (p_mowse_minor, p_param_addr, p_param_size)
48 
49 int  p_mowse_minor;                    /* Internal function to execute */
50 char *p_param_addr;                    /* Parameter structure for the function */
51 int  p_param_size;                     /* Length of parameter structure */
52 {
53 int segment;                           /* MOWSE code segment */
54 int intoff;                            /* Interrupt address offset */
55 int offset;                            /* Interrupt vectors */
56 union sigun
57 {  int  signature[SIGNATURE_ID_OFFSET];/* MOWSE signature */
58    char csig[SIGNATURE_SIZE];          /* Signature information */
59 } sig;
60 union REGS inregs, outregs;            /* Register information */
61 
62 /* : if USER_INTERRUPT not set (=0 )
63      - scan low memory for user_interrupt_handler signature which signifies
64        where MOWSE resides as a user_interrupt, or does not reside at all */
65 
66    if (USER_INTERRUPT == 0)
67    {  for (offset = 0; offset < INTRPT_VECTOR_TABLE; offset += INTRPT_ADDRESS_SIZE)
68       {  peek (0, offset, &sig.csig[0], SIGNATURE_SIZE);
69          segment = sig.signature[1];
70          intoff  = sig.signature[0] + SIGNATURE_ID_OFFSET;
71          peek (segment, intoff, &sig.csig[0], SIGNATURE_SIZE);
72          if (strcmp (&sig.csig[1],"MOWSE") == 0) break;
73       }
74 
75 /* : If passed the whole table, then MOWSE not found */
76 
77       if (offset > INTRPT_VECTOR_TABLE)
78          return (WSNOTRES);
79 
80 /* : Otherwise convert the address of the offset to an iterrupt number */
81 
82       USER_INTERRUPT = offset >> 2;
83       local_system = (int) sig.csig[0];
84    }
85 
86 /* : Generate the interrupt */
87 
88    inregs.h.ah = p_mowse_minor;                  /* ah = MOWSE minor */
89    inregs.x.si = (short)p_param_addr;            /* si = parameter structure address */
90    inregs.x.cx = p_param_size;                   /* cx = size of parameter */
91    int86(USER_INTERRUPT, &inregs, &outregs);
92    return (outregs.x.ax);                        /* ax = return code */
93 }