parse_any.inc
kolibrios-nextgen_kolibrios-kernel/kernel/sec_loader/trunk/parse_any.inc
; Copyright (c) 2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
;       * Redistributions of source code must retain the above copyright
;       notice, this list of conditions and the following disclaimer.
;       * Redistributions in binary form must reproduce the above copyright
;       notice, this list of conditions and the following disclaimer in the
;       documentation and/or other materials provided with the distribution.
;       * Neither the name of the <organization> nor the
;       names of its contributors may be used to endorse or promote products
;       derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************

;тут распологается модуль с помощью которого будут парситься все остальные секции
color_sym_black equ     0
color_sym_blue  equ     1
color_sym_green equ     2
color_sym_turquoise equ 3
color_sym_red   equ     4

color_sym_lightgray equ 7

color_sym_lightblue equ 9
color_sym_lettuce   equ 10
color_sym_pink  equ     12
color_sym_yellow equ    14

macro use_any_sec
{
;узнаем работу предыдущего шага т.е. чему = timeout, если он 0, то визуальная часть не будет отображена на дисплее с выбором загрузочных секций.
;иначе мы ее должны отобразить и ждать заявленое время для выбора и конигурирования пукнктов секции от пользователя.

if DEBUG        
        pusha
        mov     ax, word [value_timeout];идет проверка на наличее значения timeout, для более быстрой работы, этот параметр должен быть уже обработан,т.е. в этом случае при его =0 будет сформирован указатель только на дефолтную секцию, иначе информация будет собрана по всем секциям и составлены указатели в блоке памяти
;        mov     ax,cx
        mov     cx, 0x0a
        mov     di, show_db1
        mov     dword[ds:di], '    '
        mov     word [ds:di+4], '  '
        call    decode
;Show size
        mov     si, show_db1
        call    printplain
;
        popa
end if  

        test    ax, ax
        jz      .parse_run_only

;отобразим полный список всех найденых секций.
if DEBUG
        pusha
        mov     si, show_all_sect
        call    printplain
        popa
end if
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        mov     al, 0xf6        ; Сброс клавиатуры, разрешить сканирование
        out     0x60, al
        xor     cx, cx
.wait_loop:       ; variant 2
; reading state of port of 8042 controller
        in      al, 64h
        and     al, 00000010b  ; ready flag
; wait until 8042 controller is ready
        loopnz  .wait_loop


; set keyboard typematic rate & delay
        mov     al, 0xf3
        out     0x60, al
        xor     cx, cx
@@:
        in      al, 64h
        test    al, 2
        loopnz  @b
        mov     al, 0
        out     0x60, al
        xor     cx, cx
@@:
        in      al, 64h
        test    al, 2
        loopnz  @b
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; get start time
        call    gettime
        mov     dword [start_timer], eax
        mov     word [timer_], newtimer
        mov     word [timer_+2], cs
;установить свое прерывание на таймер т.е. код будет перрываться ~18 раз в сек и переходить на обработчик
        cli
        push    0
        pop     es
        push    dword [es:8*4]
        pop     dword [old_timer]
        push    dword [timer_]
        pop     dword [es:8*4]
        sti

;процедура формирования буфера для скролинга секций
;if DEBUG        
;        pusha
;       mov     ax,point_default
;        mov     ax,cx
;        mov     cx,0x0a
;        mov     di,show_db1
;        mov     dword[ds:di],'    '
;       mov     word [ds:di+4],'  '
;        call    decode                                                                    
;Show size
;        mov     si,show_db1
;        call    printplain
;
;       xor     ax,ax
;       int     0x16
;        popa
;end if  
;;;;;;;;;;;;;размер предыдущей сеции установим =0
        mov     save_descript_size, 18
;отобразить black screen
show_bl_sc      ;es=0xb800
.show_all_scr:
get_frame_buffer  ;es=0x2000
;отображение секций
        call    show_bl_sc_sect   ;es=0xb800
;отобразить активный курсор
.show_active_cursor:
show_act_cursor
show_descript   ;макрос по отображению описания секции

;отобразить Press any key ....
        mov     eax, dword [old_timer]
        cmp     eax, dword [timer_]
        jz      .interrupt_16

show_timer_message
        mov     word [start_stack], sp
.interrupt_16:
        xor     ax, ax  ;получим информацию о том что нажато
        int     0x16
;check on change
        mov     ebx, dword [old_timer]
        cmp     ebx, dword [timer_]
        jz      @f
;restore timer interrupt
        cli
        push    0
        pop     es
;        mov     eax,dword [old_timer]  ; восстановим прежднее прерывание
        mov     [es:8*4], ebx
        mov     dword [timer_], ebx
        sti
        
        push    ax
clear_timer_msg
        pop     ax
@@:
        call    clean_active_cursor   ;clean old cursor   ;es=0xb800

        cmp     ah, 0x48 ;реакция системы на события
        jz      .up
        cmp     ah, 0x50
        jz      .down
        cmp     ah, 0x49
        jz      .pgup
        cmp     ah, 0x51
        jz      .pgdown
        cmp     ah, 0x47
        jz      .home
        cmp     ah, 0x4f
        jz      .end

        cmp     al, 0xD
        jnz     .show_active_cursor

        jmp     .end_show_all           ;парсинг секции которая указана в point_default
.up:
        mov     si, point_to_point_def  ;значение указателя
        add     si, 2
        lea     ax, point_to_hframe

        cmp     si, ax
        ja      @f

        mov     point_to_point_def, si
        mov     ax, [si]
        mov     point_default, ax
        jmp     .show_active_cursor
@@:     
        call    find_before_sect
        jmp     .show_all_scr



.down:
        mov     si, point_to_point_def  ;значение указателя
        mov     ax, point_to_eframe     ;указатель на последний элемент
        sub     si, 2
        cmp     si, ax
        jb      @f

        mov     point_to_point_def, si
        mov     ax, [si]
        mov     point_default, ax
        jmp     .show_active_cursor

@@:
        call    find_next_sect
        jmp     .show_all_scr

.pgup:
        mov     cx, size_show_section
@@:
        push    cx
        call    find_before_sect
        pop     cx
        loop    @b
        jmp     .show_all_scr


.pgdown:
        mov     cx, size_show_section
@@:
        push    cx
        call    find_next_sect
        pop     cx
        loop    @b
        jmp     .show_all_scr

.home:
        xor     di, di
        call    find_next_sect.h
        jmp     .show_all_scr

.end:
        mov     di, save_cx
        call    find_before_sect.e
        jmp     .show_all_scr




; тут мы будем парсить только дефолтную секцию и выполнять ее ничего не предлагая пользователю из диалогов. 
.parse_run_only:
if DEBUG
        pusha
        mov     si, no_show_only_w
        call    printplain
        popa
end if


.end_show_all:
}















;show black screen SL
macro show_bl_sc
{
;;;;;;;;;;;;;;;
;очистим экран и выведем меню 
; draw frames
        xor     ax, ax
if DEBUG
        mov     ax, 0x0720
end if
        push    0xb800
        pop     es
        xor     di, di
; draw top
        mov     cx, 25 * 80
        rep stosw
;;;;;;;;;;;;;;;;;;;;;;; show 'Secondary Loader v0.xxx'
        mov     di, 164
        mov     si, version
        mov     cx, version_end-version
        mov     ah, color_sym_yellow
@@:
        lodsb
        stosw
        loop    @b
;;;;;;;;;;;;;;;;;;;;;;; show firm ))
        mov     di, (2*160-(2*(soft_mes_end-soft_mes+4)))       ;286
        mov     ah, color_sym_pink;color_sym_red
        mov     al, 'K'
        stosw
        mov     al, ' '
        stosw
        mov     ah, color_sym_lightgray;color_sym_lightblue;color_sym_pink
        mov     si, soft_mes
        mov     cx, soft_mes_end- soft_mes
@@:
        lodsb
        stosw
        loop    @b
;;;;;;;;;;;;;;;;;;;;;;; show '__________________________'
        mov     di, 480
        mov     ah, color_sym_yellow
        mov     al, 0xC4 ; '─'
        mov     cx, 61
        rep stosw
;;;;;;;;;;;;;;;;;;;;;;; show 'Select section'
        mov     di, 804
        mov     si, select_section
        mov     cx, select_section_end - select_section
        mov     ah, color_sym_lightgray
@@:
        lodsb
        stosw
        loop    @b
;;;;;;;;;;;;;;;;;;;;;;; show 'Section description'
        mov     di, 880
        mov     si, section_description
        mov     cx, section_description_end - section_description
;       mov     ah,color_sym_lightgray
@@:
        lodsb
        stosw
        loop    @b

}

macro show_timer_message
{
;;;;;;;;;;;;;;;;;;;;; show Press any key
;;;;;;;;;;;;;;;;;;;;; show ramk

        xor     ax, ax
        mov     di, 3360
        mov     cx, 80*4
        rep stosw

        mov     di, 3362
        mov     ah, color_sym_pink
        mov     al, 0xDA
        stosw
        mov     al, 0xc4
        mov     cx, 76
        rep stosw
        mov     al, 0xBF
        stosw
        add     di, 4
        mov     al, 0xb3
        stosw
        add     di, 152
        stosw
        add     di, 4
        stosw
        add     di, 152
        stosw
        add     di, 4
        mov     al, 0xc0
        stosw
        mov     al, 0xc4
        mov     cx, 76
        rep stosw
        mov     al, 0xd9
        stosw
;;;;;;;;;;;;;;;;;;;;;;;;ramk is complete show
;show first message
        mov     si, start_msg
        mov     cx, start_msg_e-start_msg
        mov     di, 3526
@@:
        lodsb
        stosw
        loop    @b
;;;;;;;;;;;;;;;;;;;; show press Enter to....
        add     di, 44
        mov     si, time_msg
        mov     cx, time_msg_e-time_msg
@@:
        lodsb
        stosw
        loop    @b
}








macro get_frame_buffer
{
        mov     cx, save_cx     ;it's placed size of ini file
        les     di, dword [file_data]

        mov     si, di  ;point frame
        mov     bx, cx
        mov     dx, size_show_section
;       mov     point_to_hframe,di      ; внесем значение, так подстраховка не более

        mov     al, byte [es:di]
        push    word .first_ret_bl_sc
        cmp     al, ' '
        jz      .first_bl_sc
        jmp     get_firs_sym.not_space
.first_bl_sc:
        jmp     get_firs_sym.first_sp

.start_hbl:              
        call    get_firs_sym    ;get first symbol on new line
        test    cx, cx
        jz      error.correct_exit_bl   ;critical error not found default point it's not possible because it's param chacking before
        cmp     al, '['
        jnz     .start_hbl

        mov     si, di   ;point frame
        mov     bx, cx
        mov     dx, size_show_section
        jmp     .analisist_al


.start_bl:
        call    get_firs_sym    ;get first symbol on new line
.first_ret_bl_sc:                     ;первый возврат
        test    cx, cx
        jz      error.correct_exit_bl   ;critical error not found default point it's not possible because it's param chacking before
.analisist_al:
        cmp     al, '['
        jnz     .start_bl
;просматриваем ini файл с начала в поисках секции указаной как default 
;поиск фрейма в котором содержиться значение default
.found_sect_bl:
        cmp     di, point_loader
        jz      .start_bl
        cmp     di, point_default
        jz      .save_point_def

        dec     dx
        jnz     .start_bl

        jmp     .start_hbl


.save_point_def:
;итак далее мы должны заполнить frame буфер адресов секций, что бы потом по нему быстро перемещаться не вычисляя снова адреса
        mov     di, si  ;указатель на начало 
        mov     cx, bx
        lea     si, point_to_hframe
        mov     dx, size_show_section+1  ;т.к. у нас структура содержит размер между первым и вторым указателем, то нам нужно на 1 адрес больше обсчитать секций.
;переходим на обработку значения указателя
        mov     al, byte [es:di]
        push    word .first_ret_mfb
        cmp     al, ' '
        jz      .first_bl_mbf
        jmp     get_firs_sym.not_space
.first_bl_mbf:
        jmp     get_firs_sym.first_sp

.start_mfb:
        call    get_firs_sym    ;get first symbol on new line
.first_ret_mfb:                     ;первый возврат
        jcxz    .val_buff_comp  ;.end_loader     ;found or not found parametrs in section  exit in section
        cmp     al, '['
        jnz     .start_mfb

.found_sect_mfb:
        cmp     di, point_loader    ;if we have section loader
        jz      .start_mfb

        mov     [si], di

        sub     si, 2
        dec     dx
        jnz     .start_mfb
;bufer is full
        jmp     @f
.val_buff_comp:
        push    save_cx
        pop     word [si]
        sub     si, 2
@@:

        add     si, 4
        mov     point_to_eframe, si

}

macro show_act_cursor
{
;отображение курсора по умолчанию
        lea     si, point_to_hframe
        mov     di, 962-160
        mov     ax, point_default
        mov     cx, size_show_section
.home_show_cur:
        mov     bx, [si]
        add     di, 160
        cmp     bx, ax
        jz      .show_cursor_activ
        sub     si, 2
        loop    .home_show_cur

.show_cursor_activ:
;        push   0xb800
;       pop     es
        mov     point_to_point_def, si
        mov     ax, (color_sym_red*0x100+0x10)
        stosw
        add     di, 68
        inc     ax
        stosw
}

macro clear_timer_msg
{
        push    0xb800
        pop     es
        xor     ax, ax
if DEBUG
        mov     ax, 0x0720
end if
;;;;;;;;;;;;;;;;;;;;; show Press any key
        mov     di, 3360
        mov     cx, 80*4
        rep stosw

;show sect
        push    ini_data_
        pop     es
        call    show_bl_sc_sect ;es=0xb800

}

macro show_descript
;Этот макрос показывает краткое описание, если оно есть у секции в пункте 
;Section description
{
local .start_p_sh_d
local .exit
local .rest_value_loop_sh_d
local .end_sh_desc_sec
local .loop_message
local .show_mess_prev_eq
        mov     di, point_default
        push    ini_data_
        mov     si, point_to_point_def
        pop     es
        sub     si, 2
        mov     cx, [si]        ;загрузим указатель наследующию секцию
        sub     cx, di          ;вот теперь имеем истиный размер
;di - указатель на дефолтную секцию т.е. выбранную cx - размер области. для просмотра

.start_p_sh_d:
        call    get_firs_sym    ;get first symbol on new line
        test    cx, cx
        jz      .exit   ;нету? ну ладно - следующее значение тогда ) 
        cmp     al, 'd'
        jnz     .start_p_sh_d
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        mov     bx, cx
        mov     ax, di

        mov     si, parse_descript
        mov     cx, parse_descript_e - parse_descript
        repe cmpsb
        jnz     .rest_value_loop_sh_d      ;is not compare

        sub     bx, parse_descript_e - parse_descript;correct cx
        add     bx, cx
        mov     cx, bx
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; разбор аля ' = '
        mov     ax, 0x3d20         ;cut al=' ' ah='='
        repe scasb
        jcxz    .rest_value_loop_sh_d          ;not found param timeout
        
        cmp     ah, byte [es:di-1]   ;find '='
        jnz     .rest_value_loop_sh_d
        
        repe scasb                 ;cut ' '
        inc     cx
        dec     di
;;;;;;;;;;;;;;;;;;;;di указывает на строчку, которую нам нужно выводить.
;строчка будет выводиться блоками по 37 символов.
;настроим куда будем выводить т.е. начало
;es:di - указывают на строчку из которой мы берем символ, ds:si куда будем выводить
        push    di
        pop     si

        push    es
        pop     ds

        push    0xb800
        pop     es
        
        mov     di, 1040
        mov     bx, 18
        mov     find_sec_di, di
        mov     save_cx_d, bx
;;;;;;;;;;;;;;;;;;;;;;;;;;      
;clean string

        push    di
        xor     ax, ax

@@:
        mov     cx, 38
        push    di
        rep stosw
        pop     di

        cmp     save_descript_size, bx
        jz      @f


        add     di, 160
        dec     bx
        jnz     @b

@@:
        pop     di
;enter in mess
.show_mess_prev_eq:
        lodsb
        mov     ah, color_sym_lettuce;color_sym_turquoise
;       sub     di,2
        cmp     al, '"'
        jz      .loop_message
        cmp     al, "'"
        jnz     .end_sh_desc_sec

.loop_message:        
        mov     cx, 38
@@:
        lodsb
        cmp     al, '"'
        jz      .end_sh_desc_sec
        cmp     al, "'"
        jz      .end_sh_desc_sec
        stosw
        loop    @b
        
        add     find_sec_di, 160
        mov     di, find_sec_di
        dec     save_cx_d
        cmp     save_cx_d, 0
        jnz     .loop_message

.end_sh_desc_sec:
        push    save_cx_d
        pop     save_descript_size

        push    cs
        pop     ds
        jmp     .exit


.rest_value_loop_sh_d:
        mov     di, ax
        mov     cx, bx
        jmp     .start_p_sh_d

.exit:
}
