wok diff BootProg/stuff/boot32.asm @ rev 24476
Add some current_version
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Fri Feb 18 09:29:30 2022 +0000 (2022-02-18) |
parents | |
children | 04472f031354 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/BootProg/stuff/boot32.asm Fri Feb 18 09:29:30 2022 +0000 1.3 @@ -0,0 +1,543 @@ 1.4 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.5 +;; ;; 1.6 +;; "BootProg" Loader v 1.5 by Alexey Frunze (c) 2000-2015 ;; 1.7 +;; 2-clause BSD license. ;; 1.8 +;; ;; 1.9 +;; ;; 1.10 +;; How to Compile: ;; 1.11 +;; ~~~~~~~~~~~~~~~ ;; 1.12 +;; nasm boot32.asm -f bin -o boot32.bin ;; 1.13 +;; ;; 1.14 +;; ;; 1.15 +;; Features: ;; 1.16 +;; ~~~~~~~~~ ;; 1.17 +;; - FAT32 supported using BIOS int 13h function 42h or 02h. ;; 1.18 +;; ;; 1.19 +;; - Loads a 16-bit executable file in the MS-DOS .COM or .EXE format ;; 1.20 +;; from the root directory of a disk and transfers control to it ;; 1.21 +;; (the "ProgramName" variable holds the name of the file to be loaded) ;; 1.22 +;; Its maximum size can be up to 636KB without Extended BIOS Data area. ;; 1.23 +;; ;; 1.24 +;; - Prints an error if the file isn't found or couldn't be read ;; 1.25 +;; ("File not found" or "Read error") ;; 1.26 +;; and waits for a key to be pressed, then executes the Int 19h ;; 1.27 +;; instruction and lets the BIOS continue bootstrap. ;; 1.28 +;; ;; 1.29 +;; ;; 1.30 +;; Known Limitations: ;; 1.31 +;; ~~~~~~~~~~~~~~~~~~ ;; 1.32 +;; - Works only on the 1st MBR partition which must be a PRI DOS partition ;; 1.33 +;; with FAT32 (File System ID: 0Bh,0Ch) ;; 1.34 +;; ;; 1.35 +;; ;; 1.36 +;; Known Bugs: ;; 1.37 +;; ~~~~~~~~~~~ ;; 1.38 +;; - All bugs are fixed as far as I know. The boot sector has been tested ;; 1.39 +;; on my HDD and an 8GB USB stick. ;; 1.40 +;; ;; 1.41 +;; ;; 1.42 +;; Memory Layout: ;; 1.43 +;; ~~~~~~~~~~~~~~ ;; 1.44 +;; The diagram below shows the typical memory layout. The actual location ;; 1.45 +;; of the boot sector and its stack may be lower than A0000H if the BIOS ;; 1.46 +;; reserves memory for its Extended BIOS Data Area just below A0000H and ;; 1.47 +;; reports less than 640 KB of RAM via its Int 12H function. ;; 1.48 +;; ;; 1.49 +;; physical address ;; 1.50 +;; +------------------------+ 00000H ;; 1.51 +;; | Interrupt Vector Table | ;; 1.52 +;; +------------------------+ 00400H ;; 1.53 +;; | BIOS Data Area | ;; 1.54 +;; +------------------------+ 00500H ;; 1.55 +;; | PrtScr Status / Unused | ;; 1.56 +;; +------------------------+ 00600H ;; 1.57 +;; | Loaded Image | ;; 1.58 +;; +------------------------+ nnnnnH ;; 1.59 +;; | Available Memory | ;; 1.60 +;; +------------------------+ A0000H - 2KB ;; 1.61 +;; | Boot Sector | ;; 1.62 +;; +------------------------+ A0000H - 1.5KB ;; 1.63 +;; | 1.5KB Boot Stack | ;; 1.64 +;; +------------------------+ A0000H ;; 1.65 +;; | Video RAM | ;; 1.66 +;; ;; 1.67 +;; ;; 1.68 +;; Boot Image Startup (register values): ;; 1.69 +;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;; 1.70 +;; dl = BIOS boot drive number (e.g. 80H) ;; 1.71 +;; cs:ip = program entry point ;; 1.72 +;; ss:sp = program stack (don't confuse with boot sector's stack) ;; 1.73 +;; COM program defaults: cs = ds = es = ss = 50h, sp = 0, ip = 100h ;; 1.74 +;; EXE program defaults: ds = es = EXE data - 10h (fake MS-DOS psp), ;; 1.75 +;; ax = 0ffffh (both FCB in the PSP don't have a valid drive identifier), ;; 1.76 +;; cs:ip and ss:sp depends on EXE header ;; 1.77 +;; Magic numbers: ;; 1.78 +;; si = 16381 (prime number 2**14-3) ;; 1.79 +;; di = 32749 (prime number 2**15-19) ;; 1.80 +;; bp = 65521 (prime number 2**16-15) ;; 1.81 +;; The magic numbers let the program know whether it has been loaded by ;; 1.82 +;; this boot sector or by MS-DOS, which may be handy for universal, bare- ;; 1.83 +;; metal and MS-DOS programs. ;; 1.84 +;; ;; 1.85 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.86 + 1.87 +%define bx(label) bx+label-boot 1.88 + 1.89 +[BITS 16] 1.90 +[CPU 8086] 1.91 + 1.92 +? equ 0 1.93 +ImageLoadSeg equ 60h 1.94 +StackSize equ 1536 1.95 + 1.96 +[SECTION .text] 1.97 +[ORG 0] 1.98 + 1.99 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.100 +;; Boot sector starts here ;; 1.101 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.102 + 1.103 +boot: 1.104 + jmp short start ; MS-DOS/Windows checks for this jump 1.105 + nop 1.106 +bsOemName DB "BootProg" ; 0x03 1.107 + 1.108 +;;;;;;;;;;;;;;;;;;;;;; 1.109 +;; BPB1 starts here ;; 1.110 +;;;;;;;;;;;;;;;;;;;;;; 1.111 + 1.112 +bpbBytesPerSector DW ? ; 0x0B 1.113 +bpbSectorsPerCluster DB ? ; 0x0D 1.114 +bpbReservedSectors DW ? ; 0x0E 1.115 +bpbNumberOfFATs DB ? ; 0x10 1.116 +bpbRootEntries DW ? ; 0x11 1.117 +bpbTotalSectors DW ? ; 0x13 1.118 +bpbMedia DB ? ; 0x15 1.119 +bpbSectorsPerFAT DW ? ; 0x16 1.120 +bpbSectorsPerTrack DW ? ; 0x18 1.121 +bpbHeadsPerCylinder DW ? ; 0x1A 1.122 +bpbHiddenSectors DD ? ; 0x1C 1.123 +bpbTotalSectorsBig DD ? ; 0x20 1.124 + 1.125 +;;;;;;;;;;;;;;;;;;;; 1.126 +;; BPB1 ends here ;; 1.127 +;;;;;;;;;;;;;;;;;;;; 1.128 + 1.129 +;;;;;;;;;;;;;;;;;;;;;; 1.130 +;; BPB2 starts here ;; 1.131 +;;;;;;;;;;;;;;;;;;;;;; 1.132 + 1.133 +bsSectorsPerFAT32 DD ? ; 0x24 1.134 +bsExtendedFlags DW ? ; 0x28 1.135 +bsFSVersion DW ? ; 0x2A 1.136 +bsRootDirectoryClusterNo DD ? ; 0x2C 1.137 +bsFSInfoSectorNo DW ? ; 0x30 1.138 +bsBackupBootSectorNo DW ? ; 0x32 1.139 +bsreserved times 12 DB ? ; 0x34 1.140 +bsDriveNumber DB ? ; 0x40 1.141 +bsreserved1 DB ? ; 0x41 1.142 +bsExtendedBootSignature DB ? ; 0x42 1.143 +bsVolumeSerialNumber DD ? ; 0x43 1.144 +bsVolumeLabel DB "NO NAME " ; 0x47 1.145 +bsFileSystemName DB "FAT32 " ; 0x52 1.146 + 1.147 +;;;;;;;;;;;;;;;;;;;; 1.148 +;; BPB2 ends here ;; 1.149 +;;;;;;;;;;;;;;;;;;;; 1.150 + 1.151 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.152 +;; Boot sector code starts here ;; 1.153 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.154 + 1.155 +start: 1.156 + cld 1.157 + 1.158 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.159 +;; How much RAM is there? ;; 1.160 +;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.161 + 1.162 + int 12h ; get conventional memory size (in KBs) 1.163 + mov cx, 106h 1.164 + dec ax 1.165 + dec ax ; reserve 2K bytes for the code and the stack 1.166 + shl ax, cl ; and convert it to 16-byte paragraphs 1.167 + 1.168 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.169 +;; Reserve memory for the boot sector and its stack ;; 1.170 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.171 + 1.172 + mov es, ax ; cs:0 = ds:0 = ss:0 -> top - 512 - StackSize 1.173 + mov ss, ax 1.174 + mov sp, 512+StackSize ; bytes 0-511 are reserved for the boot code 1.175 + 1.176 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.177 +;; Copy ourselves to top of memory ;; 1.178 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.179 + 1.180 + mov si, 7C00h 1.181 + xor di, di 1.182 + mov ds, di 1.183 + rep movsw ; move 512 bytes (+ 12) 1.184 + 1.185 +;;;;;;;;;;;;;;;;;;;;;; 1.186 +;; Jump to the copy ;; 1.187 +;;;;;;;;;;;;;;;;;;;;;; 1.188 + 1.189 + push es 1.190 + mov cl, main 1.191 + push cx 1.192 + retf 1.193 + 1.194 +main: 1.195 + push cs 1.196 + pop ds 1.197 + 1.198 + xor bx, bx 1.199 + mov [bx], dx ; store BIOS boot drive number 1.200 + 1.201 + and byte [bx(bsRootDirectoryClusterNo)+3], 0Fh ; mask cluster value 1.202 + les si, [bx(bsRootDirectoryClusterNo)] ; si2:si=cluster # of root dir 1.203 + mov si2, es 1.204 + 1.205 + mov cl, ImageLoadSeg 1.206 + mov es, cx 1.207 + 1.208 +RootDirReadContinue: 1.209 + call ReadCluster ; read one sector of root dir; clear ch 1.210 + pushf ; save carry="not last sector" flag 1.211 + 1.212 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.213 +;; Look for the COM/EXE file to load and run ;; 1.214 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.215 + 1.216 + xor di, di ; es:di -> root entries array 1.217 + 1.218 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.219 +;; Looks for the file/dir ProgramName ;; 1.220 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.221 +;; Input: ES:DI -> root directory array ;; 1.222 +;; BP = paragraphs count ;; 1.223 +;; Output: ESI = cluster number ;; 1.224 +;; DI = file paragraph count ;; 1.225 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.226 + 1.227 +FindNameCycle: 1.228 + cmp byte [es:di], bh 1.229 + je FindNameFailed ; end of root directory (NULL entry found) 1.230 + push si 1.231 + push di 1.232 + mov cl, 11 1.233 + mov si, ProgramName ; ds:si -> program name 1.234 + repe cmpsb 1.235 + pop di 1.236 + pop si 1.237 + je FindNameFound 1.238 + add di, 32 ; max cluster = 64k 1.239 + dec bp 1.240 + dec bp 1.241 + jnz FindNameCycle ; next root entry 1.242 + popf ; restore carry="not last sector" flag 1.243 + jc RootDirReadContinue ; continue to the next root dir cluster 1.244 +FindNameFailed: ; end of root directory (dir end reached) 1.245 + call Error 1.246 + db "File not found." 1.247 +FindNameFound: 1.248 + mov si2, word [es:di+14h] 1.249 + mov si, word [es:di+1Ah] ; si2:si = cluster no; cx = 0. 1.250 + 1.251 +============== 1.252 + dec dword [es:di+1Ch] ; load ((n - 1)/256)*16 +1 paragraphs 1.253 + imul di, [es:di+1Dh], 16 ; file size in paragraphs (full pages) 1.254 + 1.255 +;;;;;;;;;;;;;;;;;;;;;;;;;; 1.256 +;; Load the entire file ;; 1.257 +;;;;;;;;;;;;;;;;;;;;;;;;;; 1.258 + 1.259 + push es 1.260 +FileReadContinue: 1.261 + push di 1.262 + call ReadCluster ; read one more sector 1.263 + mov di, es 1.264 + add di, bp ; adjust segment for next sector 1.265 + mov es, di ; es:0 updated 1.266 + pop di 1.267 + sub di, bp 1.268 + jae FileReadContinue 1.269 +============== 1.270 + pop bp 1.271 + 1.272 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.273 +;; Type detection, .COM or .EXE? ;; 1.274 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.275 + 1.276 + mov dl, [bx] ; pass the BIOS boot drive 1.277 + mov ds, bp ; bp=ds=seg the file is loaded to 1.278 + 1.279 + add bp, [bx+08h] ; bp = image base 1.280 + mov ax, [bx+06h] ; ax = reloc items 1.281 + mov di, [bx+18h] ; di = reloc table pointer 1.282 + 1.283 + cmp word [bx], 5A4Dh ; "MZ" signature? 1.284 + je RelocateEXE ; yes, it's an EXE program 1.285 + 1.286 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.287 +;; Setup and run a .COM program ;; 1.288 +;; Set CS=DS=ES=SS SP=0 IP=100h ;; 1.289 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.290 + 1.291 + mov bp, ImageLoadSeg-10h ; "org 100h" stuff :) 1.292 + mov ss, bp 1.293 + xor sp, sp 1.294 + push bp ; cs, ds and es 1.295 + mov bh, 1 ; ip 1.296 + jmp short Run 1.297 + 1.298 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.299 +;; Relocate, setup and run a .EXE program ;; 1.300 +;; Set CS:IP, SS:SP, DS, ES and AX according ;; 1.301 +;; to wiki.osdev.org/MZ#Initial_Program_State ;; 1.302 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.303 + 1.304 +ReloCycle: 1.305 + add [di+2], bp ; item seg (abs) 1.306 + les si, [di] ; si = item ofs, es = item seg 1.307 + add [es:si], bp ; fixup 1.308 + scasw ; di += 2 1.309 + scasw ; point to next entry 1.310 + 1.311 +RelocateEXE: 1.312 + dec ax ; 32768 max (128KB table) 1.313 + jns ReloCycle ; leave with ax=0ffffh: both FCB in the 1.314 + ; PSP don't have a valid drive identifier 1.315 + les si, [bx+0Eh] 1.316 + add si, bp 1.317 + mov ss, si ; ss for EXE 1.318 + mov sp, es ; sp for EXE 1.319 + 1.320 + lea si, [bp-10h] ; ds and es both point to the segment 1.321 + push si ; containing the PSP structure 1.322 + 1.323 + add bp, [bx+16h] ; cs for EXE 1.324 + mov bx, [bx+14h] ; ip for EXE 1.325 +Run: 1.326 + pop ds 1.327 + push bp 1.328 + push bx 1.329 + push ds 1.330 + pop es 1.331 + 1.332 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.333 +;; Set the magic numbers so the program knows that it ;; 1.334 +;; has been loaded by this bootsector and not by MS-DOS ;; 1.335 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.336 + mov si, 16381 ; prime number 2**14-3 1.337 + mov di, 32749 ; prime number 2**15-19 1.338 + mov bp, 65521 ; prime number 2**16-15 1.339 + 1.340 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.341 +;; All done, transfer control to the program now ;; 1.342 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.343 + retf 1.344 + 1.345 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.346 +;; Reads a FAT32 cluster ;; 1.347 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.348 +;; Input: ES:0 -> buffer ;; 1.349 +;; EDX:EAX = sector no ;; 1.350 +;; CX = sectors to load ;; 1.351 +;; ESI = cluster no ;; 1.352 +;; BX = 0 ;; 1.353 +;; Output: ES:0 -> buffer ;; 1.354 +;; EDX:EAX = sector no ;; 1.355 +;; CX = sectors to load ;; 1.356 +;; ESI = next cluster ;; 1.357 +;; BX = 0 ;; 1.358 +;; CH = 0 ;; 1.359 +;; BP = para/sector ;; 1.360 +;; C=0 for last sector ;; 1.361 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.362 + 1.363 +ReadCluster: 1.364 +============== 1.365 + mov bp, word [bx(bpbBytesPerSector)] 1.366 + shr bp, 4 ; paragraphs per sector 1.367 + inc cx 1.368 + add ax, 1 ; adjust LBA for next sector 1.369 +? adc dx, bx 1.370 + loop ReadSectorLBANext 1.371 + 1.372 + imul ax, bp, 2 1.373 + cwde ; eax=# of FAT32 entries per sector 1.374 + lea edi, [esi-2] ; edi=cluster #-2 1.375 + xchg eax, esi 1.376 + cdq 1.377 + div esi ; eax=FAT sector #, edx=entry # in sector < 128 1.378 + 1.379 + imul si, dx, 4 ; si=entry # offset in sector 1.380 + 1.381 + call ReadSectorLBA ; read 1 FAT32 sector 1.382 + 1.383 + mov si2, 0FFFh 1.384 + and si2, [es:si+2] ; mask cluster value 1.385 + mov si, [es:si] ; si2:si=next cluster # 1.386 + 1.387 + movzx eax, byte [bx(bpbNumberOfFATs)] 1.388 + mul dword [bx(bsSectorsPerFAT32)] ; edx < 256 1.389 + 1.390 + xchg eax, edi ; get cluster #-2 ; save data offset 1.391 + 1.392 + movzx ecx, byte [bx(bpbSectorsPerCluster)] 1.393 + mul ecx 1.394 + 1.395 + add eax, edi ; sector # relative to FAT32 1.396 + 1.397 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.398 +;; Reads a sector using BIOS Int 13h ;; 1.399 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.400 +;; Input: ES:0 -> buffer address ;; 1.401 +;; EAX = LBA (FAT based) ;; 1.402 +;; BX = 0 ;; 1.403 +;; CX = sector count ;; 1.404 +;; Output: ES:0 -> buffer address ;; 1.405 +;; EDX:EAX = absolute LBA ;; 1.406 +;; BX = 0 ;; 1.407 +;; CX = next sector count ;; 1.408 +;; BP = paragraphs/sector ;; 1.409 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.410 + 1.411 +ReadSectorLBA: 1.412 + 1.413 + mov dx, word [bx(bpbReservedSectors)] 1.414 + add eax, edx 1.415 + mov dx, bx 1.416 + adc dx, bx 1.417 + add eax, [bx(bpbHiddenSectors)] 1.418 + 1.419 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.420 +;; Input: ES:0 -> buffer address ;; 1.421 +;; EDX:EAX = absolute LBA ;; 1.422 +;; BX = 0 ;; 1.423 +;; CX = sector count ;; 1.424 +;; Output: ES:0 -> buffer address ;; 1.425 +;; EDX:EAX = absolute LBA ;; 1.426 +;; BX = 0 ;; 1.427 +;; CX = next sector count ;; 1.428 +;; BP = paragraphs/sector ;; 1.429 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.430 + 1.431 +ReadSectorLBANext: 1.432 + 1.433 + adc dx, bx ; FAT32 partition can start up to 2TB 1.434 + 1.435 + pusha 1.436 + 1.437 + push edx ; 33-bit LBA only: up to 4TB disks 1.438 + push eax ; 32-bit LBA: up to 2TB FAT32 partition start 1.439 + push es 1.440 + push bx 1.441 + push byte 1 ; sector count word = 1 1.442 + push byte 16 ; packet size byte = 16, reserved byte = 0 1.443 + 1.444 + push eax 1.445 + pop cx ; low LBA 1.446 + pop ax ; high LBA, dx=0 (<2TB) 1.447 + div word [bx(bpbSectorsPerTrack)] ; up to 8GB disks 1.448 + 1.449 + xchg ax, cx ; restore low LBA, save high LBA / SPT 1.450 + div word [bx(bpbSectorsPerTrack)] 1.451 + ; ax = LBA / SPT 1.452 + ; dx = LBA % SPT = sector - 1 1.453 + inc dx 1.454 + 1.455 + xchg cx, dx ; restore high LBA / SPT, save sector no. 1.456 + div word [bx(bpbHeadsPerCylinder)] 1.457 + ; ax = (LBA / SPT) / HPC = cylinder 1.458 + ; dx = (LBA / SPT) % HPC = head 1.459 + shl ah, 6 1.460 + mov ch, al 1.461 + ; ch = LSB 0...7 of cylinder no. 1.462 + or cl, ah 1.463 + ; cl = MSB 8...9 of cylinder no. + sector no. 1.464 + mov dh, dl 1.465 + ; dh = head no. 1.466 + 1.467 +ReadSectorLBARetry: 1.468 + mov dl, [bx] 1.469 + ; dl = drive no. 1.470 + mov si, sp 1.471 + mov ah, 42h ; ah = 42h = extended read function no. 1.472 + int 13h ; extended read sectors (DL, DS:SI) 1.473 + jnc ReadSectorNextSegment 1.474 + 1.475 +ReadSectorCHSRetry: 1.476 + mov ax, 201h ; al = sector count = 1 1.477 + ; ah = 2 = read function no. 1.478 + int 13h ; read sectors (AL, CX, DX, ES:BX) 1.479 + jnc ReadSectorNextSegment 1.480 + 1.481 + cbw ; ah = 0 = reset function 1.482 + int 13h ; reset drive (DL) 1.483 + 1.484 + dec bp 1.485 + jnz ReadSectorLBARetry 1.486 + 1.487 + call Error 1.488 + db "Read error." 1.489 + 1.490 +ReadSectorNextSegment: 1.491 + 1.492 + popa ; sp += 16 1.493 + popa ; restore real registers 1.494 +============== 1.495 + stc 1.496 + loop ReadSectorDone 1.497 + 1.498 + cmp si2, 0FFFh 1.499 + jne ReadSectorDone 1.500 + cmp si, 0FFF8h ; carry=0 if last cluster, and carry=1 otherwise 1.501 + 1.502 +ReadSectorDone: 1.503 + ret 1.504 + 1.505 +;;;;;;;;;;;;;;;;;;;;;;;;;; 1.506 +;; Error Messaging Code ;; 1.507 +;;;;;;;;;;;;;;;;;;;;;;;;;; 1.508 + 1.509 +Error: 1.510 + pop si 1.511 + mov dl, [bx] ; restore BIOS boot drive number 1.512 + mov ah, 0Eh 1.513 + mov bl, 7 1.514 + 1.515 +PutStr: 1.516 + lodsb 1.517 + int 10h 1.518 + cmp al, "." 1.519 + jne PutStr 1.520 + 1.521 + cbw 1.522 + int 16h ; wait for a key... 1.523 + int 19h ; bootstrap 1.524 + 1.525 +Stop: 1.526 + hlt 1.527 + jmp short Stop 1.528 + 1.529 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.530 +;; Fill free space with zeroes ;; 1.531 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.532 + 1.533 + times (512-13-($-$$)) db 0 1.534 + 1.535 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.536 +;; Name of the file to load and run ;; 1.537 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.538 + 1.539 +ProgramName db "STARTUP BIN" ; name and extension each must be 1.540 + ; padded with spaces (11 bytes total) 1.541 + 1.542 +;;;;;;;;;;;;;;;;;;;;;;;;;; 1.543 +;; End of the sector ID ;; 1.544 +;;;;;;;;;;;;;;;;;;;;;;;;;; 1.545 + 1.546 + dw 0AA55h ; BIOS checks for this ID