Guest User

Untitled

a guest
Jul 17th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.                                                                      
  2.                                                                      
  3.                                                                      
  4.                                              
  5. ;/****************************************************************************
  6. ;*
  7. ;*      Low-level Video I/O module for Windowing environment
  8. ;*
  9. ;*      Copyright (C) 1993-1994  Emory Horvath
  10. ;*      All rights reserved.
  11. ;*
  12. ;****************************************************************************/
  13.  
  14. MOUSE_SUPPORT  EQU  1
  15.  
  16. IFDEF DEBUG
  17.   MONO_2  EQU  1
  18. ENDIF
  19.  
  20. .286
  21. .MODEL  small, pascal
  22.  
  23.  
  24.  
  25.  
  26. CR      EQU     13
  27. LF      EQU     10
  28. TAB     EQU     9
  29. SPACE   EQU     32
  30.  
  31.  
  32. MDA             EQU     0               ; Adapter constants
  33. CGA             EQU     1
  34. MCGA            EQU     2
  35. EGA             EQU     3
  36. VGA             EQU     4
  37.  
  38. MONO            EQU     0               ; Display constants
  39. COLOR           EQU     1
  40.  
  41.  
  42. ;;
  43. ;; Structure for video configuration
  44. ;;
  45. VIDINFO         STRUCT
  46.   sgmnt         WORD    ?
  47.   curStd        WORD    ?
  48.   curInsert     WORD    ?
  49.   curOverwrite  WORD    ?
  50.   mode          BYTE    ?
  51.   dpage         BYTE    ?
  52.   rows          BYTE    ?
  53.   cols          BYTE    ?
  54.   display       BYTE    ?
  55.   adapter       BYTE    ?
  56.   primary       BYTE    ?
  57.   secondary     BYTE    ?
  58.   fShowCursor   BYTE    ?
  59. VIDINFO         ENDS
  60.  
  61.  
  62. ;;
  63. ;; Structure for storing startup video info, for restoring upon exit
  64. ;;
  65. OLDINFO         STRUCT
  66.   cursor        WORD    ?
  67.   sgmnt         WORD    ?
  68.   mode          BYTE    ?
  69.   dpage         BYTE    ?
  70.   rows          BYTE    ?
  71.   xCur          BYTE    ?
  72.   yCur          BYTE    ?
  73. OLDINFO         ENDS
  74.  
  75.  
  76. RECT    STRUCT
  77.         left    WORD    ?
  78.         top     WORD    ?
  79.         right   WORD    ?
  80.         bottom  WORD    ?
  81. RECT    ENDS
  82.  
  83. POINT   STRUCT
  84.         x       WORD    ?
  85.         y       WORD    ?
  86. POINT   ENDS
  87.  
  88.  
  89. ;;
  90. ;; BLOCK - Header structure for saved screen regions
  91. ;;
  92. BLOCK   STRUCT
  93.         voffset WORD    ?
  94.         ccols   WORD    ?
  95.         clines  WORD    ?
  96. BLOCK   ENDS
  97.  
  98.  
  99. IFDEF MOUSE_SUPPORT
  100.   EXTERN PASCAL MouseShow:PROC
  101.   EXTERN PASCAL MouseHide:PROC
  102. ENDIF
  103.  
  104. IFDEF DEBUG
  105.   EXTERN PASCAL DbgOut:PROC
  106. ENDIF
  107.  
  108. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  109.  
  110.  
  111. .DATA
  112.  
  113. vinfo           VIDINFO <>
  114. PUBLIC vinfo
  115. oinfo           OLDINFO <>
  116. PUBLIC oinfo
  117.  
  118. attr            BYTE    07h             ; Current cell attributes
  119.  
  120.  
  121. IFDEF MONO_2
  122. ;; Info for secondary mono debug monitor, if present
  123. ;;
  124.   mseg          WORD    0               ; Saved vid buffer seg of primary
  125.   mattr         BYTE    ?               ; Saved attr for primary
  126.   mdisplay      BYTE    ?               ; Saved primary display type
  127.   mrows         BYTE    ?               ; Saved # of rows
  128.   mcols         BYTE    ?               ; Saved # of cols
  129.  
  130.   sseg          WORD    ?               ; Vid buffer seg of secondary
  131.   sattr         BYTE    07h             ; Attr to use for secondary
  132.   sdisplay      BYTE    ?               ; Secondary type (MONO, COLOR)
  133.   srows         BYTE    ?               ; Secondary monitor rows
  134.   scols         BYTE    ?               ; Secondary monitor cols
  135. ENDIF
  136.  
  137.  
  138. IFDEF MOUSE_SUPPORT
  139.   EXTERN cxMouse:WORD                   ; Current mouse x-coord (in MOUSE.ASM)
  140.   EXTERN cyMouse:WORD                   ; Current mouse y-coord (in MOUSE.ASM)
  141.   EXTERN fUpdateMouse:BYTE              ; Cursor has been overwritten and
  142. ENDIF                                   ;    needs to be redisplayed.
  143.  
  144.  
  145. IFDEF DEBUG
  146.    msgVid1      DB      '  10.1A passed', LF, 0
  147.    msgVid2      DB      '  Check EGA', LF, 0
  148.    msgVid3      DB      '  Check CGA', LF, 0
  149. ENDIF
  150.  
  151. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  152.  
  153.  
  154.  
  155. .CODE
  156.  
  157.  
  158. IFDEF DEBUG
  159. ;/****************************************************************************
  160. ;*  VidDbgOut() - Displays a debug message
  161. ;****************************************************************************/
  162. VidDbgOut      PROC NEAR  USES ax bx cx dx es,  pszMsg:WORD
  163.         pushf
  164.         push    pszMsg
  165.         call    DbgOut
  166.         popf
  167.         ret
  168. VidDbgOut      ENDP
  169. ENDIF
  170.  
  171.  
  172. DebugOut MACRO msg
  173.   IFDEF DEBUG
  174.         push    offset msg
  175.         call    VidDbgOut
  176.   ENDIF
  177. ENDM
  178.  
  179.  
  180.  
  181. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  182. ;;      VideoBios() -
  183. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  184. public VideoBios
  185. VideoBios::
  186.         push    bp
  187.         int     10h
  188.         pop     bp
  189.         ret
  190.  
  191.  
  192.  
  193. ;/*****************************************************************************
  194. ;*      VidInit() - Initializes video module
  195. ;*
  196. ;*      Determines current mode and hardware, saves old mode, puts video in
  197. ;*      known state, and clears screen.
  198. ;*
  199. ;*      GetVidInfo() MUST be called before calling VidInit()!
  200. ;*
  201. ;*      Params
  202. ;*          cLines - #of lines to init screen to, or 0 if use current #lines
  203. ;*          fHigh  - TRUE to enable high-intensity background colors
  204. ;*      Return
  205. ;*          TRUE if successful, FALSE if error.
  206. ;*****************************************************************************/
  207. VidInit         PROC    cLines:WORD, fHigh:WORD
  208.     ;; Save original screen state, to restore upon exit
  209.         mov     ax, vinfo.curStd
  210.         mov     oinfo.cursor, ax
  211.         mov     ax, vinfo.sgmnt
  212.         mov     oinfo.sgmnt, ax
  213.         mov     al, vinfo.dpage
  214.         mov     oinfo.dpage, al
  215.         mov     al, vinfo.rows
  216.         mov     oinfo.rows, al
  217.         mov     al, vinfo.mode
  218.         mov     oinfo.mode, al
  219.  
  220.     ;; Get original cursor position
  221.         mov     ax, 0300h
  222.         mov     bh, vinfo.dpage
  223.         call    VideoBios
  224.         mov     oinfo.xCur, dl
  225.         mov     oinfo.yCur, dh
  226.  
  227.     ;; Set to display page 0
  228.         cmp     vinfo.dpage, 0h
  229.         je      vi1
  230.         mov     ax, 0500h
  231.         call    VideoBios
  232.         mov     vinfo.dpage, 0h
  233.     vi1:
  234.  
  235.     ;;
  236.     ;; Are we in standard 80x25/43/50 mode?  If not, then put us in it.
  237.     ;; There be a lot of custom modes out there, and i'll have no idea how
  238.     ;; to handle them (not to mention those graphics modes!).
  239.     ;;
  240.         cmp     vinfo.mode, 02          ; 80x25/43/50 no burst ?
  241.         je      vi4
  242.         cmp     vinfo.mode, 03          ; 80x25/43/50 burst ?
  243.         je      vi4
  244.         cmp     vinfo.mode, 07          ; 80x25 monochrome ?
  245.         je      vi4
  246.  
  247.         mov     ax, 0003h               ; Switch to standard 80x25 mode
  248.         call    VideoBios
  249.         call    GetVidInfo              ; Everything's changed now, so recheck
  250.  
  251.         ;; If previous mode had large # of lines, then try to switch to
  252.         ;; 43/50 line mode here.
  253.         cmp     oinfo.rows, 40
  254.         jl      vi4
  255.         push    word ptr 50
  256.         call    VidSetLines
  257.         jmp     short vi2
  258.  
  259.     vi4:
  260.         call    VidClearScreen
  261.     ;; Set new line mode, if caller requested it
  262.         mov     ax, cLines
  263.         or      ax, ax
  264.         jz      vi2
  265.         cmp     vinfo.mode, 07h         ; Don't change if in mono-text mode
  266.         je      vi2
  267.         push    ax
  268.         call    VidSetLines
  269.  
  270.     ;; Set insert-mode cursor
  271.     vi2:
  272.         push    word ptr 01h
  273.         call    VidSetCurType
  274.  
  275.     ;; Enable high-intensity background colors?
  276.         cmp     fHigh, 00h
  277.         jz      vi3
  278.         xor     ax, ax
  279.         push    ax
  280.         call    VidSetBlink
  281.  
  282.     vi3:
  283.         mov     ax, 1                   ; Return success
  284.         ret
  285. VidInit         ENDP
  286.  
  287.  
  288.  
  289. ;/*****************************************************************************
  290. ;*      VidTerminate() - Closes down video library and restores startup state
  291. ;*
  292. ;*      Params
  293. ;*          None.
  294. ;*      Return
  295. ;*          None.
  296. ;*****************************************************************************/
  297. VidTerminate    PROC
  298.     ;; Reenable blinking
  299.         push    word ptr 01h
  300.         call    VidSetBlink
  301.  
  302.     ;; Does video mode need to be restored?
  303.     ;;
  304.     ;; My thinking here is that the standard 25/43/50 line EGA/VGA modes will
  305.     ;; be restored correctly by VidSetLines(), and that the proprietary modes
  306.     ;; will be using a different mode #, so they'll be restored correctly
  307.     ;; by SetVideoMode below.  We'll see how well this turns out...
  308.     ;;
  309.         mov     al, oinfo.mode
  310.         cmp     al, vinfo.mode
  311.         je      vt3
  312.         mov     vinfo.mode, al
  313.         xor     ah, ah                  ; Set Video Mode
  314.         call    VideoBios
  315.         jmp     short vt1               ; And skip the restore-linemode step
  316.  
  317.     vt3:
  318.         call    VidClearScreen
  319.     ;; Does linemode need to be restored?
  320.         xor     ax, ax
  321.         mov     al, oinfo.rows
  322.         cmp     al, vinfo.rows
  323.         je      vt1
  324.         inc     ax
  325.         push    ax
  326.         call    VidSetLines
  327.  
  328.     vt1:
  329.     ;; Does page need to be restored?
  330.         mov     al, oinfo.dpage
  331.         cmp     al, vinfo.dpage
  332.         je      vt2
  333.         mov     ah, 05h
  334.         call    VideoBios
  335.  
  336.     vt2:
  337.     ;; Restore cursor type
  338.         mov     cx, oinfo.cursor
  339.         mov     ax, 0100h
  340.         call    VideoBios
  341.  
  342.     ;; Set cursor to orginal position
  343.         mov     bh, oinfo.dpage
  344.         mov     dl, oinfo.xCur
  345.         mov     dh, oinfo.yCur
  346.         mov     ax, 0200h
  347.         call    VideoBios
  348.  
  349.         ret
  350. VidTerminate    ENDP
  351.  
  352.  
  353.  
  354. ;****************************************************************************
  355. ;* GetVidInfo - Determines current video configuration and initializes
  356. ;* the vconfig structure.
  357. ;*
  358. ;* Derived from QC251/MASM6 sample source
  359. ;*
  360. ;* Uses:    vinfo
  361. ;*
  362. ;* Params:  None
  363. ;*
  364. ;* Return:  None
  365. ;****************************************************************************
  366. GetVidInfo      PROC
  367.         mov     ax, 1A00h               ; Get video info for VGA
  368.         call    VideoBios
  369.     chkVGA:
  370.         cmp     al, 1Ah                 ; Is VGA or MCGA present?
  371.         jne     chkEGA                  ; No?  Then check for EGA
  372.  
  373.         DebugOut msgVid1
  374.  
  375. IFDEF MONO_2
  376. ;; Determine if secondary debug monitor.  I allow only the following for now:
  377. ;;    Primary=VGA with Secondary=MDA.
  378. ;; If anything else, they can't use debug monitor.
  379. ;;
  380. ;; BL = Active display type
  381. ;; BH = Inactive display type
  382. ;;
  383.         mov     sseg, 00h               ; Assume no debug monitor
  384.         cmp     bh, 01h                 ; Secondary == MDA?
  385.         jne     gviNoDebug
  386.         cmp     bl, 07h                 ; Primary < Monochrome VGA?
  387.         jl      gviNoDebug
  388.         cmp     bl, 08h                 ; Primary > Color VGA?
  389.         jg      gviNoDebug
  390.  
  391.         mov     sseg, 0B000h            ; Set up secondary info
  392.         mov     sdisplay, MONO
  393.         mov     srows, 24
  394.         mov     scols, 80
  395.     gviNoDebug:
  396. ENDIF
  397.  
  398.         cmp     bl, 2                   ; If VGA exists as secondary adapter,
  399.         je      isCGA                   ;   check for CGA and mono as primary
  400.         jb      isMONO
  401.         cmp     bl, 5                   ; If EGA is primary, do normal
  402.         jbe     chkEGA                  ;   EGA checking
  403.     chkMCGA:
  404.         mov     vinfo.adapter, MCGA     ; Yes?  Assume MCGA
  405.         mov     vinfo.display, COLOR
  406.         cmp     bl, 8                   ; Correct assumption?
  407.         ja      gotmode                 ; Yes?  Continue
  408.     isVGA:
  409.         mov     vinfo.adapter, VGA      ; Assume it's VGA color
  410.  
  411. ;; ECH - Use color colors for VGA Mono as well (8514 reports as VGA Mono)
  412. ;;        je      gotmode                 ; Yes?  Continue
  413. ;;        mov     vinfo.display, MONO     ; No?  Must be VGA mono
  414.  
  415.         jmp     gotmode                 ; Finished with VGA, so jump
  416.  
  417.     chkEGA:
  418.         DebugOut msgVid2
  419.         mov     ah, 12h                 ; Call EGA status function
  420.         mov     bl, 10h
  421.         sub     cx, cx                  ; Clear status bits
  422.         call    VideoBios
  423. ;;
  424. ;; ?BUGBUG? - _Interrupt_List_ says that you should call this function with
  425. ;;      BH=FFh.  If BH unchanged on return, then EGA not installed.
  426. ;;
  427.         jcxz    chkCGA                  ; If CX is unchanged, not EGA
  428.     isEGA:
  429.         mov     vinfo.adapter, EGA      ; Set structure fields for EGA
  430.         mov     vinfo.display, MONO     ; Assume EGA mono
  431.         or      bh, bh                  ; Correct assumption?
  432.         jnz     gotmode                 ; Yes?  Continue
  433.         mov     vinfo.display, COLOR    ; No?  Must be EGA color
  434.         jmp     gotmode                 ; Finished with EGA, so jump
  435.  
  436.     chkCGA:
  437.         DebugOut msgVid3
  438.         int     11h                     ; Get equipment list
  439.         and     al, 30h                 ; If bits 4-5 set, monochrome
  440.         cmp     al, 30h                 ; Monochrome text mode?
  441.         je      isMONO                  ; Yes?  Continue
  442.     isCGA:
  443.         mov     vinfo.adapter, CGA      ; No?  Must be CGA
  444.         mov     vinfo.display, COLOR
  445.         jmp     gotmode
  446.  
  447.     isMONO:
  448.         mov     vinfo.adapter, MDA      ; Set MONO
  449.         mov     vinfo.display, MONO
  450.         mov     vinfo.sgmnt, 0B000h     ; Monochrome (MDA) mode
  451.  
  452.     gotmode:
  453.         mov     ah, 0Fh
  454.         call    VideoBios               ; Get current mode
  455.         mov     vinfo.mode, al          ; Record mode
  456.         mov     vinfo.dpage, bh         ;   and current page
  457.  
  458.     ;; If mode 7, force to use monochrome
  459.         cmp     al, 7
  460.         jne     gviColor
  461.         mov     vinfo.display, MONO
  462.         mov     vinfo.sgmnt, 0B000h     ; Monochrome (MDA) mode
  463.         mov     vinfo.curInsert, 0B0Ch
  464.         mov     vinfo.curOverwrite, 000Ch
  465.         jmp     short getdispl
  466.  
  467.     gviColor:
  468.         mov     vinfo.sgmnt, 0B800h     ; Color mode
  469.         mov     vinfo.curInsert, 0607h
  470.         mov     vinfo.curOverwrite, 0007h
  471.  
  472.     getdispl:
  473.         mov     ax, 0040h
  474.         mov     es, ax
  475.         mov     al, es:[004Ah]          ; Get number of display cols
  476.         mov     vinfo.cols, al          ; Store in structure
  477.         mov     vinfo.rows, 24          ; Assume bottom row # = 24
  478.         cmp     vinfo.adapter, EGA      ; EGA or VGA?
  479.         jl      gviCurs                 ; No?  Exit
  480.         mov     ax, 1130h               ; Yes?  Request character info
  481.         sub     bh, bh                  ; Set BH to valid value
  482.         call    VideoBios               ; Get number of rows/screen
  483. ;;
  484. ;; ?BUGBUG? - _Interrupt_List_ says that EGA returns (#of rows), rather than
  485. ;;      (#of rows - 1).  But INFOPLUS doesn't take this into account either.
  486. ;; MSD gets #of rows-1 from byte at 0040h:0084h.
  487. ;;
  488.         mov     vinfo.rows, dl          ; Keep in structure
  489.  
  490.     gviCurs:
  491.     ;; Get cursor info
  492.         mov     ax, 0300h
  493.         mov     bh, vinfo.dpage
  494.         call    VideoBios
  495.         mov     vinfo.curStd, cx
  496.  
  497.         ret
  498. GetVidInfo      ENDP
  499.  
  500.  
  501.  
  502. ;****************************************************************************
  503. ;* VidSetLines - Sets line mode for EGA or VGA.
  504. ;*
  505. ;* Derived from QC251/MASM6 sample source.
  506. ;*
  507. ;* Uses:    vinfo - Video configuration structure (initialized
  508. ;*          by calling the GetVidConfig procedure)
  509. ;*
  510. ;* Params:  Line - Requested line mode (25, 43, or 50)
  511. ;*
  512. ;* Return:  Short integer with error code
  513. ;*          0 if successful
  514. ;*          1 if error
  515. ;****************************************************************************
  516. VidSetLines     PROC        Line:WORD
  517.         cmp     vinfo.adapter, EGA
  518.         jl      slmE_exit
  519. ;;
  520. ;; Sets highest linemode possible that's <= Line
  521. ;;
  522.         mov     ax, Line
  523.         cmp     vinfo.adapter, EGA      ; >25 lines only available on EGA/VGA
  524.         jl      line25
  525.  
  526.         cmp     al, 25
  527.         jle     line25
  528.         cmp     al, 43
  529.         jle     line43
  530.         jmp     short line50
  531.  
  532.     line25:
  533.         mov     vinfo.rows, 24
  534.         mov     al, 11h                 ; Set for EGA 25-line mode
  535.         cmp     vinfo.adapter, EGA      ; EGA?
  536.         je      linemode                ; Yes?  Continue
  537.         mov     ax, 1202h               ; No?  Function 12h for VGA
  538.         mov     bl, 30h                 ; AL = 2 for 400 scan lines
  539.         call    VideoBios               ; Reset to 400 scan lines
  540.         mov     ax, 0003                ; Reset mode to enable new #scanlines
  541.         call    VideoBios
  542.         mov     al, 14h                 ; Request 8x16 char matrix
  543.         jmp     linemode
  544.  
  545.     line43:
  546.         mov     vinfo.rows, 42
  547.         mov     al, 12h                 ; Set for EGA 43-line mode
  548.         cmp     vinfo.adapter, EGA      ; EGA?
  549.         je      linemode                ; Yes?  Continue
  550.         mov     ax, 1201h               ; No?  Function 12h for VGA
  551.         mov     bl, 30h                 ; AL = 1 for 350 scan lines
  552.         call    VideoBios               ; Reset to 350 scan lines
  553.         mov     ax, 0003                ; Reset mode to enable new #scanlines
  554.         call    VideoBios
  555.         mov     al, 12h                 ; Request 8x8 character matrix
  556.         jmp     linemode
  557.  
  558.     line50:
  559.         mov     vinfo.rows, 49
  560.         cmp     vinfo.adapter, VGA      ; VGA?
  561.         jne     line43                  ; No?  Try 43line mode instead
  562.         mov     ax, 1202h               ; Yes?  Function 12h
  563.         mov     bl, 30h                 ; AL = 2 for 400 scan lines
  564.         call    VideoBios               ; Reset to 400 scan lines
  565.         mov     ax, 0003                ; Reset mode to enable new #scanlines
  566.         call    VideoBios
  567.         mov     al, 12h                 ; Request 8x8 character matrix
  568.  
  569.     linemode:
  570.         sub     bl, bl                  ; Use table 0
  571.         mov     ah, 11h                 ; Request Function 11h
  572.         call    VideoBios               ; Set new line mode
  573.  
  574.         mov     ah, 12h                 ; Select alternate print
  575.         mov     bl, 20h                 ;   screen for EGA and VGA
  576.         call    VideoBios
  577.  
  578.         cmp     vinfo.adapter, VGA      ; VGA?
  579.         je      slmExit                 ; Yes?  Then exit
  580.  
  581.         push    word ptr 01h
  582.         call    VidSetCurType
  583.         jmp     slmExit                 ; Normal exit
  584.  
  585.     slmE_exit:
  586.         mov     ax, 1                   ; Set error code
  587.         jmp     slmExit2
  588.     slmExit:
  589.         call    VidClearScreen
  590.         sub     ax, ax                  ; Clear error code
  591.     slmExit2:
  592.         ret
  593. VidSetLines ENDP
  594.  
  595.  
  596.  
  597. ;/*****************************************************************************
  598. ;*      VidSetBlink() - Enables/Disables background blinking
  599. ;*
  600. ;*      Params
  601. ;*          fBlink - TRUE to enable blinking, FALSE to enable high-intensity
  602. ;*      Return
  603. ;*          None.
  604. ;*****************************************************************************/
  605. VidSetBlink     PROC            fBlink:WORD
  606.         mov     al, vinfo.adapter
  607.         cmp     al, CGA                 ; If <CGA, don't bother
  608.         jl      vsblExit1
  609.         cmp     al, MCGA                ; If <MCGA, must set it manually
  610.         jl      vsblUsePort
  611.  
  612.     ;; For EGA and above, we can use Int 10h, Function 1003h.
  613.         mov     ax, 01003h
  614.         xor     bh, bh                  ; For Boca EGA (see _Interrupt_List_)
  615.         mov     bl, byte ptr fBlink
  616.         call    VideoBios
  617.         jmp     short vsblExit1
  618.  
  619.     ;; Oh well, got to do it manually...
  620.     vsblUsePort:
  621.         mov     dx, 03D8h               ; CGA's Mode-Control register
  622.  
  623. ;;
  624. ;; My MDA card did some strange things once in awhile when i tried this.
  625. ;; MDA not important enough to bother with here anyway.
  626. ;;
  627. ;;;;
  628. ;;;; Well no wonder it did strange things - the previous code was using
  629. ;;;; random values in ES!
  630. ;;;;
  631. ;        cmp     al, CGA
  632. ;        je      vsblDoIt
  633. ;        cmp     al, MDA                 ; Not CGA, is it MDA?
  634. ;        jne     vsblExit1               ; Don't recognize the adapter
  635. ;        mov     dx, 03B8h               ; MDA's Mode-Control register
  636.  
  637.     vsblDoIt:
  638.     ;; Load current value of Mode-Control register from video data area
  639.         mov     ax, 040h                ; Video-data segment
  640.         mov     es, ax
  641.         mov     bx, 065h                ; Mode-Control reg contents address
  642.         mov     al, es:[bx]
  643.     ;; Do we set it or clear it?
  644.         cmp     byte ptr fBlink, 00h
  645.         jnz     vsblSetIt
  646.         and     al, 11011111b           ; Clear blink-enable bit
  647.         jmp     short vsblWrite
  648.     vsblSetIt:
  649.         or      al, 00100000b           ; Set blink-enable bit
  650.  
  651.     ;; Ok, write it out now
  652.     vsblWrite:
  653.         mov     es:[bx], al             ; Save changes back to vid-data area
  654.         out     dx, al                  ; And set the Mode-Control register
  655.  
  656.     vsblExit1:
  657.         ret
  658. VidSetBlink     ENDP
  659.  
  660.  
  661.  
  662. ;****************************************************************************
  663. ;*      VidClearScreen() - Clears entire screen to white-on-black
  664. ;*
  665. ;*      Params
  666. ;*          None.
  667. ;*      Returns
  668. ;*          None.
  669. ;****************************************************************************
  670. VidClearScreen  PROC
  671.         LOCAL   r:RECT
  672.  
  673.         xor     ax, ax                  ; Set up rect to include entire screen
  674.         mov     r.top, ax
  675.         mov     r.left, ax
  676.         mov     al, vinfo.cols
  677.         mov     r.right, ax
  678.         mov     al, vinfo.rows
  679.         inc     al
  680.         mov     r.bottom, ax
  681.  
  682.         lea     ax, r.left
  683.         push    ax
  684.         mov     ah, 07h                 ; assume white on black for now
  685.         mov     attr, ah
  686.         mov     al, SPACE
  687.         push    ax
  688.         call    VidFillBlock
  689.         ret
  690. VidClearScreen  ENDP
  691.  
  692.  
  693.  
  694. IFDEF MONO_2
  695. ;/*****************************************************************************
  696. ;*      VidHasDebug() - Returns TRUE if system has secondary debug monitor.
  697. ;*                    Currently only recognizes Primary=VGA with Secondary=MDA.
  698. ;*
  699. ;*      Params
  700. ;*          None.
  701. ;*      Return
  702. ;*          TRUE if debug monitor present, FALSE if not.
  703. ;*****************************************************************************/
  704. VidHasDebug PROC
  705.         xor     ax, ax
  706.     ;; Do we have a debug monitor?
  707.         cmp     sseg, 0h
  708.         jz      vhdExit1
  709.         mov     al, 01h
  710.     vhdExit1:
  711.         ret
  712. VidHasDebug ENDP
  713. ENDIF
  714.  
  715.  
  716. IFDEF MONO_2
  717. ;/*****************************************************************************
  718. ;*      VidUseDebug() - Switches to secondary debug monitor.
  719. ;*
  720. ;*      Params
  721. ;*          None.
  722. ;*      Return
  723. ;*          None.
  724. ;*****************************************************************************/
  725. VidUseDebug PROC
  726.     ;; Do we have a debug monitor?
  727.         cmp     sseg, 0h
  728.         jz      vudErr1
  729.  
  730.     ;; Are we already using debug?
  731.         cmp     mseg, 0h
  732.         jnz     vudErr1
  733.  
  734.     ;; Save primary info
  735.         mov     ax, vinfo.sgmnt
  736.         mov     mseg, ax
  737.         mov     al, vinfo.display
  738.         mov     mdisplay, al
  739.         mov     al, attr
  740.         mov     mattr, al
  741.         mov     al, vinfo.rows
  742.         mov     ah, vinfo.cols
  743.         mov     mrows, al
  744.         mov     mcols, ah
  745.  
  746.     ;; Reintialize with debug info
  747.         mov     ax, sseg
  748.         mov     vinfo.sgmnt, ax
  749.         mov     al, sdisplay
  750.         mov     vinfo.display, al
  751.         mov     al, sattr
  752.         mov     attr, al
  753.         mov     al, srows
  754.         mov     ah, scols
  755.         mov     vinfo.rows, al
  756.         mov     vinfo.cols, ah
  757.  
  758.     vudErr1:
  759.         ret
  760. VidUseDebug ENDP
  761. ENDIF
  762.  
  763.  
  764. IFDEF MONO_2
  765. ;/*****************************************************************************
  766. ;*      VidUseMain() - Switches back to primary monitor.
  767. ;*
  768. ;*      Params
  769. ;*          None.
  770. ;*      Return
  771. ;*          None.
  772. ;*****************************************************************************/
  773. VidUseMain PROC
  774.     ;; Are we already using main?
  775.         cmp     mseg, 0h
  776.         jz      vumErr1
  777.  
  778.     ;; Save debug info
  779.         mov     al, attr
  780.         mov     sattr, al
  781.  
  782.     ;; Reintialize with primary info
  783.         mov     ax, mseg
  784.         mov     vinfo.sgmnt, ax
  785.         mov     mseg, 0h                ; Record that we're now in 'main' mode
  786.         mov     al, mdisplay
  787.         mov     vinfo.display, al
  788.         mov     al, mattr
  789.         mov     attr, al
  790.         mov     al, mrows
  791.         mov     ah, mcols
  792.         mov     vinfo.rows, al
  793.         mov     vinfo.cols, ah
  794.  
  795.     vumErr1:
  796.         ret
  797. VidUseMain ENDP
  798. ENDIF
  799.  
  800.  
  801. IFDEF MONO_2
  802. ;/*****************************************************************************
  803. ;*      MDAShowCursor() - Shows/hides the cursor on MDA, bypassing BIOS.
  804. ;*
  805. ;*      Params
  806. ;*          AX: TRUE if show cursor, FALSE if hide
  807. ;*      Return
  808. ;*          None.
  809. ;*      Uses
  810. ;*          AX, CD DX
  811. ;*****************************************************************************/
  812. MDAShowCursor   PROC
  813.     ;;
  814.     ;; I can't use the bios to set cursor on debug monitor, since primary
  815.     ;; monitor is currently active (changing video mode to monochrome didn't
  816.     ;; work at all).  So i've got to write directly to the CRT registers.
  817.     ;;
  818.     ;; Show or Hide cursor?
  819.         mov     cx, 2000h               ; Assume hide-cursor
  820.         or      ax, ax
  821.         mov     ax, 0B0Ah               ; Cursor end-line/start-line registers
  822.         jz      mdaWriteIt
  823.  
  824.         mov     cx, 0B0Ch               ; Else set normal cursor
  825.         jmp     short mdaWriteIt
  826. MDAShowCursor   ENDP
  827. ENDIF
  828.  
  829.  
  830. IFDEF MONO_2
  831. ;/*****************************************************************************
  832. ;*      MDASetCurPos() - Sets cursor position on MDA, bypassing BIOS
  833. ;*
  834. ;*      Params
  835. ;*          AX: Y coordinate
  836. ;*          DX: X coordinate
  837. ;*      Return
  838. ;*          None.
  839. ;*      Uses
  840. ;*          AX, CX, DX
  841. ;*****************************************************************************/
  842. MDASetCurPos    PROC
  843.     ;;
  844.     ;; I can't use the bios to set cursor on debug monitor, since primary
  845.     ;; monitor is currently active (changing video mode to monochrome didn't
  846.     ;; work at all).  So i've got to write directly to the CRT registers.
  847.     ;;
  848.     ;; Calculate new cursor offset
  849.         mov     cl, 80
  850.         mul     cl
  851.         add     ax, dx
  852.         mov     cx, ax                  ; And save it in CX
  853.         mov     ax, 0F0Eh               ; Cursor-location low/high register
  854.  
  855. mdaWriteIt::
  856.     ;; Write high-byte of new cursor offset
  857.         mov     dx, 03B4h               ; CRT Index Register for MDA
  858.         out     dx, al
  859.         inc     dx                      ; Output port is at 3B5h
  860.         mov     al, ch                  ; Write high-byte of offset
  861.         out     dx, al
  862.         dec     dx
  863.     ;; Write low-byte of new cursor offset
  864.         mov     al, ah
  865.         out     dx, al
  866.         inc     dx                      ; Output port is at 3B5h
  867.         mov     al, cl                  ; Write low-byte of offset
  868.         out     dx, al
  869.         ret
  870. MDASetCurPos    ENDP
  871. ENDIF
  872.  
  873.  
  874.  
  875.  
  876. ;/*****************************************************************************
  877. ;*  Internal function.  Calculates offset to write to in video segment, and
  878. ;*  determines whether mouse cursor will be overwritten.
  879. ;*
  880. ;*      Params
  881. ;*          AX : Line to move to (0-based, and cliprect-relative)
  882. ;*          DX : Column to move to (0-based, and cliprect-relative)
  883. ;*          CX : # of chars requested to write
  884. ;*      Return
  885. ;*          BX    : Offset into video buffer
  886. ;*          CX    : # of chars to write (clipped to current cliprect)
  887. ;*          Carry : Clear if char visible, Set if not.
  888. ;*      Registers Destroyed
  889. ;*          AX, BX, CX, DX, Flags
  890. ;*
  891. ;*****************************************************************************/
  892. CalcXYC:
  893.     ; If 0 chars to write, then abort now.  The writestring routines have
  894.     ; problems with 0-length strings.  So DON'T remove this check!
  895.     ; Also, a 0-length string is NOT an error.
  896.         or      cx, cx
  897.         jz      cxyErr1
  898.  
  899. IFDEF MOUSE_SUPPORT
  900.     ; Determine whether mouse cursor might be overwritten
  901.         cmp     ax, cyMouse             ; Check if on same line
  902.         jne     cxyCalc
  903.         cmp     dx, cxMouse             ; Check if after starting column
  904.         jg      cxyCalc
  905.         mov     bx, dx                  ; Check if before ending column.
  906.         add     bx, cx
  907.         cmp     bx, cxMouse
  908.         jle     cxyCalc
  909.  
  910.         push    ax
  911.         push    cx
  912.         push    dx
  913.         call    MouseHide
  914.         pop     dx
  915.         pop     cx
  916.         pop     ax
  917.         mov     BYTE PTR fUpdateMouse, 01h      ; It might be overwritten
  918. ENDIF
  919.     ; Now calculate offset
  920.     ; Line# is already in AX
  921.     cxyCalc:
  922.         mul     BYTE PTR vinfo.cols     ; Calculate start of line
  923.         add     ax, dx
  924.         shl     ax, 1                   ; Change units from bytes to chars
  925.         mov     bx, ax                  ; Return address in BX
  926.  
  927.     cxyExit:
  928.         clc
  929.         ret
  930.  
  931.     cxyErr1:
  932.         stc
  933.         ret
  934.  
  935.  
  936.  
  937. ;/*****************************************************************************
  938. ;*      VidWrtChar() -- Write character to screen, in current cliprect
  939. ;*
  940. ;*      Notes
  941. ;*          Doesn't handle special chars.  This is the responsibility of
  942. ;*          other modules.
  943. ;*      Params
  944. ;*          ry   - y-coord (0-based)
  945. ;*          rx   - x-coord (0-based)
  946. ;*          char - char to write
  947. ;*      Return
  948. ;*          None.
  949. ;*****************************************************************************/
  950. VidWrtChar      PROC    ry:WORD, rx:WORD, char:BYTE
  951.         mov     ax, ry
  952.         mov     dx, rx
  953.         mov     cx, 01h                 ; Tell CalcXy() we're writing one char
  954.         call    CalcXYC                 ; Calculate video address to write to
  955.         ; returns offset in BX
  956.  
  957.         mov     es, vinfo.sgmnt         ; Load video segment
  958.         mov     al, char                ; Load char
  959.         mov     ah, attr                ; Load char attributes
  960.         mov     es:[bx], ax             ; Write the char!
  961.  
  962. IFDEF MOUSE_SUPPORT
  963.     ;; If mouse may have been overwritten, then redisplay it
  964.         cmp     BYTE PTR fUpdateMouse, 00h
  965.         jz      vwcEnd
  966.         call    MouseShow
  967. ENDIF
  968.     ;; Exit sequence
  969.     vwcEnd:
  970.         ret
  971. VidWrtChar      ENDP
  972.  
  973.  
  974.  
  975. ;/*****************************************************************************
  976. ;*      VidWrtStr() -- Writes a string to screen
  977. ;*
  978. ;*      Notes
  979. ;*          Doesn't handle special chars.  This is the responsibility of
  980. ;*          other modules.
  981. ;*      Params
  982. ;*          RY ry       - y-coord
  983. ;*          RX rx       - x-coord
  984. ;*          LPSTR lpsz  - far ptr to string
  985. ;*          uint cChars - #of chars to write
  986. ;*      Return
  987. ;*          None.
  988. ;*****************************************************************************/
  989. VidWrtStr       PROC USES si,    ry:WORD, rx:WORD, lpsz:DWORD, cChars:WORD
  990. ;;
  991. ;; DS:SI - Address of current char in supplied string
  992. ;; ES:BX - Address to write current char to
  993. ;; CX    - Number of chars left to write (adjusted for cliprect)
  994. ;; AL    - Current char to write
  995. ;; AH    - Attributes to use
  996. ;;
  997.         mov     ax, ry
  998.         mov     dx, rx
  999.         mov     cx, cChars
  1000.         call    CalcXYC                 ; Calculate video address to write to
  1001.         ; returns offset in BX, and #of chars to write in CX
  1002.         jc      vwsEnd                  ; Not visible!
  1003.  
  1004.         ; BX has starting offset
  1005.         ; CX has # of chars to write
  1006.         mov     es, vinfo.sgmnt         ; Load video segment
  1007.         mov     ah, attr                ; Load current display attribute
  1008.         push    ds
  1009.         lds     si, lpsz                ; Load string to display
  1010.  
  1011.         even
  1012.     vwsLoop:
  1013.         mov     al, ds:[si]             ; read current char
  1014.         mov     es:[bx], ax             ; write curent char
  1015.         inc     si                      ; goto next char
  1016.         add     bx, 2                   ; goto next video cell
  1017.         dec     cx                      ; decrement chars-left-to-write counter
  1018.         jnz     vwsLoop                 ; loop again if more chars to write
  1019.         pop     ds
  1020.  
  1021. IFDEF MOUSE_SUPPORT
  1022.     ;; If mouse may have been overwritten, then redisplay it
  1023.         cmp     BYTE PTR fUpdateMouse, 00h
  1024.         jz      vwsEnd
  1025.         call    MouseShow
  1026. ENDIF
  1027.     vwsEnd:
  1028.         ret
  1029. VidWrtStr       ENDP
  1030.  
  1031.  
  1032.  
  1033. IFNDEF QEDIT
  1034. ;/*****************************************************************************
  1035. ;*      VidWrtCells() -- Writes string/attributes to screen
  1036. ;*
  1037. ;*      Notes
  1038. ;*          Doesn't handle special chars.  This is the responsibility of
  1039. ;*          other modules.
  1040. ;*      Params
  1041. ;*          RY ry
  1042. ;*          RX rx
  1043. ;*          LPSTR lpCells
  1044. ;*          uint cCells   : # of cells, not # of chars
  1045. ;*      Return
  1046. ;*          None.
  1047. ;*****************************************************************************/
  1048. VidWrtCells   PROC USES ds si di,  ry:WORD, rx:WORD, lpCells:DWORD, cCells:WORD
  1049. ;;
  1050. ;; DS:SI - Address of current char in supplied string
  1051. ;; ES:BX - Address to write current char to
  1052. ;; CX    - Number of chars left to write (adjusted for cliprect)
  1053. ;; AL    - Current char to write
  1054. ;; AH    - Attributes to use
  1055. ;;
  1056.         mov     ax, ry
  1057.         mov     dx, rx
  1058.         mov     cx, cCells
  1059.         call    CalcXYC                 ; Calculate video address to write to
  1060.         ; returns offset in BX, and #of chars to write in CX
  1061.         jc      vwclEnd                 ; Not visible!
  1062.         mov     di, bx
  1063.  
  1064.         ; BX has starting offset
  1065.         ; CX has # of chars to write
  1066.         mov     es, vinfo.sgmnt         ; Load video segment
  1067.         lds     si, lpCells             ; Load string to display
  1068.         cld
  1069.         rep     movsw                   ; Write the chars
  1070.  
  1071. IFDEF MOUSE_SUPPORT
  1072.     ;; If mouse may have been overwritten, then redisplay it
  1073.         cmp     BYTE PTR fUpdateMouse, 00h
  1074.         jz      vwclEnd
  1075.         call    MouseShow
  1076. ENDIF
  1077.     vwclEnd:
  1078.         ret
  1079. VidWrtCells     ENDP
  1080. ENDIF
  1081.  
  1082.  
  1083.  
  1084. ;/*****************************************************************************
  1085. ;*      VidWrtCharN() - Writes char to screen N times
  1086. ;*
  1087. ;*      Params
  1088. ;*          RY ry       : row
  1089. ;*          RX rx       : column
  1090. ;*          CHAR char   : char to write
  1091. ;*          uint cChars : #of chars to write
  1092. ;*      Return
  1093. ;*          None.
  1094. ;*****************************************************************************/
  1095. VidWrtCharN     PROC    USES di,   ry:WORD, rx:WORD, char:BYTE, cChars:WORD
  1096.         mov     ax, ry
  1097.         mov     dx, rx
  1098.         mov     cx, cChars
  1099.         call    CalcXYC                 ; Calculate video address to write to
  1100.         ; returns offset in BX, and #of chars to write in CX
  1101.         jc      vwnEnd                  ; Not visible!
  1102.         mov     di, bx
  1103.  
  1104.         ;; CX has # of chars to write
  1105.         ;; DI has offset in video buffer to start at
  1106.         mov     al, char
  1107.         mov     ah, attr                ; Load current display attribute
  1108.         mov     es, vinfo.sgmnt         ; Load video segment
  1109.         cld
  1110.         rep     stosw                   ; Write the chars
  1111.  
  1112. IFDEF MOUSE_SUPPORT
  1113.     ;; If mouse may have been overwritten, then redisplay it
  1114.         cmp     BYTE PTR fUpdateMouse, 00h
  1115.         jz      vwnEnd
  1116.         call    MouseShow
  1117. ENDIF
  1118.     vwnEnd:
  1119.         ret
  1120. VidWrtCharN     ENDP
  1121.  
  1122.  
  1123.  
  1124. ;/*****************************************************************************
  1125. ;*      VidGetColor() - Returns current text color
  1126. ;*
  1127. ;*      Notes
  1128. ;*      Params
  1129. ;*          None.
  1130. ;*      Return
  1131. ;*          Returns CLR2 current color
  1132. ;*****************************************************************************/
  1133. VidGetColor     PROC
  1134.         xor     ax, ax
  1135.         mov     al, attr
  1136.         ret
  1137. VidGetColor     ENDP
  1138.  
  1139.  
  1140.  
  1141. ;/*****************************************************************************
  1142. ;*      VidSetColor() - Sets current text color
  1143. ;*
  1144. ;*      Notes
  1145. ;*      Params
  1146. ;*          CLR2 color : Color to set it to
  1147. ;*      Return
  1148. ;*          None.
  1149. ;*****************************************************************************/
  1150. VidSetColor     PROC    clr:BYTE
  1151.         mov     al, clr
  1152.         mov     attr, al
  1153.         ret
  1154. VidSetColor     ENDP
  1155.  
  1156.  
  1157.  
  1158. ;/*****************************************************************************
  1159. ;*      VidShowCursor() - Shows/hides the cursor
  1160. ;*
  1161. ;*      Params
  1162. ;*          bool bShow : TRUE if show cursor, FALSE if hide
  1163. ;*      Return
  1164. ;*          None.
  1165. ;*****************************************************************************/
  1166. VidShowCursor   PROC    bShow:WORD
  1167.         mov     ax, bShow
  1168. IFDEF MONO_2
  1169.     ;; Are we using debug monitor?  If so, bypass bios.
  1170.         cmp     mseg, 0h
  1171.         jz      vscUseBios
  1172.         call    MDAShowCursor
  1173.         jmp     short vscExit1
  1174.     vscUseBios:
  1175. ENDIF
  1176.         or      ax, ax
  1177.         jz      vscHidecur
  1178.  
  1179.         mov     cx, vinfo.curStd
  1180.         mov     vinfo.fShowCursor, 01h
  1181.         jmp     short vscDoit
  1182.     vscHidecur:
  1183.         mov     cx, 2000h
  1184.         mov     vinfo.fShowCursor, 00h
  1185.  
  1186.     vscDoit:
  1187.     ;;
  1188.     ;; _Interrupt_List_ says that AMI 386 BIOS and AST Premier 386 BIOS will
  1189.     ;; lock up the system if AL is not equal to the current video mode.
  1190.     ;;
  1191.         mov     al, vinfo.mode
  1192.         mov     ah, 01h
  1193.         call    VideoBios
  1194.     vscExit1:
  1195.         ret
  1196. VidShowCursor   ENDP
  1197.  
  1198.  
  1199.  
  1200. ;/*****************************************************************************
  1201. ;*      VidSetCurType() - Sets insert or overwrite cursor
  1202. ;*
  1203. ;*      Params
  1204. ;*          bool bInsert : TRUE for insert, FALSE for overwrite
  1205. ;*      Return
  1206. ;*          None.
  1207. ;*****************************************************************************/
  1208. ;;
  1209. ;; BUGBUG: There's supposed to be some sort of EGA 43-line-mode BIOS bug
  1210. ;;      here, but i can't find any details on it.  The code to handle it is
  1211. ;;      sort of large, so i'm leaving it out for now.  If someone complains,
  1212. ;;      i may implement it.
  1213. ;;
  1214. VidSetCurType   PROC    bInsert:WORD
  1215.         mov     cx, vinfo.curInsert
  1216.         cmp     bInsert, 0
  1217.         jnz     vsc1
  1218.         mov     cx, vinfo.curOverwrite
  1219.     vsc1:
  1220.         mov     vinfo.curStd, cx
  1221.         cmp     vinfo.fShowCursor, 00h      ; Cursor currently hidden?
  1222.         jz      vscExit                     ; If so, then don't really set it
  1223.     ;;
  1224.     ;; _Interrupt_List_ says that AMI 386 BIOS and AST Premier 386 BIOS will
  1225.     ;; lock up the system if AL is not equal to the current video mode.
  1226.     ;;
  1227.         mov     al, vinfo.mode
  1228.         mov     ah, 01h
  1229.         call    VideoBios
  1230.     vscExit:
  1231.         ret
  1232. VidSetCurType   ENDP
  1233.  
  1234.  
  1235.  
  1236. ;/*****************************************************************************
  1237. ;*      VidSetCurPos() - Sets cursor position
  1238. ;*
  1239. ;*      Params
  1240. ;*          uint cy : row to move to
  1241. ;*          uint cx : column to move to
  1242. ;*      Return
  1243. ;*          None.
  1244. ;*****************************************************************************/
  1245. VidSetCurPos    PROC    y:WORD, x:WORD
  1246.         mov     dx, x
  1247.         mov     ax, y
  1248. IFDEF MONO_2
  1249.     ;; Are we using debug monitor?  If so, bypass bios.
  1250.         cmp     mseg, 0h
  1251.         jz      vscpUseBios
  1252.         call    MDASetCurPos
  1253.         jmp     short vscpExit1
  1254.     vscpUseBios:
  1255. ENDIF
  1256.         mov     dh, al
  1257.         mov     ax, 0200h
  1258.         mov     bh, vinfo.dpage
  1259.         call    VideoBios
  1260.     vscpExit1:
  1261.         ret
  1262. VidSetCurPos    ENDP
  1263.  
  1264.  
  1265.  
  1266.  
  1267. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1268. ;;  CheckMouse() - Checks if mouse would be overwritten, and checks params.
  1269. ;;
  1270. ;;  Params
  1271. ;;      BX : Ptr to RECT structure
  1272. ;;  Return
  1273. ;;      Carry : Set if error, Clear if ok.
  1274. ;;
  1275. ;;  Registers Destroyed
  1276. ;;      AX, CX, DX, and Flags may be destroyed.
  1277. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1278. CheckMouse:
  1279. IFDEF MOUSE_SUPPORT
  1280.     ;; Check if cursor would be overwritten
  1281.     ;;
  1282.     ;; Since the mouse moves at interrupt-time, it's possible for it to move
  1283.     ;; DURING a video i/o call, after we've done our check here.  Only appears
  1284.     ;; to be a real problem during large scroll operations, that take a large
  1285.     ;; amount of time (and that make mouse droppings very noticeable).
  1286.     ;; For now, i'm adding a little fudge-factor (2 rows/cols) that hopefully
  1287.     ;; should handle it.
  1288.     ;; cxMouse/cyMouse are set at interrupt-time by mouse handler.
  1289.     ;;
  1290.         mov     ax, cxMouse
  1291.         add     ax, 2                   ; Fudge factor
  1292.         cmp     ax, [bx].RECT.left      ; Cursor before starting column?
  1293.         jl      cmNoHide
  1294.         sub     ax, 3                   ; Opposite fudge factor.
  1295.         cmp     ax, [bx].RECT.right     ; Cursor after ending column?
  1296.         jg      cmNoHide
  1297.  
  1298.         mov     ax, cyMouse
  1299.         add     ax, 2                   ; Fudge factor
  1300.         cmp     ax, [bx].RECT.top       ; Cursor before starting row?
  1301.         jl      cmNoHide
  1302.         sub     ax, 3                   ; Opposite fudge factor.
  1303.         cmp     ax, [bx].RECT.bottom    ; Cursor after ending row?
  1304.         jg      cmNoHide
  1305.  
  1306.         push    bx                      ; Save rect ptr
  1307.         call    MouseHide               ; If not, it'd be overwritten
  1308.         pop     bx                      ; Restore rect ptr
  1309.         mov     BYTE PTR fUpdateMouse, 01h
  1310.     cmNoHide:
  1311. ENDIF
  1312.         clc
  1313.     cmExit1:
  1314.         ret
  1315.  
  1316.  
  1317.  
  1318. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1319. ;;  SetupBlock() - Internal function.
  1320. ;;
  1321. ;;  Params
  1322. ;;      BX : Ptr to RECT
  1323. ;;  Returns
  1324. ;;      Carry : Set if error, Clear if ok.
  1325. ;;
  1326. ;;      BX : Start address for 1st line
  1327. ;;      CX : Line length (in chars)
  1328. ;;      DX : cxLineLen * 2
  1329. ;;      SI : #of lines to process
  1330. ;;      DI : Starting read/write offset
  1331. ;;      BP : Line length (in chars)
  1332. ;;      ES : video buffer segment
  1333. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1334. SetupBlock:
  1335.         call CheckMouse
  1336.         jc      sbExit1
  1337.  
  1338.         mov     ax, [bx].RECT.top
  1339.         mov     dx, [bx].RECT.left
  1340.         mov     cx, [bx].RECT.right
  1341.         mov     bx, [bx].RECT.bottom
  1342.  
  1343.         mov     si, bx                  ; Calculate number of lines
  1344.         sub     si, ax
  1345.  
  1346.         mul     BYTE PTR vinfo.cols     ; Calculate first line start
  1347.         add     ax, dx
  1348.         shl     ax, 1
  1349.         mov     di, ax
  1350.  
  1351.         sub     cx, dx                  ; Calculate line length
  1352.         mov     bp, cx                  ; Save it in BP
  1353.  
  1354.         xor     dx, dx
  1355.         mov     dl, vinfo.cols          ; Load columns * 2
  1356.         shl     dx, 1
  1357.         mov     bx, di                  ; Save line start
  1358.         mov     es, vinfo.sgmnt         ; Load video buffer segment
  1359.         cld
  1360.         clc
  1361.     sbExit1:
  1362.         ret
  1363.  
  1364.  
  1365.  
  1366. ;/*****************************************************************************
  1367. ;*      VidFillBlock() - Fills block on screen with specified char/attr.
  1368. ;*
  1369. ;*      Params
  1370. ;*          RECT *pr    : Ptr to RECT struct containing block to clear
  1371. ;*          uint chFill : Char/attr to fill with (HIBYTE:Attr, LOBYTE:Char)
  1372. ;*      Return
  1373. ;*          None.
  1374. ;*****************************************************************************/
  1375. VidFillBlock   PROC    USES si di,     pr:WORD, chFill:WORD
  1376.         push    bp
  1377.         mov     ax, chFill
  1378.         push    ax
  1379.         mov     bx, pr
  1380.         call    SetupBlock
  1381.         pop     ax                      ; Load char/attr to write
  1382. ;;
  1383. ;;  ES:DI : Current read/write address
  1384. ;;  AX : Char/attr to write
  1385. ;;  BX : Start address for current line
  1386. ;;  CX : Scratch line length
  1387. ;;  DX : cxLineLen * 2
  1388. ;;  SI : # of lines left to process
  1389. ;;  BP : Length of line to write
  1390. ;;
  1391.         even
  1392.     vfbLoop:
  1393.         dec     si                      ; Decrement LinesLeftToDo
  1394.  
  1395.         rep stosw                       ; Write the line
  1396.  
  1397.         or      si, si                  ; Any more lines to do?
  1398.         jz      vfbEnd2
  1399.         add     bx, dx                  ; Advance to next line
  1400.         mov     cx, bp                  ; Reset line length
  1401.         mov     di, bx                  ; Set r/w address to start of next line
  1402.         jmp     SHORT vfbLoop
  1403.  
  1404.     vfbEnd2:
  1405. IFDEF MOUSE_SUPPORT
  1406.     ;; If mouse may have been overwritten, then redisplay it
  1407.         cmp     BYTE PTR fUpdateMouse, 00h
  1408.         jz      vfbEnd
  1409.         call    MouseShow
  1410. ENDIF
  1411.     vfbEnd:
  1412.         pop     bp
  1413.         ret
  1414. VidFillBlock   ENDP
  1415.  
  1416.  
  1417.  
  1418. IFDEF QHELP
  1419.   ;; Don't include it!
  1420. ELSEIFDEF QEDIT
  1421.   ;; Don't include it!
  1422. ELSE
  1423. ;/*****************************************************************************
  1424. ;*      VidInvert() - Inverts a block on screen
  1425. ;*
  1426. ;*      Entry
  1427. ;*          RECT pRect : block to invert
  1428. ;*      Exit
  1429. ;*          None.
  1430. ;*****************************************************************************/
  1431. VidInvert       PROC    USES si di,     pr:WORD
  1432.         push    bp
  1433.         mov     bx, pr
  1434.         call    SetupBlock
  1435. ;;
  1436. ;;  ES:DI : Current read/write address
  1437. ;;  AL : Char to write
  1438. ;;  AH : Attr to write
  1439. ;;  BX : Start address for current line
  1440. ;;  CX : Scratch line length
  1441. ;;  DX : cxLineLen * 2
  1442. ;;  SI : # of lines left to process
  1443. ;;  BP : Length of line to write
  1444. ;;
  1445.         even
  1446.     viLoop:
  1447.         mov     ax, es:[di]             ; Load attr/char
  1448.         dec     cx
  1449.  
  1450.     ;; Invert it by swapping foreground/background attributes
  1451.         rol     ah, 4                   ; Swap fg/bg attributes.
  1452.  
  1453.         and     ah, 7Fh                 ; Make sure no blinking background
  1454.         stosw                           ; Store it back
  1455.         or      cx, cx
  1456.         jnz     viLoop
  1457.  
  1458.         dec     si                      ; Decrement LinesLeftToDo
  1459.         or      si, si                  ; Any more lines to do?
  1460.         jz      viEnd2
  1461.         add     bx, dx                  ; Advance to next line
  1462.         mov     cx, bp                  ; Reset line length
  1463.         mov     di, bx                  ; Set r/w address to start of next line
  1464.         jmp     SHORT viLoop
  1465.  
  1466.     viEnd2:
  1467. IFDEF MOUSE_SUPPORT
  1468.     ;; If mouse may have been overwritten, then redisplay it
  1469.         cmp     BYTE PTR fUpdateMouse, 00h
  1470.         jz      viEnd
  1471.         call    MouseShow
  1472. ENDIF
  1473.     viEnd:
  1474.         pop     bp
  1475.         ret
  1476. VidInvert       ENDP
  1477. ENDIF
  1478.  
  1479.  
  1480.  
  1481. ;/*****************************************************************************
  1482. ;*      VidSetAttr() - Sets attributes in a block, allowing shadow effects.
  1483. ;*
  1484. ;*      Entry
  1485. ;*          RECT pRect : block to shadow
  1486. ;*          char attr  : attribute to fill with
  1487. ;*      Exit
  1488. ;*          None.
  1489. ;*****************************************************************************/
  1490. VidSetAttr      PROC    USES si di,     pr:WORD, attrib:BYTE
  1491.         push    bp
  1492.         mov     bx, pr
  1493.         xor     ax, ax
  1494.         mov     ah, attrib
  1495.         push    ax
  1496.         call    SetupBlock
  1497.         pop     ax
  1498. ;;
  1499. ;;  ES:DI : Current read/write address
  1500. ;;  AL : Current char
  1501. ;;  AH : New attribute
  1502. ;;  BX : Start address for current line
  1503. ;;  CX : Scratch line length
  1504. ;;  DX : cxLineLen * 2
  1505. ;;  SI : # of lines left to process
  1506. ;;  BP : Length of line to write
  1507. ;;
  1508.         even
  1509.     vsLoop:
  1510.         mov     al, es:[di]             ; Load char
  1511.         dec     cx
  1512.         stosw                           ; Store it back, along with new attr
  1513.         or      cx, cx
  1514.         jnz     vsLoop
  1515.  
  1516.         dec     si                      ; Decrement LinesLeftToDo
  1517.         or      si, si                  ; Any more lines to do?
  1518.         jz      vsEnd2
  1519.         add     bx, dx                  ; Advance to next line
  1520.         mov     cx, bp                  ; Reset line length
  1521.         mov     di, bx                  ; Set r/w address to start of next line
  1522.         jmp     SHORT vsLoop
  1523.  
  1524.     vsEnd2:
  1525. IFDEF MOUSE_SUPPORT
  1526.     ;; If mouse may have been overwritten, then redisplay it
  1527.         cmp     BYTE PTR fUpdateMouse, 00h
  1528.         jz      vsEnd
  1529.         call    MouseShow
  1530. ENDIF
  1531.     vsEnd:
  1532.         pop     bp
  1533.         ret
  1534. VidSetAttr      ENDP
  1535.  
  1536.  
  1537.  
  1538.  
  1539. ;/*****************************************************************************
  1540. ;*      VidGetBlockSize() - Calculates buf size needed to save screen region
  1541. ;*
  1542. ;*      Params
  1543. ;*          RECT *pr : Ptr to RECT containing block to save.
  1544. ;*      Return
  1545. ;*          Buffer size in bytes, or 0 if error.
  1546. ;*****************************************************************************/
  1547. VidGetBlockSize    PROC    pr:WORD
  1548.         mov     bx, pr
  1549.  
  1550.     ;; Calculate buffer size needed
  1551.         mov     ax, [bx].RECT.bottom    ; #of lines   = Bottom - Top
  1552.         sub     ax, [bx].RECT.top
  1553.         mov     dx, [bx].RECT.right     ; #of cols    = Right - Left
  1554.         sub     dx, [bx].RECT.left
  1555.         mul     dl                      ; total chars = #of lines * #of cols
  1556.         shl     ax, 1                   ; Change units from chars to bytes
  1557.         add     ax, SIZEOF BLOCK        ; Add header size to buffer size
  1558.     vgbsExit1:
  1559.         ret
  1560. VidGetBlockSize    ENDP
  1561.  
  1562.  
  1563.  
  1564. ;/*****************************************************************************
  1565. ;*      VidSaveBlock() - Saves part of screen to memory
  1566. ;*
  1567. ;*      Params
  1568. ;*          RECT *pr   : Ptr to RECT containing block to save.
  1569. ;*          void *pBuf : Buffer to save screen region into
  1570. ;*      Return
  1571. ;*          None.
  1572. ;*****************************************************************************/
  1573. ;*  The saved block buffer has the following format :
  1574. ;*
  1575. ;*      Header:
  1576. ;*          uint Screen offset of start of first line
  1577. ;*          uint Block line length in chars
  1578. ;*          uint Number of lines in block
  1579. ;*      Data:
  1580. ;*          Block bytes in row-major order.  Both the chars and attrs are
  1581. ;*          saved (BYTE char, BYTE attr)
  1582. ;*
  1583. ;*****************************************************************************
  1584. VidSaveBlock    PROC    USES si di,     pr:WORD, pBuf:WORD
  1585.         mov     bx, pr
  1586.         call    CheckMouse
  1587.     ;;
  1588.     ;;  AX : Start of first screen line
  1589.     ;;  BX : Length in bytes of full-screen line
  1590.     ;;  DX : Number of lines left to copy
  1591.     ;;  BP : Saved line length
  1592.     ;;
  1593.     ;;  CX : Scratch line length
  1594.     ;;  SI : Src offset
  1595.     ;;  DI : Dst offset
  1596.     ;;  DS : Src seg
  1597.     ;;  ES : Dst seg
  1598.     ;;
  1599.         mov     dx, [bx].RECT.bottom    ; Calculate number of lines to copy
  1600.         mov     ax, [bx].RECT.top
  1601.         sub     dx, ax
  1602.  
  1603.         mov     di, [bx].RECT.left      ; Calculate start of first screen line
  1604.         mul     BYTE PTR vinfo.cols
  1605.         add     ax, di
  1606.         shl     ax, 1                   ; Convert from chars to bytes
  1607.         mov     si, ax                  ; Set up source start
  1608.  
  1609.         mov     cx, [bx].RECT.right     ; Calculate line length
  1610.         sub     cx, di                  ; Right - Left
  1611.  
  1612.     ;; Initialize the buffer header
  1613.         mov     bx, pBuf                ; Load save-buffer address
  1614.         mov     [bx].BLOCK.voffset, ax  ; Base offset of region in video page
  1615.         mov     [bx].BLOCK.ccols, cx    ; # of columns in region
  1616.         mov     [bx].BLOCK.clines, dx   ; # of rows in region
  1617.  
  1618.     ;; Set up registers for copy.  No local vars can be accessed after this
  1619.     ;; point!
  1620.         push    bp
  1621.         cld
  1622.         mov     bp, cx                  ; Save line length
  1623.         mov     di, bx
  1624.         add     di, SIZEOF BLOCK        ; Advance past header to data field
  1625.         mov     bx, ds                  ; ES gets data seg (destination)
  1626.         mov     es, bx
  1627.         xor     bh, bh                  ; Calculate full-screen line length
  1628.         mov     bl, vinfo.cols
  1629.         shl     bx, 1
  1630.         mov     ds, vinfo.sgmnt         ; DS gets source seg
  1631.  
  1632.         even
  1633.     ;; Copy the lines
  1634.     vsbLoop:
  1635.         dec     dx                      ; Decrement lines-left counter
  1636.         rep movsw                       ; Copy a line
  1637.         or      dx, dx                  ; More lines to copy?
  1638.         jz      vsbEnd1                 ; If not, exit.
  1639.         add     ax, bx                  ; Advance to next screen line
  1640.         mov     cx, bp                  ; Reset line length
  1641.         mov     si, ax
  1642.         jmp     short vsbLoop
  1643.  
  1644.     vsbEnd1:
  1645.         mov     ax, es                  ; Restore DS
  1646.         mov     ds, ax
  1647.         pop     bp
  1648. IFDEF MOUSE_SUPPORT
  1649.     ;; If mouse may have been overwritten, then redisplay it
  1650.         cmp     BYTE PTR fUpdateMouse, 00h
  1651.         jz      vsbEnd2
  1652.         call    MouseShow
  1653. ENDIF
  1654.     vsbEnd2:
  1655.         ret
  1656. VidSaveBlock    ENDP
  1657.  
  1658.  
  1659.  
  1660. ;/*****************************************************************************
  1661. ;*      VidRestoreBlock() - Restores screen block from memory
  1662. ;*
  1663. ;*      Params
  1664. ;*          HBLOCK pb : Block to restore
  1665. ;*      Return
  1666. ;*          None.
  1667. ;*      Notes
  1668. ;*          The block must have been previously saved with VidSaveBlock().
  1669. ;*          VidRestoreBlock() does NOT free the block buffer.
  1670. ;*****************************************************************************/
  1671. VidRestoreBlock   PROC   USES si di,    pb:WORD
  1672.     ;;
  1673.     ;;  AX : Saved line length
  1674.     ;;  BX : Full-screen line length
  1675.     ;;  DX : Number of lines left to copy
  1676.     ;;  BP : Line starting address
  1677.     ;;
  1678.     ;;  CX : Scratch line length
  1679.     ;;  SI : Src offset
  1680.     ;;  DI : Dst offset
  1681.     ;;  DS : Src seg
  1682.     ;;  ES : Dst seg
  1683.     ;;
  1684. IFDEF MOUSE_SUPPORT
  1685.         call    MouseHide
  1686. ENDIF
  1687.         push    bp
  1688.         mov     bx, pb
  1689.  
  1690.     ;; Read buffer header and set up registers for copy
  1691.         mov     si, bx                  ; Advance SI to data field
  1692.         add     si, SIZEOF BLOCK
  1693.         mov     di, [bx].BLOCK.voffset  ; Load screen starting address
  1694.         mov     bp, di                  ; Save it
  1695.         mov     cx, [bx].BLOCK.ccols    ; Load line length
  1696.         mov     ax, cx                  ; Save it
  1697.         mov     dx, [bx].BLOCK.clines   ; Load number of lines in block
  1698.         xor     bh, bh
  1699.         mov     bl, vinfo.cols          ; Calculate full-screen line length
  1700.         shl     bx, 1
  1701.         mov     es, vinfo.sgmnt
  1702.         cld
  1703.         even
  1704.     ;; Copy the lines
  1705.     vrbLoop:
  1706.         dec     dx                      ; Decrement lines-left counter
  1707.         rep     movsw                   ; Copy a line
  1708.         or      dx, dx                  ; Any more lines to copy?
  1709.         jz      vrbEnd1                 ; If not, exit.
  1710.         mov     cx, ax                  ; Reset line length
  1711.         add     bp, bx                  ; Advance to next line
  1712.         mov     di, bp
  1713.         jmp     SHORT vrbLoop
  1714.  
  1715.     vrbEnd1:
  1716.         pop     bp
  1717. IFDEF MOUSE_SUPPORT
  1718.         call    MouseShow
  1719. ENDIF
  1720.         ret
  1721. VidRestoreBlock   ENDP
  1722.  
  1723.  
  1724.  
  1725.  
  1726. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1727. ;;  SetupScroll() - Internal function.
  1728. ;;
  1729. ;;  Params
  1730. ;;      AX : delta
  1731. ;;      BX : Ptr to RECT
  1732. ;;  Returns
  1733. ;;      AX : cbLine
  1734. ;;      DI : cbDelta
  1735. ;;      BX : Ptr to RECT
  1736. ;;      CX : #of chars in line
  1737. ;;      DX : #of lines to move
  1738. ;;      SI : rect.left
  1739. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1740. SetupScroll:
  1741.         mov     dx, [bx].RECT.left
  1742.         mov     cx, [bx].RECT.right
  1743.         sub     cx, dx                  ; Calculate line length
  1744.  
  1745.         mov     si, dx                  ; Save rect.left temporarily
  1746.         mov     dx, [bx].RECT.bottom    ; Calculate number of lines to move
  1747.         sub     dx, [bx].RECT.top
  1748.  
  1749.         sub     dx, ax
  1750.  
  1751.         mul     BYTE PTR vinfo.cols     ; Calculate distance from dest to src
  1752.         shl     ax, 1
  1753.         mov     di, ax
  1754.  
  1755.         xor     ax, ax                  ; Precalculate full-screen line length
  1756.         mov     al, vinfo.cols
  1757.         shl     ax, 1
  1758.  
  1759.         mov     es, vinfo.sgmnt         ; Load seg registers
  1760.         ret
  1761.  
  1762.  
  1763.  
  1764. ;/*****************************************************************************
  1765. ;*      VidScrollDown() - scrolls screen down N lines
  1766. ;*
  1767. ;*      Params
  1768. ;*          RECT *pr   : Block to scroll
  1769. ;*          uint delta : #of lines to scroll
  1770. ;*      Return
  1771. ;*          None.
  1772. ;*****************************************************************************/
  1773. VidScrollDown   PROC    USES si di,
  1774.                         pr:WORD, delta:WORD
  1775.                         LOCAL cbDelta:WORD, cbLine:WORD
  1776.         mov     bx, pr
  1777.         call    CheckMouse
  1778.         ; RECT containing new coords returned in BX
  1779.  
  1780.         mov     ax, delta
  1781.         call    SetupScroll
  1782.  
  1783.         mov     cbDelta, di
  1784.         mov     cbLine, ax
  1785.  
  1786.         mov     ax, [bx].RECT.top
  1787.         mul     BYTE PTR vinfo.cols     ; Calculate starting line start
  1788.         add     ax, si
  1789.         shl     ax, 1
  1790.         mov     di, ax
  1791.  
  1792.         mov     si, ax                  ; Calculate src start
  1793.         add     si, cbDelta
  1794.  
  1795.         mov     bx, di                  ; Save line start
  1796.         mov     ax, cx                  ; Save line length
  1797.         push    ds                      ; Save DS
  1798.         mov     ds, vinfo.sgmnt
  1799.         cld
  1800. ;;
  1801. ;;  AX : Line length (in chars)
  1802. ;;  BX : Current line start
  1803. ;;  CX : Scratch line length
  1804. ;;  DX : Number of lines left to process
  1805. ;;  SI : Source
  1806. ;;  DI : Dest
  1807. ;;  cxLine  : #of bytes in screen line
  1808. ;;  cbDelta : Distance from dest to src
  1809. ;;
  1810.         even
  1811.     vsdLoop1:
  1812.         dec     dx                      ; Decrement lines-left counter
  1813.         rep     movsw
  1814.         add     bx, cbLine              ; Advance to next line
  1815.         mov     di, bx
  1816.         mov     si, bx
  1817.         add     si, cbDelta
  1818.         mov     cx, ax                  ; Reset line length
  1819.         or      dx, dx                  ; More lines to copy?
  1820.         jz      vsdDone1
  1821.         jmp     short vsdLoop1
  1822.  
  1823. ;;
  1824. ;; Now clear the last lines
  1825. ;;
  1826.     vsdDone1:
  1827.         pop     ds                      ; Restore DS
  1828.         mov     si, ax                  ; SI just opened up, give it LineLength
  1829.         mov     ah, attr                ; Load Space char/attr
  1830.         mov     al, SPACE
  1831.         mov     dx, delta               ; #of lines to clear
  1832. ;;
  1833. ;;  AX : Attr:Space
  1834. ;;  BX : Current line start
  1835. ;;  CX : Scratch line length
  1836. ;;  DX : Number of lines left to clear
  1837. ;;  SI : Line length (in chars)
  1838. ;;  DI : Dest
  1839. ;;  cbLine : #of bytes in screen line
  1840. ;;
  1841.     vsdLoop2:
  1842.         mov     di, bx                  ; DI = start of current line
  1843.         mov     cx, si                  ; Reset line length
  1844.         dec     dx                      ; Decrement lines-left counter
  1845.         rep     stosw
  1846.         or      dx, dx                  ; More lines to clear?
  1847.         jz      vsdExit2
  1848.         add     bx, cbLine              ; Advance to next line
  1849.         mov     di, bx
  1850.         jmp     short vsdLoop2
  1851.  
  1852.     vsdExit2:
  1853. IFDEF MOUSE_SUPPORT
  1854.     ;; If mouse may have been overwritten, then redisplay it
  1855.         cmp     BYTE PTR fUpdateMouse, 00h
  1856.         jz      vsdExit1
  1857.         call    MouseShow
  1858. ENDIF
  1859.     vsdExit1:
  1860.         ret
  1861. VidScrollDown   ENDP
  1862.  
  1863.  
  1864.  
  1865. ;/*****************************************************************************
  1866. ;*      VidScrollUp() - scrolls screen up N lines
  1867. ;*
  1868. ;*      Params
  1869. ;*          RECT *pr   : Block to scroll
  1870. ;*          uint delta : #of lines to scroll
  1871. ;*      Return
  1872. ;*          None.
  1873. ;*****************************************************************************/
  1874. VidScrollUp     PROC    USES si di,
  1875.                         pr:WORD, delta:WORD
  1876.                         LOCAL cbDelta:WORD, cbLine:WORD
  1877.         mov     bx, pr
  1878.         call    CheckMouse
  1879.         ; RECT containing new coords returned in BX
  1880.  
  1881.         mov     ax, delta
  1882.         call    SetupScroll
  1883.  
  1884.         mov     cbDelta, di
  1885.         mov     cbLine, ax
  1886.  
  1887.         mov     ax, [bx].RECT.top       ; Calculate addr of 1st line to move
  1888.         add     ax, dx                  ; rect.top + # lines to move = 1st line
  1889.         dec     ax
  1890.         mul     BYTE PTR vinfo.cols     ; * #of cols = start of line (in chars)
  1891.         add     ax, si                  ; + rect.left
  1892.         shl     ax, 1                   ; Convert from chars to bytes
  1893.         mov     si, ax
  1894.  
  1895.         mov     di, ax                  ; Calculate dest start
  1896.         add     di, cbDelta             ; SrcStart + cbDelta = DestStart
  1897.         mov     bx, di                  ; And save it to BX too
  1898.  
  1899.         mov     ax, cx                  ; Save line length
  1900.         push    ds                      ; Save DS
  1901.         mov     ds, vinfo.sgmnt
  1902.         cld
  1903. ;;
  1904. ;;  AX : Line length (in chars)
  1905. ;;  BX : Current line start
  1906. ;;  CX : Scratch line length
  1907. ;;  DX : Number of lines left to process
  1908. ;;  SI : Source
  1909. ;;  DI : Dest
  1910. ;;  cxLine  : #of bytes in screen line
  1911. ;;  cbDelta : Distance from dest to src
  1912. ;;
  1913.         even
  1914.     vsuLoop1:
  1915.         dec     dx                      ; Decrement lines-left counter
  1916.         rep     movsw
  1917.         sub     bx, cbLine              ; Advance to next (previous) line
  1918.         mov     si, bx
  1919.         mov     di, bx
  1920.         sub     si, cbDelta
  1921.         mov     cx, ax                  ; Reset line length
  1922.         or      dx, dx                  ; More lines to copy?
  1923.         jz      vsuDone1
  1924.         jmp     short vsuLoop1
  1925.  
  1926. ;;
  1927. ;; Now clear the last lines
  1928. ;;
  1929.     vsuDone1:
  1930.         pop     ds                      ; Restore DS
  1931.         mov     si, ax                  ; SI just opened up, give it LineLength
  1932.         mov     ah, attr                ; Load Space char/attr
  1933.         mov     al, SPACE
  1934.         mov     dx, delta               ; #of lines to clear
  1935. ;;
  1936. ;;  AX : Attr:Space
  1937. ;;  BX : Current line start
  1938. ;;  CX : Scratch line length
  1939. ;;  DX : Number of lines left to clear
  1940. ;;  SI : Line length (in chars)
  1941. ;;  DI : Dest
  1942. ;;  cbLine : #of bytes in screen line
  1943. ;;
  1944.     vsuLoop2:
  1945.         mov     di, bx                  ; DI = start of current line
  1946.         mov     cx, si                  ; Reset line length
  1947.         dec     dx                      ; Decrement lines-left counter
  1948.         rep     stosw
  1949.         or      dx, dx                  ; More lines to clear?
  1950.         jz      vsuExit2
  1951.         sub     bx, cbLine              ; Advance to next (previous) line
  1952.         mov     di, bx
  1953.         jmp     short vsuLoop2
  1954.  
  1955.     vsuExit2:
  1956. IFDEF MOUSE_SUPPORT
  1957.     ;; If mouse may have been overwritten, then redisplay it
  1958.         cmp     BYTE PTR fUpdateMouse, 00h
  1959.         jz      vsuExit1
  1960.         call    MouseShow
  1961. ENDIF
  1962.     vsuExit1:
  1963.         ret
  1964. VidScrollUp     ENDP
  1965.  
  1966.  
  1967.  
  1968. ;/*****************************************************************************
  1969. ;*      Beep() - Beeps the speaker
  1970. ;*
  1971. ;*      Params
  1972. ;*          None
  1973. ;*      Return
  1974. ;*          None.
  1975. ;*****************************************************************************/
  1976. Beep    PROC
  1977.         mov     ax, 0E07h
  1978.         mov     bh, vinfo.dpage
  1979.         mov     bl, 0
  1980.         call    VideoBios
  1981.         ret
  1982. Beep    ENDP
  1983.  
  1984.  
  1985.  
  1986.  
  1987.  
  1988. END
Add Comment
Please, Sign In to add comment