The Microsoft MACRO Assembler , Version 1.25 Page 1-1 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1 2 Page 55,132 3 Title FREECOPY Version 1.0 (C)Copyright 1984 4 ;*********************** F R E E C O P Y ****************************** 5 ;* * 6 ;* Program: FREECOPY * 7 ;* * 8 ;* Author: Donald L. Buresh, C.D.P. * 9 ;* Squire Buresh Associates, Inc. * 10 ;* Post Office Box 112 * 11 ;* Millbury, MA 01527 * 12 ;* (617) 865-3435 * 13 ;* * 14 ;* !!!!!!!!!!!!!!!!!!!!!! N O T I C E !!!!!!!!!!!!!!!!!!!!!! * 15 ;* * 16 ;* A limited license is granted to all users of this program to * 17 ;* make copies of this source code and to distribute them to * 18 ;* other users under the following conditions: * 19 ;* * 20 ;* 1. The notice contained in the variable MES00_Copy_Notice * 21 ;* is not to be altered, bypassed or removed. * 22 ;* * 23 ;* 2. The program is not to be distributed to others in * 24 ;* modified form. * 25 ;* * 26 ;* 3. If you think that this program has helped you, we request * 27 ;* a $25.00 contribution. * 28 ;* * 29 ;* 4. No other fee is to be charged or any consideration received * 30 ;* for copying or distributing the program without the * 31 ;* expressed written permission of Squire Buresh Assoc, Inc. * 32 ;* * 33 ;* * 34 ;* (C) Copyright 1984 Squire Buresh Associates, Inc. * 35 ;* * 36 ;************************************************************************  The Microsoft MACRO Assembler , Version 1.25 Page 1-2 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 37 Page 38 ;************************************************************************ 39 ;* * 40 ;* EQUATES * 41 ;* * 42 ;* The constants defined below are used to to specify: * 43 ;* * 44 ;* o Disk commands, * 45 ;* * 46 ;* o Keyboard commands, * 47 ;* * 48 ;* o Video commands * 49 ;* * 50 ;* o Miscellaneous parameters, * 51 ;* * 52 ;* o Various ASCII characters. * 53 ;* * 54 ;************************************************************************ 55 ; 56 = 0078 Disk_Parameter_Addr Equ 001EH*4 ; Address of Disk Parameter Table 57 ; 58 = 0000 Reset_Command Equ 0000D ; Diskette reset command 59 = 0001 Status_Command Equ 0001D ; Diskette status command 60 = 0002 Read_Command Equ 0002D ; Diskette read command 61 = 0003 Write_Command Equ 0003D ; Diskette write command 62 = 0004 Verify_Command Equ 0004D ; Diskette verify command 63 = 0005 Format_Command Equ 0005D ; Diskette format command 64 ; 65 = 0080 Time_Out_Error Equ 0080H ; Diskette error codes 66 = 0040 Seek_Error Equ 0040H ; . 67 = 0020 Controller_Error Equ 0020H ; . 68 = 0010 CRC_Error Equ 0010H ; . 69 = 0009 DMA_Boundary_Error Equ 0009H ; . 70 = 0008 DMA_Error Equ 0008H ; . 71 = 0004 Sector_Error Equ 0004H ; . 72 = 0003 Write_Protect_Error Equ 0003H ; . 73 = 0002 Address_Mark_Error Equ 0002H ; . 74 = 0001 Command_Error Equ 0001H ; ..End 75 ; 76 = A000 Video_Address Equ 0A000H ; Starting segment addr of Video RAM 77 ; 78 = 0000 Set_Mode_Command Equ 0000D ; Set the video mode 79 = 0001 Set_CType_Command Equ 0001D ; Set the cursor type 80 = 0002 Set_CPos_Command Equ 0002D ; Set the cursor position 81 = 0003 Read_Cursor_Command Equ 0003D ; Get cursor position and attributes 82 = 0004 Read_LPen_Command Equ 0004D ; Get the light pen position 83 = 0005 Set_ADPage_Command Equ 0005D ; Set the active display page 84 = 0006 Scroll_Up_Command Equ 0006D ; Scrool up or blank a portion of 85 ; . the video display 86 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-3 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 87 Page 88 ;************************************************************************ 89 ;* * 90 ;* EQUATES Page 2 * 91 ;* * 92 ;************************************************************************ 93 ; 94 = 0007 Scroll_Down_Command Equ 0007D ; Scroll down or blank a portion 95 ; . of the video display 96 = 0008 Read_AChar_Command Equ 0008D ; Read the attribute and character 97 = 0009 Write_AChar_command Equ 0009D ; Write the attribute and character 98 = 000A Write_Char_Command Equ 0010D ; Write the character only 99 = 000B Set_Color_Command Equ 0011D ; Set the color pallette 100 = 000C Write_Dot_Command Equ 0012D ; Write a pixel to a graphics screen 101 = 000D Read_Dot_Command Equ 0013D ; Read a pixel from a graphics screen 102 = 000E Write_TTY_Command Equ 0014D ; Write a character with automatic 103 ; . processing for LF, CR, Bell & BS 104 = 000F Video_State_Command Equ 0015D ; Get the current video state 105 ; 106 = 0007 Read_Keyboard_Command Equ 0007D ; Reads character from the keyboard 107 ; 108 = 0019 Default_Drive_Command Equ 0025D ; Get PC DOS default drive number 109 ; 110 = 0010 Video_Interrupt Equ 0010H ; Interrupt 10H for video calls 111 = 0011 Equipment_Interrupt Equ 0011H ; Interrupt 11H for equipment 112 = 0013 Disk_Interrupt Equ 0013H ; Interrupt 13H for disk calls 113 = 0021 PC_DOS_Interrupt Equ 0021H ; Interrupt 21H for PC DOS calls 114 ; 115 = C000 Parallel_Ports_Mask Equ 0C000H ; Equipment masks 116 = 0100 Game_Adapters_Mask Equ 00100H ; . 117 = 0E00 RS232_Ports_Mask Equ 00E00H ; . 118 = 00C0 Disk_Drives_Mask Equ 000C0H ; . 119 = 0030 Init_Video_Mask Equ 00030H ; . 120 = 000C Planar_RAM_Mask Equ 0000CH ; . 121 = 0001 IPL_Diskette_Mask Equ 00001H ; ..End 122 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-4 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 123 Page 124 ;************************************************************************ 125 ;* * 126 ;* EQUATES Page 3 * 127 ;* * 128 ;************************************************************************ 129 ; 130 = 0465 Command_Com_Size Equ 1125D ; Size of various tables and programs 131 = 00B4 CHRN_Table_Size Equ 0180D ; in 16 byte paragraphs 132 ; . 133 ; . 134 = 0014 ESBX_Table_Size Equ 0020D ; . 135 ; . 136 ; . 137 = 0020 FAT_Sector_Size Equ 0032D ; ..End 138 ; 139 = 0FFF DMA_Boundary_Mask Equ 0FFFH ; Mask to isolate the high nibble of 140 ; . the ES segment address 141 ; 142 = 00FF Invalid_Drive Equ 0255D ; Invalid drive parameter 143 = 0003 Maximum_Drives Equ 0003D ; Maximum number of floppy drives 144 = 0000 Minimum_Drives Equ 0000D ; Minimum number of floppy drives 145 ; 146 = 0200 Sector_Size Equ 0512D ; Number of bytes per sector 147 = 0010 Paragraph_Size Equ 0016D ; Number of bytes per paragraph 148 = 0005 Number_of_Retries Equ 0005D ; Number of attempts to copy 149 ; . a track before admitting failure 150 = 0027 Final_Track Equ 0039D ; The last track on a PC DOS diskette 151 ; 152 = 00FE One_Side_Eight_Sectors Equ 00FEH ; First entry in the File Allocation 153 = 00FF Two_Sides_Eight_Sectors Equ 00FFH ; Table (FAT) 154 = 00FC One_Side_Nine_Sectors Equ 00FCH ; . 155 = 00FD Two_Sides_Nine_Sectors Equ 00FDH ; . 156 = 00F8 Fixed_Disk Equ 00F8H ; ..End 157 ; 158 = 0050 Keyboard_Buffer_Size Equ 0080D ; Maximum number of characters in 159 ; . the keyboard buffer 160 ; 161 = 0120 Minimum_Memory_Size Equ 0288D ; Minimum memory size in 16 byte 162 ; . paragraphs to hold a nine 163 ; . sectored track 164 ; 165 = 0F0F Blank_Cursor Equ 0F0FH ; Blank cursor value 166 = 0D0D Underline_Cursor Equ 0D0DH ; Underline cursor value 167 ; 168 = 0001 True Equ 0001D ; Correct processing occured 169 = 0000 False Equ 0000D ; Incorrect processing occured 170 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-5 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 171 Page 172 ;************************************************************************ 173 ;* * 174 ;* EQUATES Page 4 * 175 ;* * 176 ;************************************************************************ 177 ; 178 = 0000 NUL Equ 0000D ; Null character 179 = 0001 SOH Equ 0001D ; SOH character 180 = 0002 STX Equ 0002D ; STX character 181 = 0003 ETX Equ 0003D ; Control Break character 182 = 0007 Bell Equ 0007D ; Bell character 183 = 0008 BS Equ 0008D ; Backspace character 184 = 000A LF Equ 0010D ; Line feed character 185 = 000D CR Equ 0013D ; Carriage return character 186 = 0020 Space Equ 0032D ; Space or blank character 187 = 002F Slash Equ 0047D ; Slash character 188 = 0030 Zero_Digit Equ 0048D ; Digit Zero 189 = 0031 One_Digit Equ 0049D ; Digit One 190 = 0041 Capital_Letter_A Equ 0065D ; Capital letter A 191 = 004E Capital_Letter_N Equ 0078D ; Capital letter N 192 = 0059 Capital_Letter_Y Equ 0089D ; Capital letter Y 193 = 006E Small_Letter_n Equ 0110D ; Small letter n 194 = 0079 Small_Letter_y Equ 0121D ; Small letter y 195 = 00FF EOT Equ 0255D ; End of text character 196 ; 197 =-0001 Minus_One Equ -1D ; Numbers used in FREECOPY 198 = 0000 Zero Equ 0000D ; . 199 = 0001 One Equ 0001D ; . 200 = 0002 Two Equ 0002D ; . 201 = 0003 Three Equ 0003D ; . 202 = 0004 Four Equ 0004D ; . 203 = 0006 Six Equ 0006D ; . 204 = 0008 Eight Equ 0008D ; . 205 = 0009 Nine Equ 0009D ; . 206 = 000A Ten Equ 0010D ; . 207 = 000B Eleven Equ 0011D ; . 208 = 000C Twelve Equ 0012D ; . 209 = 000E Fourteen Equ 0014D ;. 210 = 000F Fifteen Equ 0015D ; . 211 = 0018 Twenty_Four Equ 0024D ; . 212 = 0019 Twenty_Five Equ 0025D ; . 213 = 0022 Thirty_Four Equ 0034D ; . 214 = 0024 Thirty_Six Equ 0036D ; . 215 = 0027 Thirty_Nine Equ 0039D ; . 216 = 004F Seventy_Nine Equ 0079D ; ..End 217 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-6 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 218 Page 219 ;************************************************************************ 220 ;* * 221 ;* CSEG Segment * 222 ;* * 223 ;* This segment contains all of the code of the program. It is * 224 ;* named CSEG because this name conforms with ASM-86. * 225 ;* * 226 ;************************************************************************ 227 ; 228 0000 CSEG Segment Para Public 'CSEG' 229 Assume CS:CSEG,DS:CSEG,ES:CSEG,SS:Nothing 230 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-7 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 231 Page 232 ;************************************************************************ 233 ;* * 234 ;* PROGRAM SEGMENT PREFIX * 235 ;* * 236 ;* The first 256 bytes of every program executed under PC DOS * 237 ;* contains a Program Segment Prefix control block. The data * 238 ;* stored in this block of memory is used by FREECOPY to process * 239 ;* the parameters when invoking the program. * 240 ;* * 241 ;************************************************************************ 242 ; 243 005C Org 05CH 244 005C Source_Drive Label Byte ; Source diskette drive number 245 005D Org 05DH 246 005D Source_Filename Label Byte ; Source diskette filename 247 0068 Org 068H 248 0068 Source_Filler_Area Label Byte 249 006C Org 06CH 250 006C Target_Drive Label Byte ; Target diskette drive number 251 006D Org 06DH 252 006D Target_Filename Label Byte ; Target diskette filename 253 0078 Org 078H 254 0078 Target_Filler_Area Label Byte 255 0080 Org 080H 256 0080 Parameter_Count Label Byte ; Number of parameters 257 0081 Org 081H 258 0081 Parameter_String Label Byte ; String entered by the user 259 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-8 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 260 Page 261 ;************************************************************************ 262 ;* * 263 ;* A1000_MAIN_MODULE * 264 ;* * 265 ;* This is the top level of FREECOPY and it controls the flow of * 266 ;* the program. The first sequence of commands in the routine * 267 ;* preserve the state of the machine. Next, there is a set of * 268 ;* three (3) calls to sub-modules that control the initial * 269 ;* processing, detail processing and final processing. Finally, * 270 ;* FREECOPY restores the state of the machine an returns to * 271 ;* PC DOS via INT 20H. * 272 ;* * 273 ;************************************************************************ 274 ; 275 0100 Org 0100H 276 ; 277 Public A1000_Main_Module 278 ; 279 0100 A1000_Main_Module Proc Far 280 ; 281 0100 A1001: 282 0100 FA Cli ; Set up the top of the stack 283 0101 BC 140C R Mov SP,Offset MEM04_Top_of_the_Stack 284 0104 FB Sti ; ..End 285 ; 286 0105 55 Push BP ; Save the state of the machine 287 0106 1E Push DS ; . 288 0107 06 Push ES ; . 289 0108 16 Push SS ; . 290 0109 50 Push AX ; . 291 010A 53 Push BX ; . 292 010B 51 Push CX ; . 293 010C 52 Push DX ; . 294 010D 56 Push SI ; . 295 010E 57 Push DI ; . 296 010F 9C Pushf ; ..End 297 ; 298 0110 FA Cli ; Save the current stack pointer 299 0111 89 26 137B R Mov Word Ptr SYS15_Stack_Pointer,SP 300 0115 FB Sti ; ..End 301 ; 302 0116 E8 013A R Call B1000_Initial_Process ; Main flow of control 303 0119 80 3E 0CD6 R 00 Cmp Byte Ptr FLG01_Good_Command,False 304 011E 74 0A Je A1002 ; . 305 0120 80 3E 0CD8 R 00 Cmp Byte Ptr FLG03_Default_Drive,False 306 0125 74 03 Je A1002 ; . 307 0127 E8 0184 R Call B1100_Detail_Process ; . 308 012A A1002: ; . 309 012A E8 0276 R Call B1200_Final_Process ; ..End  The Microsoft MACRO Assembler , Version 1.25 Page 1-9 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 310 012D A1090: 311 012D 9D Popf ; Restore the state of the machine 312 012E 5F Pop DI ; . 313 012F 5E Pop SI ; . 314 0130 5A Pop DX ; . 315 0131 59 Pop CX ; . 316 0132 5B Pop BX ; . 317 0133 58 Pop AX ; . 318 0134 17 Pop SS ; . 319 0135 07 Pop ES ; . 320 0136 1F Pop DS ; . 321 0137 5D Pop BP ; ..End 322 0138 A1099: 323 0138 CD 20 Int 20H ; Return to PC DOS 324 ; 325 013A A1000_Main_Module Endp 326 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-10 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 327 Page 328 ;************************************************************************ 329 ;* * 330 ;* B1000_INITIAL_PROCESS * 331 ;* * 332 ;* This module performs the following functions after control * 333 ;* passess to FREECOPY: * 334 ;* * 335 ;* 1. Sets up the Disk Parameter Table. * 336 ;* * 337 ;* 2. Initializes various parameters. * 338 ;* * 339 ;* 3. Gets and sets the video mode. * 340 ;* * 341 ;* 4. Displays the intiial message. * 342 ;* * 343 ;* 5. Parses the command line entered by a user. * 344 ;* * 345 ;* 6. Determines the amount of equipment on the machine. * 346 ;* * 347 ;* 7. Validates the number of disk drives on the system. * 348 ;* * 349 ;* 8. Displays the appropriate disk copying message. * 350 ;* * 351 ;* 9. Gets the amount of available memory. * 352 ;* * 353 ;* 10. Calculates the number and position of the entries in the * 354 ;* ES:BX buffer address table. * 355 ;* * 356 ;************************************************************************ 357 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-11 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 358 Page 359 ; 360 Public B1000_Initial_Process 361 ; 362 013A B1000_Initial_Process Proc Near 363 ; 364 013A B1001: 365 013A E8 0AF2 R Call S1000_Setup_Disk_Param_Table 366 ; 367 013D C6 06 0CD6 R 01 Mov Byte Ptr FLG01_Good_Command,True 368 0142 C6 06 0CD7 R 01 Mov Byte Ptr FLG02_Double_Side,True 369 0147 C6 06 0CD8 R 01 Mov Byte Ptr FLG03_Default_Drive,True 370 014C C6 06 0CD9 R 01 Mov Byte Ptr FLG04_Single_Drive,True 371 0151 C6 06 0CDC R 01 Mov Byte Ptr FLG07_First_Time,True 372 0156 B1002: 373 0156 E8 0292 R Call C1000_Get_And_Set_Video ; Get and set current video state 374 0159 E8 02AF R Call C1100_Display_Intro ; Display the intial screen 375 015C E8 02B6 R Call C1200_Parse_Commands ; Parse the command line entered 376 ; . by the user 377 015F 80 3E 0CD6 R 00 Cmp Byte Ptr FLG01_Good_Command,False 378 0164 74 1D Je B1099 ; If false, go to end of the module 379 0166 E8 0382 R Call C1300_Get_Equipment ; Find out the equipment on the PC 380 0169 E8 03D5 R Call C1400_Validate_Drives ; Validate the drive numbers 381 016C 80 3E 0CD8 R 00 Cmp Byte Ptr FLG03_Default_Drive,False 382 0171 74 10 Je B1099 ; If false, go to end of the module 383 0173 E8 0442 R Call C1500_Diskette_Messages ; Display the appropriate messages 384 0176 E8 0488 R Call C1600_Get_Free_Memory ; Get the available memory in 16 385 ; . byte paragraphs 386 0179 80 3E 0CD6 R 00 Cmp Byte Ptr FLG01_Good_Command,False 387 017E 74 03 Je B1099 ; If false, go to end of the module 388 0180 E8 052A R Call C1700_Create_ESBX_Table ; Create the ES:BX table for the disk 389 ; reads and writes 390 0183 B1099: 391 0183 C3 Ret 392 ; 393 0184 B1000_Initial_Process Endp 394 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-12 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 395 Page 396 ;************************************************************************ 397 ;* * 398 ;* B1100_DETAIL_PROCESS * 399 ;* * 400 ;* This module performs the following functions when copying one * 401 ;* or more diskettes: * 402 ;* * 403 ;* 1. Initializes various parameters. * 404 ;* * 405 ;* 2. Validates the contents of the source diskette. * 406 ;* * 407 ;* 3. Creates all of the entries of the CHRN table used in * 408 ;* formatting the target diskette. * 409 ;* * 410 ;* 4. Reads the tracks of the source diskette. * 411 ;* * 412 ;* 5. If the diskette is being copied on only one drive, the * 413 ;* routines asks the user to enter the target diskette. * 414 ;* * 415 ;* 6. Writes the tracks on the target diskette. * 416 ;* * 417 ;* 7. If FREECOPY is finished copying the source diskette, the * 418 ;* program asks whether wants to copy another one. If not, * 419 ;* the module returns to A1000_Main_Module. If so, control * 420 ;* transfers to 1. * 421 ;* * 422 ;* 8. If FREECOPY is not completed copying the source diskette, * 423 ;* control transfers to 4. * 424 ;* * 425 ;************************************************************************ 426 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-13 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 427 Page 428 ; 429 Public B1100_Detail_Process 430 ; 431 0184 B1100_Detail_Process Proc Near 432 ; 433 0184 B1101: 434 0184 C6 06 135D R 00 Mov Byte Ptr WRK20_Current_Source_Head,Zero 435 0189 C6 06 135E R 00 Mov Byte Ptr WRK21_Current_Source_Track,Zero 436 018E C6 06 135F R 00 Mov Byte Ptr WRK22_Current_Target_Head,Zero 437 0193 C6 06 1360 R 00 Mov Byte Ptr WRK23_Current_Target_Track,Zero 438 0198 C7 06 136A R 154E R Mov Word Ptr WRK33_CHRN_Table_Address,Offset MEM02_CHRN_Table 439 019E C6 06 0CE2 R 01 Mov Byte Ptr FLG13_First_Read_Write,True 440 01A3 C6 06 0CE3 R 00 Mov Byte Ptr FLG14_Copy_Complete,False 441 01A8 C6 06 0CE4 R 03 Mov Byte Ptr FLG15_IO_Error,Three 442 01AD B1102: 443 01AD E8 059D R Call C1800_Validate_Source_Disk 444 01B0 80 3E 0CDD R 01 Cmp Byte Ptr FLG08_Good_Read,True 445 01B5 74 10 Je B1103 ; If it is a valid source, continue 446 01B7 BE 0E7B R Mov SI,Offset MES07_Correct_And_Press_Key 447 01BA E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 448 01BD C6 06 0CDA R 00 Mov Byte Ptr FLG05_Store_Buffer,False 449 01C2 E8 0B54 R Call U1100_Get_Response ; Get the user's response 450 01C5 EB BD Jmp B1101 ; Go back and try again 451 01C7 B1103: 452 01C7 E8 06FD R Call C1900_Create_CHRN_Table 453 01CA B1104: 454 01CA E8 073D R Call C2000_Read_Source_Disk 455 01CD 80 3E 0CDD R 01 Cmp Byte Ptr FLG08_Good_Read,True 456 01D2 74 10 Je B1105 ; If read disk correctly, continue 457 01D4 BE 0E7B R Mov SI,Offset MES07_Correct_And_Press_Key 458 01D7 E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 459 01DA C6 06 0CDA R 00 Mov Byte Ptr FLG05_Store_Buffer,False 460 01DF E8 0B54 R Call U1100_Get_Response ; Get the user's response 461 01E2 EB A0 Jmp B1101 ; Go back and try again 462 01E4 B1105: 463 01E4 80 3E 0CD9 R 00 Cmp Byte Ptr FLG04_Single_Drive,False 464 01E9 74 1C Je B1106 ; If a single drive copy, continue 465 01EB BE 0EEC R Mov SI,Offset MES10_Insert_Target 466 01EE A0 12EC R Mov AL,Byte Ptr WRK02_Target_Drive 467 01F1 04 41 Add AL,Capital_Letter_A ; Put drive letter into AL 468 01F3 88 44 22 Mov [SI+Thirty_Four],AL ; Put the drive letter into the 469 ; . correct position in the message 470 01F6 E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 471 01F9 BE 0FC6 R Mov SI,Offset MES16_Press_Any_Key 472 01FC E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 473 01FF C6 06 0CDA R 00 Mov Byte Ptr FLG05_Store_Buffer,False 474 0204 E8 0B54 R Call U1100_Get_Response ; Get the user's response 475 0207 B1106: 476 0207 E8 0821 R Call C2100_Write_Format_Target_Disk  The Microsoft MACRO Assembler , Version 1.25 Page 1-14 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 477 020A 80 3E 0CDE R 00 Cmp Byte Ptr FLG09_Good_Write,False 478 020F 74 4E Je B1110 ; If bad write, go to bottom of loop 479 0211 80 3E 0CE0 R 00 Cmp Byte Ptr FLG11_Good_Format,False 480 0216 74 47 Je B1110 ; If bad format, go to bottom of loop 481 0218 B1107: 482 0218 80 3E 0CE3 R 01 Cmp Byte Ptr FLG14_Copy_Complete,True 483 021D 74 35 Je B1109 ; If copy done, go to bottom of loop 484 021F 80 3E 0CD9 R 00 Cmp Byte Ptr FLG04_Single_Drive,False 485 0224 74 1C Je B1108 ; If double drive copy, continue 486 0226 BE 0EC4 R Mov SI,Offset MES09_Insert_Source 487 0229 A0 12EB R Mov AL,Byte Ptr WRK01_Source_Drive 488 022C 04 41 Add AL,Capital_Letter_A ; Put the drive letter into AL 489 022E 88 44 22 Mov [SI+Thirty_Four],AL ; Put the drive letter into the 490 ; . correct position in the message 491 0231 E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 492 0234 BE 0FC6 R Mov SI,Offset MES16_Press_Any_Key 493 0237 E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 494 023A C6 06 0CDA R 00 Mov Byte Ptr FLG05_Store_Buffer,False 495 023F E8 0B54 R Call U1100_Get_Response ; Get the user's response 496 0242 B1108: 497 0242 E8 08F8 R Call C2200_Check_File_Alloc_Table 498 0245 80 3E 0CE1 R 00 Cmp Byte Ptr FLG12_Good_FAT,False 499 024A 74 13 Je B1110 ; If bad FAT, go to bottom of loop 500 024C C6 06 0CE2 R 00 Mov Byte Ptr FLG13_First_Read_Write,False 501 0251 E9 01CA R Jmp B1104 ; Go back and read some more 502 0254 B1109: 503 0254 C6 06 0CDC R 00 Mov Byte Ptr FLG07_First_Time,False 504 0259 BE 0DC2 R Mov SI,Offset MES02_Copy_Complete 505 025C E8 0B36 R Call U1000_Display_Message 506 025F B1110: 507 025F BE 0DA2 R Mov SI,Offset MES01_Copy_Another 508 0262 E8 0B36 R Call U1000_Display_Message 509 0265 E8 0BFA R Call U1200_Get_Yes_or_No 510 0268 80 3E 0CDB R 00 Cmp Byte Ptr FLG06_Yes_or_No,False 511 026D 74 06 Je B1199 ; Go to the end of the module 512 026F E8 0442 R Call C1500_Diskette_Messages ; Print out the messages on screen 513 0272 E9 0184 R Jmp B1101 ; Start copying a diskette again 514 0275 B1199: 515 0275 C3 Ret 516 ; 517 0276 B1100_Detail_Process Endp 518 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-15 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 519 Page 520 ;************************************************************************ 521 ;* * 522 ;* B1200_FINAL_PROCESS * 523 ;* * 524 ;* This module performs the following functions before returning * 525 ;* control to PC DOS: * 526 ;* * 527 ;* 1. Restores the value of the stack pointer. * 528 ;* * 529 ;* 2. Displays the final message of the program. * 530 ;* * 531 ;* 3. Restores the underline cursor. * 532 ;* * 533 ;* 4. Restores the settings in the Disk Parameter Table. * 534 ;* * 535 ;* 5. Returns control to A1000_Main_Module. * 536 ;* * 537 ;************************************************************************ 538 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-16 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 539 Page 540 ; 541 Public B1200_Final_Process 542 ; 543 0276 B1200_Final_Process Proc Near 544 ; 545 0276 B1201: 546 0276 FA Cli ; Establish the stack pointer 547 0277 8B 26 137B R Mov SP,Word Ptr SYS15_Stack_Pointer 548 027B FB Sti ; ..End 549 ; 550 027C BE 12D2 R Mov SI,Offset MES99_Freecopy_Finished 551 027F E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 552 ; 553 0282 B4 01 Mov AH,Set_CType_Command ; Restore the underline cursor 554 0284 B9 0D0D Mov CX,Underline_Cursor ; . 555 0287 CD 10 Int Video_Interrupt ; ..End 556 ; 557 0289 E8 0B19 R Call S1100_Restore_Disk_Param_Table 558 ; 559 028C B8 012D R Mov AX,Offset A1090 ; Setup to return to the main module 560 028F 0E Push CS ; . 561 0290 50 Push AX ; ..End 562 0291 B1299: 563 0291 C3 Ret 564 ; 565 0292 B1200_Final_Process Endp 566 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-17 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 567 Page 568 ;************************************************************************ 569 ;* * 570 ;* C1000_GET_AND_SET_VIDEO * 571 ;* * 572 ;* This module gets the current video state and saves this * 573 ;* information in the various SYStem variables. * 574 ;* * 575 ;************************************************************************ 576 ; 577 Public C1000_Get_And_Set_Video 578 ; 579 0292 C1000_Get_And_Set_Video Proc Near 580 ; 581 0292 C1001: 582 0292 50 Push AX ; Save the registers 583 0293 53 Push BX ; . 584 0294 51 Push CX ; ..End 585 0295 C1002: 586 0295 B4 0F Mov AH,Video_State_Command ; Get the current video state 587 0297 CD 10 Int Video_Interrupt ; ..End 588 0299 88 26 136C R Mov Byte Ptr SYS01_Number_Columns,AH 589 029D A2 136D R Mov Byte Ptr SYS02_Current_Mode,AL 590 02A0 88 3E 136E R Mov Byte Ptr SYS03_Active_Page,BH 591 02A4 C1003: 592 02A4 B4 01 Mov AH,Set_CType_Command ; Set the cursor to blanks 593 02A6 B9 0F0F Mov CX,Blank_Cursor ; . 594 02A9 CD 10 Int Video_Interrupt ; ..End 595 02AB C1090: 596 02AB 59 Pop CX ; Restore the registers 597 02AC 5B Pop BX ; . 598 02AD 58 Pop AX ; ..End 599 02AE C1099: 600 02AE C3 Ret 601 ; 602 02AF C1000_Get_And_Set_Video Endp 603 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-18 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 604 Page 605 ;************************************************************************ 606 ;* * 607 ;* C1100_DISPLAY_INTRO * 608 ;* * 609 ;* This module displays the introductory message to FREECOPY. * 610 ;* Please do not disable this message, since it states the * 611 ;* conditions under which a person may copy this program. * 612 ;* * 613 ;************************************************************************ 614 ; 615 Public C1100_Display_Intro 616 ; 617 02AF C1100_Display_Intro Proc Near 618 ; 619 02AF C1101: 620 02AF BE 0CE5 R Mov SI,Offset MES00_Copy_Notice ; Display the copy notice 621 02B2 E8 0B36 R Call U1000_Display_Message ; ..End 622 02B5 C1199: 623 02B5 C3 Ret 624 02B6 C1100_Display_Intro Endp 625 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-19 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 626 Page 627 ;************************************************************************ 628 ;* * 629 ;* C1200_PARSE_COMMANDS * 630 ;* * 631 ;* This module parses the command line entered by the user * 632 ;* by checking the following conditions: * 633 ;* * 634 ;* 1. The source and/or the target drives do not exist. * 635 ;* * 636 ;* 2. The command line contains any characters other than two * 637 ;* drive letters (e.g., a filename). * 638 ;* * 639 ;* 3. The /1 (single side) parameter is on the command line. * 640 ;* * 641 ;************************************************************************ 642 ; 643 Public C1200_Parse_Commands 644 ; 645 02B6 C1200_Parse_Commands Proc Near 646 ; 647 02B6 C1201: 648 02B6 80 FC FF Cmp AH,Invalid_Drive ; Compare for invalid drive parms 649 02B9 75 0E Jne C1202 ; . 650 02BB C6 06 0CD6 R 00 Mov Byte Ptr FLG01_Good_Command,False 651 02C0 BE 0F78 R Mov SI,Offset MES14_Invalid_Drive 652 02C3 E8 0B36 R Call U1000_Display_Message 653 02C6 E9 0381 R Jmp C1299 ; . 654 02C9 C1202: ; . 655 02C9 3C FF Cmp AL,Invalid_Drive ; . 656 02CB 75 0E Jne C1203 ; . 657 02CD C6 06 0CD6 R 00 Mov Byte Ptr FLG01_Good_Command,False 658 02D2 BE 0F78 R Mov SI,Offset MES14_Invalid_Drive 659 02D5 E8 0B36 R Call U1000_Display_Message 660 02D8 E9 0381 R Jmp C1299 ; ..End 661 02DB C1203: 662 02DB A0 005C R Mov AL,Byte Ptr Source_Drive 663 02DE A2 12EB R Mov Byte Ptr WRK01_Source_Drive,AL 664 02E1 A0 006C R Mov AL,Byte Ptr Target_Drive 665 02E4 A2 12EC R Mov Byte Ptr WRK02_Target_Drive,AL 666 02E7 C1204: 667 02E7 BE 005D R Mov SI,Offset Source_Filename 668 02EA BF 12ED R Mov DI,Offset WRK03_Valid_Filename 669 02ED B9 000B Mov CX,Eleven ; Set CX to compare 11 characters 670 02F0 C1205: 671 02F0 8A 04 Mov AL,[SI] ; Compare for valid source diskette 672 02F2 8A 25 Mov AH,[DI] ; filename in the FCB at 05DH 673 02F4 3A E0 Cmp AH,AL ; . 674 02F6 74 0E Je C1206 ; . 675 02F8 C6 06 0CD6 R 00 Mov Byte Ptr FLG01_Good_Command,False  The Microsoft MACRO Assembler , Version 1.25 Page 1-20 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 676 02FD BE 0F2E R Mov SI,Offset MES12_Invalid_Parameter 677 0300 E8 0B36 R Call U1000_Display_Message 678 0303 EB 7C 90 Jmp C1299 ; . 679 0306 C1206: ; . 680 0306 46 Inc SI ; . 681 0307 47 Inc DI ; . 682 0308 E2 E6 Loop C1205 ; ..End 683 030A C1207: 684 030A BE 006D R Mov SI,Offset Target_Filename 685 030D BF 12ED R Mov DI,Offset WRK03_Valid_Filename 686 0310 B9 000B Mov CX,Eleven ; Set CX to comapre 11 characters 687 0313 C1208: 688 0313 8A 04 Mov AL,[SI] ; Compare for valid target diskette 689 0315 8A 25 Mov AH,[DI] ; . filename in the FCB at 06DH 690 0317 3A E0 Cmp AH,AL ; . 691 0319 74 0E Je C1209 ; . 692 031B C6 06 0CD6 R 00 Mov Byte Ptr FLG01_Good_Command,False 693 0320 BE 0F2E R Mov SI,Offset MES12_Invalid_Parameter 694 0323 E8 0B36 R Call U1000_Display_Message 695 0326 EB 59 90 Jmp C1299 ; . 696 0329 C1209: ; . 697 0329 46 Inc SI ; . 698 032A 47 Inc DI ; . 699 032B E2 E6 Loop C1208 ; ..End 700 032D C1210: 701 032D A0 0080 R Mov AL,Byte Ptr Parameter_Count 702 0330 A2 12F8 R Mov Byte Ptr WRK04_Parameter_Count,AL 703 0333 BE 0081 R Mov SI,Offset Parameter_String 704 0336 FE 06 12F8 R Inc Byte Ptr WRK04_Parameter_Count 705 033A C1211: 706 033A FE 0E 12F8 R Dec Byte Ptr WRK04_Parameter_Count 707 033E 74 41 Jz C1299 ; Go to the end of the module 708 0340 8A 04 Mov AL,[SI] ; Put the character into AL 709 0342 3C 2F Cmp AL,Slash ; Compare character with a slash 710 0344 74 03 Je C1212 ; If so, then continue processing 711 0346 46 Inc SI ; Increment the command string addr 712 0347 EB F1 Jmp C1211 ; Go back and try again 713 0349 C1212: 714 0349 46 Inc SI ; Increment the command string addr 715 034A 8A 04 Mov AL,[SI] ; Get the next char after the slash 716 034C 3C 31 Cmp AL,One_Digit ; Compare with the char 1 717 034E 74 0E Je C1214 ; Set double side flag to false 718 0350 C1213: 719 0350 C6 06 0CD6 R 00 Mov Byte Ptr FLG01_Good_Command,False 720 0355 BE 0F2E R Mov SI,Offset MES12_Invalid_Parameter 721 0358 E8 0B36 R Call U1000_Display_Message 722 035B EB 24 90 Jmp C1299 ; Go to the end of the module 723 035E C1214: 724 035E C6 06 0CD7 R 00 Mov Byte Ptr FLG02_Double_Side,False 725 0363 FE 0E 12F8 R Dec Byte Ptr WRK04_Parameter_Count  The Microsoft MACRO Assembler , Version 1.25 Page 1-21 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 726 0367 74 18 Jz C1299 ; Go to the end of the module 727 0369 C1215: 728 0369 FE 0E 12F8 R Dec Byte Ptr WRK04_Parameter_Count 729 036D 74 12 Jz C1299 ; Go to the end of the module 730 036F 46 Inc SI ; Increment the command string addr 731 0370 8A 04 Mov AL,[SI] ; Get the next char in command line 732 0372 3C 20 Cmp AL,Space ; Check for spaces 733 0374 74 F3 Je C1215 ; If equal to a space, continue 734 0376 C1216: 735 0376 C6 06 0CD6 R 00 Mov Byte Ptr FLG01_Good_Command,False 736 037B BE 0F2E R Mov SI,Offset MES12_Invalid_Parameter 737 037E E8 0B36 R Call U1000_Display_Message 738 0381 C1299: 739 0381 C3 Ret 740 ; 741 0382 C1200_Parse_Commands Endp 742 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-22 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 743 Page 744 ;************************************************************************ 745 ;* * 746 ;* C1300_GET_EQUIPMENT * 747 ;* * 748 ;* This module determines the peripheral devices on the machine. * 749 ;* It invokes the equipment status interrupt and places the * 750 ;* information into the appropriate SYStem parameters. * 751 ;* * 752 ;************************************************************************ 753 ; 754 Public C1300_Get_Equipment 755 756 0382 C1300_Get_Equipment Proc Near 757 ; 758 0382 C1301: 759 0382 CD 11 Int Equipment_Interrupt ; Get the equipment on machine 760 0384 8B D8 Mov BX,AX ; Save the result for future use 761 ; 762 0386 25 C000 And AX,Parallel_Ports_Mask ; Get the number of parallel ports 763 0389 B1 0E Mov CL,Fourteen ; . 764 038B D3 E8 Shr AX,CL ; . 765 038D A2 1373 R Mov Byte Ptr SYS07_No_Parallel_Ports,AL 766 ; 767 0390 8B C3 Mov AX,BX ; Get the game adapter attachments 768 0392 25 0100 And AX,Game_Adapters_Mask ; . 769 0395 B1 0C Mov CL,Twelve ; . 770 0397 D3 E8 Shr AX,CL ; . 771 0399 A2 1374 R Mov Byte Ptr SYS08_Game_Adapters,AL 772 ; 773 039C 8B C3 Mov AX,BX ; Get the number of RS-232 ports 774 039E 25 0E00 And AX,RS232_Ports_Mask ; . 775 03A1 B1 09 Mov CL,Nine ; . 776 03A3 D3 E8 Shr AX,CL ; . 777 03A5 A2 1375 R Mov Byte Ptr SYS09_No_RS232_Ports,AL 778 ; 779 03A8 8B C3 Mov AX,BX ; Get the number of diskette drives 780 03AA 25 00C0 And AX,Disk_Drives_Mask ; . 781 03AD B1 06 Mov CL,Six ; . 782 03AF D3 E8 Shr AX,CL ; . 783 03B1 A2 1376 R Mov Byte Ptr SYS10_No_Disk_Drives,AL 784 ; 785 03B4 8B C3 Mov AX,BX ; Get the initial video mode 786 03B6 25 0030 And AX,Init_Video_Mask ; . 787 03B9 B1 04 Mov CL,Four ; . 788 03BB D3 E8 Shr AX,CL ; . 789 03BD A2 1377 R Mov Byte Ptr SYS11_Init_Video_Mode,AL 790 ; 791 03C0 8B C3 Mov AX,BX ; Get planar RAM size 792 03C2 25 000C And AX,Planar_RAM_Mask ; .  The Microsoft MACRO Assembler , Version 1.25 Page 1-23 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 793 03C5 B1 02 Mov CL,Two ; . 794 03C7 D3 E8 Shr AX,CL ; . 795 03C9 A2 1378 R Mov Byte Ptr SYS12_Planar_RAM_Size,AL 796 ; 797 03CC 8B C3 Mov AX,BX ; Get IPL from diskette flag 798 03CE 25 0001 And AX,IPL_Diskette_Mask ; . 799 03D1 A2 1379 R Mov Byte Ptr SYS13_IPL_From_Diskette,AL 800 ; 801 03D4 C1399: 802 03D4 C3 Ret 803 ; 804 03D5 C1300_Get_Equipment Endp 805 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-24 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 806 Page 807 ;************************************************************************ 808 ;* * 809 ;* C1400_VALIDATE_DRIVES * 810 ;* * 811 ;* This module determines if the drives specified in the * 812 ;* command line are floppy disk drives or RAM disk drives. * 813 ;* It also checks if copying the source diskette takes place * 814 ;* on a single drive. * 815 ;* * 816 ;************************************************************************ 817 ; 818 Public C1400_Validate_Drives 819 ; 820 03D5 C1400_Validate_Drives Proc Near 821 ; 822 03D5 C1401: 823 03D5 B4 19 Mov AH,Default_Drive_Command; Get the PC DOS default drive 824 03D7 CD 21 Int PC_DOS_Interrupt ; . 825 03D9 A2 137A R Mov Byte Ptr SYS14_Default_Drive,AL 826 03DC C1402: 827 03DC 80 3E 1376 R 00 Cmp Byte Ptr SYS10_No_Disk_Drives,Minimum_Drives 828 03E1 77 12 Ja C1403 ; If not single drive copy, set 829 ; . FLG04 to false 830 03E3 C6 06 137A R 00 Mov Byte Ptr SYS14_Default_Drive,Minimum_Drives 831 03E8 C6 06 12EB R 00 Mov Byte Ptr WRK01_Source_Drive,Minimum_Drives 832 03ED C6 06 12EC R 00 Mov Byte Ptr WRK02_Target_Drive,Minimum_Drives 833 03F2 EB 4D 90 Jmp C1499 ; Go to the end of the module 834 03F5 C1403: 835 03F5 C6 06 0CD9 R 00 Mov Byte Ptr FLG04_Single_Drive,False 836 03FA C1404: 837 03FA 80 3E 137A R 03 Cmp Byte Ptr SYS14_Default_Drive,Maximum_Drives 838 03FF 76 0E Jbe C1405 ; If below maximum, continue 839 0401 C6 06 0CD8 R 00 Mov Byte Ptr FLG03_Default_Drive,False 840 0406 BE 0F52 R Mov SI,Offset MES13_Invalid_Default 841 0409 E8 0B36 R Call U1000_Display_Message 842 040C EB 33 90 Jmp C1499 ; Go to the end of the module 843 040F C1405: 844 040F FE 0E 12EB R Dec Byte Ptr WRK01_Source_Drive 845 0413 80 3E 12EB R FF Cmp Byte Ptr WRK01_Source_Drive,Minus_One 846 0418 75 06 Jne C1406 847 041A A0 137A R Mov AL,Byte Ptr SYS14_Default_Drive 848 041D A2 12EB R Mov Byte Ptr WRK01_Source_Drive,AL 849 0420 C1406: 850 0420 FE 0E 12EC R Dec Byte Ptr WRK02_Target_Drive 851 0424 80 3E 12EC R FF Cmp Byte Ptr WRK02_Target_Drive,Minus_One 852 0429 75 06 Jne C1407 853 042B A0 137A R Mov AL,Byte Ptr SYS14_Default_Drive 854 042E A2 12EC R Mov Byte Ptr WRK02_Target_Drive,AL 855 0431 C1407:  The Microsoft MACRO Assembler , Version 1.25 Page 1-25 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 856 0431 A0 12EB R Mov AL,Byte Ptr WRK01_Source_Drive 857 0434 8A 26 12EC R Mov AH,Byte Ptr WRK02_Target_Drive 858 0438 3A E0 Cmp AH,AL ; Check source drive = target drive 859 043A 75 05 Jne C1499 ; If so, then continue 860 043C C6 06 0CD9 R 01 Mov Byte Ptr FLG04_Single_Drive,True 861 0441 C1499: 862 0441 C3 Ret 863 ; 864 0442 C1400_Validate_Drives Endp 865 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-26 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 866 Page 867 ;************************************************************************ 868 ;* * 869 ;* C1500_DISKETTE_MESSAGES * 870 ;* * 871 ;* This module displays the appropriate source and target * 872 ;* insertion diskette messages on the screen. * 873 ;* * 874 ;************************************************************************ 875 ; 876 Public C1500_Diskette_Messages 877 ; 878 0442 C1500_Diskette_Messages Proc Near 879 ; 880 0442 C1501: 881 0442 80 3E 0CDC R 00 Cmp Byte Ptr FLG07_First_Time,False 882 0447 74 0D Je C1502 ; If not first time, continue 883 0449 80 3E 0CD9 R 00 Cmp Byte Ptr FLG04_Single_Drive,False 884 044E 74 06 Je C1502 ; If false, then continue 885 0450 BE 0F99 R Mov SI,Offset MES15_Single_Drive_Copy 886 0453 E8 0B36 R Call U1000_Display_Message 887 0456 C1502: 888 0456 BE 0EC4 R Mov SI,Offset MES09_Insert_Source 889 0459 A0 12EB R Mov AL,Byte Ptr WRK01_Source_Drive 890 045C 04 41 Add AL,Capital_Letter_A ; Put the drive letter into AL 891 045E 88 44 22 Mov [SI+Thirty_Four],AL ; Put the drive letter into the 892 ; . correct position in the message 893 0461 E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 894 0464 C1503: 895 0464 80 3E 0CD9 R 01 Cmp Byte Ptr FLG04_Single_Drive,True 896 0469 74 0E Je C1505 ; If true, go to the message to press 897 ; . any key to continue 898 046B C1504: 899 046B BE 0EEC R Mov SI,Offset MES10_Insert_Target 900 046E A0 12EC R Mov AL,Byte Ptr WRK02_Target_Drive 901 0471 04 41 Add AL,Capital_Letter_A ; Put the drive letter into AL 902 0473 88 44 22 Mov [SI+Thirty_Four],AL ; Put the drive letter into the 903 ; . correct position in the message 904 0476 E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 905 0479 C1505: 906 0479 BE 0FC6 R Mov SI,Offset MES16_Press_Any_Key 907 047C E8 0B36 R Call U1000_Display_Message 908 047F C6 06 0CDA R 00 Mov Byte Ptr FLG05_Store_Buffer,False 909 0484 E8 0B54 R Call U1100_Get_Response 910 0487 C1599: 911 0487 C3 Ret 912 ; 913 0488 C1500_Diskette_Messages Endp 914 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-27 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 915 Page 916 ;************************************************************************ 917 ;* * 918 ;* C1600_GET_FREE_MEMORY * 919 ;* * 920 ;* This module calculates the amount of free 16 byte paragraphs * 921 ;* available on the machine. The segment address of the beginning * 922 ;* of free memory is obtained by setting DX to: * 923 ;* * 924 ;* 1. The contents of the stack segment SS plus * 925 ;* * 926 ;* 2. 256 bytes for the Program Segment Prefix plus * 927 ;* * 928 ;* 3. 128 bytes for the stack. * 929 ;* * 930 ;* After saving the ES segment register on the stack and * 931 ;* initializing both the offset register BX and the 16 byte * 932 ;* counter register CX to zero, the routine begins the looping * 933 ;* through memory 16 bytes at a time (incrementing the segment * 934 ;* register ES by one) until either the module encounters one * 935 ;* of the two (2) conditions: * 936 ;* * 937 ;* 1. The beginning of Video RAM at the segment address * 938 ;* specified in Video_Address. * 939 ;* * 940 ;* 2. The memory pattern defined by the machine that * 941 ;* indicates no more memory. * 942 ;* * 943 ;* When either of these two (2) conditions occur, CX contains * 944 ;* the number of 16 bytes paragraphs of free memory. * 945 ;* * 946 ;* Since we do not know the size of the transient portion of * 947 ;* COMMAND.COM, FREECOPY makes the worst case assumption that * 948 ;* all of the bytes in COMMAND.COM reside in high memory. * 949 ;* * 950 ;* This module also allocates space for the ES:BX table, the * 951 ;* CHRN table, the File Allocation Table (FAT) of the source * 952 ;* diskette and at least one track (4608 bytes). * 953 ;* * 954 ;************************************************************************ 955 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-28 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 956 Page 957 ; 958 Public C1600_Get_Free_Memory 959 ; 960 0488 C1600_Get_Free_Memory Proc Near 961 ; 962 0488 C1601: 963 0488 8C D2 Mov DX,SS ; Calculate the segment address for 964 ; . the beginning of free memory 965 048A 81 C2 140C R Add DX,Offset MEM04_Top_of_the_Stack 966 ; 967 048E 06 Push ES ; Save ES on the stack for a moment 968 048F BB 0000 Mov BX,NUL ; Initialize BX and CX registers 969 0492 B9 0000 Mov CX,NUL ; ..End 970 0495 C1602: 971 0495 8E C2 Mov ES,DX ; Set ES to the appropriate value 972 0497 FA Cli ; Turn off interrupts for a moment 973 0498 26: 8B 07 Mov AX,ES:[BX] ; Read a word from memory into AX 974 049B 26: C7 07 0001 Mov Word Ptr ES:[BX],SOH ; Put the test pattern into memory 975 04A0 26: 83 3F 01 Cmp Word Ptr ES:[BX],SOH ; Compare memory with test pattern 976 04A4 26: 89 07 Mov ES:[BX],AX ; Restore the contents of memory 977 04A7 FB Sti ; Turn on the interrupts 978 04A8 75 0A Jne C1603 ; If not equal, stop looping 979 04AA 42 Inc DX ; Increment DX segment register 980 04AB 81 FA A000 Cmp DX,Video_Address ; Compare for start of Video RAM 981 04AF 73 03 Jae C1603 ; If so, stop looping 982 04B1 41 Inc CX ; Increment 16 byte counter CX 983 04B2 EB E1 Jmp C1602 ; Go back and try again 984 04B4 C1603: 985 04B4 07 Pop ES ; Restore the ES register 986 04B5 81 F9 0465 Cmp CX,Command_Com_Size ; Compare the paragraph size of 987 ; . free memory with the paragraph 988 ; . size of COMMAND.COM. 989 04B9 77 0E Ja C1604 ; If greater, continue 990 ; 991 04BB C6 06 0CD6 R 00 Mov Byte Ptr FLG01_Good_Command,False 992 04C0 BE 0F14 R Mov SI,Offset MES11_Insufficient_Memory 993 04C3 E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 994 04C6 EB 61 90 Jmp C1699 ; Go to the end of the module 995 04C9 C1604: 996 04C9 81 E9 0465 Sub CX,Command_Com_Size ; Subtract the size of COMMAND.COM 997 04CD 83 F9 14 Cmp CX,ESBX_Table_Size ; Compare the paragraph size of the 998 ; . free memory with the paragraph 999 ; . size of the ES:BX table 1000 04D0 77 0E Ja C1605 ; If greater, continue 1001 04D2 C6 06 0CD6 R 00 Mov Byte Ptr FLG01_Good_Command,False 1002 04D7 BE 0F14 R Mov SI,Offset MES11_Insufficient_Memory 1003 04DA E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 1004 04DD EB 4A 90 Jmp C1699 ; Go to the end of the module 1005 04E0 C1605:  The Microsoft MACRO Assembler , Version 1.25 Page 1-29 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1006 04E0 83 E9 14 Sub CX,ESBX_Table_Size ; Subtract the size of ES:BX table 1007 04E3 81 F9 00B4 Cmp CX,CHRN_Table_Size ; Compare the paragraph size of the 1008 ; . free memory with the paragraph 1009 ; . size of the CHRN table 1010 04E7 77 0E Ja C1606 ; If greater, continue 1011 ; 1012 04E9 C6 06 0CD6 R 00 Mov Byte Ptr FLG01_Good_Command,False 1013 04EE BE 0F14 R Mov SI,Offset MES11_Insufficient_Memory 1014 04F1 E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 1015 04F4 EB 33 90 Jmp C1699 ; Go to the end of the module 1016 04F7 C1606: 1017 04F7 81 E9 00B4 Sub CX,CHRN_Table_Size ; Subtract the size of CHRN Table 1018 04FB 83 F9 20 Cmp CX,FAT_Sector_Size ; Determine if there is enough memory 1019 04FE 73 0E Jae C1607 ; to read the File Allocation Table 1020 0500 C6 06 0CD6 R 00 Mov Byte Ptr FLG01_Good_Command,False 1021 0505 BE 0F14 R Mov SI,Offset MES11_Insufficient_Memory 1022 0508 E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 1023 050B EB 1C 90 Jmp C1699 ; Go to the end of the module 1024 050E C1607: 1025 050E 83 E9 20 Sub CX,FAT_Sector_Size ; Subtract the size of the source FAT 1026 0511 81 F9 0120 Cmp CX,Minimum_Memory_Size ; Determine if the amount of memory 1027 0515 73 0E Jae C1608 ; can hold a nine sectored track 1028 ; 1029 0517 C6 06 0CD6 R 00 Mov Byte Ptr FLG01_Good_Command,False 1030 051C BE 0F14 R Mov SI,Offset MES11_Insufficient_Memory 1031 051F E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 1032 0522 EB 05 90 Jmp C1699 ; Go to the end of the module 1033 0525 C1608: 1034 0525 89 0E 1370 R Mov Word Ptr SYS05_Para_RAM_Size,CX 1035 0529 C1699: 1036 0529 C3 Ret 1037 ; 1038 052A C1600_Get_Free_Memory Endp 1039 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-30 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1040 Page 1041 ;************************************************************************ 1042 ;* * 1043 ;* C1700_CREATE_ESBX_TABLE * 1044 ;* * 1045 ;* This module creates the correct ES:BX addresses that are * 1046 ;* used when storing tracks read from the source diskette. * 1047 ;* The routine allocates at most 80 entries in the table for * 1048 ;* double sided diskettes. * 1049 ;* * 1050 ;************************************************************************ 1051 ; 1052 Public C1700_Create_ESBX_Table 1053 ; 1054 052A C1700_Create_ESBX_Table Proc Near 1055 ; 1056 052A C1701: 1057 052A C7 06 1359 R 0000 Mov Word Ptr WRK18_Counter_ESBX_Entries,Zero 1058 0530 B8 0009 Mov AX,Nine ; Calculate DI = the number of bytes 1059 0533 BB 0200 Mov BX,Sector_Size ; per track and BX = the number of 1060 0536 F7 E3 Mul BX ; paragraphs per track 1061 0538 8B F8 Mov DI,AX ; . 1062 053A BB 0010 Mov BX,Paragraph_Size ; . 1063 053D F7 F3 Div BX ; . 1064 053F 8B D8 Mov BX,AX ; ..End 1065 ; 1066 0541 8C C8 Mov AX,CS ; Calculate the address of the 1st 1067 0543 B1 04 Mov CL,Four ; that will be copied into memory 1068 0545 D3 E0 Shl AX,CL ; . 1069 0547 05 228E R Add AX,Offset MEM00_Bottom_Free_Memory 1070 054A D3 E8 Shr AX,CL ; . 1071 054C 40 Inc AX ; ..End 1072 ; 1073 054D BE 140E R Mov SI,Offset MEM03_ESBX_Table 1074 0550 C7 04 0000 Mov Word Ptr [SI],Zero ; Put the 1st entry into the table 1075 0554 89 44 02 Mov Word Ptr [SI+Two],AX ; ..End 1076 0557 C1702: 1077 0557 83 3E 1359 R 4F Cmp Word Ptr WRK18_Counter_ESBX_Entries,Seventy_Nine 1078 055C 73 29 Jae C1705 ; Calculate the ES:BX valid entries 1079 055E 83 C6 04 Add SI,Four ; Get the next ES:BX table address 1080 ; 1081 0561 8B 44 FE Mov AX,[SI-Two] ; Check for DMA overflow error 1082 0564 25 0FFF And AX,DMA_Boundary_Mask ; . 1083 0567 D3 E0 Shl AX,CL ; . 1084 0569 03 C7 Add AX,DI ; . 1085 056B 73 08 Jnc C1703 ; ..End 1086 ; 1087 056D 8B 44 FE Mov AX,[SI-Two] ; Correction for DMA overflow 1088 0570 03 C3 Add AX,BX ; . 1089 0572 89 44 FE Mov [SI-Two],AX ; ..End  The Microsoft MACRO Assembler , Version 1.25 Page 1-31 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1090 0575 C1703: 1091 0575 8B 44 FE Mov AX,[SI-Two] ; Increment the ES segment address 1092 0578 03 C3 Add AX,BX ; ..End 1093 057A C1704: 1094 057A C7 04 0000 Mov Word Ptr [SI],Zero ; Put the address into the table 1095 057E 89 44 02 Mov Word Ptr [SI+Two],AX ; ..End 1096 0581 FF 06 1359 R Inc Word Ptr WRK18_Counter_ESBX_Entries 1097 0585 EB D0 Jmp C1702 ; Go back and find another entry 1098 0587 C1705: 1099 0587 A1 1370 R Mov AX,Word Ptr SYS05_Para_RAM_Size 1100 058A F7 F3 Div BX ; Divide by the paragraphs per track 1101 058C A3 135B R Mov Word Ptr WRK19_Number_ESBX_Entries,AX 1102 058F 83 3E 135B R 4F Cmp Word Ptr WRK19_Number_ESBX_Entries,Seventy_Nine 1103 0594 76 06 Jbe C1799 ; If less than 79, continue 1104 0596 C7 06 135B R 004F Mov Word Ptr WRK19_Number_ESBX_Entries,Seventy_Nine 1105 059C C1799: 1106 059C C3 Ret 1107 ; 1108 059D C1700_Create_ESBX_Table Endp 1109 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-32 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1110 Page 1111 ;************************************************************************ 1112 ;* * 1113 ;* C1800_VALIDATE_SOURCE_DISK * 1114 ;* * 1115 ;* This module determines if the source diskette is readable * 1116 ;* and whether it was formatted under PC DOS 1.0, 1.1, 2.0 or * 1117 ;* 2.1. The routine also reads the first copy of the File * 1118 ;* Allocation Table (FAT) storing it for future comparisons * 1119 ;* as well as analyzing it first entry. * 1120 ;* * 1121 ;* A series of comparisons for the number of sectors per track * 1122 ;* is done for the following reasons. All diskettes formatted * 1123 ;* under PC DOS 2.0 and 2.1 really have nine sectors. In order * 1124 ;* to obtain an eight sectored diskette, the operating system * 1125 ;* sets the first byte of the File Allocation Table (FAT) * 1126 ;* accordingly. In contrast, PC DOS 1.0 and 1.1 formats a track * 1127 ;* to have exactly eight sectors. * 1128 ;* * 1129 ;************************************************************************ 1130 ; 1131 Public C1800_Validate_Source_Disk 1132 ; 1133 059D C1800_Validate_Source_Disk Proc Near 1134 ; 1135 059D C1801: 1136 059D C6 06 0CDD R 01 Mov Byte Ptr FLG08_Good_Read,True 1137 ; 1138 05A2 A0 12EB R Mov AL,Byte Ptr WRK01_Source_Drive 1139 05A5 A2 134B R Mov Byte Ptr WRK06_Drive_Number,AL 1140 05A8 C6 06 134C R 00 Mov Byte Ptr WRK07_Head_Number,Zero 1141 05AD C6 06 134D R 00 Mov Byte Ptr WRK08_Track_Number,Zero 1142 05B2 C6 06 134E R 09 Mov Byte Ptr WRK09_Sector_Number,Nine 1143 05B7 C6 06 134F R 01 Mov Byte Ptr WRK10_Number_of_Sectors,One 1144 05BC 0E Push CS ; Establish the address ES:BX 1145 05BD 07 Pop ES ; ..End 1146 05BE BB 208E R Mov BX,Offset MEM01_File_Allocation_Table 1147 ; 1148 05C1 E8 0956 R Call D1000_Read_Diskette 1149 ; 1150 05C4 FA Cli ; Set the number of sectors to nine 1151 05C5 C6 06 1385 R 09 Mov Byte Ptr SYS18_Disk_Parameter_Table[Four],Nine 1152 05CA FB Sti ; . 1153 05CB C6 06 1358 R 09 Mov Byte Ptr WRK17_Maximum_Sectors,Nine 1154 ; 1155 05D0 80 3E 0CDD R 01 Cmp Byte Ptr FLG08_Good_Read,True 1156 05D5 74 1E Je C1803 ; Check for good read of sector nine 1157 05D7 80 3E 1355 R 04 Cmp Byte Ptr WRK14_Status_Operation,Sector_Error 1158 05DC 74 0B Je C1802 ; If so, continue 1159 05DE C6 06 0CE4 R 01 Mov Byte Ptr FLG15_IO_Error,One  The Microsoft MACRO Assembler , Version 1.25 Page 1-33 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1160 05E3 E8 0A31 R Call D1200_Disk_IO_Error ; Process the error 1161 05E6 E9 06FC R Jmp C1899 ; ..End 1162 05E9 C1802: 1163 05E9 FA Cli ; Set the number of sectors to eight 1164 05EA C6 06 1385 R 08 Mov Byte Ptr SYS18_Disk_Parameter_Table[Four],Eight 1165 05EF FB Sti ; . 1166 05F0 C6 06 1358 R 08 Mov Byte Ptr WRK17_Maximum_Sectors,Eight 1167 05F5 C1803: ; . 1168 05F5 C6 06 0CDD R 01 Mov Byte Ptr FLG08_Good_Read,True 1169 ; 1170 05FA A0 12EB R Mov AL,Byte Ptr WRK01_Source_Drive 1171 05FD A2 134B R Mov Byte Ptr WRK06_Drive_Number,AL 1172 0600 C6 06 134C R 00 Mov Byte Ptr WRK07_Head_Number,Zero 1173 0605 C6 06 134D R 00 Mov Byte Ptr WRK08_Track_Number,Zero 1174 060A C6 06 134E R 02 Mov Byte Ptr WRK09_Sector_Number,Two 1175 060F C6 06 134F R 01 Mov Byte Ptr WRK10_Number_of_Sectors,One 1176 0614 0E Push CS ; Establish the address ES:BX 1177 0615 07 Pop ES ; ..End 1178 0616 BB 208E R Mov BX,Offset MEM01_File_Allocation_Table 1179 ; 1180 0619 E8 0956 R Call D1000_Read_Diskette 1181 ; 1182 061C 80 3E 0CDD R 01 Cmp Byte Ptr FLG08_Good_Read,True 1183 0621 74 0B Je C1804 ; If the read operation was 1184 ; . successful, continue 1185 0623 C6 06 0CE4 R 01 Mov Byte Ptr FLG15_IO_Error,One 1186 0628 E8 0A31 R Call D1200_Disk_IO_Error ; Display appropriate error message 1187 062B E9 06FC R Jmp C1899 ; Go to the end of the module 1188 062E C1804: 1189 062E A0 208E R Mov AL,Byte Ptr MEM01_File_Allocation_Table[Zero] 1190 ; 1191 0631 3C FE Cmp AL,One_Side_Eight_Sectors 1192 0633 75 10 Jne C1805 ; If not, continue 1193 0635 C6 06 1356 R 00 Mov Byte Ptr WRK15_Maximum_Heads,Zero 1194 063A C6 06 1357 R 27 Mov Byte Ptr WRK16_Maximum_Tracks,Thirty_Nine 1195 063F BE 0DD5 R Mov SI,Offset MES03_Copy81_Sectors 1196 0642 EB 51 90 Jmp C1809 ; Continue the processing 1197 0645 C1805: 1198 0645 3C FF Cmp AL,Two_Sides_Eight_Sectors 1199 0647 75 10 Jne C1806 ; If not, continue 1200 0649 C6 06 1356 R 01 Mov Byte Ptr WRK15_Maximum_Heads,One 1201 064E C6 06 1357 R 4F Mov Byte Ptr WRK16_Maximum_Tracks,Seventy_Nine 1202 0653 BE 0DFE R Mov SI,Offset MES04_Copy82_Sectors 1203 0656 EB 3D 90 Jmp C1809 ; Continue the processing 1204 0659 C1806: 1205 0659 3C FC Cmp AL,One_Side_Nine_Sectors 1206 065B 75 10 Jne C1807 ; If not, continue 1207 065D C6 06 1356 R 00 Mov Byte Ptr WRK15_Maximum_Heads,Zero 1208 0662 C6 06 1357 R 27 Mov Byte Ptr WRK16_Maximum_Tracks,Thirty_Nine 1209 0667 BE 0E28 R Mov SI,Offset MES05_Copy91_Sectors  The Microsoft MACRO Assembler , Version 1.25 Page 1-34 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1210 066A EB 29 90 Jmp C1809 ; Continue the processing 1211 066D C1807: 1212 066D 3C FD Cmp AL,Two_Sides_Nine_Sectors 1213 066F 75 10 Jne C1808 ; If not, continue 1214 0671 C6 06 1356 R 01 Mov Byte Ptr WRK15_Maximum_Heads,One 1215 0676 C6 06 1357 R 4F Mov Byte Ptr WRK16_Maximum_Tracks,Seventy_Nine 1216 067B BE 0E51 R Mov SI,Offset MES06_Copy92_Sectors 1217 067E EB 15 90 Jmp C1809 ; Continue the processing 1218 0681 C1808: 1219 0681 C6 06 0CDD R 00 Mov Byte Ptr FLG08_Good_Read,False 1220 0686 BE 102D R Mov SI,Offset MES19_Unrecoverable_Read 1221 0689 E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 1222 068C BE 1252 R Mov SI,Offset MES90_Unknown_FAT_Error 1223 068F E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 1224 0692 EB 68 90 Jmp C1899 ; Go to display the message 1225 0695 C1809: 1226 0695 80 3E 1356 R 00 Cmp Byte Ptr WRK15_Maximum_Heads,Zero 1227 069A 74 11 Je C1810 ; If the diskette is single sided, 1228 ; . display the diskette message 1229 069C 80 3E 0CD7 R 01 Cmp Byte Ptr FLG02_Double_Side,True 1230 06A1 74 0A Je C1810 ; If the flag indicates to copy 1231 ; . both sides of the diskette, 1232 ; . then continue 1233 06A3 C6 06 1356 R 00 Mov Byte Ptr WRK15_Maximum_Heads,Zero 1234 06A8 C6 06 1357 R 27 Mov Byte Ptr WRK16_Maximum_Tracks,Thirty_Nine 1235 06AD C1810: 1236 06AD A0 12EB R Mov AL,Byte Ptr WRK01_Source_Drive 1237 06B0 A2 134B R Mov Byte Ptr WRK06_Drive_Number,AL 1238 06B3 C6 06 134C R 01 Mov Byte Ptr WRK07_Head_Number,One 1239 06B8 C6 06 134D R 00 Mov Byte Ptr WRK08_Track_Number,Zero 1240 06BD C6 06 134E R 01 Mov Byte Ptr WRK09_Sector_Number,One 1241 06C2 C6 06 134F R 01 Mov Byte Ptr WRK10_Number_of_Sectors,One 1242 06C7 0E Push CS ; Establish the ES segment register 1243 06C8 07 Pop ES ; ..End 1244 06C9 BB 228E R Mov BX,Offset MEM00_Bottom_Free_Memory 1245 ; 1246 06CC E8 0956 R Call D1000_Read_Diskette 1247 ; 1248 06CF 80 3E 0CDD R 01 Cmp Byte Ptr FLG08_Good_Read,True 1249 06D4 74 23 Je C1812 ; Go to display the message 1250 06D6 80 3E 1356 R 01 Cmp Byte Ptr WRK15_Maximum_Heads,One 1251 06DB 74 0D Je C1811 ; If double sided diskette, error!!! 1252 06DD C6 06 0CDD R 01 Mov Byte Ptr FLG08_Good_Read,True 1253 06E2 C6 06 0CD7 R 00 Mov Byte Ptr FLG02_Double_Side,False 1254 06E7 EB 10 90 Jmp C1812 ; Display the appropriate message 1255 06EA C1811: 1256 06EA BE 102D R Mov SI,Offset MES19_Unrecoverable_Read 1257 06ED E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 1258 06F0 BE 1293 R Mov SI,Offset MES91_Single_Side_Error 1259 06F3 E8 0B36 R Call U1000_Display_Message ; Display the message on the screen  The Microsoft MACRO Assembler , Version 1.25 Page 1-35 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1260 06F6 EB 04 90 Jmp C1899 ; Go to the end of the module 1261 06F9 C1812: 1262 06F9 E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 1263 06FC C1899: 1264 06FC C3 Ret 1265 ; 1266 06FD C1800_Validate_Source_Disk Endp 1267 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-36 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1268 Page 1269 ;************************************************************************ 1270 ;* * 1271 ;* C1900_CREATE_CHRN_TABLE * 1272 ;* * 1273 ;* This module creates the CHRN table to be used in case the * 1274 ;* target diskette needs to be formatted. The abbreviation * 1275 ;* stands for C = track number, H = head number, R = sector * 1276 ;* number and N = a code for the number of bytes per sector. * 1277 ;* * 1278 ;************************************************************************ 1279 ; 1280 Public C1900_Create_CHRN_Table 1281 ; 1282 06FD C1900_Create_CHRN_Table Proc Near 1283 ; 1284 06FD C1901: 1285 06FD 8A 3E 1356 R Mov BH,Byte Ptr WRK15_Maximum_Heads 1286 0701 8A 1E 1357 R Mov BL,Byte Ptr WRK16_Maximum_Tracks 1287 0705 B0 09 Mov AL,Nine 1288 ; 1289 0707 8A CF Mov CL,BH ; Establish correct track number 1290 0709 D2 EB Shr BL,CL ; ..End 1291 ; 1292 070B B2 02 Mov DL,Two ; . DL = number of sectors 1293 070D B6 00 Mov DH,Zero ; . DH = head number 1294 070F B5 00 Mov CH,Zero ; . CH = track number 1295 0711 B1 01 Mov CL,One ; . CL = sector number 1296 0713 BE 154E R Mov SI,Offset MEM02_CHRN_Table; Set up initial registers 1297 0716 C1902: 1298 0716 88 2C Mov [SI],CH ; Establish an entry in the CHRN 1299 0718 88 74 01 Mov [SI+One],DH ; . table 1300 071B 88 4C 02 Mov [SI+Two],CL ; . 1301 071E 88 54 03 Mov [SI+Three],DL ; ..End 1302 ; 1303 0721 83 C6 04 Add SI,Four ; Get the addr of next CHRN entry 1304 0724 FE C1 Inc CL ; Increment the sector number 1305 0726 3A C8 Cmp CL,AL ; Compare for maximum sectors 1306 0728 76 EC Jbe C1902 ; If not, go back and try again 1307 ; 1308 072A B1 01 Mov CL,One ; Initialize sector number 1309 072C FE C6 Inc DH ; Increment the head number 1310 072E 3A F7 Cmp DH,BH ; Compare for maximum heads 1311 0730 76 E4 Jbe C1902 ; If not, go back and try again 1312 ; 1313 0732 B1 01 Mov CL,One ; Initialize sector number 1314 0734 B6 00 Mov DH,Zero ; Initialize head number 1315 0736 FE C5 Inc CH ; Increment the track number 1316 0738 3A EB Cmp CH,BL ; Compare for maximum tracks 1317 073A 76 DA Jbe C1902 ; If not, go back and try again  The Microsoft MACRO Assembler , Version 1.25 Page 1-37 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1318 073C C1999: 1319 073C C3 Ret 1320 ; 1321 073D C1900_Create_CHRN_Table Endp 1322 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-38 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1323 Page 1324 ;************************************************************************ 1325 ;* * 1326 ;* C2000_READ_SOURCE_DISK * 1327 ;* * 1328 ;* This module reads a diskette track by track until it fills * 1329 ;* all of available memory specified by the ES:BX table. The * 1330 ;* processing sequence is: * 1331 ;* * 1332 ;* 1. Initializes the SI resgister to point to the correct entry * 1333 ;* in the ES:BX table. * 1334 ;* * 1335 ;* 2. Prints the initial read message on the screen. * 1336 ;* * 1337 ;* 3. Compares for the end of the ES:BX table and/or the number * 1338 ;* of tracks on the diskette. If not, continue. If so, * 1339 ;* return to B1100_Detail_Processing. * 1340 ;* * 1341 ;* 4. Reads a track from the source diskette. * 1342 ;* * 1343 ;* 5. Displays the track and head numbers on the screen. * 1344 ;* * 1345 ;* 6. Transfers control to 3. * 1346 ;* * 1347 ;************************************************************************ 1348 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-39 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1349 Page 1350 ; 1351 Public C2000_Read_Source_Disk 1352 ; 1353 073D C2000_Read_Source_Disk Proc Near 1354 ; 1355 073D C2001: 1356 073D C6 06 0CDD R 01 Mov Byte Ptr FLG08_Good_Read,True 1357 ; 1358 0742 BE 140E R Mov SI,Offset MEM03_ESBX_Table 1359 0745 C7 06 1359 R 0000 Mov Word Ptr WRK18_Counter_ESBX_Entries,Zero 1360 ; 1361 074B 80 3E 0CE2 R 00 Cmp Byte Ptr FLG13_First_Read_Write,False 1362 0750 74 08 Je C2002 ; If not first time, continue 1363 0752 C6 06 1368 R 00 Mov Byte Ptr WRK31_Track_Read_Counter,Zero 1364 0757 EB 08 90 Jmp C2003 ; Go to display the message 1365 075A C2002: 1366 075A 80 3E 0CD9 R 00 Cmp Byte Ptr FLG04_Single_Drive,False 1367 075F 74 2E Je C2004 ; If double drive copy, continue 1368 0761 C2003: 1369 0761 56 Push SI ; Save SI = Addr of ES:BX table 1370 0762 BE 12CA R Mov SI,Offset MES97_Return_Linefeed 1371 0765 E8 0B36 R Call U1000_Display_Message ; Display a return and linefeed 1372 0768 BE 0FE4 R Mov SI,Offset MES17_Reading_Track 1373 076B A0 135E R Mov AL,Byte Ptr WRK21_Current_Source_Track 1374 076E E8 0C5C R Call U1300_Convert_Binary_to_ASCII 1375 0771 89 44 0F Mov [SI+Fifteen],AX ; Put the track number into message 1376 0774 A0 135D R Mov AL,Byte Ptr WRK20_Current_Source_Head 1377 0777 E8 0C5C R Call U1300_Convert_Binary_to_ASCII 1378 077A 88 44 19 Mov [SI+Twenty_Five],AL ; Put the head number into message 1379 077D E8 0B36 R Call U1000_Display_Message ; Display the message on the screeen 1380 ; 1381 0780 B4 03 Mov AH,Read_Cursor_Command ; Get the current cursor position 1382 0782 8A 3E 136E R Mov BH,Byte Ptr SYS03_Active_Page 1383 0786 CD 10 Int Video_Interrupt ; ..End 1384 ; 1385 0788 FE CE Dec DH ; Save the row of the read track and 1386 078A 88 36 1361 R Mov Byte Ptr WRK24_Read_Message_Row,DH; . head message 1387 ; 1388 078E 5E Pop SI ; Restore SI = Addr of ES:BX table 1389 078F C2004: 1390 078F A1 1359 R Mov AX,Word Ptr WRK18_Counter_ESBX_Entries 1391 0792 3B 06 135B R Cmp AX,Word Ptr WRK19_Number_ESBX_Entries 1392 0796 76 03 Jbe C2005 ; If more memory exists, continue 1393 0798 E9 0820 R Jmp C2099 ; Go to the end of the module 1394 079B C2005: 1395 079B A0 1368 R Mov AL,Byte Ptr WRK31_Track_Read_Counter 1396 079E 3A 06 1357 R Cmp AL,Byte Ptr WRK16_Maximum_Tracks 1397 07A2 76 03 Jbe C2006 ; If more tracks, then continue 1398 07A4 EB 7A 90 Jmp C2099 ; Go to the end of the module  The Microsoft MACRO Assembler , Version 1.25 Page 1-40 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1399 07A7 C2006: 1400 ; ; Display the current track and head 1401 07A7 A0 1361 R Mov AL,Byte Ptr WRK24_Read_Message_Row 1402 07AA A2 1365 R Mov Byte Ptr WRK28_Current_Message_Row,AL 1403 07AD A0 135D R Mov AL,Byte Ptr WRK20_Current_Source_Head 1404 07B0 A2 1366 R Mov Byte Ptr WRK29_Current_Head,AL 1405 07B3 A0 135E R Mov AL,Byte Ptr WRK21_Current_Source_Track 1406 07B6 A2 1367 R Mov Byte Ptr WRK30_Current_Track,AL 1407 ; 1408 07B9 E8 0C6B R Call U1400_Display_Head_and_Track 1409 ; 1410 ; Establish the disk parameters 1411 07BC A0 12EB R Mov AL,Byte Ptr WRK01_Source_Drive 1412 07BF A2 134B R Mov Byte Ptr WRK06_Drive_Number,AL 1413 07C2 A0 135D R Mov AL,Byte Ptr WRK20_Current_Source_Head 1414 07C5 A2 134C R Mov Byte Ptr WRK07_Head_Number,AL 1415 07C8 A0 135E R Mov AL,Byte Ptr WRK21_Current_Source_Track 1416 07CB A2 134D R Mov Byte Ptr WRK08_Track_Number,AL 1417 07CE C6 06 134E R 01 Mov Byte Ptr WRK09_Sector_Number,One 1418 07D3 A0 1358 R Mov AL,Byte Ptr WRK17_Maximum_Sectors 1419 07D6 A2 134F R Mov Byte Ptr WRK10_Number_of_Sectors,AL 1420 07D9 8B 04 Mov AX,DS:[SI] ; . 1421 07DB 8B D8 Mov BX,AX ; . 1422 07DD 8B 44 02 Mov AX,DS:[SI+Two] ; . 1423 07E0 8E C0 Mov ES,AX ; ..End 1424 ; 1425 07E2 E8 0956 R Call D1000_Read_Diskette ; Read the source diskette 1426 07E5 C2007: 1427 07E5 80 3E 0CDD R 01 Cmp Byte Ptr FLG08_Good_Read,True 1428 07EA 74 0B Je C2008 ; If the read operation was 1429 ; . successful, then continue 1430 07EC C6 06 0CE4 R 01 Mov Byte Ptr FLG15_IO_Error,One 1431 07F1 E8 0A31 R Call D1200_Disk_IO_Error ; Display appropriate error message 1432 07F4 EB 2A 90 Jmp C2099 ; Go to the end of the module 1433 07F7 C2008: 1434 07F7 FE 06 1368 R Inc Byte Ptr WRK31_Track_Read_Counter 1435 07FB FF 06 1359 R Inc Word Ptr WRK18_Counter_ESBX_Entries 1436 07FF 83 C6 04 Add SI,Four ; Increment addr of the ES:BX table 1437 0802 80 3E 0CD7 R 00 Cmp Byte Ptr FLG02_Double_Side,False 1438 0807 74 10 Je C2009 ; If single sided, then continue 1439 0809 FE 06 135D R Inc Byte Ptr WRK20_Current_Source_Head 1440 080D 80 3E 135D R 01 Cmp Byte Ptr WRK20_Current_Source_Head,One 1441 0812 76 09 Jbe C2010 ; If the head number is less than or 1442 ; . equal to one, then continue 1443 0814 C6 06 135D R 00 Mov Byte Ptr WRK20_Current_Source_Head,Zero 1444 0819 C2009: 1445 0819 FE 06 135E R Inc Byte Ptr WRK21_Current_Source_Track 1446 081D C2010: 1447 081D E9 078F R Jmp C2004 ; Go back and read another track 1448 0820 C2099:  The Microsoft MACRO Assembler , Version 1.25 Page 1-41 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1449 0820 C3 Ret 1450 ; 1451 0821 C2000_Read_Source_Disk Endp 1452 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-42 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1453 Page 1454 ;************************************************************************ 1455 ;* * 1456 ;* C2100_WRITE_FORMAT_TARGET_DISK * 1457 ;* * 1458 ;* This module formats and writes a diskette track by track * 1459 ;* until it fills all of available memory specified by the * 1460 ;* ES:BX table. The processing sequence is: * 1461 ;* * 1462 ;* 1. Initializes the SI resgister to point to the correct entry * 1463 ;* in the ES:BX table. * 1464 ;* * 1465 ;* 2. Prints the initial write message on the screen. * 1466 ;* * 1467 ;* 3. Compares for the end of the ES:BX table and/or the number * 1468 ;* of tracks on the diskette. If not, continue. If so, * 1469 ;* return to B1100_Detail_Processing. * 1470 ;* * 1471 ;* 4. Writes a track from the source diskette. * 1472 ;* * 1473 ;* 5. Displays the track and head numbers on the screen. * 1474 ;* * 1475 ;* 6. Transfers control to 3. * 1476 ;* * 1477 ;************************************************************************ 1478 ; 1479 Public C2100_Write_Format_Target_Disk 1480 ; 1481 0821 C2100_Write_Format_Target_Disk Proc Near 1482 ; 1483 0821 C2101: 1484 0821 C6 06 0CDE R 01 Mov Byte Ptr FLG09_Good_Write,True 1485 0826 C6 06 0CE0 R 01 Mov Byte Ptr FLG11_Good_Format,True 1486 ; 1487 082B C6 06 1354 R 05 Mov Byte Ptr WRK13_Retry_Counter,Number_of_Retries 1488 ; 1489 0830 BE 140E R Mov SI,Offset MEM03_ESBX_Table 1490 0833 C7 06 1359 R 0000 Mov Word Ptr WRK18_Counter_ESBX_Entries,Zero 1491 ; 1492 0839 80 3E 0CE2 R 00 Cmp Byte Ptr FLG13_First_Read_Write,False 1493 083E 74 08 Je C2102 ; If not first time, continue 1494 0840 C6 06 1369 R 00 Mov Byte Ptr WRK32_Track_Write_Counter,Zero 1495 0845 EB 08 90 Jmp C2103 ; Go to display the message 1496 0848 C2102: 1497 0848 80 3E 0CD9 R 00 Cmp Byte Ptr FLG04_Single_Drive,False 1498 084D 74 23 Je C2104 ; If double drive copy, continue 1499 084F C2103: 1500 084F 56 Push SI ; Save SI = Addr of ES:BX table 1501 ; 1502 0850 BE 12CA R Mov SI,Offset MES97_Return_Linefeed  The Microsoft MACRO Assembler , Version 1.25 Page 1-43 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1503 0853 E8 0B36 R Call U1000_Display_Message ; Display return and line feed 1504 0856 BE 10C4 R Mov SI,Offset MES23_Writing_Track 1505 0859 E8 0B36 R Call U1000_Display_Message ; Display write track message 1506 ; 1507 085C B4 03 Mov AH,Read_Cursor_Command ; Get the current cursor position 1508 085E 8A 3E 136E R Mov BH,Byte Ptr SYS03_Active_Page 1509 0862 CD 10 Int Video_Interrupt ; ..End 1510 ; 1511 0864 FE CE Dec DH ; Save the row of the I/O track and 1512 0866 88 36 1364 R Mov Byte Ptr WRK27_Write_Message_Row,DH; . head information 1513 086A 80 EE 02 Sub DH,Two ; . 1514 086D 88 36 1361 R Mov Byte Ptr WRK24_Read_Message_Row,DH 1515 ; 1516 0871 5E Pop SI ; Restore SI = Addr of ES:BX table 1517 0872 C2104: 1518 0872 A1 1359 R Mov AX,Word Ptr WRK18_Counter_ESBX_Entries 1519 0875 3B 06 135B R Cmp AX,Word Ptr WRK19_Number_ESBX_Entries 1520 0879 76 03 Jbe C2105 ; If more memory exists, continue 1521 087B EB 7A 90 Jmp C2199 ; Go to the end of the module 1522 087E C2105: 1523 087E A0 1369 R Mov AL,Byte Ptr WRK32_Track_Write_Counter 1524 0881 3A 06 1357 R Cmp AL,Byte Ptr WRK16_Maximum_Tracks 1525 0885 76 08 Jbe C2106 ; If more tracks, then continue 1526 0887 C6 06 0CE3 R 01 Mov Byte Ptr FLG14_Copy_Complete,True 1527 088C EB 69 90 Jmp C2199 ; Go to the end of the module 1528 088F C2106: 1529 ; ; Establish the disk parameters 1530 088F A0 12EC R Mov AL,Byte Ptr WRK02_Target_Drive 1531 0892 A2 134B R Mov Byte Ptr WRK06_Drive_Number,AL 1532 0895 A0 135F R Mov AL,Byte Ptr WRK22_Current_Target_Head 1533 0898 A2 134C R Mov Byte Ptr WRK07_Head_Number,AL 1534 089B A0 1360 R Mov AL,Byte Ptr WRK23_Current_Target_Track 1535 089E A2 134D R Mov Byte Ptr WRK08_Track_Number,AL 1536 08A1 C6 06 134E R 01 Mov Byte Ptr WRK09_Sector_Number,One 1537 08A6 A0 1358 R Mov AL,Byte Ptr WRK17_Maximum_Sectors 1538 08A9 A2 134F R Mov Byte Ptr WRK10_Number_of_Sectors,AL 1539 08AC 8B 44 02 Mov AX,DS:[SI+Two] ; . 1540 08AF A3 1350 R Mov Word Ptr WRK11_Segment_Address,AX 1541 08B2 8B 04 Mov AX,DS:[SI] ; . 1542 08B4 A3 1352 R Mov Word Ptr WRK12_Offset_Address,AX 1543 ; 1544 08B7 E8 0992 R Call D1100_Write_Format_Diskette 1545 ; 1546 08BA 80 3E 0CE0 R 01 Cmp Byte Ptr FLG11_Good_Format,True 1547 08BF 74 0D Je C2107 ; If a good format, continue 1548 08C1 80 3E 0CDE R 01 Cmp Byte Ptr FLG09_Good_Write,True 1549 08C6 74 06 Je C2107 ; If a good write, continue 1550 08C8 E8 0A31 R Call D1200_Disk_IO_Error ; Display appropriate error message 1551 08CB EB 2A 90 Jmp C2199 ; Go to the end of the module 1552 08CE C2107:  The Microsoft MACRO Assembler , Version 1.25 Page 1-44 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1553 08CE FE 06 1369 R Inc Byte Ptr WRK32_Track_Write_Counter 1554 08D2 FF 06 1359 R Inc Word Ptr WRK18_Counter_ESBX_Entries 1555 08D6 83 C6 04 Add SI,Four ; Increment addr of the ES:BX table 1556 08D9 80 3E 0CD7 R 00 Cmp Byte Ptr FLG02_Double_Side,False 1557 08DE 74 10 Je C2108 ; If single sided, then continue 1558 08E0 FE 06 135F R Inc Byte Ptr WRK22_Current_Target_Head 1559 08E4 80 3E 135F R 01 Cmp Byte Ptr WRK22_Current_Target_Head,One 1560 08E9 76 09 Jbe C2109 ; If the head number is less than or 1561 ; . equal to one, then continue 1562 08EB C6 06 135F R 00 Mov Byte Ptr WRK22_Current_Target_Head,Zero 1563 08F0 C2108: 1564 08F0 FE 06 1360 R Inc Byte Ptr WRK23_Current_Target_Track 1565 08F4 C2109: 1566 08F4 E9 0872 R Jmp C2104 ; Go back and write another track 1567 08F7 C2199: 1568 08F7 C3 Ret 1569 ; 1570 08F8 C2100_Write_Format_Target_Disk Endp 1571 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-45 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1572 Page 1573 ;************************************************************************ 1574 ;* * 1575 ;* C2200_CHECK_FILE_ALLOC_TABLE * 1576 ;* * 1577 ;* This module checks the File Allocation Table (FAT) of the * 1578 ;* diskette in the source drive and compares it with the File * 1579 ;* Allocation Table (FAT) of the original source diskette. If * 1580 ;* there are any differences, the program sets the flag * 1581 ;* FLG12_Good_FAT to False; otherwise, the flag is True. * 1582 ;* * 1583 ;************************************************************************ 1584 ; 1585 Public C2200_Check_File_Alloc_Table 1586 ; 1587 08F8 C2200_Check_File_Alloc_Table Proc Near 1588 ; 1589 08F8 C2201: 1590 08F8 C6 06 0CE1 R 01 Mov Byte Ptr FLG12_Good_FAT,True 1591 ; 1592 08FD A0 12EB R Mov AL,Byte Ptr WRK01_Source_Drive 1593 0900 A2 134B R Mov Byte Ptr WRK06_Drive_Number,AL 1594 0903 C6 06 134C R 00 Mov Byte Ptr WRK07_Head_Number,Zero 1595 0908 C6 06 134D R 00 Mov Byte Ptr WRK08_Track_Number,Zero 1596 090D C6 06 134E R 02 Mov Byte Ptr WRK09_Sector_Number,Two 1597 0912 C6 06 134F R 01 Mov Byte Ptr WRK10_Number_of_Sectors,One 1598 0917 0E Push CS ; Establish the ES segment register 1599 0918 07 Pop ES ; ..End 1600 0919 BB 228E R Mov BX,Offset MEM00_Bottom_Free_Memory 1601 ; 1602 091C E8 0956 R Call D1000_Read_Diskette ; Read the File Allocation Table 1603 ; 1604 091F 80 3E 0CDD R 01 Cmp Byte Ptr FLG08_Good_Read,True 1605 0924 74 0B Je C2202 ; If the read operation was 1606 ; . successful, continue 1607 0926 C6 06 0CE4 R 01 Mov Byte Ptr FLG15_IO_Error,One 1608 092B E8 0A31 R Call D1200_Disk_IO_Error ; Display appropriate error message 1609 092E EB 25 90 Jmp C2299 ; Go to the end of the module 1610 0931 C2202: 1611 0931 BE 208E R Mov SI,Offset MEM01_File_Allocation_Table 1612 0934 BF 228E R Mov DI,Offset MEM00_Bottom_Free_Memory 1613 0937 B9 0200 Mov CX,Sector_Size ; Set counter CX to compare the 1614 ; . sector size in words 1615 093A D1 E9 Shr CX,1 ; ..End 1616 093C FC Cld ; Clear the direction flag 1617 093D F3/ A7 Rep Cmpsw ; Compare all of the 512 bytes 1618 093F 75 03 Jne C2203 ; If there is a discrepancy, go to 1619 ; . the error message routine 1620 0941 EB 12 90 Jmp C2299 ; Go to the end of the module 1621 0944 C2203:  The Microsoft MACRO Assembler , Version 1.25 Page 1-46 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1622 0944 C6 06 0CE1 R 00 Mov Byte Ptr FLG12_Good_FAT,False 1623 0949 BE 102D R Mov SI,Offset MES19_Unrecoverable_Read 1624 094C E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 1625 094F BE 1252 R Mov SI,Offset MES90_Unknown_FAT_Error 1626 0952 E8 0B36 R Call U1000_Display_Message ; Display the message on the screen 1627 0955 C2299: 1628 0955 C3 Ret 1629 ; 1630 0956 C2200_Check_File_Alloc_Table Endp 1631 ;  The Microsoft MACRO Assembler , Version 1.25 Page 1-47 FREECOPY Version 1.0 (C)Copyright 1984 09-15-84 1632 Page 1633 ;************************************************************************ 1634 ;* * 1635 ;* D1000_READ_DISKETTE * 1636 ;* * 1637 ;* This module reads a track at a time from a diskette. If it * 1638 ;* fails to read the diskette it tries Number_of_Retries = 5 * 1639 ;* times. * 1640 ;* * 1641 ;************************************************************************ 1642 ; 1643 Public D1000_Read_Diskette 1644 ; 1645 0956 D1000_Read_Diskette Proc Near 1646 ; 1647 0956 D1001: 1648 0956 C6 06 1354 R 05 Mov Byte Ptr WRK13_Retry_Counter,Number_of_Retries 1649 095B D1002: 1650 095B F8 Clc ; Clear the carry flag 1651 095C B4 02 Mov AH,Read_Command ; Read the data on the diskette 1652 095E 8A 16 134B R Mov DL,Byte Ptr WRK06_Drive_Number 1653 0962 8A 36 134C R Mov DH,Byte Ptr WRK07_Head_Number 1654 0966 8A 2E 134D R Mov CH,Byte Ptr WRK08_Track_Number 1655 096A 8A 0E 134E R Mov CL,Byte Ptr WRK09_Sector_Number  0966 8A 2E 134D R Mov CH,Byte Ptr WRK08_Track_Number 1655 096A 8A 0E 134E R Mov CL,Byte Ptr WRK09_Sector_Num