home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 December / simtel1292_SIMTEL_1292_Walnut_Creek.iso / msdos / filutl / be.arc / DISPIO.ASM < prev    next >
Assembly Source File  |  1988-01-01  |  38KB  |  1,836 lines

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