Subversion Repositories Kolibri OS

Rev

Rev 412 | Rev 425 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                        ;;
  3. ;;  BOOTCODE.INC                                          ;;
  4. ;;                                                        ;;
  5. ;;  KolibriOS 16-bit loader,                              ;;
  6. ;;                        based on bootcode for MenuetOS  ;;
  7. ;;                                                        ;;
  8. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  9.  
  10.  
  11.  
  12. ;==========================================================================
  13. ;
  14. ;                           16 BIT FUNCTIONS
  15. ;
  16. ;==========================================================================
  17.  
  18. ; 16-bit data
  19.                 org $+0x10000
  20.  
  21. old_ints_h:
  22.         dw      0x400
  23.         dd      0
  24.         dw      0
  25.  
  26. kernel_restart_bootblock:
  27.     db    1    ; version
  28.     dw    1    ; floppy image is in memory
  29.     dd    0    ; cannot save parameters
  30.  
  31.  
  32. align 32
  33.  
  34. ; GDT TABLE
  35.  
  36. gdts:
  37.  
  38.         dw     gdte-$-1
  39.         dd     gdts
  40.         dw     0
  41.  
  42. ; Attention! The order first four selectors not to change, is used in Fast System Call
  43. ; must be : os_code, os_data, app_code, app_data, ....
  44.  
  45. int_code_l:
  46. os_code_l:
  47.         dw     0xffff
  48.         dw     0x0000
  49.         db     0x00
  50.         dw     11011111b *256 +10011010b
  51.         db     0x00
  52.  
  53. int_data_l:
  54. os_data_l:
  55.         dw     0xffff
  56.         dw     0x0000
  57.         db     0x00
  58.         dw     11011111b *256 +10010010b
  59.         db     0x00
  60.  
  61. app_code_l:
  62.         dw 0xFFFF
  63.         dw 0
  64.         db 0
  65.         db cpl3
  66.         dw G32+D32+0x8000+0x7;
  67.  
  68. app_data_l:
  69.         dw 0xFFFF
  70.         dw 0
  71.         db 0
  72.         db drw3
  73.         dw G32+D32+0x8000+0x7;
  74.  
  75. ; --------------- APM ---------------------
  76. apm_code_32:
  77.         dw     0x0f        ; limit 64kb
  78.         db     0, 0, 0
  79.         dw     11010000b *256 +10011010b
  80.         db     0x00
  81. apm_code_16:
  82.         dw     0x0f
  83.         db     0, 0, 0
  84.         dw     10010000b *256 +10011010b
  85.         db     0x00
  86. apm_data_16:
  87.         dw     0x0f
  88.         db     0, 0, 0
  89.         dw     10010000b *256 +10010010b
  90.         db     0x00
  91. ; -----------------------------------------
  92.  
  93. graph_data_l:
  94.  
  95.         dw     0x7ff
  96.         dw     0x0000
  97.         db     0x00
  98.         dw     11010000b *256 +11110010b
  99.         db     0x00
  100.  
  101. tss0_l:
  102. ;      times (max_processes+10) dd 0,0
  103. gdte = $ + (max_processes+10)*8
  104.  
  105. ; videomodes table
  106. gr_table:
  107.     dw      0x112+0100000000000000b ,  640 ,  480        ; 1
  108.     dw      0x115+0100000000000000b ,  800 ,  600        ; 2
  109.     dw      0x118+0100000000000000b , 1024 ,  768        ; 3
  110.     dw      0x11B+0100000000000000b , 1280 , 1024        ; 4
  111.     dw      0x112 ,  640 , 480                ; 5
  112.     dw      0x115 ,  800 , 600                ; 6
  113.     dw      0x118 , 1024 , 768                ; 7
  114.     dw      0x11B , 1280 ,1024                ; 8
  115.     dw    0x13, 640, 480                    ; 9
  116.     dw    0x12, 640, 480                    ; 0
  117.  
  118. ; table for move to extended memory (int 15h, ah=87h)
  119.        movedesc:
  120.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  121.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  122.  
  123.         db      0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0
  124.         db      0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0
  125.  
  126.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  127.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  128.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  129.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  130.                 org $-0x10000
  131.  
  132. putchar:
  133. ; in: al=character
  134.     mov    ah, 0Eh
  135.     mov    bh, 0
  136.     int    10h
  137.     ret
  138.  
  139. print:
  140. ; in: si->string
  141.     mov    al, 186
  142.     call    putchar
  143.     mov    al, ' '
  144.     call    putchar
  145.  
  146. printplain:
  147. ; in: si->string
  148.     pusha
  149.     lodsb
  150. @@:
  151.     call    putchar
  152.     lodsb
  153.     cmp    al, 0
  154.     jnz    @b
  155.     popa
  156.     ret
  157.  
  158. ; Now int 16 is used for keyboard support.
  159. ; This is shorter, simpler and more reliable.
  160. if 0
  161. getkey:      push  ecx
  162.              push  edx
  163.              add   ebx,0x0101
  164.              xor   eax,eax
  165.  
  166.            gk1:
  167.              in    al,0x60
  168.              mov   cl,al
  169.            gk0:
  170.              in    al,0x60
  171.              cmp   al,cl
  172.              je    gk0
  173.              cmp   ax,11
  174.              jg    gk0
  175.              gk0_1:
  176.              mov   cl,al
  177.  
  178. ;             add   al,47
  179. ;             mov   [ds:keyinbs-0x10000],al
  180. ;             mov   si,keyinbs-0x10000
  181. ;             call  printplain
  182.  
  183.            gk12:
  184.              in    al,0x60
  185.              cmp   al,cl
  186.              je    gk12
  187.              cmp   ax,240
  188.              jne   gk13
  189.              mov   al,cl
  190.              jmp   gk14
  191.            gk13:
  192.              add   cl,128
  193.              cmp   al,cl
  194.              jne   gk1
  195.              sub   al,128
  196.            gk14:
  197.  
  198.              movzx edx,bl
  199.              cmp   eax,edx
  200.              jb    gk1
  201.              movzx edx,bh
  202.              cmp   eax,edx
  203.              jg    gk1
  204.              test  ebx,0x010000
  205.              jnz   gk3
  206.              mov   cx,0x1000
  207.              mov   dx,cx
  208.              add   eax,47
  209.              mov   cx,ax
  210.              cmp   cx,58
  211.              jb    gk_nozero
  212.              sub   cx,10
  213.            gk_nozero:
  214.              mov   [ds:keyin-0x10000],cl
  215.              mov   si,keyin-0x10000
  216.              call  printplain
  217.            gk3:
  218.              sub   eax,48
  219.              pop   edx
  220.              pop   ecx
  221.              ret
  222. end if
  223.  
  224. getkey:
  225. ; get number in range [bl,bh] (bl,bh in ['0'..'9'])
  226. ; in: bx=range
  227. ; out: ax=digit (1..9, 10 for 0)
  228.     mov    ah, 0
  229.     int    16h
  230.     cmp    al, bl
  231.     jb    getkey
  232.     cmp    al, bh
  233.     ja    getkey
  234.     push    ax
  235.     call    putchar
  236.     pop    ax
  237.     and    ax, 0Fh
  238.     jnz    @f
  239.     mov    al, 10
  240. @@:
  241.     ret
  242.  
  243. setcursor:
  244. ; in: dl=column, dh=row
  245.     mov    ah, 2
  246.     mov    bh, 0
  247.     int    10h
  248.     ret
  249.  
  250. macro _setcursor row,column
  251. {
  252.     mov    dx, row*256 + column
  253.     call    setcursor
  254. }
  255.  
  256. ;pagetable_set:
  257. ;eax - physical address
  258. ;es:di - page table
  259. ;ecx - number of pages to map
  260. ;    or    al, 7
  261. ;@@:
  262. ;    stosd
  263. ;    add    eax, 1000h
  264. ;    loop    @b
  265. ;    ret
  266.  
  267. boot_read_floppy:
  268.         push    si
  269.         xor     si, si
  270.         mov     ah, 2   ; read
  271. @@:
  272.         push    ax
  273.         int     0x13
  274.         pop     ax
  275.         jnc     @f
  276.         inc     si
  277.         cmp     si, 10
  278.         jb      @b
  279.         mov     si, badsect-0x10000
  280. sayerr_plain:
  281.         call    printplain
  282.         jmp     $
  283. @@:
  284.         pop     si
  285.         ret
  286.  
  287. ;=========================================================================
  288. ;
  289. ;                           16 BIT CODE
  290. ;
  291. ;=========================================================================
  292.  
  293.  
  294. start_of_code:
  295.     cld
  296. ; \begin{diamond}[02.12.2005]
  297.     cmp    ax, 'KL'
  298.     jnz    @f
  299.     mov    word [cs:cfgmanager.loader_block-0x10000], si
  300.     mov    word [cs:cfgmanager.loader_block+2-0x10000], ds
  301. @@:
  302. ; \end{diamond}[02.12.2005]
  303.  
  304.  
  305.         mov    word [cs:bx_from_load - 0x10000], bx             ; {SPraid}[13.03.2007]
  306.        
  307.        
  308. ; set up stack
  309.     mov    ax, 3000h
  310.     mov    ss, ax
  311.     mov    sp, 0EC00h
  312. ; set up segment registers
  313.     push    cs
  314.     pop    ds
  315.     push    cs
  316.     pop    es
  317.  
  318. ; set videomode
  319.     mov    ax, 3
  320.         int  0x10
  321.  
  322. if lang eq ru
  323.  ; Load & set russian VGA font (RU.INC)
  324.         mov  bp,RU_FNT1-10000h   ; RU_FNT1 - First part
  325.           mov  bx,1000h            ; 768 bytes
  326.           mov  cx,30h              ; 48 symbols
  327.           mov  dx,80h              ; 128 - position of first symbol
  328.         mov  ax,1100h
  329.           int  10h
  330.  
  331.         mov  bp,RU_FNT2-10000h   ; RU_FNT2 -Second part
  332.         mov  bx,1000h            ; 512 bytes
  333.         mov  cx,20h              ; 32 symbols
  334.         mov  dx,0E0h             ; 224 - position of first symbol
  335.         mov  ax,1100h
  336.           int  10h
  337.  ; End set VGA russian font
  338. else if lang eq et
  339.         mov  bp,ET_FNT-10000h   ; ET_FNT1
  340.         mov  bx,1000h           ;
  341.         mov  cx,255             ; 256 symbols
  342.         mov  dx,0h              ; 0 - position of first symbol
  343.         mov  ax,1100h
  344.         int  10h
  345. end if
  346.  
  347. ; draw frames
  348.     push    0xb800
  349.     pop    es
  350.     xor    di, di
  351. ;        mov  si,d80x25-0x10000
  352. ;        mov  cx,80*25
  353. ;        mov  ah,1*16+15
  354. ;       dfl1:
  355. ;        lodsb
  356. ;        stosw
  357. ;        loop dfl1
  358.     mov    ah, 1*16+15
  359. ; draw top
  360.     mov    si, d80x25_top - 0x10000
  361.     mov    cx, d80x25_top_num * 80
  362. @@:
  363.     lodsb
  364.     stosw
  365.     loop    @b
  366. ; draw spaces
  367.     mov    si, space_msg - 0x10000
  368.     mov    cx, 25 - d80x25_top_num - d80x25_bottom_num
  369. dfl1:
  370.     push    cx
  371.     push    si
  372.     mov    cx, 80
  373. @@:
  374.     lodsb
  375.     stosw
  376.     loop    @b
  377.     pop    si
  378.     pop    cx
  379.     loop    dfl1
  380. ; draw bottom
  381.     mov    si, d80x25_bottom - 0x10000
  382.     mov    cx, d80x25_bottom_num * 80
  383. @@:
  384.     lodsb
  385.     stosw
  386.     loop    @b
  387.  
  388.     mov    byte [space_msg-0x10000+80], 0    ; now space_msg is null terminated
  389.  
  390.     _setcursor d80x25_top_num,0
  391.  
  392.  
  393. ; TEST FOR 386+
  394.  
  395.     mov    bx, 0x4000
  396.         pushf
  397.         pop     ax
  398.         mov     dx,ax
  399.         xor     ax,bx
  400.         push    ax
  401.         popf
  402.         pushf
  403.         pop     ax
  404.         and     ax,bx
  405.         and     dx,bx
  406.         cmp     ax,dx
  407.         jnz     cpugood
  408.         mov     si,not386-0x10000
  409. sayerr:
  410.         call    print
  411.         jmp     $
  412.      cpugood:
  413.  
  414. ; set up esp
  415.     movzx    esp, sp
  416.  
  417. ; FLUSH 8042 KEYBOARD CONTROLLER
  418.  
  419. ;// mike.dld [
  420.  ;       mov     al,0xED
  421.  ;       out     0x60,al
  422.  ;       or      cx,-1
  423.  ;     @@:
  424.  ;       in      al,0x64
  425.  ;       test    al,2
  426.  ;       jz      @f
  427.  ;       loop    @b
  428.  ;     @@:
  429.  ;       mov     al,0
  430.  ;       out     0x60,al
  431.  ;       or      cx,-1
  432.  ;     @@:
  433.  ;       in      al,0x64
  434.  ;       test    al,2
  435.  ;       jz      @f
  436.  ;       loop    @b
  437.  ;     @@:
  438. ;// mike.dld ]
  439.  
  440. ;       mov     ecx,10000
  441. ;      fl1:
  442. ;       in      al,0x64
  443. ;       loop    fl1
  444. ;       test    al,1
  445. ;       jz      fl2
  446. ;       in      al,0x60
  447. ;       jmp     fl1
  448. ;      fl2:
  449.  
  450. ;****************************************************************
  451. ; The function is modified Mario79
  452. ;*****************************************************************
  453. ; wait_kbd:        ; variant 1
  454. ;       mov      cx,2500h  ;çàäåðæêà ïîðÿäêà 10 ìñåê
  455. ; test_kbd:
  456. ;       in       al,64h    ;÷èòàåì ñîñòîÿíèå êëàâèàòóðû
  457. ;       test     al,2      ;ïðîâåðêà áèòà ãîòîâíîñòè
  458. ;       loopnz   test_kbd
  459.  
  460.         push    0
  461.         pop     es
  462.         and     word [es:0x9031], 0
  463. ; \begin{Mario79}
  464. ; find HDD IDE DMA PCI device
  465. ; check for PCI BIOS
  466.         mov     ax, 0xB101
  467.         int     0x1A
  468.         jc      .nopci
  469.         cmp     edx, 'PCI '
  470.         jnz     .nopci
  471. ; find PCI class code
  472. ; class 1 = mass storage
  473. ; subclass 1 = IDE controller
  474. ; a) class 1, subclass 1, programming interface 0x80
  475.         mov     ax, 0xB103
  476.         mov     ecx, 1*10000h + 1*100h + 0x80
  477.         mov     si, 0   ; device index = 0
  478.         int     0x1A
  479.         jnc     .found
  480. ; b) class 1, subclass 1, programming interface 0x8A
  481.         mov     ax, 0xB103
  482.         mov     ecx, 1*10000h + 1*100h + 0x8A
  483.         mov     si, 0   ; device index = 0
  484.         int     0x1A
  485.         jnc     .found
  486. ; c) class 1, subclass 1, programming interface 0x85
  487.         mov     ax, 0xB103
  488.         mov     ecx, 1*10000h + 1*100h + 0x85
  489.         mov     si, 0
  490.         int     0x1A
  491.         jc      .nopci
  492. .found:
  493. ; get memory base
  494.         mov     ax, 0xB10A
  495.         mov     di, 0x20        ; memory base is config register at 0x20
  496.         int     0x1A
  497.         jc      .nopci
  498.         and     cx, 0xFFF0      ; clear address decode type
  499.         mov     [es:0x9031], cx
  500. .nopci:
  501. ; \end{Mario79}
  502.  
  503.     mov   al,0xf6         ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå
  504.     out   0x60,al
  505.     xor   cx,cx
  506. wait_loop:       ; variant 2
  507. ; reading state of port of 8042 controller
  508.         in      al,64h
  509.         and     al,00000010b  ; ready flag
  510. ; wait until 8042 controller is ready
  511.         loopnz  wait_loop
  512.  
  513. ; --------------- APM ---------------------
  514.     push    0
  515.     pop    es
  516.     mov    word [es : 0x9044], 0        ; ver = 0.0 (APM not found)
  517.     mov    ax, 0x5300
  518.     xor    bx, bx
  519.     int    0x15
  520.     jc    apm_end                ; APM not found
  521.     test    cx, 2
  522.     jz    apm_end                ; APM 32-bit protected-mode interface not supported
  523.     mov    [es : 0x9044], ax        ; Save APM Version
  524.     mov    [es : 0x9046], cx        ; Save APM flags
  525.  
  526.     ; Write APM ver ----
  527.     and    ax, 0xf0f
  528.     add    ax, '00'
  529.     mov    si, msg_apm - 0x10000
  530.     mov    [si + 5], ah
  531.     mov    [si + 7], al
  532.     _setcursor 0, 3
  533.     call    printplain
  534.     _setcursor d80x25_top_num,0
  535.     ; ------------------
  536.  
  537.     mov    ax, 0x5304            ; Disconnect interface
  538.     xor    bx, bx
  539.     int    0x15
  540.     mov    ax, 0x5303            ; Connect 32 bit mode interface
  541.     xor    bx, bx
  542.     int    0x15
  543.     ; init selectors
  544.     movzx    eax, ax ; real-mode segment base address of protected-mode 32-bit code segment
  545.     shl    eax, 4
  546.     mov    [apm_code_32 - 0x10000 + 2], ax
  547.     shr    eax, 16
  548.     mov    [apm_code_32 - 0x10000 + 4], al
  549.     movzx    ecx, cx ; real-mode segment base address of protected-mode 16-bit code segment
  550.     shl    ecx, 4
  551.     mov    [apm_code_16 - 0x10000 + 2], cx
  552.     shr    ecx, 16
  553.     mov    [apm_code_16 - 0x10000 + 4], cl
  554.     movzx    edx, dx ; real-mode segment base address of protected-mode 16-bit data segment
  555.     shl    edx, 4
  556.     mov    [apm_data_16 - 0x10000 + 2], dx
  557.     shr    edx, 16
  558.     mov    [apm_data_16 - 0x10000 + 4], dl
  559.     mov    [es : 0x9040], ebx              ; offset of APM entry point
  560. apm_end:
  561. ; -----------------------------------------
  562.  
  563. ; DISPLAY VESA INFORMATION
  564.  
  565.     push    0
  566.     pop    es
  567.         mov     ax,0x4f00
  568.         mov     di,0xa000
  569.         int     0x10
  570.         cmp     ax,0x004f
  571.         mov    si, novesa-0x10000
  572.         jnz    @f
  573.         mov bx, word [es:di+0x12]
  574.         shl ebx,16
  575.         mov [es:0x9050], ebx
  576.         mov     ax,[es:di+4]
  577.         add     ax,'0'*256+'0'
  578.         mov    si,vervesa-0x10000
  579.         mov     [si+vervesa_off], ah
  580.         mov     [si+vervesa_off+2], al
  581. @@:     call    print
  582.  
  583. ; \begin{diamond}[30.11.2005]
  584. cfgmanager:
  585. ; settings:
  586. ; a) preboot_graph = graphical mode
  587. ;    preboot_gprobe = probe this mode?
  588. ; b) preboot_dma_write  = use DMA write?
  589. ; c) preboot_vrrm = use VRR?
  590. ; d) preboot_device = from what boot?
  591.     mov    di, preboot_graph-0x10000
  592. ; check bootloader block
  593.     cmp    [.loader_block-0x10000], -1
  594.     jz    .noloaderblock
  595.     les    bx, [.loader_block-0x10000]
  596.     cmp    byte [es:bx], 1
  597.     mov    si, loader_block_error-0x10000
  598.     jnz    sayerr
  599.     test    byte [es:bx+1], 1
  600.     jz    @f
  601. ; image in memory present
  602.     cmp    [di+preboot_device-preboot_graph], 0
  603.     jnz    @f
  604.     mov    [di+preboot_device-preboot_graph], 3
  605. @@:
  606. .noloaderblock:
  607. ; determine default settings
  608.     mov    [.bSettingsChanged-0x10000], 0
  609.     cmp    byte [di], 0
  610.     jnz    .preboot_gr_end
  611.     mov    [di+preboot_gprobe-preboot_graph], 0
  612.     mov    al, [vervesa+vervesa_off-0x10000]
  613.     cmp    al, 'x'
  614.     jz    .novesa
  615.     cmp    al, '1'
  616.     jz    .vesa12
  617.     mov    [di+preboot_gprobe-preboot_graph], 2
  618.     mov    al, 3
  619.     jmp    @f
  620. .vesa12:
  621.     mov    al, 7
  622.     jmp    @f
  623. .novesa:
  624.     mov    al, 10
  625. @@:
  626.     mov    [di], al
  627. .preboot_gr_end:
  628.     cmp    [di+preboot_dma_write-preboot_graph], 1
  629.     adc    [di+preboot_dma_write-preboot_graph], 0
  630.     cmp    [di+preboot_vrrm-preboot_graph], 1
  631.     adc    [di+preboot_vrrm-preboot_graph], 0
  632.     cmp    [di+preboot_device-preboot_graph], 1
  633.     adc    [di+preboot_device-preboot_graph], 0
  634. ; notify user
  635.     mov    si, linef-0x10000
  636.     call    print
  637.     mov    si, start_msg-0x10000
  638.     call    print
  639.     mov    si, time_msg-0x10000
  640.     call    print
  641. ; get start time
  642.     call    .gettime
  643.     mov    [.starttime-0x10000], eax
  644.     mov    word [.timer-0x10000], .newtimer
  645.     mov    word [.timer-0x10000+2], cs
  646. .printcfg:
  647.     _setcursor 9,0
  648.     mov    si, current_cfg_msg-0x10000
  649.     call    print
  650.     mov    si, curvideo_msg-0x10000
  651.     call    print
  652.     mov    al, [preboot_graph-0x10000]
  653.     cmp    al, 8
  654.     ja    .pnovesa
  655.     mov    dl, al
  656.     and    eax, 3
  657.     mov    si, [modes_msg-0x10000+eax*2]
  658.     call    printplain
  659.     mov    si, modevesa20-0x10000
  660.     cmp    dl, 4
  661.     jbe    @f
  662.     mov    si, modevesa12-0x10000
  663. @@:
  664.     call    printplain
  665.     cmp    dl, 4
  666.     ja    .x
  667.     mov    si, probeno_msg-0x10000
  668.     cmp    [preboot_gprobe-0x10000], 2
  669.     jnz    @f
  670.     mov    si, probeok_msg-0x10000
  671. @@:
  672.     call    printplain
  673. .x:
  674.     jmp    .c
  675. .pnovesa:
  676.     cmp    al, 9
  677.     mov    si, mode9-0x10000
  678.     jz    @b
  679.     mov    si, mode10-0x10000
  680.     jmp    @b
  681. .c:
  682.     mov    si, linef-0x10000
  683.     call    printplain
  684.     mov    si, dma_msg-0x10000
  685.     cmp    [preboot_dma_write-0x10000], 1
  686.     call    .say_on_off
  687.     mov    si, vrrm_msg-0x10000
  688.     cmp    [preboot_vrrm-0x10000], 1
  689.     call    .say_on_off
  690.     mov    si, preboot_device_msg-0x10000
  691.     call    print
  692.     mov    al, [preboot_device-0x10000]
  693.     and    eax, 3
  694.     mov    si, [preboot_device_msgs-0x10000+eax*2]
  695.     call    printplain
  696. .wait:
  697.     _setcursor 25,0        ; out of screen
  698. ; set timer interrupt handler
  699.     cli
  700.     push    0
  701.     pop    es
  702.     mov    eax, [es:8*4]
  703.     mov    [.oldtimer-0x10000], eax
  704.     mov    eax, [.timer-0x10000]
  705.     mov    [es:8*4], eax
  706.     sti
  707. ; wait for keypressed
  708.     mov    ah, 0
  709.     int    16h
  710.     push    ax
  711. ; restore timer interrupt
  712.     push    0
  713.     pop    es
  714.     mov    eax, [.oldtimer-0x10000]
  715.     mov    [es:8*4], eax
  716.     mov    [.timer-0x10000], eax
  717.     _setcursor 7,0
  718.     mov    si, space_msg-0x10000
  719.     call    printplain
  720.     pop    ax
  721. ; switch on key
  722.     cmp    al, 13
  723.     jz    .continue
  724.     or    al, 20h
  725.     cmp    al, 'a'
  726.     jz    .change_a
  727.     cmp    al, 'b'
  728.     jz    .change_b
  729.     cmp    al, 'c'
  730.     jz    .change_c
  731.     cmp    al, 'd'
  732.     jnz    .wait
  733.     _setcursor 15,0
  734.     mov     si,bdev-0x10000
  735.     call    print
  736.     mov     bx,'13'
  737.     call    getkey
  738.     mov    [preboot_device-0x10000], al
  739.     _setcursor 13,0
  740. .d:
  741.     mov    [.bSettingsChanged-0x10000], 1
  742.     mov    si, space_msg-0x10000
  743.     call    printplain
  744.     _setcursor 15,0
  745.     mov    cx, 6
  746. @@:
  747.     call    printplain
  748.     loop    @b
  749.     jmp    .printcfg
  750. .change_a:
  751.     _setcursor 15,0
  752.     mov    si, gr_mode-0x10000
  753.     call    printplain
  754.     mov     bx, '09'
  755.     call    getkey
  756.     mov    [preboot_graph-0x10000], al
  757.     cmp    al, 4
  758.     ja    @f
  759.     mov    si, probetext-0x10000
  760.     call    printplain
  761.     mov    bx, '12'
  762.     call    getkey
  763.     mov    [preboot_gprobe-0x10000], al
  764. @@:
  765.     _setcursor 10,0
  766.     jmp    .d
  767. .change_b:
  768.     _setcursor 15,0
  769.     mov    si, ask_dma-0x10000
  770.     call    print
  771.     mov    bx, '12'
  772.     call    getkey
  773.     mov    [preboot_dma_write-0x10000], al
  774.     _setcursor 11,0
  775.     jmp    .d
  776. .change_c:
  777.     _setcursor 15,0
  778.     mov    si, vrrmprint-0x10000
  779.     call    print
  780.     mov    bx, '12'
  781.     call    getkey
  782.     mov    [preboot_vrrm-0x10000], al
  783.     _setcursor 12,0
  784.     jmp    .d
  785. .say_on_off:
  786.     pushf
  787.     call    print
  788.     mov    si, on_msg-0x10000
  789.     popf
  790.     jz    @f
  791.     mov    si, off_msg-0x10000
  792. @@:    call    printplain
  793.     ret
  794. ; novesa and vervesa strings are not used at the moment of executing this code
  795. virtual at novesa
  796. .oldtimer dd ?
  797. .starttime dd ?
  798. .bSettingsChanged db ?
  799. .timer dd ?
  800. end virtual
  801.         org $+0x10000
  802. .loader_block dd -1
  803.         org $-0x10000
  804. .gettime:
  805.     mov    ah, 0
  806.     int    1Ah
  807.     xchg    ax, cx
  808.     shl    eax, 10h
  809.     xchg    ax, dx
  810.     ret
  811. .newtimer:
  812.     push    ds
  813.     push    cs
  814.     pop    ds
  815.     pushf
  816.     call    [.oldtimer-0x10000]
  817.     pushad
  818.     call    .gettime
  819.     sub    eax, [.starttime-0x10000]
  820.     sub    ax, 18*5
  821.     jae    .timergo
  822.     neg    ax
  823.     add    ax, 18-1
  824.     mov    bx, 18
  825.     xor    dx, dx
  826.     div    bx
  827. if lang eq ru
  828. ; ¯®¤®¦¤¨â¥ 5 ᥪ㭤, 4/3/2 ᥪ㭤ë, 1 ᥪ㭤ã
  829.     cmp    al, 5
  830.     mov    cl, ' '
  831.     jae    @f
  832.     cmp    al, 1
  833.     mov    cl, 'ã'
  834.     jz    @f
  835.     mov    cl, 'ë'
  836. @@:    mov    [time_str+9-0x10000], cl
  837. else if lang eq et
  838.     cmp    al, 1
  839.     ja     @f
  840.     mov    [time_str+9-0x10000], ' '
  841.     mov    [time_str+10-0x10000],' '
  842. @@:
  843. else
  844. ; wait 5/4/3/2 seconds, 1 second
  845.     cmp    al, 1
  846.     mov    cl, 's'
  847.     ja    @f
  848.     mov    cl, ' '
  849. @@:    mov    [time_str+9-0x10000], cl
  850. end if
  851.     add    al, '0'
  852.     mov    [time_str+1-0x10000], al
  853.     mov    si, time_msg-0x10000
  854.     _setcursor 7,0
  855.     call    print
  856.     _setcursor 25,0
  857.     popad
  858.     pop    ds
  859.     iret
  860. .timergo:
  861.     push    0
  862.     pop    es
  863.     mov    eax, [.oldtimer-0x10000]
  864.     mov    [es:8*4], eax
  865.     mov    sp, 0EC00h
  866. .continue:
  867.     sti
  868.     _setcursor 6,0
  869.     mov    si, space_msg-0x10000
  870.     call    printplain
  871.     call    printplain
  872.     _setcursor 6,0
  873.     mov    si, loading_msg-0x10000
  874.     call    print
  875.     _setcursor 15,0
  876.     cmp    [.bSettingsChanged-0x10000], 0
  877.     jz    .load
  878.     cmp    [.loader_block-0x10000], -1
  879.     jz    .load
  880.     les    bx, [.loader_block-0x10000]
  881.     mov    eax, [es:bx+3]
  882.     push    ds
  883.     pop    es
  884.     test    eax, eax
  885.     jz    .load
  886.     push    eax
  887.     mov    si, save_quest-0x10000
  888.     call    print
  889. .waityn:
  890.     mov    ah, 0
  891.     int    16h
  892.     or    al, 20h
  893.     cmp    al, 'n'
  894.     jz    .loadc
  895.     cmp    al, 'y'
  896.     jnz    .waityn
  897.     call    putchar
  898.     mov    byte [space_msg-0x10000+80], 186
  899.     pop    eax
  900.     push    cs
  901.     push    .cont
  902.     push    eax
  903.     retf
  904. .loadc:
  905.     pop    eax
  906. .cont:
  907.     push    cs
  908.     pop    ds
  909.     mov    si, space_msg-0x10000
  910.     mov    byte [si+80], 0
  911.     _setcursor 15,0
  912.     call    printplain
  913.     _setcursor 15,0
  914. .load:
  915. ; \end{diamond}[02.12.2005]
  916.  
  917. ; ASK GRAPHICS MODE
  918.  
  919.     movzx    ax, [preboot_graph-0x10000]
  920.     push    0
  921.     pop    es
  922. ; address is gr_table+6*(ax-1)-0x10000
  923.         add    ax, ax
  924.         lea    si, [gr_table-0x10000 + eax + eax*2 - 6]
  925.         mov     bx,[si+0]
  926.         mov     cx,[si+2]
  927.         mov     dx,[si+4]
  928.         cmp    al, 9*2
  929.         mov    al, 32    ; BPP
  930.         jb    @f
  931.         mov    [es:0x9000], al
  932.         mov    dword [es:0x9018], 0xFFFFFFFF; 0x800000
  933.        @@:
  934.         mov     [es:0x9008],bx
  935.         mov     [es:0x900A],cx
  936.         mov     [es:0x900C],dx
  937.         test    bh, bh
  938.         jz    nov
  939.  
  940. ; USE DEFAULTS OR PROBE
  941.  
  942. ; bx - mode : cx - x size : dx - y size
  943.     cmp    [preboot_gprobe-0x10000], 1
  944.     jz    noprobe
  945.  
  946.         mov     bx,0x100
  947.      newprobe:
  948.         inc     bx
  949.         cmp     bx,0x17f
  950.         mov    si,prnotfnd-0x10000
  951.         jz    sayerr
  952.  
  953.      probemore:
  954.          push    cx
  955.         mov     ax,0x4f01
  956.         mov     cx,bx
  957.         and     cx,0xfff
  958.         mov     di,0xa000
  959.         int     0x10
  960.         pop    cx
  961.  
  962.     test    byte [es:di], 80h    ; lfb?
  963.     jz    newprobe
  964.     cmp    [es:di+0x12], cx    ; x size?
  965.     jnz    newprobe
  966.     cmp    [es:di+0x14], dx    ; y size?
  967.     jnz    newprobe
  968.     cmp    byte [es:di+0x19], 32 ;24
  969.     jb    newprobe
  970.  
  971. ;       add     bx,0100000000000000b
  972.     or    bh, 40h
  973.         mov     [es:0x9008],bx
  974.  
  975.      noprobe:
  976.  
  977.  
  978. ; FIND VESA 2.0 LFB & BPP
  979.  
  980.         mov     ax,0x4f01
  981.         mov     cx,bx
  982.         and     cx,0xfff
  983.         mov     di,0xa000
  984.         int     0x10
  985.         ; LFB
  986.         mov     eax,[es:di+0x28]
  987.         mov     [es:0x9018],eax
  988.         ; ---- vbe voodoo
  989.         BytesPerLine equ 0x10
  990.         mov ax, [es:di+BytesPerLine]
  991.         mov [es:0x9001],ax
  992.         ; BPP
  993.         mov     al,byte [es:di+0x19]
  994.         mov     [es:0x9000],al
  995.        nov:
  996.         cmp     al,24
  997.         mov    si,bt24-0x10000
  998.         jz    bppl
  999.         cmp     al,32
  1000.         mov     si,bt32-0x10000
  1001.         jz     bppl
  1002.         mov     si,btns-0x10000
  1003.         jmp    sayerr
  1004.        bppl:
  1005.         call    print
  1006.  
  1007.  
  1008. ; FIND VESA 1.2 PM BANK SWITCH ADDRESS
  1009.  
  1010.     push    es
  1011.         mov     ax,0x4f0A
  1012.         xor    bx, bx
  1013.         int     0x10
  1014.         xor     eax,eax
  1015.         mov     ax,es
  1016.         shl     eax,4
  1017.         movzx   ebx,di
  1018.         add     eax,ebx
  1019.         mov     bx,[es:di]
  1020.         add     eax,ebx
  1021.         pop     es
  1022.         mov     [es:0x9014],eax
  1023.  
  1024.  
  1025. ; GRAPHICS ACCELERATION
  1026. ; force yes
  1027.         mov     [es:0x901C], byte 1
  1028.  
  1029. ; DMA WRITE
  1030.  
  1031.         mov     al, [preboot_dma_write-0x10000]
  1032.         mov     [es:0x901F],al
  1033.  
  1034. ; VRR_M USE
  1035.  
  1036.         mov     al,[preboot_vrrm-0x10000]
  1037.         mov     [es:0x9030],al
  1038.         mov     [es:0x901E],byte 1
  1039.  
  1040. ; BOOT DEVICE
  1041.  
  1042.     mov    al, [preboot_device-0x10000]
  1043.         dec     al
  1044.         mov     [boot_dev-0x10000],al
  1045.  
  1046. ; READ DISKETTE TO MEMORY
  1047.  
  1048. ;        cmp     [boot_dev-0x10000],0
  1049.         jne     no_sys_on_floppy
  1050.         mov     si,diskload-0x10000
  1051.         call    print
  1052.         xor    ax, ax            ; reset drive
  1053.         xor    dx, dx
  1054.         int     0x13
  1055. ; now load floppy image to memory
  1056. ; at first load boot sector and first FAT table
  1057.         mov     cx, 0x0001      ; startcyl,startsector
  1058.         xor     dx, dx          ; starthead,drive
  1059.         mov     al, 1+9         ; no of sectors to read
  1060.         mov     bx, 0xB000      ; es:bx -> data area
  1061.         call    boot_read_floppy
  1062. ; and copy them to extended memory
  1063.         mov     si, movedesc-0x10000
  1064.         mov     [si+8*2+3], bh
  1065.         push    es
  1066.         push    ds
  1067.         pop     es
  1068.         mov     cx, 256*10
  1069.         mov     ah, 0x87
  1070.         int     0x15
  1071.         test    ah, ah
  1072.         jz      @f
  1073. sayerr_floppy:
  1074.         mov     dx, 0x3f2
  1075.         mov     al, 0
  1076.         out     dx, al
  1077.         mov     si, memmovefailed-0x10000
  1078.         jmp     sayerr_plain
  1079. @@:
  1080.         add     dword [si+8*3+2], 512*10
  1081. ; copy FAT to second copy
  1082.         mov     byte [si+8*2+3], 0xB2
  1083.         mov     cx, 256*9
  1084.         mov     ah, 0x87
  1085.         int     0x15
  1086.         pop     es
  1087.         test    ah, ah
  1088.         jnz     sayerr_floppy
  1089.         add     dword [si+8*3+2], 512*9
  1090. ; calculate total number of sectors to read
  1091.         mov     ax, 1+9+14      ; boot+FAT+root
  1092.         mov     di, 0xB203
  1093. .calc_loop:
  1094.         test    word [es:di], 0xFFF
  1095.         jz      @f
  1096.         inc     ax
  1097. @@:
  1098.         test    word [es:di+1], 0xFFF0
  1099.         jz      @f
  1100.         inc     ax
  1101. @@:
  1102.         add     di, 3
  1103.         cmp     di, 0xB200+1440*3
  1104.         jb      .calc_loop
  1105.         push    ax
  1106.         mov     bp, 1+9         ; already read sectors
  1107. ; now read rest
  1108.         mov     byte [si+8*2+3], 0xA0
  1109.         mov     di, 2-14        ; absolute sector-31
  1110.         mov     cx, 0x0002      ; cylinder=0, sector=2
  1111.         mov     dx, 0x0100      ; head=1, disk=0
  1112. .read_loop:
  1113. ; determine whether sector must be read
  1114.         cmp     di, 2
  1115.         jl      .read
  1116.         mov     bx, di
  1117.         shr     bx, 1
  1118.         jnc     .even
  1119.         test    word [es:bx+di+0xB200], 0xFFF0
  1120.         jmp     @f
  1121. .even:
  1122.         test    word [es:bx+di+0xB200], 0xFFF
  1123. @@:
  1124.         jz      .skip
  1125. .read:
  1126.         mov     bx, 0xA000
  1127.         mov     al, 1           ; 1 sector
  1128.         call    boot_read_floppy
  1129.         inc     bp
  1130.         push    es
  1131.         push    ds
  1132.         pop     es
  1133.         pusha
  1134.         mov     cx, 256
  1135.         mov     ah, 0x87
  1136.         int     0x15
  1137.         test    ah, ah
  1138.         popa
  1139.         pop     es
  1140.         jnz     sayerr_floppy
  1141. .skip:
  1142.         add     dword [si+8*3+2], 512
  1143.         inc     cx
  1144.         cmp     cl, 19
  1145.         jnz     @f
  1146.         mov     cl, 1
  1147.         inc     dh
  1148.         cmp     dh, 2
  1149.         jnz     @f
  1150.         mov     dh, 0
  1151.         inc     ch
  1152. @@:
  1153.         pop     ax
  1154.         push    ax
  1155.         pusha
  1156. ; draw percentage
  1157. ; total sectors: ax
  1158. ; read sectors: bp
  1159.         xchg    ax, bp
  1160.         mov     cx, 100
  1161.         mul     cx
  1162.         div     bp
  1163.         aam
  1164.         xchg    al, ah
  1165.         add     ax, '00'
  1166.         mov     si, pros-0x10000
  1167.         cmp     [si], ax
  1168.         jz      @f
  1169.         mov     [si], ax
  1170.         call    printplain
  1171. @@:
  1172.         popa
  1173.         inc     di
  1174.         cmp     di, 2880-31
  1175.         jnz     .read_loop
  1176.  
  1177. ;        mov     cx, 0x0001      ; startcyl,startsector
  1178. ;        xor     dx, dx          ; starthead,drive
  1179. ;        push    word 80*2               ; read no of sect
  1180. ;       reads:
  1181. ;        pusha
  1182. ;        xor     si,si
  1183. ;       newread:
  1184. ;        mov     bx,0xa000               ; es:bx -> data area
  1185. ;        mov     ax,0x0200+18            ; read, no of sectors to read
  1186. ;        int     0x13
  1187. ;        test    ah, ah
  1188. ;        jz      goodread
  1189. ;        inc    si
  1190. ;        cmp     si,10
  1191. ;        jnz     newread
  1192. ;        mov     si,badsect-0x10000
  1193. ;sayerr_plain:
  1194. ;        call    printplain
  1195. ;        jmp     $
  1196. ;       goodread:
  1197. ;        ; move -> 1mb
  1198. ;        mov     si,movedesc-0x10000
  1199. ;        push    es
  1200. ;        push    ds
  1201. ;        pop     es
  1202. ;        mov     cx,256*18
  1203. ;        mov     ah,0x87
  1204. ;        int     0x15
  1205. ;        pop    es
  1206. ;
  1207. ;        test    ah,ah                  ; was the move successfull ?
  1208. ;        je      goodmove
  1209. ;        mov     dx,0x3f2              ; floppy motor off
  1210. ;        mov     al,0
  1211. ;        out     dx,al
  1212. ;        mov     si,memmovefailed-0x10000
  1213. ;        jmp    sayerr_plain
  1214. ;      goodmove:
  1215. ;
  1216. ;    add    dword [movedesc-0x10000+0x18+2], 512*18
  1217. ;        popa
  1218. ;        inc     dh
  1219. ;        cmp     dh,2
  1220. ;        jnz     bb2
  1221. ;        mov     dh,0
  1222. ;        inc     ch
  1223. ;        pusha                        ; print prosentage
  1224. ;        mov     si,pros-0x10000
  1225. ;    shr    ch, 2
  1226. ;    mov    al, '5'
  1227. ;    test    ch, 1
  1228. ;    jnz    @f
  1229. ;    mov    al, '0'
  1230. ;@@:
  1231. ;    mov    [si+1], al
  1232. ;    shr    ch, 1
  1233. ;    add    ch, '0'
  1234. ;    mov    [si], ch
  1235. ;        call    printplain
  1236. ;        popa
  1237. ;       bb2:
  1238. ;        pop     ax
  1239. ;        dec     ax
  1240. ;        push    ax
  1241. ;        jnz     reads
  1242. ;       readdone:
  1243. ;        pop     ax
  1244.         mov     si,backspace2-0x10000
  1245.         call    printplain
  1246.         mov     si,okt-0x10000
  1247.         call    printplain
  1248.        no_sys_on_floppy:
  1249.         xor    ax, ax        ; reset drive
  1250.         xor    dx, dx
  1251.         int     0x13
  1252.        mov dx,0x3f2 ; floppy motor off
  1253.        mov al,0
  1254.        out dx,al
  1255.  
  1256.  
  1257. ; SET GRAPHICS
  1258.  
  1259.         xor ax, ax
  1260.         mov es, ax
  1261.  
  1262.         mov   ax,[es:0x9008]        ; vga & 320x200
  1263.         mov    bx, ax
  1264.         cmp     ax,0x13
  1265.         je      setgr
  1266.         cmp     ax,0x12
  1267.         je      setgr
  1268.         mov     ax,0x4f02            ; Vesa
  1269. setgr:
  1270.         int     0x10
  1271.         test    ah,ah
  1272.         mov    si, fatalsel-0x10000
  1273.         jnz    sayerr
  1274. ; set mode 0x12 graphics registers:
  1275.         cmp     bx,0x12
  1276.         jne     gmok2
  1277.  
  1278.         mov     al,0x05
  1279.         mov     dx,0x03ce
  1280.         push    dx
  1281.         out     dx,al      ; select GDC mode register
  1282.         mov     al,0x02
  1283.         inc    dx
  1284.         out     dx,al      ; set write mode 2
  1285.  
  1286.         mov     al,0x02
  1287.         mov     dx,0x03c4
  1288.         out     dx,al      ; select VGA sequencer map mask register
  1289.         mov     al,0x0f
  1290.         inc    dx
  1291.         out     dx,al      ; set mask for all planes 0-3
  1292.  
  1293.         mov     al,0x08
  1294.         pop    dx
  1295.         out     dx,al      ; select GDC bit mask register
  1296.                            ; for writes to 0x03cf
  1297. gmok2:
  1298.         push    ds
  1299.         pop    es
  1300.