Subversion Repositories Kolibri OS

Rev

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