標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第655回]
●ルート計算プログラム(TK−80応用プログラム)(その2)
ND80ZV組立キットをご購入いただいた北海道のM様から、TK−80応用プログラムを送っていただきました。
01〜99の範囲の整数のみですが、ルート(平方根)を求めるプログラムです。
前回はそのマシン語プログラムの16進コードをお見せしました。
戻って見ていただくのも面倒なことと思いますので下に再掲いたします。
>dm 8000,80b5 8000 06 0A 21 AC 82 AF 77 23-05 C2 06 80 CD 16 02 07 ..!ャ.ッw#.ツ..ヘ... 8010 07 07 07 21 AC 82 77 E5-CD 16 02 E1 86 77 7E 11 ...!ャ.w.ヘ....w~. 8020 F4 83 12 3E 01 32 B3 82-CD 70 80 DA 37 80 CD 90 ...>.2ウ.ヘp.レ7.ヘ. 8030 80 CD A0 80 C3 28 80 21-B4 82 06 02 11 F6 83 7E .ヘ.テ(.!エ......~ 8040 12 23 13 05 C2 3F 80 CD-C0 01 21 FA 83 11 F9 83 .#..ツ?.ヘタ.!..... 8050 1A 77 21 F9 83 11 F8 83-1A 77 21 FB 83 3E 48 77 .w!......w!..>Hw 8060 21 F8 83 3E 0E 77 21 FC-83 3E 80 B6 77 C3 00 80 !..>.w!..>.カwテ.. 8070 21 B3 82 11 AF 82 06 04-AF 1A 9E 27 12 2B 1B 05 !ウ..ッ...ッ..'.+.. 8080 C2 79 80 C9 00 00 00 00-00 00 00 00 00 00 00 00 ツy.ノ............ 8090 21 B5 82 7E C6 01 27 77-2B 7E CE 00 27 77 C9 00 !オ.~ニ.'w+~ホ.'wノ. 80A0 06 03 21 B3 82 7E C6 02-27 77 17 E6 01 2B 86 27 ..!ウ.~ニ.'w...+.' 80B0 77 05 C2 AA 80 C9 66 6F-0E 00 CD 5D 10 CD 1B 10 w.ツェ.ノfo..ヘ].ヘ..
これじゃあ何がなんだかさっぱりわからんではないか、とお思いかも知れませんが、昔は大抵こんな感じだったのです。
もっとも右のASCIIダンプは余計です。
マシン語プログラムには無用なものです。
ZB3BASICのメモリダンプコマンドを利用しましたので、こういうリストになってしまいました。
昔はソースプログラムを入力してマシン語プログラムに翻訳してくれる便利なアセンブラなど一般には使うことはできませんでしたから、みんな16進コードを直接メモリに入力したのです。
プログラムを理解するためには、このままではちょっと困りますけれど、自分のマシン(この場合には当然のことながらTK−80)に入力するためには、これで十分です。
マシン語プログラムに慣れてきますと、16進コードを見ただけで、ある程度はプログラムが読めるようになってきます。
LD B,06
LD HL,$82AC
XOR A
LD (HL),A
INC HL
DEC B
JP NZ,$8006
という調子です。
あ…。
私の場合には、ずっと長い間Z80でしたから、やっぱりZ80ニーモニックが出てきてしまいます。
しかし、それじゃあいかにも原始的すぎます。
幸い今はアセンブラも逆アセンブラも使うことができますから、それを利用しない手はありません。
で、さっそくZ80逆アセンブラを使ってみました。
Z80逆アセンブラはND80ZV組立キットの付属ソフトウェアです。
M様から送っていただいたのは、バイナリファイルなのですがTK−80形式で先頭にアドレス情報4バイトがついていますから、そのままでは逆アセンブラにかけることができません。
Z80逆アセンブラにかけるには、普通のバイナリファイルでなければいけません。
最も簡単な方法はZB3BASICを利用する方法です。
ZB3BASICもND80ZV組立キットに付属しています。
まずND80ZVをTK80モードで起動して、USBケーブルを接続し、TK−80方式のバイナリファイル(BTKファイル)をLOADします。(プログラムを実行しなければ、ND80ZモードでLOADしても構いません)
次にリセットスイッチを押しながら、ディップスイッチを操作してND80Zモードにします。
パソコンのDOSプロンプト画面からZB3BASICを起動します。
ZB3BASICが起動したら、マシン語SAVEコマンドを使って、
/SV ROOT.BIN,8000,80B5
のように入力して、バイナリファイルを作成します。
あとは、そのようにして作成したバイナリファイルをZ80逆アセンブラにかけるだけです。
DOSプロンプトで
ZDAS ROOT.BIN,8000
と入力すると、逆アセンブルリストファイルが作成されます。
●ルート計算プログラムの逆アセンブルリストです
Z80逆アセンブラによって作成されたルート計算プログラムの逆アセンブルリストです。
8000 060A LD B,0A 8002 21AC82 LD HL,$82AC 8005 AF XOR A 8006 77 LD (HL),A 8007 23 INC HL 8008 05 DEC B 8009 C20680 JP NZ,$8006 800C CD1602 CALL $0216 800F 07 RLCA 8010 07 RLCA 8011 07 RLCA 8012 07 RLCA 8013 21AC82 LD HL,$82AC 8016 77 LD (HL),A 8017 E5 PUSH HL 8018 CD1602 CALL $0216 801B E1 POP HL 801C 86 ADD A,(HL) 801D 77 LD (HL),A 801E 7E LD A,(HL) 801F 11F483 LD DE,$83F4 8022 12 LD (DE),A 8023 3E01 LD A,01 8025 32B382 LD ($82B3),A 8028 CD7080 CALL $8070 802B DA3780 JP C,$8037 802E CD9080 CALL $8090 8031 CDA080 CALL $80A0 8034 C32880 JP $8028 8037 21B482 LD HL,$82B4 803A 0602 LD B,02 803C 11F683 LD DE,$83F6 803F 7E LD A,(HL) 8040 12 LD (DE),A 8041 23 INC HL 8042 13 INC DE 8043 05 DEC B 8044 C23F80 JP NZ,$803F 8047 CDC001 CALL $01C0 804A 21FA83 LD HL,$83FA 804D 11F983 LD DE,$83F9 8050 1A LD A,(DE) 8051 77 LD (HL),A 8052 21F983 LD HL,$83F9 8055 11F883 LD DE,$83F8 8058 1A LD A,(DE) 8059 77 LD (HL),A 805A 21FB83 LD HL,$83FB 805D 3E48 LD A,48 805F 77 LD (HL),A 8060 21F883 LD HL,$83F8 8063 3E0E LD A,0E 8065 77 LD (HL),A 8066 21FC83 LD HL,$83FC 8069 3E80 LD A,80 806B B6 OR (HL) 806C 77 LD (HL),A 806D C30080 JP $8000 8070 21B382 LD HL,$82B3 8073 11AF82 LD DE,$82AF 8076 0604 LD B,04 8078 AF XOR A 8079 1A LD A,(DE) 807A 9E SBC A,(HL) 807B 27 DAA 807C 12 LD (DE),A 807D 2B DEC HL 807E 1B DEC DE 807F 05 DEC B 8080 C27980 JP NZ,$8079 8083 C9 RET 8084 00 NOP 8085 00 NOP 8086 00 NOP 8087 00 NOP 8088 00 NOP 8089 00 NOP 808A 00 NOP 808B 00 NOP 808C 00 NOP 808D 00 NOP 808E 00 NOP 808F 00 NOP 8090 21B582 LD HL,$82B5 8093 7E LD A,(HL) 8094 C601 ADD A,01 8096 27 DAA 8097 77 LD (HL),A 8098 2B DEC HL 8099 7E LD A,(HL) 809A CE00 ADC A,00 809C 27 DAA 809D 77 LD (HL),A 809E C9 RET 809F 00 NOP 80A0 0603 LD B,03 80A2 21B382 LD HL,$82B3 80A5 7E LD A,(HL) 80A6 C602 ADD A,02 80A8 27 DAA 80A9 77 LD (HL),A 80AA 17 RLA 80AB E601 AND 01 80AD 2B DEC HL 80AE 86 ADD A,(HL) 80AF 27 DAA 80B0 77 LD (HL),A 80B1 05 DEC B 80B2 C2AA80 JP NZ,$80AA 80B5 C9 RET
オリジナルは8080のプログラムなのですが、Z80は8080の命令をそのまま実行できます。
ですからマシン語コードは8080の命令のまま全て実行できるのですが、同じ命令コードでも8080とZ80とではニーモニック表現が異なります。
ND80ZV組立キットに付属している逆アセンブラはZ80用ですから、Z80ニーモニックに翻訳してしまいます。
それはそれとして、このリストのままでも16進コードだけに比べればはるかにわかりやすいのですけれど、でも、もう少しなんとかならないかなあ、という気がします。
実はZ80逆アセンブラは、このような逆アセンブルリストを作成するだけではなくて、そのままZ80アセンブラにかけられる、ソースプログラムファイルも同時に作成してしまうのです。
●同時に作成されたソースプログラムリストです
ORG $8000 Z82AC=$82AC Z0216=$0216 Z83F4=$83F4 Z82B3=$82B3 Z82B4=$82B4 Z83F6=$83F6 Z01C0=$01C0 Z83FA=$83FA Z83F9=$83F9 Z83F8=$83F8 Z83FB=$83FB Z83FC=$83FC Z82AF=$82AF Z82B5=$82B5 Z8000:LD B,0A LD HL,Z82AC XOR A Z8006:LD (HL),A INC HL DEC B JP NZ,Z8006 CALL Z0216 RLCA RLCA RLCA RLCA LD HL,Z82AC LD (HL),A PUSH HL CALL Z0216 POP HL ADD A,(HL) LD (HL),A LD A,(HL) LD DE,Z83F4 LD (DE),A LD A,01 LD (Z82B3),A Z8028:CALL Z8070 JP C,Z8037 CALL Z8090 CALL Z80A0 JP Z8028 Z8037:LD HL,Z82B4 LD B,02 LD DE,Z83F6 Z803F:LD A,(HL) LD (DE),A INC HL INC DE DEC B JP NZ,Z803F CALL Z01C0 LD HL,Z83FA LD DE,Z83F9 LD A,(DE) LD (HL),A LD HL,Z83F9 LD DE,Z83F8 LD A,(DE) LD (HL),A LD HL,Z83FB LD A,48 LD (HL),A LD HL,Z83F8 LD A,0E LD (HL),A LD HL,Z83FC LD A,80 OR (HL) LD (HL),A JP Z8000 Z8070:LD HL,Z82B3 LD DE,Z82AF LD B,04 XOR A Z8079:LD A,(DE) SBC A,(HL) DAA LD (DE),A DEC HL DEC DE DEC B JP NZ,Z8079 RET NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP Z8090:LD HL,Z82B5 LD A,(HL) ADD A,01 DAA LD (HL),A DEC HL LD A,(HL) ADC A,00 DAA LD (HL),A RET NOP Z80A0:LD B,03 LD HL,Z82B3 LD A,(HL) ADD A,02 DAA LD (HL),A Z80AA:RLA AND 01 DEC HL ADD A,(HL) DAA LD (HL),A DEC B JP NZ,Z80AA RET
かなりプログラムらしくなってきました。
Z80逆アセンブラによって作成されたソースプログラムは、拡張子はDTXですが、中身はテキストファイルですからテキストエディタで編集することができます。
さっそく編集をしてみました。
編集作業の目的は、Z80逆アセンブラによって機械的につけられたラベル名を意味のあるラベル名に変更することです。
Z80逆アセンブラはプログラムの中で使っている変数や外部参照アドレスをプログラムの先頭にまとめて表示します。
そこを見れば、このプログラムで使っているワークエリアや外部サブルーチンのアドレスがわかります。
このプログラムでは、TK80モニタプログラムのサブルーチンを利用しています。
Z0216(アドレス0216)とZ01C0(アドレス01C0)です。
このようにZ80逆アセンブラはラベル名として、そのアドレスの前にZの文字をつけたものを生成します。
0216はキー入力ルーチン(KEYIN)です。
01C0はセグメント表示データ変換ルーチン(SEGCG)です。
またこのプログラムはTK80モニタプログラムのLED表示データエリアをアクセスしています。
83F4はLED表示用レジスタ1、83F6はLED表示用レジスタ3です。
それぞれLEDDP1、LEDDP3というラベルに変更します。
83F8〜83FCはLED桁表示レジスタ1〜5です。
それぞれLED1〜LED5に変更します。
このプログラムは計算用のワークエリアとして82AC〜82B5を使っているようです。
ここはプログラムの内容を解析しないと適切なラベル名はつけられません。
参照しているワークエリアのアドレスは、
82AC、82AF、82B3、82B4、82B5だけです。
仮にそれぞれ、DATA1、DATA4、DATA8、DATA9、DATA10としておきます。
Z80逆アセンブラはプログラム内でCALLしているサブルーチンやジャンプ先のアドレスにもラベルをつけて示します。
ここもプログラムを解析しないと意味の有るラベル名はつけられません。
ここはとりあえずは、そのままにしておくことにします。
ラベル名の変更はテキストエディタの文字列変換機能を使って一括変換をすれば簡単に置き換えることができます。
●編集したソースプログラムリストです
;;; root program for ND80Z3 ; 2010/11/08 ; ORG $8000 ; SEGCG=$01C0 KEYIN=$0216 ; LEDDP1=$83F4 LEDDP3=$83F6 ; LED1=$83F8 LED2=$83F9 LED3=$83FA LED4=$83FB LED5=$83FC ; DATA1=$82AC DATA4=$82AF DATA8=$82B3 DATA9=$82B4 DATA10=$82B5 ; Z8000:LD B,0A LD HL,DATA1 XOR A Z8006:LD (HL),A INC HL DEC B JP NZ,Z8006 CALL KEYIN RLCA RLCA RLCA RLCA LD HL,DATA1 LD (HL),A PUSH HL CALL KEYIN POP HL ADD A,(HL) LD (HL),A LD A,(HL) LD DE,LEDDP1 LD (DE),A LD A,01 LD (DATA8),A Z8028:CALL Z8070 JP C,Z8037 CALL Z8090 CALL Z80A0 JP Z8028 Z8037:LD HL,DATA9 LD B,02 LD DE,LEDDP3 Z803F:LD A,(HL) LD (DE),A INC HL INC DE DEC B JP NZ,Z803F CALL SEGCG LD HL,LED3 LD DE,LED2 LD A,(DE) LD (HL),A LD HL,LED2 LD DE,LED1 LD A,(DE) LD (HL),A LD HL,LED4 LD A,48 LD (HL),A LD HL,LED1 LD A,0E LD (HL),A LD HL,LED5 LD A,80 OR (HL) LD (HL),A JP Z8000 Z8070:LD HL,DATA8 LD DE,DATA4 LD B,04 XOR A Z8079:LD A,(DE) SBC A,(HL) DAA LD (DE),A DEC HL DEC DE DEC B JP NZ,Z8079 RET NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP Z8090:LD HL,DATA10 LD A,(HL) ADD A,01 DAA LD (HL),A DEC HL LD A,(HL) ADC A,00 DAA LD (HL),A RET NOP Z80A0:LD B,03 LD HL,DATA8 LD A,(HL) ADD A,02 DAA LD (HL),A Z80AA:RLA AND 01 DEC HL ADD A,(HL) DAA LD (HL),A DEC B JP NZ,Z80AA RET
●編集したソースプログラムをZ80アセンブラにかけてみました
上のようにして編集作成したソースプログラムをZ80アセンブラにかけてみました。
Z80アセンブラもND80ZV組立キットに付属しています。
DOSプロンプトで
ZASM ROOT.TXT
と入力するだけです。
実に簡単です。
Z80アセンブラによって作成されたアセンブルリストです。
2010/11/8 23:33 root.txt END=80B5 ;;; root program for ND80Z3 ; 2010/11/08 ; ORG $8000 ; SEGCG=$01C0 KEYIN=$0216 ; LEDDP1=$83F4 LEDDP3=$83F6 ; LED1=$83F8 LED2=$83F9 LED3=$83FA LED4=$83FB LED5=$83FC ; DATA1=$82AC DATA4=$82AF DATA8=$82B3 DATA9=$82B4 DATA10=$82B5 ; 8000 060A Z8000:LD B,0A 8002 21AC82 LD HL,DATA1 8005 AF XOR A 8006 77 Z8006:LD (HL),A 8007 23 INC HL 8008 05 DEC B 8009 C20680 JP NZ,Z8006 800C CD1602 CALL KEYIN 800F 07 RLCA 8010 07 RLCA 8011 07 RLCA 8012 07 RLCA 8013 21AC82 LD HL,DATA1 8016 77 LD (HL),A 8017 E5 PUSH HL 8018 CD1602 CALL KEYIN 801B E1 POP HL 801C 86 ADD A,(HL) 801D 77 LD (HL),A 801E 7E LD A,(HL) 801F 11F483 LD DE,LEDDP1 8022 12 LD (DE),A 8023 3E01 LD A,01 8025 32B382 LD (DATA8),A 8028 CD7080 Z8028:CALL Z8070 802B DA3780 JP C,Z8037 802E CD9080 CALL Z8090 8031 CDA080 CALL Z80A0 8034 C32880 JP Z8028 8037 21B482 Z8037:LD HL,DATA9 803A 0602 LD B,02 803C 11F683 LD DE,LEDDP3 803F 7E Z803F:LD A,(HL) 8040 12 LD (DE),A 8041 23 INC HL 8042 13 INC DE 8043 05 DEC B 8044 C23F80 JP NZ,Z803F 8047 CDC001 CALL SEGCG 804A 21FA83 LD HL,LED3 804D 11F983 LD DE,LED2 8050 1A LD A,(DE) 8051 77 LD (HL),A 8052 21F983 LD HL,LED2 8055 11F883 LD DE,LED1 8058 1A LD A,(DE) 8059 77 LD (HL),A 805A 21FB83 LD HL,LED4 805D 3E48 LD A,48 805F 77 LD (HL),A 8060 21F883 LD HL,LED1 8063 3E0E LD A,0E 8065 77 LD (HL),A 8066 21FC83 LD HL,LED5 8069 3E80 LD A,80 806B B6 OR (HL) 806C 77 LD (HL),A 806D C30080 JP Z8000 8070 21B382 Z8070:LD HL,DATA8 8073 11AF82 LD DE,DATA4 8076 0604 LD B,04 8078 AF XOR A 8079 1A Z8079:LD A,(DE) 807A 9E SBC A,(HL) 807B 27 DAA 807C 12 LD (DE),A 807D 2B DEC HL 807E 1B DEC DE 807F 05 DEC B 8080 C27980 JP NZ,Z8079 8083 C9 RET 8084 00 NOP 8085 00 NOP 8086 00 NOP 8087 00 NOP 8088 00 NOP 8089 00 NOP 808A 00 NOP 808B 00 NOP 808C 00 NOP 808D 00 NOP 808E 00 NOP 808F 00 NOP 8090 21B582 Z8090:LD HL,DATA10 8093 7E LD A,(HL) 8094 C601 ADD A,01 8096 27 DAA 8097 77 LD (HL),A 8098 2B DEC HL 8099 7E LD A,(HL) 809A CE00 ADC A,00 809C 27 DAA 809D 77 LD (HL),A 809E C9 RET 809F 00 NOP 80A0 0603 Z80A0:LD B,03 80A2 21B382 LD HL,DATA8 80A5 7E LD A,(HL) 80A6 C602 ADD A,02 80A8 27 DAA 80A9 77 LD (HL),A 80AA 17 Z80AA:RLA 80AB E601 AND 01 80AD 2B DEC HL 80AE 86 ADD A,(HL) 80AF 27 DAA 80B0 77 LD (HL),A 80B1 05 DEC B 80B2 C2AA80 JP NZ,Z80AA 80B5 C9 RET DATA1 =82AC DATA10 =82B5 DATA4 =82AF DATA8 =82B3 DATA9 =82B4 KEYIN =0216 LED1 =83F8 LED2 =83F9 LED3 =83FA LED4 =83FB LED5 =83FC LEDDP1 =83F4 LEDDP3 =83F6 SEGCG =01C0 Z8000 =8000 Z8006 =8006 Z8028 =8028 Z8037 =8037 Z803F =803F Z8070 =8070 Z8079 =8079 Z8090 =8090 Z80A0 =80A0 Z80AA =80AA
いかがでしょう。
これなら、何をやっているか、読めるような気がしませんでしょうか?
2010.11.8upload
前へ
次へ
ホームページトップへ戻る