Bochs and stupid Floppy Driver

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Bochs and stupid Floppy Driver

Post 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.
Gizmic OS
Currently - Busy with FAT12 driver and VFS
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Re: Bochs and stupid Floppy Driver

Post 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
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: Bochs and stupid Floppy Driver

Post by System123 »

Im using 500ms on spin up and 500ms spin down. Is that enough
Gizmic OS
Currently - Busy with FAT12 driver and VFS
User avatar
xyjamepa
Member
Member
Posts: 397
Joined: Fri Sep 29, 2006 8:59 am

Re: Bochs and stupid Floppy Driver

Post by xyjamepa »

It should be enough,but try to make it 1000
The man who follows the crowd will usually get no further than the crowd.
The man who walks alone is likely to find himself in places
no one has ever been before.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Bochs and stupid Floppy Driver

Post 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.
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: Bochs and stupid Floppy Driver

Post by System123 »

That won't work as the driver works correctly on an emulator.
Gizmic OS
Currently - Busy with FAT12 driver and VFS
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Bochs and stupid Floppy Driver

Post 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:

Code: Select all

DEBUG_PRINT("here we are!");
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.
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: Bochs and stupid Floppy Driver

Post by System123 »

Ok thanks. Sorry i misunderstood what you meant the first time
Gizmic OS
Currently - Busy with FAT12 driver and VFS
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: Bochs and stupid Floppy Driver

Post 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.
Gizmic OS
Currently - Busy with FAT12 driver and VFS
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Re: Bochs and stupid Floppy Driver

Post by pcmattman »

Code: Select all

//IRQWaiting := false;
PrintString(#10'Floppy IRQ Fired Correctly');
Why's IRQWaiting := false commented out?
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: Bochs and stupid Floppy Driver

Post 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.
Gizmic OS
Currently - Busy with FAT12 driver and VFS
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: Bochs and stupid Floppy Driver

Post by System123 »

Can anyone see any problems in my code?
Gizmic OS
Currently - Busy with FAT12 driver and VFS
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Re: Bochs and stupid Floppy Driver

Post 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. :P
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
System123
Member
Member
Posts: 196
Joined: Mon Jul 07, 2008 1:25 am

Re: Bochs and stupid Floppy Driver

Post 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
Gizmic OS
Currently - Busy with FAT12 driver and VFS
Post Reply