wok annotate ipxe/stuff/bootloader.S @ rev 25503

f3: include extra programs
author Hans-G?nter Theisgen
date Fri Jan 27 10:37:43 2023 +0100 (17 months ago)
parents 8e505f99deb3
children
rev   line source
pascal@20179 1 // Image/zImage & tiny bzImage linux kernel boot sector, (C) SliTaz, GPL2.
pascal@20179 2
pascal@20179 3 SYSSEG = 0x1000
pascal@20179 4 setup_sects = 497
pascal@20179 5 syssize = 500
pascal@20179 6 cmd_line_ptr = 0x228
pascal@20179 7
pascal@20179 8 .text
pascal@20179 9 .code16
pascal@20179 10 .org 0
pascal@20179 11 .globl _start
pascal@20179 12 _start:
pascal@20179 13
pascal@20179 14 #define CODESZ 512 /* patched by installer */
pascal@20179 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@20179 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@20179 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@24954 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@25044 33 #define NO_DOTS show progression dots ? -5
pascal@20179 34 #ifndef BZIMAGE
pascal@20184 35 //#define TINY_ZIMAGE system < 64Kb ? -11
pascal@24045 36 //#define NO_MINSETUP default setup (dos only) ? -4
pascal@20179 37 //#define NO_CURSOR_DEFINITION -8
pascal@20179 38 #endif
pascal@20179 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@20179 70 #ifdef EXE_SUPPORT
pascal@20179 71 #define EXEADRS(x) (x+0xE0)
pascal@20179 72 #define FLAT20(x) (x+16*INITSEG)
pascal@20179 73
pascal@20179 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@20179 92 pushl $4
pascal@20179 93 popw %si
pascal@20179 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@20179 103 pushl (%si)
pascal@20179 104 movl $step19+(INITSEG<<16), (%si)
pascal@20184 105 #endif
pascal@20179 106 pushfw
pascal@20179 107 popw %ax
pascal@20179 108 incb %ah # set TF
pascal@20179 109 pushw %ax
pascal@20179 110 popfw
pascal@24954 111 #ifdef ONLY8086
pascal@24954 112 ljmp *4*0x19(%si)
pascal@24954 113 #else
pascal@20179 114 ljmp *4*0x19-4(%si)
pascal@24954 115 #endif
pascal@20179 116 .endm
pascal@20179 117
pascal@20179 118 stacktop = 0x9E00 # in 0x8000 .. 0xA000
pascal@20179 119 decw %bp // Magic number: MZ
pascal@20179 120 popw %dx
pascal@20179 121 jmp start // Bytes on last page of file
pascal@20179 122 .word (CODESZ+511)/512 // Pages in file INSTALLER
pascal@20179 123 .word 0 // Relocations
pascal@20179 124 .word (end_header-_start)/16 // Size of header in paragraphs
pascal@20179 125 .word 4096 // Minimum extra paragraphs needed
pascal@20179 126 .word -1 // Maximum extra paragraphs needed
pascal@20179 127 .word (CODESZ+15)/16 // Initial (relative) SS value INSTALLER
pascal@20179 128 .word stacktop // Initial SP value
pascal@20179 129 .word 0 // Checksum INSTALLER?
pascal@20179 130 .word EXEADRS(comstart) // Initial IP value
pascal@20179 131 .word 0xFFF0 // Initial (relative) CS value
pascal@20179 132 // .word 0x001C // File address of relocation table
pascal@20179 133 // .word 0,0,0 // Overlay number
pascal@20184 134 #else
pascal@20184 135 #undef VCPI
pascal@20179 136 #endif
pascal@20179 137 start:
pascal@20179 138 xorw %ax, %ax # %ax = 0
pascal@20179 139 zeroed = 12 # zeroed registers
pascal@20179 140 movw $zeroed/2, %cx # clear gdt + offset, %ds, limits
pascal@20179 141 stacktop = 0x9E00 # in 0x8000 .. 0xA000 (+zeroed+12)
pascal@20184 142 #ifdef ONLY8086
pascal@20184 143 movw $INITSEG, %bx
pascal@20184 144 #else
pascal@20179 145 pushw $INITSEG
pascal@20184 146 #endif
pascal@20179 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@20179 153 # cmdline offset at 0x22
pascal@20179 154 movw $stacktop, %di # stacktop is an arbitrary value >=
pascal@20179 155 # length of bootsect + length of
pascal@20179 156 # setup + room for stack;
pascal@20179 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@20179 165 movw %di, %sp # put stack at INITSEG:stacktop-...
pascal@20179 166 #ifdef EXE_SUPPORT
pascal@20179 167 cwd # force %dx = 0 (floppy only)
pascal@20179 168 #endif
pascal@20179 169
pascal@20179 170 # Many BIOS's default disk parameter tables will not recognize
pascal@20179 171 # multi-sector reads beyond the maximum sector number specified
pascal@20179 172 # in the default diskette parameter tables - this may mean 7
pascal@20179 173 # sectors in some cases.
pascal@20179 174 #
pascal@20179 175 # Since single sector reads are slow and out of the question,
pascal@20179 176 # we must take care of this by creating new parameter tables
pascal@20179 177 # (for the first disk) in RAM. We can set the maximum sector
pascal@20179 178 # count to 36 - the most we will encounter on an ED 2.88.
pascal@20179 179 #
pascal@20179 180 # High doesn't hurt. Low does. Let's use the max: 63
pascal@20179 181
pascal@20179 182 rep # don't worry about cld
pascal@20179 183 stosw # already done above
pascal@20179 184 popw %bx # offset = 0
pascal@20179 185 popw %ds # %ds = 0
pascal@20179 186
pascal@20179 187 movb setup_sects+0x7C00, %al # read bootsector + setup (%ds = 0)
pascal@20179 188 incw %ax
pascal@20179 189
pascal@20179 190 ldsw 0x78(%bx), %si # %ds:%bx+0x78 is parameter table address
pascal@20179 191 pushw %es
pascal@20179 192 pushw %di
pascal@20179 193 movb $6, %cl # copy 12 bytes
pascal@20179 194 rep # don't worry about cld
pascal@20179 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@20179 203 pushw %ss
pascal@20179 204 popw %ds # now %ds = %es = %ss = INITSEG
pascal@20179 205 movb $63, 0x4-12(%di) # patch sector count, %di = stacktop
pascal@20179 206
pascal@20179 207 xchg %ax, %di # sector count
pascal@20179 208 popw %ax # limits = 0
pascal@20179 209 incw %cx # cylinder 0, sector 1, clear Z
pascal@20179 210 call read_first_sectors # read setup
pascal@20179 211
pascal@20179 212 # This routine loads the system at address LOADSEG, making sure
pascal@20179 213 # no 64kB boundaries are crossed. We try to load it as fast as
pascal@20179 214 # possible, loading whole tracks whenever we can.
pascal@20179 215
pascal@20179 216 movw syssize, %di
pascal@20179 217 decw %di
pascal@20184 218 shrclw $9-4, %di
pascal@20179 219 incw %di
pascal@20179 220 movw $SYSSEG, %cx
pascal@20179 221 #ifdef BZIMAGE
pascal@20179 222 push %cx
pascal@20179 223 #endif
pascal@20179 224 call read_sectorsCX
pascal@20179 225
pascal@20179 226 # This procedure turns off the floppy drive motor, so
pascal@20179 227 # that we enter the kernel in a known state, and
pascal@20179 228 # don't have to worry about it later.
pascal@20179 229
pascal@20179 230 kill_motor:
pascal@20179 231 xchgw %ax, %di # reset FDC (%di < 128)
pascal@20179 232 int $0x13
pascal@20179 233
pascal@20179 234 # After that (everything loaded), we jump to the setup-routine
pascal@20179 235 # loaded directly after the bootblock:
pascal@20179 236 # Segments are as follows: %ds = %ss = INITSEG
pascal@20179 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@20179 277 jmp_setup:
pascal@20184 278 cli
pascal@20179 279 ljmp $SETUPSEG, $0
pascal@20179 280
pascal@20179 281 #ifdef EXE_SUPPORT
pascal@20179 282 #ifdef SHUTDOWNDOS
pascal@20179 283 doiret:
pascal@20179 284 iret
pascal@20179 285 step19:
pascal@20179 286 pushw %si
pascal@20179 287 pushw %ds
pascal@20179 288 movw %sp, %si
pascal@20179 289 ldsw %ss:4(%si), %si
pascal@20179 290 cmpw $0x19CD, (%si)
pascal@20179 291 popw %ds
pascal@20179 292 popw %si
pascal@20179 293 jne doiret
pascal@20179 294 xorw %si, %si
pascal@20179 295 movw %si, %ds
pascal@20179 296 pushw %cs
pascal@20179 297 popw %ss
pascal@20179 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@20179 311 popl 4(%si)
pascal@24957 312 skip_step19:
pascal@20179 313 popaw
pascal@20184 314 #endif
pascal@20179 315 #ifdef BZIMAGE
pascal@20179 316 jmp movesys
pascal@20179 317 #endif
pascal@20179 318 #endif
pascal@20179 319 #ifndef BZIMAGE
pascal@20179 320 movesys: // %ax = SYSSEG, %bx = DS, %si
pascal@20184 321 shrclw $4, %si
pascal@20179 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@24045 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@20179 339 subw %ax, %bx
pascal@20179 340 jnc forward
pascal@24045 341 //movw $0x8FFF, %ax
pascal@20179 342 movb $0x90, %ah
pascal@20179 343 forward:
pascal@20179 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@20179 349 cmc // C = 1 : 0
pascal@20179 350 adcw %di, %ax
pascal@20179 351 xorw %si, %si
pascal@20179 352 xorw %di, %di
pascal@20179 353 movb $0x10, %cl
pascal@20179 354 cmpb %cl, %ah // move 512k
pascal@20179 355 rep
pascal@20179 356 movsb
pascal@20179 357 jns forward
pascal@20184 358 #endif
pascal@20179 359 #ifndef NO_CURSOR_DEFINITION
pascal@20179 360 movb $1, %ah
pascal@20179 361 movb $0, %bh
pascal@20179 362 movb $0x20, %ch // 0x2000
pascal@20179 363 int $0x10
pascal@20179 364 #endif
pascal@20179 365 pushw %ss
pascal@20179 366 popw %ds
pascal@20179 367 jmp jmp_setup
pascal@20179 368 #endif
pascal@20179 369 comstart:
pascal@20179 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@20179 375 pushw $INITSEG
pascal@20184 376 #endif
pascal@20179 377 popw %es
pascal@20179 378 #ifdef CMDLINE
pascal@20179 379 movw %sp, %di
pascal@20179 380 movw $0x80, %si
pascal@20179 381 lodsb
pascal@20179 382 cbw
pascal@20179 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@20179 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@20179 393 movw $0xA33F, 0x7F(%si)
pascal@20179 394 # endif
pascal@20179 395 # ifndef NO_CMDLINE_SHRINK
pascal@20179 396 skipspace:
pascal@20179 397 lodsb
pascal@20179 398 cmpb $0x20, %al
pascal@20179 399 je skipspace
pascal@20179 400 # ifndef NO_CMDLINE_FILE
pascal@20179 401 movw %si,%dx
pascal@20179 402 decw %si
pascal@20179 403 subb $'@',%al
pascal@20179 404 jne notafile
pascal@20179 405 movb $0x3D,%ah
pascal@20179 406 int $0x21
pascal@20179 407 jc notafile
pascal@20179 408 xchgw %ax,%bx
pascal@20179 409 //movw %si,%dx // ~320 bytes max
pascal@20179 410 movw $EXEADRS(notafile)-130,%cx
pascal@20179 411 movb $0x3F,%ah
pascal@20179 412 int $0x21
pascal@20179 413 xchgw %ax,%cx
pascal@20179 414 notafile:
pascal@20179 415 # else
pascal@20179 416 decw %si
pascal@20179 417 # endif
pascal@20179 418 # endif
pascal@20179 419 rep
pascal@20179 420 movsb
pascal@20179 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@20179 432 #endif
pascal@20179 433 movb $(512-(end_header-_start))/2, %cl
pascal@20179 434 movw $0x100, %si
pascal@20179 435 movw $end_header, %di
pascal@20179 436 rep
pascal@20179 437 movsw
pascal@20179 438 movw $SYSSEG, %ax
pascal@20179 439 movw %ds, %bx
pascal@20179 440 pushw %es
pascal@20179 441 popw %ss
pascal@20179 442 #ifndef SHUTDOWNDOS
pascal@20179 443 pushw %es
pascal@20179 444 pushw $movesys
pascal@20179 445 #endif
pascal@20179 446 #ifdef VCPI
pascal@20179 447 pushaw
pascal@20179 448 smsww %ax
pascal@20179 449 andb $1, %al
pascal@20179 450 je isrm
pascal@20179 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@20179 454 call_vcpi:
pascal@20179 455 movb $0xDE,%ah // DE01, EBX = getiface(DS:SI, ES:DI)
pascal@20179 456 int $0x67
pascal@20179 457 movl $FLAT20(sw2pm_params),%esi
pascal@20179 458 movb $0x0C,%al // DE0C switchpm(ESI)
pascal@20179 459 jmp call_vcpi
pascal@20179 460 pm_code:
pascal@25044 461 .byte 0x6A, SEL_DATA // pushw $SEL_DATA
pascal@25044 462 popw %ss
pascal@20179 463 movl %cr0,%eax
pascal@20179 464 andl $0x7FFFFFFE,%eax
pascal@20179 465 movl %eax,%cr0
pascal@20179 466 movl %eax,%cr3
pascal@20179 467 isrm:
pascal@20179 468 # ifdef SHUTDOWNDOS
pascal@20179 469 trace_int19
pascal@20179 470 # else
pascal@20179 471 popaw
pascal@20179 472 retf
pascal@20179 473 # endif
pascal@20179 474 #else
pascal@20179 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@20179 485 pushaw
pascal@20184 486 # endif
pascal@20179 487 trace_int19
pascal@20179 488 # endif
pascal@20179 489 retf
pascal@20179 490 #endif
pascal@20179 491 #endif
pascal@20179 492
pascal@20179 493 # read_sectors reads %di sectors into %es:0 buffer.
pascal@20179 494 # %es:0 is updated to the next memory location.
pascal@20179 495 # First, sectors are read sector by sector until
pascal@20179 496 # sector per track count is known. Then they are
pascal@20179 497 # read track by track.
pascal@20179 498 # Assume no error on first track.
pascal@20179 499
pascal@20179 500 #ifdef FLOPPY_1440K_ONLY
pascal@24045 501 #ifndef FLOPPY_HAS_2_SIDES
pascal@20179 502 #define FLOPPY_HAS_2_SIDES hardcore heads count to 2
pascal@24045 503 #endif
pascal@20179 504 #define FLOPPY_SECTORS 18 /* 18 sectors */
pascal@20179 505 #else
pascal@20179 506 #define FLOPPY_HEADS 2 /* 2 heads minimum */
pascal@20179 507 #endif
pascal@20179 508
pascal@20179 509 return:
pascal@20179 510 #ifndef NO_DOTS
pascal@20179 511 movw $0xE2E,%ax
pascal@20179 512 int $0x10
pascal@20179 513 #endif
pascal@20179 514 ret
pascal@20179 515
pascal@20179 516 check_limits:
pascal@20179 517 #ifndef FLOPPY_1440K_ONLY
pascal@20179 518 popw %dx
pascal@20179 519 cmpb %al, %cl # max sector known ?
pascal@20179 520 ja next_head # no -> store it
pascal@20179 521 #ifndef FLOPPY_HAS_2_SIDES
pascal@20179 522 #ifdef FLOPPY_HEADS
pascal@20179 523 cmpb $FLOPPY_HEADS, %dh # 2 heads minimum
pascal@20179 524 jb check_cylinder
pascal@20179 525 #endif
pascal@20179 526 cmpb %ah, %dh # max head known ?
pascal@20179 527 ja next_cylinder # no -> store it
pascal@20179 528 check_cylinder:
pascal@20179 529 #endif
pascal@20184 530 pushw %ax
pascal@20179 531 cbw # %ah = 0
pascal@20184 532 #else
pascal@20184 533 pushw %dx
pascal@20179 534 #endif
pascal@20179 535 int $0x13 # reset controler
pascal@20184 536 #ifndef FLOPPY_1440K_ONLY
pascal@20184 537 popw %ax
pascal@20179 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@20179 543 read_sectorslp:
pascal@20179 544 pushw %dx # some bios break dx...
pascal@20179 545 #ifndef FLOPPY_1440K_ONLY
pascal@20179 546 pushw %ax # limits
pascal@20179 547 subb %cl, %al # sectors remaining in track
pascal@20179 548 ja tolastsect
pascal@20184 549 movb $1, %al # first track sector by sector
pascal@20179 550 tolastsect:
pascal@20179 551 #else
pascal@20179 552 movb $FLOPPY_SECTORS+1, %al
pascal@20179 553 subb %cl, %al # sectors remaining in track
pascal@20179 554 #endif
pascal@20179 555 cbw
pascal@20179 556 cmpw %di, %ax
pascal@20179 557 jb more1trk
pascal@20179 558 movw %di, %ax # sectors to read
pascal@20179 559 more1trk:
pascal@20179 560 pushw %ax # save context
pascal@20179 561 movb $2, %ah # cmd: read chs
pascal@20179 562 int $0x13
pascal@20179 563 #ifndef FLOPPY_1440K_ONLY
pascal@20179 564 popw %dx # save %ax
pascal@20179 565 popw %ax # limits
pascal@20179 566 #else
pascal@20179 567 popw %ax # restore context
pascal@20179 568 popw %dx
pascal@20179 569 #endif
pascal@20179 570 jc check_limits
pascal@20179 571 #ifndef FLOPPY_1440K_ONLY
pascal@20179 572 xchgw %ax, %bp
pascal@20179 573 addw %dx,%cx # next sector
pascal@20184 574 movw %cx, %si
pascal@20184 575 pushw %dx
pascal@20184 576 shlclw $5, %dx
pascal@20179 577 movw %es, %cx
pascal@20179 578 addw %dx, %cx
pascal@20179 579 popw %dx
pascal@20179 580 subw %dx,%di # update sector counter
pascal@20179 581 popw %dx
pascal@20179 582 #else
pascal@20179 583 addw %ax,%cx # next sector
pascal@20184 584 movw %cx, %si
pascal@20184 585 pushw %ax
pascal@20184 586 shlclw $5, %ax
pascal@20179 587 movw %es, %cx
pascal@20179 588 addw %ax, %cx
pascal@20179 589 popw %ax
pascal@20179 590 subw %ax,%di # update sector counter
pascal@20179 591 #endif
pascal@20179 592 read_sectorsCX:
pascal@20179 593 movw %cx, %es # next location
pascal@20179 594 jz return
pascal@20179 595 read_sectors:
pascal@20184 596 movw %si, %cx
pascal@20179 597 #ifndef FLOPPY_1440K_ONLY
pascal@20179 598 # al is last sector+1
pascal@20184 599 # ah is last head+1
pascal@20179 600 xchgw %ax, %bp
pascal@20179 601 #endif
pascal@20179 602 #ifndef FLOPPY_1440K_ONLY
pascal@20179 603 cmpb %al,%cl # reach sector limit ?
pascal@20179 604 jne bdendlp
pascal@20179 605 next_head:
pascal@20179 606 movb %cl,%al
pascal@20179 607 #else
pascal@20179 608 cmpb $FLOPPY_SECTORS+1,%cl # reach sector limit ?
pascal@20179 609 jne bdendlp
pascal@20179 610 #endif
pascal@20179 611 movb $1,%cl # first sector
pascal@20179 612 #ifndef FLOPPY_HAS_2_SIDES
pascal@20179 613 incb %dh # next head
pascal@20179 614 cmpb %ah, %dh # reach head limit ?
pascal@20179 615 jne bdendlp
pascal@20179 616 next_cylinder:
pascal@20179 617 movb %dh,%ah
pascal@20179 618 movb $0,%dh # first head
pascal@20179 619 #else
pascal@20179 620 xorb %cl,%dh # next head
pascal@20179 621 jne bdendlp # reach head limit ?
pascal@20179 622 #endif
pascal@20179 623 # NOTE : support 256 cylinders max
pascal@20179 624 incb %ch # next cylinder
pascal@20179 625 read_first_sectors:
pascal@20179 626 bdendlp:
pascal@20179 627 jmp read_sectorslp
pascal@20179 628
pascal@20179 629 #ifdef VCPI
pascal@20179 630 pagebuf = 0x98000
pascal@20179 631 tss = gdt_abs-40
pascal@20179 632 gdt = gdt_abs-32
pascal@20179 633 gdt_null = gdt_abs-32
pascal@20179 634 gdt_vcpi = gdt_abs-24
pascal@20179 635 gdt_vcpi2 = gdt_abs-16
pascal@20179 636 gdt_vcpi3 = gdt_abs-8
pascal@20179 637 gdt_abs:
pascal@25044 638 SEL_DATA = gdt_abs-gdt_null
pascal@20179 639 .word 0xFFFF
pascal@20179 640 .long 0x92000000
pascal@25044 641 .byte 0x8F,0
pascal@20179 642 gdt_code:
pascal@20179 643 .word 0xFFFF
pascal@20179 644 gdt_code_base:
pascal@20179 645 .long 0x9A000000+FLAT20(0)
pascal@20179 646 .byte 0x8F,0
pascal@20179 647 gdt_tss:
pascal@20179 648 .word 0x00FF
pascal@20179 649 gdt_tss_base:
pascal@20179 650 .long 0x89000000+FLAT20(tss)
pascal@20179 651 .byte 0,0
pascal@20179 652 gdtr:
pascal@20179 653 gdt_lim:
pascal@20179 654 .word 0xFFFF
pascal@20179 655 gdt_base:
pascal@20179 656 .long FLAT20(gdt)
pascal@20179 657 sw2pm_params:
pascal@20179 658 sw2pm_cr3:
pascal@20179 659 .long pagebuf+0x1000
pascal@20179 660 sw2pm_gdtr_ptr:
pascal@20179 661 .long FLAT20(gdtr)
pascal@20179 662 sw2pm_idtr_ptr:
pascal@20179 663 .long FLAT20(idtr)
pascal@20179 664 sw2pm_ldtr:
pascal@20179 665 .word 0
pascal@20179 666 sw2pm_tr:
pascal@20179 667 SEL_TSS = gdt_tss-gdt_null
pascal@20179 668 .word SEL_TSS
pascal@20179 669 sw2pm_jumpaddr:
pascal@20179 670 .long pm_code
pascal@20179 671 SEL_CODE = gdt_code-gdt_null
pascal@20179 672 .word SEL_CODE
pascal@20179 673 idtr:
pascal@20179 674 idt_lim:
pascal@20179 675 .word 0x03FF
pascal@20179 676 idt_base:
pascal@20179 677 .long 0
pascal@20179 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
pascal@25045 684 .org 0x1F1