Subversion Repositories Kolibri OS

Rev

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

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