PC-6001では滅多に使われることのなかったUSR関数を、今になって無理やり使ってみようと思い立ち、簡易PCGライブラリーっぽいものを作ってみました。
マシン語を使っているとはいえ、速度の面ではかなり厳しいですが、テキスト画面で動いているBASICプログラムであれば、比較的簡単にPCG化できると思います。
文法的には、プチコンのBG系命令を参考にしました。「誰得?」とかは、考えるだけ野暮というものです。
すべてのファイル(+おまけ)のダウンロードはこちら
MODE2あるいはMODE4、PAGE 2での動作を想定しています。
また、SCREEN 3 または SCREEN 4 のどちらでも動作します。
List.1 PCGライブラリー
10 CLEAR 200,&HD000 20 AD=&HDB00:GOSUB 50000 49990 END 50000 REM------------- 50010 REM PCG LIB 50020 REM------------- 50030 RESTORE 50100 50040 FOR I=AD TO AD+&H1FF 50050 READ A$:POKE I,VAL("&H"+A$) 50060 NEXT 50070 POKE &HFAEB,AD AND 255:POKE &HFAEC,(AD/256)AND 255 50080 RETURN 50100 DATA E1,CD,41,07,E1,2B,D7,CA,EA,03,FE,49,20,63,23,7E 50110 DATA FE,4E,C2,EA,03,23,7E,FE,49,C2,EA,03,23,7E,FE,54 50120 DATA C2,EA,03,ED,53,FB,FB,D7,20,10,01,00,D8,ED,43,FF 50130 DATA FB,01,00,D0,ED,43,FD,FB,18,1B,FE,2C,C2,EA,03,23 50140 DATA CD,06,0E,ED,53,FD,FB,7E,FE,2C,C2,EA,03,23,CD,06 50150 DATA 0E,ED,53,FF,FB,AF,E5,2A,FD,FB,5D,54,13,77,01,FF 50160 DATA 07,ED,B0,2A,FF,FB,5D,54,13,77,01,FF,02,ED,B0,E1 50170 DATA C9,F5,7A,B7,C2,55,07,ED,53,F9,FB,F1,FE,A0,20,29 50180 DATA 23,E5,2A,FB,FB,0E,18,06,20,C5,E5,2A,EB,FA,01,99 50190 DATA 00,09,D1,E5,EB,5D,54,18,71,C1,23,10,EC,11,E0,00 50200 DATA 19,0D,20,E3,3A,F9,FB,18,BA,FE,AE,28,12,FE,50,20 50210 DATA 75,23,7E,FE,55,C2,EA,03,23,7E,FE,54,C2,EA,03,23 50220 DATA 7E,FE,2C,C2,EA,03,23,CD,06,0E,7A,B7,C2,55,07,7B 50230 DATA FE,20,D2,55,07,7E,FE,2C,C2,EA,03,23,D5,CD,06,0E 50240 DATA 7A,B7,C2,55,07,7B,FE,18,D2,55,07,EB,29,29,29,29 50250 DATA 29,C1,C5,E5,09,ED,4B,FF,FB,09,3A,F9,FB,77,E1,29 50260 DATA 29,29,C1,09,ED,4B,FB,FB,09,EB,E5,ED,4B,FD,FB,2A 50270 DATA F9,FB,29,29,29,09,EB,06,08,1A,77,C5,01,20,00,09 50280 DATA 13,C1,10,F5,E1,C9,FE,86,20,41,23,7E,FE,2C,C2,EA 50290 DATA 03,23,CD,06,0E,7A,B7,C2,55,07,7B,FE,20,D2,55,07 50300 DATA 7E,FE,2C,C2,EA,03,23,D5,CD,06,0E,7A,B7,C2,55,07 50310 DATA 7B,FE,18,D2,55,07,EB,29,29,29,29,29,C1,09,ED,4B 50320 DATA FF,FB,09,7E,EB,E5,CD,2B,0D,E1,C9,FE,53,C2,EA,03 50330 DATA 23,7E,FE,45,C2,EA,03,23,7E,FE,54,C2,EA,03,23,7E 50340 DATA FE,2C,C2,EA,03,23,CD,09,0B,3A,25,FF,B7,CA,EA,03 50350 DATA E5,2A,67,FF,23,23,5E,23,56,EB,06,08,E5,ED,5B,FD 50360 DATA FB,2A,F9,FB,29,29,29,19,EB,E1,7E,D6,30,DA,EA,03 50370 DATA FE,0A,38,17,D6,07,FE,0A,DA,EA,03,FE,10,38,0C,D6 50380 DATA 20,FE,0A,DA,EA,03,FE,10,D2,EA,03,07,07,07,07,4F 50390 DATA 23,7E,D6,30,DA,EA,03,FE,0A,38,17,D6,07,FE,0A,DA 50400 DATA EA,03,FE,10,38,0C,D6,20,FE,0A,DA,EA,03,FE,10,D2 50410 DATA EA,03,81,12,23,13,10,B2,AF,CD,2B,0D,E1,C9,00,00
先程のプログラムを実行すると、USR関数が拡張され、以下の関数が使えるようになります。[ ] 内は省略可能です。
A=USR(&HE200)INIT,&HD000,&HD800
ビットマップ | 16進 |
---|---|
11111111 11000011 11000011 11000011 11000011 11000011 11000011 11111111 |
FF C3 C3 C3 C3 C3 C3 FF |
A=USR(2)SET,"FFC3C3C3C3C3C3FF"
A=USR(2)PUT,16,4
A=USR(2)CLS
A=USR(0)READ,16,4
例)IF文などで使う場合は括弧で囲むIF (USR(0)READ,16,4)=5 THEN PRINT"HIT"
デフォルトでのメモリマップは、以下のようになっています。
D000H-D7FFH | キャラクターデータ(256キャラ分) | USR()SETで定義されたキャラクターデータが格納される。 |
D800H-DAFFH | パターンネームテーブル(32x24文字) | USR()PUTで画面に描画されたキャラクターの番号が保存される。 USR()READで読めるので、ゲームなどでSCREEN(X,Y)の変わりに使う。 |
DB00H-DCFFH | プログラム | プログラム本体。ここだけをBSAVEしても動作するはず。 |
FBF9H-FC00H | ワークエリア | RS-232C用のバッファをワークエリアとして使用。 |
PCGを使ったサンプルです。
敵に捕まらないようにフルーツを取るだけです。
PCGライブラリのプログラムとマージするか、ライブラリ組み込み後に実行してください。
ただ……すみません、やっつけで作ったので面白くないです。。。
List.2 サンプルプログラム(List.1とマージして実行)
70 REM------------------------ 80 REM MAIN 90 REM------------------------ 100 SCREEN 3,2,2:CONSOLE 0,16,0,0:COLOR 3,1,1:CLS 110 A=USR(&HE200)INIT 120 RESTORE 1000 130 FOR I=0 TO 14 140 READ A$ 150 A=USR(I)SET,A$ 160 NEXT 170 A=USR(0)CLS 180 FOR I=0 TO 31 190 A=USR(1)PUT,I,1:A=USR(1)PUT,I,23 200 NEXT 210 FOR I=1 TO 23 220 A=USR(1)PUT,0,I:A=USR(1)PUT,31,I 230 NEXT 240 X=16:Y=12:EX=1:EY=2:F=0:M=0:S=0:GOSUB 900 250 FX=RND(1)*30+1:FY=RND(1)*21+2 260 IF (USR(0)READ,FX,FY)=0 THEN A=USR(1+(M AND 1)*2)PUT,FX,FY 300 T=STICK(0):M=M+1 310 VX=(T=7)-(T=3):VY=(T=1)-(T=5) 320 IF VX<>0 OR VY<>0 THEN A=USR(F)PUT,X,Y:F=0:PLAY"V13O4C32" 340 A=USR(0)READ,X+VX,Y+VY 350 IF A=0 OR A=2 THEN 500 360 IF A=1 THEN VX=0:VY=0:GOTO 500 370 S=S+10:GOSUB 900 380 F=1:PLAY"V13O5C32G32" 500 X=X+VX:Y=Y+VY 510 A=USR(2)PUT,X,Y 600 A=USR(0)PUT,EX,EY 610 VX=SGN(X-EX):VY=SGN(Y-EY) 620 IF VX=0 OR VY=0 THEN 650 630 IF RND(1)*2>1 THEN VX=0:GOTO 650 640 VY=0 650 A=USR(0)READ,EX+VX,EY+VY 660 IF A=1 AND (M AND 1)=0 THEN VX=0:VY=0 670 EX=EX+VX:EY=EY+VY:PLAY"V13O3C32" 680 A=USR(4)PUT,EX,EY 690 IF X=EX AND Y=EY THEN 800 700 GOTO 250 800 EXEC&H1058 810 FOR I=0 TO 30:A=USR(2)PUT,X,Y:A=USR(4)PUT,X,Y:NEXT 820 IF INKEY$="" THEN 820 830 GOTO 110 900 A$=" "+STR$(S) 910 FOR I=0 TO 4 920 A=USR(VAL(MID$(A$,LEN(A$)-I,1))+5)PUT,6-I,0 930 NEXT 940 RETURN 1000 DATA AAAAAAAAAAAAAAAA 1010 DATA DD77DD77DD77DD77 1020 DATA BE979600820028EB 1030 DATA 8AA2B2FFFFFFFFBE 1040 DATA 69557755486996AA 1050 DATA 56666666666656AA 1060 DATA 9A5A9A9A9A9A56AA 1070 DATA 56A6A6566A6A56AA 1080 DATA 56A6A656A6A656AA 1090 DATA 66666656A6A6A6AA 1100 DATA 566A6A56A6A656AA 1110 DATA 566A6A56666656AA 1120 DATA 56A6A69A9A9A9AAA 1130 DATA 56666656666656AA 1140 DATA 56666656A6A656AA
「PCGを使っている他機種のBASICプログラムを移植するのに使えそう」と期待に燃えた方、すみません。
BASICからの呼び出しが原因なのか、引数をFACに格納するルーチンが原因なのか、あるいは私のプログラムが原因なのかわかりませんが、
処理が重いです。
mkIIの PUT@ くらいな感じで考えていただけると良いかと思います。
やはり、高速なゲームを作るには、メインのプログラム部分もマシン語で書かないとダメかもしれません。。。