- fix package size in pointing device flags 2 (SF patch #3435049)

- implemented legacy BIOS int13 AL=17/18h diskette functions (patch taken from
  comment to SF feature request #3424738)
This commit is contained in:
Volker Ruppert 2011-11-19 12:38:12 +00:00
parent 34130cc1ad
commit e247b0f14d

View File

@ -4257,7 +4257,7 @@ BX_DEBUG_INT15("case 1 or 5:\n");
return;
}
mouse_flags_2 = read_byte(ebda_seg, &EbdaData->mouse_flag2);
mouse_flags_2 = (mouse_flags_2 & 0xF8) | regs.u.r8.bh;
mouse_flags_2 = (mouse_flags_2 & 0xF8) | regs.u.r8.bh - 1;
mouse_flags_1 = 0x00;
write_byte(ebda_seg, &EbdaData->mouse_flag1, mouse_flags_1);
write_byte(ebda_seg, &EbdaData->mouse_flag2, mouse_flags_2);
@ -5260,7 +5260,7 @@ BX_DEBUG_INT74("int74: read byte %02x\n", in_byte);
index = mouse_flags_1 & 0x07;
write_byte(ebda_seg, &EbdaData->mouse_data[index], in_byte);
if ( (index+1) >= package_count ) {
if (index >= package_count) {
BX_DEBUG_INT74("int74_function: make_farcall=1\n");
status = read_byte(ebda_seg, &EbdaData->mouse_data[0]);
X = read_byte(ebda_seg, &EbdaData->mouse_data[1]);
@ -7178,8 +7178,8 @@ int13_diskette_function(DS, ES, DI, SI, BP, ELDX, BX, DX, CX, AX, IP, CS, FLAGS)
Bit16u base_address, base_count, base_es;
Bit8u page, mode_register, val8, dor;
Bit8u return_status[7];
Bit8u drive_type, num_floppies, ah;
Bit16u es, last_addr;
Bit8u drive_type, num_floppies, ah, spt;
Bit16u es, last_addr, maxCyl;
BX_DEBUG_INT13_FL("int13_diskette: AX=%04x BX=%04x CX=%04x DX=%04x ES=%04x\n", AX, BX, CX, DX, ES);
@ -7842,17 +7842,264 @@ BX_DEBUG_INT13_FL("floppy f16\n");
case 0x17: // set diskette type for format(old)
BX_DEBUG_INT13_FL("floppy f17\n");
/* not used for 1.44M floppies */
SET_AH(0x01); // not supported
set_diskette_ret_status(1); /* not supported */
SET_CF();
// NOTE: 1.44M diskette not supported by this function,
// should use Int13 al=0x18 instead.
// Intr Reference: http://www.ctyme.com/intr
//
// ** media state byte **
// Bitfields for diskette drive media state byte that we might
// change in this function:
// Bit(s) Description (Table M0030)
// 7-6 data rate
// 00=500kbps, 01=300kbps, 10=250kbps, 11=1Mbps
// 5 double stepping required (e.g. 360kB in 1.2MB)
// 4 media type established
// Drive number (0 or 1) values allowed
drive = GET_ELDL();
// Drive type (AL)
// 00 - NOT USED
// 01 - DISKETTE 320/360K IN 360K DRIVE
// 02 - DISKETTE 360K IN 1.2M DRIVE
// 03 - DISKETTE 1.2M IN 1.2M DRIVE
// 04 - DISKETTE 720K IN 720K DRIVE
drive_type = GET_AL();
if (drive > 1) {
SET_AH(0x01); // invalid drive
set_diskette_ret_status(1); // bad parameter
SET_CF();
return;
}
// see if drive exists
if (floppy_drive_exists(drive) == 0) {
SET_AH(0x80); // not responding/time out
set_diskette_ret_status(0x80);
SET_CF();
return;
}
// Get current drive status into 'status'. Set 'base_address' to media status offset address
base_address = (drive) ? 0x0091 : 0x0090;
status = read_byte(0x0040, base_address);
// Mask out (clear) bits 4-7 (4:media type established, 5:double stepping, 6-7:data rate),
val8 = status & 0x0f;
switch(drive_type) {
case 1:
// 320/360K media in 360K drive
val8 |= 0x90; // 1001 0000 (media type established, data rate=250)
break;
case 2:
// 360K media in 1.2M drive
val8 |= 0x70; // 0111 0000 (media type established, double stepping, data rate=300)
break;
case 3:
// 1.2M media in 1.2M drive
val8 |= 0x10; // 0001 0000 (media type established, data rate=500)
break;
case 4:
// 720K media in 720K drive
if (((status >> 4) & 0x01) && ((status >> 1) & 0x01))
{
// Media type already determined, and multiple format capable, so assume a higher data rate.
val8 |= 0x50; // 0101 0000 (media type established, data rate=300)
}
else
{
// Media type not yet determined, or not multiple format capable, assume a lower data rate.
val8 |= 0x90; // 1001 0000 (media type established, data rate=250)
}
break;
default:
// bad parameter
SET_AH(0x01); // invalid drive
set_diskette_ret_status(1); // bad parameter
SET_CF();
return;
}
BX_DEBUG_INT13_FL("floppy f17 - media status set to: %02x\n", val8);
// Update media status
write_byte(0x0040, base_address, val8);
// return success!
SET_AH(0);
set_diskette_ret_status(0);
CLEAR_CF();
return;
case 0x18: // set diskette type for format(new)
BX_DEBUG_INT13_FL("floppy f18\n");
SET_AH(0x01); // do later
set_diskette_ret_status(1);
SET_CF();
// Set Media Type for Format verifies that the device supports a specific geometry.
// Unlike Int13 al=0x17 entry point, this version supports higher capacity
// drives like 1.44M and even 2.88M.
// Drive number (0 or 1) values allowed
drive = GET_ELDL();
val8 = GET_CL();
spt = val8 & 0x3f; // sectors per track
maxCyl = ((val8 >> 6) << 8) + GET_CH(); // max cylinder number (max cylinders - 1)
BX_DEBUG_INT13_FL("floppy f18 - drive: %d, max cylinder number: %d, sectors-per-tracks: %d\n", drive, maxCyl, spt);
if (drive > 1) {
SET_AH(0x01); // invalid drive
set_diskette_ret_status(1); // bad parameter
SET_CF();
return;
}
// see if drive exists
if (floppy_drive_exists(drive) == 0) {
SET_AH(0x80); // not responding/time out
set_diskette_ret_status(0x80);
SET_CF();
return;
}
// see if media in drive, and type is known
if (floppy_media_known(drive) == 0) {
if (floppy_media_sense(drive) == 0) {
SET_AH(0x0C); // drive type unknown
set_diskette_ret_status(0x0C);
SET_CF();
return;
}
}
// get current drive type
drive_type = inb_cmos(0x10);
if (drive == 0)
drive_type >>= 4;
else
drive_type &= 0x0f;
// Get current drive status into 'status'. Set 'base_address' to media status offset address
base_address = (drive) ? 0x0091 : 0x0090;
status = read_byte(0x0040, base_address);
// Mask out (clear) bits 4-7 (4:media type established, 5:double stepping, 6-7:data rate),
val8 = status & 0x0f;
SET_AH(0x0C); // Assume error - unsupported combination of drive-type/max-cylinders/sectors-per-track
switch (drive_type) {
case 0: // none
break;
case 1: // 360KB, 5.25"
case 6: // 160k, 5.25"
case 7: // 180k, 5.25"
case 8: // 320k, 5.25"
if (maxCyl == 39 && (spt == 8 || spt == 9))
{
val8 |= 0x90; // 1001 0000 (media type established, data rate=250)
SET_AH(0);
}
break;
case 2: // 1.2MB, 5.25"
if (maxCyl == 39 && (spt == 8 || spt == 9))
{
// 320K/360K disk in 1.2M drive
val8 |= 0x70; // 0111 0000 (media type established, double stepping, data rate=300)
SET_AH(0);
}
else if (maxCyl == 79 && spt == 15)
{
// 1.2M disk in 1.2M drive
val8 |= 0x10; // 0001 0000 (media type established, data rate=500)
SET_AH(0);
}
break;
case 3: // 720KB, 3.5"
if (maxCyl == 79 && spt == 9)
{
val8 |= 0x90; // 1001 0000 (media type established, data rate=250)
SET_AH(0);
}
break;
case 4: // 1.44MB, 3.5"
if (maxCyl == 79)
{
if (spt == 9)
{
// 720K disk in 1.44M drive
val8 |= 0x90; // 1001 0000 (media type established, data rate=250)
SET_AH(0);
}
else if (spt == 18)
{
// 1.44M disk in 1.44M drive
val8 |= 0x10; // 0001 0000 (media type established, data rate=500)
SET_AH(0);
}
}
break;
case 5: // 2.88MB, 3.5"
if (maxCyl == 79)
{
if (spt == 9)
{
// 720K disk in 2.88M drive
val8 |= 0x90; // 1001 0000 (media type established, data rate=250)
SET_AH(0);
}
else if (spt == 18)
{
// 1.44M disk in 2.88M drive
val8 |= 0x10; // 0001 0000 (media type established, data rate=500)
SET_AH(0);
}
else if (spt == 36)
{
// 2.88M disk in 2.88M drive
val8 |= 0xD0; // 1101 0000 (media type established, data rate=1mb/s)
SET_AH(0);
}
}
break;
default:
break;
}
if (0 != GET_AH())
{
// Error - assume requested max-cylinder/sectors-per-track not supported
// for current drive type - or drive type is unknown!
set_diskette_ret_status(GET_AH());
SET_CF();
return;
}
BX_DEBUG_INT13_FL("floppy f18 - media status set to: %02x\n", val8);
// Update media status
write_byte(0x0040, base_address, val8);
// set es & di to point to 11 byte diskette param table in ROM
// Note that we do not update the table, as I don't see it being used anywhere...
ASM_START
push bp
mov bp, sp
mov ax, #diskette_param_table2
mov _int13_diskette_function.DI+2[bp], ax
mov _int13_diskette_function.ES+2[bp], cs
pop bp
ASM_END
// return success!
set_diskette_ret_status(0);
CLEAR_CF();
return;
default: