/
shot.asm
168 lines (132 loc) · 2.49 KB
/
shot.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
.model tiny
.stack
.386
KBD_PORT EQU 060h
F10_SCAN EQU 044h
.code
.startup
jmp install
old_keyboard DD ?
old_timer DD ?
buffer_waiting DB 0
buffer DB 80*50*2 DUP(?)
filename DB "C:\screen.ans",0
indos_seg DW ?
indos_offs DW ?
ctrl_pushed DB 0
; save screen from ds:dx to file
save PROC
; create or truncate file
push ds
push dx
; create and open the file
push cs ; our data is in cs
pop ds
mov ah, 03Ch ; truncate/create and open
xor cx, cx ; file attributes
mov dx, OFFSET filename
int 21h
pop dx
pop ds
; write from memory (screen or buffer) to file
mov bx, ax ; file handle
mov ax, 04000h ; write to file
mov cx, 80*25*2
int 21h
; close file
mov ah, 03Eh
int 21h
ret
save ENDP
keyboard PROC FAR
pusha
; is this keypress F10?
in al, KBD_PORT
cmp al, F10_SCAN
jne done
; is DOS busy?
mov es, cs:indos_seg
mov bx, cs:indos_offs
cmp BYTE PTR es:[bx], 0
jnz capture
; save directly from screen to file
mov dx, 0B800h
mov ds, dx
xor dx, dx
call save
jmp done
capture: ; copy from screen into buffer to save later
mov ax, 0B800h ; from video memory
mov ds, ax
xor si, si
mov ax, cs ; to data
mov es, ax
mov di, OFFSET buffer
; perform the copy
mov cx, 80*25
@@: lodsw
stosw
loop @b
; signify we have data waiting in buffer
inc cs:buffer_waiting
; call the old keyboard handler
done: pushf
call cs:old_keyboard
sti
popa
iret
keyboard ENDP
timer PROC
pusha
; if we have data waiting in the buffer
cmp cs:buffer_waiting, 0
je done
; and DOS is not busy
mov es, cs:indos_seg
mov bx, cs:indos_offs
cmp BYTE PTR es:[bx], 0
jnz done
; save the file
mov dx, cs
mov ds, dx
mov dx, OFFSET buffer
call save
dec cs:buffer_waiting
; call old timer interrupt handler
done: pushf
call cs:old_timer
popa
iret
timer ENDP
install PROC
; get the offset to indos flag
mov ah, 034h
int 21h
mov indos_seg, es
mov indos_offs, bx
; get old keyboard interrupt and save it
mov ax, 3509h
int 21h
mov WORD PTR old_keyboard[0], bx
mov WORD PTR old_keyboard[2], es
; install new keyboard interrupt
mov ax, 2509h
mov dx, OFFSET keyboard
int 21h
; get old timer interrupt and save it
mov ax, 3508h
int 21h
mov WORD PTR old_timer[0], bx
mov WORD PTR old_timer[2], es
; install new timer interrupt
mov ax, 2508h
mov dx, OFFSET timer
int 21h
; TSR
mov dx, OFFSET install
shr dx, 4
inc dx
mov ax, 3100h
int 21h
install ENDP
END