wok annotate memtest/stuff/bootloader.S @ rev 25044

*/stuff/bootloader.S: fix VCPI case
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Jun 02 15:48:36 2022 +0000 (24 months ago)
parents 50e835d951d8
children 232ba43d30af
rev   line source
pascal@20179 1 // Image/zImage & tiny bzImage linux kernel boot sector, (C) SliTaz, GPL2.
pascal@19941 2
pascal@15188 3 SYSSEG = 0x1000
pascal@19941 4 setup_sects = 497
pascal@19941 5 syssize = 500
pascal@20179 6 cmd_line_ptr = 0x228
pascal@15188 7
pascal@15188 8 .text
pascal@15188 9 .code16
pascal@15188 10 .org 0
pascal@15188 11 .globl _start
pascal@15188 12 _start:
pascal@15188 13
pascal@19399 14 #define CODESZ 512 /* patched by installer */
pascal@15188 15
pascal@20184 16 // Default kernel format is 386 Image/zImage
pascal@20179 17 //#define BZIMAGE 0x207 /* setup version ; for bzImage < 512 Kb only */
pascal@20184 18 //#define ELKS /* 8086/286 linux port */
pascal@20179 19
pascal@15188 20 /* some extra features */
pascal@20184 21 #define EXE_SUPPORT real mode dos .exe file support +208/264
pascal@20184 22 #define CMDLINE dos kernel cmdline support +45
pascal@24942 23 #define BUGGY_CMDLINE verify cmdline length +2
pascal@20184 24 #define VCPI VCPI 4.0 support (386+) +109
pascal@20184 25 #define SHUTDOWNDOS shutdown DOS services +29
pascal@24954 26 #define CHK_DOS_INT19 do not trace bios +12/13
pascal@15188 27
pascal@20179 28 /* some contraints to reduce the code size */
pascal@20184 29 //#define FLOPPY_1440K_ONLY 1.44M floppies support only -26
pascal@20184 30 //#define FLOPPY_HAS_2_SIDES hardcoded heads count to 2 -15
pascal@20184 31 //#define NO_CMDLINE_SHRINK remove heading spaces ? -6-21
pascal@20184 32 //#define NO_CMDLINE_FILE remove @cmdline file support ? -21
pascal@24954 33 #define NO_DOTS show progression dots ? -5
pascal@20179 34 #ifndef BZIMAGE
pascal@20184 35 //#define TINY_ZIMAGE system < 64Kb ? -11
pascal@21983 36 //#define NO_MINSETUP default setup (dos only) ? -4
pascal@20179 37 //#define NO_CURSOR_DEFINITION -8
pascal@20179 38 #endif
pascal@15188 39
pascal@20184 40 #ifdef ELKS
pascal@20184 41 .arch i8086
pascal@20184 42 INITSEG = 0x0100
pascal@20184 43 SETUPSEG = 0x0120
pascal@20184 44 #define ONLY8086
pascal@20184 45 #undef BZIMAGE
pascal@20184 46 #undef VCPI
pascal@20184 47 #else
pascal@20184 48 INITSEG = 0x9000
pascal@20184 49 SETUPSEG = 0x9020
pascal@20184 50 #endif
pascal@20184 51
pascal@20184 52 .macro shlclw cnt,obj
pascal@20184 53 #ifdef ONLY8086
pascal@20184 54 movb \cnt,%cl
pascal@20184 55 shlw %cl,\obj
pascal@20184 56 #else
pascal@20184 57 shlw \cnt,\obj
pascal@20184 58 #endif
pascal@20184 59 .endm
pascal@20184 60
pascal@20184 61 .macro shrclw cnt,obj
pascal@20184 62 #ifdef ONLY8086
pascal@20184 63 movb \cnt,%cl
pascal@20184 64 shrw %cl,\obj
pascal@20184 65 #else
pascal@20184 66 shrw \cnt,\obj
pascal@20184 67 #endif
pascal@20184 68 .endm
pascal@20184 69
pascal@15188 70 #ifdef EXE_SUPPORT
pascal@19399 71 #define EXEADRS(x) (x+0xE0)
pascal@19941 72 #define FLAT20(x) (x+16*INITSEG)
pascal@19941 73
pascal@19941 74 .macro trace_int19
pascal@20184 75 #ifdef ONLY8086
pascal@20184 76 xorw %si, %si
pascal@20184 77 movw %si, %ds
pascal@24954 78 # ifdef CHK_DOS_INT19
pascal@24954 79 cmpb $0xF0, 4*0x19+3(%si)
pascal@24954 80 jne stepit
pascal@24954 81 pushw %es
pascal@24957 82 movw $skip_step19, %si
pascal@24954 83 pushw %si
pascal@24954 84 retf
pascal@24954 85 stepit:
pascal@24954 86 # endif
pascal@20184 87 pushw 4+2(%si)
pascal@20184 88 pushw 4(%si)
pascal@20184 89 movw $step19, 4(%si)
pascal@20184 90 movw $INITSEG, 4+2(%si)
pascal@20184 91 #else
pascal@19941 92 pushl $4
pascal@19941 93 popw %si
pascal@19941 94 popw %ds
pascal@24954 95 # ifdef CHK_DOS_INT19
pascal@24954 96 cmpb $0xF0, 4*0x19+3-4(%si)
pascal@24954 97 jne stepit
pascal@24954 98 pushw %es
pascal@24957 99 pushw $skip_step19
pascal@24954 100 retf
pascal@24954 101 stepit:
pascal@24954 102 # endif
pascal@19400 103 pushl (%si)
pascal@19941 104 movl $step19+(INITSEG<<16), (%si)
pascal@20184 105 #endif
pascal@19399 106 pushfw
pascal@19399 107 popw %ax
pascal@19399 108 incb %ah # set TF
pascal@19399 109 pushw %ax
pascal@19399 110 popfw
pascal@24954 111 #ifdef ONLY8086
pascal@24954 112 ljmp *4*0x19(%si)
pascal@24954 113 #else
pascal@19400 114 ljmp *4*0x19-4(%si)
pascal@24954 115 #endif
pascal@19941 116 .endm
pascal@19941 117
pascal@19941 118 stacktop = 0x9E00 # in 0x8000 .. 0xA000
pascal@19941 119 decw %bp // Magic number: MZ
pascal@19941 120 popw %dx
pascal@19941 121 jmp start // Bytes on last page of file
pascal@19941 122 .word (CODESZ+511)/512 // Pages in file INSTALLER
pascal@19941 123 .word 0 // Relocations
pascal@19941 124 .word (end_header-_start)/16 // Size of header in paragraphs
pascal@19949 125 .word 4096 // Minimum extra paragraphs needed
pascal@19941 126 .word -1 // Maximum extra paragraphs needed
pascal@19941 127 .word (CODESZ+15)/16 // Initial (relative) SS value INSTALLER
pascal@19941 128 .word stacktop // Initial SP value
pascal@19941 129 .word 0 // Checksum INSTALLER?
pascal@19941 130 .word EXEADRS(comstart) // Initial IP value
pascal@19941 131 .word 0xFFF0 // Initial (relative) CS value
pascal@19941 132 // .word 0x001C // File address of relocation table
pascal@19941 133 // .word 0,0,0 // Overlay number
pascal@20184 134 #else
pascal@20184 135 #undef VCPI
pascal@19399 136 #endif
pascal@15188 137 start:
pascal@19941 138 xorw %ax, %ax # %ax = 0
pascal@15188 139 zeroed = 12 # zeroed registers
pascal@20179 140 movw $zeroed/2, %cx # clear gdt + offset, %ds, limits
pascal@19941 141 stacktop = 0x9E00 # in 0x8000 .. 0xA000 (+zeroed+12)
pascal@20184 142 #ifdef ONLY8086
pascal@20184 143 movw $INITSEG, %bx
pascal@20184 144 #else
pascal@19941 145 pushw $INITSEG
pascal@20184 146 #endif
pascal@19941 147 end_header:
pascal@20179 148 cld # assume nothing
pascal@20179 149 #if defined(BZIMAGE) && BZIMAGE >= 0x202
pascal@20179 150 popw %es # %es contain INITSEG
pascal@20179 151 movw %es, %di
pascal@20179 152 #else
pascal@19941 153 # cmdline offset at 0x22
pascal@19941 154 movw $stacktop, %di # stacktop is an arbitrary value >=
pascal@15188 155 # length of bootsect + length of
pascal@15188 156 # setup + room for stack;
pascal@15188 157 # 12 is disk parm size.
pascal@20184 158 # ifdef ONLY8086
pascal@20184 159 pushw %bx
pascal@20184 160 # endif
pascal@20179 161 popw %es # %es contain INITSEG
pascal@20179 162 #endif
pascal@20179 163 pushw %es
pascal@20179 164 popw %ss # %es = %ss = INITSEG
pascal@15188 165 movw %di, %sp # put stack at INITSEG:stacktop-...
pascal@19941 166 #ifdef EXE_SUPPORT
pascal@20179 167 cwd # force %dx = 0 (floppy only)
pascal@19941 168 #endif
pascal@15188 169
pascal@15188 170 # Many BIOS's default disk parameter tables will not recognize
pascal@15188 171 # multi-sector reads beyond the maximum sector number specified
pascal@15188 172 # in the default diskette parameter tables - this may mean 7
pascal@15188 173 # sectors in some cases.
pascal@15188 174 #
pascal@15188 175 # Since single sector reads are slow and out of the question,
pascal@15188 176 # we must take care of this by creating new parameter tables
pascal@15188 177 # (for the first disk) in RAM. We can set the maximum sector
pascal@15188 178 # count to 36 - the most we will encounter on an ED 2.88.
pascal@15188 179 #
pascal@15188 180 # High doesn't hurt. Low does. Let's use the max: 63
pascal@15188 181
pascal@15188 182 rep # don't worry about cld
pascal@15188 183 stosw # already done above
pascal@15188 184 popw %bx # offset = 0
pascal@15188 185 popw %ds # %ds = 0
pascal@15188 186
pascal@15188 187 movb setup_sects+0x7C00, %al # read bootsector + setup (%ds = 0)
pascal@15188 188 incw %ax
pascal@15188 189
pascal@15188 190 ldsw 0x78(%bx), %si # %ds:%bx+0x78 is parameter table address
pascal@15188 191 pushw %es
pascal@15188 192 pushw %di
pascal@15188 193 movb $6, %cl # copy 12 bytes
pascal@15188 194 rep # don't worry about cld
pascal@15188 195 movsw # already done above
pascal@20222 196 movw %cx, %ds # %ds = 0
pascal@20184 197 #ifdef ONLY8086
pascal@20184 198 popw 0x78(%bx) # update parameter table address
pascal@20184 199 popw 0x78+2(%bx)
pascal@20184 200 #else
pascal@20184 201 popl 0x78(%bx) # update parameter table address
pascal@20184 202 #endif
pascal@15188 203 pushw %ss
pascal@15188 204 popw %ds # now %ds = %es = %ss = INITSEG
pascal@15188 205 movb $63, 0x4-12(%di) # patch sector count, %di = stacktop
pascal@15188 206
pascal@15188 207 xchg %ax, %di # sector count
pascal@15188 208 popw %ax # limits = 0
pascal@15188 209 incw %cx # cylinder 0, sector 1, clear Z
pascal@15188 210 call read_first_sectors # read setup
pascal@15188 211
pascal@15188 212 # This routine loads the system at address LOADSEG, making sure
pascal@15188 213 # no 64kB boundaries are crossed. We try to load it as fast as
pascal@15188 214 # possible, loading whole tracks whenever we can.
pascal@15188 215
pascal@15188 216 movw syssize, %di
pascal@17223 217 decw %di
pascal@20184 218 shrclw $9-4, %di
pascal@17223 219 incw %di
pascal@15188 220 movw $SYSSEG, %cx
pascal@20179 221 #ifdef BZIMAGE
pascal@20179 222 push %cx
pascal@20179 223 #endif
pascal@15188 224 call read_sectorsCX
pascal@15188 225
pascal@15188 226 # This procedure turns off the floppy drive motor, so
pascal@15188 227 # that we enter the kernel in a known state, and
pascal@15188 228 # don't have to worry about it later.
pascal@15188 229
pascal@15188 230 kill_motor:
pascal@15188 231 xchgw %ax, %di # reset FDC (%di < 128)
pascal@15188 232 int $0x13
pascal@15188 233
pascal@15188 234 # After that (everything loaded), we jump to the setup-routine
pascal@15188 235 # loaded directly after the bootblock:
pascal@15188 236 # Segments are as follows: %ds = %ss = INITSEG
pascal@15188 237
pascal@20179 238 #ifdef BZIMAGE
pascal@20179 239 popw %bx
pascal@20179 240 popw %si // SYSSEG:0
pascal@20179 241 movesys: // %bx = DS, %si
pascal@20179 242 movw $16, %ax
pascal@20179 243 mulw %bx
pascal@20179 244 addw %si, %ax
pascal@20179 245 adcw $0x9300, %dx // %dx:%ax src flat address
pascal@20179 246 movw $9, %cx
pascal@20179 247 zero1:
pascal@20179 248 pushw $0 // 2E..1E
pascal@20179 249 loop zero1
pascal@20179 250 //pushl $0x93100000 // 1A: dest
pascal@20179 251 pushw $0x9310
pascal@20179 252 pushw %cx
pascal@20179 253 pushw $-1 // 18
pascal@20179 254 pushw %cx // 16
pascal@20179 255 pushw %dx // src
pascal@20179 256 pushw %ax
pascal@20179 257 pushw $-1 // 10
pascal@20179 258 movb $8, %cl
pascal@20179 259 movw %cx, %bx // will move 8*64 = 512Kb
pascal@20179 260 zero2:
pascal@20179 261 pushw $0 // 0E..00
pascal@20179 262 loop zero2
pascal@20179 263 movw %sp, %si
pascal@20179 264 pushw %ss
pascal@20179 265 popw %es
pascal@20179 266 pushw %es
pascal@20179 267 popw %ds
pascal@20179 268 syslp:
pascal@20179 269 movb $0x80, %ch
pascal@20179 270 movb $0x87, %ah
pascal@20179 271 int $0x15
pascal@20179 272 incb 0x14(%si)
pascal@20179 273 incb 0x1C(%si)
pascal@20179 274 decw %bx
pascal@20179 275 jne syslp
pascal@20179 276 #endif
pascal@15188 277 jmp_setup:
pascal@20184 278 cli
pascal@15188 279 ljmp $SETUPSEG, $0
pascal@15188 280
pascal@15188 281 #ifdef EXE_SUPPORT
pascal@19399 282 #ifdef SHUTDOWNDOS
pascal@19399 283 doiret:
pascal@19399 284 iret
pascal@19399 285 step19:
pascal@19399 286 pushw %si
pascal@19399 287 pushw %ds
pascal@19399 288 movw %sp, %si
pascal@19399 289 ldsw %ss:4(%si), %si
pascal@19399 290 cmpw $0x19CD, (%si)
pascal@19399 291 popw %ds
pascal@19399 292 popw %si
pascal@19399 293 jne doiret
pascal@19399 294 xorw %si, %si
pascal@19402 295 movw %si, %ds
pascal@19401 296 pushw %cs
pascal@19401 297 popw %ss
pascal@19400 298 movw $stacktop-4-16, %sp
pascal@20184 299 #ifdef ONLY8086
pascal@20184 300 popw 4(%si)
pascal@20184 301 popw 4+2(%si)
pascal@24957 302 skip_step19:
pascal@20184 303 popw %bp
pascal@20184 304 popw %di
pascal@20184 305 popw %si
pascal@20184 306 popw %dx
pascal@20184 307 popw %cx
pascal@20184 308 popw %bx
pascal@20184 309 popw %ax
pascal@20184 310 #else
pascal@19399 311 popl 4(%si)
pascal@24957 312 skip_step19:
pascal@19399 313 popaw
pascal@20184 314 #endif
pascal@20179 315 #ifdef BZIMAGE
pascal@20179 316 jmp movesys
pascal@19399 317 #endif
pascal@20179 318 #endif
pascal@20179 319 #ifndef BZIMAGE
pascal@19941 320 movesys: // %ax = SYSSEG, %bx = DS, %si
pascal@20184 321 shrclw $4, %si
pascal@19193 322 addw %si, %bx
pascal@20184 323 #ifdef TINY_ZIMAGE
pascal@20184 324 movw $0xFFFF, %cx
pascal@20184 325 xorw %si, %si
pascal@20184 326 xorw %di, %di
pascal@20184 327 cmpw %ax, %bx
pascal@21983 328 jnc forward
pascal@20184 329 decw %si
pascal@20184 330 decw %di
pascal@20184 331 std
pascal@20184 332 forward:
pascal@20184 333 movw %ax, %es
pascal@20184 334 movw %bx, %ds
pascal@20184 335 rep
pascal@20184 336 movsb
pascal@20184 337 cld
pascal@20184 338 #else
pascal@17223 339 subw %ax, %bx
pascal@15188 340 jnc forward
pascal@24045 341 //movw $0x8FFF, %ax
pascal@20179 342 movb $0x90, %ah
pascal@15188 343 forward:
pascal@15188 344 movw %ax, %es
pascal@20179 345 movw %ax, %di
pascal@20179 346 addw %bx, %di
pascal@20179 347 movw %di, %ds
pascal@20179 348 sbbw %di, %di // %di = 0 : -1
pascal@17223 349 cmc // C = 1 : 0
pascal@20179 350 adcw %di, %ax
pascal@19193 351 xorw %si, %si
pascal@15188 352 xorw %di, %di
pascal@20179 353 movb $0x10, %cl
pascal@20179 354 cmpb %cl, %ah // move 512k
pascal@15188 355 rep
pascal@20179 356 movsb
pascal@15188 357 jns forward
pascal@20184 358 #endif
pascal@15188 359 #ifndef NO_CURSOR_DEFINITION
pascal@15188 360 movb $1, %ah
pascal@15188 361 movb $0, %bh
pascal@15188 362 movb $0x20, %ch // 0x2000
pascal@15188 363 int $0x10
pascal@15188 364 #endif
pascal@15188 365 pushw %ss
pascal@15188 366 popw %ds
pascal@15188 367 jmp jmp_setup
pascal@20179 368 #endif
pascal@19941 369 comstart:
pascal@19941 370 cld # assume nothing
pascal@20184 371 #ifdef ONLY8086
pascal@20184 372 movw $INITSEG, %ax
pascal@20184 373 pushw %ax
pascal@20184 374 #else
pascal@19941 375 pushw $INITSEG
pascal@20184 376 #endif
pascal@19941 377 popw %es
pascal@19941 378 #ifdef CMDLINE
pascal@19941 379 movw %sp, %di
pascal@19941 380 movw $0x80, %si
pascal@19941 381 lodsb
pascal@19941 382 cbw
pascal@19941 383 xchgw %ax, %cx
pascal@24942 384 #ifdef BUGGY_CMDLINE
pascal@24942 385 test %cl, %cl # C=O=0, set S & Z
pascal@24942 386 jng nocmdline # Z == 1 or O != S ?
pascal@24942 387 #else
pascal@19941 388 jcxz nocmdline
pascal@24942 389 #endif
pascal@20179 390 # if defined(BZIMAGE) && BZIMAGE >= 0x202
pascal@20179 391 movw $INITSEG/16+stacktop/256, EXEADRS(cmd_line_ptr+1)
pascal@20179 392 # else
pascal@19941 393 movw $0xA33F, 0x7F(%si)
pascal@20179 394 # endif
pascal@19941 395 # ifndef NO_CMDLINE_SHRINK
pascal@19941 396 skipspace:
pascal@19941 397 lodsb
pascal@19941 398 cmpb $0x20, %al
pascal@19941 399 je skipspace
pascal@19949 400 # ifndef NO_CMDLINE_FILE
pascal@19949 401 movw %si,%dx
pascal@19941 402 decw %si
pascal@19949 403 subb $'@',%al
pascal@19949 404 jne notafile
pascal@19949 405 movb $0x3D,%ah
pascal@19949 406 int $0x21
pascal@19949 407 jc notafile
pascal@19949 408 xchgw %ax,%bx
pascal@19949 409 //movw %si,%dx // ~320 bytes max
pascal@19949 410 movw $EXEADRS(notafile)-130,%cx
pascal@19949 411 movb $0x3F,%ah
pascal@19949 412 int $0x21
pascal@19949 413 xchgw %ax,%cx
pascal@19949 414 notafile:
pascal@19949 415 # else
pascal@19949 416 decw %si
pascal@19949 417 # endif
pascal@19941 418 # endif
pascal@19941 419 rep
pascal@19941 420 movsb
pascal@19941 421 nocmdline:
pascal@20179 422 orb EXEADRS(setup_sects), %ch
pascal@20179 423 # ifndef NO_MINSETUP
pascal@20179 424 # ifndef BZIMAGE
pascal@20179 425 jnz setupok
pascal@20179 426 mov $4, %ch
pascal@20179 427 setupok:
pascal@20179 428 # endif
pascal@20179 429 # endif
pascal@20179 430 #else
pascal@20179 431 movb EXEADRS(setup_sects), %ch
pascal@15188 432 #endif
pascal@19941 433 movb $(512-(end_header-_start))/2, %cl
pascal@19941 434 movw $0x100, %si
pascal@19941 435 movw $end_header, %di
pascal@19941 436 rep
pascal@19941 437 movsw
pascal@19941 438 movw $SYSSEG, %ax
pascal@19941 439 movw %ds, %bx
pascal@19941 440 pushw %es
pascal@19941 441 popw %ss
pascal@19941 442 #ifndef SHUTDOWNDOS
pascal@19941 443 pushw %es
pascal@19941 444 pushw $movesys
pascal@15188 445 #endif
pascal@19941 446 #ifdef VCPI
pascal@19941 447 pushaw
pascal@19941 448 smsww %ax
pascal@19941 449 andb $1, %al
pascal@19941 450 je isrm
pascal@19941 451 movw $EXEADRS(gdt_vcpi),%si
pascal@20179 452 movw $pagebuf-0x90000,%di // %es = 0x9000
pascal@20179 453 movl $pagebuf+3,%es:0x1000(%di)
pascal@19941 454 call_vcpi:
pascal@19941 455 movb $0xDE,%ah // DE01, EBX = getiface(DS:SI, ES:DI)
pascal@19941 456 int $0x67
pascal@19941 457 movl $FLAT20(sw2pm_params),%esi
pascal@19941 458 movb $0x0C,%al // DE0C switchpm(ESI)
pascal@19941 459 jmp call_vcpi
pascal@19941 460 pm_code:
pascal@25044 461 .byte 0x6A, SEL_DATA // pushw $SEL_DATA
pascal@25044 462 popw %ss
pascal@19941 463 movl %cr0,%eax
pascal@19941 464 andl $0x7FFFFFFE,%eax
pascal@19941 465 movl %eax,%cr0
pascal@19941 466 movl %eax,%cr3
pascal@19941 467 isrm:
pascal@19941 468 # ifdef SHUTDOWNDOS
pascal@19941 469 trace_int19
pascal@19941 470 # else
pascal@19941 471 popaw
pascal@19941 472 retf
pascal@19941 473 # endif
pascal@19941 474 #else
pascal@19941 475 # ifdef SHUTDOWNDOS
pascal@20184 476 # ifdef ONLY8086
pascal@20184 477 pushw %ax
pascal@20184 478 pushw %bx
pascal@20184 479 pushw %cx
pascal@20184 480 pushw %dx
pascal@20184 481 pushw %si
pascal@20184 482 pushw %di
pascal@20184 483 pushw %bp
pascal@20184 484 # else
pascal@19941 485 pushaw
pascal@20184 486 # endif
pascal@19941 487 trace_int19
pascal@19941 488 # endif
pascal@19941 489 retf
pascal@19941 490 #endif
pascal@19941 491 #endif
pascal@15188 492
pascal@15188 493 # read_sectors reads %di sectors into %es:0 buffer.
pascal@15188 494 # %es:0 is updated to the next memory location.
pascal@15188 495 # First, sectors are read sector by sector until
pascal@15188 496 # sector per track count is known. Then they are
pascal@15188 497 # read track by track.
pascal@15188 498 # Assume no error on first track.
pascal@15188 499
pascal@15188 500 #ifdef FLOPPY_1440K_ONLY
pascal@21984 501 #ifndef FLOPPY_HAS_2_SIDES
pascal@19941 502 #define FLOPPY_HAS_2_SIDES hardcore heads count to 2
pascal@21984 503 #endif
pascal@15188 504 #define FLOPPY_SECTORS 18 /* 18 sectors */
pascal@15188 505 #else
pascal@15188 506 #define FLOPPY_HEADS 2 /* 2 heads minimum */
pascal@15188 507 #endif
pascal@15188 508
pascal@19941 509 return:
pascal@19941 510 #ifndef NO_DOTS
pascal@19941 511 movw $0xE2E,%ax
pascal@19941 512 int $0x10
pascal@19941 513 #endif
pascal@19941 514 ret
pascal@19941 515
pascal@15188 516 check_limits:
pascal@15188 517 #ifndef FLOPPY_1440K_ONLY
pascal@15188 518 popw %dx
pascal@15188 519 cmpb %al, %cl # max sector known ?
pascal@15188 520 ja next_head # no -> store it
pascal@19941 521 #ifndef FLOPPY_HAS_2_SIDES
pascal@15188 522 #ifdef FLOPPY_HEADS
pascal@15188 523 cmpb $FLOPPY_HEADS, %dh # 2 heads minimum
pascal@15188 524 jb check_cylinder
pascal@15188 525 #endif
pascal@15188 526 cmpb %ah, %dh # max head known ?
pascal@15188 527 ja next_cylinder # no -> store it
pascal@15188 528 check_cylinder:
pascal@15188 529 #endif
pascal@20184 530 pushw %ax
pascal@15188 531 cbw # %ah = 0
pascal@20184 532 #else
pascal@20184 533 pushw %dx
pascal@15188 534 #endif
pascal@15188 535 int $0x13 # reset controler
pascal@20184 536 #ifndef FLOPPY_1440K_ONLY
pascal@20184 537 popw %ax
pascal@15188 538 movb $1, %al # sector by sector...
pascal@20184 539 #else
pascal@20184 540 movw $1, %ax
pascal@20184 541 jmp more1trk
pascal@20184 542 #endif
pascal@15188 543 read_sectorslp:
pascal@15188 544 pushw %dx # some bios break dx...
pascal@15188 545 #ifndef FLOPPY_1440K_ONLY
pascal@15188 546 pushw %ax # limits
pascal@15188 547 subb %cl, %al # sectors remaining in track
pascal@15188 548 ja tolastsect
pascal@20184 549 movb $1, %al # first track sector by sector
pascal@15188 550 tolastsect:
pascal@15188 551 #else
pascal@19402 552 movb $FLOPPY_SECTORS+1, %al
pascal@15188 553 subb %cl, %al # sectors remaining in track
pascal@15188 554 #endif
pascal@15188 555 cbw
pascal@15188 556 cmpw %di, %ax
pascal@15188 557 jb more1trk
pascal@15188 558 movw %di, %ax # sectors to read
pascal@15188 559 more1trk:
pascal@15188 560 pushw %ax # save context
pascal@15188 561 movb $2, %ah # cmd: read chs
pascal@15188 562 int $0x13
pascal@15188 563 #ifndef FLOPPY_1440K_ONLY
pascal@15188 564 popw %dx # save %ax
pascal@15188 565 popw %ax # limits
pascal@15188 566 #else
pascal@15188 567 popw %ax # restore context
pascal@15188 568 popw %dx
pascal@15188 569 #endif
pascal@15188 570 jc check_limits
pascal@15188 571 #ifndef FLOPPY_1440K_ONLY
pascal@15188 572 xchgw %ax, %bp
pascal@15188 573 addw %dx,%cx # next sector
pascal@20184 574 movw %cx, %si
pascal@20184 575 pushw %dx
pascal@20184 576 shlclw $5, %dx
pascal@15188 577 movw %es, %cx
pascal@15188 578 addw %dx, %cx
pascal@15188 579 popw %dx
pascal@15188 580 subw %dx,%di # update sector counter
pascal@15188 581 popw %dx
pascal@15188 582 #else
pascal@15188 583 addw %ax,%cx # next sector
pascal@20184 584 movw %cx, %si
pascal@20184 585 pushw %ax
pascal@20184 586 shlclw $5, %ax
pascal@15188 587 movw %es, %cx
pascal@15188 588 addw %ax, %cx
pascal@15188 589 popw %ax
pascal@15188 590 subw %ax,%di # update sector counter
pascal@19941 591 #endif
pascal@15188 592 read_sectorsCX:
pascal@15188 593 movw %cx, %es # next location
pascal@19941 594 jz return
pascal@15188 595 read_sectors:
pascal@20184 596 movw %si, %cx
pascal@15188 597 #ifndef FLOPPY_1440K_ONLY
pascal@15188 598 # al is last sector+1
pascal@20184 599 # ah is last head+1
pascal@15188 600 xchgw %ax, %bp
pascal@15188 601 #endif
pascal@15188 602 #ifndef FLOPPY_1440K_ONLY
pascal@15188 603 cmpb %al,%cl # reach sector limit ?
pascal@15188 604 jne bdendlp
pascal@15188 605 next_head:
pascal@15188 606 movb %cl,%al
pascal@15188 607 #else
pascal@15188 608 cmpb $FLOPPY_SECTORS+1,%cl # reach sector limit ?
pascal@15188 609 jne bdendlp
pascal@15188 610 #endif
pascal@19941 611 movb $1,%cl # first sector
pascal@19941 612 #ifndef FLOPPY_HAS_2_SIDES
pascal@15188 613 incb %dh # next head
pascal@15188 614 cmpb %ah, %dh # reach head limit ?
pascal@15188 615 jne bdendlp
pascal@15188 616 next_cylinder:
pascal@15188 617 movb %dh,%ah
pascal@19941 618 movb $0,%dh # first head
pascal@15188 619 #else
pascal@19941 620 xorb %cl,%dh # next head
pascal@19941 621 jne bdendlp # reach head limit ?
pascal@15188 622 #endif
pascal@15188 623 # NOTE : support 256 cylinders max
pascal@15188 624 incb %ch # next cylinder
pascal@15188 625 read_first_sectors:
pascal@15188 626 bdendlp:
pascal@15188 627 jmp read_sectorslp
pascal@15188 628
pascal@19941 629 #ifdef VCPI
pascal@19941 630 pagebuf = 0x98000
pascal@19920 631 tss = gdt_abs-40
pascal@19920 632 gdt = gdt_abs-32
pascal@19920 633 gdt_null = gdt_abs-32
pascal@19920 634 gdt_vcpi = gdt_abs-24
pascal@19920 635 gdt_vcpi2 = gdt_abs-16
pascal@19920 636 gdt_vcpi3 = gdt_abs-8
pascal@19920 637 gdt_abs:
pascal@25044 638 SEL_DATA = gdt_abs-gdt_null
pascal@19941 639 .word 0xFFFF
pascal@19941 640 .long 0x92000000
pascal@25044 641 .byte 0x8F,0
pascal@19920 642 gdt_code:
pascal@19920 643 .word 0xFFFF
pascal@19920 644 gdt_code_base:
pascal@19941 645 .long 0x9A000000+FLAT20(0)
pascal@19920 646 .byte 0x8F,0
pascal@19920 647 gdt_tss:
pascal@19920 648 .word 0x00FF
pascal@19920 649 gdt_tss_base:
pascal@19941 650 .long 0x89000000+FLAT20(tss)
pascal@19920 651 .byte 0,0
pascal@19920 652 gdtr:
pascal@19920 653 gdt_lim:
pascal@19920 654 .word 0xFFFF
pascal@19920 655 gdt_base:
pascal@19941 656 .long FLAT20(gdt)
pascal@19920 657 sw2pm_params:
pascal@19920 658 sw2pm_cr3:
pascal@19920 659 .long pagebuf+0x1000
pascal@19920 660 sw2pm_gdtr_ptr:
pascal@19941 661 .long FLAT20(gdtr)
pascal@19920 662 sw2pm_idtr_ptr:
pascal@19941 663 .long FLAT20(idtr)
pascal@19920 664 sw2pm_ldtr:
pascal@19920 665 .word 0
pascal@19920 666 sw2pm_tr:
pascal@19920 667 SEL_TSS = gdt_tss-gdt_null
pascal@19920 668 .word SEL_TSS
pascal@19920 669 sw2pm_jumpaddr:
pascal@19941 670 .long pm_code
pascal@19920 671 SEL_CODE = gdt_code-gdt_null
pascal@19920 672 .word SEL_CODE
pascal@19920 673 idtr:
pascal@19920 674 idt_lim:
pascal@19920 675 .word 0x03FF
pascal@19920 676 idt_base:
pascal@19920 677 .long 0
pascal@19920 678 #endif
pascal@20184 679 #ifdef ELKS
pascal@20184 680 .org 0x1E3
pascal@20184 681 .byte 13,10,7
pascal@20184 682 .asciz "ELKS Boot"
pascal@20184 683 #endif