1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
!
! This is a bootblock to load an execute a standalone program from an
! MSDOS filesystem on a floppy disk.
!
! The program is divided into two parts, the first 512 bytes contains a
! loader to fetch one block from a file called 'BOOTFILE.SYS' from the
! root directory of the disk. The second 512, which is stored in this file,
! loads the executable using functions supplied by the first.
!
! The 2nd part is loaded as if it's a floppy boot block and can be used to
! store, for instance, a LILO boot block to let LILO boot from an MSDOS
! floppy.
!
! The second part is NOT yet complete!
!
ORGADDR=$0500
use16
! Absolute position macro, fails if code before it is too big.
macro locn
if *-start>?1
fail! *-start>?1
endif
.blkb ?1 + start-*
mend
org ORGADDR
start:
include sysboot.s
! Data into the temp area, 30 clear bytes
org floppy_temp
root_count: .blkw 1
old_bpb: .blkw 2
bios_disk: .blkb 12
locn(codestart-start)
cld ! Assume _nothing_!
mov bx,#$7C00 ! Pointer to start of BB.
xor ax,ax ! Segs all to zero
mov ds,ax
mov es,ax
mov ss,ax
mov sp,bx ! SP Just below BB
mov cx,#$100 ! Move 256 words
mov si,bx ! From default BB
mov di,#ORGADDR ! To the correct address.
rep
movsw
jmpi cont,#0 ! Set CS:IP correct.
cont:
sti ! Let the interrupts back in.
! Need to fix BPB for fd0 to correct sectors (Like linux bootblock does)
mov di,#bios_disk
mov bp,#0x78
! 0:bx is parameter table address
push ds
lds si,[bp]
! ds:si is source
mov cx,#6
! copy 12 bytes
push di
rep
movsw
pop di
pop ds
! New BPB is 0:di
mov [bp],di
mov 2[bp],ax
mov al,[dos_spt]
mov 4[di],al
! For each sector in root dir
! For each dir entry
! If entry name is == boot_name
! then load and call sector
! First dir = dos_fatlen*dos_nfat+dos_resv
mov ax,[dos_fatlen]
mov dl,[dos_nfat]
xor dh,dh
mul dx
add ax,[dos_resv]
mov di,ax
! DI is sector number of first root dir sector.
mov ax,[dos_nroot]
mov [root_count],ax
add ax,#15
mov cl,#4
shr ax,cl
add ax,di
mov bp,ax ! bp is first data sector.
nextsect:
call linsect
mov ax,#$0201
int $13
jc floppy_error
! ... foreach dir entry
mov si,bx
nextentry:
! test entry name
push si
push di
mov di,#boot_name
mov cx,#11
rep
cmpsb
pop di
pop si
je got_entry
add si,#32
cmp si,#512
jnz nextentry
inc di
sub [root_count],#16
jp nextsect
jmp no_system
got_entry:
mov ax,[si+26] ! Cluster number of start of file
test ax,ax
jz no_system ! Make sure we have a block.
mov di,ax ! Save the cluster number we are loading.
call linclust
mov ax,#$0201
int $13
jc floppy_error
mov bx,#7
mov ax,#$0E3E
int $10
jmpi $7C00,0 ! No magics, just go.
! Convert a cluster number into a CHS in CX:DX
linclust:
sub ax,#2
mov dl,[dos_clust]
xor dh,dh
mul dx
add ax,bp
mov di,ax
! JMP linsect ...
!
! This function converts a linear sector number in DI
! into a CHS representation in CX:DX
!
linsect:
xor dx,dx
mov ax,di
div [dos_spt]
inc dx
mov cl,dl ! Sector num
xor dx,dx ! Drive 0
shr ax,#1 ! Assume dos_heads == 2
adc dh,#0 ! Head num
mov ch,al ! Cylinder
ret
no_system:
floppy_error:
mov si,#error_msg
no_boot: ! SI now has pointer to error message
lodsb
cmp al,#0
jz EOS
mov bx,#7
mov ah,#$E ! Can't use $13 cause that's AT+ only!
int $10
jmp no_boot
EOS:
xor ax,ax
int $16
int $19 ! This should be OK as we haven't touched anything.
jmpi $0,$FFFF ! Wam! Try or die!
error_msg:
.asciz "\r\nError during initial boot\r\nPress a key:"
export boot_name
boot_name:
.ascii "BOOTFILESYS"
name_end:
! NNNNNNNNEEE
!
!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
!
! Part 2, loaded like a boot block by part 1
! ... Here we will allow some assumptions (cause we've set them)
fat_table = ORGADDR+$400 ! Where to load the fat
locn(512)
part2_addr:
push di
mov cx,#$100 ! Move 256 words
mov si,#$7C00 ! From default BB
mov di,#part2_addr ! To the correct address.
rep
movsw
jmpi cont2,#0 ! Set CS:IP correct.
cont2:
! 1) Load FAT
! This assumes all of FAT1 is on the first track, this is normal
mov ax,[dos_fatlen]
mov ah,#2
mov bx,#fat_table
mov cx,[dos_resv] ! Fat starts past bootblock
inc cx
xor dx,dx ! Head zero
int $13
!jc floppy_error
mov bx,#$7C00
pop di ! Cluster to start load.
! load whole cluster
next_cluster:
call next_fat
cmp di,#0
jnz next_cluster
br maincode
next_fat:
!mov ax,di
!mov bx,ax
!shr ax,#1
!add bx,ax
! The end ... place a marker.
locn(1023)
.byte $FF
maincode:
|