diff --git a/Arcade_MiST/Data East Express Raider/rtl/core.v b/Arcade_MiST/Data East Express Raider/rtl/core.v index 24c6fcaf..55b07b44 100644 --- a/Arcade_MiST/Data East Express Raider/rtl/core.v +++ b/Arcade_MiST/Data East Express Raider/rtl/core.v @@ -168,6 +168,7 @@ video u_video( .cpu_ab ( cpu_ab ), .cpu_dout ( cpu_dout ), .rw ( rw ), + .dma_swap ( dma_swap ), .sram_data ( sram_data ), .map_rom_addr ( map_rom_addr ), .map_data ( map_data ), diff --git a/Arcade_MiST/Data East Express Raider/rtl/video/video.v b/Arcade_MiST/Data East Express Raider/rtl/video/video.v index b0bf8ab0..a70b9250 100644 --- a/Arcade_MiST/Data East Express Raider/rtl/video/video.v +++ b/Arcade_MiST/Data East Express Raider/rtl/video/video.v @@ -12,8 +12,9 @@ module video( input [15:0] cpu_ab, input [7:0] cpu_dout, input rw, + input dma_swap, - output reg [7:0] sram_data, + output [7:0] sram_data, output [14:0] map_rom_addr, input [7:0] map_data, @@ -52,10 +53,6 @@ wire [7:0] sram1_q; wire [7:0] sram2_q; wire [7:0] sram3_q; wire [7:0] sram4_q; -wire [7:0] sram1_dout; -wire [7:0] sram2_dout; -wire [7:0] sram3_dout; -wire [7:0] sram4_dout; reg [7:0] scx1; // 10C reg [7:0] scx2; // 11C @@ -96,29 +93,62 @@ dpram #(12,8) u8C( // SRAM -wire sram_wr = sram_cs & ~rw; -wire sram1_en = cpu_ab[1:0] == 2'b00; -wire sram2_en = cpu_ab[1:0] == 2'b01; -wire sram3_en = cpu_ab[1:0] == 2'b10; -wire sram4_en = cpu_ab[1:0] == 2'b11; +reg [8:0] dma_a; +wire [7:0] sram_q; +reg dma_wr; -// must be synced to cpu clock if chip_6502 is used -// a typical symptom is the horse with static legs -always @(posedge clk_sys) - if (rw) - sram_data <= - sram1_en ? sram1_dout : - sram2_en ? sram2_dout : - sram3_en ? sram3_dout : - sram4_en ? sram4_dout : 8'hff; +wire sram_wr = sram_cs & ~rw; +wire sram1_en = dma_a[1:0] == 2'b00; +wire sram2_en = dma_a[1:0] == 2'b01; +wire sram3_en = dma_a[1:0] == 2'b10; +wire sram4_en = dma_a[1:0] == 2'b11; + +reg [1:0] dma_state; +always @(posedge clk_sys) begin + if (reset) begin + dma_state <= 0; + dma_wr <= 0; + end else begin + dma_wr <= 0; + + case (dma_state) + 0: begin + dma_a <= 0; + if (dma_swap) dma_state <= 1; + end + 1: begin + dma_wr <= 1; + dma_state <= 2; + end + 2: begin + dma_a <= dma_a + 1'd1; + if (dma_a == 9'h1FF) dma_state <= 0; // finished + else dma_state <= 3; + end + 3: dma_state <= 1; + endcase + end +end + +dpram #(9,8) sram( + .clock ( clk_sys ), + .address_a ( cpu_ab ), + .data_a ( cpu_dout ), + .q_a ( sram_data ), + .rden_a ( 1'b1 ), + .wren_a ( sram_wr ), + .address_b ( dma_a ), + .rden_b ( 1'b1 ), + .q_b ( sram_q ) +); dpram #(7,8) sram1( .clock ( ~clk_sys ), - .address_a ( cpu_ab[8:2] ), - .data_a ( cpu_dout ), - .q_a ( sram1_dout ), + .address_a ( dma_a[8:2] ), + .data_a ( sram_q ), + .q_a ( ), .rden_a ( 1'b1 ), - .wren_a ( sram_wr & sram1_en ), + .wren_a ( dma_wr & sram1_en ), .address_b ( sram_addr ), .rden_b ( 1'b1 ), .q_b ( sram1_q ) @@ -126,11 +156,11 @@ dpram #(7,8) sram1( dpram #(7,8) sram2( .clock ( ~clk_sys ), - .address_a ( cpu_ab[8:2] ), - .data_a ( cpu_dout ), - .q_a ( sram2_dout ), + .address_a ( dma_a[8:2] ), + .data_a ( sram_q ), + .q_a ( ), .rden_a ( 1'b1 ), - .wren_a ( sram_wr & sram2_en ), + .wren_a ( dma_wr & sram2_en ), .address_b ( sram_addr ), .rden_b ( 1'b1 ), .q_b ( sram2_q ) @@ -138,11 +168,11 @@ dpram #(7,8) sram2( dpram #(7,8) sram3( .clock ( ~clk_sys ), - .address_a ( cpu_ab[8:2] ), - .data_a ( cpu_dout ), - .q_a ( sram3_dout ), + .address_a ( dma_a[8:2] ), + .data_a ( sram_q ), + .q_a ( ), .rden_a ( 1'b1 ), - .wren_a ( sram_wr & sram3_en ), + .wren_a ( dma_wr & sram3_en ), .address_b ( sram_addr ), .rden_b ( 1'b1 ), .q_b ( sram3_q ) @@ -150,11 +180,11 @@ dpram #(7,8) sram3( dpram #(7,8) sram4( .clock ( ~clk_sys ), - .address_a ( cpu_ab[8:2] ), - .data_a ( cpu_dout ), - .q_a ( sram4_dout ), + .address_a ( dma_a[8:2] ), + .data_a ( sram_q ), + .q_a ( ), .rden_a ( 1'b1 ), - .wren_a ( sram_wr & sram4_en ), + .wren_a ( dma_wr & sram4_en ), .address_b ( sram_addr ), .rden_b ( 1'b1 ), .q_b ( sram4_q ) @@ -281,7 +311,7 @@ always @(posedge clk_sys) begin sxc <= 0; sp_rom_addr <= { sram2_q[7:5], id, flip, syc[3:0] }; next_state <= 2; - state <= 3;//7; + state <= 3; end else begin sram_addr <= sram_addr + 7'd1; @@ -298,7 +328,7 @@ always @(posedge clk_sys) begin if (sxc == 4'd7) begin sp_rom_addr <= { sram2_q[7:5], id, ~flip, syc[3:0] }; next_state <= 2; - state <= 3;//7; + state <= 3; end else if (sxc == 4'd15) begin sram_addr <= sram_addr + 7'd1; diff --git a/Arcade_MiST/IremM72 Hardware/IremM72.qsf b/Arcade_MiST/IremM72 Hardware/IremM72.qsf index 2ff1dbe2..18501f7f 100644 --- a/Arcade_MiST/IremM72 Hardware/IremM72.qsf +++ b/Arcade_MiST/IremM72 Hardware/IremM72.qsf @@ -132,7 +132,7 @@ set_global_assignment -name TOP_LEVEL_ENTITY IremM72_MiST set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8 set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP -set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED +set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE BALANCED set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON set_global_assignment -name ALLOW_SYNCH_CTRL_USAGE ON set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008 @@ -237,32 +237,12 @@ set_location_assignment PLL_1 -to pll|altpll_component|auto_generated|pll1 set_global_assignment -name DSP_BLOCK_BALANCING "DSP BLOCKS" set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING OFF set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION OFF -set_global_assignment -name AUTO_SHIFT_REGISTER_RECOGNITION OFF +set_global_assignment -name AUTO_SHIFT_REGISTER_RECOGNITION AUTO set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF set_global_assignment -name SYSTEMVERILOG_FILE rtl/IremM72_MiST.sv -set_global_assignment -name VERILOG_FILE rtl/build_id.v set_global_assignment -name QIP_FILE rtl/pll_mist.qip -set_global_assignment -name SYSTEMVERILOG_FILE rtl/ddr_debug.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/m72.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/pal.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/mcu.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/sample_rom.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/m72_pkg.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/m72_pic.sv -set_global_assignment -name VERILOG_FILE rtl/iir_filter.v -set_global_assignment -name VERILOG_FILE rtl/kna6034201.v -set_global_assignment -name VERILOG_FILE rtl/kna91h014.v -set_global_assignment -name SYSTEMVERILOG_FILE rtl/kna70h015.sv -set_global_assignment -name VERILOG_FILE rtl/jtframe_frac_cen.v -set_global_assignment -name SYSTEMVERILOG_FILE rtl/dualport_mailbox.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/dpramv.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/board_b_d_layer.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/board_b_d.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/sprite.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/sound.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram_4w.sv -set_global_assignment -name SYSTEMVERILOG_FILE rtl/rom.sv +set_global_assignment -name QIP_FILE rtl/m72.qip set_global_assignment -name QIP_FILE ../../common/mist/mist.qip set_global_assignment -name QIP_FILE ../../common/CPU/T80/T80.qip set_global_assignment -name QIP_FILE ../../common/CPU/v30/V30.qip @@ -271,4 +251,5 @@ set_global_assignment -name QIP_FILE ../../common/Sound/jt51/jt51.qip set_global_assignment -name SIGNALTAP_FILE output_files/cpu.stp set_global_assignment -name SIGNALTAP_FILE output_files/cpu2.stp set_global_assignment -name SIGNALTAP_FILE output_files/cpu3.stp +set_global_assignment -name AUTO_RESOURCE_SHARING ON set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/IremM72 Hardware/meta/Air Duel (World, M72 hardware).mra b/Arcade_MiST/IremM72 Hardware/meta/Air Duel (World, M72 hardware).mra index 1daf315b..e151b306 100644 --- a/Arcade_MiST/IremM72 Hardware/meta/Air Duel (World, M72 hardware).mra +++ b/Arcade_MiST/IremM72 Hardware/meta/Air Duel (World, M72 hardware).mra @@ -65,7 +65,7 @@ 04 00 10 00 - + 05 02 00 00 diff --git a/Arcade_MiST/IremM72 Hardware/meta/Mr. HELI no Daibouken (Japan).mra b/Arcade_MiST/IremM72 Hardware/meta/Mr. HELI no Daibouken (Japan).mra index c95959de..fdebc2ca 100644 --- a/Arcade_MiST/IremM72 Hardware/meta/Mr. HELI no Daibouken (Japan).mra +++ b/Arcade_MiST/IremM72 Hardware/meta/Mr. HELI no Daibouken (Japan).mra @@ -14,7 +14,7 @@ - + diff --git a/Arcade_MiST/IremM72 Hardware/rtl/m72.qip b/Arcade_MiST/IremM72 Hardware/rtl/m72.qip new file mode 100644 index 00000000..6f4b11f4 --- /dev/null +++ b/Arcade_MiST/IremM72 Hardware/rtl/m72.qip @@ -0,0 +1,20 @@ +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ./kna91h014.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ./iir_filter.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ./kna6034201.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) ./jtframe_frac_cen.v ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./rom.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./pal.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./sample_rom.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./board_b_d.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./m72_pkg.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./sound.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./kna70h015.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./ddr_debug.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./mcu.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./dualport_mailbox.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./m72_pic.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./sprite.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./dpramv.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./m72.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./sdram_4w.sv ] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) ./board_b_d_layer.sv ] diff --git a/Arcade_MiST/IremM72 Hardware/rtl/sprite.sv b/Arcade_MiST/IremM72 Hardware/rtl/sprite.sv index dca16b0e..1c0a5744 100644 --- a/Arcade_MiST/IremM72 Hardware/rtl/sprite.sv +++ b/Arcade_MiST/IremM72 Hardware/rtl/sprite.sv @@ -268,7 +268,6 @@ module line_buffer( output reg [7:0] pixel_out ); -reg scan_buffer; reg [9:0] scan_pos = 0; wire [9:0] scan_pos_nl = scan_pos ^ {10{NL}}; reg [7:0] line_pixel; @@ -281,13 +280,13 @@ dpramv #(.widthad_a(10)) buffer_0 .clock_a(CLK_32M), .address_a(scan_pos_nl), .q_a(scan_0), - .wren_a(!scan_buffer && CE_PIX), + .wren_a(!V0 && CE_PIX), .data_a(8'd0), .clock_b(CLK_96M), .address_b(line_position), .data_b(line_pixel), - .wren_b(scan_buffer && line_write), + .wren_b(V0 && line_write), .q_b() ); @@ -296,13 +295,13 @@ dpramv #(.widthad_a(10)) buffer_1 .clock_a(CLK_32M), .address_a(scan_pos_nl), .q_a(scan_1), - .wren_a(scan_buffer && CE_PIX), + .wren_a(V0 && CE_PIX), .data_a(8'd0), .clock_b(CLK_96M), .address_b(line_position), .data_b(line_pixel), - .wren_b(!scan_buffer && line_write), + .wren_b(!V0 && line_write), .q_b() ); @@ -336,9 +335,8 @@ always_ff @(posedge CLK_32M) begin if (old_v0 != V0) begin scan_pos <= 249; // TODO why? old_v0 <= V0; - scan_buffer <= ~scan_buffer; end else if (CE_PIX) begin - pixel_out <= scan_buffer ? scan_1 : scan_0; + pixel_out <= V0 ? scan_1 : scan_0; scan_pos <= scan_pos + 10'd1; end end diff --git a/Arcade_MiST/Namco Super Pacman Hardware/rtl/druaga_video.v b/Arcade_MiST/Namco Super Pacman Hardware/rtl/druaga_video.v index 389c4fa3..e2589230 100644 --- a/Arcade_MiST/Namco Super Pacman Hardware/rtl/druaga_video.v +++ b/Arcade_MiST/Namco Super Pacman Hardware/rtl/druaga_video.v @@ -17,7 +17,7 @@ module DRUAGA_VIDEO input [8:0] PV, output PCLK, output PCLK_EN, - output [7:0] POUT, // pixel colour output + output reg [7:0]POUT, // pixel colour output output VB, output [10:0] VRAM_A, @@ -134,9 +134,9 @@ DRUAGA_SPRITE spr //---------------------------------------- always @(posedge VCLKx8) if (VCLK_EN) begin PALT_A <= BGHI ? BGCOL : ((SPCOL[3:0]==4'd15) ? BGCOL : SPCOL ); + POUT <= PALT_D; end -assign POUT = oHB ? 8'd0 : PALT_D; assign PCLK = VCLK; assign PCLK_EN = VCLK_EN; diff --git a/Arcade_MiST/Namco Super Pacman Hardware/rtl/hvgen.v b/Arcade_MiST/Namco Super Pacman Hardware/rtl/hvgen.v index 322471a9..0e88f2c1 100644 --- a/Arcade_MiST/Namco Super Pacman Hardware/rtl/hvgen.v +++ b/Arcade_MiST/Namco Super Pacman Hardware/rtl/hvgen.v @@ -25,7 +25,7 @@ assign VPOS = vcnt; always @(posedge MCLK) begin if (PCLK_EN) case (hcnt) - 1: begin HBLK <= 0; hcnt <= hcnt+1'd1; end + 2: begin HBLK <= 0; hcnt <= hcnt+1'd1; end 290: begin HBLK <= 1; hcnt <= hcnt+1'd1; end 311: begin HSYN <= 0; hcnt <= hcnt+1'd1; end 342: begin HSYN <= 1; hcnt <= 9'd470; end diff --git a/Arcade_MiST/Namco Super Pacman Hardware/rtl/wsg.v b/Arcade_MiST/Namco Super Pacman Hardware/rtl/wsg.v index 0e03e6d6..db66eb27 100644 --- a/Arcade_MiST/Namco Super Pacman Hardware/rtl/wsg.v +++ b/Arcade_MiST/Namco Super Pacman Hardware/rtl/wsg.v @@ -36,12 +36,14 @@ reg [7:0] fm [0:7]; reg [3:0] fh [0:7]; reg [2:0] fv [0:7]; reg [3:0] v [0:7]; +reg [4:0] ct [0:7]; wire [2:0] ra = ADDR[5:3]; always @( posedge MCLK ) begin if ( CLK24M_EN & WE ) begin case ( ADDR[2:0] ) + 3'h2: ct[ra] <= DATA[4:0]; 3'h3: v[ra] <= DATA[3:0]; 3'h4: fl[ra] <= DATA; 3'h5: fm[ra] <= DATA; @@ -65,12 +67,12 @@ reg [7:0] o, ot; reg [19:0] c [0:7]; reg [7:0] wa; reg [3:0] wm; -reg en; wire [7:0] va = WAVE_DT * wm; wire [19:0] cx = c[phase]; wire [19:0] fq = { fh[phase], fm[phase], fl[phase] }; +wire [4:0] ctx = ct[phase]; assign WAVE_CLK = CLK_WSGx8; assign WAVE_AD = wa; @@ -78,16 +80,15 @@ assign WAVE_AD = wa; always @ ( posedge MCLK ) begin if (CLK_WSGx8_EN) begin if ( phase ) begin - ot <= ot + (en ? { 4'h0, va[7:4] } : 8'd0); + ot <= ot + { 4'h0, va[7:4] }; end else begin o <= ot; - ot <= (en ? { 4'h0, va[7:4] } : 8'd0); + ot <= { 4'h0, va[7:4] }; end c[phase] <= cx + fq; - en <= (fq!=0); wm <= v[phase]; - wa <= { fv[phase], cx[19:15] }; + wa <= { fv[phase], fq == 0 ? ctx[4:0] : cx[19:15] }; phase <= phase + 1'd1; end end diff --git a/common/CPU/T65/README b/common/CPU/T65/README new file mode 100644 index 00000000..c698998d --- /dev/null +++ b/common/CPU/T65/README @@ -0,0 +1,68 @@ +-- 65xx compatible microprocessor core +-- +-- Copyright (c) 2002...2015 +-- Daniel Wallner (jesus opencores org) +-- Mike Johnson (mikej fpgaarcade com) +-- Wolfgang Scherr (WoS pin4 at> +-- Morten Leikvoll () +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author(s), but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- ----- IMPORTANT NOTES ----- +-- +-- Limitations: +-- 65C02 and 65C816 modes are incomplete (and definitely untested after all 6502 undoc fixes) +-- 65C02 supported : inc, dec, phx, plx, phy, ply +-- 65D02 missing : bra, ora, lda, cmp, sbc, tsb*2, trb*2, stz*2, bit*2, wai, stp, jmp, bbr*8, bbs*8 +-- Some interface signals behave incorrect +-- NMI interrupt handling not nice, needs further rework (to cycle-based encoding). +-- +-- Usage: +-- The enable signal allows clock gating / throttling without using the ready signal. +-- Set it to constant '1' when using the Clk input as the CPU clock directly. +-- +-- TAKE CARE you route the DO signal back to the DI signal while R_W_n='0', +-- otherwise some undocumented opcodes won't work correctly. +-- EXAMPLE: +-- CPU : entity work.T65 +-- port map ( +-- R_W_n => cpu_rwn_s, +-- [....all other ports....] +-- DI => cpu_din_s, +-- DO => cpu_dout_s +-- ); +-- cpu_din_s <= cpu_dout_s when cpu_rwn_s='0' else +-- [....other sources from peripherals and memories...] +-- +-- ----- IMPORTANT NOTES ----- +-- diff --git a/common/CPU/T65/T65.qip b/common/CPU/T65/T65.qip index 09161f2d..3de9d396 100644 --- a/common/CPU/T65/T65.qip +++ b/common/CPU/T65/T65.qip @@ -1,4 +1,4 @@ -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T65.vhd ] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T65_MCode.vhd ] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T65_ALU.vhd ] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T65_Pack.vhd ] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T65_Pack.vhd] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T65_ALU.vhd] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T65_MCode.vhd] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T65.vhd] diff --git a/common/CPU/T65/T65.vhd b/common/CPU/T65/T65.vhd index c049d4a3..48f6942e 100644 --- a/common/CPU/T65/T65.vhd +++ b/common/CPU/T65/T65.vhd @@ -194,6 +194,8 @@ architecture rtl of T65 is signal RstCycle : std_logic; signal IRQCycle : std_logic; signal NMICycle : std_logic; + signal IRQReq : std_logic; + signal NMIReq : std_logic; signal SO_n_o : std_logic; signal IRQ_n_o : std_logic; @@ -354,6 +356,9 @@ begin MF_i <= '1'; XF_i <= '1'; + NMICycle <= '0'; + IRQCycle <= '0'; + elsif Clk'event and Clk = '1' then if (Enable = '1') then -- some instructions behavior changed by the Rdy line. Detect this at the correct cycles. @@ -376,16 +381,24 @@ begin Mode_r <= Mode; BCD_en_r <= BCD_en; - if IRQCycle = '0' and NMICycle = '0' then + if IRQReq = '0' and NMIReq = '0' then PC <= PC + 1; end if; - if IRQCycle = '1' or NMICycle = '1' then + if IRQReq = '1' or NMIReq = '1' then IR <= "00000000"; else IR <= DI; end if; + IRQCycle <= '0'; + NMICycle <= '0'; + if NMIReq = '1' then + NMICycle <= '1'; + elsif IRQReq = '1' then + IRQCycle <= '1'; + end if; + if LDS = '1' then -- LAS won't work properly if not limited to machine cycle 0 S(7 downto 0) <= unsigned(ALU_Q); end if; @@ -499,20 +512,12 @@ begin end if; - -- detect irq even if not rdy - if IR(4 downto 0)/="10000" or Jump/="01" or really_rdy = '0' then -- delay interrupts during branches (checked with Lorenz test and real 6510), not best way yet, though - but works... - IRQ_n_o <= IRQ_n; - end if; - -- detect nmi even if not rdy - if IR(4 downto 0)/="10000" or Jump/="01" then -- delay interrupts during branches (checked with Lorenz test and real 6510) not best way yet, though - but works... - NMI_n_o <= NMI_n; - end if; end if; -- act immediately on SO pin change -- The signal is sampled on the trailing edge of phi1 and must be externally synchronized (from datasheet) SO_n_o <= SO_n; - if SO_n_o = '1' and SO_n = '0' then - P(Flag_V) <= '1'; + if SO_n_o = '1' and SO_n = '0' then + P(Flag_V) <= '1'; end if; end if; @@ -671,29 +676,38 @@ begin if Res_n_i = '0' then MCycle <= "001"; RstCycle <= '1'; - IRQCycle <= '0'; - NMICycle <= '0'; NMIAct <= '0'; + IRQReq <= '0'; + NMIReq <= '0'; elsif Clk'event and Clk = '1' then if (Enable = '1') then if (really_rdy = '1') then if MCycle = LCycle or Break = '1' then MCycle <= "000"; RstCycle <= '0'; - IRQCycle <= '0'; - NMICycle <= '0'; - if NMIAct = '1' and IR/=x"00" then -- delay NMI further if we just executed a BRK - NMICycle <= '1'; - NMIAct <= '0'; -- reset NMI edge detector if we start processing the NMI - elsif IRQ_n_o = '0' and P(Flag_I) = '0' then - IRQCycle <= '1'; - end if; else MCycle <= std_logic_vector(unsigned(MCycle) + 1); end if; + + if (IR(4 downto 0)/="10000" or Jump/="11") then -- taken branches delay the interrupts + if NMIAct = '1' and IR/=x"00" then + NMIReq <= '1'; + else + NMIReq <= '0'; + end if; + if IRQ_n_o = '0' and P(Flag_I) = '0' then + IRQReq <= '1'; + else + IRQReq <= '0'; + end if; + end if; end if; + + IRQ_n_o <= IRQ_n; + NMI_n_o <= NMI_n; + --detect NMI even if not rdy - if NMI_n_o = '1' and (NMI_n = '0' and (IR(4 downto 0)/="10000" or Jump/="01")) then -- branches have influence on NMI start (not best way yet, though - but works...) + if NMI_n_o = '1' and NMI_n = '0' then NMIAct <= '1'; end if; -- we entered NMI during BRK instruction diff --git a/common/CPU/v30/cpu.vhd b/common/CPU/v30/cpu.vhd index 533b6981..f908b72f 100644 --- a/common/CPU/v30/cpu.vhd +++ b/common/CPU/v30/cpu.vhd @@ -336,6 +336,8 @@ architecture arch of cpu is signal adjustNegate : std_logic; signal enterCnt : unsigned(5 downto 0); signal bcdOffset : unsigned(6 downto 0); + signal bcdAccLow : unsigned(4 downto 0); + signal bcdAccHigh : unsigned(4 downto 0); signal bcdAcc : unsigned(7 downto 0); type tMemAccessType is @@ -511,6 +513,7 @@ begin variable result32 : unsigned(31 downto 0); variable result8 : unsigned(7 downto 0); variable result8h : unsigned(7 downto 0); + variable result9 : unsigned(8 downto 0); variable newZero : std_logic; variable newParity : std_logic; variable newSign : std_logic; @@ -544,7 +547,8 @@ begin variable newRepeat : std_logic; variable jumpNow : std_logic; variable jumpAddr : unsigned(15 downto 0); - variable bcdResult : unsigned(7 downto 0); + variable bcdResultLow : unsigned(4 downto 0); + variable bcdResultHigh : unsigned(4 downto 0); begin if rising_edge(clk) then @@ -1178,7 +1182,7 @@ begin -- #################################################################################### when CPUSTAGE_MODRM => - if (consumePrefetch = 0) then + if (consumePrefetch = 0 and prefetchCount > 2) then regs.reg_ip <= regs.reg_ip + 1; consumePrefetch <= 1; MODRM_mem := unsigned(prefetchBuffer(2 downto 0)); @@ -2207,24 +2211,26 @@ begin result := result32(15 downto 0); when ALU_OP_DECADJUST => - result8 := regs.reg_ax(7 downto 0); + result9 := resize(regs.reg_ax(7 downto 0), 9); + regs.FlagCar <= '0'; if (regs.FlagHaC = '1' or regs.reg_ax(3 downto 0) > x"9") then if (adjustNegate = '1') then - result8 := result8 - 6; + result9 := result9 - 6; else - result8 := result8 + 6; + result9 := result9 + 6; end if; regs.FlagHaC <= '1'; + regs.FlagCar <= flagCarry or result9(8); end if; - if (regs.FlagCar = '1' or regs.reg_ax(7 downto 0) > x"99") then + if (flagCarry = '1' or regs.reg_ax(7 downto 0) > x"99") then if (adjustNegate = '1') then - result8 := result8 - 16#60#; + result9 := result9 - 16#60#; else - result8 := result8 + 16#60#; + result9 := result9 + 16#60#; end if; regs.FlagCar <= '1'; end if; - result := x"00" & result8; + result := x"00" & result9(7 downto 0); newZero := '1'; newParity := '1'; newSign := '1'; when ALU_OP_ASCIIADJUST => @@ -2524,30 +2530,35 @@ begin when 5 => opstep <= 6; if (bcdOp = BCD_OP_ADD) then - bcdAcc <= unsigned(bus_dataread(7 downto 0)) + fetch1Val(7 downto 0); + bcdAccLow <= resize(unsigned(bus_dataread(3 downto 0)), 5) + resize(unsigned(fetch1Val(3 downto 0)), 5); + bcdAccHigh <= resize(unsigned(bus_dataread(7 downto 4)), 5) + resize(unsigned(fetch1Val(7 downto 4)), 5); else - bcdAcc <= unsigned(bus_dataread(7 downto 0)) - fetch1Val(7 downto 0); + bcdAccLow <= resize(unsigned(bus_dataread(3 downto 0)), 5) - resize(unsigned(fetch1Val(3 downto 0)), 5); + bcdAccHigh <= resize(unsigned(bus_dataread(7 downto 4)), 5) - resize(unsigned(fetch1Val(7 downto 4)), 5); end if; when 6 => opstep <= 7; - bcdResult := bcdAcc; - if (bcdResult(3 downto 0) > x"9") then + bcdResultLow := bcdAccLow; + bcdResultHigh := bcdAccHigh; + if (bcdResultLow > x"9") then if (bcdOp = BCD_OP_ADD) then - bcdResult := bcdResult + 6; + bcdResultLow := bcdResultLow + 6; + bcdResultHigh := bcdResultHigh + 1; else - bcdResult := bcdResult - 6; + bcdResultLow := bcdResultLow - 6; + bcdResultHigh := bcdResultHigh - 1; end if; end if; - if (bcdResult(7 downto 0) > x"99") then + if (bcdResultHigh > x"9") then if (bcdOp = BCD_OP_ADD) then - bcdResult := bcdResult + 16#60#; + bcdResultHigh := bcdResultHigh + 6; else - bcdResult := bcdResult - 16#60#; + bcdResultHigh := bcdResultHigh - 6; end if; regs.FlagCar <= '1'; end if; - bcdAcc <= bcdResult; + bcdAcc <= bcdResultHigh(3 downto 0) & bcdResultLow(3 downto 0); when 7 => if (bcdOp = BCD_OP_CMP) then