SSブログ
English Version

超小型Z80マイコン(その11)動作モニタ用LEDの実装 [Z80]

 前回の記事で書いた汎用基板を使いポリウレタン線で結線した開発用基板は順調に動くようになりました(末尾に状況を書いた Twitter のメッセージを貼っておきます)。

 手軽に CP/M も起動できるので色々遊んで見ると SD カード(以降 TF カードと記す)のアクセス中等の状態を示す LED が無いとコンパイル中等に動いているのか不安になります。
 今回の3チップ構成の Z80PicCompact の開発では小型化のために 20 ピンの PIC を使用しており、I/O 数が圧倒的に足りないため一つの I/O で複数の制御を行っています(具体的なピンアサインはこの連載の最初のページを参照してください)。
 TF カード イネーブル信号を割り振った I/O ビットには Z80 への WAIT/ 出力及び IORQ/ 読込みの機能の合計で三つの機能を割り振っていて、キー入力時にもアクティブになるので状態表示用の LED 制御には使えません。

 色々考えた結果、TF カードとのインターフェースである SPI のクロック信号が low の時に LED を点灯することにしました。クロック信号に割り振った I/O ビットは Z80 の A0 信号の読込みと兼用していますがソフトで何とかするようにします。

 結果としてハードウェア的には下図のトランジスタ回路を追加することにしました。low でオンなので珍しく PNP 型トランジスタを使用しています。

モニタ LED 用に追加した回路


 汎用基板で作った開発用基板はブレッドボードより安定していていいのですが部品交換が面倒です。リード部品をメインに使っていましたが、今回はSMD部品を使いました(部品交換等はSMDの方がやり易いですね)。

開発用基板への部品追加例


 これで TF カードアクセス時には点灯し、キー入力待ちの時(待機状態)では消灯する動作確認用 LED を追加することが出来ました。コンソール出力時等でも薄っすら点灯しますが動作モニタと言う観点では問題無い(寧ろ好都合)と思います。動作確認用 LED 実装後の開発用基板が下図になります。

モニタ用 LED 実装後の開発用基板


 下図が今回の追加を反映したグランドベタ化前のパターン図になります。緑色の部分はグランドです。段々込み合ってきてこれ以上の部品の追加が難しくなってきました。

モニタ用 LED 実装後のパターン(グランドベタ化前)


 グランドベタ化後のトップ面のパターンが下図になります。左下に追加した LED と従来からある電源表示用の LED が並んでいます。

モニタ用 LED 実装後のトップ面


 下図はボトム面のパターンで左端に追加したトランジスタ等を配置しました。ロゴマークを入れる場所もかろうじて確保できました。

モニタ用 LED 実装後のボトム面


 パターンの更新ができたので製造依頼しました。回路 CAD(DesignSpakPCB)での3D表示画面のキャプチャも貼っておきます。トップ面にはほぼ同サイズの Z80 のチップが実装されます。

3D表示(トップ面)


3D表示(ボトム面)



 [ Twitter にポストした開発状況に関するメッセージ]





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

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

ポケコン(G850)用拡張基板(その9)コンパクト化 [ポケコン]

 ポケコン(PC-G850V)の LCD で BadApple の動画表示をした前回の記事からだいぶ時間が経ってしまいましたが、今までのメモリ拡張ボード(Eborsy)に付けていた動作確認用のピンソケットは削除して実装するメモリと GAL を表面実装タイプのもの(動作確認済みなので GAL はソケット無しで直付け予定)にして小型化してみました。名称も Eborsy Compact と呼ぶことにします。

 グランドベタ化前のパターン図が下図になります。小型化のためメモリと GAL のチップを表裏で同じ位置にしたため、パターン作成に結構時間が掛かりました。緑色の部分はグランド部分で細い斜め線の部分はグランドベタ化により接続されます。

PC-G860V用増設ボード(Eborsy)パターン図(グランドベタ化前)


 下図がグランベタ化後のトップ面でコネクタとメモリが実装されています。トップ面と言ってもポケコンに付けた際は内側になり実質的には裏面になります。バージョンやロゴマークは逆の面には適当なスペースを確保できなかったのでこちらの面に書いています。

PC-G860V用増設ボード(Eborsy)パターン図(トップ面)


 下図がボトム面のパターンです。TF カードコネクタと GAL を実装しています。上記のようにポケコンに実装した際はこちらが表面になるので電源とアクセス表示の LED もこちらの面に実装しました。

PC-G860V用増設ボード(Eborsy)パターン図(ボトム面)


 下図は設計 CAD (DesignSparkPCB)で3D表示した画面のキャプチャです。下側の茶色の直方体がポケコンに接続するコネクタなのでコンパクトにまとめられたことが確認できます。

PC-G860V用増設ボード(Eborsy)3D表示(トップ面)


 下図がボトム面(ポケコン実装時は表面)の3D表示です。シルク面を上側に設定していますが3D表示ではレジストに隠れてしまいますね^^;
 レイヤーの順番を弄れば表示できたはずですが面倒なのでパターン設計時のままで表示しています。

PC-G860V用増設ボード(Eborsy)3D表示(ボトム面)


 もう少し確認後に製造依頼したいと思います。


★追記 2024/07/23
 「ポケコン(G850)用拡張ボード(EborsyEEP)でCP/M(その7)改善基板到着」の記事に SD カードの代わりに EEPROM を使用し、更に小型化したプリント基板について記載しました。


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

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

CP/Mコマンドにおける小文字パラメータの実現 [Z80]

 CP/M-80(以降、CP/M と記す) でコマンドのパラメータに小文字を入力しても強制的に大文字に変換されます。このため PC から CP/M へシリアル通信等で転送したアーカイブファイルを解凍した場合等に小文字のファイル名があると ERA コマンドでは消せなくなってしまいます(今まで MBASIC を起動して KILL コマンドで消していた^^;)
 また、grep のようなファイルの内容を参照するようなコマンドを作成する場合、コマンドパラメータで対象文字列として小文字を指定できず不便でした。

 CP/M でコマンドパラメータに小文字が使えないのは「入力されたコマンドを処理する CCP(Console Command Processor) 内の1行入力処理部で小文字を大文字に変換している」ためです。

 そこで CCP の1行入力処理内の大文字変換部にパッチを当て一時的に小文字の入力を可能にするコマンドを作ってみました。注意点として CCP はコマンド解析を大文字前提で行っているのでコマンド自体は大文字で入力する必要があります。
 また、このパッチは外部プログラムのみならず ERA 等のビルトインコマンドにも有効になるので上記のような小文字のファイル名の削除も可能になります。上記で”一時的”と書いたのは、コントロールC押下または実行したプログラムの終了時に WBOOT が実行されると CCP が再度読み込まれてパッチが消えてしまうからです(なのでパッチを元に戻すコマンドは準備していません)。

 実行例を下図に示します。argtest は実行時に与えられたパラメータを表示するだけのテスト用プログラムです。

小文字パラメータコマンドの実行例


 リストも貼っておきます。0080H に保存されている起動時のパラメータ文字列の長さがゼロ以外の場合、ヘルプ内容を表示するようにしました。

CP/Mー80 用の小文字パラメータ対応コマンドリスト(Z80 アセンブラ)
;********************************************************* ; patch to allow lowercase command parameter for CP/M-80 ; Ver 0.01 2023/01/20 by skyriver ; Ver 0.01a 2023/01/20 by skyriver ; Compatible with 8080 ; 64K CP/M sample ; E5B1 7E MOV A,M ;convert to upper case. ; E5B2 CD30E5 CALL UPPER ; E5B5 77 MOV M,A <- change to NOP ; ;********************************************************* 000D CR EQU 13 000A LF EQU 10 0005 BDOS EQU 0005H ; BDOS call adrress 0080 ARGBUF EQU 0080H ; command argment save area 0000' ASEG ORG 0100H 0100 3A 0080 START: LD A,(ARGBUF) ; get argment length 0103 B7 OR A 0104 C2 0147 JP NZ,DispHlp 0107 3A 0007 LD A,(BDOS + 2) ; get high addr of BDOS entry 010A D6 07 SUB 07H 010C 57 LD D,A 010D 1E 00 LD E,0 010F 06 00 LD B,0 ; counter 0111 21 0154 LD HL,PATCH ; patch data pointer 0114 E5 LOOP: PUSH HL 0115 D5 PUSH DE 0116 7E LOOP10: LD A,(HL) 0117 23 INC HL 0118 FE FE CP 0FEH 011A CA 013A JP Z,FIND 011D FE FF CP 0FFH 011F CA 0128 JP Z,MATCH 0122 EB EX DE,HL 0123 BE CP (HL) 0124 EB EX DE,HL 0125 C2 012C JP NZ,NEXT 0128 13 MATCH: INC DE 0129 C3 0116 JP LOOP10 012C D1 NEXT: POP DE 012D E1 POP HL 012E 13 INC DE 012F 05 DEC B 0130 C2 0114 JP NZ,LOOP 0133 11 0197 LD DE,MsgNg 0136 CD 014E CALL PUTS 0139 C9 RET 013A EB FIND: EX DE,HL 013B 2B DEC HL 013C 36 00 LD (HL),00H ; change nop 013E 11 015A LD DE,MsgOk 0141 CD 014E CALL PUTS 0144 E1 POP HL 0145 D1 POP DE 0146 C9 RET 0147 DispHlp: 0147 11 01A7 LD DE,MsgHlp 014A CD 014E CALL PUTS 014D C9 RET 014E 0E 09 PUTS: LD C,9 0150 CD 0005 CALL BDOS 0153 C9 RET 0154 7E CD 30 FF PATCH: DB 07EH, 0CDH, 030H, 0FFH, 077H, 0FEH 0158 77 FE 015A 20 50 61 74 MsgOk: DB " Patch success! Please enter the command in capital letters.$" 015E 63 68 20 73 0162 75 63 63 65 0166 73 73 21 20 016A 50 6C 65 61 016E 73 65 20 65 0172 6E 74 65 72 0176 20 74 68 65 017A 20 63 6F 6D 017E 6D 61 6E 64 0182 20 69 6E 20 0186 63 61 70 69 018A 74 61 6C 20 018E 6C 65 74 74 0192 65 72 73 2E 0196 24 0197 20 46 61 69 MsgNg: DB " Fail to patch.$" 019B 6C 20 74 6F 019F 20 70 61 74 01A3 63 68 2E 24 01A7 75 73 61 67 MsgHlp: DB "usage : smallarg",CR,LF 01AB 65 20 3A 20 01AF 73 6D 61 6C 01B3 6C 61 72 67 01B7 0D 0A 01B9 20 20 20 54 DB " This command allows lowercase command parameter.",CR,LF 01BD 68 69 73 20 01C1 63 6F 6D 6D 01C5 61 6E 64 20 01C9 61 6C 6C 6F 01CD 77 73 20 6C 01D1 6F 77 65 72 01D5 63 61 73 65 01D9 20 63 6F 6D 01DD 6D 61 6E 64 01E1 20 70 61 72 01E5 61 6D 65 74 01E9 65 72 2E 0D 01ED 0A 01EE 20 20 20 45 DB " Enter the command in capital letters after execution.",CR,LF 01F2 6E 74 65 72 01F6 20 74 68 65 01FA 20 63 6F 6D 01FE 6D 61 6E 64 0202 20 69 6E 20 0206 63 61 70 69 020A 74 61 6C 20 020E 6C 65 74 74 0212 65 72 73 20 0216 61 66 74 65 021A 72 20 65 78 021E 65 63 75 74 0222 69 6F 6E 2E 0226 0D 0A 0228 20 20 20 52 DB " Return to original after wboot(pushed ^C or program finished).",CR,LF 022C 65 74 75 72 0230 6E 20 74 6F 0234 20 6F 72 69 0238 67 69 6E 61 023C 6C 20 61 66 0240 74 65 72 20 0244 77 62 6F 6F 0248 74 28 70 75 024C 73 68 65 64 0250 20 5E 43 20 0254 6F 72 20 70 0258 72 6F 67 72 025C 61 6D 20 66 0260 69 6E 69 73 0264 68 65 64 29 0268 2E 0D 0A 026B 20 20 20 20 DB " Ver 0.01a 2023/01/20 by skyriver$" 026F 20 20 20 56 0273 65 72 20 30 0277 2E 30 31 61 027B 20 32 30 32 027F 33 2F 30 31 0283 2F 32 30 20 0287 62 79 20 73 028B 6B 79 72 69 028F 76 65 72 24 END Macros: Symbols: 0080 ARGBUF 0005 BDOS 000D CR 0147 DISPHLP 013A FIND 000A LF 0114 LOOP 0116 LOOP10 0128 MATCH 01A7 MSGHLP 0197 MSGNG 015A MSGOK 012C NEXT 0154 PATCH 014E PUTS 0100 START No Fatal error(s)


 今回作成したコマンドは下記のリンクからダウンロードできます。
[history]
Ver 0.01a 2023/01/20 8080対応


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

GAME言語で 3DHAT の高速描画 [Z80]

 Z80 アセンブラで作成した 16 ビットの固定小数の乗算演算処理を使って asciiart を高速に描画できたことを「GAME言語での ASCIIART の高速化」の記事で書きました。

 GAME言語コンパイラはGAME言語自身で記述されているので固定小数点のような新たな演算子の追加も割合楽にできます。
 上記の記事では固定小数点の乗算のみを追加しましたが、今回はコンパイラに下記の演算子を追加して3DHATを高速に描いてみたいと思います。
 尚、3DHATのプログラムは「Pic24MC68Kマイコン(その9)ehBASICの移植」の記事にアップしたものを今回の拡張GAMEコンパイラ(以降、拡張コンパイラと記す)用に移植します。

No演算子記号種別実装方法演算内容
1x2項演算子アセンブラ固定小数点の乗算
2¥s単項演算子アセンブラSIN(引数:固定小数点(90°=1))
3¥c単項演算子アセンブラCOS(引数: 同上 )
4¥r単項演算子アセンブラ平方根(引数:固定小数点)
5¥f単項演算子コンパイラ整数から固定小数点への変換
6¥i単項演算子コンパイラ固定小数点から整数への変換
7&2項演算子コンパイラAND 演算
8|2項演算子コンパイラOR 演算
9<<2項演算子コンパイラ左シフト
10>>2項演算子コンパイラ算術右シフト
    ※:コンパイラ内に Z80 のマシン語への変換ロジックを実装


 No.1 の固定小数点の乗算記号を '*' としなかったのは従来の整数演算も並行して使用したかったからです。BASCI 言語等でも整数と浮動小数点を同時に使えますが、こうしないと既存のプログラムの移植の際等に非常に不便であることが今回身に染みて判りました。
 No.7 までは今回移植する3DHATを動かす上で必要なものですが No.8 以降はついでに付加したものです。

 No.2 と No.3 の三角関数は速度優先で 0 .. pai/2 区間の SIN の値からなる 256 バイトのテーブルから値を引くようにしました。今回の固定小数点では 0x0100 が1の値なのですが、256 は1バイトに収まらないので テーブル先頭の唯一の 0 は参照しないようにして 角度が pai/2 の整数倍の時は -1,0,1 のいずれかを判断して返す様にすることでテーブル内のゼロを 256 と見なすようにしました。

 No.4 の平方根は Twitter で見かけた下記の処理手法を Z80 アセンブラで記述しました。



 アセンブラのソースも貼っておきます。乗算処理のメインループのステップ数はこれ以上短くならないのではないかと思います。

今回作成した固定小数点演算処理(乗算、平方根、SIN/COS)
;++++++++++++++++++++++++++++++++++ ; calcurate Fixed point[8.8] sin ; Ver 0.01 2023/01/06 skyriver ; Ver 0.02 2023/01/12 skyriver ; Ver 0.02b 2023/01/15 skyriver ; Ver 0.03 2023/05/05 skyriver ;++++++++++++++++++++++++++++++++++ 0000' ASEG ORG 8400H 8400 C3 8443 JP SIN 8403 C3 8442 JP COS 8406 C3 8470 JP SQRT ; HL,DE <- value ; DE -> result:HL*DE 8409 01 0F01 Mul: LD BC,15*256 + 1 840C CB 7C BIT 7,H 840E 28 07 JR Z,Mul10 8410 0C INC C 8411 AF XOR A 8412 95 SUB L 8413 6F LD L,A 8414 9F SBC A,A 8415 94 SUB H 8416 67 LD H,A 8417 EB Mul10: EX DE,HL 8418 29 ADD HL,HL 8419 30 07 JR NC,Mul20 841B 0C INC C 841C AF XOR A 841D 95 SUB L 841E 6F LD L,A 841F 9F SBC A,A 8420 94 SUB H 8421 67 LD H,A 8422 CB 19 Mul20: RR C ; Cy 0:negative 8424 08 EX AF,AF' 8425 4C LD C,H 8426 7D LD A,L 8427 21 0000 LD HL,0 842A MulLoop: 842A 29 ADD HL,HL 842B 17 RLA 842C CB 11 RL C 842E 30 03 JR NC,MulL10 8430 19 ADD HL,DE 8431 CE 00 ADC A,0 8433 10 F5 MulL10: DJNZ MulLoop 8435 57 LD D,A 8436 5C LD E,H 8437 08 EX AF,AF' 8438 D8 RET C 8439 AF XOR A 843A 93 SUB E 843B 5F LD E,A 843C 9F SBC A,A 843D 92 SUB D 843E 57 LD D,A 843F C9 RET ; cos ; DE <- 256:90deg ; DE -> SIN value 8440 14 COS: INC D ; go through to SIN ; sin ; DE <- 256:90deg ; DE -> SIN value 8441 7B SIN: LD A,E 8442 B7 OR A 8443 C2 8452 JP NZ,SIN10 8446 CB 1A RR D 8448 17 RLA ; A:0 8449 CB 1A RR D 844B D2 8450 JP NC,SIN02 844E ED 44 NEG 8450 57 SIN02: LD D,A ; orgD:D = 00:00, 01:01, 02:00, 03:FF 8451 C9 RET 8452 CB 42 SIN10: BIT 0,D 8454 28 02 JR Z,SIN20 8456 ED 44 NEG 8458 6F SIN20: LD L,A 8459 26 85 LD H,HIGH SINTAB 845B 5E LD E,(HL) 845C 26 00 LD H,0 845E 1C INC E 845F 1D DEC E 8460 20 01 JR NZ,SIN30 8462 24 INC H 8463 CB 4A SIN30: BIT 1,D 8465 54 LD D,H 8466 C8 RET Z 8467 AF XOR A 8468 93 SUB E 8469 5F LD E,A 846A 9F SBC A,A 846B 92 SUB D 846C 57 LD D,A 846D C9 RET ; sqrt ; DE <- data:fixed8.8 ; DE -> result:fixed8.8 846E 21 0000 SQRT: LD HL,0 ; ans = 0 8471 01 8000 LD BC,08000H ; for( bit=4000H; bit; bit >>= 2 ) { 8474 CB 38 SQRFOR: SRL B 8476 CB 19 RR C 8478 CB 3C SRL H ; ans >>= 1 847A CB 1D RR L 847C E5 PUSH HL 847D 29 ADD HL,HL ; if( n >= ( tmp = (ans << 1) | bit ) ) { 847E 09 ADD HL,BC 847F D5 PUSH DE 8480 EB EX DE,HL ;; OR A ; already Cy:0 8481 ED 52 SBC HL,DE ; HL:n, DE:tmp 8483 D1 POP DE ; DE:n 8484 38 04 JR C,SQR10 8486 EB EX DE,HL ; n -= tmp 8487 E1 POP HL 8488 09 ADD HL,BC ; ans |= bit; 8489 FE DB 0FEH ; } skip POP 848A E1 SQR10: POP HL 848B CB 38 SRL B 848D CB 19 RR C 848F D2 8474 JP NC,SQRFOR ; } 8492 29 ADD HL,HL ; convert fixed point 8.8 8493 29 ADD HL,HL 8494 29 ADD HL,HL 8495 29 ADD HL,HL 8496 EB EX DE,HL 8497 C9 RET ORG ( $ + 255 ) AND 0FF00H 8500 00 02 03 05 SINTAB: DB 0, 2, 3, 5, 6, 8, 9, 11 8504 06 08 09 0B 8508 0D 0E 10 11 DB 13, 14, 16, 17, 19, 20, 22, 24 850C 13 14 16 18 8510 19 1B 1C 1E DB 25, 27, 28, 30, 31, 33, 34, 36 8514 1F 21 22 24 8518 26 27 29 2A DB 38, 39, 41, 42, 44, 45, 47, 48 851C 2C 2D 2F 30 8520 32 33 35 37 DB 50, 51, 53, 55, 56, 58, 59, 61 8524 38 3A 3B 3D 8528 3E 40 41 43 DB 62, 64, 65, 67, 68, 70, 71, 73 852C 44 46 47 49 8530 4A 4C 4D 4F DB 74, 76, 77, 79, 80, 82, 83, 85 8534 50 52 53 55 8538 56 58 59 5B DB 86, 88, 89, 91, 92, 94, 95, 97 853C 5C 5E 5F 61 8540 62 63 65 66 DB 98, 99, 101,102, 104, 105, 107, 108 8544 68 69 6B 6C 8548 6D 6F 70 72 DB 109, 111, 112, 114, 115, 117, 118, 119 854C 73 75 76 77 8550 79 7A 7B 7D DB 121, 122, 123, 125, 126, 128, 129, 130 8554 7E 80 81 82 8558 84 85 86 88 DB 132, 133, 134, 136, 137, 138, 140, 141 855C 89 8A 8C 8D 8560 8E 90 91 92 DB 142, 144, 145, 146, 147, 149, 150, 151 8564 93 95 96 97 8568 98 9A 9B 9C DB 152, 154, 155, 156, 157, 159, 160, 161 856C 9D 9F A0 A1 8570 A2 A4 A5 A6 DB 162, 164, 165, 166, 167, 168, 170, 171 8574 A7 A8 AA AB 8578 AC AD AE AF DB 172, 173, 174, 175, 177, 178, 179, 180 857C B1 B2 B3 B4 8580 B5 B6 B7 B8 DB 181, 182, 183, 184, 185, 186, 188, 189 8584 B9 BA BC BD 8588 BE BF C0 C1 DB 190, 191, 192, 193, 194, 195, 196, 197 858C C2 C3 C4 C5 8590 C6 C7 C8 C9 DB 198, 199, 200, 201, 202, 203, 204, 205 8594 CA CB CC CD 8598 CE CF CF D0 DB 206, 207, 207, 208, 209, 210, 211, 212 859C D1 D2 D3 D4 85A0 D5 D6 D7 D7 DB 213, 214, 215, 215, 216, 217, 218, 219 85A4 D8 D9 DA DB 85A8 DC DC DD DE DB 220, 220, 221, 222, 223, 224, 224, 225 85AC DF E0 E0 E1 85B0 E2 E3 E3 E4 DB 226, 227, 227, 228, 229, 229, 230, 231 85B4 E5 E5 E6 E7 85B8 E7 E8 E9 E9 DB 231, 232, 233, 233, 234, 235, 235, 236 85BC EA EB EB EC 85C0 ED ED EE EE DB 237, 237, 238, 238, 239, 239, 240, 241 85C4 EF EF F0 F1 85C8 F1 F2 F2 F3 DB 241, 242, 242, 243, 243, 244, 244, 245 85CC F3 F4 F4 F5 85D0 F5 F5 F6 F6 DB 245, 245, 246, 246, 247, 247, 248, 248 85D4 F7 F7 F8 F8 85D8 F8 F9 F9 F9 DB 248, 249, 249, 249, 250, 250, 250, 251 85DC FA FA FA FB 85E0 FB FB FC FC DB 251, 251, 252, 252, 252, 252, 253, 253 85E4 FC FC FD FD 85E8 FD FD FE FE DB 253, 253, 254, 254, 254, 254, 254, 255 85EC FE FE FE FF ; DB 255, 255, 255, 255, 255, 255, 256, 256 ; DB 256, 256, 256, 256, 256, 256, 256, 256 85F0 FF FF FF FF DB 255, 255, 255, 255, 255, 255, 0, 0 85F4 FF FF 00 00 85F8 00 00 00 00 DB 0, 0, 0, 0, 0, 0, 0, 0 85FC 00 00 00 00 END Macros: Symbols: 8442 COS 8409 MUL 8418 MUL10 8424 MUL20 8435 MULL10 842C MULLOOP 8443 SIN 8452 SIN02 8454 SIN10 845A SIN20 8465 SIN30 8500 SINTAB 848C SQR10 8476 SQRFOR 8470 SQRT No Fatal error(s)

[history]
・Ver0.02b 2023/01/15 improve srqt a little
・Ver0.03 2023/05/05 improve Mul


 3DHATを描画するGAME言語のソースは下記になります。元々が記号言語なので読み辛いとは思いますが、全てをアセンブラで記述するよりは効率的に記述できるのではないかと思います。

3DHat描画ソース(拡張GAME言語)
10' ** 3D graphic with teraterm 20'GOSUB 1000:REM TEKCLS 21 !=1000 30'X1=2:GOSUB 1100:REM TEKCOLOR(2) 31 G=2 !=1100 40'DIM D(1,255):FOR L=0 TO 255:D(0,L)=-1:D(1,L)=-1:NEXT 41 D=&+1 L=0,255 D(L)=-1 D(L+256)=-1 @=L+1 60'FOR Y=-180 TO 180 STEP 4:FOR X=-180 TO 180 STEP 4 61'-10,10 62 YF=$F600,$0A00 XF=$F600,$0A00 80'R=PI/180*SQR(X*X+Y*Y):Z=100*COS(R)-30*COS(3*R) 81 RF=¥r(XFxXF+(YFxYF))x$0033 83 T=$1E00x¥c($0300xRF) 84 Z=¥i($6400x¥c(RF)-T) 100'V=INT(116+X/2+(16-Y/2)/2):W=INT((130-Y/2-Z)/2) 101' TF=YFx$0400 V=\i($0800xXF-TF)+124 102 TF=YF<<2 V=\i(XF<<3-TF)+124 103 W=65-(Z>>1)-¥iTF 104 T=V+256 120'IF (V<0)+(V>255) THEN GOTO 160 121 ;=(V<0)+(V>255) #=160 130'IF D(0,V)=-1 THEN GOTO 500 131 ;=D(V)=-1#=500 140'IF W<=D(0,V) THEN GOTO 700 141 ;=W<=D(V) #=700 150'IF W>=D(1,V) THEN GOTO 800 151 ;=W>=D(T) #=800 160'NEXT X:NEXT Y:END 161 @=XF+$0040 @=YF+$0040 #=-1 500'IF V=0 THEN GOTO 600 501 ;=V=0 #=600 510'IF D(0,V-1)=-1 THEN GOTO 600 511 ;=D(V-1)=-1 #=600 520'IF D(0,V+1)=-1 THEN GOTO 600 521 ;=D(V+1)=-1 #=600 530'D(0,V)=INT((D(0,V-1)+D(0,V+1))/2) 531 D(V)=(D(V-1)+D(V+1))>>1 540'D(1,V)=INT((D(1,V-1)+D(1,V+1))/2) 541 D(T)=(D(T-1)+D(T+1))>>1 550'GOSUB 900:GOTO 160 551 !=900 #=160 600'D(0,V)=W:D(1,V)=W:GOSUB 900:GOTO 160 601 D(V)=W D(T)=W !=900 #=160 700'GOSUB 900:D(0,V)=W:IF D(1,V)=-1 THEN D(1,V)=W 701 !=900 D(V)=W ;=D(T)=-1 D(T)=W 710'GOTO 160 711 #=160 800'GOSUB 900:D(1,V)=W:IF D(0,V)=-1 THEN D(0,V)=W 801 !=900 D(T)=W ;=D(V)=-1 D(V)=W 810'GOTO 160 811 #=160 900'X1=V*3.5+30:Y1=600-W*3.5:GOSUB 2100:RETURN 901 G=V<<2-(V>>1)+30 902 H=W>>1-(W<<2)+600 903 !=2100 ] 999' TEKCLS 1000'PRINT CHR$($1B);CHR$($0C);CHR$($0D);CHR$($0A);:RETURN 1001 $=$1B $=$0C $=$0D $=$0A ] 1100' TEKCOLOR(X) 1110'PRINT CHR$($1B);CHR$($5B);CHR$($33);CHR$($30+X1);CHR$($6D);:RETURN 1111 $=$1B $=$5B $=$33 $=G+$30 $=$6D ] 2100'REM TEKDOT(X1,Y1) 2110'PRINT CHR$($1D); 2111 $=$1D 2120'PRINT CHR$($20+(Y1/32 AND $1F));CHR$($60+(Y1 AND $1F)); 2121 $=H>>5&$1F+$20 $=H&$1F+$60 2140'PRINT CHR$($20+(X1/32 AND $1F));CHR$($40+(X1 AND $1F)); 2141 $=G>>5&$1F+$20 $=G&$1F+$40 2160'PRINT CHR$($20+(Y1/32 AND $1F));CHR$($60+(Y1 AND $1F)); 2161 $=H>>5&$1F+$20 $=H&$1F+$60 2180'PRINT CHR$($20+(X1/32 AND $1F));CHR$($40+(X1 AND $1F));:RETURN 2181 $=G>>5&$1F+$20 $=G&$1F+$40 ]


 GAMEコンパイラでコンパイル後に実行した画面のキャプチャーが下図になります。冒頭で紹介した「ehBASICの移植の記事」の記事で書いたように TeraTerm のテクトロ端末機能(TEKウィンド)を使ってグラフィック描画しています。描画に掛かった時間は開発中の Z80PicCompact(Z80 12MHz)で 8s 程度でした。
★変更 2023/01/09 16s から 14s に変更。STEP幅が大きかったので元版に合わせ 14s から 9s に変更
★変更 2023/01/11 乗算の一部をシフトに変更して 9s から 8s に変更


 16 ビットの固定小数点では精度不足で若干ガタガタしている部分がありますが「ehBASICの移植の記事」で書いたように MC68K 16MHz での描画時間が 2 分 34 秒なので今回作成したものはメチャ速いことが判ります。

 もう少し精度を上げたいところですが、現状でも処理の一部で MSB まで桁あふれした値を MSB まで対応している 平方根処理で固定小数点の範囲内に戻しているので 16 ビットでのほぼ限界に近い処理になっているのではないかと思います。

3DHAT描画画面


 最後に今回機能追加した拡張GAMEGAMEコンパイラ(GAME80用)も貼っておきます。



★追記 2023/01/09 {
 Twitter に投稿した動画付きメッセージを貼っておきます。動画にすると描画のドットの色が薄くて全画面表示にしないと殆ど見えないですね ^^;;

}


★追記 2023/01/10 {
 MSX に移植して MSXPen で実行した際に投稿した動画付きの Twitter コメントも貼っておきます。
 グラフィックはオーバーヘッドが少なそうな Graphics7(256x192 in 256 colors)を使っています。

}

★追記 2023/04/20
 MSX 用 3DHat の実行ファイルは下記からダウンロードできます。


★追記 2024/07/03
 X(旧Twitter)に投稿した更に高速化した動画を貼っておきます。全体をアセンブリ言語化し、MSXturboRに搭載されているR800の符号無し16bit乗算命令を利用するように変更しています。



★追記 2024/01/29
 MZ-2200 のエミュレータである EmyuZ-2200 を弄る機会があり関連資料を見ていたところ、MZ 系の CM ではお馴染みの3Dハットを表示中の画面の写真を見つけました。
 本家の MZ のエミュで固定小数点+拡張 GAME コンパイラによる高速3Dハット描画を試したところ、CPU クロック 6MHz の設定で描画時間は約 20 秒でした。

EmyuZ-2200 での3Dハット描画画面

★追記 2024/01/30
 MZ-2200 用の 3DHat 描画プログラム( MZT ファイル)は下記URLからダウンロードできます。
[History]
2023/02/03 Ver 2 若干高速化(描画時間は6MHzで約12秒)



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

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

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回目だと思います。

}


★追記 2024/08/04
 「GAME言語で 3DHAT の高速描画」の記事にGAME 言語のコンパイラに固定小数点演算を追加して3DHATを高速に描画する試みについて記載しました。



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

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