Subversion Repositories Kolibri OS

Rev

Rev 76 | Rev 89 | 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.     or    al, 7
  144. @@:
  145.     stosd
  146.     add    eax, 1000h
  147.     loop    @b
  148.     ret
  149.  
  150. ; 16-bit data
  151. ; videomodes table
  152.                 org $+0x10000
  153. gr_table:
  154.     dw      0x112+0100000000000000b ,  640 ,  480        ; 1
  155.     dw      0x115+0100000000000000b ,  800 ,  600        ; 2
  156.     dw      0x118+0100000000000000b , 1024 ,  768        ; 3
  157.     dw      0x11B+0100000000000000b , 1280 , 1024        ; 4
  158.     dw      0x112 ,  640 , 480                ; 5
  159.     dw      0x115 ,  800 , 600                ; 6
  160.     dw      0x118 , 1024 , 768                ; 7
  161.     dw      0x11B , 1280 ,1024                ; 8
  162.     dw    0x13, 320, 200                    ; 9
  163.     dw    0x12, 640, 480                    ; 0
  164.  
  165. ; table for move to extended memory (int 15h, ah=87h)
  166.        movedesc:
  167.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  168.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  169.  
  170.         db      0xff,0xff,0x0,0xa0,0x00,0x93,0x0,0x0
  171.         db      0xff,0xff,0x0,0x00,0x10,0x93,0x0,0x0
  172.  
  173.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  174.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  175.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  176.         db      0x00,0x00,0x0,0x00,0x00,0x00,0x0,0x0
  177.                 org $-0x10000
  178.  
  179. ;=========================================================================
  180. ;
  181. ;                           16 BIT CODE
  182. ;
  183. ;=========================================================================
  184.  
  185.  
  186. start_of_code:
  187.     cld
  188. ; \begin{diamond}[02.12.2005]
  189.     cmp    ax, 'KL'
  190.     jnz    @f
  191.     mov    word [cs:cfgmanager.loader_block-0x10000], si
  192.     mov    word [cs:cfgmanager.loader_block+2-0x10000], ds
  193. @@:
  194. ; \end{diamond}[02.12.2005]
  195.  
  196. ; set up stack
  197.     mov    ax, 3000h
  198.     mov    ss, ax
  199.     mov    sp, 0EC00h
  200. ; set up segment registers
  201.     push    cs
  202.     pop    ds
  203.     push    cs
  204.     pop    es
  205.  
  206. ; set videomode
  207.     mov    ax, 3
  208.         int  0x10
  209.  
  210.  ; Load & set russian VGA font (RU.INC)
  211.         mov  bp,RU_FNT1-10000h   ; RU_FNT1 - First part
  212.           mov  bx,1000h            ; 768 bytes
  213.           mov  cx,30h              ; 48 symbols
  214.           mov  dx,80h              ; 128 - position of first symbol
  215.         mov  ax,1100h
  216.           int  10h
  217.  
  218.         mov  bp,RU_FNT2-10000h   ; RU_FNT2 -Second part
  219.         mov  bx,1000h            ; 512 bytes
  220.         mov  cx,20h              ; 32 symbols
  221.         mov  dx,0E0h             ; 224 - position of first symbol
  222.         mov  ax,1100h
  223.           int  10h
  224.  ; End set VGA russian font
  225.  
  226. ; draw frames
  227.     push    0xb800
  228.     pop    es
  229.     xor    di, di
  230. ;        mov  si,d80x25-0x10000
  231. ;        mov  cx,80*25
  232. ;        mov  ah,1*16+15
  233. ;       dfl1:
  234. ;        lodsb
  235. ;        stosw
  236. ;        loop dfl1
  237.     mov    ah, 1*16+15
  238. ; draw top
  239.     mov    si, d80x25_top - 0x10000
  240.     mov    cx, d80x25_top_num * 80
  241. @@:
  242.     lodsb
  243.     stosw
  244.     loop    @b
  245. ; draw spaces
  246.     mov    si, space_msg - 0x10000
  247.     mov    cx, 25 - d80x25_top_num - d80x25_bottom_num
  248. dfl1:
  249.     push    cx
  250.     push    si
  251.     mov    cx, 80
  252. @@:
  253.     lodsb
  254.     stosw
  255.     loop    @b
  256.     pop    si
  257.     pop    cx
  258.     loop    dfl1
  259. ; draw bottom
  260.     mov    si, d80x25_bottom - 0x10000
  261.     mov    cx, d80x25_bottom_num * 80
  262. @@:
  263.     lodsb
  264.     stosw
  265.     loop    @b
  266.  
  267.     mov    byte [space_msg-0x10000+80], 0    ; now space_msg is null terminated
  268.  
  269.     _setcursor d80x25_top_num,0
  270.  
  271.  
  272. ; TEST FOR 386+
  273.  
  274.     mov    bx, 0x4000
  275.         pushf
  276.         pop     ax
  277.         mov     dx,ax
  278.         xor     ax,bx
  279.         push    ax
  280.         popf
  281.         pushf
  282.         pop     ax
  283.         and     ax,bx
  284.         and     dx,bx
  285.         cmp     ax,dx
  286.         jnz     cpugood
  287.         mov     si,not386-0x10000
  288. sayerr:
  289.         call    print
  290.         jmp     $
  291.      cpugood:
  292.  
  293. ; set up esp
  294.     movzx    esp, sp
  295.  
  296. ; FLUSH 8042 KEYBOARD CONTROLLER
  297.  
  298. ;// mike.dld [
  299.  ;       mov     al,0xED
  300.  ;       out     0x60,al
  301.  ;       or      cx,-1
  302.  ;     @@:
  303.  ;       in      al,0x64
  304.  ;       test    al,2
  305.  ;       jz      @f
  306.  ;       loop    @b
  307.  ;     @@:
  308.  ;       mov     al,0
  309.  ;       out     0x60,al
  310.  ;       or      cx,-1
  311.  ;     @@:
  312.  ;       in      al,0x64
  313.  ;       test    al,2
  314.  ;       jz      @f
  315.  ;       loop    @b
  316.  ;     @@:
  317. ;// mike.dld ]
  318.  
  319. ;       mov     ecx,10000
  320. ;      fl1:
  321. ;       in      al,0x64
  322. ;       loop    fl1
  323. ;       test    al,1
  324. ;       jz      fl2
  325. ;       in      al,0x60
  326. ;       jmp     fl1
  327. ;      fl2:
  328.  
  329. ;****************************************************************
  330. ; The function is modified Mario79
  331. ;*****************************************************************
  332. ; wait_kbd:        ; variant 1
  333. ;       mov      cx,2500h  ;чрфхЁцър яюЁ фър 10 ьёхъ
  334. ; test_kbd:
  335. ;       in       al,64h    ;ўшЄрхь ёюёЄю эшх ъыртшрЄєЁ√
  336. ;       test     al,2      ;яЁютхЁър сшЄр уюЄютэюёЄш
  337. ;       loopnz   test_kbd
  338.  
  339.     mov   al,0xf6         ; ╤сЁюё ъыртшрЄєЁ√, ЁрчЁх°шЄ№ ёърэшЁютрэшх
  340.     out   0x60,al
  341.     xor   cx,cx
  342. wait_loop:       ; variant 2
  343. ; reading state of port of 8042 controller
  344.         in      al,64h
  345.         and     al,00000010b  ; ready flag
  346. ; wait until 8042 controller is ready
  347.         loopnz  wait_loop
  348.  
  349. ; --------------- APM ---------------------
  350.     push    0
  351.     pop    es
  352.     mov    word [es : 0x9044], 0        ; ver = 0.0 (APM not found)
  353.     mov    ax, 0x5300
  354.     xor    bx, bx
  355.     int    0x15
  356.     jc    apm_end                ; APM not found
  357.     test    cx, 2
  358.     jz    apm_end                ; APM 32-bit protected-mode interface not supported
  359.     mov    [es : 0x9044], ax        ; Save APM Version
  360.     mov    [es : 0x9046], cx        ; Save APM flags
  361.    
  362.     ; Write APM ver ----
  363.     and    ax, 0xf0f
  364.     add    ax, '00'
  365.     mov    si, msg_apm - 0x10000
  366.     mov    [si + 5], ah
  367.     mov    [si + 7], al
  368.     _setcursor 0, 3
  369.     call    printplain
  370.     _setcursor d80x25_top_num,0
  371.     ; ------------------
  372.    
  373.     mov    ax, 0x5304            ; Disconnect interface
  374.     xor    bx, bx
  375.     int    0x15
  376.     mov    ax, 0x5303            ; Connect 32 bit mode interface
  377.     xor    bx, bx
  378.     int    0x15
  379.     ; init selectors
  380.     movzx    eax, ax ; real-mode segment base address of protected-mode 32-bit code segment
  381.     shl    eax, 4
  382.     mov    [apm_code_32 - 0x10000 + 2], ax
  383.     shr    eax, 16
  384.     mov    [apm_code_32 - 0x10000 + 4], al
  385.     movzx    ecx, cx ; real-mode segment base address of protected-mode 16-bit code segment
  386.     shl    ecx, 4
  387.     mov    [apm_code_16 - 0x10000 + 2], cx
  388.     shr    ecx, 16
  389.     mov    [apm_code_16 - 0x10000 + 4], cl
  390.     movzx    edx, dx ; real-mode segment base address of protected-mode 16-bit data segment
  391.     shl    edx, 4
  392.     mov    [apm_data_16 - 0x10000 + 2], dx
  393.     shr    edx, 16
  394.     mov    [apm_data_16 - 0x10000 + 4], dl
  395.     mov    [es : 0x9040], ebx              ; offset of APM entry point
  396. apm_end:
  397. ; -----------------------------------------        
  398.  
  399. ; DISPLAY VESA INFORMATION
  400.  
  401.     push    0
  402.     pop    es
  403.         mov     ax,0x4f00
  404.         mov     di,0xa000
  405.         int     0x10
  406.         cmp     ax,0x004f
  407.         mov    si, novesa-0x10000
  408.         jnz    @f
  409.         mov     ax,[es:di+4]
  410.         add     ax,'0'*256+'0'
  411.         mov    si,vervesa-0x10000
  412.         mov     [si+vervesa_off], ah
  413.         mov     [si+vervesa_off+2], al
  414. @@:     call    print
  415.  
  416. ; \begin{diamond}[30.11.2005]
  417. cfgmanager:
  418. ; settings:
  419. ; a) preboot_graph = graphical mode
  420. ;    preboot_gprobe = probe this mode?
  421. ; b) preboot_mtrr = use hardware acceleration?
  422. ; c) preboot_vrrm = use VRR?
  423. ; d) preboot_device = from what boot?
  424.     mov    di, preboot_graph-0x10000
  425. ; check bootloader block
  426.     cmp    [.loader_block-0x10000], 0
  427.     jz    .noloaderblock
  428.     les    bx, [.loader_block-0x10000]
  429.     cmp    byte [es:bx], 1
  430.     mov    si, loader_block_error-0x10000
  431.     jnz    sayerr
  432.     test    byte [es:bx+1], 1
  433.     jz    @f
  434. ; image in memory present
  435.     cmp    [di+preboot_device-preboot_graph], 0
  436.     jnz    @f
  437.     mov    [di+preboot_device-preboot_graph], 3
  438. @@:
  439. .noloaderblock:
  440. ; determine default settings
  441.     mov    [.bSettingsChanged-0x10000], 0
  442.     cmp    byte [di], 0
  443.     jnz    .preboot_gr_end
  444.     mov    [di+preboot_gprobe-preboot_graph], 0
  445.     mov    al, [vervesa+vervesa_off-0x10000]
  446.     cmp    al, 'x'
  447.     jz    .novesa
  448.     cmp    al, '1'
  449.     jz    .vesa12
  450.     mov    [di+preboot_gprobe-preboot_graph], 2
  451.     mov    al, 3
  452.     jmp    @f
  453. .vesa12:
  454.     mov    al, 7
  455.     jmp    @f
  456. .novesa:
  457.     mov    al, 10
  458. @@:
  459.     mov    [di], al
  460. .preboot_gr_end:
  461.     cmp    [di+preboot_mtrr-preboot_graph], 1
  462.     adc    [di+preboot_mtrr-preboot_graph], 0
  463.     cmp    [di+preboot_vrrm-preboot_graph], 1
  464.     adc    [di+preboot_vrrm-preboot_graph], 0
  465.     cmp    [di+preboot_device-preboot_graph], 1
  466.     adc    [di+preboot_device-preboot_graph], 0
  467. ; notify user
  468.     mov    si, linef-0x10000
  469.     call    print
  470.     mov    si, start_msg-0x10000
  471.     call    print
  472.     mov    si, time_msg-0x10000
  473.     call    print
  474. ; get start time
  475.     call    .gettime
  476.     mov    [.starttime-0x10000], eax
  477.     mov    word [.timer-0x10000], .newtimer
  478.     mov    word [.timer-0x10000+2], cs
  479. .printcfg:
  480.     _setcursor 9,0
  481.     mov    si, current_cfg_msg-0x10000
  482.     call    print
  483.     mov    si, curvideo_msg-0x10000
  484.     call    print
  485.     mov    al, [preboot_graph-0x10000]
  486.     cmp    al, 8
  487.     ja    .pnovesa
  488.     mov    dl, al
  489.     and    eax, 3
  490.     mov    si, [modes_msg-0x10000+eax*2]
  491.     call    printplain
  492.     mov    si, modevesa20-0x10000
  493.     cmp    dl, 4
  494.     jbe    @f
  495.     mov    si, modevesa12-0x10000
  496. @@:
  497.     call    printplain
  498.     cmp    dl, 4
  499.     ja    .x
  500.     mov    si, probeno_msg-0x10000
  501.     cmp    [preboot_gprobe-0x10000], 2
  502.     jnz    @f
  503.     mov    si, probeok_msg-0x10000
  504. @@:
  505.     call    printplain
  506. .x:
  507.     jmp    .c
  508. .pnovesa:
  509.     cmp    al, 9
  510.     mov    si, mode9-0x10000
  511.     jz    @b
  512.     mov    si, mode10-0x10000
  513.     jmp    @b
  514. .c:
  515.     mov    si, linef-0x10000
  516.     call    printplain
  517.     mov    si, mtrr_msg-0x10000
  518.     cmp    [preboot_mtrr-0x10000], 1
  519.     call    .say_on_off
  520.     mov    si, vrrm_msg-0x10000
  521.     cmp    [preboot_vrrm-0x10000], 1
  522.     call    .say_on_off
  523.     mov    si, preboot_device_msg-0x10000
  524.     call    print
  525.     mov    al, [preboot_device-0x10000]
  526.     and    eax, 3
  527.     mov    si, [preboot_device_msgs-0x10000+eax*2]
  528.     call    printplain
  529. .wait:
  530.     _setcursor 25,0        ; out of screen
  531. ; set timer interrupt handler
  532.     cli
  533.     push    0
  534.     pop    es
  535.     mov    eax, [es:8*4]
  536.     mov    [.oldtimer-0x10000], eax
  537.     mov    eax, [.timer-0x10000]
  538.     mov    [es:8*4], eax
  539.     sti
  540. ; wait for keypressed
  541.     mov    ah, 0
  542.     int    16h
  543.     push    ax
  544. ; restore timer interrupt
  545.     push    0
  546.     pop    es
  547.     mov    eax, [.oldtimer-0x10000]
  548.     mov    [es:8*4], eax
  549.     mov    [.timer-0x10000], eax
  550.     _setcursor 7,0
  551.     mov    si, space_msg-0x10000
  552.     call    printplain
  553.     pop    ax
  554. ; switch on key
  555.     cmp    al, 13
  556.     jz    .continue
  557.     or    al, 20h
  558.     cmp    al, 'a'
  559.     jz    .change_a
  560.     cmp    al, 'b'
  561.     jz    .change_b
  562.     cmp    al, 'c'
  563.     jz    .change_c
  564.     cmp    al, 'd'
  565.     jnz    .wait
  566.     _setcursor 15,0
  567.     mov     si,bdev-0x10000
  568.     call    print
  569.     mov     bx,'13'
  570.     call    getkey
  571.     mov    [preboot_device-0x10000], al
  572.     _setcursor 13,0
  573. .d:
  574.     mov    [.bSettingsChanged-0x10000], 1
  575.     mov    si, space_msg-0x10000
  576.     call    printplain
  577.     _setcursor 15,0
  578.     mov    cx, 6
  579. @@:
  580.     call    printplain
  581.     loop    @b
  582.     jmp    .printcfg
  583. .change_a:
  584.     _setcursor 15,0
  585.     mov    si, gr_mode-0x10000
  586.     call    printplain
  587.     mov     bx, '09'
  588.     call    getkey
  589.     mov    [preboot_graph-0x10000], al
  590.     cmp    al, 4
  591.     ja    @f
  592.     mov    si, probetext-0x10000
  593.     call    printplain
  594.     mov    bx, '12'
  595.     call    getkey
  596.     mov    [preboot_gprobe-0x10000], al
  597. @@:
  598.     _setcursor 10,0
  599.     jmp    .d
  600. .change_b:
  601.     _setcursor 15,0
  602.     mov    si, gr_acc-0x10000
  603.     call    print
  604.     mov    bx, '12'
  605.     call    getkey
  606.     mov    [preboot_mtrr-0x10000], al
  607.     _setcursor 11,0
  608.     jmp    .d
  609. .change_c:
  610.     _setcursor 15,0
  611.     mov    si, vrrmprint-0x10000
  612.     call    print
  613.     mov    bx, '12'
  614.     call    getkey
  615.     mov    [preboot_vrrm-0x10000], al
  616.     _setcursor 12,0
  617.     jmp    .d
  618. .say_on_off:
  619.     pushf
  620.     call    print
  621.     mov    si, on_msg-0x10000
  622.     popf
  623.     jz    @f
  624.     mov    si, off_msg-0x10000
  625. @@:    call    printplain
  626.     ret
  627. ; novesa and vervesa strings are not used at the moment of executing this code
  628. virtual at novesa
  629. .oldtimer dd ?
  630. .starttime dd ?
  631. .bSettingsChanged db ?
  632. .timer dd ?
  633. end virtual
  634.         org $+0x10000
  635. .loader_block dd 0
  636.         org $-0x10000
  637. .gettime:
  638.     mov    ah, 0
  639.     int    1Ah
  640.     xchg    ax, cx
  641.     shl    eax, 10h
  642.     xchg    ax, dx
  643.     ret
  644. .newtimer:
  645.     push    ds
  646.     push    cs
  647.     pop    ds
  648.     pushf
  649.     call    [.oldtimer-0x10000]
  650.     pushad
  651.     call    .gettime
  652.     sub    eax, [.starttime-0x10000]
  653.     sub    ax, 18*5
  654.     jae    .timergo
  655.     neg    ax
  656.     add    ax, 18-1
  657.     mov    bx, 18
  658.     xor    dx, dx
  659.     div    bx
  660. if lang eq ru
  661. ; подождите 5 секунд, 4/3/2 секунды, 1 секунду
  662.     cmp    al, 5
  663.     mov    cl, ' '
  664.     jae    @f
  665.     cmp    al, 1
  666.     mov    cl, 'у'
  667.     jz    @f
  668.     mov    cl, 'ы'
  669. @@:    mov    [time_str+9-0x10000], cl
  670. else
  671. ; wait 5/4/3/2 seconds, 1 second
  672.     cmp    al, 1
  673.     mov    cl, 's'
  674.     ja    @f
  675.     mov    cl, ' '
  676. @@:    mov    [time_str+9-0x10000], cl
  677. end if
  678.     add    al, '0'
  679.     mov    [time_str+1-0x10000], al
  680.     mov    si, time_msg-0x10000
  681.     _setcursor 7,0
  682.     call    print
  683.     _setcursor 25,0
  684.     popad
  685.     pop    ds
  686.     iret
  687. .timergo:
  688.     push    0
  689.     pop    es
  690.     mov    eax, [.oldtimer-0x10000]
  691.     mov    [es:8*4], eax
  692.     mov    sp, 0EC00h
  693. .continue:
  694.     sti
  695.     _setcursor 6,0
  696.     mov    si, space_msg-0x10000
  697.     call    printplain
  698.     call    printplain
  699.     _setcursor 6,0
  700.     mov    si, loading_msg-0x10000
  701.     call    print
  702.     _setcursor 15,0
  703.     cmp    [.bSettingsChanged-0x10000], 0
  704.     jz    .load
  705.     cmp    [.loader_block-0x10000], 0
  706.     jz    .load
  707.     les    bx, [.loader_block-0x10000]
  708.     mov    eax, [es:bx+3]
  709.     push    ds
  710.     pop    es
  711.     test    eax, eax
  712.     jz    .load
  713.     push    eax
  714.     mov    si, save_quest-0x10000
  715.     call    print
  716. .waityn:
  717.     mov    ah, 0
  718.     int    16h
  719.     or    al, 20h
  720.     cmp    al, 'n'
  721.     jz    .loadc
  722.     cmp    al, 'y'
  723.     jnz    .waityn
  724.     call    putchar
  725.     mov    byte [space_msg-0x10000+80], 186
  726.     pop    eax
  727.     push    cs
  728.     push    .cont
  729.     push    eax
  730.     retf
  731. .loadc:
  732.     pop    eax
  733. .cont:
  734.     push    cs
  735.     pop    ds
  736.     mov    si, space_msg-0x10000
  737.     mov    byte [si+80], 0
  738.     _setcursor 15,0
  739.     call    printplain
  740.     _setcursor 15,0
  741. .load:
  742. ; \end{diamond}[02.12.2005]
  743.  
  744. ; ASK GRAPHICS MODE
  745.  
  746.     movzx    ax, [preboot_graph-0x10000]
  747.     push    0
  748.     pop    es
  749. ; address is gr_table+6*(ax-1)-0x10000
  750.         add    ax, ax
  751.         lea    si, [gr_table-0x10000 + eax + eax*2 - 6]
  752.         mov     bx,[si+0]
  753.         mov     cx,[si+2]
  754.         mov     dx,[si+4]
  755.         cmp    al, 9*2
  756.         mov    al, 32    ; BPP
  757.         jb    @f
  758.         mov    [es:0x9000], al
  759.         mov    dword [es:0x9018], 0x800000
  760.        @@:
  761.         mov     [es:0x9008],bx
  762.         mov     [es:0x900A],cx
  763.         mov     [es:0x900C],dx
  764.         test    bh, bh
  765.         jz    nov
  766.  
  767. ; USE DEFAULTS OR PROBE
  768.  
  769. ; bx - mode : cx - x size : dx - y size
  770.     cmp    [preboot_gprobe-0x10000], 1
  771.     jz    noprobe
  772.  
  773.         mov     bx,0x100
  774.      newprobe:
  775.         inc     bx
  776.         cmp     bx,0x17f
  777.         mov    si,prnotfnd-0x10000
  778.         jz    sayerr
  779.  
  780.      probemore:
  781.          push    cx
  782.         mov     ax,0x4f01
  783.         mov     cx,bx
  784.         and     cx,0xfff
  785.         mov     di,0xa000
  786.         int     0x10
  787.         pop    cx
  788.  
  789.     test    byte [es:di], 80h    ; lfb?
  790.     jz    newprobe
  791.     cmp    [es:di+0x12], cx    ; x size?
  792.     jnz    newprobe
  793.     cmp    [es:di+0x14], dx    ; y size?
  794.     jnz    newprobe
  795.     cmp    byte [es:di+0x19], 32 ;24
  796.     jb    newprobe
  797.  
  798. ;       add     bx,0100000000000000b
  799.     or    bh, 40h
  800.         mov     [es:0x9008],bx
  801.  
  802.      noprobe:
  803.  
  804.  
  805. ; FIND VESA 2.0 LFB & BPP
  806.  
  807.         mov     ax,0x4f01
  808.         mov     cx,bx
  809.         and     cx,0xfff
  810.         mov     di,0xa000
  811.         int     0x10
  812.         ; LFB
  813.         mov     eax,[es:di+0x28]
  814.         mov     [es:0x9018],eax
  815.         ; ---- vbe voodoo
  816.         BytesPerScanLine equ 0x10
  817.         mov ax, [es:di+BytesPerScanLine]
  818.         mov [es:0x9001],ax
  819.         ; BPP
  820.         mov     al,byte [es:di+0x19]
  821.         mov     [es:0x9000],al
  822.        nov:
  823.         cmp     al,24
  824.         mov    si,bt24-0x10000
  825.         jz    bppl
  826.         cmp     al,32
  827.         mov     si,bt32-0x10000
  828.         jz     bppl
  829.         mov     si,btns-0x10000
  830.         jmp    sayerr
  831.        bppl:
  832.         call    print
  833.  
  834.  
  835. ; FIND VESA 1.2 PM BANK SWITCH ADDRESS
  836.  
  837.     push    es
  838.         mov     ax,0x4f0A
  839.         xor    bx, bx
  840.         int     0x10
  841.         xor     eax,eax
  842.         mov     ax,es
  843.         shl     eax,4
  844.         movzx   ebx,di
  845.         add     eax,ebx
  846.         mov     bx,[es:di]
  847.         add     eax,ebx
  848.         pop     es
  849.         mov     [es:0x9014],eax
  850.  
  851.  
  852. ; GRAPHICS ACCELERATION
  853.  
  854.         mov     al, [preboot_mtrr-0x10000]
  855.         mov     [es:0x901C],al
  856.  
  857. ; VRR_M USE
  858.  
  859.         mov     al,[preboot_vrrm-0x10000]
  860.         mov     [es:0x9030],al
  861.  
  862.  
  863. ; MEMORY MODEL
  864.  
  865. ;        movzx   eax,byte [es:preboot_memory-0x10000]
  866. ;        cmp     eax,0
  867. ;        jne     pre_mem
  868. ;;;;;;;;;;;;;;;;;;;;;;;;;
  869. ; mario79 - memory size ;
  870. ;;;;;;;;;;;;;;;;;;;;;;;;;
  871. ;           mov ax,0E801h
  872. ;;;           xor bx,bx    ; thanks to Alexei for bugfix [18.07.2004]
  873. ;           xor cx, cx
  874. ;           xor dx, dx
  875. ;           int 0x15
  876. ;           movzx ebx, dx ;bx
  877. ;           movzx eax, cx ;ax
  878. ;           shl   ebx,6   ; яхЁхтюф т ъшыюсрщЄ√ (x64)
  879. ;           add   eax,ebx
  880. ;           add eax, 1000h ;440h
  881. ;           cmp eax,40000h ; 256?
  882. ;           jge mem_256_z
  883. ;           cmp eax,20000h ; 128?
  884. ;           jge mem_128_z
  885. ;           cmp eax,10000h ; 64?
  886. ;           jge mem_64_z
  887. ;           cmp eax,8000h ; 32?
  888. ;           jge mem_32_z
  889. ;           jmp mem_16_z
  890. ;
  891. ;mem_256_z: mov     si,memokz256-0x10000
  892. ;           call    printplain
  893. ;           mov eax,5
  894. ;           jmp pre_mem
  895. ;mem_128_z: mov     si,memokz128-0x10000
  896. ;           call    printplain
  897. ;           mov eax,4
  898. ;           jmp pre_mem
  899. ;mem_64_z:  mov     si,memokz64-0x10000
  900. ;           call    printplain
  901. ;           mov eax,3
  902. ;           jmp pre_mem
  903. ;mem_32_z:  mov     si,memokz32-0x10000
  904. ;           call    printplain
  905. ;           mov eax,2
  906. ;           jmp pre_mem
  907. ;mem_16_z:  mov     si,memokz16-0x10000
  908. ;           call    printplain
  909. ;           mov eax,1
  910. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  911. ;      pre_mem:
  912. ;        push    word 0x0000
  913. ;        pop     es
  914. ;        mov     [es:0x9030],al
  915. ;        push    word 0x1000
  916. ;        pop     es
  917. ;        mov     si,linef-0x10000
  918. ;        call    printplain
  919.  
  920.  
  921.  
  922.  
  923. ; DIRECT WRITE TO LFB, PAGING DISABLED
  924.  
  925. ;        movzx   eax,byte [es:preboot_lfb-0x10000]
  926. ;        mov     eax,1                             ; paging disabled
  927. ;        cmp     eax,0
  928. ;        jne     pre_lfb
  929. ;        mov     si,gr_direct-0x10000
  930. ;        call    printplain
  931. ;        mov     ebx,'12'
  932. ;        call    getkey
  933. ;      pre_lfb:
  934. ;        push    word 0x0000
  935. ;        pop     es
  936. ;        mov     [es:0x901E],al
  937. ;        mov     ax,0x1000
  938. ;        mov     es,ax
  939. ;        mov     si,linef-0x10000
  940. ;        call    printplain
  941.         mov     [es:0x901E],byte 1
  942.  
  943.  
  944.  
  945. ; BOOT DEVICE
  946.  
  947.     mov    al, [preboot_device-0x10000]
  948.         dec     al
  949.         mov     [boot_dev-0x10000],al
  950.  
  951. ; READ DISKETTE TO MEMORY
  952.  
  953. ;        cmp     [boot_dev-0x10000],0
  954.         jne     no_sys_on_floppy
  955.         mov     si,diskload-0x10000
  956.         call    print
  957.         xor    ax, ax            ; reset drive
  958.         xor    dx, dx
  959.         int     0x13
  960.         mov     cx,0x0001               ; startcyl,startsector
  961.         xor    dx, dx            ; starthead,drive
  962.         push    word 80*2               ; read no of sect
  963.        reads:
  964.         pusha
  965.         xor     si,si
  966.        newread:
  967.         mov     bx,0xa000               ; es:bx -> data area
  968.         mov     ax,0x0200+18            ; read, no of sectors to read
  969.         int     0x13
  970.         test    ah, ah
  971.         jz      goodread
  972.         inc    si
  973.         cmp     si,10
  974.         jnz     newread
  975.         mov     si,badsect-0x10000
  976. sayerr_plain:
  977.         call    printplain
  978.         jmp     $
  979.        goodread:
  980.         ; move -> 1mb
  981.         mov     si,movedesc-0x10000
  982.         push    es
  983.         push    ds
  984.         pop     es
  985.         mov     cx,256*18
  986.         mov     ah,0x87
  987.         int     0x15
  988.         pop    es
  989.  
  990.         test    ah,ah                  ; was the move successfull ?
  991.         je      goodmove
  992.         mov     dx,0x3f2              ; floppy motor off
  993.         mov     al,0
  994.         out     dx,al
  995.         mov     si,memmovefailed-0x10000
  996.         jmp    sayerr_plain
  997.       goodmove:
  998.  
  999.     add    dword [movedesc-0x10000+0x18+2], 512*18
  1000.         popa
  1001.         inc     dh
  1002.         cmp     dh,2
  1003.         jnz     bb2
  1004.         mov     dh,0
  1005.         inc     ch
  1006.         pusha                        ; print prosentage
  1007.         mov     si,pros-0x10000
  1008.     shr    ch, 2
  1009.     mov    al, '5'
  1010.     test    ch, 1
  1011.     jnz    @f
  1012.     mov    al, '0'
  1013. @@:
  1014.     mov    [si+1], al
  1015.     shr    ch, 1
  1016.     add    ch, '0'
  1017.     mov    [si], ch
  1018.         call    printplain
  1019.         popa
  1020.        bb2:
  1021.         pop     ax
  1022.         dec     ax
  1023.         push    ax
  1024.         jnz     reads
  1025.        readdone:
  1026.         pop     ax
  1027.         mov     si,backspace2-0x10000
  1028.         call    printplain
  1029.         mov     si,okt-0x10000
  1030.         call    printplain
  1031.        no_sys_on_floppy:
  1032.         xor    ax, ax        ; reset drive
  1033.         xor    dx, dx
  1034.         int     0x13
  1035.        mov dx,0x3f2 ; floppy motor off
  1036.        mov al,0
  1037.        out dx,al
  1038.  
  1039.     push    es
  1040. ; PAGE TABLE
  1041.  
  1042.     push    dword [es:0x9018]
  1043.  
  1044.         map_mem equ 64                ; amount of memory to map
  1045.  
  1046.         push    0x6000
  1047.         pop    es                    ; es:di = 6000:0
  1048.         xor     di,di
  1049.         mov     cx,256*map_mem         ; Map (mapmem) M
  1050. ;        mov     eax,7
  1051. ;       pt2:
  1052. ;        cmp     cx,256*(map_mem-8)     ; 8 M map to LFB
  1053. ;        jnz     pt3
  1054. ;        pop     eax
  1055. ;        add     eax,7
  1056. ;       pt3:
  1057. ;        cmp     cx,256*(map_mem-12)    ; 12 M back to linear = physical
  1058. ;        jnz     pt4
  1059. ;        mov     eax,12*0x100000 + 7
  1060. ;       pt4:
  1061. ;        stosd
  1062. ;        add     eax,4096
  1063. ;        loop    pt2
  1064. ; initialize as identity mapping
  1065.     xor    eax, eax
  1066.     call    pagetable_set
  1067. ; 8M..12M map to LFB
  1068.     pop    eax
  1069. ;    mov    cx, 256*4
  1070.     mov    ch, 4
  1071.     mov    di, 2000h
  1072.     call    pagetable_set
  1073.  
  1074.     push    0x7100
  1075.     pop    es
  1076.         xor     di,di
  1077.         mov     eax,8*0x100000
  1078.         mov     cx,256*4
  1079.         call    pagetable_set
  1080.        
  1081. ; 4 KB PAGE DIRECTORY
  1082.  
  1083.     push    0x7F00
  1084.     pop    es                ; es:di = 7F00:0
  1085.         xor     di, di
  1086.         mov     cx, 64 / 4
  1087.         mov     eax, 0x60007            ; for 0 M
  1088.         call    pagetable_set
  1089.         mov     dword [es:0x800],0x71007   ;map region 0x80000000-0x803FFFFF to 0x800000-0xCFFFFF
  1090.         xor     si,si
  1091.         mov     di,second_base_address shr 20
  1092.         mov     cx,64/2
  1093.         rep     movs word [es:di], [es:si]
  1094.        
  1095.         mov     eax, 0x7F000 +8+16      ; Page directory and enable caches
  1096.         mov     cr3, eax
  1097.  
  1098. ; SET GRAPHICS
  1099.  
  1100.     pop    es
  1101.         mov     ax,[es:0x9008]        ; vga & 320x200
  1102.         mov    bx, ax
  1103.         cmp     ax,0x13
  1104.         je      setgr
  1105.         cmp     ax,0x12
  1106.         je      setgr
  1107.         mov     ax,0x4f02            ; Vesa
  1108.        setgr:
  1109.         int     0x10
  1110.         test    ah,ah
  1111.         mov    si, fatalsel-0x10000
  1112.         jnz    sayerr
  1113. ; set mode 0x12 graphics registers:
  1114.         cmp     bx,0x12
  1115.         jne     gmok2
  1116.  
  1117.         mov     al,0x05
  1118.         mov     dx,0x03ce
  1119.         push    dx
  1120.         out     dx,al      ; select GDC mode register
  1121.         mov     al,0x02
  1122.         inc    dx
  1123.         out     dx,al      ; set write mode 2
  1124.  
  1125.         mov     al,0x02
  1126.         mov     dx,0x03c4
  1127.         out     dx,al      ; select VGA sequencer map mask register
  1128.         mov     al,0x0f
  1129.         inc    dx
  1130.         out     dx,al      ; set mask for all planes 0-3
  1131.  
  1132.         mov     al,0x08
  1133.         pop    dx
  1134.         out     dx,al      ; select GDC bit mask register
  1135.                            ; for writes to 0x03cf
  1136.  
  1137.        gmok2:
  1138.         push    ds
  1139.         pop    es
  1140.