Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                        ;;
  3. ;;  BOOTCODE.INC                                          ;;
  4. ;;                                                        ;;
  5. ;;  KolibriOS 16-bit loader,                              ;;
  6. ;;                        based on bootcode for MenuetOS  ;;
  7. ;;                                                        ;;
  8. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  9.  
  10.  
  11.  
  12. ;==========================================================================
  13. ;
  14. ;                           16 BIT FUNCTIONS
  15. ;
  16. ;==========================================================================
  17.  
  18. putchar:
  19. ; in: al=character
  20.     mov    ah, 0Eh
  21.     mov    bh, 0
  22.     int    10h
  23.     ret
  24.  
  25. print:
  26. ; in: si->string
  27.     mov    al, 186
  28.     call    putchar
  29.     mov    al, ' '
  30.     call    putchar
  31.  
  32. printplain:
  33. ; in: si->string
  34.     pusha
  35.     lodsb
  36. @@:
  37.     call    putchar
  38.     lodsb
  39.     cmp    al, 0
  40.     jnz    @b
  41.     popa
  42.     ret
  43.  
  44. ; Now int 16 is used for keyboard support.
  45. ; This is shorter, simpler and more reliable.
  46. if 0
  47. getkey:      push  ecx
  48.              push  edx
  49.              add   ebx,0x0101
  50.              xor   eax,eax
  51.  
  52.            gk1:
  53.              in    al,0x60
  54.              mov   cl,al
  55.            gk0:
  56.              in    al,0x60
  57.              cmp   al,cl
  58.              je    gk0
  59.              cmp   ax,11
  60.              jg    gk0
  61.              gk0_1:
  62.              mov   cl,al
  63.  
  64. ;             add   al,47
  65. ;             mov   [ds:keyinbs-0x10000],al
  66. ;             mov   si,keyinbs-0x10000
  67. ;             call  printplain
  68.  
  69.            gk12:
  70.              in    al,0x60
  71.              cmp   al,cl
  72.              je    gk12
  73.              cmp   ax,240
  74.              jne   gk13
  75.              mov   al,cl
  76.              jmp   gk14
  77.            gk13:
  78.              add   cl,128
  79.              cmp   al,cl
  80.              jne   gk1
  81.              sub   al,128
  82.            gk14:
  83.  
  84.              movzx edx,bl
  85.              cmp   eax,edx
  86.              jb    gk1
  87.              movzx edx,bh
  88.              cmp   eax,edx
  89.              jg    gk1
  90.              test  ebx,0x010000
  91.              jnz   gk3
  92.              mov   cx,0x1000
  93.              mov   dx,cx
  94.              add   eax,47
  95.              mov   cx,ax
  96.              cmp   cx,58
  97.              jb    gk_nozero
  98.              sub   cx,10
  99.            gk_nozero:
  100.              mov   [ds:keyin-0x10000],cl
  101.              mov   si,keyin-0x10000
  102.              call  printplain
  103.            gk3:
  104.              sub   eax,48
  105.              pop   edx
  106.              pop   ecx
  107.              ret
  108. end if
  109.  
  110. getkey:
  111. ; get number in range [bl,bh] (bl,bh in ['0'..'9'])
  112. ; in: bx=range
  113. ; out: ax=digit (1..9, 10 for 0)
  114.     mov    ah, 0
  115.     int    16h
  116.     cmp    al, bl
  117.     jb    getkey
  118.     cmp    al, bh
  119.     ja    getkey
  120.     push    ax
  121.     call    putchar
  122.     pop    ax
  123.     and    ax, 0Fh
  124.     jnz    @f
  125.     mov    al, 10
  126. @@:
  127.     ret
  128.  
  129. setcursor:
  130. ; in: dl=column, dh=row
  131.     mov    ah, 2
  132.     mov    bh, 0
  133.     int    10h
  134.     ret
  135.  
  136. macro _setcursor row,column
  137. {
  138.     mov    dx, row*256 + column
  139.     call    setcursor
  140. }
  141.  
  142. pagetable_set:
  143. ;eax - physical address
  144. ;es:di - page table
  145. ;ecx - number of pages to map
  146.     or    al, 7
  147. @@:
  148.     stosd
  149.     add    eax, 1000h
  150.     loop    @b
  151.     ret
  152.  
  153. boot_read_floppy:
  154.         push    si
  155.         xor     si, si
  156.         mov     ah, 2   ; read
  157. @@:
  158.         push    ax
  159.         int     0x13
  160.         pop     ax
  161.         jnc     @f
  162.         inc     si
  163.         cmp     si, 10
  164.         jb      @b
  165.         mov     si, badsect-0x10000
  166. sayerr_plain:
  167.         call    printplain
  168.         jmp     $
  169. @@:
  170.         pop     si
  171.         ret
  172.  
  173. ; 16-bit data
  174. ; videomodes table
  175.                 org $+0x10000
  176. gr_table:
  177.     dw      0x112+0100000000000000b ,  640 ,  480        ; 1
  178.     dw      0x115+0100000000000000b ,  800 ,  600        ; 2
  179.     dw      0x118+0100000000000000b , 1024 ,  768        ; 3
  180.     dw      0x11B+0100000000000000b , 1280 , 1024        ; 4
  181.     dw      0x112 ,  640 , 480                ; 5
  182.     dw      0x115 ,  800 , 600                ; 6
  183.     dw      0x118 , 1024 , 768                ; 7
  184.     dw      0x11B , 1280 ,1024                ; 8
  185.     dw    0x13, 640, 480                    ; 9
  186.     dw    0x12, 640, 480                    ; 0
  187.  
  188. ; table for move to extended memory (int 15h, ah=87h)
  189.        movedesc:
  190.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  191.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  192.  
  193.         db      0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0
  194.         db      0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0
  195.  
  196.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  197.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  198.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  199.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  200.                 org $-0x10000
  201.  
  202. ;=========================================================================
  203. ;
  204. ;                           16 BIT CODE
  205. ;
  206. ;=========================================================================
  207.  
  208.  
  209. start_of_code:
  210.     cld
  211. ; \begin{diamond}[02.12.2005]
  212.     cmp    ax, 'KL'
  213.     jnz    @f
  214.     mov    word [cs:cfgmanager.loader_block-0x10000], si
  215.     mov    word [cs:cfgmanager.loader_block+2-0x10000], ds
  216. @@:
  217. ; \end{diamond}[02.12.2005]
  218.  
  219. ; set up stack
  220.     mov    ax, 3000h
  221.     mov    ss, ax
  222.     mov    sp, 0EC00h
  223. ; set up segment registers
  224.     push    cs
  225.     pop    ds
  226.     push    cs
  227.     pop    es
  228.  
  229. ; set videomode
  230.     mov    ax, 3
  231.         int  0x10
  232.  
  233. if lang eq ru
  234.  ; Load & set russian VGA font (RU.INC)
  235.         mov  bp,RU_FNT1-10000h   ; RU_FNT1 - First part
  236.           mov  bx,1000h            ; 768 bytes
  237.           mov  cx,30h              ; 48 symbols
  238.           mov  dx,80h              ; 128 - position of first symbol
  239.         mov  ax,1100h
  240.           int  10h
  241.  
  242.         mov  bp,RU_FNT2-10000h   ; RU_FNT2 -Second part
  243.         mov  bx,1000h            ; 512 bytes
  244.         mov  cx,20h              ; 32 symbols
  245.         mov  dx,0E0h             ; 224 - position of first symbol
  246.         mov  ax,1100h
  247.           int  10h
  248.  ; End set VGA russian font
  249. end if
  250.  
  251. ; draw frames
  252.     push    0xb800
  253.     pop    es
  254.     xor    di, di
  255. ;        mov  si,d80x25-0x10000
  256. ;        mov  cx,80*25
  257. ;        mov  ah,1*16+15
  258. ;       dfl1:
  259. ;        lodsb
  260. ;        stosw
  261. ;        loop dfl1
  262.     mov    ah, 1*16+15
  263. ; draw top
  264.     mov    si, d80x25_top - 0x10000
  265.     mov    cx, d80x25_top_num * 80
  266. @@:
  267.     lodsb
  268.     stosw
  269.     loop    @b
  270. ; draw spaces
  271.     mov    si, space_msg - 0x10000
  272.     mov    cx, 25 - d80x25_top_num - d80x25_bottom_num
  273. dfl1:
  274.     push    cx
  275.     push    si
  276.     mov    cx, 80
  277. @@:
  278.     lodsb
  279.     stosw
  280.     loop    @b
  281.     pop    si
  282.     pop    cx
  283.     loop    dfl1
  284. ; draw bottom
  285.     mov    si, d80x25_bottom - 0x10000
  286.     mov    cx, d80x25_bottom_num * 80
  287. @@:
  288.     lodsb
  289.     stosw
  290.     loop    @b
  291.  
  292.     mov    byte [space_msg-0x10000+80], 0    ; now space_msg is null terminated
  293.  
  294.     _setcursor d80x25_top_num,0
  295.  
  296.  
  297. ; TEST FOR 386+
  298.  
  299.     mov    bx, 0x4000
  300.         pushf
  301.         pop     ax
  302.         mov     dx,ax
  303.         xor     ax,bx
  304.         push    ax
  305.         popf
  306.         pushf
  307.         pop     ax
  308.         and     ax,bx
  309.         and     dx,bx
  310.         cmp     ax,dx
  311.         jnz     cpugood
  312.         mov     si,not386-0x10000
  313. sayerr:
  314.         call    print
  315.         jmp     $
  316.      cpugood:
  317.  
  318. ; set up esp
  319.     movzx    esp, sp
  320.  
  321. ; FLUSH 8042 KEYBOARD CONTROLLER
  322.  
  323. ;// mike.dld [
  324.  ;       mov     al,0xED
  325.  ;       out     0x60,al
  326.  ;       or      cx,-1
  327.  ;     @@:
  328.  ;       in      al,0x64
  329.  ;       test    al,2
  330.  ;       jz      @f
  331.  ;       loop    @b
  332.  ;     @@:
  333.  ;       mov     al,0
  334.  ;       out     0x60,al
  335.  ;       or      cx,-1
  336.  ;     @@:
  337.  ;       in      al,0x64
  338.  ;       test    al,2
  339.  ;       jz      @f
  340.  ;       loop    @b
  341.  ;     @@:
  342. ;// mike.dld ]
  343.  
  344. ;       mov     ecx,10000
  345. ;      fl1:
  346. ;       in      al,0x64
  347. ;       loop    fl1
  348. ;       test    al,1
  349. ;       jz      fl2
  350. ;       in      al,0x60
  351. ;       jmp     fl1
  352. ;      fl2:
  353.  
  354. ;****************************************************************
  355. ; The function is modified Mario79
  356. ;*****************************************************************
  357. ; wait_kbd:        ; variant 1
  358. ;       mov      cx,2500h  ;çàäåðæêà ïîðÿäêà 10 ìñåê
  359. ; test_kbd:
  360. ;       in       al,64h    ;÷èòàåì ñîñòîÿíèå êëàâèàòóðû
  361. ;       test     al,2      ;ïðîâåðêà áèòà ãîòîâíîñòè
  362. ;       loopnz   test_kbd
  363.  
  364.         push    0
  365.         pop     es
  366.         and     word [es:0x9031], 0
  367. ; check for PCI BIOS
  368.         mov     ax, 0xB101
  369.         int     0x1A
  370.         jc      .nopci
  371.         cmp     edx, 'PCI '
  372.         jnz     .nopci
  373. ; find PCI class code
  374. ; class 1 = mass storage
  375. ; subclass 1 = IDE controller
  376. ; a) class 1, subclass 1, programming interface 0x80
  377.         mov     ax, 0xB103
  378.         mov     ecx, 1*10000h + 1*100h + 0x80
  379.         mov     si, 0   ; device index = 0
  380.         int     0x1A
  381.         jnc     .found
  382. ; b) class 1, subclass 1, programming interface 0x85
  383.         mov     ax, 0xB103
  384.         mov     ecx, 1*10000h + 1*100h + 0x85
  385.         mov     si, 0   ; device index = 0
  386.         int     0x1A
  387.         jnc     .found
  388. ; c) class 1, subclass 1, programming interface 0x8A
  389.         mov     ax, 0xB103
  390.         mov     ecx, 1*10000h + 1*100h + 0x8A
  391.         mov     si, 0
  392.         int     0x1A
  393.         jc      .nopci
  394. .found:
  395. ; get memory base
  396.         mov     ax, 0xB10A
  397.         mov     di, 0x20        ; memory base is config register at 0x20
  398.         int     0x1A
  399.         jc      .nopci
  400.         and     cx, 0xFFF0      ; clear address decode type
  401.         mov     [es:0x9031], cx
  402. .nopci:
  403.  
  404.     mov   al,0xf6         ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå
  405.     out   0x60,al
  406.     xor   cx,cx
  407. wait_loop:       ; variant 2
  408. ; reading state of port of 8042 controller
  409.         in      al,64h
  410.         and     al,00000010b  ; ready flag
  411. ; wait until 8042 controller is ready
  412.         loopnz  wait_loop
  413.  
  414. ; --------------- APM ---------------------
  415.     push    0
  416.     pop    es
  417.     mov    word [es : 0x9044], 0        ; ver = 0.0 (APM not found)
  418.     mov    ax, 0x5300
  419.     xor    bx, bx
  420.     int    0x15
  421.     jc    apm_end                ; APM not found
  422.     test    cx, 2
  423.     jz    apm_end                ; APM 32-bit protected-mode interface not supported
  424.     mov    [es : 0x9044], ax        ; Save APM Version
  425.     mov    [es : 0x9046], cx        ; Save APM flags
  426.    
  427.     ; Write APM ver ----
  428.     and    ax, 0xf0f
  429.     add    ax, '00'
  430.     mov    si, msg_apm - 0x10000
  431.     mov    [si + 5], ah
  432.     mov    [si + 7], al
  433.     _setcursor 0, 3
  434.     call    printplain
  435.     _setcursor d80x25_top_num,0
  436.     ; ------------------
  437.    
  438.     mov    ax, 0x5304            ; Disconnect interface
  439.     xor    bx, bx
  440.     int    0x15
  441.     mov    ax, 0x5303            ; Connect 32 bit mode interface
  442.     xor    bx, bx
  443.     int    0x15
  444.     ; init selectors
  445.     movzx    eax, ax ; real-mode segment base address of protected-mode 32-bit code segment
  446.     shl    eax, 4
  447.     mov    [apm_code_32 - 0x10000 + 2], ax
  448.     shr    eax, 16
  449.     mov    [apm_code_32 - 0x10000 + 4], al
  450.     movzx    ecx, cx ; real-mode segment base address of protected-mode 16-bit code segment
  451.     shl    ecx, 4
  452.     mov    [apm_code_16 - 0x10000 + 2], cx
  453.     shr    ecx, 16
  454.     mov    [apm_code_16 - 0x10000 + 4], cl
  455.     movzx    edx, dx ; real-mode segment base address of protected-mode 16-bit data segment
  456.     shl    edx, 4
  457.     mov    [apm_data_16 - 0x10000 + 2], dx
  458.     shr    edx, 16
  459.     mov    [apm_data_16 - 0x10000 + 4], dl
  460.     mov    [es : 0x9040], ebx              ; offset of APM entry point
  461. apm_end:
  462. ; -----------------------------------------        
  463.  
  464. ; DISPLAY VESA INFORMATION
  465.  
  466.     push    0
  467.     pop    es
  468.         mov     ax,0x4f00
  469.         mov     di,0xa000
  470.         int     0x10
  471.         cmp     ax,0x004f
  472.         mov    si, novesa-0x10000
  473.         jnz    @f
  474.         mov     ax,[es:di+4]
  475.         add     ax,'0'*256+'0'
  476.         mov    si,vervesa-0x10000
  477.         mov     [si+vervesa_off], ah
  478.         mov     [si+vervesa_off+2], al
  479. @@:     call    print
  480.  
  481. ; \begin{diamond}[30.11.2005]
  482. cfgmanager:
  483. ; settings:
  484. ; a) preboot_graph = graphical mode
  485. ;    preboot_gprobe = probe this mode?
  486. ; b) preboot_mtrr = use hardware acceleration?
  487. ; c) preboot_vrrm = use VRR?
  488. ; d) preboot_device = from what boot?
  489.     mov    di, preboot_graph-0x10000
  490. ; check bootloader block
  491.     cmp    [.loader_block-0x10000], -1
  492.     jz     .noloaderblock
  493.     les    bx, [.loader_block-0x10000]
  494.     cmp    byte [es:bx], 1
  495.     mov    si, loader_block_error-0x10000
  496.     jnz    sayerr
  497.     test    byte [es:bx+1], 1
  498.     jz    @f
  499. ; image in memory present
  500.     cmp    [di+preboot_device-preboot_graph], 0
  501.     jnz    @f
  502.     mov    [di+preboot_device-preboot_graph], 3
  503. @@:
  504. .noloaderblock:
  505. ; determine default settings
  506.     mov    [.bSettingsChanged-0x10000], 0
  507.     cmp    byte [di], 0
  508.     jnz    .preboot_gr_end
  509.     mov    [di+preboot_gprobe-preboot_graph], 0
  510.     mov    al, [vervesa+vervesa_off-0x10000]
  511.     cmp    al, 'x'
  512.     jz    .novesa
  513.     cmp    al, '1'
  514.     jz    .vesa12
  515.     mov    [di+preboot_gprobe-preboot_graph], 2
  516.     mov    al, 3
  517.     jmp    @f
  518. .vesa12:
  519.     mov    al, 7
  520.     jmp    @f
  521. .novesa:
  522.     mov    al, 10
  523. @@:
  524.     mov    [di], al
  525. .preboot_gr_end:
  526.     cmp    [di+preboot_mtrr-preboot_graph], 1
  527.     adc    [di+preboot_mtrr-preboot_graph], 0
  528.     cmp    [di+preboot_vrrm-preboot_graph], 1
  529.     adc    [di+preboot_vrrm-preboot_graph], 0
  530.     cmp    [di+preboot_device-preboot_graph], 1
  531.     adc    [di+preboot_device-preboot_graph], 0
  532. ; notify user
  533.     mov    si, linef-0x10000
  534.     call    print
  535.     mov    si, start_msg-0x10000
  536.     call    print
  537.     mov    si, time_msg-0x10000
  538.     call    print
  539. ; get start time
  540.     call    .gettime
  541.     mov    [.starttime-0x10000], eax
  542.     mov    word [.timer-0x10000], .newtimer
  543.     mov    word [.timer-0x10000+2], cs
  544. .printcfg:
  545.     _setcursor 9,0
  546.     mov    si, current_cfg_msg-0x10000
  547.     call    print
  548.     mov    si, curvideo_msg-0x10000
  549.     call    print
  550.     mov    al, [preboot_graph-0x10000]
  551.     cmp    al, 8
  552.     ja    .pnovesa
  553.     mov    dl, al
  554.     and    eax, 3
  555.     mov    si, [modes_msg-0x10000+eax*2]
  556.     call    printplain
  557.     mov    si, modevesa20-0x10000
  558.     cmp    dl, 4
  559.     jbe    @f
  560.     mov    si, modevesa12-0x10000
  561. @@:
  562.     call    printplain
  563.     cmp    dl, 4
  564.     ja    .x
  565.     mov    si, probeno_msg-0x10000
  566.     cmp    [preboot_gprobe-0x10000], 2
  567.     jnz    @f
  568.     mov    si, probeok_msg-0x10000
  569. @@:
  570.     call    printplain
  571. .x:
  572.     jmp    .c
  573. .pnovesa:
  574.     cmp    al, 9
  575.     mov    si, mode9-0x10000
  576.     jz    @b
  577.     mov    si, mode10-0x10000
  578.     jmp    @b
  579. .c:
  580.     mov    si, linef-0x10000
  581.     call    printplain
  582.     mov    si, mtrr_msg-0x10000
  583.     cmp    [preboot_mtrr-0x10000], 1
  584.     call    .say_on_off
  585.     mov    si, vrrm_msg-0x10000
  586.     cmp    [preboot_vrrm-0x10000], 1
  587.     call    .say_on_off
  588.     mov    si, preboot_device_msg-0x10000
  589.     call    print
  590.     mov    al, [preboot_device-0x10000]
  591.     and    eax, 3
  592.     mov    si, [preboot_device_msgs-0x10000+eax*2]
  593.     call    printplain
  594. .wait:
  595.     _setcursor 25,0        ; out of screen
  596. ; set timer interrupt handler
  597.     cli
  598.     push    0
  599.     pop    es
  600.     mov    eax, [es:8*4]
  601.     mov    [.oldtimer-0x10000], eax
  602.     mov    eax, [.timer-0x10000]
  603.     mov    [es:8*4], eax
  604.     sti
  605. ; wait for keypressed
  606.     mov    ah, 0
  607.     int    16h
  608.     push    ax
  609. ; restore timer interrupt
  610.     push    0
  611.     pop    es
  612.     mov    eax, [.oldtimer-0x10000]
  613.     mov    [es:8*4], eax
  614.     mov    [.timer-0x10000], eax
  615.     _setcursor 7,0
  616.     mov    si, space_msg-0x10000
  617.     call    printplain
  618.     pop    ax
  619. ; switch on key
  620.     cmp    al, 13
  621.     jz    .continue
  622.     or    al, 20h
  623.     cmp    al, 'a'
  624.     jz    .change_a
  625.     cmp    al, 'b'
  626.     jz    .change_b
  627.     cmp    al, 'c'
  628.     jz    .change_c
  629.     cmp    al, 'd'
  630.     jnz    .wait
  631.     _setcursor 15,0
  632.     mov     si,bdev-0x10000
  633.     call    print
  634.     mov     bx,'13'
  635.     call    getkey
  636.     mov    [preboot_device-0x10000], al
  637.     _setcursor 13,0
  638. .d:
  639.     mov    [.bSettingsChanged-0x10000], 1
  640.     mov    si, space_msg-0x10000
  641.     call    printplain
  642.     _setcursor 15,0
  643.     mov    cx, 6
  644. @@:
  645.     call    printplain
  646.     loop    @b
  647.     jmp    .printcfg
  648. .change_a:
  649.     _setcursor 15,0
  650.     mov    si, gr_mode-0x10000
  651.     call    printplain
  652.     mov     bx, '09'
  653.     call    getkey
  654.     mov    [preboot_graph-0x10000], al
  655.     cmp    al, 4
  656.     ja    @f
  657.     mov    si, probetext-0x10000
  658.     call    printplain
  659.     mov    bx, '12'
  660.     call    getkey
  661.     mov    [preboot_gprobe-0x10000], al
  662. @@:
  663.     _setcursor 10,0
  664.     jmp    .d
  665. .change_b:
  666.     _setcursor 15,0
  667.     mov    si, gr_acc-0x10000
  668.     call    print
  669.     mov    bx, '12'
  670.     call    getkey
  671.     mov    [preboot_mtrr-0x10000], al
  672.     _setcursor 11,0
  673.     jmp    .d
  674. .change_c:
  675.     _setcursor 15,0
  676.     mov    si, vrrmprint-0x10000
  677.     call    print
  678.     mov    bx, '12'
  679.     call    getkey
  680.     mov    [preboot_vrrm-0x10000], al
  681.     _setcursor 12,0
  682.     jmp    .d
  683. .say_on_off:
  684.     pushf
  685.     call    print
  686.     mov    si, on_msg-0x10000
  687.     popf
  688.     jz    @f
  689.     mov    si, off_msg-0x10000
  690. @@:    call    printplain
  691.     ret
  692. ; novesa and vervesa strings are not used at the moment of executing this code
  693. virtual at novesa
  694. .oldtimer dd ?
  695. .starttime dd ?
  696. .bSettingsChanged db ?
  697. .timer dd ?
  698. end virtual
  699.         org $+0x10000
  700. .loader_block dd -1
  701.         org $-0x10000
  702. .gettime:
  703.     mov    ah, 0
  704.     int    1Ah
  705.     xchg    ax, cx
  706.     shl    eax, 10h
  707.     xchg    ax, dx
  708.     ret
  709. .newtimer:
  710.     push    ds
  711.     push    cs
  712.     pop    ds
  713.     pushf
  714.     call    [.oldtimer-0x10000]
  715.     pushad
  716.     call    .gettime
  717.     sub    eax, [.starttime-0x10000]
  718.     sub    ax, 18*5
  719.     jae    .timergo
  720.     neg    ax
  721.     add    ax, 18-1
  722.     mov    bx, 18
  723.     xor    dx, dx
  724.     div    bx
  725. if lang eq ru
  726. ; ¯®¤®¦¤¨â¥ 5 ᥪ㭤, 4/3/2 ᥪ㭤ë, 1 ᥪ㭤ã
  727.     cmp    al, 5
  728.     mov    cl, ' '
  729.     jae    @f
  730.     cmp    al, 1
  731.     mov    cl, 'ã'
  732.     jz    @f
  733.     mov    cl, 'ë'
  734. @@:    mov    [time_str+9-0x10000], cl
  735. else
  736. ; wait 5/4/3/2 seconds, 1 second
  737.     cmp    al, 1
  738.     mov    cl, 's'
  739.     ja    @f
  740.     mov    cl, ' '
  741. @@:    mov    [time_str+9-0x10000], cl
  742. end if
  743.     add    al, '0'
  744.     mov    [time_str+1-0x10000], al
  745.     mov    si, time_msg-0x10000
  746.     _setcursor 7,0
  747.     call    print
  748.     _setcursor 25,0
  749.     popad
  750.     pop    ds
  751.     iret
  752. .timergo:
  753.     push    0
  754.     pop    es
  755.     mov    eax, [.oldtimer-0x10000]
  756.     mov    [es:8*4], eax
  757.     mov    sp, 0EC00h
  758. .continue:
  759.     sti
  760.     _setcursor 6,0
  761.     mov    si, space_msg-0x10000
  762.     call    printplain
  763.     call    printplain
  764.     _setcursor 6,0
  765.     mov    si, loading_msg-0x10000
  766.     call    print
  767.     _setcursor 15,0
  768.     cmp    [.bSettingsChanged-0x10000], 0
  769.     jz    .load
  770.     cmp    [.loader_block-0x10000], -1
  771.     jz    .load
  772.     les    bx, [.loader_block-0x10000]
  773.     mov    eax, [es:bx+3]
  774.     push    ds
  775.     pop    es
  776.     test    eax, eax
  777.     jz    .load
  778.     push    eax
  779.     mov    si, save_quest-0x10000
  780.     call    print
  781. .waityn:
  782.     mov    ah, 0
  783.     int    16h
  784.     or    al, 20h
  785.     cmp    al, 'n'
  786.     jz    .loadc
  787.     cmp    al, 'y'
  788.     jnz    .waityn
  789.     call    putchar
  790.     mov    byte [space_msg-0x10000+80], 186
  791.     pop    eax
  792.     push    cs
  793.     push    .cont
  794.     push    eax
  795.     retf
  796. .loadc:
  797.     pop    eax
  798. .cont:
  799.     push    cs
  800.     pop    ds
  801.     mov    si, space_msg-0x10000
  802.     mov    byte [si+80], 0
  803.     _setcursor 15,0
  804.     call    printplain
  805.     _setcursor 15,0
  806. .load:
  807. ; \end{diamond}[02.12.2005]
  808.  
  809. ; ASK GRAPHICS MODE
  810.  
  811.     movzx    ax, [preboot_graph-0x10000]
  812.     push    0
  813.     pop    es
  814. ; address is gr_table+6*(ax-1)-0x10000
  815.         add    ax, ax
  816.         lea    si, [gr_table-0x10000 + eax + eax*2 - 6]
  817.         mov     bx,[si+0]
  818.         mov     cx,[si+2]
  819.         mov     dx,[si+4]
  820.         cmp    al, 9*2
  821.         mov    al, 32    ; BPP
  822.         jb    @f
  823.         mov    [es:0x9000], al
  824.         mov    dword [es:0x9018], 0x800000
  825.        @@:
  826.         mov     [es:0x9008],bx
  827.         mov     [es:0x900A],cx
  828.         mov     [es:0x900C],dx
  829.         test    bh, bh
  830.         jz    nov
  831.  
  832. ; USE DEFAULTS OR PROBE
  833.  
  834. ; bx - mode : cx - x size : dx - y size
  835.     cmp    [preboot_gprobe-0x10000], 1
  836.     jz    noprobe
  837.  
  838.         mov     bx,0x100
  839.      newprobe:
  840.         inc     bx
  841.         cmp     bx,0x17f
  842.         mov    si,prnotfnd-0x10000
  843.         jz    sayerr
  844.  
  845.      probemore:
  846.          push    cx
  847.         mov     ax,0x4f01
  848.         mov     cx,bx
  849.         and     cx,0xfff
  850.         mov     di,0xa000
  851.         int     0x10
  852.         pop    cx
  853.  
  854.     test    byte [es:di], 80h    ; lfb?
  855.     jz    newprobe
  856.     cmp    [es:di+0x12], cx    ; x size?
  857.     jnz    newprobe
  858.     cmp    [es:di+0x14], dx    ; y size?
  859.     jnz    newprobe
  860.     cmp    byte [es:di+0x19], 32 ;24
  861.     jb    newprobe
  862.  
  863. ;       add     bx,0100000000000000b
  864.     or    bh, 40h
  865.         mov     [es:0x9008],bx
  866.  
  867.      noprobe:
  868.  
  869.  
  870. ; FIND VESA 2.0 LFB & BPP
  871.  
  872.         mov     ax,0x4f01
  873.         mov     cx,bx
  874.         and     cx,0xfff
  875.         mov     di,0xa000
  876.         int     0x10
  877.         ; LFB
  878.         mov     eax,[es:di+0x28]
  879.         mov     [es:0x9018],eax
  880.         ; ---- vbe voodoo
  881.         BytesPerScanLine equ 0x10
  882.         mov ax, [es:di+BytesPerScanLine]
  883.         mov [es:0x9001],ax
  884.         ; BPP
  885.         mov     al,byte [es:di+0x19]
  886.         mov     [es:0x9000],al
  887.        nov:
  888.         cmp     al,24
  889.         mov    si,bt24-0x10000
  890.         jz    bppl
  891.         cmp     al,32
  892.         mov     si,bt32-0x10000
  893.         jz     bppl
  894.         mov     si,btns-0x10000
  895.         jmp    sayerr
  896.        bppl:
  897.         call    print
  898.  
  899.  
  900. ; FIND VESA 1.2 PM BANK SWITCH ADDRESS
  901.  
  902.     push    es
  903.         mov     ax,0x4f0A
  904.         xor    bx, bx
  905.         int     0x10
  906.         xor     eax,eax
  907.         mov     ax,es
  908.         shl     eax,4
  909.         movzx   ebx,di
  910.         add     eax,ebx
  911.         mov     bx,[es:di]
  912.         add     eax,ebx
  913.         pop     es
  914.         mov     [es:0x9014],eax
  915.  
  916.  
  917. ; GRAPHICS ACCELERATION
  918.  
  919.         mov     al, [preboot_mtrr-0x10000]
  920.         mov     [es:0x901C],al
  921.  
  922. ; VRR_M USE
  923.  
  924.         mov     al,[preboot_vrrm-0x10000]
  925.         mov     [es:0x9030],al
  926.  
  927.  
  928. ; MEMORY MODEL
  929.  
  930. ;        movzx   eax,byte [es:preboot_memory-0x10000]
  931. ;        cmp     eax,0
  932. ;        jne     pre_mem
  933. ;;;;;;;;;;;;;;;;;;;;;;;;;
  934. ; mario79 - memory size ;
  935. ;;;;;;;;;;;;;;;;;;;;;;;;;
  936. ;           mov ax,0E801h
  937. ;;;           xor bx,bx    ; thanks to Alexei for bugfix [18.07.2004]
  938. ;           xor cx, cx
  939. ;           xor dx, dx
  940. ;           int 0x15
  941. ;           movzx ebx, dx ;bx
  942. ;           movzx eax, cx ;ax
  943. ;           shl   ebx,6   ; ïåðåâîä â êèëîáàéòû (x64)
  944. ;           add   eax,ebx
  945. ;           add eax, 1000h ;440h
  946. ;           cmp eax,40000h ; 256?
  947. ;           jge mem_256_z
  948. ;           cmp eax,20000h ; 128?
  949. ;           jge mem_128_z
  950. ;           cmp eax,10000h ; 64?
  951. ;           jge mem_64_z
  952. ;           cmp eax,8000h ; 32?
  953. ;           jge mem_32_z
  954. ;           jmp mem_16_z
  955. ;
  956. ;mem_256_z: mov     si,memokz256-0x10000
  957. ;           call    printplain
  958. ;           mov eax,5
  959. ;           jmp pre_mem
  960. ;mem_128_z: mov     si,memokz128-0x10000
  961. ;           call    printplain
  962. ;           mov eax,4
  963. ;           jmp pre_mem
  964. ;mem_64_z:  mov     si,memokz64-0x10000
  965. ;           call    printplain
  966. ;           mov eax,3
  967. ;           jmp pre_mem
  968. ;mem_32_z:  mov     si,memokz32-0x10000
  969. ;           call    printplain
  970. ;           mov eax,2
  971. ;           jmp pre_mem
  972. ;mem_16_z:  mov     si,memokz16-0x10000
  973. ;           call    printplain
  974. ;           mov eax,1
  975. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  976. ;      pre_mem:
  977. ;        push    word 0x0000
  978. ;        pop     es
  979. ;        mov     [es:0x9030],al
  980. ;        push    word 0x1000
  981. ;        pop     es
  982. ;        mov     si,linef-0x10000
  983. ;        call    printplain
  984.  
  985.  
  986.  
  987.  
  988. ; DIRECT WRITE TO LFB, PAGING DISABLED
  989.  
  990. ;        movzx   eax,byte [es:preboot_lfb-0x10000]
  991. ;        mov     eax,1                             ; paging disabled
  992. ;        cmp     eax,0
  993. ;        jne     pre_lfb
  994. ;        mov     si,gr_direct-0x10000
  995. ;        call    printplain
  996. ;        mov     ebx,'12'
  997. ;        call    getkey
  998. ;      pre_lfb:
  999. ;        push    word 0x0000
  1000. ;        pop     es
  1001. ;        mov     [es:0x901E],al
  1002. ;        mov     ax,0x1000
  1003. ;        mov     es,ax
  1004. ;        mov     si,linef-0x10000
  1005. ;        call    printplain
  1006.         mov     [es:0x901E],byte 1
  1007.  
  1008.  
  1009.  
  1010. ; BOOT DEVICE
  1011.  
  1012.     mov    al, [preboot_device-0x10000]
  1013.         dec     al
  1014.         mov     [boot_dev-0x10000],al
  1015.  
  1016. ; READ DISKETTE TO MEMORY
  1017.  
  1018. ;        cmp     [boot_dev-0x10000],0
  1019.         jne     no_sys_on_floppy
  1020.         mov     si,diskload-0x10000
  1021.         call    print
  1022.         xor    ax, ax            ; reset drive
  1023.         xor    dx, dx
  1024.         int     0x13
  1025. ; now load floppy image to memory
  1026. ; at first load boot sector and first FAT table
  1027.         mov     cx, 0x0001      ; startcyl,startsector
  1028.         xor     dx, dx          ; starthead,drive
  1029.         mov     al, 1+9         ; no of sectors to read
  1030.         mov     bx, 0xB000      ; es:bx -> data area
  1031.         call    boot_read_floppy
  1032. ; and copy them to extended memory
  1033.         mov     si, movedesc-0x10000
  1034.         mov     [si+8*2+3], bh
  1035.         push    es
  1036.         push    ds
  1037.         pop     es
  1038.         mov     cx, 256*10
  1039.         mov     ah, 0x87
  1040.         int     0x15
  1041.         test    ah, ah
  1042.         jz      @f
  1043. sayerr_floppy:
  1044.         mov     dx, 0x3f2
  1045.         mov     al, 0
  1046.         out     dx, al
  1047.         mov     si, memmovefailed-0x10000
  1048.         jmp     sayerr_plain
  1049. @@:
  1050.         add     dword [si+8*3+2], 512*10
  1051. ; copy FAT to second copy
  1052.         mov     byte [si+8*2+3], 0xB2
  1053.         mov     cx, 256*9
  1054.         mov     ah, 0x87
  1055.         int     0x15
  1056.         pop     es
  1057.         test    ah, ah
  1058.         jnz     sayerr_floppy
  1059.         add     dword [si+8*3+2], 512*9
  1060. ; calculate total number of sectors to read
  1061.         mov     ax, 1+9+14      ; boot+FAT+root
  1062.         mov     di, 0xB203
  1063. .calc_loop:
  1064.         test    word [es:di], 0xFFF
  1065.         jz      @f
  1066.         inc     ax
  1067. @@:
  1068.         test    word [es:di+1], 0xFFF0
  1069.         jz      @f
  1070.         inc     ax
  1071. @@:
  1072.         add     di, 3
  1073.         cmp     di, 0xB200+1440*3
  1074.         jb      .calc_loop
  1075.         push    ax
  1076.         mov     bp, 1+9         ; already read sectors
  1077. ; now read rest
  1078.         mov     byte [si+8*2+3], 0xA0
  1079.         mov     di, 2-14        ; absolute sector-31
  1080.         mov     cx, 0x0002      ; cylinder=0, sector=2
  1081.         mov     dx, 0x0100      ; head=1, disk=0
  1082. .read_loop:
  1083. ; determine whether sector must be read
  1084.         cmp     di, 2
  1085.         jl      .read
  1086.         mov     bx, di
  1087.         shr     bx, 1
  1088.         jnc     .even
  1089.         test    word [es:bx+di+0xB200], 0xFFF0
  1090.         jmp     @f
  1091. .even:
  1092.         test    word [es:bx+di+0xB200], 0xFFF
  1093. @@:
  1094.         jz      .skip
  1095. .read:
  1096.         mov     bx, 0xA000
  1097.         mov     al, 1           ; 1 sector
  1098.         call    boot_read_floppy
  1099.         inc     bp
  1100.         push    es
  1101.         push    ds
  1102.         pop     es
  1103.         pusha
  1104.         mov     cx, 256
  1105.         mov     ah, 0x87
  1106.         int     0x15
  1107.         test    ah, ah
  1108.         popa
  1109.         pop     es
  1110.         jnz     sayerr_floppy
  1111. .skip:
  1112.         add     dword [si+8*3+2], 512
  1113.         inc     cx
  1114.         cmp     cl, 19
  1115.         jnz     @f
  1116.         mov     cl, 1
  1117.         inc     dh
  1118.         cmp     dh, 2
  1119.         jnz     @f
  1120.         mov     dh, 0
  1121.         inc     ch
  1122. @@:
  1123.         pop     ax
  1124.         push    ax
  1125.         pusha
  1126. ; draw percentage
  1127. ; total sectors: ax
  1128. ; read sectors: bp
  1129.         xchg    ax, bp
  1130.         mov     cx, 100
  1131.         mul     cx
  1132.         div     bp
  1133.         aam
  1134.         xchg    al, ah
  1135.         add     ax, '00'
  1136.         mov     si, pros-0x10000
  1137.         cmp     [si], ax
  1138.         jz      @f
  1139.         mov     [si], ax
  1140.         call    printplain
  1141. @@:
  1142.         popa
  1143.         inc     di
  1144.         cmp     di, 2880-31
  1145.         jnz     .read_loop
  1146.  
  1147. ;        mov     cx, 0x0001      ; startcyl,startsector
  1148. ;        xor     dx, dx          ; starthead,drive
  1149. ;        push    word 80*2               ; read no of sect
  1150. ;       reads:
  1151. ;        pusha
  1152. ;        xor     si,si
  1153. ;       newread:
  1154. ;        mov     bx,0xa000               ; es:bx -> data area
  1155. ;        mov     ax,0x0200+18            ; read, no of sectors to read
  1156. ;        int     0x13
  1157. ;        test    ah, ah
  1158. ;        jz      goodread
  1159. ;        inc    si
  1160. ;        cmp     si,10
  1161. ;        jnz     newread
  1162. ;        mov     si,badsect-0x10000
  1163. ;sayerr_plain:
  1164. ;        call    printplain
  1165. ;        jmp     $
  1166. ;       goodread:
  1167. ;        ; move -> 1mb
  1168. ;        mov     si,movedesc-0x10000
  1169. ;        push    es
  1170. ;        push    ds
  1171. ;        pop     es
  1172. ;        mov     cx,256*18
  1173. ;        mov     ah,0x87
  1174. ;        int     0x15
  1175. ;        pop    es
  1176. ;
  1177. ;        test    ah,ah                  ; was the move successfull ?
  1178. ;        je      goodmove
  1179. ;        mov     dx,0x3f2              ; floppy motor off
  1180. ;        mov     al,0
  1181. ;        out     dx,al
  1182. ;        mov     si,memmovefailed-0x10000
  1183. ;        jmp    sayerr_plain
  1184. ;      goodmove:
  1185. ;
  1186. ;    add    dword [movedesc-0x10000+0x18+2], 512*18
  1187. ;        popa
  1188. ;        inc     dh
  1189. ;        cmp     dh,2
  1190. ;        jnz     bb2
  1191. ;        mov     dh,0
  1192. ;        inc     ch
  1193. ;        pusha                        ; print prosentage
  1194. ;        mov     si,pros-0x10000
  1195. ;    shr    ch, 2
  1196. ;    mov    al, '5'
  1197. ;    test    ch, 1
  1198. ;    jnz    @f
  1199. ;    mov    al, '0'
  1200. ;@@:
  1201. ;    mov    [si+1], al
  1202. ;    shr    ch, 1
  1203. ;    add    ch, '0'
  1204. ;    mov    [si], ch
  1205. ;        call    printplain
  1206. ;        popa
  1207. ;       bb2:
  1208. ;        pop     ax
  1209. ;        dec     ax
  1210. ;        push    ax
  1211. ;        jnz     reads
  1212. ;       readdone:
  1213. ;        pop     ax
  1214.         mov     si,backspace2-0x10000
  1215.         call    printplain
  1216.         mov     si,okt-0x10000
  1217.         call    printplain
  1218.        no_sys_on_floppy:
  1219.         xor    ax, ax        ; reset drive
  1220.         xor    dx, dx
  1221.         int     0x13
  1222.        mov dx,0x3f2 ; floppy motor off
  1223.        mov al,0
  1224.        out dx,al
  1225.  
  1226.     push    es
  1227. ; PAGE TABLE
  1228.  
  1229.     push    dword [es:0x9018]
  1230.  
  1231.         map_mem equ 64                ; amount of memory to map
  1232.  
  1233.         push    0x6000
  1234.         pop    es                    ; es:di = 6000:0
  1235.         xor     di,di
  1236.         mov     cx,256*map_mem         ; Map (mapmem) M
  1237. ; initialize as identity mapping
  1238.     xor    eax, eax
  1239.     call    pagetable_set
  1240.  
  1241.        
  1242. ; 4 KB PAGE DIRECTORY
  1243.  
  1244.     push    0x7F00
  1245.     pop    es                ; es:di = 7F00:0
  1246.         xor     di, di
  1247.         mov     cx, 64 / 4
  1248.         mov     eax, 0x60007            ; for 0 M
  1249.         call    pagetable_set
  1250.         xor     si,si
  1251.         mov     di,second_base_address shr 20
  1252.         mov     cx,64/2
  1253.         rep     movs word [es:di], [es:si]
  1254.        
  1255.         mov     eax, 0x7F000 +8+16      ; Page directory and enable caches
  1256.         mov     cr3, eax
  1257.  
  1258. ; SET GRAPHICS
  1259.  
  1260.     pop    es
  1261.         mov     ax,[es:0x9008]        ; vga & 320x200
  1262.         mov    bx, ax
  1263.         cmp     ax,0x13
  1264.         je      setgr
  1265.         cmp     ax,0x12
  1266.         je      setgr
  1267.         mov     ax,0x4f02            ; Vesa
  1268.        setgr:
  1269.         int     0x10
  1270.         test    ah,ah
  1271.         mov    si, fatalsel-0x10000
  1272.         jnz    sayerr
  1273. ; set mode 0x12 graphics registers:
  1274.         cmp     bx,0x12
  1275.         jne     gmok2
  1276.  
  1277.         mov     al,0x05
  1278.         mov     dx,0x03ce
  1279.         push    dx
  1280.         out     dx,al      ; select GDC mode register
  1281.         mov     al,0x02
  1282.         inc    dx
  1283.         out     dx,al      ; set write mode 2
  1284.  
  1285.         mov     al,0x02
  1286.         mov     dx,0x03c4
  1287.         out     dx,al      ; select VGA sequencer map mask register
  1288.         mov     al,0x0f
  1289.         inc    dx
  1290.         out     dx,al      ; set mask for all planes 0-3
  1291.  
  1292.         mov     al,0x08
  1293.         pop    dx
  1294.         out     dx,al      ; select GDC bit mask register
  1295.                            ; for writes to 0x03cf
  1296.  
  1297.        gmok2:
  1298.         push    ds
  1299.         pop    es
  1300.