on bochs it works perfectly, but on vpc it doesn't write anything but also don't say it got an error, yet on my real pc it gets an error(and tells you)
this is my condensed code:
Code: Select all
unsigned char FDD_GetByte(){
FDD_ReadyGet();
return inportb(DATA_REG);
}
unsigned char FDD_SendByte(unsigned char data){
unsigned char tmp;
tmp=FDD_ReadySend();
outportb(DATA_REG,data);
return tmp;
}
unsigned char FDD_ReadyGet(){
unsigned int delay;
delay=timer_ticks+2000; //2second timeout
while(delay>timer_ticks){
if((inportb(MAIN_STAT)&0xC0)==0xC0){return 1;}
}
return 0;
}
unsigned char FDD_ReadySend(){
unsigned int delay;
delay=timer_ticks+2000; //2second timeout
while(delay>timer_ticks){
if((inportb(MAIN_STAT)&0xC0)==0x80){return 1;}
}
return 0;
}
unsigned char WriteSector_01(unsigned char drive,unsigned char sector,unsigned char track,unsigned char head, unsigned char *buffer){ //used for error checking
unsigned int i;
unsigned char error;
for(i=0;i<4;i++){
error=_WriteSector_01(drive,sector,track,head,buffer);
if(error==1){return 1;}
//recalibrate
}
return error;
}
unsigned char _WriteSector_01(unsigned char drive,unsigned char sector,unsigned char track,unsigned char head, unsigned char *buffer){ //w00t working mostly
unsigned char ST0,ST1,ST2;
unsigned int delay;
//add diskchange detection and recalibrate if changed
//call this function from another function for error tolerance
FDD_MotorOn(drive);
if(!FDD_SendByte(0x46)){return 0;} //if 1 fails they all fail!
FDD_SendByte((drive&3)|((head&4)<<3));
FDD_SendByte(track);
FDD_SendByte(head);
FDD_SendByte(sector);
FDD_SendByte(0x02); //sector size
FDD_SendByte(18); //track length
FDD_SendByte(27); //GAP3 length
FDD_SendByte(0xFF); //Data length --ignored because of sector size
//now transfer the data!
fdd_int_done=0;
fdd_int_buffer=1024;
memcpy(fdd_int_buffer,buffer,512);
dma_xfer(2,fdd_int_buffer,512,1);
delay=timer_ticks+5000; //2 second time-out
while ((volatile)fdd_int_done<1){
if(delay<timer_ticks){FDD_MotorOff(drive);return 0;} //time-out
}
FDD_MotorOff(drive);
//error checking... blah blah blah
//results phase:
ST0=FDD_GetByte();
ST1=FDD_GetByte();
ST2=FDD_GetByte();
//all this sector id crap is ignored
FDD_GetByte(); //track
FDD_GetByte(); //head
FDD_GetByte(); //sector number
FDD_GetByte(); //sector size
//error checking.....
//for now returns 0 if a drive not ready error or such
//and returns 2 if write protected
if((ST0&0xC0)!=0){return 0;} //interrupt code
if((ST0&16)!=0){return 0;} //unit check
if((ST0&8)!=0){return 0;} //drive not ready
if((ST1&2)!=0){return 2;} //write protected -do not copy for read
if((ST1&16)!=0){return 0;} //time-out
if((ST1&32)!=0){return 0;} //data error
if((ST1&128)!=0){return 0;} //sector number exceeds track
//nothign in ST2
return 1;
}
void FDD_MotorOn(drive){
if(drive==0){
outportb(DOR,0x1C);
}else{
outportb(DOR,0x2D);
}
wait(500);
}
void FDD_MotorOff(drive){
if(drive==0){
outportb(DOR,4);
}else{
outportb(DOR,5);
}
//wait(500);
}