home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 1.ddi / WINLBSRC.ZIP / INT86.CAS < prev    next >
Encoding:
Text File  |  1992-06-10  |  6.4 KB  |  208 lines

  1. /*-----------------------------------------------------------------------*
  2.  * filename - int86.cas
  3.  *
  4.  * function(s)
  5.  *        int86  - general 8086 software interrupt interface
  6.  *        int86x - general 8086 software interrupt interface
  7.  *-----------------------------------------------------------------------*/
  8.  
  9. /*
  10.  *      C/C++ Run Time Library - Version 5.0
  11.  *
  12.  *      Copyright (c) 1987, 1992 by Borland International
  13.  *      All Rights Reserved.
  14.  *
  15.  */
  16.  
  17. #pragma inline
  18. #include <asmrules.h>
  19. #include <dos.h>
  20. #include <_io.h>
  21.  
  22. #if defined(_Windows)
  23. void far pascal AllocDStoCSAlias(void);
  24. void far pascal FreeSelector(void);
  25. void far pascal GlobalFix(void);
  26. void far pascal GlobalUnfix(void);
  27. #endif
  28.  
  29. /*-----------------------------------------------------------------------*
  30.  
  31. Name            int86  - general 8086 software interrupt interface
  32.  
  33. Usage           int int86(int intr_num, union REGS *inregs,
  34.                           union REGS *outregs);
  35.  
  36. Prototype in    dos.h
  37.  
  38. Description     Both of these functions execute an 8086 software
  39.                 interrupt specified by the argument intr_num.
  40.  
  41.                 Before executing the software interrupt, both functions
  42.                 copy register values from inregs into the registers.
  43.  
  44.                 In addition, int86x copies the segregs->x.ds and
  45.                 segregs->x.es values into the corresponding registers
  46.                 before executing the software interrupt. This feature
  47.                 allows programs that use far pointers, or that use a
  48.                 large data memory model, to specify which segment is
  49.                 to be used during the software interrupt.
  50.  
  51.                 After the software interrupt returns, both functions
  52.                 copy the current register values to outregs, copy the
  53.                 status of the system carry flag to the x.cflag field
  54.                 in outregs, and copy the value of the 8086 flags register
  55.                 to the x.flags field in outregs.  In addition, int86x
  56.                 restores DS, and sets the segregs->es and segregs->ds
  57.                 fields to the values of the corresponding segment
  58.                 registers.
  59.  
  60.                 If the carry flag is set, it indicates that an error
  61.                 occurred.
  62.  
  63.                 int86x allows you to invoke an 8086 software interrupt
  64.                 that takes a value of DS different from the default data
  65.                 segment, and/or that takes an argument in ES.
  66.  
  67.                 Note that inregs can point to the same structure that
  68.                 outregs points to.
  69.  
  70. Return value    int86 and int86x return the value of AX after completion
  71.                 of the software interrupt. If the carry flag is set
  72.                 (outregs->x.cflag != 0), indicating an error, these
  73.                 functions set _doserrno to the error code.
  74.  
  75. *------------------------------------------------------------------------*/
  76. int int86(int intno, union REGS *inregs, union REGS *outregs)
  77. {
  78.         struct  SREGS   s;
  79.  
  80.         segread(&s);
  81.         return(int86x(intno, inregs, outregs, &s));
  82. }
  83.  
  84. /*-----------------------------------------------------------------------*
  85.  
  86. Name            int86x  - general 8086 software interrupt interface
  87.  
  88. Usage           int int86x(int intr_num, union REGS *inregs,
  89.                           union REGS *outregs,struct SREGS *segregs);
  90.  
  91. Prototype in    dos.h
  92.  
  93. Description     see int86 above.
  94.  
  95. Return value    int86 and int86x return the value of AX after completion
  96.                 of the software interrupt. If the carry flag is set
  97.                 (outregs->x.cflag != 0), indicating an error, these
  98.                 functions set _doserrno to the error code.
  99.  
  100. *------------------------------------------------------------------------*/
  101. int int86x(int intno, union REGS *inregs, union REGS *outregs,
  102.            struct SREGS *segregs)
  103. {
  104.         void    (far * Vector)(void);
  105.         char    Code[10];
  106.  
  107.         /* Save caller context */
  108.  
  109. asm     push    ds
  110.  
  111.         /* Prepare Interrupt call */
  112.  
  113. asm     mov     byte ptr Code, 055h
  114. asm     mov     byte ptr Code+1, 0CDh
  115. asm     mov     ax, intno
  116. asm     mov     byte ptr Code+2, al
  117. asm     mov     word ptr Code+3, 0CB5Dh
  118. asm     cmp     al, 025h
  119. asm     jb      InitVector
  120. asm     cmp     al, 026h
  121. asm     ja      InitVector
  122. asm     mov     byte ptr Code+3, 036h
  123. asm     mov     word ptr Code+4, 0068Fh
  124. asm     mov     word ptr Code+6, cx
  125. asm     mov     word ptr Code+8, 0CB5Dh
  126.  
  127.         /* Set up the vector to our interrupt function */
  128.  
  129. InitVector:
  130. asm     lea     cx, Code
  131. asm     mov     word ptr Vector, cx
  132.  
  133. #if !defined( _Windows )
  134. asm     mov     word ptr Vector+2, ss
  135. #else
  136. asm     push    ss
  137.         GlobalFix();
  138. asm     push    ss
  139.         AllocDStoCSAlias();
  140. asm     mov     word ptr Vector+2, ax
  141. #endif
  142.  
  143.         /* Set registers with register structure content */
  144.  
  145. asm     LDS_    si, segregs
  146. asm     push    [si].es
  147. asm     push    [si].ds
  148. asm     LDS_    si, inregs
  149. asm     mov     ax, [si].ax
  150. asm     mov     bx, [si].bx
  151. asm     mov     cx, [si].cx
  152. asm     mov     dx, [si].dx
  153. asm     mov     di, [si].di
  154. asm     mov     si, [si].si
  155. asm     pop     ds
  156. asm     pop     es
  157.  
  158.         /* Call the interrupt routine */
  159.  
  160. asm     push    bp          /* Just to be safe */
  161.         (* Vector)();
  162. asm     pop     bp
  163.  
  164.         /* Set register structure with registers */
  165.  
  166. asm     pushf
  167. asm     pushf
  168. asm     push    si
  169. asm     push    ds
  170. asm     push    es
  171. #if     !LDATA
  172. asm     mov     ds, [bp-20]
  173. #endif
  174. asm     LDS_    si, segregs
  175. asm     pop     [si].es
  176. asm     pop     [si].ds
  177. asm     LDS_    si, outregs
  178. asm     pop     [si].si
  179. asm     pop     [si].flags
  180. asm     pop     [si].cflag
  181. asm     and     word ptr [si].cflag, 1
  182. asm     mov     [si].di, di
  183. asm     mov     [si].dx, dx
  184. asm     mov     [si].cx, cx
  185. asm     mov     [si].bx, bx
  186. asm     mov     [si].ax, ax
  187.  
  188. #if defined( _Windows )
  189. asm     pushf           /* save state of carry test */
  190. asm     push    ax      /* save AX */
  191. asm     push    word ptr Vector+2
  192.         FreeSelector();
  193. asm     push    ss
  194.         GlobalUnfix();
  195. asm     pop     ax      /* restore AX */
  196. asm     popf            /* restore state of carry test */
  197. #endif
  198.  
  199. asm     pop     ds
  200. asm     jz      int86Ok
  201. asm     push    ax
  202.         __IOerror(_AX);
  203. asm     pop     ax
  204.  
  205. int86Ok:
  206.         return(_AX);
  207. }
  208.