summaryrefslogtreecommitdiff
path: root/Boot.asm
diff options
context:
space:
mode:
Diffstat (limited to 'Boot.asm')
-rw-r--r--Boot.asm296
1 files changed, 296 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