home *** CD-ROM | disk | FTP | other *** search
/ Boston 2 / boston-2.iso / DOS / PROGRAM / C / GRAPH / GRAPH.ASM next >
Assembly Source File  |  1993-12-01  |  34KB  |  1,592 lines

  1. ;
  2. ; Graphics display routines.    Copyright 1987    Everett Kaser
  3. ;                        35405 Spruce St
  4. ;                        Albany, OR 97321
  5. ;                        (503) 928-5259
  6. ;                    work:    (503) 750-3569
  7. ;
  8. page    60,132
  9. title    DISPLAY I/O ROUTINES for CGA 320x200 and EGA 640x350 graphics modes
  10. ;
  11. font1    equ    0
  12. ;
  13. ; for this entire module, the origin (0,0) is at the bottom-left of the screen.
  14. ;
  15. ;                    Everett Kaser    11-03-86
  16. ;                        for C    06-24-87
  17. CGA    EQU    0    ; return values for
  18. EGA    EQU    1    ;   setmode function
  19. ;
  20. _text    segment    byte public 'code'
  21. _text    ends
  22. _data    segment    word public 'data'
  23. _data    ends
  24. const    segment    word public 'const'
  25. const    ends
  26. _bss    segment    word public 'bss'
  27. _bss    ends
  28. ;
  29.     public    _setmode
  30.     public    _setcolors
  31.     public    _plotxy
  32.     public    _bplotxy
  33.     public    _line
  34.     public    _horline
  35.     public    _verline
  36.     public    _clrscreen
  37.     public    _setrand
  38.     public    _rand
  39.     public    _beepon
  40.     public    _beepoff
  41.     public    _flabel
  42.     public    _iskey
  43.     public    _key
  44.     public    _movebytes
  45. ;
  46.     public    _machine
  47. ;
  48. dgroup    group    const, _bss, _data
  49.     assume    cs:_text, ds:dgroup, ss:dgroup, es:dgroup
  50. ;
  51. _data    segment    word public 'data'
  52. ;
  53. _machine    dw    ?
  54. ;
  55. seed    dw    4
  56. ;
  57. color    db    ?
  58. rule    db    ?
  59. backclr    db    ?
  60. string    dw    ?
  61. rowcnt    db    ?
  62. colcnt    db    ?
  63. x1    dw    ?
  64. y1    dw    ?
  65. x2    dw    ?
  66. y2    dw    ?
  67. stepx    dw    ?
  68. stepy    dw    ?
  69. difx    dw    ?
  70. dify    dw    ?
  71. halfdifx dw    ?
  72. halfdify dw    ?
  73. ;
  74. vidseg    dw    ?
  75. ;
  76. maskbyte db    ?
  77. masks    db    256 dup (0)
  78. ;
  79. ; here are two different fonts. currently I'm using the second font. If
  80. ; you want to use the first, you have to change the FONT1 EQU at the
  81. ; beginning of the file to be EQU'd to 1.
  82. ;
  83. if font1
  84. chartab    db    00h,00h,00h,00h,00h,00h,00h,00h        ; 0
  85.     db    0Eh,10h,0Ch,02h,1Ch,05h,07h,05h
  86.     db    0Eh,10h,0Ch,02h,1Ch,05h,02h,05h
  87.     db    1Ch,10h,1Ch,10h,1Ch,05h,02h,05h
  88.     db    1Ch,10h,1Ch,10h,1Ch,07h,02h,02h
  89.     db    1Ch,10h,1Ch,10h,1Ch,0Ah,0Ah,07h
  90.     db    0Ch,12h,1Eh,12h,04h,05h,06h,05h
  91.     db    1Ch,12h,1Ch,12h,1Ch,04h,04h,07h
  92.     db    1Ch,12h,1Ch,12h,1Fh,04h,02h,0Ch
  93.     db    14h,14h,1Ch,14h,14h,07h,02h,02h
  94.     db    10h,10h,10h,1Ch,07h,04h,06h,04h        ; 10
  95.     db    11h,0Ah,04h,00h,07h,02h,02h,02h
  96.     db    1Eh,10h,1Ch,10h,17h,04h,06h,04h
  97.     db    0Ch,12h,10h,10h,0Eh,09h,0Eh,09h
  98.     db    0Eh,10h,0Ch,02h,1Eh,09h,09h,06h
  99.     db    0Eh,10h,0Ch,02h,1Ch,07h,02h,07h
  100.     db    1Ch,12h,12h,1Ch,00h,04h,04h,07h
  101.     db    1Ch,12h,12h,1Ch,01h,01h,01h,01h
  102.     db    1Ch,12h,12h,1Ch,06h,01h,02h,07h
  103.     db    1Ch,12h,12h,1Fh,01h,03h,01h,07h
  104.     db    1Ch,12h,12h,1Ch,05h,05h,07h,01h        ; 20
  105.     db    12h,1Ah,16h,12h,04h,05h,06h,05h
  106.     db    0Eh,10h,0Ch,02h,1Dh,0Dh,0Bh,09h
  107.     db    1Ch,10h,18h,16h,1Dh,06h,05h,06h
  108.     db    0Ch,12h,10h,0Ch,09h,0Dh,0Bh,09h
  109.     db    1Ch,10h,1Ch,10h,1Dh,1Bh,15h,11h
  110.     db    07h,08h,04h,1Eh,05h,06h,05h,06h
  111.     db    1Ch,10h,1Ch,10h,1Fh,04h,04h,03h
  112.     db    1Eh,10h,1Ch,10h,13h,04h,02h,0Ch
  113.     db    0Eh,10h,16h,12h,0Fh,04h,02h,0Ch
  114.     db    1Ch,12h,1Ch,12h,13h,04h,02h,0Ch        ; 30
  115.     db    12h,12h,12h,0Ch,03h,04h,02h,0Ch
  116.     db    00h,00h,00h,00h,00h,00h,00h,00h
  117.     db    06h,06h,06h,06h,06h,00h,06h,00h
  118.     db    1Bh,1Bh,09h,12h,00h,00h,00h,00h
  119.     db    00h,0Ah,1Fh,0Ah,1Fh,0Ah,00h,00h
  120.     db    04h,0Fh,14h,0Eh,05h,1Eh,04h,00h
  121.     db    18h,19h,02h,04h,08h,13h,03h,00h
  122.     db    0Ch,1Ah,1Ah,0Dh,1Ah,1Ah,0Dh,00h
  123.     db    06h,06h,02h,04h,00h,00h,00h,00h
  124.     db    06h,0Ch,18h,18h,18h,0Ch,06h,00h        ; 40
  125.     db    0Ch,06h,03h,03h,03h,06h,0Ch,00h
  126.     db    00h,0Ah,04h,1Fh,04h,0Ah,00h,00h
  127.     db    00h,04h,04h,1Fh,04h,04h,00h,00h
  128.     db    00h,00h,00h,00h,06h,06h,02h,04h
  129.     db    00h,00h,00h,1Fh,00h,00h,00h,00h
  130.     db    00h,00h,00h,00h,00h,06h,06h,00h
  131.     db    00h,01h,03h,06h,0Ch,18h,10h,00h
  132.     db    0Eh,19h,19h,1Bh,1Dh,19h,0Eh,00h
  133.     db    06h,0Eh,06h,06h,06h,06h,0Fh,00h
  134.     db    0Eh,13h,03h,06h,0Ch,18h,1Fh,00h        ; 50
  135.     db    0Eh,13h,03h,0Eh,03h,13h,0Eh,00h
  136.     db    16h,16h,16h,16h,1Fh,06h,06h,00h
  137.     db    1Fh,18h,1Eh,03h,03h,13h,0Eh,00h
  138.     db    0Eh,19h,18h,1Eh,19h,19h,0Eh,00h
  139.     db    1Fh,03h,06h,0Ch,0Ch,0Ch,0Ch,00h
  140.     db    0Eh,19h,19h,0Eh,19h,19h,0Eh,00h
  141.     db    0Eh,13h,13h,0Fh,03h,13h,0Eh,00h
  142.     db    00h,06h,06h,00h,06h,06h,00h,00h
  143.     db    00h,06h,06h,00h,06h,06h,02h,04h
  144.     db    03h,06h,0Ch,18h,0Ch,06h,03h,00h        ; 60
  145.     db    00h,00h,1Fh,00h,1Fh,00h,00h,00h
  146.     db    18h,0Ch,06h,03h,06h,0Ch,18h,00h
  147.     db    0Eh,13h,03h,06h,04h,00h,04h,00h
  148.     db    0Eh,11h,17h,15h,17h,10h,0Fh,00h
  149.     db    0Eh,19h,19h,1Fh,19h,19h,19h,00h
  150.     db    1Eh,19h,19h,1Eh,19h,19h,1Eh,00h
  151.     db    0Eh,19h,18h,18h,18h,19h,0Eh,00h
  152.     db    1Eh,19h,19h,19h,19h,19h,1Eh,00h
  153.     db    1Fh,18h,18h,1Eh,18h,18h,1Fh,00h
  154.     db    1Fh,18h,18h,1Eh,18h,18h,18h,00h        ; 70
  155.     db    0Eh,19h,18h,1Bh,19h,19h,0Fh,00h
  156.     db    19h,19h,19h,1Fh,19h,19h,19h,00h
  157.     db    0Fh,06h,06h,06h,06h,06h,0Fh,00h
  158.     db    1Fh,06h,06h,06h,16h,16h,0Ch,00h
  159.     db    19h,1Ah,1Ch,18h,1Ch,1Ah,19h,00h
  160.     db    18h,18h,18h,18h,18h,18h,1Fh,00h
  161.     db    11h,1Bh,1Fh,15h,15h,11h,11h,00h
  162.     db    19h,19h,1Dh,1Fh,1Bh,19h,19h,00h
  163.     db    0Eh,19h,19h,19h,19h,19h,0Eh,00h
  164.     db    1Eh,19h,19h,1Eh,18h,18h,18h,00h        ; 80
  165.     db    0Eh,19h,19h,19h,1Dh,1Ah,0Dh,00h
  166.     db    1Eh,19h,19h,1Eh,1Bh,19h,19h,00h
  167.     db    0Eh,19h,18h,0Eh,03h,13h,0Eh,00h
  168.     db    1Fh,0Ch,0Ch,0Ch,0Ch,0Ch,0Ch,00h
  169.     db    19h,19h,19h,19h,19h,19h,0Eh,00h
  170.     db    19h,19h,19h,19h,19h,0Ah,04h,00h
  171.     db    11h,11h,15h,15h,1Fh,1Bh,11h,00h
  172.     db    19h,1Bh,0Eh,04h,0Eh,1Bh,13h,00h
  173.     db    19h,19h,0Bh,0Eh,06h,06h,06h,00h
  174.     db    1Fh,03h,07h,0Eh,1Ch,18h,1Fh,00h        ; 90
  175.     db    1Eh,18h,18h,18h,18h,18h,1Eh,00h
  176.     db    00h,10h,18h,0Ch,06h,03h,01h,00h
  177.     db    0Fh,03h,03h,03h,03h,03h,0Fh,00h
  178.     db    04h,0Eh,1Bh,11h,00h,00h,00h,00h
  179.     db    00h,00h,00h,00h,00h,00h,3Fh,00h
  180.     db    04h,08h,0Ch,0Ch,00h,00h,00h,00h
  181.     db    00h,00h,0Eh,03h,0Fh,13h,0Fh,00h
  182.     db    18h,18h,1Eh,19h,19h,19h,1Eh,00h
  183.     db    00h,00h,0Eh,19h,18h,18h,0Fh,00h
  184.     db    03h,03h,0Fh,13h,13h,13h,0Fh,00h        ; 100
  185.     db    00h,00h,0Eh,19h,1Fh,18h,0Fh,00h
  186.     db    07h,0Ch,1Fh,0Ch,0Ch,0Ch,1Eh,00h
  187.     db    00h,00h,0Fh,13h,13h,0Fh,03h,1Eh
  188.     db    18h,18h,1Eh,19h,19h,19h,19h,00h
  189.     db    06h,00h,0Eh,06h,06h,06h,0Fh,00h
  190.     db    03h,00h,07h,03h,03h,03h,13h,0Eh
  191.     db    18h,18h,19h,1Ah,1Ch,1Ah,19h,00h
  192.     db    0Eh,06h,06h,06h,06h,06h,0Fh,00h
  193.     db    00h,00h,11h,1Bh,1Fh,15h,11h,00h
  194.     db    00h,00h,1Eh,19h,19h,19h,19h,00h        ; 110
  195.     db    00h,00h,0Eh,19h,19h,19h,0Eh,00h
  196.     db    00h,00h,1Eh,19h,19h,1Eh,18h,18h
  197.     db    00h,00h,0Fh,13h,13h,0Fh,03h,03h
  198.     db    00h,00h,1Eh,19h,18h,18h,18h,00h
  199.     db    00h,00h,0Fh,18h,1Fh,03h,1Eh,00h
  200.     db    0Ch,0Ch,1Fh,0Ch,0Ch,0Dh,06h,00h
  201.     db    00h,00h,13h,13h,13h,13h,0Fh,00h
  202.     db    00h,00h,19h,19h,19h,0Ah,04h,00h
  203.     db    00h,00h,11h,15h,1Fh,1Bh,11h,00h
  204.     db    00h,00h,19h,0Eh,04h,0Eh,13h,00h        ; 120
  205.     db    00h,00h,13h,13h,13h,0Fh,03h,1Eh
  206.     db    00h,00h,1Fh,06h,0Ch,18h,1Fh,00h
  207.     db    07h,0Ch,0Ch,18h,0Ch,0Ch,07h,00h
  208.     db    06h,06h,06h,06h,06h,06h,06h,00h
  209.     db    1Ch,06h,06h,03h,06h,06h,1Ch,00h
  210.     db    00h,08h,1Dh,17h,02h,00h,00h,00h
  211.     db    15h,0Ah,15h,0Ah,15h,0Ah,15h,00h
  212. else
  213. chartab    db    4,12,28,60,28,12,4,0            ; 0
  214.     db    8,0,8,16,34,34,28,0
  215.     db    124,0,68,40,16,40,68,0
  216.     db    124,0,68,100,84,76,68,0
  217.     db    0,0,52,72,72,72,52,0
  218.     db    56,68,68,120,68,68,120,0
  219.     db    124,68,32,16,32,68,124,0
  220.     db    0,16,8,124,8,16,0,0
  221.     db    0,16,32,124,32,16,0,0
  222.     db    16,16,16,16,84,56,16,0
  223.     db    16,56,84,16,16,16,16,0            ; 10
  224.     db    64,32,16,40,68,68,68,0
  225.     db    0,0,36,36,36,56,64,0
  226.     db    0,0,0,0,0,0,0,0
  227.     db    0,4,56,80,16,16,16,0
  228.     db    0,4,56,104,40,40,40,0
  229.     db    56,68,68,124,68,68,56,0
  230.     db    60,80,80,120,80,80,124,0
  231.     db    0,0,40,84,92,80,60,0
  232.     db    16,56,68,68,124,68,68,0
  233.     db    16,0,56,72,72,72,52,0            ; 20
  234.     db    40,56,68,68,124,68,68,0
  235.     db    40,0,56,72,72,72,52,0
  236.     db    40,56,68,68,68,68,56,0
  237.     db    40,0,56,68,68,68,56,0
  238.     db    40,68,68,68,68,68,56,0
  239.     db    40,0,68,68,68,68,56,0
  240.     db    64,64,64,124,64,64,64,0
  241.     db    24,24,24,24,24,24,24,24
  242.     db    0,0,0,255,255,0,0,0
  243.     db    24,36,32,112,32,32,124,0        ; 30
  244.     db    24,24,24,255,255,24,24,24
  245.     db    0,0,0,0,0,0,0,0
  246.     db    8,8,8,8,8,0,8,0
  247.     db    40,40,40,0,0,0,0,0
  248.     db    40,40,124,40,124,40,40,0
  249.     db    16,60,80,56,20,120,16,0
  250.     db    96,100,8,16,32,76,12,0
  251.     db    32,80,80,32,84,72,52,0
  252.     db    8,8,8,0,0,0,0,0
  253.     db    16,32,64,64,64,32,16,0            ; 40
  254.     db    16,8,4,4,4,8,16,0
  255.     db    16,84,56,16,56,84,16,0
  256.     db    0,16,16,124,16,16,0,0
  257.     db    0,0,0,0,8,8,16,0
  258.     db    0,0,0,124,0,0,0,0
  259.     db    0,0,0,0,0,8,0,0
  260.     db    0,4,8,16,32,64,0,0
  261.     db    56,68,76,84,100,68,56,0
  262.     db    16,48,16,16,16,16,56,0
  263.     db    56,68,4,24,32,64,124,0            ; 50
  264.     db    124,4,8,24,4,68,56,0
  265.     db    8,24,40,72,124,8,8,0
  266.     db    124,64,120,4,4,68,56,0
  267.     db    28,32,64,120,68,68,56,0
  268.     db    124,4,8,16,32,32,32,0
  269.     db    56,68,68,56,68,68,56,0
  270.     db    56,68,68,60,4,8,112,0
  271.     db    0,0,16,0,16,0,0,0
  272.     db    0,0,16,0,16,16,32,0
  273.     db    4,8,16,32,16,8,4,0            ; 60
  274.     db    0,0,124,0,124,0,0,0
  275.     db    64,32,16,8,16,32,64,0
  276.     db    56,68,68,8,16,0,16,0
  277.     db    56,68,84,88,88,64,60,0
  278.     db    56,68,68,124,68,68,68,0            ; 65 A
  279.     db    120,68,68,120,68,68,120,0
  280.     db    56,68,64,64,64,68,56,0
  281.     db    120,68,68,68,68,68,120,0
  282.     db    124,64,64,120,64,64,124,0
  283.     db    124,64,64,120,64,64,64,0        ; 70
  284.     db    60,64,64,64,76,68,60,0
  285.     db    68,68,68,124,68,68,68,0
  286.     db    56,16,16,16,16,16,56,0
  287.     db    4,4,4,4,4,68,56,0
  288.     db    68,72,80,96,80,72,68,0
  289.     db    64,64,64,64,64,64,124,0
  290.     db    68,108,84,84,68,68,68,0
  291.     db    68,68,100,84,76,68,68,0
  292.     db    56,68,68,68,68,68,56,0
  293.     db    120,68,68,120,64,64,64,0        ; 80
  294.     db    56,68,68,68,84,72,52,0
  295.     db    120,68,68,120,80,72,68,0
  296.     db    56,68,64,56,4,68,56,0
  297.     db    124,16,16,16,16,16,16,0
  298.     db    68,68,68,68,68,68,56,0
  299.     db    68,68,68,68,40,40,16,0
  300.     db    68,68,68,84,84,108,68,0
  301.     db    68,68,40,16,40,68,68,0
  302.     db    68,68,40,16,16,16,16,0
  303.     db    124,4,8,16,32,64,124,0            ; 90
  304.     db    124,96,96,96,96,96,124,0
  305.     db    0,64,32,16,8,4,0,0
  306.     db    124,12,12,12,12,12,124,0
  307.     db    16,40,68,0,0,0,0,0
  308.     db    0,0,0,0,0,0,124,0
  309.     db    64,32,16,8,0,0,0,0
  310.     db    0,0,56,4,60,68,60,0
  311.     db    64,64,88,100,68,68,120,0
  312.     db    0,0,0,60,64,64,60,0
  313.     db    4,4,52,76,68,68,60,0            ; 100
  314.     db    0,0,56,68,124,64,56,0
  315.     db    8,16,16,56,16,16,16,0
  316.     db    0,0,60,68,60,4,24,0
  317.     db    64,64,88,100,68,68,68,0
  318.     db    0,8,0,24,8,8,28,0
  319.     db    0,4,0,4,4,36,24,0
  320.     db    32,32,36,40,48,40,36,0
  321.     db    24,8,8,8,8,8,28,0
  322.     db    0,0,104,84,84,84,84,0
  323.     db    0,0,88,100,68,68,68,0            ; 110
  324.     db    0,0,56,68,68,68,56,0
  325.     db    0,0,120,68,120,64,64,0
  326.     db    0,0,56,72,56,8,4,0
  327.     db    0,0,44,48,32,32,32,0
  328.     db    0,0,60,64,56,4,120,0
  329.     db    0,16,56,16,16,16,8,0
  330.     db    0,0,68,68,68,72,52,0
  331.     db    0,0,68,68,40,40,16,0
  332.     db    0,0,68,68,84,84,40,0
  333.     db    0,0,68,40,16,40,68,0            ; 120
  334.     db    0,0,68,40,16,32,64,0
  335.     db    0,0,124,8,16,32,124,0
  336.     db    16,32,32,64,32,32,16,0
  337.     db    16,16,16,0,16,16,16,0
  338.     db    16,8,8,4,8,8,16,0
  339.     db    0,0,32,84,8,0,0,0
  340.     db    84,40,84,40,84,40,84,0            ; 127
  341. endif
  342. ;
  343. _data    ends
  344.     page
  345.  
  346.  
  347.  
  348. _text    segment
  349.  
  350.  
  351.  
  352. ; setmode(mode);
  353. ;
  354. ; SETMODE --- change the display mode
  355. ;    at entry:    AL = 0    40x25 BW
  356. ;                 1    40x25 COLOR
  357. ;                 2    80x25 BW
  358. ;                 3    80x25 COLOR
  359. ;                 4    320x200 COLOR
  360. ;                 5    320x200 BW
  361. ;                 6    640x200 BW
  362. ;                 7    80x25 BW (monochrome)
  363. ;                10h    640x350 COLOR (ega)
  364. _setmode:
  365.     push    bp
  366.     mov    bp,sp
  367.     mov    ax,[bp+4]        ; get mode
  368.     cmp    al,4            ; 320x200 CGA graphics?
  369.     jb    smode            ; jif no
  370. ;
  371. ; the following sets up the byte mask table for the bplotxy 'collision' function
  372. ; (currently is supported only by 320x200 CGA graphics mode 4).
  373. ;
  374.     push    ax            ; save mode
  375.     push    es
  376.     push    ds
  377.     pop    es
  378. cgamakemasks:
  379.     lea    di,masks        ; load offset of mask bytes
  380.     xor    ah,ah            ; there are four pixels per byte of
  381. smloop:    xor    al,al            ; CGA 320x200 color video RAM.  Each
  382.     test    ah,3            ; pixel has 2 bits, selecting one of
  383.     jz    sml1            ; four colors. 00 = background color.
  384.     or    al,3            ; these mask bytes are used during 
  385. sml1:    test    ah,0ch            ; BPLOTXY to determine if a non-backgnd
  386.     jz    sml2            ; color is being bplotted onto a 
  387.     or    al,0ch            ; non-background color, resulting in a
  388. sml2:    test    ah,30h            ; 'collision'.  There are 256 masks, 1
  389.     jz    sml3            ; for each possible bplot byte.  For
  390.     or    al,30h            ; each pixel (pair of bits), if either
  391. sml3:    test    ah,0c0h            ; bit is set, then both bits of the 
  392.     jz    sml4            ; mask are set, so by ANDing the masks
  393.     or    al,0c0h            ; with the bplot bytes and the video
  394. sml4:    stosb                ; bytes, we can tell if any of the four
  395.     inc    ah            ; pixels in the current byte collide.
  396.     jnz    smloop
  397.     pop    es
  398.     pop    ax
  399. smode:
  400.     mov    ah,0            ; bios int 10 function setmode
  401.     cmp    al,10h            ; EGA graphics?
  402.     jz    isega            ; jif yes
  403.     mov    vidseg,0b800h        ; default video ram segment to CGA
  404.     mov    _machine,CGA        ; default machine type to CGA
  405. successful:
  406.     int    10h
  407.     mov    ax,1
  408.     pop    bp
  409.     ret
  410. isega:
  411.     mov    vidseg,0a000h        ; set video ram segment to EGA
  412.     mov    _machine,EGA        ; set disptype to EGA
  413.     push    ax
  414.     mov    ah,12h            ; return ega information
  415.     mov    bx,0ff10h        ; set bh = ff to see if it changes 
  416.     int    10h            ;   if bh changes, it's ega
  417.     pop    ax
  418.     cmp    bh,0ffh            ; ega?
  419.     jnz    successful        ; jif yes
  420.     xor    ax,ax
  421.     pop    bp
  422.     ret
  423.     page
  424. ;
  425. ; setcolors(colorset, color);
  426. ;
  427. _setcolors:
  428.     push    bp
  429.     mov    bp,sp
  430.     mov    bx,[bp+4]    ; get colorset
  431.     mov    ax,[bp+6]    ; get color
  432.     call    setcolor
  433.     pop    bp
  434.     ret
  435. ;
  436. setcolor:
  437.     cmp    _machine,0
  438.     jnz    egasetcolors
  439. ;
  440. ; cgasetcolors --- sets colorset, background color
  441. ;
  442. ;    at entry:    AL = background color (0-15)
  443. ;                0 black        6  brown    12 light red
  444. ;                1 blue        7  white    13 light magenta
  445. ;                2 green        8  gray        14 yellow
  446. ;                3 cyan        9  light blue    15 white bright
  447. ;                4 red        10 light green
  448. ;                5 magenta    11 light cyan
  449. ;            BL = color set (1=cyan/magenta/white 0=green/red/brown)
  450. cgasetcolors:
  451.     push    ax        ; save background color
  452.     mov    bh,1        ; set color id 1 (select palette)
  453.     mov    ah,11        ; set color palette function of int 10h
  454.     int    10h
  455.     pop    bx        ; recover background color
  456.     mov    bh,0        ; set color id 0 (background color)
  457.     mov    ah,11        ; set color palette function of int 10h
  458.     int    10h
  459.     ret
  460. ;
  461. ; sets ega palette registers
  462. ;    on entry:
  463. ;        AL = color value
  464. ;        BL = palette number
  465. ;
  466. egasetcolors:
  467.     mov    bh,al        ; copy color value
  468.     mov    ah,10h        ; set palette call
  469.     mov    al,0        ; set palette color sub-function number
  470.     cmp    bl,16        ; overscan?
  471.     jnz    egasc        ; jif no
  472.     inc    al        ; change sub-function
  473. egasc:
  474.     int    10h
  475.     ret
  476.     page
  477. ;
  478. ; plotxy(x,y,color,rule);
  479. ;
  480. _plotxy:
  481.     push    bp
  482.     mov    bp,sp
  483.     push    si
  484.     push    di
  485.     mov    cx,[bp+4]    ; get x
  486.     mov    bx,[bp+6]    ; get y
  487.     mov    dx,[bp+8]    ; get color
  488.     mov    ax,[bp+10]    ; get rule
  489.     mov    dh,al
  490.     call    pixel
  491.     pop    di
  492.     pop    si
  493.     pop    bp
  494.     ret
  495. ;
  496. ; xxxPIXEL --- color a pixel on the display
  497. ;
  498. ;    at entry:    BX = y-coordinate
  499. ;            CX = x-coordinate
  500. ;            DL = color
  501. ;            DH = replacement rule (0=force, 1=and, 2=or, 3=xor)
  502. ;
  503. pixel:
  504.     cmp    _machine,0
  505.     jnz    egapixel
  506. ;
  507. cgapixel:
  508.     call    cgamapxy
  509.     push    ds
  510.     mov    ds,vidseg
  511.     or    dh,dh        ; force pixel?
  512.     jz    pxyforce
  513.     cmp    dh,3        ; xor pixel?
  514.     jz    pxyxor
  515.     cmp    dh,2        ; or pixel?
  516.     jz    pxyor
  517. pxyand:
  518.     or    al,dl        ; put and-mask into color byte
  519.     and    [di],al        ; and color into display
  520.     jmp    short plotexit
  521. pxyxor:
  522.     xor    [di],dl        ; xor color into display
  523. plotexit:
  524.     pop    ds
  525.     ret
  526. pxyor:
  527.     or    [di],dl        ; or color into display
  528.     jmp    plotexit
  529. pxyforce:
  530.     and    [di],al        ; clear pixel in display
  531.     or    [di],dl        ; force new bits into display
  532.     jmp    plotexit
  533. ;
  534. egapixel:
  535.     call    egamapxy
  536.     push    es
  537.     mov    es,vidseg
  538.     push    dx        ; save bit mask
  539.  
  540.     shl    cl,1
  541.     shl    cl,1        ; set logical operation in ega controller
  542.     shl    cl,1
  543.     mov    dx,3ceh
  544.     mov    al,3
  545.     out    dx,al
  546.     inc    dx
  547.     mov    al,cl
  548.     out    dx,al
  549.  
  550.     dec    dx
  551.     mov    al,8
  552.     out    dx,al        ; set bit mask
  553.     inc    dx
  554.     pop    ax        ; recover bit mask
  555.     out    dx,al
  556.  
  557.     mov    dx,3c4h
  558.     mov    al,2
  559.     out    dx,al        ; set plane mask (to set 1 bits of color)
  560.     inc    dx
  561.     mov    al,ch        ; get color
  562.     out    dx,al
  563.  
  564.     mov    ah,es:[di]    ; latch current data first
  565.     mov    al,0ffh        ; blend in new bits
  566.     stosb
  567.     dec    di
  568.  
  569.     mov    dx,3c4h
  570.     mov    al,2
  571.     out    dx,al        ; set plane mask (to zero 0 bits of color)
  572.     inc    dx
  573.     mov    al,ch        ; get color
  574.     not    al        ; invert
  575.     out    dx,al
  576.  
  577.     mov    ah,es:[di]    ; latch current data first
  578.     mov    al,0        ; logic-force new off bits
  579.     stosb
  580.     pop    es
  581.     ret
  582. ;
  583. cgamapxy:
  584.     mov    ax,199
  585.     sub    ax,bx        ; invert y coord
  586.     and    ax,0fffeh    ; trash lower bit for odd/even
  587.     shl    ax,1
  588.     shl    ax,1
  589.     shl    ax,1
  590.     mov    di,ax        ; si = 16*y
  591.     shl    ax,1
  592.     shl    ax,1        ; ax = 64*y
  593.     add    di,ax        ; si = 16*y + 64*y = 80*y
  594.     test    bl,1        ; odd or even scan line?
  595.     jnz    cgamapodd
  596.     add    di,2000h    ; offset to odd bank
  597. cgamapodd:
  598.     mov    ax,cx        ; get x-coord
  599.     shr    ax,1
  600.     shr    ax,1        ; ax = x/4    (cga320x200 = 4 pixels/byte)
  601.     add    di,ax        ; si = offset of byte containing pixel
  602.     and    cl,3        ; keep bit address
  603.     shl    cl,1
  604.     ror    dl,1        ; get color info in msbits
  605.     ror    dl,1
  606.     ror    dl,cl        ; put color info in right place for pixel
  607.     mov    al,3fh        ; get pixel mask
  608.     ror    al,cl
  609.     ret
  610. ;
  611. egamapxy:
  612.     mov    ax,349
  613.     sub    ax,bx        ; invert y coord
  614.     shl    ax,1
  615.     shl    ax,1
  616.     shl    ax,1
  617.     shl    ax,1
  618.     mov    di,ax        ; di = 16*y
  619.     shl    ax,1
  620.     shl    ax,1        ; ax = 64*y
  621.     add    di,ax        ; di = 16*y + 64*y = 80*y
  622.     mov    ax,cx        ; get x-coord
  623.     shr    ax,1
  624.     shr    ax,1        ; ax = x/8    (ega650x350 = 8 pixels/byte)
  625.     shr    ax,1
  626.     add    di,ax        ; di = offset of byte containing pixel
  627.     and    cx,7        ; keep bit address
  628.     mov    ch,dl        ; save color
  629.     mov    dl,80h
  630.     ror    dl,cl        ; put color info in right place for pixel
  631.     mov    cl,dh        ; save rule
  632.     ret
  633.     page
  634. ;
  635. ; bplotxy(x, y, height, width, picture, rule);
  636. ;
  637. ; BPLOTXY --- plot a raster picture
  638. ;    at entry:    BX = y-coordinate
  639. ;            CX = x-coordinate
  640. ;            DL = height (# of rows in picture)
  641. ;            DH = width (# of bytes in picture)
  642. ;            SI = ptr to picture
  643. ;            BP = 0 for force,  8000h for xor
  644. ;
  645. ;    at exit:    AL = 0 if no collision, #0 if collision
  646. _bplotxy:
  647.     push    bp
  648.     mov    bp,sp
  649.     cld
  650.     push    si
  651.     push    di
  652.     mov    bx,[bp+6]
  653.     mov    cx,[bp+4]
  654.     mov    dx,[bp+8]
  655.     mov    ax,[bp+10]
  656.     mov    dh,al
  657.     mov    si,[bp+12]
  658.     mov    bp,[bp+14]
  659.     cmp    _machine,0
  660.     jz    cgabplot
  661.     jmp    egabplot
  662. cgabplot:
  663.     push    dx        ; save high,wide
  664.     call    cgamapxy
  665.     pop    dx        ; recover
  666.     and    bx,1
  667.     and    bp,8000h
  668.     or    bp,bx        ; bp = even/odd row flag
  669.     lea    bx,masks
  670.     mov    maskbyte,0
  671.     push    es
  672.     mov    es,vidseg
  673. bpxybeglin:
  674.     mov    ch,dh        ; copy bytes/row
  675.     xor    ah,ah        ; zero upper byte
  676. bpxydoline:
  677.     mov    al,[si]        ; get first byte of data
  678.     shr    ax,cl        ; shift to correct bit alignment
  679.     push    ax
  680.     xlat
  681.     and    al,es:[di]    ; check for collisions
  682.     or    maskbyte,al
  683.     pop    ax
  684.     test    bp,8000h    ; force?
  685.     jz    bpxyf1        ; jif yes
  686.     xor    es:[di],al    ; xor in the byte
  687.     jmp    short bpxyfcom
  688. bpxyf1:
  689.     mov    es:[di],al    ; force it
  690. bpxyfcom:
  691.     inc    di        ; move to next byte of display
  692.     lodsb            ; refetch byte for upper this time
  693.     mov    ah,al        ; copy it
  694.     dec    ch        ; decrement bytes/row count
  695.     jnz    bpxydoline    ; jif til line is done
  696.     or    cl,cl        ; byte aligned?
  697.     jz    bpxyaligned    ; jif yes, we're done with row
  698.     xor    al,al        ; zero lower byte (last byte on row)
  699.     shr    ax,cl        ; shift to correct bit alignment
  700.     push    ax
  701.     xlat
  702.     and    al,es:[di]    ; check for collisions
  703.     or    maskbyte,al
  704.     pop    ax
  705.     test    bp,8000h    ; force?
  706.     jz    bpxyf2        ; jif yes
  707.     xor    es:[di],al    ; xor last bits into display
  708.     jmp    short bpxyaligned
  709. bpxyf2:
  710.     mov    es:[di],al
  711. bpxyaligned:
  712.     mov    al,dh        ; get bytes/row
  713.     xor    ah,ah
  714.     sub    di,ax        ; move back to start of display box
  715.     xor    bp,1        ; toggle odd/even flag
  716.     test    bp,1        ; even next?
  717.     jnz    bpxyeven    ; jif yes
  718.     add    di,2000h    ; move to odd bank
  719.     jmp    short bpxynext
  720. bpxyeven:
  721.     sub    di,1fb0h    ; move back to even bank, next row
  722. bpxynext:
  723.     dec    dl        ; decrement row counter
  724.     jnz    bpxybeglin    ; jif til done
  725.     pop    es
  726.     mov    al,maskbyte
  727.     pop    di
  728.     pop    si
  729.     pop    bp
  730.     ret
  731. ;
  732. ;
  733. egabplot:
  734.     push    dx
  735.     call    egamapxy
  736.     mov    bl,dl        ; save bit mask
  737.     pop    dx        ; recover high/wide
  738.     mov    ah,dh        ; copy width
  739.     mov    bh,dl        ; copy height
  740.     push    es
  741.     mov    es,vidseg
  742.     mov    cl,0
  743.     test    bp,8000h    ; force?
  744.     jz    egab2        ; jif yes
  745.     mov    cl,18h        ; xor
  746. egab2:
  747.     mov    dx,3ceh
  748.     mov    al,3
  749.     out    dx,al        ; set logical operation in ega controller
  750.     inc    dx
  751.     mov    al,cl
  752.     out    dx,al
  753. egab1:
  754.     mov    cl,ah        ; get width of picture
  755.     xor    ch,ch
  756.     push    di        ; save screen pointer
  757.     push    bx        ; save bit mask
  758. egab3:
  759.     mov    dx,3ceh
  760.     mov    al,8
  761.     out    dx,al        ; set bit mask
  762.     inc    dx
  763.     mov    al,bl
  764.     out    dx,al
  765.  
  766.     mov    dx,3c4h
  767.     mov    al,2
  768.     out    dx,al        ; set plane mask (to set 1 bits of color)
  769.     inc    dx
  770.     mov    al,[si]        ; get next pixel color
  771.     out    dx,al
  772.  
  773.     mov    al,es:[di]        ; latch current data first
  774.     mov    byte ptr es:[di],0ffh    ; blend in new color bits
  775.  
  776.     dec    dx
  777.     mov    al,2
  778.     out    dx,al        ; set plane mask (to zero 0 bits of color)
  779.     inc    dx
  780.     lodsb            ; get color
  781.     not    al        ; invert
  782.     out    dx,al
  783.  
  784.     mov    al,es:[di]        ; latch current data first
  785.     mov    byte ptr es:[di],0    ; logic-force new off bits
  786.     ror    bl,1
  787.     or    bl,bl
  788.     jns    egabok
  789.     inc    di
  790. egabok:
  791.     loop    egab3
  792.     pop    bx
  793.     pop    di
  794.     add    di,80        ; move to next row
  795.     dec    bh
  796.     jnz    egab1
  797.     mov    ax,0
  798.     pop    es
  799.     pop    di
  800.     pop    si
  801.     pop    bp
  802.     ret
  803.     page
  804. ;
  805. ; line(x1, y1, x2, y2, color, rule);
  806. ;
  807. _line:
  808.     push    bp
  809.     mov    bp,sp
  810.  
  811.     mov    word ptr stepx,1    ; init x step value
  812.     mov    word ptr stepy,1    ; init y step value
  813.  
  814.     mov    bx,[bp+4]        ; get x-coords of endpoints
  815.     mov    x1,bx
  816.     mov    ax,[bp+8]
  817.     mov    x2,ax
  818.  
  819.     sub    ax,bx            ; get difx
  820.     jnb    gotdifx            ; jif x2 >= x1
  821.     neg    ax            ; else get x1-x2
  822.     neg    word ptr stepx        ; make stepx = -1
  823. gotdifx:
  824.     mov    difx,ax            ; save difx away
  825.  
  826.     mov    dx,[bp+6]        ; get y-coords of endpoints
  827.     mov    y1,dx
  828.     mov    cx,[bp+10]
  829.     mov    y2,cx
  830.  
  831.     sub    cx,dx            ; get dify
  832.     jnb    gotdify            ; jif y2 >= y1
  833.     neg    cx            ; else get y1-y2
  834.     neg    word ptr stepy        ; make stepy = -1
  835. gotdify:    
  836.     mov    dify,cx            ; save dify away
  837.  
  838.     mov    ax,[bp+12]        ; get color
  839.     mov    color,al
  840.     mov    al,[bp+14]        ; get replacement rule
  841.     mov    rule,al
  842.  
  843. ;**************************************************************
  844. ; register usage:
  845. ;
  846. ;    bp=incflag
  847. ;    ds=data segment
  848. ;    si=counter
  849. ;    ax=scratch
  850. ;    bx=row
  851. ;    cx=scratch
  852. ;    dx=row
  853. ;**************************************************************
  854. ;
  855.     xor    bp,bp            ; init flag
  856.     mov    si,bp            ; init counter
  857. ;
  858. ; if difx >= dify then stepx else stepy
  859. ;
  860.     mov    ax,difx            ; get difx
  861.     cmp    ax,cx            ; is difx >= dify ?
  862.     jb    dostepy            ; jif no
  863.     shr    ax,1            ; get difx / 2
  864.     mov    halfdifx,ax        ; save away
  865.     mov    bx,dx            ; get y1
  866. forcol:
  867.     mov    cx,x1            ; get x1
  868.     jmp    short forcolloop
  869. fcl:
  870.     add    cx,stepx
  871. forcolloop:    
  872.     call    linedot
  873.     add    si,dify            ; add it to counter
  874.     cmp    halfdifx,si        ; if halfdifx >= counter
  875.     jnb    notx            ;     then don't do it
  876.     or    bp,bp            ; if incflag
  877.     jnz    notx            ;     then don't do it
  878.     inc    bp            ; set flag
  879.     add    bx,stepy        ; move to next row
  880. notx:
  881.     cmp    si,difx            ; if counter < difx
  882.     jb    colwhile        ;     then don't reset flag
  883.     sub    si,difx            ; dock counter by proper count
  884.     xor    bp,bp            ; reset flag
  885. colwhile:
  886.     cmp    cx,x2
  887.     jnz    fcl
  888. done:
  889.     pop    bp
  890.     ret
  891. ;
  892. ;
  893. dostepy:
  894.     mov    ax,dify            ; get dify
  895.     shr    ax,1            ; get dify / 2
  896.     mov    halfdify,ax        ; save away
  897.     mov    cx,bx            ; get x1
  898. forrow:
  899.     mov    bx,y1            ; get y1
  900.     jmp    short forrowloop
  901. frl:
  902.     add    bx,stepy
  903. forrowloop:    
  904.     call    linedot
  905.     add    si,difx            ; add it to counter
  906.     cmp    halfdify,si        ; if halfdifx >= counter
  907.     jnb    noty            ;     then don't do it
  908.     or    bp,bp            ; if incflag
  909.     jnz    noty            ;     then don't do it
  910.     inc    bp            ; set flag
  911.     add    cx,stepx        ; move to next col
  912. noty:
  913.     cmp    si,dify            ; if counter < dify
  914.     jb    rowwhile        ;     then don't reset flag
  915.     sub    si,dify            ; dock counter by proper count
  916.     xor    bp,bp            ; reset flag
  917. rowwhile:
  918.     cmp    bx,y2
  919.     jnz    frl
  920.     jmp    done
  921. ;
  922. ;
  923. ;
  924. ;    bx=row
  925. ;    cx=col
  926. ;    bp, si, bx, cx should not be destroyed
  927. ;
  928. linedot:
  929.     push    cx
  930.     push    bx
  931.     push    si
  932.     push    bp
  933.     mov    dl,color
  934.     mov    dh,rule
  935.     call    pixel
  936.     pop    bp
  937.     pop    si
  938.     pop    bx
  939.     pop    cx
  940.     ret
  941.     page
  942. ;
  943. ; horline(x1, y1, x2, color, rule);
  944. ;
  945. _horline:
  946.     push    bp
  947.     mov    bp,sp
  948.     mov    bx,[bp+4]        ; get x1
  949.     mov    x1,bx
  950.     mov    cx,[bp+6]        ; get y1
  951.     mov    y1,cx
  952.     mov    ax,[bp+8]        ; get x2
  953.     mov    x2,ax
  954.     mov    dx,[bp+10]        ; get color
  955.     mov    color,dl
  956.     mov    dx,[bp+12]        ; get rule
  957.     mov    rule,dl
  958.  
  959.     sub    ax,bx            ; get difx
  960.     jnb    hgotdifx        ; jif x2 >= x1
  961.     neg    ax            ; else get x1-x2
  962.     mov    dx,x2
  963.     mov    x1,dx
  964.     mov    x2,bx
  965. hgotdifx:
  966.     inc    ax            ; # of dots to write
  967.     mov    difx,ax            ; save difx away
  968.     mov    bx,cx            ; get start y
  969.     mov    cx,x1            ; get start x
  970.     mov    dl,color
  971.     cmp    _machine,0
  972.     jz    cgahorline
  973.     jmp    egahorline
  974. cgahorline:
  975.     call    cgamapxy
  976.     mov    cx,difx
  977.     mov    dh,rule
  978.     push    ds
  979.     mov    ds,vidseg
  980.     or    dh,dh
  981.     jz    hpxyforce
  982.     cmp    dh,3
  983.     jz    hpxyxor
  984.     cmp    dh,2
  985.     jz    hpxyor
  986. hpxyand:
  987.     or    dl,al        ; force all other bits on for anding
  988. hpxya:
  989.     and    [di],dl        ; and in color
  990.     ror    dl,1
  991.     ror    dl,1
  992.     ror    al,1
  993.     ror    al,1
  994.     or    al,al
  995.     js    hxandok
  996.     inc    di
  997. hxandok:
  998.     loop    hpxya
  999.     jmp    short hlexit
  1000. hpxyxor:
  1001.     xor    [di],dl        ; xor color into display
  1002.     ror    dl,1
  1003.     ror    dl,1
  1004.     ror    al,1
  1005.     ror    al,1
  1006.     or    al,al
  1007.     js    hxorok
  1008.     inc    di
  1009. hxorok:
  1010.     loop    hpxyxor
  1011. hlexit:
  1012.     pop    ds
  1013.     pop    bp
  1014.     ret
  1015. hpxyor:
  1016.     or    [di],dl        ; or color into display
  1017.     ror    dl,1
  1018.     ror    dl,1
  1019.     ror    al,1
  1020.     ror    al,1
  1021.     or    al,al
  1022.     js    horok
  1023.     inc    di
  1024. horok:
  1025.     loop    hpxyor
  1026.     jmp    hlexit
  1027. hpxyforce:
  1028.     and    [di],al        ; clear pixel in display
  1029.     or    [di],dl        ; force new bits into display
  1030.     ror    dl,1
  1031.     ror    dl,1
  1032.     ror    al,1
  1033.     ror    al,1
  1034.     or    al,al
  1035.     js    hforceok
  1036.     inc    di
  1037. hforceok:
  1038.     loop    hpxyforce
  1039.     jmp    hlexit
  1040. ;
  1041. ;
  1042. egahorline:
  1043.     call    egamapxy
  1044.     mov    bl,dl        ; save bit mask
  1045.     mov    bh,ch        ; save color
  1046.     mov    cx,difx
  1047.     mov    ah,rule
  1048.     push    ds
  1049.     mov    ds,vidseg
  1050.  
  1051.     shl    ah,1
  1052.     shl    ah,1        ; set logical operation in ega controller
  1053.     shl    ah,1
  1054.     mov    dx,3ceh
  1055.     mov    al,3
  1056.     out    dx,al
  1057.     inc    dx
  1058.     mov    al,ah
  1059.     out    dx,al
  1060.  
  1061. egahl:
  1062.     mov    dx,3ceh
  1063.     mov    al,8
  1064.     out    dx,al        ; set bit mask
  1065.     inc    dx
  1066.     mov    al,bl        ; recover bit mask
  1067.     test    al,80h        ; at start of byte?
  1068.     jz    eganot80    ; jif no
  1069.     cmp    cx,8        ; full byte to do?
  1070.     jb    eganot80    ; jif no
  1071.     call    egahlbytes    ; do full bytes
  1072.     or    cx,cx        ; any odd bits left?
  1073.     jz    egahlexit    ; jif no
  1074.     jmp    egahl
  1075. eganot80:
  1076.     out    dx,al        ; set bit mask
  1077.  
  1078.     mov    dx,3c4h
  1079.     mov    al,2
  1080.     out    dx,al        ; set plane mask (to set 1 bits of color)
  1081.     inc    dx
  1082.     mov    al,bh        ; get color
  1083.     out    dx,al
  1084.  
  1085.     mov    al,[di]        ; latch current data first
  1086.     mov    byte ptr [di],0ffh    ; blend in new color bits
  1087.  
  1088.     dec    dx
  1089.     mov    al,2
  1090.     out    dx,al        ; set plane mask (to zero 0 bits of color)
  1091.     inc    dx
  1092.     mov    al,bh        ; get color
  1093.     not    al        ; invert
  1094.     out    dx,al
  1095.  
  1096.     mov    al,[di]        ; latch current data first
  1097.     mov    byte ptr [di],0    ; logic-force new off bits
  1098.     ror    bl,1
  1099.     or    bl,bl
  1100.     jns    egahlok
  1101.     inc    di
  1102. egahlok:
  1103.     loop    egahl
  1104. egahlexit:
  1105.     pop    ds
  1106.     pop    bp
  1107.     ret
  1108. ;
  1109. egahlbytes:
  1110.     mov    al,0ffh        ; write all bits of byte at once
  1111.     out    dx,al        ; set bit mask
  1112. egahlb:
  1113.     mov    dx,3c4h
  1114.     mov    al,2
  1115.     out    dx,al        ; set plane mask (to set 1 bits of color)
  1116.     inc    dx
  1117.     mov    al,bh        ; get color
  1118.     out    dx,al
  1119.  
  1120.     mov    al,[di]        ; latch current data first
  1121.     mov    byte ptr [di],0ffh    ; blend in new color bits
  1122.  
  1123.     dec    dx
  1124.     mov    al,2
  1125.     out    dx,al        ; set plane mask (to zero 0 bits of color)
  1126.     inc    dx
  1127.     mov    al,bh        ; get color
  1128.     not    al        ; invert
  1129.     out    dx,al
  1130.  
  1131.     mov    al,[di]        ; latch current data first
  1132.     mov    byte ptr [di],0    ; logic-force new off bits
  1133.     inc    di
  1134.     sub    cx,8        ; decrement dot count by one bytes worth
  1135.     cmp    cx,8        ; another full byte left?
  1136.     jnb    egahlb        ; jif yess
  1137.     ret
  1138.     page
  1139. ;
  1140. ; verline(x1, y1, y2, color, rule);
  1141. ;
  1142. _verline:
  1143.     push    bp
  1144.     mov    bp,sp
  1145.     push    di
  1146.     mov    bx,[bp+4]        ; get x1
  1147.     mov    x1,bx
  1148.     mov    cx,[bp+6]        ; get y1
  1149.     mov    y1,cx
  1150.     mov    ax,[bp+8]        ; get y2
  1151.     mov    y2,ax
  1152.     mov    dx,[bp+10]        ; get color
  1153.     mov    color,dl
  1154.     mov    dx,[bp+12]        ; get rule
  1155.     mov    rule,dl
  1156.  
  1157.     sub    ax,cx            ; get difx
  1158.     jnb    vgotdify        ; jif y2 >= y1
  1159.     neg    ax            ; else get y1-y2
  1160.     mov    dx,y2
  1161.     mov    y1,dx
  1162.     mov    y2,cx
  1163. vgotdify:
  1164.     inc    ax            ; # of dots to write
  1165.     mov    dify,ax            ; save difx away
  1166.     mov    cx,bx
  1167.     mov    bx,y2
  1168.     mov    dl,color
  1169.     cmp    _machine,0
  1170.     jz    cgaverline
  1171.     jmp    egaverline
  1172. cgaverline:
  1173.     call    cgamapxy
  1174.     mov    cx,dify
  1175.     mov    dh,rule
  1176.     push    ds
  1177.     mov    ds,vidseg
  1178.     or    dh,dh
  1179.     jz    vpxyforce
  1180.     cmp    dh,3
  1181.     jz    vpxyxor
  1182.     cmp    dh,2
  1183.     jz    vpxyor
  1184. vpxyand:
  1185.     or    dl,al
  1186.     test    byte ptr es:y2,1    ; in upper 2000h bytes?
  1187.     jz    vaupper        ; jif yes
  1188. vpand:
  1189.     and    [di],dl        ; xor color into display
  1190.     add    di,2000h
  1191.     dec    cx
  1192.     jz    vpdone
  1193. vaupper:
  1194.     and    [di],dl
  1195.     sub    di,1fb0h
  1196.     loop    vpand
  1197.     jmp    short vpdone
  1198. vpxyxor:
  1199.     test    byte ptr es:y2,1    ; in upper 2000h bytes?
  1200.     jz    vupper        ; jif yes
  1201. vpxor:
  1202.     xor    [di],dl        ; xor color into display
  1203.     add    di,2000h
  1204.     dec    cx
  1205.     jz    vpdone
  1206. vupper:
  1207.     xor    [di],dl
  1208.     sub    di,1fb0h
  1209.     loop    vpxor
  1210. vpdone:
  1211.     pop    ds
  1212.     pop    di
  1213.     pop    bp
  1214.     ret
  1215. vpxyor:
  1216.     test    byte ptr es:y2,1    ; in upper 2000h bytes?
  1217.     jz    voupper            ; jif yes
  1218. vpor:
  1219.     or    [di],dl            ; force new bits into display
  1220.     add    di,2000h
  1221.     dec    cx
  1222.     jz    vpdone
  1223. voupper:
  1224.     or    [di],dl
  1225.     sub    di,1fb0h
  1226.     loop    vpor
  1227.     jmp    vpdone
  1228. vpxyforce:
  1229.     test    byte ptr es:y2,1    ; in upper 2000h bytes?
  1230.     jz    vfupper            ; jif yes
  1231. vpforce:
  1232.     and    [di],al            ; clear pixel in display
  1233.     or    [di],dl            ; force new bits into display
  1234.     add    di,2000h
  1235.     dec    cx
  1236.     jz    vpdone
  1237. vfupper:
  1238.     and    [di],al
  1239.     or    [di],dl
  1240.     sub    di,1fb0h
  1241.     loop    vpforce
  1242.     jmp    vpdone
  1243. ;
  1244. ;
  1245. egaverline:
  1246.     call    egamapxy
  1247.     mov    bl,dl        ; save bit mask
  1248.     mov    bh,ch        ; save color
  1249.     mov    cx,dify
  1250.     mov    ah,rule
  1251.     push    ds
  1252.     mov    ds,vidseg
  1253.  
  1254.     shl    ah,1
  1255.     shl    ah,1        ; set logical operation in ega controller
  1256.     shl    ah,1
  1257.     mov    dx,3ceh
  1258.     mov    al,3
  1259.     out    dx,al
  1260.     inc    dx
  1261.     mov    al,ah
  1262.     out    dx,al
  1263.  
  1264.     mov    dx,3ceh
  1265.     mov    al,8
  1266.     out    dx,al        ; set bit mask
  1267.     inc    dx
  1268.     mov    al,bl        ; recover bit mask
  1269.     out    dx,al
  1270. egavl:
  1271.     mov    dx,3c4h
  1272.     mov    al,2
  1273.     out    dx,al        ; set plane mask (to set 1 bits of color)
  1274.     inc    dx
  1275.     mov    al,bh        ; get color
  1276.     out    dx,al
  1277.  
  1278.     mov    al,[di]            ; latch current data first
  1279.     mov    byte ptr [di],0ffh    ; blend in new color bits
  1280.  
  1281.     dec    dx
  1282.     mov    al,2
  1283.     out    dx,al        ; set plane mask (to zero 0 bits of color)
  1284.     inc    dx
  1285.     mov    al,bh        ; get color
  1286.     not    al        ; invert
  1287.     out    dx,al
  1288.  
  1289.     mov    al,[di]        ; latch current data first
  1290.     mov    byte ptr [di],0    ; logic-force new off bits
  1291.     add    di,80        ; move to next line
  1292.     loop    egavl
  1293.     pop    ds
  1294.     pop    di
  1295.     pop    bp
  1296.     ret
  1297.     page
  1298. ;
  1299. ; clrscreen(color);
  1300. ;
  1301. _clrscreen:
  1302.     push    bp
  1303.     mov    bp,sp
  1304.     cld
  1305.     push    di
  1306.     mov    ax,[bp+4]        ; get color
  1307.     push    es
  1308.     mov    es,vidseg
  1309.     xor    di,di
  1310.     cmp    _machine,0
  1311.     jnz    egaclear
  1312. cgaclear:
  1313.     mov    bx,ax
  1314.     shl    bx,1
  1315.     shl    bx,1
  1316.     or    ax,bx
  1317.     shl    bx,1
  1318.     shl    bx,1
  1319.     or    ax,bx            ; build entire byte of color
  1320.     shl    bx,1
  1321.     shl    bx,1
  1322.     or    ax,bx
  1323.     mov    cx,8192
  1324.     rep    stosw
  1325.     pop    es
  1326.     pop    di
  1327.     pop    bp
  1328.     ret
  1329. egaclear:
  1330.     mov    bl,al            ; save color
  1331.  
  1332.     mov    dx,3ceh
  1333.     mov    al,3
  1334.     out    dx,al
  1335.     inc    dx
  1336.     mov    al,0        ; no rotate and no logical operation on data
  1337.     out    dx,al
  1338.  
  1339.     mov    dx,3ceh
  1340.     mov    al,8
  1341.     out    dx,al        ; set bit mask
  1342.     inc    dx
  1343.     mov    al,0ffh        ; all bits
  1344.     out    dx,al
  1345.  
  1346.     mov    dx,3c4h
  1347.     mov    al,2
  1348.     out    dx,al        ; set plane mask (to set 1 bits of color)
  1349.     inc    dx
  1350.     mov    al,bl        ; get color
  1351.     out    dx,al
  1352.  
  1353.     push    di
  1354.     mov    cx,28000    ; number of bytes on ega display
  1355.     mov    al,0ffh        ; blend in new color bits
  1356.     rep    stosb
  1357.     pop    di
  1358.  
  1359.     dec    dx
  1360.     mov    al,2
  1361.     out    dx,al        ; set plane mask (to zero 0 bits of color)
  1362.     inc    dx
  1363.     mov    al,bl        ; get color
  1364.     not    al        ; invert
  1365.     out    dx,al
  1366.  
  1367.     mov    al,0        ; logic-force new off bits
  1368.     mov    cx,28000
  1369.     rep    stosb
  1370.  
  1371.     pop    es
  1372.     pop    di
  1373.     pop    bp
  1374.     ret
  1375. ;
  1376.     page
  1377. ;
  1378. ;
  1379. ; setrand(seed);
  1380. ;
  1381. ; setrand - set random  # seed
  1382. ;
  1383. _setrand:
  1384.     push    bp
  1385.     mov    bp,sp
  1386.     mov    ax,[bp+4]
  1387.      or    ax,ax              ; if seed specified
  1388.      jnz    setit              ;   use it
  1389.      mov    ah,2ch              ; else
  1390.      int    21h              ;   use system time (secs &
  1391.      mov    ax,dx              ;   1/100's) to get rand seed
  1392. setit:
  1393.      mov    seed,ax              ; save seed
  1394.     pop    bp
  1395.      ret                   ; that's all folks
  1396. ;
  1397. ; rand();
  1398. ;
  1399. ; rand - fetch a new random number;  at entry, cx=limit
  1400. ;         at exit, ax=random number
  1401. ;
  1402. ;   formula:     rand(i+1)=261*rand(i) mod 65521
  1403. ;
  1404. _rand:
  1405.     push    bp
  1406.      mov    ax,seed         ; get last rand
  1407.      mov    bx,261         ; multiplier
  1408.      mul    bx         ;
  1409.      mov    bx,65521
  1410.      div    bx
  1411.      cmp    dx,0         ; new seed=0?
  1412.      jnz    seedok         ; jif no
  1413.      inc    word ptr seed    ; change seed
  1414.      jmp    _rand         ; try again
  1415. seedok:
  1416.      mov    seed,dx
  1417.      mov    ax,dx
  1418.      mov    dx,0
  1419.      div    cx
  1420.      mov    ax,dx
  1421.     pop    bp
  1422.      ret                   ; that's all
  1423. ;
  1424.     page
  1425. _beepoff:
  1426.     in    al,61h
  1427.     and    al,0fch
  1428.     out    61h,al
  1429.     ret
  1430. ;
  1431. ; BEEPON --- turns beeper on with timer 2 gate to value in AX at entry.
  1432. ;
  1433. _beepon:
  1434.     push    bp
  1435.     mov    bp,sp
  1436.     mov    al,0b6h
  1437.     out    43h,al
  1438.     mov    ax,[bp+4]
  1439.     out    42h,al
  1440.     mov    al,ah
  1441.     out    42h,al
  1442.     in    al,61h
  1443.     or    al,3
  1444.     out    61h,al
  1445.     pop    bp
  1446.     ret
  1447. ;
  1448.     page
  1449. ;
  1450. ;
  1451. ; flabel (x, y, string, fore_color, back_color, rule);
  1452. ;
  1453. _flabel:
  1454.     push    bp
  1455.     mov    bp,sp
  1456.     cld
  1457.     push    si
  1458.     push    di
  1459.     push    es
  1460.     mov    cx,[bp+4]
  1461.     mov    dx,[bp+6]
  1462.     mov    si,[bp+8]
  1463.     mov    ax,[bp+10]
  1464.     mov    color,al
  1465.     mov    ax,[bp+12]
  1466.     mov    backclr,al
  1467.     mov    ax,[bp+14]
  1468.     mov    rule,al
  1469.     mov    x1,cx
  1470.     mov    y1,dx
  1471.     mov    string,si
  1472. floop:
  1473.     mov    si,string        ; get ptr to string
  1474.     lodsb                ; get next char
  1475.     mov    string,si        ; save new ptr
  1476.     cmp    al,0            ; done?
  1477.     jz    fldone            ; jif yes
  1478.     call    fchar            ; label the char
  1479.     add    x1,6            ; move to next char space
  1480.     jmp    floop            ; do next
  1481. ;
  1482. fldone:
  1483.     pop    es
  1484.     pop    di
  1485.     pop    si
  1486.     pop    bp
  1487.     ret
  1488. ;
  1489. ;    cx = x1
  1490. ;    dx = y1
  1491. ;    si = char byte ptr
  1492. ;    al = char byte
  1493. ;
  1494. fchar:
  1495.     lea    si,chartab        ; address of char data
  1496.     cbw
  1497.     shl    ax,1
  1498.     shl    ax,1
  1499.     shl    ax,1
  1500.     add    si,ax            ; point to actual char data
  1501.     mov    cx,x1            ; get top left x address
  1502.     mov    dx,y1            ; get top left y address
  1503.     mov    byte ptr rowcnt,8    ; # of rows of char data
  1504. bytloop:
  1505.     lodsb                ; get next byte (row)
  1506.     mov    byte ptr colcnt,6    ; # of cols per row
  1507.     shl    ax,1            ; throw away leading blanks
  1508. if font1
  1509.     shl    ax,1
  1510.     shl    ax,1
  1511. endif
  1512.     push    si            ; save char data ptr
  1513. bitloop:
  1514.     mov    ah,backclr        ; default background color
  1515.     shl    al,1            ; get the next bit
  1516.     jnc    flbc            ; jif bit clear, use background color
  1517.     mov    ah,color        ; else load foreground color
  1518. flbc:
  1519.     push    ax            ; save rest of byte
  1520.     push    bx
  1521.     push    cx
  1522.     push    dx
  1523.     mov    bx,dx            ; move y-coord
  1524.     mov    dl,ah            ; move color
  1525.     mov    dh,rule            ; get rule
  1526.     call    pixel            ; plot it
  1527.     pop    dx
  1528.     pop    cx
  1529.     pop    bx
  1530.     pop    ax
  1531.     inc    cx            ; move to right one dot
  1532.     dec    byte ptr colcnt        ; done with byte?
  1533.     jnz    bitloop            ; jif no
  1534.     pop    si            ; recover char data ptr
  1535.     sub    cx,6            ; move back to left of space
  1536.     dec    dx            ; move down a row
  1537.     dec    byte ptr rowcnt        ; done with char?
  1538.     jnz    bytloop            ; jif no
  1539.     ret
  1540. ;
  1541. _iskey:
  1542.     mov    ah,1
  1543.     int    16h
  1544.     jnz    iskeyret
  1545.     mov    ax,0
  1546. iskeyret:
  1547.     ret
  1548. ;
  1549. _key:
  1550.     mov    ah,0
  1551.     int    16h
  1552.     ret
  1553.     page
  1554. ;
  1555. ; movebytes(*to, *from, count);   for fast moving of a block of bytes
  1556. ;
  1557. _movebytes:
  1558.     push    bp
  1559.     mov    bp,sp
  1560.     push    si
  1561.     push    di
  1562.     mov    di,[bp+4]        ; get destination
  1563.     mov    si,[bp+6]        ; get source
  1564.     mov    cx,[bp+8]        ; get count
  1565.     or    cx,cx            ; any to move?
  1566.     jz    mbdone            ; jif no
  1567.     cmp    di,si            ; to < from?
  1568.     ja    movrev            ; jif no, negative move
  1569.     cld
  1570. movcom:
  1571.     rep    movsb
  1572. mbdone:
  1573.     cld
  1574.     pop    di
  1575.     pop    si
  1576.     pop    bp
  1577.     ret
  1578. ;
  1579. movrev:
  1580.     add    si,cx            ; move to other end
  1581.     add    di,cx
  1582.     dec    si
  1583.     dec    di
  1584.     std
  1585.     jmp    movcom
  1586. ;
  1587. ;
  1588. ;
  1589. _text    ends
  1590. ;
  1591.     end
  1592.