home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / MISC / TNH_PC.ZIP / BRIDGER.NL < prev    next >
Encoding:
Text File  |  1987-01-14  |  8.5 KB  |  300 lines

  1. BASIC And Machine Code Interfacing
  2.  
  3.              Mark Bridger
  4.       The Boston Computer Society
  5.           IBM PC Users' Group
  6.  
  7. While BASIC has many deficiencies as
  8. a programming language, it is the
  9. most popular and simplest language to
  10. use. In fact, IBM chose to
  11. concentrate most of the PC's special
  12. effects in ROM BASIC. However, if one
  13. wants the features of BASIC, plus
  14. speed, control or extra effects not
  15. provided by IBM BASIC, the only
  16. alternative is to interface with
  17. assembly language.  This raises the
  18. problem of how to link and call an
  19. assembly language routine from a
  20. BASIC program. Appendix C of the IBM
  21. BASIC Manual gives a rather sketchy
  22. account of this. This article will
  23. try to explain the BASIC to machine
  24. language interface procedure.
  25.  
  26. Fundamentally, the problems of
  27. linkage are as follows:
  28.  
  29. o   Problem 1: BASIC can only call a
  30.     routine which is loaded into
  31.     memory somewhere. So  - how to
  32.     load, and where?
  33.  
  34. o   Answer 1: Use the BLOAD
  35.     statement, and make sure that the
  36.     subroutine does not overlap
  37.     either BASIC or your program
  38.     (more of this later).
  39.  
  40. o   Problem 2: You can only BLOAD
  41.     something which has been BSAVEd.
  42.     To BSAVE something, you must:(a)
  43.     be in BASIC and (b) have that
  44.     something in memory at the same
  45.     time.
  46.  
  47. o   Answer 2: The only way to do this
  48.     is by using that all-purpose
  49.     tool, DEBUG. To illustrate the
  50.     procedure in detail, we shall
  51.     construct a small program which
  52.     does something that can't be done
  53.     from BASIC alone; namely, write a
  54.     character in color on the
  55.     graphics screen. The reader
  56.     should be somewhat familiar with
  57.     PC assembly language.
  58.  
  59. The BASIC part of the package is the
  60. small program called "SMALL.BAS",
  61. listed in figure 1.  The assembly
  62. language part is the code which
  63. contains the procedure
  64. "writechar",listed in figure 2.
  65. Notice that the BASIC program refers
  66. to the file "write.srt" as well as
  67. the procedure writechar; it is the
  68. construction of this file we will
  69. examine first.
  70.  
  71. Figure 1:Basic program small.bas
  72.  
  73. 10 CLS: KEY OFF
  74. 20 SCREEN 1,0: COLOR 1,1 'blue
  75.                     graphics screen
  76. 30 INPUT "Choose color 0,1,2,3:";HUE%
  77. 40 HUE% = HUE% - 4*INT(HUE%/4)
  78. 50 X$ = INKEY$: IF X$ = ""GOTO 50
  79. 60 IF ASC(X$) = 0 GOTO 50 'only ASCII
  80. 70 CHAR% = ASC(X$):CLS
  81. 80 DEF SEG = &HFCO 'reserve top of
  82.                          memory
  83. 90 BLOAD "write.srt",0
  84. 100 WRITECHAR% = 0
  85. 110 CALL WRITECHAR%(CHAR%,HUE%)
  86. 120 END
  87.  
  88. Figure 2: Assembly Lang- WRITE.ASM
  89. stack segment para  public  'stack'
  90. stack ends
  91.  
  92. cseg  segment para  public  'code'
  93.       assume  cs:c  ss:stack
  94.  
  95. ;procedure writechar (var char,
  96. ;hue:byte) This procedure prints a
  97. ;single character, whose ASCII code
  98. ;is char, in the color specified by
  99. ;its parameter "hue". In graphics mode
  100. ;this is one of the four palette
  101. ;colors.
  102.  
  103.         public   writechar
  104. writechar        proc    far
  105.  
  106. push bp       ;save bp
  107. mov  bp,sp    ;bp points to stack
  108. push ax       ;save ax
  109. push bx       ;save bx
  110. push cx       ;save cx
  111. push si       ;save si
  112. sti           ;enable interrupts
  113. mov ah,9      ;prepare to write
  114. mov si,[bp+8] ;si gets address of cha
  115. mov al,[si]   ;al gets value of char
  116. mov si,[bp+6] ;si gets address of hue
  117. mov bl,[si]   ;bl gets value of hue
  118. mov cx,1      ;write only once
  119. mov bh,0      ;graphics mode
  120. int 10h       ;do it!
  121. pop si        ;restore registers
  122. pop cx
  123. pop bx
  124. pop ax
  125. pop bp
  126. ret  4        ;pop addresses, return
  127. writechar  endp
  128. cseg  ends
  129. end
  130.  
  131. Proceed as follows:
  132.  
  133. 1.  Type the contents of figure2
  134.     under the filename write.asm.
  135.  
  136. 2.  Run this through the Assembler to
  137.     produce the file called
  138.     write.obj.  This is machine code
  139.     which must be linked.
  140.  
  141.     As mentioned previously, we want
  142.     to have the program and BASIC in
  143.     memory at the same time so we can
  144.     BSAVE it. To do this we must make
  145.     sure that it is loaded fairly low
  146.     in memory; we also want to make
  147.     sure that our procedure write
  148.     gets loaded 'high' in memory by
  149.     DEBUG. One way to do this is to
  150.     use the Linker with the 'H'
  151.     option. This is done as follows:
  152.  
  153. 3.  Call up the Linker by typing LINK
  154.     at the DOS prompt.
  155.  
  156. 4.  Answer its first question (for an
  157.     object file) with WRITE/h and
  158.     press Enter.  Continue until the
  159.     Linker runs out of questions. It
  160.     will probably give you an error
  161.     message that there is no stack
  162.     segment. That's OK. It will
  163.     create a file called WRITE.EXE
  164.     which is what we want. For
  165.     simplicity's sake, assume from
  166.     now on that all files mentioned
  167.     are on the same disk in drive A
  168.     (the default).
  169.  
  170. 5.  Now for the debugger.  At the A>,
  171.     type DEBUG BASIC.COM and press
  172.     ENTER.  This loads BASIC into
  173.     memory.  (You can also use
  174.     BASICA.) To see the exact memory
  175.     locations, at the DEBUG
  176.     prompt-hyphen, type r and press
  177.     ENTER. You will see a display in
  178.     hex of the contents of all the
  179.     registers.
  180.  
  181. 6.  Important: Make a note of the
  182.     contents of the segment registers
  183.     DS,ES,CS,SS (they should all be
  184.     the same; mine read 052A). The
  185.     instruction pointer (IP) should
  186.     be 0100.
  187.  
  188. 7.  Quit DEBUG by entering q.
  189.  
  190. 8.  It is now time to load the
  191.     subroutine. Type DEBUG WRITE.EXE
  192.     and press ENTER.
  193.  
  194. 9.  To look at the registers again,
  195.     enter r and press ENTER.
  196.  
  197. 10.  Important: Make note of the
  198.     contents of CS (segment
  199.     location), IP (offset), and CX
  200.     (length). CS should be fairly
  201.     large (mine reads 4FFD), IP
  202.     should be 0000, and CX should be
  203.     0030 for the file write.exe
  204.     (length  = 30HEX bytes = 48
  205.     bytes).
  206.  
  207. 11.  Now, load BASIC exactly as it
  208.     would have been if write.exe had
  209.     not been loaded.
  210.  
  211. 12.  Make sure that DS,ES,CS,SSS and
  212.     IP are exactly the same as when
  213.     BASIC was loaded initially. That
  214.     is why you made note of the
  215.     registers. DS and ES are probably
  216.     OK, but CS,SS, and IP must be
  217.     changed. To change CS, for
  218.     example, respond to the DEBUG
  219.     hyphen with r cs and press Enter.
  220.     DEBUG will display a colon. You
  221.     type in the correct value and
  222.     enter. Fix SS and IP also. Don't
  223.     leave the debugger!
  224.  
  225. 13.  Reload BASIC as follows. After
  226.     the hyphen type n basic.com and
  227.     press Enter.  This names the
  228.     file. Then type L and press
  229.     Enter. This loads the file. If
  230.     all has gone well, the two files
  231.     should be loaded into disjoint
  232.     parts of memory whose locations
  233.     we know from the CS and IP
  234.     settings.
  235.  
  236. 14.  Now run BASIC from the debugger.
  237.     Respond to the hyphen with
  238.     g=(BASIC's CS):(BASIC's IP) and
  239.     press Enter. You should get a
  240.     "direct statement in file"
  241.     message and BASIC's familiar OK
  242.  
  243. 15.  Now from BASIC we want to BSAVE
  244.     our subroutine.
  245.  
  246.     o   Set the default segment to
  247.         the value of write.exe's CS
  248.         register as follows:
  249.  
  250.          Type:def seg = &H(CS value).
  251.             Then press Enter.
  252.  
  253.     o   Think of a name for the
  254.         subroutine. In the example,
  255.         we used the unimaginative
  256.         name of write.srt.
  257.  
  258.     o   BSAVE it as follows:
  259.  
  260.         bsave "name, &H(IP value),
  261.         &H(CX value)
  262.         (Hex numbers require the
  263.         prefix'&H' in BASIC.)
  264.  
  265. Let's take a brief look at the BASIC
  266. call procedure. One of the problems
  267. with BASIC is where to put its
  268. machine language program. The BASIC
  269. work segment is the first 64K bytes
  270. of memory. If you have more than 64K,
  271. you can BLOAD machine language
  272. anywhere above this segment:&H1700 is
  273. a popular choice. If you a have a
  274. color graphics card (we're assuming
  275. you do here) you can even put
  276. programs fewer than 192 bytes at
  277. &H1F40 (between the even and odd
  278. buffers). Assumming 64K, we located
  279. the subroutine in the  top 1K, in
  280. step 8. To be perfectly safe, you can
  281. reserve this space by beginning the
  282. program with a CLEAR,&H8C00 command.
  283. (BASIC and DOS take up about 28K
  284. leaving 36K. Then 36K - 1K = 35K =
  285. Hex 8C00). Step 9, the BLOAD command,
  286. actually puts our subroutine in the
  287. default segment with an offset of 0
  288. (Hex FC00).
  289.  
  290. That's about it. Further details
  291. about the BASIC 'CALL' command are in
  292. the BASIC Manual. Two clearly written
  293. books about assembly language are:
  294. "The iAPX Book (Intel) and "IBM PC
  295. Assembly Language" (L. Scanlon, Brady
  296. Publishing Co.,1983).  (Editor's
  297. note: Another excellent book on this
  298. subject is "IBM PC Assembly Language
  299. Programming" by Dave Bradley.)
  300.