SSブログ
English Version

GAME言語での ASCIIART の高速化 [Z80]

 自作した CPU 基板等の処理能力を確認するためにマンデルブロ演算結果をキャラクタで表示するアスキーアートのベーシックプログラム(以降、asciiart と記す)が使われるようになってきました。

 最近、Twitter の TL で整数型ベーシックの環境で固定小数点演算処理を行いアスキーアートを表示する例を見かけました。
 asciiart のベーシックプログラムの中身を見てみると除算を使用していないので乗算のみを固定小数点対応にすれば対応できそうであることが判ります。

 そこで16ビット長の固定小数点の乗算処理をアセンブラで作成することでGAME言語の環境で高速に asciiart を実行できないか検討してみました。16ビット長の固定小数点を使えば元々の加減算処理はそのまま使えます。

 結果から先に書くと asciiart の実行時間は下記になりました^^

No.実行環境実行時間ハード環境
1GAME80インタープリタ 30.7s Z80PicCompact 
 Z80:12MHz
2GAME80コンパイラ 6.2s Z80PicCompact 
 Z80:12MHz
3人間が
アセンブラで記述
4.8s skyriver     
 Heartbeat:0.97Hz

[History]
  • 2023/01/05 Ver0.02
    Fixed Point処理改善でコンパイラとインタプリタの実行時間がそれぞれ 8.8s⇒8.4s、40.0s⇒39.6sに改善
  • 2023/01/05 Ver0.03e
    Fixed Point処理変更でコンパイラとインタプリタの実行時間がそれぞれ 8.4s⇒6.2s、39.6s⇒30.7sに改善
  • 2023/01/05
    人間コンパイラ環境での実行時間を追記。計算方法を修正(5.8s⇒4.8s)

 尚、Z80PicCompact は現在開発中の 20 ピンの PIC を使用した3チップ構成で小型の Z80 ワンボードマイコンです。

 乗算処理のみをアセンブラの処理に入れ替えれる手段としてGAME言語の環境では次の二通りが考えられます。
  1. GAMEコンパイラでの対応
     GAME言語のコンパイラで乗算処理時にコールするアドレスをアセンブラで作った処理のアドレス(今回は 8500H)に変更してコンパイルすることで生成された実行プログラムは固定小数点の乗算処理をコールするようになります。

  2. インタープリタ内処理のフック
     GAME言語のコンパイラのソースからも判るようにGAME80の乗算処理は 8A0FH にあります。この部分をアセンブラで作った処理へのジャンプ命令に置き換えれば、固定小数点の乗算を行うことができます。

 最も悩ましいのは固定小数のフォーマットとして整数部と小数点部にそれぞれ何ビットを割り振るかです。滑らかな描画にするためには小数点部分のビット数をなるべく多くしたいものです。特にマンデルブロの周辺に広がっている楕円形はスムーズに描きたいですね。

 試行錯誤の結果下記のようにしました。
  • asciiart処理内の最大値
     主要な変数の値を確認したところ 37 程度の大きさの変数がありました。最小限のマージンで整数部には6ビット必要で符号の1ビットを加えると整数部で最小でも7ビット必要になります。

  • 処理中のオーバーフロー
     オーバーフローのために描画させたマンデルブロ図が変になるので X,Y のステップ範囲を元々の処理の 1/2 にし、ステップ幅も同様に 1/2 の 0.5 にしました。
    ★追記 2023/01/05 オリジナルのものと同じ値に戻しました。

  • 小数点部分
     上記から必然的に小数点に割り振れるビット数は9ビットになります。ネット上で見かける固定小数点のマンデルブロプログラムの小数点は 50~64 位なので9ビット(512)であればより詳細に描けるのではないかと期待が膨らみます^^

 結果として 整数部:7ビット、小数点部:9ビット 整数部:8ビット、小数点部:8ビット にしました。(★変更 2023/01/05)

 アセンブラで書いた固定小数点の処理を貼っておきます。高速化を意識して作りましたがまだギリギリまで詰めてはいません。

★追記 2023/01/05 {
 固定小数点のループ処理でH,Lそれぞれを右シフトしていましたがシフト方向を左側に変更し、ADD HL,HLを使用することで高速化しました。
 また、asciiart の実行時間は描画条件により大きく変動するのでX,Yの範囲やステップ幅等をオリジナルのものと同様にし、固定小数点の整数部のビット数を7ビットから8ビットに変更しました。更にキャリー処理部を修正し、マンデルブロ図のノイズの様なものも無くなりました。
 これに伴いマンデルブロ図がオリジナルのものと更に近くなりました。ソース及び図も最新のものと差し換えました。
}

固定小数点乗算処理(ビット長:16[8.8]ビット)(Z80 アセンブラ)
;++++++++++++++++++++++++++++++++++ ; fixed point caliculater ; format : 7bit.9bit MSB:sign ; Ver 0.01 2023/01/03 skyriver ; Ver 0.02 2023/01/04 skyriver ; Ver 0.03e 2023/01/05 skyriver ; Ver 0.03g 2023/05/05 skyriver ;++++++++++++++++++++++++++++++++++ 8500 TOPADR EQU 08500H 0000' ASEG ORG TOPADR ; HL,DE <- value ; DE -> result:HL*DE 8500 01 0F01 Mul: LD BC,15*256 + 1 8503 CB 7C BIT 7,H 8505 28 07 JR Z,Mul10 8507 0C INC C 8508 AF XOR A 8509 95 SUB L 850A 6F LD L,A 850B 9F SBC A,A 850C 94 SUB H 850D 67 LD H,A 850E EB Mul10: EX DE,HL 850F 29 ADD HL,HL 8510 30 07 JR NC,Mul20 8512 0C INC C 8513 AF XOR A 8514 95 SUB L 8515 6F LD L,A 8516 9F SBC A,A 8517 94 SUB H 8518 67 LD H,A 8519 CB 19 Mul20: RR C ; Cy 0:negative 851B 08 EX AF,AF' 851C 4C LD C,H 851D 7D LD A,L 851E 21 0000 LD HL,0 8521 MulLoop: 8521 29 ADD HL,HL 8522 17 RLA 8523 CB 11 RL C 8525 30 03 JR NC,MulL10 8527 19 ADD HL,DE 8528 CE 00 ADC A,0 852A 10 F5 MulL10: DJNZ MulLoop 852C 57 LD D,A 852D 5C LD E,H 852E 08 EX AF,AF' 852F D8 RET C 8530 AF XOR A 8531 93 SUB E 8532 5F LD E,A 8533 9F SBC A,A 8534 92 SUB D 8535 57 LD D,A 8536 C9 RET END Macros: Symbols: 8500 MUL 850E MUL10 8519 MUL20 852A MULL10 8521 MULLOOP 8500 TOPADR No Fatal error(s)
★変更 2023/05/05 若干高速化、上記の実行時間には未反映


 今回の固定小数点用に変更した asciiart のソースが下記になります。

固定小数点用アスキーアート(GAME言語)
10 Y=$F400,$0C00 20 X=$D900,$2700 29' 0.0458 30 C=X*$000B 39' 0.08333 40 D=Y*$0015 50 A=C 60 B=D 70 I=0,15 80 T=(A+B)*(A-B)+C 90 B=$0200*A*B+D 100 A=T 110 ;=(A*A+(B*B))>$0400 #=200 120 @=I+1 130 " " 140 #=210 200 ;=I>9 I=I+7 205 $=48+I I=15 @=I+1 210 @=X+$0100 220 / 230 @=Y+$0100


 下図は上記の2番目の手法であるインタープリタ内処理をフックして実行した場合の画面キャプチャになります。周辺の輪も奇麗に描かれていますね^^
 実行時間を 0.1 秒単位で計測する TeraTerm マクロも新規に作成しました。

固定小数点アスキーアート画面(GAMEインタープリタ)


★追記 2023/01/05 {
 GAME言語コンパイラ環境での実行画面のキャプチャーを追記しました。

固定小数点アスキーアート画面(GAMEコンパイラ)
}

★追記 2023/01/05 {
 全てアセンブラで記述したプログラムの実行時のキャプチャーを追記しました。

固定小数点アスキーアート画面(フルアセンブラ)
 CP/M 用の超高速 asciiart 表示プログラム(Z80用)も置いておきます。
★Ver0.02 22023/01/17 精度を少し上げ、オリジナルの形状により近くなりました。
}

 上記画面で使用した TeraTerm 用の実行時間計測マクロ(0.1秒単位で計測可能)は BASIC、CP/M、GAME言語等に対応しています。下記からダウンロード可能です(商用用途以外であれば使用可能)。


 Twitterにアップした動画付きコメントも貼っておきます。(Z80:16MHzは誤記で12MHzで動作しています)



★追記 2023/01/09 {
 Twitter へのメッセージ投稿後、早い段階で西さんから”いいね”を頂いた MSXPen での asciiart 描画動画を上げたメッセージを貼っておきます。西さんから”いいね”を頂くのは「Z80での1バイトのビット順反転処理」の記事を書いた時に投稿したメッセージ以来、2回目だと思います。

}


[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(0) 
共通テーマ:趣味・カルチャー

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。