Subversion Repositories Kolibri OS

Rev

Rev 9958 | Details | Compare with Previous | Last modification | View Log | RSS feed

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