home *** CD-ROM | disk | FTP | other *** search
- TITLE SCROLLK.COM -- DOS RESIDENT SCROLL LOCK CONTROL
- PAGE 60,132
-
- COMMENT* This program provides scrolling control of the video display with
- the Scroll Lock key. Assemble, Link, and convert the EXE file to a
- COM program. Run the program once on system boot-up then the Scroll
- Lock key can be used to toggle scrolling on and off. If scroll lock
- is ON, the screen will pause after 23 continuous lines are displayed.
- Press the Left shift key to scroll another 23 lines or the Right
- shift key to scroll one line; or press Scroll Lock again to turn OFF
- the lock and the screen will scroll uninterrupted.*
-
- ;----------------------------------------------------------------------------;
- ;This program intercepts calls to the VIDEO_IO routines. Commands to scroll
- ;the screen will be intercepted; all others passed through. This routine is
- ;attached to DOS.
- ;
- ;Program by John Socha, 'Softalk', May 1983, pp. 38-49
- ;
- ;keyed in by Lee M Buck, Arlington VA
- ;
- ;----------------------------------------------------------------------------;
-
-
- ;----------------------------------------------------------------------------;
- ;Interrupt vectors for video and keyboard routines
- ;----------------------------------------------------------------------------;
-
- VECTORS SEGMENT AT 0
- ORG 10H*4
- VIDEO_INT LABEL DWORD
- ORG 16H*4
- KEYBOARD_INT LABEL DWORD
- VECTORS ENDS
-
-
- ;----------------------------------------------------------------------------;
- ;ROM BIOS data area for keyboard
- ;
- ;Contents of KB_FLAG - bits 7 to 0
- ;<--- --- --- --- --- --- --- --->
- ; ^INS_STATE ^NUM_STATE ^ALT_SHIFT ^LEFT_SHIFT
- ; ^CAPS_STATE ^SCROLL_STATE ^CTL_STATE ^RIGHT_SHIFT
- ;----------------------------------------------------------------------------;
-
- ROM_BIOS_DATA SEGMENT AT 40H
- ORG 17H
- KB_FLAG DB ? ;Bit 4 set for scroll lock
- ROM_BIOS_DATA ENDS
-
-
- ;----------------------------------------------------------------------------;
- ;Initialize vectors and attach to DOS
- ;----------------------------------------------------------------------------;
-
- CSEG SEGMENT PARA
- ASSUME CS:CSEG
- ORG 100H ;Set starting point for COM file
- BEGIN: JMP INIT_VECTORS ;Initialize INT 10H and attach to DOS
-
-
- ;----------------------------------------------------------------------------;
- ;These memory locations store the addresses of the ROM routines for video and
- ;keyboard I/O routines
- ;----------------------------------------------------------------------------;
-
- ROM_VIDEO_IO DD ;Address of the ROM routines
- ROM_KEYBOARD_IO DD
- SCROLL_COUNT DB 0 ;Lines scrolled since last pause
- LAST_LOCK_STATE DB 0 ;0 if scrl lock off last time checked
- MAX_LINES DB 23 ;Scroll by 23 lines, leaving one old
- ;line at top before pausing
- LAST_LINE DB ;Last line cursor was on
-
- ;----------------------------------------------------------------------------;
- ;This routine intercepts all calls to the VIDEO_IO routine in ROM.
- ;Scroll Lock:
- ; OFF This routine passes control directly to the ROM BIOS
- ; routine.
- ; ON Functions other than SCROLL UP or SCROLL DOWN are
- ; passed directly to the ROM routines. Otherwise, this
- ; routine increments the scroll count and checks to see
- ; if it exceeds the page size of 23 lines (MAX_LINES).
- ; If so, loop until either shift key pressed.
- ; Left shift allows scroll of whole window
- ; Right shift scrolls one line.
- ;--------------------------------------------------------------------------;
-
- INTERCEPT_VIDEO PROC FAR
- ASSUME CS:CSEG
- STI ;Turn on interrupts again
- PUSH DS ;Save registers used
- PUSH BX
- PUSH AX
-
- ASSUME DS:ROM_BIOS_DATA
- MOV BX,ROM_BIOS_DATA
- MOV DS,BX
- MOV AL,KB_FLAG ;Check state of scroll lock key
- AND AL,10H ;Isolate scroll lock bit
- ASSUME DS:CSEG
- MOV BX,CS ;Data segment for variables (above)
- MOV DS,BX
- CMP AL,LAST_LOCK_STATE
- JE UN_CHANGED ;Scroll lock key hasn't changed
- MOV BL,MAX_LINES ;Scroll lock key has changed, set to
- MOV SCROLL_COUNT,BL ;MAX_LINES to stop scrolling
- MOV LAST_LOCK_STATE,AL ;Save the new scroll lock state
- PUSH CX ;Now read current cursor position and
- PUSH DX ;save in LAST_LINE so SCROLLK won't
- PUSH AX ;freeze in the middle of a line
- MOV AH,3
- MOV BH,0
- PUSHF
- CALL ROM_VIDEO_IO ;This is a pseudo INT 10H call to BIOS
- MOV LAST_LINE,DH ;to find old cursor position and save
- POP AX ;in LAST_LINE. (see Tech. Ref. A-43)
- POP DX
- POP CX
- UN_CHANGED:
- XCHG AX,BX ;Recover function (AH) and retain scroll lock
- POP AX
- OR BL,BL ;Is scroll lock on?
- JZ TO_VIDEO_IO ;No, jump to the ROM VIDEO_IO routine
- ;-----------------------;
- ;Scroll Lock ON ;
- ;-----------------------;
- CMP AH,2 ;Check for SET CURSOR POSITION function
- JNE NOPE
- CMP DH,LAST_LINE ;Is the cursor being moved to the next line?
- MOV LAST_LINE,DH ;Save new cursor line
- JLE TO_VIDEO_IO ;No, jump to ROM routine
- JMP SHORT CHECK_LOCK ;Yes, see if need to lock
- NOPE: CMP AH,6 ;Scroll up?
- JNE TO_VIDEO_IO ;No, go to ROM routines
- CHECK_LOCK:
- INC SCROLL_COUNT ;Take care of scroll lock
- MOV BH,MAX_LINES
- CMP SCROLL_COUNT,BH ;Have we scrolled more than MAX_LINES?
- JL TO_VIDEO_IO ;Nope, it's ok to scroll
- ;Yes, wait until a shift key is hit
- MOV BL,BH ;Set SCROLL_COUNT to MAX_LINES-1
- DEC BL ;so we can print one more line
- MOV SCROLL_COUNT,BL
- ASSUME DS:ROM_BIOS_DATA
- MOV BX,ROM_BIOS_DATA
- MOV DS,BX
- LOOP: MOV BL,KB_FLAG ;Wait for left or right shift key push
- TEST BL,10H ;Is scroll lock still on?
- JZ TO_VIDEO_IO
- AND BL,3 ;Pick off shift key info
- JZ LOOP ;Stay in loop until shift key pressed
- CMP BL,1 ;Right shift key pressed?
- JE SCROLL_LINE ;Yes, allow scroll of one line
- ;No, must be left shift key, so reset scroll count
- XOR BX,BX
- MOV SCROLL_COUNT,BL
- SCROLL_LINE:
-
- TO_VIDEO_IO:
- POP BX ;Restore BX register
- PUSHF
- CALL ROM_VIDEO_IO ;Perform a pseudo INT 10H call to BIOS
- POP DS
- IRET ;interrupt Return
- INTERCEPT_VIDEO ENDP
-
-
- ;----------------------------------------------------------------------------;
- ;This routine intercepts all calls to KEYBOARD_IO
- ;If the keyboard function calls for a read (AH=0) then reset the scroll count
- ;----------------------------------------------------------------------------;
-
- INTERCEPT_KEYBOARD PROC FAR
- ASSUME CS:CSEG,DS:CSEG
- STI ;Turn interrupts on
- PUSH DS ;Save registers used by this routine
- PUSH BX
- MOV BX,CS ;Set up data segment for variables
- MOV DS,BX
- OR AH,AH ;Check to see if AH=0
- JNZ KB1 ;Nope, branch to keyboard I/O
- XOR BX,BX ;Yes, set scroll count to 0
- MOV SCROLL_COUNT,BL
- KB1: POP BX ;Restore BX register
- ASSUME DS:NOTHING
- POP DS
- JMP ROM_KEYBOARD_IO ;Jump to keyboard routine and return
- ;directly to the routine that called
- ;this one
- INTERCEPT_KEYBOARD ENDP
-
- ;----------------------------------------------------------------------------;
- ;This section of code saves the old interrupt vectors for the keyboard and
- ;video I/O routines. These vectors are replaced by the addresses of
- ;INTERCEPT_VIDEO and INTERCEPT_KEYBOARD PROCS above.
- ;----------------------------------------------------------------------------;
-
- INIT_VECTORS PROC NEAR
- ASSUME CS:CSEG,DS:CSEG
- MOV AH,3 ;Set LAST_LINE to cursor line number
- XOR BH,BH
- INT 10H
- MOV LAST_LINE,DH
-
- ASSUME CS:CSEG,DS:VECTORS
- MOV AX,VECTORS
- MOV DS,AX
-
- MOV AX,VIDEO_INT ;Save the ROM routine address
- MOV ROM_VIDEO_IO,AX
- MOV AX,VIDEO_INT[2]
- MOV ROM_VIDEO_IO[2],AX
- MOV AX,OFFSET INTERCEPT_VIDEO ;Set video INT 10H to point to
- MOV VIDEO_INT,AX ;INTERCEPT_VIDEO PROC above.
- MOV VIDEO_INT[2],CS
-
- MOV AX,KEYBOARD_INT ;Save the ROM routine address
- MOV ROM_KEYBOARD_IO,AX
- MOV AX,KEYBOARD_INT[2]
- MOV ROM_KEYBOARD_IO[2],AX
- MOV AX,OFFSET INTERCEPT_KEYBOARD ;Set keyboard INT 16H to point
- MOV KEYBOARD_INT,AX ;to INTERCEPT_KEYBOARD PROC
- MOV KEYBOARD_INT[2],CS
-
- MOV DX,OFFSET INIT_VECTORS ;End of resident portion
- INT 27H ;Terminate but stay resident
- INIT_VECTORS ENDP
-
- CSEG ENDS
- END BEGIN
-
-