summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/DISK3.ASM
blob: 306b34ea66226b69c97faac7629fadc5592d932a (plain) (blame)
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
;	SCCSID = @(#)disk3.asm	1.3 85/07/26
;	SCCSID = @(#)disk3.asm	1.3 85/07/26
TITLE	DISK3 - Disk utility routines
NAME	Disk3
; Low level Read and write routines for local SFT I/O on files and devs
;
;   DISKWRITE
;   WRTERR
;
;   Revision history:
;
;    AN000 version 4.00 Jan. 1988
;

;
; get the appropriate segment definitions
;
.xlist
include dosseg.asm

CODE	SEGMENT BYTE PUBLIC  'CODE'
	ASSUME	SS:DOSGROUP,CS:DOSGROUP

.xcref
INCLUDE DOSSYM.INC
INCLUDE DEVSYM.INC
include version.inc
.cref
.list

Installed = TRUE

	i_need	THISSFT,DWORD
	i_need	DMAADD,DWORD
	i_need	SecClusPos,BYTE
	i_need	ClusNum,WORD
	i_need	Trans,BYTE
	i_need	BytPos,4
	i_need	SecPos,DWORD		  ;F.C. >32mb	;AN000;
	i_need	BytSecPos,WORD
	i_need	BytCnt1,WORD
	i_need	BytCnt2,WORD
	i_need	SecCnt,WORD
	i_need	ThisDPB,DWORD
	i_need	LastPos,WORD
	i_need	ValSec,WORD		  ;F.C. >32mb	       ;AN000;
	i_need	GrowCnt,DWORD
	i_need	ALLOWED,BYTE
	I_need	JShare,DWORD
	I_need	FSeek_drive,BYTE	  ; DOS 4.00	       ;AN000;
	I_need	FSeek_firclus,WORD	  ; DOS 4.00	       ;AN000;
	I_need	FSeek_logclus,WORD	  ; DOS 4.00	       ;AN000;
	I_need	HIGH_SECTOR,WORD	  ;F.C. >32mb	       ;AN000;
	I_need	HIGH_SECTOR_TEMP,WORD	  ;F.C. >32mb	       ;AN000;
	I_need	EXTERR,WORD			   ; DOS 4.00   ;AN000;
	I_need	EXTERR_LOCUS,BYTE		   ; DOS 4.00   ;AN000;
	I_need	EXTERR_ACTION,BYTE		   ; DOS 4.00   ;AN000;
	I_need	EXTERR_CLASS,BYTE		   ; DOS 4.00   ;AN000;
	I_need	EXITHOLD,DWORD			   ; DOS 4.00   ;AN000;
	I_need	DISK_FULL,BYTE			   ; DOS 4.00   ;AN000;
	I_need	SC_DRIVE,BYTE			   ; DOS 4.00   ;AN000;
	I_need	SC_CACHE_COUNT,WORD		   ; DOS 4.00   ;AN000;
	I_need	ThisDRV,BYTE			   ; DOS 4.00   ;AN000;
	I_need	User_In_AX,WORD 		   ; DOS 4.00   ;AN000;
	I_need	DOS34_FLAG,WORD 		   ; DOS 4.00   ;AN000;
	I_need	FIRST_BUFF_ADDR,WORD		   ; DOS 4.00   ;AN000;

IF	BUFFERFLAG
	EXTRN	SAVE_MAP:NEAR
	EXTRN	RESTORE_MAP:NEAR
	EXTRN	SAVE_USER_MAP:NEAR
	EXTRN	RESTORE_USER_MAP:NEAR
	i_need	BUF_EMS_SAFE_FLAG,BYTE
	i_need	BUF_EMS_MODE,BYTE
ENDIF

	

Break	<DISKWRITE -- PERFORM USER DISK WRITE>

; Inputs:
;	Outputs of SETUP
; Function:
;	Perform disk write
; Outputs:
;    Carry clear
;	CX = No. of bytes read
;	ES:DI point to SFT
;	SFT offset and cluster pointers updated
;    Carry set
;	CX = 0
;	ES:DI point to SFT
;	AX has error code

	procedure   DISKWRITE,NEAR
	DOSAssume   CS,<DS>,"DiskWrite"
	ASSUME	ES:NOTHING

	Assert	ISSFT,<ES,DI>,"DiskWrite"
	PUSH	ES:[DI.sf_firclus]	  ; set up 1st cluster # for FastSeek
	POP	[FSeek_firclus]

	invoke	CHECK_WRITE_LOCK	  ;IFS. check write lock		 ;AN000;
	JNC	WRITE_OK		  ;IFS. lock check ok			 ;AN000;
	return

WRTEOFJ:
	JMP	WRTEOF

WRITE_OK:
	AND	ES:[DI.sf_flags],NOT (sf_close_nodate OR devid_file_clean)
				; Mark file as dirty, clear no date on close
	LES	BP,[THISDPB]
	Assert	ISDPB,<ES,BP>,"DiskWrite/WriteOk"
	MOV	AL,ES:[BP.dpb_drive]   ; set up drive # for FastSeek
	MOV	[FSeek_drive],AL       ; 11/5/86 DOS 4.00

	invoke	BREAKDOWN
	MOV	AX,WORD PTR [BYTPOS]
	MOV	DX,WORD PTR [BYTPOS+2]
	JCXZ	WRTEOFJ 		;Make the file length = sf_position
	ADD	AX,CX
	ADC	DX,0			; AX:DX=byte after last byte accessed
;
; Make sure divide won't overflow
;
	MOV	BX,ES:[BP.dpb_sector_size]
;	CMP	DX,BX			;F.C. >32mb  16 bit sector check	;AN000;
;	JAE	WrtErr			;F.C. >32mb				;AN000;

	CALL	DIV32			;F.C. perform 32 bit divide		;AN000;
	MOV	BX,AX			; Save last full sector
	OR	DX,DX
	JNZ	CALCLUS
	SUB	AX,1			; AX must be zero base indexed		;AC000;
	SBB	[HIGH_SECTOR],0 	;F.C. >32mb				;AN000;
CALCLUS:
	PUSH	[HIGH_SECTOR]		;F.C. >32mb				;AN000;
	CALL	SHR32			;F.C. >32mb				;AN000;
	POP	[HIGH_SECTOR]		;F.C. >32mb				;AN000;

;	SHR	AX,CL			; Last cluster to be accessed
	PUSH	AX
	PUSH	DX			; Save the size of the "tail"
	PUSH	ES
	LES	DI,[THISSFT]
	Assert	ISSFT,<ES,DI>,"DiskWrite/CalClus"
	MOV	AX,WORD PTR ES:[DI.sf_size]
	MOV	DX,WORD PTR ES:[DI.sf_size+2]
	POP	ES



	PUSH	AX			;F.C. >32mb				;AN000;
	MOV	AX,DX			;F.C. >32mb				;AN000;
	XOR	DX,DX			;F.C. >32mb				;AN000;
	DIV	ES:[BP.dpb_sector_size] ;F.C. >32mb				;AN000;
	MOV	[HIGH_SECTOR_TEMP],AX	;F.C. >32mb				;AN000;
	POP	AX			;F.C. >32mb				;AN000;

	DIV	ES:[BP.dpb_sector_size]
	MOV	CX,AX		; Save last full sector of current file
	OR	DX,DX
	JZ	NORNDUP
	ADD	AX,1		; Round up if any remainder			;AC000;
	ADC	[HIGH_SECTOR_TEMP],0	;F.C. >32mb				;AN000;
NORNDUP:
	PUSH	[HIGH_SECTOR_TEMP]	;F.C. >32mb				;AN000;
	POP	WORD PTR [VALSEC+2]	;F.C. >32mb				;AN000;
	MOV	WORD PTR [VALSEC],AX  ;Number of sectors that have been written
	XOR	AX,AX
	MOV	WORD PTR [GROWCNT],AX
	MOV	WORD PTR [GROWCNT+2],AX
	POP	AX

	MOV	DI,[HIGH_SECTOR]	;F.C. >32mb				;AN000;
	CMP	DI,[HIGH_SECTOR_TEMP]	;F.C. >32mb				;AN000;
	JB	NOGROW			;F.C. >32mb				;AN000;
	JZ	lowsec			;F.C. >32mb				;AN000;
	SUB	BX,CX			;F.C. >32mb				;AN000;
	SBB	DI,[HIGH_SECTOR_TEMP]	;F.C. >32mb di:bx no. of sectors	;AN000;
	JMP	yesgrow 		;F.C. >32mb				;AN000;
lowsec:
	MOV	DI,0		;F.C. >32mb
	SUB	BX,CX		; Number of full sectors
	JB	NOGROW
	JZ	TESTTAIL
yesgrow:
	MOV	CX,DX
	XCHG	AX,BX
	MUL	ES:[BP.dpb_sector_size]  ; Bytes of full sector growth
	MOV	[HIGH_SECTOR],DX	 ;F.C. >32mb save dx			;AN000;
	MOV	[HIGH_SECTOR_TEMP],AX	 ;F.C. >32mb save ax			;AN000;
	MOV	AX,DI			 ;F.C. >32mb				;AN000;
	MUL	ES:[BP.dpb_sector_size]  ;F.C. >32mb do higher word multiply	;AN000;
	ADD	AX,[HIGH_SECTOR]	 ;F.C. >32mb add lower value		;AN000;
	MOV	DX,AX			 ;F.C. >32mb DX:AX is the result of	;AN000;
	MOV	AX,[HIGH_SECTOR_TEMP]	 ;F.C. >32mb a 32 bit multiply		;AN000;

	SUB	AX,CX		; Take off current "tail"
	SBB	DX,0		; 32-bit extension
	ADD	AX,BX		; Add on new "tail"
	ADC	DX,0		; ripple tim's head off
	JMP	SHORT SETGRW
HAVSTART:
;int 3
	MOV	CX,AX
	invoke	SKPCLP
	JCXZ	DOWRTJ
;;; 11/5/86 FastSeek
	MOV	[FSeek_logclus],DX   ; delete EOF (FFFFH)
	INC	[FSeek_logclus]
	invoke	FastSeek_Truncate    ;
;;; 11/5/86 FastSeek
	invoke	ALLOCATE
	JNC	DOWRTJ

	entry	WRTERR
	DOSAssume   CS,<DS>,"DiskWrite/WrtErr"
	ASSUME	ES:NOTHING

	MOV	AH,0FH				;MS. write/data/fail/abort	;AN000;
 entry WRTERR22
	MOV	AL,[THISDRV]			;MS.				;AN000;
	CALL	File_Handle_Fail_Error	;MS. issue disk full I24
	MOV	CX,0			;No bytes transferred
;	XOR	CX,CX			; will be deleted
	LES	DI,[THISSFT]
	Assert	ISSFT,<ES,DI>,"DiskWrite/WrtErr"
;	CLC
	return

DOWRTJ: JMP	DOWRT

ACC_ERRWJ:
	JMP	SET_ACC_ERRW

TESTTAIL:
	SUB	AX,DX
	JBE	NOGROW
	XOR	DX,DX
SETGRW:
	MOV	WORD PTR [GROWCNT],AX
	MOV	WORD PTR [GROWCNT+2],DX
NOGROW:
	POP	AX
	MOV	CX,[CLUSNUM]	; First cluster accessed
	invoke	FNDCLUS
	JC	ACC_ERRWJ
	MOV	[CLUSNUM],BX
	MOV	[LASTPOS],DX
;;; 11/5/86 FastSeek
	MOV	[FSeek_logclus],AX    ; set up last position
	SUB	AX,DX		; Last cluster minus current cluster
	JZ	DOWRT		; If we have last clus, we must have first
	JCXZ	HAVSTART	; See if no more data
	PUSH	CX		; No. of clusters short of first
	MOV	CX,AX

;;; 11/5/86 FastSeek
	CMP	[CLUSNUM],0	      ;FS. null file				;AN000;
	JZ	NULL_FILE	      ;FS. yes					;AN000;
	MOV	[FSeek_logclus],DX    ;FS. delete EOF (FFFFH)			;AN000;
	INC	[FSeek_logclus]       ;FS.					;AN000;
	invoke	FastSeek_Truncate     ;FS.					;AN000;
NULL_FILE:
;;; 11/5/86 FastSeek
	invoke	ALLOCATE
	POP	AX
	JC	WRTERR
	MOV	CX,AX
	MOV	DX,[LASTPOS]
	INC	DX
	DEC	CX
	JZ	NOSKIP
;;; 11/5/86 FastSeek
	MOV	[FSeek_logclus],DX    ;
	ADD	[FSeek_logclus],CX    ; set up last position
	invoke	SKPCLP
	JC	ACC_ERRWJ
NOSKIP:
	MOV	[CLUSNUM],BX
	MOV	[LASTPOS],DX
DOWRT:
	CMP	[BYTCNT1],0
	JZ	WRTMID
	MOV	BX,[CLUSNUM]
	invoke	BUFWRT
	JC	ACC_ERRWJ
WRTMID:
	MOV	AX,[SECCNT]
	OR	AX,AX
	JNZ	havemid
	JMP	WRTLAST
havemid:
	ADD	WORD PTR [SECPOS],AX
	ADC	WORD PTR [SECPOS+2],0	 ;F.C. >32mb				;AN000;
	invoke	NEXTSEC
	JNC	gotok
	JMP	ACC_ERRWJ
gotok:
	MOV	BYTE PTR [TRANS],1	 ; A transfer is taking place
	MOV	DL,[SECCLUSPOS]
	MOV	BX,[CLUSNUM]
	MOV	CX,[SECCNT]
WRTLP:
	invoke	OPTIMIZE
	JNC	wokok
	JMP	ACC_ERRWJ
wokok:
	PUSH	DI
	PUSH	AX
	PUSH	DX
	PUSH	BX
	Assert	ISDPB,<ES,BP>,"DiskWrite/WrtLp"
	MOV	AL,ES:[BP.dpb_drive]
	MOV	[SC_DRIVE],AL		  ;LB. save it for INVALIDATE_SC	;AN000;
	PUSH	CX			  ;LB.					;AN000;
	PUSH	[HIGH_SECTOR]		  ;LB.					;AN000;
SCANNEXT:				  ;LB.					;AN000;
	invoke	GETCURHEAD		  ;LB.					;AN000;
ASSUME	DS:NOTHING
NEXTBUFF:			; Search for buffers
	CMP	[SC_CACHE_COUNT],0	    ;LB. SC support ?			;AN000;
	JZ	nosc			    ;LB. no				;AN000;
	PUSH	AX			    ;LB. save reg			;AN000;
	PUSH	CX			    ;LB. save reg			;AN000;
	PUSH	DX			    ;LB. save reg			;AN000;
	invoke	INVALIDATE_SC		    ;LB. invalidate SC			;AN000;
	POP	DX			    ;LB. save reg			;AN000;
	POP	CX			    ;LB. save reg			;AN000;
	POP	AX			    ;LB. save reg			;AN000;
nosc:
	CALL	BUFF_RANGE_CHECK	    ;F.C. >32mb 			;AN000;
	JNC	inrange2		    ;F.C. >32mb 			;AN000;
	mov	DI,[DI.buf_next]	    ;LB. get next buffer 1/19/88	;AN000;
	JMP	DONEXTBUFF		    ;LB.				;AN000;
inrange2:
	TEST	[DI.buf_flags],buf_dirty    ;LB. if dirty			;AN000;
	JZ	not_dirty		    ;LB.				;AN000;
	invoke	DEC_DIRTY_COUNT 	    ;LB. then decrement dirty count	;AN000;
not_dirty:
	MOV	WORD PTR [DI.buf_ID],(buf_visit SHL 8) OR 0FFH	  ; Free the buffer, it is being over written
	invoke	SCANPLACE
DONEXTBUFF:
	CMP	DI,[FIRST_BUFF_ADDR]	  ;LB. end of chain			;AN000;
	JNZ	NEXTBUFF		  ;LB. no				;AN000;
	ADD	DX,1			  ;LB. next sector number		;AN000;
	ADC	[HIGH_SECTOR],0 	  ;LB.					;AN000;
	LOOP	SCANNEXT		  ;LB. check again			;AN000;
	POP	[HIGH_SECTOR]		  ;LB.					;AN000;
	POP	CX			  ;LB. get count back			;AN000;

	POP	BX
	POP	DX
	MOV	DS,WORD PTR [DMAADD+2]
	MOV	[ALLOWED],allowed_RETRY + allowed_FAIL + allowed_IGNORE

IF	BUFFERFLAG
	pushf
	cmp	[BUF_EMS_MODE], -1
	je	safe_write	
	call	save_map
	call	restore_user_map
safe_write:
	popf
ENDIF	

	invoke	DWRITE

IF	BUFFERFLAG
	pushf
	cmp	[BUF_EMS_MODE], -1
	je	safe_map	
	call	save_user_map
	call	restore_map
safe_map:
	popf
ENDIF

	POP	CX
	POP	BX
	Context DS
	JC	SET_ACC_ERRW
	JCXZ	WRTLAST
	MOV	DL,0
	INC	[LASTPOS]	; We'll be using next cluster
	JMP	WRTLP

WRTLAST:
	MOV	AX,[BYTCNT2]
	OR	AX,AX
	JZ	FINWRT
	MOV	[BYTCNT1],AX
	invoke	NEXTSEC
	JC	SET_ACC_ERRW
	MOV	[BYTSECPOS],0
	invoke	BUFWRT
	JC	SET_ACC_ERRW
FINWRT:
	LES	DI,[THISSFT]
	Assert	ISSFT,<ES,DI>,"DiskWrite/FinWrt"
	MOV	AX,WORD PTR [GROWCNT]
	MOV	CX,WORD PTR [GROWCNT+2]
	OR	AX,AX
	JNZ	UPDATE_size
	JCXZ	SAMSIZ
Update_size:
	ADD	WORD PTR ES:[DI.sf_size],AX
	ADC	WORD PTR ES:[DI.sf_size+2],CX
;
; Make sure that all other SFT's see this growth also.
;
	MOV	AX,1
if installed
	call	JShare + 14 * 4
else
	Call	ShSU
endif
SAMSIZ:
	transfer SETCLUS		  ; ES:DI already points to SFT

SET_ACC_ERRW:
	transfer SET_ACC_ERR_DS

WRTEOF:
	MOV	CX,AX
	OR	CX,DX
	JZ	KILLFIL
	SUB	AX,1
	SBB	DX,0

	PUSH	BX
	MOV	BX,ES:[BP.dpb_sector_size]    ;F.C. >32mb			;AN000;
	CALL	DIV32			      ;F.C. >32mb			;AN000;
	POP	BX			      ;F.C. >32mb			;AN000;
	CALL	SHR32			      ;F.C. >32mb			;AN000;


;	SHR	AX,CL
	MOV	CX,AX
	invoke	FNDCLUS
SET_ACC_ERRWJ2:
	JC	SET_ACC_ERRW
;;; 11/5/86 FastSeek
	MOV	[FSeek_logclus],DX    ; truncate clusters starting from DX
	invoke	FastSeek_Truncate
;;; 11/5/86 FastSeek
	JCXZ	RELFILE
	invoke	ALLOCATE
	JC	WRTERRJ 	     ;;;;;;;;; disk full
UPDATE:
	LES	DI,[THISSFT]
	Assert	ISSFT,<ES,DI>,"DiskWrite/update"
	MOV	AX,WORD PTR [BYTPOS]
	MOV	WORD PTR ES:[DI.sf_size],AX
	MOV	AX,WORD PTR [BYTPOS+2]
	MOV	WORD PTR ES:[DI.sf_size+2],AX
;
; Make sure that all other SFT's see this growth also.
;
	MOV	AX,2
if installed
	Call	JShare + 14 * 4
else
	Call	ShSU
endif
	XOR	CX,CX
	transfer ADDREC

WRTERRJ: JMP	 WRTERR
;;;;;;;;;;;;;;;; 7/18/86
;;;;;;;;;;;;;;;;;
RELFILE:
	MOV	DX,0FFFFH
	invoke	RELBLKS
Set_Acc_ERRWJJ:
	JC	SET_ACC_ERRWJ2
	JMP	SHORT UPDATE

KILLFIL:
	XOR	BX,BX
	PUSH	ES
	LES	DI,[THISSFT]
	Assert	ISSFT,<ES,DI>,"DiskWrite/KillFil"
	MOV	ES:[DI.sf_cluspos],BX
	MOV	ES:[DI.sf_lstclus],BX
	XCHG	BX,ES:[DI.sf_firclus]
	POP	ES
;; 11/5/86 FastSeek
	invoke	Delete_FSeek   ; delete fastseek entry

	OR	BX,BX
	JZ	UPDATEJ
;; 10/23/86 FastOpen update
	PUSH	ES		; since first cluster # is 0
	PUSH	BP		; we must delete the old cache entry
	PUSH	AX
	PUSH	CX
	PUSH	DX
	LES	BP,[THISDPB]		 ; get current DPB
	MOV	DL,ES:[BP.dpb_drive]	 ; get current drive
	MOV	CX,BX			 ; first cluster #
	MOV	AH,2			 ; delete cache entry by drive:firclus
	invoke	FastOpen_Update 	 ; call fastopen
	POP	DX
	POP	CX
	POP	AX
	POP	BP
	POP	ES
;; 10/23/86 FastOpen update

	invoke	RELEASE
	JC	SET_ACC_ERRWJJ
UpDateJ:
	JMP	UPDATE
EndProc DISKWRITE



Break	<DIV32 -- PERFORM 32 BIT DIVIDE>

; Inputs:
;	DX:AX = 32 bit dividend   BX= divisor
; Function:
;	Perform 32 bit division
; Outputs:
;	[HIGH_SECTOR]:AX = quotiend , DX= remainder

	procedure   DIV32,NEAR
	ASSUME	DS:NOTHING,ES:NOTHING


	PUSH	AX			;F.C. >32mb				;AN000;
	MOV	AX,DX			;F.C. >32mb				;AN000;
	XOR	DX,DX			;F.C. >32mb				;AN000;
	DIV	BX			;F.C. >32mb				;AN000;
	MOV	[HIGH_SECTOR],AX	;F.C. >32mb				;AN000;
	POP	AX			;F.C. >32mb				;AN000;


	DIV	BX			; AX=last sector accessed
	return

EndProc DIV32

Break	<SHR32 -- PERFORM 32 BIT SHIFT RIGHT>

; Inputs:
;	[HIGH_SECTOR]:AX = 32 bit sector number
; Function:
;	Perform 32 bit shift right
; Outputs:
;	AX= cluster number

	procedure   SHR32,NEAR
	ASSUME	DS:NOTHING,ES:NOTHING


	MOV	CL,ES:[BP.dpb_cluster_shift]
	XOR	CH,CH
entry ROTASHFT				;F.C. >32mb				;AN000;
	OR	CX,CX			;F.C. >32mb				;AN000;
	JZ	norota			;F.C. >32mb				;AN000;
ROTASHFT2:
	CLC				;F.C. >32mb				;AN000;
	RCR	[HIGH_SECTOR],1 	;F.C. >32mb				;AN000;
	RCR	AX,1			;F.C. >32mb				;AN000;
	LOOP	ROTASHFT2		;F.C. >32mb:				;AN000;
norota:
	return

EndProc SHR32


; Issue File Handle Fail INT 24 Critical Error
; Input: Disk_Full=0  ok
;		   1  disk full or EOF
; Function: issue critical error for disk full or EOF error
;
; OutPut: carry clear , no I24
;	  carry set, fail from I24

procedure File_Handle_Fail_Error,NEAR						;AN000;
	ASSUME	ES:NOTHING,DS:NOTHING						;AN000;
										;AN000;
	CMP	[DISK_FULL],0	 ;MS. disk full or EOF				;AN000;
	JZ	Fexit		 ;MS. no					;AN000;
	TEST	[DOS34_FLAG],Disable_EOF_I24   ;MS. check input status ?	;AN000;
	JNZ	Fexit		 ;MS. yes					;AN000;
										;AN000;
	LES	DI,[THISSFT]	 ;MS. get current SFT				;AN000;
;	LES	DI,ES:[DI.sf_DEVPTR];MS. get device header			;AN000;
	TEST	ES:[DI.sf_flags],Handle_Fail_I24  ;MS. gen I24 ?		;AN000;
	JZ	Fexit		 ;MS. no					;AN000;
	PUSH	DS		 ;MS. save DS					;AN000;
	TEST	AH,1				;MS. READ ?			;AN000;
	JZ	readeof 			;MS. yes			;AN000;
	MOV	[EXTERR],error_Handle_Disk_Full ;MS. set extended error 	;AN000;
	JMP	SHORT errset			;MS. set extended error 	;AN000;
readeof:
	MOV	[EXTERR],error_Handle_EOF	;MS. set extended error 	;AN000;
errset:
	MOV	[EXTERR_CLASS],errCLASS_OutRes	;MS. set class			;AN000;
	MOV	[EXTERR_ACTION],errACT_Abort	;MS. set action 		;AN000;
	MOV	[EXTERR_LOCUS],errLOC_Unk	;MS. set locus			;AN000;
	MOV	word ptr [EXITHOLD + 2],ES	;MS. save es:bp in exithold	;AN000;
	MOV	word ptr [EXITHOLD],BP		;MS.				;AN000;
	TEST	ES:[DI.sf_flags],devid_device	  ;MS. device  ?		;AN000;
	JNZ	chardev2			  ;MS. yes			;AN000;
	LDS	SI,ES:[DI.sf_DEVPTR]		  ;MS. get dpb			;AN000;
	LDS	SI,[SI.dpb_driver_addr] 	  ;MS. get drive device haeder	;AN000;
	JMP	SHORT doi24			  ;MS. gen I24 ?		;AN000;
chardev2:
	LDS	SI,ES:[DI.sf_DEVPTR]		  ;MS. get chr dev header	;AN000;
doi24:
	MOV	BP,DS				  ;MS. bp:si -> device header	;AN000;
	MOV	DI,error_I24_gen_failure	;MS. general error		;AN000;
	invoke	NET_I24_ENTRY			;MS. issue I24			;AN000;
	STC					;MS. must be fail		;AN000;
	POP	DS				;MS. restore DS 		;AN000;
	MOV	AX,[EXTERR]			;MS. set error			;AN000;
	JMP	SHORT Fend			;MS. exit			;AN000;
Fexit:										;AN000;
	CLC					;MS. clear carry		;AN000;
Fend:										;AN000;
	return					;MS.				;AN000;
										;AN000;
EndProc File_Handle_Fail_Error							;AN000;


Break	<BUFF_RANGE_CHECK- buffer range checkink>

; Inputs:
;	DS:DI -> buffer. AL= drive #
;	[HIGH_SECTOR]:DX = sector #
; Function:
;	check if sector is in the buffer
; Outputs:
;	carry clear= in the range
;	      set  = not in the range

	procedure   BUFF_RANGE_CHECK,NEAR
	ASSUME	DS:NOTHING,ES:NOTHING

	CMP	WORD PTR [DI.buf_sector],DX					;AN000;
	JNZ	DONEXTBUFF2	; not this sector	   ;F.C. >32mb		;AN000;
	MOV	SI,[HIGH_SECTOR]			   ;F.C. >32mb		;AN000;
	CMP	WORD PTR [DI.buf_sector+2],SI		   ;F.C. >32mb		;AN000;
	JNZ	DONEXTBUFF2	; Not for this drive
	CMP	AL,[DI.buf_ID]
	JZ	secfound	; Buffer has the sector 			;AN000;
DONEXTBUFF2:
	STC
secfound:
	return

EndProc BUFF_RANGE_CHECK

CODE	ENDS
    END