Subversion Repositories Kolibri OS

Rev

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

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