2007年になりましたね。月に1回更新するか怪しいこのブログを購読してくださってる方々、ありがとうございます(笑
無事卒論も提出し、気楽な学生気分を満喫しています。ちなみに、卒論は完璧にコンピュータは関係ないもので、まぁラットと戯れていました。生物、こと脳にかかわる話も面白いですよ。まったくもって大した研究ではないのですが、教授が今年ヨーロッパの学会で発表してくださるらしいです。とりあえず書けて何より。
さて、プログラミング関連ですが、卒論もようやく終わり4月までは暇な学生生活、まとまった時間がとれるようになったので、ちょろちょろ書き始めています。
書いているのは・・・なんと今更NESエミュレータ。
一から自分で解析してエミュレータを書くのは達人ワザですが、十分なハードウェアの情報がある場合、実はそんなに難しくなかったりします。
というわけで書いているんですが、ここで普通にC言語やアセンブラで書こうというような楽?はしてません!NESエミュレータをPythonで書いてみる、これがチャレンジング。ぶっちゃけPythonで速度がシビアに求められるものを書いたことがないので、チャレンジです。
書く上で、とりあえず
- ctypesは使わない(Cの流儀をそのままもっていってもおもしろくない)
- 当然Cで拡張モジュールは書かない
というポリシーで書き進めています。
しかしやっぱりキツイ。絶対Cの方が楽な気がするのは気のせいだろうか・・・。現在はだいたいCPU(6502)のコアが書き終わったので、メモリ周りを書き進めてます。とりあえず.NESファイルから読み込んでメモリに読み込み、PCをセットするあたりまで書きました。
まず、NESのヘッダ読み込むのもめんどくさい。Cならfreadで構造体にマップしておわり、なのにPythonだとそうは行かない。そしてなんといってもポインタがない。これ。メモリのミラーリングとかめんどくさいだろうな・・・(笑
そうこう書いてるうちに、Pythonでのバイナリの扱いが上手くなってきました(きたような気がします)。 今のところ以下のような関数が活躍しています。エディアンは今のところ決めうちです。
1from struct import *
2from array import array
3
4def unpack_byte(b):
5 return unpack("<B", b)[0]
6
7def zero_filled(n):
8 n /= 2
9 return pack('h'*n, *([0]*n))
10
11def byte_array(v):
12 return array('c', v)
13
14class byte_ref(object):
15 def __init__(self, p):
16 self._value = p
17 def get_value(self):
18 return self._value
19 def set_value(self, v):
20 self.value[0:] = byte_array(v)
21 value = property(get_value, set_value)
まず、PythonでRAMをエミュレートしようと思うと、可変なunsigned charな配列が当然必要です。
Pythonで data = open("name", "rb").read()
とした場合、きちんとバイナリデータがdataに入って、 unpack_byte(data[0:1])
などとするとちゃんとデータを取り出せます。
しかし、この場合、Pythonの内部では*不変な型である*文字列型として扱われているので data[w_addr & 0x7ff] = 0x12
みたいなことは出来ません。つまりROMにはなりますが、RAMになれません。じゃあどうやってunsigned charの配列を表現するか、ということで array
モジュールの登場なわけです。 data = byte_array(open("name", "rb").read())
という感じで使っています。生成方法がことなるだけで data[0]
みたいなインデックスによるアクセスも出来るし、部分書き換えも可能です。
byte_refは・・・別になくてもいいかもしれませんが、byte配列に対する参照を表現するオブジェクトです。といっても注意して使わないと意味がないクラスで気持ちの問題かもしれません。
ここをctypesでポインタを使えば考えなくてもよかったんですが、あえてPythonなんだ、ということで(笑
近況はこんな感じです。
ついに就職が近づいてきました。仕事はプログラマではないので、プログラムを書く時間はあんまり取れないかもしれません。でもまぁ、日曜プログラマとして細々やっていけたらなあ、と思っています。