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