Subversion Repositories Kolibri OS

Rev

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