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.         org     0x7E00
  28. ; the KordOS FAT32 bootsector loads first cluster of this file to 0:7E00 and transfers control to here
  29. ; ss:bp = 0:7C00
  30. ; ds = 0
  31. virtual at bp
  32.                 rb      3       ; BS_jmpBoot
  33.                 rb      8       ; BS_OEMName, ignored
  34.                 dw      ?       ; 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. filesize:
  51.                 dw      ?       ; BPB_FSInfo
  52.                 dw      ?       ; BPB_BkBootSec
  53.                 rb      12      ; BPB_Reserved
  54. BS_DrvNum       db      ?
  55.                 db      ?       ; BS_Reserved1
  56.                 db      ?       ; BS_BootSig
  57.                 dd      ?       ; BS_VolID
  58. ;               rb      11      ; BS_VolLab
  59. ;               rb      5       ; BS_FilSysType, first 5 bytes
  60. read_sectors32  dw      ?
  61. read_sectors2   dw      ?
  62. err_             dw      ?
  63. noloader        dw      ?
  64. cachelimit      dw      ?
  65. fatcachehead    rw      2
  66. fatcacheend     dw      ?
  67.                 rb      3       ; BS_FilSysType, last 3 bytes
  68. curseg          dw      ?
  69. num_sectors     dd      ?
  70. cur_cluster     dd      ?
  71. next_cluster    dd      ?
  72. flags           dw      ?
  73. cur_delta       dd      ?
  74. end virtual
  75.  
  76. ; procedures from boot sector
  77. ; LBA version
  78. lba_read_sectors2 = 7CD6h
  79. lba_err = 7CAAh
  80. lba_noloader = 7CA7h    ; = lba_err - 3
  81. ; CHS version
  82. chs_read_sectors2 = 7CD2h
  83. chs_err = 7CA6h
  84. chs_noloader = 7CA3h    ; = chs_err - 3
  85.  
  86.         push    eax cx          ; save our position on disk
  87. ; determine version of bootsector (LBA vs CHS)
  88.         mov     [read_sectors2], chs_read_sectors2
  89.         mov     bx, chs_err
  90.         mov     [err_], bx
  91. ;       mov     [noloader], chs_noloader
  92.         cmp     byte [bx], 0xE8         ; [chs_err] = 0xE8 for CHS version, 0x14 for LBA version
  93.         jz      @f
  94.         add     [read_sectors2], lba_read_sectors2 - chs_read_sectors2
  95.         add     [err_], lba_err - chs_err
  96. ;       mov     [noloader], lba_noloader
  97. @@:
  98.         xor     bx, bx
  99. ; determine size of cache for folders
  100.         int     12h             ; ax = size of available base memory in Kb
  101.         sub     ax, 92000h / 1024
  102.         jae     @f
  103. nomem:
  104.         mov     si, nomem_str
  105.         jmp     [err_]
  106. @@:
  107.         shr     ax, 3
  108.         mov     [cachelimit], ax        ; size of cache - 1
  109.         mov     es, bx
  110. ; no folders in cache yet
  111.         mov     di, foldcache_clus
  112.         mov     cx, 8*4/2 + 1
  113.         xor     ax, ax
  114.         rep     stosw
  115. ; bootsector code caches one FAT sector, [bp-14], in 6000:0000
  116. ; initialize our (more advanced) FAT caching from this
  117.         mov     di, 8400h
  118.         mov     cx, di
  119.         lea     si, [fatcachehead]
  120.         mov     [si], si                ; no sectors in cache:
  121.         mov     [si+2], si              ; 'prev' & 'next' links point to self
  122.         mov     [fatcacheend], di       ; first free item = 8400h
  123.         stosw                   ; 'next cached sector' link
  124.         stosw                   ; 'prev cached sector' link
  125.         mov     eax, [bp-14]
  126.         stosd                           ; first sector number in cache
  127.         test    eax, eax
  128.         js      @f
  129.         mov     [si], cx                ; 'first cached sector' link = 8400h
  130.         mov     [si+2], cx              ; 'next cached sector' link = 8400h
  131.         mov     [fatcacheend], di       ; first free item = 8406h
  132. @@:
  133. ; if cluster = sector, we need to read second part of our file
  134. ; (bootsector loads only first cluster of kordldr.f32)
  135.         pop     cx eax          ; restore our position on disk
  136.         cmp     cx, 1
  137.         ja      kordldr_full
  138.         sub     eax, [bp-10]
  139.         inc     eax
  140.         inc     eax             ; eax = first cluster of kordldr.f32
  141.         call    get_next_cluster
  142.         jc      @f
  143. ;       jmp     [noloader]
  144.         mov     ax, [err_]
  145.         sub     ax, 3
  146.         jmp     ax
  147. @@:
  148.         dec     eax
  149.         dec     eax
  150.         push    0x800
  151.         pop     es
  152.         call    [read_sectors2]
  153. kordldr_full:
  154. ; bootsector code has read some data of root directory to 8000:0000
  155. ; initialize our folder caching from this
  156.         mov     eax, [BPB_RootClus]
  157.         mov     [foldcache_clus], eax
  158.         mov     cx, [curseg]
  159.         mov     ax, 8000h
  160.         sub     cx, ax          ; cx = size of data read in paragraphs (0x10 bytes)
  161.         shr     cx, 1           ; cx = size of folder data read in entries (0x20 bytes)
  162.         mov     [foldcache_size], cx
  163.         shl     cx, 4
  164.         push    ds
  165.         mov     ds, ax
  166.         push    0x9000
  167.         pop     es
  168.         xor     si, si
  169.         xor     di, di
  170.         rep     movsw
  171.         pop     ds
  172. ; ...continue loading...
  173.         mov     di, secondary_loader_info
  174.         call    load_file
  175.         test    bx, bx
  176.         mov     bx, [err_]
  177.         jz      @f
  178.         mov     si, aKernelNotFound
  179.         jmp     bx
  180. @@:
  181. ; for subsequent calls to callback function, hook error handler
  182. ; push hooked_err / ret
  183.         mov     dword [bx], 0x68 + (hooked_err shl 8) + (0xC3 shl 24)
  184. ; set registers for secondary loader
  185.         mov     ah, [bp-2]              ; drive id
  186.         mov     al, 'f'
  187.         btr     ax, 15
  188.         jnc     @f
  189.         mov     al, 'h'
  190. @@:
  191.         mov     bx, '32'
  192.         mov     si, callback
  193.         jmp     far [si+secondary_loader_info-callback]
  194.  
  195. nomem_str       db      'No memory',0
  196.  
  197. cluster2sector:
  198.         sub     eax, 2
  199. clustersz2sectorsz:
  200.         movzx   ecx, [BPB_SecsPerClus]
  201.         mul     ecx
  202.         ret
  203.  
  204. get_next_cluster:
  205. ; in: eax = cluster
  206. ; out: if there is next cluster: CF=1, eax = next cluster
  207. ; out: if there is no next cluster: CF=0
  208.         push    di bx
  209.         push    ds es
  210.         push    ss
  211.         pop     ds
  212.         push    ss
  213.         pop     es
  214.         push    ax
  215.         shr     eax, 7
  216. ; eax = FAT sector number; look in cache
  217.         mov     di, 8400h
  218. .cache_lookup:
  219.         cmp     di, [fatcacheend]
  220.         jae     .not_in_cache
  221.         scasd
  222.         scasd
  223.         jnz     .cache_lookup
  224. .in_cache:
  225.         sub     di, 8
  226. ; delete this sector from the list
  227.         push    si
  228.         mov     si, [di]
  229.         mov     bx, [di+2]
  230.         mov     [si+2], bx
  231.         mov     [bx], si
  232.         pop     si
  233.         jmp     @f
  234. .not_in_cache:
  235. ; cache miss
  236. ; cache is full?
  237.         mov     di, [fatcacheend]
  238.         cmp     di, 8C00h
  239.         jnz     .cache_not_full
  240. ; yes, delete the oldest entry
  241.         mov     di, [fatcachehead]
  242.         mov     bx, [di]
  243.         mov     [fatcachehead], bx
  244.         push    word [di+2]
  245.         pop     word [bx+2]
  246.         jmp     .cache_append
  247. .cache_not_full:
  248. ; no, allocate new sector
  249.         add     [fatcacheend], 8
  250. .cache_append:
  251. ; read FAT
  252.         mov     [di+4], eax
  253.         pushad
  254.         lea     cx, [di + 0x10000 - 0x8400 + (0x6000 shr (9-4-3))]      ; +0x10000 - for FASM
  255.         shl     cx, 9-4-3
  256.         mov     es, cx
  257.         xor     bx, bx
  258.         mov     cx, 1
  259.         add     eax, [bp-6]     ; FAT start
  260.         sub     eax, [bp-10]
  261.         call    [read_sectors2]
  262.         popad
  263. @@:
  264. ; add new sector to the end of list
  265.         mov     bx, di
  266.         xchg    bx, [fatcachehead+2]
  267.         push    word [bx]
  268.         pop     word [di]
  269.         mov     [bx], di
  270.         mov     [di+2], bx
  271. ; get requested item
  272.         lea     ax, [di + 0x10000 - 0x8400 + (0x6000 shr (9-4-3))]
  273.         pop     di
  274.         and     di, 0x7F
  275.         shl     di, 2
  276.         shl     ax, 9-4-3
  277.         mov     ds, ax
  278.         and     byte [di+3], 0x0F
  279.         mov     eax, [di]
  280.         pop     es ds
  281.         pop     bx di
  282.         ;and    eax, 0x0FFFFFFF
  283.         cmp     eax, 0x0FFFFFF7
  284.         ret
  285.  
  286. if $ > 0x8000
  287. error 'get_next_cluster must fit in first sector of kordldr.f32!'
  288. end if
  289.  
  290. load_file:
  291. ; in: ss:bp = 0:7C00
  292. ; in: ds:di -> information structure
  293. ;       dw:dw   address
  294. ;       dw      limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
  295. ;       ASCIIZ  name
  296. ; out: bx = status: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found
  297. ; out: dx:ax = file size (0xFFFFFFFF if file not found)
  298.         mov     eax, [BPB_RootClus]     ; start from root directory
  299.         or      dword [filesize], -1    ; initialize file size with invalid value
  300.         lea     si, [di+6]
  301. parse_dir_loop:
  302. ; convert name to FAT name
  303.         push    di
  304.         push    ax
  305.         push    ss
  306.         pop     es
  307. ; convert ASCIIZ filename to FAT name
  308. filename equ bp
  309.         mov     di, filename
  310.         push    di
  311.         mov     cx, 8+3
  312.         mov     al, ' '
  313.         rep     stosb
  314.         pop     di
  315.         mov     cl, 8   ; 8 symbols per name
  316.         mov     bl, 1
  317. nameloop:
  318.         lodsb
  319.         test    al, al
  320.         jz      namedone
  321.         cmp     al, '/'
  322.         jz      namedone
  323.         cmp     al, '.'
  324.         jz      namedot
  325.         dec     cx
  326.         js      badname
  327.         cmp     al, 'a'
  328.         jb      @f
  329.         cmp     al, 'z'
  330.         ja      @f
  331.         sub     al, 'a'-'A'
  332. @@:
  333.         stosb
  334.         jmp     nameloop
  335. namedot:
  336.         inc     bx
  337.         jp      badname
  338.         add     di, cx
  339.         mov     cl, 3
  340.         jmp     nameloop
  341. badname:        ; do not make direct js/jp to notfound_pop:
  342.                 ; this generates long forms of conditional jumps and results in longer code
  343.         jmp     notfound_pop
  344. namedone:
  345. ; scan directory
  346.         pop     ax      ; eax = cluster of directory
  347.                         ; high word of eax is preserved by operations above
  348.         push    ds
  349.         push    si
  350. ; read a folder sector-by-sector and scan
  351. ; first, try to use the cache
  352.         push    ss
  353.         pop     ds
  354.         mov     di, foldcache_mark
  355.         xor     bx, bx
  356.         mov     cx, [cachelimit]
  357. @@:
  358.         lea     si, [di+bx]
  359.         mov     edx, dword [foldcache_clus+si-foldcache_mark+bx]
  360.         cmp     edx, eax
  361.         jz      cacheok
  362.         test    edx, edx
  363.         jz      cacheadd        ; the cache has place for new entry
  364.         inc     bx
  365.         inc     bx
  366.         dec     cx
  367.         jns     @b
  368. ; the folder is not present in the cache, so add it
  369. ; the cache is full; find the oldest entry and replace it with the new one
  370.         mov     bx, -2
  371.         mov     dx, [cachelimit]
  372. @@:
  373.         inc     bx
  374.         inc     bx
  375.         cmp     word [di+bx], dx        ; marks have values 0 through [cachelimit]
  376.         jnz     @b
  377.         lea     si, [di+bx]
  378. cacheadd:
  379.         or      word [di+bx], 0xFFFF    ; very big value, it will be changed soon
  380.         and     [foldcache_size+di-foldcache_mark+bx], 0        ; no folder items yet
  381.         mov     dword [foldcache_clus+si-foldcache_mark+bx], eax
  382. cacheok:
  383. ; update cache marks
  384.         mov     dx, [di+bx]
  385.         mov     cx, [foldcache_size+di-foldcache_mark+bx]
  386.         mov     di, [cachelimit]
  387.         add     di, di
  388. cacheupdate:
  389.         cmp     [foldcache_mark+di], dx
  390.         adc     [foldcache_mark+di], 0
  391.         dec     di
  392.         dec     di
  393.         jns     cacheupdate
  394.         and     [foldcache_mark+bx], 0
  395. ; done, bx contains (position in cache)*2
  396.         ;mov    dx, bx
  397.         ;shl    dx, 8           ; dx = (position in cache)*0x2000/0x10
  398.         ;add    dx, 0x9000
  399.         lea     dx, [bx + 0x90]
  400.         xchg    dl, dh
  401.         mov     ds, dx
  402.         mov     si, filename    ; ss:si -> filename in FAT style
  403.         call    scan_for_filename
  404.         jz      lookup_done
  405. ; cache miss, read folder data from disk
  406.         mov     bx, cx
  407.         shr     bx, 4
  408.         shl     cx, 5
  409.         mov     di, cx          ; es:di -> free space in cache entry
  410. ; external loop: scan clusters
  411. folder_next_cluster:
  412. ; internal loop: scan sectors in cluster
  413.         push    eax
  414.         call    cluster2sector
  415. folder_next_sector:
  416. ; skip first bx sectors
  417.         dec     bx
  418.         jns     folder_skip_sector
  419.         push    cx
  420.         push    es di
  421.         push    0x8000
  422.         pop     es
  423.         xor     bx, bx
  424.         mov     cx, 1
  425.         push    es
  426.         push    eax
  427.         call    [read_sectors2]
  428.         pop     eax
  429. ; copy data to the cache...
  430.         pop     ds
  431.         pop     di es
  432.         cmp     di, 0x2000      ; ...if there is free space, of course
  433.         jae     @f
  434.         pusha
  435.         mov     cx, 0x100
  436.         xor     si, si
  437.         rep     movsw
  438.         mov     di, es
  439.         shr     di, 8
  440.         add     [ss:foldcache_size+di-0x90], 0x10       ; 0x10 new entries in the cache
  441.         popa
  442. @@:
  443.         push    es
  444.         mov     cl, 0x10        ; ch=0 at this point
  445.         call    scan_for_filename
  446.         pop     es
  447.         pop     cx
  448.         jz      lookup_done_pop
  449. folder_skip_sector:
  450.         inc     eax
  451.         loop    folder_next_sector
  452.         pop     eax     ; eax = current cluster
  453.         call    get_next_cluster
  454.         jc      folder_next_cluster
  455.         stc
  456.         push    eax
  457. lookup_done_pop:
  458.         pop     eax
  459. lookup_done:
  460.         pop     si
  461. ; CF=1 <=> failed
  462.         jnc     found
  463.         pop     ds
  464. notfound:
  465.         pop     di
  466. notfound2:
  467.         mov     bx, 2   ; file not found
  468.         mov     ax, 0xFFFF
  469.         mov     dx, ax  ; invalid file size
  470.         ret
  471. notfound_pop:
  472.         pop     ax
  473.         jmp     notfound
  474. found:
  475.         mov     eax, [di+20-2]
  476.         mov     edx, [di+28]
  477.         mov     ax, [di+26]     ; get cluster
  478.         test    byte [di+11], 10h       ; directory?
  479.         pop     ds
  480.         pop     di
  481.         jz      regular_file
  482.         cmp     byte [si-1], 0
  483.         jz      notfound2       ; don't read directories as regular files
  484. ; ok, we have found a directory and the caller requested a file into it
  485.         jmp     parse_dir_loop  ; restart with new cluster in ax
  486. regular_file:
  487.         cmp     byte [si-1], 0
  488.         jnz     notfound2       ; file does not contain another files
  489. ; ok, we have found a regular file and the caller requested it
  490. ; save file size
  491.         mov     [filesize], edx
  492.         mov     si, [di+4]      ; [ds:di+4] = limit in 4K blocks
  493.         shl     si, 3
  494.         push    si
  495.         les     bx, [di]        ; es:bx -> buffer
  496. clusloop:
  497. ; eax = first cluster, top of stack contains limit in sectors
  498.         mov     esi, eax        ; remember current cluster
  499.         xor     ecx, ecx        ; ecx will contain number of consecutive clusters
  500.         mov     [cur_delta], ecx
  501.         mov     edi, eax
  502. clusfind:
  503.         inc     edi
  504.         inc     ecx
  505.         call    get_next_cluster
  506.         jnc     clusread
  507.         cmp     eax, edi
  508.         jz      clusfind
  509.         stc
  510. clusread:
  511.         pop     di      ; limit in sectors
  512.         movzx   edi, di
  513.         push    eax     ; save next cluster
  514.         pushf           ; save flags
  515. ; read cx clusters, starting from si
  516. ; calculate number of sectors
  517.         xchg    eax, ecx
  518.         call    clustersz2sectorsz
  519.         mov     [num_sectors], eax
  520.         jmp     @f
  521. continue_load_file:
  522.         les     bx, [di]        ; es:bx -> buffer
  523.         movzx   edi, word [di+4]        ; di = limit in 4K blocks
  524.         shl     di, 3   ; now di = limit in sectors
  525.         mov     eax, [num_sectors]
  526.         mov     esi, [cur_cluster]
  527.         push    [next_cluster]
  528.         push    [flags]
  529.         test    eax, eax
  530.         jz      nextclus
  531. @@:
  532. ; eax = number of sectors; compare with limit
  533.         cmp     eax, edi
  534.         seta    dl
  535.         push    dx      ; limit was exceeded?
  536.         jbe     @f
  537.         mov     eax, edi
  538. @@:
  539.         sub     di, ax  ; calculate new limit
  540.         sub     [num_sectors], eax
  541.         mov     [cur_cluster], esi
  542. ; calculate starting sector
  543.         push    ax
  544.         xchg    eax, esi
  545.         call    cluster2sector
  546.         pop     cx
  547.         add     eax, [cur_delta]
  548.         add     [cur_delta], ecx
  549. ; read
  550.         call    [read_sectors2]
  551.         pop     dx
  552. ; next cluster?
  553. nextclus:
  554.         popf
  555.         pop     eax
  556.         mov     [next_cluster], eax
  557.         pushf
  558.         pop     [flags]
  559.         jnc     @f      ; no next cluster => return
  560.         mov     dl, 1
  561.         test    di, di
  562.         jz      @f      ; if there is next cluster but current limit is 0 => return: limit exceeded
  563.         push    di
  564.         jmp     clusloop        ; all is ok, continue
  565. hooked_err:
  566.         mov     sp, 7C00h-14-2  ; restore stack
  567.         mov     dl, 3           ; return: read error
  568. @@:
  569.         mov     bl, dl
  570.         mov     bh, 0
  571.         mov     ax, [filesize]
  572.         mov     dx, [filesize+2]
  573.         ret
  574.  
  575. scan_for_filename:
  576. ; in: ss:si -> 11-bytes FAT name
  577. ; in: ds:0 -> part of directory data
  578. ; in: cx = number of entries
  579. ; in: bh = 0
  580. ; out: if found: CF=0, ZF=1, es:di -> directory entry
  581. ; out: if not found, but continue required: CF=1 and ZF=0
  582. ; out: if not found and zero item reached: CF=1 and ZF=1
  583.         push    ds
  584.         pop     es
  585.         xor     di, di
  586.         push    cx
  587.         jcxz    snoent
  588. sloop:
  589.         cmp     byte [di], bh
  590.         jz      snotfound
  591.         test    byte [di+11], 8         ; volume label?
  592.         jnz     scont                   ; ignore volume labels
  593.         pusha
  594.         mov     cx, 11
  595.         repz    cmps byte [ss:si], byte [es:di]
  596.         popa
  597.         jz      sdone
  598. scont:
  599.         add     di, 0x20
  600.         loop    sloop
  601. snoent:
  602.         inc     cx      ; clear ZF flag
  603. snotfound:
  604.         stc
  605. sdone:
  606.         pop     cx
  607. lrdret:
  608.         ret
  609.  
  610. ; Callback function for secondary loader
  611. callback:
  612. ; in: ax = function number; only functions 1 and 2 are defined for now
  613. ; save caller's stack
  614.         mov     dx, ss
  615.         mov     cx, sp
  616. ; set our stack (required because we need ss=0)
  617.         xor     si, si
  618.         mov     ss, si
  619.         mov     sp, 7C00h-10
  620.         mov     bp, 7C00h
  621.         push    dx
  622.         push    cx
  623. ; call our function
  624.         stc     ; unsupported function
  625.         dec     ax
  626.         jz      callback_readfile
  627.         dec     ax
  628.         jnz     callback_ret
  629. ; function 2: continue loading file
  630. ; can be called only after function 1 returned value bx=1 (only part of file was loaded)
  631. ; in: ds:di -> information structure
  632. ;       dw:dw   address
  633. ;       dw      limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
  634. ; out: bx=0 - ok, bx=1 - still only part of file was loaded, bx=3 - read error
  635. ; out: dx:ax = file size
  636.         call    continue_load_file
  637.         jmp     callback_ret_succ
  638. callback_readfile:
  639. ; function 1: read file
  640. ; in: ds:di -> information structure
  641. ;       dw:dw   address
  642. ;       dw      limit in 4Kb blocks (0x1000 bytes) (must be non-zero and not greater than 0x100)
  643. ;       ASCIIZ  name
  644. ; out: bx=0 - ok, bx=1 - file is too big, only part of file was loaded, bx=2 - file not found, bx=3 - read error
  645. ; out: dx:ax = file size (0xFFFFFFFF if file was not found)
  646.         call    load_file
  647. callback_ret_succ:
  648.         clc     ; function is supported
  649. callback_ret:
  650. ; restore caller's stack
  651.         pop     cx
  652.         pop     ss
  653.         mov     sp, cx
  654. ; return to caller
  655.         retf
  656.  
  657. secondary_loader_info:
  658.         dw      0, 0x1000
  659.         dw      0x30000 / 0x1000
  660.         db      'kernel.mnt',0
  661. aKernelNotFound db      'Fatal error: cannot load the kernel',0
  662.  
  663. ;if $ > 0x8200
  664. ;error 'total size of kordldr.f32 must not exceed 1024 bytes!'
  665. ;end if
  666.  
  667. ;foldcache_clus dd      0,0,0,0,0,0,0,0 ; start with no folders in cache
  668. ;foldcache_mark dw      0
  669. ;               rw      7
  670. ;foldcache_size rw      8
  671. foldcache_clus  rd      8
  672. foldcache_mark  rw      8
  673. foldcache_size  rw      8
  674.