📄 ide_drv_new.c
字号:
/*************************************************************************/
/* */
/* VERSION RELEASE DATE: 02-16-95 */
/* */
/* RTX/PLUS/386 PC WITH */
/* NUCLEUS BIOS */
/* FILE SYSTEM 1.5 */
/* */
/* */
/* HISTORY */
/* */
/* DATE REMARKS */
/* */
/* 12-08-93 Initial version of the Nucleus Single */
/* Board File System. This version was */
/* originally only for the Nucleus PLUS */
/* Single Board version. */
/* */
/* 12-22-93 The File System is updated to run with */
/* either Nucleus RTX Single Board (ver 1.1)*/
/* or Nucleus Plus Single Board (ver 1.1b). */
/* */
/* 03-30-94 Replaced all non-ANSI C comments with */
/* the ANSI C equivalent. */
/* */
/* 07-28-94 Modified the file to work with Watcom. */
/* */
/* 04-01-96 Larry: Changed if(ide_wait_not_busy) */
/* to if(!ide_wait_not_busy) Line 1072 */
/* Relulting in ver 1.5 (spr106) */
/* */
/* 10-17-1997 Mike Trippi ide_wait_not_busy was not handling the */
/* system clock rollover properly. Changed */
/* the local variable to match system clock */
/* size and added code to handle rollover */
/* properly. */
/* */
/*************************************************************************/
/* Contains NUCLEUS Specific Code */
/*
* EBS - RTFS (Real Time File Manager)
*
* Copyright Peter Van Oudenaren , 1993
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*/
/* Portable IDE Device driver.
*
*
*/
//#define PLUS 1
#ifdef PLUS
#include "nucleus.h"
#else
#include "nu_defs.h"
#include "nu_extr.h"
void enable(void);
#endif
#include "pcdisk.h"
#include "miniexec.h"
//以下由张士玉定义
#define inpIDE( portid) *((unsigned short*)(portid))
//#define inport(portid) *((unsigned short *)(portid))
#define outpIDE( portid, value) *((unsigned short *)(portid)) = value
//#define outport(portid, value) *((unsigned short *)(portid)) = value
extern BOOL ReportError(UCOUNT error_code);
BOOL mex_hard_disk_geometry(COUNT driveno, UTINY *heads, UTINY *sectors); /*__fn__*/
//定义到这里为止
//系统自检加入, Liao Yibai 2002-11-26
char HardDiskName[40]={"NO TITLE"};//存放硬盘名称;
/* pseudo modifier. helps us identify optional routines */
#define OPTIONAL
/* Set this to 0 to run in a non interupt mode */
#define IDE_USE_INTERRUPT 0
/* IBM PC specific code */
/* IBM-PC real mode specific Constants */
/* IO addresses used for ibm pc hard disks */
/* See IDE_OFFS_XXXX for io offsets */
#define IBM_PC_STD_IO_ADDRESS 0x22000000 //0x1f0 0x700001E0 // //DP8800 0x88000000 Liao Yibai 2002-10-15
//#define IBM_PC_STD_IO_ADDRESS 0x700001E0 //0x1f0
#define IBM_PC_ALT_IO_ADDRESS 0x170
/* Store the data register file address here, use the standard io address.
convert it to the alternate address if needed. */
unsigned int register_file_address = IBM_PC_STD_IO_ADDRESS;
#define ide_inbyte(X) *(unsigned short*)(IBM_PC_STD_IO_ADDRESS + X)
#define ide_outbyte(X,Y) *(unsigned short*)(IBM_PC_STD_IO_ADDRESS + X) = (UTINY)(Y)
/*
#ifdef _MSC_VER
#include <dos.h>
#include <conio.h>
#define ide_inbyte(X) ((UTINY) inp((UCOUNT) (register_file_address+X) ))
#define ide_outbyte(X,Y) outp((UCOUNT)(register_file_address+X), (UTINY)(Y))
#endif
#ifdef __TURBOC__
#include <dos.h>
#define ide_inbyte(X) inportb((UCOUNT)(register_file_address+X))
#define ide_outbyte(X,Y) outportb((UCOUNT)(register_file_address+X),(UTINY)(Y))
#endif
*/
/* Always expect a large model pointer */
typedef unsigned char * USERADDRESS;
/* Don't allow more then 128 blocks (64K) for fear of a segment wrap. */
#define MAX_BLOCKS 256//128 与FAT32文件系统一致 廖怡白 02.7.4
/*
程序这样做,可能是考虑到要防止PC上的磁盘段交换,我们这里如果不考虑这
样的问题,代码中不去判断这样的情况,则后面也会出现错误。在函数
ide_rdwr_setup中c_s.vo_sector_count会越界。
Daniel 2001/4/16
*/
/* Store the users buffer address here. The assembly language
in and out subroutines will copy to/from these locations */
UCOUNT user_segment = 0;
UCOUNT user_offset = 0;
/* C pointer address of the user's buffer */
USERADDRESS user_address; /* Temporary while in/out is done in c */
/* Event type. Must be ported */
/* COUNT mex_ide_event; */
/* End IBM-PC Specific Constants =================== */
/* Function prototypes *by Liao Yibai 2002.6.26
BOOL ide_ioctl(UCOUNT driveno, UCOUNT command, VOID *buffer);
BOOL ide_open(UCOUNT driveno);
BOOL ide_raw_open(UCOUNT driveno);
BOOL ide_close(UCOUNT driveno);
BOOL ide_io(UCOUNT driveno, ULONG sector, VOID *buffer, UCOUNT count, BOOL reading);
*/
INT ide_ioctl(UINT16 driveno, UINT16 command, VOID *buffer);
INT ide_open(UINT16 driveno);
INT ide_raw_open(UINT16 driveno);
INT ide_close(UINT16 driveno);
INT ide_io(UINT16 driveno, UINT32 sector, VOID FAR *buffer, UINT16 count, INT reading);
/*static*/ BOOL ide_init_drive(INT16 driveno/*physical_drive*/);//Liao Yibai 2002.6.26
static BOOL ide_drive_init(UCOUNT drive, UTINY heads, UTINY sectors);
static BOOL ide_controller_init(VOID);
static BOOL ide_reset(VOID);
static BOOL ide_command_diags(VOID);
static BOOL ide_command_setparms(COUNT drive, UTINY heads, UTINY sectors);
static BOOL ide_command_recal(COUNT drive);
static BOOL ide_command_read_sectors(USERADDRESS address, COUNT drive, ULONG blockno, UCOUNT nblocks);
static BOOL ide_command_write_sectors(USERADDRESS address, COUNT drive, ULONG blockno, UCOUNT nblocks);
static BOOL ide_rdwr_setup(USERADDRESS address, COUNT drive, ULONG blockno, UCOUNT nblocks);
static BOOL ide_do_command(VOID);
void ide_interrupt(VOID);
#ifdef PLUS
void ide_lisr_interrupt(VOID);
VOID ide_init_HISR(VOID);
#endif /* PLUS */
void ide_isr(VOID);
static void ide_error(VOID);
static void ide_clear_voregs(VOID);
static BOOL ide_wait_not_busy(COUNT millis);
static void ide_read_register_file(VOID);
/* OPTIONAL BOOL ide_command_writebuffer(USERADDRESS address, COUNT drive); */
/* OPTIONAL BOOL ide_command_readbuffer(USERADDRESS address, COUNT drive); */
/* OPTIONAL BOOL ide_command_identify(USERADDRESS address, COUNT drive); */
/* OPTIONAL BOOL ide_command_verify(COUNT drive, ULONG blockno, UCOUNT nblocks); */
/* OPTIONAL BOOL ide_command_seek(COUNT drive, UCOUNT cylinder); */
static void ide_establish_user_address(USERADDRESS address);
void ide_in_words(unsigned short nwords);
void ide_out_words(unsigned short nwords);
int puts(const char *p);
/* Timeout values - These indicate how long we will wait until deciding
that an operation has failed. Set these high if you are not worried about
bus latches. Values are in miliseconds */
/* Time outs. Under nucleus these are ticks. Here we are assuming 18 ticks
per second. Change your clockj frequency is different */
#define IDE_RESET_COUNT 2 /* Time delay during reset At least 60 ms */
#define TIMEOUT_RDWR 206 /* 12 second for a multiblock read or write
transfer to take. This is from start to finish.
We can't diddle the timer on each interrupt of
a multiblock transfer */
#define TIMEOUT_DIAG 206 /* 12 seconds maximum to complete diagnostics */
#define TIMEOUT_RESET 206 /* 12 seconds maximum to complete reset */
#define TIMEOUT_RECAL 206 /* 12 seconds maximum to complete recal */
#define TIMEOUT_TYPICAL 18 /* Max miliseconds for other commands not listed*/
/* Error codes. One will be in c_s.error_code if an ide function fails. */
#define IDE_ERC_RESET 1 /* Controller reset failed in initialize */
#define IDE_ERC_DIAG 2 /* Drive diagnostic failed in initialize */
#define IDE_ERC_ARGS 3 /* User supplied invalid arguments */
#define IDE_ERC_SETPARMS 4 /* Set parmaters failed in initialize */
#define IDE_ERC_BUS 5 /* DRQ should be asserted but it isn't */
#define IDE_ERC_TIMEOUT 6 /* Timeout during some operation */
#define IDE_ERC_RECAL 7 /* Drive recal failed */
#define IDE_ERC_DATA 8 /* Unrecoverable data error */
#define IDE_ERC_BADBLK 9 /* Bad Block mark detected */
#define IDE_ERC_WRITEFAULT 10 /* Failed writing to device */
#define IDE_ERC_READY 11 /* Drive not ready */
#define IDE_ERC_SEEK 12 /* Sector Not Found */
#define IDE_ERC_UNKNOWN 13 /* Should not happen. Error bit is set but */
/* Register file address offsets
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -