Subversion Repositories Kolibri OS

Rev

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