- 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:
parent
34130cc1ad
commit
e247b0f14d
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user