summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2003-06-08 11:05:06 +0000
committerDimitri Sokolyuk <demon@dim13.org>2003-06-08 11:05:06 +0000
commit4b1d510b9bfb088c142ee129d31764a73ceb1fd0 (patch)
treee71696810e671891489ab2dcc7c548f6990417b4
initial import
-rw-r--r--Boot.asm296
-rw-r--r--Boot.binbin0 -> 512 bytes
-rw-r--r--Boot.lst414
-rw-r--r--Bootinst.c256
-rw-r--r--Compile.bat8
-rw-r--r--Readme57
6 files changed, 1031 insertions, 0 deletions
diff --git a/Boot.asm b/Boot.asm
new file mode 100644
index 0000000..1f3465e
--- /dev/null
+++ b/Boot.asm
@@ -0,0 +1,296 @@
+; BOOTEASY, version 1.7.
+; Developed from BOOTANY, with many improvements.
+; The main idea was to simplify the installation
+; procedure and to remove unnecessary partition type switching.
+; Second hard disk switching added.
+; Author: Serge Vakulenko, <vak@kiae.su>
+
+F1_scancode equ 59 ; scancode of 'F1' key
+Enter_scancode equ 28 ; scancode of 'Enter' key
+Timeout equ 5 ; wait up to 5 seconds for reply
+
+StdBase equ 7c00h ; address where DOS loads us
+Base equ 600h ; address where we rewrite itself
+Partab equ 1beh ; partition table offset
+NumDisks equ 475h ; number of disk drives (BIOS data area)
+
+BootIndicator equ 0 ; partition record: boot indicator
+BeginHead equ 1 ; first partition sector: head number
+BeginSector equ 2 ; sector and cylinder
+SystemId equ 4 ; system type
+
+; -------------------------------
+
+dummy segment at 0
+ assume cs:dummy
+ org Base ; address where we rewrite itself
+BaseEntry:
+ org StdBase ; address where DOS loads us
+StdBaseEntry:
+dummy ends
+
+; -------------------------------
+
+code segment
+ assume cs:code, ds:code, es:code, ss:code
+ org 0
+Boot:
+;
+; Setup the stack and segment registers
+;
+ xor AX,AX ; Zero register
+ mov ES,AX ; ES := 0
+ mov DS,AX ; DS := 0
+ mov SS,AX ; disables intrs up to the next command
+ mov SP,StdBase ; SP at 7c00
+;
+; DOS loads this pgm at 0000:7C00. Any boot routine
+; we call also expects to execute there so the first
+; exercise is to move this code somewhere else.
+;
+ cld ; Clear direction
+ mov SI,SP ; Copy from 7c00h...
+ mov DI,Base ; ...to 600h...
+ mov CX,256 ; ...512 bytes, or 256 words
+ repne movsw ; Move itself to new location
+
+ jmp FAR PTR BaseEntry+(Entry-Boot)
+
+; -------------------------------
+;
+; A valid function key was depressed (or defaulted)
+; Attempt to boot the corresponding partition.
+;
+Load:
+ mov DX,BP ; restore drive number
+ pop AX ; key '1'..'5'
+ mov Base+default,AL ; save function key number
+ cmp AL,'5'
+ je SwitchDrive
+ mov AH,16
+ mul AH ; AX = key * 16
+ add AX,Base+Partab-'1'*16 ; subtract '1'
+ mov SI,AX
+;
+; Check if the partition is empty.
+;
+ cmp BYTE PTR SystemId[SI],0
+ je Menu ; Empty - display menu again
+ cmp BYTE PTR SystemId[SI],05h
+ je Menu ; DOS extended type - never load
+
+ mov BYTE PTR BootIndicator[SI],80h ; Mark partition as bootable
+ call SaveBoot
+;
+; Read in and validate the partition's boot sector.
+;
+ mov DH,BeginHead[SI] ; head from partition table
+ mov CX,BeginSector[SI]
+ jmp loadboot
+;
+; Read in the boot sector from second disk.
+;
+SwitchDrive:
+ call SaveBoot
+ mov CX,0001h ; cylinder 0, sector 1
+ xor DL,CL ; (DL ^= 1) switch drive
+loadboot:
+ mov BX,StdBase ; ES already == 0
+ mov AX,0201h ; function, # of sectors
+ int 13h ; read system boot record
+ jc Menu ; exit if error
+ cmp WORD PTR 510[BX],0aa55h ; test signature
+ jne Menu ; reprompt if invalid
+;
+; Jump to secondary boot.
+; DL now contains boot disk number (80h or 81h);
+; ES:SI contains the address of partition table
+; entry to boot.
+;
+ jmp FAR PTR StdBaseEntry
+
+; -------------------------------
+;
+; The main entry to the boot
+;
+Entry:
+ cmp DL,81h ; DL contains current drive number
+ je driveok ; is it valid?
+ mov DL,80h ; no - use the default value
+driveok: mov BP,DX ; save the drive number
+ inc DX ; 80h -> 81h, 81h -> 82h
+ xor DL,80h+'3' ; 80h -> '2', 81h -> '1'
+ mov Base+diskNum,DL
+;
+; Display the menu
+;
+Menu:
+ mov DI,Base+Partab ; set index
+ mov CX,4 ; set loop count
+ mov Base+key,'1' ; set key number in message
+ xor DH,DH ; count of partitions
+menuloop:
+ mov BYTE PTR BootIndicator[DI],CH ; Clear active flag
+ mov AL,SystemId[DI]
+ cmp AL,0 ; unused partition?
+ je next
+ cmp AL,5 ; extended DOS partition?
+ je next
+ inc DH ; increment partition count
+
+ lea SI,Base+FkeyMsg ; get msg addr
+ call Output
+
+ lea SI,Base+nameTable-2
+nameloop:
+ inc SI
+ inc SI
+ mov BX,[SI]
+ or BH,BH
+ je endnameloop
+ xor BH,SystemId[DI]
+ jne nameloop
+endnameloop:
+ lea SI,Base+namtab[BX]
+ call Output
+next:
+ add DI,16 ; next entry address
+ inc Base+key
+ loop menuloop
+
+ cmp BYTE PTR DS:NumDisks,2 ; is the second disk present?
+ je have2disks ; have disk 2
+
+ lea SI,Base+defaultMsg ; prepare 'Default' message
+ or DH,DH ; no disk 2; do we have valid partitions?
+ jne prompt ; several partitions, wait for reply
+
+ int 18h ; no partitions, load ROM basic
+ jmp Menu ; repeat, if no ROM basic
+have2disks:
+ lea SI,Base+FkeyMsg ; print 'F5'
+ call Output ; now SI points to "disk 2\nDefault..."
+prompt:
+ call Output ; print 'Default' message
+reprompt:
+ xor AH,AH ; GetTickCount
+ int 1ah ; BiosTimerService
+ mov BX,DX ; lo-order tick count
+ add BX,192*Timeout/10 ; timeout value in ticks
+;
+; Get the reply
+;
+waitkey:
+ mov AH,1 ; keyboard status
+ int 16h ; keybd bios service
+ mov AH,0 ; GetTickCount
+ jnz reply ; jump if reply
+ int 1ah ; BiosTimerService
+ cmp DX,BX ; check for timeout
+ jb waitkey ; wait for scancode
+loaddefault:
+ mov AL,Base+default ; prior system id
+ jmp testkey ; boot default system
+reply:
+ int 16h ; AH=0, keybd bios service
+ mov AL,AH ; Copy to AL
+ cmp AL,Enter_scancode
+ je loaddefault
+ add AL,'1'-F1_scancode ; Turn into index
+testkey:
+ cmp AL,'1' ; max Function key
+ jb reprompt ; Invalid code check
+ cmp AL,'5' ; max Function key
+ jnbe reprompt ; if not F1..F5, branch
+ push AX
+
+ lea SI,Base+newLine ; new line
+ lea BX,Base+Load
+ push BX ; call Output; jmp Load
+
+; -------------------------------
+;
+; Output line [SI] to screen, end of line marked with 80h
+;
+Output:
+ cld ; reset direction flag
+ lodsb ; load argument from string
+ push AX ; save byte
+ and AL,7fh ; insure valid character
+ mov AH,14 ; write tty
+ int 10h ; bios video service
+ pop AX ; restore byte
+ test AL,80h ; test for end of string
+ jz Output ; do until end of string
+ ret ; return to caller
+
+; -------------------------------
+;
+; Save boot block default partition settings
+;
+SaveBoot:
+ push SI
+ mov AX,0301h ; write sector
+ mov BX,Base ; ES already == 0
+ mov CX,0001h ; cylinder 0, sector 1
+ xor DH,DH ; drive #, head 0
+ int 13h ; replace boot record
+ pop SI
+ mov Base+default,'?' ; reset default
+ ret
+
+; -------------------------------
+
+newLine db 13,10+80h
+FkeyMsg db 13,10,'F'
+key db '0 . . .',' '+80h,'disk '
+diskNum db '1'
+defaultMsg db 13,10,10,'Default: F'
+default db '?',' '+80h
+
+nameTable db dos -namtab, 1
+ db dos -namtab, 4
+ db dos -namtab, 6
+ db hpfs -namtab, 7
+ db os2 -namtab, 0Ah
+ db unix -namtab, 63h
+ db novell -namtab, 64h
+ db novell -namtab, 65h
+ db minix -namtab, 80h
+ db linux -namtab, 81h
+ db linux -namtab, 82h
+ db linux -namtab, 83h
+ db amoeba -namtab, 93h
+ db freebsd -namtab, 0A5h
+ db bsdi -namtab, 9fh
+ db pcix -namtab, 75h
+ db cpm -namtab, 52h
+ db cpm -namtab, 0dbh
+ db venix -namtab, 40h
+ db dossec -namtab, 0F2h
+ db noname -namtab, 0
+
+namtab:
+dos db 'Do','s'+80h
+hpfs db 'Hpf','s'+80h
+os2 db 'Os','2'+80h
+unix db 'Uni','x'+80h
+novell db 'Novel','l'+80h
+minix db 'Mini','x'+80h
+linux db 'Linu','x'+80h
+amoeba db 'Amoeb','a'+80h
+freebsd db 'FreeBS','D'+80h
+bsdi db 'BSD','i'+80h
+pcix db 'Pci','x'+80h
+cpm db 'Cp','m'+80h
+venix db 'Veni','x'+80h
+dossec db 'Dosse','c'+80h
+noname db '?','?'+80h
+
+used equ $ - Boot
+ db (1beh - used + 1) dup (0) ; error if code too big
+ db 63 dup (0) ; clear rest of record
+ dw 0aa55h ; magic
+
+code ends
+ end
diff --git a/Boot.bin b/Boot.bin
new file mode 100644
index 0000000..ec56052
--- /dev/null
+++ b/Boot.bin
Binary files differ
diff --git a/Boot.lst b/Boot.lst
new file mode 100644
index 0000000..a10c7b3
--- /dev/null
+++ b/Boot.lst
@@ -0,0 +1,414 @@
+Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 1
+boot.ASM
+
+
+
+ 1 ; BOOTEASY, version 1.7.
+ 2 ; Developed from BOOTANY, with many improvements.
+ 3 ; The main idea was to simplify the installation
+ 4 ; procedure and to remove unnecessary partition type switching.
+ 5 ; Second hard disk switching added.
+ 6 ; Author: Serge Vakulenko, <vak@kiae.su>
+ 7
+ 8 =003B F1_scancode equ 59 ; scancode of 'F1' key
+ 9 =001C Enter_scancode equ 28 ; scancode of 'Enter' key
+ 10 =0005 Timeout equ 5 ; wait up to 5 seconds for reply
+ 11
+ 12 =7C00 StdBase equ 7c00h ; address where DOS loads us
+ 13 =0600 Base equ 600h ; address where we rewrite itself
+ 14 =01BE Partab equ 1beh ; partition table offset
+ 15 =0475 NumDisks equ 475h ; number of disk drives (BIOS data area)
+ 16
+ 17 =0000 BootIndicator equ 0 ; partition record: boot indicator
+ 18 =0001 BeginHead equ 1 ; first partition sector: head number
+ 19 =0002 BeginSector equ 2 ; sector and cylinder
+ 20 =0004 SystemId equ 4 ; system type
+ 21
+ 22 ; -------------------------------
+ 23
+ 24 0000 dummy segment at 0
+ 25 assume cs:dummy
+ 26 org Base ; address where we rewrite itself
+ 27 0600 BaseEntry:
+ 28 org StdBase ; address where DOS loads us
+ 29 7C00 StdBaseEntry:
+ 30 7C00 dummy ends
+ 31
+ 32 ; -------------------------------
+ 33
+ 34 0000 code segment
+ 35 assume cs:code, ds:code, es:code, ss:code
+ 36 org 0
+ 37 0000 Boot:
+ 38 ;
+ 39 ; Setup the stack and segment registers
+ 40 ;
+ 41 0000 33 C0 xor AX,AX ; Zero register
+ 42 0002 8E C0 mov ES,AX ; ES := 0
+ 43 0004 8E D8 mov DS,AX ; DS := 0
+ 44 0006 8E D0 mov SS,AX ; disables intrs up to the next command
+ 45 0008 BC 7C00 mov SP,StdBase ; SP at 7c00
+ 46 ;
+ 47 ; DOS loads this pgm at 0000:7C00. Any boot routine
+ 48 ; we call also expects to execute there so the first
+ 49 ; exercise is to move this code somewhere else.
+ 50 ;
+ 51 000B FC cld ; Clear direction
+ 52 000C 8B F4 mov SI,SP ; Copy from 7c00h...
+ 53 000E BF 0600 mov DI,Base ; ...to 600h...
+ 54 0011 B9 0100 mov CX,256 ; ...512 bytes, or 256 words
+ 55 0014 F2> A5 repne movsw ; Move itself to new location
+ 56
+ 57 0016 EA 00000667sr jmp FAR PTR BaseEntry+(Entry-Boot)
+ Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 2
+boot.ASM
+
+
+
+ 58
+ 59 ; -------------------------------
+ 60 ;
+ 61 ; A valid function key was depressed (or defaulted)
+ 62 ; Attempt to boot the corresponding partition.
+ 63 ;
+ 64 001B Load:
+ 65 001B 8B D5 mov DX,BP ; restore drive number
+ 66 001D 58 pop AX ; key '1'..'5'
+ 67 001E A2 074Fr mov Base+default,AL ; save function key number
+ 68 0021 3C 35 cmp AL,'5'
+ 69 0023 74 23 je SwitchDrive
+ 70 0025 B4 10 mov AH,16
+ 71 0027 F6 E4 mul AH ; AX = key * 16
+ 72 0029 05 04AE add AX,Base+Partab-'1'*16 ; subtract '1'
+ 73 002C 8B F0 mov SI,AX
+ 74 ;
+ 75 ; Check if the partition is empty.
+ 76 ;
+ 77 002E 80 7C 04 00 cmp BYTE PTR SystemId[SI],0
+ 78 0032 74 44 je Menu ; Empty - display menu again
+ 79 0034 80 7C 04 05 cmp BYTE PTR SystemId[SI],05h
+ 80 0038 74 3E je Menu ; DOS extended type - never load
+ 81
+ 82 003A C6 04 80 mov BYTE PTR BootIndicator[SI],80h ; Mark partition as bootable
+ 83 003D E8 00DA call SaveBoot
+ 84 ;
+ 85 ; Read in and validate the partition's boot sector.
+ 86 ;
+ 87 0040 8A 74 01 mov DH,BeginHead[SI] ; head from partition table
+ 88 0043 8B 4C 02 mov CX,BeginSector[SI]
+ 89 0046 EB 08 jmp loadboot
+ 90 ;
+ 91 ; Read in the boot sector from second disk.
+ 92 ;
+ 93 0048 SwitchDrive:
+ 94 0048 E8 00CF call SaveBoot
+ 95 004B B9 0001 mov CX,0001h ; cylinder 0, sector 1
+ 96 004E 32 D1 xor DL,CL ; (DL ^= 1) switch drive
+ 97 0050 loadboot:
+ 98 0050 BB 7C00 mov BX,StdBase ; ES already == 0
+ 99 0053 B8 0201 mov AX,0201h ; function, # of sectors
+ 100 0056 CD 13 int 13h ; read system boot record
+ 101 0058 72 1E jc Menu ; exit if error
+ 102 005A 81 BF 01FE AA55 cmp WORD PTR 510[BX],0aa55h ; test signature
+ 103 0060 75 16 jne Menu ; reprompt if invalid
+ 104 ;
+ 105 ; Jump to secondary boot.
+ 106 ; DL now contains boot disk number (80h or 81h);
+ 107 ; ES:SI contains the address of partition table
+ 108 ; entry to boot.
+ 109 ;
+ 110 0062 EA 00007C00sr jmp FAR PTR StdBaseEntry
+ 111
+ 112 ; -------------------------------
+ 113 ;
+ 114 ; The main entry to the boot
+ Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 3
+boot.ASM
+
+
+
+ 115 ;
+ 116 0067 Entry:
+ 117 0067 80 FA 81 cmp DL,81h ; DL contains current drive number
+ 118 006A 74 02 je driveok ; is it valid?
+ 119 006C B2 80 mov DL,80h ; no - use the default value
+ 120 006E 8B EA driveok: mov BP,DX ; save the drive number
+ 121 0070 42 inc DX ; 80h -> 81h, 81h -> 82h
+ 122 0071 80 F2 B3 xor DL,80h+'3' ; 80h -> '2', 81h -> '1'
+ 123 0074 88 16 0741r mov Base+diskNum,DL
+ 124 ;
+ 125 ; Display the menu
+ 126 ;
+ 127 0078 Menu:
+ 128 0078 BF 07BE mov DI,Base+Partab ; set index
+ 129 007B B9 0004 mov CX,4 ; set loop count
+ 130 007E C6 06 0734r 31 mov Base+key,'1' ; set key number in message
+ 131 0083 32 F6 xor DH,DH ; count of partitions
+ 132 0085 menuloop:
+ 133 0085 88 2D mov BYTE PTR BootIndicator[DI],CH ; Clear active flag
+ 134 0087 8A 45 04 mov AL,SystemId[DI]
+ 135 008A 3C 00 cmp AL,0 ; unused partition?
+ 136 008C 74 23 je next
+ 137 008E 3C 05 cmp AL,5 ; extended DOS partition?
+ 138 0090 74 1F je next
+ 139 0092 FE C6 inc DH ; increment partition count
+ 140
+ 141 0094 BE 0731r lea SI,Base+FkeyMsg ; get msg addr
+ 142 0097 E8 0071 call Output
+ 143
+ 144 009A BE 074Fr lea SI,Base+nameTable-2
+ 145 009D nameloop:
+ 146 009D 46 inc SI
+ 147 009E 46 inc SI
+ 148 009F 8B 1C mov BX,[SI]
+ 149 00A1 0A FF or BH,BH
+ 150 00A3 74 05 je endnameloop
+ 151 00A5 32 7D 04 xor BH,SystemId[DI]
+ 152 00A8 75 F3 jne nameloop
+ 153 00AA endnameloop:
+ 154 00AA 8D B7 077Br lea SI,Base+namtab[BX]
+ 155 00AE E8 005A call Output
+ 156 00B1 next:
+ 157 00B1 83 C7 10 add DI,16 ; next entry address
+ 158 00B4 FE 06 0734r inc Base+key
+ 159 00B8 E2 CB loop menuloop
+ 160
+ 161 00BA 80 3E 0475 02 cmp BYTE PTR DS:NumDisks,2 ; is the second disk present?
+ 162 00BF 74 0B je have2disks ; have disk 2
+ 163
+ 164 00C1 BE 0742r lea SI,Base+defaultMsg ; prepare 'Default' message
+ 165 00C4 0A F6 or DH,DH ; no disk 2; do we have valid partitions?
+ 166 00C6 75 0A jne prompt ; several partitions, wait for reply
+ 167
+ 168 00C8 CD 18 int 18h ; no partitions, load ROM basic
+ 169 00CA EB AC jmp Menu ; repeat, if no ROM basic
+ 170 00CC have2disks:
+ 171 00CC BE 0731r lea SI,Base+FkeyMsg ; print 'F5'
+ Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 4
+boot.ASM
+
+
+
+ 172 00CF E8 0039 call Output ; now SI points to "disk 2\nDefault..."
+ 173 00D2 prompt:
+ 174 00D2 E8 0036 call Output ; print 'Default' message
+ 175 00D5 reprompt:
+ 176 00D5 32 E4 xor AH,AH ; GetTickCount
+ 177 00D7 CD 1A int 1ah ; BiosTimerService
+ 178 00D9 8B DA mov BX,DX ; lo-order tick count
+ 179 00DB 83 C3 60 add BX,192*Timeout/10 ; timeout value in ticks
+ 180 ;
+ 181 ; Get the reply
+ 182 ;
+ 183 00DE waitkey:
+ 184 00DE B4 01 mov AH,1 ; keyboard status
+ 185 00E0 CD 16 int 16h ; keybd bios service
+ 186 00E2 B4 00 mov AH,0 ; GetTickCount
+ 187 00E4 75 0B jnz reply ; jump if reply
+ 188 00E6 CD 1A int 1ah ; BiosTimerService
+ 189 00E8 3B D3 cmp DX,BX ; check for timeout
+ 190 00EA 72 F2 jb waitkey ; wait for scancode
+ 191 00EC loaddefault:
+ 192 00EC A0 074Fr mov AL,Base+default ; prior system id
+ 193 00EF EB 0A jmp testkey ; boot default system
+ 194 00F1 reply:
+ 195 00F1 CD 16 int 16h ; AH=0, keybd bios service
+ 196 00F3 8A C4 mov AL,AH ; Copy to AL
+ 197 00F5 3C 1C cmp AL,Enter_scancode
+ 198 00F7 74 F3 je loaddefault
+ 199 00F9 04 F6 add AL,'1'-F1_scancode ; Turn into index
+ 200 00FB testkey:
+ 201 00FB 3C 31 cmp AL,'1' ; max Function key
+ 202 00FD 72 D6 jb reprompt ; Invalid code check
+ 203 00FF 3C 35 cmp AL,'5' ; max Function key
+ 204 0101 77 D2 jnbe reprompt ; if not F1..F5, branch
+ 205 0103 50 push AX
+ 206
+ 207 0104 BE 072Fr lea SI,Base+newLine ; new line
+ 208 0107 BB 061Br lea BX,Base+Load
+ 209 010A 53 push BX ; call Output; jmp Load
+ 210
+ 211 ; -------------------------------
+ 212 ;
+ 213 ; Output line [SI] to screen, end of line marked with 80h
+ 214 ;
+ 215 010B Output:
+ 216 010B FC cld ; reset direction flag
+ 217 010C AC lodsb ; load argument from string
+ 218 010D 50 push AX ; save byte
+ 219 010E 24 7F and AL,7fh ; insure valid character
+ 220 0110 B4 0E mov AH,14 ; write tty
+ 221 0112 CD 10 int 10h ; bios video service
+ 222 0114 58 pop AX ; restore byte
+ 223 0115 A8 80 test AL,80h ; test for end of string
+ 224 0117 74 F2 jz Output ; do until end of string
+ 225 0119 C3 ret ; return to caller
+ 226
+ 227 ; -------------------------------
+ 228 ;
+ Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 5
+boot.ASM
+
+
+
+ 229 ; Save boot block default partition settings
+ 230 ;
+ 231 011A SaveBoot:
+ 232 011A 56 push SI
+ 233 011B B8 0301 mov AX,0301h ; write sector
+ 234 011E BB 0600 mov BX,Base ; ES already == 0
+ 235 0121 B9 0001 mov CX,0001h ; cylinder 0, sector 1
+ 236 0124 32 F6 xor DH,DH ; drive #, head 0
+ 237 0126 CD 13 int 13h ; replace boot record
+ 238 0128 5E pop SI
+ 239 0129 C6 06 074Fr 3F mov Base+default,'?' ; reset default
+ 240 012E C3 ret
+ 241
+ 242 ; -------------------------------
+ 243
+ 244 012F 0D 8A newLine db 13,10+80h
+ 245 0131 0D 0A 46 FkeyMsg db 13,10,'F'
+ 246 0134 30 20 2E 20 2E 20 2E+ key db '0 . . .',' '+80h,'disk '
+ 247 A0 64 69 73 6B 20
+ 248 0141 31 diskNum db '1'
+ 249 0142 0D 0A 0A 44 65 66 61+ defaultMsg db 13,10,10,'Default: F'
+ 250 75 6C 74 3A 20 46
+ 251 014F 3F A0 default db '?',' '+80h
+ 252
+ 253 0151 00 01 nameTable db dos -namtab, 1
+ 254 0153 00 04 db dos -namtab, 4
+ 255 0155 00 06 db dos -namtab, 6
+ 256 0157 03 07 db hpfs -namtab, 7
+ 257 0159 07 0A db os2 -namtab, 0Ah
+ 258 015B 0A 63 db unix -namtab, 63h
+ 259 015D 0E 64 db novell -namtab, 64h
+ 260 015F 0E 65 db novell -namtab, 65h
+ 261 0161 14 80 db minix -namtab, 80h
+ 262 0163 19 81 db linux -namtab, 81h
+ 263 0165 19 82 db linux -namtab, 82h
+ 264 0167 19 83 db linux -namtab, 83h
+ 265 0169 1E 93 db amoeba -namtab, 93h
+ 266 016B 24 A5 db freebsd -namtab, 0A5h
+ 267 016D 2B 9F db bsdi -namtab, 9fh
+ 268 016F 2F 75 db pcix -namtab, 75h
+ 269 0171 33 52 db cpm -namtab, 52h
+ 270 0173 33 DB db cpm -namtab, 0dbh
+ 271 0175 36 40 db venix -namtab, 40h
+ 272 0177 3B F2 db dossec -namtab, 0F2h
+ 273 0179 41 00 db noname -namtab, 0
+ 274
+ 275 017B namtab:
+ 276 017B 44 6F F3 dos db 'Do','s'+80h
+ 277 017E 48 70 66 F3 hpfs db 'Hpf','s'+80h
+ 278 0182 4F 73 B2 os2 db 'Os','2'+80h
+ 279 0185 55 6E 69 F8 unix db 'Uni','x'+80h
+ 280 0189 4E 6F 76 65 6C EC novell db 'Novel','l'+80h
+ 281 018F 4D 69 6E 69 F8 minix db 'Mini','x'+80h
+ 282 0194 4C 69 6E 75 F8 linux db 'Linu','x'+80h
+ 283 0199 41 6D 6F 65 62 E1 amoeba db 'Amoeb','a'+80h
+ 284 019F 46 72 65 65 42 53 C4 freebsd db 'FreeBS','D'+80h
+ 285 01A6 42 53 44 E9 bsdi db 'BSD','i'+80h
+ Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 6
+boot.ASM
+
+
+
+ 286 01AA 50 63 69 F8 pcix db 'Pci','x'+80h
+ 287 01AE 43 70 ED cpm db 'Cp','m'+80h
+ 288 01B1 56 65 6E 69 F8 venix db 'Veni','x'+80h
+ 289 01B6 44 6F 73 73 65 E3 dossec db 'Dosse','c'+80h
+ 290 01BC 3F BF noname db '?','?'+80h
+ 291
+ 292 =01BE used equ $ - Boot
+ 293 01BE 01*(00) db (1beh - used + 1) dup (0) ; error if code too big
+ 294 01BF 3F*(00) db 63 dup (0) ; clear rest of record
+ 295 01FE AA55 dw 0aa55h ; magic
+ 296
+ 297 0200 code ends
+ 298 end
+ Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 7
+Symbol Table
+
+
+
+
+Symbol Name Type Value Cref (defined at #)
+
+??DATE Text "11/14/95"
+??FILENAME Text "boot "
+??TIME Text "18:41:35"
+??VERSION Number 030A
+@CPU Text 0101H
+@CURSEG Text CODE #24 #34
+@FILENAME Text BOOT
+@WORDSIZE Text 2 #24 #34
+AMOEBA Byte CODE:0199 265 #283
+BASE Number 0600 #13 26 53 67 72 123 128 130 141 144 154 158 164 171 192 +
+ 207 208 234 239
+BASEENTRY Near DUMMY:0600 #27 57
+BEGINHEAD Number 0001 #18 87
+BEGINSECTOR Number 0002 #19 88
+BOOT Near CODE:0000 #37 57 292
+BOOTINDICATOR Number 0000 #17 82 133
+BSDI Byte CODE:01A6 267 #285
+CPM Byte CODE:01AE 269 270 #287
+DEFAULT Byte CODE:014F 67 192 239 #251
+DEFAULTMSG Byte CODE:0142 164 #249
+DISKNUM Byte CODE:0141 123 #248
+DOS Byte CODE:017B 253 254 255 #276
+DOSSEC Byte CODE:01B6 272 #289
+DRIVEOK Near CODE:006E 118 #120
+ENDNAMELOOP Near CODE:00AA 150 #153
+ENTER_SCANCODE Number 001C #9 197
+ENTRY Near CODE:0067 57 #116
+F1_SCANCODE Number 003B #8 199
+FKEYMSG Byte CODE:0131 141 171 #245
+FREEBSD Byte CODE:019F 266 #284
+HAVE2DISKS Near CODE:00CC 162 #170
+HPFS Byte CODE:017E 256 #277
+KEY Byte CODE:0134 130 158 #246
+LINUX Byte CODE:0194 262 263 264 #282
+LOAD Near CODE:001B #64 208
+LOADBOOT Near CODE:0050 89 #97
+LOADDEFAULT Near CODE:00EC #191 198
+MENU Near CODE:0078 78 80 101 103 #127 169
+MENULOOP Near CODE:0085 #132 159
+MINIX Byte CODE:018F 261 #281
+NAMELOOP Near CODE:009D #145 152
+NAMETABLE Byte CODE:0151 144 #253
+NAMTAB Near CODE:017B 154 253 254 255 256 257 258 259 260 261 262 263 264 265 +
+ 266 267 268 269 270 271 272 273 #275
+NEWLINE Byte CODE:012F 207 #244
+NEXT Near CODE:00B1 136 138 #156
+NONAME Byte CODE:01BC 273 #290
+NOVELL Byte CODE:0189 259 260 #280
+NUMDISKS Number 0475 #15 161
+OS2 Byte CODE:0182 257 #278
+OUTPUT Near CODE:010B 142 155 172 174 #215 224
+PARTAB Number 01BE #14 72 128
+PCIX Byte CODE:01AA 268 #286
+PROMPT Near CODE:00D2 166 #173
+ Turbo Assembler Version 3.1 11/14/95 18:41:36 Page 8
+Symbol Table
+
+
+
+REPLY Near CODE:00F1 187 #194
+REPROMPT Near CODE:00D5 #175 202 204
+SAVEBOOT Near CODE:011A 83 94 #231
+STDBASE Number 7C00 #12 28 45 98
+STDBASEENTRY Near DUMMY:7C00 #29 110
+SWITCHDRIVE Near CODE:0048 69 #93
+SYSTEMID Number 0004 #20 77 79 134 151
+TESTKEY Near CODE:00FB 193 #200
+TIMEOUT Number 0005 #10 179
+UNIX Byte CODE:0185 258 #279
+USED Number 01BE #292 293
+VENIX Byte CODE:01B1 271 #288
+WAITKEY Near CODE:00DE #183 190
+
+Groups & Segments Bit Size Align Combine Class Cref (defined at #)
+
+CODE 16 0200 Para none #34 35 35 35 35
+DUMMY 16 7C00 AT 0000 #24 25
+ \ No newline at end of file
diff --git a/Bootinst.c b/Bootinst.c
new file mode 100644
index 0000000..f0e470a
--- /dev/null
+++ b/Bootinst.c
@@ -0,0 +1,256 @@
+/*
+ * Boot installator.
+ * Author: Serge Vakulenko, <vak@kiae.su>
+ */
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <dos.h>
+
+#define BOOTFILE "boot.bin"
+#define SAVEFILE "bootsav.bin"
+#define SAVE2FILE "boot2sav.bin"
+
+#define PartAddr 0x1be /* Offset to partition table */
+#define ValidationAddr 0x1fe /* Offset to validation bytes */
+#define MAGIC 0xaa55 /* Validation tag */
+
+#define DISK1 0
+#define DISK2 1
+#define READ 0
+#define WRITE 1
+
+typedef struct PartitionEntry {
+ unsigned char bootIndicator;
+ unsigned char beginHead;
+ unsigned char beginSector;
+ unsigned char beginCyl;
+ unsigned char systemId;
+ unsigned char endHead;
+ unsigned char endSector;
+ unsigned char endCyl;
+ unsigned short relSectorLow;
+ unsigned short relSectorHigh;
+ unsigned short numSectorsLow;
+ unsigned short numSectorsHigh;
+} PartitionEntry;
+
+unsigned char bootRecord [512];
+unsigned char bootProg [512];
+
+char head1 [] = "ÚÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄ¿\n";
+char head2 [] = "³ ³Partition³Can ³Boot³ Beginning ³ Ending ³ Relative³Number of³\n";
+char head3 [] = "³N³ Type ³Boot³Part³Head Cyl Sect³Head Cyl Sect³ Sectors ³ Sectors ³\n";
+char head4 [] = "ÃÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÅÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´\n";
+char mid1 [] = "³%d³%-9.9s³%-4.4s³%-4.4s³%3u ³%4u ³%3u ³%3u ³%4u ³%3u ³%8lu ³%8lu ³\n";
+char mid2 [] = "ÃÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ´\n";
+char foot [] = "ÀÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÙ\n";
+
+void printtable (disk)
+{
+ PartitionEntry *part = (PartitionEntry *) (bootRecord + PartAddr);
+ int i, cb;
+ long relSectors;
+ long numSectors;
+ char *typeString, block [512];
+
+ printf ("\n");
+ printf (head1);
+ printf (head2);
+ printf (head3);
+ printf (head4);
+
+ for (i=0; i<4; ++i) {
+ switch (part->systemId) {
+ default: typeString = " ?????"; cb = 1; break;
+ case 0: typeString = " empty"; cb = 0; break;
+ case 1: typeString = " dos-12"; cb = 1; break;
+ case 2: typeString = " xenix"; cb = 1; break;
+ case 3: typeString = "xenix usr"; cb = 0; break;
+ case 4: typeString = " dos-16"; cb = 1; break;
+ case 5: typeString = " extend"; cb = 0; break;
+ case 6: typeString = " bigdos"; cb = 1; break;
+ case 7: typeString = " hpfs"; cb = 1; break;
+ case 0x75: typeString = " pcix"; cb = 1; break;
+ case 0xdb: typeString = " cp/m"; cb = 1; break;
+ case 0xff: typeString = " bbt"; cb = 0; break;
+ case 0x08: typeString = " aix"; cb = 0; break;
+ case 0x09: typeString = " coherent"; cb = 1; break;
+ case 0x0A: typeString = " os/2"; cb = 1; break;
+ case 0x10: typeString = " opus"; cb = 1; break;
+ case 0x40: typeString = "venix 286"; cb = 1; break;
+ case 0x50:
+ case 0x51: typeString = " dm"; cb = 1; break;
+ case 0x52: typeString = "microport"; cb = 1; break;
+ case 0x56: typeString = " gb"; cb = 1; break;
+ case 0x61:
+ case 0xE1:
+ case 0xE3:
+ case 0xE4:
+ case 0xF1:
+ case 0xF4: typeString = " speed"; cb = 1; break;
+ case 0x63: typeString = " unix"; cb = 1; break;
+ case 0x64: typeString = "novell286"; cb = 1; break;
+ case 0x65: typeString = "novell386"; cb = 1; break;
+ case 0x80: typeString = "old minix"; cb = 1; break;
+ case 0x81: typeString = " minix"; cb = 1; break;
+ case 0x82: typeString = " linux"; cb = 1; break;
+ case 0x93: typeString = " amoeba"; cb = 1; break;
+ case 0x94: typeString = "amoebaBBT"; cb = 0; break;
+ case 0xA5: typeString = " 386bsd"; cb = 1; break;
+ case 0x9f:
+ case 0xB7: typeString = " bsdi"; cb = 1; break;
+ case 0xB8: typeString = "bsdi swap"; cb = 0; break;
+ case 0xF2: typeString = " dos sec"; cb = 1; break;
+ }
+ relSectors = part->relSectorLow |
+ (unsigned long) part->relSectorHigh<<16;
+ numSectors = part->numSectorsLow |
+ (unsigned long) part->numSectorsHigh<<16;
+
+ if (cb && (bootio (disk, READ, part->beginHead, part->beginCyl,
+ part->beginSector, block) != 0 ||
+ *(short *) &block [ValidationAddr] != (short) MAGIC))
+ cb = 0;
+
+ printf (mid1, i+1, typeString, cb ? " yes" : " no",
+ (part->bootIndicator & 0x80) ? " yes" : " no",
+ part->beginHead, part->beginCyl |
+ part->beginSector<<2 & 0x300,
+ part->beginSector & 077, part->endHead,
+ part->endCyl | part->endSector<<2 & 0x300,
+ part->endSector & 077, relSectors, numSectors);
+ if (i < 3)
+ printf (mid2);
+ ++part;
+ }
+ printf (foot);
+}
+
+int yes ()
+{
+ char reply [80];
+
+ printf (" (yes/no) ");
+ fgets (reply, sizeof (reply), stdin);
+ return (!stricmp (reply, "y\n") || !stricmp (reply, "yes\n"));
+}
+
+int install (disk, file, savefile)
+char *file, *savefile;
+{
+ int rc, fd;
+
+ rc = bootio (disk, READ, 0, 0, 1, bootRecord);
+ if (rc) {
+ fprintf (stderr, "Error %d reading boot record from disk %d\n",
+ rc, disk);
+ return (-1);
+ }
+ if (*(short *) &bootRecord [ValidationAddr] != (short) MAGIC) {
+ fprintf (stderr, "Bad master boot record on disk %d!\n",
+ disk);
+ return (-1);
+ }
+
+ printtable (disk);
+
+ fd = open (file, O_RDONLY|O_BINARY);
+ if (fd < 0) {
+ fprintf (stderr, "Cannot read file %s\n", file);
+ return (-1);
+ }
+ if (read (fd, bootProg, 512) != 512) {
+ fprintf (stderr, "Error reading %s\n", file);
+ return (-1);
+ }
+ close (fd);
+ if (*(short *) &bootProg [ValidationAddr] != (short) MAGIC) {
+ fprintf (stderr, "Bad boot image in file %s\n", file);
+ return (-1);
+ }
+
+ printf ("\nAre you sure you want to install new boot on disk %d?",
+ disk);
+ if (! yes ())
+ return (0);
+
+ close (creat (savefile, 0664));
+ fd = open (savefile, O_WRONLY|O_BINARY);
+ if (fd < 0) {
+ fprintf (stderr, "Cannot write to file %s\n", savefile);
+ return (-1);
+ }
+ if (write (fd, bootRecord, 512) != 512) {
+ fprintf (stderr, "Error writing to %s\n", savefile);
+ return (-1);
+ }
+ close (fd);
+
+ memcpy (bootRecord, bootProg, PartAddr);
+
+ rc = bootio (disk, WRITE, 0, 0, 1, bootRecord);
+ if (rc) {
+ fprintf (stderr, "Error %d updating boot record on disk %d\n",
+ rc, disk);
+ return (-1);
+ }
+ printf ("New boot record successfully installed.\n");
+ return (0);
+}
+
+bootio (disk, op, head, cyl, sect, buf)
+char *buf;
+{
+ return (biosdisk (op==WRITE ? 3 : 2, disk==DISK1 ? 0x80 : 0x81,
+ head, cyl, sect, 1, buf));
+}
+
+int main (argc, argv)
+char **argv;
+{
+ char *bootfile;
+ int disk2present;
+
+ printf ("Boot installer, version 1.7, Copyright (C) Serge Vakulenko\n\n");
+
+ printf ("This utility allows you to install new boot program on your\n");
+ printf ("hard disk. The usage is:\n\n");
+ printf (" bootinst [bootfile]\n\n");
+ printf ("It installs boot block from bootfile (default boot.bin) to the first\n");
+ printf ("drive and, if second drive is present, to the second drive.\n");
+ printf ("Old boot sectors are saved to bootsav.bin and boot2sav.bin respectively.\n");
+ printf ("\nYou can copy and distribute this software free of charge,\n");
+ printf ("provided that sources are included. No warranty, of course.\n\n");
+
+ if (argc > 3)
+ return (-1);
+
+ bootfile = argc>1 ? argv[1] : BOOTFILE;
+ if (access (bootfile, 4) < 0) {
+ perror (bootfile);
+ return (-1);
+ }
+
+ /*
+ * Is second disk present? Try to read boot sector,
+ * check that it is bootable and has valid partition table.
+ */
+ disk2present = (bootio (DISK2, READ, 0, 0, 1, bootRecord) == 0 &&
+ *(short *) &bootRecord [ValidationAddr] == (short) MAGIC &&
+ (bootRecord [PartAddr] == 0 || bootRecord [PartAddr] == 0x80) &&
+ (bootRecord [PartAddr+16] == 0 || bootRecord [PartAddr+16] == 0x80) &&
+ (bootRecord [PartAddr+32] == 0 || bootRecord [PartAddr+32] == 0x80) &&
+ (bootRecord [PartAddr+48] == 0 || bootRecord [PartAddr+48] == 0x80));
+
+ printf ("Continue with installation?");
+ if (! yes ())
+ return (0);
+
+ install (DISK1, bootfile, SAVEFILE);
+
+ if (disk2present)
+ install (DISK2, bootfile, SAVE2FILE);
+
+ return (0);
+}
diff --git a/Compile.bat b/Compile.bat
new file mode 100644
index 0000000..8b3ca5d
--- /dev/null
+++ b/Compile.bat
@@ -0,0 +1,8 @@
+tasm /l /c /m3 boot
+link /noi /noe /farcall boot,,;
+@del boot.obj
+@del boot.map
+exe2bin boot.exe boot.bin
+@del boot.exe
+tcc -G -O -Z -d -ebootinst bootinst.c
+@del bootinst.obj \ No newline at end of file
diff --git a/Readme b/Readme
new file mode 100644
index 0000000..99a589a
--- /dev/null
+++ b/Readme
@@ -0,0 +1,57 @@
+This is a program, called BOOTEASY, version 1.7.
+It serves as a replacement for the ordinary master boot.
+It is very simple in installation, and quite intelligent
+in handling various types of partitions.
+
+BOOTEASY makes possible coexistence of several different operating
+systems on the same machine. At the boot time the short menu
+is displayed, and you can choose and load the required OS.
+
+You can also boot from second hard disk.
+
+Some useful features:
+
+1) Very simple installation. Just call BOOTINST and answer 'yes'
+to several questions.
+
+2) Saves the copy of original boot sector. You can restore it
+calling BOOTINST with a parameter - the name of the file with
+original boot sector. By default this is 'BOOTSAVE.BIN'.
+
+3) If no key is pressed during 5-second timeout, the default OS
+will boot.
+
+4) The last booted partition is remembered and used as a default.
+
+5) BOOTEASY marks the booted partition as active, which is required
+by some OS, such as Interactive Unix.
+
+6) If the second hard disk is present, you can boot from it.
+
+Changes in version 1.3:
+- Fixed error with activating loaded partition. Loaded
+ partition was not marked active in partition table.
+ Now it is activated correctly.
+
+Changes in version 1.4:
+- Fixed error with system timer 0 reset. Timer 0 was
+ cleared to zero after boot. Because MSDOS uses it (not RTC!)
+ as the real time value, the time was always 12:00.
+ Now system timer is not cleared.
+
+Changes in version 1.5:
+- Added the possibility to install on the second disk only.
+
+Changes in version 1.6:
+- Added the check of the drive number, got from the BIOS
+ in the DL register. Some BIOSes pass incorect value.
+
+Changes in version 1.7:
+- Partition type names changed from lower case to mixed upper/lower case.
+- Some program size optimizations added.
+
+BOOTEASY have been tested on Interactive Unix SVR3 and SVR4,
+386bsd, FreeBSD, BSD/386 (BSDI), MSDOS 3, 4 and 5, MINIX, Xenix,
+Windows NT, OS/2.
+
+Author: Serge Vakulenko, <vak@kiae.su>