SBC68系バスへSBC80系ボードをつなぐ

先日作成した6502CPUマイコンですが、SBC6303ルーズキットやSBC6800 Adapterと同じSBC68系バスを装備してみました。
KZ80シリーズで使っているSBC80系バスへ変換するボードがあると、外部駆動できるボードの幅が広がりそう。
SBC68系バスとSBC80系バスの違い
SBC68系バスは以下のようなピン配置となっています。KZ80などのSBC80系バスとピン数はいっしょですが、電源の位置や制御信号が違っています。
SBC6800 AdapterだとP10〜P17端子のあたりにCPUボードの74138でデコードしたアドレス信号線が出ていたりしますので若干違います。
信号線の変換回路
KZ80用外部ボードではZ80のI/Oアドレス($00〜$FF)をデコードする仕組みはありますが、SBC68系ではメモリーマップドI/OですのでアドレスバスA15〜A8をデコードする追加してあげる必要があります。また、リセット端子もSBC68系バスでは負論理、SBC80系バスでは正論理で反転する必要があります。

アドレスバスA15〜A13のデコードは74HCT138に任せまして、#RD/#WR信号とあわせて74HC139で#IOR/#IOW信号を生成しました。
74HC139の余った部分で#RESET信号をRES信号へ反転させるようにしました。CLK端子にはE(φ2)信号を入れてみました。
KZ80-IOB(I/Oボード)の8255はNG
以前 アドレスデコーダ74HC139に#IOREQを入れて試したときもNGだったのですが、I/Oボード(KZ80-IOB)の8255をつないで試したところNGでした。
SBC68系バスからSBC8080バスへ変換するボード配線はしてみましたが、当然 うんともすんともいいませんでしたw うーむ。ロジアナで動きを探ってみます。 pic.twitter.com/JW5iBvB5D9— KUNI-NET元シソペ (@kuninet) April 29, 2020
実は上記のTweetをしたときには、#WRと#RDの配線が逆だったり、RESの配線端子がずれていたりとヘッポコな状態でした。配線を直してもNGでしたが…(X_X)
FM音源ボードで挑戦
続いて、以前SBC6303でも稼働実績があるFM音源LSI YM2151で試してみることにしました。Arduinoでも演奏できた事例もありますので、ちょっと期待して…
つないだだけでは音楽演奏はできませんので、以前作ったZ80やSBC6303のVGMデータ演奏プログラムを見ながら移植します、どちらのプログラムも元は上記のArduino用VGM Playerです。
6502のニーモニックの資料を参照しながら作ったプログラムは以下になります。いつものThe Macroassembler ASでアセンブリできます。
`;
; YM2151 PLAY
; Universal Minitor for 6502 & SBC68toSBC80 Adapter
;
CPU 6502
TARGET: EQU "6502"
;
;;; Functions
low function x,(x & 255)
high function x,(x >> 8)
;
;
MUSIC EQU $1000
OPM_ADDR EQU $8040
OPM_DATA EQU $8041
;
org $0200
MAIN:
LDA #low(MUSIC)
STA MUSIC_PTR
LDA #high(MUSIC)
STA MUSIC_PTR+1
LOOP:
LDY #0
LDA (MUSIC_PTR),Y
CMP #$54
BEQ PLAY
CMP #$61
BEQ WAIT1_S
CMP #$62
BEQ WAIT2_S
CMP #$63
BEQ WAIT3_S
CMP #$64
BEQ WAIT3_S
CMP #$66
BEQ END_RTN
;
CMP #$70
BEQ WAIT4_S
JMP CHK_WAIT_S
;
NEXT:
JSR ADD_PTR
JMP LOOP
;
END_RTN:
BRK
;
; SUB ROUTINE JUMP
;
PLAY:
JMP PLAY_S
;
ADD_PTR:
LDA #1
CLC
ADC MUSIC_PTR
STA MUSIC_PTR
LDA #0
ADC MUSIC_PTR+1
STA MUSIC_PTR+1
RTS
WAIT1_S:
INY
LDA (MUSIC_PTR),Y
STA WAIT_CNT
INY
LDA (MUSIC_PTR),Y
STA WAIT_CNT+1
JSR WAIT
JSR ADD_PTR
JSR ADD_PTR
JMP NEXT
;
WAIT2_S:
LDA #low(735)
STA WAIT_CNT
LDA #high(735)
STA WAIT_CNT+1
JSR WAIT
JMP NEXT
;
WAIT3_S:
LDA #low(882)
STA WAIT_CNT
LDA #high(882)
STA WAIT_CNT+1
JSR WAIT
JMP NEXT
;
CHK_WAIT_S:
CMP #$80
BCS WAIT4_EXIT
WAIT4_S:
AND #$0F
CLC
ADC #1
STA WAIT_CNT
LDA #0
STA WAIT_CNT+1
JSR WAIT
WAIT4_EXIT:
JMP NEXT
;
WAIT:
JSR WAIT_1MS
SEC
LDA WAIT_CNT
SBC #1
STA WAIT_CNT
LDA WAIT_CNT+1
SBC #0
STA WAIT_CNT+1
;
LDA WAIT_CNT
CMP WAIT_CNT+1
BNE WAIT
WAIT_EXIT:
RTS
WAIT_1MS:
LDA #$E0
STA WAIT_1MS_CNT
WAIT_1MS_LOOP:
DEC WAIT_1MS_CNT
NOP
NOP
BNE WAIT_1MS_LOOP
RTS
;
;
PLAY_S:
INY
LDA (MUSIC_PTR),Y
STA WK_ADDR
INY
LDA (MUSIC_PTR),Y
STA WK_DATA
;
WRITE_OPM
LDA OPM_DATA
CMP #$80
BEQ WRITE_OPM
;
LDA WK_ADDR
STA OPM_ADDR
NOP
NOP
NOP
NOP
LDA WK_DATA
STA OPM_DATA
JSR ADD_PTR
JSR ADD_PTR
JMP NEXT
;
; Work Area
;
org $30
MUSIC_PTR RMB 2
WK_ADDR RMB 1
WK_DATA RMB 1
WAIT_CNT RMB 2
WAIT_1MS_CNT RMB 1
SUB_PTR FDB SUB_PTR_TBL
;
END`
そんなに長いプログラムではないものの、6502CPUのニーモニックに慣れていないもので半日ぐらいウンウン言ってました。コーディングしてみて気がついた点としては…
- アキュームレーターのインクリメント命令が無い
- インデックスレジスタのインクリメント命令(INY)が255を超えてもキャリーフラグが立たない
- 加算命令、減算命令にキャリー付きしかないので、加算前はキャリークリア、減算前はキャリーセットが吉
- M6800 CPUも同じですが、条件分岐ジャンプが相対ジャンプなのですぐ127バイトの壁を超えて飛べなくなってしまう
- やっぱり間接アドレス用に16bitレジスタが1つは欲しいw メモリーの16bitデータの加算命令があればなぁとか…
ボードの回路データや、上記のプログラム等はgithubにUPしました。
サンプル音楽を演奏、鳴った!!
KZ80-YM2151FM音源ボードのリポジトリにも添付しているサンプルVGMデータで鳴らしてみました。無事音楽が鳴りました!! やった〜。
6502マイコン+FM音源ボード KZ80-YM2151 いい感じで鳴りました。WAITルーチンで アキュームレータから -1するときにキャリーフラグの操作を間違えてました。引き算のときにはキャリーをセットしておくんですね。 pic.twitter.com/mzQI8WOZB1— KUNI-NET元シソペ (@kuninet) May 5, 2020
これで、SBC68系からSBC80系バスへの変換ボードの回路が良さげな感じということがわかりましたので、今後 他のKZ80シリーズとして作ったボードを接続してみたいと思います。
