Subversion Repositories Kolibri OS

Rev

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

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