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