Subversion Repositories Kolibri OS

Rev

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

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