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 ;;