2013.8.17
前へ
次へ
ホームページトップへ戻る

復活!CP/M ワンボードマイコンでCP/Mを!
CP/MがTK−80互換のワンボードマイコンの上で復活します
ND80ZVとMYCPU80の上でCP/Mが走ります

[第460回]


●論理アドレスから物理アドレスへの変換(8086の場合)

前回のベースレジスタを使って20ビットのアドレスを算出するという説明を書いていて思い出しました。
これって8086のセグメントレジスタと同じやり方じゃないの?
ということで、ちょっと余談です。

8086は16ビットCPUですがアクセスできるメモリアドレスはZ8S180と同じ00000〜FFFFFの1MBです。
16ビットCPUなのでそれくらいのアドレスは命令で直接制御できるだろうと思われるかも知れませんが、意外にもそのあたりの機能に関しては8ビットCPUとそれほど変わりはありません。
なんと8ビットCPUと同様に16ビットのレジスタしか持っていないのです。
ということは8080やZ80、Z8S180と同様に通常のレジスタでアクセスできるメモリアドレスは0000〜FFFFの64KBに限られます。

それでは8086もZ8S180と同じようにメモリバンクによって1MBのメモリ空間をアクセスしているのかと言いますと、それはちょっと違います。
ただ論理メモリアドレスから物理メモリアドレスに変換する仕組みはZ8S180と似たところがあります。
16ビットのアドレスを20ビットのアドレスに変換するにはZ8S180と同じように、2つのレジスタの値を加算します。
8086ではメモリバンクではなくてセグメントという概念を使います。

セグメントはその中に論理的なアドレス0000〜FFFFをもつ64KBのメモリブロックです。
そのセグメントには使用目的別に、主として命令コードが置かれるコードセグメント(CS)、スタックとして使われるスタックセグメント(SS)、データ領域として使われるデータセグメント(DS)、それだけでは不足する場合に使われるエクストラセグメント(ES)の4つがあります。
セグメントレジスタを使って20ビットの物理アドレスを算出する方法はZ8S180での方法とよく似ています。



Z8S180のベースレジスタは8ビットですが8086のセグメントレジスタは16ビットです。
そして図のようにセグメントレジスタの値を4ビット左にずらして、命令中の16ビットの論理アドレスと加算して物理アドレスを求めます。
セグメントレジスタの値をベースにして、そこから64KBのメモリ空間がそのセグメントに割り当てられます。
セグメントレジスタの値は物理メモリ上で16バイトごとに指定することができます。
しかしもし各セグメントを16バイトごとに置いたとすると、各セグメントの中身が重なり合ってしまいます。
そうなるとたとえばデータセグメントにデータを書き込んだらコードセグメントのプログラムを破壊してしまった、というようなことが起きてしまう可能性があります。
ですからZ8S180のベースレジスタと同じように、セグメントレジスタもセグメントが重ならないように、64KBおきの値を入れるようにするのが普通です。

以上余談でした。

●メモリバンクテストプログラム

前回説明しましたバンクベースレジスタを使って1MBのメモリにバンクを切り換えながらテストデータを書き込んでいって、次にまた最初からバンクを切り換えながらメモリの値を読み出して正しく書き込まれているか比較チェックするプログラムです。
1MBのメモリを先頭から32KBづつに区切って、バンク0、バンク1、バンク2…としたとき、バンク0〜バンク2はシステムで使いますから、バンク3(物理アドレス18000〜18FFF)から後ろのアドレスを対象にします。
プログラムのうちバンクを切り換えてテストデータを書き込み、読み出すところは下のマシン語サブルーチンで行ないます。
結果の表示などを伴いますからその部分はBASICで書いて、マシン語のサブルーチンを呼び出して実行します。

2013/7/30  8:6  membkts.txt
END=80AB
              ;;;memory bank test
              ; 13/7/30
              ;
                ORG $8004
              ;
                PA=$F440
                PB=$F442
                PC=$F444
                PD=$F446
                PE=$F448
              ;
8004 C30A80     JP WR
8007 C34780     JP RDCK
800A 210000   WR:LD HL,$0000
800D ED4B42F4   LD BC,(PB)
8011 ED5B44F4   LD DE,(PC)
8015 3A40F4     LD A,(PA)
8018 ED         DB ED
8019 39         DB 39;OUT0 [n],A
801A 39         DB 39
801B 73       WR2:LD (HL),E
801C 23         INC HL
801D 7C         LD A,H
801E B7         OR A
801F FA3A80     JP M,WREND
8022 72         LD (HL),D
8023 23         INC HL
8024 7C         LD A,H
8025 B7         OR A
8026 FA3A80     JP M,WREND
8029 71         LD (HL),C
802A 23         INC HL
802B 7C         LD A,H
802C B7         OR A
802D FA3A80     JP M,WREND
8030 13         INC DE
8031 7A         LD A,D
8032 B3         OR E
8033 C21B80     JP NZ,WR2
8036 0C         INC C
8037 C31B80     JP WR2
803A ED4342F4 WREND:LD (PB),BC
803E ED5344F4   LD (PC),DE
8042 AF         XOR A
8043 ED         DB ED
8044 39         DB 39;OUT0 [n],A
8045 39         DB 39
8046 C9         RET
              ;
8047 210000   RDCK:LD HL,$0000
804A ED4B42F4   LD BC,(PB)
804E ED5B44F4   LD DE,(PC)
8052 3A40F4     LD A,(PA)
8055 ED         DB ED
8056 39         DB 39;OUT0 [n],A
8057 39         DB 39
8058 7B       RDCK2:LD A,E
8059 BE         CP (HL)
805A C29980     JP NZ,RDERR
805D 23         INC HL
805E 7C         LD A,H
805F B7         OR A
8060 FA8380     JP M,RDEND
8063 7A         LD A,D
8064 BE         CP (HL)
8065 C29980     JP NZ,RDERR
8068 23         INC HL
8069 7C         LD A,H
806A B7         OR A
806B FA8380     JP M,RDEND
806E 79         LD A,C
806F BE         CP (HL)
8070 C29980     JP NZ,RDERR
8073 23         INC HL
8074 7C         LD A,H
8075 B7         OR A
8076 FA8380     JP M,RDEND
8079 13         INC DE
807A 7A         LD A,D
807B B3         OR E
807C C25880     JP NZ,RDCK2
807F 0C         INC C
8080 C35880     JP RDCK2
8083 ED4342F4 RDEND:LD (PB),BC
8087 ED5344F4   LD (PC),DE
808B 210000     LD HL,$0000
808E 2246F4     LD (PD),HL
8091 2248F4     LD (PE),HL
8094 AF       RDEND2:XOR A
8095 ED         DB ED
8096 39         DB 39;OUT0 [n],A
8097 39         DB 39
8098 C9         RET
              ;
8099 ED4342F4 RDERR:LD (PB),BC
809D ED5344F4   LD (PC),DE
80A1 2246F4     LD (PD),HL
80A4 6E         LD L,(HL)
80A5 67         LD H,A
80A6 2248F4     LD (PE),HL
80A9 C39480     JP RDEND2
              ;
PA           =F440  PB           =F442  PC           =F444  
PD           =F446  PE           =F448  RDCK         =8047  
RDCK2        =8058  RDEND        =8083  RDEND2       =8094  
RDERR        =8099  WR           =800A  WR2          =801B  
WREND        =803A  

こちらはBASICのメインプログラムです。
ND80ZV(ND80Z3.5)に搭載のZB3BASICと同じBASICをE−80上でも実行できます。
マシン語プログラムの$4004はバンクメモリにテストデータを書き込むルーチンで$4007はバンクメモリからデータを読み出して、書き込んだときと同じ値かどうかを比較チェックするルーチンです。

     10 A=0
     20 B%=0
     30 C%=0
     40 PRINT "*** write start"
     50 FOR A%=$18 TO $78 STEP 8
     60 PRINT HEX$(A%,2),
     70 USR($8004)
     80 PRINT "done"
     90 NEXT A%
    100 A%=2
    110 B%=0
    120 C%=0
    130 PRINT "*** read check start"
    140 FOR A%=$18 TO $78 STEP 8
    150 PRINT HEX$(A%,2),
    160 USR($8007)
    170 IF E%<>0 GOTO 210
    180 PRINT "done"
    190 NEXT A%
    200 STOP
    210 PRINT "error!"
    220 PRINT "b%=";HEX$(B%,4),"c%=";HEX$(C%,4),
    230 PRINT "d%=";HEX$(D%,4),"e%=";HEX$(E%,4) 

下は上のテストプログラムをE−80にロードして実行したときのログです。

>/ld membkts.bin,8004
loading MEMBKTS.BIN ...00a8(168)bytes loaded,from 8004 to 80AB
>/load membktst.txt,8100
    10 A=0
    20 B%=0
    30 C%=0
    40 PRINT "*** write start"
    50 FOR A%=$18 TO $78 STEP 8
    60 PRINT HEX$(A%,2),
    70 USR($8004)
    80 PRINT "done"
    90 NEXT A%
   100 A%=2
   110 B%=0
   120 C%=0
   130 PRINT "*** read check start"
   140 FOR A%=$18 TO $78 STEP 8
   150 PRINT HEX$(A%,2),
   160 USR($8007)
   170 IF E%<>0 GOTO 210
   180 PRINT "done"
   190 NEXT A%
   200 STOP 
   210 PRINT "error!"
   220 PRINT "b%=";HEX$(B%,4),"c%=";HEX$(C%,4),
   230 PRINT "d%=";HEX$(D%,4),"e%=";HEX$(E%,4)
data end
>r.
*** write start
18           done
20           done
28           done
30           done
38           done
40           done
48           done
50           done
58           done
60           done
68           done
70           done
78           done
*** read check start
18           done
20           done
28           done
30           done
38           done
40           done
48           done
50           done
58           done
60           done
68           done
70           done
78           done

break in 200

ワンボードマイコンでCP/Mを![第460回]
2013.8.17upload

前へ
次へ
ホームページトップへ戻る