wok annotate plop/stuff/bootloader.S @ rev 25076

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