Subversion Repositories Kolibri OS

Rev

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

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