home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / c / pcw_c.zip / PCTSCRN.ASM < prev    next >
Assembly Source File  |  1991-12-16  |  30KB  |  591 lines

  1.               Title Tscrn.Asm
  2.               Page ,120
  3. ;****************************************************************
  4. ;* File Id.                       Pctscrn.Asm                   *
  5. ;* Author.                        Stan Milam.                   *
  6. ;* Date Written.                  11/03/88.                     *
  7. ;* Date Last Modified.            11/03/88.                     *
  8. ;*                                                              *
  9. ;*            (c) Copyright 1989, 1990 by Stan Milam            *
  10. ;*                                                              *
  11. ;* Modifications:  This file was modified to work with Power C. *
  12. ;* Powerc does not prefix global symbols with the underscore (_)*
  13. ;* and to retrieve parameters off of the stack.                 *
  14. ;* Also, the save screen function had to be modified to make    *
  15. ;* sure that ES has the same value as DS upon entry. Otherwise, *
  16. ;* you are saving the screen to something pointed to by ES:DI.  *
  17. ;*                                                              *
  18. ;* Comments: This file is represents a group of Assembler       *
  19. ;* routines designed to make screen handling in C more powerful.*
  20. ;* Featured routines for screen save & restore, quick screen    *
  21. ;* writes with color.                                           *
  22. ;*                                                              *
  23. ;* NOTE: This file is assembled with Micorsoft MASM 5.10, but   *
  24. ;* can be assembled using Borland's Turbo C.                    *
  25. ;****************************************************************
  26. ;
  27. SyncCntl      Equ       200
  28. True          Equ       1
  29. False         Equ       0
  30. MaxMove       Equ       2000
  31.  
  32.               Dosseg                        ;Use standard segmentation
  33.               .Model Huge
  34.  
  35.               .Data
  36.               Extrn     CheckSnow:Word
  37.               Extrn     Vbump:Word
  38.               .Code
  39.               Page
  40. ;
  41. ;****************************************************************
  42. ;*                            Tputchar                          *
  43. ;*                                                              *
  44. ;* This routine will write a character to the screen with a     *
  45. ;* color attribute at the specified row, col                    *
  46. ;*                                                              *
  47. ;* Uses:    Sync_Wait                                           *
  48. ;* Prototype:                                                   *
  49. ;*  void Tputchar(int far *scrnptr, int attrchar);              *
  50. ;****************************************************************
  51. ;
  52.               Public    Tputchar
  53. Tputchar      Proc      Far
  54.               Push      Bp
  55.               Mov       Bp,Sp
  56.               Push      Di
  57.               Push      Es
  58.               Push      Ax
  59.               Mov       Ax,[Bp + 10]        ;Put attribut & character in Ax
  60.               Les       Di,[Bp + 6]         ;Get Screen pointer
  61.               Cmp       [CheckSnow],True
  62.               Jne       Putchar
  63.               Call      Sync_Wait
  64. Putchar:
  65.               Stosw                         ;Put the attr & char in video
  66.               Pop       Ax
  67.               Pop       Es
  68.               Pop       Di
  69.               Pop       Bp
  70.               Ret
  71. Tputchar      Endp
  72.               Page
  73. ;
  74. ;****************************************************************
  75. ;*                             Tputs                            *
  76. ;*                                                              *
  77. ;* This routine will be used to write character strings into    *
  78. ;* video memory with color attribute.  It will return the number*
  79. ;* characters written.                                          *
  80. ;*                                                              *
  81. ;* Prototype:                                                   *
  82. ;* int Tputs(far *Sptr, char far *strptr, int attr)             *
  83. ;****************************************************************
  84. ;
  85.               Public    Tputs               ;Make function global
  86. Tputs         Proc      Far
  87.               Push      Bp
  88.               Mov       Bp,Sp
  89.               Push      Si
  90.               Push      Di
  91.               Push      Es                  ;Save Es
  92.               Push      Cx                  ;Save Cx
  93.               Xor       Cx,Cx               ;Clear Cx
  94.               Mov       Ax,[Bp + 14]        ;Get color attribute
  95.               Lds       Si,[Bp + 10]        ;Get string pointer
  96.               Les       Di,[Bp + 6]         ;point to screen memory ES:DI
  97.               Cmp       [CheckSnow],True    ;Need to wait for vertical sync?
  98.               Jne       Twrite              ;No - proceed
  99.               Call      Sync_Wait           ;Yes - so wait
  100. Twrite:       Lodsb                         ;Get character from string
  101.               Or        Al,Al               ;Is it a '\0'?
  102.               Jz        Exit                ;Yes - we are done
  103.               Stosw                         ;Else put attr & char in video
  104.               Inc       Cx                  ;Add 1 to our count
  105.               Jmp       Twrite              ;And do it all again
  106. Exit:
  107.               Mov       Ax,Cx               ;Return the count
  108.               Pop       Cx                  ;Restore Cx
  109.               Pop       Es                  ;Restore Es
  110.               Pop       Di
  111.               Pop       Si
  112.               Mov       Sp,Bp
  113.               Pop       Bp
  114.               Ret
  115. Tputs         Endp
  116.               Page
  117. ;
  118. ;****************************************************************
  119. ;*                            Tvputs                            *
  120. ;*                                                              *
  121. ;* This routine will write a string vertically on the screen.   *
  122. ;*                                                              *
  123. ;* Uses:     Sync_Wait                                          *
  124. ;* C Prototype:                                                 *
  125. ;*  Tvputs((int far *) ScrnSeg, (char far *) str, int attr);    *
  126. ;****************************************************************
  127. ;
  128.               Public    Tvputs
  129. Tvputs        Proc      Far
  130.               Push      Bp                  ;Save Bp
  131.               Mov       Bp,Sp               ;Set up the stack frame
  132.               Push      Es                  ;
  133.               Push      Ds                  ;
  134.               Push      Si                  ;
  135.               Push      Di                  ;
  136.               Push      Ax                  ;
  137.               Push      Bx                  ;
  138.               Push      Dx                  ;
  139.               Mov       Bx,[CheckSnow]      ;Save CheckSnow in Bx
  140.               Mov       Dx,[Vbump]          ;Save vertical increment
  141.               Les       Di,[Bp + 6]         ;Gets Pointer to Screen Segment
  142.               Lds       Si,[Bp + 10]        ;Get Pointer to String
  143.               Mov       Ax,[Bp + 14]        ;Get Color Attribute in Ax
  144.               Cmp       Bx,True             ;Need to call Sync_Wait?
  145.               Jne       Tvwrite             ;No - proceed
  146.               Call      Sync_Wait           ;Wait for vertical retrace
  147. Tvwrite:                                    ;
  148.               Lodsb                         ;Get Char & Attribute in Ax
  149.               Or        Al,Al               ;Is Char '\0'
  150.               Jz        Tvend               ;Yes - We are done
  151.               Push      Di                  ;Save current column
  152.               Stosw                         ;Write to Screen Memory
  153.               Pop       Di                  ;Restore Column
  154.               Add       Di,Dx               ;Next Column
  155.               Jmp       Tvwrite             ;Go back to do it again
  156. Tvend:                                      ;
  157.               Pop       Dx                  ;
  158.               Pop       Bx                  ;
  159.               Pop       Ax                  ;
  160.               Pop       Di                  ;Restore Registers
  161.               Pop       Si                  ;
  162.               Pop       Ds                  ;
  163.               Pop       Es                  ;
  164.               Mov       Sp,Bp               ;Restore Stack Frame
  165.               Pop       Bp                  ;Restore Bp or Die!
  166.               Ret                           ;Return to C program
  167. Tvputs        Endp
  168.               Page
  169.  
  170. ;
  171. ;****************************************************************
  172. ;*                          SaveScrn                            *
  173. ;*                                                              *
  174. ;* This module will be used to save a specified block of a      *
  175. ;* screen in a character buffer.                                *
  176. ;*                                                              *
  177. ;* Uses Sync_Wait                                               *
  178. ;* Prototype:                                                   *
  179. ;*  int SaveScrn(int rows, int cols, int far *scrnptr, char *ptr*
  180. ;*                                                              *
  181. ;****************************************************************
  182.               Public    SaveScrn
  183. SaveScrn      Proc      Far
  184.               Push      Bp
  185.               Mov       Bp,Sp
  186.               Push      Si                  ;
  187.               Push      Di                  ;
  188.               Push      Ds                  ;Save the Regs!
  189.               Push      Es                  ;
  190.               Push      Ax                  ;
  191.               Push      Bx                  ;
  192.               Push      Cx                  ;
  193.               Push      Dx                  ;
  194. ;
  195.               Xor       Dx,Dx               ;Clear Dx
  196.               Mov       Bx,[CheckSnow]      ;Save Snow indicator
  197.               Mov       Ax,[Vbump]          ;Save vertical increment
  198.               Lds       Si,[Bp + 10]        ;get pointer to screen
  199.               Les       Di,[Bp + 14]        ;pointer to save buffer
  200.               Mov       Cx,[Bp + 6]         ;get number of rows
  201.               Cmp       Bx,True             ;Check for CGA monitor
  202.               Jne       SaveRow             ;Not a CGA so go ahead
  203.               Call      Sync_Wait           ;Otherwise wait for vert sync
  204. SaveRow:
  205.               Push      Cx                  ;Save the Number of rows to go
  206.               Push      Si                  ;Save screen offset
  207.               Mov       Cx,[Bp + 8]         ;get # of cols
  208.               Cmp       Bx,True             ;CGA monitor?
  209.               Jne       Save                ;No - go ahead.
  210.               Cmp       Dx,SyncCntl         ;Ax > SyncCntl?
  211.               Jl        Save                ;Yes - Go Ahead
  212.               Xor       Dx,Dx               ;Else clear Ax
  213.               Call      Sync_Wait           ;and wait for vert sync
  214. Save:
  215.               Add       Dx,Cx               ;Accumulate number of words
  216.               Rep       Movsw               ;Save quickly
  217.               Pop       Si                  ;Pop screen offset
  218.               Add       Si,Ax               ;Bump offset to next screen row
  219.               Pop       Cx                  ;Pop number of rows to go
  220.               Loop      SaveRow             ;Do again if Cx != zero
  221.               Pop       Dx                  ;
  222.               Pop       Cx                  ;
  223.               Pop       Bx                  ;
  224.               Pop       Ax
  225.               Pop       Es                  ;Restore the Regs!
  226.               Pop       Ds                  ;
  227.               Pop       Di                  ;
  228.               Pop       Si                  ;
  229.               Mov       Sp,Bp
  230.               Pop       Bp
  231.               Xor       Ax,Ax               ;Send back zero return code
  232.               Ret
  233. SaveScrn      Endp
  234.               Page
  235. ;
  236. ;****************************************************************
  237. ;*                          RestoreScrn                         *
  238. ;*                                                              *
  239. ;* This routine will restore a previously saved screen.         *
  240. ;*                                                              *
  241. ;* Uses:   Sync_Wait                                            *
  242. ;* ProtoType:                                                   *
  243. ;*   int RestoreScrn(int rows, int cols, int far *sptr, char ch *
  244. ;****************************************************************
  245. ;
  246.               Public    RestoreScrn
  247. RestoreScrn   Proc      Far
  248.               Push      Bp
  249.               Mov       Bp,Sp
  250.               Push      Ds                  ;
  251.               Push      Es                  ;
  252.               Push      Di                  ;
  253.               Push      Si                  ;Save the Regs
  254.               Push      Ax                  ;
  255.               Push      Cx                  ;
  256.               Push      Bx                  ;
  257.               Push      Dx
  258.               Mov       Bx,[CheckSnow]
  259.               Mov       Dx,[Vbump]
  260.               Xor       Ax,Ax               ;Clear Ax 
  261.               Les       Di,[Bp + 10]        ;Get screen pointer
  262.               Lds       Si,[Bp + 14]        ;Get pointer to buffer
  263.               Mov       Cx,[Bp + 6]         ;Get number of Rows
  264.               Cmp       Bx,1                ;Check for CGA
  265.               Jne       RestoreRow
  266.               Call      Sync_Wait           ;Call sync_wait if CGA
  267. RestoreRow:
  268.               Push      Cx                  ;Save the rows to go
  269.               Push      Di                  ;Save screen offset
  270.               Mov       Cx,[Bp + 8]         ;Get number of columns
  271.               Cmp       Bx,1                ;Check for CGA
  272.               Jne       Restore             ;Go around if not
  273.               Cmp       Ax,SyncCntl         ;Is Ax > SyncCntl
  274.               Jl        ReStore             ;Yes: Go Ahead
  275.               Xor       Ax,Ax               ;Zero Ax
  276.               Call      Sync_Wait           ;And Call Sync_Wait
  277. Restore:
  278.               Add       Ax,Cx               ;Add number of cols to Ax
  279.               Rep       Movsw               ;Restore a row on screen
  280.               Pop       Di                  ;Pop screen offset
  281.               Add       Di,Dx               ;Bump offset 1 row
  282.               Pop       Cx                  ;Pop # of rows to go
  283.               Loop      RestoreRow          ;Do again if Cx != 0
  284.               Pop       Dx                  ;
  285.               Pop       Bx                  ;
  286.               Pop       Cx                  ;
  287.               Pop       Ax                  ;
  288.               Pop       Si                  ;Restore Regs!
  289.               Pop       Di                  ;
  290.               Pop       Es                  ;
  291.               Pop       Ds                  ;
  292.               Mov       Sp,Bp
  293.               Pop       Bp
  294.               Xor       Ax,Ax               ;Send 0 return code back
  295.               Ret
  296. RestoreScrn   Endp
  297.               Page
  298. ;
  299. ;****************************************************************
  300. ;*                          TextFill                            *
  301. ;*                                                              *
  302. ;* This routine will define the window by filling the rectan-   *
  303. ;* gular area with a color attribute and spaces.  Needless to   *
  304. ;* say, this is usualy done after the area has been saved away. *
  305. ;*                                                              *
  306. ;* Uses:    Sync_Wait.                                          *
  307. ;* Prototype:                                                   *
  308. ;* void TextFill(int rows, int cols, int far *sptr, int attrchr)*
  309. ;****************************************************************
  310. ;
  311.               Public    TextFill
  312. TextFill      Proc      Far
  313.               Push      Bp                  ;
  314.               Mov       Bp,Sp               ;
  315.               Push      Si                  ;
  316.               Push      Di                  ;
  317.               Push      Ds                  ;
  318.               Push      Es                  ;Save Registers
  319.               Push      Ax                  ;
  320.               Push      Bx                  ;
  321.               Push      Cx                  ;
  322.               Push      Dx                  ;
  323.               Xor       Dx,Dx               ;Clear Dx
  324.               Mov       Bx,[CheckSnow]      ;Save in Bx
  325.               Mov       Si,[Vbump]          ;Save in Si
  326.               Mov       Cx,[Bp + 6]         ;Get # of rows
  327.               Les       Di,[Bp + 10]        ;Get pointer to screen
  328.               Mov       Ax,[Bp + 14]        ;Get color attr & space
  329.               Cmp       Bx,True             ;Is CGA active?
  330.               Jne       Fill                ;No, continue on
  331.               Call      Sync_Wait           ;Yes, wait for vert sync
  332. Fill:
  333.               Push      Cx                  ;Save number of rows to go
  334.               Push      Di                  ;Save screen offset
  335.               Mov       Cx,[Bp + 8]         ;Move in number of columns
  336.               Cmp       Bx,True             ;CGA active?
  337.               Jne       Fill1               ;No so skip
  338.               Cmp       Dx,SyncCntl         ;Dx < SyncCntl?
  339.               Jl        Fill1               ;Yes so skip
  340.               Xor       Dx,Dx               ;Clear Dx
  341.               Call      Sync_Wait           ;Wait for vertical sync
  342. Fill1:
  343.               Add       Dx,Cx               ;Add to count control
  344.               Rep       Stosw               ;Store attr & character in Ax
  345.               Pop       Di                  ;Get offset back
  346.               Add       Di,Si               ;Bump it by 1 screen row
  347.               Pop       Cx                  ;Get number of rows back
  348.               Loop      Fill                ;and repeat until finished
  349.               Pop       Dx                  ;
  350.               Pop       Cx                  ;
  351.               Pop       Bx                  ;
  352.               Pop       Ax                  ;Restore Regs!
  353.               Pop       Es                  ;
  354.               Pop       Ds                  ;
  355.               Pop       Di                  ;
  356.               Pop       Si                  ;
  357.               Mov       Sp,Bp
  358.               Pop       Bp
  359.               Xor       Ax,Ax               ;Return zero return code
  360.               Ret
  361. TextFill      Endp
  362.               Page
  363. ;
  364. ;****************************************************************
  365. ;*                           TvertChar                          *
  366. ;*                                                              *
  367. ;* This function will write a character to the screen repeatedly*
  368. ;* The number of time the character will be written is          *
  369. ;* spcecified by 'count'.                                       *
  370. ;*                                                              *
  371. ;* Prototype:                                                   *
  372. ;*  void Tvertchar(int count, int charattr, int far *scrnptr);  *
  373. ;****************************************************************
  374. ;
  375.               Public    Tvertchar
  376. Tvertchar     Proc      Far
  377.               Push      Bp
  378.               Mov       Bp,Sp
  379.               Push      Ax                  ;
  380.               Push      Cx                  ;Save Regs
  381.               Push      Es                  ;
  382.               Push      Di                  ;
  383.               Mov       Cx,[Bp + 6]         ;Get the count
  384.               Mov       Ax,[Bp + 8]         ;Get char & attribute
  385.               Les       Di,[Bp + 10]        ;Pointer to screen memory
  386.               Cmp       [CheckSnow],True    ;Is CheckSnow True?
  387.               Jne       VertLoop            ;No - go right to it
  388.               Call      Sync_Wait           ;Wait for Vert Sync
  389. VertLoop:
  390.               Push      Di                  ;Save screen offset
  391.               Stosw                         ;Put the character to memory
  392.               Pop       Di                  ;Return the segment
  393.               Add       Di,[Vbump]          ;Bump to next row
  394.               Loop      VertLoop            ;Do it again
  395.               Pop       Di                  ;
  396.               Pop       Es                  ;
  397.               Pop       Cx                  ;Restore Registers
  398.               Pop       Ax                  ;
  399.               Mov       Sp,Bp               ;
  400.               Pop       Bp                  ;
  401.               Ret
  402. Tvertchar     Endp
  403.               Page
  404. ;
  405. ;****************************************************************
  406. ;*                          Thorzchar                           *
  407. ;*                                                              *
  408. ;* This routine will repeatedly write a character horizontally  *
  409. ;* across the screen.  The number of times the character is     *
  410. ;* is written is determined by the count in Cx.                 *
  411. ;* Prototype:                                                   *
  412. ;*   void Thorzchar(int count, int chrattr, int far *scrnptr)   * 
  413. ;****************************************************************
  414. ;
  415.               Public    Thorzchar
  416. Thorzchar     Proc      Far
  417.               Push      Bp                  ;
  418.               Mov       Bp,Sp               ;
  419.               Push      Ax                  ;
  420.               Push      Cx                  ;Save Registers
  421.               Push      Di                  ;
  422.               Push      Es                  ;
  423.               Mov       Cx,[Bp + 6]         ;Get the count
  424.               Mov       Ax,[Bp + 8]         ;Get character & attribute
  425.               Les       Di,[Bp + 10]        ;Get pointer to screen mem
  426.               Cmp       [CheckSnow],True    ;Is it a CGA?
  427.               Jne       HorzLoop            ;No!
  428.               Call      Sync_Wait           ;Yes - Wait for vert sync
  429. HorzLoop:
  430.               Rep       Stosw               ;Continually write char
  431.               Pop       Es                  ;Restore Registers
  432.               Pop       Di                  ;
  433.               Pop       Cx                  ;
  434.               Pop       Ax                  ;
  435.               Pop       Bp                  ;
  436.               Ret                           ;Return to calling C pgm
  437. Thorzchar     Endp
  438.               Page
  439. ;
  440. ;****************************************************************
  441. ;*                          Tchg_Attr                           *
  442. ;*                                                              *
  443. ;* This function will change the attributes of a specified num- *
  444. ;* ber of columns on the screen.                                *
  445. ;*                                                              *
  446. ;* C Prototype:                                                 *
  447. ;*   Tchg_Attr(int far *scrnptr, int count, int attr);          *
  448. ;****************************************************************
  449. ;
  450.               Public    Tchg_Attr
  451. Tchg_Attr     Proc      Far
  452.               Push      Bp                  ;Set up stack frame
  453.               Mov       Bp,Sp               ;
  454.               Push      Ax                  ;Save registers
  455.               Push      Cx                  ;
  456.               Push      Dx                  ;
  457.               Push      Si                  ;
  458.               Push      Di                  ;
  459.               Push      Ds                  ;
  460.               Push      Es                  ;
  461.               Mov       Dx,[CheckSnow]      ;Save in Dx
  462.               Lds       Si,[Bp + 6]         ;Get Segment/Offset to scrn
  463.               Les       Di,[Bp + 6]         ;Get it again
  464.               Mov       Cx,[Bp + 10]        ;Get number of columns
  465.               Mov       Ax,[Bp + 12]        ;Get Attribute (in Ah)
  466.               Cmp       Dx,True             ;Is it CGA?
  467.               Jne       Tchg                ;No!
  468.               Call      Sync_Wait           ;Yes - wait for vert sync
  469. Tchg:
  470.               Lodsb                         ;Read character from screen
  471.               Inc       Si                  ;Bump past screen attribute
  472.               Stosw                         ;Write char & attr to screen
  473.               Loop      Tchg                ;Do it again
  474.               Pop       Es                  ;Restore Registers
  475.               Pop       Ds                  ;
  476.               Pop       Di                  ;
  477.               Pop       Si                  ;
  478.               Pop       Dx                  ;
  479.               Pop       Cx                  ;
  480.               Pop       Ax                  ;
  481.               Pop       Bp                  ;
  482.               Ret                           ;Return to Calling C Pgm
  483. Tchg_Attr     Endp
  484.               Page
  485. ;*********************************************************************
  486. ;*                             Tscroll                               *
  487. ;*                                                                   *
  488. ;* Low level routine to scroll the video screen up & down.           *
  489. ;*                                                                   *
  490. ;* Tscroll(void far *srce, void far *dest, int row, int col, int dir)*
  491. ;*********************************************************************
  492.  
  493. Source        Equ       [Bp + 6]            ;Source pointer to video memory
  494. Dest          Equ       [Bp +10]            ;And the destination
  495. Rows          Equ       [Bp +14]            ;Number of Rows
  496. Cols          Equ       [Bp +16]            ;Number of Cols
  497. Dir           Equ       [Bp +18]            ;Direction - Up or Down
  498.               Public    Tscroll
  499. Tscroll       Proc      Far
  500.               Push      Bp
  501.               Mov       Bp,Sp               ;Save Stack Frame
  502.               Push      Ax                  ;Save All Registers Used
  503.               Push      Bx
  504.               Push      Cx
  505.               Push      Dx
  506.               Push      Di
  507.               Push      Si
  508.               Push      Ds
  509.               Push      Es
  510.               Pushf                         ;Save flags - we change direction
  511.               Xor       Dx,Dx               ;Clear Accumulator
  512.               Mov       Bx,[CheckSnow]      ;Save before changing Ds
  513.               Mov       Bh,Bl               ;Put in Bh
  514.               Mov       Ax,Dir              ;Get Direction Flag
  515.               Mov       Bl,Al               ;Save it in Bl
  516.               Mov       Ax,[Vbump]          ;Save before Changing Ds
  517.               Lds       Si,Source           ;Get source pointer off of stack
  518.               Les       Di,Dest             ;Get Destination pointer
  519.               Mov       Cx,Rows             ;Get The number of Rows
  520.               Cld                           ;Set direction flag forward
  521.               Cmp       Bh,1                ;Is monitor a CGA?
  522.               Jne       Scroll_Line         ;No
  523.               Call      Sync_Wait           ;Yes wait for vertical sync
  524. Scroll_Line:
  525.               Push      Si                  ;Save pointers
  526.               Push      Di                  ;
  527.               Push      Cx                  ;Save Number of Rows to go
  528.               Mov       Cx,Cols             ;Get number of columns to save
  529.               Cmp       Bh,1                ;Do we have a CGA?
  530.               Jne       Moveit              ;No just save
  531.               Add       Dx,Cx               ;Accumulate number of bytes saved
  532.               Cmp       Dx,SyncCntl         ;Have we saved all we can?
  533.               Jl        Moveit              ;No continue onward and downward
  534.               Xor       Dx,Dx               ;Clear accumulator
  535.               Call      Sync_Wait           ;Wait for vertical retrace
  536. Moveit:       Rep       Movsw               ;Save a Row
  537.               Pop       Cx                  ;Restore row count
  538.               Pop       Di                  ;Restore Screen pointers
  539.               Pop       Si
  540.               Cmp       Bl,0                ;Going Down?
  541.               Jne       Adjust_Up           ;No 
  542.               Sub       Si,Ax               ;Mov Pointer up
  543.               Sub       Di,Ax               ;
  544.               Loop      Scroll_Line         ;Scroll one more line
  545.               Jmp       Scroll_Exit         ;Exit when done
  546. Adjust_Up:
  547.               Add       Si,Ax               ;Move pointers to next row
  548.               Add       Di,Ax               ;
  549.               Loop      Scroll_Line         ;Scroll one more line
  550. Scroll_Exit:  Popf                          ;Retore all saved registers
  551.               Pop       Es                  ;
  552.               Pop       Ds                  ;
  553.               Pop       Si                  ;
  554.               Pop       Di                  ;Restore Regs & Stack
  555.               Pop       Dx                  ;
  556.               Pop       Cx                  ;
  557.               Pop       Bx                  ;
  558.               Pop       Ax                  ;
  559.               Pop       Bp                  ;
  560.               Ret                           ;Return to caller
  561. Tscroll       Endp
  562.               Page
  563. ;
  564. ;****************************************************************
  565. ;*                           Sync_Wait                          *
  566. ;*                                                              *
  567. ;* A useful procedure to wait for the vertical sync of CGA      *
  568. ;* monitors.                                                    *
  569. ;****************************************************************
  570. ;
  571. Sync_Wait     Proc      Near
  572.               Push      Ax
  573.               Push      Dx
  574.               Cli
  575.               Mov       Dx,3DAh
  576. Not_Sync:
  577.               In        Al,Dx
  578.               And       Al,08h
  579.               Jnz       Not_Sync
  580. Sync:
  581.               In        Al,Dx
  582.               And       Al,08h
  583.               Jz        Sync
  584.               Pop       Dx
  585.               Pop       Ax
  586.               Sti
  587.               Ret
  588. Sync_Wait     Endp
  589.               End
  590.  
  591.