Subversion Repositories Kolibri OS

Rev

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

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