Subversion Repositories Kolibri OS

Rev

Rev 1065 | Rev 1156 | 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
 
1091
;//проверка наличия такого же имени в рут дир
1092
 
1151 Lrz 1093
@@:     mov     al,byte [es:di]
1094
        cmp     al,','          ; т.е. ищем разделитель
1095
        jz      .found_end_str
1096
        inc     di
1097
        dec     cx
1098
        jnz     @b
1065 Lrz 1099
;;;not found допустим,что это конец файла и он не имеет привычного завершения строки
1100
.found_end_str:
1151 Lrz 1101
;        mov    al,byte [es:di]
1102
;       cmp     al,' '          ; убираем пробелы, если они есть
1103
;       jnz     @f
1104
;       inc     di
1105
;       dec     cx
1106
;       jnz     .found_end_str
1065 Lrz 1107
 
1108
;@@:
1151 Lrz 1109
        mov     point_to_dest_file_name,di
1110
        inc     di
1065 Lrz 1111
;проверка индивидуальности имени файла
1112
check_name_file
1113
;/restore di - point and cx -size section
1151 Lrz 1114
        mov     di,save_di_RAMDISK
1115
        mov     cx,save_cx_RAMDISK
1065 Lrz 1116
 
1151 Lrz 1117
        test    al,al
1118
        jnz     .start_loop     ;если в al значение не =0, то такое имя уже существует в системе.
1065 Lrz 1119
 
1120
 
1121
 
1151 Lrz 1122
        push    dword [es:di-6]
1123
        lea     si,[di-6]
1065 Lrz 1124
 
1151 Lrz 1125
        push    word  [es:di-2]
1126
        push    di
1127
        xor     ax,ax
1128
        mov     word [es:di-6],ax       ;вносим нужные значения
1065 Lrz 1129
;info_real_mode_size размер и указатель на область в которую можно загрузиться
1151 Lrz 1130
        mov     ax,info_real_mode_size  ;0x3000   ;следующий сегмент за данными
1065 Lrz 1131
 
1132
 
1151 Lrz 1133
        mov     word [es:di-4],ax
1134
        mov     word [es:di-2],16       ;кол-во блоков по 4 кб =64 кб т.е. больше не читаем
1065 Lrz 1135
 
1151 Lrz 1136
        mov     di,point_to_dest_file_name
1065 Lrz 1137
 
1151 Lrz 1138
        push    word [es:di]
1139
        push    cx
1140
        xor     ax,ax
1141
        mov     word [es:di],ax
1065 Lrz 1142
;        xor     ax,ax   ; function 1 - read file
1151 Lrz 1143
        push    di
1144
        mov     di,si   ;file_data
1145
        inc     ax
1146
        push    si
1147
        push    es
1148
        push    bp
1065 Lrz 1149
 
1151 Lrz 1150
        push    es
1151
        pop     ds
1152
        push    cs
1153
        pop     es
1065 Lrz 1154
 
1155
        call    far  dword [es:loader_callback]
1156
 
1157
 
1158
        push    cs
1159
        pop     ds
1160
 
1151 Lrz 1161
        pop     bp
1162
        pop     es
1163
        pop     si
1065 Lrz 1164
 
1165
        cmp    bx,2
1166
        ja     .error
1167
; сейчас у нас в dx:ax размер файла, который мы загрузили.
1168
; возможна ситуация, когда в bx=1 т.е. есть еще данные на диске
1151 Lrz 1169
        mov     status_flag_loader_f,bx
1065 Lrz 1170
 
1151 Lrz 1171
        shl     edx,16
1172
        mov     dx,ax
1173
;       shr     edx,10  ;размер файла в кб.
1174
;;в edx размер в байтах.
1175
        mov     save_file_size,edx
1176
        mov     eax,edx
1065 Lrz 1177
;восстановим полностью файл сценария
1151 Lrz 1178
        pop     di
1179
        pop     cx      ;длинна остатка с 2-ой частью имени т.е. с именем назначением.
1180
        pop     word [es:di]
1181
        pop     di
1182
        pop     word  [es:di-2]
1183
        pop     dword [es:di-6]
1184
 
1065 Lrz 1185
 
1186
if DEBUG
1187
        pusha
1188
        mov     cx,0x0a
1189
        mov     di,RamdiskFile_msg
1190
        mov     dword[ds:di],'    '
1191
        call    decode
1192
;Show size
1193
        mov     si,RamdiskFile_msg
1194
        call    printplain
1195
 
1196
        popa
1197
end if
1198
 
1199
 
1200
 
1201
 
1202
 
1203
 
1204
 
1205
 
1206
 
1207
 
1208
; загрузим чему у нас равен кластер
1151 Lrz 1209
;       mov     ax,word [fat12_buffer.BPB_BytsPerSec] ;кол-во байтов в секторе может быть любое 512 1024 2048 4096 2 байта
1210
;       movzx   bx,byte [fat12_buffer.BPB_SecPerClus] ;кол-во секторов в кластере
1211
;       imul    ax,bx
1065 Lrz 1212
;сейчас в eax размер кластера (512) байт
1151 Lrz 1213
;в edx длина файла в байтах до 64 кб
1065 Lrz 1214
;закиним файл за 1 мб
1215
;1 нам нужно составить фат таблицу т.е. произвести разметку рамдиска, затем перенесем по адресу файл
1216
 
1217
;записать инфорамацию о файле в корневую директорию
1218
register_file_in_fat
1219
;перенести за 1 мб содержимое файла
1220
move_file_up
1221
 
1222
;проверим, загружен ли до конца файл? т.е. если размер файла больше чем 64 кб, то будет подгружать оставшиеся блоки
1151 Lrz 1223
        cmp     status_flag_loader_f,0x1
1224
        jnz     @f
1225
;нужно дозагузить данные файла и перенести их за 1-ый мб согласно фат структуре
1065 Lrz 1226
 
1227
 
1228
 
1229
 
1230
 
1231
 
1232
 
1233
 
1234
 
1235
@@:
1236
;тут организован цикл по загрузке файлов в корневую директорию
1151 Lrz 1237
        mov     di,save_di_RAMDISK
1238
        mov     cx,save_cx_RAMDISK
1065 Lrz 1239
if DEBUG
1240
        pusha
1151 Lrz 1241
        xor     ax,ax
1242
        int     0x16
1065 Lrz 1243
        popa
1244
end if
1245
 
1246
 
1151 Lrz 1247
        jmp     .start_loop
1065 Lrz 1248
 
1249
 
1250
.error:
1151 Lrz 1251
        ;call   error.LoaderModule
1065 Lrz 1252
;fixme!
1253
.rest_value_loop:
1151 Lrz 1254
        mov     di,ax
1255
        mov     cx,bx
1256
        jmp     .start_loop
1065 Lrz 1257
 
1258
._end:
1259
;перенесем за 1-ый мб фат и рут дир
1260
move_up_fat_and_root_d
1261
 
1262
 
1263
 
1264
 
1265
 
1266
 
1267
;загрузка блока
1151 Lrz 1268
;       mov     ah,0x87
1269
;       mov     cx,     ;size in byte
1270
 
1065 Lrz 1271
 
1272
;es:si point to descripts
1273
 
1274
 
1275
}
1276
 
1277
macro use_BPB_RAM
1278
;данный макрос закидывает BPB структуру, пока только фат12 за 1 мб
1279
{
1151 Lrz 1280
        mov     ax,fat12_buffer
1065 Lrz 1281
        mov     si,table_15_87
1151 Lrz 1282
        add     word [si+8*2+2],ax
1065 Lrz 1283
        push    es
1284
        push    ds
1285
        pop     es
1151 Lrz 1286
        mov     cx,31   ;фат12 укладывается в 62 байта 62/2=31
1065 Lrz 1287
        mov     ah, 0x87
1288
        int     0x15
1289
        pop     es
1290
;add 512 byte for destination adress
1151 Lrz 1291
;       add     dword [si+8*3+2], 512
1065 Lrz 1292
;        test    ah, ah
1151 Lrz 1293
;        jz
1065 Lrz 1294
if DEBUG
1295
        pusha
1151 Lrz 1296
        mov     ax,word [si+8*2+2]
1065 Lrz 1297
        mov     cx,0x0a
1298
        mov     di,BPB_msg
1299
        call    decode
1300
;Show size
1301
        mov     si,BPB_msg
1302
        call    printplain
1303
        popa
1304
end if
1305
}
1306
macro first_create_fat_table
1307
;данный макрос создает оформляет 3 первых байта fat таблицы, и устанавливает указатель на следующий блок, и вносит 0 значение
1308
;для смещения в корневой таблице.
1309
{
1151 Lrz 1310
        mov     al,byte [fat12_buffer.BPB_Media]
1065 Lrz 1311
 
1312
 
1151 Lrz 1313
        push    ds
1065 Lrz 1314
 
1315
 
1151 Lrz 1316
        mov     di,info_real_mode_size
1317
        add     di,0x1000
1318
        push    di   ;  push    word info_real_mode_size+0x1000   ;cледующий сегмент за загруженным участком
1319
 
1320
        xor     di,di
1321
        mov     point_to_free_root,di   ;значение смещения =0 в корневой фат таблице описания
1065 Lrz 1322
 
1323
 
1151 Lrz 1324
        pop     ds   ; загружен следующий сегмент т.е. пустой сегмент
1065 Lrz 1325
 
1151 Lrz 1326
        mov     byte [di],al
1327
        or      ax,-1
1328
        inc     di
1329
        mov     word [di],ax
1065 Lrz 1330
 
1331
 
1332
 
1151 Lrz 1333
        pop     ds
1334
        mov     point_next_fat_str,3
1065 Lrz 1335
 
1336
if DEBUG
1151 Lrz 1337
        pushad
1338
        mov     ax,point_next_fat_str
1065 Lrz 1339
        mov     cx,0x0a
1340
        mov     di,fat_create_msg
1341
        call    decode
1342
;Show size
1343
        mov     si,fat_create_msg
1344
        call    printplain
1151 Lrz 1345
        popad
1065 Lrz 1346
end if
1347
 
1348
}
1349
macro register_file_in_fat
1350
;макрос регистрации файла в файловой структуре Fat
1351
;пока поддерживается только фат12, пока ))
1352
;вычисление смежных кластеров и занесение инфы в fat/
1353
{
1151 Lrz 1354
local   .step2
1355
local   .step3
1356
local   .end
1065 Lrz 1357
local   .eof_file
1358
 
1359
;di point on root dir на фри секцию.
1151 Lrz 1360
        push    es
1065 Lrz 1361
 
1151 Lrz 1362
        mov     ax,info_real_mode_size
1363
        add     ax,0x1000
1364
        mov     es,ax  ;        push    word info_real_mode_size+0x1000   ;сегмент следующий за загруженным блоком в 64 кб
1065 Lrz 1365
 
1366
; определяем тип фат пока не определяем, пока только фат 12
1367
; 12 бит, для вычесления соседних каластеров.
1151 Lrz 1368
        mov     di,firstDataSect     ;в секторах
1369
        sub     di,size_root_dir
1065 Lrz 1370
;теперь в ax размер в секторах начала рут дир
1151 Lrz 1371
        shl     di,9 ;imul 512
1372
        add     di,point_to_free_root   ;смещение в уже записанных 32-х структурах.
1065 Lrz 1373
;необходимо внести значение в рут дир т.е. 32 байта
1374
;gs:di - указатель для внесения инфорации в рут область фат таблицы инормации о файле.
1151 Lrz 1375
        mov     si,shot_name_fat
1376
        mov     cx,11
1065 Lrz 1377
;запишем в структуру имя
1151 Lrz 1378
@@:     lodsb
1379
        stosb
1380
        loop    @b
1065 Lrz 1381
 
1382
;запишем атрибуты файла и DIR_NTRes - зарезеврированный байт =0
1151 Lrz 1383
        xor     ax,ax
1384
        mov     ah,ATTR_VOLUME_ID
1385
        mov     word [es:di],ax
1386
        add     di,2
1065 Lrz 1387
;DIR_CrtTimeTenth
1151 Lrz 1388
        mov     byte [es:di],100
1389
        inc     di
1065 Lrz 1390
;DIR_CrtTime
1151 Lrz 1391
        mov     word [es:di],0x032b    ;дата
1392
        add     di,2
1065 Lrz 1393
;DIR_CrtDate
1151 Lrz 1394
        mov     word [es:di],0x0       ;время ><
1395
        add     di,2
1065 Lrz 1396
;DIR_LstAccDate
1151 Lrz 1397
        mov     word [es:di],0x032b    ;дата моего
1398
        add     di,2
1065 Lrz 1399
;DIR_FstClusHI
1151 Lrz 1400
        mov     word [es:di],0x0       ;время для фат12 /16 всегда 0
1401
        add     di,2
1065 Lrz 1402
;DIR_WrtTime
1151 Lrz 1403
        mov     word [es:di],0x0       ;время ><
1404
        add     di,2
1065 Lrz 1405
;DIR_WrtDate
1151 Lrz 1406
        mov     word [es:di],0x032b
1407
        add     di,2
1408
 
1409
        mov     ax,point_next_fat_str
1410
        mov     word [es:di],ax
1411
        add     di,2
1065 Lrz 1412
 
1151 Lrz 1413
        push    di
1414
;DIR_FstClusLO                  Младшее слово номера первого кластера.
1415
;       mov     ax,point_next_fat_str   ;загрузим указатель на элемент фат таблицы т.е. это номер фат записи
1065 Lrz 1416
;FATOffset = N + (N / 2) т.е. это уже у нас смещение мы знаем что -начинается все с 3-го элемента записи фат
1151 Lrz 1417
        mov     bx,ax
1418
        shr     bx,1
1419
        add     ax,bx
1065 Lrz 1420
;в ах сейчас FATOffset
1421
;ThisFATEntOffset = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec);
1151 Lrz 1422
        mov     bx, word [fat12_buffer.BPB_BytsPerSec]
1423
        cwd
1424
        idiv    bx
1065 Lrz 1425
;ax=ThisFATEntOffset= rem (FATOffset / BPB_BytsPerSec) четный или нечетный указатель.
1151 Lrz 1426
        mov     si,ax
1065 Lrz 1427
;нам нужно в цикле записать все кластеры которые будут использованы для размещения файла.
1428
;узнаем размер кластера.
1151 Lrz 1429
        movzx   eax,word [fat12_buffer.BPB_BytsPerSec]
1430
        movzx   ebx,byte [fat12_buffer.BPB_SecPerClus]
1431
        imul    eax,ebx
1065 Lrz 1432
;ax - размер кластера.
1433
;сейчас будем записывать во временный буфер фат таблицу для выбранного файла. Поскольку мы его загрузили возможно не полностью
1151 Lrz 1434
;мы обработаем запись для фат полностью, в не зависимости от предела буфера где возможна часть файла.
1435
        mov     ebx,save_file_size      ;размер файла в байтах
1436
 
1437
@@:     sub     ebx,eax
1438
        cmp     ebx,eax
1439
        jbe     .eof_file
1065 Lrz 1440
 
1151 Lrz 1441
        inc     point_next_fat_str
1442
        mov     cx,point_next_fat_str   ;загрузим указатель на элемент фат таблицы т.е. это номер фат записи
1065 Lrz 1443
;FATOffset = N + (N / 2) т.е. это уже у нас смещение мы знаем что -начинается все с 3-го элемента записи фат
1151 Lrz 1444
        mov     dx,ax
1445
        shr     dx,1
1446
        add     cx,dx
1065 Lrz 1447
 
1448
 
1449
 
1151 Lrz 1450
        test    si,0x1
1451
        jz      .step2
1452
        shl     cx,4
1453
        mov     word[es:si],cx
1454
        inc     si
1455
        add     cx,ax
1456
        jmp     @b
1065 Lrz 1457
 
1151 Lrz 1458
.step2: and     cx,0x0FFF
1459
        mov     word[es:si],cx
1460
        inc     si
1461
        add     cx,ax
1462
        jmp     @b
1065 Lrz 1463
 
1464
.eof_file:
1151 Lrz 1465
        mov     cx,0x0fff
1466
        test    si,0x1
1467
        jz      .step3
1468
        shl     cx,4
1469
        mov     word[es:si],cx
1470
        jmp     .end
1065 Lrz 1471
 
1151 Lrz 1472
.step3: and     cx,0x0FFF
1473
        mov     word[es:si],cx
1065 Lrz 1474
 
1151 Lrz 1475
.end:   inc     point_next_fat_str
1065 Lrz 1476
 
1151 Lrz 1477
        pop     di
1065 Lrz 1478
;DIR_FileSize 32-битный DWORD содержит размер файла в байтах.
1151 Lrz 1479
        mov     eax,save_file_size
1480
        mov     dword [es:di],eax
1065 Lrz 1481
 
1482
if DEBUG
1483
        pushad
1484
 
1151 Lrz 1485
        mov     di,firstDataSect     ;в секторах
1486
        sub     di,size_root_dir
1065 Lrz 1487
;теперь в ax размер в секторах начала рут дир
1151 Lrz 1488
        shl     di,9 ;imul 512
1489
        add     di,point_to_free_root   ;смещение в уже записанных 32-х структурах.
1065 Lrz 1490
 
1151 Lrz 1491
        mov     si,dest_name_fat
1492
        mov     cx,11
1065 Lrz 1493
;запишем в структуру имя
1151 Lrz 1494
@@:     mov     al,byte [es:di]
1495
        inc     di
1496
        mov     byte [ds:si],al
1497
        inc     si
1498
        loop    @b
1499
 
1500
        xor     ax,ax
1501
        mov     byte [si],al
1502
        mov     si,dest_name_fat
1065 Lrz 1503
        call    printplain
1151 Lrz 1504
        popad
1065 Lrz 1505
 
1506
END IF
1507
 
1508
 
1509
 
1510
 
1511
 
1151 Lrz 1512
        add     point_to_free_root,32   ;увелицим смещение до следующего значения.
1513
        pop     es
1065 Lrz 1514
 
1515
}
1516
 
1517
 
1518
 
1519
 
1520
 
1521
macro get_firstDataSector
1522
;макрос для вычисления певого сектора данных т.е. данных файлов в фате
1523
;вычислим FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors;
1524
{
1151 Lrz 1525
        mov     ax,word [fat12_buffer.BPB_FATSz16]
1526
        movzx   bx,byte [fat12_buffer.BPB_NumFATs]
1527
        imul    ax,bx   ;9x1=9
1065 Lrz 1528
;ax=BPB_NumFATs * FATSz
1151 Lrz 1529
        mov     bx,word [fat12_buffer.BPB_RootEntCnt]   ; count of 32-byte dir. entries (224*32 = 14 sectors= 7 kb)
1530
        shr     bx,4    ;imul bx,32 and then div 512 -> in bx size in sectors
1531
        add     ax,bx   ;9+14=23
1532
        mov     size_root_dir,bx
1533
        movzx   bx,byte [fat12_buffer.BPB_RsvdSecCnt]   ;add 1 for fat 16/12
1534
        add     ax,bx
1065 Lrz 1535
;ax=firstDataSector - где начинается первый секторо от 0 сектора в секторах. - фактически = 24 сектор
1151 Lrz 1536
        mov     firstDataSect,ax        ;сохраним для вычисления
1537
;       получимзначение кластеров, это объем в который мы можем записать данные
1538
        mov     bx,word [fat12_buffer.BPB_TotSec16]
1539
        sub     bx,ax
1540
        mov     ax,bx
1541
        movzx   bx,byte [fat12_buffer.BPB_SecPerClus]
1542
        cwd
1543
        idiv    bx
1544
        mov     DataClasters,ax
1065 Lrz 1545
 
1546
if DEBUG
1151 Lrz 1547
        pushad
1548
        mov     ax,firstDataSect        ;первый сектор данных
1065 Lrz 1549
        mov     cx,0x0a
1550
        mov     di,firstDataSect_msg
1551
        call    decode
1552
;Show size
1553
        mov     si,firstDataSect_msg
1554
        call    printplain
1555
;;;;;;;;;;;;;;;;;;;;;;;;;;
1151 Lrz 1556
        mov     ax,size_root_dir        ;размер рут дир в сетокторах
1065 Lrz 1557
        mov     cx,0x0a
1558
        mov     di,size_root_dir_msg
1559
        call    decode
1560
;Show size
1561
        mov     si,size_root_dir_msg
1562
        call    printplain
1563
;;;;;;;;;;;;;;;;;;;;;;;;;;
1151 Lrz 1564
        mov     ax,DataClasters ;кластеры
1065 Lrz 1565
        mov     cx,0x0a
1566
        mov     di,DataClasters_msg
1567
        call    decode
1568
;Show size
1569
        mov     si,DataClasters_msg
1570
        call    printplain
1151 Lrz 1571
        popad
1065 Lrz 1572
 
1573
end if
1574
 
1575
}
1576
 
1577
macro use_RamdiskPATHS
1578
;парсинг пути источника файлов.
1579
{
1580
 
1581
}
1582
 
1583
macro use_RamdiskPATHD
1584
;парсинг пути назначения файлов.
1585
{
1586
 
1587
}
1588
macro check_name_file
1589
;макрос проверки имени на повтор, имя должно быть уникальным.
1590
;входные данные: es- сегмент где лежит файл для парсинга т.е. startos.ini
1591
;di - указатель на имя файла т.е. es:di указывает на имя файла назначения
1592
;выходные данные eax =-1 имя совпало, eax=0 имя не совпало.
1593
{
1151 Lrz 1594
local   .no_equal
1595
local   .exit
1065 Lrz 1596
;вычислим длинну строчки имени назначения, которую будем сравнивать с уже записанными данными.
1597
;преобразуем в аналог фат записи сточку с именем назначения
1151 Lrz 1598
        convertion_file_name
1599
        test    ax,ax
1600
        jnz     .exit
1065 Lrz 1601
 
1151 Lrz 1602
        mov     si,shot_name_fat
1065 Lrz 1603
 
1604
;вычислим указатель на корневую директорию
1151 Lrz 1605
        mov     di,firstDataSect
1606
        sub     di,size_root_dir
1065 Lrz 1607
;теперь в ax размер в секторах начала рут дир
1608
 
1609
 
1151 Lrz 1610
        shl     di,9 ;imul 512
1065 Lrz 1611
 
1612
 
1613
 
1614
 
1615
;di= Это смещение от начала буфера до рут директории.
1616
;загрузим значение - т.е. кол-во элементов, которые мы можем просматривать.
1151 Lrz 1617
        mov     dx,root_dir_entry_count
1065 Lrz 1618
;        mov     si,point_to_dest_file_name
1151 Lrz 1619
 
1620
        mov     ax,info_real_mode_size
1621
        add     ax,0x1000
1065 Lrz 1622
 
1623
 
1151 Lrz 1624
        mov     gs,ax
1625
        mov     cx,11   ;size of name in struct FAT
1065 Lrz 1626
 
1151 Lrz 1627
@@:
1628
        mov     al,byte [ds:si+bx]
1629
        mov     ah,byte [gs:di+bx]      ;gs:di - point to name in fat struct
1065 Lrz 1630
 
1151 Lrz 1631
if DEBUG
1632
        pushad
1065 Lrz 1633
 
1151 Lrz 1634
 
1635
        mov     cx,11
1636
;input cx=size al=char будет выведен символ сколько раз указано в cx
1637
@@:
1638
        mov     al,byte [gs:di]
1639
        inc     di
1640
        call    putchar
1641
        loop    @b
1642
 
1643
        xor     ax,ax
1644
        int     0x16
1645
 
1646
 
1647
        popad
1648
end if
1649
        inc     bx
1650
 
1651
        cmp     ah,al
1652
        jnz     .no_equal
1653
 
1654
;       dec     cx
1655
;       jnz     @b
1656
        loop    @b
1065 Lrz 1657
;.succesfuly:
1658
;печально, такое имя уже имеется :(
1151 Lrz 1659
        or      ax,-1
1660
        jmp     .exit
1065 Lrz 1661
 
1662
 
1663
.no_equal:
1151 Lrz 1664
        mov     cx,11;save_cx_check_name
1665
        xor     bx,bx
1666
        add     di,32           ;fat struct =32 byte
1667
        dec     dx
1668
        jnz     @b
1065 Lrz 1669
 
1670
;.exit_check_name:
1151 Lrz 1671
        and     ax,0
1065 Lrz 1672
 
1673
.exit:
1674
 
1675
if DEBUG
1676
        pusha
1151 Lrz 1677
;       movzx   eax,ax;point_next_fat_str
1065 Lrz 1678
        mov     cx,0x0a
1679
        mov     di,check_name_fat_msg
1151 Lrz 1680
        mov     dword [di],'    '
1681
        mov     word  [di+4],'  '
1065 Lrz 1682
        call    decode
1683
;Show size
1684
        mov     si,check_name_fat_msg
1685
        call    printplain
1686
        popa
1687
end if
1688
 
1689
}
1690
 
1691
 
1692
macro convertion_file_name
1693
;макрос конвертации имени, это нужно поскольку формат представленный не соответсвует фат и напрямую редко можно когда использовать
1694
;преобразование имени типа hello.asm в 'HELLO   ASM', в соответствии с правилами fat.
1151 Lrz 1695
;входные параметры es:di указатель на имя файла которое нужно преобразовать, конечный буфер shot_name_fat
1065 Lrz 1696
{
1151 Lrz 1697
local   .next_step
1065 Lrz 1698
local   .error
1699
local   .st1
1700
local   .st2
1151 Lrz 1701
local   .st2_l
1702
local   .st3
1703
local   .st4_s
1704
local   .st4
1705
local   .st5
1065 Lrz 1706
 
1707
;вычислим длинну строчки имени назначения, которую будем сравнивать с уже записанными данными.
1151 Lrz 1708
;       mov     di,point_to_dest_file_name   входной параметр
1709
        mov     si,shot_name_fat
1710
        or      first_input,-1  ;при первом входе устанавливаем флаг
1711
        mov     cx,11   ;длинна имени в стуктуре фат таблицы
1065 Lrz 1712
 
1151 Lrz 1713
@@:
1714
        mov     al,byte [es:di]
1715
        cmp     al,0xa
1716
        jz      .st4_s
1717
        cmp     al,0xd
1718
        jz      .st4_s
1719
        cmp     al,0x20
1720
        jz      .st4_s
1065 Lrz 1721
 
1151 Lrz 1722
        cmp     al,0x20
1723
        jb      .error
1724
        cmp     al,0x22
1725
        jz      .error
1726
        cmp     al,0x2a
1727
        jz      .error
1728
        cmp     al,0x2b
1729
        jz      .error
1730
        cmp     al,0x2c
1731
        jz      .error
1732
        cmp     al,0x2F
1733
        jz      .error
1065 Lrz 1734
 
1151 Lrz 1735
        cmp     al,0x3a
1736
        jz      .error
1737
        cmp     al,0x3b
1738
        jz      .error
1739
        cmp     al,0x3c
1740
        jz      .error
1741
        cmp     al,0x3d
1742
        jz      .error
1743
        cmp     al,0x3E
1744
        jz      .error
1745
        cmp     al,0x3F
1746
        jz      .error
1065 Lrz 1747
 
1151 Lrz 1748
        cmp     al,0x5b
1749
        jz      .error
1750
        cmp     al,0x5c
1751
        jz      .error
1752
        cmp     al,0x5d
1753
        jz      .error
1065 Lrz 1754
 
1151 Lrz 1755
        cmp     al,0x7c
1756
        jz      .error
1065 Lrz 1757
 
1151 Lrz 1758
 
1759
        cmp     first_input,-1
1760
        jnz     .next_step
1761
        and     first_input,0   ;сборосим флаг.
1762
        cmp     al,'.'
1763
        jz      .error  ;обработка точки, файл не может начинаться с точки
1065 Lrz 1764
 
1765
.next_step:
1151 Lrz 1766
        cmp     al,0x2e
1767
        jnz     .st2            ;обработка точки, в середине файла
1065 Lrz 1768
;тут у нас установлен разделитель
1769
;все остальнео место займут пробелы
1151 Lrz 1770
        mov     al,' '
1065 Lrz 1771
 
1772
;!fixme обработаны не все исключения :(
1151 Lrz 1773
        cmp     cl,3    ;формат файла такой GIDGIDIIASM т.е. gidgidii.asm
1774
        jbe     .st2
1065 Lrz 1775
 
1776
 
1151 Lrz 1777
.st3:
1778
        mov     byte [si],al
1779
        inc     si
1780
        dec     cx
1781
        cmp     cx,3
1782
        ja      .st3
1783
;       inc     cx
1784
        inc     di
1785
        jmp     @b
1065 Lrz 1786
 
1787
.st2:
1151 Lrz 1788
        cmp     al,0x60
1789
        jbe     .st2_l
1790
 
1791
        xor     al,0x20 ;сделаем заглавные буквы
1792
.st2_l: mov     byte [si],al
1793
        inc     di
1794
        inc     si
1795
;        dec    cx
1796
;       jnz     @b
1797
        loop    @b
1798
.st5:   xor     ax,ax
1799
        jmp     @f
1065 Lrz 1800
 
1801
;;;;;;;;файл закончился, и нужно внести в конец пробелы
1151 Lrz 1802
.st4_s: mov     al,' '
1803
.st4:   mov     byte [si],al
1804
        inc     si
1805
        loop    .st4
1806
        jmp     .st5
1065 Lrz 1807
 
1151 Lrz 1808
.error: or      ax,-1
1065 Lrz 1809
@@:
1810
 
1811
if DEBUG
1812
        pusha
1151 Lrz 1813
;       mov     ax,point_next_fat_str
1065 Lrz 1814
        mov     cx,0x0a
1815
        mov     di,convertion_file_name_msg
1816
        call    decode
1817
;Show size
1818
        mov     si,convertion_file_name_msg
1819
        call    printplain
1820
 
1151 Lrz 1821
        mov     si,shot_name_fat
1822
        mov     byte [si+12],0
1823
        call    printplain
1065 Lrz 1824
        popa
1825
 
1826
end if
1827
}
1828
 
1829
macro move_file_up
1830
;макрос который перемещает за 1 мб с правилами фат данные файла.
1831
{
1151 Lrz 1832
local   .st1
1833
local   .correct_on_byte
1065 Lrz 1834
;сейчас имеет быть ситуация, когда BPB уже перемещен за 1 мб, фат, и рут дир будут позже перемещены,
1835
;а нам нужно вычислить место, и перенести туда содержимое файла
1836
;полученое значение указывает в байтах на начало данных
1837
 
1151 Lrz 1838
        mov     ax,info_real_mode_size  ; сегмент где расположены данные
1065 Lrz 1839
        mov     si,table_15_87
1151 Lrz 1840
        mov     word [si+8*2+2],ax
1065 Lrz 1841
;смещение до данных уже за 1-м мб
1151 Lrz 1842
        movzx   eax,firstDataSect
1843
        movzx   edx,data_offset
1844
        add     eax,edx
1065 Lrz 1845
 
1151 Lrz 1846
        movzx   ebx,word [fat12_buffer.BPB_BytsPerSec]
1847
        movzx   edx,byte [fat12_buffer.BPB_SecPerClus]
1848
        imul    bx,dx   ;получим размер кластера
1065 Lrz 1849
 
1850
 
1851
 
1151 Lrz 1852
        push    ebx     ;save bx
1065 Lrz 1853
 
1151 Lrz 1854
        imul    eax,ebx
1855
;       shl     eax,9   ;умножим на 512
1856
 
1065 Lrz 1857
if DEBUG
1151 Lrz 1858
        pusha
1859
;       mov     eax,ebx;point_next_fat_str
1065 Lrz 1860
        mov     cx,0x0a
1861
        mov     di,show_db1
1862
        call    decode
1863
;Show size
1864
        mov     si,show_db1
1865
        call    printplain
1151 Lrz 1866
        popa
1065 Lrz 1867
 
1868
end if
1869
 
1151 Lrz 1870
;       mov     bx,word [fat12_buffer.BPB_BytsPerSec]
1871
;       movzx   dx,byte [fat12_buffer.BPB_SecPerClus]
1872
;       imul    bx,dx
1873
;       cwd
1874
;       idiv    bx
1065 Lrz 1875
 
1151 Lrz 1876
        mov     dl,0x10
1065 Lrz 1877
 
1151 Lrz 1878
@@:     cmp     eax,0x00010000
1879
        jb      @f
1065 Lrz 1880
 
1151 Lrz 1881
        sub     eax,0x00010000
1882
        inc     dl
1883
        jmp     @b
1065 Lrz 1884
 
1885
 
1151 Lrz 1886
@@:     mov     byte [si+8*3+3],dl      ;куда писать
1887
        mov     word [si+8*3+2],ax
1065 Lrz 1888
 
1151 Lrz 1889
        mov     ecx,save_file_size      ;размер файла в байтах.
1890
        cmp     ecx,0x0000ffff          ;размер блока т.е. 64 кб
1891
        jbe     .correct_on_byte        ;корректировка на байт значения
1065 Lrz 1892
 
1893
 
1894
 
1151 Lrz 1895
        mov     ecx,0x00010000          ;65536
1896
        sub     save_file_size,ecx      ;отнимим
1897
;       jmp     .st1                    ;получим 0х8000
1065 Lrz 1898
 
1899
 
1900
 
1901
 
1902
;корректировка значения должна быть выполенена на размер кластера
1903
.correct_on_byte:
1904
;/узнаем размер кластера
1151 Lrz 1905
        pop     eax     ;restore size of claster
1906
        push    ecx
1907
@@:     inc     data_offset
1065 Lrz 1908
 
1151 Lrz 1909
        cmp     eax,ecx
1910
        jae     @f
1911
        sub     ecx,eax
1912
        jmp     @b
1913
@@:     pop     ecx
1065 Lrz 1914
 
1915
 
1916
 
1917
 
1151 Lrz 1918
        test    ecx,0x1
1919
        jz      .st1
1920
        inc     ecx
1921
.st1:   shr     ecx,1     ; преобразовать значение для 0x87 function
1065 Lrz 1922
 
1923
;перенесем блок за 1 мб
1924
        push    es
1925
        push    ds
1926
        pop     es
1927
 
1928
        mov     ah, 0x87
1929
        int     0x15
1930
        pop     es
1931
 
1932
if DEBUG
1151 Lrz 1933
        pusha
1934
;       mov     ax,point_next_fat_str
1065 Lrz 1935
        mov     cx,0x0a
1936
        mov     di,return_code_af_move
1937
        call    decode
1938
;Show size
1939
        mov     si,return_code_af_move
1940
        call    printplain
1151 Lrz 1941
        popa
1065 Lrz 1942
 
1943
end if
1944
 
1945
}
1946
 
1947
 
1948
macro move_up_fat_and_root_d
1949
;макрос, который позволяет перенести выше 1 мб в структуру образа фат таблицу и рут директорию
1950
{
1951
local  .st1
1952
 
1151 Lrz 1953
        mov     ax,info_real_mode_size
1954
        add     ax,0x1000
1065 Lrz 1955
 
1956
        mov     si,table_15_87
1151 Lrz 1957
        mov     word [si+8*2+2],ax
1065 Lrz 1958
;смещение до данных
1151 Lrz 1959
        mov     ax,512
1960
        mov     word [si+8*3+2],ax
1065 Lrz 1961
;fixme! тут необходимо сделать подержку т.е. формировать смещение файла в уже записанных данных.
1962
 
1151 Lrz 1963
        movzx   ecx,word [fat12_buffer.BPB_FATSz16]
1964
        movzx   bx,byte [fat12_buffer.BPB_NumFATs]
1965
        imul    cx,bx   ;9x1=9
1065 Lrz 1966
 
1151 Lrz 1967
        add     cx,size_root_dir        ;размер корневой дирректории
1968
        shl     ecx,9   ;imul 512
1065 Lrz 1969
 
1970
 
1971
;корректировка значения
1151 Lrz 1972
        test    ecx,0x1
1973
        jz      .st1
1974
        inc     ecx
1975
.st1:   shr     ecx,1
1065 Lrz 1976
 
1977
        push    es
1978
        push    ds
1979
        pop     es
1980
 
1981
        mov     ah, 0x87
1982
        int     0x15
1983
        pop     es
1984
 
1985
if DEBUG
1151 Lrz 1986
        pusha
1987
;       mov     ax,point_next_fat_str
1065 Lrz 1988
        mov     cx,0x0a
1989
        mov     di,return_code_af_fat_m
1990
        call    decode
1991
;Show size
1992
        mov     si,return_code_af_fat_m
1993
        call    printplain
1151 Lrz 1994
        popa
1065 Lrz 1995
 
1996
end if
1997
 
1998
}