home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / Assembly / PHANTOM.ASM < prev    next >
Assembly Source File  |  1986-10-07  |  20KB  |  621 lines

  1. CGROUP    GROUP    CODE_SEG, DATA_SEG
  2.     ASSUME    CS:CGROUP, DS:CGROUP
  3.  
  4.  
  5. ;-----------------------------------------------------------------------;
  6. ; This file contains procedures that handle the phantom cursor:        ;
  7. ;                                    ;
  8. ; WRITE_PHANTOM            Write the phantom cursor        ;
  9. ; ERASE_PHANTOM            Erase the phantom cursor        ;
  10. ;                                    ;
  11. ; PHANTOM_UP            Move the phantom cursor up        ;
  12. ; PHANTOM_DOWN            Move the phantom cursor down        ;
  13. ; PHANTOM_LEFT            Move the phantom cursor left        ;
  14. ; PHANTOM_RIGHT            Move the phantom cursor right        ;
  15. ; PAGE_UP            Scroll window back by 8 lines        ;
  16. ; PAGE_DOWN            Scroll window forward by 8 lines    ;
  17. ; HOME_KEY            Move to the first byte in the sector    ;
  18. ; END_KEY            Move to the last byte in the sector    ;
  19. ;                                    ;
  20. ; MOV_TO_HEX_POSITION        Move cursor to hex phantom cursor    ;
  21. ; MOV_TO_ASCII_POSITION        Move cursor to ASCII phantom cursor    ;
  22. ; MOV_TO_LEFT_NUMBERS        Move to current left number        ;
  23. ; MOV_TO_TOP_HEX_NUMBERS    Move to current top hex number        ;
  24. ; MOV_TO_ASCII_NUMBERS        Move to number above ASCII window    ;
  25. ; SAVE_REAL_CURSOR        Remember the location of real cursor    ;
  26. ; RESTORE_REAL_CURSOR        Put real cursor back where it was    ;
  27. ; SCROLL_UP            Scroll the window up by N lines        ;
  28. ; SCROLL_DOWN            Scroll the window down by N lines    ;
  29. ; SCROLL_WINDOW            Do the actual scrolling of windows    ;
  30. ; FILL_SCROLLED_LINES        Fill lines left blank by scrolling    ;
  31. ;-----------------------------------------------------------------------;
  32.  
  33.  
  34. DATA_SEG    SEGMENT PUBLIC
  35. REAL_CURSOR_X        DB    0
  36. REAL_CURSOR_Y        DB    0
  37.     PUBLIC    PHANTOM_CURSOR_X, PHANTOM_CURSOR_Y
  38. PHANTOM_CURSOR_X    DB    0
  39. PHANTOM_CURSOR_Y    DB    0
  40. DATA_SEG    ENDS
  41.  
  42.  
  43. CODE_SEG    SEGMENT PUBLIC
  44.  
  45.     PUBLIC    WRITE_PHANTOM
  46.     EXTRN    WRITE_ATTRIBUTE_N_TIMES:NEAR
  47. ;-----------------------------------------------------------------------;
  48. ; This procedure uses CURSOR_X and CURSOR_Y, through MOV_TO_..., as the    ;
  49. ; coordinates for the phantom cursor.  WRITE_PHANTOM writes this    ;
  50. ; phantom cursor.                            ;
  51. ;                                    ;
  52. ; Uses:        WRITE_ATTRIBUTE_N_TIMES, SAVE_REAL_CURSOR        ;
  53. ;        RESTORE_REAL_CURSOR, MOV_TO_HEX_POSITION        ;
  54. ;        MOV_TO_ASCII_POSITION, MOV_TO_LEFT_NUMBERS        ;
  55. ;        MOV_TO_TOP_HEX_NUMBERS, MOV_TO_TOP_ASCII_NUMBERS    ;
  56. ;-----------------------------------------------------------------------;
  57. WRITE_PHANTOM    PROC    NEAR
  58.     PUSH    CX
  59.     PUSH    DX
  60.     CALL    SAVE_REAL_CURSOR    ;Save position of the real cursor
  61.     CALL    MOV_TO_HEX_POSITION    ;Coord of cursor in hex window
  62.     MOV    CX,4            ;Make phantom cursor four chars wide
  63.     MOV    DL,70H            ;Attribute for reverse video
  64.     CALL    WRITE_ATTRIBUTE_N_TIMES    ;Write hex number in inverse video
  65.     CALL    MOV_TO_ASCII_POSITION    ;Coord. of cursor in ASCII window
  66.     MOV    CX,1            ;Cursor is one character wide here
  67.     CALL    WRITE_ATTRIBUTE_N_TIMES    ;Write ASCII character in inverse
  68.     MOV    DL,0FH            ;Attribute for high intensity
  69.     CALL    MOV_TO_LEFT_NUMBERS    ;Move to current offset on left side
  70.     MOV    CX,5
  71.     CALL    WRITE_ATTRIBUTE_N_TIMES    ;Make current offset bright
  72.     CALL    MOV_TO_TOP_HEX_NUMBERS    ;Move to hex offset along top
  73.     MOV    CX,4
  74.     CALL    WRITE_ATTRIBUTE_N_TIMES    ;Make current offset bright
  75.     CALL    MOV_TO_TOP_ASCII_NUMBERS ;Move to offset above ASCII window
  76.     MOV    CX,1
  77.     CALL    WRITE_ATTRIBUTE_N_TIMES    ;Make current offset bright
  78.     CALL    RESTORE_REAL_CURSOR    ;Put cursor back where it was
  79.     POP    DX
  80.     POP    CX
  81.     RET
  82. WRITE_PHANTOM    ENDP
  83.  
  84.  
  85.     PUBLIC    ERASE_PHANTOM
  86.     EXTRN    WRITE_ATTRIBUTE_N_TIMES:NEAR
  87. ;-----------------------------------------------------------------------;
  88. ; This procedure erases the phantom cursor, just the opposite of    ;
  89. ; WRITE_PHANTOM                                ;
  90. ;                                    ;
  91. ; Uses:        WRITE_ATTRIBUTE_N_TIMES, SAVE_REAL_CURSOR        ;
  92. ;        RESTORE_REAL_CURSOR, MOV_TO_HEX_POSITION        ;
  93. ;        MOV_TO_ASCII_POSITION, MOV_TO_LEFT_NUMBERS        ;
  94. ;        MOV_TO_TOP_HEX_NUMBERS, MOV_TO_TOP_ASCII_NUMBERS    ;
  95. ;-----------------------------------------------------------------------;
  96. ERASE_PHANTOM    PROC    NEAR
  97.     PUSH    CX
  98.     PUSH    DX
  99.     CALL    SAVE_REAL_CURSOR    ;Remember where the cursor was
  100.     CALL    MOV_TO_HEX_POSITION    ;Coord. of cursor in hex window
  101.     MOV    CX,4            ;Make characters normal video
  102.     MOV    DL,7            ;Attribute for normal video
  103.     CALL    WRITE_ATTRIBUTE_N_TIMES    ;Make hex number normal video
  104.     CALL    MOV_TO_ASCII_POSITION    ;Move to character in ASCII window
  105.     MOV    CX,1
  106.     CALL    WRITE_ATTRIBUTE_N_TIMES    ;Make attribute normal video
  107.     CALL    MOV_TO_LEFT_NUMBERS    ;Move to offset along left side
  108.     MOV    CX,5
  109.     CALL    WRITE_ATTRIBUTE_N_TIMES    ;Make attribute normal video
  110.     CALL    MOV_TO_TOP_HEX_NUMBERS    ;Move to offset above hex window
  111.     MOV    CX,4
  112.     CALL    WRITE_ATTRIBUTE_N_TIMES    ;Make attribute normal video
  113.     CALL    MOV_TO_TOP_ASCII_NUMBERS ;Move to offset above ASCII window
  114.     MOV    CX,1
  115.     CALL    WRITE_ATTRIBUTE_N_TIMES    ;Make attribute normal video
  116.     CALL    RESTORE_REAL_CURSOR    ;Put cursor back where it was
  117.     POP    DX
  118.     POP    CX
  119.     RET
  120. ERASE_PHANTOM    ENDP
  121.  
  122.  
  123. ;-----------------------------------------------------------------------;
  124. ; These four procedures move the phantom cursor.            ;
  125. ;                                    ;
  126. ; Uses:        ERASE_PHANTOM, WRITE_PHANTOM, SCROLL_DOWN, SCROLL_UP    ;
  127. ; Writes:    PHANTOM_CURSOR_X, PHANTOM_CURSOR_Y            ;
  128. ;-----------------------------------------------------------------------;
  129.  
  130.     PUBLIC    PHANTOM_UP
  131. PHANTOM_UP    PROC    NEAR
  132.     PUSH    CX
  133.     CALL    ERASE_PHANTOM        ;Erase at current position
  134.     DEC    PHANTOM_CURSOR_Y    ;Move cursor up one line
  135.     JNS    WASNT_AT_TOP        ;Was not at the top, write cursor
  136.     MOV    PHANTOM_CURSOR_Y,0    ;Was at top, so put back there
  137.     MOV    CL,1            ;Scroll by one line
  138.     CALL    SCROLL_DOWN        ;Was at the top, scroll
  139. WASNT_AT_TOP:
  140.     CALL    WRITE_PHANTOM        ;Write the phantom at new position
  141.     POP    CX
  142.     RET
  143. PHANTOM_UP    ENDP
  144.  
  145.     PUBLIC    PHANTOM_DOWN
  146. PHANTOM_DOWN    PROC    NEAR
  147.     PUSH    CX
  148.     CALL    ERASE_PHANTOM        ;Erase at current position
  149.     INC    PHANTOM_CURSOR_Y    ;Move cursor up one line
  150.     CMP    PHANTOM_CURSOR_Y,16    ;Was it at the bottom?
  151.     JB    WASNT_AT_BOTTOM        ;No, so write phantom
  152.     MOV    PHANTOM_CURSOR_Y,15    ;Was at bottom, so put back there
  153.     MOV    CL,1            ;Scroll by one line
  154.     CALL    SCROLL_UP        ;Was at bottom, scroll
  155. WASNT_AT_BOTTOM:
  156.     CALL    WRITE_PHANTOM        ;Write the phantom cursor
  157.     POP    CX
  158.     RET
  159. PHANTOM_DOWN    ENDP
  160.  
  161.     PUBLIC    PHANTOM_LEFT
  162. PHANTOM_LEFT    PROC    NEAR
  163.     CALL    ERASE_PHANTOM        ;Erase at current position
  164.     DEC    PHANTOM_CURSOR_X    ;Move cursor left one column
  165.     JNS    WASNT_AT_LEFT        ;Was not at the left side, write cursor
  166.     MOV    PHANTOM_CURSOR_X,0    ;Was at left, so put back there
  167. WASNT_AT_LEFT:
  168.     CALL    WRITE_PHANTOM        ;Write the phantom cursor
  169.     RET
  170. PHANTOM_LEFT    ENDP
  171.  
  172.     PUBLIC    PHANTOM_RIGHT
  173. PHANTOM_RIGHT    PROC    NEAR
  174.     CALL    ERASE_PHANTOM        ;Erase at current position
  175.     INC    PHANTOM_CURSOR_X    ;Move cursor right one column
  176.     CMP    PHANTOM_CURSOR_X,16    ;Was it already at the right side?
  177.     JB    WASNT_AT_RIGHT
  178.     MOV    PHANTOM_CURSOR_X,15    ;Was at right, so put back there
  179. WASNT_AT_RIGHT:
  180.     CALL    WRITE_PHANTOM        ;Write the phantom cursor
  181.     RET
  182. PHANTOM_RIGHT    ENDP
  183.  
  184.  
  185. ;-----------------------------------------------------------------------;
  186. ; These two procedures move the window 8 lines at a time.        ;
  187. ;                                    ;
  188. ; Uses:        ERASE_PHANTOM, WRITE_PHANTOM, SCROLL_DOWN (UP)        ;
  189. ;-----------------------------------------------------------------------;
  190.     PUBLIC    PAGE_UP
  191. PAGE_UP        PROC    NEAR
  192.     PUSH    CX
  193.     CALL    ERASE_PHANTOM        ;Remove the phantom cursor
  194.     MOV    CL,4
  195.     CALL    SCROLL_DOWN        ;Scroll windows down by 4 lines
  196.     CALL    WRITE_PHANTOM        ;Draw the phantom cursor again
  197.     POP    CX
  198.     RET
  199. PAGE_UP        ENDP
  200.  
  201.  
  202.     PUBLIC    PAGE_DOWN
  203. PAGE_DOWN    PROC    NEAR
  204.     PUSH    CX
  205.     CALL    ERASE_PHANTOM        ;Remove the phantom cursor
  206.     MOV    CL,4
  207.     CALL    SCROLL_UP        ;Scroll windows up by 4 lines
  208.     CALL    WRITE_PHANTOM        ;Draw the phantom cursor again
  209.     POP    CX
  210.     RET
  211. PAGE_DOWN    ENDP
  212.  
  213.  
  214. ;-----------------------------------------------------------------------;
  215. ; These two procedures move the cursor to the end and beginning of the    ;
  216. ; sector.                                ;
  217. ;                                    ;
  218. ; Uses:        ERASE_PHANTOM, WRITE_PHANTOM, SCROLL_DOWN (UP)        ;
  219. ; Writes:    PHANTOM_CURSOR_X, PHANTOM_CURSOR_Y            ;
  220. ;-----------------------------------------------------------------------;
  221.     PUBLIC    HOME_KEY
  222. HOME_KEY    PROC    NEAR
  223.     PUSH    CX
  224.     CALL    ERASE_PHANTOM        ;First remove the phantom cursor
  225.     MOV    CL,16            ;Now scroll down by 16 lines to move
  226.     CALL    SCROLL_DOWN        ;  to the beginning of the sector
  227.     XOR    CL,CL            ;Now reset the cursor to (0,0)
  228.     MOV    PHANTOM_CURSOR_X,CL    ;Save the new phantom cursor position
  229.     MOV    PHANTOM_CURSOR_Y,CL
  230.     CALL    WRITE_PHANTOM        ;and write phantom cursor at (0,0)
  231.     POP    CX
  232.     RET
  233. HOME_KEY    ENDP
  234.  
  235.  
  236.     PUBLIC    END_KEY
  237. END_KEY        PROC    NEAR
  238.     PUSH    CX
  239.     CALL    ERASE_PHANTOM        ;First remove the phantom cursor
  240.     MOV    CL,16            ;Now scroll down by 16 lines to move
  241.     CALL    SCROLL_UP        ; to the end of the sector
  242.     MOV    CL,15
  243.     MOV    PHANTOM_CURSOR_X,CL    ;Save the new phantom cursor position
  244.     MOV    PHANTOM_CURSOR_Y,CL
  245.     CALL    WRITE_PHANTOM        ;And write phantom cursor at (15,15)
  246.     POP    CX
  247.     RET
  248. END_KEY        ENDP
  249.  
  250.  
  251.     PUBLIC    MOV_TO_HEX_POSITION
  252.     EXTRN    GOTO_XY:NEAR
  253. DATA_SEG    SEGMENT PUBLIC
  254.     EXTRN    LINES_BEFORE_SECTOR:BYTE
  255. DATA_SEG    ENDS
  256. ;-----------------------------------------------------------------------;
  257. ; This procedure moves the real cursor to the position of the phantom    ;
  258. ; cursor in the hex window.                        ;
  259. ;                                    ;
  260. ; Uses:        GOTO_XY                            ;
  261. ; Reads:    LINES_BEFORE_SECTOR, PHANTOM_CURSOR_X, PHANTOM_CURSOR_Y    ;
  262. ;-----------------------------------------------------------------------;
  263. MOV_TO_HEX_POSITION    PROC    NEAR
  264.     PUSH    AX
  265.     PUSH    CX
  266.     PUSH    DX
  267.     MOV    DH,LINES_BEFORE_SECTOR    ;Find row of phantom (0,0)
  268.     ADD    DH,2            ;Plus row of hex and horizontal bar
  269.     ADD    DH,PHANTOM_CURSOR_Y    ;DH = row of phantom cursor
  270.     MOV    DL,8            ;Indent on left side
  271.     MOV    CL,3            ;Each column uses 3 characters,so
  272.     MOV    AL,PHANTOM_CURSOR_X    ; we must multiply CURSOR_X by 3
  273.     MUL    CL
  274.     ADD    DL,AL            ;And add to the indent, to get column
  275.     CALL    GOTO_XY            ;for phantom cursor.
  276.     POP    DX
  277.     POP    CX
  278.     POP    AX
  279.     RET
  280. MOV_TO_HEX_POSITION    ENDP
  281.  
  282.  
  283.     PUBLIC    MOV_TO_ASCII_POSITION
  284.     EXTRN    GOTO_XY:NEAR
  285. DATA_SEG    SEGMENT PUBLIC
  286.     EXTRN    LINES_BEFORE_SECTOR:BYTE
  287. DATA_SEG    ENDS
  288. ;-----------------------------------------------------------------------;
  289. ; This procedure moves the real cursor to the beginning of the phantom    ;
  290. ; cursor in the ASCII window.                        ;
  291. ;                                    ;
  292. ; Uses:        GOTO_XY                            ;
  293. ; Reads:    LINES_BEFORE_SECTOR, PHANTOM_CURSOR_X, PHANTOM_CURSOR_Y    ;
  294. ;-----------------------------------------------------------------------;
  295. MOV_TO_ASCII_POSITION    PROC    NEAR
  296.     PUSH    AX
  297.     PUSH    DX
  298.     MOV    DH,LINES_BEFORE_SECTOR    ;Find row for phantom (0,0)
  299.     ADD    DH,2            ;Plus row of hex and horizontal bar
  300.     ADD    DH,PHANTOM_CURSOR_Y    ;DH = row of phantom cursor
  301.     MOV    DL,59            ;Indent on left side
  302.     ADD    DL,PHANTOM_CURSOR_X    ;Add CURSOR_X to get X position
  303.     CALL    GOTO_XY            ; for phantom cursor.
  304.     POP    DX
  305.     POP    AX
  306.     RET
  307. MOV_TO_ASCII_POSITION    ENDP
  308.  
  309.  
  310.     PUBLIC    MOV_TO_LEFT_NUMBERS
  311.     EXTRN    GOTO_XY:NEAR
  312. DATA_SEG    SEGMENT PUBLIC
  313.     EXTRN    LINES_BEFORE_SECTOR:BYTE
  314. DATA_SEG    ENDS
  315. ;-----------------------------------------------------------------------;
  316. ; This procedure moves the real cursor to the hex offset number to the    ;
  317. ; left of the half-sector display.                    ;
  318. ;                                    ;
  319. ; Uses:        GOTO_XY                            ;
  320. ; Reads:    LINES_BEFORE_SECTOR                    ;
  321. ;-----------------------------------------------------------------------;
  322. MOV_TO_LEFT_NUMBERS    PROC    NEAR
  323.     PUSH    AX
  324.     PUSH    DX
  325.     MOV    DH,LINES_BEFORE_SECTOR    ;Find row of phantom (0,0)
  326.     ADD    DH,2            ;Plus row of hex and horizontal bar
  327.     ADD    DH,PHANTOM_CURSOR_Y    ;DH = row of phantom cursor
  328.     MOV    DL,2            ;Indent of left side
  329.     CALL    GOTO_XY
  330.     POP    DX
  331.     POP    AX
  332.     RET
  333. MOV_TO_LEFT_NUMBERS    ENDP
  334.  
  335.  
  336.     PUBLIC    MOV_TO_TOP_HEX_NUMBERS
  337.     EXTRN    GOTO_XY:NEAR, READ_CURSOR_POSITION:NEAR
  338. DATA_SEG    SEGMENT PUBLIC
  339.     EXTRN    LINES_BEFORE_SECTOR:BYTE
  340. DATA_SEG    ENDS
  341. ;-----------------------------------------------------------------------;
  342. ; This procedure moves the real cursor to the hex offset number above    ;
  343. ; the hex window.                            ;
  344. ;                                    ;
  345. ; Uses:        MOV_TO_HEX_POSITION, READ_CURSOR_POSITION, GOTO_XY    ;
  346. ; Reads:    LINES_BEFORE_SECTOR                    ;
  347. ;-----------------------------------------------------------------------;
  348. MOV_TO_TOP_HEX_NUMBERS    PROC    NEAR
  349.     PUSH    DX
  350.     CALL    MOV_TO_HEX_POSITION    ;Get to proper column
  351.     CALL    READ_CURSOR_POSITION    ;Now read cursor position
  352.     MOV    DH,LINES_BEFORE_SECTOR    ;Move up to line with numbers
  353.     CALL    GOTO_XY
  354.     POP    DX
  355.     RET
  356. MOV_TO_TOP_HEX_NUMBERS    ENDP
  357.  
  358.  
  359.     PUBLIC    MOV_TO_TOP_ASCII_NUMBERS
  360. DATA_SEG    SEGMENT PUBLIC
  361.     EXTRN    LINES_BEFORE_SECTOR:BYTE
  362. DATA_SEG    ENDS
  363. ;-----------------------------------------------------------------------;
  364. ; This procedure moves to the hex offset number at the top of the    ;
  365. ; ASCII window.                                ;
  366. ;                                    ;
  367. ; Uses:        MOV_TO_ASCII_POSITION, READ_CURSOR_POSITION, GOTO_XY    ;
  368. ; Reads:    LINES_BEFORE_SECTOR                    ;
  369. ;-----------------------------------------------------------------------;
  370. MOV_TO_TOP_ASCII_NUMBERS    PROC    NEAR
  371.     PUSH    DX
  372.     CALL    MOV_TO_ASCII_POSITION    ;Get to proper column
  373.     CALL    READ_CURSOR_POSITION    ;Now read cursor position
  374.     MOV    DH,LINES_BEFORE_SECTOR    ;Move up to line with numbers
  375.     CALL    GOTO_XY
  376.     POP    DX
  377.     RET
  378. MOV_TO_TOP_ASCII_NUMBERS    ENDP
  379.  
  380.  
  381.     PUBLIC    SAVE_REAL_CURSOR
  382. ;-----------------------------------------------------------------------;
  383. ; This procedures saves the position of the real cursor in the two    ;
  384. ; variables REAL_CURSOR_X and REAL_CURSOR_Y                ;
  385. ;                                    ;
  386. ; Uses:        READ_CURSOR_POSITION                    ;
  387. ; Writes:    REAL_CURSOR_X, REAL_CURSOR_Y                ;
  388. ;-----------------------------------------------------------------------;
  389. SAVE_REAL_CURSOR    PROC    NEAR
  390.     PUSH    DX
  391.     CALL    READ_CURSOR_POSITION    ;Read cursor position
  392.     MOV    REAL_CURSOR_Y,DL    ;Save position
  393.     MOV    REAL_CURSOR_X,DH
  394.     POP    DX
  395.     RET
  396. SAVE_REAL_CURSOR    ENDP
  397.  
  398.  
  399.     PUBLIC    RESTORE_REAL_CURSOR
  400.     EXTRN    GOTO_XY:NEAR
  401. ;-----------------------------------------------------------------------;
  402. ; This procedure restores the real cursor to its old position, saved in    ;
  403. ; REAL_CURSOR_X and REAL_CURSOR_Y                    ;
  404. ;                                    ;
  405. ; Uses:        GOTO_XY                            ;
  406. ; Reads:    REAL_CURSOR_X, REAL_CURSOR_Y                ;
  407. ;-----------------------------------------------------------------------;
  408. RESTORE_REAL_CURSOR    PROC    NEAR
  409.     PUSH    DX
  410.     MOV    DL,REAL_CURSOR_Y    ;Get the old cursor position
  411.     MOV    DH,REAL_CURSOR_X
  412.     CALL    GOTO_XY            ;Move the cursor back there
  413.     POP    DX
  414.     RET
  415. RESTORE_REAL_CURSOR    ENDP
  416.  
  417.  
  418.     PUBLIC    SCROLL_UP
  419. DATA_SEG    SEGMENT PUBLIC
  420.     EXTRN    SECTOR_OFFSET:WORD
  421. DATA_SEG    ENDS
  422. ;-----------------------------------------------------------------------;
  423. ; This procedure scrolls the sector display, leaving blank lines at    ;
  424. ; the bottom of the display.  SCROLL_UP uses SECTOR_OFFSET to determine    ;
  425. ; how many lines it can scroll without moving past the end of the half-    ;
  426. ; sector display.                            ;
  427. ;                                    ;
  428. ;    CL    Number of lines to scroll by.                ;
  429. ;                                    ;
  430. ; Uses:        SCROLL_WINDOW, FILL_SCROLLED_LINES            ;
  431. ; Reads:    SECTOR_OFFSET                        ;
  432. ; Writes:    SECTOR_OFFSET                        ;
  433. ;-----------------------------------------------------------------------;
  434. SCROLL_UP    PROC    NEAR
  435.     PUSH    AX
  436.     PUSH    BX
  437.     PUSH    CX
  438.     PUSH    DX
  439.     MOV    AL,CL            ;Move scroll count; we need to use CL
  440.     MOV    BX,SECTOR_OFFSET    ;See where we are in the buffer
  441.     MOV    CL,4            ;divide by 16 to get number of lines
  442.     SHR    BX,CL            ;  offset into the half-sector
  443.     ADD    BL,AL            ;See if we have enough room to scroll
  444.     CMP    BL,16            ;Enough room?
  445.     JBE    CAN_SCROLL_UP        ;Yes, scroll up by AL lines
  446.     SUB    BL,16            ;Number of extra lines we can't scroll
  447.     SUB    AL,BL            ;Total number of lines we can scroll
  448.     JLE    DONT_SCROLL        ;Don't scroll if this is zero
  449. CAN_SCROLL_UP:
  450.     MOV    BL,AL            ;Adjust the SECTOR_OFFSET
  451.     XOR    BH,BH            ;BX contains num of lines scrolled
  452.     MOV    CL,4
  453.     SHL    BX,CL            ;Number of bytes scrolled
  454.     ADD    BX,SECTOR_OFFSET    ;New sector offset
  455.     MOV    SECTOR_OFFSET,BX
  456.     MOV    CL,AL            ;Mov scroll count into CL
  457.     MOV    AL,6            ;Call for scroll up
  458.     CALL    SCROLL_WINDOW
  459.     MOV    DL,16            ;(16 - scroll count) = first blank
  460.     SUB    DL,CL            ;  blank line
  461.     CALL    FILL_SCROLLED_LINES
  462.  
  463. DONT_SCROLL:
  464.     POP    DX
  465.     POP    CX
  466.     POP    BX
  467.     POP    AX
  468.     RET
  469. SCROLL_UP    ENDP
  470.  
  471.  
  472.     PUBLIC    SCROLL_DOWN
  473. DATA_SEG    SEGMENT PUBLIC
  474.     EXTRN    SECTOR_OFFSET:WORD
  475. DATA_SEG    ENDS
  476. ;-----------------------------------------------------------------------;
  477. ; This procedure scrolls the sector display, leaving blank lines at    ;
  478. ; the top of the display.  SCROLL_UP uses SECTOR_OFFSET to determine    ;
  479. ; how many lines it can scroll without moving past the top of the half-    ;
  480. ; sector display.                            ;
  481. ;                                    ;
  482. ;    CL    Number of lines to scroll by.                ;
  483. ;                                    ;
  484. ; Uses:        SCROLL_WINDOW, FILL_SCROLLED_LINES            ;
  485. ; Reads:    SECTOR_OFFSET                        ;
  486. ; Writes:    SECTOR_OFFSET                        ;
  487. ;-----------------------------------------------------------------------;
  488. SCROLL_DOWN    PROC    NEAR
  489.     PUSH    AX
  490.     PUSH    BX
  491.     PUSH    CX
  492.     PUSH    DX
  493.     MOV    AL,CL            ;Move scroll count; we need to use CL
  494.     MOV    BX,SECTOR_OFFSET    ;See where we are in the buffer
  495.     MOV    CL,4            ;divide by 16 to get number of lines
  496.     SHR    BX,CL            ;  offset into the half-sector
  497.     SUB    BL,AL            ;See if we have enough room to scroll
  498.     JNS    CAN_SCROLL_DOWN        ;Yes, we can scroll down
  499.     ADD    AL,BL            ;Total number of lines we can scroll
  500.     JZ    DONT_SCROLL        ;Don't scroll if zero
  501. CAN_SCROLL_DOWN:
  502.     MOV    BL,AL            ;Adjust the SECTOR_OFFSET
  503.     XOR    BH,BH            ;BX contains num of lines scrolled
  504.     MOV    CL,4
  505.     SHL    BX,CL            ;Number of bytes scrolled
  506.     SUB    BX,SECTOR_OFFSET    ;New sector offset
  507.     NEG    BX
  508.     MOV    SECTOR_OFFSET,BX
  509.     MOV    CL,AL            ;Mov scroll count into CL
  510.     MOV    AL,7            ;Call for scroll up
  511.     CALL    SCROLL_WINDOW
  512.     MOV    DL,0            ;First blank line
  513.     CALL    FILL_SCROLLED_LINES
  514.     JMP    DONT_SCROLL
  515. SCROLL_DOWN    ENDP
  516.  
  517.  
  518.     PUBLIC    SCROLL_WINDOW
  519. DATA_SEG    SEGMENT PUBLIC
  520.     EXTRN    LINES_BEFORE_SECTOR:BYTE
  521. DATA_SEG    ENDS
  522. ;-----------------------------------------------------------------------;
  523. ; This procedure scrolls the half-sector display.            ;
  524. ;                                    ;
  525. ;    AL    6 for scroll up, 7 for scroll down.            ;
  526. ;    CL    Number of lines to scroll                ;
  527. ;                                    ;
  528. ; Reads:    LINES_BEFORE_SECTOR                    ;
  529. ;-----------------------------------------------------------------------;
  530. SCROLL_WINDOW    PROC    NEAR
  531.     PUSH    AX
  532.     PUSH    BX
  533.     PUSH    CX
  534.     PUSH    DX
  535.     MOV    AH,AL            ;Put 6 or 7 into AH register
  536.     MOV    AL,CL            ;Place scroll count into AL
  537.     CMP    AL,15            ;Should we blank entire window?
  538.     JBE    DONT_BLANK        ;No, continue.
  539.     XOR    AL,AL            ;Yes, set scroll count to 0
  540. DONT_BLANK:
  541.     MOV    CH,LINES_BEFORE_SECTOR    ;Top row
  542.     ADD    CH,2
  543.     MOV    DH,CH            ;Bottom row
  544.     ADD    DH,15
  545.  
  546.     XOR    CL,CL            ;Left column
  547.     MOV    DL,6            ;Right column
  548.     MOV    BH,7            ;Normal attribute for blank lines
  549.     PUSH    AX
  550.     INT    10h            ;Scroll offset numbers on left side
  551.     POP    AX
  552.  
  553.     MOV    CL,8            ;Left side of the hex window
  554.     MOV    DL,56            ;Right side of the hex window
  555.     PUSH    AX
  556.     INT    10h            ;Scroll the hex window
  557.     POP    AX
  558.  
  559.     MOV    CL,58            ;Left side of the ASCII window
  560.     MOV    DL,75            ;Right side of the ASCII window
  561.     PUSH    AX
  562.     INT    10h            ;Scroll the ASCII window
  563.     POP    AX
  564.  
  565.     POP    DX
  566.     POP    CX
  567.     POP    BX
  568.     POP    AX
  569.     RET
  570. SCROLL_WINDOW    ENDP
  571.  
  572.  
  573.     PUBLIC    FILL_SCROLLED_LINES
  574.     EXTRN    DISP_LINE:NEAR, SEND_CRLF:NEAR
  575.     EXTRN    GOTO_XY:NEAR
  576. DATA_SEG    SEGMENT PUBLIC
  577.     EXTRN    SECTOR_OFFSET:WORD
  578.     EXTRN    LINES_BEFORE_SECTOR:BYTE
  579. DATA_SEG    ENDS
  580. ;-----------------------------------------------------------------------;
  581. ; This procedure fills in the lines blanked by scrolling.        ;
  582. ;                                    ;
  583. ;    CL    Number of lines scrolled                ;
  584. ;    DL    First line to fill in                    ;
  585. ;                                    ;
  586. ; Uses:        DISP_LINE, SEND_CRLF, GOTO_XY                ;
  587. ;        SAVE_REAL_CURSOR, RESTORE_REAL_CURSOR            ;
  588. ; Reads:    LINES_BEFORE_SECTOR, SECTOR_OFFSET            ;
  589. ;-----------------------------------------------------------------------;
  590. FILL_SCROLLED_LINES    PROC    NEAR
  591.     PUSH    CX
  592.     PUSH    DX
  593.     CALL    SAVE_REAL_CURSOR    ;Remember where cursor was
  594.     MOV    DH,LINES_BEFORE_SECTOR    ;Calculate the first row
  595.     ADD    DH,2            ;Row of first line in sector display
  596.     ADD    DH,DL            ;Row of first line to fill
  597.     XOR    DL,DL
  598.     CALL    GOTO_XY            ;Move cursor to start of row
  599.     POP    DX            ;Restore DX
  600.     PUSH    DX
  601.     XOR    DH,DH            ;DX -- first line to fill in (0..15)
  602.     PUSH    CX
  603.     MOV    CL,4
  604.     SHL    DX,CL            ;Number of bytes from start of display
  605.     POP    CX
  606.     ADD    DX,SECTOR_OFFSET    ;Starting byte.
  607. FILL_LINE_LOOP:
  608.     CALL    DISP_LINE        ;Display one line
  609.     CALL    SEND_CRLF        ;Move to start of next line
  610.     ADD    DX,16            ;Move to next line in SECTOR
  611.     LOOP    FILL_LINE_LOOP        ;Keep filling empty lines
  612.     CALL    RESTORE_REAL_CURSOR    ;Put cursor back where it was
  613.     POP    DX
  614.     POP    CX
  615.     RET
  616. FILL_SCROLLED_LINES    ENDP
  617.  
  618. CODE_SEG    ENDS
  619.  
  620.     END
  621.