Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                     ;;
  3. ;; Last modify Alexey Teplov <Lrz> 2008. All rights reserved.          ;;
  4. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved.        ;;
  5. ;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa             ;;
  6. ;; Distributed under terms of the GNU General Public License           ;;
  7. ;;                                                                     ;;
  8. ;;  kolibri_ldm.asm the module for Secondary Loader                    ;;
  9. ;;                                                                     ;;
  10. ;;  KolibriOS 16-bit loader module,                                    ;;
  11. ;;                        based on bootcode for KolibriOS              ;;
  12. ;;                                                                     ;;
  13. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  14.  
  15. include "lang.inc"
  16.  
  17. macro _setcursor row,column
  18. {
  19.         mov     dx, row*256 + column
  20.         call    setcursor
  21. }
  22. long_v_table equ 9   ;long of visible video table
  23. size_of_step equ 10
  24. d80x25_bottom_num equ 3
  25. d80x25_top_num equ 4
  26. ;It's a module for Secondary Loader to load kolibri OS
  27. ;
  28. start_of_code:
  29.         cld
  30. ; \begin{diamond}[02.12.2005]
  31. ; if bootloader sets ax = 'KL', then ds:si points to loader block
  32. ;        cmp     ax, 'KL'
  33. ;        jnz     @f
  34. ;        mov     word [cs:cfgmanager.loader_block], si
  35. ;        mov     word [cs:cfgmanager.loader_block+2], ds
  36. ;@@:
  37. ; \end{diamond}[02.12.2005]
  38.  
  39. ; if bootloader sets cx = 'HA' and dx = 'RD', then bx contains identifier of source hard disk
  40. ; (see comment to bx_from_load)
  41. ;        cmp     cx, 'HA'
  42. ;        jnz     no_hd_load
  43. ;        cmp     dx,'RD'
  44. ;        jnz     no_hd_load
  45. ;        mov     word [cs:bx_from_load], bx              ; {SPraid}[13.03.2007]
  46. ;no_hd_load:
  47.  
  48. ; set up stack
  49.         push    cs
  50.         pop     ss
  51.         xor     ax, ax
  52.         mov     sp, ax
  53. ;        mov     ax, 3000h
  54. ;        mov     ss, ax
  55. ;        mov     sp, 0EC00h
  56. ; set up segment registers
  57.         push    cs
  58.         pop     ds
  59.         push    cs
  60.         pop     es
  61.  
  62. ; set videomode
  63.         mov     ax, 3
  64.         int     0x10
  65.  
  66. ;if lang eq ru
  67.  ; Load & set russian VGA font (RU.INC)
  68.         mov     bp, RU_FNT1             ; RU_FNT1 - First part
  69.         mov     bx, 1000h               ; 768 bytes
  70.         mov     cx, 30h                 ; 48 symbols
  71.         mov     dx, 80h                 ; 128 - position of first symbol
  72.         mov     ax, 1100h
  73.         int     10h
  74.  
  75.         mov     bp, RU_FNT2             ; RU_FNT2 -Second part
  76.         mov     bx, 1000h               ; 512 bytes
  77.         mov     cx, 20h                 ; 32 symbols
  78.         mov     dx, 0E0h                ; 224 - position of first symbol
  79.         mov     ax, 1100h
  80.         int     10h
  81.  ; End set VGA russian font
  82. ;else if lang eq et
  83. ;        mov     bp, ET_FNT              ; ET_FNT1
  84. ;        mov     bx, 1000h               ;
  85. ;        mov     cx, 255                 ; 256 symbols
  86. ;        xor     dx, dx                  ; 0 - position of first symbol
  87. ;        mov     ax, 1100h
  88. ;        int     10h
  89. ;end if
  90.  
  91. ; draw frames
  92.         push    0xb800
  93.         pop     es
  94.         xor     di, di
  95.         mov     ah, 1*16+15
  96.  
  97. ; draw top
  98.         mov     si, d80x25_top
  99.         mov     cx, d80x25_top_num * 80
  100. @@:
  101.         lodsb
  102.         stosw
  103.         loop    @b
  104. ; draw spaces
  105.         mov     si, space_msg
  106.         mov     dx, 25 - d80x25_top_num - d80x25_bottom_num
  107. dfl1:
  108.         push    si
  109.         mov     cx, 80
  110. @@:
  111.         lodsb
  112.         stosw
  113.         loop    @b
  114.         pop     si
  115.         dec     dx
  116.         jnz     dfl1
  117. ; draw bottom
  118.         mov     si, d80x25_bottom
  119.         mov     cx, d80x25_bottom_num * 80
  120. @@:
  121.         lodsb
  122.         stosw
  123.         loop    @b
  124.  
  125.         mov     byte [space_msg+80], 0    ; now space_msg is null terminated
  126.  
  127.         _setcursor d80x25_top_num,0
  128.  
  129.  
  130. ; TEST FOR 386+
  131.  
  132.         mov     bx, 0x4000
  133.         pushf
  134.         pop     ax
  135.         mov     dx, ax
  136.         xor     ax, bx
  137.         push    ax
  138.         popf
  139.         pushf
  140.         pop     ax
  141.         and     ax, bx
  142.         and     dx, bx
  143.         cmp     ax, dx
  144.         jnz     cpugood
  145.         mov     si, not386
  146. sayerr:
  147.         call    print
  148.         jmp     $
  149.      cpugood:
  150.  
  151.         push    0
  152.         popf
  153.         sti
  154.  
  155. ; set up esp
  156.         movzx   esp, sp
  157.  
  158.         push    0
  159.         pop     es
  160.         and     word [es:BOOT_IDE_BASE_ADDR], 0
  161. ; \begin{Mario79}
  162. ; find HDD IDE DMA PCI device
  163. ; check for PCI BIOS
  164.         mov     ax, 0xB101
  165.         int     0x1A
  166.         jc      .nopci
  167.         cmp     edx, 'PCI '
  168.         jnz     .nopci
  169. ; find PCI class code
  170. ; class 1 = mass storage
  171. ; subclass 1 = IDE controller
  172. ; a) class 1, subclass 1, programming interface 0x80
  173.         mov     ax, 0xB103
  174.         mov     ecx, 1*10000h + 1*100h + 0x80
  175.         xor     si, si  ; device index = 0
  176.         int     0x1A
  177.         jnc     .found
  178. ; b) class 1, subclass 1, programming interface 0x8A
  179.         mov     ax, 0xB103
  180.         mov     ecx, 1*10000h + 1*100h + 0x8A
  181.         xor     si, si  ; device index = 0
  182.         int     0x1A
  183.         jnc     .found
  184. ; c) class 1, subclass 1, programming interface 0x85
  185.         mov     ax, 0xB103
  186.         mov     ecx, 1*10000h + 1*100h + 0x85
  187.         xor     si, si
  188.         int     0x1A
  189.         jc      .nopci
  190. .found:
  191. ; get memory base
  192.         mov     ax, 0xB10A
  193.         mov     di, 0x20        ; memory base is config register at 0x20
  194.         int     0x1A
  195.         jc      .nopci
  196.         and     cx, 0xFFF0      ; clear address decode type
  197.         mov     [es:BOOT_IDE_BASE_ADDR], cx
  198. .nopci:
  199. ; \end{Mario79}
  200.  
  201.         mov     al, 0xf6        ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå
  202.         out     0x60, al
  203.         xor     cx, cx
  204. wait_loop:       ; variant 2
  205. ; reading state of port of 8042 controller
  206.         in      al, 64h
  207.         and     al, 00000010b  ; ready flag
  208. ; wait until 8042 controller is ready
  209.         loopnz  wait_loop
  210.  
  211. ;;;/diamond today   5.02.2008
  212. ; set keyboard typematic rate & delay
  213.         mov     al, 0xf3
  214.         out     0x60, al
  215.         xor     cx, cx
  216. @@:
  217.         in      al, 64h
  218.         test    al, 2
  219.         loopnz  @b
  220.         mov     al, 0
  221.         out     0x60, al
  222.         xor     cx, cx
  223. @@:
  224.         in      al, 64h
  225.         test    al, 2
  226.         loopnz  @b
  227. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  228. ; --------------- APM ---------------------
  229.         and     word [es:BOOT_APM_VERSION], 0     ; ver = 0.0 (APM not found)
  230.         mov     ax, 0x5300
  231.         xor     bx, bx
  232.         int     0x15
  233.         jc      apm_end                 ; APM not found
  234.         test    cx, 2
  235.         jz      apm_end                 ; APM 32-bit protected-mode interface not supported
  236.         mov     [es:BOOT_APM_VERSION], ax         ; Save APM Version
  237.         mov     [es:BOOT_APM_FLAGS], cx         ; Save APM flags
  238.  
  239.         ; Write APM ver ----
  240.         and     ax, 0xf0f
  241.         add     ax, '00'
  242.         mov     si, msg_apm
  243.         mov     [si + 5], ah
  244.         mov     [si + 7], al
  245.         _setcursor 0, 3
  246.         call    printplain
  247.         ; ------------------
  248.  
  249.         mov     ax, 0x5304              ; Disconnect interface
  250.         xor     bx, bx
  251.         int     0x15
  252.         mov     ax, 0x5303              ; Connect 32 bit mode interface
  253.         xor     bx, bx
  254.         int     0x15
  255.  
  256.         mov     [es:BOOT_APM_ENTRY], ebx
  257.         mov     [es:BOOT_APM_CODE_32], ax
  258.         mov     [es:BOOT_APM_CODE_16], cx
  259.         mov     [es:BOOT_APM_DATA_16], dx
  260.  
  261. apm_end:
  262.         _setcursor d80x25_top_num, 0
  263.  
  264. ;CHECK current of code
  265.         cmp     [cfgmanager.loader_block], -1
  266.         jz      noloaderblock
  267.         les     bx, [cfgmanager.loader_block]
  268.         cmp     byte [es:bx], 1
  269.         mov     si, loader_block_error
  270.         jnz     sayerr
  271.         push    0
  272.         pop     es
  273.  
  274. noloaderblock:
  275. ; DISPLAY VESA INFORMATION
  276.         call    print_vesa_info
  277.         call    calc_vmodes_table
  278.         call    check_first_parm   ;check and enable cursor_pos
  279.  
  280.  
  281. ; \begin{diamond}[30.11.2005]
  282. cfgmanager:
  283. ; settings:
  284. ; a) preboot_graph = graphical mode
  285. ;    preboot_gprobe = probe this mode?
  286. ; b) preboot_dma  = use DMA access?
  287. ; c) preboot_vrrm = use VRR?
  288.  
  289. ; determine default settings
  290.         mov     [.bSettingsChanged], 0
  291.  
  292. ;.preboot_gr_end:
  293.         mov     di, preboot_device
  294. ; if image in memory is present and [preboot_device] is uninitialized,
  295. ; set it to use this preloaded image
  296.         cmp     byte [di], 0
  297.         jnz     .preboot_device_inited
  298.         cmp     [.loader_block], -1
  299.         jz      @f
  300.         les     bx, [.loader_block]
  301.         test    byte [es:bx+1], 1
  302.         jz      @f
  303.         mov     byte [di], 3
  304.         jmp     .preboot_device_inited
  305. @@:
  306. ; otherwise, set [preboot_device] to 1 (default value - boot from floppy)
  307.         mov     byte [di], 1
  308. .preboot_device_inited:
  309. ; following 6 lines set variables to 1 if its current value is 0
  310.         cmp     byte [di+preboot_dma-preboot_device], 1
  311.         adc     byte [di+preboot_dma-preboot_device], 0
  312.         cmp     byte [di+preboot_biosdisk-preboot_device], 1
  313.         adc     byte [di+preboot_biosdisk-preboot_device], 0
  314.         cmp     byte [di+preboot_vrrm-preboot_device], 1
  315.         adc     byte [di+preboot_vrrm-preboot_device], 0
  316. ; notify user
  317.         _setcursor 5,2
  318.  
  319.         mov     si, linef
  320.         call    printplain
  321.         mov     si, start_msg
  322.         call    print
  323.         mov     si, time_msg
  324.         call    print
  325. ; get start time
  326.         call    .gettime
  327.         mov     [.starttime], eax
  328.         mov     word [.timer], .newtimer
  329.         mov     word [.timer+2], cs
  330. .printcfg:
  331.         _setcursor 9,0
  332.         mov     si, current_cfg_msg
  333.         call    print
  334.         mov     si, curvideo_msg
  335.         call    print
  336.  
  337.         call    draw_current_vmode
  338.  
  339.         mov     si, usebd_msg
  340.         cmp     [preboot_biosdisk], 1
  341.         call    .say_on_off
  342.         mov     si, vrrm_msg
  343.         cmp     [preboot_vrrm], 1
  344.         call    .say_on_off
  345. ;        mov     si, preboot_device_msg
  346. ;        call    print
  347. ;        mov     al, [preboot_device]
  348. ;        and     eax, 7
  349. ;        mov     si, [preboot_device_msgs+eax*2]
  350. ;        call    printplain
  351. .show_remarks:
  352. ; show remarks in gray color
  353.         mov     di, ((21-num_remarks)*80 + 2)*2
  354.         push    0xB800
  355.         pop     es
  356.         mov     cx, num_remarks
  357.         mov     si, remarks
  358. .write_remarks:
  359.         lodsw
  360.         push    si
  361.         xchg    ax, si
  362.         mov     ah, 1*16+7      ; background: blue (1), foreground: gray (7)
  363.         push    di
  364. .write_remark:
  365.         lodsb
  366.         test    al, al
  367.         jz      @f
  368.         stosw
  369.         jmp     .write_remark
  370. @@:
  371.         pop     di
  372.         pop     si
  373.         add     di, 80*2
  374.         loop    .write_remarks
  375. .wait:
  376.         _setcursor 25,0         ; out of screen
  377. ; set timer interrupt handler
  378.         cli
  379.         push    0
  380.         pop     es
  381.         push    dword [es:8*4]
  382.         pop     dword [.oldtimer]
  383.         push    dword [.timer]
  384.         pop     dword [es:8*4]
  385. ;        mov     eax, [es:8*4]
  386. ;        mov     [.oldtimer], eax
  387. ;        mov     eax, [.timer]
  388. ;        mov     [es:8*4], eax
  389.         sti
  390. ; wait for keypressed
  391.         xor     ax, ax
  392.         int     16h
  393.         push    ax
  394. ; restore timer interrupt
  395. ;        push    0
  396. ;        pop     es
  397.         mov     eax, [.oldtimer]
  398.         mov     [es:8*4], eax
  399.         mov     [.timer], eax
  400.         _setcursor 7,0
  401.         mov     si, space_msg
  402.         call    printplain
  403. ; clear remarks and restore normal attributes
  404.         push    es
  405.         mov     di, ((21-num_remarks)*80 + 2)*2
  406.         push    0xB800
  407.         pop     es
  408.         mov     cx, num_remarks
  409.         mov     ax, ' ' + (1*16 + 15)*100h
  410. @@:
  411.         push    cx
  412.         mov     cx, 76
  413.         rep stosw
  414.         pop     cx
  415.         add     di, 4*2
  416.         loop    @b
  417.         pop     es
  418.         pop     ax
  419. ; switch on key
  420.         cmp     al, 13
  421.         jz      .continue
  422.         or      al, 20h
  423.         cmp     al, 'a'
  424.         jz      .change_a
  425.         cmp     al, 'b'
  426.         jz      .change_b
  427.         cmp     al, 'c'
  428.         jnz     .show_remarks
  429.  
  430.         _setcursor 15,0
  431.         mov     si, vrrmprint
  432.         call    print
  433.         mov     bx, '12'
  434.         call    getkey
  435.         mov     [preboot_vrrm], al
  436.         _setcursor 12,0
  437. .d:
  438.         mov     [.bSettingsChanged], 1
  439.         call    clear_vmodes_table             ;clear vmodes_table
  440.         jmp     .printcfg
  441. .change_a:
  442. .loops:
  443.         call    draw_vmodes_table
  444.         _setcursor 25,0         ; out of screen
  445.         xor     ax, ax
  446.         int     0x16
  447. ;        call    clear_table_cursor             ;clear current position of cursor
  448.  
  449.         mov     si, word [cursor_pos]
  450.  
  451.         cmp     ah, 0x48;x,0x48E0               ; up
  452.         jne     .down
  453.         cmp     si, modes_table
  454.         jbe     .loops
  455.         sub     word [cursor_pos], size_of_step
  456.         jmp     .loops
  457.  
  458. .down:
  459.         cmp     ah, 0x50;x,0x50E0               ; down
  460.         jne     .pgup
  461.         cmp     word[es:si+10], -1
  462.         je      .loops
  463.         add     word [cursor_pos], size_of_step
  464.         jmp     .loops
  465.  
  466. .pgup:
  467.         cmp     ah, 0x49                ; page up
  468.         jne     .pgdn
  469.         sub     si, size_of_step*long_v_table
  470.         cmp     si, modes_table
  471.         jae     @f
  472.         mov     si, modes_table
  473. @@:
  474.         mov     word [cursor_pos], si
  475.         mov     si, word [home_cursor]
  476.         sub     si, size_of_step*long_v_table
  477.         cmp     si, modes_table
  478.         jae     @f
  479.         mov     si, modes_table
  480. @@:
  481.         mov     word [home_cursor], si
  482.         jmp     .loops
  483.  
  484. .pgdn:
  485.         cmp     ah, 0x51                ; page down
  486.         jne     .enter
  487.         mov     ax, [end_cursor]
  488.         add     si, size_of_step*long_v_table
  489.         cmp     si, ax
  490.         jb      @f
  491.         mov     si, ax
  492.         sub     si, size_of_step
  493. @@:
  494.         mov     word [cursor_pos], si
  495.         mov     si, word [home_cursor]
  496.         sub     ax, size_of_step*long_v_table
  497.         add     si, size_of_step*long_v_table
  498.         cmp     si, ax
  499.         jb      @f
  500.         mov     si, ax
  501. @@:
  502.         mov     word [home_cursor], si
  503.         jmp     .loops
  504.  
  505. .enter:
  506.         cmp     al, 0x0D;x,0x1C0D               ; enter
  507.         jne     .loops
  508.         push    word [cursor_pos]
  509.         pop     bp
  510.         push    word [es:bp]
  511.         pop     word [x_save]
  512.         push    word [es:bp+2]
  513.         pop     word [y_save]
  514.         push    word [es:bp+6]
  515.         pop     word [number_vm]
  516.         mov     word [preboot_graph], bp          ;save choose
  517.        
  518.         jmp     .d
  519.  
  520. .change_b:
  521.         _setcursor 15,0
  522. ;        mov     si, ask_dma
  523. ;        call    print
  524. ;        mov     bx, '13'
  525. ;        call    getkey
  526. ;        mov     [preboot_dma], al
  527.         mov     si, ask_bd
  528.         call    print
  529.         mov     bx, '12'
  530.         call    getkey
  531.         mov     [preboot_biosdisk], al
  532.         _setcursor 11,0
  533.         jmp     .d
  534. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  535. .say_on_off:
  536.         pushf
  537.         call    print
  538.         mov     si, on_msg
  539.         popf
  540.         jz      @f
  541.         mov     si, off_msg
  542. @@:
  543.         jmp     printplain
  544. ; novesa and vervesa strings are not used at the moment of executing this code
  545. virtual at novesa
  546. .oldtimer dd ?
  547. .starttime dd ?
  548. .bSettingsChanged db ?
  549. .timer dd ?
  550. end virtual
  551. .loader_block dd -1
  552. .gettime:
  553.         mov     ah, 0
  554.         int     1Ah
  555.         xchg    ax, cx
  556.         shl     eax, 10h
  557.         xchg    ax, dx
  558.         ret
  559. .newtimer:
  560.         push    ds
  561.         push    cs
  562.         pop     ds
  563.         pushf
  564.         call    [.oldtimer]
  565.         pushad
  566.         call    .gettime
  567.         sub     eax, [.starttime]
  568.         sub     ax, 18*5
  569.         jae     .timergo
  570.         neg     ax
  571.         add     ax, 18-1
  572.         mov     bx, 18
  573.         xor     dx, dx
  574.         div     bx
  575. if lang eq ru
  576. ; ¯®¤®¦¤¨â¥ 5 ᥪ㭤, 4/3/2 ᥪ㭤ë, 1 ᥪ㭤ã
  577.         cmp     al, 5
  578.         mov     cl, ' '
  579.         jae     @f
  580.         cmp     al, 1
  581.         mov     cl, 'ã'
  582.         jz      @f
  583.         mov     cl, 'ë'
  584. @@:
  585.         mov     [time_str+9], cl
  586. else if lang eq et
  587.         cmp     al, 1
  588.         ja      @f
  589.         mov     [time_str+9], ' '
  590.         mov     [time_str+10], ' '
  591. @@:
  592. else
  593. ; wait 5/4/3/2 seconds, 1 second
  594.         cmp     al, 1
  595.         mov     cl, 's'
  596.         ja      @f
  597.         mov     cl, ' '
  598. @@:
  599.         mov     [time_str+9], cl
  600. end if
  601.         add     al, '0'
  602.         mov     [time_str+1], al
  603.         mov     si, time_msg
  604.         _setcursor 7,0
  605.         call    print
  606.         _setcursor 25,0
  607.         popad
  608.         pop     ds
  609.         iret
  610. .timergo:
  611.         push    0
  612.         pop     es
  613.         mov     eax, [.oldtimer]
  614.         mov     [es:8*4], eax
  615.         mov     sp, 0EC00h
  616. .continue:
  617.         sti
  618.         _setcursor 6,0
  619.         mov     si, space_msg
  620.         call    printplain
  621.         call    printplain
  622.         _setcursor 6,0
  623.         mov     si, loading_msg
  624.         call    print
  625.         _setcursor 15,0
  626.         cmp     [.bSettingsChanged], 0
  627.         jz      .load
  628.         cmp     [.loader_block], -1
  629.         jz      .load
  630.         les     bx, [.loader_block]
  631.         mov     eax, [es:bx+3]
  632.         push    ds
  633.         pop     es
  634.         test    eax, eax
  635.         jz      .load
  636.         push    eax
  637.         mov     si, save_quest
  638.         call    print
  639. .waityn:
  640.         mov     ah, 0
  641.         int     16h
  642.         or      al, 20h
  643.         cmp     al, 'n'
  644.         jz      .loadc
  645.         cmp     al, 'y'
  646.         jnz     .waityn
  647.         call    putchar
  648.         mov     byte [space_msg+80], 186
  649.         pop     eax
  650.         push    cs
  651.         push    .cont
  652.         push    eax
  653.         retf
  654. .loadc:
  655.         pop     eax
  656. .cont:
  657.         push    cs
  658.         pop     ds
  659.         mov     si, space_msg
  660.         mov     byte [si+80], 0
  661.         _setcursor 15,0
  662.         call    printplain
  663.         _setcursor 15,0
  664. .load:
  665. ; \end{diamond}[02.12.2005]
  666.  
  667. ; ASK GRAPHICS MODE
  668.  
  669.         call    set_vmode
  670.  
  671. ; GRAPHICS ACCELERATION
  672. ; force yes
  673.         mov     [es:BOOT_MTRR], byte 1
  674.  
  675. ; DMA ACCESS TO HD
  676.  
  677.         mov     al, [preboot_dma]
  678.         mov     [es:BOOT_DMA], al
  679.  
  680. ; VRR_M USE
  681.  
  682. ;        mov     al, [preboot_vrrm]
  683. ;        mov     [es:0x9030], al
  684.  
  685. ; BOOT DEVICE
  686.  
  687.         mov     al, [preboot_device]
  688.         dec     al
  689.         mov     [boot_dev], al
  690.  
  691.  
  692.  
  693.  
  694.  
  695.  
  696. ;;;;;;;;;;; set videomode
  697.         xor     ax, ax
  698.         mov     es, ax
  699.  
  700.         mov     ax, [es:BOOT_VESA_MODE]         ; vga & 320x200
  701.         mov     bx, ax
  702.         cmp     ax, 0x13
  703.         je      setgr
  704.         cmp     ax, 0x12
  705.         je      setgr
  706.         mov     ax, 0x4f02              ; Vesa
  707. setgr:
  708.         int     0x10
  709.         test    ah, ah
  710.         mov     si, fatalsel
  711.         jnz     v_mode_error
  712. ; set mode 0x12 graphics registers:
  713.         cmp     bx, 0x12
  714.         jne     gmok2
  715.  
  716.         mov     al, 0x05
  717.         mov     dx, 0x03ce
  718.         push    dx
  719.         out     dx, al      ; select GDC mode register
  720.         mov     al, 0x02
  721.         inc     dx
  722.         out     dx, al      ; set write mode 2
  723.  
  724.         mov     al, 0x02
  725.         mov     dx, 0x03c4
  726.         out     dx, al      ; select VGA sequencer map mask register
  727.         mov     al, 0x0f
  728.         inc     dx
  729.         out     dx, al      ; set mask for all planes 0-3
  730.  
  731.         mov     al, 0x08
  732.         pop     dx
  733.         out     dx, al      ; select GDC bit mask register
  734.                            ; for writes to 0x03cf
  735. gmok2:
  736.         push    ds
  737.         pop     es
  738.  
  739.         jmp     $
  740.  
  741. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  742. ;data
  743. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  744. include "lang.inc"
  745. include "bootstr.inc"     ; language-independent boot messages
  746. ;if lang eq en
  747. ;include "booteng.inc"     ; english system boot messages
  748. ;else if lang eq ru
  749. include "bootru.inc"      ; russian system boot messages
  750. include "ru.inc"               ; Russian font
  751. ;else if lang eq et
  752. ;include "bootet.inc"      ; estonian system boot messages
  753. ;include "et.inc"              ; Estonian font
  754. ;else
  755. ;include "bootge.inc"      ; german system boot messages
  756. ;end if
  757.  
  758. include 'macros.inc'
  759. include 'bootvesa.inc'
  760.  
  761. include "preboot.inc"
  762.  
  763.  
  764. setcursor:
  765. ; in: dl=column, dh=row
  766.         mov     ah, 2
  767.         mov     bh, 0
  768.         int     10h
  769.         ret
  770.  
  771. putchar:
  772. ; in: al=character
  773.         mov     ah, 0Eh
  774.         mov     bh, 0
  775.         int     10h
  776.         ret
  777.  
  778. print:
  779. ; in: si->string
  780.         mov     al, 186
  781.         call    putchar
  782.         mov     al, ' '
  783.         call    putchar
  784.  
  785. printplain:
  786. ; in: si->string
  787.         pusha
  788.         lodsb
  789. @@:
  790.         call    putchar
  791.         lodsb
  792.         cmp     al, 0
  793.         jnz     @b
  794.         popa
  795.         ret
  796.  
  797. getkey:
  798. ; get number in range [bl,bh] (bl,bh in ['0'..'9'])
  799. ; in: bx=range
  800. ; out: ax=digit (1..9, 10 for 0)
  801.         mov     ah, 0
  802.         int     16h
  803.         cmp     al, bl
  804.         jb      getkey
  805.         cmp     al, bh
  806.         ja      getkey
  807.         push    ax
  808.         call    putchar
  809.         pop     ax
  810.         and     ax, 0Fh
  811.         jnz     @f
  812.         mov     al, 10
  813. @@:
  814.         ret
  815.