GALを使用したZ80ボードについて
前回の記事ではソフトウェアシリアルを実装し、GAME言語を移植したところまで書きました。
今回はHexファイルローダーと簡易モニタ(Gamon)の製作について書いてみます。
前回記事の最後の方に、まずはHexファイルをロードできる環境が必要であることを書きましたが、メモリ64KBの8bit系の場合、HEXファイルは非常に単純なのでアセンブラでサクッとできました。
リストを以下に貼りました。GetcとPutcが前回記事で書いたソフトウェアシリアルの1文字入出力処理でPutsは文字列出力処理です。
Hexファイルローダー
|
C ;*********************************
C ; HexLoader for Z80
C ; Ver0.01 2020/10/26 by skyriver
C ;*********************************
C
C
0100 21 015E C HexLd: LD HL,HexMsg
0103 CD 0064 C CALL Puts
C
0106 CD 0010 C LOAD: CALL Getc
0109 FE 3A C CP ':'
010B 20 F9 C JR NZ,LOAD
C
010D CD 0148 C CALL RDBYTE ; get byte count
0110 47 C LD B,A
0111 CD 0155 C CALL RDWORD ; get address
0114 CD 0148 C CALL RDBYTE ; get record type
0117 5F C LD E,A ; save type
0118 FE 01 C CP 1 ; check end of data
011A 28 15 C JR Z,DSPTYP
C
011C B7 C OR A ; check data record or not
011D 20 0C C JR NZ,LdErr
C
011F CD 0148 C RDDATA: CALL RDBYTE
0122 77 C LD (HL),A
0123 23 C INC HL
0124 10 F9 C DJNZ RDDATA
C
0126 CD 0131 C CALL DSPTYP
0129 18 DB C JR LOAD
C
012B 21 0170 C LdErr: LD HL,ErrMsg ; error occur
012E C3 0064 C JP Puts
C
C
0131 CD 0148 C DSPTYP: CALL RDBYTE ; read check sum
0134 CD 0010 C CALL Getc ; read delimitor
0137 7B C LD A,E ; get type
0138 C6 30 C ADD A,'0'
013A C3 0008 C JP Putc
C
C
C ; read hex nible
C ; A -> data
C
013D CD 0010 C RDNBL: CALL Getc
0140 D6 30 C SUB '0'
0142 FE 0A C CP 10
0144 D8 C RET C
C
0145 C6 F9 C ADD A,10 + '0' - 'A'
0147 C9 C RET
C
C
C ; read byte data
C ; A -> byte data
C
0148 CD 013D C RDBYTE: CALL RDNBL
014B 07 C RLCA
014C 07 C RLCA
014D 07 C RLCA
014E 07 C RLCA
014F 4F C LD C,A
0150 CD 013D C CALL RDNBL
0153 B1 C OR C
0154 C9 C RET
C
C
C ; read hex word
C ; HL -> data
C
0155 CD 0148 C RDWORD: CALL RDBYTE
0158 67 C LD H,A
0159 CD 0148 C CALL RDBYTE
015C 6F C LD L,A
015D C9 C RET
C
015E 48 65 78 4C C HexMsg: DB 'HexLoader Start',13,10,0
0162 6F 61 64 65 C
0166 72 20 53 74 C
016A 61 72 74 0D C
016E 0A 00 C
0170 20 65 72 72 C ErrMsg: DB ' err!',13,10,0
0174 21 0D 0A 00 C
C
|
GAME言語を移植済みなのでメモリダンプ等をGAME言語で作成しているうちに必要最小限のメモリ操作とHexファイルリード/ライト機能が揃い、簡易モニタが出来てしまいました。
最初から作ろうと思って設計したわけではないので若干力づくの部分等もありますが、100行程度のソースで手軽に簡易モニタが作れてしまうのは流石GAME言語と言ったところですね。
この簡易モニタはGAME言語で作ったので
Gamonと命名しました。
GAME言語はアセンブラよりは高級言語なので手軽に変更できて移植性も高いのではないかと思います。
下記の操作例の中のヘルプ表示部分で実装コマンドが判りますが、ReadとWriteコマンドはHexファイルの読み書き用コマンドでRead処理だけは読みこぼし対策として上記のようにアセンブラで作っています。
また、Hexファイルのロード中は一行処理毎にレコードタイプを表示しています。
Gamon操作例
|
*READY
:#=1
** Gamon(Game Monitor) V0.01 2020/10/27 by skyriver ?:Help **
]?
DUMP: Daaaa,aaaa FILL : Faaaa,aaaa,dd
GO : Gaaaa SET : Saaaa
IN ; Iaa OUT : Oaa,dd
READ: R WRITE: Waaaa,aaaa
QUIT: Q HELP : ?
]fc000,c03f,e5
]d89abc000,c048
C000 : E5 E5 E5 E5 E5 E5 E5 E5 - E5 E5 E5 E5 E5 E5 E5 E5 ........ - ........
C010 : E5 E5 E5 E5 E5 E5 E5 E5 - E5 E5 E5 E5 E5 E5 E5 E5 ........ - ........
C020 : E5 E5 E5 E5 E5 E5 E5 E5 - E5 E5 E5 E5 E5 E5 E5 E5 ........ - ........
C030 : E5 E5 E5 E5 E5 E5 E5 E5 - E5 E5 E5 E5 E5 E5 E5 E5 ........ - ........
C040 : 30 31 32 33 34 35 36 37 - 38 01234567 - 8
]sc000
C000 E5 - 1
C001 E5 - 2
C002 E5 -
C003 E5 - -
C002 E5 - 3
C003 E5 - .
]dc000,c00f
C000 : 01 02 03 E5 E5 E5 E5 E5 - E5 E5 E5 E5 E5 E5 E5 E5 ........ - ........
]r
HexLoader Start
0001
]dc000,c03f
C000 : 30 31 32 33 34 35 36 37 - 38 39 41 42 43 44 45 46 01234567 - 89ABCDEF
C010 : 00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F ........ - ........
C020 : 30 31 32 33 34 35 36 37 - 38 39 41 42 43 44 45 46 01234567 - 89ABCDEF
C030 : 00 01 02 03 04 05 06 07 - 08 09 0A 0B 0C 0D 0E 0F ........ - ........
]
|
最後に現時点でのGamonソースを貼っておきます。
Gamonソース(GAME言語)
|
1' simple monitor(Gamon) V002 2020/10/30 by skyriver
10 #=10000
100'*** init
110 M=&+1
120 M:1)=$DB M:3)=$32 M(2)=M M:6)=$C9
130 M:7)=$3E M:9)=$D3 M:11)=$C9
140 M:12)=$3E M:14)=$E6 M:15)=$0F M(8)=$3200 M(9)=M M:20)=$C9
150 M:21)=$3E M:23)=$0F M(12)=$0F0F M(13)=$320F M(14)=M M:30)=$C9
160 B=M+31 Y=B+256
170 /"** Gamon(Game Monitor) V0.02 2020/10/30 by skyriver H:Help **"//
180 ]
200'*** get line
210 P=B Q=B $=Z
220 @
230 C=$ ;=C<>8 #=260
240 ;=Q=B $=Z #=260
250 Q=Q-1 " " $=8
260 ;=(C=$18)*(Q>B) @ $=8 " " $=8 Q=Q-1 @=(Q=B)
262 ;=Q-B>253 $=8 " " $=8 #=280
270 ;=C>=" " Q:0)=C Q=Q+1
280 @=(C=13)
290 ]
300'** Getc from buf
310 C=0 ;=P<Q C=P:0) P=P+1 ;=(C>="a")*(C<="z") C=C-("a"-"A")
320 ]
400'** Get Hex byte D-> 0..15, -1:NG
410 D=-1
420 !=300
430 ;=(C>="0")*(C<="9") D=C-"0"
440 ;=(C>="A")*(C<="F") D=C-"A"+10
450 ]
500'** Get value A->value F->1:OK,0:NG
510 A=0 F=0
520 @
530 !=400 ;=D>=0 A=16*A+D F=1
540 @=(D=-1)
550 ]
600'** PutHex byte D<-data,G<-sum
610 M:22)=D >=M+21 M:13)=M:0) >=M+12
620 M:13)=M:0) >=M+12 C=M:0)
630 C=C+"0" ;=C>"9" C=C+"A"-"0"-10
640 $=C
650 M:13)=D >=M+12 C=M:0)
660 C=C+"0" ;=C>"9" C=C+"A"-"0"-10
670 $=C G=G+D
680 ]
1000'** dump
1010 ;=P<Q !=500 S=A
1020 E=S+$7F ;=P<Q !=500 ;=A>S E=A
1030 @ ??=S " :"
1040 I=0,15
1050 " "
1060 ;=S+I>E " " #=1080
1070 ?$=S:I)
1080 ;=I=7 " -"
1090 @=I+1
1100 " "
1110 I=0,15
1120 T=S:I) ;=(T<" ")+(T>"z") T="."
1130 $=T ;=I=7 " - "
1140 ;=S+I>=E I=15
1150 @=I+1
1160 / S=S+I
1170 @=(S>E)
1180 ]
2000'** Set Memory
2010 ;=P<Q !=500 S=A
2012 ;=P<Q !=500 ;=F ??=S " " ?$=S:0) S:0)=A " - " ?$=A / #=2100
2020 @
2030 ??=S " " ?$=S:0) " -"
2040 Z=" " !=200 /
2050 ;=P=Q S=S+1 F=1 #=2090
2060 !=500
2070 ;=F S:0)=A S=S+1
2080 ;=C="-" S=S-1 F=1
2090 @=(F=0)
2100 ]
3000'** Fill
3010 G=-1
3020 ;=P<Q !=500 S=A ;=P<Q !=500 ;=A>S E=A+1 !=500 ;=F G=A
3030 ;=G=-1 " ?"/
3040 ;=G>=0 @ S:0)=G S=S+1 @=(S=E)
3050 ]
4000'** Go
4010 F=0
4020 ;=P<Q !=500 ;=F "G:" ??=A " " >=A /
4030 ;=F=0 " ?"/
4040 ]
5000'** IN
5010 !=500 ;=F M:2)=A >=M+1 ?$=A " -> " ?$=M:0) /
5020 ]
6000'** OUT
6010 !=500 ;=F S=A !=500 ;=F M:8)=A M:10)=S >=M+7 #=6030
6020 " ?"/ #=6040
6030 ?$=S " <- " ?$=A /
6040 ]
7000'** Help
7010 " *DUMP: D[aaaa[,aaaa]] *FILL : Faaaa,aaaa,dd"/
7020 " *GO : Gaaaa *SET : S[aaaa[,dd]]"/
7030 " *IN ; Iaa *OUT : Oaa,dd"/
7040 " READ: R WRITE: Waaaa,aaaa"/
7050 " QUIT: Q HELP : H"/
7060 " *:can use multi statement separated with ':'"/
7070 " command set:= exec:! display:?"/
7080 ]
8000'** Write
8010 !=500 ;=F=0 #=8900
8020 S=A !=500 ;=F=0 #=8900
8030 ;=S>A #=8900
8040 @
8050 G=0 E=32 ;=A-S+1<E E=A-S+1
8060 ":" D=E !=600 D=S/256 !=600 D=S !=600 D=0 !=600
8070 @ D=S:0) S=S+1 E=E-1 !=600 @=(E=0)
8080 D=-G !=600 /
8090 @=(S>A)
8100 ":00000001FF"/
8110 ]
8900 " ?"/
8910 ]
9000'** set cmd
9010 Y:0)=Q-P ;=P<Q I=1 @ Y:I)=P:0) I=I+1 P=P+1 @=(P=Q)
9020 ]
9100'** Display cmd
9110 ;=Y:0)>0 " " I=1,Y:0) $=Y:I) @=I+1 /
9120 ]
9200'** exec cmd
9210 P=B+1 Q=P
9220 ;=Y:0)>0 I=1,Y:0) Q:0)=Y:I) Q=Q+1 @=I+1
9230 C=":"
9240 ]
10000'** main
10010 !=100
10020 @
10030 Z="]" !=200 !=300 /
10040 ;=C="H" !=7000 #=11000
10050 ;=C="R" >=$100 / #=11000
10060 ;=C="W" !=8000 #=11000
10070 ;=C="=" !=9000 #=11000
10080 ;=C="?" !=9100 #=11000
10090 ;=C="!" !=9200 #=11000
10100 ;=C="G" !=4000 #=11000
10110 ;=C="D" !=1000 #=11000
10120 ;=C="S" !=2000 #=11000
10130 ;=C="F" !=3000 #=11000
10140 ;=C="I" !=5000 #=11000
10150 ;=C="O" !=6000 #=11000
10160 ;=(C<>"Q")*(C>0) $=C " ??"/
11000 ;=C=":" !=300 #=10100
11010 @=(C="Q")
|
★更新 2020/10/30 最新版に更新
Ver0.02 マルチステートメント対応、コマンド記憶機能追加
これで今後の予定であるタイマー割込みによるシリアル受信処理とSPIインターフェースの開発環境が揃いました^^
★追記 2020/10/30 {
モニタを操作していると同じようなコマンドの組合せを何度も実行するよう場面が出てきます。
コマンドをマルチステートメント対応にしてコピペできるようにしました。
更にコマンド記憶機能を追加し、コマンドをまとめて実行できるようにしました。
ちょっとした機能を簡単に追加できるのもGAME言語で作った効用ですね。なにげに便利です^^
}
★追記 2020/11/10
パソコン内のバイナリファイルをモニタでダウンロードする際にHEXファイルに変換する必要があります。
パソコン上のファイルを開始アドレスを指定してインテルヘキサフォーマットに変換するバイナリヘキサ変換ツールを探したけど見つからなかった・・・
処理自体は非常に簡単で探すより作った方が早いのでDOS窓で実行する変換プログラムを作りました。
需要は少ないでしょうがアップしておきます。使い方は下記のヘルプ表示を参照してください。
- Bin2Hex20201109.zip
C:¥tool>bin2hex
convert binary file to intel hex format(can set start address)
usage : bin2hex [-sxxxx] InputFile [>OutputFile]
-s : set start address of hex file
ver 0.01 2020/11/09 by skyriver
C:¥tool>
|
- BIN2HEX_CPM80_20210117v001a.zip
★変更 2021/01/17
Ver0.01a HEXファイル名生成でNGになる場合があったので修正
★追記 2020/12/05
CP/M-80用のbin2hexです。CP/Mではリダイレクトできないので対象ファイル名のセカンドファイル名が".HEX"のファイル名でHEXファイルが生成されます。
HI-TECH Cでコンパイルしているので動作させるためにはCPUがZ-80相当品である必要があります。
★追記 2020/11/19
「
Z80GALの構想(その9)簡易モニタの製作(その2)ブレーク機能の実装」の記事にブレーク機能の追加実装について書きました。
★追記 2023/01/04
「
GAME言語で作った簡易モニタ(Gamon)」の記事に Gamon Ver0.04 を公開しました。
[TOP] [ 前へ ] 連載記事
[ 次へ ]
posted by skyriver at 23:29|
Comment(0)
|
Z80
|

|