Subversion Repositories Kolibri OS

Rev

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