home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / misc / window.asm < prev    next >
Assembly Source File  |  1990-04-17  |  21KB  |  612 lines

  1.     Page    58,132
  2.     Title    WINDOW.ASM    Window Routines
  3. ;******************************************************************************
  4. ;
  5. ;   Name:    WINDOW.ASM    Window Routines
  6. ;
  7. ;   Group:    Emulator
  8. ;
  9. ;   Revision:    1.00
  10. ;
  11. ;   Date:    January 30, 1988
  12. ;
  13. ;   Author:    Randy W. Spurlock
  14. ;
  15. ;******************************************************************************
  16. ;
  17. ;  Module Functional Description:
  18. ;
  19. ;        This module contains all the code for the window routines
  20. ;    used by the Apple emulator.
  21. ;
  22. ;******************************************************************************
  23. ;
  24. ;  Changes:
  25. ;
  26. ;    DATE     REVISION                DESCRIPTION
  27. ;  --------   --------    -------------------------------------------------------
  28. ;   1/30/88    1.00    Original
  29. ;
  30. ;******************************************************************************
  31.     Page
  32. ;
  33. ;  Public Declarations
  34. ;
  35.     Public    Scroll_Up        ; Scroll window up routine
  36.     Public    Scroll_Down        ; Scroll window down routine
  37.     Public    Clear_Window        ; Clear window routine
  38.     Public    Save_Window        ; Save window routine
  39.     Public    Restore_Window        ; Restore window routine
  40. ;
  41. ;  External Declarations
  42. ;
  43.     Extrn    Cursor_Off:Near     ; Turn cursor off routine    (VIDEO)
  44.     Extrn    Cursor_On:Near        ; Turn cursor on routine    (VIDEO)
  45.     Extrn    Blink_Off:Near        ; Turn blink off routine    (VIDEO)
  46.     Extrn    Blink_On:Near        ; Turn blink on routine     (VIDEO)
  47.     Extrn    CGA_Restore:Near    ; CGA restore screen routine      (CGA)
  48.     Extrn    EGA_Restore:Near    ; EGA restore screen routine      (EGA)
  49.     Extrn    Current_Fore:Word    ; Current foreground color value  (TTY)
  50.     Extrn    Current_Back:Word    ; Current background color value  (TTY)
  51.     Extrn    System_Flag:Byte    ; Apple emulator system flag byte(DATA)
  52.     Extrn    Video_Flag:Byte     ; Video system flag byte     (DATA)
  53. ;
  54. ;  LOCAL Equates
  55. ;
  56. BACK_SHIFT    Equ    04h        ; Background attribute shift value
  57. MAX_ROW     Equ    19h        ; Maximum row number value (25)
  58. MAX_COLUMN    Equ    28h        ; Maximum column number value (40)
  59. PARA_ROUND    Equ    0Fh        ; Bytes to paragraphs rounding value
  60. PARA_SHIFT    Equ    04h        ; Bytes to paragraphs shift value
  61. VIDEO_MEMORY    Equ    0B800h        ; Start of video memory segment
  62. ;
  63. ;  Define any include files needed
  64. ;
  65.     Include     Macros.inc    ; Include the macro definitions
  66.     Include     Equates.inc    ; Include the equate definitions
  67.     .286c                ; Include 80286 instructions
  68.     Page
  69. ;
  70. ;  Define the emulator code segment
  71. ;
  72. Emulate Segment Word Public 'EMULATE'   ; Emulator code segment
  73.     Assume    cs:Emulate, ds:Nothing, es:Nothing
  74.     Subttl    Scroll_Up    Scroll Window Up Routine
  75.     Page    +
  76. ;******************************************************************************
  77. ;
  78. ;    Scroll_Up(Window, Count)
  79. ;
  80. ;        Save the required registers
  81. ;        If window coordinates are valid
  82. ;            Setup access to video memory
  83. ;            Calculate source and destination rows values
  84. ;            Compute the actual window size
  85. ;            Compute and save the column count
  86. ;            Calculate source and destination addresses
  87. ;            Compute address increment value
  88. ;            Save the address increment value
  89. ;            If scroll count greater than window size
  90. ;                Limit scroll to entire window
  91. ;            Endif
  92. ;            Save the scroll count value
  93. ;            Compute the number of rows to move
  94. ;            While more rows to move
  95. ;                Setup the column count value
  96. ;                While more columns to move
  97. ;                    Move the next column
  98. ;                    Decrement the column count
  99. ;                EndWhile
  100. ;                Update the screen addresses
  101. ;                Decrement the row count
  102. ;            EndWhile
  103. ;            Restore the scroll count value
  104. ;            Setup the clear character (Space)
  105. ;            While more rows to clear
  106. ;                Setup the column count value
  107. ;                While more columns to clear
  108. ;                    Store the clear character (Space)
  109. ;                    Decrement the column count
  110. ;                EndWhile
  111. ;                Update the screen address
  112. ;                Decrement the row count
  113. ;            EndWhile
  114. ;        Endif
  115. ;        Restore the required registers
  116. ;        Return to the caller
  117. ;
  118. ;    Registers on Entry:
  119. ;
  120. ;        AX    - Upper left window row coordinate
  121. ;        BX    - Upper left window column coordinate
  122. ;        CX    - Lower right window row coordinate
  123. ;        DX    - Lower right window column coordinate
  124. ;        BP    - Scroll count (Lines)
  125. ;
  126. ;    Registers on Exit:
  127. ;
  128. ;        None
  129. ;
  130. ;******************************************************************************
  131.         Even            ; Force procedure to even address
  132. Scroll_Up    Proc    Near        ; Scroll window up procedure
  133.     Save    ax,bx,cx,dx,si,di,bp,ds,es
  134.     cmp    ax,cx            ; Check the row coordinate values
  135.     ja    Up_Exit         ; Jump if row coordinates are invalid
  136.     cmp    bx,dx            ; Check column coordinate values
  137.     ja    Up_Exit         ; Jump if column coordinates are invalid
  138.     cmp    ax,MAX_ROW        ; Check upper left row value
  139.     jnc    Up_Exit         ; Jump if invalid row value
  140.     cmp    bx,MAX_COLUMN        ; Check upper left column value
  141.     jnc    Up_Exit         ; Jump if invalid column value
  142.     cmp    cx,MAX_ROW        ; Check lower right row value
  143.     jnc    Up_Exit         ; Jump if invalid row value
  144.     cmp    dx,MAX_COLUMN        ; Check lower right column value
  145.     jnc    Up_Exit         ; Jump if invalid column value
  146.     mov    si,VIDEO_MEMORY     ; Setup access
  147.     mov    ds,si            ;           to video
  148.     mov    es,si            ;            memory
  149.     mov    si,ax            ; Compute the source
  150.     add    si,bp            ;             row number
  151.     mov    di,ax            ; Get the destination row number
  152.     sub    cx,ax            ; Compute the actual
  153.     inc    cx            ;             window size (Rows)
  154.     sub    dx,bx            ; Compute and save
  155.     inc    dx            ;           the column count
  156.     shl    si,4            ; Compute
  157.     mov    ax,si            ;      source
  158.     shl    ax,2            ;         row times
  159.     add    si,ax            ;               eighty
  160.     shl    di,4            ; Compute
  161.     mov    ax,di            ;      destination
  162.     shl    ax,2            ;              times
  163.     add    di,ax            ;                eighty
  164.     shl    bx,1            ; Compute column offset value
  165.     add    si,bx            ; Compute the actual source address
  166.     add    di,bx            ; Compute actual destination address
  167.     mov    bx,MAX_COLUMN        ; Compute and save
  168.     sub    bx,dx            ;           increment value
  169.     cmp    cx,bp            ; Check the scroll count value
  170.     ja    Up_Move         ; Jump if partial window scroll
  171.     mov    bp,cx            ; Limit scroll to entire window
  172. Up_Move:
  173.     Save    bp            ; Save the scroll count value
  174.     sub    cx,bp            ; Compute and save
  175.     mov    bp,cx            ;           the move count
  176.     jz    Up_Clear        ; Jump if entire window scroll
  177. Move_Up_Loop:
  178.     mov    cx,dx            ; Setup the column count value
  179.     rep    movsw            ; Move an entire row
  180.     add    si,bx            ; Update the
  181.     add    di,bx            ;         screen addresses
  182.     dec    bp            ; Decrement the row count value
  183.     jnz    Move_Up_Loop        ; Loop till all rows are moved
  184. Up_Clear:
  185.     Restore bp            ; Restore the row count value
  186.     mov    al,SPACE        ; Setup to write a space character
  187.     mov    ah,Byte Ptr cs:[Current_Back]
  188.     shl    ah,BACK_SHIFT        ; Shift background into position
  189.     or    ah,Byte Ptr cs:[Current_Fore]
  190. Clear_Up_Loop:
  191.     mov    cx,dx            ; Setup the column count value
  192.     rep    stosw            ; Clear an entire row
  193.     add    di,bx            ; Update the screen address
  194.     dec    bp            ; Decrement the row count value
  195.     jnz    Clear_Up_Loop        ; Loop till all rows are cleared
  196. Up_Exit:
  197.     Restore ax,bx,cx,dx,si,di,bp,ds,es
  198.     ret                ; Return to the caller
  199. Scroll_Up    Endp            ; End of the Scroll_Up procedure
  200.     Subttl    Scroll_Down    Scroll Window Down Routine
  201.     Page    +
  202. ;******************************************************************************
  203. ;
  204. ;    Scroll_Down(Window, Count)
  205. ;
  206. ;        Save the required registers
  207. ;        If window coordinates are valid
  208. ;            Setup access to video memory
  209. ;            Calculate source and destination rows values
  210. ;            Compute the actual window size
  211. ;            Compute and save the column count
  212. ;            Calculate source and destination addresses
  213. ;            Compute address decrement value
  214. ;            Save the address decrement value
  215. ;            If scroll count greater than window size
  216. ;                Limit scroll to entire window
  217. ;            Endif
  218. ;            Save the scroll count value
  219. ;            Compute the number of rows to move
  220. ;            While more rows to move
  221. ;                Setup the column count value
  222. ;                While more columns to move
  223. ;                    Move the next column
  224. ;                    Decrement the column count
  225. ;                EndWhile
  226. ;                Update the screen addresses
  227. ;                Decrement the row count
  228. ;            EndWhile
  229. ;            Restore the scroll count value
  230. ;            Setup the clear character (Space)
  231. ;            While more rows to clear
  232. ;                Setup the column count value
  233. ;                While more columns to clear
  234. ;                    Store the clear character (Space)
  235. ;                    Decrement the column count
  236. ;                EndWhile
  237. ;                Update the screen address
  238. ;                Decrement the row count
  239. ;            EndWhile
  240. ;        Endif
  241. ;        Restore the required registers
  242. ;        Return to the caller
  243. ;
  244. ;    Registers on Entry:
  245. ;
  246. ;        AX    - Upper left window row coordinate
  247. ;        BX    - Upper left window column coordinate
  248. ;        CX    - Lower right window row coordinate
  249. ;        DX    - Lower right window column coordinate
  250. ;        BP    - Scroll count (Lines)
  251. ;
  252. ;    Registers on Exit:
  253. ;
  254. ;        None
  255. ;
  256. ;******************************************************************************
  257.         Even            ; Force procedure to even address
  258. Scroll_Down    Proc    Near        ; Scroll window down procedure
  259.     Save    ax,bx,cx,dx,si,di,bp,ds,es
  260.     cmp    ax,cx            ; Check the row coordinate values
  261.     ja    Down_Exit        ; Jump if row coordinates are invalid
  262.     cmp    bx,dx            ; Check column coordinate values
  263.     ja    Down_Exit        ; Jump if column coordinates are invalid
  264.     cmp    ax,MAX_ROW        ; Check upper left row value
  265.     jnc    Down_Exit        ; Jump if invalid row value
  266.     cmp    bx,MAX_COLUMN        ; Check upper left column value
  267.     jnc    Down_Exit        ; Jump if invalid column value
  268.     cmp    cx,MAX_ROW        ; Check lower right row value
  269.     jnc    Down_Exit        ; Jump if invalid row value
  270.     cmp    dx,MAX_COLUMN        ; Check lower right column value
  271.     jnc    Down_Exit        ; Jump if invalid column value
  272.     mov    si,VIDEO_MEMORY     ; Setup access
  273.     mov    ds,si            ;           to video
  274.     mov    es,si            ;            memory
  275.     mov    si,cx            ; Compute the source
  276.     sub    si,bp            ;             row number
  277.     mov    di,cx            ; Get the destination row number
  278.     sub    cx,ax            ; Compute the actual
  279.     inc    cx            ;             window size (Rows)
  280.     sub    dx,bx            ; Compute and save
  281.     inc    dx            ;           the column count
  282.     shl    si,4            ; Compute
  283.     mov    ax,si            ;      source
  284.     shl    ax,2            ;         row times
  285.     add    si,ax            ;               eighty
  286.     shl    di,4            ; Compute
  287.     mov    ax,di            ;      destination
  288.     shl    ax,2            ;              times
  289.     add    di,ax            ;                eighty
  290.     shl    bx,1            ; Compute column offset value
  291.     add    si,bx            ; Compute the actual source address
  292.     add    di,bx            ; Compute actual destination address
  293.     mov    bx,MAX_COLUMN        ; Compute and
  294.     add    bx,dx            ;          save decrement
  295.     shl    bx,1            ;                 value
  296.     cmp    cx,bp            ; Check the scroll count value
  297.     ja    Down_Move        ; Jump if partial window scroll
  298.     mov    bp,cx            ; Limit scroll to entire window
  299. Down_Move:
  300.     Save    bp            ; Save the scroll count value
  301.     sub    cx,bp            ; Compute and save
  302.     mov    bp,cx            ;           the move count
  303.     jz    Down_Clear        ; Jump if entire window scroll
  304. Move_Down_Loop:
  305.     mov    cx,dx            ; Setup the column count value
  306.     rep    movsw            ; Move an entire row
  307.     sub    si,bx            ; Update the
  308.     sub    di,bx            ;         screen addresses
  309.     dec    bp            ; Decrement the row count value
  310.     jnz    Move_Down_Loop        ; Loop till all rows are moved
  311. Down_Clear:
  312.     Restore bp            ; Restore the row count value
  313.     mov    al,SPACE        ; Setup to write a space character
  314.     mov    ah,Byte Ptr cs:[Current_Back]
  315.     shl    ah,BACK_SHIFT        ; Shift background into position
  316.     or    ah,Byte Ptr cs:[Current_Fore]
  317. Clear_Down_Loop:
  318.     mov    cx,dx            ; Setup the column count value
  319.     rep    stosw            ; Clear an entire row
  320.     sub    di,bx            ; Update the screen address
  321.     dec    bp            ; Decrement the row count value
  322.     jnz    Clear_Down_Loop     ; Loop till all rows are cleared
  323. Down_Exit:
  324.     Restore ax,bx,cx,dx,si,di,bp,ds,es
  325.     ret                ; Return to the caller
  326. Scroll_Down    Endp            ; End of the Scroll_Down procedure
  327.     Subttl    Clear_Window    Clear Window Routine
  328.     Page    +
  329. ;******************************************************************************
  330. ;
  331. ;    Clear_Window(Window)
  332. ;
  333. ;        Save the required registers
  334. ;        If window coordinates are valid
  335. ;            Calculate starting address
  336. ;            Compute and save the row count
  337. ;            Compute address increment value
  338. ;            Compute and save the column count
  339. ;            Save the address increment value
  340. ;            Setup the clear character (Space)
  341. ;            While more rows to clear
  342. ;                Setup the column count value
  343. ;                While more columns to clear
  344. ;                    Store the clear character (Space)
  345. ;                    Decrement the column count
  346. ;                EndWhile
  347. ;                Update the screen address
  348. ;                Decrement the row count
  349. ;            EndWhile
  350. ;        Endif
  351. ;        Restore the required registers
  352. ;        Return to the caller
  353. ;
  354. ;    Registers on Entry:
  355. ;
  356. ;        AX    - Upper left window row coordinate
  357. ;        BX    - Upper left window column coordinate
  358. ;        CX    - Lower right window row coordinate
  359. ;        DX    - Lower right window column coordinate
  360. ;
  361. ;    Registers on Exit:
  362. ;
  363. ;        None
  364. ;
  365. ;******************************************************************************
  366.         Even            ; Force procedure to even address
  367. Clear_Window    Proc    Near        ; Clear window procedure
  368.     Save    ax,bx,cx,dx,si,di,es    ; Save the required registers
  369.     cmp    ax,cx            ; Check the row coordinate values
  370.     ja    Clear_Exit        ; Jump if row coordinates are invalid
  371.     cmp    bx,dx            ; Check column coordinate values
  372.     ja    Clear_exit        ; Jump if column coordinates are invalid
  373.     cmp    ax,MAX_ROW        ; Check upper left row value
  374.     jnc    Clear_Exit        ; Jump if invalid row value
  375.     cmp    bx,MAX_COLUMN        ; Check upper left column value
  376.     jnc    Clear_Exit        ; Jump if invalid column value
  377.     cmp    cx,MAX_ROW        ; Check lower right row value
  378.     jnc    Clear_Exit        ; Jump if invalid row value
  379.     cmp    dx,MAX_COLUMN        ; Check lower right column value
  380.     jnc    Clear_Exit        ; Jump if invalid column value
  381.     mov    di,ax            ; Compute
  382.     shl    di,2            ;      row number
  383.     add    di,ax            ;             times five (*80)
  384.     add    di,VIDEO_MEMORY     ; Compute actual video memory segment
  385.     mov    es,di            ; Setup to access video memory
  386.     mov    di,bx            ; Compute the actual
  387.     shl    di,1            ;             memory address
  388.     mov    si,cx            ; Compute and
  389.     sub    si,ax            ;          save the
  390.     inc    si            ;               row count
  391.     mov    ax,MAX_COLUMN - 1    ; Compute
  392.     sub    ax,dx            ;      address
  393.     add    ax,bx            ;          increment
  394.     shl    ax,1            ;                value
  395.     sub    dx,bx            ; Compute and save
  396.     inc    dx            ;           the column count
  397.     mov    bx,ax            ; Save the address increment value
  398.     mov    al,SPACE        ; Setup to write a space character
  399.     mov    ah,Byte Ptr cs:[Current_Back]
  400.     shl    ah,BACK_SHIFT        ; Shift background into position
  401.     or    ah,Byte Ptr cs:[Current_Fore]
  402. Clear_Loop:
  403.     mov    cx,dx            ; Setup the column count value
  404.     rep    stosw            ; Clear an entire row
  405.     add    di,bx            ; Update the screen address
  406.     dec    si            ; Decrement the row count value
  407.     jnz    Clear_Loop        ; Loop till all rows are cleared
  408. Clear_Exit:
  409.     Restore ax,bx,cx,dx,si,di,es    ; Restore the required registers
  410.     ret                ; Return to the caller
  411. Clear_Window    Endp            ; End of the Clear_Window procedure
  412.     Subttl    Save_Window    Save Window Routine
  413.     Page    +
  414. ;******************************************************************************
  415. ;
  416. ;    Save_Window(Window)
  417. ;
  418. ;        Save the required registers
  419. ;        If window coordinates are valid
  420. ;            Calculate amount of storage required
  421. ;            If enough memory is available
  422. ;                Save the window coordinates
  423. ;                Calculate starting address
  424. ;                Compute and save the row count
  425. ;                Compute address increment value
  426. ;                Compute and save the column count
  427. ;                Save the address increment value
  428. ;                While more rows to save
  429. ;                    Setup the column count value
  430. ;                    While more columns to save
  431. ;                        Save the next column
  432. ;                        Decrement the column count
  433. ;                    EndWhile
  434. ;                    Update the screen address
  435. ;                    Decrement the row count
  436. ;                EndWhile
  437. ;                Setup the window handle value
  438. ;            Endif
  439. ;        Endif
  440. ;        Restore the required registers
  441. ;        Return to the caller
  442. ;
  443. ;    Registers on Entry:
  444. ;
  445. ;        AX    - Upper left window row coordinate
  446. ;        BX    - Upper left window column coordinate
  447. ;        CX    - Lower right window row coordinate
  448. ;        DX    - Lower right window column coordinate
  449. ;
  450. ;    Registers on Exit:
  451. ;
  452. ;        BP    - Window save handle (If no errors)
  453. ;
  454. ;******************************************************************************
  455.         Even            ; Force procedure to even address
  456. Save_Window    Proc    Near        ; Save window procedure
  457.     Save    ax,bx,cx,dx,si,di,ds,es ; Save the required registers
  458.     cmp    ax,cx            ; Check the row coordinate values
  459.     ja    Save_Exit        ; Jump if row coordinates are invalid
  460.     cmp    bx,dx            ; Check column coordinate values
  461.     ja    Save_exit        ; Jump if column coordinates are invalid
  462.     cmp    ax,MAX_ROW        ; Check upper left row value
  463.     jnc    Save_Exit        ; Jump if invalid row value
  464.     cmp    bx,MAX_COLUMN        ; Check upper left column value
  465.     jnc    Save_Exit        ; Jump if invalid column value
  466.     cmp    cx,MAX_ROW        ; Check lower right row value
  467.     jnc    Save_Exit        ; Jump if invalid row value
  468.     cmp    dx,MAX_COLUMN        ; Check lower right column value
  469.     jnc    Save_Exit        ; Jump if invalid column value
  470.     Save    ax,bx,cx,dx        ; Save the window coordinates
  471.     sub    cx,ax            ; Compute the
  472.     inc    cx            ;          number of rows
  473.     sub    dx,bx            ; Compute the
  474.     inc    dx            ;          number of columns
  475.     mov    ax,cx            ; Compute amount
  476.     mul    dx            ;         of storage
  477.     shl    ax,1            ;                required
  478.     mov    bx,ax            ; Compute the
  479.     add    bx,PARA_ROUND + 8    ;          number of
  480.     shr    bx,PARA_SHIFT        ;            paragraphs
  481.     mov    ah,ALLOCATE_MEMORY    ; Get allocate memory function code
  482.     int    DOS            ; Try to allocate the memory
  483.     mov    es,ax            ; Save the returned memory address
  484.     Restore ax,bx,cx,dx        ; Restore the window coordinates
  485.     jc    Save_Exit        ; Jump if unable to allocate memory
  486.     xor    di,di            ; Setup to access the memory area
  487.     stosw                ; Save the
  488.     xchg    ax,bx            ;       upper left
  489.     stosw                ;              coordinate
  490.     xchg    ax,cx            ; Save the
  491.     stosw                ;       lower
  492.     xchg    ax,dx            ;         right
  493.     stosw                ;               coordinate
  494.     xchg    ax,bx            ; Restore the
  495.     xchg    cx,dx            ;          window
  496.     xchg    bx,dx            ;             coordinates
  497.     mov    si,ax            ; Compute
  498.     shl    si,2            ;      row number
  499.     add    si,ax            ;             times five (*80)
  500.     add    si,VIDEO_MEMORY     ; Compute actual video memory segment
  501.     mov    ds,si            ; Setup to access video memory
  502.     mov    si,bx            ; Compute the actual
  503.     shl    si,1            ;             memory address
  504.     mov    bp,cx            ; Compute and
  505.     sub    bp,ax            ;          save the
  506.     inc    bp            ;               row count
  507.     mov    ax,MAX_COLUMN - 1    ; Compute
  508.     sub    ax,dx            ;      address
  509.     add    ax,bx            ;          increment
  510.     shl    ax,1            ;                value
  511.     sub    dx,bx            ; Compute and save
  512.     inc    dx            ;           the column count
  513.     mov    bx,ax            ; Save the address increment value
  514. Save_Loop:
  515.     mov    cx,dx            ; Setup the column count value
  516.     rep    movsw            ; Save an entire row
  517.     add    si,bx            ; Update the screen address
  518.     dec    bp            ; Decrement the row count value
  519.     jnz    Save_Loop        ; Loop till all rows are saved
  520.     mov    bp,es            ; Get the window handle value
  521. Save_Exit:
  522.     Restore ax,bx,cx,dx,si,di,ds,es ; Restore the required registers
  523.     ret                ; Return to the caller
  524. Save_Window    Endp            ; End of the Save_Window procedure
  525.     Subttl    Restore_Window    Restore Window Routine
  526.     Page    +
  527. ;******************************************************************************
  528. ;
  529. ;    Restore_Window(Handle)
  530. ;
  531. ;        Save the required registers
  532. ;        Setup access to the window data
  533. ;        Get the window coordinates
  534. ;        Calculate starting address
  535. ;        Compute and save the row count
  536. ;        Compute address increment value
  537. ;        Compute and save the column count
  538. ;        Save the address increment value
  539. ;        While more rows to restore
  540. ;            Setup the column count value
  541. ;            While more columns to restore
  542. ;                Restore the next column
  543. ;                Decrement the column count
  544. ;            EndWhile
  545. ;            Update the screen address
  546. ;            Decrement the row count
  547. ;        EndWhile
  548. ;        Free the allocated memory
  549. ;        Restore the required registers
  550. ;        Return to the caller
  551. ;
  552. ;    Registers on Entry:
  553. ;
  554. ;        BP    - Window handle to restore
  555. ;
  556. ;    Registers on Exit:
  557. ;
  558. ;        None
  559. ;
  560. ;******************************************************************************
  561.         Even            ; Force procedure to even address
  562. Restore_Window    Proc    Near        ; Restore window procedure
  563.     Save    ax,bx,cx,dx,si,di,bp,ds,es
  564.     mov    ds,bp            ; Setup access to
  565.     xor    si,si            ;          the window data
  566.     lodsw                ; Restore
  567.     mov    dx,ax            ;      upper left
  568.     lodsw                ;             window
  569.     mov    bx,ax            ;                coordinate
  570.     lodsw                ; Restore
  571.     mov    cx,ax            ;      lower right
  572.     lodsw                ;              window
  573.     xchg    ax,dx            ;                 coordinate
  574.     mov    di,ax            ; Compute
  575.     shl    di,2            ;      row number
  576.     add    di,ax            ;             times five (*80)
  577.     add    di,VIDEO_MEMORY     ; Compute actual video memory segment
  578.     mov    es,di            ; Setup to access video memory
  579.     mov    di,bx            ; Compute the actual
  580.     shl    di,1            ;             memory address
  581.     mov    bp,cx            ; Compute and
  582.     sub    bp,ax            ;          save the
  583.     inc    bp            ;               row count
  584.     mov    ax,MAX_COLUMN - 1    ; Compute
  585.     sub    ax,dx            ;      address
  586.     add    ax,bx            ;          increment
  587.     shl    ax,1            ;                value
  588.     sub    dx,bx            ; Compute and save
  589.     inc    dx            ;           the column count
  590.     mov    bx,ax            ; Save the address increment value
  591. Restore_Loop:
  592.     mov    cx,dx            ; Setup the column count value
  593.     rep    movsw            ; Restore an entire row
  594.     add    di,bx            ; Update the screen address
  595.     dec    bp            ; Decrement the row count value
  596.     jnz    Restore_Loop        ; Loop till all rows are restored
  597.     mov    ax,ds            ; Setup to free
  598.     mov    es,ax            ;        the allocated memory
  599.     mov    ah,FREE_MEMORY        ; Get free memory function code
  600.     int    DOS            ; Try to free the allocated memory
  601. Restore_Exit:
  602.     Restore ax,bx,cx,dx,si,di,bp,ds,es
  603.     ret                ; Return to the caller
  604. Restore_Window    Endp            ; End of the Restore_Window procedure
  605. ;******************************************************************************
  606. ;
  607. ;    Define the end of the Emulator Code Segment
  608. ;
  609. ;******************************************************************************
  610. Emulate Ends
  611.     End                ; End of the Window module
  612.