Many changes:
[Marmot.git] / boot.S
blob2e73d1420d63fb79e285cae4d6091314e82b962d
1         /* boot loader for Marmot */
3         /* 2k stack starting at 0x6000 */
4 #define BOOT_SS      0x400
5 #define BOOT_SP      0x2000
7 #define LOADER_START 0x8000
10         .section .boot, "xa"
12         .code16
13         .global _start
14 _start: jmp     around
17         /* BIOS parameter block */
19         .org    3
20 oem_signature:
21         .ascii  "=marmot="
23         /* DOSv2 */
24 sector_size:
25         .word   512
26 sectors_per_allocation_unit:
27         .byte   2
28 reserved_sectors:
29         .word   2
30 fat_count:
31         .byte   0
32 record_count:
33         .word   2
34 sectors_in_volume:
35         .word   2880
36 media_descriptor:
37         .byte   0xf0    /* 3.5" floppy */
38 sectors_per_fat:
39         .word   0
41         /* DOSv3.4 */
42 sectors_per_track:
43         .word   0
44 head_count:
45         .word   0
46 hidden_sector_count:
47         .long   0
48 sectors_in_volume_long:
49         .long   0
51         /* Marmot format */
53         .global loaderStart
54 loaderStart:
55         .word   0
56         .global loaderSectors
57 loaderSectors:
58         .word   0
59         .global bootPreferredVideoMode
60 bootPreferredVideoMode:
61         .word   0x0144          /* 1280x1024x32bpp */
64 around: cli
65         ljmp    $0, $boing
66 boing:  xor     %ax, %ax
67         mov     %ax, %ds
68         mov     %ax, %es
69         lss     BOOT_SS_SP, %sp
70         sti
72         mov     %dl, bootDevice
73         call    VideoInit
74         call    LoadRest
75         jmp     Loader
78         /*
79          * VideoInit --
80          *
81          *      Initialize the display.
82          *
83          */
84 VideoInit:
85         /* 80x25 16 colors */
86         movb    $0x03, %al      /* ah is already zeroed */
87         int     $0x10
88         /* disable cursor */
89         mov     $1, %ah
90         mov     $0x2000, %cx
91         int     $0x10
93         xor     %dx, %dx
94         call    MoveCursor
95         ret
98         /*
99          * MoveCursor --
100          *
101          *      Position the cursor to the coordinates in dx.
102          *
103          */
105 MoveCursor:
106         mov     $2, %ah
107         mov     $1, %bh
108         int     $0x10
109         ret
112         /*
113          * PrintMessage --
114          *
115          *      Print the message pointed to by si.
116          *
117          */
119 PrintMessage:
120         mov     $0x0e, %ah
121         mov     $0x0100, %bx
122 1:      lodsb
123         test    %al, %al
124         jz      1f
125         int     $0x10
126         jmp     1b
127 1:      ret
130         /*
131          * LoadRest --
132          *
133          *      Load the rest of the boot loader from disk into memory.
134          *
135          */
137 LoadRest:
138         call    ResetDevice
140         /* Get driver parameters */
141         mov     $8, %ah
142         mov     bootDevice, %dl
143         int     $0x13
144         jnc     1f
146         mov     $noParams, %si
147         jmp     Die
149 1:      /* Important values from int 13,8 are:
150          *    cx[5:0]  - sectors per track
151          *    dh       - heads
152          */
154         movb    %dh, driveHeads
155         and     $0x3f, %cx
156         movb    %cl, sectorsPerTrack
158         mov     esSave, %es
159         xor     %bx, %bx
160         xor     %ax, %ax
162 ReadLoop:
163         inc     %ax
164         cmpw    loaderSectors, %ax
165         jbe     1f
167         /* All done */
168         xor     %ax, %ax
169         mov     %ax, %es
170         ret
172 1:      mov     $3, %dx
173         mov     %dx, tries
174         mov     %ax, sector
176 _retry:
177         call    LBA2CHS
179         mov     $0x0201, %ax
180         mov     bootDevice, %dl
181         int     $0x13
182         jnc     1f
183         
184         /* read failed - reset and try again */
185         mov     sector, %ax
186         decw    tries
187         jnz     _retry
189         /* oops - too many tries */
190         mov     $readFailed, %si
191         jmp     Die
193 1:      addw    $0x20, esSave
194         mov     esSave, %es
195         mov     sector, %ax
196         jmp     ReadLoop
199         /*
200          * LBA2CHS --
201          *
202          *      Convert the block number in ax to a CHS value in cx and dh.
203          *
204          *      Clobbers ax, cx, dx
205          */
206         
207         .global LBA2CHS
208 LBA2CHS:
209         xor     %dx, %dx
210         divw    sectorsPerTrack
211         mov     %dx, chsScratch
213         xor     %dx, %dx
214         divw    driveHeads
216         /* Values are:
217          *
218          *     (%sp) sector
219          *     ax    cylinder
220          *     dx    head
221          */
223         shl     $8, %dx         /* dh => head */
224         mov     %ax, %cx
225         shl     $8, %cx         /* ch => low 8 bits of cylinder */
226         shr     $2, %ax
227         and     $0xc0, %al
228         movb    chsScratch, %cl
229         inc     %cl
230         and     $0x3f, %cl      /* cl[5:0] => sector */
231         or      %al, %cl        /* cl[7:6] => high 2 bits of cylinder */
233         .global LBA2CHS_Done
234 LBA2CHS_Done:
235         ret
238         /*
239          * ResetDevice --
240          *
241          *      Reset the disk controller for the boot device.
242          *
243          */
245 ResetDevice:
246         mov     bootDevice, %dl
247         mov     $0, %ah
248         int     $0x13
249         jc      1f
250         ret
252 1:      mov     $resetFailed, %si
254         /* fall through */
257         /*
258          * Die --
259          *
260          *      Print the message pointed to by %si and halt.
261          */
263         .global Die             /* so it's visible to VProbes */
264 Die:    xor     %dx, %dx
265         call    MoveCursor
266         push    %si
267         mov     $diskn, %si
268         call    PrintMessage
269         pop     %si
270         call    PrintMessage
271         mov     $failed, %si
272         pushw   $halt
273         jmp     PrintMessage
275 halt:   hlt
276         jmp     halt
279         /* %ss/%sp values for lss - saves a byte over two movs */
280 BOOT_SS_SP:
281         .word   BOOT_SP, BOOT_SS
282         /* %es value during load loop */
283 esSave:
284         .word   LOADER_START >> 4
285         /* start of string for Die */
286 diskn:
287         .asciz  "Disk "
288         /* end of string for Die */
289 failed:
290         .asciz  " failed!!!"
291         /* various strings for error messages */
292 resetFailed:
293         .asciz  "reset"
294 readFailed:
295         .asciz  "read"
296 noParams:
297         .asciz  "get params"
300         /* Master boot record */
302         .org    0x1b8
303 disk_signature:
304         .long   0xbebaefbe
305         .word   0
306 partitions:
307         .fill   64, 1, 0
308 signature:
309         .byte   0x55, 0xaa
312         /*
313          * .boot_bss --
314          *
315          *      Scratch area for the boot loader located at 0x7e00.
316          *
317          */
319         .section .boot_bss
320 bootDevice:
321         .byte   0
322 driveHeads:
323         .byte   0
324 sectorsPerTrack:
325         .byte   0
326 tries:
327         .byte   0
328 sector:
329         .word   0
330 chsScratch:
331         .word   0