Line 17... |
Line 17... |
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
|
|
module sound1942;
|
module sound1942;
|
// inputs to Z80
|
// inputs to Z80
|
reg reset_n, clk, int_n, sound_clk;
|
reg reset_n, clk, int_n, sound_clk;
|
|
parameter dump_text = 1; // set to 1 to dump data to use log2wav later
|
|
|
initial begin
|
initial begin
|
/* $dumpfile("dump.lxt");
|
/* $dumpfile("dump.lxt");
|
$dumpvars(1,pwm0);
|
$dumpvars(1,pwm0);
|
$dumpvars(1,pwm1);*/
|
$dumpvars(1,pwm1);*/
|
Line 28... |
Line 29... |
// $dumpon;
|
// $dumpon;
|
// $shm_open("1942.shm");
|
// $shm_open("1942.shm");
|
// $shm_probe( sound1942, "ACTFS" );
|
// $shm_probe( sound1942, "ACTFS" );
|
reset_n=0;
|
reset_n=0;
|
#1500 reset_n=1;
|
#1500 reset_n=1;
|
|
$display("1942 START");
|
// change finish time depending on song
|
// change finish time depending on song
|
//#4e6 $finish;
|
//#0.1e9 $finish;
|
#6e9 $finish;
|
#7e9 $finish;
|
end
|
end
|
|
|
always begin // main clock
|
always begin // main clock
|
clk=0;
|
clk=0;
|
forever clk = #167 ~clk;
|
forever clk = #167 ~clk;
|
Line 71... |
Line 73... |
*/
|
*/
|
reg vhf_clk;
|
reg vhf_clk;
|
always begin
|
always begin
|
vhf_clk=0;
|
vhf_clk=0;
|
forever begin
|
forever begin
|
if( vhf_clk ) begin
|
if( vhf_clk && dump_text ) begin
|
$display("%d, %d, %d, %d, %d, %d",
|
$display("%d, %d, %d, %d, %d, %d",
|
pwm0_a, pwm0_b, pwm0_c, pwm1_a, pwm1_b, pwm1_c );
|
pwm0_a, pwm0_b, pwm0_c, pwm1_a, pwm1_b, pwm1_c );
|
end
|
end
|
#10 vhf_clk <= ~vhf_clk; // 50MHz
|
#10 vhf_clk <= ~vhf_clk; // 50MHz
|
end
|
end
|
Line 88... |
Line 90... |
SQM_PWM_1 a1pwm( .clk(vhf_clk), .reset_n(reset_n), .din(ay1_a), .pwm(pwm1_a) );
|
SQM_PWM_1 a1pwm( .clk(vhf_clk), .reset_n(reset_n), .din(ay1_a), .pwm(pwm1_a) );
|
SQM_PWM_1 b1pwm( .clk(vhf_clk), .reset_n(reset_n), .din(ay1_b), .pwm(pwm1_b) );
|
SQM_PWM_1 b1pwm( .clk(vhf_clk), .reset_n(reset_n), .din(ay1_b), .pwm(pwm1_b) );
|
SQM_PWM_1 c1pwm( .clk(vhf_clk), .reset_n(reset_n), .din(ay1_c), .pwm(pwm1_c) );
|
SQM_PWM_1 c1pwm( .clk(vhf_clk), .reset_n(reset_n), .din(ay1_c), .pwm(pwm1_c) );
|
endmodule
|
endmodule
|
|
|
/////////////////////////////////////////////////////
|
|
module computer_1942
|
|
#(parameter dump_regs=0) // set to 1 to dump sqmusic registers
|
|
(
|
|
input clk,
|
|
input sound_clk,
|
|
input reset_n,
|
|
input int_n,
|
|
output [3:0] ay0_a,
|
|
output [3:0] ay0_b,
|
|
output [3:0] ay0_c,
|
|
output [3:0] ay1_a,
|
|
output [3:0] ay1_b,
|
|
output [3:0] ay1_c
|
|
);
|
|
reg wait_n, nmi_n, busrq_n;
|
|
|
|
wire [7:0]cpu_in, cpu_out;
|
|
wire [15:0]adr;
|
|
wire m1_n, mreq_n, iorq_n, rd_n, wr_n, rfsh_n, halt_n, busak_n;
|
|
wire bus_error;
|
|
|
|
|
|
wire [3:0] ay0_a, ay0_b, ay0_c, ay1_a, ay1_b, ay1_c;
|
|
wire [15:0] amp0_y, amp1_y;
|
|
|
|
wire [7:0]ram_out, rom_out, latch_out;
|
|
wire rom_enable = adr<16'h4000 ? 1:0;
|
|
wire ram_enable = adr>=16'h4000 && adr<16'h4800 ? 1:0;
|
|
wire latch_enable = adr==16'h6000 ? 1 : 0;
|
|
wire ay_0_enable = adr==16'h8000 || adr==16'h8001 ? 1:0;
|
|
wire ay_1_enable = adr==16'hC000 || adr==16'hC001 ? 1:0;
|
|
assign bus_error = ~ram_enable & ~rom_enable & ~latch_enable &
|
|
~ay_0_enable & ~ay_1_enable;
|
|
assign cpu_in=ram_out | rom_out | latch_out;
|
|
/*
|
|
always @(negedge rd_n)
|
|
if( !rd_n && adr==8'h38 )
|
|
$display("IRQ processing started @ %t us",$time/1e6);
|
|
*/
|
|
initial begin
|
|
nmi_n=1;
|
|
wait_n=1;
|
|
end
|
|
|
|
tv80n cpu( //outputs
|
|
.m1_n(m1_n), .mreq_n(mreq_n), .iorq_n(iorq_n), .rd_n(rd_n), .wr_n(wr_n),
|
|
.rfsh_n(rfsh_n), .halt_n(halt_n), .busak_n(busak_n), .A(adr), .do(cpu_out),
|
|
// Inputs
|
|
.reset_n(reset_n), .clk(clk), .wait_n(wait_n),
|
|
.int_n(int_n), .nmi_n(nmi_n), .busrq_n(busrq_n), .di(cpu_in) );
|
|
|
|
RAM ram(.adr(adr[10:0]), .din(cpu_out), .dout(ram_out), .enable( ram_enable ),
|
|
.clk(clk), .wr_n(wr_n), .rd_n(rd_n) );
|
|
ROM rom(.adr(adr[13:0]), .data(rom_out), .enable(rom_enable),
|
|
.rd_n(rd_n), .clk(clk));
|
|
SOUND_LATCH sound_latch( .dout(latch_out), .enable(latch_enable),
|
|
.clk(clk), .rd_n(rd_n) );
|
|
|
|
// fake_ay ay_0( .adr(adr[0]), .din(din), .clk(clk), .wr_n(~ay_0_enable|wr_n) );
|
|
|
|
AY_3_8910_capcom #(dump_regs,0) ay_0( .reset_n(reset_n), .clk(clk), .sound_clk(sound_clk),
|
|
.din(cpu_out), .adr(adr[0]), .wr_n(wr_n), .cs_n(~ay_0_enable),
|
|
.A(ay0_a), .B(ay0_b), .C(ay0_c) );
|
|
AY_3_8910_capcom #(dump_regs,1) ay_1( .reset_n(reset_n), .clk(clk), .sound_clk(sound_clk),
|
|
.din(cpu_out), .adr(adr[0]), .wr_n(wr_n), .cs_n(~ay_1_enable),
|
|
.A(ay1_a), .B(ay1_b), .C(ay1_c) );
|
|
endmodule
|
|
|
|
//////////////////////////////////////////////////////////
|
|
// this module is used to check the communication of the
|
|
// Z80 with the AY-3-8910
|
|
// only used for debugging
|
|
module fake_ay(
|
|
input adr,
|
|
input [7:0] din,
|
|
input clk,
|
|
input wr_n );
|
|
|
|
reg [7:0] contents[1:0];
|
|
wire sample = clk & ~wr_n;
|
|
|
|
always @(posedge sample) begin
|
|
// if( contents[adr] != din ) begin
|
|
$display("%t -> %d = %d", $realtime/1e6, adr, din );
|
|
if( !adr && din>15 ) $display("AY WARNING");
|
|
contents[adr] = din;
|
|
end
|
|
|
|
endmodule
|
|
|
|
//////////////////////////////////////////////////////////
|
|
module RAM(
|
|
input [10:0] adr,
|
|
input [7:0] din,
|
|
output reg [7:0] dout,
|
|
input enable,
|
|
input clk,
|
|
input rd_n,
|
|
input wr_n );
|
|
|
|
reg [7:0] contents[2047:0];
|
|
wire sample = clk & (~rd_n | ~wr_n );
|
|
|
|
initial dout=0;
|
|
|
|
always @(posedge sample) begin
|
|
if( !enable )
|
|
dout=0;
|
|
else begin
|
|
if( !wr_n ) contents[adr]=din;
|
|
if( !rd_n ) dout=contents[adr];
|
|
end
|
|
end
|
|
endmodule
|
|
|
|
//////////////////////////////////////////////////////////
|
|
module ROM(
|
|
input [13:0] adr,
|
|
output reg [7:0] data,
|
|
input enable,
|
|
input rd_n,
|
|
input clk );
|
|
|
|
reg [7:0] contents[16383:0];
|
|
|
|
wire sample = clk & ~rd_n;
|
|
|
|
initial begin
|
|
$readmemh("../rom/sr-01.c11.hex", contents ); // this is the hex dump of the ROM
|
|
data=0;
|
|
end
|
|
|
|
always @( posedge sample ) begin
|
|
if ( !enable )
|
|
data=0;
|
|
else
|
|
data=contents[ adr ];
|
|
end
|
|
endmodule
|
|
|
|
//////////////////////////////////////////////////////////
|
|
module SOUND_LATCH(
|
|
output reg [7:0] dout,
|
|
input enable,
|
|
input clk,
|
|
input rd_n );
|
|
|
|
wire sample = clk & ~rd_n;
|
|
reg [7:0]data;
|
|
|
|
initial begin
|
|
dout=0;
|
|
data=0;
|
|
#100e6 data=8'h12; // enter the song/sound code here
|
|
end
|
|
|
|
always @(posedge sample) begin
|
|
if( !enable )
|
|
dout=0;
|
|
else begin
|
|
if( !rd_n ) begin
|
|
// $display("Audio latch read @ %t us", $realtime/1e6 );
|
|
// if( data != 0 )
|
|
// $display("Audio latch read (%X) @ %t us", data, $realtime/1e6 );
|
|
dout=data;
|
|
end
|
|
end
|
|
end
|
|
endmodule
|
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|