pc98顯示原理及字型檔rom的訪問方法
此部分的資料幾乎沒有,此文件基本上都是根據分析pc98遊戲和nekoprojectii原始碼得來。疏漏之處還請見諒。
* 指令與中斷
1. 因pc98的晶元是相當於80286的晶元,所以其指令就是8086系列的指令。也就是說,你可以用乙個支援8086的反匯程式設計序來反彙編它的.exe和.com檔案,也可以用turbo c2.0/borland c 3.1 for dos來寫它的程式,只要不涉及具體硬體操作,編譯後放到hdi中一樣可以執行。另外,其實pc98也是可以進入保護模式的,但是我們目前接觸的遊戲幾乎無一用到,而且模擬器貌似也不支援。
2. 因pc98上的dos通常為5.0/6.21等版本,所以其中斷(21h號和13h號等)是通用的。你可以查閱dos中斷手冊(或者著名的helppc)來閱讀它的**。
3. pc98和286純dos最大的區別在於硬體的訪問方式不同。也就是說,turbo c的bgi庫無法通用。理論上若能找到turbo c2.0 for pc98的話,它的bgi庫應該能在pc98上跑。pc98上是內建的顯示晶元,無顯示卡一說,但是pc98也有多種主機型號,它們所用的晶元也有不同,有的甚至是支援256色的。關於音效卡晶元,pc98標配是使用的fm音源,但也有midi口可供擴充套件。
* bios 18h號中斷
這是pc98上有關顯示的所有功能集,有點相當於dos中的10h號中斷。以下只例出有粗略研究的功能:
ah: 子功能號
0: 等待按鍵,並返回掃瞄碼於ax中
1: 取按鍵(無等待),返回值在ax中(bh返回1)。若按鍵緩衝為空,bh返回0。
2: 讀shift鍵狀態
0ah: 設定crt模式(設定文字模式下的列數和字元顏色等)
0bh: 獲取crt模式
0ch: 進入文字模式
0dh: 退出文字模式
10h: 設定游標型別(文字模式下的游標,下同)
11h: 顯示游標
12h: 隱藏游標
13h: 設定游標位置(dx)
14h: 讀字型檔rom(重要!!詳細解釋見後)
1ah: 寫字庫rom(重要!!詳細解釋見後)
40h: 進入圖形模式
41h: 退出圖形模式
42h: 設定圖形模式區域(320x200 or 640x400, ch為區域,引數不詳,可自行嘗試)
43h: 設定調色版(ms是文字狀態下的調色盤,可略過)
* 字型檔rom訪問
兩種方式可以訪問字型檔rom,分別是18h中斷方式和埠訪問方式。遊戲中使用後者較多。
中斷方式:
ah=14h, int 18h 讀字型檔rom
bx=緩衝區segment, cx=緩衝區offset, dx=字元編碼
因為字型檔rom中既有全形又有半形字元,另外也有8x8的英文,所以隨字元編碼不同返回的內容也不同。返回的內容會拷貝到緩衝區中。緩衝區的前兩個位元組(1個word)將會收到表示長度的**。
當dx高8位為0時,讀8x8半形字元(以及8x8片假名,請見jis碼表),此時緩衝區長度**為0x101,後面緊跟8個位元組的畫素資料。(每個點1bit,下同)
當dx高8位為29h,2ah或2bh時,此編碼為8x16 kanji碼。此時緩衝區長度**為0x102,後面緊跟16個位元組的畫素資料。
當dx高8位為80h時,此編碼為8x16的 ank碼。此時緩衝區長度**為0x102,後面緊跟16個位元組的畫素資料。
其餘情況,編碼為shiftjis碼,16x16大小,緩衝區長度**為0x202,後面緊跟32個位元組的畫素資料。
ah=1ah, int 18h 寫字庫rom
bx=緩衝區segment, cx=緩衝區offset, dx=字元編碼
bx:cx指向的緩衝區同ah=14h的緩衝區,提供字型檔資料供寫入rom。
使用此功能可以改變pc98的預設字型或自定義字元。
注:對於anex86和next,dx可為任何編碼;對於nekoprojectii(真實硬體同?),dx的高8位中的第2-7位必須為0x76,即x111011x。另外由於sjis編碼的限制,第0位也必須為0,所以實際上可以寫入的字元僅為188個!這也是目前pc98漢化的重大難題之一(請參閱有關sjis編碼文件中的自定義字元部分http://zh.wikipedia.org/wiki/shift_jis)
埠方式:
先設定要訪問的行,三條指令:
out 0a1h, 字元編碼低8位
out 0a3h, 字元編碼高8位
out 0a5h, 希望訪問的畫素行索引(低4位為0-15,高4位為0表示全形字符的左半邊,為非0表示右半邊)
設定完畢,此時可以讀或寫:
in al, 0a9h 返回該行畫素(8個點)
out 0a9h, al 寫該行畫素(8個點)
舉例來說,要設定編碼0xf040的字模為全白(全為ffh),則使用如下指令:
out 0a1h, 0f0h
out 0a3h, 040h
out 0a5h, 00h ; 第一行左半
out 0a9h, 0ffh
out 0a5h, 01h ; 第二行左半
out 0a9h, 0ffh
out 0a5h, 02h ; 第三行左半
out 0a9h, 0ffh
out 0a5h, 04h ; 第四行左半
out 0a9h, 0ffh
...out 0a5h, 0fh ; 第十六行左半
out 0a9h, 0ffh
out 0a5h, 011h ; 第一行右半
out 0a9h, 0ffh
out 0a5h, 012h ; 第二行右半
out 0a9h, 0ffh
out 0a5h, 013h ; 第三行右半
out 0a9h, 0ffh
...out 0a5h, 01fh ; 第十六行右半
out 0a9h, 0ffh
以上,總共32次寫操作。讀的方式也同樣。只是把out 0a9h改為in 0a9h。
* 位平面的訪問(這裡只討論640x400模式下的位平面訪問)
640x400x16色模式下,每個點應該有4個bit儲存。為了便於顯示卡訪問,它們不是順序儲存在每乙個位元組的高8位和低8位的,而是分散儲存在4個位平面中。
位平面的起始段為a800h, b000h, b800h和e000h。
例如,要在座標0,0處寫乙個顏色索引為7的點,二進位制為0111,那麼其第0,1,2位平面為1,而第3個位平面為0。可使用下面的**:
mov ax, 0a000h
mov es, ax
or byte ptr es:[0], 080h
mov ax, 0b000h
mov es, ax
or byte ptr es:[0], 080h
mov ax, 0b800h
mov es, ax
or byte ptr es:[0], 080h
mov ax, 0e000h
mov es, ax
and byte ptr es:[0], 07fh
你可以看到每個位平面的乙個位元組都有8個點的資料,所以為了不動其它的點我們必須使用位操作。這個例子比較簡單是因為它的座標是(0,0)所以位址不用計算。在640x400的模式下,每乙個位平面的一行有80個位元組,一共是640個點。所以座標和位址的計算方式你應該能簡單算出來。通常在破解時跟蹤到乘以50h或累加50h的操作時就可以先猜測一下是不是在計算顯示座標,很可能你就猜中了哦!
* 調色盤的訪問
理論上是可以用bios中斷來訪問的,但是目前我對此沒有研究。這裡給出埠方式:
out 0a8h, 調色盤索引(0-15)
out/in 0aah, red (0-15)
out/in 0ach, green (0-15)
out/in 0aeh, blue (0-15)
注意:和普通帶ega顯示卡的80286系列不同,pc98是4096色的,每個調色盤值僅有4位。而ega/vga顯示卡是6位。
2009/12/30: 位平面起始段修改(特別感謝:yusjoel)
2011/05/03: 40x400 => 640x400(特別感謝:slughterman)
套接字程式設計原理及例程
套接字 英文為socekt,是乙個指向傳輸提供者的控制代碼。套接字分為 原始套接字 流式套接字和資料報套接字三種。原始套接字 能夠給是程式開發人員對底層的網路傳輸機制進行控制,在原始套機子下接收的資料匯中含有ip頭 流式套接字 提供雙向 有序 可靠的資料傳輸服務,該型別套接字在通訊前需要雙方建立連線...
手機瀏覽pc網頁,字型顯示比樣式中設定的字型更大
用手機訪問專案的乙個內容頁時,正文的字型比邊欄的字型要大,但是樣式中他們的font size大小是一樣的。其中的 片段如下 alt 連續的 style width 80 11 div style height 20px 連續的 div 12 p 一直 p 13 p style font size 1...
PC機控制簡訊收發裝置原理及實現 1
最近公司某部門要在管理系統中整合簡訊收發功能,任務落到我頭上,雖然簡訊平台並不是什麼新鮮事,買裝置也能提供二次開發庫,但之前沒接觸過,於是也很投入地作了學習和研究。起初很神秘很刺激,在網上一通搜,發現純收發簡訊功能其實並不複雜,也就是通過串列埠把at 指令傳送到簡訊收發裝置,然後從串列埠讀取傳回的資...