Subversion Repositories Kolibri OS

Rev

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

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