Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. ; Copyright (c) 2008-2009, diamond
  2. ; All rights reserved.
  3. ;
  4. ; Redistribution and use in source and binary forms, with or without
  5. ; modification, are permitted provided that the following conditions are met:
  6. ;       * Redistributions of source code must retain the above copyright
  7. ;       notice, this list of conditions and the following disclaimer.
  8. ;       * Redistributions in binary form must reproduce the above copyright
  9. ;       notice, this list of conditions and the following disclaimer in the
  10. ;       documentation and/or other materials provided with the distribution.
  11. ;       * Neither the name of the <organization> nor the
  12. ;       names of its contributors may be used to endorse or promote products
  13. ;       derived from this software without specific prior written permission.
  14. ;
  15. ; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
  16. ; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. ; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. ; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
  19. ; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. ; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  22. ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. ;*****************************************************************************
  26.  
  27. use_lba = 0
  28.         org     0x7C00
  29.         jmp     start
  30.         nop
  31. ; FAT parameters, BPB
  32. ; they must be changed at install, replaced with real values
  33.                 rb      8       ; BS_OEMName, ignored
  34.                 dw      200h    ; BPB_BytsPerSec
  35. BPB_SecsPerClus db      ?
  36. BPB_RsvdSecCnt  dw      ?
  37. BPB_NumFATs     db      ?
  38. BPB_RootEntCnt  dw      ?
  39.                 dw      ?       ; BPB_TotSec16
  40.                 db      ?       ; BPB_Media
  41.                 dw      ?       ; BPB_FATSz16 = 0 for FAT32
  42. BPB_SecPerTrk   dw      ?
  43. BPB_NumHeads    dw      ?
  44. BPB_HiddSec     dd      ?
  45.                 dd      ?       ; BPB_TotSec32
  46. BPB_FATSz32     dd      ?
  47. BPB_ExtFlags    dw      ?
  48.                 dw      ?       ; BPB_FSVer
  49. BPB_RootClus    dd      ?
  50.                 dw      ?       ; BPB_FSInfo
  51. BPB_BkBootSec   dw      ?
  52.                 rb      12      ; BPB_Reserved
  53. BS_DrvNum       db      ?
  54.                 db      ?       ; BS_Reserved1
  55.                 db      ?       ; BS_BootSig
  56.                 dd      ?       ; BS_VolID
  57.                 rb      11      ; BS_VolLab
  58.                 rb      8       ;
  59.  
  60. curseg  dw      0x8000
  61.  
  62. start:
  63.         xor     ax, ax
  64.         mov     ss, ax
  65.         mov     sp, 0x7C00
  66.         mov     ds, ax
  67.         mov     bp, sp
  68.         cld
  69.         sti
  70.         push    dx      ; byte [bp-2] = boot drive
  71. if use_lba
  72.         mov     ah, 41h
  73.         mov     bx, 55AAh
  74.         int     13h
  75.         mov     si, aNoLBA
  76.         jc      err_
  77.         cmp     bx, 0AA55h
  78.         jnz     err_
  79.         test    cl, 1
  80.         jz      err_
  81. else
  82.         mov     ah, 8
  83.         int     13h
  84.         jc      @f
  85.         movzx   ax, dh
  86.         inc     ax
  87.         mov     [bp+BPB_NumHeads-0x7C00], ax
  88.         and     cx, 3Fh
  89.         mov     [bp+BPB_SecPerTrk-0x7C00], cx
  90. @@:
  91. end if
  92. ; get FAT parameters
  93.         xor     bx, bx
  94.         movzx   eax, [bp+BPB_NumFATs-0x7C00]
  95.         mul     [bp+BPB_FATSz32-0x7C00]
  96.         movzx   ecx, [bp+BPB_RsvdSecCnt-0x7C00]
  97.         push    ecx     ; FAT start = dword [bp-6]
  98.         add     eax, ecx
  99.         push    eax     ; data start = dword [bp-10]
  100.         ;push   dword -1        ; dword [bp-14] = current sector for FAT cache
  101.         db      66h
  102.         push    -1      ; dword [bp-14] = current sector for FAT cache
  103.         mov     eax, [bp+BPB_RootClus-0x7C00]
  104.         mov     si, main_loader
  105.         call    lookup_in_dir
  106.         jnc     kordldr_ok
  107. noloader:
  108.         mov     si, aLoaderNotFound
  109. err_:
  110.         call    out_string
  111.         mov     si, aPressAnyKey
  112.         call    out_string
  113.         xor     ax, ax
  114.         int     16h
  115.         int     18h
  116.         jmp     $
  117. kordldr_ok:
  118.         mov     eax, [es:di+20-2]       ; hiword(eax) = hiword(cluster)
  119.         mov     ax, [es:di+26]          ; loword(eax) = loword(cluster)
  120.         mov     es, bx          ; es = 0
  121.         mov     bx, 0x7E00
  122.         push    bx      ; save return address: bx = 7E00
  123. ; fall through - 'ret' in read_cluster will return to 7E00
  124.  
  125. read_cluster:
  126. ; ss:bp = 0:7C00
  127. ; es:bx = pointer to data
  128. ; eax = cluster
  129.         sub     eax, 2
  130.         movzx   ecx, [bp+BPB_SecsPerClus-0x7C00]
  131.         mul     ecx
  132.  
  133. read_sectors2:
  134. ; same as read_sectors32, but eax is relative to start of data
  135.         add     eax, [bp-10]
  136. read_sectors32:
  137. ; ss:bp = 0:7C00
  138. ; es:bx = pointer to data
  139. ; eax = first sector
  140. ; cx = number of sectors
  141. ; some high words of 32-bit registers are destroyed!
  142.         pusha
  143.         add     eax, [bp+BPB_HiddSec-0x7C00]
  144. if use_lba
  145.         push    ds
  146. do_read_sectors:
  147.         push    ax
  148.         push    cx
  149.         cmp     cx, 0x7F
  150.         jbe     @f
  151.         mov     cx, 0x7F
  152. @@:
  153. ; create disk address packet on the stack
  154. ; dq starting LBA
  155.         push    0
  156.         push    0
  157.         push    eax
  158. ; dd buffer
  159.         push    es
  160.         push    bx
  161. ; dw number of blocks to transfer (no more than 0x7F)
  162.         push    cx
  163. ; dw packet size in bytes
  164.         push    10h
  165. ; issue BIOS call
  166.         push    ss
  167.         pop     ds
  168.         mov     si, sp
  169.         mov     dl, [bp-2]
  170.         mov     ah, 42h
  171.         int     13h
  172.         mov     si, aReadError
  173.         jc      err_
  174. ; restore stack
  175.         add     sp, 10h
  176. ; increase current sector & buffer; decrease number of sectors
  177.         movzx   esi, cx
  178.         mov     ax, es
  179.         shl     cx, 5
  180.         add     ax, cx
  181.         mov     es, ax
  182.         pop     cx
  183.         pop     ax
  184.         add     eax, esi
  185.         sub     cx, si
  186.         jnz     do_read_sectors
  187.         pop     ds
  188.         popa
  189.         ret
  190. else
  191. do_read_sectors:
  192.         pusha
  193.         pop     edi     ; loword(edi) = di, hiword(edi) = si
  194.         push    bx
  195.  
  196. ; eax / (SectorsPerTrack) -> eax, remainder bx
  197.         movzx   esi, [bp+BPB_SecPerTrk-0x7C00]
  198.         xor     edx, edx
  199.         div     esi
  200.         mov     bx, dx          ; bx=sector-1
  201.  
  202. ; eax -> dx:ax
  203.         push    eax
  204.         pop     ax
  205.         pop     dx
  206. ; (dword in dx:ax) / (NumHeads) -> (word in ax), remainder dx
  207.         div     [bp+BPB_NumHeads-0x7C00]
  208.  
  209. ; number of sectors: read no more than to end of track
  210.         sub     si, bx
  211.         cmp     cx, si
  212.         jbe     @f
  213.         mov     cx, si
  214. @@:
  215.  
  216.         inc     bx
  217. ; now ax=track, dl=head, dh=0, cl=number of sectors, ch=0, bl=sector; convert to int13 format
  218.         movzx   edi, cx
  219.         mov     dh, dl
  220.         mov     dl, [bp-2]
  221.         shl     ah, 6
  222.         mov     ch, al
  223.         mov     al, cl
  224.         mov     cl, bl
  225.         or      cl, ah
  226.         pop     bx
  227.         mov     si, 3
  228.         mov     ah, 2
  229. @@:
  230.         push    ax
  231.         int     13h
  232.         jnc     @f
  233.         xor     ax, ax
  234.         int     13h     ; reset drive
  235.         pop     ax
  236.         dec     si
  237.         jnz     @b
  238.         mov     si, aReadError
  239.         jmp     err_
  240. @@:
  241.         pop     ax
  242.         mov     ax, es
  243.         mov     cx, di
  244.         shl     cx, 5
  245.         add     ax, cx
  246.         mov     es, ax
  247.         push    edi
  248.         popa
  249.         add     eax, edi
  250.         sub     cx, di
  251.         jnz     do_read_sectors
  252.         popa
  253.         ret
  254. end if
  255.  
  256. lookup_in_dir:
  257. ; in: ds:si -> 11-bytes FAT name
  258. ; in: eax = cluster
  259. ; in: bx = 0
  260. ; out: if found: CF=0, es:di -> directory entry
  261. ; out: if not found: CF=1
  262. ;       push    0x8000
  263. ;       pop     es
  264. ; read current cluster: first cluster goes to 8000:0000, others - to 8200:0000
  265.         mov     es, [bp-7C00h + curseg]
  266.         push    es
  267.         push    eax
  268.         call    read_cluster
  269.         mov     ax, es
  270.         cmp     ah, 82h
  271.         jb      @f
  272.         mov     ax, 8200h
  273. @@:
  274.         mov     [bp-7C00h + curseg], ax
  275.         pop     eax
  276.         pop     es
  277. ; scan for filename
  278.         shl     cx, 4
  279.         xor     di, di
  280. sloop:
  281.         cmp     byte [es:di], bl
  282.         jz      snotfound
  283.         test    byte [es:di+11], 8      ; volume label?
  284.         jnz     scont                   ; ignore volume labels
  285.         pusha
  286.         mov     cx, 11
  287.         repz    cmpsb
  288.         popa
  289.         jz      sdone
  290. scont:
  291.         add     di, 0x20
  292.         loop    sloop
  293. ; next cluster
  294.         push    0x6000
  295.         pop     es
  296.         push    es ax
  297.         shr     eax, 7
  298.         cmp     eax, [bp-14]
  299.         mov     [bp-14], eax
  300.         jz      @f
  301.         add     eax, [bp-6]
  302.         mov     cx, 1
  303.         call    read_sectors32
  304. @@:
  305.         pop     di es
  306.         and     di, 0x7F
  307.         shl     di, 2
  308.         and     byte [es:di+3], 0x0F
  309.         mov     eax, [es:di]
  310.         ;and    eax, 0x0FFFFFFF
  311.         cmp     eax, 0x0FFFFFF7
  312.         jb      lookup_in_dir
  313. snotfound:
  314.         stc
  315. sdone:
  316.         ret
  317.  
  318. out_string:
  319. ; in: ds:si -> ASCIIZ string
  320.         lodsb
  321.         test    al, al
  322.         jz      sdone
  323.         mov     ah, 0Eh
  324.         mov     bx, 7
  325.         int     10h
  326.         jmp     out_string
  327.  
  328. aReadError      db      'Read error',0
  329. if use_lba
  330. aNoLBA          db      'The drive does not support LBA!',0
  331. end if
  332. aLoaderNotFound db      'Loader not found',0
  333. aPressAnyKey    db      13,10,'Press any key...',13,10,0
  334. main_loader     db      'KORDLDR F32'
  335.  
  336.         db      56h
  337. ; just to make file 512 bytes long :)
  338.         db      'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd'
  339.  
  340. ; bootsector signature
  341.         dw      0xAA55
  342.  
  343. ; display offsets of all procedures used by kordldr.f12.asm
  344. macro show [procedure]
  345. {
  346.         bits = 16
  347.         display `procedure,' = '
  348.         repeat bits/4
  349.                 d = '0' + procedure shr (bits - %*4) and 0Fh
  350.                 if d > '9'
  351.                         d = d + 'A'-'9'-1
  352.                 end if
  353.                 display d
  354.         end repeat
  355.         display 13,10
  356. }
  357.  
  358. show read_sectors32, read_sectors2, err_, noloader
  359.