WonderSwanのソフトをどう自作するか

こちらの続きです。

nicotakuya.hatenablog.com

WonderSwan用ソフトを自作する方法を検討します。希望する条件は以下の通りです。

・開発環境がフリーであること。

・対応OSがWindows10であること。

WonderWitchを使わないこと。

f:id:nicotakuya:20210522120707j:plain

WonderWitchは使いません

、、、さすがに都合良すぎかな、と思って検索したら、すぐに見つかりました。

 Sebastian Mihaiさんという方が、WonderSwan Color用のプログラム「Swan Driving」を自作されていました。車をボタンで操作するソフトです。

 

sebastianmihai.com

公開しているROMイメージをダウンロードして、エミュレータで実行するとソフトが動きます。ソースコードも公開しています。素晴らしいです。

これを参考にさせて頂こうと思います。

「Dev Kit」のリンク先から開発ツールもダウンロードすることができますが、今回はbatファイルやexeファイルは使わず、ソースファイルと画像データだけを使わせて頂きます。

 

続いて、開発環境を入手します。

アセンブラは「NASM(Netwide Assembler)」を使います。x86系のアセンブラです。

f:id:nicotakuya:20210524111503j:plain

NASMをWindows10で動かした場合

NASMはDOSプログラムなのでWindows10では動きません。そこで、エミュレータで動かすために16bit版を入手します。自分は以下のサイトから2005年公開のVersion 0.98.39をダウンロードしました。 ファイルは「NASM.EXE」だけ使います。もう、サポートが終了しているので、行儀の良くない使い方です。

sourceforge.net

 

「Swan Driving」をビルドします。

適当なフォルダを作って、ソースファイルを置きます。  

f:id:nicotakuya:20210522200813p:plain

ファイルの一覧
  • 「swandriving.asm」はアセンブラのソースファイルです。
  • WonderSwan.inc」はOrion_さん(http://onorisoft.free.fr/)という方が作られたインクルードファイルです。アドレス等が記述されています。
  • 「gfx」フォルダの中身は画像/パレットデータのバイナリファイルです。

さらに「NASM.EXE」と「MSDOS Player(msdos.exe)」をソースファイルと同じ階層に置きます。MSDOS Playerは16bit版DOSプログラムを動かすエミュレータです。DOSBoxでも実行可能だと思います。ここではexeファイルを同じ階層に置きましたが、パスを設定して、別のフォルダに置いたほうがスマートだと思います。

それから、テキストエディタでビルド用のバッチファイル(_build.bat)を作ります。内容は以下の通りです。

echo off

set SRCFILE=swandriving.asm
set ROMFILE=swandriving.wsc

msdos nasm -f bin -o %ROMFILE% %SRCFILE%

pause

 

アセンブラを呼び出してバイナリを生成します。

「_build.bat」を実行すると、コマンドプロンプトが立ち上がって、ビルドを行います。

ビルドに成功すると、「swandriving.wsc」というROMイメージが出来上がります。

f:id:nicotakuya:20210522195858p:plain

ROM情報

参考までに生成したROM情報です。ROMイメージの最後の16バイトにROM情報が記録されています。Sumが0x0000だったり、ROMのサイズが間違っていますが、問題なく動くようです。 

 

f:id:nicotakuya:20210522024756p:plain

WonderSwanエミュレータでの実行結果

 WonderSwanエミュレータで実行すると、上のような画面が動きます。

この技術を応用すれば、WonderSwan用ソフトを自作できるようになります。

ROMイメージをフラッシュメモリに書き込めば、実機でも動くのでは?、、、と期待しています。

 

f:id:nicotakuya:20210522200249p:plain

画像データの例1

f:id:nicotakuya:20210522202339p:plain

画像データの例2

ちなみに「gfx」フォルダには画像データと、パレットデータのバイナリファイルが格納されています。16色モードを使っています。

タイル1枚あたり8x8pixel x4bit=32Byte。

パレット1つあたり2Byte x16色=32Byteです。

将来的には変換ツールを自作したいです。

 

(2021/05/23追記)

以下のページにモノクロ版「Swan Driving」が公開されていましたので、こちらも動かしてみました。初代WonderSwan用プログラムです。

sebastianmihai.com

先ほどと同じく、ソースコードをダウンロードします。

次のようにビルド用のバッチファイルを作ります。ファイル名を変更するだけです。

 

echo off

set SRCFILE=swandrivingBW.asm
set ROMFILE=swandrivingBW.ws

msdos nasm -f bin -o %ROMFILE% %SRCFILE%

pause 

 

ただし、このままビルドして実行すると、画面が灰色のまま固まってしまいます

そこで、次のようにソースを修正してみました。

 

f:id:nicotakuya:20210523001050p:plain

機種のチェックを外す

機種のチェック処理を丸ごとコメントアウトしました。

カラー機の場合、ここで無限ループに落ちてしまうので、それを防ぎます。

 

f:id:nicotakuya:20210523001122p:plain

色の設定を修正

画面モード設定の処理で「VMODE_16C_CHK」を削除しました。あてずっぽで対応したので、間違っているかもしれません。

 

f:id:nicotakuya:20210523001013p:plain

モノクロ版Swan Driving

ビルドし直すと、このように動きました。タイル1枚あたり4階調の表現ができます。

WonderSwanのプログラムを作る場合、初代専用カラー専用両対応のうちどれかを選択しないといけません。

 

f:id:nicotakuya:20210523000931p:plain

画像データの例3

f:id:nicotakuya:20210523001221p:plain

画像データの例4

モノクロの場合、タイルは8x8pixel x2bit=16Byte。パレットは4bit(実質3bit) x4色 =2Byteです。

スターフリート/Bの話

f:id:nicotakuya:20210515201529j:plain

スターフリート/B

昔、遊んだパソコンゲームの中で特に衝撃的だった作品がこちら。

テクノソフトの「スターフリート/B」です。自分はPC−6001mkII版を遊びました。

スターフリート/Bはスタートレック系のゲームです。ここでいうスタートレック」はゲームのジャンルのことです。全盛期には数多くのソフトハウスからスタートレックが発売されました。著作権の意識が低かったころの時代です。

スターフリート/Bは他のスタートレックとは違って、とにかく斬新でした。

表示は「本物の3D」。「オリオン」みたいな単一方向じゃなくて、プレイヤーがあらゆる方向に移動が可能です。しかもリアルタイムで進行します。これは実際の宇宙空間を飛び回っているかのような衝撃的なプレイ体験でした。とにかく3Dが珍しかったので、今、遊んだら全く感動しないかもしれません。

 

f:id:nicotakuya:20210516032829j:plain

マイコンソフトの広告(ベーマガ1984年1月号より)

ほぼ同時期にマイコンソフトでもスタートレックを販売していました。

題名は「リアルタイム SUPER STAR TREK」。この作品はFORESIGHTというマイコンサークルで沼田裕さんが開発されています。アスキーの「トレードトレック」もこの方です。

 

f:id:nicotakuya:20210516161438j:plain

当時の広告(ベーマガ84年10月号)

1984年当時のテクノソフトの広告。

ページの上半分を「プラズマライン」が占めていて、残ったスペースに小さく載ってます。本作は最初にMZ-80B版がリリースされて、移植を繰り返すうちに表現力がパワーアップしていったという経緯があります。この時点でもうMZ-80B版がありません。

あと、スターフリート/Bの「/B」の意味がいまだにわからないです。パッケージを見ると、/Bがないのが正しいみたいですが、個人的に違和感があるので/Bを付けて書きます。

 

f:id:nicotakuya:20210517013016j:plain

スターラスター(ナムコアンソロジー1より)

数年後、1985年にナムコが「スターラスター」を発売。

当時は「スターフリート/Bをパクった!!」と思ったのですが、実際は1979年にAtariが発売した「Star Raiders」のリメイクでした。そして、Star Raidersはスタートレックの影響を大きく受けています。元ネタがすべて同じです。

 

f:id:nicotakuya:20210515200547j:plain

Atari Vaultにも収録

f:id:nicotakuya:20210515200724j:plain

Star Raiders(Atari 2600)

Star Raidersは「Atari Vault」にも収録されています。これは1979年発売のAtari 400/800版じゃなくて、1982年発売のAtari 2600版でした。Atari 2600版は力作ですが、性能が追い付いていないです。

これを見て、スターラスターを連想するのは難しいかも。

追加コンテンツのAtari 5200版のほうがグラフィックは綺麗です。

 

f:id:nicotakuya:20210516204056p:plain

Stellar Track(Atari 2600)

f:id:nicotakuya:20210516204007p:plain

Stellar Track

この他、1980年にAtari 2600用として発売した「Stellar Track」というゲームもあります。表示はテキストのみ。まぎれもないスタートレックです。

 

f:id:nicotakuya:20210516230252p:plain

Tinyスタートレック  ver.1.0

話が前後しますが、オリジナルのスタートレックについて紹介します。検索したところでは、スタートレックは1971年から存在していたようです。コンピュータが全くパーソナルじゃなかった時代です。

さらに元ネタをたどるとウォーゲームがあって、さらにボードゲームの「海戦ゲーム(Battle ship)」に行きつくと思います。wikipedia情報だとBattle ship風のボードゲームは1930年代から商品化されていたそうです。Battle shipは軍人将棋の「ストラテゴ」の影響があるとも書かれてますが、これ以上、元をたどるとキリがありません。

上の写真はVectorで公開されている「Tinyスタートレック」。1993年公開。これは、1977年に石田晴久先生の「マイクロコンピュータの活かし方」に掲載していた「Tiny Trek」をeyesさんという方が移植したものです。自分は石田先生の翻訳した本でC言語を学びました。

 

www.atariarchives.org

1978年には「BASIC COMPUTER GAMES(Microcomputer Edition)」という本で「Super Star Trek」が掲載されています(日本語版は1979年)。現在、本の内容は合法的にアーカイブ化されていますツクモ電機の「スーパースタートレック」よりも、こっちが先です。この本によると、作者さんが1967~68年ごろに大学でスタートレックを遊んだと書かれてて、wikipedia情報と食い違う。コンピュータじゃなくてウォーゲーム版という意味?

1978年にはApple II用に「Apple II trek」が登場。プログラムがBASICなので、容易に移植が可能でした。

 

f:id:nicotakuya:20210517221805j:plain

ハドソンの広告(月刊マイコン1979年7月号より)

1979年に「月刊マイコン」に掲載されたハドソンコスモス札幌/ハドソン丸井今井店の広告。「おなじみの」と書かれているので、この時点でスタートレック知名度は相当なものだったと思います。

他にも、TK-80やプログラム電卓で動くスタートレックがあるのですが、よく知りません。

 

f:id:nicotakuya:20210516230153p:plain

敵戦艦に攻撃が命中!!(この熱さが伝わるでしょうか?)

MSDOS Player(msdos.exe)を使って「Tinyスタートレック」を遊んでみました。コマンドプロンプトを起動して、「msdos strek.exe」を実行します。

ゲームの進め方ですが、大ざっぱにいうと

  • 敵を探す。
  • 敵に近づく。
  • 敵を撃つ。

、、、の繰り返しです。「それで面白いの?」と思われるかもしれませんが、プレイヤーが得られる情報が限られているので、頭を使って敵の位置を予想する必要があり、それが面白いところです。残り時間が減ったり、センサーが故障したり、残弾が減ったり、トラブルが発生して緊張感を高めてくれます。狙いどおりに敵を見つけて、攻撃が当たることの気持ち良さ。

情報が限られてるというコンセプトはテキスト画面とマッチしています。

 

遊んでみて思ったのですが、「情報が限られている」「敵の位置を予想する」というのが、スタートレックの特に重要な要素だと感じます。

そう考えると、スターラスタースタートレック要素が抜け落ちてしまってます。敵の位置がゲーム開始時からバレバレです。その代わり、ゲームがスピーディーに進むので、一長一短なのかなという気がします。

一方、スターフリート/Bはスタートレック要素がかなり残っています。センサーで探索しないと敵の位置がわかりません。ただし、メッセージ表示が遅いし、座標入力はキーボードだし、進行が遅いのが難点です。今、プレイすると、イライラするかもしれません。

スターフリート/Bみたいなゲームを今、快適な状態で遊んでみたいです。

ぷよぷよの連鎖プログラム(pygame zero)

ぷよぷよの連鎖を再現するプログラムです。pygame zeroで動きます。
2020年にセガが公式でぷよぷよのプログラミング学習用のキットを公開していますが、このプログラムはそれを使っていません。

f:id:nicotakuya:20210514135848j:plain

ぷよぷよの連鎖

 

実行画面です。消えていくプロセスを一気に表示します。
ぷよの接続数は再帰処理で検出しています。プログラムの特徴はそれだけです。

# 落ち物の連鎖
import pgzrun # Pygame Zeroをインポート
WIDTH = 800   # 画面の幅(ピクセル)
HEIGHT = 600  # 画面の高さ(ピクセル)
CELLW = 6     # 舞台の幅(セル数)
CELLH = 8     # 舞台の高さ(セル数)
CELLSIZE = 20 # 1セルのピクセル数
DISPW = int(WIDTH/CELLSIZE)
DISPH = int(HEIGHT/CELLSIZE)

cell = [[0 for j in range(DISPW)] for i in range(DISPH)]

initialdata = [
    [0,0,0,0,0,0],
    [0,2,0,0,0,0],
    [0,2,3,0,0,0],
    [0,2,3,4,0,0],
    [0,1,3,4,0,0],
    [0,1,2,3,3,0],
    [0,1,2,4,3,4],
    [2,1,3,3,4,4]
]

# カラーテーブル
colortable = ['black','blue','red','purple','green']

# セルの書き込み(X座標,Y座標,カラー番号)
def setcell(x,y,data):
    cell[y][x] = data

# セルの読み込み(X座標,Y座標)。戻り値=カラー番号
def getcell(x,y):
    ret = 0
    if x>=0 and x<CELLW and y>=0 and y<CELLH: ret = cell[y][x]
    return ret

# セルを塗りつぶす(X座標,Y座標,変更前の色,変更後の色,連結セル数)
def fill(x,y,before,after,cnt):
    if (before<=0) or (after<0):return 0
    if getcell(x,y)==before:
        setcell(x,y,after)  # 色を変更する
        cnt = cnt+1         # 連結セル数を加算する

    if getcell(x,y-1)==before: cnt = fill(x,y-1,before,after,cnt)
    if getcell(x,y+1)==before: cnt = fill(x,y+1,before,after,cnt)
    if getcell(x-1,y)==before: cnt = fill(x-1,y,before,after,cnt)
    if getcell(x+1,y)==before: cnt = fill(x+1,y,before,after,cnt)
    return cnt  # 戻り値=連結セル数

# セルの落下
def movecell():
    for i in range(CELLH-1):
        for y in range(CELLH-1,0,-1):
            for x in range(CELLW):
                num = getcell(x,y-1)
                if (getcell(x,y)==0) and (num!=0):
                    setcell(x,y-1,0)
                    setcell(x,y  ,num)

# セルの消去。戻り値=消去した回数
def checkcell():
    clearcnt = 0
    for y in range(CELLH):
        for x in range(CELLW):
            num = getcell(x,y)
            if num>=10:continue  # 調査済みのセルはスキップする
            cnt = fill(x,y,num,num+10,0)  # 連結セル数を算出
            if cnt>=4:             # 4個以上連結した場合
                cnt = fill(x,y,num+10,0,0)  # セル消去
                clearcnt = clearcnt+1

    for y in range(CELLH):
        for x in range(CELLW):
            num = getcell(x,y)
            if num<10:continue  # 復元済みのセルはスキップする
            cnt = fill(x,y,num,num-10,0)    # セルの復元

    return clearcnt  # 消去した回数を返す

#セルの状態をバックアップ(X座標,Y座標)
def backup(ofsx,ofsy):
    for y in range(CELLH):
        for x in range(CELLW):
            setcell(ofsx+x,ofsy+y,getcell(x,y))

# 画面の描画
def draw():
    screen.fill('BLACK')
    for y in range(DISPH):
        for x in range(DISPW):
            color = colortable[cell[y][x]]
            r = int(CELLSIZE / 2)
            pos =(x*CELLSIZE+r,y*CELLSIZE+r)
            screen.draw.filled_circle(pos, r, color)

    for i in range(4):
         screen.draw.text(str(i+1)+' COMBO',
              left=CELLSIZE*8*i,top=CELLSIZE*27,fontsize=30)

# セルの初期化と連鎖処理
for y in range(CELLH):
    for x in range(CELLW):
        setcell(x,y,initialdata[y][x])

for combo in range(100):  # 連鎖のループ
    movecell()               # セルの落下
    backup(combo*8,8)        # 消去前のセルをバックアップ
    if checkcell()==0:break  # セルの消去。不可能な場合は終了
    backup(combo*8,18)       # 消去後のセルをバックアップ

pgzrun.go()

ワンダースワン用カートリッジの自作(検討中)

ワンダースワンカートリッジの自作を検討してみました。まだ完成していません。

ワンダーウィッチ(開発キット)は発売からもう20年以上経過していますが、さすがにもうサポートは望めません。そこで、自分でカートリッジを作ることを思い立ちました。20年経っているということは合法的に作れるはず

ただし、ワンダーウィッチと同じ仕様だと、あまりにも技術的なハードルが高い。ここでは、フラッシュメモリが搭載しているだけの、最低限のスペックにしたいと思います。あと、違法コピーに使われると困るので、オリジナルの仕様が望ましいです。

 

f:id:nicotakuya:20210512010423j:plain

寸法を測る

いつもどおり、カートリッジとガワの実物を元に寸法を割り出します。

目コピーなので誤差があると思います。

 

f:id:nicotakuya:20210512010118j:plain

ピン間隔

最も重要な寸法は、カードエッジのピン間隔です。

ピンの端から端まで58.8mmでした。

全48ピンなので、これを47で割ると、1.2510....。1.25mmピッチということにします。

 

f:id:nicotakuya:20210512010213p:plain

フラッシュメモリを選定

フラッシュメモリを選びます。

採用の条件としては、手軽に買えて、3.3Vで動作して、ハンダ付けしやすいものです。

Digi-Keyで検索しました。DIPかPLCCだと、容量が1M bitしかありません。別の会社だとあったりするのでしょうか。

 

f:id:nicotakuya:20210512010338j:plain

CADで設計中

CADでいきなり描いてみました。

ガワの調達は無理っぽいので、直接、基板を差し込む形状にします。

16bitバスってことは、8bitを2個載せればいいわけですよね。1Mを2個載せます。PLCC ソケットを付けると基板の反対側からトゲトゲが出てしまうので、本体からはみ出るようにします。

f:id:nicotakuya:20210512091237j:plain

完成イメージ

これはカッコ悪い、、、。が、組み立てやすさを考えると、これしかないように思えます。

あとは配線するだけです。今回はここまでです。

 

(2021/5/14追記)

f:id:nicotakuya:20210514112043p:plain

配線中

アドレスバスと、データバスを一通りつないでみました、、、が、うまく動く気がしない。

ワンダースワン側の「SEL」信号が謎です。カートリッジのROMにアクセスする時にSELがLowになると仮定して、CEに直結してみました。A17~A19になにも接続していませんが、本来だったらここでアドレスのデコードをすべきだと思います。不明点が多いので、実際に作ってみて検証したいです。

 

(2021/5/15追記)

f:id:nicotakuya:20210515135102p:plain

さらに修正

GNDをつなぎ間違っていたので、修正。あと、配線をミスした時にそなえてピンヘッダを追加。

基板の厚さは1.6mmくらいを想定してます。厚さ1mmで作って、カードエッジ部分に0.5mmくらいのプラ板を足すという方式だったら、もっと基板を小型化できるような気がします。どういう路線でいくべきか悩むところです。

 

(2021/05/16追記)

f:id:nicotakuya:20210516041519p:plain

サイズを縮小

ワンダースワンのカートリッジと同サイズに変更しました。この形状じゃないと落ち着かなかったので、、、。

部品のトゲトゲが本体に当たってしまいますが、基板の厚さを1mmにすることで調整したいと思います。

 

(2021/05/18追記)

f:id:nicotakuya:20210518122440p:plain

コンデンサを足しました

ちょっとだけ修正。

これで、設計は完了のつもりです。サイズは66x42mm。

P板.comで見積もったら、20枚で2万8402円でした。ちょっと金額が大きいので、なにかのついでに作ったらいいかと思います。

 

(2021/5/21追記)

f:id:nicotakuya:20210521092416j:plain

紙で確認

紙に印刷して配線の確認。理屈はわかりませんが、こうやるとミスが見つかりやすいです。

D11 とD12 が逆につながってることに気がついたので、これから直します。

 

続き

nicotakuya.hatenablog.com

WonderWitch用の通信ケーブルの自作

WonderWitch用の純正の通信ケーブル(スワンケーブル)が使えなくなってしまったため、ケーブルを自作してみました。

このケーブルを使うと、WonderWitchで作ったプログラムをPCからワンダースワンに転送することができます。

f:id:nicotakuya:20210509102812j:plain

自作したケーブル

 

f:id:nicotakuya:20210510011450j:plain

純正の通信ケーブル

純正の通信ケーブルは接続に「シリアルポート(RS-232)」を採用していました。RS-232は発売当時(2000年)の時点で「ちょっとレガシー」だったと思うのですが、2021年だともう「完全にレガシー」です。

f:id:nicotakuya:20210509103013j:plain

USB - シリアルポート変換アダプタ

つい最近までは、こうしたUSBのシリアルポート変換アダプタを使っていたのですが、残念ながら、この製品はもうWindows10には対応していません。レガシーデバイス向けの周辺機器すらレガシー化しています。

こうして通信ケーブルを作る必要が出てきたわけです。

 

f:id:nicotakuya:20210510002518p:plain

回路図

回路図です。動作無保証です。

ワンダースワンは3.3Vで動作します。そこで、USBの5Vをダイオードで3Vくらいに落として、ロジックICを動かしています。

USBシリアルの変換モジュールは秋月のFT232RQを使いました。価格は980円。FT232RQは信号の電圧を3V/5Vの二種類から選択可能です。この回路では、5Vで送信してしまった場合を想定して、(R1)抵抗を付けてます。3.3Vで送信した場合は、抵抗は不要です。

ワンダースワンの通信仕様はUARTとほぼ同じなのですが、信号の論理が逆になっています。受信&送信ともに無通信状態はLowです(UARTは逆にHigh)。そのため、論理を反転させるために、NANDのロジックIC「74HC00」を使います。秋月で30円で売ってます。

 

f:id:nicotakuya:20210509103206j:plain

ワンダースワン用の通信コネクタ

ワンダースワン用の通信コネクタです。

自分の場合は対戦用の通信ケーブルをニッパで分解しました。今だと、入手が難しいかもしれません。

 

f:id:nicotakuya:20210509103256j:plain

ピンアサイ

コネクタのピンアサインです。

カードエッジになっていて、裏表で4ピン+4ピン=8ピンあります。基板の裏側を使います。

 

f:id:nicotakuya:20210509103443j:plain

通信モード

f:id:nicotakuya:20210510003216p:plain

通信ソフト「TransMagic」

動作中はこんな感じです。

WonderWitch側は「通信」モードを選択します。 

通信ケーブルをPCのUSBポートに接続すると、COMポートとして認識されます。デバイスマネージャでCOMポート番号を確認しておきます。

TransMagicを起動して、「シリアルポート設定」を行います。デフォルトのボーレートは38400bpsです。あとはファイルを転送するだけです。

純正の通信ケーブルはICの電源をワンダースワンから供給していたので、通信を行うたびにバッテリ残量が激減するという欠点がありました。

一方、自作した通信ケーブルはPCから給電するので、安心して通信することができます。

 

f:id:nicotakuya:20210510133254j:plain

WWGP2001版ジャッジメントシルバーソード

2001年のコンテストでグランプリを受賞したバージョンの「ジャッジメントシルバーソード」。単体のカートリッジとして商品化されたのが2004年です。本作はワンダースワンの最高傑作だと思いますが、ファミ通2004年2月20日号のクロスレビューは7777。

 

f:id:nicotakuya:20210510130937j:plain

WWGP2002版のDicingKnight

2002年のコンテストでグランプリを受賞したバージョンの「DicingKnight」。今でもコンテストページから入手可能です。配布しているファイルだけだと、実行して即、異常終了してしまいます。「sound102.il(サウンドドライバ)」「bmpsaver.il(キャプチャライブラリ)」もカートリッジに転送してから実行しましょう。

 

続き

nicotakuya.hatenablog.com

 

 

ワンダースワン関連

nicotakuya.hatenablog.com