📄 grabscrn.asm
字号:
; GRABSCRN.ASM
;
; A short TSR to capture the current display screen and display it later.
;
; Note that this code does not patch into int 2Fh (multiplex interrupt)
; nor can you remove this code from memory except by rebooting.
; If you want to be able to do these two things (as well as check for
; a previous installation), see the chapter on resident programs. Such
; code was omitted from this program because of length constraints.
;
;
; cseg and EndResident must occur before the standard library segments!
cseg segment para public 'code'
OldInt9 dword ?
ScreenSave byte 4096 dup (?)
cseg ends
; Marker segment, to find the end of the resident section.
EndResident segment para public 'Resident'
EndResident ends
.xlist
include stdlib.a
includelib stdlib.lib
.list
RShiftScan equ 36h
LShiftScan equ 2ah
; Bits for the shift/modifier keys
RShfBit equ 1
LShfBit equ 2
KbdFlags equ <byte ptr ds:[17h]>
byp equ <byte ptr>
; Screen segment address. This value is for color displays only.
; Change to B000h if you want to use this program on a mono display.
ScreenSeg equ 0B800h
cseg segment para public 'code'
assume ds:nothing
; MyInt9- INT 9 ISR. This routine reads the keyboard port to see
; if a shift key scan code just came along. If the right
; shift bit is set in KbdFlags the a left shift key scan
; code comes along, we want to copy the data from our
; internal buffer to the screen's memory. If the left shift
; bit is set and a right shift key scan code comes along,
; we want to copy the screen memory into our local array.
; In any case (including none of the above), we always transfer
; control to the original INT 9 handler.
MyInt9 proc far
push ds
push ax
mov ax, 40h
mov ds, ax
in al, 60h ;Read the keyboard port.
cmp al, RShiftScan ;Right shift just go down?
je DoRight
cmp al, LShiftScan ;How about the left shift?
jne QuitMyInt9
; If this is the left scan code, see if the right shift key is already
; down.
test KbdFlags, RShfBit
je QuitMyInt9 ;Branch if no
; Okay, right shift was down and we just saw left shift, copy our local
; data back to screen memory:
pushf
push es
push cx
push di
push si
mov cx, 2048
mov si, cs
mov ds, si
lea si, ScreenSave
mov di, ScreenSeg
mov es, di
xor di, di
jmp DoMove
; Okay, we just saw the right shift key scan code, see if the left shift
; key is already down. If so, save the current screen data to our local
; array.
DoRight: test KbdFlags, LShfBit
je QuitMyInt9
pushf
push es
push cx
push di
push si
mov cx, 2048
mov ax, cs
mov es, ax
lea di, ScreenSave
mov si, ScreenSeg
mov ds, si
xor si, si
DoMove: cld
rep movsw
pop si
pop di
pop cx
pop es
popf
QuitMyInt9:
pop ax
pop ds
jmp OldInt9
MyInt9 endp
Main proc
assume ds:cseg
mov ax, cseg
mov ds, ax
print
byte "Screen capture TSR",cr,lf
byte "Pressing left shift, then right shift, captures "
byte "the current screen.",cr,lf
byte "Pressing right shift, then left shift, displays "
byte "the last captured screen.",cr,lf
byte 0
; Patch into the INT 9 interrupt vector. Note that the
; statements above have made cseg the current data segment,
; so we can store the old INT 9 value directly into
; the OldInt9 variable.
cli ;Turn off interrupts!
mov ax, 0
mov es, ax
mov ax, es:[9*4]
mov word ptr OldInt9, ax
mov ax, es:[9*4 + 2]
mov word ptr OldInt9+2, ax
mov es:[9*4], offset MyInt9
mov es:[9*4+2], cs
sti ;Okay, ints back on.
; We're hooked up, the only thing that remains is to terminate and
; stay resident.
print
byte "Installed.",cr,lf,0
mov ah, 62h ;Get this program's PSP
int 21h ; value.
mov dx, EndResident ;Compute size of program.
sub dx, bx
mov ax, 3100h ;DOS TSR command.
int 21h
Main endp
cseg ends
sseg segment para stack 'stack'
stk db 1024 dup ("stack ")
sseg ends
zzzzzzseg segment para public 'zzzzzz'
LastBytes db 16 dup (?)
zzzzzzseg ends
end Main
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -