summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/FCBIO2.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/DOS/FCBIO2.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/DOS/FCBIO2.ASM')
-rw-r--r--v4.0/src/DOS/FCBIO2.ASM722
1 files changed, 722 insertions, 0 deletions
diff --git a/v4.0/src/DOS/FCBIO2.ASM b/v4.0/src/DOS/FCBIO2.ASM
new file mode 100644
index 0000000..ec0ee3e
--- /dev/null
+++ b/v4.0/src/DOS/FCBIO2.ASM
@@ -0,0 +1,722 @@
1; SCCSID = @(#)fcbio2.asm 1.2 85/07/23
2; SCCSID = @(#)fcbio2.asm 1.2 85/07/23
3TITLE FCBIO2 - FCB system calls
4NAME 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;
41include dosseg.asm
42
43CODE SEGMENT BYTE PUBLIC 'CODE'
44 ASSUME SS:DOSGROUP,CS:DOSGROUP
45
46.xcref
47INCLUDE DOSSYM.INC
48INCLUDE DEVSYM.INC
49include 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
62if debug
63 I_need BugLev,WORD
64 I_need BugTyp,WORD
65 include bugtyp.asm
66endif
67
68IF 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
82ENDIF
83
84
85; Defintions for FCBOp flags
86
87Random = 2 ; random operation
88FCBRead = 4 ; doing a read
89Block = 8 ; doing a block I/O
90
91Break <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
102Procedure 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
109GetRRBye:
110 return
111EndProc GetRR
112
113Break <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
123Procedure 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
134EndProc GetExtent
135
136Break <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
147Procedure 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
161EndProc SetExtent
162
163Break <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
173Procedure 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
179GetBye:
180 CMP SI,DX ; set condition codes
181 return
182EndProc GetExtended
183
184Break <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
193Procedure 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
201EndProc GetRecSize
202
203BREAK <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
214Procedure FCBIO,NEAR
215 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
216PUBLIC FCBIO001S,FCBIO001E
217FCBIO001S:
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
227FCBIO001E:
228 Enter
229
230FEOF EQU 1
231FTRIM 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;
238GetPos:
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 ();
246GetRec:
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
269DoDiv:
270 XOR DX,DX
271 DIV BX
272 MOV cRec,AX
273 MUL BX ; cByte = cRec * RecSize;
274 MOV cByte,AX ; }
275DoOper:
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) {
281IF debug
282 JZ DoGetExt
283 JMP SkipOp
284ELSE
285 JZ SKP_SkipOp
286 JMP SkipOp
287SKP_SkipOp:
288ENDIF
289DoGetExt:
290 invoke SFTFromFCB ; if (!SFTFromFCB (SFT,FCB))
291 JNC ContinueOp
292FCBDeath:
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!
297ContinueOp:
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
316DoContext:
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
324IF 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
342dos_fcb_call_done:
343 pop bx
344 pop ax
345 popf
346ENDIF
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
354NODSKFULL:
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 ; }
366SkipOp:
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
385SetEOF:
386 MOV FCBErr,FEOF ; FCBErr = FEOF;
387TryBlank: ;
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 ; } }
402SetExt:
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
409DoSetExt:
410 invoke SetExtent ; SetExtent (RecPos, FCB);
411TrySetRR:
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
419TryReturn:
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 ; }
427FCBSave:
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
433DoReturn:
434 MOV AL,FCBErr ; return (FCBERR);
435 Leave
436 return
437EndProc FCBIO
438
439Break <$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
450Procedure $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;
459DoAccess:
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
465FCBOpenErr:
466;
467; AL has error code
468;
469 transfer FCB_Ret_Err
470FindFCB:
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"
492failopen:
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
501HardMessage:
502 PUSH AX
503 invoke FCBHardErr
504 POP AX
505DeadFCB:
506 transfer FCB_Ret_Err
507FCBOK:
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
516FCBOK2:
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
529FCBNoDrive:
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
547OpenScan:
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!
554SkipCheck:
555 INC AL ; advance to next FCB
556 CMP AL,AH ; table full?
557 JNZ OpenScan ; no, go for more
558OpenDone:
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;
581OpenFound:
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
598EndProc $FCB_Open
599
600BREAK <$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
611Procedure $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
618DoAccessJ:
619 JMP DoAccess ; do dirty work
620EndProc $FCB_Create
621
622BREAK <$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
633Procedure $FCB_Random_Write_Block,NEAR
634 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
635 MOV AL,Random+Block
636 JMP FCBIO
637EndProc $FCB_Random_Write_Block
638
639BREAK <$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
649Procedure $FCB_Random_Read_Block,NEAR
650 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
651 MOV AL,Random+FCBRead+Block
652 JMP FCBIO
653EndProc $FCB_Random_Read_Block
654
655BREAK <$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
665Procedure $FCB_Seq_Read,NEAR
666 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
667 MOV AL,FCBRead
668 JMP FCBIO
669EndProc $FCB_Seq_Read
670
671BREAK <$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
681Procedure $FCB_Seq_Write,NEAR
682 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
683 MOV AL,0
684 jmp FCBIO
685EndProc $FCB_SEQ_WRITE
686
687BREAK <$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
697Procedure $FCB_Random_Read,NEAR
698 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
699 MOV AL,Random+FCBRead
700 jmp FCBIO ; single block
701EndProc $FCB_RANDOM_READ
702
703BREAK <$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
713Procedure $FCB_Random_Write,NEAR
714 ASSUME CS:DOSGROUP,DS:NOTHING,ES:NOTHING,SS:DOSGroup
715 MOV AL,Random
716 jmp FCBIO
717EndProc $FCB_RANDOM_WRITE
718
719CODE ENDS
720END
721
722 \ No newline at end of file