Ticket #824 : [solution] check your floppy code.spin the drive down and stop the motor. you are supposed to do this on access, maybe it is the boot code, but it shouldn't invert the drive access routines.THESE I have in Pascal. [thanks to numerous GPL donors]. nevermind the stray characters, they are otherwise invisible. int24 is [at least in dos] a critical IO handler, which for project FPOS is handled in the kernels isr (interrupt service request) routines. MY floppy drive is usb, so I cannot test this code, yet anyway. see below: [I know,in Pascal but translation should prove too difficult...] type drive_type:array[0..5] of string=('no floppy drive', '360kb 5.25in floppy drive', '1.2mb 5.25in floppy drive', '720kb 3.5in', '1.44mb 3.5in', '2.88mb 3.5in' ) end; THardDiskParam = record Cylinders: LongWord; Heads: LongWord; Sectors: LongWord; end; THardDiskPorts = ( Data:=$1F0, Error, { $1F1 } SectorCount, { $1F2 } SectorNumber, { $1F3 } LowCylinder, { $1F4 } HighCylinder, { $1F5 } Head, { $1F6 } Status, { $1F7 } Command { $1F7 } ); THardDiskCommands = ( ReadHD:=$20, WriteHD:=$30 ); JmpRec=record { The starting jump in the bootsector } Code:byte; { $E9 XX XX / $EB XX XX} case byte of 0:(Adr1:byte; NOP:byte); 1:(Adr2:word); end; BpbRec=record { The Bios Data Block (returned by DOS, and stored in } BytesPSec:word; { the bootsector } SecPClus:byte; ResSec:word; NrFATs:byte; NrROOT:word; TotalSec:word; MDB:byte; SecPFAT:word; SecPSpoor:word; NrHead:word; HidSec32:longint; TotalSec32:longint; end; BootSec=record { The bootsector format in DOS } JmpCode:JmpRec; Name:array[0..7] of char; { Isn't meaningfull at all, just FORMAT prg name } Bpb:BpbRec; end; BootSecP=^BootSec; var buf:array [1..512]of byte; ch:char; S:string[1]; { To store driveletter } I:byte; BigPart:boolean; { 32-bit sectors? } Drive:byte; { which drive are we using } ROOTSec,FATSec,DataSec:longint; { Some starting sectors } FAT12:boolean; { 12-bit FAT? } LastSecNo:longint; { Save last sector number... } LastError:word; { ... and error code for error report } MotorState : byte = 0; Ticks : byte; Waiting : boolean; Size : LongWord; {$Align 32} Buffer : array[1..$4800] of byte; regs:tregisters; const SizeBpb=SizeOf(BpbRec); { Needed for assembly part, AFAIK you can't get the size of a structure } { (record) in an asm..end; block (shame on you, Borland (or on me :-) )) } StatusRegA : word = $0000; // Read Only StatusRegB : word = $0001; // Read Only DOReg : word = $0002; TapeDrvReg : word = $0003; MSReg : word = $0004; // Read Only - Main Status Reg FIFOReg : word = $0005; // Write-only DIReg : word = $0007; // Read Only CCReg : word = $0007; // Write-only MotorOnDelay : integer = 50; MotorOffDelay : integer = 300; DMAChan : byte = 2; DMABufLen : word = $4800; 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 Seek(Drive : byte; cyli, head : byte) : byte; function FloppyReset(Drive : byte) : byte; procedure Motor(Drive : byte; State : byte); function FloppyDoTrack(Drive : byte; cyl : byte; dir : byte) : byte; function FloppyDoTrackLBA(Drive : byte; LBA : byte; dir : byte; NoSectors : byte) : byte; procedure detectFloppys; //pulled from C --Jazz var a,b,c:char; begin writeportb($70, $10); c = readportb($71); a := c shr 4; // get the high nibble b := c and $F; // get the low nibble by ANDing out the high nibble write("Floppy drive A is a: "); writeln(drive_type[a]); write("Floppy drive B is a: "); writeln(drive_type[b]); writechar(#10); end; procedure LBA2CHS(LBA:LongWord; var cyl,head,sec : byte); begin sec := (LBA mod 18) + 1; cyl := LBA Div 36; head := (LBA Div 18) mod 2; end; procedure FloppyWriteCmd(Drive : byte; cmd : byte); var base : word; i : integer; begin base := DriveBase[Drive]; repeat Delay(100); until(($C0 and ReadPortb(base + MSReg)) <> $C0); for i := 1 to 300 do begin if (($C0 and ReadPortb(base + MSReg)) = $80) then begin WritePortb((Base + FIFOReg), cmd); Exit; end; Delay(100); end; WriteLn('Floppy drive write command : Timeout'); end; function FloppyReadCmd(Drive : byte) : byte; var base : word; i : integer; begin base := DriveBase[Drive]; repeat Delay(100); until(($C0 and ReadPortb(base + MSReg)) <> $80); for i := 1 to 300 do begin if (($80 and ReadPortb(base + MSReg)) = $80) then begin FloppyReadCmd := ReadPortb(base + FIFOReg); Exit; end; Delay(100); end; WriteLn('Floppy drive read command : Timeout'); FloppyReadCmd := 0; end; procedure IRQwait(no : byte); begin while Waiting = true do end; procedure SenseInt(Drive : byte; var st0, cyl : byte); var base : word; begin base := DriveBase[Drive]; FloppyWriteCmd(Drive, FloppyCmd[7]); Delay(500); 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 WritePortb(base + DOReg, $1C); Delay(MotorOnDelay); MotorState := 1; end else begin if MotorState = 2 then // WriteLn(#10'Floppy Motor: Strange, motor already waiting'); Ticks := 300; Delay(Ticks); MotorState := 2; end; end; if State = 0 then if MotorState = 1 then begin WritePortb(base + DOReg, $0C); MotorState := 0; Delay(MotorOffDelay); end; end; function Calibrate(Drive : byte) : byte; var i, st0, cyl : byte ; s : string; begin st0 := -1; cyl := -1; WriteLn(#10'Calibrating floppy drive...'); Motor(Drive, 1); for i:= 0 to 10 do begin Waiting := True; FloppyWriteCmd(Drive, FloppyCmd[6]); FloppyWriteCmd(Drive, Drive); IrqWait(6); SenseInt(Drive, st0, cyl); if (st0 and $C0) = $C0 then WriteLn(#10'Floppy Calibrate : Status =' + DriveStatus[st0 shr 6]); //Calibration error if cyl = 0 then begin Motor(Drive, 0); Calibrate := 0; WriteLn(#10'Floppy calibration done'); Exit; end; end; WriteLn('Floppy calibrate : Timeout'); Motor(Drive, 0); Calibrate := 1; end; function FloppyReset(Drive : byte) : byte; var base : word; st0, cyl : byte; begin st0 := -1; cyl := -1; Waiting := True; base := DriveBase[Drive]; WritePortb(base + DOReg, $00); WritePortb(base + DOReg, $0C); IrqWait(6); SenseInt(Drive, st0, cyl); //Set transfer speed WritePortb(base + CCReg, $00); FloppyWriteCmd(Drive, FloppyCmd[2]); FloppyWriteCmd(Drive, $DF); FloppyWriteCmd(Drive, $02); if Calibrate(Drive) = 1 then FloppyReset := 1 else FloppyReset := 0; end; function Seek(Drive : byte; cyli, head : byte):byte; //floppy seek var st0, cyl, i : byte; s : string; begin st0 := -1; cyl := -1; Motor(Drive, 1); for i := 0 to 10 do begin Waiting := True; FloppyWriteCmd(Drive, FloppyCmd[12]); FloppyWriteCmd(Drive, (head shl 2)); FloppyWriteCmd(Drive, cyli); IRQWait(6); SenseInt(Drive, st0, cyl); if (st0 and $C0) = $C0 then WriteLn(#10'Floppy Seek: Status = ' + DriveStatus[st0 shr 6]); //Calibration error if cyl = cyli then begin Motor(Drive,0); //WriteLn(#10'Cylinder Found'); ok, we found it, read or write it. Seek := 0; Exit; end; end; Seek := -1; Motor(Drive, 0); WriteLn('Floppy Seek : Timeout'); end; procedure FloppyDMAInit(dir : byte; Size : LongWord); var Addr, Count : Longword; mode : byte; begin Addr := PtrUInt(@Buffer); Count := Size - 1; //enable DMA 2 //and setup buffer of 512 byte. if (Addr and $ff000000) or (Count and $ffff0000) or ((Addr + Count) and $ffff0000) <> (Addr and $ffff0000) then WriteLn('Floppy DMA: Static buffer problem'); //tells where to assign the buffer... mode := $40; mode := mode or $02; case dir of 1 : mode := mode or $04; //Read to mem 2 : mode := mode or $08; //Write from mem end; WritePortb($0A,$06); //Mask DMA 2 WritePortb($0C,$FF); //Reset Flip-Flop WritePortb($04,(Addr and $000000FF)); //Address Low byte WritePortb($04,((Addr shr 8) and $000000FF)); //Address High byte WritePortb($81,((Addr shr 16) and $000000FF)); //External Page Register WritePortb($0C,$FF); //Reset Flip-Flop WritePortb($05,(Count and $000000FF)); //Count low byte WritePortb($05,((Count shr 8) and $000000FF)); //Count High byte WritePortb($0B,Mode); //Set Mode -see above WritePortb($0A,$02); //Unmask DMA 2 end; function FloppyDoTrackLBA(Drive : byte; LBA : byte; dir : byte; NoSectors : byte) : byte; var cmd, i, st0, st1, st2, rcy, rhe, rse, bps, error : byte; cyl, head, sec : byte; begin error := 0; case dir of 1 : cmd := FloppyCmd[5] or $C0; //Read 2 : cmd := FloppyCmd[4] or $C0; //Write end; LBA2CHS(LBA, cyl, head, sec); Size := NoSectors * 512; if (Seek(Drive, cyl, head)) = -1 then begin FloppyDoTrackLBA := -1; Exit; end; for i := 1 to 20 do begin Motor(Drive, 1); FloppyDMAInit(dir, Size); Delay(100); FloppyWriteCmd(Drive, cmd); FloppyWriteCmd(Drive, ((head shl 2) or Drive)); FloppyWriteCmd(Drive, cyl); FloppyWriteCmd(Drive, head); FloppyWriteCmd(Drive, sec); FloppyWriteCmd(Drive, 2); FloppyWriteCmd(Drive, 0); FloppyWriteCmd(Drive, 0); FloppyWriteCmd(Drive, $FF); IRQWait(6); st0 := FloppyReadCmd(Drive); st1 := FloppyReadCmd(Drive); st2 := FloppyReadCmd(Drive); //Read Cylinder, Head, Sector rcy := FloppyReadCmd(Drive); rhe := FloppyReadCmd(Drive); rse := FloppyReadCmd(Drive); bps := FloppyReadCmd(Drive); if error = 0 then begin Motor(Drive, 0); FloppyDoTrackLBA := 0; Exit; end; if error >= 1 then begin Motor(Drive, 0); FloppyDoTrackLBA := -2; asm int 24h //trip the handler for critical Disk I/O end; error:=0; FloppyDoTrack:=0; Exit; end; end; WriteLn(#10'Floppy Read Write Timeout'); Motor(Drive, 0); FloppyDoTrackLBA := -1; end; function FloppyDoTrack(Drive : byte; cyl : byte; dir : byte) : byte; var cmd, i, st0, st1, st2, rcy, rhe, rse, bps, error : byte; begin error := 0; case dir of 1 : cmd := FloppyCmd[5] or $C0; //Read 2 : cmd := FloppyCmd[4] or $C0; //Write end; Size := DMABufLen; if (Seek(Drive, cyl, 0)) or (Seek(Drive, cyl, 1)) = -1 then begin FloppyDoTrack := -1; Exit; end; for i := 1 to 20 do begin Motor(Drive, 1); FloppyDMAInit(dir, Size); Delay(100); FloppyWriteCmd(Drive, cmd); FloppyWriteCmd(Drive, 0); FloppyWriteCmd(Drive, cyl); FloppyWriteCmd(Drive, 0); FloppyWriteCmd(Drive, 1); FloppyWriteCmd(Drive, 2); FloppyWriteCmd(Drive, 18); FloppyWriteCmd(Drive, $1B); FloppyWriteCmd(Drive, $FF); IRQWait(6); st0 := FloppyReadCmd(Drive); st1 := FloppyReadCmd(Drive); st2 := FloppyReadCmd(Drive); //Read Cylinder, Head, Sector rcy := FloppyReadCmd(Drive); rhe := FloppyReadCmd(Drive); rse := FloppyReadCmd(Drive); bps := FloppyReadCmd(Drive); if error = 0 then begin Motor(Drive, 0); FloppyDoTrack := 0; Exit; end; if error >= 1 then begin Motor(Drive, 0); FloppyDoTrack := -2 asm int 24h //trip the handler for critical Disk I/O end; error:=0; FloppyDoTrack:=0; Exit; end; end; WriteLn(#10'Floppy Read /Write Timeout'); Motor(Drive, 0); FloppyDoTrack := -1; end; function FloppyRead(Drive : byte; Data : byte; LBA : boolean; NoSec : byte) : byte; begin if LBA = false then FloppyRead := FloppyDoTrack(Drive, Data, 1); if LBA = true then FloppyRead := FloppyDoTrackLBA(Drive, Data, 1, NoSec); end; function FloppyWrite(Drive : byte; Data : byte; LBA : boolean; NoSec : byte) : byte; begin if LBA = false then FloppyWrite := FloppyDoTrack(Drive, Data, 2); if LBA = true then FloppyWrite := FloppyDoTrackLBA(Drive, Data, 2, NoSec); end; procedure initFloppy; var s : string; b : Byte; begin WriteLn(#10'Locating floppy drives...'); DetectDrives; WriteLn(#10'Installing floppy driver'); FloppyReset(0); WriteLn(#10'Floppy driver install done'); end; --------- On Thu, 2009-05-07 at 19:05 -0700, pete.goodeve@xxxxxxxxxxxx wrote: > On Mon, May 04, 2009 at 01:16:20PM +0200, Ingo Weinhold wrote: > > > > > [...on changing script recognition] To me, it looks fine, but I have only > > > a dim grasp of what I'm looking at. > > > > So do I. In r30626 I changed it accordingly anyway. ;-) > > > I got rather sidetracked for a while there, but I can now happily report > that, with Ingo's fix and the required Haiku directory changes, xicon > now works a treat! > > Thanks Ingo...! > -- Pete -- > >