📄 miniexec.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 Changed the mex_restore_vectors to */
/* restore the correct vector for the */
/* floppy. */
/* */
/* 07-28-94 Modified the file to work with Watcom. */
/* */
/* 08-20-97 The File System is updated to run */
/* without using DMA. The compile line */
/* option POLLED will turn off DMA support */
/* and use polled mode to talk to the */
/* floppy controller (release 1.5). */
/* */
/*************************************************************************/
/* 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.
*/
/* miniexec.c - Timer and interrupt service routines for EBS drivers.
*
* These routines provide executive services for the EBS drivers running
* on a PC with no executive kernel. Equivalent services should be
* provided by the kernel environment, replacing these.
*/
#ifdef PLUS
#include "nucleus.h"
#else
#include "nu_defs.h"
#include "nu_extr.h"
extern int IND_Set_Interrupt_Level(unsigned int int_enable);
#if EBS_FLOPPY
extern void enable_irq6(void);
#endif
#if EBS_IDE
extern void enable_irq14(void);
#endif
#endif
#include "pcdisk.h"
#include "miniexec.h"
int outp(unsigned portid, int value);
int inp(unsigned portid);
/* static UTINY read_cmos(UCOUNT address); */
/* POKE 0xff at offset 0x40 in the bios ram area. This forces the bios
to not shut the motor down. This way the bios doesn't interfere with us */
void PCAT_disable_bios_motor()
{
/* unsigned char far *p; */
unsigned char NEAR *p;
unsigned short *c;
c = (unsigned short *) &p;
c[1] = 0x40; c[0] = 0x40; /* MK_FP(0x40, 0x40) SEG:OFFSET */
*p = 0xff;
}
static UCOUNT PCAT_read_8254()
{
UCOUNT val;
UTINY low;
UTINY high;
outp(0x43, 0);
low = (UTINY) inp(0x40);
high = (UTINY) inp(0x40);
val = (UCOUNT) high;
val <<= 8;
val |= low;
return(val);
}
/* AT specific code. */
static UTINY PCAT_read_cmos(UCOUNT address) /* __fn__ */
{
outp(0x70,(UCOUNT) (address | 0x80));
return((UTINY)inp(0x71));
}
VOID mex_delay_25()
{
UCOUNT val;
UCOUNT val2;
UCOUNT oldval;
/* Sleep 25 microseconds
The 8253 count 2 ticks every .8 microseconds
so we need to wait at least 64 ticks
*/
UCOUNT micros = 64;
/* Get the current tick value. */
val = PCAT_read_8254(); /* Get the timer */
/* If we are close to a wrap, let it wrap */
while (val < micros){val = PCAT_read_8254();}
/* Now loop wile we are between val and val - micros */
oldval = val;
val -= micros; /* Wait til the clock is current val - delay ticks */
do {val2 = PCAT_read_8254();} while( (val2 >= val) && (val2 <= oldval));
}
/* AT IDE hard disk driver support */
#if (EBS_IDE)
/* This is a bios compatible drive table. We read the drive type out of the
cmos and look up the drive parameters. here. Only sectors and heads are
used in this table. In a non pc heads and sectors must be gotten some
other way.
*/
/* Define a macro which lets us document the table drive table information
while only compiling in heads and sectors */
/* IBM PC Rom Bios compatible drive table entry. We only use two
* fields (heads & sectors). The others are left in as a reference so
* it may be used in a PC with bios environment.
*/
typedef struct drive_table
{
/* UCOUNT cylinders; Total user cylinders (not used on IDE) */
UTINY heads; /* Total user heads */
#if 0
UCOUNT dummy_1;
UCOUNT precomp; /* Write precomp (not used on IDE) */
UTINY dummy_2;
UTINY control; /* Control register (not used on IDE) */
UTINY dummy_3;
UTINY dummy_4;
UTINY dummy_5;
UCOUNT landing; /* Landing zone (not used on IDE) */
#endif
UTINY sectors; /* User sectors per track */
/* UTINY dummy_6; */
} DRIVE_TABLE;
typedef struct drive_table * PDRIVE_TABLE;
#define DTE(A, B, C, D, E, F, G, H, I, J, K, L) {(B), (K)}
static DRIVE_TABLE bios_table[] = {
DTE(306, 4, 0, 128,0, 0, 0, 0, 0, 305,17, 0),
DTE(615, 4, 0, 300,0, 0, 0, 0, 0, 615,17, 0),
DTE(615, 6, 0, 300,0, 0, 0, 0, 0, 615,17, 0),
DTE(940, 8, 0, 512,0, 0, 0, 0, 0, 940,17, 0),
DTE(940, 6, 0, 512,0, 0, 0, 0, 0, 940,17, 0),
DTE(615, 4, 0, -1,0, 0, 0, 0, 0, 615,17, 0),
DTE(462, 8, 0, 256,0, 0, 0, 0, 0, 511,17, 0),
DTE(733, 5, 0, -1,0, 0, 0, 0, 0, 733,17, 0),
DTE(900,15, 0, -1,0, 8, 0, 0, 0, 901,17, 0),
DTE(820, 3, 0, -1,0, 0, 0, 0, 0, 820,17, 0),
DTE(855, 5, 0, -1,0, 0, 0, 0, 0, 855,17, 0),
DTE(855, 7, 0, -1,0, 0, 0, 0, 0, 855,17, 0),
DTE(306, 8, 0, 128,0, 0, 0, 0, 0, 319,17, 0),
DTE(733, 7, 0, -1,0, 0, 0, 0, 0, 733,17, 0),
DTE( 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0),
DTE(612, 4, 0, 0,0, 0, 0, 0, 0, 663,17, 0),
DTE(977, 5, 0, 300,0, 0, 0, 0, 0, 977,17, 0),
DTE(977, 7, 0, -1,0, 0, 0, 0, 0, 977,17, 0),
DTE(1024,7, 0, 512,0, 0, 0, 0, 0,1023,17, 0),
DTE(733, 5, 0, 300,0, 0, 0, 0, 0, 732,17, 0),
DTE(733, 7, 0, 300,0, 0, 0, 0, 0, 733,17, 0),
DTE(733, 5, 0, 300,0, 0, 0, 0, 0, 733,17, 0),
DTE(306, 4, 0, 0,0, 0, 0, 0, 0, 336,17, 0),
DTE(612, 4, 0, 305,0, 0, 0, 0, 0, 663,17, 0),
DTE(306, 4, 0, -1,0, 0, 0, 0, 0, 340,17, 0),
DTE(612, 4, 0, -1,0, 0, 0, 0, 0, 670,17, 0),
DTE(698, 7, 0, 300,0, 0, 0, 0, 0, 732,17, 0),
DTE(976, 5, 0, 488,0, 0, 0, 0, 0, 977,17, 0),
DTE(306, 4, 0, 0,0, 0, 0, 0, 0, 340,17, 0),
DTE(611, 4, 0, 306,0, 0, 0, 0, 0, 663,17, 0),
DTE(732, 7, 0, 300,0, 0, 0, 0, 0, 732,17, 0),
DTE(1023,5, 0, -1,0, 0, 0, 0, 0,1023,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(306, 2, 0, -1,0, 0, 0, 0, 0, 305,17, 0),
DTE(745, 4, 0, -1,0, 0, 0, 0, 0, 744,28, 0),
};
/* Return the drive type from cmos */
/* PC SPECIFIC USED only by init_drive() !!!!!!!!! */
BOOL mex_hard_disk_geometry(COUNT driveno, UTINY *heads, UTINY *sectors) /*__fn__*/
{
UTINY ttemp;
UTINY cdrive_type;
UTINY ddrive_type;
COUNT type;
/* Winch 0 is in high nibble of x12 */
ttemp = PCAT_read_cmos(0x12);
cdrive_type = (UTINY) (ttemp >> 4);
/* If =='s 0xf then the drive type comes out of location 0x19 */
if (cdrive_type == 0x0f)
cdrive_type = PCAT_read_cmos(0x19);
/* Winch 1 is in low nibble of x12 */
ddrive_type = (UTINY) (ttemp & 0xf);
/* If =='s 0xf then the drive type comes out of location 0x1a */
if (ddrive_type == 0x0f)
ddrive_type = PCAT_read_cmos(0x1a);
if (driveno == 0)
type = (COUNT) cdrive_type;
else
type = (COUNT) ddrive_type;
if (!type)
return(NO);
else
{
if (type == 47) /* USER TYPE. Look in CMOS for values. */
{
if (driveno == 0) /* C: */
{
*heads = PCAT_read_cmos(29); /* Heads at loc 29 in cmos */
*sectors = PCAT_read_cmos(35); /* SpTRK at loc 35 in cmos */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -