非専門的シンギュラリティー研究所

無限に動き続けるシステムを表す方法を AI なども使って考えていきます。

X68000(12)

X68000 のマウス処理のやり方は Windows とは違うということがわかってきたので、Windows 上で動作確認をするためには同様の処理を Windows 上のプログラミング言語で書けるようにした方が良いようです。

X68000 のマウス処理のサンプルを ChatGPT で C と X-BASIC で書いてもらいましたが、まだ X68000エミュレーター上で実行することはできていません。

X68000エミュレーター上でマウスの処理をする C 言語のプログラムのサンプルを作ってください

と入力すると以下のような回答が返されました。

もちろんです!
X68000エミュレーター(例えば XM6i や PX68k)上で動かすために、X68000 のハードウェア(特にSCCやジョイスティックポート)を直接叩くか、またはHuman68k OSのAPIBios, GEM等)を利用する方法がありますが、ここでは Human68k OS上で動作する、マウス座標の取得とクリック検出を行う簡単なC言語プログラムのサンプル を紹介します。

🖱️ Human68k + C言語 + Human68k API使用例

Human68k には、`INT 3Eh`(マウスサービス)というBIOSコールがあります。
C言語(HUMAN68K用)からは、インラインアセンブラまたはラッパー関数を使って呼び出すのが一般的です。

以下に、C言語GCC / Aztec Cなど)でマウス座標とボタン状態を取得して画面に表示するサンプルを示します。

📄 サンプルコード

#include <stdio.h>
#include <dos.h>   // for _bios_ and _bios_68k_ support (depending on compiler)
#include <conio.h> // for getch()

// Human68k BIOS マウスサービス呼び出し(INT 3Eh)
typedef struct {
    short x;
    short y;
    short buttons;
} MouseState;

// マウス座標取得
void get_mouse_state(MouseState *state)
{
    union REGS regs;

    regs.h.ah = 0;  // AH=0: Get Mouse Status
    int86(0x3E, &regs, &regs);

    state->x = regs.x.cx;
    state->y = regs.x.dx;
    state->buttons = regs.x.bx; // 0=none, 1=left, 2=right, 3=both
}

int main(void)
{
    MouseState state;

    printf("X68000 Mouse Sample Program\n");
    printf("Press any key to exit.\n");

    while (!kbhit())
    {
        get_mouse_state(&state);

        printf("\rX: %d  Y: %d  Buttons: %d  ", state.x, state.y, state.buttons);
    }

    getch(); // wait for a key press before exit
    printf("\nBye!\n");
    return 0;
}

💡 ポイント

✅ `int86()` を使って `INT 3Eh` を呼び出しています。
✅ 取得したマウスのX座標、Y座標、ボタン状態を画面に表示しています。
✅ `kbhit()` でキー押下を検出し、プログラムを終了できます。

⚠️ 注意

1. コンパイラ依存

* `int86()` が使えるかどうかはコンパイラ(Aztec C, Lattice C, GCC68k など)によります。
* GCC (e.g. cross-GCC) ならアセンブラで書いたほうが移植しやすいです。

2. GEM使用の場合

* GEMを使用している場合は、GEMのマウスAPI経由でマウス座標を取得する方法もあります。
* ここではあえてHuman68k BIOS呼び出しの例にしています。

3. 解像度について

* 画面解像度や表示座標の単位は、X68000のグラフィックモードやマウスドライバの設定によって変わります。

もし特定のコンパイラ(Aztec C, GCC68kなど)やライブラリ(GEM, Human68k BIOS直叩きなど)の指定があれば、もう少し具体的に合わせたコードを提供できますので、教えてくださいね!

クロス開発環境 elf2x68k でコンパイルする方法を教えてください

と入力すると以下のような回答が返されました。

もちろんです!
`elf2x68k` を使って ロスコンパイル環境X68000 用のバイナリを作る流れを簡単に説明しますね。

🛠️ 基本的な流れ

1️⃣ ソースコード作成

例えば `mouse.c` という名前で以下のようなコードを書きます:

#include <stdio.h>

int main(void)
{
    printf("Hello, X68000 World!\n");
    return 0;
}

(実際には先ほどの `get_mouse_state()` のサンプルでもOKです)

2️⃣ クロスコンパイル(GCC68k)

例えばLinuxWindowsのWSLで以下のようにGCC(m68k-elf-gccなど)を使ってコンパイルします:

m68k-elf-gcc -O2 -o mouse.elf mouse.c

この時点で `mouse.elf` というELFフォーマットのファイルができます。
(実行形式はまだX68000上でそのまま実行できません)

3️⃣ elf2x68k で X68000形式に変換

次に `elf2x68k` を使って `.x`(X68000実行形式)に変換します:

elf2x68k mouse.elf mouse.x

この `mouse.x` がX68000エミュレーターや実機)で実行できるバイナリです。

🔧 追加ヒント

パスが通っていない場合 は `elf2x68k` コマンドが見つからないので、ビルド済みの `elf2x68k` をパスに通すか `./elf2x68k` のようにパスを明示します。

リンカスクリプト
特定のセクションアドレスを設定したい場合は、`m68k-elf-ld` にカスタムリンカスクリプトを指定します(例: `-T x68k.ld`)。

libc
Human68k のAPI呼び出しやstdioサポートは、ツールチェインやサンプルライブラリ(libx68kなど)を使用する必要があります。
一部のクロス環境(`gcc68k`)では libx68k などが同梱されています。
もし「undefined reference to `_bios`」などのリンクエラーが出た場合、リンク時に `-lx68k` を追加したり、自分で実装する必要があります。

🔥 まとめ

ステップ コマンド例
ソースコード作成 `mouse.c`
ロスコンパイル `m68k-elf-gcc -O2 -o mouse.elf mouse.c`
X68000形式変換 `elf2x68k mouse.elf mouse.x`

もし「マウス処理込み」「Human68k呼び出し付き」「リンカスクリプト」など、さらに詳しくしたい場合は教えてください!
どの開発環境を使っているか(Linux/Mac/Windows、m68k-elf-gccのインストール方法)なども合わせてお伝えいただければ、もっと具体的にサポートできますよ。

X68000エミュレーター上でマウスの処理をする X-BASIC のプログラムのサンプルを作ってください

と入力すると以下のような回答が返されました。

もちろんです!X68000 上の X-BASIC でマウス入力を扱うサンプルプログラムを作成しますね。

🔶 ポイント

1. X68000 のマウスは標準でポート0(通常は接続されたマウス)からデータを読みます。
2. X-BASIC では、`MOUSE` コマンドを使用してマウスの座標やボタンの状態を取得できます。
3. 簡単な例として、画面上にマウスカーソル位置を表示し、左クリックを検出してみましょう。

✅ X-BASIC サンプルプログラム

' X68000 X-BASIC マウス処理サンプル

SCREEN 0,0  ' テキストスクリーン
CLS

' マウス初期化
MOUSE ON

PRINT "マウス入力テスト"
PRINT "ESCキーで終了します"

DO
    ' マウス座標取得
    mx = MOUSE(0)
    my = MOUSE(1)
    ' ボタン状態取得(左ボタンは1、右ボタンは2)
    mb = MOUSE(2)
    
    ' 画面表示更新
    LOCATE 0, 4
    PRINT "X="; mx; "  Y="; my; "  Button="; mb; "    "
    
    ' 左ボタンクリック検出
    IF (mb AND 1) <> 0 THEN
        LOCATE 0, 6
        PRINT "左ボタンが押されました!     "
    ELSE
        LOCATE 0, 6
        PRINT "                              "
    END IF
    
    ' ESCキーで終了
    key = INKEY$
    IF key = CHR$(27) THEN EXIT DO
    
    ' CPUを休ませる
    WAIT 1
LOOP

' 終了処理
MOUSE OFF
CLS
PRINT "終了しました。"

🔶 説明

✅ `MOUSE(0)` と `MOUSE(1)` はそれぞれマウスのX座標、Y座標を取得します。
✅ `MOUSE(2)` はボタンの状態をビットフラグで返します(左ボタン1、右ボタン2、両方なら3)。
✅ `WAIT 1` で無限ループ中のCPU負荷を下げています。
✅ `ESC` キーで終了します。

もし追加機能(マウスカーソル表示、右ボタン対応、クリック位置でアクションなど)が欲しければ教えてくださいね!
どんどん改良版も作れます。