Z8000のエンディアンはどうなっているのか気になったので調べてみた。電脳伝説さんのSBCZ8002があるので簡易モニタを利用して確認した。
Z8000のレジスタは以下のとおり。
基本は16bit幅の汎用レジスタR0〜R15で、R0〜R7は8bit幅のRH0〜7、RL0〜7で上位/下位バイトをアクセスできる。RR0,2,4,6,8,10,12,14は32bit幅のレジスタで16bit幅のレジスタをペアで使う。RQ0,4,8,12は64bit幅の4レジスタペアでこれは直接メモリアクセスはできず、乗算や除算で使用する。
レジスタの指定は4bitで、どの幅のレジスタ(RH/RL,R,RR,RQ)を使うかは命令によって決まる。
こんな感じで自分の直感とは違っていたのでハンドアセンブルで間違えたのよね。
RH0~RH7 → 0~7 / RL0~RL7 → 8~15 でした。
ではエンディアンの確認方法。メモリ上の8100H番地より4バイトのデータを置き、これを元データとする。
(1) 4バイトのRR0にロードし、8108H番地からRH1,RL1,RH0,RL0の順に1バイトずつストア。
(2) 4バイトのRR0にロードし、810CH番地からR1,R0の順に2バイトずつストア。
(3) 2バイトのR0にロードし、8104H番地からRH0,RL0の順に1バイトずつストア。
91F0 PUSHL @R15,RR0
91F2 PUSHL @R15,RR2
2102 8100 LD R2,#8100
2103 8108 LD R3,#8108
1420 LDL RR0,@R2
3231 0000 LDB R3(0),RH1
3239 0001 LDB R3(1),RL1
3230 0002 LDB R3(2),RH0
3238 0003 LDB R3(3),RL0
3331 0004 LD R3(4),R1
3330 0006 LD R3(6),R0
2103 8104 LD R3,#8104
2F20 LD R0,@R2
3230 0000 LDB R3(0),RH0
3238 0001 LDB R3(1),RL0
95F2 POPL RR2,@15
95F0 POPL RR0,@15
9E08 RTS
前後でレジスタをスタックに保存してます。実行結果はこのとおり。

'UNIX'の文字列をロードしてRR0の上位から1バイトずつストアしたら'IXUN'となった。R0は上位バイトがRH0で下位バイトがRL0なので、16bit幅に関してはビッグエンディアンとなる。
ここで残る疑問が。RR0はR1:R0なのだろうかそれともR0:R1なのだろうか?R1:R0ならばPDP-11とも異なるmiddle endianとなり、R0:R1ならば正真正銘のビッグエンディアンとなる。RQ0についても同様。
これについてはレジスタペアを使った演算をやってみて確認する予定。次回につづく。
追記:レジスタペアについて調査。以下のとおり上位から小さい番号のレジスタ順に並びます。
32bitレジスタRRのペアは RR0 = R0:R1
64bitレジスタRQのペアは RQ0 = RR0:RR2 = R0:R1:R2:R3
以下は確認コード:
93FA PUSH @15,R1032bitレジスタペアのRR4について、R4:R5と仮定しR4=0,R5=0x0123を設定、MULT命令で即値0x4567を掛けてRR4に保存。その後8100Hから2バイトずつR4,R5,R6,R7を書き込む。乗算の結果0x004ee415がそのまま見えるので32bitペアの順序は仮定どおり。
91F4 PUSHL @R10,RR4
91F6 PUSHL @R10,RR6
210A 8100 LD R10,#8100
8D48 CLR R4
8D58 CLR R5
8D68 CLR R6
8D78 CLR R7
2105 0123 LD R5,#0123
1904 4567 MULT RR4,#4567
33A4 0000 LD R10(0),R4
33A5 0002 LD R10(2),R5
33A6 0004 LD R10(4),R6
33A7 0006 LD R10(6),R7
1406 0123 4567 LDL RR6,#01234567
1804 1122 3344 MULTL RQ4,#11223344
33A4 0008 LD R10(8),R4
33A5 000A LD R10(A),R5
33A6 000C LD R10(C),R6
33A7 000E LD R10(E),R7
95F6 POPL RR6,@R15
95F4 POPL RR4,@R15
97FA POP R10,@R15
9E08 RTS
64bitレジスタペアのRQ4について、RR4:RR6と仮定しRR4=0,RR6=0x01234567を設定、MULTL命令で即値0x11223344を掛けてRQ4に保存。その後8108Hから2バイトずつR4,R5,R6,R7を書き込む。乗算の結果0x00137e8562dff45cがそのまま見えるので64bitペアの順序は仮定どおり。
検算はgawk --bignum 'BEGIN{printf "%lx ",0x12345678*0x11223344}' などなど。
ということでZ8000のレジスタペアは上位側が小さい番号であり、メモリアクセスはビッグエンディアン。
さて、以上のことはソフトウェア側から見た話であり、ハードウェアでメモリのセレクトを見るとアドレスラインのA0=0のときに奇数アドレスとなるのでバイト単位で入れ替わるという話になります。ややこしいですね。
SBCZ8002でhello,worldに成功(電脳伝説)
電脳伝説@vintagechips
Z8000のエンディアンまとめ。プログラマの皆さんにとってはビッグエンディアンです。下のとおり。ただし、製作担当の立場でいうと、SBCZ8002は偶数バンクと奇数バンクを逆に接続しているので、その状態で普通に並ぶってことはPDPエ… https://t.co/mudGeQK9C0
2020/02/29 10:46:33







