Przeglądaj źródła

Proof of concept; works, but has several hard-coded hacks.

tags/v0.9.3
Michael Brown 17 lat temu
rodzic
commit
c7d9fdb5b9
1 zmienionych plików z 46 dodań i 7 usunięć
  1. 46
    7
      src/arch/i386/interface/pcbios/int13.c

+ 46
- 7
src/arch/i386/interface/pcbios/int13.c Wyświetl plik

@@ -355,12 +355,18 @@ static int int13_cdrom_status_terminate ( struct int13_drive *drive,
355 355
  */
356 356
 static void int13 ( struct i386_all_regs *ix86 ) {
357 357
 	int command = ix86->regs.ah;
358
+	unsigned int bios_drive = ix86->regs.dl;
359
+	unsigned int original_bios_drive = bios_drive;
358 360
 	struct int13_drive *drive;
359 361
 	int status;
360 362
 
361 363
 	list_for_each_entry ( drive, &drives, list ) {
362
-		if ( drive->drive != ix86->regs.dl )
364
+		if ( drive->drive > bios_drive )
363 365
 			continue;
366
+		if ( drive->drive < bios_drive ) {
367
+			original_bios_drive--;
368
+			continue;
369
+		}
364 370
 		
365 371
 		DBG ( "INT 13,%04x (%02x): ", ix86->regs.ax, drive->drive );
366 372
 
@@ -421,6 +427,13 @@ static void int13 ( struct i386_all_regs *ix86 ) {
421 427
 
422 428
 		break;
423 429
 	}
430
+
431
+	/* Remap BIOS drive */
432
+	if ( bios_drive != original_bios_drive ) {
433
+		DBG ( "INT 13,%04x (%02x) remapped to (%02x)\n",
434
+		      ix86->regs.ax, bios_drive, original_bios_drive );
435
+	}
436
+	ix86->regs.dl = original_bios_drive;
424 437
 }
425 438
 
426 439
 /**
@@ -434,19 +447,42 @@ static void hook_int13 ( void ) {
434 447
 	 */
435 448
 	__asm__  __volatile__ (
436 449
 	       TEXT16_CODE ( "\nint13_wrapper:\n\t"
437
-			     "orb $0, %%al\n\t" /* clear OF */
450
+			     /* Preserve %ax and %dx for future reference */
451
+			     "pushw %%bp\n\t"
452
+			     "movw %%sp, %%bp\n\t"			     
453
+			     "pushw %%ax\n\t"
454
+			     "pushw %%dx\n\t"
455
+			     /* Clear OF, set CF, call int13() */
456
+			     "orb $0, %%al\n\t" 
438 457
 			     "stc\n\t"
439
-			     "pushl %0\n\t" /* call int13() */
458
+			     "pushl %0\n\t"
440 459
 			     "pushw %%cs\n\t"
441 460
 			     "call prot_call\n\t"
442
-			     "jo 1f\n\t" /* chain if OF not set */
461
+			     /* Chain if OF not set */
462
+			     "jo 1f\n\t"
443 463
 			     "pushfw\n\t"
444 464
 			     "lcall *%%cs:int13_vector\n\t"
445 465
 			     "\n1:\n\t"
446
-			     "call 2f\n\t" /* return with flags intact */
447
-			     "lret $2\n\t"
466
+			     /* Overwrite flags for iret */
467
+			     "pushfw\n\t"
468
+			     "popw 6(%%bp)\n\t"
469
+			     /* Restore %dl (except for %ah=0x08 or 0x15) */
470
+			     "cmpb $0x08, -1(%%bp)\n\t"
471
+
472
+			     "jne 7f\n\t"
473
+			     "movb $2, %%dl\n\t"
474
+			     "jmp 2f\n\t"
475
+			     "\n7:\n\t"
476
+
477
+			     "je 2f\n\t"
478
+			     "cmpb $0x15, -1(%%bp)\n\t"
479
+			     "je 2f\n\t"
480
+			     "movb -4(%%bp), %%dl\n\t"
448 481
 			     "\n2:\n\t"
449
-			     "ret $4\n\t" ) : : "i" ( int13 ) );
482
+			     /* Return */
483
+			     "movw %%bp, %%sp\n\t"
484
+			     "popw %%bp\n\t"
485
+			     "iret\n\t" ) : : "i" ( int13 ) );
450 486
 
451 487
 	hook_bios_interrupt ( 0x13, ( unsigned int ) int13_wrapper,
452 488
 			      &int13_vector );
@@ -541,6 +577,9 @@ void register_int13_drive ( struct int13_drive *drive ) {
541 577
 		drive->drive = ( num_drives | 0x80 );
542 578
 	if ( num_drives <= ( drive->drive & 0x7f ) )
543 579
 		num_drives = ( ( drive->drive & 0x7f ) + 1 );
580
+
581
+	num_drives = 2;
582
+
544 583
 	put_real ( num_drives, BDA_SEG, BDA_NUM_DRIVES );
545 584
 
546 585
 	DBG ( "Registered INT13 drive %02x with C/H/S geometry %d/%d/%d\n",

Ładowanie…
Anuluj
Zapisz