diff --git a/cores/Spectrum/audio_management.v b/cores/Spectrum/audio_management.v index 86c427e..883991a 100644 --- a/cores/Spectrum/audio_management.v +++ b/cores/Spectrum/audio_management.v @@ -19,68 +19,83 @@ // ////////////////////////////////////////////////////////////////////////////////// -`define MSBI 9 // Most significant Bit of DAC input +`define MSBI 7 // Most significant Bit of DAC input //This is a Delta-Sigma Digital to Analog Converter module dac (DACout, DACin, Clk, Reset); - output DACout; // This is the average output that feeds low pass filter - input [`MSBI:0] DACin; // DAC input (excess 2**MSBI) - input Clk; - input Reset; + output DACout; // This is the average output that feeds low pass filter + input [`MSBI:0] DACin; // DAC input (excess 2**MSBI) + input Clk; + input Reset; - reg DACout; // for optimum performance, ensure that this ff is in IOB - reg [`MSBI+2:0] DeltaAdder; // Output of Delta adder - reg [`MSBI+2:0] SigmaAdder; // Output of Sigma adder - reg [`MSBI+2:0] SigmaLatch = 1'b1 << (`MSBI+1); // Latches output of Sigma adder - reg [`MSBI+2:0] DeltaB; // B input of Delta adder + reg DACout; // for optimum performance, ensure that this ff is in IOB + reg [`MSBI+2:0] DeltaAdder; // Output of Delta adder + reg [`MSBI+2:0] SigmaAdder; // Output of Sigma adder + reg [`MSBI+2:0] SigmaLatch = 1'b1 << (`MSBI+1); // Latches output of Sigma adder + reg [`MSBI+2:0] DeltaB; // B input of Delta adder - always @(SigmaLatch) DeltaB = {SigmaLatch[`MSBI+2], SigmaLatch[`MSBI+2]} << (`MSBI+1); - always @(DACin or DeltaB) DeltaAdder = DACin + DeltaB; - always @(DeltaAdder or SigmaLatch) SigmaAdder = DeltaAdder + SigmaLatch; - always @(posedge Clk or posedge Reset) - begin - if(Reset) - begin - SigmaLatch <= #1 1'b1 << (`MSBI+1); - DACout <= #1 1'b0; - end - else - begin - SigmaLatch <= #1 SigmaAdder; - DACout <= #1 SigmaLatch[`MSBI+2]; - end - end + always @(SigmaLatch) DeltaB = {SigmaLatch[`MSBI+2], SigmaLatch[`MSBI+2]} << (`MSBI+1); + always @(DACin or DeltaB) DeltaAdder = DACin + DeltaB; + always @(DeltaAdder or SigmaLatch) SigmaAdder = DeltaAdder + SigmaLatch; + always @(posedge Clk) + begin + if(Reset) + begin + SigmaLatch <= #1 1'b1 << (`MSBI+1); + DACout <= #1 1'b0; + end + else + begin + SigmaLatch <= #1 SigmaAdder; + DACout <= #1 SigmaLatch[`MSBI+2]; + end + end endmodule module mixer ( - input wire clkdac, - input wire reset, - input wire ear, - input wire mic, - input wire spk, - input wire [7:0] ay1, - input wire [7:0] ay2, - output wire audio - ); + input wire clkdac, + input wire reset, + input wire ear, + input wire mic, + input wire spk, + input wire [7:0] ay1, + input wire [7:0] ay2, + output wire audio + ); - reg [9:0] mezcla = 10'h000; - wire [7:0] beeper = ({ear,spk,mic}==3'b000)? 8'd17 : - ({ear,spk,mic}==3'b001)? 8'd36 : - ({ear,spk,mic}==3'b010)? 8'd184 : - ({ear,spk,mic}==3'b011)? 8'd192 : - ({ear,spk,mic}==3'b100)? 8'd22 : - ({ear,spk,mic}==3'b101)? 8'd48 : - ({ear,spk,mic}==3'b110)? 8'd244 : 8'd255; + parameter + SRC_BEEPER = 2'd0, + SRC_AY1 = 2'd1, + SRC_AY2 = 2'd2; - wire [9:0] mezcla10bits = {2'b00,ay1} + {2'b00,ay2} + {2'b00,beeper} ; + wire [7:0] beeper = ({ear,spk,mic}==3'b000)? 8'd17 : + ({ear,spk,mic}==3'b001)? 8'd36 : + ({ear,spk,mic}==3'b010)? 8'd184 : + ({ear,spk,mic}==3'b011)? 8'd192 : + ({ear,spk,mic}==3'b100)? 8'd22 : + ({ear,spk,mic}==3'b101)? 8'd48 : + ({ear,spk,mic}==3'b110)? 8'd244 : 8'd255; + + reg [7:0] mezcla; + reg [3:0] cntsamples = 4'd0; + reg [1:0] sndsource = 2'd0; + + always @(posedge clkdac) begin + if (cntsamples == 4'd0) begin // cada 256 cuentas de reloj, cambiamos de fuente de sonido + case (sndsource) + SRC_BEEPER: mezcla <= beeper; + SRC_AY1 : mezcla <= ay1; + SRC_AY2 : mezcla <= ay2; + endcase + sndsource <= (sndsource == 2'd2)? 2'd0 : sndsource + 2'd1; // en lugar de sumar, multiplexamos en el tiempo las fuentes de sonido + end + cntsamples <= cntsamples + 4'd1; + end - always @(posedge clkdac) - mezcla <= mezcla10bits; - - dac audio_dac ( - .DACout(audio), - .DACin(mezcla), - .Clk(clkdac), - .Reset(reset) - ); + dac audio_dac ( + .DACout(audio), + .DACin(mezcla), + .Clk(clkdac), + .Reset(reset) + ); endmodule diff --git a/cores/Spectrum/cuatro_relojes.v b/cores/Spectrum/cuatro_relojes.v index 5b911ce..780f79e 100644 --- a/cores/Spectrum/cuatro_relojes.v +++ b/cores/Spectrum/cuatro_relojes.v @@ -8,7 +8,7 @@ module clock_generator input wire CLK_IN1, input wire CPUContention, input wire [2:0] pll_option, - input wire turbo_enable, + input wire [1:0] turbo_enable, // Clock out ports output wire CLK_OUT1, output wire CLK_OUT2, @@ -17,8 +17,6 @@ module clock_generator output wire cpuclk ); - wire cpuclk_selected; - reg [2:0] pll_option_stored = 3'b000; reg [7:0] pulso_reconf = 8'h01; // force initial reset at boot always @(posedge CLK_IN1) begin @@ -56,19 +54,87 @@ module clock_generator .CLK3OUT(CLK_OUT4) ); - BUFGMUX cpuclk_selector ( - .O(cpuclk_selected), +// wire clk28, clk14, clk7, clk3d5, cpuclk_3_2, cpuclk_1_0; +// +// BUFGMUX reloj28_contenido ( +// .O(clk28), +// .I0(CLK_OUT1), +// .I1(1'b1), +// .S(CPUContention) +// ); +// +// BUFGMUX reloj14_contenido ( +// .O(clk14), +// .I0(CLK_OUT2), +// .I1(1'b1), +// .S(CPUContention) +// ); +// +// BUFGMUX reloj7_contenido ( +// .O(clk7), +// .I0(CLK_OUT3), +// .I1(1'b1), +// .S(CPUContention) +// ); +// +// BUFGMUX reloj3d5_contenido ( +// .O(clk3d5), +// .I0(CLK_OUT4), +// .I1(1'b1), +// .S(CPUContention) +// ); +// +// BUFGMUX speed_3_and_2 ( // 28MHz and 14MHz for CPU +// .O(cpuclk_3_2), +// .I0(clk14), +// .I1(clk28), +// .S(turbo_enable[0]) +// ); +// +// BUFGMUX speed_1_and_0 ( // 7MHz and 3.5MHz for CPU +// .O(cpuclk_1_0), +// .I0(clk3d5), +// .I1(clk7), +// .S(turbo_enable[0]) +// ); +// +// BUFGMUX cpuclk_selector ( +// .O(cpuclk), +// .I0(cpuclk_1_0), +// .I1(cpuclk_3_2), +// .S(turbo_enable[1]) +// ); + + + wire cpuclk_selected, cpuclk_3_2, cpuclk_1_0; + +// BUFGMUX speed_3_and_2 ( // 28MHz and 14MHz for CPU +// .O(cpuclk_3_2), +// .I0(CLK_OUT2), +// .I1(CLK_OUT1), +// .S(turbo_enable[0]) +// ); + + BUFGMUX speed_1_and_0 ( // 7MHz and 3.5MHz for CPU + .O(cpuclk_1_0), .I0(CLK_OUT4), .I1(CLK_OUT3), - .S(turbo_enable) + .S(turbo_enable[0]) ); - BUFGMUX selector_reloj_cpu ( + BUFGMUX cpuclk_selector ( + .O(cpuclk_selected), + .I0(cpuclk_1_0), + .I1(CLK_OUT2), + .S(turbo_enable[1]) + ); + + BUFGMUX aplicar_contienda ( .O(cpuclk), .I0(cpuclk_selected), // when no contention, clock is this one .I1(1'b1), // during contention, clock is pulled up .S(CPUContention) // contention signal ); - + endmodule diff --git a/cores/Spectrum/flash_spi.v b/cores/Spectrum/flash_spi.v index db0856a..3780ab3 100644 --- a/cores/Spectrum/flash_spi.v +++ b/cores/Spectrum/flash_spi.v @@ -22,7 +22,7 @@ ////////////////////////////////////////////////////////////////////////////////// module flash_and_sd ( - input wire clk, // 7MHz + input wire clk, // input wire [15:0] a, // input wire iorq_n, // Señales de control de E/S estándar input wire rd_n, // para manejar los puertos ZXMMC y DIVMMC @@ -40,6 +40,7 @@ module flash_and_sd ( output wire flash_di, // input wire flash_do, // + input wire disable_spisd, output wire sd_cs_n, // output wire sd_clk, // Interface SPI con la SD/MMC output wire sd_mosi, // (de momento, solo puertos ZXMMC) @@ -74,7 +75,7 @@ module flash_and_sd ( flashpincs <= din[0]; sdpincs <= 1'b1; // si accedemos a la flash para cambiar su estado CS, automaticamente deshabilitamos la SD end - else if (!iorq_n && (a[7:0]==SDCS || a[7:0]==DIVCS) && !wr_n) begin + else if (!disable_spisd && !iorq_n && (a[7:0]==SDCS || a[7:0]==DIVCS) && !wr_n) begin sdpincs <= din[0]; flashpincs <= 1'b1; // y lo mismo hacemos si es la SD a la que estamos accediendo end @@ -84,11 +85,11 @@ module flash_and_sd ( reg enviar_dato; reg recibir_dato; always @* begin - if ((addr==SPIPORT && ior && in_boot_mode) || (!iorq_n && (a[7:0]==SDSPI || a[7:0]==DIVSPI) && !rd_n)) + if ((addr==SPIPORT && ior && in_boot_mode) || (!disable_spisd && !iorq_n && (a[7:0]==SDSPI || a[7:0]==DIVSPI) && !rd_n)) recibir_dato = 1'b1; else recibir_dato = 1'b0; - if ((addr==SPIPORT && iow && in_boot_mode) || (!iorq_n && (a[7:0]==SDSPI || a[7:0]==DIVSPI) && !wr_n)) + if ((addr==SPIPORT && iow && in_boot_mode) || (!disable_spisd && !iorq_n && (a[7:0]==SDSPI || a[7:0]==DIVSPI) && !wr_n)) enviar_dato = 1'b1; else enviar_dato = 1'b0; diff --git a/cores/Spectrum/multiboot.v b/cores/Spectrum/multiboot.v index 2d8906f..72700ed 100644 --- a/cores/Spectrum/multiboot.v +++ b/cores/Spectrum/multiboot.v @@ -223,31 +223,12 @@ always @* end GEN2_L: - begin - next_state = MOD_H; - icap_ce = 0; - icap_wr = 0; - icap_din = {8'h6B, spi_addr[23:16]}; // 16'h030A; // 03 lectura SPI opcode + direccion SPI ALTA (03 = 1x, 6B = 4x) - end - -/////// Registro MODE (para carga a 4x tras reboot) - - MOD_H: - begin - next_state = MOD_L; - icap_ce = 0; - icap_wr = 0; - icap_din = 16'h3301; // Escritura a reg MODE - end - - MOD_L: begin next_state = NUL_L; icap_ce = 0; icap_wr = 0; - icap_din = 16'h3100; // Activamos bit de lectura a modo 4x en el proceso de Config - end -///// + icap_din = {8'h03, spi_addr[23:16]}; // 16'h030A; // 03 lectura SPI opcode + direccion SPI ALTA + end NUL_L: begin diff --git a/cores/Spectrum/scandoubler_ctrl.v b/cores/Spectrum/scandoubler_ctrl.v index 6903e09..6b7ddab 100644 --- a/cores/Spectrum/scandoubler_ctrl.v +++ b/cores/Spectrum/scandoubler_ctrl.v @@ -34,7 +34,7 @@ module scandoubler_ctrl ( output wire vga_enable, output wire scanlines_enable, output wire [2:0] freq_option, - output wire turbo_enable + output wire [1:0] turbo_enable ); parameter SCANDBLCTRL = 8'h0B; @@ -45,14 +45,14 @@ module scandoubler_ctrl ( assign vga_enable = scandblctrl[0]; assign scanlines_enable = scandblctrl[1]; assign freq_option = scandblctrl[4:2]; - assign turbo_enable = scandblctrl[7]; + assign turbo_enable = scandblctrl[7:6]; reg [7:0] scandblctrl = 8'h00; // initial value always @(posedge clk) begin if (zxuno_addr == SCANDBLCTRL && zxuno_regwr == 1'b1) scandblctrl <= din; else if (iorq_n == 1'b0 && wr_n == 1'b0 && a == PRISMSPEEDCTRL) - scandblctrl[7] <= (din[3:0] == 4'b0000)? 1'b0 : 1'b1; + scandblctrl[7:6] <= din[1:0]; dout <= scandblctrl; end endmodule diff --git a/cores/Spectrum/tld_zxuno.v b/cores/Spectrum/tld_zxuno.v index 287fed2..0ba4ab0 100644 --- a/cores/Spectrum/tld_zxuno.v +++ b/cores/Spectrum/tld_zxuno.v @@ -63,7 +63,7 @@ module tld_zxuno ( wire wssclk,sysclk,clk14,clk7,clk3d5,cpuclk; wire CPUContention; - wire turbo_enable; + wire [1:0] turbo_enable; wire [2:0] pll_frequency_option; assign wssclk = 1'b0; // de momento, sin WSS diff --git a/cores/Spectrum/turbosound.v b/cores/Spectrum/turbosound.v index 884cd5a..7b6deef 100644 --- a/cores/Spectrum/turbosound.v +++ b/cores/Spectrum/turbosound.v @@ -24,6 +24,8 @@ module turbosound ( input wire clk, input wire clkay, input wire reset_n, + input wire disable_ay, + input wire disable_turboay, input wire bdir, input wire bc1, input wire [7:0] din, @@ -37,7 +39,7 @@ module turbosound ( always @(posedge clk) begin if (reset_n==1'b0) ay_select <= 1'b1; - else if (bdir && bc1 && din[7:1]==7'b1111111) + else if (disable_ay == 1'b0 && disable_turboay == 1'b0 && bdir && bc1 && din[7:1]==7'b1111111) ay_select <= din[0]; end @@ -63,7 +65,7 @@ YM2149 ay1 ( .I_IOB(8'h00), .O_IOB(), .O_IOB_OE_L(), - .ENA(1'b1), + .ENA(~disable_ay), .RESET_L(reset_n), .CLK(clkay) ); @@ -85,7 +87,7 @@ YM2149 ay2 ( .I_IOB(8'h00), .O_IOB(), .O_IOB_OE_L(), - .ENA(1'b1), + .ENA(~disable_ay & ~disable_turboay), .RESET_L(reset_n), .CLK(clkay) ); diff --git a/cores/Spectrum/ula_radas.v b/cores/Spectrum/ula_radas.v index dd4847e..6d92acd 100644 --- a/cores/Spectrum/ula_radas.v +++ b/cores/Spectrum/ula_radas.v @@ -58,6 +58,7 @@ module ula_radas ( input wire disable_contention, input wire access_to_contmem, output wire doc_ext_option, + input wire enable_timexmmu, // Video output wire [2:0] r, @@ -179,7 +180,7 @@ module ula_radas ( wire PG = TimexConfigReg[0]; wire HCL = TimexConfigReg[1]; wire HR = TimexConfigReg[2]; - assign doc_ext_option = TimexConfigReg[7]; + assign doc_ext_option = enable_timexmmu & TimexConfigReg[7]; wire [2:0] HRInk = TimexConfigReg[5:3]; always @(posedge clk7) begin if (rst_n == 1'b0) @@ -444,10 +445,8 @@ module ula_radas ( // Z80 writes values into registers // Port 0xFE always @(posedge clk7) begin - if (iorq_n==1'b0 && wr_n==1'b0) begin - if (a[0]==1'b0 && a[7:0]!=8'hF4) begin - {spk,mic} <= din[4:3]; - end + if (WriteToPortFE) begin + {spk,mic} <= din[4:3]; end end @@ -494,11 +493,13 @@ module ula_radas ( dout = PaletteEntryToCPU; else if (a==ULAPLUSDATA && PaletteReg[6]==1'b1) dout = {7'b0000000,ConfigReg}; - else if (a[7:0]==TIMEXPORT) begin + else if (a[7:0]==TIMEXPORT && enable_timexmmu) + dout = TimexConfigReg; + else begin if (BitmapAddr || AttrAddr) - dout = vramdata; + dout = vramdata; else - dout = 8'hFF; + dout = 8'hFF; end end end diff --git a/cores/Spectrum/zxuno.v b/cores/Spectrum/zxuno.v index f02a0e1..34bfc51 100644 --- a/cores/Spectrum/zxuno.v +++ b/cores/Spectrum/zxuno.v @@ -65,7 +65,7 @@ module zxuno ( input wire joyleft, input wire joyright, input wire joyfire, - + // MOUSE inout wire mouseclk, inout wire mousedata, @@ -74,7 +74,7 @@ module zxuno ( output wire vga_enable, output wire scanlines_enable, output wire [2:0] freq_option, - output wire turbo_enable + output wire [1:0] turbo_enable ); // Señales de la CPU @@ -162,6 +162,18 @@ module zxuno ( wire [7:0] rasterint_dout; wire oe_n_rasterint; + // Device enable options + wire disable_ay; + wire disable_turboay; + wire disable_7ffd; + wire disable_1ffd; + wire disable_romsel7f; + wire disable_romsel1f; + wire enable_timexmmu; + wire disable_spisd; + wire [7:0] devoptions_dout; + wire oe_n_devoptions; + // NMI events wire [7:0] nmievents_dout; wire oe_n_nmievents; @@ -195,6 +207,7 @@ module zxuno ( (oe_n_mousedata==1'b0)? mousedata_dout : (oe_n_mousestatus==1'b0)? mousestatus_dout : (oe_n_rasterint==1'b0)? rasterint_dout : + (oe_n_devoptions==1'b0)? devoptions_dout : ula_dout; tv80n_wrapper el_z80 ( @@ -219,7 +232,7 @@ module zxuno ( ); ula_radas la_ula ( - // Clocks + // Clocks .clk14(clk14), // 14MHz master clock .clk7(clk7), .wssclk(wssclk), // 5MHz WSS clock @@ -227,15 +240,15 @@ module zxuno ( .CPUContention(CPUContention), .rst_n(mrst_n & rst_n & power_on_reset_n), - // CPU interface - .a(cpuaddr), + // CPU interface + .a(cpuaddr), .access_to_contmem(access_to_screen), - .mreq_n(mreq_n), - .iorq_n(iorq_n), - .rd_n(rd_n), - .wr_n(wr_n), - .int_n(int_n), - .din(cpudout), + .mreq_n(mreq_n), + .iorq_n(iorq_n), + .rd_n(rd_n), + .wr_n(wr_n), + .int_n(int_n), + .din(cpudout), .dout(ula_dout), .rasterint_enable(rasterint_enable), .vretraceint_disable(vretraceint_disable), @@ -245,7 +258,7 @@ module zxuno ( // VRAM interface .va(vram_addr), // 16KB videoram, 2 pages .vramdata(vram_dout), - + // I/O ports .ear(ear), .mic(mic), @@ -255,12 +268,13 @@ module zxuno ( .mode(timing_mode), .disable_contention(disable_contention), .doc_ext_option(doc_ext_option), + .enable_timexmmu(enable_timexmmu), // Video - .r(r), - .g(g), - .b(b), - .hsync(hsync), + .r(r), + .g(g), + .b(b), + .hsync(hsync), .vsync(vsync) ); @@ -281,7 +295,7 @@ module zxuno ( ); flash_and_sd cacharros_con_spi ( - .clk(clk14), + .clk(clk), .a(cpuaddr), .iorq_n(iorq_n), .rd_n(rd_n), @@ -298,7 +312,7 @@ module zxuno ( .flash_clk(flash_clk), .flash_di(flash_di), .flash_do(flash_do), - + .disable_spisd(disable_spisd), .sd_cs_n(sd_cs_n), .sd_clk(sd_clk), .sd_mosi(sd_mosi), @@ -344,6 +358,13 @@ module zxuno ( .ior(zxuno_regrd), .iow(zxuno_regwr), .in_boot_mode(in_boot_mode), + + // Interface con modulo de habilitacion de opciones + .disable_7ffd(disable_7ffd), + .disable_1ffd(disable_1ffd), + .disable_romsel7f(disable_romsel7f), + .disable_romsel1f(disable_romsel1f), + .enable_timexmmu(enable_timexmmu), // Interface con la SRAM .sram_addr(sram_addr), @@ -418,6 +439,25 @@ module zxuno ( .oe_n(oe_n_scratch) ); + control_enable_options device_enables ( + .clk(clk), + .rst_n(mrst_n & power_on_reset_n), + .zxuno_addr(zxuno_addr), + .zxuno_regrd(zxuno_regrd), + .zxuno_regwr(zxuno_regwr), + .din(cpudout), + .dout(devoptions_dout), + .oe_n(oe_n_devoptions), + .disable_ay(disable_ay), + .disable_turboay(disable_turboay), + .disable_7ffd(disable_7ffd), + .disable_1ffd(disable_1ffd), + .disable_romsel7f(disable_romsel7f), + .disable_romsel1f(disable_romsel1f), + .enable_timexmmu(enable_timexmmu), + .disable_spisd(disable_spisd) + ); + scandoubler_ctrl control_scandoubler ( .clk(clk), .a(cpuaddr), @@ -517,6 +557,8 @@ module zxuno ( turbosound dos_ays ( .clk(clk), .clkay(clk3d5), + .disable_ay(disable_ay), + .disable_turboay(disable_turboay), .reset_n(rst_n & mrst_n & power_on_reset_n), .bdir(bdir), .bc1(bc1), @@ -525,21 +567,21 @@ module zxuno ( .oe_n(oe_n_ay), .audio_out_ay1(ay1_audio), .audio_out_ay2(ay2_audio) - ); + ); /////////////////////////////////// // SOUND MIXER /////////////////////////////////// // 8-bit mixer to generate different audio levels according to input sources - mixer audio_mix( - .clkdac(clk), - .reset(1'b0), - .mic(mic), - .spk(spk), + mixer audio_mix( + .clkdac(clk), + .reset(1'b0), + .mic(mic), + .spk(spk), .ear(ear), .ay1(ay1_audio), - .ay2(ay2_audio), - .audio(audio_out) - ); + .ay2(ay2_audio), + .audio(audio_out) + ); endmodule