Subversion Repositories Kolibri OS

Rev

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

  1. ; Copyright (c) 2009, <Lrz>
  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 nickname <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. ; в этой секции идет разбор параметров указатель на секцию храниться в point_default
  28. ;типы ошибок при обработке макроса
  29. ;Макрос RamdiskFS
  30. ;/определение флагов в записи корневой директории
  31. ATTR_READ_ONLY  equ     0x01
  32. ATTR_HIDDEN     equ     0x02
  33. ATTR_SYSTEM     equ     0x04
  34. ATTR_VOLUME_ID  equ     0x08
  35. ATTR_DIRECTORY  equ     0x10
  36. ATTR_ARCHIVE    equ     0x20
  37.  
  38.  
  39.  
  40. show_error_1    equ     0x1     ;кончились данные - не запланированный конец секции
  41. show_error_2    equ     0x2     ;нет завершающего символа в размере рам диска.
  42. show_error_3    equ     0x4     ; рам диск будет иметь размер =64 кб.
  43. show_error_4    equ     0x8     ;
  44.  
  45. macro use_parse_def_sect
  46. {
  47.         mov     di, point_default
  48.         push    ini_data_
  49.         pop     es
  50.         mov     si, point_to_point_def
  51.         sub     si, 2
  52.         mov     cx, [si]        ;загрузим указатель наследующию секцию
  53.  
  54.         xor     ax, ax  ;обнулим аx для очистки флагов  
  55.  
  56.         sub     cx, di          ;вот теперь имеем истиный размер
  57.         mov     save_cx_d, cx   ;сохраним значение cx своей переменной
  58. ;обнулим переменную флагов, это необходимо, для того, что бы избежать обработку повторяющихся значений
  59.  
  60.         mov     status_flag, ax
  61. ;;;;
  62. ;ВХод в обработку парсинга значений секций. es:di - указатель на начало секции cx размер секции доступной для парсинга
  63. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  64. ;соглашение не разрушаем bp, es, cs, sp        
  65. ;use_Loader_Image       ;загрузить образ выше 1 мб
  66. use_RamdiskFS
  67. ;проверяется самый последний.
  68. use_LoaderModule    ;особенность - передает управление на загруженный модуль.
  69. }
  70.  
  71. macro use_LoaderModule
  72. ;как вариант сейчас используется модель, при загрузке модуля на него передается управление, решение временое
  73. ;управление будет передаваться только после обработки всей секции
  74. {
  75. local .found_end_str
  76.  
  77.         mov     di, point_default  ;restore value
  78.         mov     cx, save_cx_d
  79. ;обработка конструкции типа LoaderModule=kord/kolibri.ldm
  80. .start_p_LM:
  81.         call    get_firs_sym    ;get first symbol on new line
  82.         test    cx, cx
  83.         jz      ._afterLoaderModule     ;нету? ну ладно - следующее значение тогда )
  84.         cmp     al, 'L'
  85.         jnz     .start_p_LM
  86. ;проверка на значение LoaderModule
  87. ;        parse_LoaderModule
  88.         mov     bx, cx
  89.         mov     ax, di
  90.  
  91.         mov     si, parse_LoaderModule
  92.         mov     cx, parse_LoaderModule_e - parse_LoaderModule
  93.         repe cmpsb
  94.         jnz     .rest_value_loop_LM        ;is not compare
  95.  
  96.         sub     bx, parse_LoaderModule_e - parse_LoaderModule;correct cx
  97.         add     bx, cx
  98.         mov     cx, bx
  99.  
  100.         test    status_flag, flag_found_LM              ;оценка флагов
  101.         jz      .correct_is_not_set_LM
  102.  
  103. ;       mov     si,found_equal_timeout                          ;мы нашли что флаг уже установлен, информируем
  104. ;       call    printplain
  105. ;       jmp     .get_next_str
  106.  
  107. .correct_is_not_set_LM:
  108.         mov     ax, 0x3d20         ;cut al=' ' ah='='
  109.         repe scasb
  110.         jcxz    .rest_value_loop_LM          ;not found param timeout
  111.        
  112.         cmp     ah, byte [es:di-1]   ;find '='
  113.         jnz     .rest_value_loop_LM
  114.        
  115.         repe scasb                 ;cut ' '
  116.         inc     cx
  117.         dec     di
  118. ;di указывает на начало блока информации, в cx длинна до конца секции.
  119. ;после загрузки заноситься значение занятой памяти.
  120. ;для того что бы загрузить модуль, воспользуемся callback сервисом
  121. ;оригинальное решение - разместим dd перед строчкой и после строчки разместим byte =0
  122. ;это выглядит так: в ini файле существует строчка LoaderModule = kord/kernel.loader
  123. ;мы ее модифицируем до такого состояния       dw,dw,db'kord/kernel.loader',0 конечно сохранив те значения которые мы заменяем
  124. ;сохранили певые 2 word
  125.         push    dword [es:di-6]
  126.         lea     si, [di-6]
  127.  
  128.         push    word [es:di-2]
  129.         xor     ax, ax
  130.         mov     word [es:di-6], ax      ;вносим нужные значения
  131. ;info_real_mode_size размер и указатель на область в которую можно загрузиться
  132.         mov     ax, info_real_mode_size ;0x3000   ;следующий сегмент за данными
  133.  
  134.  
  135.         mov     word [es:di-4], ax
  136.         mov     word [es:di-2], 16      ;кол-во блоков по 4 кб =64 кб т.е. больше не считаем
  137. ;;;;;; поиск конца строчки
  138. @@:
  139.         mov     al, byte [es:di]
  140.         cmp     al, ' '
  141.         jz      .found_end_str
  142.         cmp     al, 0xa
  143.         jz      .found_end_str
  144.         cmp     al, 0xd
  145.         jz      .found_end_str
  146.         inc     di
  147.         dec     cx
  148.         jnz     @b
  149. ;;;not found допустим,что это конец файла и он не имеет привычного заверешния строки
  150. .found_end_str:
  151.  
  152.         push    word [es:di]
  153.         xor     ax, ax
  154.         mov     word [es:di], ax
  155. ;        xor     ax,ax   ; function 1 - read file
  156.         mov     di, si  ;file_data
  157.         inc     ax
  158.         push    si
  159.         push    es
  160.  
  161.         push    es
  162.         pop     ds
  163.         push    cs
  164.         pop     es
  165.  
  166.         call    far dword [es:loader_callback]
  167.  
  168.         push    cs
  169.         pop     ds
  170.  
  171.         pop     es
  172.         pop     si
  173.  
  174.         test    bx, bx
  175.         jnz     .error_LM
  176.  
  177.  
  178.         jmp     far dword [es:si]
  179.  
  180.  
  181. .error_LM:
  182.         call    error.LoaderModule
  183. .rest_value_loop_LM:
  184.         mov     di, ax
  185.         mov     cx, bx
  186.         jmp     .start_p_LM
  187.  
  188. ._afterLoaderModule:
  189. }
  190.  
  191. macro use_RamdiskFS
  192. ; формирование рам диска, + обработка всего связанного.
  193. {
  194. if DEBUG
  195. local ._not_memory_in_sys
  196. ;//////// clear window
  197.         mov     ax, 3
  198.         int     0x10
  199. ;\\\\\\\\\ clear window is end
  200.         mov     si, ramdiskFS_st
  201.         call    printplain
  202. end if
  203. ; обнулим регистр состояния ошибок
  204.         xor     ax, ax
  205.         mov     show_errors_sect, ax
  206. use_free_memory ; узнаем какого объема у нас доступна память. значение возаращается в ax
  207. ;узнаем сколько у нас есть памяти и сможем ли мы сформировать нужного размера рам диск.
  208. use_RamdiskSize ;значение возвращается в bx
  209.         cmp     free_ad_memory, bx      ; размерность в кб.
  210.         jbe     ._not_memory_in_sys
  211.         movzx   eax, bx
  212.         shl     eax, 10 ;*1024 = get size in byte
  213.         mov     save_ramdisksize, eax   ; сорханим размер в byte
  214.  
  215. get_type_FS     ;получим тип файловой системы + создадим ее
  216.  
  217.        
  218. ._not_memory_in_sys:
  219.        
  220. if DEBUG
  221. ;pause
  222.         xor     ax, ax
  223.         int     0x16
  224. end if
  225. }
  226. macro use_RamdiskSize
  227. {
  228. local .start_p_RS
  229. local .correct_is_not_set_RS
  230. local .CS
  231. local .correct_val_RS
  232. local .correct_size_RS
  233. local .rest_value_loop_RS
  234. local .end_get_RS_ERROR_1
  235. local .end_get_RS_ERROR_2
  236. local ._end_parse_RS
  237. ;обрабатывается размер формируемого рам диска
  238. ;загрузим начало секции, т.к. будем просматривать с начала и всю секцию
  239.         mov     di, point_default  ;restore value
  240.         mov     cx, save_cx_d
  241. .start_p_RS:
  242.         call    get_firs_sym    ;get first symbol on new line
  243.         test    cx, cx
  244.         jz      ._end_parse_RS  ;нету? ну ладно - следующее значение тогда )
  245.         cmp     al, 'R'
  246.         jnz     .start_p_RS
  247. ;проверка на значения RamdiskSize
  248. ;        parse_RamdiskSize
  249.         mov     bx, cx
  250.         mov     ax, di
  251.  
  252.         mov     si, parse_RamdiskSize
  253.         mov     cx, parse_RamdiskSize_e - parse_RamdiskSize
  254.         repe cmpsb
  255.         jnz     .rest_value_loop_RS    ;is not compare
  256.  
  257.         sub     bx, parse_RamdiskSize_e - parse_RamdiskSize;correct cx
  258.         add     bx, cx
  259.         mov     cx, bx
  260.  
  261.         test    status_flag, flag_found_RS              ;оценка флагов
  262.         jz      .correct_is_not_set_RS
  263.  
  264. ;       mov     si,found_equal_timeout                          ;мы нашли что флаг уже установлен, информируем
  265. ;       call    printplain
  266. ;       jmp     .get_next_str
  267.  
  268. .correct_is_not_set_RS:
  269.         mov     ax, 0x3d20         ;cut al=' ' ah='='
  270.         repe scasb
  271.         jcxz    .end_get_RS_ERROR_1          ;not found param
  272.        
  273.         cmp     ah, byte [es:di-1]   ;find '='
  274.         jnz     .start_p_RS                     ; перейдем на начало и попробуем найти еще секцию
  275.        
  276.         repe scasb                 ;cut ' '
  277.         inc     cx
  278.         dec     di
  279. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  280. ;Тут нужно преобразовывать строчку в цифровое значение.
  281. ;;;;;;;;;;;;;;;;;;;;;;;;;;
  282.         xor     bx, bx
  283.         mov     cx, 5
  284. @@:
  285.         mov     al, byte [es:di]
  286.         cmp     al, '0'
  287.         jb      .CS
  288.         cmp     al, '9'
  289.         jbe     .correct_val_RS
  290. .CS:
  291.         cmp     al, 'K'
  292.         jz      .correct_size_RS
  293.         jmp     .end_get_RS_ERROR_2
  294. .correct_val_RS:        
  295.         imul    bx, 10
  296.         xor     al, 0x30
  297.         add     bl, al
  298.         inc     di
  299.         loop    @b
  300.  
  301. .correct_size_RS:
  302. ;возможен 1 вариант, когда размер задан в K киллобайтах
  303. ;внутренный формат данных это кол-во запрощеной памяти в кб.
  304.         test    bx, bx
  305.         jnz     @f      ;если значение отлично от 0
  306. ;;;;;сообщение об ошибке, размер "найденого" блока =0 минимально мы должны
  307. ;установить 64 кб размер рам диска.
  308.         or      show_errors_sect, show_error_3
  309.         mov     bx, 64
  310. @@:
  311.         jmp     ._end_parse_RS
  312.  
  313.  
  314. .rest_value_loop_RS:
  315.         mov     di, ax
  316.         mov     cx, bx
  317.         jmp     .start_p_RS
  318.        
  319.        
  320.        
  321. .end_get_RS_ERROR_1:
  322. ;сообщение об ошибке - данный участок кода не был корректно обработан :(
  323.         or      show_errors_sect, show_error_1
  324.         jmp     ._end_parse_RS
  325. .end_get_RS_ERROR_2:    
  326.         or      show_errors_sect, show_error_2
  327.  
  328. ._end_parse_RS:
  329. if DEBUG
  330.         pusha
  331.         movzx   eax, bx
  332.         mov     cx, 0x0a
  333.         mov     di, RamdiskSize_msg
  334.         mov     dword[ds:di], '    '
  335.         mov     word [ds:di+4], '  '
  336.         call    decode
  337. ;Show size
  338.         mov     si, RamdiskSize_msg
  339.         call    printplain
  340.  
  341.         popa
  342. end if  
  343.  
  344. }
  345.  
  346. macro use_free_memory
  347. {      
  348. local _support_function_use_free_memory
  349. ;макрос для получения общего числа доступной памяти в кб, для формирования рам диска за пределами 1 мб.
  350. ;используется 0х88 функция 0х15 прерывания
  351. ; если поддерживается функция, то в ax значение в кб, если нет, то в ax=0
  352.         mov     ah, 0x88 ;ah,0x88
  353.         int     0x15
  354.         jnc     ._support_function_use_free_memory
  355.         xor     ax, ax
  356. ;возвращает в ax число в кб
  357. ._support_function_use_free_memory:
  358.         mov     free_ad_memory, ax ; если не поддерживается биосом, то в ax=0
  359. if DEBUG
  360.         pushad
  361.         movzx   eax, ax
  362.         mov     cx, 0x0a
  363.         mov     di, free_memory_msg
  364.         mov     dword[ds:di], '    '
  365.         mov     word [ds:di+4], '  '
  366.         call    decode
  367. ;Show size
  368.         mov     si, free_memory_msg
  369.         call    printplain
  370.  
  371.         popad
  372. end if  
  373.  
  374.  
  375.  
  376.  
  377. }
  378. macro show_ERRORS
  379. {
  380.  
  381. }
  382.  
  383. macro get_type_FS ;получить и создать образ для заданной RFS.
  384. {
  385.         mov     di, point_default  ;restore value
  386.         mov     cx, save_cx_d
  387. .start_g_tpe_RFS:
  388.         call    get_firs_sym    ;get first symbol on new line
  389.         test    cx, cx
  390.         jz      ._end_parse_FRS ;._end_get_type_RFS     ;нету? ну ладно - следующее значение тогда )
  391.         cmp     al, 'R'
  392.         jnz     .start_g_tpe_RFS
  393. ;проверка на значения RamdiskSize
  394. ;        parse_RamdiskSize
  395.         mov     bx, cx
  396.         mov     ax, di
  397.  
  398.         mov     si, parse_RamdiskFS
  399.         mov     cx, parse_RamdiskFS_e - parse_RamdiskFS
  400.         repe cmpsb
  401.         jnz     .start_g_tpe_RFS_rest_v    ;is not compare
  402.  
  403.         sub     bx, parse_RamdiskFS_e - parse_RamdiskFS;correct cx
  404.         add     bx, cx
  405.         mov     cx, bx
  406.  
  407.         test    status_flag, flag_found_GTRFMS          ;оценка флагов
  408.         jz      .correct_is_not_set_FRS
  409.  
  410. ;       mov     si,found_equal_timeout                          ;мы нашли что флаг уже установлен, информируем
  411. ;       call    printplain
  412. ;       jmp     .get_next_str
  413.  
  414. .correct_is_not_set_FRS:
  415.         mov     ax, 0x3d20         ;cut al=' ' ah='='
  416.         repe scasb
  417.         test    cx, cx
  418.         jz      .end_get_FRS_ERROR_1          ;not found param
  419.        
  420.         cmp     ah, byte [es:di-1]   ;find '='
  421.         jnz     .start_g_tpe_RFS                        ; перейдем на начало и попробуем найти еще секцию
  422.        
  423.         repe scasb                 ;cut ' '
  424.         inc     cx
  425.         dec     di
  426. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  427. ;Тут нужно преобразовывать строчку в цифровое значение.
  428. ;;;;;;;;;;;;;;;;;;;;;;;;;;
  429.         mov     bx, cx
  430.         mov     ax, di
  431.  
  432.         mov     si, parse_RFS_FAT
  433.         mov     cx, parse_RFS_FAT_e - parse_RFS_FAT
  434.         repe cmpsb
  435.         jnz     .krfs_cmp          ;is not compare
  436.  
  437. make_FAT_RamFS  ;сделать
  438.  
  439. if DEBUG
  440.         pusha
  441.         mov     si, make_fat12_RFS_msg
  442.         call    printplain
  443.         popa
  444. end if  
  445.         jmp     ._end_parse_FRS
  446.  
  447. .krfs_cmp:              
  448.         mov     cx, bx
  449.         mov     di, ax
  450.  
  451.         mov     si, parse_RFS_KRFS
  452.         mov     cx, parse_RFS_KRFS_e - parse_RFS_KRFS
  453.         repe cmpsb
  454. ;       jnz     @f         ;is not compare
  455.  
  456.         jmp     ._end_parse_FRS
  457.  
  458.  
  459. .start_g_tpe_RFS_rest_v:
  460.         mov     cx, bx
  461.         mov     di, ax
  462.         jmp     .start_g_tpe_RFS
  463.        
  464.        
  465.        
  466. .end_get_FRS_ERROR_1:
  467. ;сообщение об ошибке - данный участок кода не был корректно обработан :(
  468.         or      show_errors_sect, show_error_1
  469.         jmp     ._end_parse_FRS
  470. .end_get_FRS_ERROR_2:  
  471.         or      show_errors_sect, show_error_2
  472.  
  473. ._end_parse_FRS:
  474. if DEBUG
  475.         pusha
  476.         mov     si, get_type_FS_msg
  477.         call    printplain
  478.         popa
  479. end if  
  480.  
  481.  
  482.  
  483. }
  484. macro make_FAT_RamFS
  485. {
  486. local .RS1
  487. local .fat12
  488. local .fat16
  489. ; мы должны сформировать в начальный образ Ram FS, а потом записать его за область выше 1 мб..
  490. ;для случая с FAT12
  491. ;       mov     di,fat12_buffer ;ds должен быть = cs
  492. ;es:di - указывают на начало блока для формирования рам фс.
  493. use_RamdiskSector       ;возращаемое значение в ax размер сектора в байтах
  494.         cmp     ax, 4096;по спецификации значение должно быть в пределах от 1 до 4096
  495.         ja      .RS1
  496.         test    ax, ax
  497.         jnz     @f      ;ошибка если сюда прыгнули все таки ...
  498.  
  499. .RS1:
  500.         mov     word [fat12_buffer.BPB_BytsPerSec], 512
  501. ;;;;;;;;;;скажем что по дефолту будем юзать значение...
  502. @@:
  503.         mov     word [fat12_buffer.BPB_BytsPerSec], ax;тут все ок
  504.  
  505. ;BPB_SecPerClus кол-во секторов в кластере
  506. use_RamdiskCluster      ;возращаемое значение в al
  507.         cmp     al, 128
  508.         ja      @f
  509. ;       test    al,0x1  ;проверка на кратность )
  510. ;       jnz     @f
  511.  
  512.         mov     byte [fat12_buffer.BPB_SecPerClus], al
  513.  
  514.         ;incorrect value will be set dafault
  515.  
  516. ;ниже некорректное значение в т.к. размер кратен 2 и в диапазоне от 1 до 128 включительно
  517. ; мы должны ругнуться на это
  518. ;@@:    ;mov    byte [fat12_buffer.BPB_SecPerClus],1    
  519.  
  520. ;;;;; определеим какая у нас будет использоваться FAT
  521. ;по условию, fat12<4085<=fat16<65525<=fat32
  522. ; fat12_buffer.BPB_BytsPerSec*fat12_buffer.BPB_SecPerClus = кол-во секторов
  523.         movzx   eax, word [fat12_buffer.BPB_BytsPerSec]
  524.         movzx   ebx, byte [fat12_buffer.BPB_SecPerClus]
  525.  
  526.         imul    ebx, eax;тут размерность сектора
  527.         mov     eax, save_ramdisksize ;размер запрошенного рам диска в байтах
  528.         cdq
  529.         idiv    ebx
  530. ;;;;;;;; сейчас частное в eax, а остаток в edx
  531. ;получим кол-во секторов, и можем уже определить тип FAT которую нужно делать.
  532.         cmp     eax, 4085
  533.         jb      .fat12
  534.         cmp     eax, 65525
  535.         jb      .fat16
  536. ;;;;;;;;;;;;;;;;;;;;;;;; тут fat32
  537.         mov     set_ramfs, 32   ;установим тип файловой системы
  538.         mov     word [fat12_buffer.BPB_RsvdSecCnt], 32
  539.         xor     eax, eax
  540.         mov     word [fat12_buffer.BPB_RootEntCnt], ax
  541.         mov     word [fat12_buffer.BPB_TotSec16], ax
  542.         mov     dword [fat12_buffer.BPB_TotSec32], eax
  543.  
  544.  
  545. .fat16: ;fat16
  546. ;Для FAT12 и FAT16 дисков это поле содержит количество секторов, а BPB_TotSec32 равно 0, если значение <умещается> (меньше 0x10000).
  547.         jmp     $
  548.         mov     set_ramfs, 16   ;установим тип файловой системы
  549.         movzx   ebx, byte [fat12_buffer.BPB_SecPerClus]
  550.         imul    eax, ebx
  551.  
  552.         cmp     eax, 0x10000
  553.         jae     @f
  554.         mov     word [fat12_buffer.BPB_TotSec16], ax
  555.         mov     dword [fat12_buffer.BPB_TotSec32], 0
  556. @@:
  557. ;количество секторов занимаемое одной копией фат
  558. ;       mov     word [fat12_buffer.BPB_FATSz16],0x9     ;Для FAT12/FAT16 это количество секторов одной FAT. ??
  559. ;;;; заполним BPB_RootEntCnt Для FAT12 и FAT16 дисков, это поле содержит число
  560. ;32-байтных элементов корневой директории. Для FAT32 дисков, это поле должно
  561. ;быть 0. Пока константа, нужно будет позже доделать.
  562.         mov     eax, root_dir_entry_count
  563.         mov     word [fat12_buffer.BPB_RootEntCnt], ax  ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb)
  564. ;по документации рекомендуют отрезать 16 кб для рут дир но это оч много, даже для коос. имхо для начала хватит и 7 кб
  565. ;;;;;;;
  566. ;Для FAT16 это количество секторов одной FAT. Для FAT32 это значение
  567. ;равно 0, а количество секторов одной FAT содержится в BPB_FATSz32.
  568. ;RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec - 1)) / BPB_BytsPerSec;
  569.  
  570. ;TmpVal1 = DskSize - (BPB_ResvdSecCnt + RootDirSectors);
  571. ;TmpVal2 = (256 * BPB_SecPerClus) + BPB_NumFATs;
  572. ;If(FATType == FAT32)
  573. ;    TmpVal2 = TmpVal2 / 2;
  574. ;FATSz = (TMPVal1 + (TmpVal2 - 1)) / TmpVal2;
  575. ;If(FATType == FAT32) {
  576. ;    BPB_FATSz16 = 0;
  577. ;    BPB_FATSz32 = FATSz;
  578. ;} else {
  579. ;    BPB_FATSz16 = LOWORD(FATSz);
  580. ;    /* there is no BPB_FATSz32 in a FAT16 BPB */
  581. ;}
  582. ;=====================================
  583. ;RootDirSectors
  584.         movzx   ebx, word [fat12_buffer.BPB_BytsPerSec]
  585.         imul    eax, 32
  586.         add     eax, ebx
  587.         dec     eax
  588.  
  589.         cdq
  590.         idiv    ebx
  591. ;;;;;;;; сейчас частное в eax, а остаток в edx для дискеты 1.44 у нас должно быть значение =14
  592. ;BPB_ResvdSecCnt + RootDirSectors
  593.         movzx   ebx, word [fat12_buffer.BPB_RsvdSecCnt]
  594.         add     ebx, eax
  595.          
  596. ;DskSize у нас это значение уже получено и доступно
  597.         movzx   eax, word [fat12_buffer.BPB_TotSec16]   ;должен быть в секторах
  598.         sub     eax, ebx
  599.  
  600.  
  601. ;TmpVal1=eax
  602.         shl     edi, 8  ;=edi*256
  603.         movzx   ecx, byte [fat12_buffer.BPB_NumFATs]
  604.         add     edi, ecx
  605. ;TmpVal2=edi
  606.         add     eax, edi
  607.         dec     eax
  608.         cdq
  609.         idiv    edi
  610. ;FATSz = сейчас частное в eax, а остаток в edx
  611.         mov     word [fat12_buffer.BPB_FATSz16], ax
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620. .fat12: ;fat12
  621. if DEBUG
  622. ; выведем в отладке, что собираемся делать образ диска c FS=fat12
  623.         pushad
  624.         mov     si, start_making_FAT12_msg
  625.         call    printplain
  626.         popad
  627. end if
  628.  
  629.  
  630.  
  631. ;Для FAT12 и FAT16 дисков это поле содержит количество секторов, а BPB_TotSec32 равно 0, если значение <умещается> (меньше 0x10000).
  632.         mov     set_ramfs, 12   ;установим тип файловой системы
  633.         movzx   ebx, byte [fat12_buffer.BPB_SecPerClus]
  634.         imul    eax, ebx
  635.  
  636.         cmp     eax, 0x10000
  637.         jae     @f
  638.         mov     word [fat12_buffer.BPB_TotSec16], ax
  639.         mov     dword [fat12_buffer.BPB_TotSec32], 0
  640. @@:
  641. ;количество секторов занимаемое одной копией фат
  642. ;       mov     word [fat12_buffer.BPB_FATSz16],0x9     ;Для FAT12/FAT16 это количество секторов одной FAT. ??
  643. ;;;; заполним BPB_RootEntCnt Для FAT12 и FAT16 дисков, это поле содержит число
  644. ;32-байтных элементов корневой директории. Для FAT32 дисков, это поле должно
  645. ;быть 0. Пока константа, нужно будет позже доделать.
  646.         mov     eax, root_dir_entry_count
  647.         mov     word [fat12_buffer.BPB_RootEntCnt], ax  ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb)
  648. ;по документации рекомендуют отрезать 16 кб для рут дир но это оч много, даже для коос. имхо для начала хватит и 7 кб
  649. ;;;;;;;
  650. ;DskSize(в секторах)*12 (размерность файловой системы, т.е предположим сколько битов потребуется для адресации этого объема) /8 (что получить размер в байтах)
  651. ;полученное число округляем в большую сторону кратное сектору т.е. 512 байт Такой подход не универсален, но пока пойдет
  652. ;вообще у мелкософт это все считается ручками, но мы будем юзать только под коос рам диск с фат12
  653.         movzx   eax, word [fat12_buffer.BPB_TotSec16]
  654.         imul    eax, 12
  655.         shr     eax, 3  ;делим на 8 но т.е. нам нужно делить еще и на 512 или более в зависимости от размеров кластера
  656.         movzx   ebx, word [fat12_buffer.BPB_BytsPerSec] ;размер сектора
  657.         cdq
  658.         idiv    ebx     ;разделим на размер кластера
  659. ;сейчас у нас в eax значение его нужно округлить в большую сторону кратному 512 байтам
  660. ;применим следующее очистим and и добавим 512 байт. таким образом выравним на 512 байт
  661. ;но т.к. все равно делить нижний код нам не нужен
  662. ;       and     eax,0xfff200
  663. ;       add     eax,0x200       ;добавим 512 байт        для 1.44 дискеты идеально подходит ))  
  664.  
  665.         inc     ax
  666. ;по идее должно на каждую фат таблицу
  667. ;резервироваться 9 секторов т.е. получается 2*9=18+1 =19 секторов т.е. рут дир находиться на с 20 сетора т.е. с адреса 0х2600
  668. ;сейчас нужно вычислить сколько будет секторов занимать фат ) нужно разделить на 512
  669. ;FATSz = сейчас частное в eax
  670.         mov     word [fat12_buffer.BPB_FATSz16], ax
  671. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  672. get_firstDataSector ;получить смещение до данных
  673. ;создадим певую запись в фат по определенному адресу.
  674. first_create_fat_table
  675. ;закиним BPB файловой системы за 1 мб.
  676. use_BPB_RAM
  677. ;
  678. ;копирование файла.
  679. use_RamdiskFile
  680.  
  681. ;;;; вычисляем указатель на корневую дир FirstRootDirSecNum = BPB_ResvdSecCnt + (BPB_NumFATs * BPB_FATSz16);
  682. ;       movzx   ebx, [fat12_buffer.BPB_NumFATs]
  683. ;       movzx   eax,ax
  684. ;       imul    eax,ebx
  685. ;eax=(BPB_NumFATs * BPB_FATSz16)
  686. ;       inc     eax
  687. ; BPB_ResvdSecCnt значение только 1 для fat12/16
  688. ;в eax указатель на root dir. для дискеты fat12 должно получиться при кол-во копий fat 1  = 1+ (1*1) =2 или 3
  689.  
  690. if DEBUG        
  691.         pusha
  692. ;       mov     ax,point_default
  693. ;        mov     ax,cx
  694.         mov     cx, 0x0a
  695.         mov     di, show_db1
  696. ;        mov     dword[ds:di],'    '
  697. ;       mov     word [ds:di+4],'  '
  698.         call    decode
  699. ;Show size
  700.         mov     si, show_db1
  701.         call    printplain
  702. ;
  703. ;       xor     ax,ax
  704. ;       int     0x16
  705.         popa
  706. end if  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714. }
  715.  
  716. macro use_RamdiskSector
  717. {
  718. ;для некоторых FS будет игнорироваться
  719.         mov     di, point_default  ;restore value
  720.         mov     cx, save_cx_d
  721.  
  722. .start_RamdiskSector:
  723.         call    get_firs_sym    ;get first symbol on new line
  724.         test    cx, cx
  725.         jz      .end_RamdiskSector      ;нету? ну ладно - следующее значение тогда )
  726.  
  727.         cmp     al, 'R'
  728.         jnz     .start_RamdiskSector
  729. ;проверка на значения RamdiskSize
  730. ;        parse_RamdiskSize
  731.  
  732.         mov     bx, cx
  733.         mov     ax, di
  734.  
  735.         mov     si, parse_RamdiskSector
  736.         mov     cx, parse_RamdiskSector_e - parse_RamdiskSector
  737.         repe cmpsb
  738.         jnz     .RamdiskSector_rest_val    ;is not compare
  739.  
  740.         sub     bx, parse_RamdiskSector_e - parse_RamdiskSector;correct cx
  741.         add     bx, cx
  742.         mov     cx, bx
  743.  
  744.         test    status_flag, flag_found_RamdiskSector           ;оценка флагов
  745.         jz      .correct_is_not_set_RamdiskSector
  746.  
  747. ;       mov     si,found_equal_timeout                          ;мы нашли что флаг уже установлен, информируем
  748. ;       call    printplain
  749. ;       jmp     .get_next_str
  750.  
  751. .correct_is_not_set_RamdiskSector:
  752.         mov     ax, 0x3d20         ;cut al=' ' ah='='
  753.         repe scasb
  754.         jcxz    .end_get_RamS_ERROR_1          ;not found param
  755.        
  756.         cmp     ah, byte [es:di-1]   ;find '='
  757.         jnz     .start_RamdiskSector                    ; перейдем на начало и попробуем найти еще секцию
  758.        
  759.         repe scasb                 ;cut ' '
  760.         inc     cx
  761.         dec     di
  762. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  763.         xor     bx, bx
  764.         mov     cx, 4
  765. @@:
  766.         movzx   ax, byte [es:di]
  767.         cmp     al, '0'
  768.         jb      .end_RamdiskSector
  769.         cmp     al, '9'
  770.         ja      .end_RamdiskSector
  771. ;;;;;;;;;;;;;;;;;;;
  772.  
  773.         imul    bx, 10
  774.         xor     al, 0x30
  775.         add     bx, ax
  776.  
  777.         inc     di
  778.  
  779.         loop    @b
  780.         jmp     .end_RamdiskSector
  781.  
  782.  
  783. .RamdiskSector_rest_val:
  784.         mov     cx, bx
  785.         mov     di, ax
  786.         jmp     .start_RamdiskSector
  787. .end_get_RamS_ERROR_1:
  788.  
  789. .end_RamdiskSector:
  790.         mov     ax, bx
  791.  
  792. if DEBUG
  793.         pusha
  794.         movzx   eax, bx;save_cx_d;point_default
  795.         mov     cx, 0x0a
  796.         mov     di, RamdiskSector_msg
  797.         mov     dword[ds:di], '    '
  798.         mov     dword [ds:di+4], '    '
  799.         call    decode
  800. ;Show size
  801.         mov     si, RamdiskSector_msg
  802.         call    printplain
  803.  
  804.         popa
  805. end if  
  806.  
  807. ;       pop     di
  808. ;       pop     es
  809. }
  810.  
  811. macro use_RamdiskCluster
  812. {
  813. ;для некоторых FS будет игнорироваться
  814. ;       push    es
  815. ;       push    di
  816.         mov     di, point_default  ;restore value
  817.         mov     cx, save_cx_d
  818. ;       push    ini_data_
  819. ;       pop     es
  820. .start_RamdiskCluster:
  821.         call    get_firs_sym    ;get first symbol on new line
  822.         test    cx, cx
  823.         jz      .end_RamdiskCluster     ;нету? ну ладно - следующее значение тогда )
  824.         cmp     al, 'R'
  825.         jnz     .start_RamdiskCluster
  826. ;проверка на значения RamdiskSize
  827. ;        parse_RamdiskSize
  828.  
  829.         mov     bx, cx
  830.         mov     ax, di
  831.  
  832.         mov     si, parse_RamdiskCluster
  833.         mov     cx, parse_RamdiskCluster_e - parse_RamdiskCluster
  834.         repe cmpsb
  835.         jnz     .RamdiskCluster_rest_val           ;is not compare
  836.  
  837.         sub     bx, parse_RamdiskCluster_e - parse_RamdiskCluster;correct cx
  838.         add     bx, cx
  839.         mov     cx, bx
  840.  
  841.         test    status_flag, flag_found_RamdiskCluster          ;оценка флагов
  842.         jz      .correct_is_not_set_RamdiskCluster
  843.  
  844. ;       mov     si,found_equal_timeout                          ;мы нашли что флаг уже установлен, информируем
  845. ;       call    printplain
  846. ;       jmp     .get_next_str
  847.  
  848. .correct_is_not_set_RamdiskCluster:
  849.         mov     ax, 0x3d20         ;cut al=' ' ah='='
  850.         repe scasb
  851.         jcxz    .end_get_RamSC_ERROR_1          ;not found param
  852.        
  853.         cmp     ah, byte [es:di-1]   ;find '='
  854.         jnz     .start_RamdiskCluster                   ; перейдем на начало и попробуем найти еще секцию
  855.        
  856.         repe scasb                 ;cut ' '
  857.         inc     cx
  858.         dec     di
  859. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  860. @@:
  861.         movzx   ax, byte [es:di]
  862.         cmp     al, '0'
  863.         jb      .end_RamdiskCluster
  864.         cmp     al, '9'
  865.         ja      .end_RamdiskCluster
  866. ;;;;;;;;;;;;;;;;;;;
  867.         xor     al, 0x30
  868.  
  869.         jmp     .end_RamdiskCluster
  870.  
  871.  
  872. .RamdiskCluster_rest_val:
  873.         mov     cx, bx
  874.         mov     di, ax
  875.         jmp     .start_RamdiskCluster
  876. .end_get_RamSC_ERROR_1:
  877.  
  878. .end_RamdiskCluster:
  879. if DEBUG
  880.         pusha
  881.         mov     cx, 0x0a
  882.         mov     di, RamdiskCluster_msg
  883. ;        mov     word[ds:di],'  '
  884.         call    decode
  885. ;Show size
  886.         mov     si, RamdiskCluster_msg
  887.         call    printplain
  888.  
  889.         popa
  890. end if  
  891.  
  892. }
  893.  
  894. macro use_Loader_Image
  895. ;предназначен для загрузки образов выше 1 Мб.
  896. ;первоначальная версия загружает образ дискеты 1.44 мб
  897. {
  898. local .start_p_LI
  899. local .exit
  900. local .error_LI
  901. local .rest_value_loop
  902. local .found_end_str
  903.         mov     di, point_default  ;restore value
  904.         mov     cx, save_cx_d
  905. ;обработка конструкции типа LoaderModule=kord/kolibri.ldm
  906. .start_p_LI:
  907.         call    get_firs_sym    ;get first symbol on new line
  908.         test    cx, cx
  909.         jz      .exit   ;нету? ну ладно - следующее значение тогда )
  910.         cmp     al, 'L'
  911.         jnz     .start_p_LI
  912. ;проверка на значение LoaderModule
  913. ;        parse_LoaderModule
  914.         mov     bx, cx
  915.         mov     ax, di
  916.  
  917.         mov     si, parse_LoaderImage
  918.         mov     cx, parse_LoaderImage_e - parse_LoaderImage
  919.         repe cmpsb
  920.         jnz     .rest_value_loop           ;is not compare
  921.  
  922.         sub     bx, parse_LoaderImage_e - parse_LoaderImage;correct cx
  923.         add     bx, cx
  924.         mov     cx, bx
  925.  
  926. ;       test    status_flag,flag_found_LM               ;оценка флагов
  927. ;       jz      .correct_is_not_set_LI          
  928.  
  929. ;       mov     si,found_equal_timeout                          ;мы нашли что флаг уже установлен, информируем
  930. ;       call    printplain
  931. ;       jmp     .get_next_str
  932.  
  933. ;.correct_is_not_set_LI:
  934.         mov     ax, 0x3d20         ;cut al=' ' ah='='
  935.         repe scasb
  936.         jcxz    .rest_value_loop_LI          ;not found param timeout
  937.        
  938.         cmp     ah, byte [es:di-1]   ;find '='
  939.         jnz     .rest_value_loop_LI
  940.        
  941.         repe scasb                 ;cut ' '
  942.         inc     cx
  943.         dec     di
  944. ;di указывает на начало блока информации, в cx длинна до конца секции.
  945. ;после загрузки заноситься значение занятой памяти.
  946. ;для того что бы загрузить модуль, воспользуемся callback сервисом
  947. ;оригинальное решение - разместим dd перед строчкой и после строчки разместим byte =0
  948. ;это выглядит так: в ini файле существует строчка LoaderModule = kord/kernel.loader
  949. ;мы ее модифицируем до такого состояния       dw,dw,db'kord/kernel.loader',0 конечно сохранив те значения которые мы заменяем
  950. ;сохранили певые 2 word
  951.         push    dword [es:di-6]
  952.         lea     si, [di-6]
  953.  
  954.         push    word [es:di-2]
  955.         xor     ax, ax
  956.         mov     word [es:di-6], ax      ;вносим нужные значения
  957. ;info_real_mode_size размер и указатель на область в которую можно загрузиться
  958.         mov     ax, info_real_mode_size ;0x3000   ;следующий сегмент за данными
  959.  
  960.  
  961.         mov     word [es:di-4], ax
  962.         mov     word [es:di-2], 16      ;кол-во блоков по 4 кб =64 кб т.е. больше не считаем
  963. ;;;;;; поиск конца строчки
  964. @@:
  965.         mov     al, byte [es:di]
  966.         cmp     al, ' '
  967.         jz      .found_end_str
  968.         cmp     al, 0xa
  969.         jz      .found_end_str
  970.         cmp     al, 0xd
  971.         jz      .found_end_str
  972.         inc     di
  973.         dec     cx
  974.         jnz     @b
  975. ;;;not found допустим,что это конец файла и он не имеет привычного заверешния строки
  976. .found_end_str:
  977. ; чтение блока по 64 кб в сегмент и забрасывание его выше 1 мб.
  978.         push    word [es:di]
  979.         xor     ax, ax
  980.         mov     word [es:di], ax
  981. ;        xor     ax,ax   ; function 1 - read file
  982.         mov     di, si  ;file_data
  983.         inc     ax
  984.         push    si
  985.         push    es
  986.         call    far dword [loader_callback]
  987.         push    cs
  988.         pop     ds
  989.  
  990.         pop     es
  991.         pop     si
  992.  
  993.         test    bx, bx
  994.         jnz     .error_LM
  995.  
  996.  
  997. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; забрасывание блока в 64 кб выше 1 мб.
  998.         mov     si, table_15_87
  999.         push    es
  1000.         push    ds
  1001.         pop     es
  1002.         mov     cx, 256*18
  1003.         mov     ah, 0x87
  1004.         int     0x15
  1005.         pop     es
  1006.         pop     dx cx
  1007.         test    ah, ah
  1008.  
  1009.  
  1010.  
  1011.         jmp     far dword [es:si]
  1012.  
  1013.  
  1014.  
  1015.  
  1016. .rest_value_loop:
  1017.         mov     di, ax
  1018.         mov     cx, bx
  1019.         jmp     .start_p_LI
  1020.  
  1021. .exit:
  1022.  
  1023.  
  1024.  
  1025. }
  1026.  
  1027.  
  1028.  
  1029. macro name_in_root_fat
  1030. ;макрос, который записывает информацию о загруженном файле в корневую фат таблицу
  1031. {
  1032.  
  1033. }
  1034.  
  1035.  
  1036.  
  1037. macro use_RamdiskFile
  1038. {
  1039. ;загрузка файлов с использование callback сервиса первичного загрузчика
  1040. ;используется только для загрузки необходимых и небольших файлов, т.к. достаточно медленно работает
  1041. ;для загрузки использует 0х87 функцию int 0x15 прерывания - загрузка блоков данных до 64 кб выше 1 мб
  1042. local   .start_loop
  1043. local   ._end
  1044. local   .rest_value_loop
  1045. local   .error
  1046.         mov     di, point_default  ;restore value
  1047.         mov     cx, save_cx_d
  1048.         mov     data_offset, 0  ;clean offset
  1049. ;обработка конструкции типа LoaderModule=kord/kolibri.ldm
  1050. .start_loop:
  1051.         call    get_firs_sym    ;get first symbol on new line
  1052.         test    cx, cx
  1053.         jz      ._end   ;нету? ну ладно - следующее значение тогда )
  1054.         cmp     al, 'R'
  1055.         jnz     .start_loop
  1056. ;проверка на значение RamdiskFile
  1057.         mov     bx, cx
  1058.         mov     ax, di
  1059.  
  1060.         mov     si, parse_RamdiskFile
  1061.         mov     cx, parse_RamdiskFile_e - parse_RamdiskFile
  1062.         repe cmpsb
  1063.         jnz     .rest_value_loop           ;is not compare
  1064.  
  1065.         sub     bx, parse_RamdiskFile_e - parse_RamdiskFile;correct cx
  1066.         add     bx, cx
  1067.         mov     cx, bx
  1068. ;       test    status_flag,flag_found_LM               ;оценка флагов
  1069. ;       jz      .correct_is_not_set_LM          
  1070.  
  1071. ;       mov     si,found_equal_timeout                          ;мы нашли что флаг уже установлен, информируем
  1072. ;       call    printplain
  1073. ;       jmp     .get_next_str
  1074.  
  1075. ;.correct_is_not_set_LM:
  1076.         mov     ax, 0x3d20         ;cut al=' ' ah='='
  1077.         repe scasb
  1078.         test    ecx, ecx
  1079.         jz      .rest_value_loop   ;not found param timeout
  1080.        
  1081.         cmp     ah, byte [es:di-1] ;find '='
  1082.         jnz     .rest_value_loop
  1083.        
  1084.         repe scasb                 ;cut ' '
  1085.         inc     cx
  1086.         dec     di
  1087.  
  1088.         mov     save_di_RAMDISK, di
  1089.         mov     save_cx_RAMDISK, cx
  1090. ;di указывает на начало блока информации, в cx длинна до конца секции.
  1091. ;после загрузки заноситься значение занятой памяти.
  1092. ;для того что бы загрузить модуль, воспользуемся callback сервисом
  1093. ;оригинальное решение - разместим dd перед строчкой и после строчки разместим byte =0
  1094. ;это выглядит так: в ini файле существует строчка RamdiskFile = @menu,@menu
  1095. ;мы ее модифицируем до такого состояния       dw,dw,db'@menu',0 конечно сохранив те значения которые мы заменяем
  1096. ;сохранили певые 2 word
  1097.  
  1098. ;
  1099. @@:
  1100.         mov     al, byte [es:di]
  1101.         cmp     al, ','         ; т.е. ищем разделитель
  1102.         jz      .found_end_str
  1103.         inc     di
  1104.         dec     cx
  1105.         jnz     @b
  1106. ;;;not found допустим,что это конец файла и он не имеет привычного завершения строки
  1107. .found_end_str:
  1108. ;        mov    al,byte [es:di]
  1109. ;       cmp     al,' '          ; убираем пробелы, если они есть
  1110. ;       jnz     @f
  1111. ;       inc     di
  1112. ;       dec     cx
  1113. ;       jnz     .found_end_str
  1114.  
  1115. ;@@:
  1116.         mov     point_to_dest_file_name, di
  1117.         inc     di
  1118. ;проверка индивидуальности имени файла
  1119. check_name_file
  1120. ;/restore di - point and cx -size section
  1121.         mov     di, save_di_RAMDISK
  1122.         mov     cx, save_cx_RAMDISK
  1123.  
  1124.         test    al, al
  1125.         jnz     .start_loop     ;если в al значение не =0, то такое имя уже существует в системе.
  1126.  
  1127.  
  1128.  
  1129.         push    dword [es:di-6]
  1130.         lea     si, [di-6]
  1131.  
  1132.         push    word [es:di-2]
  1133.         push    di
  1134.         xor     ax, ax
  1135.         mov     word [es:di-6], ax      ;вносим нужные значения
  1136. ;info_real_mode_size размер и указатель на область в которую можно загрузиться
  1137.         mov     ax, info_real_mode_size ;0x3000   ;следующий сегмент за данными
  1138.  
  1139.  
  1140.         mov     word [es:di-4], ax
  1141.         mov     word [es:di-2], 16      ;кол-во блоков по 4 кб =64 кб т.е. больше не читаем
  1142.  
  1143.         mov     di, point_to_dest_file_name
  1144.  
  1145. if DEBUG
  1146.         pushad
  1147. ;       mov     ax,di
  1148.         mov     cx, 0x0a
  1149.         mov     di, name_of_seg_get_64
  1150.         mov     dword[ds:di], '    '
  1151.         mov     word[ds:di+4], '  '
  1152.         call    decode
  1153. ;Show size
  1154.         mov     si, name_of_seg_get_64
  1155.         call    printplain
  1156.  
  1157.         popad
  1158. end if  
  1159.  
  1160.         push    word [es:di]
  1161.         push    cx
  1162.         xor     ax, ax
  1163.         mov     word [es:di], ax
  1164. ;        xor     ax,ax   ; function 1 - read file
  1165.         push    di
  1166.         mov     di, si  ;file_data
  1167.         inc     ax
  1168.         push    si
  1169.         push    es
  1170.         push    bp
  1171.  
  1172.         push    es
  1173.         pop     ds
  1174.         push    cs
  1175.         pop     es
  1176.  
  1177.         call    far dword [es:loader_callback]
  1178.  
  1179.  
  1180.         push    cs
  1181.         pop     ds
  1182.  
  1183.         pop     bp
  1184.         pop     es
  1185.         pop     si
  1186.  
  1187.         cmp     bx, 2
  1188.         ja      .error
  1189. ; сейчас у нас в dx:ax размер файла, который мы загрузили.
  1190. ; возможна ситуация, когда в bx=1 т.е. есть еще данные на диске
  1191.         mov     status_flag_loader_f, bx
  1192.  
  1193.         shl     edx, 16
  1194.         mov     dx, ax
  1195. ;       shr     edx,10  ;размер файла в кб.
  1196. ;;в edx размер в байтах.        
  1197.         mov     save_file_size, edx
  1198.         mov     eax, edx
  1199. ;восстановим полностью файл сценария
  1200.         pop     di
  1201.         pop     cx      ;длинна остатка с 2-ой частью имени т.е. с именем назначением.
  1202.         pop     word [es:di]
  1203.         pop     di
  1204.         pop     word [es:di-2]
  1205.         pop     dword [es:di-6]
  1206.        
  1207.  
  1208. if DEBUG
  1209.         pushad
  1210.         mov     cx, 0x0a
  1211.         mov     di, RamdiskFile_msg
  1212.         mov     dword[ds:di], '    '
  1213.         call    decode
  1214. ;Show size
  1215.         mov     si, RamdiskFile_msg
  1216.         call    printplain
  1217.  
  1218.         popad
  1219. end if  
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.  
  1229.  
  1230. ; загрузим чему у нас равен кластер
  1231. ;       mov     ax,word [fat12_buffer.BPB_BytsPerSec] ;кол-во байтов в секторе может быть любое 512 1024 2048 4096 2 байта
  1232. ;       movzx   bx,byte [fat12_buffer.BPB_SecPerClus] ;кол-во секторов в кластере
  1233. ;       imul    ax,bx
  1234. ;сейчас в eax размер кластера (512) байт
  1235. ;в edx длина файла в байтах до 64 кб    
  1236. ;закиним файл за 1 мб
  1237. ;1 нам нужно составить фат таблицу т.е. произвести разметку рамдиска, затем перенесем по адресу файл
  1238.  
  1239. ;записать инфорамацию о файле в корневую директорию
  1240. register_file_in_fat
  1241. ;перенести за 1 мб содержимое файла
  1242. move_file_up
  1243.  
  1244. ;проверим, загружен ли до конца файл? т.е. если размер файла больше чем 64 кб, то будет подгружать оставшиеся блоки
  1245.         cmp     status_flag_loader_f, 0x1
  1246.         jnz     @f
  1247. ;нужно дозагузить данные файла и перенести их за 1-ый мб согласно фат структуре
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257. @@:
  1258. ;тут организован цикл по загрузке файлов в корневую директорию
  1259.         mov     di, save_di_RAMDISK
  1260.         mov     cx, save_cx_RAMDISK
  1261. if DEBUG        
  1262.         pusha
  1263.         xor     ax, ax
  1264.         int     0x16
  1265.         popa
  1266. end if  
  1267.  
  1268.  
  1269.         jmp     .start_loop
  1270.  
  1271.  
  1272. .error:
  1273.         ;call   error.LoaderModule
  1274. ;fixme!
  1275. .rest_value_loop:
  1276.         mov     di, ax
  1277.         mov     cx, bx
  1278.         jmp     .start_loop
  1279.  
  1280. ._end:
  1281. ;перенесем за 1-ый мб фат и рут дир
  1282. move_up_fat_and_root_d
  1283.  
  1284.  
  1285.  
  1286.  
  1287.  
  1288.  
  1289. ;загрузка блока
  1290. ;       mov     ah,0x87
  1291. ;       mov     cx,     ;size in byte
  1292.        
  1293.  
  1294. ;es:si point to descripts
  1295.  
  1296.  
  1297. }
  1298.  
  1299. macro use_BPB_RAM ;закинуть самые первые 512 байт за 1-й мб
  1300. ;данный макрос закидывает BPB структуру т.е. первые 512 байт, пока только фат12 за 1 мб
  1301. {
  1302.         mov     ax, fat12_buffer
  1303.         mov     si, table_15_87
  1304.         add     word [si+8*2+2], ax
  1305.         push    es
  1306.         push    ds
  1307.         pop     es
  1308.         mov     cx, 256  ;бут сектор  укладывается в 512 байт 512/2=256
  1309.         mov     ah, 0x87
  1310.         int     0x15
  1311.         pop     es
  1312. ;add 512 byte for destination adress
  1313. ;       add     dword [si+8*3+2], 512
  1314. ;        test    ah, ah
  1315. ;        jz    
  1316. if DEBUG        
  1317.         pusha
  1318.         mov     ax, word [si+8*2+2]
  1319.         mov     cx, 0x0a
  1320.         mov     di, BPB_msg
  1321.         call    decode
  1322. ;Show size
  1323.         mov     si, BPB_msg
  1324.         call    printplain
  1325.         popa
  1326. end if  
  1327. }
  1328. macro first_create_fat_table
  1329. ;данный макрос создает оформляет 3 первых байта fat таблицы, и устанавливает указатель на следующий блок, и вносит 0 значение
  1330. ;для смещения в корневой таблице.
  1331. {
  1332.         mov     al, byte [fat12_buffer.BPB_Media]
  1333.  
  1334.  
  1335.         push    ds
  1336.  
  1337.  
  1338.         mov     di, info_real_mode_size
  1339.         add     di, 0x1000
  1340.  
  1341. if DEBUG
  1342.         pushad
  1343.  
  1344.         mov     ax, info_real_mode_size
  1345.         add     ax, 0x1000
  1346. ;       mov     ax,ds
  1347.         mov     cx, 0xa
  1348.                
  1349.         mov     di, first_entry_in_fat
  1350.         mov     dword [di], '    '
  1351.         mov     word [di+4], '  '
  1352.         call    decode
  1353. ;Show size
  1354.         mov     si, first_entry_in_fat
  1355.         call    printplain
  1356.  
  1357.         xor     ax, ax
  1358.         int     0x16
  1359.      
  1360.         popad
  1361. end if
  1362.  
  1363.  
  1364.         push    di   ;  push    word info_real_mode_size+0x1000   ;cледующий сегмент за загруженным участком
  1365.        
  1366.         xor     di, di
  1367.         mov     point_to_free_root, di  ;значение смещения =0 в корневой фат таблице описания
  1368.  
  1369.         pop     ds   ; загружен следующий сегмент т.е. пустой сегмент
  1370.  
  1371.         mov     byte [di], al
  1372.         or      ax, -1
  1373.         inc     di
  1374.         mov     word [di], ax
  1375.  
  1376.         pop     ds
  1377.         mov     point_next_fat_str, 3
  1378.  
  1379. if DEBUG        
  1380.         pushad
  1381.         mov     ax, point_next_fat_str
  1382.         mov     cx, 0x0a
  1383.         mov     di, fat_create_msg
  1384.         call    decode
  1385. ;Show size
  1386.         mov     si, fat_create_msg
  1387.         call    printplain
  1388.         popad
  1389. end if  
  1390.  
  1391. }
  1392. macro register_file_in_fat
  1393. ;макрос регистрации файла в файловой структуре Fat
  1394. ;пока поддерживается только фат12, пока ))
  1395. ;вычисление смежных кластеров и занесение инфы в fat/
  1396. {
  1397. local   .step2
  1398. local   .step3
  1399. local   .end
  1400. local   .eof_file
  1401.  
  1402. ;di point on root dir на фри секцию.
  1403.         push    es
  1404.  
  1405.         mov     ax, info_real_mode_size
  1406.         add     ax, 0x1000
  1407.         mov     es, ax ;        push    word info_real_mode_size+0x1000   ;сегмент следующий за загруженным блоком в 64 кб
  1408.  
  1409. ; определяем тип фат пока не определяем, пока только фат 12
  1410. ; 12 бит, для вычесления соседних каластеров.
  1411.         mov     di, firstDataSect    ;в секторах
  1412.         sub     di, size_root_dir
  1413. ;теперь в ax размер в секторах начала рут дир
  1414.         shl     di, 9;imul 512
  1415.         add     di, point_to_free_root  ;смещение в уже записанных 32-х структурах.
  1416. ;необходимо внести значение в рут дир т.е. 32 байта
  1417. if DEBUG        
  1418.         pushad
  1419. ;       mov     ax,point_default
  1420. ;        mov     ax,
  1421.         mov     cx, 0x0a
  1422.         mov     di, show_db2
  1423.         mov     dword[ds:di], '    '
  1424.         mov     word [ds:di+4], '  '
  1425.         call    decode
  1426. ;Show size
  1427.         mov     si, show_db2
  1428.         call    printplain
  1429. ;
  1430. ;       xor     ax,ax
  1431. ;       int     0x16
  1432.         popad
  1433. end if  
  1434.  
  1435.  
  1436.  
  1437. ;gs:di - указатель для внесения инфорации в рут область фат таблицы инормации о файле.
  1438.         mov     si, shot_name_fat
  1439.         mov     cx, 11
  1440. ;запишем в структуру имя
  1441. @@:
  1442.         lodsb
  1443.         stosb
  1444.         loop    @b
  1445.  
  1446. ;запишем атрибуты файла и DIR_NTRes - зарезеврированный байт =0
  1447.         xor     ax, ax
  1448.         mov     ah, ATTR_VOLUME_ID
  1449.         mov     word [es:di], ax
  1450.         add     di, 2
  1451. ;DIR_CrtTimeTenth
  1452.         mov     byte [es:di], 100
  1453.         inc     di
  1454. ;DIR_CrtTime
  1455.         mov     word [es:di], 0x032b   ;дата
  1456.         add     di, 2
  1457. ;DIR_CrtDate
  1458.         mov     word [es:di], 0x0      ;время ><
  1459.         add     di, 2
  1460. ;DIR_LstAccDate
  1461.         mov     word [es:di], 0x032b   ;дата моего
  1462.         add     di, 2
  1463. ;DIR_FstClusHI
  1464.         mov     word [es:di], 0x0      ;время для фат12 /16 всегда 0
  1465.         add     di, 2
  1466. ;DIR_WrtTime
  1467.         mov     word [es:di], 0x0      ;время ><
  1468.         add     di, 2
  1469. ;DIR_WrtDate
  1470.         mov     word [es:di], 0x032b
  1471.         add     di, 2
  1472.        
  1473.         mov     ax, point_next_fat_str
  1474.         mov     word [es:di], ax
  1475.         add     di, 2
  1476.  
  1477.         push    di
  1478. ;DIR_FstClusLO                  Младшее слово номера первого кластера.
  1479.  ;       mov     ax,point_next_fat_str   ;загрузим указатель на элемент фат таблицы т.е. это номер фат записи
  1480. ;FATOffset = N + (N / 2) т.е. это уже у нас смещение мы знаем что -начинается все с 3-го элемента записи фат
  1481.         mov     bx, ax
  1482.         shr     bx, 1
  1483.         add     ax, bx
  1484. ;в ах сейчас FATOffset
  1485. ;ThisFATEntOffset = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec);
  1486.         mov     bx, word [fat12_buffer.BPB_BytsPerSec]
  1487.         cwd
  1488.         idiv    bx
  1489. ;ax=ThisFATEntOffset= rem (FATOffset / BPB_BytsPerSec) четный или нечетный указатель.
  1490.         mov     si, ax
  1491. ;нам нужно в цикле записать все кластеры которые будут использованы для размещения файла.
  1492. ;узнаем размер кластера.
  1493.         movzx   eax, word [fat12_buffer.BPB_BytsPerSec]
  1494.         movzx   ebx, byte [fat12_buffer.BPB_SecPerClus]
  1495.         imul    eax, ebx
  1496. ;ax - размер кластера.
  1497. ;сейчас будем записывать во временный буфер фат таблицу для выбранного файла. Поскольку мы его загрузили возможно не полностью
  1498. ;мы обработаем запись для фат полностью, в не зависимости от предела буфера где возможна часть файла.  
  1499.         mov     ebx, save_file_size     ;размер файла в байтах
  1500.        
  1501. @@:
  1502.         sub     ebx, eax
  1503.         cmp     ebx, eax
  1504.         jbe     .eof_file
  1505.  
  1506.         inc     point_next_fat_str
  1507.         mov     cx, point_next_fat_str  ;загрузим указатель на элемент фат таблицы т.е. это номер фат записи
  1508. ;FATOffset = N + (N / 2) т.е. это уже у нас смещение мы знаем что -начинается все с 3-го элемента записи фат
  1509.         mov     dx, ax
  1510.         shr     dx, 1
  1511.         add     cx, dx
  1512.  
  1513.  
  1514.  
  1515.         test    si, 0x1
  1516.         jz      .step2
  1517.         shl     cx, 4
  1518.         mov     word[es:si], cx
  1519.         inc     si
  1520.         add     cx, ax
  1521.         jmp     @b
  1522.  
  1523. .step2:
  1524.         and     cx, 0x0FFF
  1525.         mov     word[es:si], cx
  1526.         inc     si
  1527.         add     cx, ax
  1528.         jmp     @b
  1529.  
  1530. .eof_file:
  1531.         mov     cx, 0x0fff
  1532.         test    si, 0x1
  1533.         jz      .step3
  1534.         shl     cx, 4
  1535.         mov     word[es:si], cx
  1536.         jmp     .end
  1537.  
  1538. .step3:
  1539.         and     cx, 0x0FFF
  1540.         mov     word[es:si], cx
  1541.  
  1542. .end:
  1543.         inc     point_next_fat_str
  1544.  
  1545.         pop     di
  1546. ;DIR_FileSize 32-битный DWORD содержит размер файла в байтах.
  1547.         mov     eax, save_file_size
  1548.         mov     dword [es:di], eax
  1549.  
  1550. if DEBUG        
  1551.         pushad
  1552.  
  1553.         mov     di, firstDataSect    ;в секторах
  1554.         sub     di, size_root_dir
  1555. ;теперь в ax размер в секторах начала рут дир
  1556.         shl     di, 9;imul 512
  1557.         add     di, point_to_free_root  ;смещение в уже записанных 32-х структурах.
  1558.  
  1559.         push    di
  1560.  
  1561.         mov     si, dest_name_fat
  1562.         mov     cx, 11
  1563.  
  1564. ;запишем в структуру имя
  1565. @@:
  1566.         mov     al, byte [es:di]
  1567.         inc     di
  1568.         mov     byte [ds:si], al
  1569.         inc     si
  1570.         loop    @b
  1571.        
  1572.         mov     di, si
  1573.         inc     di
  1574.         pop     ax
  1575.         mov     cx, 0xa
  1576.         call    decode
  1577.  
  1578.         mov     si, dest_name_fat
  1579.         call    printplain
  1580.         popad
  1581.  
  1582. END IF
  1583.  
  1584.  
  1585.  
  1586.  
  1587.  
  1588.         add     point_to_free_root, 32  ;увелицим смещение до следующего значения.
  1589.         pop     es
  1590.  
  1591. }
  1592.  
  1593.  
  1594.  
  1595.  
  1596.  
  1597. macro get_firstDataSector
  1598. ;макрос для вычисления певого сектора данных т.е. данных файлов в фате
  1599. ;вычислим FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors;
  1600. {
  1601.         mov     ax, word [fat12_buffer.BPB_FATSz16]
  1602.         movzx   bx, byte [fat12_buffer.BPB_NumFATs]
  1603.         imul    ax, bx  ;9x1=9
  1604. ;ax=BPB_NumFATs * FATSz
  1605.         mov     bx, word [fat12_buffer.BPB_RootEntCnt]  ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb)
  1606.         shr     bx, 4   ;imul bx,32 and then div 512 -> in bx size in sectors
  1607.         add     ax, bx  ;9+14=23
  1608.         mov     size_root_dir, bx
  1609.         movzx   bx, byte [fat12_buffer.BPB_RsvdSecCnt]  ;add 1 for fat 16/12
  1610.         add     ax, bx
  1611. ;ax=firstDataSector - где начинается первый секторо от 0 сектора в секторах. - фактически = 24 сектор
  1612.         mov     firstDataSect, ax       ;сохраним для вычисления
  1613. ;       получимзначение кластеров, это объем в который мы можем записать данные
  1614.         mov     bx, word [fat12_buffer.BPB_TotSec16]
  1615.         sub     bx, ax
  1616.         mov     ax, bx
  1617.         movzx   bx, byte [fat12_buffer.BPB_SecPerClus]
  1618.         cwd
  1619.         idiv    bx
  1620.         mov     DataClasters, ax
  1621.  
  1622. if DEBUG        
  1623.         pushad
  1624.         mov     ax, firstDataSect       ;первый сектор данных
  1625.         mov     cx, 0x0a
  1626.         mov     di, firstDataSect_msg
  1627.         call    decode
  1628. ;Show size
  1629.         mov     si, firstDataSect_msg
  1630.         call    printplain
  1631. ;;;;;;;;;;;;;;;;;;;;;;;;;;
  1632.         mov     ax, size_root_dir       ;размер рут дир в сетокторах
  1633.         mov     cx, 0x0a
  1634.         mov     di, size_root_dir_msg
  1635.         call    decode
  1636. ;Show size
  1637.         mov     si, size_root_dir_msg
  1638.         call    printplain
  1639. ;;;;;;;;;;;;;;;;;;;;;;;;;;
  1640.         mov     ax, DataClasters;кластеры
  1641.         mov     cx, 0x0a
  1642.         mov     di, DataClasters_msg
  1643.         call    decode
  1644. ;Show size
  1645.         mov     si, DataClasters_msg
  1646.         call    printplain
  1647.         popad
  1648.  
  1649. end if  
  1650.  
  1651. }
  1652.  
  1653. macro use_RamdiskPATHS
  1654. ;парсинг пути источника файлов.
  1655. {
  1656.  
  1657. }
  1658.  
  1659. macro use_RamdiskPATHD
  1660. ;парсинг пути назначения файлов.
  1661. {
  1662.  
  1663. }
  1664. macro check_name_file
  1665. ;макрос проверки имени на повтор, имя должно быть уникальным.
  1666. ;входные данные: es- сегмент где лежит файл для парсинга т.е. startos.ini
  1667. ;di - указатель на имя файла т.е. es:di указывает на имя файла назначения
  1668. ;выходные данные eax =-1 имя совпало, eax=0 имя не совпало.
  1669. {
  1670. local   .no_equal
  1671. local   .exit
  1672. local   .loop_size_root_dir
  1673. ;вычислим длинну строчки имени назначения, которую будем сравнивать с уже записанными данными.
  1674. ;преобразуем в аналог фат записи сточку с именем назначения
  1675.         convertion_file_name    ; преобразовали имя по нужным правилам
  1676.         test    ax, ax
  1677.         jnz     .exit
  1678.  
  1679.         lea     si, [shot_name_fat]     ; desination name of file
  1680.  
  1681. ;вычислим указатель на корневую директорию
  1682.         mov     di, firstDataSect
  1683.         sub     di, size_root_dir
  1684. ;теперь в ax размер в секторах начала рут дир
  1685.         shl     di, 9;imul 512
  1686. ;di= Это смещение от начала буфера до рут директории. в пределах 64 кб.
  1687. ;загрузим значение - т.е. кол-во элементов, которые мы можем просматривать.
  1688.         mov     dx, root_dir_entry_count
  1689.        
  1690.         mov     ax, info_real_mode_size
  1691.         add     ax, 0x1000
  1692.  
  1693.  
  1694.         mov     gs, ax
  1695. .loop_size_root_dir:
  1696. DEBUG1 equ 0
  1697. if DEBUG1        
  1698.         pushad
  1699.         push    di
  1700.         mov     eax, dword[gs:di]
  1701.         lea     si, [check_root_fat_+14]
  1702.         mov     dword [ds:si], '----'
  1703.         mov     dword [ds:si+4], '----'
  1704.         mov     dword [ds:si+8], '----'
  1705.         mov     dword[ds:si], eax
  1706.         mov     eax, dword[gs:di+4]
  1707.         mov     dword[ds:si+4], eax
  1708.         mov     eax, dword[gs:di+8]
  1709.         mov     dword[ds:si+8], eax
  1710.  
  1711. ;
  1712.         xor     eax, eax
  1713.         mov     ax, gs;point_next_fat_str
  1714.         mov     cx, 0x0a
  1715.         mov     di, check_root_fat_
  1716.         mov     dword [di], '    '
  1717.         mov     word [di+4], '  '
  1718.         call    decode
  1719.         xor     eax, eax
  1720.         pop     ax
  1721.         mov     di, (check_root_fat_+7)
  1722.         mov     dword [di], '    '
  1723.         mov     word [di+4], '  '
  1724.         call    decode
  1725.  
  1726. ;Show size
  1727.         lea     si, [check_root_fat_]
  1728.         call    printplain
  1729.  
  1730.         lea     si, [shot_name_fat]
  1731.         call    printplain
  1732.  
  1733.         xor     ax, ax
  1734.         int     0x16
  1735.         popad
  1736. end if  
  1737.  
  1738.         xor     bx, bx
  1739.         mov     cx, 11  ;size of name in struct FAT
  1740.  
  1741. @@:    
  1742.         mov     al, byte [ds:si+bx]     ;ds:si - point to name of convertion variable.
  1743.         mov     ah, byte [gs:di+bx]     ;gs:di - point to name in fat struct
  1744.         inc     bx
  1745.  
  1746. if DEBUG
  1747. ;        pushad
  1748. ;        lea    si,[check_root_fat_+14]
  1749. ;        mov     dword [ds:si],'----'
  1750. ;        mov    word [ds:si],ax
  1751. ;       call    printplain
  1752.  
  1753. ;       xor     ax,ax
  1754. ;       int     0x16
  1755.  
  1756. ;        popad
  1757. end if
  1758.  
  1759.  
  1760.  
  1761.         cmp     ah, al
  1762.         jnz     .no_equal
  1763.  
  1764. ;       dec     cx
  1765. ;       jnz     @b
  1766.         loop    @b
  1767.  
  1768. ;.succesfuly:
  1769. ;печально, такое имя уже имеется :(
  1770.         or      ax, -1
  1771.         jmp     .exit
  1772.  
  1773.  
  1774. .no_equal:
  1775.         add     di, 32          ;fat struct =32 byte
  1776.         dec     dx
  1777.         jnz     .loop_size_root_dir
  1778.  
  1779. ;.exit_check_name:
  1780.         and     ax, 0
  1781.  
  1782. .exit:
  1783.  
  1784. if DEBUG        
  1785.         pushad
  1786. ;Show size
  1787.         lea     si, [check_name_fat_msg_n]
  1788.         test    ax, ax
  1789.         jz      @f
  1790.         lea     si, [check_name_fat_msg_y]
  1791.         call    printplain
  1792.         lea     si, [alarm_msg]
  1793. @@:
  1794.         call    printplain
  1795.         popad
  1796. end if  
  1797.  
  1798. }
  1799.  
  1800.  
  1801. macro convertion_file_name
  1802. ;макрос конвертации имени, это нужно поскольку формат представленный не соответсвует фат и напрямую редко можно когда использовать
  1803. ;преобразование имени типа hello.asm в 'HELLO   ASM', в соответствии с правилами fat.
  1804. ;входные параметры es:di указатель на имя файла которое нужно преобразовать, конечный буфер shot_name_fat
  1805. {
  1806. local   .next_step
  1807. local   .error
  1808. local   .st1
  1809. local   .st2
  1810. local   .st2_l
  1811. local   .st3
  1812. local   .st4_s
  1813. local   .st4
  1814. local   .st5
  1815.  
  1816. ;вычислим длинну строчки имени назначения, которую будем сравнивать с уже записанными данными.
  1817. ;       mov     di,point_to_dest_file_name   входной параметр
  1818.         mov     si, shot_name_fat
  1819.         or      first_input, -1 ;при первом входе устанавливаем флаг
  1820.         mov     cx, 11  ;длинна имени в стуктуре фат таблицы
  1821.  
  1822. @@:    
  1823.         mov     al, byte [es:di]
  1824.         cmp     al, 0xa
  1825.         jz      .st4_s
  1826.         cmp     al, 0xd
  1827.         jz      .st4_s
  1828.         cmp     al, 0x20
  1829.         jz      .st4_s
  1830.  
  1831.         cmp     al, 0x20
  1832.         jb      .error
  1833.         cmp     al, 0x22
  1834.         jz      .error
  1835.         cmp     al, 0x2a
  1836.         jz      .error
  1837.         cmp     al, 0x2b
  1838.         jz      .error
  1839.         cmp     al, 0x2c
  1840.         jz      .error
  1841.         cmp     al, 0x2F
  1842.         jz      .error
  1843.  
  1844.         cmp     al, 0x3a
  1845.         jz      .error
  1846.         cmp     al, 0x3b
  1847.         jz      .error
  1848.         cmp     al, 0x3c
  1849.         jz      .error
  1850.         cmp     al, 0x3d
  1851.         jz      .error
  1852.         cmp     al, 0x3E
  1853.         jz      .error
  1854.         cmp     al, 0x3F
  1855.         jz      .error
  1856.  
  1857.         cmp     al, 0x5b
  1858.         jz      .error
  1859.         cmp     al, 0x5c
  1860.         jz      .error
  1861.         cmp     al, 0x5d
  1862.         jz      .error
  1863.  
  1864.         cmp     al, 0x7c
  1865.         jz      .error
  1866.  
  1867.        
  1868.         cmp     first_input, -1
  1869.         jnz     .next_step
  1870.         and     first_input, 0  ;сборосим флаг.
  1871.         cmp     al, '.'
  1872.         jz      .error  ;обработка точки, файл не может начинаться с точки
  1873.  
  1874. .next_step:
  1875.         cmp     al, 0x2e
  1876.         jnz     .st2            ;обработка точки, в середине файла
  1877. ;тут у нас установлен разделитель
  1878. ;все остальнео место займут пробелы
  1879.         mov     al, ' '
  1880.  
  1881. ;!fixme обработаны не все исключения :(
  1882.         cmp     cl, 3   ;формат файла такой GIDGIDIIASM т.е. gidgidii.asm
  1883.         jbe     .st2
  1884.  
  1885.  
  1886. .st3:  
  1887.         mov     byte [si], al
  1888.         inc     si
  1889.         dec     cx
  1890.         cmp     cx, 3
  1891.         ja      .st3
  1892. ;       inc     cx
  1893.         inc     di
  1894.         jmp     @b
  1895.  
  1896. .st2:
  1897.         cmp     al, 0x60
  1898.         jbe     .st2_l
  1899.        
  1900.         xor     al, 0x20;сделаем заглавные буквы
  1901. .st2_l:
  1902.         mov     byte [si], al
  1903.         inc     di
  1904.         inc     si
  1905. ;        dec    cx
  1906. ;       jnz     @b
  1907.         loop    @b
  1908. .st5:
  1909.         xor     ax, ax
  1910.         jmp     @f
  1911.  
  1912. ;;;;;;;;файл закончился, и нужно внести в конец пробелы
  1913. .st4_s:
  1914.         mov     al, ' '
  1915. .st4:
  1916.         mov     byte [si], al
  1917.         inc     si
  1918.         loop    .st4
  1919.         jmp     .st5
  1920.  
  1921. .error:
  1922.         or      ax, -1
  1923. @@:
  1924.  
  1925. if DEBUG        
  1926.         pushad
  1927.        
  1928.         mov     si, convertion_file_name_msg_y
  1929.         test    ax, ax
  1930.         jz      @f
  1931.         mov     si, convertion_file_name_msg_n
  1932. @@:
  1933.         call    printplain
  1934.  
  1935.         mov     si, shot_name_fat
  1936.         mov     byte [si+12], 0
  1937.         call    printplain
  1938.         popad
  1939.  
  1940. end if  
  1941. }
  1942.  
  1943. macro move_file_up
  1944. ;макрос который перемещает за 1 мб с правилами фат данные файла.
  1945. {
  1946. local   .st1
  1947. local   .correct_on_byte
  1948. ;сейчас имеет быть ситуация, когда BPB уже перемещен за 1 мб, фат, и рут дир будут позже перемещены,
  1949. ;а нам нужно вычислить место, и перенести туда содержимое файла
  1950. ;полученое значение указывает в байтах на начало данных
  1951.  
  1952.         mov     ax, info_real_mode_size ; сегмент где расположены данные
  1953.         mov     si, table_15_87
  1954.         mov     word [si+8*2+2], ax
  1955. ;смещение до данных уже за 1-м мб
  1956.         movzx   eax, firstDataSect
  1957.         movzx   edx, data_offset
  1958.         add     eax, edx
  1959.  
  1960.         movzx   ebx, word [fat12_buffer.BPB_BytsPerSec]
  1961.         movzx   edx, byte [fat12_buffer.BPB_SecPerClus]
  1962.         imul    bx, dx  ;получим размер кластера
  1963.  
  1964.  
  1965.  
  1966.         push    ebx     ;save bx
  1967.  
  1968.         imul    eax, ebx
  1969. ;       shl     eax,9   ;умножим на 512
  1970.        
  1971. if DEBUG
  1972.         pushad
  1973.         xor     eax, eax
  1974.         mov     ax, info_real_mode_size
  1975.         mov     cx, 0x0a
  1976.         mov     di, seg_where_get_data
  1977.         mov     dword [di], '    '
  1978.         mov     word [di+4], '  '
  1979.         call    decode
  1980. ;Show size
  1981.         mov     si, seg_where_get_data
  1982.         call    printplain
  1983.         popad
  1984.  
  1985. end if
  1986.  
  1987. ;       mov     bx,word [fat12_buffer.BPB_BytsPerSec]
  1988. ;       movzx   dx,byte [fat12_buffer.BPB_SecPerClus]
  1989. ;       imul    bx,dx
  1990. ;       cwd
  1991. ;       idiv    bx
  1992.  
  1993.         mov     dl, 0x10
  1994.  
  1995. @@:
  1996.         cmp     eax, 0x00010000
  1997.         jb      @f
  1998.  
  1999.         sub     eax, 0x00010000
  2000.         inc     dl
  2001.         jmp     @b
  2002.  
  2003.  
  2004. @@:
  2005.         mov     byte [si+8*3+3], dl     ;куда писать
  2006.         mov     word [si+8*3+2], ax
  2007.  
  2008.         mov     ecx, save_file_size     ;размер файла в байтах.
  2009.         cmp     ecx, 0x0000ffff         ;размер блока т.е. 64 кб
  2010.         jbe     .correct_on_byte        ;корректировка на байт значения
  2011.  
  2012.  
  2013.  
  2014.         mov     ecx, 0x00010000         ;65536
  2015.         sub     save_file_size, ecx     ;отнимим
  2016. ;       jmp     .st1                    ;получим 0х8000
  2017.  
  2018.  
  2019.  
  2020.  
  2021. ;корректировка значения должна быть выполенена на размер кластера
  2022. .correct_on_byte:
  2023. ;/узнаем размер кластера
  2024.         pop     eax     ;restore size of claster
  2025.         push    ecx
  2026. @@:
  2027.         inc     data_offset
  2028.  
  2029.         cmp     eax, ecx
  2030.         jae     @f
  2031.         sub     ecx, eax
  2032.         jmp     @b
  2033. @@:
  2034.         pop     ecx
  2035.  
  2036.  
  2037.  
  2038.  
  2039.         test    ecx, 0x1
  2040.         jz      .st1
  2041.         inc     ecx
  2042. .st1:
  2043.         shr     ecx, 1    ; преобразовать значение для 0x87 function
  2044.  
  2045. ;перенесем блок за 1 мб        
  2046.         push    es
  2047.         push    ds
  2048.         pop     es
  2049.  
  2050.         mov     ah, 0x87
  2051.         int     0x15
  2052.         pop     es
  2053.  
  2054. if DEBUG
  2055.         pusha
  2056. ;       mov     ax,point_next_fat_str
  2057.         mov     cx, 0x0a
  2058.         mov     di, return_code_af_move
  2059.         call    decode
  2060. ;Show size
  2061.         mov     si, return_code_af_move
  2062.         call    printplain
  2063.         popa
  2064.  
  2065. end if
  2066.  
  2067. }
  2068.  
  2069.  
  2070. macro move_up_fat_and_root_d
  2071. ;макрос, который позволяет перенести выше 1 мб в структуру образа фат таблицу и рут директорию
  2072. {
  2073. local  .st1
  2074.  
  2075.         mov     ax, info_real_mode_size
  2076.         add     ax, 0x1000
  2077.  
  2078.         mov     si, table_15_87
  2079.         mov     word [si+8*2+2], ax
  2080. ;смещение до данных
  2081.         mov     ax, 512
  2082.         mov     word [si+8*3+2], ax
  2083. ;fixme! тут необходимо сделать подержку т.е. формировать смещение файла в уже записанных данных.
  2084.  
  2085.         movzx   ecx, word [fat12_buffer.BPB_FATSz16]
  2086.         movzx   bx, byte [fat12_buffer.BPB_NumFATs]
  2087.         imul    cx, bx  ;9x1=9
  2088.  
  2089.         add     cx, size_root_dir       ;размер корневой дирректории
  2090.         shl     ecx, 9  ;imul 512
  2091.  
  2092.  
  2093. ;корректировка значения
  2094.         test    ecx, 0x1
  2095.         jz      .st1
  2096.         inc     ecx
  2097. .st1:
  2098.         shr     ecx, 1
  2099.  
  2100.         push    es
  2101.         push    ds
  2102.         pop     es
  2103.  
  2104.         mov     ah, 0x87
  2105.         int     0x15
  2106.         pop     es
  2107.  
  2108. if DEBUG
  2109.         pusha
  2110. ;       mov     ax,point_next_fat_str
  2111.         mov     cx, 0x0a
  2112.         mov     di, return_code_af_fat_m
  2113.         call    decode
  2114. ;Show size
  2115.         mov     si, return_code_af_fat_m
  2116.         call    printplain
  2117.         popa
  2118.  
  2119. end if
  2120.  
  2121. }
  2122.