Browse Source

Added interrupt handling. Timer interrupt support.
(UNIXTimer, WWInterrupt, WWTimer, WonxSystem addition)
According to interrupt support, compatibility functions are replaced with UNIXTimer_Pause (), UNIXTimer_Unpause ()
It hung around.
UNIXTimer, WWTimer, WonxSystem's callback functions,
It is necessary to check finely whether there are bugs peculiar to interrupts.
(The setting of the interrupt in the callback function may change, or from the callback function
It is necessary to check whether the callback function is called or not)

Version 0.2 beta - from wonx-b02.tar.gz

Hiroaki Sakai 23 years ago
parent
commit
0f43e6d6ee
27 changed files with 2394 additions and 148 deletions
  1. 19 5
      HISTORY
  2. 3 3
      Makefile
  3. 299 0
      UNIXTimer.c
  4. 101 0
      UNIXTimer.h
  5. 49 0
      UNIXTimerP.h
  6. 353 0
      WWInterrupt.c
  7. 170 0
      WWInterrupt.h
  8. 35 0
      WWInterruptP.h
  9. 114 0
      WWTimer.c
  10. 65 0
      WWTimer.h
  11. 31 0
      WWTimerP.h
  12. 10 2
      Wonx.c
  13. 2 0
      Wonx.h
  14. 1 0
      WonxP.h
  15. 172 0
      WonxSystem.c
  16. 53 0
      WonxSystem.h
  17. 37 0
      WonxSystemP.h
  18. 15 1
      XDisplay.c
  19. 26 2
      bank.c
  20. 28 4
      comm.c
  21. 15 0
      configure.h
  22. 349 83
      disp.c
  23. 84 13
      key.c
  24. 26 2
      sound.c
  25. 87 3
      system.c
  26. 120 23
      text.c
  27. 130 7
      timer.c

+ 19 - 5
HISTORY

@@ -1,6 +1,20 @@
-2000/10/8(日)
+wonx-b02
 
-wonx-a08 未公開
+割り込み処理の追加.タイマ割り込みサポート.
+(UNIXTimer, WWInterrupt, WWTimer, WonxSystem 追加)
+割り込みサポートに合わせて,互換関数を UNIXTimer_Pause(), UNIXTimer_Unpause()
+でくくった.
+UNIXTimer, WWTimer, WonxSystem のコールバック関数などは,
+割り込み特有のバグが無いか細かくチェックする必要がある.
+(コールバック関数中で割り込みの設定が変わってしまったり,コールバック関数から
+ コールバック関数が呼ばれたりすることはないかどうかチェックする必要がある)
+
+
+
+
+2000/10/9(月)
+
+wonx-b01 公開
 
 テキスト表示機能の追加.(0~127のASCII文字のみで,漢字は未対応)
 
@@ -19,7 +33,7 @@ disp.c 
 
 2000/10/5(木)
 
-wonx-a07 公開
+wonx-a07 公開
 
 WWLCDPanel にビットマップデータを2枚持たせ,一度描画したビットマップは
 描画しないように修正.Xサーバの負荷を減らした.
@@ -36,7 +50,7 @@ wonx-a05 
 
 2000/10/4(水)
 
-wonx-a06 公開
+wonx-a06 公開
 
 WWDisplay_DrawScreen() のアルゴリズムを大幅に修正.
 たいして高速にならなかった.X サーバの描画がホットスポットになっていると
@@ -47,7 +61,7 @@ WWDisplay_DrawScreen() 
 
 2000/10/3(火)
 
-wonx-a05 公開
+wonx-a05 公開
 
 XDisplay_DrawLCDWindow() を修正.無駄な計算をループ外に出した.
 

+ 3 - 3
Makefile

@@ -2,10 +2,10 @@ XINCLUDEDIR = /usr/X11R6/include
 INCLUDEDIR = .
 XLIBDIR = /usr/X11R6/lib
 
-VERSION = Wonx-b01
-PKGNAME = wonx-b01
+VERSION = Wonx-b02
+PKGNAME = wonx-b02
 
-OBJS = WWCharacter.o WWColorMap.o WWDisplay.o WWLCDPanel.o WWPalette.o WWScreen.o WWSprite.o WWText.o Wonx.o WonxDisplay.o WonxText.o XDisplay.o bank.o comm.o disp.o text.o key.o sound.o system.o timer.o etc.o
+OBJS = WWCharacter.o WWColorMap.o WWDisplay.o WWLCDPanel.o WWPalette.o WWScreen.o WWSprite.o WWText.o WWInterrupt.o WWTimer.o Wonx.o WonxDisplay.o WonxText.o WonxSystem.o XDisplay.o UNIXTimer.o bank.o comm.o disp.o text.o key.o sound.o system.o timer.o etc.o
 
 .SUFFIXES: .c .o
 

+ 299 - 0
UNIXTimer.c

@@ -0,0 +1,299 @@
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
+#include <unistd.h>
+#include <signal.h>
+
+#include "UNIXTimerP.h"
+#include "etc.h"
+
+/*****************************************************************************/
+/* メンバ関数の定義                                                          */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* コールバック関数                                                          */
+/*---------------------------------------------------------------------------*/
+
+/* pointed_unix_timer の値はいつ変化するかわからないので,最適化を禁止する */
+
+volatile static UNIXTimer pointed_unix_timer = NULL;
+
+static void UNIXTimer_CallBackFunction(int argument)
+{
+  int ret;
+
+  /*
+    static なフラグを立てて,コールバック関数からコールバック関数が
+    呼ばれたのを検出するのが必要かも.
+    */
+
+  if (pointed_unix_timer == NULL) return;
+  if (!pointed_unix_timer->timer_on) return;
+
+  if (pointed_unix_timer->pause) {
+    pointed_unix_timer->interrupt_in_pause++;
+  } else {
+    if (pointed_unix_timer->interrupt_in_pause == 0)
+      pointed_unix_timer->interrupt_in_pause = 1;
+    while (pointed_unix_timer->interrupt_in_pause > 0) {
+      pointed_unix_timer->interrupt_in_pause--;
+      if (pointed_unix_timer->callback != NULL) {
+
+	/*
+	 * コールバック関数の中から UNIXTimer_Unpause() などが呼ばれて,
+	 * そこからさらにコールバック関数が呼ばれたりしたときのために,
+	 * ポーズする.
+	 */
+	pointed_unix_timer->pause++;
+
+	ret = (*pointed_unix_timer->callback)(pointed_unix_timer->parameter);
+
+	pointed_unix_timer->pause--;
+
+	/*
+	 * コールバック関数の中で UNIXTimer_* 関連の関数が呼び出されると,
+	 * ここで UNIXTimer オブジェクトの状態が変わってしまう可能性がある.
+	 */
+
+	/*
+	 * 以下の処理は同じことを関数の先頭でやっているので,
+	 * 最適化されて削除されないように注意すること.
+	 */
+	if (pointed_unix_timer == NULL) return;
+	if (!pointed_unix_timer->timer_on) return;
+
+	if (ret) {
+	  pointed_unix_timer->interrupt_in_pause = 0;
+	  UNIXTimer_OFF(pointed_unix_timer);
+	  return;
+	}
+
+	/*
+	 * コールバック関数中で,ポーズの状態が切り替わってしまった
+	 * ときのため.
+	 * 以下の処理は同じようなことをちょっと前にやっているので,
+	 * 最適化されて削除されないように注意すること.
+	 */
+	if (pointed_unix_timer->pause) break;
+
+      }
+    }
+  }
+
+  if (pointed_unix_timer->auto_preset)
+    UNIXTimer_ON(pointed_unix_timer);
+  else
+    UNIXTimer_OFF(pointed_unix_timer);
+
+  return;
+}
+
+/*---------------------------------------------------------------------------*/
+/* タイマの ON, OFF                                                          */
+/*---------------------------------------------------------------------------*/
+
+/*
+ * このあたりの処理は,処理中にタイマ割り込みが発生しないかどうかを
+ * 常に注意すること.でないと不可解なバグの原因になる.
+ */
+
+int UNIXTimer_ON(UNIXTimer unix_timer)
+{
+  unix_timer->timer_on = 1;
+  pointed_unix_timer = unix_timer;
+  ualarm(unix_timer->interval, 0);
+  return (0);
+}
+
+int UNIXTimer_OFF(UNIXTimer unix_timer)
+{
+  alarm(0); /* タイマを無効にする */
+  unix_timer->timer_on = 0;
+  pointed_unix_timer = NULL;
+  return (0);
+}
+
+int UNIXTimer_IsON(UNIXTimer unix_timer)
+{ return (unix_timer->timer_on != 0); }
+int UNIXTimer_IsOFF(UNIXTimer unix_timer)
+{ return (unix_timer->timer_on == 0); }
+
+/*---------------------------------------------------------------------------*/
+/* 一時停止                                                                  */
+/*---------------------------------------------------------------------------*/
+
+/*
+ * 関数の先頭と末尾を Pause, Unpause でくくるばあいなどは,
+ * 関数から関数を呼び出したときに,2重 Pause, Unpause が起きるので
+ * 注意すること.(ただし,ポーズはネストできる)
+ */
+
+/*
+ * ポーズはネストされるので,UNIXTimer_Unpause() を安易に繰り返し呼んだり
+ * しないように注意すること.
+ */
+
+/*
+ * このあたりの処理は,処理中にタイマ割り込みが発生しないかどうかを
+ * 常に注意すること.でないと不可解なバグの原因になる.
+ */
+
+int UNIXTimer_Pause(UNIXTimer unix_timer)
+{
+  unix_timer->pause++; /* ポーズはネストできる */
+
+  return (0);
+}
+
+int UNIXTimer_Unpause(UNIXTimer unix_timer)
+{
+  if (unix_timer->pause == 0)
+    Error("UNIXTimer_Unpause", "Duplicated unpause.");
+
+  if (unix_timer->pause == 1) {
+    if (unix_timer->interrupt_in_pause > 0) {
+
+      /*
+       * 万が一,ここでタイマ割り込みが発生しても,
+       * unix_timer->pause は 1 なので,コールバック関数は呼ばれないので,
+       * 問題無し.
+       * オートプリセットならば,べつに問題無し.
+       * オートプリセットでなければ timer_on フラグが落ちるので,問題無い.
+       */
+
+      /*
+       * 処理中にタイマ割り込みが発生すると面倒なので,
+       * タイマをいったん無効にする.
+       */
+      alarm(0);
+
+      /*
+       * 状態値を変更する直前・直後で割り込みが入ると面倒なので,
+       * 割り込みをOFFにしてからデクリメントする.
+       */
+      /* コールバック関数を呼ぶ前に,pause フラグを無効にする */
+      unix_timer->pause--; /* ポーズはネストできる */
+
+      /* コールバック関数の呼び出し */
+      UNIXTimer_CallBackFunction(0);
+    }
+  } else {
+    unix_timer->pause--; /* ポーズはネストできる */
+  }
+
+  return (0);
+}
+
+int UNIXTimer_IsPause(UNIXTimer unix_timer)
+{ return (unix_timer->pause != 0); }
+
+/*---------------------------------------------------------------------------*/
+/* オートプリセット                                                          */
+/*---------------------------------------------------------------------------*/
+
+int UNIXTimer_SetAutoPreset(UNIXTimer unix_timer)
+{ return (unix_timer->auto_preset = 1); }
+int UNIXTimer_ResetAutoPreset(UNIXTimer unix_timer)
+{ return (unix_timer->auto_preset = 0); }
+int UNIXTimer_IsAutoPreset(UNIXTimer unix_timer)
+{ return (unix_timer->auto_preset != 0); }
+
+/*---------------------------------------------------------------------------*/
+/* インターバル                                                              */
+/*---------------------------------------------------------------------------*/
+
+int UNIXTimer_GetInterval(UNIXTimer unix_timer)
+{ return (unix_timer->interval); }
+int UNIXTimer_SetInterval(UNIXTimer unix_timer, int interval)
+{
+  /* ualarm(); の引数に0を用いてはダメなので */
+  if (interval < 1) interval = 1;
+  return (unix_timer->interval = interval);
+}
+
+/*---------------------------------------------------------------------------*/
+/* コールバック関数の呼び出し時のパラメータ                                  */
+/*---------------------------------------------------------------------------*/
+
+void * UNIXTimer_GetParameter(UNIXTimer unix_timer)
+{ return (unix_timer->parameter); }
+void * UNIXTimer_SetParameter(UNIXTimer unix_timer, void * parameter)
+{ return (unix_timer->parameter = parameter); }
+
+/*---------------------------------------------------------------------------*/
+/* コールバック関数の取得・登録                                              */
+/*---------------------------------------------------------------------------*/
+
+UNIXTimerCallBack UNIXTimer_GetCallBack(UNIXTimer unix_timer)
+{ return (unix_timer->callback); }
+UNIXTimerCallBack UNIXTimer_SetCallBack(UNIXTimer unix_timer,
+					UNIXTimerCallBack callback)
+{ return (unix_timer->callback = callback); }
+
+/*---------------------------------------------------------------------------*/
+/* オブジェクトの作成                                                        */
+/*---------------------------------------------------------------------------*/
+
+UNIXTimer UNIXTimer_Create(int auto_preset, int interval, void * parameter,
+			   UNIXTimerCallBack callback)
+{
+  UNIXTimer unix_timer;
+
+  unix_timer = (UNIXTimer)malloc(sizeof(_UNIXTimer));
+  if (unix_timer == NULL)
+    Error("UNIXTimer_Create", "Cannot allocate memory.");
+
+  unix_timer->timer_on           = 0;
+  unix_timer->pause              = 0;
+  unix_timer->interrupt_in_pause = 0;
+  unix_timer->auto_preset        = 0;
+  unix_timer->interval           = 0;
+  unix_timer->parameter          = NULL;
+  unix_timer->callback           = NULL;
+
+  if (auto_preset) UNIXTimer_SetAutoPreset(unix_timer);
+  else UNIXTimer_ResetAutoPreset(unix_timer);
+
+  UNIXTimer_SetInterval(unix_timer, interval);
+  UNIXTimer_SetParameter(unix_timer, parameter);
+  UNIXTimer_SetCallBack(unix_timer, callback);
+
+  /*
+   * SIGALRM を使用するので,sleep() 中にアラームが起きた場合には,
+   * コールバック関数からの復帰後に sleep() の残り時間は継続されない.
+   */
+  signal(SIGALRM, UNIXTimer_CallBackFunction);
+
+  return (unix_timer);
+}
+
+/*---------------------------------------------------------------------------*/
+/* オブジェクトの削除                                                        */
+/*---------------------------------------------------------------------------*/
+
+/*
+ * このあたりの処理は,処理中にタイマ割り込みが発生しないかどうかを
+ * 常に注意すること.でないと不可解なバグの原因になる.
+ */
+
+UNIXTimer UNIXTimer_Destroy(UNIXTimer unix_timer)
+{
+  if (unix_timer == NULL)
+    Error("UNIXTimer_Destroy", "Object is not created.");
+
+  UNIXTimer_OFF(unix_timer);
+
+  free(unix_timer);
+
+  return (NULL);
+}
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 101 - 0
UNIXTimer.h

@@ -0,0 +1,101 @@
+#ifndef _UNIXTimer_h_INCLUDED_
+#define _UNIXTimer_h_INCLUDED_
+
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/*****************************************************************************/
+/* クラスの定義                                                              */
+/*****************************************************************************/
+
+typedef struct _UNIXTimer * UNIXTimer;
+typedef int (*UNIXTimerCallBack)(void *);
+
+/*****************************************************************************/
+/* メンバ関数の宣言                                                          */
+/*****************************************************************************/
+
+/*---------------------------------------------------------------------------*/
+/* タイマの ON, OFF                                                          */
+/*---------------------------------------------------------------------------*/
+
+int UNIXTimer_ON(UNIXTimer unix_timer);
+int UNIXTimer_OFF(UNIXTimer unix_timer);
+int UNIXTimer_IsON(UNIXTimer unix_timer);
+int UNIXTimer_IsOFF(UNIXTimer unix_timer);
+
+/*---------------------------------------------------------------------------*/
+/* 一時停止                                                                  */
+/*---------------------------------------------------------------------------*/
+
+/*
+ * 関数の先頭と末尾を Pause, Unpause でくくるばあいなどは,
+ * 関数から関数を呼び出したときに,2重 Pause, Unpause が起きるので
+ * 注意すること.(ただし,ポーズはネストできる)
+ */
+
+/*
+ * ポーズはネストされるので,UNIXTimer_Unpause() を安易に繰り返し呼んだり
+ * しないように注意すること.
+ */
+
+int UNIXTimer_Pause(UNIXTimer unix_timer);
+int UNIXTimer_Unpause(UNIXTimer unix_timer);
+int UNIXTimer_IsPause(UNIXTimer unix_timer);
+
+/*---------------------------------------------------------------------------*/
+/* オートプリセット                                                          */
+/*---------------------------------------------------------------------------*/
+
+int UNIXTimer_SetAutoPreset(UNIXTimer unix_timer);
+int UNIXTimer_ResetAutoPreset(UNIXTimer unix_timer);
+int UNIXTimer_IsAutoPreset(UNIXTimer unix_timer);
+
+/*---------------------------------------------------------------------------*/
+/* インターバル                                                              */
+/*---------------------------------------------------------------------------*/
+
+int UNIXTimer_GetInterval(UNIXTimer unix_timer);
+int UNIXTimer_SetInterval(UNIXTimer unix_timer, int interval);
+
+/*---------------------------------------------------------------------------*/
+/* コールバック関数の呼び出し時のパラメータ                                  */
+/*---------------------------------------------------------------------------*/
+
+void * UNIXTimer_GetParameter(UNIXTimer unix_timer);
+void * UNIXTimer_Setparameter(UNIXTimer unix_timer, void * parameter);
+
+/*---------------------------------------------------------------------------*/
+/* コールバック関数の取得・登録                                              */
+/*---------------------------------------------------------------------------*/
+
+UNIXTimerCallBack UNIXTimer_GetCallBack(UNIXTimer unix_timer);
+UNIXTimerCallBack UNIXTimer_SetCallBack(UNIXTimer unix_timer,
+					UNIXTimerCallBack callback);
+
+/*---------------------------------------------------------------------------*/
+/* オブジェクトの作成                                                        */
+/*---------------------------------------------------------------------------*/
+
+UNIXTimer UNIXTimer_Create(int auto_preset, int interval, void * parameter,
+			   UNIXTimerCallBack callback);
+
+/*---------------------------------------------------------------------------*/
+/* オブジェクトの削除                                                        */
+/*---------------------------------------------------------------------------*/
+
+UNIXTimer UNIXTimer_Destroy(UNIXTimer unix_timer);
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+#endif
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 49 - 0
UNIXTimerP.h

@@ -0,0 +1,49 @@
+#ifndef _UNIXTimerP_h_INCLUDED_
+#define _UNIXTimerP_h_INCLUDED_
+
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
+#include "UNIXTimer.h"
+
+/*****************************************************************************/
+/* クラスの定義                                                              */
+/*****************************************************************************/
+
+typedef struct _UNIXTimer {
+
+  int timer_on; /* タイマを動作させるかどうかのフラグ */
+
+  /*
+   * タイマの一時停止.停止中にタイマの時間が来た場合には,
+   * 時間が来たことだけ記憶しておき,一時停止の解除時にコールバック関数が
+   * 呼び出される.
+   * Wonx では X サーバとの通信中にタイマ割り込みが入って,さらに X サーバとの
+   * 通信が発生したりすると,通信の整合性がとれなくなるような気がするので,
+   * それを防ぐために,一部の関数内部ではタイマ割り込みを停止させる.
+   */
+  int pause;
+
+  /*
+   * タイマ割り込みの一時停止中に割り込みがかかった場合には,このフラグを
+   * セットして,一時停止の解除時にコールバック関数を呼ぶ.
+   */
+  int interrupt_in_pause;
+
+  int auto_preset; /* オートプリセット.1 だとオートプリセットを行う */
+  int interval; /* タイマのインターバル.マイクロ秒で指定 */
+  void * parameter; /* コールバック関数の呼び出し時のパラメータ */
+  UNIXTimerCallBack callback; /* コールバック関数 */
+
+} _UNIXTimer;
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+#endif
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 353 - 0
WWInterrupt.c

@@ -0,0 +1,353 @@
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
+#include "WWInterruptP.h"
+#include "etc.h"
+
+/*****************************************************************************/
+/* メンバ関数の定義                                                          */
+/*****************************************************************************/
+
+/*===========================================================================*/
+/* WWInterruptVector クラスのもの                                            */
+/*===========================================================================*/
+
+static int WWInterruptVector_GetNumber(WWInterruptVector v)
+{ return (v->number); }
+static WWInterruptCallback WWInterruptVector_GetCallback(WWInterruptVector v)
+{ return (v->callback); }
+static int WWInterruptVector_GetCS(WWInterruptVector v)
+{ return (v->cs); }
+static int WWInterruptVector_GetDS(WWInterruptVector v)
+{ return (v->ds); }
+
+static int WWInterruptVector_SetNumber(WWInterruptVector v, int number)
+{ return (v->number = number); }
+static WWInterruptCallback WWInterruptVector_SetCallback(WWInterruptVector v,
+							 WWInterruptCallback cb)
+{ return (v->callback = cb); }
+static int WWInterruptVector_SetCS(WWInterruptVector v, int cs)
+{ return (v->cs = cs); }
+static int WWInterruptVector_SetDS(WWInterruptVector v, int ds)
+{ return (v->ds = ds); }
+
+static int WWInterruptVector_ExecuteCallback(WWInterruptVector vector)
+{
+  if (vector->callback == NULL) return (1);
+  (*(vector->callback))();
+  return (0);
+}
+
+static WWInterruptVector WWInterruptVector_Create(int number)
+{
+  WWInterruptVector vector;
+
+  vector = (WWInterruptVector)malloc(sizeof(_WWInterruptVector));
+  if (vector == NULL)
+    Error("WWInterruptVector_Create", "Cannot allocate memory.");
+
+  WWInterruptVector_SetNumber(vector, number);
+  WWInterruptVector_SetCallback(vector, NULL);
+  WWInterruptVector_SetCS(vector, 0);
+  WWInterruptVector_SetDS(vector, 0);
+
+  return (vector);
+}
+
+static WWInterruptVector WWInterruptVector_Destroy(WWInterruptVector vector)
+{
+  if (vector == NULL)
+    Error("WWInterruptVector_Destroy", "Object is not created.");
+  free(vector);
+  return (NULL);
+}
+
+/*===========================================================================*/
+/* WWInterrupt クラスのもの                                                  */
+/*===========================================================================*/
+
+static WWInterruptVector WWInterrupt_GetVector(WWInterrupt interrupt,
+					       int number)
+{
+  if ((number < 0) || (number > 7))
+    Error("WWInterrupt_SetVector", "Invalid interrupt number.");
+  return (interrupt->vector[number]);
+}
+
+static WWInterruptVector WWInterrupt_SetVector(WWInterrupt interrupt,
+					       int number,
+					       WWInterruptVector vector)
+{
+  if ((number < 0) || (number > 7))
+    Error("WWInterrupt_SetVector", "Invalid interrupt number.");
+  return (interrupt->vector[number] = vector);
+}
+
+int WWInterrupt_GetNumber(WWInterrupt interrupt, int num)
+{
+  return (WWInterruptVector_GetNumber(WWInterrupt_GetVector(interrupt, num)));
+}
+
+WWInterruptCallback WWInterrupt_GetCallback(WWInterrupt interrupt, int n)
+{
+  return (WWInterruptVector_GetCallback(WWInterrupt_GetVector(interrupt, n)));
+}
+
+int WWInterrupt_GetCS(WWInterrupt interrupt, int number)
+{
+  return (WWInterruptVector_GetCS(WWInterrupt_GetVector(interrupt, number)));
+}
+
+int WWInterrupt_GetDS(WWInterrupt interrupt, int number)
+{
+  return (WWInterruptVector_GetDS(WWInterrupt_GetVector(interrupt, number)));
+}
+
+WWInterruptCallback WWInterrupt_SetCallback(WWInterrupt interrupt, int num,
+					    WWInterruptCallback callback)
+{
+  return (WWInterruptVector_SetCallback(WWInterrupt_GetVector(interrupt, num),
+					callback));
+}
+
+int WWInterrupt_SetCS(WWInterrupt interrupt, int num, int cs)
+{
+  return (WWInterruptVector_SetCS(WWInterrupt_GetVector(interrupt, num), cs));
+}
+
+int WWInterrupt_SetDS(WWInterrupt interrupt, int num, int ds)
+{
+  return (WWInterruptVector_SetDS(WWInterrupt_GetVector(interrupt, num), ds));
+}
+
+int WWInterrupt_ExecuteCallback(WWInterrupt i, int n)
+{
+  return (WWInterruptVector_ExecuteCallback(WWInterrupt_GetVector(i, n)));
+}
+
+/*---------------------------------------------------------------------------*/
+/* Number の取得                                                             */
+/*---------------------------------------------------------------------------*/
+
+int WWInterrupt_GetSendReadyNumber(WWInterrupt interrupt)
+{ return (WWInterrupt_GetNumber(interrupt, SYS_INT_SENDREADY)); }
+int WWInterrupt_GetKeyNumber(WWInterrupt interrupt)
+{ return (WWInterrupt_GetNumber(interrupt, SYS_INT_KEY)); }
+int WWInterrupt_GetCasetteNumber(WWInterrupt interrupt)
+{ return (WWInterrupt_GetNumber(interrupt, SYS_INT_CASETTE)); }
+int WWInterrupt_GetReceiveReadyNumber(WWInterrupt interrupt)
+{ return (WWInterrupt_GetNumber(interrupt, SYS_INT_RECEIVEREADY)); }
+int WWInterrupt_GetDisplineNumber(WWInterrupt interrupt)
+{ return (WWInterrupt_GetNumber(interrupt, SYS_INT_DISPLINE)); }
+int WWInterrupt_GetTimerCountUpNumber(WWInterrupt interrupt)
+{ return (WWInterrupt_GetNumber(interrupt, SYS_INT_TIMER_COUNTUP)); }
+int WWInterrupt_GetVBlankNumber(WWInterrupt interrupt)
+{ return (WWInterrupt_GetNumber(interrupt, SYS_INT_VBLANK)); }
+int WWInterrupt_GetHBlankCountUpNumber(WWInterrupt interrupt)
+{ return (WWInterrupt_GetNumber(interrupt, SYS_INT_HBLANK_COUNTUP)); }
+
+/*---------------------------------------------------------------------------*/
+/* コールバック関数の取得                                                    */
+/*---------------------------------------------------------------------------*/
+
+WWInterruptCallback WWInterrupt_GetSendReadyCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCallback(interrupt, SYS_INT_SENDREADY)); }
+WWInterruptCallback WWInterrupt_GetKeyCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCallback(interrupt, SYS_INT_KEY)); }
+WWInterruptCallback WWInterrupt_GetCasetteCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCallback(interrupt, SYS_INT_CASETTE)); }
+WWInterruptCallback WWInterrupt_GetReceiveReadyCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCallback(interrupt, SYS_INT_RECEIVEREADY)); }
+WWInterruptCallback WWInterrupt_GetDisplineCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCallback(interrupt, SYS_INT_DISPLINE)); }
+WWInterruptCallback WWInterrupt_GetTimerCountUpCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCallback(interrupt, SYS_INT_TIMER_COUNTUP)); }
+WWInterruptCallback WWInterrupt_GetVBlankCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCallback(interrupt, SYS_INT_VBLANK)); }
+WWInterruptCallback WWInterrupt_GetHBlankCountUpCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCallback(interrupt, SYS_INT_HBLANK_COUNTUP)); }
+
+/*---------------------------------------------------------------------------*/
+/* CS の取得                                                                 */
+/*---------------------------------------------------------------------------*/
+
+int WWInterrupt_GetSendReadyCS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCS(interrupt, SYS_INT_SENDREADY)); }
+int WWInterrupt_GetKeyCS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCS(interrupt, SYS_INT_KEY)); }
+int WWInterrupt_GetCasetteCS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCS(interrupt, SYS_INT_CASETTE)); }
+int WWInterrupt_GetReceiveReadyCS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCS(interrupt, SYS_INT_RECEIVEREADY)); }
+int WWInterrupt_GetDisplineCS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCS(interrupt, SYS_INT_DISPLINE)); }
+int WWInterrupt_GetTimerCountUpCS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCS(interrupt, SYS_INT_TIMER_COUNTUP)); }
+int WWInterrupt_GetVBlankCS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCS(interrupt, SYS_INT_VBLANK)); }
+int WWInterrupt_GetHBlankCountUpCS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetCS(interrupt, SYS_INT_HBLANK_COUNTUP)); }
+
+/*---------------------------------------------------------------------------*/
+/* DS の取得                                                                 */
+/*---------------------------------------------------------------------------*/
+
+int WWInterrupt_GetSendReadyDS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetDS(interrupt, SYS_INT_SENDREADY)); }
+int WWInterrupt_GetKeyDS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetDS(interrupt, SYS_INT_KEY)); }
+int WWInterrupt_GetCasetteDS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetDS(interrupt, SYS_INT_CASETTE)); }
+int WWInterrupt_GetReceiveReadyDS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetDS(interrupt, SYS_INT_RECEIVEREADY)); }
+int WWInterrupt_GetDisplineDS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetDS(interrupt, SYS_INT_DISPLINE)); }
+int WWInterrupt_GetTimerCountUpDS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetDS(interrupt, SYS_INT_TIMER_COUNTUP)); }
+int WWInterrupt_GetVBlankDS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetDS(interrupt, SYS_INT_VBLANK)); }
+int WWInterrupt_GetHBlankCountUpDS(WWInterrupt interrupt)
+{ return (WWInterrupt_GetDS(interrupt, SYS_INT_HBLANK_COUNTUP)); }
+
+/*---------------------------------------------------------------------------*/
+/* コールバック関数の設定                                                    */
+/*---------------------------------------------------------------------------*/
+
+WWInterruptCallback WWInterrupt_SetSendReadyCallback(WWInterrupt interrupt,
+						     WWInterruptCallback f)
+{ return (WWInterrupt_SetCallback(interrupt, SYS_INT_SENDREADY, f)); }
+WWInterruptCallback WWInterrupt_SetKeyCallback(WWInterrupt interrupt,
+					       WWInterruptCallback f)
+{ return (WWInterrupt_SetCallback(interrupt, SYS_INT_KEY, f)); }
+WWInterruptCallback WWInterrupt_SetCasetteCallback(WWInterrupt interrupt,
+						   WWInterruptCallback f)
+{ return (WWInterrupt_SetCallback(interrupt, SYS_INT_CASETTE, f)); }
+WWInterruptCallback WWInterrupt_SetReceiveReadyCallback(WWInterrupt interrupt,
+							WWInterruptCallback f)
+{ return (WWInterrupt_SetCallback(interrupt, SYS_INT_RECEIVEREADY, f)); }
+WWInterruptCallback WWInterrupt_SetDisplineCallback(WWInterrupt interrupt,
+						    WWInterruptCallback f)
+{ return (WWInterrupt_SetCallback(interrupt, SYS_INT_DISPLINE, f)); }
+WWInterruptCallback WWInterrupt_SetTimerCountUpCallback(WWInterrupt interrupt,
+							WWInterruptCallback f)
+{ return (WWInterrupt_SetCallback(interrupt, SYS_INT_TIMER_COUNTUP, f)); }
+WWInterruptCallback WWInterrupt_SetVBlankCallback(WWInterrupt interrupt,
+						  WWInterruptCallback f)
+{ return (WWInterrupt_SetCallback(interrupt, SYS_INT_VBLANK, f)); }
+WWInterruptCallback WWInterrupt_SetHBlankCountUpCallback(WWInterrupt interrupt,
+							 WWInterruptCallback f)
+{ return (WWInterrupt_SetCallback(interrupt, SYS_INT_HBLANK_COUNTUP, f)); }
+
+/*---------------------------------------------------------------------------*/
+/* CS の設定                                                                 */
+/*---------------------------------------------------------------------------*/
+
+int WWInterrupt_SetSendReadyCS(WWInterrupt interrupt, int cs)
+{ return (WWInterrupt_SetCS(interrupt, SYS_INT_SENDREADY, cs)); }
+int WWInterrupt_SetKeyCS(WWInterrupt interrupt, int cs)
+{ return (WWInterrupt_SetCS(interrupt, SYS_INT_KEY, cs)); }
+int WWInterrupt_SetCasetteCS(WWInterrupt interrupt, int cs)
+{ return (WWInterrupt_SetCS(interrupt, SYS_INT_CASETTE, cs)); }
+int WWInterrupt_SetReceiveReadyCS(WWInterrupt interrupt, int cs)
+{ return (WWInterrupt_SetCS(interrupt, SYS_INT_RECEIVEREADY, cs)); }
+int WWInterrupt_SetDisplineCS(WWInterrupt interrupt, int cs)
+{ return (WWInterrupt_SetCS(interrupt, SYS_INT_DISPLINE, cs)); }
+int WWInterrupt_SetTimerCountUpCS(WWInterrupt interrupt, int cs)
+{ return (WWInterrupt_SetCS(interrupt, SYS_INT_TIMER_COUNTUP, cs)); }
+int WWInterrupt_SetVBlankCS(WWInterrupt interrupt, int cs)
+{ return (WWInterrupt_SetCS(interrupt, SYS_INT_VBLANK, cs)); }
+int WWInterrupt_SetHBlankCountUpCS(WWInterrupt interrupt, int cs)
+{ return (WWInterrupt_SetCS(interrupt, SYS_INT_HBLANK_COUNTUP, cs)); }
+
+/*---------------------------------------------------------------------------*/
+/* DS の設定                                                                 */
+/*---------------------------------------------------------------------------*/
+
+int WWInterrupt_SetSendReadyDS(WWInterrupt interrupt, int ds)
+{ return (WWInterrupt_SetDS(interrupt, SYS_INT_SENDREADY, ds)); }
+int WWInterrupt_SetKeyDS(WWInterrupt interrupt, int ds)
+{ return (WWInterrupt_SetDS(interrupt, SYS_INT_KEY, ds)); }
+int WWInterrupt_SetCasetteDS(WWInterrupt interrupt, int ds)
+{ return (WWInterrupt_SetDS(interrupt, SYS_INT_CASETTE, ds)); }
+int WWInterrupt_SetReceiveReadyDS(WWInterrupt interrupt, int ds)
+{ return (WWInterrupt_SetDS(interrupt, SYS_INT_RECEIVEREADY, ds)); }
+int WWInterrupt_SetDisplineDS(WWInterrupt interrupt, int ds)
+{ return (WWInterrupt_SetDS(interrupt, SYS_INT_DISPLINE, ds)); }
+int WWInterrupt_SetTimerCountUpDS(WWInterrupt interrupt, int ds)
+{ return (WWInterrupt_SetDS(interrupt, SYS_INT_TIMER_COUNTUP, ds)); }
+int WWInterrupt_SetVBlankDS(WWInterrupt interrupt, int ds)
+{ return (WWInterrupt_SetDS(interrupt, SYS_INT_VBLANK, ds)); }
+int WWInterrupt_SetHBlankCountUpDS(WWInterrupt interrupt, int ds)
+{ return (WWInterrupt_SetDS(interrupt, SYS_INT_HBLANK_COUNTUP, ds)); }
+
+/*---------------------------------------------------------------------------*/
+/* コールバック関数の実行                                                    */
+/*---------------------------------------------------------------------------*/
+
+int WWInterrupt_ExecuteSendReadyCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_ExecuteCallback(interrupt, SYS_INT_SENDREADY)); }
+int WWInterrupt_ExecuteKeyCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_ExecuteCallback(interrupt, SYS_INT_KEY)); }
+int WWInterrupt_ExecuteCasetteCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_ExecuteCallback(interrupt, SYS_INT_CASETTE)); }
+int WWInterrupt_ExecuteReceiveReadyCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_ExecuteCallback(interrupt, SYS_INT_RECEIVEREADY)); }
+int WWInterrupt_ExecuteDisplineCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_ExecuteCallback(interrupt, SYS_INT_DISPLINE)); }
+int WWInterrupt_ExecuteTimerCountUpCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_ExecuteCallback(interrupt, SYS_INT_TIMER_COUNTUP)); }
+int WWInterrupt_ExecuteVBlankCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_ExecuteCallback(interrupt, SYS_INT_VBLANK)); }
+int WWInterrupt_ExecuteHBlankCountUpCallback(WWInterrupt interrupt)
+{ return (WWInterrupt_ExecuteCallback(interrupt, SYS_INT_HBLANK_COUNTUP)); }
+
+/*---------------------------------------------------------------------------*/
+/* オブジェクトの作成                                                        */
+/*---------------------------------------------------------------------------*/
+
+WWInterrupt WWInterrupt_Create()
+{
+  WWInterrupt interrupt;
+  int i;
+
+  interrupt = (WWInterrupt)malloc(sizeof(_WWInterrupt));
+  if (interrupt == NULL)
+    Error("WWInterrupt_Create", "Cannot allocate memory.");
+
+  for (i = 0; i < 8; i++)
+    WWInterrupt_SetVector(interrupt, i, WWInterruptVector_Create(i));
+
+  return (interrupt);
+}
+
+/*---------------------------------------------------------------------------*/
+/* オブジェクトの削除                                                        */
+/*---------------------------------------------------------------------------*/
+
+WWInterrupt WWInterrupt_Destroy(WWInterrupt interrupt)
+{
+  int i;
+  WWInterruptVector vector;
+
+  if (interrupt == NULL)
+    Error("WWInterrupt_Destroy", "Object is not created.");
+
+  for (i = 0; i < 8; i++) {
+    vector = WWInterrupt_GetVector(interrupt, i);
+    if (vector != NULL)
+      WWInterrupt_SetVector(interrupt, i, WWInterruptVector_Destroy(vector));
+  }
+
+  free(interrupt);
+
+  return (NULL);
+}
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 170 - 0
WWInterrupt.h

@@ -0,0 +1,170 @@
+#ifndef _WWInterrupt_h_INCLUDED_
+#define _WWInterrupt_h_INCLUDED_
+
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sys/system.h"
+
+/*****************************************************************************/
+/* クラスの定義                                                              */
+/*****************************************************************************/
+
+typedef struct _WWInterrupt * WWInterrupt;
+typedef void (*WWInterruptCallback)();
+
+/*****************************************************************************/
+/* メンバ関数の宣言                                                          */
+/*****************************************************************************/
+
+/*===========================================================================*/
+/* WWInterrupt クラスのもの                                                  */
+/*===========================================================================*/
+
+int WWInterrupt_GetNumber(WWInterrupt interrupt, int num);
+WWInterruptCallback WWInterrupt_GetCallback(WWInterrupt interrupt, int n);
+int WWInterrupt_GetCS(WWInterrupt interrupt, int number);
+int WWInterrupt_GetDS(WWInterrupt interrupt, int number);
+WWInterruptCallback WWInterrupt_SetCallback(WWInterrupt interrupt, int num,
+					    WWInterruptCallback callback);
+int WWInterrupt_SetCS(WWInterrupt interrupt, int num, int cs);
+int WWInterrupt_SetDS(WWInterrupt interrupt, int num, int ds);
+int WWInterrupt_ExecuteCallback(WWInterrupt i, int n);
+
+/*---------------------------------------------------------------------------*/
+/* Number の取得                                                             */
+/*---------------------------------------------------------------------------*/
+
+int WWInterrupt_GetSendReadyNumber(WWInterrupt interrupt);
+int WWInterrupt_GetKeyNumber(WWInterrupt interrupt);
+int WWInterrupt_GetCasetteNumber(WWInterrupt interrupt);
+int WWInterrupt_GetReceiveReadyNumber(WWInterrupt interrupt);
+int WWInterrupt_GetDisplineNumber(WWInterrupt interrupt);
+int WWInterrupt_GetTimerCountUpNumber(WWInterrupt interrupt);
+int WWInterrupt_GetVBlankNumber(WWInterrupt interrupt);
+int WWInterrupt_GetHBlankCountUpNumber(WWInterrupt interrupt);
+
+/*---------------------------------------------------------------------------*/
+/* コールバック関数の取得                                                    */
+/*---------------------------------------------------------------------------*/
+
+WWInterruptCallback WWInterrupt_GetSendReadyCallback(WWInterrupt interrupt);
+WWInterruptCallback WWInterrupt_GetKeyCallback(WWInterrupt interrupt);
+WWInterruptCallback WWInterrupt_GetCasetteCallback(WWInterrupt interrupt);
+WWInterruptCallback WWInterrupt_GetReceiveReadyCallback(WWInterrupt interrupt);
+WWInterruptCallback WWInterrupt_GetDisplineCallback(WWInterrupt interrupt);
+WWInterruptCallback WWInterrupt_GetTimerCountUpCallback(WWInterrupt interrupt);
+WWInterruptCallback WWInterrupt_GetVBlankCallback(WWInterrupt interrupt);
+WWInterruptCallback WWInterrupt_GetHBlankCountUpCallback(WWInterrupt interrupt);
+
+/*---------------------------------------------------------------------------*/
+/* CS の取得                                                                 */
+/*---------------------------------------------------------------------------*/
+
+int WWInterrupt_GetSendReadyCS(WWInterrupt interrupt);
+int WWInterrupt_GetKeyCS(WWInterrupt interrupt);
+int WWInterrupt_GetCasetteCS(WWInterrupt interrupt);
+int WWInterrupt_GetReceiveReadyCS(WWInterrupt interrupt);
+int WWInterrupt_GetDisplineCS(WWInterrupt interrupt);
+int WWInterrupt_GetTimerCountUpCS(WWInterrupt interrupt);
+int WWInterrupt_GetVBlankCS(WWInterrupt interrupt);
+int WWInterrupt_GetHBlankCountUpCS(WWInterrupt interrupt);
+
+/*---------------------------------------------------------------------------*/
+/* DS の取得                                                                 */
+/*---------------------------------------------------------------------------*/
+
+int WWInterrupt_GetSendReadyDS(WWInterrupt interrupt);
+int WWInterrupt_GetKeyDS(WWInterrupt interrupt);
+int WWInterrupt_GetCasetteDS(WWInterrupt interrupt);
+int WWInterrupt_GetReceiveReadyDS(WWInterrupt interrupt);
+int WWInterrupt_GetDisplineDS(WWInterrupt interrupt);
+int WWInterrupt_GetTimerCountUpDS(WWInterrupt interrupt);
+int WWInterrupt_GetVBlankDS(WWInterrupt interrupt);
+int WWInterrupt_GetHBlankCountUpDS(WWInterrupt interrupt);
+
+/*---------------------------------------------------------------------------*/
+/* コールバック関数の設定                                                    */
+/*---------------------------------------------------------------------------*/
+
+WWInterruptCallback WWInterrupt_SetSendReadyCallback(WWInterrupt interrupt,
+						     WWInterruptCallback f);
+WWInterruptCallback WWInterrupt_SetKeyCallback(WWInterrupt interrupt,
+					       WWInterruptCallback f);
+WWInterruptCallback WWInterrupt_SetCasetteCallback(WWInterrupt interrupt,
+						   WWInterruptCallback f);
+WWInterruptCallback WWInterrupt_SetReceiveReadyCallback(WWInterrupt interrupt,
+							WWInterruptCallback f);
+WWInterruptCallback WWInterrupt_SetDisplineCallback(WWInterrupt interrupt,
+						    WWInterruptCallback f);
+WWInterruptCallback WWInterrupt_SetTimerCountUpCallback(WWInterrupt interrupt,
+							WWInterruptCallback f);
+WWInterruptCallback WWInterrupt_SetVBlankCallback(WWInterrupt interrupt,
+						  WWInterruptCallback f);
+WWInterruptCallback WWInterrupt_SetHBlankCountUpCallback(WWInterrupt interrupt,
+							 WWInterruptCallback f);
+
+/*---------------------------------------------------------------------------*/
+/* CS の設定                                                                 */
+/*---------------------------------------------------------------------------*/
+
+int WWInterrupt_SetSendReadyCS(WWInterrupt interrupt, int cs);
+int WWInterrupt_SetKeyCS(WWInterrupt interrupt, int cs);
+int WWInterrupt_SetCasetteCS(WWInterrupt interrupt, int cs);
+int WWInterrupt_SetReceiveReadyCS(WWInterrupt interrupt, int cs);
+int WWInterrupt_SetDisplineCS(WWInterrupt interrupt, int cs);
+int WWInterrupt_SetTimerCountUpCS(WWInterrupt interrupt, int cs);
+int WWInterrupt_SetVBlankCS(WWInterrupt interrupt, int cs);
+int WWInterrupt_SetHBlankCountUpCS(WWInterrupt interrupt, int cs);
+
+/*---------------------------------------------------------------------------*/
+/* DS の設定                                                                 */
+/*---------------------------------------------------------------------------*/
+
+int WWInterrupt_SetSendReadyDS(WWInterrupt interrupt, int ds);
+int WWInterrupt_SetKeyDS(WWInterrupt interrupt, int ds);
+int WWInterrupt_SetCasetteDS(WWInterrupt interrupt, int ds);
+int WWInterrupt_SetReceiveReadyDS(WWInterrupt interrupt, int ds);
+int WWInterrupt_SetDisplineDS(WWInterrupt interrupt, int ds);
+int WWInterrupt_SetTimerCountUpDS(WWInterrupt interrupt, int ds);
+int WWInterrupt_SetVBlankDS(WWInterrupt interrupt, int ds);
+int WWInterrupt_SetHBlankCountUpDS(WWInterrupt interrupt, int ds);
+
+/*---------------------------------------------------------------------------*/
+/* コールバック関数の実行                                                    */
+/*---------------------------------------------------------------------------*/
+
+int WWInterrupt_ExecuteSendReadyCallback(WWInterrupt interrupt);
+int WWInterrupt_ExecuteKeyCallback(WWInterrupt interrupt);
+int WWInterrupt_ExecuteCasetteCallback(WWInterrupt interrupt);
+int WWInterrupt_ExecuteReceiveReadyCallback(WWInterrupt interrupt);
+int WWInterrupt_ExecuteDisplineCallback(WWInterrupt interrupt);
+int WWInterrupt_ExecuteTimerCountUpCallback(WWInterrupt interrupt);
+int WWInterrupt_ExecuteVBlankCallback(WWInterrupt interrupt);
+int WWInterrupt_ExecuteHBlankCountUpCallback(WWInterrupt interrupt);
+
+/*---------------------------------------------------------------------------*/
+/* オブジェクトの作成                                                        */
+/*---------------------------------------------------------------------------*/
+
+WWInterrupt WWInterrupt_Create();
+
+/*---------------------------------------------------------------------------*/
+/* オブジェクトの削除                                                        */
+/*---------------------------------------------------------------------------*/
+
+WWInterrupt WWInterrupt_Destroy(WWInterrupt interrupt);
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+#endif
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 35 - 0
WWInterruptP.h

@@ -0,0 +1,35 @@
+#ifndef _WWInterruptP_h_INCLUDED_
+#define _WWInterruptP_h_INCLUDED_
+
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
+#include "WWInterrupt.h"
+
+/*****************************************************************************/
+/* クラスの定義                                                              */
+/*****************************************************************************/
+
+typedef struct _WWInterruptVector {
+  int number;
+  WWInterruptCallback callback;
+  int cs;
+  int ds;
+} _WWInterruptVector;
+
+typedef struct _WWInterruptVector * WWInterruptVector;
+
+typedef struct _WWInterrupt {
+  WWInterruptVector vector[8]; /* 割り込みは全部で8種類 */
+} _WWInterrupt;
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+#endif
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 114 - 0
WWTimer.c

@@ -0,0 +1,114 @@
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
+#include "WWTimerP.h"
+#include "etc.h"
+
+/*****************************************************************************/
+/* メンバ関数の定義                                                          */
+/*****************************************************************************/
+
+int WWTimer_ON(   WWTimer ww_timer) { return (ww_timer->timer_on =  1); }
+int WWTimer_OFF(  WWTimer ww_timer) { return (ww_timer->timer_on =  0); }
+int WWTimer_IsON( WWTimer ww_timer) { return (ww_timer->timer_on != 0); }
+int WWTimer_IsOFF(WWTimer ww_timer) { return (ww_timer->timer_on == 0); }
+
+int WWTimer_GetAutoPreset(WWTimer ww_timer)
+{ return (ww_timer->auto_preset); }
+int WWTimer_GetPresetCounter(WWTimer ww_timer)
+{ return (ww_timer->preset_counter); }
+int WWTimer_GetCounter(WWTimer ww_timer)
+{ return (ww_timer->counter); }
+
+int WWTimer_IsAutoPresetOFF(WWTimer ww_timer)
+{ return (WWTimer_GetAutoPreset(ww_timer) == 0); }
+int WWTimer_IsAutoPresetON(WWTimer ww_timer)
+{ return (WWTimer_GetAutoPreset(ww_timer) == 1); }
+
+int WWTimer_SetAutoPreset(WWTimer ww_timer, int auto_preset)
+{ return (ww_timer->auto_preset = auto_preset); }
+int WWTimer_SetPresetCounter(WWTimer ww_timer, int preset_counter)
+{ return (ww_timer->preset_counter = preset_counter); }
+int WWTimer_SetCounter(WWTimer ww_timer, int counter)
+{ return (ww_timer->counter = counter); }
+
+int WWTimer_SetAutoPresetOFF(WWTimer ww_timer)
+{ return (WWTimer_SetAutoPreset(ww_timer, 0)); }
+int WWTimer_SetAutoPresetON(WWTimer ww_timer)
+{ return (WWTimer_SetAutoPreset(ww_timer, 1)); }
+
+int WWTimer_Reset(WWTimer ww_timer)
+{
+  int counter;
+  counter = WWTimer_GetCounter(ww_timer);
+  WWTimer_SetCounter(ww_timer, WWTimer_GetPresetCounter(ww_timer));
+  return (counter);
+}
+
+int WWTimer_Count(WWTimer ww_timer)
+{
+  int ret;
+  int counter;
+
+  if (WWTimer_IsOFF(ww_timer)) return (0);
+
+  counter = WWTimer_GetCounter(ww_timer);
+
+  counter--;
+
+  if (counter <= 0) {
+    ret = 1;
+    if (WWTimer_IsAutoPresetON(ww_timer))
+      WWTimer_Reset(ww_timer);
+    else
+      WWTimer_OFF(ww_timer);
+  } else {
+    ret = 0;
+    WWTimer_SetCounter(ww_timer, counter);
+  }
+
+  return (ret);
+}
+
+/*---------------------------------------------------------------------------*/
+/* オブジェクトの作成                                                        */
+/*---------------------------------------------------------------------------*/
+
+WWTimer WWTimer_Create(int auto_preset, int preset)
+{
+  WWTimer ww_timer;
+
+  ww_timer = (WWTimer)malloc(sizeof(_WWTimer));
+  if (ww_timer == NULL)
+    Error("WWTimer_Create", "Cannot allocate memory.");
+
+  WWTimer_OFF(ww_timer);
+  WWTimer_SetAutoPreset(ww_timer, auto_preset);
+  WWTimer_SetPresetCounter(ww_timer, preset);
+  WWTimer_Reset(ww_timer);
+
+  return (ww_timer);
+}
+
+/*---------------------------------------------------------------------------*/
+/* オブジェクトの削除                                                        */
+/*---------------------------------------------------------------------------*/
+
+WWTimer WWTimer_Destroy(WWTimer ww_timer)
+{
+  if (ww_timer == NULL)
+    Error("WWTimer_Destroy", "Object is not created.");
+
+  free(ww_timer);
+
+  return (NULL);
+}
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 65 - 0
WWTimer.h

@@ -0,0 +1,65 @@
+#ifndef _WWTimer_h_INCLUDED_
+#define _WWTimer_h_INCLUDED_
+
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "sys/timer.h"
+
+/*****************************************************************************/
+/* クラスの定義                                                              */
+/*****************************************************************************/
+
+typedef struct _WWTimer * WWTimer;
+
+/*****************************************************************************/
+/* メンバ関数の宣言                                                          */
+/*****************************************************************************/
+
+int WWTimer_ON(WWTimer ww_timer);
+int WWTimer_OFF(WWTimer ww_timer);
+int WWTimer_IsON(WWTimer ww_timer);
+int WWTimer_IsOFF(WWTimer ww_timer);
+
+int WWTimer_GetAutoPreset(WWTimer ww_timer);
+int WWTimer_GetPresetCounter(WWTimer ww_timer);
+int WWTimer_GetCounter(WWTimer ww_timer);
+
+int WWTimer_IsAutoPresetOFF(WWTimer ww_timer);
+int WWTimer_IsAutoPresetON(WWTimer ww_timer);
+
+int WWTimer_SetAutoPreset(WWTimer ww_timer, int auto_preset);
+int WWTimer_SetPresetCounter(WWTimer ww_timer, int preset_counter);
+int WWTimer_SetCounter(WWTimer ww_timer, int counter);
+
+int WWTimer_SetAutoPresetOFF(WWTimer ww_timer);
+int WWTimer_SetAutoPresetON(WWTimer ww_timer);
+
+int WWTimer_Reset(WWTimer ww_timer);
+int WWTimer_Count(WWTimer ww_timer);
+
+/*---------------------------------------------------------------------------*/
+/* オブジェクトの作成                                                        */
+/*---------------------------------------------------------------------------*/
+
+WWTimer WWTimer_Create(int auto_preset, int preset);
+
+/*---------------------------------------------------------------------------*/
+/* オブジェクトの削除                                                        */
+/*---------------------------------------------------------------------------*/
+
+WWTimer WWTimer_Destroy(WWTimer ww_timer);
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+#endif
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 31 - 0
WWTimerP.h

@@ -0,0 +1,31 @@
+#ifndef _WWTimerP_h_INCLUDED_
+#define _WWTimerP_h_INCLUDED_
+
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
+#include "WWTimer.h"
+
+/*****************************************************************************/
+/* クラスの定義                                                              */
+/*****************************************************************************/
+
+typedef struct _WWTimer {
+
+  int timer_on; /* タイマの状態 */
+  int auto_preset; /* オートプリセット */
+  int preset_counter; /* プリセット・カウンタ */
+  int counter; /* カウンタ */
+
+} _WWTimer;
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+#endif
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 10 - 2
Wonx.c

@@ -1,8 +1,9 @@
 #include "WonxP.h"
 #include "etc.h"
 
-#include <sys/disp.h>
-#include <sys/text.h>
+#include "sys/disp.h"
+#include "sys/text.h"
+#include "sys/system.h"
 
 /*****************************************************************************/
 /* ¥Ç¥£¥¹¥×¥ì¥¤¤Î³ÎÊÝ                                                        */
@@ -37,6 +38,8 @@ void Wonx_Create(void)
     WonxText_Create(screen, 0, 0, TEXT_SCREEN_WIDTH, TEXT_SCREEN_HEIGHT,
 		    palette);
 
+  wonx->wonx_system = WonxSystem_Create();
+
   return;
 }
 
@@ -50,3 +53,8 @@ WonxText Wonx_GetWonxText(void)
   return (wonx->wonx_text);
 }
 
+WonxSystem Wonx_GetWonxSystem(void)
+{
+  return (wonx->wonx_system);
+}
+

+ 2 - 0
Wonx.h

@@ -3,6 +3,7 @@
 
 #include "WonxDisplay.h"
 #include "WonxText.h"
+#include "WonxSystem.h"
 
 /*****************************************************************************/
 /* ¥Ç¥£¥¹¥×¥ì¥¤¤Î³ÎÊÝ                                                        */
@@ -12,5 +13,6 @@ int Wonx_IsCreated(void);
 void Wonx_Create(void);
 WonxDisplay Wonx_GetWonxDisplay(void);
 WonxText Wonx_GetWonxText(void);
+WonxSystem Wonx_GetWonxSystem(void);
 
 #endif

+ 1 - 0
WonxP.h

@@ -14,6 +14,7 @@
 typedef struct _Wonx {
   WonxDisplay wonx_display;
   WonxText wonx_text;
+  WonxSystem wonx_system;
 } _Wonx;
 
 typedef struct _Wonx * Wonx;

+ 172 - 0
WonxSystem.c

@@ -0,0 +1,172 @@
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
+#include "WonxSystemP.h"
+#include "configure.h"
+#include "etc.h"
+
+/*****************************************************************************/
+/* メンバ関数の定義                                                          */
+/*****************************************************************************/
+
+WWInterrupt WonxSystem_GetWWInterrupt(WonxSystem wonx_system)
+{ return (wonx_system->ww_interrupt); }
+WWInterrupt WonxSystem_SetWWInterrupt(WonxSystem wonx_system,
+				      WWInterrupt ww_interrupt)
+{ return (wonx_system->ww_interrupt = ww_interrupt); }
+
+WWTimer WonxSystem_GetWWTimer(WonxSystem wonx_system, int type)
+{ return (wonx_system->ww_timer[type]); }
+WWTimer WonxSystem_SetWWTimer(WonxSystem wonx_system, int type, WWTimer t)
+{ return (wonx_system->ww_timer[type] = t); }
+
+WWTimer WonxSystem_GetWWVBlankTimer(WonxSystem wonx_system)
+{ return (WonxSystem_GetWWTimer(wonx_system, 0)); }
+WWTimer WonxSystem_SetWWVBlankTimer(WonxSystem wonx_system, WWTimer t)
+{ return (WonxSystem_SetWWTimer(wonx_system, 0, t)); }
+
+WWTimer WonxSystem_GetWWVBlankCountUpTimer(WonxSystem wonx_system)
+{ return (WonxSystem_GetWWTimer(wonx_system, 1)); }
+WWTimer WonxSystem_SetWWVBlankCountUpTimer(WonxSystem wonx_system, WWTimer t)
+{ return (WonxSystem_SetWWTimer(wonx_system, 1, t)); }
+
+WWTimer WonxSystem_GetWWHBlankCountUpTimer(WonxSystem wonx_system)
+{ return (WonxSystem_GetWWTimer(wonx_system, 2)); }
+WWTimer WonxSystem_SetWWHBlankCountUpTimer(WonxSystem wonx_system, WWTimer t)
+{ return (WonxSystem_SetWWTimer(wonx_system, 2, t)); }
+
+UNIXTimer WonxSystem_GetUNIXTimer(WonxSystem wonx_system)
+{ return (wonx_system->unix_timer); }
+UNIXTimer WonxSystem_SetUNIXTimer(WonxSystem wonx_system,
+				  UNIXTimer unix_timer)
+{ return (wonx_system->unix_timer = unix_timer); }
+
+static int WonxTimer_Callback(WonxSystem wonx_system)
+{
+  WWTimer ww_timer;
+  WWInterrupt ww_interrupt;
+
+  ww_interrupt = WonxSystem_GetWWInterrupt(wonx_system);
+
+  ww_timer = WonxSystem_GetWWVBlankTimer(wonx_system);
+  if (WWTimer_IsON(ww_timer)) {
+    if (WWTimer_Count(ww_timer))
+      WWInterrupt_ExecuteVBlankCallback(ww_interrupt);
+  }
+
+  ww_timer = WonxSystem_GetWWVBlankCountUpTimer(wonx_system);
+  if (WWTimer_IsON(ww_timer)) {
+    if (WWTimer_Count(ww_timer))
+      WWInterrupt_ExecuteTimerCountUpCallback(ww_interrupt);
+  }
+
+  ww_timer = WonxSystem_GetWWHBlankCountUpTimer(wonx_system);
+  if (WWTimer_IsON(ww_timer)) {
+    if (WWTimer_Count(ww_timer))
+      WWInterrupt_ExecuteHBlankCountUpCallback(ww_interrupt);
+  }
+
+  return (0);
+}
+
+WonxSystem WonxSystem_Create()
+{
+  WonxSystem wonx_system;
+  WWInterrupt ww_interrupt;
+  WWTimer ww_timer;
+  UNIXTimer unix_timer;
+
+  wonx_system = (WonxSystem)malloc(sizeof(_WonxSystem));
+  if (wonx_system == NULL)
+    Error("WonxSystem_Create", "Cannot allocate memory.");
+
+  ww_interrupt = WWInterrupt_Create();
+  if (ww_interrupt == NULL)
+    Error("WonxSystem_Create", "Cannot create WonderWitch interrupt.");
+  WonxSystem_SetWWInterrupt(wonx_system, ww_interrupt);
+
+  /* VBlank は WONX_VBLANK_INTERVAL * 0.1 秒毎とする */
+  ww_timer = WWTimer_Create(1, WONX_VBLANK_INTERVAL);
+  if (ww_timer == NULL)
+    Error("WonxSystem_Create", "Cannot create WonderWitch VBlank timer.");
+  WonxSystem_SetWWVBlankTimer(wonx_system, ww_timer);
+
+  ww_timer = WWTimer_Create(0, WONX_VBLANK_INTERVAL);
+  if (ww_timer == NULL)
+    Error("WonxSystem_Create",
+	  "Cannot create WonderWitch VBlank count up timer.");
+  WonxSystem_SetWWVBlankCountUpTimer(wonx_system, ww_timer);
+
+  ww_timer = WWTimer_Create(0, WONX_HBLANK_INTERVAL);
+  if (ww_timer == NULL)
+    Error("WonxSystem_Create",
+	  "Cannot create WonderWitch HBlank count up timer.");
+  WonxSystem_SetWWHBlankCountUpTimer(wonx_system, ww_timer);
+
+  WWTimer_Reset(WonxSystem_GetWWVBlankTimer(       wonx_system));
+  WWTimer_Reset(WonxSystem_GetWWVBlankCountUpTimer(wonx_system));
+  WWTimer_Reset(WonxSystem_GetWWHBlankCountUpTimer(wonx_system));
+
+  WWTimer_ON( WonxSystem_GetWWVBlankTimer(       wonx_system));
+  WWTimer_OFF(WonxSystem_GetWWVBlankCountUpTimer(wonx_system));
+  WWTimer_OFF(WonxSystem_GetWWHBlankCountUpTimer(wonx_system));
+
+  /* タイマのインターバルは,0.1 秒単位とする */
+  unix_timer = UNIXTimer_Create(1, WONX_TIMER_INTERVAL, wonx_system, 
+				(UNIXTimerCallBack)WonxTimer_Callback);
+  if (unix_timer == NULL)
+    Error("WonxSystem_Create", "Cannot create UNIX timer.");
+  WonxSystem_SetUNIXTimer(wonx_system, unix_timer);
+
+  UNIXTimer_ON(unix_timer);
+
+  return (wonx_system);
+}
+
+WonxSystem WonxSystem_Destroy(WonxSystem wonx_system)
+{
+  WWInterrupt wi;
+  WWTimer wt;
+  UNIXTimer unix_timer;
+
+  if (wonx_system == NULL)
+    Error("WonxSystem_Destroy", "Object is not created.");
+
+  unix_timer = WonxSystem_GetUNIXTimer(wonx_system);
+
+  if (unix_timer)
+    UNIXTimer_OFF(unix_timer);
+
+  wt = WonxSystem_GetWWVBlankTimer(wonx_system);
+  if (wt) WWTimer_OFF(wt);
+  wt = WonxSystem_GetWWVBlankCountUpTimer(wonx_system);
+  if (wt) WWTimer_OFF(wt);
+  wt = WonxSystem_GetWWHBlankCountUpTimer(wonx_system);
+  if (wt) WWTimer_OFF(wt);
+
+  if (unix_timer)
+    WonxSystem_SetUNIXTimer(wonx_system, UNIXTimer_Destroy(unix_timer));
+
+  wt = WonxSystem_GetWWVBlankTimer(wonx_system);
+  if (wt) WonxSystem_SetWWVBlankTimer(wonx_system, WWTimer_Destroy(wt));
+  wt = WonxSystem_GetWWVBlankCountUpTimer(wonx_system);
+  if (wt) WonxSystem_SetWWVBlankCountUpTimer(wonx_system, WWTimer_Destroy(wt));
+  wt = WonxSystem_GetWWHBlankCountUpTimer(wonx_system);
+  if (wt) WonxSystem_SetWWHBlankCountUpTimer(wonx_system, WWTimer_Destroy(wt));
+
+  wi = WonxSystem_GetWWInterrupt(wonx_system);
+  if (wi) WonxSystem_SetWWInterrupt(wonx_system, WWInterrupt_Destroy(wi));
+
+  free(wonx_system);
+
+  return (NULL);
+}
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 53 - 0
WonxSystem.h

@@ -0,0 +1,53 @@
+#ifndef _WonxSystem_h_INCLUDED_
+#define _WonxSystem_h_INCLUDED_
+
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
+#include "WWInterrupt.h"
+#include "WWTimer.h"
+#include "UNIXTimer.h"
+
+/*****************************************************************************/
+/* クラスの定義                                                              */
+/*****************************************************************************/
+
+typedef struct _WonxSystem * WonxSystem;
+
+/*****************************************************************************/
+/* メンバ関数の定義                                                          */
+/*****************************************************************************/
+
+WWInterrupt WonxSystem_GetWWInterrupt(WonxSystem wonx_system);
+WWInterrupt WonxSystem_SetWWInterrupt(WonxSystem wonx_system,
+				      WWInterrupt ww_interrupt);
+
+WWTimer WonxSystem_GetWWTimer(WonxSystem wonx_system, int type);
+WWTimer WonxSystem_SetWWTimer(WonxSystem wonx_system, int type, WWTimer t);
+
+WWTimer WonxSystem_GetWWVBlankTimer(WonxSystem wonx_system);
+WWTimer WonxSystem_SetWWVBlankTimer(WonxSystem wonx_system, WWTimer t);
+
+WWTimer WonxSystem_GetWWVBlankCountUpTimer(WonxSystem wonx_system);
+WWTimer WonxSystem_SetWWVBlankCountUpTimer(WonxSystem wonx_system, WWTimer t);
+
+WWTimer WonxSystem_GetWWHBlankCountUpTimer(WonxSystem wonx_system);
+WWTimer WonxSystem_SetWWHBlankCountUpTimer(WonxSystem wonx_system, WWTimer t);
+
+UNIXTimer WonxSystem_GetUNIXTimer(WonxSystem wonx_system);
+UNIXTimer WonxSystem_SetUNIXTimer(WonxSystem wonx_system,
+				  UNIXTimer unix_timer);
+
+WonxSystem WonxSystem_Create();
+WonxSystem WonxSystem_Destroy(WonxSystem wonx_system);
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+#endif
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 37 - 0
WonxSystemP.h

@@ -0,0 +1,37 @@
+#ifndef _WonxSystemP_h_INCLUDED_
+#define _WonxSystemP_h_INCLUDED_
+
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
+#include "WonxSystem.h"
+
+/*****************************************************************************/
+/* クラスの定義                                                              */
+/*****************************************************************************/
+
+typedef struct _WonxSystem {
+
+  WWInterrupt ww_interrupt;
+
+  /*
+   * ww_timer[0] はVBLANK割り込み用.
+   * ww_timer[1] はVBLANKを利用したタイマカウンタ割り込み用.
+   * ww_timer[2] はHBLANKを利用したタイマカウンタ割り込み用.
+   */
+  WWTimer ww_timer[3];
+
+  UNIXTimer unix_timer;
+
+} _WonxSystem;
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+#endif
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 15 - 1
XDisplay.c

@@ -7,8 +7,9 @@
 #include "etc.h"
 
 #include <stdio.h>
-#include <sys/types.h>
+#include <time.h>
 #include <unistd.h>
+#include <sys/types.h>
 
 /*****************************************************************************/
 /* メンバ関数の定義                                                          */
@@ -69,7 +70,20 @@ static void iconify(Widget w, XEvent * event, String * params, Cardinal * num)
 
 static void sleep_3(Widget w, XEvent * event, String * params, Cardinal * num)
 {
+  time_t old_t;
+  time_t t;
+  int i;
+  /* UNIXTimer.c 内部で SIGALRM を使用しているので,sleep() は使用できない */
+#if 0
   sleep(3);
+#else
+  for (i = 0; i < 3; i++) {
+    time(&t);
+    old_t = t;
+    while (t == old_t)
+      time(&t);
+  }
+#endif
 }
 
 static XtActionsRec actions[] = {

+ 26 - 2
bank.c

@@ -5,14 +5,30 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <sys/bank.h>
+#include "sys/bank.h"
 
 #include "Wonx.h"
 
 /*****************************************************************************/
-/* メンバ関数の定義                                                          */
+/* 互換関数の定義                                                            */
 /*****************************************************************************/
 
+/*
+ * Xサーバとの同期の整合性がとれなくなるなどの問題が考えられるので,
+ * 互換関数の内部は UNIXTimer_Pause(), UNIXTimer_Unpause() でくくり,
+ * タイマ割り込みを一時停止して処理を行う.また,unpause するまえに,
+ * かならず sync するようにする.
+ */
+
+/*
+ * タイマの一時停止の2重解除の問題が出てくるので,
+ * 互換関数から互換関数を呼んではいけない.
+ * (一時停止はネストされるが,いちおう)
+ * 似たような処理をする関数の場合は,必ず static な別関数に処理をまとめ,
+ * そっちを呼び出すようにすること.
+ * 引数の表示の問題もあるしね.
+ */
+
 void bank_set_map(int bank, int bank_num)
 {
   return;
@@ -65,3 +81,11 @@ void bank_erase_flash(int bank)
 {
   return;
 }
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 28 - 4
comm.c

@@ -5,14 +5,30 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <sys/comm.h>
+#include "sys/comm.h"
 
 #include "Wonx.h"
 
 /*****************************************************************************/
-/* メンバ関数の定義                                                          */
+/* 互換関数の定義                                                            */
 /*****************************************************************************/
 
+/*
+ * Xサーバとの同期の整合性がとれなくなるなどの問題が考えられるので,
+ * 互換関数の内部は UNIXTimer_Pause(), UNIXTimer_Unpause() でくくり,
+ * タイマ割り込みを一時停止して処理を行う.また,unpause するまえに,
+ * かならず sync するようにする.
+ */
+
+/*
+ * タイマの一時停止の2重解除の問題が出てくるので,
+ * 互換関数から互換関数を呼んではいけない.
+ * (一時停止はネストされるが,いちおう)
+ * 似たような処理をする関数の場合は,必ず static な別関数に処理をまとめ,
+ * そっちを呼び出すようにすること.
+ * 引数の表示の問題もあるしね.
+ */
+
 void comm_open(void)
 {}
 
@@ -71,9 +87,17 @@ unsigned int comm_get_cancel_key(void)
   return (0);
 }
 
-/*
+#if 0
 int comm_xmodem(void * xmodem)
 {
   return (0);
 }
-*/
+#endif
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 15 - 0
configure.h

@@ -0,0 +1,15 @@
+/* configure.h for configuration of xfireworks */
+
+#ifndef _WONX_CONFIGURE_H_INCLUDED_
+#define _WONX_CONFIGURE_H_INCLUDED_
+
+/* Wonx でのタイマ割り込みの周期(単位はマイクロ秒) */
+#define WONX_TIMER_INTERVAL 100000 /* 0.1 秒*/
+
+/* HBLANK, VBLANK 割り込みのデフォルトのインターバル(0.1秒単位) */
+#define WONX_HBLANK_INTERVAL ( 3 * 10) /*  3 秒毎 */
+#define WONX_VBLANK_INTERVAL (20 * 10) /* 20 秒毎 */
+
+#endif /* _WONX_CONFIGURE_H_INCLUDED_ */
+
+/* End of configure.h */

+ 349 - 83
disp.c

@@ -5,23 +5,42 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <sys/disp.h>
+#include "sys/disp.h"
 
 #include "Wonx.h"
 
 /*****************************************************************************/
-/* メンバ関数の定義                                                          */
+/* 互換関数の定義                                                            */
 /*****************************************************************************/
 
+/*
+ * Xサーバとの同期の整合性がとれなくなるなどの問題が考えられるので,
+ * 互換関数の内部は UNIXTimer_Pause(), UNIXTimer_Unpause() でくくり,
+ * タイマ割り込みを一時停止して処理を行う.また,unpause するまえに,
+ * かならず sync するようにする.
+ */
+
+/*
+ * タイマの一時停止の2重解除の問題が出てくるので,
+ * 互換関数から互換関数を呼んではいけない.
+ * (一時停止はネストされるが,いちおう)
+ * 似たような処理をする関数の場合は,必ず static な別関数に処理をまとめ,
+ * そっちを呼び出すようにすること.
+ * 引数の表示の問題もあるしね.
+ */
+
 void display_control(unsigned int flags)
 {
   WWDisplay ww_display;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : display_control() : flags = 0x%04x\n", (int)flags);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   ww_display = WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay());
 
   WWScreen_SetEnable(WWDisplay_GetScreen(ww_display, SCREEN1),
@@ -47,6 +66,9 @@ void display_control(unsigned int flags)
 
   printf("call : display_control() : return value = none\n"); fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -55,10 +77,13 @@ unsigned int display_status()
   WWDisplay ww_display;
   unsigned short int ret;
 
-  printf("call : display_status() : \n"); fflush(stdout);
-
   if (!Wonx_IsCreated()) Wonx_Create();
 
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  printf("call : display_status() : \n"); fflush(stdout);
+
   ww_display = WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay());
 
   ret = 0;
@@ -69,10 +94,10 @@ unsigned int display_status()
   if (WWScreen_GetEnable(WWDisplay_GetScreen(ww_display, SCREEN2)))
     ret |= DCM_SCR2;
 
-  if (WWDisplay_GetSpriteEnable(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay())))
+  if (WWDisplay_GetSpriteEnable(ww_display))
     ret |= DCM_SPR;
 
-  if (WWDisplay_GetSpriteWindowEnable(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay())))
+  if (WWDisplay_GetSpriteWindowEnable(ww_display))
     ret |= DCM_SPR_WIN;
 
   switch (WWScreen_GetMode(WWDisplay_GetScreen(ww_display, SCREEN2))) {
@@ -85,13 +110,16 @@ unsigned int display_status()
     default:
   }
 
-  ret |= WWDisplay_GetBorder(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay())) << 7;
+  ret |= WWDisplay_GetBorder(ww_display) << 7;
 
   WonxDisplay_Sync(Wonx_GetWonxDisplay());
 
   printf("call : display_status() : return value = %u\n", (int)ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -101,20 +129,25 @@ void font_set_monodata(unsigned int number, unsigned int count, void * data)
   int i, x, y, n, p;
   int f, b;
   unsigned char * d;
+  WWDisplay ww_display;
+
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
 
   printf("call : font_set_monodata() : number = %u, count = %u, data = %p\n",
 	 (int)number, (int)count, data); fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
+  ww_display = WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay());
 
   n = 0;
   d = (unsigned char *)data; /* ひとつのキャラクタデータは8バイト */
-  f = WWDisplay_GetForegroundColor(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()));
-  b = WWDisplay_GetBackgroundColor(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()));
+  f = WWDisplay_GetForegroundColor(ww_display);
+  b = WWDisplay_GetBackgroundColor(ww_display);
 
   for (i = 0; i < count; i++) {
-    c = WWDisplay_GetCharacter(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()),
-			       number + i);
+    c = WWDisplay_GetCharacter(ww_display, number + i);
     for (y = 0; y < 8; y++) {
       for (x = 0; x < 8; x++) {
 	p = (d[n] & (1 << (7 - x))) ? f : b; /*これでよいのか?*/
@@ -129,6 +162,9 @@ void font_set_monodata(unsigned int number, unsigned int count, void * data)
   printf("call : font_set_monodata() : return value = none\n");
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -139,11 +175,14 @@ void font_set_colordata(unsigned int number,
   int i, x, y, n, p;
   unsigned char * d;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : font_set_colordata() : number = %u, count = %u, data = %p\n",
 	 (int)number, (int)count, data); fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   n = 0;
   d = (unsigned char *)data; /* ひとつのキャラクタデータは16バイト */
 
@@ -154,7 +193,8 @@ void font_set_colordata(unsigned int number,
       for (x = 0; x < 8; x++) {
 
 	/*これでよいのか?*/
-	p = ((d[n] & (1 << (7-x))) ? 2 : 0) + ((d[n + 1] & (1 << (7-x))) ? 1 : 0);
+	p = ((d[n] & (1 << (7-x))) ? 2 : 0)
+	  + ((d[n + 1] & (1 << (7-x))) ? 1 : 0);
 
 	WWCharacter_SetPixel(c, x, y, p);
       }
@@ -168,6 +208,9 @@ void font_set_colordata(unsigned int number,
   printf("call : font_set_colordata() : return value = none\n");
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -179,11 +222,14 @@ void font_get_data(unsigned int number,
   int i, x, y, n, p;
   unsigned char * d;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : font_get_data() : number = %u, count = %u, data = %p\n",
 	 (int)number, (int)count, data); fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   n = 0;
   d = (unsigned char *)data; /* ひとつのキャラクタデータは16バイト? */
 
@@ -206,7 +252,11 @@ void font_get_data(unsigned int number,
 
   WonxDisplay_Sync(Wonx_GetWonxDisplay());
 
-  printf("call : font_get_data() : return value = none\n"); fflush(stdout);
+  printf("call : font_get_data() : return value = none\n");
+  fflush(stdout);
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
 
   return;
 }
@@ -215,11 +265,14 @@ void font_set_color(unsigned int colors)
 {
   WWDisplay dis;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : font_set_color() : colors = 0x%04x\n", (int)colors);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   dis = WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay());
   WWDisplay_SetForegroundColor(dis, colors & 0x03);
   WWDisplay_SetBackgroundColor(dis, (colors >> 2) & 0x03);
@@ -228,6 +281,9 @@ void font_set_color(unsigned int colors)
 
   printf("call : font_set_color() : return value = none\n"); fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -236,10 +292,13 @@ unsigned int font_get_color(void)
   unsigned short int ret;
   WWDisplay dis;
 
-  printf("call : font_get_color() : \n"); fflush(stdout);
-
   if (!Wonx_IsCreated()) Wonx_Create();
 
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  printf("call : font_get_color() : \n"); fflush(stdout);
+
   dis = WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay());
   ret = 0;
   ret |= WWDisplay_GetForegroundColor(dis);
@@ -250,6 +309,9 @@ unsigned int font_get_color(void)
   printf("call : font_get_color() : return value = 0x%04x\n", (int)ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -290,12 +352,15 @@ void screen_set_char(int screen, int x, int y, int w, int h, void * data)
   int i, j;
   unsigned short int * d;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : screen_set_char() : screen = %d, x = %d, y = %d, w = %d, h = %d, data = %p\n",
 	 screen, x, y, w, h, data);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   d = (unsigned short int *)data;
 
   for (j = 0; j < h; j++) {
@@ -307,7 +372,11 @@ void screen_set_char(int screen, int x, int y, int w, int h, void * data)
 
   WonxDisplay_Flush(Wonx_GetWonxDisplay());
 
-  printf("call : screen_set_char() : return value = none\n"); fflush(stdout);
+  printf("call : screen_set_char() : return value = none\n");
+  fflush(stdout);
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
 
   return;
 }
@@ -347,12 +416,15 @@ void screen_get_char(int screen, int x, int y, int w, int h, void * data)
   int i, j;
   unsigned short int * d;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : screen_get_char() : screen = %d, x = %d, y = %d, w = %d, h = %d, data = %p\n",
 	 screen, x, y, w, h, data);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   d = (unsigned short int *)data;
 
   for (j = 0; j < h; j++) {
@@ -364,7 +436,11 @@ void screen_get_char(int screen, int x, int y, int w, int h, void * data)
 
   WonxDisplay_Sync(Wonx_GetWonxDisplay());
 
-  printf("call : screen_get_char() : return value = none\n"); fflush(stdout);
+  printf("call : screen_get_char() : return value = none\n");
+  fflush(stdout);
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
 
   return;
 }
@@ -373,12 +449,15 @@ unsigned int screen_get_char1(int screen, int x, int y)
 {
   unsigned short int ret;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : screen_get_char1() : screen = %d, x = %d, y = %d\n",
 	 screen, x, y);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   ret = _screen_get_char1(screen, x, y);
 
   WonxDisplay_Sync(Wonx_GetWonxDisplay());
@@ -386,6 +465,9 @@ unsigned int screen_get_char1(int screen, int x, int y)
   printf("call : screen_get_char1() : return value = 0x%04x\n", (int)ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -394,12 +476,15 @@ void screen_fill_char(int screen, int x, int y, int w, int h,
 {
   int i, j;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : screen_fill_char() : screen = %d, x = %d, y = %d, w = %d, h = %d, data = 0x%04x\n",
 	 screen, x, y, w, h, (int)data);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   for (j = 0; j < h; j++) {
     for (i = 0; i < w; i++) {
       _screen_set_char1(screen, x + i, y + j, data);
@@ -410,6 +495,9 @@ void screen_fill_char(int screen, int x, int y, int w, int h,
 
   printf("call : screen_fill_char() : return value = none\n"); fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -419,11 +507,14 @@ void screen_fill_attr(int screen, int x, int y, int w, int h,
   int i, j;
   unsigned short int c;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : screen_fill_attr() : screen = %d, x = %d, y = %d, w = %d, h = %d, data = 0x%04x, mask = 0x%04x\n",
 	 screen, x, y, w, h, (int)data, (int)mask); fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   for (j = 0; j < h; j++) {
     for (i = 0; i < w; i++) {
       c = _screen_get_char1(screen, x + i, y + j);
@@ -435,18 +526,25 @@ void screen_fill_attr(int screen, int x, int y, int w, int h,
 
   WonxDisplay_Flush(Wonx_GetWonxDisplay());
 
-  printf("call : screen_fill_attr() : return value = none\n"); fflush(stdout);
+  printf("call : screen_fill_attr() : return value = none\n");
+  fflush(stdout);
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
 
   return;
 }
 
 void sprite_set_range(unsigned int sprite_start, unsigned int sprite_count)
 {
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : sprite_set_range() : start = %u, count = %u\n",
 	 (int)sprite_start, (int)sprite_count); fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   WWDisplay_SetSpriteStart(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()),
 			   sprite_start);
   WWDisplay_SetSpriteCount(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()),
@@ -454,7 +552,11 @@ void sprite_set_range(unsigned int sprite_start, unsigned int sprite_count)
 
   WonxDisplay_Flush(Wonx_GetWonxDisplay());
 
-  printf("call : sprite_set_range() : return value = none\n"); fflush(stdout);
+  printf("call : sprite_set_range() : return value = none\n");
+  fflush(stdout);
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
 
   return;
 }
@@ -486,16 +588,23 @@ static void _sprite_set_char(unsigned int sprite_num, unsigned int data)
 
 void sprite_set_char(unsigned int sprite_num, unsigned int data)
 {
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : sprite_set_char() : number = %u, data = 0x%04x\n",
 	 (int)sprite_num, (int)data); fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   _sprite_set_char(sprite_num, data);
 
   WonxDisplay_Flush(Wonx_GetWonxDisplay());
 
-  printf("call : sprite_set_char() : return value = none\n"); fflush(stdout);
+  printf("call : sprite_set_char() : return value = none\n");
+  fflush(stdout);
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
 
   return;
 }
@@ -529,11 +638,14 @@ unsigned int sprite_get_char(unsigned int sprite_num)
 {
   unsigned short int ret;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : sprite_get_char() : number = %u\n", (int)sprite_num);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   ret = _sprite_get_char(sprite_num);
 
   WonxDisplay_Sync(Wonx_GetWonxDisplay());
@@ -541,6 +653,9 @@ unsigned int sprite_get_char(unsigned int sprite_num)
   printf("call : sprite_get_char() : return value = 0x%04x\n", (int)ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -557,12 +672,15 @@ static void _sprite_set_location(unsigned int sprite_num, int x, int y)
 
 void sprite_set_location(unsigned int sprite_num, int x, int y)
 {
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : sprite_set_location() : number = %u, x = %d, y = %d\n",
 	 (int)sprite_num, x, y);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   _sprite_set_location(sprite_num, x, y);
 
   WonxDisplay_Flush(Wonx_GetWonxDisplay());
@@ -570,6 +688,9 @@ void sprite_set_location(unsigned int sprite_num, int x, int y)
   printf("call : sprite_set_location() : return value = none\n");
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -590,11 +711,14 @@ unsigned int sprite_get_location(unsigned int sprite_num)
 {
   unsigned short int ret;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : sprite_get_location() : number = %u\n", (int)sprite_num);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   ret = _sprite_get_location(sprite_num);
 
   WonxDisplay_Sync(Wonx_GetWonxDisplay());
@@ -602,6 +726,9 @@ unsigned int sprite_get_location(unsigned int sprite_num)
   printf("call : sprite_get_location() : return value = 0x%04x\n", (int)ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -617,12 +744,15 @@ static void _sprite_set_char_location(unsigned int sprite_num,
 void sprite_set_char_location(unsigned int sprite_num,
 			      unsigned int data, int x, int y)
 {
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : sprite_set_char_location() : number = %u, data = 0x%04x, x = %d, y = %d\n",
 	 (int)sprite_num, (int)data, x, y);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   _sprite_set_char_location(sprite_num, data, x, y);
 
   WonxDisplay_Flush(Wonx_GetWonxDisplay());
@@ -630,6 +760,9 @@ void sprite_set_char_location(unsigned int sprite_num,
   printf("call : sprite_set_char_location() : return value = none\n");
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -637,11 +770,14 @@ unsigned long int sprite_get_char_location(unsigned int sprite_num)
 {
   unsigned long int ret;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : sprite_get_char_location() : number = %u\n", (int)sprite_num);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   ret = 0;
   ret |= ((unsigned long int)_sprite_get_char(sprite_num));
   ret |= (unsigned long int)_sprite_get_location(sprite_num) << 16;
@@ -652,6 +788,9 @@ unsigned long int sprite_get_char_location(unsigned int sprite_num)
 	 (int)ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -660,12 +799,15 @@ void sprite_set_data(unsigned int sprite_num, unsigned int count, void * data)
   int i;
   unsigned long int * n;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : sprite_set_data() : number = %u, count = %u, data = %p\n",
 	 (int)sprite_num, (int)count, data);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   n = (unsigned long int *)data;
   for (i = 0; i < count; i++) {
     _sprite_set_char_location(sprite_num + i,
@@ -676,7 +818,11 @@ void sprite_set_data(unsigned int sprite_num, unsigned int count, void * data)
 
   WonxDisplay_Flush(Wonx_GetWonxDisplay());
 
-  printf("call : sprite_set_data() : return value = none\n"); fflush(stdout);
+  printf("call : sprite_set_data() : return value = none\n");
+  fflush(stdout);
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
 
   return;
 }
@@ -685,12 +831,15 @@ void screen_set_scroll(int screen, int x, int y)
 {
   WWScreen s;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : screen_set_scroll() : screen = %d, x = %d, y = %d\n",
 	 screen, x, y);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   s = WWDisplay_GetScreen(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()),
 			  screen);
   WWScreen_SetRollX(s, x);
@@ -698,7 +847,11 @@ void screen_set_scroll(int screen, int x, int y)
 
   WonxDisplay_Flush(Wonx_GetWonxDisplay());
 
-  printf("call : screen_set_scroll() : return value = none\n"); fflush(stdout);
+  printf("call : screen_set_scroll() : return value = none\n");
+  fflush(stdout);
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
 
   return;
 }
@@ -708,10 +861,13 @@ unsigned int screen_get_scroll(int screen)
   unsigned short int ret;
   WWScreen s;
 
-  printf("call : screen_get_scroll() : screen = %d\n", screen); fflush(stdout);
-
   if (!Wonx_IsCreated()) Wonx_Create();
 
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  printf("call : screen_get_scroll() : screen = %d\n", screen); fflush(stdout);
+
   s = WWDisplay_GetScreen(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()),
 			  screen);
 
@@ -724,6 +880,9 @@ unsigned int screen_get_scroll(int screen)
   printf("call : screen_get_scroll() : return value = %u\n", (int)ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -731,11 +890,14 @@ void screen2_set_window(int x, int y, int w, int h)
 {
   WWScreen s;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : screen2_set_window() : x = %d, y = %d, width = %d, height = %d\n",
 	 x, y, w, h); fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   s = WWDisplay_GetScreen(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()),
 			  SCREEN2);
   WWScreen_SetDrawX(s, x);
@@ -748,6 +910,9 @@ void screen2_set_window(int x, int y, int w, int h)
   printf("call : screen2_set_window() : return value = none\n");
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -760,6 +925,9 @@ unsigned long int screen2_get_window(void)
 
   if (!Wonx_IsCreated()) Wonx_Create();
 
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : screen2_get_window() : \n"); fflush(stdout);
 
   s = WWDisplay_GetScreen(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()),
@@ -778,6 +946,9 @@ unsigned long int screen2_get_window(void)
   printf("call : screen2_get_window() : return value = 0x%08x\n", (int)ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -785,12 +956,15 @@ void sprite_set_window(int x, int y, int w, int h)
 {
   WWDisplay d;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : sprite_set_window() : x = %d, y = %d, w = %d, h = %d\n",
 	 x, y, w, h);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   d = WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay());
 
   WWDisplay_SetSpriteWindowX(d, x);
@@ -803,6 +977,9 @@ void sprite_set_window(int x, int y, int w, int h)
   printf("call : sprite_set_window() : return value = none\n");
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -813,11 +990,14 @@ unsigned long int sprite_get_window(void)
   unsigned short int wh;
   unsigned long int ret;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : sprite_get_window() : \n");
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   d = WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay());
 
   xy =
@@ -833,6 +1013,9 @@ unsigned long int sprite_get_window(void)
   printf("call : sprite_get_window() : return value = 0x%08x\n", (int)ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -842,23 +1025,32 @@ void palette_set_color(unsigned int palette_num,
   int mapped_colors[4];
   WWPalette palette;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : palette_set_color() : number = %u, colors = 0x%04x\n",
 	 (int)palette_num, (int)colors); fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   mapped_colors[0] = colors & 0x07;
   mapped_colors[1] = (colors >>  4) & 0x07;
   mapped_colors[2] = (colors >>  8) & 0x07;
   mapped_colors[3] = (colors >> 12) & 0x07;
 
-  palette = WWDisplay_GetPalette(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()), palette_num);
+  palette =
+    WWDisplay_GetPalette(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()),
+			 palette_num);
 
   WWPalette_SetMappedColors(palette, mapped_colors);
 
   WonxDisplay_Flush(Wonx_GetWonxDisplay());
 
-  printf("call : palette_set_color() : return value = none\n"); fflush(stdout);
+  printf("call : palette_set_color() : return value = none\n");
+  fflush(stdout);
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
 
   return;
 }
@@ -869,13 +1061,17 @@ unsigned int palette_get_color(unsigned int palette_num)
   WWPalette palette;
   unsigned short int ret;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : palette_get_color() : number = %u\n", (int)palette_num);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
-  palette = WWDisplay_GetPalette(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()),
-				 palette_num);
+  palette =
+    WWDisplay_GetPalette(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()),
+			 palette_num);
   WWPalette_GetMappedColors(palette, mapped_colors);
 
   ret = 0;
@@ -889,6 +1085,9 @@ unsigned int palette_get_color(unsigned int palette_num)
   printf("call : palette_get_color() : return value = %u\n", (int)ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -897,11 +1096,14 @@ void lcd_set_color(unsigned int colors0, unsigned int colors1)
   WWColorMap color_map;
   int lcd_colors[8];
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : lcd_set_color() : colors0 = 0x%04x, colors1 = 0x%04x\n",
 	 (int)colors0, (int)colors1); fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   lcd_colors[0] =  colors0        & 0x0f;
   lcd_colors[1] = (colors0 >>  4) & 0x0f;
   lcd_colors[2] = (colors0 >>  8) & 0x0f;
@@ -911,12 +1113,17 @@ void lcd_set_color(unsigned int colors0, unsigned int colors1)
   lcd_colors[6] = (colors1 >>  8) & 0x0f;
   lcd_colors[7] = (colors1 >> 12) & 0x0f;
 
-  color_map = WWDisplay_GetColorMap(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()));
+  color_map =
+    WWDisplay_GetColorMap(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()));
   WWColorMap_SetLCDColors(color_map, lcd_colors);
 
   WonxDisplay_Flush(Wonx_GetWonxDisplay());
 
-  printf("call : lcd_set_color() : return value = none\n"); fflush(stdout);
+  printf("call : lcd_set_color() : return value = none\n");
+  fflush(stdout);
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
 
   return;
 }
@@ -927,11 +1134,15 @@ unsigned long int lcd_get_color(void)
   int lcd_colors[8];
   unsigned long int ret;
 
-  printf("call : lcd_get_color() : \n"); fflush(stdout);
-
   if (!Wonx_IsCreated()) Wonx_Create();
 
-  color_map = WWDisplay_GetColorMap(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()));
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  printf("call : lcd_get_color() : \n"); fflush(stdout);
+
+  color_map =
+    WWDisplay_GetColorMap(WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay()));
   WWColorMap_GetLCDColors(color_map, lcd_colors);
 
   ret = 0;
@@ -949,42 +1160,77 @@ unsigned long int lcd_get_color(void)
   printf("call : lcd_get_color() : return value = 0x%08x\n", (int)ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
 void lcd_set_segments(unsigned segments)
 {
   if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   /* セグメント表示は未サポートか? */
 
   WonxDisplay_Flush(Wonx_GetWonxDisplay());
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  return;
 }
 
 unsigned int lcd_get_segments(void)
 {
   if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   /* セグメント表示は未サポートか? */
 
   WonxDisplay_Sync(Wonx_GetWonxDisplay());
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (0);
 }
 
-void lcd_set_sleep(unsigned sleep)
+void lcd_set_sleep(unsigned slp)
 {
   if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   /* ? */
 
   WonxDisplay_Sync(Wonx_GetWonxDisplay());
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  return;
 }
 
 unsigned int lcd_get_sleep(void)
 {
   if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   /* ? */
 
   WonxDisplay_Sync(Wonx_GetWonxDisplay());
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (0);
 }
 
@@ -992,14 +1238,34 @@ void screen_set_vram(int screen, int locationID)
 {
   if (!Wonx_IsCreated()) Wonx_Create();
 
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  /* 未サポート */
+
   WonxDisplay_Sync(Wonx_GetWonxDisplay());
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  return;
 }
 
 void sprite_set_vram(int locationID)
 {
   if (!Wonx_IsCreated()) Wonx_Create();
 
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  /* 未サポート */
+
   WonxDisplay_Sync(Wonx_GetWonxDisplay());
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  return;
 }
 
 /*****************************************************************************/

+ 84 - 13
key.c

@@ -1,19 +1,46 @@
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <sys/key.h>
+#include "sys/key.h"
 
 #include "Wonx.h"
 
+/*****************************************************************************/
+/* 互換関数の定義                                                            */
+/*****************************************************************************/
+
+/*
+ * Xサーバとの同期の整合性がとれなくなるなどの問題が考えられるので,
+ * 互換関数の内部は UNIXTimer_Pause(), UNIXTimer_Unpause() でくくり,
+ * タイマ割り込みを一時停止して処理を行う.また,unpause するまえに,
+ * かならず sync するようにする.
+ */
+
+/*
+ * タイマの一時停止の2重解除の問題が出てくるので,
+ * 互換関数から互換関数を呼んではいけない.
+ * (一時停止はネストされるが,いちおう)
+ * 似たような処理をする関数の場合は,必ず static な別関数に処理をまとめ,
+ * そっちを呼び出すようにすること.
+ * 引数の表示の問題もあるしね.
+ */
+
 int key_press_check(void)
 {
   XDisplay x_display;
   int ret;
 
-  printf("call : key_press_check() : "); fflush(stdout);
-
   if (!Wonx_IsCreated()) Wonx_Create();
 
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  printf("call : key_press_check() : "); fflush(stdout);
+
   x_display = WonxDisplay_GetXDisplay(Wonx_GetWonxDisplay());
   XDisplay_Sync(x_display);
 
@@ -23,6 +50,9 @@ int key_press_check(void)
 
   printf("return value = 0x%04x\n", (int)ret); fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -31,10 +61,13 @@ int key_hit_check(void)
   XDisplay x_display;
   int ret;
 
-  printf("call : key_hit_check() : "); fflush(stdout);
-
   if (!Wonx_IsCreated()) Wonx_Create();
 
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  printf("call : key_hit_check() : "); fflush(stdout);
+
   x_display = WonxDisplay_GetXDisplay(Wonx_GetWonxDisplay());
   XDisplay_Sync(x_display);
 
@@ -44,6 +77,9 @@ int key_hit_check(void)
 
   printf("return value = 0x%04x\n", (int)ret); fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -52,12 +88,19 @@ int key_wait(void)
   XDisplay x_display;
   int ret;
 
-  printf("call : key_wait() : "); fflush(stdout);
-
   if (!Wonx_IsCreated()) Wonx_Create();
 
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  printf("call : key_wait() : "); fflush(stdout);
+
   x_display = WonxDisplay_GetXDisplay(Wonx_GetWonxDisplay());
 
+  /*
+   * 以下はホットスポットになり得るので注意!
+   */
+
   ret = 0;
   do {
     XDisplay_Sync(x_display);
@@ -68,20 +111,29 @@ int key_wait(void)
 
   printf("return value = 0x%04x\n", (int)ret); fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
 void key_set_repeat(int rate, int delay)
 {
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : key_set_repeat() : rate = %d, delay = %d, ", rate, delay);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   WonxDisplay_Sync(Wonx_GetWonxDisplay());
 
   printf("return value = none\n"); fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -89,16 +141,22 @@ int key_get_repeat(void)
 {
   int ret;
 
-  printf("call : key_get_repeat() : "); fflush(stdout);
-
   if (!Wonx_IsCreated()) Wonx_Create();
 
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  printf("call : key_get_repeat() : "); fflush(stdout);
+
   ret = 0;
 
   WonxDisplay_Sync(Wonx_GetWonxDisplay());
 
   printf("return value = 0x%04x\n", (int)ret); fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -107,10 +165,13 @@ int key_hit_check_with_repeat(void)
   XDisplay x_display;
   int ret;
 
-  printf("call : key_hit_check_with_repeat() : "); fflush(stdout);
-
   if (!Wonx_IsCreated()) Wonx_Create();
 
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  printf("call : key_hit_check_with_repeat() : "); fflush(stdout);
+
   x_display = WonxDisplay_GetXDisplay(Wonx_GetWonxDisplay());
   XDisplay_Sync(x_display);
 
@@ -120,6 +181,16 @@ int key_hit_check_with_repeat(void)
 
   printf("return value = 0x%04x\n", (int)ret); fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 26 - 2
sound.c

@@ -5,14 +5,30 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include <sys/sound.h>
+#include "sys/sound.h"
 
 #include "Wonx.h"
 
 /*****************************************************************************/
-/* メンバ関数の定義                                                          */
+/* 互換関数の定義                                                            */
 /*****************************************************************************/
 
+/*
+ * Xサーバとの同期の整合性がとれなくなるなどの問題が考えられるので,
+ * 互換関数の内部は UNIXTimer_Pause(), UNIXTimer_Unpause() でくくり,
+ * タイマ割り込みを一時停止して処理を行う.また,unpause するまえに,
+ * かならず sync するようにする.
+ */
+
+/*
+ * タイマの一時停止の2重解除の問題が出てくるので,
+ * 互換関数から互換関数を呼んではいけない.
+ * (一時停止はネストされるが,いちおう)
+ * 似たような処理をする関数の場合は,必ず static な別関数に処理をまとめ,
+ * そっちを呼び出すようにすること.
+ * 引数の表示の問題もあるしね.
+ */
+
 void sound_init(void)
 {
   return;
@@ -87,3 +103,11 @@ unsigned int sound_get_random(void)
 {
   return (0);
 }
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 87 - 3
system.c

@@ -1,15 +1,91 @@
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
 #include <stdlib.h>
 
-#include <sys/system.h>
+#include "sys/system.h"
 
 #include "Wonx.h"
 
+/*****************************************************************************/
+/* 互換関数の定義                                                            */
+/*****************************************************************************/
+
+/*
+ * Xサーバとの同期の整合性がとれなくなるなどの問題が考えられるので,
+ * 互換関数の内部は UNIXTimer_Pause(), UNIXTimer_Unpause() でくくり,
+ * タイマ割り込みを一時停止して処理を行う.また,unpause するまえに,
+ * かならず sync するようにする.
+ */
+
+/*
+ * タイマの一時停止の2重解除の問題が出てくるので,
+ * 互換関数から互換関数を呼んではいけない.
+ * (一時停止はネストされるが,いちおう)
+ * 似たような処理をする関数の場合は,必ず static な別関数に処理をまとめ,
+ * そっちを呼び出すようにすること.
+ * 引数の表示の問題もあるしね.
+ */
+
 void sys_interrupt_set_hook(int type, intvector_t * intvector,
 			    intvector_t * last_intvector)
-{}
+{
+  WWInterrupt ww_interrupt;
+
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  printf("call : sys_interrupt_set_hook() : type = %d, intvector = %p, last_intvector = %p\n", type, intvector, last_intvector);
+  fflush(stdout);
+
+  ww_interrupt = WonxSystem_GetWWInterrupt(Wonx_GetWonxSystem());
+
+  last_intvector->callback = WWInterrupt_GetCallback(ww_interrupt, type);
+  last_intvector->cs = WWInterrupt_GetCS(ww_interrupt, type);
+  last_intvector->ds = WWInterrupt_GetDS(ww_interrupt, type);
+
+  WWInterrupt_SetCallback(ww_interrupt, type, intvector->callback);
+  WWInterrupt_SetCS(ww_interrupt, type, intvector->cs);
+  WWInterrupt_SetDS(ww_interrupt, type, intvector->ds);
+
+  printf("call : sys_interrupt_set_hook() : return value = none\n");
+  fflush(stdout);
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  return;
+}
 
 void sys_interrupt_reset_hook(int type, intvector_t * last_intvector)
-{}
+{
+  WWInterrupt ww_interrupt;
+
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  printf("call : sys_interrupt_reset_hook() : type = %d, last_intvector = %p\n", type, last_intvector);
+  fflush(stdout);
+
+  ww_interrupt = WonxSystem_GetWWInterrupt(Wonx_GetWonxSystem());
+
+  WWInterrupt_SetCallback(ww_interrupt, type, last_intvector->callback);
+  WWInterrupt_SetCS(ww_interrupt, type, last_intvector->cs);
+  WWInterrupt_SetDS(ww_interrupt, type, last_intvector->ds);
+
+  printf("call : sys_interrupt_reset_hook() : return value = none\n");
+  fflush(stdout);
+
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
+  return;
+}
 
 void sys_wait(unsigned int time)
 {
@@ -99,3 +175,11 @@ unsigned int sys_get_resume(void)
 {
   return (0);
 }
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 120 - 23
text.c

@@ -1,11 +1,35 @@
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
 #include <stdlib.h>
 #include <string.h>
 
-#include <sys/text.h>
+#include "sys/text.h"
 
 #include "Wonx.h"
 #include "WWText.h"
 
+/*****************************************************************************/
+/* 互換関数の定義                                                            */
+/*****************************************************************************/
+
+/*
+ * Xサーバとの同期の整合性がとれなくなるなどの問題が考えられるので,
+ * 互換関数の内部は UNIXTimer_Pause(), UNIXTimer_Unpause() でくくり,
+ * タイマ割り込みを一時停止して処理を行う.また,unpause するまえに,
+ * かならず sync するようにする.
+ */
+
+/*
+ * タイマの一時停止の2重解除の問題が出てくるので,
+ * 互換関数から互換関数を呼んではいけない.
+ * (一時停止はネストされるが,いちおう)
+ * 似たような処理をする関数の場合は,必ず static な別関数に処理をまとめ,
+ * そっちを呼び出すようにすること.
+ * 引数の表示の問題もあるしね.
+ */
+
 static void _text_window_init(int x, int y, int w, int h, unsigned font_base)
 {
   WWText ww_text;
@@ -27,11 +51,14 @@ void text_screen_init(void)
   WWDisplay ww_display;
   WWLCDPanel ww_lcd_panel;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : text_screen_init() : \n");
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   ww_display = WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay());
   ww_lcd_panel = WWDisplay_GetLCDPanel(ww_display);
 
@@ -41,6 +68,9 @@ void text_screen_init(void)
 
   printf("call : text_screen_init() : return value = none\n"); fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -48,11 +78,14 @@ void text_window_init(int x, int y, int w, int h, unsigned int font_base)
 {
   WWDisplay ww_display;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : text_window_init() : x = %d, y = %d, width = %d, height = %d, base = %u\n", x, y, w, h, (int)font_base);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   ww_display = WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay());
 
   _text_window_init(x, y, w, h, font_base);
@@ -61,6 +94,9 @@ void text_window_init(int x, int y, int w, int h, unsigned int font_base)
 
   printf("call : text_screen_init() : return value = none\n"); fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -88,17 +124,23 @@ void _text_put_char(int x, int y, unsigned int c)
 
 void text_put_char(int x, int y, unsigned int c)
 {
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : text_put_char() : x = %d, y = %d, character = %u\n", x, y, (int)c);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   _text_put_char(x, y, c);
 
   WonxDisplay_Flush(Wonx_GetWonxDisplay());
 
   printf("call : text_put_char() : return value = none\n"); fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -125,11 +167,14 @@ int text_put_string(int x, int y, char * s)
 {
   int ret;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : text_put_string() : x = %d, y = %d, string = %s\n", x, y, s);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   ret = _text_put_string(x, y, s);
 
   WonxDisplay_Flush(Wonx_GetWonxDisplay());
@@ -137,6 +182,9 @@ int text_put_string(int x, int y, char * s)
   printf("call : text_put_string() : return value = %d\n", ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -146,11 +194,14 @@ int text_put_substring(int x, int y, char * s, int len)
   WWText ww_text;
   WWDisplay ww_display;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : text_put_substring() : x = %d, y = %d, string = %s, length = %d\n", x, y, s, len);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   ww_text = WonxText_GetWWText(Wonx_GetWonxText());
   ww_display = WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay());
 
@@ -165,6 +216,9 @@ int text_put_substring(int x, int y, char * s, int len)
   printf("call : text_put_substring() : return value = %d\n", ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
 
@@ -173,11 +227,14 @@ void text_put_numeric(int x, int y, int len, int format, int number)
   char buf[20];
   char f[20];
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : text_put_numeric() : x = %d, y = %d, len = %d, format = %04x, number = %d\n", x, y, len, format, number);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   strcpy(f, "%");
 
   if (format & NUM_PADZERO) strcat(f, "0");
@@ -195,6 +252,9 @@ void text_put_numeric(int x, int y, int len, int format, int number)
   printf("call : text_put_numeric() : return value = none\n");
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -206,11 +266,14 @@ void text_fill_char(int x, int y, int len, int code)
 {
   int i;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : text_fill_char() : x = %d, y = %d, length = %d, code = %d\n", x, y, len, code);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   for (i = 0; i < len; i++) {
     _text_put_char(x + i, y, code);
   }
@@ -220,6 +283,9 @@ void text_fill_char(int x, int y, int len, int code)
   printf("call : text_fill_char() : return value = none\n");
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -228,11 +294,14 @@ void text_set_palette(int palette_num)
   WWText ww_text;
   WWDisplay ww_display;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : text_set_palette() : palette = %d\n", palette_num);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   ww_text = WonxText_GetWWText(Wonx_GetWonxText());
   ww_display = WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay());
 
@@ -243,6 +312,9 @@ void text_set_palette(int palette_num)
   printf("call : text_set_palette() : return value = none\n");
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -251,11 +323,14 @@ int text_get_palette(void)
   WWText ww_text;
   int num;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : text_get_palette() : \n");
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   ww_text = WonxText_GetWWText(Wonx_GetWonxText());
 
   num = WWPalette_GetNumber(WWText_GetPalette(ww_text));
@@ -265,6 +340,9 @@ int text_get_palette(void)
   printf("call : text_get_palette() : return value = %d\n", num);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (num);
 }
 
@@ -286,11 +364,14 @@ void text_set_screen(int screen)
   WWText ww_text;
   WWDisplay ww_display;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : text_set_screen() : screen = %d\n", screen);
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   ww_text = WonxText_GetWWText(Wonx_GetWonxText());
   ww_display = WonxDisplay_GetWWDisplay(Wonx_GetWonxDisplay());
 
@@ -301,6 +382,9 @@ void text_set_screen(int screen)
   printf("call : text_set_screen() : return value = none\n");
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
@@ -309,11 +393,14 @@ int text_get_screen(void)
   WWText ww_text;
   int n;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : text_get_screen() : \n");
   fflush(stdout);
 
-  if (!Wonx_IsCreated()) Wonx_Create();
-
   ww_text = WonxText_GetWWText(Wonx_GetWonxText());
 
   n = WWScreen_GetNumber(WWText_GetScreen(ww_text));
@@ -323,6 +410,9 @@ int text_get_screen(void)
   printf("call : text_set_screen() : return value = %d\n", n);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (n);
 }
 
@@ -358,3 +448,10 @@ int text_printf(int x, int y, const char *format, ...)
   return (0);
 }
 
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/

+ 130 - 7
timer.c

@@ -1,10 +1,15 @@
+/*****************************************************************************/
+/* ここから                                                                  */
+/*****************************************************************************/
+
 #include <stdlib.h>
 #include <time.h>
 
-#include <sys/timer.h>
+#include "sys/timer.h"
 
 #include "Wonx.h"
 #include "etc.h"
+#include "configure.h"
 
 typedef struct {
   unsigned char year;
@@ -31,6 +36,26 @@ static int get_minute(struct tm * tblock) { return (tblock->tm_min); }
 /* int tm_sec; seconds (0 - 60) */
 static int get_second(struct tm * tblock) { return (tblock->tm_sec); }
 
+/*****************************************************************************/
+/* 互換関数の定義                                                            */
+/*****************************************************************************/
+
+/*
+ * Xサーバとの同期の整合性がとれなくなるなどの問題が考えられるので,
+ * 互換関数の内部は UNIXTimer_Pause(), UNIXTimer_Unpause() でくくり,
+ * タイマ割り込みを一時停止して処理を行う.また,unpause するまえに,
+ * かならず sync するようにする.
+ */
+
+/*
+ * タイマの一時停止の2重解除の問題が出てくるので,
+ * 互換関数から互換関数を呼んではいけない.
+ * (一時停止はネストされるが,いちおう)
+ * 似たような処理をする関数の場合は,必ず static な別関数に処理をまとめ,
+ * そっちを呼び出すようにすること.
+ * 引数の表示の問題もあるしね.
+ */
+
 void rtc_set_datetime(int field, unsigned int value)
 {
   printf("call : rtc_set_datetime() : field = %d, value = %d\n",
@@ -147,45 +172,143 @@ void rtc_disable_alarm(void)
 
 void timer_enable(int type, unsigned int auto_preset, unsigned int preset)
 {
+  WWTimer ww_timer;
+
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : timer_enable() : type = %d, auto_preset = %u, preset = %u\n",
 	 type, (int)auto_preset, (int)preset);
   fflush(stdout);
 
-  /* 未サポート */
-  printf("call : timer_enable() : not supported\n");
+  /*
+   * TIMER_HBLANK の場合は,1/(75*144) 秒?
+   * TIMER_VBLANK の場合は,1/75 秒
+   * だが,実際にそんな短い時間にしたら wonx の描画がついていけないので,
+   * だいぶ長めにしてある.
+   */
+
+  switch (type) {
+  case TIMER_VBLANK:
+    ww_timer = WonxSystem_GetWWVBlankCountUpTimer(Wonx_GetWonxSystem());
+    WWTimer_SetPresetCounter(ww_timer, preset * WONX_VBLANK_INTERVAL);
+    break;
+  case TIMER_HBLANK:
+    ww_timer = WonxSystem_GetWWHBlankCountUpTimer(Wonx_GetWonxSystem());
+    WWTimer_SetPresetCounter(ww_timer, preset * WONX_HBLANK_INTERVAL);
+    break;
+  default:
+    /*
+     * 無意味だが,gcc -Wall でコンパイルするとワーニングが出るので,
+     * NULL に初期化する.
+     */
+    ww_timer = NULL;
+    Error("timer_enable", "Invalid timer type.");
+  }
+
+  switch (auto_preset) {
+  case TIMER_ONESHOT:    WWTimer_SetAutoPresetOFF(ww_timer); break;
+  case TIMER_AUTOPRESET: WWTimer_SetAutoPresetON( ww_timer); break;
+  default: Error("timer_enable", "Invalid auto preset type.");
+  }
+
+  WWTimer_Reset(ww_timer);
+  WWTimer_ON(ww_timer);
 
   printf("call : timer_enable() : return value = none\n");
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
 void timer_disable(int type)
 {
+  WWTimer ww_timer;
+
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : timer_disable() : type = %d\n", type);
   fflush(stdout);
 
-  /* 未サポート */
-  printf("call : timer_disable() : not supported\n");
+  switch (type) {
+  case TIMER_VBLANK:
+    ww_timer = WonxSystem_GetWWVBlankCountUpTimer(Wonx_GetWonxSystem());
+    break;
+  case TIMER_HBLANK:
+    ww_timer = WonxSystem_GetWWHBlankCountUpTimer(Wonx_GetWonxSystem());
+    break;
+  default:
+    /*
+     * 無意味だが,gcc -Wall でコンパイルするとワーニングが出るので,
+     * NULL に初期化する.
+     */
+    ww_timer = NULL;
+    Error("timer_disable", "Invalid timer type.");
+  }
+
+  WWTimer_OFF(ww_timer);
 
   printf("call : timer_disable() : return value = none\n");
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return;
 }
 
 unsigned int timer_get_count(int type)
 {
+  WWTimer ww_timer;
   unsigned int ret = 0;
 
+  if (!Wonx_IsCreated()) Wonx_Create();
+
+  /* タイマを一時停止する */
+  UNIXTimer_Pause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   printf("call : timer_get_count() : type = %d\n", type);
   fflush(stdout);
 
-  /* 未サポート */
-  printf("call : timer_get_count() : not supported\n");
+  switch (type) {
+  case TIMER_VBLANK:
+    ww_timer = WonxSystem_GetWWVBlankCountUpTimer(Wonx_GetWonxSystem());
+    break;
+  case TIMER_HBLANK:
+    ww_timer = WonxSystem_GetWWHBlankCountUpTimer(Wonx_GetWonxSystem());
+    break;
+  default:
+    /*
+     * 無意味だが,gcc -Wall でコンパイルするとワーニングが出るので,
+     * NULL に初期化する.
+     */
+    ww_timer = NULL;
+    Error("timer_get_count", "Invalid timer type.");
+  }
+
+  ret = WWTimer_GetCounter(ww_timer);
 
   printf("call : timer_get_count() : return value = %u\n", ret);
   fflush(stdout);
 
+  /* タイマをもとに戻す */
+  UNIXTimer_Unpause(WonxSystem_GetUNIXTimer(Wonx_GetWonxSystem()));
+
   return (ret);
 }
+
+/*****************************************************************************/
+/* ここまで                                                                  */
+/*****************************************************************************/
+
+/*****************************************************************************/
+/* End of File.                                                              */
+/*****************************************************************************/