FP-1100サブCPU制御参考プログラム・リスト

ごくごく一部で求められていたような気がしたので、FP-1100のサブCPU直接制御サンプルプログラムをまとめてみました。実記でもエミュレータでも動くように調整しました。ご自由にお使い、または参考にしてください。


冒頭はサンプルです。実際必要なのはSUBINIT以下になります。んで使い方。まずSUBINITをCALLしてください。SUBINITでは、画面を40字モードに切り替えた後、サブCPUのFF80h〜にプログラムを転送します。
サブCPUのプログラムは後半のsubdata〜になります。


サブ側のハックが成功すると、サブCPUはメインからの1byteを待ち続けます。
そして1byteを受け取るとその値を下位8ビットとして&HFFxx番地にジャンプします。


サブ側には
・HL受け取り(FF95h
・1バイト受け取って(HL)に書き込み、HL++(FFA0h
beep on(FFA7h
beep off(FFAEh
・ポートBの内容をメインに送る(FFB5h
・8バイトを連続で受け取り、(HL)に書き込み(FFC6h
のルーチンを作ってあります。どれも読みやすさを優先したもので、まだまだ最適化できると思います。メモリもまだちょっと余裕あります。


たとえばFPのキースキャンは「サブCPUの&HE400にラインNoを書き込んでから少し待つと、ポートBにスキャン結果が帰ってくる」ので、HLに&HE400をセットしてあげた後にラインNoを1バイト送信してあげて、さらにポートBの内容を受け取っています。


FP-1100の基礎知識としてこちらのエントリ(http://d.hatena.ne.jp/tanzi/20150623/p2)も参考にしてください。


更なる高速化への夢:
・せっかくCPUが二つあるのに全くと言っていいほど並列化されていないので、いかに並列化させるかがポイント?
・キャラクタ消去専用のルーチンを作っておけばちょっと並列化できる
・メインからグラフィックデータを1バイトずつ送るとつきっきりなので並列化できない。VRAMの見えてない範囲にデータを置いてサブ側で転送させるのはどうか? VRAMアクセスでウェイトがかかるのがネックになりそうだが、CPUが並列で動く恩恵のほうが大きいのでは?
・キーボード読み取りにも時間がかかっている。複数ラインの読み取りが必要な場合、もっと処理を考えないといけないような気がする。
・複数のデータをやりとりする場合、一度同期すればあとはクロック数をみてサブとメインのタイミングを合わせるとこができそうだけど・・・エミュと実機で再現性が違ったりいろいろ問題もありそう。


とはいえ、このまま使っても無印88のゲームくらいだったら動かせそうな予感。まぁ、パレットがないのでアルフォスなどは無理ですが・・・・
ちゅーわけで、以下!

※2022.10.10 ソースリストを若干更新。SUBINITをコールした後に空ループを入れました。エミュレータだと無くても問題ないのですが、実機だとSUBINITの後の処理によってはウェイトを入れておかないと上手く動かないことがあるための処置になります。

ORG 0A800h

;********************
	CALL	SUBINIT

	LD	B,0FFh
SLOOP:	
        DJNZ	SLOOP

SOUND:
	LD	B,0FFh
BEEPON:
	LD	A,0A7h
	CALL	MtoS
BEEPOFF:
	LD	A,0AEh
	CALL	MtoS
	
	LD	A,B
SLOOP2:	DEC	A
	JR	NZ,SLOOP2
	
	DJNZ	BEEPON

KEYSCAN:
	LD	HL,0E400h
	CALL	setHL
	LD	A,0A0h
	CALL	MtoS
	LD	A,026h
	CALL	MtoS
	CALL	StoM
	
PUTCHR:	
	PUSH	AF
	LD	HL,0A000h
	CALL	setHL
	LD	A,0C6h
	CALL	MtoS
	POP	AF
	LD	B,08h
PCLOOP:	CALL	MtoS
	DJNZ	PCLOOP
	
	JP	KEYSCAN
	
;********************
SUBINIT:
	LD	A,33
	LD	B,0
	CALL	0B00H		;width40
	LD	A,19
	LD	BC,07001H
	CALL	0B09H		;COLOR 1,0
	LD	HL,00617h
	LD	(09FD7h),HL
	CALL	007A4h		;locate 6,23
	LD	HL,subdata-7
	LD	B,017h		;23chr
loop1:	CALL	0077Eh		;print defchr$
	DJNZ	loop1
	LD	A,052h
	CALL	00AFBh		;Int.SubCPU  / code = $52
	RET

;********************
MtoS:
	PUSH	BC
	EX	AF,AF'
	LD	BC,0FF80h
p1:	IN	A,(C)
	OR	A
	JR	NZ,p1		;wait code 0 from sub CPU
	EX	AF,AF'
	PUSH	AF
	LD	C,0C0h
	OUT	(C),A		;Areg <- (FFC0h)
	LD	C,080h
	LD	A,0C0h
	OUT	(C),A		;INTS ON
	LD	A,020h
	OUT	(C),A		;INTS OFF
p2:	IN	A,(C)
	INC	A
	JR	NZ,p2		;wait code ffh from sub CPU
	POP	AF
	POP	BC
	RET
	
;********************
StoM:
	PUSH	BC
	LD	A,0B5h
	CALL	MtoS
	LD	B,028h
sml1:	DJNZ	sml1
	LD	BC,0FF80h
	IN	A,(C)
	PUSH	AF
sml2:	IN	A,(C)
	INC	A
	JR	NZ,sml2
	POP	AF
	POP	BC
	RET

;********************
setHL:
	PUSH	AF
	LD	A,095h
	CALL	MtoS
	LD	A,L
	CALL	MtoS
	LD	A,H
	CALL	MtoS
	POP	AF
	RET
	
;********************
subdata:
					;VRAMからSUBCPUへコード転送
	DB	048h,024h		;DI
	DB	069h,0FFh		;MVI	A,FFh
	DB	070h,079h,000h,0E8h	;MOV	E800h,A
	DB	004h,000h,000h		;LXI	SP,0000h
	DB	034h,061h,028h		;LXI	HL,2861h		転送元
	DB	024h,080h,0FFh		;LXI	DE,FF80h		転送先
	DB	06Bh,07Fh		;MVI	C,7Fh		転送バイト数
	DB	031h			;BLOCK
	DB	024h,000h,0FFh		;LXI	DE,FF00h
	DB 	014h,000h,0FFh		;LXI	BC,FF00h
	DB	011h			;EXX
	DB	024h,000h,0E4h		;LXI	DE,E400h
	DB	011h			;EXX
	DB	054h,080h,0FFh		;JMP	FF80h
	
	
;ORG	sub - FF80h
;MAIN
	DB	044h,085h,0FFh		;CALL	MtoS
	DB	01Bh			;MOV	C,A
	DB	073h			;JB
;FF85h
;MtoS
	DB	070h,07Dh,000h,0E8h	;MOV	E800h,E
	DB	048h,003h		;SKIT	F2		:L1
	DB	0FDh			;JR	L1
	DB	070h,069h,000h,0E8h	;MOV	A,E800h
	DB	070h,07Ch,000h,0E8h	;MOV	E800h,D
	DB	008h			;RET
;FF95h
;getHL
	DB	044h,085h,0FFh		;CALL	MtoS
	DB	01Fh			;MOV	L,A
	DB	044h,085h,0FFh		;CALL	MtoS
	DB	01Eh			;MOV	H,A
	DB	054h,080h,0FFh		;JMP	MAIN
;FFA0h
;get&write1byte				
	DB	044h,085h,0FFh		;CALL	MtoS
	DB	03Dh			;STAX	H+ (HL)
	DB	054h,080h,0FFh		;JMP	MAIN
;FFA7h
;beepOn					
	DB	011h			;EXX
	DB	04Ah,030h		;MVIX (DE),30h  		:BEEP ON
	DB	011h			;EXX
	DB	054h,080h,0FFh		;JMP	MAIN
;FFAEh
;beepOff				
	DB	011h			;EXX
	DB	04Ah,020h		;MVIX (DE),20h  		:BEEP OFF
	DB	011h			;EXX
	DB	054h,080h,0FFh		;JMP	MAIN
;FFB5h
;sendPortB				
	DB	04Ch,0C1h		;MOV	A,PortB
	DB	070h,079h,000h,0E8h	;MOV	E800h,A
	DB	06Bh,00Dh		;MVI	C,0Dh
	DB	053h			;DCR	C		:L2
	DB	0FEh			;JR	L2
	DB	070h,07Ch,000h,0E8h	;MOV	E800h,D
	DB	054h,080h,0FFh		;JMP	MAIN
;FFC6h
;get&write8byte				
	DB	06Bh,007h		;MVI	C,07h
	DB	044h,085h,0FFh		;CALL	MtoS		:L3
	DB	03Dh			;STAX	H+ (HL)
	DB	053h			;DCR	C
	DB	0FAh			;JR	L3
	DB	054h,080h,0FFh		;JMP	MAIN
	
END

参考:FP-1100 100%活用法(技術評論社) / ベジタブルクラッシュ(ハドソン)