Page 1 of 1
Bochs and stupid Floppy Driver
Posted: Mon Sep 22, 2008 10:58 am
by System123
Hi
I am about half way with my floppy driver now. Everything works fine when I run it in Bochs but as soon as I boot my pc with my disk it gets stuck somewhere loading the floppy driver. What can be the reason for this.
I will post my code if it is needed.
Re: Bochs and stupid Floppy Driver
Posted: Mon Sep 22, 2008 12:53 pm
by AJ
Hi,
Most likely its a timing issue - you need to wait for the drive to spin up and down and need to account for the fact that the FDC is sloooow. What delays are you using?
Cheers,
Adam
Re: Bochs and stupid Floppy Driver
Posted: Mon Sep 22, 2008 11:05 pm
by System123
Im using 500ms on spin up and 500ms spin down. Is that enough
Re: Bochs and stupid Floppy Driver
Posted: Tue Sep 23, 2008 12:26 am
by xyjamepa
It should be enough,but try to make it 1000
Re: Bochs and stupid Floppy Driver
Posted: Wed Sep 24, 2008 2:00 am
by pcmattman
Instead of guessing the timing, I'd venture to suggest putting some debugging output into your driver before testing on a real system. Then you know where it gets stuck. Then if it is timing, you can adjust that rather than guessing and checking.
Re: Bochs and stupid Floppy Driver
Posted: Wed Sep 24, 2008 10:57 am
by System123
That won't work as the driver works correctly on an emulator.
Re: Bochs and stupid Floppy Driver
Posted: Wed Sep 24, 2008 5:14 pm
by pcmattman
If it works correctly on the emulator then the debugging output will help when you run it on a physical computer. You could put something like:
Code: Select all
#ifdef REALPC
#define DEBUG_PRINT write_str
#else
#define DEBUG_PRINT
#endif
And then in your code you simply:
You'd have to adapt it to your OS of course, but it would mean when you test on a real computer you can see where the driver is at and figure out where it's crashing.
Most likely it will be a timing issue, as Bochs does not emulate the timings of the FDC at all. However, the debugging output will still help even if it is a timing issue because you'll know where to fix.
Re: Bochs and stupid Floppy Driver
Posted: Thu Sep 25, 2008 6:48 am
by System123
Ok thanks. Sorry i misunderstood what you meant the first time
Re: Bochs and stupid Floppy Driver
Posted: Thu Sep 25, 2008 11:50 am
by System123
Here is my code. It seems to be getting stuck at an IRQWait in the Calibrate function.
Code: Select all
unit Floppy;
interface
const
StatusRegA : word = $0; // Read Only
StatusRegB : word = $1; // Read Only
DOReg : word = $2;
TapeDrvReg : word = $3;
MSReg : word = $4; // Read Only - Main Status Reg
DataRateReg : word = $5; // Write-only
FIFOReg : word = $6;
DIReg : word = $7; // Read Only
CCReg : word = $7; // Write-only
MotorOnDelay : integer = 200;
MotorOffDelay : integer = 300;
DMAChan : cardinal = 2;
DriveBase : array[0..1] of word = (
$03F0, //DriveA base
$0370 //DriveB base
);
DriveTypes : array[0..7] of string =(
'none',
'360kB 5.25\',
'1.2MB 5.25\',
'720kB 3.5\',
'1.44MB 3.5\',
'2.88MB 3.5\',
'unknown type',
'unknown type'
);
DriveStatus : array[0..3] of string = (
'0','error','invalid','drive');
FloppyCmd : array[1..19] of byte = (
$02, // READ_TRACK 1
$03, // SPECIFY 2
$04, // SENSE_DRIVE_STATUS 3
$05, // WRITE_DATA 4
$06, // READ_DATA 5
$07, // RECALIBRATE 6
$08, // SENSE_INTERRUPT 7
$09, // WRITE_DELETED_DATA 8
$10, // READ_ID 9
$12, // READ_DELETED_DATA 10
$13, // FORMAT_TRACK 11
$15, // SEEK 12
$16, // VERSION 13
$17, // SCAN_EQUAL 14
$18, // PERPENDICULAR_MODE 15
$19, // CONFIGURE 16
$22, // VERIFY 17
$25, // SCAN_LOW_OR_EQUAL 18
$29 // SCAN_HIGH_OR_EQUAL 19
);
procedure initFloppy;
function DetectDrives(DriveNo : byte) : byte;
{procedure FloppyWriteCmd(Drive : byte; cmd : byte);
function FloppyReadCmd(Drive : byte) : byte; }
procedure SenseInt(Drive : byte; var st0, cyl : byte);
function Calibrate(Drive : byte) : byte;
//function FloppyReset(Drive : byte) : byte;
{procedure Motor(Drive : byte; State : byte);}
var
MotorState : byte = 0;
Ticks : byte;
IRQWaiting : boolean = false;
implementation
uses console, ports, pit, irq;
function DetectDrives(DriveNo : byte) : byte;
var
drive : byte;
begin
WritePort($70, $10);
drive := ReadPort($71);
if DriveNo = 0 then
DetectDrives := (drive shr 4);
if DriveNo = 1 then
DetectDrives := (drive and $F);
//Testing Purposes
{PrintString(#10'Floppy Drive 0: ' + DriveTypes[drive shr 4]);
PrintString(#10'Floppy Drive 1: ' + DriveTypes[drive and $F]);}
end;
procedure FloppyHandler(var Reg : TRegisters);
begin
//IRQWaiting := false;
PrintString(#10'Floppy IRQ Fired Correctly');
end;
{procedure IRQWait;
begin
IRQwaiting := true;
while IRQWaiting = true do ;
end; }
procedure FloppyWriteCmd(Drive : byte; cmd : byte);
var
base : word;
i : integer;
begin
base := DriveBase[Drive];
for i := 1 to 600 do
begin
Delay(1);
if (($80 and ReadPort(base + MSReg)) = $80) then
begin
WritePort((Base + FIFOReg), cmd);
Exit;
end;
end;
Panic('Floppy drive write command : Timeout');
end;
function FloppyReadCmd(Drive : byte) : byte;
var
base : word;
i : integer;
begin
base := DriveBase[Drive];
for i := 1 to 600 do
begin
Delay(1);
if (($80 and ReadPort(base + MSReg)) = $80) then
begin
FloppyReadCmd := ReadPort(base + MSReg);
Exit;
end;
end;
Panic('Floppy drive read command : Timeout');
FloppyReadCmd := 0;
end;
procedure SenseInt(Drive : byte; var st0, cyl : byte);
var
base : word;
begin
base := DriveBase[Drive];
FloppyWriteCmd(Drive, FloppyCmd[7]);
st0 := FloppyReadCmd(Drive);
cyl := FloppyReadCmd(Drive);
end;
procedure Motor(Drive : byte; State : byte);
var
base : word;
begin
base := DriveBase[Drive];
// 0 - Off; 1 - On; 2 - Wait
if State = 1 then
begin
// If requested on
if MotorState = 0 then
begin
//Turn motor on
WritePort(base + DOReg, $1C);
Delay(MotorOnDelay);
MotorState := 1;
end
else
begin
if MotorState = 2 then
PrintString(#10'Floppy Motor: Strange, motor already waiting');
Ticks := 300;
MotorState := 2;
end;
end;
if State = 0 then
begin
WritePort(base + DOReg, $0C);
MotorState := 0;
Delay(MotorOffDelay);
end;
end;
function Calibrate(Drive : byte) : byte;
var
i, st0, cyl : byte ;
begin
i := -1;
st0 := -1;
cyl := -1;
Motor(Drive, 1);
for i:= 0 to 10 do
begin
FloppyWriteCmd(Drive, FloppyCmd[6]);
FloppyWriteCmd(Drive, $0);
IrqWait(6);
SenseInt(Drive, st0, cyl);
PrintString(#10'Sense Int Done');
if (st0 and $C0) = $C0 then
PrintString(#10'Floppy Calibrate : ' + DriveStatus[st0 shr 6]); //Calibtation error
if cyl = 0 then
begin
Motor(Drive, 0);
Calibrate := 0;
PrintString(#10'Floppy Calibrate Done');
Exit;
end;
end;
Panic('Floppy clibrate : Timeout');
Motor(Drive, 0);
Calibrate := -1;
end;
function FloppyReset(Drive : byte) : byte;
var
base : word;
st0, cyl : byte;
begin
base := DriveBase[Drive];
WritePort(base + DOReg, $00);
WritePort(base + DOReg, $0C);
IrqWait(6);
SenseInt(Drive, st0, cyl);
//Set transfer speed
WritePort(base + CCReg, $00);
FloppyWriteCmd(Drive, FloppyCmd[2]);
FloppyWriteCmd(Drive, $DF);
FloppyWriteCmd(Drive, $02);
if Calibrate(Drive) = -1 then
FloppyReset := -1
else
FloppyReset := 0;
end;
procedure Seek(Drive : byte; cyli, head : byte);
var
st0, cyl, i : byte;
begin
end;
procedure initFloppy;
var
b : byte;
s : string;
begin
PrintString(#10'Floppy Drive 0: ' + DriveTypes[DetectDrives(0)]);
PrintString(#10'Floppy Drive 1: ' + DriveTypes[DetectDrives(1)]);
InstallIRQHandler(6,@FloppyHandler);
FloppyReset(0);
PrintString('Reset FDD');
end;
end.
Re: Bochs and stupid Floppy Driver
Posted: Thu Sep 25, 2008 10:04 pm
by pcmattman
Code: Select all
//IRQWaiting := false;
PrintString(#10'Floppy IRQ Fired Correctly');
Why's IRQWaiting := false commented out?
Re: Bochs and stupid Floppy Driver
Posted: Fri Sep 26, 2008 11:05 pm
by System123
Ok sorry i forgot to explain i created a new irqwait procedure that is in my irq unit. I did this so i can wait on any interupt and not just one.. The irqwait works fine.
Re: Bochs and stupid Floppy Driver
Posted: Mon Sep 29, 2008 12:16 pm
by System123
Can anyone see any problems in my code?
Re: Bochs and stupid Floppy Driver
Posted: Wed Oct 08, 2008 4:31 am
by mystran
I'm too lazy to try to understand your code, especially as it's some 15 years since I last tried to write Pascal, but I guess you've read and understood the old tutorial I wrote
http://forum.osdev.org/viewtopic.php?t=13538 (linked in our wiki)?
I'm asking, 'cos I personally first understood floppy drives completely wrong, and I still managed to read floppies in Bochs. Turns out, Bochs floppy emulation happens to be written in a way that survives drives that wouldn't have the slightest chance to work on real hardware.
Re: Bochs and stupid Floppy Driver
Posted: Wed Oct 08, 2008 6:57 am
by System123
Yeah that is the tutorial I was following and I followed it in depth. I think I have solved the problem. There was a Page fault that was occuring but due to a small error the kernel panic. never happened