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

2013年2月20日 星期三

menuetOS interview

http://www.goodgearguide.com.au/article/315421/we_talk_developer s_behind_menuetos_an_operating_system_written_entirely_assembly_ language/?pp=4

MenuetOS 是英國軟體工程師Mike Hibbett利用業餘時間,編寫網路程式的部分!

MenuetOS由芬蘭人Ville Turjanmaa開發,是一個操作系统,用於和IBM PC相容的電腦。它由汇編語言寫成,可以存入一隻1.44MB的软盘中。介面華麗,可以勝任文本編輯,播放CD。

MenuetOS使用的組合語言組譯器為免費的Flat Accembler

http://www.menuetos.net/index.htm 
http://www.menuetos.net/faq.txt
http://phlashback.blog.hexun.com.tw/4294535_d.html 常見問題


MenuetOS 是 GEOS( http://www.osnews.com/story.php/15223/)這套作業
 系統的『現代版』完全以 32/64bit 的組合語言打造!!它與其他作業系統
 (如 UNIX)不同,也沒有遵循其他 posix 標準。它的設計目標是省略了層
 層相疊錯綜複雜的架構,因為那會使程式寫作更加複雜化,並且製造臭蟲。
 不過,Menuet 的應用程式架構不只是專為組合語言而寫,它的標頭(
 header)可以與其他任何程式語言並行。不過,這整個環境還是為 64/32 
 bit 的組語程式設計環境打造的。Menuets 敏捷的 GUI 很容易用組合語言
 掌控。使用GNU通用公共许可证發放。

MenuetOS的两位开发者Ville Turjanmaa和Madis Kalme接受PC World Australia的采访,谈论了是什么激励他们去着手去做这样一个令人畏惧的任务,以及操作系统的现状和未来。

Ville称开发操作系统的最初源由是:某日他上网浏览,打开了一个包含脚本语言的网页,然而短短的一段脚本却执行起来无比缓慢,他决定寻找极端的 方法,尽可能多的用汇编语言.....MenuetOS的32位版本采用GPL发布,但64位版本没有使用开源许可证,个人或教育使用则是免费的。开发者 还没有制定1.0版的发布时间表,他们还需要加入新驱动程序和改进现有应用,增加新特性。


 特色

 - Pre-emptive multitasking 先佔式多工
 - Responsive GUI with resolutions up to 1280x1024, 16 million 
   colours 反應快速的 GUI,解析度可達 1280x1024 全彩。
 - IDE: Editor/Macro Assembler for applications 應用程式的組合語言
   開發環境。
 - TCP/IP stack with Loopback & Ethernet drivers 具有 Loopback 與乙
   太網路的 TCP/IP 堆疊。
 - Network applications include ftp/http/mp3 servers 網路相關的應用
   包括 ftp/http/mp3 servers
 - Free-form application windows 應用軟體視窗外觀沒有任何限制
 - Hard real-time data fetch 夠猛的 real-time 資料取得
 - Fits on a single floppy 一張磁片就能裝下 ^^
 - 在上面玩 Quark?OK 啦~
 - 有DOS模式,貼幾款令人懷念的遊戲:
   Doom
   http://www.menuetos.org/displays/mdoom5-small.jpg
   波斯王子
   http://www.menuetos.org/displays/077p-small.png


install to usb drive
1. goto the menuetos website and download the .img file of menuetos
2. winimage(will only write a floppy image to a floppy) to write it to your usb drive.
3. change your motherobard options to boot from whatever drive the usb drive is.

如何設計簡單的作業系統



這份文件將教你如何撰寫與建立你的第一個作業系統,使用x86組合語言。它將說明你需要什麼,PC啟動過程的基礎,與組合語言。完成的作業系統很小(足以進入一個啟動載入器)且有很少的功能,但是它是一個好的開始。

你閱讀完這份教學後,可以查看MikeOS專案,它是一個x86組合語言的作業系統,你可以閱讀它來增進你的技術。

需求

有程式設計經驗是必須的。假如你已經有過高階語言設計的經驗,像是PHP或Java,但你將會需要低階語言的經驗像是C,特別是記憶體或是指標的主題。

這個教學中我們使用Linux作業系統。作業系統的開發也可以在Windows,但是它並不像Linux這般容易,在Linux中你可以取得一個完整的工具箱。Linux也能容易地建立磁碟片與CD-ROM影像檔─你不需要安裝繁瑣的程式。

在今天安裝Linux是很容易的;假如你想要雙系統,你可以取得Ubuntu並安裝它到VMware或VirtualBox。當你進入到Ubuntu,你可以參考這份教學,進入終端機視窗並取得所有需要的工具:

sudo apt-get install build-essential qemu nasm

這個指令你將取得開發工具箱(編譯器等等)。QEMU 電腦模擬器與NASM組譯器,它將轉換組合語言為機器能執行的語言。

PC入門

假如你要撰寫一個x86電腦的作業系統(這是個好選擇,因為有大量文件可以供你參考),你將需要了解一部個人電腦的啟動流程。幸運地,你不需要深入知道複雜的主題,像是圖形驅動程式或網路協定,你將專注於需要的部分。

當一部個人電腦開機,它會執行BIOS(基本輸入輸出系統),是一個迷你的作業系統被建置在系統中。它實現一些硬體的測試(例如記憶體檢查)和噴射出圖形(例如Dell圖標)或檢測文字到螢幕上。之後,當它做完了,它會啟動並載入作業系統,從任何可以找到作業系統的媒體。許多個人電腦會跳到硬碟,並啟動他們在Master Boot Record(MBR)中找到的可執行碼,一個硬碟開始的512位元組區段;有些會試著在磁片(boot sector)或CD-ROM中找到可執行碼。

這是根據啟動順序─你可以在BIOS的選項螢幕中設定他們。BIOS從所選擇的媒體中載入512位元組到它的記憶體,並開始執行它。這是一個啟動載入器,這隻小程式會載入主要的作業系統核心或一個大的啟動程式(例如Linux系統中的GRUB/LILO)。這個512位元組的啟動載入器後面有兩個特別的數字,用來告訴作業系統它是一個啟動區域,我們將在之後介紹。

個人電腦的啟動是一個有趣的特色。歷史上,許多個人電腦有磁片,所以能從BIOS中設定為啟動媒體。時至今日,然而,許多個人電腦不再使用磁片裝置─只有使用CD-ROM─為了迎合它。當你從CD-ROM啟動,它將會模擬一個磁片裝置;BIOS讀取CD-ROM裝置,載入大量的資料,執行它像是一個磁片裝置。這對於我們作業系統的開發者而言不是有用的,當我們為我們的作業系統建立磁片,但仍然是在只有CD的機器啟動它。(磁碟裝置是較容易處裡的,但CD-ROM的檔案系統就不是這麼簡單了)

所以,啟動過程是;
1. 給電:個人電腦啟動,並開始執行BIOS程式碼。
2. BIOS查看許多媒體像是磁片裝置或硬碟。
3. BIOS載入一個512位元組的啟動磁區從指定的媒體並開始執行它。
4. 512位元組然後載入作業系統,或者是一個更複雜的啟動載入器。

對於MikeOS而言,我們有一個512位元組的啟動載入器,那裡我們寫入一個磁片映像檔(一個虛擬的磁片)。我們能注射磁片映像檔到CD,所以個人電腦只要有CD-ROM裝置就可以執行。
另一種方式,BIO載入它,假如它在一個磁片上,開始執行它。我們就能控制系統。

組合語言入門

許多現代的作業系統都使用C/C++撰寫。這是個好用且具有移植性且容易維護的語言,但是它也增加了許多複雜的層。對於你的第一個作業系統,你最好從組合語言做起,它也被使用在MikeOS。它是很冗長的且沒有移植性的,但你不用擔心編譯器或連結器的問題。此外,你需要了解一點組合語言。

組合語言(簡稱asm)是用文字的方式來表示CPC執行的一段指令。例如:一個指令用來移動一些記憶體到CPU可能是11001001 01101110─但是這是很難閱讀的!所以組合語言提供可以記憶的方式來取代這些指令,像是mov ax,30。有了他們就不用使用無意義的二進位數字。

就像許多程式語言,組合語言有一個指令列表。你可以跳躍到不同的地方,且能這定副函式與方程式。你不能只是印出"Hello world"到螢幕上─CPU不懂螢幕上的什麼!換句話說,你需要對記憶體工作,操作一堆RAM,執行運算,並將結果放到對的位置。聽起來很複雜嗎?

在組合語言階層,這裡沒有高階語言裡面所說的變數的觀念。然而有的只是一堆暫存器,在CPU記憶體中。你可以放數字到暫存器中,並執行計算。在16位元模式中,這些暫存器可以放0到65535個數字。這裡有一個對於x86CPU的基本暫存器列表:


MikeOs使用者手冊

執行

使用
當MikeOS啟動,你將會看到一個對話方塊,用來顯示一個程式選項列表。用游標鍵和Enter鍵,選擇OK進入或Cancel取消。

在程式列表中,你可以選擇一個.BIN或.BAS的程式,使用上下游標鍵和Enter鍵來執行他。你也可以按下Esc來回到之前的選項列表。

在指令行中,輸入DIR可以顯示程式列表,且HELP可以顯示內建的指令。你可以輸入全路徑名來執行一個程式。(例如EDIT.BIN)或指輸入名稱不需要延伸檔名(例如EDIT)。那裡也有檔案管理的指令像是COPY, REN, DEL和SIZE。

程式
MikeOS包含許多程式用來執行各種不同的任務,並證明作業系統的特色,像是:
EDIT.BIN -- 簡單的全螢幕文字編輯器 (只支援Unix類型的文字檔案)
EXAMPLE.BAS -- BASIC特色的證明 (用EDIT.BIN開啟它來瀏覽)
FILEMAN.BIN -- 在磁片中,執行刪除,重新命名並複製檔案的動作
HANGMAN.BIN -- 猜猜看世界城市的名字
MEMEDIT.BAS -- 富顏色的,強大的記憶體編輯器
DRAW.BAS -- ASCII藝術繪圖程式
CALC.BAS -- 簡易的計算機
MIKETRON.BAS -- Tron類型的遊戲
KEYBOARD.BIN -- 音樂鍵盤;使用最下面一列的鍵盤來操作,且按下Q來離開程式
MONITOR.BIN -- 簡易的機器碼監視器 (查閱下面)
SERIAL.BIN -- 似Minicom的序列終端程式 (查閱下面)
VIEWER.BIN -- 檢視文字檔案和 320x200x16 PCX 影像,像是 SAMPLE.PCX
註記:檔案FILEMAN.BIN和EDIT.BIN會試圖寫入磁片,所以假如你使用CD-R啟動且試圖操作檔案時,你將會看到寫入錯誤的訊息,因為他是個唯讀的媒體。

複製檔案

假如你將MikeOS寫到一個磁片,你可以經由檔案總管複製額外的檔案到磁片。但假如你想要新增檔案到磁片影像,就需要一點功夫了─你需要存取磁片影像。首先在Linux中:切換到MikeOS主要目錄,然後用root輸入下列指令:
mkdir looptmp
mount -o loop -t vfat disk_images/mikeos.flp looptmp
現在MikeOS虛擬磁片影像的內容就能在新建立的目錄looptmp/底下存取。﹝我們用loopback-mounted磁片影像到我們的檔案系統。﹞複製你的程式到目錄下,例如:
cp MYPROG.BIN looptmp/
當你完成後,unmount虛擬磁片影像並移除暫存目錄:
{{{
umount looptmp
rm -rf looptmp
}}}
現在你就可以寫入mikeos.flp到一個磁片或在模擬器中啟動它。假如你想重新建立CD ISO的影像,用root執行build-linux.sh;這將用新的磁片內容更新mikeos.iso。

假如你在Windows下複製檔案,你將需要一個特別的程式來存取mikeos.flp。你將使用到的工具是ImDisk Virtual Disk Driver;下載並執行它以安裝。之後你就能掛載磁片影像如:
{{{
imdisk -a -f mikeos.flp -s 1440K -m B:
}}}
複製你的檔案到B:槽。當你完成後,輸入;
{{{
imdisk -d -m B:
}}}
現在檔案都複製到B:且寫入mikeos.flp了。

監視器
Yutaka Saito貢獻了一個MikeOS程式,讓你能輸入16進制的機器語言並執行他。從指令行中執行MONITOR.BIN,且你將得到一個'='提示字元。現在你可以輸入你的指令,或按下'x'離開回到作業系統。

MikeOS程式載入到32K(32768)的位置。監視器轉換16進制碼並執行他在RAM中的36864的位置─在監視器程式載入的4K之後。因此你的程式碼不會覆蓋到監視器!

序列阜
你可以像一個類Minicom的序列終端模擬器來使用MikeOS。
這能讓你連接到一部MikeOS機器,例如,一部UNIX機器,從MikeOS中操作Unix機器。連接一條序列(null-moden)線在兩 台機器之間,然後設定你的unix機器讓序列阜使用一個終端會議。


例如,假如你有一台linux機器,你可以新增一行到/etc/inittab檔案中:
TO:2345:respawn:/sbin/getty/ -L ttyS0 9600 vt100

當你重新啟動Linux機器,它將在序列阜等待登入。連接null-moden線到MikeOS機器,並在MikeOS中執行SERIAL.BIN。 你就能輸入你的名字和密碼並登入它。

備註:MikeOS須設定序列阜為9600 baud,no parity , 8 data bits, 1stop bit。假如你想要改變這些設定值,可以編 輯source/features/serial.asm,查看在檔案開始的阜設定碼(然後重新建置MikeOS描述在系統開發者手冊)。只有 VT100指令能夠實現,所以程式不能在螢幕上做複雜的事情(像Emacs)就無法正確的顯示。

要離開程式,須按下F8鍵。(你可以改變為其他的鍵,藉由修改程式碼路徑在programs/serial.asm)

MikeOS組譯程式開發者手冊

這份文件用來解釋如何用組合語言來開發MikeOS的軟體。他將說明所需要的工具,即MikeOS程式是如何運作的。和使用核心所提供的系統呼叫。假如你有任何問題,可以參考MikeOS網站中有連絡的細節與信箱列表資訊。
點擊左邊的連結來瀏覽這份文件。

概觀
介紹
許多MikeOS程式在16位元下撰寫,真實模式的組合語言。(作業系統也包含一個BASIC解譯器)因為MikeOS和他的程式被放在單一個64K記憶體區段,你不需要關注使用的區段暫存器。
MikiOS程式載入到32K 點(32768)的區段,且最大為32K。結果,你的程式將會用下面這兩行做開頭:
BITS 16
ORG 32768
在MikeOS中有許多系統呼叫用來控制螢幕,取得輸入,操作字串,載入/儲存檔案等等。所有的MikeOS系統呼叫通過對暫存器傳遞參數,而非堆疊。要在你的程式中使用它,你需要;
%INCLUDE "mikedev.inc"

這沒有包含任何碼,但會有等同的指令指向核心中的系統呼叫向量。所以,引入這個檔案你才能呼叫。MikeOS的os_print_string常式不用確實知道他在核心的哪個位置。mikedev.inc被包括在MikeOS下載中的programs/目錄─他也提供一個對系統呼叫的快速參考。

假如一個MikeOS程式在指令行下執行,一個或多個參數被提供給指令,他們會藉由SI暫存器傳遞給程式通過一個零結束的字串。

需要的工具

寫下MikeOS程式你需要:
NASM ─ 一個強大,免費且開放原始碼的組譯器
mikedev.inc ─ 系統呼叫向量描述在上面
一個方式新增程式到磁片

細節是:MikeOS使用NASM在他的程式和核心程式碼,所以我們在這裡推薦他。當然你可以使用任何組譯器來輸出二元檔案且接受16位元碼。NASM在許多Linux系統中可以取得,或你也可以從這裡下載Windows版本(取得'win32'檔案)。

第二點,複製programs/mikedev.inc 

第三點,假如你要寫入MikeOS到實體硬碟,你只要複製你的.BIN程式到磁片上(僅有根目錄),啟動MikeOS並測試他。假如你在虛擬mikeos.flp磁片影像下工作,可以查看使用者手冊中的複製檔案。

例子

程式碼

這裡有一個MikeOS程式的範例,使用NASM格式,用來印出一段文字到螢幕上,且等待使用者按下一個按鍵:

BITS 16
    ORG 32768
    %INCLUDE 'mikedev.inc'

start:
    mov si, mystring
    call os_print_string

    call os_wait_for_key

    ret

    mystring db 'My first MikeOS program!', 0

建置

將上面的程式儲存為testapp.asm,並輸入指令來組譯他(在Windows和Linux都適用):
nasm -f bin -o testapp.bin testapp.asm

使用-f bin選項用來告訴NASM,我們想要一個二元檔案:沒有標頭或片段。結果的可執行檔是testapp.bin,我們可以複製到我們的磁片或加入到虛擬磁片影像,描述在使用者手冊中的複製檔案。然後我們可以啟動MikeOS並執行程式。

解釋

這是一個簡短的程式,但是我們將描述他是如何工作的。最初的三行不能被組譯為機器碼指令,但是這個宣告告訴NASM我們要在16位元模式下操作,我們的碼被寫入執行從32K的位置,我們將使用MikeOS API中的系統呼叫。

接下來,我們有一個'start:'標籤,他能讓我們的程式更清楚。我們放入零結束字串的位置到SI暫存器,然後呼叫MikeOS中的os_print_string常式,我們能存取藉由在mikedev.inc中的向量列表。之後我們暫停程式直到使用者按下一個鍵。

所以的MikeOS程式必須以ret指令結束,傳回控制權到作業系統中,之後我們擁有資料給我們的字串。

系統呼叫

介紹

MikeOS核心包含系統呼叫用來輸出到螢幕上,取得鍵盤輸入,操作字串,產生PC聲音,數學運算,硬碟輸入輸出。你可以參考mikedev.inc,和查看使用這些 呼叫的練習從programs/目錄。

這裡我們有一個細節API的描述。你可以查看系統呼叫的完整的程式碼從source/features目錄。每個API都包含了組譯程式碼,所以你能增強系統呼叫的功能,須參考MikeOS系統開發者手冊。

磁碟
os_get_file_list

產生磁碟的檔案字串,檔案間以逗號分隔
IN/OUT: AX = 儲存零結束檔名字串之位置

Example:
    mov ax, .filestring
    call os_get_file_list

    ; Now .filestring will contain something like
    ; 'HELLO.BIN,FOO.BAR,THREE.TXT', 0

    .filestring    times 256 db 0

os_load_file

載入檔案到RAM

IN: AX=檔案位置,CX=在RAM中載入檔案的位置
OUT:BX=檔案大小(以bytes計), carry set if file not found
例子:
    mov ax, filename
    mov cx, 36960        ; 4K after where external program loads
    call os_load_file

    ...

    filename db 'README.TXT'

os_write_file

儲存檔案到磁碟(最大64K)
IN: AX = 檔名, BX = 資料位置, CX = 寫入多少位元組
OUT: Carry clear if OK, set if failure

Example:
    ; For this example, there's some text stored in .data

    mov ax, .filename
    mov bx, .data
    mov cx, 4192
    call os_write_file

    .filename    db 'HELLO.TXT', 0
    .data        times 4192 db 0

os_file_exists

檢查檔案是否存在於磁片
IN: AX = 檔名位置
OUT: carry clear if found, set if not

Example:
    mov ax, .filename
    call os_file_exists
    jc .not_found

    ...

.not_found:
    ; Print error message here

    .filename    db 'HELLO.TXT', 0

os_create_file

建立一個新的零個位元組的檔案到磁片中
IN: AX = 檔名位置
OUT: Nothing

Example:
    mov ax, .filename
    call os_create_file

    ...

    .filename    db 'HELLO.TXT', 0

os_remove_file

從檔案系統中刪除指定的檔案
IN: AX = 要刪除的檔名位置
OUT: Nothing

os_rename_file

在磁碟中更改檔案名稱
IN: AX = 要更改的檔案之檔名, BX = 新的檔名 (零結束字串)
OUT: carry set on error

Example:
    mov ax, .filename1
    mov bx, .filename2
    call os_rename_file

    jc .error

    ...

.error:
    ; File couldn't be renamed (may already exist)

    .filename1    db 'ORIG.TXT', 0
    .filename2    db 'NEW.TXT', 0

os_get_file_size

取得指定檔案之檔案大小資訊
IN: AX = 檔名
OUT: BX = 檔案大小以位元組計 (最大 64K) or carry set if file not found

Keyboard
os_wait_for_key

Waits for keypress and returns key
IN: Nothing
OUT: AX = key pressed, other regs preserved

Example:
.loop:
    call os_wait_for_key
    cmp al, 'y'
    je .yes
    cmp al, 'n'
    je .no
    jmp .loop

os_check_for_key

Scans keyboard for input, but doesn't wait
IN: Nothing
OUT: AX = 0 if no key pressed, otherwise scan code

Example: see code above

Math
os_bcd_to_int

Converts binary coded decimal number to an integer
IN: AL = BCD number
OUT: AX = integer value

Example:
    mov al, 00010110b    ; 0001 0110 = 16 (decimal) or 10h in BCD
    call os_bcd_to_int 
     
    ; AX now contains the 16 bit-integer 00000000 00010000b

os_long_int_negate

Multiply value in DX:AX by -1
IN: DX:AX = long integer 
OUT: DX:AX = -(initial DX:AX)

Example:
    mov dx, 01h
    mov ax, 45h
    call os_long_int_negate

    ; DX now contains 0xFFFF
    ; and AX 0xFEBB

os_get_random

Get a random integer between high and low values (inclusive)
IN: AX = low integer, BX = high
OUT: CX = random number between AX and BX

Misc
os_get_api_version

Return current version of MikeOS API
IN: Nothing 
OUT: AL = API version number

Example:
    call os_get_api_version
    ; AL now contains version number (eg 8)

os_pause

Delay execution for specified 10ths of second
IN: AX = number of 10ths of second to wait
OUT: nothing

Example:
    ; Halt execution for 3 secs

    mov ax, 30
    call os_pause

os_fatal_error

Display error message and halt execution
IN: AX = error message string location
OUT: nothing

Example:
    mov ax, .error_msg
    call os_fatal_error

    .error_msg    db 'Massive error!', 0

Ports
os_port_byte_out

Sends a byte to the specified port
IN: DX = port address, AL = byte
OUT: Nothing

os_port_byte_in

Retrieves a byte from the specified port
IN: DX = port address
OUT: AL = byte

os_serial_port_enable

Turn on the first serial port
IN: AX = 0 for normal mode (9600 baud), or 1 for slow mode (1200 baud)
OUT: AH = bit 7 clear on success

os_send_via_serial

Send a byte via the serial port
IN: AL = byte to send via serial
OUT: AH = bit 7 clear on success

Example:
    mov al, 'a'            ; Place char to transmit in AL
    call os_send_via_serial
    cmp ah, 128            ; If bit 7 is set, there's an error
    jnz all_ok            ; Otherwise it's all OK
    jmp oops_error            ; Deal with the error

os_get_via_serial

Get a byte from the serial port
IN: nothing
OUT: AL = byte that was received; OUT: AH = bit 7 clear on success

Example:
    call os_get_via_serial
    cmp ah, 128        ; If bit 7 is set, there's an error.
    jnz all_ok        ; Otherwise it's all OK
    jmp oops_error        ; Deal with the error

all_ok:           
    mov [rx_byte], al    ; Store byte we retrieved

Screen
os_print_string

Displays text
IN: SI = message location (zero-terminated string)
OUT: Nothing (registers preserved)

Example:
    mov si, .message
    call os_print_string

    ...

    .message    db 'Hello, world', 0

os_clear_screen

Clears the screen to background
IN/OUT: Nothing (registers preserved)

os_move_cursor

Moves cursor in text mode
IN: DH, DL = row, column 
OUT: Nothing (registers preserved)

Example:
    ; Move to middle of screen

    mov dh, 12
    mov dl, 40
    call os_move_cursor

os_get_cursor_pos

Return position of text cursor
OUT: DH, DL = row, column

os_print_horiz_line

Draw a horizontal line on the screen
IN: AX = line type (1 for double, otherwise single)
OUT: Nothing (registers preserved)

os_show_cursor

Turns on cursor in text mode
IN/OUT: Nothing

os_hide_cursor

Turns off cursor in text mode
IN/OUT: Nothing

os_draw_block

Render block of specified colour
IN: BL/DL/DH/SI/DI = colour/start X pos/start Y pos/width/finish Y pos
OUT: Nothing

Example:
    mov bl, 0100111b    ; White on red
    mov dl, 20        ; Start X position
    mov dh, 2        ; Start Y position
    mov si, 40        ; Width
    mov di, 23        ; Finish Y position
    call os_draw_block

os_file_selector

Show a file selection dialog
IN: Nothing 
OUT: AX = location of filename string (or carry set if Esc pressed)

Example:
    call os_file_selector
    jc .esc_pressed

    ; Now AX points to the chosen filename
    ...

.esc_pressed:
    ...

os_list_dialog

Show a dialog with a list of options
IN: AX = comma-separated list of strings to show (zero-terminated),
 BX = first help string, CX = second help string
OUT: AX = number (starts from 1) of entry selected carry set if Esc pressed

Example:
    mov ax, .list
    mov bx, .msg1
    mov cx, .msg2
    call os_list_dialog
    jc .esc_pressed

    ; Now AX = number (from 1) of option chosen
    ...

.esc_pressed:
    ...

    .list    db 'Open,Close,Reboot', 0
    .msg1    db 'Choose an option', 0
    .msg2    db 'Or press Esc to quit', 0

os_draw_background

Clear screen with white top and bottom bars, containing text, and a coloured middle section
IN: AX/BX = top/bottom string locations, CX = colour
OUT: Nothing

Example:
    mov ax, .title_msg
    mov bx, .footer_msg
    mov cx, 00100000b    ; Colour
    call os_draw_background

    ...

    .title_msg    db 'File manager', 0
    .footer_msg    db 'Choose an option...', 0

os_print_newline

Reset cursor to start of next line
IN/OUT: Nothing (registers preserved)

os_dump_registers

Displays register contents in hex on the screen
IN/OUT: AX/BX/CX/DX = registers to show

os_input_dialog

Get text string from user via a dialog box
IN: AX = string location, BX = message to show 
OUT: AX = string location

Example:
    mov bx, .filename_msg
    mov ax, .filename_input
    call os_input_dialog

    ...

    .filename_msg    'Please enter a filename:', 0
    .filename_input    times 12 db 0

os_dialog_box

Print dialog box in middle of screen, with button(s)
IN: AX, BX, CX = string locations (set registers to 0 for no display),
 DX = 0 for single 'OK' dialog, 1 for two-button 'OK' and 'Cancel'
OUT: If two-button mode, AX = 0 for OK and 1 for cancel
NOTE: Each string is limited to 40 characters

Example:
    mov ax, .string1
    mov bx, .string1
    mov cx, .string1
    mov dx, 1
    call os_dialog_box

    cmp ax, 1
    je .first_option_chosen

    ; Otherwise second was chosen
    ...

.first_option_chosen:
    ...

    .string1    db 'Welcome to my program!', 0
    .string2    db 'Please choose to destroy the world,', 0
    .string3    db 'or play with fluffy kittens.', 0

os_print_space

Print a space to the screen
IN/OUT: nothing

os_dump_string

Dump string as hex bytes and printable characters
IN: SI = points to string to dump
OUT: Nothing

os_print_digit

Displays contents of AX as a single digit (works up to base 37, ie digits 0-Z)
IN: AX = "digit" to format and print
OUT: Nothing

os_print_1hex

Displays low nibble of AL in hex format
IN: AL = number to format and print
OUT: Nothing

os_print_2hex

Displays AL in hex format
IN: AL = number to format and print
OUT: Nothing

os_print_4hex

Displays AX in hex format
IN: AX = number to format and print
OUT: Nothing

os_input_string

Take string from keyboard entry
IN/OUT: AX = location of string, other regs preserved
(Location will contain up to 255 characters, zero-terminated)

Example:
    mov ax, .string
    call os_input_string

    ...

    .string        times 256 db 0

String
os_string_length

Return length of a string
IN: AX = string location
OUT AX = length (other regs preserved)

Example:
    jmp Get_Len

    Test_String db 'This string has 46 characters including spaces', 0

Get_Len:
    mov ax, Test_String
    call os_string_length
    ; AX now contains the number 46

os_find_char_in_string

Get the position of a character in a string
IN: SI = string location, AL = character to find
OUT: AX = location in string, or 0 if char not present

Example:
jmp Search_Str

     Test_String db 'This is the test string', 0
     message_1   db 'Character not found', 0
     message_2   db 'Character found at position', 0
     message_3   db '  ', 0
     str_len     dw  0

Search_Str:

     mov ax, Test_String           ; string to search
     mov si, ax
     xor ax, ax                    ; clear ax

     mov al, 'x'                   ; x is the character to find
     call os_find_char_in_string

     mov [str_len], ax             ; store result
     cmp ax, 0                  
     jz Char_Not_Found 
     jmp Char_Found

Char_Not_Found:

     mov si, message_1
     call os_print_string     
     jmp Main_Pgm

Char_Found:

     mov ax, [str_len]             ; convert result into string first
     mov bx, message_3
     call os_int_to_string

     mov si, message_2
     call os_print_string          ; print message_2
     call os_print_space           ; print a space

     mov si, message_3
     call os_print_string          ; print the position at which x was found     

os_string_reverse

Swar order of characters in a string
IN: SI = location of zero-terminated string

Example:
    mov si, mystring
    call os_string_reverse

    ; Now mystring contains 'olleH'

    mystring db 'Hello', 0

os_string_charchange

Change instances of character in a string
IN: SI = string location, AL = char to find, BL = char to replace with

os_string_uppercase

Convert zero-terminated string to upper case
IN/OUT: AX = string location

os_string_lowercase

Convert zero-terminated string to lower case
IN/OUT: AX = string location

os_string_copy

Copy one string into another
IN/OUT: SI = source, DI = destination (programmer ensure sufficient room)

Example:
    mov si, .old_string
    mov di, .new_string
    call os_string_copy

    ...

    .old_string    db 'Hello', 0
    .new_string    times 16 db 0

os_string_truncate

Chop string down to specified number of characters
IN: SI = string location, AX = number of characters
OUT: string modified, registers preserved

Example:
    mov si, .string
    mov ax, 3
    call os_string_truncate

    ; .string now contains 'HEL', 0

    .string        db 'HELLO', 0

os_string_join

Join two strings into a third string
IN/OUT: AX = string one, BX = string two, CX = destination string

Example:
    mov ax, .string1
    mov bx, .string2
    mov cx, .string3

    ; CX now points to 'HELLOYOU', 0

    .string1    db 'HELLO', 0
    .string2    db 'YOU', 0
    .string3    times 50 db 0

os_string_chomp

Strip leading and trailing spaces from a string
IN: AX = string location
OUT: nothing

Example:
    mov ax, .string
    call os_string_chomp

    ; AX now points to 'KITTEN', 0

    .string        db '  KITTEN  ', 0

os_string_strip

Removes specified character from a string
IN: SI = string location, AL = character to remove
OUT: nothing

Example:
    mov si, .string
    mov al, 'U'
    call os_string_strip

    ; .string now contains 'MOSE', 0

    .string        db 'MOUSE', 0

os_string_compare

See if two strings match
IN: SI = string one, DI = string two
OUT: carry set if same, clear if different

Example:
    mov si, .string1
    mov di, .string2
    call os_string_compare
    jc .same

    ; Strings are different

    ...

.same:
    ; Strings are the same

    .string1    db 'ONE', 0
    .string2    db 'TWO', 0

os_string_strincmp

See if two strings match up to set number of chars
IN: SI = string one, DI = string two, CL = chars to check
OUT: carry set if same, clear if different

Example: like above, but with CL = number of characters to check

os_string_parse

Take string (eg "run foo bar baz") and return pointers to zero-terminated strings (eg AX = "run", BX =  "foo" etc.)
IN: SI = string
OUT: AX, BX, CX, DX = individual strings

Example:
    mov si, .string
    call os_string_parse

    ; Now AX points to 'This',
    ; BX to 'is',
    ; CX to 'a',
    ; and DX to 'test'

    .string        db 'This is a test', 0

os_string_to_int

Convert decimal string to integer value
IN: SI = string location (max 5 chars, up to '65536')
OUT: AX = number

Example:
    mov si, .string
    call os_string_to_int

    ; Now AX contains the number 1234

    .string        db '1234', 0

os_int_to_string

Convert unsigned value in AX to string
IN: AX = unsigned integer
OUT: AX = location of internal string buffer with result

Example:
    mov ax, 1234
    call os_int_to_string

    ; Now AX points to '1234', 0

os_sint_to_string

Convert signed value in AX to string
IN: AX = signed integer
OUT: AX = location of internal string buffer with result

Example:
    mov ax, -1234
    call os_int_to_string

    ; Now AX points to '-1234', 0

os_long_int_to_string

Convert value in DX:AX to string
IN: DX:AX = long unsigned integer, BX = number base, DI = string location
OUT: DI = location of converted string

os_set_time_fmt

Set time reporting format (eg '10:25 AM' or '2300 hours')
IN: AL = format flag, 0 = 12-hr format
OUT: nothing

os_get_time_string

Get current time in a string (eg '10:25')
IN/OUT: BX = string location

os_set_date_fmt

Set date reporting format (M/D/Y, D/M/Y or Y/M/D - 0, 1, 2)
IN: AX = format flag, 0-2
 If AX bit 7 = 1 = use name for months
 If AX bit 7 = 0, high byte = separator character
OUT: nothing

os_get_date_string

Get current date in a string (eg '12/31/2007')
IN/OUT: BX = string location

聲音
os_speaker_tone

Generate PC speaker tone (call os_speaker_off to turn off)
IN: AX = note frequency
OUT: Nothing (registers preserved)

Example: see code below

os_speaker_off

Turn off PC speaker
IN/OUT: Nothing (registers preserved)

Example:
; Generate "middle C" 261.626 Hz (263 Hz close enough) for 2 secs
; 2 secs = 2,000,000 uS which is 1E8480h

    jmp Play_It

    music_note  dw  263

Play_It:
    mov ax, [music_note]
    call os_speaker_tone

    mov cx, 1Eh
    mov dx, 8480h
    call os_pause

    call os_speaker_off         

BASIC
os_run_basic

在指定點執行核心BASIC解譯器
IN: AX = lBASIC碼的位置, BX = 碼的大小 (以位元組計)


幫助

假如你有任何關於MikeOS的問題,或你要開發類似的系統且想要分享程式碼和想法,
可前往MikeOS網站,並加入到信箱列表。你就可以寫信到 mikeos-developer@lists.berlios.de
來發表到列表。

授權
MikeOS是個開放原始碼,在BSD-like下授權釋出(可參考在MikeOS.zip檔案中的doc/LI
CENSE.TXT)。它意指你可以為程式碼做任何事情,包括在你的專案中使用它,
你只須保留授權檔案。