home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / screen / advid105.arc / AD_VIDEO.ASM < prev    next >
Assembly Source File  |  1989-04-12  |  33KB  |  1,347 lines

  1.             PAGE 60,132
  2.  
  3.             TITLE ad_video.sys  version 1.05  April 12, 1989
  4.  
  5. ;
  6. ; Copyright (c) Andan Software 1989
  7. ;
  8. ; This SYS-program replace some of the BIOS Video routines so video access
  9. ; from other program goes faster.
  10. ;
  11. ; It is loaded as an installable device driver with the
  12. ; command 'device=ad_video.sys' in the config.sys file.
  13. ;
  14. ;
  15. ; Shareware: This source code may be copied if no fee is charged and if no
  16. ; changes are done, for educate purposes only.
  17. ;
  18. ;
  19. ; Please help us distribute AD_VIDEO by copying it in it's unmodified
  20. ; form. Please make a contribution to us for using this program. We
  21. ; recommend a contribution of $10 for students, $20 for private use and
  22. ; $40 for companies. Send an international check or money order to:
  23. ;
  24. ;               Seffle Instrument AB
  25. ;               P.O. Box 25
  26. ;               S-661 00  SÄFFLE
  27. ;               SWEDEN
  28. ;
  29. ;               Telephone +46 533 17250
  30. ;
  31. ; Mark the payment with "AnDan Software Video BIOS Version 1.05".
  32. ; You may use Visa or MasterCard if you write a letter with your
  33. ; payment, card number, expiration date, and your signature.
  34. ;
  35. ; For Swedish users:      Telefon:        0533-17250
  36. ;                         Postgiro:       509517-9  
  37. ;                         Bankgiro:       720-6733  
  38. ;
  39. ;
  40. ;
  41. ;
  42. ;
  43. ;
  44. ; Revision history:
  45. ;
  46. ; Vers:     Date:       Comments:
  47. ;
  48. ; 1.00      890402      First release
  49. ; 1.01      890403      Set cursor position corrected when setting in non-
  50. ;                       active page. Write TTY corrected, didn't handle 
  51. ;                       attributes right. Some smaller optimations have been
  52. ;                       done.
  53. ; 1.02      890405      Set cursor position corrected, again.
  54. ;                       The video position wasn't calculated correctly for
  55. ;                       other pages than page 0.
  56. ;                       The vidoe memory position is calculated only in
  57. ;                       the setcur function. Due to some badly written programs
  58. ;                       like ProComm Plus, two cursor savings are needed.
  59. ; 1.03      890408      Fixed calculation to work with more than 25 lines on
  60. ;                       other videopages than page zero. To use this a label
  61. ;                       must be defined, se below. 
  62. ; 1.04      890410      The BIOS funtions scroll up and down have been
  63. ;                       implemented.
  64. ; 1.05      890412      Scroll up/down did only handle one row at time.
  65. ;                       Write teletype optimized better.
  66. ;
  67. ;
  68. ;
  69. ;
  70. ; Syntax:
  71. ;
  72. ; device=[path]ad_video.sys [/w] [/bNNNN] [/d]
  73. ;
  74. ; /w        Waits before each video memory access, used to prevent "snow"
  75. ;           This option is valid only for when 'ega' is undefined, see below
  76. ; /bNNNN    Loop value NNNN to be used with the Bell, default 800
  77. ; /d        Use DOS to set new value to interrupt table
  78. ;
  79. ;
  80. ; Use MASM with the following options to produce different styles 
  81. ; of ad_video.sys:
  82. ;
  83. ; /dwaitio      Waits are inserted after all I/O accesses
  84. ; /dwideio      16 bits I/O is used whenever possible
  85. ; /dega         More then 25 lines are supported, /w option not available
  86. ;               May be used only on EGA or VGA cards
  87. ;
  88. ;
  89. ; AD_VIDEO.SYS replaces the following Video BIOS functions:
  90. ;
  91. ;  2 Set cursor position                
  92. ;  3 Read cursor position               
  93. ;  6 Scroll active page up              
  94. ;  7 Scroll active page down            
  95. ;  8 Read attribute/character at cursor 
  96. ;  9 Write attribute/character at cursor
  97. ; 10 Write character at cursor          
  98. ; 14 Write teletype to active page
  99. ;
  100. ; AD_VIDEO.SYS should be loaded before any programs that filters and uses
  101. ; these functions.
  102. ;
  103. ;
  104. ; AD_VIDEO.SYS filters the following Video BIOS functions:
  105. ;
  106. ;  0 Set video mode
  107. ;
  108. ;
  109. ;
  110. ;
  111. ; Equates and macros for different styles of the program
  112. ;
  113.  
  114. io_wait     MACRO
  115.             ifdef waitio
  116.             jmp $+2
  117.             endif
  118.             ENDM
  119.  
  120. bios        SEGMENT AT 0
  121.  
  122.             ASSUME ds:bios
  123.  
  124.             ORG 410H
  125.  
  126. equip_flag  DW ?
  127.  
  128.             ORG 449H
  129.  
  130. crt_mode    DB ?
  131. crt_cols    DW ?
  132. crt_len     DW ?
  133. crt_start   DW ?
  134. cursor_posn DW 8 DUP(?)
  135. cursor_mode DW ?
  136. active_page DB ?
  137. addr_6845   DW ?
  138. crt_mode_set DB ?
  139. crt_palette DB ?
  140.  
  141. bios        ENDS
  142.  
  143.  
  144. sys         SEGMENT PARA PUBLIC 'CODE'
  145.  
  146.             ASSUME cs:sys,ds:sys,ss:nothing,es:nothing
  147.  
  148. ;
  149. ;
  150. ; Device handling
  151. ;
  152. ;
  153.  
  154. next_off    DW -1
  155. next_seg    DW -1
  156.  
  157.             DW 1000000000000000B
  158.  
  159.             DW stategy            ;Strategy entry point
  160. intp        DW interrupt          ;Interrupt entry point
  161.             DB '$ADVIDEO'         ;8 byte character device name or
  162.                                   ;number of units
  163. ptr_cmd     DD ?
  164.  
  165. stategy     PROC FAR
  166.  
  167.             mov WORD PTR cs:[ptr_cmd],bx
  168.             mov WORD PTR cs:[ptr_cmd+2],es
  169.             ret
  170.  
  171. stategy     ENDP
  172.  
  173. ;
  174. ;
  175. ; New Interrupt entry point (after initialization):
  176. ;
  177.  
  178. newint      PROC FAR
  179.  
  180.             push ds
  181.             push bx
  182.             lds bx,cs:[ptr_cmd]
  183.             mov WORD PTR ds:[bx+03],8002H
  184.             pop bx
  185.             pop ds
  186.             ret
  187.  
  188. newint      ENDP
  189.  
  190. ;
  191. ;
  192. ; Resident code and data
  193. ;
  194. ;
  195.  
  196. wait_mode   DB 0
  197. dos_mode    DB 0
  198. bell_loop   DW 800
  199. video_mem   DW 0B800H
  200. functablep  DW OFFSET functable1
  201. mem_pos     DW 8 DUP(?)
  202. cur_pos     DW 8 DUP(?)                 ;This is needed due to bad programs
  203.  
  204.  
  205.             ASSUME cs:sys,ds:bios,ss:nothing,es:nothing
  206.  
  207. ;
  208. ; New INT 10H routine
  209. ;
  210.  
  211. int10h      PROC FAR
  212.  
  213.             sti     
  214.             push ds 
  215.             push bx 
  216.             xor bx,bx 
  217.             mov ds,bx 
  218.             cmp ah,19
  219.             ja jump_bios 
  220.             mov bl,ah 
  221.             shl bl,1 
  222.             add bx,cs:[functablep] 
  223.             jmp cs:[bx]
  224.             
  225. int10h      ENDP
  226.   
  227. jump_bios:  pop bx
  228.             pop ds
  229.             DB 0EAH                     ;Jump far direct
  230. old10h_o    DW 0
  231. old10h_s    DW 0
  232.  
  233.  
  234. functable1  DW OFFSET func00            ;00 Set videmode
  235.             DW OFFSET jump_bios         ;01 Set cursor type                    
  236.             DW OFFSET jump_bios         ;02 Set cursor position                
  237.             DW OFFSET jump_bios         ;03 Read cursor position               
  238.             DW OFFSET jump_bios         ;04 Read light pen position            
  239.             DW OFFSET jump_bios         ;05 Select active display page         
  240.             DW OFFSET jump_bios         ;06 Scroll active page up              
  241.             DW OFFSET jump_bios         ;07 Scroll active page down            
  242.             DW OFFSET jump_bios         ;08 Read attribute/character at cursor 
  243.             DW OFFSET jump_bios         ;09 Write attribute/character at cursor
  244.             DW OFFSET jump_bios         ;10 Write character at cursor          
  245.             DW OFFSET jump_bios         ;11 Set color palette                 
  246.             DW OFFSET jump_bios         ;12 Write dot                          
  247.             DW OFFSET jump_bios         ;13 Read dot
  248.             DW OFFSET jump_bios         ;14 Write teletype to active page
  249.             DW OFFSET jump_bios         ;15 Current video state
  250.             DW OFFSET jump_bios         ;16 Set palette registers
  251.             DW OFFSET jump_bios         ;17 Character generator
  252.             DW OFFSET jump_bios         ;18 Reserved
  253.             DW OFFSET jump_bios         ;19 Write string
  254.           
  255. functable2  DW OFFSET func00            ;00 Set videmode
  256.             DW OFFSET jump_bios         ;01 Set cursor type                    
  257.             DW OFFSET func02            ;02 Set cursor position                
  258.             DW OFFSET func03            ;03 Read cursor position               
  259.             DW OFFSET jump_bios         ;04 Read light pen position            
  260.             DW OFFSET jump_bios         ;05 Select active display page         
  261.             DW OFFSET func06            ;06 Scroll active page up              
  262.             DW OFFSET func07            ;07 Scroll active page down            
  263.             DW OFFSET func08            ;08 Read attribute/character at cursor 
  264.             DW OFFSET func09            ;09 Write attribute/character at cursor
  265.             DW OFFSET func10            ;10 Write character at cursor          
  266.             DW OFFSET jump_bios         ;11 Set color palette                 
  267.             DW OFFSET jump_bios         ;12 Write dot                          
  268.             DW OFFSET jump_bios         ;13 Read dot
  269.             DW OFFSET func14            ;14 Write teletype to active page
  270.             DW OFFSET jump_bios         ;15 Current video state
  271.             DW OFFSET jump_bios         ;16 Set palette registers
  272.             DW OFFSET jump_bios         ;17 Character generator
  273.             DW OFFSET jump_bios         ;18 Reserved
  274.             DW OFFSET jump_bios         ;19 Write string
  275.  
  276. ;
  277. ; beep
  278. ;
  279. ; ax,cx,dx destroyed
  280. ;
  281.  
  282. beep        PROC NEAR
  283.  
  284.             mov al,10110110B
  285.             out 43H,al
  286.             jmp $+2
  287.             mov al,33H
  288.             out 42H,al
  289.             jmp $+2
  290.             mov al,05H
  291.             out 42H,al
  292.             jmp $+2
  293.             in al,61H
  294.             jmp $+2
  295.             mov ah,al
  296.             or al,3
  297.             out 61H,al
  298.             mov cx,cs:[bell_loop]
  299. beep1:      xor al,al
  300. beep2:      dec al
  301.             jnz beep2
  302.             loop beep1
  303.             mov al,ah
  304.             out 61H,al
  305.             ret
  306.  
  307. beep        ENDP
  308.  
  309.  
  310.  
  311. ;
  312. ; setcur
  313. ;
  314. ; in:       bh = display page
  315. ;           dx = cursor position
  316. ;           ds = 0
  317. ;
  318. ; ax,bx,cx,dx destroyed
  319. ;
  320. ;
  321. ; Calculates current position for Alpha 80x25 modes:
  322. ;
  323. ; pos = page*[crt_len]+(row*80+col)*2
  324. ;
  325.  
  326. setcur      PROC NEAR
  327.  
  328.             ifdef ega
  329.  
  330.             xor al,al
  331.             mov ah,dh           ;AX = row * 256
  332.             shr ax,1            ;AX = row * 128
  333.             shr ax,1            ;AX = row * 64
  334.             mov cx,ax
  335.             shr ax,1            ;AX = row * 32
  336.             shr ax,1            ;AX = row * 16
  337.             add ax,cx           ;AX = row * 16 + row * 64 = row * 80
  338.             mov cl,dl
  339.             xor ch,ch
  340.             add ax,cx           ;AX = row * 80 + col
  341.             shl ax,1            ;AX = (row * 80 + col) * 2
  342.             mov cx,ax
  343.             mov bl,bh
  344.             xor bh,bh
  345.             mov ax,bx
  346.             shl bl,1            ;BX = page * 2
  347.             mov [bx+OFFSET cursor_posn],dx
  348.             mov cs:[bx+OFFSET cur_pos],dx       ;This is needed due to bad programs
  349.             mul [crt_len]       ;DX:AX = page * [crt_len] (DX assumed to be zero)
  350.             add ax,cx
  351.             mov cs:[bx+OFFSET mem_pos],ax
  352.             shr bl,1
  353.             cmp bl,[active_page]
  354.             jnz setcur1
  355.  
  356.             else
  357.  
  358. ;
  359. ; Old method, didn't handle more then 25 rows for other pages than zero
  360. ;
  361. ; pos = page*4096+(row*80+col)*2 = 
  362. ;     = (page*2048+row*80+col)*2 = 
  363. ;     = ((page*256+row*10)*8+col)*2
  364. ;
  365.             mov cx,2
  366.             mov al,dh           ;AL = row
  367.             shl al,cl           ;AL = row * 4
  368.             add al,dh           ;AL = row * 4 + row = row * 5
  369.             xor ah,ah
  370.             shl ax,1            ;AX = row * 10
  371.             add ah,bh           ;AX = page * 256 + row * 10
  372.             inc cl
  373.             shl ax,cl           ;AX = (page * 256 + row * 10) * 8
  374.             mov cl,dl
  375.             add ax,cx           ;AX = (page * 256 + row * 10) * 8 + col
  376.             shl ax,1            ;AX = (page * 2048 + row * 80 + col) * 2
  377.             mov cl,bh           ;CX = page
  378.             mov bx,cx
  379.             shl bl,1            ;BX = page * 2
  380.             mov [bx+OFFSET cursor_posn],dx
  381.             mov cs:[bx+OFFSET cur_pos],dx       ;This is needed due to bad programs
  382.             mov cs:[bx+OFFSET mem_pos],ax
  383.             cmp cl,[active_page]
  384.             jnz setcur1
  385.  
  386.             endif
  387.  
  388.             mov bx,ax
  389.             mov dx,[addr_6845]
  390.             shr bx,1
  391.  
  392.             ifdef wideio
  393.  
  394.             mov al,0EH
  395.             mov ah,bh
  396.             out dx,ax
  397.             io_wait
  398.             inc al
  399.             mov ah,bl
  400.             out dx,ax
  401.  
  402.             else
  403.  
  404.             mov al,0EH
  405.             out dx,al
  406.             io_wait
  407.             inc dx
  408.             mov al,bh
  409.             out dx,al
  410.             io_wait
  411.             dec dx
  412.             mov al,0FH
  413.             out dx,al
  414.             io_wait
  415.             inc dx
  416.             mov al,bl
  417.             out dx,al
  418.  
  419.             endif
  420.  
  421. setcur1:    ret
  422.  
  423. setcur      ENDP
  424.  
  425.  
  426. ;
  427. ;
  428. ; Calculation macro, used when cursor position is changed by programs without
  429. ; calling BIOS.
  430. ;
  431. ;
  432.  
  433. calcpos     MACRO
  434.  
  435.             ifdef ega
  436.  
  437.             xor al,al
  438.             mov ah,dh           ;AX = row * 256
  439.             shr ax,1            ;AX = row * 128
  440.             shr ax,1            ;AX = row * 64
  441.             mov cx,ax
  442.             shr ax,1            ;AX = row * 32
  443.             shr ax,1            ;AX = row * 16
  444.             add ax,cx           ;AX = row * 16 + row * 64 = row * 80
  445.             mov cl,dl
  446.             xor ch,ch
  447.             add ax,cx           ;AX = row * 80 + col
  448.             shl ax,1            ;AX = (row * 80 + col) * 2
  449.             mov cx,ax
  450.             mov cs:[bx+OFFSET cur_pos],dx       ;This is needed due to bad programs
  451.             mov ax,bx
  452.             shr ax,1
  453.             mul [crt_len]       ;DX:AX = page * [crt_len] (DX assumed to be zero)
  454.             add ax,cx
  455.             mov cs:[bx+OFFSET mem_pos],ax
  456.             mov bx,ax
  457.  
  458.             else
  459.  
  460. ;
  461. ; Old method, didn't handle more then 25 rows for other pages than zero
  462. ;
  463.  
  464.             mov cx,2
  465.             mov al,dh           ;AL = row
  466.             shl al,cl           ;AL = row * 4
  467.             add al,dh           ;AL = row * 4 + row = row * 5
  468.             xor ah,ah
  469.             shl ax,cl           ;AX = row * 20
  470.             add ah,bl           ;AX = page * 512 + row * 20
  471.             shl ax,cl           ;AX = (page * 512 + row * 20) * 4
  472.             mov cl,dl
  473.             add ax,cx           ;AX = (page * 512 + row * 20) * 4 + col
  474.             shl ax,1            ;AX = (page * 2048 + row * 80 + col) * 2
  475.             mov cs:[bx+OFFSET cur_pos],dx
  476.             mov cs:[bx+OFFSET mem_pos],ax
  477.             mov bx,ax
  478.  
  479.             endif
  480.  
  481.             ENDM
  482.  
  483.  
  484.  
  485. init_pos    PROC NEAR
  486.  
  487.             mov bx,OFFSET functable1
  488.             mov al,[crt_mode]
  489.             cmp al,07H
  490.             jz init_pos1
  491.             cmp al,02H
  492.             jb init_pos3
  493.             cmp al,03H
  494.             ja init_pos3
  495.  
  496. init_pos1:  xor cx,cx
  497. init_pos2:  push cx
  498.             mov bx,cx
  499.             shl bl,1
  500.             mov dx,[bx+OFFSET cursor_posn]
  501.             mov bh,cl
  502.             call setcur
  503.             pop cx
  504.             inc cl
  505.             cmp cl,8
  506.             jc init_pos2
  507.             mov bx,OFFSET functable2
  508.  
  509. init_pos3:  mov cs:[functablep],bx
  510.             ret
  511.  
  512. init_pos    ENDP
  513.  
  514.  
  515.  
  516. ;00 Set videmode
  517.  
  518. func00:     pop bx
  519.             pushf
  520.             call DWORD PTR cs:[old10h_o]
  521.             push ax
  522.             push bx
  523.             push cx
  524.             push dx
  525.             call init_pos
  526.             pop dx
  527.             pop cx
  528.             pop bx
  529.             pop ax
  530.             pop ds
  531.             iret
  532.  
  533.  
  534. ;02 Set cursor position                
  535.  
  536. func02:     pop bx
  537.             push ax
  538.             push bx
  539.             push cx
  540.             push dx
  541.             call setcur
  542.             pop dx
  543.             pop cx
  544.             pop bx
  545.             pop ax
  546.             pop ds
  547.             iret
  548.   
  549.  
  550. ;03 Read cursor position                 
  551.  
  552. func03:     pop bx
  553.             mov cx,bx
  554.             mov bl,bh
  555.             xor bh,bh
  556.             shl bl,1
  557.             mov dx,[bx+OFFSET cursor_posn]
  558.             mov bx,cx
  559.             mov cx,[cursor_mode]
  560.             pop ds
  561.             iret
  562.  
  563.  
  564. ;08 Read attribute/character at cursor 
  565.  
  566. func08:     pop bx
  567.             push bx
  568.             push dx
  569.             push es
  570.  
  571. ;
  572. ; Read char
  573. ;
  574. ; in:       bh = page
  575. ;
  576. ; out:      al = char
  577. ;           ah = attribute
  578. ;
  579. ; bx,dx,es destroyed
  580. ;
  581.  
  582.             mov dx,cs:[video_mem]
  583.             mov es,dx
  584.             mov bl,bh
  585.             xor bh,bh
  586.             shl bl,1
  587.             mov dx,[bx+OFFSET cursor_posn]      ;This is needed due to bad programs
  588.             cmp dx,cs:[bx+OFFSET cur_pos]       ;This is needed due to bad programs
  589.             jnz rcharcalc                       ;This is needed due to bad programs
  590.             mov bx,cs:[bx+OFFSET mem_pos]
  591.  
  592. rchar0:
  593.             ifndef ega
  594.  
  595.             cmp cs:[wait_mode],0
  596.             jnz rchar2 
  597.  
  598.             endif
  599.  
  600.             mov ax,es:[bx]
  601. rchar1:     pop es
  602.             pop dx
  603.             pop bx
  604.             pop ds
  605.             iret
  606.  
  607.             ifndef ega
  608.  
  609. rchar2:     mov ah,1
  610.             mov dx,3DAH
  611. rchar3:     in al,dx
  612.             test al,ah
  613.             jnz rchar3
  614.             cli
  615. rchar4:     in al,dx
  616.             test al,ah
  617.             jz rchar4
  618.             mov ax,es:[bx]
  619.             sti
  620.             jmp rchar1
  621.  
  622.             endif
  623.  
  624. rcharcalc:  push cx
  625.             calcpos
  626.             pop cx
  627.             jmp rchar0
  628.  
  629.  
  630.   
  631. ;09 Write attribute/character at cursor
  632.  
  633. func09:     pop bx
  634.             push ax
  635.             push bx
  636.             push cx
  637.             push dx
  638.             push es
  639.             mov ah,bl
  640.  
  641. ;
  642. ; Write char and attribut
  643. ;
  644. ; in:       bh = page
  645. ;           al = char
  646. ;           ah = attribute
  647. ;           cx = count
  648. ;
  649. ; bx,cx,dx,es destroyed
  650. ;
  651.  
  652.             mov dx,cs:[video_mem]
  653.             mov es,dx
  654.             mov bl,bh
  655.             xor bh,bh
  656.             shl bl,1
  657.             mov dx,[bx+OFFSET cursor_posn]      ;This is needed due to bad programs
  658.             cmp dx,cs:[bx+OFFSET cur_pos]       ;This is needed due to bad programs
  659.             jnz wachrcalc                       ;This is needed due to bad programs
  660.             mov bx,cs:[bx+OFFSET mem_pos]
  661.  
  662. wachr0:     
  663.             ifndef ega
  664.  
  665.             cmp cs:[wait_mode],0
  666.             jnz wachr3 
  667.  
  668.             endif
  669.  
  670. wachr1:     mov es:[bx],ax
  671.             add bx,2
  672.             loop wachr1
  673.  
  674. wachr2:     pop es
  675.             pop dx
  676.             pop cx
  677.             pop bx
  678.             pop ax
  679.             pop ds
  680.             iret
  681.  
  682.             ifndef ega
  683.  
  684. wachr3:     push ax
  685.             mov ah,1
  686.             mov dx,3DAH
  687. wachr4:     in al,dx
  688.             test al,ah
  689.             jnz wachr4
  690.             cli
  691. wachr5:     in al,dx
  692.             test al,ah
  693.             jz wachr5
  694.             pop ax
  695.             mov es:[bx],ax
  696.             sti
  697.             add bx,2
  698.             loop wachr3
  699.             jmp wachr2
  700.  
  701.             endif
  702.  
  703. wachrcalc:  push ax
  704.             push cx
  705.             calcpos
  706.             pop cx
  707.             pop ax
  708.             jmp wachr0
  709.  
  710.  
  711. ;10 Write character at cursor          
  712.   
  713. func10:     pop bx
  714.             push ax
  715.             push bx
  716.             push cx
  717.             push dx
  718.             push es
  719.  
  720. ;
  721. ; Write char
  722. ;
  723. ; in:       bh = page
  724. ;           al = char
  725. ;           cx = count
  726. ;
  727. ; bx,cx,dx,es destroyed
  728. ;
  729.             mov dx,cs:[video_mem]
  730.             mov es,dx
  731.             mov bl,bh
  732.             xor bh,bh
  733.             shl bl,1
  734.             mov dx,[bx+OFFSET cursor_posn]      ;This is needed due to bad programs
  735.             cmp dx,cs:[bx+OFFSET cur_pos]       ;This is needed due to bad programs
  736.             jnz wcharcalc                       ;This is needed due to bad programs
  737.             mov bx,cs:[bx+OFFSET mem_pos]
  738.  
  739. wchar0:
  740.             ifndef ega
  741.  
  742.             cmp cs:[wait_mode],0
  743.             jnz wchar3 
  744.  
  745.             endif
  746.  
  747. wchar1:     mov es:[bx],al
  748.             add bx,2
  749.             loop wchar1
  750.  
  751. wchar2:     pop es
  752.             pop dx
  753.             pop cx
  754.             pop bx
  755.             pop ax
  756.             pop ds
  757.             iret
  758.  
  759.             ifndef ega
  760.  
  761. wchar3:     push ax
  762.             mov ah,1
  763.             mov dx,3DAH
  764. wchar4:     in al,dx
  765.             test al,ah
  766.             jnz wchar4
  767.             cli
  768. wchar5:     in al,dx
  769.             test al,ah
  770.             jz wchar5
  771.             pop ax
  772.             mov es:[bx],al
  773.             sti
  774.             add bx,2
  775.             loop wchar3
  776.             jmp wchar2
  777.  
  778.             endif
  779.  
  780. wcharcalc:  push ax
  781.             push cx
  782.             calcpos
  783.             pop cx
  784.             pop ax
  785.             jmp wchar0
  786.  
  787.  
  788. ;
  789. ; scroll
  790. ;
  791. ; in:       ax = Value to add to si and di for next row
  792. ;           bh = Attribute on blanked line
  793. ;           bl = Number of rows to scroll
  794. ;           dh = Number of rows
  795. ;           dl = Number of columns
  796. ;           di = Destination address in video memory
  797. ;           si = Source address in video memory
  798. ;
  799. ; ax,bx,cx,dx,di,si,es,ds destroyed
  800. ;
  801.  
  802. scroll      PROC NEAR
  803.  
  804.             ifndef ega
  805.  
  806.             cmp cs:[wait_mode],0
  807.             jz scroll0b
  808.  
  809.             push dx
  810.             mov cx,ax
  811.             mov dx,3DAH
  812. scroll0a:   in al,dx
  813.             test al,8
  814.             jz scroll0a
  815.             mov al,25H
  816.             mov dx,3D8H
  817.             out dx,al
  818.             mov ax,cx
  819.             pop dx
  820. scroll0b:
  821.             endif
  822.  
  823.             mov cx,cs:[video_mem]
  824.             mov es,cx
  825.             mov ds,cx
  826.             xor ch,ch
  827.             cld
  828.             and bl,bl
  829.             jz scroll4
  830.             sub dh,bl
  831.             jz scroll2
  832.  
  833. scroll1:    mov cl,dl
  834.             rep movsw
  835.             add di,ax
  836.             add si,ax
  837.             dec dh
  838.             jnz scroll1
  839.  
  840. scroll2:    xchg ax,bx
  841.             mov dh,al
  842.             mov al,32
  843.  
  844. scroll3:    mov cl,dl
  845.             rep stosw
  846.             add di,bx
  847.             dec dh
  848.             jnz scroll3
  849.  
  850.             ifndef ega
  851.  
  852.             cmp cs:[wait_mode],0
  853.             jz scroll3a
  854.  
  855.             xor ax,ax
  856.             mov ds,ax
  857.             mov al,[crt_mode_set]
  858.             mov dx,3D8H
  859.             out dx,al
  860. scroll3a:
  861.             endif
  862.  
  863.             ret
  864.  
  865. scroll4:    mov bl,dh
  866.             jmp scroll2
  867.  
  868. scroll      ENDP
  869.  
  870.  
  871. ;06 Scroll active page up              
  872.  
  873. func06:     pop bx
  874.             push ax
  875.             push bx
  876.             push cx
  877.             push dx
  878.             push si
  879.             push di
  880.             push es
  881.             mov bl,al
  882.             mov ah,al
  883.             xor al,al           ;AX = rows * 256
  884.             shr ax,1            ;AX = rows * 128
  885.             mov si,ax
  886.             shr ax,1            ;AX = rows * 64
  887.             shr ax,1            ;AX = rows * 32
  888.             add si,ax           ;SI = rows * 160
  889.             xor al,al
  890.             mov ah,ch           ;AX = row * 256
  891.             shr ax,1            ;AX = row * 128
  892.             shr ax,1            ;AX = row * 64
  893.             mov di,ax
  894.             shr ax,1            ;AX = row * 32
  895.             shr ax,1            ;AX = row * 16
  896.             add ax,di           ;AX = row * 16 + row * 64 = row * 80
  897.             add al,cl
  898.             adc ah,0            ;AX = row * 80 + col
  899.             shl ax,1            ;AX = (row * 80 + col) * 2
  900.             add ax,[crt_start]
  901.             mov di,ax
  902.             add si,ax
  903.             sub dx,cx
  904.             inc dh
  905.             inc dl
  906.             mov al,80
  907.             sub al,dl
  908.             cbw                 ;Due to bugs in other programs
  909.             shl ax,1
  910.             call scroll
  911.             pop es
  912.             pop di
  913.             pop si
  914.             pop dx
  915.             pop cx
  916.             pop bx
  917.             pop ax
  918.             pop ds
  919.             iret
  920.  
  921.  
  922. ;07 Scroll active page down            
  923.  
  924. func07:     pop bx
  925.             push ax
  926.             push bx
  927.             push cx
  928.             push dx
  929.             push si
  930.             push di
  931.             push es
  932.             mov bl,al
  933.             mov ah,al
  934.             xor al,al           ;AX = rows * 256
  935.             shr ax,1            ;AX = rows * 128
  936.             mov si,ax
  937.             shr ax,1            ;AX = rows * 64
  938.             shr ax,1            ;AX = rows * 32
  939.             add si,ax           ;SI = rows * 160
  940.             xor al,al
  941.             mov ah,dh           ;AX = row * 256
  942.             shr ax,1            ;AX = row * 128
  943.             shr ax,1            ;AX = row * 64
  944.             mov di,ax
  945.             shr ax,1            ;AX = row * 32
  946.             shr ax,1            ;AX = row * 16
  947.             add ax,di           ;AX = row * 16 + row * 64 = row * 80
  948.             add al,cl
  949.             adc ah,0            ;AX = row * 80 + col
  950.             shl ax,1            ;AX = (row * 80 + col) * 2
  951.             add ax,[crt_start]
  952.             mov di,ax
  953.             sub ax,si
  954.             mov si,ax
  955.             sub dx,cx
  956.             inc dh
  957.             inc dl
  958.             mov ax,80
  959.             add al,dl
  960.             shl ax,1
  961.             neg ax
  962.             call scroll
  963.             pop es
  964.             pop di
  965.             pop si
  966.             pop dx
  967.             pop cx
  968.             pop bx
  969.             pop ax
  970.             pop ds
  971.             iret
  972.  
  973.  
  974. ;14 Write teletype to active page  
  975.  
  976. wttycalc:   push ax
  977.             push cx
  978.             ifdef ega
  979.             push dx
  980.             endif
  981.             calcpos
  982.             ifdef ega
  983.             pop dx
  984.             endif
  985.             pop cx
  986.             pop ax
  987.             jmp SHORT w_tty1
  988.  
  989.             ifndef ega
  990.  
  991. w_tty2:     push ax
  992.             push dx
  993.             mov ah,1
  994.             mov dx,3DAH
  995. w_tty3:     in al,dx
  996.             test al,ah
  997.             jnz w_tty3
  998.             cli
  999. w_tty4:     in al,dx
  1000.             test al,ah
  1001.             jz w_tty4
  1002.             pop dx
  1003.             pop ax
  1004.             mov es:[bx],al
  1005.             sti
  1006.             jmp SHORT w_tty5
  1007.  
  1008.             endif
  1009.  
  1010. func14_bell: push cx
  1011.             call beep
  1012.             pop cx
  1013.             jmp func14ret
  1014.  
  1015. func14_bs:  and dl,dl
  1016.             jz func14ret
  1017.             dec dl
  1018.             sub bx,2
  1019.             jmp SHORT func14c1
  1020.  
  1021. func14:     pop bx
  1022.             push ax
  1023.             push bx
  1024.             push dx
  1025.             push si
  1026.             push es
  1027.             mov dx,cs:[video_mem]
  1028.             mov es,dx
  1029.             mov bl,[active_page]
  1030.             xor bh,bh
  1031.             shl bl,1
  1032.             mov si,bx
  1033.             mov dx,[si+OFFSET cursor_posn]
  1034.             cmp dx,cs:[si+OFFSET cur_pos]       ;This is needed due to bad programs
  1035.             jnz wttycalc                        ;This is needed due to bad programs
  1036.             mov bx,cs:[si+OFFSET mem_pos]
  1037.  
  1038. w_tty1:     cmp al,8
  1039.             jz func14_bs
  1040.             cmp al,13
  1041.             jz func14_cr
  1042.             cmp al,10
  1043.             jz func14_lf
  1044.             cmp al,7
  1045.             jz func14_bell
  1046.  
  1047.             ifndef ega
  1048.  
  1049.             cmp cs:[wait_mode],0
  1050.             jnz w_tty2 
  1051.  
  1052.             endif
  1053.  
  1054.             mov es:[bx],al
  1055.  
  1056. w_tty5:     inc dl
  1057.             cmp dl,80
  1058.             jae func14nl
  1059.             add bx,2
  1060.  
  1061. func14c1:   mov [si+OFFSET cursor_posn],dx
  1062.             mov cs:[si+OFFSET cur_pos],dx       ;This is needed due to bad programs
  1063. func14c2:   mov cs:[si+OFFSET mem_pos],bx
  1064.             mov dx,[addr_6845]
  1065.             shr bx,1
  1066.  
  1067.             ifdef wideio
  1068.  
  1069.             mov al,0EH
  1070.             mov ah,bh
  1071.             out dx,ax
  1072.             io_wait
  1073.             inc al
  1074.             mov ah,bl
  1075.             out dx,ax
  1076.  
  1077.             else
  1078.  
  1079.             mov al,0EH
  1080.             out dx,al
  1081.             io_wait
  1082.             inc dx
  1083.             mov al,bh
  1084.             out dx,al
  1085.             io_wait
  1086.             dec dx
  1087.             mov al,0FH
  1088.             out dx,al
  1089.             io_wait
  1090.             inc dx
  1091.             mov al,bl
  1092.             out dx,al
  1093.  
  1094.             endif
  1095.  
  1096. func14ret:  pop es
  1097.             pop si
  1098.             pop dx
  1099.             pop bx
  1100.             pop ax
  1101.             pop ds
  1102.             iret
  1103.  
  1104. func14_cr:  mov al,dl
  1105.             xor ah,ah
  1106.             shl ax,1
  1107.             sub bx,ax
  1108.             xor dl,dl
  1109.             jmp SHORT func14c1
  1110.  
  1111. func14_lf1: inc dh
  1112.             add bx,160
  1113.             jmp SHORT func14c1
  1114.  
  1115. func14nl:   xor dl,dl
  1116.             sub bx,79*2
  1117.  
  1118. func14_lf:  cmp dh,24
  1119.             jb func14_lf1
  1120.             mov [si+OFFSET cursor_posn],dx
  1121.             mov cs:[si+OFFSET cur_pos],dx       ;This is needed due to bad programs
  1122.             push si
  1123.             push di
  1124.             push cx
  1125.             mov di,[crt_start]
  1126.             mov si,di
  1127.             add si,160
  1128.             mov ax,es
  1129.             mov ds,ax
  1130.             cld
  1131.             mov cx,80*24
  1132.  
  1133.             ifndef ega
  1134.  
  1135.             cmp cs:[wait_mode],0
  1136.             jz scrllx0b
  1137.  
  1138.             mov dx,3DAH
  1139. scrllx0a:   in al,dx
  1140.             test al,8
  1141.             jz scrllx0a
  1142.             mov al,25H
  1143.             mov dx,3D8H
  1144.             out dx,al
  1145. scrllx0b:
  1146.             endif
  1147.  
  1148.             mov ah,es:[bx+1]
  1149.             mov al,32
  1150.             rep movsw
  1151.             mov cl,80
  1152.             rep stosw
  1153.             xor ax,ax
  1154.             mov ds,ax
  1155.  
  1156.             ifndef ega
  1157.  
  1158.             cmp cs:[wait_mode],0
  1159.             jz scrllx3a
  1160.  
  1161.             mov al,[crt_mode_set]
  1162.             mov dx,3D8H
  1163.             out dx,al
  1164. scrllx3a:
  1165.             endif
  1166.  
  1167.             pop cx
  1168.             pop di
  1169.             pop si
  1170.             jmp func14c2
  1171.  
  1172. endofprog   EQU $
  1173.  
  1174.  
  1175.             ASSUME cs:sys,ds:sys,ss:nothing,es:nothing
  1176.  
  1177. ;
  1178. ;
  1179. ; Interrupt entry point of the device driver:
  1180. ;
  1181. interrupt   PROC FAR
  1182.  
  1183.             pushf
  1184.             push ds
  1185.             push es
  1186.             push si
  1187.             push di
  1188.             push bp
  1189.             push ax
  1190.             push bx
  1191.             push cx
  1192.             push dx
  1193.             lds bx,cs:[ptr_cmd]
  1194.             mov al,ds:[bx+02] 
  1195.             and al,al
  1196.             jnz no_init
  1197.             jmp init 
  1198. no_init:    mov WORD PTR ds:[bx+03],8002H
  1199. intret:     pop dx
  1200.             pop cx
  1201.             pop bx
  1202.             pop ax
  1203.             pop bp
  1204.             pop di
  1205.             pop si
  1206.             pop es
  1207.             pop ds
  1208.             popf
  1209.             ret
  1210.  
  1211. interrupt   ENDP
  1212.  
  1213.  
  1214. asc_dec:    xor ax,ax
  1215.             mov cx,10
  1216.             mov bh,ch
  1217. asc_dec1:   mov bl,es:[si]
  1218.             sub bl,'0'
  1219.             jb asc_dec2
  1220.             cmp bl,10
  1221.             jae asc_dec2
  1222.             mul cx
  1223.             add ax,bx
  1224.             inc si
  1225.             jmp asc_dec1
  1226. asc_dec2:   ret
  1227.  
  1228. ;
  1229. ;
  1230. ; Initialization of device driver
  1231. ;
  1232. ;
  1233. ; Note, Only 6 words left on stack !!
  1234. ;       No MS-DOS calls are allowed, except 01H to 0CH and 30H !!
  1235. ;
  1236.  
  1237. text1       DB 13,10,10,'AnDan Software Video BIOS Version 1.05',13,10,10,'$'
  1238. text2       DB 7,'WRONG ARGUMENT TO AD_VIDEO.SYS !!',13,10,'$'
  1239.  
  1240. init:       mov ax,OFFSET endofprog
  1241.             mov ds:[bx+14],ax        ;End address offset
  1242.             mov ds:[bx+16],cs        ;End address segment
  1243.             mov WORD PTR ds:[bx+03],0100H
  1244.             mov si,[bx+18]
  1245.             mov ax,[bx+20]
  1246.             mov es,ax
  1247.             mov ax,cs
  1248.             mov ds,ax
  1249.             cld
  1250.             mov ax,OFFSET newint
  1251.             mov [intp],ax
  1252.             mov dx,OFFSET text1
  1253.             mov ah,09H
  1254.             int 21H
  1255.  
  1256. init1:      lods BYTE PTR es:[si]
  1257.             cmp al,' '
  1258.             ja init1
  1259.             jb init7
  1260. init2:      lods BYTE PTR es:[si]
  1261.             cmp al,' '
  1262.             jz init2
  1263.             jb init7
  1264.             cmp al,'/'
  1265.             jnz init6
  1266.             lods BYTE PTR es:[si]
  1267.  
  1268.             ifndef ega
  1269.  
  1270.             cmp al,'W'
  1271.             jz init4
  1272.             cmp al,'w'
  1273.             jz init4
  1274.  
  1275.             endif
  1276.  
  1277.             cmp al,'D'
  1278.             jz init5
  1279.             cmp al,'d'
  1280.             jz init5
  1281.             cmp al,'B'
  1282.             jz init3
  1283.             cmp al,'b'
  1284.             jnz init6
  1285.  
  1286. init3:      call asc_dec
  1287.             mov [bell_loop],ax
  1288.             jmp init2
  1289.  
  1290.             ifndef ega
  1291.  
  1292. init4:      mov [wait_mode],1
  1293.             jmp init2
  1294.  
  1295.             endif
  1296.  
  1297. init5:      mov [dos_mode],1
  1298.             jmp init2
  1299.  
  1300. init6:      mov dx,OFFSET text2
  1301.             mov ah,09H
  1302.             int 21H
  1303.  
  1304. ;
  1305. ; Initialize resident code
  1306. ;
  1307. init7:      xor ax,ax
  1308.             mov es,ax
  1309.  
  1310.             ASSUME es:bios
  1311.  
  1312.             mov ax,es:[equip_flag]
  1313.             and al,30H
  1314.             cmp al,30H
  1315.             jnz init7a
  1316.             mov [video_mem],0B000H
  1317.  
  1318. init7a:     mov ax,3510H
  1319.             int 21H
  1320.             mov [old10h_o],bx
  1321.             mov ax,es
  1322.             mov [old10h_s],ax
  1323.             cmp [dos_mode],0
  1324.             jnz init8
  1325.             xor ax,ax
  1326.             mov es,ax
  1327.             mov ax,cs
  1328.             cli
  1329.             mov es:[10H*4+2],ax
  1330.             mov WORD PTR es:[10H*4],OFFSET int10h
  1331.             sti
  1332.             jmp SHORT init9
  1333.  
  1334. init8:      mov ax,2510H
  1335.             mov dx,OFFSET int10h
  1336.             int 21H
  1337.  
  1338. init9:      xor ax,ax
  1339.             mov ds,ax
  1340.             call init_pos
  1341.  
  1342.             jmp intret
  1343.  
  1344. sys         ENDS
  1345.  
  1346.             END
  1347.