Appearance
day14高分辨率以及键盘输入
提高系统的分辨率
assembly
; 画面
MOV BX,0x4101
MOV AX,0x4f02
INT 0x10 ; 使用这两个数字就可以进行调整
MOV BYTE [VMODE],8 ; 保存画面的信息
MOV WORD [SCRNX],640
MOV WORD [SCRNY],480
MOV DWORD [VRAM],0xe0000000
在最初的时候, 所有的公司使用的是IBM公司的标准, 但是之后有的公司制作的显卡的性能超过了IBM, 使得自己设定显卡的模式设定, 之后VESA协会出台, 制作专门的BIOS, 可以利用它进行提高分辨率, 成为VBE
切换到不适用VBE的模式, 设置AH=0, AL=画面号码, 使用AH=0x4f02, BX=画面号码
- 0x101 640x480 8bit
- 0x103 800x600 8bit
- 0x105 1024x768 8bit
- 0x107 1280x1024 8bit
在虚拟机使用的时候需要加上0x4000
assembly
; 检测VBE是否存在
MOV AX,0x9000
MOV ES,AX
MOV DI,0
MOV AX,0x4f00
INT 0x10
CMP AX,0x004f
JNE scrn320
存在的话AX会变为0x004f
assembly
MOV AX,[ES:DI+4]
CMP AX,0x0200
JB scrn320 ; if (AX < 0x0200) goto scrn320
检测版本, 版本过低就进行跳转
assembly
MOV CX,VBEMODE
MOV AX,0x4f01
INT 0x10
CMP AX,0x004f
JNE scrn320
在这里检测模式是否可用, 信息会被放在[ES:DI]开始的256个字节里面
- [ES:DI + 0x00] 模式的属性, bit7是1, 因为在设置的时候需要加上0x4000
- [ES:DI + 0x12] X的分辨率
- [ES:DI + 0x14] Y的分辨率
- [ES:DI + 0x19] 颜色数
- [ES:DI + 0x1b] 颜色的指定方法, 必须为4
- [ES:DI + 0x28] VRAM的地址
assembly
CMP BYTE [ES:DI+0x19],8
JNE scrn320
CMP BYTE [ES:DI+0x1b],4
JNE scrn320
MOV AX,[ES:DI+0x00]
AND AX,0x0080
JZ scrn320 ; bit7是0所以放弃
对信息进行确认, 失败的话仍使用原来的模式
assembly
MOV BX,VBEMODE+0x4000
MOV AX,0x4f02
INT 0x10
MOV BYTE [VMODE],8 ; 进行切换
MOV AX,[ES:DI+0x12]
MOV [SCRNX],AX
MOV AX,[ES:DI+0x14]
MOV [SCRNY],AX
MOV EAX,[ES:DI+0x28]
MOV [VRAM],EAX
JMP keystatus
切换之后记录下各种信息
键盘输入
键盘按下抬起的时候传回去不同的数字
c
if (256 <= i && i <= 511) { /* 处理的数字来自键盘 */
sprintf(s, "%02X", i - 256);
putfonts8_asc_sht(sht_back, 0, 16, COL8_FFFFFF, COL8_008484, s, 2);//打印出得到的数字
if (i == 0x1e + 256) {
putfonts8_asc_sht(sht_win, 40, 28, COL8_000000, COL8_C6C6C6, "A", 1);//获得的按键是A
}
}
对键盘的数字进行处理
c
static char keytable[0x54] = {
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^', 0, 0,
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', 0, 0, 'A', 'S',
'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0, 0, ']', 'Z', 'X', 'C', 'V',
'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1',
'2', '3', '0', '.'
};
if (256 <= i && i <= 511) { /* キーボードデータ */
sprintf(s, "%02X", i - 256);
putfonts8_asc_sht(sht_back, 0, 16, COL8_FFFFFF, COL8_008484, s, 2);
if (i < 256 + 0x54) {
if (keytable[i - 256] != 0) {
s[0] = keytable[i - 256];
s[1] = 0;
putfonts8_asc_sht(sht_win, 40, 28, COL8_000000, COL8_C6C6C6, s, 1);
}
}
}
实现退格
c
if (256 <= i && i <= 511) { /* キーボードデータ */
sprintf(s, "%02X", i - 256);
putfonts8_asc_sht(sht_back, 0, 16, COL8_FFFFFF, COL8_008484, s, 2);
if (i < 0x54 + 256) {
if (keytable[i - 256] != 0 && cursor_x < 144) { /* 通常文字 */
/* 文字进行显示 */
s[0] = keytable[i - 256];
s[1] = 0;
putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, s, 1);
cursor_x += 8;//设置打印的位置
}
}
if (i == 256 + 0x0e && cursor_x > 8) { /* バックスペース */
/* 如果这个是退格键, 这是为了删去光标 */
putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, " ", 1);
cursor_x -= 8;
}
/* 光标再次显示 */
boxfill8(sht_win->buf, sht_win->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);
sheet_refresh(sht_win, cursor_x, 28, cursor_x + 8, 44);
}
c
// 这个函数是在窗口中绘制一个文本框
void make_textbox8(struct SHEET *sht, int x0, int y0, int sx, int sy, int c)
{
int x1 = x0 + sx, y1 = y0 + sy;
boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 2, y0 - 3, x1 + 1, y0 - 3);
boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 3, y0 - 3, x0 - 3, y1 + 1);
boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x0 - 3, y1 + 2, x1 + 1, y1 + 2);
boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x1 + 2, y0 - 3, x1 + 2, y1 + 2);
boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 1, y0 - 2, x1 + 0, y0 - 2);
boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 2, y0 - 2, x0 - 2, y1 + 0);
boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x0 - 2, y1 + 1, x1 + 0, y1 + 1);
boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x1 + 1, y0 - 2, x1 + 1, y1 + 1);
boxfill8(sht->buf, sht->bxsize, c, x0 - 1, y0 - 1, x1 + 0, y1 + 0);
return;
}
增加鼠标移动窗口
c
if (512 <= i && i <= 767) { /* マウスデータ */
if (mouse_decode(&mdec, i - 512) != 0) {
/* データが3バイト揃ったので表示 */
sprintf(s, "[lcr %4d %4d]", mdec.x, mdec.y);
if ((mdec.btn & 0x01) != 0) {
s[1] = 'L';
}
if ((mdec.btn & 0x02) != 0) {
s[3] = 'R';
}
if ((mdec.btn & 0x04) != 0) {
s[2] = 'C';
}
putfonts8_asc_sht(sht_back, 32, 16, COL8_FFFFFF, COL8_008484, s, 15);
/* 记录鼠标的移动 */
mx += mdec.x;
my += mdec.y;
if (mx < 0) {
mx = 0;
}
if (my < 0) {
my = 0;
}
if (mx > binfo->scrnx - 1) {
mx = binfo->scrnx - 1;
}
if (my > binfo->scrny - 1) {
my = binfo->scrny - 1;
}
sprintf(s, "(%3d, %3d)", mx, my);
putfonts8_asc_sht(sht_back, 0, 0, COL8_FFFFFF, COL8_008484, s, 10);
sheet_slide(sht_mouse, mx, my);
if ((mdec.btn & 0x01) != 0) {
/* 鼠标左键按下 */
sheet_slide(sht_win, mx - 80, my - 8);
}
}
}