|
@@ -51,6 +51,48 @@ extern void int13_wrapper ( void );
|
51
|
51
|
/** List of registered emulated drives */
|
52
|
52
|
static LIST_HEAD ( drives );
|
53
|
53
|
|
|
54
|
+/**
|
|
55
|
+ * Number of BIOS drives
|
|
56
|
+ *
|
|
57
|
+ * Note that this is the number of drives in the system as a whole
|
|
58
|
+ * (i.e. a mirror of the counter at 40:75), rather than a count of the
|
|
59
|
+ * number of emulated drives.
|
|
60
|
+ */
|
|
61
|
+static uint8_t num_drives;
|
|
62
|
+
|
|
63
|
+/**
|
|
64
|
+ * Update BIOS drive count
|
|
65
|
+ */
|
|
66
|
+static void int13_set_num_drives ( void ) {
|
|
67
|
+ struct int13_drive *drive;
|
|
68
|
+
|
|
69
|
+ /* Get current drive count */
|
|
70
|
+ get_real ( num_drives, BDA_SEG, BDA_NUM_DRIVES );
|
|
71
|
+
|
|
72
|
+ /* Ensure count is large enough to cover all of our emulated drives */
|
|
73
|
+ list_for_each_entry ( drive, &drives, list ) {
|
|
74
|
+ if ( num_drives <= ( drive->drive & 0x7f ) )
|
|
75
|
+ num_drives = ( ( drive->drive & 0x7f ) + 1 );
|
|
76
|
+ }
|
|
77
|
+
|
|
78
|
+ /* Update current drive count */
|
|
79
|
+ put_real ( num_drives, BDA_SEG, BDA_NUM_DRIVES );
|
|
80
|
+}
|
|
81
|
+
|
|
82
|
+/**
|
|
83
|
+ * Check number of drives
|
|
84
|
+ */
|
|
85
|
+static void int13_check_num_drives ( void ) {
|
|
86
|
+ uint8_t check_num_drives;
|
|
87
|
+
|
|
88
|
+ get_real ( check_num_drives, BDA_SEG, BDA_NUM_DRIVES );
|
|
89
|
+ if ( check_num_drives != num_drives ) {
|
|
90
|
+ int13_set_num_drives();
|
|
91
|
+ DBG ( "INT13 fixing up number of drives from %d to %d\n",
|
|
92
|
+ check_num_drives, num_drives );
|
|
93
|
+ }
|
|
94
|
+}
|
|
95
|
+
|
54
|
96
|
/**
|
55
|
97
|
* INT 13, 00 - Reset disk system
|
56
|
98
|
*
|
|
@@ -340,6 +382,9 @@ static __asmcall void int13 ( struct i386_all_regs *ix86 ) {
|
340
|
382
|
struct int13_drive *drive;
|
341
|
383
|
int status;
|
342
|
384
|
|
|
385
|
+ /* Check BIOS hasn't killed off our drive */
|
|
386
|
+ int13_check_num_drives();
|
|
387
|
+
|
343
|
388
|
list_for_each_entry ( drive, &drives, list ) {
|
344
|
389
|
|
345
|
390
|
if ( bios_drive != drive->drive ) {
|
|
@@ -555,7 +600,6 @@ void register_int13_drive ( struct int13_drive *drive ) {
|
555
|
600
|
/* Assign natural drive number */
|
556
|
601
|
get_real ( num_drives, BDA_SEG, BDA_NUM_DRIVES );
|
557
|
602
|
drive->natural_drive = ( num_drives | 0x80 );
|
558
|
|
- num_drives++;
|
559
|
603
|
|
560
|
604
|
/* Assign drive number */
|
561
|
605
|
if ( ( drive->drive & 0xff ) == 0xff ) {
|
|
@@ -564,13 +608,8 @@ void register_int13_drive ( struct int13_drive *drive ) {
|
564
|
608
|
} else {
|
565
|
609
|
/* Use specified drive number (+0x80 if necessary) */
|
566
|
610
|
drive->drive |= 0x80;
|
567
|
|
- if ( num_drives <= ( drive->drive & 0x7f ) )
|
568
|
|
- num_drives = ( ( drive->drive & 0x7f ) + 1 );
|
569
|
611
|
}
|
570
|
612
|
|
571
|
|
- /* Update BIOS drive count */
|
572
|
|
- put_real ( num_drives, BDA_SEG, BDA_NUM_DRIVES );
|
573
|
|
-
|
574
|
613
|
DBG ( "Registered INT13 drive %02x (naturally %02x) with C/H/S "
|
575
|
614
|
"geometry %d/%d/%d\n", drive->drive, drive->natural_drive,
|
576
|
615
|
drive->cylinders, drive->heads, drive->sectors_per_track );
|
|
@@ -581,6 +620,9 @@ void register_int13_drive ( struct int13_drive *drive ) {
|
581
|
620
|
|
582
|
621
|
/* Add to list of emulated drives */
|
583
|
622
|
list_add ( &drive->list, &drives );
|
|
623
|
+
|
|
624
|
+ /* Update BIOS drive count */
|
|
625
|
+ int13_set_num_drives();
|
584
|
626
|
}
|
585
|
627
|
|
586
|
628
|
/**
|