ゲームアプリに限らず、コンピュータのプログラムが実際にやっていることは、 周辺デバイスのデータを読み込んで、作業用メモリに移し替えて、 それを何やら処理して、周辺デバイスに書き出す、ということの繰り返しです。
本項目は、その「作業メモリ」について説明します。
X68000の搭載メモリは、初代が1Mバイト、EXPERTからは2Mバイトで、 オプションを購入することで最大12Mバイトまで拡張できます。
OSであるHuman68kが起動するには、このメモリ上にHUMAN.SYSが読み込まれ、 CONFIG.SYSで設定されたデバイスドライバも読み込まれます。
自作のプログラムも、このあとCOMMAND.Xを挟むか、CONFIG.SYSのPROGRAM設定から 実行するときに、同様にメインメモリにロードされ、OSから処理を引き継ぎます。
このとき、自作プログラムがロードされる先頭アドレスが、 デバイスドライバの組込状況によって変わることは容易に想像がつくと思いますが、 どこまでのメモリを使っていいかについては、搭載メモリの最後までとは限らないので注意してください。 具体的には、RAMディスクを組み込んだ場合、後方のメモリから占有されるため、それ以前の領域になります。
自作プログラムが使えるRAM領域の使用限界アドレスは、プログラム開始時にa0レジスタに 与えられたメモリ管理ポインタの8バイト目で確認する方法が正解です。
さて、ここまで何を説明したかというと、自作プログラムはRAM領域のどこかにロードされて実行可能になり、 プログラムが使える作業用メモリ(ワークメモリ)も同じ領域内で工面するということです。
ここからは、作業用メモリ(変数)をプログラム内のどこに置くのが適切かについて検討します。
上記の説明のとおり、プログラム自体がRAM上に配置されるので、TEXTセクションやDATAセクションも、 書き換え可能です。そのため、下記のような書き方ができます。
.text .even reset: move #100,workvalue * 作業変数を100にする rts update: move workvalue,d0 * 作業変数が0になるまで1ずつ減算する beq @f subq #1,d0 move d0,workvalue @@: rts workvalue: .dc.w 0 * 作業変数を初期値0で確保する
ですが、この書き方では作業変数が絶対アドレスになります。 つまり、このプログラムはworkvalueがロングワードで埋め込まれ、再配置処理の対象になります。
それを承知の上で使うならそれでも良いのですが、作業変数をBSSに確保すると、 次のような書き方ができます。
.offset 0 workvalue: .ds.w 1 * 作業変数領を確保する WORK_SIZE: .text .even start: lea WORK_AREA(pc),a6 * BSSの先頭アドレスをa6に参照する clr workvalue(a6) * 作業変数を0で初期化しておく rts reset: move #100,workvalue(a6) * 作業変数を100にする rts update: move workvalue(a6),d0 * 作業変数が0になるまで1ずつ減算する beq @f subq #1,d0 move d0,workvalue(a6) @@: rts .bss .even WORK_AREA: .ds.b WORK_SIZE
複雑な書き方になっていますが、注意して読んで欲しいのはworkvalueのアクセス方法とa6レジスタの使い方です。
start処理で、a6レジスタにBSS(ブロックストレージセクション)の先頭アドレスを参照し、以後、実行中は保持します。
workvalueは、先頭の.offsetからWORK_SIZEの間で定義されており(今回は0)、 BSS先頭(a6レジスタ値)からの距離を表す定数です。
この書き方をすると、workvalueをアクセスする箇所はロングワード(32bit)ではなく、ワードサイズ(16bit)に短縮され、再配置情報が不要です。
実際にゲームを作る場面では、作業変数は1個や2個ではありませんから、全体での短縮効果は数に比例して大きくなります。
ついでに、コンバータCV.Xでフルリロケータブルな実行ファイル(.R形式)に変換できるようになります。
まあ、後半の話は余談なので、アセンブラに十分慣れてから読み直してください。
Copyright©2026 カピバラ父さん