]> pd.if.org Git - mmurtl/blob - mscode16/bootcode/bootblok.asm
autocommit for file dated 1995-02-09 16:00:32
[mmurtl] / mscode16 / bootcode / bootblok.asm
1 .386P\r
2 ;This boot sector is STUFFed to the gills to do a single\r
3 ;stage boot of the MMURTL OS which is about 160K stored as\r
4 ;a loadable image beginning at cluster 2 on the disk. The OS must\r
5 ;be stored contiguously in each of the following logical sectors.\r
6 ;The actual number of sectors is stored in the data param nOSSectors.\r
7 \r
8 CSEG    SEGMENT WORD 'Code' USE16\r
9         ASSUME CS:CSEG, DS:CSEG, ES:Nothing\r
10 \r
11 ORG     0h\r
12 \r
13         JMP SHORT Bootup\r
14         NOP\r
15 \r
16 ;This 59 byte structure follows the 3 jump bytes above\r
17 ;and is found on all MS-DOS FAT compatible\r
18 ;disks. This contains additional information about the file system\r
19 ;on this disk that the operating needs to know. The boot sector code also\r
20 ;needs some of this information if this is a bootable disk.\r
21 \r
22 Herald          DB   'MURTL1.0'\r
23 nBytesPerSect   DW   0200h              ;nBytes/Sector\r
24 nSectPerClstr   DB   01h                ;Sect/Cluster\r
25 nRsvdSect       DW   0001h              ;Resvd sectors\r
26 nFATS           DB   02                 ;nFATs\r
27 nRootDirEnts    DW   00E0h              ;Root Dir entries max\r
28 nTotalSectors   DW   0B40h              ;nTotal Sectors (0 = <32Mb)\r
29 bMedia          DB   0F0h               ;media desc. (worthless)\r
30 nSectPerFAT     DW   0009h              ;nSect in FAT\r
31 nSectPerTrack   DW   0012h              ;nSectors/track\r
32 nHeads          DW   0002h              ;nHeads\r
33 nHidden         DD   00000000h  ;nHidden Sectors (first whole track on HD)\r
34 nTotalSect32    DD   00000000h  ;nTotalSectors if > 32Mb\r
35 bBootDrive              DB   00h                ;Drive boot sector came from\r
36 ResvdByte       DB   00h                ;Used for temp storage of Sector to Read\r
37 ExtBootSig      DB   29h                ; Ext Boot Signature (always 29h)\r
38 nOSSectors              DW   0140h      ; (140 sectors max) Was Volume ID number\r
39 ResvdWord               DW   0000h\r
40 Volname                 DB   'RICH       '      ;11 bytes for volume name\r
41 FatType                 DB   'FAT12   '         ;8 bytes for FAT name (Type)\r
42 \r
43 \r
44 ;The following are pointers to my IDT and GDT after my OS loads\r
45 ; and are not part of the above boot sector structure.\r
46 \r
47 IDTptr          DW 7FFh                 ;LIMIT 256 IDT Slots\r
48                     DD 0000h                ;BASE (Linear)\r
49 \r
50 GDTptr          DW 17FFh                ;LIMIT 768 slots\r
51                 DD 0800h                ;BASE (Linear)\r
52 \r
53 ;This is where we jump from those first 3 bytes\r
54 \r
55 BootUp:\r
56 \r
57 ;Boot blocks first instruction starts here after initial jump from beginning\r
58     CLI                                 ;Clear interrupts\r
59 \r
60         ;Stick the stack at 98000h (an arbitrary location)\r
61 \r
62     MOV  AX,9000h\r
63     MOV  SS, AX\r
64         MOV  SP, 8000h\r
65 \r
66 ;Move this boot sector UP to 90000h Linear.\r
67 \r
68         MOV  AX, 09000h\r
69         MOV  ES, AX\r
70         XOR  DI, DI\r
71         MOV      AX, 7C0h\r
72         MOV  DS, AX\r
73         XOR  SI, SI\r
74         MOV  CX, 512\r
75     REP  MOVSB\r
76 \r
77         ; Now we jump UP to where we moved it.\r
78 \r
79         MOV AX, 09000h          ;Segment\r
80         PUSH AX\r
81         MOV AX, 6Fh                     ;Offset to new location\r
82         PUSH AX\r
83         RETF\r
84 \r
85 ; Now set DS equal to ES which is 9000h\r
86         PUSH ES\r
87         POP  DS\r
88         MOV CX, nSectPerTrack\r
89 \r
90         XOR AX, AX\r
91         MOV DS, AX\r
92     MOV  BX, 0078h         ;Int 1E FDC Params!\r
93     LDS  SI, DS:[BX]\r
94 \r
95     MOV  BYTE PTR [SI+4], CL\r
96         MOV  BYTE PTR [SI+9], 0Fh\r
97 \r
98         PUSH ES\r
99         POP DS\r
100         PUSH DS\r
101 \r
102     STI\r
103 \r
104         MOV DL, bBootDrive              ;Required for Disk System Reset\r
105         XOR AX, AX\r
106 \r
107     INT  13h                            ;Reset Disk Controller (DL has drive num)\r
108     JC   SHORT BadBoot          ;Reset failed...\r
109 \r
110         POP DS\r
111 \r
112     ;The controller is reset, now let's read some stuff!!\r
113         ;We are gonna skip checking to see if the first file\r
114         ;really IS the OS. We need the space for other code.\r
115 \r
116     MOV  SI, OFFSET MsgLoad\r
117     CALL PutChars\r
118 \r
119         ;What we do now is calcualte our way to the third cluster\r
120         ;on the disk and read in the total number of OS sectors in\r
121         ;logical sector order. (3rd cluster is really the first allocated\r
122         ; cluster because first 2 are unused).\r
123         ;The layout of the Disk is:\r
124         ;       Boot Sector (at logical sector 0)\r
125         ;   Hidden Sectors (optional)\r
126         ;       FATS (1 or more)\r
127         ;   Additional Reserved sectors (optional)\r
128         ;       Root Directory (n Sectors long)\r
129 \r
130         XOR AX, AX\r
131     MOV  AL, nFATS\r
132     MUL  WORD PTR nSectPerFAT\r
133     ADD  AX, WORD PTR nHidden   ;\r
134     ADC  DX, WORD PTR nHidden+2\r
135     ADD  AX, nRsvdSect\r
136         MOV  CX, AX                             ;Save in CX\r
137 \r
138         ;CX now has a Word that contains the sector of the Root\r
139 \r
140         ;Calculate the size of the root directory and skip past it\r
141         ;to the first allocated sectors (this is where the OS or\r
142         ;stage one of the a two stage loader should be).\r
143 \r
144     MOV  AX,0020h                       ;Size of Dir Entry\r
145     MUL  WORD PTR nRootDirEnts\r
146     MOV  BX, nBytesPerSect\r
147     DIV  BX\r
148         ADD  AX, CX\r
149 \r
150         ;AX is at sector for cluster 0, but cluster 0 and 1 don't exist\r
151         ;so we are really at cluster 2 like we want to be.\r
152 \r
153     MOV  CX, nOSSectors ;Number of OS sectors to read\r
154         JMP SHORT ContinueBoot\r
155 \r
156 ;Bad boot goes here and displays a message then\r
157 ;waits for a key to reboot (or tries to) via int 19h\r
158 \r
159 BadBoot:\r
160     MOV  SI, OFFSET MsgBadDisk\r
161     CALL PutChars\r
162 \r
163     XOR  AX,AX\r
164     INT  16h            ;Wait for keystroke\r
165     INT  19h        ;Sys Reboot\r
166 \r
167 PutChars:\r
168     LODSB\r
169     OR   AL,AL\r
170     JZ   SHORT Done\r
171     MOV  AH, 0Eh\r
172     MOV  BX,0007\r
173     INT  10h\r
174     JMP  SHORT PutChars\r
175 Done:\r
176         RETN\r
177 \r
178 ContinueBoot:\r
179     MOV  BX, 06000h    ;This is segment where we load the OS.\r
180     MOV  ES, BX\r
181 \r
182 NextSector:\r
183     PUSH AX\r
184     PUSH CX\r
185     PUSH DX\r
186         PUSH ES\r
187 \r
188         XOR BX, BX\r
189 \r
190 ; Read a logical sector to ES:BX\r
191 ; AX has Logical Sector Number\r
192 ;\r
193         MOV  SI, nSectPerTrack\r
194     DIV  SI                                     ;Divide LogicalSect by nSectPerTrack\r
195     INC  DL                                     ;Sector numbering begins at 1 (not 0)\r
196     MOV  ResvdByte, DL                  ;Sector to read\r
197     XOR  DX, DX                         ;Logical Track left in AX\r
198     DIV  WORD PTR nHeads        ;Leaves Head in DL, Cyl in AX\r
199         MOV  DH, bBootDrive\r
200         XCHG DL, DH                             ;Head to DH, Drive to DL\r
201         MOV  CX, AX                             ;Cyl into CX\r
202         XCHG CL, CH                             ;Low 8 bits of Cyl to CH, Hi 2 bits to CL\r
203         SHL  CL, 6                              ;  shifted to bits 6 and 7\r
204         OR   CL, BYTE PTR ResvdByte     ;OR with Sector number\r
205         MOV  AL, 1                              ;Number of sectors\r
206     MOV  AH, 2                          ;Read\r
207     INT  13h                            ;Read that sucker!\r
208     JC   SHORT BadBoot\r
209 \r
210     MOV  SI, OFFSET MsgDot\r
211     CALL PutChars\r
212 \r
213     POP  ES\r
214     POP  DX\r
215     POP  CX\r
216     POP  AX\r
217 \r
218         MOV  BX, ES\r
219         ADD  BX, 20h    ;512 bytes for segment\r
220         MOV  ES, BX\r
221         INC  AX                 ;Next Sector\r
222     LOOP NextSector\r
223 \r
224         ;At this point we have the OS loaded in a contigous section\r
225         ;from 60000 linear up to about 80000 linear.\r
226         ;Now we disable interrupts, turn on the A20 line, move\r
227         ;it down to address 0, set protected mode and JUMP!\r
228 \r
229         CLI\r
230         XOR CX,CX\r
231 IBEmm0:\r
232         IN AL,64h\r
233         TEST AL,02h\r
234         LOOPNZ IBEmm0\r
235         MOV AL,0D1h\r
236         OUT 64h,AL\r
237         XOR CX,CX\r
238 IBEmm1:\r
239         IN AL,64h\r
240         TEST AL,02h\r
241         LOOPNZ IBEmm1\r
242         MOV AL,0DFh\r
243         OUT 60h,AL\r
244         XOR CX,CX\r
245 IBEmm2:\r
246         IN AL,64h\r
247         TEST AL,02h\r
248         LOOPNZ IBEmm2\r
249 \r
250         ;A20 line should be ON Now\r
251         ;So move the OS\r
252 \r
253         ; Set up our new DS to where we moved the data\r
254         ; We must do this before each 32K load cause we use DS */\r
255 \r
256         MOV DX, 8000h\r
257 \r
258         ; Move 64K data chunk from linear 60000h to linear 0\r
259 \r
260         MOV BX, 06000h\r
261         MOV DS, BX\r
262         XOR SI, SI\r
263         XOR AX, AX\r
264         MOV ES,AX\r
265         XOR DI,DI\r
266         MOV CX, DX\r
267         CLD                     ;\r
268         REP MOVSW                               ;WORD move\r
269 \r
270         ; Move first 64K code chunk from linear 70000h to 10000h\r
271 \r
272         MOV BX, 07000h\r
273         MOV DS, BX\r
274         XOR SI, SI\r
275         MOV AX,1000h\r
276         MOV ES,AX\r
277         XOR DI,DI\r
278         MOV CX, DX\r
279         REP MOVSW                               ;WORD move\r
280 \r
281         ; Move last code (32K) from linear 80000h to 18000h\r
282 \r
283         MOV DS, DX                              ;DX is 8000h anyway\r
284         XOR SI, SI\r
285         MOV AX,2000h\r
286         MOV ES,AX\r
287         XOR DI,DI\r
288         MOV CX, DX\r
289         REP MOVSB                               ;BYTE move\r
290 \r
291         MOV BX, 9000h\r
292         MOV DS, BX\r
293 \r
294         XOR EDX, EDX\r
295         MOV DL, bBootDrive              ;OS can find bootdrive in DL on entry\r
296 \r
297         LIDT FWORD PTR IDTptr\r
298         LGDT FWORD PTR GDTptr\r
299 \r
300         MOV EAX,CR0\r
301         OR AL,1\r
302         MOV CR0,EAX\r
303         JMP $+2\r
304         NOP\r
305         NOP\r
306 \r
307     MOV BX, 10h\r
308         MOV DS,BX\r
309         MOV ES,BX\r
310         MOV FS,BX\r
311         MOV GS,BX\r
312         MOV SS,BX\r
313 \r
314         ;We define a far jump with 48 bit pointer manually\r
315 \r
316         DB 66h\r
317         DB 67h\r
318         DB 0EAh\r
319         DD 10000h\r
320         DW 8h\r
321 \r
322 MsgNone     DB '                                '\r
323 MsgBadDisk  DB 0Dh, 0Ah, 'Bad Boot Disk!', 00h\r
324 MsgLoad     DB 0Dh, 0Ah, 'Loading MMURTL', 00h\r
325 MsgDot      DB '.', 00h\r
326 \r
327 BootSig   DW 0AA5Fh\r
328 \r
329 CSEG    ENDS\r
330         END\r
331 \r
332 ;Character Message stuff to save for troubleshooting\r
333 ;       MOV BX, 0B800h\r
334 ;       MOV ES, BX\r
335 ;       XOR BX,BX\r
336 ;       MOV WORD PTR ES:[BX], 4730h\r