Subversion Repositories Kolibri OS

Rev

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

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