テスト用プログラムの作成 (LIFEゲーム)
サンプルプログラムとしてLIFEゲームを取り上げます。
- 生物の生死をシミュレーションするゲーム。
- 3×3の格子において、中心マスの生物の変化をまわりの8マスの状況によ
り定義する。
- 誕生:中心に生物がいないとき、まわりに3つの生物が居れば、中心の生
物は生き残る。
- 維持:中心に生物がいるとき、まわりに2〜3つの生物が居れば、中心の生
物は生き残る。
- 死亡:その他の場合、中心の生物は居なくなる。
- プログラムは以下のように処理すれば良い。
- 初期エリアを用意し、生物を配置しておく。
- 初期エリアの情報を画面上に表示する。
- 必要に応じて時間待ちをする。(プロセッサの動作が早いので)
- LIFEのアルゴリズムにしたがい、各マス毎の生物の情報を求め、ワークエ
リアの方へ保存していく。
- すべてのマスについてアルゴリズムを適用すると、ワークエリアに次世代
の生物情報が完成する。
- ワークエリアの内容を初期エリアにコピーする。
- 2. 以降を繰り返す
キャラクタタイプの表示装置の場合、表示したい箇所のVRAMアドレスのメモリに
キャラクタコードを書込み際すれば良い。
VRAMのベースアドレスを VRAM、書き込みたい箇所の座標をX、Yとするとき、
VRAM + ( Y * 80 ) + X のアドレスに書き込めば良い。
プログラムは、以下のようにアセンブルし、プログラムメモリ内に初期プログラ
ムとして配置できるようにしておく。
kiteasm -l life.asm
lst2ram -s -f -2 life.lst
メモリの初期化は以下のように $readmemh を利用する。
initial
begin
$readmemh( "life.ram", MEM );
end
以下に、LIFE プログラムを示す。
;;
;; Life Game 48x16 for LCD Monitor on ATLYS Board
;;
.word MAIN ; Start Vector
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
MAIN: ld16 #STACK ; sp = 0x800
mv sp, acc
;;
;; Main Loop
;;
NEXT1:
;;
;; Display DATA1 area
;;
call disp ; copy DATA1 to Display
call wait ; wait
;;
;; Clear DATA2 area
;;
ld16 #768
st X
ld DAT2
mv ixr, acc
LOOP3: ld #0
st ixr, 0
inc ixr, ixr
ld X
dec acc, acc
st X
jpz NEXT3
jp LOOP3
;;
;; for( x=0 ; x<48 ; x++ )
;;
NEXT3: ld #0
FOR1: st X
sub #48
jpz FOREND1
;;
;; for( y=0 ; y<16 ; y++ )
;;
ld #0
FOR2: st Y
sub #16
jpz FOREND2
BODY: ld #0 ; NoOf = 0
st NoOf
ld X ; if( what1(x-1,y-1) ) NoOf++;
dec acc, acc
push
ld Y
dec acc, acc
push
call what1
jpz SKIP1
ld NoOf
inc acc, acc
st NoOf
SKIP1: pop
ld Y ; if( what1(x-1 ,y ) ) NoOf++;
push
call what1
jpz SKIP2
ld NoOf
inc acc, acc
st NoOf
SKIP2: pop
ld Y ; if( what1(x-1,y+1) ) NoOf++;
inc acc, acc
push
call what1
jpz SKIP3
ld NoOf
inc acc, acc
st NoOf
SKIP3: pop
pop
ld X ; if( what1(x ,y-1) ) NoOf++;
push
ld Y
dec acc, acc
push
call what1
jpz SKIP4
ld NoOf
inc acc, acc
st NoOf
SKIP4: pop
ld Y ; if( what1(x ,y+1) ) NoOf++;
inc acc, acc
push
call what1
jpz SKIP5
ld NoOf
inc acc, acc
st NoOf
SKIP5: pop
pop
ld X ; if( what1(x+1,y-1) ) NoOf++;
inc acc, acc
push
ld Y
dec acc, acc
push
call what1
jpz SKIP6
ld NoOf
inc acc, acc
st NoOf
SKIP6: pop
ld Y ; if( what1(x+1,y ) ) NoOf++;
push
call what1
jpz SKIP7
ld NoOf
inc acc, acc
st NoOf
SKIP7: pop
ld Y ; if( what1(x+1,y+1) ) NoOf++;
inc acc, acc
push
call what1
jpz SKIP8
ld NoOf
inc acc, acc
st NoOf
SKIP8: pop
pop
ld X ; if( what1(x,y) ) {
push
ld Y
push
call what1
jpz CENTER0
CENTER1:ld NoOf ; if( NoOf == 2 || NoOf == 3 )
sub #2 ; set1(x,y);
jpz SET ; else
ld NoOf ; set0(x,y);
sub #3
jpz SET
jp DEL
CENTER0:ld NoOf ; } else {
sub #3 ; if( NoOf == 3 )
jpz SET ; set1(x,y);
DEL: call SET0
jp SKIP10
SET: call SET1 ; }
SKIP10: pop
pop
ld Y ; y++;
inc acc, acc
jp FOR2 ; };// forend y
FOREND2:ld X ; x++;
inc acc, acc
jp FOR1 ; };// forend x
FOREND1:ld16 #768 ; Copy DATA2 -> DATA1 area
st X
ld DAT1
st PTR1
ld DAT2
st PTR2
LOOP4: ld PTR2
mv ixr, acc
ld ixr, 0
push
ld PTR1
mv ixr, acc
pop
st ixr,0
ld PTR1
inc acc, acc
st PTR1
ld PTR2
inc acc, acc
st PTR2
ld X
dec acc, acc
st X
jpz NEXT1 ; Goto Main Loop
jp LOOP4
;;
;; What1(x,y) return 0 and set Z flag
;; if thare is no object in DATA1[x,y]
;;
what1: mv ixr, sp
call check ; area check
jpz return ; if out of area
call adgen ; acc = Y*48+X
st PTR1
ld16 #PTR1
mv ixr, acc
ld DAT1
add ixr, 0 ; acc = DATA1+Y*48+X
mv ixr, acc
ld ixr, 0 ; acc = *(DATA1+Y*48+X)
or #0
return: ret
;;
;; check boundary
;;
check: ld ixr, 2 ; load X
sub #-1 ; if out of left side then return Z
jpz return
ld ixr, 2
sub #48 ; if out of right side then return Z
jpz return
ld ixr, 1 ; load Y
sub #-1 ; if out of upper side then return Z
jpz return
ld ixr, 1
sub #16 ; if out of lower side then return Z
ret ; return NZ if within area
;;
;; acc = 48*Y+X
;;
adgen: ld ixr, 1 ; acc = Y
add ixr, 1 ; acc = 2*Y
add ixr, 1 ; acc = 3*Y
asl ; acc = 6*Y
asl ; acc = 12*Y
asl ; acc = 24*Y
asl ; acc = 48*Y
add ixr, 2 ; acc = 48*Y + X
ret
;;
;; SET1(x,y) sets "1" into DATA2[x,y]
;;
SET1: mv ixr, sp
call adgen ; acc = Y*48+X
st PTR1
ld16 #PTR1
mv ixr, acc
ld DAT2
add ixr, 0 ; acc = DATA2+Y*48+X
mv ixr, acc
ld #1
st ixr, 0 ; *(DAT2+Y*48+X) = 1
ret
;;
;; SET0(x,y) sets "0" into DATA2[x,y]
;;
SET0: mv ixr, sp
call adgen ; acc = Y*80+X
st PTR1
ld16 #PTR1
mv ixr, acc
ld DAT2
add ixr, 0 ; acc = DATA2+Y*80+X
mv ixr, acc
ld #0
st ixr, 0 ; *(DAT2+Y*80+X) = 0
ret
;;
;; Display : Copy DATA -> VRAM area
;;
disp: ld #16
st Y
ld16 #VRAM940
st PTR2 ; ptr2 = dest. pointer
ld DAT1
st PTR1 ; ptr1 = DATA1 pointer
disp1: ld #48
st X ; X = 48
disp5: ld PTR1
mv ixr, acc
ld ixr, 0
push
ld PTR2
mv ixr, acc
pop
or #0
jpz disp2
ld #0x4f ; 'O'
jp disp3
disp2: ld #0x20 ; ' '
disp3: st ixr,0
ld PTR1 ; ptr1++
inc acc, acc
st PTR1
ld PTR2 ; ptr2++
inc acc, acc
st PTR2
ld X ; x--
dec acc, acc
st X
jpz disp4
jp disp5
disp4: ld PTR2 ; ptr2 += 32
add #32
st PTR2
ld Y ; y--
dec acc, acc
st Y
jpz return
jp disp1
;;
;; wait
;;
wait: ld #10
LOOP22: push
ld #0
LOOP2: dec acc, acc
jpz LOOP21
jp LOOP2
LOOP21: pop
dec acc, acc
jpz return
jp LOOP22
;;
;;
;;
DAT1: .word DATA1 ; DATA1 pointer
DAT2: .word DATA2 ; DATA2 pointer
X: .word 0 ; Variable x
Y: .word 0 ; Variable y
PTR1: .word 0 ; General pointer 1
PTR2: .word 0 ; General pointer 2
NoOf: .word 0 ; Number of object
;; Current space
DATA1: .space 24 ; line 0
.word 1
.space 11
.space 12
.space 22 ; line 1
.word 1
.word 0
.word 1
.space 11
.space 12
.space 12 ; line 2
.word 1
.word 1
.space 6
.word 1
.word 1
.space 12
.word 1
.word 1
.space 12
.space 11 ; line 3
.word 1
.space 3
.word 1
.space 4
.word 1
.word 1
.space 12
.word 1
.word 1
.space 12
.word 1 ; line 4
.word 1
.space 8
.word 1
.space 5
.word 1
.space 3
.word 1
.word 1
.space 14
.space 12
.word 1 ; line 5
.word 1
.space 8
.word 1
.space 3
.word 1
.word 0
.word 1
.word 1
.space 4
.word 1
.word 0
.word 1
.space 11
.space 12
.space 10 ; line 6
.word 1
.space 5
.word 1
.space 7
.word 1
.space 11
.space 12
.space 11 ; line 7
.word 1
.space 3
.word 1
.space 20
.space 12
.space 12 ; line 8
.word 1
.word 1
.space 22
.space 12
.space 336
DATA2: .space 768 ; Next space
.data 0x800
STACK:
VRAM:
.data 0x940
VRAM940:
| Back |
CAD Home |