2011年1月30日 星期日

DJGPP - HelloWorld

聽說另一個open source的編譯器也可以編寫純DOS的應用程式。

但是,我試到現在,在純DOS下都會出現
Load error: no DPMI - Get csdpmi*b.zip
的錯誤訊息

其實大部分的安裝都很簡單,另外開這一篇是因為Makefile的部分寫法,也就是內隱規則有一點不一樣,這裡特別寫出來。
到目前我用過linux下的make、wmake與DJGPP的make的內隱規則都不一樣~真是麻煩~

Makefile

# Program, flags, ect.

ASM = gcc
OBJ = hello.obj
TARGET = hello.exe

.PHONY: everything all clean

everything: $(TARGET)

all: clean everything

clean:
[tab]if exist *.obj del *.obj
[tab]if exist $(TARGET) del $(TARGET)

$(OBJ): %.obj: %.c
[tab]gcc -c $< -o $@

$(TARGET): $(OBJ)
[tab]gcc $(OBJ) -o $@


參考資料:
DJGPP

2011年1月29日 星期六

Watcom c - ExecBat

一開始要接觸Watcom就是因為有在純DOS下完成long run test,並且有做次數的計數,但是,因為在純dos下的指令並不完全~所以,必需要自已寫一個在純DOS下的程式。

ExecBat.c

#include "ExecBat.h"

int
main (
  )
{
  int     CountValue = 0;
  int     DefaultCountValue = 10;
  char    SaveFile[] = "BatCount.txt";
  char    ActiveBat[] = "BatStart.bat";
  char    EndBat[] = "BatEnd.bat";
  int     WaitSecond = 10;

  if (FileExistOrNot (SaveFile)) {

    CountValue = ReadIntFromFile (SaveFile);

    printf ("The residue conut is %d\n", CountValue);

    if (CountValue == 0) {
      //
      // Execute
      //
      DelaySecond (WaitSecond);
      ExecuteBat (EndBat);

    } else if (CountValue < 0) {

      DelaySecond (WaitSecond);
      ExecuteBat (ActiveBat);

    } else {

      DelaySecond (WaitSecond);

      if (FileExistOrNot (ActiveBat)) {
        CountValue = CountValue - 1;
        WriteIntIntoFile (SaveFile, CountValue);
      }

      ExecuteBat (ActiveBat);

    }

  } else {

    printf ("Create %s and write default value into %s", SaveFile, SaveFile);
    WriteIntIntoFile (SaveFile, DefaultCountValue);

  }

  return 0;
}

void
ExecuteBat (
  char    FileName[]
  )
{
  if (FileExistOrNot (FileName)) {
    //
    // execute the ActiveBat
    //
    printf ("Execute %s\n", FileName);
    system (FileName);
  } else {
    printf ("The %s does not exist!!\n", FileName);
    printf ("Can not execute %s!!", FileName);
  }
}

void
DecreaseCountToFile (
  char    SaveFile[],
  int     CountValue,
  bool    DecreaseCount
  )
{
  //
  // Decrease 1
  //
  CountValue = CountValue - 1;

  if (DecreaseCount) {
    WriteIntIntoFile (SaveFile, CountValue);
  }
}

bool
FileExistOrNot (
  char FileName[]
  )
{
  FILE  *fp = NULL;

  fp = fopen (FileName, "r");

  if (fp == NULL) {
    return false;
  } else {
    fclose (fp);
    return true;
  }
}

int
ReadIntFromFile (
  char FileName[]
  )
{
  FILE    *fp = NULL;
  char    szInput [256];
  int     CountValue = 0;

  if (FileExistOrNot (FileName)) {
    fp = fopen (FileName, "r");

    //
    // While the SaveFile exists!!
    //
    fgets ( szInput, 256, fp );

    //
    // Convert character to Integer
    //
    CountValue = atoi (szInput);

    //
    // Close file
    //
    fclose (fp);

    printf ("Read %s sucessfully!!\n", FileName);
  }

  return CountValue;
}

void
WriteIntIntoFile (
  char  FileName[],
  int   CountValue
  )
{
  FILE    *fp = NULL;
  char    szInput [256];

  //
  // Open file
  //
  fp = fopen (FileName, "w");

  //
  // Convert Integer to Character
  //
  itoa (CountValue, szInput, 10);

  //
  // Write value into file
  //
  fwrite (szInput, strlen (szInput), 1, fp);
  
  //
  // Close file
  //
  fclose (fp);

}

void
DelaySecond (
  int   Second
  )
{
  int Index;
  for (Index = 0; Index < Second; Index++) {
    printf ("%d...", Index);
    fflush (stdout);
    delay (1000);
  }
  printf ("\n");
}

ExecBat.h
#ifndef _EXECBAT_H_
#define _EXECBAT_H_

#include 
#include 
#include 
#include 

typedef short bool;

#define true  ((bool) 1 == 1)
#define false ((bool) 0 == 1)

void
ExecuteBat (
  char    FileName[]
  );

void
DecreaseCountToFile (
  char    SaveFile[],
  int     CountValue,
  bool    DecreaseCount
  );

bool
FileExistOrNot (
  char FileName[]
  );


int
ReadIntFromFile (
  char FileName[]
  );

void
WriteIntIntoFile (
  char  FileName[],
  int   CountValue
  );

void
DelaySecond (
  int   Second
  );

#endif //#ifndef _EXECBAT_H_


Makefile
# Program, flags, ect.

ASM = wcl
TARGET = ExecBat.exe
OBJ = ExecBat.obj

everything: $(TARGET) .symbolic

all: clean everything

clean: cleanobj cleanexe .symbolic

cleanobj: .symbolic
[tab]@if exist *.obj del *.obj > NUL
[tab]@if exist *.err del *.err > NUL
[tab]@echo All OBJ cleaned

cleanexe: .symbolic
[tab]@if exist $(TARGET) del $(TARGET) >NUL
[tab]@echo All EXE cleaned

$(TARGET): $(OBJ)
[tab]$(ASM) /bcl=dos $< /fe=$@

.c.obj:
[tab]$(ASM) /c $*.c /fo=$*.obj


操作方式:
直接在Dos下執行ExecBat
會產生BatCount.txt,內含預設值10
再執行一次,每一次會減1,並且會執行BatStart.bat

當執行到值為0時,會執行BatEnd.bat

若要一直執行BatStart.bat的話,就把BatCount.txt的值設為負數的整數,就會一直執行BatStart.bat

另外使用者可以在BatStart.bat或EndBat.bat內加自己要執行的指令!

Watcom c - ReadFile

這是一個讀取stdin的範例:
readfile.c

#include <stdio.h>
#include <stdlib.h>

int main (
)
{
FILE *fp = stdin;
char readbuf[4];
int cnt = 0;
int count = 0;

while (!feof (fp))
{
count = fread (readbuf, 1, 4, fp);
printf ("cnt: %d, data size: %d\n", ++cnt, count);
}
return 0;
}


Makefile
# Program, flags, ect.

ASM = wcl
TARGET = readfile.exe
OBJ = readfile.obj

everything: $(TARGET)

clean: .symbolic
[tab]@if exist $(TARGET) del $(TARGET)
[tab]@if exist $(OBJ) del $(OBJ)

$(TARGET): $(OBJ)
[tab]$(ASM) -bcl=dos $< -fe=$@

.c.obj:
[tab]$(ASM) -c $*.c

參考資料:
[C] 使用 fread 讀取檔案的觀念 - 小心使用 End-of-file (EOF)

2011年1月28日 星期五

Watcom c - HelloWorld

Watcom c是一個Open Source,它可以編譯許多平台的可執行檔~

而我需要用到是因為,我要編譯在純dos下的執行檔,原本我是打算用bat就可以完成我要做的事情,但是,dos底下的bat指令非常的不完全,很基本上動作都做不到,所以只要尋找有什麼東西可以開發純dos下的應用程式。

找到Watcom c是一個不錯的開發套件,他可以開發for許多平台的應用程式,如DOS, DOS/4GW, Windows 3.x, Windows NT, OS/2, Novell NLM
而另一個DJGPP好像也可以build dos下的應用程式

第一步下載Watcom
下載點
安裝很簡單,直接安裝就可以了。

第二步
用命令提示字元到C:\WATCOM目錄
hello.c

#include <stdio.h>

void
main (
  )
{
  printf ("Hello World!!\n");
}


第三步:編譯
% wcl /c hello.c /fo=hello.obj
% wcl /l=dos hello.obj /fe=hello.exe

/l後面接的是要編譯出哪一個平台的應用程式

為了以後修改方便,利用watcom內建的wmake來執行編譯的程序
Makefile
# Program, flags, ect.

ASM = wcl
TARGET = hello.exe
OBJ = hello.obj

everything: $(TARGET)

clean: .symbolic
[tab]@if exist $(TARGET) del $(TARGET)
[tab]@if exist $(OBJ) del $(OBJ)

$(TARGET): $(OBJ)
[tab]$(ASM) -bcl=dos $< -fe=$@

.c.obj:
[tab]$(ASM) -c $*.c
#hello.obj: hello.c
#[tab]$(ASM) -c $< -fo=$@


在輸入以下的指令之後,就會出現hello.exe執行檔~
% wmake

參考PGUIDE.pdf,FTools.pdf檔案~

參考資料:
Open Watcom
WATCOMC教學
[C] 使用 fread 讀取檔案的觀念 - 小心使用 End-of-file (EOF)
watcom 编译器怎么使用呀?

2011年1月26日 星期三

丹田發音

丹田發音的話,丹田的位置就是在你的肚臍眼下面,將你的兩隻手掌張開"用力"的壓在你肚臍眼下面那片地方,然後首先你先發出ㄙ的音(使用氣音,而非真正發出聲音),在你發出ㄙ的氣音的時候,你用你的丹田去抗衡手掌往內推的力量!
你可以試著咳嗽看看,肚子有在震動ㄉ地方就是丹田喔!找出施力點,用丹田發幾個音,不要急著咬字,習慣之後,再試著唱歌,記得下巴脖子的部分不要用力,剛開始站著唱也會比較順利利用丹田發聲。如果一下子 不注意又用喉嚨用力ㄉ話,再利用咳嗽的震動找回丹田施力點ㄉ感覺
丹田在肚肚三指下的地方....
吸氣的時候 肚子會向外撐
吐氣的時候 肚子會向內縮
(也就是吸氣時要吸深,深到肚子裡,肚子就會漲起來,可用躺著感覺吸氣)
唱歌的時候 適時的運用 一吸一吐來發聲。

參考資料:
丹田發音

2011年1月25日 星期二

用歌來加強記憶力!!

1/24-1/30
當我知道你們相愛 - 何維健