修改asmhead.nas畫面模式的設定,只考慮支持QEMU模擬器的顯卡:
; 設定畫面模式 MOV BX,0x4101 ; VBE的640x480x8bi彩色 MOV AX,0x4f02 INT 0x10 MOV BYTE [VMODE],8 ; 記下畫面模式,參照C語言 MOV WORD [SCRNX],640 MOV WORD [SCRNY],480 MOV DWORD [VRAM],0xe0000000
運行:
我們不能斷定真機上使用上的是什麼顯卡,有的公司尚未與VESA合作,如果是這種公司的產品,不能使用VBE。
asmhead.nas節選:
; 確認VBE是否存在 MOV AX,0x9000 MOV ES,AX MOV DI,0 MOV AX,0x4f00 INT 0x10 CMP AX,0x004f JNE scrn320
; 檢查VBE的版本 MOV AX,[ES:DI+4] CMP AX,0x0200 JB scrn320 ; if (AX < 0x0200) goto scrn320
; 獲取畫面模式信息 MOV CX,VBEMODE MOV AX,0x4f01 INT 0x10 CMP AX,0x004f JNE scrn320
; 畫面模式信息的確認 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 ; 模式屬性的bit是0,所以放棄
; 畫面模式的切換 MOV BX,VBEMODE+0x4000 MOV AX,0x4f02 INT 0x10 MOV BYTE [VMODE],8 ; 記下畫面模式,參考C語言 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
scrn320: MOV AL,0x13 ; VGA圖,320x200x8bit彩色 MOV AH,0x00 INT 0x10 MOV BYTE [VMODE],8 ; 記下畫面模式(參考C語言) MOV WORD [SCRNX],320 MOV WORD [SCRNY],200 MOV DWORD [VRAM],0x000a0000
不滿足顯卡的高分辨率設定時只能使用我們之前的scrn320模式了。
運行:
畫面還是蠻大的,而且分辨率也挺高的。
我們按下鍵盤上的A鍵的時候我們希望它能顯示出a這個字符出來:
只需要判斷下鍵盤中斷髮送的數據是否爲A的通碼即可,運行:
我們將鍵盤輸入字符封裝在一個靜態字節數組中,靜態字節數組會被編譯爲DB命令,每當有鍵盤輸入時,我們去查這個靜態字節數組即可:
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', '.' };
運行:
追加內容也沒那麼難,只需每次寫入一個字符的時候將光標往前移動一位,下一個字符寫入的位置即光標當前位置,對於退格鍵只需將當前字符設置爲" "後將光標後移1位即可:
其中bootpack.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; }
運行:
只需在按下鼠標的左鍵,並且鼠標移動的狀態下重新繪製窗體即可實現移動效果:
運行效果: