home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- ;============================================================================
- ; MultiBoot - A program to allow PC Compatibles to have multiple
- ; boot sequences.
- ;
- ; Release history:
- ;
- ; 1.0 Initial Release PC Magazine Vol. 10, Num 4
- ; 1.1 Fixed bug in Session add code.
- ; Added better error messages to Install routine.
- ;
- ;============================================================================
- ROOT_DIR equ 2400h ;Offset in of root dir
-
- DATA_SEG1 equ 1790h ;Holds IO.SYS data on copy
- DATA_SEG2 equ 2790h ;Holds MSDOS.SYS data on copy
- FAT_SEGMENT1 equ 3790h ;Holds 1st 64K of FAT
- FAT_SEGMENT2 equ 4790h ;Holds 2nd 64K of FAT
-
- NAME_LENGTH equ 20 ;Length of session name
- DTA_OFFSET equ 80h
- SYSFILE_ATTR equ 07h ;Hidden, system, read only.
-
- NEXT_ENTRY equ offset name2 - offset name1
- AUTO_OFFSET equ offset auto1 - offset name1
- CONFIG_OFFSET equ offset config1 - offset name1
- OSTYPE_OFFSET equ offset ostype1 - offset name1
-
- NEXT_OSENTRY equ offset os_name2 - offset opsys_table
- OPSYS_TYPE equ offset os_boottype - offset opsys_table
-
- MENU_SELECTED equ offset selected - offset menu_struc
- MENU_PROMPT equ offset prompt_loc - offset menu_struc
- MENU_TIMEOUT equ offset timeout - offset menu_struc
- MENU_FIRSTITEM equ offset firstitem - offset menu_struc
-
- COLOR_NORM equ 17h ;Video attributes used for
- COLOR_HIGH equ 71h ; menus.
- BW_NORM equ 07h
- BW_HIGH equ 70h
-
- partition_ptrl equ word ptr [bp-60]
- partition_ptrh equ word ptr [bp-58]
- boot_disk equ byte ptr [bp-56]
- sectors2read equ byte ptr [bp-55]
- fat_sectorl equ word ptr [bp-54]
- fat_sectorh equ word ptr [bp-52]
- root_sectorl equ word ptr [bp-50]
- root_sectorh equ word ptr [bp-48]
- root_bytes equ word ptr [bp-46]
- data_startl equ word ptr [bp-44]
- data_starth equ word ptr [bp-42]
- read_buff equ word ptr [bp-36]
- old_choice equ word ptr [bp-34]
- bytes_per_clust equ word ptr [bp-30]
- new_io_size equ word ptr [bp-24]
- new_dos_size equ word ptr [bp-22]
- low_fat_size equ word ptr [bp-20]
- hi_fat_size equ word ptr [bp-18]
-
- bytes_per_sec equ word ptr [bp+0bh]
- sec_per_cluster equ byte ptr [bp+0dh]
- reserved_sec equ word ptr [bp+0eh]
- number_of_fats equ byte ptr [bp+10h]
- root_size equ word ptr [bp+11h]
- total_sec equ word ptr [bp+13h]
- media_des_byte equ byte ptr [bp+15h]
- sec_per_fat equ word ptr [bp+16h]
- sec_per_track equ word ptr [bp+18h]
- number_of_heads equ word ptr [bp+1ah]
- num_hidden_sec equ word ptr [bp+1ch]
- total_sec_long equ word ptr [bp+20h]
- drive_number equ word ptr [bp+24h]
- reserved equ word ptr [bp+25h]
- extended_flag equ word ptr [bp+26h]
- vol_serial equ word ptr [bp+27h]
- vol_name equ word ptr [bp+2bh]
-
- ;============================================================================
- ; MBOOT - A substitute boot record to allow PC Compatibles to have
- ; multiple boot sequences.
- ;
- ; ***********************
- ; !!!! WARNING !!!!
- ; ***********************
- ;
- ; Tampering with this source code can cause boot failures, lost data,
- ; and sad times. Be smart, just say no.
- ;
- ;============================================================================
-
- code segment
- assume cs:code
-
- org 100h
- entry: jmp main
-
- ooem_name db 8 dup (" ") ;These values will be modified
- obytes_per_sec dw ? ; by the install routine.
- osec_per_cluster db ?
- oreserved_sec dw ?
- onumber_of_fats db ?
- oroot_size dw ?
- ototal_sec dw ?
- omedia_des_byte db ?
- osec_per_fat dw ?
- osec_per_track dw ?
- onumber_of_heads dw ?
-
- onum_hidden_sec dw ? ;Added in DOS 3.x
- dw ?
- ototal_sec_long dd ? ;Added in DOS 4.x
- odrive_number db ?
- oreserved db ?
- oextended_flag db ?
- ovol_serial dd ?
- ovol_name db 11 dup (?)
- oreserved1 db 8 dup (?)
-
- ;-----------------------------------------------------------------------
- ; Start of boot code
- ;-----------------------------------------------------------------------
- bootcode proc near
- assume ds:code
- cli ;Disable interrupts
- cld ;Set direction UP.
- xor bx,bx
- mov ax,790h
- mov ss,ax ;SS:SP = 790:0
- mov sp,bx
- sti ;Interrupts OK
- mov bp,100h ;Set up BP for data addressing
- mov partition_ptrl,si ;Save partition table ptr
-
- mov ds,bx ;DS = 0
- mov es,ax ;ES = 790h
- mov di,bp ;Move boot code out of the way
- mov si,7c00h
- mov cx,256
- rep movsw
-
- push es
- mov ax,offset boot_1
- push ax
- retf
- boot_1:
- push cs
- pop ds ;DS = 790h
- mov boot_disk,dl ;Save boot_disk
-
- mov ax,bx ;BX = 0
- mov al,number_of_fats ;Compute the sector of the
- mul sec_per_fat ; root directory.
- mov cx,reserved_sec
- add cx,num_hidden_sec
- adc dx,num_hidden_sec[2]
- mov fat_sectorl,cx
- mov fat_sectorh,dx
- add cx,ax
- adc dx,bx ;BX = 0
- mov root_sectorl,cx
- mov root_sectorh,dx
- mov data_startl,cx
- mov data_starth,dx
- push dx
-
- mov ax,32 ;Get length of dir entry
- mul root_size ;Compute the size -in sectors-
- mov si,bytes_per_sec ; of the Root Directory.
- add ax,si
- dec ax
- div si
- add data_startl,ax
- adc data_starth,bx
- mov root_bytes,ax ;Save size of root dir
-
- xchg ax,cx
- pop dx
- mov bx,ROOT_DIR
- call read_disk
- jc boot_error
-
- mov si,offset mboot_name
- call load_and_boot
- call print_line ;Print lost MBOOT.SYS msg
-
- mov si,offset lastboot_name ;If fail, try old boot record
- call load_and_boot
- boot_error:
- push si
- mov si,offset bootfail_msg
- call print_line
- pop si
- call print_line
-
- boot_halt: jmp short boot_halt
- bootcode endp
-
- ;-----------------------------------------------------------------------
- ; Read disk / Write Disk
- ; Entry: DX,AX - Absolute sector to read/write
- ; BX - address of buffer.
- ; CL - Number of sectors to read
- ; Exit: CF - Clear if read successful.
- ;-----------------------------------------------------------------------
- write_disk proc near
- mov ch,3 ;BIOS write disk
- jmp short read_0
- write_disk endp
-
- read_disk proc near
- mov ch,2 ;BIOS read disk
- read_0:
- push di
- mov sectors2read,cl ;Save number of sectors to read
- mov si,ax ;Save starting sector to read
- mov di,dx
- mov read_buff,bx
- read_1:
- ;Compute the Cylinder, Head, and Sector to read.
- mov ax,si ;Get logical sector
- mov dx,di
- mov bx,sec_per_track ;Get sectors per track
- div bx
- inc dx
-
- inc bx
- cmp cl,4 ;Never read more than 4
- jb read_2 ; sectors
- mov cl,4
- read_2:
- push dx
- add dl,cl ;Prevent a disk read across
- cmp dx,bx ; a track boundry.
- pop dx
- jbe read_21
- dec cl
- jmp short read_2
- read_21:
- mov bx,dx ;Save sector
- push cx ;Save sectors to read
-
- cwd
- div number_of_heads ;Compute head and cylinder
- xchg ah,al ;Swap cyl low and high bytes
- mov cl,6
- shl al,cl ;Shift high cyl bits
- xchg cx,ax ;Copy cyl into CX
- or cl,bl ;Combine cyl with sector
- mov dh,dl ;Move head number
- pop ax
- mov bh,5 ;Try to read 5 times.
- read_3:
- push bx
- push ax
- mov bx,read_buff
- mov dl,boot_disk ;Get disk to read
- push ax ;Save sectors read
- int 13h ;Read/Write disk.
- pop ax ;Get sectors read
- xor ah,ah
- jc read_4 ;Error, try again.
- pop cx ;Restore read/write cmd
- pop bx ;Restore retry count
-
- add si,ax ;Update starting sector
- adc di,0
- sub sectors2read,al ;Sub from total sectors to read
- mul bytes_per_sec ;Move read buffer pointer
- add read_buff,ax
- mov cl,sectors2read
- cmp cl,0
- ja read_1
- clc
- read_exit:
- pop di
- ret
- read_4:
- xor ax,ax ;Reset disk before reading
- int 13h
- pop ax
- pop bx
- dec bh
- jnz read_3
- mov si,offset readerr_msg
- stc
- jmp short read_exit
- read_disk endp
- ;-----------------------------------------------------------------------
- ; Find file - Searches the root directory for a filename.
- ; Entry: SI - Ptr to file name to find
- ; Exit: CF - Clear if found.
- ; DI - If CF clear, ptr to entry containing file name.
- ;-----------------------------------------------------------------------
- find_file proc near
- mov cx,root_size ;Get number of entries
- mov di,ROOT_DIR
- findfile_1:
- push cx
- push si
- push di
- mov cx,11 ;Compare names in entry
- repe cmpsb
- pop di
- pop si
- pop cx
- je findfile_2
- add di,32 ;Point to next entry
- loop findfile_1
- stc
- ret
- findfile_2:
- clc
- ret
- find_file endp
- ;-----------------------------------------------------------------------
- ; Print Line
- ; Entry: SI - Ptr to string to print.
- ;-----------------------------------------------------------------------
- print_line proc near
- lodsb
- or al,al
- je findfile_2
- mov ah,0eh
- mov bx,7
- int 10h
- jmp short print_line
- print_line endp
-
- ;-----------------------------------------------------------------------
- ; CLUSTER2SECTOR - Convert cluster number into sector number.
- ; Entry: AX - Cluster to read
- ; Exit: AX - Sector number
- ; CX - Cluster size
- ;-----------------------------------------------------------------------
- cluster2sector proc near
- dec ax ;Compensate for 1st to FAT
- dec ax ; entries not being used.
- xor cx,cx ;Compute the starting sector
- mov cl,sec_per_cluster
- mul cx ;CX, number of sectors to read
- add ax,data_startl
- adc dx,data_starth
- ret
- cluster2sector endp
-
- ;-----------------------------------------------------------------------
- ; LOAD FIRST - Reads the first cluster of a file.
- ; Entry: BX - Destination buffer
- ; DI - Ptr to directory entry
- ;-----------------------------------------------------------------------
- load_first proc near
- mov ax,[di+1ah] ;Get starting cluster
- mov di,ax ;Save starting cluster
- call cluster2sector ;Read 1st cluster.
- call read_disk
- ret
- load_first endp
-
- ;-----------------------------------------------------------------------
- ; Load and Boot
- ; Entry: SI - Ptr to file name to load and boot
- ; Exit: This routine will not return if boot file found.
- ; CF - Set if boot file not found.
- ; SI - Offset of error message.
- ;-----------------------------------------------------------------------
- load_and_boot proc near
- assume cs:code,ds:code
- call find_file ;Find filename in dir list
- jnc lab_1
- lab_error:
- mov di,offset bootfile ;Copy name of boot file
- mov cx,11 ; not found.
- rep movsb
- xor ax,ax ;Terminate string
- stosb
- mov si,offset mbootlost_msg
- ret
- lab_1:
- mov bx,300h ;Offset to load extended boot
- call load_first ;Read first cluster of file
- jc lab_error
-
- pop ax ;Remove local return address
-
- mov dl,boot_disk
- mov si,partition_ptrl
- xor ax,ax ;Set up expected segment config
- push ax
- mov ah,7ch
- push ax
- retf
- load_and_boot endp
-
- ;-----------------------------------------------------------------------
- ; Data used by the Boot record.
- ;-----------------------------------------------------------------------
- mboot_name db "MBOOT SYS"
- lastboot_name db "LASTBOOTBIN"
- bootfail_msg db "Boot Failure",13,10,0
- readerr_msg db "Disk Error",0
- mbootlost_msg db "Can",27h,"t find file "
- bootfile = $
- org 2FEh
- dw 0aa55h ;Boot record flag
-
- ;============================================================================
- ;============================================================================
- ; This part of Multiboot is loaded by the boot record.
- ;============================================================================
- ;============================================================================
- boot_extend_start = $
- jmp boot_extend
- org 303h
- boot_ptr_array = $
- boot_data_ptr dw offset boot_data1 - offset boot_extend_start
- boot_data_size dw offset boot_data1_end - offset boot_data1
- boot_sess_ptr dw offset boot_array - offset boot_extend_start
- boot_sess_size dw offset boot_array_end - offset boot_array
- boot_ostab_ptr dw offset opsys_table - offset boot_extend_start
- boot_ostab_size dw offset opsys_table_end - offset opsys_table
- boot_version dw 05h
-
- boot_data1 = $
- last_choice dw 1 ;Boot session currently active
- last_opsys db 1 ;Last operating system booted.
- last_DOS db 1 ;Last DOS version booted
-
- boot_default db 0 ;Default boot session
- boot_timeout dw 0 ;Time until default
- opsys_clusters dw 0 ;Size of original op sys files
- time_stamp dd 0 ;Time stamp to verify disk.
- boot_data1_end = $
-
- fat_seg_low dw FAT_SEGMENT1
- fat_seg_high dw FAT_SEGMENT2
- fat_mask dw 0
- fat_size dw 0
- load_error db "Boot extend load error",13,10,0
- ;-------------------------------------------------------------------------
- ; GET FATTYPE - Determines if the FAT is 12 bit or 16 bit.
- ; Entry: BP - Pointer to boot data structure.
- ; Exit: fat_mask initialized
- ;-------------------------------------------------------------------------
- get_fattype proc near
- mov si,0fff8h ;Assume 16 bit FAT
- xor dx,dx
- mov ax,total_sec
- or ax,ax ;If total sectors = 0, huge
- jne get_fattype_1 ; partition.
- mov ax,word ptr total_sec_long
- mov dx,word ptr total_sec_long[2]
- get_fattype_1:
- xor cx,cx ;If more than 4087 clusters,
- mov cl,sec_per_cluster ; assume 16 bit FAT.
- div cx
- cmp ax,4087
- ja get_fattype_2
- mov si,0ff8h ;Set 12 bit FAT mask
- get_fattype_2:
- mov fat_mask,si ;Save FAT mask
- mov fat_size,ax
- ret
- get_fattype endp
-
- ;-------------------------------------------------------------------------
- ; GET FAT ENTRY - Finds a FAT entry from index
- ; Entry: BP - Pointer to boot data structure.
- ; DI - Entry into FAT table
- ; Exit: DI - Next entry
- ; CF - Clear if last entry
- ;-------------------------------------------------------------------------
- get_fat_entry proc near
- push bx
- push ds
- push es
- mov dx,fat_mask ;Get FAT mask
- mov es,fat_seg_high ;Load DS and ES with segments
- mov ds,fat_seg_low ; containing the FAT table.
-
- mov bx,di ;Copy index number
- add bx,di
- mov ax,ds:[bx] ;Assume low segment of 16 bit
- jnc get_fat_entry_1 ; FAT.
- mov ax,es:[bx] ;CF set, high segment
- get_fat_entry_1:
- or dx,dx ;Test for 12 or 16 bit FAT
- js get_fat_entry_3
- mov bx,di
- shr di,1 ;12 bit FAT
- mov ax,ds:[bx+di]
- jnc get_fat_entry_2
- mov cl,4 ;If odd index, shift
- shr ax,cl
- get_fat_entry_2:
- and ah,0fh ;Clear top nibble
- get_fat_entry_3:
- mov di,ax ;Copy entry data
- cmp ax,dx ;See if last entry
- pop es
- pop ds
- pop bx
- ret
- get_fat_entry endp
-
- ;-------------------------------------------------------------------------
- ; LOAD FILE1 - Loads a file by reading the FAT table (Skips first cluster)
- ; Entry: BP - Pointer to boot data structure.
- ; ES:BX - Destination buffer
- ; DI - Entry into FAT table
- ; Exit: CF - Set if error
- ;-------------------------------------------------------------------------
- load_file1 proc near
- load_file_1:
- call get_fat_entry
- jnc load_file_exit
- push bx
- call cluster2sector ;Read next cluster
- call read_disk
- pop bx
- jc load_file_exit1
- add bx,bytes_per_clust ;Update read destination
- jmp short load_file_1
- load_file_exit:
- clc
- load_file_exit1:
- ret
- load_file1 endp
-
-
- debug_msg5 db ".",0
-
- ;====================================================================
- ; BOOT EXTEND
- ; Entry: DL - Boot Disk
- ; SI - Pointer to booted partition table entry
- ; DI - Starting cluster for this file
- ;====================================================================
- boot_extend proc near
- mov ax,790h ;Reload CS and DS.
- mov ds,ax
- mov es,ax
- push ax
- mov ax,offset extend_load_0
- push ax
- retf
- ;
- ; Since MBOOT.SYS may be larger than one cluster, the FAT table must be read
- ; and interpeted. This next section of code must reside in the first
- ; 512 bytes of MBOOT.SYS.
- ;
- extend_load_0:
- mov hi_fat_size,0
- mov ax,sec_per_fat ;Compute size of FAT
- mov cx,ax
- mul bytes_per_sec
- or dx,dx ;See if larger than 64K
- je extend_load_1 ;Compute the max number of
- mov dx,1 ; sectors in 64K.
- xor ax,ax
- div bytes_per_sec
- mov cx,ax ;Copy sectors to read
- extend_load_1:
- mov low_fat_size,cx
- mov ax,FAT_SEGMENT1
- mov es,ax
- xor bx,bx
- mov ax,fat_sectorl ;Get starting sector of FAT
- mov dx,fat_sectorh
- push cx
- call read_disk ;Read FAT
- pop cx
- jc extend_read_error
-
- mov ax,cx ;If FAT larger than 64K
- sub cx,sec_per_fat ; read remainder into second
- jbe extend_load_2 ; segment.
- mov hi_fat_size,cx
- mov bx,FAT_SEGMENT2
- mov es,bx
- xor bx,bx
- mov dx,bx
- add ax,fat_sectorl ;Get ptr to remainder of FAT
- adc dx,fat_sectorh
- call read_disk ;Read FAT
- jc extend_read_error
- extend_load_2:
- push cs ;Restore ES
- pop es
- call get_fattype ;See if 12 or 16 bit fat
- xor ax,ax
- mov al,sec_per_cluster
- mul bytes_per_sec
- mov bytes_per_clust,ax ;Save bytes per cluster
- mov bx,ax ;BX = dest for file data. Add
- add bx,300h ; size of boot rec + 100h
- call load_file1 ;Read remainder of MBOOT.SYS
- jnc extend_load_3
- extend_read_error:
- mov si,offset load_error ;Indicate load error
- jmp boot_error
- ;
- ; MBOOT.SYS fully loaded. Get on with displaying the menu.
- ;
- extend_load_3:
- mov screen_rows,25 ;Configure screen
- mov normal_attr,COLOR_NORM
- mov highlight_attr,COLOR_HIGH
- xor ax,ax
- int 11h ;Get screen type
- mov bx,0003h ;Set video mode 3
- test ax,10h ;See if color or BW
- jz boot_extend_00
- mov bx,0007h ;Set video mode 7
- mov normal_attr,BW_NORM
- mov highlight_attr,BW_HIGH
- boot_extend_00:
- mov ax,bx ;Set video mode.
- call vidint
- call write_box ;Write copyright box
- boot_extend_01:
- xor ax,ax
- mov al,boot_default ;Copy defaults
- push bp
- mov bp,offset boot_menu
- mov [bp+MENU_SELECTED],al
- cmp al,0 ;If no default, no timeout
- je extend_load_02
- mov ax,boot_timeout
- extend_load_02:
- mov [bp+MENU_TIMEOUT],ax
- call menu
- pop bp
- cmp bl,0 ;If no choice, ask again.
- je boot_extend_01
-
- call scroll_half ;Clear screen
-
- cmp bx,last_choice ;See if the choice is the same
- jne boot_extend_11 ; as last time.
- jmp boot_extend_boot ;Yes, boot with old files.
- boot_extend_11:
- push bx
- call get_entry ;Get ptr to new entry
- mov di,bx
- pop bx
- xchg last_choice,bx ;Save new choice, get last
- mov old_choice,bx ;Save in case of write error
- call get_entry ;Compute offset of old entry
-
- mov al,[di+OSTYPE_OFFSET] ;If the operating system is
- cmp al,last_opsys ; different from the last
- je boot_extend_2 ; one, read the os files.
-
- mov bl,al ;See if OS/2 or DOS op sys.
- call get_os_entry
- cmp word ptr [di+OPSYS_TYPE],100h ;If OS/2 skip file
- jae boot_extend_22 ; copying.
-
- cmp al,last_DOS ;If last DOS version same,
- je boot_extend_22 ; skip file copy.
-
- push ax ;Tell user we are changing
- push bx ; the DOS files.
- mov si,offset change_os_msg
- call write_linenorm
- pop bx
- pop ax
-
- mov last_DOS,al
- call load_os_files ;Read the DOS system files
- mov si,offset read_os_error
- jc boot_extend_write_error1
-
- call write_os_files ;Write DOS sys files to disk
- jc boot_extend_write_error1
- push ax
- xor ax,ax
- mov cx,ax
- mov cl,number_of_fats
- boot_extend_21:
- call write_fat_table ;Write updated FAT to disk
- inc ax
- loop boot_extend_21
- pop ax
- boot_extend_22:
- push ax
- mov bl,last_opsys ;Rename the boot record file
- call make_os_names ; to the name in the os table
- mov di,si
- mov si,offset lastboot_name
- call rename_file
- pop bx ;Get back the new op sys type
- mov last_opsys,bl
- call make_os_names ;Rename the new boot file to
- call rename_file ; LASTBOOT.SYS
-
- mov bx,old_choice ;Get prev session
- call get_entry ;Compute offset of old entry
- boot_extend_2:
- lea di,[bx+AUTO_OFFSET] ;Rename the current AUTOEXEC
- mov si,offset autoexec_name ; file to its old name
- call rename_file
-
- lea di,[bx+CONFIG_OFFSET] ;Rename the current CONFIG.SYS
- mov si,offset config_name ; file to its old name.
- call rename_file
-
- mov bx,last_choice ;Rename saved files to
- call get_entry ; CONFIG.SYS and AUTOEXEC.BAT
- lea si,[bx+AUTO_OFFSET] ;Start with AUTOEXEC.BAT
- mov di,offset autoexec_name
- call rename_file
-
- lea si,[bx+CONFIG_OFFSET] ;Now rename CONFIG.SYS
- mov di,offset config_name
- call rename_file
- boot_extend_3:
- mov ax,root_sectorl ;Write the Root directory back
- mov dx,root_sectorh ; to the disk.
- mov bx,ROOT_DIR
- mov cx,root_bytes ;Get size of root directory
- call write_disk
- jnc boot_extend_4 ;If write error, Boot last
- boot_extend_write_error:
- mov si,offset boot_extend_err ; boot record.
- boot_extend_write_error1:
- call write_linenorm
- mov bx,old_choice
- jmp short boot_extend_boot
- boot_extend_4:
- mov si,offset mboot_name ;Find MBOOT again in dir list
- call find_file
- jc boot_extend_write_error
- mov ax,[di+1ah] ;Get starting cluster
- mov bx,300h
- call cluster2sector ;Update the MBOOT boot table
- call write_disk
- jc boot_extend_write_error
- mov bx,last_choice
- boot_extend_boot:
- call get_entry ;Print message to identify
- push bx ; the session booting
- mov si,bx
- mov di,offset boot_sess_msg1
- mov cx,NAME_LENGTH+1
- rep movsb
- mov si,offset boot_sess_msg
- call write_linenorm
- pop bx
-
- mov bl,[bx+OSTYPE_OFFSET] ;Print message to identify
- call get_os_entry ; operating system booting.
- mov si,offset boot_os_msg1
- xchg si,di
- mov cx,9
- rep movsb
- mov si,offset boot_os_msg
- call write_linenorm
-
- mov dx,0d00h ;Row 13, Column 0
- call set_cursor
- mov si,offset lastboot_name ;Boot operating system.
- call load_and_boot
- jmp boot_halt ;If this returns, halt
- boot_extend endp
-
- ;--------------------------------------------------------------------
- ; MENU querys the user menu selection.
- ; Entry: BP - Pointer to menu structure.
- ; Exit: BX - Menu item selected.
- ;--------------------------------------------------------------------
- menu proc near
- mov last_timeout,0
- mov dx,[bp+MENU_TIMEOUT] ;Point to timeout line
- mov timeout_value,dx ;Copy timeout value
- or dx,dx ;If 0, no timeout
- je menu_wrtprompt
- mov si,offset timeout_str ;Ptr to timeout string
- call write_linenorm
-
- xor ax,ax ;Read system timer
- int 1ah
- add dx,timeout_value ;Set timeout value
- mov timeout_value,dx
- menu_wrtprompt:
- mov dx,[bp+MENU_PROMPT] ;Write menu prompt
- mov si,offset prompt_text
- call write_line_at
- key_loop:
- call write_menu ;Write menu choices
- key_loop_1:
- mov ax,timeout_value
- cmp ax,0 ;If timout not disabled, print
- jne key_1 ; time remaining.
- cmp ax,last_timeout
- je key_2
- mov last_timeout,ax
- mov si,offset timetext1
- call write_linenorm
- jmp short key_2
- key_1:
- xor ax,ax ;Read system timer
- int 1ah
- mov ax,timeout_value
- sub ax,dx ;Subtract current time
- ja key_11 ;If no time, exit with
- jmp key_quit ; carry.
- key_11:
- mov cx,18
- xor dx,dx
- div cx
- inc ax
- cmp ax,last_timeout
- je key_2
- mov last_timeout,ax
- mov dx,173ch ;Write time remaining
- call hex2asc
- mov dx,1a00h ;Hide cursor
- call set_cursor
- key_2:
- cmp no_DOS_flag,0
- je key_3
- int 28h ;Call DOS idle
- key_3:
- call get_key ;Get key from keyboard
- jz key_loop_1 ;No key available, loop
-
- cmp al,0dh ;If CR, exit.
- je key_exit
- cmp al,27 ;If ESC, quit.
- je key_quit
- cmp al,3 ;If Ctl-C, quit.
- je key_quit
-
- cmp al,31h ;If valid number jump
- jb key_down_0 ; directly to selection.
- cmp al,39h
- ja key_down_0
- sub al,30h
- call check_valid ;See if selection valid
- jc key_loop_1 ;No, get another key
- jmp short key_loop_2
- key_down_0:
- cmp al,9 ;Tab
- je key_down_1
- cmp ah,4dh ;Right
- je key_down_1
- cmp ah,50h ;Down
- jne key_up_1
- key_down_1:
- mov al,[bp+MENU_SELECTED]
- key_down_2:
- inc al
- cmp al,[bp]
- jbe key_down_3
- mov al,1
- key_down_3:
- call check_valid ;See if selection valid
- jc key_down_2
- jmp short key_loop_2
- key_up_1:
- cmp ax,0f00h ;Back Tab
- je key_up_2
- cmp ah,4bh ;Left
- je key_up_2
- cmp ah,48h ;Up
- je key_up_2
- jmp key_loop_1
- key_up_2:
- mov al,[bp+MENU_SELECTED]
- key_up_3:
- sub al,1
- ja key_loop_2
- mov al,[bp]
- key_loop_2:
- call check_valid ;See if selection valid
- jc key_up_3
- mov [bp+MENU_SELECTED],al
- mov timeout_value,0 ;Disable timeout
- jmp key_loop
- key_exit:
- clc
- key_exit1:
- mov bh,0
- mov bl,[bp+MENU_SELECTED] ;Get menu item selected
- ret
- key_quit:
- stc
- jmp short key_exit1
- menu endp
-
- ;--------------------------------------------------------------------
- ; GET KEY gets a key from the keyboard.
- ; Exit: AX - key returned
- ; ZF - Set if no key
- ;--------------------------------------------------------------------
- get_key proc near
- mov ah,1
- int 16h ;Check for key
- jz get_key_1
- mov ah,0
- int 16h ;Get key
- or ax,ax
- get_key_1:
- ret
- get_key endp
-
- ;--------------------------------------------------------------------
- ; FETCH KEY waits for and gets a key from the keyboard
- ; Exit: AX - key returned
- ;--------------------------------------------------------------------
- fetch_key proc near
- int 28h ;Call DOS idle
- call get_key ;Read a key from the keyboard
- jz fetch_key
- ret
- fetch_key endp
-
- ;--------------------------------------------------------------------
- ; CHECK VALID determines if a menu selection is valid.
- ; Entry: BP - Pointer to menu structure.
- ; AL - Menu selection
- ; Exit: CF - Clear if valid selection
- ;--------------------------------------------------------------------
- check_valid proc near
- push ax
- push di
- dec al
- cmp al,[bp] ;See if beyond choices
- ja check_valid_bad
- xor ah,ah ;Convert selection into
- shl ax,1 ; index into menu structure
- shl ax,1
- lea di,[bp+MENU_FIRSTITEM] ;Get ptr to 1st item
- add di,ax
- mov si,[di+2] ;Get location of string
- or al,[si] ;If 1st byte > 80h, disabled
- js check_valid_bad ; item.
- clc
- check_valid_exit:
- pop di
- pop ax
- ret
- check_valid_bad:
- stc
- jmp short check_valid_exit
- check_valid endp
-
- ;--------------------------------------------------------------------
- ; WRITE MENU displays the choices on the screen.
- ; Entry: BP - Pointer to menu structure.
- ;--------------------------------------------------------------------
- write_menu proc near
- xor cx,cx
- mov cl,[bp] ;Get number of choices
- xor bx,bx
- lea di,[bp+MENU_FIRSTITEM] ;Get ptr to 1st item
- write_menu_1:
- inc bh ;Inc menu item counter
-
- mov si,[di+2] ;Get location of string
- cmp byte ptr [si],80h ;If 1st byte > 80h, disabled
- jae write_menu_3 ; item, don't print.
-
- mov dx,[di] ;Get location of item
- mov al,bh ;Print menu item number
- call printnum
-
- add dl,4
- mov si,[di+2] ;Get location of string
- cmp bh,[bp+MENU_SELECTED] ;If selected, use highlight
- jne write_menu_2 ; attribute.
- call write_line_hi
- jmp short write_menu_3
- write_menu_2:
- call write_line_at
- write_menu_3:
- add di,4 ;Point to next item
- loop write_menu_1
-
- mov dx,[bp+MENU_PROMPT]
- add dl,8
- call set_cursor ;Set cursor pos
-
- mov al,[bp+MENU_SELECTED] ;Get current selection
- or al,al
- je write_menu_exit
- add al,30h
-
- mov ah,0ah ;BIOS Write Char
- mov cx,1 ;1 character
- xor bx,bx
- call vidint
- write_menu_exit:
- ret
- write_menu endp
-
- ;--------------------------------------------------------------------
- ; GETENTRY - Computes the offset of a boot array entry given the
- ; entry number
- ; Entry: BL - Entry number
- ; Exit: BX - Offset of that entry
- ;--------------------------------------------------------------------
- get_entry proc near
- mov ax,offset boot_array
- get_entry1:
- push ax ;Save start of table
- dec bx
- mov al,NEXT_ENTRY ;Multiply the size of
- mul bl ; each entry by the
- pop bx ; number then add the
- add bx,ax ; starting offset.
- ret
- get_entry endp
-
- ;--------------------------------------------------------------------
- ; GET OS ENTRY - Computes offset of entry in the op sys table.
- ; Entry: BL - Operating system number. 1 - 4
- ; Exit: DI - Pointer to entry in op sys table.
- ;--------------------------------------------------------------------
- get_os_entry proc near
- push ax
- push bx
- xor bh,bh
- dec bl
- mov al,NEXT_OSENTRY
- mul bl
- add ax,offset opsys_table
- mov di,ax
- pop bx
- pop ax
- ret
- get_os_entry endp
-
- ;--------------------------------------------------------------------
- ; LOAD_FILE - Computes offset of entry in the op sys table.
- ; Entry: ES:BX - Destination buffer
- ; DI - Ptr to directory table entry
- ; BP - Boot data ptr
- ;--------------------------------------------------------------------
- load_file proc near
- push bx
- call load_first
- pop bx
- add bx,bytes_per_clust
- call load_file1
- ret
- load_file endp
-
- ;--------------------------------------------------------------------
- ; LOAD_OS_FILES - Reads the operating system files into memory.
- ; Entry: AL - Operating system number
- ; BP - Boot data ptr
- ;--------------------------------------------------------------------
- load_os_files proc near
- push ax
- push bx
- mov bl,al
- call make_os_names ;Make op sys names
- add si,11 ;Point to IO.SYS name
- call find_file ;Find the filename
- jc load_os_files_exit
- mov cx,[di+1ch] ;Read file size
- mov new_io_size,cx
- push di
- add si,11 ;Point to MSDOS.SYS
- call find_file ;Find the filename
- mov si,di
- pop di
- jc load_os_files_exit
- mov cx,[si+1ch] ;Read file size
- mov new_dos_size,cx
-
- mov ax,DATA_SEG1
- mov es,ax
- xor bx,bx
- push si
- call load_file ;Read IO.SYS
- pop di
- jc load_os_files_exit
- mov ax,DATA_SEG2
- mov es,ax
- xor bx,bx
- call load_file ;Read MSDOS.SYS
- load_os_files_exit:
- push cs ;Restore ES
- pop es
- pop bx
- pop ax
- ret
- load_os_files endp
-
- ;--------------------------------------------------------------------
- ; WRITE_OS_FILES - Writes the operating system files onto the disk.
- ; Entry: BP - Boot data ptr
- ; AL - Operating system number
- ;--------------------------------------------------------------------
- write_os_files proc near
- push ax
- push bx
-
- mov bx,ax ;Copy os number
- call get_os_entry
- mov cx,[di+OPSYS_TYPE] ;Get os config
-
- cmp cx,50h
- je write_os_files_0
- mov ax,1 ;At least 1 cluster needed
- cmp cx,40h ; for DOS 4 type os
- jae write_os_files_02
-
- mov ax,new_io_size ;Get clusters needed for
- xor dx,dx ; files.
- div bytes_per_clust
- inc ax
- push ax ;Save clusters for IO.SYS
-
- xor ax,ax
- cmp cx,30h ;If DOS 3 type os, only IO.SYS
- jae write_os_files_01 ; size needs to be checked
- mov ax,new_dos_size
- xor dx,dx
- div bytes_per_clust
- inc ax
- write_os_files_01:
- pop dx ;Get IO.SYS clusters needed
- add ax,dx
- write_os_files_02:
- push ax ;Save clusters needed
- push bx
- call check_fat ;See if enough room for opsys
- pop bx ; files.
- pop dx
- cmp dx,cx
- mov si,offset no_room_error
- ja write_os_files_err1
- write_os_files_0:
- mov cx,new_io_size ;Get size of new IO.SYS
- add di,9 ;Point to IO.SYS name
- mov si,di ;Copy entry in op sys table
-
- mov di,ROOT_DIR ;Get ptr to root dir
- push cx
- push di
- call clear_file ;Remove IO.SYS from FAT
- add di,20h ;Point to next file
- call clear_file ;Remove MSDOS.SYS from FAT
- call clean_fat ;Remove any bad cluster flags
-
- mov ax,DATA_SEG1 ;Get seg of IO.SYS data
- mov es,ax
- mov dx,1 ;Look for 1st free cluster.
- call find_free_clust
- mov dx,di
- pop di
- pop cx
- call store_os_file ;Write IO.SYS to disk
- jc write_os_files_exit
-
- add di,20h ;Point to next dir entry
- add si,11 ;Point to MSDOS.SYS name
-
- mov cx,new_dos_size ;Get size of new MSDOS.SYS
- mov ax,DATA_SEG2 ;Get seg of MSDOS.SYS data
- mov es,ax
- call store_os_file ;Write MSDOS.SYS to disk
- jc write_os_files_exit
-
- mov bx,opsys_clusters ;Get number of sys sectors
- inc bx
- mov di,dx
- mov ax,0fff7h ;Bad sector flag
- cmp bx,di
- jb write_os_files_2
- write_os_files_1:
- call write_fat_entry ;Fill in empty sectors with
- inc di ; bad sector flags.
- cmp bx,di
- jae write_os_files_1
- write_os_files_2:
- clc
- write_os_files_exit:
- push cs ;Restore ES
- pop es
- pop bx
- pop ax
- ret
- write_os_files_err:
- mov si,offset write_os_error
- write_os_files_err1:
- stc
- jmp short write_os_files_exit
- write_os_files endp
-
- ;-----------------------------------------------------------------------
- ; STORE OS FILE - Writes an operating system file to the disk
- ; Entry: DX - Starting Cluster of file
- ; CX - Size of file
- ; SI - New file name
- ; DI - Ptr to directory entry
- ; ES - Segment of file data
- ; Exit: DX - Next free cluster
- ; CF - Set if error
- ;-----------------------------------------------------------------------
- store_os_file proc near
- push di
- push si
- push es
- push ds
- pop es
- push di ;First, copy new name to
- push cx ; dir entry.
- mov cx,11
- rep movsb
- pop cx
- pop di
- pop es
-
- mov [di+1Ah],dx ;Save new starting cluster
- mov [di+1Ch],cx ;Save size in dir entry
- xor bx,bx ;Start at beginning of buffer
- store_os_file_1:
- mov ax,dx ;Copy cluster to write
- push bx
- push cx
- push dx
- call cluster2sector ;Convert to sector number
- call write_disk ;Write cluster to disk
- pop dx
- pop cx
- pop bx
- add bx,bytes_per_clust ;Update read dest
- sub cx,bytes_per_clust ;Sub bytes written from size
- ja store_os_file_11
- mov di,dx ;Get new cluster
- mov ax,-1 ;Write -1 to FAT entry to
- call write_fat_entry ; indicate end of file.
- call find_free_clust ;Get next free cluster
- mov dx,di ;Copy ptr to free cluster
- store_os_file_exit:
- pop si
- pop di
- ret
- store_os_file_11:
- call find_free_clust ;Get next free cluster
- jc store_os_file_exit
- mov ax,di ;Copy new FAT entry
- xchg di,dx ;Xchg old, new FAT entries
- call write_fat_entry ;Write new cluster to old FAT
- jmp short store_os_file_1 ; entry. Loop back for more.
- store_os_file endp
-
- ;-----------------------------------------------------------------------
- ; FIND FREE CLUST - Finds the next free cluster in the FAT
- ; Entry: DX - Current cluster
- ; Exit: DI - Next free cluster
- ; CF - Set if no free clusters
- ;-----------------------------------------------------------------------
- find_free_clust proc near
- push dx
- find_free_clust_1:
- inc dx ;First, check to see if at
- cmp fat_size,dx ; end of FAT.
- jb find_free_clust_exit
-
- mov di,dx ;Scan through FAT to find next
- push dx ; entry with 0, indicating
- call get_fat_entry ; free cluster.
- pop dx
- or di,di ;See if cluster = 0 -> free
- jne find_free_clust_1 ;No, keep looking
- mov di,dx ;Copy free cluster
- clc
- find_free_clust_exit:
- pop dx
- ret
- find_free_clust endp
-
- ;-----------------------------------------------------------------------
- ; CHECK FAT - Counts the number of consecutive clusters at the start of
- ; the disk.
- ; Exit: CX - Count of available clusters.
- ;-----------------------------------------------------------------------
- check_fat proc near
- push di
- mov di,ROOT_DIR
- mov bx,[di+1Ah] ;Get starting cluster. If not
- call get_fat_chain ; consecutive clusters, skip
- jc check_fat_1 ; msdos.sys check.
- inc bx
- mov si,bx ;Save ending cluster
- add di,20h ;Point to MSDOS.SYS entry
- mov bx,[di+1Ah] ;Get starting cluster
- cmp si,bx
- jne check_fat_6
- call get_fat_chain
- add cx,si ;Sum consec clusters.
- check_fat_1:
- inc bx
- mov ax,fat_mask ;Convert FAT mask into bad
- mov al,0f7h ; sector detector
- check_fat_2:
- mov di,bx ;Copy ptr to last FAT entry
- push cx
- push ax ;Count the number of bad
- call get_fat_entry ; sectors at the end of
- pop ax ; the system files.
- pop cx
- or di,di ;See if sector free.
- je check_fat_3
- cmp di,ax ;See if sector marked bad
- jne check_fat_4
- check_fat_3:
- inc bx ;Inc FAT pointer
- inc cx ;Inc Count
- jmp short check_fat_2
- check_fat_4:
- clc
- check_fat_5:
- pop di
- ret
- check_fat_6:
- stc
- jmp short check_fat_1
- check_fat endp
-
- ;-----------------------------------------------------------------------
- ; CLEAN FAT - Removes bad cluster markers used to reserve clusters.
- ;-----------------------------------------------------------------------
- clean_fat proc near
- mov di,2 ;Start at cluster 2
- mov bx,fat_mask
- and bl,0f7h ;Create Bad entry mask
- or bl,0f7h
- clean_fat_1:
- push di
- call get_fat_entry ;See if entry marked bad
- cmp di,bx
- pop di
- jne clean_fat_2 ;No, skip write.
- xor ax,ax
- call write_fat_entry ;Clear entry
- clean_fat_2:
- inc di ;Point to next entry
- mov ax,opsys_clusters
- add ax,2
- cmp di,ax
- jbe clean_fat_1
- ret
- clean_fat endp
-
- ;-----------------------------------------------------------------------
- ; GET FAT CHAIN - Follows a FAT chain for a file.
- ; Entry: BX - Ptr to start of chain
- ; Exit: CX - Count of consecutive clusters
- ; BX - Last entry in FAT table.
- ; CF - Set if file not in consecutive clusters
- ;-----------------------------------------------------------------------
- get_fat_chain proc near
- push di
- xor cx,cx
- mov di,bx
- get_fat_chain_1:
- inc cx
- mov bx,di ;Copy FAT entry ptr
- push cx
- call get_fat_entry
- pop cx
- mov ax,bx
- jnc get_fat_chain_2 ;CF = 0, last entry
- sub bx,di ;See if consecutive
- cmp bx,-1
- je get_fat_chain_1
- stc
- get_fat_chain_2:
- mov bx,ax ;Get back last FAT entry
- pop di
- ret
- get_fat_chain endp
-
- ;-------------------------------------------------------------------------
- ; CLEAR FILE - Removes the FAT table entries for a file.
- ; Entry: BP - Pointer to boot data structure.
- ; DI - Pointer to directory entry
- ;-------------------------------------------------------------------------
- clear_file proc near
- push di
- push si
- mov bx,[di+1Ah] ;Get starting cluster
- clear_file_1:
- mov di,bx ;Save FAT pointer
- call get_fat_entry
- pushf ;Save end of file flag
- xchg di,bx
- xor ax,ax
- call write_fat_entry ;Zero entry to free cluster
- popf
- jc clear_file_1
- pop si
- pop di
- ret
- clear_file endp
-
- ;-------------------------------------------------------------------------
- ; WRITE FAT ENTRY - Writes FAT table entry
- ; Entry: BP - Pointer to boot data structure.
- ; DI - Pointer to fat table entry
- ; AX - Data to write to FAT table
- ;-------------------------------------------------------------------------
- write_fat_entry proc near
- push ax
- push bx
- push dx
- push di
- push ds
- push es
-
- mov ds,fat_seg_low ;Load DS and ES with segments
- mov es,fat_seg_high ; containing the FAT table.
-
- mov dx,cs:fat_mask ;Mask data to FAT size.
- or dl,-1
- and ax,dx
- xor dx,dx
- or dx,cs:fat_mask ;Mask unwanted bits
- jns write_fat_4 ;If 0fffh, 12 bit FAT
- mov bx,di ;16 bit FAT
- add di,bx ;Ptr = Index * 2
- jnc write_fat_2 ;CF = 1, Upper segment
- write_fat_1:
- mov es:[di],ax ;Write data
- jmp short write_fat_3
- write_fat_11:
- or ax,bx
- write_fat_2:
- mov ds:[di],ax ;Write data
- write_fat_3:
- pop es
- pop ds
- pop di
- pop dx
- pop bx
- pop ax
- ret
- write_fat_4:
- mov bx,di
- shr di,1 ;12 bit FAT
- pushf
- add di,bx
- mov bx,ds:[di] ;Get data
- popf
- jc write_fat_5 ;Jump if odd
- and bx,0f000h ;Remove old data
- jmp short write_fat_11
- write_fat_5:
- and bx,000fh ;Remove old data
- push cx
- mov cl,4
- shl ax,cl
- pop cx
- jmp short write_fat_11
- write_fat_entry endp
-
- ;-----------------------------------------------------------------------
- ; WRITE FAT TABLE - Writes data in memory FAT to disk FAT.
- ; Entry: AX - FAT number to write
- ;-----------------------------------------------------------------------
- write_fat_table proc near
- push ax
- push cx
- push es
- mov cx,sec_per_fat ;Compute starting sector
- mul cx ; of this FAT
- add ax,fat_sectorl
- adc dx,fat_sectorh
-
- push ax
- push dx
- mov bx,FAT_SEGMENT1
- mov es,bx
- xor bx,bx
- mov cx,low_fat_size
- call write_disk ;Write FAT
- pop dx
- pop ax
- jc write_fat_table_exit
-
- xor cx,cx
- or cx,hi_fat_size
- je write_fat_table_exit
- add ax,cx
- adc dx,0
- mov bx,FAT_SEGMENT2
- mov es,bx
- xor bx,bx
- call write_disk
- write_fat_table_exit:
- pop es
- pop cx
- pop ax
- ret
- write_fat_table endp
-
- ;-----------------------------------------------------------------------
- ; RENAME FILE
- ; Entry: SI - Ptr to file name to find
- ; DI - Ptr to new file name.
- ;-----------------------------------------------------------------------
- rename_file proc near
- push di
- push si
- cmp byte ptr [di],0 ;See if filename exists
- je rename_1
- push di ;Save ptr to new file name
- call find_file
- pop si
- jc rename_1
- mov cx,11 ;Copy name to entry.
- rep movsb
- clc
- rename_1:
- pop di
- pop si
- ret
- rename_file endp
-
- ;-----------------------------------------------------------------------
- ; MAKE OS NAMES
- ; Entry: BL - Operating System number
- ; Exit: SI - Ptr array of 8.3 op sys names
- ;-----------------------------------------------------------------------
- make_os_names proc near
- push bx
- mov si,offset os_names_table
- add bl,"0"
- mov [si+7],bl
- mov [si+18],bl
- mov [si+29],bl
- pop bx
- ret
- make_os_names endp
-
- ;--------------------------------------------------------------------
- ; WRITE VERT
- ;--------------------------------------------------------------------
- write_vert proc near
- lodsw ;Get location
- mov dx,ax
- write_vert1:
- mov di,dx ;Save cursor pos
- call set_cursor
- lodsb
- or al,al
- je write_vert2
- mov ah,0ah ;BIOS Write Char
- mov cx,1 ;1 character
- call vidint
- mov dx,di ;Get cursor pos
- inc dh
- call set_cursor
- jmp short write_vert1
- write_vert2:
- ret
- write_vert endp
-
- ;--------------------------------------------------------------------
- ; WRITE LINENORM
- ;Entry: SI - Offset of ASCIIZ string with leading word detailing
- ; row and column to start string.
- ;--------------------------------------------------------------------
- write_linenorm proc near
- push dx
- lodsw ;Get location
- mov dx,ax
- call write_line_at
- pop dx
- ret
- write_linenorm endp
-
- ;--------------------------------------------------------------------
- ; WRITE LINE AT/HI
- ;Entry: DX - Row/Column to start string
- ; SI - Offset of ASCIIZ string
- ;--------------------------------------------------------------------
- write_line_hi proc near
- mov bl,highlight_attr ;Write with highlight attribute
- jmp short write_line_at1
- write_line_hi endp
-
- write_line_at proc near
- mov bl,normal_attr
- write_line_at1:
- call set_cursor
- call write_line
- ret
- write_line_at endp
-
- ;--------------------------------------------------------------------
- ; WRITE LINE
- ;Entry: BL - Attribute for line
- ; SI - Offset of ASCIIZ string
- ;--------------------------------------------------------------------
- write_line proc near
- push bx
- push cx
- push dx
- push di
- xor bh,bh ;Set video page
- mov di,dx ;Save cursor pos
- write_line_1:
- lodsb
- or al,al
- je write_line_2
- mov ah,09h ;BIOS Write Char/Attr
- mov cx,1 ;1 character
- call vidint
- inc di
- mov dx,di ;Get cursor pos
- call set_cursor
- jmp short write_line_1
- write_line_2:
- pop di
- pop dx
- pop cx
- pop bx
- ret
- write_line endp
-
- ;--------------------------------------------------------------------
- ;WRITE BORDER
- ;--------------------------------------------------------------------
- write_border proc near
- call set_cursor
- mov ax,0acdh ;Write border
- mov cx,59
- call vidint
- ret
- write_border endp
-
- ;--------------------------------------------------------------------
- ; WRITE BOX writes copyright box to the screen.
- ;--------------------------------------------------------------------
- write_box proc near
- call scroll_scr
- xor bx,bx
- mov bl,normal_attr
- mov dx,010bh
- call write_border
- mov dx,050bh
- call write_border
-
- mov si,offset box1
- call write_vert
- mov si,offset box2
- call write_vert
-
- mov si,offset boxtext1 ;Point to 1st line
- mov cx,3
- title1: mov bl,normal_attr ;Set attribute
- call write_linenorm
- loop title1
- ret
- write_box endp
-
- ;-----------------------------------------------------------------------------
- ; VIDINT - Calls the BIOS int 10h. Saves BP to correct bug in old PC BIOS.
- ;-----------------------------------------------------------------------------
- vidint proc near
- push bp
- int 10h
- pop bp
- ret
- vidint endp
-
- ;-----------------------------------------------------------------------------
- ; SCROLL SCR Clears the screen.
- ;-----------------------------------------------------------------------------
- scroll_scr proc near
- xor cx,cx
- mov dh,screen_rows
- mov dl,50h
- call scroll_block
- ret
- scroll_scr endp
-
- ;-----------------------------------------------------------------------------
- ; SCROLL HALF Clears the screen below the copyright box.
- ;-----------------------------------------------------------------------------
- scroll_half proc near
- mov cx,0700h ;Row 7 Col 0
- mov dx,1950h
- call scroll_block
- ret
- scroll_half endp
-
- ;-----------------------------------------------------------------------------
- ; SCROLL BLOCK Clears a part of the screen.
- ; Entry: CX - Upper left corner
- ; DX - Lower right corner
- ;-----------------------------------------------------------------------------
- scroll_block proc near
- push bx
- xor bx,bx
- mov bh,normal_attr
- mov ax,0600h ;Scroll up
- call vidint
- pop bx
- ret
- scroll_block endp
-
- ;-----------------------------------------------------------------------------
- ; SCROLL BLOCK Clears a part of the screen.
- ; Entry: DX - Cursor Location
- ;-----------------------------------------------------------------------------
- set_cursor proc near
- push ax
- push bx
- mov ah,02h ;Set cursor
- xor bx,bx
- call vidint
- pop bx
- pop ax
- ret
- set_cursor endp
-
- ;-----------------------------------------------------------------------------
- ; PRINTNUM - Prints a single digit number to the screen.
- ; Entry: AL - binary number
- ; DX - Cursor location
- ;-----------------------------------------------------------------------------
- printnum proc near
- add al,30h
- mov si,offset number_buff
- mov [si],al
- call write_line_at ;Write number
- ret
- printnum endp
-
- ;-----------------------------------------------------------------------------
- ; HEX2ASC converts a binary number to ASCII and prints it to the screen.
- ; Entry: AX - binary number
- ;-----------------------------------------------------------------------------
- hex2asc proc near
- call set_cursor
- xor cx,cx
- mov cl,1 ;If number = 0, print 1
- or ax,ax ; zero.
- jne hex_0
- mov al,"0"
- jmp short hex_1
- hex_0:
- mov cl,3 ;Allow max of three digits
- hex_loop1:
- xor dx,dx ;Clear high word
- mov bx,10 ;Load number base
- div bx ;Divide by base (10)
- add dl,30h ;Convert to ascii
- push dx ;Save digit on stack
- loop hex_loop1
- mov cx,3 ;Allow max of three digits
- mov bl,"0" ;Set leading zero indicator
- hex_loop2:
- pop ax ;Get digit off stack
- or bl,al ;Don't print leading zeros.
- cmp bl,"0" ;The first non zero will
- jne hex_1 ; change bl to non-zero.
- mov al,20h
- hex_1:
- push bx
- mov ah,0eh ;Write TTY
- mov bl,12h
- call vidint
- pop bx
- loop hex_loop2
- hex_exit:
- ret
- hex2asc endp
- ;-----------------------------------------------------------------------------
- ; Extended boot data.
- ;-----------------------------------------------------------------------------
- boot_data_start = $
- boot_array = $
- name1 db "DOS Session ",0
- auto1 db "AUTOEXECMB1"
- config1 db "CONFIG MB1"
- ostype1 db 1 ;Index into op sys table
-
- name2 db NAME_LENGTH dup (80h),0
- db "AUTOEXECMB2"
- db "CONFIG MB2"
- db 0
-
- name3 db NAME_LENGTH dup (80h),0
- db "AUTOEXECMB3"
- db "CONFIG MB3"
- db 0
-
- name4 db NAME_LENGTH dup (80h),0
- db "AUTOEXECMB4"
- db "CONFIG MB4"
- db 0
- boot_array_end = $
-
- opsys_table = $
- os_name1 db 8 dup (80h),0 ;Name of operating system
- os_ioname db "IO SYS" ;IO.SYS file name
- os_comname db "MSDOS SYS" ;MSDOS.SYS file name
- os_boottype dw 0
- os_name2 db 8 dup (80h),0
- db "OS2LDR "
- db "OS2KRNL "
- dw 0
- os_name3 db 8 dup (80h),0
- db "BIOS SYS"
- db "DOS SYS"
- dw 0
- os_name4 db 8 dup (80h),0
- db "BIOS SYS"
- db "DOS SYS"
- dw 0
- opsys_table_end = $
- boot_data_end = $
-
- normal_attr db COLOR_NORM
- highlight_attr db COLOR_HIGH
- screen_rows db 0
- last_timeout dw 0
- timeout_value dw 0
- no_DOS_flag db 1 ;0 = No DOS resident.
-
- number_buff db 0,".",0
-
- read_os_error db 2,7,"Error Reading new DOS files",0
- write_os_error db 2,7,"Error Writing new DOS files",0
- no_room_error db 2,7,"Not enough room for new DOS files",0
- boot_extend_err db 2,7,"Write error, Last choice booted.",0
- change_os_msg db 2,7,"Changing DOS System files",0
-
- boot_os_msg db 2,11,"Operating System: "
- boot_os_msg1 db NAME_LENGTH+1 dup (0)
- boot_sess_msg db 2,9,"Booting Session: "
- boot_sess_msg1 db 9 dup (0)
-
- timeout_str db 41,23,"Time until default:",0
- timetext1 db 61,23,"Indefinite",0
- prompt_text db "Choice [ ]",0
-
- autoexec_name db "AUTOEXECBAT" ;Filenames to rename.
- config_name db "CONFIG SYS"
-
- ibmbio_name db "IBMBIO COM" ;IBM DOS system file names
- ibmcom_name db "IBMDOS COM"
- iosys_name db "IO SYS" ;MS DOS system file names
- msdos_name db "MSDOS SYS"
-
- os_names_table db "MBOOTOSaBOT" ;This array is used to hold
- db "MBOOTOSaSYS" ; the generated names of the
- db "MBOOTOSaCOM" ; DOS system files.
- ;
- ; Boot Menu structure
- ;
- boot_menu = $
- menu_struc db 4 ;Number of choices
- selected db 0 ;Selected Item
- prompt_loc db 30,20 ;Location of "Choices" prompt
- timeout dw 0 ;Timeout value
- db 40,23 ;Col, Row of Timeout string
- firstitem db 24,9 ;Column, Row of menu item
- dw offset name1 ;Offset of menu text
- db 24,11
- dw offset name2
- db 24,13
- dw offset name3
- db 24,15
- dw offset name4
-
- boxtext1 db 27,02,"PC Magazine",39,"s MultiBoot 1.1",0
- boxtext2 db 26,03,"(c) 1991 Ziff Communications",0
- boxtext3 db 32,04,"Douglas Boling",0
- box1 db 10,01,201,186,186,186,200,0 ;"╔","║","║","║","╚"
- box2 db 69,01,187,186,186,186,188,0 ;"╗","║","║","║","╝"
-
- ;============================================================================
- ;============================================================================
- ; Start of installation code and data.
- ;============================================================================
- ;============================================================================
- even
- install_start = $
- inst_text1 db "Session Title AUTOEXEC File "
- db "CONFIG File System",0
-
- main_menu db 8,0 ;Number of choices, Selected
- db 30,22 ;Location of "Choices" prompt
- dw 0 ;Timeout value
- db 0,0 ;Col, Row of Timeout string
- db 13,17 ;Column, Row of menu item
- dw offset add_entry ;Offset of menu text
- db 13,18
- dw offset delete_entry
- db 13,19
- dw offset set_default
- db 13,20
- dw offset add_osentry
- db 40,17
- dw offset install
- db 40,18
- dw offset remove
- db 40,19
- dw offset exit_prog
- db 40,20
- dw offset quit_prog
-
- confirm_msg db 20,16,"Do you wish to discard changes?",0
-
- yes_text db "Yes",0
- no_text db "No",0
- yesno_menu db 2,1 ;Number of choices, Selected
- db 25,22 ;Location of "Choices" prompt
- dw 0 ;Timeout value
- db 0,0 ;Col, Row of Timeout string
- db 25,18 ;Column, Row of menu item
- dw offset yes_text ;Offset of menu text
- db 25,20
- dw offset no_text
-
- add_entry db "Add Session",0
- delete_entry db "Delete Session",0
- set_default db "Set Defaults",0
- add_osentry db "Load Operating System",0
- install db "Install MultiBoot",0
- remove db "Remove MultiBoot",0
- exit_prog db "Update and Exit MultiBoot",0
- quit_prog db "Quit MultiBoot",0
-
- return_text db "Update and Return",0
- quit_text db "Return Without Changing",0
- unused_text db "< Unused >",0
- unused_text_end = $
-
- os2knl_name db "OS2KRNL "
- os2ldr_name db "OS2LDR "
- os2boot_aname db "C:\OS2\SYSTEM\BOOT.OS2",0
-
- default_str db "Def.",0
-
- command_table dw offset main_menu ;Offset of menu for this table
- dw offset main_add ;Command jump table
- dw offset main_delete
- dw offset main_defaults
- dw offset main_osadd
- dw offset main_install
- dw offset main_remove
- dw offset exit
- dw offset quit
-
- dos_version dw 0
- installed_flag db 0 ;Set if MultiBoot installed
- changed_flag db 0
- local_changed db 0
- huge_flag db 0 ;Set if target disk > 32M
- targ_sec_per_cluster dw 0
-
- session_count db 0 ;Number of used sessions
- opsys_count db 0 ;Number of operating systems
-
- iosys_size dw 0 ;Size of IO.SYS read
- doscom_size dw 0 ;Size of MSDOS.SYS read
- opsys_ostype dw 0 ;DOS File config
-
- databuff_ptr dd 0 ;Pointer to data buffer
- databuff1_ptr dd 0 ;Pointer to second data buffer
- crit_vec dd 0 ;Saved critical error vector
- ctlc_vec dd 0 ;Saved control C vector
- ctlc_stack dw 0
- ctlc_return dw 0
-
- drive_letter db "A" ;Target drive
-
- installed_data = $
- db 3 dup (0) ;Bytes for jump instruction
- inst_data_ptr dw 0 ;Offset of last boot data
- inst_data_size dw 0 ;Size of last boot data
- inst_sess_ptr dw 0 ;Offset of boot session table
- inst_sess_size dw 0 ;Size of boot session table
- inst_boot_ptr dw 0 ;Offset of boot os table
- inst_boot_size dw 0 ;Size of boot os table
- inst_version dw 0 ;Version of installed code
- installed_data_end = $
-
- key_buffer db 64 dup (0)
- temp_buff db 64 dup (0)
- filename_buff db 20 dup (0)
- temp dw 0 ;Temp storage buffer
-
-
- errmsg0 db "Requires at least DOS 2.x$"
- errmsg1 db "This program cannot be run under OS/2$"
- errmsg2 db "Not enough memory for MultiBoot$"
- errmsg3 db "Too many open files$"
- errmsg4 db "Access to files denied$"
- errmsg5 db "Drive Letter not specified on command line$"
- errmsg6 db "Drive Letter invalid$"
- errmsg7 db "MultiBoot file MBOOT.SYS not found$"
- errmsg8 db "Not a bootable disk or unknown operating system$"
- errmsg9 db "MultiBoot must be run in 80 column mode$"
- errmsg10 db "Installed data is incompatible with this version$"
- crmsg db 13,10,"$"
-
- error_msg_loc dw 180ah ;Column, Row of error msgs
-
- errmsg20 db "Install error",0
- errmsg21 db "MultiBoot Already Installed",0
- errmsg22 db "Remove error",0
- errmsg23 db "MultiBoot Not Installed",0
-
- ;-----------------------------------------------------------------------------
- ; Prevent Abort,Retry,Ignore error msg with this dummy crit. error routine
- ;-----------------------------------------------------------------------------
- crit_error proc far
- mov al,0 ;Ignore critical error.
- iret
- crit_error endp
-
- ;-----------------------------------------------------------------------------
- ; Installation code.
- ;-----------------------------------------------------------------------------
- main proc near
- assume ds:code
- cld ;Set string operations up
- mov ah,30h ;Get DOS version, run only
- int 21h ; if 2.0 or greater.
- xchg al,ah ;Swap major, minor numbers
- mov dx,offset errmsg0 ;Bad DOS version
- cmp ah,2
- jb jmp1_error_exit
- mov dx,offset errmsg1 ;Program cannot be run in the
- cmp ah,10 ; DOS box under OS/2.
- jae jmp1_error_exit
- mov dos_version,ax ;Save version number
-
- mov sp,offset end_of_code + 512 ;Move stack
- mov ah,4ah ;Reduce memory alloc
- mov bx,offset end_of_code + 527
- mov cl,4
- shr bx,cl
- int 21h
-
- int 12h ;Get size of machine RAM
- cmp ax,384 ;Must be at least 384K to
- mov dx,offset errmsg2 ; use extended boot code.
- jb jmp1_error_exit
-
- mov ah,48h ;Allocate memory block for
- mov bx,1000h ; data buffer.
- int 21h
- mov dx,offset errmsg2 ;Not enough memory msg
- jc jmp1_error_exit
- mov word ptr databuff_ptr[2],ax ;Save segment.
-
- mov ah,48h ;Allocate memory block for
- mov bx,1000h ; second data buffer.
- int 21h
- mov dx,offset errmsg2 ;Not enough memory msg
- jc jmp1_error_exit
- mov word ptr databuff1_ptr[2],ax ;Save segment.
-
- call set_ctlc_vec ;Setup Control-C routine
-
- mov si,81h ;Point to command line tail
- xor cx,cx
- or cl,[si-1] ;Get cmd tail length
- jne main_2
- main_1:
- mov dx,offset errmsg5 ;Drive letter not specified.
- jmp1_error_exit:
- jmp error_exit
- main_2:
- lodsb
- cmp al,13 ;See if end of line
- je main_1 ;If so, error.
- cmp al," "
- ja main_3
- loop main_2
- jmp short main_1
- main_3:
- cmp byte ptr [si],":" ;Make sure drive letter
- jne main_1 ; terminated by colon.
- and al,0dfh ;Convert drive letter to
- cmp al,"A" ; upper case.
- jb main_1
- cmp al,"Z"
- ja main_1
- mov drive_letter,al ;Save drive letter
-
- call set_crit_vec ;Set crit vec to int routine
- call huge_disk_check ;See if target disk > 32 Meg
- call reset_crit_vec
- mov dx,offset errmsg6
- jc jmp1_error_exit
- je main_not_huge
- inc huge_flag ;If so, set flag
- main_not_huge:
- mov targ_sec_per_cluster,di
- call check_os ;See what system on target
- cmp al,-1 ; disk.
- mov dx,offset errmsg6 ;See if error reading disk.
- je jmp1_error_exit
-
- push ax
- xor al,al ;Copy BIOS parameter block
- call copy_bpb ; to boot rec data area.
- pop ax
-
- cmp al,3 ;See if MultiBoot installed
- je main_installed
- mov dx,offset errmsg8 ;If OS unknown or unbootable,
- cmp al,2 ; error.
- jae jmp1_error_exit
-
- call setup_multiboot ;Not installed, setup.
- jmp short main_5
- main_installed:
- inc installed_flag ;Set installed flag
- call get_inst_data ;Read data from MBOOT.SYS
- jc jmp1_error_exit
- main_5:
- mov cx,4
- mov si,offset opsys_table ;Count sessions and op systems
- mov di,offset boot_array
- add di,OSTYPE_OFFSET
- main_count_loop:
- cmp byte ptr [si],80h ;If lead byte 80h, entry
- jae main_6 ; unused.
- inc opsys_count ;Inc number of op systems
- main_6:
- cmp byte ptr [di],0 ;Op Sys = 0, no session.
- je main_7
- inc session_count
- main_7:
- add di,NEXT_ENTRY ;Point to next entries
- add si,NEXT_OSENTRY
- loop main_count_loop
-
- push ds
- mov ax,40h ;Get number of screen rows
- mov ds,ax
- mov dl,[84h]
- pop ds
- mov screen_rows,dl
-
- mov ah,0fh ;Read video mode
- call vidint
- mov dx,offset errmsg9 ;Must be in 80 column mode
- cmp ah,80
- jb error_exit
- cmp al,0fh ;Check for BW modes
- je main_set_bw
- cmp al,6
- jb main_set_color
- cmp al,7
- ja main_set_color
- main_set_bw:
- mov normal_attr,BW_NORM ;Use Black/White attributes
- mov highlight_attr,BW_HIGH
- main_set_color:
- call write_box ;Write copyright box
- main_loop:
- mov di,offset name1 ;Display current sessions
- call disp_settings
- mov local_changed,0
- mov si,offset command_table ;Display menu and jump to
- mov al,1 ; proper routine. Default
- call jump_menu ; to Add Session.
- pushf
- cmp al,-1 ;See if exit
- je main_exit
- add changed_flag,al ;Set flag if mboot modified.
- call scroll_half
- popf
- jnc main_loop ;If carry, print message
-
- call write_error ;Print error message
- jmp short main_loop
- error_exit:
- mov ah,9 ;Print error message
- int 21h
- mov dx,offset crmsg
- mov ah,9 ;Insert carrage return
- int 21h
- mov al,1
- jmp short main_exit1
- main_exit:
- popf ;Remove flags from stack
- mov dx,0700h ;Set cursor to Row 7 Column 0.
- call set_cursor
- xor ax,ax ;Clear return code
- main_exit1:
- push ax
- mov ax,word ptr databuff_ptr[2] ;Get segment.
- or ax,ax
- je main_exit2
- mov es,ax
- mov ah,49h ;Free data buffer
- int 21h
- main_exit2:
- mov ax,word ptr databuff1_ptr[2] ;Get segment.
- or ax,ax
- je main_exit3
- mov es,ax
- mov ah,49h ;Free data buffer
- int 21h
- main_exit3:
- pop ax
- mov ah,4ch
- int 21h
- main endp
-
- ;--------------------------------------------------------------------
- ; SETUP MULTIBOOT - Configures Multiboot if not installed.
- ; Entry: AX - Operating system on target disk
- ; BX - DOS version
- ; CX - Consecutive clusters used by DOS files
- ;--------------------------------------------------------------------
- setup_multiboot proc near
- push ax ;Save operating system type
- push bx ; and size.
- mov opsys_clusters,cx
-
- mov ah,2ch ;Get system time for time
- int 21h ; stamp ID
- mov word ptr time_stamp,cx
- mov word ptr time_stamp[2],dx
- pop cx ;Get os config
- pop ax ;Get os type
-
- mov bl,1 ;The current os becomes the
- call copy_os_name ; default.
-
- mov si,offset boot_extend_start ;Copy installed data ptrs
- mov di,offset installed_data
- mov cx,offset installed_data_end - offset installed_data
- rep movsb
-
- cmp ah,1 ;See if OS/2 installed
- jne setup_multiboot_1
- mov dx,offset os2boot_aname ;Yes, look for BOOT.OS2
- mov cl,drive_letter
- mov byte ptr os2boot_aname,cl
- push es
- les si,databuff_ptr ;Read OS/2 boot record file.
- call read_file
- pop es
- jc setup_multiboot_1
- mov bl,2
- mov cx,100h ;OS type = OS/2
- call copy_os_name ;Copy OEM name.
- setup_multiboot_1:
- mov bl,1 ;Verify default session
- call get_entry ; filenames are not used.
- mov cx,8
- setup_multiboot_2:
- lea si,[bx+AUTO_OFFSET] ;Search for the filenames used
- call find_first ; in the default session. If
- jnc setup_multiboot_3 ; used, rename by changing
- lea si,[bx+CONFIG_OFFSET] ; the extension.
- call find_first
- jc setup_exit
- setup_multiboot_3:
- inc byte ptr [bx+AUTO_OFFSET+10]
- inc byte ptr [bx+CONFIG_OFFSET+10]
- loop setup_multiboot_2 ;If all filenames used
- mov byte ptr [bx+OSTYPE_OFFSET],0 ; delete default.
- setup_exit:
- ret
- setup_multiboot endp
-
- ;--------------------------------------------------------------------
- ; GET INST DATA - Reads the configutation data from MBOOT.SYS
- ; Exit: CF - Set if error
- ; DX - Offset of error message.
- ;--------------------------------------------------------------------
- get_inst_data proc near
- mov si,offset mboot_name ;Open the MBOOT.SYS file to
- call make_filename ; read the boot information.
- xor cx,cx
- call set_attributes ;Clear the file attributes.
- mov ax,3d02h
- int 21h
- jc get_inst_file_error
-
- mov bx,ax ;Copy file handle
- mov ah,3fh ;Read ptr to boot table
- mov dx,offset installed_data
- mov cx,offset installed_data_end - offset installed_data
- int 21h
- jc get_inst_file_error
-
- mov dx,offset errmsg10 ;See if installed data
- cmp inst_version,20h ; compatible
- jae get_inst_data_error
-
- mov ax,4200h ;Move file ptr
- mov dx,inst_data_ptr
- xor cx,cx
- int 21h
- jc get_inst_file_error
- mov ah,3fh ;Read default session data
- mov dx,offset boot_data1
- mov cx,inst_data_size
- int 21h
- jnc get_inst_data_1
- get_inst_file_error:
- mov dx,offset errmsg7 ;Boot file error.
- cmp ax,2 ;See if file not found
- je get_inst_data_error ;Yes, error
- mov dx,offset errmsg3 ;See if too many files opened
- cmp ax,4
- je get_inst_data_error
- mov dx,offset errmsg4 ;Assume access denied
- get_inst_data_error:
- stc
- jmp short get_inst_data_exit
- get_inst_data_1:
- mov ax,4200h ;Move file ptr to session table
- mov dx,inst_sess_ptr
- xor cx,cx
- int 21h
- jc get_inst_file_error
- mov ah,3fh ;Read boot session data
- mov dx,offset boot_array
- mov cx,inst_sess_size
- int 21h
- jc get_inst_file_error
-
- mov ax,4200h ;Move file ptr to session table
- mov dx,inst_boot_ptr
- xor cx,cx
- int 21h
- jc get_inst_file_error
- mov ah,3fh ;Read boot session data
- mov dx,offset opsys_table
- mov cx,inst_boot_size
- int 21h
- jc get_inst_file_error
-
- mov ah,3eh ;Close file
- int 21h
- mov si,offset mboot_name ;Set MBOOT.SYS file attributes
- call make_filename ; to hidden, system, and
- mov cx,SYSFILE_ATTR ; read only.
- call set_attributes
- jc get_inst_file_error
- get_inst_data_exit:
- ret
- get_inst_data endp
-
- ;--------------------------------------------------------------------
- ; MAIN ADD - Displays the Add Session submenu.
- ;--------------------------------------------------------------------
- local_add1 db NEXT_ENTRY dup (0) ;Local copy of boot table
- local_add2 db NEXT_ENTRY dup (0)
- local_add3 db NEXT_ENTRY dup (0)
- local_add4 db NEXT_ENTRY dup (0)
- local_add_end = $
- local_add_count db 0
-
- local_selection dw 0 ;Current selected session
- local_add_menu = $
- db 4 ;Number of choices
- add_select db 0 ;Selected Item
- db 30,20 ;Location of "Choices" prompt
- dw 0 ;Timeout value
- db 0, 0 ;Col, Row of Timeout string
- db 24,9 ;Column, Row of menu item
- dw offset local_add1 ;Offset of menu text
- db 24,11
- dw offset local_add2
- db 24,13
- dw offset local_add3
- db 24,15
- dw offset local_add4
-
- add_str2 db 20,7
- add_select_str1 db "Current Sessions",0
- add_add_text db "Add Session",0
- add_rename_text db "Rename Session",0
-
- add_str4 db 05,14,"Enter the title of the session:",0
- add_str7 db 15,16,"Is this correct?",0
-
- add_str_msg1 db 10,22,"Press Ctrl-Break to return to Add Menu",0
- add_str_err1 db "No Sessions Added",0
- add_str_err2 db "No free sessions, delete a session first",0
-
- add_table dw offset add_menu
- dw offset add_add_sess
- dw offset add_rename
- dw offset add_exit
- dw offset add_quit
-
- add_menu db 4,0 ;Number of choices, Selected
- db 30,22 ;Location of "Choices" prompt
- dw 0 ;Timeout value
- db 0,0 ;Col, Row of Timeout string
- db 25,17 ;Column, Row of menu item
- dw offset add_add_text ;Offset of menu text
- db 25,18
- dw offset add_rename_text
- db 25,19
- dw offset return_text
- db 25,20
- dw offset quit_text
-
- main_add proc near
- assume cs:code,ds:code
- mov di,offset local_add1 ;Copy boot array
- mov si,offset boot_array
- mov cx,4 ;4 Entries.
- main_add_0:
- push cx ;Copy the contents of the
- mov cx,NEXT_ENTRY ; marked unused, replace
- mov bx,di
- rep movsb
- cmp byte ptr [bx+OSTYPE_OFFSET],0 ;See if session unused.
- jne main_add_02
- mov byte ptr [bx+AUTO_OFFSET],0 ;If unused, clear
- mov byte ptr [bx+CONFIG_OFFSET],0 ; filename entries
- mov byte ptr [bx],80h
- main_add_02:
- pop cx
- loop main_add_0
- mov al,session_count ;Copy session count
- mov local_add_count,al
- main_add_1:
- mov di,offset local_add1 ;Display current sessions.
- call disp_settings
-
- mov si,offset add_table ;Display the add menu
- mov al,1
- call jump_menu ;Call submenu routines
- pushf ;Save carry flag
- pop bx
- cmp al,-1
- jne main_add_1
- mov al,local_changed ;Indicate if changes made.
- push bx ;Restore carry flag if needed
- popf
- ret
-
- ;--------------------------------------------------------------------
- ; ADD ADD SESSION - adds an entry to the boot table.
- ;--------------------------------------------------------------------
- add_add_sess proc near
- call scroll_half
- xor bx,bx
- mov bl,local_add_count ;Get number of sessions.
- cmp bl,4 ;See if too many
- jb add_add_sess_1
- mov si,offset add_str_err2
- call write_error ;Print error message
- jmp add_add_sess_exit
- add_add_sess_1:
- mov cx,4
- xor bx,bx ;Find first free boot table
- mov si,offset local_add1 ; entry.
- add_add_sess_11:
- inc bx
- cmp byte ptr [si+OSTYPE_OFFSET],0
- je add_add_sess_12
- add si,NEXT_ENTRY
- loop add_add_sess_11
- add_add_sess_12:
- call get_sess_name ;Get session name
- jnc add_add_sess_13
- jmp_add_add_sess_5:
- jmp add_add_sess_5
- add_add_sess_13:
- mov local_selection,bp
- mov si,offset autoexec_name ;Point to AUTOEXEC.BAT name
- call add_file
- jc jmp_add_add_sess_5
- mov di,local_selection ;Copy AUTOEXEC filename to
- add di,AUTO_OFFSET ; local array.
- mov cx,12
- rep movsb
-
- mov si,offset config_name ;Point to CONFIG.SYS name
- call add_file
- jc add_add_sess_5
- mov di,local_selection ;Copy CONFIG filename to
- add di,CONFIG_OFFSET ; local array.
- mov cx,12
- rep movsb
-
- mov dh,10
- call clear_line
- mov di,local_selection ;Write session data to screen
- call disp_session
-
- mov dh,14
- call clear_line
- add_add_sess_2:
- mov bl,1 ;Assume only one OS.
- cmp opsys_count,1
- je add_add_sess_3 ;If only one OS, don't display
- call get_ostype ; OS menu.
- or bl,bl
- je add_add_sess_2 ;Must select an os.
- add_add_sess_3:
- mov di,local_selection ;Set OS type
- add di,OSTYPE_OFFSET
- mov byte ptr [di],bl
-
- mov dh,10
- call clear_line
- mov di,local_selection ;Write session data to screen
- call disp_session
-
- mov al,1
- mov si,offset add_str7 ;Ask user to verify changes.
- call msg_box
- cmp bl,1 ;See if Yes.
- je add_add_sess_4
- mov di,local_selection ;If no, clear entries
- mov byte ptr [di],80h ; and return to
- mov byte ptr [di+AUTO_OFFSET],0 ; add menu.
- mov byte ptr [di+CONFIG_OFFSET],0
- mov byte ptr [di+OSTYPE_OFFSET],0
- jmp short add_add_sess_exit
- add_add_sess_4:
- mov local_changed,1 ;Set changes flag
- inc local_add_count ;Inc number of sessions
- add_add_sess_5:
- call scroll_half
- add_add_sess_exit:
- xor al,al
- ret
- add_add_sess endp
-
- ;--------------------------------------------------------------------
- ; ADD RENAME SESSION - Renames a session.
- ;--------------------------------------------------------------------
- add_rename proc near
- mov bp,offset local_add_menu
- xor ax,ax
- call get_session_2 ;Ask for a session
- jc add_rename_session_exit
-
- or bx,bx ;See if no choice
- jz add_rename_session_exit
-
- call get_sess_name ;Ask for a session name
- jc add_rename_session_exit
- mov local_changed,1
- add_rename_session_exit:
- call scroll_half
- xor al,al ;Clear exit flag
- ret
- add_rename endp
- ;--------------------------------------------------------------------
- ; ADD EXIT - Copies the local data to the main boot table then sets
- ; the exit flag
- ;--------------------------------------------------------------------
- add_exit proc near
- mov bx,offset local_add1
- mov dx,offset boot_array
- mov cx,4 ;4 Entries.
- main_add_5:
- push cx ;Copy only entrys used.
- mov si,bx
- mov di,dx
- cmp byte ptr [bx+OSTYPE_OFFSET],0 ;See of entry used.
- je main_add_6
- mov cx,NEXT_ENTRY
- rep movsb
- main_add_6:
- add dx,NEXT_ENTRY
- add bx,NEXT_ENTRY
- pop cx
- loop main_add_5
- mov al,local_add_count ;Copy new number of sessions
- mov session_count,al
- mov al,-1 ;Set exit flag
- ret
- add_exit endp
-
- ;--------------------------------------------------------------------
- ; ADD QUIT - Querys user for verification then returns exit flag
- ;--------------------------------------------------------------------
- add_quit proc near
- xor al,al
- cmp local_changed,0 ;See if any changes made
- je add_quit_1
- call confirm_quit
- jne add_quit_exit
- mov si,offset add_str_err1 ;No changes message.
- mov local_changed,0 ;Clear changes flag
- add_quit_1:
- mov al,-1 ;Set exit flag
- add_quit_exit:
- ret
- add_quit endp
- main_add endp
-
- ;--------------------------------------------------------------------
- ; MAIN DELETE - Deletes an entry to the boot table.
- ;--------------------------------------------------------------------
- local_delete dw 4 dup (0) ;Delete flag for each session
-
- delete_str2 db 20,07
- del_select db "Select Session to Delete",0
- delete_str3 db 15,11,"Do you want to delete the CONFIG.SYS"
- db " and AUTOEXEC.BAT",0
- delete_str4 db 15,12,"files for this Session?",0
-
- delete_err1 db "Can",39,"t delete active session.",0
-
- tbdel_text db "To Be Deleted ->",0
-
- delete_table dw offset delete_menu
- dw offset delete_delete_session
- dw offset delete_exit
- dw offset add_quit
-
- delete_menu db 3,0 ;Number of choices, Selected
- db 30,22 ;Location of "Choices" prompt
- dw 0 ;Timeout value
- db 0,0 ;Col, Row of Timeout string
- db 25,18 ;Column, Row of menu item
- dw offset del_select ;Offset of menu text
- db 25,19
- dw offset return_text
- db 25,20
- dw offset quit_text
-
- main_delete proc near
- assume cs:code,ds:code
- xor ax,ax ;Clear local delete flags.
- mov di,offset local_delete
- stosw
- stosw
- stosw
- stosw
- xor bx,bx
- main_delete_1:
- push bx
- popf
- jnc main_delete_2
- call write_error
- main_delete_2:
- mov bp,offset boot_menu ;Display sessions
- call write_menu ; in menu form.
- mov cx,4
- mov dx,word ptr firstitem ;Starting cursor loc from
- mov dl,5 ; boot menu structure.
- mov si,offset local_delete
- main_delete_3:
- lodsw
- or al,al ;See if session to be deleted
- je main_delete_4 ;No, skip
- push si
- mov si,offset tbdel_text
- call write_line_at
- pop si
- main_delete_4:
- inc dh ;Move to next cursor location
- inc dh
- loop main_delete_3
- ;Display delete menu.
- mov si,offset delete_table ;Display the delete menu
- mov al,1
- call jump_menu
- pushf ;Save carry flag
- pop bx
- cmp al,-1 ;See if exit flag set
- jne main_delete_1
- mov al,local_changed ;Indicate if changes made.
- push bx ;Restore carry flag if needed
- popf
- ret
-
- ;--------------------------------------------------------------------
- ; DELETE DELETE SESSION - Querys the user for the session to delete
- ;--------------------------------------------------------------------
- delete_delete_session proc near
- mov al,0 ;Get session to delete.
- call get_session
- jc delete_delete_exit
- cmp bx,last_choice ;Make sure not deleting
- jne delete_delete_0 ; current session.
- mov si,offset delete_err1
- xor al,al
- stc
- jmp short delete_delete_exit1
- delete_delete_0:
- push bx
- call scroll_half ;See if we need to delete the
- mov si,offset delete_str3 ; CONFIG.SYS and AUTOEXEC.BAT
- call write_linenorm ; files.
- mov si,offset delete_str4
- mov al,2
- call msg_box
- mov ah,bl ;Copy yes no answer
- pop bx ;Restore selection to delete
- jnc delete_delete_1
- mov ah,2 ;If <esc> force No reply.
- delete_delete_1:
- dec ah
- dec bx
- shl bx,1
- mov al,1
- mov [bx+local_delete],ax ;Save delete flags for this
- call scroll_half ; selection.
- delete_delete_exit:
- xor al,al ;Clear exit flag
- delete_delete_exit1:
- ret
- delete_delete_session endp
-
- ;--------------------------------------------------------------------
- ; DELETE EXIT - Performs the delete of sessions requested then sets
- ; the error flag.
- ;--------------------------------------------------------------------
- delete_exit proc near
- mov cx,4
- mov si,offset local_delete ;Set ptr to delete selections
- mov di,offset name1 ;Point to 1st session title
- delete_exit_1:
- lodsw ;Get flag for selection
- or al,al ;Delete entry?
- je delete_exit_3
- mov byte ptr [di+OSTYPE_OFFSET],0 ;Delete entry in list
- or byte ptr [di],80h
- dec session_count
- mov local_changed,1 ;Set changed flag
- mov dl,5
- sub dl,cl
- cmp dl,boot_default ;If entry just deleted was
- jne delete_exit_2 ; the default, remove default.
- mov boot_default,0
- delete_exit_2:
- or ah,ah ;Should the AUTOEXEC and
- jne delete_exit_3 ; CONFIG files be deleted?
- push si
- lea si,[di+AUTO_OFFSET] ;Yes, delete files
- call delete_file
- lea si,[di+CONFIG_OFFSET]
- call delete_file
- pop si
- delete_exit_3:
- add di,NEXT_ENTRY ;Point to next session title
- loop delete_exit_1
- mov al,-1 ;Set exit flag
- ret
- delete_exit endp
- main_delete endp
-
- ;--------------------------------------------------------------------
- ; INST OSADD - Adds an operating system to the disk.
- ;--------------------------------------------------------------------
- osadd_str0 db 25,07,"Current Operating Systems",0
- osadd_str1 db 10,08,"Insert Diskette with new DOS system"
- db " into Drive A:",0
- osadd_str2 db 10,10,"Press any key when Diskette inserted.",0
- osadd_str3 db 10,08,"Insert Target diskette into Drive A:",0
- osadd_str4 db 10,08,"Current Operating System name: "
- osadd_namestr db 9 dup (0)
- osadd_str5 db 10,10,"New Operating System name:",0
- osadd_str6 db 10,10,"Reading DOS System files",0
- osadd_str7 db 10,10,"Writing DOS System files",0
- osadd_dos5 db 15,16,"Are you installing DOS 5.0 or greater?",0
- osadd_dos4 db 15,16,"Are you installing DOS 4.0 or greater?",0
- osadd_dos3 db 15,16,"Are you installing DOS 3.0 or greater?",0
-
- osadd_err1 db "Only four operating systems can be added",0
- osadd_err2 db "Can",39,"t delete last operating system",0
- osadd_err3 db "Diskette is not a bootable DOS diskette",0
- osadd_err4 db "MultiBoot installed on diskette",0
- osadd_err5 db "OS/2 cannot be installed from diskette",0
- osadd_err6 db "Error writing DOS System files to the disk",0
- osadd_err7 db "Operating system used by a session. Delete session "
- db "first",0
- osadd_err8 db "New DOS system files larger than original DOS system"
- db " files",0
- osadd_err9 db "Target disk not original MultiBoot disk."
- db " DOS system not loaded",0
- osadd_err10 db "MultiBoot must be installed before adding"
- db " an Operating System",0
- osadd_err11 db "Error updating MBOOT.SYS file",0
-
- osa_addos_text db "Add an operating system",0
- osa_delos_text db "Delete an operating system",0
- osa_renos_text db "Rename an operating system",0
-
- osadd_table dw offset osadd_menu
- dw offset osadd_add_opsys
- dw offset osadd_del_opsys
- dw offset osadd_ren_opsys
- dw offset osadd_exit
-
- osadd_menu db 4,0 ;Number of choices, Selected
- db 30,22 ;Location of "Choices" prompt
- dw 0 ;Timeout value
- db 0,0 ;Col, Row of Timeout string
- db 25,17 ;Column, Row of menu item
- dw offset osa_addos_text ;Offset of menu text
- db 25,18
- dw offset osa_delos_text
- db 25,19
- dw offset osa_renos_text
- db 25,20
- dw offset return_text
-
- main_osadd proc near
- assume cs:code,ds:code
- xor bx,bx ;First time, no error.
- main_osadd_1:
- push bx ;Check for carry indicating
- popf ; an error message display
- jc main_osadd_2
- call scroll_half ;Clear screen
- main_osadd_2:
- mov si,offset osadd_str0 ;Display current op systems
- call write_linenorm
-
- xor cx,cx
- mov cl,opsys_count ;Four operating systems
- mov dx,0920h
- mov si,offset opsys_table ;Point to the opsys table
- main_osadd_3:
- push si
- call write_line_at
- pop si
- add si,NEXT_OSENTRY
- add dh,2
- loop main_osadd_3
- ;Display os add menu.
- mov si,offset osadd_table ;Display the op sys add menu
- mov al,1
- call jump_menu
- pushf ;Save carry flag
- pop bx
- cmp al,-1 ;See if exit flag set
- jne main_osadd_1
- xor ax,ax ;Indicate if changes made.
- push bx ;Restore carry flag if needed
- popf
- ret
-
- ;--------------------------------------------------------------------
- ; OSADD ADD OPSYS - Adds an operating system to the disk.
- ;--------------------------------------------------------------------
- osadd_add_opsys proc near
- mov si,offset osadd_err1 ;Only room for four operating
- cmp opsys_count,4 ; systems.
- jae jmp_osadd_error
-
- mov si,offset osadd_err10 ;Must be installed message
- cmp installed_flag,0
- je jmp_osadd_error
-
- mov si,offset osadd_str1 ;Prompt user for opsys
- call write_linenorm ; diskette.
- mov si,offset osadd_str2
- call write_linenorm
-
- call fetch_key ;Read a key from the keyboard
-
- call clear_msg ;Clear message off screen
- mov si,offset osadd_str6 ;Reading files message
- call write_linenorm
-
- mov al,"A" ;Set disk A
- call get_opsys ;Read operating sys from disk
-
- mov ah,0 ;Ignore OS/2 flag
- push ax ;Save os type
- push cx
- push dx
- pushf ;Save error flag
- cmp drive_letter,"A"
- jne osadd_add_3
- mov si,offset osadd_str3 ;Prompt user for target
- call write_linenorm ; diskette.
- mov si,offset osadd_str2
- call write_linenorm
-
- call fetch_key ;Read a key from the keyboard
- osadd_add_3:
- call clear_msg ;Clear message off screen
- popf ;Restore error flags
- pop dx ;Restore IO.SYS size
- pop cx ;Restore DOS system size
- pop ax ;Restore os type
-
- jnc osadd_add_11
- mov si,offset osadd_err8
- cmp al,7 ;See if Op sys too big
- je jmp_osadd_error
- mov si,offset osadd_err4
- cmp al,3 ;See if Multiboot diskette
- je jmp_osadd_error
- mov si,offset osadd_err5
- cmp al,2 ;See if OS/2 diskette
- je jmp_osadd_error
- mov si,offset osadd_err3
- cmp al,1 ;See if diskette is bootable
- jbe osadd_add_11
- jmp_osadd_error:
- jmp osadd_error
- osadd_add_11:
- call chk_mboot_disk ;See that proper disk is in
- mov si,offset osadd_err9 ; drive.
- jc jmp_osadd_error
-
- cmp opsys_ostype,50h
- je osadd_add_14
- mov si,offset osadd_dos5 ;Ask user if installing DOS 5
- mov di,50h
- cmp opsys_clusters,0
- je osadd_add_12
-
- mov si,offset osadd_dos4 ;Ask user if installing DOS 4
- mov di,40h
- cmp huge_flag,0 ;If disk > 32 Meg, ask for
- jne osadd_add_12 ; DOS 4
- cmp dx,opsys_clusters
- ja osadd_add_12
- mov si,offset osadd_dos3 ;Ask user if installing DOS 3
- mov di,30h
- cmp cx,opsys_clusters
- jb osadd_add_14
- osadd_add_12:
- push ax
- push di
- mov al,1 ;Set default to Yes
- call msg_box
- pop di
- pop ax
- cmp bl,1 ;See if answer Yes
- mov si,offset osadd_err8
- jne jmp_osadd_error
- mov opsys_ostype,di ;Save new opsys type
- osadd_add_14:
- push ax ;Save os type
- mov si,offset osadd_str7 ;Writing files message
- call write_linenorm
- inc opsys_count ;Inc count of operating systems
- xor bx,bx
- mov bl,opsys_count ;Get slot to place names
-
- mov al,1 ;Copy BIOS param blk to
- call copy_bpb ; new boot record.
- pop ax ;Get opsys type
- mov bp,ax
- call put_opsys
-
- mov si,offset osadd_err6 ;Error writing files
- jc jmp_osadd_error
-
- mov cx,4
- mov si,offset opsys_table ;Find first empty entry in
- xor bx,bx ; the op sys table.
- osadd_add_32:
- inc bl
- cmp byte ptr [si],80h
- jae osadd_add_33
- add si,NEXT_OSENTRY
- loop osadd_add_32
- osadd_add_33:
- mov cx,opsys_ostype ;Get DOS file config
- mov ax,bp ;Copy the op sys name from
- call copy_os_name ; the OEM name in the boot.
- xor ax,ax
- mov local_changed,1
- ret
- osadd_error:
- call scroll_half ;Clear screen
- call write_error ;Print error message
- stc
- ret
- osadd_add_opsys endp
-
- ;--------------------------------------------------------------------
- ; OSADD DEL OPSYS - Deletes an operating system from the disk.
- ;--------------------------------------------------------------------
- osadd_del_opsys proc near
- mov si,offset osadd_err2 ;Delete. Don't delete active
- cmp opsys_count,1 ; OS files.
- jbe osadd_error
-
- call get_ostype ;Query user for opsys
- mov cx,4
- mov si,offset osadd_err7 ;Check to see if os is in use
- mov di,offset ostype1
- osadd_del_opsys_1:
- cmp [di],bl
- je osadd_error
- add di,NEXT_ENTRY
- loop osadd_del_opsys_1
-
- call delete_opsys ;Erase op sys files
- osadd_del_opsys_exit:
- dec opsys_count
- xor ax,ax
- mov local_changed,1
- ret
- osadd_del_opsys endp
-
- ;--------------------------------------------------------------------
- ; OSADD REN OPSYS - Renames an operating system on the disk.
- ;--------------------------------------------------------------------
- osadd_ren_opsys proc near
- call get_ostype ;Query user for OP SYS
- or bl,bl
- je jmp_osadd_1
-
- push di ;Save ptr to op sys name
- mov si,offset osadd_namestr
- xchg di,si
- mov cx,8 ;Only 8 characters in name
- rep movsb
- mov si,offset osadd_str4 ;Print old OS name
- call write_linenorm
-
- mov si,offset osadd_str5 ;Prompt user for new OS name
- call write_linenorm
- mov dx,0a29h
- mov al,8 ;8 characters
- call entry_box
-
- pop di ;Get pointer to table entry
- mov si,bx ;Copy ptr to new name
- rep movsb ;Copy name
- xor ax,ax
- stosb ;Terminate name
- mov local_changed,1
- jmp_osadd_1:
- xor ax,ax
- ret
- osadd_ren_opsys endp
-
- ;--------------------------------------------------------------------
- ; OSADD EXIT - Sets the exit flag to return from this submenu
- ;--------------------------------------------------------------------
- osadd_exit proc near
- cmp local_changed,0
- clc
- je osadd_exit_1
- mov si,offset mboot_name ;Open the MBOOT.SYS file to
- call make_filename ; write opsys information.
-
- mov si,dx ;Copy ptr to ASCIIZ filename
- xor cx,cx
- call set_attributes ;Clear file attributes
- mov ax,3d02h
- int 21h
- jc osadd_exit_error
-
- mov bx,ax ;Copy file handle
- mov ax,4200h ;Move file ptr to os table
- mov dx,inst_boot_ptr
- xor cx,cx
- int 21h
- mov ah,40h ;Write boot op sys data
- mov dx,offset opsys_table
- mov cx,inst_boot_size
- int 21h
- jc osadd_exit_error
-
- mov ah,3eh ;Close file
- int 21h
- mov dx,si
- mov cx,SYSFILE_ATTR
- call set_attributes
- jc osadd_exit_error
- osadd_exit_1:
- mov al,-1 ;Set exit flag
- ret
- osadd_exit_error:
- mov si,offset osadd_err11
- stc
- jmp short osadd_exit_1
- osadd_exit endp
-
- main_osadd endp
-
- ;--------------------------------------------------------------------
- ; MAIN DEFAULTS - Sets boot default values
- ;--------------------------------------------------------------------
- def_string1 db 20,08,"Current Defaults",0
- def_string2 db 25,10,"Default Session:",0
- def_string3 db 25,12,"Default Timeout:",0
- def_string4 db 46,12,"Seconds",0
- def_string6 db 15,14,"Enter Timeout Value in Seconds",0
-
- default_msg1 db "Defaults Not Changed",0
- default_msg2 db "No Default Session",0
- default_msg3 db "Indefinite ",0
- default_err1 db "Invalid number",0
-
- local_timeout dw 0
- local_default db 0
-
- def_chdef db "Change Default Session",0
- def_chtime db "Change Timeout",0
-
- default_table dw offset default_menu
- dw offset default_ch_def
- dw offset default_ch_time
- dw offset default_exit
- dw offset add_quit
-
- default_menu db 4,0 ;Number of choices, Selected
- db 30,22 ;Location of "Choices" prompt
- dw 0 ;Timeout value
- db 0,0 ;Col, Row of Timeout string
- db 25,17 ;Column, Row of menu item
- dw offset def_chdef ;Offset of menu text
- db 25,18
- dw offset def_chtime
- db 25,19
- dw offset return_text
- db 25,20
- dw offset quit_text
-
- main_defaults proc near
- assume cs:code,ds:code
- mov al,boot_default ;Copy system values to local
- mov local_default,al ; variables.
- mov ax,boot_timeout
- mov local_timeout,ax
- main_default_0:
- mov si,offset def_string1
- call write_linenorm
- mov si,offset def_string2
- call write_linenorm
- mov si,offset def_string3
- call write_linenorm
- mov si,offset def_string4
- call write_linenorm
- main_default_1:
- mov si,offset default_msg2 ;Point to no default msg
- xor bx,bx
- or bl,local_default ;Get pointer to default entry
- je main_default_3
- call get_entry
- mov si,bx
- main_default_3:
- mov dx,0a2ah ;Row 10, Col 42
- call write_line_at ;Write string
-
- mov ax,local_timeout ;Get timeout value
- or ax,ax
- jne main_default_4
- mov si,offset default_msg3 ;No timeout message
- mov dx,0c2ah
- call write_line_at
- jmp short main_default_5
- main_default_4:
- xor dx,dx ;Convert to seconds
- mov bx,18
- div bx
- mov dx,0c2ah ;Write default timeout
- call hex2asc
- main_default_5:
- mov si,offset default_table
- mov al,1
- call jump_menu
- cmp al,-1
- jne main_default_0
- mov al,local_changed
- ret
-
- ;--------------------------------------------------------------------
- ; DEFAULT CH DEF - Changes the default session
- ;--------------------------------------------------------------------
- default_ch_def proc near
- mov al,local_default ;To select default session,
- call get_session ; display menu of all
- ; sessions.
- jc default_ch_def_1 ;If carry set or no selection
- or bl,bl ; skip default set.
- jc default_ch_def_1
- mov local_default,bl ;Set new default
- mov local_changed,1
- default_ch_def_1:
- xor al,al
- ret
- default_ch_def endp
-
- ;--------------------------------------------------------------------
- ; DEFAULT CH TIME - Changes the default timeout.
- ;--------------------------------------------------------------------
- default_ch_time proc near
- mov si,offset def_string6
- call write_linenorm
-
- mov dx,0e2fh ;Set cursor
- mov al,3 ;Allow 3 characters
- call get_number
- jc default_ch_time_1 ;Carry set, error
-
- mov dx,18 ;Convert seconds to ticks
- mul dx
- mov local_timeout,ax
- mov local_changed,1
- call scroll_half
- ret
- default_ch_time_1:
- call scroll_half
- mov si,offset default_err1 ;Illegal number
- call write_error
- ret
- default_ch_time endp
-
- ;--------------------------------------------------------------------
- ; DEFAULT_EXIT - Copys the new default values to the boot table.
- ;--------------------------------------------------------------------
- default_exit proc near
- mov al,local_default ;Copy local value to system
- mov boot_default,al ; values.
- mov ax,local_timeout
- mov boot_timeout,ax
- mov al,-1
- ret
- default_exit endp
- main_defaults endp
-
- ;--------------------------------------------------------------------
- ; INST INSTALL - Installs MultiBoot on a system.
- ;--------------------------------------------------------------------
- install_msg1 db 15,9,"WARNING! You should back up your"
- db " disk before",0
- install_msg2 db 25,10,"installing MultiBoot.",0
-
- install_msg db 15,16,"Do You wish to install MultiBoot?",0
- install1_msg db 15,16,"Installing MultiBoot. Please wait.",0
- install_nomsg db "MultiBoot not installed",0
-
- install_err1 db "Operating system not found",0
- install_err2 db "Error writing operating system files",0
- install_err3 db "Error creating MBOOT.SYS",0
- install_err4 db "Error creating MultiBoot boot record",0
-
- main_install proc near
- assume cs:code,ds:code
- cmp installed_flag,0 ;See if already installed
- je install_0
- mov si,offset errmsg21
- jmp install_error1
- install_0:
- mov si,offset install_msg1
- call write_linenorm
- mov si,offset install_msg2
- call write_linenorm
- mov si,offset install_msg
- mov al,1 ;Set default to Yes
- call msg_box
- cmp bl,1 ;See if answer Yes
- je install_01
- mov si,offset install_nomsg ;Answer No, abort install.
- jmp install_error1
- install_01:
- mov si,offset install1_msg
- call write_linenorm
-
- mov al,drive_letter
- call get_opsys ;Get operating system
- mov si,offset install_err1
- jc jmp_install_error1
-
- mov bx,101h ;Write operating system with
- call put_opsys ; bootfile = LASTBOOT.BIN
- mov si,offset install_err2
- jc jmp_install_error1
-
- mov si,offset mboot_name ;Write Boot extend file
- call make_filename
- mov si,offset boot_extend_start
- mov cx,offset install_start - offset boot_extend_start
- mov ax,SYSFILE_ATTR
- mov no_DOS_flag,0
- call write_file
- mov no_DOS_flag,1
- mov si,offset install_err3
- jc jmp_install_error1
- ; Modify Multiboot boot record with data from original boot record.
- push ds ;Compute the amount of
- lds si,databuff_ptr ; boot data on old boot
- mov di,100h ; record. If too much,
- mov cx,ds:[si+1] ; don't install.
- add cx,3
- cmp byte ptr ds:[si],0e9h ;See if long jump
- je install_2
- cmp byte ptr ds:[si],0ebh ;See if short jmp
- je install_1
- pop ds
- jmp_install_error:
- jmp install_error ;If not a jump, error
- jmp_install_error1:
- jmp install_error1
- install_1:
- xor cx,cx
- mov cl,ds:[si+1] ;Get size of data area
- add cx,2 ;Add room for jmp
- install_2:
- cmp cx,offset bootcode - offset entry
- ja install_error
- rep movsb ;Copy boot data
- pop ds
- mov byte ptr cs:entry,0e9h ;Copy jump opcode
- mov dx,offset bootcode - 103h ;Compute the jump value
- mov word ptr cs:entry[1],dx
-
- mov ax,dos_version
- cmp ax,300h ;If DOS 2.x clear hidden sec
- ja install_3 ; count.
- mov bp,100h
- mov word ptr num_hidden_sec,0
- cmp ax,314h ;If DOS 3.0 - 3.2, clear high
- ja install_3 ; word.
- mov word ptr num_hidden_sec[2],0
- install_3:
- ; Write Multiboot boot record to target drive.
- mov al,drive_letter
- mov bx,offset entry ;Get ptr to boot record
- call put_bootrec
- mov si,offset install_err4
- jc install_error1
-
- mov cx,4
- mov si,offset opsys_table
- add si,OPSYS_TYPE
- mov bl,1
- install_4:
- cmp word ptr [si],100h ;See if OS/2 installed on
- je install_5 ; disk.
- inc bl
- add si,NEXT_OSENTRY
- loop install_4
- jmp short install_6
- install_5:
- call make_os_names
- call make_filename
- mov di,si
- mov dx,offset os2boot_aname
- call copy_file
- mov dx,di ;Hide boot file.
- mov cx,SYSFILE_ATTR
- call set_attributes
- install_6:
- mov changed_flag,0
- mov installed_flag,1 ;Set install flag
- xor al,al ;Clear error flag
- install_exit1:
- ret
- install_error:
- mov si,offset errmsg20
- install_error1:
- stc
- jmp short install_exit1
- main_install endp
-
- ;--------------------------------------------------------------------
- ; INST REMOVE - Removes Multiboot from a system.
- ;--------------------------------------------------------------------
- remove_msg db 15,16,"Do you wish to remove MultiBoot?",0
- remove1_msg db 15,16,"Removing MultiBoot. Please wait.",0
- remove_nomsg db "MultiBoot not removed",0
-
- main_remove proc near
- assume cs:code,ds:code
- ; Check to see if already installed
- cmp installed_flag,0 ;If not installed, don't
- jne remove_1 ; remove.
- mov si,offset errmsg23
- jmp remove_error1
- remove_1:
- mov si,offset remove_msg ;Verify remove request.
- mov al,1 ;Set default to Yes
- call msg_box
- cmp bl,1 ;See if answer Yes
- mov si,offset remove_nomsg
- jne remove_error1
-
- mov si,offset remove1_msg ;Indicate removing.
- call write_linenorm
-
- mov si,offset lastboot_name ;Read current op sys boot
- call make_filename ; record from the file.
- push es
- les si,databuff_ptr
- call read_file ;Read LASTBOOT.BIN
- pop es
- jc remove_error
- ;Write old boot record to boot sector
- mov al,drive_letter
- push ds
- lds bx,databuff_ptr ;Get ptr to data buffer
- call put_bootrec ;Write the boot record
- pop ds
- jc remove_error
-
- call fixup_fat ;Remove bad sectors in FAT
-
- mov si,offset mboot_name ;Delete MBOOT.SYS
- call delete_file
- mov si,offset lastboot_name ;Delete LASTBOOT.BIN
- call delete_file
-
- mov cx,4
- mov si,offset opsys_table ;Scan operating system table
- xor bx,bx ; deleteing the MBOOTOS files
- remove_2:
- inc bl
- cmp byte ptr [si],80h ;Is OS entry used?
- jae remove_3
- call delete_opsys
- remove_3:
- add si,NEXT_OSENTRY
- loop remove_2
-
- mov changed_flag,0
- mov installed_flag,0 ;Clear install flag
- call scroll_half ;Clear screen
- clc ;Clear error flag
- mov al,-1 ;Set terminate flag
- remove_exit1:
- ret
- remove_error:
- mov si,offset errmsg22
- remove_error1:
- stc
- mov al,0
- jmp short remove_exit1
- main_remove endp
-
- ;--------------------------------------------------------------------
- ; EXIT - Updates changes to installed files and exits program.
- ;--------------------------------------------------------------------
- exit_str0 db 15,14,"MultiBoot not installed.",0
- exit_str1 db 15,16,"Do you wish to install MultiBoot?",0
- exit_err1 db "Installed data incompatible with this version.",0
- exit proc near
- assume cs:code,ds:code
- cmp installed_flag,0 ;If not installed, ask if
- jne exit_1 ; prog should install.
- mov si,offset exit_str0
- call write_linenorm
- mov al,1 ;Default Yes
- mov si,offset exit_str1
- call msg_box
- cmp bl,1
- jne exit_3
- call main_install ;Install Multiboot
- jc exit_4
- jmp short exit_3
- exit_1:
- mov si,offset mboot_name ;Open the MBOOT.SYS file to
- call make_filename ; write updated information.
-
- mov si,dx ;Copy ptr to ASCIIZ filename
- xor cx,cx
- call set_attributes ;Clear file attributes
- mov ax,3d02h
- int 21h
- jc exit_3
-
- mov bx,ax ;Copy file handle
- mov ax,4200h ;Move file ptr to boot table
- mov dx,inst_data_ptr
- xor cx,cx
- int 21h
- mov ah,40h ;Write boot data
- mov dx,offset boot_data1
- mov cx,inst_data_size
- int 21h
-
- mov ax,4200h ;Move file ptr to boot table
- mov dx,inst_sess_ptr
- xor cx,cx
- int 21h
- mov ah,40h ;Write boot session data
- mov dx,offset boot_array
- mov cx,inst_sess_size
- int 21h
-
- mov ax,4200h ;Move file ptr to os table
- mov dx,inst_boot_ptr
- xor cx,cx
- int 21h
- mov ah,40h ;Write boot op sys data
- mov dx,offset opsys_table
- mov cx,inst_boot_size
- int 21h
-
- mov ah,3eh ;Close file
- int 21h
- mov dx,si
- mov cx,SYSFILE_ATTR
- call set_attributes
- exit_3:
- mov al,-1 ;Set flag to end program
- exit_4:
- ret
- exit endp
-
- ;--------------------------------------------------------------------
- ; QUIT - Quits program without changing installed files.
- ;--------------------------------------------------------------------
- quit_msg db 20,15,"Do you wish to discard all changes made?",0
- quit_msg1 db 20,9,"You have choosen to leave MultiBoot without",0
- quit_msg2 db 17,10,"making your changes permanent. To make your",0
- quit_msg3 db 17,11,"changes permanent, answer No, then select",0
- quit_msg4 db 17,12,"Update and Exit MultiBoot on the Main Menu.",0
- quit proc near
- assume cs:code,ds:code
- cmp changed_flag,0
- je quit_1
- mov si,offset quit_msg1 ;Tell user what he/she is
- call write_linenorm ; doing.
- mov si,offset quit_msg2
- call write_linenorm
- mov si,offset quit_msg3
- call write_linenorm
- mov si,offset quit_msg4
- call write_linenorm
- mov si,offset quit_msg
- mov al,2 ;Set default to No.
- call msg_box
- mov al,0
- cmp bl,2 ;See if No.
- je quit_2
- quit_1:
- call scroll_half
- mov al,-1 ;Set terminate prog flag
- quit_2:
- ret
- quit endp
-
- ;--------------------------------------------------------------------
- ; JUMP MENU - Displays a menu then calls the routines pointed to in
- ; in the jump table.
- ; Entry: AL - Default selection
- ; SI - Offset of jump table
- ;--------------------------------------------------------------------
- jump_menu proc near
- mov bp,[si] ;Display main menu.
- mov byte ptr [bp+MENU_SELECTED],al
- push si
- call menu
- pop si
- jnc jump_menu_2 ;Esc pressed -> Assume quit
- jump_menu_1:
- mov bl,[bp] ;BL = last choice
- jump_menu_2:
- or bl,bl ;If no cmd, assume quit.
- je jump_menu_1 ;Convert menu choice to
- shl bx,1 ; index into jump table of
- add bx,si ; routines.
- call scroll_half ;Clear lower half of screen.
- call [bx] ;Call routine.
- ret
- jump_menu endp
-
- ;--------------------------------------------------------------------
- ; GET SESS NAME - Querys the user for a session name
- ; Entry: BL - Ptr to session entry
- ; Exit: CF - Set if Ctrl-C entered.
- ;--------------------------------------------------------------------
-
- get_sess_name proc near
- mov ax,offset local_add1 ;Compute entry into
- call get_entry1 ; local table.
- mov bp,bx ;Save ptr to table entry
- call scroll_half ;Clear screen
-
- mov dx,0806h ;Write header.
- mov si,offset inst_text1
- call write_line_at
-
- mov di,bp ;Write session data to screen
- mov dx,0a06h
- call disp_session
-
- mov si,offset add_str_msg1 ;Print message on how to
- call write_linenorm ; return to add menu.
-
- mov si,offset add_str4 ;Prompt user for Session name
- call write_linenorm
- mov dx,0e34h
- mov al,offset auto1 - offset name1 - 1
- call entry_box
- jc get_sess_exit
- mov si,bx
- mov di,bp ;Copy title to local buffer.
- rep movsb
- mov byte ptr [di],0 ;Terminate string
- mov dh,14
- call clear_line
- get_sess_exit:
- ret
- get_sess_name endp
-
- ;--------------------------------------------------------------------
- ; ADD FILE - Asks user for a filename and verifys its correctness.
- ; Entry: SI - Pointer to filename (CONFIG or AUTOEXEC)
- ;--------------------------------------------------------------------
- add_file_str db 05,14,"Enter the file that will become the "
- add_file_name db 12 dup (" ")
- add_file_str1 db " file:",0
-
- add_file_str2 db 05,14,"The file "
- add_file_name0 db 12 dup (" ")
- db "does not exist.",0
- add_file_str3 db 05,16,"Do you want to copy the current "
- add_file_name1 db 12 dup (" ")
- db " file into this one?",0
-
- add_file_err1 db "A filename must be entered",0
-
- add_file_err2 db "The filename "
- add_file_name2 db 12 dup (" ")
- db " cannot be used",0
-
- add_file_err3 db "Error creating file",0
- add_file_err4 db "This file does not exist",0
-
- add_file proc near
- push si ;Save ptr to filename
-
- mov dh,10
- call clear_line
- mov di,local_selection ;Write session data to screen
- call disp_session
-
- mov al," " ;Clear file names from strings
- mov di,offset add_file_name
- mov cx,12
- rep stosb
- mov di,offset add_file_name0
- mov cx,12
- rep stosb
- mov di,offset add_file_name1
- mov cx,12
- rep stosb
- mov di,offset add_file_name2
- mov cx,12
- rep stosb
-
- pop bp ;Get ptr to filename
- mov si,bp
- mov di,offset add_file_name
- call fn2asciiz
- mov bx,cx
- mov byte ptr [bx+si]," " ;Erase zero
-
- push si ;Copy filename to other
- mov di,offset add_file_name1 ; messages
- push cx
- rep movsb
- pop cx
- pop si
- mov di,offset add_file_name2
- rep movsb
- add_file_1:
- mov dh,14 ;Clear line for query.
- call clear_line
-
- mov si,offset add_file_str ;Assemble prompt message using
- call write_linenorm ; destination filename
- mov si,offset add_file_str1 ; provided.
- call write_linenorm
-
- mov si,offset add_str_msg1 ;Print message on how to
- call write_linenorm ; return to add menu.
-
- mov dx,0e3ch ;Get filename max char = 12
- mov al,12
- call entry_box
- pushf
- mov dh,22 ;Erase ctl-break message
- call clear_line
- popf
- jnc add_file_11
- jmp add_file_4
- add_file_11:
- or cx,cx ;If zero length string, error
- mov si,offset add_file_err1
- je add_file_error
- mov si,cx
- mov byte ptr [bx+si],0 ;Terminate name with zero
-
- push cx
- mov si,bx
- mov di,offset temp_buff
- call asciiz2fn
- mov di,bp ;Make sure destination name
- mov cx,11 ; not used.
- repe cmpsb
- pop cx
- jne add_file_2
- mov si,offset add_file_err2 ;Can't use dest filename
- add_file_error:
- call write_error
- jmp short add_file_1
- add_file_2:
- mov si,offset temp_buff ;Create filename from 8.3
- call make_filename ; format.
-
- mov ax,3d00h ;Open file, read only
- int 21h
- jnc add_file_3
-
- mov si,offset temp_buff ;Add filename to error msg
- mov di,offset add_file_name0
- call fn2asciiz
- mov bx,cx
- mov byte ptr [bx+si]," " ;Erase terminating zero
-
- mov si,offset add_file_err4 ;Indicate to the user that
- call write_error ; the file can't be found.
-
- mov si,bp ;Get destination file
- call find_file
- jc add_file_1 ;If no file, skip copy question
-
- mov dh,14 ;File does not exist, prompt
- call clear_line ; user for choices.
-
- mov si,offset add_file_str2
- call write_linenorm
- mov al,1 ;Set default answer
- mov si,offset add_file_str3 ;See if user wants to copy
- call msg_box ; the current autoexec or
- mov dh,14 ; config file to this one.
- call clear_line
- cmp bl,1 ;If not Yes, skip copy.
- je add_file_21
- jmp add_file_1
- add_file_21:
- mov si,bp
- mov di,offset temp_buff+40
- call make_filename
- mov di,offset filename_buff ;Copy autoexec or config to
- call copy_file ; new filename
- mov si,offset add_file_err3
- jc add_file_error
- add_file_3:
- mov si,offset temp_buff ;Point SI to new filename
- clc
- add_file_4:
- ret
- add_file endp
-
- ;--------------------------------------------------------------------
- ; GET SESSION - Displays a session menu.
- ; Entry: AL - Default session.
- ; Exit: BX - Session number selected.
- ;--------------------------------------------------------------------
- get_sess_str db 20,7,"Select Session",0
- get_session proc near
- mov bx,1 ;If only one session, don't
- cmp session_count,1 ; ask user to pick.
- ja get_session_1
- jmp short get_session_3
- get_session_1:
- mov bp,offset boot_menu
- get_session_2:
- push ax
- call scroll_half ;Clear screen.
- mov si,offset get_sess_str ;Display message
- call write_linenorm
- pop ax
- mov [bp+MENU_SELECTED],al ;Set default
- mov word ptr [bp+MENU_TIMEOUT],0
- call menu
- get_session_3:
- pushf ;Carry indicates <esc> pressed
- call scroll_half
- popf
- ret
- get_session endp
-
- ;--------------------------------------------------------------------
- ; GET OSTYPE - Prompts the user to select an operating system.
- ; Exit: BL - OS selection
- ;--------------------------------------------------------------------
- os_menu_str1 db 05,14,"Select Operating System",0
-
- os_menu db 4,1 ;Number of choices, Selected
- db 30,22 ;Location of "Choices" prompt
- dw 0 ;Timeout value
- db 0,0 ;Col, Row of Timeout string
- db 25,17 ;Column, Row of menu item
- dw offset os_name1 ;Offset of menu text
- db 25,18
- dw offset os_name2
- db 25,19
- dw offset os_name3
- db 25,20
- dw offset os_name4
-
- get_ostype proc near
- mov si,offset os_menu_str1 ;Prompt user for the
- call write_linenorm ; operating system
- mov bp,offset os_menu ;Operating system menu
- call menu
- pushf
- mov cx,0e00h ;Clear screen
- mov dx,1950h
- call scroll_block
- xor di,di
- popf ;If <esc> no choice made
- jc get_ostype_exit
- call get_os_entry
- clc
- get_ostype_exit:
- ret
- get_ostype endp
-
- ;--------------------------------------------------------------------
- ; MAKE FILENAME - Adds drive and directory stuff to 8.3 filename.
- ; Entry: SI - Pointer to filename
- ; Exit: SI = DX - Pointer to filename
- ;--------------------------------------------------------------------
- make_filename proc near
- push cx
- push di
- mov di,offset filename_buff
- push di
- mov al,drive_letter ;Copy drive letter
- stosb
- mov ax,"\:" ;Add DOS dir stuff
- stosw
- call fn2asciiz ;Append filename
- pop si
- mov dx,si ;Copy pointer to filename
- pop di
- pop cx
- ret
- make_filename endp
-
- ;--------------------------------------------------------------------
- ; READ FILE - Opens a file, reads the data, and closes the file.
- ; Entry: DS:DX - Pointer to source ASCIIZ filename
- ; ES:SI - Pointer to data buffer
- ; Exit: CX - Bytes read
- ;--------------------------------------------------------------------
- read_file proc near
- call set_crit_vec ;Set crit vec to int routine
- mov ax,3d00h ;Open file, read only
- int 21h
- jc read_file_exit
- mov bx,ax ;Copy file handle
-
- push ds ;Read file into data buffer
- push es
- pop ds
- mov dx,si
- mov cx,65013 ;Buffer size
- mov ah,3fh ;Read file
- int 21h
- mov cx,ax ;Save bytes read
- pop ds
- jc read_file_exit
-
- mov ah,3eh ;Close file
- int 21h
- read_file_exit:
- call reset_crit_vec ;Restore critical error vec
- ret
- read_file endp
-
- ;--------------------------------------------------------------------
- ; WRITE FILE - Creates a file and writes data to the file
- ; Entry: AX - Attributes for destination file
- ; CX - Size of data
- ; DS:DX - Pointer to desination ASCIIZ filename
- ; ES:SI - Pointer to data
- ;--------------------------------------------------------------------
- write_file proc near
- push cx ;Save size of data
- call set_crit_vec ;Set crit vec to int routine
- mov cx,ax ;Copy attributes
- mov ah,3ch ;Create file.
- int 21h
- mov bx,ax ;Copy file handle
- pop cx ;Restore data size
- jc write_file_exit
-
- push ds
- push es
- pop ds
- mov dx,si ;Copy pointer to data
- mov ah,40h ;Write file
- int 21h
- pop ds
- jc write_file_exit
- mov ah,3eh ;Close file
- int 21h
- write_file_exit:
- call reset_crit_vec ;Restore critical error vec
- ret
- write_file endp
-
- ;--------------------------------------------------------------------
- ; READ ABSOLUTE - Reads sectors from the disk.
- ; Entry: AL - Letter of drive to read
- ; CX - Number of sectors to read.
- ; SI,DX - Sector to start read (SI only used on huge disks)
- ; DS:BX - Pointer to data buffer.
- ;--------------------------------------------------------------------
- read_abs_hstruc = $ ;Needed for >32M disks
- read_abs_start dd 0 ;Starting sector
- read_abs_cnt dw 0 ;Number of sectors to read
- read_abs_dbp dd 0 ;Data buffer ptr
-
- read_absolute proc near
- push bx
- push cx
- push ds
- call set_crit_vec ;Set crit vec to int routine
- call huge_disk_check
- jc read_abs_2
- je read_abs_1
- push ds ;Save ptr to data buffer
- push bx
- push cs
- pop ds
- mov bx,offset read_abs_hstruc
- mov [bx],dx ;More than 64K sectors
- mov [bx+2],si ; -> huge disk uses a
- mov [bx+4],cx ; different format
- pop [bx+6] ; than std int 25h.
- pop [bx+8]
- mov cx,-1
- read_abs_1:
- sub al,'A' ;Convert to hex (0 base)
- int 25h ;DOS Absolute Disk Read
- pop bx ;Clean off old flags
- cld
- read_abs_2:
- call reset_crit_vec ;Restore critical error vec
- pop ds
- pop cx
- pop bx
- ret
- read_absolute endp
-
- ;--------------------------------------------------------------------
- ; WRITE ABSOLUTE - Writes sectors to the disk.
- ; Entry: AL - Letter of drive to write
- ; CX - Number of sectors to write
- ; SI,DX - Sector to start write (SI only used on huge disks)
- ; DS:BX - Pointer to data buffer.
- ;--------------------------------------------------------------------
- write_absolute proc near
- push bx
- push cx
- push ds
- call set_crit_vec ;Set crit vec to int routine
- call huge_disk_check
- jc write_abs_2
- je write_abs_1
- push ds ;Save data buffer pointer
- push bx
- push cs
- pop ds
- mov bx,offset read_abs_hstruc
- mov [bx],dx ;More than 64K sectors
- mov [bx+2],si ; -> huge disk uses a
- mov [bx+4],cx ; different format
- pop [bx+6] ; than std int 26h.
- pop [bx+8]
- mov cx,-1
- write_abs_1:
- sub al,'A' ;Convert to hex (0 based)
- int 26h ;DOS Absolute Disk Write
- pop bx ;Clean off old flags
- cld
- write_abs_2:
- call reset_crit_vec ;Restore critical error vec
- pop ds
- pop cx
- pop bx
- ret
- write_absolute endp
-
- ;--------------------------------------------------------------------
- ; HUGE DISK CHECK - Checks if disk is greater than 32 Meg
- ; Entry: AL - Disk to check
- ; Exit: ZF - Clear if > 32 Meg disk
- ; CF - Set if error
- ; DI - Sectors per cluster
- ;--------------------------------------------------------------------
- last_disk_read db -1
- last_disk_huge db 0
- last_disk_spc dw 0
- huge_disk_check proc near
- push ax
- push bx
- push cx
- push dx
- cmp al,last_disk_read ;Save last disk checked, if
- jne huge_disk_check_1 ; same as last disk, just
- mov di,last_disk_spc ; get saved answer.
- cmp last_disk_huge,0
- jmp short huge_disk_check_3
- huge_disk_check_1:
- mov last_disk_read,al
- mov last_disk_huge,0
- mov dl,al ;Copy disk number
- sub dl,40h ;Convert ASCII to hex (1 base)
- mov ah,36h ;DOS Get Free disk space
- int 21h
- cmp ax,-1
- jne huge_disk_check_2
- mov last_disk_read,-1
- jmp short huge_disk_check_4
- huge_disk_check_2:
- mov di,ax ;Save sectors per cluster
- mov last_disk_spc,di
- mul dx
- or dx,dx ;See if more than 64K sectors
- je huge_disk_check_3
- mov last_disk_huge,1
- huge_disk_check_3:
- clc
- huge_disk_check_4:
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- huge_disk_check endp
-
- ;--------------------------------------------------------------------
- ; COPY FILE - Copies a file
- ; Entry: DX - Pointer to source ASCIIZ filename
- ; DI - Pointer to destination ASCIIZ filename
- ;--------------------------------------------------------------------
- copy_file proc near
- push es
- les si,databuff_ptr
- call read_file
- jc copy_file_exit
- mov dx,di ;Point to new file name
- xor ax,ax ;Normal attributes
- call write_file
- copy_file_exit:
- pop es
- ret
- copy_file endp
-
- ;--------------------------------------------------------------------
- ; DELETE FILE - Deletes file
- ; Entry: SI - Pointer to filename in 8.3 format
- ;--------------------------------------------------------------------
- delete_file proc near
- push cx
- push si
- call make_filename ;Convert to ASCIIZ
- xor cx,cx
- call set_attributes
-
- mov ah,41h ;DOS Delete File
- int 21h
- pop si
- pop cx
- ret
- delete_file endp
-
- ;--------------------------------------------------------------------
- ; SET ATTRIBUTES - Sets file attribute flags.
- ; Entry: CX - file attributes
- ; DX - pointer to ASCIIZ filename.
- ;--------------------------------------------------------------------
- set_attributes proc near
- mov ax,4301h ;DOS Set Attributes
- int 21h
- ret
- set_attributes endp
-
- ;--------------------------------------------------------------------
- ; MAKE BOOTFILE - Writes the boot record data in the data buffer
- ; to a file on the disk.
- ; Entry: SI - Destination filename in 8.3 format
- ;--------------------------------------------------------------------
- make_bootfile proc near
- push es
- les si,databuff_ptr ;Get ptr to boot record
- mov ax,SYSFILE_ATTR ;Get attributes
- mov cx,512 ;Boot file size
- call write_file
- pop es
- ret
- make_bootfile endp
-
- ;--------------------------------------------------------------------
- ; GET BOOTREC - Reads the boot record into the data buffer.
- ; Entry: AL - Letter of drive to read
- ;--------------------------------------------------------------------
- get_bootrec proc near
- mov cx,1 ;Read 1 sector
- xor dx,dx ;Read 1st sector
- xor si,si
- push ds
- lds bx,databuff_ptr ;Get ptr to data buffer
- call read_absolute ;DOS Absolute Disk Read
- pop ds
- ret
- get_bootrec endp
-
- ;--------------------------------------------------------------------
- ; PUT BOOTREC - Writes the boot record with data from the data buffer.
- ; Entry: AL - Drive letter to write
- ; DS:BX - Segment:Offset of boot record to write.
- ;--------------------------------------------------------------------
- put_bootrec proc near
- mov cx,1 ;Write 1 sector
- xor dx,dx ;Write 1st sector
- xor si,si
- call write_absolute ;DOS Absolute Disk Write
- ret
- put_bootrec endp
-
- ;--------------------------------------------------------------------
- ; COPY BPB - Copies a BIOS parameter block.
- ; Entry: AL - 0 = to MBOOT boot rec, 1 = from MBOOT bootrec
- ;--------------------------------------------------------------------
- copy_bpb proc near
- push cx
- push ds
- push es
- les di,databuff_ptr ;Offset of boot rec BPB
- add di,11
- mov si,10bh ;Offset of MBOOT BPB
- or al,al
- jne copy_bpb_1
- xchg si,di ;Exchange pointers.
- push es
- push ds
- pop es
- pop ds
- copy_bpb_1:
- mov cx,32 ;Copy BPB
- rep movsb
- or al,al
- je copy_bpb_2
- cmp cs:[drive_letter],"C"
- jb copy_bpb_2
- cmp byte ptr es:[1fdh],0
- jne copy_bpb_2
- mov byte ptr es:[1fdh],80h
- copy_bpb_2:
- pop es
- pop ds
- pop cx
- ret
- copy_bpb endp
-
- ;--------------------------------------------------------------------
- ; COPY OS NAME - Reads the operating system name from the OEM field
- ; of the boot record.
- ; Entry: AL - Operating system type.
- ; BL - Operating system number.
- ;--------------------------------------------------------------------
- copy_os_name proc near
- call get_os_entry ;Get index into the os table
- mov word ptr [di+OPSYS_TYPE],cx
- push di
- push si
- push ds
- lds si,databuff_ptr ;Copy the OEM name to the
- add si,3 ; field pointed to by
- mov cx,8 ; DI.
- rep movsb
- pop ds
- pop si
- pop di
- add di,9
- mov si,offset ibmbio_name ;Copy the proper names of the
- cmp al,1 ; os files to the os table.
- jb copy_os_name_1
- ja copy_os_name_2
- mov si,offset iosys_name
- copy_os_name_1:
- mov cx,22 ;Copy both names at the same
- rep movsb ; time.
- copy_os_name_2:
- ret
- copy_os_name endp
-
- ;--------------------------------------------------------------------
- ; GET OPSYS - Gets the operating system files from a disk
- ; Entry: AL - Drive letter to read operating system
- ; Exit: CF - Set if error
- ; AL - Return code:
- ; 0 - PC DOS 3 - MultiBoot 6 - Read error
- ; 1 - MS DOS 4 - Unbootable 7 - OS too large
- ; 2 - OS/2 disk 5 - Unknown
- ; AH - 1 if OS/2 system on disk
- ; CX - Number of consecutive clusters used by DOS
- ; DX - Number of consecutive clusters used by IO.SYS
- ; CF - Set if error
- ; opsys_ostype, iosys_size, doscom_size updated.
- ;--------------------------------------------------------------------
- get_opsys proc near
- mov bl,drive_letter
- push bx
- mov drive_letter,al
- call check_os ;See what type of OS loaded
- mov opsys_ostype,bx ; on disk.
- mov bp,offset ibmbio_name
- cmp al,1 ;If PC DOS use different
- ja get_opsys_error1 ; names from MS DOS
- jb get_opsys_1
- mov bp,offset iosys_name
- get_opsys_1:
- push ax
- push cx
- push dx
- mov iosys_size,0
- mov si,bp ;Copy ptr to first name
- call make_filename
- push es
- les si,databuff_ptr
- add si,512 ;Skip past boot data
- call read_file
- pop es
- mov al,6
- jc get_opsys_error
- mov al,7 ;Error, os file too big
- cmp cx,65013
- jae get_opsys_error
- mov iosys_size,cx
-
- mov doscom_size,0
- mov si,bp ;Copy ptr to first name
- add si,11 ;Point to second name
- call make_filename
- push es
- les si,databuff1_ptr
- call read_file
- pop es
- mov al,6
- jc get_opsys_error
- mov al,7 ;Error, os file too big
- cmp cx,65013
- jae get_opsys_error
- mov doscom_size,cx ;Save DOSCOM file size
- pop dx
- pop cx
- pop ax
- clc
- get_opsys_exit1:
- mov bp,ax
- pop ax
- mov drive_letter,al ;Restore target disk letter
- mov ax,bp
- ret
- get_opsys_error:
- add sp,6 ;Clean off stack
- get_opsys_error1:
- stc
- jmp short get_opsys_exit1
- get_opsys endp
-
- ;--------------------------------------------------------------------
- ; CHECK SIZE - Compares the size of two numbers to the nearest sector
- ; Entry: BX - File 1 size in bytes
- ; CX - File 2 size in bytes
- ; Exit: Flags set from compare
- ;--------------------------------------------------------------------
- check_size proc near
- push ax
- mov ax,bx
- xor dx,dx ;Clear high word
- mov bx,512 ;Div by sector size
- div bx
- xchg ax,cx ;Get second number
- xor dx,dx
- div bx ;Div second number
- cmp ax,cx ;Compare results
- pop ax
- ret
- check_size endp
- ;--------------------------------------------------------------------
- ; PUT OPSYS - Saves the operating system to files on the disk
- ; Entry: BL - Operating system number
- ; BH - 1 = Make bootfile name LASTBOOT.BIN
- ;--------------------------------------------------------------------
- put_opsys proc near
- push bp
- call make_os_names ;Generate names for files
- push si
- or bh,bh
- je put_opsys_1
- mov si,offset lastboot_name
- put_opsys_1:
- call make_filename
- xor cx,cx
- call set_attributes
- call make_bootfile ;Write boot rec to file.
- pop si
-
- add si,11 ;Point to iosys name
- mov bp,si
- call make_filename
- xor cx,cx
- call set_attributes
- push es
- les si,databuff_ptr ;Load ptr to SYS file data
- add si,512
- mov cx,iosys_size ;Set size
- mov ax,SYSFILE_ATTR ;Set attributes
- call write_file ;Write IO.SYS file
- pop es
- jc put_os_exit
-
- mov si,bp
- add si,11 ;Point to doscom name
- call make_filename
- xor cx,cx
- call set_attributes
- push es
- les si,databuff1_ptr
- mov cx,doscom_size ;Set size
- mov ax,SYSFILE_ATTR ;Set attributes
- call write_file ;Write MSDOS.COM file
- pop es
- put_os_exit: clc
- pop bp
- ret
- put_opsys endp
-
- ;--------------------------------------------------------------------
- ; DELETE OPSYS - Deletes the MBOOT operating system files from the disk.
- ; Entry: BL - Operating system number
- ;--------------------------------------------------------------------
- delete_opsys proc near
- push si
- push bx
- call make_os_names ;Get names of op sys files
- call delete_file ;Delete boot rec file
- add si,11
- call delete_file ;Delete IO.SYS file
- add si,11
- call delete_file ;Delete MSDOS.COM file
- pop bx
- call get_os_entry
- mov byte ptr [di],80h ;Delete entry in opsys table
- pop si
- ret
- delete_opsys endp
- ;--------------------------------------------------------------------
- ; CHECK OS - Reads the boot record to determine the type of operating
- ; system currently loaded.
- ; Exit: AL - Type of operating system loaded:
- ; 0 - PC DOS 2 - OS/2 4 - Not a bootable disk
- ; 1 - MS DOS 3 - MultiBoot 5 - Unknown OS type
- ; AH - 1 if OS/2 system files are loaded (if AL = 0, 1, or 2)
- ; BX - DOS System file configuration:
- ; 20 = Consec files, sectors
- ; 30 = IO.SYS Consec. MSDOS.SYS not consec
- ; 40 = IO.SYS not Consec
- ; CX - Number of consecutive clusters used by DOS
- ; DX - Number of consecutive clusters used by IO.SYS
- ;--------------------------------------------------------------------
- check_os proc near
- mov al,drive_letter
- call get_bootrec ;Load boot record.
- mov ax,00ffh
- jc check_os_exit ;If error loading, exit
-
- mov di,offset mboot_name ;Check if Multiboot is
- call find_filename ; installed on drive.
- mov ax,3 ;Multiboot installed
- jnc check_os_exit
-
- xor bp,bp
- mov di,offset os2ldr_name ;See if OS/2 disk
- call find_filename
- mov ax,2 ;OS/2 disk
- jnc check_os_exit
-
- mov di,offset ibmbio_name ;See if PC DOS disk
- call find_filename
- jnc check_os_1
-
- inc bp
- mov di,offset iosys_name ;See if MS DOS disk
- call find_filename
- mov ax,5 ;Error, unknown DOS type
- jc check_os_exit
- check_os_1:
- mov ax,bp
- call get_sys_size ;Get size of DOS file area
- mov bx,ax ; on disk.
- mov ax,4
- jc check_os_exit ;CF=1 not bootable.
- check_os_2:
- push bx ;Save DOS config
- push cx ;Save DOS size
- push dx ;Save IO.SYS size
- mov si,offset os2ldr_name ;See if OS/2 system files
- call find_first ; on disk. Start with OS2LDR
- jc check_os_3
- mov si,offset os2knl_name ;Look for OS2KRNL
- call find_first
- jc check_os_3
- mov si,offset os2boot_aname ;Look for \OS2\SYSTEM\BOOT.OS2
- mov al,drive_letter
- mov [si],al
- call find_first1
- jc check_os_3
- or bp,0100h ;Set OS/2 found flag
- check_os_3:
- mov ax,bp ;Get OS type
- pop dx ;Get IO.SYS size
- pop cx ;Get DOS size
- pop bx ;Get DOS config
- check_os_exit:
- ret
- check_os endp
-
- ;--------------------------------------------------------------------
- ; GET SYS SIZE - Computes the number of consecutive clusters assigned
- ; to the system files at the beginning of the disk.
- ; Entry: AL - Type of operating system loaded:
- ; 0 - PC DOS 1 - MS DOS
- ; The Boot record for the desired disk must be in the data
- ; buffer.
- ; Exit: AX - DOS System file configuration:
- ; 20 = Consec files, sectors
- ; 30 = IO.SYS consec. MSDOS.SYS not consec
- ; 40 = IO.SYS not consec
- ; CX - Number of consecutive clusters
- ; DX - Number of consecutive clusters used by IO.SYS
- ; CF - Set on error
- ;--------------------------------------------------------------------
- sys_size_os db 0
- sys_size_bio dw 0
- sys_size_dos dw 0
-
- get_sys_size proc near
- push bp
- mov sys_size_os,al
- call get_disk_ptrs ;Compute disk pointers.
- mov dx,word ptr root_pointer
- mov si,word ptr root_pointer[2]
- mov cx,1 ;Read only one sector of root
- lds bx,databuff_ptr ;Use buffer past boot rec
- add bx,512
- mov al,cs:drive_letter
- call read_absolute ;Read 1st part of root dir
- mov di,offset ibmbio_name
- cmp cs:sys_size_os,0 ;Get proper system file names
- je get_sys_size_2 ; for DOS.
- mov di,offset iosys_name
- get_sys_size_2:
- mov si,bx ;Copy ptr to start of root
- mov cx,11
- repe cmpsb ;See if first file is IO.SYS
- je get_sys_size_3
- get_sys_size_err:
- stc
- jmp get_sys_size_exit1
- get_sys_size_3:
- mov ax,[bx+1ah] ;Get starting cluster
- cmp ax,2 ;See if starts in 1st cluster
- je get_sys_size_4
- xor dx,dx ;No free clusters
- xor cx,cx
- mov ax,50h
- jmp get_sys_size_exit1
- get_sys_size_4:
- mov cs:sys_size_bio,ax
- add si,21
- mov cx,11
- repe cmpsb ;See if 2nd file is MSDOS.SYS
- jne get_sys_size_err
- mov ax,[bx+3ah] ;Get starting cluster
- mov cs:sys_size_dos,ax
-
- mov dx,word ptr cs:fat_pointer
- mov si,word ptr cs:fat_pointer[2]
- mov al,cs:drive_letter
- mov cx,4 ;Read four sectors
- call read_absolute ;Read FAT
- mov ax,ds
- push cs
- pop ds
- push fat_seg_low ;Save FAT ptr for installed
- add ax,20h ; code.
- mov fat_seg_low,ax ;Point to loaded FAT table
- mov bx,sys_size_bio
- mov bp,offset temp_buff
- call get_fat_chain ;Get consec clusters
- pushf
- xor ax,ax
- mov al,sec_per_cluster ;Convert cluster count into
- mul cx ; sector count
- mov di,ax
- xchg cx,ax
- popf
- mov ax,40h
- jc get_sys_size_exit ;If non-consecutive, DOS 4
-
- inc bx
- mov si,bx ;Save ending cluster
- mov bx,sys_size_dos
- cmp si,bx ;If IO.SYS and MSDOS.SYS are
- mov ax,30h ; not consecutive, DOS 3.
- jne get_sys_size_exit
- call get_fat_chain
- pushf
- xor ax,ax ;Convert cluster count into
- mov al,sec_per_cluster ; sector count.
- mul cx
- mov cx,ax
- add cx,di ;Add sector sizes
- mov dx,di ;Copy IO.SYS sector size
- popf
- mov ax,30h
- jc get_sys_size_exit
- mov ax,20h ;Both consecutive, DOS 2
- get_sys_size_exit:
- push ax
- xchg ax,dx
- cwd
- div targ_sec_per_cluster ;Convert sectors to clusters
- or dx,dx ; on target disk.
- je get_sys_size_e1
- inc ax
- get_sys_size_e1:
- push ax
- xchg ax,cx
- cwd
- div targ_sec_per_cluster
- or dx,dx
- je get_sys_size_e2
- inc ax
- get_sys_size_e2:
- xchg ax,cx
- pop dx
- pop ax
- pop fat_seg_low
- clc
- get_sys_size_exit1:
- push cs
- pop ds
- pop bp
- ret
- get_sys_size endp
-
- ;--------------------------------------------------------------------
- ; FIXUP FAT - Removes the bad cluster entries placed by the boot
- ; extension prog.
- ; Entry: Boot sector loaded in the 1st 512 bytes of the data buffer.
- ; Exit: CF - Set if error
- ;--------------------------------------------------------------------
- fixup_fat proc near
- call get_disk_ptrs
- mov dx,word ptr cs:fat_pointer
- mov si,word ptr cs:fat_pointer[2]
- mov al,cs:drive_letter
- lds bx,databuff_ptr
- add bx,512
- mov cx,4 ;Read four sectors
- call read_absolute ;Read FAT
- jc fixup_fat_exit
- mov ax,ds
- push cs
- pop ds
- push fat_seg_low ;Save FAT ptr for installed
- add ax,20h ; code.
- mov fat_seg_low,ax ;Point to loaded FAT table
- call clean_fat ;Remove bad cluster flags
- pop fat_seg_low ;Restore FAT segment
-
- push ds
- lds bx,databuff_ptr ;Write FAT table to disk
- add bx,512
- mov dx,word ptr cs:fat_pointer ;Write FAT tables
- mov si,word ptr cs:fat_pointer[2]
- xor cx,cx
- mov bp,cx
- mov cl,ds:number_of_fats
- fixup_fat_1:
- push cx
- mov al,cs:drive_letter
- mov cx,4 ;Write four sectors
- call write_absolute ;Write FAT
- pop cx
- jc fixup_fat_2
- add dx,ds:sec_per_fat ;Point to next FAT
- adc si,0
- loop fixup_fat_1
- fixup_fat_2:
- pop ds
- fixup_fat_exit:
- ret
- fixup_fat endp
-
- ;--------------------------------------------------------------------
- ; GET DISK PTRS - Computes the logical sector numbers of the FAT and
- ; root directorys.
- ; Entry: Boot sectors loaded in the 1st 512 bytes of the data buffer.
- ; Exit: CF - Set if error
- ;--------------------------------------------------------------------
- fat_pointer dd 0
- root_pointer dd 0
- get_disk_ptrs proc near
- push bp
- push ds
- push cs
- pop es
- lds si,databuff_ptr ;Copy the BPB from the
- mov di,offset temp_buff ; boot record.
- mov bp,di
- mov cx,40
- rep movsb
- pop ds
-
- call get_fattype ;See if FAT 12 or 16 bit
- xor ax,ax
- mov al,number_of_fats ;Compute the sector of the
- mul sec_per_fat ; root directory and FAT
- mov dx,reserved_sec ; table.
- xor si,si
- mov word ptr fat_pointer,dx
- mov word ptr fat_pointer[2],si
- add dx,ax ;Add size of FAT to get ptr
- adc si,0 ; to root directory
- mov word ptr root_pointer,dx
- mov word ptr root_pointer[2],si
- pop bp
- ret
- get_disk_ptrs endp
-
- ;--------------------------------------------------------------------
- ; FIND FIRST - Searches the disk for a file.
- ; Entry: SI - Pointer to an 8.3 filename
- ; Exit: CF - Clear if found
- ;
- ; FIND FIRST1 - Searches the disk for a file.
- ; Entry: SI - Pointer to an ASCIIZ filename
- ; Exit: CF - Clear if found
- ;--------------------------------------------------------------------
- find_first proc near
- call make_filename ;Convert to ASCIIZ filename
- mov si,dx
- find_first1:
- mov ah,1ah ;Insure that DTA set to
- mov dx,DTA_OFFSET ; empty space in PSP
- int 21h
-
- push cx
- mov dx,si
- mov ah,4eh ;Find file
- mov cx,6 ;Inc system and hidden files
- int 21h
- pop cx
- ret
- find_first endp
-
- ;--------------------------------------------------------------------
- ; FIND FILENAME - Searches a loaded boot record for a filename
- ; Entry: DI - Pointer to 8.3 filename
- ; Exit: CF - Clear if found
- ;--------------------------------------------------------------------
- find_filename proc near
- push di
- push ds
- lds si,databuff_ptr ;Search boot record for
- mov bx,11 ; the filename pointed
- mov cx,512 ; to by DI.
- call find_string
- pop ds
- pop di
- ret
- find_filename endp
-
- ;--------------------------------------------------------------------
- ; FIND STRING - Searches a buffer for a specified string
- ; Entry: DS:SI - Pointer to buffer
- ; ES:DI - Pointer to string to find
- ; BX - Length of string
- ; CX - Length of buffer
- ;--------------------------------------------------------------------
- find_string proc near
- push bp
- push dx
- mov bp,si ;Compute end of buffer
- add bp,cx
- mov dx,di ;Save ptr to string
- find_string_1:
- mov di,dx ;Get ptr to string
- mov ax,si
- mov cx,bx ;Get length of string
- repe cmpsb ;Check string
- je find_string_exit
- mov si,ax
- inc si ;Point to next char in buffer
- lea di,[si+bx] ;Determine if we are at the
- cmp di,bp ; end of the buffer.
- jbe find_string_1
- stc
- find_string_exit:
- pop dx
- pop bp
- ret
- find_string endp
-
- ;--------------------------------------------------------------------
- ; SET CRIT VEC - Sets the critical error vector to an internal routine
- ; to avoid the abort, retry, ignore message.
- ;--------------------------------------------------------------------
- set_crit_vec proc near
- push ax
- push bx
- push dx
- push ds
- push es
- mov ax,3524h ;Get crititcal error vector
- int 21h
- mov word ptr crit_vec,bx ;Save vector
- push cs
- pop ds
- mov word ptr crit_vec[2],es
- mov dx,offset crit_error ;Set to internal routine.
- mov ax,2524h
- int 21h
- pop es
- pop ds
- pop dx
- pop bx
- pop ax
- ret
- set_crit_vec endp
-
- ;--------------------------------------------------------------------
- ; RESET CRIT VEC - Resets the critical error vector to its original
- ; state.
- ;--------------------------------------------------------------------
- reset_crit_vec proc near
- pushf
- push ax
- push dx
- push ds
- lds dx,crit_vec ;Get old vector
- mov ax,2524h ;Set vector
- int 21h
- pop ds
- pop dx
- pop ax
- popf
- ret
- reset_crit_vec endp
-
- ;--------------------------------------------------------------------
- ; SET CTLC VEC - Sets the control C vector to an internal routine
- ; to handle the problem in a polite manner.
- ;--------------------------------------------------------------------
- set_ctlc_vec proc near
- push ax
- push bx
- push dx
- push ds
- push es
- mov ax,3523h ;Get ctl-c vector
- int 21h
- mov word ptr ctlc_vec,bx ;Save vector
- push cs
- pop ds
- mov word ptr ctlc_vec[2],es
- mov dx,offset ctlc_error ;Set to internal routine.
- mov ax,2523h
- int 21h
- pop es
- pop ds
- pop dx
- pop bx
- pop ax
- ret
- set_ctlc_vec endp
-
- ;--------------------------------------------------------------------
- ; RESET CTLC VEC - Resets the control C vector to its original
- ; state.
- ;--------------------------------------------------------------------
- reset_ctlc_vec proc near
- push dx
- push ds
- lds dx,ctlc_vec ;Get old vector
- mov ax,2523h ;Set vector
- int 21h
- pop ds
- pop dx
- ret
- reset_ctlc_vec endp
-
- ;--------------------------------------------------------------------
- ; CHK MBOOT DISK - Reads the time stamp from the installed mboot.sys
- ; code to verify proper disk is in drive.
- ;--------------------------------------------------------------------
- chk_mboot_disk proc near
- push ax
- push cx
- push dx
- cmp installed_flag,0 ;If not installed, skip
- je chk_mboot_disk_exit ; check.
- mov si,offset mboot_name ;Open the MBOOT.SYS file to
- call make_filename ; read the time stamp.
- mov ax,3d00h
- int 21h
- jc chk_mboot_disk_exit
-
- mov bx,ax ;Copy file handle
- mov ax,4200h ;Move file ptr
- mov dx,inst_data_ptr
- add dx,offset time_stamp - offset boot_data1
- xor cx,cx
- int 21h
-
- mov ah,3fh ;Read time stamp
- mov dx,offset temp_buff
- mov cx,4
- int 21h
-
- mov ah,3eh ;Close file
- int 21h
-
- mov cx,word ptr temp_buff ;Compare time stamps
- mov dx,word ptr temp_buff[2]
- cmp cx,word ptr time_stamp
- jne chk_mboot_disk_error
- cmp dx,word ptr time_stamp[2]
- je chk_mboot_disk_exit
- chk_mboot_disk_error:
- stc
- chk_mboot_disk_exit:
- pop dx
- pop cx
- pop ax
- ret
- chk_mboot_disk endp
-
- ;--------------------------------------------------------------------
- ; DISP SETTINGS - Displays settings for all sessions.
- ; Entry: DI - Pointer to first entry data
- ; DH - Row to start display
- ;--------------------------------------------------------------------
- disp_settings proc near
- mov dx,0806h ;Write header.
- mov si,offset inst_text1
- call write_line_at ;Write string
- add dh,2
- mov cx,4 ;4 Sessions
- mov bh,1 ;Set session counter
- disp_settings_1:
- push di
- mov al,bh ;Print session number
- mov dl,2
- call printnum ;Write number
-
- mov dl,5
- cmp byte ptr [di+OSTYPE_OFFSET],0 ;See if session disabled
- jne disp_settings_2
- mov si,offset unused_text ;Point to unused string
- call write_line_at ;Write string
- jmp short disp_settings_3
- disp_settings_2:
- call disp_session
- cmp bh,boot_default ;If this selection is the
- jne disp_settings_3 ; default selection, print
- mov dl,74 ; default indication.
- mov si,offset default_str
- call write_line_at ;Write string
- disp_settings_3:
- pop di
- add di,NEXT_ENTRY
- inc dh ;Next row
- inc bh ;Next number
- loop disp_settings_1
- ret
- disp_settings endp
-
- ;--------------------------------------------------------------------
- ; DISP SESSION - Displays settings for one entry.
- ; Entry: DI - Pointer to entry data
- ; DH - Row to start display
- ;--------------------------------------------------------------------
- disp_session proc near
- push bx
- push cx
- push dx
- push bp
- mov bp,di ;Copy pointer to data
-
- mov dl,5 ;Set starting column
- mov si,bp ;Get ptr to name
- cmp byte ptr [si],80h ;If unused, don't print
- jae disp_session_1
- call write_line_at ;Write string
-
- lea si,[bp+AUTO_OFFSET] ;Get ptr to autoexec name
- mov dl,29
- call print_fn ;Print AUTOEXEC name
-
- mov dl,46
- lea si,[bp+CONFIG_OFFSET] ;Get ptr to config name
- call print_fn ;Print CONFIG name
-
- xor bx,bx ;Get op sys type. If not
- or bl,[bp+OSTYPE_OFFSET] ; defined, don't print.
- jz disp_session_1
- call get_os_entry ;Get offset into os table
- mov si,di
- mov di,offset key_buffer ;First copy to buffer, then
- push di ; terminate string with zero.
- mov cx,8
- rep movsb
- mov byte ptr [di],0
- pop si
- mov dl,63
- call write_line_at ;Write string
- disp_session_1:
- pop bp
- pop dx
- pop cx
- pop bx
- ret
- disp_session endp
-
- ;--------------------------------------------------------------------
- ; MSG BOX - Displays a string and prompts the user for a Yes/No answer.
- ; Entry: SI - Pointer to string. 1st two bytes are the cursor location.
- ; Exit: BL - User response, 1 = yes, 2 = no.
- ;--------------------------------------------------------------------
- msg_box proc near
- push bp
- push ax
- call write_linenorm ;Write prompt string
- pop ax
- mov bp,offset yesno_menu ;Yes / No menu.
- mov [bp+MENU_SELECTED],al ;Set default
- call menu
- mov cx,1000h ;Clear yes/no menu.
- mov dx,1980h
- call scroll_block
- pop bp
- ret
- msg_box endp
-
- ;--------------------------------------------------------------------
- ; CONFIRM QUIT - Asks the user to confirm quit request.
- ; Exit: ZF - Set, quit confirmed.
- ;--------------------------------------------------------------------
- confirm_quit proc near
- mov cx,1000h ;Make room for question
- mov dx,1980h
- call scroll_block
- mov si,offset confirm_msg
- mov al,2 ;Set default to No.
- call msg_box
- cmp bl,1 ;See if answer Yes.
- ret
- confirm_quit endp
-
- ;--------------------------------------------------------------------
- ; GET NUMBER - Querys the user for a number.
- ; Entry: AL - Number of characters allowed.
- ; DX - Cursor location for entry box.
- ; Exit: AX - Number returned by the user entered.
- ; CF - Set if user returned an invalid number.
- ;--------------------------------------------------------------------
- get_number proc near
- call entry_box
- jc get_number_exit
-
- xor ax,ax ;Convert ascii number into
- xor dx,dx ; hex.
- mov si,10 ;Base 10
- get_number_loop:
- mul si ;Mul current num by base
- mov dl,[bx] ;Get character
- sub dl,30h ;Convert to hex from ASCII
- jb get_number_err
- cmp dl,9
- ja get_number_err
- add ax,dx ;Add to total.
- inc bx ;Move to next char
- loop get_number_loop
- clc
- get_number_exit:
- ret
- get_number_err:
- stc
- jmp short get_number_exit
- get_number endp
-
- ;-----------------------------------------------------------------------------
- ; CTLC ERROR - Ctl-C routine to allow polite control C action.
- ;-----------------------------------------------------------------------------
- ctlc_error proc far
- cmp ctlc_return,0
- je ctlc_1
- mov sp,ctlc_stack
- jmp [ctlc_return]
- ctlc_1:
- iret
- ctlc_error endp
-
- ;--------------------------------------------------------------------
- ; ENTRY BOX - Querys user for one line of input.
- ; Entry: AL - Number of characters allowed.
- ; DX - Cursor location for entry box.
- ; Exit: BX - Pointer to buffer containing the user response.
- ; CX - length of response.
- ;--------------------------------------------------------------------
- entry_box proc near
- push ax
- xor bx,bx
- mov ah,2 ;Set cursor position
- call vidint
- pop ax
- mov bx,offset key_buffer
- inc al
- mov [bx],al ;Set buffer size
- mov dx,bx
- mov ax,offset entry_box_error
- mov ctlc_stack,sp
- mov ctlc_return,ax
- mov ah,0ah ;DOS buffered read
- int 21h
- inc bx ;Point to length of string
- xor cx,cx
- or cl,[bx] ;Get length of string
- inc bx ;Point to string.
- clc
- entry_box_1:
- mov ctlc_stack,0
- mov ctlc_return,0
- ret
- entry_box_error:
- mov byte ptr [bx+1],0
- xor cx,cx
- inc bx
- stc
- jmp entry_box_1
- entry_box endp
-
- ;--------------------------------------------------------------------
- ; SCAN4TERM - Checks to see if a character is a filename terminator.
- ; Entry: AL - character
- ; Exit: ZF - Set if terminator.
- ;--------------------------------------------------------------------
- term_chars db ".:;,=+/",22h,"[]|<> ",9,13,0 ;Filename term. chars
- term_chars_end = $
-
- scan4term proc near
- push cx
- push di
- mov cx,offset term_chars_end - offset term_chars
- mov di,offset term_chars
- repne scasb ;See if char is a terminator
- pop di
- pop cx
- ret
- scan4term endp
-
- ;--------------------------------------------------------------------
- ; CAPS CHAR - capitalizes a character
- ; Entry: AL - character
- ;--------------------------------------------------------------------
- caps_char proc near
- cmp al,"a"
- jb caps1
- cmp al,"z"
- ja caps1
- and al,0dfh
- caps1:
- ret
- caps_char endp
-
- ;--------------------------------------------------------------------
- ; ASCIIZ2FN - Converts a filename in ASCIIZ format to 8.3 format
- ; Entry: SI - Pointer to filename
- ; DI - Pointer to buffer to store the 8.3 string.
- ; Exit: SI - Pointer to 8.3 name.
- ;--------------------------------------------------------------------
- asciiz2fn proc near
- push bx
- push di
- push di
- push di
- mov cx,11 ;Fill destination buffer
- mov al," " ; with blanks.
- rep stosb
- pop di
- mov bx,di ;Save ptr to buffer
- mov cx,8
- add bx,cx ;BX = ptr to ext
- asciiz2fn_1:
- lodsb ;Read each character in the
- cmp al,"." ; name. If '.' then jmp
- je asciiz2fn_ext ; to code for ext. If term
- call scan4term ; char, end filename, else
- je asciiz2fn_exit ; write the char in the dest
- call caps_char ; buffer.
- stosb
- loop asciiz2fn_1
- asciiz2fn_3:
- lodsb ;If > 8 characters, scan until
- cmp al,"." ; '.' or end of string.
- je asciiz2fn_ext
- call scan4term
- je asciiz2fn_exit
- jmp short asciiz2fn_3
- asciiz2fn_ext:
- mov di,bx ;Get ptr to ext
- mov cx,3
- asciiz2fn_4:
- lodsb ;Save the ext just like the
- call scan4term ; filename.
- je asciiz2fn_exit
- call caps_char
- stosb
- loop asciiz2fn_4
- asciiz2fn_exit:
- pop si
- pop di
- pop bx
- ret
- asciiz2fn endp
-
- ;--------------------------------------------------------------------
- ; FN2ASCIIZ - Converts a filename in 8.3 format to ASCIIZ
- ; Entry: SI - Pointer to filename
- ; DI - Pointer to buffer to store the ASCIIZ string.
- ; Exit: SI - Pointer to ASCIIZ name.
- ; CX - Length of string
- ;--------------------------------------------------------------------
- fn2asciiz proc near
- push bx
- push dx
- push di ;Save ptr to destination
- mov bx,si
- mov cx,8
- xor dx,dx ;Clear count
- fn2asciiz_1:
- lodsb
- cmp al," " ;See if space
- je fn2asciiz_2 ;If so, end of filename
- jb fn2asciiz_4 ;If ctl char, no ext.
- stosb
- inc dx
- loop fn2asciiz_1
- fn2asciiz_2:
- mov si,bx ;Compute ptr to ext.
- add si,8
- mov al,"."
- stosb
- inc dx
- mov cx,3
- fn2asciiz_3:
- lodsb
- cmp al," " ;See if space
- jbe fn2asciiz_4 ;If so, end of ext
- stosb
- inc dx
- loop fn2asciiz_3
- fn2asciiz_4:
- xor al,al ;Terminate string with zero
- stosb
- mov cx,dx ;Copy count
- pop si ;Get ptr to filename start
- pop dx
- pop bx
- ret
- fn2asciiz endp
-
- ;--------------------------------------------------------------------
- ; PRINT FILENAME - Prints a filename
- ; Entry: SI - Pointer to filename in 8.3 format
- ; DH - Row to start display
- ;--------------------------------------------------------------------
- print_fn proc near
- mov di,offset key_buffer
- call fn2asciiz
- call write_line_at ;Write string
- ret
- print_fn endp
-
- ;-----------------------------------------------------------------------------
- ; WRITE ERROR - Writes an error message to the screen.
- ; Entry: SI - Ptr to error ASCIIZ message string.
- ;-----------------------------------------------------------------------------
- write_error proc near
- mov dx,error_msg_loc ;Get location for error
- call clear_line ; message.
- call write_line_at
- ret
- write_error endp
-
- ;-----------------------------------------------------------------------------
- ; CLEAR LINE - Clears a line off the screen.
- ; Entry: DH - Line to clear
- ;-----------------------------------------------------------------------------
- clear_line proc near
- push cx
- push dx
- mov cx,dx ;Copy cursor start loc
- mov dl,80 ;Scroll 1 line to end
- mov cl,0
- call scroll_block
- pop dx
- pop cx
- ret
- clear_line endp
-
- ;-----------------------------------------------------------------------------
- ; CLEAR MSG - Clears a message off the screen.
- ; Entry: DH - Line to clear
- ;-----------------------------------------------------------------------------
- clear_msg proc near
- mov cx,0800h ;Row 8 Col 0
- mov dx,0a50h ;Row 10 Col 80
- call scroll_block
- ret
- clear_msg endp
-
- end_of_code = $
- code ends
-
- end entry