bloggerads

顯示具有 DOS 標籤的文章。 顯示所有文章
顯示具有 DOS 標籤的文章。 顯示所有文章

2017年2月5日 星期日

DOS : Legacy Graphic Output Control

在Dos下想輸出文字到螢幕上,除了呼叫C/C++提供的函數 printf, cout 或 Bios提供的軟體中斷 int 10, 是否有直接控制硬體的方法呢?  答案是有的,可以直接把要顯示的資料搬到A/B Segment。用以下的code來做範例 (Compile using Watcom)

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;

 enum Colour{ BLACK=0, BLUE, GREEN, CYAN, RED, MAGNETA, BROWN, LGRAY, \
   DGRAY=8, LBLUE, LGREEN, LCYAN, LRED, LMAGNETA, YELLOW, WHITE};
 
#define COLOUR(forecolour, backcolour)  ((backcolour) << 4 | (forecolour) & 0x0F)

 void WriteString(int y, int x, BYTE colour, char *string)
 {
     volatile WORD *pvram;
     
     for (DWORD i=0;string[i]!=0; x++, i++) {
       pvram = (volatile WORD *)0xB8000 + y * 80 + x;
       *pvram = (BYTE)string[i] | colour << 8;
     }
 }
 

 void WriteCharacter(int y, int x, BYTE colour, BYTE ch)
 {
      volatile WORD * pvram;
      pvram = (volatile WORD *)0xB8000 + (y * 80 + x) ;
      *pvram = ch | (colour << 8);
 }

 int main()
{
     WriteCharacter(1,0, COLOUR(RED, BLACK), 'H');    
     WriteCharacter(1,1, COLOUR(RED, BLACK), 'i');
     WriteString(1, 3, COLOUR(GREEN, BLACK), "Martin.");
}

在螢幕座標(y,x) = (1, 0) 秀出 Hi Martin.


ps. 如果想畫一個點陣圖請參考 mode 13h, 解析度為320*200, 256色, 透過寫入A000:0來完成


題外話, 我用了以上的技巧寫了一個Dos版的source code Editor, 名稱叫E editor (下圖)。 平常工作時都會開個Dos模擬器跑Dos tool,享受Dos單純的美。



Key:
F1: Copy Line
F2: Paste Line
F3: Delete Line
F10: Save File

下載: (password: martinlee)

E Editor

2017年1月13日 星期五

DOS : Increase Dosbox screen size in Windows

Step 1. Find dosbox-0.74.conf

Step 2. Modify the SDL part in the dosbox-0.74.conf


[SDL]

fullscreen=false 
fulldouble=false 
fullresolution=original 
windowresolution=1024x768 
output=ddraw 
autolock=true 
sensitivity=100 
waitonerror=true 
priority=higher,normal 
mapperfile=mapper.txt 
usescancodes=true 

ps. Some Dos application may consume lot of CPU usage. Fix it by Setting a fixed CPU cycles, for example, 16000.
[CPU]
cycles=auto 
cycles=16000

2016年1月14日 星期四

Hook my own interrupt vector in DOS

因為工作上需要驗證中斷的tool, 所以把塵封已久的Watcom DOS程式拿出來改。以下是一個基本的掛中斷、呼叫中斷、移除中斷的範例
// Author: Martin Lee  

 #include <stdio.h>
 #include <conio.h>
 #include <dos.h>

 #define getvect(n) _dos_getvect(n)

 #define setvect(n,v) {\
   _disable();\
   _dos_setvect(n,v);\
   _enable();\
 }

 #define HOOKVECTOR 0x7F

 int sig;

 void interrupt  (*origin_int)();

 void interrupt handle_7Fh(void)
 {
     sig=1;
     //_chain_intr( origin_int); // not execute original vector
 }

 void hook_int(void)
 {
     origin_int = getvect(HOOKVECTOR);
     setvect (HOOKVECTOR, handle_7Fh);
 }

 void restore_int(void)
 {
     setvect(HOOKVECTOR,origin_int);
 }

 void main()
 {
     sig = 0;

     hook_int();

     printf("Before int 7fh, sig = %d\n", sig);

     __asm  int 7Fh    
   
     printf("After int 7fh, sig = %d\n", sig);
       
     restore_int();
   
 }

----------------------執行結果-----------------------------
Before int 7fh, sig = 0
After int 7fh, sig = 1


2015年9月14日 星期一

DOS boot menu problem (autoexec.bat + exe file )

在dos下想要做選單連結一些執行檔,但是將執行檔路徑寫在autoexec.bat 常常會碰到顏色花掉以及執行完執行檔卻回不了DOS的問題。
原因是因為在執行autoexec.bat時DOS initial還沒完成(還必須設定VGA mode跟執行int 21h回到Dos),因此autoexec.bat內不能直接執行用C寫的程式,要先寫執行一個組合語言寫的程式切video mode 以及呼叫DOS中斷來回到DOS,才會完整跑完DOS initial的流程。
在autoexec.bat最前面先放以下這隻程式,之後再跑其他的C語言寫的執行檔都能順正常執行,執行完後也能順利回到DOS

2014年7月25日 星期五

在DOS下寫程式常會用到的中斷 (to DOS愛好者)

現在還在用Dos的人其實不少只是比較不顯眼 :P ,就我知道幾乎所有的x86系統在開發過程中,還是以Dos tool來驗證chipset問題。(畢竟誰會這麼閒重新在UEFI shell上開發以前在Dos下沒問題的程式XD)

我也是Dos的愛用者,開發過的Dos測試程式比在其他作業系統上的測試程式多得多,寫程式的功力也是從這邊開始練起。

基本上使用Watcom若是default使用protect mode, 那麼寫Dos程式幾乎跟在windows上感覺差不多,但是Watcom可以透過inline assembly神不知鬼不覺地使用原始 real mode 的中斷。

由於中斷很多,這篇僅列出我常使用的中斷給大家參考:

1. Access PCI configuration: INT 1A

提供範例函數來讀取PCI cfg data:
+
+  //Author: Martin Lee
+   const unsigned char PCI_FUNCTION_ID= 0xB1;
+   const unsigned char READ_CONFIG_DWORD 0x0A
+   
+   DWORD READ_PCI_CONFIG_DWORD(WORD BDF, WORD index)
+   {
+   
+      DWORD data;
+       __asm
+       {
+       // 1AB109 INT 1A - PCI BIOS v2.0c+ - READ CONFIGURATION WORD
+       // BH = bus number
+       // BL = device/function number (bits 7-3 device, bits 2-0 function)
+       // ECX = dword read
+       mov     BX,  BDF
+       mov     di,  index
+       mov     ah,  PCI_FUNCTION_ID
+       mov     al,  READ_CONFIG_DWORD
+       int     1ah
+       mov     data, ecx
+       }
+       return data;
+   }

2. 對碟機做讀寫: INT 13

3. 設定螢幕的顏色游標什麼的: INT 10 (Watcom有很多內建的函數可以使用,使用上方便又美觀), 像我這個介面就完全是呼叫Watcom 的library做的

(待續)

2014年3月19日 星期三

ASCII table

因為常在DOS下寫測是程式,總是會加上一些ASCII做的文字方塊,每次都是寫code再一邊查ASCII。
乾脆把表放上來,方便參考

這張圖片取自網站(This photo is originally from the website as follow):
https://commons.wikimedia.org/wiki/File:Ascii-codes-table.png
http://www.theasciicode.com.ar/ascii-printable-characters/lowercase-letter-h-minuscule-ascii-code-104.html

2014年1月3日 星期五

WATCOM C 使用教學

Watcom官網download watcom編譯器 (1.9版, 2010),安裝完後會在"開始"出現IDE的圖示, 開啟它


先到File->New Project新增一個project (預設為noname),然後選你要編譯成哪種環境下執行的應用程式。我主要是用Watcom編譯DOS程式,而且我要直接跑在protect mode上,因此選擇DOS - 32 bit。至於要用哪種方法進入32位元,我比較常選的是PMODE/W  Executable(.exe), 這個執行檔執行時會自行先進入protect mode。
另一個選擇是 DOS/4GW Executable(.exe), 編譯成這個執行檔則程式的運行是寄生在DOS/4GW下,因此必須把dos4gw.exe放在同個目錄下程式才能正確執行。


 環境選擇好了就在白色處點右鍵,加入你寫的.c/.h/.cpp/.hpp檔


最後點選紅色框框處來執行,若編譯沒問題,就會產生一個noname.exe檔案了


完成。