home *** CD-ROM | disk | FTP | other *** search
- ;***********************************************************************
- ;* *
- ;* Fmt.asm 23-JAN-1990 *
- ;* *
- ;* Format Floppy Disk - version 1.00 - IBM(R) DOS 4.0 style format *
- ;* *
- ;* Designed for use with IBM AT compatible sytems (including PS/2s) *
- ;* *
- ;* Syntax: FMT d: size [v] [s] [n] *
- ;* *
- ;* where: d = drive (A or B), size = floppy size in Kb, *
- ;* *
- ;* the optional v enables format verification, *
- ;* *
- ;* the optional s copies the system files, *
- ;* *
- ;* and the optional n bypasses the `insert floppy' prompt *
- ;* *
- ;* supported sizes are: *
- ;* *
- ;* 360 for a 360 Kb floppy in a 360 Kb or 1.2 Mb drive *
- ;* 720 for a 720 Kb floppy in a 720 Kb or 1.44 Mb drive *
- ;* 1200 for a 1.2 Mb floppy in a 1.2 Mb drive *
- ;* 1440 for a 1.44 Mb floppy in a 1.44 Mb drive *
- ;* *
- ;* Exit codes: *
- ;* *
- ;* 0 = successful format *
- ;* 1 = failure during format, verify, or write *
- ;* 2 = disk size / drive type combination is not supported *
- ;* 3 = requested drive does not exist *
- ;* 4 = invalid or null command line *
- ;* 5 = system files not found or error writing system files *
- ;* 6 = computer is not AT compatible *
- ;* 7 = insufficient memory for file copy buffer (system transfer) *
- ;* *
- ;* In order to use the system transfer option, the following files *
- ;* *
- ;* must be in the root diectory of the default drive: *
- ;* *
- ;* 1: IBMBIO.COM (normally a hidden file) *
- ;* *
- ;* 2: IBMDOS.COM (normally a hidden file) *
- ;* *
- ;* 3: COMMAND.COM *
- ;* *
- ;* Compile with Borland Turbo Assembler(R) version 1.0 or greater *
- ;* *
- ;* tasm /t fmt tasm /t /zi fmt *
- ;* or *
- ;* tlink /t /x fmt tlink /v /x fmt *
- ;* *
- ;* tdstrip -c -s fmt *
- ;* *
- ;* for use with Turbo Debugger(R) *
- ;* or *
- ;* *
- ;* Compile with Microsoft(R) Macro Assembler version 5.1 or greater *
- ;* *
- ;* masm /t fmt; *
- ;* *
- ;* link fmt; *
- ;* *
- ;* exe2bin fmt fmt.com *
- ;* *
- ;* del fmt.exe *
- ;* *
- ;* Copyright (C) 1990 by: *
- ;* *
- ;* Clair Alan Hardesty *
- ;* IBM-PC Hardware/Software Consultant *
- ;* 10301 Johnson Av *
- ;* Cupertino, CA 95014 *
- ;* (408) 446-0550 *
- ;* CompuServe 75350,16 *
- ;* *
- ;* Microsoft(R) is a registered trademark of Microsoft Corporation *
- ;* *
- ;* IBM(R) and PS/2 are registered trademarks of International *
- ;* *
- ;* Business Machines Corporation *
- ;* *
- ;* Turbo Assembler(R) and Turbo Debugger(R) are registered trademarks *
- ;* *
- ;* of Borland International *
- ;* *
- ;***********************************************************************
-
- ;***********************************************************************
-
- ; set-up for the far jump used in the boot record code
-
- ;***********************************************************************
-
- ibmbio segment at 0070h
-
- assume cs:ibmbio
-
- org 0000h
-
- program_loader label far
-
- ibmbio ends
-
- ;***********************************************************************
-
- ; set-up for system identification
-
- ;***********************************************************************
-
- rom_bios segment at 0f000h
-
- assume ds:rom_bios
-
- org 0fffeh
-
- system_id label byte
-
- rom_bios ends
-
- ;***********************************************************************
-
- ; main program code
-
- ;***********************************************************************
-
- cseg segment
-
- assume cs:cseg,ds:cseg,es:cseg,ss:cseg
-
- org 0100h
- entry_point:
- jmp start ; skip over data area
-
- ;***********************************************************************
-
- ; format data area
-
- ;***********************************************************************
-
- ; format sector tables
- sector_table_0:
- db 000h,000h,001h,002h
- db 000h,000h,002h,002h
- db 000h,000h,003h,002h
- db 000h,000h,004h,002h
- db 000h,000h,005h,002h
- db 000h,000h,006h,002h
- db 000h,000h,007h,002h
- db 000h,000h,008h,002h
- db 000h,000h,009h,002h
- db 000h,000h,00Ah,002h
- db 000h,000h,00Bh,002h
- db 000h,000h,00Ch,002h
- db 000h,000h,00Dh,002h
- db 000h,000h,00Eh,002h
- db 000h,000h,00Fh,002h
- db 000h,000h,010h,002h
- db 000h,000h,011h,002h
- db 000h,000h,012h,002h
-
- sector_table_1:
- db 000h,001h,001h,002h
- db 000h,001h,002h,002h
- db 000h,001h,003h,002h
- db 000h,001h,004h,002h
- db 000h,001h,005h,002h
- db 000h,001h,006h,002h
- db 000h,001h,007h,002h
- db 000h,001h,008h,002h
- db 000h,001h,009h,002h
- db 000h,001h,00Ah,002h
- db 000h,001h,00Bh,002h
- db 000h,001h,00Ch,002h
- db 000h,001h,00Dh,002h
- db 000h,001h,00Eh,002h
- db 000h,001h,00Fh,002h
- db 000h,001h,010h,002h
- db 000h,001h,011h,002h
- db 000h,001h,012h,002h
-
- ;***********************************************************************
-
- temp_size: db 4 dup (?)
- binary_size: dw ?
- verify: db 0 ; default is no verification
- system: db 0 ; default is no system file transfer
- prompt: db 1 ; default is prompt for floppy
- drive_number: db ?
- disk_drive: dw ?
- max_track: db ?
- retry_count: db ?
- write_track: dw ?
- write_head: db ?
- write_sector: db ?
- cursor: dw ?
- stack_size: dw 2048 ; used in buffer size calculation
- minimum_buffer: dw 4096 ; minimum file copy buffer size
- buffer_size: dw ? ; actual file copy buffer size
-
- ;***********************************************************************
-
- disk_size: db ?
-
- ; 1 = 360kb
- ; 2 = 1.2Mb
- ; 3 = 720kb
- ; 4 = 1.44Mb
-
- drive_type: db ?
-
- ; 0 = no drive
- ; 1 = 360kb
- ; 2 = 1.2Mb
- ; 3 = 720kb
- ; 4 = 1.44Mb
-
- ;***********************************************************************
-
- parameter_pointer:
-
- dd ? ; storage for the original disk parameter table pointer
-
- ;***********************************************************************
-
- floppy_table:
- ; 360 Kb
-
- db 0FDh ; media descriptor
- db 40 ; number of tracks
- dw 9 ; sectors per track
- dw 112 ; entries per root directory
- db 7 ; sectors per root directory
- db 2 ; sectors per cluster
- dw 2 ; sectors per FAT
-
- ; 1.2 Mb
-
- db 0F9h ; media descriptor
- db 80 ; number of tracks
- dw 15 ; sectors per track
- dw 224 ; entries per root directory
- db 14 ; sectors per root directory
- db 1 ; sectors per cluster
- dw 7 ; sectors per FAT
-
- ; 720 Kb
-
- db 0F9h ; media descriptor
- db 80 ; number of tracks
- dw 9 ; sectors per track
- dw 112 ; entries per root directory
- db 7 ; sectors per root directory
- db 2 ; sectors per cluster
- dw 3 ; sectors per FAT
-
- ; 1.44 Mb
-
- db 0F0h ; media descriptor
- db 80 ; number of tracks
- dw 18 ; sectors per track
- dw 224 ; entries per root directory
- db 14 ; sectors per root directory
- db 1 ; sectors per cluster
- dw 9 ; sectors per FAT
-
- ;***********************************************************************
-
- parameter_table:
-
- ; 360 Kb
-
- db 0D2h,002h,009h,002h,009h,02Ah,0FFh,050h,0F6h,001h,001h
-
- ; 1.2 Mb
-
- db 082h,002h,009h,002h,00Fh,01Bh,0FFh,054h,0F6h,001h,001h
-
- ; 720 Kb
-
- db 012h,002h,009h,002h,009h,02Ah,0FFh,050h,0F6h,001h,001h
-
- ; 1.44 Mb
-
- db 012h,002h,009h,002h,012h,01Bh,0FFh,06Ch,0F6h,001h,001h
-
- ;***********************************************************************
-
- ; informational messages
-
- ;***********************************************************************
-
- cr_lf:
- db 00Dh,00Ah
- db "$"
-
- insert_floppy:
-
- db "Put desired floppy in drive "
-
- insert_drive:
-
- db ?
- db ": and press any key"
- db "$"
-
- clear_line:
-
- db 50 dup (008h)
- db 50 dup (020h)
- db 50 dup (008h)
- db "$"
-
- format_display:
-
- db 26 dup (008h)
- db "Formatting track "
-
- format_track_number:
-
- db 2 dup (?)
- db " head "
-
- format_head_number:
-
- db ?
- db "$"
-
- verify_display:
-
- db 26 dup (008h)
- db "Verifying track "
-
- verify_track_number:
-
- db 2 dup (?)
- db " head "
-
- verify_head_number:
-
- db ?
- db "$"
-
- boot_message:
-
- db 26 dup (008h)
- db 26 dup (020h)
- db 26 dup (008h)
- db "Writing boot record"
- db "$"
-
- fat_message:
-
- db 19 dup (008h)
- db 19 dup (020h)
- db 19 dup (008h)
- db "Writing FATs"
- db "$"
-
- dir_message:
-
- db 12 dup (008h)
- db 12 dup (020h)
- db 12 dup (008h)
- db "Writing root directory"
- db "$"
-
- file_copy_message:
-
- db 22 dup (008h)
- db 22 dup (020h)
- db 22 dup (008h)
- db "Copying system files"
- db "$"
-
- exit_message:
-
- db 22 dup (008h)
- db 22 dup (020h)
- db 22 dup (008h)
- db "Format complete"
- db 00Dh,00Ah
- db "$"
-
- ;***********************************************************************
-
- ; error messages
-
- ;***********************************************************************
-
- computer_message:
-
- db 00Dh,00Ah,"IBM AT or compatible computer required",00Dh,00Ah
- db "$"
-
- no_drive_error:
-
- db 00Dh,00Ah,"No such drive in system",00Dh,00Ah
- db "$"
-
- reset_error:
-
- db 00Dh,00Ah,"Disk controller reset error",00Dh,00Ah
- db "$"
-
- set_drive_error:
-
- db 00Dh,00Ah,"Disk drive type not supported by BIOS",00Dh,00Ah
- db "$"
-
- no_floppy_error:
-
- db 00Dh,00Ah,"No floppy in drive",00Dh,00Ah
- db "$"
-
- set_disk_error:
-
- db 00Dh,00Ah,"Disk / Drive combination not supported",00Dh,00Ah
- db "$"
-
- write_boot_error:
-
- db 00Dh,00Ah,"Error writing boot record",00Dh,00Ah
- db "$"
-
- write_fat_error:
-
- db 00Dh,00Ah,"Error writing FAT",00Dh,00Ah
- db "$"
-
- write_dir_error:
-
- db 00Dh,00Ah,"Error writing directory",00Dh,00Ah
- db "$"
-
- write_protect_error:
-
- db 00Dh,00Ah,"Disk is write protected",00Dh,00Ah
- db "$"
-
- error_during_format:
-
- db 00Dh,00Ah,"Error during format",00Dh,00Ah
- db "$"
-
- disk_type_error:
-
- db 00Dh,00Ah,"Probably wrong floppy type",00Dh,00Ah
- db "$"
-
- verify_error:
-
- db 00Dh,00Ah,"Verification error",00Dh,00Ah
- db "$"
-
- buffer_space_error:
-
- db 00Dh,00Ah,"No room for file copy buffer",00Dh,00Ah
- db "$"
-
- help_message:
-
- db 00Dh,00Ah,"FMT version 1.00, Copyright (C) 1990 Clair Alan Hardesty"
- db 00Dh,00Ah
- db 00Dh,00Ah," syntax: fmt d: size [v] [s] [n]"
- db 00Dh,00Ah
- db 00Dh,00Ah," where: d = drive (A or B), size = floppy size in Kb,"
- db 00Dh,00Ah
- db 00Dh,00Ah," the optional v enables format verification,"
- db 00Dh,00Ah
- db 00Dh,00Ah," the optional s copies the system files,"
- db 00Dh,00Ah
- db 00Dh,00Ah," and the optional n bypasses the `insert floppy' prompt"
- db 00Dh,00Ah
- db 00Dh,00Ah," supported sizes are:"
- db 00Dh,00Ah
- db 00Dh,00Ah," 360 for a 360 Kb floppy in a 360 Kb or 1.2 Mb drive"
- db 00Dh,00Ah," 720 for a 720 Kb floppy in a 720 Kb or 1.44 Mb drive"
- db 00Dh,00Ah," 1200 for a 1.2 Mb floppy in a 1.2 Mb drive"
- db 00Dh,00Ah," 1440 for a 1.44 Mb floppy in a 1.44 Mb drive"
- db 00Dh,00Ah
- db "$"
-
- ;***********************************************************************
-
- ; check cpu and computer type
-
- ;***********************************************************************
-
- start:
- ; check CPU for 80286 or above
-
- xor ax,ax
- push ax
- popf
- pushf
- pop ax
- and ax,08000h
- cmp ax,08000h
-
- jnz two_eighty_six
-
- mov dx,offset computer_message
- mov ah,09h
-
- int 21h
-
- ; exit
-
- jmp short not_an_at
- two_eighty_six:
- ; check the model byte in ROM
-
- push ds
- mov ax,rom_bios
- mov ds,ax
-
- assume ds:rom_bios
-
- cmp system_id,0fch ; AT or compatible
-
- je at_or_better
-
- cmp system_id,0fah ; most P/S-2 (80286) models
-
- je at_or_better
-
- cmp system_id,0f8h ; P/S-2 model 80
-
- je at_or_better
-
- ; computer is not AT compatible
-
- pop ds
-
- assume ds:cseg
-
- mov dx,offset computer_message
- mov ah,09h
-
- int 21h
- not_an_at:
- ; set exit code to 6 (not an AT or compatible)
-
- mov ax,4c06h
-
- int 21h
-
- at_or_better:
-
- ;***********************************************************************
-
- .286 ; enable the 80286 instruction set
-
- ;***********************************************************************
-
- pop ds
-
- assume ds:cseg
-
- ; initialize some variables
-
- mov cl,0 ; parameter counter
- mov dl,0 ; disk size digit counter
- mov di,offset temp_size ; temporary disk size storage
- mov bx,0080h ; pointer to command line
-
- ;***********************************************************************
-
- ; parse the command line
-
- ;***********************************************************************
-
- parse_loop:
- inc bx
- cmp byte ptr [bx],0dh ; carriage return
-
- jne not_finished
-
- jmp got_command
- not_finished:
- cmp byte ptr [bx],' ' ; space
-
- je parse_loop
-
- cmp byte ptr [bx],09h ; tab
-
- je parse_loop
-
- cmp cl,0
-
- jg number_check
-
- and byte ptr [bx],5fh ; capitalize drive letter
- cmp byte ptr [bx],'A'
-
- jnl check_for_b
-
- jmp help ; invalid drive
- check_for_b:
- cmp byte ptr [bx],'B'
-
- jng store_drive
-
- jmp help ; invalid drive
- store_drive:
- mov al,byte ptr [bx]
- sub al,'A'
- mov byte ptr [drive_number],al
- colon_check:
- cmp byte ptr [bx+1],':'
-
- je found_colon
-
- jmp help ; no colon after drive letter
- found_colon:
- inc bx ; skip over the colon
- inc cl ; increment parameter count
-
- jmp parse_loop
- number_check:
- cmp cl,1
-
- jg check_option
-
- cmp byte ptr [bx],'0'
-
- jnl maybe_a_number
-
- jmp help ; not a number
- maybe_a_number:
- cmp byte ptr [bx],'9'
-
- jng is_a_number
-
- jmp help ; not a number
- is_a_number:
- cmp byte ptr [bx+1],0Dh ; next character is a return
-
- je last_digit
-
- cmp byte ptr [bx+1],' ' ; next character is a space
-
- je last_digit
-
- cmp byte ptr [bx+1],09h ; next character is a tab
-
- jne store_digit
- last_digit:
- inc cl ; increment parameter count
- store_digit:
- mov al,byte ptr [bx]
- sub al,'0' ; convert ASCII to BCD
- mov byte ptr [di],al
- inc di
- inc dl
- cmp dl,4
-
- jle jump_to_parse
-
- jmp help ; too many digits in disk size
- jump_to_parse:
- jmp parse_loop
- check_option:
- cmp cl,5
-
- jng parse_option
-
- jmp help ; too many parameters
- parse_option:
- and byte ptr [bx],5fh
- cmp byte ptr [bx],'V'
-
- je set_verify
-
- cmp byte ptr [bx],'S'
-
- je set_system
-
- cmp byte ptr [bx],'N'
-
- je clear_prompt
-
- jmp help ; invalid option
- set_verify:
- mov byte ptr [verify],1 ; set format verify true
- inc cl
-
- jmp parse_loop
- set_system:
- mov byte ptr [system],1 ; set transfer system true
- inc cl
-
- jmp parse_loop
- clear_prompt:
- mov byte ptr [prompt],0 ; set transfer system true
- inc cl
-
- jmp parse_loop
- got_command:
- cmp cl,2
-
- jnl two_parameters
-
- jmp help ; too few parameters
- two_parameters:
- cmp dl,3
-
- jl help ; too few digits in disk size
-
- ; convert the size parameter from BCD to binary
-
- mov cl,dl
- dec di
- xor ah,ah
- mov al,byte ptr [di]
- mov word ptr [binary_size],ax
- dec di
- dec cl
- xor ah,ah
- mov al,byte ptr [di]
- imul ax,10
- add word ptr [binary_size],ax
- dec di
- dec cl
- xor ah,ah
- mov al,byte ptr [di]
- imul ax,100
- add word ptr [binary_size],ax
- dec di
- dec cl
-
- jz test_size_360
-
- xor ah,ah
- mov al,byte ptr [di]
- imul ax,1000
- add word ptr [binary_size],ax
- test_size_360:
- cmp word ptr [binary_size],360
-
- jne test_size_1200 ; not 360 Kb
-
- mov byte ptr [disk_size],1
-
- jmp short set_up ; command line is valid
- test_size_1200:
- cmp word ptr [binary_size],1200
-
- jne test_size_720 ; not 1.2 Mb
-
- mov byte ptr [disk_size],2
-
- jmp short set_up ; command line is valid
- test_size_720:
- cmp word ptr [binary_size],720
-
- jne test_size_1440 ; not 720 Kb
-
- mov byte ptr [disk_size],3
-
- jmp short set_up ; command line is valid
- test_size_1440:
- cmp word ptr [binary_size],1440
-
- jne help ; not 1.44 Mb
-
- mov byte ptr [disk_size],4
-
- jmp short set_up ; command line is valid
- help:
- ; command line is invalid or null
-
- mov dx,offset help_message
- mov ah,09h
-
- int 21h
-
- ; set exit code to 4 (null or invalid command line)
-
- mov ax,4c04h
-
- int 21h
-
- ;***********************************************************************
-
- ; set up the drive parameters and the parameter table
-
- ;***********************************************************************
-
- set_up:
- ; if transfering system, check file copy buffer space
-
- cmp byte ptr [system],1
-
- jne cursor_off
-
- ; calculate copy buffer size
-
- mov ax,sp
- cmp ax,offset file_buffer
-
- jc no_buffer
-
- sub ax,offset file_buffer
- sbb ax,word ptr [stack_size]
-
- jc no_buffer
-
- cmp ax,word ptr [minimum_buffer]
-
- jnc buffer_ok
- no_buffer:
- mov dx,offset buffer_space_error
- mov ah,09h
-
- int 21h
-
- ; set exit code to 7 (no room for file copy buffer)
-
- mov ax,4c07h
-
- int 21h
- buffer_ok:
- mov word ptr [buffer_size],ax
- cursor_off:
- ; save the current cursor and then turn the cursor off
-
- mov ah,03h
-
- int 10h
-
- mov word ptr [cursor],cx
- or cx,2000h
- mov ah,01h
-
- int 10h
-
- ; issue a carrriage-return / line-feed to stdout
-
- mov dx,offset cr_lf
- mov ah,09h
-
- int 21h
-
- ; check for prompt bypass
-
- cmp byte ptr [prompt],1
-
- jne no_prompt
-
- ; prompt for a floppy
-
- mov dx,offset insert_floppy
- mov ah,09h
- mov al,byte ptr [drive_number]
- add al,41h
- mov byte ptr [insert_drive],al
-
- int 21h
-
- ; wait for a key press
-
- xor ah,ah
-
- int 16h
-
- ; clear the message line
-
- mov dx,offset clear_line
- mov ah,09h
- int 21h
- no_prompt:
- ; get disk drive information
-
- push es
- push di
- push si
- mov ah,08h
- mov dl,byte ptr [drive_number]
-
- int 13h
-
- cmp bl,0
-
- jne drive_exists
-
- mov dx,offset no_drive_error
- mov ah,09h
-
- int 21h
-
- ; set exit code to 3 (drive does not exist)
-
- pop ax
- pop ax
- pop ax
- mov ax,4c03h
-
- int 21h
- drive_exists:
- mov byte ptr [max_track],ch
- mov byte ptr [sectors_track],cl
- mov byte ptr [drive_type],bl
- mov ah,byte ptr [disk_size]
- mov al,bl
- mov word ptr [disk_drive],ax
-
- ; check for floppy size less than drive maximum capacity
-
- ; check for a 360 Kb floppy in a 1.2 Mb drive
-
- cmp word ptr [disk_drive],0102h
-
- je forty_tracks
-
- ; check for a 720 Kb floppy in a 1.44 Mb drive
-
- cmp word ptr [disk_drive],0304h
-
- je nine_sectors
-
- ; check for improper disk / drive cominations
-
- cmp word ptr [disk_drive],0201h
-
- je bad_size ; 1.2 Mb in 360 Kb
-
- cmp word ptr [disk_drive],0301h
-
- je bad_size ; 720 Kb in 360 Kb
-
- cmp word ptr [disk_drive],0401h
-
- je bad_size ; 1.44 Mb in 360 Kb
-
- cmp word ptr [disk_drive],0302h
-
- je bad_size ; 720 Kb in 1.2 Mb
-
- cmp word ptr [disk_drive],0402h
-
- je bad_size ; 1.44 Mb in 1.2 Mb
-
- cmp word ptr [disk_drive],0103h
-
- je bad_size ; 360 Kb in 720 Kb
-
- cmp word ptr [disk_drive],0203h
-
- je bad_size ; 1.2 Mb in 720 Kb
-
- cmp word ptr [disk_drive],0403h
-
- je bad_size ; 1.44 Mb in 720 Kb
-
- cmp word ptr [disk_drive],0104h
-
- je bad_size ; 360 Kb in 1.44 Mb
-
- cmp word ptr [disk_drive],0204h
-
- je bad_size ; 1.2 Mb in 1.44 Mb
-
- jmp short size_ok
- bad_size:
- mov dx,offset set_disk_error
- mov ah,09h
-
- int 21h
-
- ; set exit code to 2 (disk / drive comination error)
-
- pop ax
- pop ax
- pop ax
- mov ax,4c02h
-
- int 21h
- forty_tracks:
- mov byte ptr [max_track],39
- nine_sectors:
- mov byte ptr [sectors_track],9
- size_ok:
- ; save the original disk parameter table pointer
-
- xor ax,ax
- mov es,ax
- mov ax,word ptr es:[0078h]
- mov dx,word ptr es:[007ah]
- mov word ptr [parameter_pointer],ax
- mov word ptr [parameter_pointer+2],dx
-
- ; set the disk parameter table pointer for formatting
-
- xor ah,ah
- mov al,byte ptr [disk_size]
- dec ax
- imul ax,11
- add ax,offset parameter_table
- cli
- mov word ptr es:[0078h],ax
- mov word ptr es:[007ah],cs
- sti
-
- ; put the parameter table in the boot record
-
- push cs
- pop es
- mov si,ax
- mov di,offset disk_table
- mov cx,11
- cld
-
- rep movsb
-
- pop si
- pop di
- pop es
-
- ;***********************************************************************
-
- ; store the disk parameters in the boot record and FAT
-
- ;***********************************************************************
-
- push si
-
- ; calculate the offset to the parameters in floppy_table
-
- xor ah,ah
- mov al,byte ptr [disk_size]
- dec ax
- imul ax,10
- mov bx,ax
- mov si,offset floppy_table
-
- ; set the media descriptor byte
-
- mov al,byte ptr [si+bx]
- mov byte ptr [descriptor],al
- mov byte ptr [fat_record],al ; first byte of FAT
-
- ; set the number of root directory entries
-
- mov ax,word ptr [si+bx+4]
- mov word ptr [directory_size],ax
-
- ; set the number of sectors per directory
-
- mov al,byte ptr [si+bx+6]
- mov byte ptr [sectors_directory],al
-
- ; set the number of sectors per cluster
-
- mov al,byte ptr [si+bx+7]
- mov byte ptr [sectors_cluster],al
-
- ; set the number of sectors per FAT
-
- mov ax,word ptr [si+bx+8]
- mov word ptr [sectors_fat],ax
-
- ; set the total number of sectors per disk
-
- xor dx,dx
- xor ah,ah
- mov al,byte ptr [max_track]
- inc ax
- mul word ptr [sectors_track]
- xor bh,bh
- mov bl,byte ptr [heads]
- mul bx
- mov word ptr [small_total],ax
-
- ; calculate the location of the first directory sector
-
- xor dx,dx
- xor ah,ah
- mov al,byte ptr [fats]
- mul word ptr [sectors_fat]
- add ax,word ptr [hidden_sectors]
- adc dx,word ptr [hidden_sectors+2]
- add ax,word ptr [reserved_sectors]
- adc dx,0
-
- ; store directory start sector (absolute sector number)
-
- mov word ptr [dir_start],ax
- mov word ptr [dir_start+2],dx
-
- ; calculate the location of the first data sector
-
- xor bh,bh
- mov bl,byte ptr [sectors_directory]
- add ax,bx
- adc dx,0
-
- ; store data start sector (absolute sector number)
-
- mov word ptr [data_start],ax
- mov word ptr [data_start+2],dx
-
- pop si
-
- ;***********************************************************************
-
- ; reset the disk controller
-
- ;***********************************************************************
-
- reset:
- mov byte ptr [retry_count],3
- reset_retry:
- xor ah,ah
- mov dl,byte ptr [drive_number]
-
- int 13h
-
- jnc short set_drive
-
- dec byte ptr [retry_count]
-
- jnz reset_retry
-
- mov dx,offset reset_error
-
- jmp write_error
-
- ;***********************************************************************
-
- ; set the drive type for format
-
- ;***********************************************************************
-
- set_drive:
- mov byte ptr [retry_count],3
- drive_retry:
- mov al,byte ptr [drive_type]
- cmp al,3
-
- jl five_inch
-
- mov al,4
-
- jmp short set_type
- five_inch:
- cmp al,2
-
- jne low_density
-
- cmp byte ptr [disk_size],1
-
- jg high_density
-
- mov al,2
-
- jmp short set_type
- high_density:
- mov al,3
-
- jmp short set_type
- low_density:
- mov al,1
- set_type:
- mov ah,17h
-
- int 13h
-
- jnc short set_disk
-
- cmp ah,80h
-
- jne floppy_exists
-
- mov dx,offset no_floppy_error
-
- jmp write_error
- floppy_exists:
- dec byte ptr [retry_count]
-
- jnz drive_retry
-
- mov dx,offset set_drive_error
-
- jmp write_error
-
- ;***********************************************************************
-
- ; set the disk type for format
-
- ;***********************************************************************
-
- set_disk:
- mov byte ptr [retry_count],3
- disk_retry:
- push es
- push di
- mov ah,18h
- mov ch,byte ptr [max_track]
- mov cl,byte ptr [sectors_track]
- mov dl,byte ptr [drive_number]
-
- int 13h
-
- pop di
- pop es
-
- jnc format_disk
-
- dec byte ptr [retry_count]
-
- jnz disk_retry
-
- mov dx,offset set_disk_error
-
- jmp write_error
-
- ;***********************************************************************
-
- ; format the disk
-
- ;***********************************************************************
-
- format_disk:
- ; set up the loop counter
-
- xor ch,ch
- mov cl,byte ptr [max_track]
- inc cx
- format_loop:
- push cx
-
- call format_track
-
- jnc continue
-
- pop cx
-
- jmp write_error
- continue:
- call next_track
-
- pop cx
-
- loop format_loop
-
- ;***********************************************************************
-
- ; set up the volume serial number in the boot record
-
- ;***********************************************************************
-
- serial_number:
- ; get the time
-
- mov ah,2ch
-
- int 21h
-
- ; fiddle the serial number bytes (similar to DOS 4.0)
- ;
- ; I don't know why IBM does this. It may be done to
- ; hide the fact that the serial number is derived
- ; from the system clock.
- ;
- ; I am not sure that the numbers that I have chosen are
- ; the same as IBM's, but they are close.
- ;
- ; a more reasonable approach might be to simply add one
- ; to each byte to avoid zero bytes in the serial number
-
- add cx,07c7h
- add dx,0707h
-
- ; store the serial number in the boot record
-
- mov word ptr [sn_low],cx
- mov word ptr [sn_high],dx
-
- ;***********************************************************************
-
- ; write the boot record and FAT1
-
- ;***********************************************************************
-
- write_boot:
- mov dx,offset boot_message
- mov ah,09h
-
- int 21h
-
- mov byte ptr [retry_count],3
- boot_retry:
- mov ax,0302h
- mov bx,offset boot_record
- mov cx,0001h
- xor dh,dh
- mov dl,byte ptr [drive_number]
-
- int 13h
-
- jnc short finish_fat1
-
- dec byte ptr [retry_count]
-
- jnz boot_retry
-
- mov dx,offset write_boot_error
-
- jmp write_error
- finish_fat1:
- mov dx,offset fat_message
- mov ah,09h
-
- int 21h
-
- ; set the starting sector (absolute)
-
- mov ax,2
- xor dx,dx
-
- ; set the number of sectors to write
-
- mov cx,word ptr [sectors_fat]
- dec cx
- fat1:
- push ax
- push cx
- push dx
-
- call write_ths
-
- jnc fat1_ths_ok
-
- pop ax
- pop ax
- pop ax
-
- mov dx,offset write_fat_error
-
- jmp write_error
- fat1_ths_ok:
- mov bx,offset fat_dir_record
- mov byte ptr [retry_count],3
- fat1_retry:
- call write_disk
-
- jnc fat1_write_ok
-
- dec byte ptr [retry_count]
-
- jnz fat1_retry
-
- pop ax
- pop ax
- pop ax
-
- mov dx,offset write_fat_error
-
- jmp write_error
- fat1_write_ok:
- pop dx
- pop cx
- pop ax
-
- ; increment the absolute sector number
-
- add ax,1
- adc dx,0
-
- loop fat1
-
- jnc write_fat
-
- mov dx,offset write_fat_error
-
- jmp write_error
-
- ;***********************************************************************
-
- ; write FAT2
-
- ;***********************************************************************
-
- write_fat:
- mov byte ptr [retry_count],3
- fat_retry:
- mov ax,0301h
- mov bx,offset fat_record
- xor ch,ch
- mov cl,byte ptr [sectors_fat]
- add cl,2
- xor dh,dh
- mov dl,byte ptr [drive_number]
-
- int 13h
-
- jnc finish_fat2
-
- dec byte ptr [retry_count]
-
- jnz fat_retry
-
- mov dx,offset write_fat_error
-
- jmp write_error
- finish_fat2:
- ; set the starting sector (absolute)
-
- mov ax,2
- xor dx,dx
- add ax,word ptr [sectors_fat]
- adc dx,0
-
- ; set the number of sectors to write
-
- mov cx,word ptr [sectors_fat]
- dec cx
- fat2:
- push ax
- push cx
- push dx
-
- call write_ths
-
- jnc fat2_ths_ok
-
- pop ax
- pop ax
- pop ax
-
- mov dx,offset write_fat_error
-
- jmp write_error
- fat2_ths_ok:
- mov bx,offset fat_dir_record
- mov byte ptr [retry_count],3
- fat2_retry:
- call write_disk
-
- jnc fat2_write_ok
-
- dec byte ptr [retry_count]
-
- jnz fat2_retry
-
- pop ax
- pop ax
- pop ax
-
- mov dx,offset write_fat_error
-
- jmp short write_error
- fat2_write_ok:
- pop dx
- pop cx
- pop ax
-
- ; increment the absolute sector number
-
- add ax,1
- adc dx,0
-
- loop fat2
-
- jnc write_dir
-
- mov dx,offset write_fat_error
-
- jmp short write_error
-
- ;***********************************************************************
-
- ; write the directory
-
- ;***********************************************************************
-
- write_dir:
- mov dx,offset dir_message
- mov ah,09h
-
- int 21h
-
- ; set the starting sector (absolute)
-
- xor dx,dx
- mov ax,word ptr [sectors_fat]
- mul byte ptr [fats]
- add ax,word ptr [reserved_sectors]
- adc dx,0
-
- ; set the number of sectors to write
-
- xor ch,ch
- mov cl,byte ptr [sectors_directory]
- dir:
- push ax
- push cx
- push dx
-
- call write_ths
-
- jnc dir_ths_ok
-
- pop ax
- pop ax
- pop ax
-
- mov dx,offset write_dir_error
-
- jmp short write_error
- dir_ths_ok:
- mov bx,offset fat_dir_record
- mov byte ptr [retry_count],3
- dir_retry:
- call write_disk
-
- jnc dir_write_ok
-
- dec byte ptr [retry_count]
-
- jnz dir_retry
-
- pop ax
- pop ax
- pop ax
-
- mov dx,offset write_dir_error
-
- jmp short write_error
- dir_write_ok:
- pop dx
- pop cx
- pop ax
-
- ; increment the absolute sector number
-
- add ax,1
- adc dx,0
-
- loop dir
-
- jnc transfer
-
- mov dx,offset write_dir_error
-
- jmp short write_error
- transfer:
- cmp byte ptr [system],1
-
- jne exit
-
- ; transfer the system files
-
- call load_system
-
- jnc exit
-
- ; set exit code to 5 (error copying system files)
-
- mov ax,4c05h
- push ax
-
- jmp short error_exit
- write_error:
- mov ah,09h
-
- int 21h
-
- ; set exit code to 1 (format, verify, or write error)
-
- mov ax,4c01h
- push ax
-
- jmp short error_exit
-
- ;***********************************************************************
-
- ; clean up and exit
-
- ;***********************************************************************
-
- exit:
- ; set exit code to 0 (Success)
-
- mov ax,4c00h
- push ax
- error_exit:
- ; restore the original disk parameter table pointer
-
- mov cx,word ptr [parameter_pointer]
- mov dx,word ptr [parameter_pointer+2]
- push ds
- xor ax,ax
- mov ds,ax
-
- assume ds:0000h
-
- cli
- mov word ptr ds:[0078h],cx
- mov word ptr ds:[007ah],dx
- sti
- pop ds
-
- assume ds:cseg
-
- ; park the heads on track 0
-
- mov ah,0ch
- xor cl,cl
- xor dh,dh
- mov dl,byte ptr [drive_number]
-
- int 13h
-
- pop ax
- push ax
- cmp al,0
-
- jne error_out
-
- ; display format complete message
-
- mov dx,offset exit_message
- mov ah,09h
-
- int 21h
- error_out:
- ; restore the cursor
-
- mov cx,word ptr [cursor]
- mov ah,01h
-
- int 10h
-
- ; terminate with exit code (0 = Success, else = Failure)
-
- pop ax
-
- int 21h
-
- ;***********************************************************************
-
- ; format subroutines
-
- ;***********************************************************************
-
- ;***********************************************************************
-
- ; information display during format
-
- ;***********************************************************************
-
- display_format:
- xor ah,ah
- aam
- or ax,3030h
- mov byte ptr [format_track_number+1],al
- cmp ah,30h
-
- jne format_digit
-
- mov ah,20h
- format_digit:
- mov byte ptr [format_track_number],ah
- mov al,bl
- xor ah,ah
- aam
- or ax,3030h
- mov byte ptr [format_head_number],al
- mov dx,offset format_display
- mov ah,09h
-
- int 21h
-
- ret
-
- ;***********************************************************************
-
- ; information display during verification
-
- ;***********************************************************************
-
- display_verify:
- xor ah,ah
- aam
- or ax,3030h
- mov byte ptr [verify_track_number+1],al
- cmp ah,30h
-
- jne verify_digit
-
- mov ah,20h
- verify_digit:
- mov byte ptr [verify_track_number],ah
- mov al,bl
- xor ah,ah
- aam
- or ax,3030h
- mov byte ptr [verify_head_number],al
- mov dx,offset verify_display
- mov ah,09h
-
- int 21h
-
- ret
-
- ;***********************************************************************
-
- ; increment the track number in the sector tables
-
- ;***********************************************************************
-
- next_track:
- xor ch,ch
- mov cl,36
- mov bx,offset sector_table_0
- track_counter:
- inc byte ptr [bx]
- add bx,4
-
- loop track_counter
-
- ret
-
- ;***********************************************************************
-
- ; format (and possibly verify) both heads on one track
-
- ;***********************************************************************
-
- format_track:
- mov al,byte ptr [sector_table_0]
- mov bl,0
-
- ; display formatting message
-
- call display_format
-
- mov byte ptr [retry_count],3
- head_0_retry:
- mov ah,5
- mov al,byte ptr [sectors_track]
- mov bx,offset sector_table_0
- mov ch,byte ptr [bx]
- mov cl,byte ptr [bx+2]
- mov dh,byte ptr [bx+1]
- mov dl,byte ptr [drive_number]
-
- int 13h
-
- jnc short head_0_ok
-
- cmp ah,80h
-
- jne no_timeout
-
- mov dx,offset no_floppy_error
- stc
- ret
- no_timeout:
- cmp ah,03h
-
- jne not_protected
-
- mov dx,offset write_protect_error
- stc
- ret
- not_protected:
- dec byte ptr [retry_count]
-
- jnz head_0_retry
-
- mov dx,offset error_during_format
- stc
- ret
- head_0_ok:
- cmp byte ptr [verify],1
-
- je verify_head_0
-
- ; check for proper floppy type
- ;
- ; this is done via a verification of tracks 0,
- ; 59, and 79, for head 0 only, for all 1.2 Mb disks
- ; not being verified, and on track 0 head 0 only, for
- ; 360 Kb, 720 Kb and 1.44 Mb disks not being verified.
- ;
- ; the following combinations will fail at track 0:
- ;
- ; 1: trying to format a 1.2 Mb floppy to 360 Kb
- ; 2: trying to format a 720 Kb floppy to 1.44 Mb *
- ; 3: trying to format a 1.44 Mb floppy to 720 Kb * !
- ;
- ; the following combination will fail at track 79:
- ;
- ; 1: trying to format a 360 Kb floppy to 1.2 Mb (it will
- ; probably fail sooner, but it is sure to here)
- ;
- ; notes:
- ;
- ; * - these combinations may not fail if the drive-
- ; controller combination does not properly detect
- ; the the floppy type.
- ;
- ; ! - this combination may not fail in 720 Kb drives.
- ;
- ; While certain non-standard combinations may not fail,
- ; either the data on the disk may be at risk, or your
- ; pocketbook may suffer, if you insist on using them.
-
- cmp byte ptr [sector_table_0],0
-
- je verify_type
-
- cmp byte ptr [disk_size],2
-
- je one_point_two
-
- jmp short format_head_1
- one_point_two:
- cmp byte ptr [sector_table_0],59
-
- je verify_type
-
- cmp byte ptr [sector_table_0],79
-
- je verify_type
-
- jmp short format_head_1
- verify_type:
- mov ah,04h
-
- int 13h
-
- jnc format_head_1
-
- mov dx,offset disk_type_error
- stc
- ret
- verify_head_0:
- pushf
- pusha
- mov al,byte ptr [sector_table_0]
- mov bl,0
-
- ; display verifying message
-
- call display_verify
-
- popa
- popf
- mov ah,04h
-
- int 13h
-
- jnc format_head_1
-
- mov dx,offset verify_error
- stc
- ret
- format_head_1:
- pushf
- pusha
- mov al,byte ptr [sector_table_0]
- mov bl,1
-
- ; display formatting message
-
- call display_format
-
- popa
- popf
- mov byte ptr [retry_count],3
- head_1_retry:
- mov ah,5
- mov al,byte ptr [sectors_track]
- mov bx,offset sector_table_1
- mov ch,byte ptr [bx]
- mov cl,byte ptr [bx+2]
- mov dh,byte ptr [bx+1]
- mov dl,byte ptr [drive_number]
-
- int 13h
-
- jnc short head_1_ok
-
- dec byte ptr [retry_count]
-
- jnz head_1_retry
-
- mov dx,offset error_during_format
- stc
- ret
- head_1_ok:
- cmp byte ptr [verify],1
-
- je verify_head_1
- format_return:
- clc
- ret
- verify_head_1:
- pushf
- pusha
- mov al,byte ptr [sector_table_0]
- mov bl,1
-
- ; display verifying message
-
- call display_verify
-
- popa
- popf
- mov ah,04h
-
- int 13h
-
- jnc format_return
-
- mov dx,offset verify_error
- stc
- ret
-
- ;***********************************************************************
-
- ; calculate the track, head, and sector for a disk write
-
- ;***********************************************************************
-
- write_ths:
- ; check for a valid absolute sector number
-
- cmp dx,word ptr [sectors_track]
-
- jb write_ths_ok
-
- stc
- ret
- write_ths_ok:
- ; calculate the sector number
-
- div word ptr [sectors_track]
- inc dl
-
- ; store the sector number
-
- mov byte ptr [write_sector],dl
-
- ; calculate the head number and the track number
-
- xor dx,dx
- div word ptr [heads]
-
- ; store the head number
-
- mov byte ptr [write_head],dl
-
- ; store the track number
-
- mov word ptr [write_track],ax
-
- clc
- ret
-
- ;***********************************************************************
-
- ; write one sector to the disk
-
- ;***********************************************************************
-
- write_disk:
- ; get the track number
-
- mov dx,word ptr [write_track]
-
- ; shift the upper 2 bits of the track number
- ; into the upper 2 bits of the sector number
-
- mov cl,06
- shl dh,cl
-
- ; get the sector number
-
- or dh,byte ptr [write_sector]
-
- mov cx,dx
- xchg ch,cl
-
- ; get the drive number
-
- mov dl,byte ptr [drive_number]
-
- ; get the head number
-
- mov dh,byte ptr [write_head]
-
- ; write one sector to the disk
-
- mov ax,0301h
-
- int 13h
-
- ret
-
- ;***********************************************************************
-
- ; transfer system files
-
- ;***********************************************************************
-
- bios_source_path:
-
- db "d:\"
-
- bios_source_filename:
-
- db "IBMBIO.COM",000h,008h
- db "$"
-
- bios_destination_path:
-
- db "d:\"
-
- bios_destination_filename:
-
- db "IBMBIO.COM",000h,008h
- db "$"
-
- dos_source_path:
-
- db "d:\"
-
- dos_source_filename:
-
- db "IBMDOS.COM",000h,008h
- db "$"
-
- dos_destination_path:
-
- db "d:\"
-
- dos_destination_filename:
-
- db "IBMDOS.COM",000h,008h
- db "$"
-
- cmd_source_path:
-
- db "d:\"
-
- cmd_source_filename:
-
- db "COMMAND.COM",000h,008h
- db "$"
-
- cmd_destination_path:
-
- db "d:\"
-
- cmd_destination_filename:
-
- db "COMMAND.COM",000h,008h
- db "$"
-
- load_system:
- mov dx,offset file_copy_message
- mov ah,09h
-
- int 21h
-
- ; get default drive
-
- mov ah,19h
-
- int 21h
-
- ; set source drive
-
- add al,41h
- mov byte ptr [bios_source_path],al
- mov byte ptr [dos_source_path],al
- mov byte ptr [cmd_source_path],al
-
- ; set destination drive
-
- mov al,byte ptr [drive_number]
- add al,41h
- mov byte ptr [bios_destination_path],al
- mov byte ptr [dos_destination_path],al
- mov byte ptr [cmd_destination_path],al
-
- ; copy IBMBIOS.COM
-
- mov bx,offset file_buffer
- mov cx,word ptr [buffer_size]
- mov si,offset bios_source_path
- mov di,offset bios_destination_path
-
- call file_copy
-
- jc load_error
-
- ; copy IBMDOS.COM
-
- mov bx,offset file_buffer
- mov cx,word ptr [buffer_size]
- mov si,offset dos_source_path
- mov di,offset dos_destination_path
-
- call file_copy
-
- jc load_error
-
- ; copy COMMAND.COM
-
- mov bx,offset file_buffer
- mov cx,word ptr [buffer_size]
- mov si,offset cmd_source_path
- mov di,offset cmd_destination_path
-
- call file_copy
-
- jc load_error
-
- clc
- ret
- load_error:
- stc
- ret
-
- ;***********************************************************************
-
- ; copy a file
- ;
- ; input:
- ;
- ; bx = pointer to copy buffer
- ; cx = copy buffer size in bytes
- ; si = pointer to source path\filename
- ; di = pointer to destination path\filename
-
- ;***********************************************************************
-
- source: dw ?
- destination: dw ?
- read_handle: dw ?
- write_handle: dw ?
- file_time: dw ?
- file_date dw ?
- file_attr: dw ?
- bytes_read: dw ?
- copy_buffer_size: dw ?
- copy_buffer: dw ?
-
- ; file copy messages
-
- file_not_found:
-
- db " - error opening input file",00Dh,00Ah
- db "$"
-
- file_create_error:
-
- db " - error creating output file",00Dh,00Ah
- db "$"
-
- file_read_error:
-
- db " - error reading file",00Dh,00Ah
- db "$"
-
- file_write_error:
-
- db " - error writing file",00Dh,00Ah
- db "$"
-
- file_copy:
- mov word ptr [copy_buffer],bx
- mov word ptr [copy_buffer_size],cx
- mov word ptr [source],si
- mov word ptr [destination],di
- mov dx,word ptr [source]
- mov ah,3dh
- xor al,al
-
- int 21h ; open source file
-
- mov word ptr [read_handle],ax
-
- jnc file_open
-
- ; display file not found message
-
- mov dx,offset cr_lf
-
- call write_message
-
- mov dx,word ptr [source]
-
- call write_message
-
- mov dx,offset file_not_found
-
- call write_message
-
- jmp load_error
- file_open:
- mov ax,5700h
- mov bx,word ptr [read_handle]
-
- int 21h ; get file time and date
-
- mov word ptr [file_time],cx
- mov word ptr [file_date],dx
- mov ax,4300h
- mov dx,word ptr [source]
-
- int 21h ; get file attributes
-
- mov word ptr [file_attr],cx
- mov al,byte ptr [drive_number]
- mov cx,0000h
- mov dx,word ptr [destination]
- mov ah,3ch
-
- int 21h ; create destination file
-
- mov word ptr [write_handle],ax
-
- jnc copy_cmd
-
- ; display file not created message
-
- mov dx,offset cr_lf
-
- call write_message
-
- mov dx,word ptr [destination]
-
- call write_message
-
- mov dx,offset file_create_error
-
- call write_message
-
- jmp copy_error
- copy_cmd:
- call read_file
-
- jnc file_read_ok
-
- ; display file read error message
-
- mov dx,offset cr_lf
-
- call write_message
-
- mov dx,word ptr [source]
-
- call write_message
-
- mov dx,offset file_read_error
-
- call write_message
-
- jmp copy_error
- file_read_ok:
- call write_file
-
- jnc file_write_ok
-
- ; display file write error message
-
- mov dx,offset cr_lf
-
- call write_message
-
- mov dx,word ptr [destination]
-
- call write_message
-
- mov dx,offset file_write_error
-
- call write_message
-
- jmp copy_error
- file_write_ok:
- cmp ax,word ptr [copy_buffer_size]
-
- je copy_cmd
-
- mov bx,word ptr [read_handle]
- mov ah,3eh
-
- int 21h ; close read_file
-
- mov ax,5701h
- mov bx,word ptr [write_handle]
- mov cx,word ptr [file_time]
- mov dx,word ptr [file_date]
-
- int 21h ; set file time and date
-
- mov bx,word ptr [write_handle]
- mov ah,3eh
-
- int 21h ; close write_file
-
- mov ax,4301h
- mov cx,word ptr [file_attr]
- mov dx,word ptr [destination]
-
- int 21h ; set file attributes
-
- clc
- ret
- copy_error:
- stc
- ret
-
- ;***********************************************************************
-
- ; issue a file copy error message
-
- ;***********************************************************************
-
- write_message:
- mov ah,09h
-
- int 21h
-
- ret
-
- ;***********************************************************************
-
- ; read file block into buffer
-
- ;***********************************************************************
-
- read_file:
- mov cx,word ptr [copy_buffer_size]
- mov bx,word ptr [read_handle]
- mov dx,word ptr [copy_buffer]
- mov ah,3fh
-
- int 21h
-
- mov word ptr [bytes_read],ax
- mov cx,ax
- ret
-
- ;***********************************************************************
-
- ; write file block from buffer
-
- ;***********************************************************************
-
- write_file:
- mov bx,word ptr [write_handle]
- mov dx,word ptr [copy_buffer]
- mov ah,40h
-
- int 21h
-
- ret
-
- ;***********************************************************************
-
- ; boot sector data (track 0, head 0, sector 1)
-
- ;***********************************************************************
-
- boot_record:
-
- ;***********************************************************************
-
- .8086 ; enable the 8086 instruction set
-
- ;***********************************************************************
-
- jmp boot_strap ; skip over data areas
-
- ;***********************************************************************
-
- ; DOS data area
-
- ;***********************************************************************
-
- oem_name: db "FMT 1.00"
- bytes_sector: dw 512
- sectors_cluster: db ? ; filled in before writing boot
- reserved_sectors: dw 1
- fats: db 2
- directory_size: dw ? ; filled in before writing boot
- small_total: dw ? ; filled in before writing boot
- descriptor: db ? ; filled in before writing boot
- sectors_fat: dw ? ; filled in before writing boot
- sectors_track: dw ? ; filled in before writing boot
- heads: dw 2
- hidden_sectors: dd 0
- big_total: dd 0
- physical_drive: db 0
- reserved: db 0
- extended_boot: db 029h
- sn_low: dw ? ; filled in before writing boot
- sn_high: dw ? ; filled in before writing boot
- volume_label: db "NO NAME "
- fat_type: db "FAT12 "
-
- ;***********************************************************************
-
- ; bootstrap program data area
-
- ;***********************************************************************
-
- sectors_directory: db ? ; filled in before writing boot
- dir_start: dd ? ; filled in before writing boot
- data_start: dd ? ; filled in before writing boot
- track: dw ? ; boot program variable
- head: db ? ; boot program variable
- sector: db ? ; boot program variable
- disk_table: db 11 dup (?) ; filled in before writing boot
-
- bios_name: db "IBMBIO COM"
-
- dos_name: db "IBMDOS COM"
-
- ; boot program messages
- reset_message:
- db 00Dh,00Ah,00Ah
- db "Disk controller error ..."
- db 000h
-
- system_message:
- db 00Dh,00Ah,00Ah
- db "No system on disk or disk read error ..."
- db 000h
-
- retry_message:
- db 00Dh,00Ah,00Ah
- db "Press any key to retry boot."
- db 000h
-
- ;***********************************************************************
-
- boot_strap:
- ; temporarily disable interrupts
-
- cli
-
- ; set the stack segment and the extra segment to 0000
- ; DOS loads the boot record at 0000:7c00,
- ; so put the stack just below it
-
- xor ax,ax
- mov es,ax
- mov ss,ax
- mov sp,7c00h
-
- assume es:0000h,ss:0000h
-
- ; set up the parameters used by the BIOS program loader
-
- lds si,es:[0078h]
- mov bx,0078h
-
- ; save current disk parameter table
-
- push ds
- push si
- push ss
- push bx
-
- ; set the data segment to 0000
-
- mov ds,ax
-
- assume ds:0000h
-
- ; use the disk parameter table in the floppy boot record
-
- mov word ptr [bx],7c00h+disk_table-boot_record
- mov word ptr [bx+02],ax
-
- ; enable interrupts
-
- sti
-
- ; reset the disk controller
-
- int 13h
-
- jnc reset_ok
-
- ; display reset error message
-
- mov si,7c00h+offset reset_message-offset boot_record
-
- call write_string
-
- jmp not_bootable
- reset_ok:
- ; get directory start sector (absolute sector number)
-
- mov ax,word ptr ds:[7c00h+dir_start-boot_record]
- mov dx,word ptr ds:[7c00h+dir_start-boot_record+2]
-
- ; get track, head, and sector
-
- call calculate_ths
-
- jnc dir_sector_ok
-
- ; display system error message
-
- mov si,7c00h+offset system_message-offset boot_record
-
- call write_string
-
- jmp not_bootable
- dir_sector_ok:
- ; set the offset of the disk read buffer
-
- mov bx,0500h
-
- ; read the first directory sector
-
- call read_disk
-
- jc not_bootable
-
- ; check directory for the BIOS file
- ; (it must be the first directory entry)
-
- mov di,bx
- mov cx,11
- mov si,7c00h+offset bios_name-offset boot_record
-
- rep cmpsb
-
- jz dir_read_ok
-
- ; display system error message
-
- mov si,7c00h+offset system_message-offset boot_record
-
- call write_string
-
- jmp not_bootable
- dir_read_ok:
- ; check directory for the DOS file
- ; (it must be the second directory entry)
-
- lea di,[bx+32]
- mov si,7c00h+offset dos_name-offset boot_record
- mov cx,11
-
- rep cmpsb
-
- ; valid directory, attempt to boot from the disk
-
- jz system_found
-
- ; display system error message
-
- mov si,7c00h+offset system_message-offset boot_record
-
- call write_string
-
- jmp not_bootable
-
- ;***********************************************************************
-
- system_found:
- ; get the data start sector (absolute sector number)
-
- mov ax,word ptr ds:[7c00h+data_start-boot_record]
- mov dx,word ptr ds:[7c00h+data_start-boot_record+2]
-
- ; set the offset of the disk read buffer
-
- mov bx,0700h
-
- ; read 3 sectors (the length of the BIOS program loader)
-
- mov cx,3
- read_next:
- push ax
- push cx
- push dx
-
- ; get track, head, and sector
-
- call calculate_ths
-
- jnb ok_to_read
-
- ; clean up the stack
-
- pop ax
- pop ax
- pop ax
-
- ; display system error message
-
- mov si,7c00h+offset system_message-offset boot_record
-
- call write_string
-
- jmp not_bootable
- ok_to_read:
- call read_disk
-
- pop dx
- pop cx
- pop ax
-
- jnc disk_read_ok
-
- ; display system error message
-
- mov si,7c00h+offset system_message-offset boot_record
-
- call write_string
-
- jmp not_bootable
- disk_read_ok:
- ; increment the sector to read
-
- add ax,1
- adc dx,0
-
- ; bump the offset of the read buffer by the sector size
-
- add bx,word ptr ds:[7c00h+bytes_sector-boot_record]
-
- loop read_next
-
- ; set up the parameters for the BIOS program loader
-
- ; get the media descriptor
-
- mov ch,byte ptr ds:[7c00h+descriptor-boot_record]
-
- ; get the drive number
-
- mov dl,byte ptr ds:[7c00h+physical_drive-boot_record]
-
- ; get the data start sector (absolute sector number)
-
- mov ax,word ptr ds:[7c00h+data_start-boot_record+2]
- mov bx,word ptr ds:[7c00h+data_start-boot_record]
-
- ; execute the BIOS program loader
-
- jmp far ptr program_loader
-
- ;***********************************************************************
-
- not_bootable:
- ; display retry message
-
- mov si,7c00h+offset retry_message-offset boot_record
-
- call write_string
-
- ; wait for a key to be pressed
-
- xor ah,ah
-
- int 16h
-
- ; clean up the stack
-
- pop si
- pop ds
- pop [si]
- pop [si+2]
-
- ; try to boot the system again
-
- int 19h
-
- ;***********************************************************************
-
- ; bootstrap subroutines
-
- ;***********************************************************************
-
- write_string:
- ; get one character
-
- lodsb
-
- ; check for end of ASCIIZ string
-
- or al,al
-
- jnz next_char
-
- ret
- next_char:
- ; write one character to the screen
-
- mov ah,0eh
-
- ; use video page 0, normal white
-
- mov bx,0007h
-
- int 10h
-
- jmp write_string
-
- ;***********************************************************************
-
- read_disk:
- ; get the track number
-
- mov dx,word ptr ds:[7c00h+track-boot_record]
-
- ; shift the upper 2 bits of the track number
- ; into the upper 2 bits of the sector number
-
- mov cl,06
- shl dh,cl
-
- ; get the sector number
-
- or dh,byte ptr ds:[7c00h+sector-boot_record]
-
- mov cx,dx
- xchg ch,cl
-
- ; get the drive number
-
- mov dl,byte ptr ds:[7c00h+physical_drive-boot_record]
-
- ; get the head number
-
- mov dh,byte ptr ds:[7c00h+head-boot_record]
-
- ; read one sector from the disk
-
- mov ax,0201h
-
- int 13h
-
- ret
-
- ;***********************************************************************
-
- calculate_ths:
- ; check for valid absolute sector number
-
- cmp dx,word ptr ds:[7c00h+sectors_track-boot_record]
-
- jb ths_ok
-
- stc
- ret
- ths_ok:
- ; calculate the sector number
-
- div word ptr ds:[7c00h+sectors_track-boot_record]
- inc dl
-
- ; store the sector number
-
- mov byte ptr ds:[7c00h+sector-boot_record],dl
-
- ; calculate the head number and the track number
-
- xor dx,dx
- div word ptr ds:[7c00h+heads-boot_record]
-
- ; store the head number
-
- mov byte ptr ds:[7c00h+head-boot_record],dl
-
- ; store the track number
-
- mov word ptr ds:[7c00h+track-boot_record],ax
-
- clc
- ret
-
- ;***********************************************************************
-
- ; adjust the boot record size to 512 bytes
-
- ;***********************************************************************
-
- fill: db (512-(offset fill-offset boot_record)-2) dup (0)
-
- ;***********************************************************************
-
- ; boot sector signature
-
- ;***********************************************************************
-
- signature: dw 0AA55h
-
- ;***********************************************************************
-
- ; end of boot sector data
-
- ;***********************************************************************
-
- ;***********************************************************************
-
- ; FAT and directory data
-
- ;***********************************************************************
-
- ; the first FAT sector has the media descriptor byte
- fat_record:
- db ? ; filled in before writing FAT
- db 0ffh,0ffh
- db 509 dup (0)
-
- ; other FAT sectors and directory sectors are all zeros
- fat_dir_record:
- db 512 dup (0)
-
- ;***********************************************************************
-
- ; copyright information
-
- ;***********************************************************************
-
- version: db "FMT version 1.00 23-JAN-1990",000h
-
- copyright: db "Copyright (C) 1990 by Clair Alan Hardesty",000h
-
- ;***********************************************************************
-
- ; put file copy buffer after code and other data
-
- ;***********************************************************************
-
- file_buffer:
- ; buffer space starts here
-
- cseg ends
-
- end entry_point
-
- ;***********************************************************************
-
- ; end of Fmt.asm
-
- ;***********************************************************************