ArduinoとZ80自作マイコンで動いたFM音源 YM2151をSBC6303でも動かしてみたいと思います。
拡張基板の作成
Arduinoのシールドとして作ったYM2151 FM音源ボード を載せる子基板を作成しました。
…実は以前作った拡張RAMボードに載せようとおもって40pinヘッダをずらそうと奮闘して壊してしまったのでイチから作り直しました。
拡張RAM以外の部分のFM音源シールドを接続する回路図はこんな感じです。
68系はメモリーマップドI/Oなので拡張RAMのRD とWR はSBC6303の拡張コネクタに出力していただいていますのでZ80より回路は更に簡単です。74HC138によるアドレスのデコードだけです。
アドレスもなんとなく$C000あたりにしてみました。
各基板はこんな感じです。
演奏ソフト BASIC 〜 MC6800 ASM
電大版TinyBASICで試しに演奏ソフトを書いてみました。音楽データは$3000からLILBUGのLコマンドで配置しておきます。
WAITがインチキですけど音が出たので一安心。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
1 REM -------------------
2 REM YM2151 PLAY FOR SBC6303
3 REM -------------------
4 REM
10 W=$3000:X=$4393
20 FOR I=W TO X
30 GOSUB 100
40 NEXT I
50 END
100 REM - HANTEI -
110 IF #(I)=$54 GOTO 200
120 IF #(I)=$61 GOTO 300
130 IF #(I)=$62 GOTO 310
140 IF #(I)=$63 GOTO 320
150 IF #(I)=$64 GOTO 320
160 IF #(I)=$66 GOTO 50
170 GOSUB 330:RET
200 REM - PLAY -
210 I=I+1:#($C000)=#(I)
220 I=I+1:#($C001)=#(I)
230 RET
299 REM - WAIT -
300 FOR J=1 TO 1 : NEXT J:RET
310 FOR J=1 TO 2 : NEXT J:RET
320 FOR J=1 TO 3 : NEXT J:RET
330 FOR J=1 TO 4 : NEXT J:RET
やはりZ80マイコンのときといっしょで、アセンブラで書かないとちゃんとした演奏はできなさそう。
MC6800のアセンブラ表とにらめっこしながらArduinoやZ80のアセンブラソースとほぼ同じコードを書いてみました。
Z80のつもりで書くと16bitレジスタペアが少ないとか、分岐命令が+/-127バイト程度だったりとかヒッカカリポイントは多数…
通称prontfデバグと、LILBUGのT(トレース)コマンドで無事稼働しました。
ソースをまたgistにUPしました。長いですが以下のようなソースになります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;
; YM2151 Play for SBC6303
;
ORG $0100
;
; LILBUG INTERNAL ROUTINE
PDATA1 EQU $F80C
LIL_MAIN EQU $F952
;
MUSIC EQU $3000
OPN_IO EQU $C000
;
START EQU *
LDS #STACK
STS SP
;
LDX #MESG
JSR PDATA1
BSR MAIN
;
JMP LIL_MAIN ;PGM END
;
MAIN EQU *
LDX #MUSIC
LOOP EQU *
LDAA 0,X
CMPA #$54
BEQ PLAY
CMPA #$61
BEQ WAIT11
CMPA #$62
BEQ WAIT22
CMPA #$63
BEQ WAIT33
CMPA #$64
BEQ WAIT33
CMPA #$66
BEQ END_RTN
;
CMPA #$70
BEQ WAIT4
BGT CHK_WAIT
NEXT EQU *
INX
BRA LOOP
;
END_RTN EQU *
RTS
;
WAIT11 EQU *
JMP WAIT1
WAIT33 EQU *
JMP WAIT3
WAIT22 EQU *
JMP WAIT2
;
PLAY EQU *
INX
LDAA 0,X
PSHA
INX
LDAB 0,X
;
WRITEOPN EQU *
LDAA OPN_IO+1
ROLA
BCS WRITEOPN
;
PULA
STAA OPN_IO
NOP ;DUMMY
NOP ;DUMMY
STAB OPN_IO+1
JMP NEXT
;
CHK_WAIT EQU *
CMPA #$80
BLT NEXT
;
WAIT4 EQU *
ANDA $0F
INCA
STAA WAIT_T+1
LDAA #0
STAA WAIT_T
JSR WAIT
JMP NEXT
;
WAIT1 EQU *
INX
LDAA 0,X
STAA WAIT_T+1
INX
LDAA 0,X
STAA WAIT_T
BSR WAIT
JMP NEXT
;
WAIT2 EQU *
STS SP
LDS #735
STS WAIT_T
LDS SP
BSR WAIT
JMP NEXT
;
WAIT3 EQU *
STS SP
LDS #882
STS WAIT_T
LDS SP
BSR WAIT
JMP NEXT
;
;
WAIT EQU *
STX X_BUF
LDX WAIT_T
;
WAIT_LOOP EQU *
BSR WAIT1MS
DEX
BEQ WAIT_END
BRA WAIT_LOOP
;
WAIT_END EQU *
LDX X_BUF
RTS
;
WAIT1MS EQU *
LDAA #1
WAIT1MS_LOOP EQU *
DECA
NOP ;DUMMY
NOP ;DUMMY
NOP ;DUMMY
BNE WAIT1MS_LOOP
RTS
; MESSAGE
MESG FCB $0D,$0C
FCC "** YM2151 PLAY for SBC6303 **"
FCB $0D,$0C,4
; RAM
SP RMB 2 ; STACK POINTER STORE
X_BUF RMB 2 ; IX BUFF
WAIT_T RMB 2
; STACK
RMB 46
STACK RMB 1 ;STACK POINTER
View the code on Gist .
アセンブリはクロスアセンブラAS を使ってMac上で実施しました。
(ソースファイル名はPLAY.ASM)
1
2
$ asl -cpu 6800 -L PLAY.ASM
$ p2hex -r \$-\$ -F Moto PLAY.p
音楽データは FCB命令でバイナリデータを並べたものを別途準備。
MacのCoolTERM を使用して1文字あたり1msのウェイトを入れてLILBUGのLコマンドへ転送しました。
MC6800のコードで書いたのはSBC6800でも将来動いたら良いなぁという気持ちもあったりしたのです。
無事 FM音源で 音楽を奏でることができました!!
コメント