Subversion Repositories Kolibri OS

Rev

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