2026年04月01日

TMPZ84Compactの開発(その6)PICの乗算機能


1.はじめに
 秋月さんが秋葉原店で安売りしていた Super AKI-80 から取り外したCPU(東芝製TMPZ84C015)を使って開発した TMPZ84Compact(下の写真)はハードを開発してからかなり時間が経ちましたが、ここで制御用に使用している20ピンの PIC(PIC18F14K50)には8bitの符号無し乗算を1サイクルで実行できる命令があることを思い出しました。今回、この乗算機能を Z80 から利用できるようにしてみたので記録しておきます。

開発したTMPZ84Compact


2.PICの乗算命令
 下図は PIC のデータシートから引用した命令表の一部です。黄色マーカー部に記載されているように1サイクルで8bitの乗算が完了します。
 実は「CPLD(XC9572)で遊ぶ」の記事で書いた XC9572 を使って8x8の乗算器を作って TMPZ84Compact に接続してみようかとも考えていたのですが、上述のように PIC に同様の機能があるのでPIC 側を使うことにしました。

PICの命令表(抜粋)


3.Z80とのインターフェース
 もともと PIC から Z80 にパソコンとの通信機能やSDアクセス機能を提供しているので、同様の手法で乗算機能を利用できるように対応するサービスIDを追加しました。
 具体的には下記のようなコードでZ80が乗算機能を利用できるようにしました。

乗算機能使用のサンプルソース(Z80アセンブラ)
                                ;+++++++++++++++++++++++++++++++++++++++++++
                                ; PIC18 Mul service test
                                ;  ver 0.01 2026/04/01 skyriver
                                ;+++++++++++++++++++++++++++++++++++++++++++
                                
                                INCLUDE	TMPZ84C.INC

  0007                          MUL_SRV	EQU	7	; MUL service ID
                                
                                	ORG	0100H
                                
  0100    3E 07                 START:	LD	A,MUL_SRV
  0102    D3 01                 	OUT	(CMDPORT),A	; send mul service ID
  0104    2A 0200               	LD	HL,(MULVAL)
  0107    7D                    	LD	A,L
  0108    D3 00                 	OUT	(DATPORT),A	; send variable0
  010A    7C                    	LD	A,H
  010B    D3 00                 	OUT	(DATPORT),A	; send variable1
  010D    DB 00                 	IN	A,(DATPORT)	; get result(low)
  010F    6F                    	LD	L,A
  0110    DB 00                 	IN	A,(DATPORT)	; get result(high)
  0112    67                    	LD	H,A
  0113    22 0202               	LD	(RESULT),HL
  0116    C9                    	RET
                                
                                
                                	ORG	0200H
                                
  0200    04 05                 MULVAL:	DB	4,5
  0202                          RESULT:	DS	2
                                
                                	END

 CP/M環境でGAME言語を使って下記のソースで 0x00~0xff の全範囲での乗算結果の検証を行い、問題無いことを確認しました。
 尚、下記のソースで 1000~1040行の部分は動作確認のためのもので最終的には非実行にしています。

乗算機能の検証ソース(GAME言語)
1'++++++++++++++++++++++++++++++++++++
2' PIC18 Mul service function test
3'  ver 0.01 2026/04/01 skyriver
4'++++++++++++++++++++++++++++++++++++
10 M=$2000
20 M(1)=$2100 M(3)=$073E M(4)=$01D3 M(5)=$D37D
30 M(6)=$7C00 M(7)=$00D3 M(8)=$00DB M(9)=$DB6F
40 M(10)=$6700 M(11)=$2200 M(12)=M M(13)=$C9
50 #=2000
1000 /"input val0" M:4)=?
1002 ;=M:4)=0 #=-1
1010 "      val1" M:5)=?
1020 >=$2002
1030 /"result:" ?=M(0)
1040 #=1000
2000 I=0,255
2002  "."
2010  M:4)=I
2020  J=0,255
2030   M:5)=J
2040   >=$2002
2050   ;=M(0)<>(I*J) /"error at " ?=I " x " ?=J " ans:" ?=M(0) #=-1
2060  @=J+1
2070 @=I+1


4.乗算機能の評価
 追加した乗算機能を評価するために ASCIIART のアセンブラソースに適用してみました。この ASCIIART の処理は2バイトの固定小数点を使って高速化しています。2バイトの乗算を行うために乗数をバイトに分割して処理するバイト分割法を使いました。
 実行した際の画面キャプチャが下図になります。今回追加した乗算機能を使った場合、マンデルブロ描画は 14.5秒で完了しました(TMPZ84C015は6MHz12.5MHz、メモリウェイト無しで動作 ※修正 2026/04/02)。

ASCIIART実行画面

 ん~~、思った程には高速化していませんね・・
 実は元々のソフト演算による2バイト固定小数点処理を使ったものでは、4.6秒で描画が完了します。
 8bitの乗算処理単体では PICから提供する乗算機能の方が速そうですが、2バイト乗算ではバイト分割法によるオーバーヘッドがかなり大きいようです。

 最後に、2バイトの固定小数点乗算処理のソースも貼っておきます(後半が元々あったソフト乗算処理)。

2バイト固定小数点演算処理(Z80アセンブラ)
				if	01

                                ; use PIC's Mul Function
                                ; HL,DE <- value
                                ; HL -> result:HL*DE
                                ;    (256*x1 + x0)*(256*y1 + y0)
                                ;   = 2^16x1y1 + 2^8(x0*y1 + x1*y0) + x0*y0
                                ; 
                                ; |   .   |   .   |   .   |   .   |
                                ; <---  x1y1   --->
                                ;         <---  x0y1  --->
                                ;         <---  x1y0  --->
                                ;                 <---  x0y0  --->
                                
  01C8    0E 00                 MUL:	LD	C,0
  01CA    CB 7C                 	BIT	7,H
  01CC    28 07                 	JR	Z,Mul10
                                
  01CE    0C                    	INC	C
  01CF    AF                    	XOR	A
  01D0    95                    	SUB	L
  01D1    6F                    	LD	L,A
  01D2    9C                    	SBC	A,H
  01D3    95                    	SUB	L
  01D4    67                    	LD	H,A
  01D5    CB 7A                 Mul10:	BIT	7,D
  01D7    28 07                 	JR	Z,Mul20
                                
  01D9    0C                    	INC	C
  01DA    AF                    	XOR	A
  01DB    93                    	SUB	E
  01DC    5F                    	LD	E,A
  01DD    9A                    	SBC	A,D
  01DE    93                    	SUB	E
  01DF    57                    	LD	D,A
  01E0    CB 19                 Mul20:	RR	C		; Cy 1:negative
  01E2    08                    	EX	AF,AF'
                                
  01E3    3E 07                 	LD	A,MUL_SRV
  01E5    D3 01                 	OUT	(CMDPORT),A
  01E7    0E 00                 	LD	C,DATPORT
  01E9    ED 59                 	OUT	(C),E
  01EB    ED 69                 	OUT	(C),L
  01ED    ED 40                 	IN	B,(C)		; dummy read
  01EF    ED 40                 	IN	B,(C)
  01F1    D3 01                 	OUT	(CMDPORT),A
  01F3    ED 59                 	OUT	(C),E
  01F5    ED 61                 	OUT	(C),H
  01F7    ED 78                 	IN	A,(C)
  01F9    80                    	ADD	A,B
  01FA    5F                    	LD	E,A
  01FB    ED 78                 	IN	A,(C)
  01FD    CE 00                 	ADC	A,0
  01FF    47                    	LD	B,A		; B:E
  0200    3E 07                 	LD	A,MUL_SRV
  0202    D3 01                 	OUT	(CMDPORT),A
  0204    ED 51                 	OUT	(C),D
  0206    ED 69                 	OUT	(C),L
  0208    ED 78                 	IN	A,(C)
  020A    83                    	ADD	A,E
  020B    6F                    	LD	L,A
  020C    ED 78                 	IN	A,(C)
  020E    88                    	ADC	A,B
  020F    47                    	LD	B,A		; B:L
  0210    3E 07                 	LD	A,MUL_SRV
  0212    D3 01                 	OUT	(CMDPORT),A
  0214    ED 51                 	OUT	(C),D
  0216    ED 61                 	OUT	(C),H
  0218    ED 78                 	IN	A,(C)
  021A    80                    	ADD	A,B
  021B    67                    	LD	H,A
  021C    ED 78                 	IN	A,(C)		; dummy read
                                
  021E    08                    	EX	AF,AF'
  021F    D0                    	RET	NC
                                
  0220    AF                    	XOR	A
  0221    95                    	SUB	L
  0222    6F                    	LD	L,A
  0223    9C                    	SBC	A,H
  0224    95                    	SUB	L
  0225    67                    	LD	H,A
  0226    C9                    	RET
                                
                                
                                	else
                                
                                
                                MUL:	LD	BC,15*256
                                	BIT	7,H
                                	JR	Z,Mul10
                                
                                	INC	C
                                	XOR	A
                                	SUB	L
                                	LD	L,A
                                	SBC	A,H
                                	SUB	L
                                	LD	H,A
                                Mul10:	EX	DE,HL
                                	ADD	HL,HL
                                	JR	NC,Mul20
                                
                                	INC	C
                                	XOR	A
                                	SUB	L
                                	LD	L,A
                                	SBC	A,H
                                	SUB	L
                                	LD	H,A
                                Mul20:	RR	C		; Cy 1:negative
                                	EX	AF,AF'
                                	LD	C,H
                                	LD	A,L
                                	LD	HL,0
                                MulLoop:
                                	ADD	HL,HL
                                	RLA
                                	RL	C
                                	JR	NC,MulL10
                                
                                	ADD	HL,DE
                                	ADC	A,0
                                MulL10:	DJNZ	MulLoop
                                
                                	LD	L,H
                                	LD	H,A
                                
                                	EX	AF,AF'
                                	RET	NC
                                
                                	XOR	A
                                	SUB	L
                                	LD	L,A
                                	SBC	A,H
                                	SUB	L
                                	LD	H,A
                                	RET
                                
                                	endif
	
※2026/04/03 変更



[TOP] [ 前へ ] TMPZ84Compactの開発 [ 次へ ]

posted by skyriver at 22:42| Comment(2) | Z80 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
2バイト処理もPIC側に移して、Z80側からは2バイト乗算器に見せることができれば速くなるかなあ。
AVRと違ってPICはCPIが低いから、Z80比で速くならないかもしれない。
dsPIC30とかをアクセラレータにしてみたい。
Posted by enaka at 2026年04月01日 23:00
制御側のチップ性能をどんどん向上させた場合の行き着く先は・・
Z80には電源供給のみで制御チップがZ80をエミュっているマトリックスのような世界かもしれませんねw
Posted by skyriver at 2026年04月01日 23:20
コメントを書く
コチラをクリックしてください