#define YCORG -1
#include "ycio.cpp"
ycttyCLASS YCTTY; //函数接口对象
void main(void **pObj)
{
*pObj = &YCTTY; //把函数接口对象地址传给调用者
}
int SCRwide = 80; //屏幕宽度
int g_curpos = SCRwide * 8; //光标位置
byte key_buf[32]; //键盘缓冲区
byte *key_head = key_buf; //键盘缓冲区头指针
byte *key_tail = key_buf; //键盘缓冲区尾指针
byte bg_color = 0x07; //屏幕前景颜色和背景颜色属性
int pmt_pos; //提示符位置
int disk_no = 2; //磁盘号
void ycttyCLASS::sys_write(int *pdata) //向屏幕写字符串
{
const char *_Source = (const char *)pdata[0]; //字符串地址
int glen = pdata[1]; //字符串长度
int wrpos = pdata[2]; //不小于0时为屏幕缓冲区位置
auto vidBuf = (byte*)(KERNEL_POS + 0xb8000); //屏幕缓冲区地址
if(glen < 0)
{
ycio_clear_screen(g_curpos,-glen); //清屏
return;
}
int maxPos = (25 - 1) * SCRwide;
int bcurpos = g_curpos;
if(wrpos >= 0) g_curpos = wrpos;
for(int ii=0; ii<glen; ii++)
{
byte uu = _Source[ii];
switch(uu)
{
case '\t': //tab字符
g_curpos += 8 - (g_curpos % 8);
continue;
case '\r': //回车
g_curpos -= g_curpos % SCRwide;
continue;
case '\n': //换行
g_curpos -= g_curpos % SCRwide;
if(g_curpos >= maxPos)
{
rn_000:
memcpy(vidBuf,&vidBuf[SCRwide*2],maxPos*2);//向上滚动一行
ycio_clear_screen(maxPos,SCRwide); //清除一行
}
else g_curpos += SCRwide;
continue;
}
vidBuf[g_curpos * 2] = uu; //在位置 g_curpos 写字符
vidBuf[g_curpos * 2 + 1] = bg_color; //在位置 g_curpos 写属性
g_curpos++;
if(g_curpos>=maxPos + SCRwide) //位置 g_curpos 超出屏幕底部
{
g_curpos = maxPos;
goto rn_000;
}
}
if(wrpos >= 0) g_curpos = bcurpos;
else ycio_cursor(g_curpos); //设置光标位置
}
void ycttyCLASS::clear_screen(int bpos,int len)
{
auto vidBuf = (byte*)(KERNEL_POS + 0xb8000);
auto memsetS = asm[](void *_Dst,int _Val,unsigned int _Size)
{
push ebp
mov ebp, esp
push edi
mov edi, _Dst
mov eax, _Val
mov ecx, _Size
rep stosw
pop edi
mov esp, ebp
pop ebp
ret
};
memsetS(&vidBuf[bpos * 2], (bg_color<<8) + ' ', len);
}
void set_cursor_pos(int wrpos,int *pOld=nullptr)
{
if(pOld) *pOld = g_curpos;
if(wrpos == -1) return;
g_curpos = wrpos;
ycio_cursor(g_curpos);
}
void ycttyCLASS::pmt_cursor_pos(int cpos)
{
set_cursor_pos(pmt_pos + cpos);
}
void ycttyCLASS::wr_prompt()
{
char hbuf[] = "\nC:\\>"; //写当前路径提示符
hbuf[1] = 'A' + disk_no;
printf(hbuf);
set_cursor_pos(-1,&pmt_pos);
}
void ycttyCLASS::cls()
{
set_cursor_pos(0);
ycio_clear_screen(0,25*80);
}
void ycttyCLASS::keyboard_proc() //该函数被键盘中断服务例程调用(见ycker.cpp)
{
byte *pHead = key_head + 1;
if(pHead == key_buf + sizeof(key_buf)) pHead = key_buf; //到达底部,卷回头部
if(pHead == key_tail) return; //头部等于底部缓冲区满, 忽略键盘输入
*key_head = inb(0x60); //从60h口读键盘数据
key_head = pHead; //设置键盘缓冲区头指针
}
void ycttyCLASS::set_disk(int mval)
{
disk_no = mval;
}
void ycttyCLASS::display_LED(byte capsV,byte numV,byte scrollV)
{
outb(0x60, 0xed);
outb(0x60, (capsV << 2) | (numV << 1) | scrollV);
}
void ycttyCLASS::sys_cursor(int curpos)
{
outb(0x3D4, 0x0E);
outb(0x3D5, (curpos >> 8) & 0xFF);
outb(0x3D4, 0x0F);
outb(0x3D5, curpos & 0xFF);
}
void ycttyCLASS::keyboard_read(int &vk_char,int &vk_value,int &vk_press,
byte &capsL,byte &numL,byte &scrollL,byte &shiftV,byte &altV,byte &ctrlV)
{
auto get_scanCode = []() //可在函数内部定义的lambda局部函数
{
if(key_tail == key_head) return (byte)0; //键盘缓冲区无数据
byte scan_code = *key_tail++; //从键盘缓冲区尾部读出键盘数据
if(key_tail == key_buf + sizeof(key_buf)) key_tail = key_buf;
return scan_code;
};
byte scan_code = get_scanCode();
int bb,ii = scan_code & ~0x80;
vk_press = !(scan_code & 0x80);
static byte vk_buf[] = { 0,VK_ESCAPE,'1','2','3','4','5','6','7','8','9','0',
'-','=',VK_BACK,VK_TAB,'Q','W','E','R','T','Y','U','I','O','P',
'[',']',VK_RETURN,VK_LCONTROL,'A','S','D','F','G','H','J','K',
'L',';','\'','`',VK_LSHIFT,'\\','Z','X','C','V','B','N','M',',',
'.','/',VK_RSHIFT,VK_MULTIPLY,VK_LMENU,' ',VK_CAPITAL,
VK_F1,VK_F2,VK_F3,VK_F4,VK_F5,VK_F6,VK_F7,VK_F8,VK_F9,VK_F10,
VK_NUMLOCK,VK_SCROLL,VK_HOME,VK_UP,VK_PRIOR,VK_SUBTRACT,VK_LEFT,
VK_CLEAR,VK_RIGHT,VK_ADD,VK_END,VK_DOWN,VK_NEXT,VK_INSERT,
VK_DELETE,0,0,0,VK_F11,VK_F12,0,0,0,0,0,0,0,VK_PRINT,VK_PAUSE};
if(ii < sizeof vk_buf/sizeof vk_buf[0]) vk_value = vk_buf[ii];
switch(vk_value)
{
case VK_LSHIFT: case VK_RSHIFT: shiftV = vk_press; return;
case VK_LCONTROL: case VK_RCONTROL: ctrlV = vk_press; return;
case VK_LMENU: case VK_RMENU: altV = vk_press; return;
case VK_PAUSE: for(bb=0; bb<5; bb++) get_scanCode(); break;
case VK_CAPITAL:
case VK_NUMLOCK:
case VK_SCROLL:
if(!vk_press) return;
if(vk_value == VK_CAPITAL) capsL = !capsL;
else if(vk_value == VK_NUMLOCK) numL = !numL;
else scrollL = !scrollL;
YCTTY.display_LED(capsL,numL,scrollL);
return;
}
if(!vk_press) return;
if(vk_value>='A' && vk_value<='Z')
{
vk_char = vk_value;
if(!capsL && !shiftV || capsL && shiftV) vk_char += ' ';
}
auto get_real_key = [ vk_value ](byte *kmap,int pnum)
{
for(int ii=0; ii<pnum/2; ii++) if(kmap[ii*2] == vk_value) return ii*2;
return -1;
};
if(numL)
{
static byte pad_map[] = { VK_HOME,'7',VK_UP,'8',VK_PRIOR,'9',VK_LEFT,'4',
VK_CLEAR,'5',VK_RIGHT,'6',VK_END,'1',VK_DOWN,
'2',VK_NEXT,'3',VK_INSERT,'0',VK_DELETE,'.'};
bb = get_real_key(pad_map,sizeof pad_map/sizeof pad_map[0]);
if(bb >= 0) vk_char = pad_map[bb + 1];
}
if(ii < 0x37)
{
static byte shift_map[] = {'1','!','2','@','3','#','4','$','5','%','6',
'^','7','&','8','*','9','(','0',')','-','_',
'=','+',';',':','\'','"','`','~','\\','|',
',','<','.','>','/','?','[','{',']','}'};
bb = get_real_key(shift_map,sizeof shift_map/sizeof shift_map[0]);
if(bb >= 0) vk_char = shift_map[bb + shiftV];
}
else
{
static byte Amap[]={VK_ADD,'+',VK_SUBTRACT,'-',VK_MULTIPLY,'*',' ',' '};
bb = get_real_key(Amap,sizeof Amap/sizeof Amap[0]);
if(bb >= 0) vk_char = Amap[bb + 1];
}
}
C/C++代码文件: yctty.cpp
转载:https://blog.csdn.net/xiaobingyang/article/details/105009848
查看评论