- floppy cleanup patch from Alex Thiel. New functions enter_idle_phase() and
enter_result_phase(). This patch does not add new features and should not break anything.
This commit is contained in:
parent
de6fa4e2c5
commit
d05e7cc10c
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: floppy.cc,v 1.57 2002-10-25 11:44:39 bdenney Exp $
|
||||
// $Id: floppy.cc,v 1.58 2002-11-30 09:39:29 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||
@ -101,7 +101,7 @@ bx_floppy_ctrl_c::init(void)
|
||||
{
|
||||
Bit8u i;
|
||||
|
||||
BX_DEBUG(("Init $Id: floppy.cc,v 1.57 2002-10-25 11:44:39 bdenney Exp $"));
|
||||
BX_DEBUG(("Init $Id: floppy.cc,v 1.58 2002-11-30 09:39:29 vruppert Exp $"));
|
||||
DEV_dma_register_8bit_channel(2, dma_read, dma_write, "Floppy Drive");
|
||||
DEV_register_irq(6, "Floppy Drive");
|
||||
for (unsigned addr=0x03F2; addr<=0x03F7; addr++) {
|
||||
@ -161,10 +161,10 @@ bx_floppy_ctrl_c::init(void)
|
||||
& BX_FD_THIS s.media[0]))
|
||||
BX_FD_THIS s.media_present[0] = 1;
|
||||
else
|
||||
bx_options.floppya.Ostatus->set(BX_EJECTED);
|
||||
bx_options.floppya.Ostatus->set(BX_EJECTED);
|
||||
#define MED (BX_FD_THIS s.media[0])
|
||||
BX_INFO(("fd0: '%s' ro=%d, h=%d,t=%d,spt=%d", bx_options.floppya.Opath->getptr(),
|
||||
MED.write_protected, MED.heads, MED.tracks, MED.sectors_per_track));
|
||||
BX_INFO(("fd0: '%s' ro=%d, h=%d,t=%d,spt=%d", bx_options.floppya.Opath->getptr(),
|
||||
MED.write_protected, MED.heads, MED.tracks, MED.sectors_per_track));
|
||||
#undef MED
|
||||
}
|
||||
}
|
||||
@ -212,10 +212,10 @@ bx_floppy_ctrl_c::init(void)
|
||||
& BX_FD_THIS s.media[1]))
|
||||
BX_FD_THIS s.media_present[1] = 1;
|
||||
else
|
||||
bx_options.floppyb.Ostatus->set(BX_EJECTED);
|
||||
bx_options.floppyb.Ostatus->set(BX_EJECTED);
|
||||
#define MED (BX_FD_THIS s.media[1])
|
||||
BX_INFO(("fd1: '%s' ro=%d, h=%d,t=%d,spt=%d", bx_options.floppyb.Opath->getptr(),
|
||||
MED.write_protected, MED.heads, MED.tracks, MED.sectors_per_track));
|
||||
BX_INFO(("fd1: '%s' ro=%d, h=%d,t=%d,spt=%d", bx_options.floppyb.Opath->getptr(),
|
||||
MED.write_protected, MED.heads, MED.tracks, MED.sectors_per_track));
|
||||
#undef MED
|
||||
}
|
||||
}
|
||||
@ -233,7 +233,7 @@ bx_floppy_ctrl_c::init(void)
|
||||
if (BX_FD_THIS s.floppy_timer_index == BX_NULL_TIMER_HANDLE) {
|
||||
BX_FD_THIS s.floppy_timer_index =
|
||||
bx_pc_system.register_timer( this, timer_handler,
|
||||
bx_options.Ofloppy_command_delay->get (), 0,0, "floppy");
|
||||
bx_options.Ofloppy_command_delay->get (), 0,0, "floppy");
|
||||
}
|
||||
|
||||
BX_DEBUG(("bx_options.Ofloppy_command_delay = %u",
|
||||
@ -247,19 +247,10 @@ bx_floppy_ctrl_c::reset(unsigned type)
|
||||
{
|
||||
Bit32u i;
|
||||
|
||||
BX_FD_THIS s.command_complete = 1; /* waiting for new command */
|
||||
BX_FD_THIS s.command_index = 0;
|
||||
BX_FD_THIS s.command_size = 0;
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
|
||||
BX_FD_THIS s.pending_irq = 0;
|
||||
BX_FD_THIS s.reset_sensei = 0; /* no reset result present */
|
||||
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.result_size = 0;
|
||||
|
||||
/* data register ready, not in DMA mode */
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ;
|
||||
BX_FD_THIS s.main_status_reg = 0;
|
||||
BX_FD_THIS s.status_reg0 = 0;
|
||||
BX_FD_THIS s.status_reg1 = 0;
|
||||
BX_FD_THIS s.status_reg2 = 0;
|
||||
@ -286,10 +277,9 @@ bx_floppy_ctrl_c::reset(unsigned type)
|
||||
BX_FD_THIS s.sector[i] = 0;
|
||||
}
|
||||
|
||||
BX_FD_THIS s.floppy_buffer_index = 0;
|
||||
|
||||
DEV_pic_lower_irq(6);
|
||||
DEV_dma_set_drq(FLOPPY_DMA_CHAN, 0);
|
||||
enter_idle_phase();
|
||||
}
|
||||
|
||||
|
||||
@ -344,12 +334,9 @@ bx_floppy_ctrl_c::read(Bit32u address, unsigned io_len)
|
||||
value = BX_FD_THIS s.result[BX_FD_THIS s.result_index++];
|
||||
BX_FD_THIS s.main_status_reg &= 0xF0;
|
||||
if (BX_FD_THIS s.result_index >= BX_FD_THIS s.result_size) {
|
||||
BX_FD_THIS s.result_size = 0;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.result[0] = value;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ;
|
||||
if (!BX_FD_THIS s.reset_sensei) BX_FD_THIS s.pending_irq = 0;
|
||||
DEV_pic_lower_irq(6);
|
||||
DEV_pic_lower_irq(6);
|
||||
enter_idle_phase();
|
||||
}
|
||||
return(value);
|
||||
break;
|
||||
@ -360,12 +347,12 @@ bx_floppy_ctrl_c::read(Bit32u address, unsigned io_len)
|
||||
|
||||
switch( BX_FD_THIS s.DOR & 0x03 )
|
||||
{
|
||||
case 0x00:
|
||||
if( (BX_FD_THIS s.DOR & 0x10) == 0) break;
|
||||
return(2);
|
||||
case 0x01:
|
||||
if( (BX_FD_THIS s.DOR & 0x20) == 0) break;
|
||||
return(1);
|
||||
case 0x00:
|
||||
if( (BX_FD_THIS s.DOR & 0x10) == 0) break;
|
||||
return(2);
|
||||
case 0x01:
|
||||
if( (BX_FD_THIS s.DOR & 0x20) == 0) break;
|
||||
return(1);
|
||||
}
|
||||
return(3);
|
||||
|
||||
@ -524,15 +511,17 @@ bx_floppy_ctrl_c::write(Bit32u address, Bit32u value, unsigned io_len)
|
||||
// the enhanced controller.
|
||||
BX_DEBUG(("io_write: 0x3f5: unsupported floppy command 0x%02x",
|
||||
(unsigned) value));
|
||||
BX_FD_THIS s.command_size = 1;
|
||||
BX_FD_THIS s.command_size = 0; // make sure we don't try to process this command
|
||||
BX_FD_THIS s.status_reg0 = 0x80; // status: invalid command
|
||||
enter_result_phase();
|
||||
break;
|
||||
|
||||
default:
|
||||
BX_ERROR(("io_write: 0x3f5: invalid floppy command 0x%02x",
|
||||
(unsigned) value));
|
||||
BX_FD_THIS s.command_size = 1;
|
||||
BX_FD_THIS s.command_size = 0; // make sure we don't try to process this command
|
||||
BX_FD_THIS s.status_reg0 = 0x80; // status: invalid command
|
||||
enter_result_phase();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -605,7 +594,8 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
BX_FD_THIS s.main_status_reg |= 20;
|
||||
#endif
|
||||
|
||||
switch (BX_FD_THIS s.command[0]) {
|
||||
BX_FD_THIS s.pending_command = BX_FD_THIS s.command[0];
|
||||
switch (BX_FD_THIS s.pending_command) {
|
||||
case 0x03: // specify
|
||||
// execution: specified parameters are loaded
|
||||
// result: no result bytes, no interrupt
|
||||
@ -614,19 +604,17 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
head_load_time = BX_FD_THIS s.command[2] >> 1;
|
||||
if (BX_FD_THIS s.command[2] & 0x01)
|
||||
BX_ERROR(("non DMA mode selected"));
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ;
|
||||
enter_idle_phase();
|
||||
return;
|
||||
break;
|
||||
|
||||
case 0x04: // get status
|
||||
drive = (BX_FD_THIS s.command[1] & 0x03);
|
||||
BX_FD_THIS s.head[drive] = (BX_FD_THIS s.command[1] >> 2) & 0x01;
|
||||
BX_FD_THIS s.result[0] = 0x28 | (BX_FD_THIS s.head[drive]<<2) | drive
|
||||
BX_FD_THIS s.status_reg3 = 0x28 | (BX_FD_THIS s.head[drive]<<2) | drive
|
||||
| (BX_FD_THIS s.media[drive].write_protected ? 0x40 : 0x00);
|
||||
if (BX_FD_THIS s.cylinder[drive] == 0) BX_FD_THIS s.result[0] |= 0x10;
|
||||
BX_FD_THIS s.result_size = 1;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
if (BX_FD_THIS s.cylinder[drive] == 0) BX_FD_THIS s.status_reg3 |= 0x10;
|
||||
enter_result_phase();
|
||||
return;
|
||||
break;
|
||||
|
||||
@ -651,10 +639,10 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
* controller set to non-busy
|
||||
* error condition noted in Status reg 0's equipment check bit
|
||||
* seek end bit set to 1 in Status reg 0 regardless of outcome
|
||||
* The last two are taken care of in timer().
|
||||
*/
|
||||
/* data reg not ready, drive busy */
|
||||
BX_FD_THIS s.cylinder[drive] = 0;
|
||||
BX_FD_THIS s.main_status_reg = (1 << drive);
|
||||
BX_FD_THIS s.pending_command = 0x07; // recalibrate pending
|
||||
return;
|
||||
break;
|
||||
|
||||
@ -669,7 +657,6 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
drive = BX_FD_THIS s.DOR & 0x03;
|
||||
if (!BX_FD_THIS s.pending_irq) {
|
||||
BX_FD_THIS s.status_reg0 = 0x80;
|
||||
BX_FD_THIS s.result_size = 1;
|
||||
}
|
||||
else {
|
||||
if (BX_FD_THIS s.reset_sensei > 0) {
|
||||
@ -677,17 +664,11 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
BX_FD_THIS s.status_reg0 &= 0xf8;
|
||||
BX_FD_THIS s.status_reg0 |= (BX_FD_THIS s.head[drive] << 2) | drive;
|
||||
BX_FD_THIS s.reset_sensei--;
|
||||
}
|
||||
BX_FD_THIS s.result[1] = BX_FD_THIS s.cylinder[drive];
|
||||
BX_FD_THIS s.result_size = 2;
|
||||
}
|
||||
}
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
|
||||
/* read ready */
|
||||
BX_FD_THIS s.main_status_reg &= 0x0f;
|
||||
BX_FD_THIS s.main_status_reg |= (FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY);
|
||||
BX_DEBUG(("sense interrupt status"));
|
||||
enter_result_phase();
|
||||
return;
|
||||
break;
|
||||
|
||||
@ -712,7 +693,6 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
bx_options.Ofloppy_command_delay->get (), 0 );
|
||||
/* data reg not ready, drive busy */
|
||||
BX_FD_THIS s.main_status_reg = (1 << drive);
|
||||
BX_FD_THIS s.pending_command = 0x0f; /* seek pending */
|
||||
return;
|
||||
break;
|
||||
|
||||
@ -722,10 +702,7 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
BX_DEBUG(("configure (no poll = 0x%02x)", BX_FD_THIS s.command[2] & 0x10 ));
|
||||
BX_DEBUG(("configure (fifothr = 0x%02x)", BX_FD_THIS s.command[2] & 0x0f ));
|
||||
BX_DEBUG(("configure (pretrk = 0x%02x)", BX_FD_THIS s.command[3] ));
|
||||
BX_FD_THIS s.result_size = 0;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_BUSY;
|
||||
enter_idle_phase();
|
||||
return;
|
||||
break;
|
||||
|
||||
@ -743,20 +720,11 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
}
|
||||
if (BX_FD_THIS s.device_type[drive] == BX_FLOPPY_NONE)
|
||||
BX_PANIC(("floppy_command(): read ID: bad drive #%d", drive));
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
// setting result[0] in timer handler
|
||||
BX_FD_THIS s.result[1] = BX_FD_THIS s.status_reg1;
|
||||
BX_FD_THIS s.result[2] = BX_FD_THIS s.status_reg2;
|
||||
BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
|
||||
BX_FD_THIS s.result[4] = BX_FD_THIS s.head[drive];
|
||||
BX_FD_THIS s.result[5] = 1; /* sector at completion */
|
||||
BX_FD_THIS s.result[6] = 2; /* sector size code */
|
||||
BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive]<<2) | drive;
|
||||
bx_pc_system.activate_timer( BX_FD_THIS s.floppy_timer_index,
|
||||
bx_options.Ofloppy_command_delay->get (), 0 );
|
||||
/* data reg not ready, controller busy */
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
BX_FD_THIS s.pending_command = 0x4a; /* read ID pending */
|
||||
return;
|
||||
break;
|
||||
|
||||
@ -784,31 +752,19 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
if ( BX_FD_THIS s.media_present[drive] == 0 ) {
|
||||
// media not in drive, return error
|
||||
BX_INFO(("attempt to format track with media not present"));
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = 0x25; // 0010 0101
|
||||
BX_FD_THIS s.result[2] = 0x31; // 0011 0001
|
||||
// 4 result bytes are unused
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
raise_interrupt();
|
||||
BX_FD_THIS s.status_reg1 = 0x25; // 0010 0101
|
||||
BX_FD_THIS s.status_reg2 = 0x31; // 0011 0001
|
||||
enter_result_phase();
|
||||
return;
|
||||
}
|
||||
if (BX_FD_THIS s.media[drive].write_protected) {
|
||||
// media write-protected, return error
|
||||
BX_INFO(("attempt to format track with media write-protected"));
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = 0x27; // 0010 0111
|
||||
BX_FD_THIS s.result[2] = 0x31; // 0011 0001
|
||||
// 4 result bytes are unused
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
raise_interrupt();
|
||||
BX_FD_THIS s.status_reg1 = 0x27; // 0010 0111
|
||||
BX_FD_THIS s.status_reg2 = 0x31; // 0011 0001
|
||||
enter_result_phase();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -819,7 +775,6 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
|
||||
/* data reg not ready, controller busy */
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
BX_FD_THIS s.pending_command = 0x4d; /* format track pending */
|
||||
BX_DEBUG(("format track"));
|
||||
return;
|
||||
break;
|
||||
@ -862,20 +817,10 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
// read input error checking).
|
||||
if (head != ((BX_FD_THIS s.command[1]>>2)&1)) {
|
||||
BX_ERROR(("head number in command[1] doesn't match head field"));
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = 0x04; // 0000 0100
|
||||
BX_FD_THIS s.result[2] = 0x00; // 0000 0000
|
||||
BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
|
||||
BX_FD_THIS s.result[4] = BX_FD_THIS s.head[drive];
|
||||
BX_FD_THIS s.result[5] = BX_FD_THIS s.sector[drive];
|
||||
BX_FD_THIS s.result[6] = 2; // sector size = 512
|
||||
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
raise_interrupt();
|
||||
BX_FD_THIS s.status_reg1 = 0x04; // 0000 0100
|
||||
BX_FD_THIS s.status_reg2 = 0x00; // 0000 0000
|
||||
enter_result_phase();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -885,20 +830,10 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
BX_INFO(("attempt to read/write sector %u,"
|
||||
" sectors/track=%u", (unsigned) sector,
|
||||
(unsigned) BX_FD_THIS s.media[drive].sectors_per_track));
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive; // abnormal termination
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = 0x25; // 0010 0101
|
||||
BX_FD_THIS s.result[2] = 0x31; // 0011 0001
|
||||
BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
|
||||
BX_FD_THIS s.result[4] = BX_FD_THIS s.head[drive];
|
||||
BX_FD_THIS s.result[5] = BX_FD_THIS s.sector[drive];
|
||||
BX_FD_THIS s.result[6] = 2; // sector size = 512
|
||||
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
raise_interrupt();
|
||||
BX_FD_THIS s.status_reg1 = 0x25; // 0010 0101
|
||||
BX_FD_THIS s.status_reg2 = 0x31; // 0011 0001
|
||||
enter_result_phase();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -906,9 +841,9 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
BX_PANIC(("sector_size not 512"));
|
||||
}
|
||||
if ( cylinder >= BX_FD_THIS s.media[drive].tracks ) {
|
||||
BX_PANIC(("io: norm r/w parms out of range: sec#%02xh cyl#%02xh eot#%02xh head#%02xh",
|
||||
(unsigned) sector, (unsigned) cylinder, (unsigned) eot,
|
||||
(unsigned) head));
|
||||
BX_PANIC(("io: norm r/w parms out of range: sec#%02xh cyl#%02xh eot#%02xh head#%02xh",
|
||||
(unsigned) sector, (unsigned) cylinder, (unsigned) eot,
|
||||
(unsigned) head));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -923,34 +858,20 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
BX_FD_THIS s.head[drive] = head;
|
||||
BX_FD_THIS s.sector[drive] = BX_FD_THIS s.media[drive].sectors_per_track;
|
||||
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
// 0100 0HDD abnormal termination
|
||||
BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive;
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
// 1000 0101 end of cyl/NDAT/NID
|
||||
BX_FD_THIS s.result[1] = 0x85;
|
||||
BX_FD_THIS s.status_reg1 = 0x85;
|
||||
// 0000 0000
|
||||
BX_FD_THIS s.result[2] = 0x00;
|
||||
BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
|
||||
BX_FD_THIS s.result[4] = BX_FD_THIS s.head[drive];
|
||||
BX_FD_THIS s.result[5] = BX_FD_THIS s.sector[drive];
|
||||
BX_FD_THIS s.result[6] = 2; // sector size = 512
|
||||
BX_FD_THIS s.status_reg2 = 0x00;
|
||||
|
||||
bx_pc_system.activate_timer( BX_FD_THIS s.floppy_timer_index,
|
||||
bx_options.Ofloppy_command_delay->get (), 0 );
|
||||
/* data reg not ready, controller busy */
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
BX_FD_THIS s.pending_command = BX_FD_THIS s.command[0];
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (eot != BX_FD_THIS s.media[drive].sectors_per_track)
|
||||
BX_DEBUG(("io: bad eot #%02xh", (unsigned) eot));
|
||||
#endif
|
||||
|
||||
if (cylinder != BX_FD_THIS s.cylinder[drive])
|
||||
BX_DEBUG(("io: cylinder request != current cylinder"));
|
||||
|
||||
@ -969,23 +890,19 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
if ((BX_FD_THIS s.command[0] & 0x4f) == 0x46) { // read
|
||||
floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer,
|
||||
512, FROM_FLOPPY);
|
||||
BX_FD_THIS s.floppy_buffer_index = 0;
|
||||
|
||||
DEV_dma_set_drq(FLOPPY_DMA_CHAN, 1);
|
||||
|
||||
/* data reg not ready, controller busy */
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
BX_FD_THIS s.pending_command = BX_FD_THIS s.command[0];
|
||||
return;
|
||||
}
|
||||
else if ((BX_FD_THIS s.command[0] & 0x7f) == 0x45) { // write
|
||||
BX_FD_THIS s.floppy_buffer_index = 0;
|
||||
|
||||
DEV_dma_set_drq(FLOPPY_DMA_CHAN, 1);
|
||||
|
||||
/* data reg not ready, controller busy */
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_BUSY;
|
||||
BX_FD_THIS s.pending_command = BX_FD_THIS s.command[0];
|
||||
return;
|
||||
}
|
||||
else
|
||||
@ -994,12 +911,9 @@ bx_floppy_ctrl_c::floppy_command(void)
|
||||
return;
|
||||
break;
|
||||
|
||||
default: // invalid or unsupported command
|
||||
BX_FD_THIS s.result_size = 1;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.status_reg0 = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
default: // invalid or unsupported command; these are captured in write() above
|
||||
BX_PANIC(("You should never get here! cmd = 0x%02x",
|
||||
BX_FD_THIS s.command[0]));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1084,27 +998,7 @@ bx_floppy_ctrl_c::timer()
|
||||
drive = BX_FD_THIS s.DOR & 0x03;
|
||||
switch ( BX_FD_THIS s.pending_command ) {
|
||||
case 0x07: // recal
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
/* write ready, not busy */
|
||||
BX_FD_THIS s.cylinder[drive] = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | (1 << drive);
|
||||
BX_FD_THIS s.status_reg0 = 0x20 | (BX_FD_THIS s.head[drive]<<2) | drive;
|
||||
if (BX_FD_THIS s.device_type[drive] == BX_FLOPPY_NONE) {
|
||||
BX_FD_THIS s.status_reg0 |= 0x50;
|
||||
}
|
||||
else if (BX_FD_THIS s.media_present[drive] == 0) {
|
||||
BX_FD_THIS s.status_reg0 |= 0x40;
|
||||
BX_FD_THIS s.status_reg1 = 0x25;
|
||||
BX_FD_THIS s.status_reg2 = 0x31;
|
||||
}
|
||||
raise_interrupt();
|
||||
goto reset_changeline;
|
||||
break;
|
||||
|
||||
case 0x0f: // seek
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
/* write ready, not busy */
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | (1 << drive);
|
||||
BX_FD_THIS s.status_reg0 = 0x20 | (BX_FD_THIS s.head[drive]<<2) | drive;
|
||||
if (BX_FD_THIS s.device_type[drive] == BX_FLOPPY_NONE) {
|
||||
BX_FD_THIS s.status_reg0 |= 0x50;
|
||||
@ -1114,29 +1008,18 @@ bx_floppy_ctrl_c::timer()
|
||||
BX_FD_THIS s.status_reg1 = 0x25;
|
||||
BX_FD_THIS s.status_reg2 = 0x31;
|
||||
}
|
||||
|
||||
/* reset changeline */
|
||||
if (drive > 1) return;
|
||||
if (BX_FD_THIS s.media_present[drive])
|
||||
BX_FD_THIS s.DIR[drive] &= ~0x80; // clear disk change line
|
||||
|
||||
enter_idle_phase();
|
||||
raise_interrupt();
|
||||
goto reset_changeline;
|
||||
break;
|
||||
|
||||
case 0x4a: /* read ID */
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
/* read ready, busy */
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO;
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
raise_interrupt();
|
||||
break;
|
||||
|
||||
case 0x46: // read normal data
|
||||
case 0x66:
|
||||
case 0xc6:
|
||||
case 0xe6:
|
||||
case 0x45: // write normal data
|
||||
case 0xc5:
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
/* read ready, busy */
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY | (1 << drive);
|
||||
BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive]<<2) | drive;
|
||||
raise_interrupt();
|
||||
enter_result_phase();
|
||||
break;
|
||||
|
||||
case 0xfe: // (contrived) RESET
|
||||
@ -1155,11 +1038,6 @@ bx_floppy_ctrl_c::timer()
|
||||
(unsigned) BX_FD_THIS s.pending_command));
|
||||
}
|
||||
return;
|
||||
|
||||
reset_changeline:
|
||||
if (drive > 1) return;
|
||||
if (BX_FD_THIS s.media_present[drive])
|
||||
BX_FD_THIS s.DIR[drive] &= ~0x80; // clear disk change line
|
||||
}
|
||||
|
||||
void
|
||||
@ -1179,18 +1057,9 @@ bx_floppy_ctrl_c::dma_write(Bit8u *data_byte)
|
||||
increment_sector(); // increment to next sector before retrieving next one
|
||||
BX_FD_THIS s.floppy_buffer_index = 0;
|
||||
if (DEV_dma_get_tc()) { // Terminal Count line, done
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY | (1 << drive);
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive] << 2) | drive;
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = 0;
|
||||
BX_FD_THIS s.result[2] = 0;
|
||||
BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
|
||||
BX_FD_THIS s.result[4] = BX_FD_THIS s.head[drive];
|
||||
BX_FD_THIS s.result[5] = BX_FD_THIS s.sector[drive];
|
||||
BX_FD_THIS s.result[6] = 2;
|
||||
BX_FD_THIS s.status_reg1 = 0;
|
||||
BX_FD_THIS s.status_reg2 = 0;
|
||||
|
||||
if (bx_dbg.floppy) {
|
||||
BX_INFO(("<<READ DONE>>"));
|
||||
@ -1201,8 +1070,8 @@ bx_floppy_ctrl_c::dma_write(Bit8u *data_byte)
|
||||
BX_INFO((" sector = %u", (unsigned) BX_FD_THIS s.sector[drive]));
|
||||
}
|
||||
|
||||
raise_interrupt();
|
||||
DEV_dma_set_drq(FLOPPY_DMA_CHAN, 0);
|
||||
enter_result_phase();
|
||||
}
|
||||
else { // more data to transfer
|
||||
Bit32u logical_sector;
|
||||
@ -1258,17 +1127,9 @@ bx_floppy_ctrl_c::dma_read(Bit8u *data_byte)
|
||||
}
|
||||
if ((BX_FD_THIS s.format_count == 0) || (DEV_dma_get_tc())) {
|
||||
BX_FD_THIS s.format_count = 0;
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY | (1 << drive);
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive] << 2) | drive;
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = BX_FD_THIS s.status_reg1;
|
||||
BX_FD_THIS s.result[2] = BX_FD_THIS s.status_reg2;
|
||||
// 4 result bytes are unused
|
||||
raise_interrupt();
|
||||
DEV_dma_set_drq(FLOPPY_DMA_CHAN, 0);
|
||||
enter_result_phase();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1282,22 +1143,13 @@ bx_floppy_ctrl_c::dma_read(Bit8u *data_byte)
|
||||
if ( BX_FD_THIS s.media[drive].write_protected ) {
|
||||
// write protected error
|
||||
BX_INFO(("tried to write disk %u, which is write-protected", drive));
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
// ST0: IC1,0=01 (abnormal termination: started execution but failed)
|
||||
BX_FD_THIS s.result[0] = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive;
|
||||
BX_FD_THIS s.status_reg0 = 0x40 | (BX_FD_THIS s.head[drive]<<2) | drive;
|
||||
// ST1: DataError=1, NDAT=1, NotWritable=1, NID=1
|
||||
BX_FD_THIS s.result[1] = 0x27; // 0010 0111
|
||||
BX_FD_THIS s.status_reg1 = 0x27; // 0010 0111
|
||||
// ST2: CRCE=1, SERR=1, BCYL=1, NDAM=1.
|
||||
BX_FD_THIS s.result[2] = 0x31; // 0011 0001
|
||||
BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
|
||||
BX_FD_THIS s.result[4] = BX_FD_THIS s.head[drive];
|
||||
BX_FD_THIS s.result[5] = BX_FD_THIS s.sector[drive];
|
||||
BX_FD_THIS s.result[6] = 2; // sector size = 512
|
||||
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY | (1 << drive);
|
||||
raise_interrupt();
|
||||
BX_FD_THIS s.status_reg2 = 0x31; // 0011 0001
|
||||
enter_result_phase();
|
||||
return;
|
||||
}
|
||||
floppy_xfer(drive, logical_sector*512, BX_FD_THIS s.floppy_buffer,
|
||||
@ -1305,18 +1157,10 @@ bx_floppy_ctrl_c::dma_read(Bit8u *data_byte)
|
||||
increment_sector(); // increment to next sector after writing current one
|
||||
BX_FD_THIS s.floppy_buffer_index = 0;
|
||||
if (DEV_dma_get_tc()) { // Terminal Count line, done
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.status_reg0 = (BX_FD_THIS s.head[drive] << 2) | drive;
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = 0;
|
||||
BX_FD_THIS s.result[2] = 0;
|
||||
BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
|
||||
BX_FD_THIS s.result[4] = BX_FD_THIS s.head[drive];
|
||||
BX_FD_THIS s.result[5] = BX_FD_THIS s.sector[drive];
|
||||
BX_FD_THIS s.result[6] = 2;
|
||||
BX_FD_THIS s.status_reg1 = 0;
|
||||
BX_FD_THIS s.status_reg2 = 0;
|
||||
|
||||
if (bx_dbg.floppy) {
|
||||
BX_INFO(("<<WRITE DONE>>"));
|
||||
BX_INFO(("AFTER"));
|
||||
@ -1326,8 +1170,8 @@ bx_floppy_ctrl_c::dma_read(Bit8u *data_byte)
|
||||
BX_INFO((" sector = %u", (unsigned) BX_FD_THIS s.sector[drive]));
|
||||
}
|
||||
|
||||
raise_interrupt();
|
||||
DEV_dma_set_drq(FLOPPY_DMA_CHAN, 0);
|
||||
enter_result_phase();
|
||||
}
|
||||
else { // more data to transfer
|
||||
} // else
|
||||
@ -1475,11 +1319,11 @@ bx_floppy_ctrl_c::evaluate_media(unsigned type, char *path, floppy_t *media)
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
if ( (path[1] == ':') && (strlen(path) == 2) ) {
|
||||
wsprintf(sTemp, "\\\\.\\%s", path);
|
||||
media->fd = open(sTemp, BX_RDWR);
|
||||
} else {
|
||||
media->fd = open(path, BX_RDWR);
|
||||
}
|
||||
wsprintf(sTemp, "\\\\.\\%s", path);
|
||||
media->fd = open(sTemp, BX_RDWR);
|
||||
} else {
|
||||
media->fd = open(path, BX_RDWR);
|
||||
}
|
||||
#else
|
||||
media->fd = open(path, BX_RDWR);
|
||||
#endif
|
||||
@ -1494,11 +1338,11 @@ bx_floppy_ctrl_c::evaluate_media(unsigned type, char *path, floppy_t *media)
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
if ( (path[1] == ':') && (strlen(path) == 2) ) {
|
||||
wsprintf(sTemp, "\\\\.\\%s", path);
|
||||
media->fd = open(sTemp, BX_RDONLY);
|
||||
} else {
|
||||
media->fd = open(path, BX_RDONLY);
|
||||
}
|
||||
wsprintf(sTemp, "\\\\.\\%s", path);
|
||||
media->fd = open(sTemp, BX_RDONLY);
|
||||
} else {
|
||||
media->fd = open(path, BX_RDONLY);
|
||||
}
|
||||
#else
|
||||
media->fd = open(path, BX_RDONLY);
|
||||
#endif
|
||||
@ -1566,11 +1410,11 @@ bx_floppy_ctrl_c::evaluate_media(unsigned type, char *path, floppy_t *media)
|
||||
media->tracks = 80;
|
||||
media->heads = 2;
|
||||
}
|
||||
else if (stat_buf.st_size == 1763328) {
|
||||
else if (stat_buf.st_size == 1763328) {
|
||||
media->sectors_per_track = 21;
|
||||
media->tracks = 82;
|
||||
media->heads = 2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
BX_INFO(("evaluate_media: file '%s' of unknown size %lu",
|
||||
path, (unsigned long) stat_buf.st_size));
|
||||
@ -1643,3 +1487,68 @@ bx_floppy_ctrl_c::evaluate_media(unsigned type, char *path, floppy_t *media)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bx_floppy_ctrl_c::enter_result_phase(void)
|
||||
{
|
||||
|
||||
Bit8u drive;
|
||||
|
||||
drive = BX_FD_THIS s.DOR & 0x03;
|
||||
|
||||
/* these are always the same */
|
||||
BX_FD_THIS s.result_index = 0;
|
||||
BX_FD_THIS s.main_status_reg = FD_MS_MRQ | FD_MS_DIO | FD_MS_BUSY;
|
||||
|
||||
/* invalid command */
|
||||
if ((BX_FD_THIS s.status_reg0 & 0xc0) == 0x80) {
|
||||
BX_FD_THIS s.result_size = 1;
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (BX_FD_THIS s.pending_command) {
|
||||
case 0x04: // get status
|
||||
BX_FD_THIS s.result_size = 1;
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg3;
|
||||
break;
|
||||
case 0x08: // sense interrupt
|
||||
BX_FD_THIS s.result_size = 2;
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = BX_FD_THIS s.cylinder[drive];
|
||||
break;
|
||||
case 0x4a: // read ID
|
||||
case 0x4d: // format track
|
||||
case 0x46: // read normal data
|
||||
case 0x66:
|
||||
case 0xc6:
|
||||
case 0xe6:
|
||||
case 0x45: // write normal data
|
||||
case 0xc5:
|
||||
BX_FD_THIS s.result_size = 7;
|
||||
BX_FD_THIS s.result[0] = BX_FD_THIS s.status_reg0;
|
||||
BX_FD_THIS s.result[1] = BX_FD_THIS s.status_reg1;
|
||||
BX_FD_THIS s.result[2] = BX_FD_THIS s.status_reg2;
|
||||
BX_FD_THIS s.result[3] = BX_FD_THIS s.cylinder[drive];
|
||||
BX_FD_THIS s.result[4] = BX_FD_THIS s.head[drive];
|
||||
BX_FD_THIS s.result[5] = BX_FD_THIS s.sector[drive];
|
||||
BX_FD_THIS s.result[6] = 2; /* sector size code */
|
||||
raise_interrupt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bx_floppy_ctrl_c::enter_idle_phase(void)
|
||||
{
|
||||
BX_FD_THIS s.main_status_reg &= 0x0f; // leave drive status untouched
|
||||
BX_FD_THIS s.main_status_reg |= FD_MS_MRQ; // data register ready
|
||||
|
||||
BX_FD_THIS s.command_complete = 1; /* waiting for new command */
|
||||
BX_FD_THIS s.command_index = 0;
|
||||
BX_FD_THIS s.command_size = 0;
|
||||
BX_FD_THIS s.pending_command = 0;
|
||||
|
||||
BX_FD_THIS s.floppy_buffer_index = 0;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: floppy.h,v 1.15 2002-11-10 10:14:55 vruppert Exp $
|
||||
// $Id: floppy.h,v 1.16 2002-11-30 09:39:29 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2002 MandrakeSoft S.A.
|
||||
@ -127,6 +127,8 @@ private:
|
||||
BX_FD_SMF void floppy_command(void);
|
||||
BX_FD_SMF void floppy_xfer(Bit8u drive, Bit32u offset, Bit8u *buffer, Bit32u bytes, Bit8u direction);
|
||||
BX_FD_SMF void raise_interrupt(void);
|
||||
BX_FD_SMF void enter_idle_phase(void);
|
||||
BX_FD_SMF void enter_result_phase(void);
|
||||
static void timer_handler(void *);
|
||||
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user