1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-04-14 07:29:37 +00:00

Merge pull request #152 from gyurco/master

M72 + ExpressRaider + Druaga fixes
This commit is contained in:
Marcel
2022-12-12 14:02:35 +01:00
committed by GitHub
14 changed files with 247 additions and 123 deletions

View File

@@ -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 ),

View File

@@ -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;

View File

@@ -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

View File

@@ -65,7 +65,7 @@
<!-- mcu -->
<part>04 00 10 00</part>
<part name="ad_c-pr-.ic1" crc="8785e4e2"/>
<part name="ad_c-pr-c.ic1" crc="8785e4e2"/>
<!-- samples -->
<part>05 02 00 00</part>

View File

@@ -14,7 +14,7 @@
<buttons default="B,A,R,L" names="Fire,Secondary,-,-,Start,Coin,P2 Start,Pause"></buttons>
<switches default="04,02" base="16" page_id="1" page_name="Switches">
<dip bits="0,1" ids="3,2,4,1" name="Lives"></dip>
<dip bits="2" ids="Off,On" name="Demo Sounds"></dip>
<dip bits="2" ids="On,Off" name="Demo Sounds"></dip>
<dip bits="3" ids="80K,100K" name="Bonus Life"></dip>
<dip bits="4,7" ids="1C/1P,2C/1P,3C/1P,4C/1P,5C/1P,6C/1P,1C/2P,1C/3P,1C/4P,1C/5P,1C/6P,2C/3P,4C/2P,5C/3P,8C/3P,Free Play" name="Coin Mode"></dip>
<dip bits="8" ids="Off,On" name="Flip Picture"></dip>

View File

@@ -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 ]

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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

68
common/CPU/T65/README Normal file
View File

@@ -0,0 +1,68 @@
-- 65xx compatible microprocessor core
--
-- Copyright (c) 2002...2015
-- Daniel Wallner (jesus <at> opencores <dot> org)
-- Mike Johnson (mikej <at> fpgaarcade <dot> com)
-- Wolfgang Scherr (WoS <at> pin4 <dot> 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 -----
--

View File

@@ -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]

View File

@@ -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

View File

@@ -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