Subversion Repositories Kolibri OS

Rev

Rev 321 | Rev 375 | 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_dma_write  = use DMA write?
  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_dma_write-preboot_graph], 1
  624.     adc    [di+preboot_dma_write-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, dma_msg-0x10000
  680.     cmp    [preboot_dma_write-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, ask_dma-0x10000
  765.     call    print
  766.     mov    bx, '12'
  767.     call    getkey
  768.     mov    [preboot_dma_write-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. ; force yes
  1022.         mov     [es:0x901C], byte 1
  1023.  
  1024. ; DMA WRITE
  1025.  
  1026.         mov     al, [preboot_dma_write-0x10000]
  1027.         mov     [es:0x901F],al
  1028.  
  1029. ; VRR_M USE
  1030.  
  1031.         mov     al,[preboot_vrrm-0x10000]
  1032.         mov     [es:0x9030],al
  1033.  
  1034.  
  1035. ; MEMORY MODEL
  1036.  
  1037. ;        movzx   eax,byte [es:preboot_memory-0x10000]
  1038. ;        cmp     eax,0
  1039. ;        jne     pre_mem
  1040. ;;;;;;;;;;;;;;;;;;;;;;;;;
  1041. ; mario79 - memory size ;
  1042. ;;;;;;;;;;;;;;;;;;;;;;;;;
  1043. ;           mov ax,0E801h
  1044. ;;;           xor bx,bx    ; thanks to Alexei for bugfix [18.07.2004]
  1045. ;           xor cx, cx
  1046. ;           xor dx, dx
  1047. ;           int 0x15
  1048. ;           movzx ebx, dx ;bx
  1049. ;           movzx eax, cx ;ax
  1050. ;           shl   ebx,6   ; яхЁхтюф т ъшыюсрщЄ√ (x64)
  1051. ;           add   eax,ebx
  1052. ;           add eax, 1000h ;440h
  1053. ;           cmp eax,40000h ; 256?
  1054. ;           jge mem_256_z
  1055. ;           cmp eax,20000h ; 128?
  1056. ;           jge mem_128_z
  1057. ;           cmp eax,10000h ; 64?
  1058. ;           jge mem_64_z
  1059. ;           cmp eax,8000h ; 32?
  1060. ;           jge mem_32_z
  1061. ;           jmp mem_16_z
  1062. ;
  1063. ;mem_256_z: mov     si,memokz256-0x10000
  1064. ;           call    printplain
  1065. ;           mov eax,5
  1066. ;           jmp pre_mem
  1067. ;mem_128_z: mov     si,memokz128-0x10000
  1068. ;           call    printplain
  1069. ;           mov eax,4
  1070. ;           jmp pre_mem
  1071. ;mem_64_z:  mov     si,memokz64-0x10000
  1072. ;           call    printplain
  1073. ;           mov eax,3
  1074. ;           jmp pre_mem
  1075. ;mem_32_z:  mov     si,memokz32-0x10000
  1076. ;           call    printplain
  1077. ;           mov eax,2
  1078. ;           jmp pre_mem
  1079. ;mem_16_z:  mov     si,memokz16-0x10000
  1080. ;           call    printplain
  1081. ;           mov eax,1
  1082. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  1083. ;      pre_mem:
  1084. ;        push    word 0x0000
  1085. ;        pop     es
  1086. ;        mov     [es:0x9030],al
  1087. ;        push    word 0x1000
  1088. ;        pop     es
  1089. ;        mov     si,linef-0x10000
  1090. ;        call    printplain
  1091.  
  1092.  
  1093.  
  1094.  
  1095. ; DIRECT WRITE TO LFB, PAGING DISABLED
  1096.  
  1097. ;        movzx   eax,byte [es:preboot_lfb-0x10000]
  1098. ;        mov     eax,1                             ; paging disabled
  1099. ;        cmp     eax,0
  1100. ;        jne     pre_lfb
  1101. ;        mov     si,gr_direct-0x10000
  1102. ;        call    printplain
  1103. ;        mov     ebx,'12'
  1104. ;        call    getkey
  1105. ;      pre_lfb:
  1106. ;        push    word 0x0000
  1107. ;        pop     es
  1108. ;        mov     [es:0x901E],al
  1109. ;        mov     ax,0x1000
  1110. ;        mov     es,ax
  1111. ;        mov     si,linef-0x10000
  1112. ;        call    printplain
  1113.         mov     [es:0x901E],byte 1
  1114.  
  1115.  
  1116.  
  1117. ; BOOT DEVICE
  1118.  
  1119.     mov    al, [preboot_device-0x10000]
  1120.         dec     al
  1121.         mov     [boot_dev-0x10000],al
  1122.  
  1123. ; READ DISKETTE TO MEMORY
  1124.  
  1125. ;        cmp     [boot_dev-0x10000],0
  1126.         jne     no_sys_on_floppy
  1127.         mov     si,diskload-0x10000
  1128.         call    print
  1129.         xor    ax, ax            ; reset drive
  1130.         xor    dx, dx
  1131.         int     0x13
  1132. ; now load floppy image to memory
  1133. ; at first load boot sector and first FAT table
  1134.         mov     cx, 0x0001      ; startcyl,startsector
  1135.         xor     dx, dx          ; starthead,drive
  1136.         mov     al, 1+9         ; no of sectors to read
  1137.         mov     bx, 0xB000      ; es:bx -> data area
  1138.         call    boot_read_floppy
  1139. ; and copy them to extended memory
  1140.         mov     si, movedesc-0x10000
  1141.         mov     [si+8*2+3], bh
  1142.         push    es
  1143.         push    ds
  1144.         pop     es
  1145.         mov     cx, 256*10
  1146.         mov     ah, 0x87
  1147.         int     0x15
  1148.         test    ah, ah
  1149.         jz      @f
  1150. sayerr_floppy:
  1151.         mov     dx, 0x3f2
  1152.         mov     al, 0
  1153.         out     dx, al
  1154.         mov     si, memmovefailed-0x10000
  1155.         jmp     sayerr_plain
  1156. @@:
  1157.         add     dword [si+8*3+2], 512*10
  1158. ; copy FAT to second copy
  1159.         mov     byte [si+8*2+3], 0xB2
  1160.         mov     cx, 256*9
  1161.         mov     ah, 0x87
  1162.         int     0x15
  1163.         pop     es
  1164.         test    ah, ah
  1165.         jnz     sayerr_floppy
  1166.         add     dword [si+8*3+2], 512*9
  1167. ; calculate total number of sectors to read
  1168.         mov     ax, 1+9+14      ; boot+FAT+root
  1169.         mov     di, 0xB203
  1170. .calc_loop:
  1171.         test    word [es:di], 0xFFF
  1172.         jz      @f
  1173.         inc     ax
  1174. @@:
  1175.         test    word [es:di+1], 0xFFF0
  1176.         jz      @f
  1177.         inc     ax
  1178. @@:
  1179.         add     di, 3
  1180.         cmp     di, 0xB200+1440*3
  1181.         jb      .calc_loop
  1182.         push    ax
  1183.         mov     bp, 1+9         ; already read sectors
  1184. ; now read rest
  1185.         mov     byte [si+8*2+3], 0xA0
  1186.         mov     di, 2-14        ; absolute sector-31
  1187.         mov     cx, 0x0002      ; cylinder=0, sector=2
  1188.         mov     dx, 0x0100      ; head=1, disk=0
  1189. .read_loop:
  1190. ; determine whether sector must be read
  1191.         cmp     di, 2
  1192.         jl      .read
  1193.         mov     bx, di
  1194.         shr     bx, 1
  1195.         jnc     .even
  1196.         test    word [es:bx+di+0xB200], 0xFFF0
  1197.         jmp     @f
  1198. .even:
  1199.         test    word [es:bx+di+0xB200], 0xFFF
  1200. @@:
  1201.         jz      .skip
  1202. .read:
  1203.         mov     bx, 0xA000
  1204.         mov     al, 1           ; 1 sector
  1205.         call    boot_read_floppy
  1206.         inc     bp
  1207.         push    es
  1208.         push    ds
  1209.         pop     es
  1210.         pusha
  1211.         mov     cx, 256
  1212.         mov     ah, 0x87
  1213.         int     0x15
  1214.         test    ah, ah
  1215.         popa
  1216.         pop     es
  1217.         jnz     sayerr_floppy
  1218. .skip:
  1219.         add     dword [si+8*3+2], 512
  1220.         inc     cx
  1221.         cmp     cl, 19
  1222.         jnz     @f
  1223.         mov     cl, 1
  1224.         inc     dh
  1225.         cmp     dh, 2
  1226.         jnz     @f
  1227.         mov     dh, 0
  1228.         inc     ch
  1229. @@:
  1230.         pop     ax
  1231.         push    ax
  1232.         pusha
  1233. ; draw percentage
  1234. ; total sectors: ax
  1235. ; read sectors: bp
  1236.         xchg    ax, bp
  1237.         mov     cx, 100
  1238.         mul     cx
  1239.         div     bp
  1240.         aam
  1241.         xchg    al, ah
  1242.         add     ax, '00'
  1243.         mov     si, pros-0x10000
  1244.         cmp     [si], ax
  1245.         jz      @f
  1246.         mov     [si], ax
  1247.         call    printplain
  1248. @@:
  1249.         popa
  1250.         inc     di
  1251.         cmp     di, 2880-31
  1252.         jnz     .read_loop
  1253.  
  1254. ;        mov     cx, 0x0001      ; startcyl,startsector
  1255. ;        xor     dx, dx          ; starthead,drive
  1256. ;        push    word 80*2               ; read no of sect
  1257. ;       reads:
  1258. ;        pusha
  1259. ;        xor     si,si
  1260. ;       newread:
  1261. ;        mov     bx,0xa000               ; es:bx -> data area
  1262. ;        mov     ax,0x0200+18            ; read, no of sectors to read
  1263. ;        int     0x13
  1264. ;        test    ah, ah
  1265. ;        jz      goodread
  1266. ;        inc    si
  1267. ;        cmp     si,10
  1268. ;        jnz     newread
  1269. ;        mov     si,badsect-0x10000
  1270. ;sayerr_plain:
  1271. ;        call    printplain
  1272. ;        jmp     $
  1273. ;       goodread:
  1274. ;        ; move -> 1mb
  1275. ;        mov     si,movedesc-0x10000
  1276. ;        push    es
  1277. ;        push    ds
  1278. ;        pop     es
  1279. ;        mov     cx,256*18
  1280. ;        mov     ah,0x87
  1281. ;        int     0x15
  1282. ;        pop    es
  1283. ;
  1284. ;        test    ah,ah                  ; was the move successfull ?
  1285. ;        je      goodmove
  1286. ;        mov     dx,0x3f2              ; floppy motor off
  1287. ;        mov     al,0
  1288. ;        out     dx,al
  1289. ;        mov     si,memmovefailed-0x10000
  1290. ;        jmp    sayerr_plain
  1291. ;      goodmove:
  1292. ;
  1293. ;    add    dword [movedesc-0x10000+0x18+2], 512*18
  1294. ;        popa
  1295. ;        inc     dh
  1296. ;        cmp     dh,2
  1297. ;        jnz     bb2
  1298. ;        mov     dh,0
  1299. ;        inc     ch
  1300. ;        pusha                        ; print prosentage
  1301. ;        mov     si,pros-0x10000
  1302. ;    shr    ch, 2
  1303. ;    mov    al, '5'
  1304. ;    test    ch, 1
  1305. ;    jnz    @f
  1306. ;    mov    al, '0'
  1307. ;@@:
  1308. ;    mov    [si+1], al
  1309. ;    shr    ch, 1
  1310. ;    add    ch, '0'
  1311. ;    mov    [si], ch
  1312. ;        call    printplain
  1313. ;        popa
  1314. ;       bb2:
  1315. ;        pop     ax
  1316. ;        dec     ax
  1317. ;        push    ax
  1318. ;        jnz     reads
  1319. ;       readdone:
  1320. ;        pop     ax
  1321.         mov     si,backspace2-0x10000
  1322.         call    printplain
  1323.         mov     si,okt-0x10000
  1324.         call    printplain
  1325.        no_sys_on_floppy:
  1326.         xor    ax, ax        ; reset drive
  1327.         xor    dx, dx
  1328.         int     0x13
  1329.        mov dx,0x3f2 ; floppy motor off
  1330.        mov al,0
  1331.        out dx,al
  1332.  
  1333.     push    es
  1334. ; PAGE TABLE
  1335.  
  1336.     push    dword [es:0x9018]
  1337. ;
  1338. ;        mmap_mem equ 64                ; amount of memory to map
  1339. ;
  1340.         push    0x6000
  1341.         pop    es                    ; es:di = 6000:0
  1342. ;        xor     di,di
  1343. ;        mov     cx,256*mmap_mem         ; Map (mapmem) M
  1344. ;; initialize as identity mapping
  1345. ;        xor    eax, eax
  1346. ;        call    pagetable_set
  1347. ;
  1348. ;
  1349. ; 4 KB PAGE DIRECTORY
  1350. ;
  1351.        push    0x7F00
  1352.        pop    es                ; es:di = 7F00:0
  1353. ;        xor     di, di
  1354. ;        mov     cx, 64 / 4
  1355. ;        mov     eax, 0x60007            ; for 0 M
  1356. ;        call    pagetable_set
  1357. ;        xor     si,si
  1358. ;        mov     di,second_base_address shr 20
  1359. ;        mov     cx,64/2
  1360. ;        rep     movs word [es:di], [es:si]
  1361.  
  1362. ;        mov     eax, 0x7F000 +8+16      ; Page directory and enable caches
  1363. ;        mov     cr3, eax
  1364.  
  1365. ; SET GRAPHICS
  1366.  
  1367.     pop    es
  1368.  
  1369.         xor ax, ax
  1370.         mov es, ax
  1371.  
  1372.         mov   ax,[es:0x9008]        ; vga & 320x200
  1373.         mov    bx, ax
  1374.         cmp     ax,0x13
  1375.         je      setgr
  1376.         cmp     ax,0x12
  1377.         je      setgr
  1378.         mov     ax,0x4f02            ; Vesa
  1379.        setgr:
  1380.         int     0x10
  1381.         test    ah,ah
  1382.         mov    si, fatalsel-0x10000
  1383.         jnz    sayerr
  1384. ; set mode 0x12 graphics registers:
  1385.         cmp     bx,0x12
  1386.         jne     gmok2
  1387.  
  1388.         mov     al,0x05
  1389.         mov     dx,0x03ce
  1390.         push    dx
  1391.         out     dx,al      ; select GDC mode register
  1392.         mov     al,0x02
  1393.         inc    dx
  1394.         out     dx,al      ; set write mode 2
  1395.  
  1396.         mov     al,0x02
  1397.         mov     dx,0x03c4
  1398.         out     dx,al      ; select VGA sequencer map mask register
  1399.         mov     al,0x0f
  1400.         inc    dx
  1401.         out     dx,al      ; set mask for all planes 0-3
  1402.  
  1403.         mov     al,0x08
  1404.         pop    dx
  1405.         out     dx,al      ; select GDC bit mask register
  1406.                            ; for writes to 0x03cf
  1407.  
  1408.        gmok2:
  1409.         push    ds
  1410.         pop    es
  1411.