Subversion Repositories Kolibri OS

Rev

Rev 420 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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