Subversion Repositories Kolibri OS

Rev

Rev 3989 | Rev 4291 | 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: 3999 $
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
3711 clevermous 404
        xor     ax, ax
405
        and     word [es:BOOT_IDE_BASE_ADDR], ax        ;0
406
        and     word [es:BOOT_IDE_BAR0_16], ax  ;0
407
        and     word [es:BOOT_IDE_BAR1_16], ax  ;0
408
        and     word [es:BOOT_IDE_BAR2_16], ax  ;0
409
        and     word [es:BOOT_IDE_BAR3_16], ax  ;0
2288 clevermous 410
; \begin{Mario79}
411
; find HDD IDE DMA PCI device
412
; check for PCI BIOS
413
        mov     ax, 0xB101
414
        int     0x1A
415
        jc      .nopci
416
        cmp     edx, 'PCI '
417
        jnz     .nopci
418
; find PCI class code
419
; class 1 = mass storage
420
; subclass 1 = IDE controller
421
; a) class 1, subclass 1, programming interface 0x80
3712 mario79 422
; This is a Parallel IDE Controller which uses IRQs 14 and 15.
2288 clevermous 423
        mov     ax, 0xB103
424
        mov     ecx, 1*10000h + 1*100h + 0x80
3702 mario79 425
        mov     [es:BOOT_IDE_PI_16], cx
2288 clevermous 426
        xor     si, si  ; device index = 0
427
        int     0x1A
3712 mario79 428
        jnc     .found_1 ; Parallel IDE Controller
3702 mario79 429
; b) class 1, subclass 1, programming interface 0x8f
2288 clevermous 430
        mov     ax, 0xB103
3702 mario79 431
        mov     ecx, 1*10000h + 1*100h + 0x8f
432
        mov     [es:BOOT_IDE_PI_16], cx
2288 clevermous 433
        xor     si, si  ; device index = 0
434
        int     0x1A
435
        jnc     .found
436
; c) class 1, subclass 1, programming interface 0x85
437
        mov     ax, 0xB103
438
        mov     ecx, 1*10000h + 1*100h + 0x85
3702 mario79 439
        mov     [es:BOOT_IDE_PI_16], cx
440
        xor     si, si  ; device index = 0
2288 clevermous 441
        int     0x1A
3702 mario79 442
        jnc     .found
443
; d) class 1, subclass 1, programming interface 0x8A
3712 mario79 444
; This is a Parallel IDE Controller which uses IRQs 14 and 15.
3702 mario79 445
        mov     ax, 0xB103
446
        mov     ecx, 1*10000h + 1*100h + 0x8A
447
        mov     [es:BOOT_IDE_PI_16], cx
448
        xor     si, si  ; device index = 0
449
        int     0x1A
3964 mario79 450
        jnc     .found ; Parallel IDE Controller
3774 mario79 451
; Controller not found!
452
        xor     ax, ax
453
        mov     [es:BOOT_IDE_PI_16], ax
3711 clevermous 454
        jmp     .nopci
3774 mario79 455
;--------------------------------------
3702 mario79 456
.found_1:
457
; get memory base BAR4
2288 clevermous 458
        mov     ax, 0xB10A
459
        mov     di, 0x20        ; memory base is config register at 0x20
3711 clevermous 460
        push    cx
2288 clevermous 461
        int     0x1A
3711 clevermous 462
        jc      .no_BAR4        ;.nopci
3774 mario79 463
        and     cx, 0xFFFC      ; clear address decode type
2466 Serge 464
        mov     [es:BOOT_IDE_BASE_ADDR], cx
3702 mario79 465
.no_BAR4:
3711 clevermous 466
        pop     cx
3774 mario79 467
;--------------------------------------
3762 mario79 468
.found:
469
; get Interrupt Line
470
        mov     ax, 0xB10A
471
        mov     di, 0x3c        ; memory base is config register at 0x3c
472
        push    cx
473
        int     0x1A
474
        jc      .no_Interrupt        ;.nopci
3774 mario79 475
 
3762 mario79 476
        mov     [es:BOOT_IDE_INTERR_16], cx
477
.no_Interrupt:
478
        pop     cx
3774 mario79 479
;--------------------------------------
3702 mario79 480
; get memory base BAR0
481
        mov     ax, 0xB10A
3712 mario79 482
        mov     di, 0x10        ; memory base is config register at 0x10
3711 clevermous 483
        push    cx
3702 mario79 484
        int     0x1A
3711 clevermous 485
        jc      .no_BAR0        ;.nopci
3774 mario79 486
 
3702 mario79 487
        mov     [es:BOOT_IDE_BAR0_16], cx
488
.no_BAR0:
3711 clevermous 489
        pop     cx
3774 mario79 490
;--------------------------------------
3702 mario79 491
; get memory base BAR1
492
        mov     ax, 0xB10A
3712 mario79 493
        mov     di, 0x14        ; memory base is config register at 0x14
3711 clevermous 494
        push    cx
3702 mario79 495
        int     0x1A
3711 clevermous 496
        jc      .no_BAR1        ;.nopci
3774 mario79 497
 
3702 mario79 498
        mov     [es:BOOT_IDE_BAR1_16], cx
499
.no_BAR1:
3711 clevermous 500
        pop     cx
3774 mario79 501
;--------------------------------------
3702 mario79 502
; get memory base BAR2
503
        mov     ax, 0xB10A
3712 mario79 504
        mov     di, 0x18        ; memory base is config register at 0x18
3711 clevermous 505
        push    cx
3702 mario79 506
        int     0x1A
3711 clevermous 507
        jc      .no_BAR2        ;.nopci
3774 mario79 508
 
3702 mario79 509
        mov     [es:BOOT_IDE_BAR2_16], cx
510
.no_BAR2:
3711 clevermous 511
        pop     cx
3774 mario79 512
;--------------------------------------
3702 mario79 513
; get memory base BAR3
514
        mov     ax, 0xB10A
3712 mario79 515
        mov     di, 0x1C        ; memory base is config register at 0x1c
3711 clevermous 516
        push    cx
3702 mario79 517
        int     0x1A
3711 clevermous 518
        jc      .no_BAR3        ;.nopci
3774 mario79 519
 
3702 mario79 520
        mov     [es:BOOT_IDE_BAR3_16], cx
521
.no_BAR3:
3711 clevermous 522
        pop     cx
3774 mario79 523
;--------------------------------------
2288 clevermous 524
.nopci:
525
; \end{Mario79}
526
 
3539 clevermous 527
        mov     al, 0xf6        ; Сброс клавиатуры, разрешить сканирование
2288 clevermous 528
        out     0x60, al
529
        xor     cx, cx
530
wait_loop:       ; variant 2
531
; reading state of port of 8042 controller
532
        in      al, 64h
533
        and     al, 00000010b  ; ready flag
534
; wait until 8042 controller is ready
535
        loopnz  wait_loop
536
 
537
;;;/diamond today   5.02.2008
538
; set keyboard typematic rate & delay
539
        mov     al, 0xf3
540
        out     0x60, al
541
        xor     cx, cx
542
@@:
543
        in      al, 64h
544
        test    al, 2
545
        loopnz  @b
546
        mov     al, 0
547
        out     0x60, al
548
        xor     cx, cx
549
@@:
550
        in      al, 64h
551
        test    al, 2
552
        loopnz  @b
553
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
554
; --------------- APM ---------------------
2466 Serge 555
        and     word [es:BOOT_APM_VERSION], 0     ; ver = 0.0 (APM not found)
2288 clevermous 556
        mov     ax, 0x5300
557
        xor     bx, bx
558
        int     0x15
559
        jc      apm_end                 ; APM not found
560
        test    cx, 2
561
        jz      apm_end                 ; APM 32-bit protected-mode interface not supported
2466 Serge 562
        mov     [es:BOOT_APM_VERSION], ax         ; Save APM Version
563
        mov     [es:BOOT_APM_FLAGS], cx           ; Save APM flags
2288 clevermous 564
 
565
        ; Write APM ver ----
566
        and     ax, 0xf0f
567
        add     ax, '00'
568
        mov     si, msg_apm
569
        mov     [si + 5], ah
570
        mov     [si + 7], al
571
        _setcursor 0, 3
572
        call    printplain
573
        ; ------------------
574
 
575
        mov     ax, 0x5304              ; Disconnect interface
576
        xor     bx, bx
577
        int     0x15
578
        mov     ax, 0x5303              ; Connect 32 bit mode interface
579
        xor     bx, bx
580
        int     0x15
581
 
2466 Serge 582
        mov     [es:BOOT_APM_ENTRY], ebx
583
        mov     [es:BOOT_APM_CODE_32], ax
584
        mov     [es:BOOT_APM_CODE_16], cx
585
        mov     [es:BOOT_APM_DATA_16], dx
2288 clevermous 586
 
587
apm_end:
588
        _setcursor d80x25_top_num, 0
589
 
590
if ~ defined extended_primary_loader
591
;CHECK current of code
592
        cmp     [cfgmanager.loader_block], -1
593
        jz      noloaderblock
594
        les     bx, [cfgmanager.loader_block]
595
        cmp     byte [es:bx], 1
596
        mov     si, loader_block_error
597
        jnz     sayerr
598
        push    0
599
        pop     es
600
end if
601
 
602
noloaderblock:
603
; DISPLAY VESA INFORMATION
604
        call    print_vesa_info
605
        call    calc_vmodes_table
606
        call    check_first_parm   ;check and enable cursor_pos
607
 
608
; \begin{diamond}[30.11.2005]
609
cfgmanager:
610
; settings:
611
; a) preboot_graph = graphical mode
612
;    preboot_gprobe = probe this mode?
3777 yogev_ezra 613
; b) preboot_biosdisk  = use BIOS disks through V86 emulation? // (earlier was: preboot_dma  = use DMA access?)
614
; c) preboot_debug = duplicates kernel debug output to the screen // (earlier was: preboot_vrrm = use VRR?)
615
;    // VRR is an obsolete functionality, used only with CRT monitors: increase display frequency by reducing screen resolution
616
; d) preboot_launcher = start the first app (right now it's LAUNCHER) after kernel is loaded?
617
; e) preboot_device = from where to boot?
2288 clevermous 618
 
619
; determine default settings
620
if ~ defined extended_primary_loader
621
        mov     [.bSettingsChanged], 0
622
end if
623
 
624
;.preboot_gr_end:
625
        mov     di, preboot_device
626
; if image in memory is present and [preboot_device] is uninitialized,
627
; set it to use this preloaded image
628
        cmp     byte [di], 0
629
        jnz     .preboot_device_inited
630
if defined extended_primary_loader
631
        inc     byte [di]
632
        cmp     byte [bootdevice], 'f' ; floppy?
633
        jz      .preboot_device_inited
634
        inc     byte [di]
635
else
636
        cmp     [.loader_block], -1
637
        jz      @f
638
        les     bx, [.loader_block]
639
        test    byte [es:bx+1], 1
640
        jz      @f
641
        mov     byte [di], 3
642
        jmp     .preboot_device_inited
643
@@:
644
; otherwise, set [preboot_device] to 1 (default value - boot from floppy)
645
        mov     byte [di], 1
646
end if
647
.preboot_device_inited:
648
; following 4 lines set variables to 1 if its current value is 0
649
        cmp     byte [di+preboot_dma-preboot_device], 1
650
        adc     byte [di+preboot_dma-preboot_device], 0
3777 yogev_ezra 651
        cmp     byte [di+preboot_launcher-preboot_device], 1        ; Start LAUNCHER by default
652
        adc     byte [di+preboot_launcher-preboot_device], 0
3702 mario79 653
;        cmp     byte [di+preboot_biosdisk-preboot_device], 1
654
;        adc     byte [di+preboot_biosdisk-preboot_device], 0
2288 clevermous 655
;; default value for VRR is OFF
656
;        cmp     byte [di+preboot_vrrm-preboot_device], 0
657
;        jnz    @f
658
;        mov    byte [di+preboot_vrrm-preboot_device], 2
659
;@@:
660
; notify user
661
        _setcursor 5,2
662
 
663
        mov     si, linef
664
        call    printplain
665
        mov     si, start_msg
666
        call    print
667
        mov     si, time_msg
668
        call    print
669
; get start time
670
        call    .gettime
671
        mov     [.starttime], eax
672
        mov     word [.timer], .newtimer
673
        mov     word [.timer+2], cs
674
.printcfg:
675
 
676
        _setcursor 9,0
677
        mov     si, current_cfg_msg
678
        call    print
679
        mov     si, curvideo_msg
680
        call    print
681
 
682
        call    draw_current_vmode
683
 
684
        mov     si, usebd_msg
685
        cmp     [preboot_biosdisk], 1
686
        call    .say_on_off
687
;        mov     si, vrrm_msg
688
;        cmp     [preboot_vrrm], 1
689
;        call    .say_on_off
3777 yogev_ezra 690
        mov     si, debug_mode_msg
691
        cmp     [preboot_debug], 1
692
        call    .say_on_off
693
        mov     si, launcher_msg
694
        cmp     [preboot_launcher], 1
695
        call    .say_on_off
2288 clevermous 696
        mov     si, preboot_device_msg
697
        call    print
698
        mov     al, [preboot_device]
699
if defined extended_primary_loader
700
        and     eax, 3
701
else
702
        and     eax, 7
703
end if
704
        mov     si, [preboot_device_msgs+eax*2]
705
        call    printplain
706
.show_remarks:
707
; show remarks in gray color
708
        mov     di, ((21-num_remarks)*80 + 2)*2
709
        push    0xB800
710
        pop     es
711
        mov     cx, num_remarks
712
        mov     si, remarks
713
.write_remarks:
714
        lodsw
715
        push    si
716
        xchg    ax, si
717
        mov     ah, 1*16+7      ; background: blue (1), foreground: gray (7)
718
        push    di
719
.write_remark:
720
        lodsb
721
        test    al, al
722
        jz      @f
723
        stosw
724
        jmp     .write_remark
725
@@:
726
        pop     di
727
        pop     si
728
        add     di, 80*2
729
        loop    .write_remarks
730
.wait:
731
        _setcursor 25,0         ; out of screen
732
; set timer interrupt handler
733
        cli
734
        push    0
735
        pop     es
736
        push    dword [es:8*4]
737
        pop     dword [.oldtimer]
738
        push    dword [.timer]
739
        pop     dword [es:8*4]
740
;        mov     eax, [es:8*4]
741
;        mov     [.oldtimer], eax
742
;        mov     eax, [.timer]
743
;        mov     [es:8*4], eax
744
        sti
745
; wait for keypressed
746
        xor     ax, ax
747
        int     16h
748
        push    ax
749
; restore timer interrupt
750
;        push    0
751
;        pop     es
752
        mov     eax, [.oldtimer]
753
        mov     [es:8*4], eax
754
        mov     [.timer], eax
755
 
756
        _setcursor 7,0
757
        mov     si, space_msg
758
        call    printplain
759
; clear remarks and restore normal attributes
760
        push    es
761
        mov     di, ((21-num_remarks)*80 + 2)*2
762
        push    0xB800
763
        pop     es
764
        mov     cx, num_remarks
765
        mov     ax, ' ' + (1*16 + 15)*100h
766
@@:
767
        push    cx
768
        mov     cx, 76
769
        rep stosw
770
        pop     cx
771
        add     di, 4*2
772
        loop    @b
773
        pop     es
774
        pop     ax
775
; switch on key
776
        cmp     al, 13
777
        jz      .continue
778
        or      al, 20h
3777 yogev_ezra 779
        cmp     al, 'a'         ; select graphical mode
2288 clevermous 780
        jz      .change_a
3760 hidnplayr 781
        cmp     al, 'q'         ; Trick to make 'A' key on azerty keyboard work
782
        je      .change_a
3777 yogev_ezra 783
        cmp     al, 'b'         ; use BIOS disks? // (selecting YES will make BIOS disks visible as /bd)
2288 clevermous 784
        jz      .change_b
3777 yogev_ezra 785
        cmp     al, 'c'         ; load kernel in debug mode?  // (earlier was: use VRR?)
786
        jz      .change_c
787
        cmp     al, 'd'         ; start launcher after kernel is loaded?
788
        jz      .change_d
789
        cmp     al, 'e'         ; select boot origin
2288 clevermous 790
        jnz     .show_remarks
3777 yogev_ezra 791
; e) preboot_device = from where to boot?
2288 clevermous 792
if defined extended_primary_loader
3989 yogev_ezra 793
        _ask_question bdev,'12',preboot_device              ; range accepted for answer: 1-2
2288 clevermous 794
else
3989 yogev_ezra 795
        _ask_question bdev,'14',preboot_device              ; range accepted for answer: 1-4
796
end if
3777 yogev_ezra 797
        _setcursor 14,0
3989 yogev_ezra 798
 
2288 clevermous 799
.d:
800
if ~ defined extended_primary_loader
801
        mov     [.bSettingsChanged], 1
802
end if
3989 yogev_ezra 803
.esc_pressed:
2288 clevermous 804
        call    clear_vmodes_table             ;clear vmodes_table
805
        jmp     .printcfg
3989 yogev_ezra 806
 
2288 clevermous 807
.change_a:
3797 mario79 808
        call    clear_vmodes_table             ;clear vmodes_table
3999 mario79 809
 
810
        mov     si, word [cursor_pos]
811
        mov     word [cursor_pos_old], si
2288 clevermous 812
.loops:
813
        call    draw_vmodes_table
814
        _setcursor 25,0         ; out of screen
815
        xor     ax, ax
816
        int     0x16
817
;        call    clear_table_cursor             ;clear current position of cursor
818
 
819
        mov     si, word [cursor_pos]
820
 
3989 yogev_ezra 821
        cmp     al, 27              ; If ESC was pressed, do not change the value
3999 mario79 822
        jnz     @f                   ; Just exit the resolution selection box
823
 
824
        mov     si, word [cursor_pos_old]
825
        mov     word [cursor_pos], si
826
        jmp     .esc_pressed
827
@@:
2288 clevermous 828
        cmp     ah, 0x48;x,0x48E0               ; up
829
        jne     .down
830
        cmp     si, modes_table
831
        jbe     .loops
832
        sub     word [cursor_pos], size_of_step
833
        jmp     .loops
834
 
835
.down:
836
        cmp     ah, 0x50;x,0x50E0               ; down
837
        jne     .pgup
838
        cmp     word[es:si+10], -1
839
        je      .loops
840
        add     word [cursor_pos], size_of_step
841
        jmp     .loops
842
 
843
.pgup:
844
        cmp     ah, 0x49                ; page up
845
        jne     .pgdn
846
        sub     si, size_of_step*long_v_table
847
        cmp     si, modes_table
848
        jae     @f
849
        mov     si, modes_table
850
@@:
851
        mov     word [cursor_pos], si
852
        mov     si, word [home_cursor]
853
        sub     si, size_of_step*long_v_table
854
        cmp     si, modes_table
855
        jae     @f
856
        mov     si, modes_table
857
@@:
858
        mov     word [home_cursor], si
859
        jmp     .loops
860
 
861
.pgdn:
862
        cmp     ah, 0x51                ; page down
863
        jne     .enter
864
        mov     ax, [end_cursor]
865
        add     si, size_of_step*long_v_table
866
        cmp     si, ax
867
        jb      @f
868
        mov     si, ax
869
        sub     si, size_of_step
870
@@:
871
        mov     word [cursor_pos], si
872
        mov     si, word [home_cursor]
873
        sub     ax, size_of_step*long_v_table
874
        add     si, size_of_step*long_v_table
875
        cmp     si, ax
876
        jb      @f
877
        mov     si, ax
878
@@:
879
        mov     word [home_cursor], si
880
        jmp     .loops
881
 
882
.enter:
883
        cmp     al, 0x0D;x,0x1C0D               ; enter
884
        jne     .loops
885
        push    word [cursor_pos]
886
        pop     bp
887
        push    word [es:bp]
888
        pop     word [x_save]
889
        push    word [es:bp+2]
890
        pop     word [y_save]
891
        push    word [es:bp+6]
892
        pop     word [number_vm]
893
        mov     word [preboot_graph], bp          ;save choose
894
 
895
        jmp     .d
896
 
3777 yogev_ezra 897
.change_b:                      ; b) preboot_biosdisk  = use BIOS disks through V86 emulation?
3989 yogev_ezra 898
;        _setcursor 16,0
3777 yogev_ezra 899
;        mov     si, ask_dma    // (earlier was: preboot_dma  = use DMA access?)
2288 clevermous 900
;        call    print
3796 yogev_ezra 901
;        mov     bx, '13'       ; range accepted for answer: 1-3
2288 clevermous 902
;        call    getkey
903
;        mov     [preboot_dma], al
3989 yogev_ezra 904
        _ask_question ask_bd,'12',preboot_biosdisk              ; range accepted for answer: 1-2
2288 clevermous 905
        _setcursor 11,0
906
        jmp     .d
3777 yogev_ezra 907
;.change_c:                     ; //  VRR is an obsolete functionality, used only with CRT monitors
908
;        _setcursor 16,0
2288 clevermous 909
;        mov     si, vrrmprint
910
;        call    print
3796 yogev_ezra 911
;        mov     bx, '12'       ; range accepted for answer: 1-2
2288 clevermous 912
;        call    getkey
913
;        mov     [preboot_vrrm], al
914
;        _setcursor 12,0
915
;        jmp     .d
3796 yogev_ezra 916
.change_c:                      ; c) preboot_debug = duplicates kernel debug output to the screen
3989 yogev_ezra 917
        _ask_question ask_debug,'12',preboot_debug              ; range accepted for answer: 1-2
3777 yogev_ezra 918
        _setcursor 12,0
919
        jmp     .d
3796 yogev_ezra 920
.change_d:                      ; d) preboot_launcher = start the first app (right now it's LAUNCHER) after kernel is loaded?
3989 yogev_ezra 921
        _ask_question ask_launcher,'12',preboot_launcher        ; range accepted for answer: 1-2
3777 yogev_ezra 922
        _setcursor 13,0
923
        jmp     .d
2288 clevermous 924
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
925
.say_on_off:
926
        pushf
927
        call    print
928
        mov     si, on_msg
929
        popf
930
        jz      @f
931
        mov     si, off_msg
932
@@:
933
        jmp     printplain
934
; novesa and vervesa strings are not used at the moment of executing this code
935
virtual at novesa
936
.oldtimer dd ?
937
.starttime dd ?
938
if ~ defined extended_primary_loader
939
.bSettingsChanged db ?
940
end if
941
.timer dd ?
942
end virtual
943
if ~ defined extended_primary_loader
944
.loader_block dd -1
945
end if
946
.gettime:
947
        mov     ah, 0
948
        int     1Ah
949
        xchg    ax, cx
950
        shl     eax, 10h
951
        xchg    ax, dx
952
        ret
953
.newtimer:
954
        push    ds
955
        push    cs
956
        pop     ds
957
        pushf
958
        call    [.oldtimer]
959
        pushad
960
        call    .gettime
961
        sub     eax, [.starttime]
962
if defined extended_primary_loader
963
        sub     ax, [preboot_timeout]
964
else
965
        sub     ax, 18*5
966
end if
967
        jae     .timergo
968
        neg     ax
969
        add     ax, 18-1
970
        mov     bx, 18
971
        xor     dx, dx
972
        div     bx
973
if lang eq ru
3539 clevermous 974
; подождите 5 секунд, 4/3/2 секунды, 1 секунду
2288 clevermous 975
        cmp     al, 5
976
        mov     cl, ' '
977
        jae     @f
978
        cmp     al, 1
3539 clevermous 979
        mov     cl, 0xE3 ; 'у' in cp866
2288 clevermous 980
        jz      @f
3539 clevermous 981
        mov     cl, 0xEB ; 'ы' in cp866
2288 clevermous 982
@@:
983
        mov     [time_str+9], cl
984
else if lang eq et
985
        cmp     al, 1
986
        ja      @f
3539 clevermous 987
        mov     byte [time_str+9], ' '
988
        mov     byte [time_str+10], ' '
2288 clevermous 989
@@:
3274 esevece 990
else if lang eq sp
991
; esperar 5/4/3/2 segundos, 1 segundo
992
        cmp     al, 1
993
        mov     cl, 's'
994
        ja      @f
995
        mov     cl, ' '
996
@@:
997
        mov     [time_str+10], cl
2288 clevermous 998
else
999
; wait 5/4/3/2 seconds, 1 second
1000
        cmp     al, 1
1001
        mov     cl, 's'
1002
        ja      @f
1003
        mov     cl, ' '
1004
@@:
1005
        mov     [time_str+9], cl
1006
end if
1007
        add     al, '0'
1008
        mov     [time_str+1], al
1009
        mov     si, time_msg
1010
        _setcursor 7,0
1011
        call    print
1012
        _setcursor 25,0
1013
        popad
1014
        pop     ds
1015
        iret
1016
.timergo:
1017
        push    0
1018
        pop     es
1019
        mov     eax, [.oldtimer]
1020
        mov     [es:8*4], eax
1021
        mov     sp, 0EC00h
1022
.continue:
1023
        sti
1024
        _setcursor 6,0
1025
        mov     si, space_msg
1026
        call    printplain
1027
        call    printplain
1028
        _setcursor 6,0
1029
        mov     si, loading_msg
1030
        call    print
3777 yogev_ezra 1031
        _setcursor 16,0
2288 clevermous 1032
if ~ defined extended_primary_loader
1033
        cmp     [.bSettingsChanged], 0
1034
        jz      .load
1035
        cmp     [.loader_block], -1
1036
        jz      .load
1037
        les     bx, [.loader_block]
1038
        mov     eax, [es:bx+3]
1039
        push    ds
1040
        pop     es
1041
        test    eax, eax
1042
        jz      .load
1043
        push    eax
1044
        mov     si, save_quest
1045
        call    print
1046
.waityn:
1047
        mov     ah, 0
1048
        int     16h
1049
        or      al, 20h
1050
        cmp     al, 'n'
1051
        jz      .loadc
3430 esevece 1052
        if lang eq sp
1053
        cmp     al, 's'
1054
        else
2288 clevermous 1055
        cmp     al, 'y'
3430 esevece 1056
        end if
2288 clevermous 1057
        jnz     .waityn
1058
        call    putchar
1059
        mov     byte [space_msg+80], 186
1060
 
1061
        pop     eax
1062
        push    cs
1063
        push    .cont
1064
        push    eax
1065
        retf                          ;call back
1066
.loadc:
1067
        pop     eax
1068
.cont:
1069
        push    cs
1070
        pop     ds
1071
        mov     si, space_msg
1072
        mov     byte [si+80], 0
3777 yogev_ezra 1073
        _setcursor 16,0
2288 clevermous 1074
        call    printplain
3777 yogev_ezra 1075
        _setcursor 16,0
2288 clevermous 1076
.load:
1077
end if
1078
; \end{diamond}[02.12.2005]
1079
 
1080
; ASK GRAPHICS MODE
1081
 
1082
        call    set_vmode
1083
 
1084
; GRAPHICS ACCELERATION
1085
; force yes
2466 Serge 1086
        mov     [es:BOOT_MTRR], byte 1
2288 clevermous 1087
 
1088
; DMA ACCESS TO HD
1089
 
1090
        mov     al, [preboot_dma]
2466 Serge 1091
        mov     [es:BOOT_DMA], al
2288 clevermous 1092
 
1093
;; VRR_M USE
1094
;
1095
;        mov     al,[preboot_vrrm]
3777 yogev_ezra 1096
;        mov     [es:BOOT_VRR], al              ;// 0x9030
2288 clevermous 1097
 
3777 yogev_ezra 1098
; Set kernel DEBUG mode - if nonzero, duplicates debug output to the screen.
1099
        mov     al, [preboot_debug]
1100
        mov     [es:BOOT_DEBUG_PRINT], al       ;// 0x901E
1101
 
1102
; Start the first app (right now it's LAUNCHER) after kernel is loaded?
1103
        mov     al, [preboot_launcher]
1104
        mov     [es:BOOT_LAUNCHER_START], al    ;// 0x901D
1105
 
2288 clevermous 1106
; BOOT DEVICE
1107
 
1108
        mov     al, [preboot_device]
1109
        dec     al
1110
        mov     [boot_dev], al
1111
 
1112
; GET MEMORY MAP
1113
include '../detect/biosmem.inc'
1114
 
1115
; READ DISKETTE TO MEMORY
1116
 
1117
        cmp     [boot_dev], 0
1118
        jne     no_sys_on_floppy
1119
        mov     si, diskload
1120
        call    print
1121
        xor     ax, ax            ; reset drive
1122
        xor     dx, dx
1123
        int     0x13
1124
; do we boot from CD-ROM?
1125
        mov     ah, 41h
1126
        mov     bx, 55AAh
1127
        xor     dx, dx
1128
        int     0x13
1129
        jc      .nocd
1130
        cmp     bx, 0AA55h
1131
        jnz     .nocd
1132
        mov     ah, 48h
1133
        push    ds
1134
        push    es
1135
        pop     ds
1136
        mov     si, 0xa000
1137
        mov     word [si], 30
1138
        int     0x13
1139
        pop     ds
1140
        jc      .nocd
1141
        push    ds
1142
        lds     si, [es:si+26]
1143
        test    byte [ds:si+10], 40h
1144
        pop     ds
1145
        jz      .nocd
1146
; yes - read all floppy by 18 sectors
1147
 
1148
; TODO: !!!! read only first sector and set variables !!!!!
1149
; ...
1150
; TODO: !!! then read flippy image track by track
1151
 
1152
        mov     cx, 0x0001      ; startcyl,startsector
1153
.a1:
1154
        push    cx dx
1155
        mov     al, 18
1156
        mov     bx, 0xa000
1157
        call    boot_read_floppy
1158
        mov     si, movedesc
1159
        push    es
1160
        push    ds
1161
        pop     es
1162
        mov     cx, 256*18
1163
        mov     ah, 0x87
1164
        int     0x15
1165
        pop     es
1166
        pop     dx cx
1167
        test    ah, ah
1168
        jnz     sayerr_floppy
1169
        add     dword [si+8*3+2], 512*18
1170
        inc     dh
1171
        cmp     dh, 2
1172
        jnz     .a1
1173
        mov     dh, 0
1174
        inc     ch
1175
        cmp     ch, 80
1176
        jae     ok_sys_on_floppy
1177
        pusha
1178
        mov     al, ch
1179
        shr     ch, 2
1180
        add     al, ch
1181
        aam
1182
        xchg    al, ah
1183
        add     ax, '00'
1184
        mov     si, pros
1185
        mov     [si], ax
1186
        call    printplain
1187
        popa
1188
        jmp     .a1
1189
.nocd:
1190
; no - read only used sectors from floppy
1191
; now load floppy image to memory
1192
; at first load boot sector and first FAT table
1193
 
1194
; read only first sector and fill variables
1195
        mov     cx, 0x0001      ; first logical sector
1196
        xor     dx, dx          ; head = 0, drive = 0 (a:)
1197
        mov     al, 1           ; read one sector
1198
        mov     bx, 0xB000      ; es:bx -> data area
1199
        call    boot_read_floppy
1200
; fill the necessary parameters to work with a floppy
1201
        mov     ax, word [es:bx+24]
1202
        mov     word [BPB_SecPerTrk], ax
1203
        mov     ax, word [es:bx+26]
1204
        mov     word [BPB_NumHeads], ax
1205
        mov     ax, word [es:bx+17]
1206
        mov     word [BPB_RootEntCnt], ax
1207
        mov     ax, word [es:bx+14]
1208
        mov     word [BPB_RsvdSecCnt], ax
1209
        mov     ax, word [es:bx+19]
1210
        mov     word [BPB_TotSec16], ax
1211
        mov     al, byte [es:bx+13]
1212
        mov     byte [BPB_SecPerClus], al
1213
        mov     al, byte [es:bx+16]
1214
        mov     byte [BPB_NumFATs], al
1215
; 18.11.2008
1216
        mov     ax, word [es:bx+22]
1217
        mov     word [BPB_FATSz16], ax
1218
        mov     cx, word [es:bx+11]
1219
        mov     word [BPB_BytsPerSec], cx
1220
 
1221
; count of clusters in FAT12 ((size_of_FAT*2)/3)
1222
;        mov     ax, word [BPB_FATSz16]
1223
;        mov     cx, word [BPB_BytsPerSec]
1224
;end  18.11.2008
1225
        xor     dx, dx
1226
        mul     cx
1227
        shl     ax, 1
1228
        mov     cx, 3
1229
        div     cx              ; now ax - number of clusters in FAT12
1230
        mov     word [end_of_FAT], ax
1231
 
1232
; load first FAT table
1233
        mov     cx, 0x0002      ; startcyl,startsector          ; TODO!!!!!
1234
        xor     dx, dx          ; starthead,drive
1235
        mov     al, byte [BPB_FATSz16]     ; no of sectors to read
1236
        add     bx, word [BPB_BytsPerSec]  ; es:bx -> data area
1237
        call    boot_read_floppy
1238
        mov     bx, 0xB000
1239
 
1240
; and copy them to extended memory
1241
        mov     si, movedesc
1242
        mov     [si+8*2+3], bh          ; from
1243
 
1244
        mov     ax, word [BPB_BytsPerSec]
1245
        shr     ax, 1                   ; words per sector
1246
        mov     cx, word [BPB_RsvdSecCnt]
1247
        add     cx, word [BPB_FATSz16]
1248
        mul     cx
1249
        push    ax                      ; save to stack count of words in boot+FAT
1250
        xchg    ax, cx
1251
 
1252
        push    es
1253
        push    ds
1254
        pop     es
1255
        mov     ah, 0x87
1256
        int     0x15
1257
        pop     es
1258
        test    ah, ah
1259
        jz      @f
1260
sayerr_floppy:
1261
        mov     dx, 0x3f2
1262
        mov     al, 0
1263
        out     dx, al
1264
sayerr_memmove:
1265
        mov     si, memmovefailed
1266
        jmp     sayerr_plain
1267
@@:
1268
        pop     ax                      ; restore from stack count of words in boot+FAT
1269
        shl     ax, 1                   ; make bytes count from count of words
1270
        and     eax, 0ffffh
1271
        add     dword [si+8*3+2], eax
1272
 
1273
; copy first FAT to second copy
1274
; TODO: BPB_NumFATs !!!!!
1275
        add     bx, word [BPB_BytsPerSec]       ; !!! TODO: may be need multiply by BPB_RsvdSecCnt !!!
1276
        mov     byte [si+8*2+3], bh     ; bx - begin of FAT
1277
 
1278
        mov     ax, word [BPB_BytsPerSec]
1279
        shr     ax, 1                   ; words per sector
1280
        mov     cx, word [BPB_FATSz16]
1281
        mul     cx
1282
        mov     cx, ax                  ; cx - count of words in FAT
1283
 
1284
        push    es
1285
        push    ds
1286
        pop     es
1287
        mov     ah, 0x87
1288
        int     0x15
1289
        pop     es
1290
        test    ah, ah
1291
        jnz     sayerr_floppy
1292
 
1293
        mov     ax, cx
1294
        shl     ax, 1
1295
        and     eax, 0ffffh             ; ax - count of bytes in FAT
1296
        add     dword [si+8*3+2], eax
1297
 
1298
; reading RootDir
1299
; TODO: BPB_NumFATs
1300
        add     bx, ax
1301
        add     bx, 100h
1302
        and     bx, 0ff00h                      ; bx - place in buffer to write RootDir
1303
        push    bx
1304
 
1305
        mov     bx, word [BPB_BytsPerSec]
1306
        shr     bx, 5                           ; divide bx by 32
1307
        mov     ax, word [BPB_RootEntCnt]
1308
        xor     dx, dx
1309
        div     bx
1310
        push    ax                              ; ax - count of RootDir sectors
1311
 
1312
        mov     ax, word [BPB_FATSz16]
1313
        xor     cx, cx
1314
        mov     cl, byte [BPB_NumFATs]
1315
        mul     cx
1316
        add     ax, word [BPB_RsvdSecCnt]       ; ax - first sector of RootDir
1317
 
1318
        mov     word [FirstDataSector], ax
1319
        pop     bx
1320
        push    bx
1321
        add     word [FirstDataSector], bx      ; Begin of data region of floppy
1322
 
1323
; read RootDir
1324
        call    conv_abs_to_THS
1325
        pop     ax
1326
        pop     bx                              ; place in buffer to write
1327
        push    ax
1328
        call    boot_read_floppy                ; read RootDir into buffer
1329
; copy RootDir
1330
        mov     byte [si+8*2+3], bh             ; from buffer
1331
        pop     ax                              ; ax = count of RootDir sectors
1332
        mov     cx, word [BPB_BytsPerSec]
1333
        mul     cx
1334
        shr     ax, 1
1335
        mov     cx, ax                          ; count of words to copy
1336
        push    es
1337
        push    ds
1338
        pop     es
1339
        mov     ah, 0x87
1340
        int     0x15
1341
        pop     es
1342
 
1343
        mov     ax, cx
1344
        shl     ax, 1
1345
        and     eax, 0ffffh             ; ax - count of bytes in RootDir
1346
        add     dword [si+8*3+2], eax   ; add count of bytes copied
1347
 
1348
; Reading data clusters from floppy
1349
        mov     byte [si+8*2+3], bh
1350
        push    bx
1351
 
1352
        mov     di, 2                   ; First data cluster
1353
.read_loop:
1354
        mov     bx, di
1355
        shr     bx, 1                   ; bx+di = di*1.5
1356
        jnc     .even
1357
        test    word [es:bx+di+0xB200], 0xFFF0  ; TODO: may not be 0xB200 !!!
1358
        jmp     @f
1359
.even:
1360
        test    word [es:bx+di+0xB200], 0xFFF   ; TODO: may not be 0xB200 !!!
1361
 
1362
@@:
1363
        jz      .skip
1364
; read cluster di
1365
;.read:
1366
        ;conv cluster di to abs. sector ax
1367
        ; ax = (N-2) * BPB_SecPerClus + FirstDataSector
1368
        mov     ax, di
1369
        sub     ax, 2
1370
        xor     bx, bx
1371
        mov     bl, byte [BPB_SecPerClus]
1372
        mul     bx
1373
        add     ax, word [FirstDataSector]
1374
        call    conv_abs_to_THS
1375
        pop     bx
1376
        push    bx
1377
        mov     al, byte [BPB_SecPerClus]       ; number of sectors in cluster
1378
        call    boot_read_floppy
1379
        push    es
1380
        push    ds
1381
        pop     es
1382
        pusha
1383
;
1384
        mov     ax, word [BPB_BytsPerSec]
1385
        xor     cx, cx
1386
        mov     cl, byte [BPB_SecPerClus]
1387
        mul     cx
1388
        shr     ax, 1                           ; ax = (BPB_BytsPerSec * BPB_SecPerClus)/2
1389
        mov     cx, ax                          ; number of words to copy (count words in cluster)
1390
;
1391
        mov     ah, 0x87
1392
        int     0x15                            ; copy data
1393
        test    ah, ah
1394
        popa
1395
        pop     es
1396
        jnz     sayerr_floppy
1397
; skip cluster di
1398
.skip:
1399
        mov     ax, word [BPB_BytsPerSec]
1400
        xor     cx, cx
1401
        mov     cl, byte [BPB_SecPerClus]
1402
        mul     cx
1403
        and     eax, 0ffffh             ; ax - count of bytes in cluster
1404
        add     dword [si+8*3+2], eax
1405
 
1406
        mov     ax, word [end_of_FAT]   ; max cluster number
1407
        pusha
1408
; draw percentage
1409
; total clusters: ax
1410
; read clusters: di
1411
        xchg    ax, di
1412
        mov     cx, 100
1413
        mul     cx
1414
        div     di
1415
        aam
1416
        xchg    al, ah
1417
        add     ax, '00'
1418
        mov     si, pros
1419
        cmp     [si], ax
1420
        jz      @f
1421
        mov     [si], ax
1422
        call    printplain
1423
@@:
1424
        popa
1425
        inc     di
1426
        cmp     di, word [end_of_FAT]   ; max number of cluster
1427
        jnz     .read_loop
1428
        pop     bx                      ; clear stack
1429
 
1430
ok_sys_on_floppy:
1431
        mov     si, backspace2
1432
        call    printplain
1433
        mov     si, okt
1434
        call    printplain
1435
no_sys_on_floppy:
1436
        xor     ax, ax          ; reset drive
1437
        xor     dx, dx
1438
        int     0x13
1439
        mov     dx, 0x3f2       ; floppy motor off
1440
        mov     al, 0
1441
        out     dx, al
1442
 
1443
if defined extended_primary_loader
1444
        cmp     [boot_dev], 1
1445
        jne     no_sys_from_primary
1446
; load kolibri.img using callback from primary loader
1447
        and     word [movedesc + 24 + 2], 0
1448
        mov     byte [movedesc + 24 + 4], 10h
1449
; read in blocks of 64K until file is fully loaded
1450
        mov     ax, 1
1451
.repeat:
1452
        mov     di, image_file_struct
1453
        call    [bootcallback]
1454
        push    cs
1455
        pop     ds
1456
        push    cs
1457
        pop     es
1458
        cmp     bx, 1
1459
        ja      sayerr_badsect
1460
        push    bx
1461
        mov     si, movedesc
1462
        and     word [si + 16 + 2], 0
1463
        mov     byte [si + 16 + 4], 4
1464
        mov     ah, 87h
1465
        mov     cx, 8000h
1466
        int     15h
1467
        pop     bx
1468
        test    ah, ah
1469
        jnz     sayerr_memmove
1470
        inc     byte [si + 24 + 4]
1471
        test    bx, bx
1472
        jz      no_sys_from_primary
1473
        mov     ax, 2
1474
        jmp     .repeat
1475
no_sys_from_primary:
1476
end if
1477
 
1478
; SET GRAPHICS
1479
 
1480
        xor     ax, ax
1481
        mov     es, ax
1482
 
2466 Serge 1483
        mov     ax, [es:BOOT_VESA_MODE]         ; vga & 320x200
2288 clevermous 1484
        mov     bx, ax
1485
        cmp     ax, 0x13
1486
        je      setgr
1487
        cmp     ax, 0x12
1488
        je      setgr
1489
        mov     ax, 0x4f02              ; Vesa
1490
setgr:
1491
        int     0x10
1492
        test    ah, ah
1493
        mov     si, fatalsel
1494
        jnz     v_mode_error
1495
; set mode 0x12 graphics registers:
1496
        cmp     bx, 0x12
1497
        jne     gmok2
1498
 
1499
        mov     al, 0x05
1500
        mov     dx, 0x03ce
1501
        push    dx
1502
        out     dx, al      ; select GDC mode register
1503
        mov     al, 0x02
1504
        inc     dx
1505
        out     dx, al      ; set write mode 2
1506
 
1507
        mov     al, 0x02
1508
        mov     dx, 0x03c4
1509
        out     dx, al      ; select VGA sequencer map mask register
1510
        mov     al, 0x0f
1511
        inc     dx
1512
        out     dx, al      ; set mask for all planes 0-3
1513
 
1514
        mov     al, 0x08
1515
        pop     dx
1516
        out     dx, al      ; select GDC bit mask register
1517
                           ; for writes to 0x03cf
1518
gmok2:
1519
        push    ds
1520
        pop     es