home *** CD-ROM | disk | FTP | other *** search
/ Boston 2 / boston-2.iso / DOS / PROGRAM / PASCAL / VGAFONT / VGA_FONT.ASM < prev    next >
Assembly Source File  |  1993-12-01  |  50KB  |  1,308 lines

  1. ; vga_font:  Some primitives for working with text mode evga fonts.
  2. ;
  3. ;    To use this system with the higher-level unit, V_FONT_U, first call
  4. ;    FontInit, then use the graphic primitives in the standard fashion.
  5. ;    I.e., Line(0,0,639,399) to draw a diagonal line.  The ClearChars
  6. ;    procedure is used to de-allocate all of the characters that have
  7. ;    been used to draw any graphic image on the screen, and clear the
  8. ;    screen to the way it was when you used FontInit.
  9. ;
  10. ;    Memory required:  The main program must declare two areas of memory:
  11. ;      One to be used to store the contents of the current screen (4096 bytes),
  12. ;      and another to store the 384-element character set (6144 bytes).
  13. ;      Procedure headers are clearly marked as to which buffers should
  14. ;      be used with which procedure.
  15. ;
  16. ; Specifications:
  17. ;    - Programmed for 80x25 color EGA or VGA text modes only.
  18. ;    - Works with resolutions of 640x200, 640x350, and 640x400
  19. ;    - Redefines up to 384 characters, starting with character number 511
  20. ;      and working down to character number 128.  Extended characters are
  21. ;      used which means that only 8 colors can be controlled directly.
  22. ;    - Two major primitives supported are Line and Ellipse, as well as
  23. ;      many other less-significant ones.
  24.  
  25.  
  26. data            segment         public
  27. ; Line variables:
  28. delta_x        dw        ?
  29. delta_y        dw        ?
  30. halfy        label        word
  31. halfx        dw        ?
  32. count        dw        ?
  33. ; Temporary variables:
  34. Temp            dw              ?
  35. Temp2           dw              ?
  36. ; Internal control variables:
  37. extrn           SizeFor128Chars:word
  38.  
  39. ; Global variables:
  40. extrn           Buffer:         dword         ; Font buffer
  41. extrn           TotalUsed:      word          ; Total # of allocated chars
  42. extrn           CharsUsed:      byte          ; Array of 384 character flags
  43. extrn           MaxX:           word          ; Maximum X coordinate
  44. extrn           MaxY:           word          ; Maximum Y coordinate
  45. extrn           Points:         byte          ; # of bytes per character
  46.  
  47. ; Ellipse variables:
  48.                 even
  49. t_e_lo          dw              ?
  50. t_e_hi          dw              ?
  51. r1_lo           dw              ?
  52. r1_hi           dw              ?
  53. r2_lo           dw              ?
  54. r2_hi           dw              ?
  55. y_p_lo          dw              ?
  56. y_p_hi          dw              ?
  57. max_x           dw              ?
  58. c_x             dw              ?
  59. c_y             dw              ?
  60. xe              dw              ?
  61. ye              dw              ?
  62. portion         db              ?
  63. Old_BP          dw              ?
  64.  
  65. data            ends
  66.  
  67. Code            segment         public
  68.                 assume          cs:code,ds:data
  69.  
  70.                 public          Line
  71.                 public          Freeze
  72.                 public          Unfreeze
  73.                 public          Ellipse
  74.                 public          Hlin
  75.                 public          Vlin
  76.                 public          Box
  77.                 public          OpenBox
  78.                 public          MaskColors
  79.                 public          Pset
  80.                 public          Make512chars
  81.                 public          GetScrn
  82.                 public          PutScrn
  83.                 public          WriteFont
  84.                 public          FontInit
  85.                 public          ClearChars
  86.                 public          Make8bitChars
  87.                 public          Make9bitChars
  88.  
  89. Make8bitChars   proc            far
  90. ; Calling sequence:  Make8bitChars(Lines:  integer);
  91. ; This procedure sets the BIOS video mode so that the character generator
  92. ; displays only 8 pixels per character.  Two modes support this:  a 350
  93. ; line mode, and a 200 line mode.
  94. ; Note:  Lines can be 350 or 200.
  95. Lines           equ             word ptr [bp+6]
  96.  
  97.                 push            bp
  98.                 mov             bp,sp
  99.                 mov             ah,12h
  100.                 mov             bl,30h
  101.                 cmp             Lines,200
  102.                 jz              Set200lines
  103.                 mov             al,1         ; 350 scan lines
  104.                 int             10h
  105.                 mov             MaxY,349
  106.                 mov             Points,14
  107.                 mov             SizeFor128chars,128*14
  108.                 jmp             short ExitM8
  109. Set200lines:    mov             al,0
  110.                 int             10h
  111.                 mov             MaxY,199
  112.                 mov             Points,8
  113.                 mov             SizeFor128chars,128*8
  114. ExitM8:         pop             bp
  115.                 ret             2
  116. Make8bitChars   endp
  117.  
  118. Make9bitChars   proc            far
  119. ; 400-line mode.
  120. ; Configures the BIOS to program the character generator to display 9
  121. ; pixels for every 8-bit character.  Doing this adds a blank vertical line
  122. ; to the right of every displayed character, except for the ones designated
  123. ; as border characters which have their rightmost pixels extended to the
  124. ; ninth position.  Using graphics with this mode is more difficult than
  125. ; with the 200 & 350 line modes since the programmer must be able to
  126. ; deal with the problem of having blank spaces in an otherwise solid
  127. ; graphic.  Sometimes this effect might actually be beneficial.  As for
  128. ; diagonal or vertical lines, this effect won't be noticed as much.  Keep
  129. ; in mind that the screen is still 640 pixels wide, and all pixels will
  130. ; be displayed as usual;  it's just that there are added blanks.
  131.                 mov             ah,12h
  132.                 mov             bl,30h
  133.                 mov             al,2         ; 400 scan lines
  134.                 int             10h
  135.                 mov             MaxY,399
  136.                 mov             Points,16
  137.                 mov             SizeFor128chars,128*16
  138.                 ret
  139. Make9bitChars   endp
  140.  
  141. ClearChars      proc            far
  142. ; Calling sequence:  ClearChars(ScrnBuf:  pointer);
  143. ; Display original screen (in ScrnBuf), clear the font, and de-allocate
  144. ; all of the characters.  Note that the video page gets set to page 0.
  145. ScrnBuf         equ             [bp+6]
  146.  
  147.                 push            bp
  148.                 mov             bp,sp
  149.                 cld
  150.                 mov             ax,ds
  151.                 mov             es,ax
  152.                 mov             di,offset CharsUsed
  153.                 mov             cx,192
  154.                 mov             ax,0
  155.                 rep stosw
  156.                 mov             TotalUsed,0
  157.                 les             di,Buffer
  158.                 mov             cx,0c00h
  159.                 rep stosw
  160.                 push            word ptr ScrnBuf[2]
  161.                 push            word ptr ScrnBuf
  162.                 call            far ptr PutScrn
  163.                 call            far ptr WriteFont
  164.                 pop             bp
  165.                 ret             4
  166. ClearChars      endp
  167.  
  168. FontInit        proc            far
  169. ; Calling sequence:  FontInit(FontBuffer,ScrnBuffer:  pointer);
  170. ; Initializes the font information.  FontBuffer is a pointer to a
  171. ; 6144-byte array used to store the font.  ScrnBuffer is a pointer to
  172. ; a 4096-byte array used to store the current screen.  PutScrn & GetScrn
  173. ; are alternate ways of using ScrnBuffer.  FontInit also configures the
  174. ; BIOS to handle 512-character fonts, 384 of which are used for VGA_FONT.
  175. ScrnBuffer      equ             [bp+6]
  176. FontBuffer      equ             [bp+10]
  177.  
  178.                 push            bp
  179.                 mov             bp,sp
  180.                 mov             TotalUsed,0
  181.                 les             di,FontBuffer
  182.                 mov             word ptr Buffer,di
  183.                 mov             word ptr Buffer[2],es
  184.                 push            word ptr ScrnBuffer[2]
  185.                 push            word ptr ScrnBuffer
  186.                 call            far ptr GetScrn
  187.                 cld
  188.                 mov             ax,ds
  189.                 mov             es,ax
  190.                 mov             di,offset CharsUsed
  191.                 mov             ax,0
  192.                 mov             cx,192
  193.                 rep stosw
  194.                 les             di,Buffer
  195.                 mov             cx,0c00h
  196.                 rep stosw
  197.                 call            far ptr Make512chars
  198.                 pop             bp
  199.                 ret             8
  200. FontInit        endp
  201.  
  202. WriteFont       proc            far
  203. ; Uses the BIOS to write the font information (contained in Buffer) to the
  204. ; EVGA adapter.  This procedure has the unfortunate consequence of setting
  205. ; the video page to page 0 (among other things).  This makes it more difficult
  206. ; to stop flickering since the primary way to achieve animation is to use
  207. ; the Freeze & UnFreeze procedures to copy the screen to another page and
  208. ; switch to it, thereby effectively "freezing" the screen until
  209. ; page 0 is switched back.  WriteFont will do this switching -- although
  210. ; it is usually not the correct time to be doing it.
  211.                 push            bp
  212.                 mov             ax,1100h
  213.                 mov             bh,Points
  214.                 mov             bl,0
  215.                 mov             cx,128
  216.                 mov             dx,128
  217.                 les             bp,Buffer
  218.                 int             10h
  219.                 mov             ax,1100h
  220.                 mov             bh,Points
  221.                 mov             bl,1
  222.                 mov             cx,256
  223.                 xor             dx,dx
  224.                 les             bp,Buffer
  225.                 add             bp,SizeFor128chars
  226.                 int             10h
  227.                 pop             bp
  228.                 call            far ptr Make512chars
  229.                 ret
  230. WriteFont       endp
  231.  
  232. GetScrn         proc            far
  233. ; Calling sequence:  GetScrn(SBuffer:  pointer);
  234. ; Reads the screen into the 4096-byte buffer pointed to by SBuffer.
  235. ; Copies all character codes & attributes.  In the future, ClearChars
  236. ; can use this screen to switch to in order to get a clean slate.
  237. ; This method allows text to remain constant while graphics get
  238. ; cleared.
  239. SBuffer         equ             [bp+6]
  240.  
  241.                 push            bp
  242.                 mov             bp,sp
  243.                 push            ds
  244.                 cld
  245.                 mov             si,0
  246.                 mov             ax,0b800h
  247.                 mov             ds,ax
  248.                 les             di,SBuffer
  249.                 mov             cx,2048
  250.                 rep movsw
  251.                 pop             ds
  252.                 pop             bp
  253.                 ret             4
  254. GetScrn         endp
  255.  
  256. PutScrn         proc            far
  257. ; Calling sequence:  PutScrn(SBuffer:  pointer);
  258. ; Opposite of GetScrn;  transfers SBuffer to the screen.
  259. SBuffer         equ             [bp+6]
  260.  
  261.                 push            bp
  262.                 mov             bp,sp
  263.                 push            ds
  264.                 cld
  265.                 lds             si,SBuffer
  266.                 mov             di,0
  267.                 mov             ax,0b800h
  268.                 mov             es,ax
  269.                 mov             cx,2048
  270.                 rep movsw
  271.                 pop             ds
  272.                 pop             bp
  273.                 ret             4
  274. PutScrn         endp
  275.  
  276. Make512chars    proc            far
  277. ; Configures the BIOS for 512-element fonts.  The lower 256 characters
  278. ; remain in bank 0 while the upper 256 characters are in bank 1.
  279.                 mov             ax,1103h
  280.                 mov             bl,4
  281.                 int             10h
  282.                 ret
  283. Make512chars    endp
  284.  
  285. PutChar         proc            near
  286. ; Calling sequence:  PutChar(CharNo:  integer;  Color,x,y:  byte);
  287. ; Displays CharNo at the specified x,y coordinate.  x & y are given
  288. ; as character positions, based on a resolution of 80x25.  The attribute
  289. ; of the character is in Color.  CharNo can be anywhere from 0 to 511.
  290. y               equ             byte ptr [bp+4]
  291. x               equ             byte ptr [bp+6]
  292. Color           equ             byte ptr [bp+8]
  293. CharNo          equ             word ptr [bp+10]
  294.  
  295.                 push            bp
  296.                 mov             bp,sp
  297.                 mov             bx,CharNo
  298.                 cmp             bx,255
  299.                 jbe             Less255
  300.                 or              Color,8
  301.                 jmp             short SkipNextPC
  302. Less255:        and             Color,0f7h
  303. SkipNextPC:     mov             si,80
  304.                 mov             al,y
  305.                 xor             ah,ah
  306.                 xor             dx,dx
  307.                 mul             si
  308.                 add             al,x
  309.                 adc             ah,0
  310.                 shl             ax,1
  311.                 mov             si,ax
  312.                 mov             ax,0b800h
  313.                 mov             es,ax
  314.                 mov             ah,Color
  315.                 mov             al,bl
  316.                 mov             es:[si],ax
  317.                 pop             bp
  318.                 ret             8
  319. PutChar         endp
  320.  
  321. WriteDot        proc            near
  322. ; Calling sequence:  WriteDot(CharNo,x,y:  integer;  Value,Color:  byte);
  323. ; Sets a pixel of a particular character given in CharNo.  The x & y
  324. ; values specified are offsets into the character matrix based on
  325. ; resolutions of 8x8, 8x14, and 8x16.  Value is either a 1 or a 0 and
  326. ; represents the value of the pixel.  Color is a standard text-mode attribute.
  327. ; CharNo must be in the range of 128 through 511.
  328. Color           equ             byte ptr [bp+4]
  329. Value           equ             byte ptr [bp+6]
  330. y               equ             word ptr [bp+8]
  331. x               equ             word ptr [bp+10]
  332. CharNo          equ             word ptr [bp+12]
  333.  
  334.                 push            bp
  335.                 mov             bp,sp
  336.                 push            CharNo
  337.                 mov             ax,x
  338.                 and             ax,7
  339.                 push            ax
  340.                 mov             ax,y
  341.                 div             Points
  342.                 mov             Temp,ax
  343.                 mov             al,ah
  344.                 xor             ah,ah
  345.                 push            ax
  346.                 mov             al,Value
  347.                 push            ax
  348.                 call            ModifyPixel
  349.                 cmp             ax,0           ; Is character blank or not?
  350.                 jz              ContWD         ; Not blank;  continue
  351.                 mov             CharNo,32      ; It's blank, and a space
  352. ContWD:         push            CharNo
  353.                 mov             al,Color
  354.                 xor             ah,ah
  355.                 push            ax
  356.                 mov             ax,x
  357.                 mov             cl,3
  358.                 shr             ax,cl
  359.                 push            ax
  360.                 and             Temp,0ffh
  361.                 push            Temp
  362.                 call            PutChar
  363.                 pop             bp
  364.                 ret             10
  365. WriteDot        endp
  366.  
  367. GetNewChar      proc            near
  368. ; Calling sequence:  GetNewChar:  integer;
  369. ; This function returns and allocates a new character to be used for
  370. ; graphics display.  GetNewChar starts from character 511 and goes
  371. ; backwards to character 128, thereby allowing the program to be
  372. ; easily changed to allow fewer characters to be displayed (and
  373. ; use the remaining characters as the symbols that IBM intended them
  374. ; to be).  TotalUsed gets incremented.
  375.                 mov             si,(offset CharsUsed)+383
  376.                 std
  377.                 mov             bx,128
  378. WhileLoop:      cmp             bx,511
  379.                 ja              LimitExceeded
  380.                 lodsb
  381.                 cmp             al,1
  382.                 jnz             FoundSpot
  383.                 inc             bx
  384.                 jmp             short WhileLoop
  385. FoundSpot:      mov             ax,639
  386.                 sub             ax,bx
  387.                 mov             bx,ax
  388.                 sub             bx,128
  389.                 mov             CharsUsed[bx],1
  390.                 inc             TotalUsed
  391.                 push            ax
  392.                 mov             al,Points
  393.                 xor             ah,ah
  394.                 mul             bx
  395.                 les             di,Buffer
  396.                 add             di,ax
  397.                 mov             cl,Points
  398.                 xor             ch,ch
  399.                 shr             cl,1
  400.                 cld
  401.                 xor             ax,ax
  402.                 rep stosw
  403.                 pop             ax
  404.                 ret
  405. LimitExceeded:  xor             ax,ax
  406.                 ret
  407. GetNewChar      endp
  408.  
  409. SeeIfSpace      proc            near
  410. ; Search the currect character (pointed to by Tmp2) to see if it is blank.
  411. ; If it is, de-allocate character from list, and return 1 in AX.
  412. ; If it is not blank, return 0 in AX.  SeeIfSpace is for use by
  413. ; ModifyPixel.
  414.                 cld
  415.                 les             di,Buffer
  416.                 add             di,Temp2
  417.                 mov             cl,Points
  418.                 xor             ch,ch
  419.                 shr             cl,1
  420.                 xor             ax,ax
  421.                 repe scasw
  422.                 or              cx,cx
  423.                 jnz             ExitSIS0
  424.                 mov             si,[bp+10]
  425.                 sub             si,128
  426.                 mov             CharsUsed[si],0
  427.                 dec             TotalUsed
  428.                 mov             ax,1
  429. ExitSIS0:       ret
  430. SeeIfSpace      endp
  431.  
  432. ModifyPixel     proc            near
  433. ; Calling sequence:  ModifyPixel(CharNo:  integer;  x,y,Value:  byte);
  434. ; Set a pixel in CharNo to Value, which can be 0 or 1.  x & y are offsets
  435. ; into the character matrix which are based on resolutions of 8x8, 8x14,
  436. ; and 8x16.  CharNo is in the range of 128 to 511.
  437.  
  438. Value           equ             byte ptr [bp+4]
  439. y               equ             word ptr [bp+6]     ; Treat as a word so it
  440. x               equ             byte ptr [bp+8]     ; can be added quickly
  441. CharNo          equ             word ptr [bp+10]
  442.  
  443.                 push            bp
  444.                 mov             bp,sp
  445.                 mov             si,CharNo
  446.                 cmp             si,128
  447.                 jb              ExitMP
  448.                 cmp             si,511
  449.                 ja              ExitMP
  450.                 les             di,Buffer
  451.                 sub             si,128
  452.                 mov             al,Points
  453.                 xor             ah,ah
  454.                 xor             dx,dx
  455.                 mul             si
  456.                 mov             si,ax
  457.                 mov             Temp2,ax
  458.                 and             y,0ffh
  459.                 add             si,y
  460.                 add             di,si
  461.                 cmp             Value,1
  462.                 jz              SetPixel
  463.                 mov             cl,x
  464.                 mov             bl,128
  465.                 shr             bl,cl
  466.                 not             bl
  467.                 and             es:[di],bl
  468.                 call            SeeIfSpace
  469.                 jmp             short ExitMP
  470. SetPixel:       mov             cl,x
  471.                 mov             bl,128
  472.                 shr             bl,cl
  473.                 or              es:[di],bl
  474.                 xor             ax,ax
  475. ExitMP:         pop             bp
  476.                 ret             8
  477. ModifyPixel     endp
  478.  
  479. GetChar         proc            near
  480. ; Calling sequence:  GetChar(x,y:  integer):  integer;
  481. ; Given a coordinate, return the character at that coordinate.  x & y
  482. ; are given as screen coordinates in the range of 640x200, 640x350, or
  483. ; 640x400 depending on the mode.  The returned character is in the range
  484. ; of 0 to 511.
  485. y               equ             word ptr [bp+4]
  486. x               equ             word ptr [bp+6]
  487.  
  488.                 push            bp
  489.                 mov             bp,sp
  490.                 mov             ax,0b800h
  491.                 mov             es,ax
  492.                 mov             ax,y
  493.                 div             Points
  494.                 xor             ah,ah
  495.                 mov             si,ax
  496.                 mov             ax,80
  497.                 xor             dx,dx
  498.                 mul             si
  499.                 mov             si,x
  500.                 mov             cl,3
  501.                 shr             si,cl
  502.                 add             ax,si
  503.                 shl             ax,1
  504.                 mov             si,ax
  505.                 mov             ax,es:[si]
  506.                 and             ah,8
  507.                 shr             ah,cl
  508.                 pop             bp
  509.                 ret             4
  510. GetChar         endp
  511.  
  512. Pset            proc            far
  513. ; Calling sequence:  Pset(x,y:  integer;  Color:  byte);
  514. ; Plot a point at x,y with the attribute in Color.  Update the hardware
  515. ; font with the new information.
  516. Color           equ             byte ptr [bp+6]
  517. y               equ             word ptr [bp+8]
  518. x               equ             word ptr [bp+10]
  519.  
  520.                 push            bp
  521.                 mov             bp,sp
  522.                 push            x
  523.                 push            y
  524.                 call            GetChar
  525.                 cmp             ax,128
  526.                 jae             InRang
  527.                 cmp             TotalUsed,384
  528.                 jb              InRang2
  529.                 jmp             short ExitP1
  530. InRang2:        cmp             Color,0
  531.                 jz              ExitP1
  532.                 call            GetNewChar
  533. InRang:         cmp             ax,0
  534.                 jz              ExitP1
  535.                 push            ax
  536.                 push            x
  537.                 push            y
  538.                 cmp             Color,0
  539.                 jz              DoPush0
  540.                 mov             ax,1
  541.                 push            ax
  542.                 jmp             short DidPush1
  543. DoPush0:        mov             ax,0
  544.                 push            ax
  545. DidPush1:       mov             al,Color
  546.                 xor             ah,ah
  547.                 push            ax
  548.                 call            WriteDot
  549.                 call            WriteFont
  550. ExitP1:         pop             bp
  551.                 ret             6
  552. Pset            endp
  553.  
  554. Pset2           proc            near
  555. ; Calling sequence:  Pset2(x,y:  integer;  Color:  byte);
  556. ; Plot a point at x,y with the attribute in Color.  Does not update the
  557. ; actual hardware font table (for use by higher-level routines).
  558. Color           equ             byte ptr [bp+4]
  559. y               equ             word ptr [bp+6]
  560. x               equ             word ptr [bp+8]
  561.  
  562.                 push            bp
  563.                 mov             bp,sp
  564.                 push            x
  565.                 push            y
  566.                 call            GetChar
  567.                 cmp             ax,128
  568.                 jae             InRange
  569.                 cmp             TotalUsed,384
  570.                 jb              InRange2
  571.                 jmp             short ExitP2
  572. InRange2:       cmp             Color,0
  573.                 jz              ExitP2
  574.                 call            GetNewChar
  575. InRange:        cmp             ax,0
  576.                 jz              ExitP2
  577.                 push            ax
  578.                 push            x
  579.                 push            y
  580.                 cmp             Color,0
  581.                 jz              Push0
  582.                 mov             ax,1
  583.                 push            ax
  584.                 jmp             short Pushed1
  585. Push0:          mov             ax,0
  586.                 push            ax
  587. Pushed1:        mov             al,Color
  588.                 xor             ah,ah
  589.                 push            ax
  590.                 call            WriteDot
  591. ExitP2:         pop             bp
  592.                 ret             6
  593. Pset2           endp
  594.  
  595. MaskColors      proc            far
  596. ; Display the low-intensity character attributes only, disregarding the
  597. ; value specfied at bit 3 of the attribute bytes.  Effective until
  598. ; the video mode is changed.
  599.                 mov             ax,1000h
  600.                 mov             bx,0712h
  601.                 int             10h
  602.                 ret
  603. MaskColors      endp
  604.  
  605. Freeze          proc             far
  606. ; Copies video memory to an alternate page and flips to that page.
  607.                 push             ax
  608.                 push             ds
  609.                 mov              ax,40h         ; Save CRT start & active page
  610.                 mov              es,ax
  611.                 push             word ptr es:[4eh]   ; BIOS CRT_START
  612.                 push             word ptr es:[62h]   ; BIOS ACTIVE_PAGE
  613.                 mov              ax,0b800h      ; Segment of mode CO80 (3)
  614.                 mov              es,ax
  615.                 mov              ds,ax
  616.                 mov              si,0           ; Source:       This page
  617.                 mov              di,2000h       ; Destination:  Page 2
  618.                 mov              cx,1000h       ; Set to copy 2000h bytes
  619.                 cld                             ; Forward copy
  620.                 rep movsw                       ; Do the copy
  621.                 mov              ax,0502h       ; Function:  Go to page 2
  622.                 int              10h            ; Switch the page
  623.                 mov              ax,40h         ; Restore CRT start &
  624.                 mov              es,ax          ; active page so that all
  625.                 pop              word ptr es:[62h] ; BIOS functions take
  626.                 pop              word ptr es:[4eh] ; place on "frozen," non-
  627.                 pop              ds                ; displayed page 0
  628.                 pop              ax
  629.                 ret
  630. Freeze          endp
  631.  
  632. Unfreeze        proc             far
  633. ; Flips back to page 0 to show what has been put there.
  634.                 mov              ax,0500h       ; Function:  Display page 0
  635.                 int              10h            ; Call BIOS
  636.                 ret
  637. Unfreeze        endp
  638.  
  639. DoHlin          proc            near
  640. ; Designed for interface with Ellipse procedure.  Call with the first
  641. ; (x,y) coordinate in CX,DX, and the amount to add (twice) in SI
  642. ; Color is in AX
  643.                 push            ax
  644.                 push            bx
  645.                 push            cx
  646.                 push            dx
  647.                 push            si
  648.                 push            di
  649.  
  650.                 push            cx
  651.                 push            dx
  652.                 add             cx,si
  653.                 add             cx,si
  654.                 push            cx
  655.                 push            ax
  656.                 call            Hlin2
  657.  
  658.                 pop             di
  659.                 pop             si
  660.                 pop             dx
  661.                 pop             cx
  662.                 pop             bx
  663.                 pop             ax
  664.                 ret
  665. DoHlin          endp
  666.  
  667. DoPset          proc            near
  668. ; For use with the Ellipse procedure as an interface to the main pixel-set
  669. ; routine, Pset2.
  670. x               equ             word ptr [bp+8]
  671. y               equ             word ptr [bp+6]
  672. Color           equ             byte ptr [bp+4]
  673.                 push            bp
  674.                 mov             bp,sp
  675.  
  676.                 push            ax
  677.                 push            bx
  678.                 push            cx
  679.                 push            dx
  680.                 push            si
  681.                 push            di
  682.                 push            es
  683.  
  684.                 push            x
  685.                 push            y
  686.                 mov             al,Color
  687.                 xor             ah,ah
  688.                 push            ax
  689.                 call            Pset2
  690.  
  691.                 pop             es
  692.                 pop             di
  693.                 pop             si
  694.                 pop             dx
  695.                 pop             cx
  696.                 pop             bx
  697.                 pop             ax
  698.                 pop             bp
  699.                 ret             6
  700. DoPset          endp
  701.  
  702. ; The following macro swaps n1 & n2 if n1>n2:
  703. SwapIfNeeded    macro        n1,n2
  704.         Local        ExitSwap
  705.         mov        ax,n1
  706.         cmp        ax,n2
  707.         jle        ExitSwap
  708.         xchg        ax,n2
  709.         mov        n1,ax
  710. ExitSwap:
  711.         endm
  712.  
  713. Hlin            proc            far
  714. ; Calling sequence:  Hlin(x1,y1,x2:  integer;  Color:  byte);
  715. ; Draws a horizontal line from x1,y1 to x2,y1 using the attribute
  716. ; specified in Color.  Updates the hardware font table.
  717. Color           equ             byte ptr [bp+6]
  718. x2              equ             word ptr [bp+8]
  719. y1              equ             word ptr [bp+10]
  720. x1              equ             word ptr [bp+12]
  721.  
  722.                 push            bp
  723.                 mov             bp,sp
  724.                 SwapIfNeeded    x1,x2
  725.                 mov             bx,x1
  726. LoopHlin1:      push            bx
  727.                 push            bx
  728.                 push            y1
  729.                 mov             al,Color
  730.                 xor             ah,ah
  731.                 push            ax
  732.                 call            Pset2
  733.                 pop             bx
  734.                 inc             bx
  735.                 cmp             bx,x2
  736.                 jbe             LoopHlin1
  737.                 call            WriteFont
  738.                 pop             bp
  739.                 ret             8
  740. Hlin            endp
  741.  
  742. Hlin2           proc            near
  743. ; Calling sequence:  Hlin2(x1,y1,x2:  integer;  Color:  byte);
  744. ; Draws a horizontal line from x1,y1 to x2,y1 using the attribute
  745. ; specified in Color.  The hardware font table is not updated.
  746. Color           equ             byte ptr [bp+4]
  747. x2              equ             word ptr [bp+6]
  748. y1              equ             word ptr [bp+8]
  749. x1              equ             word ptr [bp+10]
  750.  
  751.                 push            bp
  752.                 mov             bp,sp
  753.                 SwapIfNeeded    x1,x2
  754.                 mov             bx,x1
  755. LoopHlin2:      push            bx
  756.                 push            bx
  757.                 push            y1
  758.                 mov             al,Color
  759.                 xor             ah,ah
  760.                 push            ax
  761.                 call            Pset2
  762.                 pop             bx
  763.                 inc             bx
  764.                 cmp             bx,x2
  765.                 jbe             LoopHlin2
  766.                 pop             bp
  767.                 ret             8
  768. Hlin2           endp
  769.  
  770. Vlin            proc            far
  771. ; Calling sequence:  Vlin(x1,y1,y2:  integer;  Color:  byte);
  772. ; Draws a vertical line from x1,y1 to x1,y2 using the attribute specified
  773. ; in Color.  The hardware font table is updated.
  774. Color           equ             byte ptr [bp+6]
  775. y2              equ             word ptr [bp+8]
  776. y1              equ             word ptr [bp+10]
  777. x1              equ             word ptr [bp+12]
  778.  
  779.                 push            bp
  780.                 mov             bp,sp
  781.                 SwapIfNeeded    y1,y2
  782.                 mov             bx,y1
  783. LoopVlin:       push            bx
  784.                 push            x1
  785.                 push            bx
  786.                 mov             al,Color
  787.                 xor             ah,ah
  788.                 push            ax
  789.                 call            Pset2
  790.                 pop             bx
  791.                 inc             bx
  792.                 cmp             bx,y2
  793.                 jbe             LoopVlin
  794.                 call            WriteFont
  795.                 pop             bp
  796.                 ret             8
  797. Vlin            endp
  798.  
  799. Vlin2           proc            near
  800. ; Calling sequence:  Vlin(x1,y1,y2:  integer;  Color:  byte);
  801. ; Draws a vertical line from x1,y1 to x1,y2 using the attribute
  802. ; specified in Color.  The hardware font table is not updated.
  803. Color           equ             byte ptr [bp+4]
  804. y2              equ             word ptr [bp+6]
  805. y1              equ             word ptr [bp+8]
  806. x1              equ             word ptr [bp+10]
  807.  
  808.                 push            bp
  809.                 mov             bp,sp
  810.                 SwapIfNeeded    y1,y2
  811.                 mov             bx,y1
  812. LoopVlin2:      push            bx
  813.                 push            x1
  814.                 push            bx
  815.                 mov             al,Color
  816.                 xor             ah,ah
  817.                 push            ax
  818.                 call            Pset2
  819.                 pop             bx
  820.                 inc             bx
  821.                 cmp             bx,y2
  822.                 jbe             LoopVlin2
  823.                 pop             bp
  824.                 ret             8
  825. Vlin2           endp
  826.  
  827. Box             proc            far
  828. ; Calling sequence:  Box(x1,y1,x2,y2:  integer;  Color:  byte);
  829. ; Draws a filled-in box with the attribute specified in Color.
  830. ; The upper-left coordinate is x1,y1.  The lower right is x2,y2.
  831. Color           equ             byte ptr [bp+6]
  832. y2              equ             word ptr [bp+8]
  833. x2              equ             word ptr [bp+10]
  834. y1              equ             word ptr [bp+12]
  835. x1              equ             word ptr [bp+14]
  836.  
  837.                 push            bp
  838.                 mov             bp,sp
  839.                 SwapIfNeeded    x1,x2
  840.                 SwapIfNeeded    y1,y2
  841.                 mov             bx,y1
  842. LoopBox:        push            bx
  843.                 push            x1
  844.                 push            bx
  845.                 push            x2
  846.                 mov             al,Color
  847.                 xor             ah,ah
  848.                 push            ax
  849.                 call            Hlin2
  850.                 pop             bx
  851.                 inc             bx
  852.                 cmp             bx,y2
  853.                 jbe             LoopBox
  854.                 call            WriteFont
  855.                 pop             bp
  856.                 ret             10
  857. Box             endp
  858.  
  859. OpenBox         proc            far
  860. ; Calling sequence:  OpenBox(x1,y1,x2,y2:  integer;  Color:  byte);
  861. ; Draws the outline of a box using the attribute specified in Color.
  862. ; The upper-left coordinate is x1,y1.  The lower-right is x2,y2.
  863. Color           equ             byte ptr [bp+6]
  864. y2              equ             word ptr [bp+8]
  865. x2              equ             word ptr [bp+10]
  866. y1              equ             word ptr [bp+12]
  867. x1              equ             word ptr [bp+14]
  868.  
  869.                 push            bp
  870.                 mov             bp,sp
  871.                 mov             al,Color
  872.                 xor             ah,ah
  873.                 push            ax
  874.                 push            x1
  875.                 push            y1
  876.                 push            x2
  877.                 push            ax
  878.                 call            Hlin2
  879.                 pop             ax
  880.                 push            ax
  881.                 push            x1
  882.                 push            y2
  883.                 push            x2
  884.                 push            ax
  885.                 call            Hlin2
  886.                 pop             ax
  887.                 push            ax
  888.                 push            x1
  889.                 push            y1
  890.                 push            y2
  891.                 push            ax
  892.                 call            Vlin2
  893.                 pop             ax
  894.                 push            ax
  895.                 push            x2
  896.                 push            y1
  897.                 push            y2
  898.                 push            ax
  899.                 call            Vlin2
  900.                 pop             ax
  901.                 call            WriteFont
  902.                 pop             bp
  903.                 ret             10
  904. OpenBox         endp
  905.  
  906. Line        proc        far
  907. ; Calling sequence:  Line(x1,y1,x2,y2:  integer;  Color:  byte);
  908. ; Draws a line from x1,y1 to x2,y2 using the attribute specified in Color.
  909. ; Uses Bresenham's line algorithm.  Actual code has been taken from
  910. ; a Plume/Waite book by Robert Lafore:  Assembly language primer for the
  911. ; IBM PC & XT.
  912. Color        equ        word ptr [bp+6]
  913. y2        equ        word ptr [bp+8]
  914. x2        equ        word ptr [bp+10]
  915. y1        equ        word ptr [bp+12]
  916. x1        equ        word ptr [bp+14]
  917.  
  918.         push        bp
  919.         mov        bp,sp
  920.         mov        ax,y2
  921.         sub        ax,y1
  922.         mov        si,1
  923.         jge        store_y
  924.         mov        si,-1
  925.         neg        ax
  926. store_y:    mov        delta_y,ax
  927.         mov        ax,x2
  928.         sub        ax,x1
  929.         mov        di,1
  930.         jge        store_x
  931.         mov        di,-1
  932.         neg        ax
  933. store_x:    mov        delta_x,ax
  934.         mov        ax,delta_x
  935.         cmp        ax,delta_y
  936.         jl        csteep
  937.         call        easy
  938.         jmp        finish
  939. csteep:        call        steep
  940. finish:         call            WriteFont
  941.                 pop        bp
  942.              ret        10
  943.  
  944. easy        proc        near
  945.         mov        ax,delta_x
  946.         shr        ax,1
  947.         mov        halfx,ax
  948.         mov        cx,x1
  949.         mov        dx,y1
  950.         mov        bx,0
  951.         mov        ax,delta_x
  952.         mov        count,ax
  953. newdot:        push        cx
  954.         push        dx
  955.         push        Color
  956.         call        DoPset
  957.         add        cx,di
  958.         add        bx,delta_y
  959.         cmp        bx,halfy
  960.         jle        dcount
  961.         sub        bx,delta_x
  962.         add        dx,si
  963. dcount:        dec        count
  964.         jge        newdot
  965.         ret
  966. easy        endp
  967.  
  968. steep        proc        near
  969.         mov        ax,delta_y
  970.         shr        ax,1
  971.         mov        halfy,ax
  972.         mov        cx,x1
  973.         mov        dx,y1
  974.         mov        bx,0
  975.         mov        ax,delta_y
  976.         mov        count,ax
  977. newdot2:        push        cx
  978.         push        dx
  979.         push        Color
  980.         call        DoPset
  981.         add        dx,si
  982.         add        bx,delta_x
  983.         cmp        bx,halfy
  984.         jle        dcount2
  985.         sub        bx,delta_y
  986.         add        cx,di
  987. dcount2:    dec        count
  988.         jge        newdot2
  989.         ret
  990. steep        endp
  991. Line        endp
  992.  
  993. Ellipse         proc            far
  994. ; Call With:  Ellipse(x1,y1,r1,r2:  word;  Color:  byte);
  995. ; Draws an ellipse centered at x1,y1;  the x-radius is in r1, and the
  996. ; y-radius is in r2.  The attribute is specified in Color.
  997. ; Note:  if bit 7 of the color is high, the entire ellipse if
  998. ; filled (and the bit is stripped).  If it's low, just the
  999. ; perimeter is filled.
  1000. ; The code has been taken from "EGA/VGA, A Programmer's Reference Guide" by
  1001. ; Dyck Kliewer and published by Intertext/McGraw-Hill
  1002. x1              equ             word ptr [bp+14]
  1003. y1              equ             word ptr [bp+12]
  1004. r1              equ             word ptr [bp+10]
  1005. r2              equ             word ptr [bp+8]
  1006. Color           equ             byte ptr [bp+6]
  1007. ;
  1008. r_l             equ             1
  1009. t_b             equ             11111110b
  1010. pixpb           equ             3
  1011. b_mask          equ             10000000b
  1012.  
  1013.  
  1014.                 push            bp
  1015.                 mov             bp,sp
  1016.  
  1017.                 and             portion,t_b
  1018.                 call            e_call
  1019.                 or              portion,r_l
  1020.                 push            r2
  1021.                 push            r1
  1022.                 pop             r2
  1023.                 pop             r1
  1024.                 call            e_call
  1025.  
  1026.                 call            WriteFont
  1027.  
  1028.                 pop             bp
  1029.                 ret             10
  1030.  
  1031. e_call          proc            near
  1032.                 push            ax
  1033.                 push            bx
  1034.                 push            cx
  1035.                 push            dx
  1036.                 mov             ax,x1
  1037.                 mov             c_x,ax
  1038.                 mov             ax,y1
  1039.                 mov             c_y,ax
  1040.                 mov             ax,0
  1041.                 mov             xe,0
  1042.                 mov             bx,r2
  1043.                 mov             ye,bx
  1044.                 mov             cx,r1
  1045.                 call            near ptr ellip
  1046.                 pop             dx
  1047.                 pop             cx
  1048.                 pop             bx
  1049.                 pop             ax
  1050.                 ret
  1051. e_call          endp
  1052.  
  1053.  
  1054. ellip           proc            near
  1055.                 push            bp
  1056.                 mov             Old_BP,bp
  1057.                 mov             si,ax
  1058.                 mov             ax,bx
  1059.                 mul             bx
  1060.                 mov             bp,dx
  1061.                 mov             bx,ax
  1062.                 mov             r2_lo,ax
  1063.                 mov             r2_hi,dx
  1064.                 mov             ax,cx
  1065.                 mul             cx
  1066.                 mov             di,dx
  1067.                 mov             cx,ax
  1068.                 mov             r1_lo,ax
  1069.                 mov             r1_hi,dx
  1070.  
  1071.                 push            bx
  1072.                 push            cx
  1073.                 push            di
  1074.                 push            bp
  1075.                 push            si
  1076.                 mul             ax
  1077.                 mov             bp,ax
  1078.                 mov             bx,dx
  1079.                 mov             ax,di
  1080.                 mul             cx
  1081.                 shl             ax,1
  1082.                 rcl             dx,1
  1083.                 add             bx,ax
  1084.                 mov             cx,dx
  1085.                 mov             ax,di
  1086.                 mul             ax
  1087.                 add             cx,ax
  1088.                 mov             ax,bp
  1089.                 mov             dx,r2_lo
  1090.                 mov             di,r2_hi
  1091.                 add             dx,r1_lo
  1092.                 adc             di,r1_hi
  1093.                 mov             bp,0
  1094.                 mov             si,0
  1095. div_loop:       cmp             cx,0
  1096.                 jne             c_div
  1097.                 cmp             bx,di
  1098.                 ja              c_div
  1099.                 cmp             ax,dx
  1100.                 jae             c_div
  1101.                 jmp             short div_done
  1102. c_div:          inc             bp
  1103.                 jnz             no_of
  1104.                 inc             si
  1105. no_of:          sub             ax,dx
  1106.                 sbb             bx,di
  1107.                 sbb             cx,0
  1108.                 jmp             short div_loop
  1109. div_done:       shl             ax,1
  1110.                 rcl             bx,1
  1111.                 cmp             di,bx
  1112.                 ja              no_up
  1113.                 cmp             dx,ax
  1114.                 ja              no_up
  1115.                 inc             bp
  1116.                 jnz             no_up
  1117.                 inc             si
  1118. no_up:          sub             bx,bx
  1119.                 cmp             dx,0
  1120.                 jne             rt_strt
  1121.                 cmp             si,0
  1122.                 jne             rt_strt
  1123.                 jmp             rt_done
  1124. rt_strt:        mov             bx,512
  1125.                 mov             cx,512
  1126. rt_lp:          shr             cx,1
  1127.                 mov             ax,bx
  1128.                 mul             ax
  1129.                 cmp             dx,si
  1130.                 jg              t_lg
  1131.                 jl              t_sm
  1132.                 cmp             ax,bp
  1133.                 jb              t_sm
  1134.                 jmp             short t_lg
  1135. t_sm:           add             ax,bx
  1136.                 adc             dx,0
  1137.                 cmp             si,dx
  1138.                 ja              t_sm2
  1139.                 cmp             bp,ax
  1140.                 ja              t_sm2
  1141.                 jmp             short rt_done
  1142. t_sm2:          add             bx,cx
  1143.                 jmp             short rt_lp
  1144. t_lg:           sub             ax,bx
  1145.                 sbb             dx,0
  1146.                 cmp             dx,si
  1147.                 ja              t_lg2
  1148.                 cmp             ax,bp
  1149.                 ja              t_lg2
  1150.                 jmp             short rt_done
  1151. t_lg2:          sub             bx,cx
  1152.                 jmp             short rt_lp
  1153. rt_done:        inc             bx
  1154.                 mov             max_x,bx
  1155.                 pop             si
  1156.                 pop             bp
  1157.                 pop             di
  1158.                 pop             cx
  1159.                 pop             bx
  1160.  
  1161.                 push            bx
  1162.                 push            bp
  1163.                 mov             ax,cx
  1164.                 mul             ye
  1165.                 mov             bx,ax
  1166.                 mov             bp,dx
  1167.                 mov             ax,di
  1168.                 mul             ye
  1169.                 add             bp,ax
  1170.                 neg             bx
  1171.                 not             bp
  1172.                 shl             bx,1
  1173.                 rcl             bp,1
  1174.                 add             cx,bx
  1175.                 adc             di,bp
  1176.                 mov             t_e_lo,cx
  1177.                 mov             t_e_hi,di
  1178.  
  1179.                 shl             r1_lo,1
  1180.                 rcl             r1_hi,1
  1181.                 shl             r1_lo,1
  1182.                 rcl             r1_hi,1
  1183.                 mov             bx,ye
  1184.                 dec             bx
  1185.                 mov             ax,r1_lo
  1186.                 mul             bx
  1187.                 mov             bp,dx
  1188.                 neg             ax
  1189.                 mov             y_p_lo,ax
  1190.                 mov             ax,r1_hi
  1191.                 mul             bx
  1192.                 add             ax,bp
  1193.                 not             ax
  1194.                 mov             y_p_hi,ax
  1195.                 pop             bp
  1196.                 pop             bx
  1197.                 shl             bx,1
  1198.                 rcl             bp,1
  1199.                 push            bx
  1200.                 push            bp
  1201.                 shl             bx,1
  1202.                 rcl             bp,1
  1203.                 mov             r2_lo,bx
  1204.                 mov             r2_hi,bp
  1205.                 mov             cx,bx
  1206.                 mov             di,bp
  1207.                 pop             bp
  1208.                 pop             bx
  1209.                 mov             dx,t_e_hi
  1210.                 mov             ax,t_e_lo
  1211.  
  1212. retest:         ; Plot the points:
  1213.  
  1214.                 push            ax
  1215.                 push            bx
  1216.                 push            cx
  1217.                 push            dx
  1218.                 push            di
  1219.                 push            si
  1220.                 push            bp
  1221.                 mov             bp,Old_BP
  1222.                 mov             di,ye
  1223.                 test            portion,r_l
  1224.                 jz              no_xchg
  1225.                 xchg            si,di
  1226. no_xchg:        mov             al,Color
  1227.                 xor             ah,ah
  1228.                 test            al,128
  1229.                 jnz             DoHlinPlot
  1230.                 mov             cx,c_x
  1231.                 add             cx,si
  1232.                 mov             dx,c_y
  1233.                 add             dx,di
  1234.                 push            cx
  1235.                 push            dx
  1236.                 push            ax
  1237.                 call            DoPset
  1238.                 sub             cx,si
  1239.                 sub             cx,si
  1240.                 push            cx
  1241.                 push            dx
  1242.                 push            ax
  1243.                 call            DoPset
  1244.                 sub             dx,di
  1245.                 sub             dx,di
  1246.                 push            cx
  1247.                 push            dx
  1248.                 push            ax
  1249.                 call            DoPset
  1250.                 add             cx,si
  1251.                 add             cx,si
  1252.                 push            cx
  1253.                 push            dx
  1254.                 push            ax
  1255.                 call            DoPset
  1256.                 jmp             short DonePlot
  1257.  
  1258. DoHlinPlot:     and             al,01111111b
  1259.                 mov             cx,c_x
  1260.                 sub             cx,si
  1261.                 mov             dx,c_y
  1262.                 add             dx,di
  1263.                 call            DoHlin
  1264.                 sub             dx,di
  1265.                 sub             dx,di
  1266.                 call            DoHlin
  1267.  
  1268. DonePlot:       pop             bp
  1269.                 pop             si
  1270.                 pop             di
  1271.                 pop             dx
  1272.                 pop             cx
  1273.                 pop             bx
  1274.                 pop             ax
  1275.  
  1276.                 cmp             si,max_x
  1277.                 jne             e_cont
  1278.                 jmp             e_done
  1279.  
  1280. e_cont:         cmp             dx,0
  1281.                 jl              Less1
  1282.                 push            bx
  1283.                 push            bp
  1284.                 mov             bx,y_p_lo
  1285.                 mov             bp,y_p_hi
  1286.                 add             ax,bx
  1287.                 adc             dx,bp
  1288.                 dec             ye
  1289.                 add             bx,r1_lo
  1290.                 adc             bp,r1_hi
  1291.                 mov             y_p_lo,bx
  1292.                 mov             y_p_hi,bp
  1293.                 pop             bp
  1294.                 pop             bx
  1295. Less1:          add             ax,bx
  1296.                 adc             dx,bp
  1297.                 inc             si
  1298.                 add             bx,cx
  1299.                 adc             bp,di
  1300.                 jmp             Retest
  1301. e_done:         pop             bp
  1302.                 ret
  1303. ellip           endp
  1304. Ellipse         endp
  1305.  
  1306. Code            ends
  1307.                 end
  1308.