summaryrefslogtreecommitdiff
path: root/v4.0/src/DEV/XMA2EMS/I13HOOK.INC
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/DEV/XMA2EMS/I13HOOK.INC')
-rw-r--r--v4.0/src/DEV/XMA2EMS/I13HOOK.INC449
1 files changed, 449 insertions, 0 deletions
diff --git a/v4.0/src/DEV/XMA2EMS/I13HOOK.INC b/v4.0/src/DEV/XMA2EMS/I13HOOK.INC
new file mode 100644
index 0000000..2f981c2
--- /dev/null
+++ b/v4.0/src/DEV/XMA2EMS/I13HOOK.INC
@@ -0,0 +1,449 @@
1
2include MSBDS.INC ;include BDS struc ;an000; dms;
3
4
5
6
7;=========================================================================
8; I13_Handler - This routine is the main driver of the
9; INT 13h hook.
10;=========================================================================
11
12I13_Handler proc far ; ;an000; dms;
13
14 jmp I13_Handler_Start
15
16
17I13_Max_Head db ? ;max head count on drive ;an000; dms;
18I13_SPT db ? ;max sectors/track count ;an000; dms;
19I13_BPS dw ? ;max number bytes/sector ;an000; dms;
20I13_Bytes_Per_Para dw 10h ;number of bytes per paragraph ;an000; dms;
21I13_Bytes_Per_EMS_Page dw 4000h ;bytes per EMS page ;an000; dms;
22I13_Paras_Per_Sector dw ? ;paras per sector ;an000; dms;
23I13_DD_Per_Sector dw ? ;double words per sector ;an000; dms;
24I13_Operation db ? ;INT 13h function ;an000; dms;
25I13_Sector_Count db ? ;sector count ;an000; dms;
26I13_Track_Number dw ? ;track number ;an000; dms;
27I13_Sector_Number db ? ;sector number ;an000; dms;
28I13_Head_Number db ? ;head number ;an000; dms;
29I13_Drive_Number db ? ;drive number ;an000; dms;
30I13_Sectors_To_Trf db 1 ;current sectors to trf ;an000; dms;
31I13_Curr_Trf_Cnt db ? ;total transfer count in secs ;an000; dms;
32I13_Trf_Off dw ? ;current address for trf ;an000; dms;
33I13_Trf_Seg dw ? ;an000; dms;
34I13_512_Byte_Buffer db 512 dup(0) ;buffer for sector ;an000; dms;
35
36I13_Handler_Start:
37
38 sti ;ints on ;an000; dms;
39 cmp ah,02h ;read operation? ;an000; dms;
40 je I13_Handler_Get_Parms ;yes - get drive parms ;an000; dms;
41
42 cmp ah,03h ;write operation? ;an000; dms;
43 je I13_Handler_Get_Parms ;yes - get drive parms ;an000; dms;
44
45 jmp cs:IntV13 ;neither - go to old INT 13h ;an000; dms;
46
47I13_Handler_Get_Parms:
48
49 call I13_Get_Dev_Parms ;get device parms for this drive;an000; dms;
50 jnc I13_Handler_Range_Ck ;we have device data ;an000; dms;
51 jmp cs:IntV13 ;go to old INT 13h vector ;an000; dms;
52
53I13_Handler_Range_Ck:
54
55 call I13_Target_Source_Range_Ck ;crosses the 640k boundary? ;an000; dms;
56 jc I13_Handler_Request_Break ;break up the request ;an000; dms;
57 jmp cs:IntV13 ;go to old INT 13h vector ;an000; dms;
58
59I13_Handler_Request_Break:
60
61 call I13_Request_Break_Up ;break up I13 request ;an000; dms;
62
63 ret 2 ;return to caller ;an000; dms;
64 ;clear the flags from the stack
65 ; and pass back ours
66I13_Handler endp ; ;an000; dms;
67
68
69
70;=========================================================================
71; I13_Target_Source_Range_Ck - This routine determines if the
72; target or source resides in an EMS
73; page.
74;
75; Inputs : ES:BX - Source/target address
76;
77; Outputs : CY - if address resides in an EMS page
78; NC - address not in an EMS page
79;=========================================================================
80
81
82I13_Target_Source_Range_Ck proc near ; ;an000; dms;
83
84 push ax ;save regs ;an000; dms;
85 push bx ; ;an000; dms;
86 push cx ; ;an000; dms;
87 push si ; ;an000; dms;
88 push ds ; ;an000; dms;
89
90 mov ax,cs ;get cs addressibility ;an000; dms;
91 mov ds,ax ; ;an000; dms;
92 mov si,offset cs:Map_Table ;point to the map table ;an000; dms;
93
94 mov cx,cs:Map_Count ;get the number of phys. pages ;an000; dms;
95
96I13_Target_Source_Loop:
97
98 cmp cx,0 ;at end? ;an000; dms;
99 je I13_Target_Source_Not_EMS_Page ;yes - source/target not in pg ;an000; dms;
100
101 mov ax,ds:[si].Phys_Page_Segment ;get the segment value ;an000; dms;
102 mov bx,es ; ;an000; dms;
103 cmp bx,ax ;source/target > EMS page? ;an000; dms;
104 jb I13_Target_Source_Not_EMS_Page ;no - we are OK for old INT 13 ;an000; dms;
105 ;must be >= EMS page
106
107 add ax,400h ;get end address of EMS page ;an000; dms;
108 cmp bx,ax ;source/target < end of EMS pg? ;an000; dms;
109 jb I13_Target_Source_In_EMS_Page ;yes - we are in a page ;an000; dms;
110
111 add si,type Mappable_Phys_Page_Struct ;adjust pointer to next page ;an000; dms;
112 dec cx ;dec counter ;an000; dms;
113
114 jmp I13_Target_Source_Loop ;continue loop ;an000; dms;
115
116I13_Target_Source_Not_EMS_Page:
117
118 clc ;flag not in EMS page ;an000; dms;
119 jmp I13_Target_Source_Exit ;exit routine ;an000; dms;
120
121I13_Target_Source_In_EMS_Page:
122
123 stc ;flag in an EMS page ;an000; dms;
124
125I13_Target_Source_Exit:
126
127 pop ds ;restore regs ;an000; dms;
128 pop si ; ;an000; dms;
129 pop cx ; ;an000; dms;
130 pop bx ; ;an000; dms;
131 pop ax ; ;an000; dms;
132
133 ret ; ;an000; dms;
134
135I13_Target_Source_Range_Ck endp ; ;an000; dms;
136
137
138;=========================================================================
139; I13_Request_Break_Up - Break up the INT 13h request onto 16k
140; boundaries.
141;
142; Inputs : AH - 02 (Read)
143; 03 (Write)
144; AL - Sector count
145; CH - Track number
146; CL - Sector number
147; DH - Head number
148; DL - Drive number
149; ES:BX - Buffer address
150;
151; Outputs : Data transferred
152;=========================================================================
153
154
155I13_Request_Break_Up proc near ; ;an000; dms;
156
157 push bx ;save regs ;an000; dms;
158 push cx ; ;an000; dms;
159 push dx ; ;an000; dms;
160 push di ; ;an000; dms;
161 push si ; ;an000; dms;
162 push ds ; ;an000; dms;
163 push es ; ;an000; dms;
164
165
166 mov cs:I13_Trf_Seg,es ;save segment ;an000; dms;
167 mov cs:I13_Trf_Off,bx ;save offset ;an000; dms;
168 mov cs:I13_Curr_Trf_Cnt,0 ;init transfer count ;an000; dms;
169 mov cs:I13_Operation,ah ;save operation ;an000; dms;
170 mov cs:I13_Sector_Count,al ;save sector count ;an000; dms;
171
172
173 mov byte ptr cs:I13_Track_Number,ch ;save starting track number ;an000; dms;
174 mov ch,cl ;xchg bytes ;an000; dms;
175 shr ch,1 ;shift 6 bits ;an000; dms;
176 shr ch,1 ; ;an000; dms;
177 shr ch,1 ; ;an000; dms;
178 shr ch,1 ; ;an000; dms;
179 shr ch,1 ; ;an000; dms;
180 shr ch,1 ; ;an000; dms;
181
182 mov byte ptr cs:I13_Track_Number[+1],ch ;high byte for cylinder ;an000; dms;
183 and cl,00111111b ;get bits 0-5 for sector number ;an000; dms;
184
185 mov cs:I13_Sector_Number,cl ;save starting sector number ;an000; dms;
186 mov cs:I13_Head_Number,dh ;save starting head number ;an000; dms;
187 mov cs:I13_Drive_Number,dl ;save drive number ;an000; dms;
188
189 mov cl,cs:I13_Sector_Count ;while sectors ;an000; dms;
190
191 cmp cs:I13_Operation,02h ;read? ;an000; dms;
192 jne I13_Request_Write ;must be a write ;an000; dms;
193
194I13_Request_Read:
195
196 cmp cl,0 ;at end? ;an000; dms;
197 je I13_Request_Success ;exit we are done ;an000; dms;
198
199 lea bx,cs:I13_512_Byte_Buffer ;point to 512 byte buffer ;an000; dms;
200 mov ax,cs ;pass cs to es ;an000; dms;
201 mov es,ax ; ;an000; dms;
202
203 call I13_Invoke ;do the INT 13h to our buffer ;an000; dms;
204 jc I13_Request_Failed ;signal failure ;an000; dms;
205 mov ax,cs ;point to our buffer to the ;an000; dms;
206 mov ds,ax ; transfer ;an000; dms;
207 mov si,offset cs:I13_512_Byte_Buffer; ;an000; dms;
208
209 mov es,cs:I13_Trf_Seg ;restore seg to target ;an000; dms;
210 mov di,cs:I13_Trf_Off ;restore off to target ;an000; dms;
211
212 push cx ;save cx across move ;an000; dms;
213 cld ;do a forward move ;an000; dms;
214 mov cx,cs:I13_DD_Per_Sector ; for 128 dd's ;an000; dms;
215 db 66h ;op code for dd word move ;an000; dms;
216 rep movsw ;do the move - wow that was fast;an000; dms;
217 pop cx ;restore it ;an000; dms;
218
219 call I13_Adjust ;adjust our pointers ;an000; dms;
220
221 dec cl ;decrease sector counter ;an000; dms;
222 jmp I13_Request_Read ;continue loop ;an000; dms;
223
224I13_Request_Write:
225
226 cmp cl,0 ;at end? ;an000; dms;
227 je I13_Request_Success ;exit we are done ;an000; dms;
228
229 mov ax,cs ;point to 512 byte buffer ;an000; dms;
230 mov es,ax ; ;an000; dms;
231 mov di,offset cs:I13_512_Byte_Buffer; ;an000; dms;
232
233 mov ds,cs:I13_Trf_Seg ;get source segment ;an000; dms;
234 mov si,cs:I13_Trf_Off ;get source offset ;an000; dms;
235
236 push cx ;save cx across move ;an000; dms;
237 cld ;do a forward move ;an000; dms;
238 mov cx,cs:I13_DD_Per_Sector ; for 128 dd's ;an000; dms;
239 db 66h ;op code for dd word move ;an000; dms;
240 rep movsw ;do the move - wow that was fast;an000; dms;
241 pop cx ;restore it ;an000; dms;
242
243 lea bx,cs:I13_512_Byte_Buffer ;point to 512 byte buffer ;an000; dms;
244 mov ax,cs ;pass cs to es ;an000; dms;
245 mov es,ax ; ;an000; dms;
246
247 call I13_Invoke ;do the INT 13h to our buffer ;an000; dms;
248 jc I13_Request_Failed ;signal failure ;an000; dms;
249 call I13_Adjust ;adjust our pointers ;an000; dms;
250
251 dec cl ;decrease sector counter ;an000; dms;
252 jmp I13_Request_Write ;continue loop ;an000; dms;
253
254I13_Request_Failed:
255
256 jmp I13_Request_Exit ;exit on error ;an000; dms;
257
258
259I13_Request_Success:
260
261 xor ax,ax ;clear status byte ;an000; dms;
262
263I13_Request_Exit:
264
265 pop es ;restore regs ;an000; dms;
266 pop ds ; ;an000; dms;
267 pop si ; ;an000; dms;
268 pop di ; ;an000; dms;
269 pop dx ; ;an000; dms;
270 pop cx ; ;an000; dms;
271 pop bx ; ;an000; dms;
272
273
274 ret ; ;an000; dms;
275
276I13_Request_Break_Up endp ; ;an000; dms;
277
278
279
280;=========================================================================
281; I13_Adjust - This routine adjusts the needed fields for
282; the next iteration of INT 13h.
283;
284; Inputs : I13_Sectors_To_Trf - Sectors just read/written
285; I13_Sector_Number - Starting sector number for trf
286; I13_Head_Number - Starting head number for trf
287; I13_Track_Number - Starting track number for trf
288;
289; Outputs : I13_Sector_Number - New starting sector for trf
290; I13_Head_Number - New starting head for trf
291; I13_Track_Number - New starting track for trf
292;=========================================================================
293
294
295I13_Adjust proc near ;adjust values ;an000; dms;
296
297 push ax ;save regs ;an000; dms;
298
299 inc cs:I13_Sector_Number ;next sector ;an000; dms;
300 mov al,cs:I13_Sector_Number ; ;an000; dms;
301 cmp al,cs:I13_SPT ;> sectors on track? ;an000; dms;
302 jna I13_Adjust_Exit ;no ;an000; dms;
303 mov cs:I13_Sector_Number,1 ;yes - start at next ;an000; dms;
304 inc cs:I13_Head_Number ;next head ;an000; dms;
305 mov al,cs:I13_Head_Number ; ;an000; dms;
306 cmp al,cs:I13_Max_Head ;> head count ;an000; dms;
307 jb I13_Adjust_Exit ;no ;an000; dms;
308 mov cs:I13_Head_Number,0 ;yes - head 0 ;an000; dms;
309 inc cs:I13_Track_Number ;next track ;an000; dms;
310
311I13_Adjust_Exit:
312
313 mov ax,cs:I13_Paras_Per_Sector ;get bytes per sector ;an000; dms;
314 add cs:I13_Trf_Seg,ax ;adjust segment ;an000; dms;
315
316 pop ax ;restore regs ;an000; dms;
317
318 ret ; ;an000; dms;
319
320I13_Adjust endp ; ;an000; dms;
321
322
323;=========================================================================
324; I13_Invoke - This routine sets up the regs for the INT 13h
325; and invokes it for the sector we need.
326;
327; Inputs : I13_Operation - read/write
328; I13_Track_Number - cylinder to read/write
329; I13_Sector_Number - starting sector for read/write
330; I13_Head_Number - starting head
331; I13_Drive_Number - starting drive
332;
333; Outputs : NC - good read/write
334; CY - bad read/write
335;=========================================================================
336
337I13_Invoke proc near ;invoke INT 13h ;an000; dms;
338
339 push bx ;save regs ;an000; dms;
340 push cx ; ;an000; dms;
341 push dx ; ;an000; dms;
342
343 mov ah,cs:I13_Operation ;get function call ;an000; dms;
344 mov al,cs:I13_Sectors_To_Trf ;get sectors to transfer ;an000; dms;
345
346 mov ch,byte ptr cs:I13_Track_Number ;get track number ;an000; dms;
347 mov cl,byte ptr cs:I13_Track_Number[+1] ;get high 2 bits ;an000; dms;
348 shl cl,1 ;put bit is positions 6&7 ;an000; dms;
349 shl cl,1 ; ;an000; dms;
350 shl cl,1 ; ;an000; dms;
351 shl cl,1 ; ;an000; dms;
352 shl cl,1 ; ;an000; dms;
353 shl cl,1 ; ;an000; dms;
354 or cl,cs:I13_Sector_Number ;place the sector number in cl ;an000; dms;
355
356 mov dh,cs:I13_Head_Number ;get head number ;an000; dms;
357 mov dl,cs:I13_Drive_Number ;get drive number ;an000; dms;
358 pushf
359 call cs:IntV13 ;go to old vector ;an000; dms;
360 inc cs:I13_Curr_Trf_Cnt ;increment counter ;an000; dms;
361
362 pop dx ;restore regs ;an000; dms;
363 pop cx ; ;an000; dms;
364 pop bx ; ;an000; dms;
365
366 ret ; ;an000; dms;
367
368I13_Invoke endp ; ;an000; dms;
369
370
371;=========================================================================
372; I13_Get_Dev_Parms - This routine obtains the device parameters for
373; the drive being accessed for the INT 13h.
374;
375; Inputs : DL - drive number
376;
377; Outputs : I13_Max_Head - max head count on drive
378; I13_SPT - max sectors/track count for drive
379; CY - error
380; NC - no error
381;=========================================================================
382
383
384
385I13_Get_Dev_Parms proc near ;get sectors/track & head cnt. ;an000; dms;
386
387 push ax ;save regs ;an000; dms;
388 push bx ; ;an000; dms;
389 push cx ; ;an000; dms;
390 push dx ; ;an000; dms;
391 push di ; ;an000; dms;
392 push ds ; ;an000; dms;
393
394 mov ax,0803h ;get the BDS table ;an000; dms;
395 int 2fh ; ;an000; dms;
396
397I13_Get_Dev_Next_Entry:
398
399 cmp ds:[di].Drivenum,dl ;do we have our drive? ;an000; dms;
400 je I13_Get_Dev_Save_Parms ;yes get data ;an000; dms;
401 cmp word ptr ds:[di].Link[+0],-1 ;last entry in list? ;an000; dms;
402 je I13_Get_Dev_Parms_Error_Exit ;yes - did not find drive ;an000; dms;
403 mov ax,word ptr ds:[di].Link[+0] ;get offset of next entry ;an000; dms;
404 mov bx,word ptr ds:[di].Link[+2] ;get segment of next entry ;an000; dms;
405 mov ds,bx ;stuff into ds:di ;an000; dms;
406 mov di,ax ; ;an000; dms;
407 jmp I13_Get_Dev_Next_Entry ;continue ;an000; dms;
408
409I13_Get_Dev_Save_Parms:
410
411 mov ax,ds:[di].BytePerSec ;get byte count per sector ;an000; dms;
412 mov cs:I13_BPS,ax ; ;an000; dms;
413
414 xor dx,dx ;clear high word ;an000; dms;
415 div cs:I13_Bytes_Per_Para ;get number of paras in sector ;an000; dms;
416 mov cs:I13_Paras_Per_Sector,ax ;save it ;an000; dms;
417 shl ax,1 ;get DD's per sector ;an000; dms;
418 shl ax,1 ; ;an000; dms;
419 mov cs:I13_DD_Per_Sector,ax ; ;an000; dms;
420
421 mov ax,ds:[di].SecLim ;get sectors per track ;an000; dms;
422 mov cs:I13_SPT,al ; ;an000; dms;
423
424 mov ax,ds:[di].HdLim ;get max head count ;an000; dms;
425 mov cs:I13_Max_Head,al ; ;an000; dms;
426
427 clc ;flag data found ;an000; dms;
428
429 jmp I13_Get_Dev_Parms_Exit ; ;an000; dms;
430
431
432I13_Get_Dev_Parms_Error_Exit:
433
434 stc ;flag no data found ;an000; dms;
435
436I13_Get_Dev_Parms_Exit:
437
438 pop ds ;restore regs ;an000; dms;
439 pop di ; ;an000; dms;
440 pop dx ; ;an000; dms;
441 pop cx ; ;an000; dms;
442 pop bx ; ;an000; dms;
443 pop ax ; ;an000; dms;
444
445 ret ; ;an000; dms;
446
447I13_Get_Dev_Parms endp ; ;an000; dms;
448
449