Subversion Repositories Kolibri OS

Rev

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