Subversion Repositories Kolibri OS

Rev

Rev 3964 | Rev 3999 | 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: 3989 $
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
2288 clevermous 809
.loops:
810
        call    draw_vmodes_table
811
        _setcursor 25,0         ; out of screen
812
        xor     ax, ax
813
        int     0x16
814
;        call    clear_table_cursor             ;clear current position of cursor
815
 
816
        mov     si, word [cursor_pos]
817
 
3989 yogev_ezra 818
        cmp     al, 27              ; If ESC was pressed, do not change the value
819
        jz      .esc_pressed        ; Just exit the resolution selection box
820
 
2288 clevermous 821
        cmp     ah, 0x48;x,0x48E0               ; up
822
        jne     .down
823
        cmp     si, modes_table
824
        jbe     .loops
825
        sub     word [cursor_pos], size_of_step
826
        jmp     .loops
827
 
828
.down:
829
        cmp     ah, 0x50;x,0x50E0               ; down
830
        jne     .pgup
831
        cmp     word[es:si+10], -1
832
        je      .loops
833
        add     word [cursor_pos], size_of_step
834
        jmp     .loops
835
 
836
.pgup:
837
        cmp     ah, 0x49                ; page up
838
        jne     .pgdn
839
        sub     si, size_of_step*long_v_table
840
        cmp     si, modes_table
841
        jae     @f
842
        mov     si, modes_table
843
@@:
844
        mov     word [cursor_pos], si
845
        mov     si, word [home_cursor]
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 [home_cursor], si
852
        jmp     .loops
853
 
854
.pgdn:
855
        cmp     ah, 0x51                ; page down
856
        jne     .enter
857
        mov     ax, [end_cursor]
858
        add     si, size_of_step*long_v_table
859
        cmp     si, ax
860
        jb      @f
861
        mov     si, ax
862
        sub     si, size_of_step
863
@@:
864
        mov     word [cursor_pos], si
865
        mov     si, word [home_cursor]
866
        sub     ax, size_of_step*long_v_table
867
        add     si, size_of_step*long_v_table
868
        cmp     si, ax
869
        jb      @f
870
        mov     si, ax
871
@@:
872
        mov     word [home_cursor], si
873
        jmp     .loops
874
 
875
.enter:
876
        cmp     al, 0x0D;x,0x1C0D               ; enter
877
        jne     .loops
878
        push    word [cursor_pos]
879
        pop     bp
880
        push    word [es:bp]
881
        pop     word [x_save]
882
        push    word [es:bp+2]
883
        pop     word [y_save]
884
        push    word [es:bp+6]
885
        pop     word [number_vm]
886
        mov     word [preboot_graph], bp          ;save choose
887
 
888
        jmp     .d
889
 
3777 yogev_ezra 890
.change_b:                      ; b) preboot_biosdisk  = use BIOS disks through V86 emulation?
3989 yogev_ezra 891
;        _setcursor 16,0
3777 yogev_ezra 892
;        mov     si, ask_dma    // (earlier was: preboot_dma  = use DMA access?)
2288 clevermous 893
;        call    print
3796 yogev_ezra 894
;        mov     bx, '13'       ; range accepted for answer: 1-3
2288 clevermous 895
;        call    getkey
896
;        mov     [preboot_dma], al
3989 yogev_ezra 897
        _ask_question ask_bd,'12',preboot_biosdisk              ; range accepted for answer: 1-2
2288 clevermous 898
        _setcursor 11,0
899
        jmp     .d
3777 yogev_ezra 900
;.change_c:                     ; //  VRR is an obsolete functionality, used only with CRT monitors
901
;        _setcursor 16,0
2288 clevermous 902
;        mov     si, vrrmprint
903
;        call    print
3796 yogev_ezra 904
;        mov     bx, '12'       ; range accepted for answer: 1-2
2288 clevermous 905
;        call    getkey
906
;        mov     [preboot_vrrm], al
907
;        _setcursor 12,0
908
;        jmp     .d
3796 yogev_ezra 909
.change_c:                      ; c) preboot_debug = duplicates kernel debug output to the screen
3989 yogev_ezra 910
        _ask_question ask_debug,'12',preboot_debug              ; range accepted for answer: 1-2
3777 yogev_ezra 911
        _setcursor 12,0
912
        jmp     .d
3796 yogev_ezra 913
.change_d:                      ; d) preboot_launcher = start the first app (right now it's LAUNCHER) after kernel is loaded?
3989 yogev_ezra 914
        _ask_question ask_launcher,'12',preboot_launcher        ; range accepted for answer: 1-2
3777 yogev_ezra 915
        _setcursor 13,0
916
        jmp     .d
2288 clevermous 917
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
918
.say_on_off:
919
        pushf
920
        call    print
921
        mov     si, on_msg
922
        popf
923
        jz      @f
924
        mov     si, off_msg
925
@@:
926
        jmp     printplain
927
; novesa and vervesa strings are not used at the moment of executing this code
928
virtual at novesa
929
.oldtimer dd ?
930
.starttime dd ?
931
if ~ defined extended_primary_loader
932
.bSettingsChanged db ?
933
end if
934
.timer dd ?
935
end virtual
936
if ~ defined extended_primary_loader
937
.loader_block dd -1
938
end if
939
.gettime:
940
        mov     ah, 0
941
        int     1Ah
942
        xchg    ax, cx
943
        shl     eax, 10h
944
        xchg    ax, dx
945
        ret
946
.newtimer:
947
        push    ds
948
        push    cs
949
        pop     ds
950
        pushf
951
        call    [.oldtimer]
952
        pushad
953
        call    .gettime
954
        sub     eax, [.starttime]
955
if defined extended_primary_loader
956
        sub     ax, [preboot_timeout]
957
else
958
        sub     ax, 18*5
959
end if
960
        jae     .timergo
961
        neg     ax
962
        add     ax, 18-1
963
        mov     bx, 18
964
        xor     dx, dx
965
        div     bx
966
if lang eq ru
3539 clevermous 967
; подождите 5 секунд, 4/3/2 секунды, 1 секунду
2288 clevermous 968
        cmp     al, 5
969
        mov     cl, ' '
970
        jae     @f
971
        cmp     al, 1
3539 clevermous 972
        mov     cl, 0xE3 ; 'у' in cp866
2288 clevermous 973
        jz      @f
3539 clevermous 974
        mov     cl, 0xEB ; 'ы' in cp866
2288 clevermous 975
@@:
976
        mov     [time_str+9], cl
977
else if lang eq et
978
        cmp     al, 1
979
        ja      @f
3539 clevermous 980
        mov     byte [time_str+9], ' '
981
        mov     byte [time_str+10], ' '
2288 clevermous 982
@@:
3274 esevece 983
else if lang eq sp
984
; esperar 5/4/3/2 segundos, 1 segundo
985
        cmp     al, 1
986
        mov     cl, 's'
987
        ja      @f
988
        mov     cl, ' '
989
@@:
990
        mov     [time_str+10], cl
2288 clevermous 991
else
992
; wait 5/4/3/2 seconds, 1 second
993
        cmp     al, 1
994
        mov     cl, 's'
995
        ja      @f
996
        mov     cl, ' '
997
@@:
998
        mov     [time_str+9], cl
999
end if
1000
        add     al, '0'
1001
        mov     [time_str+1], al
1002
        mov     si, time_msg
1003
        _setcursor 7,0
1004
        call    print
1005
        _setcursor 25,0
1006
        popad
1007
        pop     ds
1008
        iret
1009
.timergo:
1010
        push    0
1011
        pop     es
1012
        mov     eax, [.oldtimer]
1013
        mov     [es:8*4], eax
1014
        mov     sp, 0EC00h
1015
.continue:
1016
        sti
1017
        _setcursor 6,0
1018
        mov     si, space_msg
1019
        call    printplain
1020
        call    printplain
1021
        _setcursor 6,0
1022
        mov     si, loading_msg
1023
        call    print
3777 yogev_ezra 1024
        _setcursor 16,0
2288 clevermous 1025
if ~ defined extended_primary_loader
1026
        cmp     [.bSettingsChanged], 0
1027
        jz      .load
1028
        cmp     [.loader_block], -1
1029
        jz      .load
1030
        les     bx, [.loader_block]
1031
        mov     eax, [es:bx+3]
1032
        push    ds
1033
        pop     es
1034
        test    eax, eax
1035
        jz      .load
1036
        push    eax
1037
        mov     si, save_quest
1038
        call    print
1039
.waityn:
1040
        mov     ah, 0
1041
        int     16h
1042
        or      al, 20h
1043
        cmp     al, 'n'
1044
        jz      .loadc
3430 esevece 1045
        if lang eq sp
1046
        cmp     al, 's'
1047
        else
2288 clevermous 1048
        cmp     al, 'y'
3430 esevece 1049
        end if
2288 clevermous 1050
        jnz     .waityn
1051
        call    putchar
1052
        mov     byte [space_msg+80], 186
1053
 
1054
        pop     eax
1055
        push    cs
1056
        push    .cont
1057
        push    eax
1058
        retf                          ;call back
1059
.loadc:
1060
        pop     eax
1061
.cont:
1062
        push    cs
1063
        pop     ds
1064
        mov     si, space_msg
1065
        mov     byte [si+80], 0
3777 yogev_ezra 1066
        _setcursor 16,0
2288 clevermous 1067
        call    printplain
3777 yogev_ezra 1068
        _setcursor 16,0
2288 clevermous 1069
.load:
1070
end if
1071
; \end{diamond}[02.12.2005]
1072
 
1073
; ASK GRAPHICS MODE
1074
 
1075
        call    set_vmode
1076
 
1077
; GRAPHICS ACCELERATION
1078
; force yes
2466 Serge 1079
        mov     [es:BOOT_MTRR], byte 1
2288 clevermous 1080
 
1081
; DMA ACCESS TO HD
1082
 
1083
        mov     al, [preboot_dma]
2466 Serge 1084
        mov     [es:BOOT_DMA], al
2288 clevermous 1085
 
1086
;; VRR_M USE
1087
;
1088
;        mov     al,[preboot_vrrm]
3777 yogev_ezra 1089
;        mov     [es:BOOT_VRR], al              ;// 0x9030
2288 clevermous 1090
 
3777 yogev_ezra 1091
; Set kernel DEBUG mode - if nonzero, duplicates debug output to the screen.
1092
        mov     al, [preboot_debug]
1093
        mov     [es:BOOT_DEBUG_PRINT], al       ;// 0x901E
1094
 
1095
; Start the first app (right now it's LAUNCHER) after kernel is loaded?
1096
        mov     al, [preboot_launcher]
1097
        mov     [es:BOOT_LAUNCHER_START], al    ;// 0x901D
1098
 
2288 clevermous 1099
; BOOT DEVICE
1100
 
1101
        mov     al, [preboot_device]
1102
        dec     al
1103
        mov     [boot_dev], al
1104
 
1105
; GET MEMORY MAP
1106
include '../detect/biosmem.inc'
1107
 
1108
; READ DISKETTE TO MEMORY
1109
 
1110
        cmp     [boot_dev], 0
1111
        jne     no_sys_on_floppy
1112
        mov     si, diskload
1113
        call    print
1114
        xor     ax, ax            ; reset drive
1115
        xor     dx, dx
1116
        int     0x13
1117
; do we boot from CD-ROM?
1118
        mov     ah, 41h
1119
        mov     bx, 55AAh
1120
        xor     dx, dx
1121
        int     0x13
1122
        jc      .nocd
1123
        cmp     bx, 0AA55h
1124
        jnz     .nocd
1125
        mov     ah, 48h
1126
        push    ds
1127
        push    es
1128
        pop     ds
1129
        mov     si, 0xa000
1130
        mov     word [si], 30
1131
        int     0x13
1132
        pop     ds
1133
        jc      .nocd
1134
        push    ds
1135
        lds     si, [es:si+26]
1136
        test    byte [ds:si+10], 40h
1137
        pop     ds
1138
        jz      .nocd
1139
; yes - read all floppy by 18 sectors
1140
 
1141
; TODO: !!!! read only first sector and set variables !!!!!
1142
; ...
1143
; TODO: !!! then read flippy image track by track
1144
 
1145
        mov     cx, 0x0001      ; startcyl,startsector
1146
.a1:
1147
        push    cx dx
1148
        mov     al, 18
1149
        mov     bx, 0xa000
1150
        call    boot_read_floppy
1151
        mov     si, movedesc
1152
        push    es
1153
        push    ds
1154
        pop     es
1155
        mov     cx, 256*18
1156
        mov     ah, 0x87
1157
        int     0x15
1158
        pop     es
1159
        pop     dx cx
1160
        test    ah, ah
1161
        jnz     sayerr_floppy
1162
        add     dword [si+8*3+2], 512*18
1163
        inc     dh
1164
        cmp     dh, 2
1165
        jnz     .a1
1166
        mov     dh, 0
1167
        inc     ch
1168
        cmp     ch, 80
1169
        jae     ok_sys_on_floppy
1170
        pusha
1171
        mov     al, ch
1172
        shr     ch, 2
1173
        add     al, ch
1174
        aam
1175
        xchg    al, ah
1176
        add     ax, '00'
1177
        mov     si, pros
1178
        mov     [si], ax
1179
        call    printplain
1180
        popa
1181
        jmp     .a1
1182
.nocd:
1183
; no - read only used sectors from floppy
1184
; now load floppy image to memory
1185
; at first load boot sector and first FAT table
1186
 
1187
; read only first sector and fill variables
1188
        mov     cx, 0x0001      ; first logical sector
1189
        xor     dx, dx          ; head = 0, drive = 0 (a:)
1190
        mov     al, 1           ; read one sector
1191
        mov     bx, 0xB000      ; es:bx -> data area
1192
        call    boot_read_floppy
1193
; fill the necessary parameters to work with a floppy
1194
        mov     ax, word [es:bx+24]
1195
        mov     word [BPB_SecPerTrk], ax
1196
        mov     ax, word [es:bx+26]
1197
        mov     word [BPB_NumHeads], ax
1198
        mov     ax, word [es:bx+17]
1199
        mov     word [BPB_RootEntCnt], ax
1200
        mov     ax, word [es:bx+14]
1201
        mov     word [BPB_RsvdSecCnt], ax
1202
        mov     ax, word [es:bx+19]
1203
        mov     word [BPB_TotSec16], ax
1204
        mov     al, byte [es:bx+13]
1205
        mov     byte [BPB_SecPerClus], al
1206
        mov     al, byte [es:bx+16]
1207
        mov     byte [BPB_NumFATs], al
1208
; 18.11.2008
1209
        mov     ax, word [es:bx+22]
1210
        mov     word [BPB_FATSz16], ax
1211
        mov     cx, word [es:bx+11]
1212
        mov     word [BPB_BytsPerSec], cx
1213
 
1214
; count of clusters in FAT12 ((size_of_FAT*2)/3)
1215
;        mov     ax, word [BPB_FATSz16]
1216
;        mov     cx, word [BPB_BytsPerSec]
1217
;end  18.11.2008
1218
        xor     dx, dx
1219
        mul     cx
1220
        shl     ax, 1
1221
        mov     cx, 3
1222
        div     cx              ; now ax - number of clusters in FAT12
1223
        mov     word [end_of_FAT], ax
1224
 
1225
; load first FAT table
1226
        mov     cx, 0x0002      ; startcyl,startsector          ; TODO!!!!!
1227
        xor     dx, dx          ; starthead,drive
1228
        mov     al, byte [BPB_FATSz16]     ; no of sectors to read
1229
        add     bx, word [BPB_BytsPerSec]  ; es:bx -> data area
1230
        call    boot_read_floppy
1231
        mov     bx, 0xB000
1232
 
1233
; and copy them to extended memory
1234
        mov     si, movedesc
1235
        mov     [si+8*2+3], bh          ; from
1236
 
1237
        mov     ax, word [BPB_BytsPerSec]
1238
        shr     ax, 1                   ; words per sector
1239
        mov     cx, word [BPB_RsvdSecCnt]
1240
        add     cx, word [BPB_FATSz16]
1241
        mul     cx
1242
        push    ax                      ; save to stack count of words in boot+FAT
1243
        xchg    ax, cx
1244
 
1245
        push    es
1246
        push    ds
1247
        pop     es
1248
        mov     ah, 0x87
1249
        int     0x15
1250
        pop     es
1251
        test    ah, ah
1252
        jz      @f
1253
sayerr_floppy:
1254
        mov     dx, 0x3f2
1255
        mov     al, 0
1256
        out     dx, al
1257
sayerr_memmove:
1258
        mov     si, memmovefailed
1259
        jmp     sayerr_plain
1260
@@:
1261
        pop     ax                      ; restore from stack count of words in boot+FAT
1262
        shl     ax, 1                   ; make bytes count from count of words
1263
        and     eax, 0ffffh
1264
        add     dword [si+8*3+2], eax
1265
 
1266
; copy first FAT to second copy
1267
; TODO: BPB_NumFATs !!!!!
1268
        add     bx, word [BPB_BytsPerSec]       ; !!! TODO: may be need multiply by BPB_RsvdSecCnt !!!
1269
        mov     byte [si+8*2+3], bh     ; bx - begin of FAT
1270
 
1271
        mov     ax, word [BPB_BytsPerSec]
1272
        shr     ax, 1                   ; words per sector
1273
        mov     cx, word [BPB_FATSz16]
1274
        mul     cx
1275
        mov     cx, ax                  ; cx - count of words in FAT
1276
 
1277
        push    es
1278
        push    ds
1279
        pop     es
1280
        mov     ah, 0x87
1281
        int     0x15
1282
        pop     es
1283
        test    ah, ah
1284
        jnz     sayerr_floppy
1285
 
1286
        mov     ax, cx
1287
        shl     ax, 1
1288
        and     eax, 0ffffh             ; ax - count of bytes in FAT
1289
        add     dword [si+8*3+2], eax
1290
 
1291
; reading RootDir
1292
; TODO: BPB_NumFATs
1293
        add     bx, ax
1294
        add     bx, 100h
1295
        and     bx, 0ff00h                      ; bx - place in buffer to write RootDir
1296
        push    bx
1297
 
1298
        mov     bx, word [BPB_BytsPerSec]
1299
        shr     bx, 5                           ; divide bx by 32
1300
        mov     ax, word [BPB_RootEntCnt]
1301
        xor     dx, dx
1302
        div     bx
1303
        push    ax                              ; ax - count of RootDir sectors
1304
 
1305
        mov     ax, word [BPB_FATSz16]
1306
        xor     cx, cx
1307
        mov     cl, byte [BPB_NumFATs]
1308
        mul     cx
1309
        add     ax, word [BPB_RsvdSecCnt]       ; ax - first sector of RootDir
1310
 
1311
        mov     word [FirstDataSector], ax
1312
        pop     bx
1313
        push    bx
1314
        add     word [FirstDataSector], bx      ; Begin of data region of floppy
1315
 
1316
; read RootDir
1317
        call    conv_abs_to_THS
1318
        pop     ax
1319
        pop     bx                              ; place in buffer to write
1320
        push    ax
1321
        call    boot_read_floppy                ; read RootDir into buffer
1322
; copy RootDir
1323
        mov     byte [si+8*2+3], bh             ; from buffer
1324
        pop     ax                              ; ax = count of RootDir sectors
1325
        mov     cx, word [BPB_BytsPerSec]
1326
        mul     cx
1327
        shr     ax, 1
1328
        mov     cx, ax                          ; count of words to copy
1329
        push    es
1330
        push    ds
1331
        pop     es
1332
        mov     ah, 0x87
1333
        int     0x15
1334
        pop     es
1335
 
1336
        mov     ax, cx
1337
        shl     ax, 1
1338
        and     eax, 0ffffh             ; ax - count of bytes in RootDir
1339
        add     dword [si+8*3+2], eax   ; add count of bytes copied
1340
 
1341
; Reading data clusters from floppy
1342
        mov     byte [si+8*2+3], bh
1343
        push    bx
1344
 
1345
        mov     di, 2                   ; First data cluster
1346
.read_loop:
1347
        mov     bx, di
1348
        shr     bx, 1                   ; bx+di = di*1.5
1349
        jnc     .even
1350
        test    word [es:bx+di+0xB200], 0xFFF0  ; TODO: may not be 0xB200 !!!
1351
        jmp     @f
1352
.even:
1353
        test    word [es:bx+di+0xB200], 0xFFF   ; TODO: may not be 0xB200 !!!
1354
 
1355
@@:
1356
        jz      .skip
1357
; read cluster di
1358
;.read:
1359
        ;conv cluster di to abs. sector ax
1360
        ; ax = (N-2) * BPB_SecPerClus + FirstDataSector
1361
        mov     ax, di
1362
        sub     ax, 2
1363
        xor     bx, bx
1364
        mov     bl, byte [BPB_SecPerClus]
1365
        mul     bx
1366
        add     ax, word [FirstDataSector]
1367
        call    conv_abs_to_THS
1368
        pop     bx
1369
        push    bx
1370
        mov     al, byte [BPB_SecPerClus]       ; number of sectors in cluster
1371
        call    boot_read_floppy
1372
        push    es
1373
        push    ds
1374
        pop     es
1375
        pusha
1376
;
1377
        mov     ax, word [BPB_BytsPerSec]
1378
        xor     cx, cx
1379
        mov     cl, byte [BPB_SecPerClus]
1380
        mul     cx
1381
        shr     ax, 1                           ; ax = (BPB_BytsPerSec * BPB_SecPerClus)/2
1382
        mov     cx, ax                          ; number of words to copy (count words in cluster)
1383
;
1384
        mov     ah, 0x87
1385
        int     0x15                            ; copy data
1386
        test    ah, ah
1387
        popa
1388
        pop     es
1389
        jnz     sayerr_floppy
1390
; skip cluster di
1391
.skip:
1392
        mov     ax, word [BPB_BytsPerSec]
1393
        xor     cx, cx
1394
        mov     cl, byte [BPB_SecPerClus]
1395
        mul     cx
1396
        and     eax, 0ffffh             ; ax - count of bytes in cluster
1397
        add     dword [si+8*3+2], eax
1398
 
1399
        mov     ax, word [end_of_FAT]   ; max cluster number
1400
        pusha
1401
; draw percentage
1402
; total clusters: ax
1403
; read clusters: di
1404
        xchg    ax, di
1405
        mov     cx, 100
1406
        mul     cx
1407
        div     di
1408
        aam
1409
        xchg    al, ah
1410
        add     ax, '00'
1411
        mov     si, pros
1412
        cmp     [si], ax
1413
        jz      @f
1414
        mov     [si], ax
1415
        call    printplain
1416
@@:
1417
        popa
1418
        inc     di
1419
        cmp     di, word [end_of_FAT]   ; max number of cluster
1420
        jnz     .read_loop
1421
        pop     bx                      ; clear stack
1422
 
1423
ok_sys_on_floppy:
1424
        mov     si, backspace2
1425
        call    printplain
1426
        mov     si, okt
1427
        call    printplain
1428
no_sys_on_floppy:
1429
        xor     ax, ax          ; reset drive
1430
        xor     dx, dx
1431
        int     0x13
1432
        mov     dx, 0x3f2       ; floppy motor off
1433
        mov     al, 0
1434
        out     dx, al
1435
 
1436
if defined extended_primary_loader
1437
        cmp     [boot_dev], 1
1438
        jne     no_sys_from_primary
1439
; load kolibri.img using callback from primary loader
1440
        and     word [movedesc + 24 + 2], 0
1441
        mov     byte [movedesc + 24 + 4], 10h
1442
; read in blocks of 64K until file is fully loaded
1443
        mov     ax, 1
1444
.repeat:
1445
        mov     di, image_file_struct
1446
        call    [bootcallback]
1447
        push    cs
1448
        pop     ds
1449
        push    cs
1450
        pop     es
1451
        cmp     bx, 1
1452
        ja      sayerr_badsect
1453
        push    bx
1454
        mov     si, movedesc
1455
        and     word [si + 16 + 2], 0
1456
        mov     byte [si + 16 + 4], 4
1457
        mov     ah, 87h
1458
        mov     cx, 8000h
1459
        int     15h
1460
        pop     bx
1461
        test    ah, ah
1462
        jnz     sayerr_memmove
1463
        inc     byte [si + 24 + 4]
1464
        test    bx, bx
1465
        jz      no_sys_from_primary
1466
        mov     ax, 2
1467
        jmp     .repeat
1468
no_sys_from_primary:
1469
end if
1470
 
1471
; SET GRAPHICS
1472
 
1473
        xor     ax, ax
1474
        mov     es, ax
1475
 
2466 Serge 1476
        mov     ax, [es:BOOT_VESA_MODE]         ; vga & 320x200
2288 clevermous 1477
        mov     bx, ax
1478
        cmp     ax, 0x13
1479
        je      setgr
1480
        cmp     ax, 0x12
1481
        je      setgr
1482
        mov     ax, 0x4f02              ; Vesa
1483
setgr:
1484
        int     0x10
1485
        test    ah, ah
1486
        mov     si, fatalsel
1487
        jnz     v_mode_error
1488
; set mode 0x12 graphics registers:
1489
        cmp     bx, 0x12
1490
        jne     gmok2
1491
 
1492
        mov     al, 0x05
1493
        mov     dx, 0x03ce
1494
        push    dx
1495
        out     dx, al      ; select GDC mode register
1496
        mov     al, 0x02
1497
        inc     dx
1498
        out     dx, al      ; set write mode 2
1499
 
1500
        mov     al, 0x02
1501
        mov     dx, 0x03c4
1502
        out     dx, al      ; select VGA sequencer map mask register
1503
        mov     al, 0x0f
1504
        inc     dx
1505
        out     dx, al      ; set mask for all planes 0-3
1506
 
1507
        mov     al, 0x08
1508
        pop     dx
1509
        out     dx, al      ; select GDC bit mask register
1510
                           ; for writes to 0x03cf
1511
gmok2:
1512
        push    ds
1513
        pop     es