summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/SYS
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/SYS')
-rw-r--r--v4.0/src/CMD/SYS/MAKEFILE46
-rw-r--r--v4.0/src/CMD/SYS/SYS.LNK2
-rw-r--r--v4.0/src/CMD/SYS/SYS.SKL48
-rw-r--r--v4.0/src/CMD/SYS/SYS1.ASM3710
-rw-r--r--v4.0/src/CMD/SYS/SYS2.ASM2622
-rw-r--r--v4.0/src/CMD/SYS/SYSHDR.INC427
-rw-r--r--v4.0/src/CMD/SYS/SYSSR.ASM82
7 files changed, 6937 insertions, 0 deletions
diff --git a/v4.0/src/CMD/SYS/MAKEFILE b/v4.0/src/CMD/SYS/MAKEFILE
new file mode 100644
index 0000000..08a7fea
--- /dev/null
+++ b/v4.0/src/CMD/SYS/MAKEFILE
@@ -0,0 +1,46 @@
1#************************** makefile for cmd\... ***************************
2
3msg =..\..\messages
4dos =..\..\dos
5inc =..\..\inc
6hinc =..\..\h
7boot =..\..\boot
8here =..\cmd\sys
9
10#
11####################### dependencies begin here. #########################
12#
13
14all: sys.com
15
16$(inc)\boot.inc: $(boot)\msboot.asm $(msg)\$(COUNTRY).msg
17 cd $(boot)
18 nmake
19 cd $(here)
20
21sys.ctl: sys.skl $(msg)\$(COUNTRY).msg
22
23sys1.obj: sys1.asm $(inc)\dossym.inc $(inc)\dosmac.inc \
24 $(inc)\bpb.inc $(inc)\buffer.inc $(inc)\sysvar.inc \
25 $(inc)\mult.inc $(inc)\dirent.inc $(inc)\dpb.inc \
26 $(inc)\curdir.inc $(inc)\cpmfcb.inc $(inc)\find.inc \
27 $(inc)\pdb.inc $(inc)\sf.inc $(inc)\arena.inc $(inc)\intnat.inc \
28 $(inc)\error.inc $(inc)\syscall.inc $(inc)\ioctl.inc \
29 $(inc)\bootform.inc $(inc)\boot.inc syshdr.inc
30
31sys2.obj: sys2.asm $(inc)\dossym.inc $(inc)\dosmac.inc \
32 $(inc)\bpb.inc $(inc)\buffer.inc $(inc)\sysvar.inc \
33 $(inc)\mult.inc $(inc)\dirent.inc $(inc)\dpb.inc \
34 $(inc)\curdir.inc $(inc)\cpmfcb.inc $(inc)\find.inc \
35 $(inc)\pdb.inc $(inc)\sf.inc $(inc)\arena.inc $(inc)\intnat.inc \
36 $(inc)\error.inc $(inc)\syscall.inc $(inc)\ioctl.inc \
37 $(inc)\bootform.inc $(inc)\boot.inc syshdr.inc
38
39syssr.obj: syssr.asm $(inc)\parse.asm \
40 $(inc)\psdata.inc $(inc)\msgserv.asm $(inc)\sysmsg.inc \
41 sys.ctl sys.cl1 sys.cl2 sys.cla sys.clb sys.clc sys.cld
42
43sys.com: sys.ctl sys1.obj syssr.obj sys1.obj sys2.obj
44 link @sys.lnk
45 exe2bin sys.exe sys.com
46 del sys.exe
diff --git a/v4.0/src/CMD/SYS/SYS.LNK b/v4.0/src/CMD/SYS/SYS.LNK
new file mode 100644
index 0000000..fd12b9d
--- /dev/null
+++ b/v4.0/src/CMD/SYS/SYS.LNK
@@ -0,0 +1,2 @@
1SYS1+SYS2+SYSSR,sys,sys.map /m;
2 \ No newline at end of file
diff --git a/v4.0/src/CMD/SYS/SYS.SKL b/v4.0/src/CMD/SYS/SYS.SKL
new file mode 100644
index 0000000..c9cebd9
--- /dev/null
+++ b/v4.0/src/CMD/SYS/SYS.SKL
@@ -0,0 +1,48 @@
1;================================================
2; Message Skeleton File
3;================================================
4
5:util SYS
6
7:class 1
8
9:use EXTEND15 ; INVALID DRIVE
10
11:class 2
12
13:use PARSE1 ;1 - Too many operands
14:use PARSE2 ;2 - Required operand missing
15 ;3 - Not in switch list provided
16 ;4 - Not in keyword list provided
17 ;5 - (reserved)
18 ;6 - Out of range specified
19 ;7 - Not in value list provided
20 ;8 - Not in string list provided
21:use PARSE9 ;9 - Invalid Parameter
22
23:class A
24
25:use 1 COMMON1
26
27:class B
28
29:def 7 "No room for system on destination disk",CR,LF ; Old
30:def 8 "Incompatible system size",CR,LF ; Old
31:use 9 COMMON30 ; System transferred Old
32:def 10 "No system on default drive",CR,LF ; Old
33:def 11 "Can not specify default drive",CR,LF ; New
34:def 12 "Write failure, diskette unusable",CR,LF ; New
35
36:class C
37
38:use 13 COMMON12 ; Cannot %1 to a Network drive Old
39:def 14 "Insert system disk in drive %1",CR,LF ; Old
40:use 15 COMMON19 ; Insert destination disk in drive %1 - Old
41:def 16 "Not able to SYS to %1 file system",CR,LF ; New
42:use 18 COMMON14 ; Cannot %1 a SUBSTed or ASSIGNed drive - NEW
43
44:class D
45
46:use 17 COMMON28 ; Press any key to continue. .; Old
47
48:end
diff --git a/v4.0/src/CMD/SYS/SYS1.ASM b/v4.0/src/CMD/SYS/SYS1.ASM
new file mode 100644
index 0000000..5d5db9d
--- /dev/null
+++ b/v4.0/src/CMD/SYS/SYS1.ASM
@@ -0,0 +1,3710 @@
1 TITLE SYS-1- Program
2 INCLUDE SYSHDR.INC
3 include version.inc
4 page 80,132
5
6false = 0
7
8DATA SEGMENT PARA PUBLIC
9
10 public TargDrvNum, TargSpec, bio_owns_it, DOS_VER
11 public packet, packet_sectors, packet_buffer
12 extrn THIS_DPB:dword, BUF:word, DIR_SECTOR:word, first_dir_sector:word
13
14; $SALUT (4,25,30,41)
15
16DOS_VER DB 0 ; DOS Version - 0 = current
17 ; 1 = 3.2 or 3
18DEFALT DB 0 ; Default Drive (source - NUMBER
19TargDrvNum DB 0 ; Target Drive (destination) - NUMBER
20TargDrv DB 0 ; Target Drive (destination) - LETTER
21TargSpec DB "A:\",0 ; z string for target name
22IF IBMCOPYRIGHT
23BIOSName DB "A:\IBMBIO.COM",0 ; z string for target name
24DOSName DB "A:\IBMDOS.COM",0 ; z string for target name
25ELSE
26BIOSName DB "A:\IO.SYS",0
27DOSName DB "A:\MSDOS.SYS",0
28ENDIF
29
30SourceBIOSName LABEL WORD
31SourceSpec DB "A:"
32 DB 53 dup (0)
33IF IBMCOPYRIGHT
34SourceBIOS DB "\IBMBIO.COM",0
35ELSE
36SourceBIOS DB "\IO.SYS",0
37ENDIF
38
39IF IBMCOPYRIGHT
40NameLen equ $ - SourceBios
41ELSE
42BiosNameLen equ $ - SourceBios
43ENDIF
44
45SourceDOSName DB "A:"
46 DB 53 dup (0)
47IF IBMCOPYRIGHT
48SourceDOS DB "\IBMDOS.COM",0
49ELSE
50SourceDOS DB "\MSDOS.SYS",0
51ENDIF
52
53IF IBMCOPYRIGHT
54ELSE
55DosNameLen equ $ - SourceDOS
56ENDIF
57
58SourceSize dw 2
59Spec_flag db 0
60
61IBMBIO_LOW DW 0 ;length of IBMBIO on disk
62IBMBIO_HIGH DW 0
63IBMDOS_LOW DW 0 ;length of old IBMDOS on disk
64IBMDOS_HIGH DW 0
65
66SIZE_OLD_HIGH DW 0
67SIZE_OLD_LOW DW 0
68
69NEWBIO_SIZE_LOW DW 0
70NEWBIO_SIZE_HIGH DW 0
71NEWDOS_SIZE_LOW DW 0
72NEWDOS_SIZE_HIGH DW 0
73
74
75Need_Clusters dw 0
76Bytes_Per_Cluster dw 0
77Number_Free_Clusters dw 0
78
79; $SALUT (4,9,17,41)
80 ;---------------------------------------
81 ; SRORAGE FOR COMMAND LINE PARAMETERS
82 ;---------------------------------------
83
84PARMS LABEL WORD
85 DW OFFSET PARMSX ; POINTER TO PARMS STRUCTURE
86 DB 0 ; NO DELIMITER LIST FOLLOWS
87 DB 0 ; NUMBER OF ADDITIONAL DELIMITERS
88
89 ;---------------------------------------
90 ; STRUCTURE TO DEFINE SYS SYNTAX REQUIREMENT
91 ;---------------------------------------
92
93PARMSX LABEL BYTE
94PAR_MIN DB 1 ; MINIMUM POSITIONAL PARAMETERS = 1 ;AC021;
95 DB 2 ; MAXIMUM PARAMETERS = 2 ;AC021;
96 DW OFFSET POS1 ; POINTER TO POSITIONAL DEFINITION
97 DW OFFSET POS1 ; POINTER TO SAME POSITIONAL DEFINITION;AC021;
98 DB 0 ; THERE ARE NO SWITCHES
99 DB 0 ; THERE ARE NO KEYWORDS IN PRINT SYNTAX
100
101 ;---------------------------------------
102 ; STRUCTURE TO DEFINE THE POSITIONAL PARAMETER (Drive ID)
103 ;---------------------------------------
104
105POS1 LABEL WORD
106POSREP DB reqd ; MATCH FLAG LOW ;AC021;
107POSTYP DB f_spec + drv_id ; MATCH FLAG HIGH ;AC021;
108 DW 0001H ; CAPS BY FILE TABLE
109 DW OFFSET POS_BUFF ; PLACE RESULT IN POSITIONAL BUFFER
110 DW OFFSET NOVALS ; NO VALUES LIST REQUIRED
111 DB 0 ; NO KEYWORDS
112
113reqd equ 0
114f_spec equ 2
115drv_id equ 1
116 ;---------------------------------------
117 ; VALUE LIST FOR POSITIONAL
118 ;---------------------------------------
119
120NOVALS LABEL WORD
121 DB 0 ; NO VALUES
122
123; $SALUT (4,25,30,41)
124
125 ;---------------------------------------
126 ; RETURN BUFFER FOR POSITIONAL INFORMATION
127 ;---------------------------------------
128POS_BUFF LABEL BYTE
129POS_TYPE DB ? ; TYPE RETURNED
130POS_ITEM_TAG DB ? ; SPACE FOR ITEM TAG
131POS_SYN DW ? ; POINTER TO LIST ENTRY
132POS_OFF LABEL WORD
133POS_DRV_ID DB ? ; SPACE FOR DRIVE NUMBER (1=A, 2=B, ect)
134 DB ? ; ;AC021;
135POS_SEG DW ? ; ;AC021;
136
137
138failopen equ 0 ; extended open 'does not exist action
139openit equ 1 ; extended open 'exists' action
140replaceit equ 2 ; extended open 'exists' action - replace
141
142OPEN_PARMS label dword
143
144open_off dw ? ; name pointer offset
145open_seg dw ? ; name pointer segment
146
147PACKET dw 0,0 ; CONTROL PACKET ;AN001;
148packet_sectors dw 0 ; COUNT ;AN001;
149PACKET_BUFFER dw 0,0 ; BUFFER ADDRESS ;AN001;
150
151 ;---------------------------------------
152 ; Buffer for IOCtl Get/Set Media
153 ;---------------------------------------
154
155IOCTL_BUF LABEL BYTE
156
157IOCtl_Level DW 0 ; INFO LEVEL (SET ON INPUT)
158IOCtl_Ser_No_Low DW ? ; SERIAL #
159IOCtl_Ser_No_Hi DW ? ; SERIAL #
160IOCtl_Vol_ID DB "NO NAME " ; VOLUME LABEL - 11 bytes
161IOCTL_File_Sys DB 8 DUP(' ') ; FILE SYSTEM TYPE
162
163IOCTL_Ser_Vol_Sys equ $ - IOCtl_Ser_No_Low
164file_sys_size equ $ - IOCtl_File_Sys
165
166File_Sys_End LABEL WORD
167
168 db 0 ; safety
169
170fat_12 DB "FAT12 " ; 12 bit FAT
171FAT_len equ $ - fat_12
172fat_16 DB "FAT16 " ; 16 or 32 bit FAT
173
174 ;---------------------------------------
175 ; SUBLIST for Message call
176 ;---------------------------------------
177
178.xlist
179 include sysmsg.inc
180
181 MSG_UTILNAME <SYS> ; ;AN000;
182
183 MSG_SERVICES <MSGDATA> ; ;AN000;
184.list
185
186SUBLIST LABEL DWORD
187
188 DB sub_size ; size of sublist
189 DB 0 ; reserved
190insert_ptr_off DW ? ; pointer to insert - offset
191insert_ptr_seg DW ? ; pointer to insert - segment
192insert_number DB 1 ; number of insert
193 DB Char_Field_ASCIIZ ;type flag
194insert_max DB 3 ; maximum field size (limited to 3)
195 ; - this handles - SYS
196 ; - and - D:\
197 DB 1 ; minimum field size
198 DB " " ; pad character
199
200sub_size equ $ - SUBLIST ; size of sublist
201
202sys_ptr db "SYS",0
203
204bio_owns_it db 0
205EntryFree db 0 ; for create file
206
207;*** WARNING ***
208; KEEP THE FOLLOWING ITEMS IN THE EXACT ORDER BELOW!!!
209DOSEntFree DB 1
210BIOSEntFree DB 1
211
212Xfer_data STRUC
213
214InFH DW ? ; file handle of source
215LenLow DW ? ; 32-bit length of source
216LenHigh DW ?
217FTime DW ? ; place to store time of write
218FDate DW ? ; place to store date of write
219OutFH DW ? ; fh of destination
220
221Xfer_data ENDS
222
223BIOSInFH DW ? ; file handle of source BIOS
224BIOSLenLow DW ? ; 32-bit length of BIOS
225BIOSLenHigh DW ?
226BIOSTime DW 2 DUP (?) ; place to store time of BIOS write
227BIOSOutFH DW ? ; fh of BIOS destination
228BIOSPos dw 0,0 ;AN001;lseek position into file
229
230DOSInFH DW ? ; file handle of source DOS
231DOSLenLow DW ? ; 32-bit length of DOS
232DOSLenHigh DW ?
233DOSTime DW 2 DUP (?) ; place to store time of DOS write
234DOSOutFH DW ? ; fh of DOS destination
235DOSPos dw 0,0 ;AN001;lseek position into file
236
237IF IBMCOPYRIGHT
238FCBDOS DB "IBMDOS COM"
239FCBBIO DB "IBMBIO COM"
240ELSE
241FCBDOS DB "MSDOS SYS"
242FCBBIO DB "IO SYS"
243ENDIF
244
245;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; The following is a Extended FCB
246ExtFCB db 0FFh
247 db 5 dup (0)
248 db DOS_volume_atrib
249ExtFCB_Drive db 0
250ExtFCB_Name db "???????????"
251 db 24 dup (0)
252;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
253
254DOS_BUFFER DB 80h DUP (?)
255cbBuf DW ? ; number of bytes in buffer
256pDOS DW ? ; offset of beginning of DOS in buffer
257pDOSEnd DW ? ; offset of end of DOS in buffer
258
259
260public boot
261BOOT LABEL BYTE
262.xlist
263 INCLUDE BOOT.INC
264.list
265 ;
266 ; Following structure used by Generic IOCTL call Get Device Parameters to get
267 ; the BPB of a hard disk. It 'overflows' into area of BUF.
268 ;
269DeviceParameters a_DeviceParameters <1,DEV_HARDDISK>
270
271DATA ENDS
272
273CODE SEGMENT PARA PUBLIC
274
275 EXTRN SYSLOADMSG:near, SYSDISPMSG:near, SYSPARSE:near
276 EXTRN Data_Space:WORD, Find_DPB:near,
277 EXTRN Move_DIR_Entry:near, Free_Cluster:near, Direct_Access:near
278
279 BREAK <SYS - Main>
280;******************* START OF SPECIFICATIONS ***********************************
281;Routine name: Main
282;*******************************************************************************
283;
284;Description: Main control routine. Subroutines are structured so that they
285; will pass back an error return code (message number) and set
286; the fail flag (CF) if there was a fatal error.
287;
288; NOTES:
289;
290; 1 - This program uses its own internal stack. The stack space provided
291; by DOS is used as an input buffer for transfering IBMBIO and IBMDOS.
292;
293; SYS is linked with the CODE segment followed by the DATA segment. The
294; last symbol in DATA is BUF. It marks the end end of data and the
295; start of the BUFfer. The BUFfer extends from here to SP. The first
296; 6.5Kb (13 sectors) in BUFfer are used for up to 12 sectors of the FAT
297; or the directory. In Main, the remaining space is set
298; as follows:
299; cdBuf = SP - ( FAT_BUF + BUF )
300;
301; 2 - The main line program calls 1 routine that loops until specific
302; requirements are met. It is:
303; Get_System_Files - if default drive has replaceable
304; media this routine loops until
305; a diskette with the correct system
306; files is inserted.
307;
308; 3 - Great effort is expended to keep the number of open files to a minimum.
309; This is required in case output is directed to NULL. (See DOS 4.00
310; PTR P71)
311;
312;Called Procedures: Init_Input_Output
313; Validate_Target_Drive
314; Get_System_Files
315; Check_SYS_Conditions
316; Do_SYS
317; Message
318;
319;Input: Command line input in PSP
320;
321;Ouput: no error - System transfered to target media
322; error - Appropriate error message displayed
323;
324;Change History: Created 5/01/87 FG
325;
326;******************* END OF SPECIFICATIONS *************************************
327;******************+ START OF PSEUDOCODE +**************************************
328;
329; START Main
330;
331; setup messages and parsing (CALL Init_Input_Output)
332; if there is no error and
333; verify target drive is valid (CALL Validate_Target_Drive)
334; if there is no error and
335; get system files loaded (CALL Get_System_Files)
336; if there is no error and
337; verify target drive is SYSable (Check_SYS_Conditions)
338; if there is no error and
339; perform SYS operation (CALL Do_SYS)
340; if no error and
341; clean up loose ends (CALL Do_End)
342; if no error
343; load return code (System transfered)
344; endif
345; display message (CALL Message)
346; ret
347;
348; END Main
349;
350;******************- END OF PSEUDOCODE -**************************************
351
352 ASSUME CS:CODE,DS:NOTHING,ES:NOTHING
353
354 ORG 80H
355
356PSP_PRAM DB 128 DUP(?)
357
358START: JMP BEGIN
359
360 DB " - SYS - Utility "
361 DB 01Ah
362
363 even
364
365 db 510 dup(0) ; stack
366
367EOS EQU BYTE PTR $
368
369 DW 0 ; RETURN OFFSET
370
371
372public Begin
373
374BEGIN PROC NEAR
375
376; $SALUT (4,4,9,41)
377
378 mov ax,OFFSET Data_Space
379 add ax,15 ; round up to next segment
380 mov cl,4 ; convert to segment value
381 shr ax,cl
382 mov cx,ds
383 add ax,cx ; generate DATA segment value
384 mov ds,ax
385
386 ASSUME DS:DATA,ES:NOTHING
387
388 mov cx,sp ; get lowest available spot
389 mov sp,OFFSET EOS ; set up internal stack
390 sub cx,FAT_BUF + (OFFSET BUF) ; leave room for:
391 ; CODE +
392 ; DATA +
393 ; FAT_BUF (12 sectors of FAT)
394
395 mov cbBuf,cx ; store length of Xfer buffer
396
397 mov dx,OFFSET DOS_BUFFER ; set up DTA
398 mov ah,SET_DMA
399 INT 21h
400
401 call Init_Input_Output ; setup messages and parsing ;AN000;
402
403; $if nc,and ; there is no error and ;AN000;
404 JC $$IF1
405
406 call Validate_Target_Drive ; verify target drive is valid ;AN000;
407
408; $if nc,and ; there is no error ;AN000;
409 JC $$IF1
410
411 call Get_System_Files ; get system files loaded ;AN000;
412
413; $if nc,and ; there is no error ;AN000;
414 JC $$IF1
415
416 call Check_SYS_Conditions ; verify target drive is SYSable ;AN000;
417
418; $if nc,and ; there is no error ;AN000;
419 JC $$IF1
420
421 call Do_SYS ; perform SYS operation ;AN000;
422
423; $if nc,and ; no error and ;AN000;
424 JC $$IF1
425
426 call Do_End ; clean up loose ends ;AN000;
427
428; $if nc ; no error ;AN000;
429 JC $$IF1
430
431 mov ax,(util_B shl 8) + done ; load return code (System transfered) ;AN000;
432
433; $endif ; ;AN000;
434$$IF1:
435
436 call Message ; display message ;AN000;
437
438 mov ah,exit ; just set function - RC set by MAIN
439 int 21h ; if version is < DOS 2.0 the int 21
440
441 ret ; ret if version < 2.00
442
443BEGIN ENDP
444
445 BREAK <SYS - Init_Input_Output >
446;******************* START OF SPECIFICATIONS ***********************************
447;Routine name: Init_Input_Output
448;*******************************************************************************
449;
450;Description: Initialize messages and Parse command line.
451;
452;Called Procedures: Preload_Messages
453; Parse_Command_Line
454;
455;Input: PSP command line at 81h and length at 80h
456;
457;Output: no error - CF = 0 AX = 0
458; error - CF = 1 AX = return code (message #)
459;
460;Change History: Created 5/01/87 FG
461;
462;******************* END OF SPECIFICATIONS *************************************
463;******************+ START OF PSEUDOCODE +**************************************
464;
465; START Init_Input_Output
466;
467; load messages (CALL Preload_Messages)
468; if no error
469; get DOS version
470; if not = current and
471; set not current flag
472; if not = current - 1
473; load incorrect DOS version message
474; set fail flag
475; else
476; if no error and
477; parse the saved command line (CALL Parse_Command_Line)
478; if no error
479; load return code (success)
480; endif
481; endif
482; endif
483; ret
484;
485; END Init_Input_Output
486;
487;******************- END OF PSEUDOCODE -**************************************
488
489public Init_Input_Output
490
491 Init_Input_Output PROC NEAR
492
493 call SysLoadMsg ; preload all error messages ;AN000;
494
495; $if c ; if error - set to Utility ;AN000;
496 JNC $$IF3
497 mov ah,0bh ; ;AN000;
498; $else ; ;AN019;
499 JMP SHORT $$EN3
500$$IF3:
501 mov ax,(GET_VERSION shl 8) ; ;AN019;
502 int 21h ; ;AN019;
503 xchg al,ah ; ;AN019;
504 cmp ax,(major_version shl 8) + minor_version ; ;AN019;
505; $if ne ; ;AN019;
506 JE $$IF5
507 mov DOS_VER,0ffh ; keep track that DOS is down a level ;AN019;
508 ; 0 = current (default)
509; $endif ; ff = down one level ;AN021;
510$$IF5:
511; $if be,and ; ;AN019;
512 JNBE $$IF7
513 cmp ax,DOS_low ; ;AC023;
514; $if ae ; ;AN019;
515 JNAE $$IF7
516
517
518
519cmp ax,(3 shl 8) + 40 ;;;; to
520; $if e ;;;; cover
521 JNE $$IF8
522mov DOS_VER,0 ;;;; 4.00
523; $endif ;;;; this must be remover
524$$IF8:
525
526
527
528
529 clc ; ;AN019;
530; $else ; ;AN019;
531 JMP SHORT $$EN7
532$$IF7:
533 mov ax,(util shl 8) + DOS_error ; ;AN019;
534 stc ; ;AN019;
535; $endif ; ;AN019;
536$$EN7:
537
538; $if nc,and ; no error and ;AN000;
539 JC $$IF12
540
541 xor cx,cx ; zero out # of parms processed so far ;AN000;
542 mov si,command_line ; move here to loop thru twice ;AN000;
543 call Parse_Command_Line ; parse the saved command line ;AN000;
544
545; $if nc ; no error ;AN000;
546 JC $$IF12
547
548 mov al,noerror ; load return code (success) ;AN000;
549
550; $endif ; ;AN000;
551$$IF12:
552; $endif ; ;AC019;
553$$EN3:
554
555 ret ; ;AN000;
556
557 ENDPROC Init_Input_Output
558
559 BREAK <SYS - Parse_Command_Line >
560;******************* START OF SPECIFICATIONS ***********************************
561;Routine name: Parse_Command_Line
562;*******************************************************************************
563;
564;Description: Parse the command line. Check for errors, loading return code and
565; setting fail flag if found. Use parse error messages except in
566; case of no parameters, which has its own message.
567;
568;Called Procedures: SysParse
569;
570;Input: None
571;
572;Output: no error - CF = 0
573; error - CF = 1 AX = return code (Parse error + error #)
574;
575;Change History: Created 5/01/87 FG
576;
577;******************* END OF SPECIFICATIONS *************************************
578;******************+ START OF PSEUDOCODE +**************************************
579;
580; START Parse_Command_Line
581;
582; parse command line (Call Do_Parse)
583; if parse error
584; call GetError to find out what happened
585; (fail flag set)
586; else
587; if filespec found
588; set up to move filespec into SourceBIOSName
589; call Move_It to do the move
590; save size of filespec
591; set source spec flag
592; else
593; call Set_Target to process drive id (only other non error
594; endif
595; turn off filespec as valid input
596; if first parm was NOT a filespec (ie a drive id)
597; turn on optional bit
598; else
599; force required parms to 2
600; endif
601; call Do_Parse
602; if no errors
603; call Set_Target to initialize drive id
604; call Do_Parse to look for EOF or error
605; if eol
606; clear error flag
607; else
608; call Get_Error to see what went wrong
609; endif
610; else
611; if not EOL
612; call Get_Error to see what went wrong
613; else
614; clear error flag
615; endif
616; endif
617; endif
618;
619; ret
620;
621; END Parse_Command_Line
622;
623;******************- END OF PSEUDOCODE -**************************************
624
625public Parse_Command_Line
626
627 Parse_Command_Line PROC NEAR
628 ;---------------------------------------
629 ; Parse Equates
630 ;---------------------------------------
631; $SALUT (4,27,34,41)
632
633eol equ -1 ; Indicator for End-Of-Line ;AN000;
634noerror equ 0 ; Return Indicator for No Errors ;AN000;
635command_line equ 081H ; offset of command line in PSP ;AN000;
636Syntax_Error equ 9 ; PARSE syntax error ;AN000;
637
638; $SALUT (4,4,9,41)
639
640 ;---------------------------------------
641 ; Get address of command line
642 ;---------------------------------------
643
644 push ds ; ;AN000;
645 pop es ; ;AN000;
646 lea di,PARMS ; ;AC021:
647
648 call Do_Parse ; ;AC021:
649
650 cmp ax,0 ; did we find our required parm? ;AN000;
651
652; $if ne ; no -check what happened ;AN000;
653 JE $$IF15
654
655 call Get_Error ; ;AC021;
656
657; $else ; ;AC021;
658 JMP SHORT $$EN15
659$$IF15:
660
661 cmp POS_TYPE,5 ; is it a file spec? ;AN021;
662; $if e ; if it is a file spec ;AN021;
663 JNE $$IF17
664 push ds ; copy spec into source ;AN021;
665 push di ; ;AN021;
666 push si ; ;AN021;
667 lea di,SourceSpec ; ;AN021;
668 mov si,word ptr POS_OFF ; ;AN021;
669 mov ax,POS_SEG ; ;AN021;
670 mov ds,ax ; ;AN021;
671
672 ASSUME ds:nothing,es:DATA
673
674 xor bx,bx ; ;AN021;
675
676 call Move_Source ; ;AN021;
677
678 pop si ; ;AN021;
679 pop di ; ;AN021;
680 pop ds ; ;AN021;
681
682 ASSUME ds:DATA,es:nothing
683
684 mov SourceSize,bx ; ;AN021;
685 mov Spec_Flag,1 ; set spec flag ;AN021;
686; $else ; must be a drive id ;AN021;
687 JMP SHORT $$EN17
688$$IF17:
689 call Set_Target ; initialize target just in case ;AN021;
690 mov SourceSpec,al ; save Source Spec ;AN000;
691 ; remember that the colon and size
692; $endif ; ;AN021;
693$$EN17:
694 and POSTYP,drv_id ; off filespec bit - on drive bit ;AN021;
695 cmp Spec_Flag,0 ; do we have a source spec ? ;AN021;
696; $if e ; if spec flag not set ;AN021;
697 JNE $$IF20
698 inc POSREP ; turn on optional ;AN021;
699; $else ; ;AN021;
700 JMP SHORT $$EN20
701$$IF20:
702 inc PAR_MIN ; must have the second parm. ;AN021;
703; $endif ; ;AN021;
704$$EN20:
705
706 call Do_Parse ; ;AN021;
707
708 cmp ax,0 ; no parse errors? ;AN000;
709
710; $if e ; if no error - must be a drive id ;AN021;
711 JNE $$IF23
712 call Set_Target ; initialize target ;AN021;
713 cmp Spec_Flag,0 ; do we have a source spec ? ;AN021;
714; $if e ; if spec flag not set ;AN021;
715 JNE $$IF24
716 inc Spec_Flag ; turn it on ;AN021;
717; $endif ; ;AN021;
718$$IF24:
719
720 call Do_Parse ; make sure there are no extra parms. ;AN021;
721 cmp ax,eol ; ;AN021;
722; $if e ; ;AN021;
723 JNE $$IF26
724 clc ; ;AN021;
725; $else ; ;AN021;
726 JMP SHORT $$EN26
727$$IF26:
728 call Get_Error ; ;AN021;
729; $endif ; ;AN021;
730$$EN26:
731; $else ; could be EOL or error ;AN021;
732 JMP SHORT $$EN23
733$$IF23:
734 cmp ax,eol ; is it EOL ? ;AN021;
735; $if ne ; if it is not eol ;AN021;
736 JE $$IF30
737 call Get_Error ; error - make sure it makes sense ;AN021;
738; $else ; ;AN021;
739 JMP SHORT $$EN30
740$$IF30:
741 clc ; ;AN021;
742; $endif ; ;AN021;
743$$EN30:
744; $endif ; ;AN021;
745$$EN23:
746; $endif ; ;AN000;
747$$EN15:
748
749 ret ; ;AN000;
750
751
752 Move_Source PROC NEAR
753
754; $search ; ;AN021;
755$$DO35:
756 lodsb ; ;AN021;
757 stosb ; ;AN021;
758 inc bl ; ;AN021;
759 cmp bl,54 ; are we past the maximum? ;AN021;
760; $exitif a ; ;AN021;
761 JNA $$IF35
762 mov ax,(util_B SHL 8) + bad_path ; Invalid path ;AN021;
763 stc ; ;AN021;
764; $orelse ; ;AN021;
765 JMP SHORT $$SR35
766$$IF35:
767 or al,al ; ;AN021;
768; $endloop z ; ;AN021;
769 JNZ $$DO35
770 dec bl ; ;AN021;
771 clc ; ;AN021;
772; $endsrch ; ;AN021;
773$$SR35:
774
775 ret ; ;AN021;
776
777 ENDPROC Move_Source
778
779 Do_Parse PROC NEAR
780
781 mov insert_ptr_off,si ; save it in case of error ;AN024;
782 push cs ; ;AN000;
783 pop ds ; ;AN000;
784 xor dx,dx ; ;AN021;
785
786 ASSUME ds:nothing,es:DATA
787
788 call SysParse ; parse command line ;AN000;
789
790 push es ; ;AN000;
791 pop ds ; ;AN000;
792
793 ASSUME ds:DATA,es:nothing
794
795
796 ret ; ;AN021;
797
798 ENDPROC Do_Parse
799
800 Set_Target PROC NEAR
801
802 mov al,byte ptr pos_drv_id ; initalize drive id ;AN000;
803 mov TargDrvNum,al ; save it for later ;AN000;
804 mov ExtFCB_Drive,al ; save it for finding VOL id ;AN000;
805 or al,num_2_letter ; convert to a drive letter ;AC000;
806 mov TargSpec,al ; save it for later ;AN000;
807 mov TargDrv,al ; ;AC000;
808 ret ; ;AN021;
809
810 ENDPROC Set_Target
811
812 Get_Error PROC NEAR
813
814 lea bx,Parse_Ret_Code ; error - make sure it makes sense ;AN000;
815 xlat cs:[bx] ; ;AN000;
816 mov ah,parse_error ; indicate parse error CLASS ;AN000;
817 stc ; set fail flag ;AN000;
818 ret ; ;AN021;
819
820 ENDPROC Get_Error
821
822Parse_Ret_Code label byte
823
824 db 0 ; Ret Code 0 - ;AN000;
825 db 1 ; Ret Code 1 - Too many operands ;AN000;
826 db 2 ; Ret Code 2 - Required operand missing;AC002;
827 db 9 ; Ret Code 3 - Not in switch list provided ;AC002;
828 db 9 ; Ret Code 4 - Not in keyword list provided;AC002;
829 db 9 ; Ret Code 5 - (not used) ;AN000;
830 db 9 ; Ret Code 6 - Out of range specified ;AN000;
831 db 9 ; Ret Code 7 - Not in value list provided
832 db 9 ; Ret Code 8 - Not in string list provided
833 db 9 ; Ret Code 9 - Syntax error
834
835 ENDPROC Parse_Command_Line
836
837 BREAK <SYS - Validate_Target_Drive >
838;******************* START OF SPECIFICATIONS ***********************************
839;Routine name: Validate_Target_Drive
840;*******************************************************************************
841;
842;Description: Verify that target drive was specified, is not default drive,
843; is a valid drive letter, and is not a network drive
844;
845;Called Procedures: Check_Default_Drive
846; Check_Target_Drive
847; Check_For_Network
848;
849;Input: None
850;
851;Output: no error - CF = 0 AX = 0
852; error - CF = 1 AX = return code (message #)
853;
854;Change History: Created 5/01/87 FG
855;
856;******************* END OF SPECIFICATIONS *************************************
857;******************+ START OF PSEUDOCODE +**************************************
858;
859; START Validate_Target_Drive
860;
861; can't have target as default (CALL Check_Default_Drive)
862; if no error and
863; can't have target as network (CALL Check_For_Network)
864; if no error
865; see if valid drive letter (CALL Check_Target_Drive)
866; ret
867;
868; END Validate_Target_Drive
869;
870;******************- END OF PSEUDOCODE -**************************************
871
872public Validate_Target_Drive
873
874 Validate_Target_Drive PROC NEAR
875
876 call Check_Default_Drive ; can't have target as default ;AN000;
877
878; $if nc,and ; no error and ;AN000;
879 JC $$IF40
880
881 call Check_For_Network ; can't have target as network ;AC022;
882
883; $if nc ; no error ;AN000;
884 JC $$IF40
885
886 call Check_Target_Drive ; see if valid drive letter ;AC022;
887
888; $endif ; ;AN000;
889$$IF40:
890
891 ret ; ;AN000;
892
893 ENDPROC Validate_Target_Drive
894
895 BREAK <SYS - Check_Default_Drive >
896;******************* START OF SPECIFICATIONS ***********************************
897;Routine name: Check_Default_Drive
898;*******************************************************************************
899;
900;Description: Check to see if drive specified is default drive. If it is,
901; load return code and set fail flag.
902;
903;Called Procedures: None
904;
905;Input: None
906;
907;Output: no error - CF = 0
908; error - CF = 1 AX = 16d - Can not specify default drive
909;
910;Change History: Created 5/01/87 FG
911;Change History: Ax021 2/22/88 FG
912;
913;******************* END OF SPECIFICATIONS *************************************
914;******************+ START OF PSEUDOCODE +**************************************
915;
916; START Check_Default_Drive
917;
918; initialize BIO and DOS found flags
919; if source specified
920; copy source into SourceDOSName from SourceBIOName
921; else
922; get_default_drive (INT21 Get_Default_Drive + 00 <1900>)
923; if target drive = default drive
924; load return code (Can not specify default drive)
925; set fail flag
926; else
927; initialize SourceBIOName and SourceDOSName
928; reset fail flag
929; endif
930; endif
931; remove blanks in \IBMBIO.COM
932; remove blanks in \IBMDOS.COM
933; ret
934;
935; END Check_Default_Drive
936;
937;******************- END OF PSEUDOCODE -**************************************
938
939public Check_Default_Drive
940
941 Check_Default_Drive PROC NEAR
942
943 push ds
944 pop es
945
946 ASSUME DS:DATA,ES:DATA
947
948 mov DOSEntFree,1 ; set to not found ;AC021;
949 mov BIOSEntFree,1 ; set to not found ;AC021;
950 cmp Spec_Flag,1 ; was a source specified ? ;AN021;
951; $if e ; if a source was specified ;AN021;
952 JNE $$IF42
953 lea si,SourceSpec ; copy source for IBMDOS.COM ;AN021;
954 mov al,[si] ; get the drive ID ;AN025;
955 sub al,num_2_letter ; convert it to a 1 base number ;AN025;
956 mov DEFALT,al ; save it in case its removable ;AN025;
957 lea di,SourceDOSName ; ;AN021;
958 mov cx,SourceSize ; set up size to move ;AN021;
959 rep movsb ; move it! ;AN021;
960
961; $else ; figure out what the default is ;AN021;
962 JMP SHORT $$EN42
963$$IF42:
964
965 mov ax,(Get_Default_Drive shl 8) + not_used ; get_default_drive
966 INT 21h ; Get_Default_Drive <1900>
967 inc al ; turn from phys drive to logical drive
968 mov DEFALT,al ; save default for later
969 mov SourceSpec,al
970 or SourceSpec,num_2_letter ; covert number to letter
971 cmp al,TargDrvNum ; is target drive = default drive
972; $if e ; if it is the same - we have a problem;AC000;
973 JNE $$IF44
974
975 mov ax,(util_B shl 8) + not_on_default ; load return code
976 ; - Can not specify default drive
977 stc ; set fail flag
978
979; $else ; it wasn't = so its ok ;AC000;
980 JMP SHORT $$EN44
981$$IF44:
982
983 ; initalize SourceBIOSNane, SourceDOSName
984 mov al,DEFALT
985 or al,num_2_letter ; turn into letter
986 mov byte ptr SourceBIOSName,AL ; twiddle source name
987 mov SourceDOSName,AL ; twiddle source name
988 clc ; reset fail flag ;AN000;
989
990; $endif ; ;AC000;
991$$EN44:
992; $endif ; ;AN021;
993$$EN42:
994; $if nc ; if no error to this point ;AN021;
995 JC $$IF48
996 cld ; ;AN021;
997
998 IF IBMCOPYRIGHT
999 mov bx,NameLen ; ;AN021;
1000 mov cx,bx ; ;AN021;
1001 ELSE
1002 mov cx,BIOSNameLen
1003 ENDIF
1004
1005 lea di,SourceBiosName ; move IBMBIO.COM into place ;AN021;
1006 add di,SourceSize ; move to end of specified part ;AN021;
1007 lea si,SourceBIOS ; point to system file name ;AN021;
1008 rep movsb ; ;AN021;
1009
1010 IF IBMCOPYRIGHT
1011 mov cx,bx ; ;AN021;
1012 ELSE
1013 mov cx,DosNameLen
1014 ENDIF
1015
1016 lea di,SourceDOSName ; move IBMDOS.COM into place ;AN021;
1017 add di,SourceSize ; move to end of specified part ;AN021;
1018 lea si,SourceDOS ; point to system file name ;AN021;
1019 rep movsb ; ;AN021;
1020; $endif ; ;AN021;
1021$$IF48:
1022
1023 ret ; ;AN000;
1024
1025 ENDPROC Check_Default_Drive
1026
1027 BREAK <SYS - Check_Target_Drive >
1028;******************* START OF SPECIFICATIONS ***********************************
1029;Routine name: Check_Target_Drive
1030;*******************************************************************************
1031;
1032;Description: Determine if target drive is valid. To do this, we will make an
1033; IOCTL - check media ID call.
1034;
1035;Called Procedures:
1036;
1037;Input: Default_Drive
1038;
1039;Output: no error - CF = 0
1040; error - CF = 1 AX = 16d - Can not specify default drive
1041;
1042;Change History: Created 5/01/87 FG
1043;
1044;******************* END OF SPECIFICATIONS *************************************
1045;******************+ START OF PSEUDOCODE +**************************************
1046;
1047; START Check_Target_Drive
1048;
1049; Check media ID (INT21 IOCTL + IOCTL_CHANGEABLE? <4408>)
1050; if no error
1051; if invalid drive
1052; set return code
1053; set fail flag
1054; else
1055; clear fail flag
1056; else
1057; reset fail flag
1058; endif
1059; if no error
1060; if ASSIGNed or SUBSTd drive
1061; set return code
1062; set fail flag
1063; else
1064; clear fail flag
1065; else
1066; reset fail flag
1067; endif
1068; ret
1069;
1070; END Check_Target_Drive
1071;
1072;******************- END OF PSEUDOCODE -**************************************
1073
1074public Check_Target_Drive
1075
1076 Check_Target_Drive PROC NEAR
1077
1078 mov bl,TargDrvNum ; get the target drive number ;AN000;
1079 mov ax,(IOCTL SHL 8) + IOCTL_CHANGEABLE? ; do a media check ;AC000;
1080 INT 21h ; IOCtl + 08 <4408> ;AC000;
1081
1082 cmp ax,0fh ; is it invalid - al = F (CF may be set;AC000;
1083
1084; $if e ; ;AC000;
1085 JNE $$IF50
1086
1087 mov ax,(DOS_error shl 8) + extended_15 ; load return code ;AC000;
1088 ; - invalid drive
1089 stc ; ;AC000;
1090
1091; $else ; if valid device so far - make sure ;AN012;
1092 JMP SHORT $$EN50
1093$$IF50:
1094 ; its not ASSIGNed or SUBSTed drive
1095 mov si,offset TargSpec ; point to Target Spec ;AN012;
1096 mov di,offset DIR_SECTOR ; point at output buffer ;AN012;
1097 mov ax,(xNameTrans SHL 8) ; check for name translation ;AN012;
1098 int 21h ; get real path ;AN012;
1099; $if nc ; ;AC012;
1100 JC $$IF52
1101 mov bl,byte ptr [TargSpec] ; get drive letter from path ;AN012;
1102 cmp bl,byte ptr DIR_SECTOR ; did drive letter change? ;AN012;
1103; $if ne ; if not the same, it be bad ;AN012;
1104 JE $$IF53
1105 lea si,sys_ptr ; set insert pointer in SUBLIST ;AN012;
1106 mov [insert_ptr_off],si ; ;AN012;
1107 mov [insert_ptr_seg],ds ; ;AN012;
1108 lea si,sublist ; set pointer to SUBLIST ;AN012;
1109 mov ax,(util_C shl 8) + cant_assign ; load ret cd (Cannot..SUB);AN012;
1110 stc ; tell user ;AN012;
1111; $else ; - its ok ;AN012;
1112 JMP SHORT $$EN53
1113$$IF53:
1114 clc ; keep going ;AN012;
1115; $endif ; ;AN012;
1116$$EN53:
1117; $else ; - its a critical error ;AN012;
1118 JMP SHORT $$EN52
1119$$IF52:
1120 xor ah,ah ; set up for extended error call ;AN012;
1121 inc ah ; ;AN012;
1122; $endif ; ;AN012;
1123$$EN52:
1124; $endif ; ;AN012;
1125$$EN50:
1126
1127 ret ; ;AC000;
1128
1129 ENDPROC Check_Target_Drive
1130
1131 BREAK <SYS - Check_For_Network >
1132;******************* START OF SPECIFICATIONS ***********************************
1133;Routine name: Check_For_Network
1134;*******************************************************************************
1135;
1136;Description: Verify that the target drive is local, and not a shared drive.
1137; If shared,load return code and set fail flag.
1138;
1139; NOTE: This is a design point on how to determine net
1140;
1141;CALLed Procedures: None
1142;
1143;Input: None
1144;
1145;Output: no error - CF = 0
1146; error - CF = 1 AX = return code = 7 - Cannot SYS to a Network drive
1147;
1148;Change History: Created 5/01/87 FG
1149;
1150;******************* END OF SPECIFICATIONS *************************************
1151;******************+ START OF PSEUDOCODE +**************************************
1152;
1153; START Check_For_Network
1154;
1155; IOCtl call to see if target drive is local
1156; if target drive not local (INT21 IOCtl + 09 <4409>) and
1157; if return code indicates network drive (test 1200h)
1158; set insert pointer in SUBLIST
1159; set pointer to SUBLIST
1160; load return code (Cannot SYS to a Network drive)
1161; set fail flag
1162; else
1163; reset fail flag
1164; endif
1165; ret
1166;
1167; END Check_For_Network
1168;
1169;******************- END OF PSEUDOCODE -**************************************
1170
1171public Check_For_Network
1172
1173 Check_For_Network PROC NEAR
1174
1175 ; IOCtl call to see if target drive is local
1176 mov bl,TargDrvNum ; x = IOCTL (getdrive, Drive+1) ;AC022;
1177 mov ax,(IOCTL SHL 8) + dev_local
1178 INT 21h ; IOCtl + dev_local <4409>
1179
1180; $if nc,and ; target drive local and ;AC000;
1181 JC $$IF59
1182
1183 test dx,1200H ; check if (x & 0x1000)
1184 ; (redirected or shared)
1185; $if nz ; return code indicates network drive ;AC000;
1186 JZ $$IF59
1187
1188 lea si,sys_ptr ; set insert pointer in SUBLIST ;AN000;
1189 mov [insert_ptr_off],si ; ;AN000;
1190 mov [insert_ptr_seg],ds ; ;AN000;
1191 lea si,sublist ; set pointer to SUBLIST ;AN000;
1192 mov ax,(util_C shl 8) + cant_network ; load return code (Cannot SYS to.;AC000;
1193 stc ; set fail flag ;AN000;
1194
1195; $else ; ;AC000;
1196 JMP SHORT $$EN59
1197$$IF59:
1198
1199 clc ; reset fail flag ;AC000;
1200
1201; $endif ; ;AC000;
1202$$EN59:
1203
1204 ret ; ;AN000;
1205
1206 ENDPROC Check_For_Network
1207
1208 BREAK <SYS - Get_System_Files >
1209;******************* START OF SPECIFICATIONS ***********************************
1210;Routine name: Get_System_Files
1211;*******************************************************************************
1212;
1213;Description: Ensure that the the files IBMBIO and IBMDOS are available
1214; on the source media. If they are not on the source media,
1215; and the media is removeable, a prompt will be issued to
1216; insert a new source.
1217;
1218;Called Procedures: Prompt_For_Media Open_File
1219; Check_Removable Fill_Memory
1220;
1221;Input: IBMBIO and IBMDOS on source media
1222;
1223;Output: no error - CF = 0
1224; error - CF = 1 AX = return code (message #)
1225;
1226;Change History: Created 5/01/87 FG
1227; Major change 1/07/88 FG Ax019 now makes SYS check
1228; for the CORRECT version
1229; of IBMBIO !
1230; IBMBIO looks like this:
1231;
1232; 1 2 3 4 5
1233; ÚÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄ
1234; ³ JMP ³ LO ³ HI ³extected_version³
1235; ÀÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄ
1236;******************* END OF SPECIFICATIONS *************************************
1237;******************+ START OF PSEUDOCODE +**************************************
1238;
1239; START Get_System_Files
1240;
1241; initalize SourceBIOSNane, SourceDOSName
1242; do
1243; find IBMBIOS
1244; if found and
1245; open file (CALL Open_File)
1246; if no error and
1247; find IBMDOS
1248; if found and
1249; open file (CALL Open_File)
1250; if no error and
1251; load memory with files (CALL Fill_Memory)
1252; if no error and
1253; if correct version of IBMBIO
1254; reset fail flag
1255; load success return code
1256; else
1257; check if source media replaceable (CALL Check_Removeable)
1258; if fail flag reset (replaceable)
1259; load message number (Insert system disk....)
1260; and class (utility)
1261; set up pointer to insert (drive id)
1262; prompt for source media (CALL Prompt_For_Media)
1263; if fail flag reset
1264; load return code (try again)
1265; endif
1266; endif
1267; endif
1268; leave if success return code
1269; leave if fail flag set
1270; enddo
1271; ret
1272;
1273; END Get_System_Files
1274;
1275;******************- END OF PSEUDOCODE -**************************************
1276
1277public Get_System_Files
1278
1279 Get_System_Files PROC NEAR
1280 cld
1281
1282; $search ; ;AC018;
1283$$DO62:
1284
1285 lea si,DOS_BUFFER ; set up addressability
1286 mov dx,OFFSET SourceBIOSName ; look on source for IBMBIOS
1287 mov CX,DOS_system_atrib ; its an 'everything' file
1288 mov ah,Find_First ; do a find first INT21
1289 INT 21h ; Find_First <4Exx>
1290
1291; $if nc,and ; if found and..................... ;AC000;
1292 JC $$IF63
1293 mov ax,ds:[si].find_buf_size_l ; move size (low and high) ;AC000;
1294 mov WORD PTR NEWBIO_SIZE_LOW,AX ; from DTA
1295 mov ax,ds:[si].find_buf_size_h ; to ;AC000;
1296 mov WORD PTR NEWBIO_SIZE_HIGH,AX ; SYS data space
1297 mov dx,OFFSET SourceBIOSName ; point to source name
1298 mov di,OFFSET BIOSInFH ; pointer to block of data
1299
1300 call Open_File ; open file
1301
1302; $if nc,and ; if no error and.................... ;AC000;
1303 JC $$IF63
1304
1305 mov dx,OFFSET SourceDOSName ; look on source for IBMDOS
1306 mov CX,DOS_system_atrib ; its an 'everything' file
1307 mov ah,Find_First ; do a find first INT21
1308 INT 21h ; Find_First <4Exx>
1309
1310; $if nc,and ; if found and....................... ;AC000;
1311 JC $$IF63
1312
1313 mov ax,ds:[si].find_buf_size_l ; move size (low and high) ;AC000;
1314 mov WORD PTR NEWDOS_SIZE_LOW,AX ; from DTA
1315 mov ax,ds:[si].find_buf_size_h ; to ;AC000;
1316 mov WORD PTR NEWDOS_SIZE_HIGH,AX ; SYS data space
1317 mov dx,OFFSET SourceDOSName ; pointer to source of DOS
1318 mov di,OFFSET DOSInFH ; pointer to block of data
1319
1320 call Open_File ; open file
1321
1322; $if nc,and ; if no error and......................;AC000;
1323 JC $$IF63
1324
1325 call Fill_Memory ; load memory with files
1326
1327; $if nc,and ; if no error..................: ;AC019;
1328 JC $$IF63
1329
1330 cmp WORD PTR BUF+FAT_BUF+3,expected_version ; point to beginning ;AN019;
1331 ; of buffer + near jump instruction
1332
1333; $if e ; if correct version of IBMBIO ;AN019;
1334 JNE $$IF63
1335
1336 clc ; reset fail flag ;AN019:
1337 mov al,noerror ; load success return code ;AN000;
1338
1339; $else ; ELSE - something wrong with source ;AC000;
1340 JMP SHORT $$EN63
1341$$IF63:
1342
1343 mov bl,defalt ;; specify drive ;;dcl ;AN001;
1344 call Check_Removeable ; check if source media replaceable ;AC000;
1345
1346; $if nc ; fail flag reset (replaceable) ;AC000;
1347 JC $$IF65
1348
1349 mov ax,(util_C shl 8) + sys_disk ; load message number ;AC000;
1350 ; - Insert system disk....
1351 lea si,SourceSpec ; set insert pointer to DRIVE ID ;AC000;
1352 mov bx,SourceSize ; only display correct path length ;AN025;
1353
1354 call Prompt_For_Media ; prompt for source media ;AN000;
1355
1356; $if nc ; fail flag reset ;AC000;
1357 JC $$IF66
1358
1359 mov ax,error_RC ; load return code (try again) ;AN000;
1360
1361; $endif ; ;AC000;
1362$$IF66:
1363
1364; $endif ; ;AC000;
1365$$IF65:
1366
1367; $endif ; ;AC000;
1368$$EN63:
1369
1370; $leave c ; if fail flag set ;AC018;
1371 JC $$EN62
1372
1373 cmp al,noerror ; is it an error return code? ;AC018;
1374
1375; $exitif e ; quit if success return code ;AC018;
1376 JNE $$IF62
1377
1378 mov bx,BIOSInFH ; ;AC018;
1379 mov ah,Close ; ;AC018;
1380 int 21h ; ;AC018;
1381
1382 mov bx,DOSInFH ; ;AC018;
1383 mov ah,Close ; ;AC018;
1384 int 21h ; ;AC018;
1385
1386; $orelse ; ;AN018;
1387 JMP SHORT $$SR62
1388$$IF62:
1389
1390; $endloop long ; ;AC018;
1391 JMP $$DO62
1392$$EN62:
1393; $endsrch ; ;AN018;
1394$$SR62:
1395
1396
1397
1398 ret ; ;AN000;
1399
1400 ENDPROC Get_System_Files
1401
1402 BREAK <SYS - Prompt_For_Media >
1403;******************* START OF SPECIFICATIONS ***********************************
1404;Routine name: Prompt_For_Media
1405;*******************************************************************************
1406;
1407;Description: Make call to Message to display:
1408;
1409; Insert system disk in drive %1
1410; and strike any key when ready
1411;
1412;Called Procedures: Message
1413;
1414;Input: (AL) = message #
1415; (BL) = drive/path length
1416; (SI) = insert pointer
1417;
1418;Output: no error - CF = 0
1419; error - CF = 1 AX = return code (DOS error)
1420;
1421;Change History: Created 5/01/87 FG
1422;
1423;******************* END OF SPECIFICATIONS *************************************
1424;******************+ START OF PSEUDOCODE +**************************************
1425;
1426; START Prompt_For_Media
1427;
1428; set up for message call
1429; call Message - display first line
1430; if no error
1431; clear insert indicator
1432; load Message #x - Press any key to continue
1433; ask for keystroke response (direct CON in no echo)
1434; call Message - display second line
1435; endif
1436; if error
1437; load return code (DOS extended error)
1438; endif
1439; ret
1440;
1441; END Prompt_For_Media
1442;
1443;******************- END OF PSEUDOCODE -**************************************
1444
1445public Prompt_For_Media
1446
1447 Prompt_For_Media PROC NEAR
1448
1449 mov [insert_ptr_off],si ; set up for message call ;AN000;
1450 mov [insert_ptr_seg],ds
1451 mov insert_max,bl ; only display correct path length ;AN025;
1452 lea si,sublist ; set pointer to SUBLIST ;AN000;
1453
1454 call Message ; display first line ;AN000;
1455
1456; $if nc ; if no error ;AN000;
1457 JC $$IF75
1458
1459 mov ax,(util_D shl 8) + press_key ; load Message ;AN000;
1460 ; - Press any key to continue
1461 ; the class will signal to ask for
1462 ; keystroke response
1463 ; (direct CON in no echo)
1464 call Message ; display second line ;AN000;
1465
1466; $endif ; ;AN000;
1467$$IF75:
1468
1469; $if c ; if an error occured ;AN000;
1470 JNC $$IF77
1471
1472 mov ah,DOS_error ; load return code (DOS extended error);AN000;
1473
1474; $endif ; ;AN000;
1475$$IF77:
1476
1477 ret ; ;AN000;
1478
1479 ENDPROC Prompt_For_Media
1480
1481 BREAK <SYS - Check_Removeable >
1482;******************* START OF SPECIFICATIONS ***********************************
1483;Routine name: Check_Removeable
1484;*******************************************************************************
1485;
1486;Description: Make IOCtl call to see if media in the drive indicated in
1487; BX is removable
1488;
1489;Called Procedures: None
1490;
1491;Input: BX has drive (0=default, 1=A)
1492;
1493;Output: removeable - CF = 0
1494; nonremovable or error - CF = 1
1495; AX = 11d - No system on default drive
1496;
1497;Change History: Created 5/01/87 FG
1498;
1499;******************* END OF SPECIFICATIONS *************************************
1500;******************+ START OF PSEUDOCODE +**************************************
1501;
1502; START Check_Removeable
1503;
1504; if source not specified
1505; do an IOCTL changeable check (INT21 IOCtl + 08 <4408>)
1506; if no error
1507; test if removeable
1508; if removeable
1509; reset fail flag
1510; else
1511; load return code (No system on default drive)
1512; set fail flag
1513; endif
1514; endif
1515; else
1516; load return code (No system on specified path)
1517; set fail flag
1518; endif
1519; ret
1520;
1521; END Check_Removeable
1522;
1523;******************- END OF PSEUDOCODE -**************************************
1524
1525public Check_Removeable
1526
1527 Check_Removeable PROC NEAR
1528
1529 mov ax,(IOCTL SHL 8) + IOCTL_CHANGEABLE? ; do a media check
1530 INT 21h ; IOCtl + 08 <4408>
1531 ; cy set if remote or invalid device ;;dcl;;
1532; $if nc ;
1533 JC $$IF79
1534 cmp ax,0 ;
1535; $if e ;
1536 JNE $$IF80
1537 clc ;
1538; $else ;
1539 JMP SHORT $$EN80
1540$$IF80:
1541 cmp Spec_Flag,1 ; ;AC025;
1542; $if ne ; ;AC025;
1543 JE $$IF82
1544 mov ax,(util_B shl 8) + no_sys_on_def ; No system on... ;AC000;
1545; $else ; ;AC025;
1546 JMP SHORT $$EN82
1547$$IF82:
1548 mov ax,(util_B shl 8) + system_not_found ; Invalid path or Sy..;AN021;
1549; $endif ; ;AC025;
1550$$EN82:
1551 stc ;
1552; $endif ;
1553$$EN80:
1554; $endif ;
1555$$IF79:
1556
1557 ret ; ;AN021;
1558
1559 ENDPROC Check_Removeable
1560
1561 BREAK <SYS - Open_File >
1562;******************* START OF SPECIFICATIONS ***********************************
1563;Routine name: Open_File
1564;*****************************************************************************
1565;
1566;Description: Opens file and gets size and date
1567;
1568;Called Procedures: None
1569;
1570;Input: ES:DI = Data space for DOS operations
1571;
1572;Output: no error - CF = 0
1573; error - CF = 1 AX = DOS extended errors
1574;
1575;Change History: Created 5/01/87 FG
1576;
1577;******************* END OF SPECIFICATIONS *************************************
1578;******************+ START OF PSEUDOCODE +**************************************
1579;
1580; START Open_File
1581;
1582; open file for read (INT21 Read + 00 <3D00>)
1583; if no error
1584; save handle
1585; find End Of File (INT21 LSeak + 02 <4202>)
1586; zero offsets
1587; get offsets (INT21)
1588; save low part of size
1589; save high part of size
1590; find start of file (INT21 LSeak + 00 <4200>)
1591; find last write time(INT21 File_Times + 00 <5700>)
1592; save time
1593; save date
1594; else
1595; load return code (DOS extended errors)
1596; endif
1597; ret
1598;
1599; END Open_File
1600;
1601;******************- END OF PSEUDOCODE -**************************************
1602
1603public open_file
1604
1605 Open_File PROC NEAR
1606
1607 mov ax,(OPEN SHL 8) + not_used ; open file for read
1608 INT 21h ; Read + not_used <3D00>
1609
1610; $if nc ; no error ;AC000;
1611 JC $$IF87
1612
1613 mov es:[di].InFH,ax ; save file handle ;AC000;
1614 mov bx,ax ; get ready for seeks
1615 mov ax,(LSeek SHL 8) + LSeek_EOF ; seek relative to eof
1616 xor cx,cx ; zero offset
1617 xor dx,dx ; zero offset
1618 INT 21h ; find End Of File to get offsets
1619 ; LSeak + LSeek_EOF <4202>
1620 mov es:[di].LenLow,ax ; save low part of size ;AC000;
1621 mov es:[di].LenHigh,dx ; save high part of size ;AC000;
1622 xor dx,dx ; zero offset
1623 mov ax,(LSeek SHL 8) + LSeek_Start ; seek relative to beginning
1624 INT 21h ; LSeak + LSeek_Start <4200>
1625 mov ax,(File_Times SHL 8) + 0 ; find last write time
1626 INT 21h ; File_Times + not_used <5700>
1627 mov es:[di].FTime,cx ; save time ;AC000;
1628 mov es:[di].FDate,dx ; save date ;AC000;
1629
1630; $else ; ;AC000;
1631 JMP SHORT $$EN87
1632$$IF87:
1633
1634 mov ah,DOS_error ; load return code (DOS extended error);AC000;
1635
1636; $endif ; ;AC000;
1637$$EN87:
1638
1639 ret
1640
1641 ENDPROC Open_File
1642
1643 BREAK <SYS - Fill_Memory >
1644;******************* START OF SPECIFICATIONS ***********************************
1645;Routine name: Fill_Memory
1646;*******************************************************************************
1647;
1648;Description: Read in as much of IBMBIOS and IBMDOS as room permits
1649;
1650;Called Procedures: None
1651;
1652;Input: None
1653;
1654;Output: no error - CF = 0
1655; error - CF = 1
1656;
1657;Change History: Created 5/01/87 FG
1658;
1659;******************* END OF SPECIFICATIONS *************************************
1660;******************+ START OF PSEUDOCODE +**************************************
1661;
1662; START Fill_Memory
1663;
1664; get length of buffer
1665; get BIOS source handle
1666; point to beginning of buffer
1667; save total buffer length
1668; if < 64k to read and
1669; if amount to read < buffer
1670; set length to IBMBIO length
1671; endif
1672; if amount to read > 0
1673; read the file (INT21 read +00 <3F00>)
1674; else
1675; set size to zero
1676; clear error flag (CF)
1677; endif
1678; if error or
1679; if not all of file read
1680; recover size
1681; set fail flag
1682; else
1683; update pointer for dos read
1684; recover size
1685; calculate remainder
1686; get DOS source handle
1687; if < 64k to read and
1688; if amount to read < buffer
1689; set length to IBMBIO length
1690; endif
1691; read the file (INT21 read +00 <3F00>)
1692; if no error and
1693; if all of file read
1694; update pointer for DOS read
1695; reset fail flag
1696; endif
1697; endif
1698; ret
1699;
1700; END Fill_Memory
1701;
1702;******************- END OF PSEUDOCODE -**************************************
1703
1704public fill_memory
1705
1706 Fill_Memory PROC NEAR
1707
1708 mov ax,4200h ; LSEEK to end of last read ;AN001;
1709 mov bx,BIOSInFH ; ;AN001;
1710 mov cx,BIOSPos[2] ; ;AN001;
1711 mov dx,BIOSPos[0] ; ;AN001;
1712 int 21h ; ;AN001;
1713 mov ax,4200h ; LSEEK to end of last read ;AN001;
1714 mov bx,DOSInFH ; ;AN001;
1715 mov cx,DOSPos[2] ; ;AN001;
1716 mov dx,DOSPos[0] ; ;AN001;
1717 int 21h ; ;AN001;
1718
1719 mov cx,cbBuf ; get length of buffer
1720 mov bx,BIOSInFH ; get bios source handle
1721 mov dx,OFFSET BUF+FAT_BUF ; point to beginning of buffer
1722 ; past area to read in boot rec
1723 push cx ; save away total length
1724 cmp BIOSLenHigh,0 ; is there < 64K to read?
1725
1726; $if e,and ; if so - or................... ;AC000;
1727 JNE $$IF90
1728 ; :
1729 cmp BIOSLenLow,cx ; more left to read? :
1730 ; ie: is amount to read < buffer
1731; $if b ; if amount to read < buffer..: ;AC000;
1732 JNB $$IF90
1733
1734 mov cx,BIOSLenLow ; set length to IBMBIO length
1735
1736; $endif ; ;AC000;
1737$$IF90:
1738
1739 cmp cx,0 ; is there anything to read?
1740
1741; $if a ; if so - read it
1742 JNA $$IF92
1743
1744 mov ah,Read ; read the file
1745 int 21h ; read + not_used <3F00>)
1746
1747; $else ; don't bother
1748 JMP SHORT $$EN92
1749$$IF92:
1750
1751 xor ax,ax
1752 clc
1753
1754; $endif
1755$$EN92:
1756
1757; $if c,or ; if error or.................. ;AC000;
1758 JC $$LL95
1759
1760 cmp ax,cx ; Did we get it all? :
1761
1762; $if nz ; if not all of file read.....: ;AC000;
1763 JZ $$IF95
1764$$LL95:
1765
1766 pop cx ; recover size
1767 stc ; set fail flag
1768
1769; $else ; ;AC000;
1770 JMP SHORT $$EN95
1771$$IF95:
1772
1773 add BIOSPos[0],ax ; save amount read for later lseek ;AN001;
1774 adc BIOSPos[2],0 ; save amount read for later lseek ;AN001;
1775
1776 add dx,ax ; update pointer for DOS Read
1777 mov pDOS,dx ; point to beginning of DOS
1778 sub BIOSLenLow,ax ; decrement remaining
1779 sbb BIOSLenHigh,0 ; do 32 bit
1780 pop cx ; get original length
1781 sub cx,ax ; this much is left
1782 mov bx,DOSInFH ; get bios source handle
1783 cmp DOSLenHigh,0 ; > 64K to read?
1784; $if e,and ; if < 64k to read and.......... ;AC000;
1785 JNE $$IF97
1786 cmp DOSLenLow,cx ; is amount to read < buffer :
1787
1788; $if b ; if its less .................: ;AC000;
1789 JNB $$IF97
1790
1791 mov cx,DOSLenLow ; set length to IBMDOS length
1792
1793; $endif ; ;AC000;
1794$$IF97:
1795
1796 mov ah,Read ; read the file
1797 INT 21h ; read + not_used <3F00>)
1798
1799; $if nc,and ; no error and................... ;AC000;
1800 JC $$IF99
1801
1802 cmp ax,cx ; is all of file read ? :
1803
1804; $if z ; all of file read..............: ;AC000;
1805 JNZ $$IF99
1806
1807 add DOSPos[0],ax ; save amount read for later lseek ;AN001;
1808 adc DOSPos[2],0 ; save amount read for later lseek ;AN001;
1809
1810 add dx,ax ; update pointer for DOS Read
1811 mov pDOSEnd,DX ; point to End of dos DOS
1812 sub DOSLenLow,AX ; decrement remaining
1813 sbb DOSLenHigh,0 ; do 32 bit arithmetic
1814 clc ; reset fail flag
1815
1816; $endif ; ;AC000;
1817$$IF99:
1818
1819; $endif ; ;AC000;
1820$$EN95:
1821
1822 ret
1823
1824 ENDPROC Fill_Memory
1825
1826 BREAK <SYS - Check_SYS_Conditions >
1827;******************* START OF SPECIFICATIONS ***********************************
1828;Routine name: Check_SYS_Conditions
1829;*******************************************************************************
1830;
1831;Description: Verify that the target disk is in a state that a SYS to it will
1832; be allowed. If an error occurs in any of the called routines,
1833; the return code will already be loaded by the failing routine.
1834;
1835;Called Procedures: Verify_File_System
1836; Read_Directory
1837; Verify_File_Location
1838; Determine_Free_Space
1839;
1840;Input: None
1841;
1842;Output: no error - CF = 0
1843; error - CF = 1 AX = return code (message #)
1844;
1845;Change History: Created 5/01/87 FG
1846;
1847;******************* END OF SPECIFICATIONS *************************************
1848;******************+ START OF PSEUDOCODE +**************************************
1849;
1850; START Check_SYS_Conditions
1851;
1852; verify target is a FAT file system (CALL Verify_File_System)
1853; if no error and
1854; load root directory of target (CALL Read_Directory)
1855; if no error and
1856; check that IBMBIO,IBMDOS are in right place (CALL Verify_File_Location)
1857; if no error and
1858; check for sufficient space for system files (CALL Determine_Free_Space)
1859; if no error
1860; load return code (success)
1861; reset fail flag
1862; endif
1863; ret
1864;
1865; END Check_SYS_Conditions
1866;
1867;******************- END OF PSEUDOCODE -**************************************
1868
1869public Check_SYS_Conditions
1870
1871 Check_SYS_Conditions PROC NEAR
1872
1873 call Verify_File_System ; verify target is a FAT file system ;AN000;
1874
1875; $if nc,and ; no error and ;AN000;
1876 JC $$IF102
1877
1878 call Read_Directory ; load root directory of target ;AN000;
1879
1880; $if nc,and ; no error and ;AN000;
1881 JC $$IF102
1882
1883 call Verify_File_Location ; check that IBMBIO,IBMDOS are in right;AN000;
1884 ; place
1885; $if nc ; no error and ;AN000;
1886 JC $$IF102
1887
1888 call Determine_Free_Space ; check if enough space for system file;AN000;
1889
1890; $endif ; ;AN000;
1891$$IF102:
1892
1893 ret ; ;AN000;
1894
1895 ENDPROC Check_SYS_Conditions
1896
1897 BREAK <SYS - Verify_File_System >
1898;******************* START OF SPECIFICATIONS ***********************************
1899;Routine name: Verify_File_System
1900;*******************************************************************************
1901;
1902;Description: Get the file system for the specified drive, then compare to
1903; FAT. If not, issue message and exit. Must ensure that target
1904; drive has media in it before this routine is called
1905;
1906;Note: This routine contains code that is specifically required for
1907; operation on DOS 3.3. This code must be removed for later releases
1908; of DOS.
1909;
1910;Called Procedures: None
1911;
1912;Input: Drive Number (0=default, 1=A, 2=B) in BL
1913;
1914;Output: no error - CF = 0
1915; error - CF = 1
1916; AX = return code
1917; AH = utility messages
1918; AL = 15d - Not able to SYS to xxx file system
1919; CX = 1 - only one substitution
1920; DS:SI = sublist for substitution
1921;
1922;Change History: Created 5/01/87 FG
1923;
1924;******************* END OF SPECIFICATIONS *************************************
1925;******************+ START OF PSEUDOCODE +**************************************
1926;
1927; START Verify_File_System
1928;
1929; if dos = current
1930; load drive id (BL)
1931; get_extended_device_parameters (INT21 IOCtl + 0Dh <440D> CX=086E) for drive
1932; if error - check if old version destination
1933; find out what the error was (CALL Get_DOS_Error)
1934; if not old version error
1935; load return code (DOS Extended Error Class)
1936; set fail flag
1937; else
1938; reset fail flag
1939; endif
1940; else
1941; if returned file system type = "FAT12 " or
1942; if returned file system type = "FAT16 "
1943; reset fail flag
1944; else
1945; indicate insert required
1946; set up pointer for insert - sublist
1947; load return code (Unable to SYS to xxxxxxxx file system)
1948; set fail flag
1949; endif
1950; endif
1951; endif
1952;
1953; ret
1954;
1955; END Verify_File_System
1956;
1957;******************- END OF PSEUDOCODE -**************************************
1958
1959public Verify_File_System
1960
1961 Verify_File_System PROC NEAR
1962
1963 cmp DOS_VER,0 ; running on current DOS ? ;AN019;
1964; $if e ; if we are ;AN019;
1965 JNE $$IF104
1966 mov bl,TargDrvNum ; load drive id (BL) ;AN000;
1967 lea dx,IOCtl_Buf ; point to output buffer ;AN000;
1968 mov ax,(GetSetMediaID shl 8) + 0 ; get volid, ser# and filetype ;AC019;
1969 INT 21h ; INT 21 GetSetMediaID request <6900> ;AC019;
1970
1971; $if c ; error - check if old version dest ;AN000;
1972 JNC $$IF105
1973
1974 call Get_DOS_Error ; find out what the error was ;AN000;
1975
1976 cmp al,old_type_media ; is it IBM but < 4.0 ? ;AN000;
1977
1978; $if ne ; not old version error ;AN000;
1979 JE $$IF106
1980
1981 mov ah,DOS_error ; load return code (DOS Extended Error);AN000;
1982 stc ; set fail flag ;AN000;
1983
1984; $else ; ;AN000;
1985 JMP SHORT $$EN106
1986$$IF106:
1987
1988 clc ; reset fail flag ;AN000;
1989
1990; $endif ; ;AN000;
1991$$EN106:
1992
1993; $else ; ELSE it is => 4.00 ;AN000;
1994 JMP SHORT $$EN105
1995$$IF105:
1996
1997 lea si,IOCtl_File_Sys ; see if file type is fat12 ;AN000;
1998 lea di,fat_12 ; ;AN000;
1999 mov cx,file_sys_size ; ;AN000;
2000 cld ; ;AN000;
2001 repe cmpsb ; ;AN000;
2002 cmp cx,3 ; did it fail at the 2 in fat12 ? ;AN000;
2003
2004; $if e,and ; if it did and............ ;AN000;
2005 JNE $$IF110
2006
2007 cmp BYTE PTR ds:[si-1],"6" ; was it a 6 ? : ;AN000;
2008
2009; $if e ; if it was...............: ;AN000;
2010 JNE $$IF110
2011
2012 repe cmpsb ; then keep going ;AN000;
2013
2014; $endif ; ;AN000;
2015$$IF110:
2016
2017 cmp cx,0 ; did we reach the end ? ;AN000;
2018
2019; $if e ; if we did it was "FAT12 " or ;AN000;
2020 JNE $$IF112
2021 ; "FAT16 " so its OK to SYS
2022
2023 clc ; reset fail flag ;AN000;
2024
2025; $else ; ;AN000;
2026 JMP SHORT $$EN112
2027$$IF112:
2028
2029 lea di,File_Sys_End ; set up pointer to end of insert ;AN000;
2030 dec di ; back up to last character ;AN000;
2031 mov cx,file_sys_size ; strip off trailing blanks ;AN017;
2032 mov al," " ; strip off trailing blanks ;AN017;
2033 std ; scan backwards ;AN017;
2034 repe scas IOCTL_File_Sys ; ;AN017;
2035 cld ; stops at 2 past last " " ;AN017;
2036 inc di ; 1 past ;AN017;
2037 inc di ; last (first) blank ;AN017;
2038 xor al,al ; make it an ASCIIZ ;AN017;
2039 stos IOCTL_File_Sys ; ;AN017;
2040 lea si,IOCTL_File_Sys ; set up pointer to the insert ;AN000;
2041 mov [insert_ptr_off],si ; ;AN017;
2042 mov [insert_ptr_seg],ds ; ;AN017;
2043 lea si,sublist ; set pointer to SUBLIST ;AN017;
2044 mov ax,(util_C shl 8) + cant_sys ; load return code ;AN000;
2045 ; - Unable to SYS to xxx file system
2046 stc ; set fail flag ;AN000;
2047
2048; $endif ; ;AN000;
2049$$EN112:
2050
2051; $endif ; ;AN000;
2052$$EN105:
2053
2054; $else ; not running on current DOS ;AN019;
2055 JMP SHORT $$EN104
2056$$IF104:
2057
2058 clc ; keep going ;AN019;
2059
2060; $endif ; running on current DOS ;AN019;
2061$$EN104:
2062
2063 ret ; ;AN000;
2064
2065 ENDPROC Verify_File_System
2066
2067 BREAK <SYS - Read_Directory >
2068;******************* START OF SPECIFICATIONS ***********************************
2069;Routine name: Read_Directory
2070;*******************************************************************************
2071;
2072;Description: Read in first sector of directory. The reason that we do the
2073; direct read of the directory is the find first/next or search
2074; first/next do an exclusive search for volume labels. By using
2075; these CALLs, there is no way to determine if a volume label
2076; occupies the first location in the directory. Hence we get sleazy
2077; and read the directory directly (no pun intended) to get this
2078; info. Only read in the first sector of directory. Also, this
2079; ensures there is a media in the drive.
2080;
2081;CALLed Procedures: Prompt_for_Media, Find_DPB
2082;
2083;Input: None
2084;
2085;Output: no error - CF = 0
2086; error - CF = 1 AX = return code (message #)
2087;
2088;Change History: Created 5/01/87 FG
2089;
2090;******************* END OF SPECIFICATIONS *************************************
2091;******************+ START OF PSEUDOCODE +**************************************
2092;
2093; START Read_Directory
2094;
2095; set up drive letter in destignation filespecs
2096; call Find_DPB to get directory location
2097; load first DIR sector number
2098; point at buffer for directory
2099; read first sector of directory (INT 25h)
2100; ret
2101;
2102; END Read_Directory
2103;
2104;******************- END OF PSEUDOCODE -**************************************
2105
2106 public Read_Directory
2107
2108 Read_Directory PROC NEAR
2109
2110 mov al,TargDrv ; set up drive letter in destignation filespecs
2111 mov BIOSName,al ; point names at destination drive
2112 mov DOSName,al ;
2113
2114 MOV DL,TargDrvNum ; load drive
2115 PUSH DS ; save register
2116 call Find_DPB ; initalize DPB parameters
2117 POP AX
2118 mov ds,ax
2119 mov es,ax
2120 xor ax,ax ; request a read
2121 mov dx,[first_dir_sector] ; read starting dir sector
2122 mov [packet],dx ; get starting dir sector ;AN001;
2123 mov bx,offset DIR_SECTOR
2124 mov PACKET_BUFFER[0],bx ; ;AN001;
2125 mov PACKET_BUFFER[2],ds ; ;AN001;
2126 mov word ptr [packet_sectors],1 ; ;AN001;
2127 call Direct_Access ; to read the sector
2128
2129 mov ax, (util_B shl 8) + write_fail ; load message ;AC000;
2130 ; - Write failure, diskette unuseable
2131 ; in case an error occured
2132 ret
2133
2134 ENDPROC Read_Directory
2135
2136 BREAK <SYS - Verify_File_Location >
2137;******************* START OF SPECIFICATIONS ***********************************
2138;Routine name: Verify_File_Location
2139;*******************************************************************************
2140;
2141;Last Update: 09/22/87
2142;
2143;Description: Determines if IBMBIO and IBMDOS are the first two directory
2144; entries, or if these entries are empty. If so, find the size
2145; of the files if they exist. If spaces not empty and don't
2146; contain IBMBIO and IBMDOS, set fail flag and load return code.
2147; Also determines if existing IBMBIO starts in cluster 2. If not
2148; set fail flag and load return code.
2149;
2150;CALLed Procedures: None
2151;
2152;Input: DIR in BUFFER
2153;
2154;Output: no error - CF = 0
2155; error - CF = 1
2156; AX = return code
2157; AH = utility essages
2158; AL = 8 - No room for system on destination disk
2159; 9 - Incompatible system size
2160;
2161;Change History: Created 5/01/87 FG
2162;
2163;******************* END OF SPECIFICATIONS *************************************
2164;******************+ START OF PSEUDOCODE +**************************************
2165;
2166; START Verify_File_Location
2167;
2168; if all files deleted (Dir_Name in dir is 00h)
2169; reset fail flag
2170; else
2171; if first file deleted (Dir_Name is 0E5h)
2172; reset fail flag
2173; else
2174; if first file IBMBIO.COM
2175; get IBMBIO Size
2176; indicate we found IBMBIO
2177; clear error flag
2178; else
2179; call Move_DIR_Entry
2180; call Free_Cluster
2181; endif
2182; endif
2183; if no error so far and
2184; if IBMBIO found
2185; call Free_Cluster
2186; endif
2187; if no error so far
2188; if all files deleted starting at second location or
2189; if second file deleted (Dir_Name is 0E5h)
2190; reset fail flag
2191; else
2192; if second file IBMDOS.COM
2193; get IBMDOS size
2194; indicate we found IBMDOS
2195; reset fail flag
2196; else
2197; call Move_DIR_Entry
2198; endif
2199; endif
2200; endif
2201; endif
2202;
2203; ret
2204;
2205; END Verify_File_Location
2206;******************- END OF PSEUDOCODE -**************************************
2207
2208 public Verify_File_Location
2209
2210 Verify_File_Location PROC NEAR
2211 ;---------------------------------------
2212 ; Now see if the first two directory
2213 ; entries are available...
2214 ; First check for being free:
2215 ;---------------------------------------
2216 mov bp,OFFSET DIR_SECTOR
2217 mov si,bp
2218 cmp BYTE PTR [si],empty ; empty dir?
2219
2220; $if e,or ; if all files deleted ;AC012;
2221 JE $$LL118
2222 ; (Dir_Name in dir is 00h)
2223
2224 cmp BYTE PTR [si],deleted ; is first file deleted ?
2225
2226; $if e ; if it is ;AC012;
2227 JNE $$IF118
2228$$LL118:
2229 ; (Dir_Name is 0E5h)................:
2230 clc ; clear error flag ;AN003;
2231 call Free_Cluster ; check the cluster chain just in case ;AC012;
2232
2233; $else long ; not empty ;AC000;
2234 JMP $$EN118
2235$$IF118:
2236 ;---------------------------------------
2237 ; The first entry is not free. See if
2238 ; the BIOS is there.
2239 ;---------------------------------------
2240 mov di,OFFSET FCBBIO ; pointer to name
2241 mov cx,file_spec_length ; length of name
2242 cld ; go forward
2243 rep cmpsb ; check it
2244
2245; $if e ; first file IBMBIO.COM ;AC000;
2246 JNE $$IF120
2247
2248 dec BIOSEntFree ; indicate we found IBMBIO ( = 0)
2249 mov si,bp
2250 mov ax,word ptr ds:[si].dir_size_l ; Get the size of IBMBIO ;AC000;
2251 mov word ptr IBMBIO_Low,ax
2252 mov ax,word ptr ds:[si].dir_size_h ; ;AC000;
2253 mov word ptr IBMBIO_High,ax
2254 cmp ds:[si].dir_first,2 ; does IBMBIO own Clust 2? ;AC005;
2255; $if e ; if so ;AC005;
2256 JNE $$IF121
2257 inc [bio_owns_it] ; - keep track ;AC005;
2258; $endif ; ;AC005;
2259$$IF121:
2260
2261 call Free_Cluster ; ;AN003;
2262
2263; $else ; its not IBMBIO ;AC000;
2264 JMP SHORT $$EN120
2265$$IF120:
2266
2267 mov si,bp ; restore pointer to start of entry ;AN003;
2268 call Move_DIR_Entry ; move the entry out of the way ;AN003;
2269
2270; $if nc,and ; ;AN003;
2271 JC $$IF124
2272
2273 call Free_Cluster ; make sure reqd. clusters are free ;AN003;
2274
2275; $if nc ; ;AC000;
2276 JC $$IF124
2277
2278 xor ax,ax ;
2279
2280; $else ; ;AC000;
2281 JMP SHORT $$EN124
2282$$IF124:
2283
2284 mov ax,(util_B shl 8) + no_room ; load return code in case we fail;AN000;
2285 stc ; - No room for system on dest... ;AC000;
2286
2287; $endif ; ;AC000;
2288$$EN124:
2289
2290; $endif ; ;AC000;
2291$$EN120:
2292
2293; $endif ; ;AC000;
2294$$EN118:
2295
2296 ;---------------------------------------
2297 ; Check the second entry
2298 ;---------------------------------------
2299
2300; $if nc ; if no errors so far ;AC000;
2301 JC $$IF129
2302
2303 ; ensure that the first sector of root ;AN003;
2304 ; is loaded ;AN003;
2305 mov ax,[first_dir_sector] ; get starting dir sector ;AN001;
2306 mov packet,ax ; ;AN001;
2307 mov [packet_buffer],offset DIR_SECTOR ; ;AN001;
2308 mov word ptr [packet_sectors],1 ; ;AN001;
2309 xor ax,ax ; request a read
2310 call Direct_Access ; to read the root
2311
2312; $if nc ; ;AC000;
2313 JC $$IF130
2314
2315 add bp,TYPE dir_entry ; ;AC000;
2316 mov si,bp ; ;AC000;
2317 mov ax,(util_B shl 8) + no_room ; load return code in case we fail ;AC000;
2318 ; - No room for system on dest..
2319 cmp BYTE PTR [si],empty ; empty dir entry?
2320
2321; $if e,or ; if deleted starting at 2nd entry or. ;AC000;
2322 JE $$LL131
2323
2324 cmp BYTE PTR [si],deleted ; deleted ? :
2325
2326; $if e ; if deleted (0E5h)...................:;AC000;
2327 JNE $$IF131
2328$$LL131:
2329
2330 clc ; reset fail flag
2331
2332; $else ; ;AC000;
2333 JMP SHORT $$EN131
2334$$IF131:
2335
2336 ; This entry is not free.
2337 mov di,OFFSET FCBDOS ; see if it is IBMDOS
2338 mov cx,file_spec_length ; length of name
2339 rep cmpsb ; compare it
2340 mov si,bp ; restore pointer to start ;AC000;
2341
2342; $if e ; if second file is IBMDOS.COM. ;AC000;
2343 JNE $$IF133
2344
2345 dec DOSEntFree ; indicate we found IBMDOS
2346 mov ax,word ptr ds:[si].dir_size_l ; Get the size of ;AC000;
2347 mov word ptr IBMDOS_Low,ax ; file for IBMDOS
2348 mov ax,word ptr ds:[si].dir_size_h ; ;AC000;
2349 mov word ptr IBMDOS_High,ax
2350 clc ; reset fail flag ;AN000;
2351
2352; $else ; error condition ;AC000;
2353 JMP SHORT $$EN133
2354$$IF133:
2355
2356 call Move_DIR_Entry ; ;AN003;
2357
2358; $endif ; ;AC000;
2359$$EN133:
2360
2361; $endif ; ;AC000;
2362$$EN131:
2363
2364; $else ; ;AC000;
2365 JMP SHORT $$EN130
2366$$IF130:
2367 mov ax,(util_B shl 8) + no_room ; load return code in case we fail ;AN000;
2368; $endif ; ;AC000;
2369$$EN130:
2370
2371; $endif ; ;AC000;
2372$$IF129:
2373
2374 ret ; ;AN000;
2375
2376 ENDPROC Verify_File_Location
2377
2378 BREAK <SYS - Determine_Free_Space >
2379;******************* START OF SPECIFICATIONS ***********************************
2380;Routine name: Determine_Free_Space
2381;*******************************************************************************
2382;
2383;Last Update: 3/18/87
2384;
2385;Description: Determine if there is enough space on the disk, given the free
2386; space and the space taken up by IBMBIO and IBMDOS to install the
2387; new IBMBIO and IBMDOS. Routine will set fail flag and load return
2388; code if there is not enough room.
2389;
2390; Here we make some VERY IMPORTANT assumptions.
2391;
2392; 1) If IBMBIO exists on the disk currently, we assume it is in the
2393; correct place, i.e. at the front of the data area & contiguous.
2394; 2) The stub loader portion of IBMBIO is less than 2048 bytes long.
2395; This number comes about by assuming we will never overlay
2396; anything smaller than 1920 bytes (DOS 1.10 IBMBIO size). This
2397; can be expanded to 2048 if we also assume the smallest possible
2398; cluster length is 512 bytes.
2399;
2400; Therefore, if we have an empty disk or IBMBIO exists, then we have
2401; enough contiguous room to install the portion of IBMBIO that
2402; requires itself to be contiguous.
2403;
2404;CALLed Procedures: None
2405;
2406;Input: None
2407;
2408;Output: no error - CF = 0
2409; error - CF = 1
2410; AX = return code
2411; AH = utility messages
2412; AL = 8d - No room for system on destination disk
2413;
2414;Change History: Created 5/01/87 FG
2415;
2416;******************* END OF SPECIFICATIONS *************************************
2417;******************+ START OF PSEUDOCODE +**************************************
2418;
2419; START Determine_Free_Space
2420;
2421; get disk free space (INT21 Get_Drive_Freespace + 00 <3600>)
2422; compute Bytes/Cluster (32bit math required)
2423; convert current IBMBIO into cluster size (CALL Get_Cluster)
2424; convert current IBMDOS into cluster size (CALL Get_Cluster)
2425; get total number of clusters available
2426; convert new IBMBIO into cluster size (CALL Get_Cluster)
2427; convert new IBMDOS into cluster size (CALL Get_Cluster)
2428; get total number of clusters needed
2429; if available clusters < needed clusters
2430; load return code (No room for system on destination disk)
2431; set fail flag
2432; else
2433; reset fail flag
2434; endif
2435; ret
2436;
2437; END Determine_Free_Space
2438;
2439;******************- END OF PSEUDOCODE -**************************************
2440
2441 public Determine_Free_Space
2442
2443 Determine_Free_Space PROC NEAR
2444
2445 mov ah,Get_Drive_Freespace ; get disk free space
2446 mov dl,TargDrvNum ; get the drive number
2447 INT 21h ; Get_Drive_Freespace <36xx>
2448 ; compute Bytes/Cluster - 16 bit math ok
2449 ; AX = sectors / cluster
2450 ; CX = bytes / sector
2451 ; BX = available clusters
2452 mul cx ; get bytes/cluster
2453 ; result left in AX
2454 mov Bytes_Per_Cluster,ax ; save this value for Get_Clusters
2455 mov Number_Free_Clusters,bx ; save available space
2456
2457 mov ax,IBMBIO_Low ; low result in AX, High result in DX
2458 mov dx,IBMBIO_High
2459 call Get_Cluster ; convert old IBMBIO into cluster size
2460
2461 add Number_Free_Clusters,ax ; add it to available space
2462
2463 mov ax,IBMDOS_Low ; low result in AX, High result in DX
2464 mov dx,IBMDOS_High
2465 call Get_Cluster ; convert old IBMDOS into cluster size
2466
2467 add Number_Free_Clusters,AX ; get total number of clusters available
2468
2469 mov ax,NEWBIO_Size_Low ; find total size of new DOS and BIOS
2470 mov dx,NEWBIO_Size_High
2471
2472 call Get_Cluster ; convert new IBMBIO into cluster size
2473
2474 mov Need_Clusters,ax ;save new BIO clusters
2475
2476 mov ax,NEWDOS_Size_Low
2477 mov dx,NEWDOS_Size_High
2478
2479 call Get_Cluster ; convert new IBMDOS into cluster size
2480
2481 add AX,Need_Clusters ; get total number of clusters needed
2482
2483 cmp AX,Number_Free_Clusters ;Now see if there is enough room
2484 ; for all of it on the disk
2485; $if a ; if needed > available clusters ;AC000;
2486 JNA $$IF140
2487
2488 mov ax,(util_B shl 8) + no_room ; load return code ;AC000;
2489 ; - No room for system on dest..
2490 stc ; set fail flag
2491
2492; $else ; ;AC000;
2493 JMP SHORT $$EN140
2494$$IF140:
2495
2496 clc ; reset fail flag
2497
2498; $endif ; ;AC000;
2499$$EN140:
2500
2501 ret ; ;AN000;
2502
2503 ENDPROC Determine_Free_Space
2504
2505 BREAK <SYS - Get_Cluster >
2506;******************* START OF SPECIFICATIONS ***********************************
2507;Routine name: Get_Cluster
2508;*******************************************************************************
2509;
2510;Description: Convert bytes to clusters, rounding up to the next
2511; cluster size if needed.
2512;
2513;Called Procedures: None
2514;
2515;Input: (AX) = Number of bytes
2516; Bytes_Per_Cluster = # of bytes per cluster
2517;
2518;Output: (AX) = Number of clusters
2519;
2520;Registers used: AX BX DX
2521;
2522;Change History: Created 5/01/87 FG
2523;
2524;******************* END OF SPECIFICATIONS *************************************
2525;******************+ START OF PSEUDOCODE +**************************************
2526;
2527; START Get_Cluster
2528;
2529; divide size by bytes_per_cluster
2530; if there is a remainder
2531; round up to next cluster
2532; endif
2533; ret
2534;
2535; END Get_Cluster
2536;
2537;******************- END OF PSEUDOCODE -**************************************
2538
2539 public Get_Cluster
2540
2541 Get_Cluster PROC NEAR
2542
2543 mov bx,Bytes_Per_Cluster ; Bytes/cluster
2544 div bx ; divide size by bytes_per_cluster
2545 cmp dx,0 ; is there a remainder in DX?
2546
2547; $if ne ; if there is a remainder ;AC000;
2548 JE $$IF143
2549 ; we have another cluster to round up
2550 inc ax ; round up to next cluster
2551
2552; $endif ; ;AC000;
2553$$IF143:
2554
2555 ret
2556
2557 ENDPROC Get_Cluster
2558
2559 BREAK <SYS - Do_SYS >
2560;******************* START OF SPECIFICATIONS ***********************************
2561;Routine name: Do_SYS
2562;*******************************************************************************
2563;
2564;Description: Control routine to handle the transfer of system files from
2565; memory to target drive.
2566;
2567;Called Procedures: Create_System
2568; Fill_Memory
2569; Dump_Memory
2570;
2571;Input: IBMBIO_Size_Loaded
2572; IBMDOS_Size_Loaded
2573;
2574;Output: no error - CF = 0
2575; error - CF = 1 AX = return code (message #)
2576;
2577;Change History: Created 5/01/87 FG
2578;
2579;******************* END OF SPECIFICATIONS *************************************
2580;******************+ START OF PSEUDOCODE +**************************************
2581;
2582; START Do_SYS
2583;
2584; create new IBMBIO and IBMDOS, in place if exist (CALL CREATE_SYSTEM)
2585; if no error
2586; search
2587; write out contents of memory to file (CALL Dump_Memory)
2588; load error return code (assume error)
2589; leave if error
2590; exit if if all files copied
2591; reset fail flag
2592; orelse
2593; read in file from source (CALL Fill_Memory)
2594; load error return code (assume error)
2595; leave if error
2596; endloop
2597; set fail flag
2598; endsearch
2599; endif
2600; ret
2601;
2602; END Do_SYS
2603;
2604;******************- END OF PSEUDOCODE -**************************************
2605
2606 public Do_SYS
2607
2608 Do_SYS PROC NEAR
2609
2610 call CREATE_SYSTEM ; create IBMBIO and IBMDOS, in place ;AN000;
2611
2612; $if nc ; no error ;AC000;
2613 JC $$IF145
2614
2615 push ds
2616 lds bx,THIS_DPB ; set up pointer to DPB ;AC000;
2617 mov [bx.dpb_next_free],2 ; reset Allocation to start of disk ;AC000;
2618 pop ds ; so BIOS goes in right place!
2619
2620; $search ; ;AC000;
2621$$DO146:
2622
2623 call Dump_Memory ; write out contents of memory to file
2624
2625 mov ax,(util_B shl 8) + no_room ; load error RC (assume error) ;AC000;
2626
2627; $leave c ; quit if error ;AC000;
2628 JC $$EN146
2629
2630 mov ax,DOSLenHigh ; more DOS to move ?
2631 or AX,DOSLenLow ; more low dos
2632 or AX,BIOSLenHigh ; more high BIOS
2633 or AX,BIOSLenLow ; more low BIOS
2634
2635; $exitif z ; if all files copied ;AC000;
2636 JNZ $$IF146
2637
2638 clc ; reset fail flag ;AC000;
2639
2640; $orelse ; ;AC000;
2641 JMP SHORT $$SR146
2642$$IF146:
2643
2644 call get_rest_of_system
2645
2646 mov ax,(util_B shl 8) + no_room ; load error RC (assume error) ;AC000;
2647
2648; $leave c ; if error ;AC000;
2649 JC $$EN146
2650
2651; $endloop ; ;AC000;
2652 JMP SHORT $$DO146
2653$$EN146:
2654
2655; $endsrch ; ;AC000;
2656$$SR146:
2657
2658; $endif ; ;AC000;
2659$$IF145:
2660
2661 ret ; ;AN000;
2662
2663 ENDPROC Do_SYS
2664
2665 PUBLIC Get_Rest_of_System
2666
2667 Get_Rest_of_System Proc near
2668
2669 pushf ; ;AN001;
2670
2671 mov bx,BIOSOutFH ; ;AN001;
2672 mov ah,Close ; ;AN001;
2673 int 21h ; ;AN001;
2674
2675 mov bx,DOSOutFH ; ;AN001;
2676 mov ah,Close ; ;AN001;
2677 int 21h ; ;AN001;
2678
2679 mov dx,offset SourceBIOSName ; ;AN001;
2680 mov ax,(OPEN SHL 8) + not_used ; open file for read
2681 int 21h ; ;AN001;
2682 mov biosinfh,ax
2683
2684 mov dx,offset SourceDOSName ; ;AN001;
2685 mov ax,(OPEN SHL 8) + not_used ; open file for read
2686 int 21h ; ;AN001;
2687 mov dosinfh,ax
2688
2689 call Fill_Memory ; read in file from source
2690
2691 mov bx,BIOSInFH ; ;AN001;
2692 mov ah,Close ; ;AN001;
2693 int 21h ; ;AN001;
2694
2695 mov bx,DOSInFH ; ;AN001;
2696 mov ah,Close ; ;AN001;
2697 int 21h ; ;AN001;
2698
2699 mov dx,offset BIOSName ; ;AN001;
2700 mov ax,(Open shl 8) + 2 ; Open file
2701 INT 21h
2702 mov BIOSOutFH,ax
2703
2704 mov dx,offset DOSName ; ;AN001;
2705 mov ax,(Open shl 8) + 2 ; Open file
2706 INT 21h
2707 mov DOSOutfh,ax
2708
2709 popf ; ;AN001;
2710
2711 RET
2712
2713 endproc get_rest_of_system
2714
2715 BREAK <SYS - Create_System >
2716;******************* START OF SPECIFICATIONS ***********************************
2717;Routine name: Create_System
2718;*******************************************************************************
2719;
2720;Description:
2721;
2722;Called Procedures: Create_File
2723;
2724;Input: None
2725;
2726;Output: IBMBIO_Handle
2727; IBMDOS_Handle
2728;
2729;Change History: Created 5/01/87 FG
2730;
2731;******************* END OF SPECIFICATIONS *************************************
2732;******************+ START OF PSEUDOCODE +**************************************
2733;
2734; START Create_System
2735;
2736; create IBMBIO (CALL Create_File)
2737; if no error and
2738; save handle to IBMBIO_Handle
2739; create IBMDOS (CALL Create_File)
2740; if no error
2741; save handle to IBMDOS_Handle
2742; reset fail flag
2743; endif
2744; ret
2745;
2746; END Create_System
2747;
2748;******************- END OF PSEUDOCODE -**************************************
2749
2750 public Create_System
2751
2752 Create_System PROC NEAR
2753
2754 mov [open_seg],ds
2755 mov dx,OFFSET BIOSName ; point to IBMBIO ASCIIZ string
2756 mov al,[BIOSEntFree] ; get status of IBMBIO ;AN006;
2757 mov [EntryFree],al ; update file status (0 = found,1 = not;AN006;
2758
2759 call Create_File ; create IBMBIO ;AN000;
2760
2761; $if nc,and ; no error and ;AC000;
2762 JC $$IF154
2763
2764 mov BIOSOutFH,ax ; save handle to IBMBIO_Handle
2765 mov dx,OFFSET DOSName ; pointer to IBMDOS ASCIIZ string
2766 mov al,[DOSEntFree] ; get status of IBMDOS ;AN006;
2767 mov [EntryFree],al ; update file status (0 = found,1 = not;AN006;
2768
2769 call Create_File ; create IBMDOS ;AN000;
2770
2771; $if nc ; no error ;AC000;
2772 JC $$IF154
2773
2774 mov DOSOutFH,ax ; save handle to IBMDOS_Handle
2775
2776; $endif ; ;AC000;
2777$$IF154:
2778
2779 ret ; ;AN000;
2780
2781 ENDPROC Create_System
2782
2783 BREAK <SYS - Create_File >
2784;******************* START OF SPECIFICATIONS ***********************************
2785;Routine name: Create_File
2786;*******************************************************************************
2787;
2788;Last Update: 9/23/87
2789;
2790;Description: Remove the read only attribute from IBMBIO and IBMDOS. If
2791; file not found error occurs, it is okay, because it just
2792; means the file was not there. Do create with read-only
2793; hidden, and system file attributes. This is an in place
2794; create if the file exists already.
2795;
2796;
2797;Called Procedures: None
2798;
2799;Input: DS:DX = pointer to ASCIIZ string for file create
2800;
2801;Output: no error - CF = 0
2802; AX = file handle
2803; error - CF = 1
2804; AX = return code
2805; AH = extended DOS errors
2806;
2807;Change History: Created 5/01/87 FG
2808;
2809;******************* END OF SPECIFICATIONS *************************************
2810;******************+ START OF PSEUDOCODE +**************************************
2811;
2812; START Create_File
2813;
2814; set file attributes to 0 (INT21 CHMod + SetAtrib <4301>)
2815; if no error or
2816; if error = file not found and
2817; ext Open file with attributes of 7 (INT21 ExtOpen + SetAtrib <6C12> CX=7)
2818; if no error
2819; reset fail flag
2820; else
2821; load return code (DOS Extended Error)
2822; set fail flag
2823; endif
2824; ret
2825;
2826; END Create_File
2827;
2828;******************- END OF PSEUDOCODE -**************************************
2829
2830 public Create_File
2831
2832 Create_File PROC NEAR
2833
2834 mov ax,(CHMod shl 8) + SetAtrib ; set file attributes to 0
2835 xor cx,cx ; set attributes to 0
2836 mov [open_off],dx ; save pointer to ASCIIZ for OPEN
2837 INT 21h ; CHMod + SetAtrib <4301>)
2838
2839; $if nc ; no error ;AC000;
2840 JC $$IF156
2841
2842 cmp [EntryFree],0 ; is file in the correct spot? ;AN006;
2843; $if ne ; if it is not - we have a problem ;AN006;
2844 JE $$IF157
2845 mov dx,[open_off] ; get pointer to ASCIIZ for UNLINK ;AN006;
2846 mov ax,(UNLINK shl 8) ; UNLINK the file
2847 INT 21h ; UNLINK <4100>) ;AN006;
2848; $endif ; ;AN006;
2849$$IF157:
2850; $else ; - check the error ;AN006;
2851 JMP SHORT $$EN156
2852$$IF156:
2853 call Get_DOS_Error ; find out what went wrong ;AN000;
2854 cmp al,file_not_found ; not there?
2855
2856; $if e ; IBMBIO was not there ;AC000;
2857 JNE $$IF160
2858 clc ; ok to open ;AC000;
2859; $else ; ;AC000;
2860 JMP SHORT $$EN160
2861$$IF160:
2862 stc ; some other error - quit ;AC000;
2863; $endif ; ;AC000;
2864$$EN160:
2865; $endif ; ;AC000;
2866$$EN156:
2867; $if nc ; if no error ;AC006;
2868 JC $$IF164
2869
2870 lds si,OPEN_PARMS ; ;AC005;
2871 xor cx,cx ; DOS system file atributes ;AC005;
2872 cmp DOS_VER,0 ; running on current DOS ? ;AN019;
2873
2874; $if ne ; if on old DOS ;AN019;
2875 JE $$IF165
2876 mov dx,si ; DS:DX - file name ;AN019;
2877 mov ax,(Creat shl 8) + 0 ; Create file <3D00> ;AN019;
2878; $else ; ;AN019;
2879 JMP SHORT $$EN165
2880$$IF165:
2881 mov di,cx ; ;AC005;
2882 dec di ; ;AC005;
2883 mov bx,open_mode ; set up for mode ;AN000;
2884 mov dx,(openit shl 4) + replaceit ; create if does not exist, ;AN000;
2885 ; replace it if it does
2886 mov ax,(ExtOpen shl 8) + 0 ; ext Open file with attributes of 0 ;AN000;
2887 ; ExtOpen + SetAtrib <6C12> CX=0
2888; $endif ; ;AN019;
2889$$EN165:
2890
2891 INT 21h ; do the open
2892
2893; $endif ; ;AC000;
2894$$IF164:
2895
2896; $if c ; if error ;AN000;
2897 JNC $$IF169
2898
2899 call Get_DOS_Error ; find out what went wrong ;AN000;
2900 mov ah,DOS_error ; load return code (DOS Extended Error);AN000;
2901 stc ; ;AN006;
2902
2903; $endif ; ;AN000;
2904$$IF169:
2905
2906 ret ; ;AC000;
2907
2908 ENDPROC Create_File
2909
2910 BREAK <SYS - Dump_Memory >
2911;******************* START OF SPECIFICATIONS ***********************************
2912;Routine name: Dump_Memory
2913;*******************************************************************************
2914;
2915;Description: Write out as much of IBMBIOS and IBMDOS as is in memory.
2916;
2917;Called Procedures: None
2918;
2919;Input: None
2920;
2921;Output: no error - CF = 0
2922; error - CF = 1
2923;
2924;Change History: Created 5/01/87 FG
2925;
2926;******************* END OF SPECIFICATIONS *************************************
2927;******************+ START OF PSEUDOCODE +**************************************
2928;
2929; START Dump_Memory
2930;
2931; get pointer to start of buffer
2932; subtract the start of IBMDOS
2933; if lenght is non-zero and . . . . . . . . . . . . . . . .
2934; load IBMBIOS handle :
2935; write out IBMBIOS (INT21 Write + 00 <4000>) :
2936; if no error and . . . . . . . . . . . . . . . . . . . . :
2937; if not all data written . . . . . . . . . . . . . . . . :
2938; set fail flag
2939; endif
2940; if no error so far
2941; get beginning of dos
2942; subtract end of dos
2943; if lenght is non-zero and
2944; load IBMDOS handle
2945; write out IBMDOS (INT21 Write + 00 <4000>)
2946; if no error and
2947; if not all data written . . . . . . . . . . . . . . . . :
2948; set fail flag
2949; endif
2950; endif
2951; ret
2952;
2953; END Dump_Memory
2954;
2955;******************- END OF PSEUDOCODE -**************************************
2956
2957 public Dump_Memory
2958
2959 Dump_Memory PROC NEAR
2960
2961 mov ax,4202h ; LSEEK to end of file ;AN001;
2962 mov bx,BIOSOutFH ; ;AN001;
2963 xor cx,cx ; ;AN001;
2964 xor dx,dx ; ;AN001;
2965 int 21h ; ;AN001;
2966 mov ax,4202h ; LSEEK to end of file ;AN001;
2967 mov bx,DOSOutFH ; ;AN001;
2968 xor cx,cx ; ;AN001;
2969 xor dx,dx ; ;AN001;
2970 int 21h ; ;AN001;
2971
2972 mov dx,OFFSET BUF+FAT_BUF ; get pointer to start of buffer
2973 mov cx,pDOS ; beginning of next guy
2974 sub cx,dx ; difference is length
2975
2976; $if nz,and ; if lenght is non-zero and....... ;AC000;
2977 JZ $$IF171
2978
2979 mov bx,BIOSOutFH ; load IBMBIOS handle :
2980 mov ah,Write ; write out IBMBIOS :
2981 INT 21h ; Write + 00 <4000> :
2982
2983; $if nc,and ; if no error and.................: ;AC000;
2984 JC $$IF171
2985
2986 cmp ax,cx ; Did it work? :
2987
2988; $if ne ; all data written................: ;AC000;
2989 JE $$IF171
2990
2991 stc ; set fail flag
2992
2993; $endif ; ;AC000;
2994$$IF171:
2995
2996; $if nc ; if no error so far ;AC000;
2997 JC $$IF173
2998
2999 mov dx,pDOS ; get beginning of dos
3000 mov cx,pDOSEnd ; subtract end of dos
3001 sub cx,dx ; difference is length
3002
3003; $if nz,and ; if lenght is non-zero and........ ;AC000;
3004 JZ $$IF174
3005
3006 mov bx,DOSOutFH ; load IBMDOS handle :
3007 mov ah,Write ; write out IBMDOS :
3008 INT 21h ; Write + 00 <4000> :
3009
3010; $if nc,and ; if no error.....................: ;AC000;
3011 JC $$IF174
3012
3013 cmp ax,cx ; Did it work? :
3014
3015; $if ne ; all data written................: ;AC000;
3016 JE $$IF174
3017
3018 stc ; set fail flag
3019
3020; $endif ; ;AC000;
3021$$IF174:
3022
3023; $endif ; ;AC000;
3024$$IF173:
3025
3026 ret
3027
3028 ENDPROC Dump_Memory
3029
3030
3031 BREAK <SYS - Do_End >
3032;******************* START OF SPECIFICATIONS ***********************************
3033;Routine name: Do_End
3034;*******************************************************************************
3035;
3036;Description: Finish off with IBMBIOS and IBMDOS
3037;
3038;Called Procedures: Close_File
3039; Write_Boot_Record
3040;
3041;Input: None
3042;
3043;Output: no error - CF = 0
3044;
3045;Change History: Created 5/01/87 FG
3046;
3047;******************* END OF SPECIFICATIONS *************************************
3048;******************+ START OF PSEUDOCODE +**************************************
3049;
3050; START Do_End
3051;
3052; finish off and close IBMBIOS and IBMDOS (CALL Close_Files)
3053; update boot record (CALL Write_Boot_Record)
3054; ret
3055;
3056; END Do_End
3057;
3058;******************- END OF PSEUDOCODE -**************************************
3059
3060 public Do_End
3061
3062 Do_End PROC NEAR
3063
3064 call Close_File ; finish off & close IBMBIOS and IBMDOS;AN000;
3065
3066 call Write_Boot_Record ; update boot record ;AN000;
3067
3068 ret ; ;AN000;
3069
3070 ENDPROC Do_End
3071
3072 BREAK <SYS - Close_File >
3073;******************* START OF SPECIFICATIONS ***********************************
3074;Routine name: Close_File
3075;*******************************************************************************
3076;
3077;Description: Set date and time on IBMBIOS and IBMDOS and close
3078; them.
3079;
3080;Called Procedures: None
3081;
3082;Input: BIOSTime, BIOSOutFH, DOSTime. DOSOutFH
3083;
3084;Output: IBMBIOS and IBMDOS closed
3085;
3086;Change History: Created 5/01/87 FG
3087;
3088;******************* END OF SPECIFICATIONS *************************************
3089;******************+ START OF PSEUDOCODE +**************************************
3090;
3091; START Close_File
3092;
3093; load IBMBIOS time and date
3094; load IBMBIOS handle
3095; update file times (INT21 File_Times + 01 <5701>)
3096; close file (INT21 Close + 00 <3E00>)
3097; load IBMDOS time and date
3098; load IBMDOS handle
3099; update file times (INT21 File_Times + 01 <5701>)
3100; close file (INT21 Close + 00 <3E00>)
3101; ret
3102;
3103; END Close_File
3104;
3105;******************- END OF PSEUDOCODE -**************************************
3106
3107 public Close_File
3108
3109 Close_File PROC NEAR
3110
3111 mov cx,BIOSTime ; load IBMBIOS time and date
3112 mov dx,BIOSTime+2
3113 mov bx,BIOSOutFH ; load IBMBIOS handle
3114 mov ax,(File_Times SHL 8) + set ; update file times
3115 INT 21h ; File_Times + 01 <5701>
3116 mov ah,Close ; close file IBMBIO
3117 INT 21h ; Close + not_used <3Exx>
3118 mov cx,DOSTime ; load IBMDOS time and date
3119 mov dx,DOSTime+2
3120 mov bx,DOSOutFH ; load IBMDOS handle
3121 mov ax,(File_Times SHL 8) + set ; update file times
3122 INT 21h ; File_Times + 01 <5701>
3123 mov ah,Close ; close file IBMDOS
3124 INT 21h ; Close + not_used <3Exx>
3125
3126 mov dx,offset BIOSName ; ;AN001;
3127 mov ax,(CHMod shl 8) + SetAtrib ; set file attributes to 0
3128 mov cx,DOS_system_atrib ; DOS system file atributes
3129 INT 21h ; CHMod + SetAtrib <4301>)
3130
3131 mov dx,offset DOSName ; ;AN001;
3132 mov ax,(CHMod shl 8) + SetAtrib ; set file attributes to 0
3133 mov cx,DOS_system_atrib ; DOS system file atributes
3134 INT 21h ; CHMod + SetAtrib <4301>)
3135
3136 ret ; ;AN000;
3137
3138 ENDPROC Close_File
3139
3140 BREAK <SYS - Write_Boot_Record >
3141;******************* START OF SPECIFICATIONS ***********************************
3142;Routine name: Write_Boot_Record
3143;*******************************************************************************
3144;
3145;Description: Get a best guess EBPB and get the Media ID or fill the
3146; information in manually. Write out the canned boot record
3147; and then make IOCtl calls to set the EBPB and Media ID.
3148;
3149;Called Procedures: Create_Serial_ID
3150;
3151;Input: None
3152;
3153;Output: Boot record on destination media is installed.
3154;
3155;Change History: Created 5/01/87 FG
3156;
3157;******************* END OF SPECIFICATIONS *************************************
3158;******************+ START OF PSEUDOCODE +**************************************
3159;
3160; START Write_Boot_Record
3161;
3162; get BPB using IOCtl Get Device Parameters (INT21 IOCtl + 0Dh <440d> CX=0860)
3163; get volid, ser# and file type using IOCtl Get Media ID (INT21 IOCtl + 0Dh <440d> CX=086E)
3164; if error and
3165; get Extended error
3166; if 'unknown media' - set fields manually
3167; compute serial id and put in field (CALL Create_Serial_ID)
3168; copy in volume label if available
3169; set pointer to FAT1x (CALL FAT_Size)
3170; move file system string into Boot_System_ID field
3171; else
3172; set fail flag
3173; load return code (DOS error)
3174; endif
3175; if no fail flag
3176; if fixed media
3177; fill in Ext_PhyDrv in canned boot record
3178; endif
3179; set BPB using data from GET BPB IOCTL
3180; write out canned boot record (INT26)
3181; set volid, ser# and file type using Set Media ID (INT21 SetID <6900> CX=084E)
3182; endif
3183; ret
3184;
3185; END Write_Boot_Record
3186;
3187;******************- END OF PSEUDOCODE -**************************************
3188
3189 public Write_Boot_Record
3190
3191 Write_Boot_Record PROC NEAR
3192
3193 mov bl,TargDrvNum ; Drive number ;AN000;
3194 mov dx,offset DeviceParameters ; ;AN000;
3195 mov cx,(rawio shl 8) + get_device_parameters ; Generic IOCtl Request ;AN000;
3196 ; CX=0860
3197 mov ax,(IOCtl shl 8) + generic_ioctl ; get BPB using Set Device Parm ;AN000;
3198 INT 21h ; IOCtl + gen_IOCtl_request <440d> ;AN000;
3199
3200 cmp DOS_VER,0ffh ; is it DOS 3.3? ;AN019;
3201; $if ne ; only do a GET if DOS 4.00 ;AN019;
3202 JE $$IF177
3203 lea dx,IOCtl_Buf ; point to output buffer ;AN000;
3204 mov ax,(GetSetMediaID shl 8) + 0 ; get volid, ser# and file type ;AC008;
3205 INT 21h ; GetSetMediaID + 0 INT 21 <6900> ;AC008;
3206
3207; $if c ; error - see if its 'unknown media' ;AN000;
3208 JNC $$IF178
3209
3210 call Get_DOS_Error ; get error ;AN000;
3211 cmp al,old_type_media ; ;AN000;
3212
3213; $if e ; ;AN019;
3214 JNE $$IF179
3215 stc ; do it all manually ;AN019;
3216; $else ; ;AN019;
3217 JMP SHORT $$EN179
3218$$IF179:
3219 clc ; some other dos error occured - le ;AN019;
3220; $endif ; it go by ;AN019;
3221$$EN179:
3222
3223; $endif ; ;AN019;
3224$$IF178:
3225; $else ; ;AN019;
3226 JMP SHORT $$EN177
3227$$IF177:
3228 stc ; do it all manually ;AN019;
3229; $endif ; ;AN019;
3230$$EN177:
3231
3232; $if c ; if it is pre 4.00 IBM format ;AN000;
3233 JNC $$IF185
3234
3235 call Create_Serial_ID ; compute serial id and put in field ;AN000;
3236
3237 ; find first with type = VOLUME ID
3238
3239 mov dx,OFFSET ExtFCB ; set up for FCB call ;AN019;
3240 mov ah,Dir_Search_First ; do a find first INT21 ;AN019;
3241
3242 INT 21h ; Find_First <11xx> ;AN000;
3243
3244 cmp al,0 ; was a match found? al = 0 yes ;AN019;
3245 ; al = ff no
3246; $if e ; if so - copy it in ;AN000;
3247 JNE $$IF186
3248
3249 lea si,DOS_BUFFER + 8 ; source id is in DTA ;AN019;
3250 lea di,IOCtl_Vol_ID ; destination is in IOCtl_Buf ;AN000;
3251 mov cx,file_spec_length ; move 11 bytes worth ;AN000;
3252 cld ; copy it in ;AN000;
3253 rep movsb ; ;AN000;
3254
3255; $else
3256 JMP SHORT $$EN186
3257$$IF186:
3258
3259 clc ; leave it as default - NO NAME
3260
3261; $endif ; endif ;AN000;
3262$$EN186:
3263
3264 ; NOTE:
3265 ; since the GET MEDIA ID failed - its
3266 ; pre 32 bit fat - so no 32 bit math
3267 ; is required.
3268 call FAT_Size ; set pointer to FAT1x ;AN000;
3269
3270 mov cx,FAT_len ; move file system string into ;AN000;
3271 ; Boot_System_ID field
3272 lea di,IOCTL_File_Sys ; update buffer ;AN000;
3273 cld ; ;AN000;
3274 rep movsb ; ;AN000;
3275; $endif
3276$$IF185:
3277
3278; $if nc ; ;AN000;
3279 JC $$IF190
3280
3281 lea si,DeviceParameters.DP_BPB
3282 lea di,boot.EXT_BOOT_BPB
3283 mov cx,type EXT_BPB_INFO
3284 cld
3285 rep movsb
3286
3287 cmp DeviceParameters.DP_BPB.BPB_MediaDescriptor,hard_drive ; is it Hard drive?;AC000;
3288
3289; $if e ; if its a hard drive ;AC000;
3290 JNE $$IF191
3291
3292 ; NOTE: The physical hard drive number
3293 ; is placed in the third byte from
3294 ; the end in the boot sector in
3295 ; DOS 3.2. This is a change from
3296 ; the previous DOS versions.
3297
3298 ; fill in PhyDrv in canned boot record
3299 mov al,80h ; (set physical hard drive number) ;AC016;
3300; $else
3301 JMP SHORT $$EN191
3302$$IF191:
3303 xor al,al ; (set physical drive number to zero) ;AC016;
3304; $endif ; ;AC000;
3305$$EN191:
3306
3307 mov BOOT.EXT_PHYDRV,al ; (set physical hard drive number) ;AC016;
3308
3309 cmp DOS_VER,0 ; ;AN019;
3310; $if ne ; copy IOCTL stuff into boot record ;AN019;
3311 JE $$IF194
3312 ; (no set ID available for 3.3)
3313 lea si,IOCtl_Ser_No_Low ; point to source buffer (IOCTL) ;AN000;
3314 lea di,BOOT.EXT_BOOT_SERIAL ; point to target buffer (BOOT record) ;AN000;
3315
3316 mov cx,IOCTL_Ser_Vol_SyS ; move serial # , Volid , System ;AN019;
3317 cld ; ;AN019;
3318 rep movsb ; ;AN019;
3319; $endif ; ;AN019;
3320$$IF194:
3321
3322 xor cx,cx ; Sector 0 ;AN019;
3323 mov [packet],cx ; set starting sector as 0 ;AN019;
3324 mov bx,offset BOOT ; ;AN019;
3325 mov packet_buffer[0],bx ; ;AN019;
3326 mov word ptr [packet_sectors],1 ; ;AN019;
3327 mov ah,1 ; request a write ;AN019;
3328 call Direct_Access ; ;AN019;
3329
3330; $if c ; ;AC000;
3331 JNC $$IF196
3332; $endif ; ;AC000;
3333$$IF196:
3334
3335 cmp DOS_VER,0 ; ;AN019
3336; $if e ; only do a SET if DOS 4.00
3337 JNE $$IF198
3338 mov bl,TargDrvNum ; Drive number ;AN000;
3339 lea dx,IOCtl_Buf ; point to output buffer ;AN000;
3340 mov ax,(GetSetMediaID shl 8) + 1 ; set volid, ser# and filetype ;AC008;
3341 INT 21h ; GetSetMediaID + 1 INT 21 <6901> ;AC008;
3342; $endif ;AN019;
3343$$IF198:
3344
3345; $endif ; ;AC000;
3346$$IF190:
3347
3348 ret
3349
3350 ENDPROC Write_Boot_Record
3351
3352 BREAK <SYS - FAT_Size >
3353;******************* START OF SPECIFICATIONS ***********************************
3354;Routine name: FAT_Size
3355;*******************************************************************************
3356;
3357;Description: Determine FAT Type (12 or 16)
3358;
3359; NOTE: This routine is only called if the IOCtl call for
3360; Get Media Type FAILS with an extended error of
3361; 'Unknown media type'. This indicates it is a
3362; pre DOS 4.00 media (ie: it MUST be a 12 or old style
3363; 16 bit FAT
3364;
3365; This is the same algorithm used by FORMAT
3366;
3367; Algorithm:
3368;
3369; UsedSectors = number of reserved sectors
3370; + number of FAT Sectors ( Number of FATS * Sectors Per FAT )
3371; + number of directory sectors ( 32* Root Entries / bytes Per Sector )
3372;
3373; t_clusters = ( (Total Sectors - Used Sector) / Sectors Per Cluster)
3374;
3375; if T_Clusters <= 4086 then it a FAT12 - else - its a FAT16
3376;
3377;Called Procedures: None
3378;
3379;Input: EBPB of Target media in memory
3380;
3381;Output: SI: points to "FAT12 "
3382; or "FAT16 "
3383;
3384;Change History: Created 5/01/87 FG
3385;
3386;******************* END OF SPECIFICATIONS *************************************
3387;******************+ START OF PSEUDOCODE +**************************************
3388;
3389; START FAT_Size
3390;
3391; Calculate the number of directory sectors
3392; Calculate and add the number of FAT sectors
3393; Add in the number of boot sectors
3394; subtract used sectors from total sectors
3395; if <= FAT THRESHOLD then
3396; set pointer to FAT12
3397; else
3398; set pointer to FAT12
3399; endif
3400;
3401; ret
3402;
3403; END FAT_Size
3404;
3405;******************- END OF PSEUDOCODE -**************************************
3406
3407 public FAT_Size
3408
3409 FAT_Size PROC NEAR
3410
3411 ;--------------------------
3412 ; Calculate UsedSectors
3413 ;---------------------------
3414
3415 ; Calculate the number of directory sectors
3416
3417 mov ax, deviceParameters.DP_BPB.BPB_RootEntries ; ;AN000;
3418 mov bx, TYPE dir_entry ; ;AN000;
3419 mul bx ; ;AN000;
3420 add ax, deviceParameters.DP_BPB.BPB_BytesPerSector ; ;AN000;
3421 dec ax ; ;AN000;
3422 xor dx,dx ; ;AN000;
3423 div deviceParameters.DP_BPB.BPB_BytesPerSector ; ;AN000;
3424 mov cx,ax ; ;AN000;
3425
3426 ; Calculate the number of FAT sectors
3427
3428 mov ax, deviceParameters.DP_BPB.BPB_SectorsPerFAT ; ;AN000;
3429 mul deviceParameters.DP_BPB.BPB_NumberOfFATs ; ;AN000;
3430
3431 ; Add in the number of boot sectors
3432
3433 add ax, deviceParameters.DP_BPB.BPB_ReservedSectors ; ;AN000;
3434 add cx,ax ; ;AN000;
3435
3436 ;--------------------------
3437 ; Calculate t_clusters
3438 ;--------------------------
3439
3440 mov ax, deviceParameters.DP_BPB.BPB_TotalSectors ; ;AN000;
3441
3442 sub ax,cx ;Get sectors in data area ;AN000;
3443 xor dx,dx ; ;AN000;
3444 xor bx,bx ; ;AN000;
3445 mov bl,deviceParameters.DP_BPB.BPB_SectorsPerCluster ; ;AN000;
3446 div bx ;Get total clusters ;AN000;
3447 cmp ax,BIG_FAT_THRESHOLD ;Is clusters < 4086? ;AN000;
3448
3449; $if be ; if less then its a FAT12 ;AN000;
3450 JNBE $$IF201
3451 lea si,FAT_12 ; ;AN000;
3452; $else ; ;AN000;
3453 JMP SHORT $$EN201
3454$$IF201:
3455 lea si,FAT_16 ; ;AN000;
3456; $endif ; ;AN000;
3457$$EN201:
3458
3459 clc ; leave cleanly
3460
3461 return ; ;AN000;
3462
3463 ENDPROC FAT_Size
3464
3465 BREAK <SYS - Create_Serial_ID >
3466;******************* START OF SPECIFICATIONS ***********************************
3467;Routine name: Create_Serial_ID
3468;*******************************************************************************
3469;
3470;Description: Create unique 32 bit serial number by getting current date
3471; and time and then scrambling it around
3472;
3473;Called Procedures: None
3474;
3475;Input: None
3476;
3477;Output: serial number installed in Boot_Serial
3478;
3479;Change History: Created 5/01/87 FG
3480;
3481;******************* END OF SPECIFICATIONS *************************************
3482;******************+ START OF PSEUDOCODE +**************************************
3483;
3484; START Create_Serial_ID
3485;
3486; Get date (INT21 Get_Date + 00 <2A00>)
3487; Get time (INT21 Get_Time + 00 <2C00>)
3488; Boot_Serial+0 = DX reg date + DX reg date
3489; Boot_Serial+2 = CX reg time + CX reg time
3490; ret
3491;
3492; END Create_Serial_ID
3493;
3494;******************- END OF PSEUDOCODE -**************************************
3495
3496 public Create_Serial_ID
3497
3498 Create_Serial_ID PROC NEAR
3499
3500 mov ax,(Get_Date shl 8) + not_used ; Get date ;AN000;
3501 INT 21h ; Get_Date + not_used <2A00> ;AN000;
3502 mov ax,(Get_Time shl 8) + not_used ; Get time ;AN000;
3503 INT 21h ; Get_Time + not_used <2C00> ;AN000;
3504 add dx,dx ; Boot_Serial+0 = DX (date) + DX (date);AN000;
3505 add cx,cx ; Boot_Serial+2 = CX (time) + CX (time);AN000;
3506 mov IOCtl_Ser_No_Low,dx ; SERIAL # - low ;AN000;
3507 mov IOCtl_Ser_No_Hi,cx ; SERIAL # - hi ;AN000;
3508
3509 ret ; ;AN000;
3510
3511 ENDPROC Create_Serial_ID
3512
3513 BREAK <SYS - Message >
3514;******************* START OF SPECIFICATIONS ***********************************
3515;Routine name: Message
3516;*******************************************************************************
3517;
3518;Description: Display a message
3519;
3520;Called Procedures: SYSDISPMSG, Get_DOS_Error
3521;
3522;Input: (AL) message number
3523; (AH) message class
3524; = C - DS:SI points to sublist
3525;
3526;Output: no error AX = 0
3527; error - AX = error exit code
3528;
3529;Change History: Created 5/01/87 FG
3530;
3531;******************* END OF SPECIFICATIONS *************************************
3532;******************+ START OF PSEUDOCODE +**************************************
3533;
3534; START Message
3535;
3536; if DOS error
3537; call Get_DOS_error
3538; endif
3539; move message class into place
3540; reset insert (CX)
3541; reset response (DL)
3542; set output handle (BX)
3543; if CLASS requires insert
3544; load insert required
3545; if CLASS requires response
3546; flush keystroke buffer
3547; load response required (Dir CON in no echo)
3548; endif
3549; call SysDispMsg to display message
3550; if error or
3551; call Get_DOS_error
3552; call SysDispMsg to try again
3553; if not success message
3554; load error exit code
3555; else
3556; load success exit code
3557; endif
3558; ret
3559;
3560; END Message
3561;
3562;******************- END OF PSEUDOCODE -**************************************
3563
3564 public Message
3565
3566 Message PROC NEAR
3567
3568 xor dx,dx ; reset response (DL) ;AN000;
3569 xor cx,cx ; reset insert (CX) ;AC024;
3570 dec dh ; assume CLASS is Utility ;AN000;
3571
3572 cmp ah,PARSE_Error ; ;AN000;
3573
3574; $if be,and ; if DOS or PARSE error ;AN000;
3575 JNBE $$IF204
3576
3577 mov dh,ah ; ;AN000;
3578
3579; $if e,and ; if PARSE error ;AN024;
3580 JNE $$IF204
3581 cmp al,reqd_missing ; ;AC024;
3582; $if ne ; and if theres something there ;AC024;
3583 JE $$IF204
3584
3585 push cs ; set up for insert ;AN024;
3586 pop [insert_ptr_seg] ; (offset set by parse routine) ;AN024;
3587 mov cs:[si],dl ; make it an ASCIIZ string ;AN024;
3588 mov insert_number,dl ; zero out for %0
3589 mov insert_max,030h ; set length to something reasonable ;AN024;
3590 inc cx ; there's an insert ;AC024;
3591 lea si,SUBLIST ; point to the sublist ;AC024;
3592
3593; $endif ; ;AN024;
3594$$IF204:
3595
3596
3597 cmp ah,DOS_Error ; ;AN000;
3598
3599; $if be ; if DOS error ;AC019;
3600 JNBE $$IF206
3601
3602 call Get_DOS_error ; to find out what message to display ;AN000;
3603 mov dh,DOS_Error ; ensure message type is DOS_Error ;AN019;
3604
3605; $endif ; ;AN000;
3606$$IF206:
3607
3608 mov bx,STDERR ; set output handle (BX) ;AN000;
3609
3610 cmp ah,util_C ; is it CLASS C ;AN000;
3611
3612; $if e ; CLASS C requires insert ;AN000;
3613 JNE $$IF208
3614
3615 inc cx ; load insert required ;AN000;
3616
3617; $endif ; ;AN000;
3618$$IF208:
3619
3620 cmp ah,util_D ; is it CLASS D ;AN000;
3621
3622; $if e ; CLASS D requires response ;AN000;
3623 JNE $$IF210
3624
3625 mov dl,DOS_CON_INP ; load response required - con: input ;AN000;
3626
3627; $endif ; ;AN000;
3628$$IF210:
3629
3630 xor ah,ah ; ;AN000;
3631
3632
3633 call SysDispMsg ; to display message ;AN000;
3634
3635; $if c,and ; error and............... ;AN000;
3636 JNC $$IF212
3637
3638 call SysDispMsg ; to try again : ;AN000;
3639
3640; $if c ; if reaaly bad .........: ;AN000;
3641 JNC $$IF212
3642
3643 mov ax,return_error ; load error exit code ;AN000;
3644
3645; $else ; ;AN000;
3646 JMP SHORT $$EN212
3647$$IF212:
3648
3649 mov ax,success ; load success exit code ;AN000;
3650
3651; $endif ; ;AN000;
3652$$EN212:
3653
3654 ret ; ;AN000;
3655
3656 ENDPROC Message
3657
3658
3659 BREAK <SYS - Get_DOS_Error >
3660;******************* START OF SPECIFICATIONS ***********************************
3661;Routine name: Get_DOS_Error
3662;*******************************************************************************
3663;
3664;Description: Call DOS to obtain DOS extended error #
3665;
3666;Called Procedures: None
3667;
3668;Input: None
3669;
3670;Output: AX = error number
3671;
3672;Change History: Created 5/01/87 FG
3673;
3674;******************* END OF SPECIFICATIONS *************************************
3675;******************+ START OF PSEUDOCODE +**************************************
3676;
3677; START Get_DOS_Error
3678;
3679; call DOS for extended error (INT21 GetExtendedError + 00 <5900>)
3680; set up registers for return
3681; ret
3682;
3683; END Get_DOS_Error
3684;
3685;******************- END OF PSEUDOCODE -**************************************
3686
3687 public Get_DOS_Error
3688
3689 Get_DOS_Error PROC NEAR
3690
3691 push bx
3692 mov ax,(GetExtendedError shl 8) + not_used ; call DOS for extended error ;AN000;
3693 xor bx,bx
3694 push es ; ;AN000;
3695 INT 21h ; GetExtendedError + not_used <5900>;AN000;
3696 pop es
3697 pop bx ; ;AN000;
3698 xor cx,cx ; reset insert (CX) ;AC024;
3699
3700 ret ; ;AN000;
3701
3702 ENDPROC Get_DOS_Error
3703
3704 CODE ENDS
3705
3706 include msgdcl.inc
3707
3708 END START
3709
3710 \ No newline at end of file
diff --git a/v4.0/src/CMD/SYS/SYS2.ASM b/v4.0/src/CMD/SYS/SYS2.ASM
new file mode 100644
index 0000000..6c96070
--- /dev/null
+++ b/v4.0/src/CMD/SYS/SYS2.ASM
@@ -0,0 +1,2622 @@
1 TITLE SYS-2- Program
2 include version.inc
3 INCLUDE SYSHDR.INC
4
5 page 80,132
6 BREAK <SYS2 - Program Organization>
7;******************+ START OF PSEUDOCODE +**************************************
8; Ä Ä Ä Ä Ä Ä Ä Ä¿ ÚÄÄÄÄÄÄÄÄÄ¿
9; Read_Directory ÃÄÄÄÄÄÄ´Find_DPB ³
10; Ä Ä Ä Ä Ä Ä Ä ÄÙ ÀÄÄÄÄÄÄÄÄÄÙ
11; Ä Ä Ä Ä Ä Ä Ä Ä Ä ÄÄ¿
12; Verify_File_LocationÃÄ¿
13; Ä Ä Ä Ä Ä Ä Ä Ä Ä ÄÄÙ ³
14; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
15; ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä Ä Ä Ä ¿
16; ÃÄ´Move_DIR_EntryÃÄÄ´Find_Empty_Entry ÃÄÄ´Direct_Access³
17; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ À Ä Ä Ä Ä Ä Ä Ù
18; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
19; ³ À´Direct_Access³
20; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
21; ³ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22; ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄ¿
23; ÀÄ´Free_ClusterÃÄÄÄÄ´Is_It_EmptyÃÄÄÄÄÄÄÄÄ´Unpack ³
24; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÙ
25; ³ÚÄÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä ¿
26; ôSearch_FATÃÄÄÄÄÄÄÄÄ´Unpack ³
27; ³ÀÄÄÄÄÄÄÄÄÄÄÙ ³À Ä Ä Ä Ù
28; ³ ³ÚÄÄÄÄÄÄ¿
29; ³ ôPack ³
30; ³ ³ÀÄÄÄÄÄÄÙ
31; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä ¿
32; ³ ôFind_Empty_Cluster³ÄÄ´Unpack ³
33; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ À Ä Ä Ä Ù
34; ³ ³ÚÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä Ä Ä Ä ¿
35; ³ ôXfer_DataÃÄÄÄÄÄÄÄÄÄÄÄ´Direct_Access³
36; ³ ³ÀÄÄÄÄÄÄÄÄÄÙ À Ä Ä Ä Ä Ä Ä Ù
37; ³ ³Ú Ä Ä Ä Ä Ä Ä ¿
38; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÙ À´Direct_Access³
39; ³ À Ä Ä Ä Ä Ä Ä Ù
40; ³ÚÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä ¿
41; À´Search_DIRÃÄÄÄÄ´Search_LoopÃÄÄÄÄÄ´Unpack ³
42; ÀÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ ³À Ä Ä Ä Ù
43; ³ÚÄÄÄÄÄÄ¿
44; ôPack ³ Direct_Access
45; ³ÀÄÄÄÄÄÄÙ
46; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä ¿
47; ôFind_Empty_Cluster³ÄÄ´Unpack ³
48; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ À Ä Ä Ä Ù
49; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä ¿
50; ôSub_DIR_Loop³ÄÄ´Unpack ³
51; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ À Ä Ä Ä Ù
52; ³ÚÄÄÄÄÄÄÄÄÄ¿ Ú Ä Ä Ä Ä Ä Ä ¿
53; ôXfer_DataÃÄÄÄÄÄÄÄÄÄÄÄ´Direct_Access³
54; ³ÀÄÄÄÄÄÄÄÄÄÙ À Ä Ä Ä Ä Ä Ä Ù
55; ³Ú Ä Ä Ä Ä Ä Ä ¿
56; À´Direct_Access³
57; À Ä Ä Ä Ä Ä Ä Ù
58;
59;******************+ END OF PSEUDOCODE +*****************************************
60 BREAK <SYS2 - Data space>
61
62 DATA SEGMENT PARA PUBLIC
63
64 extrn TargDrvNum:BYTE, TargSpec:WORD, bio_owns_it:BYTE, DOS_VER:BYTE
65 extrn packet_sectors:WORD, packet_buffer:WORD, packet:WORD
66
67 public THIS_DPB, BUF, DIR_SECTOR, first_dir_sector
68
69
70; $SALUT (4,25,30,41)
71
72first_dir_sector dw ?
73current_dir_sector dw ?
74last_dir_sector dw ?
75entries_per_sector db ?
76current_entry db 3
77source_ptr dw ?
78ibmbio_status db ?
79ibmdos_status db ?
80FAT_sectors dw FAT_sect_size ; initailize it to 12 sectors
81FAT_changed db 0 ; FAT must be written - its packed
82FAT_2 db 0 ; if non zero, [packet] points at FAT 2
83cluster_count dw ? ; number of clusters that must be free
84last_cluster dw 0 ; cluster pointing to [current_cluster]
85current_cluster dw 2 ; start at cluster 2
86next_cluster dw 0 ; cluster [current_cluster] points at
87empty_cluster dw 0 ; newly aquired cluster
88cluster_low dw 0
89cluster_high dw clusters_loaded
90
91l_sector_offset dw ? ; this is the value required to convert
92 ; a sector from a cluster # to a
93 ; logical sector # for INT 25 & 26
94
95DIR_cluster dw 0 ; Sub DIR cluster being processed
96 ; = 0 - not processing s Sub DIR
97 ; = 1 - starting to process
98 ; (set by Search_Loop)
99 ; = n - Sub DIR cluster now being
100 ; processed. (set by Xfer_Data)
101present_cluster dw ? ; current cluster for DIR search
102sector_offset dw ? ; current sector in present_cluster
103entry_number db ? ; DIR entry in current sector
104FRAME_ptr dw ?
105dir_sector_low dw ?
106dir_sector_hi dw ?
107DIR_offset dw ?
108sector_count db 1
109
110FRAME STRUC
111
112p_cluster dw ? ; current cluster for DIR search
113s_offset dw ? ; current sector in present_cluster
114e_number db ? ; DIR entry in current sector
115
116FRAME ENDS
117
118BIGFAT DB 0 ;0=12 bit FAT, NZ=16bit FAT
119EOFVAL DW 0FF8H ;0FF8 for 12 bit FAT,0FFF8 for 16 bit
120BADVAL DW 0FF7H ;0FF7 for 12 bit FAT,0FFF7 for 16 bit
121
122THIS_DPB DD ? ;Pointer to drive DPB
123CSIZE DW ? ;Sectors per cluster
124SSIZE DW ? ;bytes per sector
125DSIZE DW ? ;# alloc units on disk
126FSIZE DW ? ;# sectors in 1 FAT
127first_FAT DW ? ; first cluster of first FAT
128num_of_FATS db ? ; number of FATS
129MCLUS DW ? ;DSIZE + 1
130;
131; The following is used as the source/destination for a name trans
132;
133ENTRY_BUF DB size dir_entry DUP (?)
134DIR_BUF DB ( 34 * size frame) DUP (?) ; space for DIR frames - see Search_DIR
135DIR_SECTOR DB 512 DUP (?) ; space for 1 DIR sector
136
137BUF LABEL BYTE ; beginning of area for file reads
138
139 DATA ENDS
140
141; $SALUT (4,4,9,41)
142
143 CODE SEGMENT PARA PUBLIC
144
145 ASSUME cs:CODE, ds:nothing, es:nothing
146
147 BREAK <SYS - Find_DPB >
148;******************* START OF SPECIFICATIONS ***********************************
149;Routine name: Find_DPB
150;*******************************************************************************
151;
152;Description: Find_DPB gets the pointer to the Target DPB and initializes all
153; local valiables required by Move_DIR_Entry and Free_Cluster.
154;
155;NOTE: This routine contains code that is specific for DOS 3.3. It
156; must be removed for subsequent releases. In and before
157; DOS 3.3 the DPB was one byte smaller. The field dpb_FAT_size
158; was changed from a byte to a word in DOS 4.00.
159;
160;
161;Entry: Called by Verify_File_Location
162;
163;Called Procedures:
164;
165; INT 21 - 32h
166;
167;Input: al = Drive number
168;
169;Output: All local variables initalized
170; DS:BX = pointer to DPB
171;
172;Change History: Created 7/01/87 FG
173;
174;******************* END OF SPECIFICATIONS *************************************
175;******************+ START OF PSEUDOCODE +**************************************
176;
177; START Find_DPB
178;
179; get DPB pointer (INT 21 - 32h)
180; initalize first_dir_sector
181; initalize current_dir_sector
182; initalize current_cluster (0 for root)
183; calculate # of clusters required by IBMBIO
184; initalize [cluster_count]
185; calculate # of dir sectors
186; initalize [dir_sectors]
187; initalize [current_entry] to #3
188; allocate memory for FAT + 32 DIR frames
189; allocate memory for data sectors
190;
191; ret
192;
193; END Find_DPB
194;
195;******************- END OF PSEUDOCODE -**************************************
196
197
198 PUBLIC Find_DPB
199
200 Find_DPB PROC NEAR
201
202 MOV AH,GET_DPB ;Get the DPB ;AN004;
203 INT 21H
204
205 mov ax,(disk_reset shl 8) ; reset the disk to protect all INT 26's
206 INT 21h ; that follow
207
208
209 ; initalize current_entry to #3
210
211 ASSUME ds:nothing,es:DATA
212
213 MOV WORD PTR [THIS_DPB+2],DS ; ;AN004;
214 push es ; ;AN004;
215 pop ds ; ;AN004;
216
217 ASSUME ds:DATA
218
219 mov WORD PTR [THIS_DPB],bx ; ;AN004;
220 lds bx,[THIS_DPB] ; ;AN004;
221
222 ASSUME ds:nothing
223
224 mov ax,[bx.dpb_sector_size] ; ;AN004;
225 mov [SSIZE],ax ;Sector size in bytes ;AN004;
226
227 xor ax,ax ; ;AN004;
228 mov al,[bx.dpb_cluster_mask] ; ;AN004;
229 inc al ; ;AN004;
230 mov [CSIZE],ax ;Sectros per cluster ;AN004;
231
232 mov ax,[BX.dpb_first_FAT] ;First sector of FAT ;AN004;
233 mov [first_FAT],ax ; ;AN004;
234
235 mov al,[BX.dpb_FAT_count] ;Number of FATs ;AN004;
236 mov [num_of_FATS],al ; ;AN004;
237
238 mov ax,[bx.dpb_max_cluster] ; ;AN004;
239 mov [MCLUS],ax ;Bound for FAT searching ;AN004;
240
241 cmp ax,4096-10 ;Big or little FAT? ;AN004;
242; $if ae ; ;AN004;
243 JNAE $$IF1
244 inc [BIGFAT] ; ;AN004;
245 mov [EOFVAL],0FFF8h ; ;AN004;
246 mov [BADVAL],0FFF7h ; ;AN004;
247; $endif ; ;AN004;
248$$IF1:
249 dec ax ; ;AN004;
250 mov [DSIZE],ax ;Total data clusters on disk ;AN004;
251
252 ;--------------------------------------
253 ; calculate # of dir sectors and
254 ; initalize last_dir_sector
255 ;--------------------------------------
256 mov ax,[bx.dpb_root_entries] ; max # of entries in the root ;AN004;
257 mov cx,size dir_entry ; size of each entry ;AN004;
258 mul cx ; size of root directory in bytes ;AN004;
259 ; in AX:DX ;AN004;
260 mov cx,[SSIZE] ; # of bytes per sector ;AN004;
261 div cx ; = # of root directory sectors ;AN004;
262 cmp dx,0 ; any remainder ? ;AN004;
263; $if nz ; ;AN004;
264 JZ $$IF3
265 inc ax ; ;AN004;
266; $endif ; ;AN004;
267$$IF3:
268 mov [first_dir_sector],ax ; save for last directory sector calc. ;AN004;
269
270 mov ax,[bx.dpb_FAT_size] ;Sectors for one fat ;AN004;
271 cmp DOS_VER,0 ; running on current version? ;AN019;
272
273; $if ne ; BANG! - we'er running on DOS 3.3 ;AN019;
274 JE $$IF5
275 ; dpb_FAT_size is only a BYTE
276 ; so ajust it to a word
277 xor ah,ah ;AN019;
278 dec bx ; BACK UP the index into the DPB ;AN019;
279 mov WORD PTR [THIS_DPB],bx ; save it for later (dpb_next_free) ;AN021;
280 ; Now everything else lines up !
281; $endif
282$$IF5:
283
284 mov [FSIZE],ax ; ;AN004;
285
286 mov ax,[SSIZE] ; ;AN004;
287 mov cx,SIZE dir_entry ; ;AN004;
288 div cx ; ;AN004;
289 dec ax ; first entry number is zero ;AN004;
290 mov [entries_per_sector],al ; ;AN004;
291 cmp [BIGFAT],0 ; is it a big fat ? ;AN004;
292
293; $if e ; if not ;AN004;
294 JNE $$IF7
295 mov ax,[FSIZE] ; ;AN004;
296 mov [FAT_sectors],ax ; bring it down to the actual size ;AN004;
297; $endif ; ;AN004;
298$$IF7:
299 ;--------------------------------------
300 ; initalize first_dir_sector
301 ; and current_dir_sector
302 ;--------------------------------------
303 mov ax,[bx.dpb_dir_sector] ; first dir sector ;AN004;
304 mov [current_dir_sector],ax ; save it for later ;AN004;
305 xchg [first_dir_sector],ax ; save it and recover # of dir sectors ;AN004;
306
307 add ax,[first_dir_sector] ; # of last directory sector ;AN004;
308 mov [l_sector_offset],ax ; ;AN004;
309 dec ax ; ;AN004;
310 mov [last_dir_sector],ax ; save it for later ;AN004;
311
312 ret ; ;AN004;
313
314 Find_DPB ENDP
315
316 BREAK <SYS - Move_DIR_Entry >
317;******************* START OF SPECIFICATIONS ***********************************
318;Routine name: Move_DIR_Entry
319;*******************************************************************************
320;
321;Description: Move_DIR_Entry will move the entry pointed to by the caller into
322; the first available location in the root, if one exists.
323;
324;Entry: Called by Verify_File_Location
325;
326;Called Procedures:
327;
328; Find_Empty_Entry - find an available entry
329; Direct_Access - do an INT 25 & INT 26
330;
331;Input: first_dir_sector
332; current_dir_sector
333; last_dir_sector
334; current_entry
335; pointer set to source entry to be moved
336;
337;Output: CF = 0 - DIR entry moved to first available entry
338; CF = 1 - Error, not able to free up entry
339;
340;Change History: Created 7/01/87 FG
341;
342;******************* END OF SPECIFICATIONS *************************************
343;******************+ START OF PSEUDOCODE +**************************************
344;
345; START Move_DIR_Entry
346;
347; set dest = entry_buffer
348; save source pointer
349; copy input entry to buffer
350; if no error and
351; call Find_Empty_Entry to find hole in directory
352; if no error
353; set source to entry_buffer
354; set dest to hole pointer
355; copy buffer to enpty entry
356; if first_dir_sector != current_dir_sector
357; set up for write
358; call Direct_Access to write it out
359; if no error
360; set up for first_dir_sector
361; set up for read
362; call Direct_Access to read it in
363; endif
364; if no error
365; recover source pointer
366; null out entry being processed
367; set up for write
368; call Direct_Access to update the root
369; endif
370; endif
371;
372; ret
373;
374; END Move_DIR_Entry
375;
376;******************- END OF PSEUDOCODE -**************************************
377
378
379 PUBLIC Move_DIR_Entry
380
381 Move_DIR_Entry PROC NEAR
382
383 ASSUME ds:DATA ; must ensure this is true xxxxxxxxxxxxxxxxx
384
385 ; source = source entry (#1 or #2) DS:SI
386 lea di,ENTRY_BUF ; dest = entry_buffer ;AN004;
387 mov [source_ptr],si ; save source pointer ;AN004;
388 mov ax,size dir_entry ; ;AN004;
389 mov cx,ax ; ;AN004;
390 rep movsb ; copy directory entry into entry buffer;AN004;
391 lea si,DIR_SECTOR ; start at beginning of directory ;AN004;
392 mov di,si ; save start for end calculation ;AN004;
393 shl ax,1 ; set pointer for current entry to #3 ;AN004;
394 add ax,si ; ;AN004;
395 mov si,ax ; ;AN004;
396 add di,[SSIZE] ; calculate end of directory ;AN004;
397 call Find_Empty_Entry ; find hole in directory ;AN004;
398; $if nc ; if no error and ;AN004;
399 JC $$IF9
400 mov di,si ; dest = hole pointer ;AN004;
401 lea si,ENTRY_BUF ; source = entry_buffer ;AN004;
402 mov cx,size dir_entry ; ;AN004;
403 rep movsb ; copy buffer to DTA ;AN004;
404 mov ax,[first_dir_sector] ; ;AN004;
405 cmp ax,[current_dir_sector] ; ;AN004;
406; $if ne ; if first_dir_sector != current_dir_sector;AN004;
407 JE $$IF10
408 mov ah,-1 ; set up for write ;AN004;
409 call Direct_Access ; write it out ;AN004;
410; $if nc ; if no error ;AN004;
411 JC $$IF11
412 mov ax,[first_dir_sector] ; set up for first_dir_sector ;AN004;
413 mov [current_dir_sector],ax ; update current_dir_sector ;AN004;
414 mov [packet],ax ; ;AN004;
415 xor ah,ah ; set up for read ;AN004;
416 call Direct_Access ; read it in ;AN004;
417; $endif ; ;AN004;
418$$IF11:
419; $endif ; ;AN004;
420$$IF10:
421; $if nc ; if no error ;AN004;
422 JC $$IF14
423 mov si,[source_ptr] ; recover source pointer ;AN004;
424 mov BYTE PTR [si],deleted ; delete entry being processed ;AN004;
425 mov BYTE PTR [si.dir_first],0 ; null out cluster # ;AN004;
426 cmp si,offset DIR_SECTOR ; are we at the first entry ? ;AN010;
427; $if e,and ; if so - ;AN010;
428 JNE $$IF15
429 cmp BYTE PTR [si + size DIR_ENTRY],0 ; is second one a null entry? ;AN010;
430; $if e ; if so - ;AN010;
431 JNE $$IF15
432 mov BYTE PTR [si + size DIR_ENTRY],deleted ; make it deleted ;AN010;
433; $endif ; ;AN010;
434$$IF15:
435 mov ah,-1 ; set up for write ;AN004;
436 call Direct_Access ; write it out ;AN004;
437; $endif ; ;AN004;
438$$IF14:
439; $endif ; ;AN004;
440$$IF9:
441
442 ret ; ;AN004;
443
444 Move_DIR_Entry ENDP
445
446 BREAK <SYS - Find_Empty_Entry >
447;******************* START OF SPECIFICATIONS ***********************************
448;Routine name: Find_Empty_Entry
449;*******************************************************************************
450;
451;Description: Find_Empty_Entry scans all root directory sectors looking for
452; an empty entry.
453;
454; NOTE; It is assumed that each DIRectory entry is 32 bytes long
455;
456;Called Procedures:
457;
458; Direct_Acces - do INT 25
459;
460;Input: current_dir_sector
461; last_dir_sector
462; first_dir_sector in DTA buffer
463; DS:SI set for first entry to check
464; DS:DI set to end of directory (sector)
465;
466;Output: success pointer set to hole
467; CF = 0 current_entry updated
468; current_dir_sector updated
469;
470; fail message # set
471; CF = 1
472;
473;Change History: Created 7/01/87 FG
474;
475;******************* END OF SPECIFICATIONS *************************************
476;******************+ START OF PSEUDOCODE +**************************************
477;
478; START Find_Empty_Entry
479;
480; search all available sectors
481; search for hole (leaves pointer set to the hole)
482; leave if empty
483; leave if deleted
484; advace to next entry
485; exitif past end of sector
486; set carry
487; orelse
488; endloop
489; clear carry
490; save current_entry
491; endsrch
492; exitif hole found (no CF)
493; update current_entry
494; orelse
495; if not at end (current <= last)
496; set for read
497; call Direct_Access to read in next sector
498; else
499; load error message (no room for system files)
500; set error (CF)
501; endif
502; leave if error (CF)
503; update current_DIR_sector
504; update current_entry
505; endif
506; endloop
507; endsrch
508;
509; ret
510;
511; END Find_Empty_Entry
512;
513;******************- END OF PSEUDOCODE -**************************************
514
515 PUBLIC Find_Empty_Entry
516
517 Find_Empty_Entry PROC NEAR
518
519; $search ; for sectors available ;AN004;
520$$DO19:
521 ; ;AN004;
522; $search ; for hole - this leaves pointer set at;AN004;
523$$DO20:
524 ; the hole ;AN004;
525 cmp BYTE PTR [si],empty ; empty ? ;AN004;
526; $leave e ; ;AN004;
527 JE $$EN20
528 cmp BYTE PTR [si],deleted ; deleted ? ;AN004;
529; $leave e ; ;AN004;
530 JE $$EN20
531 add ax,size dir_entry ; advace to next entry ;AN004;
532 mov si,ax ; ;AN004;
533 cmp ax,di ; past end of sector ? ;AN004;
534; $exitif ae ; at end ;AN004;
535 JNAE $$IF20
536 stc ; set carry ;AN004;
537; $orelse ; ;AN004;
538 JMP SHORT $$SR20
539$$IF20:
540; $endloop ; ;AN004;
541 JMP SHORT $$DO20
542$$EN20:
543 clc ; clear carry ;AN004;
544; $endsrch ; ;AN004;
545$$SR20:
546; $exitif nc ; hole is found ;AN004;
547 JC $$IF19
548; $orelse ; ;AN004;
549 JMP SHORT $$SR19
550$$IF19:
551 inc [current_dir_sector] ; advance to next sector ;AN004;
552 mov ax,[current_dir_sector] ; ;AN004;
553 cmp ax,[last_dir_sector] ; past last_dir_sector ? ;AN004;
554; $leave a ; if at end (current <= last) ;AN004;
555 JA $$EN19
556 lea si,DIR_SECTOR ; start at start of next sector ;AN004;
557 mov [packet],ax ; ;AN004;
558 xor ah,ah ; set for read ;AN004;
559 call Direct_Access ; read in next sector ;AN004;
560; $if c ; if error ;AN004;
561 JNC $$IF30
562 dec [current_dir_sector] ; restore curren_dir_sector ;AN004;
563; $endif ; ;AN004;
564$$IF30:
565; $leave c ; error ;AN004;
566 JC $$EN19
567 mov ax,si ; reset pointer to start ;AN004;
568; $endloop a ; past last_dir_sector ;AN004;
569 JNA $$DO19
570$$EN19:
571 mov ax,(util shl 8) + no_room ; set message# and class ;AN004;
572 stc ; ensure carry still set ;AN004;
573; $endsrch ; ;AN004;
574$$SR19:
575
576 ret ; ;AN004;
577
578 Find_Empty_Entry ENDP
579
580
581
582 BREAK <SYS - Direct_Access >
583;******************* START OF SPECIFICATIONS ***********************************
584;Routine name: Direct_Access
585;*******************************************************************************
586;
587;Description: Direct_Access
588;
589;Called Procedures:
590;
591; INT 25
592; INT 26
593;
594;Input: ah = 0 - read
595; ah = -1 - write
596;
597;Output: CF = 0 - Sectors moved
598; CF = 1 - Message and class in AX
599;
600;Change History: Created 7/01/87 FG
601;
602;******************* END OF SPECIFICATIONS *************************************
603;******************+ START OF PSEUDOCODE +**************************************
604;
605; START Direct_Access
606;
607; save registers
608; if read
609; INT 25
610; else
611; zero ah
612; INT 26
613; endif
614; save return flag
615; clear stack
616; if error
617; set message# and class
618; endif
619; restore registers
620;
621; ret
622;
623; END Direct_Access
624;
625;******************- END OF PSEUDOCODE -**************************************
626
627 public Direct_Access
628
629 Direct_Access PROC NEAR
630
631 push si ; save registers ;AN004;
632 push bp ; save registers ;AN004;
633 cmp DOS_VER,0 ; ;AN019;
634
635; $if e ; ;AN019;
636 JNE $$IF35
637
638 mov cx,-1 ; set up for INT ;AN004;
639 mov bx,offset packet ; ;AN004;
640
641; $else ; ;AN019;
642 JMP SHORT $$EN35
643$$IF35:
644 ; If running on DOS 3.3 the INT 25
645 ; interface is:
646 ; al = drive number
647 ; bx = buffer for read data
648 ; cx = # of sectors
649 ; dx = start sector
650 mov cx,word ptr [packet_sectors] ; ;AN019;
651 mov dx,[packet] ; get starting dir sector ;AN019;
652 mov bx,PACKET_BUFFER[0] ; ;AN019;
653
654; $endif ; ;AN019;
655$$EN35:
656
657 mov al,TargDrvNum ; set up drive number ;AN004;
658 dec al ; ;AN004;
659 cmp ah,0 ; ;AN004;
660; $if e ; if read ;AN004;
661 JNE $$IF38
662 INT 25h ; INT 25 ;AN004;
663; $else ; else ;AN004;
664 JMP SHORT $$EN38
665$$IF38:
666 xor ah,ah ; zero ah ;AN004;
667 INT 26h ; INT 26 ;AN004;
668; $endif ; endif ;AN004;
669$$EN38:
670;; ? ; save return flag ;AN004;
671 pop ax ; clear stack ;AN004;
672 pop bp ; ;AN004;
673 pop si ; ;AN004;
674
675 ret ; ;AN004;
676
677 Direct_Access ENDP
678
679 BREAK <SYS - Free_Cluster >
680;******************* START OF SPECIFICATIONS ***********************************
681;Routine name: Free_Cluster processor
682;*******************************************************************************
683;
684;Description: IBMBIO MUST have at lease cluster 2 as its first cluster. This
685; routine ensures that cluster 2 and any additional clusters (if
686; needed) ARE available. If they are chained, their data is copied
687; into the first available cluster, and the needed cluster is
688; is replaced by this cluster in the FAT
689;
690;Entry: Called by Verify_File_Location
691;
692;Called Procedures:
693;
694; Is_It_Empty - see if Cluster is empty
695; Search_FAT - scan FAT to see if the cluster is chained
696; Search_DIR - use FAT to walk directories looking for the cluster
697;
698; NOTES: Check_FAT and Check_DIR will do the processing requred to move
699; data out of the cluster and fix up the FAT and the Dir (if needed).
700;
701;Input: All local DBP values initalized by Get_DPB
702;
703;Ouput: CF = 0 - Cluster available
704; CF = 1 - Cluster not available
705;
706;
707;Change History: Created 7/01/87 FG
708;
709;******************* END OF SPECIFICATIONS *************************************
710;******************+ START OF PSEUDOCODE +**************************************
711;
712; START Free_Cluster
713;
714; initialize [cluster_count]
715; do until all copies of FAT attempted
716; load FAT into memory (INT 25)
717; leave if successful
718; enddo
719; do until [cluster_count] = 0
720; call Is_It_Empty
721; if not found and
722; if no errors and
723; call Search_FAT
724; if not found and
725; if no errors
726; call Search_DIR
727; endif
728; leave if error
729; enddo
730;
731; ret
732;
733; END Free_Cluster
734;
735;******************- END OF PSEUDOCODE -**************************************
736
737 public Free_Cluster
738
739 Free_Cluster PROC NEAR
740
741 mov ax,IBMLOADSIZE ; calculate # of clusters reqd ;AN004;
742 xor cx,cx ; ;AN004;
743 mov di,cx ; ;AN004;
744 dec di ; ;AN004;
745 mov cx,[CSIZE] ; by IBMLOAD (consecutive clusters ;AN004;
746 div cl ; for IBMBIO) ;AN004;
747 cmp ah,0 ; ;AN004;
748; $if ne ; ;AN004;
749 JE $$IF41
750 inc al ; ;AN004;
751 xor ah,ah ; ;AN004;
752; $endif ; ;AN004;
753$$IF41:
754 inc ax ; will be decrimenter immediately upon ;AN004;
755 ; entering complex do below
756 mov [cluster_count],ax ; save for later ;AN004;
757 mov ax,[FAT_sectors] ;only read needed sectors ;AN004;
758 mov [packet_sectors],ax ; ;AN004;
759 mov cl,[num_of_FATS] ;Number of FATs ;AN004;
760 mov ax,[first_FAT] ;First sector of FAT ;AN004;
761 mov [packet],ax ; ;AN004;
762 mov [packet_buffer],OFFSET BUF ; point to FAT buffer ;AN004;
763 call Load_FAT ; ;AN004;
764; $if nc ; no error so far....... ;AN004;
765 JC $$IF43
766; $do complex ; ;AN004;
767 JMP SHORT $$SD44
768$$DO44:
769 mov [cluster_count],cx ; ;AN004;
770 call Is_It_Empty ; ;AN004;
771; $leave c ; ;AN014;
772 JC $$EN44
773 cmp al,not_found ; ( -1 ?) ;AN004;
774; $if e ; if not found ;AN004;
775 JNE $$IF46
776 call Search_FAT ; scan FAT to see if cluster chained ;AN004;
777; $else ; ;AN004;
778 JMP SHORT $$EN46
779$$IF46:
780 clc ; ;AN004;
781; $endif ; ;AN004;
782$$EN46:
783; $leave c ; ;AN004;
784 JC $$EN44
785 cmp al,not_found ; if still not found ;AN004;
786; $if e ; ;AN004;
787 JNE $$IF50
788 call Search_DIR ; scan DIR to see who starts with #2 ;AN004;
789; $else ; ;AC013;
790 JMP SHORT $$EN50
791$$IF50:
792 clc ; ensure carry is still clear ;AC013;
793; $endif ; ;AN004;
794$$EN50:
795; $leave c ; ;AN004;
796 JC $$EN44
797 inc [current_cluster] ; ;AN004;
798; $strtdo ; ;AN004;
799$$SD44:
800 mov cx,[cluster_count] ; ;AN004;
801; $enddo LOOP ; ;AN004;
802 LOOP $$DO44
803$$EN44:
804; $endif ; ;AN004;
805$$IF43:
806; $if c ; ;AN004;
807 JNC $$IF57
808 mov ax,(util shl 8) + no_room ; error message - no room to sys ;AN014;
809; $endif ; ;AN004;
810$$IF57:
811
812 ret ; ;AN004;
813
814 Free_Cluster ENDP
815
816 public Load_FAT
817
818 Load_FAT PROC NEAR
819
820 lea bx,[packet] ; ;AN004;
821
822; $search ; ;AN004;
823$$DO59:
824 xchg cx,di ; ;AN004;
825 push cx ; ;AN004;
826 push di ; ;AN004;
827 push dx ; ;AN004;
828 push bx ; ;AN004;
829 xor ah,ah ; ;AN004;
830 mov al,TargDrvNum ; set up drive number ;AN004;
831 dec al ; ;AN004;
832 cmp DOS_VER,0 ; if DOS 3.3 ;AN019;
833
834; $if ne ; load registers for old style INT 25 ;AN019;
835 JE $$IF60
836 mov bx,[packet_buffer] ; ;AN019;
837 mov cx,[packet_sectors] ; ;AN019;
838 mov dx,[packet] ; ;AN019;
839; $endif ; ;AN019;
840$$IF60:
841
842 push bp ; ;AN019;
843 int 25h ;Read in the FAT ;AN004;
844 pop ax ;Flags ;AN004;
845 pop bp ; ;AN019;
846; $exitif nc ; error - set up for next fat ;AN004;
847 JC $$IF59
848 add sp,8 ;Clean up stack ;AN004;
849 mov ax,1 ; ;AN004;
850; mov [packet],ax ; reset to first FAT ;AN004;
851; $orelse ; ;AN004;
852 JMP SHORT $$SR59
853$$IF59:
854 pop bx ; ;AN004;
855 pop dx ; ;AN004;
856 pop cx ; ;AN004;
857 pop di ; ;AN004;
858 add [packet],dx ; point to start of next FAT ;AN004;
859 inc [FAT_2] ; ;AN004;
860; $endloop LOOP ;Try next FAT ;AN004;
861 LOOP $$DO59
862 mov ax,(util shl 8) + no_room ; set message# and class ;AN004;
863; $endsrch ; ;AN004;
864$$SR59:
865
866 ret
867
868 Load_FAT ENDP
869
870
871 BREAK <SYS - Is_It_Empty >
872;******************* START OF SPECIFICATIONS ***********************************
873;Routine name: Is_It_Empty
874;*******************************************************************************
875;
876;Description: Is_It_Empty looks directly into the FAT to see if a specified
877; cluster is allocated.
878;
879;Entry: Called by Free_Cluster
880;
881;Called Procedures:
882;
883; Unpack - unpack a FAT cluster number (CF set on error)
884;
885;Input: CX = cluster to check
886; 12 sectors of FAT in BUF
887;
888;Output: CF = 0 AL = 0 - cluster 2 found empty
889; AL =-1 - not found & no error
890; CF = 1 - critical error
891;
892;Change History: Created 7/01/87 FG
893;
894;******************* END OF SPECIFICATIONS *************************************
895;******************+ START OF PSEUDOCODE +**************************************
896;
897; START Is_It_Empty
898;
899; set up for call to Unpack
900; set cluster # to [cluster_number]
901; call Unpack
902; if no error
903; if cluster is not empty
904; if bad cluster
905; set error flag
906; else
907; if cluster belongs to IBMBIO
908; if next cluster is not contiguous
909; reset ownership flag
910; endif
911; set cluster empty (ax = 0)
912; else
913; save cluster number
914; set cluster used (ax = -1)
915; endif
916; else
917; set cluster empty (ax = 0)
918; endif
919; endif
920;
921; ret
922;
923; END Is_It_Empty
924;
925;******************- END OF PSEUDOCODE -**************************************
926
927 public Is_It_Empty
928
929 Is_It_Empty PROC NEAR
930
931 mov si,[current_cluster] ; set up for call to Unpack ;AN004;
932 call Unpack ; to find the value ;AN004;
933; $if nc ; if no error ;AN004;
934 JC $$IF66
935; $if nz ; cluster is not empty ;AN004;
936 JZ $$IF67
937 mov ax,di ; ;AN004;
938 cmp al,bad_sector ; ;AN004;
939; $if e ; ;AN004;
940 JNE $$IF68
941 stc ; ;AN004;
942; $else ; ;AN004;
943 JMP SHORT $$EN68
944$$IF68:
945 cmp [bio_owns_it],0 ; is it owned by IBMBIO ? ;AN004;
946; $if ne ; if it is ;AN004;
947 JE $$IF70
948 dec ax ; ;AN004;
949 cmp ax,[current_cluster] ; ;AN004;
950; $if ne ; ;AC011;
951 JE $$IF71
952 dec [bio_owns_it] ; its not the owner form here on ;AC011;
953; $endif ; ;AC011;
954$$IF71:
955 xor ax,ax ; ;AN004;
956 clc ; its IBMBIO's anyway ;AC011;
957; $else ; ;AN004;
958 JMP SHORT $$EN70
959$$IF70:
960 mov [next_cluster],di ; ;AN004;
961 xor ax,ax ; reset fail flag ;AN004;
962 dec ax ; - its not empty ;AN014;
963; $endif ; ;AN004;
964$$EN70:
965; $endif ; ;AN004;
966$$EN68:
967; $else ; its empty ! ;AN005;
968 JMP SHORT $$EN67
969$$IF67:
970 xor ax,ax ; its empty - and no error ;AN014;
971; $endif ; ;AN014;
972$$EN67:
973; $endif ; ;AN004;
974$$IF66:
975
976 ret ; ;AN004;
977
978 Is_It_Empty ENDP
979
980 BREAK <SYS - Search_FAT >
981;******************* START OF SPECIFICATIONS ***********************************
982;Routine name: Search_FAT
983;*******************************************************************************
984;
985;Description: Search_FAT for a [cluster_number]. If it is listed in the FAT,
986; then its chained into a file. The data in the [cluster_number] is
987; then buffered, and copied into an empty cluster, and the FAT is
988; updated
989;
990;Called Procedures:
991;
992; Unpack - to find a FAT entry for a Cluster #
993; Pack - to set a FAT entry for a Cluster #
994; Find_Empty_Cluster - find an unused cluster
995; Xfer_Data - transfere data from one cluster to another
996; Direct_Access - absolute disk i/o
997;
998;Input: FAT in BUF
999; [cluster_number] of specified cluster
1000;
1001;Output: CF = 0 - AX = 0 if cluster found
1002; = -1 if cluster not found
1003; CF = 1 if critical error
1004;
1005;Change History: Created 7/01/87 FG
1006;
1007;******************* END OF SPECIFICATIONS *************************************
1008;******************+ START OF PSEUDOCODE +**************************************
1009;
1010; START Search_FAT
1011;
1012; set cluster # to [cluster_number]
1013; search till at end of FAT
1014; call Unpack
1015; exitif cluster found
1016; save [last_cluster]
1017; clear CF
1018; orelse
1019; advance to next cluster
1020; endloop if past last cluster in fat
1021; set CF
1022; endsrch
1023; if cluster found
1024; call Find_Empty_Cluster
1025; endif
1026;
1027; if empty cluster available and
1028;
1029; call Xfer_Data
1030;
1031; if no errors
1032;
1033; set taget cluster as one pointing to [cluster_number]
1034; set value to that of empty cluster
1035; call Pack to update FAT
1036; set target cluster as [cluster_number]
1037; set cluster value to empty
1038; call Pack to update FAT
1039; set destination to first sector of first FAT
1040; set count to # of fat sectors
1041; set up for write
1042; do until all FATS written
1043; call Direct_Access
1044; advace to next FAT (ignore errors)
1045; enddo
1046;
1047; endif
1048;
1049; if no errors
1050; update DPB first cluster and total empty clusters
1051; endif
1052;
1053; ret
1054;
1055; END Search_FAT
1056;
1057;******************- END OF PSEUDOCODE -**************************************
1058
1059 public Search_FAT
1060
1061 Search_FAT PROC NEAR
1062
1063 mov si,[current_cluster] ; set cluster # to [cluster_number] ;AN004;
1064; $search ; till at end of FAT ;AN004;
1065$$DO79:
1066 call Unpack ; ;AN004;
1067; $leave c ; quit on an error ;AN004;
1068 JC $$EN79
1069 cmp di,[current_cluster] ; is it [current_cluster] ? ;AN004;
1070; $exitif e ; it is ;AN004;
1071 JNE $$IF79
1072 mov [last_cluster],si ; save number for later ;AN004;
1073 xor ax,ax ; ;AN004;
1074 clc ; clear error flag (found) ;AN004;
1075; $orelse ; ;AN004;
1076 JMP SHORT $$SR79
1077$$IF79:
1078 inc si ; advance to next cluster ;AN004;
1079 xor ax,ax ; ;AN004;
1080 dec ax ; ;AN004;
1081 cmp si,[MCLUS] ; at the end ? ;AN004;
1082; $endloop e ; if past last cluster ;AN004;
1083 JNE $$DO79
1084$$EN79:
1085 stc ; ;AN014;
1086; $endsrch ; ;AN004;
1087$$SR79:
1088; $if nc ; if cluster found ;AN004;
1089 JC $$IF85
1090 call Find_Empty_Cluster ; to move data to ;AN004;
1091; $endif ; ;AN004;
1092$$IF85:
1093; $if nc,and ; empty cluster available and ;AN004;
1094 JC $$IF87
1095 call Xfer_Data ; to move data to new cluster ;AN004;
1096; $if nc,and ; no errors ;AN004;
1097 JC $$IF87
1098 mov si,[last_cluster] ; set target [last_cluster] ;AN004;
1099 mov dx,[empty_cluster] ; set value to [empty_cluster] ;AN004;
1100 call Pack ; to update FAT ;AN004;
1101; $if nc,and ; no errors ;AN004;
1102 JC $$IF87
1103 mov si,[empty_cluster] ; set target [empty_cluster] ;AN004;
1104 mov dx,[next_cluster] ; set value to [next_cluster] ;AN004;
1105 call Pack ; to update FAT ;AN004;
1106; $if nc,and ; no errors ;AN004;
1107 JC $$IF87
1108 mov si,[current_cluster] ; set target [current_cluster] ;AN004;
1109 xor dx,dx ; set cluster value to empty ;AN004;
1110 call Pack ; to update FAT ;AN004;
1111; $if nc ; no errors ;AN004;
1112 JC $$IF87
1113 xor ah,ah ; ;AN004;
1114 dec ah ; ;AN004;
1115 call Direct_Access ; write it out - ignore errors ;AN004;
1116 mov ax,[FSIZE] ; ;AN004;
1117 cmp [FAT_2],0 ; ;AN004;
1118; $if e ; ;AN004;
1119 JNE $$IF88
1120 add [packet],ax ; ;AN004;
1121 inc [FAT_2] ; packet points to FAT #2 ;AC006;
1122; $else ; ;AN004;
1123 JMP SHORT $$EN88
1124$$IF88:
1125 sub [packet],ax ; ;AN004;
1126 mov [FAT_2],0 ; reset - packet points to FAT #1 ;AN004;
1127; $endif ; ;AN004;
1128$$EN88:
1129 xor ah,ah ; ;AN004;
1130 dec ah ; ;AN004;
1131 call Direct_Access ; write it out - ignore errors ;AN004;
1132 mov [FAT_changed],0 ; FAT now cleared ;AN004;
1133 push es ; update DPB first cluster ;AN004;
1134 mov bx,ds ; ;AN004;
1135 mov es,bx ; ;AN004;
1136 lds bx,[THIS_DPB] ; ;AN004;
1137
1138 ASSUME ds:nothing,es:DATA
1139
1140 mov [bx.dpb_next_free],2 ; ;AN004;
1141 mov ax,es ; ;AN004;
1142 mov ds,ax ; ;AN004;
1143 pop es ; ;AN004;
1144 xor ax,ax ; signal success (ax = 0 , cf = 0) ;AN004;
1145
1146 ASSUME DS:data, es:nothing
1147
1148; $endif ; ;AN004;
1149$$IF87:
1150; $if c ; ;AN004;
1151 JNC $$IF92
1152 cmp ax,-1 ; ;AN004;
1153; $if e ; ;AN004;
1154 JNE $$IF93
1155 clc ; not a critical error - keep trying ;AN004;
1156; $else ; ;AN004;
1157 JMP SHORT $$EN93
1158$$IF93:
1159 stc ; major problem - critical error ;AN004;
1160; $endif ; ;AN004;
1161$$EN93:
1162; $endif ; ;AN004;
1163$$IF92:
1164
1165 ret ; ;AN000;
1166
1167 Search_FAT ENDP
1168
1169 BREAK <SYS - Find_Empty_Cluster >
1170;******************* START OF SPECIFICATIONS ***********************************
1171;Routine name: Find_Empty_Cluster
1172;*******************************************************************************
1173;
1174;Description: Find_Empty_Cluster finds the first available empty cluster
1175;
1176;Called Procedures:
1177;
1178; Unpack - find next cluster number
1179;
1180;Input: none
1181;
1182;Output: CF = 0 - empty cluster found (# in [empty_cluster])
1183; CF = 1 - no empty clusters (ax = message)
1184;
1185;Change History: Created 7/01/87 FG
1186;
1187;******************* END OF SPECIFICATIONS *************************************
1188;******************+ START OF PSEUDOCODE +**************************************
1189;
1190; START Find_Empty_Cluster
1191;
1192; search till at end of FAT
1193; call Unpack
1194; exitif cluster is empty (ZF)
1195; save empty cluster number
1196; clear CF
1197; orelse
1198; advance to next cluster
1199; endloop if past last cluster
1200; load ax message # - no room for sys files
1201; set CF
1202; endsrch
1203;
1204; ret
1205;
1206; END Find_Empty_Cluster
1207;
1208;******************- END OF PSEUDOCODE -**************************************
1209
1210 public Find_Empty_Cluster
1211
1212 Find_Empty_Cluster PROC NEAR
1213
1214 mov si,[current_cluster] ; ;AN004;
1215 mov ax,[cluster_count] ; ;AN004;
1216 add si,ax ; look past required space ;AN004;
1217; $search ; till at end of FAT ;AN004;
1218$$DO97:
1219 call Unpack ; to convert # to value ;AN004;
1220; $exitif z ; cluster is empty ;AN004;
1221 JNZ $$IF97
1222 mov [empty_cluster],si ; save it for later ;AN004;
1223 clc ; clear error flag ;AN004;
1224; $orelse ; ;AN004;
1225 JMP SHORT $$SR97
1226$$IF97:
1227 inc si ; advance to next cluster ;AN004;
1228 cmp si,[MCLUS] ; past the end ? ;AN004;
1229; $endloop e ; if past last cluster ;AN004;
1230 JNE $$DO97
1231 stc ; set error flag ;AN004;
1232 mov ax,(util shl 8) + no_room ; error message - no room to sys ;AN014;
1233; $endsrch ; ;AN004;
1234$$SR97:
1235
1236 ret ; ;AN004;
1237
1238 Find_Empty_Cluster ENDP
1239
1240 BREAK <SYS - Xfer_Data >
1241;******************* START OF SPECIFICATIONS ***********************************
1242;Routine name: Xfer_Data
1243;*******************************************************************************
1244;
1245;Description: Xfer_Data moves the data from [cluster_number] into the cluster
1246; number passed in ax.
1247;
1248;Called Procedures:
1249;
1250; Direct_Access - do disk i/o
1251;
1252;Input: [current_cluster]
1253; [empty_cluster]
1254;
1255;Output: CF = 0 - data transfered
1256; CF = 1 - error - message in AX
1257;
1258;Change History: Created 7/01/87 FG
1259;
1260;******************* END OF SPECIFICATIONS *************************************
1261;******************+ START OF PSEUDOCODE +**************************************
1262;
1263; START Xfer_Data
1264;
1265; save active FAT starting sector
1266; set source to first sector of [current_cluster]
1267; set count to # of sectors per cluster
1268; set up for read
1269; call Direct_Access to read data
1270; if no errors
1271; set source to first sector of [empty_cluster]
1272; set up for write
1273; call Direct_Access to write data
1274; endif
1275; restore Fat starting sector
1276; set count to FAT_sectors
1277; set up for read
1278; call Direct_Access to restore the FAT copy
1279;
1280; endif
1281;
1282; ret
1283;
1284; END Xfer_Data
1285;
1286;******************- END OF PSEUDOCODE -**************************************
1287
1288 public Xfer_Data
1289
1290 Xfer_Data PROC NEAR
1291
1292 push [packet] ; save active FAT starting sector ;AN004;
1293 push [packet+2] ; ;AN004;
1294 push [packet_sectors] ; ;AN004;
1295 mov ax,[CSIZE] ; ;AN004;
1296 mov [packet_sectors],ax ; ;AN004;
1297 mov ax,[current_cluster] ; set source to [current_cluster] ;AN004;
1298 call cluster_2_sector ; convert Cluster to sector # ;AN004;
1299 mov [packet],ax ; low sector word ;AN004;
1300 mov [packet+2],dx ; high sector word ;AN004;
1301 xor ah,ah ; set up for read ;AN004;
1302 call Direct_Access ; to read data ;AN004;
1303; $if nc ; no errors ;AN004;
1304 JC $$IF102
1305 mov ax,[empty_cluster] ; set destination to [empty_cluster] ;AN004;
1306 cmp [DIR_cluster],0 ; have we just loaded a directory? ;AN007;
1307; $if ne ; if so - ;AN007;
1308 JE $$IF103
1309 mov [DIR_cluster],ax ; save the new cluster ;AN007;
1310 lea bx,BUF ; ;AN007;
1311 mov [bx.dir_first],ax ; update the '.' entry start cluster ;AN007;
1312; $endif ; ;AN007;
1313$$IF103:
1314 call cluster_2_sector ; conver to logical sector ;AN004;
1315 mov [packet],ax ; low word ;AN004;
1316 mov [packet+2],dx ; high word ;AN004;
1317 xor ah,ah ; set up for write ;AN004;
1318 dec ah ; ;AN004;
1319 call Direct_Access ; to write data ;AN004;
1320; $endif ; ;AN004;
1321$$IF102:
1322 pop [packet_sectors] ; ;AN004;
1323 pop [packet+2] ; restore starting sector ;AN004;
1324 pop [packet] ; ;AN004;
1325 xor ah,ah ; set up for read ;AN004;
1326 call Direct_Access ; to restore the FAT copy ;AN004;
1327
1328 ret ; ;AN004;
1329
1330 Xfer_Data ENDP
1331
1332 BREAK <SYS - cluster_2_sector >
1333;******************* START OF SPECIFICATIONS ***********************************
1334;Routine name: cluster_2_sector
1335;*******************************************************************************
1336;
1337;Description: cluster_2_sector
1338;
1339;
1340;Called Procedures:
1341;
1342; none
1343;
1344;Input: AX - cluster number
1345;
1346;Output: AX - low word of sector
1347; DX - high word of sector
1348; CX - sectors per cluster
1349;
1350;Change History: Created 7/01/87 FG
1351;
1352;******************* END OF SPECIFICATIONS *************************************
1353;******************+ START OF PSEUDOCODE +**************************************
1354;
1355; START cluster_2_sector
1356;
1357; ret
1358;
1359; END cluster_2_sector
1360;
1361;******************- END OF PSEUDOCODE -**************************************
1362
1363 public cluster_2_sector
1364
1365 cluster_2_sector PROC NEAR
1366
1367 dec ax ; of [current_cluster] ;AN004;
1368 dec ax ; ;AN004;
1369 mov cx,[CSIZE] ; ;AN004;
1370 mul cx ; ;AN004;
1371 add ax,[l_sector_offset] ; ;AN004;
1372
1373 ret ; ;AN004;
1374
1375 cluster_2_sector ENDP
1376
1377 BREAK <SYS - Search_DIR >
1378;******************* START OF SPECIFICATIONS ***********************************
1379;Routine name: Search_DIR
1380;*******************************************************************************
1381;
1382;Description: Search_DIR walks the directory tree looking for the file that
1383; starts with [cluster_number]. If found, the data is moved to the
1384; first empty cluster (if available), and the directory entry is
1385; updated.
1386;
1387; This routine walks the DIR tree by creating a 'FRAME' for each
1388; Sub DIR it encounters. It saves all the data needed to continue
1389; the search once the Sub DIR has been checked.
1390;
1391; FRAME ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
1392; ³ present_cluster # ³sector_offset ³ entry_number ³
1393; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
1394; byte 1 2 3 4
1395;
1396; There is space in DIR_BUF for 32 frames (current DOS maximum
1397; level of nesting).
1398;
1399;Called Procedures:
1400;
1401; Search_Loop - scan the directory
1402;
1403;Input: [current_cluster] - # of cluster to be freed
1404;
1405;Output: CF = 0 cluster now available
1406; CF = 1 error - ax = message #
1407;
1408;
1409;Change History: Created 7/01/87 FG
1410;
1411;******************* END OF SPECIFICATIONS *************************************
1412;******************+ START OF PSEUDOCODE +**************************************
1413;
1414; START Search_DIR
1415;
1416; set up for first_dir_sector of root DIR
1417; set up for read
1418; call Direct_Access to read first root sector
1419; if no error
1420; set [current_sector]
1421; set [sector_count] = #_dir_sectors
1422; set [current_entry] = 1
1423; set [sub_dir_level] = 0
1424; do until cluster free (NC)
1425; call Search_Loop
1426; if SubDir
1427; save [current_cluster] in frame
1428; save [current_sector]in frame
1429; save [current_entry] in frame
1430; save [sector_count] in frame
1431; incriment [sub_dir_level] (frame)
1432; zero ax
1433; set error flag (CF)
1434; else
1435; if end of DIR (CF + 00) and
1436; if [dir_count] > 0
1437; recover [current_cluster] from frame
1438; recover [current_sector] from frame
1439; recover [current_entry] from frame
1440; recover [sector_count] from frame
1441; decriment [sub_dir_level]
1442; zero ax
1443; set error flag (CF)
1444; else
1445; load error message - no room to sys
1446; endif
1447; set error flag (CF) (ax = message)
1448; endif
1449; leave if error (ax > 0)
1450; enddo
1451; endif
1452;
1453; ret
1454;
1455; END Search_DIR
1456;
1457;******************- END OF PSEUDOCODE -**************************************
1458
1459 public Search_DIR
1460
1461 Search_DIR PROC NEAR
1462
1463 mov ax,[first_dir_sector] ; set up for first_dir_sector of root ;AN004;
1464 mov [packet],ax ; ;AN004;
1465 mov [packet+2],0 ; zero out high word ;AN004;
1466 mov [packet_sectors],1 ; only process 1 sector at a time ;AN004;
1467 mov [packet_buffer],OFFSET DIR_SECTOR ; ;AN004;
1468 xor ah,ah ; set up for read ;AN004;
1469 call Direct_Access ; to read first root sector ;AN004;
1470; $if nc,long ; no error ;AN004;
1471 JNC $$XL1
1472 JMP $$IF106
1473$$XL1:
1474 xor ax,ax ; ;AN004;
1475 mov [present_cluster],ax ; set [present_cluster] = 0 (root) ;AN004;
1476 mov [entry_number],al ; set [entry_number] = 0 (first) ;AN004;
1477 mov ax,[first_dir_sector] ; ;AN013;
1478 mov [sector_offset],ax ; set [sector_offset] = [first_dir_sec];AC015;
1479 lea bx,DIR_BUF ; set [FRAME_ptr] = DIR_BUF ;AN004;
1480 mov [FRAME_ptr],bx ; ;AN004;
1481; $do ; until cluster free (NC) ;AN004;
1482$$DO107:
1483 call Search_Loop ; ;AN004;
1484; $leave nc,long ; cluster found and moved ;AN004;
1485 JC $$XL2
1486 JMP $$EN107
1487$$XL2:
1488 cmp ax,0ffffh ; ;AN004;
1489; $if e ; SubDir ;AN004;
1490 JNE $$IF109
1491
1492 ; Search DIR returned with BX pointing
1493 ; to the current entry - now update
1494 ; current_cluster to this SubDIRs first
1495 ; cluster
1496
1497 mov ax,[bx.dir_first] ; get starting cluster for where we ;AN007;
1498 ; want to go
1499 mov bx,[present_cluster] ; get [present_cluster] for frame ;AN004;
1500 ; (where we were)
1501 mov [present_cluster],ax ; [present_cluster] for next pass ;AN007;
1502 xchg ax,bx ; recover old [present_cluster] ;AN007;
1503 mov bx,[FRAME_ptr] ; get FRAME pointer ;AN004;
1504 mov [bx.p_cluster],ax ; save [present_cluster] in frame ;AN004;
1505 mov ax,[sector_offset] ; save [sector_offset]in frame ;AC015;
1506 mov [bx.s_offset],ax ; ;AC015;
1507 mov al,[entry_number] ; save [entry_number] in frame ;AN004;
1508 mov [bx.e_number],al ; ;AN004;
1509 xor ax,ax ; reset - ;AN007;
1510 mov [sector_offset],ax ; [sector_offset] ;AC015;
1511 mov [entry_number],al ; [entry_number] ;AN007;
1512 add bx,SIZE FRAME ; incriment FRAME pointer ;AN004;
1513 lea ax,DIR_SECTOR ; ;AN004;
1514 cmp ax,bx ; ;AN004;
1515; $if a ; ;AC007;
1516 JNA $$IF110
1517 mov [FRAME_ptr],bx ; ;AN004;
1518 clc ; no error ;AN004;
1519; $else ; ;AN004;
1520 JMP SHORT $$EN110
1521$$IF110:
1522 stc ; set error flag (CF) ;AN004;
1523; $endif ; ;AN004;
1524$$EN110:
1525; $else long ; ;AN004;
1526 JMP $$EN109
1527$$IF109:
1528 cmp ax,0 ; ;AN004;
1529; $if e,and,long ; end of DIR (CF + 00) and ;AN004;
1530 JE $$XL3
1531 JMP $$IF114
1532$$XL3:
1533next_level_down: ; ;AN004;
1534 mov bx,[FRAME_ptr] ; recover FRAME_ptr - but remember ** ;AC007;
1535 ; it points to the next available
1536 ; frame - not the last one - so
1537 sub bx,SIZE FRAME ; move back! ;AN007;
1538 lea ax,DIR_BUF ; ;AN004;
1539 cmp ax,bx ; ;AN004;
1540; $if be ; as long as there are still FRAMEs ;AC007;
1541 JNBE $$IF114
1542 mov ax,[bx.p_cluster] ; get [present_cluster] from frame ;AN004;
1543 mov [present_cluster],ax ; ;AN004;
1544 mov ax,[bx.s_offset] ; recover [sector_offset] from frame ;AC015;
1545 mov [sector_offset],ax ; ;AC015;
1546 mov al,[bx.e_number] ; recover [entry_number] from frame ;AN004;
1547 mov [entry_number],al ; ;AN004;
1548 mov [FRAME_ptr],bx ; ;AN004;
1549
1550 ; Now set up at exactly same point
1551 ; as when SubDIR was entered -
1552 ; advance to next entry
1553
1554 inc al ; ;AN004;
1555 cmp al,[entries_per_sector] ; ;AN004;
1556; $if b ; ;AN004;
1557 JNB $$IF115
1558 inc [entry_number] ; ;AN004;
1559 clc ; no error ;AN004;
1560; $else ; we've left the sector ;AN004;
1561 JMP SHORT $$EN115
1562$$IF115:
1563if not ibmcopyright
1564 xor al, al
1565 mov [entry_number], al ; shall we start at, say, ENTRY ZERO? Hmmmmm?
1566endif
1567 mov ax,[present_cluster] ; ;AN004;
1568 cmp ax,0 ; in the root ? ;AN004;
1569; $if ne ; no ;AN004;
1570 JE $$IF117
1571 mov si,ax ; ;AN004;
1572 mov [cluster_high],1 ; force Upack to load FAT ;AN004;
1573 mov ax,[FAT_sectors] ; get the size right ;AN004;
1574 mov [packet_sectors],ax ; ;AN004;
1575 mov [packet_buffer],OFFSET BUF ; ;AN004;
1576 call Unpack ; to get next cluster # ;AN004;
1577 mov [packet_buffer],OFFSET DIR_SECTOR ; ;AN004;
1578 mov [packet_sectors],1 ; set size back ;AN004;
1579 mov [cluster_high],1 ; ensure that FAT will be ;AN004;
1580 ; re-loaded
1581
1582 mov ax,di ; check if at end ;AN007;
1583 cmp al,end_cluster ; at the end? ;AN007;
1584; $if nz ; not at end of line ;AN004;
1585 JZ $$IF118
1586 mov [present_cluster],di ; save it ;AN004;
1587 clc ; ;AN004;
1588; $else ; we are at the end of a Sub DIR chain ;AN004;
1589 JMP SHORT $$EN118
1590$$IF118:
1591
1592 ; the following is a best attempt fix
1593 ; to a bad design problem ...... (how
1594 ; to get back a level.....???
1595
1596; SEPT 21 - best solution is to check BEFORE putting the entry in the frame
1597; (not when taking it off !!! )
1598
1599 jmp next_level_down ; ;AN004;
1600
1601; $endif ; ;AN004;
1602$$EN118:
1603; $else ; yes - in the root ;AN004;
1604 JMP SHORT $$EN117
1605$$IF117:
1606 mov ax,[sector_offset] ; ;AC015;
1607 inc ax ; ;AN004;
1608 cmp ax,[l_sector_offset] ; ;AC015;
1609; $if b ; ;AN004;
1610 JNB $$IF122
1611 inc [sector_offset] ; ;AN004;
1612if not ibmcopyright
1613 clc ; no error, continue with loop
1614endif
1615; $else ; end of the line ;AN004;
1616 JMP SHORT $$EN122
1617$$IF122:
1618 stc ; we failed to find it ;AN004;
1619; $endif ; ;AN004;
1620$$EN122:
1621; $endif ; ;AN004;
1622$$EN117:
1623; $endif ; ;AN004;
1624$$EN115:
1625; $else ; ;AN004;
1626 JMP SHORT $$EN114
1627$$IF114:
1628 stc ; set error flag (CF) ;AN004;
1629; $endif ; ;AN004;
1630$$EN114:
1631; $endif ; ;AN004;
1632$$EN109:
1633; $if c ; error ;AN004;
1634 JNC $$IF130
1635 mov ax,(util shl 8) + no_room ; error message - no room to sys ;AN004;
1636; $endif ; ;AN004;
1637$$IF130:
1638; $leave c ; if error ;AN004;
1639 JC $$EN107
1640; $enddo long ; ;AN004;
1641 JMP $$DO107
1642$$EN107:
1643; $endif ; ;AN004;
1644$$IF106:
1645
1646 ret ; ;AN004;
1647
1648 Search_DIR ENDP
1649
1650 BREAK <SYS - Search_Loop >
1651;******************* START OF SPECIFICATIONS ***********************************
1652;Routine name: Search_Loop
1653;*******************************************************************************
1654;
1655;Description: Search_Loop scans through all entries of all sectors of all
1656; clusters of a given Directory for a specified cluster
1657;
1658;Called Procedures:
1659;
1660; Unpack - to find a FAT entry for a Cluster #
1661; Pack - to set a FAT entry for a Cluster #
1662; Find_Empty_Cluster - find an unused cluster
1663; Xfer_Data - transfere data from one cluster to another
1664; Direct_Access - absolute disk i/o
1665;
1666;Input:
1667;
1668;Output: CF = 0 found and freed [cluster_number]
1669; CF = 1 - ax = 0 - at end of directory
1670; ax = (message + class) - error occured
1671; ax = -1 - SubDir found
1672; bx = pointer to current entry
1673;
1674;Change History: Created 7/01/87 FG
1675;
1676;******************* END OF SPECIFICATIONS *************************************
1677;******************+ START OF PSEUDOCODE +**************************************
1678;
1679; START Search_Loop
1680;
1681; search till at end of directory - all clusters checked
1682; search till at end of sectors - in given cluster
1683; search till at end of sector - all entries checked
1684; exitif starting cluster = [cluster_number]
1685; set up for FAT
1686; call Find_Empty_Cluster
1687; if no error and
1688; call Xfer_Data
1689; reset for DIR
1690; if no error
1691; update dir_first_clust
1692; set up for write
1693; call Direct_Access to write out the directory
1694; endif
1695; orelse
1696; leave if entry is a subdirectory (ah = ffh)
1697; advace to next entry
1698; zero ax
1699; endloop if past end of sector
1700; set fail flag (CF)
1701; endsrch
1702; exit if [current_cluster] found (NC)
1703; orelse
1704; leave if subdirectory found (CF + FF)
1705; if sectors left to read
1706; set up to read
1707; call Direct_Access to read sector
1708; else
1709; set error flag (CF)
1710; zero ax (end of sectors)
1711; endif
1712; endloop if error
1713; endsrch
1714; leave if [current_cluster] found (NC)
1715; leave if SubDir found (CF + FF)
1716; leave if Error (CF + message)
1717; get [current_cluster] #
1718; call Unpack to get next cluster #
1719; exitif no more clusters
1720; zero ax (end of clusters)
1721; set error flag (CF)
1722; orelse
1723; convert cluster # to logical sector #
1724; update [current_sector]
1725; endloop
1726; endsrch
1727;
1728; ret
1729;
1730; END Search_Loop
1731;
1732;******************- END OF PSEUDOCODE -**************************************
1733
1734 public Search_Loop
1735
1736 Search_Loop PROC NEAR
1737
1738 mov ax,[present_cluster] ; initailize for search ;AN004;
1739 cmp ax,0 ; ;AN004;
1740; $if ne ; ;AN004;
1741 JE $$IF135
1742 call cluster_2_sector ; convert it to a sector ;AN004;
1743 add ax,[sector_offset] ; ;AC015;
1744; $if c ; ;AN004;
1745 JNC $$IF136
1746 inc dx ; ;AN004;
1747; $endif ; ;AN004;
1748$$IF136:
1749; $else ; ;AN004;
1750 JMP SHORT $$EN135
1751$$IF135:
1752 mov ax,[sector_offset] ;[sector_offset] = current root sector ;AC015;
1753 xor dx,dx ; ;AN004;
1754; $endif ; ;AN004;
1755$$EN135:
1756 mov [packet],ax ; ;AN004;
1757 mov [packet+2],dx ; ;AN004;
1758 xor ah,ah ; ;AN004;
1759 call Direct_Access ; to read the DIR ;AN004;
1760 mov al,SIZE dir_entry ; ;AN004;
1761 mov cl,[entry_number] ; ;AN004;
1762 mul cl ; ;AN004;
1763 lea bx,DIR_SECTOR ; ;AN004;
1764 add bx,ax ; BX now points to the DIR entry ;AN004;
1765; $search ; till at end of directory ;AN004;
1766$$DO140:
1767 ; - all clusters checked
1768; $search ; till at end of sectors ;AN004;
1769$$DO141:
1770 ; - in given cluster
1771; $search ; till at end of sector ;AN004;
1772$$DO142:
1773 ; - all entries checked
1774 cmp BYTE PTR [bx],deleted ; make sure the entry is valid !!! ;AN019;
1775; $if e ; if it is not - ;AN019;
1776 JNE $$IF143
1777 xor ax,ax ; ;AN019:
1778 mov [bx.dir_first],ax ; zap the starting cluster ;AN019;
1779 mov [bx.dir_attr],al ; zap the attribute ;AN019;
1780; $endif ; ;AN019;
1781$$IF143:
1782 mov ax,[bx.dir_first] ; ;AN004;
1783 cmp ax,[current_cluster] ; ;AN004;
1784; $exitif e,and,long ; starting cluster = [current_cluster] ;AN004;
1785 JE $$XL4
1786 JMP $$IF142
1787$$XL4:
1788 cmp BYTE PTR [bx],deleted ; make sure the entry is valid !!! ;AN007;
1789; $exitif ne,and,long ; and entry is not deleted ;AN007;
1790 JNE $$XL5
1791 JMP $$IF142
1792$$XL5:
1793 cmp BYTE PTR [bx],dot ; ;AN007;
1794; $exitif ne,long ; and entry is not a . or .. name ;AN007;
1795 JNE $$XL6
1796 JMP $$IF142
1797$$XL6:
1798 test [bx.dir_attr],attr_directory ; is it a subdir ? ;AN007;
1799; $if nz ;if entry is a subdirectory ;AN007;
1800 JZ $$IF146
1801 inc [DIR_cluster] ; signal special processing ;AN007;
1802 ; Xfere_Data will use this later -
1803 ; 0 = not a sub DIR
1804 ; 1 = do Sub DIR processing and
1805 ; update [DIR_cluster] to the
1806 ; same value as [empty_cluster]
1807; $endif ; ;AN007;
1808$$IF146:
1809 mov ax,[packet] ; save pointer to this DIR ;AN007;
1810 mov [dir_sector_low],ax ; ;AN007;
1811 mov ax,[packet+2] ; ;AN007;
1812 mov [dir_sector_hi],ax ; ;AN007;
1813 mov [source_ptr],bx ; save pointer ;AN004;
1814 mov [cluster_high],1 ; force Upack to load FAT ;AN004;
1815 mov ax,[FAT_sectors] ; get the size right ;AN004;
1816 mov [packet_sectors],ax ; ;AN004;
1817 mov [packet],1 ; ;AN004;
1818 mov [packet+2],0 ; ;AN004;
1819 mov [packet_buffer],OFFSET BUF ; ;AN004;
1820 call Find_Empty_Cluster ; ;AN004;
1821; $if nc,and ; no errors so far ;AN004;
1822 JC $$IF148
1823 mov si,[empty_cluster] ; ;AN004;
1824 mov dx,[next_cluster] ; ;AN004;
1825 call PACK ; ;AN004;
1826; $if nc,and ; no errors so far ;AN004;
1827 JC $$IF148
1828 mov si,[current_cluster] ; ;AN004;
1829 xor dx,dx ; make it empty ;AN004;
1830 call PACK ; ;AN004;
1831; $if nc ; no errors so far ;AN004;
1832 JC $$IF148
1833 cmp [bigfat],0 ; ;AN004;
1834; $if ne ; ;AN004;
1835 JE $$IF149
1836 mov [cluster_high],1 ; ensure that FAT will be updated ;AN004;
1837 call Unpack ; ;AN004;
1838; $else ; must manualy write out 12 bit FATS ;AN004;
1839 JMP SHORT $$EN149
1840$$IF149:
1841 xor ah,ah ; ;AN004;
1842 dec ah ; ;AN004;
1843 mov [packet],1 ; start with the first FAT ;AN004;
1844 call Direct_Access ; write it out - ignore errors ;AN004;
1845 mov ax,[FSIZE] ; ;AN004;
1846 add [packet],ax ; advance to second FAT ;AN004;
1847 xor ah,ah ; ;AN004;
1848 dec ah ; ;AN004;
1849 call Direct_Access ; write it out - ignore errors ;AN004;
1850; $endif ; ;AN004;
1851$$EN149:
1852; $endif ; ;AN004;
1853$$IF148:
1854; $if nc,and ; no error and ;AN004;
1855 JC $$IF153
1856 call Xfer_Data ; ;AN004;
1857; $if nc ; no error ;AN004;
1858 JC $$IF153
1859 mov ax,[empty_cluster] ; update dir_first_clust ;AN004;
1860 mov bx,[source_ptr] ; recover pointer ;AN004;
1861 mov [bx.dir_first],ax ; ;AN004;
1862 mov [packet_sectors],1 ; set size back ;AN004;
1863 mov [packet_buffer],OFFSET DIR_SECTOR ; ;AN004;
1864 mov ax,[dir_sector_low] ; reset DIR sector ;AN007;
1865 mov [packet],ax ; ;AN007;
1866 mov ax,[dir_sector_hi] ; ;AN007;
1867 mov [packet+2],ax ; ;AN007;
1868 xor ah,ah ; set up for write ;AN004;
1869 dec ah ; ;AN004;
1870 call Direct_Access ; to write out the directory ;AN004;
1871; $if nc,and ; ;AN004;
1872 JC $$IF154
1873 cmp [DIR_cluster],0 ; is a DIR being processed ? ;AN007;
1874; $if ne ; ;AN007;
1875 JE $$IF154
1876 call Sub_DIR_Loop ; update any children ;AN007;
1877; $endif ; ;AN007;
1878$$IF154:
1879; $if nc ; if no errors ;AN007;
1880 JC $$IF156
1881 mov ax,[FAT_sectors] ;only read needed sectors ;AN004;
1882 mov [packet_sectors],ax ; ;AN004;
1883 mov [packet],1 ; ;AN004;
1884 mov [packet_buffer],OFFSET BUF ; point to FAT buffer ;AN004;
1885 mov [cluster_high],clusters_loaded ; ;AN004;
1886 mov [cluster_low],0 ; ;AN004;
1887 xor cx,cx ; ;AN004;
1888 mov di,cx ; ;AN004;
1889 dec di ; ;AN004;
1890 mov cl,[num_of_FATS] ; ;AN004;
1891 ; ;AN004;
1892 call Load_FAT ; restore FAT ;AN004;
1893 ; ;AN004;
1894 push es ; update DPB first cluster ;AN004;
1895 mov bx,ds ; ;AN004;
1896 mov es,bx ; ;AN004;
1897 lds bx,[THIS_DPB] ; ;AN004;
1898
1899 ASSUME ds:nothing,es:DATA
1900
1901 mov [bx.dpb_next_free],2 ; ;AN004;
1902 mov ax,es ; ;AN004;
1903 mov ds,ax ; ;AN004;
1904 pop es ; ;AN004;
1905
1906 ASSUME DS:data, es:nothing
1907
1908; $endif ; ;AN004;
1909$$IF156:
1910; $endif ; ;AN004;
1911$$IF153:
1912; $orelse ; ;AN004;
1913 JMP SHORT $$SR142
1914$$IF142:
1915 xor ax,ax ; get ready in case ----- ;AN007;
1916 cmp BYTE PTR [bx],0 ; at the end of the dir? ;AN007;
1917; $leave e ; then no point in continuing ;AN007;
1918 JE $$EN142
1919 dec ax ; get ready in case we fail ;AN004;
1920 test [bx.dir_attr],attr_directory ; is it a subdir ? ;AN004;
1921; $leave nz, and ;if entry is a subdirectory (ah = ffh) ;AN004;
1922 JZ $$LL161
1923 cmp byte ptr [bx],dot ; but not a DOT ;AN007;
1924; $leave ne ; ;AN007;
1925 JNE $$EN142
1926$$LL161:
1927 xor ax,ax ; zero ax ;AN004;
1928 add bx,SIZE dir_entry ; advace to next entry ;AN004;
1929 inc [entry_number] ; ;AN004;
1930 cmp bx,OFFSET BUF ; are we out of sector ? ;AN004;
1931; $endloop ae,long ;if past end of sector ;AN004;
1932 JAE $$XL7
1933 JMP $$DO142
1934$$XL7:
1935$$EN142:
1936 stc ; set fail flag (CF) ;AN004;
1937; $endsrch ; ;AN004;
1938$$SR142:
1939; $exitif nc ;[current_cluster] found (NC) ;AN004;
1940 JC $$IF141
1941; $orelse ; ;AN004;
1942 JMP SHORT $$SR141
1943$$IF141:
1944
1945 ; we have CF = 1 and could have:
1946 ; AX = 0 -
1947 ; AX = 1 to fffe
1948 ; AX = ffff
1949 ; so - leave if anything other than
1950 ; AX = 0 (out of stuff)
1951
1952; $leave c,and ; if not out of stuff ;AN004;
1953 JNC $$LL166
1954 cmp ax,0 ; ;AN009;
1955 stc ; restore carry flag! ;AN007;
1956; $leave nz ; ------ leave ! ;AN009;
1957 JNZ $$EN141
1958$$LL166:
1959 mov ax,[sector_offset] ; ;AC015;
1960 inc ax ; ;AN004;
1961 cmp [present_cluster],0 ; are we in the root? ;AN007;
1962; $if e ; if so - ;AN004;
1963 JNE $$IF167
1964 cmp ax,[l_sector_offset] ; use root sectors ;AC013;
1965; $else ; else - ;AN004;
1966 JMP SHORT $$EN167
1967$$IF167:
1968 cmp ax,[CSIZE] ; use sectors per cluster ;AN004;
1969; $endif ; ;AN004;
1970$$EN167:
1971; $if b ; sectors left to read ;AN004;
1972 JNB $$IF170
1973 add [packet],1 ; advance to the next sector ;AN004;
1974; $if c ; ;AN004;
1975 JNC $$IF171
1976 inc [packet+2] ; adjust high word if needed ;AN004;
1977; $endif ; ;AN004;
1978$$IF171:
1979 xor ah,ah ; set up to read ;AN004;
1980 mov [entry_number],ah ; ;AN004;
1981 inc [sector_offset] ; ;AN004;
1982 call Direct_Access ; to read sector ;AN004;
1983 lea bx,DIR_SECTOR ; set index to start of sector ;AN004;
1984; $else ; ;AN004;
1985 JMP SHORT $$EN170
1986$$IF170:
1987 xor ax,ax ; zero ax (end of sectors) ;AN004;
1988 stc ; set error flag (CF) ;AN004;
1989; $endif ; ;AN004;
1990$$EN170:
1991; $endloop c,long ; if error ;AN004;
1992 JC $$XL8
1993 JMP $$DO141
1994$$XL8:
1995$$EN141:
1996; $endsrch ; ;AN004;
1997$$SR141:
1998; $leave nc ; if [current_cluster] found (NC) ;AN004;
1999 JNC $$EN140
2000; $leave c,and ;if SubDir found (CF + FF) ;AN004;
2001 JNC $$LL178
2002 cmp ax,0 ; ;AN004;
2003 stc ; set carry ;AN007;
2004; $leave nz ; if Error (CF + messageor FFFFh) ;AN004;
2005 JNZ $$EN140
2006$$LL178:
2007
2008 ;--------------------------------------
2009 ; CF = 1 and AX = 0 means - no critical
2010 ; errors
2011 ; - no Sub DIR
2012 ; found
2013 ; inner SEARCH is out of sectors
2014 ; - so advance to the next cluster
2015 ;--------------------------------------
2016 mov si,[present_cluster] ; get [present_cluster] # ;AN004;
2017 cmp si,0 ; end of the root ? ;AN004;
2018; $if nz ; ;AN004;
2019 JZ $$IF179
2020 mov [cluster_high],1 ; force Upack to load FAT ;AN004;
2021 mov ax,FAT_sectors ; get the size right ;AN004;
2022 mov [packet_sectors],ax ; ;AN004;
2023 mov [packet_buffer],OFFSET BUF ; ;AN004;
2024 call Unpack ; to get next cluster # ;AN004;
2025 mov [packet_sectors],1 ; set size back ;AN004;
2026 mov [cluster_high],1 ; ensure that FAT will be re-loaded ;AN004;
2027 mov [packet_buffer],OFFSET DIR_SECTOR ; ;AN004;
2028 mov ax,di ; ;AN007;
2029 cmp al,end_cluster ; ;AN007;
2030; $endif ; ;AN004;
2031$$IF179:
2032; $exitif z ; no more clusters ;AN004;
2033 JNZ $$IF140
2034 xor ax,ax ; zero ax (end of clusters) ;AN004;
2035 stc ; set error flag (CF) ;AN004;
2036; $orelse ; ;AN004;
2037 JMP SHORT $$SR140
2038$$IF140:
2039 mov [present_cluster],di ; ;AN004;
2040 mov ax,di ; set up for cluster_2_sector ;AN004;
2041 call cluster_2_sector ; convert cluster # to logical sector #;AN004;
2042 mov [packet],ax ; ;AN004;
2043 mov [packet+2],dx ; ;AN004;
2044 xor ax,ax ; ;AN004;
2045 mov [sector_offset],ax ; reset [sector_offset] ;AC015;
2046 mov [entry_number],ah ; reset [entry_number] ;AN004;
2047 call Direct_Access ; to read sector ;AN004;
2048 lea bx,DIR_SECTOR ; set pointer ;AN004;
2049; $endloop c,long ; end loop if read fails ;AN004;
2050 JC $$XL9
2051 JMP $$DO140
2052$$XL9:
2053$$EN140:
2054; $endsrch ; ;AN004;
2055$$SR140:
2056
2057 ret ; ;AN004;
2058
2059 Search_Loop ENDP
2060
2061 BREAK <SYS - Sub_DIR_Loop >
2062
2063;******************* START OF SPECIFICATIONS ***********************************
2064;Routine name: Sub_DIR_Loop
2065;*******************************************************************************
2066;
2067;Description: Sub_DIR_Loop scans through all entries of a subdirectory looking
2068; child subdirectories. If found, their parent [dir_first] entries
2069; (the .. entry) are updated to point to the correct cluster
2070;
2071;Called Procedures:
2072;
2073; Unpack - to find a FAT entry for a Cluster #
2074; Direct_Access - absolute disk i/o
2075;
2076;Input: [empty_cluster] - new parent Sub DIR cluster #
2077; [DIR_cluster] - current cluster of DIR being looped
2078;
2079;Output: CF = 0 at end of directory
2080; CF = 1 a read/write error occured
2081;
2082;Change History: Created 10/07/87 FG
2083;
2084;******************* END OF SPECIFICATIONS *************************************
2085;******************+ START OF PSEUDOCODE +**************************************
2086;
2087; START Sub_DIR _Loop
2088;
2089; get DIR_cluster
2090; call cluster_2_sector
2091; update packet
2092; set for read
2093; reset entry pointer
2094; reset sector count
2095; call Direct_Access
2096; if no error
2097; search till at end of directory - all clusters checked
2098; search till at end of sectors - in given cluster
2099; search till at end of sector - all entries checked
2100; leave if null entry
2101; if entry is not deleted and
2102; if this entry is a subdir and
2103; if this is a true entry and
2104; save current sector
2105; save current entry
2106; get start cluster
2107; call cluster_2_sector
2108; set for read
2109; call Direct_Access
2110; if no errors and
2111; update pointer to parent
2112; set for write
2113; call Direct_Access
2114; if no errors and
2115; recover current sector
2116; recover current entry
2117; if no errors
2118; call Direct_Access
2119; endif
2120; exitif error (CF)
2121; orelse
2122; advance to next entry
2123; endloop if past end of sector
2124; clear error flag
2125; endsrch
2126; leave if error
2127; advance to next sector (packet)
2128; incriment sector count
2129; exitif past end of cluster
2130; clear error flag
2131; orelse
2132; reset entry pointer
2133; set for read
2134; call Direct_Access
2135; endloop if error
2136; endsrch
2137; leave if error
2138; get DIR_cluster
2139; call UNPACK to find next Sub DIR cluster
2140; exitif at end of chain
2141; clear error flag
2142; orelse
2143; update DIR_cluster
2144; call cluster_2_sector
2145; update packet
2146; set for read
2147; call Direct_Access
2148; leave if error
2149; reset entry pointer
2150; reset sector count
2151; endloop
2152; endsrch
2153; endif
2154; reset Sub_DIR_cluster to 0
2155;
2156; ret
2157;
2158; END Sub_DIR_Loop
2159;
2160;******************- END OF PSEUDOCODE -**************************************
2161
2162 public Sub_DIR_Loop
2163
2164 Sub_DIR_Loop PROC NEAR
2165
2166 mov ax,[DIR_cluster] ; get DIR_cluster ;AN007;
2167 call cluster_2_sector ; to convert to a logical sector ;AN007;
2168 mov [packet],ax ; update packet ;AN007;
2169 mov [packet+2],dx ; ;AN007;
2170 xor ax,ax ; set for read ;AN007;
2171 call Direct_Access ; to read the first sector of the DIR ;AN007;
2172; $if nc,long ; if no error ;AN007;
2173 JNC $$XL10
2174 JMP $$IF185
2175$$XL10:
2176 mov [sector_count],1 ; reset sector count ;AN007;
2177 lea bx,DIR_SECTOR ; reset entry pointer ;AN007;
2178; $search ; till at end of directory ;AN007;
2179$$DO186:
2180 ; - all clusters checked ;AN007;
2181; $search ; till at end of sectors ;AN007;
2182$$DO187:
2183 ; - in given cluster ;AN007;
2184; $search ; till at end of sector ;AN007;
2185$$DO188:
2186 ; - all entries checked ;AN007;
2187 mov [dir_offset],bx ; reset entry pointer ;AN007;
2188 cmp BYTE PTR [bx],0 ; null entry (00)? ;AN007;
2189; $leave z ; if null entry ;AN007;
2190 JZ $$EN188
2191 cmp BYTE PTR [bx],deleted ; deleted entry (E5)? ;AN007;
2192; $if ne,and ; if entry is not deleted and ;AN007;
2193 JE $$IF190
2194 test [bx.dir_attr],attr_directory ; is it a subdir ? ;AN007;
2195; $if nz,and ; if this entry is a subdir and ;AN007;
2196 JZ $$IF190
2197 cmp BYTE PTR [bx],dot ; dot entry (2E)? ;AN007;
2198; $if ne,and ; this is a true entry and ;AN007;
2199 JE $$IF190
2200 mov ax,[packet] ; save current sector ;AN007;
2201 mov [dir_sector_low],ax ; ;AN007;
2202 mov ax,[packet+2] ; ;AN007;
2203 mov [dir_sector_hi],ax ; ;AN007;
2204 mov ax,[bx.dir_first] ; get start cluster ;AN007;
2205 call cluster_2_sector ; convert to sector ;AN007;
2206 mov [packet],ax ; update packet ;AN007;
2207 mov [packet+2],dx ; ;AN007;
2208 xor ax,ax ; set for read ;AN007;
2209 call Direct_Access ; to read it in ;AN007;
2210; $if nc,and ; no errors and ;AN007;
2211 JC $$IF190
2212 mov ax,[empty_cluster] ; update pointer to parent ;AN007;
2213 lea bx,DIR_SECTOR ; ;AN007;
2214 mov [bx + dir_first + size dir_entry],ax ; ;AN007;
2215 xor ax,ax ; set for write ;AN007;
2216 dec ax ; ;AN007;
2217 call Direct_Access ; to write it back ;AN007;
2218; $if nc,and ; if no errors and ;AN007;
2219 JC $$IF190
2220 mov ax,[dir_sector_low] ; ;AN007;
2221 mov [packet],ax ; recover current sector ;AN007;
2222 mov ax,[dir_sector_hi] ; ;AN007;
2223 mov [packet+2],ax ; ;AN007;
2224; $if nc ; if no errors ;AN007;
2225 JC $$IF190
2226 call Direct_Access ; to continue where we left off ;AN007;
2227; $endif ; ;AN007;
2228$$IF190:
2229; $exitif c ; quit if error (CF) ;AN007;
2230 JNC $$IF188
2231; $orelse ; ;AN007;
2232 JMP SHORT $$SR188
2233$$IF188:
2234 mov bx,[dir_offset] ; recover current entry ;AN007;
2235 add bx,SIZE dir_entry ; advance to next entry ;AN007;
2236 cmp bx,OFFSET BUF ; ;AN007;
2237; $endloop a ; if past end of sector ;AN007;
2238 JNA $$DO188
2239$$EN188:
2240 clc ; clear error flag ;AN007;
2241; $endsrch ; ;AN007;
2242$$SR188:
2243; $leave c ; if error - quit ;AN007;
2244 JC $$EN187
2245 xor ax,ax ; ;AN007;
2246 mov ax,[CSIZE] ; incriment sector count ;AN007;
2247 inc [sector_count] ; ;AN007;
2248 cmp [sector_count],al ; ;AN007;
2249; $exitif a ; past end of cluster ;AN007;
2250 JNA $$IF187
2251 clc ; clear error flag ;AN007;
2252 mov [sector_count],1 ; reset sector count ;AN007;
2253; $orelse ; ;AN007;
2254 JMP SHORT $$SR187
2255$$IF187:
2256 xor ax,ax ; set for read ;AN007;
2257 add WORD PTR [packet],1 ; advance to next sector (packet) ;AN007;
2258 adc [packet+2],ax ; look after carry ;AN007;
2259 call Direct_Access ; to read in next sector ;AN007;
2260 lea bx,DIR_SECTOR ; reset entry pointer ;AN007;
2261; $endloop c,long ; if error - quit ;AN007;
2262 JC $$XL11
2263 JMP $$DO187
2264$$XL11:
2265$$EN187:
2266; $endsrch ; ;AN007;
2267$$SR187:
2268; $leave c ; if error - quit ;AN007;
2269 JC $$EN186
2270 mov si,[DIR_cluster] ; get DIR_cluster ;AN007;
2271 push [packet_sectors] ; save current packet stuff ;AN007;
2272 push [packet_buffer] ; ;AN007;
2273 mov ax,[FAT_sectors] ; update packet to FAT ;AN007;
2274 mov [packet_sectors],ax ; ;AN007;
2275 mov [packet_buffer],OFFSET BUF ; ;AN007;
2276 mov [cluster_high],1 ; force FAT to be reloaded - if needed ;AN007;
2277 call UNPACK ; to find next Sub DIR cluster ;AN007;
2278 pop [packet_buffer] ; recover packet to DIR ;AN007;
2279 pop [packet_sectors] ; ;AN007;
2280 mov ax,di ; ;AN007;
2281 cmp al,end_cluster ; ;AN007;
2282; $exitif e ; at end of chain ;AN007;
2283 JNE $$IF186
2284 clc ; clear error flag ;AN007;
2285; $orelse ; ;AN007;
2286 JMP SHORT $$SR186
2287$$IF186:
2288 mov [DIR_cluster],ax ; ;AN007;
2289 call cluster_2_sector ; to convert to sector ;AN007;
2290 mov [packet],ax ; update packet ;AN007;
2291 mov [packet+2],dx ; ;AN007;
2292 xor ax,ax ; set for read ;AN007;
2293 call Direct_Access ; to read first sector of next cluster ;AN007;
2294; $leave c ; if error ;AN007;
2295 JC $$EN186
2296 lea bx,DIR_SECTOR ; reset entry pointer ;AN007;
2297 mov [sector_count],1 ; reset sector count ;AN007;
2298; $endloop long ; ;AN007;
2299 JMP $$DO186
2300$$EN186:
2301; $endsrch ; ;AN007;
2302$$SR186:
2303; $endif ; ;AN007;
2304$$IF185:
2305 mov [DIR_cluster],0 ; reset Sub_DIR_cluster to 0 ;AN007;
2306
2307 ret ; ;AN007;
2308
2309 Sub_DIR_Loop ENDP
2310
2311 BREAK <SYS - Unpack >
2312;******************* START OF SPECIFICATIONS ***********************************
2313;Routine name: Unpack
2314;*******************************************************************************
2315;
2316;Description: Read an entry in the FAT
2317;
2318;Called Procedures:
2319;
2320; Check_FAT - to make sure right part of FAT is loaded (16 bit only)
2321;
2322;Input: Cluster number in SI
2323;
2324;Output: Return contents in DI
2325; xX destroyed
2326; ZF set if cluster is free
2327;
2328;Change History: Created 7/01/87 FG
2329;
2330;******************* END OF SPECIFICATIONS *************************************
2331;******************+ START OF PSEUDOCODE +**************************************
2332;
2333; START Unpack
2334;
2335; if 16 bit FAT
2336; call Check_FAT
2337; multiply # by 2
2338; read value
2339; check if empty
2340; else
2341; multiply # by 2
2342; read value
2343; if not word alligned
2344; shift to allign
2345; endif
2346; mask off unused portion (set ZF if empty)
2347; endif
2348;
2349; ret
2350;
2351; END Unpack
2352;
2353;******************- END OF PSEUDOCODE -**************************************
2354
2355 public Unpack
2356
2357 Unpack PROC NEAR
2358
2359 lea bx,BUF ; ;AN004;
2360 mov di,si ; ;AN004;
2361 cmp [BIGFAT],0 ; ;AN004;
2362; $if nz ; if 16 bit FAT ;AN004;
2363 JZ $$IF208
2364 push si ; ;AN004;
2365 call Check_FAT ; make sure right part of FAT loaded ;AN004;
2366; $if nc ; ;AN004;
2367 JC $$IF209
2368 mov di,si ; Check_FAT ajusts si ;AN004;
2369 shl di,1 ; Mult by 2 ;AN004;
2370 mov di,WORD PTR [di+bx] ; ;AN004;
2371 or di,di ; Set zero ;AN004;
2372 clc ; ;AN004;
2373; $endif ; ;AN004;
2374$$IF209:
2375 pop si ; ;AN004;
2376; $else ; is 12 bit fat ;AN004;
2377 JMP SHORT $$EN208
2378$$IF208:
2379 shr di,1 ; ;AN004;
2380 add di,si ; Mult by 1.5 ;AN004;
2381 mov di,WORD PTR [di+bx] ; ;AN004;
2382 test si,1 ; ;AN004;
2383; $if nz ; not allign on cluster ;AN004;
2384 JZ $$IF212
2385 shr di,1 ; ;AN004;
2386 shr di,1 ; ;AN004;
2387 shr di,1 ; ;AN004;
2388 shr di,1 ; ;AN004;
2389; $endif ; ;AN004;
2390$$IF212:
2391 and di,0FFFh ; ;AN004;
2392; $endif ; ;AN004;
2393$$EN208:
2394
2395
2396 ret ; ;AN004;
2397
2398 Unpack ENDP
2399
2400 BREAK <SYS - Pack >
2401;******************* START OF SPECIFICATIONS ***********************************
2402;Routine name: Pack
2403;*******************************************************************************
2404;
2405;Description: Change an entry in the FAT
2406;
2407;Called Procedures:
2408;
2409; Check_FAT - to make sure right part of FAT is loaded (16 bit only)
2410;
2411;Input: si - cluster number to be packed
2412; dx - data to be placed in cluster (si)
2413;
2414;Output: bx,dx destroyed
2415;
2416;Change History: Created 7/01/87 FG
2417;
2418;******************* END OF SPECIFICATIONS *************************************
2419;******************+ START OF PSEUDOCODE +**************************************
2420;
2421; START Pack
2422;
2423; if 16 bit FAT
2424; call Check_FAT
2425; convert cluster # to offset
2426; add offset of FAT
2427; store value
2428; else
2429; convert cluster # to offset
2430; add offset of FAT
2431; recover current entry word
2432; if not alligned on word boundary
2433; shift to allign
2434; mask off value to be replaced (byte)
2435; else
2436; mask off value to be replaced (word)
2437; endif
2438; combine new value and ballace
2439; store the entry
2440;
2441; ret
2442;
2443; END Pack
2444;
2445;******************- END OF PSEUDOCODE -**************************************
2446
2447 public Pack
2448
2449 Pack PROC NEAR
2450
2451 lea bx,BUF ; ;AN004;
2452 push si ; ;AN004;
2453 mov di,si ; ;AN004;
2454 cmp [BIGFAT],0 ; ;AN004;
2455; $if nz ; 16 bit FAT ;AN004;
2456 JZ $$IF215
2457 call Check_FAT ; make sure the part of the FAT we want;AN004;
2458 ; is loaded & ajust offset to match ;AN004;
2459 shl si,1 ; convert cluster # to offset ;AN004;
2460 add si,bx ; add offset of FAT ;AN004;
2461 mov [si],dx ; store value ;AN004;
2462 mov [FAT_changed],1 ; the fat has been changed ;AN004;
2463; $else ; its 12 bit FAT ;AN004;
2464 JMP SHORT $$EN215
2465$$IF215:
2466 shr si,1 ; ;AN004;
2467 add si,bx ; ;AN004;
2468 add si,di ; ;AN004;
2469 shr di,1 ; ;AN004;
2470 mov di,[si] ; ;AN004;
2471; $if c ; no alligned ;AN004;
2472 JNC $$IF217
2473 shl dx,1 ; ;AN004;
2474 shl dx,1 ; ;AN004;
2475 shl dx,1 ; ;AN004;
2476 shl dx,1 ; ;AN004;
2477 and di,0Fh ; ;AN004;
2478; $else ; ;AN004;
2479 JMP SHORT $$EN217
2480$$IF217:
2481 and di,0F000h ; ;AN004;
2482; $endif ; ;AN004;
2483$$EN217:
2484 or di,dx ; ;AN004;
2485 mov [si],di ; ;AN004;
2486; $endif ; ;AN004;
2487$$EN215:
2488 pop si ; ;AN004;
2489
2490 ret ; ;AN004;
2491
2492 Pack ENDP
2493
2494 BREAK <SYS - Check_FAT >
2495;******************* START OF SPECIFICATIONS ***********************************
2496;Routine name: Check_FAT
2497;*******************************************************************************
2498;
2499;Description: Check that the protion of the FAT that is referenced in SI
2500; is presently in memory.
2501;
2502; Only 12 sectors of the FAT are kept in memory. If the requested
2503; cluster does not fall within that range, 12 sectors of the FAT
2504; are read into memory - the first cluster will contain the entry
2505; of interest.
2506;
2507;Called Procedures:
2508;
2509; none
2510;
2511;Input: si - cluster number to be checked
2512; [FAT_changed] = 0 - no need to write out FAT before changing
2513; = x - must write before reading.
2514;
2515;
2516;Output: appropriate block of FAT in BUF
2517; si ajusted to match
2518; NB: BX, DX preserved (for UNPACK)
2519;
2520;Change History: Created 7/01/87 FG
2521;
2522;******************* END OF SPECIFICATIONS *************************************
2523;******************+ START OF PSEUDOCODE +**************************************
2524;
2525; START Check_FAT
2526;
2527;
2528; ret
2529;
2530; END Check_FAT
2531;
2532;******************- END OF PSEUDOCODE -**************************************
2533
2534 public Check_FAT
2535
2536 Check_FAT PROC NEAR
2537
2538 push bx
2539 cmp si,[cluster_low] ; ;AN004;
2540; $if ae,and ; ;AN004;
2541 JNAE $$IF221
2542 cmp si,[cluster_high] ; ;AN004;
2543; $if be ; ;AN004;
2544 JNBE $$IF221
2545 sub si,[cluster_low] ; ;AN004;
2546; $else ; the cluster is outside the range
2547 JMP SHORT $$EN221
2548$$IF221:
2549 ; of the part of the FAT presently loaded.
2550 ; convert cluster # into sector + offset
2551 ; by dividing the cluster # by # of entries
2552 ; per sector IE: sector = 512 bytes
2553 ; cluster entry = 2 bytes
2554 ; then # of entries/sector = 256
2555
2556 cmp [FAT_changed],0 ; ;AN004;
2557; $if ne ; ;AN004;
2558 JE $$IF223
2559 xor ah,ah ; ;AN004;
2560 dec ah ; ;AN004;
2561 call Direct_Access ; write it out - ignore errors ;AN004;
2562 mov ax,[FSIZE] ; ;AN004;
2563 cmp [FAT_2],0 ; ;AN004;
2564; $if e ; ;AN004;
2565 JNE $$IF224
2566 add [packet],ax ; ;AN004;
2567; $else ; ;AN004;
2568 JMP SHORT $$EN224
2569$$IF224:
2570 sub [packet],ax ; ;AN004;
2571 mov [FAT_2],0 ; packet points to FAT #2 ;AN004;
2572; $endif ; ;AN004;
2573$$EN224:
2574 xor ah,ah ; ;AN004;
2575 dec ah ; ;AN004;
2576 call Direct_Access ; write it out - ignore errors ;AN004;
2577 mov [FAT_changed],0 ; FAT now cleared ;AN004;
2578; $endif ; ;AN004;
2579$$IF223:
2580 mov ax,si ; ;AN004;
2581 xor cx,cx ; ;AN004;
2582 mov cl,al ; this is a cheap and ;AN004;
2583 mov al,ah ; dirty divide by 256 ;AN004;
2584 xor ah,ah ; ax = result ;AN004;
2585 push ax ; save starting sector ;AN006;
2586 mov si,cx ; cx = remainder ;AN004;
2587 inc ax ; leave room for boot sector ;AN004;
2588 mov [packet],ax ; ;AN004;
2589 mov [packet+2],0 ; ;AN004;
2590 push dx ; ;AN004;
2591 call Direct_Access ; ;AN004;
2592; $if c ; ;AN004;
2593 JNC $$IF228
2594 mov ax,[FSIZE] ; ;AN004;
2595 add [packet],ax ; ;AN004;
2596 mov [FAT_2],1 ; packet points to FAT #2 ;AN004;
2597 call Direct_Access ; ;AN004;
2598; $endif ; ;AN004;
2599$$IF228:
2600 pop dx ; ;AN004;
2601 pop ax ; recover starting sector ;AN006;
2602; $if nc ; ;AN004;
2603 JC $$IF230
2604 xchg al,ah ; convert sector back to cluster ;AN004;
2605 mov [cluster_low],ax ; new bottom of FAT ;AN004;
2606 mov [cluster_high],ax ; ;AN004;
2607 add [cluster_high],clusters_loaded ; new top of FAT ;AN004;
2608; $endif ; ;AN004;
2609$$IF230:
2610; $endif ; ;AN004;
2611$$EN221:
2612 pop bx
2613
2614
2615 ret ; ;AN004;
2616
2617 Check_FAT ENDP
2618
2619 CODE ENDS
2620
2621 END
2622 \ No newline at end of file
diff --git a/v4.0/src/CMD/SYS/SYSHDR.INC b/v4.0/src/CMD/SYS/SYSHDR.INC
new file mode 100644
index 0000000..896d382
--- /dev/null
+++ b/v4.0/src/CMD/SYS/SYSHDR.INC
@@ -0,0 +1,427 @@
1 page 80,132
2;******************* START OF SPECIFICATIONS ***********************************
3;
4; MODULE NAME: SYS1.SAL + SYS2.SAL + SYSSR.SAL
5;
6; DESCRIPTIVE NAME: SYS
7;
8; FUNCTION: Copies system programs IBMBIO.COM and
9; IBMDOS.COM onto a specified media.
10;
11; ENTRY POINT:
12;
13; INPUT:
14;
15; EXIT NORMAL:
16;
17; EXIT ERROR:
18;
19; INTERNAL REFERENCES:
20;
21; ROUTINES:
22;
23; DATA AREAS:
24;
25; EXTERNAL REFERENCES:
26;
27; ROUTINES:
28;
29; DATA AREAS:
30;
31; NOTES: Version 4.0 is a MAJOR diversion from all previous versions of DOS.
32;
33; In all older versions of SYS the target diskette, HAD to meet the
34; following criteria in order to be SYSed:
35; - there must be enough physical room for IBMBIO and
36; IBMDOS.
37; - the first data cluster (#2) had to be either not
38; used - or owned by IBMBIO allready on the disk
39; - The first 2 root DIR entries had to be unused, deleted
40; or owned by IBMBIO and IBMDOS.
41;
42; 4.0 SYS is far less restrictive.
43; - there must still be enough physical room for IBMBIO
44; and IBMDOS.
45; - SYS will free up all required data clusters required
46; by IBMBIO.
47; - The 2 root DIR entries for IBMDOS and IBMBIO may
48; be anywhere in the root. SYS will move entrys
49; in order for IBMBIO and IBMDOS to be in their proper
50; positions.
51; *** NOTE **** - Sys will operate on DOS 3.2, 3.3 and 4.0.
52; This has reqired a HARD CODED lower bound - DOS_low
53; that is set in this file to 3.20
54;
55; REVISION HISTORY: Ax000 Version 4.0 05/01/87 - first release FG
56; Ax001 4.0 PTR P324 D Love
57; Ax002 4.0 PTR P583 FG
58; Ax003 4.0 DCR D4 - sys anything,anywhere FG
59; Ax004 4.0 DCR D201 - extended arbib change FG
60; Ax005 4.0 PTR P1334 - 1.2 MB + system hang FG
61; Ax006 4.0 PTR P1403 - BIO & DOS wrong spots FG
62; Ax007 4.0 PTR P1404,5 - DIR search error FG
63; Ax008 4.0 PTR P1406 - IOCTL to INT 21-69 FG
64; Ax009 4.0 PTR P1637 - full 720KB error FG
65; Ax010 4.0 PTR P1764 - single file error FG
66; Ax011 4.0 PTR P1772 - IBMBIO cluster chain FG
67; Ax012 4.0 PTR P1710 - ASSIGN or SUBST invalid FG
68; Ax013 4.0 PTR P1872 - ROOT restoration problem FG
69; Ax014 4.0 PTR P1884 - more ROOT problems FG
70; Ax015 4.0 PTR P2165 - ROOT DIR above #100h sec.FG
71; Ax016 4.0 DCR D304 - change in BOOT.INC FG
72; Ax017 4.0 PTR P2356 - HILDA error message FG
73; Ax018 4.0 PTR P2769 - no system on default drv FG
74; Ax019 4.0 DCR D380 - run on current VER -1 FG
75; Ax020 4.0 PTR P3028 - run using PATHGEN FG
76; Ax021 4.0 DCR D494 - add "source" & DOS 3.2 FG
77; Ax022 4.0 PTR P3728 - wrong network message FG
78; Ax023 4.0 DCR D503 - Version is now 4.0 FG
79; Ax024 4.0 PTM P3905 - fix parse error format FG
80; Ax025 4.0 PTM P4118 - fix message error FG
81;
82; PRE-VERSION 4.0 HISTORY:
83;
84; 1.6 05/21/82 Added rev number message
85; 1.61 06/04/82 Allow SYS to blank disk TimP at SCP
86; 1.70 06/30/82 NON contiguous DOS allowed on 2.00 IBM. Allows SYS to
87; 1.0 1.1 disks.
88; 1.71 07/02/82 Put in CHDIRs to make sure everything done in root dir.
89; 1.80 04/26/83 MZ make sys work in small machines; use full 2.0
90; system calls
91; 1.81 07/22/83 ARR Added check in IBM version for valid FAT ID on
92; destination because of IBM problem with SYSing to
93; unformatted disks which are really formatted. Prints
94; NoDest message for ridic IBM reasons, should have a
95; better message.
96; 1.82 08/12/83 ARR ZIBOed again. Mark fails to check for errors on
97; his file I/O. Results in SYS saying system
98; transferred when it hasn't been.
99; 1.83 09/08/83 EKE Added code to quit if sys called on a drive across
100; a net.
101; 1.84 09/09/83 CHRISP grabbed against his will to make this stupid
102; program write out a boot sector
103; 1.85 10/18/83 NP Printf to print messages and it's now an .EXE file
104; 1.86 11/8/83 MZ fix hard file output of boot sector
105; 1.87 5/1/84 MZ make sys prompt for system disk in default drive.
106; 3.20 11/9/84 RS make sys write out a correct boot sector for the
107; version of DOS. It grabs the boot sector off the system
108; disk and inserts the correct BPB.
109; Uses IOCTL Get Device Parms to get BPB for a Hard drive.
110; 3.20 08/5/85 RS Allow FAT ID byte of 0F0H for 'strange' media
111; layouts. These come about because of /T /N switches in
112; FORMAT.
113; 3.20 09/16/85 Incorporate tables of filenames to allow system files
114; used by other OEMs to be SYSed onto disks formatted on
115; other MSDOS systems. Allows the flexibility to replace
116; system files for one OEM by system files for another.
117;
118;
119; 3.30 06/04/86 MT removes initial check for IBMBIO and DOS - not needed
120; because of later search of dirs
121; 3.30 06/16/86 MT only force part of IBMBIO contig - do this by assuming
122; contig part smaller than 1.10 BIOS
123; 3.30 06/16/86 MT Check diks space for enough room to install BIO and DOS
124;
125; Label: "The DOS SHARE Utility"
126; "Version 4.00 (C) Copyright 1988 Microsoft
127; "Licenced Material - Program Property of Microsoft"
128;
129;******************* END OF SPECIFICATIONS *************************************
130 BREAK <SYS1 - Program Organization>
131;******************+ START OF PSEUDOCODE +**************************************
132;
133;ÚÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄ¿
134;³ Main ÃÄÄ´Init_Input_OutputÃÄÄÄÄ´SysLoadMsg³ (DOS version check)
135;ÀÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÙ
136; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
137; ³ À´Parse_Command_Line³
138; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
139; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
140; ôValidate_Target_DriveôCheck_Default_Drive³
141; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
142; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
143; ³ ôCheck_Target_Drive³
144; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
145; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
146; ³ À´Check_For_Network³
147; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
148; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
149; ôGet_System_FilesÃÄÄÄÄÄ´Prompt_For_Media³
150; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
151; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
152; ³ ôCheck_Removable³
153; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
154; ³ ³ÚÄÄÄÄÄÄÄÄÄ¿
155; ³ ôOpen_File³
156; ³ ³ÀÄÄÄÄÄÄÄÄÄÙ
157; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄ¿
158; ³ À´Fill_Memory³
159; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÙ
160; ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
161; ôCheck_SYS_ConditionsÃÄ´Verify_File_System³
162; ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
163; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄ Ä Ä Ä Ä Ä Ä Ä ¿
164; ³ ôRead_DirectoryÃÄÄÄÄÄÄÄÄÄ´Prompt_For_Media³
165; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄ Ä Ä Ä Ä Ä Ä Ä Ù
166; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
167; ³ ôVerify_File_Location³
168; ³ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
169; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄ¿
170; ³ À´Determine_Free_SpaceÃÄÄÄ´Get_Cluster³
171; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ
172; ³ÚÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄ¿
173; ôDo_SYSÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´Create_SystemÃÄÄÄÄÄÄÄÄÄÄ´Create_File³
174; ³ÀÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ
175; ³ ³ÚÄ Ä Ä Ä Ä Ä¿
176; ³ ôFill_Memory³
177; ³ ³ÀÄ Ä Ä Ä Ä ÄÙ
178; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄ¿
179; ³ À´Dump_Memory³
180; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÙ
181; ³ÚÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄ¿
182; ôDo_EndÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´Close_Files³
183; ³ÀÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÙ
184; ³ ³ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
185; ³ À´Write_Boot_RecordÃÄÄÄÄÄ´Create_Serial_ID³
186; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
187; ³ ³ÚÄÄÄÄÄÄÄÄ¿
188; ³ À´FAT_Size³
189; ³ ÀÄÄÄÄÄÄÄÄÙ
190; ³ÚÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
191; À´Message ÃÄÄÄÄÄÄÄÄÄÄÄÄ´Get_DOS_Error³
192; ÀÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
193;
194;******************- END OF PSEUDOCODE -**************************************
195 BREAK <SYS - Segment Definition>
196 ;---------------------------------------
197 ; NOTE: Structures used by SYS include:
198 ;
199 ; find_buf - DTA mapper
200 ; a_bpb - EBPB struc
201 ; dir_entry - Directory struc
202 ; A_DeviceParameters - IOCtl struc
203 ; BootForm - Boot Rec struc
204 ;---------------------------------------
205
206
207; INCLUDE DOSSYM.INC ;also defines version of dos
208.xlist
209.xcref
210 INCLUDE DOSSYM.INC
211.cref
212.list
213
214
215; INCLUDE IOCTL.INC ; Get / Set Device Parameters IOCTL
216.xlist
217.xcref
218 INCLUDE IOCTL.INC
219.cref
220.list
221
222
223; INCLUDE BOOTFORM.INC ; Boot Record Structure
224.xlist
225.xcref
226 INCLUDE BOOTFORM.INC
227.cref
228
229
230; INCLUDE PATHMAC.INC ; PATH macro for PATHGEN
231.xlist
232.xcref
233 INCLUDE PATHMAC.INC
234.cref
235.list
236
237IBMJAPVER EQU FALSE ; this and the following are mutually
238IBMVER EQU TRUE ; exclusive
239
240CODE SEGMENT PARA PUBLIC
241CODE ENDS
242
243DATA SEGMENT PARA PUBLIC
244DATA ENDS
245
246; $SALUT (4,25,30,41)
247 ;--------------------------------------
248 ; constants
249 ;--------------------------------------
250
251DOS_low equ 0300h + 20 ; 3 in high reg, 20 in low reg. ;AN023;
252not_used equ 0 ; filler for INT 21's
253num_2_letter equ 040h ; turn dirve number to letter
254dev_local equ 9 ; IOCtl - get device parameters
255removable equ 01h ; for testing removeability
256net_drive equ 01000h ; for testing net drive
257DOS_system_atrib equ 7 ; DOS system file atributes
258DOS_volume_atrib equ 8 ; DOS volume label atribute
259error_RC equ 1 ; error return code
260any_error equ 255 ; mask for detecting errors
261success equ 0 ; successful completion of SYS
262LSeek_EOF equ 2 ; seek relative to eof
263LSeek_Start equ 0 ; seek relative to beginning
264old_type_media equ 26 ; DOS extended error - old type media
265file_not_found equ 2 ; DOS extended error - file not found
266file_spec_length equ 11 ; length of file name
267empty equ 0 ; empty directory entry
268deleted equ 0E5h ; entry is deleted
269SetAtrib equ 01h ; set file attributes
270set equ 1 ; set file date and time
271BIG_FAT_THRESHOLD equ 4086 ; size break for FAT12 - FAT16
272PRELOAD equ 1 ; normal preload
273return_error equ 1 ; SYS return error code
274FQ_DOS_DIR_CON_INP equ 07h ; Flush Queue / Direct CON in no echo
275hard_drive equ 0F8H ; Media Descriptor for Hard drive
276first_drive equ 80H ; first physical hard drive number
277noerror equ 0 ; no errors
278FAT_sect_size equ 12 ; FAT sector count
279dot equ 02Eh ; Sub DIR DOT
280bad_sector equ 0F7h ; FAT bad sector mark
281end_cluster equ 0FFh ; FAT last cluster mark
282not_found equ 0FFh ; current cluster not yet found
283cluster_ent_per_sect equ 512/2 ; (bytes/sector) / (bytes/cluster entry)
284 ; = cluster entries / sector
285clusters_loaded equ cluster_ent_per_sect * FAT_sect_size ; = # of cluster
286 ; entries loaded in 12 sectors.
287
288FAT_BUF equ 512 * 13 ; This space is used to do a number
289 ; of tasks. It existes at the START
290 ; of BUF. It is used as a 1 sector
291 ; buffer for processing DIR sector
292 ; manipulation. It is also used to
293 ; process the FAT. NOTE: a 12 bit fat
294 ; has a max. of FFFh (4K) entries - or
295 ; 6K of space - or 12 sectors (512 bytes)
296 ; an extra 512 bytes is added for safety
297
298 ;----------------------------------------
299 ; definition of the MODE bits
300 ; for an extended open
301 ;----------------------------------------
302
303; BITS DEFINED FOR THE MODE WORD
304; FORMAT = 0WF0000CISSS0AAA
305; Write ÄÄÄÄÄÄÄÄÄÄÄÙ³ ³³³ ÀÄÄÄ Access code
306; 0 = no commit ³ ³³³ 0 = read
307; 1 = auto commit ³ ³³³ 1 = write
308; ³ ³³³ 2 = read/write
309; Fail action ÄÄÄÄÄÄÄÄÄÄÄÄÙ ³³³ 3 = execute
310; 0 = INT 24h ³³³ 4 = FCB
311; 1 = return error ³³³
312; ³³ÀÄÄÄ Sharing mode
313; Code Page support ÄÄÄÄÄÄÄÄÙ³ 0 = compatability
314; 0 = validate code page ³ 1 = deny read/write
315; 1 = no code page check ³ 2 = deny write
316; ³ 3 = deny read
317; ³ 4 = deny none
318; Inherit
319; 0 = pass handle to child
320; 1 = no inherit
321;
322MODE_COM equ 0100000000000000b ; Auto Commit
323MODE_NO24 equ 0010000000000000b ; No 24 - return error
324MODE_NOCP equ 0000000100000000b ; No 24 - return error
325MODE_NOINH equ 0000000010000000b ; No child procees access
326; Sharing mode
327;MODE_SH_COMP equ 0000000000000000b 0 = compatability
328MODE_SH_D_RW equ 0000000000010000b ; 1 = deny read/write
329MODE_SH_D_W equ 0000000000100000b ; 2 = deny write
330MODE_SH_D_R equ 0000000000110000b ; 3 = deny read
331MODE_SH_D_NONE equ 0000000001000000b ; 4 = deny none
332; Access code
333;MODE_AC_R equ 0000000000000000b 0 = read
334MODE_AC_W equ 0000000000000001b ; 1 = write
335MODE_AC_RW equ 0000000000000010b ; 2 = read/write
336MODE_AC_EXE equ 0000000000000011b ; 3 = execute
337MODE_AC_FCB equ 0000000000000100b ; 4 = FCB
338
339open_mode equ MODE_NO24+MODE_NOCP+MODE_NOINH+MODE_SH_D_RW+ MODE_AC_RW
340
341;-------------------------------------------------
342; Message Skeleton File
343;-------------------------------------------------
344
345;util SYS
346
347;class 1
348
349;use EXTEND15 ; INVALID DRIVE
350
351;class 2
352
353;use PARSE1 ;1 - Too many operands
354;use PARSE2 ;2 - Required operand missing
355 ;3 - Not in switch list provided
356 ;4 - Not in keyword list provided
357 ;6 - Out of range specified
358 ;7 - Not in value list provided
359 ;8 - Not in string list provided
360;use PARSE9 ;9 - Invalid Parameter
361
362;class A
363
364;use 1 COMMON1
365
366;class B
367
368;def 7 "No room for system on destination disk",CR,LF ; Old
369;def 8 "Ivalid path or System files not found",CR,LF ; New
370;use 9 COMMON30 ; System transferred - Old
371;def 10 "No system on default drive",CR,LF ; Old
372;def 11 "Can not specify default drive",CR,LF ; New
373;def 12 "Write failure, diskette unusable",CR,LF ; New
374;use 19 COMMON25 ; Invalid path ; New
375
376;class C
377
378;use 13 COMMON12 ; Cannot %1 to a Network drive - Old
379;def 14 "Insert system disk in drive %1",CR,LF ; Old
380;use 15 COMMON19 ; Insert destination disk in drive %1 - Old
381;def 16 "Not able to SYS to %1 file system",CR,LF ; New
382;use 18 COMMON14 ; Cannot %1 a SUBSTed or ASSIGNed drive - NEW
383
384;class D
385
386;use 17 COMMON28 ; Press any key to continue. . . - Old
387
388;end
389
390 ;----------------------------------------
391 ; Message Number Equates
392 ;----------------------------------------
393
394util equ 0ffh ; all Utility messages
395DOS_error equ 1 ; DOS error CLASS
396PARSE_error equ 2 ; PARSE error CLASS
397util_B equ 0bh ; Utility CLASS B messages
398 ; (plain message)
399util_C equ 0ch ; Utility CLASS C messages
400 ; (insert message)
401util_D equ 0dh ; Utility CLASS D messages
402 ; (wait message)
403extended_15 equ 15 ; DOS extended error 15
404reqd_missing equ 2 ; PARSE error 2
405
406 ; CLASS B
407
408no_room equ 7 ; No room for system on destination disk Old
409system_not_found equ 8 ; Invalid path or System files not found Old
410done equ 9 ; System transferred Old
411no_sys_on_def equ 10 ; No system on default drive Old
412not_on_default equ 11 ; Can not specify default drive New
413write_fail equ 12 ; Write failure, diskette unusable New
414bad_path equ 19 ; Invalid path
415 ; CLASS C
416
417cant_network equ 13 ; Cannot %1 to a Network drive Old
418sys_disk equ 14 ; Insert system disk in drive %1 Old
419dest_disk equ 15 ; Insert destination disk in drive %1 Old
420cant_sys equ 16 ; Not able to SYS to %1 file system New
421cant_assign equ 18 ; Cannot %1 a SUBSTed or ASSIGNed drive Old
422
423 ; CLASS D
424
425press_key equ 17 ; Press any key to continue. . . Change
426
427 BREAK <SYS >
diff --git a/v4.0/src/CMD/SYS/SYSSR.ASM b/v4.0/src/CMD/SYS/SYSSR.ASM
new file mode 100644
index 0000000..f54f233
--- /dev/null
+++ b/v4.0/src/CMD/SYS/SYSSR.ASM
@@ -0,0 +1,82 @@
1 INCLUDE SYSHDR.INC
2
3; include SYSMSG.INC
4
5.xlist
6.xcref
7
8 include SYSMSG.INC ; ;AN000;
9
10.cref
11.list
12
13 MSG_UTILNAME <SYS> ; ;AN000;
14
15CODE SEGMENT PARA PUBLIC
16
17ASSUME CS:CODE,DS:nothing,ES:nothing
18
19 PUBLIC SYSDISPMSG, SYSLOADMSG, SYSPARSE
20 PUBLIC Data_Space
21
22;;dcl MSG_SERVICES <MSGDATA> ; ;AN000;
23
24; MSG_SERVICES <SYS.CL1,SYS.CL2,SYS.CLA,SYS.CLB,SYS.CLC,SYS.CLD> ;AN000;
25
26.xlist
27.xcref
28
29 MSG_SERVICES <SYS.CL1,SYS.CL2,SYS.CLA,SYS.CLB,SYS.CLC,SYS.CLD> ; ;AN000;
30
31.cref
32.list
33
34; MSG_SERVICES <LOADmsg,DISPLAYmsg,INPUTmsg,CHARmsg,NOVERCHECKmsg>
35
36.xlist
37.xcref
38
39 MSG_SERVICES <LOADmsg,DISPLAYmsg,INPUTmsg,CHARmsg,NOVERCHECKmsg> ; ;AN000;
40
41.cref
42.list
43
44
45false = 0 ; ;AN000;
46
47DateSW equ false ; ;AN000;
48TimeSW equ false ; ;AN000;
49CmpxSW equ false ; ;AN000;
50KeySW equ false ; ;AN000;
51QusSW equ false ; ;AN000;
52Val1SW equ false ; ;AN000;
53Val2SW equ false ; ;AN000;
54Val3SW equ false ; ;AN000;
55SwSW equ false ; ;AN000;
56NumSW equ false ; ;AN000;
57CAPSW equ false ; Perform CAPS if specified ;AN000;
58
59
60ASSUME CS:CODE,DS:CODE,ES:nothing
61
62; include parse.asm
63
64;xlist
65;xcref
66
67include parse.asm ; ;AN000;
68
69.cref
70.list
71
72Data_Space LABEL BYTE ; ;AN000;
73
74
75
76CODE Ends
77
78include msgdcl.inc
79
80 End
81
82 \ No newline at end of file