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
8 CSEG SEGMENT WORD 'Code' USE16
\r
9 ASSUME CS:CSEG, DS:CSEG, ES:Nothing
\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
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
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
40 Volname DB 'RICH ' ;11 bytes for volume name
\r
41 FatType DB 'FAT12 ' ;8 bytes for FAT name (Type)
\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
47 IDTptr DW 7FFh ;LIMIT 256 IDT Slots
\r
48 DD 0000h ;BASE (Linear)
\r
50 GDTptr DW 17FFh ;LIMIT 768 slots
\r
51 DD 0800h ;BASE (Linear)
\r
53 ;This is where we jump from those first 3 bytes
\r
57 ;Boot blocks first instruction starts here after initial jump from beginning
\r
58 CLI ;Clear interrupts
\r
60 ;Stick the stack at 98000h (an arbitrary location)
\r
66 ;Move this boot sector UP to 90000h Linear.
\r
77 ; Now we jump UP to where we moved it.
\r
79 MOV AX, 09000h ;Segment
\r
81 MOV AX, 6Fh ;Offset to new location
\r
85 ; Now set DS equal to ES which is 9000h
\r
88 MOV CX, nSectPerTrack
\r
92 MOV BX, 0078h ;Int 1E FDC Params!
\r
95 MOV BYTE PTR [SI+4], CL
\r
96 MOV BYTE PTR [SI+9], 0Fh
\r
104 MOV DL, bBootDrive ;Required for Disk System Reset
\r
107 INT 13h ;Reset Disk Controller (DL has drive num)
\r
108 JC SHORT BadBoot ;Reset failed...
\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
116 MOV SI, OFFSET MsgLoad
\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
127 ; Additional Reserved sectors (optional)
\r
128 ; Root Directory (n Sectors long)
\r
132 MUL WORD PTR nSectPerFAT
\r
133 ADD AX, WORD PTR nHidden ;
\r
134 ADC DX, WORD PTR nHidden+2
\r
136 MOV CX, AX ;Save in CX
\r
138 ;CX now has a Word that contains the sector of the Root
\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
144 MOV AX,0020h ;Size of Dir Entry
\r
145 MUL WORD PTR nRootDirEnts
\r
146 MOV BX, nBytesPerSect
\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
153 MOV CX, nOSSectors ;Number of OS sectors to read
\r
154 JMP SHORT ContinueBoot
\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
160 MOV SI, OFFSET MsgBadDisk
\r
164 INT 16h ;Wait for keystroke
\r
165 INT 19h ;Sys Reboot
\r
179 MOV BX, 06000h ;This is segment where we load the OS.
\r
190 ; Read a logical sector to ES:BX
\r
191 ; AX has Logical Sector Number
\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
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
207 INT 13h ;Read that sucker!
\r
210 MOV SI, OFFSET MsgDot
\r
219 ADD BX, 20h ;512 bytes for segment
\r
221 INC AX ;Next Sector
\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
250 ;A20 line should be ON Now
\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
258 ; Move 64K data chunk from linear 60000h to linear 0
\r
268 REP MOVSW ;WORD move
\r
270 ; Move first 64K code chunk from linear 70000h to 10000h
\r
279 REP MOVSW ;WORD move
\r
281 ; Move last code (32K) from linear 80000h to 18000h
\r
283 MOV DS, DX ;DX is 8000h anyway
\r
289 REP MOVSB ;BYTE move
\r
295 MOV DL, bBootDrive ;OS can find bootdrive in DL on entry
\r
297 LIDT FWORD PTR IDTptr
\r
298 LGDT FWORD PTR GDTptr
\r
314 ;We define a far jump with 48 bit pointer manually
\r
323 MsgBadDisk DB 0Dh, 0Ah, 'Bad Boot Disk!', 00h
\r
324 MsgLoad DB 0Dh, 0Ah, 'Loading MMURTL', 00h
\r
332 ;Character Message stuff to save for troubleshooting
\r
336 ; MOV WORD PTR ES:[BX], 4730h
\r