wok diff BootProg/stuff/boot16.asm @ rev 25450
BootProg: avoid divide errors
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Wed Sep 14 18:33:54 2022 +0000 (2022-09-14) |
parents | b56b38cfd475 |
children | e3609bca2577 |
line diff
1.1 --- a/BootProg/stuff/boot16.asm Sat Jun 18 10:52:55 2022 +0000 1.2 +++ b/BootProg/stuff/boot16.asm Wed Sep 14 18:33:54 2022 +0000 1.3 @@ -83,6 +83,12 @@ 1.4 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.5 1.6 %define bx(label) bx+label-boot 1.7 +%define si(label) si+label-boot 1.8 +NullEntryCheck equ 1 ; +3 bytes 1.9 +ReadRetry equ 1 ; +9 bytes 1.10 +LBAsupport equ 1 ; +16 bytes 1.11 +Over2GB equ 1 ; +5 bytes 1.12 +GeometryCheck equ 1 ; +18 bytes 1.13 1.14 [BITS 16] 1.15 [CPU 8086] 1.16 @@ -98,6 +104,7 @@ 1.17 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.18 1.19 boot: 1.20 +DriveNumber: 1.21 jmp short start ; MS-DOS/Windows checks for this jump 1.22 nop 1.23 bsOemName DB "BootProg" ; 0x03 1.24 @@ -161,14 +168,14 @@ 1.25 mov si, 7C00h 1.26 xor di, di 1.27 mov ds, di 1.28 - mov [si], dx ; store BIOS boot drive number 1.29 + push es 1.30 + mov [si(DriveNumber)], dx ; store BIOS boot drive number 1.31 rep movsw ; move 512 bytes (+ 12) 1.32 1.33 ;;;;;;;;;;;;;;;;;;;;;; 1.34 ;; Jump to the copy ;; 1.35 ;;;;;;;;;;;;;;;;;;;;;; 1.36 1.37 - push es 1.38 mov cl, byte main 1.39 push cx 1.40 retf 1.41 @@ -189,13 +196,16 @@ 1.42 ;; for current BIOS ;; 1.43 ;;;;;;;;;;;;;;;;;;;;;;;;;; 1.44 1.45 +%if GeometryCheck != 0 1.46 mov ah, 8 1.47 int 13h ; may destroy SI,BP, and DS registers 1.48 +%endif 1.49 ; update AX,BL,CX,DX,DI, and ES registers 1.50 push cs 1.51 pop ds 1.52 xor bx, bx 1.53 1.54 +%if GeometryCheck != 0 1.55 and cx, byte 3Fh 1.56 cmp [bx(bpbSectorsPerTrack)], cx 1.57 jne BadParams ; verify updated and validity 1.58 @@ -203,6 +213,7 @@ 1.59 inc ax 1.60 mov [bpbHeadsPerCylinder], ax 1.61 BadParams: 1.62 +%endif 1.63 1.64 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.65 ;; Load FAT (FAT12: 6KB max, FAT16: 128KB max) ;; 1.66 @@ -255,9 +266,13 @@ 1.67 repe cmpsb 1.68 pop di 1.69 je FindNameFound 1.70 +%if NullEntryCheck != 0 1.71 scasb 1.72 je FindNameFailed ; end of root directory (NULL entry found) 1.73 add di, byte 31 1.74 +%else 1.75 + add di, byte 32 1.76 +%endif 1.77 dec word [bx(bpbRootEntries)] 1.78 jnz FindNameCycle ; next root entry 1.79 1.80 @@ -289,35 +304,49 @@ 1.81 ;; CH = 0 ;; 1.82 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.83 1.84 +FAT12 equ 1 1.85 +FAT16 equ 1 1.86 push di ; up to 2 * 635K / BytesPerCluster bytes 1.87 +%if FAT12 == 1 1.88 mov cl, 12 1.89 +%endif 1.90 ClusterLoop: 1.91 mov [di], si 1.92 1.93 + add si, si ; si = cluster * 2 1.94 +%if FAT16 == 1 1.95 mov ax, es ; ax = FAT segment = ImageLoadSeg 1.96 - add si, si ; si = cluster * 2 1.97 jnc First64k 1.98 mov ah, (1000h+ImageLoadSeg)>>8 ; adjust segment for 2nd part of FAT16 1.99 First64k: 1.100 mov dx, 0FFF8h 1.101 +%else 1.102 + mov dx, 0FF8h 1.103 +%endif 1.104 1.105 +%if FAT12 == 1 && FAT16 == 1 1.106 cmp [bx(bpbSectorsPerFAT)], cx ; 1..12 = FAT12, 16..256 = FAT16 1.107 ja ReadClusterFat16 1.108 - 1.109 mov dh, 0Fh 1.110 +%endif 1.111 +%if FAT12 == 1 1.112 add si, [di] 1.113 shr si, 1 ; si = cluster * 3 / 2 1.114 - 1.115 +%endif 1.116 +%if FAT16 == 1 1.117 ReadClusterFat16: 1.118 push ds 1.119 mov ds, ax 1.120 lodsw ; ax = next cluster 1.121 pop ds 1.122 +%else 1.123 + lodsw ; ax = next cluster 1.124 +%endif 1.125 +%if FAT12 == 1 1.126 jnc ReadClusterEven 1.127 - 1.128 rol ax, cl 1.129 - 1.130 ReadClusterEven: 1.131 +%endif 1.132 scasw ; di += 2 1.133 and ah, dh ; mask cluster value 1.134 cmp ax, dx 1.135 @@ -464,31 +493,41 @@ 1.136 push di 1.137 push cx 1.138 1.139 +%if LBAsupport != 0 1.140 push bx 1.141 push bx 1.142 +%endif 1.143 push dx ; 32-bit LBA: up to 2TB 1.144 push ax 1.145 push es 1.146 +%if ReadRetry != 0 || LBAsupport != 0 1.147 + mov di, 16 ; packet size byte = 16, reserved byte = 0 1.148 +%endif 1.149 +%if LBAsupport != 0 1.150 push bx 1.151 inc bx ; sector count word = 1 1.152 push bx 1.153 dec bx 1.154 - mov di, 16 ; packet size byte = 16, reserved byte = 0 1.155 push di 1.156 +%endif 1.157 1.158 +%if Over2GB != 0 1.159 xchg ax, cx ; save low LBA 1.160 xchg ax, dx ; get high LBA 1.161 cwd ; clear dx (LBA offset <2TB) 1.162 - div word [bx(bpbSectorsPerTrack)] ; up to 8GB disks 1.163 + idiv word [bx(bpbSectorsPerTrack)] ; up to 8GB disks 1.164 1.165 xchg ax, cx ; restore low LBA, save high LBA / SPT 1.166 - div word [bx(bpbSectorsPerTrack)] 1.167 +%else 1.168 + xor cx, cx ; up to 2GB disks otherwise divide error interrupt ! 1.169 +%endif 1.170 + idiv word [bx(bpbSectorsPerTrack)] 1.171 ; ax = LBA / SPT 1.172 ; dx = LBA % SPT = sector - 1 1.173 inc dx 1.174 1.175 xchg cx, dx ; restore high LBA / SPT, save sector no. 1.176 - div word [bx(bpbHeadsPerCylinder)] 1.177 + idiv word [bx(bpbHeadsPerCylinder)] 1.178 ; ax = (LBA / SPT) / HPC = cylinder 1.179 ; dx = (LBA / SPT) % HPC = head 1.180 mov ch, al 1.181 @@ -501,41 +540,54 @@ 1.182 ; dh = head no. 1.183 1.184 ReadSectorRetry: 1.185 - mov dl, [bx] 1.186 + mov dl, [bx(DriveNumber)] 1.187 ; dl = drive no. 1.188 + mov si, sp 1.189 +%if LBAsupport != 0 1.190 mov ah, 42h ; ah = 42h = extended read function no. 1.191 - mov si, sp 1.192 int 13h ; extended read sectors (DL, DS:SI) 1.193 jnc ReadSectorNextSegment 1.194 +%endif 1.195 1.196 mov ax, 201h ; al = sector count = 1 1.197 ; ah = 2 = read function no. 1.198 int 13h ; read sectors (AL, CX, DX, ES:BX) 1.199 1.200 jnc ReadSectorNextSegment 1.201 +%if ReadRetry != 0 1.202 cbw ; ah = 0 = reset function 1.203 int 13h ; reset drive (DL) 1.204 1.205 dec di 1.206 jnz ReadSectorRetry ; extra attempt 1.207 +%endif 1.208 1.209 call Error 1.210 db "Read error." 1.211 1.212 ReadSectorNextSegment: 1.213 1.214 +%if LBAsupport != 0 1.215 pop ax ; al = 16 1.216 mul byte [bx(bpbBytesPerSector)+1] ; = (bpbBytesPerSector/256)*16 1.217 pop cx ; sector count = 1 1.218 pop bx 1.219 add [si+6], ax ; adjust segment for next sector 1.220 +%else 1.221 + mov al, 16 1.222 + mul byte [bx(bpbBytesPerSector)+1] ; = (bpbBytesPerSector/256)*16 1.223 + add [si], ax ; adjust segment for next sector 1.224 +%endif 1.225 pop es ; es:0 updated 1.226 pop ax 1.227 pop dx 1.228 +%if LBAsupport != 0 1.229 pop di 1.230 pop di 1.231 - 1.232 add ax, cx ; adjust LBA for next sector 1.233 +%else 1.234 + add ax, 1 ; adjust LBA for next sector 1.235 +%endif 1.236 1.237 pop cx ; cluster sectors to read 1.238 pop di ; file sectors to read 1.239 @@ -543,7 +595,7 @@ 1.240 loopne ReadSectorNext ; until cluster sector count or file sector count is reached 1.241 pop si 1.242 mov ax, bx ; clear ax 1.243 - mov dx, [bx] ; pass the BIOS boot drive to Run or Error 1.244 + mov dx, [bx(DriveNumber)] ; pass the BIOS boot drive to Run or Error 1.245 1.246 ret 1.247 1.248 @@ -581,7 +633,7 @@ 1.249 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1.250 1.251 ProgramName db "STARTUP BIN" ; name and extension each must be 1.252 - ; padded with spaces (11 bytes total) 1.253 + times (510-($-$$)) db ' ' ; padded with spaces (11 bytes total) 1.254 1.255 ;;;;;;;;;;;;;;;;;;;;;;;;;; 1.256 ;; End of the sector ID ;;