Subversion Repositories Kolibri OS

Rev

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

  1. $Revision: 514 $
  2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3. ;;                                                              ;;
  4. ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
  5. ;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa      ;;
  6. ;; Distributed under terms of the GNU General Public License    ;;
  7. ;;                                                              ;;
  8. ;;  BOOTCODE.INC                                                ;;
  9. ;;                                                              ;;
  10. ;;  KolibriOS 16-bit loader,                                    ;;
  11. ;;                        based on bootcode for MenuetOS        ;;
  12. ;;                                                              ;;
  13. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  14.  
  15.  
  16.  
  17. ;==========================================================================
  18. ;
  19. ;                           16 BIT FUNCTIONS
  20. ;
  21. ;==========================================================================
  22.  
  23.  
  24. putchar:
  25. ; in: al=character
  26.         mov     ah, 0Eh
  27.         mov     bh, 0
  28.         int     10h
  29.         ret
  30.  
  31. print:
  32. ; in: si->string
  33.         mov     al, 186
  34.         call    putchar
  35.         mov     al, ' '
  36.         call    putchar
  37.  
  38. printplain:
  39. ; in: si->string
  40.         pusha
  41.         lodsb
  42. @@:
  43.         call    putchar
  44.         lodsb
  45.         cmp     al, 0
  46.         jnz     @b
  47.         popa
  48.         ret
  49.  
  50. getkey:
  51. ; get number in range [bl,bh] (bl,bh in ['0'..'9'])
  52. ; in: bx=range
  53. ; out: ax=digit (1..9, 10 for 0)
  54.         mov     ah, 0
  55.         int     16h
  56.         cmp     al, bl
  57.         jb      getkey
  58.         cmp     al, bh
  59.         ja      getkey
  60.         push    ax
  61.         call    putchar
  62.         pop     ax
  63.         and     ax, 0Fh
  64.         jnz     @f
  65.         mov     al, 10
  66. @@:
  67.         ret
  68.  
  69. setcursor:
  70. ; in: dl=column, dh=row
  71.         mov     ah, 2
  72.         mov     bh, 0
  73.         int     10h
  74.         ret
  75.  
  76. macro _setcursor row,column
  77. {
  78.         mov     dx, row*256 + column
  79.         call    setcursor
  80. }
  81.  
  82. boot_read_floppy:
  83.         push    si
  84.         xor     si, si
  85.         mov     ah, 2   ; read
  86. @@:
  87.         push    ax
  88.         int     0x13
  89.         pop     ax
  90.         jnc     @f
  91.         inc     si
  92.         cmp     si, 10
  93.         jb      @b
  94.         mov     si, badsect
  95. sayerr_plain:
  96.         call    printplain
  97.         jmp     $
  98. @@:
  99.         pop     si
  100.         ret
  101.  
  102. ;=========================================================================
  103. ;
  104. ;                           16 BIT CODE
  105. ;
  106. ;=========================================================================
  107.  
  108.  
  109. start_of_code:
  110.         cld
  111. ; \begin{diamond}[02.12.2005]
  112. ; if bootloader sets ax = 'KL', then ds:si points to loader block
  113.         cmp     ax, 'KL'
  114.         jnz     @f
  115.         mov     word [cs:cfgmanager.loader_block], si
  116.         mov     word [cs:cfgmanager.loader_block+2], ds
  117. @@:
  118. ; \end{diamond}[02.12.2005]
  119.  
  120. ; if bootloader sets cx = 'HA' and dx = 'RD', then bx contains identifier of source hard disk
  121. ; (see comment to bx_from_load)
  122.         cmp     cx, 'HA'
  123.         jnz     no_hd_load
  124.         cmp     dx,'RD'
  125.         jnz     no_hd_load
  126.         mov     word [cs:bx_from_load], bx              ; {SPraid}[13.03.2007]
  127. no_hd_load:
  128.  
  129. ; set up stack
  130.         mov     ax, 3000h
  131.         mov     ss, ax
  132.         mov     sp, 0EC00h
  133. ; set up segment registers
  134.         push    cs
  135.         pop     ds
  136.         push    cs
  137.         pop     es
  138.  
  139. ; set videomode
  140.         mov     ax, 3
  141.         int     0x10
  142.  
  143. if lang eq ru
  144.  ; Load & set russian VGA font (RU.INC)
  145.         mov     bp, RU_FNT1             ; RU_FNT1 - First part
  146.         mov     bx, 1000h               ; 768 bytes
  147.         mov     cx, 30h                 ; 48 symbols
  148.         mov     dx, 80h                 ; 128 - position of first symbol
  149.         mov     ax, 1100h
  150.         int     10h
  151.  
  152.         mov     bp, RU_FNT2             ; RU_FNT2 -Second part
  153.         mov     bx, 1000h               ; 512 bytes
  154.         mov     cx, 20h                 ; 32 symbols
  155.         mov     dx, 0E0h                ; 224 - position of first symbol
  156.         mov     ax, 1100h
  157.         int     10h
  158.  ; End set VGA russian font
  159. else if lang eq et
  160.         mov     bp, ET_FNT              ; ET_FNT1
  161.         mov     bx, 1000h               ;
  162.         mov     cx, 255                 ; 256 symbols
  163.         xor     dx, dx                  ; 0 - position of first symbol
  164.         mov     ax, 1100h
  165.         int     10h
  166. end if
  167.  
  168. ; draw frames
  169.         push    0xb800
  170.         pop     es
  171.         xor     di, di
  172.         mov     ah, 1*16+15
  173.  
  174. ; draw top
  175.         mov     si, d80x25_top
  176.         mov     cx, d80x25_top_num * 80
  177. @@:
  178.         lodsb
  179.         stosw
  180.         loop    @b
  181. ; draw spaces
  182.         mov     si, space_msg
  183.         mov     dx, 25 - d80x25_top_num - d80x25_bottom_num
  184. dfl1:
  185.         push    si
  186.         mov     cx, 80
  187. @@:
  188.         lodsb
  189.         stosw
  190.         loop    @b
  191.         pop     si
  192.         dec     dx
  193.         jnz     dfl1
  194. ; draw bottom
  195.         mov     si, d80x25_bottom
  196.         mov     cx, d80x25_bottom_num * 80
  197. @@:
  198.         lodsb
  199.         stosw
  200.         loop    @b
  201.  
  202.         mov     byte [space_msg+80], 0    ; now space_msg is null terminated
  203.  
  204.         _setcursor d80x25_top_num,0
  205.  
  206.  
  207. ; TEST FOR 386+
  208.  
  209.         mov     bx, 0x4000
  210.         pushf
  211.         pop     ax
  212.         mov     dx, ax
  213.         xor     ax, bx
  214.         push    ax
  215.         popf
  216.         pushf
  217.         pop     ax
  218.         and     ax, bx
  219.         and     dx, bx
  220.         cmp     ax, dx
  221.         jnz     cpugood
  222.         mov     si, not386
  223. sayerr:
  224.         call    print
  225.         jmp     $
  226.      cpugood:
  227.  
  228.         push    0
  229.         popf
  230.         sti
  231.  
  232. ; set up esp
  233.         movzx   esp, sp
  234.  
  235.         push    0
  236.         pop     es
  237.         and     word [es:0x9031], 0
  238. ; \begin{Mario79}
  239. ; find HDD IDE DMA PCI device
  240. ; check for PCI BIOS
  241.         mov     ax, 0xB101
  242.         int     0x1A
  243.         jc      .nopci
  244.         cmp     edx, 'PCI '
  245.         jnz     .nopci
  246. ; find PCI class code
  247. ; class 1 = mass storage
  248. ; subclass 1 = IDE controller
  249. ; a) class 1, subclass 1, programming interface 0x80
  250.         mov     ax, 0xB103
  251.         mov     ecx, 1*10000h + 1*100h + 0x80
  252.         xor     si, si  ; device index = 0
  253.         int     0x1A
  254.         jnc     .found
  255. ; b) class 1, subclass 1, programming interface 0x8A
  256.         mov     ax, 0xB103
  257.         mov     ecx, 1*10000h + 1*100h + 0x8A
  258.         xor     si, si  ; device index = 0
  259.         int     0x1A
  260.         jnc     .found
  261. ; c) class 1, subclass 1, programming interface 0x85
  262.         mov     ax, 0xB103
  263.         mov     ecx, 1*10000h + 1*100h + 0x85
  264.         xor     si, si
  265.         int     0x1A
  266.         jc      .nopci
  267. .found:
  268. ; get memory base
  269.         mov     ax, 0xB10A
  270.         mov     di, 0x20        ; memory base is config register at 0x20
  271.         int     0x1A
  272.         jc      .nopci
  273.         and     cx, 0xFFF0      ; clear address decode type
  274.         mov     [es:0x9031], cx
  275. .nopci:
  276. ; \end{Mario79}
  277.  
  278.         mov     al, 0xf6        ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå
  279.         out     0x60, al
  280.         xor     cx, cx
  281. wait_loop:       ; variant 2
  282. ; reading state of port of 8042 controller
  283.         in      al, 64h
  284.         and     al, 00000010b  ; ready flag
  285. ; wait until 8042 controller is ready
  286.         loopnz  wait_loop
  287.  
  288. ; --------------- APM ---------------------
  289.         and     word [es:0x9044], 0     ; ver = 0.0 (APM not found)
  290.         mov     ax, 0x5300
  291.         xor     bx, bx
  292.         int     0x15
  293.         jc      apm_end                 ; APM not found
  294.         test    cx, 2
  295.         jz      apm_end                 ; APM 32-bit protected-mode interface not supported
  296.         mov     [es:0x9044], ax         ; Save APM Version
  297.         mov     [es:0x9046], cx         ; Save APM flags
  298.  
  299.         ; Write APM ver ----
  300.         and     ax, 0xf0f
  301.         add     ax, '00'
  302.         mov     si, msg_apm
  303.         mov     [si + 5], ah
  304.         mov     [si + 7], al
  305.         _setcursor 0, 3
  306.         call    printplain
  307.         ; ------------------
  308.  
  309.         mov     ax, 0x5304              ; Disconnect interface
  310.         xor     bx, bx
  311.         int     0x15
  312.         mov     ax, 0x5303              ; Connect 32 bit mode interface
  313.         xor     bx, bx
  314.         int     0x15
  315.  
  316.         mov     [es:0x9040], ebx
  317.         mov     [es:0x9050], ax
  318.         mov     [es:0x9052], cx
  319.         mov     [es:0x9054], dx
  320.  
  321. apm_end:
  322.         _setcursor d80x25_top_num, 0
  323.  
  324. ; DISPLAY VESA INFORMATION
  325.  
  326.         mov     ax, 0x4f00
  327.         mov     di, 0xa000
  328.         int     0x10
  329.         cmp     ax, 0x004f
  330.         mov     si, novesa
  331.         jnz     @f
  332.         mov     ax, [es:di+4]
  333.         add     ax, '0'*256+'0'
  334.         mov     si, vervesa
  335.         mov     [si+vervesa_off], ah
  336.         mov     [si+vervesa_off+2], al
  337. @@:     call    print
  338.  
  339. ; \begin{diamond}[30.11.2005]
  340. cfgmanager:
  341. ; settings:
  342. ; a) preboot_graph = graphical mode
  343. ;    preboot_gprobe = probe this mode?
  344. ; b) preboot_dma  = use DMA access?
  345. ; c) preboot_vrrm = use VRR?
  346. ; d) preboot_device = from what boot?
  347.         mov     di, preboot_graph
  348. ; check bootloader block
  349.         cmp     [.loader_block], -1
  350.         jz      .noloaderblock
  351.         les     bx, [.loader_block]
  352.         cmp     byte [es:bx], 1
  353.         mov     si, loader_block_error
  354.         jnz     sayerr
  355.         test    byte [es:bx+1], 1
  356.         jz      @f
  357. ; image in memory present
  358.         cmp     [di+preboot_device-preboot_graph], 0
  359.         jnz     @f
  360.         mov     [di+preboot_device-preboot_graph], 3
  361. @@:
  362. .noloaderblock:
  363. ; determine default settings
  364.         mov     [.bSettingsChanged], 0
  365.         cmp     byte [di], 0
  366.         jnz     .preboot_gr_end
  367.         mov     [di+preboot_gprobe-preboot_graph], 0
  368.         mov     al, [vervesa+vervesa_off]
  369.         cmp     al, 'x'
  370.         jz      .novesa
  371.         cmp     al, '1'
  372.         jz      .vesa12
  373.         mov     [di+preboot_gprobe-preboot_graph], 2
  374.         mov     al, 3
  375.         jmp     @f
  376. .vesa12:
  377.         mov     al, 7
  378.         jmp     @f
  379. .novesa:
  380.         mov     al, 10
  381. @@:
  382.         mov     [di], al
  383. .preboot_gr_end:
  384. ; following 6 lines set variables to 1 if its current value is 0
  385.         cmp     [di+preboot_dma-preboot_graph], 1
  386.         adc     [di+preboot_dma-preboot_graph], 0
  387.         cmp     [di+preboot_vrrm-preboot_graph], 1
  388.         adc     [di+preboot_vrrm-preboot_graph], 0
  389.         cmp     [di+preboot_device-preboot_graph], 1
  390.         adc     [di+preboot_device-preboot_graph], 0
  391. ; notify user
  392.         mov     si, linef
  393.         call    print
  394.         mov     si, start_msg
  395.         call    print
  396.         mov     si, time_msg
  397.         call    print
  398. ; get start time
  399.         call    .gettime
  400.         mov     [.starttime], eax
  401.         mov     word [.timer], .newtimer
  402.         mov     word [.timer+2], cs
  403. .printcfg:
  404.         _setcursor 9,0
  405.         mov     si, current_cfg_msg
  406.         call    print
  407.         mov     si, curvideo_msg
  408.         call    print
  409.         mov     al, [preboot_graph]
  410.         cmp     al, 8
  411.         ja      .pnovesa
  412.         mov     dl, al
  413.         and     eax, 3
  414.         mov     si, [modes_msg+eax*2]
  415.         call    printplain
  416.         mov     si, modevesa20
  417.         cmp     dl, 4
  418.         jbe     @f
  419.         mov     si, modevesa12
  420. @@:
  421.         call    printplain
  422.         cmp     dl, 4
  423.         ja      .x
  424.         mov     si, probeno_msg
  425.         cmp     [preboot_gprobe], 2
  426.         jnz     @f
  427.         mov     si, probeok_msg
  428. @@:
  429.         call    printplain
  430. .x:
  431.         jmp     .c
  432. .pnovesa:
  433.         cmp     al, 9
  434.         mov     si, mode9
  435.         jz      @b
  436.         mov     si, mode10
  437.         jmp     @b
  438. .c:
  439.         mov     si, linef
  440.         call    printplain
  441.         mov     si, dma_msg
  442.         call    print
  443.         cmp     [preboot_dma], 2
  444.         mov     si, on_msg
  445.         jb      @f
  446.         mov     si, off_msg
  447.         ja      @f
  448.         mov     si, readonly_msg
  449. @@:
  450.         call    printplain
  451.         mov     si, vrrm_msg
  452.         cmp     [preboot_vrrm], 1
  453.         call    .say_on_off
  454.         mov     si, preboot_device_msg
  455.         call    print
  456.         mov     al, [preboot_device]
  457.         and     eax, 3
  458.         mov     si, [preboot_device_msgs+eax*2]
  459.         call    printplain
  460. .wait:
  461.         _setcursor 25,0         ; out of screen
  462. ; set timer interrupt handler
  463.         cli
  464.         push    0
  465.         pop     es
  466.         mov     eax, [es:8*4]
  467.         mov     [.oldtimer], eax
  468.         mov     eax, [.timer]
  469.         mov     [es:8*4], eax
  470.         sti
  471. ; wait for keypressed
  472.         mov     ah, 0
  473.         int     16h
  474.         push    ax
  475. ; restore timer interrupt
  476.         push    0
  477.         pop     es
  478.         mov     eax, [.oldtimer]
  479.         mov     [es:8*4], eax
  480.         mov     [.timer], eax
  481.         _setcursor 7,0
  482.         mov     si, space_msg
  483.         call    printplain
  484.         pop     ax
  485. ; switch on key
  486.         cmp     al, 13
  487.         jz      .continue
  488.         or      al, 20h
  489.         cmp     al, 'a'
  490.         jz      .change_a
  491.         cmp     al, 'b'
  492.         jz      .change_b
  493.         cmp     al, 'c'
  494.         jz      .change_c
  495.         cmp     al, 'd'
  496.         jnz     .wait
  497.         _setcursor 15,0
  498.         mov     si, bdev
  499.         call    print
  500.         mov     bx, '13'
  501.         call    getkey
  502.         mov     [preboot_device], al
  503.         _setcursor 13,0
  504. .d:
  505.         mov     [.bSettingsChanged], 1
  506.         mov     si, space_msg
  507.         call    printplain
  508.         _setcursor 15,0
  509.         mov     cx, 6
  510. @@:
  511.         call    printplain
  512.         loop    @b
  513.         jmp    .printcfg
  514. .change_a:
  515.         _setcursor 15,0
  516.         mov     si, gr_mode
  517.         call    printplain
  518.         mov     bx, '09'
  519.         call    getkey
  520.         mov     [preboot_graph], al
  521.         cmp     al, 4
  522.         ja      @f
  523.         mov     si, probetext
  524.         call    printplain
  525.         mov     bx, '12'
  526.         call    getkey
  527.         mov     [preboot_gprobe], al
  528. @@:
  529.         _setcursor 10,0
  530.         jmp    .d
  531. .change_b:
  532.         _setcursor 15,0
  533.         mov     si, ask_dma
  534.         call    print
  535.         mov     bx, '13'
  536.         call    getkey
  537.         mov     [preboot_dma], al
  538.         _setcursor 11,0
  539.         jmp     .d
  540. .change_c:
  541.         _setcursor 15,0
  542.         mov     si, vrrmprint
  543.         call    print
  544.         mov     bx, '12'
  545.         call    getkey
  546.         mov     [preboot_vrrm], al
  547.         _setcursor 12,0
  548.         jmp     .d
  549. .say_on_off:
  550.         pushf
  551.         call    print
  552.         mov     si, on_msg
  553.         popf
  554.         jz      @f
  555.         mov     si, off_msg
  556. @@:     jmp     printplain
  557. ; novesa and vervesa strings are not used at the moment of executing this code
  558. virtual at novesa
  559. .oldtimer dd ?
  560. .starttime dd ?
  561. .bSettingsChanged db ?
  562. .timer dd ?
  563. end virtual
  564. .loader_block dd -1
  565. .gettime:
  566.         mov     ah, 0
  567.         int     1Ah
  568.         xchg    ax, cx
  569.         shl     eax, 10h
  570.         xchg    ax, dx
  571.         ret
  572. .newtimer:
  573.         push    ds
  574.         push    cs
  575.         pop     ds
  576.         pushf
  577.         call    [.oldtimer]
  578.         pushad
  579.         call    .gettime
  580.         sub     eax, [.starttime]
  581.         sub     ax, 18*5
  582.         jae     .timergo
  583.         neg     ax
  584.         add     ax, 18-1
  585.         mov     bx, 18
  586.         xor     dx, dx
  587.         div     bx
  588. if lang eq ru
  589. ; ¯®¤®¦¤¨â¥ 5 ᥪ㭤, 4/3/2 ᥪ㭤ë, 1 ᥪ㭤ã
  590.         cmp     al, 5
  591.         mov     cl, ' '
  592.         jae     @f
  593.         cmp     al, 1
  594.         mov     cl, 'ã'
  595.         jz      @f
  596.         mov     cl, 'ë'
  597. @@:     mov     [time_str+9], cl
  598. else if lang eq et
  599.         cmp     al, 1
  600.         ja      @f
  601.         mov     [time_str+9], ' '
  602.         mov     [time_str+10],' '
  603. @@:
  604. else
  605. ; wait 5/4/3/2 seconds, 1 second
  606.         cmp     al, 1
  607.         mov     cl, 's'
  608.         ja      @f
  609.         mov     cl, ' '
  610. @@:     mov     [time_str+9], cl
  611. end if
  612.         add     al, '0'
  613.         mov     [time_str+1], al
  614.         mov     si, time_msg
  615.         _setcursor 7,0
  616.         call    print
  617.         _setcursor 25,0
  618.         popad
  619.         pop     ds
  620.         iret
  621. .timergo:
  622.         push    0
  623.         pop     es
  624.         mov     eax, [.oldtimer]
  625.         mov     [es:8*4], eax
  626.         mov     sp, 0EC00h
  627. .continue:
  628.         sti
  629.         _setcursor 6,0
  630.         mov     si, space_msg
  631.         call    printplain
  632.         call    printplain
  633.         _setcursor 6,0
  634.         mov     si, loading_msg
  635.         call    print
  636.         _setcursor 15,0
  637.         cmp     [.bSettingsChanged], 0
  638.         jz      .load
  639.         cmp     [.loader_block], -1
  640.         jz      .load
  641.         les     bx, [.loader_block]
  642.         mov     eax, [es:bx+3]
  643.         push    ds
  644.         pop     es
  645.         test    eax, eax
  646.         jz      .load
  647.         push    eax
  648.         mov     si, save_quest
  649.         call    print
  650. .waityn:
  651.         mov     ah, 0
  652.         int     16h
  653.         or      al, 20h
  654.         cmp     al, 'n'
  655.         jz      .loadc
  656.         cmp     al, 'y'
  657.         jnz     .waityn
  658.         call    putchar
  659.         mov     byte [space_msg+80], 186
  660.         pop     eax
  661.         push    cs
  662.         push    .cont
  663.         push    eax
  664.         retf
  665. .loadc:
  666.         pop     eax
  667. .cont:
  668.         push    cs
  669.         pop     ds
  670.         mov     si, space_msg
  671.         mov     byte [si+80], 0
  672.         _setcursor 15,0
  673.         call    printplain
  674.         _setcursor 15,0
  675. .load:
  676. ; \end{diamond}[02.12.2005]
  677.  
  678. ; ASK GRAPHICS MODE
  679.  
  680.         movzx   ax, [preboot_graph]
  681.         push    0
  682.         pop     es
  683. ; address is gr_table+6*(ax-1)
  684.         add     ax, ax
  685.         lea     si, [gr_table + eax + eax*2 - 6]
  686.         mov     bx, [si+0]
  687.         mov     cx, [si+2]
  688.         mov     dx, [si+4]
  689.         cmp     al, 9*2
  690.         mov     al, 32    ; BPP
  691.         jb      @f
  692.         mov     [es:0x9000], al
  693.         or      dword [es:0x9018], 0xFFFFFFFF; 0x800000
  694. @@:
  695.         mov     [es:0x9008], bx
  696.         mov     [es:0x900A], cx
  697.         mov     [es:0x900C], dx
  698.         test    bh, bh
  699.         jz      nov
  700.  
  701. ; USE DEFAULTS OR PROBE
  702.  
  703. ; bx - mode : cx - x size : dx - y size
  704.         cmp     [preboot_gprobe], 1
  705.         jz      noprobe
  706.  
  707.         mov     bx, 0x100
  708.      newprobe:
  709.         inc     bx
  710.         cmp     bx, 0x17f
  711.         mov     si, prnotfnd
  712.         jz      invalid_video_mode
  713.  
  714.      probemore:
  715.         push    cx
  716.         mov     ax, 0x4f01
  717.         mov     cx, bx
  718.         mov     di, 0xa000
  719.         int     0x10
  720.         pop     cx
  721.  
  722.         test    byte [es:di], 80h    ; lfb?
  723.         jz      newprobe
  724.         cmp     [es:di+0x12], cx    ; x size?
  725.         jnz     newprobe
  726.         cmp     [es:di+0x14], dx    ; y size?
  727.         jnz     newprobe
  728.         cmp     byte [es:di+0x19], 32 ;24
  729.         jb      newprobe
  730.  
  731. ;       add     bx, 0100000000000000b
  732.         or      bh, 40h
  733.         mov     [es:0x9008], bx
  734.  
  735.      noprobe:
  736.  
  737.  
  738. ; FIND VESA 2.0 LFB & BPP
  739.  
  740.         mov     ax, 0x4f01
  741.         mov     cx, bx
  742.         and     cx, 0xfff
  743.         mov     di, 0xa000
  744.         int     0x10
  745.         ; LFB
  746.         mov     eax, [es:di+0x28]
  747.         mov     [es:0x9018], eax
  748.         ; ---- vbe voodoo
  749.         BytesPerLine equ 0x10
  750.         mov     ax, [es:di+BytesPerLine]
  751.         mov     [es:0x9001], ax
  752.         ; BPP
  753.         mov     al, byte [es:di+0x19]
  754.         mov     [es:0x9000], al
  755. nov:
  756.         cmp     al, 24
  757.         mov     si, bt24
  758.         jz      bppl
  759.         cmp     al, 32
  760.         mov     si, bt32
  761.         jz      bppl
  762.         mov     si, btns
  763. invalid_video_mode:
  764.         call    print
  765.         _setcursor (d80x25_top_num+2), 0
  766.         mov     si, start_msg
  767.         call    print
  768.         jmp     cfgmanager.printcfg
  769. bppl:
  770.         call    print
  771.  
  772.  
  773. ; FIND VESA 1.2 PM BANK SWITCH ADDRESS
  774.  
  775.         push    es
  776.         mov     ax, 0x4f0A
  777.         xor     bx, bx
  778.         int     0x10
  779.         xor     eax, eax
  780.         mov     ax, es
  781.         shl     eax, 4
  782.         movzx   ebx, di
  783.         add     eax, ebx
  784.         mov     bx, [es:di]
  785.         add     eax, ebx
  786.         pop     es
  787.         mov     [es:0x9014], eax
  788.  
  789.  
  790. ; GRAPHICS ACCELERATION
  791. ; force yes
  792.         mov     [es:0x901C], byte 1
  793.  
  794. ; DMA ACCESS TO HD
  795.  
  796.         mov     al, [preboot_dma]
  797.         mov     [es:0x901F], al
  798.  
  799. ; VRR_M USE
  800.  
  801.         mov     al,[preboot_vrrm]
  802.         mov     [es:0x9030], al
  803.         mov     [es:0x901E], byte 1
  804.  
  805. ; BOOT DEVICE
  806.  
  807.         mov     al, [preboot_device]
  808.         dec     al
  809.         mov     [boot_dev], al
  810.  
  811. ; READ DISKETTE TO MEMORY
  812.  
  813. ;        cmp     [boot_dev],0
  814.         jne     no_sys_on_floppy
  815.         mov     si,diskload
  816.         call    print
  817.         xor     ax, ax            ; reset drive
  818.         xor     dx, dx
  819.         int     0x13
  820. ; now load floppy image to memory
  821. ; at first load boot sector and first FAT table
  822.         mov     cx, 0x0001      ; startcyl,startsector
  823.         xor     dx, dx          ; starthead,drive
  824.         mov     al, 1+9         ; no of sectors to read
  825.         mov     bx, 0xB000      ; es:bx -> data area
  826.         call    boot_read_floppy
  827. ; and copy them to extended memory
  828.         mov     si, movedesc
  829.         mov     [si+8*2+3], bh
  830.         push    es
  831.         push    ds
  832.         pop     es
  833.         mov     cx, 256*10
  834.         mov     ah, 0x87
  835.         int     0x15
  836.         test    ah, ah
  837.         jz      @f
  838. sayerr_floppy:
  839.         mov     dx, 0x3f2
  840.         mov     al, 0
  841.         out     dx, al
  842.         mov     si, memmovefailed
  843.         jmp     sayerr_plain
  844. @@:
  845.         add     dword [si+8*3+2], 512*10
  846. ; copy FAT to second copy
  847.         mov     byte [si+8*2+3], 0xB2
  848.         mov     cx, 256*9
  849.         mov     ah, 0x87
  850.         int     0x15
  851.         pop     es
  852.         test    ah, ah
  853.         jnz     sayerr_floppy
  854.         add     dword [si+8*3+2], 512*9
  855. ; calculate total number of sectors to read
  856.         mov     ax, 1+9+14      ; boot+FAT+root
  857.         mov     di, 0xB203
  858. .calc_loop:
  859.         test    word [es:di], 0xFFF
  860.         jz      @f
  861.         inc     ax
  862. @@:
  863.         test    word [es:di+1], 0xFFF0
  864.         jz      @f
  865.         inc     ax
  866. @@:
  867.         add     di, 3
  868.         cmp     di, 0xB200+1440*3
  869.         jb      .calc_loop
  870.         push    ax
  871.         mov     bp, 1+9         ; already read sectors
  872. ; now read rest
  873.         mov     byte [si+8*2+3], 0xA0
  874.         mov     di, 2-14        ; absolute sector-31
  875.         mov     cx, 0x0002      ; cylinder=0, sector=2
  876.         mov     dx, 0x0100      ; head=1, disk=0
  877. .read_loop:
  878. ; determine whether sector must be read
  879.         cmp     di, 2
  880.         jl      .read
  881.         mov     bx, di
  882.         shr     bx, 1
  883.         jnc     .even
  884.         test    word [es:bx+di+0xB200], 0xFFF0
  885.         jmp     @f
  886. .even:
  887.         test    word [es:bx+di+0xB200], 0xFFF
  888. @@:
  889.         jz      .skip
  890. .read:
  891.         mov     bx, 0xA000
  892.         mov     al, 1           ; 1 sector
  893.         call    boot_read_floppy
  894.         inc     bp
  895.         push    es
  896.         push    ds
  897.         pop     es
  898.         pusha
  899.         mov     cx, 256
  900.         mov     ah, 0x87
  901.         int     0x15
  902.         test    ah, ah
  903.         popa
  904.         pop     es
  905.         jnz     sayerr_floppy
  906. .skip:
  907.         add     dword [si+8*3+2], 512
  908.         inc     cx
  909.         cmp     cl, 19
  910.         jnz     @f
  911.         mov     cl, 1
  912.         inc     dh
  913.         cmp     dh, 2
  914.         jnz     @f
  915.         mov     dh, 0
  916.         inc     ch
  917. @@:
  918.         pop     ax
  919.         push    ax
  920.         pusha
  921. ; draw percentage
  922. ; total sectors: ax
  923. ; read sectors: bp
  924.         xchg    ax, bp
  925.         mov     cx, 100
  926.         mul     cx
  927.         div     bp
  928.         aam
  929.         xchg    al, ah
  930.         add     ax, '00'
  931.         mov     si, pros
  932.         cmp     [si], ax
  933.         jz      @f
  934.         mov     [si], ax
  935.         call    printplain
  936. @@:
  937.         popa
  938.         inc     di
  939.         cmp     di, 2880-31
  940.         jnz     .read_loop
  941.  
  942. ;        mov     cx, 0x0001      ; startcyl,startsector
  943. ;        xor     dx, dx          ; starthead,drive
  944. ;        push    word 80*2               ; read no of sect
  945. ;       reads:
  946. ;        pusha
  947. ;        xor     si,si
  948. ;       newread:
  949. ;        mov     bx,0xa000               ; es:bx -> data area
  950. ;        mov     ax,0x0200+18            ; read, no of sectors to read
  951. ;        int     0x13
  952. ;        test    ah, ah
  953. ;        jz      goodread
  954. ;        inc    si
  955. ;        cmp     si,10
  956. ;        jnz     newread
  957. ;        mov     si,badsect-0x10000
  958. ;sayerr_plain:
  959. ;        call    printplain
  960. ;        jmp     $
  961. ;       goodread:
  962. ;        ; move -> 1mb
  963. ;        mov     si,movedesc-0x10000
  964. ;        push    es
  965. ;        push    ds
  966. ;        pop     es
  967. ;        mov     cx,256*18
  968. ;        mov     ah,0x87
  969. ;        int     0x15
  970. ;        pop    es
  971. ;
  972. ;        test    ah,ah                  ; was the move successfull ?
  973. ;        je      goodmove
  974. ;        mov     dx,0x3f2              ; floppy motor off
  975. ;        mov     al,0
  976. ;        out     dx,al
  977. ;        mov     si,memmovefailed-0x10000
  978. ;        jmp    sayerr_plain
  979. ;      goodmove:
  980. ;
  981. ;    add    dword [movedesc-0x10000+0x18+2], 512*18
  982. ;        popa
  983. ;        inc     dh
  984. ;        cmp     dh,2
  985. ;        jnz     bb2
  986. ;        mov     dh,0
  987. ;        inc     ch
  988. ;        pusha                        ; print prosentage
  989. ;        mov     si,pros-0x10000
  990. ;    shr    ch, 2
  991. ;    mov    al, '5'
  992. ;    test    ch, 1
  993. ;    jnz    @f
  994. ;    mov    al, '0'
  995. ;@@:
  996. ;    mov    [si+1], al
  997. ;    shr    ch, 1
  998. ;    add    ch, '0'
  999. ;    mov    [si], ch
  1000. ;        call    printplain
  1001. ;        popa
  1002. ;       bb2:
  1003. ;        pop     ax
  1004. ;        dec     ax
  1005. ;        push    ax
  1006. ;        jnz     reads
  1007. ;       readdone:
  1008. ;        pop     ax
  1009.  
  1010.         mov     si, backspace2
  1011.         call    printplain
  1012.         mov     si, okt
  1013.         call    printplain
  1014. no_sys_on_floppy:
  1015.         xor     ax, ax          ; reset drive
  1016.         xor     dx, dx
  1017.         int     0x13
  1018.         mov     dx, 0x3f2       ; floppy motor off
  1019.         mov     al, 0
  1020.         out     dx, al
  1021.  
  1022.  
  1023. ; SET GRAPHICS
  1024.  
  1025.         xor     ax, ax
  1026.         mov     es, ax
  1027.  
  1028.         mov     ax, [es:0x9008]         ; vga & 320x200
  1029.         mov     bx, ax
  1030.         cmp     ax, 0x13
  1031.         je      setgr
  1032.         cmp     ax, 0x12
  1033.         je      setgr
  1034.         mov     ax, 0x4f02              ; Vesa
  1035. setgr:
  1036.         int     0x10
  1037.         test    ah, ah
  1038.         mov     si, fatalsel
  1039.         jnz     sayerr
  1040. ; set mode 0x12 graphics registers:
  1041.         cmp     bx, 0x12
  1042.         jne     gmok2
  1043.  
  1044.         mov     al, 0x05
  1045.         mov     dx, 0x03ce
  1046.         push    dx
  1047.         out     dx, al      ; select GDC mode register
  1048.         mov     al, 0x02
  1049.         inc     dx
  1050.         out     dx, al      ; set write mode 2
  1051.  
  1052.         mov     al, 0x02
  1053.         mov     dx, 0x03c4
  1054.         out     dx, al      ; select VGA sequencer map mask register
  1055.         mov     al, 0x0f
  1056.         inc     dx
  1057.         out     dx, al      ; set mask for all planes 0-3
  1058.  
  1059.         mov     al, 0x08
  1060.         pop     dx
  1061.         out     dx, al      ; select GDC bit mask register
  1062.                            ; for writes to 0x03cf
  1063. gmok2:
  1064.         push    ds
  1065.         pop     es
  1066.