summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/SYS/SYS1.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/SYS/SYS1.ASM')
-rw-r--r--v4.0/src/CMD/SYS/SYS1.ASM3710
1 files changed, 3710 insertions, 0 deletions
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