forked from devekar/Bootloader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstage1.asm
221 lines (176 loc) · 5.28 KB
/
stage1.asm
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
; BIOS block
; Functions:
; Print
; ReadSectors
; LBAtoCHS
; ClustertoLBA
; MAIN:
; Set up registers
; LOAD_ROOT
; SEARCH_ROOT
; LOAD_FAT
; LOAD_STAGE2
bits 16
org 0
jmp MAIN
; BIOS Parameter Block with dummy data
;------------------------------------------
bpbOEM db "MyLoader" ;8
bpbBytesPerSector: DW 512 ;2
bpbSectorsPerCluster: DB 1 ;1
bpbReservedSectors: DW 1 ;2
;-----------
bpbNumberOfFATs: DB 2 ;1
bpbRootEntries: DW 224 ;2
bpbTotalSectors: DW 2880 ;2
bpbMedia: DB 0xf8 ;; 0xF1 ;1
bpbSectorsPerFAT: DW 9 ;2
bpbSectorsPerTrack: DW 18 ;2
bpbHeadsPerCylinder: DW 2 ;2
bpbHiddenSectors: DD 0 ;4
;------------
bpbTotalSectorsBig: DD 0 ;4
bsDriveNumber: DB 0 ;1
bsUnused: DB 0 ;1
bsExtBootSignature: DB 0x29 ;1
bsSerialNumber: DD 0xa0a1a2a3 ;4
bsVolumeLabel: DB "MOS FLOPPY " ;11
bsFileSystem: DB "FAT12 " ;8
; Print message referred by SI register
;--------------------------------------
Print:
lodsb
or al, al
jz PrintReturn
mov ah, 0eh
int 10h
jmp Print
PrintReturn:
ret
; Reads a series of sectors
; CX - Number of sectors to read
; AX - Starting sector
; ES:BX - Buffer to read to
;-----------------------------------
ReadSectors:
.MAIN_LOOP
mov di, 0x0005 ; five retries for error
.SECTORLOOP
push ax
push bx
push cx
call LBAtoCHS ; convert sector to CHS
mov ah, 0x02 ; BIOS read sector
mov al, 0x01 ; read one sector
mov ch, BYTE [absoluteTrack]
mov cl, BYTE [absoluteSector]
mov dh, BYTE [absoluteHead]
mov dl, BYTE [bsDriveNumber]
int 0x13 ; invoke interrupt
jnc .SUCCESS ; test for read error
xor ax, ax ; BIOS reset disk
int 0x13 ; invoke interrupt
dec di ; decrement error counter
pop cx
pop bx
pop ax
jnz .SECTORLOOP ; attempt to read again
int 0x18 ; Cannot read disk, invoke ROM BASIC
;jmp FAILURE
.SUCCESS
mov si, msgProgress
call Print
pop cx
pop bx
pop ax
add bx, WORD [bpbBytesPerSector] ; next buffer
inc ax ; next sector
loop .MAIN_LOOP ; read next sector
ret
; Convert LBA to CHS
; AX - LBA Address to convert
; absolute sector = (logical sector % sectors per track) + 1
; absolute head = (logical sector / sectors per track) MOD number of heads
; absolute track = (logical sector / sectors per track) / number of heads
;-----------------------------------------------------------------------------
LBAtoCHS:
xor dx, dx
div WORD [bpbSectorsPerTrack]
inc dl
mov BYTE [absoluteSector], dl
xor dx, dx
div WORD [bpbHeadsPerCylinder]
mov BYTE [absoluteHead], dl
mov BYTE [absoluteTrack], al
ret
; Convert CHS to LBA
; LBA = (cluster - 2) * sectors per cluster
;--------------------------------------------
ClustertoLBA:
sub ax, 0x0002
xor cx, cx
mov cl, BYTE [bpbSectorsPerCluster]
mul cx
add ax, WORD [datasector] ; base data sector
ret
;====================================================================
; MAIN
;====================================================================
MAIN:
; Set up registers
cli
mov ax, 0x07c0
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ax, 0x0000 ; set the stack
mov ss, ax
mov sp, 0xFFFF
sti
mov BYTE [bsDriveNumber], dl ; save boot drive number
mov si, msg ; print "Registers set up"
call Print
; stage2_sec = 1
; stage2_num_secs = 3
LOAD_STAGE2:
; destination for image in memory (0050:0000)
mov si, msgCRLF
call Print
xor cx, cx
xor dx, dx
mov ax, 0x0050
mov es, ax
mov bx, 0x0000
mov ax, 0x3 ; num of sectors to read into CX
xchg ax, cx
mov ax, 0x1 ; Starting sector in AX
call ReadSectors
DONE:
mov si, msgStage1
call Print
mov dl, BYTE [bsDriveNumber]
push WORD 0x0050 ; load Stage 2 address
push WORD 0x0000
retf ; simulate function return to Stage 2
FAILURE:
mov si, msgFailure
call Print
mov ah, 0x00
int 0x16 ; wait for key press
int 0x19 ; reset computer
absoluteSector db 0x00
absoluteHead db 0x00
absoluteTrack db 0x00
datasector dw 0x0000
cluster dw 0x0000
ImageName db "STAGE2 BIN"
;BootDrive db 0
msg db "Registers setup", 0Dh, 0Ah, 0
msgCRLF db 0x0D, 0x0A, 0x00 ;newline
msgStage1 db 0x0D, 0x0A,"Stage1 complete", 0Dh, 0Ah, 0
msgProgress db ".", 0x00
msgLOAD_ROOT db 0x0D, 0x0A, "Root loaded", 0x0A, 0x00
msgFailure db 0x0D, 0x0A, "ERROR : Press Any Key to Reboot", 0x0A, 0x00
times 510 - ($-$$) db 0
DW 0xAA55