Subversion Repositories Kolibri OS

Rev

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

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