Subversion Repositories Kolibri OS

Rev

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

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