Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
  4. ;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa      ;;
  5. ;; Distributed under terms of the GNU General Public License    ;;
  6. ;;                                                              ;;
  7. ;;  BOOTCODE.INC                                                ;;
  8. ;;                                                              ;;
  9. ;;  KolibriOS 16-bit loader,                                    ;;
  10. ;;                        based on bootcode for MenuetOS        ;;
  11. ;;                                                              ;;
  12. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  13.  
  14. $Revision: 1508 $
  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.         test    al,al
  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. ; convert abs. sector number (AX) to BIOS T:H:S
  103. ; sector number = (abs.sector%BPB_SecPerTrk)+1
  104. ; pre.track number = (abs.sector/BPB_SecPerTrk)
  105. ; head number = pre.track number%BPB_NumHeads
  106. ; track number = pre.track number/BPB_NumHeads
  107. ; Return: cl - sector number
  108. ;         ch - track number
  109. ;         dl - drive number (0 = a:)
  110. ;         dh - head number
  111. conv_abs_to_THS:
  112.         push    bx
  113.         mov     bx,word [BPB_SecPerTrk]
  114.         xor     dx,dx
  115.         div     bx
  116.         inc     dx
  117.         mov     cl, dl                          ; cl = sector number
  118.         mov     bx,word [BPB_NumHeads]
  119.         xor     dx,dx
  120.         div     bx
  121.         ; !!!!!!! ax = track number, dx = head number
  122.         mov     ch,al                           ; ch=track number
  123.         xchg    dh,dl                           ; dh=head number
  124.         mov     dl,0                            ; dl=0 (drive 0 (a:))
  125.         pop     bx
  126.         retn
  127. ; needed variables
  128. BPB_SecPerTrk   dw      0                       ; sectors per track
  129. BPB_NumHeads    dw      0                       ; number of heads
  130. BPB_FATSz16     dw      0                       ; size of FAT
  131. BPB_RootEntCnt  dw      0                       ; count of root dir. entries
  132. BPB_BytsPerSec  dw      0                       ; bytes per sector
  133. BPB_RsvdSecCnt  dw      0                       ; number of reserved sectors
  134. BPB_TotSec16    dw      0                       ; count of the sectors on the volume
  135. BPB_SecPerClus  db      0                       ; number of sectors per cluster
  136. BPB_NumFATs     db      0                       ; number of FAT tables
  137. abs_sector_adj  dw      0                       ; adjustment to make abs. sector number
  138. end_of_FAT      dw      0                       ; end of FAT table
  139. FirstDataSector dw      0                       ; begin of data
  140.  
  141. ;=========================================================================
  142. ;
  143. ;                           16 BIT CODE
  144. ;
  145. ;=========================================================================
  146.  
  147. include 'bootvesa.inc'                 ;Include source for boot vesa
  148.  
  149. start_of_code:
  150.         cld
  151. ; \begin{diamond}[02.12.2005]
  152. ; if bootloader sets ax = 'KL', then ds:si points to loader block
  153.         cmp     ax, 'KL'
  154.         jnz     @f
  155.         mov     word [cs:cfgmanager.loader_block], si
  156.         mov     word [cs:cfgmanager.loader_block+2], ds
  157. @@:
  158. ; \end{diamond}[02.12.2005]
  159.  
  160. ; if bootloader sets cx = 'HA' and dx = 'RD', then bx contains identifier of source hard disk
  161. ; (see comment to bx_from_load)
  162.         cmp     cx, 'HA'
  163.         jnz     no_hd_load
  164.         cmp     dx,'RD'
  165.         jnz     no_hd_load
  166.         mov     word [cs:bx_from_load], bx              ; {SPraid}[13.03.2007]
  167. no_hd_load:
  168.  
  169. ; set up stack
  170.         mov     ax, 3000h
  171.         mov     ss, ax
  172.         mov     sp, 0EC00h
  173. ; set up segment registers
  174.         push    cs
  175.         pop     ds
  176.         push    cs
  177.         pop     es
  178.  
  179. ; set videomode
  180.         mov     ax, 3
  181.         int     0x10
  182.  
  183. if lang eq ru
  184.  ; Load & set russian VGA font (RU.INC)
  185.         mov     bp, RU_FNT1             ; RU_FNT1 - First part
  186.         mov     bx, 1000h               ; 768 bytes
  187.         mov     cx, 30h                 ; 48 symbols
  188.         mov     dx, 80h                 ; 128 - position of first symbol
  189.         mov     ax, 1100h
  190.         int     10h
  191.  
  192.         mov     bp, RU_FNT2             ; RU_FNT2 -Second part
  193.         mov     bx, 1000h               ; 512 bytes
  194.         mov     cx, 20h                 ; 32 symbols
  195.         mov     dx, 0E0h                ; 224 - position of first symbol
  196.         mov     ax, 1100h
  197.         int     10h
  198.  ; End set VGA russian font
  199. end if
  200.  
  201. ; draw frames
  202.         push    0xb800
  203.         pop     es
  204.         xor     di, di
  205.         mov     ah, 1*16+15
  206.  
  207. ; draw top
  208.         mov     si, d80x25_top
  209.         mov     cx, d80x25_top_num * 80
  210. @@:
  211.         lodsb
  212.         stosw
  213.         loop    @b
  214. ; draw spaces
  215.         mov     si, space_msg
  216.         mov     dx, 25 - d80x25_top_num - d80x25_bottom_num
  217. dfl1:
  218.         push    si
  219.         mov     cx, 80
  220. @@:
  221.         lodsb
  222.         stosw
  223.         loop    @b
  224.         pop     si
  225.         dec     dx
  226.         jnz     dfl1
  227. ; draw bottom
  228.         mov     si, d80x25_bottom
  229.         mov     cx, d80x25_bottom_num * 80
  230. @@:
  231.         lodsb
  232.         stosw
  233.         loop    @b
  234.  
  235.         mov     byte [space_msg+80], 0    ; now space_msg is null terminated
  236.  
  237.         _setcursor d80x25_top_num,0
  238.  
  239.  
  240. ; TEST FOR 386+
  241.         jmp     cpugood
  242. ;        mov     bx, 0x4000
  243. ;        pushf
  244. ;        pop     ax
  245. ;        mov     dx, ax
  246. ;        xor     ax, bx
  247. ;        push    ax
  248. ;        popf
  249. ;        pushf
  250. ;        pop     ax
  251. ;        and     ax, bx
  252. ;        and     dx, bx
  253. ;        cmp     ax, dx
  254. ;        jnz     cpugood
  255. ;        mov     si, not386
  256. sayerr:
  257.         call    print
  258.         jmp     $
  259.      cpugood:
  260.  
  261.         push    0
  262.         popf
  263.         sti
  264.  
  265. ; set up esp
  266.         movzx   esp, sp
  267.  
  268.         push    0
  269.         pop     es
  270.         and     word [es:0x9031], 0
  271. ; \begin{Mario79}
  272. ; find HDD IDE DMA PCI device
  273. ; check for PCI BIOS
  274.         mov     ax, 0xB101
  275.         int     0x1A
  276.         jc      .nopci
  277.         cmp     edx, 'PCI '
  278.         jnz     .nopci
  279. ; find PCI class code
  280. ; class 1 = mass storage
  281. ; subclass 1 = IDE controller
  282. ; a) class 1, subclass 1, programming interface 0x80
  283.         mov     ax, 0xB103
  284.         mov     ecx, 1*10000h + 1*100h + 0x80
  285.         xor     si, si  ; device index = 0
  286.         int     0x1A
  287.         jnc     .found
  288. ; b) class 1, subclass 1, programming interface 0x8A
  289.         mov     ax, 0xB103
  290.         mov     ecx, 1*10000h + 1*100h + 0x8A
  291.         xor     si, si  ; device index = 0
  292.         int     0x1A
  293.         jnc     .found
  294. ; c) class 1, subclass 1, programming interface 0x85
  295.         mov     ax, 0xB103
  296.         mov     ecx, 1*10000h + 1*100h + 0x85
  297.         xor     si, si
  298.         int     0x1A
  299.         jc      .nopci
  300. .found:
  301. ; get memory base
  302.         mov     ax, 0xB10A
  303.         mov     di, 0x20        ; memory base is config register at 0x20
  304.         int     0x1A
  305.         jc      .nopci
  306.         and     cx, 0xFFF0      ; clear address decode type
  307.         mov     [es:0x9031], cx
  308. .nopci:
  309. ; \end{Mario79}
  310.  
  311. ;        mov     al, 0xf6        ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå
  312. ;        out     0x60, al
  313. ;        xor     cx, cx
  314. ;wait_loop:       ; variant 2
  315. ; reading state of port of 8042 controller
  316. ;        in      al, 64h
  317. ;        and     al, 00000010b  ; ready flag
  318. ; wait until 8042 controller is ready
  319. ;        loopnz  wait_loop
  320.  
  321. ;;;/diamond   5.02.2008
  322. ; set keyboard typematic rate & delay
  323. ;        mov     al, 0xf3
  324. ;        out     0x60, al
  325. ;        xor     cx, cx
  326. ;@@:
  327. ;        in      al, 64h
  328. ;        test    al, 2
  329. ;        loopnz  @b
  330. ;        mov     al, 0
  331. ;        out     0x60, al
  332. ;        xor     cx, cx
  333. ;@@:
  334. ;        in      al, 64h
  335. ;        test    al, 2
  336. ;        loopnz  @b
  337. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  338. ; --------------- APM ---------------------
  339.         and     word [es:0x9044], 0     ; ver = 0.0 (APM not found)
  340.         mov     ax, 0x5300
  341.         xor     bx, bx
  342.         int     0x15
  343.         jc      apm_end                 ; APM not found
  344.         test    cx, 2
  345.         jz      apm_end                 ; APM 32-bit protected-mode interface not supported
  346.         mov     [es:0x9044], ax         ; Save APM Version
  347.         mov     [es:0x9046], cx         ; Save APM flags
  348.  
  349.         ; Write APM ver ----
  350.         and     ax, 0xf0f
  351.         add     ax, '00'
  352.         mov     si, msg_apm
  353.         mov     [si + 5], ah
  354.         mov     [si + 7], al
  355.         _setcursor 0, 3
  356.         call    printplain
  357.         ; ------------------
  358.  
  359.         mov     ax, 0x5304              ; Disconnect interface
  360.         xor     bx, bx
  361.         int     0x15
  362.         mov     ax, 0x5303              ; Connect 32 bit mode interface
  363.         xor     bx, bx
  364.         int     0x15
  365.  
  366.         mov     [es:0x9040], ebx
  367.         mov     [es:0x9050], ax
  368.         mov     [es:0x9052], cx
  369.         mov     [es:0x9054], dx
  370.  
  371. apm_end:
  372.         _setcursor d80x25_top_num, 0
  373.  
  374. ;CHECK current of code
  375.         cmp     [cfgmanager.loader_block], -1
  376.         jz      noloaderblock
  377.         les     bx, [cfgmanager.loader_block]
  378.         cmp     byte [es:bx], 1
  379.         mov     si, loader_block_error
  380.         jnz     sayerr
  381.         push    0
  382.         pop     es
  383.  
  384. noloaderblock:
  385. ; DISPLAY VESA INFORMATION
  386.          call    print_vesa_info
  387.          call    calc_vmodes_table
  388.          call    check_first_parm  ;check and enable cursor_pos
  389.  
  390. ; \begin{diamond}[30.11.2005]
  391. cfgmanager:
  392. ; settings:
  393. ; a) preboot_graph = graphical mode
  394. ;    preboot_gprobe = probe this mode?
  395. ; b) preboot_dma  = use DMA access?
  396. ; c) preboot_vrrm = use VRR?
  397. ; d) preboot_device = from what boot?
  398.  
  399. ; determine default settings
  400.         mov     [.bSettingsChanged], 0
  401.  
  402. ;.preboot_gr_end:
  403.         mov     di, preboot_device
  404. ; if image in memory is present and [preboot_device] is uninitialized,
  405. ; set it to use this preloaded image
  406.         cmp     byte [di], 0
  407.         jnz     .preboot_device_inited
  408.         cmp     [.loader_block], -1
  409.         jz      @f
  410.         les     bx, [.loader_block]
  411.         test    byte [es:bx+1], 1
  412.         jz      @f
  413.         mov     byte [di], 3
  414.         jmp     .preboot_device_inited
  415. @@:
  416. ; otherwise, set [preboot_device] to 1 (default value - boot from floppy)
  417.         mov     byte [di], 1
  418. .preboot_device_inited:
  419. ; following 4 lines set variables to 1 if its current value is 0
  420.         cmp     byte [di+preboot_dma-preboot_device], 1
  421.         adc     byte [di+preboot_dma-preboot_device], 0
  422.         cmp     byte [di+preboot_biosdisk-preboot_device], 1
  423.         adc     byte [di+preboot_biosdisk-preboot_device], 0
  424. ; default value for VRR is OFF
  425.         cmp     byte [di+preboot_vrrm-preboot_device], 0
  426.         jnz     @f
  427.         mov     byte [di+preboot_vrrm-preboot_device], 2
  428. @@:
  429. ; notify user
  430.         _setcursor 5,2
  431.  
  432.         mov     si, linef
  433.         call    printplain
  434.         mov     si, start_msg
  435.         call    print
  436.         mov     si, time_msg
  437.         call    print
  438. ; get start time
  439.         call    .gettime
  440.         mov     [.starttime], eax
  441.         mov     word [.timer], .newtimer
  442.         mov     word [.timer+2], cs
  443. .printcfg:
  444.  
  445.         _setcursor 9,0
  446.         mov     si, current_cfg_msg
  447.         call    print
  448.         mov     si, curvideo_msg
  449.         call    print
  450.  
  451.             call    draw_current_vmode
  452.  
  453.         mov     si, usebd_msg
  454.         cmp     [preboot_biosdisk], 1
  455.         call    .say_on_off
  456.         mov     si, vrrm_msg
  457.         cmp     [preboot_vrrm], 1
  458.         call    .say_on_off
  459.         mov     si, preboot_device_msg
  460.         call    print
  461.         mov     al, [preboot_device]
  462.         and     eax, 7
  463.         mov     si, [preboot_device_msgs+eax*2]
  464.         call    printplain
  465. .show_remarks:
  466. ; show remarks in gray color
  467.         mov     di, ((21-num_remarks)*80 + 2)*2
  468.         push    0xB800
  469.         pop     es
  470.         mov     cx, num_remarks
  471.         mov     si, remarks
  472. .write_remarks:
  473.         lodsw
  474.         push    si
  475.         xchg    ax, si
  476.         mov     ah, 1*16+7      ; background: blue (1), foreground: gray (7)
  477.         push    di
  478. .write_remark:
  479.         lodsb
  480.         test    al, al
  481.         jz      @f
  482.         stosw
  483.         jmp     .write_remark
  484. @@:
  485.         pop     di
  486.         pop     si
  487.         add     di, 80*2
  488.         loop    .write_remarks
  489. .wait:
  490.         _setcursor 25,0         ; out of screen
  491. ; set timer interrupt handler
  492.         cli
  493.         push    0
  494.         pop     es
  495.         push    dword [es:8*4]
  496.         pop     dword [.oldtimer]
  497.         push    dword [.timer]
  498.         pop     dword [es:8*4]    
  499. ;        mov     eax, [es:8*4]
  500. ;        mov     [.oldtimer], eax
  501. ;        mov     eax, [.timer]
  502. ;        mov     [es:8*4], eax
  503.         sti
  504. ; wait for keypressed
  505.         xor     ax,ax
  506.         int     16h
  507.         push    ax
  508. ; restore timer interrupt
  509. ;        push    0
  510. ;        pop     es
  511.         mov     eax, [.oldtimer]
  512.         mov     [es:8*4], eax
  513.         mov     [.timer], eax
  514.  
  515.         _setcursor 7,0
  516.         mov     si, space_msg
  517.         call    printplain
  518. ; clear remarks and restore normal attributes
  519.         push    es
  520.         mov     di, ((21-num_remarks)*80 + 2)*2
  521.         push    0xB800
  522.         pop     es
  523.         mov     cx, num_remarks
  524.         mov     ax, ' ' + (1*16 + 15)*100h
  525. @@:
  526.         push    cx
  527.         mov     cx, 76
  528.         rep     stosw
  529.         pop     cx
  530.         add     di, 4*2
  531.         loop    @b
  532.         pop     es
  533.         pop     ax
  534. ; switch on key
  535.         cmp     al, 13
  536.         jz      .continue
  537.         or      al, 20h
  538.         cmp     al, 'a'
  539.         jz      .change_a
  540.         cmp     al, 'b'
  541.         jz      .change_b
  542.         cmp     al, 'c'
  543.         jz      .change_c
  544.         cmp     al, 'd'
  545.         jnz     .show_remarks
  546.         _setcursor 15,0
  547.         mov     si, bdev
  548.         call    print
  549.         mov     bx, '14'
  550.         call    getkey
  551.         mov     [preboot_device], al
  552.         _setcursor 13,0
  553. .d:
  554.         mov     [.bSettingsChanged], 1
  555.         call    clear_vmodes_table             ;clear vmodes_table
  556.         jmp    .printcfg
  557. .change_a:
  558. .loops:
  559.         call    draw_vmodes_table
  560.         _setcursor 25,0         ; out of screen
  561.         xor     ax,ax
  562.         int     0x16
  563. ;        call    clear_table_cursor             ;clear current position of cursor
  564.  
  565.         mov     si,word [cursor_pos]
  566.  
  567.         cmp     ah,0x48;x,0x48E0               ; up
  568.         jne     .down
  569.         cmp     si,modes_table
  570.         jbe     .loops
  571.         sub     word [cursor_pos],size_of_step
  572.         jmp     .loops
  573.  
  574. .down:  cmp     ah,0x50;x,0x50E0               ; down
  575.         jne     .pgup
  576.         cmp     word[es:si+10],-1
  577.         je      .loops        
  578.         add     word [cursor_pos],size_of_step
  579.         jmp     .loops
  580.  
  581. .pgup:  cmp     ah,0x49                 ; page up
  582.         jne     .pgdn
  583.         sub     si, size_of_step*long_v_table
  584.         cmp     si, modes_table
  585.         jae     @f
  586.         mov     si, modes_table
  587. @@:
  588.         mov     word [cursor_pos], si
  589.         mov     si, word [home_cursor]
  590.         sub     si, size_of_step*long_v_table
  591.         cmp     si, modes_table
  592.         jae     @f
  593.         mov     si, modes_table
  594. @@:
  595.         mov     word [home_cursor], si
  596.         jmp     .loops
  597.  
  598. .pgdn:  cmp     ah,0x51                 ; page down
  599.         jne     .enter
  600.         mov     ax, [end_cursor]
  601.         add     si, size_of_step*long_v_table
  602.         cmp     si, ax
  603.         jb      @f
  604.         mov     si, ax
  605.         sub     si, size_of_step
  606. @@:
  607.         mov     word [cursor_pos], si
  608.         mov     si, word [home_cursor]
  609.         sub     ax, size_of_step*long_v_table
  610.         add     si, size_of_step*long_v_table
  611.         cmp     si, ax
  612.         jb      @f
  613.         mov     si, ax
  614. @@:
  615.         mov     word [home_cursor], si
  616.         jmp     .loops
  617.  
  618. .enter: cmp     al,0x0D;x,0x1C0D               ; enter
  619.         jne     .loops
  620.         push    word [cursor_pos]
  621.         pop     bp
  622.         push    word [es:bp]
  623.         pop     word [x_save]
  624.         push    word [es:bp+2]
  625.         pop     word [y_save]
  626.         push    word [es:bp+6]
  627.         pop     word [number_vm]
  628.         mov     word [preboot_graph],bp           ;save choose
  629.        
  630.         jmp    .d
  631.  
  632. .change_b:
  633.         _setcursor 15,0
  634. ;        mov     si, ask_dma
  635. ;        call    print
  636. ;        mov     bx, '13'
  637. ;        call    getkey
  638. ;        mov     [preboot_dma], al
  639.         mov     si, ask_bd
  640.         call    print
  641.         mov     bx, '12'
  642.         call    getkey
  643.         mov     [preboot_biosdisk], al
  644.         _setcursor 11,0
  645.         jmp     .d
  646. .change_c:
  647.         _setcursor 15,0
  648.         mov     si, vrrmprint
  649.         call    print
  650.         mov     bx, '12'
  651.         call    getkey
  652.         mov     [preboot_vrrm], al
  653.         _setcursor 12,0
  654.         jmp     .d
  655. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  656. .say_on_off:
  657.         pushf
  658.         call    print
  659.         mov     si, on_msg
  660.         popf
  661.         jz      @f
  662.         mov     si, off_msg
  663. @@:     jmp     printplain
  664. ; novesa and vervesa strings are not used at the moment of executing this code
  665. virtual at novesa
  666. .oldtimer dd ?
  667. .starttime dd ?
  668. .bSettingsChanged db ?
  669. .timer dd ?
  670. end virtual
  671. .loader_block dd -1
  672. .gettime:
  673.         mov     ah, 0
  674.         int     1Ah
  675.         xchg    ax, cx
  676.         shl     eax, 10h
  677.         xchg    ax, dx
  678.         ret
  679. .newtimer:
  680.         push    ds
  681.         push    cs
  682.         pop     ds
  683.         pushf
  684.         call    [.oldtimer]
  685.         pushad
  686.         call    .gettime
  687.         sub     eax, [.starttime]
  688.         sub     ax, 18*5
  689.         jae     .timergo
  690.         neg     ax
  691.         add     ax, 18-1
  692.         mov     bx, 18
  693.         xor     dx, dx
  694.         div     bx
  695. if lang eq ru
  696. ; ¯®¤®¦¤¨â¥ 5 ᥪ㭤, 4/3/2 ᥪ㭤ë, 1 ᥪ㭤ã
  697.         cmp     al, 5
  698.         mov     cl, ' '
  699.         jae     @f
  700.         cmp     al, 1
  701.         mov     cl, 'ã'
  702.         jz      @f
  703.         mov     cl, 'ë'
  704. @@:     mov     [time_str+9], cl
  705. else if lang eq et
  706.         cmp     al, 1
  707.         ja      @f
  708.         mov     [time_str+9], ' '
  709.         mov     [time_str+10],' '
  710. @@:
  711. else
  712. ; wait 5/4/3/2 seconds, 1 second
  713.         cmp     al, 1
  714.         mov     cl, 's'
  715.         ja      @f
  716.         mov     cl, ' '
  717. @@:     mov     [time_str+9], cl
  718. end if
  719.         add     al, '0'
  720.         mov     [time_str+1], al
  721.         mov     si, time_msg
  722.         _setcursor 7,0
  723.         call    print
  724.         _setcursor 25,0
  725.         popad
  726.         pop     ds
  727.         iret
  728. .timergo:
  729.         push    0
  730.         pop     es
  731.         mov     eax, [.oldtimer]
  732.         mov     [es:8*4], eax
  733.         mov     sp, 0EC00h
  734. .continue:
  735.         sti
  736.         _setcursor 6,0
  737.         mov     si, space_msg
  738.         call    printplain
  739.         call    printplain
  740.         _setcursor 6,0
  741.         mov     si, loading_msg
  742.         call    print
  743.         _setcursor 15,0
  744.         cmp     [.bSettingsChanged], 0
  745.         jz      .load
  746.         cmp     [.loader_block], -1
  747.         jz      .load
  748.         les     bx, [.loader_block]
  749.         mov     eax, [es:bx+3]
  750.         push    ds
  751.         pop     es
  752.         test    eax, eax
  753.         jz      .load
  754.         push    eax
  755.         mov     si, save_quest
  756.         call    print
  757. .waityn:
  758.         mov     ah, 0
  759.         int     16h
  760.         or      al, 20h
  761.         cmp     al, 'n'
  762.         jz      .loadc
  763.         cmp     al, 'y'
  764.         jnz     .waityn
  765.         call    putchar
  766.         mov     byte [space_msg+80], 186
  767.  
  768.         pop     eax
  769.         push    cs
  770.         push    .cont
  771.         push    eax
  772.         retf                          ;call back
  773. .loadc:
  774.         pop     eax
  775. .cont:
  776.         push    cs
  777.         pop     ds
  778.         mov     si, space_msg
  779.         mov     byte [si+80], 0
  780.         _setcursor 15,0
  781.         call    printplain
  782.         _setcursor 15,0
  783. .load:
  784. ; \end{diamond}[02.12.2005]
  785.  
  786. ; ASK GRAPHICS MODE
  787.  
  788.         call    set_vmode
  789.  
  790. ; GRAPHICS ACCELERATION
  791. ; force yes
  792.         mov     [es:0x901C], byte 1
  793.  
  794. ; DMA ACCESS TO HD
  795.  
  796.         mov     al, [preboot_dma]
  797.         mov     [es:0x901F], al
  798.  
  799. ; VRR_M USE
  800.  
  801.         mov     al,[preboot_vrrm]
  802.         mov     [es:0x9030], al
  803.         mov     [es:0x901E], byte 1
  804.  
  805. ; BOOT DEVICE
  806.  
  807.         mov     al, [preboot_device]
  808.         dec     al
  809.         mov     [boot_dev], al
  810.  
  811. ; GET MEMORY MAP
  812. include 'detect/biosmem.inc'
  813.  
  814. ; READ DISKETTE TO MEMORY
  815.  
  816.         cmp     [boot_dev],0
  817.         jne     no_sys_on_floppy
  818.         mov     si,diskload
  819.         call    print
  820.         xor     ax, ax            ; reset drive
  821.         xor     dx, dx
  822.         int     0x13
  823. ; do we boot from CD-ROM?
  824.         mov     ah, 41h
  825.         mov     bx, 55AAh
  826.         xor     dx, dx
  827.         int     0x13
  828.         jc      .nocd
  829.         cmp     bx, 0AA55h
  830.         jnz     .nocd
  831.         mov     ah, 48h
  832.         push    ds
  833.         push    es
  834.         pop     ds
  835.         mov     si, 0xa000
  836.         mov     word [si], 30
  837.         int     0x13
  838.         pop     ds
  839.         jc      .nocd
  840.         push    ds
  841.         lds     si, [es:si+26]
  842.         test    byte [ds:si+10], 40h
  843.         pop     ds
  844.         jz      .nocd
  845. ; yes - read all floppy by 18 sectors
  846.  
  847. ; TODO: !!!! read only first sector and set variables !!!!!
  848. ; ...
  849. ; TODO: !!! then read flippy image track by track
  850.        
  851.         mov     cx, 0x0001      ; startcyl,startsector
  852. .a1:
  853.         push    cx dx
  854.         mov     al, 18
  855.         mov     bx, 0xa000
  856.         call    boot_read_floppy
  857.         mov     si, movedesc
  858.         push    es
  859.         push    ds
  860.         pop     es
  861.         mov     cx, 256*18
  862.         mov     ah, 0x87
  863.         int     0x15
  864.         pop     es
  865.         pop     dx cx
  866.         test    ah, ah
  867.         jnz     sayerr_floppy
  868.         add     dword [si+8*3+2], 512*18
  869.         inc     dh
  870.         cmp     dh, 2
  871.         jnz     .a1
  872.         mov     dh, 0
  873.         inc     ch
  874.         cmp     ch, 80
  875.         jae     ok_sys_on_floppy
  876.         pusha
  877.         mov     al, ch
  878.         shr     ch, 2
  879.         add     al, ch
  880.         aam
  881.         xchg    al, ah
  882.         add     ax, '00'
  883.         mov     si, pros
  884.         mov     [si], ax
  885.         call    printplain
  886.         popa
  887.         jmp     .a1
  888. .nocd:
  889. ; no - read only used sectors from floppy
  890. ; now load floppy image to memory
  891. ; at first load boot sector and first FAT table
  892.  
  893. ; read only first sector and fill variables
  894.         mov     cx, 0x0001      ; first logical sector
  895.         xor     dx, dx          ; head = 0, drive = 0 (a:)
  896.         mov     al, 1           ; read one sector
  897.         mov     bx, 0xB000      ; es:bx -> data area
  898.         call    boot_read_floppy
  899. ; fill the necessary parameters to work with a floppy
  900.         mov     ax, word [es:bx+24]
  901.         mov     word [BPB_SecPerTrk], ax
  902.         mov     ax, word [es:bx+26]
  903.         mov     word [BPB_NumHeads], ax
  904.         mov     ax, word [es:bx+17]
  905.         mov     word [BPB_RootEntCnt], ax
  906.         mov     ax, word [es:bx+14]
  907.         mov     word [BPB_RsvdSecCnt], ax
  908.         mov     ax, word [es:bx+19]
  909.         mov     word [BPB_TotSec16], ax
  910.         mov     al, byte [es:bx+13]
  911.         mov     byte [BPB_SecPerClus], al
  912.         mov     al, byte [es:bx+16]
  913.         mov     byte [BPB_NumFATs], al
  914. ;<Lrz> 18.11.2008
  915.         mov     ax, word [es:bx+22]
  916.         mov     word [BPB_FATSz16], ax
  917.         mov     cx, word [es:bx+11]
  918.         mov     word [BPB_BytsPerSec], cx
  919.  
  920. ; count of clusters in FAT12 ((size_of_FAT*2)/3)
  921. ;        mov     ax, word [BPB_FATSz16]
  922. ;        mov     cx, word [BPB_BytsPerSec]
  923. ;end <Lrz> 18.11.2008
  924.         xor     dx, dx
  925.         mul     cx
  926.         shl     ax, 1
  927.         mov     cx, 3
  928.         div     cx              ; now ax - number of clusters in FAT12
  929.         mov     word [end_of_FAT], ax
  930.  
  931. ; load first FAT table
  932.         mov     cx, 0x0002      ; startcyl,startsector          ; TODO!!!!!
  933.         xor     dx, dx          ; starthead,drive
  934.         mov     al, byte [BPB_FATSz16]     ; no of sectors to read
  935.         add     bx, word [BPB_BytsPerSec]  ; es:bx -> data area
  936.         call    boot_read_floppy
  937.         mov     bx, 0xB000
  938.  
  939. ; and copy them to extended memory
  940.         mov     si, movedesc
  941.         mov     [si+8*2+3], bh          ; from
  942.        
  943.         mov     ax, word [BPB_BytsPerSec]
  944.         shr     ax, 1                   ; words per sector
  945.         mov     cx, word [BPB_RsvdSecCnt]
  946.         add     cx, word [BPB_FATSz16]
  947.         mul     cx
  948.         push    ax                      ; save to stack count of words in boot+FAT
  949.         xchg    ax, cx
  950.        
  951.         push    es
  952.         push    ds
  953.         pop     es
  954.         mov     ah, 0x87
  955.         int     0x15
  956.         pop     es
  957.         test    ah, ah
  958.         jz      @f
  959. sayerr_floppy:
  960.         mov     dx, 0x3f2
  961.         mov     al, 0
  962.         out     dx, al
  963.         mov     si, memmovefailed
  964.         jmp     sayerr_plain
  965. @@:
  966.         pop     ax                      ; restore from stack count of words in boot+FAT
  967.         shl     ax, 1                   ; make bytes count from count of words
  968.         and     eax, 0ffffh
  969.         add     dword [si+8*3+2], eax
  970.  
  971. ; copy first FAT to second copy
  972. ; TODO: BPB_NumFATs !!!!!
  973.         add     bx, word [BPB_BytsPerSec]       ; !!! TODO: may be need multiply by BPB_RsvdSecCnt !!!
  974.         mov     byte [si+8*2+3], bh     ; bx - begin of FAT
  975.        
  976.         mov     ax, word [BPB_BytsPerSec]
  977.         shr     ax, 1                   ; words per sector
  978.         mov     cx, word [BPB_FATSz16]
  979.         mul     cx
  980.         mov     cx, ax                  ; cx - count of words in FAT
  981.  
  982.         push    es
  983.         push    ds
  984.         pop     es
  985.         mov     ah, 0x87
  986.         int     0x15
  987.         pop     es
  988.         test    ah, ah
  989.         jnz     sayerr_floppy
  990.        
  991.         mov     ax, cx
  992.         shl     ax, 1
  993.         and     eax, 0ffffh             ; ax - count of bytes in FAT
  994.         add     dword [si+8*3+2], eax
  995.        
  996. ; reading RootDir
  997. ; TODO: BPB_NumFATs
  998.         add     bx, ax
  999.         add     bx, 100h
  1000.         and     bx, 0ff00h                      ; bx - place in buffer to write RootDir
  1001.         push    bx
  1002.  
  1003.         mov     bx, word [BPB_BytsPerSec]
  1004.         shr     bx, 5                           ; divide bx by 32
  1005.         mov     ax, word [BPB_RootEntCnt]
  1006.         xor     dx, dx
  1007.         div     bx
  1008.         push    ax                              ; ax - count of RootDir sectors
  1009.  
  1010.         mov     ax, word [BPB_FATSz16]
  1011.         xor     cx, cx
  1012.         mov     cl, byte [BPB_NumFATs]
  1013.         mul     cx
  1014.         add     ax, word [BPB_RsvdSecCnt]       ; ax - first sector of RootDir
  1015.  
  1016.         mov     word [FirstDataSector], ax
  1017.         pop     bx
  1018.         push    bx
  1019.         add     word [FirstDataSector], bx      ; Begin of data region of floppy
  1020.        
  1021. ; read RootDir
  1022.         call    conv_abs_to_THS
  1023.         pop     ax
  1024.         pop     bx                              ; place in buffer to write
  1025.         push    ax
  1026.         call    boot_read_floppy                ; read RootDir into buffer
  1027. ; copy RootDir
  1028.         mov     byte [si+8*2+3], bh             ; from buffer
  1029.         pop     ax                              ; ax = count of RootDir sectors
  1030.         mov     cx, word [BPB_BytsPerSec]
  1031.         mul     cx
  1032.         shr     ax, 1
  1033.         mov     cx, ax                          ; count of words to copy
  1034.         push    es
  1035.         push    ds
  1036.         pop     es
  1037.         mov     ah, 0x87
  1038.         int     0x15
  1039.         pop     es
  1040.  
  1041.         mov     ax, cx
  1042.         shl     ax, 1
  1043.         and     eax, 0ffffh             ; ax - count of bytes in RootDir
  1044.         add     dword [si+8*3+2], eax   ; add count of bytes copied
  1045.  
  1046. ; Reading data clusters from floppy
  1047.         mov     byte [si+8*2+3], bh
  1048.         push    bx
  1049.  
  1050.         mov     di, 2                   ; First data cluster
  1051. .read_loop:
  1052.         mov     bx, di
  1053.         shr     bx, 1                   ; bx+di = di*1.5
  1054.         jnc     .even
  1055.         test    word [es:bx+di+0xB200], 0xFFF0  ; TODO: may not be 0xB200 !!!
  1056.         jmp     @f
  1057. .even:
  1058.         test    word [es:bx+di+0xB200], 0xFFF   ; TODO: may not be 0xB200 !!!
  1059.  
  1060. @@:
  1061.         jz      .skip
  1062. ; read cluster di
  1063. ;.read:
  1064.         ;conv cluster di to abs. sector ax
  1065.         ; ax = (N-2) * BPB_SecPerClus + FirstDataSector
  1066.         mov     ax, di
  1067.         sub     ax, 2
  1068.         xor     bx, bx
  1069.         mov     bl, byte [BPB_SecPerClus]
  1070.         mul     bx
  1071.         add     ax, word [FirstDataSector]
  1072.         call    conv_abs_to_THS
  1073.         pop     bx
  1074.         push    bx
  1075.         mov     al, byte [BPB_SecPerClus]       ; number of sectors in cluster
  1076.         call    boot_read_floppy
  1077.         push    es
  1078.         push    ds
  1079.         pop     es
  1080.         pusha
  1081. ;
  1082.         mov     ax, word [BPB_BytsPerSec]
  1083.         xor     cx, cx
  1084.         mov     cl, byte [BPB_SecPerClus]
  1085.         mul     cx
  1086.         shr     ax, 1                           ; ax = (BPB_BytsPerSec * BPB_SecPerClus)/2
  1087.         mov     cx, ax                          ; number of words to copy (count words in cluster)
  1088. ;
  1089.         mov     ah, 0x87
  1090.         int     0x15                            ; copy data
  1091.         test    ah, ah
  1092.         popa
  1093.         pop     es
  1094.         jnz     sayerr_floppy
  1095. ; skip cluster di
  1096. .skip:
  1097.         mov     ax, word [BPB_BytsPerSec]
  1098.         xor     cx, cx
  1099.         mov     cl, byte [BPB_SecPerClus]
  1100.         mul     cx
  1101.         and     eax, 0ffffh             ; ax - count of bytes in cluster
  1102.         add     dword [si+8*3+2], eax
  1103.  
  1104.         mov     ax, word [end_of_FAT]   ; max cluster number
  1105.         pusha
  1106. ; draw percentage
  1107. ; total clusters: ax
  1108. ; read clusters: di
  1109.         xchg    ax, di
  1110.         mov     cx, 100
  1111.         mul     cx
  1112.         div     di
  1113.         aam
  1114.         xchg    al, ah
  1115.         add     ax, '00'
  1116.         mov     si, pros
  1117.         cmp     [si], ax
  1118.         jz      @f
  1119.         mov     [si], ax
  1120.         call    printplain
  1121. @@:
  1122.         popa
  1123.         inc     di
  1124.         cmp     di, word [end_of_FAT]   ; max number of cluster
  1125.         jnz     .read_loop
  1126.         pop     bx                      ; clear stack
  1127.  
  1128. ok_sys_on_floppy:
  1129.         mov     si, backspace2
  1130.         call    printplain
  1131.         mov     si, okt
  1132.         call    printplain
  1133. no_sys_on_floppy:
  1134.         xor     ax, ax          ; reset drive
  1135.         xor     dx, dx
  1136.         int     0x13
  1137.         mov     dx, 0x3f2       ; floppy motor off
  1138.         mov     al, 0
  1139.         out     dx, al
  1140.  
  1141.  
  1142. ; SET GRAPHICS
  1143.  
  1144.         xor     ax, ax
  1145.         mov     es, ax
  1146.  
  1147.         mov     ax, [es:0x9008]         ; vga & 320x200
  1148.         mov     bx, ax
  1149.         cmp     ax, 0x13
  1150.         je      setgr
  1151.         cmp     ax, 0x12
  1152.         je      setgr
  1153.         mov     ax, 0x4f02              ; Vesa
  1154. setgr:
  1155.         int     0x10
  1156.         test    ah, ah
  1157.         mov     si, fatalsel
  1158.         jnz     v_mode_error
  1159. ; set mode 0x12 graphics registers:
  1160.         cmp     bx, 0x12
  1161.         jne     gmok2
  1162.  
  1163.         mov     al, 0x05
  1164.         mov     dx, 0x03ce
  1165.         push    dx
  1166.         out     dx, al      ; select GDC mode register
  1167.         mov     al, 0x02
  1168.         inc     dx
  1169.         out     dx, al      ; set write mode 2
  1170.  
  1171.         mov     al, 0x02
  1172.         mov     dx, 0x03c4
  1173.         out     dx, al      ; select VGA sequencer map mask register
  1174.         mov     al, 0x0f
  1175.         inc     dx
  1176.         out     dx, al      ; set mask for all planes 0-3
  1177.  
  1178.         mov     al, 0x08
  1179.         pop     dx
  1180.         out     dx, al      ; select GDC bit mask register
  1181.                            ; for writes to 0x03cf
  1182. gmok2:
  1183.         push    ds
  1184.         pop     es
  1185.