Subversion Repositories Kolibri OS

Rev

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