見出し画像

Tang Nano 9K で Apple II を再現する(8)ROM

第六章 The 6502 and System Bus

Apple II の ROM は、最大 6 個の 2K バイトマスク ROM 9316B で構成され、12K バイトのスペースを使用します。
Tang Nano 9K の BSRAM は、2K バイト単位で 26 個のブロックが使用できます。RAM 用に24 ブロック使うと、残り 2 ブロック(4K バイト)しかありません。そのため、F0 と F8 ROM を SSRAM(ROM16)、E0 と E8 を BSRAM(pROM)に割り当てることにします。D0 と D8 ROM のスペースが足りないため、Apple II standard の ROM データを使用します。

回路図 C-10 を a2_rom.sv として実装します。

`default_nettype none

module a2_rom(
    input wire [15:0] ad,
    input wire inh_n,
    input wire ph1,
    output reg [7:0] d,
    output wire io_stb_n,
    output wire f12_15,
    input wire mclk
);

// F3:9316B
logic f3_cs;
logic [7:0] f3_dout;
logic [7:0] dout_f8;

Gowin_ROM16_F8 rom_f8(
    .dout(dout_f8), //output [7:0] dout
    .ad(ad[10:0]) //input [10:0] ad
);

//Gowin_pROM_f8 rom_f8(
//    .dout(dout_f8), //output [7:0] dout
//    .clk(mclk), //input clk
//    .oce(1'b1), //input oce
//    .ce(1'b1), //input ce
//    .reset(1'b0), //input reset
//    .ad(ad[10:0]) //input [10:0] ad
//);

assign f3_cs = f12_z7_n | ~inh_n;
assign f3_dout = f3_cs ? 8'bz : dout_f8;

// F5:9316B
logic f5_cs;
logic [7:0] f5_dout;
logic [7:0] dout_f0;

Gowin_ROM16_F0 rom_f0(
    .dout(dout_f0), //output [7:0] dout
    .ad(ad[10:0]) //input [10:0] ad
);

//Gowin_pROM_F0 rom_f0(
//    .dout(dout_f0), //output [7:0] dout
//    .clk(mclk), //input clk
//    .oce(1'b1), //input oce
//    .ce(1'b1), //input ce
//    .reset(1'b0), //input reset
//    .ad(ad[10:0]) //input [10:0] ad
//);

assign f5_cs = f12_z6_n | ~inh_n;
assign f5_dout = f5_cs ? 8'bz : dout_f0;

// F6:9318B
logic f6_cs;
logic [7:0] f6_dout;
logic [7:0] dout_e8;

//Gowin_ROM16_E8 rom_e8(
//    .dout(dout_e8), //output [7:0] dout
//    .ad(ad[10:0]) //input [10:0] ad
//);

Gowin_pROM_e8 rom_e8(
    .dout(dout_e8), //output [7:0] dout
    .clk(mclk), //input clk
    .oce(1'b1), //input oce
    .ce(1'b1), //input ce
    .reset(1'b0), //input reset
    .ad(ad[10:0]) //input [10:0] ad
);

assign f6_cs = f12_z5_n | ~inh_n;
assign f6_dout = f6_cs ? 8'bz : dout_e8;

// F8:9318B
logic f8_cs;
logic [7:0] f8_dout;
logic [7:0] dout_e0;

//Gowin_ROM16_E0 rom_e0(
//    .dout(dout_e0), //output [7:0] dout
//    .ad(ad[10:0]) //input [10:0] ad
//);

Gowin_pROM_e0 rom_e0(
    .dout(dout_e0), //output [7:0] dout
    .clk(mclk), //input clk
    .oce(1'b1), //input oce
    .ce(1'b1), //input ce
    .reset(1'b0), //input reset
    .ad(ad[10:0]) //input [10:0] ad
);

assign f8_cs = f12_z4_n | ~inh_n;
assign f8_dout = f8_cs ? 8'bz : dout_e0;

// F9:9318B
logic f9_cs;
logic [7:0] f9_dout;
logic [7:0] dout_d8;

//Gowin_pROM_d8 rom_d8(
//    .dout(dout_d8), //output [7:0] dout
//    .clk(mclk), //input clk
//    .oce(1'b1), //input oce
//    .ce(1'b1), //input ce
//    .reset(1'b0), //input reset
//    .ad(ad[10:0]) //input [10:0] ad
//);

assign f9_cs = f12_z3_n | ~inh_n;
assign f9_dout = f9_cs ? 8'bz : dout_d8;

// F11:9318B
logic f11_cs;
logic [7:0] f11_dout;
logic [7:0] dout_d0;

//Gowin_pROM_d0 rom_d0(
//    .dout(dout_d0), //output [7:0] dout
//    .clk(mclk), //input clk
//    .oce(1'b1), //input oce
//    .ce(1'b1), //input ce
//    .reset(1'b0), //input reset
//    .ad(ad[10:0]) //input [10:0] ad
//);

assign f11_cs = f12_z2_n | ~inh_n;
assign f11_dout = f11_cs ? 8'bz : dout_d0;

// F12:74LS138
logic f12_z0_n;
logic f12_z1_n;
logic f12_z2_n;
logic f12_z3_n;
logic f12_z4_n;
logic f12_z5_n;
logic f12_z6_n;
logic f12_z7_n;
logic f12_e;

assign f12_e = h1_6 & ~ph1;
assign f12_z0_n = f12_e ? (ad[11] | ad[12] | ad[13]) : 1'b1;
assign f12_z1_n = f12_e ? (!ad[11] | ad[12] | ad[13]) : 1'b1;
assign f12_z2_n = f12_e ? (ad[11] | !ad[12] | ad[13]) : 1'b1;
assign f12_z3_n = f12_e ? (!ad[11] | !ad[12] | ad[13]) : 1'b1;
assign f12_z4_n = f12_e ? (ad[11] | ad[12] | !ad[13]) : 1'b1;
assign f12_z5_n = f12_e ? (!ad[11] | ad[12] | !ad[13]) : 1'b1;
assign f12_z6_n = f12_e ? (ad[11] | !ad[12] | !ad[13]) : 1'b1;
assign f12_z7_n = f12_e ? (!ad[11] | !ad[12] | !ad[13]) : 1'b1;

assign f12_15 = f12_z0_n;
assign io_stb_n = f12_z1_n;

// H1:74LS08
logic h1_6;
assign h1_6 = ad[14] & ad[15];

logic [7:0] d0;

always_ff@(posedge mclk) begin
    d0 <= f3_dout | f5_dout | f6_dout | f8_dout | f9_dout | f11_dout;
    d <= d0;
end

endmodule

`default_nettype wire

BSRAM のアクセスにクロックが必要なため、 mclk(14 MHz)を使用します。また、ROM 出力を 1 mclk 分遅延させます。

ROM アクセスの様子を観察してみます。
下図は、リセットベクター $FFFC-FFFD を読み、$FF59 から実行しているところです。

6502 read from ROM

参考文献


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