EX-80メモリ増設

部品箱に眠っていたメモリをEX-80に増設を試してみました。

もともとついてるメモリはTMM314APというチップで一般的には2114とよばれる4bitx1Kで2つで8Bitにして1KByteになります。製品は標準で1KByteで二つ増設して最大2KByteになります。

||アドレス|
|:--|:--|
|1K|8000-83FF|
|2K|8400-87FF|

2114にはOEがなくCEが0でWEが1の時にデーターがOUTPUTされます。

余談ですが2114より前の世代のメモリはDataのINとOUTが別になっていたようです。

EX-80BSでは標準で4KByteで最大16KByteにできたようです。EX-80のメモリは上位ビットのデコードがないので、EX-80からメモリを抜いてEX-80BSに移していたようです。EX-80BSはスタックして使っていたので、まったく写真が無くどのような構成だったか確認できません。

# 実験1

発掘された部品は同じく東芝のTC5564PL-15で、8KByteのメモリです。

![写真（2020-06-20 12.35）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/d6db7b81-678c-2845-3690-b0749f564465.jpeg)

8625とあるので1986年25週の製造だと思われます。同じ東京芝浦電気のマークのチップですがEX-80のチップには9Jのような記号しかありません。東京芝浦電気は1984年に東芝への社名変更とともにロゴも変更されたのですが、それ以前からの製品は従来のロゴが使われていたのかもしれません。歌詞に「東芝マーク」と歌われているCMソングの作曲は三木鶏郎グループにいた越部信義さんです。

近いチップのデーターシートは紙をスキャンしたものがネットにあります。

![5564.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/3a5b85ae-31b4-f7d1-ca00-47432f4f4e54.png)

ROMと互換のあるピン配置になっています。32KByteのメモリも同じ28ピンになり、CE2(26)がA13でN.C(1)がA14になります。

このチップはCEが二つあります。

![5564CE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/9f01f06a-b9c6-a29b-bcd6-94ad81a7a946.png)

2114の代わりにしたかったのですが、うまくできなかったので元のメモリをそのままにして、デコードされていてメモリが乗ってない、8800-8FFFの2Kだけ増設してみます。

![写真（2020-06-21 4.47）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/011bc830-ac44-e692-b774-821aa8dac526.jpeg)

R/WにはMEMWでOEにはMEMRを入れます。CE2はA15でCE1にはGALで信号を入れます。

GALはこのようにしてみました。

```verilog
module test(
input rst_in,
input memw,
input memr,
input hlda,
input a11,
output rst_out,
output ce0,
output ce1
);


assign rst_out = ~rst_in;

assign ce0 = a11 == 1 ? memw & memr & rst_in & hlda : 1;

// not use
assign ce1 = memr & hlda;

endmodule
```

モニターでテストしてみます。

![Untitled.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/8ba55ec6-136d-7af1-024b-05cde8022e2f.jpeg)

うまくいっているようです。

# 実験2

せっかく8KByteあるので大きく使う方法をいろいろ考えて、EX-80BS方式はとらずに、オンボードのメモリのデコードを強化する方法にしました。

理由は拡張ボードが無いときにも普通に動く方がいいと思いました。またメインボードからRAMやROMを抜いてしまうとちょっと寂しい気がしました。

あと74LS156の挙動が理解できなかったので、できるだけいじらない方法にしたかったというのもあります。

デコーダーの74LS156は4KをデコードしているのですがRAMは後半2Kは未使用ですし、ROMも後半は2Kは拡張用で必要無いので、これをうまく使うことにします。

A11-A14をOR(7432)で束ねて元の156に入れることにしました。これで8000-87FFは他の番地で見えることはありません。最初DIPの74LS32で試していたところ、いろいろやってるうちに足を折ってしまい、部品箱から出てきた何かからはがしたSOPなチップで作ってみました。A12-A14はpull downしないと正常に動かなかったので、抵抗を入れてあります。

![EX-MEM-DEC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/5a6d36d3-3b2f-911e-3d36-9708a6fddd79.png)

![写真（2022-04-09 17.42） #2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/c9947d04-1808-9b6b-4289-a4de33006ec7.jpeg)

増設側ではこの領域を見えないようにすればいけるはずです。

メモリは二つあったのでGAL書き直しました。

```verilog
module test(
input rst_in,
input memw,
input memr,
input hlda,
input [2:0] address,   // A11,A12,A13
output rst_out,
output ce0,
output ce1
);


assign rst_out = ~rst_in;

assign ce0 = address >= 1 && address <= 3 ? memw & memr & rst_in & hlda : 1;

assign ce1 = address >= 4 ? memw & memr & rst_in & hlda : 1;

endmodule
```

構成はこのようになりました。

![EX-MEM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/cd294055-d7f6-980f-362e-3db90c26ef75.png)

2K+16Kもできそうですが、アドレスが複雑になるので、諦めました。

ピンを追加するとアサインが変わってしまうのがちょっとあれですが、GALはとっても便利です。

メモリチェックプログラム書いてみました。

```
;

TVCLR   EQU     036CH
TVDSP   EQU     02DEH

MEMS    EQU     8400H
MEME    EQU     0C000H

; 8279 ports

DAT     EQU     0EEH
CTL     EQU     0EFH

        ORG     8200H

        CALL    TVCLR
; initialize 8279
        MVI     A, 00H
        OUT     CTL
        MVI     A, 0A0H
        OUT     CTL
        MVI     A, 32H
        OUT     CTL
        MVI     A, 50H
        OUT     CTL
        MVI     A, 0D0H
        OUT     CTL
        MVI     A, 90H
        OUT     CTL

START
        MVI     B, MEMS SHR 8
        MVI     C, MEMS AND 0FFH
LOOP1
        MVI     A, 90H
        OUT     CTL
        CALL    WAIT
        MOV     A, B
        CALL    DISP
        MOV     A, C
        CALL    DISP
LOOP
        MOV     A, C
        STAX    B
        LDAX    B
        CMP     C
        JNZ     ERR
        INR     C
        JNZ     LOOP
        INR     B
        MOV     A, B
        CPI     MEME SHR 8
        JNZ     LOOP1
        JMP     START

WAIT
        MVI     A, 90H
WLOOP
        DCR     A
        JNZ     WLOOP
        RET

ERR
        MVI     A, 79H
        OUT     DAT
LOOP0
        JMP     LOOP0

DISP
        PUSH    B
        MOV     B, A
        LXI     H, SEG
        MVI     D, 00H
        MOV     A, B
        ANI     0F0H
        RRC
        RRC
        RRC
        RRC
        MOV     E, A
        DAD     D
        MOV     A, M
        OUT     DAT

        LXI     H, SEG
        MOV     A, B
        ANI     0FH
        MOV     E, A
        DAD     D
        MOV     A, M
        OUT     DAT
        POP     B
        RET

SEG     DB      3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 27H
        DB      7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H
```

標準が1Kなのでデフォルトのスタックポインタは8400Hに設定されていて、メモリテストの対象とはかぶっていません。かぶっていると暴走します。

動かすとこんな感じです。

https://youtu.be/Z_AJmX-Ty2Q


スタックポインターをメモリの一番後ろに設定するコードは以下になります。


```
         LXI     SP, 0B000H
```

昔の本を見ていて気がついたのですが、「マイコン設計トレーニング」というZ80を使った製作記事の本にEX-80 Basic Level2を使うことが書いてあります。当時東芝はオープンソースにはしていなかったでしょうしGPLなどもない時代ですから、単にピーコしていたのではないでしょうか。この本はすでに16ビットのコンピュータが出てからのもので、8ビット時代のコードはオープン化していると勝手に解釈していたのかもしれません。平和な時代でしたね。

16KもメモリのったのでBASICも試して見たい。東芝さんEX-80 Basic Level2をオープンソースにしてください。