Subversion Repositories Kolibri OS

Rev

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