2014年12月13日土曜日

ARMの上で動くリンゴ印のOSで究極のLチカを楽しむ

ARMは仕事で初めてゲームを作ったコンシューマ機、ゲームボーイアドバンスのCPUという事で、とても思い入れのあるCPUです。ゆんゆんに「ちょっと手伝ってー」と言われて立ち寄ったのが今や泣く子も黙る神移植のM2さん。タイトルはデ・ジ・キャラット。楽曲は憧れの並木学さん。そしてサウンドプログラムを手がけていたのがX68k界でブイブイ言わせてた齊藤彰良さん。当時はお二方ともM2移籍前。僕もワクワクしながら仕事をしていました(最近は大きな仕事に慣れすぎてワクワク感が麻痺してしまってるかも……)。
そんな思い入れのあるARMですが、今やモバイルを中心とした組み込み世界の覇者。AndroidやiPhone向けの高性能プロセッサであると同時に、ホビー向けには個人でも100円程度で手に入るモデルが沢山あります。そこで、せっかくだから久々に何か遊べないかなー……という事で考えたのが……

120円ARMの上でリンゴ印のアイツを動かす!


そう、あれです、あれ。Apple II。
秋月で手に入るLPC1114の性能を見ていてピンと来ませんか?
  • ARM Cortex-M0
  • 50MHz(最大)
  • Flash: 32KB
  • RAM: 4KB
このギリギリ感!ちなみに以前からマイコンだけで古のマシンを再現する企画を続けており
  • CP/Mega88 ... CP/M Z-80 on ATMEGA88 (20MHz, Flash: 8KB, RAM: 1KB) + 外付けSRAM 64K
  • MegaZ-80K ... MZ-80K on ATMEGA644 (20MHz, Flash: 64KB, RAM: 4KB) + ATMEGA328 (20MHz, Flash: 32KB, RAM: 2KB) + TINY2313(20MHz, Flash: 2K, RAM: 128B)
に続く第三弾です。ソースはgithubに置いてありますが全てアセンブリで書かれています。毎回何かしら無駄な挑戦をしているわけですが、今回の見どころは
  1. I/O 4KB、ROM 12KB、RAM 48KBをFlash 32KB、RAM 4KBだけでごまかす
  2. ビデオ出力とキーボード入力をUARTのTX/RXに変換する
  3. 空いてるI/OにGPIOを割り当てて、Apple BASICからLチカ
の3点。

1は単純なローテクで実現。ROMはFlash側に埋め込み、VRAMについては一切記憶しない事でメモリ節約(次節でも説明)。ゼロページやスタック、Apple BASICが本気で使う空間にはRAMをまじめに割り当て、それ以外の領域に関しては全部同じ1-Byteを共有するようにしてあります。主記憶のないキャッシュみたいなもんで、書いて読んで比較……という単純なメモリチェックに対しては正しく動くけど、本当にワークとして触りだしたら動きません。まぁ、初期化コードを騙して、小さいプログラムを動かすには十分。

2は気合。UART入力をキーボードに変えるのは比較的簡単ですが、出力をUARTに変換するのはちょっと大変です。VRAMへの書き込みを見はりつつ、前に書いたアドレスからの差分でカーソル移動を行います。書き込み内容はTXに送るだけでVRAMの実体は実装しません。読まれたら固定値0xFFを返すだけ。スクロール時の画面書き換えは書き込みパタンから自動判別します。読んで1段上のラインに書き込んで……という処理を繰り返すのでアドレスパタンからも判別できるし、本来使われることのない"読み出し値0xFF由来の値"の書き込みを検知する事でも判断できます。スクロール処理中は再描画の書き込みを無視し、スクロール終了を検出したらしれっと改行を送って通常モードに戻ります。

3は特に難しいことはなく。拡張スロット用のI/O空間が開いているので、そこへのアクセスをGPIOにつなげてみました。Apple BASICからはPEEK/POKEで気軽に全メモリ空間へアクセスできるので、これだけでBASICからGPIO制御が可能になります。

という事で簡単なデモ。YouTubeの編集機能使って音とか説明つけてみた。携帯片手に左手でぽちぽち入力した映像なんですが、フラフラしてた画面も手ぶれ補正であっさり安定。



という事で、次はこのプロジェクトを始めた真の目的、佐藤一憲さんにもらったWIZnetを繋げて遊ぶ、というステップに進もうかと。宿題間に合いそうで良かった、良かった。

0 件のコメント: