wok annotate memtest64/stuff/bootloader.S @ rev 25852

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