summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/DISKCOMP/DISKCOMP.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/DISKCOMP/DISKCOMP.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/DISKCOMP/DISKCOMP.ASM')
-rw-r--r--v4.0/src/CMD/DISKCOMP/DISKCOMP.ASM2060
1 files changed, 2060 insertions, 0 deletions
diff --git a/v4.0/src/CMD/DISKCOMP/DISKCOMP.ASM b/v4.0/src/CMD/DISKCOMP/DISKCOMP.ASM
new file mode 100644
index 0000000..83d6a61
--- /dev/null
+++ b/v4.0/src/CMD/DISKCOMP/DISKCOMP.ASM
@@ -0,0 +1,2060 @@
1 PAGE 90,132 ;A2
2 TITLE DISKCOMP.SAL - COPY COMPLETE DISKETTE
3;****************** START OF SPECIFICATIONS *****************************
4; MODULE NAME: DISKCOMP
5
6; DESCRIPTIVE NAME: Diskette to diskette complete compare Utility
7
8;FUNCTION: DISKCOMP is to compare the contents of the diskette in the
9; specified first drive to the diskette in the second
10; drive. If the first drive has a vol serial number, that
11; field in both diskettes is ignored in the comparison
12; of that one sector, because DISKCOPY will create a unique
13; volume serial number when it duplicates a diskette.
14
15; Multiple compares may be performed with one load of DISKCOMP.
16; A prompt, "Compare another (Y/N)?" permits additional
17; executions, all with the same drive specifications.
18
19; ENTRY POINT: "DISKCOMP" at ORG 100h, jumps to "BEGIN".
20
21; INPUT: (DOS command line parameters)
22
23; [d:][path] DISKCOMP [d: [d:]] [/1] [/8]
24
25; WHERE
26; [d:][path] - Path where the DISKCOMP command resides.
27
28; [d:] - To specify the First drive
29;
30; [d:] - To specify the Second drive
31;
32; [/1] - To compare only the first side of the diskette,
33; regardless of the diskette or drive type.
34
35; [/8] - To compare only the first 8 sectors per track,
36; even if the first diskette contains 9/15 sectors
37; per track.
38;
39; EXIT-NORMAL: Errorlevel = 0
40; Function completed successfully.
41
42; EXIT-ERROR: Errorlevel = 1
43; Abnormal termination due to error, wrong DOS,
44; invalid parameters, unrecoverable I/O errors on
45; the diskette.
46; Errorlevel = 2
47; Termination requested by CTRL-BREAK.
48
49; EFFECTS: The entire diskette is compared, including the unused
50; sectors. There is no awareness of the separate files
51; involved. A unique volume serial number is ignored
52; for the comparison of the first sector.
53
54; INCLUDED FILES:
55; PATHMAC.INC - PATHGEN MACRO
56; INCLUDE DCMPMACR.INC ;(FORMERLY CALLED MACRO.DEF)
57; INCLUDE DISKCOMP.EQU ;EQUATES
58
59; INTERNAL REFERENCES:
60; ROUTINES:
61; BEGIN - entry point from DOS
62; SET_LOGICAL_DRIVE - set log. drive letter as owner of drive
63; COMP - compare the diskette image
64; TEST_REPEAT - see if user wants to compare another
65; READ_SOURCE - read from first drive as much as possible
66; CHECK_SOURCE - determine first diskette type
67; READ_A_SECTOR - use IOCTL read to get a sector
68; CALC_TRACK_SIZE - find mem size to hold one track
69; CHECK_MEMORY_SIZE - be sure enuf memory to compare 1 track
70; COMP_TARGET - compare memory data with secon diskette
71; CHECK_TARGET - compare second disk boot record
72; SET_DRV_PARM - request IOCTL to set device parm
73; COMP_TRACK - read and compare specified track
74; SWAP_DRIVE - setup for diskette swapping
75; READ_TRACK - read a track to memory
76; READ_OP - IOCTL to read a track
77; SET_FOR_THE_OLD - use pre 2.0 BPB
78; SET_TRACKLAYOUT - determine sectors per track
79; GENERIC_IOCTL - perform specified IOCTL function
80; EXTENDED_ERROR_HANDLER - determine and service extended errors
81; SET_DRV_PARM_DEF - set drive parms via IOCTL
82;
83; VOLSER - during compare of first sector, avoid vol ser #
84; SENDMSG - passes parms to regs and invokes the system message routine.
85
86; DATA AREAS:
87; PSP - Contains the DOS command line parameters.
88; WORKAREA - Temporary storage
89
90; EXTERNAL REFERENCES:
91; ROUTINES:
92; SYSDISPMSG - Uses the MSG parm lists to construct the messages
93; on STDOUT.
94; SYSLOADMSG - Loads messages, makes them accessable.
95; SYSPARSE - Processes the DOS Command line, finds parms.
96
97; DATA AREAS:
98; DCOMPSM.SAL - Defines the control blocks that describe the messages
99; DCOMPPAR.SAL - Defines the control blocks that describe the
100; DOS Command line parameters.
101
102; NOTES:
103; This module should be processed with the SALUT preprocessor
104; with the re-alignment not requested, as:
105
106; SALUT DISKCOMP,NUL
107
108; To assemble these modules, the alphabetical or sequential
109; ordering of segments may be used.
110
111; Sample LINK command:
112
113; LINK @DISKCOMP.ARF
114
115; Where the DISKCOMP.ARF is defined as:
116
117; DISKCOMP+
118; DCOMPSM+
119; DCOMPP+
120; DCOMPPAR+
121; COMPINIT
122
123; These modules must be linked in this order. The load module is
124; a COM file, to be converted to COM with EXE2BIN.
125
126; REVISION HISTORY:
127; A000 Version 4.00: add PARSER, System Message Handler,
128; Ignore vol serial number differences.
129; A001 386 Support
130; A002 Avoid duplicate switches
131; A003 PTM 540 Show parm in error
132; A004 PTM 752 Add close door after drive not ready
133; A005 PTM 756 Add help msg after parm error message
134; A006 PTM1100 Clear keyboard buffer before input response
135; A007 PTM1464 Delete unused msgs: 22,23,24
136; A008 PTM1406 USE 69H INSTEAD OF IOCTL FOR GET/SET MEDIA ID
137; A009 PTM1605 PUT A BLANK LINE OUT BEFORE PRESS ANY KEY MSG
138; A010 PTM1821 move INCLUDE COPYRIGH.INC to MSG_SERVICE macro
139; A011 PTM3184 SUPPORT OS/2 1.0/1.1 TYPE BOOT RECORDS ALSO
140; REMOVE USE OF GET/SET MEDIA ID
141; A012 PTM3262 Specify BASESW EQU 1 before PARSE.ASM
142; A013 PTM3512 PATHGEN
143;
144; COPYRIGHT: The following notice is found in the OBJ code generated from
145; the "DCOMPSM.SAL" module:
146
147; "Version 4.00 (C) Copyright 1988 Microsoft"
148; "Licensed Material - Property of Microsoft "
149
150;PROGRAM AUTHOR: Original written by: Jin K.
151; 4.00 modifications by: Edwin M. K.
152;****************** END OF SPECIFICATIONS *****************************
153 IF1 ; ;AN000;
154 %OUT COMPONENT=DISKCOMP, MODULE=DISKCOMP.SAL
155 ENDIF ; ;AN000;
156;*****************************************************************************
157; *
158; D I S K C O M P *
159; *
160; UPDATE HISTORY: 8-21, 8-22, 8-30, 9-4, 9-20, 9-21, 12-19 *
161; 2-15-84, 2-17, 4-29, 6-20,7-24,3-27-85 *
162; *
163;*****************************************************************************
164
165 INCLUDE PATHMAC.INC ;AN013;
166 INCLUDE DCMPMACR.INC ;(FORMERLY CALLED MACRO.DEF)
167 INCLUDE DISKCOMP.EQU ;EQUATES
168
169; $salut (4,16,22,36) ; ;AN000;
170;THIS MESSAGE DESCRIPTOR CONTROL BLOCK IS GENERATED, ONE PER MESSAGE,
171;TO DEFINE THE SEVERAL PARAMETERS THAT ARE EXPECTED TO BE PASSED IN
172;CERTAIN REGISTERS WHEN THE SYSDISPMSG FUNCTION IS TO BE INVOKED.
173
174MSG_DESC STRUC ; ;AN000;
175MSG_NUM DW ? ;MESSAGE NUMBER (TO AX) ;AN000;
176MSG_HANDLE DW ? ;HANDLE OF OUTPUT DEVICE (TO BX) ;AN000;
177MSG_SUBLIST DW ? ;POINTER TO SUBLIST (TO SI) ;AN000;
178MSG_COUNT DW ? ;SUBSTITUTION COUNT (TO CX) ;AN000;
179MSG_CLASS DW ? ;MESSAGE CLASS (IN HIGH BYTE, TO DH) ;AN000;
180 ;LOW BYTE HAS 0 (FUNCTION "NO INPUT", TO DL) ;AN000;
181MSG_DESC ENDS ; ;AN000;
182
183MY_BPB STRUC
184CBYTE_SECT DW 0 ; 200H ;BYTES / SECTOR
185CSECT_CLUSTER DB 0 ; 2h ;SECTORS / CLUSTER
186CRESEV_SECT DW 0 ; 1h ;RESERVED SECTORS
187CFAT DB 0 ; 2h ;# OF FATS
188CROOTENTRY DW 0 ; 70h ;# OF ROOT ENTRIES
189CTOTSECT DW 0 ; 02D0h ;TOTAL # OF SECTORS INCLUDING
190 ; BOOT SECT, DIRECTORIES
191MEDIA_DESCRIP DB 0 ;0FDh ;MEDIA DISCRIPTOR
192CSECT_FAT DW 0 ; 2h ;SECTORS / FAT
193CSECT_TRACK DW 0 ;
194CHEAD DW 0 ;
195CHIDDEN_SECT DD 0 ;
196BIG_TOT_SECT DD 0 ;
197 DB 6 DUP (0) ;
198MY_BPB ENDS
199
200CSEG SEGMENT PARA PUBLIC 'CODE' ; ;AN000;
201 ASSUME CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
202
203;*****************************************************************************
204; *
205; EXTERNAL VARIABLES *
206; *
207;*****************************************************************************
208;$salut (4,2,9,36)
209
210.XLIST
211;EXTRN PROMPT :NEAR ;MESSAGE DISPLAY AND KEYBOARD INPUT ROUTINE
212;EXTRN ERROR_MESSAGE :NEAR ;ERROR MESSAGE DISPLAY ROUTINE
213;EXTRN COMPAT_ERROR :NEAR
214;EXTRN PRINTF :NEAR ;MESSAGE DISPLAY ROUTINE
215;EXTRN YES :BYTE
216;EXTRN NO :BYTE
217;EXTRN MSG_FIRST_BAD_PTR :BYTE
218.LIST
219
220 EXTRN SYSLOADMSG :NEAR ;SYSTEM MSG HANDLER INTIALIZATION ;AN000;
221 EXTRN SYSDISPMSG :NEAR ;SYSTEM MSG HANDLER DISPLAY ;AN000;
222
223 EXTRN INIT :NEAR ;INITIALIZATION ROUTINE
224
225 EXTRN MSG_TRACKS :WORD ; ;AN000;
226 EXTRN MSG_SECTRK :WORD ; ;AN000;
227 EXTRN MSG_SIDES :WORD ; ;AN000;
228
229 EXTRN ASCII_DRV1_ID :BYTE ; ;AN000;
230 EXTRN ASCII_DRV2_ID :BYTE ; ;AN000;
231
232 EXTRN SUBLIST_78 :WORD ; ;AN000;
233 EXTRN SUBLIST_17B :WORD ; ;AN000;
234
235 EXTRN MSGNUM_EXTERR :WORD ;EXTENDED ERROR MSG DESCRIPTOR ;AN000;
236 EXTRN MSGNUM_LOAD_FIRST :BYTE ; ;AC000;
237 EXTRN MSGNUM_LOAD_SECOND :BYTE ; ;AC000;
238 EXTRN MSGNUM_NOT_COMPATIBLE:BYTE ; ;AC000;
239 EXTRN MSGNUM_COMP_ANOTHER:BYTE ; ;AC000;
240 EXTRN MSGNUM_GET_READY :BYTE ; ;AC000;
241 EXTRN MSGNUM_CLOSE_DOOR :BYTE ; ;AN004;
242 EXTRN MSGNUM_FATAL_ERROR :BYTE ; ;AC000;
243 EXTRN MSGNUM_UNSUF_MEMORY:BYTE ; ;AC000;
244 EXTRN MSGNUM_BAD_FIRST :BYTE ; ;AC000;
245 EXTRN MSGNUM_BAD_SECOND :BYTE ; ;AC000;
246 EXTRN MSGNUM_HARD_ERROR_READ :BYTE ; ;AC000;
247 EXTRN MSGNUM_HARD_ERROR_COMP :BYTE ; ;AC000;
248 EXTRN MSGNUM_COMPARING :BYTE ; ;AC000;
249 EXTRN MSGNUM_STRIKE :BYTE ; ;AC000;
250 EXTRN MSGNUM_WRITE_PROTECT:BYTE ; ;AC000;
251 EXTRN MSGNUM_COMP_OK :BYTE ; ;AC000;
252 EXTRN MSGNUM_NEWLINE :BYTE ;
253 EXTRN DRIVE_LETTER :BYTE ;
254 EXTRN SKIP_MSG :BYTE ;NULL REPLACEMENT FOR DRIVE LETTER ;AN000;
255 PAGE
256;*****************************************************************************
257; *
258; PUBLIC VARIABLES *
259; *
260;*****************************************************************************
261
262 PUBLIC DISKCOMP_BEGIN
263 PUBLIC DISKCOMP_END
264 PUBLIC RECOMMENDED_BYTES_SECTOR
265 PUBLIC S_OWNER_SAVED
266 PUBLIC T_OWNER_SAVED
267 PUBLIC COMP
268 PUBLIC SOURCE_DRIVE
269 PUBLIC TARGET_DRIVE
270 PUBLIC S_DRV_SECT_TRACK
271 PUBLIC S_DRV_HEADS
272 PUBLIC S_DRV_TRACKS
273 PUBLIC T_DRV_SECT_TRACK
274 PUBLIC T_DRV_HEADS
275 PUBLIC T_DRV_TRACKS
276 PUBLIC USER_OPTION
277 PUBLIC COPY_TYPE
278 PUBLIC END_OF_TRACK
279 PUBLIC BUFFER_BEGIN
280 PUBLIC START_BUFFER
281 PUBLIC BUFFER_END
282 PUBLIC TRACK_TO_READ
283 PUBLIC TRACK_TO_COMP
284 PUBLIC SIDE
285 PUBLIC USER_INPUT
286 PUBLIC MAIN_EXIT
287
288 PUBLIC NO_OF_SIDES
289 PUBLIC USER_OPTION_8
290 PUBLIC ORG_SOURCE_DRIVE
291 PUBLIC ORG_TARGET_DRIVE
292 PUBLIC COMP_STATUS
293 PUBLIC OPERATION
294
295 PUBLIC IO_ERROR
296
297 PUBLIC DS_IOCTL_DRV_PARM ;PLACE HOLDER FOR DEFAULT SOURCE DRV PARM
298 PUBLIC DT_IOCTL_DRV_PARM ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
299 PUBLIC DS_specialFunctions ;AND THEIR CONTENTS
300 PUBLIC DT_specialFunctions
301 PUBLIC DS_deviceType
302 PUBLIC DT_deviceType
303 PUBLIC DS_deviceAttributes
304 PUBLIC DT_deviceAttributes
305 PUBLIC DS_numberOfCylinders
306 PUBLIC DT_numberOfCylinders
307 PUBLIC DS_mediaType
308 PUBLIC DT_mediaType
309 PUBLIC DS_BPB_PTR
310 PUBLIC DT_BPB_PTR
311
312 PUBLIC MS_IOCTL_DRV_PARM ;DRIVE PARM FROM SOURCE MEDIUM
313 PUBLIC MT_IOCTL_DRV_PARM ;DRIVE PARM FROM TARGET MEDIUM
314
315;*****************************************************************************
316 ORG 100H ;PROGRAM ENTRY POINT ;
317
318DISKCOMP:
319 JMP BEGIN
320;*****************************************************************************
321 EVEN ;PUT STACK ONTO A WORD ALIGNMENT BOUNDARY ;AN000;
322;INTERNAL STACK AREA
323
324 DB 64 DUP ('STACK ') ;512 BYTES
325
326MY_STACK_PTR LABEL WORD
327 PAGE
328;*****************************************************************************
329; *
330; INTERNAL VARIABLES *
331; *
332;*****************************************************************************
333
334; $salut (4,22,26,36) ; ;AN000;
335;DEFAULT BPB FOR OLD MEDIA
336;5.25, 48 TPI BPB SINGLE SIDE (9 SECTORS/TRACK)
337BPB48_SINGLE DW 512 ;BYTES/SECTOR
338 DB 1 ;SECTOR/CLUSTER
339 DW 1 ;# OF RESERVED SECTORS
340 DB 2 ;# OF FATS
341 DW 40h ;# OF ROOT ENTRY
342 DW 168h ;TOTAL # OF SECTORS IN THE MEDIA
343 DB 0FCh ;MEDIA BYTE
344 DW 2 ;SECTORS/FAT
345
346;5.25, 48 TPI BPB DOUBLE SIDE (9 SECTORS/TRACK)
347BPB48_DOUBLE DW 512 ;BYTES/SECTOR
348 DB 2 ;SECTOR/CLUSTER
349 DW 1 ;# OF RESERVED SECTORS
350 DB 2 ;# OF FATS
351 DW 70h ;# OF ROOT ENTRY
352 DW 2D0h ;TOTAL # OF SECTORS IN THE MEDIA
353 DB 0FDh ;MEDIA BYTE
354 DW 2 ;SECTORS/FAT
355
356;5.25, 96 TPI BPB DOUBLE SIDE (15 SECTORS/TRACK)
357BPB96 DW 512 ;BYTES/SECTOR
358 DB 1 ;SECTOR/CLUSTER
359 DW 1 ;# OF RESERVED SECTORS
360 DB 2 ;# OF FATS
361 DW 0E0h ;# OF ROOT ENTRY
362 DW 960h ;TOTAL # OF SECTORS IN THE MEDIA
363 DB 0F9h ;MEDIA BYTE
364 DW 7 ;SECTORS/FAT
365BPB96_LENG EQU $-BPB96 ;THIS LENGTH WILL BE USED FOR BPB48 ALSO.
366
367
368
369; INPUT PARMETERS FROM INIT SUBROUTINE:
370
371S_OWNER_SAVED DB 0 ;DRIVE LETTER THAT OWNED
372 ; SOURCE DRIVE OWNERSHIP
373T_OWNER_SAVED DB 0
374RECOMMENDED_BYTES_SECTOR DW 0 ;RECOMMENED BYTES/SECTOR FROM DEVICE PARA
375
376;IT IS ASSUMED THE NEXT TWO BYTES ARE CONSECUTIVE,
377;AND DEFINED IN SOURCE/TARGET ORDER, BY DCOMPPAR.SAL.
378SOURCE_DRIVE DB 0 ;1=A:, 2=B:,...
379TARGET_DRIVE DB 0
380
381ORG_SOURCE_DRIVE DB ? ;ORIGINAL SOURCE DRIVE
382ORG_TARGET_DRIVE DB ? ;ORIGINAL TARGET DRIVE
383
384USER_OPTION DB 0
385COPY_TYPE DB 1
386START_BUFFER DW 0
387BUFFER_BEGIN DW 1000H ;BEGINNING OF BUFFER ADDR [IN SEGMENT]
388BUFFER_END DW 3FF0H ;END OF BUFFER ADDR [IN SEGMENT]
389USER_OPTION_8 DB ?
390SECT_TRACK_LAYOUT DW 0
391
392S_DRV_SECT_TRACK DB ? ;SECT/TRACK, device informations.
393S_DRV_HEADS DB ? ;# OF HEADS
394S_DRV_TRACKS DB ? ;# OF TRACKS
395T_DRV_SECT_TRACK DB ?
396T_DRV_HEADS DB ?
397T_DRV_TRACKS DB ?
398
399;LOCAL VARIABLES:
400FIRST_TIME DB 0 ;SWITCH TO ACTIVATE VOLSER CHECK ;AN000;
401EXITFL DB EXOK ;ERRORLEVEL VALUE ;AN000;
402 PUBLIC EXITFL ; ;AN000;
403EXCBR EQU 2 ;CONTROL-BREAK REQUESTED TERMINATION ;AN000;
404EXVER EQU 1 ;BAD DOS VERSION ERRORLEVEL CODE ;AN000;
405EXPAR EQU 1 ;ERROR IN INPUT PARMS IN COMMAND LINE ;AN000;
406EXOK EQU 0 ;NORMAL ERRORLEVEL RET CODE ;AN000;
407 PUBLIC EXPAR ; ;AN000;
408
409IOCTL_SECTOR DW 1 ;used for READ_A_SECTOR routine.
410IOCTL_TRACK DW 0 ;IN THE TRACK
411IOCTL_HEAD DW 0 ;HEAD 0
412SAV_CSECT DW 0 ;TEMPORARY SAVING PLACE
413
414BOOT_SECT_TRACK DW 0 ;TEMP SAVING PLACE OF SECTOR/TRACK
415BOOT_TOT_TRACK DW 0 ;FOUND FROM THE BOOT SECTOR. max # of tracks
416BOOT_NUM_HEAD DW 0 ;NUMBER OF HEADS
417BOOT_BYTE_SECTOR DW 0 ;BYTES / SECTOR
418
419READ_S_BPB_FAILURE DB 0 ;GET MEDIA BPB. SUCCESS=0, FAILURE=1
420READ_T_BPB_FAILURE DB 0
421
422;*** Informations gotten from CHECK_SOURCE.
423;*** These will be used as a basis for the comp process.
424LAST_TRACK DB 79 ;LAST CYLINDER OF THE DASD (39 OR 79)
425END_OF_TRACK DB 15 ;END OF TRACK
426bSECTOR_SIZE DW 512 ;BYTES/SECTOR in bytes
427NO_OF_SIDES DB ? ;0=SINGLE SIDED, 1=DOUBLE SIDED
428
429TRACK_TO_READ DB 0
430TRACK_TO_COMP DB 0
431TRACK_SIZE DW 0 ;BYTES/CYLINDER [IN SEGMENTS]
432SECTOR_SIZE DB 0 ;BYTES/SECTOR [IN SEGMENTS]
433BYTES_IN_TRACK DW ? ;BYTES/ONE SIDE TRACK (USED IN COMP_TRACK)
434BUFFER_PTR DW ?
435COMP_ERROR DB 0
436SIDE DB ?
437OPERATION DB ?
438COMP_STATUS DB ?
439USER_INPUT DB ? ;DISKCOMP AGAIN?
440SEC_BUFFER DW ? ;SECONDARY BUFFER SEG ADDR
441COMPARE_PTR DW ? ;COMPARE POINTER
442IO_ERROR DB 0 ;USED TO INDICATE IF READ/WRITE ERROR MESSAGE
443MSG_FLAG DB ?
444S_DRV_SET_FLAG DB 0 ;SOURCE DEVICE PARM HAS BEEN SET?
445T_DRV_SET_FLAG DB 0
446
447;---------------------------------------
448;DEVICE PARAMETER TABLE
449;the returned info. still has the following format.
450
451DS_IOCTL_DRV_PARM LABEL BYTE ;PLACE HOLDER FOR DEFAULT TARGET DRV PARM
452DS_specialFunctions db ?
453DS_deviceType db ? ;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB
454 ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK
455DS_deviceAttributes dw ? ;0001h - NOT REMOVABLE, 0002h - CHANGE
456 ; LINE SUPPORTED
457DS_numberOfCylinders dw ?
458DS_mediaType db ?
459DS_BPB_PTR LABEL BYTE
460DS_deviceBPB my_bpb <>
461DS_trackLayout LABEL WORD ; ;AC000;
462 my_trackLayout ; ;AC000;
463;---------------------------------------
464
465DT_IOCTL_DRV_PARM LABEL BYTE
466DT_specialFunctions db ?
467DT_deviceType db ? ;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB
468 ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK
469DT_deviceAttributes dw ? ;0001h - NOT REMOVABLE, 0002h - CHANGE
470 ; LINE SUPPORTED
471DT_numberOfCylinders dw ?
472DT_mediaType db ?
473DT_BPB_PTR LABEL BYTE
474DT_deviceBPB my_bpb <>
475DT_trackLayout LABEL WORD ; ;AC000;
476 my_trackLayout ; ;AC000;
477
478;---------------------------------------
479
480MS_IOCTL_DRV_PARM LABEL BYTE ;DRIVE PARM FROM SOURCE MEDIUM
481MS_specialFunctions db ?
482MS_deviceType db ? ;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB
483 ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK
484MS_deviceAttributes dw ? ;0001h - NOT REMOVABLE, 0002h - CHANGE
485 ; LINE SUPPORTED
486MS_numberOfCylinders dw ?
487MS_mediaType db ?
488MS_BPB_PTR LABEL BYTE
489MS_deviceBPB my_bpb <>
490MS_deviceBPB_leng equ $-MS_deviceBPB
491MS_trackLayout LABEL WORD ; ;AC000;
492 my_trackLayout ; ;AC000;
493;---------------------------------------
494MT_IOCTL_DRV_PARM LABEL BYTE ;DRIVE PARM FROM TARGET MEDIUM
495MT_specialFunctions db ?
496MT_deviceType db ? ;0=5.25, 1=5.25 96 TPI, 2=3.5" 720 KB
497 ;3=8" SINGLE, 4=8" DOUBLE, 5=HARD DISK
498MT_deviceAttributes dw ? ;0001h - NOT REMOVABLE, 0002h - CHANGE
499 ; LINE SUPPORTED
500MT_numberOfCylinders dw ?
501MT_mediaType db ?
502MT_BPB_PTR LABEL BYTE
503MT_deviceBPB my_bpb <>
504MT_trackLayout LABEL WORD ; ;AC000;
505 my_trackLayout ; ;AC000;
506
507;IOCTL read/write a track.
508IOCTL_R_W LABEL BYTE
509specialFunctions db 0
510Head dw ?
511Cylinder dw ?
512FirstSectors dw ?
513numberOfSectors dw ?
514TAddress_off dw ?
515TAddress_seg dw ?
516
517;(deleted ;AN011;) MEDIA_ID_BUFFER A_MEDIA_ID_INFO <> ;BUFFER FOR GET/SET MEDIA ID ;AN000;
518 PATHLABL DISKCOMP ;AN013;
519 HEADER <BEGIN - VERSION CHECK, SYSMSG INIT, EXIT TO DOS> ; ;AN000;
520 PUBLIC DISKCOMP_BEGIN ; ;AN000;
521DISKCOMP_BEGIN LABEL BYTE
522;*****************************************************************************
523; *
524; D I S K C O M P M A I N P R O G R A M *
525; *
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 AREA
534 CALL SYSLOADMSG ;INIT SYSMSG HANDLER ;AN000;
535
536; $IF C ;IF THERE WAS A PROBLEM ;AN000;
537 JNC $$IF1
538 CALL SYSDISPMSG ;LET HIM SAY WHY HE HAD A PROBLEM ;AN000;
539
540 MOV EXITFL,EXVER ;TELL ERRORLEVEL BAD DOS VERSION ;AN000;
541; $ELSE ;SINCE SYSDISPMSG IS HAPPY ;AN000;
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 COMP
548 JNE $$IF3
549; $DO
550$$DO4:
551 CALL COMP ;PERFORM DISKCOMP
552
553 CALL TEST_REPEAT ;COMP 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 MOV DI,DX ;PASS NUMBER OF ERROR MSG, IF ANY ;AD000;
562 ;DI HAS OFFSET OF MESSAGE DESCRIPTOR
563 CALL SENDMSG ;DISPLAY THE ERROR MESSAGE ;AC000;
564
565 MOV EXITFL,EXVER ;ERROR RETURN CODE ;AC000;
566; $ENDIF
567$$EN3:
568 JMP SHORT EXIT_TO_DOS
569
570MAIN_EXIT: ;COME HERE AFTER CONTROL-BREAK
571 MOV EXITFL,EXCBR ; FOR CONTROL-BREAK EXIT ;AC000;
572
573EXIT_TO_DOS:
574 XOR BX, BX
575
576 MOV BL, S_OWNER_SAVED ;RESTORE ORIGINAL SOURCE,
577 ; TARGET DRIVE OWNER.
578 CALL SET_LOGICAL_DRIVE
579
580 MOV BL, T_OWNER_SAVED
581 CALL SET_LOGICAL_DRIVE
582
583 CMP S_DRV_SET_FLAG, 0
584; $IF NE ; ;AN000;
585 JE $$IF8
586 MOV BL, S_OWNER_SAVED
587 MOV DS_specialFunctions, SET_SP_FUNC_DOS ;=0
588 MOV DX, OFFSET DS_IOCTL_DRV_PARM
589 CALL SET_DRV_PARM_DEF ;RESTORE SOURCE DRIVE PARM
590
591; $ENDIF ; ;AN000;
592$$IF8:
593
594 CMP T_DRV_SET_FLAG, 0
595; $IF NE ; ;AN000;
596 JE $$IF10
597 MOV BL, T_OWNER_SAVED
598 MOV DT_specialFunctions, SET_SP_FUNC_DOS ;=0
599 MOV DX, OFFSET DT_IOCTL_DRV_PARM
600 CALL SET_DRV_PARM_DEF ;RESTORE TARGET DRIVE PARM
601
602; $ENDIF ; ;AN000;
603$$IF10:
604EXIT_PROGRAM:
605 MOV AL,EXITFL ;PASS ERRORLEVEL RET CODE ;AN000;
606; $ENDIF ;OK WITH SYSDISPMSG? ;AN000;
607$$EN1:
608 MOV AL,EXITFL ;PASS BACK ERRORLEVEL RET CODE ;AN000;
609 DOSCALL RET_CD_EXIT ;RETURN TO DOS WITH RET CODE ;AN000;
610
611 INT 20H ;IF ABOVE NOT WORK, ;AN000;
612BEGIN ENDP ; ;AN000;
613; = = = = = = = = = = = = = = = = =
614 HEADER <MORE_INIT - FINISH INIT, DO COMP> ; ;AN000;
615MORE_INIT PROC NEAR ; ;AN000;
616 RET ;RETURN TO CALLER ;AN000;
617MORE_INIT 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 ;IS THIS DRIVE ZERO?
628 ;IF BL = 0, THEN JUST RETURN
629; $IF NE
630 JE $$IF13
631 DOSCALL IOCTL_FUNC,SET_LOG_DRIVE ; ;AC000;
632 ;SET BL AS AN OWNER OF THAT DRIVE
633; $ENDIF
634$$IF13:
635 RET
636SET_LOGICAL_DRIVE ENDP
637; = = = = = = = = = = = =
638 HEADER <COMP - PERFORM THE OVERALL COMPARISON> ; ;AN000;
639;*****************************************************************************
640COMP PROC NEAR
641;*****************************************************************************
642 MOV AL,ORG_SOURCE_DRIVE ;INITIALIZE THE FIRST AND SECOND
643 MOV SOURCE_DRIVE,AL ;DRIVE IN THE ORDER THE USER
644 MOV AL,ORG_TARGET_DRIVE ;ENTERED ON THE COMMAND LINE
645 MOV TARGET_DRIVE,AL
646 MOV AX, RECOMMENDED_BYTES_SECTOR
647 MOV bSECTOR_SIZE, AX ;USE RECOMMENDED SECTOR SIZE
648 ; TO READ A SECTOR
649 MOV READ_S_BPB_FAILURE, 0 ;RESET GET BPB FAILURE FLAG
650 MOV READ_T_BPB_FAILURE, 0
651 MOV COMP_ERROR,0 ;RESET COMPARE ERROR COUNT
652 MOV COMP_STATUS,OK ;RESET COMP STATUS BYTE
653 CMP COPY_TYPE,2 ;IF TWO DRIVE COMP
654; $IF E
655 JNE $$IF15
656 CALL DISPLAY_LOAD_FIRST ;"Insert FIRST diskette in drive %1:" ;AN000;
657
658 CALL DISPLAY_LOAD_SECOND ;"Insert SECOND diskette in drive %1:" ;AN000;
659
660 CALL PRESS_ANY_KEY ;"Press any key to continue . . ." ;AC009;
661
662; $ENDIF
663$$IF15:
664 MOV TRACK_TO_READ,0 ;INITIALIZE TRACK NUMBERS
665 MOV TRACK_TO_COMP,0
666
667COMP_TEST_END:
668 MOV AL,TRACK_TO_COMP ;WHILE TRACK_TO_COMP<=LAST_TRACK
669 CMP AL,LAST_TRACK
670 JA COMP_END
671
672 CALL READ_SOURCE
673
674 CMP COMP_STATUS,FATAL ;MAKE SURE DRIVES WERE COMPATIBLE
675 JE COMP_EXIT
676
677 CALL COMP_TARGET
678
679 CMP COMP_STATUS,FATAL ;MAKE SURE TARGET AND SOURCE
680 JE COMP_EXIT ;DISKETTES ARE COMPATIBLE
681
682 JMP COMP_TEST_END
683
684COMP_END:
685 CMP COMP_ERROR,0 ;IF ERROR IN COMP
686; $IF E ;WARN USER
687 JNE $$IF17
688 PRINT MSGNUM_COMP_OK ;"Compare OK" ;AC000;
689
690;kiser note: this is a warning????
691
692; $ENDIF
693$$IF17:
694
695COMP_EXIT:
696 CMP COMP_STATUS,FATAL ;WAS COMP ABORTED ?
697; $IF E
698 JNE $$IF19
699 ;"Compare process ended"
700 PRINT MSGNUM_FATAL_ERROR ;IF SO THEN TELL USER ;AC000;
701
702; $ENDIF
703$$IF19:
704 RET
705
706COMP ENDP
707; = = = = = = = = = = = =
708 HEADER <DISPLAY_LOAD_FIRST - MOUNT FIRST DISKETTE> ; ;AN000;
709DISPLAY_LOAD_FIRST PROC NEAR ; ;AN000;
710 PUBLIC DISPLAY_LOAD_FIRST ; ;AN000;
711; = = = = = = = = = = = =
712
713 MOV SUBLIST_78.SUB_VALUE,OFFSET ASCII_DRV1_ID ;PASS CHAR DRIVE ID ;AN000;
714 ;"Insert FIRST diskette in drive %1:"
715 PRINT MSGNUM_LOAD_FIRST ;OUTPUT LOAD FIRST DISKETTE MESSAGE ;AC000;
716
717 MOV MSG_FLAG,SECOND
718 RET ;RETURN TO CALLER ;AN000;
719DISPLAY_LOAD_FIRST ENDP ; ;AN000;
720; = = = = = = = = = = = =
721 HEADER <DISPLAY_SECOND - MOUNT FIRST DISKETTE> ; ;AN000;
722DISPLAY_LOAD_SECOND PROC NEAR ; ;AN000;
723 PUBLIC DISPLAY_LOAD_SECOND ; ;AN000;
724; = = = = = = = = = = = =
725
726 MOV SUBLIST_78.SUB_VALUE,OFFSET ASCII_DRV2_ID ;PASS CHAR DRIVE ID ;AN000;
727 ;CR,LF,"Insert SECOND diskette in drive %1:",CR,LF
728 PRINT MSGNUM_LOAD_SECOND ;OUTPUT LOAD SECOND DISKETTE MESSAGE ;AC000;
729
730 MOV MSG_FLAG,FIRST
731 RET ;RETURN TO CALLER ;AN000;
732DISPLAY_LOAD_SECOND ENDP ; ;AN000;
733; = = = = = = = = = = = =
734 HEADER <TEST_REPEAT - PROMPT FOR ANOTHER COMPARE> ; ;AN000;
735;*****************************************************************************
736; *
737 PUBLIC TEST_REPEAT ;MAKE ENTRY IN LINK MAP ;AN000;
738TEST_REPEAT PROC NEAR ;TEST IF USER WANTS TO COMP ANOTHER *
739; DISKETTE *
740; INPUT : USER_INPUT ("Y" OR "N")
741; OUTPUT: NC = COMP AGAIN *
742; CY = EXIT TO DOS *
743;*****************************************************************************
744; $SEARCH ;REPEAT THIS PROMPT UNTIL (Y/N) RESPONDED ;AC000;
745$$DO21:
746 ;"Compare another diskette (Y/N)?"
747 PRINT MSGNUM_COMP_ANOTHER ;SEE IF USER WANTS TO COMPARE ANOTHER ;AC000;
748 ; AND READ RESPONSE TO AL
749 PUSH AX ;SAVE THE RESPONSE ;AN000;
750 PRINT MSGNUM_NEWLINE ;CR,LF,LF ;AC000;
751
752 POP DX ;RESTORE THE REPONSE CHAR TO DL ;AN000;
753 CALL YESNO ;CHECK FOR (Y/N) ;AN000;
754
755; $EXITIF C,NUL ;QUIT IF OK ANSWER ;AN000;
756 JC $$SR21
757 CMP AL,BAD_YESNO ;WAS THE RESPONSE INVALID? ;AN000;
758; $ENDLOOP B ;QUIT IF OK ANSWER (AX=0 OR 1) ;AN000;
759 JNB $$DO21
760 CMP AL,YES ;WAS "YES" SPECIFIED ;AN000;
761; $IF E ;IF "YES" ;AN000;
762 JNE $$IF24
763 MOV FIRST_TIME,ZERO ;SET UP TO DO ANOTHER VOLSER CHECK ;AN000;
764 CLC ;CLEAR CARRY TO INDICATE COMPARE AGAIN ;AN000;
765; $ELSE ;SINCE NOT "YES" ;AN000;
766 JMP SHORT $$EN24
767$$IF24:
768 STC ;SET CARRY TO INDICATE NO REPEAT ;AN000;
769; $ENDIF ; ;AN000;
770$$EN24:
771; $ENDSRCH ; ;AN000;
772$$SR21:
773 RET
774
775TEST_REPEAT ENDP
776; = = = = = = = = = = = =
777 HEADER <READ_SOURCE - FILL AVAIL MEM WITH FIRST DISKETTE> ; ;AN000;
778;*****************************************************************************
779; *
780 PUBLIC READ_SOURCE ;MAKE ENTRY IN LINK MAP ;AN000;
781READ_SOURCE PROC NEAR ;FILL ALL AVAILABLE MOMORY WITH SOURCE DATA
782; *
783;*****************************************************************************
784
785 CMP TRACK_TO_READ,0 ;1ST TRACK ?
786; $IF E ;IF SO
787 JNE $$IF28
788 CMP COPY_TYPE,1 ;IF SINGLE DRIVE COMP
789; $IF E ;PROMPT MSG
790 JNE $$IF29
791 CALL DISPLAY_LOAD_FIRST ;"Insert FIRST diskette in drive %1:" ;AN000;
792
793 CALL PRESS_ANY_KEY ;"Press any key to continue . . ." ;AC000;
794
795; $ENDIF
796$$IF29:
797 CALL CHECK_SOURCE ;DO NECESSARY CHECKING
798
799 CALL CALC_TRACK_SIZE
800
801 CALL CHECK_MEMORY_SIZE
802
803 CMP COMP_STATUS,FATAL
804 JE RS_EXIT
805
806; $ENDIF
807$$IF28:
808 MOV BX,BUFFER_BEGIN
809 MOV BUFFER_PTR,BX ;INITIALIZE BUFFER POINTER
810
811; $DO
812$$DO32:
813 MOV AL,TRACK_TO_READ ;DID WE FINISH READING ALL TRACKS?
814 CMP AL,LAST_TRACK
815; $LEAVE A
816 JA $$EN32
817
818 MOV AX,BUFFER_PTR ;DID WE RUN OUT OF BUFFER SPACE
819 ADD AX,TRACK_SIZE
820 CMP AX,BUFFER_END
821; $LEAVE A
822 JA $$EN32
823
824 CALL READ_TRACK ;NO, GO READ ANOTHER TRACK
825
826 INC TRACK_TO_READ
827; $ENDDO
828 JMP SHORT $$DO32
829$$EN32:
830
831RS_EXIT:
832 RET
833
834READ_SOURCE ENDP
835; = = = = = = = = = = = =
836 HEADER <CHECK_SOURCE - DETERMINE FIRST DISKETTE TYPE> ; ;AN000;
837;*****************************************************************************
838; *
839 PUBLIC CHECK_SOURCE ;MAKE ENTRY IN LINK MAP ;AN000;
840CHECK_SOURCE PROC NEAR ;CHECK SOURCE DISKETTE TYPE *
841; SET END_OF_TRACK, LAST_TRACK *
842; NO_OF_SIDES, bSECTOR_SIZE *
843; ** this routine will call "Get dev parm" with "BUILD BPB BIT" on. If it *
844; ** fails to get that info, then the source medium must be bad(vergin) or *
845; ** below DOS 2.0 level diskette, and will jmp to the old logic. *
846; ** For compatibility reasons (in case of non IBM formatted media), this *
847; ** routine covers old diskcopy routines. But this will only supports
848; ** 5.25" 48 tpi 8, 9 sectors, 40 tracks and 5.25" 96 tpi, 15 sectors, 80 tracks
849; ** media. Other non IBM formatted media which are formatted differenty
850; ** from those values will result in unpreditable copy process.
851;*****************************************************************************
852
853CS_AGAIN:
854 XOR BX, BX
855 MOV BL, SOURCE_DRIVE
856 MOV MS_specialFunctions, GET_SP_FUNC_MED ;=00000001b
857 MOV CL, GETDEVPARM ;=60h
858 MOV DX, OFFSET MS_IOCTL_DRV_PARM
859 CALL GENERIC_IOCTL ;TRY TO GET MEDIA BPB INFO TOGETHER
860 ;WITH DEFAULT DEVICE INFO.
861 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
862 JE CS_AGAIN
863
864 CMP IO_ERROR, HARD_ERROR ;CANNOT GET MEDIA BPB?
865 JNE CS_NEW ; ;AC000;
866CS_OLD_BRIDGE:
867 JMP CS_OLD ;ASSUME OLD FORMATTED DISKETTE, FIRST. ;AC000;
868CS_NEW: ; ;AN000;
869 cmp ms_deviceBPB.csect_track,0 ;patch 1/16/86 J.K.
870 je cs_old_BRIDGE
871
872 cmp ms_deviceBPB.chead,0 ;cannot trust the info. from DOS.
873 je cs_old ;sanity check for devide by 0.
874
875 MOV AX, MS_deviceBPB.CTOTSECT
876 CWD ;CONVERT IT TO A DOUBLE WORD
877 DIV MS_deviceBPB.CSECT_TRACK
878 DIV MS_deviceBPB.CHEAD ;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
879 CMP AL, T_DRV_TRACKS ;IF # OF TRACKS FOR SOURCE MEDIA > # OF
880 ; TRACKS FOR TARGET DEVICE
881 JA CS_FATAL ;THEN, NOT COMPATIBLE
882
883 DEC AX ;DECREASE BY 1 FOR THIS PROGRAM'S USE.
884 MOV LAST_TRACK, AL ;SET LAST_TRACK
885 MOV AX, MS_deviceBPB.CSECT_TRACK
886 MOV SECT_TRACK_LAYOUT, AX ;VARIABLE FOR MS, MT_trackLayout.CSECT_F
887 CMP USER_OPTION_8, ON ;/8 OPTION SPECIFIED?
888 JNE CS_GO_ON
889
890 CMP AX, 8 ;SOURCE MEDIA # OF SECTORS/TRACK < 8 ?
891 JB CS_FATAL ;IF IT IS, THEN FATAL ERROR.
892
893 MOV AX, 8 ;ELSE SET IT TO 8
894CS_GO_ON:
895 CMP AL, T_DRV_SECT_TRACK
896 JA CS_FATAL
897
898 MOV END_OF_TRACK, AL ;SET END_OF_TRACK
899 MOV AX, MS_deviceBPB.CBYTE_SECT
900 MOV bSECTOR_SIZE, AX ;set the sector size in bytes.
901 CMP USER_OPTION, 1
902 JE CS_OPTION_1
903
904 MOV AX, MS_deviceBPB.CHEAD ;HEAD=1, 2
905 CMP AL, T_DRV_HEADS ;COMPARE SOURCE MEDIA SIDE WITH TARGET
906 ; DRIVE HEAD NUMBER
907 JA CS_FATAL ;SOURCE MEDIUM IS DOUBLE SIDED AND
908 ; TARGET DRIVE IS SINGLE SIDED.
909
910 DEC AX
911 MOV NO_OF_SIDES, AL ;NO_OF_SIDES=0, 1
912 JMP CS_SET_TABLE
913
914CS_FATAL:
915 MOV COMP_STATUS, FATAL
916 ;"Drive types or diskette types"
917 ;"not compatible"
918 PRINT MSGNUM_NOT_COMPATIBLE ; ;AC000;
919
920 JMP CS_EXIT
921
922CS_BAD:
923 MOV COMP_STATUS, FATAL
924 PRINT MSGNUM_BAD_FIRST ;"FIRST diskette bad or incompatible" ;AC000;
925
926 JMP CS_EXIT
927
928CS_OLD:
929
930 MOV READ_S_BPB_FAILURE, 1 ;SET FLAG
931 MOV bSECTOR_SIZE, 512 ;OLD SECTOR SIZE MUST BE 512 BYTES
932 XOR BX, BX
933 MOV BL, SOURCE_DRIVE
934 MOV IOCTL_TRACK, 0 ;TRACK=0
935 MOV IOCTL_SECTOR, 8 ;SECTOR=8
936 MOV IOCTL_HEAD, 0 ;HEAD = 0
937 CALL READ_A_SECTOR
938
939 JC CS_BAD ;SOURCE BAD
940
941 MOV IOCTL_SECTOR, 9 ;TRY TO READ SECTOR=9
942 CALL READ_A_SECTOR
943
944 JC CS_SECT8 ;YES, 8 SECTORS. ASSUME 40 TRACKS
945
946 MOV IOCTL_SECTOR, 15 ;try to read sector=15
947 CALL READ_A_SECTOR
948
949 JC CS_SECT9 ;**REMEMBER THIS ROUTINE DOES NOT COVER 3.5" MEDIA
950
951 JMP CS_SECT15
952
953CS_OPTION_1:
954 MOV NO_OF_SIDES, 0 ;1 SIDE COPY
955 JMP CS_SET_TABLE
956
957CS_SECT15:
958 MOV SECT_TRACK_LAYOUT, 15 ;VARIABLE FOR MS, MT_trackLayout.CSECT_F
959 MOV END_OF_TRACK, 15 ;ELSE END_OF_TRACK = 15
960 MOV LAST_TRACK, 79
961 JMP CS_OPTIONS
962
963CS_SECT8:
964 MOV SECT_TRACK_LAYOUT, 8 ;VARIABLE FOR MS, MT_trackLayout.CSECT_F
965 MOV END_OF_TRACK, 8 ;SOURCE 8 SECTORS
966 MOV LAST_TRACK, 39 ;ASSUME 40 TRACKS.
967 JMP CS_OPTIONS
968
969CS_SECT9:
970 MOV SECT_TRACK_LAYOUT, 9 ;VARIABLE FOR MS, MT_trackLayout.CSECT_F
971 MOV END_OF_TRACK, 9
972 MOV LAST_TRACK, 39 ;ASSUME 5.25 DISKETTE
973CS_OPTIONS:
974 CMP USER_OPTION_8, ON
975 JNE CS_CHK_SIDE
976
977 MOV END_OF_TRACK, 8
978CS_CHK_SIDE:
979 CMP USER_OPTION, 1
980 JE CS_OPTION_1
981
982 MOV IOCTL_HEAD, 1 ;HEAD 1
983 XOR AX, AX
984 MOV AL, END_OF_TRACK ;READ MATCHING END_OF_TRACK
985 ; OF THE OTHER SURFACE.
986 MOV IOCTL_SECTOR, AX
987 CALL READ_A_SECTOR
988
989 JC CS_OPTION_1 ;1 SIDED SOURCE
990
991 MOV NO_OF_SIDES, 1 ;2 SIDED SOURCE
992 CMP T_DRV_HEADS, 2 ;SOUCE=2 SIDED MEDIUM. IS TARGET
993 ; DOUBLE SIDED DRV?
994 JE CS_SET_TABLE
995
996 JMP CS_FATAL ;NOT COMPATIBLE
997
998CS_SET_TABLE:
999 CMP READ_S_BPB_FAILURE, 1 ;diskette without BPB info?
1000 JNE CS_SET_TABLE_NEXT
1001
1002 CALL SET_FOR_THE_OLD ;set deviceBPB info for before 2.0 level
1003
1004CS_SET_TABLE_NEXT:
1005 MOV BX, OFFSET MS_trackLayout ;SET TRACKLAYOUT OF SOURCE
1006 CALL SET_TRACKLAYOUT
1007
1008 MOV S_DRV_SET_FLAG, 1 ;indicate SOURCE DRIVE
1009 ; PARAMETER HAS BEEN SET
1010 XOR BX, BX
1011 MOV BL, SOURCE_DRIVE
1012 MOV DX, OFFSET MS_IOCTL_DRV_PARM
1013 MOV MS_specialFunctions, SET_SP_FUNC_DEF
1014 CALL SET_DRV_PARM_DEF ;set device parameter for read
1015
1016 XOR AX, AX
1017 MOV AL, END_OF_TRACK
1018 MOV numberOfSectors, AX ;SET NUMBEROFSECTORS IN IOCTL_R_W TABLE
1019
1020 MOV AL, LAST_TRACK ;NOW, SHOW THE MESSAGE "COMPARING ..."
1021 INC AL
1022 MOV BYTE PTR MSG_TRACKS,AL ;HOW MANY TRACKS? ;AC000;
1023
1024 MOV AL, END_OF_TRACK
1025 MOV BYTE PTR MSG_SECTRK,AL ;HOW MANY SECTORS? ;AC000;
1026
1027 MOV AL, NO_OF_SIDES ;TELL USER HOW MANY SIDE TO COPY
1028 INC AL
1029 MOV BYTE PTR MSG_SIDES,AL ; ;AC000;
1030 ;CR,LF,"Comparing %1 tracks",CR,LF
1031 ;"%2 Sectors/Track, %3 Side(s)",CR,LF
1032 PRINT MSGNUM_COMPARING ; ;AC000;
1033
1034CS_EXIT:
1035 RET
1036
1037CHECK_SOURCE ENDP
1038; = = = = = = = = = = = =
1039 HEADER <READ_A_SECTOR - USE IOCTL READ TO GET A SECTOR> ; ;AN000;
1040;*****************************************************************************
1041 PUBLIC READ_A_SECTOR ;MAKE ENTRY IN LINK MAP ;AN000;
1042READ_A_SECTOR PROC NEAR
1043;
1044;TRY TO READ A SECTOR USING IOCTL READ FUNCTION CALL.
1045;THIS ROUTINE WILL STEAL "IOCTL_R_W" TABLE TEMPORARILY.
1046;INPUT: BX - LOGICAL DRIVE NUMBER
1047; IOCTL_SECTOR - SECTOR TO READ
1048; IOCTL_TRACK - TRACK
1049; IOCTL_HEAD - HEAD TO READ
1050; bSECTOR_SIZE - SECTOR SIZE IN BYTES
1051;OUTPUT:
1052; IF NOT A SUCCESS, CARRY WILL BE SET
1053; ALL REGISTORS SAVED
1054;*****************************************************************************
1055 PUSH AX
1056 PUSH BX
1057 PUSH CX
1058 PUSH DX
1059
1060 MOV AX, numberOfSectors ;SAVE IOCTL_R_W TABLE VALUES
1061 MOV SAV_CSECT, AX
1062
1063; $DO
1064$$DO36:
1065 MOV AX, IOCTL_HEAD
1066 MOV Head, AX ;SURFACE TO READ
1067 MOV AX, IOCTL_TRACK
1068 MOV Cylinder, AX ;TRACK TO READ
1069 MOV AX, IOCTL_SECTOR
1070 dec ax ;????? currently firstsector=0 =>
1071 ; 1st sector ????
1072 MOV FirstSectors, AX ;SECTOR TO READ
1073 MOV numberOfSectors, 1 ;read just one sector
1074 MOV AX, offset INIT ;READ IT INTO INIT (CURRELTLY, MAX 1K)
1075 MOV TAddress_off, AX
1076 MOV TAddress_seg, DS
1077 MOV CL, READ_FUNC
1078 MOV DX, OFFSET IOCTL_R_W ;POINTS TO CONTROL TABLE
1079 call generic_ioctl
1080
1081 CMP IO_ERROR, SOFT_ERROR ;TRY ONCE MORE?
1082; $ENDDO NE
1083 JE $$DO36
1084
1085 CMP IO_ERROR, HARD_ERROR ;HARD ERROR?
1086; $IF NE
1087 JE $$IF38
1088
1089 CLC ;READ SUCCESS
1090; $ELSE
1091 JMP SHORT $$EN38
1092$$IF38:
1093
1094 STC ;READ FAILURE, SET CARRY
1095; $ENDIF
1096$$EN38:
1097 MOV AX, SAV_CSECT ;RESTORE ORIGINAL IOCTL_R_W TABLE
1098 MOV numberOfSectors, AX
1099 POP DX
1100 POP CX
1101 POP BX
1102 POP AX
1103 RET
1104READ_A_SECTOR ENDP
1105; = = = = = = = = = = = =
1106 HEADER <CALC_TRACK_SIZE - FIND MEM SIZE TO HOLD ONE TRACK> ; ;AN000;
1107;*****************************************************************************
1108; *
1109 PUBLIC CALC_TRACK_SIZE ;MAKE ENTRY IN LINK MAP ;AN000;
1110CALC_TRACK_SIZE PROC NEAR ;CALCULATE MEMORY SIZE REQUIRED TO STORE ONE
1111; TRACK (IN SEGMENTS) *
1112;CALCULATE SECTOR_SIZE IN PARA FROM bSECTOR_SIZE. IF bSECTOR_SIZE CANNOT BE
1113;CHANGED TO SECTOR_SIZE IN PARA EXACTLY, THEN ADD 1 TO THE SECTOR_SIZE.
1114;SECTOR_SIZE IS USED FOR MEMORY MANAGEMANT ONLY. THE ACTUAL COPY OR FORMAT
1115;SHOULD BE DEPENDS ON bSECTOR_SIZE TO FIGURE OUT HOW BIG A SECTOR IS.
1116;ALSO, CURRENTLY, THIS ROUTINE ASSUME A BSECTOR SIZE BE LESS THAN 0FFFh.
1117;*****************************************************************************
1118
1119 PUSH AX
1120 PUSH BX
1121 PUSH CX
1122
1123 MOV AX, bSECTOR_SIZE
1124 XOR DX, DX
1125 XOR BX, BX
1126 MOV BL, END_OF_TRACK
1127 MUL BX ;ASSUME DX=0
1128 MOV BYTES_IN_TRACK,AX ;BYTES/TRACK ON A SIDE OF THE DISKETTE
1129
1130 MOV AX, bSECTOR_SIZE
1131 MOV CL, 16
1132 DIV CL ;AX / 16 = AL ... AH
1133 CMP AH, 0 ;NO REMAINER?
1134; $IF NE
1135 JE $$IF41
1136
1137 INC AL ;THERE REMAINER IS. INC AL
1138; $ENDIF
1139$$IF41:
1140 MOV SECTOR_SIZE, AL ;SECTOR_SIZE+ IN PARA.
1141 MOV AL,NO_OF_SIDES ;TRACK_SIZE = (NO OF SIDES
1142 INC AL ; + 1)
1143 MUL END_OF_TRACK ; * END_OF_TRACK
1144 MOV BL,SECTOR_SIZE ; * SECTPR_SIZE
1145 MUL BL ;AMOUNT OF MEMORY REQUIRED (IN SEG)
1146 MOV TRACK_SIZE,AX ;TO STORE A TRACK
1147
1148 MOV BX,START_BUFFER ;SET SECONDARY AT START OF BUFFER SPACE
1149 MOV SEC_BUFFER,BX ;SET THE SECONDARY BUFFER SEG ADDR
1150 ADD BX,AX ;MOVE THE PRIMARY BUFFER BELOW THE
1151 MOV BUFFER_BEGIN,BX ;SECONDARY BUFFER
1152 POP CX
1153 POP BX
1154 POP AX
1155
1156 RET
1157
1158CALC_TRACK_SIZE ENDP
1159; = = = = = = = = = = = =
1160 HEADER <CHECK_MEMORY_SIZE - BE SURE ENUF ME TO COMPARE 1 TRACK> ; ;AN000;
1161;*****************************************************************************
1162; *
1163 PUBLIC CHECK_MEMORY_SIZE ;MAKE ENTRY IN LINK MAP ;AN000;
1164CHECK_MEMORY_SIZE PROC NEAR ;MAKE SURE WE HAVE ENOUGH TO COMP 1 TRACK INTO
1165; TO BUFFER ELSE ABORT COMP *
1166;*****************************************************************************
1167 MOV AX,BUFFER_END
1168 SUB AX,BUFFER_BEGIN
1169 CMP AX,TRACK_SIZE
1170; $IF B
1171 JNB $$IF43
1172 MOV COMP_STATUS,FATAL
1173 ;"Insufficient memory"
1174 PRINT MSGNUM_UNSUF_MEMORY ; ;AC000;
1175
1176; $ENDIF
1177$$IF43:
1178 RET
1179
1180CHECK_MEMORY_SIZE ENDP
1181; = = = = = = = = = = = =
1182 HEADER <COMP_TARGET - COMPARE MEM DATA WITH SECOND DISKETTE> ; ;AN000;
1183;*****************************************************************************
1184; *
1185 PUBLIC COMP_TARGET ;MAKE ENTRY IN LINK MAP ;AN000;
1186COMP_TARGET PROC NEAR ;COMPARE DATA FROM MEMORY TO TARGET DISKETTE
1187; *
1188;*****************************************************************************
1189
1190 CMP COPY_TYPE,1 ;IF SINGLE DRIVE COMP
1191; $IF E ;PROMPT MSG
1192 JNE $$IF45
1193 CMP MSG_FLAG,SECOND
1194; $IF E
1195 JNE $$IF46
1196 CALL DISPLAY_LOAD_SECOND ;"Insert SECOND diskette in drive %1:" ;AN000;
1197
1198; $ELSE
1199 JMP SHORT $$EN46
1200$$IF46:
1201 CALL DISPLAY_LOAD_FIRST ;"Insert FIRST diskette in drive %1:" ;AN000;
1202
1203; $ENDIF
1204$$EN46:
1205 CALL PRESS_ANY_KEY ;"Press any key to continue . . ." ;AC009;
1206
1207; $ENDIF
1208$$IF45:
1209 MOV BX,BUFFER_BEGIN
1210 MOV COMPARE_PTR,BX ;INITIALIZE BUFFER POINTER
1211 CMP TRACK_TO_COMP,0 ;IF TRK 0, CHECK COMPATIBILITY
1212; $IF E
1213 JNE $$IF50
1214 CALL CHECK_TARGET
1215
1216 CMP COMP_STATUS,FATAL ;IF INCOMPATIBLE, THEN EXIT
1217 JE CT_EXIT
1218
1219; $ENDIF
1220$$IF50:
1221
1222 CALL SWAP_DRIVE
1223
1224; $DO
1225$$DO52:
1226 CALL COMP_TRACK ;NO, GO READ ANOTHER TRACK
1227
1228 INC TRACK_TO_READ
1229 MOV AL,TRACK_TO_READ ;DID WE FINISH READING ALL TRACKS?
1230 CMP AL,LAST_TRACK
1231; $LEAVE A
1232 JA $$EN52
1233
1234 MOV AX,COMPARE_PTR ;DID WE RUN OUT OF BUFFER SPACE
1235 ADD AX,TRACK_SIZE
1236 CMP AX,BUFFER_END
1237; $ENDDO A
1238 JNA $$DO52
1239$$EN52:
1240
1241CT_EXIT:
1242 RET
1243COMP_TARGET ENDP
1244; = = = = = = = = = = = =
1245 HEADER <CHECK_TARGET - COMPARE SECOND DISK BOOT RECORD> ; ;AN000;
1246;*****************************************************************************
1247 PUBLIC CHECK_TARGET ;MAKE ENTRY IN LINK MAP ;AN000;
1248CHECK_TARGET PROC NEAR ; *
1249; ** CHECK_SOURCE PROCEDURE ALREADY CHECKS OUT THE INCOMPATIBILITY BETWEEN *
1250; ** SOURCE MEDIA AND TARGET DRIVE. (CHECKING SOURCE MEDIA SECTOR/TRACK *
1251; ** EXCEEDS TARGET DRV SECTOR/TRACK, AND SOURCE MEDIA # OF TRACKS WITH *
1252; ** THAT OF TARGET DRV.) *
1253; ** THIS ROUTINE WILL TRY TO READ TARGET MEDIA BOOT RECORD. *
1254; ** IF A SUCCESS,THEN COMPARE BPB INFO WITH THAT OF SOURCE MEDIA. *
1255; ** IF THEY ARE DIFFERENT, THEN ERROR - NOT COMPATIBLE *
1256; ** IF FAILED TO READ A BOOT, THEN TRY OLD LOGICS BEFORE DOS 3.2 FOR *
1257; ** COMPATIBILITY REASONS. *
1258;*****************************************************************************
1259; $DO
1260$$DO55:
1261 XOR BX, BX
1262 MOV BL, TARGET_DRIVE
1263 MOV MT_specialFunctions, GET_SP_FUNC_MED ;=00000001b
1264 MOV CL, GETDEVPARM
1265 MOV DX, OFFSET MT_IOCTL_DRV_PARM
1266 CALL GENERIC_IOCTL ;TRY TO GET MEDIA BPB INFO TOGETHER
1267 ;WITH THE DEFAULT DEVICE INFO.
1268 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
1269; $ENDDO NE
1270 JE $$DO55
1271
1272 CMP IO_ERROR, HARD_ERROR ;ASSUME OLD DISKTETTE. OR DISKETTE BAD
1273 JE CHT_OLD
1274
1275 cmp mt_deviceBPB.csect_track,0 ;patch 1/16/86, J.K.
1276 je cht_old
1277
1278 cmp mt_deviceBPB.chead,0 ;cannot trust the info from DOS.
1279 je cht_old ;sanity check for devide by 0
1280
1281 MOV AX, MT_deviceBPB.CTOTSECT
1282 CWD ;CONVERT IT TO A DOUBLE WORD
1283 DIV MT_deviceBPB.CSECT_TRACK
1284 DIV MT_deviceBPB.CHEAD ;(TOTAL SECTORS / # OF TRACKS) / # OF HEADS
1285 DEC AX ;DECREASE BY 1 FOR THIS PROGRAM
1286 CMP LAST_TRACK, AL ;COMPARE WITH SOURCE LAST TRACK
1287 JNE CHT_FATAL_BRIDGE ;IF LAST_TRACK IS DIFFERENT,
1288 ; THEN INCOMPATIBLE.
1289
1290 MOV AX, MT_deviceBPB.CSECT_TRACK
1291 MOV SECT_TRACK_LAYOUT, AX ;VARIBLE FOR MT_trackLayout.CSECT_F
1292CHT_GO_ON:
1293 CMP END_OF_TRACK, AL
1294 JA CHT_FATAL_BRIDGE ;IF SOURCE END_OF_TRACK > TARGET
1295 ; END_OF_TRACK, THEN ERROR
1296
1297 ;8 SECTORED SOURCE AND 9 SECTORED TARGET
1298 ; IS OK AS FAR AS THE COMPATIBILITY GOES.
1299 MOV AX, MT_deviceBPB.CBYTE_SECT
1300 CMP AX, bSECTOR_SIZE ;IF SECTOR SIZE ARE DIFFERENT, THEN
1301 ; NOT COMPATIBLE
1302 JNE CHT_FATAL_BRIDGE
1303
1304 CMP NO_OF_SIDES, 1 ;TWO SIDED COPY?
1305 JNE CHT_SET_BRIDGE ;NO, ONE SIDED. DON'T
1306 ; CARE ABOUT TARGET SIDES.
1307
1308 CMP MT_deviceBPB.CHEAD, 2 ;TARGET FORMATTED INTO TWO SIDES?
1309 JNE CHT_FATAL_BRIDGE ;NO, NOT COMPATIBLE
1310
1311 JMP CHT_SET_DRV ;OK. SOURCE, TARGET MEDIA ARE MATCHING. SET
1312 ; DRV PARM FOR READING
1313
1314CHT_SET_BRIDGE:
1315 JMP CHT_SET_DRV
1316
1317CHT_FATAL_BRIDGE:
1318 JMP CHT_FATAL
1319
1320CHT_SECOND_BAD:
1321 MOV COMP_STATUS, FATAL
1322 PRINT MSGNUM_BAD_SECOND ;"SECOND diskette bad or incompatible" ;AC000;
1323
1324 JMP CHT_EXIT
1325
1326CHT_OLD: ;SAME OLD. ;AGAIN, THIS DOES
1327 ; NOT RECOGNIZE 3.5 MEDIA
1328 MOV READ_T_BPB_FAILURE, 1 ;SET THE FLAG.
1329 XOR BX, BX
1330 MOV BL, TARGET_DRIVE
1331 MOV IOCTL_TRACK, 0
1332 MOV IOCTL_SECTOR, 8
1333 MOV IOCTL_HEAD, 0 ;TRY TO READ HEAD 0, TRACK 0, SECTOR 8
1334 CALL READ_A_SECTOR
1335
1336 JC CHT_SECOND_BAD ;ASSUME TARGET MEDIA NOT FORMATTED.
1337
1338 MOV IOCTL_SECTOR, 9 ;TRY TO READ SECTOR 9
1339 CALL READ_A_SECTOR
1340
1341 JC CHT_8_SECTOR ;TARGET IS 8 SECTOR MEDIA
1342
1343 MOV IOCTL_SECTOR, 15
1344 CALL READ_A_SECTOR
1345
1346 JC CHT_9_SECTOR ;TARGET IS 9 SECTOR MEDIA
1347
1348;CHT_15_SECTOR: ;TARGET IS 15 SECTOR MEDIA
1349 MOV SECT_TRACK_LAYOUT, 15
1350 CMP END_OF_TRACK, 15 ;IS SOUCE ALSO 96 TPI?
1351 JNE CHT_FATAL ;NO, FATAL ERROR
1352
1353 JMP SHORT CHT_CHK_SIDE ;YES, OK.
1354
1355CHT_8_SECTOR:
1356 MOV SECT_TRACK_LAYOUT, 8
1357 CMP END_OF_TRACK, 15
1358 JE CHT_FATAL ;IF SOURCE IS 96 TPI, THEN FATAL ERROR
1359
1360 CMP END_OF_TRACK, 9
1361 JE CHT_FATAL ;IF SOURCE IS 9 SECTOR, THEN
1362 ; SHOULD FORMAT TARGET
1363
1364 JMP SHORT CHT_CHK_SIDE ;ELSE ASSUME SOURCE IS 8 SECTOR.
1365
1366CHT_9_SECTOR:
1367 MOV SECT_TRACK_LAYOUT, 9
1368 CMP END_OF_TRACK, 15 ;IS SOURCE 96 TPI? THEN ERROR
1369 JE CHT_FATAL ;ELSE SOUCE IS 8 OR 9 SECTORED
1370 ; 48 TPI DISKETTE
1371
1372CHT_CHK_SIDE: ;CHECK THE TARGET DISKETTE # OF SIDES
1373 CMP NO_OF_SIDES, 0 ;1 SIDE COMP?
1374 JE CHT_EXIT_OLD ;
1375
1376 MOV IOCTL_HEAD, 1 ;ELSE TWO SIDE COMP
1377 XOR AX, AX
1378 MOV AL, END_OF_TRACK ;TRY TO READ MATCHING TARGET SECTOR
1379 MOV IOCTL_SECTOR, AX ;OF THE OTHERSIDE
1380 CALL READ_A_SECTOR
1381
1382 JNC CHT_EXIT_OLD ;SUCCESS? OK
1383
1384CHT_FATAL:
1385 CALL COMPAT_ERROR
1386
1387 JMP SHORT CHT_EXIT
1388
1389CHT_EXIT_OLD:
1390 CALL SET_FOR_THE_OLD ;SET MT_deviceBPB INFO.
1391
1392CHT_SET_DRV:
1393 MOV BX, OFFSET MT_trackLayout ;SET TARGET TRACK LAYOUT
1394 CALL SET_TRACKLAYOUT
1395
1396 JC CHT_FATAL ;IF FAILED, THEN, NOT COMPATIBLE
1397
1398 MOV T_DRV_SET_FLAG, 1 ;INDICATES THE TARGET DEFAULT
1399 ; DEVICE PARM HAS BEEN SET
1400 XOR BX, BX
1401 mov bl, last_track ;To make sure the number of
1402 ; cyl. of target. 3/27/86,J.K.
1403 inc bl
1404 mov MT_numberOfCylinders, bx
1405 MOV BL, TARGET_DRIVE
1406 MOV DX, OFFSET MT_IOCTL_DRV_PARM
1407 MOV MT_specialFunctions, SET_SP_FUNC_DEF
1408 CALL SET_DRV_PARM_DEF
1409
1410CHT_EXIT:
1411 RET
1412
1413CHECK_TARGET ENDP
1414; = = = = = = = = = = = =
1415 HEADER <SET_DRV_PARM - REQUEST IOCTL TO SET DEVICE PARM> ; ;AN000;
1416;*****************************************************************************
1417 PUBLIC SET_DRV_PARM_DEF ;MAKE ENTRY IN LINK MAP ;AN000;
1418SET_DRV_PARM_DEF PROC NEAR
1419;INPUT: BL - DRIVE NUMBER
1420; DX - POINTER TO THE PARAMETER TABLE
1421; specialFunction should be set before this call
1422;*****************************************************************************
1423
1424 MOV CL, SETDEVPARM ;=40H
1425 CALL GENERIC_IOCTL
1426
1427 RET
1428
1429SET_DRV_PARM_DEF ENDP
1430; = = = = = = = = = = = =
1431 HEADER <COMP_TRACK - READ AND COMPARE SPECIFIED TRACK> ; ;AN000;
1432;*****************************************************************************
1433; *
1434 PUBLIC COMP_TRACK ;MAKE ENTRY IN LINK MAP ;AN000;
1435COMP_TRACK PROC NEAR ;COMPARE TRACK SPECIFIED IN TRACK_TO_COMP
1436; *
1437;*****************************************************************************
1438 MOV AX,SEC_BUFFER ;READ IN THE TRACK TO BE COMPARED
1439 MOV BUFFER_PTR,AX ;INTO THE SECONDARY BUFFER
1440 CALL READ_TRACK
1441
1442 MOV SIDE,0 ;START ON SIDE ZERO
1443 MOV CX,BYTES_IN_TRACK ;GET NUMBER TO COMPARE
1444 PUSH DS
1445 PUSH ES
1446 MOV ES,COMPARE_PTR ;SET DESTINATION SEG ADDR
1447 MOV DS,SEC_BUFFER ;SET SOURCE SEG ADDR
1448
1449 ASSUME ES:NOTHING
1450 ASSUME DS:NOTHING
1451
1452 XOR DI,DI ;SET TO START OF TRACK
1453 XOR SI,SI
1454 CMP FIRST_TIME,ZERO ;IF THIS IS THE FIRST SECTOR TO BE COMPARED ;AN000;
1455; $IF E ; ;AN000;
1456 JNE $$IF57
1457 CALL VOLSER ;SPECIAL HANDLING FOR VOL SER # ;AN000;
1458
1459 MOV FIRST_TIME,ONE ;FLAG FIRST TIME AS "DONE" ;AN000;
1460; $ENDIF ; ;AN000;
1461$$IF57:
1462 CALL DO_COMPARE ;COMPARE STRING ;AN000;
1463
1464 POP ES
1465 POP DS
1466
1467 ASSUME ES:CSEG
1468 ASSUME DS:CSEG
1469
1470; $IF NZ
1471 JZ $$IF59
1472 PUSH AX ;SAVE AX SINCE ERROR_MESSAGE WILL DESTROY IT
1473 MOV OPERATION,COMPARE_FUNC
1474 CALL ERROR_MESSAGE
1475
1476 INC COMP_ERROR
1477 POP AX
1478; $ENDIF
1479$$IF59:
1480 CMP NO_OF_SIDES,1 ;TWO SIDED COMPARE?
1481; $IF E ;YES
1482 JNE $$IF61
1483 MOV SIDE,1 ;MARK IT AS SUCH
1484 MOV SI,BYTES_IN_TRACK ;BUMP UP BUFFER POINTERS
1485 MOV DI,BYTES_IN_TRACK ;TO START OF SECOND SIDE
1486 MOV CX,BYTES_IN_TRACK ;GET NUMBER TO COMPARE
1487 PUSH DS
1488 PUSH ES
1489 MOV ES,COMPARE_PTR ;SET DESTINATION SEG ADDR
1490 MOV DS,SEC_BUFFER ;SET SOURCE SEG ADDR
1491 CALL DO_COMPARE ;COMPARE STRING ;AN000;
1492
1493 POP ES
1494 POP DS
1495; $IF NZ
1496 JZ $$IF62
1497 PUSH AX ;SAVE AX SINCE ERROR_MESSAGE WILL DESTROY IT
1498 MOV OPERATION,COMPARE_FUNC
1499 CALL ERROR_MESSAGE
1500
1501 INC COMP_ERROR
1502 POP AX
1503; $ENDIF
1504$$IF62:
1505; $ENDIF
1506$$IF61:
1507 MOV AX,TRACK_SIZE ;ADVANCE COMPARE POINTER
1508 ADD COMPARE_PTR,AX
1509 RET
1510COMP_TRACK ENDP
1511; = = = = = = = = = = = =
1512 HEADER <DO_COMPARE - PERFORM THE COMPARISON> ; ;AN000;
1513DO_COMPARE PROC NEAR ; ;AN000;
1514 PUBLIC DO_COMPARE ;ADD ENTRY TO LINK MAP ;AN000;
1515;INPUT: DS:[SI] POINTS TO ONE BUFFER, ES:[DI] POINTS TO THE OTHER
1516; CX HAS THE BYTE COUNT
1517;OUTPUT:CONDITION CODE IN CONDITION FLAGS REFLECT RESULT OF COMPARISON
1518; = = = = = = = = = = = =
1519 SHR CX,1 ;DIVIDE BY TWO, CHANGE TO WORD COUNT ;AN000;
1520
1521 PUBLIC PATCH_386 ;SO INIT CAN DO FIXUP ;AN001;
1522PATCH_386 LABEL BYTE
1523 SHR CX,1 ;CONVERT WORD COUNT TO DWORD COUNT ;AN001;
1524 DB 66H ;PREFIX FOR A DWORD COMPARE ;AN001;
1525; END OF PATCH AREA. IF THIS IS NOT A 386, THE ABOVE 3 BYTES ARE CHANGED
1526; TO NOP BY DISKINIT.SAL DURING INITIALIZATION.
1527
1528 REPE CMPSW ;PERFORM THE COMPARISON ;AN000;
1529
1530 RET ;RETURN TO CALLER ;AN000;
1531DO_COMPARE ENDP ; ;AN000;
1532; = = = = = = = = = = = =
1533 HEADER <SWAP_DRIVE - SETUP FOR DISKETTE SWAPPING> ; ;AN000;
1534;*****************************************************************************
1535 PUBLIC SWAP_DRIVE ;MAKE ENTRY IN LINK MAP ;AN000;
1536SWAP_DRIVE PROC NEAR ;SWAP SOURCE, TARGET DRIVE
1537;*****************************************************************************
1538 MOV AL,SOURCE_DRIVE
1539 XCHG AL,TARGET_DRIVE
1540 MOV SOURCE_DRIVE,AL
1541 MOV AL,TRACK_TO_COMP
1542 XCHG AL,TRACK_TO_READ
1543 MOV TRACK_TO_COMP,AL
1544 RET
1545
1546SWAP_DRIVE ENDP
1547 HEADER <READ_TRACK - READ A TRACK TO MEMORY> ; ;AN000;
1548;*****************************************************************************
1549; *
1550 PUBLIC READ_TRACK ;MAKE ENTRY IN LINK MAP ;AN000;
1551READ_TRACK PROC NEAR ;READ A TRACK AND STORE IT INTO MEMORY
1552; *
1553;*****************************************************************************
1554
1555 MOV SIDE, 0
1556; $DO
1557$$DO65:
1558 CALL READ_OP
1559
1560 CMP NO_OF_SIDES, 0 ;SINGLE SIDE COPY?
1561; $IF E ;YES
1562 JNE $$IF66
1563 MOV AX, TRACK_SIZE
1564; $ELSE ;NO, DOUBLE SIDE
1565 JMP SHORT $$EN66
1566$$IF66:
1567 XOR DX, DX
1568 MOV AX, TRACK_SIZE
1569 MOV CX, 2
1570 DIV CX ;AX / 2
1571; $ENDIF
1572$$EN66:
1573 ADD BUFFER_PTR, AX
1574 INC SIDE ;NEXT SIDE
1575 MOV AL, SIDE
1576 CMP AL, NO_OF_SIDES ;FINISHED WITH THE LAST SIDE?
1577; $ENDDO G
1578 JNG $$DO65
1579 RET
1580
1581READ_TRACK ENDP
1582; = = = = = = = = = = = =
1583 HEADER <READ_OP - IOCTL TO READ A TRACK> ; ;AN000;
1584;*****************************************************************************
1585; *
1586 PUBLIC READ_OP ;MAKE ENTRY IN LINK MAP ;AN000;
1587READ_OP PROC NEAR ;IOCTL READ A TRACK OPERATION
1588; *
1589;*****************************************************************************
1590; $SEARCH
1591$$DO70:
1592RO_AGAIN:
1593 XOR AX, AX
1594 MOV AL, SIDE
1595 MOV Head, AX ;HEAD TO READ
1596 MOV AL, TRACK_TO_READ
1597 MOV Cylinder, AX ;TRACK TO READ
1598 MOV FirstSectors, 0 ;???? SHOULD BE 1 BUT CURRENTLY 0 ???
1599 MOV AX, BUFFER_PTR
1600 MOV Taddress_seg, AX ;BUFFER ADDRESS
1601 MOV Taddress_off, 0
1602 XOR BX, BX
1603 MOV BL, SOURCE_DRIVE
1604 MOV CL, READ_FUNC ;=61h
1605 MOV DX, OFFSET IOCTL_R_W
1606 CALL GENERIC_IOCTL
1607
1608 CMP IO_ERROR, NO_ERROR ;OK?
1609; $EXITIF E,NUL
1610 JE $$SR70
1611
1612 CMP IO_ERROR, SOFT_ERROR ;TRY AGAIN?
1613; $ENDLOOP NE
1614 JE $$DO70
1615
1616 MOV OPERATION, READ_FUNC
1617 PUSH AX
1618 CALL ERROR_MESSAGE
1619
1620 POP AX
1621 INC COMP_ERROR ;INCREASE COPY_ERROR COUNT
1622; $ENDSRCH
1623$$SR70:
1624 RET
1625READ_OP ENDP
1626; = = = = = = = = = = = =
1627 HEADER <SET_FOR_THE_OLD - USE PRE 2.0 BPB> ; ;AN000;
1628;*****************************************************************************
1629 PUBLIC SET_FOR_THE_OLD ;MAKE ENTRY IN LINK MAP ;AN000;
1630SET_FOR_THE_OLD PROC NEAR
1631;set MS_deviceBPB or MT_deviceBPB for before-2.0 formatted media.
1632;*****************************************************************************
1633 PUSH AX
1634
1635 CMP SECT_TRACK_LAYOUT,9 ;IF SECTORS/TRACK <= 9, THEN CHECK
1636 ;NO_OF_SIDES. IF SINGLE SIDE COPY
1637 ; THEN USE BPB48_SINGLE
1638 ;ELSE USE BPB48_DOUBLE.
1639; $IF A ;SECTORS/TRACK > 9 THEN USE BPB96 TABLE
1640 JNA $$IF74
1641 MOV SI, OFFSET BPB96
1642; $ELSE
1643 JMP SHORT $$EN74
1644$$IF74:
1645 CMP NO_OF_SIDES, 0 ;SINGLE SIDE COPY?
1646; $IF NE
1647 JE $$IF76
1648 MOV SI, OFFSET BPB48_DOUBLE ;ELSE USE BPB48 DOUBLE
1649; $ELSE
1650 JMP SHORT $$EN76
1651$$IF76:
1652 MOV SI, OFFSET BPB48_SINGLE
1653; $ENDIF
1654$$EN76:
1655; $ENDIF
1656$$EN74:
1657 MOV AX, SECT_TRACK_LAYOUT
1658 CMP READ_S_BPB_FAILURE, 1 ;FAILURE ON THE SOURCE?
1659; $IF E
1660 JNE $$IF80
1661 MOV MS_deviceBPB.CSECT_TRACK,AX ;SET # OF SECTORS IN IOCTL_DRV_PARM
1662 MOV DI, OFFSET MS_deviceBPB
1663 MOV CX, BPB96_LENG
1664 REP MOVSB ;OLD DEFAULT BPB INFO => MS_deviceBPB
1665; $ELSE
1666 JMP SHORT $$EN80
1667$$IF80:
1668 CMP READ_T_BPB_FAILURE, 1 ;FAILURE ON THE TARGET?
1669; $IF E
1670 JNE $$IF82
1671 MOV MT_deviceBPB.CSECT_TRACK,AX
1672 MOV DI, OFFSET MT_deviceBPB
1673 MOV CX, BPB96_LENG
1674 REP MOVSB ;OLD DEFAULT BPB INTO => MT_deviceBPB
1675; $ENDIF
1676$$IF82:
1677; $ENDIF
1678$$EN80:
1679 POP AX
1680 RET
1681SET_FOR_THE_OLD ENDP
1682; = = = = = = = = = = = =
1683 HEADER <SET_TRACKLAYOUT - DETERMINE SECTORS PER TRACK> ; ;AN000;
1684;*****************************************************************************
1685 PUBLIC SET_TRACKLAYOUT ;MAKE ENTRY IN LINK MAP ;AN000;
1686SET_TRACKLAYOUT PROC NEAR
1687;INPUT: BX - POINTER TO DESTINATION
1688; SECT_TRACK_LAYOUT
1689;*****************************************************************************
1690 MOV CX, SECT_TRACK_LAYOUT ;MEDIA SECTORS/TRACK
1691 MOV WORD PTR [BX], CX ;SET CSECT_F TO THE NUMBER OF SECTORS
1692 ; IN A TRACK
1693 ADD BX, 2 ;NOW BX POINTS TO THE FIRST SECTORNUMBER
1694 MOV CX, 1
1695 MOV AX, bSECTOR_SIZE
1696
1697; $DO
1698$$DO85:
1699 CMP CX, SECT_TRACK_LAYOUT
1700; $LEAVE A
1701 JA $$EN85
1702
1703 MOV WORD PTR [BX], CX
1704 INC BX
1705 INC BX
1706 MOV WORD PTR [BX], AX
1707 INC BX
1708 INC BX
1709
1710 INC CX
1711; $ENDDO
1712 JMP SHORT $$DO85
1713$$EN85:
1714
1715 RET
1716SET_TRACKLAYOUT ENDP
1717; = = = = = = = = = = = =
1718 HEADER <GENERIC_IOCTL - PERFORM SPECIFIED IOCTL FUNCTION> ; ;AN000;
1719PUBLIC GENERIC_IOCTL
1720;******************************************************************************
1721GENERIC_IOCTL PROC NEAR
1722;INPUT: CL - MINOR CODE; 60 - GET DEVICE PARM, 40 - SET DEVICE PARM
1723; 61 - READ TRACK, 41 - WRITE TRACK,
1724; 42 - FORMAT AND VERIFY TRACK
1725; 62 - VERIFY TRACK
1726; BL - LOGICAL DRIVE LETTER
1727; DS:DX - POINTER TO PARAMETERS
1728;******************************************************************************
1729
1730 MOV IO_ERROR, NO_ERROR ;reset io_error
1731 MOV AH, IOCTL_FUNC ;IOCTL FUNC = 44H
1732 MOV AL, GENERIC_IOCTL_CODE ;GENERIC IOCTL REQUEST = 0DH
1733 MOV CH, MAJOR_CODE ;MAJOR CODE=08H, REMOVABLE
1734 INT 21H
1735; $IF C
1736 JNC $$IF88
1737 CALL EXTENDED_ERROR_HANDLER ;ERROR, SEE WHAT IT IS!
1738
1739; $ENDIF
1740$$IF88:
1741 RET
1742GENERIC_IOCTL ENDP
1743; = = = = = = = = = = = =
1744 HEADER <EXTENDED_ERROR - DETERMINE AND SERVICE EXTENDED ERRORS> ; ;AN000;
1745;******************************************************************************
1746 PUBLIC EXTENDED_ERROR_HANDLER ;MAKE ENTRY IN LINK MAP ;AN000;
1747EXTENDED_ERROR_HANDLER PROC NEAR
1748;INPUT: BL - LOGICAL DRIVE LETTER
1749;******************************************************************************
1750 PUSHF
1751 PUSH AX
1752 PUSH BX
1753 PUSH CX
1754 PUSH DX
1755 PUSH SI
1756 PUSH DI
1757 PUSH ES
1758 PUSH DS
1759 PUSH BX
1760
1761 MOV AH, 59H
1762 MOV BX, 0
1763 INT 21H
1764
1765; CMP BL, 5 ;ACTION=IMMEDIATE EXIT?
1766; JE EEH_JUST_EXIT
1767
1768 POP BX ;RESTORE BL FOR DRIVE LETTER
1769 POP DS
1770 POP ES
1771
1772 CMP AX, 21 ;DRIVE NOT READY?
1773 JE WARN_USER_1
1774
1775 CMP AX, 19 ;ATTEMP TO WRITE ON WRITE_PROTECTED?
1776 JE WARN_USER_2
1777
1778 JMP EEH_HARD_ERROR ;OTHERWISE, HARD_ERROR
1779
1780WARN_USER_1:
1781 MOV DRIVE_LETTER, 'A'
1782 DEC BL ;CHANGE LOGICAL TO PHYSICAL
1783 ADD DRIVE_LETTER, BL
1784 ;"Drive not ready - X:"
1785 PRINT MSGNUM_GET_READY ; ;AC000;
1786
1787 PRINT MSGNUM_CLOSE_DOOR ;"Make sure a diskette is inserted into ;AN004;
1788 ; the drive and the door is closed"
1789 JMP WAIT_FOR_USER
1790
1791WARN_USER_2:
1792 ;"Attempt to write to write-protected diskette"
1793 PRINT MSGNUM_WRITE_PROTECT ; ;AC000;
1794
1795WAIT_FOR_USER:
1796 CALL PRESS_ANY_KEY ;"Press any key to continue . . ." ;AC009;
1797
1798EEH_SOFT_ERROR:
1799 MOV IO_ERROR, SOFT_ERROR ;INDICATE THE CALLER TO TRY AGAIN
1800 JMP SHORT EEH_EXIT
1801
1802EEH_HARD_ERROR:
1803 MOV IO_ERROR, HARD_ERROR
1804
1805EEH_EXIT:
1806 POP DI
1807 POP SI
1808 POP DX
1809 POP CX
1810 POP BX
1811 POP AX
1812 POPF
1813 RET
1814
1815;EEH_JUST_EXIT:
1816; JMP EXIT_PROGRAM ;UNCONDITIONAL EXIT
1817
1818EXTENDED_ERROR_HANDLER ENDP
1819.XLIST
1820; HEADER <CALL_PRINTF - COMMON DRIVER TO PRINTF, DISPLAY MESSAGE>
1821;CALL_PRINTF PROC NEAR
1822; PUBLIC CALL_PRINTF
1823;;INPUT - DX HAS OFFSET INTO DS OF MESSAGE PARM LIST
1824; PUSH DX
1825; PUSH CS
1826; CALL PRINTF
1827;
1828; RET
1829;CALL_PRINTF ENDP
1830.LIST
1831; = = = = = = = = = = = =
1832 HEADER <ERROR_MESSAGE - DISPLAY THE ERROR MESSAGE> ; ;AN000;
1833ERROR_MESSAGE PROC NEAR ;DISPLAY ERROR MESSAGE
1834 PUBLIC ERROR_MESSAGE
1835;
1836; FUNCTION: THIS SUBROUTINE DISPLAYS WHAT OPERATION FAILED (READ OR WRITE)
1837; AND WHERE IT FAILED (TRACK NO. AND SIDE).
1838;
1839; INPUT: OPERATION = IOCTL DISKETTE READ(=61H) OR COMPARE_FUNC(59H)
1840; = = = = = = = = = = = =
1841
1842 CMP OPERATION,READ_FUNC ;ERROR DURING READ ?
1843; $IF E
1844 JNE $$IF90
1845.XLIST
1846; MOV BX,OFFSET READ_ERROR ;TELL USER ERROR DURING READ OP
1847; MOV MSG_HARD_ERROR_PTR+2,BX
1848.LIST
1849 MOV DL,SOURCE_DRIVE ;WHICH DRIVE IS BAD
1850 dec dl ;change logical letter to phisical
1851 ADD DL,"A" ;CORRESPONDANT ALPHABET
1852 MOV DRIVE_LETTER,DL
1853 MOV SUBLIST_17B.SUB_VALUE,OFFSET DRIVE_LETTER ;
1854
1855 MOV BL,TRACK_TO_READ ;SAVE BAD TRACK NUMBER FOR READ
1856 ;CR,LF,"Unrecoverable read error on drive %2",CR,LF
1857 ;"side %3, track %4",CR,LF
1858 ;%2 IS "DRIVE_LETTER", AND
1859 ;"MSG_SIDES" AND "MSG_TRACKS" ARE %3 AND %4.
1860 MOV DI,OFFSET MSGNUM_HARD_ERROR_READ ; ;AN000;
1861; $ELSE
1862 JMP SHORT $$EN90
1863$$IF90:
1864.XLIST
1865; MOV BX,OFFSET COMPARE_ERROR ;TELL USER ERROR DURING COMPARE OP
1866; MOV MSG_HARD_ERROR_PTR+2,BX
1867.LIST
1868 MOV BL,TRACK_TO_READ ;SAVE BAD TRACK NUMBER FOR WRITE
1869 ;CR,LF,"Compare error on",CR,LF
1870 ;"side %3, track %4",CR,LF
1871 ;"MSG_SIDES" AND "MSG_TRACKS" ARE %3 AND %4.
1872 MOV DI,OFFSET MSGNUM_HARD_ERROR_COMP ; ;AN000;
1873; $ENDIF
1874$$EN90:
1875
1876 MOV AL,SIDE
1877 MOV BYTE PTR MSG_SIDES,AL
1878 MOV BYTE PTR MSG_TRACKS,BL
1879 CALL SENDMSG ;PRINT MSG SELECTED ABOVE ;AN000;
1880
1881 RET
1882ERROR_MESSAGE ENDP
1883; = = = = = = = = = = = =
1884 HEADER <COMBAT_ERROR - DISPLAY INCOMPATIBLE MSG> ; ;AN000;
1885COMPAT_ERROR PROC NEAR ;DISPLAY COMPAT MSG
1886 PUBLIC COMPAT_ERROR
1887; = = = = = = = = = = = =
1888
1889 MOV COMP_STATUS,FATAL ;INCOMPATIBLE, ABORT
1890 ;"Drive types or diskette types"
1891 ;"not compatible"
1892 PRINT MSGNUM_NOT_COMPATIBLE
1893
1894 RET
1895COMPAT_ERROR ENDP
1896; = = = = = = = = = = = =
1897 HEADER <PRESS_ANY_KEY - PUTS A BLANK LINE BEFORE PROMPT> ; ;AN009;
1898PRESS_ANY_KEY PROC NEAR ;
1899;THE CANNED MESSAGE "PRESS ANY KEY..." DOES NOT START WITH CR,LF.
1900;THIS PUTS OUT THE CR LF TO CAUSE SEPARATION OF THIS PROMP FROM
1901;PRECEEDING MESSAGES.
1902; = = = = = = = = = = = =
1903 PRINT MSGNUM_NEWLINE ;SKIP A SPACE ;AN009;
1904
1905 PRINT MSGNUM_STRIKE ;"Press any key when ready..." ;AN009;
1906
1907 RET ;RETURN TO CALLER ;AN009;
1908PRESS_ANY_KEY ENDP ; ;AN009;
1909; = = = = = = = = = = = =
1910 HEADER <SENDMSG - PASS IN REGS DATA FROM MSG DESCRIPTOR TO DISP MSG> ; ;AN000;
1911SENDMSG PROC NEAR ; ;AN000;
1912 PUBLIC SENDMSG ; ;AN000;
1913; INPUT - DI=POINTER TO MSG_DESC STRUC FOR THIS MESSAGE
1914; OUTPUT - IF CARRY SET, EXTENDED ERROR MSG ATTEMPTED DISPLAYED
1915; IF CARRY CLEAR, ALL OK
1916; IN EITHER CASE, DI AND AX ALTERED, OTHERS OK
1917
1918; = = = = = = = = = = = =
1919
1920 PUSH BX ; SAVE CALLER'S REGS ;AN000;
1921 PUSH CX ; ;AN000;
1922 PUSH DX ; ;AN000;
1923 PUSH SI ; ;AN000;
1924
1925; PASS PARMS TO MESSAGE HANDLER IN
1926; THE APPROPRIATE REGISTERS IT NEEDS.
1927 MOV AX,[DI].MSG_NUM ;MESSAGE NUMBER ;AN000;
1928 MOV BX,[DI].MSG_HANDLE ;HANDLE TO DISPLAY TO ;AN000;
1929 MOV SI,[DI].MSG_SUBLIST ;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE ;AN000;
1930 MOV CX,[DI].MSG_COUNT ;NUMBER OF %PARMS, 0 IF NONE ;AN000;
1931 MOV DX,[DI].MSG_CLASS ;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW ;AN000;
1932 CALL SYSDISPMSG ;DISPLAY THE MESSAGE ;AN000;
1933
1934; $IF C ;IF THERE IS A PROBLEM ;AN000;
1935 JNC $$IF93
1936 ;AX=EXTENDED ERROR NUMBER ;AN000;
1937 LEA DI,MSGNUM_EXTERR ;GET REST OF ERROR DESCRIPTOR ;AN000;
1938 MOV BX,[DI].MSG_HANDLE ;HANDLE TO DISPLAY TO ;AN000;
1939 MOV SI,[DI].MSG_SUBLIST ;OFFSET IN ES: OF SUBLIST, OR 0 IF NONE ;AN000;
1940 MOV CX,[DI].MSG_COUNT ;NUMBER OF %PARMS, 0 IF NONE ;AN000;
1941 MOV DX,[DI].MSG_CLASS ;CLASS IN HIGH BYTE, INPUT FUNCTION IN LOW ;AN000;
1942 CALL SYSDISPMSG ;TRY TO SAY WHAT HAPPENED ;AN000;
1943
1944 STC ;REPORT PROBLEM ;AN000;
1945; $ENDIF ;PROBLEM WITH DISPLAY? ;AN000;
1946$$IF93:
1947
1948 POP SI ;RESTORE CALLER'S REGISTERS ;AN000;
1949 POP DX ; ;AN000;
1950 POP CX ; ;AN000;
1951 POP BX ; ;AN000;
1952
1953 RET ;RETURN TO CALLER ;AN000;
1954SENDMSG ENDP ; ;AN000;
1955; = = = = = = = = = = = =
1956 HEADER <YESNO - DETERMINE IF A RESPONSE IS YES OR NO> ; ;AN000;
1957YESNO PROC NEAR ; ;AN000;
1958 PUBLIC YESNO ;MAKE ENTRY IN LINK MAP ;AN000;
1959;INPUT: DL=CHAR WITH Y OR N EQUIVALENT CHAR TO BE TESTED
1960;OUTPUT: AX=0=NO; AX=1=YES ; AX=2=INVALID RESPONSE, NEITHER Y NOR N
1961; IF CARRY SET, PROBLEM WITH THE FUNCTION, CALLER SHOULD ASSUME "NO"
1962; = = = = = = = = = = = =
1963 ;AL=SUBFUNCTION, AS:
1964 ; 20H=CAPITALIZE SINGLE CHAR
1965 ; 21H=CAPITALIZE STRING
1966 ; 22H=CAPITALIZE ASCIIZ STRING
1967 ; 23H=YES/NO CHECK
1968 ; 80H BIT 0=USE NORMAL UPPER CASE TABLE
1969 ; 80H BIT 1=USE FILE UPPER CASE TABLE
1970 ;DL=CHAR TO CAP (FUNCTION 23H) ;AN000;
1971 MOV AX,(GET_EXT_CNTRY_INFO SHL 8) + YESNO_CHECK ;(6523H) GET EXTENDED ;AN000;
1972 ; COUNTRY INFORMATION, (Y/N)
1973 INT 21H ;SEE IF Y OR N ;AN000;
1974
1975 RET ;RETURN TO CALLER ;AN000;
1976YESNO ENDP ; ;AN000;
1977; = = = = = = = = = = = =
1978 HEADER <VOLSER - VERIFY FIRST SECTOR, IGNORE VOL SER #> ; ;AN000;
1979VOLSER PROC NEAR ;VERIFY FIRST SECTOR, IGNORING VOL SER # ;AN000;
1980 PUBLIC VOLSER ; ;AN000;
1981;IF THE FIRST DISKETTE SUPPORTED A VOL SERIAL NUMBER, THEN
1982;COPY IT TO THE SECOND DISKETTE BUFFER AREA (NOT THE DISKETTE).
1983;INPUT: FIRST DRIVE NUMBER
1984; DS:=SEGID OF BUFFER OF FIRST DISKETTE, FIRST SECTOR, SIDE 0
1985; ES:=SEGID OF BUFFER OF SECOND DISKETTE, FIRST SECTOR, SIDE 0
1986; SI AND DI = 0, INDEX OF WHERE IN BUFFERS TO START LOOKING
1987; CX="BYTES_IN_TRACK"; NUMBER OF BYTES TO BE EVENTUALLY COMPARED
1988;OUTPUT: BUFFER OF 2ND DISKETTE ALTERED TO MATCH THE VOL SERIAL NUMBER OF 1ST.
1989; = = = = = = = = = = = = = = = = = =
1990
1991 ASSUME DS:NOTHING ;BUFFER OF FIRST DISKETTE ;AN000;
1992 ASSUME ES:NOTHING ;BUFFER OF SECOND DISKETTE ;AN000;
1993
1994 PUSH CX ;SAVE CALLER'S REGS ;AN000;
1995 PUSH SI ; ;AN000;
1996 PUSH DI ; ;AN000;
1997;(deleted ;AN011;) PUSH DS ;SAVE BUFFER OF FIRST DISKETTE ;AN000;
1998
1999;(deleted ;AN011;) PUSH CS ;RESTORE ADDRESSABILITY TO COMMON SEG ;AN000;
2000;(deleted ;AN011;) POP DS ; TO ACCESS GET MEDIA ID BUFFER AREA ;AN000;
2001;(deleted ;AN011;) ASSUME DS:CSEG ;AN000;
2002
2003;(deleted ;AN011;); ISSUE GET MEDIA ID FROM SOURCE
2004;(deleted ;AN011;) MOV BH,0 ;BH=0, RES ;AN000;
2005;(deleted ;AN011;) MOV BL,SOURCE_DRIVE ;BL=DRIVE NUM (A:=1, B:=2, ETC.) ;AN000;
2006;(deleted ;AN011;) MOV DX,OFFSET MEDIA_ID_BUFFER ;DS:DX=BUFFER
2007;(deleted ;AN011;) DOSCALL GSET_MEDIA_ID,GET_ID ;(6900H) GET MEDIA ID ;AC008;
2008;(deleted ;AN011;) ;CARRY SET ON ERROR (OLD STYLE BOOT RECORD)
2009;(deleted ;AN011;) POP DS ;RESTORE THIS BACK TO BUFFER OF FIRST DISKETTE;AN000;
2010;(deleted ;AN011;) ASSUME DS:NOTHING ; LIKE IT WAS AT ENTRY TO THIS PROC ;AN000;
2011
2012;(deleted ;AN011;) $IF NC ;IF THERE IS NO PROBLEM ;AN000;
2013;(deleted ;AN011;) ; THEN THIS DISKETTE HAS A VOL SER #
2014
2015 PUSH BX ;AN011;
2016 LEA BX,DS:[DI].EXT_BOOT_BPB ;AN011;POINT TO BPB PORTION OF BOOT RECORD
2017 MOV AL,DS:[BX].EBPB_MEDIADESCRIPTOR ;AN011;GET TYPE OF MEDIA
2018 AND AL,0F0H ;AN011;SAVE LEFT NIBBLE ONLY
2019 CMP AL,0F0H ;AN011;IF DISKETTE HAS PROPER DESCRIPTOR
2020; $IF E ;AN011;
2021 JNE $$IF95
2022 MOV AL,DS:[DI].EXT_BOOT_SIG ;AN011;GET "SIGNATURE" OF BOOT RECORD
2023 CMP AL,28H ;AN011;IS THIS BOOT STYLE OF OS/2 1.0 OR 1.1?
2024; $IF E,OR ;AN011;YES, IS A BOOT WITH A SERIAL IN IT
2025 JE $$LL96
2026 CMP AL,29H ;AN011;IS THIS A BOOT STYLE OF OS/S 1.2?
2027; $IF E ;AN011;YES, IS A BOOT WITH A SERIAL IN IT
2028 JNE $$IF96
2029$$LL96:
2030
2031;THE PURPOSE HERE IS TO CAUSE DISKCOMP TO IGNORE ANY DIFFERENCES IN THE
2032;VOL SERIAL NUMBER FIELD. THIS IS DONE BY TAKING ONE VOL SERIAL NUMBER
2033;FROM ONE BUFFER, ALREADY LOADED WITH THE FIRST TRACK OF ONE DISKETTE,
2034;AND MOVING THAT SERIAL NUMBER TO THE CORRESPONDING POSITION IN THE OTHER
2035;BUFFER, ALREADY LOADED WITH THE SIMILAR TRACK FROM THE OTHER DISKETTE.
2036;WHEN THIS RETURNS TO THE MAIN ROUTINE, THE ENTIRE TRACK (INCUDING THIS
2037;VOL SERIAL NUMBER FIELD) WILL BE COMPARED. IF THERE ARE ANY DIFFERENCES,
2038;THEY WILL BE OTHER THAN IN THE VOL SERIAL NUMBERS.
2039
2040 MOV SI,OFFSET VOL_SERIAL ;GET WHERE VOL SERIAL NUMBER IS
2041 MOV DI,OFFSET VOL_SERIAL ;GET WHERE VOL SERIAL NUMBER IS
2042 MOV CX,TYPE VOL_SERIAL ;GET NUMBER BYTES IN VOL SER FIELD
2043 REP MOVSB ;FORCE THE SERIAL NUMBERS TO BE ALIKE
2044
2045; $ENDIF ; ;AN000;
2046$$IF96:
2047; $ENDIF ;AN011;
2048$$IF95:
2049 POP BX ;AN011;
2050 POP DI
2051 POP SI
2052 POP CX ;RESTORE COUNT
2053 RET ;RETURN TO CALLER ;AN000;
2054VOLSER ENDP ;AN000;
2055; = = = = = = = = = = = = = = = = = = =
2056DISKCOMP_END LABEL BYTE
2057 PATHLABL DISKCOMP ;AN013;
2058CSEG ENDS
2059 END DISKCOMP
2060 \ No newline at end of file