Subversion Repositories Kolibri OS

Rev

Rev 3712 | Rev 3762 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2455 mario79 3
;; Copyright (C) KolibriOS team 2004-2011. All rights reserved. ;;
2288 clevermous 4
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa      ;;
5
;; Distributed under terms of the GNU General Public License    ;;
6
;;                                                              ;;
7
;;  BOOTCODE.INC                                                ;;
8
;;                                                              ;;
9
;;  KolibriOS 16-bit loader,                                    ;;
10
;;                        based on bootcode for MenuetOS        ;;
11
;;                                                              ;;
12
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13
 
14
$Revision: 3760 $
15
 
16
 
17
;==========================================================================
18
;
19
;                           16 BIT FUNCTIONS
20
;
21
;==========================================================================
22
 
23
 
24
putchar:
25
; in: al=character
26
        mov     ah, 0Eh
27
        mov     bh, 0
28
        int     10h
29
        ret
30
 
31
print:
32
; in: si->string
33
        mov     al, 186
34
        call    putchar
35
        mov     al, ' '
36
        call    putchar
37
 
38
printplain:
39
; in: si->string
40
        pusha
41
        lodsb
42
@@:
43
        call    putchar
44
        lodsb
45
        test    al, al
46
        jnz     @b
47
        popa
48
        ret
49
 
50
getkey:
51
; get number in range [bl,bh] (bl,bh in ['0'..'9'])
52
; in: bx=range
53
; out: ax=digit (1..9, 10 for 0)
54
        mov     ah, 0
55
        int     16h
56
        cmp     al, bl
57
        jb      getkey
58
        cmp     al, bh
59
        ja      getkey
60
        push    ax
61
        call    putchar
62
        pop     ax
63
        and     ax, 0Fh
64
        jnz     @f
65
        mov     al, 10
66
@@:
67
        ret
68
 
69
setcursor:
70
; in: dl=column, dh=row
71
        mov     ah, 2
72
        mov     bh, 0
73
        int     10h
74
        ret
75
 
76
macro _setcursor row,column
77
{
78
        mov     dx, row*256 + column
79
        call    setcursor
80
}
81
 
82
boot_read_floppy:
83
        push    si
84
        xor     si, si
85
        mov     ah, 2   ; read
86
@@:
87
        push    ax
88
        int     0x13
89
        pop     ax
90
        jnc     @f
91
        inc     si
92
        cmp     si, 10
93
        jb      @b
94
sayerr_badsect:
95
        mov     si, badsect
96
sayerr_plain:
97
        call    printplain
98
        jmp     $
99
@@:
100
        pop     si
101
        ret
102
 
103
; convert abs. sector number (AX) to BIOS T:H:S
104
; sector number = (abs.sector%BPB_SecPerTrk)+1
105
; pre.track number = (abs.sector/BPB_SecPerTrk)
106
; head number = pre.track number%BPB_NumHeads
107
; track number = pre.track number/BPB_NumHeads
108
; Return: cl - sector number
109
;         ch - track number
110
;         dl - drive number (0 = a:)
111
;         dh - head number
112
conv_abs_to_THS:
113
        push    bx
114
        mov     bx, word [BPB_SecPerTrk]
115
        xor     dx, dx
116
        div     bx
117
        inc     dx
118
        mov     cl, dl                          ; cl = sector number
119
        mov     bx, word [BPB_NumHeads]
120
        xor     dx, dx
121
        div     bx
122
        ; !!!!!!! ax = track number, dx = head number
123
        mov     ch, al                          ; ch=track number
124
        xchg    dh, dl                          ; dh=head number
125
        mov     dl, 0                           ; dl=0 (drive 0 (a:))
126
        pop     bx
127
        retn
128
; needed variables
129
BPB_SecPerTrk   dw      0                       ; sectors per track
130
BPB_NumHeads    dw      0                       ; number of heads
131
BPB_FATSz16     dw      0                       ; size of FAT
132
BPB_RootEntCnt  dw      0                       ; count of root dir. entries
133
BPB_BytsPerSec  dw      0                       ; bytes per sector
134
BPB_RsvdSecCnt  dw      0                       ; number of reserved sectors
135
BPB_TotSec16    dw      0                       ; count of the sectors on the volume
136
BPB_SecPerClus  db      0                       ; number of sectors per cluster
137
BPB_NumFATs     db      0                       ; number of FAT tables
138
abs_sector_adj  dw      0                       ; adjustment to make abs. sector number
139
end_of_FAT      dw      0                       ; end of FAT table
140
FirstDataSector dw      0                       ; begin of data
141
 
142
;=========================================================================
143
;
144
;                           16 BIT CODE
145
;
146
;=========================================================================
147
 
148
include 'bootvesa.inc'                 ;Include source for boot vesa
149
if defined extended_primary_loader
150
include 'parsers.inc'
151
end if
152
 
153
start_of_code:
154
 
155
if defined extended_primary_loader
156
; save data from primary loader
157
        mov     word [cs:bootcallback], si
158
        mov     word [cs:bootcallback+2], ds
159
        push    cs
160
        pop     ds
161
        mov     [bootdevice], ax
162
        mov     [bootfs], bx
163
 
164
; set up stack
165
        mov     ax, 3000h
166
        mov     ss, ax
167
        mov     sp, 0EC00h
168
 
169
; try to load configuration file
170
        mov     ax, 1
171
        mov     di, config_file_struct
172
        call    [bootcallback]
173
        cld
174
        push    cs
175
        pop     es
176
; bx=0 - ok, bx=1 - part of file loaded, assume this is ok
177
        cmp     bx, 1
178
        ja      .config_bad
179
; configuration file was loaded, parse
180
; if length is too big, use first 0FFFFh bytes
181
        test    dx, dx
182
        jz      @f
183
        mov     ax, 0FFFFh
184
@@:
185
; ds:si will be pointer to current data, dx = limit
186
        xchg    ax, dx
187
        push    4000h
188
        pop     ds
189
        xor     si, si
190
.parse_loop:
191
; skip spaces
192
        cmp     si, dx
193
        jae     .parse_done
194
        lodsb
195
        cmp     al, ' '
196
        jbe     .parse_loop
197
        dec     si
198
; loop over all possible configuration values
199
        mov     bx, config_file_variables
200
.find_variant:
201
; get length
202
        mov     cx, [es:bx]
203
; zero length = end of list
204
        jecxz   .find_newline
205
; skip over length
206
        inc     bx
207
        inc     bx
208
        mov     di, bx
209
; skip over string
210
        add     bx, cx
211
; test whether we have at least cx symbols left
212
        mov     ax, cx
213
        add     ax, si
214
        jc      .next_variant1
215
        cmp     ax, dx
216
        jae     .next_variant1
217
; save current position
218
        push    si
219
; compare strings
220
        repz cmpsb
221
        jnz     .next_variant2
222
; strings are equal; look for "=" with possible spaces before and after
223
@@:
224
        cmp     si, dx
225
        jae     .next_variant2
226
        lodsb
227
        cmp     al, ' '
228
        jbe     @b
229
        cmp     al, '='
230
        jnz     .next_variant2
231
; ok, we found the true variant
232
; ignore saved position on the stack
233
        pop     ax
234
; call the parser
235
        call    word [es:bx]
236
; line parsed, find next
237
.find_newline:
238
        cmp     si, dx
239
        jae     .parse_done
240
        lodsb
241
        cmp     al, 13
242
        jz      .parse_loop
243
        cmp     al, 10
244
        jz      .parse_loop
245
        jmp     .find_newline
246
.next_variant2:
247
; continue to the next variant, restoring current position
248
        pop     si
249
.next_variant1:
250
; continue to the next variant
251
; skip over the parser
252
        inc     bx
253
        inc     bx
254
        jmp     .find_variant
255
.parse_done:
256
.config_bad:
257
 
258
; set up segment registers
259
        push    cs
260
        pop     ds
261
else
262
        cld
263
; \begin{diamond}[02.12.2005]
264
; if bootloader sets ax = 'KL', then ds:si points to loader block
265
        cmp     ax, 'KL'
266
        jnz     @f
267
        mov     word [cs:cfgmanager.loader_block], si
268
        mov     word [cs:cfgmanager.loader_block+2], ds
269
@@:
270
; \end{diamond}[02.12.2005]
271
 
272
; if bootloader sets cx = 'HA' and dx = 'RD', then bx contains identifier of source hard disk
273
; (see comment to bx_from_load)
274
        cmp     cx, 'HA'
275
        jnz     no_hd_load
276
        cmp     dx, 'RD'
277
        jnz     no_hd_load
278
        mov     word [cs:bx_from_load], bx              ; {SPraid}[13.03.2007]
279
no_hd_load:
280
 
281
; set up stack
282
        mov     ax, 3000h
283
        mov     ss, ax
284
        mov     sp, 0EC00h
285
; set up segment registers
286
        push    cs
287
        pop     ds
288
        push    cs
289
        pop     es
290
end if
291
 
292
; set videomode
293
        mov     ax, 3
294
        int     0x10
295
 
296
if lang eq ru
297
 ; Load & set russian VGA font (RU.INC)
298
        mov     bp, RU_FNT1             ; RU_FNT1 - First part
299
        mov     bx, 1000h               ; 768 bytes
300
        mov     cx, 30h                 ; 48 symbols
301
        mov     dx, 80h                 ; 128 - position of first symbol
302
        mov     ax, 1100h
303
        int     10h
304
 
305
        mov     bp, RU_FNT2             ; RU_FNT2 -Second part
306
        mov     bx, 1000h               ; 512 bytes
307
        mov     cx, 20h                 ; 32 symbols
308
        mov     dx, 0E0h                ; 224 - position of first symbol
309
        mov     ax, 1100h
310
        int     10h
311
 ; End set VGA russian font
312
else if lang eq et
313
        mov     bp, ET_FNT              ; ET_FNT1
314
        mov     bx, 1000h               ;
315
        mov     cx, 255                 ; 256 symbols
316
        xor     dx, dx                  ; 0 - position of first symbol
317
        mov     ax, 1100h
318
        int     10h
319
end if
320
 
321
; draw frames
322
        push    0xb800
323
        pop     es
324
        xor     di, di
325
        mov     ah, 1*16+15
326
 
327
; draw top
328
        mov     si, d80x25_top
329
        mov     cx, d80x25_top_num * 80
330
@@:
331
        lodsb
332
        stosw
333
        loop    @b
334
; draw spaces
335
        mov     si, space_msg
336
        mov     dx, 25 - d80x25_top_num - d80x25_bottom_num
337
dfl1:
338
        push    si
339
        mov     cx, 80
340
@@:
341
        lodsb
342
        stosw
343
        loop    @b
344
        pop     si
345
        dec     dx
346
        jnz     dfl1
347
; draw bottom
348
        mov     si, d80x25_bottom
349
        mov     cx, d80x25_bottom_num * 80
350
@@:
351
        lodsb
352
        stosw
353
        loop    @b
354
 
355
        mov     byte [space_msg+80], 0    ; now space_msg is null terminated
356
 
357
        _setcursor d80x25_top_num,0
358
 
359
 
360
; TEST FOR 386+
361
 
362
        mov     bx, 0x4000
363
        pushf
364
        pop     ax
365
        mov     dx, ax
366
        xor     ax, bx
367
        push    ax
368
        popf
369
        pushf
370
        pop     ax
371
        and     ax, bx
372
        and     dx, bx
373
        cmp     ax, dx
374
        jnz     cpugood
375
        mov     si, not386
376
sayerr:
377
        call    print
378
        jmp     $
379
     cpugood:
380
 
381
        push    0
382
        popf
383
        sti
384
 
385
; set up esp
386
        movzx   esp, sp
387
 
388
        push    0
389
        pop     es
3711 clevermous 390
        xor     ax, ax
391
        and     word [es:BOOT_IDE_BASE_ADDR], ax        ;0
392
        and     word [es:BOOT_IDE_BAR0_16], ax  ;0
393
        and     word [es:BOOT_IDE_BAR1_16], ax  ;0
394
        and     word [es:BOOT_IDE_BAR2_16], ax  ;0
395
        and     word [es:BOOT_IDE_BAR3_16], ax  ;0
2288 clevermous 396
; \begin{Mario79}
397
; find HDD IDE DMA PCI device
398
; check for PCI BIOS
399
        mov     ax, 0xB101
400
        int     0x1A
401
        jc      .nopci
402
        cmp     edx, 'PCI '
403
        jnz     .nopci
404
; find PCI class code
405
; class 1 = mass storage
406
; subclass 1 = IDE controller
407
; a) class 1, subclass 1, programming interface 0x80
3712 mario79 408
; This is a Parallel IDE Controller which uses IRQs 14 and 15.
2288 clevermous 409
        mov     ax, 0xB103
410
        mov     ecx, 1*10000h + 1*100h + 0x80
3702 mario79 411
        mov     [es:BOOT_IDE_PI_16], cx
2288 clevermous 412
        xor     si, si  ; device index = 0
413
        int     0x1A
3712 mario79 414
        jnc     .found_1 ; Parallel IDE Controller
3702 mario79 415
; b) class 1, subclass 1, programming interface 0x8f
2288 clevermous 416
        mov     ax, 0xB103
3702 mario79 417
        mov     ecx, 1*10000h + 1*100h + 0x8f
418
        mov     [es:BOOT_IDE_PI_16], cx
2288 clevermous 419
        xor     si, si  ; device index = 0
420
        int     0x1A
421
        jnc     .found
422
; c) class 1, subclass 1, programming interface 0x85
423
        mov     ax, 0xB103
424
        mov     ecx, 1*10000h + 1*100h + 0x85
3702 mario79 425
        mov     [es:BOOT_IDE_PI_16], cx
426
        xor     si, si  ; device index = 0
2288 clevermous 427
        int     0x1A
3702 mario79 428
        jnc     .found
429
; d) class 1, subclass 1, programming interface 0x8A
3712 mario79 430
; This is a Parallel IDE Controller which uses IRQs 14 and 15.
3702 mario79 431
        mov     ax, 0xB103
432
        mov     ecx, 1*10000h + 1*100h + 0x8A
433
        mov     [es:BOOT_IDE_PI_16], cx
434
        xor     si, si  ; device index = 0
435
        int     0x1A
3712 mario79 436
        jnc     .found_1 ; Parallel IDE Controller
3702 mario79 437
 
3711 clevermous 438
        jmp     .nopci
3702 mario79 439
.found_1:
440
; get memory base BAR4
2288 clevermous 441
        mov     ax, 0xB10A
442
        mov     di, 0x20        ; memory base is config register at 0x20
3711 clevermous 443
        push    cx
2288 clevermous 444
        int     0x1A
3711 clevermous 445
        jc      .no_BAR4        ;.nopci
2288 clevermous 446
        and     cx, 0xFFF0      ; clear address decode type
2466 Serge 447
        mov     [es:BOOT_IDE_BASE_ADDR], cx
3702 mario79 448
.no_BAR4:
3711 clevermous 449
        pop     cx
450
.found:
3702 mario79 451
; get memory base BAR0
452
        mov     ax, 0xB10A
3712 mario79 453
        mov     di, 0x10        ; memory base is config register at 0x10
3711 clevermous 454
        push    cx
3702 mario79 455
        int     0x1A
3711 clevermous 456
        jc      .no_BAR0        ;.nopci
3702 mario79 457
        mov     [es:BOOT_IDE_BAR0_16], cx
458
.no_BAR0:
3711 clevermous 459
        pop     cx
3702 mario79 460
; get memory base BAR1
461
        mov     ax, 0xB10A
3712 mario79 462
        mov     di, 0x14        ; memory base is config register at 0x14
3711 clevermous 463
        push    cx
3702 mario79 464
        int     0x1A
3711 clevermous 465
        jc      .no_BAR1        ;.nopci
3702 mario79 466
        mov     [es:BOOT_IDE_BAR1_16], cx
467
.no_BAR1:
3711 clevermous 468
        pop     cx
3702 mario79 469
; get memory base BAR2
470
        mov     ax, 0xB10A
3712 mario79 471
        mov     di, 0x18        ; memory base is config register at 0x18
3711 clevermous 472
        push    cx
3702 mario79 473
        int     0x1A
3711 clevermous 474
        jc      .no_BAR2        ;.nopci
3702 mario79 475
        mov     [es:BOOT_IDE_BAR2_16], cx
476
.no_BAR2:
3711 clevermous 477
        pop     cx
3702 mario79 478
; get memory base BAR3
479
        mov     ax, 0xB10A
3712 mario79 480
        mov     di, 0x1C        ; memory base is config register at 0x1c
3711 clevermous 481
        push    cx
3702 mario79 482
        int     0x1A
3711 clevermous 483
        jc      .no_BAR3        ;.nopci
3702 mario79 484
        mov     [es:BOOT_IDE_BAR3_16], cx
485
.no_BAR3:
3711 clevermous 486
        pop     cx
2288 clevermous 487
.nopci:
488
; \end{Mario79}
489
 
3539 clevermous 490
        mov     al, 0xf6        ; Сброс клавиатуры, разрешить сканирование
2288 clevermous 491
        out     0x60, al
492
        xor     cx, cx
493
wait_loop:       ; variant 2
494
; reading state of port of 8042 controller
495
        in      al, 64h
496
        and     al, 00000010b  ; ready flag
497
; wait until 8042 controller is ready
498
        loopnz  wait_loop
499
 
500
;;;/diamond today   5.02.2008
501
; set keyboard typematic rate & delay
502
        mov     al, 0xf3
503
        out     0x60, al
504
        xor     cx, cx
505
@@:
506
        in      al, 64h
507
        test    al, 2
508
        loopnz  @b
509
        mov     al, 0
510
        out     0x60, al
511
        xor     cx, cx
512
@@:
513
        in      al, 64h
514
        test    al, 2
515
        loopnz  @b
516
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
517
; --------------- APM ---------------------
2466 Serge 518
        and     word [es:BOOT_APM_VERSION], 0     ; ver = 0.0 (APM not found)
2288 clevermous 519
        mov     ax, 0x5300
520
        xor     bx, bx
521
        int     0x15
522
        jc      apm_end                 ; APM not found
523
        test    cx, 2
524
        jz      apm_end                 ; APM 32-bit protected-mode interface not supported
2466 Serge 525
        mov     [es:BOOT_APM_VERSION], ax         ; Save APM Version
526
        mov     [es:BOOT_APM_FLAGS], cx           ; Save APM flags
2288 clevermous 527
 
528
        ; Write APM ver ----
529
        and     ax, 0xf0f
530
        add     ax, '00'
531
        mov     si, msg_apm
532
        mov     [si + 5], ah
533
        mov     [si + 7], al
534
        _setcursor 0, 3
535
        call    printplain
536
        ; ------------------
537
 
538
        mov     ax, 0x5304              ; Disconnect interface
539
        xor     bx, bx
540
        int     0x15
541
        mov     ax, 0x5303              ; Connect 32 bit mode interface
542
        xor     bx, bx
543
        int     0x15
544
 
2466 Serge 545
        mov     [es:BOOT_APM_ENTRY], ebx
546
        mov     [es:BOOT_APM_CODE_32], ax
547
        mov     [es:BOOT_APM_CODE_16], cx
548
        mov     [es:BOOT_APM_DATA_16], dx
2288 clevermous 549
 
550
apm_end:
551
        _setcursor d80x25_top_num, 0
552
 
553
if ~ defined extended_primary_loader
554
;CHECK current of code
555
        cmp     [cfgmanager.loader_block], -1
556
        jz      noloaderblock
557
        les     bx, [cfgmanager.loader_block]
558
        cmp     byte [es:bx], 1
559
        mov     si, loader_block_error
560
        jnz     sayerr
561
        push    0
562
        pop     es
563
end if
564
 
565
noloaderblock:
566
; DISPLAY VESA INFORMATION
567
        call    print_vesa_info
568
        call    calc_vmodes_table
569
        call    check_first_parm   ;check and enable cursor_pos
570
 
571
; \begin{diamond}[30.11.2005]
572
cfgmanager:
573
; settings:
574
; a) preboot_graph = graphical mode
575
;    preboot_gprobe = probe this mode?
576
; b) preboot_dma  = use DMA access?
577
; c) preboot_vrrm = use VRR?
578
; d) preboot_device = from what boot?
579
 
580
; determine default settings
581
if ~ defined extended_primary_loader
582
        mov     [.bSettingsChanged], 0
583
end if
584
 
585
;.preboot_gr_end:
586
        mov     di, preboot_device
587
; if image in memory is present and [preboot_device] is uninitialized,
588
; set it to use this preloaded image
589
        cmp     byte [di], 0
590
        jnz     .preboot_device_inited
591
if defined extended_primary_loader
592
        inc     byte [di]
593
        cmp     byte [bootdevice], 'f' ; floppy?
594
        jz      .preboot_device_inited
595
        inc     byte [di]
596
else
597
        cmp     [.loader_block], -1
598
        jz      @f
599
        les     bx, [.loader_block]
600
        test    byte [es:bx+1], 1
601
        jz      @f
602
        mov     byte [di], 3
603
        jmp     .preboot_device_inited
604
@@:
605
; otherwise, set [preboot_device] to 1 (default value - boot from floppy)
606
        mov     byte [di], 1
607
end if
608
.preboot_device_inited:
609
; following 4 lines set variables to 1 if its current value is 0
610
        cmp     byte [di+preboot_dma-preboot_device], 1
611
        adc     byte [di+preboot_dma-preboot_device], 0
3702 mario79 612
;        cmp     byte [di+preboot_biosdisk-preboot_device], 1
613
;        adc     byte [di+preboot_biosdisk-preboot_device], 0
2288 clevermous 614
;; default value for VRR is OFF
615
;        cmp     byte [di+preboot_vrrm-preboot_device], 0
616
;        jnz    @f
617
;        mov    byte [di+preboot_vrrm-preboot_device], 2
618
;@@:
619
; notify user
620
        _setcursor 5,2
621
 
622
        mov     si, linef
623
        call    printplain
624
        mov     si, start_msg
625
        call    print
626
        mov     si, time_msg
627
        call    print
628
; get start time
629
        call    .gettime
630
        mov     [.starttime], eax
631
        mov     word [.timer], .newtimer
632
        mov     word [.timer+2], cs
633
.printcfg:
634
 
635
        _setcursor 9,0
636
        mov     si, current_cfg_msg
637
        call    print
638
        mov     si, curvideo_msg
639
        call    print
640
 
641
        call    draw_current_vmode
642
 
643
        mov     si, usebd_msg
644
        cmp     [preboot_biosdisk], 1
645
        call    .say_on_off
646
;        mov     si, vrrm_msg
647
;        cmp     [preboot_vrrm], 1
648
;        call    .say_on_off
649
        mov     si, preboot_device_msg
650
        call    print
651
        mov     al, [preboot_device]
652
if defined extended_primary_loader
653
        and     eax, 3
654
else
655
        and     eax, 7
656
end if
657
        mov     si, [preboot_device_msgs+eax*2]
658
        call    printplain
659
.show_remarks:
660
; show remarks in gray color
661
        mov     di, ((21-num_remarks)*80 + 2)*2
662
        push    0xB800
663
        pop     es
664
        mov     cx, num_remarks
665
        mov     si, remarks
666
.write_remarks:
667
        lodsw
668
        push    si
669
        xchg    ax, si
670
        mov     ah, 1*16+7      ; background: blue (1), foreground: gray (7)
671
        push    di
672
.write_remark:
673
        lodsb
674
        test    al, al
675
        jz      @f
676
        stosw
677
        jmp     .write_remark
678
@@:
679
        pop     di
680
        pop     si
681
        add     di, 80*2
682
        loop    .write_remarks
683
.wait:
684
        _setcursor 25,0         ; out of screen
685
; set timer interrupt handler
686
        cli
687
        push    0
688
        pop     es
689
        push    dword [es:8*4]
690
        pop     dword [.oldtimer]
691
        push    dword [.timer]
692
        pop     dword [es:8*4]
693
;        mov     eax, [es:8*4]
694
;        mov     [.oldtimer], eax
695
;        mov     eax, [.timer]
696
;        mov     [es:8*4], eax
697
        sti
698
; wait for keypressed
699
        xor     ax, ax
700
        int     16h
701
        push    ax
702
; restore timer interrupt
703
;        push    0
704
;        pop     es
705
        mov     eax, [.oldtimer]
706
        mov     [es:8*4], eax
707
        mov     [.timer], eax
708
 
709
        _setcursor 7,0
710
        mov     si, space_msg
711
        call    printplain
712
; clear remarks and restore normal attributes
713
        push    es
714
        mov     di, ((21-num_remarks)*80 + 2)*2
715
        push    0xB800
716
        pop     es
717
        mov     cx, num_remarks
718
        mov     ax, ' ' + (1*16 + 15)*100h
719
@@:
720
        push    cx
721
        mov     cx, 76
722
        rep stosw
723
        pop     cx
724
        add     di, 4*2
725
        loop    @b
726
        pop     es
727
        pop     ax
728
; switch on key
729
        cmp     al, 13
730
        jz      .continue
731
        or      al, 20h
732
        cmp     al, 'a'
733
        jz      .change_a
3760 hidnplayr 734
        cmp     al, 'q'         ; Trick to make 'A' key on azerty keyboard work
735
        je      .change_a
2288 clevermous 736
        cmp     al, 'b'
737
        jz      .change_b
738
;        cmp     al, 'c'
739
;        jz      .change_c
740
        cmp     al, 'c'         ; 'd'
741
        jnz     .show_remarks
742
        _setcursor 15,0
743
        mov     si, bdev
744
        call    print
745
if defined extended_primary_loader
746
        mov     bx, '12'
747
else
748
        mov     bx, '14'
749
end if
750
        call    getkey
751
        mov     [preboot_device], al
752
        _setcursor 13,0
753
.d:
754
if ~ defined extended_primary_loader
755
        mov     [.bSettingsChanged], 1
756
end if
757
        call    clear_vmodes_table             ;clear vmodes_table
758
        jmp     .printcfg
759
.change_a:
760
.loops:
761
        call    draw_vmodes_table
762
        _setcursor 25,0         ; out of screen
763
        xor     ax, ax
764
        int     0x16
765
;        call    clear_table_cursor             ;clear current position of cursor
766
 
767
        mov     si, word [cursor_pos]
768
 
769
        cmp     ah, 0x48;x,0x48E0               ; up
770
        jne     .down
771
        cmp     si, modes_table
772
        jbe     .loops
773
        sub     word [cursor_pos], size_of_step
774
        jmp     .loops
775
 
776
.down:
777
        cmp     ah, 0x50;x,0x50E0               ; down
778
        jne     .pgup
779
        cmp     word[es:si+10], -1
780
        je      .loops
781
        add     word [cursor_pos], size_of_step
782
        jmp     .loops
783
 
784
.pgup:
785
        cmp     ah, 0x49                ; page up
786
        jne     .pgdn
787
        sub     si, size_of_step*long_v_table
788
        cmp     si, modes_table
789
        jae     @f
790
        mov     si, modes_table
791
@@:
792
        mov     word [cursor_pos], si
793
        mov     si, word [home_cursor]
794
        sub     si, size_of_step*long_v_table
795
        cmp     si, modes_table
796
        jae     @f
797
        mov     si, modes_table
798
@@:
799
        mov     word [home_cursor], si
800
        jmp     .loops
801
 
802
.pgdn:
803
        cmp     ah, 0x51                ; page down
804
        jne     .enter
805
        mov     ax, [end_cursor]
806
        add     si, size_of_step*long_v_table
807
        cmp     si, ax
808
        jb      @f
809
        mov     si, ax
810
        sub     si, size_of_step
811
@@:
812
        mov     word [cursor_pos], si
813
        mov     si, word [home_cursor]
814
        sub     ax, size_of_step*long_v_table
815
        add     si, size_of_step*long_v_table
816
        cmp     si, ax
817
        jb      @f
818
        mov     si, ax
819
@@:
820
        mov     word [home_cursor], si
821
        jmp     .loops
822
 
823
.enter:
824
        cmp     al, 0x0D;x,0x1C0D               ; enter
825
        jne     .loops
826
        push    word [cursor_pos]
827
        pop     bp
828
        push    word [es:bp]
829
        pop     word [x_save]
830
        push    word [es:bp+2]
831
        pop     word [y_save]
832
        push    word [es:bp+6]
833
        pop     word [number_vm]
834
        mov     word [preboot_graph], bp          ;save choose
835
 
836
        jmp     .d
837
 
838
.change_b:
839
        _setcursor 15,0
840
;        mov     si, ask_dma
841
;        call    print
842
;        mov     bx, '13'
843
;        call    getkey
844
;        mov     [preboot_dma], al
845
        mov     si, ask_bd
846
        call    print
847
        mov     bx, '12'
848
        call    getkey
849
        mov     [preboot_biosdisk], al
850
        _setcursor 11,0
851
        jmp     .d
852
;.change_c:
853
;        _setcursor 15,0
854
;        mov     si, vrrmprint
855
;        call    print
856
;        mov     bx, '12'
857
;        call    getkey
858
;        mov     [preboot_vrrm], al
859
;        _setcursor 12,0
860
;        jmp     .d
861
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
862
.say_on_off:
863
        pushf
864
        call    print
865
        mov     si, on_msg
866
        popf
867
        jz      @f
868
        mov     si, off_msg
869
@@:
870
        jmp     printplain
871
; novesa and vervesa strings are not used at the moment of executing this code
872
virtual at novesa
873
.oldtimer dd ?
874
.starttime dd ?
875
if ~ defined extended_primary_loader
876
.bSettingsChanged db ?
877
end if
878
.timer dd ?
879
end virtual
880
if ~ defined extended_primary_loader
881
.loader_block dd -1
882
end if
883
.gettime:
884
        mov     ah, 0
885
        int     1Ah
886
        xchg    ax, cx
887
        shl     eax, 10h
888
        xchg    ax, dx
889
        ret
890
.newtimer:
891
        push    ds
892
        push    cs
893
        pop     ds
894
        pushf
895
        call    [.oldtimer]
896
        pushad
897
        call    .gettime
898
        sub     eax, [.starttime]
899
if defined extended_primary_loader
900
        sub     ax, [preboot_timeout]
901
else
902
        sub     ax, 18*5
903
end if
904
        jae     .timergo
905
        neg     ax
906
        add     ax, 18-1
907
        mov     bx, 18
908
        xor     dx, dx
909
        div     bx
910
if lang eq ru
3539 clevermous 911
; подождите 5 секунд, 4/3/2 секунды, 1 секунду
2288 clevermous 912
        cmp     al, 5
913
        mov     cl, ' '
914
        jae     @f
915
        cmp     al, 1
3539 clevermous 916
        mov     cl, 0xE3 ; 'у' in cp866
2288 clevermous 917
        jz      @f
3539 clevermous 918
        mov     cl, 0xEB ; 'ы' in cp866
2288 clevermous 919
@@:
920
        mov     [time_str+9], cl
921
else if lang eq et
922
        cmp     al, 1
923
        ja      @f
3539 clevermous 924
        mov     byte [time_str+9], ' '
925
        mov     byte [time_str+10], ' '
2288 clevermous 926
@@:
3274 esevece 927
else if lang eq sp
928
; esperar 5/4/3/2 segundos, 1 segundo
929
        cmp     al, 1
930
        mov     cl, 's'
931
        ja      @f
932
        mov     cl, ' '
933
@@:
934
        mov     [time_str+10], cl
2288 clevermous 935
else
936
; wait 5/4/3/2 seconds, 1 second
937
        cmp     al, 1
938
        mov     cl, 's'
939
        ja      @f
940
        mov     cl, ' '
941
@@:
942
        mov     [time_str+9], cl
943
end if
944
        add     al, '0'
945
        mov     [time_str+1], al
946
        mov     si, time_msg
947
        _setcursor 7,0
948
        call    print
949
        _setcursor 25,0
950
        popad
951
        pop     ds
952
        iret
953
.timergo:
954
        push    0
955
        pop     es
956
        mov     eax, [.oldtimer]
957
        mov     [es:8*4], eax
958
        mov     sp, 0EC00h
959
.continue:
960
        sti
961
        _setcursor 6,0
962
        mov     si, space_msg
963
        call    printplain
964
        call    printplain
965
        _setcursor 6,0
966
        mov     si, loading_msg
967
        call    print
968
        _setcursor 15,0
969
if ~ defined extended_primary_loader
970
        cmp     [.bSettingsChanged], 0
971
        jz      .load
972
        cmp     [.loader_block], -1
973
        jz      .load
974
        les     bx, [.loader_block]
975
        mov     eax, [es:bx+3]
976
        push    ds
977
        pop     es
978
        test    eax, eax
979
        jz      .load
980
        push    eax
981
        mov     si, save_quest
982
        call    print
983
.waityn:
984
        mov     ah, 0
985
        int     16h
986
        or      al, 20h
987
        cmp     al, 'n'
988
        jz      .loadc
3430 esevece 989
        if lang eq sp
990
        cmp     al, 's'
991
        else
2288 clevermous 992
        cmp     al, 'y'
3430 esevece 993
        end if
2288 clevermous 994
        jnz     .waityn
995
        call    putchar
996
        mov     byte [space_msg+80], 186
997
 
998
        pop     eax
999
        push    cs
1000
        push    .cont
1001
        push    eax
1002
        retf                          ;call back
1003
.loadc:
1004
        pop     eax
1005
.cont:
1006
        push    cs
1007
        pop     ds
1008
        mov     si, space_msg
1009
        mov     byte [si+80], 0
1010
        _setcursor 15,0
1011
        call    printplain
1012
        _setcursor 15,0
1013
.load:
1014
end if
1015
; \end{diamond}[02.12.2005]
1016
 
1017
; ASK GRAPHICS MODE
1018
 
1019
        call    set_vmode
1020
 
1021
; GRAPHICS ACCELERATION
1022
; force yes
2466 Serge 1023
        mov     [es:BOOT_MTRR], byte 1
2288 clevermous 1024
 
1025
; DMA ACCESS TO HD
1026
 
1027
        mov     al, [preboot_dma]
2466 Serge 1028
        mov     [es:BOOT_DMA], al
2288 clevermous 1029
 
1030
;; VRR_M USE
1031
;
1032
;        mov     al,[preboot_vrrm]
1033
;        mov     [es:0x9030], al
1034
 
1035
; BOOT DEVICE
1036
 
1037
        mov     al, [preboot_device]
1038
        dec     al
1039
        mov     [boot_dev], al
1040
 
1041
; GET MEMORY MAP
1042
include '../detect/biosmem.inc'
1043
 
1044
; READ DISKETTE TO MEMORY
1045
 
1046
        cmp     [boot_dev], 0
1047
        jne     no_sys_on_floppy
1048
        mov     si, diskload
1049
        call    print
1050
        xor     ax, ax            ; reset drive
1051
        xor     dx, dx
1052
        int     0x13
1053
; do we boot from CD-ROM?
1054
        mov     ah, 41h
1055
        mov     bx, 55AAh
1056
        xor     dx, dx
1057
        int     0x13
1058
        jc      .nocd
1059
        cmp     bx, 0AA55h
1060
        jnz     .nocd
1061
        mov     ah, 48h
1062
        push    ds
1063
        push    es
1064
        pop     ds
1065
        mov     si, 0xa000
1066
        mov     word [si], 30
1067
        int     0x13
1068
        pop     ds
1069
        jc      .nocd
1070
        push    ds
1071
        lds     si, [es:si+26]
1072
        test    byte [ds:si+10], 40h
1073
        pop     ds
1074
        jz      .nocd
1075
; yes - read all floppy by 18 sectors
1076
 
1077
; TODO: !!!! read only first sector and set variables !!!!!
1078
; ...
1079
; TODO: !!! then read flippy image track by track
1080
 
1081
        mov     cx, 0x0001      ; startcyl,startsector
1082
.a1:
1083
        push    cx dx
1084
        mov     al, 18
1085
        mov     bx, 0xa000
1086
        call    boot_read_floppy
1087
        mov     si, movedesc
1088
        push    es
1089
        push    ds
1090
        pop     es
1091
        mov     cx, 256*18
1092
        mov     ah, 0x87
1093
        int     0x15
1094
        pop     es
1095
        pop     dx cx
1096
        test    ah, ah
1097
        jnz     sayerr_floppy
1098
        add     dword [si+8*3+2], 512*18
1099
        inc     dh
1100
        cmp     dh, 2
1101
        jnz     .a1
1102
        mov     dh, 0
1103
        inc     ch
1104
        cmp     ch, 80
1105
        jae     ok_sys_on_floppy
1106
        pusha
1107
        mov     al, ch
1108
        shr     ch, 2
1109
        add     al, ch
1110
        aam
1111
        xchg    al, ah
1112
        add     ax, '00'
1113
        mov     si, pros
1114
        mov     [si], ax
1115
        call    printplain
1116
        popa
1117
        jmp     .a1
1118
.nocd:
1119
; no - read only used sectors from floppy
1120
; now load floppy image to memory
1121
; at first load boot sector and first FAT table
1122
 
1123
; read only first sector and fill variables
1124
        mov     cx, 0x0001      ; first logical sector
1125
        xor     dx, dx          ; head = 0, drive = 0 (a:)
1126
        mov     al, 1           ; read one sector
1127
        mov     bx, 0xB000      ; es:bx -> data area
1128
        call    boot_read_floppy
1129
; fill the necessary parameters to work with a floppy
1130
        mov     ax, word [es:bx+24]
1131
        mov     word [BPB_SecPerTrk], ax
1132
        mov     ax, word [es:bx+26]
1133
        mov     word [BPB_NumHeads], ax
1134
        mov     ax, word [es:bx+17]
1135
        mov     word [BPB_RootEntCnt], ax
1136
        mov     ax, word [es:bx+14]
1137
        mov     word [BPB_RsvdSecCnt], ax
1138
        mov     ax, word [es:bx+19]
1139
        mov     word [BPB_TotSec16], ax
1140
        mov     al, byte [es:bx+13]
1141
        mov     byte [BPB_SecPerClus], al
1142
        mov     al, byte [es:bx+16]
1143
        mov     byte [BPB_NumFATs], al
1144
; 18.11.2008
1145
        mov     ax, word [es:bx+22]
1146
        mov     word [BPB_FATSz16], ax
1147
        mov     cx, word [es:bx+11]
1148
        mov     word [BPB_BytsPerSec], cx
1149
 
1150
; count of clusters in FAT12 ((size_of_FAT*2)/3)
1151
;        mov     ax, word [BPB_FATSz16]
1152
;        mov     cx, word [BPB_BytsPerSec]
1153
;end  18.11.2008
1154
        xor     dx, dx
1155
        mul     cx
1156
        shl     ax, 1
1157
        mov     cx, 3
1158
        div     cx              ; now ax - number of clusters in FAT12
1159
        mov     word [end_of_FAT], ax
1160
 
1161
; load first FAT table
1162
        mov     cx, 0x0002      ; startcyl,startsector          ; TODO!!!!!
1163
        xor     dx, dx          ; starthead,drive
1164
        mov     al, byte [BPB_FATSz16]     ; no of sectors to read
1165
        add     bx, word [BPB_BytsPerSec]  ; es:bx -> data area
1166
        call    boot_read_floppy
1167
        mov     bx, 0xB000
1168
 
1169
; and copy them to extended memory
1170
        mov     si, movedesc
1171
        mov     [si+8*2+3], bh          ; from
1172
 
1173
        mov     ax, word [BPB_BytsPerSec]
1174
        shr     ax, 1                   ; words per sector
1175
        mov     cx, word [BPB_RsvdSecCnt]
1176
        add     cx, word [BPB_FATSz16]
1177
        mul     cx
1178
        push    ax                      ; save to stack count of words in boot+FAT
1179
        xchg    ax, cx
1180
 
1181
        push    es
1182
        push    ds
1183
        pop     es
1184
        mov     ah, 0x87
1185
        int     0x15
1186
        pop     es
1187
        test    ah, ah
1188
        jz      @f
1189
sayerr_floppy:
1190
        mov     dx, 0x3f2
1191
        mov     al, 0
1192
        out     dx, al
1193
sayerr_memmove:
1194
        mov     si, memmovefailed
1195
        jmp     sayerr_plain
1196
@@:
1197
        pop     ax                      ; restore from stack count of words in boot+FAT
1198
        shl     ax, 1                   ; make bytes count from count of words
1199
        and     eax, 0ffffh
1200
        add     dword [si+8*3+2], eax
1201
 
1202
; copy first FAT to second copy
1203
; TODO: BPB_NumFATs !!!!!
1204
        add     bx, word [BPB_BytsPerSec]       ; !!! TODO: may be need multiply by BPB_RsvdSecCnt !!!
1205
        mov     byte [si+8*2+3], bh     ; bx - begin of FAT
1206
 
1207
        mov     ax, word [BPB_BytsPerSec]
1208
        shr     ax, 1                   ; words per sector
1209
        mov     cx, word [BPB_FATSz16]
1210
        mul     cx
1211
        mov     cx, ax                  ; cx - count of words in FAT
1212
 
1213
        push    es
1214
        push    ds
1215
        pop     es
1216
        mov     ah, 0x87
1217
        int     0x15
1218
        pop     es
1219
        test    ah, ah
1220
        jnz     sayerr_floppy
1221
 
1222
        mov     ax, cx
1223
        shl     ax, 1
1224
        and     eax, 0ffffh             ; ax - count of bytes in FAT
1225
        add     dword [si+8*3+2], eax
1226
 
1227
; reading RootDir
1228
; TODO: BPB_NumFATs
1229
        add     bx, ax
1230
        add     bx, 100h
1231
        and     bx, 0ff00h                      ; bx - place in buffer to write RootDir
1232
        push    bx
1233
 
1234
        mov     bx, word [BPB_BytsPerSec]
1235
        shr     bx, 5                           ; divide bx by 32
1236
        mov     ax, word [BPB_RootEntCnt]
1237
        xor     dx, dx
1238
        div     bx
1239
        push    ax                              ; ax - count of RootDir sectors
1240
 
1241
        mov     ax, word [BPB_FATSz16]
1242
        xor     cx, cx
1243
        mov     cl, byte [BPB_NumFATs]
1244
        mul     cx
1245
        add     ax, word [BPB_RsvdSecCnt]       ; ax - first sector of RootDir
1246
 
1247
        mov     word [FirstDataSector], ax
1248
        pop     bx
1249
        push    bx
1250
        add     word [FirstDataSector], bx      ; Begin of data region of floppy
1251
 
1252
; read RootDir
1253
        call    conv_abs_to_THS
1254
        pop     ax
1255
        pop     bx                              ; place in buffer to write
1256
        push    ax
1257
        call    boot_read_floppy                ; read RootDir into buffer
1258
; copy RootDir
1259
        mov     byte [si+8*2+3], bh             ; from buffer
1260
        pop     ax                              ; ax = count of RootDir sectors
1261
        mov     cx, word [BPB_BytsPerSec]
1262
        mul     cx
1263
        shr     ax, 1
1264
        mov     cx, ax                          ; count of words to copy
1265
        push    es
1266
        push    ds
1267
        pop     es
1268
        mov     ah, 0x87
1269
        int     0x15
1270
        pop     es
1271
 
1272
        mov     ax, cx
1273
        shl     ax, 1
1274
        and     eax, 0ffffh             ; ax - count of bytes in RootDir
1275
        add     dword [si+8*3+2], eax   ; add count of bytes copied
1276
 
1277
; Reading data clusters from floppy
1278
        mov     byte [si+8*2+3], bh
1279
        push    bx
1280
 
1281
        mov     di, 2                   ; First data cluster
1282
.read_loop:
1283
        mov     bx, di
1284
        shr     bx, 1                   ; bx+di = di*1.5
1285
        jnc     .even
1286
        test    word [es:bx+di+0xB200], 0xFFF0  ; TODO: may not be 0xB200 !!!
1287
        jmp     @f
1288
.even:
1289
        test    word [es:bx+di+0xB200], 0xFFF   ; TODO: may not be 0xB200 !!!
1290
 
1291
@@:
1292
        jz      .skip
1293
; read cluster di
1294
;.read:
1295
        ;conv cluster di to abs. sector ax
1296
        ; ax = (N-2) * BPB_SecPerClus + FirstDataSector
1297
        mov     ax, di
1298
        sub     ax, 2
1299
        xor     bx, bx
1300
        mov     bl, byte [BPB_SecPerClus]
1301
        mul     bx
1302
        add     ax, word [FirstDataSector]
1303
        call    conv_abs_to_THS
1304
        pop     bx
1305
        push    bx
1306
        mov     al, byte [BPB_SecPerClus]       ; number of sectors in cluster
1307
        call    boot_read_floppy
1308
        push    es
1309
        push    ds
1310
        pop     es
1311
        pusha
1312
;
1313
        mov     ax, word [BPB_BytsPerSec]
1314
        xor     cx, cx
1315
        mov     cl, byte [BPB_SecPerClus]
1316
        mul     cx
1317
        shr     ax, 1                           ; ax = (BPB_BytsPerSec * BPB_SecPerClus)/2
1318
        mov     cx, ax                          ; number of words to copy (count words in cluster)
1319
;
1320
        mov     ah, 0x87
1321
        int     0x15                            ; copy data
1322
        test    ah, ah
1323
        popa
1324
        pop     es
1325
        jnz     sayerr_floppy
1326
; skip cluster di
1327
.skip:
1328
        mov     ax, word [BPB_BytsPerSec]
1329
        xor     cx, cx
1330
        mov     cl, byte [BPB_SecPerClus]
1331
        mul     cx
1332
        and     eax, 0ffffh             ; ax - count of bytes in cluster
1333
        add     dword [si+8*3+2], eax
1334
 
1335
        mov     ax, word [end_of_FAT]   ; max cluster number
1336
        pusha
1337
; draw percentage
1338
; total clusters: ax
1339
; read clusters: di
1340
        xchg    ax, di
1341
        mov     cx, 100
1342
        mul     cx
1343
        div     di
1344
        aam
1345
        xchg    al, ah
1346
        add     ax, '00'
1347
        mov     si, pros
1348
        cmp     [si], ax
1349
        jz      @f
1350
        mov     [si], ax
1351
        call    printplain
1352
@@:
1353
        popa
1354
        inc     di
1355
        cmp     di, word [end_of_FAT]   ; max number of cluster
1356
        jnz     .read_loop
1357
        pop     bx                      ; clear stack
1358
 
1359
ok_sys_on_floppy:
1360
        mov     si, backspace2
1361
        call    printplain
1362
        mov     si, okt
1363
        call    printplain
1364
no_sys_on_floppy:
1365
        xor     ax, ax          ; reset drive
1366
        xor     dx, dx
1367
        int     0x13
1368
        mov     dx, 0x3f2       ; floppy motor off
1369
        mov     al, 0
1370
        out     dx, al
1371
 
1372
if defined extended_primary_loader
1373
        cmp     [boot_dev], 1
1374
        jne     no_sys_from_primary
1375
; load kolibri.img using callback from primary loader
1376
        and     word [movedesc + 24 + 2], 0
1377
        mov     byte [movedesc + 24 + 4], 10h
1378
; read in blocks of 64K until file is fully loaded
1379
        mov     ax, 1
1380
.repeat:
1381
        mov     di, image_file_struct
1382
        call    [bootcallback]
1383
        push    cs
1384
        pop     ds
1385
        push    cs
1386
        pop     es
1387
        cmp     bx, 1
1388
        ja      sayerr_badsect
1389
        push    bx
1390
        mov     si, movedesc
1391
        and     word [si + 16 + 2], 0
1392
        mov     byte [si + 16 + 4], 4
1393
        mov     ah, 87h
1394
        mov     cx, 8000h
1395
        int     15h
1396
        pop     bx
1397
        test    ah, ah
1398
        jnz     sayerr_memmove
1399
        inc     byte [si + 24 + 4]
1400
        test    bx, bx
1401
        jz      no_sys_from_primary
1402
        mov     ax, 2
1403
        jmp     .repeat
1404
no_sys_from_primary:
1405
end if
1406
 
1407
; SET GRAPHICS
1408
 
1409
        xor     ax, ax
1410
        mov     es, ax
1411
 
2466 Serge 1412
        mov     ax, [es:BOOT_VESA_MODE]         ; vga & 320x200
2288 clevermous 1413
        mov     bx, ax
1414
        cmp     ax, 0x13
1415
        je      setgr
1416
        cmp     ax, 0x12
1417
        je      setgr
1418
        mov     ax, 0x4f02              ; Vesa
1419
setgr:
1420
        int     0x10
1421
        test    ah, ah
1422
        mov     si, fatalsel
1423
        jnz     v_mode_error
1424
; set mode 0x12 graphics registers:
1425
        cmp     bx, 0x12
1426
        jne     gmok2
1427
 
1428
        mov     al, 0x05
1429
        mov     dx, 0x03ce
1430
        push    dx
1431
        out     dx, al      ; select GDC mode register
1432
        mov     al, 0x02
1433
        inc     dx
1434
        out     dx, al      ; set write mode 2
1435
 
1436
        mov     al, 0x02
1437
        mov     dx, 0x03c4
1438
        out     dx, al      ; select VGA sequencer map mask register
1439
        mov     al, 0x0f
1440
        inc     dx
1441
        out     dx, al      ; set mask for all planes 0-3
1442
 
1443
        mov     al, 0x08
1444
        pop     dx
1445
        out     dx, al      ; select GDC bit mask register
1446
                           ; for writes to 0x03cf
1447
gmok2:
1448
        push    ds
1449
        pop     es