home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / BGICHR.ZIP / INTERNAL.DOC < prev   
Encoding:
Text File  |  1988-03-29  |  9.0 KB  |  186 lines

  1. BGI-TEST and CHR-TEST were written by Sam Denton, St. Louis, MO,
  2. CompuServ ID 76314,1512.
  3.  
  4. The programs and this documentation are Copyright 1988 by Sam Denton,
  5. all rights reserved.  Private use is permitted, otherwise call me.
  6. (My rates are reasonable, and/or you can hire me if you like my code.)
  7.  
  8. ----------------------------------------------------------------------------
  9.  
  10. NOTE/WARNING:
  11.  
  12. If, like me, you make the .BGI and .CHR files ReadOnly, you should insert
  13. "System.FileMode := 0;" before calling InitGraph. I spent an entire night
  14. tracing the code before I realized what I had done to myself.
  15.  
  16. ----------------------------------------------------------------------------
  17.  
  18. BGI-TEST.PAS
  19.  
  20. To use with DOS DEBUG, try "DEBUG C:\TP4\TURBO.EXE C:\MYPGMS\BGI-TEST.PAS".
  21. At the DEBUG prompt, enter the "G" command.  BGI-TEST will stop of its own
  22. volition at the start of the .BGI driver if you remove the "$" from the
  23. "{$define trace}" at the start of the program.  Use the "RIP" command to
  24. manually advance the program counter past the "INT 3" instruction.
  25.  
  26. All .BGI files start with a 2 byte signature = 'pk' (checked for by code in
  27. the Graph unit), followed by two backspace characters.  For comparison, .CHR
  28. files start with 'PK', and are otherwise similar.  BTW, I presume that 'pk'
  29. is Philipe Kahn, and the backspaces are so you can TYPE the files and be
  30. able to read the comments without seeing the 'pk'.  Then comes free-form
  31. ASCII comments ending in Ctrl-Z, then:
  32.     dw  offset within file to the start of code
  33.     dw  driver id, a value from 0 to 5,
  34.         0=CGA, 1=EGA/VGA, 2=reserved(?), 3=Hercules, 4=AT&T, 5=PC3270
  35.     dw  size of just the code, NOT the entire file
  36.     db  a non-zero value
  37.     db  zero
  38.     db  either 0 or 1
  39.     db  dup(0) until start of code
  40.  
  41. GRAPH normally does a FAR CALL to the start-of-code address (normalized so
  42. that the offset is 0) with a value in SI determining the type of call.
  43. The value is always even, so the driver may use it to index a branch-table.
  44.  
  45. All numbers from here on are given in HEXADECIMAL, and all offsets are
  46. taken from CGA.BGI and are relative to start-of-code.
  47.  
  48.     org 0111
  49.     dw  ?   ; cp.x
  50.     dw  ?   : cp.y
  51.  
  52. BitBlt code is at 0EAC, it is invoked at 0F60, it is really weird stuff.
  53.  
  54. In the following table, for each legal value of SI is shown the offset into
  55. the driver's code of the routine.  Also, if there seems to be a direct
  56. correspondence between the routine and a GRAPH entry point, the name of the
  57. entry point and how the arguments are passed is shown.  Some GRAPH calls
  58. turn into a pair of calls, first a MoveTo to set the X and Y parameters,
  59. then a call to pass the rest of the parameters.  In this case, the first
  60. two parameters are shown as CP.X and CP.Y.  During InitGraph, the driver
  61. gets a CALL FAR instruction stuffed into offset 0010.  The CALL FAR points
  62. back into GRAPH and will execute many complicated "primitives" by doing
  63. recursive calls back into the driver.  This means that if you write your
  64. own graphic device driver, you don't have to write 'hard' routines.
  65.  
  66. si  addr  name (if any), args :- results
  67. --  ----  ------------------------------
  68. 00  01D7  AL=1 :- CX=nbr of modes?
  69.           AL=2,CL=mode :- [ES:BX]=string(name of mode)
  70.           AL=?,CL=mode :- [ES:BX]=descriptor table, other stuff happens
  71. 02  0231  :- set graphics hardware to mode
  72. 04  0248  ClrScr?
  73. 06  0015 ?No Operation
  74. 08  0297  MoveTo(AX,BX)
  75. 0A  029F  LineTo(AX,BX)
  76. 0C  02B3  Line(AX,BX,CX,DX)
  77. 0E  0010* Do Polygon [ES:BX]=point list, CX=nbr pts, ?=draw or fill
  78. 10  0010* Bar3D(cp.x,cp.y,AX,BX,CX,DX)
  79. 12  07FE* Bar(AX,BX,CX,DX)
  80. 14  0010* Ellipse(cp.x,cp.y,AX,BX,CX,DX)
  81.           (this entry point is also used by Arc and Circle)
  82. 16  0010* PieSlice(cp.x,cp.y,AX,BX,CX)
  83. 18  0015 ?No Operation
  84. 1A  00BD  SetBkColor(BX)
  85. 1C  00DE ?SetColor(BX)
  86. 1E  0286  SetColor, AL=AH=color
  87. 20  00E3*?SetFillStyle/Pattern, AL=pattern nbr, or if FF then [ES:BX]=pattern
  88. 22  03D2  SetLineStyle(AX,BX,CX)
  89. 24  0398* SetTextStyle AL=direction, BX=8*scale, CX=8*scale
  90.           When AH has bit 80 on, DX is also significant
  91. 26  035C* OutText @ CP, [ES:BX]=string, CX=length
  92. 28  00FD* TextSize [ES:BX]=string, CX=length :- BX=width, CX=height in pixels
  93. 2A  0015 ?No Operation
  94. 2C  009F  FloodFill(AX,BX,CX)
  95. 2E  0FDC  GetPixel(AX,BX) :- DX
  96. 30  0FF5  PutPixel(AX,BX,DL)
  97. 32  006C  really strange, see below
  98. 34  0084  GetImage CX=x1,DX=y1,[ES:BX]=image(dx,dy,dup(?))
  99. 36  0099  PutImage AL=BitBlt,CX=x,DX=y,[ES:BX]=image(dx,dy,data...)
  100. 38  0050  SetViewport(AX,BX,CX,DX)
  101.  
  102. SI=32 returns [ES:BX] pointing to a table of offsets into the code that GRAPH
  103. uses as additional entry points.  The code GRAPH uses is kludgy, but the net
  104. effect is to simulate CALL [ES:[ES:BX+n]].  There are only 6 entries and
  105. most of them point to RETF instructions, but [ES:BX+8] will return the number
  106. of bits per pixel in the current graphics mode.  However, in EGAVGA.BGI only,
  107. [ES:BX+0A] does some sort of segment arithmetic involving display memory.  In
  108. any event, SI=32 is used by GetImageSize and SetActivePage
  109.  
  110. When InitGraph is called, GRAPH calls the device driver seventeen times with
  111. SI= 00, 02, 24, 38, 08, 1E, 1E, 1E, 1E, 20, 24, 1E, 1E, 20, 22, 24, and 08,
  112. and only Frank Borland knows why.  SetGraphMode issues the same sequence of
  113. calls.  Also, when LineTo or LineRel is called, GRAPH calls SI=08 (MOVE! to a
  114. new place), SI=0A (draw a line to the OLD! point), SI=08 (move back to new
  115. point), even though a single call to SI=0A (draw a line to the new point)
  116. would have the same net effect.  OutText and OutTextXY both call SI=08 TWICE
  117. in succession with IDENTICAL arguments before writing out the string.  I
  118. guess they want to be absolutely certain the text lands in the right place.
  119. (As nearly as I can tell, both GRAPH and the .BGI drivers maintain their own
  120. copies of the current position, but the copy in the driver is used to pass
  121. positioning data when Bar3D, Arc, PieSlice, etc. are called.  Only the
  122. current position kept by GRAPH matches the documentation.)
  123.  
  124. (P.S.  If, like me, you make the .BGI files ReadOnly, you should insert
  125. "System.FileMode := 0;" before calling InitGraph. I spent an entire night
  126. tracing the code before I realized what I had done to myself.)
  127.  
  128. ----------------------------------------------------------------------------
  129.  
  130. CHR-TEST.PAS
  131.  
  132. All .CHR files start with a 2 byte signature = 'PK' (checked for by code in
  133. the Graph unit), followed by two backspaces (which are not checked anywhere).
  134. For comparison, .BGI files start with 'pk', and are otherwise similar.  Then
  135. comes free-form ASCII comments ending in Ctrl-Z, then:
  136.     dw  offset within file to the start of descriptors
  137.     db  driver id, four characters
  138.         GOTH=gothic, LITT=small, SANS=sans serif, TRIP=triplex
  139.     dw  size of just the code, NOT the entire file
  140.     db  one
  141.     db  zero
  142.     db  one
  143.     db  dup(0) until start of descriptors
  144.  
  145. Within the descriptors, first is a ten byte area laid out as:
  146.     db  unknown, apparently alway $2B
  147.     dw  number of characters defined
  148.     db  unknown, apparently alway zero
  149.     db  the first character drawable with this character set
  150.         (usually blank ($20))
  151.     dw  offset to table of plot commands
  152.     db  unknown, apparently alway zero
  153.     db  Y value of top of character cell (shortint)
  154.     db  unknown, apparently alway zero
  155.     db  Y value of bottom of character cell (shortint, usually negative)
  156.     db  5 bytes, unknown, apparently alway zero
  157.  
  158. Next is an array of words pointing to the plot commands:
  159.     dw  0,4,...    ; offset to blank, exclaimation point, ...
  160.  
  161. Thirdly is an array of bytes containing the widths of each character:
  162.     db  6,3,...    ; width of blank, exclaimation point, ...
  163.  
  164. Finally come the plot commands. Each consists of 16 bits broken into several
  165. fields.  The high order bit ($80) from both bytes are used to decide what to
  166. do.  The cases are (expressed in binary):
  167.     1xxxxxxx 0yyyyyyy -- move to (x,y)
  168.     1xxxxxxx 1yyyyyyy -- line to (x,y)
  169.     0xxxxxxx 0yyyyyyy -- done, (x,y) is ignored
  170.     0xxxxxxx 1yyyyyyy -- no operation, (x,y) is ignored
  171. The remaining seven bits of each byte are two's complement numbers.  Each
  172. character is drawn within a box with the leftmost portion and the base of
  173. the image lying on the y and x axii, respectively. Lower-case descenders
  174. and some punctuation will drop below the x axis.
  175.  
  176. The first data area is of fixed size at the start of the 'segment', so
  177. addressing it is no problem, and the second data is also easy to address,
  178. although it is of variable size.  The third and fourth areas are more
  179. problematical.  To calculate the offset of the third area, use the formula
  180. 2*(number of characters defined) + 16, and then index to the needed byte.
  181. To find the plot commands in the fourth area for a given character, c, use
  182. 2*(ord(c) - (first char defined)) + 16 to get the offset of a word whose
  183. value is then added to the offset of the table of plot commands.  See the
  184. program for examples of Pascal code.  It's actually somewhat easier to do in
  185. assembler (or C), however.
  186.