📄 pc.c
字号:
setjmp(PC_JumpBuf); /* Capture where we are in DOS */
if (PC_ExitFlag == TRUE) { /* See if we are exiting back to DOS */
OS_ENTER_CRITICAL();
PC_SetTickRate(18); /* Restore tick rate to 18.2 Hz */
OS_EXIT_CRITICAL();
PC_VectSet(VECT_TICK, PC_TickISR); /* Restore DOS's tick vector */
PC_DispClrScr(DISP_FGND_WHITE + DISP_BGND_BLACK); /* Clear the display */
exit(0); /* Return to DOS */
}
}
/*$PAGE*/
/**********************************************************************************************************
ELAPSED TIME INITIALIZATION
Description : This function initialize the elapsed time module by determining how long the START and
STOP functions take to execute. In other words, this function calibrates this module
to account for the processing time of the START and STOP functions.
Arguments : None.
Returns : None.
**********************************************************************************************************/
void PC_ElapsedInit(void)
{
PC_ElapsedOverhead = 0;
PC_ElapsedStart();
PC_ElapsedOverhead = PC_ElapsedStop();
}
/*$PAGE*/
/**********************************************************************************************************
INITIALIZE PC'S TIMER #2
Description : This function initialize the PC's Timer #2 to be used to measure the time between events.
Timer #2 will be running when the function returns.
Arguments : None.
Returns : None.
**********************************************************************************************************/
void PC_ElapsedStart(void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT8U data;
OS_ENTER_CRITICAL();
data = (INT8U)inp(0x61); /* Disable timer #2 */
data &= 0xFE;
outp(0x61, data);
outp(TICK_T0_8254_CWR, TICK_T0_8254_CTR2_MODE0); /* Program timer #2 for Mode 0 */
outp(TICK_T0_8254_CTR2, 0xFF);
outp(TICK_T0_8254_CTR2, 0xFF);
data |= 0x01; /* Start the timer */
outp(0x61, data);
OS_EXIT_CRITICAL();
}
/*$PAGE*/
/**********************************************************************************************************
STOP THE PC'S TIMER #2 AND GET ELAPSED TIME
Description : This function stops the PC's Timer #2, obtains the elapsed counts from when it was
started and converts the elapsed counts to micro-seconds.
Arguments : None.
Returns : The number of micro-seconds since the timer was last started.
Notes : - The returned time accounts for the processing time of the START and STOP functions.
- 54926 represents 54926S-16 or, 0.838097 which is used to convert timer counts to
micro-seconds. The clock source for the PC's timer #2 is 1.19318 MHz (or 0.838097 uS)
**********************************************************************************************************/
INT16U PC_ElapsedStop(void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT8U data;
INT8U low;
INT8U high;
INT16U cnts;
OS_ENTER_CRITICAL();
data = (INT8U)inp(0x61); /* Disable the timer */
data &= 0xFE;
outp(0x61, data);
outp(TICK_T0_8254_CWR, TICK_T0_8254_CTR2_LATCH); /* Latch the timer value */
low = inp(TICK_T0_8254_CTR2);
high = inp(TICK_T0_8254_CTR2);
cnts = (INT16U)0xFFFF - (((INT16U)high << 8) + (INT16U)low); /* Compute time it took for operation */
OS_EXIT_CRITICAL();
return ((INT16U)((INT32U)cnts * 54926L >> 16) - PC_ElapsedOverhead);
}
/*$PAGE*/
/**********************************************************************************************************
GET THE CURRENT DATE AND TIME
Description: This function obtains the current date and time from the PC.
Arguments : s is a pointer to where the ASCII string of the current date and time will be stored.
You must allocate at least 21 bytes (includes the NUL) of storage in the return
string. The date and time will be formatted as follows:
"YYYY-MM-DD HH:MM:SS"
Returns : none
**********************************************************************************************************/
void PC_GetDateTime (char *s)
{
struct time now;
struct date today;
gettime(&now);
getdate(&today);
sprintf(s, "%04d-%02d-%02d %02d:%02d:%02d",
today.da_year,
today.da_mon,
today.da_day,
now.ti_hour,
now.ti_min,
now.ti_sec);
}
/*$PAGE*/
/**********************************************************************************************************
CHECK AND GET KEYBOARD KEY
Description: This function checks to see if a key has been pressed at the keyboard and returns TRUE if
so. Also, if a key is pressed, the key is read and copied where the argument is pointing
to.
Arguments : c is a pointer to where the read key will be stored.
Returns : TRUE if a key was pressed
FALSE otherwise
**********************************************************************************************************/
BOOLEAN PC_GetKey (INT16S *c)
{
if (kbhit()) { /* See if a key has been pressed */
*c = (INT16S)getch(); /* Get key pressed */
return (TRUE);
} else {
*c = 0x00; /* No key pressed */
return (FALSE);
}
}
/*$PAGE*/
/**********************************************************************************************************
SET THE PC'S TICK FREQUENCY
Description: This function is called to change the tick rate of a PC.
Arguments : freq is the desired frequency of the ticker (in Hz)
Returns : none
Notes : 1) The magic number 2386360 is actually twice the input frequency of the 8254 chip which
is always 1.193180 MHz.
2) The equation computes the counts needed to load into the 8254. The strange equation
is actually used to round the number using integer arithmetic. This is equivalent to
the floating point equation:
1193180.0 Hz
count = ------------ + 0.5
freq
**********************************************************************************************************/
void PC_SetTickRate (INT16U freq)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT16U count;
if (freq == 18) { /* See if we need to restore the DOS frequency */
count = 0;
} else if (freq > 0) {
/* Compute 8254 counts for desired frequency and ... */
/* ... round to nearest count */
count = (INT16U)(((INT32U)2386360L / freq + 1) >> 1);
} else {
count = 0;
}
OS_ENTER_CRITICAL();
outp(TICK_T0_8254_CWR, TICK_T0_8254_CTR0_MODE3); /* Load the 8254 with desired frequency */
outp(TICK_T0_8254_CTR0, count & 0xFF); /* Low byte */
outp(TICK_T0_8254_CTR0, (count >> 8) & 0xFF); /* High byte */
OS_EXIT_CRITICAL();
}
/*$PAGE*/
/**********************************************************************************************************
OBTAIN INTERRUPT VECTOR
Description: This function reads the pointer stored at the specified vector.
Arguments : vect is the desired interrupt vector number, a number between 0 and 255.
Returns : The address of the Interrupt handler stored at the desired vector location.
**********************************************************************************************************/
void *PC_VectGet (INT8U vect)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT16U *pvect;
INT16U off;
INT16U seg;
pvect = (INT16U *)MK_FP(0x0000, vect * 4); /* Point into IVT at desired vector location */
OS_ENTER_CRITICAL();
off = *pvect++; /* Obtain the vector's OFFSET */
seg = *pvect; /* Obtain the vector's SEGMENT */
OS_EXIT_CRITICAL();
return (MK_FP(seg, off));
}
/**********************************************************************************************************
INSTALL INTERRUPT VECTOR
Description: This function sets an interrupt vector in the interrupt vector table.
Arguments : vect is the desired interrupt vector number, a number between 0 and 255.
isr is a pointer to a function to execute when the interrupt or exception occurs.
Returns : none
**********************************************************************************************************/
void PC_VectSet (INT8U vect, void (*isr)(void))
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
INT16U *pvect;
pvect = (INT16U *)MK_FP(0x0000, vect * 4); /* Point into IVT at desired vector location */
OS_ENTER_CRITICAL();
*pvect++ = (INT16U)FP_OFF(isr); /* Store ISR offset */
*pvect = (INT16U)FP_SEG(isr); /* Store ISR segment */
OS_EXIT_CRITICAL();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -