summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM')
-rw-r--r--v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM2452
1 files changed, 2452 insertions, 0 deletions
diff --git a/v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM b/v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM
new file mode 100644
index 0000000..e278c9e
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOPY/DISKCOPY.ASM
@@ -0,0 +1,2452 @@
1 PAGE 90,132 ;A2
2 TITLE DISKCOPY.SAL - DISKETTE DUPLICATION UTILITY ;
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: DISKCOPY
5
6; DESCRIPTIVE NAME: Diskette to diskette complete copy Utility
7
8;FUNCTION: DISKCOPY is to copy the contents of the diskette in the
9; specified source drive to the diskette in the target
10; drive. If necessary, the target diskette is also
11; formatted.
12
13
14; Multiple copies may be performed with one load of DISKCOPY.
15; A prompt, "Copy another (Y/N)?" permits additional
16; executions, all with the same drive specifications.
17
18; ENTRY POINT: "DISKCOPY" at ORG 100h, jumps to "BEGIN".
19
20; INPUT: (DOS command line parameters)
21; [d:][path]DISKCOPY [d: [D:]][/1]
22
23; Where
24
25; [d:][path] before DISKCOPY to specify the drive and path that
26; contains the DISKCOPY command file.
27
28; [d:] to specify the source drive id
29
30; [D:] to specify the destination drive id
31
32; [/1] to request single sided operations only
33
34; EXIT-NORMAL: Errorlevel = 0
35; Function completed successfully.
36
37; EXIT-ERROR: Errorlevel = 1
38; Abnormal termination due to error, wrong DOS,
39; invalid parameters, unrecoverable I/O errors on
40; the diskette.
41;
42; Errorlevel = 2
43; Termination requested by Cntrl-Break.
44
45; EFFECTS: The entire source diskette is copied, including the unused
46; sectors. There is no awareness of the separate files
47; involved. A unique volume serial number is generated
48; for the target diskette.
49
50; INCLUDED FILES:
51; INCLUDE DCPYMACR.INC ;(formerly called MACRO.DEF)
52; INCLUDE DISKCOPY.EQU ;EQUATES
53; INCLUDE BOOTFORM.INC ;DEFINE EXT_BPB_INFO & EXT_IBMBOOT_HEADER
54; INCLUDE PATHMAC.INC ;PATHGEN MACRO
55
56; INTERNAL REFERENCES:
57; ROUTINES:
58; BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS
59; SET_LOGICAL_DRIVE - SET LOG. DRV LETTER THAT OWNS DRIVE
60; COPY - COPY THE DISKETTE IMAGE
61; TEST_REPEAT - SEE IF USER WANTS TO COPY ANOTHER
62; READ_SOURCE - READ FROM SOURCE AS MUCH AS POSSIBLE
63; WRITE_TARGET - WRITE DATA FROM MEMORY TO TARGET DISKETTE
64; READ_WRITE_TRACK - READ A TRACK AND STORE IT INTO MEMORY
65; READ_OP - IOCTL READ A TRACK OPERATION
66; MAYBE_ADJUST_SERIAL - MAKE NEW SERIAL IN BOOT
67; WRITE_OP - IOCTL WRITE A TRACK OPERATION
68; FORMAT_ALL - FORMATS ALL TRACKS TO END
69; FORMAT_TRACK - IOCTL FORMAT A TRACK
70; CHECK_SOURCE - CHECK SOURCE DISKETTE TYPE
71; READ_A_SECTOR - GET ONE SECTOR WITH IOCTL READ
72; CALC_TRACK_SIZE - GET MEM SIZE TO STORE ONE TRACK
73; CHECK_MEMORY_SIZE - VERIFY WE HAVE ENUF TO COPY 1 TRACK
74; SET_FOR_THE_OLD - SET BPB FOR BEFORE-2.0 FMTTED MEDIA
75; SET_TRACKLAYOUT - MOVE DATA TO TRACK IMAGE
76; CHECK_TARGET - READ TARGET BOOT RCD, NEEDS FORMAT?
77; CHK_MULTI_MEDIA - CHECK IF DRIVE IS MULTI-MEDIA
78; SET_DRV_PARM_DEF - SET DRIVE PARMS VIA IOCTL
79; CHK_MEDIATYPE - DETERMINE MEDIATYPE OF TARGET FOR FORMAT
80; GENERIC_IOCTL - COMMUNICATE WITH THE DEVICE DRIVER
81; EXTENDED_ERROR_HANDLER - RESPOND TO DOS ERRORS
82; TRY_FORMAT - ATTEMPT TRACK FORMAT, TRY FOR ERROR RECOVERY
83; ERROR_MESSAGE - SAY WHAT AND WHERE FAILURE
84; SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG
85; YESNO - DETERMINE IF A RESPONSE IS YES OR NO
86;(DELETED ;AN013;)READ_VOLSER - OBTAIN OLD VOLUME SERIAL NUMBER FROM SOURCE
87; WRITE_VOLSER - PUT NEW VOL SER NUMBER TO TARGET
88; DATA AREAS:
89; PSP - Contains the DOS command line parameters.
90; WORKAREA - Temporary storage
91
92; EXTERNAL REFERENCES:
93; ROUTINES:
94; SYSDISPMSG - Uses the MSG parm lists to construct the messages
95; on STDOUT.
96; SYSLOADMSG - Loads messages, makes them accessable.
97; SYSPARSE - Processes the DOS Command line, finds parms.
98
99; DATA AREAS:
100; DCOPYSM.SAL - Defines the control blocks that describe the messages
101; DCOPYPAR.SAL - Defines the control blocks that describe the
102; DOS Command line parameters.
103
104; NOTES:
105; This module should be processed with the SALUT preprocessor
106; with the re-alignment not requested, as:
107
108; SALUT DISKCOPY,NUL
109
110; To assemble these modules, the alphabetical or sequential
111; ordering of segments may be used.
112
113; Sample LINK command:
114
115; LINK @DISKCOPY.ARF
116
117; Where the DISKCOPY.ARF is defined as:
118
119; DISKCOPY+
120; DCOPYSM+
121; DCOPYP+
122; DCOPYPAR+
123; COPYINIT
124
125; These modules must be linked in this order. The load module is
126; a COM file, to be converted to COM with EXE2BIN.
127
128; REVISION HISTORY:
129; A000 Version 4.00: add PARSER, System Message Handler,
130; Make new unique vol serial number on new diskette.
131; A001 DCR 27, display vol serial number, if present.
132; A002 ptm473 Flag duplicate switches as error
133; A003 Display parm in error
134; A004 PTR752 Add close door to drive not ready
135; A005 PTR756 After bad parms, specify help info
136; A006 DCR210 SELECT, if present, handles all msgs
137; A007 PTM1100 Clear keyboard buffer before input response
138; A008 PTM1434 CR,LF MISSING FROM MSGS 22 AND 23
139; A009 PTM1406 USE 69H INSTEAD OF IOCTL FOR GET/SET MEDIA ID
140; A010 PTM1821 Move INCLUDE COPYRIGH.INC into MSG_SERVICE macro.
141; A011 PTM1837 ADD CHECK FOR UNKNOWN MEDIA TO TRIGGER FORMAT
142; A012 PTM2441 COPY FROM 360 TO 1.2 CLOBBERS 1.2
143; A013 PTM3184 SUPPORT OS/2 1.0/1.1 TYPE BOOT RECORDS ALSO
144; REMOVE USE OF GET/SET MEDIA ID
145; A014 PTM3262 specify BASESW EQU 1 before PARSE.ASM
146; A015 PTM3512 PATHGEN
147;
148; COPYRIGHT: The following notice is found in the OBJ code generated from
149; the "DCOPYSM.SAL" module:
150
151; "Version 4.00 (C) Copyright 1988 Microsoft"
152; "Licensed Material - Property of Microsoft "
153
154;PROGRAM AUTHOR: Original written by: JK
155; 4.00 modifications by: EMK
156;****************** END OF SPECIFICATIONS *****************************
157 IF1 ;
158 %OUT COMPONENT=DISKCOPY, MODULE=DISKCOPY.SAL ;
159 ENDIF ;
160
161;*****************************************************************************
162; *
163; D I S K C O P Y *
164; *
165; UPDATE HISTORY: 7-31, 8-3, 8-5A, 8-6, 8-7, 8-8, 8-10, 8-11, 8-13, 8-14 *
166; 8-16, 8-17, 8-18, 8-20, 8-28, 9-3, 9-11, 10-6, 10-11 *
167; 11-7,11-12, 11-17, 11-18, 12-19, 2-16-84, 3-27, 4-5, 4-7 *
168; 6-20,7-23,10-31,3-27,4-24 *
169; *
170;*****************************************************************************
171
172
173
174;*****************************************************************************
175; *
176; MACRO DEFINITION *
177; *
178;*****************************************************************************
179
180 INCLUDE PATHMAC.INC ;AN015;PATHGEN MACRO
181 INCLUDE DCPYMACR.INC ;(formerly called MACRO.DEF)
182 INCLUDE DISKCOPY.EQU ;EQUATES
183
184; $salut (4,16,22,36) ;AN000;
185MY_BPB STRUC ;
186CBYTE_SECT DW 0 ; 200H BYTES / SECTOR
187CSECT_CLUSTER DB 0 ; 2h SECTORS / CLUSTER
188CRESEV_SECT DW 0 ; 1h RESERVED SECTORS
189CFAT DB 0 ; 2h # OF FATS
190CROOTENTRY DW 0 ; 70h # OF ROOT ENTRIES
191CTOTSECT DW 0 ; 02D0h TOTAL # OF SECTORS INCLUDING
192 ; BOOT SECT, DIRECTORIES ...
193MEDIA_DESCRIP DB 0 ;0FDh MEDIA DISCRIPTOR
194CSECT_FAT DW 0 ; 2h SECTORS / FAT
195CSECT_TRACK DW 0 ;
196CHEAD DW 0 ;
197CHIDDEN_SECT DD 0 ;
198BIG_TOT_SECT DD 0 ;
199 DB 6 DUP (0) ;
200MY_BPB ENDS ;
201
202 INCLUDE BOOTFORM.INC ;AN013;DEFINE EXT_BPB_INFO & EXT_IBMBOOT_HEADER
203
204CSEG SEGMENT PARA PUBLIC 'CODE' ;AN000;
205 ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG ;
206
207;*****************************************************************************
208; *
209; EXTERNAL VARIABLES *
210; *
211;*****************************************************************************
212;$salut (4,2,9,36) ;AN000;
213 EXTRN SYSLOADMSG :NEAR ;AN000;SYSTEM MSG HANDLER INTIALIZATION
214 EXTRN SYSDISPMSG :NEAR ;AN000;SYSTEM MSG HANDLER DISPLAY
215
216 EXTRN INIT :NEAR ;INITIALIZATION ROUTINE
217.XLIST ;
218;EXTRN PRINTF :NEAR ;MESSAGE DISPLAY ROUTINE
219;EXTRN PROMPT :NEAR ;MESSAGE DISPLAY AND KEYBOARD INPUT ROUTINE
220;EXTRN ERROR_MESSAGE :NEAR ;ERROR MESSAGE DISPLAY ROUTINE
221;EXTRN MSG_SOURCE_BAD_PTR :BYTE
222;EXTRN YES :BYTE
223;EXTRN NO :BYTE
224.LIST ;
225 EXTRN ASCII_DRV1_ID :BYTE ;AN000;SOURCE DRIVE LETTER CHARACTER
226 EXTRN ASCII_DRV2_ID :BYTE ;AN000;TARGET DRIVE LETTER CHARACTER
227 EXTRN MSG_TRACKS :WORD ;AN000;NUMBER OF TRACKS
228 EXTRN MSG_SECTRK :WORD ;AN000;SECTORS PER TRACK
229 EXTRN MSG_SIDES :WORD ;AN000;NUMBER OF SIDES
230 EXTRN ERROR_SIDE_NUMBER :WORD ;AN000;NUMBER OF SIDES (SUBFIELD OF MSG 19)
231 EXTRN ERROR_TRACK_NUMBER :WORD ;AN000;NUMBER OF TRACKS (SUBFIELD OF MSG 19)
232
233 EXTRN MSGNUM_EXTERR :WORD ;AN000;EXTENDED ERROR MSG DESCRIPTOR
234 EXTRN MSGNUM_HARD_ERROR_READ:WORD ;AN000;"Unrecoverable read/write error on drive %1",CR,LF
235 EXTRN MSGNUM_HARD_ERROR_WRITE:WORD ;AN000;"Side %2, track %3" ;
236 EXTRN MSGNUM_LOAD_SOURCE :WORD ;AC000;"Insert SOURCE diskette in drive %2:"
237 EXTRN MSGNUM_LOAD_TARGET :WORD ;AC000;"Insert TARGET diskette in drive %2:"
238 EXTRN MSGNUM_TARGET_MB_UNUSABLE :WORD ;AC000;"Target diskette may be unusable"
239 EXTRN MSGNUM_NOT_COMPATIBLE :WORD ;AC000;"Drive types or diskette types",CR,LF
240 ;"not compatible"
241 EXTRN MSGNUM_BAD_SOURCE :WORD ;AC000;"SOURCE diskette bad or incompatible"
242 EXTRN MSGNUM_BAD_TARGET :WORD ;AC000;"TARGET diskette bad or incompatible"
243 EXTRN MSGNUM_COPY_ANOTHER :WORD ;AC000;"Copy another diskette (Y/N)?"
244 EXTRN MSGNUM_FORMATTING :WORD ;AC000;"Formatting while copying"
245 EXTRN MSGNUM_GET_READY :WORD ;AC000;"Drive not ready - %0"
246 EXTRN MSGNUM_CLOSE_DOOR :WORD ;AN004;"Make sure a diskette is inserted into
247 ; the drive and the door is closed"
248 EXTRN MSGNUM_FATAL_ERROR :WORD ;AC000;"Copy process ended"
249 EXTRN MSGNUM_UNSUF_MEMORY:WORD ;AC000;"Insufficient memory"
250 EXTRN MSGNUM_COPYING :WORD ;AC000;"Copying %1 tracks",CR,LF
251 ;"%2 Sectors/Track, %3 Side(s)"
252 EXTRN MSGNUM_STRIKE :WORD ;AC000;"Press any key to continue . . ."
253 EXTRN MSGNUM_WRITE_PROTECT :WORD ;AC000;"Attempt to write to write-protected diskette"
254 EXTRN MSGNUM_CR_LF :WORD ;AC000;
255 EXTRN MSGNUM_SERNO :WORD ;AN001;"VOLUME SERIAL NUMBER IS %1-%0"
256 EXTRN SUBLIST_26A :WORD ;AN001;POINTS TO FIRST PART OF SERIAL NUMBER
257 EXTRN SUBLIST_26B :WORD ;AN001;POINTS TO SECND PART OF SERIAL NUMBER
258
259 EXTRN DRIVE_LETTER :BYTE ;AN000;
260;*****************************************************************************
261; *
262; PUBLIC VARIABLES *
263; *
264;*****************************************************************************
265
266 PUBLIC RECOMMENDED_BYTES_SECTOR ;
267 PUBLIC COPY ;
268 PUBLIC S_OWNER_SAVED ;
269 PUBLIC T_OWNER_SAVED ;
270 PUBLIC SOURCE_DRIVE ;
271 PUBLIC TARGET_DRIVE ;
272 PUBLIC S_DRV_SECT_TRACK ;
273 PUBLIC S_DRV_HEADS ;
274 PUBLIC S_DRV_TRACKS ;
275 PUBLIC T_DRV_SECT_TRACK ;
276 PUBLIC T_DRV_HEADS ;
277 PUBLIC T_DRV_TRACKS ;
278 PUBLIC USER_OPTION ;
279 PUBLIC COPY_TYPE ;
280 PUBLIC BUFFER_BEGIN ;
281 PUBLIC BUFFER_END ;
282 PUBLIC TRACK_TO_READ ;
283 PUBLIC TRACK_TO_WRITE ;
284 PUBLIC SIDE ;
285 PUBLIC USER_INPUT ;
286 PUBLIC MAIN_EXIT ;
287
288 PUBLIC IO_ERROR ;
289
290 PUBLIC DS_IOCTL_DRV_PARM ;PLACE HOLDER FOR DEFAULT SOURCE DRV PARM
291 PUBLIC DT_IOCTL_DRV_PARM ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
292 PUBLIC DS_specialFunctions ;AND THEIR CONTENTS
293 PUBLIC DT_specialFunctions ;
294 PUBLIC DS_deviceType ;
295 PUBLIC DT_deviceType ;
296 PUBLIC DS_deviceAttributes ;
297 PUBLIC DT_deviceAttributes ;
298 PUBLIC DS_numberOfCylinders ;
299 PUBLIC DT_numberOfCylinders ;
300 PUBLIC DS_mediaType ;
301 PUBLIC DT_mediaType ;
302 PUBLIC DS_BPB_PTR ;
303 PUBLIC DT_BPB_PTR ;
304
305 PUBLIC MS_IOCTL_DRV_PARM ;DRIVE PARM FROM SOURCE MEDIUM
306 PUBLIC MT_IOCTL_DRV_PARM ;DRIVE PARM FROM TARGET MEDIUM
307
308;*****************************************************************************
309 ORG 100H ;PROGRAM ENTRY POINT
310
311DISKCOPY: ;
312 JMP BEGIN ;
313;*****************************************************************************
314
315;INTERNAL STACK AREA
316 EVEN ;AN000;MAKE STACK WORD ALIGNED
317 DB 64 DUP ('STACK ') ;512 BYTES
318MY_STACK_PTR LABEL WORD ;
319
320;*****************************************************************************
321; *
322; INTERNAL VARIABLES *
323; *
324;*****************************************************************************
325; $salut (4,22,26,36) ;AN000;
326; INPUT PARMETERS FROM INIT SUBROUTINE:
327
328S_OWNER_SAVED DB 0 ;DRIVE LETTER THAT OWNED SOUCE DRIVE OWNERSHIP
329T_OWNER_SAVED DB 0 ;
330
331RECOMMENDED_BYTES_SECTOR DW 0 ;RECOMMENED BYTES/SECTOR FROM DEVICE PARA
332SOURCE_DRIVE DB 0 ;SOURCE DRIVE ID: 1=DRV A, 2=DRV B ETC.
333TARGET_DRIVE DB 0 ;TARGET DRIVE ID
334USER_OPTION DB 0 ;=1 OF /1 OPTION IS ENTERED
335COPY_TYPE DB 1 ;SINGLE DRV COPY=1, DOUBLE DRIVE COPY=2
336BUFFER_BEGIN DW 1000H ;BEGINNING OF BUFFER ADDR [IN SEGMENT]
337BUFFER_END DW 3FF0H ;END OF BUFFER ADDR [IN SEGMENT]
338S_DRV_SECT_TRACK DB ? ;SECT/TRACK, device informations.
339S_DRV_HEADS DB ? ;# OF HEADS
340S_DRV_TRACKS DB ? ;# OF TRACKS
341T_DRV_SECT_TRACK DB ? ;
342T_DRV_HEADS DB ? ;
343T_DRV_TRACKS DB ? ;
344
345;DEFAULT BPB FOR OLD MEDIA
346;5.25, 48 TPI BPB SINGLE SIDE (9 SECTORS/TRACK)
347BPB48_SINGLE DW 512 ;BYTES/SECTOR
348 DB 1 ;SECTOR/CLUSTER
349 DW 1 ;# OF RESERVED SECTORS
350 DB 2 ;# OF FATS
351 DW 40h ;# OF ROOT ENTRY
352 DW 168h ;TOTAL # OF SECTORS IN THE MEDIA
353 DB 0FCh ;MEDIA BYTE
354 DW 2 ;SECTORS/FAT
355
356;5.25, 48 TPI BPB DOUBLE SIDE (9 SECTORS/TRACK)
357BPB48_DOUBLE DW 512 ;BYTES/SECTOR
358 DB 2 ;SECTOR/CLUSTER
359 DW 1 ;# OF RESERVED SECTORS
360 DB 2 ;# OF FATS
361 DW 70h ;# OF ROOT ENTRY
362 DW 2D0h ;TOTAL # OF SECTORS IN THE MEDIA
363 DB 0FDh ;MEDIA BYTE
364 DW 2 ;SECTORS/FAT
365
366;5.25, 96 TPI BPB DOUBLE SIDE (15 SECTORS/TRACK)
367BPB96 DW 512 ;BYTES/SECTOR
368 DB 1 ;SECTOR/CLUSTER
369 DW 1 ;# OF RESERVED SECTORS
370 DB 2 ;# OF FATS
371 DW 0E0h ;# OF ROOT ENTRY
372 DW 960h ;TOTAL # OF SECTORS IN THE MEDIA
373 DB 0F9h ;MEDIA BYTE
374 DW 7 ;SECTORS/FAT
375BPB96_LENG EQU $-BPB96 ;THIS LENGTH WILL BE USED FOR BPB48 ALSO.
376
377; LOCAL VARIABLES:
378VOLSER_FLAG DB 0 ;AN000;0=EITHER MEDIA NOT READ YET, OR
379; SOURCE VOL SER ID NOT AVAILABLE
380; 1=TARGET NEEDS VOL SER WRITTEN
381SERIAL DD 0 ;AN013;SERIAL NUMBER OF NEW DISKETTE
382EXITFL DB EXOK ;AN000;ERRORLEVEL VALUE
383 PUBLIC EXITFL ;AN000;
384 PUBLIC EXPAR ;AN000;
385EXCBR EQU 2 ;AN000;CONTROL BREAK
386EXVER EQU 1 ;AN000;BAD DOS VERSION ERRORLEVEL CODE
387EXPAR EQU 1 ;AN000; BAD PARMS, OR OTHER ERRORS
388EXOK EQU 0 ;AN000;NORMAL ERRORLEVEL RET CODE
389
390S_DRV_SET_FLAG DB 0 ;1 = SOURCE DRIVE PARM HAD BEEN SET
391T_DRV_SET_FLAG DB 0 ;1 = TARGET DRIVE PARM HAD BEEN SET
392
393IOCTL_SECTOR DW 1 ;used for READ_A_SECTOR routine.
394IOCTL_TRACK DW 0 ;IN THE TRACK
395IOCTL_HEAD DW 0 ;HEAD 0
396SAV_CSECT DW 0 ;TEMPORARY SAVING PLACE
397SAV_CN1 DW 0 ;
398SAV_CB1 DW 0 ;
399SAV_CYLN DW 0 ;
400
401BOOT_SECT_TRACK DW 0 ;TEMP SAVING PLACE OF SECTOR/TRACK
402BOOT_TOT_TRACK DW 0 ;FOUND FROM THE BOOT SECTOR. max # of tracks
403BOOT_NUM_HEAD DW 0 ;NUMBER OF HEADS
404BOOT_BYTE_SECTOR DW 0 ;BYTES / SECTOR
405
406READ_S_BPB_FAILURE DB 0 ;GET MEDIA BPB. SUCCESS=0, FAILURE=1
407READ_T_BPB_FAILURE DB 0 ;
408
409;*** Informations from CHECK_SOURCE.
410;*** These will be used as a basis for the copy process.
411LAST_TRACK DB 79 ;LAST CYLINDER OF THE DASD (39 OR 79)
412END_OF_TRACK DB 15 ;END OF TRACK, 8,9 OR 15 CURRENTLY.
413bSECTOR_SIZE DW 512 ;BYTES/SECTOR in bytes
414NO_OF_SIDES DB ? ;0=SINGLE SIDED, 1=DOUBLE SIDED
415
416FORMAT_FLAG DB 0 ;(ON/OFF) FORMAT BEFORE WRITE IF TURNED ON
417TRACK_TO_READ DB 0 ;NEXT TRACK TO READ
418TRACK_TO_WRITE DB 0 ;NEXT TRACK TO WRITE
419TRACK_TO_FORMAT DB 0 ;STARTS FORMAT WITH THIS TRACK
420 ; TO THE LAST TRACK
421TRACK_SIZE DW ? ;BYTES/CYLINDER [IN SEGMENTS]
422SECTOR_SIZE DB ? ;BYTES/SECTOR [IN SEGMENTS]
423BUFFER_PTR DW ? ;BUFFER POINTER FOR READ/WRITE OP
424COPY_ERROR DB 0 ;=0 IF NO ERROR, >0 IF ERROR DETECTED
425SIDE DB ? ;NEXT SIDE TO READ/WRITE (0,1)
426SIDE_TO_FORMAT DB 0 ;NEXT SIDE TO FORMAT (0, 1)
427OPERATION DB ? ;READ/WRITE/VERIFY OPERATION
428COPY_STATUS DB ? ;(OK OR FATAL) ABORT COPY PROCESS IF FATAL
429USER_INPUT DB ? ;DISKCOPY AGAIN?
430IO_ERROR DB 0 ;SET BY EXTENDED_ERROR_HANDLER
431UKM_ERR DB 0 ;AN011;IF ON, HARD ERROR IS TYPE: "UNKNOWN MEDIA"
432MSG_FLAG DB ? ;USED TO INDICATE IF READ/WRITE ERROR MESSAGE
433 ;IS TO BE DISPLAYED (ON/OFF)
434TARGET_OP DB 0 ;FLAG TO INDICATE ANY OPERATIONS ON TARGET
435TRY_FORMAT_FLAG DB 0 ;FLAG TO INDICATE "TRY_FORMAT" PROCEDURE TO
436 ; CHECK THE "TIME OUT ERROR"
437TIME_OUT_FLAG DB 0 ;FLAG TO INDICATE THE "TIME OUT" ERROR
438 ; WAS A REAL "TIME OUT ERROR"
439SELECT_FLAG DB 0 ;INDICATES SELECT IS PRESENT
440 PAGE ;
441; DEVICE PARAMETER TABLE
442;the returned info. still has the following format.
443
444DS_IOCTL_DRV_PARM LABEL BYTE ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
445DS_specialFunctions db ? ;
446DS_deviceType db ? ;0 - 5.25"(48tpi), 1 - 5.25"(96tpi),
447 ; 2 - 3.5"(720KB)
448DS_deviceAttributes dw ? ;0001h - NOT REMOVABLE,
449 ; 0002h - CHANGE LINE SUPPORTED
450DS_numberOfCylinders dw ? ;
451DS_mediaType db ? ;
452DS_BPB_PTR LABEL BYTE ;
453DS_deviceBPB my_bpb <> ;
454DS_trackLayout LABEL WORD ;AC000;
455 my_trackLayout ;AC000;
456;---------------------------------------
457
458DT_IOCTL_DRV_PARM LABEL BYTE ;
459DT_specialFunctions db ? ;
460DT_deviceType db ? ;
461DT_deviceAttributes dw ? ;0001h - NOT REMOVABLE,
462 ; 0002h - CHANGE LINE SUPPORTED
463DT_numberOfCylinders dw ? ;
464DT_mediaType db ? ;
465DT_BPB_PTR LABEL BYTE ;
466DT_deviceBPB my_bpb <> ;
467DT_trackLayout LABEL WORD ;AC000;
468 my_trackLayout ;AC000;
469
470;---------------------------------------
471
472MS_IOCTL_DRV_PARM LABEL BYTE ;DRIVE PARM FROM SOURCE MEDIUM
473MS_specialFunctions db ? ;
474MS_deviceType db ? ;
475MS_deviceAttributes dw ? ;0001h - NOT REMOVABLE,
476 ; 0002h - CHANGE LINE SUPPORTED
477MS_numberOfCylinders dw ? ;
478MS_mediaType db ? ;
479MS_BPB_PTR LABEL BYTE ;
480MS_deviceBPB my_bpb <> ;
481MS_deviceBPB_leng equ $-MS_deviceBPB ;
482MS_trackLayout LABEL WORD ;AC000;
483 my_trackLayout ;AC000;
484;---------------------------------------
485MT_IOCTL_DRV_PARM LABEL BYTE ;DRIVE PARM FROM TARGET MEDIUM
486MT_specialFunctions db ? ;
487MT_deviceType db ? ;
488MT_deviceAttributes dw ? ;0001h - NOT REMOVABLE,
489 ; 0002h - CHANGE LINE SUPPORTED
490MT_numberOfCylinders dw ? ;
491MT_mediaType db ? ;
492MT_BPB_PTR LABEL BYTE ;
493MT_deviceBPB my_bpb <> ;
494MT_trackLayout LABEL WORD ;AC000;
495 my_trackLayout ;AC000;
496
497
498; IOCTL format a track function control string.
499IOCTL_FORMAT LABEL BYTE ;
500FspecialFunctions db 0 ;
501FHead dw ? ;
502FCylinder dw ? ;
503
504; IOCTL read/write a track.
505IOCTL_R_W LABEL BYTE ;
506specialFunctions db 0 ;
507Head dw ? ;
508Cylinder dw ? ;
509FirstSectors dw ? ;
510numberOfSectors dw ? ;
511TAddress_off dw ? ;
512TAddress_seg dw ? ;
513; = = = = = = = = = = = =
514; GET/SET MEDIA ID - FUNCTION OF GENERIC IOCTL
515; (USED BY VOLSER PROC)
516;(Deleted ;AN013;) MEDIA_ID_BUF A_MEDIA_ID_INFO <> ; ;AN000;
517; = = = = = = = = = = = =
518 PATHLABL DISKCOPY ;AN015;
519 HEADER <BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS> ;AN000;
520 PUBLIC DISKCOPY_BEGIN ;
521DISKCOPY_BEGIN LABEL NEAR ;
522
523;*****************************************************************************
524; *
525; D I S K C O P Y M A I N P R O G R A M *
526; *
527;*****************************************************************************
528; $salut (4,4,10,36) ;AN000;
529BEGIN PROC NEAR ;
530 PUBLIC BEGIN ;AN000;
531;OUTPUT - "EXITFL" HAS ERRORLEVEL RETURN CODE
532
533 MOV SP, OFFSET MY_STACK_PTR ;MOVE SP TO MY STACK PTR
534 CALL SYSLOADMSG ;AN000;INIT SYSMSG HANDLER
535
536; $IF C ;AN000;IF THERE WAS A PROBLEM
537 JNC $$IF1
538 CALL SYSDISPMSG ;AN000;LET HIM SAY WHY HE HAD A PROBLEM
539
540 MOV EXITFL,EXVER ;AN000;TELL ERRORLEVEL BAD DOS VERSION
541; $ELSE ;AN000;SINCE SYSDISPMSG IS HAPPY
542 JMP SHORT $$EN1
543$$IF1:
544 CALL INIT ;RUN INITIALIZATION ROUTINE
545
546 CMP DX,FINE ;CHECK FOR ERROR DURING INIT
547; $IF E ;IF NO ERROR THEN PROCEED TO COPY
548 JNE $$IF3
549; $DO ;
550$$DO4:
551 CALL COPY ;PERFORM DISKCOPY
552
553 CALL TEST_REPEAT ;COPY ANOTHER ?
554
555; $ENDDO C ;
556 JNC $$DO4
557 ;NORMAL RETURN CODE ALREADY IN "EXITFL"
558; $ELSE ;ELSE IF ERROR DETECTED IN INIT
559 JMP SHORT $$EN3
560$$IF3:
561.XLIST ;
562; PUSH DX
563; PUSH CS
564; CALL PRINTF ;DISPLAY ERROR MESSAGE
565.LIST ;
566 MOV DI,DX ;PASS NUMBER OF ERROR MSG, IF ANY ;AD000;
567 ;DI HAS OFFSET OF MESSAGE DESCRIPTOR
568 CALL SENDMSG ;AC000;DISPLAY THE ERROR MESSAGE
569
570 MOV EXITFL,EXVER ;AC000;ERROR RETURN CODE
571; $ENDIF ;
572$$EN3:
573 JMP SHORT EXIT_TO_DOS ;
574
575MAIN_EXIT: ;COME HERE AFTER CONTROL-BREAK
576 MOV EXITFL,EXCBR ;AC000; FOR CONTROL-BREAK EXIT
577
578EXIT_TO_DOS: ;
579 XOR BX, BX ;
580
581 MOV BL, S_OWNER_SAVED ;RESTORE ORIGINAL SOURCE,
582 ; TARGET DRIVE OWNER.
583 CALL SET_LOGICAL_DRIVE ;
584
585 MOV BL, T_OWNER_SAVED ;
586 CALL SET_LOGICAL_DRIVE ;
587
588 CMP S_DRV_SET_FLAG, 0 ;
589; $IF NE ;AN000;
590 JE $$IF8
591 MOV BL, SOURCE_DRIVE ;
592 MOV DS_specialFunctions, SET_SP_FUNC_DOS ;=0
593 MOV DX, OFFSET DS_IOCTL_DRV_PARM ;
594 CALL SET_DRV_PARM_DEF ;RESTORE SOURCE DRIVE PARM
595
596; $ENDIF ;AN000;
597$$IF8:
598
599 CMP T_DRV_SET_FLAG, 0 ;
600; $IF NE ;AN000;
601 JE $$IF10
602 MOV BL, TARGET_DRIVE ;
603 MOV DT_specialFunctions, SET_SP_FUNC_DOS ;=0
604 MOV DX, OFFSET DT_IOCTL_DRV_PARM ;
605 CALL SET_DRV_PARM_DEF ;RESTORE TARGET DRIVE PARM
606
607; $ENDIF ;AN000;
608$$IF10:
609EXIT_PROGRAM: ;
610
611; $ENDIF ;AN000;OK WITH SYSDISPMSG?
612$$EN1:
613 MOV AL,EXITFL ;AN000;PASS BACK ERRORLEVEL RET CODE
614 DOSCALL RET_CD_EXIT ;AN000;RETURN TO DOS WITH RET CODE
615
616 INT 20H ;AN000;IF ABOVE NOT WORK,
617BEGIN ENDP ;AN000;
618; = = = = = = = = = = = = = = = = =
619 HEADER <SET_LOGICAL_DRIVE - SET LOG. DRV LETTER THAT OWNS DRIVE> ;AN000;
620 PUBLIC SET_LOGICAL_DRIVE ;
621;*****************************************************************************
622SET_LOGICAL_DRIVE PROC NEAR ;
623; *** SET THE LOGICAL DRIVE LETTER THAT WILL BE THE OWNER OF THE DRIVE
624; INPUT: BL - DRIVE LETTER
625; OUTPUT: OWNER WILL BE SET ACCORDINGLY.
626;*****************************************************************************
627 CMP BL, 0 ;
628; $IF NE ;IF BL = 0, THEN JUST RETURN
629 JE $$IF13
630 ;ELSE SET BL AS AN OWNER OF THAT DRIVE
631 MOV AX,(IOCTL_FUNC SHL 8)+SET_LOGIC_DRIVE ;AC000;
632 INT 21H ;
633; $ENDIF ;
634$$IF13:
635 RET ;
636SET_LOGICAL_DRIVE ENDP ;
637; = = = = = = = = = = = =
638 HEADER <COPY - COPY THE DISKETTE IMAGE> ;AN000;
639;*****************************************************************************
640;MODULE NAME: COPY *
641; *
642; INPUT: COPY_TYPE BYTE 1=SINGLE DRIVE COPY *
643; 2=DOUBLE DRIVE COPY *
644; *
645; OUTPUT: NONE *
646;*****************************************************************************
647COPY PROC NEAR ;COPY DISKETTE IMAGE
648 MOV VOLSER_FLAG,0 ;AN000;RESET MEDIA ID VOL SERIAL NUMBER FLAG
649 MOV COPY_ERROR,0 ;RESET COPY ERROR FLAG
650 MOV COPY_STATUS,OK ;RESET COPY STATUS BYTE
651 MOV TARGET_OP, OFF ;
652 MOV TRY_FORMAT_FLAG, OFF ;
653 MOV TIME_OUT_FLAG, OFF ;
654 MOV FORMAT_FLAG,OFF ;ASSUME FORMAT IS NOT REQUIRED
655 MOV READ_S_BPB_FAILURE, 0 ;RESET GET BPB FAILURE FLAG
656 MOV READ_T_BPB_FAILURE, 0 ;
657 MOV AX, RECOMMENDED_BYTES_SECTOR ;
658 MOV bSECTOR_SIZE, AX ;USE RECOMMENDED SECTOR SIZE TO READ A SECTOR
659 CMP COPY_TYPE,2 ;IF TWO DRIVE COPY
660; $IF E ;
661 JNE $$IF15
662 PRINT MSGNUM_LOAD_SOURCE ;AC000;OUTPUT LOAD SOURCE DISKETTE MESSAGE
663 ;"INSERT SOURCE DISKETTE INTO DRIVE X:"
664
665 PRINT MSGNUM_LOAD_TARGET ;AC000;"INSERT TARGET DISKETTE INTO DRIVE X:"
666
667 CALL PRESS_ANY_KEY ;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB)
668
669; $ENDIF ;
670$$IF15:
671 MOV TRACK_TO_READ,0 ;INITIALIZE TRACK NUMBERS
672 MOV TRACK_TO_WRITE,0 ;
673
674COPY_TEST_END: ;
675; $SEARCH ;
676$$DO17:
677 MOV AL,TRACK_TO_WRITE ;WHILE TRACK_TO_WRITE<=LAST_TRACK
678 CMP AL,LAST_TRACK ;
679; $LEAVE A ;
680 JA $$EN17
681 CALL READ_SOURCE ;READ AS MANY TRACK AS POSSIBLE
682
683 CMP COPY_STATUS,FATAL ;MAKE SURE DRIVES WERE COMPATIBLE
684; $EXITIF E,NUL,OR ;
685 JE $$SR17
686 CALL WRITE_TARGET ;WRITE THE CONTENT OF BUFFER TO TARGET
687
688 CMP COPY_STATUS,FATAL ;MAKE SURE TARGET AND SOURCE
689; $EXITIF E,NUL ;
690 JE $$SR17
691; $ENDLOOP ;
692 JMP SHORT $$DO17
693$$EN17:
694
695 CMP COPY_ERROR,FALSE ;IF ERROR IN COPY
696; $IF NE ;
697 JE $$IF21
698 ;CR,LF,"Target diskette may be unusable",CR,LF
699 PRINT MSGNUM_TARGET_MB_UNUSABLE ;AC000;
700
701; $ENDIF ;
702$$IF21:
703; $ENDSRCH ;
704$$SR17:
705 CMP COPY_STATUS,FATAL ;WAS COPY ABORTED ?
706; $IF E ;
707 JNE $$IF24
708 ;CR,LF,"Copy process ended",CR,LF
709 PRINT MSGNUM_FATAL_ERROR ;AC000;IF SO THEN TELL USER
710
711; $ELSE ;AN000;SINCE NOT ABORTED,
712 JMP SHORT $$EN24
713$$IF24:
714 CALL WRITE_VOLSER ;AN000;GO CHANGE VOLID OF TARGET
715
716; $ENDIF ;
717$$EN24:
718 RET ;
719
720COPY ENDP ;
721; = = = = = = = = = = = =
722 HEADER <TEST_REPEAT - SEE IF USER WANTS TO COPY ANOTHER> ;AN000;
723;*****************************************************************************
724; *
725 PUBLIC TEST_REPEAT ;AN000;MAKE ENTRY IN LINK MAP
726TEST_REPEAT PROC NEAR ;TEST IF USER WANTS TO COPY ANOTHER *
727; DISKETTE *
728; INPUT : USER_INPUT ("Y" OR "N")
729; OUTPUT: NC = COPY AGAIN *
730; CY = EXIT TO DOS *
731;*****************************************************************************
732; $SEARCH COMPLEX ;AC000;REPEAT THIS PROMPT UNTIL (Y/N) RESPONDED
733 JMP SHORT $$SS27
734$$DO27:
735 PRINT MSGNUM_CR_LF ;AC000;
736
737; $STRTSRCH ;AN000;
738$$SS27:
739 ;CR,LF,"Copy another diskette (Y/N)?"
740 PRINT MSGNUM_COPY_ANOTHER ;AC000;SEE IF USER WANTS TO COPY ANOTHER
741 ; AND READ RESPONSE TO AL
742 PUSH AX ;AN000;SAVE THE RESPONSE
743 PRINT MSGNUM_CR_LF ;AC000;
744
745 POP DX ;AN000;RESTORE THE REPONSE CHAR TO DL
746 CALL YESNO ;AN000;CHECK FOR (Y/N)
747 ;AX=0,NO; AX=1,YES; AX=2,INVALID
748; $EXITIF C,NUL ;AN000;IF CARRY SET, PROBLEM,PRETEND "NO"
749 JC $$SR27
750
751 CMP AX,BAD_YESNO ;AN000;WAS THE RESPONSE INVALID?
752; $ENDLOOP B ;AN000;QUIT IF OK ANSWER (AX=0 OR 1)
753 JNB $$DO27
754 CMP AL,YES ;AN000;WAS "YES" SPECIFIED
755; $IF E ;AN000;IF "YES"
756 JNE $$IF31
757 CLC ;AN000;CLEAR CARRY TO INDICATE COPY AGAIN
758; $ELSE ;AN000;SINCE NOT "YES"
759 JMP SHORT $$EN31
760$$IF31:
761 STC ;AN000;SET CARRY TO INDICATE NO REPEAT
762; $ENDIF ;AN000;
763$$EN31:
764; $ENDSRCH ;AN000;
765$$SR27:
766.XLIST ;
767; MOV AL,USER_INPUT
768; AND AL,11011111B ;MAKE USER INPUT UPPER CASE
769; CMP AL,YES ;IF YES THEN COPY AGAIN
770; $EXITIF E
771; CLC ;CLEAR CARRY TO INDICATE COPY AGAIN
772; $ORELSE
773; CMP AL,NO ;IF NOT "N" OR "Y" THEN PROMPT AGAIN
774; $ENDLOOP E
775; STC ;SET CARRY TO INDICATE NO REPEAT
776; $ENDSRCH
777.LIST ;
778 RET ;
779
780TEST_REPEAT ENDP ;
781; = = = = = = = = = = = =
782 HEADER <READ_SOURCE - READ FROM SOURCE AS MUCH AS POSSIBLE> ;AN000;
783;*****************************************************************************
784; *
785 PUBLIC READ_SOURCE ;AN000;MAKE ENTRY IN LINK MAP *
786READ_SOURCE PROC NEAR ;READ AS MANY TRACKS AS POSSIBLE FROM SOURCE*
787; ;DISKETTE TO FILL THE AVAILABLE BUFFER SPACE *
788;*****************************************************************************
789
790 CMP COPY_TYPE,1 ;IF SINGLE DRIVE COPY
791; $IF E ;PROMPT MSG
792 JNE $$IF35
793 PRINT MSGNUM_LOAD_SOURCE ;AN000;"INSERT SOURCE DISKETTE INTO DRIVE X:"
794
795 CALL PRESS_ANY_KEY ;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB)
796
797; $ENDIF ;
798$$IF35:
799 CMP TRACK_TO_READ,0 ;1ST TRACK ?
800; $IF NE,OR ;IF NOT
801 JNE $$LL37
802
803 CALL CHECK_SOURCE ;DO NECESSARY CHECKING
804
805 CALL CALC_TRACK_SIZE ;
806
807 CALL CHECK_MEMORY_SIZE ;
808
809 CMP COPY_STATUS,FATAL ;
810; $IF NE ;
811 JE $$IF37
812$$LL37:
813;(deleted ;AN013;) CALL READ_VOLSER ;GO READ THE MEDIA ID TO GET SERIAL NUMBER ;AN000;
814
815 MOV BX,BUFFER_BEGIN ;
816 MOV BUFFER_PTR,BX ;INITIALIZE BUFFER POINTER
817
818; $DO ;
819$$DO38:
820 MOV AL,TRACK_TO_READ ;DID WE FINISH READING ALL TRACKS?
821 CMP AL,LAST_TRACK ;
822; $LEAVE A ;
823 JA $$EN38
824 MOV AX,BUFFER_PTR ;DID WE RUN OUT OF BUFFER SPACE
825 ADD AX,TRACK_SIZE ;
826 CMP AX,BUFFER_END ;
827; $LEAVE A ;
828 JA $$EN38
829 MOV OPERATION,READ_FUNC ;
830 CALL READ_WRITE_TRACK ;NO, GO READ ANOTHER TRACK
831
832 INC TRACK_TO_READ ;
833; $ENDDO ;
834 JMP SHORT $$DO38
835$$EN38:
836; $ENDIF ;
837$$IF37:
838 RET ;
839READ_SOURCE ENDP ;
840; = = = = = = = = = = = =
841 HEADER <WRITE_TARGET - WRITE DATA FROM MEMORY TO TARGET DISKETTE> ;AN000;
842;*****************************************************************************
843; *
844 PUBLIC WRITE_TARGET ;AN000;MAKE ENTRY IN LINK MAP
845WRITE_TARGET PROC ;WRITE DATA FROM MEMORY TO TARGET DISKETTE*
846; *
847;*****************************************************************************
848
849 CMP COPY_TYPE,1 ;IF SINGLE DRIVE COPY
850; $IF E ;PROMPT MSG
851 JNE $$IF43
852 PRINT MSGNUM_LOAD_TARGET ;AC000;"INSERT TARGET DISKETTE INTO DRIVE X:"
853
854 CALL PRESS_ANY_KEY ;AC000;"PRESS ANY KEY TO CONTINUE" (WAIT FOR KEYB)
855
856; $ENDIF ;
857$$IF43:
858 MOV TARGET_OP, ON ;INDICATE A OPERATION ON TARGET
859 MOV BX,BUFFER_BEGIN ;
860 MOV BUFFER_PTR,BX ;INITIALIZE BUFFER POINTER
861 CMP TRACK_TO_WRITE,0 ;IF TRK 0, CHECK COMPATIBILITY
862; $IF NE,OR ;
863 JNE $$LL45
864
865 MOV SIDE, 0 ;
866 CALL CHECK_TARGET ;
867
868 CMP COPY_STATUS,FATAL ;IF INCOMPATIBLE, THEN EXIT
869; $IF NE ;
870 JE $$IF45
871$$LL45:
872
873; $DO ;
874$$DO46:
875 MOV AL,TRACK_TO_WRITE ;DID WE FINISH WRITING ALL TRACKS?
876 CMP AL,LAST_TRACK ;
877; $LEAVE A ;
878 JA $$EN46
879 MOV AX,BUFFER_PTR ;DID WE RUN OUT OF BUFFER SPACE
880 ADD AX,TRACK_SIZE ;
881 CMP AX,BUFFER_END ;
882; $LEAVE A ;
883 JA $$EN46
884 MOV OPERATION,WRITE_FUNC ;
885 CALL READ_WRITE_TRACK ;NO, GO WRITE ANOTHER TRACK
886
887 CMP COPY_STATUS,FATAL ;IF INCOMPATIBLE, THEN EXIT
888; $LEAVE E ;
889 JE $$EN46
890 INC TRACK_TO_WRITE ;
891; $ENDDO ;
892 JMP SHORT $$DO46
893$$EN46:
894; $ENDIF ;
895$$IF45:
896 MOV TARGET_OP, OFF ;
897 RET ;
898WRITE_TARGET ENDP ;
899; = = = = = = = = = = = =
900 HEADER <READ_WRITE_TRACK - READ A TRACK AND STORE IT INTO MEMORY> ;AN000;
901;*****************************************************************************
902; *
903 PUBLIC READ_WRITE_TRACK ;AN000;MAKE ENTRY IN LINK MAP
904READ_WRITE_TRACK PROC NEAR ;READ A TRACK AND STORE IT INTO MEMORY *
905; *
906;INPUT: OPERATION = 61h THEN READ OPERATION *
907; 41h THEN WRITE OPERATION *
908;*****************************************************************************
909
910 MOV SIDE, 0 ;
911; $DO ;
912$$DO52:
913 MOV MSG_FLAG, ON ;
914 CMP OPERATION, READ_FUNC ;
915; $IF E ;
916 JNE $$IF53
917 CALL READ_OP ;
918
919; $ELSE ;
920 JMP SHORT $$EN53
921$$IF53:
922 CALL WRITE_OP ;
923
924 CMP COPY_STATUS, FATAL ;
925 JE RWT_EXIT ;
926
927; $ENDIF ;
928$$EN53:
929 CMP NO_OF_SIDES, 0 ;SINGLE SIDE COPY?
930; $IF E ;YES
931 JNE $$IF56
932 MOV AX, TRACK_SIZE ;
933; $ELSE ;NO, DOUBLE SIDE
934 JMP SHORT $$EN56
935$$IF56:
936 XOR DX, DX ;
937 MOV AX, TRACK_SIZE ;
938 MOV CX, 2 ;
939 DIV CX ;AX / 2
940; $ENDIF ;
941$$EN56:
942 ADD BUFFER_PTR, AX ;
943 INC SIDE ;NEXT SIDE
944 MOV AL, SIDE ;
945 CMP AL, NO_OF_SIDES ;FINISHED WITH THE LAST SIDE?
946; $ENDDO G ;
947 JNG $$DO52
948RWT_EXIT: ;
949 RET ;
950READ_WRITE_TRACK ENDP ;
951; = = = = = = = = = = = =
952 HEADER <READ_OP - IOCTL READ A TRACK OPERATION> ;AN000;
953;*****************************************************************************
954; *
955 PUBLIC READ_OP ;AN000;MAKE ENTRY IN LINK MAP
956READ_OP PROC NEAR ;IOCTL READ A TRACK OPERATION *
957; *
958;*****************************************************************************
959
960; $SEARCH ;
961$$DO60:
962 XOR AX, AX ;
963 MOV AL, SIDE ;
964 MOV Head, AX ;HEAD TO READ
965 MOV AL, TRACK_TO_READ ;
966 MOV Cylinder, AX ;TRACK TO READ
967 MOV FirstSectors, 0 ;???? SHOULD BE 1 BUT CURRENTLY 0 ???
968 MOV AX, BUFFER_PTR ;
969 MOV Taddress_seg, AX ;BUFFER ADDRESS
970 MOV Taddress_off, 0 ;
971 XOR BX, BX ;
972 MOV BL, SOURCE_DRIVE ;
973 MOV CL, READ_FUNC ;=61h
974 MOV DX, OFFSET IOCTL_R_W ;
975 CALL GENERIC_IOCTL ;
976
977 CMP IO_ERROR, NO_ERROR ;OK?
978; $EXITIF E ;AC013;IF NO ERROR SO FAR, GOOD
979 JNE $$IF60
980 CMP CYLINDER,0 ;AN013;IS THIS THE FIRST READ?
981; $IF E,AND ;AN013;IF THIS IS THE FIRST TRACK, AND
982 JNE $$IF62
983 CMP HEAD,0 ;AN013;IS THIS THE FIRST SIDE?
984; $IF E ;AN013;AND IF THIS IS THE FIRST SIDE
985 JNE $$IF62
986 CALL MAYBE_ADJUST_SERIAL ;AN013;IF BOOT HAS SERIAL, GENERATE NEW ONE
987
988; $ENDIF ;AN013;FIRST TRACK AND HEAD?
989$$IF62:
990; $ORELSE ;AN013;SINCE SOME KIND OF ERROR, OOPS
991 JMP SHORT $$SR60
992$$IF60:
993 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
994; $ENDLOOP NE ;
995 JE $$DO60
996
997 CMP MSG_FLAG, ON ;ELSE HARD ERROR. SEE IF
998 ; MESSAGE TO BE DISPLAYED
999; $IF E ;
1000 JNE $$IF66
1001
1002 MOV AH, READ_FUNC ;
1003 mov dl, source_drive ;
1004 CALL ERROR_MESSAGE ;
1005
1006 INC COPY_ERROR ;INCREASE COPY_ERROR COUNT
1007 MOV MSG_FLAG, OFF ;
1008; $ENDIF ;
1009$$IF66:
1010; $ENDSRCH ;
1011$$SR60:
1012 RET ;
1013READ_OP ENDP ;
1014; = = = = = = = = = = = =
1015 HEADER <MAYBE_ADJUST_SERIAL - MAKE NEW SERIAL IN BOOT> ;AN013;
1016MAYBE_ADJUST_SERIAL PROC NEAR ;AN013;
1017;INPUT: TADDRESS_OFF/_SEG HAS TRACK BUFFER WHICH HAS BOOT RECORD
1018; "VOLSER_FLAG" IS FALSE.
1019;OUTPUT:SERIAL NUMBER FIELD IS MODIFIED TO HAVE NEW SERIAL NUMBER
1020; A COPY OF WHICH IS PRESERVED IN "SERIAL" FOR LATER DISPLAY IN MSG.
1021; "VOLSER_FLAG" SET TO TRUE TO INDICATE NEW SERIAL GENERATED.
1022; IF THIS BOOT DOES NOT HAVE A SERIAL, NO CHANGE MADE, AND
1023; "VOLSER_FLAG" LEFT AS FALSE.
1024
1025; A BOOT RECORD IS ASSUMED TO HAVE A SERIAL NUMBER IF:
1026; EBPB_MEDIADESCRIPTOR=0F?H AND EXT_BOOT_SIG IS EITHER 28H OR 29H.
1027
1028 PUSH ES ;AN013;SAVE EXTRA SEG REG TEMPORARILY
1029 PUSH BX ;AN013;AND SAVE THE BASE POINTER
1030 PUSH SI ;AN013; AND THE INDEX
1031 LES BX,DWORD PTR TADDRESS_OFF ;AN013;POINT TO BUFFER AREA CONTAINING BOOT RECORD
1032 LEA SI,ES:[BX].EXT_BOOT_BPB ;AN013;POINT TO BPB PORTION OF BOOT RECORD
1033 MOV AL,ES:[SI].EBPB_MEDIADESCRIPTOR ;AN013;GET TYPE OF MEDIA
1034 AND AL,0F0H ;AN013;SAVE LEFT NIBBLE ONLY
1035 CMP AL,0F0H ;AN013;IF DISKETTE HAS PROPER DESCRIPTOR
1036; $IF E ;AN013;IF OK DESCRIPTOR
1037 JNE $$IF69
1038 MOV AL,ES:[BX].EXT_BOOT_SIG ;AN013;GET "SIGNATURE" OF BOOT RECORD
1039 CMP AL,28H ;AN013;IS THIS BOOT STYLE OF OS/2 1.0 OR 1.1?
1040; $IF E,OR ;AN013;YES, IS A BOOT WITH A SERIAL IN IT
1041 JE $$LL70
1042 CMP AL,29H ;AN013;IS THIS A BOOT STYLE OF OS/S 1.2?
1043; $IF E ;AN013;YES, IS A BOOT WITH A SERIAL IN IT
1044 JNE $$IF70
1045$$LL70:
1046; GET CURRENT DATE
1047 DOSCALL GET_DATE ;AN013;READ SYSTEM DATE
1048 ;OUTPUT: DL = DAY (1-31)
1049 ; AL = DAY OF WEEK (0=SUN,6=SAT)
1050 ; CX = YEAR (1980-2099)
1051 ; DH = MONTH (1-12)
1052 PUSH CX ;AN013;SAVE THESE FOR
1053 PUSH DX ;AN013; INPUT INTO HASH ALGORITHM
1054; GET CURRENT TIME
1055 DOSCALL GET_TIME ;AN013;READ SYSTEM TIME CLOCK
1056 ;OUTPUT: CH = HOUR (0-23)
1057 ; CL = MINUTES (0-59)
1058 ; DH = SECONDS (0-59)
1059 ; DL = HUNDREDTHS (0-99)
1060
1061; HASH THESE INTO A UNIQUE 4 BYTE NEW VOLUME SERIAL NUMBER:
1062; SERIAL+0 = DX FROM DATE + DX FROM TIME
1063; SERIAL+2 = CX FROM DATE + CX FROM TIME
1064
1065 POP AX ;AN013;GET THE DX FROM DATE
1066 ADD AX,DX ;AN013;ADD IN THE DX FROM TIME
1067 MOV WORD PTR SERIAL,AX ;AN013;SAVE FIRST RESULT OF HASH
1068 MOV WORD PTR ES:[BX].EXT_BOOT_SERIAL,AX ;AN013;AND IN BOOT RECORD ITSELF
1069
1070 POP AX ;AN013;GET THE CX FROM DATE
1071 ADD AX,CX ;AN013;ADD IN THE CX FROM TIME
1072 MOV WORD PTR SERIAL+WORD,AX ;AN013;SAVE SECOND RESULT OF HASH
1073 MOV WORD PTR ES:[BX].EXT_BOOT_SERIAL+WORD,AX ;AN013;AND IN BOOT RECORD
1074
1075 MOV VOLSER_FLAG,TRUE ;AN013;REQUEST THE NEW VOL SERIAL NUMBER BE WRITTEN
1076
1077; $ENDIF ;AN013;BOOT HAVE SERIAL?
1078$$IF70:
1079; $ENDIF ;AN013;PROPER DESCRIPTOR?
1080$$IF69:
1081 POP SI ;AN013;RESTORE THE INDEX REG
1082 POP BX ;AN013;RESTORE THE BASE POINTER
1083 POP ES ;AN013;RESTORE EXTRA SEG REG
1084 RET ;AN013;RETURN TO CALLER
1085MAYBE_ADJUST_SERIAL ENDP ;AN013;
1086; = = = = = = = = = = = =
1087 HEADER <WRITE_OP - IOCTL WRITE A TRACK OPERATION> ;AN000;
1088;*****************************************************************************
1089; *
1090 PUBLIC WRITE_OP ;AN000;MAKE ENTRY IN LINK MAP
1091WRITE_OP PROC NEAR ;IOCTL WRITE A TRACK OPERATION *
1092; *
1093;*****************************************************************************
1094
1095WO_AGAIN: ;
1096; $SEARCH ;
1097$$DO73:
1098 XOR AX, AX ;
1099 MOV AL, SIDE ;
1100 MOV Head, AX ;HEAD TO WRITE
1101 MOV AL, TRACK_TO_WRITE ;
1102 MOV Cylinder, AX ;TRACK TO WRITE
1103 MOV FirstSectors, 0 ;???? SHOULD BE 1 BUT CURRENTLY 0 ???
1104 MOV AX, BUFFER_PTR ;
1105 MOV Taddress_seg, AX ;BUFFER ADDRESS
1106 MOV Taddress_off, 0 ;
1107 XOR BX, BX ;
1108 MOV BL, TARGET_DRIVE ;
1109 MOV CL, WRITE_FUNC ;= 41h
1110 MOV DX, OFFSET IOCTL_R_W ;
1111 CALL GENERIC_IOCTL ;
1112
1113 CMP IO_ERROR, NO_ERROR ;OK?
1114; $LEAVE E ;YES, SUCCESS. EXIT THIS ROUTINE
1115 JE $$EN73
1116
1117 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
1118 JE WO_AGAIN ;
1119 ;ELSE HARD ERROR
1120 ;WRITE FAILURE, LET'S TRY TO FORMAT.
1121 CMP FORMAT_FLAG, ON ;WAS THIS TRACK FORMATTED BEFORE?
1122; $EXITIF E ;YES, GIVE UP WRITING AND
1123 JNE $$IF73
1124 ; CHECK WHEN IT HAPPENDED.
1125 ;GIVE UP WRITING AND SHOW ERROR MESSAGE.
1126 INC COPY_ERROR ;INDICATE ERROR OCCURS DURING COPY.
1127 MOV AH, WRITE_FUNC ;
1128 mov dl, target_drive ;
1129 CALL ERROR_MESSAGE ;SHOW MESSAGE 'WRITE ERROR SIDE, TRACK...'
1130
1131 MOV MSG_FLAG, OFF ;
1132; $ORELSE ;ELSE TRY FORMAT AND TRY WRITE AGAIN
1133 JMP SHORT $$SR73
1134$$IF73:
1135
1136 ;CR,LF,"Formatting while copying",CR,LF
1137 PRINT MSGNUM_FORMATTING ;AN000;SHOW MESSAGE
1138
1139 MOV FORMAT_FLAG, ON ;FORMAT ALL TRACKS FROM THIS TRACK
1140 CALL FORMAT_ALL ;format all the rest of the tracks
1141
1142 CMP COPY_STATUS, FATAL ;
1143; $ENDLOOP E ;
1144 JNE $$DO73
1145$$EN73:
1146.XLIST ;
1147;this next is dead code, nobody calls WO_FATAL, so the move copy_status
1148;and the print not compatible msg should be removed, and just the JMP WO_EXIT
1149;will no longer be needed to skip stuff that is not there. Kiser
1150; JMP WO_EXIT ;AND EXIT THIS ROUTINE
1151;WO_FATAL:
1152; MOV COPY_STATUS, FATAL ;WE ARE GOING TO ABORT PROGRAM
1153; PRINT MSG_NOT_COMPATIBLE ;SHOW NOT COMPATIABLE MESSAGE
1154.LIST ;
1155; $ENDSRCH ;
1156$$SR73:
1157WO_EXIT: ;
1158 RET ;
1159
1160WRITE_OP ENDP ;
1161; = = = = = = = = = = = =
1162 HEADER <FORMAT_ALL - FORMATS ALL TRACKS TO END> ;AN000;
1163;*****************************************************************************
1164; *
1165 PUBLIC FORMAT_ALL ;AN000;MAKE ENTRY IN LINK MAP
1166FORMAT_ALL PROC NEAR ;
1167; *
1168;Format all tracks starting from TRACK_TO_WRITE to the end. *
1169;This routine will set MT_deviceBPB to that of MS_deviceBPB. *
1170;trackLayout had been all set correctly. *
1171;If error, then fail to diskcopy. *
1172;*****************************************************************************
1173
1174 MOV CX, MS_deviceBPB_leng ;set length of BPB
1175 MOV SI, OFFSET MS_deviceBPB ;
1176 MOV DI, OFFSET MT_deviceBPB ;
1177 REP MOVSB ;
1178 CALL CHK_MEDIATYPE ;set MT_mediaTYPE for FORMAT operation
1179
1180 MOV MT_specialFunctions, SET_SP_BF_FORM ;=00000101B
1181 MOV CL, SETDEVPARM ;=40h
1182 MOV DX, OFFSET MT_IOCTL_DRV_PARM ;
1183 XOR BX, BX ;
1184 mov bl, last_track ;patch 3/27/86 for 3.2 diskcopy. J.K.
1185 inc bl ;
1186 mov MT_numberOfCylinders, bx ;make sure target # of cyl.
1187 MOV BL, TARGET_DRIVE ;
1188 CALL GENERIC_IOCTL ;
1189
1190 JC FA_FATAL ;
1191
1192 MOV FspecialFunctions, STATUS_CHK ;check to see if the parameters set
1193 ;by "SET DEVICE PARM" func above are
1194 ; supported or not.
1195 MOV AX,(IOCTL_FUNC SHL 8)+GENERIC_IOCTL_CODE ;AC000;(440DH)
1196 MOV CH, MAJOR_CODE ;=8
1197 MOV CL, FORMAT_FUNC ;=42H
1198 XOR BX, BX ;
1199 MOV BL, TARGET_DRIVE ;
1200 MOV DX, OFFSET IOCTL_FORMAT ;result is in Fspecialfunction
1201 INT 21H ;0 - Thre is ROM support of AH=18h, INT 13h, and
1202 ; it is a valid combination
1203
1204 MOV AL, FspecialFunctions ;1 - No ROM support. 2 - There is ROM support,
1205 ; but invalid combination
1206 MOV FspecialFunctions, FORMAT_SP_FUNC ;restore specialfunction value
1207 CMP AL, 2 ;ROM support, but this combination is not valid?
1208 JE FA_FATAL ;
1209
1210 MOV AL, TRACK_TO_WRITE ;
1211 MOV TRACK_TO_FORMAT, AL ;
1212 MOV AL, SIDE ;
1213 MOV SIDE_TO_FORMAT, AL ;
1214 CMP AL, NO_OF_SIDES ;
1215 JE FA_SIDE_WHILE ;STARTS WITH THE OTHER SIDE TO FORMAT
1216
1217FA_TRACK_WHILE: ;
1218 MOV AL, LAST_TRACK ;
1219 CMP TRACK_TO_FORMAT, AL ;
1220 JA FA_DONE ;
1221
1222FA_SIDE_WHILE: ;
1223 MOV AL, NO_OF_SIDES ;
1224 CMP SIDE_TO_FORMAT, AL ;
1225 JA FA_NEXT_TRACK ;
1226
1227 CALL FORMAT_TRACK ;FORMAT THIS TRACK
1228
1229 CMP IO_ERROR, HARD_ERROR ;
1230 JNE FA_NEXT_SIDE ;
1231
1232 CMP SIDE_TO_FORMAT, 1 ;HARD ERROR AT SIDE 1?
1233 JNE FA_TARGET_BAD ;THEN ASSUME TARGET DISKETTE BAD
1234
1235 CMP TRACK_TO_FORMAT, 0 ;AT CYLINDER 0?
1236 JNE FA_TARGET_BAD ;
1237
1238 JMP FA_FATAL ;THEN, SOURCE IS TWO SIDED AND
1239 ; TARGET IS SINGLE SIDE DISKETTE
1240
1241FA_NEXT_SIDE: ;
1242 INC SIDE_TO_FORMAT ;
1243 JMP FA_SIDE_WHILE ;
1244
1245FA_NEXT_TRACK: ;
1246 MOV SIDE_TO_FORMAT, 0 ;RESET SIDE_TO_FORMAT
1247 INC TRACK_TO_FORMAT ;
1248 JMP FA_TRACK_WHILE ;
1249
1250FA_FATAL: ;
1251 MOV COPY_STATUS, FATAL ;WE ARE GOING TO ABORT PROGRAM
1252 ;"Drive types or diskette types"
1253 ;"not compatible"
1254 PRINT MSGNUM_NOT_COMPATIBLE ;AC000;SHOW NOT COMPATIBLE MESSAGE
1255
1256 JMP SHORT FA_DONE ;
1257
1258FA_TARGET_BAD: ;
1259 MOV COPY_STATUS, FATAL ;WE ARE GOING TO ABORT PROGRAM
1260 ;CR,LF,"TARGET diskette bad or incompatible"
1261 PRINT MSGNUM_BAD_TARGET ;AC000;SHOW TARGET BAD MESSAGE
1262
1263FA_DONE: ;
1264 XOR BX, BX ;
1265 MOV BL, TARGET_DRIVE ;
1266 MOV T_DRV_SET_FLAG, 1 ;INDICATE TARGET DRIVE PARM HAS BEEN SET
1267 MOV DX, OFFSET MT_IOCTL_DRV_PARM ;
1268 MOV MT_specialFunctions, SET_SP_FUNC_DEF ;
1269 CALL SET_DRV_PARM_DEF ;SET IT BACK FOR WRITING.
1270
1271 RET ;
1272FORMAT_ALL ENDP ;
1273; = = = = = = = = = = = =
1274 HEADER <FORMAT_TRACK - IOCTL FORMAT A TRACK> ;AN000;
1275;******************************************************************************
1276; SUBROUTINE NAME : FORMAT_TRACK - IOCTL FORMAT A TRACK *
1277; (BOTH SIDES IF 2-SIDED DSKT) *
1278; *
1279; INPUT : TRACK_TO_FORMAT *
1280; : SIDE BYTE 0, 1 (HEAD NUMBER) *
1281; : END_OF_TRACK BYTE 8, 9, 15 *
1282; : TARGET_DRIVE BYTE 1 = A, 2 = B, ETC *
1283; *
1284; OUTPUT : none. This routine does not report format error. *
1285; Write routine will detect the error consequently. *
1286; REGISTER(S) AFFECTED: *
1287;******************************************************************************
1288 PUBLIC FORMAT_TRACK ;AN000;MAKE ENTRY IN LINK MAP
1289FORMAT_TRACK PROC NEAR ;
1290
1291FT_AGAIN: ;
1292; $DO ;
1293$$DO79:
1294 XOR AX, AX ;
1295 MOV AL, SIDE_TO_FORMAT ;
1296 MOV FHead, AX ;HEAD TO FORMAT
1297 MOV AL, TRACK_TO_FORMAT ;
1298 MOV FCylinder, AX ;TRACK TO FORMAT
1299
1300 XOR BX, BX ;
1301 MOV BL, TARGET_DRIVE ;DRIVE TO FORMAT
1302 MOV CL, FORMAT_FUNC ;=42h
1303 MOV DX, OFFSET IOCTL_FORMAT ;
1304 CALL GENERIC_IOCTL ;
1305
1306 CMP IO_ERROR, SOFT_ERROR ;TRY FORMAT AGAIN?
1307 ; (DRIVE NOT READY OR WRITE PROTECTED)
1308; $ENDDO NE ;
1309 JE $$DO79
1310
1311 RET ;
1312FORMAT_TRACK ENDP ;
1313; = = = = = = = = = = = =
1314 HEADER <CHECK_SOURCE - CHECK SOURCE DISKETTE TYPE> ;AN000;
1315;*****************************************************************************
1316; *
1317 PUBLIC CHECK_SOURCE ;AN000;MAKE ENTRY IN LINK MAP
1318CHECK_SOURCE PROC NEAR ;CHECK SOURCE DISKETTE TYPE *
1319; SET END_OF_TRACK, LAST_TRACK *
1320; NO_OF_SIDES, bSECTOR_SIZE *
1321; ** this routine will call "Get dev parm" with "BUILD BPB BIT" on. If it *
1322; ** fails to get that info, then the source medium must be bad(vergin) or *
1323; ** below DOS 2.0 level diskette, and will jmp to the old logic. *
1324; ** For compatibility reasons (in case of non IBM formatted media), this *
1325; ** routine covers old diskcopy routines. But this will only supports
1326; ** 5.25" 48 tpi 8, 9 sectors, 40 tracks and 5.25" 96 tpi, 15 sectors, 80 tracks
1327; ** media. Other non IBM formatted media which are formatted differenty
1328; ** from those values will result in unpreditable copy process.
1329;*****************************************************************************
1330
1331; $DO ;
1332$$DO81:
1333 XOR BX, BX ;
1334 MOV BL, SOURCE_DRIVE ;
1335 MOV MS_specialFunctions, GET_SP_FUNC_MED ;=00000001b
1336 MOV CL, GETDEVPARM ;=60h
1337 MOV DX, OFFSET MS_IOCTL_DRV_PARM ;
1338 CALL GENERIC_IOCTL ;TRY TO GET MEDIA BPB INFO TOGETHER
1339 ;WITH DEFAULT DEVICE INFO.
1340 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
1341; $ENDDO NE ;
1342 JE $$DO81
1343
1344 CMP IO_ERROR, HARD_ERROR ;CANNOT GET MEDIA BPB?
1345 JE CS_OLD ;ASSUME OLD FORMATTED DISKETTE, FIRST.
1346
1347 cmp ms_deviceBPB.csect_track,0 ;patch 1/16/86
1348 je cs_old ;
1349
1350 cmp ms_deviceBPB.chead,0 ;cannot trust the info from dos
1351 je cs_old ;sanity check for divide by 0
1352
1353 MOV AX, MS_deviceBPB.CTOTSECT ;
1354 CWD ;CONVERT IT TO A DOUBLE WORD
1355 DIV MS_deviceBPB.CSECT_TRACK ;
1356 DIV MS_deviceBPB.CHEAD ;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
1357 CMP AL, T_DRV_TRACKS ;SOURCE MEDIA # OF TRACK > TARGET
1358 ; DEVICE # OF TRACKS?
1359 JA CS_FATAL ;THEN, NOT COMPATIBLE.
1360
1361 DEC AX ;DECREASE BY 1 FOR THE USE OF THIS PROGRAM.
1362 MOV LAST_TRACK, AL ;SET LAST_TRACK
1363 MOV AX, MS_deviceBPB.CSECT_TRACK ;
1364 CMP AL, T_DRV_SECT_TRACK ;SOURCE MEDIA # OF SECT/TRACK > TARGET
1365 ; DEVICE # OF SECT/TRACK?
1366 JA CS_FATAL ;THEN, NOT COMPATIBLE
1367
1368 MOV END_OF_TRACK, AL ;
1369 MOV AX, MS_deviceBPB.CBYTE_SECT ;
1370 MOV bSECTOR_SIZE, AX ;set the sector size in bytes.
1371 CMP USER_OPTION, 1 ;
1372 JE CS_OPTION_1 ;
1373
1374 MOV AX, MS_deviceBPB.CHEAD ;HEAD=1, 2
1375 CMP AL, T_DRV_HEADS ;COMPARE SOURCE MEDIA SIDE WITH
1376 ; TARGET DRIVE HEAD NUMBER
1377 JA CS_FATAL ;SOURCE MEDIUM IS DOUBLE SIDED AND
1378 ; TARGET DRIVE IS SINGLE SIDED.
1379
1380 DEC AX ;
1381 MOV NO_OF_SIDES, AL ;NO_OF_SIDES=0, 1
1382 JMP CS_SET_TABLE ;
1383; = = = = = = = = = = =
1384CS_FATAL: ;
1385 MOV COPY_STATUS, FATAL ;
1386 ;CR,LF,"Drive types or diskette types",CR,LF
1387 ;"not compatible",CR,LF
1388 PRINT MSGNUM_NOT_COMPATIBLE ;AC000;
1389 JMP CS_EXIT ;
1390
1391; = = = = = = = = = = =
1392CS_BAD: ;
1393 MOV COPY_STATUS, FATAL ;
1394 PRINT MSGNUM_BAD_SOURCE ;CR,LF,"SOURCE diskette bad or incompatible"
1395
1396 JMP CS_EXIT ;
1397
1398; = = = = = = = = = = =
1399CS_OLD: ;
1400 MOV READ_S_BPB_FAILURE, 1 ;SET FLAG
1401 MOV bSECTOR_SIZE, 512 ;OLD SECTOR SIZE MUST BE 512 BYTES
1402 XOR BX, BX ;
1403 MOV BL, SOURCE_DRIVE ;
1404 MOV IOCTL_TRACK, 0 ;TRACK=0
1405 MOV IOCTL_SECTOR, 8 ;SECTOR=8
1406 MOV IOCTL_HEAD, 0 ;HEAD = 0
1407 CALL READ_A_SECTOR ;
1408
1409 JC CS_BAD ;SOURCE BAD
1410
1411 MOV IOCTL_SECTOR, 9 ;TRY TO READ SECTOR=9
1412 CALL READ_A_SECTOR ;
1413
1414 JC CS_SECT8 ;YES, 8 SECTORS. ASSUME 40 TRACKS
1415
1416 MOV IOCTL_SECTOR, 15 ;try to read sector=15
1417 CALL READ_A_SECTOR ;
1418
1419 JC CS_SECT9 ;**REMEMBER THIS ROUTINE DOES NOT COVER 3.5" MEDIA
1420
1421 JMP SHORT CS_SECT15 ;
1422
1423; = = = = = = = = = = =
1424CS_OPTION_1: ;
1425 MOV NO_OF_SIDES, 0 ;1 SIDE COPY
1426 JMP SHORT CS_SET_TABLE ;
1427
1428; = = = = = = = = = = =
1429CS_SECT15: ;
1430 MOV END_OF_TRACK, 15 ;ELSE END_OF_TRACK = 15
1431 MOV LAST_TRACK, 79 ;
1432 JMP SHORT CS_CHK_SIDE ;
1433
1434; = = = = = = = = = = =
1435CS_SECT8: ;
1436 MOV END_OF_TRACK, 8 ;SOURCE 8 SECTORS
1437 MOV LAST_TRACK, 39 ;ASSUME 40 TRACKS.
1438 JMP SHORT CS_CHK_SIDE ;
1439
1440; = = = = = = = = = = =
1441CS_SECT9: ;
1442 MOV END_OF_TRACK, 9 ;
1443 MOV LAST_TRACK, 39 ;ASSUME 5.25 DISKETTE
1444 JMP SHORT CS_CHK_SIDE ;
1445
1446; = = = = = = = = = = =
1447CS_CHK_SIDE: ;
1448 CMP USER_OPTION, 1 ;
1449 JE CS_OPTION_1 ;
1450
1451 MOV IOCTL_HEAD, 1 ;HEAD 1
1452 XOR AX, AX ;
1453 MOV AL, END_OF_TRACK ;READ MATCHING END_OF_TRACK
1454 ; OF THE OTHER SURFACE.
1455 MOV IOCTL_SECTOR, AX ;
1456 CALL READ_A_SECTOR ;
1457
1458 JC CS_OPTION_1 ;1 SIDED SOURCE
1459
1460 MOV NO_OF_SIDES, 1 ;2 SIDED SOURCE
1461 CMP T_DRV_HEADS, 2 ;SOUCE=2 SIDED MEDIUM. IS TARGET
1462 ; DOUBLE SIDED DRV?
1463 JE CS_SET_TABLE ;
1464
1465 JMP CS_FATAL ;NOT COMPATIBLE
1466
1467; = = = = = = = = = = =
1468CS_SET_TABLE: ;
1469 CMP READ_S_BPB_FAILURE, 1 ;DISKETTE WITHOUT BPB INFO?
1470; $IF E ;
1471 JNE $$IF83
1472 CALL SET_FOR_THE_OLD ;
1473
1474; $ENDIF ;
1475$$IF83:
1476 MOV BX, OFFSET MS_trackLayout ;SET TRACKLAYOUT OF SOURCE
1477 CALL SET_TRACKLAYOUT ;
1478
1479 MOV BX, OFFSET MT_trackLayout ;YES, ASSUME TARGET IS SAME
1480 CALL SET_TRACKLAYOUT ;
1481
1482 MOV S_DRV_SET_FLAG, 1 ;
1483 XOR BX, BX ;
1484 MOV BL, SOURCE_DRIVE ;
1485 MOV MS_specialFunctions, SET_SP_FUNC_DEF ;=00000100B
1486 MOV DX, OFFSET MS_IOCTL_DRV_PARM ;
1487 CALL SET_DRV_PARM_DEF ;NOW, SET SOURCE DRIVE PARM
1488 ; FOR READ OPERATION.
1489
1490 XOR AX, AX ;
1491 MOV AL, END_OF_TRACK ;
1492 MOV numberOfSectors, AX ;SET NUMBEROFSECTORS IN IOCTL_R_W TABLE
1493
1494 MOV AL, LAST_TRACK ;NOW, SHOW THE MESSAGE "COPYING ..."
1495 INC AL ;
1496.XLIST ;
1497; MOV BYTE PTR MSG_COPYING_PTR+2, AL ;HOW MANY TRACKS?
1498.LIST ;
1499 MOV BYTE PTR MSG_TRACKS, AL ;AC000;HOW MANY TRACKS?
1500
1501 MOV AL, END_OF_TRACK ;
1502.XLIST ;
1503; MOV BYTE PTR MSG_COPYING_PTR+4, AL ;HOW MANY SECTORS?
1504.LIST ;
1505 MOV BYTE PTR MSG_SECTRK,AL ;AC000;HOW MANY SECTORS?
1506
1507 MOV AL, NO_OF_SIDES ;TELL USER HOW MANY SIDE TO COPY
1508 INC AL ;
1509.XLIST ;
1510; MOV BYTE PTR MSG_COPYING_PTR+6, AL
1511.LIST ;
1512 MOV BYTE PTR MSG_SIDES,AL ;AC000;HOW MANY SIDES?
1513 ;CR,LF,"Copying %1 tracks",CR,LF
1514 ;"%2 Sectors/Track, %3 Side(s)",CR,LF
1515 PRINT MSGNUM_COPYING ;AC000;
1516
1517CS_EXIT: ;
1518 RET ;
1519
1520CHECK_SOURCE ENDP ;
1521; = = = = = = = = = = = =
1522 HEADER <READ_A_SECTOR - GET ONE SECTOR WITH IOCTL READ> ;AN000;
1523;******************************************************************************
1524 PUBLIC READ_A_SECTOR ;AN000;MAKE ENTRY IN LINK MAP
1525READ_A_SECTOR PROC NEAR ;
1526; *
1527;TRY TO READ A SECTOR USING IOCTL READ FUNCTION CALL. *
1528;THIS ROUTINE WILL STEAL "IOCTL_R_W" TABLE TEMPORARILY. *
1529;INPUT: BX - LOGICAL DRIVE NUMBER *
1530; IOCTL_SECTOR - SECTOR TO READ *
1531; IOCTL_TRACK - TRACK *
1532; IOCTL_HEAD - HEAD TO READ *
1533; bSECTOR_SIZE - SECTOR SIZE IN BYTES *
1534;OUTPUT: *
1535; IF NOT A SUCCESS, CARRY WILL BE SET *
1536; ALL REGISTORS SAVED *
1537;
1538;******************************************************************************
1539
1540 PUSH AX ;
1541 PUSH BX ;
1542 PUSH CX ;
1543 PUSH DX ;
1544
1545 MOV AX, numberOfSectors ;SAVE IOCTL_R_W TABLE VALUES
1546 MOV SAV_CSECT, AX ;
1547
1548;RAS_AGAIN:
1549; $DO ;
1550$$DO85:
1551 MOV AX, IOCTL_HEAD ;
1552 MOV Head, AX ;SURFACE TO READ
1553 MOV AX, IOCTL_TRACK ;
1554 MOV Cylinder, AX ;TRACK TO READ
1555 MOV AX, IOCTL_SECTOR ;
1556 dec ax ;????? currently
1557 ; firstsector=0 => 1st sector ????
1558 MOV FirstSectors, AX ;SECTOR TO READ
1559 MOV numberOfSectors, 1 ;read just one sector
1560 MOV AX, offset INIT ;READ IT INTO INIT
1561 ; (CURRELTLY, MAX 1K)
1562 MOV TAddress_off, AX ;
1563 MOV TAddress_seg, DS ;
1564 MOV CL, READ_FUNC ;
1565 MOV DX, OFFSET IOCTL_R_W ;POINTS TO CONTROL TABLE
1566 call generic_ioctl ;
1567
1568 CMP IO_ERROR, SOFT_ERROR ;TRY ONCE MORE?
1569; $ENDDO NE ;
1570 JE $$DO85
1571
1572 CMP IO_ERROR, HARD_ERROR ;HARD ERROR?
1573; $IF NE ;
1574 JE $$IF87
1575
1576 CLC ;READ SUCCESS
1577; $ELSE ;
1578 JMP SHORT $$EN87
1579$$IF87:
1580 STC ;SET CARRY
1581; $ENDIF ;
1582$$EN87:
1583 MOV AX, SAV_CSECT ;RESTORE ORIGINAL IOCTL_R_W TABLE
1584 MOV numberOfSectors, AX ;
1585 POP DX ;
1586 POP CX ;
1587 POP BX ;
1588 POP AX ;
1589 RET ;
1590
1591READ_A_SECTOR ENDP ;
1592; = = = = = = = = = = = =
1593 HEADER <CALC_TRACK_SIZE - GET MEM SIZE TO STORE ONE TRACK> ;AN000;
1594;*****************************************************************************
1595 PUBLIC CALC_TRACK_SIZE ;AN000;MAKE ENTRY IN LINK MAP
1596CALC_TRACK_SIZE PROC NEAR ;CALCULATE MEMORY SIZE REQUIRED TO STORE ONE
1597; TRACK (IN SEGMENTS) *
1598;
1599;CALCULATE SECTOR_SIZE IN PARA FROM bSECTOR_SIZE. IF bSECTOR_SIZE CANNOT BE *
1600;CHANGED TO SECTOR_SIZE IN PARA EXACTLY, THEN ADD 1 TO THE SECTOR_SIZE. *
1601;SECTOR_SIZE IS USED FOR MEMORY MANAGEMANT ONLY. THE ACTUAL COPY OR FORMAT *
1602;SHOULD BE DEPENDS ON bSECTOR_SIZE TO FIGURE OUT HOW BIG A SECTOR IS. *
1603;ALSO, CURRENTLY, THIS ROUTINE ASSUME A BSECTOR SIZE BE LESS THAN 0FFFh. *
1604;*****************************************************************************
1605
1606 PUSH AX ;
1607 PUSH BX ;
1608 PUSH CX ;
1609
1610 MOV AX, bSECTOR_SIZE ;
1611 MOV CL, 16 ;
1612 DIV CL ;AX / 16 = AL ... AH
1613 CMP AH, 0 ;NO REMAINER?
1614; $IF NE ;
1615 JE $$IF90
1616
1617 INC AL ;THERE REMAINER IS. INC AL
1618
1619; $ENDIF ;
1620$$IF90:
1621 MOV SECTOR_SIZE, AL ;SECTOR_SIZE+ IN PARA.
1622 MOV AL,NO_OF_SIDES ;TRACK_SIZE = (NO OF SIDES
1623 INC AL ; + 1)
1624 MUL END_OF_TRACK ; * END_OF_TRACK
1625 MOV BL,SECTOR_SIZE ; * SECTPR_SIZE
1626 MUL BL ;AMOUNT OF MEMORY REQUIRED (IN SEG)
1627 MOV TRACK_SIZE,AX ;TO STORE A TRACK
1628 POP CX ;
1629 POP BX ;
1630 POP AX ;
1631
1632 RET ;
1633CALC_TRACK_SIZE ENDP ;
1634; = = = = = = = = = = = =
1635 HEADER <CHECK_MEMORY_SIZE - VERIFY WE HAVE ENUF TO COPY 1 TRACK> ;AN000;
1636;*****************************************************************************
1637 PUBLIC CHECK_MEMORY_SIZE ;AN000;MAKE ENTRY IN LINK MAP
1638CHECK_MEMORY_SIZE PROC NEAR ;MAKE SURE WE HAVE ENOUGH TO COPY 1 TRACK INTO
1639; TO BUFFER ELSE ABORT COPY *
1640;*****************************************************************************
1641 MOV AX,BUFFER_END ;CALCULATE AVAILABLE MEMORY
1642 SUB AX,BUFFER_BEGIN ;IN SEGMENTS
1643 CMP AX,TRACK_SIZE ;DO WE HAVE ENOUGH TO STORE A CYLINDER?
1644; $IF B ;
1645 JNB $$IF92
1646 MOV COPY_STATUS,FATAL ;NO, ABORT COPY
1647 PRINT MSGNUM_UNSUF_MEMORY ;AC000;AND TELL USER WHY
1648
1649; $ENDIF ;
1650$$IF92:
1651 RET ;
1652
1653CHECK_MEMORY_SIZE ENDP ;
1654; = = = = = = = = = = = =
1655 HEADER <SET_FOR_THE_OLD - SET BPB FOR BEFORE-2.0 FMTTED MEDIA> ;AN000;
1656;*****************************************************************************
1657 PUBLIC SET_FOR_THE_OLD ;AN000;MAKE ENTRY IN LINK MAP
1658SET_FOR_THE_OLD PROC NEAR ;
1659
1660;set MS_deviceBPB for before-2.0 formatted media
1661;*****************************************************************************
1662 PUSH AX ;
1663
1664 CMP END_OF_TRACK,9 ;IF SECTORS/TRACK <= 9, THEN CHECK
1665 ;NO_OF_SIDES. IF SINGLE SIDE
1666 ; COPY THEN USE BPB48_SINGLE
1667 ;ELSE USE BPB48_DOUBLE.
1668; $IF A ;SECTORS/TRACK > 9 THEN USE BPB96 TABLE
1669 JNA $$IF94
1670 MOV SI, OFFSET BPB96 ;
1671; $ELSE ;
1672 JMP SHORT $$EN94
1673$$IF94:
1674 CMP NO_OF_SIDES, 0 ;SINGLE SIDE COPY?
1675; $IF NE ;IF NOT,
1676 JE $$IF96
1677 MOV SI, OFFSET BPB48_DOUBLE ;USE BPB48 DOUBLE
1678; $ELSE ;
1679 JMP SHORT $$EN96
1680$$IF96:
1681 MOV SI, OFFSET BPB48_SINGLE ;
1682; $ENDIF ;
1683$$EN96:
1684; $ENDIF ;
1685$$EN94:
1686 XOR AX, AX ;
1687 MOV AL, END_OF_TRACK ;
1688
1689 MOV MS_deviceBPB.CSECT_TRACK,AX ;SET # OF SECTORS IN IOCTL_DRV_PARM
1690 MOV DI, OFFSET MS_deviceBPB ;
1691 MOV CX, BPB96_LENG ;
1692 REP MOVSB ;OLD DEFAULT BPB INFO => MS_deviceBPB
1693
1694 POP AX ;
1695 RET ;
1696SET_FOR_THE_OLD ENDP ;
1697; = = = = = = = = = = = =
1698 HEADER <SET_TRACKLAYOUT - MOVE DATA TO TRACK IMAGE> ;AN000;
1699;*****************************************************************************
1700 PUBLIC SET_TRACKLAYOUT ;AN000;MAKE ENTRY IN LINK MAP
1701SET_TRACKLAYOUT PROC NEAR ;
1702
1703;INPUT: BX - POINTER TO DESTINATION
1704;*****************************************************************************
1705
1706 XOR CX, CX ;
1707 MOV CL, END_OF_TRACK ;
1708 MOV WORD PTR [BX], CX ;SET CSECT_F TO THE NUMBER OF
1709 ; SECTORS IN A TRACK
1710 ADD BX, 2 ;NOW BX POINTS TO
1711 ; THE FIRST SECTORNUMBER
1712 MOV CX, 1 ;
1713 MOV AX, bSECTOR_SIZE ;
1714
1715; $DO ;
1716$$DO100:
1717 CMP CL, END_OF_TRACK ;
1718; $LEAVE A ;
1719 JA $$EN100
1720
1721 MOV WORD PTR [BX], CX ;
1722 INC BX ;
1723 INC BX ;
1724 MOV WORD PTR [BX], AX ;
1725 INC BX ;
1726 INC BX ;
1727
1728 INC CX ;
1729; $ENDDO ;
1730 JMP SHORT $$DO100
1731$$EN100:
1732
1733 RET ;
1734SET_TRACKLAYOUT ENDP ;
1735; = = = = = = = = = = = =
1736 HEADER <CHECK_TARGET - READ TARGET BOOT RCD, NEEDS FORMAT?> ;AN000;
1737;*****************************************************************************
1738 PUBLIC CHECK_TARGET ;AN000;MAKE ENTRY IN LINK MAP
1739CHECK_TARGET PROC NEAR ; *
1740; ** THIS ROUTINE WILL TRY TO READ TARGET MEDIA BOOT RECORD. *
1741; ** IF A SUCCESS,THEN COMPARES BPB INFO WITH THAT OF SOURCE MEDIA. *
1742; ** IF THEY ARE DIFFERENT, THEN SET FORMAT_FLAG AND RETURN. *
1743; ** IF FAILED TO READ A BOOT, THEN TRY OLD LOGICS BEFORE DOS 3.2 FOR *
1744; ** COMPATIBILITY REASON. *
1745;*****************************************************************************
1746
1747; $DO ;
1748$$DO103:
1749 XOR BX, BX ;
1750 MOV BL, TARGET_DRIVE ;
1751 MOV MT_specialFunctions, GET_SP_FUNC_MED ;=00000001b
1752 MOV CL, GETDEVPARM ;=60h
1753 MOV DX, OFFSET MT_IOCTL_DRV_PARM ;
1754 CALL GENERIC_IOCTL ;TRY TO GET MEDIA BPB INFO TOGETHER
1755 ;WITH DEFAULT DEVICE INFO.
1756 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
1757; $ENDDO NE ;
1758 JE $$DO103
1759
1760 CMP IO_ERROR, HARD_ERROR ;CANNOT GET MEDIA BPB?
1761 JE CT_OLD ;ASSUME OLD FORMATTED DISKETTE, FIRST.
1762
1763 cmp mt_deviceBPB.csect_track,0 ;patch 1/16/86 for 3.2 diskcopy
1764 je ct_old ;
1765
1766 cmp mt_deviceBPB.chead,0 ;cannot belive the info from dos
1767 je ct_old ;sanity check for divide by 0.
1768
1769 MOV AX, MT_deviceBPB.CTOTSECT ;
1770 CWD ;CONVERT IT TO A DOUBLE WORD
1771 DIV MT_deviceBPB.CSECT_TRACK ;
1772 DIV MT_deviceBPB.CHEAD ;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
1773 DEC AX ;DECREASE BY 1 FOR THIS PROGRAM.
1774 CMP LAST_TRACK, AL ;COMPARE WITH THE LAST TRACK OF SOURCE
1775 JE CT_SECTOR_TRACK ;IF SAME, THEN CHECK SECTOR PER TRACK
1776 ;SINCE NOT THE SAME, CONTINUE...
1777
1778 CMP MT_deviceBPB.CSECT_TRACK,0FH ;AN012;IS TARGET 15 SEC / TRK?
1779 JNE CT_FORMAT ;AN012;NO, SOMETHING ELSE...
1780 ;YES, 15 SEC/TRACK, CONTINUE...
1781
1782 CMP LAST_TRACK,27H ;AN012;IS SOURCE ORIGINALLY 40 TRACK?
1783 JNE CT_FORMAT ;AN012;NO, SOMETHING ELSE...
1784 ;YES, 40 TRACK, CONTINUE...
1785 JMP CT_FATAL ;AN012;ABORT THIS, DO NOT MESS UP THE 1.2M
1786 ; WITH NOBLE ATTEMPTS TO FORMAT
1787CT_SECTOR_TRACK: ;
1788 MOV AX, MT_deviceBPB.CSECT_TRACK ;
1789 CMP END_OF_TRACK, AL ;
1790 JNE CT_FORMAT ;
1791
1792CT_BYTE_SECTOR: ;
1793 MOV AX, MT_deviceBPB.CBYTE_SECT ;
1794 CMP AX, bSECTOR_SIZE ;
1795 JNE CT_FORMAT ;
1796
1797CT_HEAD: ;
1798 MOV AX, MT_deviceBPB.CHEAD ;
1799 DEC AX ;
1800 CMP AL, NO_OF_SIDES ;
1801 JB CT_FORMAT ;IF TARGET SIDE < SOURCE SIDE
1802 ; THEN FORMAT IT.
1803
1804 JMP CT_SET_DRV ;TARGET IS O.K. SET DRIVE PARM
1805 ; AND EXIT
1806
1807CT_FORMAT: ;
1808 PRINT MSGNUM_FORMATTING ;AC000;"Formatting while copying"
1809
1810 MOV FORMAT_FLAG, ON ;
1811 CALL FORMAT_ALL ;FORMAT ALL TRACKS STARTING
1812 ; FROM TRACK_TO_WRITE
1813 JMP CT_EXIT ;
1814
1815CT_OLD: ;AC011;
1816 CMP UKM_ERR,ON ;AN011;IS THIS HARD ERROR "UNKNOWN MEDIA"?
1817 JE CT_FORMAT ;AN011; IF SO, GO TRY FORMATTING
1818 ;SAME OLD... ;AGAIN, THIS DOES
1819 ; NOT RECOGNIZE 3.5 MEDIA
1820 MOV READ_T_BPB_FAILURE, 1 ;SET THE FLAG
1821 XOR BX, BX ;
1822 MOV BL, TARGET_DRIVE ;
1823 MOV IOCTL_TRACK, 0 ;
1824 MOV IOCTL_SECTOR, 8 ;
1825 MOV IOCTL_HEAD, 0 ;TRY TO READ HEAD 0, TRACK 0, SECTOR 8
1826 CALL READ_A_SECTOR ;
1827
1828 JC CT_FORMAT ;ASSUME TARGET MEDIA NOT FORMATTED.
1829
1830 MOV IOCTL_SECTOR, 9 ;TRY TO READ SECTOR 9
1831 CALL READ_A_SECTOR ;
1832
1833 JC CT_8_SECTOR ;TARGET IS 8 SECTOR MEDIA
1834
1835 MOV IOCTL_SECTOR, 15 ;
1836 CALL READ_A_SECTOR ;
1837
1838 JC CT_9_SECTOR ;TARGET IS 9 SECTOR MEDIA
1839
1840;CT_15_SECTOR: ;TARGET IS 15 SECTOR MEDIA
1841 CMP END_OF_TRACK, 15 ;IS SOURCE ALSO 96 TPI?
1842 JNE CT_FATAL ;NO, FATAL ERROR
1843
1844 JMP CT_EXIT_OLD ;OK
1845
1846CT_8_SECTOR: ;
1847 CMP END_OF_TRACK, 15 ;
1848 JE CT_FATAL ;IF SOURCE IS 96 TPI, THEN FATAL ERROR
1849
1850 CMP END_OF_TRACK, 9 ;
1851 JE CT_FORMAT ;IF SOURCE IS 9 SECTOR, THEN
1852 ; SHOULD FORMAT TARGET
1853
1854 JMP CT_EXIT_OLD ;ELSE ASSUME SOURCE IS 8 SECTOR.
1855
1856CT_9_SECTOR: ;
1857 CMP END_OF_TRACK, 15 ;IS SOURCE 96 TPI ?
1858 JNE CT_EXIT_OLD ;NO. SOUCE IS 8 OR 9
1859 ; SECTORED 48 TPI DISKETTE
1860
1861CT_FATAL: ;
1862 MOV COPY_STATUS, FATAL ;
1863 ;"Drive types or diskette types"
1864 PRINT MSGNUM_NOT_COMPATIBLE ;AC000;"not compatible"
1865
1866 JMP SHORT CT_EXIT ;
1867
1868CT_EXIT_OLD: ;
1869 MOV CX, MS_deviceBPB_leng ;
1870 MOV SI, OFFSET MS_deviceBPB ;
1871 MOV DI, OFFSET MT_deviceBPB ;
1872 REP MOVSB ;set MT_deviceBPB to MS_deviceBPB
1873CT_SET_DRV: ;
1874 MOV T_DRV_SET_FLAG, 1 ;INDICATE THE TARGET DEFAULT
1875 ; DEVICE PARM HAS BEEN SET.
1876 XOR BX, BX ;
1877 mov bl, last_track ;patch for 3.2 diskcopy, 3/27/86 J.K.
1878 inc bl ;
1879 mov MT_numberOfCylinders, bx ;make sure the # of cyl of the target
1880 MOV BL, TARGET_DRIVE ;
1881 MOV DX, OFFSET MT_IOCTL_DRV_PARM ;
1882 MOV MT_specialFunctions, SET_SP_FUNC_DEF ;
1883 CALL SET_DRV_PARM_DEF ;
1884
1885CT_EXIT: ;
1886 RET ;
1887
1888CHECK_TARGET ENDP ;
1889; = = = = = = = = = = = =
1890 HEADER <CHK_MULTI_MEDIA - CHECK IF DRIVE IS MULTI-MEDIA> ;AN000;
1891;*****************************************************************************
1892 PUBLIC CHK_MULTI_MEDIA ;AN000;MAKE ENTRY IN LINK MAP
1893CHK_MULTI_MEDIA PROC NEAR ;
1894;IF THE SOURCE IS 96 TPI DISKETTE, AND TARGET IS 48 TPI
1895;DISKETTE, OR VICE VERSA, THEN SET THE CARRY BIT.
1896;THIS ROUTINE BE CALLED WHEN BPB INFORMATIONS OF TARGET HAS BEEN SUCCESSFULLY
1897;READ.
1898;*** CURRENTLY, ONLY 96 TPI DRIVE IN PC_AT CAN HAVE MULTI_MEDIA.
1899;INPUT: AX - TARGET MEDIA CYLINDER NUMBER - 1
1900; LAST_TRACK - SOURCE MEDIA CYLINDER NUMBER - 1
1901;*****************************************************************************
1902 CLC ;CLEAR CARRY
1903 CMP LAST_TRACK, 39 ;SOURCE IS 48 TPI MEDIA?
1904; $IF E,AND ;
1905 JNE $$IF105
1906 CMP AL, 79 ;AND TARGET IS 96 TPI MEDIA?
1907; $IF E ;
1908 JNE $$IF105
1909 STC ;THEN SET CARRY
1910; $ELSE ;
1911 JMP SHORT $$EN105
1912$$IF105:
1913 CMP LAST_TRACK, 79 ;SOURCE IS 96 TPI MEDIA?
1914; $IF E,AND ;
1915 JNE $$IF107
1916 CMP AL, 39 ;AND TARGET IS 48 TPI?
1917; $IF E ;
1918 JNE $$IF107
1919 STC ;
1920; $ENDIF ;
1921$$IF107:
1922; $ENDIF ;
1923$$EN105:
1924 RET ;
1925CHK_MULTI_MEDIA ENDP ;
1926; = = = = = = = = = = = =
1927 HEADER <SET_DRV_PARM_DEF - SET DRIVE PARMS VIA IOCTL> ;AN000;
1928;*****************************************************************************
1929 PUBLIC SET_DRV_PARM_DEF ;AN000;MAKE ENTRY IN LINK MAP
1930SET_DRV_PARM_DEF PROC NEAR ;
1931;SET THE DRV PARMAMETERS
1932;INPUT: BL - DRIVE NUMBER
1933; DX - POINTER TO THE DEFAULT PARAMETER TABLE
1934; specialfunc should be set before calling this routine
1935;*****************************************************************************
1936 MOV CL, SETDEVPARM ;=40H
1937 CALL GENERIC_IOCTL ;
1938
1939 RET ;
1940SET_DRV_PARM_DEF ENDP ;
1941; = = = = = = = = = = = =
1942 HEADER <CHK_MEDIATYPE - DETERMINE MEDIATYPE OF TARGET FOR FORMAT> ;AN000;
1943;*****************************************************************************
1944 PUBLIC CHK_MEDIATYPE ;AN000;MAKE ENTRY IN LINK MAP
1945CHK_MEDIATYPE PROC NEAR ;
1946;SET THE mediaType OF IOCTL_DRV_PARM FOR TARGET DRIVE IN CASE OF FORMAT.
1947;IF TARGET IS A MULTI-MEDIA DEVICE, mediaType SHOULD BE SET CORRECTLY
1948;TO FORMAT THE TARGET MEDIA.
1949;IF EITHER OF LAST_TRACK OR END_OF_TRACK IS LESS THAN THAT OF TARGET
1950;DRIVE, THEN mediaType WILL BE SET TO 1. OTHERWISE, IT WILL BE 0 FOR
1951;THE DEFAULT VALUE.
1952;*****************************************************************************
1953
1954 MOV AL, T_DRV_TRACKS ;TARGET DEVICE MAXIUM TRACKS
1955 DEC AL ;
1956 CMP LAST_TRACK, AL ;COMPARE SOURCE MEDIA # OF TRACKS TO IT
1957; $IF B,OR ;
1958 JB $$LL110
1959 MOV AL, T_DRV_SECT_TRACK ;
1960 CMP END_OF_TRACK, AL ;SOURCE # OF SECT/TRACK < TARGET DEVICE?
1961; $IF B ;
1962 JNB $$IF110
1963$$LL110:
1964 MOV MT_mediaType, 1 ;
1965; $ENDIF ;
1966$$IF110:
1967 RET ;
1968CHK_MEDIATYPE ENDP ;
1969; = = = = = = = = = = = =
1970 HEADER <GENERIC_IOCTL - COMMUNICATE WITH THE DEVICE DRIVER> ;AN000;
1971;*****************************************************************************
1972 PUBLIC GENERIC_IOCTL ;AN000;MAKE ENTRY IN LINK MAP
1973GENERIC_IOCTL PROC NEAR ;
1974;INPUT: CL - MINOR CODE; 60 - GET DEVICE PARM, 40 - SET DEVICE PARM
1975; 61 - READ TRACK, 41 - WRITE TRACK,
1976; 42 - FORMAT AND VERIFY TRACK, 43 - SET MEDIA ID
1977; 62 - VERIFY TRACK, 63 - GET MEDIA ID
1978; BL - LOGICAL DRIVE LETTER
1979; DS:DX - POINTER TO PARAMETERS
1980;*****************************************************************************
1981 MOV IO_ERROR, NO_ERROR ;reset io_error
1982 MOV CH, MAJOR_CODE ;MAJOR CODE, REMOVABLE = 08H
1983 DOSCALL IOCTL_FUNC,GENERIC_IOCTL_CODE ;AC000;(440DH) CALL THE DEVICE DRIVER
1984
1985; $IF C ;
1986 JNC $$IF112
1987 CALL EXTENDED_ERROR_HANDLER ;ERROR, SEE WHAT IT IS!
1988
1989; $ENDIF ;
1990$$IF112:
1991 RET ;
1992GENERIC_IOCTL ENDP ;
1993; = = = = = = = = = = = =
1994 HEADER <EXTENDED_ERROR_HANDLER - RESPOND TO DOS ERRORS> ;AN000;
1995;*****************************************************************************
1996 PUBLIC EXTENDED_ERROR_HANDLER ;AN000;MAKE ENTRY IN LINK MAP
1997EXTENDED_ERROR_HANDLER PROC NEAR ;
1998;INPUT: BL - LOGICAL DRIVE LETTER
1999;*****************************************************************************
2000
2001 PUSHF ;
2002 PUSH AX ;
2003 PUSH BX ;
2004 PUSH CX ;
2005 PUSH DX ;
2006 PUSH SI ;
2007 PUSH DI ;
2008 PUSH ES ;
2009 PUSH DS ;
2010 PUSH BX ;
2011
2012 MOV AH, EXTENDED_ERROR ;59H
2013 MOV BX, 0 ;
2014 INT 21H ;
2015
2016 POP BX ;RESTORE BL FOR DRIVE LETTER
2017 POP DS ;
2018 POP ES ;
2019
2020 CMP AX, 21 ;DRIVE NOT READY? (TIME_OUT ERROR?)
2021 JE EEH_CHK_TIMEOUT ;
2022
2023 CMP AX, 19 ;ATTEMP TO WRITE ON WRITE_PROTECTED?
2024 JE WARN_USER_2 ;
2025
2026 JMP EEH_HARD_ERROR ;OTHERWISE, HARD_ERROR
2027
2028EEH_CHK_TIMEOUT: ;BECAUSE OF THE INACCURACY
2029 ; OF TIME OUT ERROR,
2030 ;IN READING AND WRITING OPERATION,
2031 ; CHECK OUT CAREFULLY WITH "FORMAT"
2032 CMP FORMAT_FLAG, ON ;AFTER OR DURING FORMAT OPERATION,
2033 JE WARN_USER_1 ; TIME OUT ERROR IS
2034 ; ASSUMED TO BE CORRECT.
2035
2036 CMP TRY_FORMAT_FLAG, ON ;HAPPENED AT "TRY_FORMAT" PROCEDURE?
2037 JE EEH_TIMEOUT ;
2038
2039 CMP TARGET_OP, ON ;HAPPENED ON TARGET DRIVE?
2040 JNE WARN_USER_1 ;IF NOT, THEN ASSUME TIME OUT ERROR
2041
2042 MOV TRY_FORMAT_FLAG, ON ;
2043 CALL TRY_FORMAT ;JUST TRY TO FORMAT THE TRACK.
2044
2045 MOV TRY_FORMAT_FLAG, OFF ;
2046 CMP TIME_OUT_FLAG, ON ;REAL TIME OUT?
2047 JE WARN_USER_1 ;YES, A SOFT ERROR.
2048
2049 CMP IO_ERROR, SOFT_ERROR ;IT HAPPENED AT TRY_FORMAT PROC AND
2050 ; PC_AT WHEN THE DRIVE DOOR OPENED ABRUPTLY.
2051 JE EEH_EXIT ;IT WAS WRITE PROTECTED ERROR.
2052
2053 JMP EEH_HARD_ERROR ;NO, "ADDRESS MARK NOT OUT". A HARD ERROR.
2054
2055EEH_TIMEOUT: ;
2056 MOV TIME_OUT_FLAG, ON ;SET TIME_OUT_FLAG AND EXIT THIS ROUTINE
2057 JMP EEH_EXIT ;
2058
2059WARN_USER_1: ;
2060 MOV DRIVE_LETTER, 'A' ;
2061 DEC BL ;CHANGE LOGICAL TO PHYSICAL
2062 ADD DRIVE_LETTER, BL ;
2063 PRINT MSGNUM_GET_READY ;AC000;"Drive not ready - %0"
2064
2065 PRINT MSGNUM_CLOSE_DOOR ;AN004;"Make sure a diskette is inserted into
2066 ; the drive and the door is closed"
2067 JMP WAIT_FOR_USER ;
2068
2069WARN_USER_2: ;
2070 PRINT MSGNUM_WRITE_PROTECT ;AC000;"Attempt to write to write-protected diskette"
2071
2072WAIT_FOR_USER: ;
2073 ;"Press any key when ready . . ."
2074 CALL PRESS_ANY_KEY ;AC000; THEN WAIT FOR ANY RESPONSE
2075
2076 MOV IO_ERROR, SOFT_ERROR ;INDICATE THE CALLER TO TRY AGAIN
2077 JMP SHORT EEH_EXIT ;
2078
2079EEH_HARD_ERROR: ;
2080 MOV IO_ERROR, HARD_ERROR ;
2081 MOV UKM_ERR,OFF ;AN011;ASSUME NOT "UNKNOWN MEDIA" TYPE ERROR
2082 CMP AX,26 ;AN011;IS THE ERROR TYPE IS "UNKNOWN MEDIA"?
2083; $IF E ;AN011;IF "UNKNOWN MEDIA" TYPE ERROR
2084 JNE $$IF114
2085 MOV UKM_ERR,ON ;AN011;SET FLAG TO INDICATE "UNKNOWN MEDIA"
2086 ; TO CAUSE FORMATTING OF TARGET DISKETTE
2087; $ENDIF ;AN011;
2088$$IF114:
2089
2090EEH_EXIT: ;
2091 POP DI ;
2092 POP SI ;
2093 POP DX ;
2094 POP CX ;
2095 POP BX ;
2096 POP AX ;
2097 POPF ;
2098 RET ;
2099.XLIST ;
2100;EEH_JUST_EXIT:
2101; JMP EXIT_PROGRAM ;UNCONDITIONAL EXIT (IN MAIN PROC)
2102.LIST ;
2103EXTENDED_ERROR_HANDLER ENDP ;
2104; = = = = = = = = = = = =
2105 HEADER <TRY_FORMAT - ATTEMPT TRACK FORMAT, TRY FOR ERROR RECOVERY> ;AN000;
2106;*****************************************************************************
2107 PUBLIC TRY_FORMAT ;AN000;MAKE ENTRY IN LINK MAP
2108TRY_FORMAT PROC NEAR ;
2109;*** TRY TO FORMAT A TRACK.
2110;*** CALLED BY "EXTENDED_ERROR_HANDLER" TO CHECK THE TIME OUT ERROR IS A REAL
2111;*** ONE OR CAUSED BY "ADDR MARK NOT FOUND" ERROR.(THIS IS HARDWARE ERROR THAT
2112;*** DOES NOT GIVE CORRECT ERROR CODE).
2113;*** THIS ROUTINE WILL CALL "GENERIC_IOCTL" WHICH IN TURN WILL CALL "EXTENDED_
2114;*** ERROR_HANDLER" WHERE THE ERROR WILL BE REEXAMINED.
2115;*****************************************************************************
2116 PUSH ES ;
2117
2118 PUSH DS ;
2119 POP ES ;
2120
2121 MOV CX, MS_deviceBPB_leng ;set length of BPB
2122 MOV SI, OFFSET MS_deviceBPB ;
2123 MOV DI, OFFSET MT_deviceBPB ;
2124 REP MOVSB ;
2125 CALL CHK_MEDIATYPE ;set MT_mediaTYPE for FORMAT operation
2126
2127 MOV MT_specialFunctions, SET_SP_BF_FORM ;=00000101B
2128 MOV CL, SETDEVPARM ;=40h
2129 MOV DX, OFFSET MT_IOCTL_DRV_PARM ;
2130 XOR BX, BX ;
2131 MOV BL, TARGET_DRIVE ;
2132 CALL GENERIC_IOCTL ;
2133
2134 XOR AX, AX ;
2135 MOV AL, SIDE ;SIDE TO FORMAT
2136 MOV Fhead, AX ;
2137 MOV AL, TRACK_TO_WRITE ;TRACK TO FORMAT
2138 MOV Fcylinder, AX ;
2139
2140 XOR BX, BX ;
2141 MOV BL, TARGET_DRIVE ;
2142 MOV CL, FORMAT_FUNC ;=42h
2143 MOV DX, OFFSET IOCTL_FORMAT ;
2144 CALL GENERIC_IOCTL ;
2145
2146 MOV AL, IO_ERROR ;SAVE IO_ERROR, IN CASE FOR PC_AT CASE.
2147 PUSH AX ;
2148
2149 XOR BX, BX ;
2150 MOV BL, TARGET_DRIVE ;
2151 MOV T_DRV_SET_FLAG, 1 ;INDICATE TARGET DRIVE PARM HAS BEEN SET
2152 MOV DX, OFFSET MT_IOCTL_DRV_PARM ;
2153 MOV MT_specialFunctions, SET_SP_FUNC_DEF ;
2154 CALL SET_DRV_PARM_DEF ;SET IT BACK FOR NORMAL
2155 ; OPERATION, EX. WRITING
2156
2157 POP AX ;
2158 MOV IO_ERROR, AL ;RESTORE IO_ERROR
2159
2160 POP ES ;
2161
2162 RET ;
2163
2164TRY_FORMAT ENDP ;
2165; = = = = = = = = = = = =
2166 HEADER <ERROR_MESSAGE - SAY WHAT AND WHERE FAILURE> ;AN000;
2167;*****************************************************************************
2168; *
2169ERROR_MESSAGE PROC NEAR ;DISPLAY ERROR MESSAGE *
2170 PUBLIC ERROR_MESSAGE ;AN000;MAKE ENTRY IN LINK MAP
2171; *
2172; FUNCTION: THIS SUBROUTINE DISPLAYS WHAT OPERATION FAILED (READ OR WRITE) *
2173; AND WHERE IT FAILED (TRACK NO. AND SIDE). *
2174; *
2175; INPUT: AH = IOCTL I/O COMMAND CODE (3=READ, 4=WRITE) *
2176; *
2177;*****************************************************************************
2178 CMP AH,READ_FUNC ;ERROR DURING READ ?
2179.XLIST ;
2180; $IF E
2181; MOV BX,OFFSET READ_ERROR
2182; MOV MSG_HARD_ERR_TYPE,BX ;ERROR DURING READ OP
2183; MOV BL,TRACK_TO_READ ;SAVE BAD TRACK NUMBER FOR READ
2184; $ELSE
2185; MOV BX,OFFSET WRITE_ERROR
2186; MOV MSG_HARD_ERR_TYPE,BX ;ERROR DURING WRITE OP
2187; MOV BL,TRACK_TO_WRITE ;SAVE BAD TRACK NUMBER FOR WRITE
2188; $ENDIF
2189.LIST ;
2190; $IF E ;AN000;YES, READ ERROR
2191 JNE $$IF116
2192 MOV BL,TRACK_TO_READ ;SAVE BAD TRACK NUMBER FOR READ
2193 MOV DI,OFFSET MSGNUM_HARD_ERROR_READ ;AN000;
2194; $ELSE ;AN000;NO, NOT READ, MUST BE WRITE ERROR
2195 JMP SHORT $$EN116
2196$$IF116:
2197 MOV BL,TRACK_TO_WRITE ;SAVE BAD TRACK NUMBER FOR WRITE
2198 MOV DI,OFFSET MSGNUM_HARD_ERROR_WRITE ;AN000;
2199; $ENDIF ;AN000;READ ERROR?
2200$$EN116:
2201 MOV AL,SIDE ;
2202 MOV DRIVE_LETTER,"A" ;
2203 dec dl ;change logical drive letter to physical one.
2204 ADD DRIVE_LETTER,DL ;SHOW DRIVE LETTER
2205.XLIST ;
2206; MOV BYTE PTR MSG_HARD_ERROR_PTR+8,AL ;SIDE NUMBER
2207; MOV BYTE PTR MSG_HARD_ERROR_PTR+10,BL ;TRACK NUMBER WHERE THE ERROR
2208.LIST ;
2209 MOV BYTE PTR ERROR_SIDE_NUMBER,AL ;AC000;SIDE NUMBER
2210 MOV BYTE PTR ERROR_TRACK_NUMBER,BL ;AC000;TRACK NUMBER WHERE THE ERROR
2211 ;CR,LF,"Unrecoverable read/write error on drive %1",CR,LF
2212 CALL SENDMSG ;"Side %2, track %3",CR,LF ;ACN000;
2213
2214 RET ;
2215ERROR_MESSAGE ENDP ;
2216.XLIST ;
2217; HEADER <PROMPT - READ RESPONSE FROM KEYBOARD>
2218;KB_INPUT_FUNC EQU 0C01H ;DOS KEYBOARD INPUT
2219;*****************************************************************************
2220; *
2221;PROMPT PROC NEAR ;DISPLAY MESSAGE *
2222; AND GET A USER INPUT CHARACTER *
2223; PUBLIC PROMPT *
2224; *
2225; INPUT: DX = MESSAGE POINTER *
2226; OUTPUT: BYTE USER_INPUT *
2227; *
2228;*****************************************************************************
2229; PUSH AX
2230; MOV AX,KB_INPUT_FUNC ;KEYBOARD INPUT
2231; INT 21H
2232; MOV USER_INPUT,AL ;SAVE USER'S RESPONSE
2233; POP AX
2234; RET
2235;PROMPT ENDP
2236; HEADER <CALL_PRINTF - COMMON DRIVER TO PRINTF, DISPLAY MESSAGE>
2237;CALL_PRINTF PROC NEAR
2238; PUBLIC CALL_PRINTF
2239;INPUT - DX HAS OFFSET INTO DS OF MESSAGE PARM LIST
2240; PUSH DX
2241; PUSH CS
2242; CALL PRINTF
2243
2244; RET
2245;CALL_PRINTF ENDP
2246; = = = = = = = = = = = =
2247.list ;
2248 HEADER <SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG> ;AN000;
2249SENDMSG PROC NEAR ;AN000;
2250 PUBLIC SENDMSG ;AN000;
2251; INPUT - DI=POINTER TO MSG_DESC STRUC FOR THIS MESSAGE
2252; OUTPUT - IF CARRY SET, EXTENDED ERROR MSG ATTEMPTED DISPLAYED
2253; IF CARRY CLEAR, ALL OK
2254; IN EITHER CASE, DI AND AX ALTERED, OTHERS OK
2255; = = = = = = = = = = = =
2256
2257 PUSH BX ;AN000;SAVE CALLER'S REGS
2258 PUSH CX ;AN000;
2259 PUSH DX ;AN000;
2260 PUSH SI ;AN000;
2261
2262; PASS PARMS TO MESSAGE HANDLER IN
2263; THE APPROPRIATE REGISTERS IT NEEDS.
2264 MOV BX,[DI].MSG_NUM ;AC006;MESSAGE NUMBER
2265 MOV SI,[DI].MSG_SUBLIST ;AN000;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
2266 MOV CX,[DI].MSG_COUNT ;AN000;NUMBER OF %PARMS, 0 IF NONE
2267 MOV DX,[DI].MSG_CLASS ;AN000;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
2268 MOV AX,SELECT_MPX ;AN006;REQUEST THE SELECT MULTIPLEXOR, IF PRESENT
2269 INT MULTIPLEXOR ;AN006;CALL THE MULTIPLEXOR FUNCTION
2270
2271 CMP AL,SELECT_PRESENT ;AN006;CHECK MULTIPLEXOR RESPONSE CODE
2272; $IF NE ;AN006;IF SELECT HAS NOT HANDLED THE MESSAGE
2273 JE $$IF119
2274 MOV AX,[DI].MSG_NUM ;AN000;MESSAGE NUMBER
2275 MOV BX,[DI].MSG_HANDLE ;AN006;HANDLE TO DISPLAY TO
2276 CALL SYSDISPMSG ;AN000;DISPLAY THE MESSAGE
2277
2278; $IF C ;AN000;IF THERE IS A PROBLEM
2279 JNC $$IF120
2280 ;AX=EXTENDED ERROR NUMBER ;AN000;
2281 LEA DI,MSGNUM_EXTERR ;AN000;GET REST OF ERROR DESCRIPTOR
2282 MOV BX,[DI].MSG_HANDLE ;AN000;HANDLE TO DISPLAY TO
2283 MOV SI,[DI].MSG_SUBLIST ;AN000;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE
2284 MOV CX,[DI].MSG_COUNT ;AN000;NUMBER OF %PARMS, 0 IF NONE
2285 MOV DX,[DI].MSG_CLASS ;AN000;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW
2286 CALL SYSDISPMSG ;AN000;TRY TO SAY WHAT HAPPENED
2287
2288 STC ;AN000;REPORT PROBLEM
2289; $ENDIF ;AN000;PROBLEM WITH DISPLAY?
2290$$IF120:
2291; $ELSE ;AN006;SINCE SELECT DID THE MESSAGE
2292 JMP SHORT $$EN119
2293$$IF119:
2294 MOV SELECT_FLAG,TRUE ;AN006;INDICATE SELECT IS DOING THE MESSAGES
2295 CLC ;AN006;GENERATE A "NO PROBLEM" RESPONSE
2296; $ENDIF ;AN006;DID SELECT HANDLE THE MESSAGE?
2297$$EN119:
2298
2299 POP SI ;AN000;RESTORE CALLER'S REGISTERS
2300 POP DX ;AN000;
2301 POP CX ;AN000;
2302 POP BX ;AN000;
2303
2304 RET ;AN000;
2305SENDMSG ENDP ;AN000;
2306; = = = = = = = = = = = =
2307 HEADER <YESNO - DETERMINE IF A RESPONSE IS YES OR NO> ;AN000;
2308YESNO PROC NEAR ;AN000;
2309 PUBLIC YESNO ;AN000;MAKE ENTRY IN LINK MAP
2310;INPUT: DL=CHAR WITH Y OR N EQUIVALENT CHAR TO BE TESTED
2311; SELECT_FLAG - IF SELECT IS DOING MESSAGES, ALWAYS ASSUME "NO"
2312;OUTPUT: AX=0=NO; AX=1=YES ; AX=2=INVALID RESPONSE, NEITHER Y NOR N
2313; IF CARRY SET, PROBLEM WITH THE FUNCTION, CALLER SHOULD ASSUME "NO"
2314; = = = = = = = = = = = =
2315
2316 CMP SELECT_FLAG,TRUE ;AN006;IS SELECT DOING THE MESSAGES?
2317; $IF NE ;AN006;IF SELECT HAS NOT HANDLED THE MESSAGE
2318 JE $$IF124
2319 ;AL=SUBFUNCTION, AS:
2320 ; 20H=CAPITALIZE SINGLE CHAR
2321 ; 21H=CAPITALIZE STRING
2322 ; 22H=CAPITALIZE ASCIIZ STRING
2323 ; 23H=YES/NO CHECK
2324 ; 80H BIT 0=USE NORMAL UPPER CASE TABLE
2325 ; 80H BIT 1=USE FILE UPPER CASE TABLE
2326 ;DL=CHAR TO CAP (FUNCTION 23H) ;AN000;
2327 MOV AX,(GET_EXT_CNTRY_INFO SHL 8) + YESNO_CHECK ;AN000;(6523H) GET EXTENDED
2328 ; COUNTRY INFORMATION, (Y/N)
2329 INT 21H ;AN000;SEE IF Y OR N
2330
2331; $ELSE ;AN006;SINCE SELECT IS NOT PRESET
2332 JMP SHORT $$EN124
2333$$IF124:
2334 MOV AX,NO ;AN006;ASSUME RESPONSE WAS 'NO'
2335; $ENDIF ;AN006;
2336$$EN124:
2337 RET ;AN000;RETURN TO CALLER
2338YESNO ENDP ;AN000;
2339; = = = = = = = = = = = =
2340;(deleted ;AN013;) HEADER <READ_VOLSER - OBTAIN OLD VOLUME SERIAL NUMBER FROM SOURCE> ;AN000;
2341;(deleted ;AN013;) READ_VOLSER PROC NEAR ; ;AN000;
2342;(deleted ;AN013;) PUBLIC READ_VOLSER ; ;AN000;
2343;(deleted ;AN013;) ;IF THE SOURCE DISKETTE SUPPORTED A VOL SERIAL NUMBER, THEN MAKE A NEW ONE
2344;(deleted ;AN013;) ; AND SEND IT TO THE TARGET DISKETTE. FOR OLD STYLE DISKETTES THAT DID NOT
2345;(deleted ;AN013;) ; HAVE ANY VOL SERIAL NUMBER, MAKE NO CHANGE AFTER THE TRADITIONAL FULL COPY.
2346;(deleted ;AN013;) ;INPUT: SOURCE AND TARGET DRIVE ID
2347;(deleted ;AN013;) ; THE TARGET DISKETTE IS A COMPLETE COPY OF THE SOURCE.
2348;(deleted ;AN013;) ;REFERENCED: A_MEDIA_ID_INFO STRUC (DEFINED IN DISKCOPY.EQU)
2349;(deleted ;AN013;) ; = = = = = = = = = = = = = = = = = =
2350;(deleted ;AN013;) ; ISSUE GET MEDIA ID FROM SOURCE
2351;(deleted ;AN013;) MOV BH,ZERO ;BH=0, RES ;AN000;
2352;(deleted ;AN013;) MOV BL,SOURCE_DRIVE ;BL=DRIVE NUM (1=A:, 2=B:, ETC);AN000;
2353;(deleted ;AN013;) MOV DX,OFFSET MEDIA_ID_BUF ;DS:DX=BUFFER (see A_MEDIA_ID_INFO STRUC);AN000;
2354;(deleted ;AN013;) DOSCALL GSET_MEDIA_ID,GET_ID ;(6900H) GET MEDIA ID ;AC009;
2355;(deleted ;AN013;) ;CARRY SET ON ERROR (OLD STYLE BOOT RECORD)
2356;(deleted ;AN013;)
2357;(deleted ;AN013;) $IF NC ;IF THERE IS NO PROBLEM ;AN000;
2358;(deleted ;AN013;) ; GET CURRENT DATE
2359;(deleted ;AN013;) DOSCALL GET_DATE ;READ SYSTEM DATE ;AN000;
2360;(deleted ;AN013;) ;OUTPUT: DL = DAY (1-31)
2361;(deleted ;AN013;) ; AL = DAY OF WEEK (0=SUN,6=SAT)
2362;(deleted ;AN013;) ; CX = YEAR (1980-2099)
2363;(deleted ;AN013;) ; DH = MONTH (1-12)
2364;(deleted ;AN013;) PUSH CX ;SAVE THESE FOR ;AN000;
2365;(deleted ;AN013;) PUSH DX ; INPUT INTO HASH ALGORITHM ;AN000;
2366;(deleted ;AN013;) ; GET CURRENT TIME
2367;(deleted ;AN013;) DOSCALL GET_TIME ;READ SYSTEM TIME CLOCK ;AN000;
2368;(deleted ;AN013;) ;OUTPUT: CH = HOUR (0-23)
2369;(deleted ;AN013;) ; CL = MINUTES (0-59)
2370;(deleted ;AN013;) ; DH = SECONDS (0-59)
2371;(deleted ;AN013;) ; DL = HUNDREDTHS (0-99)
2372;(deleted ;AN013;)
2373;(deleted ;AN013;) ; HASH THESE INTO A UNIQUE 4 BYTE NEW VOLUME SERIAL NUMBER:
2374;(deleted ;AN013;) ; MI_SERIAL+0 = DX FROM DATE + DX FROM TIME
2375;(deleted ;AN013;) ; MI_SERIAL+2 = CX FROM DATE + CX FROM TIME
2376;(deleted ;AN013;)
2377;(deleted ;AN013;) POP AX ;GET THE DX FROM DATE ;AN000;
2378;(deleted ;AN013;) ADD AX,DX ;ADD IN THE DX FROM TIME ;AN000;
2379;(deleted ;AN013;) MOV WORD PTR MEDIA_ID_BUF.MI_SERIAL,AX ;SAVE FIRST RESULT OF HASH;AN000;
2380;(deleted ;AN013;)
2381;(deleted ;AN013;) POP AX ;GET THE CX FROM DATE ;AN000;
2382;(deleted ;AN013;) ADD AX,CX ;ADD IN THE CX FROM TIME ;AN000;
2383;(deleted ;AN013;) MOV WORD PTR MEDIA_ID_BUF.MI_SERIAL+WORD,AX ;SAVE SECOND RESULT OF HASH;AN000;
2384;(deleted ;AN013;)
2385;(deleted ;AN013;) MOV VOLSER_FLAG,TRUE ;REQUEST THE NEW VOL SERIAL NUMBER BE WRITTEN;AN000;
2386;(deleted ;AN013;) $ENDIF ; ;AN000;
2387;(deleted ;AN013;) RET ;RETURN TO CALLER ;AN000;
2388;(deleted ;AN013;) READ_VOLSER ENDP ; ;AN000;
2389; = = = = = = = = = = = = = = = = = = =
2390 HEADER <WRITE_VOLSER - PUT NEW VOL SER NUMBER TO TARGET> ;AN000;
2391WRITE_VOLSER PROC NEAR ;AN000;
2392 PUBLIC WRITE_VOLSER ;AN000;MAKE ENTRY IN LINK MAP
2393 CMP VOLSER_FLAG,TRUE ;AN000;IF NEW NUMBER READY TO BE WRITTEN
2394; $IF E ;AN000;THEN WRITE IT
2395 JNE $$IF127
2396
2397;NOTE FOR ;AN013;
2398;THERE IS NO NEED TO DO A SET MEDIA ID TO WRITE OUT THE MODIFIED SERIAL NUMBER
2399;BECAUSE THAT NUMBER WAS CHANGED IN THE IMAGE OF THE BOOT RECORD WHEN THE
2400;ORIGINAL BOOT RECORD WAS READ IN, SO WHEN THAT TRACK IMAGE WAS WRITTEN,
2401;IT CONTAINED THE NEW SERIAL NUMBER ALREADY.
2402
2403;(deleted ;AN013;) ; ISSUE SET MEDIA ID TO TARGET
2404;(deleted ;AN013;) MOV BH,ZERO ;BH=0, RES ;AN000;
2405;(deleted ;AN013;) MOV BL,TARGET_DRIVE ;BL=DRIVE NUM ;AN000;
2406;(deleted ;AN013;) MOV DX,OFFSET MEDIA_ID_BUF ;DS:DX=BUFFER (see STRUC above);AN000;
2407;(deleted ;AN013;) DOSCALL GSET_MEDIA_ID,SET_ID ;(6901H) SET MEDIA ID ;AC009;
2408
2409; NOTE: IN THE FOLLOWING TWO SUBLISTS, WE ARE GOING TO DISPLAY, IN HEX,
2410; A CONSECUTIVE SET OF 4 BYTES, THE VOLUME SERIAL NUMBER. THE ORDER OF
2411; THESE TWO WORDS OF HEX IS, LEAST SIGNIFICANT WORD FIRST, THEN THE
2412; MOST SIGNIFICANT WORD. WHEN DISPLAYED, THE MOST SIGNIFICANT IS TO BE
2413; DISPLAYED FIRST, SO THE VALUE AT SERIAL+2 GOES TO THE 26A SUBLIST,
2414; AND THE LEAST SIGNIFICANT VALUE AT SERIAL+0 GOES TO THE SECOND POSITION,
2415; REPRESENTED BY THE 26B SUBLIST.
2416
2417 LEA AX,SERIAL ;AC013;GET POINTER TO DATA TO BE PRINTED
2418 MOV SUBLIST_26B.SUB_VALUE,AX ;AN001; INTO THE SUBLIST
2419
2420 LEA AX,SERIAL+WORD ;AC013;GET POINTER TO DATA TO BE PRINTED
2421 MOV SUBLIST_26A.SUB_VALUE,AX ;AN001; INTO THE SUBLIST
2422
2423 PRINT MSGNUM_CR_LF ;AN000;SKIP A SPACE
2424
2425 ;"Volume Serial Number is %1-%2"
2426 PRINT MSGNUM_SERNO ;AN001;DISPLAY THE NEW SERIAL NUMBER
2427
2428; $ENDIF ;AN000;
2429$$IF127:
2430 RET ;AN000;RETURN TO CALLER
2431WRITE_VOLSER ENDP ;AN000;
2432; = = = = = = = = = = = = = = = = = = =
2433 HEADER <PRESS_ANY_KEY - PUTS A BLANK LINE BEFORE PROMPT> ;AN000;
2434PRESS_ANY_KEY PROC NEAR ;
2435;THE CANNED MESSAGE "PRESS ANY KEY..." DOES NOT START WITH CR,LF.
2436;THIS PUTS OUT THE CR LF TO CAUSE SEPARATION OF THIS PROMP FROM
2437;PRECEEDING MESSAGES.
2438; = = = = = = = = = = = =
2439 PRINT MSGNUM_CR_LF ;AN000;SKIP A SPACE
2440
2441 PRINT MSGNUM_STRIKE ;AN000;"Press any key when ready..."
2442
2443 RET ;AN000;RETURN TO CALLER
2444PRESS_ANY_KEY ENDP ;AN000;
2445; = = = = = = = = = = = =
2446 PUBLIC DISKCOPY_END ;
2447DISKCOPY_END LABEL NEAR ;
2448
2449 PATHLABL DISKCOPY ;AN015;
2450CSEG ENDS ;
2451 END DISKCOPY ;
2452 \ No newline at end of file