z80 golf(3)

yaneurao2007-12-29


昨日の続き。(わかる人だけ読んで)


Lレジスタの初期化が惜しいので、'Hello, world!'の文字列をコードとみなしてfall throughさせる。これが成功すれば、Lレジスタの初期化が省ける。


しかし'Hello,'の直後のスペースが20hで、これがJR NZ,e。どうも、ここで永久ループとなるようだ。仕方ないので、文字列にオフセットを加える。こういう場合の典型的なオフセットは、+1 , -1でこれなら INC A / DEC A で処理できる。


しかし、-1のほうは、'w'(77h)が76hになり、これがhalt。+1のほうは、' '(20h)が21h(LD HL,nn)になり、これがHLを破壊してしまう。Z80ではHLを破壊されるとアドレッシングが非常に不自由になる。


そこで、その他のオフセットで、なんとかならないか調べる。


ついでに文字列の最後に haltを仕込み、読み込んだ文字列を順番に LD (HL),Hのようにしてクリアしていくことで終了判定を省略したい。そのためには、'Hello, world!'の'!'にオフセットを与えたものが2バイト命令の1バイト目として認識される必要がある。


もうこの時点で相当条件は絞られている。でも手作業で調べるのは大変なのでニーモニック表(http://members.aol.com/njprog/z80_004.html)をExcelに貼り付け、Excelのセルに =INDEX(命令表!$A$1:$A$256,A1+1,0) などとして、オフセットを加えたニーモニックがすかさず表示されるようにする。


ついでにfall throughで8000HをCALLするためにPUSH DEなどで戻り先であるゼロをstackに積みたいが、そんな都合よく空きレジスタがないので、PUSH HLとHLを積んでしまう。(HLは'Hello, world!'の文字列のどこかを指している)


ここまでくればあとは簡単だ。20バイトの'Hello, world!'が完成である。
これで、私もようやくトップ集団の仲間入りを果たせた。たかが、'Hello, world!'、されど'Hello, world!'である。