📄 kaka.c
字号:
{
if (ticks > 0) { /* 0 means no delay! */
OS_ENTER_CRITICAL();
if ((OSRdyTbl[OSTCBCur->OSTCBY] &= ~OSTCBCur->OSTCBBitX) == 0) { /* Delay current task */
OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
}
OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */
OS_EXIT_CRITICAL();
OS_Sched(); /* ^^^ Find next task to run! */
}
}
void OSIntEnter (void)
{
if (OSRunning == TRUE) {
if (OSIntNesting < 255) {
OSIntNesting++; /* Increment ISR nesting level */
}
}
}
void OSIntExit (void)
{
if (OSRunning == TRUE) {
OS_ENTER_CRITICAL();
if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */
OSIntNesting--;
}
if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Reschedule only if all ISRs complete ... */
OSIntExitY = OSUnMapTbl[OSRdyGrp]; /* ... and not locked. */
OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
OSCtxSwCtr++; /* ^^^ Keep track of the number of ctx switches */
OSIntCtxSw(); /* ^^^Perform interrupt level ctx switch */
}
}
OS_EXIT_CRITICAL();
}
}
INT8U OS_TCBInit (INT8U prio, INT16U *ptos, INT16U *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt)
{
OS_TCB *ptcb;
OS_ENTER_CRITICAL();
ptcb = OSTCBFreeList; /* Get a free TCB from the free TCB list */
if (ptcb != (OS_TCB *)0) {
OSTCBFreeList = ptcb->OSTCBNext; /* Update pointer to free TCB list */
OS_EXIT_CRITICAL();
ptcb->OSTCBStkPtr = ptos; /* Load Stack pointer in TCB */
ptcb->OSTCBPrio = (INT8U)prio; /* Load task priority into TCB */
ptcb->OSTCBStat = OS_STAT_RDY; /* Task is ready to run */
ptcb->OSTCBDly = 0; /* Task is not delayed */
pext = pext; /* Prevent compiler warning if not used */
stk_size = stk_size;
pbos = pbos;
opt = opt;
id = id;
ptcb->OSTCBY = prio >> 3; /* Pre-compute X, Y, BitX and BitY */
ptcb->OSTCBBitY = OSMapTbl[ptcb->OSTCBY];
ptcb->OSTCBX = prio & 0x07;
ptcb->OSTCBBitX = OSMapTbl[ptcb->OSTCBX];
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = ptcb;
ptcb->OSTCBNext = OSTCBList; /* Link into TCB chain */
ptcb->OSTCBPrev = (OS_TCB *)0;
if (OSTCBList != (OS_TCB *)0) {
OSTCBList->OSTCBPrev = ptcb;
}
OSTCBList = ptcb;
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready to run */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
OS_EXIT_CRITICAL();
return (OS_NO_MORE_TCB);
}
INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, INT16U *ptos, INT8U prio)
{
INT16U *psp;
INT8U err;
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[prio] == (OS_TCB *)0) { /* Make sure task doesn't already exist at this priority */
OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the priority to prevent others from doing ... */
/* ... the same thing until task is created. */
OS_EXIT_CRITICAL();
psp = (INT16U *)OSTaskStkInit(task, pdata, ptos, 0); /* Initialize the task's stack */
err = OS_TCBInit(prio, psp, (INT16U *)0, 0, 0, (void *)0, 0);
if (err == OS_NO_ERR) {
OS_ENTER_CRITICAL();
OSTaskCtr++; /* Increment the #tasks counter */
OS_EXIT_CRITICAL();
if (OSRunning == TRUE) { /* Find highest priority task if multitasking has started */
OS_Sched();
}
} else {
OS_ENTER_CRITICAL();
OSTCBPrioTbl[prio] = (OS_TCB *)0;/* Make this priority available to others */
OS_EXIT_CRITICAL();
}
return (err);
}
OS_EXIT_CRITICAL();
return (OS_PRIO_EXIST);
}
INT16U *OSTaskStkInit (void (*task)(void *pd), void *pdata, INT16U *ptos, INT16U opt)
{
INT16U *stk;
opt = opt; /* 'opt' is not used, prevent warning */
stk = (INT16U *)ptos; /* Load stack pointer */
*stk-- = (INT16U)FP_SEG(pdata); /* Simulate call to function with argument */
*stk-- = (INT16U)FP_OFF(pdata);
*stk-- = (INT16U)FP_SEG(task);
*stk-- = (INT16U)FP_OFF(task);
*stk-- = (INT16U)0x0202; /* SW = Interrupts enabled */
*stk-- = (INT16U)FP_SEG(task); /* Put pointer to task on top of stack */
*stk-- = (INT16U)FP_OFF(task);
*stk-- = (INT16U)0xAAAA; /* AX = 0xAAAA */
*stk-- = (INT16U)0xCCCC; /* CX = 0xCCCC */
*stk-- = (INT16U)0xDDDD; /* DX = 0xDDDD */
*stk-- = (INT16U)0xBBBB; /* BX = 0xBBBB */
*stk-- = (INT16U)0x0000; /* SP = 0x0000 */
*stk-- = (INT16U)0x1111; /* BP = 0x1111 */
*stk-- = (INT16U)0x2222; /* SI = 0x2222 */
*stk-- = (INT16U)0x3333; /* DI = 0x3333 */
*stk-- = (INT16U)0x4444; /* ES = 0x4444 */
*stk = _DS; /* DS = Current value of DS */
return ((INT16U *)stk);
}
/*-----------------------------PC Configration ---------------------------------------------------------------*/
/*-----------------------------DEFINES -----------------------------------------------------------------------*/
#define DISP_FGND_BLACK 0x00
#define DISP_FGND_BLUE 0x01
#define DISP_FGND_GREEN 0x02
#define DISP_FGND_CYAN 0x03
#define DISP_FGND_RED 0x04
#define DISP_FGND_PURPLE 0x05
#define DISP_FGND_BROWN 0x06
#define DISP_FGND_LIGHT_GRAY 0x07
#define DISP_FGND_DARK_GRAY 0x08
#define DISP_FGND_LIGHT_BLUE 0x09
#define DISP_FGND_LIGHT_GREEN 0x0A
#define DISP_FGND_LIGHT_CYAN 0x0B
#define DISP_FGND_LIGHT_RED 0x0C
#define DISP_FGND_LIGHT_PURPLE 0x0D
#define DISP_FGND_YELLOW 0x0E
#define DISP_FGND_WHITE 0x0F
#define DISP_BGND_BLACK 0x00
#define DISP_BGND_BLUE 0x10
#define DISP_BGND_GREEN 0x20
#define DISP_BGND_CYAN 0x30
#define DISP_BGND_RED 0x40
#define DISP_BGND_PURPLE 0x50
#define DISP_BGND_BROWN 0x60
#define DISP_BGND_LIGHT_GRAY 0x70
#define DISP_BLINK 0x80
#define DISP_BASE 0xB800 /* Base segment of display (0xB800=VGA, 0xB000=Mono) */
#define DISP_MAX_X 80 /* Maximum number of columns */
#define DISP_MAX_Y 25 /* Maximum number of rows */
#define TICK_T0_8254_CWR 0x43 /* 8254 PIT Control Word Register address. */
#define TICK_T0_8254_CTR0 0x40 /* 8254 PIT Timer 0 Register address. */
#define TICK_T0_8254_CTR1 0x41 /* 8254 PIT Timer 1 Register address. */
#define TICK_T0_8254_CTR2 0x42 /* 8254 PIT Timer 2 Register address. */
#define TICK_T0_8254_CTR0_MODE3 0x36 /* 8254 PIT Binary Mode 3 for Counter 0 control word. */
#define TICK_T0_8254_CTR2_MODE0 0xB0 /* 8254 PIT Binary Mode 0 for Counter 2 control word. */
#define TICK_T0_8254_CTR2_LATCH 0x80 /* 8254 PIT Latch command control word */
#define VECT_TICK 0x08 /* Vector number for 82C54 timer tick */
#define VECT_DOS_CHAIN 0x81 /* Vector number used to chain DOS */
void PC_DispChar(INT8U x, INT8U y, INT8U c, INT8U color);
void PC_DispClrCol(INT8U x, INT8U bgnd_color);
void PC_DispClrRow(INT8U y, INT8U bgnd_color);
void PC_DispClrScr(INT8U bgnd_color);
void PC_DispStr(INT8U x, INT8U y, INT8U *s, INT8U color);
void PC_DOSReturn(void);
void PC_DOSSaveReturn(void);
void PC_ElapsedInit(void);
void PC_ElapsedStart(void);
INT16U PC_ElapsedStop(void);
void PC_GetDateTime(char *s);
BOOLEAN PC_GetKey(INT16S *c);
void PC_SetTickRate(INT16U freq);
void *PC_VectGet(INT8U vect);
void PC_VectSet(INT8U vect, void (*isr)(void));
static INT16U PC_ElapsedOverhead;
static jmp_buf PC_JumpBuf;
static BOOLEAN PC_ExitFlag;
void (*PC_TickISR)(void);
void PC_DispChar (INT8U x, INT8U y, INT8U c, INT8U color)
{
INT8U far *pscr;
INT16U offset;
offset = (INT16U)y * DISP_MAX_X * 2 + (INT16U)x * 2; /* Calculate position on the screen */
pscr = (INT8U far *)MK_FP(DISP_BASE, offset);
*pscr++ = c; /* Put character in video RAM */
*pscr = color; /* Put video attribute in video RAM */
}
void PC_DispClrCol (INT8U x, INT8U color)
{
INT8U far *pscr;
INT8U i;
pscr = (INT8U far *)MK_FP(DISP_BASE, (INT16U)x * 2);
for (i = 0; i < DISP_MAX_Y; i++) {
*pscr++ = ' '; /* Put ' ' character in video RAM */
*pscr-- = color; /* Put video attribute in video RAM */
pscr = pscr + DISP_MAX_X * 2; /* Position on next row */
}
}
void PC_DispClrRow (INT8U y, INT8U color)
{
INT8U far *pscr;
INT8U i;
pscr = (INT8U far *)MK_FP(DISP_BASE, (INT16U)y * DISP_MAX_X * 2);
for (i = 0; i < DISP_MAX_X; i++) {
*pscr++ = ' '; /* Put ' ' character in video RAM */
*pscr++ = color; /* Put video attribute in video RAM */
}
}
void PC_DispClrScr (INT8U color)
{
INT8U far *pscr;
INT16U i;
pscr = (INT8U far *)MK_FP(DISP_BASE, 0x0000);
for (i = 0; i < (DISP_MAX_X * DISP_MAX_Y); i++) { /* PC display has 80 columns and 25 lines */
*pscr++ = ' '; /* Put ' ' character in video RAM */
*pscr++ = color; /* Put video attribute in video RAM */
}
}
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 */
}
}
void PC_DOSReturn (void)
{
PC_ExitFlag = TRUE; /* Indicate we are returning to DOS */
longjmp(PC_JumpBuf, 1); /* Jump back to saved environment */
}
void PC_DOSSaveReturn (void)
{
PC_ExitFlag = FALSE; /* Indicate that we are not exiting yet! */
OSTickDOSCtr = 1; /* Initialize the DOS tick counter */
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 */
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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -