]> wirehaze git hosting - MS-DOS.git/blob - v4.0/src/DOS/FCBIO2.ASM

wirehaze git hosting

MZ is back!
[MS-DOS.git] / v4.0 / src / DOS / FCBIO2.ASM
1 ; SCCSID = @(#)fcbio2.asm 1.2 85/07/23
2 ; SCCSID = @(#)fcbio2.asm 1.2 85/07/23
3 TITLE FCBIO2 - FCB system calls
4 NAME FCBIO2
5
6 ;
7 ; Ancient 1.0 1.1 FCB system calls
8 ; regen save
9 ; GetRR
10 ; GetExtent
11 ; SetExtent
12 ; GetExtended
13 ; GetRecSize
14 ; FCBIO
15 ; $FCB_OPEN written ACC ACC
16 ; $FCB_CREATE written ACC ACC
17 ; $FCB_RANDOM_WRITE_BLOCK written fcbio fcbio
18 ; $FCB_RANDOM_READ_BLOCK written fcbio fcbio
19 ; $FCB_SEQ_READ written fcbio fcbio
20 ; $FCB_SEQ_WRITE written fcbio fcbio
21 ; $FCB_RANDOM_READ written fcbio fcbio
22 ; $FCB_RANDOM_WRITE written fcbio fcbio
23 ;
24 ; Revision history:
25 ;
26 ; Created: ARR 4 April 1983
27 ; MZ 6 June 1983 completion of functions
28 ; MZ 15 Dec 1983 Brain damaged programs close FCBs multiple
29 ; times. Change so successive closes work by
30 ; always returning OK. Also, detect I/O to
31 ; already closed FCB and return EOF.
32 ; MZ 16 Jan 1984 More braindamage. Need to separate info
33 ; out of sft into FCB for reconnection
34 ;
35 ; A000 version 4.00 Jan. 1988
36 ;
37 .xlist
38 ;
39 ; get the appropriate segment definitions
40 ;
41 include dosseg.asm
42
43 CODE SEGMENT BYTE PUBLIC 'CODE'
44 ASSUME SS:DOSGROUP,CS:DOSGROUP
45
46 .xcref
47 INCLUDE DOSSYM.INC
48 INCLUDE DEVSYM.INC
49 include version.inc
50 .cref
51 .list
52
53 EXTRN DOS_Read:NEAR, DOS_Write:NEAR
54 EXTRN DOS_Open:NEAR, DOS_Create:NEAR
55
56 I_need DMAAdd,DWORD ; current user's DMA address
57 I_need OpenBuf,128 ; buffer for translating paths
58 I_need ThisSFT,DWORD ; SFT in use
59 I_need sftFCB,DWORD ; pointer to SFTs for FCB cache
60 I_need FCBLRU,WORD ; least recently used count
61 I_need DISK_FULL,BYTE ; flag for disk full
62 if debug
63 I_need BugLev,WORD
64 I_need BugTyp,WORD
65 include bugtyp.asm
66 endif
67
68 IF BUFFERFLAG
69
70 I_need BUF_EMS_MODE,BYTE
71 I_need BUF_EMS_LAST_PAGE,DWORD
72 I_need BUF_EMS_FIRST_PAGE,DWORD
73 I_need BUF_EMS_SAFE_FLAG,BYTE
74 I_need BUF_EMS_NPA640,WORD
75 I_need BUF_EMS_PAGE_FRAME,WORD
76 I_need BUF_EMS_PFRAME,WORD
77 I_need LASTBUFFER,DWORD
78
79 extrn restore_user_map:near
80 extrn Setup_EMS_Buffers:near
81
82 ENDIF
83
84
85 ; Defintions for FCBOp flags
86
87 Random = 2 ; random operation
88 FCBRead = 4 ; doing a read
89 Block = 8 ; doing a block I/O
90
91 Break <GetRR - return the random record field in DX:AX>
92
93 ;
94 ; GetRR - correctly load DX:AX with the random record field (3 or 4 bytes)
95 ; from the FCB pointed to by DS:SI
96 ;
97 ; Inputs: DS:SI point to an FCB
98 ; BX has record size
99 ; Outputs: DX:AX contain the contents of the random record field
100 ; Registers modified: none
101
102 Procedure GetRR,NEAR
103 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
104 MOV AX,WORD PTR [SI.FCB_RR] ; get low order part
105 MOV DX,WORD PTR [SI.FCB_RR+2] ; get high order part
106 CMP BX,64 ; ignore MSB of RR if recsiz > 64
107 JB GetRRBye
108 XOR DH,DH
109 GetRRBye:
110 return
111 EndProc GetRR
112
113 Break <GetExtent - retrieve next location for sequential IO>
114
115 ;
116 ; GetExtent - Construct the next record to perform I/O from the EXTENT and
117 ; NR fields in the FCB.
118 ;
119 ; Inputs: DS:SI - point to FCB
120 ; Outputs: DX:AX contain the contents of the random record field
121 ; Registers modified: none
122
123 Procedure GetExtent,NEAR
124 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
125 MOV AL,[SI.fcb_NR] ; get low order piece
126 MOV DX,[SI.fcb_EXTENT] ; get high order piece
127 SHL AL,1
128 SHR DX,1
129 RCR AL,1 ; move low order bit of DL to high order of AH
130 MOV AH,DL
131 MOV DL,DH
132 XOR DH,DH
133 return
134 EndProc GetExtent
135
136 Break <SetExtent - update the extent/NR field>
137
138 ;
139 ; SetExtent - change the position of an FCB by filling in the extent/NR
140 ; fields
141 ;
142 ; Inputs: DS:SI point to FCB
143 ; DX:AX is a record location in file
144 ; Outputs: Extent/NR fields are filled in
145 ; Registers modified: CX
146
147 Procedure SetExtent,NEAR
148 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
149 SaveReg <AX,DX>
150 MOV CX,AX
151 AND AL,7FH ; next rec field
152 MOV [SI.fcb_NR],AL
153 AND CL,80H ; save upper bit
154 SHL CX,1
155 RCL DX,1 ; move high bit of CX to low bit of DX
156 MOV AL,CH
157 MOV AH,DL
158 MOV [SI.fcb_EXTENT],AX ; all done
159 RestoreReg <DX,AX>
160 return
161 EndProc SetExtent
162
163 Break <GetExtended - find FCB in potential extended fcb>
164
165 ;
166 ; GetExtended - Make DS:SI point to FCB from DS:DX
167 ;
168 ; Inputs: DS:DX point to a possible extended FCB
169 ; Outputs: DS:SI point to the FCB part
170 ; zeroflag set if not extended fcb
171 ; Registers modified: SI
172
173 Procedure GetExtended,NEAR
174 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
175 MOV SI,DX ; point to Something
176 CMP BYTE PTR DS:[SI],-1 ; look for extention
177 JNZ GetBye ; not there
178 ADD SI,7 ; point to FCB
179 GetBye:
180 CMP SI,DX ; set condition codes
181 return
182 EndProc GetExtended
183
184 Break <GetRecSize - return in BX the FCB record size>
185
186 ;
187 ; GetRecSize - return in BX the record size from the FCB at DS:SI
188 ;
189 ; Inputs: DS:SI point to a non-extended FCB
190 ; Outputs: BX contains the record size
191 ; Registers modified: None
192
193 Procedure GetRecSize,NEAR
194 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
195 MOV BX,[SI.fcb_RECSIZ] ; get his record size
196 OR BX,BX ; is it nul?
197 retnz
198 MOV BX,128 ; use default size
199 MOV [SI.fcb_RECSIZ],BX ; stuff it back
200 return
201 EndProc GetRecSize
202
203 BREAK <FCBIO - do internal FCB I/O>
204
205 ;
206 ; FCBIO - look at FCBOP and merge all FCB operations into a single routine.
207 ;
208 ; Inputs: FCBOP flags which operations need to be performed
209 ; DS:DX point to FCB
210 ; CX may have count of number of records to xfer
211 ; Outputs: AL has error code
212 ; Registers modified: all
213
214 Procedure FCBIO,NEAR
215 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
216 PUBLIC FCBIO001S,FCBIO001E
217 FCBIO001S:
218 LocalVar FCBErr,BYTE
219 LocalVar cRec,WORD
220 LocalVar RecPos,DWORD
221 LocalVar RecSize,WORD
222 LocalVar bPos,DWORD
223 LocalVar cByte,WORD
224 LocalVar cResult,WORD
225 LocalVar cRecRes,WORD
226 LocalVar FCBOp,BYTE
227 FCBIO001E:
228 Enter
229
230 FEOF EQU 1
231 FTRIM EQU 2
232 MOV FCBOp,AL
233 MOV FCBErr,0 ; FCBErr = 0;
234 invoke GetExtended ; FCB = GetExtended ();
235 TEST FCBOp,BLOCK ; if ((OP&BLOCK) == 0)
236 JNZ GetPos
237 MOV CX,1 ; cRec = 1;
238 GetPos:
239 MOV cRec,CX ;*Tail coalesce
240 invoke GetExtent ; RecPos = GetExtent ();
241 invoke GetRecSize ; RecSize = GetRecSize ();
242 MOV RecSize,BX
243 TEST FCBOp,RANDOM ; if ((OP&RANDOM) <> 0)
244 JZ GetRec
245 invoke GetRR ; RecPos = GetRR ();
246 GetRec:
247 MOV RecPosL,AX ;*Tail coalesce
248 MOV RecPosH,DX
249 invoke SetExtent ; SetExtent (RecPos);
250 MOV AX,RecPosH ; bPos = RecPos * RecSize;
251 MUL BX
252 MOV DI,AX
253 MOV AX,RecPosL
254 MUL BX
255 ADD DX,DI
256 MOV bPosL,AX
257 MOV bPosH,DX
258 MOV AX,cRec ; cByte = cRec * RecSize;
259 MUL BX
260 MOV cByte,AX
261 ADD AX,WORD PTR DMAAdd ; if (cByte+DMA > 64K) {
262 ADC DX,0
263 JZ DoOper
264 MOV FCBErr,FTRIM ; FCBErr = FTRIM;
265 MOV AX,WORD PTR DMAAdd ; cRec = (64K-DMA)/RecSize;
266 NEG AX
267 JNZ DoDiv
268 DEC AX
269 DoDiv:
270 XOR DX,DX
271 DIV BX
272 MOV cRec,AX
273 MUL BX ; cByte = cRec * RecSize;
274 MOV cByte,AX ; }
275 DoOper:
276 XOR BX,BX
277 MOV cResult,BX ; cResult = 0;
278 CMP cByte,BX ; if (cByte <> 0 ||
279 JNZ DoGetExt
280 TEST FCBErr,FTRIM ; (FCBErr&FTRIM) == 0) {
281 IF debug
282 JZ DoGetExt
283 JMP SkipOp
284 ELSE
285 JZ SKP_SkipOp
286 JMP SkipOp
287 SKP_SkipOp:
288 ENDIF
289 DoGetExt:
290 invoke SFTFromFCB ; if (!SFTFromFCB (SFT,FCB))
291 JNC ContinueOp
292 FCBDeath:
293 invoke FCB_Ret_Err ; signal error, map for extended
294 MOV cRecRes,0 ; no bytes transferred
295 MOV FCBErr,FEOF ; return FTRIM;
296 JMP FCBSave ; bam!
297 ContinueOp:
298 Assert ISSFT,<ES,DI>,"ContinueOP"
299 MOV AX,WORD PTR [SI].fcb_filsiz
300 MOV WORD PTR ES:[DI].sf_size,AX
301 MOV AX,WORD PTR [SI].fcb_filsiz+2
302 MOV WORD PTR ES:[DI].sf_size+2,AX
303 MOV AX,bPosL
304 MOV DX,bPosH
305 MOV WORD PTR ES:[DI.sf_position],AX
306 XCHG WORD PTR ES:[DI.sf_position+2],DX
307 PUSH DX ; save away Open age.
308 MOV CX,cByte ; cResult =
309
310 ; int 3
311
312 MOV DI,OFFSET DOSGroup:DOS_Read ; *(OP&FCBRead ? DOS_Read
313 TEST FCBOp,FCBRead ; : DOS_Write)(cRec);
314 JNZ DoContext
315 MOV DI,OFFSET DOSGroup:DOS_Write
316 DoContext:
317 SaveReg <BP,DS,SI>
318 Context DS
319 ;; Fix for disk full
320 CALL DI
321 RestoreReg <SI,DS,BP>
322 ASSUME DS:NOTHING
323
324 IF BUFFERFLAG
325 pushf
326 push ax
327 push bx
328
329 cmp cs:[BUF_EMS_MODE], -1
330 jz dos_fcb_call_done
331 call restore_user_map
332 mov ax, word ptr cs:[BUF_EMS_LAST_PAGE]
333 cmp cs:[BUF_EMS_PFRAME], ax
334 je dos_fcb_call_done
335 mov word ptr cs:[LASTBUFFER], -1
336 mov cs:[BUF_EMS_PFRAME], ax
337 mov ax, word ptr cs:[BUF_EMS_LAST_PAGE+2]
338 mov cs:[BUF_EMS_PAGE_FRAME], ax
339 mov cs:[BUF_EMS_SAFE_FLAG], 1
340 call Setup_EMS_Buffers
341
342 dos_fcb_call_done:
343 pop bx
344 pop ax
345 popf
346 ENDIF
347
348 JC FCBDeath
349
350 CMP BYTE PTR [DISK_FULL],0 ; treat disk full as error
351 JZ NODSKFULL
352 MOV BYTE PTR [DISK_FULL],0 ; clear the flag
353 MOV FCBerr,FEOF ; set disk full flag
354 NODSKFULL:
355 ;; Fix for disk full
356 MOV cResult,CX
357 invoke SaveFCBInfo ; SaveFCBInfo (FCB);
358 Assert ISSFT,<ES,DI>,"FCBIO/SaveFCBInfo"
359 %out WARNING!!! Make sure sf_position+2 is OpenAGE
360 POP WORD PTR ES:[DI].sf_Position+2 ; restore open age
361 MOV AX,WORD PTR ES:[DI].sf_size
362 MOV WORD PTR [SI].fcb_filsiz,AX
363 MOV AX,WORD PTR ES:[DI].sf_size+2
364 MOV WORD PTR [SI].fcb_filsiz+2,AX
365 ; }
366 SkipOp:
367 MOV AX,cResult ; cRecRes = cResult / RecSize;
368 XOR DX,DX
369 DIV RecSize
370 MOV cRecRes,AX
371 ADD RecPosL,AX ; RecPos += cRecResult;
372 ADC RecPosH,0
373 ;
374 ; If we have not gotten the expected number of records, we signal an EOF
375 ; condition. On input, this is EOF. On output this is usually disk full.
376 ; BUT... Under 2.0 and before, all device output IGNORED this condition. So
377 ; do we.
378 ;
379 CMP AX,cRec ; if (cRecRes <> cRec)
380 JZ TryBlank
381 TEST FCBOp,FCBRead ; if (OP&FCBRead || !DEVICE)
382 JNZ SetEOF
383 TEST ES:[DI].sf_flags,devid_device
384 JNZ TryBlank
385 SetEOF:
386 MOV FCBErr,FEOF ; FCBErr = FEOF;
387 TryBlank: ;
388 OR DX,DX ; if (cResult%RecSize <> 0) {
389 JZ SetExt
390 ADD RecPosL,1 ; RecPos++;
391 ADC RecPosH,0
392 TEST FCBOp,FCBRead ; if(OP&FCBRead) <> 0) {
393 JZ SetExt
394 INC cRecRes ; cRecRes++;
395 MOV FCBErr,FTRIM + FEOF ; FCBErr = FTRIM | FEOF;
396 MOV CX,RecSize ; Blank (RecSize-cResult%RecSize,
397 SUB CX,DX ; DMA+cResult);
398 XOR AL,AL
399 LES DI,DMAAdd
400 ADD DI,cResult
401 REP STOSB ; } }
402 SetExt:
403 MOV DX,RecPosH
404 MOV AX,RecPosL
405 TEST FCBOp,RANDOM ; if ((OP&Random) == 0 ||
406 JZ DoSetExt
407 TEST FCBOp,BLOCK ; (OP&BLOCK) <> 0)
408 JZ TrySetRR
409 DoSetExt:
410 invoke SetExtent ; SetExtent (RecPos, FCB);
411 TrySetRR:
412 TEST FCBOp,BLOCK ; if ((op&BLOCK) <> 0)
413 JZ TryReturn
414 MOV WORD PTR [SI.FCB_RR],AX ; FCB->RR = RecPos;
415 MOV BYTE PTR [SI.FCB_RR+2],DL
416 CMP [SI.fcb_RECSIZ],64
417 JAE TryReturn
418 MOV [SI+fcb_RR+2+1],DH ; Set 4th byte only if record size < 64
419 TryReturn:
420 TEST FCBOP,FCBRead ; if (!(FCBOP & FCBREAD)) {
421 JNZ FCBSave
422 SaveReg <DS> ; FCB->FDate = date;
423 Invoke Date16 ; FCB->FTime = time;
424 RestoreReg <DS>
425 MOV [SI].FCB_FDate,AX
426 MOV [SI].FCB_FTime,DX ; }
427 FCBSave:
428 TEST FCBOp,BLOCK ; if ((op&BLOCK) <> 0)
429 JZ DoReturn
430 MOV CX,cRecRes ; user_CX = cRecRes;
431 invoke Get_User_Stack
432 MOV [SI.User_CX],CX
433 DoReturn:
434 MOV AL,FCBErr ; return (FCBERR);
435 Leave
436 return
437 EndProc FCBIO
438
439 Break <$FCB_Open - open an old-style FCB>
440
441 ;
442 ; $FCB_Open - CPM compatability file open. The user has formatted an FCB
443 ; for us and asked to have the rest filled in.
444 ;
445 ; Inputs: DS:DX point to an unopenned FCB
446 ; Outputs: AL indicates status 0 is ok FF is error
447 ; FCB has the following fields filled in:
448 ; Time/Date Extent/NR Size
449
450 Procedure $FCB_Open,NEAR
451 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGROUP
452 MOV AX,sharing_Compat+Open_For_Both
453 MOV CX,OFFSET DOSGroup:DOS_Open
454 ;
455 ; The following is common code for Creation and openning of FCBs. AX is
456 ; either attributes (for create) or open mode (for open)... DS:DX points to
457 ; the FCB
458 ;
459 DoAccess:
460 SaveReg <DS,DX,CX,AX> ; save FCB pointer away
461 MOV DI,OFFSET DOSGroup:OpenBuf
462 invoke TransFCB ; crunch the fcb
463 RestoreReg <AX,CX,DX,DS> ; get fcb
464 JNC FindFCB ; everything seems ok
465 FCBOpenErr:
466 ;
467 ; AL has error code
468 ;
469 transfer FCB_Ret_Err
470 FindFCB:
471 invoke GetExtended ; DS:SI will point to FCB
472 invoke LRUFCB ; get a sft entry (no error)
473 JC HardMessage
474 ASSUME ES:NOTHING
475
476 ; Message 1,"Entering "
477 ; MessageNum ES
478 ; Message 1,":"
479 ; MessageNum DI
480 ; Message 1,<13,10>
481
482 MOV ES:[DI].sf_mode,sf_ISFCB
483 SaveReg <DS,SI,BX> ; save fcb pointer
484 MOV SI,CX
485 Context DS ; let DOS_Open see variables
486 CALL SI ; go open the file
487 RestoreReg <BX,SI,DS> ; get fcb
488 ASSUME DS:NOTHING
489 LES DI,ThisSFT ; get sf pointer
490 JNC FCBOK ; operation succeeded
491 Assert ISSFT,<ES,DI>,"DeadFCB"
492 failopen:
493 PUSH AX
494 MOV AL,"R" ; clear out field (free sft)
495 invoke BlastSFT
496 POP AX
497 CMP AX,error_too_many_open_files
498 JZ HardMessage
499 CMP AX,error_sharing_buffer_exceeded
500 jnz DeadFCB
501 HardMessage:
502 PUSH AX
503 invoke FCBHardErr
504 POP AX
505 DeadFCB:
506 transfer FCB_Ret_Err
507 FCBOK:
508 invoke IsSFTNet ;AN007;F.C. >32mb Non Fat file?
509 JNZ FCBOK2 ;AN007;F.C. >32mb yes
510 invoke CheckShare ;AN000;F.C. >32mb share around?
511 JNZ FCBOK2 ;AN000;F.C. >32mb yes
512 CMP WORD PTR ES:[DI].sf_dirsec+2,0 ;AN000;F.C. >32mb if dirsec >32mb
513 JZ FCBOK2 ;AN000;F.C. >32mb then error
514 MOV AX,error_sys_comp_not_loaded ;AN000;F.C. >32mb
515 JMP failopen ;AN000;F.C. >32mb
516 FCBOK2:
517
518 INC ES:[DI].sf_ref_count ; increment reference count
519 invoke SaveFCBInfo
520 Assert ISSFT,<ES,DI>,"FCBOK"
521 invoke SetOpenAge
522 Assert ISSFT,<ES,DI>,"FCBOK/SetOpenAge"
523 TEST ES:[DI].sf_flags,devid_device
524 JNZ FCBNoDrive ; do not munge drive on devices
525 MOV AL,DS:[SI] ; get drive byte
526 invoke GetThisDrv ; convert
527 INC AL
528 MOV DS:[SI],AL ; stash in good drive letter
529 FCBNoDrive:
530 MOV [SI].FCB_RecSiz,80h ; stuff in default record size
531 MOV AX,ES:[DI].SF_Time ; set time
532 MOV [SI].FCB_FTime,AX
533 MOV AX,ES:[DI].SF_Date ; set date
534 MOV [SI].FCB_FDate,AX
535 MOV AX,WORD PTR ES:[DI].SF_Size ; set sizes
536 MOV [SI].FCB_FILSIZ,AX
537 MOV AX,WORD PTR ES:[DI].SF_Size+2
538 MOV [SI].FCB_FILSIZ+2,AX
539 XOR AX,AX ; convenient zero
540 MOV [SI].FCB_Extent,AX ; point to beginning of file
541 ;
542 ; We must scan the set of FCB SFTs for one that appears to match the current
543 ; one. We cheat and use CheckFCB to match the FCBs.
544 ;
545 LES DI,SFTFCB ; get the pointer to head of the list
546 MOV AH,BYTE PTR ES:[DI].sfCount ; get number of SFTs to scan
547 OpenScan:
548 CMP AL,[SI].fcb_sfn ; don't compare ourselves
549 JZ SkipCheck
550 SaveReg <AX> ; preserve count
551 invoke CheckFCB ; do they match
552 RestoreReg <AX> ; get count back
553 JNC OpenFound ; found a match!
554 SkipCheck:
555 INC AL ; advance to next FCB
556 CMP AL,AH ; table full?
557 JNZ OpenScan ; no, go for more
558 OpenDone:
559 xor al,al ; return success
560 return
561 ;
562 ; The SFT at ES:DI is the one that is already in use for this FCB. We set the
563 ; FCB to use this one. We increment its ref count. We do NOT close it at all.
564 ; Consider:
565 ;
566 ; open (foo) delete (foo) open (bar)
567 ;
568 ; This causes us to recycle (potentially) bar through the same local SFT as
569 ; foo even though foo is no longer needed; this is due to the server closing
570 ; foo for us when we delete it. Unfortunately, we cannot see this closure.
571 ; If we were to CLOSE bar, the server would then close the only reference to
572 ; bar and subsequent I/O would be lost to the redirector.
573 ;
574 ; This gets solved by NOT closing the sft, but zeroing the ref count
575 ; (effectively freeing the SFT) and informing the sharer (if relevant) that
576 ; the SFT is no longer in use. Note that the SHARER MUST keep its ref counts
577 ; around. This will allow us to access the same file through multiple network
578 ; connections and NOT prematurely terminate when the ref count on one
579 ; connection goes to zero.
580 ;
581 OpenFound:
582 MOV [SI].fcb_SFN,AL ; assign with this
583 INC ES:[DI].sf_ref_count ; remember this new invocation
584 MOV AX,FCBLRU ; update LRU counts
585 MOV ES:[DI].sf_LRU,AX
586 ;
587 ; We have an FCB sft that is now of no use. We release sharing info and then
588 ; blast it to prevent other reuse.
589 ;
590 context DS
591 LES DI,ThisSFT
592 DEC ES:[DI].sf_ref_count ; free the newly allocated SFT
593 invoke ShareEnd
594 Assert ISSFT,<ES,DI>,"Open blasting"
595 MOV AL,'C'
596 invoke BlastSFT
597 JMP OpenDone
598 EndProc $FCB_Open
599
600 BREAK <$FCB_Create - create a new directory entry>
601
602 ;
603 ; $FCB_Create - CPM compatability file create. The user has formatted an
604 ; FCB for us and asked to have the rest filled in.
605 ;
606 ; Inputs: DS:DX point to an unopenned FCB
607 ; Outputs: AL indicates status 0 is ok FF is error
608 ; FCB has the following fields filled in:
609 ; Time/Date Extent/NR Size
610
611 Procedure $FCB_Create,NEAR
612 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
613 MOV CX,OFFSET DOSGroup:DOS_Create ; routine to call
614 XOR AX,AX ; attributes to create
615 invoke GetExtended ; get extended FCB
616 JZ DoAccessJ ; not an extended FCB
617 MOV AL,[SI-1] ; get attributes
618 DoAccessJ:
619 JMP DoAccess ; do dirty work
620 EndProc $FCB_Create
621
622 BREAK <$FCB_Random_write_Block - write a block of records to a file >
623
624 ;
625 ; $FCB_Random_Write_Block - retrieve a location from the FCB, seek to it
626 ; and write a number of blocks from it.
627 ;
628 ; Inputs: DS:DX point to an FCB
629 ; Outputs: AL = 0 write was successful and the FCB position is updated
630 ; AL <> 0 Not enough room on disk for the output
631 ;
632
633 Procedure $FCB_Random_Write_Block,NEAR
634 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
635 MOV AL,Random+Block
636 JMP FCBIO
637 EndProc $FCB_Random_Write_Block
638
639 BREAK <$FCB_Random_Read_Block - read a block of records to a file >
640
641 ;
642 ; $FCB_Random_Read_Block - retrieve a location from the FCB, seek to it
643 ; and read a number of blocks from it.
644 ;
645 ; Inputs: DS:DX point to an FCB
646 ; Outputs: AL = error codes defined above
647 ;
648
649 Procedure $FCB_Random_Read_Block,NEAR
650 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
651 MOV AL,Random+FCBRead+Block
652 JMP FCBIO
653 EndProc $FCB_Random_Read_Block
654
655 BREAK <$FCB_Seq_Read - read the next record from a file >
656
657 ;
658 ; $FCB_Seq_Read - retrieve the next record from an FCB and read it into
659 ; memory
660 ;
661 ; Inputs: DS:DX point to an FCB
662 ; Outputs: AL = error codes defined above
663 ;
664
665 Procedure $FCB_Seq_Read,NEAR
666 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
667 MOV AL,FCBRead
668 JMP FCBIO
669 EndProc $FCB_Seq_Read
670
671 BREAK <$FCB_Seq_Write - write the next record to a file >
672
673 ;
674 ; $FCB_Seq_Write - retrieve the next record from an FCB and write it to the
675 ; file
676 ;
677 ; Inputs: DS:DX point to an FCB
678 ; Outputs: AL = error codes defined above
679 ;
680
681 Procedure $FCB_Seq_Write,NEAR
682 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
683 MOV AL,0
684 jmp FCBIO
685 EndProc $FCB_SEQ_WRITE
686
687 BREAK <$FCB_Random_Read - Read a single record from a file >
688
689 ;
690 ; $FCB_Random_Read - retrieve a location from the FCB, seek to it and read a
691 ; record from it.
692 ;
693 ; Inputs: DS:DX point to an FCB
694 ; Outputs: AL = error codes defined above
695 ;
696
697 Procedure $FCB_Random_Read,NEAR
698 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
699 MOV AL,Random+FCBRead
700 jmp FCBIO ; single block
701 EndProc $FCB_RANDOM_READ
702
703 BREAK <$FCB_Random_Write - write a single record to a file >
704
705 ;
706 ; $FCB_Random_Write - retrieve a location from the FCB, seek to it and write
707 ; a record to it.
708 ;
709 ; Inputs: DS:DX point to an FCB
710 ; Outputs: AL = error codes defined above
711 ;
712
713 Procedure $FCB_Random_Write,NEAR
714 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
715 MOV AL,Random
716 jmp FCBIO
717 EndProc $FCB_RANDOM_WRITE
718
719 CODE ENDS
720 END
721 \1a
722 \1a