1 ! jumpboot
1.0 - Jump to another bootstrap Author
: Kees J. Bot
4 ! This code may
be placed into any free boot sector
, like the first sector
5 ! of an extended partition
, a file system partition other than the root
,
6 ! or even the master bootstrap. It will load
and run another bootstrap whose
7 ! disk
, partition
, and slice number
(not necessarily all three
) are patched
8 ! into this code by installboot. If the ALT key is held down when this code
9 ! is booted then you can type the disk
, partition
, and slice numbers manually.
10 ! The manual interface is default if no numbers are patched in by installboot.
13 o32
= 0x66 ! This assembler doesn
't know 386 extensions
14 LOADOFF = 0x7C00 ! 0x0000:LOADOFF is where this code is loaded
15 BUFFER = 0x0600 ! First free memory
16 PART_TABLE = 446 ! Location of partition table within master
17 PENTRYSIZE = 16 ! Size of one partition table entry
18 MAGIC = 510 ! Location of the AA55 magic number
28 ! Find and load another bootstrap and jump to it.
34 mov ss, ax ! ds = es = ss = Vector segment
38 ! Move this code to safety, then jump to it.
39 mov si, sp ! si = start of this code
40 mov di, #BUFFER ! di = Buffer area
41 mov cx, #512/2 ! One sector
44 jmpf BUFFER+migrate, 0 ! To safety
47 mov bp, #BUFFER+guide ! Patched guiding characters
49 movb ah, #0x02 ! Keyboard shift status
51 testb al, #0x08 ! Bit 3 = ALT key
52 jz noalt ! ALT key pressed?
54 mov bp, #zero ! Ignore patched stuff
57 ! Follow guide characters to find the boot partition.
59 .ascii "d?\b\0" ! Initial greeting
63 movb dl, #0x80 - 0x30 ! Prepare to add an ASCII digit
64 call getch ! Get number to tell which disk
65 addb dl, al ! dl = 0x80 + (al - '0')
66 jns n0nboot ! Result should be >= 0x80
67 mov si, #BUFFER+zero-lowsec ! si = where lowsec(si) is zero
68 cmpb (bp), #0x23 ! Next guide character is '#'?
70 lea si
, 1-lowsec
(bp
) ! Logical sector offset follows
'#'
72 call load
! Load chosen sector of chosen disk
74 je boot
! Run bootstrap if
a logical is chosen
76 call print
! Intro to partition number
80 call getch
! Get character to tell partition
81 call gettable
! Get partition table
82 call sort
! Sort partition table
83 call choose_load
! Compute chosen entry
and load
85 cmpb sysind
(si
), #MINIX_PART ! Minix subpartition table possible?
88 call print
! Intro to slice number
92 call getch
! Get character to tell slice
93 call gettable
! Get partition table
94 call choose_load
! Compute chosen entry
and load
97 call print
! Intro to nothing
99 call getch
! Supposed to type RETURN now
100 n0nboot
:jmp nonboot
! Sorry
, can
't go further
102 ! Get a character, either the patched-in, or one from the keyboard.
104 movb al, (bp) ! Get patched-in character
109 getkey: xorb ah, ah ! Wait for keypress
111 gotkey: testb dl, dl ! Ignore CR if disk number not yet set
113 cmpb al, #0x0D ! Carriage return?
118 putch: movb ah, #0x0E ! Print character in teletype mode
119 mov bx, #0x0001 ! Page 0, foreground color
124 print: mov cx, si ! Save si
125 pop si ! si = String following 'call print
'
126 prnext: lodsb ! al = *si++ is char to be printed
127 testb al, al ! Null marks end
131 prdone: xchg si, cx ! Restore si
132 jmp (cx) ! Continue after the string
134 ! Return typed (or in patched data) means to run the bootstrap now in core!
136 call print ! Make line on screen look proper
138 jmp LOADOFF-BUFFER ! Jump to LOADOFF
140 ! Compute address of chosen partition entry from choice al into si, then
141 ! continue to load the boot sector of that partition.
143 subb al, #0x30 ! al -= '0'
144 cmpb al, #4 ! Only four partitions
147 mulb ah ! al *= PENTRYSIZE
148 add ax, #BUFFER+PART_TABLE
149 mov si, ax ! si = &part_table[al - '0']
150 movb al, sysind(si) ! System indicator
151 testb al, al ! Unused partition?
153 !jmp load ! Continue to load boot sector
155 ! Load boot sector of the current partition.
157 push dx ! Save drive code
158 push es ! Next call sets es
159 movb ah, #0x08 ! Code for drive parameters
162 andb cl, #0x3F ! cl = max sector number (1-origin)
163 incb dh ! dh = 1 + max head number (0-origin)
164 movb al, cl ! al = cl = sectors per track
165 mulb dh ! dh = heads, ax = heads * sectors
166 mov bx, ax ! bx = sectors per cylinder = heads * sectors
168 mov dx, lowsec+2(si) ! dx:ax = sector within drive
169 cmp dx, #[1024*255*63-255]>>16 ! Near 8G limit?
171 div bx ! ax = cylinder, dx = sector within cylinder
172 xchg ax, dx ! ax = sector within cylinder, dx = cylinder
173 movb ch, dl ! ch = low 8 bits of cylinder
174 divb cl ! al = head, ah = sector (0-origin)
175 xorb dl, dl ! About to shift bits 8-9 of cylinder into dl
177 shr dx, #1 ! dl[6..7] = high cylinder
178 orb dl, ah ! dl[0..5] = sector (0-origin)
179 movb cl, dl ! cl[0..5] = sector, cl[6..7] = high cyl
180 incb cl ! cl[0..5] = sector (1-origin)
181 pop dx ! Restore drive code in dl
182 movb dh, al ! dh = al = head
183 mov bx, #LOADOFF ! es:bx = where sector is loaded
184 mov ax, #0x0201 ! ah = Code for read / al = one sector
186 jmp rdeval ! Evaluate read result
188 mov bx, dx ! bx:ax = dx:ax = sector to read
189 pop dx ! Restore drive code in dl
191 mov si, #BUFFER+ext_rw ! si = extended read/write parameter packet
192 mov 8(si), ax ! Starting block number = bx:ax
194 movb ah, #0x42 ! Extended read
196 pop si ! Restore si to point to partition entry
202 .ascii "\r\nRead error\r\n\0"
205 cmp LOADOFF+MAGIC, #0xAA55
206 je sigok ! Signature ok?
209 .ascii "\r\nNot bootable\r\n\0"
214 ! Get the partition table into my space.
216 mov si, #LOADOFF+PART_TABLE
217 mov di, #BUFFER+PART_TABLE
218 mov cx, #4*PENTRYSIZE/2
222 ! Sort the partition table.
224 mov cx, #4 ! Four times is enough to sort
225 bubble: mov si, #BUFFER+PART_TABLE ! First table entry
226 bubble1:lea di, PENTRYSIZE(si) ! Next entry
227 cmpb sysind(si), ch ! Partition type, nonzero when in use
228 jz exchg ! Unused entries sort to the end
229 inuse: mov bx, lowsec+0(di)
230 sub bx, lowsec+0(si) ! Compute di->lowsec - si->lowsec
233 jae order ! In order if si->lowsec <= di->lowsec
235 xchgb bl, PENTRYSIZE(si) ! Exchange entries byte by byte
241 cmp si, #BUFFER+PART_TABLE+3*PENTRYSIZE
248 ! Extended read/write commands require a parameter packet.
250 .data1 0x10 ! Length of extended r/w packet
252 .data2 1 ! Blocks to transfer (just one)
253 .data2 LOADOFF ! Buffer address offset
254 .data2 0 ! Buffer address segment
255 .data4 0 ! Starting block number low 32 bits (tbfi)
256 zero: .data4 0 ! Starting block number high 32 bits
260 ! Guide characters and possibly a logical partition number patched here by
261 ! installboot, up to 6 bytes maximum.