📄 pc.c
字号:
* screen followed by a video attribute. An attribute of 0x07 displays the character in
* WHITE with a black background.
用于显示一个ASCII码字符串,实际上,可以显示由255个ASCII字符所组成的任意字符串数组,只要该数组以NULL结束即可。
*
* Arguments : x corresponds to the desired column on the screen. Valid columns numbers are from
* 0 to 79. Column 0 corresponds to the leftmost column.
* y corresponds to the desired row on the screen. Valid row numbers are from 0 to 24.
* Line 0 corresponds to the topmost row.
x和y 指定所显示字符串中第1个字符的坐标(列和行)。行的值为0~DISP_MAX_Y-1,而列的值为0~DISP_MAX_X-1,可参看文件PC.C
* s Is the ASCII string to display. You can also specify a string containing
* characters with numeric values higher than 128. In this case, special character
* based graphics will be displayed.
指向所需要显示字符串的指针,字符串必须以NULL结束。可显示0x00~0xFF的任何字符
* color specifies the foreground/background color to use (see PC.H for available choices)
* and whether the characters will blink or not.
指向所显示字符的属性,即字符的色彩组合。可添加一个DISP_FGND_???常数和一个DISP_BGND_???常数,以得到所需要的色彩组合。
这2个常数的定义见PC.H文件。
*
* Returns : None
注意:字符串数组中的所有字符都以相同的颜色属性显示。
*********************************************************************************************************
*/
void PC_DispStr (INT8U x, INT8U y, INT8U *s, INT8U color)
{
INT8U far *pscr;
INT16U offset;
offset = (INT16U)y * DISP_MAX_X * 2 + (INT16U)x * 2; /* Calculate position of 1st character */
pscr = (INT8U far *)MK_FP(DISP_BASE, offset);
while (*s) {
*pscr++ = *s++; /* Put character in video RAM */
*pscr++ = color; /* Put video attribute in video RAM */
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* RETURN TO DOS
*
* Description : This functions returns control back to DOS by doing a 'long jump' back to the saved
* location stored in 'PC_JumpBuf'. The saved location was established by the function
* 'PC_DOSSaveReturn()'. After execution of the long jump, execution will resume at the
* line following the 'set jump' back in 'PC_DOSSaveReturn()'. Setting the flag
该函数让程序返回DOS。前提是已经调用过PC_DOSSaveReturn()保存重要寄存器内容以保证正常返回DOS。
* 'PC_ExitFlag' to TRUE ensures that the 'if' statement in 'PC_DOSSaveReturn()' executes.
*
* Arguments : None
*
* Returns : None
注意:用户必须保证:在调用PC_DOSReturn()函数前,已经调用过PC_DOSSaveReturn()函数。
*********************************************************************************************************
*/
void PC_DOSReturn (void)
{
PC_ExitFlag = TRUE; /* Indicate we are returning to DOS */
longjmp(PC_JumpBuf, 1); /* Jump back to saved environment希望可以返回DOS,只需调用
PC_DOSReturn()函数即可。在这个函数中,PC_ExitFlag被设定为TRUE,并且执行了跳转函数longjmp()。*/
}
/*$PAGE*/
/*
*********************************************************************************************************
* SAVE DOS RETURN LOCATION
函数PC_DOSSaveReturn()用于保存当前DOS环境,主程序main()通过调用该函数完成一下功能:1 设置ucos的环境软中断向量,以实现任务
切换。2 设置时钟中断服务子程序ISR的中断向量。3 保存DOS环境设置,使得在需要终止一个基于UCOS的应用程序时,可以返回DOS。
PC_DOSSaveReturn()函数的源代码如下
*
* Description : This function saves the location of where we are in DOS so that it can be recovered.
* This allows us to abort multitasking under uC/OS-II and return back to DOS as if we had
* never left. When this function is called by 'main()', it sets 'PC_ExitFlag' to FALSE
* so that we don't take the 'if' branch. Instead, the CPU registers are saved in the
* long jump buffer 'PC_JumpBuf' and we simply return to the caller. If a 'long jump' is
* performed using the jump buffer then, execution would resume at the 'if' statement and
* this time, if 'PC_ExitFlag' is set to TRUE then we would execute the 'if' statements and
* restore the DOS environment.
*
* Arguments : None
*
* Returns : None
*********************************************************************************************************
*/
void PC_DOSSaveReturn (void)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
PC_ExitFlag = FALSE; /* Indicate that we are not exiting yet!PC_DOSSaveReturn()从设
定PC_ExitFlag标志位FALSE开始,标志着现在不希望返回DOS。*/
OSTickDOSCtr = 1; /* Initialize the DOS tick counter函数将OSTickDOSCtr初始化为1,
这个变量将在函数OSTickISR()中递减。当其值为0时,下次递减将会翻转为255.*/
PC_TickISR = PC_VectGet(VECT_TICK); /* Get MS-DOS's tick vector */
PC_VectSet(VECT_DOS_CHAIN, PC_TickISR); /* Store MS-DOS's tick to chain;PC_DOSSaveReturn()把DOS中的时
钟处理程序保存在一个空的中断向量入口处,这样UCOS的时钟处理程序就可以调用它了 成为向量的转移。*/
setjmp(PC_JumpBuf); /* Capture where we are in DOS;PC_DOSSaveReturn()调用函数
setjmp()。这个函数将得到处理器的状态(各个主要寄存器的内容),并把它们保存在一个结构体PC_JumpBuf中。获取处理器的状态后,
setjmp()将返回PC_DOSSaveReturn()函数,然后从下一条语句继续执行。因为PC_ExitFlag被初始化为FALSE,PC_DOSSaveReturn()将
会跳过if语句,返回到主函数main()。跳转函数longjmp()使处理器返回到函数PC_DOSSaveReturn()(调用setjmp()函数的下一条语句)*/
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因为PC_ExitFlag为TRUE,将执行if
语句后的代码。*/
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;PC_DOSSaveReturn()把时钟节拍改回18.2hz,恢复
PC原来的时钟中断服务子程序并清屏,通过exit(0)函数返回DOS命令行状态。*/
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* ELAPSED TIME INITIALIZATION
程序运行时间测量函数用于确定函数的运行时间,这是通过PC机的82C54定时器#2完成的。在实际测量时,只需把被测量的代码放在
PC_ElapsedStart()和PC_ElapsedStop()2个函数之间即可;但在使用这2个函数之前,必须先调用初始化函数PC_ElapsedInit(),以测量上
面2个函数本身执行所需要的时间。这样,PC_ElapsedStop()函数返回的时间就是执行测量代码所需要的实际时间。
注意:上面3个函数都不具备可重入性,所以,必须小心:不得有果个任务同时调用这些函数。
*
* 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.
注意:在调用PC_ElapsedStart()或PC_ElapsedStop()之前,一定要调用PC_ElapsedInit()函数。
本函数不具备可重入性,不能在没有适当保护机制(信号量和调度锁定等)的情况下,由多个任务同时调用。
用户代码的执行时间必须短于54.93ms,以保证时间测量函数能够正常工作。
*********************************************************************************************************
*/
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -