home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / GLEN / QB4INT.ZIP / QB4INT.TXT
Text File  |  1989-06-26  |  11KB  |  313 lines

  1. How to Use CALL INTERRUPT with QB 4.x, BC 6.00 (Complete)     [B_QuickBas]
  2.  
  3. 4.00 4.00b 4.50
  4. MS-DOS
  5. MSINTERNAL | appnote softlib SR# S890410-107 B_BasicCom
  6.  
  7. Summary:
  8.  
  9. The application note below is supported by Microsoft QuickBASIC
  10. Versions 4.00, 4.00b, and 4.50 for MS-DOS and Microsoft BASIC
  11. Compiler Versions 6.00 and 6.00b for MS-DOS. This application note,
  12. titled "How to Use CALL INTERRUPT in QB 4.x and BC 6.00," is also
  13. available from Microsoft Product Support Services at (206) 454-2030.
  14.  
  15. This application note is also available (with ENDUSER access) for
  16. customers of on-line services in the Software/Data Library by querying
  17. for the keyword QB4INT.
  18.  
  19. CALL INTERRUPT is a complicated statement that allows programmers
  20. access to low-level MS-DOS and BIOS information and control from
  21. QuickBASIC. Effective use of the complex CALL INTERRUPT interface
  22. requires understanding of the QuickBASIC programming environment, the
  23. BASIC language, and lower-level DOS and BIOS functions. This
  24. application note explains many of these necessary features, including
  25. the following:
  26.  
  27. 1. Libraries and Quick Libraries
  28.  
  29. 2. User-defined TYPEs
  30.  
  31. 3. INCLUDE files
  32.  
  33. 4. CALL INTERRUPT input and output
  34.  
  35. 5. Example of CALL INTERRUPT
  36.  
  37. 6. Differences between CALL INTERRUPT and CALL INTERRUPTX
  38.  
  39. 7. References for documentation on INTERRUPTs
  40.  
  41. The CALL INTERRUPT statement documented in this application note is
  42. supported in Microsoft QuickBASIC 4.00 and later. In QuickBASIC 2.00,
  43. 2.01, and 3.00, CALL INT86 provides access to the BIOS and DOS
  44. INTERRUPTs using an array interface instead of user-defined TYPEs.
  45. CALL INT86 is documented on Pages 148-149 of the "Microsoft QuickBASIC
  46. Compiler" manual for Versions 2.00, 2.01, and 3.00. Although there are
  47. differences, some of the information in this application note will be
  48. useful to those who use QuickBASIC 2.00, 2.01, and 3.00.
  49.  
  50. The CALL INTERRUPT statement is not supported in OS/2 protected mode.
  51. Most of the functions provided by the INTERRUPTs are available in
  52. protected mode, but are accessed through API (application program
  53. interface) calls. The INTERRUPTs will work correctly in OS/2's real
  54. mode, with a few exceptions.
  55.  
  56. More Information:
  57.  
  58. Libraries and Quick Libraries
  59. -----------------------------
  60.  
  61. The object code for the INTERRUPT routines is located in the QB.LIB
  62. library and QB.QLB quick library, which are supplied with QuickBASIC
  63. 4.00, 4.00b, and 4.50 and BASIC compiler 6.00 and 6.00b.
  64.  
  65. The difference between libraries (.LIB) and quick libraries (.QLB) is
  66. that quick libraries are used within the QuickBASIC environment,
  67. whereas libraries are used (at link time) to produce executable
  68. programs.
  69.  
  70. To load a quick library for use with the QuickBASIC environment, you
  71. must enter QuickBASIC with the /L option (e.g. "QB /L QB.QLB"). This
  72. will allow you to make CALLs to the routines in that quick library.
  73. When you choose "Make EXE File..." from the Run menu, your program
  74. will be automatically linked with the library (.LIB) of the same name
  75. as your quick library; in this case, it would be QB.LIB.
  76.  
  77. User-Defined TYPEs
  78. ------------------
  79.  
  80. To use the CALL INTERRUPT statement, you must first create a
  81. user-defined TYPE to contain the registers for the INTERRUPT. The
  82. TYPEs defined in the INCLUDE file (QB.BI) that comes with QuickBASIC
  83. 4.00, 4.00b, and 4.50, are as follows:
  84.  
  85. TYPE RegType
  86.      ax    AS INTEGER
  87.      bx    AS INTEGER
  88.      cx    AS INTEGER
  89.      dx    AS INTEGER
  90.      bp    AS INTEGER
  91.      si    AS INTEGER
  92.      di    AS INTEGER
  93.      flags AS INTEGER
  94. END TYPE
  95.  
  96. TYPE RegTypeX                     ' See NOTE
  97.      ax    AS INTEGER
  98.      bx    AS INTEGER
  99.      cx    AS INTEGER
  100.      dx    AS INTEGER
  101.      bp    AS INTEGER
  102.      si    AS INTEGER
  103.      di    AS INTEGER
  104.      flags AS INTEGER
  105.      ds    AS INTEGER
  106.      es    AS INTEGER
  107. END TYPE
  108.  
  109. Note: RegTypeX is used with the CALL INTERRUPTX statement, which
  110. allows you to specify the DS and ES registers. For more information,
  111. please refer to the section below titled "Differences between CALL
  112. INTERRUPT and CALL INTERRUPTX."
  113.  
  114. INCLUDE Files
  115. -------------
  116.  
  117. To simplify the TYPE definition for INTERRUPTs, the INCLUDE file,
  118. QB.BI, is shipped with QuickBASIC 4.00 and 4.50. This file has the
  119. TYPE definitions (see above) and SUB DECLARations needed for
  120. INTERRUPTs. To use this file, the metacommand $INCLUDE must be placed
  121. at the beginning of your code. The syntax of this statement is as
  122. follows:
  123.  
  124.    REM $INCLUDE: 'QB.BI'
  125.  
  126. Notes:
  127.  
  128. 1. Metacommands are placed in comments (REM).
  129.  
  130. 2. A colon (:) follows the $INCLUDE.
  131.  
  132. 3. The filename (QB.BI) is enclosed in single quotation marks.
  133.  
  134. CALL INTERRUPT Input and Output
  135. -------------------------------
  136.  
  137. Besides the INTERRUPT number, there are two other parameters for the
  138. CALL INTERRUPT statement: the input registers and the output
  139. registers. Before you use these registers, you must dimension two
  140. variables AS the RegType defined above, as follows:
  141.  
  142.    DIM inregs AS RegType, outregs AS RegType
  143.  
  144. For most INTERRUPTs, you need to pass some information (function
  145. number, function parameters) in one or more of the registers. This
  146. assignment is done using the dot (.) operator, as follows:
  147.  
  148.    inregs.AX = &H1A00
  149.  
  150. Note that the above assignment uses the hexadecimal value -- denoted
  151. by the "&H"-- instead of decimal values. Most references for
  152. INTERRUPTs use hexadecimal numbers rather than decimal numbers.
  153.  
  154. For some INTERRUPTs, it is necessary to set the high-order or
  155. low-order byte of a register. These bytes are usually referred to in
  156. the technical literature with H and L instead of X. For example, the
  157. high and low bytes of the BX register are BH and BL, respectively. To
  158. assign the registers when given high and low bytes, concatenate the
  159. hexadecimal values. For example, if you need to assign CH the value 2B
  160. hex and CL the value 3D hex, you would assign CX as follows:
  161.  
  162.    inregs.CX = &H2B3D     ' High byte = &H2B    Low byte = &H3D
  163.  
  164. If you are given only 1 byte (high or low), the other byte can be
  165. assigned 00. For example, you would set AH to the value 01 hex as
  166. follows:
  167.  
  168.    inregs.AX = &H0100     ' High byte = &H01    Low byte ignored(00)
  169.  
  170. Note: The above statement is NOT equivalent to "inregs.AX=&H01". You
  171. must specify the low-order byte or the value will be stored as &H0001.
  172.  
  173. Once you have set the values of the input registers, you are ready to
  174. make the CALL. The CALL INTERRUPT syntax is as follows:
  175.  
  176.    CALL INTERRUPT(IntNum%, inregs, outregs)
  177.  
  178. If an INTERRUPT returns any values, those values will be passed back
  179. in the outregs variable. As with inregs, values will often be passed
  180. in the high or low bytes of a register. The routine, BreakWord(), in
  181. the example section below breaks a register into the 2-byte values.
  182.  
  183. With many INTERRUPTs, you need to check only a single bit (or a few
  184. bits) of any register. This is done using the bitwise operators AND,
  185. OR, XOR, and NOT. For example, the following statement will check to
  186. see if the third bit of AX is set:
  187.  
  188.    IF (outregs.AX AND &H4) THEN     ' 4 (hex) = 100 (binary)
  189.      PRINT "3rd Bit is on"
  190.    END IF
  191.  
  192. Example of CALL INTERRUPT
  193. -------------------------
  194.  
  195. The following program gives an example of the CALL INTERRUPT and
  196. provides two utility SUB programs for processing output:
  197.  
  198. '__________________________ INTSKEL.BAS _________________________
  199. '
  200. '     Skeleton Program for calling DOS or BIOS interrupts from
  201. '     QuickBASIC.
  202. '
  203. '     NOTE: The QuickBASIC environment must be started with the
  204. '           /L option to load the default QB.QLB quick library.
  205. '           This quick library provides support for CALL INTERRUPT
  206. '           and CALL INTERRUPTX.
  207. '
  208. '     There are also two SUBPROGRAMS, BreakWord() and IntToBin(), that
  209. '     you may find useful when CALLing INTERRUPTs.
  210. '
  211. '_________________________________________________________________
  212.  
  213. DEFINT A-Z
  214. CONST TRUE = -1
  215. CONST FALSE = NOT TRUE
  216.  
  217. '$INCLUDE: 'QB.BI'                'Take a look at what is in this file
  218.  
  219. DIM inregs AS RegType, outregs AS RegType
  220.  
  221. '---------------------------------------------------------------------
  222. ' Load Registers with the required input parameters, for the call that
  223. ' you want to make. (See any reference to DOS and/or BIOS calls.)
  224. '
  225. ' Example: for Interrupt 10 Hex, function 0A Hex (BIOS Write Char)
  226. '          AH = OA   Note: The function number usually goes in AH
  227. '          AL = Character Code (ASCII)
  228. '          BH = Video Page Number = 0 normally
  229. '          BL = Color in graphics mode
  230. '          CX = Number of these characters to write to screen
  231. '--------------------------------------------------------------------
  232. CLS
  233. character% = &HFB    'Character 251 decimal, square root symbol
  234. functnum% = &HA00    'Remember you want function in the HIGH Byte of AX
  235.  
  236.     'VERY IMPORTANT! Don't put the function number into
  237.     'the wrong byte of AX. Read [PROGRAM WILL HANG]
  238.  
  239. inregs.ax = character% OR &HA00
  240. inregs.cx = 2000      'Fill the screen
  241. CALL interrupt(&H10, inregs, outregs)
  242.  
  243.  
  244. DEFINT A-Z
  245. '_____________________________________________________________________
  246. '
  247. '     BreakWord() takes an integer argument and returns two integers
  248. '     representing the high and low bytes of the original.
  249. '_____________________________________________________________________
  250. '
  251. SUB BreakWord (dataword, highbyte, lowbyte)
  252.  
  253.    IF dataword < 0 THEN
  254.      highbyte = (dataword + 2 ^ 16) \ 256 'check for high BIT set
  255.    ELSE
  256.      highbyte = dataword \ 256            'integer divide off low byte
  257.    END IF
  258.  
  259.    lowbyte = dataword AND 255                'AND off the top byte
  260.  
  261. END SUB
  262.  
  263.  
  264.  
  265. DEFINT A-Z
  266. '_____________________________________________________________________
  267. '
  268. '    IntToBin() takes an INTEGER argument and produces a
  269. '    binary string representation of the INTEGER.
  270. '_____________________________________________________________________
  271. '
  272. SUB IntToBin (byte%, bin$)
  273. bin$ = ""
  274. temp% = byte%
  275.  
  276.      FOR i = 0 TO 7
  277.           IF temp% AND 1 THEN
  278.                bin$ = "1" + bin$
  279.           ELSE
  280.                bin$ = "0" + bin$
  281.           END IF
  282.            temp% = temp% \ 2
  283.      NEXT
  284.  
  285. END SUB
  286.  
  287. Differences between CALL INTERRUPT and CALL INTERRUPTX
  288. ------------------------------------------------------
  289.  
  290. The CALL INTERRUPT and CALL INTERRUPTX statements are very similar.
  291. Either statement allows you to make calls to DOS and BIOS INTERRUPTs.
  292.  
  293. The only difference is that, with INTERRUPTX, you can specify the DS
  294. and ES registers. (The documentation for INTERRUPTs -- see the
  295. following reference section -- will state whether those registers are
  296. necessary. For most INTERRUPTs, they are not needed.)
  297.  
  298. References for Documentation on INTERRUPTs
  299. ------------------------------------------
  300.  
  301. The following books are excellent resources for the different
  302. INTERRUPTs available from DOS and BIOS. Be aware that the code in
  303. these books is written in assembly language; however, they give the
  304. necessary input and output by register.
  305.  
  306. 1. "Advanced MS-DOS Programming, Second Edition" by Ray Duncan,
  307.    published by Microsoft Press (1988)
  308.  
  309. 2. "The New Peter Norton Programmer's Guide To The IBM PC & PS/2" by
  310.    Peter Norton, published by Microsoft Press (1988)
  311.  
  312. Additional reference words: QB4INT.ARC Sxxxxx.EXE
  313.