📄 pc.c
字号:
/*
*********************************************************************************************************
* PC SUPPORT FUNCTIONS
*
* (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
* All Rights Reserved
*
* File : PC.C
* By : Jean J. Labrosse
*********************************************************************************************************
*/
#include "ucos_ii.h"
#include "pc.h"
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
/*
PC display by KC51 emulation
*/
#define interrupt
#define far xdata
#define MK_FP(s, o) ((INT8U xdata *)(INT16U)(o))
#define getvect(vect) ((vect=vect),((void*)NULL))
#define setvect(vect, isr) (vect=vect, isr=isr)
int OSTickDOSCtr;
const char code * const code ExitNotice[]=
{
"Exit program",
"Program has terminated",
"Reset the processor to restart the program"
};
bit kbhit() KCREENTRANT;
INT8U getch() KCREENTRANT;
void exit(INT8U ec) KCREENTRANT
{
static char str[64];
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
OS_ENTER_CRITICAL();
for(;;)
{
INT8U i;
for(i=0; i<sizeof(ExitNotice)/sizeof(ExitNotice[0]); i++)
{
PC_DispStr (0, 8+i, ExitNotice[i], DISP_FGND_WHITE + DISP_BGND_BLACK);
}
sprintf(str, "Exit code = %bd", ec);
PC_DispStr (0, 24, str, DISP_FGND_WHITE + DISP_BGND_BLACK);
while(! kbhit());
getch();
TR0=0;
ET0=0;
((void(*)(void))0)();
}
OS_EXIT_CRITICAL();
}
/*
INT8U inp(INT8U p)
{
INT8U far *pscr;
pscr = MK_FP(DISP_BASE, 0x1000+p);
return * pscr;
}
*/
void outp(INT8U p, INT8U d)
{
INT8U far *pscr;
pscr = MK_FP(DISP_BASE, 0x1000+p);
*pscr = d;
}
struct time
{
INT8U ti_hour, ti_min, ti_sec;
};
struct date
{
INT8U da_year, da_mon, da_day;
};
void gettime(struct time * pti) KCREENTRANT
{
INT8U far *pscr;
pscr = MK_FP(DISP_BASE, 0x2010);
pti->ti_hour =* pscr ++;
pti->ti_min =* pscr ++;
pti->ti_sec =* pscr;
}
void getdate(struct date * pdt) KCREENTRANT
{
INT8U far *pscr;
pscr = MK_FP(DISP_BASE, 0x2020);
pdt->da_year = * pscr ++;
pdt->da_mon = * pscr ++;
pdt->da_day = * pscr;
}
/*
INT8U random(INT8U seed) KCREENTRANT
{
INT8U xdata * p;
p=MK_FP(0, 0x2032);
return ((*p)^((INT16U) rand())) % (INT16U)seed;
}
*/
INT8U random(INT8U seed) KCREENTRANT
{
INT8U i;
i=(((INT16U) rand())^((INT16U) rand())+TL0) % (INT16U)seed;
return i;
}
bit kbhit() KCREENTRANT
{
INT8U far *pscr;
pscr = MK_FP(DISP_BASE, 0x2030);
return *pscr;
}
INT8U getch() KCREENTRANT
{
INT8U far *pscr;
pscr = MK_FP(DISP_BASE, 0x2031);
return *pscr;
}
/*
*********************************************************************************************************
* CONSTANTS
*********************************************************************************************************
*/
#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 */
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
static INT16U PC_ElapsedOverhead;
static jmp_buf PC_JumpBuf;
static BOOLEAN PC_ExitFlag;
void (*PC_TickISR)(void);
/*$PAGE*/
/*
*********************************************************************************************************
* CLEAR SCREEN
*
* Description : This function clears the PC's screen by directly accessing video RAM instead of using
* the BIOS. It assumed that the video adapter is VGA compatible. Video RAM starts at
* absolute address 0x000B8000. Each character on the screen is composed of two bytes:
* the ASCII character to appear on the screen followed by a video attribute. An attribute
* of 0x07 displays the character in WHITE with a black background.
*
* Arguments : color specifies the foreground/background color combination to use
* (see PC.H for available choices)
*
* Returns : None
*********************************************************************************************************
*/
void PC_DispClrScr (INT8U color) KCREENTRANT
{
INT8U far *pscr;
INT16U i;
pscr = 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 */
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* CLEAR A LINE
*
* Description : This function clears one of the 25 lines on the PC's screen by directly accessing video
* RAM instead of using the BIOS. It assumed that the video adapter is VGA compatible.
* Video RAM starts at absolute address 0x000B8000. Each character on the screen is
* composed of two bytes: the ASCII character to appear on the screen followed by a video
* attribute. An attribute of 0x07 displays the character in WHITE with a black background.
*
* Arguments : y corresponds to the desired line to clear. Valid line numbers are from
* 0 to 24. Line 0 corresponds to the topmost line.
*
* color specifies the foreground/background color combination to use
* (see PC.H for available choices)
*
* Returns : None
*********************************************************************************************************
*/
void PC_DispClrLine (INT8U y, INT8U color) KCREENTRANT
{
INT8U far *pscr;
INT8U i;
pscr = 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 */
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* DISPLAY A SINGLE CHARACTER AT 'X' & 'Y' COORDINATE
*
* Description : This function writes a single character anywhere on the PC's screen. This function
* writes directly to video RAM instead of using the BIOS for speed reasons. It assumed
* that the video adapter is VGA compatible. Video RAM starts at absolute address
* 0x000B8000. Each character on the screen is composed of two bytes: the ASCII character
* to appear on the screen followed by a video attribute. An attribute of 0x07 displays
* the character in WHITE with a black background.
*
* 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.
* c Is the ASCII character to display. You can also specify a character with a
* numeric value higher than 128. In this case, special character based graphics
* will be displayed.
* color specifies the foreground/background color to use (see PC.H for available choices)
* and whether the character will blink or not.
*
* Returns : None
*********************************************************************************************************
*/
void PC_DispChar (INT8U x, INT8U y, INT8U cc, INT8U color) KCREENTRANT
{
INT8U far *pscr;
INT16U offset;
offset = (INT16U)y * DISP_MAX_X * 2 + (INT16U)x * 2; /* Calculate position on the screen */
pscr = MK_FP(DISP_BASE, offset);
*pscr++ = cc; /* Put character in video RAM */
*pscr = color; /* Put video attribute in video RAM */
}
/*$PAGE*/
/*
*********************************************************************************************************
* DISPLAY A STRING AT 'X' & 'Y' COORDINATE
*
* Description : This function writes an ASCII string anywhere on the PC's screen. This function writes
* directly to video RAM instead of using the BIOS for speed reasons. It assumed that the
* video adapter is VGA compatible. Video RAM starts at absolute address 0x000B8000. Each
* character on the screen is composed of two bytes: the ASCII character to appear on the
* screen followed by a video attribute. An attribute of 0x07 displays the character in
* WHITE with a black background.
*
* 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.
* 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.
* color specifies the foreground/background color to use (see PC.H for available choices)
* and whether the characters will blink or not.
*
* Returns : None
*********************************************************************************************************
*/
void PC_DispStr (INT8U x, INT8U y, INT8U *s, INT8U color) KCREENTRANT
{
INT8U far *pscr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -