見出し画像

Tang Nano 9K で Apple II を再現する(6) アドレスマルチプレクサ

第五章 The Memory System 後半

Apple II では、φ0 で、6502 と Video のアドレスを切り替えて共有しています。

アドレスの下位 14 ビットは、AX 信号で二つの 7 ビットアドレスに分割され、4116 の ROW と COLUMN アドレスになります。

/RAS の立ち下がりで ROW アドレスが、/CAS の立ち下がりで COLUMN アドレスが確定します。

回路図 C-5 と C-6 を memory_address.sv として実装します。

`default_nettype none

module memory_address (
    input wire rw,
    input wire kbd_n,
    input wire hires,
    input wire page2,
    input wire ph0,
    input wire [15:0] ad,
    input wire vc,
    input wire hbl,
    input wire ax,
    input wire cas_n,
    input wire h0,
    input wire h1,
    input wire h2,
    input wire h3,
    input wire h4,
    input wire h5,
    input wire va,
    input wire vb,
    input wire v0,
    input wire v1,
    input wire v2,
    input wire v3,
    input wire v4,
    output wire ramsel_n,
    output wire row_c_cas_n,
    output wire row_d_cas_n,
    output wire row_e_cas_n,
    output wire row_c_ra6,
    output wire row_d_ra6,
    output wire row_e_ra6,
    output wire [5:0] ra
);

// H1:74LS08
logic h1_8;
assign h1_8 = hires & page2;

// C11:74LS04
logic page2_n;
assign page2_n = ~page2;

// J1:74LS257
logic j1_zc;
logic j1_zd;
assign j1_zc = ph0 ? ad[14] : h1_8;
assign j1_zd = ph0 ? ad[15] : 0;

// C12:74LS257
logic c12_zc;
logic c12_zd;
assign c12_zc = hires ? page2_n : 0;
assign c12_zd = hires ? vc : hbl;

// F2:74LS139
logic f2_2y0_n;
logic f2_2y1_n;
logic f2_2y2_n;
logic f2_1y0_n;
logic f2_1y1_n;
logic f2_1y2_n;
assign f2_2y0_n = j1_zc | j1_zd;
assign f2_2y1_n = !j1_zc | j1_zd;
assign f2_2y2_n = j1_zc | !j1_zd;
assign f2_1y0_n = (j1_zc | j1_zd) | cas_n;
assign f2_1y1_n = (!j1_zc | j1_zd) | cas_n;
assign f2_1y2_n = (j1_zc | !j1_zd) | cas_n;

assign row_c_cas_n = f2_1y0_n;
assign row_d_cas_n = f2_1y1_n;
assign row_e_cas_n = f2_1y2_n;

// C1:74LS153
logic c1_za;
assign c1_za = ph0
    ? (ax ? ad[12] : ad[13]) 
    : (ax ? c12_zd : c12_zc);
assign row_c_ra6 = c1_za;
assign row_d_ra6 = c1_za;
assign row_e_ra6 = c1_za;

// D2:74LS20
logic d2_8;
assign d2_8 = ~(kbd_n & f2_2y0_n & f2_2y1_n & f2_2y2_n);

// A2:74LS00
assign ramsel_n = ~(rw & d2_8);

// E14:74LS283
logic [3:0] e14_s;
assign e14_s = {~h5, v3, h4, h3} + {v4, ~h5, v4, 1'b1} + v3;

// C12:74LS257
logic c12_za;
logic c12_zb;
assign c12_za = hires ? va : page2_n;
assign c12_zb = hires ? vb : page2;

// E13:74LS153
logic e13_za;
logic e13_zb;
assign e13_za = ax
    ? (ph0 ? ad[0] : h0)
    : (ph0 ? ad[5] : e14_s[2]);
assign e13_zb = ax
    ? (ph0 ? ad[1] : h1)
    : (ph0 ? ad[6] : e14_s[3]);

// E12:74LS153
logic e12_za;
logic e12_zb;
assign e12_za = ax 
    ? (ph0 ? ad[2] : h2)
    : (ph0 ? ad[4] : e14_s[1]);
assign e12_zb = ax
    ? (ph0 ? ad[3] : e14_s[0])
    : (ph0 ? ad[9] : v2);

// E11:74LS153
logic e11_za;
logic e11_zb;
assign e11_za = ax 
    ? (ph0 ? ad[7] : v0)
    : (ph0 ? ad[10] : c12_za);
assign e11_zb = ax
    ? (ph0 ? ad[8] : v1)
    : (ph0 ? ad[11] : c12_zb);

assign ra[2] = e13_za;
assign ra[5] = e13_zb;
assign ra[1] = e12_za;
assign ra[4] = e12_zb;
assign ra[0] = e11_za;
assign ra[3] = e11_zb;

endmodule

`default_nettype wire

RAM の読み出しサイクルを観察してみます。
/LDPS の立ち上がりでビデオアドレスが更新されます。φ0 が L、AX が H の時、RAM の ROW アドレスが設定され、/RAS の立ち下がりで確定します。
AX の立ち下がりでビデオ COLUMN アドレスが設定され、/CAS の立ち下がりで C、D、E 列いずれかの 4116 /CAS が下がり、COLUMN アドレスが確定します。
その後、DL に Video の読み出しデータがラッチされます。

一方、φ0 が H、AX が H の時、6502 ROW アドレスが設定され、/RAS の立ち下がりで確定します。
AX の立ち下がりで 6502 COLUMN アドレスが設定され、/CAS の立ち下がりで C、D、E 列いずれかの 4116 /CAS が下がり、COLUMN アドレスが確定します。
その後、DL に 6502 の読み出しデータがラッチされます。

RAM read cycle.

参考文献

この記事が気に入ったらサポートをしてみませんか?