📄 ide.c
字号:
//----------------------------------------------------------------------------
// IDE 19960417 CHG
// Small and simple interface for an "standard" IDE Harddisk connected
// to a 8051 cpu, in this case a DS5000, but all other 8051 compatible
// cpu could be used, as long as they have some external RAM, 1KByte or so
//
// This code is provided as is, with NO responsibility by the author !
// ie. this is use on your own risk !!!!!
//
// Code is free to use, the only request i have is, that if you do some
// enhancements, discoveries I would appreciate to get a copy/info on what
// YOU have done !
// That way, we can all help each other with code etc etc etc.
//
// Made by
// Carsten Groen, OZ9AAR
// Kaervaenget 46, Gl. Sole
// DK-8722 Hedensted
// Denmark
// email: cgroen@image.dk
//
//----------------------------------------------------------------------------
#include <reg5000.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
//----------------------------------------------------------------------------
// Constants...
//----------------------------------------------------------------------------
#define TRUE 1
#define FALSE 0
#define CTRL 0
#define CMD 1
#define DRIVE0 0
//----------------------------------------------------------------------------
// Types
//----------------------------------------------------------------------------
typedef struct {
unsigned char Heads;
unsigned int Tracks;
unsigned int SectorsPerTrack;
char Model[41];
} tdefDriveInfo;
//----------------------------------------------------------------------------
// I/O definitions...
// The IDE harddisk is just connected DIRECTLY to these I/O ports on the 8051
// See pin numbers on IDC connecter on IDE drive in one of the attached files.
// REMEMBER to make a pullup on the P0 port (ex 4.7 K to vcc from each of the
// 8 P0 pins
//----------------------------------------------------------------------------
#define nCS1FX P00
#define nCS3FX P01
#define DA0 P02
#define DA1 P03
#define DA2 P04
#define nDASP P05
#define LSBDATA P1
#define MSBDATA P2
#define nDIOR P06
#define nDIOW P07
#define INTRQ P32
#define IORDY P33
#define RESET P34
#define ALLINPUT 0xFF
//----------------------------------------------------------------------------
// Variables...
//----------------------------------------------------------------------------
unsigned int Timer10mSec=0; // General timer, tick is 10 mSec
unsigned char SectorBuffer[512];
//----------------------------------------------------------------------------
// Wait for a specific time in 10 mSec
// Based on a 11.0592 Mhz crystal
//----------------------------------------------------------------------------
void Delay(unsigned char t) {
unsigned int i;
if (t==0) return;
while (t--) for(i=0;i<774; i++);
}
//----------------------------------------------------------------------------
// Dump a buffer as a hex listing
//----------------------------------------------------------------------------
void HexDump( void *Dataa, int Len ) {
unsigned char *Data=Dataa;
unsigned char Line[80], *CurLine, *CurData;
int linelen, j;
unsigned short rc;
unsigned char tmp;
printf( "*************** HEX-DUMP ***************\n" );
while( Len ){
linelen = Len < 16 ? Len : 16;
*Line='\0';
CurLine = Line;
for( CurData=Data, j=0; j<linelen; j++ ) {
tmp=*CurData;
sprintf( CurLine, "%02BX ", tmp);
CurLine+=3; CurData++;
}
for( j=linelen; j<17; j++ ) {
*CurLine =' ';
CurLine[1]=' ';
CurLine[2]=' ';
CurLine+=3;
}
for( j=0; j<linelen; j++ ) {
sprintf( CurLine, "%c ", *Data > ' ' ? *Data : '_' );
Data++;CurLine+=1;
}
printf( Line );
printf("\n");
Len-=linelen;
}
rc = printf( "*************** HEXEND ***************\n" );
}
//----------------------------------------------------------------------------
// Timer 0 interrupt service function
// executes each 10 mSec @ 11.0592 MHz Crystal Clock
//----------------------------------------------------------------------------
timer0() interrupt 1 using 1 {
TH0 = 0xDC; // reload timer again
TL0 = 0x00; // to 10 mSec timeout
TR0 = 1;
if (Timer10mSec) Timer10mSec--;
}
//----------------------------------------------------------------------------
// Show state of nDASP, INTRQ and IORDY signals
//----------------------------------------------------------------------------
void ShowInputs(void) {
printf("Signals from Drive: nDASP=%s, INTRQ=%s, IORDY=%s\n",
nDASP ? "FALSE":"TRUE", INTRQ ? "TRUE":"FALSE", IORDY ? "TRUE":"FALSE");
}
//----------------------------------------------------------------------------
// Select address and CS signals
//----------------------------------------------------------------------------
void SetAddress(unsigned char cs, unsigned char adr) {
DA0=((adr & 0x01)==0x01);
DA1=((adr & 0x02)==0x02);
DA2=((adr & 0x04)==0x04);
if (cs==CTRL) {
nCS1FX=1;
nCS3FX=0;
} else {
nCS1FX=0;
nCS3FX=1;
}
}
//----------------------------------------------------------------------------
// Read data WORD from Drive
//----------------------------------------------------------------------------
unsigned int ReadWORD(unsigned char cs, unsigned char adr) {
unsigned int tmp;
MSBDATA=ALLINPUT;
LSBDATA=ALLINPUT;
SetAddress(cs,adr);
nDIOR=0;
tmp=(MSBDATA<<8)+LSBDATA;
nDIOR=1;
nCS1FX=1;
nCS3FX=1;
return tmp;
}
//----------------------------------------------------------------------------
// Read data BYTE from Drive
//----------------------------------------------------------------------------
unsigned char ReadBYTE(unsigned char cs, unsigned char adr) {
unsigned char tmp;
MSBDATA=ALLINPUT;
LSBDATA=ALLINPUT;
SetAddress(cs,adr);
nDIOR=0;
tmp=LSBDATA;
nDIOR=1;
nCS1FX=1;
nCS3FX=1;
return tmp;
}
//----------------------------------------------------------------------------
// Write data WORD to Drive
//----------------------------------------------------------------------------
void WriteWORD(unsigned char cs, unsigned char adr, unsigned int dat) {
SetAddress(cs,adr);
// OBS MSB/LSB is swapped (see writeSector function)
MSBDATA=dat;
LSBDATA=(dat>>8);
nDIOW=0;
nDIOW=1;
nCS1FX=1;
nCS3FX=1;
}
//----------------------------------------------------------------------------
// Write data BYTE to Drive
//----------------------------------------------------------------------------
void WriteBYTE(unsigned char cs, unsigned char adr, unsigned char dat) {
SetAddress(cs,adr);
MSBDATA=0;
LSBDATA=dat;
nDIOW=0;
nDIOW=1;
nCS1FX=1;
nCS3FX=1;
}
//----------------------------------------------------------------------------
// Send Identify Command to Drive, and fetch resulting data
//----------------------------------------------------------------------------
unsigned char IdentifyDrive(bit DriveNo, unsigned char *Buffer,
tdefDriveInfo *DriveInfo) {
unsigned int i;
unsigned char Tmp;
WriteBYTE(CMD, 6, 0xA0 + (DriveNo ? 0x10:0x00)); // Select drive
WriteBYTE(CMD, 1, 0);
WriteBYTE(CMD, 2, 1);
WriteBYTE(CMD, 3, 1);
WriteBYTE(CMD, 4, 0);
WriteBYTE(CMD, 5, 0);
WriteBYTE(CMD, 7, 0xEC);
Timer10mSec=10000;
while ((ReadBYTE(CMD,7) & 0x08)!=0x08 && Timer10mSec); // Wait for DRQ or timeout
if (Timer10mSec==0) return 0xFF;
// Fetch the data...
MSBDATA=ALLINPUT;
LSBDATA=ALLINPUT;
// Select address and activate CS
SetAddress(CMD, 0);
// Two bytes at a time
for (i=0; i<512; i+=2) {
nDIOR=0;
*(Buffer+i)=LSBDATA;
*(Buffer+i+1)=MSBDATA;
nDIOR=1;
}
// Disable CS
nCS1FX=1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -