Subversion Repositories Kolibri OS

Rev

Rev 160 | Rev 164 | 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. ; \begin{Mario79}
  368. ; find HDD IDE DMA PCI device
  369. ; check for PCI BIOS
  370.         mov     ax, 0xB101
  371.         int     0x1A
  372.         jc      .nopci
  373.         cmp     edx, 'PCI '
  374.         jnz     .nopci
  375. ; find PCI class code
  376. ; class 1 = mass storage
  377. ; subclass 1 = IDE controller
  378. ; a) class 1, subclass 1, programming interface 0x80
  379.         mov     ax, 0xB103
  380.         mov     ecx, 1*10000h + 1*100h + 0x80
  381.         mov     si, 0   ; device index = 0
  382.         int     0x1A
  383.         jnc     .found
  384. ; b) class 1, subclass 1, programming interface 0x85
  385.         mov     ax, 0xB103
  386.         mov     ecx, 1*10000h + 1*100h + 0x85
  387.         mov     si, 0   ; device index = 0
  388.         int     0x1A
  389.         jnc     .found
  390. ; c) class 1, subclass 1, programming interface 0x8A
  391.         mov     ax, 0xB103
  392.         mov     ecx, 1*10000h + 1*100h + 0x8A
  393.         mov     si, 0
  394.         int     0x1A
  395.         jc      .nopci
  396. .found:
  397. ; get memory base
  398.         mov     ax, 0xB10A
  399.         mov     di, 0x20        ; memory base is config register at 0x20
  400.         int     0x1A
  401.         jc      .nopci
  402.         and     cx, 0xFFF0      ; clear address decode type
  403.         mov     [es:0x9031], cx
  404. .nopci:
  405. ; \end{Mario79}
  406.  
  407.     mov   al,0xf6         ; Ñáðîñ êëàâèàòóðû, ðàçðåøèòü ñêàíèðîâàíèå
  408.     out   0x60,al
  409.     xor   cx,cx
  410. wait_loop:       ; variant 2
  411. ; reading state of port of 8042 controller
  412.         in      al,64h
  413.         and     al,00000010b  ; ready flag
  414. ; wait until 8042 controller is ready
  415.         loopnz  wait_loop
  416.  
  417. ; --------------- APM ---------------------
  418.     push    0
  419.     pop    es
  420.     mov    word [es : 0x9044], 0        ; ver = 0.0 (APM not found)
  421.     mov    ax, 0x5300
  422.     xor    bx, bx
  423.     int    0x15
  424.     jc    apm_end                ; APM not found
  425.     test    cx, 2
  426.     jz    apm_end                ; APM 32-bit protected-mode interface not supported
  427.     mov    [es : 0x9044], ax        ; Save APM Version
  428.     mov    [es : 0x9046], cx        ; Save APM flags
  429.    
  430.     ; Write APM ver ----
  431.     and    ax, 0xf0f
  432.     add    ax, '00'
  433.     mov    si, msg_apm - 0x10000
  434.     mov    [si + 5], ah
  435.     mov    [si + 7], al
  436.     _setcursor 0, 3
  437.     call    printplain
  438.     _setcursor d80x25_top_num,0
  439.     ; ------------------
  440.    
  441.     mov    ax, 0x5304            ; Disconnect interface
  442.     xor    bx, bx
  443.     int    0x15
  444.     mov    ax, 0x5303            ; Connect 32 bit mode interface
  445.     xor    bx, bx
  446.     int    0x15
  447.     ; init selectors
  448.     movzx    eax, ax ; real-mode segment base address of protected-mode 32-bit code segment
  449.     shl    eax, 4
  450.     mov    [apm_code_32 - 0x10000 + 2], ax
  451.     shr    eax, 16
  452.     mov    [apm_code_32 - 0x10000 + 4], al
  453.     movzx    ecx, cx ; real-mode segment base address of protected-mode 16-bit code segment
  454.     shl    ecx, 4
  455.     mov    [apm_code_16 - 0x10000 + 2], cx
  456.     shr    ecx, 16
  457.     mov    [apm_code_16 - 0x10000 + 4], cl
  458.     movzx    edx, dx ; real-mode segment base address of protected-mode 16-bit data segment
  459.     shl    edx, 4
  460.     mov    [apm_data_16 - 0x10000 + 2], dx
  461.     shr    edx, 16
  462.     mov    [apm_data_16 - 0x10000 + 4], dl
  463.     mov    [es : 0x9040], ebx              ; offset of APM entry point
  464. apm_end:
  465. ; -----------------------------------------        
  466.  
  467. ; DISPLAY VESA INFORMATION
  468.  
  469.     push    0
  470.     pop    es
  471.         mov     ax,0x4f00
  472.         mov     di,0xa000
  473.         int     0x10
  474.         cmp     ax,0x004f
  475.         mov    si, novesa-0x10000
  476.         jnz    @f
  477.         mov     ax,[es:di+4]
  478.         add     ax,'0'*256+'0'
  479.         mov    si,vervesa-0x10000
  480.         mov     [si+vervesa_off], ah
  481.         mov     [si+vervesa_off+2], al
  482. @@:     call    print
  483.  
  484. ; \begin{diamond}[30.11.2005]
  485. cfgmanager:
  486. ; settings:
  487. ; a) preboot_graph = graphical mode
  488. ;    preboot_gprobe = probe this mode?
  489. ; b) preboot_mtrr = use hardware acceleration?
  490. ; c) preboot_vrrm = use VRR?
  491. ; d) preboot_device = from what boot?
  492.     mov    di, preboot_graph-0x10000
  493. ; check bootloader block
  494.     cmp    [.loader_block-0x10000], -1
  495.     jz     .noloaderblock
  496.     les    bx, [.loader_block-0x10000]
  497.     cmp    byte [es:bx], 1
  498.     mov    si, loader_block_error-0x10000
  499.     jnz    sayerr
  500.     test    byte [es:bx+1], 1
  501.     jz    @f
  502. ; image in memory present
  503.     cmp    [di+preboot_device-preboot_graph], 0
  504.     jnz    @f
  505.     mov    [di+preboot_device-preboot_graph], 3
  506. @@:
  507. .noloaderblock:
  508. ; determine default settings
  509.     mov    [.bSettingsChanged-0x10000], 0
  510.     cmp    byte [di], 0
  511.     jnz    .preboot_gr_end
  512.     mov    [di+preboot_gprobe-preboot_graph], 0
  513.     mov    al, [vervesa+vervesa_off-0x10000]
  514.     cmp    al, 'x'
  515.     jz    .novesa
  516.     cmp    al, '1'
  517.     jz    .vesa12
  518.     mov    [di+preboot_gprobe-preboot_graph], 2
  519.     mov    al, 3
  520.     jmp    @f
  521. .vesa12:
  522.     mov    al, 7
  523.     jmp    @f
  524. .novesa:
  525.     mov    al, 10
  526. @@:
  527.     mov    [di], al
  528. .preboot_gr_end:
  529.     cmp    [di+preboot_mtrr-preboot_graph], 1
  530.     adc    [di+preboot_mtrr-preboot_graph], 0
  531.     cmp    [di+preboot_vrrm-preboot_graph], 1
  532.     adc    [di+preboot_vrrm-preboot_graph], 0
  533.     cmp    [di+preboot_device-preboot_graph], 1
  534.     adc    [di+preboot_device-preboot_graph], 0
  535. ; notify user
  536.     mov    si, linef-0x10000
  537.     call    print
  538.     mov    si, start_msg-0x10000
  539.     call    print
  540.     mov    si, time_msg-0x10000
  541.     call    print
  542. ; get start time
  543.     call    .gettime
  544.     mov    [.starttime-0x10000], eax
  545.     mov    word [.timer-0x10000], .newtimer
  546.     mov    word [.timer-0x10000+2], cs
  547. .printcfg:
  548.     _setcursor 9,0
  549.     mov    si, current_cfg_msg-0x10000
  550.     call    print
  551.     mov    si, curvideo_msg-0x10000
  552.     call    print
  553.     mov    al, [preboot_graph-0x10000]
  554.     cmp    al, 8
  555.     ja    .pnovesa
  556.     mov    dl, al
  557.     and    eax, 3
  558.     mov    si, [modes_msg-0x10000+eax*2]
  559.     call    printplain
  560.     mov    si, modevesa20-0x10000
  561.     cmp    dl, 4
  562.     jbe    @f
  563.     mov    si, modevesa12-0x10000
  564. @@:
  565.     call    printplain
  566.     cmp    dl, 4
  567.     ja    .x
  568.     mov    si, probeno_msg-0x10000
  569.     cmp    [preboot_gprobe-0x10000], 2
  570.     jnz    @f
  571.     mov    si, probeok_msg-0x10000
  572. @@:
  573.     call    printplain
  574. .x:
  575.     jmp    .c
  576. .pnovesa:
  577.     cmp    al, 9
  578.     mov    si, mode9-0x10000
  579.     jz    @b
  580.     mov    si, mode10-0x10000
  581.     jmp    @b
  582. .c:
  583.     mov    si, linef-0x10000
  584.     call    printplain
  585.     mov    si, mtrr_msg-0x10000
  586.     cmp    [preboot_mtrr-0x10000], 1
  587.     call    .say_on_off
  588.     mov    si, vrrm_msg-0x10000
  589.     cmp    [preboot_vrrm-0x10000], 1
  590.     call    .say_on_off
  591.     mov    si, preboot_device_msg-0x10000
  592.     call    print
  593.     mov    al, [preboot_device-0x10000]
  594.     and    eax, 3
  595.     mov    si, [preboot_device_msgs-0x10000+eax*2]
  596.     call    printplain
  597. .wait:
  598.     _setcursor 25,0        ; out of screen
  599. ; set timer interrupt handler
  600.     cli
  601.     push    0
  602.     pop    es
  603.     mov    eax, [es:8*4]
  604.     mov    [.oldtimer-0x10000], eax
  605.     mov    eax, [.timer-0x10000]
  606.     mov    [es:8*4], eax
  607.     sti
  608. ; wait for keypressed
  609.     mov    ah, 0
  610.     int    16h
  611.     push    ax
  612. ; restore timer interrupt
  613.     push    0
  614.     pop    es
  615.     mov    eax, [.oldtimer-0x10000]
  616.     mov    [es:8*4], eax
  617.     mov    [.timer-0x10000], eax
  618.     _setcursor 7,0
  619.     mov    si, space_msg-0x10000
  620.     call    printplain
  621.     pop    ax
  622. ; switch on key
  623.     cmp    al, 13
  624.     jz    .continue
  625.     or    al, 20h
  626.     cmp    al, 'a'
  627.     jz    .change_a
  628.     cmp    al, 'b'
  629.     jz    .change_b
  630.     cmp    al, 'c'
  631.     jz    .change_c
  632.     cmp    al, 'd'
  633.     jnz    .wait
  634.     _setcursor 15,0
  635.     mov     si,bdev-0x10000
  636.     call    print
  637.     mov     bx,'13'
  638.     call    getkey
  639.     mov    [preboot_device-0x10000], al
  640.     _setcursor 13,0
  641. .d:
  642.     mov    [.bSettingsChanged-0x10000], 1
  643.     mov    si, space_msg-0x10000
  644.     call    printplain
  645.     _setcursor 15,0
  646.     mov    cx, 6
  647. @@:
  648.     call    printplain
  649.     loop    @b
  650.     jmp    .printcfg
  651. .change_a:
  652.     _setcursor 15,0
  653.     mov    si, gr_mode-0x10000
  654.     call    printplain
  655.     mov     bx, '09'
  656.     call    getkey
  657.     mov    [preboot_graph-0x10000], al
  658.     cmp    al, 4
  659.     ja    @f
  660.     mov    si, probetext-0x10000
  661.     call    printplain
  662.     mov    bx, '12'
  663.     call    getkey
  664.     mov    [preboot_gprobe-0x10000], al
  665. @@:
  666.     _setcursor 10,0
  667.     jmp    .d
  668. .change_b:
  669.     _setcursor 15,0
  670.     mov    si, gr_acc-0x10000
  671.     call    print
  672.     mov    bx, '12'
  673.     call    getkey
  674.     mov    [preboot_mtrr-0x10000], al
  675.     _setcursor 11,0
  676.     jmp    .d
  677. .change_c:
  678.     _setcursor 15,0
  679.     mov    si, vrrmprint-0x10000
  680.     call    print
  681.     mov    bx, '12'
  682.     call    getkey
  683.     mov    [preboot_vrrm-0x10000], al
  684.     _setcursor 12,0
  685.     jmp    .d
  686. .say_on_off:
  687.     pushf
  688.     call    print
  689.     mov    si, on_msg-0x10000
  690.     popf
  691.     jz    @f
  692.     mov    si, off_msg-0x10000
  693. @@:    call    printplain
  694.     ret
  695. ; novesa and vervesa strings are not used at the moment of executing this code
  696. virtual at novesa
  697. .oldtimer dd ?
  698. .starttime dd ?
  699. .bSettingsChanged db ?
  700. .timer dd ?
  701. end virtual
  702.         org $+0x10000
  703. .loader_block dd -1
  704.         org $-0x10000
  705. .gettime:
  706.     mov    ah, 0
  707.     int    1Ah
  708.     xchg    ax, cx
  709.     shl    eax, 10h
  710.     xchg    ax, dx
  711.     ret
  712. .newtimer:
  713.     push    ds
  714.     push    cs
  715.     pop    ds
  716.     pushf
  717.     call    [.oldtimer-0x10000]
  718.     pushad
  719.     call    .gettime
  720.     sub    eax, [.starttime-0x10000]
  721.     sub    ax, 18*5
  722.     jae    .timergo
  723.     neg    ax
  724.     add    ax, 18-1
  725.     mov    bx, 18
  726.     xor    dx, dx
  727.     div    bx
  728. if lang eq ru
  729. ; ¯®¤®¦¤¨â¥ 5 ᥪ㭤, 4/3/2 ᥪ㭤ë, 1 ᥪ㭤ã
  730.     cmp    al, 5
  731.     mov    cl, ' '
  732.     jae    @f
  733.     cmp    al, 1
  734.     mov    cl, 'ã'
  735.     jz    @f
  736.     mov    cl, 'ë'
  737. @@:    mov    [time_str+9-0x10000], cl
  738. else
  739. ; wait 5/4/3/2 seconds, 1 second
  740.     cmp    al, 1
  741.     mov    cl, 's'
  742.     ja    @f
  743.     mov    cl, ' '
  744. @@:    mov    [time_str+9-0x10000], cl
  745. end if
  746.     add    al, '0'
  747.     mov    [time_str+1-0x10000], al
  748.     mov    si, time_msg-0x10000
  749.     _setcursor 7,0
  750.     call    print
  751.     _setcursor 25,0
  752.     popad
  753.     pop    ds
  754.     iret
  755. .timergo:
  756.     push    0
  757.     pop    es
  758.     mov    eax, [.oldtimer-0x10000]
  759.     mov    [es:8*4], eax
  760.     mov    sp, 0EC00h
  761. .continue:
  762.     sti
  763.     _setcursor 6,0
  764.     mov    si, space_msg-0x10000
  765.     call    printplain
  766.     call    printplain
  767.     _setcursor 6,0
  768.     mov    si, loading_msg-0x10000
  769.     call    print
  770.     _setcursor 15,0
  771.     cmp    [.bSettingsChanged-0x10000], 0
  772.     jz    .load
  773.     cmp    [.loader_block-0x10000], -1
  774.     jz    .load
  775.     les    bx, [.loader_block-0x10000]
  776.     mov    eax, [es:bx+3]
  777.     push    ds
  778.     pop    es
  779.     test    eax, eax
  780.     jz    .load
  781.     push    eax
  782.     mov    si, save_quest-0x10000
  783.     call    print
  784. .waityn:
  785.     mov    ah, 0
  786.     int    16h
  787.     or    al, 20h
  788.     cmp    al, 'n'
  789.     jz    .loadc
  790.     cmp    al, 'y'
  791.     jnz    .waityn
  792.     call    putchar
  793.     mov    byte [space_msg-0x10000+80], 186
  794.     pop    eax
  795.     push    cs
  796.     push    .cont
  797.     push    eax
  798.     retf
  799. .loadc:
  800.     pop    eax
  801. .cont:
  802.     push    cs
  803.     pop    ds
  804.     mov    si, space_msg-0x10000
  805.     mov    byte [si+80], 0
  806.     _setcursor 15,0
  807.     call    printplain
  808.     _setcursor 15,0
  809. .load:
  810. ; \end{diamond}[02.12.2005]
  811.  
  812. ; ASK GRAPHICS MODE
  813.  
  814.     movzx    ax, [preboot_graph-0x10000]
  815.     push    0
  816.     pop    es
  817. ; address is gr_table+6*(ax-1)-0x10000
  818.         add    ax, ax
  819.         lea    si, [gr_table-0x10000 + eax + eax*2 - 6]
  820.         mov     bx,[si+0]
  821.         mov     cx,[si+2]
  822.         mov     dx,[si+4]
  823.         cmp    al, 9*2
  824.         mov    al, 32    ; BPP
  825.         jb    @f
  826.         mov    [es:0x9000], al
  827.         mov    dword [es:0x9018], 0x800000
  828.        @@:
  829.         mov     [es:0x9008],bx
  830.         mov     [es:0x900A],cx
  831.         mov     [es:0x900C],dx
  832.         test    bh, bh
  833.         jz    nov
  834.  
  835. ; USE DEFAULTS OR PROBE
  836.  
  837. ; bx - mode : cx - x size : dx - y size
  838.     cmp    [preboot_gprobe-0x10000], 1
  839.     jz    noprobe
  840.  
  841.         mov     bx,0x100
  842.      newprobe:
  843.         inc     bx
  844.         cmp     bx,0x17f
  845.         mov    si,prnotfnd-0x10000
  846.         jz    sayerr
  847.  
  848.      probemore:
  849.          push    cx
  850.         mov     ax,0x4f01
  851.         mov     cx,bx
  852.         and     cx,0xfff
  853.         mov     di,0xa000
  854.         int     0x10
  855.         pop    cx
  856.  
  857.     test    byte [es:di], 80h    ; lfb?
  858.     jz    newprobe
  859.     cmp    [es:di+0x12], cx    ; x size?
  860.     jnz    newprobe
  861.     cmp    [es:di+0x14], dx    ; y size?
  862.     jnz    newprobe
  863.     cmp    byte [es:di+0x19], 32 ;24
  864.     jb    newprobe
  865.  
  866. ;       add     bx,0100000000000000b
  867.     or    bh, 40h
  868.         mov     [es:0x9008],bx
  869.  
  870.      noprobe:
  871.  
  872.  
  873. ; FIND VESA 2.0 LFB & BPP
  874.  
  875.         mov     ax,0x4f01
  876.         mov     cx,bx
  877.         and     cx,0xfff
  878.         mov     di,0xa000
  879.         int     0x10
  880.         ; LFB
  881.         mov     eax,[es:di+0x28]
  882.         mov     [es:0x9018],eax
  883.         ; ---- vbe voodoo
  884.         BytesPerScanLine equ 0x10
  885.         mov ax, [es:di+BytesPerScanLine]
  886.         mov [es:0x9001],ax
  887.         ; BPP
  888.         mov     al,byte [es:di+0x19]
  889.         mov     [es:0x9000],al
  890.        nov:
  891.         cmp     al,24
  892.         mov    si,bt24-0x10000
  893.         jz    bppl
  894.         cmp     al,32
  895.         mov     si,bt32-0x10000
  896.         jz     bppl
  897.         mov     si,btns-0x10000
  898.         jmp    sayerr
  899.        bppl:
  900.         call    print
  901.  
  902.  
  903. ; FIND VESA 1.2 PM BANK SWITCH ADDRESS
  904.  
  905.     push    es
  906.         mov     ax,0x4f0A
  907.         xor    bx, bx
  908.         int     0x10
  909.         xor     eax,eax
  910.         mov     ax,es
  911.         shl     eax,4
  912.         movzx   ebx,di
  913.         add     eax,ebx
  914.         mov     bx,[es:di]
  915.         add     eax,ebx
  916.         pop     es
  917.         mov     [es:0x9014],eax
  918.  
  919.  
  920. ; GRAPHICS ACCELERATION
  921.  
  922.         mov     al, [preboot_mtrr-0x10000]
  923.         mov     [es:0x901C],al
  924.  
  925. ; VRR_M USE
  926.  
  927.         mov     al,[preboot_vrrm-0x10000]
  928.         mov     [es:0x9030],al
  929.  
  930.  
  931. ; MEMORY MODEL
  932.  
  933. ;        movzx   eax,byte [es:preboot_memory-0x10000]
  934. ;        cmp     eax,0
  935. ;        jne     pre_mem
  936. ;;;;;;;;;;;;;;;;;;;;;;;;;
  937. ; mario79 - memory size ;
  938. ;;;;;;;;;;;;;;;;;;;;;;;;;
  939. ;           mov ax,0E801h
  940. ;;;           xor bx,bx    ; thanks to Alexei for bugfix [18.07.2004]
  941. ;           xor cx, cx
  942. ;           xor dx, dx
  943. ;           int 0x15
  944. ;           movzx ebx, dx ;bx
  945. ;           movzx eax, cx ;ax
  946. ;           shl   ebx,6   ; ïåðåâîä â êèëîáàéòû (x64)
  947. ;           add   eax,ebx
  948. ;           add eax, 1000h ;440h
  949. ;           cmp eax,40000h ; 256?
  950. ;           jge mem_256_z
  951. ;           cmp eax,20000h ; 128?
  952. ;           jge mem_128_z
  953. ;           cmp eax,10000h ; 64?
  954. ;           jge mem_64_z
  955. ;           cmp eax,8000h ; 32?
  956. ;           jge mem_32_z
  957. ;           jmp mem_16_z
  958. ;
  959. ;mem_256_z: mov     si,memokz256-0x10000
  960. ;           call    printplain
  961. ;           mov eax,5
  962. ;           jmp pre_mem
  963. ;mem_128_z: mov     si,memokz128-0x10000
  964. ;           call    printplain
  965. ;           mov eax,4
  966. ;           jmp pre_mem
  967. ;mem_64_z:  mov     si,memokz64-0x10000
  968. ;           call    printplain
  969. ;           mov eax,3
  970. ;           jmp pre_mem
  971. ;mem_32_z:  mov     si,memokz32-0x10000
  972. ;           call    printplain
  973. ;           mov eax,2
  974. ;           jmp pre_mem
  975. ;mem_16_z:  mov     si,memokz16-0x10000
  976. ;           call    printplain
  977. ;           mov eax,1
  978. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  979. ;      pre_mem:
  980. ;        push    word 0x0000
  981. ;        pop     es
  982. ;        mov     [es:0x9030],al
  983. ;        push    word 0x1000
  984. ;        pop     es
  985. ;        mov     si,linef-0x10000
  986. ;        call    printplain
  987.  
  988.  
  989.  
  990.  
  991. ; DIRECT WRITE TO LFB, PAGING DISABLED
  992.  
  993. ;        movzx   eax,byte [es:preboot_lfb-0x10000]
  994. ;        mov     eax,1                             ; paging disabled
  995. ;        cmp     eax,0
  996. ;        jne     pre_lfb
  997. ;        mov     si,gr_direct-0x10000
  998. ;        call    printplain
  999. ;        mov     ebx,'12'
  1000. ;        call    getkey
  1001. ;      pre_lfb:
  1002. ;        push    word 0x0000
  1003. ;        pop     es
  1004. ;        mov     [es:0x901E],al
  1005. ;        mov     ax,0x1000
  1006. ;        mov     es,ax
  1007. ;        mov     si,linef-0x10000
  1008. ;        call    printplain
  1009.         mov     [es:0x901E],byte 1
  1010.  
  1011.  
  1012.  
  1013. ; BOOT DEVICE
  1014.  
  1015.     mov    al, [preboot_device-0x10000]
  1016.         dec     al
  1017.         mov     [boot_dev-0x10000],al
  1018.  
  1019. ; READ DISKETTE TO MEMORY
  1020.  
  1021. ;        cmp     [boot_dev-0x10000],0
  1022.         jne     no_sys_on_floppy
  1023.         mov     si,diskload-0x10000
  1024.         call    print
  1025.         xor    ax, ax            ; reset drive
  1026.         xor    dx, dx
  1027.         int     0x13
  1028. ; now load floppy image to memory
  1029. ; at first load boot sector and first FAT table
  1030.         mov     cx, 0x0001      ; startcyl,startsector
  1031.         xor     dx, dx          ; starthead,drive
  1032.         mov     al, 1+9         ; no of sectors to read
  1033.         mov     bx, 0xB000      ; es:bx -> data area
  1034.         call    boot_read_floppy
  1035. ; and copy them to extended memory
  1036.         mov     si, movedesc-0x10000
  1037.         mov     [si+8*2+3], bh
  1038.         push    es
  1039.         push    ds
  1040.         pop     es
  1041.         mov     cx, 256*10
  1042.         mov     ah, 0x87
  1043.         int     0x15
  1044.         test    ah, ah
  1045.         jz      @f
  1046. sayerr_floppy:
  1047.         mov     dx, 0x3f2
  1048.         mov     al, 0
  1049.         out     dx, al
  1050.         mov     si, memmovefailed-0x10000
  1051.         jmp     sayerr_plain
  1052. @@:
  1053.         add     dword [si+8*3+2], 512*10
  1054. ; copy FAT to second copy
  1055.         mov     byte [si+8*2+3], 0xB2
  1056.         mov     cx, 256*9
  1057.         mov     ah, 0x87
  1058.         int     0x15
  1059.         pop     es
  1060.         test    ah, ah
  1061.         jnz     sayerr_floppy
  1062.         add     dword [si+8*3+2], 512*9
  1063. ; calculate total number of sectors to read
  1064.         mov     ax, 1+9+14      ; boot+FAT+root
  1065.         mov     di, 0xB203
  1066. .calc_loop:
  1067.         test    word [es:di], 0xFFF
  1068.         jz      @f
  1069.         inc     ax
  1070. @@:
  1071.         test    word [es:di+1], 0xFFF0
  1072.         jz      @f
  1073.         inc     ax
  1074. @@:
  1075.         add     di, 3
  1076.         cmp     di, 0xB200+1440*3
  1077.         jb      .calc_loop
  1078.         push    ax
  1079.         mov     bp, 1+9         ; already read sectors
  1080. ; now read rest
  1081.         mov     byte [si+8*2+3], 0xA0
  1082.         mov     di, 2-14        ; absolute sector-31
  1083.         mov     cx, 0x0002      ; cylinder=0, sector=2
  1084.         mov     dx, 0x0100      ; head=1, disk=0
  1085. .read_loop:
  1086. ; determine whether sector must be read
  1087.         cmp     di, 2
  1088.         jl      .read
  1089.         mov     bx, di
  1090.         shr     bx, 1
  1091.         jnc     .even
  1092.         test    word [es:bx+di+0xB200], 0xFFF0
  1093.         jmp     @f
  1094. .even:
  1095.         test    word [es:bx+di+0xB200], 0xFFF
  1096. @@:
  1097.         jz      .skip
  1098. .read:
  1099.         mov     bx, 0xA000
  1100.         mov     al, 1           ; 1 sector
  1101.         call    boot_read_floppy
  1102.         inc     bp
  1103.         push    es
  1104.         push    ds
  1105.         pop     es
  1106.         pusha
  1107.         mov     cx, 256
  1108.         mov     ah, 0x87
  1109.         int     0x15
  1110.         test    ah, ah
  1111.         popa
  1112.         pop     es
  1113.         jnz     sayerr_floppy
  1114. .skip:
  1115.         add     dword [si+8*3+2], 512
  1116.         inc     cx
  1117.         cmp     cl, 19
  1118.         jnz     @f
  1119.         mov     cl, 1
  1120.         inc     dh
  1121.         cmp     dh, 2
  1122.         jnz     @f
  1123.         mov     dh, 0
  1124.         inc     ch
  1125. @@:
  1126.         pop     ax
  1127.         push    ax
  1128.         pusha
  1129. ; draw percentage
  1130. ; total sectors: ax
  1131. ; read sectors: bp
  1132.         xchg    ax, bp
  1133.         mov     cx, 100
  1134.         mul     cx
  1135.         div     bp
  1136.         aam
  1137.         xchg    al, ah
  1138.         add     ax, '00'
  1139.         mov     si, pros-0x10000
  1140.         cmp     [si], ax
  1141.         jz      @f
  1142.         mov     [si], ax
  1143.         call    printplain
  1144. @@:
  1145.         popa
  1146.         inc     di
  1147.         cmp     di, 2880-31
  1148.         jnz     .read_loop
  1149.  
  1150. ;        mov     cx, 0x0001      ; startcyl,startsector
  1151. ;        xor     dx, dx          ; starthead,drive
  1152. ;        push    word 80*2               ; read no of sect
  1153. ;       reads:
  1154. ;        pusha
  1155. ;        xor     si,si
  1156. ;       newread:
  1157. ;        mov     bx,0xa000               ; es:bx -> data area
  1158. ;        mov     ax,0x0200+18            ; read, no of sectors to read
  1159. ;        int     0x13
  1160. ;        test    ah, ah
  1161. ;        jz      goodread
  1162. ;        inc    si
  1163. ;        cmp     si,10
  1164. ;        jnz     newread
  1165. ;        mov     si,badsect-0x10000
  1166. ;sayerr_plain:
  1167. ;        call    printplain
  1168. ;        jmp     $
  1169. ;       goodread:
  1170. ;        ; move -> 1mb
  1171. ;        mov     si,movedesc-0x10000
  1172. ;        push    es
  1173. ;        push    ds
  1174. ;        pop     es
  1175. ;        mov     cx,256*18
  1176. ;        mov     ah,0x87
  1177. ;        int     0x15
  1178. ;        pop    es
  1179. ;
  1180. ;        test    ah,ah                  ; was the move successfull ?
  1181. ;        je      goodmove
  1182. ;        mov     dx,0x3f2              ; floppy motor off
  1183. ;        mov     al,0
  1184. ;        out     dx,al
  1185. ;        mov     si,memmovefailed-0x10000
  1186. ;        jmp    sayerr_plain
  1187. ;      goodmove:
  1188. ;
  1189. ;    add    dword [movedesc-0x10000+0x18+2], 512*18
  1190. ;        popa
  1191. ;        inc     dh
  1192. ;        cmp     dh,2
  1193. ;        jnz     bb2
  1194. ;        mov     dh,0
  1195. ;        inc     ch
  1196. ;        pusha                        ; print prosentage
  1197. ;        mov     si,pros-0x10000
  1198. ;    shr    ch, 2
  1199. ;    mov    al, '5'
  1200. ;    test    ch, 1
  1201. ;    jnz    @f
  1202. ;    mov    al, '0'
  1203. ;@@:
  1204. ;    mov    [si+1], al
  1205. ;    shr    ch, 1
  1206. ;    add    ch, '0'
  1207. ;    mov    [si], ch
  1208. ;        call    printplain
  1209. ;        popa
  1210. ;       bb2:
  1211. ;        pop     ax
  1212. ;        dec     ax
  1213. ;        push    ax
  1214. ;        jnz     reads
  1215. ;       readdone:
  1216. ;        pop     ax
  1217.         mov     si,backspace2-0x10000
  1218.         call    printplain
  1219.         mov     si,okt-0x10000
  1220.         call    printplain
  1221.        no_sys_on_floppy:
  1222.         xor    ax, ax        ; reset drive
  1223.         xor    dx, dx
  1224.         int     0x13
  1225.        mov dx,0x3f2 ; floppy motor off
  1226.        mov al,0
  1227.        out dx,al
  1228.  
  1229.     push    es
  1230. ; PAGE TABLE
  1231.  
  1232.     push    dword [es:0x9018]
  1233.  
  1234.         map_mem equ 64                ; amount of memory to map
  1235.  
  1236.         push    0x6000
  1237.         pop    es                    ; es:di = 6000:0
  1238.         xor     di,di
  1239.         mov     cx,256*map_mem         ; Map (mapmem) M
  1240. ; initialize as identity mapping
  1241.     xor    eax, eax
  1242.     call    pagetable_set
  1243.  
  1244.        
  1245. ; 4 KB PAGE DIRECTORY
  1246.  
  1247.     push    0x7F00
  1248.     pop    es                ; es:di = 7F00:0
  1249.         xor     di, di
  1250.         mov     cx, 64 / 4
  1251.         mov     eax, 0x60007            ; for 0 M
  1252.         call    pagetable_set
  1253.         xor     si,si
  1254.         mov     di,second_base_address shr 20
  1255.         mov     cx,64/2
  1256.         rep     movs word [es:di], [es:si]
  1257.        
  1258.         mov     eax, 0x7F000 +8+16      ; Page directory and enable caches
  1259.         mov     cr3, eax
  1260.  
  1261. ; SET GRAPHICS
  1262.  
  1263.     pop    es
  1264.         mov     ax,[es:0x9008]        ; vga & 320x200
  1265.         mov    bx, ax
  1266.         cmp     ax,0x13
  1267.         je      setgr
  1268.         cmp     ax,0x12
  1269.         je      setgr
  1270.         mov     ax,0x4f02            ; Vesa
  1271.        setgr:
  1272.         int     0x10
  1273.         test    ah,ah
  1274.         mov    si, fatalsel-0x10000
  1275.         jnz    sayerr
  1276. ; set mode 0x12 graphics registers:
  1277.         cmp     bx,0x12
  1278.         jne     gmok2
  1279.  
  1280.         mov     al,0x05
  1281.         mov     dx,0x03ce
  1282.         push    dx
  1283.         out     dx,al      ; select GDC mode register
  1284.         mov     al,0x02
  1285.         inc    dx
  1286.         out     dx,al      ; set write mode 2
  1287.  
  1288.         mov     al,0x02
  1289.         mov     dx,0x03c4
  1290.         out     dx,al      ; select VGA sequencer map mask register
  1291.         mov     al,0x0f
  1292.         inc    dx
  1293.         out     dx,al      ; set mask for all planes 0-3
  1294.  
  1295.         mov     al,0x08
  1296.         pop    dx
  1297.         out     dx,al      ; select GDC bit mask register
  1298.                            ; for writes to 0x03cf
  1299.  
  1300.        gmok2:
  1301.         push    ds
  1302.         pop    es
  1303.