Subversion Repositories Kolibri OS

Rev

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