![見出し画像](https://assets.st-note.com/production/uploads/images/142611333/rectangle_large_type_2_d4063a327770157b76fd479e6d03029a.jpeg?width=1200)
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 から実行しているところです。
![](https://assets.st-note.com/img/1717239127897-vVYxT1uDMe.png?width=1200)