Subversion Repositories Kolibri OS

Rev

Rev 1151 | Rev 1231 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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