diff --git a/Arcade_MiST/Toaplan v1 Hardware/DemonsWorld.qsf b/Arcade_MiST/Toaplan v1 Hardware/DemonsWorld.qsf index 6b6ed19c..2a77a5d9 100644 --- a/Arcade_MiST/Toaplan v1 Hardware/DemonsWorld.qsf +++ b/Arcade_MiST/Toaplan v1 Hardware/DemonsWorld.qsf @@ -18,7 +18,7 @@ # # Quartus II 64-Bit # Version 13.1.4 Build 182 03/12/2014 SJ Full Version -# Date created = 12:41:19 July 08, 2023 +# Date created = 16:51:06 July 10, 2023 # # -------------------------------------------------------------------------- # # @@ -130,7 +130,7 @@ set_global_assignment -name FAMILY "Cyclone III" 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 TOP_LEVEL_ENTITY DemonsWorld_Top +set_global_assignment -name TOP_LEVEL_ENTITY DemonsWorld set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005 set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008 @@ -177,8 +177,8 @@ set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall -# ----------------------------- -# start ENTITY(DemonsWorld_Top) +# ------------------------- +# start ENTITY(DemonsWorld) # Pin & Location Assignments # ========================== @@ -229,17 +229,17 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" - # end DESIGN_PARTITION(Top) # ------------------------- -# end ENTITY(DemonsWorld_Top) -# --------------------------- +# end ENTITY(DemonsWorld) +# ----------------------- +set_global_assignment -name SYSTEMVERILOG_FILE rtl/rtl_demonsworld/DemonsWorld.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/rtl_demonsworld/DemonsWorld_Top.sv set_global_assignment -name VERILOG_FILE rtl/rtl_demonsworld/chip_select.v set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv -set_global_assignment -name VHDL_FILE rtl/pll_mist.vhd set_global_assignment -name QIP_FILE rtl/common/common.qip +set_global_assignment -name VERILOG_FILE rtl/pll_mist.v set_global_assignment -name QIP_FILE rtl/TMS320C1X/TMS320C1X.qip set_global_assignment -name QIP_FILE ../../common/Sound/jtopl/jt26.qip set_global_assignment -name QIP_FILE ../../common/CPU/T80/T80.qip set_global_assignment -name QIP_FILE ../../common/CPU/68000/FX68k/fx68k.qip set_global_assignment -name QIP_FILE ../../common/mist/mist.qip -set_global_assignment -name VERILOG_FILE rtl/pll_mist.v set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Toaplan v1 Hardware/RallyBike.qsf b/Arcade_MiST/Toaplan v1 Hardware/RallyBike.qsf index 30e083d9..c4bf5816 100644 --- a/Arcade_MiST/Toaplan v1 Hardware/RallyBike.qsf +++ b/Arcade_MiST/Toaplan v1 Hardware/RallyBike.qsf @@ -130,7 +130,7 @@ set_global_assignment -name FAMILY "Cyclone III" 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 TOP_LEVEL_ENTITY RallyBike_Top +set_global_assignment -name TOP_LEVEL_ENTITY RallyBike set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005 set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008 @@ -231,14 +231,14 @@ set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO +set_global_assignment -name SYSTEMVERILOG_FILE rtl/rtl_rallybike/RallyBike.sv set_global_assignment -name SYSTEMVERILOG_FILE rtl/rtl_rallybike/RallyBike_Top.sv set_global_assignment -name VERILOG_FILE rtl/rtl_rallybike/chip_select.v set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv -set_global_assignment -name VHDL_FILE rtl/pll_mist.vhd set_global_assignment -name QIP_FILE rtl/common/common.qip +set_global_assignment -name VERILOG_FILE rtl/pll_mist.v set_global_assignment -name QIP_FILE ../../common/Sound/jtopl/jt26.qip set_global_assignment -name QIP_FILE ../../common/CPU/T80/T80.qip set_global_assignment -name QIP_FILE ../../common/CPU/68000/FX68k/fx68k.qip set_global_assignment -name QIP_FILE ../../common/mist/mist.qip -set_global_assignment -name VERILOG_FILE rtl/pll_mist.v set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Toaplan v1 Hardware/Vimana.qsf b/Arcade_MiST/Toaplan v1 Hardware/Vimana.qsf index 33e18a6b..388d96e9 100644 --- a/Arcade_MiST/Toaplan v1 Hardware/Vimana.qsf +++ b/Arcade_MiST/Toaplan v1 Hardware/Vimana.qsf @@ -42,19 +42,8 @@ set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL set_global_assignment -name LAST_QUARTUS_VERSION 13.1 -set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" set_global_assignment -name SMART_RECOMPILE ON -set_global_assignment -name SYSTEMVERILOG_FILE rtl/rtl_vimana/Vimana_Top.sv -set_global_assignment -name VERILOG_FILE rtl/rtl_vimana/chip_select.v -set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv -set_global_assignment -name VHDL_FILE rtl/pll_mist.vhd -set_global_assignment -name QIP_FILE rtl/common/common.qip -set_global_assignment -name QIP_FILE ../../common/Sound/jtopl/jt26.qip -set_global_assignment -name QIP_FILE ../../common/CPU/T80/T80.qip -set_global_assignment -name QIP_FILE ../../common/CPU/68000/FX68k/fx68k.qip -set_global_assignment -name QIP_FILE ../../common/mist/mist.qip -set_global_assignment -name VERILOG_FILE rtl/pll_mist.v - +set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" # Pin & Location Assignments # ========================== set_location_assignment PIN_7 -to LED @@ -140,7 +129,7 @@ set_global_assignment -name FAMILY "Cyclone III" 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 TOP_LEVEL_ENTITY Vimana_Top +set_global_assignment -name TOP_LEVEL_ENTITY Vimana set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005 set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008 @@ -192,53 +181,63 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" - # Pin & Location Assignments # ========================== - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*] - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*] - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0] - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1] - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS - set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*] - set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*] # Fitter Assignments # ================== - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS - set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L - set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R - set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO # start DESIGN_PARTITION(Top) # --------------------------- # Incremental Compilation Assignments # =================================== - set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top - set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top - set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top # end DESIGN_PARTITION(Top) # ------------------------- # end ENTITY(RallyBike_Top) # ------------------------- +set_global_assignment -name SYSTEMVERILOG_FILE rtl/rtl_vimana/Vimana.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/rtl_vimana/Vimana_Top.sv +set_global_assignment -name VERILOG_FILE rtl/rtl_vimana/chip_select.v +set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv +set_global_assignment -name VERILOG_FILE rtl/pll_mist.v +set_global_assignment -name QIP_FILE rtl/common/common.qip +set_global_assignment -name QIP_FILE ../../common/Sound/jtopl/jt26.qip +set_global_assignment -name QIP_FILE ../../common/CPU/T80/T80.qip +set_global_assignment -name QIP_FILE ../../common/CPU/68000/FX68k/fx68k.qip +set_global_assignment -name QIP_FILE ../../common/mist/mist.qip +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Toaplan v1 Hardware/Zerowing.qsf b/Arcade_MiST/Toaplan v1 Hardware/Zerowing.qsf index f04631c0..ef4d0a07 100644 --- a/Arcade_MiST/Toaplan v1 Hardware/Zerowing.qsf +++ b/Arcade_MiST/Toaplan v1 Hardware/Zerowing.qsf @@ -42,17 +42,8 @@ set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL set_global_assignment -name LAST_QUARTUS_VERSION 13.1 -set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" set_global_assignment -name SMART_RECOMPILE ON -set_global_assignment -name SYSTEMVERILOG_FILE rtl/rtl_zerowing/Zerowing_Top.sv -set_global_assignment -name VERILOG_FILE rtl/rtl_zerowing/chip_select.v -set_global_assignment -name QIP_FILE rtl/common/common.qip -set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv -set_global_assignment -name VERILOG_FILE rtl/pll_mist.v -set_global_assignment -name QIP_FILE ../../common/CPU/T80/T80.qip -set_global_assignment -name QIP_FILE ../../common/mist/mist.qip -set_global_assignment -name QIP_FILE ../../common/Sound/jtopl/jt26.qip -set_global_assignment -name QIP_FILE ../../common/CPU/68000/FX68k/fx68k.qip +set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" # Pin & Location Assignments # ========================== @@ -139,7 +130,7 @@ set_global_assignment -name FAMILY "Cyclone III" 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 TOP_LEVEL_ENTITY Zerowing_Top +set_global_assignment -name TOP_LEVEL_ENTITY Zerowing set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005 set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008 @@ -191,53 +182,63 @@ set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" - # Pin & Location Assignments # ========================== - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*] - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*] - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0] - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1] - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE - set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS - set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*] - set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*] # Fitter Assignments # ================== - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[*] - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS - set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS - set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L - set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R - set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO # start DESIGN_PARTITION(Top) # --------------------------- # Incremental Compilation Assignments # =================================== - set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top - set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top - set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top # end DESIGN_PARTITION(Top) # ------------------------- # end ENTITY(Zerowing_Top) # ------------------------ +set_global_assignment -name SYSTEMVERILOG_FILE rtl/rtl_zerowing/Zerowing.sv +set_global_assignment -name SYSTEMVERILOG_FILE rtl/rtl_zerowing/Zerowing_Top.sv +set_global_assignment -name VERILOG_FILE rtl/rtl_zerowing/chip_select.v +set_global_assignment -name QIP_FILE rtl/common/common.qip +set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv +set_global_assignment -name VERILOG_FILE rtl/pll_mist.v +set_global_assignment -name QIP_FILE ../../common/CPU/T80/T80.qip +set_global_assignment -name QIP_FILE ../../common/mist/mist.qip +set_global_assignment -name QIP_FILE ../../common/Sound/jtopl/jt26.qip +set_global_assignment -name QIP_FILE ../../common/CPU/68000/FX68k/fx68k.qip +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[*] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to SDRAM_DQ[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_R[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_G[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_B[*] +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_HS +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to VGA_VS +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Toaplan v1 Hardware/rtl/pause.v b/Arcade_MiST/Toaplan v1 Hardware/rtl/pause.v deleted file mode 100644 index dda70467..00000000 --- a/Arcade_MiST/Toaplan v1 Hardware/rtl/pause.v +++ /dev/null @@ -1,103 +0,0 @@ -//============================================================================ -// Generic pause handling for MiSTer cores. -// -// https://github.com/JimmyStones/Pause_MiSTer -// -// Copyright (c) 2021 Jim Gregory -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -//============================================================================ -/* - Features: - - Pause can be triggered by user input, hiscore module or OSD opening (optionally controlled by setting in OSD) - - When paused the RGB outputs will be halved after 10 seconds to reduce burn-in (optionally controlled by setting in OSD) - - Reset signal will cancel user triggered pause - - Version history: - 0001 - 2021-03-15 - First marked release - 0002 - 2021-08-28 - Add optional output of dim_video signal (currently used by Galaga) -============================================================================ -*/ -module pause #( - parameter RW=8, // Width of red channel - parameter GW=8, // Width of green channel - parameter BW=8, // Width of blue channel - parameter CLKSPD = 12 // Main clock speed in MHz -) -( - input clk_sys, // Core system clock (should match HPS module) - input reset, // CPU reset signal (active-high) - input user_button, // User pause button signal (active-high) - input pause_request, // Pause requested by other code (active-high) - input [1:0] options, // Pause options from OSD - // [0] = pause in OSD (active-high) - // [1] = dim video (active-high) - input OSD_STATUS, // OSD is open (active-high) - input [(RW-1):0] r, // Red channel - input [(GW-1):0] g, // Green channel - input [(BW-1):0] b, // Blue channel - - output pause_cpu, // Pause signal to CPU (active-high) -`ifdef PAUSE_OUTPUT_DIM - output dim_video, // Dim video requested (active-high) -`endif - output [(RW+GW+BW-1):0] rgb_out // RGB output to arcade_video module - -); - -// Option constants -localparam pause_in_osd = 1'b0; -localparam dim_video_timer= 1'b1; - -reg pause_toggle = 1'b0; // User paused (active-high) -reg [31:0] pause_timer = 1'b0; // Time since pause -reg [31:0] dim_timeout = (CLKSPD*10000000); // Time until video output dim (10 seconds @ CLKSPD Mhz) - -`ifndef PAUSE_OUTPUT_DIM -wire dim_video; // Dim video requested (active-high) -`endif - -assign pause_cpu = (pause_request | pause_toggle | (OSD_STATUS & options[pause_in_osd])) & !reset; -assign dim_video = (pause_timer >= dim_timeout); - -always @(posedge clk_sys) begin - - // Track user pause button down - reg user_button_last; - user_button_last <= user_button; - - if (!user_button_last & user_button) begin - pause_toggle <= ~pause_toggle; - end - - // Clear user pause on reset - if (pause_toggle & reset) begin - pause_toggle <= 0; - end - - if (pause_cpu & options[dim_video_timer]) begin - // Track pause duration for video dim - if (pause_timer> 2,g >> 2, b >> 2} : {r,g,b}; - -endmodule \ No newline at end of file diff --git a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_demonsworld/DemonsWorld.sv b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_demonsworld/DemonsWorld.sv new file mode 100644 index 00000000..82028422 --- /dev/null +++ b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_demonsworld/DemonsWorld.sv @@ -0,0 +1,296 @@ +//============================================================================ +// Toaplan Hardware v1 HW top-level for MiST +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +//============================================================================ + +module DemonsWorld( + output LED, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_HS, + output VGA_VS, + output AUDIO_L, + output AUDIO_R, + input SPI_SCK, + inout SPI_DO, + input SPI_DI, + input SPI_SS2, + input SPI_SS3, + input SPI_SS4, + input CONF_DATA0, + input CLOCK_27, + + output [12:0] SDRAM_A, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nWE, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nCS, + output [1:0] SDRAM_BA, + output SDRAM_CLK, + output SDRAM_CKE +); + +`include "../build_id.v" +//`include "defs.v" + +`define CORE_NAME "DemonsWorld" +assign LED = ~ioctl_downl; +assign SDRAM_CLK = clk_72; +assign SDRAM_CKE = 1; + +localparam CONF_STR = { + `CORE_NAME, ";;", + "O2,Rotate Controls,Off,On;", + "O34,Scanlines,Off,25%,50%,75%;", + "O5,Blending,Off,On;", + "O6,Joystick Swap,Off,On;", + "DIP;", + "T0,Reset;", + "V,v1.20.",`BUILD_DATE +}; + +wire rotate = status[2]; +wire [1:0] scanlines = status[4:3]; +wire blend = status[5]; +wire joyswap = status[6]; + +wire [7:0] dsw1 = status[23:16]; +wire [7:0] dsw2 = status[31:24]; +reg [7:0] dsw_m68k, dsw_sp85; +reg [7:0] p1, p2; +wire flipped; +wire key_service = m_fire1[4]; +wire key_test = m_fire1[3]; + + + +wire clk_72; +wire pll_locked; +pll_mist pll( + .inclk0(CLOCK_27), + .c0(clk_72), + .locked(pll_locked) + ); + +// reset generation +reg reset = 1; +reg rom_loaded = 0; +always @(posedge clk_72) begin + reg ioctl_downlD; + ioctl_downlD <= ioctl_downl; + if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1; + reset <= status[0] | buttons[1] | ~rom_loaded | ioctl_downl; +end + +// ARM connection +wire [63:0] status; +wire [1:0] buttons; +wire [1:0] switches; +wire [31:0] joystick_0; +wire [31:0] joystick_1; +wire scandoublerD; +wire ypbpr; +wire no_csync; +wire key_strobe; +wire key_pressed; +wire [7:0] key_code; +wire [6:0] core_mod; + +user_io #( + .STRLEN($size(CONF_STR)>>3), + .ROM_DIRECT_UPLOAD(1)) +user_io( + .clk_sys (clk_72 ), + .conf_str (CONF_STR ), + .SPI_CLK (SPI_SCK ), + .SPI_SS_IO (CONF_DATA0 ), + .SPI_MISO (SPI_DO ), + .SPI_MOSI (SPI_DI ), + .buttons (buttons ), + .switches (switches ), + .scandoubler_disable (scandoublerD ), + .ypbpr (ypbpr ), + .no_csync (no_csync ), + .core_mod (core_mod ), + .key_strobe (key_strobe ), + .key_pressed (key_pressed ), + .key_code (key_code ), + .joystick_0 (joystick_0 ), + .joystick_1 (joystick_1 ), + .status (status ) + ); + +wire ioctl_downl; +wire [7:0] ioctl_index; +wire ioctl_wr; +wire [24:0] ioctl_addr; +wire [7:0] ioctl_dout; + +data_io #(.ROM_DIRECT_UPLOAD(1)) data_io( + .clk_sys ( clk_72 ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS2 ( SPI_SS2 ), + .SPI_SS4 ( SPI_SS4 ), + .SPI_DI ( SPI_DI ), + .SPI_DO ( SPI_DO ), + .ioctl_download( ioctl_downl ), + .ioctl_index ( ioctl_index ), + .ioctl_wr ( ioctl_wr ), + .ioctl_addr ( ioctl_addr ), + .ioctl_dout ( ioctl_dout ) +); + +wire [15:0] laudio, raudio; +wire hs, vs; +wire blankn = ~(hb | vb); +wire hb, vb; +wire [4:0] r,b,g; + +DemonsWorld_Top DemonsWorld_Top( + .pll_locked ( pll_locked ), + .clk_sys ( clk_72 ), + .reset ( reset ), + .turbo_68k (0),//cpu_turbo + .pause_cpu (0), +// input scrollDBG, + .p1_right (m_right1), + .p1_left (m_left1), + .p1_down (m_down1), + .p1_up (m_up1), + .p1_buttons (m_fire1[3:0]), + .p2_right (m_right2), + .p2_left (m_left2), + .p2_down (m_down2), + .p2_up (m_up2), + .p2_buttons (m_fire2[3:0]), + .start1 (m_one_player), + .start2 (m_two_players), + .coin_a (m_coin1), + .coin_b (m_coin2), + .b_pause (), + .service (), + .key_tilt (m_tilt), + .key_service (), + .sw0 (), + .sw1 (), + .sw2 (), + + .hblank ( hb ), + .vblank ( vb ), + .hsync ( hs ), + .vsync ( vs ), + .r ( r ), + .g ( g ), + .b ( b ), + .hs_offset (0), + .vs_offset (0), + .hs_width (0), + .vs_width (0), + .refresh_mod (0), + + .ntsc (0), + .opl2_level (2'b00), + + + .audio_l ( laudio ), + .audio_r ( raudio ), + + .ioctl_download( ioctl_downl), + .ioctl_index (ioctl_index), + .ioctl_addr ( ioctl_addr - 2'd2 ),//check + .ioctl_wr ( ioctl_wr ), + .ioctl_dout ( ioctl_dout ), + + .SDRAM_A ( SDRAM_A ), + .SDRAM_BA ( SDRAM_BA ), + .SDRAM_DQ ( SDRAM_DQ ), + .SDRAM_DQML ( SDRAM_DQML ), + .SDRAM_DQMH ( SDRAM_DQMH ), + .SDRAM_nCS ( SDRAM_nCS ), + .SDRAM_nCAS ( SDRAM_nCAS ), + .SDRAM_nRAS ( SDRAM_nRAS ), + .SDRAM_nWE ( SDRAM_nWE ) +); + +mist_video #(.COLOR_DEPTH(5),.SD_HCNT_WIDTH(10)) mist_video( + .clk_sys(clk_72), + .SPI_SCK(SPI_SCK), + .SPI_SS3(SPI_SS3), + .SPI_DI(SPI_DI), + .R(blankn ? r : 5'd0), + .G(blankn ? g : 5'd0), + .B(blankn ? b : 5'd0), + .HSync(~hs), + .VSync(~vs), + .VGA_R(VGA_R), + .VGA_G(VGA_G), + .VGA_B(VGA_B), + .VGA_VS(VGA_VS), + .VGA_HS(VGA_HS), + .no_csync(no_csync), + .rotate({~flipped,rotate}), + .ce_divider(3'd5), // pix clock = 72/6 + .blend(blend), + .scandoubler_disable(scandoublerD), + .scanlines(scanlines), + .ypbpr(ypbpr) + ); + +dac #(16) dacl( + .clk_i(clk_72), + .res_n_i(1), + .dac_i({~laudio[15], laudio[14:0]}), + .dac_o(AUDIO_L) + ); + +dac #(16) dacr( + .clk_i(clk_72), + .res_n_i(1), + .dac_i({~raudio[15], raudio[14:0]}), + .dac_o(AUDIO_R) + ); + +// Common inputs +wire m_up1, m_down1, m_left1, m_right1, m_up1B, m_down1B, m_left1B, m_right1B; +wire m_up2, m_down2, m_left2, m_right2, m_up2B, m_down2B, m_left2B, m_right2B; +wire m_up3, m_down3, m_left3, m_right3, m_up3B, m_down3B, m_left3B, m_right3B; +wire m_up4, m_down4, m_left4, m_right4, m_up4B, m_down4B, m_left4B, m_right4B; +wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players; +wire [11:0] m_fire1, m_fire2, m_fire3, m_fire4; + +arcade_inputs inputs ( + .clk ( clk_72 ), + .key_strobe ( key_strobe ), + .key_pressed ( key_pressed ), + .key_code ( key_code ), + .joystick_0 ( joystick_0 ), + .joystick_1 ( joystick_1 ), + .rotate ( rotate ), + .orientation ( {~flipped, 1'b0} ), + .joyswap ( joyswap ), + .oneplayer ( 1'b0 ), + .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ), + .player1 ( {m_up1B, m_down1B, m_left1B, m_right1B, m_fire1, m_up1, m_down1, m_left1, m_right1} ), + .player2 ( {m_up2B, m_down2B, m_left2B, m_right2B, m_fire2, m_up2, m_down2, m_left2, m_right2} ), + .player3 ( {m_up3B, m_down3B, m_left3B, m_right3B, m_fire3, m_up3, m_down3, m_left3, m_right3} ), + .player4 ( {m_up4B, m_down4B, m_left4B, m_right4B, m_fire4, m_up4, m_down4, m_left4, m_right4} ) +); + +endmodule diff --git a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_demonsworld/DemonsWorld_Top.sv b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_demonsworld/DemonsWorld_Top.sv index da755f9e..92e24032 100644 --- a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_demonsworld/DemonsWorld_Top.sv +++ b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_demonsworld/DemonsWorld_Top.sv @@ -1,13 +1,11 @@ module DemonsWorld_Top( input clk_sys, - input clk_70M, input pll_locked, input turbo_68k,//cpu_turbo - input reset, - + input reset, input pause_cpu, - - input status32, +//------------------------------------ + input scrollDBG, input p1_right, input p1_left, input p1_down, @@ -29,7 +27,7 @@ module DemonsWorld_Top( input [7:0] sw0, input [7:0] sw1, input [7:0] sw2, - +//------------------------------------ output hsync, output vsync, output hblank, @@ -44,18 +42,24 @@ module DemonsWorld_Top( output [4:0] b, input ntsc, input [1:0] opl2_level, - output [15:0] audio, - - - input ioctl_download, - input ioctl_upload, -// input ioctl_upload_req; -// input ioctl_wait; - output ioctl_wr, - input [15:0] ioctl_index, - output [26:0] ioctl_addr, - input [15:0] ioctl_dout, - output [15:0] ioctl_din +//------------------------------------ + output [15:0] audio_l, + output [15:0] audio_r, +//------------------------------------ + input ioctl_download, + input ioctl_index, + input [23:0] ioctl_addr, + input ioctl_wr, + input [7:0] ioctl_dout, + output [12:0] SDRAM_A, + output [1:0] SDRAM_BA, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nCS, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nWE ); //// INPUT @@ -81,8 +85,8 @@ always @ (posedge clk_sys ) begin z80_dswb <= sw1; z80_tjump <= sw2; - if ( status32 == 1 ) begin - system <= { vblank, start2 | p1_buttons[3], start1 | p1_buttons[3], coin_b, coin_a, service | status32, key_tilt, key_service }; + if ( scrollDBG == 1 ) begin + system <= { vblank, start2 | p1_buttons[3], start1 | p1_buttons[3], coin_b, coin_a, service | scrollDBG, key_tilt, key_service }; end else begin system <= { vblank, start2, start1, coin_b, coin_a, service, key_tilt, key_service }; end @@ -304,7 +308,7 @@ end wire tms_reset; reg [7:0] tms_reset_count; -always @ (posedge clk_70M) begin +always @ (posedge clk_sys) begin if ( reset == 1 ) begin tms_reset_count <= 0; tms_reset <= 1 ; @@ -319,7 +323,7 @@ end TMS320C1X dsp ( - .CLK(clk_70M), // (X2/CLKIN) Crystal input internal oscillator or external system clock input + .CLK(clk_sys), // (X2/CLKIN) Crystal input internal oscillator or external system clock input .RST_N(~reset), .EN(1), // (DEN) Data enable for device input data on D15-D0 @@ -480,10 +484,12 @@ jtframe_mixer #(.W0(16), .WOUT(16)) u_mix_mono( always @ (posedge clk_sys ) begin if ( pause_cpu == 1 ) begin - audio <= 0; + audio_l <= 0; + audio_r <= 0; end else if ( pause_cpu == 0 ) begin // mix audio - audio <= {~mono[15],mono[14:0]}; + audio_l <= {mono[15:0]}; + audio_r <= {mono[15:0]}; end end @@ -1478,36 +1484,36 @@ reg [11:0] shared_dsp_ram_addr ; reg shared_dsp_ram_w ; // main 68k ram high -dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_H -( - .clock_a ( clk_10M ), - .address_a ( cpu_a[14:1] ), - .wren_a ( !cpu_rw & ram_cs & !cpu_uds_n ), - .data_a ( cpu_dout[15:8] ), - .q_a ( ram_dout[15:8] ), - - .clock_b( clk_14M ), - .address_b( shared_dsp_ram_addr[11:0] ), - .wren_b( shared_dsp_ram_w ), - .data_b( shared_dsp_ram_din[15:8] ), - .q_b( shared_dsp_ram_dout[15:8] ) -); - -// main 68k ram low -dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_L -( - .clock_a( clk_10M ), - .address_a( cpu_a[14:1] ), - .wren_a( !cpu_rw & ram_cs & !cpu_lds_n ), - .data_a( cpu_dout[7:0] ), - .q_a( ram_dout[7:0] ), - - .clock_b( clk_14M ), - .address_b( shared_dsp_ram_addr[11:0] ), - .wren_b( shared_dsp_ram_w ), - .data_b( shared_dsp_ram_din[7:0] ), - .q_b( shared_dsp_ram_dout[7:0] ) -); +//dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_H +//( +// .clock_a ( clk_10M ), +// .address_a ( cpu_a[14:1] ), +// .wren_a ( !cpu_rw & ram_cs & !cpu_uds_n ), +// .data_a ( cpu_dout[15:8] ), +// .q_a ( ram_dout[15:8] ), +// +// .clock_b( clk_14M ), +// .address_b( shared_dsp_ram_addr[11:0] ), +// .wren_b( shared_dsp_ram_w ), +// .data_b( shared_dsp_ram_din[15:8] ), +// .q_b( shared_dsp_ram_dout[15:8] ) +//); +// +//// main 68k ram low +//dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_L +//( +// .clock_a( clk_10M ), +// .address_a( cpu_a[14:1] ), +// .wren_a( !cpu_rw & ram_cs & !cpu_lds_n ), +// .data_a( cpu_dout[7:0] ), +// .q_a( ram_dout[7:0] ), +// +// .clock_b( clk_14M ), +// .address_b( shared_dsp_ram_addr[11:0] ), +// .wren_b( shared_dsp_ram_w ), +// .data_b( shared_dsp_ram_din[7:0] ), +// .q_b( shared_dsp_ram_dout[7:0] ) +//); @@ -1516,20 +1522,20 @@ dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_L // z80 and 68k shared ram // 4k -dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) shared_ram -( - .clock_a( clk_10M ), - .address_a( cpu_a[12:1] ), - .wren_a( shared_ram_cs & !cpu_rw & !cpu_lds_n), - .data_a( cpu_dout[7:0] ), - .q_a( cpu_shared_dout[7:0] ), - - .clock_b( clk_3_5M ), // z80 clock is 3.5M - .address_b( z80_addr[11:0] ), - .data_b( z80_dout ), - .wren_b( sound_ram_1_cs & ~z80_wr_n ), - .q_b( z80_shared_dout ) - ); +//dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) shared_ram +//( +// .clock_a( clk_10M ), +// .address_a( cpu_a[12:1] ), +// .wren_a( shared_ram_cs & !cpu_rw & !cpu_lds_n), +// .data_a( cpu_dout[7:0] ), +// .q_a( cpu_shared_dout[7:0] ), +// +// .clock_b( clk_3_5M ), // z80 clock is 3.5M +// .address_b( z80_addr[11:0] ), +// .data_b( z80_dout ), +// .wren_b( sound_ram_1_cs & ~z80_wr_n ), +// .q_b( z80_shared_dout ) +// ); reg [11:0] sprite_rb_addr; wire [15:0] sprite_rb_dout; diff --git a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_rallybike/RallyBike_Top.sv b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_rallybike/RallyBike_Top.sv index cebb1681..c9a874f0 100644 --- a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_rallybike/RallyBike_Top.sv +++ b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_rallybike/RallyBike_Top.sv @@ -1,13 +1,12 @@ module RallyBike_Top( input clk_sys, - input clk_70M, input pll_locked, input turbo_68k,//cpu_turbo input reset, input pause_cpu, - input status32, + input scrollDBG, input p1_right, input p1_left, input p1_down, @@ -44,18 +43,24 @@ module RallyBike_Top( output [4:0] b, input ntsc, input [1:0] opl2_level, - output [15:0] audio, + output [15:0] audio_l, + output [15:0] audio_r, - - input ioctl_download, - input ioctl_upload, -// input ioctl_upload_req; -// input ioctl_wait; - output ioctl_wr, - input [15:0] ioctl_index, - output [26:0] ioctl_addr, - input [15:0] ioctl_dout, - output [15:0] ioctl_din + input ioctl_index, + input ioctl_download, + input [23:0] ioctl_addr, + input ioctl_wr, + input [7:0] ioctl_dout, + + output [12:0] SDRAM_A, + output [1:0] SDRAM_BA, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nCS, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nWE ); //// INPUT @@ -81,8 +86,8 @@ always @ (posedge clk_sys ) begin z80_dswb <= sw1; z80_tjump <= sw2; - if ( status32 == 1 ) begin - system <= { vblank, start2 | p1_buttons[3], start1 | p1_buttons[3], coin_b, coin_a, service | status32, key_tilt, key_service }; + if ( scrollDBG == 1 ) begin + system <= { vblank, start2 | p1_buttons[3], start1 | p1_buttons[3], coin_b, coin_a, service | scrollDBG, key_tilt, key_service }; end else begin system <= { vblank, start2, start1, coin_b, coin_a, service, key_tilt, key_service }; end @@ -431,10 +436,12 @@ jtframe_mixer #(.W0(16), .WOUT(16)) u_mix_mono( always @ (posedge clk_sys ) begin if ( pause_cpu == 1 ) begin - audio <= 0; + audio_l <= 0; + audio_r <= 0; end else if ( pause_cpu == 0 ) begin // mix audio - audio <= {~mono[15],mono[14:0]}; + audio_l <= {mono[15:0]}; + audio_r <= {mono[15:0]}; end end @@ -1201,23 +1208,23 @@ dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_h ( ); -// main 68k ram low -dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_L ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[14:1] ), - .wren_a ( !cpu_rw & ram_cs & !cpu_lds_n ), - .data_a ( cpu_dout[7:0] ), - .q_a ( ram_dout[7:0] ) -); - -// main 68k ram high -dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_H ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[14:1] ), - .wren_a ( !cpu_rw & ram_cs & !cpu_uds_n ), - .data_a ( cpu_dout[15:8] ), - .q_a ( ram_dout[15:8] ) -); +//// main 68k ram low +//dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_L ( +// .clock_a ( clk_10M ), +// .address_a ( cpu_a[14:1] ), +// .wren_a ( !cpu_rw & ram_cs & !cpu_lds_n ), +// .data_a ( cpu_dout[7:0] ), +// .q_a ( ram_dout[7:0] ) +//); +// +//// main 68k ram high +//dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_H ( +// .clock_a ( clk_10M ), +// .address_a ( cpu_a[14:1] ), +// .wren_a ( !cpu_rw & ram_cs & !cpu_uds_n ), +// .data_a ( cpu_dout[15:8] ), +// .q_a ( ram_dout[15:8] ) +//); //wire [15:0] z80_shared_addr = z80_addr - 16'h8000; @@ -1225,19 +1232,19 @@ dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_H ( // z80 and 68k shared ram // 4k -dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) shared_ram ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[12:1] ), - .wren_a ( shared_ram_cs & !cpu_rw & !cpu_lds_n), - .data_a ( cpu_dout[7:0] ), - .q_a ( cpu_shared_dout[7:0] ), - - .clock_b ( clk_3_5M ), // z80 clock is 3.5M - .address_b ( z80_addr[11:0] ), - .data_b ( z80_dout ), - .wren_b ( sound_ram_1_cs & ~z80_wr_n ), - .q_b ( z80_shared_dout ) -); +//dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) shared_ram ( +// .clock_a ( clk_10M ), +// .address_a ( cpu_a[12:1] ), +// .wren_a ( shared_ram_cs & !cpu_rw & !cpu_lds_n), +// .data_a ( cpu_dout[7:0] ), +// .q_a ( cpu_shared_dout[7:0] ), +// +// .clock_b ( clk_3_5M ), // z80 clock is 3.5M +// .address_b ( z80_addr[11:0] ), +// .data_b ( z80_dout ), +// .wren_b ( sound_ram_1_cs & ~z80_wr_n ), +// .q_b ( z80_shared_dout ) +//); reg sprite_attr_w ; reg [10:0] sprite_attr_addr; diff --git a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_rallybike/rallybik.sv b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_rallybike/rallybik.sv new file mode 100644 index 00000000..3d64d607 --- /dev/null +++ b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_rallybike/rallybik.sv @@ -0,0 +1,1988 @@ +//============================================================================ +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +//============================================================================ + +`default_nettype none + +module emu +( + //Master input clock + input CLK_50M, + + //Async reset from top-level module. + //Can be used as initial reset. + input RESET, + + //Must be passed to hps_io module + inout [48:0] HPS_BUS, + + //Base video clock. Usually equals to CLK_SYS. + output CLK_VIDEO, + + //Multiple resolutions are supported using different CE_PIXEL rates. + //Must be based on CLK_VIDEO + output CE_PIXEL, + + //Video aspect ratio for HDMI. Most retro systems have ratio 4:3. + //if VIDEO_ARX[12] or VIDEO_ARY[12] is set then [11:0] contains scaled size instead of aspect ratio. + output [12:0] VIDEO_ARX, + output [12:0] VIDEO_ARY, + + output [7:0] VGA_R, + output [7:0] VGA_G, + output [7:0] VGA_B, + output VGA_HS, + output VGA_VS, + output VGA_DE, // = ~(VBlank | HBlank) + output VGA_F1, + output [2:0] VGA_SL, + output VGA_SCALER, // Force VGA scaler + + input [11:0] HDMI_WIDTH, + input [11:0] HDMI_HEIGHT, + output HDMI_FREEZE, + +`ifdef MISTER_FB + // Use framebuffer in DDRAM (USE_FB=1 in qsf) + // FB_FORMAT: + // [2:0] : 011=8bpp(palette) 100=16bpp 101=24bpp 110=32bpp + // [3] : 0=16bits 565 1=16bits 1555 + // [4] : 0=RGB 1=BGR (for 16/24/32 modes) + // + // FB_STRIDE either 0 (rounded to 256 bytes) or multiple of pixel size (in bytes) + output FB_EN, + output [4:0] FB_FORMAT, + output [11:0] FB_WIDTH, + output [11:0] FB_HEIGHT, + output [31:0] FB_BASE, + output [13:0] FB_STRIDE, + input FB_VBL, + input FB_LL, + output FB_FORCE_BLANK, + +`ifdef MISTER_FB_PALETTE + // Palette control for 8bit modes. + // Ignored for other video modes. + output FB_PAL_CLK, + output [7:0] FB_PAL_ADDR, + output [23:0] FB_PAL_DOUT, + input [23:0] FB_PAL_DIN, + output FB_PAL_WR, +`endif +`endif + + output LED_USER, // 1 - ON, 0 - OFF. + + // b[1]: 0 - LED status is system status OR'd with b[0] + // 1 - LED status is controled solely by b[0] + // hint: supply 2'b00 to let the system control the LED. + output [1:0] LED_POWER, + output [1:0] LED_DISK, + + // I/O board button press simulation (active high) + // b[1]: user button + // b[0]: osd button + output [1:0] BUTTONS, + + //Audio + input CLK_AUDIO, // 24.576 MHz + output [15:0] AUDIO_L, + output [15:0] AUDIO_R, + output AUDIO_S, // 1 - signed audio samples, 0 - unsigned + output [1:0] AUDIO_MIX, // 0 - no mix, 1 - 25%, 2 - 50%, 3 - 100% (mono) + + //ADC + inout [3:0] ADC_BUS, + + //SD-SPI + output SD_SCK, + output SD_MOSI, + input SD_MISO, + output SD_CS, + input SD_CD, + + //High latency DDR3 RAM interface + //Use for non-critical time purposes + output DDRAM_CLK, + input DDRAM_BUSY, + output [7:0] DDRAM_BURSTCNT, + output [28:0] DDRAM_ADDR, + input [63:0] DDRAM_DOUT, + input DDRAM_DOUT_READY, + output DDRAM_RD, + output [63:0] DDRAM_DIN, + output [7:0] DDRAM_BE, + output DDRAM_WE, + + //SDRAM interface with lower latency + output SDRAM_CLK, + output SDRAM_CKE, + output [12:0] SDRAM_A, + output [1:0] SDRAM_BA, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nCS, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nWE, + +`ifdef MISTER_DUAL_SDRAM + //Secondary SDRAM + //Set all output SDRAM_* signals to Z ASAP if SDRAM2_EN is 0 + input SDRAM2_EN, + output SDRAM2_CLK, + output [12:0] SDRAM2_A, + output [1:0] SDRAM2_BA, + inout [15:0] SDRAM2_DQ, + output SDRAM2_nCS, + output SDRAM2_nCAS, + output SDRAM2_nRAS, + output SDRAM2_nWE, +`endif + + input UART_CTS, + output UART_RTS, + input UART_RXD, + output UART_TXD, + output UART_DTR, + input UART_DSR, + +`ifdef MISTER_ENABLE_YC + output [39:0] CHROMA_PHASE_INC, + output YC_EN, + output PALFLAG, +`endif + + // Open-drain User port. + // 0 - D+/RX + // 1 - D-/TX + // 2..6 - USR2..USR6 + // Set USER_OUT to 1 to read from USER_IN. + input [6:0] USER_IN, + output [6:0] USER_OUT, + + input OSD_STATUS +); + +///////// Default values for ports not used in this core ///////// + +assign ADC_BUS = 'Z; +assign USER_OUT = 0; +assign {UART_RTS, UART_TXD, UART_DTR} = 0; +assign {SD_SCK, SD_MOSI, SD_CS} = 'Z; +//assign {SDRAM_DQ, SDRAM_A, SDRAM_BA, SDRAM_CLK, SDRAM_CKE, SDRAM_DQML, SDRAM_DQMH, SDRAM_nWE, SDRAM_nCAS, SDRAM_nRAS, SDRAM_nCS} = 'Z; +//assign {DDRAM_CLK, DDRAM_BURSTCNT, DDRAM_ADDR, DDRAM_DIN, DDRAM_BE, DDRAM_RD, DDRAM_WE} = '0; +assign VGA_F1 = 0; +assign VGA_SCALER = 0; +assign HDMI_FREEZE = 0; + +assign AUDIO_MIX = 0; +assign LED_USER = ioctl_download & cpu_a[0]; +assign LED_DISK = 0; +assign LED_POWER = 0; +assign BUTTONS = 0; + +// Status Bit Map: +// Upper Case Lower Case +// 0 1 2 3 4 5 6 +// 01234567890123456789012345678901 23456789012345678901234567890123 +// 0123456789ABCDEFGHIJKLMNOPQRSTUV 0123456789ABCDEFGHIJKLMNOPQRSTUV +// X XXXXXXXX XX X X XXXXXXXX X XX XXXXXXXX + +wire [1:0] aspect_ratio = status[9:8]; +wire orientation = ~status[3]; +wire [2:0] scan_lines = status[6:4]; +reg refresh_mod; +reg new_vmode; + +always @(posedge clk_sys) begin + if (refresh_mod != status[19]) begin + refresh_mod <= status[19]; + new_vmode <= ~new_vmode; + end +end + +wire [3:0] hs_offset = status[27:24]; +wire [3:0] vs_offset = status[31:28]; +wire [3:0] hs_width = status[59:56]; +wire [3:0] vs_width = status[63:60]; + +assign VIDEO_ARX = (!aspect_ratio) ? (orientation ? 8'd4 : 8'd3) : (aspect_ratio - 1'd1); +assign VIDEO_ARY = (!aspect_ratio) ? (orientation ? 8'd3 : 8'd4) : 12'd0; + +`include "build_id.v" +localparam CONF_STR = { + "Toaplan V1;;", + "-;", + "P1,Video Settings;", + "P1-;", + "P1O89,Aspect Ratio,Original,Full Screen,[ARC1],[ARC2];", + "P1O3,Orientation,Horz,Vert;", + "P1-;", + "P1O46,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%,CRT 75%,CRT 100%;", + "P1OA,Force Scandoubler,Off,On;", + "P1-;", + "P1O7,Video Mode,NTSC,PAL;", + "P1OM,Video Signal,RGBS/YPbPr,Y/C;", + "P1OJ,Refresh Rate,Native,NTSC;", + "P1-;", + "P1OOR,H-sync Pos Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", + "P1OSV,V-sync Pos Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", + "P1-;", + "P1oOR,H-sync Width Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", + "P1oSV,V-sync Width Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", + "P1-;", + "P2,Audio Settings;", + "P2-;", + "P2oBC,OPL2 Volume,Default,50%,25%,0%;", + "P2-;", + "-;", + "P3,Core Options;", + "P3-;", + "P3OF,68k Freq.,10Mhz,17.5MHz;", + "P3-;", + "P3o0,Scroll Debug,Off,On;", + "P3-;", + "DIP;", + "-;", + "OK,Pause OSD,Off,When Open;", + "OL,Dim Video,Off,10s;", + "-;", + "R0,Reset;", + "V,v",`BUILD_DATE +}; + +wire hps_forced_scandoubler; +wire forced_scandoubler = hps_forced_scandoubler | status[10]; + +wire [1:0] buttons; +wire [63:0] status; +wire [10:0] ps2_key; +wire [15:0] joy0, joy1; + +hps_io #(.CONF_STR(CONF_STR)) hps_io +( + .clk_sys(clk_sys), + .HPS_BUS(HPS_BUS), + + .buttons(buttons), + .ps2_key(ps2_key), + .status(status), + .status_menumask(direct_video), + .forced_scandoubler(hps_forced_scandoubler), + .gamma_bus(gamma_bus), + .new_vmode(new_vmode), + .direct_video(direct_video), + .video_rotated(video_rotated), + + .ioctl_download(ioctl_download), + .ioctl_upload(ioctl_upload), + .ioctl_wr(ioctl_wr), + .ioctl_addr(ioctl_addr), + .ioctl_dout(ioctl_dout), + .ioctl_din(ioctl_din), + .ioctl_index(ioctl_index), + .ioctl_wait(ioctl_wait), + + .joystick_0(joy0), + .joystick_1(joy1) +); + +// INPUT + +// 8 dip switches of 8 bits +reg [7:0] sw[8]; +always @(posedge clk_sys) begin + if (ioctl_wr && (ioctl_index==254) && !ioctl_addr[24:3]) begin + sw[ioctl_addr[2:0]] <= ioctl_dout; + end +end + +wire direct_video; + +wire ioctl_download; +wire ioctl_upload; +wire ioctl_upload_req; +wire ioctl_wait; +wire ioctl_wr; +wire [15:0] ioctl_index; +wire [26:0] ioctl_addr; +wire [15:0] ioctl_dout; +wire [15:0] ioctl_din; + +wire tile_priority_type; +wire [15:0] scroll_y_offset; +wire [15:0] scroll_x_offset = 30; + +wire [21:0] gamma_bus; + +// +// Inputs tied to z80_din +reg [7:0] p1; +reg [7:0] p2; +reg [7:0] z80_dswa; +reg [7:0] z80_dswb; +reg [7:0] z80_tjump; +reg [7:0] system; + +always @ (posedge clk_sys ) begin + + p1 <= { 1'b0, p1_buttons[2:0], p1_right, p1_left, p1_down, p1_up }; + p2 <= { 1'b0, p2_buttons[2:0], p2_right, p2_left, p2_down, p2_up }; + z80_dswa <= sw[0]; + z80_dswb <= sw[1]; + z80_tjump <= sw[2]; + + if ( status[32] == 1 ) begin + system <= { vbl, start2 | p1_buttons[3], start1 | p1_buttons[3], coin_b, coin_a, service | status[32], key_tilt, key_service }; + end else begin + system <= { vbl, start2, start1, coin_b, coin_a, service, key_tilt, key_service }; + end +end + +reg p1_right; +reg p1_left; +reg p1_down; +reg p1_up; +reg [3:0] p1_buttons; + +reg p2_right; +reg p2_left; +reg p2_down; +reg p2_up; +reg [3:0] p2_buttons; + +reg start1; +reg start2; +reg coin_a; +reg coin_b; +reg b_pause; +reg service; + +always @ * begin + p1_right <= joy0[0] | key_p1_right; + p1_left <= joy0[1] | key_p1_left; + p1_down <= joy0[2] | key_p1_down; + p1_up <= joy0[3] | key_p1_up; + p1_buttons <= joy0[7:4] | {key_p1_c, key_p1_b, key_p1_a}; + + p2_right <= joy1[0] | key_p2_right; + p2_left <= joy1[1] | key_p2_left; + p2_down <= joy1[2] | key_p2_down; + p2_up <= joy1[3] | key_p2_up; + p2_buttons <= joy1[7:4] | {key_p2_c, key_p2_b, key_p2_a}; + + start1 <= joy0[8] | joy1[8] | key_start_1p; + start2 <= joy0[9] | joy1[9] | key_start_2p; + + coin_a <= joy0[10] | joy1[10] | key_coin_a; + coin_b <= joy0[11] | joy1[11] | key_coin_b; + + b_pause <= joy0[12] | key_pause; + service <= key_test; +end + +// Keyboard handler + +reg key_start_1p, key_start_2p, key_coin_a, key_coin_b; +reg key_tilt, key_test, key_reset, key_service, key_pause; + +reg key_p1_up, key_p1_left, key_p1_down, key_p1_right, key_p1_a, key_p1_b, key_p1_c; +reg key_p2_up, key_p2_left, key_p2_down, key_p2_right, key_p2_a, key_p2_b, key_p2_c; + +wire pressed = ps2_key[9]; + +always @(posedge clk_sys) begin + reg old_state; + old_state <= ps2_key[10]; + if ( old_state ^ ps2_key[10] ) begin + casex ( ps2_key[8:0] ) + 'h016 : key_start_1p <= pressed; // 1 + 'h01E : key_start_2p <= pressed; // 2 + 'h02E : key_coin_a <= pressed; // 5 + 'h036 : key_coin_b <= pressed; // 6 + 'h006 : key_test <= key_test ^ pressed; // f2 + 'h004 : key_reset <= pressed; // f3 + 'h046 : key_service <= pressed; // 9 + 'h02C : key_tilt <= pressed; // t + 'h04D : key_pause <= pressed; // p + + 'h175 : key_p1_up <= pressed; // up + 'h172 : key_p1_down <= pressed; // down + 'h16B : key_p1_left <= pressed; // left + 'h174 : key_p1_right <= pressed; // right + 'h014 : key_p1_a <= pressed; // lctrl + 'h011 : key_p1_b <= pressed; // lalt + 'h029 : key_p1_c <= pressed; // spacebar + + 'h02D : key_p2_up <= pressed; // r + 'h02B : key_p2_down <= pressed; // f + 'h023 : key_p2_left <= pressed; // d + 'h034 : key_p2_right <= pressed; // g + 'h01C : key_p2_a <= pressed; // a + 'h01B : key_p2_b <= pressed; // s + 'h015 : key_p2_c <= pressed; // q + endcase + end +end + +wire pll_locked; + +wire clk_sys; +wire turbo_68k = status[15]; +reg clk_3_5M, clk_7M, clk_10M, clk_14M; + +wire clk_70M; + +pll pll +( + .refclk(CLK_50M), + .rst(0), + .outclk_0(clk_sys), + .outclk_1(clk_70M), + .locked(pll_locked) +); + +assign SDRAM_CLK = clk_70M; + +localparam CLKSYS=70; + +reg [5:0] clk14_count; +reg [5:0] clk10_count; +reg [5:0] clk7_count; +reg [5:0] clk_3_5_count; + +always @ (posedge clk_sys ) begin + clk_10M <= 0; + if ( turbo_68k == 0 ) begin + // standard speed 20MHz = 10MHz 68k + case (clk10_count) + 1: clk_10M <= 1; + 3: clk_10M <= 1; + endcase + if ( clk10_count == 6 ) begin + clk10_count <= 0; + end else if ( pause_cpu == 0 ) begin + clk10_count <= clk10_count + 1; + end + end else begin + // standard speed 35MHz = 17.5MHz 68k + case (clk10_count) + 1: clk_10M <= 1; + endcase + if ( clk10_count == 1 ) begin + clk10_count <= 0; + end else if ( pause_cpu == 0 ) begin + clk10_count <= clk10_count + 1; + end + end + + clk_7M <= ( clk7_count == 0); + if ( clk7_count == 9 ) begin + clk7_count <= 0; + end else begin + clk7_count <= clk7_count + 1; + end + + clk_14M <= ( clk14_count == 0); + if ( clk14_count == 4 ) begin + clk14_count <= 0; + end else begin + clk14_count <= clk14_count + 1; + end + + clk_3_5M <= ( clk_3_5_count == 0); + if ( clk_3_5_count == 19 ) begin + clk_3_5_count <= 0; + end else if ( pause_cpu == 0 ) begin + clk_3_5_count <= clk_3_5_count + 1; + end +end + +wire reset; +assign reset = RESET | status[0] | (ioctl_download & !ioctl_index) | buttons[1] | key_reset; + +////////////////////////////////////////////////////////////////// +wire rotate_ccw = 1; +wire no_rotate = orientation | direct_video; +wire video_rotated; + +reg [23:0] rgb; + +wire hbl; +wire vbl; + +wire [8:0] hc; +wire [8:0] vc; + +wire hsync; +wire vsync; + +reg hbl_delay, vbl_delay; + +always @ ( posedge clk_7M ) begin + hbl_delay <= hbl; + vbl_delay <= vbl; +end + +video_timing video_timing ( + .clk(clk_7M), + .reset(reset), + .crtc0(crtc[0]), + .crtc1(crtc[1]), + .crtc2(crtc[2]), + .crtc3(crtc[3]), + .hs_offset(hs_offset), + .vs_offset(vs_offset), + .hs_width(hs_width), + .vs_width(vs_width), + .refresh_mod(refresh_mod), + .hc(hc), + .vc(vc), + .hbl_delay(hbl), + .vbl(vbl), + .hsync(hsync), + .vsync(vsync) +); + +// PAUSE SYSTEM +wire pause_cpu; +wire hs_pause; + +// 8 bits per colour, 70MHz sys clk +pause #(8,8,8,70) pause +( + .clk_sys(clk_sys), + .reset(reset), + .user_button(b_pause), + .pause_request(hs_pause), + .options(status[21:20]), + .pause_cpu(pause_cpu), + .dim_video(dim_video), + .OSD_STATUS(OSD_STATUS), + .r(rgb[23:16]), + .g(rgb[15:8]), + .b(rgb[7:0]), + .rgb_out(rgb_pause_out) +); + +wire [23:0] rgb_pause_out; +wire dim_video; + +arcade_video #(320,24) arcade_video +( + .*, + + .clk_video(clk_sys), + .ce_pix(clk_7M), + + .RGB_in(rgb_pause_out), + + .HBlank(hbl), + .VBlank(vbl), + .HSync(hsync), + .VSync(vsync), + + .fx(scan_lines) +); + +/* + Phase Accumulator Increments (Fractional Size 32, look up size 8 bit, total 40 bits) + Increment Calculation - (Output Clock * 2 ^ Word Size) / Reference Clock + Example + NTSC = 3.579545 + PAL = 4.43361875 + W = 40 ( 32 bit fraction, 8 bit look up reference) + Ref CLK = 42.954544 (This could us any clock) + NTSC_Inc = 3.579545333 * 2 ^ 40 / 96 = 40997413706 +*/ + +// SET PAL and NTSC TIMING +`ifdef MISTER_ENABLE_YC + assign CHROMA_PHASE_INC = PALFLAG ? 40'd56225080500: 40'd56225080500; + assign YC_EN = status[22]; + assign PALFLAG = status[7]; +`endif + +screen_rotate screen_rotate (.*); + +wire [9:0] sprite_adj_x = 0; +wire [9:0] sprite_adj_y = 0; +wire bcu_flip_cs; + +reg [1:0] adj_layer; +reg [15:0] scroll_adj_x [3:0]; +reg [15:0] scroll_adj_y [3:0]; +reg layer_en [3:0]; + +reg ce_pix; + +// flip is done in the rendering so leave screen_rotate flip off +wire flip = 0; + +reg tile_flip; + +//assign vc = vcx - vs_offset; + +// =============================================================== +// 68000 CPU +// =============================================================== + +// clock generation +reg fx68_phi1 = 0; +wire fx68_phi2 = !fx68_phi1; + +// phases for 68k clock +always @(posedge clk_sys) begin + if ( clk_10M == 1 ) begin + fx68_phi1 <= ~fx68_phi1; + end +end + +// CPU outputs +wire cpu_rw; // Read = 1, Write = 0 +wire cpu_as_n; // Address strobe +wire cpu_lds_n; // Lower byte strobe +wire cpu_uds_n; // Upper byte strobe +wire cpu_E; +wire [2:0]cpu_fc; // Processor state +wire cpu_reset_n_o; // Reset output signal +wire cpu_halted_n; // Halt output + +// CPU busses +wire [15:0] cpu_dout; +wire [23:0] cpu_a /* synthesis keep */; +reg [15:0] cpu_din; + +// CPU inputs +reg dtack_n; // Data transfer ack (always ready) +reg ipl2_n; + +wire reset_n; +wire vpa_n = ~ ( cpu_lds_n == 0 && cpu_fc == 3'b111 ); // from outzone schematic + +assign cpu_a[0] = reset; // debug hack odd memory address should cause cpu exception + +cc_shifter cc_reset ( + .clk_out(clk_10M), + .i(reset_z80_n & cpu_reset_n_o), + .o(reset_n) +); + +fx68k fx68k ( + // input + .clk( clk_10M ), + .enPhi1(fx68_phi1), + .enPhi2(fx68_phi2), + .extReset(reset), + .pwrUp(reset), + + // output + .eRWn(cpu_rw), + .ASn( cpu_as_n), + .LDSn(cpu_lds_n), + .UDSn(cpu_uds_n), +// .E(cpu_E), +// .VMAn(), + .FC0(cpu_fc[0]), + .FC1(cpu_fc[1]), + .FC2(cpu_fc[2]), +// .BGn(), + .oRESETn(cpu_reset_n_o), + .oHALTEDn(cpu_halted_n), + + // input + .VPAn( vpa_n ), + .DTACKn(dtack_n ), + .BERRn(1'b1), + .BRn(1'b1), + .BGACKn(1'b1), + + .IPL0n(1'b1), + .IPL1n(1'b1), + .IPL2n(ipl2_n), + + // busses + .iEdb(cpu_din), + .oEdb(cpu_dout), + .eab(cpu_a[23:1]) +); + +always @ (posedge clk_sys) begin + if ( clk_10M == 1 ) begin + // tell 68k to wait for valid data. 0=ready 1=wait + // always ack when it's not program rom + dtack_n <= prog_rom_cs ? !prog_rom_data_valid : 0; + // add dsp_ctrl_cs to cpu_din + // select cpu data input based on what is active + cpu_din <= prog_rom_cs ? prog_rom_data : + ram_cs ? ram_dout : + tile_palette_cs ? tile_palette_cpu_dout : + sprite_palette_cs ? sprite_palette_cpu_dout : + sprite_ram_cs ? sprite_ram_dout : + tile_ofs_cs ? curr_tile_ofs : + sprite_ofs_cs ? curr_sprite_ofs : + shared_ram_cs ? cpu_shared_dout : + tile_attr_cs ? ( cpu_tile_dout_attr | { 4'b0, cpu_tile_dout_attr[15:12], cpu_tile_dout_attr[5:4], 6'b0 } ) : + tile_num_cs ? cpu_tile_dout_num : + vblank_cs ? { 15'b0, vbl } : + int_en_cs ? { 15'b0, int_en } : + 16'hffff; + end +end + +wire [15:0] cpu_shared_dout; +wire [7:0] z80_shared_dout; +reg [15:0] z80_a; + +wire [15:0] z80_addr; +reg [7:0] z80_din; +wire [7:0] z80_dout; + +wire z80_wr_n; +wire z80_rd_n; +reg z80_wait_n; + +wire IORQ_n; +wire MREQ_n; + +always @ (posedge clk_sys) begin + if ( reset == 1 ) begin + z80_wait_n <= 0; + sound_wr <= 0; + end else if ( clk_3_5M == 1 ) begin + z80_wait_n <= 1; + if ( ioctl_download | ( z80_rd_n == 0 && sound_rom_1_data_valid == 0 && sound_rom_1_cs == 1 ) ) begin + // wait if rom is selected and data is not yet available + z80_wait_n <= 0; + end + + if ( z80_rd_n == 0 ) begin + if ( sound_rom_1_cs ) begin + if ( sound_rom_1_data_valid ) begin + z80_din <= sound_rom_1_data; + end else begin + z80_wait_n <= 0; + end + end else if ( sound_ram_1_cs ) begin + z80_din <= z80_shared_dout; + end else if ( z80_p1_cs ) begin + z80_din <= p1; + end else if ( z80_p2_cs ) begin + z80_din <= p2; + end else if ( z80_dswa_cs ) begin + z80_din <= z80_dswa; + end else if ( z80_dswb_cs ) begin + z80_din <= z80_dswb; + end else if ( z80_tjump_cs ) begin + z80_din <= z80_tjump; + end else if ( z80_system_cs ) begin + z80_din <= system; + end else if ( z80_sound0_cs ) begin + z80_din <= opl_dout; + end else begin + z80_din <= 8'h00; + end + end + + sound_wr <= 0; + if ( z80_wr_n == 0 ) begin + if ( z80_sound0_cs | z80_sound1_cs ) begin + sound_data <= z80_dout; + sound_addr <= { 1'b0, z80_sound1_cs }; // pad for opl3. opl2 is single bit address + sound_wr <= 1; + end + end + end +end + +reg [1:0] sound_addr; +reg [7:0] sound_data; +reg sound_wr; + +wire [7:0] opl_dout; +wire opl_irq_n; + +reg signed [15:0] sample; + +assign AUDIO_S = 1'b1; + +wire opl_sample_clk; + +jtopl #(.OPL_TYPE(2)) jtopl2 +( + .rst(~reset_n), + .clk(clk_sys), + .cen(clk_3_5M), + .din(sound_data), + .addr(sound_addr), + .cs_n('0), + .wr_n(~sound_wr), + .dout(opl_dout), + .irq_n(opl_irq_n), + .snd(sample), + .sample(opl_sample_clk) +); + +wire [1:0] opl2_level = status[44:43]; // opl2 audio mix + +reg [7:0] opl2_mult; + +// set the multiplier for each channel from menu + +always @( posedge clk_sys, posedge reset ) begin + if (reset) begin + opl2_mult<=0; + end else begin + case( opl2_level ) + 0: opl2_mult <= 8'h0c; // 75% + 1: opl2_mult <= 8'h08; // 50% + 2: opl2_mult <= 8'h04; // 25% + 3: opl2_mult <= 8'h00; // 0% + endcase + end +end + +wire signed [15:0] mono; + +jtframe_mixer #(.W0(16), .WOUT(16)) u_mix_mono( + .rst ( reset ), + .clk ( clk_sys ), + .cen ( 1'b1 ), + // input signals + .ch0 ( sample ), + .ch1 ( 16'd0 ), + .ch2 ( 16'd0 ), + .ch3 ( 16'd0 ), + // gain for each channel in 4.4 fixed point format + .gain0 ( opl2_mult ), + .gain1 ( 8'd0 ), + .gain2 ( 8'd0 ), + .gain3 ( 8'd0 ), + .mixed ( mono ), + .peak ( ) +); + +always @ (posedge clk_sys ) begin + if ( pause_cpu == 1 ) begin + AUDIO_L <= 0; + AUDIO_R <= 0; + end else if ( pause_cpu == 0 ) begin + // mix audio + AUDIO_L <= mono; + AUDIO_R <= mono; + end +end + +T80pa u_cpu( + .RESET_n ( reset_n ), + .CLK ( clk_sys ), + .CEN_p ( clk_3_5M ), + .CEN_n ( ~clk_3_5M ), + + .WAIT_n ( z80_wait_n ), // don't wait if data is valid or rom access isn't selected + .INT_n ( opl_irq_n ), // opl timer + .NMI_n ( 1'b1 ), + .BUSRQ_n ( 1'b1 ), + .RD_n ( z80_rd_n ), + .WR_n ( z80_wr_n ), + .A ( z80_addr ), + .DI ( z80_din ), + .DO ( z80_dout ), + // unused + .DIRSET ( 1'b0 ), + .DIR ( 212'b0 ), + .OUT0 ( 1'b0 ), + .RFSH_n (), + .IORQ_n ( IORQ_n ), + .M1_n (), + .BUSAK_n (), + .HALT_n ( 1'b1 ), + .MREQ_n ( MREQ_n ), + .Stop (), + .REG () +); + +// Chip select mux +wire prog_rom_cs; +wire scroll_ofs_x_cs; +wire scroll_ofs_y_cs; +wire ram_cs; +wire vblank_cs; +wire int_en_cs; +wire crtc_cs; +wire tile_ofs_cs; +wire tile_attr_cs; +wire tile_num_cs; +wire scroll_cs; +wire shared_ram_cs; +wire frame_done_cs; // word +wire tile_palette_cs; +wire sprite_palette_cs; +wire sprite_ofs_cs; +wire sprite_cs; // *** offset needs to be auto-incremented +wire sprite_size_cs; // *** offset needs to be auto-incremented +wire sprite_ram_cs; + +wire z80_p1_cs; +wire z80_p2_cs; +wire z80_dswa_cs; +wire z80_dswb_cs; +wire z80_system_cs; +wire z80_tjump_cs; +wire z80_sound0_cs; +wire z80_sound1_cs; + +chip_select cs (.*); + +wire sprite_0_cs = ( curr_sprite_ofs[1:0] == 2'b00 ) & sprite_cs; +wire sprite_1_cs = ( curr_sprite_ofs[1:0] == 2'b01 ) & sprite_cs; +wire sprite_2_cs = ( curr_sprite_ofs[1:0] == 2'b10 ) & sprite_cs; +wire sprite_3_cs = ( curr_sprite_ofs[1:0] == 2'b11 ) & sprite_cs; + +reg reset_z80_n; +wire reset_z80_cs; +wire sound_rom_1_cs = ( MREQ_n == 0 && z80_addr <= 16'h7fff ); +wire sound_ram_1_cs = ( MREQ_n == 0 && z80_addr >= 16'h8000 && z80_addr <= 16'h87ff ); + +reg int_en; +reg int_ack; + +reg [1:0] vbl_sr; + +// vblank interrupt on rising vbl +always @ (posedge clk_sys ) begin + if ( reset == 1 ) begin + ipl2_n <= 1; + int_ack <= 0; + end else begin + vbl_sr <= { vbl_sr[0], vbl }; + if ( clk_10M == 1 ) begin + int_ack <= ( cpu_as_n == 0 ) && ( cpu_fc == 3'b111 ); // cpu acknowledged the interrupt + end + if ( vbl_sr == 2'b01 ) begin// rising edge + ipl2_n <= ~int_en; + end else if ( int_ack == 1 || vbl_sr == 2'b10 ) begin + ipl2_n <= 1; + end + end +end + +reg [15:0] scroll_x [3:0]; +reg [15:0] scroll_y [3:0]; + +reg [15:0] scroll_x_latch [3:0]; +reg [15:0] scroll_y_latch [3:0]; + +reg inc_sprite_ofs; + +reg [15:0] crtc[4]; +reg [7:0] reset_counter; + +always @ (posedge clk_sys) begin + if ( reset == 1 ) begin + int_en <= 0; + reset_z80_n <= 1; + reset_counter <= 0; + end else begin + if ( reset_counter > 0 ) begin + reset_counter <= reset_counter - 1; + end else begin + reset_z80_n = 1; + end + // write asserted and rising cpu clock + if ( clk_10M == 1 && cpu_rw == 0 ) begin + if ( tile_ofs_cs ) begin + curr_tile_ofs <= cpu_dout; + end + + if ( int_en_cs ) begin + int_en <= cpu_dout[0]; + end + + if ( crtc_cs ) begin + crtc[ cpu_a[2:1] ] <= cpu_dout; + end + + if ( bcu_flip_cs ) begin + tile_flip <= cpu_dout[0]; + end + + if ( sprite_ofs_cs ) begin + // mask out valid range + curr_sprite_ofs <= { 6'b0, cpu_dout[9:0] }; + end + + if ( scroll_ofs_x_cs ) begin + scroll_ofs_x <= cpu_dout; + end + + if ( scroll_ofs_y_cs ) begin + scroll_ofs_y <= cpu_dout; + end + + // x layer values are even addresses + if ( scroll_cs ) begin + if ( cpu_a[1] == 0 ) begin + scroll_x[ cpu_a[3:2] ] <= cpu_dout[15:7]; + end else begin + scroll_y[ cpu_a[3:2] ] <= cpu_dout[15:7]; + end + end + + // offset needs to be auto-incremented + if ( sprite_cs | sprite_size_cs ) begin + inc_sprite_ofs <= 1; + end + + if ( reset_z80_cs ) begin + // the pcb writes to a latch to control the reset + if ( cpu_dout == 0 ) begin + reset_z80_n <= 0; + reset_counter <= 8'h3f; + end + end + end + + // write lasts multiple cpu clocks so limit to one increment per write signal + if ( inc_sprite_ofs == 1 && cpu_rw == 1 ) begin + curr_sprite_ofs <= curr_sprite_ofs + 1; + inc_sprite_ofs <= 0; + end + end +end + +reg [15:0] scroll_x_total [3:0]; +reg [15:0] scroll_y_total [3:0]; + +wire [15:0] ram_dout; +wire [9:0] tile_palette_addr; +wire [15:0] tile_palette_cpu_dout; +wire [15:0] tile_palette_dout; + +wire [9:0] sprite_palette_addr; +wire [15:0] sprite_palette_cpu_dout; +wire [15:0] sprite_palette_dout; + +reg [15:0] curr_tile_ofs; +reg [15:0] curr_sprite_ofs; + +reg [15:0] scroll_ofs_x; +reg [15:0] scroll_ofs_y; + +wire [15:0] cpu_tile_dout_attr; +wire [15:0] cpu_tile_dout_num; + +wire [31:0] tile_attr_dout; + +reg [15:0] sprite_buf_din; + +reg [14:0] tile; + +reg [8:0] sprite_num; +reg [8:0] sprite_num_copy; + +reg [3:0] tile_draw_state; + +reg [2:0] layer; // 4 layers + 1 for initial background + +wire [14:0] tile_idx = tile_attr[14:0]; +wire [3:0] tile_priority = tile_attr[31:28]; +wire [5:0] tile_palette_idx = tile_attr[21:16]; +wire tile_hidden = tile_attr[15]; + +reg [15:0] fb_dout; +wire [15:0] tile_fb_out; +wire [15:0] sprite_fb_out; +reg [15:0] fb_din; +reg [15:0] sprite_fb_din; + +reg tile_fb_w; +reg sprite_fb_w; +reg sprite_size_buf_w; + +dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) tile_line_buffer ( + .clock_a ( clk_sys ), + .address_a ( tile_fb_addr_w ), + .wren_a ( tile_fb_w ), + .data_a ( fb_din ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( fb_addr_r ), + .wren_b ( 0 ), +// .data_b ( ), + .q_b ( tile_fb_out ) +); + +dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) sprite_line_buffer ( + .clock_a ( clk_sys ), + .address_a ( sprite_fb_addr_w ), + .wren_a ( sprite_fb_w ), + .data_a ( sprite_fb_din ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( fb_addr_r ), + .wren_b ( 0 ), +// .data_b ( ), + .q_b ( sprite_fb_out ) +); + +reg [9:0] x_ofs; +reg [9:0] x; + +reg [9:0] y_ofs; + +// y needs to be one line ahaed of the visible line +// render the first line at the end of the previous frame +// this depends on the timing that the sprite list is valid +// sprites values are copied at the start of vblank (line 240) + +// global offsets +wire [9:0] x_ofs_dx = 495 + { ~layer[1:0], 1'b0 }; +wire [9:0] y_ofs_dx = 257; +wire [9:0] x_ofs_dx_flipped = 17 - { ~layer[1:0], 1'b0 }; +wire [9:0] y_ofs_dx_flipped = 255; + +// calculate scrolling +wire [9:0] tile_x_unflipped = scroll_x_latch[layer[1:0]] + x_ofs_dx + scroll_x_offset; +wire [9:0] tile_y_unflipped = scroll_y_latch[layer[1:0]] + y_ofs_dx + scroll_y_offset; + +wire [9:0] tile_x_flipped = ( scroll_x_latch[layer[1:0]] + x_ofs_dx_flipped + scroll_x_offset - 112); +wire [9:0] tile_y_flipped = ( scroll_y_latch[layer[1:0]] + y_ofs_dx_flipped + scroll_y_offset - 40 ); + +// reverse tiles when flipped +wire [9:0] curr_x = tile_flip ? ( tile_x_flipped - x ) : ( tile_x_unflipped + x ); +wire [9:0] curr_y = tile_flip ? ( tile_y_flipped - y ) : ( tile_y_unflipped + y ); + +reg sprite_flip_x; +reg sprite_flip_y; + +reg [9:0] y; +//wire [9:0] y_flipped = ( flip ? (240 - y ) : y ); +//wire [9:0] sprite_buf_x = flip ? 320 - (sprite_x + sprite_pos_x ) : sprite_x + sprite_pos_x; // offset from left of frame + +wire [9:0] y_flipped = y ; +wire [9:0] sprite_buf_x = tile_flip + ( sprite_flip_x ? (sprite_pos_x + ~sprite_x) : (sprite_pos_x + sprite_x) ) ; // offset from left of frame + +reg [3:0] draw_state; +reg [3:0] sprite_state; +reg [3:0] tile_copy_state; +reg [3:0] sprite_copy_state; + +// pixel 4 bit colour +wire [3:0] tile_pix; +assign tile_pix = { tile_data[7-curr_x[2:0]], tile_data[15-curr_x[2:0]], tile_data[23-curr_x[2:0]], tile_data[31-curr_x[2:0]] }; + +wire [2:0] sprite_bit = ~sprite_x[2:0]; +wire [3:0] sprite_pix; +assign sprite_pix = { sprite_data[sprite_bit], sprite_data[8+sprite_bit], sprite_data[16+sprite_bit], sprite_data[24+sprite_bit] }; + +// two lines of buffer alternate +reg [9:0] tile_fb_addr_w; +wire [9:0] fb_addr_r = {vc[0], 9'b0 } + hc; + +reg [9:0] sprite_fb_addr_w; + +reg [31:0] tile_attr; + +// two lines worth for 4 layers (~8k) +// [15:14] = layer. +// [13:10] = prioity +// [9:4] = palette offset +// [3:0] = tile colour index. + +reg [3:0] tile_priority_buf [327:0]; +reg [3:0] sprite_priority_buf [327:0]; + +reg [9:0] sprite_x; // offset from left side of sprite +reg [9:0] sprite_y; + +reg [7:0] sprite_buf_num; + + +reg [1:0] vtotal_282_flag; + +always @ (posedge clk_sys) begin // Check System Vcount flag for 60Hz mode + if ({crtc[2][7:0], 1'b1 } == 269) + vtotal_282_flag <= 0; + else + vtotal_282_flag <= 1; +end + +reg [10:0] sprite_index ;//= sprite_attr_dout[10:0]; +reg [5:0] sprite_pal_addr;//= sprite_attr_dout[5:0]; +reg [1:0] sprite_priority;//= sprite_attr_dout[11:10]; +reg [9:0] sprite_pos_x ;//= sprite_attr_dout[15:7]; +reg [9:0] sprite_pos_y ;//= sprite_attr_dout[15:7]; + +always @ (posedge clk_sys) begin + if ( reset == 1 ) begin + sprite_state <= 0; + draw_state <= 0; + tile_rom_cs <= 0; + tile_copy_state <= 0; + sprite_copy_state <= 0; + tile_draw_state <= 0; + sprite_flip_x <= 0 ; + sprite_flip_y <= 0 ; + end else begin + // render sprites + // triggered when the tile rendering starts + if ( sprite_state == 0 && draw_state > 0 ) begin + sprite_num <= 9'h000; + sprite_x <= 0; + sprite_fb_w <= 1; + sprite_state <= 1; + sprite_fb_din <= 0; + sprite_fb_addr_w <= { y[0], 9'b0 }; + end else if ( sprite_state == 1 ) begin + // erase line buffer + sprite_fb_addr_w <= { y[0], 9'b0 } + sprite_x; + sprite_priority_buf[sprite_x] <= 0; + if ( sprite_x < 320 ) begin + sprite_x <= sprite_x + 1; + end else begin + sprite_x <= 0; + sprite_fb_w <= 0; + sprite_state <= 2; + end +// sprite y could be read first so reading the rest +// could be skipped if not in range of the current scanline + end else if ( sprite_state == 2 ) begin + // sprite num is valid now + sprite_fb_w <= 0; + spritebuf_attr_addr <= { sprite_num, 2'b00 } ; // sprite num + sprite_state <= 3; + end else if ( sprite_state == 3 ) begin + spritebuf_attr_addr <= { sprite_num, 2'b01 } ; // sprite colour / priority + sprite_state <= 4; + end else if ( sprite_state == 4 ) begin + // sprite num ready + spritebuf_attr_addr <= { sprite_num, 2'b10 } ; // sprite x pos + sprite_index <= spritebuf_attr_dout[10:0]; + sprite_state <= 5; + end else if ( sprite_state == 5 ) begin + // sprite colour ready + spritebuf_attr_addr <= { sprite_num, 2'b11 } ; // sprite y pos + + sprite_pal_addr <= spritebuf_attr_dout[5:0] ; + sprite_flip_x <= spritebuf_attr_dout[8]; + sprite_flip_y <= spritebuf_attr_dout[9]; + sprite_priority <= spritebuf_attr_dout[11:10] ; + + sprite_state <= 6; + end else if ( sprite_state == 6 ) begin + // sprite x ready + sprite_pos_x <= spritebuf_attr_dout[15:7] - 31; + sprite_state <= 7; + end else if ( sprite_state == 7 ) begin + // sprite y ready + sprite_pos_y <= spritebuf_attr_dout[15:7] - 16; + if ( spritebuf_attr_dout[15:7] == 9'h100 ) begin + if ( sprite_num < 9'h1ff ) begin + sprite_num <= sprite_num + 1; + sprite_state <= 2; + end else begin + sprite_state <= 15; + end + end else begin + sprite_state <= 8; + end + end else if ( sprite_state == 8 ) begin + // start loop + sprite_fb_w <= 0; + sprite_y <= y_flipped - sprite_pos_y; + // is sprite visible and is current y in sprite y range + // sprite pos can be negative? + if ( ( $signed(y_flipped) >= $signed(sprite_pos_y) ) && $signed(y_flipped) < ( $signed(sprite_pos_y) + 16 ) ) begin + sprite_state <= 9; + end else if ( sprite_num < 9'h1ff ) begin + sprite_num <= sprite_num + 1; + sprite_state <= 2; + end else begin + sprite_state <= 15; + end + end else if ( sprite_state == 9 ) begin + if ( sprite_flip_y == 0 ) begin + sprite_rom_addr <= { sprite_index, sprite_y[3:0], sprite_x[3] }; + end else begin + sprite_rom_addr <= { sprite_index, ~sprite_y[3:0], sprite_x[3] }; + end + sprite_state <= 10; + end else if ( sprite_state == 10 ) begin + sprite_state <= 11; + end else if ( sprite_state == 11 ) begin + sprite_data <= sprite_rom_dout; + sprite_state <= 12; + end else if ( sprite_state == 12 ) begin + sprite_fb_w <= 0; + // draw if pixel value not zero and priority >= previous sprite data + if ( sprite_pix > 0 && sprite_priority >= sprite_priority_buf[sprite_buf_x] ) begin + sprite_fb_din <= { 2'b11, sprite_priority, 2'b00, sprite_pal_addr, sprite_pix }; + + sprite_fb_addr_w <= { y[0], sprite_buf_x[8:0] }; + sprite_priority_buf[sprite_buf_x] <= sprite_priority; + sprite_fb_w <= 1; + end + if ( sprite_x < 15 ) begin + sprite_x <= sprite_x + 1; + if ( sprite_x[2:0] == 7 ) begin + // do recalc bitmap address + sprite_state <= 9; + end + end else if ( sprite_num < 9'h1ff ) begin + sprite_num <= sprite_num + 1; + sprite_x <= 0; + // need to load new attributes and size + sprite_state <= 2; + end else begin + // tile state machine will reset sprite_state when line completes. + sprite_state <= 14; // done + end + end else if ( sprite_state == 14 ) begin + sprite_fb_w <= 0; + sprite_state <= 15; // done + end + + // copy tile ram and scroll info + // not sure if this is needed. need to check to see when tile ram is updated. + if ( tile_copy_state == 0 && vc == 240 ) begin + tile_copy_state <= 1; + end else begin + // copy scroll registers + scroll_x_latch[0] <= scroll_x[0] - scroll_ofs_x; + scroll_x_latch[1] <= scroll_x[1] - scroll_ofs_x; + scroll_x_latch[2] <= scroll_x[2] - scroll_ofs_x; + scroll_x_latch[3] <= scroll_x[3] - scroll_ofs_x; + scroll_y_latch[0] <= scroll_y[0] - scroll_ofs_y; + scroll_y_latch[1] <= scroll_y[1] - scroll_ofs_y; + scroll_y_latch[2] <= scroll_y[2] - scroll_ofs_y; + scroll_y_latch[3] <= scroll_y[3] - scroll_ofs_y; + end + + // copy sprite attr/size to buffer + // write is delayed one clock + if ( sprite_copy_state == 0 && vc == 240 ) begin + sprite_copy_state <= 1; + sprite_attr_w <= 0; + sprite_attr_addr <= 11'h000; + end else if ( sprite_copy_state == 1 ) begin + // sprite_attr_addr valid + sprite_attr_w <= 1; + sprite_copy_state <= 2; + end else if ( sprite_copy_state == 2 ) begin + // sprite_attr_dout valid and write enabled + sprite_attr_addr <= sprite_attr_addr + 1; + // wait for read from source + if ( sprite_attr_addr == 11'h7ff ) begin + sprite_attr_w <= 0; + sprite_copy_state <= 3; + end else begin + sprite_copy_state <= 1; + end + end else if ( sprite_copy_state == 3 ) begin + // wait for vc > 240 so copy isn't triggered again this frame + if ( vc > 240 ) begin + sprite_copy_state <= 0; + end + end + + // tile state machine + if ( draw_state == 0 && vc == ({ crtc[2][7:0], 1'b1 } - (status[19] ? (vtotal_282_flag ? 5'd19 : 4'd7) : 3'd0)) ) begin // 282 Lines standard (263 Lines for 60Hz) + layer <= 4; // layer 4 is layer 0 but draws hidden and transparent + y <= 0; + draw_state <= 2; + sprite_state <= 0; + end else if ( draw_state == 2 ) begin + x <= 0; + x_ofs <= scroll_x_latch[layer[1:0]]; + y_ofs <= scroll_y_latch[layer[1:0]]; + // latch offset info + draw_state <= 3; + tile_draw_state <= 0; + end else if ( draw_state == 3 ) begin + if ( tile_draw_state == 0 ) begin + tile <= { layer[1:0], curr_y[8:3], curr_x[8:3] }; // works + tile_draw_state <= 4'h1; + end else if ( tile_draw_state == 1 ) begin + tile_draw_state <= 2; + end else if ( tile_draw_state == 2 ) begin + // latch attribute + tile_attr <= tile_attr_dout; + if ( layer == 4 || tile_attr_dout[15] == 0 ) begin + tile_draw_state <= 3; + end else begin + if ( x < 320 ) begin// 319 + tile_draw_state <= 3; + // do we need to read another tile? + // last pixel of this tile changes based on flip direction + if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin + draw_state <= 3; + tile_draw_state <= 0; + end + x <= x + 1; + end else if ( layer > 0 ) begin + layer <= layer - 1; + tile_fb_w <= 0; + draw_state <= 2; + end else begin + // done + tile_draw_state <= 7; + tile_fb_w <= 0; + end + end + end else if ( tile_draw_state == 3 ) begin + // read bitmap info + tile_rom_cs <= 1; + tile_rom_addr <= { tile_idx, curr_y[2:0] }; + tile_draw_state <= 4; + end else if ( tile_draw_state == 4 ) begin + // wait for bitmap ram ready + if ( tile_rom_data_valid ) begin + // latch data and deassert cs + tile_data <= tile_rom_data; + tile_draw_state <= 5; + tile_rom_cs <= 0; + end + end else if ( tile_draw_state == 5 ) begin + tile_fb_w <= 0; + tile_fb_addr_w <= { y[0], 9'b0 } + x; + // force render of first layer. + // if layer == 4 then tile_pix == 0 is not transparent + // layer 4 is really layer 0 + if ( layer == 4 ) begin + tile_priority_buf[x] <= 0; //tile_pix == 0 ? 0 : tile_priority; + //fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; + fb_din <= { layer[1:0], 4'b0, tile_palette_idx, tile_pix }; + tile_fb_w <= 1; + end else if (tile_hidden == 0 && tile_pix > 0 && tile_priority > 0 && tile_priority >= tile_priority_buf[x] ) begin + tile_priority_buf[x] <= tile_priority; + // if tile hidden then make the pallette index 0. ie transparent + fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; + tile_fb_w <= 1; + end + if ( x < 320 ) begin// 319 + // do we need to read another tile? + // last pixel of this tile changes based on flip direction + if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin + draw_state <= 3; + tile_draw_state <= 0; + end + x <= x + 1; + end else if ( layer > 0 ) begin + layer <= layer - 1; + tile_fb_w <= 0; + draw_state <= 2; + end else begin + // done + tile_draw_state <= 7; + tile_fb_w <= 0; + end + end else if ( tile_draw_state == 7 ) begin + // wait for next line or quit + if ( y == 239 ) begin + draw_state <= 0; + end else if ( hc == (status[19] ? 9'd444 : 9'd449) ) begin // 450 Lines standard (445 Lines for NTSC standard 15.73kHz line freq) + y <= y + 1; + draw_state <= 2; + sprite_state <= 0; + layer <= 4; + end + end + end + end +end + +// render +reg draw_sprite; + +// two lines worth for 4 layers (~8k) +// [15:14] = layer. +// [13:10] = prioity +// [9:4] = palette offset +// [3:0] = tile colour index. + +// there are 10 70MHz cycles per pixel. clk7_count from 0-9 + +// dac values based on 120 ohm driver for the resistor dac and 75 ohm output. 4.7k, 2.2k, 1k, 470, 220 +// modeled in spice +wire [7:0] dac [0:31] = '{0,12,25,36,50,61,73,83,91,100,111,120,131,139,149,157,145,154,162,170,180,187,195,202,208,214,222,228,236,242,249,255}; + +always @ (posedge clk_sys) begin + if ( clk7_count == 4 ) begin + tile_palette_addr <= tile_fb_out[9:0]; + sprite_palette_addr <= sprite_fb_out[9:0]; + end else if ( clk7_count == 6 ) begin + // if palette index is zero then it's from layer 3 and is transparent render as blank (black). + rgb <= { dac[tile_palette_dout[4:0]], dac[tile_palette_dout[9:5]], dac[tile_palette_dout[14:10]] }; + // if not transparent and sprite is higher priority + if ( sprite_fb_out[3:0] > 0 && (sprite_fb_out[13:10] >= tile_fb_out[13:10]) ) begin + // draw sprite + rgb <= { dac[sprite_palette_dout[4:0]], dac[sprite_palette_dout[9:5]], dac[sprite_palette_dout[14:10]] }; + end + end +end + +// tile data buffer + +reg tile_buf_w; +reg [31:0] tile_buf_din; +reg [31:0] tile_buf_dout; +reg [13:0] tile_buf_addr; + +dual_port_ram #(.LEN(16384), .DATA_WIDTH(32)) ram_tile_buf ( + .clock_a ( clk_sys ), + .address_a ( tile[13:0] ), + .wren_a ( tile_buf_w ), + .data_a ( tile_attr_dout ), + + .clock_b ( clk_sys ), + .address_b ( tile[13:0] ), // only read the tile # for now + .wren_b ( 0 ), + .q_b ( tile_buf_dout ) +); + +// tile attribute ram. each tile attribute is 2 16bit words +// pppp ---- --cc cccc httt tttt tttt tttt = Tile number (0 - $7fff) +// indirect access through offset register +dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_h ( + .clock_a ( clk_10M ), + .address_a ( curr_tile_ofs ), + .wren_a ( tile_attr_cs & !cpu_rw ), + .data_a ( cpu_dout ), + .q_a ( cpu_tile_dout_attr ), + + .clock_b ( clk_sys ), + .address_b ( tile[13:0] ), // only read the tile # for now + .wren_b ( 0 ), + .q_b ( tile_attr_dout[31:16] ) +); + +dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_l ( + .clock_a ( clk_10M ), + .address_a ( curr_tile_ofs ), + .wren_a ( tile_num_cs & !cpu_rw ), + .data_a ( cpu_dout ), + .q_a ( cpu_tile_dout_num ), + + .clock_b ( clk_sys ), + .address_b ( tile[13:0] ), // only read the tile # for now + .wren_b ( 0 ), + .q_b ( tile_attr_dout[15:0] ) +); + +// tiles 1024 15 bit values. index is ( 6 bits from tile attribute, 4 bits from bitmap ) +// background palette ram low +// does this need to be byte addressable? +dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_l ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[10:1] ), + .wren_a ( tile_palette_cs & !cpu_rw & !cpu_lds_n), + .data_a ( cpu_dout[7:0] ), + .q_a ( tile_palette_cpu_dout[7:0] ), + + .clock_b ( clk_sys ), + .address_b ( tile_palette_addr ), + .wren_b ( 0 ), + .q_b ( tile_palette_dout[7:0] ) +); + +// background palette ram high +dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_h ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[10:1] ), + .wren_a ( tile_palette_cs & !cpu_rw & !cpu_uds_n), + .data_a ( cpu_dout[15:8] ), + .q_a ( tile_palette_cpu_dout[15:8] ), + + .clock_b ( clk_sys ), + .address_b ( tile_palette_addr ), + .wren_b ( 0 ), + .q_b ( tile_palette_dout[15:8] ) +); + +// sprite palette ram low +// does this need to be byte addressable? +dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_l ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[10:1] ), + .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_lds_n), + .data_a ( cpu_dout[7:0] ), + .q_a ( sprite_palette_cpu_dout[7:0] ), + + .clock_b ( clk_sys ), + .address_b ( sprite_palette_addr ), + .wren_b ( 0 ), + .q_b ( sprite_palette_dout[7:0] ) +); + +// background palette ram high +dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_h ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[10:1] ), + .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_uds_n), + .data_a ( cpu_dout[15:8] ), + .q_a ( sprite_palette_cpu_dout[15:8] ), + + .clock_b ( clk_sys ), + .address_b ( sprite_palette_addr ), + .wren_b ( 0 ), + .q_b ( sprite_palette_dout[15:8] ) +); + + +// main 68k ram low +dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_L ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[14:1] ), + .wren_a ( !cpu_rw & ram_cs & !cpu_lds_n ), + .data_a ( cpu_dout[7:0] ), + .q_a ( ram_dout[7:0] ) +); + +// main 68k ram high +dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_H ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[14:1] ), + .wren_a ( !cpu_rw & ram_cs & !cpu_uds_n ), + .data_a ( cpu_dout[15:8] ), + .q_a ( ram_dout[15:8] ) +); + + +//wire [15:0] z80_shared_addr = z80_addr - 16'h8000; +//wire [23:0] m68k_shard_addr = cpu_a - 24'h040000; + +// z80 and 68k shared ram +// 4k +dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) shared_ram ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[12:1] ), + .wren_a ( shared_ram_cs & !cpu_rw & !cpu_lds_n), + .data_a ( cpu_dout[7:0] ), + .q_a ( cpu_shared_dout[7:0] ), + + .clock_b ( clk_3_5M ), // z80 clock is 3.5M + .address_b ( z80_addr[11:0] ), + .data_b ( z80_dout ), + .wren_b ( sound_ram_1_cs & ~z80_wr_n ), + .q_b ( z80_shared_dout ) +); + +reg sprite_attr_w ; +reg [10:0] sprite_attr_addr; +wire [15:0] sprite_attr_dout; +wire [15:0] sprite_ram_dout; + +reg [10:0] spritebuf_attr_addr; +wire [15:0] spritebuf_attr_dout; + +dual_port_ram #(.LEN(2048), .DATA_WIDTH(8)) sprite_ram_l +( + .clock_a( clk_10M ), + .address_a( cpu_a[11:1] ), + .wren_a( sprite_ram_cs & !cpu_rw & !cpu_lds_n), + .data_a( cpu_dout[7:0] ), + .q_a( sprite_ram_dout[7:0] ), + + .clock_b( clk_sys ), + .address_b( sprite_attr_addr ), + .wren_b( 0 ), + .q_b( sprite_attr_dout[7:0] ) +); + +dual_port_ram #(.LEN(2048), .DATA_WIDTH(8)) sprite_ram_h +( + .clock_a( clk_10M ), + .address_a( cpu_a[11:1] ), + .wren_a( sprite_ram_cs & !cpu_rw & !cpu_uds_n), + .data_a( cpu_dout[15:8] ), + .q_a( sprite_ram_dout[15:8] ), + + .clock_b( clk_sys ), + .address_b( sprite_attr_addr ), + .wren_b( 0 ), + .q_b( sprite_attr_dout[15:8] ) +); + +dual_port_ram #(.LEN(2048), .DATA_WIDTH(16)) spritebuf_ram +( + .clock_a( clk_sys ), + .address_a( sprite_attr_addr ), + .wren_a( sprite_attr_w ), + .data_a( sprite_attr_dout ), + .q_a( ), + + .clock_b( clk_sys ), + .address_b( spritebuf_attr_addr ), + .wren_b( 0 ), + .q_b( spritebuf_attr_dout ) +); + + +reg [15:0] sprite_rom_addr ; +wire [31:0] sprite_rom_dout ; + +wire sprite_rom_w = ioctl_download & ioctl_wr & ( ioctl_index == 0 ); + +wire sbit0 = (ioctl_addr >= 24'h180000 && ioctl_addr < 24'h190000 ); +wire sbit1 = (ioctl_addr >= 24'h190000 && ioctl_addr < 24'h1a0000 ); +wire sbit2 = (ioctl_addr >= 24'h1a0000 && ioctl_addr < 24'h1b0000 ); +wire sbit3 = (ioctl_addr >= 24'h1b0000 && ioctl_addr < 24'h1c0000 ); + +dual_port_ram #(.LEN(65536), .DATA_WIDTH(8)) sprite_rom_0 +( + .clock_a( clk_sys ), + .address_a( ioctl_addr[15:0] ), + .wren_a( sprite_rom_w & sbit0 ), + .data_a( ioctl_dout ), + .q_a( ), + + .clock_b( clk_sys ), + .address_b( sprite_rom_addr ), + .wren_b( 0 ), + .q_b( sprite_rom_dout[7:0] ) +); + +dual_port_ram #(.LEN(65536), .DATA_WIDTH(8)) sprite_rom_1 +( + .clock_a ( clk_sys ), + .address_a ( ioctl_addr[15:0] ), + .wren_a( sprite_rom_w & sbit1 ), + .data_a ( ioctl_dout ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_rom_addr ), + .wren_b ( 0 ), + .q_b ( sprite_rom_dout[15:8] ) +); + +dual_port_ram #(.LEN(65536), .DATA_WIDTH(8)) sprite_rom_2 +( + .clock_a ( clk_sys ), + .address_a ( ioctl_addr[15:0] ), + .wren_a( sprite_rom_w & sbit2 ), + .data_a ( ioctl_dout ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_rom_addr ), + .wren_b ( 0 ), + .q_b ( sprite_rom_dout[23:16] ) +); + +dual_port_ram #(.LEN(65536), .DATA_WIDTH(8)) sprite_rom_3 +( + .clock_a ( clk_sys ), + .address_a ( ioctl_addr[15:0] ), + .wren_a( sprite_rom_w & sbit3 ), + .data_a ( ioctl_dout ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_rom_addr ), + .wren_b ( 0 ), + .q_b ( sprite_rom_dout[31:24] ) +); + +reg [22:0] sdram_addr; +reg [31:0] sdram_data; +reg sdram_we; +reg sdram_req; + +wire sdram_ack; +wire sdram_valid; +wire [31:0] sdram_q; + +sdram #(.CLK_FREQ(70.0)) sdram +( + .reset(~pll_locked), + .clk(clk_sys), + + // controller interface + .addr(sdram_addr), + .data(sdram_data), + .we(sdram_we), + .req(sdram_req), + + .ack(sdram_ack), + .valid(sdram_valid), + .q(sdram_q), + + // SDRAM interface + .sdram_a(SDRAM_A), + .sdram_ba(SDRAM_BA), + .sdram_dq(SDRAM_DQ), + .sdram_cke(SDRAM_CKE), + .sdram_cs_n(SDRAM_nCS), + .sdram_ras_n(SDRAM_nRAS), + .sdram_cas_n(SDRAM_nCAS), + .sdram_we_n(SDRAM_nWE), + .sdram_dqml(SDRAM_DQML), + .sdram_dqmh(SDRAM_DQMH) +); + +wire prog_cache_rom_cs; +wire [22:0] prog_cache_addr; +wire [15:0] prog_cache_data; +wire prog_cache_valid; + +wire [15:0] prog_rom_data; +wire prog_rom_data_valid; + +reg tile_rom_cs; +reg [17:0] tile_rom_addr; +wire [31:0] tile_rom_data; +wire tile_rom_data_valid; + +wire tile_cache_cs; +wire [17:0] tile_cache_addr; +wire [31:0] tile_cache_data; +wire tile_cache_valid; + +reg [31:0] tile_data; + +//wire sprite_rom_cs; +//wire [17:0] sprite_rom_addr; +//wire [31:0] sprite_rom_data; +//wire sprite_rom_data_valid; + +reg [31:0] sprite_data; + +wire [15:0] sound_rom_1_addr; +wire [7:0] sound_rom_1_data; +wire sound_rom_1_data_valid; + +// sdram priority based rom controller +// is a oe needed? +rom_controller rom_controller +( + .reset(reset), + + // clock + .clk(clk_sys), + + // program ROM interface + .prog_rom_cs(prog_cache_rom_cs), + .prog_rom_oe(1), + .prog_rom_addr(prog_cache_addr), + .prog_rom_data(prog_cache_data), + .prog_rom_data_valid(prog_cache_valid), + + // character ROM interface + .tile_rom_cs(tile_cache_cs), + .tile_rom_oe(1), + .tile_rom_addr(tile_cache_addr), + .tile_rom_data(tile_cache_data), + .tile_rom_data_valid(tile_cache_valid), + + + // sprite ROM interface +// .sprite_rom_cs(sprite_rom_cs), +// .sprite_rom_oe(1), +// .sprite_rom_addr(sprite_rom_addr), +// .sprite_rom_data(sprite_rom_data), +// .sprite_rom_data_valid(sprite_rom_data_valid), + + // sound ROM #1 interface + .sound_rom_1_cs(sound_rom_1_cs), + .sound_rom_1_oe(1), + .sound_rom_1_addr(z80_addr), + .sound_rom_1_data(sound_rom_1_data), + .sound_rom_1_data_valid(sound_rom_1_data_valid), + + // IOCTL interface + .ioctl_addr(ioctl_addr), + .ioctl_data(ioctl_dout), + .ioctl_index(ioctl_index), + .ioctl_wr(ioctl_wr), + .ioctl_download(ioctl_download), + + // SDRAM interface + .sdram_addr(sdram_addr), + .sdram_data(sdram_data), + .sdram_we(sdram_we), + .sdram_req(sdram_req), + .sdram_ack(sdram_ack), + .sdram_valid(sdram_valid), + .sdram_q(sdram_q) +); + + +cache prog_cache +( + .reset(reset), + .clk(clk_sys), + + // client + .cache_req(prog_rom_cs), + .cache_addr(cpu_a[23:1]), + .cache_valid(prog_rom_data_valid), + .cache_data(prog_rom_data), + + // to rom controller + .rom_req(prog_cache_rom_cs), + .rom_addr(prog_cache_addr), + .rom_valid(prog_cache_valid), + .rom_data(prog_cache_data) +); + +tile_cache tile_cache +( + .reset(reset), + .clk(clk_sys), + + // client + .cache_req(tile_rom_cs), + .cache_addr(tile_rom_addr), + .cache_data(tile_rom_data), + .cache_valid(tile_rom_data_valid), + + // to rom controller + .rom_req(tile_cache_cs), + .rom_addr(tile_cache_addr), + .rom_data(tile_cache_data), + .rom_valid(tile_cache_valid) +); + +endmodule + + +module cc_shifter +( + input clk_out, + input i, + output o +); + +// We use a two-stages shift-register to synchronize SignalIn_clkA to the clkB clock domain +reg [1:0] r; + +assign o = r[1]; // new signal synchronized to (=ready to be used in) clkB domain + +always @(posedge clk_out) begin + r[0] <= i; + r[1] <= r[0]; // notice that we use clkB +end + +endmodule + + diff --git a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_rallybike/rallybike.sv b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_rallybike/rallybike.sv index 3d64d607..79373e0e 100644 --- a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_rallybike/rallybike.sv +++ b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_rallybike/rallybike.sv @@ -1,4 +1,5 @@ //============================================================================ +// Toaplan Hardware v1 HW top-level for MiST // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free @@ -13,1976 +14,283 @@ // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// //============================================================================ -`default_nettype none +module RallyBike( + output LED, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_HS, + output VGA_VS, + output AUDIO_L, + output AUDIO_R, + input SPI_SCK, + inout SPI_DO, + input SPI_DI, + input SPI_SS2, + input SPI_SS3, + input SPI_SS4, + input CONF_DATA0, + input CLOCK_27, -module emu -( - //Master input clock - input CLK_50M, - - //Async reset from top-level module. - //Can be used as initial reset. - input RESET, - - //Must be passed to hps_io module - inout [48:0] HPS_BUS, - - //Base video clock. Usually equals to CLK_SYS. - output CLK_VIDEO, - - //Multiple resolutions are supported using different CE_PIXEL rates. - //Must be based on CLK_VIDEO - output CE_PIXEL, - - //Video aspect ratio for HDMI. Most retro systems have ratio 4:3. - //if VIDEO_ARX[12] or VIDEO_ARY[12] is set then [11:0] contains scaled size instead of aspect ratio. - output [12:0] VIDEO_ARX, - output [12:0] VIDEO_ARY, - - output [7:0] VGA_R, - output [7:0] VGA_G, - output [7:0] VGA_B, - output VGA_HS, - output VGA_VS, - output VGA_DE, // = ~(VBlank | HBlank) - output VGA_F1, - output [2:0] VGA_SL, - output VGA_SCALER, // Force VGA scaler - - input [11:0] HDMI_WIDTH, - input [11:0] HDMI_HEIGHT, - output HDMI_FREEZE, - -`ifdef MISTER_FB - // Use framebuffer in DDRAM (USE_FB=1 in qsf) - // FB_FORMAT: - // [2:0] : 011=8bpp(palette) 100=16bpp 101=24bpp 110=32bpp - // [3] : 0=16bits 565 1=16bits 1555 - // [4] : 0=RGB 1=BGR (for 16/24/32 modes) - // - // FB_STRIDE either 0 (rounded to 256 bytes) or multiple of pixel size (in bytes) - output FB_EN, - output [4:0] FB_FORMAT, - output [11:0] FB_WIDTH, - output [11:0] FB_HEIGHT, - output [31:0] FB_BASE, - output [13:0] FB_STRIDE, - input FB_VBL, - input FB_LL, - output FB_FORCE_BLANK, - -`ifdef MISTER_FB_PALETTE - // Palette control for 8bit modes. - // Ignored for other video modes. - output FB_PAL_CLK, - output [7:0] FB_PAL_ADDR, - output [23:0] FB_PAL_DOUT, - input [23:0] FB_PAL_DIN, - output FB_PAL_WR, -`endif -`endif - - output LED_USER, // 1 - ON, 0 - OFF. - - // b[1]: 0 - LED status is system status OR'd with b[0] - // 1 - LED status is controled solely by b[0] - // hint: supply 2'b00 to let the system control the LED. - output [1:0] LED_POWER, - output [1:0] LED_DISK, - - // I/O board button press simulation (active high) - // b[1]: user button - // b[0]: osd button - output [1:0] BUTTONS, - - //Audio - input CLK_AUDIO, // 24.576 MHz - output [15:0] AUDIO_L, - output [15:0] AUDIO_R, - output AUDIO_S, // 1 - signed audio samples, 0 - unsigned - output [1:0] AUDIO_MIX, // 0 - no mix, 1 - 25%, 2 - 50%, 3 - 100% (mono) - - //ADC - inout [3:0] ADC_BUS, - - //SD-SPI - output SD_SCK, - output SD_MOSI, - input SD_MISO, - output SD_CS, - input SD_CD, - - //High latency DDR3 RAM interface - //Use for non-critical time purposes - output DDRAM_CLK, - input DDRAM_BUSY, - output [7:0] DDRAM_BURSTCNT, - output [28:0] DDRAM_ADDR, - input [63:0] DDRAM_DOUT, - input DDRAM_DOUT_READY, - output DDRAM_RD, - output [63:0] DDRAM_DIN, - output [7:0] DDRAM_BE, - output DDRAM_WE, - - //SDRAM interface with lower latency - output SDRAM_CLK, - output SDRAM_CKE, - output [12:0] SDRAM_A, - output [1:0] SDRAM_BA, - inout [15:0] SDRAM_DQ, - output SDRAM_DQML, - output SDRAM_DQMH, - output SDRAM_nCS, - output SDRAM_nCAS, - output SDRAM_nRAS, - output SDRAM_nWE, - -`ifdef MISTER_DUAL_SDRAM - //Secondary SDRAM - //Set all output SDRAM_* signals to Z ASAP if SDRAM2_EN is 0 - input SDRAM2_EN, - output SDRAM2_CLK, - output [12:0] SDRAM2_A, - output [1:0] SDRAM2_BA, - inout [15:0] SDRAM2_DQ, - output SDRAM2_nCS, - output SDRAM2_nCAS, - output SDRAM2_nRAS, - output SDRAM2_nWE, -`endif - - input UART_CTS, - output UART_RTS, - input UART_RXD, - output UART_TXD, - output UART_DTR, - input UART_DSR, - -`ifdef MISTER_ENABLE_YC - output [39:0] CHROMA_PHASE_INC, - output YC_EN, - output PALFLAG, -`endif - - // Open-drain User port. - // 0 - D+/RX - // 1 - D-/TX - // 2..6 - USR2..USR6 - // Set USER_OUT to 1 to read from USER_IN. - input [6:0] USER_IN, - output [6:0] USER_OUT, - - input OSD_STATUS + output [12:0] SDRAM_A, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nWE, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nCS, + output [1:0] SDRAM_BA, + output SDRAM_CLK, + output SDRAM_CKE ); -///////// Default values for ports not used in this core ///////// +`include "../build_id.v" +//`include "defs.v" -assign ADC_BUS = 'Z; -assign USER_OUT = 0; -assign {UART_RTS, UART_TXD, UART_DTR} = 0; -assign {SD_SCK, SD_MOSI, SD_CS} = 'Z; -//assign {SDRAM_DQ, SDRAM_A, SDRAM_BA, SDRAM_CLK, SDRAM_CKE, SDRAM_DQML, SDRAM_DQMH, SDRAM_nWE, SDRAM_nCAS, SDRAM_nRAS, SDRAM_nCS} = 'Z; -//assign {DDRAM_CLK, DDRAM_BURSTCNT, DDRAM_ADDR, DDRAM_DIN, DDRAM_BE, DDRAM_RD, DDRAM_WE} = '0; -assign VGA_F1 = 0; -assign VGA_SCALER = 0; -assign HDMI_FREEZE = 0; +`define CORE_NAME "RallyBike" +assign LED = ~ioctl_downl; +assign SDRAM_CLK = clk_72; +assign SDRAM_CKE = 1; -assign AUDIO_MIX = 0; -assign LED_USER = ioctl_download & cpu_a[0]; -assign LED_DISK = 0; -assign LED_POWER = 0; -assign BUTTONS = 0; - -// Status Bit Map: -// Upper Case Lower Case -// 0 1 2 3 4 5 6 -// 01234567890123456789012345678901 23456789012345678901234567890123 -// 0123456789ABCDEFGHIJKLMNOPQRSTUV 0123456789ABCDEFGHIJKLMNOPQRSTUV -// X XXXXXXXX XX X X XXXXXXXX X XX XXXXXXXX - -wire [1:0] aspect_ratio = status[9:8]; -wire orientation = ~status[3]; -wire [2:0] scan_lines = status[6:4]; -reg refresh_mod; -reg new_vmode; - -always @(posedge clk_sys) begin - if (refresh_mod != status[19]) begin - refresh_mod <= status[19]; - new_vmode <= ~new_vmode; - end -end - -wire [3:0] hs_offset = status[27:24]; -wire [3:0] vs_offset = status[31:28]; -wire [3:0] hs_width = status[59:56]; -wire [3:0] vs_width = status[63:60]; - -assign VIDEO_ARX = (!aspect_ratio) ? (orientation ? 8'd4 : 8'd3) : (aspect_ratio - 1'd1); -assign VIDEO_ARY = (!aspect_ratio) ? (orientation ? 8'd3 : 8'd4) : 12'd0; - -`include "build_id.v" localparam CONF_STR = { - "Toaplan V1;;", - "-;", - "P1,Video Settings;", - "P1-;", - "P1O89,Aspect Ratio,Original,Full Screen,[ARC1],[ARC2];", - "P1O3,Orientation,Horz,Vert;", - "P1-;", - "P1O46,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%,CRT 75%,CRT 100%;", - "P1OA,Force Scandoubler,Off,On;", - "P1-;", - "P1O7,Video Mode,NTSC,PAL;", - "P1OM,Video Signal,RGBS/YPbPr,Y/C;", - "P1OJ,Refresh Rate,Native,NTSC;", - "P1-;", - "P1OOR,H-sync Pos Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", - "P1OSV,V-sync Pos Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", - "P1-;", - "P1oOR,H-sync Width Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", - "P1oSV,V-sync Width Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", - "P1-;", - "P2,Audio Settings;", - "P2-;", - "P2oBC,OPL2 Volume,Default,50%,25%,0%;", - "P2-;", - "-;", - "P3,Core Options;", - "P3-;", - "P3OF,68k Freq.,10Mhz,17.5MHz;", - "P3-;", - "P3o0,Scroll Debug,Off,On;", - "P3-;", - "DIP;", - "-;", - "OK,Pause OSD,Off,When Open;", - "OL,Dim Video,Off,10s;", - "-;", - "R0,Reset;", - "V,v",`BUILD_DATE + `CORE_NAME, ";;", + "O2,Rotate Controls,Off,On;", + "O34,Scanlines,Off,25%,50%,75%;", + "O5,Blending,Off,On;", + "O6,Joystick Swap,Off,On;", + "DIP;", + "T0,Reset;", + "V,v1.20.",`BUILD_DATE }; -wire hps_forced_scandoubler; -wire forced_scandoubler = hps_forced_scandoubler | status[10]; +wire rotate = status[2]; +wire [1:0] scanlines = status[4:3]; +wire blend = status[5]; +wire joyswap = status[6]; -wire [1:0] buttons; -wire [63:0] status; -wire [10:0] ps2_key; -wire [15:0] joy0, joy1; +wire [7:0] dsw1 = status[23:16]; +wire [7:0] dsw2 = status[31:24]; +reg [7:0] dsw_m68k, dsw_sp85; +reg [7:0] p1, p2; +wire flipped; +wire key_service = m_fire1[4]; +wire key_test = m_fire1[3]; -hps_io #(.CONF_STR(CONF_STR)) hps_io -( - .clk_sys(clk_sys), - .HPS_BUS(HPS_BUS), - .buttons(buttons), - .ps2_key(ps2_key), - .status(status), - .status_menumask(direct_video), - .forced_scandoubler(hps_forced_scandoubler), - .gamma_bus(gamma_bus), - .new_vmode(new_vmode), - .direct_video(direct_video), - .video_rotated(video_rotated), - - .ioctl_download(ioctl_download), - .ioctl_upload(ioctl_upload), - .ioctl_wr(ioctl_wr), - .ioctl_addr(ioctl_addr), - .ioctl_dout(ioctl_dout), - .ioctl_din(ioctl_din), - .ioctl_index(ioctl_index), - .ioctl_wait(ioctl_wait), - - .joystick_0(joy0), - .joystick_1(joy1) -); - -// INPUT - -// 8 dip switches of 8 bits -reg [7:0] sw[8]; -always @(posedge clk_sys) begin - if (ioctl_wr && (ioctl_index==254) && !ioctl_addr[24:3]) begin - sw[ioctl_addr[2:0]] <= ioctl_dout; - end -end - -wire direct_video; - -wire ioctl_download; -wire ioctl_upload; -wire ioctl_upload_req; -wire ioctl_wait; -wire ioctl_wr; -wire [15:0] ioctl_index; -wire [26:0] ioctl_addr; -wire [15:0] ioctl_dout; -wire [15:0] ioctl_din; - -wire tile_priority_type; -wire [15:0] scroll_y_offset; -wire [15:0] scroll_x_offset = 30; - -wire [21:0] gamma_bus; - -// -// Inputs tied to z80_din -reg [7:0] p1; -reg [7:0] p2; -reg [7:0] z80_dswa; -reg [7:0] z80_dswb; -reg [7:0] z80_tjump; -reg [7:0] system; - -always @ (posedge clk_sys ) begin - - p1 <= { 1'b0, p1_buttons[2:0], p1_right, p1_left, p1_down, p1_up }; - p2 <= { 1'b0, p2_buttons[2:0], p2_right, p2_left, p2_down, p2_up }; - z80_dswa <= sw[0]; - z80_dswb <= sw[1]; - z80_tjump <= sw[2]; - - if ( status[32] == 1 ) begin - system <= { vbl, start2 | p1_buttons[3], start1 | p1_buttons[3], coin_b, coin_a, service | status[32], key_tilt, key_service }; - end else begin - system <= { vbl, start2, start1, coin_b, coin_a, service, key_tilt, key_service }; - end -end - -reg p1_right; -reg p1_left; -reg p1_down; -reg p1_up; -reg [3:0] p1_buttons; - -reg p2_right; -reg p2_left; -reg p2_down; -reg p2_up; -reg [3:0] p2_buttons; - -reg start1; -reg start2; -reg coin_a; -reg coin_b; -reg b_pause; -reg service; - -always @ * begin - p1_right <= joy0[0] | key_p1_right; - p1_left <= joy0[1] | key_p1_left; - p1_down <= joy0[2] | key_p1_down; - p1_up <= joy0[3] | key_p1_up; - p1_buttons <= joy0[7:4] | {key_p1_c, key_p1_b, key_p1_a}; - - p2_right <= joy1[0] | key_p2_right; - p2_left <= joy1[1] | key_p2_left; - p2_down <= joy1[2] | key_p2_down; - p2_up <= joy1[3] | key_p2_up; - p2_buttons <= joy1[7:4] | {key_p2_c, key_p2_b, key_p2_a}; - - start1 <= joy0[8] | joy1[8] | key_start_1p; - start2 <= joy0[9] | joy1[9] | key_start_2p; - - coin_a <= joy0[10] | joy1[10] | key_coin_a; - coin_b <= joy0[11] | joy1[11] | key_coin_b; - - b_pause <= joy0[12] | key_pause; - service <= key_test; -end - -// Keyboard handler - -reg key_start_1p, key_start_2p, key_coin_a, key_coin_b; -reg key_tilt, key_test, key_reset, key_service, key_pause; - -reg key_p1_up, key_p1_left, key_p1_down, key_p1_right, key_p1_a, key_p1_b, key_p1_c; -reg key_p2_up, key_p2_left, key_p2_down, key_p2_right, key_p2_a, key_p2_b, key_p2_c; - -wire pressed = ps2_key[9]; - -always @(posedge clk_sys) begin - reg old_state; - old_state <= ps2_key[10]; - if ( old_state ^ ps2_key[10] ) begin - casex ( ps2_key[8:0] ) - 'h016 : key_start_1p <= pressed; // 1 - 'h01E : key_start_2p <= pressed; // 2 - 'h02E : key_coin_a <= pressed; // 5 - 'h036 : key_coin_b <= pressed; // 6 - 'h006 : key_test <= key_test ^ pressed; // f2 - 'h004 : key_reset <= pressed; // f3 - 'h046 : key_service <= pressed; // 9 - 'h02C : key_tilt <= pressed; // t - 'h04D : key_pause <= pressed; // p - - 'h175 : key_p1_up <= pressed; // up - 'h172 : key_p1_down <= pressed; // down - 'h16B : key_p1_left <= pressed; // left - 'h174 : key_p1_right <= pressed; // right - 'h014 : key_p1_a <= pressed; // lctrl - 'h011 : key_p1_b <= pressed; // lalt - 'h029 : key_p1_c <= pressed; // spacebar - - 'h02D : key_p2_up <= pressed; // r - 'h02B : key_p2_down <= pressed; // f - 'h023 : key_p2_left <= pressed; // d - 'h034 : key_p2_right <= pressed; // g - 'h01C : key_p2_a <= pressed; // a - 'h01B : key_p2_b <= pressed; // s - 'h015 : key_p2_c <= pressed; // q - endcase - end -end +wire clk_72; wire pll_locked; +pll_mist pll( + .inclk0(CLOCK_27), + .c0(clk_72), + .locked(pll_locked) + ); -wire clk_sys; -wire turbo_68k = status[15]; -reg clk_3_5M, clk_7M, clk_10M, clk_14M; - -wire clk_70M; - -pll pll -( - .refclk(CLK_50M), - .rst(0), - .outclk_0(clk_sys), - .outclk_1(clk_70M), - .locked(pll_locked) -); - -assign SDRAM_CLK = clk_70M; - -localparam CLKSYS=70; - -reg [5:0] clk14_count; -reg [5:0] clk10_count; -reg [5:0] clk7_count; -reg [5:0] clk_3_5_count; - -always @ (posedge clk_sys ) begin - clk_10M <= 0; - if ( turbo_68k == 0 ) begin - // standard speed 20MHz = 10MHz 68k - case (clk10_count) - 1: clk_10M <= 1; - 3: clk_10M <= 1; - endcase - if ( clk10_count == 6 ) begin - clk10_count <= 0; - end else if ( pause_cpu == 0 ) begin - clk10_count <= clk10_count + 1; - end - end else begin - // standard speed 35MHz = 17.5MHz 68k - case (clk10_count) - 1: clk_10M <= 1; - endcase - if ( clk10_count == 1 ) begin - clk10_count <= 0; - end else if ( pause_cpu == 0 ) begin - clk10_count <= clk10_count + 1; - end - end - - clk_7M <= ( clk7_count == 0); - if ( clk7_count == 9 ) begin - clk7_count <= 0; - end else begin - clk7_count <= clk7_count + 1; - end - - clk_14M <= ( clk14_count == 0); - if ( clk14_count == 4 ) begin - clk14_count <= 0; - end else begin - clk14_count <= clk14_count + 1; - end - - clk_3_5M <= ( clk_3_5_count == 0); - if ( clk_3_5_count == 19 ) begin - clk_3_5_count <= 0; - end else if ( pause_cpu == 0 ) begin - clk_3_5_count <= clk_3_5_count + 1; - end +// reset generation +reg reset = 1; +reg rom_loaded = 0; +always @(posedge clk_72) begin + reg ioctl_downlD; + ioctl_downlD <= ioctl_downl; + if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1; + reset <= status[0] | buttons[1] | ~rom_loaded | ioctl_downl; end -wire reset; -assign reset = RESET | status[0] | (ioctl_download & !ioctl_index) | buttons[1] | key_reset; +// ARM connection +wire [63:0] status; +wire [1:0] buttons; +wire [1:0] switches; +wire [31:0] joystick_0; +wire [31:0] joystick_1; +wire scandoublerD; +wire ypbpr; +wire no_csync; +wire key_strobe; +wire key_pressed; +wire [7:0] key_code; +wire [6:0] core_mod; -////////////////////////////////////////////////////////////////// -wire rotate_ccw = 1; -wire no_rotate = orientation | direct_video; -wire video_rotated; +user_io #( + .STRLEN($size(CONF_STR)>>3), + .ROM_DIRECT_UPLOAD(1)) +user_io( + .clk_sys (clk_72 ), + .conf_str (CONF_STR ), + .SPI_CLK (SPI_SCK ), + .SPI_SS_IO (CONF_DATA0 ), + .SPI_MISO (SPI_DO ), + .SPI_MOSI (SPI_DI ), + .buttons (buttons ), + .switches (switches ), + .scandoubler_disable (scandoublerD ), + .ypbpr (ypbpr ), + .no_csync (no_csync ), + .core_mod (core_mod ), + .key_strobe (key_strobe ), + .key_pressed (key_pressed ), + .key_code (key_code ), + .joystick_0 (joystick_0 ), + .joystick_1 (joystick_1 ), + .status (status ) + ); -reg [23:0] rgb; +wire ioctl_downl; +wire [7:0] ioctl_index; +wire ioctl_wr; +wire [24:0] ioctl_addr; +wire [7:0] ioctl_dout; -wire hbl; -wire vbl; - -wire [8:0] hc; -wire [8:0] vc; - -wire hsync; -wire vsync; - -reg hbl_delay, vbl_delay; - -always @ ( posedge clk_7M ) begin - hbl_delay <= hbl; - vbl_delay <= vbl; -end - -video_timing video_timing ( - .clk(clk_7M), - .reset(reset), - .crtc0(crtc[0]), - .crtc1(crtc[1]), - .crtc2(crtc[2]), - .crtc3(crtc[3]), - .hs_offset(hs_offset), - .vs_offset(vs_offset), - .hs_width(hs_width), - .vs_width(vs_width), - .refresh_mod(refresh_mod), - .hc(hc), - .vc(vc), - .hbl_delay(hbl), - .vbl(vbl), - .hsync(hsync), - .vsync(vsync) +data_io #(.ROM_DIRECT_UPLOAD(1)) data_io( + .clk_sys ( clk_72 ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS2 ( SPI_SS2 ), + .SPI_SS4 ( SPI_SS4 ), + .SPI_DI ( SPI_DI ), + .SPI_DO ( SPI_DO ), + .ioctl_download( ioctl_downl ), + .ioctl_index ( ioctl_index ), + .ioctl_wr ( ioctl_wr ), + .ioctl_addr ( ioctl_addr ), + .ioctl_dout ( ioctl_dout ) ); -// PAUSE SYSTEM -wire pause_cpu; -wire hs_pause; +wire [15:0] laudio, raudio; +wire hs, vs; +wire blankn = ~(hb | vb); +wire hb, vb; +wire [4:0] r,b,g; -// 8 bits per colour, 70MHz sys clk -pause #(8,8,8,70) pause -( - .clk_sys(clk_sys), - .reset(reset), - .user_button(b_pause), - .pause_request(hs_pause), - .options(status[21:20]), - .pause_cpu(pause_cpu), - .dim_video(dim_video), - .OSD_STATUS(OSD_STATUS), - .r(rgb[23:16]), - .g(rgb[15:8]), - .b(rgb[7:0]), - .rgb_out(rgb_pause_out) +RallyBike_Top RallyBike_Top( + .pll_locked ( pll_locked ), + .clk_sys ( clk_72 ), + .reset ( reset ), + .turbo_68k (0),//cpu_turbo + .pause_cpu (0), +// input scrollDBG, + .p1_right (m_right1), + .p1_left (m_left1), + .p1_down (m_down1), + .p1_up (m_up1), + .p1_buttons (m_fire1[3:0]), + .p2_right (m_right2), + .p2_left (m_left2), + .p2_down (m_down2), + .p2_up (m_up2), + .p2_buttons (m_fire2[3:0]), + .start1 (m_one_player), + .start2 (m_two_players), + .coin_a (m_coin1), + .coin_b (m_coin2), + .b_pause (), + .service (), + .key_tilt (m_tilt), + .key_service (), + .sw0 (), + .sw1 (), + .sw2 (), + + .hblank ( hb ), + .vblank ( vb ), + .hsync ( hs ), + .vsync ( vs ), + .r ( r ), + .g ( g ), + .b ( b ), + .hs_offset (0), + .vs_offset (0), + .hs_width (0), + .vs_width (0), + .refresh_mod (0), + + .ntsc (0), + .opl2_level (2'b00), + + + .audio_l ( laudio ), + .audio_r ( raudio ), + + .ioctl_download( ioctl_downl), + .ioctl_index (ioctl_index), + .ioctl_addr ( ioctl_addr - 2'd2 ),//check + .ioctl_wr ( ioctl_wr ), + .ioctl_dout ( ioctl_dout ), + + .SDRAM_A ( SDRAM_A ), + .SDRAM_BA ( SDRAM_BA ), + .SDRAM_DQ ( SDRAM_DQ ), + .SDRAM_DQML ( SDRAM_DQML ), + .SDRAM_DQMH ( SDRAM_DQMH ), + .SDRAM_nCS ( SDRAM_nCS ), + .SDRAM_nCAS ( SDRAM_nCAS ), + .SDRAM_nRAS ( SDRAM_nRAS ), + .SDRAM_nWE ( SDRAM_nWE ) ); -wire [23:0] rgb_pause_out; -wire dim_video; - -arcade_video #(320,24) arcade_video -( - .*, - - .clk_video(clk_sys), - .ce_pix(clk_7M), - - .RGB_in(rgb_pause_out), - - .HBlank(hbl), - .VBlank(vbl), - .HSync(hsync), - .VSync(vsync), - - .fx(scan_lines) -); - -/* - Phase Accumulator Increments (Fractional Size 32, look up size 8 bit, total 40 bits) - Increment Calculation - (Output Clock * 2 ^ Word Size) / Reference Clock - Example - NTSC = 3.579545 - PAL = 4.43361875 - W = 40 ( 32 bit fraction, 8 bit look up reference) - Ref CLK = 42.954544 (This could us any clock) - NTSC_Inc = 3.579545333 * 2 ^ 40 / 96 = 40997413706 -*/ - -// SET PAL and NTSC TIMING -`ifdef MISTER_ENABLE_YC - assign CHROMA_PHASE_INC = PALFLAG ? 40'd56225080500: 40'd56225080500; - assign YC_EN = status[22]; - assign PALFLAG = status[7]; -`endif - -screen_rotate screen_rotate (.*); - -wire [9:0] sprite_adj_x = 0; -wire [9:0] sprite_adj_y = 0; -wire bcu_flip_cs; - -reg [1:0] adj_layer; -reg [15:0] scroll_adj_x [3:0]; -reg [15:0] scroll_adj_y [3:0]; -reg layer_en [3:0]; - -reg ce_pix; - -// flip is done in the rendering so leave screen_rotate flip off -wire flip = 0; - -reg tile_flip; - -//assign vc = vcx - vs_offset; - -// =============================================================== -// 68000 CPU -// =============================================================== - -// clock generation -reg fx68_phi1 = 0; -wire fx68_phi2 = !fx68_phi1; - -// phases for 68k clock -always @(posedge clk_sys) begin - if ( clk_10M == 1 ) begin - fx68_phi1 <= ~fx68_phi1; - end -end - -// CPU outputs -wire cpu_rw; // Read = 1, Write = 0 -wire cpu_as_n; // Address strobe -wire cpu_lds_n; // Lower byte strobe -wire cpu_uds_n; // Upper byte strobe -wire cpu_E; -wire [2:0]cpu_fc; // Processor state -wire cpu_reset_n_o; // Reset output signal -wire cpu_halted_n; // Halt output - -// CPU busses -wire [15:0] cpu_dout; -wire [23:0] cpu_a /* synthesis keep */; -reg [15:0] cpu_din; - -// CPU inputs -reg dtack_n; // Data transfer ack (always ready) -reg ipl2_n; - -wire reset_n; -wire vpa_n = ~ ( cpu_lds_n == 0 && cpu_fc == 3'b111 ); // from outzone schematic - -assign cpu_a[0] = reset; // debug hack odd memory address should cause cpu exception - -cc_shifter cc_reset ( - .clk_out(clk_10M), - .i(reset_z80_n & cpu_reset_n_o), - .o(reset_n) -); - -fx68k fx68k ( - // input - .clk( clk_10M ), - .enPhi1(fx68_phi1), - .enPhi2(fx68_phi2), - .extReset(reset), - .pwrUp(reset), - - // output - .eRWn(cpu_rw), - .ASn( cpu_as_n), - .LDSn(cpu_lds_n), - .UDSn(cpu_uds_n), -// .E(cpu_E), -// .VMAn(), - .FC0(cpu_fc[0]), - .FC1(cpu_fc[1]), - .FC2(cpu_fc[2]), -// .BGn(), - .oRESETn(cpu_reset_n_o), - .oHALTEDn(cpu_halted_n), - - // input - .VPAn( vpa_n ), - .DTACKn(dtack_n ), - .BERRn(1'b1), - .BRn(1'b1), - .BGACKn(1'b1), - - .IPL0n(1'b1), - .IPL1n(1'b1), - .IPL2n(ipl2_n), - - // busses - .iEdb(cpu_din), - .oEdb(cpu_dout), - .eab(cpu_a[23:1]) -); - -always @ (posedge clk_sys) begin - if ( clk_10M == 1 ) begin - // tell 68k to wait for valid data. 0=ready 1=wait - // always ack when it's not program rom - dtack_n <= prog_rom_cs ? !prog_rom_data_valid : 0; - // add dsp_ctrl_cs to cpu_din - // select cpu data input based on what is active - cpu_din <= prog_rom_cs ? prog_rom_data : - ram_cs ? ram_dout : - tile_palette_cs ? tile_palette_cpu_dout : - sprite_palette_cs ? sprite_palette_cpu_dout : - sprite_ram_cs ? sprite_ram_dout : - tile_ofs_cs ? curr_tile_ofs : - sprite_ofs_cs ? curr_sprite_ofs : - shared_ram_cs ? cpu_shared_dout : - tile_attr_cs ? ( cpu_tile_dout_attr | { 4'b0, cpu_tile_dout_attr[15:12], cpu_tile_dout_attr[5:4], 6'b0 } ) : - tile_num_cs ? cpu_tile_dout_num : - vblank_cs ? { 15'b0, vbl } : - int_en_cs ? { 15'b0, int_en } : - 16'hffff; - end -end - -wire [15:0] cpu_shared_dout; -wire [7:0] z80_shared_dout; -reg [15:0] z80_a; - -wire [15:0] z80_addr; -reg [7:0] z80_din; -wire [7:0] z80_dout; - -wire z80_wr_n; -wire z80_rd_n; -reg z80_wait_n; - -wire IORQ_n; -wire MREQ_n; - -always @ (posedge clk_sys) begin - if ( reset == 1 ) begin - z80_wait_n <= 0; - sound_wr <= 0; - end else if ( clk_3_5M == 1 ) begin - z80_wait_n <= 1; - if ( ioctl_download | ( z80_rd_n == 0 && sound_rom_1_data_valid == 0 && sound_rom_1_cs == 1 ) ) begin - // wait if rom is selected and data is not yet available - z80_wait_n <= 0; - end - - if ( z80_rd_n == 0 ) begin - if ( sound_rom_1_cs ) begin - if ( sound_rom_1_data_valid ) begin - z80_din <= sound_rom_1_data; - end else begin - z80_wait_n <= 0; - end - end else if ( sound_ram_1_cs ) begin - z80_din <= z80_shared_dout; - end else if ( z80_p1_cs ) begin - z80_din <= p1; - end else if ( z80_p2_cs ) begin - z80_din <= p2; - end else if ( z80_dswa_cs ) begin - z80_din <= z80_dswa; - end else if ( z80_dswb_cs ) begin - z80_din <= z80_dswb; - end else if ( z80_tjump_cs ) begin - z80_din <= z80_tjump; - end else if ( z80_system_cs ) begin - z80_din <= system; - end else if ( z80_sound0_cs ) begin - z80_din <= opl_dout; - end else begin - z80_din <= 8'h00; - end - end - - sound_wr <= 0; - if ( z80_wr_n == 0 ) begin - if ( z80_sound0_cs | z80_sound1_cs ) begin - sound_data <= z80_dout; - sound_addr <= { 1'b0, z80_sound1_cs }; // pad for opl3. opl2 is single bit address - sound_wr <= 1; - end - end - end -end - -reg [1:0] sound_addr; -reg [7:0] sound_data; -reg sound_wr; - -wire [7:0] opl_dout; -wire opl_irq_n; - -reg signed [15:0] sample; - -assign AUDIO_S = 1'b1; - -wire opl_sample_clk; - -jtopl #(.OPL_TYPE(2)) jtopl2 -( - .rst(~reset_n), - .clk(clk_sys), - .cen(clk_3_5M), - .din(sound_data), - .addr(sound_addr), - .cs_n('0), - .wr_n(~sound_wr), - .dout(opl_dout), - .irq_n(opl_irq_n), - .snd(sample), - .sample(opl_sample_clk) -); - -wire [1:0] opl2_level = status[44:43]; // opl2 audio mix - -reg [7:0] opl2_mult; - -// set the multiplier for each channel from menu - -always @( posedge clk_sys, posedge reset ) begin - if (reset) begin - opl2_mult<=0; - end else begin - case( opl2_level ) - 0: opl2_mult <= 8'h0c; // 75% - 1: opl2_mult <= 8'h08; // 50% - 2: opl2_mult <= 8'h04; // 25% - 3: opl2_mult <= 8'h00; // 0% - endcase - end -end - -wire signed [15:0] mono; - -jtframe_mixer #(.W0(16), .WOUT(16)) u_mix_mono( - .rst ( reset ), - .clk ( clk_sys ), - .cen ( 1'b1 ), - // input signals - .ch0 ( sample ), - .ch1 ( 16'd0 ), - .ch2 ( 16'd0 ), - .ch3 ( 16'd0 ), - // gain for each channel in 4.4 fixed point format - .gain0 ( opl2_mult ), - .gain1 ( 8'd0 ), - .gain2 ( 8'd0 ), - .gain3 ( 8'd0 ), - .mixed ( mono ), - .peak ( ) -); - -always @ (posedge clk_sys ) begin - if ( pause_cpu == 1 ) begin - AUDIO_L <= 0; - AUDIO_R <= 0; - end else if ( pause_cpu == 0 ) begin - // mix audio - AUDIO_L <= mono; - AUDIO_R <= mono; - end -end - -T80pa u_cpu( - .RESET_n ( reset_n ), - .CLK ( clk_sys ), - .CEN_p ( clk_3_5M ), - .CEN_n ( ~clk_3_5M ), - - .WAIT_n ( z80_wait_n ), // don't wait if data is valid or rom access isn't selected - .INT_n ( opl_irq_n ), // opl timer - .NMI_n ( 1'b1 ), - .BUSRQ_n ( 1'b1 ), - .RD_n ( z80_rd_n ), - .WR_n ( z80_wr_n ), - .A ( z80_addr ), - .DI ( z80_din ), - .DO ( z80_dout ), - // unused - .DIRSET ( 1'b0 ), - .DIR ( 212'b0 ), - .OUT0 ( 1'b0 ), - .RFSH_n (), - .IORQ_n ( IORQ_n ), - .M1_n (), - .BUSAK_n (), - .HALT_n ( 1'b1 ), - .MREQ_n ( MREQ_n ), - .Stop (), - .REG () -); - -// Chip select mux -wire prog_rom_cs; -wire scroll_ofs_x_cs; -wire scroll_ofs_y_cs; -wire ram_cs; -wire vblank_cs; -wire int_en_cs; -wire crtc_cs; -wire tile_ofs_cs; -wire tile_attr_cs; -wire tile_num_cs; -wire scroll_cs; -wire shared_ram_cs; -wire frame_done_cs; // word -wire tile_palette_cs; -wire sprite_palette_cs; -wire sprite_ofs_cs; -wire sprite_cs; // *** offset needs to be auto-incremented -wire sprite_size_cs; // *** offset needs to be auto-incremented -wire sprite_ram_cs; - -wire z80_p1_cs; -wire z80_p2_cs; -wire z80_dswa_cs; -wire z80_dswb_cs; -wire z80_system_cs; -wire z80_tjump_cs; -wire z80_sound0_cs; -wire z80_sound1_cs; - -chip_select cs (.*); - -wire sprite_0_cs = ( curr_sprite_ofs[1:0] == 2'b00 ) & sprite_cs; -wire sprite_1_cs = ( curr_sprite_ofs[1:0] == 2'b01 ) & sprite_cs; -wire sprite_2_cs = ( curr_sprite_ofs[1:0] == 2'b10 ) & sprite_cs; -wire sprite_3_cs = ( curr_sprite_ofs[1:0] == 2'b11 ) & sprite_cs; - -reg reset_z80_n; -wire reset_z80_cs; -wire sound_rom_1_cs = ( MREQ_n == 0 && z80_addr <= 16'h7fff ); -wire sound_ram_1_cs = ( MREQ_n == 0 && z80_addr >= 16'h8000 && z80_addr <= 16'h87ff ); - -reg int_en; -reg int_ack; - -reg [1:0] vbl_sr; - -// vblank interrupt on rising vbl -always @ (posedge clk_sys ) begin - if ( reset == 1 ) begin - ipl2_n <= 1; - int_ack <= 0; - end else begin - vbl_sr <= { vbl_sr[0], vbl }; - if ( clk_10M == 1 ) begin - int_ack <= ( cpu_as_n == 0 ) && ( cpu_fc == 3'b111 ); // cpu acknowledged the interrupt - end - if ( vbl_sr == 2'b01 ) begin// rising edge - ipl2_n <= ~int_en; - end else if ( int_ack == 1 || vbl_sr == 2'b10 ) begin - ipl2_n <= 1; - end - end -end - -reg [15:0] scroll_x [3:0]; -reg [15:0] scroll_y [3:0]; - -reg [15:0] scroll_x_latch [3:0]; -reg [15:0] scroll_y_latch [3:0]; - -reg inc_sprite_ofs; - -reg [15:0] crtc[4]; -reg [7:0] reset_counter; - -always @ (posedge clk_sys) begin - if ( reset == 1 ) begin - int_en <= 0; - reset_z80_n <= 1; - reset_counter <= 0; - end else begin - if ( reset_counter > 0 ) begin - reset_counter <= reset_counter - 1; - end else begin - reset_z80_n = 1; - end - // write asserted and rising cpu clock - if ( clk_10M == 1 && cpu_rw == 0 ) begin - if ( tile_ofs_cs ) begin - curr_tile_ofs <= cpu_dout; - end - - if ( int_en_cs ) begin - int_en <= cpu_dout[0]; - end - - if ( crtc_cs ) begin - crtc[ cpu_a[2:1] ] <= cpu_dout; - end - - if ( bcu_flip_cs ) begin - tile_flip <= cpu_dout[0]; - end - - if ( sprite_ofs_cs ) begin - // mask out valid range - curr_sprite_ofs <= { 6'b0, cpu_dout[9:0] }; - end - - if ( scroll_ofs_x_cs ) begin - scroll_ofs_x <= cpu_dout; - end - - if ( scroll_ofs_y_cs ) begin - scroll_ofs_y <= cpu_dout; - end - - // x layer values are even addresses - if ( scroll_cs ) begin - if ( cpu_a[1] == 0 ) begin - scroll_x[ cpu_a[3:2] ] <= cpu_dout[15:7]; - end else begin - scroll_y[ cpu_a[3:2] ] <= cpu_dout[15:7]; - end - end - - // offset needs to be auto-incremented - if ( sprite_cs | sprite_size_cs ) begin - inc_sprite_ofs <= 1; - end - - if ( reset_z80_cs ) begin - // the pcb writes to a latch to control the reset - if ( cpu_dout == 0 ) begin - reset_z80_n <= 0; - reset_counter <= 8'h3f; - end - end - end - - // write lasts multiple cpu clocks so limit to one increment per write signal - if ( inc_sprite_ofs == 1 && cpu_rw == 1 ) begin - curr_sprite_ofs <= curr_sprite_ofs + 1; - inc_sprite_ofs <= 0; - end - end -end - -reg [15:0] scroll_x_total [3:0]; -reg [15:0] scroll_y_total [3:0]; - -wire [15:0] ram_dout; -wire [9:0] tile_palette_addr; -wire [15:0] tile_palette_cpu_dout; -wire [15:0] tile_palette_dout; - -wire [9:0] sprite_palette_addr; -wire [15:0] sprite_palette_cpu_dout; -wire [15:0] sprite_palette_dout; - -reg [15:0] curr_tile_ofs; -reg [15:0] curr_sprite_ofs; - -reg [15:0] scroll_ofs_x; -reg [15:0] scroll_ofs_y; - -wire [15:0] cpu_tile_dout_attr; -wire [15:0] cpu_tile_dout_num; - -wire [31:0] tile_attr_dout; - -reg [15:0] sprite_buf_din; - -reg [14:0] tile; - -reg [8:0] sprite_num; -reg [8:0] sprite_num_copy; - -reg [3:0] tile_draw_state; - -reg [2:0] layer; // 4 layers + 1 for initial background - -wire [14:0] tile_idx = tile_attr[14:0]; -wire [3:0] tile_priority = tile_attr[31:28]; -wire [5:0] tile_palette_idx = tile_attr[21:16]; -wire tile_hidden = tile_attr[15]; - -reg [15:0] fb_dout; -wire [15:0] tile_fb_out; -wire [15:0] sprite_fb_out; -reg [15:0] fb_din; -reg [15:0] sprite_fb_din; - -reg tile_fb_w; -reg sprite_fb_w; -reg sprite_size_buf_w; - -dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) tile_line_buffer ( - .clock_a ( clk_sys ), - .address_a ( tile_fb_addr_w ), - .wren_a ( tile_fb_w ), - .data_a ( fb_din ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( fb_addr_r ), - .wren_b ( 0 ), -// .data_b ( ), - .q_b ( tile_fb_out ) -); - -dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) sprite_line_buffer ( - .clock_a ( clk_sys ), - .address_a ( sprite_fb_addr_w ), - .wren_a ( sprite_fb_w ), - .data_a ( sprite_fb_din ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( fb_addr_r ), - .wren_b ( 0 ), -// .data_b ( ), - .q_b ( sprite_fb_out ) -); - -reg [9:0] x_ofs; -reg [9:0] x; - -reg [9:0] y_ofs; - -// y needs to be one line ahaed of the visible line -// render the first line at the end of the previous frame -// this depends on the timing that the sprite list is valid -// sprites values are copied at the start of vblank (line 240) - -// global offsets -wire [9:0] x_ofs_dx = 495 + { ~layer[1:0], 1'b0 }; -wire [9:0] y_ofs_dx = 257; -wire [9:0] x_ofs_dx_flipped = 17 - { ~layer[1:0], 1'b0 }; -wire [9:0] y_ofs_dx_flipped = 255; - -// calculate scrolling -wire [9:0] tile_x_unflipped = scroll_x_latch[layer[1:0]] + x_ofs_dx + scroll_x_offset; -wire [9:0] tile_y_unflipped = scroll_y_latch[layer[1:0]] + y_ofs_dx + scroll_y_offset; - -wire [9:0] tile_x_flipped = ( scroll_x_latch[layer[1:0]] + x_ofs_dx_flipped + scroll_x_offset - 112); -wire [9:0] tile_y_flipped = ( scroll_y_latch[layer[1:0]] + y_ofs_dx_flipped + scroll_y_offset - 40 ); - -// reverse tiles when flipped -wire [9:0] curr_x = tile_flip ? ( tile_x_flipped - x ) : ( tile_x_unflipped + x ); -wire [9:0] curr_y = tile_flip ? ( tile_y_flipped - y ) : ( tile_y_unflipped + y ); - -reg sprite_flip_x; -reg sprite_flip_y; - -reg [9:0] y; -//wire [9:0] y_flipped = ( flip ? (240 - y ) : y ); -//wire [9:0] sprite_buf_x = flip ? 320 - (sprite_x + sprite_pos_x ) : sprite_x + sprite_pos_x; // offset from left of frame - -wire [9:0] y_flipped = y ; -wire [9:0] sprite_buf_x = tile_flip + ( sprite_flip_x ? (sprite_pos_x + ~sprite_x) : (sprite_pos_x + sprite_x) ) ; // offset from left of frame - -reg [3:0] draw_state; -reg [3:0] sprite_state; -reg [3:0] tile_copy_state; -reg [3:0] sprite_copy_state; - -// pixel 4 bit colour -wire [3:0] tile_pix; -assign tile_pix = { tile_data[7-curr_x[2:0]], tile_data[15-curr_x[2:0]], tile_data[23-curr_x[2:0]], tile_data[31-curr_x[2:0]] }; - -wire [2:0] sprite_bit = ~sprite_x[2:0]; -wire [3:0] sprite_pix; -assign sprite_pix = { sprite_data[sprite_bit], sprite_data[8+sprite_bit], sprite_data[16+sprite_bit], sprite_data[24+sprite_bit] }; - -// two lines of buffer alternate -reg [9:0] tile_fb_addr_w; -wire [9:0] fb_addr_r = {vc[0], 9'b0 } + hc; - -reg [9:0] sprite_fb_addr_w; - -reg [31:0] tile_attr; - -// two lines worth for 4 layers (~8k) -// [15:14] = layer. -// [13:10] = prioity -// [9:4] = palette offset -// [3:0] = tile colour index. - -reg [3:0] tile_priority_buf [327:0]; -reg [3:0] sprite_priority_buf [327:0]; - -reg [9:0] sprite_x; // offset from left side of sprite -reg [9:0] sprite_y; - -reg [7:0] sprite_buf_num; - - -reg [1:0] vtotal_282_flag; - -always @ (posedge clk_sys) begin // Check System Vcount flag for 60Hz mode - if ({crtc[2][7:0], 1'b1 } == 269) - vtotal_282_flag <= 0; - else - vtotal_282_flag <= 1; -end - -reg [10:0] sprite_index ;//= sprite_attr_dout[10:0]; -reg [5:0] sprite_pal_addr;//= sprite_attr_dout[5:0]; -reg [1:0] sprite_priority;//= sprite_attr_dout[11:10]; -reg [9:0] sprite_pos_x ;//= sprite_attr_dout[15:7]; -reg [9:0] sprite_pos_y ;//= sprite_attr_dout[15:7]; - -always @ (posedge clk_sys) begin - if ( reset == 1 ) begin - sprite_state <= 0; - draw_state <= 0; - tile_rom_cs <= 0; - tile_copy_state <= 0; - sprite_copy_state <= 0; - tile_draw_state <= 0; - sprite_flip_x <= 0 ; - sprite_flip_y <= 0 ; - end else begin - // render sprites - // triggered when the tile rendering starts - if ( sprite_state == 0 && draw_state > 0 ) begin - sprite_num <= 9'h000; - sprite_x <= 0; - sprite_fb_w <= 1; - sprite_state <= 1; - sprite_fb_din <= 0; - sprite_fb_addr_w <= { y[0], 9'b0 }; - end else if ( sprite_state == 1 ) begin - // erase line buffer - sprite_fb_addr_w <= { y[0], 9'b0 } + sprite_x; - sprite_priority_buf[sprite_x] <= 0; - if ( sprite_x < 320 ) begin - sprite_x <= sprite_x + 1; - end else begin - sprite_x <= 0; - sprite_fb_w <= 0; - sprite_state <= 2; - end -// sprite y could be read first so reading the rest -// could be skipped if not in range of the current scanline - end else if ( sprite_state == 2 ) begin - // sprite num is valid now - sprite_fb_w <= 0; - spritebuf_attr_addr <= { sprite_num, 2'b00 } ; // sprite num - sprite_state <= 3; - end else if ( sprite_state == 3 ) begin - spritebuf_attr_addr <= { sprite_num, 2'b01 } ; // sprite colour / priority - sprite_state <= 4; - end else if ( sprite_state == 4 ) begin - // sprite num ready - spritebuf_attr_addr <= { sprite_num, 2'b10 } ; // sprite x pos - sprite_index <= spritebuf_attr_dout[10:0]; - sprite_state <= 5; - end else if ( sprite_state == 5 ) begin - // sprite colour ready - spritebuf_attr_addr <= { sprite_num, 2'b11 } ; // sprite y pos - - sprite_pal_addr <= spritebuf_attr_dout[5:0] ; - sprite_flip_x <= spritebuf_attr_dout[8]; - sprite_flip_y <= spritebuf_attr_dout[9]; - sprite_priority <= spritebuf_attr_dout[11:10] ; - - sprite_state <= 6; - end else if ( sprite_state == 6 ) begin - // sprite x ready - sprite_pos_x <= spritebuf_attr_dout[15:7] - 31; - sprite_state <= 7; - end else if ( sprite_state == 7 ) begin - // sprite y ready - sprite_pos_y <= spritebuf_attr_dout[15:7] - 16; - if ( spritebuf_attr_dout[15:7] == 9'h100 ) begin - if ( sprite_num < 9'h1ff ) begin - sprite_num <= sprite_num + 1; - sprite_state <= 2; - end else begin - sprite_state <= 15; - end - end else begin - sprite_state <= 8; - end - end else if ( sprite_state == 8 ) begin - // start loop - sprite_fb_w <= 0; - sprite_y <= y_flipped - sprite_pos_y; - // is sprite visible and is current y in sprite y range - // sprite pos can be negative? - if ( ( $signed(y_flipped) >= $signed(sprite_pos_y) ) && $signed(y_flipped) < ( $signed(sprite_pos_y) + 16 ) ) begin - sprite_state <= 9; - end else if ( sprite_num < 9'h1ff ) begin - sprite_num <= sprite_num + 1; - sprite_state <= 2; - end else begin - sprite_state <= 15; - end - end else if ( sprite_state == 9 ) begin - if ( sprite_flip_y == 0 ) begin - sprite_rom_addr <= { sprite_index, sprite_y[3:0], sprite_x[3] }; - end else begin - sprite_rom_addr <= { sprite_index, ~sprite_y[3:0], sprite_x[3] }; - end - sprite_state <= 10; - end else if ( sprite_state == 10 ) begin - sprite_state <= 11; - end else if ( sprite_state == 11 ) begin - sprite_data <= sprite_rom_dout; - sprite_state <= 12; - end else if ( sprite_state == 12 ) begin - sprite_fb_w <= 0; - // draw if pixel value not zero and priority >= previous sprite data - if ( sprite_pix > 0 && sprite_priority >= sprite_priority_buf[sprite_buf_x] ) begin - sprite_fb_din <= { 2'b11, sprite_priority, 2'b00, sprite_pal_addr, sprite_pix }; - - sprite_fb_addr_w <= { y[0], sprite_buf_x[8:0] }; - sprite_priority_buf[sprite_buf_x] <= sprite_priority; - sprite_fb_w <= 1; - end - if ( sprite_x < 15 ) begin - sprite_x <= sprite_x + 1; - if ( sprite_x[2:0] == 7 ) begin - // do recalc bitmap address - sprite_state <= 9; - end - end else if ( sprite_num < 9'h1ff ) begin - sprite_num <= sprite_num + 1; - sprite_x <= 0; - // need to load new attributes and size - sprite_state <= 2; - end else begin - // tile state machine will reset sprite_state when line completes. - sprite_state <= 14; // done - end - end else if ( sprite_state == 14 ) begin - sprite_fb_w <= 0; - sprite_state <= 15; // done - end - - // copy tile ram and scroll info - // not sure if this is needed. need to check to see when tile ram is updated. - if ( tile_copy_state == 0 && vc == 240 ) begin - tile_copy_state <= 1; - end else begin - // copy scroll registers - scroll_x_latch[0] <= scroll_x[0] - scroll_ofs_x; - scroll_x_latch[1] <= scroll_x[1] - scroll_ofs_x; - scroll_x_latch[2] <= scroll_x[2] - scroll_ofs_x; - scroll_x_latch[3] <= scroll_x[3] - scroll_ofs_x; - scroll_y_latch[0] <= scroll_y[0] - scroll_ofs_y; - scroll_y_latch[1] <= scroll_y[1] - scroll_ofs_y; - scroll_y_latch[2] <= scroll_y[2] - scroll_ofs_y; - scroll_y_latch[3] <= scroll_y[3] - scroll_ofs_y; - end - - // copy sprite attr/size to buffer - // write is delayed one clock - if ( sprite_copy_state == 0 && vc == 240 ) begin - sprite_copy_state <= 1; - sprite_attr_w <= 0; - sprite_attr_addr <= 11'h000; - end else if ( sprite_copy_state == 1 ) begin - // sprite_attr_addr valid - sprite_attr_w <= 1; - sprite_copy_state <= 2; - end else if ( sprite_copy_state == 2 ) begin - // sprite_attr_dout valid and write enabled - sprite_attr_addr <= sprite_attr_addr + 1; - // wait for read from source - if ( sprite_attr_addr == 11'h7ff ) begin - sprite_attr_w <= 0; - sprite_copy_state <= 3; - end else begin - sprite_copy_state <= 1; - end - end else if ( sprite_copy_state == 3 ) begin - // wait for vc > 240 so copy isn't triggered again this frame - if ( vc > 240 ) begin - sprite_copy_state <= 0; - end - end - - // tile state machine - if ( draw_state == 0 && vc == ({ crtc[2][7:0], 1'b1 } - (status[19] ? (vtotal_282_flag ? 5'd19 : 4'd7) : 3'd0)) ) begin // 282 Lines standard (263 Lines for 60Hz) - layer <= 4; // layer 4 is layer 0 but draws hidden and transparent - y <= 0; - draw_state <= 2; - sprite_state <= 0; - end else if ( draw_state == 2 ) begin - x <= 0; - x_ofs <= scroll_x_latch[layer[1:0]]; - y_ofs <= scroll_y_latch[layer[1:0]]; - // latch offset info - draw_state <= 3; - tile_draw_state <= 0; - end else if ( draw_state == 3 ) begin - if ( tile_draw_state == 0 ) begin - tile <= { layer[1:0], curr_y[8:3], curr_x[8:3] }; // works - tile_draw_state <= 4'h1; - end else if ( tile_draw_state == 1 ) begin - tile_draw_state <= 2; - end else if ( tile_draw_state == 2 ) begin - // latch attribute - tile_attr <= tile_attr_dout; - if ( layer == 4 || tile_attr_dout[15] == 0 ) begin - tile_draw_state <= 3; - end else begin - if ( x < 320 ) begin// 319 - tile_draw_state <= 3; - // do we need to read another tile? - // last pixel of this tile changes based on flip direction - if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin - draw_state <= 3; - tile_draw_state <= 0; - end - x <= x + 1; - end else if ( layer > 0 ) begin - layer <= layer - 1; - tile_fb_w <= 0; - draw_state <= 2; - end else begin - // done - tile_draw_state <= 7; - tile_fb_w <= 0; - end - end - end else if ( tile_draw_state == 3 ) begin - // read bitmap info - tile_rom_cs <= 1; - tile_rom_addr <= { tile_idx, curr_y[2:0] }; - tile_draw_state <= 4; - end else if ( tile_draw_state == 4 ) begin - // wait for bitmap ram ready - if ( tile_rom_data_valid ) begin - // latch data and deassert cs - tile_data <= tile_rom_data; - tile_draw_state <= 5; - tile_rom_cs <= 0; - end - end else if ( tile_draw_state == 5 ) begin - tile_fb_w <= 0; - tile_fb_addr_w <= { y[0], 9'b0 } + x; - // force render of first layer. - // if layer == 4 then tile_pix == 0 is not transparent - // layer 4 is really layer 0 - if ( layer == 4 ) begin - tile_priority_buf[x] <= 0; //tile_pix == 0 ? 0 : tile_priority; - //fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; - fb_din <= { layer[1:0], 4'b0, tile_palette_idx, tile_pix }; - tile_fb_w <= 1; - end else if (tile_hidden == 0 && tile_pix > 0 && tile_priority > 0 && tile_priority >= tile_priority_buf[x] ) begin - tile_priority_buf[x] <= tile_priority; - // if tile hidden then make the pallette index 0. ie transparent - fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; - tile_fb_w <= 1; - end - if ( x < 320 ) begin// 319 - // do we need to read another tile? - // last pixel of this tile changes based on flip direction - if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin - draw_state <= 3; - tile_draw_state <= 0; - end - x <= x + 1; - end else if ( layer > 0 ) begin - layer <= layer - 1; - tile_fb_w <= 0; - draw_state <= 2; - end else begin - // done - tile_draw_state <= 7; - tile_fb_w <= 0; - end - end else if ( tile_draw_state == 7 ) begin - // wait for next line or quit - if ( y == 239 ) begin - draw_state <= 0; - end else if ( hc == (status[19] ? 9'd444 : 9'd449) ) begin // 450 Lines standard (445 Lines for NTSC standard 15.73kHz line freq) - y <= y + 1; - draw_state <= 2; - sprite_state <= 0; - layer <= 4; - end - end - end - end -end - -// render -reg draw_sprite; - -// two lines worth for 4 layers (~8k) -// [15:14] = layer. -// [13:10] = prioity -// [9:4] = palette offset -// [3:0] = tile colour index. - -// there are 10 70MHz cycles per pixel. clk7_count from 0-9 - -// dac values based on 120 ohm driver for the resistor dac and 75 ohm output. 4.7k, 2.2k, 1k, 470, 220 -// modeled in spice -wire [7:0] dac [0:31] = '{0,12,25,36,50,61,73,83,91,100,111,120,131,139,149,157,145,154,162,170,180,187,195,202,208,214,222,228,236,242,249,255}; - -always @ (posedge clk_sys) begin - if ( clk7_count == 4 ) begin - tile_palette_addr <= tile_fb_out[9:0]; - sprite_palette_addr <= sprite_fb_out[9:0]; - end else if ( clk7_count == 6 ) begin - // if palette index is zero then it's from layer 3 and is transparent render as blank (black). - rgb <= { dac[tile_palette_dout[4:0]], dac[tile_palette_dout[9:5]], dac[tile_palette_dout[14:10]] }; - // if not transparent and sprite is higher priority - if ( sprite_fb_out[3:0] > 0 && (sprite_fb_out[13:10] >= tile_fb_out[13:10]) ) begin - // draw sprite - rgb <= { dac[sprite_palette_dout[4:0]], dac[sprite_palette_dout[9:5]], dac[sprite_palette_dout[14:10]] }; - end - end -end - -// tile data buffer - -reg tile_buf_w; -reg [31:0] tile_buf_din; -reg [31:0] tile_buf_dout; -reg [13:0] tile_buf_addr; - -dual_port_ram #(.LEN(16384), .DATA_WIDTH(32)) ram_tile_buf ( - .clock_a ( clk_sys ), - .address_a ( tile[13:0] ), - .wren_a ( tile_buf_w ), - .data_a ( tile_attr_dout ), - - .clock_b ( clk_sys ), - .address_b ( tile[13:0] ), // only read the tile # for now - .wren_b ( 0 ), - .q_b ( tile_buf_dout ) -); - -// tile attribute ram. each tile attribute is 2 16bit words -// pppp ---- --cc cccc httt tttt tttt tttt = Tile number (0 - $7fff) -// indirect access through offset register -dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_h ( - .clock_a ( clk_10M ), - .address_a ( curr_tile_ofs ), - .wren_a ( tile_attr_cs & !cpu_rw ), - .data_a ( cpu_dout ), - .q_a ( cpu_tile_dout_attr ), - - .clock_b ( clk_sys ), - .address_b ( tile[13:0] ), // only read the tile # for now - .wren_b ( 0 ), - .q_b ( tile_attr_dout[31:16] ) -); - -dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_l ( - .clock_a ( clk_10M ), - .address_a ( curr_tile_ofs ), - .wren_a ( tile_num_cs & !cpu_rw ), - .data_a ( cpu_dout ), - .q_a ( cpu_tile_dout_num ), - - .clock_b ( clk_sys ), - .address_b ( tile[13:0] ), // only read the tile # for now - .wren_b ( 0 ), - .q_b ( tile_attr_dout[15:0] ) -); - -// tiles 1024 15 bit values. index is ( 6 bits from tile attribute, 4 bits from bitmap ) -// background palette ram low -// does this need to be byte addressable? -dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_l ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[10:1] ), - .wren_a ( tile_palette_cs & !cpu_rw & !cpu_lds_n), - .data_a ( cpu_dout[7:0] ), - .q_a ( tile_palette_cpu_dout[7:0] ), - - .clock_b ( clk_sys ), - .address_b ( tile_palette_addr ), - .wren_b ( 0 ), - .q_b ( tile_palette_dout[7:0] ) -); - -// background palette ram high -dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_h ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[10:1] ), - .wren_a ( tile_palette_cs & !cpu_rw & !cpu_uds_n), - .data_a ( cpu_dout[15:8] ), - .q_a ( tile_palette_cpu_dout[15:8] ), - - .clock_b ( clk_sys ), - .address_b ( tile_palette_addr ), - .wren_b ( 0 ), - .q_b ( tile_palette_dout[15:8] ) -); - -// sprite palette ram low -// does this need to be byte addressable? -dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_l ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[10:1] ), - .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_lds_n), - .data_a ( cpu_dout[7:0] ), - .q_a ( sprite_palette_cpu_dout[7:0] ), - - .clock_b ( clk_sys ), - .address_b ( sprite_palette_addr ), - .wren_b ( 0 ), - .q_b ( sprite_palette_dout[7:0] ) -); - -// background palette ram high -dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_h ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[10:1] ), - .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_uds_n), - .data_a ( cpu_dout[15:8] ), - .q_a ( sprite_palette_cpu_dout[15:8] ), - - .clock_b ( clk_sys ), - .address_b ( sprite_palette_addr ), - .wren_b ( 0 ), - .q_b ( sprite_palette_dout[15:8] ) -); - - -// main 68k ram low -dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_L ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[14:1] ), - .wren_a ( !cpu_rw & ram_cs & !cpu_lds_n ), - .data_a ( cpu_dout[7:0] ), - .q_a ( ram_dout[7:0] ) -); - -// main 68k ram high -dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_H ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[14:1] ), - .wren_a ( !cpu_rw & ram_cs & !cpu_uds_n ), - .data_a ( cpu_dout[15:8] ), - .q_a ( ram_dout[15:8] ) -); - - -//wire [15:0] z80_shared_addr = z80_addr - 16'h8000; -//wire [23:0] m68k_shard_addr = cpu_a - 24'h040000; - -// z80 and 68k shared ram -// 4k -dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) shared_ram ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[12:1] ), - .wren_a ( shared_ram_cs & !cpu_rw & !cpu_lds_n), - .data_a ( cpu_dout[7:0] ), - .q_a ( cpu_shared_dout[7:0] ), - - .clock_b ( clk_3_5M ), // z80 clock is 3.5M - .address_b ( z80_addr[11:0] ), - .data_b ( z80_dout ), - .wren_b ( sound_ram_1_cs & ~z80_wr_n ), - .q_b ( z80_shared_dout ) -); - -reg sprite_attr_w ; -reg [10:0] sprite_attr_addr; -wire [15:0] sprite_attr_dout; -wire [15:0] sprite_ram_dout; - -reg [10:0] spritebuf_attr_addr; -wire [15:0] spritebuf_attr_dout; - -dual_port_ram #(.LEN(2048), .DATA_WIDTH(8)) sprite_ram_l -( - .clock_a( clk_10M ), - .address_a( cpu_a[11:1] ), - .wren_a( sprite_ram_cs & !cpu_rw & !cpu_lds_n), - .data_a( cpu_dout[7:0] ), - .q_a( sprite_ram_dout[7:0] ), - - .clock_b( clk_sys ), - .address_b( sprite_attr_addr ), - .wren_b( 0 ), - .q_b( sprite_attr_dout[7:0] ) -); - -dual_port_ram #(.LEN(2048), .DATA_WIDTH(8)) sprite_ram_h -( - .clock_a( clk_10M ), - .address_a( cpu_a[11:1] ), - .wren_a( sprite_ram_cs & !cpu_rw & !cpu_uds_n), - .data_a( cpu_dout[15:8] ), - .q_a( sprite_ram_dout[15:8] ), - - .clock_b( clk_sys ), - .address_b( sprite_attr_addr ), - .wren_b( 0 ), - .q_b( sprite_attr_dout[15:8] ) -); - -dual_port_ram #(.LEN(2048), .DATA_WIDTH(16)) spritebuf_ram -( - .clock_a( clk_sys ), - .address_a( sprite_attr_addr ), - .wren_a( sprite_attr_w ), - .data_a( sprite_attr_dout ), - .q_a( ), - - .clock_b( clk_sys ), - .address_b( spritebuf_attr_addr ), - .wren_b( 0 ), - .q_b( spritebuf_attr_dout ) -); - - -reg [15:0] sprite_rom_addr ; -wire [31:0] sprite_rom_dout ; - -wire sprite_rom_w = ioctl_download & ioctl_wr & ( ioctl_index == 0 ); - -wire sbit0 = (ioctl_addr >= 24'h180000 && ioctl_addr < 24'h190000 ); -wire sbit1 = (ioctl_addr >= 24'h190000 && ioctl_addr < 24'h1a0000 ); -wire sbit2 = (ioctl_addr >= 24'h1a0000 && ioctl_addr < 24'h1b0000 ); -wire sbit3 = (ioctl_addr >= 24'h1b0000 && ioctl_addr < 24'h1c0000 ); - -dual_port_ram #(.LEN(65536), .DATA_WIDTH(8)) sprite_rom_0 -( - .clock_a( clk_sys ), - .address_a( ioctl_addr[15:0] ), - .wren_a( sprite_rom_w & sbit0 ), - .data_a( ioctl_dout ), - .q_a( ), - - .clock_b( clk_sys ), - .address_b( sprite_rom_addr ), - .wren_b( 0 ), - .q_b( sprite_rom_dout[7:0] ) -); - -dual_port_ram #(.LEN(65536), .DATA_WIDTH(8)) sprite_rom_1 -( - .clock_a ( clk_sys ), - .address_a ( ioctl_addr[15:0] ), - .wren_a( sprite_rom_w & sbit1 ), - .data_a ( ioctl_dout ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_rom_addr ), - .wren_b ( 0 ), - .q_b ( sprite_rom_dout[15:8] ) -); - -dual_port_ram #(.LEN(65536), .DATA_WIDTH(8)) sprite_rom_2 -( - .clock_a ( clk_sys ), - .address_a ( ioctl_addr[15:0] ), - .wren_a( sprite_rom_w & sbit2 ), - .data_a ( ioctl_dout ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_rom_addr ), - .wren_b ( 0 ), - .q_b ( sprite_rom_dout[23:16] ) -); - -dual_port_ram #(.LEN(65536), .DATA_WIDTH(8)) sprite_rom_3 -( - .clock_a ( clk_sys ), - .address_a ( ioctl_addr[15:0] ), - .wren_a( sprite_rom_w & sbit3 ), - .data_a ( ioctl_dout ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_rom_addr ), - .wren_b ( 0 ), - .q_b ( sprite_rom_dout[31:24] ) -); - -reg [22:0] sdram_addr; -reg [31:0] sdram_data; -reg sdram_we; -reg sdram_req; - -wire sdram_ack; -wire sdram_valid; -wire [31:0] sdram_q; - -sdram #(.CLK_FREQ(70.0)) sdram -( - .reset(~pll_locked), - .clk(clk_sys), - - // controller interface - .addr(sdram_addr), - .data(sdram_data), - .we(sdram_we), - .req(sdram_req), - - .ack(sdram_ack), - .valid(sdram_valid), - .q(sdram_q), - - // SDRAM interface - .sdram_a(SDRAM_A), - .sdram_ba(SDRAM_BA), - .sdram_dq(SDRAM_DQ), - .sdram_cke(SDRAM_CKE), - .sdram_cs_n(SDRAM_nCS), - .sdram_ras_n(SDRAM_nRAS), - .sdram_cas_n(SDRAM_nCAS), - .sdram_we_n(SDRAM_nWE), - .sdram_dqml(SDRAM_DQML), - .sdram_dqmh(SDRAM_DQMH) -); - -wire prog_cache_rom_cs; -wire [22:0] prog_cache_addr; -wire [15:0] prog_cache_data; -wire prog_cache_valid; - -wire [15:0] prog_rom_data; -wire prog_rom_data_valid; - -reg tile_rom_cs; -reg [17:0] tile_rom_addr; -wire [31:0] tile_rom_data; -wire tile_rom_data_valid; - -wire tile_cache_cs; -wire [17:0] tile_cache_addr; -wire [31:0] tile_cache_data; -wire tile_cache_valid; - -reg [31:0] tile_data; - -//wire sprite_rom_cs; -//wire [17:0] sprite_rom_addr; -//wire [31:0] sprite_rom_data; -//wire sprite_rom_data_valid; - -reg [31:0] sprite_data; - -wire [15:0] sound_rom_1_addr; -wire [7:0] sound_rom_1_data; -wire sound_rom_1_data_valid; - -// sdram priority based rom controller -// is a oe needed? -rom_controller rom_controller -( - .reset(reset), - - // clock - .clk(clk_sys), - - // program ROM interface - .prog_rom_cs(prog_cache_rom_cs), - .prog_rom_oe(1), - .prog_rom_addr(prog_cache_addr), - .prog_rom_data(prog_cache_data), - .prog_rom_data_valid(prog_cache_valid), - - // character ROM interface - .tile_rom_cs(tile_cache_cs), - .tile_rom_oe(1), - .tile_rom_addr(tile_cache_addr), - .tile_rom_data(tile_cache_data), - .tile_rom_data_valid(tile_cache_valid), - - - // sprite ROM interface -// .sprite_rom_cs(sprite_rom_cs), -// .sprite_rom_oe(1), -// .sprite_rom_addr(sprite_rom_addr), -// .sprite_rom_data(sprite_rom_data), -// .sprite_rom_data_valid(sprite_rom_data_valid), - - // sound ROM #1 interface - .sound_rom_1_cs(sound_rom_1_cs), - .sound_rom_1_oe(1), - .sound_rom_1_addr(z80_addr), - .sound_rom_1_data(sound_rom_1_data), - .sound_rom_1_data_valid(sound_rom_1_data_valid), - - // IOCTL interface - .ioctl_addr(ioctl_addr), - .ioctl_data(ioctl_dout), - .ioctl_index(ioctl_index), - .ioctl_wr(ioctl_wr), - .ioctl_download(ioctl_download), - - // SDRAM interface - .sdram_addr(sdram_addr), - .sdram_data(sdram_data), - .sdram_we(sdram_we), - .sdram_req(sdram_req), - .sdram_ack(sdram_ack), - .sdram_valid(sdram_valid), - .sdram_q(sdram_q) -); - - -cache prog_cache -( - .reset(reset), - .clk(clk_sys), - - // client - .cache_req(prog_rom_cs), - .cache_addr(cpu_a[23:1]), - .cache_valid(prog_rom_data_valid), - .cache_data(prog_rom_data), - - // to rom controller - .rom_req(prog_cache_rom_cs), - .rom_addr(prog_cache_addr), - .rom_valid(prog_cache_valid), - .rom_data(prog_cache_data) -); - -tile_cache tile_cache -( - .reset(reset), - .clk(clk_sys), - - // client - .cache_req(tile_rom_cs), - .cache_addr(tile_rom_addr), - .cache_data(tile_rom_data), - .cache_valid(tile_rom_data_valid), - - // to rom controller - .rom_req(tile_cache_cs), - .rom_addr(tile_cache_addr), - .rom_data(tile_cache_data), - .rom_valid(tile_cache_valid) +mist_video #(.COLOR_DEPTH(5),.SD_HCNT_WIDTH(10)) mist_video( + .clk_sys(clk_72), + .SPI_SCK(SPI_SCK), + .SPI_SS3(SPI_SS3), + .SPI_DI(SPI_DI), + .R(blankn ? r : 5'd0), + .G(blankn ? g : 5'd0), + .B(blankn ? b : 5'd0), + .HSync(~hs), + .VSync(~vs), + .VGA_R(VGA_R), + .VGA_G(VGA_G), + .VGA_B(VGA_B), + .VGA_VS(VGA_VS), + .VGA_HS(VGA_HS), + .no_csync(no_csync), + .rotate({~flipped,rotate}), + .ce_divider(3'd5), // pix clock = 72/6 + .blend(blend), + .scandoubler_disable(scandoublerD), + .scanlines(scanlines), + .ypbpr(ypbpr) + ); + +dac #(16) dacl( + .clk_i(clk_72), + .res_n_i(1), + .dac_i({~laudio[15], laudio[14:0]}), + .dac_o(AUDIO_L) + ); + +dac #(16) dacr( + .clk_i(clk_72), + .res_n_i(1), + .dac_i({~raudio[15], raudio[14:0]}), + .dac_o(AUDIO_R) + ); + +// Common inputs +wire m_up1, m_down1, m_left1, m_right1, m_up1B, m_down1B, m_left1B, m_right1B; +wire m_up2, m_down2, m_left2, m_right2, m_up2B, m_down2B, m_left2B, m_right2B; +wire m_up3, m_down3, m_left3, m_right3, m_up3B, m_down3B, m_left3B, m_right3B; +wire m_up4, m_down4, m_left4, m_right4, m_up4B, m_down4B, m_left4B, m_right4B; +wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players; +wire [11:0] m_fire1, m_fire2, m_fire3, m_fire4; + +arcade_inputs inputs ( + .clk ( clk_72 ), + .key_strobe ( key_strobe ), + .key_pressed ( key_pressed ), + .key_code ( key_code ), + .joystick_0 ( joystick_0 ), + .joystick_1 ( joystick_1 ), + .rotate ( rotate ), + .orientation ( {~flipped, 1'b0} ), + .joyswap ( joyswap ), + .oneplayer ( 1'b0 ), + .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ), + .player1 ( {m_up1B, m_down1B, m_left1B, m_right1B, m_fire1, m_up1, m_down1, m_left1, m_right1} ), + .player2 ( {m_up2B, m_down2B, m_left2B, m_right2B, m_fire2, m_up2, m_down2, m_left2, m_right2} ), + .player3 ( {m_up3B, m_down3B, m_left3B, m_right3B, m_fire3, m_up3, m_down3, m_left3, m_right3} ), + .player4 ( {m_up4B, m_down4B, m_left4B, m_right4B, m_fire4, m_up4, m_down4, m_left4, m_right4} ) ); endmodule - - -module cc_shifter -( - input clk_out, - input i, - output o -); - -// We use a two-stages shift-register to synchronize SignalIn_clkA to the clkB clock domain -reg [1:0] r; - -assign o = r[1]; // new signal synchronized to (=ready to be used in) clkB domain - -always @(posedge clk_out) begin - r[0] <= i; - r[1] <= r[0]; // notice that we use clkB -end - -endmodule - - diff --git a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_vimana/Vimana_Top.sv b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_vimana/Vimana_Top.sv index 80c2ac50..40574dce 100644 --- a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_vimana/Vimana_Top.sv +++ b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_vimana/Vimana_Top.sv @@ -1,13 +1,13 @@ module Vimana_Top( + + input [1:0] pcb, input clk_sys, - input clk_70M, input pll_locked, input turbo_68k,//cpu_turbo - input reset, - + input reset, input pause_cpu, - - input status32, +//------------------------------------ + input scrollDBG, input p1_right, input p1_left, input p1_down, @@ -29,8 +29,7 @@ module Vimana_Top( input [7:0] sw0, input [7:0] sw1, input [7:0] sw2, - input [1:0] pcb, - +//------------------------------------ output hsync, output vsync, output hblank, @@ -45,18 +44,24 @@ module Vimana_Top( output [4:0] b, input ntsc, input [1:0] opl2_level, - output [15:0] audio, - - - input ioctl_download, - input ioctl_upload, -// input ioctl_upload_req; -// input ioctl_wait; - output ioctl_wr, - input [15:0] ioctl_index, - output [26:0] ioctl_addr, - input [15:0] ioctl_dout, - output [15:0] ioctl_din +//------------------------------------ + output [15:0] audio_l, + output [15:0] audio_r, +//------------------------------------ + input ioctl_download, + input ioctl_index, + input [23:0] ioctl_addr, + input ioctl_wr, + input [7:0] ioctl_dout, + output [12:0] SDRAM_A, + output [1:0] SDRAM_BA, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nCS, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nWE ); @@ -78,8 +83,8 @@ always @ (posedge clk_sys ) begin z80_dswa <= sw0; z80_tjump <= sw2; - if ( status32 == 1 ) begin - z80_dswb <= { sw1[7], sw1[6] | status32, sw1[5:0] }; + if ( scrollDBG == 1 ) begin + z80_dswb <= { sw1[7], sw1[6] | scrollDBG, sw1[5:0] }; system <= { vblank, start2 | p1_buttons[3], start1 | p1_buttons[3], coin_b, coin_a, service, key_tilt, key_service }; end else begin z80_dswb <= sw1; @@ -534,10 +539,12 @@ jtframe_mixer #(.W0(16), .WOUT(16)) u_mix_mono( always @ (posedge clk_sys ) begin if ( pause_cpu == 1 ) begin - audio <= 0; + audio_l <= 0; + audio_r <= 0; end else if ( pause_cpu == 0 ) begin // mix audio - audio <= {~mono[15],mono[14:0]}; + audio_l <= {mono[15:0]}; + audio_r <= {mono[15:0]}; end end diff --git a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_vimana/vimana.sv b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_vimana/vimana.sv index 6d435793..48d68849 100644 --- a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_vimana/vimana.sv +++ b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_vimana/vimana.sv @@ -1,4 +1,5 @@ //============================================================================ +// Toaplan Hardware v1 HW top-level for MiST // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free @@ -13,2077 +14,283 @@ // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// //============================================================================ -`default_nettype none +module Vimana( + output LED, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_HS, + output VGA_VS, + output AUDIO_L, + output AUDIO_R, + input SPI_SCK, + inout SPI_DO, + input SPI_DI, + input SPI_SS2, + input SPI_SS3, + input SPI_SS4, + input CONF_DATA0, + input CLOCK_27, -module emu -( - //Master input clock - input CLK_50M, - - //Async reset from top-level module. - //Can be used as initial reset. - input RESET, - - //Must be passed to hps_io module - inout [48:0] HPS_BUS, - - //Base video clock. Usually equals to CLK_SYS. - output CLK_VIDEO, - - //Multiple resolutions are supported using different CE_PIXEL rates. - //Must be based on CLK_VIDEO - output CE_PIXEL, - - //Video aspect ratio for HDMI. Most retro systems have ratio 4:3. - //if VIDEO_ARX[12] or VIDEO_ARY[12] is set then [11:0] contains scaled size instead of aspect ratio. - output [12:0] VIDEO_ARX, - output [12:0] VIDEO_ARY, - - output [7:0] VGA_R, - output [7:0] VGA_G, - output [7:0] VGA_B, - output VGA_HS, - output VGA_VS, - output VGA_DE, // = ~(VBlank | HBlank) - output VGA_F1, - output [2:0] VGA_SL, - output VGA_SCALER, // Force VGA scaler - - input [11:0] HDMI_WIDTH, - input [11:0] HDMI_HEIGHT, - output HDMI_FREEZE, - -`ifdef MISTER_FB - // Use framebuffer in DDRAM (USE_FB=1 in qsf) - // FB_FORMAT: - // [2:0] : 011=8bpp(palette) 100=16bpp 101=24bpp 110=32bpp - // [3] : 0=16bits 565 1=16bits 1555 - // [4] : 0=RGB 1=BGR (for 16/24/32 modes) - // - // FB_STRIDE either 0 (rounded to 256 bytes) or multiple of pixel size (in bytes) - output FB_EN, - output [4:0] FB_FORMAT, - output [11:0] FB_WIDTH, - output [11:0] FB_HEIGHT, - output [31:0] FB_BASE, - output [13:0] FB_STRIDE, - input FB_VBL, - input FB_LL, - output FB_FORCE_BLANK, - -`ifdef MISTER_FB_PALETTE - // Palette control for 8bit modes. - // Ignored for other video modes. - output FB_PAL_CLK, - output [7:0] FB_PAL_ADDR, - output [23:0] FB_PAL_DOUT, - input [23:0] FB_PAL_DIN, - output FB_PAL_WR, -`endif -`endif - - output LED_USER, // 1 - ON, 0 - OFF. - - // b[1]: 0 - LED status is system status OR'd with b[0] - // 1 - LED status is controled solely by b[0] - // hint: supply 2'b00 to let the system control the LED. - output [1:0] LED_POWER, - output [1:0] LED_DISK, - - // I/O board button press simulation (active high) - // b[1]: user button - // b[0]: osd button - output [1:0] BUTTONS, - - //Audio - input CLK_AUDIO, // 24.576 MHz - output [15:0] AUDIO_L, - output [15:0] AUDIO_R, - output AUDIO_S, // 1 - signed audio samples, 0 - unsigned - output [1:0] AUDIO_MIX, // 0 - no mix, 1 - 25%, 2 - 50%, 3 - 100% (mono) - - //ADC - inout [3:0] ADC_BUS, - - //SD-SPI - output SD_SCK, - output SD_MOSI, - input SD_MISO, - output SD_CS, - input SD_CD, - - //High latency DDR3 RAM interface - //Use for non-critical time purposes - output DDRAM_CLK, - input DDRAM_BUSY, - output [7:0] DDRAM_BURSTCNT, - output [28:0] DDRAM_ADDR, - input [63:0] DDRAM_DOUT, - input DDRAM_DOUT_READY, - output DDRAM_RD, - output [63:0] DDRAM_DIN, - output [7:0] DDRAM_BE, - output DDRAM_WE, - - //SDRAM interface with lower latency - output SDRAM_CLK, - output SDRAM_CKE, - output [12:0] SDRAM_A, - output [1:0] SDRAM_BA, - inout [15:0] SDRAM_DQ, - output SDRAM_DQML, - output SDRAM_DQMH, - output SDRAM_nCS, - output SDRAM_nCAS, - output SDRAM_nRAS, - output SDRAM_nWE, - -`ifdef MISTER_DUAL_SDRAM - //Secondary SDRAM - //Set all output SDRAM_* signals to Z ASAP if SDRAM2_EN is 0 - input SDRAM2_EN, - output SDRAM2_CLK, - output [12:0] SDRAM2_A, - output [1:0] SDRAM2_BA, - inout [15:0] SDRAM2_DQ, - output SDRAM2_nCS, - output SDRAM2_nCAS, - output SDRAM2_nRAS, - output SDRAM2_nWE, -`endif - - input UART_CTS, - output UART_RTS, - input UART_RXD, - output UART_TXD, - output UART_DTR, - input UART_DSR, - -`ifdef MISTER_ENABLE_YC - output [39:0] CHROMA_PHASE_INC, - output YC_EN, - output PALFLAG, -`endif - - // Open-drain User port. - // 0 - D+/RX - // 1 - D-/TX - // 2..6 - USR2..USR6 - // Set USER_OUT to 1 to read from USER_IN. - input [6:0] USER_IN, - output [6:0] USER_OUT, - - input OSD_STATUS + output [12:0] SDRAM_A, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nWE, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nCS, + output [1:0] SDRAM_BA, + output SDRAM_CLK, + output SDRAM_CKE ); -///////// Default values for ports not used in this core ///////// +`include "../build_id.v" +//`include "defs.v" -assign ADC_BUS = 'Z; -assign USER_OUT = 0; -assign {UART_RTS, UART_TXD, UART_DTR} = 0; -assign {SD_SCK, SD_MOSI, SD_CS} = 'Z; -//assign {SDRAM_DQ, SDRAM_A, SDRAM_BA, SDRAM_CLK, SDRAM_CKE, SDRAM_DQML, SDRAM_DQMH, SDRAM_nWE, SDRAM_nCAS, SDRAM_nRAS, SDRAM_nCS} = 'Z; -//assign {DDRAM_CLK, DDRAM_BURSTCNT, DDRAM_ADDR, DDRAM_DIN, DDRAM_BE, DDRAM_RD, DDRAM_WE} = '0; -assign VGA_F1 = 0; -assign VGA_SCALER = 0; -assign HDMI_FREEZE = 0; +`define CORE_NAME "Vimana" +assign LED = ~ioctl_downl; +assign SDRAM_CLK = clk_72; +assign SDRAM_CKE = 1; -assign AUDIO_MIX = 0; -assign LED_USER = ioctl_download & cpu_a[0]; -assign LED_DISK = 0; -assign LED_POWER = 0; -assign BUTTONS = 0; - -// Status Bit Map: -// Upper Case Lower Case -// 0 1 2 3 4 5 6 -// 01234567890123456789012345678901 23456789012345678901234567890123 -// 0123456789ABCDEFGHIJKLMNOPQRSTUV 0123456789ABCDEFGHIJKLMNOPQRSTUV -// X XXXXXXXX XX X X XXXXXXXX X XX XXXXXXXX - -wire [1:0] aspect_ratio = status[9:8]; -wire orientation = ~status[3]; -wire [2:0] scan_lines = status[6:4]; -reg refresh_mod; -reg new_vmode; - -always @(posedge clk_sys) begin - if (refresh_mod != status[19]) begin - refresh_mod <= status[19]; - new_vmode <= ~new_vmode; - end -end - -wire [3:0] hs_offset = status[27:24]; -wire [3:0] vs_offset = status[31:28]; -wire [3:0] hs_width = status[59:56]; -wire [3:0] vs_width = status[63:60]; - -assign VIDEO_ARX = (!aspect_ratio) ? (orientation ? 8'd4 : 8'd3) : (aspect_ratio - 1'd1); -assign VIDEO_ARY = (!aspect_ratio) ? (orientation ? 8'd3 : 8'd4) : 12'd0; - -`include "build_id.v" localparam CONF_STR = { - "Toaplan V1;;", - "-;", - "P1,Video Settings;", - "P1-;", - "P1O89,Aspect Ratio,Original,Full Screen,[ARC1],[ARC2];", - "P1O3,Orientation,Horz,Vert;", - "P1-;", - "P1O46,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%,CRT 75%,CRT 100%;", - "P1OA,Force Scandoubler,Off,On;", - "P1-;", - "P1O7,Video Mode,NTSC,PAL;", - "P1OM,Video Signal,RGBS/YPbPr,Y/C;", - "P1OJ,Refresh Rate,Native,NTSC;", - "P1-;", - "P1OOR,H-sync Pos Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", - "P1OSV,V-sync Pos Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", - "P1-;", - "P1oOR,H-sync Width Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", - "P1oSV,V-sync Width Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", - "P1-;", - "P2,Audio Settings;", - "P2-;", - "P2oBC,OPL2 Volume,Default,50%,25%,0%;", - "P2-;", - "-;", - "P3,Core Options;", - "P3-;", - "P3o6,Swap P1/P2 Joystick,Off,On;", - "P3-;", - "P3OF,68k Freq.,10Mhz,17.5MHz;", - "P3-;", - "P3o0,Scroll Debug,Off,On;", - "P3-;", - "DIP;", - "-;", - "OK,Pause OSD,Off,When Open;", - "OL,Dim Video,Off,10s;", - "-;", - "R0,Reset;", - "V,v",`BUILD_DATE + `CORE_NAME, ";;", + "O2,Rotate Controls,Off,On;", + "O34,Scanlines,Off,25%,50%,75%;", + "O5,Blending,Off,On;", + "O6,Joystick Swap,Off,On;", + "DIP;", + "T0,Reset;", + "V,v1.20.",`BUILD_DATE }; -wire hps_forced_scandoubler; -wire forced_scandoubler = hps_forced_scandoubler | status[10]; +wire rotate = status[2]; +wire [1:0] scanlines = status[4:3]; +wire blend = status[5]; +wire joyswap = status[6]; -wire [1:0] buttons; -wire [63:0] status; -wire [10:0] ps2_key; -wire [15:0] joy0, joy1; +wire [7:0] dsw1 = status[23:16]; +wire [7:0] dsw2 = status[31:24]; +reg [7:0] dsw_m68k, dsw_sp85; +reg [7:0] p1, p2; +wire flipped; +wire key_service = m_fire1[4]; +wire key_test = m_fire1[3]; -hps_io #(.CONF_STR(CONF_STR)) hps_io -( - .clk_sys(clk_sys), - .HPS_BUS(HPS_BUS), - .buttons(buttons), - .ps2_key(ps2_key), - .status(status), - .status_menumask(direct_video), - .forced_scandoubler(hps_forced_scandoubler), - .gamma_bus(gamma_bus), - .new_vmode(new_vmode), - .direct_video(direct_video), - .video_rotated(video_rotated), - - .ioctl_download(ioctl_download), - .ioctl_upload(ioctl_upload), - .ioctl_wr(ioctl_wr), - .ioctl_addr(ioctl_addr), - .ioctl_dout(ioctl_dout), - .ioctl_din(ioctl_din), - .ioctl_index(ioctl_index), - .ioctl_wait(ioctl_wait), - - .joystick_0(joy0), - .joystick_1(joy1) -); - -// INPUT - -// 8 dip switches of 8 bits -reg [7:0] sw[8]; -always @(posedge clk_sys) begin - if (ioctl_wr && (ioctl_index==254) && !ioctl_addr[24:3]) begin - sw[ioctl_addr[2:0]] <= ioctl_dout; - end -end - -always @(posedge clk_sys) begin - if (ioctl_wr && ioctl_index==1) begin - pcb <= ioctl_dout; - end -end - -wire direct_video; - -wire ioctl_download; -wire ioctl_upload; -wire ioctl_upload_req; -wire ioctl_wait; -wire ioctl_wr; -wire [15:0] ioctl_index; -wire [26:0] ioctl_addr; -wire [15:0] ioctl_dout; -wire [15:0] ioctl_din; - -reg [1:0] pcb; -wire tile_priority_type; -wire [15:0] scroll_y_offset; - -localparam pcb_vimana = 0; -localparam pcb_samesame = 1; - -wire [21:0] gamma_bus; - -// -// Inputs tied to z80_din -reg [7:0] p1; -reg [7:0] p2; -reg [7:0] z80_dswa; -reg [7:0] z80_dswb; -reg [7:0] z80_tjump; -reg [7:0] system; - -always @ (posedge clk_sys ) begin - p1 <= { 1'b0, p1_buttons[2:0], p1_right, p1_left, p1_down, p1_up }; - p2 <= { 1'b0, p2_buttons[2:0], p2_right, p2_left, p2_down, p2_up }; - z80_dswa <= sw[0]; - z80_tjump <= sw[2]; - - if ( status[32] == 1 ) begin - z80_dswb <= { sw[1][7], sw[1][6] | status[32], sw[1][5:0] }; - system <= { vbl, start2 | p1_buttons[3], start1 | p1_buttons[3], coin_b, coin_a, service, key_tilt, key_service }; - end else begin - z80_dswb <= sw[1]; - system <= { vbl, start2, start1, coin_b, coin_a, service, key_tilt, key_service }; - end -end - -reg p1_swap; - -reg p1_right; -reg p1_left; -reg p1_down; -reg p1_up; -reg [3:0] p1_buttons; - -reg p2_right; -reg p2_left; -reg p2_down; -reg p2_up; -reg [3:0] p2_buttons; - -reg start1; -reg start2; -reg coin_a; -reg coin_b; -reg b_pause; -reg service; -reg [7:0] credits; - -always @ * begin - p1_swap <= status[38]; - - if ( status[38] == 0 ) begin - p1_right <= joy0[0] | key_p1_right; - p1_left <= joy0[1] | key_p1_left; - p1_down <= joy0[2] | key_p1_down; - p1_up <= joy0[3] | key_p1_up; - p1_buttons <= joy0[7:4] | {key_p1_c, key_p1_b, key_p1_a}; - - p2_right <= joy1[0] | key_p2_right; - p2_left <= joy1[1] | key_p2_left; - p2_down <= joy1[2] | key_p2_down; - p2_up <= joy1[3] | key_p2_up; - p2_buttons <= joy1[7:4] | {key_p2_c, key_p2_b, key_p2_a}; - end else begin - p2_right <= joy0[0] | key_p1_right; - p2_left <= joy0[1] | key_p1_left; - p2_down <= joy0[2] | key_p1_down; - p2_up <= joy0[3] | key_p1_up; - p2_buttons <= joy0[7:4] | {key_p1_c, key_p1_b, key_p1_a}; - - p1_right <= joy1[0] | key_p2_right; - p1_left <= joy1[1] | key_p2_left; - p1_down <= joy1[2] | key_p2_down; - p1_up <= joy1[3] | key_p2_up; - p1_buttons <= joy1[7:4] | {key_p2_c, key_p2_b, key_p2_a}; - end -end - -always @ * begin - start1 <= joy0[8] | joy1[8] | key_start_1p; - start2 <= joy0[9] | joy1[9] | key_start_2p; - - coin_a <= joy0[10] | joy1[10] | key_coin_a; - coin_b <= joy0[11] | joy1[11] | key_coin_b; - - b_pause <= joy0[12] | key_pause; - service <= key_test; -end - -// Keyboard handler - -reg key_start_1p, key_start_2p, key_coin_a, key_coin_b; -reg key_tilt, key_test, key_reset, key_service, key_pause; - -reg key_p1_up, key_p1_left, key_p1_down, key_p1_right, key_p1_a, key_p1_b, key_p1_c; -reg key_p2_up, key_p2_left, key_p2_down, key_p2_right, key_p2_a, key_p2_b, key_p2_c; - -wire pressed = ps2_key[9]; - -always @(posedge clk_sys) begin - reg old_state; - old_state <= ps2_key[10]; - if ( old_state ^ ps2_key[10] ) begin - casex ( ps2_key[8:0] ) - 'h016 : key_start_1p <= pressed; // 1 - 'h01E : key_start_2p <= pressed; // 2 - 'h02E : key_coin_a <= pressed; // 5 - 'h036 : key_coin_b <= pressed; // 6 - 'h006 : key_test <= key_test ^ pressed; // f2 - 'h004 : key_reset <= pressed; // f3 - 'h046 : key_service <= pressed; // 9 - 'h02C : key_tilt <= pressed; // t - 'h04D : key_pause <= pressed; // p - - 'h175 : key_p1_up <= pressed; // up - 'h172 : key_p1_down <= pressed; // down - 'h16B : key_p1_left <= pressed; // left - 'h174 : key_p1_right <= pressed; // right - 'h014 : key_p1_a <= pressed; // lctrl - 'h011 : key_p1_b <= pressed; // lalt - 'h029 : key_p1_c <= pressed; // spacebar - - 'h02D : key_p2_up <= pressed; // r - 'h02B : key_p2_down <= pressed; // f - 'h023 : key_p2_left <= pressed; // d - 'h034 : key_p2_right <= pressed; // g - 'h01C : key_p2_a <= pressed; // a - 'h01B : key_p2_b <= pressed; // s - 'h015 : key_p2_c <= pressed; // q - endcase - end -end +wire clk_72; wire pll_locked; +pll_mist pll( + .inclk0(CLOCK_27), + .c0(clk_72), + .locked(pll_locked) + ); -wire clk_sys; -wire turbo_68k = status[15]; -reg clk_3_5M, clk_7M, clk_10M, clk_14M; - -wire clk_70M; - -pll pll -( - .refclk(CLK_50M), - .rst(0), - .outclk_0(clk_sys), - .outclk_1(clk_70M), - .locked(pll_locked) -); - -assign SDRAM_CLK = clk_70M; - -localparam CLKSYS=70; - -reg [5:0] clk14_count; -reg [5:0] clk10_count; -reg [5:0] clk7_count; -reg [5:0] clk_3_5_count; - -always @ (posedge clk_sys ) begin - clk_10M <= 0; - if ( turbo_68k == 0 ) begin - // standard speed 20MHz = 10MHz 68k - case (clk10_count) - 1: clk_10M <= 1; - 3: clk_10M <= 1; - endcase - if ( clk10_count == 6 ) begin - clk10_count <= 0; - end else if ( pause_cpu == 0 ) begin - clk10_count <= clk10_count + 1; - end - end else begin - // standard speed 35MHz = 17.5MHz 68k - case (clk10_count) - 1: clk_10M <= 1; - endcase - if ( clk10_count == 1 ) begin - clk10_count <= 0; - end else if ( pause_cpu == 0 ) begin - clk10_count <= clk10_count + 1; - end - end - clk_7M <= ( clk7_count == 0); - if ( clk7_count == 9 ) begin - clk7_count <= 0; - end else begin - clk7_count <= clk7_count + 1; - end - clk_14M <= ( clk14_count == 0); - if ( clk14_count == 4 ) begin - clk14_count <= 0; - end else begin - clk14_count <= clk14_count + 1; - end - clk_3_5M <= ( clk_3_5_count == 0); - if ( clk_3_5_count == 19 ) begin - clk_3_5_count <= 0; - end else if ( pause_cpu == 0 ) begin - clk_3_5_count <= clk_3_5_count + 1; - end +// reset generation +reg reset = 1; +reg rom_loaded = 0; +always @(posedge clk_72) begin + reg ioctl_downlD; + ioctl_downlD <= ioctl_downl; + if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1; + reset <= status[0] | buttons[1] | ~rom_loaded | ioctl_downl; end -wire reset; -assign reset = RESET | status[0] | (ioctl_download & !ioctl_index) | buttons[1] | key_reset; +// ARM connection +wire [63:0] status; +wire [1:0] buttons; +wire [1:0] switches; +wire [31:0] joystick_0; +wire [31:0] joystick_1; +wire scandoublerD; +wire ypbpr; +wire no_csync; +wire key_strobe; +wire key_pressed; +wire [7:0] key_code; +wire [6:0] core_mod; -////////////////////////////////////////////////////////////////// -wire rotate_ccw = 1; -wire no_rotate = orientation | direct_video; -wire video_rotated; +user_io #( + .STRLEN($size(CONF_STR)>>3), + .ROM_DIRECT_UPLOAD(1)) +user_io( + .clk_sys (clk_72 ), + .conf_str (CONF_STR ), + .SPI_CLK (SPI_SCK ), + .SPI_SS_IO (CONF_DATA0 ), + .SPI_MISO (SPI_DO ), + .SPI_MOSI (SPI_DI ), + .buttons (buttons ), + .switches (switches ), + .scandoubler_disable (scandoublerD ), + .ypbpr (ypbpr ), + .no_csync (no_csync ), + .core_mod (core_mod ), + .key_strobe (key_strobe ), + .key_pressed (key_pressed ), + .key_code (key_code ), + .joystick_0 (joystick_0 ), + .joystick_1 (joystick_1 ), + .status (status ) + ); -reg [23:0] rgb; +wire ioctl_downl; +wire [7:0] ioctl_index; +wire ioctl_wr; +wire [24:0] ioctl_addr; +wire [7:0] ioctl_dout; -wire hbl; -wire vbl; - -wire [8:0] hc; -wire [8:0] vc; - -wire hsync; -wire vsync; - -reg hbl_delay, vbl_delay; - -always @ ( posedge clk_7M ) begin - hbl_delay <= hbl; - vbl_delay <= vbl; -end - -video_timing video_timing ( - .clk(clk_7M), - .reset(reset), - .crtc0(crtc[0]), - .crtc1(crtc[1]), - .crtc2(crtc[2]), - .crtc3(crtc[3]), - .hs_offset(hs_offset), - .vs_offset(vs_offset), - .hs_width(hs_width), - .vs_width(vs_width), - .refresh_mod(refresh_mod), - .hc(hc), - .vc(vc), - .hbl_delay(hbl), - .vbl(vbl), - .hsync(hsync), - .vsync(vsync) +data_io #(.ROM_DIRECT_UPLOAD(1)) data_io( + .clk_sys ( clk_72 ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS2 ( SPI_SS2 ), + .SPI_SS4 ( SPI_SS4 ), + .SPI_DI ( SPI_DI ), + .SPI_DO ( SPI_DO ), + .ioctl_download( ioctl_downl ), + .ioctl_index ( ioctl_index ), + .ioctl_wr ( ioctl_wr ), + .ioctl_addr ( ioctl_addr ), + .ioctl_dout ( ioctl_dout ) ); -// PAUSE SYSTEM -wire pause_cpu; -wire hs_pause; +wire [15:0] laudio, raudio; +wire hs, vs; +wire blankn = ~(hb | vb); +wire hb, vb; +wire [4:0] r,b,g; -// 8 bits per colour, 70MHz sys clk -pause #(8,8,8,70) pause -( - .clk_sys(clk_sys), - .reset(reset), - .user_button(b_pause), - .pause_request(hs_pause), - .options(status[21:20]), - .pause_cpu(pause_cpu), - .dim_video(dim_video), - .OSD_STATUS(OSD_STATUS), - .r(rgb[23:16]), - .g(rgb[15:8]), - .b(rgb[7:0]), - .rgb_out(rgb_pause_out) +Vimana_Top Vimana_Top( + .pll_locked ( pll_locked ), + .clk_sys ( clk_72 ), + .reset ( reset ), + .turbo_68k (0),//cpu_turbo + .pause_cpu (0), +// input scrollDBG, + .p1_right (m_right1), + .p1_left (m_left1), + .p1_down (m_down1), + .p1_up (m_up1), + .p1_buttons (m_fire1[3:0]), + .p2_right (m_right2), + .p2_left (m_left2), + .p2_down (m_down2), + .p2_up (m_up2), + .p2_buttons (m_fire2[3:0]), + .start1 (m_one_player), + .start2 (m_two_players), + .coin_a (m_coin1), + .coin_b (m_coin2), + .b_pause (), + .service (), + .key_tilt (m_tilt), + .key_service (), + .sw0 (), + .sw1 (), + .sw2 (), + + .hblank ( hb ), + .vblank ( vb ), + .hsync ( hs ), + .vsync ( vs ), + .r ( r ), + .g ( g ), + .b ( b ), + .hs_offset (0), + .vs_offset (0), + .hs_width (0), + .vs_width (0), + .refresh_mod (0), + + .ntsc (0), + .opl2_level (2'b00), + + + .audio_l ( laudio ), + .audio_r ( raudio ), + + .ioctl_download( ioctl_downl), + .ioctl_index (ioctl_index), + .ioctl_addr ( ioctl_addr - 2'd2 ),//check + .ioctl_wr ( ioctl_wr ), + .ioctl_dout ( ioctl_dout ), + + .SDRAM_A ( SDRAM_A ), + .SDRAM_BA ( SDRAM_BA ), + .SDRAM_DQ ( SDRAM_DQ ), + .SDRAM_DQML ( SDRAM_DQML ), + .SDRAM_DQMH ( SDRAM_DQMH ), + .SDRAM_nCS ( SDRAM_nCS ), + .SDRAM_nCAS ( SDRAM_nCAS ), + .SDRAM_nRAS ( SDRAM_nRAS ), + .SDRAM_nWE ( SDRAM_nWE ) ); -wire [23:0] rgb_pause_out; -wire dim_video; - -arcade_video #(320,24) arcade_video -( - .*, - - .clk_video(clk_sys), - .ce_pix(clk_7M), - - .RGB_in(rgb_pause_out), - - .HBlank(hbl), - .VBlank(vbl), - .HSync(hsync), - .VSync(vsync), - - .fx(scan_lines) -); - -/* - Phase Accumulator Increments (Fractional Size 32, look up size 8 bit, total 40 bits) - Increment Calculation - (Output Clock * 2 ^ Word Size) / Reference Clock - Example - NTSC = 3.579545 - PAL = 4.43361875 - W = 40 ( 32 bit fraction, 8 bit look up reference) - Ref CLK = 42.954544 (This could us any clock) - NTSC_Inc = 3.579545333 * 2 ^ 40 / 96 = 40997413706 -*/ - -// SET PAL and NTSC TIMING -`ifdef MISTER_ENABLE_YC - assign CHROMA_PHASE_INC = PALFLAG ? 40'd56225080500: 40'd56225080500; - assign YC_EN = status[22]; - assign PALFLAG = status[7]; -`endif - -screen_rotate screen_rotate (.*); - -wire [9:0] sprite_adj_x = 0; -wire [9:0] sprite_adj_y = 0; -wire bcu_flip_cs; -wire fcu_flip_cs; - -reg [1:0] adj_layer; -reg [15:0] scroll_adj_x [3:0]; -reg [15:0] scroll_adj_y [3:0]; -reg layer_en [3:0]; - -reg ce_pix; - -// flip is done in the rendering so leave screen_rotate flip off -wire flip = 0; - -reg tile_flip; -reg sprite_flip; - -//assign vc = vcx - vs_offset; - -// =============================================================== -// 68000 CPU -// =============================================================== - -// clock generation -reg fx68_phi1 = 0; -wire fx68_phi2 = !fx68_phi1; - -// phases for 68k clock -always @(posedge clk_sys) begin - if ( clk_10M == 1 ) begin - fx68_phi1 <= ~fx68_phi1; - end -end - -// CPU outputs -wire cpu_rw; // Read = 1, Write = 0 -wire cpu_as_n; // Address strobe -wire cpu_lds_n; // Lower byte strobe -wire cpu_uds_n; // Upper byte strobe -wire cpu_E; -wire [2:0]cpu_fc; // Processor state -wire cpu_reset_n_o; // Reset output signal -wire cpu_halted_n; // Halt output - -// CPU busses -wire [15:0] cpu_dout; -wire [23:0] cpu_a /* synthesis keep */; -reg [15:0] cpu_din; - -// CPU inputs -reg dtack_n; // Data transfer ack (always ready) - -reg ipl1_n; -reg ipl2_n; - -wire reset_n; -wire vpa_n = ~ ( cpu_lds_n == 0 && cpu_fc == 3'b111 ); // from outzone schematic - -assign cpu_a[0] = reset; // debug hack odd memory address should cause cpu exception - -cc_shifter cc_reset ( - .clk_out(clk_10M), - .i(reset_z80_n), - .o(reset_n) -); - -fx68k fx68k ( - // input - .clk( clk_10M ), - .enPhi1(fx68_phi1), - .enPhi2(fx68_phi2), - .extReset(reset), - .pwrUp(reset), - - // output - .eRWn(cpu_rw), - .ASn( cpu_as_n), - .LDSn(cpu_lds_n), - .UDSn(cpu_uds_n), -// .E(cpu_E), -// .VMAn(), - .FC0(cpu_fc[0]), - .FC1(cpu_fc[1]), - .FC2(cpu_fc[2]), -// .BGn(), - .oRESETn(cpu_reset_n_o), - .oHALTEDn(cpu_halted_n), - - // input - .VPAn( vpa_n ), - .DTACKn(dtack_n ), - .BERRn(1'b1), - .BRn(1'b1), - .BGACKn(1'b1), - - .IPL0n(1'b1), - .IPL1n(ipl1_n), - .IPL2n(ipl2_n), - - // busses - .iEdb(cpu_din), - .oEdb(cpu_dout), - .eab(cpu_a[23:1]) -); - - - -always @ (posedge clk_sys) begin -end - -wire [15:0] cpu_shared_dout; -wire [7:0] z80_shared_dout; -reg [15:0] z80_a; - -wire [15:0] z80_addr; -reg [7:0] z80_din; -wire [7:0] z80_dout; - -wire z80_wr_n; -wire z80_rd_n; -reg z80_wait_n; - -wire IORQ_n; -wire MREQ_n; - -always @ (posedge clk_sys) begin - if ( reset == 1 ) begin - z80_wait_n <= 0; - sound_wr <= 0; - int_en <= 1; - reset_z80_n <= 1; - - end else begin - reset_z80_n <= cpu_reset_n_o; - - // write lasts multiple cpu clocks so limit to one increment per write signal - if ( inc_sprite_ofs == 1 && cpu_rw == 1 ) begin - curr_sprite_ofs <= curr_sprite_ofs + 1; - inc_sprite_ofs <= 0; - end - - if ( clk_10M == 1 ) begin - // tell 68k to wait for valid data. 0=ready 1=wait - // always ack when it's not program rom - dtack_n <= prog_rom_cs ? !prog_rom_data_valid : 0; - // add dsp_ctrl_cs to cpu_din - // select cpu data input based on what is active - if ( pcb == 0 ) begin - cpu_din <= prog_rom_cs ? prog_rom_data : - ram_cs ? ram_dout : - tile_palette_cs ? tile_palette_cpu_dout : - sprite_palette_cs ? sprite_palette_cpu_dout : - tile_ofs_cs ? curr_tile_ofs : - sprite_ofs_cs ? curr_sprite_ofs : - tile_attr_cs ? cpu_tile_dout_attr : - tile_num_cs ? cpu_tile_dout_num : - sprite_0_cs ? sprite_0_dout : - sprite_1_cs ? sprite_1_dout : - sprite_2_cs ? sprite_2_dout : - sprite_3_cs ? sprite_3_dout : - sprite_size_cs ? sprite_size_cpu_dout : - frame_done_cs ? { 16 { vbl } } : // get vblank state - shared_ram_cs ? cpu_shared_dout : - vblank_cs ? { 15'b0, vbl } : - int_en_cs ? 16'hffff : - 16'd0; - - end else begin - // same same same - cpu_din <= prog_rom_cs ? prog_rom_data : - ram_cs ? ram_dout : - tile_palette_cs ? tile_palette_cpu_dout : - sprite_palette_cs ? sprite_palette_cpu_dout : - tile_ofs_cs ? curr_tile_ofs : - sprite_ofs_cs ? curr_sprite_ofs : - tile_attr_cs ? cpu_tile_dout_attr : - tile_num_cs ? cpu_tile_dout_num : - sprite_0_cs ? sprite_0_dout : - sprite_1_cs ? sprite_1_dout : - sprite_2_cs ? sprite_2_dout : - sprite_3_cs ? sprite_3_dout : - sprite_size_cs ? sprite_size_cpu_dout : - p1_cs ? { 8'h00, p1[7:0] }: - p2_cs ? { 8'h00, p2[7:0] } : - dswa_cs ? { 8'h00, z80_dswa[7:0] } : - dswb_cs ? { 8'h00, z80_dswb[7:0] } : - system_cs ? { 8'h00, system[7:0] } : - tjump_cs ? { 8'h00, 1'b1, z80_tjump[6:0] } : - frame_done_cs ? { 15'b0, vbl } : // get vblank state - vblank_cs ? { 15'b0, vbl } : - int_en_cs ? 16'hffff : - 16'd0; - end - - if ( cpu_rw == 0 ) begin - if ( tile_ofs_cs ) begin - curr_tile_ofs <= cpu_dout; - end - if ( int_en_cs ) begin - int_en <= cpu_dout[0]; - end - if ( crtc_cs ) begin - crtc[ cpu_a[2:1] ] <= cpu_dout; - end - if ( bcu_flip_cs ) begin - tile_flip <= cpu_dout[0]; - end - if ( fcu_flip_cs ) begin - sprite_flip <= cpu_dout[15]; - end - if ( sprite_ofs_cs ) begin - // mask out valid range - curr_sprite_ofs <= { 6'b0, cpu_dout[9:0] }; - end - if ( scroll_ofs_x_cs ) begin - scroll_ofs_x <= cpu_dout; - end - if ( scroll_ofs_y_cs ) begin - scroll_ofs_y <= cpu_dout; - end - // x layer values are even addresses - if ( scroll_cs ) begin - if ( cpu_a[1] == 0 ) begin - scroll_x[ cpu_a[3:2] ] <= cpu_dout[15:7]; - end else begin - scroll_y[ cpu_a[3:2] ] <= cpu_dout[15:7]; - end - end - // offset needs to be auto-incremented - if ( sprite_cs | sprite_size_cs ) begin - inc_sprite_ofs <= 1; - end - if ( reset_z80_cs ) begin - // the pcb writes to a latch to control the reset - reset_z80_n <= cpu_dout[0]; - end - - if ( sound_latch_w_cs ) begin - sound_latch <= cpu_dout[7:0]; - sound_latch_set <= 1; - end - end - end - - if ( clk_3_5M == 1 ) begin - z80_wait_n <= 1; - if ( ioctl_download | ( z80_rd_n == 0 && sound_rom_1_data_valid == 0 && sound_rom_1_cs == 1 ) ) begin - // wait if rom is selected and data is not yet available - z80_wait_n <= 0; - end - - if ( z80_rd_n == 0 ) begin - if ( sound_rom_1_cs ) begin - if ( sound_rom_1_data_valid ) begin - z80_din <= sound_rom_1_data; - end else begin - z80_wait_n <= 0; - end - end else if ( sound_ram_1_cs ) begin - z80_din <= z80_shared_dout; - end else if ( sound0_cs ) begin - z80_din <= opl_dout; - end else if ( sound_latch_r_cs ) begin - z80_din <= sound_latch ; - end else if ( sound_status_cs ) begin - z80_din <= sound_latch_set ? 8'hff : 8'h00 ; - end else begin - z80_din <= 8'h00; - end - - if ( pcb == 0 ) begin - if ( p1_cs ) begin - z80_din <= p1 ; - end else if ( p2_cs ) begin - z80_din <= p2 ; - end else if ( dswa_cs ) begin - z80_din <= z80_dswa ; - end else if ( dswb_cs ) begin - z80_din <= ~z80_dswb ; - end else if ( tjump_cs ) begin - z80_din <= 8'hc0 | ~z80_tjump ; - end else if ( system_cs ) begin - z80_din <= system ; - end - end - end - sound_wr <= 0; - if ( z80_wr_n == 0 ) begin - if ( sound0_cs | sound1_cs ) begin - sound_data <= z80_dout; - sound_addr <= { 1'b0, sound1_cs }; - sound_wr <= 1; - end else if ( sound_done_cs ) begin - sound_latch <= z80_dout ; - sound_latch_set <= 0; - end - end - end - end -end - -reg [1:0] sound_addr; -reg [7:0] sound_data; -reg sound_wr; - -wire [7:0] opl_dout; -wire opl_irq_n; - -reg signed [15:0] sample; - -assign AUDIO_S = 1'b1; - -wire opl_sample_clk; - -jtopl #(.OPL_TYPE(2)) jtopl2 -( - .rst(~reset_n), - .clk(clk_sys), - .cen(clk_3_5M), - .din(sound_data), - .addr(sound_addr), - .cs_n('0), - .wr_n(~sound_wr), - .dout(opl_dout), - .irq_n(opl_irq_n), - .snd(sample), - .sample(opl_sample_clk) -); - -wire [1:0] opl2_level = status[44:43]; // opl2 audio mix - -reg [7:0] opl2_mult; - -// set the multiplier for each channel from menu - -always @( posedge clk_sys, posedge reset ) begin - if (reset) begin - opl2_mult<=0; - end else begin - case( opl2_level ) - 0: opl2_mult <= 8'h0c; // 75% - 1: opl2_mult <= 8'h08; // 50% - 2: opl2_mult <= 8'h04; // 25% - 3: opl2_mult <= 8'h00; // 0% - endcase - end -end - -wire signed [15:0] mono; - -jtframe_mixer #(.W0(16), .WOUT(16)) u_mix_mono( - .rst ( reset ), - .clk ( clk_sys ), - .cen ( 1'b1 ), - // input signals - .ch0 ( sample ), - .ch1 ( 16'd0 ), - .ch2 ( 16'd0 ), - .ch3 ( 16'd0 ), - // gain for each channel in 4.4 fixed point format - .gain0 ( opl2_mult ), - .gain1 ( 8'd0 ), - .gain2 ( 8'd0 ), - .gain3 ( 8'd0 ), - .mixed ( mono ), - .peak ( ) -); - -always @ (posedge clk_sys ) begin - if ( pause_cpu == 1 ) begin - AUDIO_L <= 0; - AUDIO_R <= 0; - end else if ( pause_cpu == 0 ) begin - // mix audio - AUDIO_L <= mono; - AUDIO_R <= mono; - end -end - -T80pa u_cpu( - .RESET_n ( reset_n & reset_z80_n ), - .CLK ( clk_sys ), - .CEN_p ( clk_3_5M ), - .CEN_n ( ~clk_3_5M ), - - .WAIT_n ( z80_wait_n ), // don't wait if data is valid or rom access isn't selected - .INT_n ( opl_irq_n ), // opl timer - .NMI_n ( 1'b1 ), - .BUSRQ_n ( 1'b1 ), - .RD_n ( z80_rd_n ), - .WR_n ( z80_wr_n ), - .A ( z80_addr ), - .DI ( z80_din ), - .DO ( z80_dout ), - // unused - .DIRSET ( 1'b0 ), - .DIR ( 212'b0 ), - .OUT0 ( 1'b0 ), - .RFSH_n (), - .IORQ_n ( IORQ_n ), - .M1_n (), - .BUSAK_n (), - .HALT_n ( 1'b1 ), - .MREQ_n ( MREQ_n ), - .Stop (), - .REG () -); - -// Chip select mux -wire prog_rom_cs; -wire scroll_ofs_x_cs; -wire scroll_ofs_y_cs; -wire ram_cs; -wire vblank_cs; -wire int_en_cs; -wire crtc_cs; -wire tile_ofs_cs; -wire tile_attr_cs; -wire tile_num_cs; -wire scroll_cs; -wire shared_ram_cs; -wire frame_done_cs; // word -wire tile_palette_cs; -wire sprite_palette_cs; -wire sprite_ofs_cs; -wire sprite_cs; // *** offset needs to be auto-incremented -wire sprite_size_cs; // *** offset needs to be auto-incremented -wire sprite_ram_cs; - -wire p1_cs; -wire p2_cs; -wire dswa_cs; -wire dswb_cs; -wire system_cs; -wire tjump_cs; -wire sound0_cs; -wire sound1_cs; -wire sound_latch_cs; -wire sound_latch_w_cs; -wire sound_latch_r_cs; -wire sound_status_cs; -wire sound_done_cs; - -chip_select cs (.*); - -wire sprite_0_cs = ( curr_sprite_ofs[1:0] == 2'b00 ) & sprite_cs; -wire sprite_1_cs = ( curr_sprite_ofs[1:0] == 2'b01 ) & sprite_cs; -wire sprite_2_cs = ( curr_sprite_ofs[1:0] == 2'b10 ) & sprite_cs; -wire sprite_3_cs = ( curr_sprite_ofs[1:0] == 2'b11 ) & sprite_cs; - -reg reset_z80_n; -wire reset_z80_cs; -wire sound_rom_1_cs = ( MREQ_n == 0 && z80_addr <= 16'h7fff ); -wire sound_ram_1_cs = ( MREQ_n == 0 && z80_addr >= 16'h8000 && z80_addr <= 16'hffff ); - -reg int_en; -reg int_ack; - -reg sound_latch_set; -reg [7:0] sound_latch ; - -reg [1:0] vbl_sr; - -// vblank interrupt on rising vbl -always @ (posedge clk_sys ) begin - if ( reset == 1 ) begin - ipl2_n <= 1; - ipl1_n <= 1; - int_ack <= 0; - end else begin - vbl_sr <= { vbl_sr[0], vbl }; - if ( clk_10M == 1 ) begin - int_ack <= ( cpu_as_n == 0 ) && ( cpu_fc == 3'b111 ); // cpu acknowledged the interrupt - end - if ( vbl_sr == 2'b01 ) begin// rising edge - ipl2_n <= ~int_en; - end else if ( vbl_sr == 2'b10 ) begin - if ( pcb == 1 ) begin - ipl1_n <= 0; - end - end else if ( int_ack == 1 || vbl_sr == 2'b10 ) begin - ipl2_n <= 1; - ipl1_n <= 1; - end - end -end - -reg [15:0] scroll_x [3:0]; -reg [15:0] scroll_y [3:0]; - -reg [15:0] scroll_x_latch [3:0]; -reg [15:0] scroll_y_latch [3:0]; - -reg inc_sprite_ofs; - -reg [15:0] crtc[4]; - -reg [15:0] scroll_x_total [3:0]; -reg [15:0] scroll_y_total [3:0]; - -wire [15:0] ram_dout; -wire [9:0] tile_palette_addr; -wire [15:0] tile_palette_cpu_dout; -wire [15:0] tile_palette_dout; - -wire [9:0] sprite_palette_addr; -wire [15:0] sprite_palette_cpu_dout; -wire [15:0] sprite_palette_dout; - -reg [15:0] curr_tile_ofs; -reg [15:0] curr_sprite_ofs; - -reg [15:0] scroll_ofs_x; -reg [15:0] scroll_ofs_y; - -wire [15:0] cpu_tile_dout_attr; -wire [15:0] cpu_tile_dout_num; - -wire [15:0] sprite_0_dout; -wire [15:0] sprite_1_dout; -wire [15:0] sprite_2_dout; -wire [15:0] sprite_3_dout; -wire [15:0] sprite_size_dout; -wire [15:0] sprite_size_cpu_dout; - -wire [31:0] tile_attr_dout; -wire [15:0] sprite_attr_0_dout; -wire [15:0] sprite_attr_1_dout; -wire [15:0] sprite_attr_2_dout; -wire [15:0] sprite_attr_3_dout; - -wire [15:0] sprite_size_buf_dout; -wire [15:0] sprite_attr_0_buf_dout; -wire [15:0] sprite_attr_1_buf_dout; -wire [15:0] sprite_attr_2_buf_dout; -wire [15:0] sprite_attr_3_buf_dout; - -reg [15:0] sprite_buf_din; - -reg [14:0] tile; - -reg [7:0] sprite_num; -reg [7:0] sprite_num_copy; - -reg [3:0] tile_draw_state; - -reg [2:0] layer; // 4 layers + 1 for initial background - -wire [14:0] tile_idx = tile_attr[14:0]; -wire [3:0] tile_priority = tile_attr[31:28]; -wire [5:0] tile_palette_idx = tile_attr[21:16]; -wire tile_hidden = tile_attr[15]; - -reg [15:0] fb_dout; -wire [15:0] tile_fb_out; -wire [15:0] sprite_fb_out; -reg [15:0] fb_din; -reg [15:0] sprite_fb_din; - -reg tile_fb_w; -reg sprite_fb_w; -reg sprite_buf_w; -reg sprite_size_buf_w; - -dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) tile_line_buffer ( - .clock_a ( clk_sys ), - .address_a ( tile_fb_addr_w ), - .wren_a ( tile_fb_w ), - .data_a ( fb_din ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( fb_addr_r ), - .wren_b ( 0 ), -// .data_b ( ), - .q_b ( tile_fb_out ) -); - -dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) sprite_line_buffer ( - .clock_a ( clk_sys ), - .address_a ( sprite_fb_addr_w ), - .wren_a ( sprite_fb_w ), - .data_a ( sprite_fb_din ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( fb_addr_r ), - .wren_b ( 0 ), -// .data_b ( ), - .q_b ( sprite_fb_out ) -); - -reg [9:0] x_ofs; -reg [9:0] x; - -reg [9:0] y_ofs; - -// y needs to be one line ahaed of the visible line -// render the first line at the end of the previous frame -// this depends on the timing that the sprite list is valid -// sprites values are copied at the start of vblank (line 240) - -// global offsets -wire [9:0] x_ofs_dx = 495 + { ~layer[1:0], 1'b0 }; -wire [9:0] y_ofs_dx = 257; -wire [9:0] x_ofs_dx_flipped = 17 - { ~layer[1:0], 1'b0 }; -wire [9:0] y_ofs_dx_flipped = 255; - -// calculate scrolling -wire [9:0] tile_x_unflipped = scroll_x_latch[layer[1:0]] + x_ofs_dx; -wire [9:0] tile_y_unflipped = scroll_y_latch[layer[1:0]] + y_ofs_dx + scroll_y_offset; -wire [9:0] tile_x_flipped = 319 + scroll_x_latch[layer[1:0]] + x_ofs_dx_flipped; -wire [9:0] tile_y_flipped = 239 + scroll_y_latch[layer[1:0]] + y_ofs_dx_flipped + scroll_y_offset; - -// reverse tiles when flipped -wire [9:0] curr_x = tile_flip ? tile_x_flipped - x : tile_x_unflipped + x; -wire [9:0] curr_y = tile_flip ? tile_y_flipped - y : tile_y_unflipped + y; - -reg [9:0] y; -wire [9:0] y_flipped = ( sprite_flip ? (240 - y ) + scroll_y_offset : y + scroll_y_offset); -wire [9:0] sprite_buf_x = sprite_flip ? 320 - (sprite_x + sprite_pos_x ) : sprite_x + sprite_pos_x; // offset from left of frame - -reg [3:0] draw_state; -reg [3:0] sprite_state; -reg [3:0] tile_copy_state; -reg [3:0] sprite_copy_state; - -// pixel 4 bit colour -wire [3:0] tile_pix; -assign tile_pix = { tile_data[7-curr_x[2:0]], tile_data[15-curr_x[2:0]], tile_data[23-curr_x[2:0]], tile_data[31-curr_x[2:0]] }; - -wire [2:0] sprite_bit = sprite_x[2:0]; -wire [3:0] sprite_pix; -assign sprite_pix = { sprite_data[7-sprite_bit], sprite_data[15-sprite_bit], sprite_data[23-sprite_bit], sprite_data[31-sprite_bit] }; - -// two lines of buffer alternate -reg [9:0] tile_fb_addr_w; -wire [9:0] fb_addr_r = {vc[0], 9'b0 } + hc; - -reg [9:0] sprite_fb_addr_w; - -reg [31:0] tile_attr; - -// two lines worth for 4 layers (~8k) -// [15:14] = layer. -// [13:10] = prioity -// [9:4] = palette offset -// [3:0] = tile colour index. - -reg [3:0] tile_priority_buf [327:0]; -reg [3:0] sprite_priority_buf [327:0]; - -reg [9:0] sprite_x; // offset from left side of sprite -reg [9:0] sprite_y; - -wire [14:0] sprite_index = sprite_attr_0_buf_dout[14:0] /* synthesis keep */; -wire sprite_hidden = sprite_attr_0_buf_dout[15] /* synthesis keep */; - -wire [5:0] sprite_pal_addr = sprite_attr_1_buf_dout[5:0] /* synthesis keep */; -wire [5:0] sprite_size_addr = sprite_attr_1_buf_dout[11:6] /* synthesis keep */; -wire [3:0] sprite_priority = sprite_attr_1_buf_dout[15:12] /* synthesis keep */; - -wire [9:0] sprite_pos_x = sprite_adj_x + (( sprite_attr_2_buf_dout[15:7] < 9'h180 ) ? sprite_attr_2_buf_dout[15:7] : ( sprite_attr_2_buf_dout[15:7] - 10'h200)); -wire [9:0] sprite_pos_y = sprite_adj_y + (( sprite_attr_3_buf_dout[15:7] < 9'h180 ) ? sprite_attr_3_buf_dout[15:7] : ( sprite_attr_3_buf_dout[15:7] - 10'h200)); - -// valid 1 cycle after sprite attr ready -wire [8:0] sprite_height = { sprite_size_buf_dout[7:4], 3'b0 } /* synthesis keep */; // in pixels -wire [8:0] sprite_width = { sprite_size_buf_dout[3:0], 3'b0 } /* synthesis keep */; - -reg [7:0] sprite_buf_num; - -reg [1:0] vtotal_282_flag; - -always @ (posedge clk_sys) begin // Check System Vcount flag for 60Hz mode - if ({crtc[2][7:0], 1'b1 } == 269) - vtotal_282_flag <= 0; - else - vtotal_282_flag <= 1; -end - -always @ (posedge clk_sys) begin - if ( reset == 1 ) begin - sprite_state <= 0; - draw_state <= 0; - sprite_rom_cs <= 0; - tile_rom_cs <= 0; - tile_copy_state <= 0; - sprite_copy_state <= 0; - tile_draw_state <= 0; - end else begin - // render sprites - // triggered when the tile rendering starts - if ( sprite_state == 0 && draw_state > 0 ) begin - sprite_num <= 8'h00; - sprite_x <= 0; - sprite_fb_w <= 1; - sprite_state <= 1; - sprite_fb_din <= 0; - sprite_fb_addr_w <= { y[0], 9'b0 }; - end else if ( sprite_state == 1 ) begin - // erase line buffer - sprite_fb_addr_w <= { y[0], 9'b0 } + sprite_x; - sprite_priority_buf[sprite_x] <= 0; - if ( sprite_x < 320 ) begin - sprite_x <= sprite_x + 1; - end else begin - sprite_x <= 0; - sprite_fb_w <= 0; - sprite_state <= 2; - end - end else if ( sprite_state == 2 ) begin - // sprite num is valid now - sprite_state <= 3; - end else if ( sprite_state == 3 ) begin - // sprite attr valid now. - // delay one more cycle to read sprite size - sprite_state <= 4; - end else if ( sprite_state == 4 ) begin - // start loop - sprite_rom_cs <= 0; - sprite_fb_w <= 0; - sprite_y <= y_flipped - sprite_pos_y; - // is sprite visible and is current y in sprite y range - // sprite pos can be negative? - if ( sprite_hidden == 0 && sprite_width > 0 && ( $signed(y_flipped) >= $signed(sprite_pos_y) ) && $signed(y_flipped) < ( $signed(sprite_pos_y) + $signed(sprite_height) ) ) begin - sprite_state <= 5; - end else if ( sprite_num < 8'hff ) begin - sprite_num <= sprite_num + 1; - sprite_state <= 2; - end else begin - sprite_state <= 15; - end - end else if ( sprite_state == 5 ) begin - sprite_rom_addr <= { sprite_index, 3'b0 } + { sprite_x[8:3], 3'b0 } + ( sprite_y[8:3] * sprite_width ) + sprite_y[2:0]; - sprite_rom_cs <= 1; - sprite_state <= 6; - end else if ( sprite_state == 6 ) begin - // wait for sprite bitmap ready - if ( sprite_rom_data_valid ) begin - // latch data and deassert cs - sprite_data <= sprite_rom_data; - sprite_rom_cs <= 0; - sprite_state <= 7; - end - end else if ( sprite_state == 7 ) begin - sprite_fb_w <= 0; - // draw if pixel value not zero and priority >= previous sprite data -// if ( sprite_pix > 0 && sprite_priority_buf[sprite_buf_x] == 0 ) begin -// if ( sprite_pix != 0 && ( sprite_priority == 0 || sprite_priority >= sprite_priority_buf[sprite_buf_x] ) ) begin - if ( sprite_pix != 0 ) begin - sprite_fb_din <= { 2'b11, sprite_priority, sprite_pal_addr, sprite_pix }; -// if ( sprite_priority == 0 ) begin -// sprite_priority_buf[sprite_buf_x] <= { 1'b1, sprite_priority }; -// end else begin - sprite_fb_addr_w <= { y[0], 9'b0 } + sprite_buf_x; - sprite_priority_buf[sprite_buf_x] <= sprite_priority; - sprite_fb_w <= 1; - end - if ( sprite_x < ( sprite_width - 1 ) ) begin - sprite_x <= sprite_x + 1; - if ( sprite_x[2:0] == 7 ) begin - // do recalc bitmap address - sprite_state <= 5; - end - end else if ( sprite_num < 8'hff ) begin - sprite_num <= sprite_num + 1; - sprite_x <= 0; - // need to load new attributes and size - sprite_state <= 2; - end else begin - // tile state machine will reset sprite_state when line completes. - sprite_state <= 15; // done - end - end - // copy tile ram and scroll info - // not sure if this is needed. need to check to see when tile ram is updated. - if ( tile_copy_state == 0 && vc == 256 ) begin - tile_copy_state <= 1; - end else begin - // copy scroll registers - scroll_x_latch[0] <= scroll_x[0] - scroll_ofs_x; - scroll_x_latch[1] <= scroll_x[1] - scroll_ofs_x; - scroll_x_latch[2] <= scroll_x[2] - scroll_ofs_x; - scroll_x_latch[3] <= scroll_x[3] - scroll_ofs_x; - scroll_y_latch[0] <= scroll_y[0] - scroll_ofs_y; - scroll_y_latch[1] <= scroll_y[1] - scroll_ofs_y; - scroll_y_latch[2] <= scroll_y[2] - scroll_ofs_y; - scroll_y_latch[3] <= scroll_y[3] - scroll_ofs_y; - end - // copy sprite attr/size to buffer - if ( sprite_copy_state == 0 && vc == 240 ) begin - sprite_copy_state <= 1; - sprite_buf_w <= 0; - sprite_num_copy <= 8'h00; - end else if ( sprite_copy_state == 1 ) begin - sprite_num_copy <= sprite_num_copy + 1; - sprite_buf_num <= sprite_num_copy; - sprite_buf_w <= 1; - // wait for read from source - if ( sprite_num_copy == 8'hff ) begin - sprite_copy_state <= 2; - end - end else if ( sprite_copy_state == 2 ) begin - sprite_buf_w <= 0; - sprite_copy_state <= 0; - end - // tile state machine - if ( draw_state == 0 && vc == ({ crtc[2][7:0], 1'b1 } - (status[19] ? (vtotal_282_flag ? 5'd19 : 4'd7) : 3'd0)) ) begin // 282 Lines standard (263 Lines for 60Hz) - layer <= 4; // layer 4 is layer 0 but draws hidden and transparent - y <= 0; - draw_state <= 2; - sprite_state <= 0; - end else if ( draw_state == 2 ) begin - x <= 0; - x_ofs <= scroll_x_latch[layer[1:0]]; - y_ofs <= scroll_y_latch[layer[1:0]]; - // latch offset info - draw_state <= 3; - tile_draw_state <= 0; - end else if ( draw_state == 3 ) begin - if ( tile_draw_state == 0 ) begin - tile <= { layer[1:0], curr_y[8:3], curr_x[8:3] }; // works - tile_draw_state <= 4'h1; - end else if ( tile_draw_state == 1 ) begin - tile_draw_state <= 2; - end else if ( tile_draw_state == 2 ) begin - // latch attribute - tile_attr <= tile_attr_dout; - if ( layer == 4 || tile_attr_dout[15] == 0 ) begin - tile_draw_state <= 3; - end else begin - if ( x < 320 ) begin// 319 - tile_draw_state <= 3; - // do we need to read another tile? - // last pixel of this tile changes based on flip direction - if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin - draw_state <= 3; - tile_draw_state <= 0; - end - x <= x + 1; - end else if ( layer > 0 ) begin - layer <= layer - 1; - tile_fb_w <= 0; - draw_state <= 2; - end else begin - // done - tile_draw_state <= 7; - tile_fb_w <= 0; - end - end - end else if ( tile_draw_state == 3 ) begin - // read bitmap info - tile_rom_cs <= 1; - tile_rom_addr <= { tile_idx, curr_y[2:0] }; - tile_draw_state <= 4; - end else if ( tile_draw_state == 4 ) begin - // wait for bitmap ram ready - if ( tile_rom_data_valid ) begin - // latch data and deassert cs - tile_data <= tile_rom_data; - tile_draw_state <= 5; - tile_rom_cs <= 0; - end - end else if ( tile_draw_state == 5 ) begin - tile_fb_w <= 0; - tile_fb_addr_w <= { y[0], 9'b0 } + x; - // force render of first layer. - // if layer == 4 then tile_pix == 0 is not transparent - // layer 4 is really layer 0 - if ( layer == 4 ) begin - tile_priority_buf[x] <= 0; //tile_pix == 0 ? 0 : tile_priority; - //fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; - fb_din <= { layer[1:0], 4'b0, tile_palette_idx, tile_pix }; - tile_fb_w <= 1; - end else if (tile_hidden == 0 && tile_pix > 0 && tile_priority > 0 && tile_priority >= tile_priority_buf[x] ) begin - tile_priority_buf[x] <= tile_priority; - // if tile hidden then make the pallette index 0. ie transparent - fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; - tile_fb_w <= 1; - end - if ( x < 320 ) begin// 319 - // do we need to read another tile? - // last pixel of this tile changes based on flip direction - if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin - draw_state <= 3; - tile_draw_state <= 0; - end - x <= x + 1; - end else if ( layer > 0 ) begin - layer <= layer - 1; - tile_fb_w <= 0; - draw_state <= 2; - end else begin - // done - tile_draw_state <= 7; - tile_fb_w <= 0; - end - end else if ( tile_draw_state == 7 ) begin - // wait for next line or quit - if ( y == 239 ) begin - draw_state <= 0; - end else if ( hc == (status[19] ? 9'd444 : 9'd449) ) begin // 450 Lines standard (445 Lines for NTSC standard 15.73kHz line freq) - y <= y + 1; - draw_state <= 2; - sprite_state <= 0; - layer <= 4; - end - end - end - end -end - -// render -reg draw_sprite; - -// two lines worth for 4 layers (~8k) -// [15:14] = layer. -// [13:10] = prioity -// [9:4] = palette offset -// [3:0] = tile colour index. - -// there are 10 70MHz cycles per pixel. clk7_count from 0-9 - -// dac values based on 120 ohm driver for the resistor dac and 75 ohm output. 4.7k, 2.2k, 1k, 470, 220 -// modeled in spice -wire [7:0] dac [0:31] = '{0,12,25,36,50,61,73,83,91,100,111,120,131,139,149,157,145,154,162,170,180,187,195,202,208,214,222,228,236,242,249,255}; - -always @ (posedge clk_sys) begin - if ( clk7_count == 4 ) begin - tile_palette_addr <= tile_fb_out[9:0]; - sprite_palette_addr <= sprite_fb_out[9:0]; - end else if ( clk7_count == 6 ) begin - // if palette index is zero then it's from layer 3 and is transparent render as blank (black). - rgb <= { dac[tile_palette_dout[4:0]], dac[tile_palette_dout[9:5]], dac[tile_palette_dout[14:10]] }; - - // if not transparent and sprite is higher priority - if ( sprite_fb_out[3:0] > 0 && (sprite_fb_out[13:10] > tile_fb_out[13:10]) ) begin - // draw sprite - rgb <= { dac[sprite_palette_dout[4:0]], dac[sprite_palette_dout[9:5]], dac[sprite_palette_dout[14:10]] }; - end - end -end - -// tile data buffer - -reg tile_buf_w; -reg [31:0] tile_buf_din; -reg [31:0] tile_buf_dout; -reg [13:0] tile_buf_addr; - -dual_port_ram #(.LEN(16384), .DATA_WIDTH(32)) ram_tile_buf ( - .clock_a ( clk_sys ), - .address_a ( tile[13:0] ), - .wren_a ( tile_buf_w ), - .data_a ( tile_attr_dout ), - - .clock_b ( clk_sys ), - .address_b ( tile[13:0] ), // only read the tile # for now - .wren_b ( 0 ), - .q_b ( tile_buf_dout ) -); - -// tile attribute ram. each tile attribute is 2 16bit words -// pppp ---- --cc cccc httt tttt tttt tttt = Tile number (0 - $7fff) -// indirect access through offset register -dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_h ( - .clock_a ( clk_10M ), - .address_a ( curr_tile_ofs ), - .wren_a ( tile_attr_cs & !cpu_rw ), - .data_a ( cpu_dout ), - .q_a ( cpu_tile_dout_attr ), - - .clock_b ( clk_sys ), - .address_b ( tile[13:0] ), // only read the tile # for now - .wren_b ( 0 ), - .q_b ( tile_attr_dout[31:16] ) -); - -dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_l ( - .clock_a ( clk_10M ), - .address_a ( curr_tile_ofs ), - .wren_a ( tile_num_cs & !cpu_rw ), - .data_a ( cpu_dout ), - .q_a ( cpu_tile_dout_num ), - - .clock_b ( clk_sys ), - .address_b ( tile[13:0] ), // only read the tile # for now - .wren_b ( 0 ), - .q_b ( tile_attr_dout[15:0] ) -); - -// sprite attribute ram. each tile attribute is 4 16bit words -// indirect access through offset register -// split up so 64 bits can be read in a single clock -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_0 ( - .clock_a ( clk_10M ), - .address_a ( curr_sprite_ofs[9:2] ), - .wren_a ( sprite_0_cs & !cpu_rw), - .data_a ( cpu_dout ), - .q_a ( sprite_0_dout ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num_copy ), - .wren_b ( 0 ), - .q_b ( sprite_attr_0_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_0_buf ( - .clock_a ( clk_sys ), - .address_a ( sprite_buf_num ), - .wren_a ( sprite_buf_w ), - .data_a ( sprite_attr_0_dout[15:0] ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num ), - .wren_b ( 0 ), - .q_b ( sprite_attr_0_buf_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_1 ( - .clock_a ( clk_10M ), - .address_a ( curr_sprite_ofs[9:2] ), - .wren_a ( sprite_1_cs & !cpu_rw ), - .data_a ( cpu_dout ), - .q_a ( sprite_1_dout ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num_copy ), - .wren_b ( 0 ), - .q_b ( sprite_attr_1_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_1_buf ( - .clock_a ( clk_sys ), - .address_a ( sprite_buf_num ), - .wren_a ( sprite_buf_w ), - .data_a ( sprite_attr_1_dout[15:0] ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num ), - .wren_b ( 0 ), - .q_b ( sprite_attr_1_buf_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_2 ( - .clock_a ( clk_10M ), - .address_a ( curr_sprite_ofs[9:2] ), - .wren_a ( sprite_2_cs & !cpu_rw ), - .data_a ( cpu_dout ), - .q_a ( sprite_2_dout ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num_copy ), - .wren_b ( 0 ), - .q_b ( sprite_attr_2_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_2_buf ( - .clock_a ( clk_sys ), - .address_a ( sprite_buf_num ), - .wren_a ( sprite_buf_w ), - .data_a ( sprite_attr_2_dout[15:0] ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num ), - .wren_b ( 0 ), - .q_b ( sprite_attr_2_buf_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_3 ( - .clock_a ( clk_10M ), - .address_a ( curr_sprite_ofs[9:2] ), - .wren_a ( sprite_3_cs & !cpu_rw ), - .data_a ( cpu_dout ), - .q_a ( sprite_3_dout ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num_copy ), - .wren_b ( 0 ), - .q_b ( sprite_attr_3_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_3_buf ( - .clock_a ( clk_sys ), - .address_a ( sprite_buf_num ), - .wren_a ( sprite_buf_w ), - .data_a ( sprite_attr_3_dout[15:0] ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num ), - .wren_b ( 0 ), - .q_b ( sprite_attr_3_buf_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_size ( - .clock_a ( clk_10M ), - .address_a ( curr_sprite_ofs ), - .wren_a ( sprite_size_cs & !cpu_rw), - .data_a ( cpu_dout ), - .q_a ( sprite_size_cpu_dout ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num_copy ), - .wren_b ( 0 ), - .q_b ( sprite_size_dout ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_size_buf ( - .clock_a ( clk_sys ), - .address_a ( sprite_buf_num ), - .wren_a ( sprite_buf_w ), - .data_a ( sprite_size_dout ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_size_addr ), - .wren_b ( 0 ), - .q_b ( sprite_size_buf_dout ) -); - - -// tiles 1024 15 bit values. index is ( 6 bits from tile attribute, 4 bits from bitmap ) -// background palette ram low -// does this need to be byte addressable? -dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_l ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[10:1] ), - .wren_a ( tile_palette_cs & !cpu_rw & !cpu_lds_n), - .data_a ( cpu_dout[7:0] ), - .q_a ( tile_palette_cpu_dout[7:0] ), - - .clock_b ( clk_sys ), - .address_b ( tile_palette_addr ), - .wren_b ( 0 ), - .q_b ( tile_palette_dout[7:0] ) -); - -// background palette ram high -dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_h ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[10:1] ), - .wren_a ( tile_palette_cs & !cpu_rw & !cpu_uds_n), - .data_a ( cpu_dout[15:8] ), - .q_a ( tile_palette_cpu_dout[15:8] ), - - .clock_b ( clk_sys ), - .address_b ( tile_palette_addr ), - .wren_b ( 0 ), - .q_b ( tile_palette_dout[15:8] ) -); - -// sprite palette ram low -// does this need to be byte addressable? -dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_l ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[10:1] ), - .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_lds_n), - .data_a ( cpu_dout[7:0] ), - .q_a ( sprite_palette_cpu_dout[7:0] ), - - .clock_b ( clk_sys ), - .address_b ( sprite_palette_addr ), - .wren_b ( 0 ), - .q_b ( sprite_palette_dout[7:0] ) -); - -// background palette ram high -dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_h ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[10:1] ), - .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_uds_n), - .data_a ( cpu_dout[15:8] ), - .q_a ( sprite_palette_cpu_dout[15:8] ), - - .clock_b ( clk_sys ), - .address_b ( sprite_palette_addr ), - .wren_b ( 0 ), - .q_b ( sprite_palette_dout[15:8] ) -); - - -// main 68k ram low -dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_L ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[14:1] ), - .wren_a ( !cpu_rw & ram_cs & !cpu_lds_n ), - .data_a ( cpu_dout[7:0] ), - .q_a ( ram_dout[7:0] ) - ); - -// main 68k ram high -dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_H ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[14:1] ), - .wren_a ( !cpu_rw & ram_cs & !cpu_uds_n ), - .data_a ( cpu_dout[15:8] ), - .q_a ( ram_dout[15:8] ) -); - - -//wire [15:0] z80_shared_addr = z80_addr - 16'h8000; -//wire [23:0] m68k_shard_addr = cpu_a - 24'h040000; - -// z80 and 68k shared ram -// 4k -dual_port_ram #(.LEN(32768), .DATA_WIDTH(8)) shared_ram -( - .clock_a ( clk_10M ), - .address_a ( cpu_a[12:1] ), - .wren_a ( shared_ram_cs & !cpu_rw & !cpu_lds_n), - .data_a ( cpu_dout[7:0] ), - .q_a ( cpu_shared_dout[7:0] ), - - .clock_b ( clk_3_5M ), // z80 clock is 3.5M - .address_b ( z80_addr[14:0] ), - .data_b ( z80_dout ), - .wren_b ( sound_ram_1_cs & ~z80_wr_n ), - .q_b ( z80_shared_dout ) -); - -reg [11:0] sprite_rb_addr; -wire [15:0] sprite_rb_dout; - -dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) sprite_ram_rb_l ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[12:1] ), - .wren_a ( sprite_ram_cs & !cpu_rw & !cpu_lds_n), - .data_a ( cpu_dout[7:0] ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_rb_addr ), - .wren_b ( 0 ), - .q_b ( sprite_rb_dout[7:0] ) -); - -dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) sprite_ram_rb_h ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[12:1] ), - .wren_a ( sprite_ram_cs & !cpu_rw & !cpu_uds_n), - .data_a ( cpu_dout[15:8] ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_rb_addr ), - .wren_b ( 0 ), - .q_b ( sprite_rb_dout[15:8] ) -); - -reg [22:0] sdram_addr; -reg [31:0] sdram_data; -reg sdram_we; -reg sdram_req; - -wire sdram_ack; -wire sdram_valid; -wire [31:0] sdram_q; - -sdram #(.CLK_FREQ(70.0)) sdram -( - .reset(~pll_locked), - .clk(clk_sys), - - // controller interface - .addr(sdram_addr), - .data(sdram_data), - .we(sdram_we), - .req(sdram_req), - - .ack(sdram_ack), - .valid(sdram_valid), - .q(sdram_q), - - // SDRAM interface - .sdram_a(SDRAM_A), - .sdram_ba(SDRAM_BA), - .sdram_dq(SDRAM_DQ), - .sdram_cke(SDRAM_CKE), - .sdram_cs_n(SDRAM_nCS), - .sdram_ras_n(SDRAM_nRAS), - .sdram_cas_n(SDRAM_nCAS), - .sdram_we_n(SDRAM_nWE), - .sdram_dqml(SDRAM_DQML), - .sdram_dqmh(SDRAM_DQMH) -); - -wire prog_cache_rom_cs; -wire [22:0] prog_cache_addr; -wire [15:0] prog_cache_data; -wire prog_cache_valid; - -wire [15:0] prog_rom_data; -wire prog_rom_data_valid; - -reg tile_rom_cs; -reg [17:0] tile_rom_addr; -wire [31:0] tile_rom_data; -wire tile_rom_data_valid; - -wire tile_cache_cs; -wire [17:0] tile_cache_addr; -wire [31:0] tile_cache_data; -wire tile_cache_valid; - -reg [31:0] tile_data; - -wire sprite_rom_cs; -wire [18:0] sprite_rom_addr; -wire [31:0] sprite_rom_data; -wire sprite_rom_data_valid; - -reg [31:0] sprite_data; - -wire [15:0] sound_rom_1_addr; -wire [7:0] sound_rom_1_data; -wire sound_rom_1_data_valid; - -// sdram priority based rom controller -// is a oe needed? -rom_controller rom_controller -( - .reset(reset), - - // clock - .clk(clk_sys), - - // program ROM interface - .prog_rom_cs(prog_cache_rom_cs), - .prog_rom_oe(1), - .prog_rom_addr(prog_cache_addr), - .prog_rom_data(prog_cache_data), - .prog_rom_data_valid(prog_cache_valid), - - // character ROM interface - .tile_rom_cs(tile_cache_cs), - .tile_rom_oe(1), - .tile_rom_addr(tile_cache_addr), - .tile_rom_data(tile_cache_data), - .tile_rom_data_valid(tile_cache_valid), - - - // sprite ROM interface - .sprite_rom_cs(sprite_rom_cs), - .sprite_rom_oe(1), - .sprite_rom_addr(sprite_rom_addr), - .sprite_rom_data(sprite_rom_data), - .sprite_rom_data_valid(sprite_rom_data_valid), - - // sound ROM #1 interface - .sound_rom_1_cs(sound_rom_1_cs), - .sound_rom_1_oe(1), - .sound_rom_1_addr(z80_addr), - .sound_rom_1_data(sound_rom_1_data), - .sound_rom_1_data_valid(sound_rom_1_data_valid), - - // IOCTL interface - .ioctl_addr(ioctl_addr), - .ioctl_data(ioctl_dout), - .ioctl_index(ioctl_index), - .ioctl_wr(ioctl_wr), - .ioctl_download(ioctl_download), - - // SDRAM interface - .sdram_addr(sdram_addr), - .sdram_data(sdram_data), - .sdram_we(sdram_we), - .sdram_req(sdram_req), - .sdram_ack(sdram_ack), - .sdram_valid(sdram_valid), - .sdram_q(sdram_q) -); - - -cache prog_cache -( - .reset(reset), - .clk(clk_sys), - - // client - .cache_req(prog_rom_cs), - .cache_addr(cpu_a[23:1]), - .cache_valid(prog_rom_data_valid), - .cache_data(prog_rom_data), - - // to rom controller - .rom_req(prog_cache_rom_cs), - .rom_addr(prog_cache_addr), - .rom_valid(prog_cache_valid), - .rom_data(prog_cache_data) -); - -tile_cache tile_cache -( - .reset(reset), - .clk(clk_sys), - - // client - .cache_req(tile_rom_cs), - .cache_addr(tile_rom_addr), - .cache_data(tile_rom_data), - .cache_valid(tile_rom_data_valid), - - // to rom controller - .rom_req(tile_cache_cs), - .rom_addr(tile_cache_addr), - .rom_data(tile_cache_data), - .rom_valid(tile_cache_valid) +mist_video #(.COLOR_DEPTH(5),.SD_HCNT_WIDTH(10)) mist_video( + .clk_sys(clk_72), + .SPI_SCK(SPI_SCK), + .SPI_SS3(SPI_SS3), + .SPI_DI(SPI_DI), + .R(blankn ? r : 5'd0), + .G(blankn ? g : 5'd0), + .B(blankn ? b : 5'd0), + .HSync(~hs), + .VSync(~vs), + .VGA_R(VGA_R), + .VGA_G(VGA_G), + .VGA_B(VGA_B), + .VGA_VS(VGA_VS), + .VGA_HS(VGA_HS), + .no_csync(no_csync), + .rotate({~flipped,rotate}), + .ce_divider(3'd5), // pix clock = 72/6 + .blend(blend), + .scandoubler_disable(scandoublerD), + .scanlines(scanlines), + .ypbpr(ypbpr) + ); + +dac #(16) dacl( + .clk_i(clk_72), + .res_n_i(1), + .dac_i({~laudio[15], laudio[14:0]}), + .dac_o(AUDIO_L) + ); + +dac #(16) dacr( + .clk_i(clk_72), + .res_n_i(1), + .dac_i({~raudio[15], raudio[14:0]}), + .dac_o(AUDIO_R) + ); + +// Common inputs +wire m_up1, m_down1, m_left1, m_right1, m_up1B, m_down1B, m_left1B, m_right1B; +wire m_up2, m_down2, m_left2, m_right2, m_up2B, m_down2B, m_left2B, m_right2B; +wire m_up3, m_down3, m_left3, m_right3, m_up3B, m_down3B, m_left3B, m_right3B; +wire m_up4, m_down4, m_left4, m_right4, m_up4B, m_down4B, m_left4B, m_right4B; +wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players; +wire [11:0] m_fire1, m_fire2, m_fire3, m_fire4; + +arcade_inputs inputs ( + .clk ( clk_72 ), + .key_strobe ( key_strobe ), + .key_pressed ( key_pressed ), + .key_code ( key_code ), + .joystick_0 ( joystick_0 ), + .joystick_1 ( joystick_1 ), + .rotate ( rotate ), + .orientation ( {~flipped, 1'b0} ), + .joyswap ( joyswap ), + .oneplayer ( 1'b0 ), + .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ), + .player1 ( {m_up1B, m_down1B, m_left1B, m_right1B, m_fire1, m_up1, m_down1, m_left1, m_right1} ), + .player2 ( {m_up2B, m_down2B, m_left2B, m_right2B, m_fire2, m_up2, m_down2, m_left2, m_right2} ), + .player3 ( {m_up3B, m_down3B, m_left3B, m_right3B, m_fire3, m_up3, m_down3, m_left3, m_right3} ), + .player4 ( {m_up4B, m_down4B, m_left4B, m_right4B, m_fire4, m_up4, m_down4, m_left4, m_right4} ) ); endmodule - - -module cc_shifter -( - input clk_out, - input i, - output o -); - -// We use a two-stages shift-register to synchronize SignalIn_clkA to the clkB clock domain -reg [1:0] r; - -assign o = r[1]; // new signal synchronized to (=ready to be used in) clkB domain - -always @(posedge clk_out) begin - r[0] <= i; - r[1] <= r[0]; // notice that we use clkB -end - -endmodule - - diff --git a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_vimana/vimanas.sv b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_vimana/vimanas.sv new file mode 100644 index 00000000..6d435793 --- /dev/null +++ b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_vimana/vimanas.sv @@ -0,0 +1,2089 @@ +//============================================================================ +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +//============================================================================ + +`default_nettype none + +module emu +( + //Master input clock + input CLK_50M, + + //Async reset from top-level module. + //Can be used as initial reset. + input RESET, + + //Must be passed to hps_io module + inout [48:0] HPS_BUS, + + //Base video clock. Usually equals to CLK_SYS. + output CLK_VIDEO, + + //Multiple resolutions are supported using different CE_PIXEL rates. + //Must be based on CLK_VIDEO + output CE_PIXEL, + + //Video aspect ratio for HDMI. Most retro systems have ratio 4:3. + //if VIDEO_ARX[12] or VIDEO_ARY[12] is set then [11:0] contains scaled size instead of aspect ratio. + output [12:0] VIDEO_ARX, + output [12:0] VIDEO_ARY, + + output [7:0] VGA_R, + output [7:0] VGA_G, + output [7:0] VGA_B, + output VGA_HS, + output VGA_VS, + output VGA_DE, // = ~(VBlank | HBlank) + output VGA_F1, + output [2:0] VGA_SL, + output VGA_SCALER, // Force VGA scaler + + input [11:0] HDMI_WIDTH, + input [11:0] HDMI_HEIGHT, + output HDMI_FREEZE, + +`ifdef MISTER_FB + // Use framebuffer in DDRAM (USE_FB=1 in qsf) + // FB_FORMAT: + // [2:0] : 011=8bpp(palette) 100=16bpp 101=24bpp 110=32bpp + // [3] : 0=16bits 565 1=16bits 1555 + // [4] : 0=RGB 1=BGR (for 16/24/32 modes) + // + // FB_STRIDE either 0 (rounded to 256 bytes) or multiple of pixel size (in bytes) + output FB_EN, + output [4:0] FB_FORMAT, + output [11:0] FB_WIDTH, + output [11:0] FB_HEIGHT, + output [31:0] FB_BASE, + output [13:0] FB_STRIDE, + input FB_VBL, + input FB_LL, + output FB_FORCE_BLANK, + +`ifdef MISTER_FB_PALETTE + // Palette control for 8bit modes. + // Ignored for other video modes. + output FB_PAL_CLK, + output [7:0] FB_PAL_ADDR, + output [23:0] FB_PAL_DOUT, + input [23:0] FB_PAL_DIN, + output FB_PAL_WR, +`endif +`endif + + output LED_USER, // 1 - ON, 0 - OFF. + + // b[1]: 0 - LED status is system status OR'd with b[0] + // 1 - LED status is controled solely by b[0] + // hint: supply 2'b00 to let the system control the LED. + output [1:0] LED_POWER, + output [1:0] LED_DISK, + + // I/O board button press simulation (active high) + // b[1]: user button + // b[0]: osd button + output [1:0] BUTTONS, + + //Audio + input CLK_AUDIO, // 24.576 MHz + output [15:0] AUDIO_L, + output [15:0] AUDIO_R, + output AUDIO_S, // 1 - signed audio samples, 0 - unsigned + output [1:0] AUDIO_MIX, // 0 - no mix, 1 - 25%, 2 - 50%, 3 - 100% (mono) + + //ADC + inout [3:0] ADC_BUS, + + //SD-SPI + output SD_SCK, + output SD_MOSI, + input SD_MISO, + output SD_CS, + input SD_CD, + + //High latency DDR3 RAM interface + //Use for non-critical time purposes + output DDRAM_CLK, + input DDRAM_BUSY, + output [7:0] DDRAM_BURSTCNT, + output [28:0] DDRAM_ADDR, + input [63:0] DDRAM_DOUT, + input DDRAM_DOUT_READY, + output DDRAM_RD, + output [63:0] DDRAM_DIN, + output [7:0] DDRAM_BE, + output DDRAM_WE, + + //SDRAM interface with lower latency + output SDRAM_CLK, + output SDRAM_CKE, + output [12:0] SDRAM_A, + output [1:0] SDRAM_BA, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nCS, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nWE, + +`ifdef MISTER_DUAL_SDRAM + //Secondary SDRAM + //Set all output SDRAM_* signals to Z ASAP if SDRAM2_EN is 0 + input SDRAM2_EN, + output SDRAM2_CLK, + output [12:0] SDRAM2_A, + output [1:0] SDRAM2_BA, + inout [15:0] SDRAM2_DQ, + output SDRAM2_nCS, + output SDRAM2_nCAS, + output SDRAM2_nRAS, + output SDRAM2_nWE, +`endif + + input UART_CTS, + output UART_RTS, + input UART_RXD, + output UART_TXD, + output UART_DTR, + input UART_DSR, + +`ifdef MISTER_ENABLE_YC + output [39:0] CHROMA_PHASE_INC, + output YC_EN, + output PALFLAG, +`endif + + // Open-drain User port. + // 0 - D+/RX + // 1 - D-/TX + // 2..6 - USR2..USR6 + // Set USER_OUT to 1 to read from USER_IN. + input [6:0] USER_IN, + output [6:0] USER_OUT, + + input OSD_STATUS +); + +///////// Default values for ports not used in this core ///////// + +assign ADC_BUS = 'Z; +assign USER_OUT = 0; +assign {UART_RTS, UART_TXD, UART_DTR} = 0; +assign {SD_SCK, SD_MOSI, SD_CS} = 'Z; +//assign {SDRAM_DQ, SDRAM_A, SDRAM_BA, SDRAM_CLK, SDRAM_CKE, SDRAM_DQML, SDRAM_DQMH, SDRAM_nWE, SDRAM_nCAS, SDRAM_nRAS, SDRAM_nCS} = 'Z; +//assign {DDRAM_CLK, DDRAM_BURSTCNT, DDRAM_ADDR, DDRAM_DIN, DDRAM_BE, DDRAM_RD, DDRAM_WE} = '0; +assign VGA_F1 = 0; +assign VGA_SCALER = 0; +assign HDMI_FREEZE = 0; + +assign AUDIO_MIX = 0; +assign LED_USER = ioctl_download & cpu_a[0]; +assign LED_DISK = 0; +assign LED_POWER = 0; +assign BUTTONS = 0; + +// Status Bit Map: +// Upper Case Lower Case +// 0 1 2 3 4 5 6 +// 01234567890123456789012345678901 23456789012345678901234567890123 +// 0123456789ABCDEFGHIJKLMNOPQRSTUV 0123456789ABCDEFGHIJKLMNOPQRSTUV +// X XXXXXXXX XX X X XXXXXXXX X XX XXXXXXXX + +wire [1:0] aspect_ratio = status[9:8]; +wire orientation = ~status[3]; +wire [2:0] scan_lines = status[6:4]; +reg refresh_mod; +reg new_vmode; + +always @(posedge clk_sys) begin + if (refresh_mod != status[19]) begin + refresh_mod <= status[19]; + new_vmode <= ~new_vmode; + end +end + +wire [3:0] hs_offset = status[27:24]; +wire [3:0] vs_offset = status[31:28]; +wire [3:0] hs_width = status[59:56]; +wire [3:0] vs_width = status[63:60]; + +assign VIDEO_ARX = (!aspect_ratio) ? (orientation ? 8'd4 : 8'd3) : (aspect_ratio - 1'd1); +assign VIDEO_ARY = (!aspect_ratio) ? (orientation ? 8'd3 : 8'd4) : 12'd0; + +`include "build_id.v" +localparam CONF_STR = { + "Toaplan V1;;", + "-;", + "P1,Video Settings;", + "P1-;", + "P1O89,Aspect Ratio,Original,Full Screen,[ARC1],[ARC2];", + "P1O3,Orientation,Horz,Vert;", + "P1-;", + "P1O46,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%,CRT 75%,CRT 100%;", + "P1OA,Force Scandoubler,Off,On;", + "P1-;", + "P1O7,Video Mode,NTSC,PAL;", + "P1OM,Video Signal,RGBS/YPbPr,Y/C;", + "P1OJ,Refresh Rate,Native,NTSC;", + "P1-;", + "P1OOR,H-sync Pos Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", + "P1OSV,V-sync Pos Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", + "P1-;", + "P1oOR,H-sync Width Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", + "P1oSV,V-sync Width Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", + "P1-;", + "P2,Audio Settings;", + "P2-;", + "P2oBC,OPL2 Volume,Default,50%,25%,0%;", + "P2-;", + "-;", + "P3,Core Options;", + "P3-;", + "P3o6,Swap P1/P2 Joystick,Off,On;", + "P3-;", + "P3OF,68k Freq.,10Mhz,17.5MHz;", + "P3-;", + "P3o0,Scroll Debug,Off,On;", + "P3-;", + "DIP;", + "-;", + "OK,Pause OSD,Off,When Open;", + "OL,Dim Video,Off,10s;", + "-;", + "R0,Reset;", + "V,v",`BUILD_DATE +}; + +wire hps_forced_scandoubler; +wire forced_scandoubler = hps_forced_scandoubler | status[10]; + +wire [1:0] buttons; +wire [63:0] status; +wire [10:0] ps2_key; +wire [15:0] joy0, joy1; + +hps_io #(.CONF_STR(CONF_STR)) hps_io +( + .clk_sys(clk_sys), + .HPS_BUS(HPS_BUS), + + .buttons(buttons), + .ps2_key(ps2_key), + .status(status), + .status_menumask(direct_video), + .forced_scandoubler(hps_forced_scandoubler), + .gamma_bus(gamma_bus), + .new_vmode(new_vmode), + .direct_video(direct_video), + .video_rotated(video_rotated), + + .ioctl_download(ioctl_download), + .ioctl_upload(ioctl_upload), + .ioctl_wr(ioctl_wr), + .ioctl_addr(ioctl_addr), + .ioctl_dout(ioctl_dout), + .ioctl_din(ioctl_din), + .ioctl_index(ioctl_index), + .ioctl_wait(ioctl_wait), + + .joystick_0(joy0), + .joystick_1(joy1) +); + +// INPUT + +// 8 dip switches of 8 bits +reg [7:0] sw[8]; +always @(posedge clk_sys) begin + if (ioctl_wr && (ioctl_index==254) && !ioctl_addr[24:3]) begin + sw[ioctl_addr[2:0]] <= ioctl_dout; + end +end + +always @(posedge clk_sys) begin + if (ioctl_wr && ioctl_index==1) begin + pcb <= ioctl_dout; + end +end + +wire direct_video; + +wire ioctl_download; +wire ioctl_upload; +wire ioctl_upload_req; +wire ioctl_wait; +wire ioctl_wr; +wire [15:0] ioctl_index; +wire [26:0] ioctl_addr; +wire [15:0] ioctl_dout; +wire [15:0] ioctl_din; + +reg [1:0] pcb; +wire tile_priority_type; +wire [15:0] scroll_y_offset; + +localparam pcb_vimana = 0; +localparam pcb_samesame = 1; + +wire [21:0] gamma_bus; + +// +// Inputs tied to z80_din +reg [7:0] p1; +reg [7:0] p2; +reg [7:0] z80_dswa; +reg [7:0] z80_dswb; +reg [7:0] z80_tjump; +reg [7:0] system; + +always @ (posedge clk_sys ) begin + p1 <= { 1'b0, p1_buttons[2:0], p1_right, p1_left, p1_down, p1_up }; + p2 <= { 1'b0, p2_buttons[2:0], p2_right, p2_left, p2_down, p2_up }; + z80_dswa <= sw[0]; + z80_tjump <= sw[2]; + + if ( status[32] == 1 ) begin + z80_dswb <= { sw[1][7], sw[1][6] | status[32], sw[1][5:0] }; + system <= { vbl, start2 | p1_buttons[3], start1 | p1_buttons[3], coin_b, coin_a, service, key_tilt, key_service }; + end else begin + z80_dswb <= sw[1]; + system <= { vbl, start2, start1, coin_b, coin_a, service, key_tilt, key_service }; + end +end + +reg p1_swap; + +reg p1_right; +reg p1_left; +reg p1_down; +reg p1_up; +reg [3:0] p1_buttons; + +reg p2_right; +reg p2_left; +reg p2_down; +reg p2_up; +reg [3:0] p2_buttons; + +reg start1; +reg start2; +reg coin_a; +reg coin_b; +reg b_pause; +reg service; +reg [7:0] credits; + +always @ * begin + p1_swap <= status[38]; + + if ( status[38] == 0 ) begin + p1_right <= joy0[0] | key_p1_right; + p1_left <= joy0[1] | key_p1_left; + p1_down <= joy0[2] | key_p1_down; + p1_up <= joy0[3] | key_p1_up; + p1_buttons <= joy0[7:4] | {key_p1_c, key_p1_b, key_p1_a}; + + p2_right <= joy1[0] | key_p2_right; + p2_left <= joy1[1] | key_p2_left; + p2_down <= joy1[2] | key_p2_down; + p2_up <= joy1[3] | key_p2_up; + p2_buttons <= joy1[7:4] | {key_p2_c, key_p2_b, key_p2_a}; + end else begin + p2_right <= joy0[0] | key_p1_right; + p2_left <= joy0[1] | key_p1_left; + p2_down <= joy0[2] | key_p1_down; + p2_up <= joy0[3] | key_p1_up; + p2_buttons <= joy0[7:4] | {key_p1_c, key_p1_b, key_p1_a}; + + p1_right <= joy1[0] | key_p2_right; + p1_left <= joy1[1] | key_p2_left; + p1_down <= joy1[2] | key_p2_down; + p1_up <= joy1[3] | key_p2_up; + p1_buttons <= joy1[7:4] | {key_p2_c, key_p2_b, key_p2_a}; + end +end + +always @ * begin + start1 <= joy0[8] | joy1[8] | key_start_1p; + start2 <= joy0[9] | joy1[9] | key_start_2p; + + coin_a <= joy0[10] | joy1[10] | key_coin_a; + coin_b <= joy0[11] | joy1[11] | key_coin_b; + + b_pause <= joy0[12] | key_pause; + service <= key_test; +end + +// Keyboard handler + +reg key_start_1p, key_start_2p, key_coin_a, key_coin_b; +reg key_tilt, key_test, key_reset, key_service, key_pause; + +reg key_p1_up, key_p1_left, key_p1_down, key_p1_right, key_p1_a, key_p1_b, key_p1_c; +reg key_p2_up, key_p2_left, key_p2_down, key_p2_right, key_p2_a, key_p2_b, key_p2_c; + +wire pressed = ps2_key[9]; + +always @(posedge clk_sys) begin + reg old_state; + old_state <= ps2_key[10]; + if ( old_state ^ ps2_key[10] ) begin + casex ( ps2_key[8:0] ) + 'h016 : key_start_1p <= pressed; // 1 + 'h01E : key_start_2p <= pressed; // 2 + 'h02E : key_coin_a <= pressed; // 5 + 'h036 : key_coin_b <= pressed; // 6 + 'h006 : key_test <= key_test ^ pressed; // f2 + 'h004 : key_reset <= pressed; // f3 + 'h046 : key_service <= pressed; // 9 + 'h02C : key_tilt <= pressed; // t + 'h04D : key_pause <= pressed; // p + + 'h175 : key_p1_up <= pressed; // up + 'h172 : key_p1_down <= pressed; // down + 'h16B : key_p1_left <= pressed; // left + 'h174 : key_p1_right <= pressed; // right + 'h014 : key_p1_a <= pressed; // lctrl + 'h011 : key_p1_b <= pressed; // lalt + 'h029 : key_p1_c <= pressed; // spacebar + + 'h02D : key_p2_up <= pressed; // r + 'h02B : key_p2_down <= pressed; // f + 'h023 : key_p2_left <= pressed; // d + 'h034 : key_p2_right <= pressed; // g + 'h01C : key_p2_a <= pressed; // a + 'h01B : key_p2_b <= pressed; // s + 'h015 : key_p2_c <= pressed; // q + endcase + end +end + +wire pll_locked; + +wire clk_sys; +wire turbo_68k = status[15]; +reg clk_3_5M, clk_7M, clk_10M, clk_14M; + +wire clk_70M; + +pll pll +( + .refclk(CLK_50M), + .rst(0), + .outclk_0(clk_sys), + .outclk_1(clk_70M), + .locked(pll_locked) +); + +assign SDRAM_CLK = clk_70M; + +localparam CLKSYS=70; + +reg [5:0] clk14_count; +reg [5:0] clk10_count; +reg [5:0] clk7_count; +reg [5:0] clk_3_5_count; + +always @ (posedge clk_sys ) begin + clk_10M <= 0; + if ( turbo_68k == 0 ) begin + // standard speed 20MHz = 10MHz 68k + case (clk10_count) + 1: clk_10M <= 1; + 3: clk_10M <= 1; + endcase + if ( clk10_count == 6 ) begin + clk10_count <= 0; + end else if ( pause_cpu == 0 ) begin + clk10_count <= clk10_count + 1; + end + end else begin + // standard speed 35MHz = 17.5MHz 68k + case (clk10_count) + 1: clk_10M <= 1; + endcase + if ( clk10_count == 1 ) begin + clk10_count <= 0; + end else if ( pause_cpu == 0 ) begin + clk10_count <= clk10_count + 1; + end + end + clk_7M <= ( clk7_count == 0); + if ( clk7_count == 9 ) begin + clk7_count <= 0; + end else begin + clk7_count <= clk7_count + 1; + end + clk_14M <= ( clk14_count == 0); + if ( clk14_count == 4 ) begin + clk14_count <= 0; + end else begin + clk14_count <= clk14_count + 1; + end + clk_3_5M <= ( clk_3_5_count == 0); + if ( clk_3_5_count == 19 ) begin + clk_3_5_count <= 0; + end else if ( pause_cpu == 0 ) begin + clk_3_5_count <= clk_3_5_count + 1; + end +end + +wire reset; +assign reset = RESET | status[0] | (ioctl_download & !ioctl_index) | buttons[1] | key_reset; + +////////////////////////////////////////////////////////////////// +wire rotate_ccw = 1; +wire no_rotate = orientation | direct_video; +wire video_rotated; + +reg [23:0] rgb; + +wire hbl; +wire vbl; + +wire [8:0] hc; +wire [8:0] vc; + +wire hsync; +wire vsync; + +reg hbl_delay, vbl_delay; + +always @ ( posedge clk_7M ) begin + hbl_delay <= hbl; + vbl_delay <= vbl; +end + +video_timing video_timing ( + .clk(clk_7M), + .reset(reset), + .crtc0(crtc[0]), + .crtc1(crtc[1]), + .crtc2(crtc[2]), + .crtc3(crtc[3]), + .hs_offset(hs_offset), + .vs_offset(vs_offset), + .hs_width(hs_width), + .vs_width(vs_width), + .refresh_mod(refresh_mod), + .hc(hc), + .vc(vc), + .hbl_delay(hbl), + .vbl(vbl), + .hsync(hsync), + .vsync(vsync) +); + +// PAUSE SYSTEM +wire pause_cpu; +wire hs_pause; + +// 8 bits per colour, 70MHz sys clk +pause #(8,8,8,70) pause +( + .clk_sys(clk_sys), + .reset(reset), + .user_button(b_pause), + .pause_request(hs_pause), + .options(status[21:20]), + .pause_cpu(pause_cpu), + .dim_video(dim_video), + .OSD_STATUS(OSD_STATUS), + .r(rgb[23:16]), + .g(rgb[15:8]), + .b(rgb[7:0]), + .rgb_out(rgb_pause_out) +); + +wire [23:0] rgb_pause_out; +wire dim_video; + +arcade_video #(320,24) arcade_video +( + .*, + + .clk_video(clk_sys), + .ce_pix(clk_7M), + + .RGB_in(rgb_pause_out), + + .HBlank(hbl), + .VBlank(vbl), + .HSync(hsync), + .VSync(vsync), + + .fx(scan_lines) +); + +/* + Phase Accumulator Increments (Fractional Size 32, look up size 8 bit, total 40 bits) + Increment Calculation - (Output Clock * 2 ^ Word Size) / Reference Clock + Example + NTSC = 3.579545 + PAL = 4.43361875 + W = 40 ( 32 bit fraction, 8 bit look up reference) + Ref CLK = 42.954544 (This could us any clock) + NTSC_Inc = 3.579545333 * 2 ^ 40 / 96 = 40997413706 +*/ + +// SET PAL and NTSC TIMING +`ifdef MISTER_ENABLE_YC + assign CHROMA_PHASE_INC = PALFLAG ? 40'd56225080500: 40'd56225080500; + assign YC_EN = status[22]; + assign PALFLAG = status[7]; +`endif + +screen_rotate screen_rotate (.*); + +wire [9:0] sprite_adj_x = 0; +wire [9:0] sprite_adj_y = 0; +wire bcu_flip_cs; +wire fcu_flip_cs; + +reg [1:0] adj_layer; +reg [15:0] scroll_adj_x [3:0]; +reg [15:0] scroll_adj_y [3:0]; +reg layer_en [3:0]; + +reg ce_pix; + +// flip is done in the rendering so leave screen_rotate flip off +wire flip = 0; + +reg tile_flip; +reg sprite_flip; + +//assign vc = vcx - vs_offset; + +// =============================================================== +// 68000 CPU +// =============================================================== + +// clock generation +reg fx68_phi1 = 0; +wire fx68_phi2 = !fx68_phi1; + +// phases for 68k clock +always @(posedge clk_sys) begin + if ( clk_10M == 1 ) begin + fx68_phi1 <= ~fx68_phi1; + end +end + +// CPU outputs +wire cpu_rw; // Read = 1, Write = 0 +wire cpu_as_n; // Address strobe +wire cpu_lds_n; // Lower byte strobe +wire cpu_uds_n; // Upper byte strobe +wire cpu_E; +wire [2:0]cpu_fc; // Processor state +wire cpu_reset_n_o; // Reset output signal +wire cpu_halted_n; // Halt output + +// CPU busses +wire [15:0] cpu_dout; +wire [23:0] cpu_a /* synthesis keep */; +reg [15:0] cpu_din; + +// CPU inputs +reg dtack_n; // Data transfer ack (always ready) + +reg ipl1_n; +reg ipl2_n; + +wire reset_n; +wire vpa_n = ~ ( cpu_lds_n == 0 && cpu_fc == 3'b111 ); // from outzone schematic + +assign cpu_a[0] = reset; // debug hack odd memory address should cause cpu exception + +cc_shifter cc_reset ( + .clk_out(clk_10M), + .i(reset_z80_n), + .o(reset_n) +); + +fx68k fx68k ( + // input + .clk( clk_10M ), + .enPhi1(fx68_phi1), + .enPhi2(fx68_phi2), + .extReset(reset), + .pwrUp(reset), + + // output + .eRWn(cpu_rw), + .ASn( cpu_as_n), + .LDSn(cpu_lds_n), + .UDSn(cpu_uds_n), +// .E(cpu_E), +// .VMAn(), + .FC0(cpu_fc[0]), + .FC1(cpu_fc[1]), + .FC2(cpu_fc[2]), +// .BGn(), + .oRESETn(cpu_reset_n_o), + .oHALTEDn(cpu_halted_n), + + // input + .VPAn( vpa_n ), + .DTACKn(dtack_n ), + .BERRn(1'b1), + .BRn(1'b1), + .BGACKn(1'b1), + + .IPL0n(1'b1), + .IPL1n(ipl1_n), + .IPL2n(ipl2_n), + + // busses + .iEdb(cpu_din), + .oEdb(cpu_dout), + .eab(cpu_a[23:1]) +); + + + +always @ (posedge clk_sys) begin +end + +wire [15:0] cpu_shared_dout; +wire [7:0] z80_shared_dout; +reg [15:0] z80_a; + +wire [15:0] z80_addr; +reg [7:0] z80_din; +wire [7:0] z80_dout; + +wire z80_wr_n; +wire z80_rd_n; +reg z80_wait_n; + +wire IORQ_n; +wire MREQ_n; + +always @ (posedge clk_sys) begin + if ( reset == 1 ) begin + z80_wait_n <= 0; + sound_wr <= 0; + int_en <= 1; + reset_z80_n <= 1; + + end else begin + reset_z80_n <= cpu_reset_n_o; + + // write lasts multiple cpu clocks so limit to one increment per write signal + if ( inc_sprite_ofs == 1 && cpu_rw == 1 ) begin + curr_sprite_ofs <= curr_sprite_ofs + 1; + inc_sprite_ofs <= 0; + end + + if ( clk_10M == 1 ) begin + // tell 68k to wait for valid data. 0=ready 1=wait + // always ack when it's not program rom + dtack_n <= prog_rom_cs ? !prog_rom_data_valid : 0; + // add dsp_ctrl_cs to cpu_din + // select cpu data input based on what is active + if ( pcb == 0 ) begin + cpu_din <= prog_rom_cs ? prog_rom_data : + ram_cs ? ram_dout : + tile_palette_cs ? tile_palette_cpu_dout : + sprite_palette_cs ? sprite_palette_cpu_dout : + tile_ofs_cs ? curr_tile_ofs : + sprite_ofs_cs ? curr_sprite_ofs : + tile_attr_cs ? cpu_tile_dout_attr : + tile_num_cs ? cpu_tile_dout_num : + sprite_0_cs ? sprite_0_dout : + sprite_1_cs ? sprite_1_dout : + sprite_2_cs ? sprite_2_dout : + sprite_3_cs ? sprite_3_dout : + sprite_size_cs ? sprite_size_cpu_dout : + frame_done_cs ? { 16 { vbl } } : // get vblank state + shared_ram_cs ? cpu_shared_dout : + vblank_cs ? { 15'b0, vbl } : + int_en_cs ? 16'hffff : + 16'd0; + + end else begin + // same same same + cpu_din <= prog_rom_cs ? prog_rom_data : + ram_cs ? ram_dout : + tile_palette_cs ? tile_palette_cpu_dout : + sprite_palette_cs ? sprite_palette_cpu_dout : + tile_ofs_cs ? curr_tile_ofs : + sprite_ofs_cs ? curr_sprite_ofs : + tile_attr_cs ? cpu_tile_dout_attr : + tile_num_cs ? cpu_tile_dout_num : + sprite_0_cs ? sprite_0_dout : + sprite_1_cs ? sprite_1_dout : + sprite_2_cs ? sprite_2_dout : + sprite_3_cs ? sprite_3_dout : + sprite_size_cs ? sprite_size_cpu_dout : + p1_cs ? { 8'h00, p1[7:0] }: + p2_cs ? { 8'h00, p2[7:0] } : + dswa_cs ? { 8'h00, z80_dswa[7:0] } : + dswb_cs ? { 8'h00, z80_dswb[7:0] } : + system_cs ? { 8'h00, system[7:0] } : + tjump_cs ? { 8'h00, 1'b1, z80_tjump[6:0] } : + frame_done_cs ? { 15'b0, vbl } : // get vblank state + vblank_cs ? { 15'b0, vbl } : + int_en_cs ? 16'hffff : + 16'd0; + end + + if ( cpu_rw == 0 ) begin + if ( tile_ofs_cs ) begin + curr_tile_ofs <= cpu_dout; + end + if ( int_en_cs ) begin + int_en <= cpu_dout[0]; + end + if ( crtc_cs ) begin + crtc[ cpu_a[2:1] ] <= cpu_dout; + end + if ( bcu_flip_cs ) begin + tile_flip <= cpu_dout[0]; + end + if ( fcu_flip_cs ) begin + sprite_flip <= cpu_dout[15]; + end + if ( sprite_ofs_cs ) begin + // mask out valid range + curr_sprite_ofs <= { 6'b0, cpu_dout[9:0] }; + end + if ( scroll_ofs_x_cs ) begin + scroll_ofs_x <= cpu_dout; + end + if ( scroll_ofs_y_cs ) begin + scroll_ofs_y <= cpu_dout; + end + // x layer values are even addresses + if ( scroll_cs ) begin + if ( cpu_a[1] == 0 ) begin + scroll_x[ cpu_a[3:2] ] <= cpu_dout[15:7]; + end else begin + scroll_y[ cpu_a[3:2] ] <= cpu_dout[15:7]; + end + end + // offset needs to be auto-incremented + if ( sprite_cs | sprite_size_cs ) begin + inc_sprite_ofs <= 1; + end + if ( reset_z80_cs ) begin + // the pcb writes to a latch to control the reset + reset_z80_n <= cpu_dout[0]; + end + + if ( sound_latch_w_cs ) begin + sound_latch <= cpu_dout[7:0]; + sound_latch_set <= 1; + end + end + end + + if ( clk_3_5M == 1 ) begin + z80_wait_n <= 1; + if ( ioctl_download | ( z80_rd_n == 0 && sound_rom_1_data_valid == 0 && sound_rom_1_cs == 1 ) ) begin + // wait if rom is selected and data is not yet available + z80_wait_n <= 0; + end + + if ( z80_rd_n == 0 ) begin + if ( sound_rom_1_cs ) begin + if ( sound_rom_1_data_valid ) begin + z80_din <= sound_rom_1_data; + end else begin + z80_wait_n <= 0; + end + end else if ( sound_ram_1_cs ) begin + z80_din <= z80_shared_dout; + end else if ( sound0_cs ) begin + z80_din <= opl_dout; + end else if ( sound_latch_r_cs ) begin + z80_din <= sound_latch ; + end else if ( sound_status_cs ) begin + z80_din <= sound_latch_set ? 8'hff : 8'h00 ; + end else begin + z80_din <= 8'h00; + end + + if ( pcb == 0 ) begin + if ( p1_cs ) begin + z80_din <= p1 ; + end else if ( p2_cs ) begin + z80_din <= p2 ; + end else if ( dswa_cs ) begin + z80_din <= z80_dswa ; + end else if ( dswb_cs ) begin + z80_din <= ~z80_dswb ; + end else if ( tjump_cs ) begin + z80_din <= 8'hc0 | ~z80_tjump ; + end else if ( system_cs ) begin + z80_din <= system ; + end + end + end + sound_wr <= 0; + if ( z80_wr_n == 0 ) begin + if ( sound0_cs | sound1_cs ) begin + sound_data <= z80_dout; + sound_addr <= { 1'b0, sound1_cs }; + sound_wr <= 1; + end else if ( sound_done_cs ) begin + sound_latch <= z80_dout ; + sound_latch_set <= 0; + end + end + end + end +end + +reg [1:0] sound_addr; +reg [7:0] sound_data; +reg sound_wr; + +wire [7:0] opl_dout; +wire opl_irq_n; + +reg signed [15:0] sample; + +assign AUDIO_S = 1'b1; + +wire opl_sample_clk; + +jtopl #(.OPL_TYPE(2)) jtopl2 +( + .rst(~reset_n), + .clk(clk_sys), + .cen(clk_3_5M), + .din(sound_data), + .addr(sound_addr), + .cs_n('0), + .wr_n(~sound_wr), + .dout(opl_dout), + .irq_n(opl_irq_n), + .snd(sample), + .sample(opl_sample_clk) +); + +wire [1:0] opl2_level = status[44:43]; // opl2 audio mix + +reg [7:0] opl2_mult; + +// set the multiplier for each channel from menu + +always @( posedge clk_sys, posedge reset ) begin + if (reset) begin + opl2_mult<=0; + end else begin + case( opl2_level ) + 0: opl2_mult <= 8'h0c; // 75% + 1: opl2_mult <= 8'h08; // 50% + 2: opl2_mult <= 8'h04; // 25% + 3: opl2_mult <= 8'h00; // 0% + endcase + end +end + +wire signed [15:0] mono; + +jtframe_mixer #(.W0(16), .WOUT(16)) u_mix_mono( + .rst ( reset ), + .clk ( clk_sys ), + .cen ( 1'b1 ), + // input signals + .ch0 ( sample ), + .ch1 ( 16'd0 ), + .ch2 ( 16'd0 ), + .ch3 ( 16'd0 ), + // gain for each channel in 4.4 fixed point format + .gain0 ( opl2_mult ), + .gain1 ( 8'd0 ), + .gain2 ( 8'd0 ), + .gain3 ( 8'd0 ), + .mixed ( mono ), + .peak ( ) +); + +always @ (posedge clk_sys ) begin + if ( pause_cpu == 1 ) begin + AUDIO_L <= 0; + AUDIO_R <= 0; + end else if ( pause_cpu == 0 ) begin + // mix audio + AUDIO_L <= mono; + AUDIO_R <= mono; + end +end + +T80pa u_cpu( + .RESET_n ( reset_n & reset_z80_n ), + .CLK ( clk_sys ), + .CEN_p ( clk_3_5M ), + .CEN_n ( ~clk_3_5M ), + + .WAIT_n ( z80_wait_n ), // don't wait if data is valid or rom access isn't selected + .INT_n ( opl_irq_n ), // opl timer + .NMI_n ( 1'b1 ), + .BUSRQ_n ( 1'b1 ), + .RD_n ( z80_rd_n ), + .WR_n ( z80_wr_n ), + .A ( z80_addr ), + .DI ( z80_din ), + .DO ( z80_dout ), + // unused + .DIRSET ( 1'b0 ), + .DIR ( 212'b0 ), + .OUT0 ( 1'b0 ), + .RFSH_n (), + .IORQ_n ( IORQ_n ), + .M1_n (), + .BUSAK_n (), + .HALT_n ( 1'b1 ), + .MREQ_n ( MREQ_n ), + .Stop (), + .REG () +); + +// Chip select mux +wire prog_rom_cs; +wire scroll_ofs_x_cs; +wire scroll_ofs_y_cs; +wire ram_cs; +wire vblank_cs; +wire int_en_cs; +wire crtc_cs; +wire tile_ofs_cs; +wire tile_attr_cs; +wire tile_num_cs; +wire scroll_cs; +wire shared_ram_cs; +wire frame_done_cs; // word +wire tile_palette_cs; +wire sprite_palette_cs; +wire sprite_ofs_cs; +wire sprite_cs; // *** offset needs to be auto-incremented +wire sprite_size_cs; // *** offset needs to be auto-incremented +wire sprite_ram_cs; + +wire p1_cs; +wire p2_cs; +wire dswa_cs; +wire dswb_cs; +wire system_cs; +wire tjump_cs; +wire sound0_cs; +wire sound1_cs; +wire sound_latch_cs; +wire sound_latch_w_cs; +wire sound_latch_r_cs; +wire sound_status_cs; +wire sound_done_cs; + +chip_select cs (.*); + +wire sprite_0_cs = ( curr_sprite_ofs[1:0] == 2'b00 ) & sprite_cs; +wire sprite_1_cs = ( curr_sprite_ofs[1:0] == 2'b01 ) & sprite_cs; +wire sprite_2_cs = ( curr_sprite_ofs[1:0] == 2'b10 ) & sprite_cs; +wire sprite_3_cs = ( curr_sprite_ofs[1:0] == 2'b11 ) & sprite_cs; + +reg reset_z80_n; +wire reset_z80_cs; +wire sound_rom_1_cs = ( MREQ_n == 0 && z80_addr <= 16'h7fff ); +wire sound_ram_1_cs = ( MREQ_n == 0 && z80_addr >= 16'h8000 && z80_addr <= 16'hffff ); + +reg int_en; +reg int_ack; + +reg sound_latch_set; +reg [7:0] sound_latch ; + +reg [1:0] vbl_sr; + +// vblank interrupt on rising vbl +always @ (posedge clk_sys ) begin + if ( reset == 1 ) begin + ipl2_n <= 1; + ipl1_n <= 1; + int_ack <= 0; + end else begin + vbl_sr <= { vbl_sr[0], vbl }; + if ( clk_10M == 1 ) begin + int_ack <= ( cpu_as_n == 0 ) && ( cpu_fc == 3'b111 ); // cpu acknowledged the interrupt + end + if ( vbl_sr == 2'b01 ) begin// rising edge + ipl2_n <= ~int_en; + end else if ( vbl_sr == 2'b10 ) begin + if ( pcb == 1 ) begin + ipl1_n <= 0; + end + end else if ( int_ack == 1 || vbl_sr == 2'b10 ) begin + ipl2_n <= 1; + ipl1_n <= 1; + end + end +end + +reg [15:0] scroll_x [3:0]; +reg [15:0] scroll_y [3:0]; + +reg [15:0] scroll_x_latch [3:0]; +reg [15:0] scroll_y_latch [3:0]; + +reg inc_sprite_ofs; + +reg [15:0] crtc[4]; + +reg [15:0] scroll_x_total [3:0]; +reg [15:0] scroll_y_total [3:0]; + +wire [15:0] ram_dout; +wire [9:0] tile_palette_addr; +wire [15:0] tile_palette_cpu_dout; +wire [15:0] tile_palette_dout; + +wire [9:0] sprite_palette_addr; +wire [15:0] sprite_palette_cpu_dout; +wire [15:0] sprite_palette_dout; + +reg [15:0] curr_tile_ofs; +reg [15:0] curr_sprite_ofs; + +reg [15:0] scroll_ofs_x; +reg [15:0] scroll_ofs_y; + +wire [15:0] cpu_tile_dout_attr; +wire [15:0] cpu_tile_dout_num; + +wire [15:0] sprite_0_dout; +wire [15:0] sprite_1_dout; +wire [15:0] sprite_2_dout; +wire [15:0] sprite_3_dout; +wire [15:0] sprite_size_dout; +wire [15:0] sprite_size_cpu_dout; + +wire [31:0] tile_attr_dout; +wire [15:0] sprite_attr_0_dout; +wire [15:0] sprite_attr_1_dout; +wire [15:0] sprite_attr_2_dout; +wire [15:0] sprite_attr_3_dout; + +wire [15:0] sprite_size_buf_dout; +wire [15:0] sprite_attr_0_buf_dout; +wire [15:0] sprite_attr_1_buf_dout; +wire [15:0] sprite_attr_2_buf_dout; +wire [15:0] sprite_attr_3_buf_dout; + +reg [15:0] sprite_buf_din; + +reg [14:0] tile; + +reg [7:0] sprite_num; +reg [7:0] sprite_num_copy; + +reg [3:0] tile_draw_state; + +reg [2:0] layer; // 4 layers + 1 for initial background + +wire [14:0] tile_idx = tile_attr[14:0]; +wire [3:0] tile_priority = tile_attr[31:28]; +wire [5:0] tile_palette_idx = tile_attr[21:16]; +wire tile_hidden = tile_attr[15]; + +reg [15:0] fb_dout; +wire [15:0] tile_fb_out; +wire [15:0] sprite_fb_out; +reg [15:0] fb_din; +reg [15:0] sprite_fb_din; + +reg tile_fb_w; +reg sprite_fb_w; +reg sprite_buf_w; +reg sprite_size_buf_w; + +dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) tile_line_buffer ( + .clock_a ( clk_sys ), + .address_a ( tile_fb_addr_w ), + .wren_a ( tile_fb_w ), + .data_a ( fb_din ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( fb_addr_r ), + .wren_b ( 0 ), +// .data_b ( ), + .q_b ( tile_fb_out ) +); + +dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) sprite_line_buffer ( + .clock_a ( clk_sys ), + .address_a ( sprite_fb_addr_w ), + .wren_a ( sprite_fb_w ), + .data_a ( sprite_fb_din ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( fb_addr_r ), + .wren_b ( 0 ), +// .data_b ( ), + .q_b ( sprite_fb_out ) +); + +reg [9:0] x_ofs; +reg [9:0] x; + +reg [9:0] y_ofs; + +// y needs to be one line ahaed of the visible line +// render the first line at the end of the previous frame +// this depends on the timing that the sprite list is valid +// sprites values are copied at the start of vblank (line 240) + +// global offsets +wire [9:0] x_ofs_dx = 495 + { ~layer[1:0], 1'b0 }; +wire [9:0] y_ofs_dx = 257; +wire [9:0] x_ofs_dx_flipped = 17 - { ~layer[1:0], 1'b0 }; +wire [9:0] y_ofs_dx_flipped = 255; + +// calculate scrolling +wire [9:0] tile_x_unflipped = scroll_x_latch[layer[1:0]] + x_ofs_dx; +wire [9:0] tile_y_unflipped = scroll_y_latch[layer[1:0]] + y_ofs_dx + scroll_y_offset; +wire [9:0] tile_x_flipped = 319 + scroll_x_latch[layer[1:0]] + x_ofs_dx_flipped; +wire [9:0] tile_y_flipped = 239 + scroll_y_latch[layer[1:0]] + y_ofs_dx_flipped + scroll_y_offset; + +// reverse tiles when flipped +wire [9:0] curr_x = tile_flip ? tile_x_flipped - x : tile_x_unflipped + x; +wire [9:0] curr_y = tile_flip ? tile_y_flipped - y : tile_y_unflipped + y; + +reg [9:0] y; +wire [9:0] y_flipped = ( sprite_flip ? (240 - y ) + scroll_y_offset : y + scroll_y_offset); +wire [9:0] sprite_buf_x = sprite_flip ? 320 - (sprite_x + sprite_pos_x ) : sprite_x + sprite_pos_x; // offset from left of frame + +reg [3:0] draw_state; +reg [3:0] sprite_state; +reg [3:0] tile_copy_state; +reg [3:0] sprite_copy_state; + +// pixel 4 bit colour +wire [3:0] tile_pix; +assign tile_pix = { tile_data[7-curr_x[2:0]], tile_data[15-curr_x[2:0]], tile_data[23-curr_x[2:0]], tile_data[31-curr_x[2:0]] }; + +wire [2:0] sprite_bit = sprite_x[2:0]; +wire [3:0] sprite_pix; +assign sprite_pix = { sprite_data[7-sprite_bit], sprite_data[15-sprite_bit], sprite_data[23-sprite_bit], sprite_data[31-sprite_bit] }; + +// two lines of buffer alternate +reg [9:0] tile_fb_addr_w; +wire [9:0] fb_addr_r = {vc[0], 9'b0 } + hc; + +reg [9:0] sprite_fb_addr_w; + +reg [31:0] tile_attr; + +// two lines worth for 4 layers (~8k) +// [15:14] = layer. +// [13:10] = prioity +// [9:4] = palette offset +// [3:0] = tile colour index. + +reg [3:0] tile_priority_buf [327:0]; +reg [3:0] sprite_priority_buf [327:0]; + +reg [9:0] sprite_x; // offset from left side of sprite +reg [9:0] sprite_y; + +wire [14:0] sprite_index = sprite_attr_0_buf_dout[14:0] /* synthesis keep */; +wire sprite_hidden = sprite_attr_0_buf_dout[15] /* synthesis keep */; + +wire [5:0] sprite_pal_addr = sprite_attr_1_buf_dout[5:0] /* synthesis keep */; +wire [5:0] sprite_size_addr = sprite_attr_1_buf_dout[11:6] /* synthesis keep */; +wire [3:0] sprite_priority = sprite_attr_1_buf_dout[15:12] /* synthesis keep */; + +wire [9:0] sprite_pos_x = sprite_adj_x + (( sprite_attr_2_buf_dout[15:7] < 9'h180 ) ? sprite_attr_2_buf_dout[15:7] : ( sprite_attr_2_buf_dout[15:7] - 10'h200)); +wire [9:0] sprite_pos_y = sprite_adj_y + (( sprite_attr_3_buf_dout[15:7] < 9'h180 ) ? sprite_attr_3_buf_dout[15:7] : ( sprite_attr_3_buf_dout[15:7] - 10'h200)); + +// valid 1 cycle after sprite attr ready +wire [8:0] sprite_height = { sprite_size_buf_dout[7:4], 3'b0 } /* synthesis keep */; // in pixels +wire [8:0] sprite_width = { sprite_size_buf_dout[3:0], 3'b0 } /* synthesis keep */; + +reg [7:0] sprite_buf_num; + +reg [1:0] vtotal_282_flag; + +always @ (posedge clk_sys) begin // Check System Vcount flag for 60Hz mode + if ({crtc[2][7:0], 1'b1 } == 269) + vtotal_282_flag <= 0; + else + vtotal_282_flag <= 1; +end + +always @ (posedge clk_sys) begin + if ( reset == 1 ) begin + sprite_state <= 0; + draw_state <= 0; + sprite_rom_cs <= 0; + tile_rom_cs <= 0; + tile_copy_state <= 0; + sprite_copy_state <= 0; + tile_draw_state <= 0; + end else begin + // render sprites + // triggered when the tile rendering starts + if ( sprite_state == 0 && draw_state > 0 ) begin + sprite_num <= 8'h00; + sprite_x <= 0; + sprite_fb_w <= 1; + sprite_state <= 1; + sprite_fb_din <= 0; + sprite_fb_addr_w <= { y[0], 9'b0 }; + end else if ( sprite_state == 1 ) begin + // erase line buffer + sprite_fb_addr_w <= { y[0], 9'b0 } + sprite_x; + sprite_priority_buf[sprite_x] <= 0; + if ( sprite_x < 320 ) begin + sprite_x <= sprite_x + 1; + end else begin + sprite_x <= 0; + sprite_fb_w <= 0; + sprite_state <= 2; + end + end else if ( sprite_state == 2 ) begin + // sprite num is valid now + sprite_state <= 3; + end else if ( sprite_state == 3 ) begin + // sprite attr valid now. + // delay one more cycle to read sprite size + sprite_state <= 4; + end else if ( sprite_state == 4 ) begin + // start loop + sprite_rom_cs <= 0; + sprite_fb_w <= 0; + sprite_y <= y_flipped - sprite_pos_y; + // is sprite visible and is current y in sprite y range + // sprite pos can be negative? + if ( sprite_hidden == 0 && sprite_width > 0 && ( $signed(y_flipped) >= $signed(sprite_pos_y) ) && $signed(y_flipped) < ( $signed(sprite_pos_y) + $signed(sprite_height) ) ) begin + sprite_state <= 5; + end else if ( sprite_num < 8'hff ) begin + sprite_num <= sprite_num + 1; + sprite_state <= 2; + end else begin + sprite_state <= 15; + end + end else if ( sprite_state == 5 ) begin + sprite_rom_addr <= { sprite_index, 3'b0 } + { sprite_x[8:3], 3'b0 } + ( sprite_y[8:3] * sprite_width ) + sprite_y[2:0]; + sprite_rom_cs <= 1; + sprite_state <= 6; + end else if ( sprite_state == 6 ) begin + // wait for sprite bitmap ready + if ( sprite_rom_data_valid ) begin + // latch data and deassert cs + sprite_data <= sprite_rom_data; + sprite_rom_cs <= 0; + sprite_state <= 7; + end + end else if ( sprite_state == 7 ) begin + sprite_fb_w <= 0; + // draw if pixel value not zero and priority >= previous sprite data +// if ( sprite_pix > 0 && sprite_priority_buf[sprite_buf_x] == 0 ) begin +// if ( sprite_pix != 0 && ( sprite_priority == 0 || sprite_priority >= sprite_priority_buf[sprite_buf_x] ) ) begin + if ( sprite_pix != 0 ) begin + sprite_fb_din <= { 2'b11, sprite_priority, sprite_pal_addr, sprite_pix }; +// if ( sprite_priority == 0 ) begin +// sprite_priority_buf[sprite_buf_x] <= { 1'b1, sprite_priority }; +// end else begin + sprite_fb_addr_w <= { y[0], 9'b0 } + sprite_buf_x; + sprite_priority_buf[sprite_buf_x] <= sprite_priority; + sprite_fb_w <= 1; + end + if ( sprite_x < ( sprite_width - 1 ) ) begin + sprite_x <= sprite_x + 1; + if ( sprite_x[2:0] == 7 ) begin + // do recalc bitmap address + sprite_state <= 5; + end + end else if ( sprite_num < 8'hff ) begin + sprite_num <= sprite_num + 1; + sprite_x <= 0; + // need to load new attributes and size + sprite_state <= 2; + end else begin + // tile state machine will reset sprite_state when line completes. + sprite_state <= 15; // done + end + end + // copy tile ram and scroll info + // not sure if this is needed. need to check to see when tile ram is updated. + if ( tile_copy_state == 0 && vc == 256 ) begin + tile_copy_state <= 1; + end else begin + // copy scroll registers + scroll_x_latch[0] <= scroll_x[0] - scroll_ofs_x; + scroll_x_latch[1] <= scroll_x[1] - scroll_ofs_x; + scroll_x_latch[2] <= scroll_x[2] - scroll_ofs_x; + scroll_x_latch[3] <= scroll_x[3] - scroll_ofs_x; + scroll_y_latch[0] <= scroll_y[0] - scroll_ofs_y; + scroll_y_latch[1] <= scroll_y[1] - scroll_ofs_y; + scroll_y_latch[2] <= scroll_y[2] - scroll_ofs_y; + scroll_y_latch[3] <= scroll_y[3] - scroll_ofs_y; + end + // copy sprite attr/size to buffer + if ( sprite_copy_state == 0 && vc == 240 ) begin + sprite_copy_state <= 1; + sprite_buf_w <= 0; + sprite_num_copy <= 8'h00; + end else if ( sprite_copy_state == 1 ) begin + sprite_num_copy <= sprite_num_copy + 1; + sprite_buf_num <= sprite_num_copy; + sprite_buf_w <= 1; + // wait for read from source + if ( sprite_num_copy == 8'hff ) begin + sprite_copy_state <= 2; + end + end else if ( sprite_copy_state == 2 ) begin + sprite_buf_w <= 0; + sprite_copy_state <= 0; + end + // tile state machine + if ( draw_state == 0 && vc == ({ crtc[2][7:0], 1'b1 } - (status[19] ? (vtotal_282_flag ? 5'd19 : 4'd7) : 3'd0)) ) begin // 282 Lines standard (263 Lines for 60Hz) + layer <= 4; // layer 4 is layer 0 but draws hidden and transparent + y <= 0; + draw_state <= 2; + sprite_state <= 0; + end else if ( draw_state == 2 ) begin + x <= 0; + x_ofs <= scroll_x_latch[layer[1:0]]; + y_ofs <= scroll_y_latch[layer[1:0]]; + // latch offset info + draw_state <= 3; + tile_draw_state <= 0; + end else if ( draw_state == 3 ) begin + if ( tile_draw_state == 0 ) begin + tile <= { layer[1:0], curr_y[8:3], curr_x[8:3] }; // works + tile_draw_state <= 4'h1; + end else if ( tile_draw_state == 1 ) begin + tile_draw_state <= 2; + end else if ( tile_draw_state == 2 ) begin + // latch attribute + tile_attr <= tile_attr_dout; + if ( layer == 4 || tile_attr_dout[15] == 0 ) begin + tile_draw_state <= 3; + end else begin + if ( x < 320 ) begin// 319 + tile_draw_state <= 3; + // do we need to read another tile? + // last pixel of this tile changes based on flip direction + if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin + draw_state <= 3; + tile_draw_state <= 0; + end + x <= x + 1; + end else if ( layer > 0 ) begin + layer <= layer - 1; + tile_fb_w <= 0; + draw_state <= 2; + end else begin + // done + tile_draw_state <= 7; + tile_fb_w <= 0; + end + end + end else if ( tile_draw_state == 3 ) begin + // read bitmap info + tile_rom_cs <= 1; + tile_rom_addr <= { tile_idx, curr_y[2:0] }; + tile_draw_state <= 4; + end else if ( tile_draw_state == 4 ) begin + // wait for bitmap ram ready + if ( tile_rom_data_valid ) begin + // latch data and deassert cs + tile_data <= tile_rom_data; + tile_draw_state <= 5; + tile_rom_cs <= 0; + end + end else if ( tile_draw_state == 5 ) begin + tile_fb_w <= 0; + tile_fb_addr_w <= { y[0], 9'b0 } + x; + // force render of first layer. + // if layer == 4 then tile_pix == 0 is not transparent + // layer 4 is really layer 0 + if ( layer == 4 ) begin + tile_priority_buf[x] <= 0; //tile_pix == 0 ? 0 : tile_priority; + //fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; + fb_din <= { layer[1:0], 4'b0, tile_palette_idx, tile_pix }; + tile_fb_w <= 1; + end else if (tile_hidden == 0 && tile_pix > 0 && tile_priority > 0 && tile_priority >= tile_priority_buf[x] ) begin + tile_priority_buf[x] <= tile_priority; + // if tile hidden then make the pallette index 0. ie transparent + fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; + tile_fb_w <= 1; + end + if ( x < 320 ) begin// 319 + // do we need to read another tile? + // last pixel of this tile changes based on flip direction + if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin + draw_state <= 3; + tile_draw_state <= 0; + end + x <= x + 1; + end else if ( layer > 0 ) begin + layer <= layer - 1; + tile_fb_w <= 0; + draw_state <= 2; + end else begin + // done + tile_draw_state <= 7; + tile_fb_w <= 0; + end + end else if ( tile_draw_state == 7 ) begin + // wait for next line or quit + if ( y == 239 ) begin + draw_state <= 0; + end else if ( hc == (status[19] ? 9'd444 : 9'd449) ) begin // 450 Lines standard (445 Lines for NTSC standard 15.73kHz line freq) + y <= y + 1; + draw_state <= 2; + sprite_state <= 0; + layer <= 4; + end + end + end + end +end + +// render +reg draw_sprite; + +// two lines worth for 4 layers (~8k) +// [15:14] = layer. +// [13:10] = prioity +// [9:4] = palette offset +// [3:0] = tile colour index. + +// there are 10 70MHz cycles per pixel. clk7_count from 0-9 + +// dac values based on 120 ohm driver for the resistor dac and 75 ohm output. 4.7k, 2.2k, 1k, 470, 220 +// modeled in spice +wire [7:0] dac [0:31] = '{0,12,25,36,50,61,73,83,91,100,111,120,131,139,149,157,145,154,162,170,180,187,195,202,208,214,222,228,236,242,249,255}; + +always @ (posedge clk_sys) begin + if ( clk7_count == 4 ) begin + tile_palette_addr <= tile_fb_out[9:0]; + sprite_palette_addr <= sprite_fb_out[9:0]; + end else if ( clk7_count == 6 ) begin + // if palette index is zero then it's from layer 3 and is transparent render as blank (black). + rgb <= { dac[tile_palette_dout[4:0]], dac[tile_palette_dout[9:5]], dac[tile_palette_dout[14:10]] }; + + // if not transparent and sprite is higher priority + if ( sprite_fb_out[3:0] > 0 && (sprite_fb_out[13:10] > tile_fb_out[13:10]) ) begin + // draw sprite + rgb <= { dac[sprite_palette_dout[4:0]], dac[sprite_palette_dout[9:5]], dac[sprite_palette_dout[14:10]] }; + end + end +end + +// tile data buffer + +reg tile_buf_w; +reg [31:0] tile_buf_din; +reg [31:0] tile_buf_dout; +reg [13:0] tile_buf_addr; + +dual_port_ram #(.LEN(16384), .DATA_WIDTH(32)) ram_tile_buf ( + .clock_a ( clk_sys ), + .address_a ( tile[13:0] ), + .wren_a ( tile_buf_w ), + .data_a ( tile_attr_dout ), + + .clock_b ( clk_sys ), + .address_b ( tile[13:0] ), // only read the tile # for now + .wren_b ( 0 ), + .q_b ( tile_buf_dout ) +); + +// tile attribute ram. each tile attribute is 2 16bit words +// pppp ---- --cc cccc httt tttt tttt tttt = Tile number (0 - $7fff) +// indirect access through offset register +dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_h ( + .clock_a ( clk_10M ), + .address_a ( curr_tile_ofs ), + .wren_a ( tile_attr_cs & !cpu_rw ), + .data_a ( cpu_dout ), + .q_a ( cpu_tile_dout_attr ), + + .clock_b ( clk_sys ), + .address_b ( tile[13:0] ), // only read the tile # for now + .wren_b ( 0 ), + .q_b ( tile_attr_dout[31:16] ) +); + +dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_l ( + .clock_a ( clk_10M ), + .address_a ( curr_tile_ofs ), + .wren_a ( tile_num_cs & !cpu_rw ), + .data_a ( cpu_dout ), + .q_a ( cpu_tile_dout_num ), + + .clock_b ( clk_sys ), + .address_b ( tile[13:0] ), // only read the tile # for now + .wren_b ( 0 ), + .q_b ( tile_attr_dout[15:0] ) +); + +// sprite attribute ram. each tile attribute is 4 16bit words +// indirect access through offset register +// split up so 64 bits can be read in a single clock +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_0 ( + .clock_a ( clk_10M ), + .address_a ( curr_sprite_ofs[9:2] ), + .wren_a ( sprite_0_cs & !cpu_rw), + .data_a ( cpu_dout ), + .q_a ( sprite_0_dout ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num_copy ), + .wren_b ( 0 ), + .q_b ( sprite_attr_0_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_0_buf ( + .clock_a ( clk_sys ), + .address_a ( sprite_buf_num ), + .wren_a ( sprite_buf_w ), + .data_a ( sprite_attr_0_dout[15:0] ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num ), + .wren_b ( 0 ), + .q_b ( sprite_attr_0_buf_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_1 ( + .clock_a ( clk_10M ), + .address_a ( curr_sprite_ofs[9:2] ), + .wren_a ( sprite_1_cs & !cpu_rw ), + .data_a ( cpu_dout ), + .q_a ( sprite_1_dout ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num_copy ), + .wren_b ( 0 ), + .q_b ( sprite_attr_1_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_1_buf ( + .clock_a ( clk_sys ), + .address_a ( sprite_buf_num ), + .wren_a ( sprite_buf_w ), + .data_a ( sprite_attr_1_dout[15:0] ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num ), + .wren_b ( 0 ), + .q_b ( sprite_attr_1_buf_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_2 ( + .clock_a ( clk_10M ), + .address_a ( curr_sprite_ofs[9:2] ), + .wren_a ( sprite_2_cs & !cpu_rw ), + .data_a ( cpu_dout ), + .q_a ( sprite_2_dout ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num_copy ), + .wren_b ( 0 ), + .q_b ( sprite_attr_2_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_2_buf ( + .clock_a ( clk_sys ), + .address_a ( sprite_buf_num ), + .wren_a ( sprite_buf_w ), + .data_a ( sprite_attr_2_dout[15:0] ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num ), + .wren_b ( 0 ), + .q_b ( sprite_attr_2_buf_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_3 ( + .clock_a ( clk_10M ), + .address_a ( curr_sprite_ofs[9:2] ), + .wren_a ( sprite_3_cs & !cpu_rw ), + .data_a ( cpu_dout ), + .q_a ( sprite_3_dout ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num_copy ), + .wren_b ( 0 ), + .q_b ( sprite_attr_3_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_3_buf ( + .clock_a ( clk_sys ), + .address_a ( sprite_buf_num ), + .wren_a ( sprite_buf_w ), + .data_a ( sprite_attr_3_dout[15:0] ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num ), + .wren_b ( 0 ), + .q_b ( sprite_attr_3_buf_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_size ( + .clock_a ( clk_10M ), + .address_a ( curr_sprite_ofs ), + .wren_a ( sprite_size_cs & !cpu_rw), + .data_a ( cpu_dout ), + .q_a ( sprite_size_cpu_dout ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num_copy ), + .wren_b ( 0 ), + .q_b ( sprite_size_dout ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_size_buf ( + .clock_a ( clk_sys ), + .address_a ( sprite_buf_num ), + .wren_a ( sprite_buf_w ), + .data_a ( sprite_size_dout ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_size_addr ), + .wren_b ( 0 ), + .q_b ( sprite_size_buf_dout ) +); + + +// tiles 1024 15 bit values. index is ( 6 bits from tile attribute, 4 bits from bitmap ) +// background palette ram low +// does this need to be byte addressable? +dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_l ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[10:1] ), + .wren_a ( tile_palette_cs & !cpu_rw & !cpu_lds_n), + .data_a ( cpu_dout[7:0] ), + .q_a ( tile_palette_cpu_dout[7:0] ), + + .clock_b ( clk_sys ), + .address_b ( tile_palette_addr ), + .wren_b ( 0 ), + .q_b ( tile_palette_dout[7:0] ) +); + +// background palette ram high +dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_h ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[10:1] ), + .wren_a ( tile_palette_cs & !cpu_rw & !cpu_uds_n), + .data_a ( cpu_dout[15:8] ), + .q_a ( tile_palette_cpu_dout[15:8] ), + + .clock_b ( clk_sys ), + .address_b ( tile_palette_addr ), + .wren_b ( 0 ), + .q_b ( tile_palette_dout[15:8] ) +); + +// sprite palette ram low +// does this need to be byte addressable? +dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_l ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[10:1] ), + .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_lds_n), + .data_a ( cpu_dout[7:0] ), + .q_a ( sprite_palette_cpu_dout[7:0] ), + + .clock_b ( clk_sys ), + .address_b ( sprite_palette_addr ), + .wren_b ( 0 ), + .q_b ( sprite_palette_dout[7:0] ) +); + +// background palette ram high +dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_h ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[10:1] ), + .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_uds_n), + .data_a ( cpu_dout[15:8] ), + .q_a ( sprite_palette_cpu_dout[15:8] ), + + .clock_b ( clk_sys ), + .address_b ( sprite_palette_addr ), + .wren_b ( 0 ), + .q_b ( sprite_palette_dout[15:8] ) +); + + +// main 68k ram low +dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_L ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[14:1] ), + .wren_a ( !cpu_rw & ram_cs & !cpu_lds_n ), + .data_a ( cpu_dout[7:0] ), + .q_a ( ram_dout[7:0] ) + ); + +// main 68k ram high +dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_H ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[14:1] ), + .wren_a ( !cpu_rw & ram_cs & !cpu_uds_n ), + .data_a ( cpu_dout[15:8] ), + .q_a ( ram_dout[15:8] ) +); + + +//wire [15:0] z80_shared_addr = z80_addr - 16'h8000; +//wire [23:0] m68k_shard_addr = cpu_a - 24'h040000; + +// z80 and 68k shared ram +// 4k +dual_port_ram #(.LEN(32768), .DATA_WIDTH(8)) shared_ram +( + .clock_a ( clk_10M ), + .address_a ( cpu_a[12:1] ), + .wren_a ( shared_ram_cs & !cpu_rw & !cpu_lds_n), + .data_a ( cpu_dout[7:0] ), + .q_a ( cpu_shared_dout[7:0] ), + + .clock_b ( clk_3_5M ), // z80 clock is 3.5M + .address_b ( z80_addr[14:0] ), + .data_b ( z80_dout ), + .wren_b ( sound_ram_1_cs & ~z80_wr_n ), + .q_b ( z80_shared_dout ) +); + +reg [11:0] sprite_rb_addr; +wire [15:0] sprite_rb_dout; + +dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) sprite_ram_rb_l ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[12:1] ), + .wren_a ( sprite_ram_cs & !cpu_rw & !cpu_lds_n), + .data_a ( cpu_dout[7:0] ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_rb_addr ), + .wren_b ( 0 ), + .q_b ( sprite_rb_dout[7:0] ) +); + +dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) sprite_ram_rb_h ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[12:1] ), + .wren_a ( sprite_ram_cs & !cpu_rw & !cpu_uds_n), + .data_a ( cpu_dout[15:8] ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_rb_addr ), + .wren_b ( 0 ), + .q_b ( sprite_rb_dout[15:8] ) +); + +reg [22:0] sdram_addr; +reg [31:0] sdram_data; +reg sdram_we; +reg sdram_req; + +wire sdram_ack; +wire sdram_valid; +wire [31:0] sdram_q; + +sdram #(.CLK_FREQ(70.0)) sdram +( + .reset(~pll_locked), + .clk(clk_sys), + + // controller interface + .addr(sdram_addr), + .data(sdram_data), + .we(sdram_we), + .req(sdram_req), + + .ack(sdram_ack), + .valid(sdram_valid), + .q(sdram_q), + + // SDRAM interface + .sdram_a(SDRAM_A), + .sdram_ba(SDRAM_BA), + .sdram_dq(SDRAM_DQ), + .sdram_cke(SDRAM_CKE), + .sdram_cs_n(SDRAM_nCS), + .sdram_ras_n(SDRAM_nRAS), + .sdram_cas_n(SDRAM_nCAS), + .sdram_we_n(SDRAM_nWE), + .sdram_dqml(SDRAM_DQML), + .sdram_dqmh(SDRAM_DQMH) +); + +wire prog_cache_rom_cs; +wire [22:0] prog_cache_addr; +wire [15:0] prog_cache_data; +wire prog_cache_valid; + +wire [15:0] prog_rom_data; +wire prog_rom_data_valid; + +reg tile_rom_cs; +reg [17:0] tile_rom_addr; +wire [31:0] tile_rom_data; +wire tile_rom_data_valid; + +wire tile_cache_cs; +wire [17:0] tile_cache_addr; +wire [31:0] tile_cache_data; +wire tile_cache_valid; + +reg [31:0] tile_data; + +wire sprite_rom_cs; +wire [18:0] sprite_rom_addr; +wire [31:0] sprite_rom_data; +wire sprite_rom_data_valid; + +reg [31:0] sprite_data; + +wire [15:0] sound_rom_1_addr; +wire [7:0] sound_rom_1_data; +wire sound_rom_1_data_valid; + +// sdram priority based rom controller +// is a oe needed? +rom_controller rom_controller +( + .reset(reset), + + // clock + .clk(clk_sys), + + // program ROM interface + .prog_rom_cs(prog_cache_rom_cs), + .prog_rom_oe(1), + .prog_rom_addr(prog_cache_addr), + .prog_rom_data(prog_cache_data), + .prog_rom_data_valid(prog_cache_valid), + + // character ROM interface + .tile_rom_cs(tile_cache_cs), + .tile_rom_oe(1), + .tile_rom_addr(tile_cache_addr), + .tile_rom_data(tile_cache_data), + .tile_rom_data_valid(tile_cache_valid), + + + // sprite ROM interface + .sprite_rom_cs(sprite_rom_cs), + .sprite_rom_oe(1), + .sprite_rom_addr(sprite_rom_addr), + .sprite_rom_data(sprite_rom_data), + .sprite_rom_data_valid(sprite_rom_data_valid), + + // sound ROM #1 interface + .sound_rom_1_cs(sound_rom_1_cs), + .sound_rom_1_oe(1), + .sound_rom_1_addr(z80_addr), + .sound_rom_1_data(sound_rom_1_data), + .sound_rom_1_data_valid(sound_rom_1_data_valid), + + // IOCTL interface + .ioctl_addr(ioctl_addr), + .ioctl_data(ioctl_dout), + .ioctl_index(ioctl_index), + .ioctl_wr(ioctl_wr), + .ioctl_download(ioctl_download), + + // SDRAM interface + .sdram_addr(sdram_addr), + .sdram_data(sdram_data), + .sdram_we(sdram_we), + .sdram_req(sdram_req), + .sdram_ack(sdram_ack), + .sdram_valid(sdram_valid), + .sdram_q(sdram_q) +); + + +cache prog_cache +( + .reset(reset), + .clk(clk_sys), + + // client + .cache_req(prog_rom_cs), + .cache_addr(cpu_a[23:1]), + .cache_valid(prog_rom_data_valid), + .cache_data(prog_rom_data), + + // to rom controller + .rom_req(prog_cache_rom_cs), + .rom_addr(prog_cache_addr), + .rom_valid(prog_cache_valid), + .rom_data(prog_cache_data) +); + +tile_cache tile_cache +( + .reset(reset), + .clk(clk_sys), + + // client + .cache_req(tile_rom_cs), + .cache_addr(tile_rom_addr), + .cache_data(tile_rom_data), + .cache_valid(tile_rom_data_valid), + + // to rom controller + .rom_req(tile_cache_cs), + .rom_addr(tile_cache_addr), + .rom_data(tile_cache_data), + .rom_valid(tile_cache_valid) +); + +endmodule + + +module cc_shifter +( + input clk_out, + input i, + output o +); + +// We use a two-stages shift-register to synchronize SignalIn_clkA to the clkB clock domain +reg [1:0] r; + +assign o = r[1]; // new signal synchronized to (=ready to be used in) clkB domain + +always @(posedge clk_out) begin + r[0] <= i; + r[1] <= r[0]; // notice that we use clkB +end + +endmodule + + diff --git a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_zerowing/Zerowing_Top.sv b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_zerowing/Zerowing_Top.sv index f75b1cb0..b70413da 100644 --- a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_zerowing/Zerowing_Top.sv +++ b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_zerowing/Zerowing_Top.sv @@ -1,13 +1,13 @@ module Zerowing_Top( + + input [3:0] pcb, input clk_sys, - input clk_70M, input pll_locked, input turbo_68k,//cpu_turbo - input reset, - + input reset, input pause_cpu, - - input status32, +//------------------------------------ + input scrollDBG, input p1_right, input p1_left, input p1_down, @@ -29,8 +29,7 @@ module Zerowing_Top( input [7:0] sw0, input [7:0] sw1, input [7:0] sw2, - input [3:0] pcb, - +//------------------------------------ output hsync, output vsync, output hblank, @@ -45,19 +44,28 @@ module Zerowing_Top( output [4:0] b, input ntsc, input [1:0] opl2_level, - output [15:0] audio, - - - input ioctl_download, - input ioctl_upload, -// input ioctl_upload_req; -// input ioctl_wait; - output ioctl_wr, - input [15:0] ioctl_index, - output [26:0] ioctl_addr, - input [15:0] ioctl_dout, - output [15:0] ioctl_din -); +//------------------------------------ + output [15:0] audio_l, + output [15:0] audio_r, +//------------------------------------ + input ioctl_download, + input ioctl_index, + input [23:0] ioctl_addr, + input ioctl_wr, + input [7:0] ioctl_dout, + output [12:0] SDRAM_A, + output [1:0] SDRAM_BA, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nCS, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nWE +); + + +localparam CLKSYS=72; wire tile_priority_type; wire [15:0] scroll_y_offset; @@ -80,14 +88,14 @@ always @ ( posedge clk_sys ) begin p2 <= { 1'b0, p2_buttons[2:0], p2_right, p2_left, p2_down, p2_up }; z80_tjump <= sw2; - if ( pcb == 0 || pcb == 1 || pcb == 2 || pcb == 3 && status32 == 1 ) begin + if ( pcb == 0 || pcb == 1 || pcb == 2 || pcb == 3 && scrollDBG == 1 ) begin // zerowing, hellfire, outzone, outzone conversion debug options z80_dswa <= sw0; - z80_dswb <= { sw1[7], sw1[6] | status32, sw1[5:0] }; + z80_dswb <= { sw1[7], sw1[6] | scrollDBG, sw1[5:0] }; system <= { vblank, start2 | p1_buttons[3], start1 | p1_buttons[3], coin_b, coin_a, service, key_tilt, key_service }; - end else if ( pcb == 4 && status32 == 1 ) begin + end else if ( pcb == 4 && scrollDBG == 1 ) begin // truxton debug options - z80_dswa <= { sw0[7:3], sw0[2] | status32, sw0[1:0] }; + z80_dswa <= { sw0[7:3], sw0[2] | scrollDBG, sw0[1:0] }; z80_dswb <= sw1; system <= { vblank, start2, start1, coin_b, coin_a, service, key_tilt, key_service }; end else begin @@ -293,7 +301,7 @@ always @ (posedge clk_sys) begin // add dsp_ctrl_cs to cpu_din // select cpu data input based on what is active cpu_din <= prog_rom_cs ? prog_rom_data : - ram_cs ? ram_dout : + m68k_ram_cs ? ram_dout : tile_palette_cs ? tile_palette_cpu_dout : sprite_palette_cs ? sprite_palette_cpu_dout : shared_ram_cs ? cpu_shared_dout : @@ -337,12 +345,12 @@ always @ (posedge clk_sys) begin sound_wr <= 0; end else if ( clk_3_5M == 1 ) begin z80_wait_n <= 1; - if ( ioctl_download | ( z80_rd_n == 0 && sound_rom_1_data_valid == 0 && sound_rom_1_cs == 1 ) ) begin + if ( rom_download | ( z80_rd_n == 0 && sound_rom_1_data_valid == 0 && sound_rom_1_cs == 1 ) ) begin // wait if rom is selected and data is not yet available z80_wait_n <= 0; end if ( z80_rd_n == 0 ) begin - if ( sound_rom_1_cs ) begin + if ( z80_rom_cs ) begin if ( sound_rom_1_data_valid ) begin z80_din <= sound_rom_1_data; end else begin @@ -445,10 +453,12 @@ jtframe_mixer #(.W0(16), .WOUT(16)) u_mix_mono( always @ (posedge clk_sys ) begin if ( pause_cpu == 1 ) begin - audio <= 0; + audio_l <= 0; + audio_r <= 0; end else if ( pause_cpu == 0 ) begin // mix audio - audio <= {~mono[15],mono[14:0]}; + audio_l <= {mono[15:0]}; + audio_r <= {mono[15:0]}; end end @@ -485,7 +495,7 @@ T80pa u_cpu( wire prog_rom_cs; wire scroll_ofs_x_cs; wire scroll_ofs_y_cs; -wire ram_cs; +//wire ram_cs; wire vblank_cs; wire int_en_cs; wire crtc_cs; @@ -511,7 +521,7 @@ wire z80_tjump_cs; wire z80_sound0_cs; wire z80_sound1_cs; -chip_select cs (.*); +//chip_select cs (.*); wire sprite_0_cs = ( curr_sprite_ofs[1:0] == 2'b00 ) & sprite_cs; wire sprite_1_cs = ( curr_sprite_ofs[1:0] == 2'b01 ) & sprite_cs; @@ -620,7 +630,7 @@ end reg [15:0] scroll_x_total [3:0]; reg [15:0] scroll_y_total [3:0]; -wire [15:0] ram_dout; + wire [9:0] tile_palette_addr; wire [15:0] tile_palette_cpu_dout; wire [15:0] tile_palette_dout; @@ -1309,25 +1319,6 @@ dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_h ( ); -// main 68k ram low -dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_L ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[14:1] ), - .wren_a ( !cpu_rw & ram_cs & !cpu_lds_n ), - .data_a ( cpu_dout[7:0] ), - .q_a ( ram_dout[7:0] ) - ); - -// main 68k ram high -dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_H ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[14:1] ), - .wren_a ( !cpu_rw & ram_cs & !cpu_uds_n ), - .data_a ( cpu_dout[15:8] ), - .q_a ( ram_dout[15:8] ) -); - - //wire [15:0] z80_shared_addr = z80_addr - 16'h8000; //wire [23:0] m68k_shard_addr = cpu_a - 24'h040000; @@ -1385,39 +1376,7 @@ wire sdram_ack; wire sdram_valid; wire [31:0] sdram_q; -//sdram #(.CLK_FREQ(70.0)) sdram -//( -// .reset(~pll_locked), -// .clk(clk_sys), -// -// // controller interface -// .addr(sdram_addr), -// .data(sdram_data), -// .we(sdram_we), -// .req(sdram_req), -// -// .ack(sdram_ack), -// .valid(sdram_valid), -// .q(sdram_q), -// -// // SDRAM interface -// .sdram_a(SDRAM_A), -// .sdram_ba(SDRAM_BA), -// .sdram_dq(SDRAM_DQ), -// .sdram_cke(SDRAM_CKE), -// .sdram_cs_n(SDRAM_nCS), -// .sdram_ras_n(SDRAM_nRAS), -// .sdram_cas_n(SDRAM_nCAS), -// .sdram_we_n(SDRAM_nWE), -// .sdram_dqml(SDRAM_DQML), -// .sdram_dqmh(SDRAM_DQMH) -//); - -wire prog_cache_rom_cs; -wire [22:0] prog_cache_addr; -wire [15:0] prog_cache_data; -wire prog_cache_valid; - +wire [22:0] prog_rom_addr; wire [15:0] prog_rom_data; wire prog_rom_data_valid; @@ -1446,94 +1405,231 @@ wire sound_rom_1_data_valid; // sdram priority based rom controller // is a oe needed? -rom_controller rom_controller +// M68K RAM CONTROL +reg m68k_ram_req; +wire m68k_ram_ack; +reg [21:1] m68k_ram_a; +reg m68k_ram_we; +wire [15:0] m68k_ram_dout; +reg [15:0] m68k_ram_din; +reg [1:0] m68k_ram_ds; +reg m68k_ram_dtack; +reg m68k_mcu_dtack; + +localparam M68K_RAM_IDLE = 0; +localparam M68K_RAM_M68K = 1; +localparam M68K_RAM_MCU = 2; + +reg [1:0] m68k_ram_state; + +always @ (posedge clk_sys) begin + if ( reset == 1 ) begin + m68k_ram_dtack <= 0; + m68k_mcu_dtack <= 0; + m68k_ram_state <= M68K_RAM_IDLE; + end else begin + if (!m68k_ram_cs) m68k_ram_dtack <= 0; +// if (!mcu_wl & !mcu_wh) m68k_mcu_dtack <= 0; +// +// case (m68k_ram_state) +// M68K_RAM_IDLE: +// if ((mcu_wl | mcu_wh) & !m68k_mcu_dtack) begin +// m68k_ram_a <= mcu_addr; +// m68k_ram_din <= {mcu_din, mcu_din}; +// m68k_ram_we <= 1; +// m68k_ram_ds <= {mcu_wh, mcu_wl}; +// m68k_ram_req <= !m68k_ram_req; +// m68k_ram_state <= M68K_RAM_MCU; +// end +// else +// if (m68k_ram_cs & !m68k_ram_dtack) begin +// m68k_ram_a <= m68k_a[13:1]; +// m68k_ram_din <= m68k_dout; +// m68k_ram_we <= !m68k_rw; +// m68k_ram_ds <= {!m68k_uds_n, !m68k_lds_n}; +// m68k_ram_req <= !m68k_ram_req; +// m68k_ram_state <= M68K_RAM_M68K; +// end +// +// M68K_RAM_M68K: +// if (m68k_ram_req == m68k_ram_ack) begin +// m68k_ram_dtack <= 1; +// m68k_ram_state <= M68K_RAM_IDLE; +// end +// M68K_RAM_MCU: +// if (m68k_ram_req == m68k_ram_ack) begin +// m68k_mcu_dtack <= 1; +// m68k_ram_state <= M68K_RAM_IDLE; +// end +// endcase + end +end + +wire m68k_rom_cs; +//wire m68k_rom_2_cs; +wire m68k_ram_cs; +wire m68k_pal_cs; +wire m68k_spr_cs; +wire m68k_fg_ram_cs; +wire m68k_spr_flip_cs; +//wire input_p1_cs; +//wire m68k_rotary2_cs; +//wire m68k_rotary_msb_cs; +//wire m68k_dsw_cs; +//wire irq_z80_cs; +//wire m68k_latch_cs; +//wire z80_latch_read_cs; +//wire vbl_int_clr_cs; +//wire cpu_int_clr_cs; +//wire watchdog_clr_cs; +//wire m68k_sp85_cs; +//wire m68k_ipl0_ack; +//wire m68k_ipl1_ack; +// +wire z80_rom_cs; +//wire z80_ram_cs; +//wire z80_banked_cs; +// +//wire z80_latch_cs; +//wire z80_latch_clr_cs; +//wire z80_dac_cs; +//wire z80_ym2413_cs; +//wire z80_ym2203_cs; +//wire z80_bank_set_cs; +// +//chip_select cs ( +// .pcb(pcb), +// +// // 68k bus +// .m68k_a(m68k_a), +// .m68k_as_n(m68k_as_n), +// .m68k_rw(m68k_rw), +// .m68k_uds_n(m68k_uds_n), +// .m68k_lds_n(m68k_lds_n), +// +// .z80_addr(z80_addr), +// .MREQ_n(MREQ_n), +// .IORQ_n(IORQ_n), +// .M1_n(M1_n), +// .RFSH_n(RFSH_n), +// .RD_n( z80_rd_n ), +// .WR_n( z80_wr_n ), +// +// // 68k chip selects +// .m68k_rom_cs, +// .m68k_rom_2_cs, +// .m68k_ram_cs, +// .m68k_spr_cs, +// .m68k_sp85_cs, +// .m68k_fg_ram_cs, +// .m68k_pal_cs, +// +// .m68k_rotary2_cs, +// .m68k_rotary_msb_cs, +// +// .input_p1_cs, +// .m68k_dsw_cs, +// +// // interrupt clear & watchdog +// .vbl_int_clr_cs, +// .cpu_int_clr_cs, +// .watchdog_clr_cs, +// +// .m68k_latch_cs, // write commands to z80 from 68k +// +// // z80 +// +// .z80_rom_cs, +// .z80_ram_cs, +// .z80_banked_cs, +// +// .z80_latch_cs, +// .z80_latch_clr_cs, +// .z80_dac_cs, +// .z80_ym2413_cs, +// .z80_ym2203_cs, +// .z80_bank_set_cs +// +//); + + +reg port1_req, port2_req; +always @(posedge clk_sys) begin + if (rom_download) begin + if (ioctl_wr) begin + port1_req <= ~port1_req; + port2_req <= ~port2_req; + end + end +end + +sdram #(CLKSYS) sdram ( - .reset(reset), + .*, + .init_n ( pll_locked ), + .clk ( clk_sys ), - // clock - .clk(clk_sys), + // Bank 0-1 ops + .port1_a ( ioctl_addr[23:1] ), + .port1_req ( port1_req ), + .port1_ack (), + .port1_we ( rom_download ), + .port1_ds ( {~ioctl_addr[0], ioctl_addr[0]} ), + .port1_d ( {ioctl_dout, ioctl_dout} ), + .port1_q (), - // program ROM interface - .prog_rom_cs(prog_cache_rom_cs), - .prog_rom_oe(1), - .prog_rom_addr(prog_cache_addr), - .prog_rom_data(prog_cache_data), - .prog_rom_data_valid(prog_cache_valid), + // M68K + .cpu1_rom_addr ( {prog_rom_cs, cpu_a[17:1]} ), //ioctl_addr >= 24'h000000) & (ioctl_addr < 24'h040000 + .cpu1_rom_cs ( prog_rom_cs ), + .cpu1_rom_q ( prog_rom_data ), + .cpu1_rom_valid( prog_rom_data_valid), - // character ROM interface - .tile_rom_cs(tile_cache_cs), - .tile_rom_oe(1), - .tile_rom_addr(tile_cache_addr), - .tile_rom_data(tile_cache_data), - .tile_rom_data_valid(tile_cache_valid), + .cpu1_ram_req ( ram_req ), + .cpu1_ram_ack ( ram_ack ), + .cpu1_ram_addr ( ram_a ), + .cpu1_ram_we ( ram_we ), + .cpu1_ram_d ( ram_din ), + .cpu1_ram_q ( ram_dout ), + .cpu1_ram_ds ( ram_ds ), + // Audio Z80 + .cpu2_addr ( {1'b1, sound_rom_1_addr[15:1]} ), // (ioctl_addr >= 24'h080000) & (ioctl_addr < 24'h100000) ; + .cpu2_rom_cs ( sound_rom_cs | z80_banked_cs ), + .cpu2_q ( sound_rom_do ), + .cpu2_valid ( sound_rom_data_valid ), - // sprite ROM interface - .sprite_rom_cs(sprite_rom_cs), - .sprite_rom_oe(1), - .sprite_rom_addr(sprite_rom_addr), - .sprite_rom_data(sprite_rom_data), - .sprite_rom_data_valid(sprite_rom_data_valid), + .cpu3_addr ( ), + .cpu3_rom_cs ( ), + .cpu3_q ( ), + .cpu3_valid ( ), - // sound ROM #1 interface - .sound_rom_1_cs(sound_rom_1_cs), - .sound_rom_1_oe(1), - .sound_rom_1_addr(z80_addr), - .sound_rom_1_data(sound_rom_1_data), - .sound_rom_1_data_valid(sound_rom_1_data_valid), + .cpu4_addr ( ), + .cpu4_rom_cs ( ), + .cpu4_q ( ), + .cpu4_valid ( ), - // IOCTL interface - .ioctl_addr(ioctl_addr), - .ioctl_data(ioctl_dout), - .ioctl_index(ioctl_index), - .ioctl_wr(ioctl_wr), - .ioctl_download(ioctl_download), + // Bank 2-3 ops + .port2_a ( ioctl_addr[23:1] ), + .port2_req ( port2_req ), + .port2_ack ( ), + .port2_we ( rom_download ), + .port2_ds ( {~ioctl_addr[0], ioctl_addr[0]} ), + .port2_d ( {ioctl_dout, ioctl_dout} ), + .port2_q ( ), - // SDRAM interface - .sdram_addr(sdram_addr), - .sdram_data(sdram_data), - .sdram_we(sdram_we), - .sdram_req(sdram_req), - .sdram_ack(sdram_ack), - .sdram_valid(sdram_valid), - .sdram_q(sdram_q) -); + .gfx1_addr ( {5'h10, tile_rom_addr[15:2]} ), // (ioctl_addr >= 24'h100000) & (ioctl_addr < 24'h110000) ; + .gfx1_q ( tile_rom_data ), + .gfx2_addr ( ), + .gfx2_q ( ), -cache prog_cache -( - .reset(reset), - .clk(clk_sys), + .gfx3_addr ( ), + .gfx3_q ( ), - // client - .cache_req(prog_rom_cs), - .cache_addr(cpu_a[23:1]), - .cache_valid(prog_rom_data_valid), - .cache_data(prog_rom_data), - - // to rom controller - .rom_req(prog_cache_rom_cs), - .rom_addr(prog_cache_addr), - .rom_valid(prog_cache_valid), - .rom_data(prog_cache_data) -); - -tile_cache tile_cache -( - .reset(reset), - .clk(clk_sys), - - // client - .cache_req(tile_rom_cs), - .cache_addr(tile_rom_addr), - .cache_data(tile_rom_data), - .cache_valid(tile_rom_data_valid), - - // to rom controller - .rom_req(tile_cache_cs), - .rom_addr(tile_cache_addr), - .rom_data(tile_cache_data), - .rom_valid(tile_cache_valid) + .sp_addr ( 20'h80000 + sprite_rom_addr ), // (ioctl_addr >= 24'h200000) & (ioctl_addr < 24'h480000) + .sp_req ( sprite_rom_req ), + .sp_ack ( sprite_rom_ack ), + .sp_q ( sprite_rom_data ) ); endmodule @@ -1557,934 +1653,3 @@ always @(posedge clk_out) begin end endmodule - - - -//wire [15:0] cpu_tile_dout_attr; -//wire [15:0] cpu_tile_dout_num; -// -//wire [15:0] sprite_0_dout; -//wire [15:0] sprite_1_dout; -//wire [15:0] sprite_2_dout; -//wire [15:0] sprite_3_dout; -//wire [15:0] sprite_size_dout; -//wire [15:0] sprite_size_cpu_dout; -// -//wire [31:0] tile_attr_dout; -//wire [15:0] sprite_attr_0_dout; -//wire [15:0] sprite_attr_1_dout; -//wire [15:0] sprite_attr_2_dout; -//wire [15:0] sprite_attr_3_dout; -// -//wire [15:0] sprite_size_buf_dout; -//wire [15:0] sprite_attr_0_buf_dout; -//wire [15:0] sprite_attr_1_buf_dout; -//wire [15:0] sprite_attr_2_buf_dout; -//wire [15:0] sprite_attr_3_buf_dout; -// -//reg [15:0] sprite_buf_din; -// -//reg [14:0] tile; -// -//reg [7:0] sprite_num; -//reg [7:0] sprite_num_copy; -// -//reg [3:0] tile_draw_state; -// -//reg [2:0] layer; // 4 layers + 1 for initial background -// -//wire [14:0] tile_idx = tile_attr[14:0]; -//wire [3:0] tile_priority = tile_attr[31:28]; -//wire [5:0] tile_palette_idx = tile_attr[21:16]; -//wire tile_hidden = tile_attr[15]; -// -//reg [15:0] fb_dout; -//wire [15:0] tile_fb_out; -//wire [15:0] sprite_fb_out; -//reg [15:0] fb_din; -//reg [15:0] sprite_fb_din; -// -//reg tile_fb_w; -//reg sprite_fb_w; -//reg sprite_buf_w; -//reg sprite_size_buf_w; -// -//dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) tile_line_buffer ( -// .clock_a ( clk_sys ), -// .address_a ( tile_fb_addr_w ), -// .wren_a ( tile_fb_w ), -// .data_a ( fb_din ), -// .q_a ( ), -// -// .clock_b ( clk_sys ), -// .address_b ( fb_addr_r ), -// .wren_b ( 0 ), -//// .data_b ( ), -// .q_b ( tile_fb_out ) -//); -// -//dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) sprite_line_buffer ( -// .clock_a ( clk_sys ), -// .address_a ( sprite_fb_addr_w ), -// .wren_a ( sprite_fb_w ), -// .data_a ( sprite_fb_din ), -// .q_a ( ), -// -// .clock_b ( clk_sys ), -// .address_b ( fb_addr_r ), -// .wren_b ( 0 ), -//// .data_b ( ), -// .q_b ( sprite_fb_out ) -//); -// -//reg [9:0] x_ofs; -//reg [9:0] x; -// -//reg [9:0] y_ofs; -// -//// y needs to be one line ahaed of the visible line -//// render the first line at the end of the previous frame -//// this depends on the timing that the sprite list is valid -//// sprites values are copied at the start of vblank (line 240) -// -//// global offsets -//wire [9:0] x_ofs_dx = 495 + { ~layer[1:0], 1'b0 }; -//wire [9:0] y_ofs_dx = 257; -//wire [9:0] x_ofs_dx_flipped = 17 - { ~layer[1:0], 1'b0 }; -//wire [9:0] y_ofs_dx_flipped = 255; -// -//// calculate scrolling -//wire [9:0] tile_x_unflipped = scroll_x_latch[layer[1:0]] + x_ofs_dx; -//wire [9:0] tile_y_unflipped = scroll_y_latch[layer[1:0]] + y_ofs_dx + scroll_y_offset; -//wire [9:0] tile_x_flipped = 319 + scroll_x_latch[layer[1:0]] + x_ofs_dx_flipped; -//wire [9:0] tile_y_flipped = 239 + scroll_y_latch[layer[1:0]] + y_ofs_dx_flipped + scroll_y_offset; -// -//// reverse tiles when flipped -//wire [9:0] curr_x = tile_flip ? tile_x_flipped - x : tile_x_unflipped + x; -//wire [9:0] curr_y = tile_flip ? tile_y_flipped - y : tile_y_unflipped + y; -// -//reg [9:0] y; -//wire [9:0] y_flipped = ( sprite_flip ? (240 - y ) + scroll_y_offset : y + scroll_y_offset); -//wire [9:0] sprite_buf_x = sprite_flip ? 320 - (sprite_x + sprite_pos_x ) : sprite_x + sprite_pos_x; // offset from left of frame -// -//reg [3:0] draw_state; -//reg [3:0] sprite_state; -//reg [3:0] tile_copy_state; -//reg [3:0] sprite_copy_state; -// -//// pixel 4 bit colour -//wire [3:0] tile_pix; -//assign tile_pix = { tile_data[7-curr_x[2:0]], tile_data[15-curr_x[2:0]], tile_data[23-curr_x[2:0]], tile_data[31-curr_x[2:0]] }; -// -//wire [2:0] sprite_bit = sprite_x[2:0]; -//wire [3:0] sprite_pix; -//assign sprite_pix = { sprite_data[7-sprite_bit], sprite_data[15-sprite_bit], sprite_data[23-sprite_bit], sprite_data[31-sprite_bit] }; -// -//// two lines of buffer alternate -//reg [9:0] tile_fb_addr_w; -//wire [9:0] fb_addr_r = {vc[0], 9'b0 } + hc; -// -//reg [9:0] sprite_fb_addr_w; -// -//reg [31:0] tile_attr; -// -//// two lines worth for 4 layers (~8k) -//// [15:14] = layer. -//// [13:10] = prioity -//// [9:4] = palette offset -//// [3:0] = tile colour index. -// -//reg [3:0] tile_priority_buf [327:0]; -//reg [3:0] sprite_priority_buf [327:0]; -// -//reg [9:0] sprite_x; // offset from left side of sprite -//reg [9:0] sprite_y; -// -//wire [14:0] sprite_index = sprite_attr_0_buf_dout[14:0] /* synthesis keep */; -//wire sprite_hidden = sprite_attr_0_buf_dout[15] /* synthesis keep */; -// -//wire [5:0] sprite_pal_addr = sprite_attr_1_buf_dout[5:0] /* synthesis keep */; -//wire [5:0] sprite_size_addr = sprite_attr_1_buf_dout[11:6] /* synthesis keep */; -//wire [3:0] sprite_priority = sprite_attr_1_buf_dout[15:12] /* synthesis keep */; -// -//wire [9:0] sprite_pos_x = sprite_adj_x + (( sprite_attr_2_buf_dout[15:7] < 9'h180 ) ? sprite_attr_2_buf_dout[15:7] : ( sprite_attr_2_buf_dout[15:7] - 10'h200)); -//wire [9:0] sprite_pos_y = sprite_adj_y + (( sprite_attr_3_buf_dout[15:7] < 9'h180 ) ? sprite_attr_3_buf_dout[15:7] : ( sprite_attr_3_buf_dout[15:7] - 10'h200)); -// -//// valid 1 cycle after sprite attr ready -//wire [8:0] sprite_height = { sprite_size_buf_dout[7:4], 3'b0 } /* synthesis keep */; // in pixels -//wire [8:0] sprite_width = { sprite_size_buf_dout[3:0], 3'b0 } /* synthesis keep */; -// -//reg [7:0] sprite_buf_num; -// -//reg [1:0] vtotal_282_flag; -// -//always @ (posedge clk_sys) begin // Check System Vcount flag for 60Hz mode -// if ({crtc[2][7:0], 1'b1 } == 269) -// vtotal_282_flag <= 0; -// else -// vtotal_282_flag <= 1; -//end -// -//always @ (posedge clk_sys) begin -// if ( reset == 1 ) begin -// sprite_state <= 0; -// draw_state <= 0; -// sprite_rom_cs <= 0; -// tile_rom_cs <= 0; -// tile_copy_state <= 0; -// sprite_copy_state <= 0; -// tile_draw_state <= 0; -// end else begin -// // render sprites -// // triggered when the tile rendering starts -// if ( sprite_state == 0 && draw_state > 0 ) begin -// sprite_num <= 8'h00; -// sprite_x <= 0; -// sprite_fb_w <= 1; -// sprite_state <= 1; -// sprite_fb_din <= 0; -// sprite_fb_addr_w <= { y[0], 9'b0 }; -// end else if ( sprite_state == 1 ) begin -// // erase line buffer -// sprite_fb_addr_w <= { y[0], 9'b0 } + sprite_x; -// sprite_priority_buf[sprite_x] <= 0; -// if ( sprite_x < 320 ) begin -// sprite_x <= sprite_x + 1; -// end else begin -// sprite_x <= 0; -// sprite_fb_w <= 0; -// sprite_state <= 2; -// end -// end else if ( sprite_state == 2 ) begin -// // sprite num is valid now -// sprite_state <= 3; -// end else if ( sprite_state == 3 ) begin -// // sprite attr valid now. -// // delay one more cycle to read sprite size -// sprite_state <= 4; -// end else if ( sprite_state == 4 ) begin -// // start loop -// sprite_rom_cs <= 0; -// sprite_fb_w <= 0; -// sprite_y <= y_flipped - sprite_pos_y; -// // is sprite visible and is current y in sprite y range -// // sprite pos can be negative? -// if ( sprite_hidden == 0 && sprite_width > 0 && ( $signed(y_flipped) >= $signed(sprite_pos_y) ) && $signed(y_flipped) < ( $signed(sprite_pos_y) + $signed(sprite_height) ) ) begin -// sprite_state <= 5; -// end else if ( sprite_num < 8'hff ) begin -// sprite_num <= sprite_num + 1; -// sprite_state <= 2; -// end else begin -// sprite_state <= 15; -// end -// end else if ( sprite_state == 5 ) begin -// sprite_rom_addr <= { sprite_index, 3'b0 } + { sprite_x[8:3], 3'b0 } + ( sprite_y[8:3] * sprite_width ) + sprite_y[2:0]; -// sprite_rom_cs <= 1; -// sprite_state <= 6; -// end else if ( sprite_state == 6 ) begin -// // wait for sprite bitmap ready -// if ( sprite_rom_data_valid ) begin -// // latch data and deassert cs -// sprite_data <= sprite_rom_data; -// sprite_rom_cs <= 0; -// sprite_state <= 7; -// end -// end else if ( sprite_state == 7 ) begin -// sprite_fb_w <= 0; -// // draw if pixel value not zero and priority >= previous sprite data -//// if ( sprite_pix > 0 && sprite_priority_buf[sprite_buf_x] == 0 ) begin -//// if ( sprite_pix != 0 && ( sprite_priority == 0 || sprite_priority >= sprite_priority_buf[sprite_buf_x] ) ) begin -// if ( sprite_pix != 0 ) begin -// sprite_fb_din <= { 2'b11, sprite_priority, sprite_pal_addr, sprite_pix }; -//// if ( sprite_priority == 0 ) begin -//// sprite_priority_buf[sprite_buf_x] <= { 1'b1, sprite_priority }; -//// end else begin -// sprite_fb_addr_w <= { y[0], 9'b0 } + sprite_buf_x; -// sprite_priority_buf[sprite_buf_x] <= sprite_priority; -// sprite_fb_w <= 1; -// end -// if ( sprite_x < ( sprite_width - 1 ) ) begin -// sprite_x <= sprite_x + 1; -// if ( sprite_x[2:0] == 7 ) begin -// // do recalc bitmap address -// sprite_state <= 5; -// end -// end else if ( sprite_num < 8'hff ) begin -// sprite_num <= sprite_num + 1; -// sprite_x <= 0; -// // need to load new attributes and size -// sprite_state <= 2; -// end else begin -// // tile state machine will reset sprite_state when line completes. -// sprite_state <= 15; // done -// end -// end -// // copy tile ram and scroll info -// // not sure if this is needed. need to check to see when tile ram is updated. -// if ( tile_copy_state == 0 && vc == 256 ) begin -// tile_copy_state <= 1; -// end else begin -// // copy scroll registers -// scroll_x_latch[0] <= scroll_x[0] - scroll_ofs_x; -// scroll_x_latch[1] <= scroll_x[1] - scroll_ofs_x; -// scroll_x_latch[2] <= scroll_x[2] - scroll_ofs_x; -// scroll_x_latch[3] <= scroll_x[3] - scroll_ofs_x; -// scroll_y_latch[0] <= scroll_y[0] - scroll_ofs_y; -// scroll_y_latch[1] <= scroll_y[1] - scroll_ofs_y; -// scroll_y_latch[2] <= scroll_y[2] - scroll_ofs_y; -// scroll_y_latch[3] <= scroll_y[3] - scroll_ofs_y; -// end -// // copy sprite attr/size to buffer -// if ( sprite_copy_state == 0 && vc == 240 ) begin -// sprite_copy_state <= 1; -// sprite_buf_w <= 0; -// sprite_num_copy <= 8'h00; -// end else if ( sprite_copy_state == 1 ) begin -// sprite_num_copy <= sprite_num_copy + 1; -// sprite_buf_num <= sprite_num_copy; -// sprite_buf_w <= 1; -// // wait for read from source -// if ( sprite_num_copy == 8'hff ) begin -// sprite_copy_state <= 2; -// end -// end else if ( sprite_copy_state == 2 ) begin -// sprite_buf_w <= 0; -// sprite_copy_state <= 0; -// end -// // tile state machine -// if ( draw_state == 0 && vc == ({ crtc[2][7:0], 1'b1 } - (ntsc ? (vtotal_282_flag ? 5'd19 : 4'd7) : 3'd0)) ) begin // 282 Lines standard (263 Lines for 60Hz) -// layer <= 4; // layer 4 is layer 0 but draws hidden and transparent -// y <= 0; -// draw_state <= 2; -// sprite_state <= 0; -// end else if ( draw_state == 2 ) begin -// x <= 0; -// x_ofs <= scroll_x_latch[layer[1:0]]; -// y_ofs <= scroll_y_latch[layer[1:0]]; -// // latch offset info -// draw_state <= 3; -// tile_draw_state <= 0; -// end else if ( draw_state == 3 ) begin -// if ( tile_draw_state == 0 ) begin -// tile <= { layer[1:0], curr_y[8:3], curr_x[8:3] }; // works -// tile_draw_state <= 4'h1; -// end else if ( tile_draw_state == 1 ) begin -// tile_draw_state <= 2; -// end else if ( tile_draw_state == 2 ) begin -// // latch attribute -// tile_attr <= tile_attr_dout; -// if ( layer == 4 || tile_attr_dout[15] == 0 ) begin -// tile_draw_state <= 3; -// end else begin -// if ( x < 320 ) begin// 319 -// tile_draw_state <= 3; -// // do we need to read another tile? -// // last pixel of this tile changes based on flip direction -// if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin -// draw_state <= 3; -// tile_draw_state <= 0; -// end -// x <= x + 1; -// end else if ( layer > 0 ) begin -// layer <= layer - 1; -// tile_fb_w <= 0; -// draw_state <= 2; -// end else begin -// // done -// tile_draw_state <= 7; -// tile_fb_w <= 0; -// end -// end -// end else if ( tile_draw_state == 3 ) begin -// // read bitmap info -// tile_rom_cs <= 1; -// tile_rom_addr <= { tile_idx, curr_y[2:0] }; -// tile_draw_state <= 4; -// end else if ( tile_draw_state == 4 ) begin -// // wait for bitmap ram ready -// if ( tile_rom_data_valid ) begin -// // latch data and deassert cs -// tile_data <= tile_rom_data; -// tile_draw_state <= 5; -// tile_rom_cs <= 0; -// end -// end else if ( tile_draw_state == 5 ) begin -// tile_fb_w <= 0; -// tile_fb_addr_w <= { y[0], 9'b0 } + x; -// // force render of first layer. -// // if layer == 4 then tile_pix == 0 is not transparent -// // layer 4 is really layer 0 -// if ( layer == 4 ) begin -// tile_priority_buf[x] <= 0; //tile_pix == 0 ? 0 : tile_priority; -// //fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; -// fb_din <= { layer[1:0], 4'b0, tile_palette_idx, tile_pix }; -// tile_fb_w <= 1; -// end else if (tile_hidden == 0 && tile_pix > 0 && tile_priority > 0 && tile_priority >= tile_priority_buf[x] ) begin -// tile_priority_buf[x] <= tile_priority; -// // if tile hidden then make the pallette index 0. ie transparent -// fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; -// tile_fb_w <= 1; -// end -// if ( x < 320 ) begin// 319 -// // do we need to read another tile? -// // last pixel of this tile changes based on flip direction -// if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin -// draw_state <= 3; -// tile_draw_state <= 0; -// end -// x <= x + 1; -// end else if ( layer > 0 ) begin -// layer <= layer - 1; -// tile_fb_w <= 0; -// draw_state <= 2; -// end else begin -// // done -// tile_draw_state <= 7; -// tile_fb_w <= 0; -// end -// end else if ( tile_draw_state == 7 ) begin -// // wait for next line or quit -// if ( y == 239 ) begin -// draw_state <= 0; -// end else if ( hc == (ntsc ? 9'd444 : 9'd449) ) begin // 450 Lines standard (445 Lines for NTSC standard 15.73kHz line freq) -// y <= y + 1; -// draw_state <= 2; -// sprite_state <= 0; -// layer <= 4; -// end -// end -// end -// end -//end -// -//// render -//reg draw_sprite; -// -//// two lines worth for 4 layers (~8k) -//// [15:14] = layer. -//// [13:10] = prioity -//// [9:4] = palette offset -//// [3:0] = tile colour index. -// -//// there are 10 70MHz cycles per pixel. clk7_count from 0-9 -// -//// dac values based on 120 ohm driver for the resistor dac and 75 ohm output. 4.7k, 2.2k, 1k, 470, 220 -//// modeled in spice -//wire [7:0] dac [0:31] = '{0,12,25,36,50,61,73,83,91,100,111,120,131,139,149,157,145,154,162,170,180,187,195,202,208,214,222,228,236,242,249,255}; -// -//always @ (posedge clk_sys) begin -// if ( clk7_count == 4 ) begin -// tile_palette_addr <= tile_fb_out[9:0]; -// sprite_palette_addr <= sprite_fb_out[9:0]; -// end else if ( clk7_count == 6 ) begin -// // if palette index is zero then it's from layer 3 and is transparent render as blank (black). -// r <= dac[tile_palette_dout[4:0]]; -// g <= dac[tile_palette_dout[9:5]]; -// b <= dac[tile_palette_dout[14:10]]; -// -// // if not transparent and sprite is higher priority -// if ( sprite_fb_out[3:0] > 0 && (sprite_fb_out[13:10] > tile_fb_out[13:10]) ) begin -// // draw sprite -// r <= dac[sprite_palette_dout[4:0]]; -// g <= dac[sprite_palette_dout[9:5]]; -// b <= dac[sprite_palette_dout[14:10]]; -// end -// end -//end -// -//// tile data buffer -// -//reg tile_buf_w; -//reg [31:0] tile_buf_din; -//reg [31:0] tile_buf_dout; -//reg [13:0] tile_buf_addr; -// -//dual_port_ram #(.LEN(16384), .DATA_WIDTH(32)) ram_tile_buf ( -// .clock_a ( clk_sys ), -// .address_a ( tile[13:0] ), -// .wren_a ( tile_buf_w ), -// .data_a ( tile_attr_dout ), -// -// .clock_b ( clk_sys ), -// .address_b ( tile[13:0] ), // only read the tile # for now -// .wren_b ( 0 ), -// .q_b ( tile_buf_dout ) -//); -// -//// tile attribute ram. each tile attribute is 2 16bit words -//// pppp ---- --cc cccc httt tttt tttt tttt = Tile number (0 - $7fff) -//// indirect access through offset register -//dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_h ( -// .clock_a ( clk_10M ), -// .address_a ( curr_tile_ofs ), -// .wren_a ( tile_attr_cs & !cpu_rw ), -// .data_a ( cpu_dout ), -// .q_a ( cpu_tile_dout_attr ), -// -// .clock_b ( clk_sys ), -// .address_b ( tile[13:0] ), // only read the tile # for now -// .wren_b ( 0 ), -// .q_b ( tile_attr_dout[31:16] ) -//); -// -//dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_l ( -// .clock_a ( clk_10M ), -// .address_a ( curr_tile_ofs ), -// .wren_a ( tile_num_cs & !cpu_rw ), -// .data_a ( cpu_dout ), -// .q_a ( cpu_tile_dout_num ), -// -// .clock_b ( clk_sys ), -// .address_b ( tile[13:0] ), // only read the tile # for now -// .wren_b ( 0 ), -// .q_b ( tile_attr_dout[15:0] ) -//); -// -//// sprite attribute ram. each tile attribute is 4 16bit words -//// indirect access through offset register -//// split up so 64 bits can be read in a single clock -//dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_0 ( -// .clock_a ( clk_10M ), -// .address_a ( curr_sprite_ofs[9:2] ), -// .wren_a ( sprite_0_cs & !cpu_rw), -// .data_a ( cpu_dout ), -// .q_a ( sprite_0_dout ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_num_copy ), -// .wren_b ( 0 ), -// .q_b ( sprite_attr_0_dout[15:0] ) -//); -// -//dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_0_buf ( -// .clock_a ( clk_sys ), -// .address_a ( sprite_buf_num ), -// .wren_a ( sprite_buf_w ), -// .data_a ( sprite_attr_0_dout[15:0] ), -// .q_a ( ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_num ), -// .wren_b ( 0 ), -// .q_b ( sprite_attr_0_buf_dout[15:0] ) -//); -// -//dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_1 ( -// .clock_a ( clk_10M ), -// .address_a ( curr_sprite_ofs[9:2] ), -// .wren_a ( sprite_1_cs & !cpu_rw ), -// .data_a ( cpu_dout ), -// .q_a ( sprite_1_dout ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_num_copy ), -// .wren_b ( 0 ), -// .q_b ( sprite_attr_1_dout[15:0] ) -//); -// -//dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_1_buf ( -// .clock_a ( clk_sys ), -// .address_a ( sprite_buf_num ), -// .wren_a ( sprite_buf_w ), -// .data_a ( sprite_attr_1_dout[15:0] ), -// .q_a ( ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_num ), -// .wren_b ( 0 ), -// .q_b ( sprite_attr_1_buf_dout[15:0] ) -//); -// -//dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_2 ( -// .clock_a ( clk_10M ), -// .address_a ( curr_sprite_ofs[9:2] ), -// .wren_a ( sprite_2_cs & !cpu_rw ), -// .data_a ( cpu_dout ), -// .q_a ( sprite_2_dout ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_num_copy ), -// .wren_b ( 0 ), -// .q_b ( sprite_attr_2_dout[15:0] ) -//); -// -//dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_2_buf ( -// .clock_a ( clk_sys ), -// .address_a ( sprite_buf_num ), -// .wren_a ( sprite_buf_w ), -// .data_a ( sprite_attr_2_dout[15:0] ), -// .q_a ( ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_num ), -// .wren_b ( 0 ), -// .q_b ( sprite_attr_2_buf_dout[15:0] ) -//); -// -//dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_3 ( -// .clock_a ( clk_10M ), -// .address_a ( curr_sprite_ofs[9:2] ), -// .wren_a ( sprite_3_cs & !cpu_rw ), -// .data_a ( cpu_dout ), -// .q_a ( sprite_3_dout ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_num_copy ), -// .wren_b ( 0 ), -// .q_b ( sprite_attr_3_dout[15:0] ) -//); -// -//dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_3_buf ( -// .clock_a ( clk_sys ), -// .address_a ( sprite_buf_num ), -// .wren_a ( sprite_buf_w ), -// .data_a ( sprite_attr_3_dout[15:0] ), -// .q_a ( ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_num ), -// .wren_b ( 0 ), -// .q_b ( sprite_attr_3_buf_dout[15:0] ) -//); -// -//dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_size ( -// .clock_a ( clk_10M ), -// .address_a ( curr_sprite_ofs ), -// .wren_a ( sprite_size_cs & !cpu_rw), -// .data_a ( cpu_dout ), -// .q_a ( sprite_size_cpu_dout ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_num_copy ), -// .wren_b ( 0 ), -// .q_b ( sprite_size_dout ) -//); -// -//dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_size_buf ( -// .clock_a ( clk_sys ), -// .address_a ( sprite_buf_num ), -// .wren_a ( sprite_buf_w ), -// .data_a ( sprite_size_dout ), -// .q_a ( ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_size_addr ), -// .wren_b ( 0 ), -// .q_b ( sprite_size_buf_dout ) -//); -// -// -//// tiles 1024 15 bit values. index is ( 6 bits from tile attribute, 4 bits from bitmap ) -//// background palette ram low -//// does this need to be byte addressable? -//dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_l ( -// .clock_a ( clk_10M ), -// .address_a ( cpu_a[10:1] ), -// .wren_a ( tile_palette_cs & !cpu_rw & !cpu_lds_n), -// .data_a ( cpu_dout[7:0] ), -// .q_a ( tile_palette_cpu_dout[7:0] ), -// -// .clock_b ( clk_sys ), -// .address_b ( tile_palette_addr ), -// .wren_b ( 0 ), -// .q_b ( tile_palette_dout[7:0] ) -//); -// -//// background palette ram high -//dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_h ( -// .clock_a ( clk_10M ), -// .address_a ( cpu_a[10:1] ), -// .wren_a ( tile_palette_cs & !cpu_rw & !cpu_uds_n), -// .data_a ( cpu_dout[15:8] ), -// .q_a ( tile_palette_cpu_dout[15:8] ), -// -// .clock_b ( clk_sys ), -// .address_b ( tile_palette_addr ), -// .wren_b ( 0 ), -// .q_b ( tile_palette_dout[15:8] ) -//); -// -//// sprite palette ram low -//// does this need to be byte addressable? -//dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_l ( -// .clock_a ( clk_10M ), -// .address_a ( cpu_a[10:1] ), -// .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_lds_n), -// .data_a ( cpu_dout[7:0] ), -// .q_a ( sprite_palette_cpu_dout[7:0] ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_palette_addr ), -// .wren_b ( 0 ), -// .q_b ( sprite_palette_dout[7:0] ) -//); -// -//// background palette ram high -//dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_h ( -// .clock_a ( clk_10M ), -// .address_a ( cpu_a[10:1] ), -// .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_uds_n), -// .data_a ( cpu_dout[15:8] ), -// .q_a ( sprite_palette_cpu_dout[15:8] ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_palette_addr ), -// .wren_b ( 0 ), -// .q_b ( sprite_palette_dout[15:8] ) -//); -// -// -//// main 68k ram low -//dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_L ( -// .clock_a ( clk_10M ), -// .address_a ( cpu_a[14:1] ), -// .wren_a ( !cpu_rw & ram_cs & !cpu_lds_n ), -// .data_a ( cpu_dout[7:0] ), -// .q_a ( ram_dout[7:0] ) -// ); -// -//// main 68k ram high -//dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_H ( -// .clock_a ( clk_10M ), -// .address_a ( cpu_a[14:1] ), -// .wren_a ( !cpu_rw & ram_cs & !cpu_uds_n ), -// .data_a ( cpu_dout[15:8] ), -// .q_a ( ram_dout[15:8] ) -//); -// -// -////wire [15:0] z80_shared_addr = z80_addr - 16'h8000; -////wire [23:0] m68k_shard_addr = cpu_a - 24'h040000; -// -//// z80 and 68k shared ram -//// 4k -//dual_port_ram #(.LEN(32768), .DATA_WIDTH(8)) shared_ram -//( -// .clock_a ( clk_10M ), -// .address_a ( cpu_a[12:1] ), -// .wren_a ( shared_ram_cs & !cpu_rw & !cpu_lds_n), -// .data_a ( cpu_dout[7:0] ), -// .q_a ( cpu_shared_dout[7:0] ), -// -// .clock_b ( clk_3_5M ), // z80 clock is 3.5M -// .address_b ( z80_addr[14:0] ), -// .data_b ( z80_dout ), -// .wren_b ( sound_ram_1_cs & ~z80_wr_n ), -// .q_b ( z80_shared_dout ) -//); -// -//reg [11:0] sprite_rb_addr; -//wire [15:0] sprite_rb_dout; -// -//dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) sprite_ram_rb_l ( -// .clock_a ( clk_10M ), -// .address_a ( cpu_a[12:1] ), -// .wren_a ( sprite_ram_cs & !cpu_rw & !cpu_lds_n), -// .data_a ( cpu_dout[7:0] ), -// .q_a ( ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_rb_addr ), -// .wren_b ( 0 ), -// .q_b ( sprite_rb_dout[7:0] ) -//); -// -//dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) sprite_ram_rb_h ( -// .clock_a ( clk_10M ), -// .address_a ( cpu_a[12:1] ), -// .wren_a ( sprite_ram_cs & !cpu_rw & !cpu_uds_n), -// .data_a ( cpu_dout[15:8] ), -// .q_a ( ), -// -// .clock_b ( clk_sys ), -// .address_b ( sprite_rb_addr ), -// .wren_b ( 0 ), -// .q_b ( sprite_rb_dout[15:8] ) -//); -// -//reg [22:0] sdram_addr; -//reg [31:0] sdram_data; -//reg sdram_we; -//reg sdram_req; -// -//wire sdram_ack; -//wire sdram_valid; -//wire [31:0] sdram_q; -// -////sdram #(.CLK_FREQ(70.0)) sdram -////( -//// .reset(~pll_locked), -//// .clk(clk_sys), -//// -//// // controller interface -//// .addr(sdram_addr), -//// .data(sdram_data), -//// .we(sdram_we), -//// .req(sdram_req), -//// -//// .ack(sdram_ack), -//// .valid(sdram_valid), -//// .q(sdram_q), -//// -//// // SDRAM interface -//// .sdram_a(SDRAM_A), -//// .sdram_ba(SDRAM_BA), -//// .sdram_dq(SDRAM_DQ), -//// .sdram_cke(SDRAM_CKE), -//// .sdram_cs_n(SDRAM_nCS), -//// .sdram_ras_n(SDRAM_nRAS), -//// .sdram_cas_n(SDRAM_nCAS), -//// .sdram_we_n(SDRAM_nWE), -//// .sdram_dqml(SDRAM_DQML), -//// .sdram_dqmh(SDRAM_DQMH) -////); -// -//wire prog_cache_rom_cs; -//wire [22:0] prog_cache_addr; -//wire [15:0] prog_cache_data; -//wire prog_cache_valid; -// -//wire [15:0] prog_rom_data; -//wire prog_rom_data_valid; -// -//reg tile_rom_cs; -//reg [17:0] tile_rom_addr; -//wire [31:0] tile_rom_data; -//wire tile_rom_data_valid; -// -//wire tile_cache_cs; -//wire [17:0] tile_cache_addr; -//wire [31:0] tile_cache_data; -//wire tile_cache_valid; -// -//reg [31:0] tile_data; -// -//wire sprite_rom_cs; -//wire [18:0] sprite_rom_addr; -//wire [31:0] sprite_rom_data; -//wire sprite_rom_data_valid; -// -//reg [31:0] sprite_data; -// -//wire [15:0] sound_rom_1_addr; -//wire [7:0] sound_rom_1_data; -//wire sound_rom_1_data_valid; -// -//// sdram priority based rom controller -//// is a oe needed? -//rom_controller rom_controller -//( -// .reset(reset), -// -// // clock -// .clk(clk_sys), -// -// // program ROM interface -// .prog_rom_cs(prog_cache_rom_cs), -// .prog_rom_oe(1), -// .prog_rom_addr(prog_cache_addr), -// .prog_rom_data(prog_cache_data), -// .prog_rom_data_valid(prog_cache_valid), -// -// // character ROM interface -// .tile_rom_cs(tile_cache_cs), -// .tile_rom_oe(1), -// .tile_rom_addr(tile_cache_addr), -// .tile_rom_data(tile_cache_data), -// .tile_rom_data_valid(tile_cache_valid), -// -// -// // sprite ROM interface -// .sprite_rom_cs(sprite_rom_cs), -// .sprite_rom_oe(1), -// .sprite_rom_addr(sprite_rom_addr), -// .sprite_rom_data(sprite_rom_data), -// .sprite_rom_data_valid(sprite_rom_data_valid), -// -// // sound ROM #1 interface -// .sound_rom_1_cs(sound_rom_1_cs), -// .sound_rom_1_oe(1), -// .sound_rom_1_addr(z80_addr), -// .sound_rom_1_data(sound_rom_1_data), -// .sound_rom_1_data_valid(sound_rom_1_data_valid), -// -// // IOCTL interface -// .ioctl_addr(ioctl_addr), -// .ioctl_data(ioctl_dout), -// .ioctl_index(ioctl_index), -// .ioctl_wr(ioctl_wr), -// .ioctl_download(ioctl_download), -// -// // SDRAM interface -// .sdram_addr(sdram_addr), -// .sdram_data(sdram_data), -// .sdram_we(sdram_we), -// .sdram_req(sdram_req), -// .sdram_ack(sdram_ack), -// .sdram_valid(sdram_valid), -// .sdram_q(sdram_q) -//); -// -// -//cache prog_cache -//( -// .reset(reset), -// .clk(clk_sys), -// -// // client -// .cache_req(prog_rom_cs), -// .cache_addr(cpu_a[23:1]), -// .cache_valid(prog_rom_data_valid), -// .cache_data(prog_rom_data), -// -// // to rom controller -// .rom_req(prog_cache_rom_cs), -// .rom_addr(prog_cache_addr), -// .rom_valid(prog_cache_valid), -// .rom_data(prog_cache_data) -//); -// -//tile_cache tile_cache -//( -// .reset(reset), -// .clk(clk_sys), -// -// // client -// .cache_req(tile_rom_cs), -// .cache_addr(tile_rom_addr), -// .cache_data(tile_rom_data), -// .cache_valid(tile_rom_data_valid), -// -// // to rom controller -// .rom_req(tile_cache_cs), -// .rom_addr(tile_cache_addr), -// .rom_data(tile_cache_data), -// .rom_valid(tile_cache_valid) -//); -// -//endmodule -// -// -//module cc_shifter -//( -// input clk_out, -// input i, -// output o -//); -// -//// We use a two-stages shift-register to synchronize SignalIn_clkA to the clkB clock domain -//reg [1:0] r; -// -//assign o = r[1]; // new signal synchronized to (=ready to be used in) clkB domain -// -//always @(posedge clk_out) begin -// r[0] <= i; -// r[1] <= r[0]; // notice that we use clkB -//end -// -//endmodule - - - - - diff --git a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_zerowing/zerowing.sv b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_zerowing/zerowing.sv index 2fba241f..6d83db2b 100644 --- a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_zerowing/zerowing.sv +++ b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_zerowing/zerowing.sv @@ -1,4 +1,5 @@ //============================================================================ +// Toaplan Hardware v1 HW top-level for MiST // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free @@ -13,2026 +14,283 @@ // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// //============================================================================ -`default_nettype none +module Zerowing( + output LED, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B, + output VGA_HS, + output VGA_VS, + output AUDIO_L, + output AUDIO_R, + input SPI_SCK, + inout SPI_DO, + input SPI_DI, + input SPI_SS2, + input SPI_SS3, + input SPI_SS4, + input CONF_DATA0, + input CLOCK_27, -module emu -( - //Master input clock - input CLK_50M, - - //Async reset from top-level module. - //Can be used as initial reset. - input RESET, - - //Must be passed to hps_io module - inout [48:0] HPS_BUS, - - //Base video clock. Usually equals to CLK_SYS. - output CLK_VIDEO, - - //Multiple resolutions are supported using different CE_PIXEL rates. - //Must be based on CLK_VIDEO - output CE_PIXEL, - - //Video aspect ratio for HDMI. Most retro systems have ratio 4:3. - //if VIDEO_ARX[12] or VIDEO_ARY[12] is set then [11:0] contains scaled size instead of aspect ratio. - output [12:0] VIDEO_ARX, - output [12:0] VIDEO_ARY, - - output [7:0] VGA_R, - output [7:0] VGA_G, - output [7:0] VGA_B, - output VGA_HS, - output VGA_VS, - output VGA_DE, // = ~(VBlank | HBlank) - output VGA_F1, - output [2:0] VGA_SL, - output VGA_SCALER, // Force VGA scaler - - input [11:0] HDMI_WIDTH, - input [11:0] HDMI_HEIGHT, - output HDMI_FREEZE, - -`ifdef MISTER_FB - // Use framebuffer in DDRAM (USE_FB=1 in qsf) - // FB_FORMAT: - // [2:0] : 011=8bpp(palette) 100=16bpp 101=24bpp 110=32bpp - // [3] : 0=16bits 565 1=16bits 1555 - // [4] : 0=RGB 1=BGR (for 16/24/32 modes) - // - // FB_STRIDE either 0 (rounded to 256 bytes) or multiple of pixel size (in bytes) - output FB_EN, - output [4:0] FB_FORMAT, - output [11:0] FB_WIDTH, - output [11:0] FB_HEIGHT, - output [31:0] FB_BASE, - output [13:0] FB_STRIDE, - input FB_VBL, - input FB_LL, - output FB_FORCE_BLANK, - -`ifdef MISTER_FB_PALETTE - // Palette control for 8bit modes. - // Ignored for other video modes. - output FB_PAL_CLK, - output [7:0] FB_PAL_ADDR, - output [23:0] FB_PAL_DOUT, - input [23:0] FB_PAL_DIN, - output FB_PAL_WR, -`endif -`endif - - output LED_USER, // 1 - ON, 0 - OFF. - - // b[1]: 0 - LED status is system status OR'd with b[0] - // 1 - LED status is controled solely by b[0] - // hint: supply 2'b00 to let the system control the LED. - output [1:0] LED_POWER, - output [1:0] LED_DISK, - - // I/O board button press simulation (active high) - // b[1]: user button - // b[0]: osd button - output [1:0] BUTTONS, - - //Audio - input CLK_AUDIO, // 24.576 MHz - output [15:0] AUDIO_L, - output [15:0] AUDIO_R, - output AUDIO_S, // 1 - signed audio samples, 0 - unsigned - output [1:0] AUDIO_MIX, // 0 - no mix, 1 - 25%, 2 - 50%, 3 - 100% (mono) - - //ADC - inout [3:0] ADC_BUS, - - //SD-SPI - output SD_SCK, - output SD_MOSI, - input SD_MISO, - output SD_CS, - input SD_CD, - - //High latency DDR3 RAM interface - //Use for non-critical time purposes - output DDRAM_CLK, - input DDRAM_BUSY, - output [7:0] DDRAM_BURSTCNT, - output [28:0] DDRAM_ADDR, - input [63:0] DDRAM_DOUT, - input DDRAM_DOUT_READY, - output DDRAM_RD, - output [63:0] DDRAM_DIN, - output [7:0] DDRAM_BE, - output DDRAM_WE, - - //SDRAM interface with lower latency - output SDRAM_CLK, - output SDRAM_CKE, - output [12:0] SDRAM_A, - output [1:0] SDRAM_BA, - inout [15:0] SDRAM_DQ, - output SDRAM_DQML, - output SDRAM_DQMH, - output SDRAM_nCS, - output SDRAM_nCAS, - output SDRAM_nRAS, - output SDRAM_nWE, - -`ifdef MISTER_DUAL_SDRAM - //Secondary SDRAM - //Set all output SDRAM_* signals to Z ASAP if SDRAM2_EN is 0 - input SDRAM2_EN, - output SDRAM2_CLK, - output [12:0] SDRAM2_A, - output [1:0] SDRAM2_BA, - inout [15:0] SDRAM2_DQ, - output SDRAM2_nCS, - output SDRAM2_nCAS, - output SDRAM2_nRAS, - output SDRAM2_nWE, -`endif - - input UART_CTS, - output UART_RTS, - input UART_RXD, - output UART_TXD, - output UART_DTR, - input UART_DSR, - -`ifdef MISTER_ENABLE_YC - output [39:0] CHROMA_PHASE_INC, - output YC_EN, - output PALFLAG, -`endif - - // Open-drain User port. - // 0 - D+/RX - // 1 - D-/TX - // 2..6 - USR2..USR6 - // Set USER_OUT to 1 to read from USER_IN. - input [6:0] USER_IN, - output [6:0] USER_OUT, - - input OSD_STATUS + output [12:0] SDRAM_A, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nWE, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nCS, + output [1:0] SDRAM_BA, + output SDRAM_CLK, + output SDRAM_CKE ); -///////// Default values for ports not used in this core ///////// +`include "../build_id.v" +//`include "defs.v" -assign ADC_BUS = 'Z; -assign USER_OUT = 0; -assign {UART_RTS, UART_TXD, UART_DTR} = 0; -assign {SD_SCK, SD_MOSI, SD_CS} = 'Z; -//assign {SDRAM_DQ, SDRAM_A, SDRAM_BA, SDRAM_CLK, SDRAM_CKE, SDRAM_DQML, SDRAM_DQMH, SDRAM_nWE, SDRAM_nCAS, SDRAM_nRAS, SDRAM_nCS} = 'Z; -//assign {DDRAM_CLK, DDRAM_BURSTCNT, DDRAM_ADDR, DDRAM_DIN, DDRAM_BE, DDRAM_RD, DDRAM_WE} = '0; -assign VGA_F1 = 0; -assign VGA_SCALER = 0; -assign HDMI_FREEZE = 0; +`define CORE_NAME "Zerowing" +assign LED = ~ioctl_downl; +assign SDRAM_CLK = clk_72; +assign SDRAM_CKE = 1; -assign AUDIO_MIX = 0; -assign LED_USER = ioctl_download & cpu_a[0]; -assign LED_DISK = 0; -assign LED_POWER = 0; -assign BUTTONS = 0; - -// Status Bit Map: -// Upper Case Lower Case -// 0 1 2 3 4 5 6 -// 01234567890123456789012345678901 23456789012345678901234567890123 -// 0123456789ABCDEFGHIJKLMNOPQRSTUV 0123456789ABCDEFGHIJKLMNOPQRSTUV -// X XXXXXXXXXXX X X XXXXXXXX XX XX XXXXXXXX - -wire [1:0] aspect_ratio = status[9:8]; -wire orientation = ~status[3]; -wire [2:0] scan_lines = status[6:4]; -reg refresh_mod; -reg new_vmode; - -always @(posedge clk_sys) begin - if (refresh_mod != status[19]) begin - refresh_mod <= status[19]; - new_vmode <= ~new_vmode; - end -end - -wire [3:0] hs_offset = status[27:24]; -wire [3:0] vs_offset = status[31:28]; -wire [3:0] hs_width = status[59:56]; -wire [3:0] vs_width = status[63:60]; - -assign VIDEO_ARX = (!aspect_ratio) ? (orientation ? 8'd4 : 8'd3) : (aspect_ratio - 1'd1); -assign VIDEO_ARY = (!aspect_ratio) ? (orientation ? 8'd3 : 8'd4) : 12'd0; - -`include "build_id.v" localparam CONF_STR = { - "Toaplan V1;;", - "-;", - "P1,Video Settings;", - "P1-;", - "P1O89,Aspect Ratio,Original,Full Screen,[ARC1],[ARC2];", - "P1O3,Orientation,Horz,Vert;", - "P1-;", - "P1O46,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%,CRT 75%,CRT 100%;", - "P1OA,Force Scandoubler,Off,On;", - "P1-;", - "P1O7,Video Mode,NTSC,PAL;", - "P1OM,Video Signal,RGBS/YPbPr,Y/C;", - "P1OJ,Refresh Rate,Native,NTSC;", - "P1-;", - "P1OOR,H-sync Pos Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", - "P1OSV,V-sync Pos Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", - "P1-;", - "P1oOR,H-sync Width Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", - "P1oSV,V-sync Width Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", - "P1-;", - "P2,Audio Settings;", - "P2-;", - "P2oBC,OPL2 Volume,Default,50%,25%,0%;", - "P2-;", - "-;", - "P3,Core Options;", - "P3-;", - "P3o6,Swap P1/P2 Joystick,Off,On;", - "P3-;", - "P3OF,68k Freq.,10Mhz,17.5MHz;", - "P3-;", - "P3o0,Scroll Debug,Off,On;", - "P3-;", - "DIP;", - "-;", - "OK,Pause OSD,Off,When Open;", - "OL,Dim Video,Off,10s;", - "-;", - "R0,Reset;", - "V,v",`BUILD_DATE + `CORE_NAME, ";;", + "O2,Rotate Controls,Off,On;", + "O34,Scanlines,Off,25%,50%,75%;", + "O5,Blending,Off,On;", + "O6,Joystick Swap,Off,On;", + "DIP;", + "T0,Reset;", + "V,v1.20.",`BUILD_DATE }; -wire hps_forced_scandoubler; -wire forced_scandoubler = hps_forced_scandoubler | status[10]; +wire rotate = status[2]; +wire [1:0] scanlines = status[4:3]; +wire blend = status[5]; +wire joyswap = status[6]; -wire [1:0] buttons; -wire [63:0] status; -wire [10:0] ps2_key; -wire [15:0] joy0, joy1; +wire [7:0] dsw1 = status[23:16]; +wire [7:0] dsw2 = status[31:24]; +reg [7:0] dsw_m68k, dsw_sp85; +reg [7:0] p1, p2; +wire flipped; +wire key_service = m_fire1[4]; +wire key_test = m_fire1[3]; -hps_io #(.CONF_STR(CONF_STR)) hps_io -( - .clk_sys(clk_sys), - .HPS_BUS(HPS_BUS), - .buttons(buttons), - .ps2_key(ps2_key), - .status(status), - .status_menumask(direct_video), - .forced_scandoubler(hps_forced_scandoubler), - .gamma_bus(gamma_bus), - .new_vmode(new_vmode), - .direct_video(direct_video), - .video_rotated(video_rotated), - - .ioctl_download(ioctl_download), - .ioctl_upload(ioctl_upload), - .ioctl_wr(ioctl_wr), - .ioctl_addr(ioctl_addr), - .ioctl_dout(ioctl_dout), - .ioctl_din(ioctl_din), - .ioctl_index(ioctl_index), - .ioctl_wait(ioctl_wait), - - .joystick_0(joy0), - .joystick_1(joy1) -); - -// INPUT - -// 8 dip switches of 8 bits -reg [7:0] sw[8]; -always @(posedge clk_sys) begin - if (ioctl_wr && (ioctl_index==254) && !ioctl_addr[24:3]) begin - sw[ioctl_addr[2:0]] <= ioctl_dout; - end -end - -always @(posedge clk_sys) begin - if (ioctl_wr && ioctl_index==1) begin - pcb <= ioctl_dout; - end -end - -wire direct_video; - -wire ioctl_download; -wire ioctl_upload; -wire ioctl_upload_req; -wire ioctl_wait; -wire ioctl_wr; -wire [15:0] ioctl_index; -wire [26:0] ioctl_addr; -wire [15:0] ioctl_dout; -wire [15:0] ioctl_din; - -reg [3:0] pcb; -wire tile_priority_type; -wire [15:0] scroll_y_offset; - -localparam pcb_zero_wing = 0; -localparam pcb_out_zone_conv = 1; -localparam pcb_out_zone = 2; -localparam pcb_hellfire = 3; -localparam pcb_truxton = 4; - -wire [21:0] gamma_bus; - -// -// Inputs tied to z80_din -reg [7:0] p1; -reg [7:0] p2; -reg [7:0] z80_dswa; -reg [7:0] z80_dswb; -reg [7:0] z80_tjump; -reg [7:0] system; - -always @ ( posedge clk_sys ) begin - p1 <= { 1'b0, p1_buttons[2:0], p1_right, p1_left, p1_down, p1_up }; - p2 <= { 1'b0, p2_buttons[2:0], p2_right, p2_left, p2_down, p2_up }; - z80_tjump <= sw[2]; - - if ( pcb == 0 || pcb == 1 || pcb == 2 || pcb == 3 && status[32] == 1 ) begin - // zerowing, hellfire, outzone, outzone conversion debug options - z80_dswa <= sw[0]; - z80_dswb <= { sw[1][7], sw[1][6] | status[32], sw[1][5:0] }; - system <= { vbl, start2 | p1_buttons[3], start1 | p1_buttons[3], coin_b, coin_a, service, key_tilt, key_service }; - end else if ( pcb == 4 && status[32] == 1 ) begin - // truxton debug options - z80_dswa <= { sw[0][7:3], sw[0][2] | status[32], sw[0][1:0] }; - z80_dswb <= sw[1]; - system <= { vbl, start2, start1, coin_b, coin_a, service, key_tilt, key_service }; - end else begin - // default - z80_dswa <= sw[0]; - z80_dswb <= sw[1]; - system <= { vbl, start2, start1, coin_b, coin_a, service, key_tilt, key_service }; - end -end - -reg p1_swap; - -reg p1_right; -reg p1_left; -reg p1_down; -reg p1_up; -reg [3:0] p1_buttons; - -reg p2_right; -reg p2_left; -reg p2_down; -reg p2_up; -reg [3:0] p2_buttons; - -reg start1; -reg start2; -reg coin_a; -reg coin_b; -reg b_pause; -reg service; - -always @ * begin - p1_swap <= status[38]; - - if ( status[38] == 0 ) begin - p1_right <= joy0[0] | key_p1_right; - p1_left <= joy0[1] | key_p1_left; - p1_down <= joy0[2] | key_p1_down; - p1_up <= joy0[3] | key_p1_up; - p1_buttons <= joy0[7:4] | {key_p1_c, key_p1_b, key_p1_a}; - - p2_right <= joy1[0] | key_p2_right; - p2_left <= joy1[1] | key_p2_left; - p2_down <= joy1[2] | key_p2_down; - p2_up <= joy1[3] | key_p2_up; - p2_buttons <= joy1[7:4] | {key_p2_c, key_p2_b, key_p2_a}; - end else begin - p2_right <= joy0[0] | key_p1_right; - p2_left <= joy0[1] | key_p1_left; - p2_down <= joy0[2] | key_p1_down; - p2_up <= joy0[3] | key_p1_up; - p2_buttons <= joy0[7:4] | {key_p1_c, key_p1_b, key_p1_a}; - - p1_right <= joy1[0] | key_p2_right; - p1_left <= joy1[1] | key_p2_left; - p1_down <= joy1[2] | key_p2_down; - p1_up <= joy1[3] | key_p2_up; - p1_buttons <= joy1[7:4] | {key_p2_c, key_p2_b, key_p2_a}; - end -end - -always @ * begin - start1 <= joy0[8] | joy1[8] | key_start_1p; - start2 <= joy0[9] | joy1[9] | key_start_2p; - - coin_a <= joy0[10] | joy1[10] | key_coin_a; - coin_b <= joy0[11] | joy1[11] | key_coin_b; - - b_pause <= joy0[12] | key_pause; - service <= key_test; -end - -// Keyboard handler - -reg key_start_1p, key_start_2p, key_coin_a, key_coin_b; -reg key_tilt, key_test, key_reset, key_service, key_pause; - -reg key_p1_up, key_p1_left, key_p1_down, key_p1_right, key_p1_a, key_p1_b, key_p1_c; -reg key_p2_up, key_p2_left, key_p2_down, key_p2_right, key_p2_a, key_p2_b, key_p2_c; - -wire pressed = ps2_key[9]; - -always @(posedge clk_sys) begin - reg old_state; - old_state <= ps2_key[10]; - if ( old_state ^ ps2_key[10] ) begin - casex ( ps2_key[8:0] ) - 'h016 : key_start_1p <= pressed; // 1 - 'h01E : key_start_2p <= pressed; // 2 - 'h02E : key_coin_a <= pressed; // 5 - 'h036 : key_coin_b <= pressed; // 6 - 'h006 : key_test <= key_test ^ pressed; // f2 - 'h004 : key_reset <= pressed; // f3 - 'h046 : key_service <= pressed; // 9 - 'h02C : key_tilt <= pressed; // t - 'h04D : key_pause <= pressed; // p - - 'h175 : key_p1_up <= pressed; // up - 'h172 : key_p1_down <= pressed; // down - 'h16B : key_p1_left <= pressed; // left - 'h174 : key_p1_right <= pressed; // right - 'h014 : key_p1_a <= pressed; // lctrl - 'h011 : key_p1_b <= pressed; // lalt - 'h029 : key_p1_c <= pressed; // spacebar - - 'h02D : key_p2_up <= pressed; // r - 'h02B : key_p2_down <= pressed; // f - 'h023 : key_p2_left <= pressed; // d - 'h034 : key_p2_right <= pressed; // g - 'h01C : key_p2_a <= pressed; // a - 'h01B : key_p2_b <= pressed; // s - 'h015 : key_p2_c <= pressed; // q - endcase - end -end +wire clk_72; wire pll_locked; +pll_mist pll( + .inclk0(CLOCK_27), + .c0(clk_72), + .locked(pll_locked) + ); -wire clk_sys; -wire turbo_68k = status[15]; -reg clk_3_5M, clk_7M, clk_10M, clk_14M; - -wire clk_70M; - -pll pll -( - .refclk(CLK_50M), - .rst(0), - .outclk_0(clk_sys), - .outclk_1(clk_70M), - .locked(pll_locked) -); - -assign SDRAM_CLK = clk_70M; - -localparam CLKSYS=70; - -reg [5:0] clk14_count; -reg [5:0] clk10_count; -reg [5:0] clk7_count; -reg [5:0] clk_3_5_count; - -always @ (posedge clk_sys ) begin - clk_10M <= 0; - if ( turbo_68k == 0 ) begin - // standard speed 20MHz = 10MHz 68k - case (clk10_count) - 1: clk_10M <= 1; - 3: clk_10M <= 1; - endcase - if ( clk10_count == 6 ) begin - clk10_count <= 0; - end else if ( pause_cpu == 0 ) begin - clk10_count <= clk10_count + 1; - end - end else begin - // standard speed 35MHz = 17.5MHz 68k - case (clk10_count) - 1: clk_10M <= 1; - endcase - if ( clk10_count == 1 ) begin - clk10_count <= 0; - end else if ( pause_cpu == 0 ) begin - clk10_count <= clk10_count + 1; - end - end - clk_7M <= ( clk7_count == 0); - if ( clk7_count == 9 ) begin - clk7_count <= 0; - end else begin - clk7_count <= clk7_count + 1; - end - clk_14M <= ( clk14_count == 0); - if ( clk14_count == 4 ) begin - clk14_count <= 0; - end else begin - clk14_count <= clk14_count + 1; - end - clk_3_5M <= ( clk_3_5_count == 0); - if ( clk_3_5_count == 19 ) begin - clk_3_5_count <= 0; - end else if ( pause_cpu == 0 ) begin - clk_3_5_count <= clk_3_5_count + 1; - end +// reset generation +reg reset = 1; +reg rom_loaded = 0; +always @(posedge clk_72) begin + reg ioctl_downlD; + ioctl_downlD <= ioctl_downl; + if (ioctl_downlD & ~ioctl_downl) rom_loaded <= 1; + reset <= status[0] | buttons[1] | ~rom_loaded | ioctl_downl; end -wire reset; -assign reset = RESET | status[0] | (ioctl_download & !ioctl_index) | buttons[1] | key_reset; +// ARM connection +wire [63:0] status; +wire [1:0] buttons; +wire [1:0] switches; +wire [31:0] joystick_0; +wire [31:0] joystick_1; +wire scandoublerD; +wire ypbpr; +wire no_csync; +wire key_strobe; +wire key_pressed; +wire [7:0] key_code; +wire [6:0] core_mod; -////////////////////////////////////////////////////////////////// -wire rotate_ccw = 1; -wire no_rotate = orientation | direct_video; -wire video_rotated; +user_io #( + .STRLEN($size(CONF_STR)>>3), + .ROM_DIRECT_UPLOAD(1)) +user_io( + .clk_sys (clk_72 ), + .conf_str (CONF_STR ), + .SPI_CLK (SPI_SCK ), + .SPI_SS_IO (CONF_DATA0 ), + .SPI_MISO (SPI_DO ), + .SPI_MOSI (SPI_DI ), + .buttons (buttons ), + .switches (switches ), + .scandoubler_disable (scandoublerD ), + .ypbpr (ypbpr ), + .no_csync (no_csync ), + .core_mod (core_mod ), + .key_strobe (key_strobe ), + .key_pressed (key_pressed ), + .key_code (key_code ), + .joystick_0 (joystick_0 ), + .joystick_1 (joystick_1 ), + .status (status ) + ); -reg [23:0] rgb; +wire ioctl_downl; +wire [7:0] ioctl_index; +wire ioctl_wr; +wire [24:0] ioctl_addr; +wire [7:0] ioctl_dout; -wire hbl; -wire vbl; - -wire [8:0] hc; -wire [8:0] vc; - -wire hsync; -wire vsync; - -reg hbl_delay, vbl_delay; - -always @ ( posedge clk_7M ) begin - hbl_delay <= hbl; - vbl_delay <= vbl; -end - -video_timing video_timing ( - .clk(clk_7M), - .reset(reset), - .crtc0(crtc[0]), - .crtc1(crtc[1]), - .crtc2(crtc[2]), - .crtc3(crtc[3]), - .hs_offset(hs_offset), - .vs_offset(vs_offset), - .hs_width(hs_width), - .vs_width(vs_width), - .refresh_mod(refresh_mod), - .hc(hc), - .vc(vc), - .hbl_delay(hbl), - .vbl(vbl), - .hsync(hsync), - .vsync(vsync) +data_io #(.ROM_DIRECT_UPLOAD(1)) data_io( + .clk_sys ( clk_72 ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS2 ( SPI_SS2 ), + .SPI_SS4 ( SPI_SS4 ), + .SPI_DI ( SPI_DI ), + .SPI_DO ( SPI_DO ), + .ioctl_download( ioctl_downl ), + .ioctl_index ( ioctl_index ), + .ioctl_wr ( ioctl_wr ), + .ioctl_addr ( ioctl_addr ), + .ioctl_dout ( ioctl_dout ) ); -// PAUSE SYSTEM -wire pause_cpu; -wire hs_pause; +wire [15:0] laudio, raudio; +wire hs, vs; +wire blankn = ~(hb | vb); +wire hb, vb; +wire [4:0] r,b,g; -// 8 bits per colour, 70MHz sys clk -pause #(8,8,8,70) pause -( - .clk_sys(clk_sys), - .reset(reset), - .user_button(b_pause), - .pause_request(hs_pause), - .options(status[21:20]), - .pause_cpu(pause_cpu), - .dim_video(dim_video), - .OSD_STATUS(OSD_STATUS), - .r(rgb[23:16]), - .g(rgb[15:8]), - .b(rgb[7:0]), - .rgb_out(rgb_pause_out) +Zerowing_Top Zerowing_Top( + .pll_locked ( pll_locked ), + .clk_sys ( clk_72 ), + .reset ( reset ), + .turbo_68k (0),//cpu_turbo + .pause_cpu (0), +// input scrollDBG, + .p1_right (m_right1), + .p1_left (m_left1), + .p1_down (m_down1), + .p1_up (m_up1), + .p1_buttons (m_fire1[3:0]), + .p2_right (m_right2), + .p2_left (m_left2), + .p2_down (m_down2), + .p2_up (m_up2), + .p2_buttons (m_fire2[3:0]), + .start1 (m_one_player), + .start2 (m_two_players), + .coin_a (m_coin1), + .coin_b (m_coin2), + .b_pause (), + .service (), + .key_tilt (m_tilt), + .key_service (), + .sw0 (), + .sw1 (), + .sw2 (), + + .hblank ( hb ), + .vblank ( vb ), + .hsync ( hs ), + .vsync ( vs ), + .r ( r ), + .g ( g ), + .b ( b ), + .hs_offset (0), + .vs_offset (0), + .hs_width (0), + .vs_width (0), + .refresh_mod (0), + + .ntsc (0), + .opl2_level (2'b00), + + + .audio_l ( laudio ), + .audio_r ( raudio ), + + .ioctl_download( ioctl_downl), + .ioctl_index (ioctl_index), + .ioctl_addr ( ioctl_addr - 2'd2 ),//check + .ioctl_wr ( ioctl_wr ), + .ioctl_dout ( ioctl_dout ), + + .SDRAM_A ( SDRAM_A ), + .SDRAM_BA ( SDRAM_BA ), + .SDRAM_DQ ( SDRAM_DQ ), + .SDRAM_DQML ( SDRAM_DQML ), + .SDRAM_DQMH ( SDRAM_DQMH ), + .SDRAM_nCS ( SDRAM_nCS ), + .SDRAM_nCAS ( SDRAM_nCAS ), + .SDRAM_nRAS ( SDRAM_nRAS ), + .SDRAM_nWE ( SDRAM_nWE ) ); -wire [23:0] rgb_pause_out; -wire dim_video; - -arcade_video #(320,24) arcade_video -( - .*, - - .clk_video(clk_sys), - .ce_pix(clk_7M), - - .RGB_in(rgb_pause_out), - - .HBlank(hbl), - .VBlank(vbl), - .HSync(hsync), - .VSync(vsync), - - .fx(scan_lines) -); - -/* - Phase Accumulator Increments (Fractional Size 32, look up size 8 bit, total 40 bits) - Increment Calculation - (Output Clock * 2 ^ Word Size) / Reference Clock - Example - NTSC = 3.579545 - PAL = 4.43361875 - W = 40 ( 32 bit fraction, 8 bit look up reference) - Ref CLK = 42.954544 (This could us any clock) - NTSC_Inc = 3.579545333 * 2 ^ 40 / 96 = 40997413706 -*/ - -// SET PAL and NTSC TIMING -`ifdef MISTER_ENABLE_YC - assign CHROMA_PHASE_INC = PALFLAG ? 40'd56225080500: 40'd56225080500; - assign YC_EN = status[22]; - assign PALFLAG = status[7]; -`endif - -screen_rotate screen_rotate (.*); - -wire [9:0] sprite_adj_x = 0; -wire [9:0] sprite_adj_y = 0; -wire bcu_flip_cs; -wire fcu_flip_cs; - -reg [1:0] adj_layer; -reg [15:0] scroll_adj_x [3:0]; -reg [15:0] scroll_adj_y [3:0]; -reg layer_en [3:0]; - -reg ce_pix; - -// flip is done in the rendering so leave screen_rotate flip off -wire flip = 0; - -reg tile_flip; -reg sprite_flip; - -//assign vc = vcx - vs_offset; - -// =============================================================== -// 68000 CPU -// =============================================================== - -// clock generation -reg fx68_phi1 = 0; -wire fx68_phi2 = !fx68_phi1; - -// phases for 68k clock -always @(posedge clk_sys) begin - if ( clk_10M == 1 ) begin - fx68_phi1 <= ~fx68_phi1; - end -end - -// CPU outputs -wire cpu_rw; // Read = 1, Write = 0 -wire cpu_as_n; // Address strobe -wire cpu_lds_n; // Lower byte strobe -wire cpu_uds_n; // Upper byte strobe -wire cpu_E; -wire [2:0]cpu_fc; // Processor state -wire cpu_reset_n_o; // Reset output signal -wire cpu_halted_n; // Halt output - -// CPU busses -wire [15:0] cpu_dout; -wire [23:0] cpu_a /* synthesis keep */; -reg [15:0] cpu_din; - -// CPU inputs -reg dtack_n; // Data transfer ack (always ready) -reg ipl2_n; - -wire reset_n; -wire vpa_n = ~ ( cpu_lds_n == 0 && cpu_fc == 3'b111 ); // from outzone schematic - -assign cpu_a[0] = reset; // debug hack odd memory address should cause cpu exception - -cc_shifter cc_reset ( - .clk_out(clk_10M), - .i(reset_z80_n), - .o(reset_n) -); - -fx68k fx68k ( - // input - .clk( clk_10M ), - .enPhi1(fx68_phi1), - .enPhi2(fx68_phi2), - .extReset(reset), - .pwrUp(reset), - - // output - .eRWn(cpu_rw), - .ASn( cpu_as_n), - .LDSn(cpu_lds_n), - .UDSn(cpu_uds_n), -// .E(cpu_E), -// .VMAn(), - .FC0(cpu_fc[0]), - .FC1(cpu_fc[1]), - .FC2(cpu_fc[2]), -// .BGn(), - .oRESETn(cpu_reset_n_o), - .oHALTEDn(cpu_halted_n), - - // input - .VPAn( vpa_n ), - .DTACKn(dtack_n ), - .BERRn(1'b1), - .BRn(1'b1), - .BGACKn(1'b1), - - .IPL0n(1'b1), - .IPL1n(1'b1), - .IPL2n(ipl2_n), - - // busses - .iEdb(cpu_din), - .oEdb(cpu_dout), - .eab(cpu_a[23:1]) -); - -always @ (posedge clk_sys) begin - if ( clk_10M == 1 ) begin - // tell 68k to wait for valid data. 0=ready 1=wait - // always ack when it's not program rom - dtack_n <= prog_rom_cs ? !prog_rom_data_valid : 0; - // add dsp_ctrl_cs to cpu_din - // select cpu data input based on what is active - cpu_din <= prog_rom_cs ? prog_rom_data : - ram_cs ? ram_dout : - tile_palette_cs ? tile_palette_cpu_dout : - sprite_palette_cs ? sprite_palette_cpu_dout : - shared_ram_cs ? cpu_shared_dout : - tile_ofs_cs ? curr_tile_ofs : - sprite_ofs_cs ? curr_sprite_ofs : - tile_attr_cs ? cpu_tile_dout_attr : - tile_num_cs ? cpu_tile_dout_num : - sprite_0_cs ? sprite_0_dout : - sprite_1_cs ? sprite_1_dout : - sprite_2_cs ? sprite_2_dout : - sprite_3_cs ? sprite_3_dout : - sprite_size_cs ? sprite_size_cpu_dout : - frame_done_cs ? { 16 { vbl } } : // get vblank state - vblank_cs ? { 15'b0, vbl } : - int_en_cs ? 16'hffff : - 16'd0; - end -end - -wire [15:0] cpu_shared_dout; -wire [7:0] z80_shared_dout; -reg [15:0] z80_a; - -wire [15:0] z80_addr; -reg [7:0] z80_din; -wire [7:0] z80_dout; - -wire z80_wr_n; -wire z80_rd_n; -reg z80_wait_n; - -wire IORQ_n; -wire MREQ_n; - -always @ (posedge clk_sys) begin - if ( reset == 1 ) begin - z80_wait_n <= 0; - sound_wr <= 0; - end else if ( clk_3_5M == 1 ) begin - z80_wait_n <= 1; - if ( ioctl_download | ( z80_rd_n == 0 && sound_rom_1_data_valid == 0 && sound_rom_1_cs == 1 ) ) begin - // wait if rom is selected and data is not yet available - z80_wait_n <= 0; - end - if ( z80_rd_n == 0 ) begin - if ( sound_rom_1_cs ) begin - if ( sound_rom_1_data_valid ) begin - z80_din <= sound_rom_1_data; - end else begin - z80_wait_n <= 0; - end - end else if ( sound_ram_1_cs ) begin - z80_din <= z80_shared_dout; - end else if ( z80_p1_cs ) begin - z80_din <= p1; - end else if ( z80_p2_cs ) begin - z80_din <= p2; - end else if ( z80_dswa_cs ) begin - z80_din <= z80_dswa; - end else if ( z80_dswb_cs ) begin - z80_din <= z80_dswb; - end else if ( z80_tjump_cs ) begin - z80_din <= z80_tjump; - end else if ( z80_system_cs ) begin - z80_din <= system; - end else if ( z80_sound0_cs ) begin - z80_din <= opl_dout; - end else begin - z80_din <= 8'h00; - end - end - sound_wr <= 0; - if ( z80_wr_n == 0 ) begin - if ( z80_sound0_cs | z80_sound1_cs ) begin - sound_data <= z80_dout; - sound_addr <= { 1'b0, z80_sound1_cs }; // pad for opl3. opl2 is single bit address - sound_wr <= 1; - end - end - end -end - -reg [1:0] sound_addr; -reg [7:0] sound_data; -reg sound_wr; - -wire [7:0] opl_dout; -wire opl_irq_n; - -reg signed [15:0] sample; - -assign AUDIO_S = 1'b1; - -wire opl_sample_clk; - -jtopl #(.OPL_TYPE(2)) jtopl2 -( - .rst(~reset_n), - .clk(clk_sys), - .cen(clk_3_5M), - .din(sound_data), - .addr(sound_addr), - .cs_n('0), - .wr_n(~sound_wr), - .dout(opl_dout), - .irq_n(opl_irq_n), - .snd(sample), - .sample(opl_sample_clk) -); - -wire [1:0] opl2_level = status[44:43]; // opl2 audio mix - -reg [7:0] opl2_mult; - -// set the multiplier for each channel from menu - -always @( posedge clk_sys, posedge reset ) begin - if (reset) begin - opl2_mult<=0; - end else begin - case( opl2_level ) - 0: opl2_mult <= 8'h0c; // 75% - 1: opl2_mult <= 8'h08; // 50% - 2: opl2_mult <= 8'h04; // 25% - 3: opl2_mult <= 8'h00; // 0% - endcase - end -end - -wire signed [15:0] mono; - -jtframe_mixer #(.W0(16), .WOUT(16)) u_mix_mono( - .rst ( reset ), - .clk ( clk_sys ), - .cen ( 1'b1 ), - // input signals - .ch0 ( sample ), - .ch1 ( 16'd0 ), - .ch2 ( 16'd0 ), - .ch3 ( 16'd0 ), - // gain for each channel in 4.4 fixed point format - .gain0 ( opl2_mult ), - .gain1 ( 8'd0 ), - .gain2 ( 8'd0 ), - .gain3 ( 8'd0 ), - .mixed ( mono ), - .peak ( ) -); - -always @ (posedge clk_sys ) begin - if ( pause_cpu == 1 ) begin - AUDIO_L <= 0; - AUDIO_R <= 0; - end else if ( pause_cpu == 0 ) begin - // mix audio - AUDIO_L <= mono; - AUDIO_R <= mono; - end -end - -T80pa u_cpu( - .RESET_n ( reset_n ), - .CLK ( clk_sys ), - .CEN_p ( clk_3_5M ), - .CEN_n ( ~clk_3_5M ), - - .WAIT_n ( z80_wait_n ), // don't wait if data is valid or rom access isn't selected - .INT_n ( opl_irq_n ), // opl timer - .NMI_n ( 1'b1 ), - .BUSRQ_n ( 1'b1 ), - .RD_n ( z80_rd_n ), - .WR_n ( z80_wr_n ), - .A ( z80_addr ), - .DI ( z80_din ), - .DO ( z80_dout ), - // unused - .DIRSET ( 1'b0 ), - .DIR ( 212'b0 ), - .OUT0 ( 1'b0 ), - .RFSH_n (), - .IORQ_n ( IORQ_n ), - .M1_n (), - .BUSAK_n (), - .HALT_n ( 1'b1 ), - .MREQ_n ( MREQ_n ), - .Stop (), - .REG () -); - -// Chip select mux -wire prog_rom_cs; -wire scroll_ofs_x_cs; -wire scroll_ofs_y_cs; -wire ram_cs; -wire vblank_cs; -wire int_en_cs; -wire crtc_cs; -wire tile_ofs_cs; -wire tile_attr_cs; -wire tile_num_cs; -wire scroll_cs; -wire shared_ram_cs; -wire frame_done_cs; // word -wire tile_palette_cs; -wire sprite_palette_cs; -wire sprite_ofs_cs; -wire sprite_cs; // *** offset needs to be auto-incremented -wire sprite_size_cs; // *** offset needs to be auto-incremented -wire sprite_ram_cs; - -wire z80_p1_cs; -wire z80_p2_cs; -wire z80_dswa_cs; -wire z80_dswb_cs; -wire z80_system_cs; -wire z80_tjump_cs; -wire z80_sound0_cs; -wire z80_sound1_cs; - -chip_select cs (.*); - -wire sprite_0_cs = ( curr_sprite_ofs[1:0] == 2'b00 ) & sprite_cs; -wire sprite_1_cs = ( curr_sprite_ofs[1:0] == 2'b01 ) & sprite_cs; -wire sprite_2_cs = ( curr_sprite_ofs[1:0] == 2'b10 ) & sprite_cs; -wire sprite_3_cs = ( curr_sprite_ofs[1:0] == 2'b11 ) & sprite_cs; - -reg reset_z80_n; -wire reset_z80_cs; -wire sound_rom_1_cs = ( MREQ_n == 0 && z80_addr <= 16'h7fff ); -wire sound_ram_1_cs = ( MREQ_n == 0 && z80_addr >= 16'h8000 && z80_addr <= 16'h87ff ); - -reg int_en; -reg int_ack; - -reg [1:0] vbl_sr; - -// vblank interrupt on rising vbl -always @ (posedge clk_sys ) begin - if ( reset == 1 ) begin - ipl2_n <= 1; - int_ack <= 0; - end else begin - vbl_sr <= { vbl_sr[0], vbl }; - if ( clk_10M == 1 ) begin - int_ack <= ( cpu_as_n == 0 ) && ( cpu_fc == 3'b111 ); // cpu acknowledged the interrupt - end - if ( vbl_sr == 2'b01 ) begin// rising edge - ipl2_n <= ~int_en; - end else if ( int_ack == 1 || vbl_sr == 2'b10 ) begin - ipl2_n <= 1; - end - end -end - -reg [15:0] scroll_x [3:0]; -reg [15:0] scroll_y [3:0]; - -reg [15:0] scroll_x_latch [3:0]; -reg [15:0] scroll_y_latch [3:0]; - -reg inc_sprite_ofs; - -reg [15:0] crtc[4]; - -always @ (posedge clk_sys) begin - if ( reset == 1 ) begin - int_en <= 0; - reset_z80_n <= 0; - end else begin - if ( pcb != 3 && pcb != 4 ) begin - // if the pcb uses the 68k reset pin to drive the reset line - reset_z80_n <= cpu_reset_n_o; - end - // write asserted and rising cpu clock - if ( clk_10M == 1 && cpu_rw == 0 ) begin - if ( tile_ofs_cs ) begin - curr_tile_ofs <= cpu_dout; - end - if ( int_en_cs ) begin - int_en <= cpu_dout[0]; - end - if ( crtc_cs ) begin - crtc[ cpu_a[2:1] ] <= cpu_dout; - end - if ( bcu_flip_cs ) begin - tile_flip <= cpu_dout[0]; - end - if ( fcu_flip_cs ) begin - sprite_flip <= cpu_dout[15]; - end - if ( sprite_ofs_cs ) begin - // mask out valid range - curr_sprite_ofs <= { 6'b0, cpu_dout[9:0] }; - end - if ( scroll_ofs_x_cs ) begin - scroll_ofs_x <= cpu_dout; - end - if ( scroll_ofs_y_cs ) begin - scroll_ofs_y <= cpu_dout; - end - // x layer values are even addresses - if ( scroll_cs ) begin - if ( cpu_a[1] == 0 ) begin - scroll_x[ cpu_a[3:2] ] <= cpu_dout[15:7]; - end else begin - scroll_y[ cpu_a[3:2] ] <= cpu_dout[15:7]; - end - end - // offset needs to be auto-incremented - if ( sprite_cs | sprite_size_cs ) begin - inc_sprite_ofs <= 1; - end - if ( reset_z80_cs ) begin - // the pcb writes to a latch to control the reset - reset_z80_n <= cpu_dout[0]; - end - end - // write lasts multiple cpu clocks so limit to one increment per write signal - if ( inc_sprite_ofs == 1 && cpu_rw == 1 ) begin - curr_sprite_ofs <= curr_sprite_ofs + 1; - inc_sprite_ofs <= 0; - end - end -end - -reg [15:0] scroll_x_total [3:0]; -reg [15:0] scroll_y_total [3:0]; - -wire [15:0] ram_dout; -wire [9:0] tile_palette_addr; -wire [15:0] tile_palette_cpu_dout; -wire [15:0] tile_palette_dout; - -wire [9:0] sprite_palette_addr; -wire [15:0] sprite_palette_cpu_dout; -wire [15:0] sprite_palette_dout; - -reg [15:0] curr_tile_ofs; -reg [15:0] curr_sprite_ofs; - -reg [15:0] scroll_ofs_x; -reg [15:0] scroll_ofs_y; - -wire [15:0] cpu_tile_dout_attr; -wire [15:0] cpu_tile_dout_num; - -wire [15:0] sprite_0_dout; -wire [15:0] sprite_1_dout; -wire [15:0] sprite_2_dout; -wire [15:0] sprite_3_dout; -wire [15:0] sprite_size_dout; -wire [15:0] sprite_size_cpu_dout; - -wire [31:0] tile_attr_dout; -wire [15:0] sprite_attr_0_dout; -wire [15:0] sprite_attr_1_dout; -wire [15:0] sprite_attr_2_dout; -wire [15:0] sprite_attr_3_dout; - -wire [15:0] sprite_size_buf_dout; -wire [15:0] sprite_attr_0_buf_dout; -wire [15:0] sprite_attr_1_buf_dout; -wire [15:0] sprite_attr_2_buf_dout; -wire [15:0] sprite_attr_3_buf_dout; - -reg [15:0] sprite_buf_din; - -reg [14:0] tile; - -reg [7:0] sprite_num; -reg [7:0] sprite_num_copy; - -reg [3:0] tile_draw_state; - -reg [2:0] layer; // 4 layers + 1 for initial background - -wire [14:0] tile_idx = tile_attr[14:0]; -wire [3:0] tile_priority = tile_attr[31:28]; -wire [5:0] tile_palette_idx = tile_attr[21:16]; -wire tile_hidden = tile_attr[15]; - -reg [15:0] fb_dout; -wire [15:0] tile_fb_out; -wire [15:0] sprite_fb_out; -reg [15:0] fb_din; -reg [15:0] sprite_fb_din; - -reg tile_fb_w; -reg sprite_fb_w; -reg sprite_buf_w; -reg sprite_size_buf_w; - -dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) tile_line_buffer ( - .clock_a ( clk_sys ), - .address_a ( tile_fb_addr_w ), - .wren_a ( tile_fb_w ), - .data_a ( fb_din ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( fb_addr_r ), - .wren_b ( 0 ), -// .data_b ( ), - .q_b ( tile_fb_out ) -); - -dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) sprite_line_buffer ( - .clock_a ( clk_sys ), - .address_a ( sprite_fb_addr_w ), - .wren_a ( sprite_fb_w ), - .data_a ( sprite_fb_din ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( fb_addr_r ), - .wren_b ( 0 ), -// .data_b ( ), - .q_b ( sprite_fb_out ) -); - -reg [9:0] x_ofs; -reg [9:0] x; - -reg [9:0] y_ofs; - -// y needs to be one line ahaed of the visible line -// render the first line at the end of the previous frame -// this depends on the timing that the sprite list is valid -// sprites values are copied at the start of vblank (line 240) - -// global offsets -wire [9:0] x_ofs_dx = 495 + { ~layer[1:0], 1'b0 }; -wire [9:0] y_ofs_dx = 257; -wire [9:0] x_ofs_dx_flipped = 17 - { ~layer[1:0], 1'b0 }; -wire [9:0] y_ofs_dx_flipped = 255; - -// calculate scrolling -wire [9:0] tile_x_unflipped = scroll_x_latch[layer[1:0]] + x_ofs_dx; -wire [9:0] tile_y_unflipped = scroll_y_latch[layer[1:0]] + y_ofs_dx + scroll_y_offset; -wire [9:0] tile_x_flipped = 319 + scroll_x_latch[layer[1:0]] + x_ofs_dx_flipped; -wire [9:0] tile_y_flipped = 239 + scroll_y_latch[layer[1:0]] + y_ofs_dx_flipped + scroll_y_offset; - -// reverse tiles when flipped -wire [9:0] curr_x = tile_flip ? tile_x_flipped - x : tile_x_unflipped + x; -wire [9:0] curr_y = tile_flip ? tile_y_flipped - y : tile_y_unflipped + y; - -reg [9:0] y; -wire [9:0] y_flipped = ( sprite_flip ? (240 - y ) + scroll_y_offset : y + scroll_y_offset); -wire [9:0] sprite_buf_x = sprite_flip ? 320 - (sprite_x + sprite_pos_x ) : sprite_x + sprite_pos_x; // offset from left of frame - -reg [3:0] draw_state; -reg [3:0] sprite_state; -reg [3:0] tile_copy_state; -reg [3:0] sprite_copy_state; - -// pixel 4 bit colour -wire [3:0] tile_pix; -assign tile_pix = { tile_data[7-curr_x[2:0]], tile_data[15-curr_x[2:0]], tile_data[23-curr_x[2:0]], tile_data[31-curr_x[2:0]] }; - -wire [2:0] sprite_bit = sprite_x[2:0]; -wire [3:0] sprite_pix; -assign sprite_pix = { sprite_data[7-sprite_bit], sprite_data[15-sprite_bit], sprite_data[23-sprite_bit], sprite_data[31-sprite_bit] }; - -// two lines of buffer alternate -reg [9:0] tile_fb_addr_w; -wire [9:0] fb_addr_r = {vc[0], 9'b0 } + hc; - -reg [9:0] sprite_fb_addr_w; - -reg [31:0] tile_attr; - -// two lines worth for 4 layers (~8k) -// [15:14] = layer. -// [13:10] = prioity -// [9:4] = palette offset -// [3:0] = tile colour index. - -reg [3:0] tile_priority_buf [327:0]; -reg [3:0] sprite_priority_buf [327:0]; - -reg [9:0] sprite_x; // offset from left side of sprite -reg [9:0] sprite_y; - -wire [14:0] sprite_index = sprite_attr_0_buf_dout[14:0] /* synthesis keep */; -wire sprite_hidden = sprite_attr_0_buf_dout[15] /* synthesis keep */; - -wire [5:0] sprite_pal_addr = sprite_attr_1_buf_dout[5:0] /* synthesis keep */; -wire [5:0] sprite_size_addr = sprite_attr_1_buf_dout[11:6] /* synthesis keep */; -wire [3:0] sprite_priority = sprite_attr_1_buf_dout[15:12] /* synthesis keep */; - -wire [9:0] sprite_pos_x = sprite_adj_x + (( sprite_attr_2_buf_dout[15:7] < 9'h180 ) ? sprite_attr_2_buf_dout[15:7] : ( sprite_attr_2_buf_dout[15:7] - 10'h200)); -wire [9:0] sprite_pos_y = sprite_adj_y + (( sprite_attr_3_buf_dout[15:7] < 9'h180 ) ? sprite_attr_3_buf_dout[15:7] : ( sprite_attr_3_buf_dout[15:7] - 10'h200)); - -// valid 1 cycle after sprite attr ready -wire [8:0] sprite_height = { sprite_size_buf_dout[7:4], 3'b0 } /* synthesis keep */; // in pixels -wire [8:0] sprite_width = { sprite_size_buf_dout[3:0], 3'b0 } /* synthesis keep */; - -reg [7:0] sprite_buf_num; - -reg [1:0] vtotal_282_flag; - -always @ (posedge clk_sys) begin // Check System Vcount flag for 60Hz mode - if ({crtc[2][7:0], 1'b1 } == 269) - vtotal_282_flag <= 0; - else - vtotal_282_flag <= 1; -end - -always @ (posedge clk_sys) begin - if ( reset == 1 ) begin - sprite_state <= 0; - draw_state <= 0; - sprite_rom_cs <= 0; - tile_rom_cs <= 0; - tile_copy_state <= 0; - sprite_copy_state <= 0; - tile_draw_state <= 0; - end else begin - // render sprites - // triggered when the tile rendering starts - if ( sprite_state == 0 && draw_state > 0 ) begin - sprite_num <= 8'h00; - sprite_x <= 0; - sprite_fb_w <= 1; - sprite_state <= 1; - sprite_fb_din <= 0; - sprite_fb_addr_w <= { y[0], 9'b0 }; - end else if ( sprite_state == 1 ) begin - // erase line buffer - sprite_fb_addr_w <= { y[0], 9'b0 } + sprite_x; - sprite_priority_buf[sprite_x] <= 0; - if ( sprite_x < 320 ) begin - sprite_x <= sprite_x + 1; - end else begin - sprite_x <= 0; - sprite_fb_w <= 0; - sprite_state <= 2; - end - end else if ( sprite_state == 2 ) begin - // sprite num is valid now - sprite_state <= 3; - end else if ( sprite_state == 3 ) begin - // sprite attr valid now. - // delay one more cycle to read sprite size - sprite_state <= 4; - end else if ( sprite_state == 4 ) begin - // start loop - sprite_rom_cs <= 0; - sprite_fb_w <= 0; - sprite_y <= y_flipped - sprite_pos_y; - // is sprite visible and is current y in sprite y range - // sprite pos can be negative? - if ( sprite_hidden == 0 && sprite_width > 0 && ( $signed(y_flipped) >= $signed(sprite_pos_y) ) && $signed(y_flipped) < ( $signed(sprite_pos_y) + $signed(sprite_height) ) ) begin - sprite_state <= 5; - end else if ( sprite_num < 8'hff ) begin - sprite_num <= sprite_num + 1; - sprite_state <= 2; - end else begin - sprite_state <= 15; - end - end else if ( sprite_state == 5 ) begin - sprite_rom_addr <= { sprite_index, 3'b0 } + { sprite_x[8:3], 3'b0 } + ( sprite_y[8:3] * sprite_width ) + sprite_y[2:0]; - sprite_rom_cs <= 1; - sprite_state <= 6; - end else if ( sprite_state == 6 ) begin - // wait for sprite bitmap ready - if ( sprite_rom_data_valid ) begin - // latch data and deassert cs - sprite_data <= sprite_rom_data; - sprite_rom_cs <= 0; - sprite_state <= 7; - end - end else if ( sprite_state == 7 ) begin - sprite_fb_w <= 0; - // draw if pixel value not zero and priority >= previous sprite data -// if ( sprite_pix > 0 && sprite_priority_buf[sprite_buf_x] == 0 ) begin -// if ( sprite_pix != 0 && ( sprite_priority == 0 || sprite_priority >= sprite_priority_buf[sprite_buf_x] ) ) begin - if ( sprite_pix != 0 ) begin - sprite_fb_din <= { 2'b11, sprite_priority, sprite_pal_addr, sprite_pix }; -// if ( sprite_priority == 0 ) begin -// sprite_priority_buf[sprite_buf_x] <= { 1'b1, sprite_priority }; -// end else begin - sprite_fb_addr_w <= { y[0], 9'b0 } + sprite_buf_x; - sprite_priority_buf[sprite_buf_x] <= sprite_priority; - sprite_fb_w <= 1; - end - if ( sprite_x < ( sprite_width - 1 ) ) begin - sprite_x <= sprite_x + 1; - if ( sprite_x[2:0] == 7 ) begin - // do recalc bitmap address - sprite_state <= 5; - end - end else if ( sprite_num < 8'hff ) begin - sprite_num <= sprite_num + 1; - sprite_x <= 0; - // need to load new attributes and size - sprite_state <= 2; - end else begin - // tile state machine will reset sprite_state when line completes. - sprite_state <= 15; // done - end - end - // copy tile ram and scroll info - // not sure if this is needed. need to check to see when tile ram is updated. - if ( tile_copy_state == 0 && vc == 256 ) begin - tile_copy_state <= 1; - end else begin - // copy scroll registers - scroll_x_latch[0] <= scroll_x[0] - scroll_ofs_x; - scroll_x_latch[1] <= scroll_x[1] - scroll_ofs_x; - scroll_x_latch[2] <= scroll_x[2] - scroll_ofs_x; - scroll_x_latch[3] <= scroll_x[3] - scroll_ofs_x; - scroll_y_latch[0] <= scroll_y[0] - scroll_ofs_y; - scroll_y_latch[1] <= scroll_y[1] - scroll_ofs_y; - scroll_y_latch[2] <= scroll_y[2] - scroll_ofs_y; - scroll_y_latch[3] <= scroll_y[3] - scroll_ofs_y; - end - // copy sprite attr/size to buffer - if ( sprite_copy_state == 0 && vc == 240 ) begin - sprite_copy_state <= 1; - sprite_buf_w <= 0; - sprite_num_copy <= 8'h00; - end else if ( sprite_copy_state == 1 ) begin - sprite_num_copy <= sprite_num_copy + 1; - sprite_buf_num <= sprite_num_copy; - sprite_buf_w <= 1; - // wait for read from source - if ( sprite_num_copy == 8'hff ) begin - sprite_copy_state <= 2; - end - end else if ( sprite_copy_state == 2 ) begin - sprite_buf_w <= 0; - sprite_copy_state <= 0; - end - // tile state machine - if ( draw_state == 0 && vc == ({ crtc[2][7:0], 1'b1 } - (status[19] ? (vtotal_282_flag ? 5'd19 : 4'd7) : 3'd0)) ) begin // 282 Lines standard (263 Lines for 60Hz) - layer <= 4; // layer 4 is layer 0 but draws hidden and transparent - y <= 0; - draw_state <= 2; - sprite_state <= 0; - end else if ( draw_state == 2 ) begin - x <= 0; - x_ofs <= scroll_x_latch[layer[1:0]]; - y_ofs <= scroll_y_latch[layer[1:0]]; - // latch offset info - draw_state <= 3; - tile_draw_state <= 0; - end else if ( draw_state == 3 ) begin - if ( tile_draw_state == 0 ) begin - tile <= { layer[1:0], curr_y[8:3], curr_x[8:3] }; // works - tile_draw_state <= 4'h1; - end else if ( tile_draw_state == 1 ) begin - tile_draw_state <= 2; - end else if ( tile_draw_state == 2 ) begin - // latch attribute - tile_attr <= tile_attr_dout; - if ( layer == 4 || tile_attr_dout[15] == 0 ) begin - tile_draw_state <= 3; - end else begin - if ( x < 320 ) begin// 319 - tile_draw_state <= 3; - // do we need to read another tile? - // last pixel of this tile changes based on flip direction - if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin - draw_state <= 3; - tile_draw_state <= 0; - end - x <= x + 1; - end else if ( layer > 0 ) begin - layer <= layer - 1; - tile_fb_w <= 0; - draw_state <= 2; - end else begin - // done - tile_draw_state <= 7; - tile_fb_w <= 0; - end - end - end else if ( tile_draw_state == 3 ) begin - // read bitmap info - tile_rom_cs <= 1; - tile_rom_addr <= { tile_idx, curr_y[2:0] }; - tile_draw_state <= 4; - end else if ( tile_draw_state == 4 ) begin - // wait for bitmap ram ready - if ( tile_rom_data_valid ) begin - // latch data and deassert cs - tile_data <= tile_rom_data; - tile_draw_state <= 5; - tile_rom_cs <= 0; - end - end else if ( tile_draw_state == 5 ) begin - tile_fb_w <= 0; - tile_fb_addr_w <= { y[0], 9'b0 } + x; - // force render of first layer. - // if layer == 4 then tile_pix == 0 is not transparent - // layer 4 is really layer 0 - if ( layer == 4 ) begin - tile_priority_buf[x] <= 0; //tile_pix == 0 ? 0 : tile_priority; - //fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; - fb_din <= { layer[1:0], 4'b0, tile_palette_idx, tile_pix }; - tile_fb_w <= 1; - end else if (tile_hidden == 0 && tile_pix > 0 && tile_priority > 0 && tile_priority >= tile_priority_buf[x] ) begin - tile_priority_buf[x] <= tile_priority; - // if tile hidden then make the pallette index 0. ie transparent - fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; - tile_fb_w <= 1; - end - if ( x < 320 ) begin// 319 - // do we need to read another tile? - // last pixel of this tile changes based on flip direction - if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin - draw_state <= 3; - tile_draw_state <= 0; - end - x <= x + 1; - end else if ( layer > 0 ) begin - layer <= layer - 1; - tile_fb_w <= 0; - draw_state <= 2; - end else begin - // done - tile_draw_state <= 7; - tile_fb_w <= 0; - end - end else if ( tile_draw_state == 7 ) begin - // wait for next line or quit - if ( y == 239 ) begin - draw_state <= 0; - end else if ( hc == (status[19] ? 9'd444 : 9'd449) ) begin // 450 Lines standard (445 Lines for NTSC standard 15.73kHz line freq) - y <= y + 1; - draw_state <= 2; - sprite_state <= 0; - layer <= 4; - end - end - end - end -end - -// render -reg draw_sprite; - -// two lines worth for 4 layers (~8k) -// [15:14] = layer. -// [13:10] = prioity -// [9:4] = palette offset -// [3:0] = tile colour index. - -// there are 10 70MHz cycles per pixel. clk7_count from 0-9 - -// dac values based on 120 ohm driver for the resistor dac and 75 ohm output. 4.7k, 2.2k, 1k, 470, 220 -// modeled in spice -wire [7:0] dac [0:31] = '{0,12,25,36,50,61,73,83,91,100,111,120,131,139,149,157,145,154,162,170,180,187,195,202,208,214,222,228,236,242,249,255}; - -always @ (posedge clk_sys) begin - if ( clk7_count == 4 ) begin - tile_palette_addr <= tile_fb_out[9:0]; - sprite_palette_addr <= sprite_fb_out[9:0]; - end else if ( clk7_count == 6 ) begin - // if palette index is zero then it's from layer 3 and is transparent render as blank (black). - rgb <= { dac[tile_palette_dout[4:0]], dac[tile_palette_dout[9:5]], dac[tile_palette_dout[14:10]] }; - - // if not transparent and sprite is higher priority - if ( sprite_fb_out[3:0] > 0 && (sprite_fb_out[13:10] > tile_fb_out[13:10]) ) begin - // draw sprite - rgb <= { dac[sprite_palette_dout[4:0]], dac[sprite_palette_dout[9:5]], dac[sprite_palette_dout[14:10]] }; - end - end -end - -// tile data buffer - -reg tile_buf_w; -reg [31:0] tile_buf_din; -reg [31:0] tile_buf_dout; -reg [13:0] tile_buf_addr; - -dual_port_ram #(.LEN(16384), .DATA_WIDTH(32)) ram_tile_buf ( - .clock_a ( clk_sys ), - .address_a ( tile[13:0] ), - .wren_a ( tile_buf_w ), - .data_a ( tile_attr_dout ), - - .clock_b ( clk_sys ), - .address_b ( tile[13:0] ), // only read the tile # for now - .wren_b ( 0 ), - .q_b ( tile_buf_dout ) -); - -// tile attribute ram. each tile attribute is 2 16bit words -// pppp ---- --cc cccc httt tttt tttt tttt = Tile number (0 - $7fff) -// indirect access through offset register -dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_h ( - .clock_a ( clk_10M ), - .address_a ( curr_tile_ofs ), - .wren_a ( tile_attr_cs & !cpu_rw ), - .data_a ( cpu_dout ), - .q_a ( cpu_tile_dout_attr ), - - .clock_b ( clk_sys ), - .address_b ( tile[13:0] ), // only read the tile # for now - .wren_b ( 0 ), - .q_b ( tile_attr_dout[31:16] ) -); - -dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_l ( - .clock_a ( clk_10M ), - .address_a ( curr_tile_ofs ), - .wren_a ( tile_num_cs & !cpu_rw ), - .data_a ( cpu_dout ), - .q_a ( cpu_tile_dout_num ), - - .clock_b ( clk_sys ), - .address_b ( tile[13:0] ), // only read the tile # for now - .wren_b ( 0 ), - .q_b ( tile_attr_dout[15:0] ) -); - -// sprite attribute ram. each tile attribute is 4 16bit words -// indirect access through offset register -// split up so 64 bits can be read in a single clock -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_0 ( - .clock_a ( clk_10M ), - .address_a ( curr_sprite_ofs[9:2] ), - .wren_a ( sprite_0_cs & !cpu_rw), - .data_a ( cpu_dout ), - .q_a ( sprite_0_dout ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num_copy ), - .wren_b ( 0 ), - .q_b ( sprite_attr_0_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_0_buf ( - .clock_a ( clk_sys ), - .address_a ( sprite_buf_num ), - .wren_a ( sprite_buf_w ), - .data_a ( sprite_attr_0_dout[15:0] ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num ), - .wren_b ( 0 ), - .q_b ( sprite_attr_0_buf_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_1 ( - .clock_a ( clk_10M ), - .address_a ( curr_sprite_ofs[9:2] ), - .wren_a ( sprite_1_cs & !cpu_rw ), - .data_a ( cpu_dout ), - .q_a ( sprite_1_dout ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num_copy ), - .wren_b ( 0 ), - .q_b ( sprite_attr_1_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_1_buf ( - .clock_a ( clk_sys ), - .address_a ( sprite_buf_num ), - .wren_a ( sprite_buf_w ), - .data_a ( sprite_attr_1_dout[15:0] ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num ), - .wren_b ( 0 ), - .q_b ( sprite_attr_1_buf_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_2 ( - .clock_a ( clk_10M ), - .address_a ( curr_sprite_ofs[9:2] ), - .wren_a ( sprite_2_cs & !cpu_rw ), - .data_a ( cpu_dout ), - .q_a ( sprite_2_dout ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num_copy ), - .wren_b ( 0 ), - .q_b ( sprite_attr_2_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_2_buf ( - .clock_a ( clk_sys ), - .address_a ( sprite_buf_num ), - .wren_a ( sprite_buf_w ), - .data_a ( sprite_attr_2_dout[15:0] ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num ), - .wren_b ( 0 ), - .q_b ( sprite_attr_2_buf_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_3 ( - .clock_a ( clk_10M ), - .address_a ( curr_sprite_ofs[9:2] ), - .wren_a ( sprite_3_cs & !cpu_rw ), - .data_a ( cpu_dout ), - .q_a ( sprite_3_dout ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num_copy ), - .wren_b ( 0 ), - .q_b ( sprite_attr_3_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_3_buf ( - .clock_a ( clk_sys ), - .address_a ( sprite_buf_num ), - .wren_a ( sprite_buf_w ), - .data_a ( sprite_attr_3_dout[15:0] ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num ), - .wren_b ( 0 ), - .q_b ( sprite_attr_3_buf_dout[15:0] ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_size ( - .clock_a ( clk_10M ), - .address_a ( curr_sprite_ofs ), - .wren_a ( sprite_size_cs & !cpu_rw), - .data_a ( cpu_dout ), - .q_a ( sprite_size_cpu_dout ), - - .clock_b ( clk_sys ), - .address_b ( sprite_num_copy ), - .wren_b ( 0 ), - .q_b ( sprite_size_dout ) -); - -dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_size_buf ( - .clock_a ( clk_sys ), - .address_a ( sprite_buf_num ), - .wren_a ( sprite_buf_w ), - .data_a ( sprite_size_dout ), - .q_a ( ), - - .clock_b ( clk_sys ), - .address_b ( sprite_size_addr ), - .wren_b ( 0 ), - .q_b ( sprite_size_buf_dout ) -); - - -// tiles 1024 15 bit values. index is ( 6 bits from tile attribute, 4 bits from bitmap ) -// background palette ram low -// does this need to be byte addressable? -dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_l ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[10:1] ), - .wren_a ( tile_palette_cs & !cpu_rw & !cpu_lds_n), - .data_a ( cpu_dout[7:0] ), - .q_a ( tile_palette_cpu_dout[7:0] ), - - .clock_b ( clk_sys ), - .address_b ( tile_palette_addr ), - .wren_b ( 0 ), - .q_b ( tile_palette_dout[7:0] ) -); - -// background palette ram high -dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_h ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[10:1] ), - .wren_a ( tile_palette_cs & !cpu_rw & !cpu_uds_n), - .data_a ( cpu_dout[15:8] ), - .q_a ( tile_palette_cpu_dout[15:8] ), - - .clock_b ( clk_sys ), - .address_b ( tile_palette_addr ), - .wren_b ( 0 ), - .q_b ( tile_palette_dout[15:8] ) -); - -// sprite palette ram low -// does this need to be byte addressable? -dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_l ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[10:1] ), - .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_lds_n), - .data_a ( cpu_dout[7:0] ), - .q_a ( sprite_palette_cpu_dout[7:0] ), - - .clock_b ( clk_sys ), - .address_b ( sprite_palette_addr ), - .wren_b ( 0 ), - .q_b ( sprite_palette_dout[7:0] ) -); - -// background palette ram high -dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_h ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[10:1] ), - .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_uds_n), - .data_a ( cpu_dout[15:8] ), - .q_a ( sprite_palette_cpu_dout[15:8] ), - - .clock_b ( clk_sys ), - .address_b ( sprite_palette_addr ), - .wren_b ( 0 ), - .q_b ( sprite_palette_dout[15:8] ) -); - - -// main 68k ram low -dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_L ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[14:1] ), - .wren_a ( !cpu_rw & ram_cs & !cpu_lds_n ), - .data_a ( cpu_dout[7:0] ), - .q_a ( ram_dout[7:0] ) - ); - -// main 68k ram high -dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_H ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[14:1] ), - .wren_a ( !cpu_rw & ram_cs & !cpu_uds_n ), - .data_a ( cpu_dout[15:8] ), - .q_a ( ram_dout[15:8] ) -); - - -//wire [15:0] z80_shared_addr = z80_addr - 16'h8000; -//wire [23:0] m68k_shard_addr = cpu_a - 24'h040000; - -// z80 and 68k shared ram -// 4k -dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) shared_ram ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[12:1] ), - .wren_a ( shared_ram_cs & !cpu_rw & !cpu_lds_n), - .data_a ( cpu_dout[7:0] ), - .q_a ( cpu_shared_dout[7:0] ), - - .clock_b ( clk_3_5M ), // z80 clock is 3.5M - .address_b ( z80_addr[11:0] ), - .data_b ( z80_dout ), - .wren_b ( sound_ram_1_cs & ~z80_wr_n ), - .q_b ( z80_shared_dout ) -); - -reg [11:0] sprite_rb_addr; -wire [15:0] sprite_rb_dout; - -dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) sprite_ram_rb_l ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[12:1] ), - .wren_a ( sprite_ram_cs & !cpu_rw & !cpu_lds_n), - .data_a ( cpu_dout[7:0] ), - .q_a ( sprite_rb_dout[7:0] ), - - .clock_b ( clk_sys ), - .address_b ( sprite_rb_addr ), - .wren_b ( 0 ), - .q_b ( sprite_rb_dout[7:0] ) -); - -dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) sprite_ram_rb_h ( - .clock_a ( clk_10M ), - .address_a ( cpu_a[12:1] ), - .wren_a ( sprite_ram_cs & !cpu_rw & !cpu_uds_n), - .data_a ( cpu_dout[15:8] ), - .q_a ( cpu_shared_dout[15:8] ), - - .clock_b ( clk_sys ), - .address_b ( sprite_rb_addr ), - .wren_b ( 0 ), - .q_b ( sprite_rb_dout[15:8] ) -); - -reg [22:0] sdram_addr; -reg [31:0] sdram_data; -reg sdram_we; -reg sdram_req; - -wire sdram_ack; -wire sdram_valid; -wire [31:0] sdram_q; - -sdram #(.CLK_FREQ(70.0)) sdram -( - .reset(~pll_locked), - .clk(clk_sys), - - // controller interface - .addr(sdram_addr), - .data(sdram_data), - .we(sdram_we), - .req(sdram_req), - - .ack(sdram_ack), - .valid(sdram_valid), - .q(sdram_q), - - // SDRAM interface - .sdram_a(SDRAM_A), - .sdram_ba(SDRAM_BA), - .sdram_dq(SDRAM_DQ), - .sdram_cke(SDRAM_CKE), - .sdram_cs_n(SDRAM_nCS), - .sdram_ras_n(SDRAM_nRAS), - .sdram_cas_n(SDRAM_nCAS), - .sdram_we_n(SDRAM_nWE), - .sdram_dqml(SDRAM_DQML), - .sdram_dqmh(SDRAM_DQMH) -); - -wire prog_cache_rom_cs; -wire [22:0] prog_cache_addr; -wire [15:0] prog_cache_data; -wire prog_cache_valid; - -wire [15:0] prog_rom_data; -wire prog_rom_data_valid; - -reg tile_rom_cs; -reg [17:0] tile_rom_addr; -wire [31:0] tile_rom_data; -wire tile_rom_data_valid; - -wire tile_cache_cs; -wire [17:0] tile_cache_addr; -wire [31:0] tile_cache_data; -wire tile_cache_valid; - -reg [31:0] tile_data; - -wire sprite_rom_cs; -wire [17:0] sprite_rom_addr; -wire [31:0] sprite_rom_data; -wire sprite_rom_data_valid; - -reg [31:0] sprite_data; - -wire [15:0] sound_rom_1_addr; -wire [7:0] sound_rom_1_data; -wire sound_rom_1_data_valid; - -// sdram priority based rom controller -// is a oe needed? -rom_controller rom_controller -( - .reset(reset), - - // clock - .clk(clk_sys), - - // program ROM interface - .prog_rom_cs(prog_cache_rom_cs), - .prog_rom_oe(1), - .prog_rom_addr(prog_cache_addr), - .prog_rom_data(prog_cache_data), - .prog_rom_data_valid(prog_cache_valid), - - // character ROM interface - .tile_rom_cs(tile_cache_cs), - .tile_rom_oe(1), - .tile_rom_addr(tile_cache_addr), - .tile_rom_data(tile_cache_data), - .tile_rom_data_valid(tile_cache_valid), - - - // sprite ROM interface - .sprite_rom_cs(sprite_rom_cs), - .sprite_rom_oe(1), - .sprite_rom_addr(sprite_rom_addr), - .sprite_rom_data(sprite_rom_data), - .sprite_rom_data_valid(sprite_rom_data_valid), - - // sound ROM #1 interface - .sound_rom_1_cs(sound_rom_1_cs), - .sound_rom_1_oe(1), - .sound_rom_1_addr(z80_addr), - .sound_rom_1_data(sound_rom_1_data), - .sound_rom_1_data_valid(sound_rom_1_data_valid), - - // IOCTL interface - .ioctl_addr(ioctl_addr), - .ioctl_data(ioctl_dout), - .ioctl_index(ioctl_index), - .ioctl_wr(ioctl_wr), - .ioctl_download(ioctl_download), - - // SDRAM interface - .sdram_addr(sdram_addr), - .sdram_data(sdram_data), - .sdram_we(sdram_we), - .sdram_req(sdram_req), - .sdram_ack(sdram_ack), - .sdram_valid(sdram_valid), - .sdram_q(sdram_q) -); - - -cache prog_cache -( - .reset(reset), - .clk(clk_sys), - - // client - .cache_req(prog_rom_cs), - .cache_addr(cpu_a[23:1]), - .cache_valid(prog_rom_data_valid), - .cache_data(prog_rom_data), - - // to rom controller - .rom_req(prog_cache_rom_cs), - .rom_addr(prog_cache_addr), - .rom_valid(prog_cache_valid), - .rom_data(prog_cache_data) -); - -tile_cache tile_cache -( - .reset(reset), - .clk(clk_sys), - - // client - .cache_req(tile_rom_cs), - .cache_addr(tile_rom_addr), - .cache_data(tile_rom_data), - .cache_valid(tile_rom_data_valid), - - // to rom controller - .rom_req(tile_cache_cs), - .rom_addr(tile_cache_addr), - .rom_data(tile_cache_data), - .rom_valid(tile_cache_valid) +mist_video #(.COLOR_DEPTH(5),.SD_HCNT_WIDTH(10)) mist_video( + .clk_sys(clk_72), + .SPI_SCK(SPI_SCK), + .SPI_SS3(SPI_SS3), + .SPI_DI(SPI_DI), + .R(blankn ? r : 5'd0), + .G(blankn ? g : 5'd0), + .B(blankn ? b : 5'd0), + .HSync(~hs), + .VSync(~vs), + .VGA_R(VGA_R), + .VGA_G(VGA_G), + .VGA_B(VGA_B), + .VGA_VS(VGA_VS), + .VGA_HS(VGA_HS), + .no_csync(no_csync), + .rotate({~flipped,rotate}), + .ce_divider(3'd5), // pix clock = 72/6 + .blend(blend), + .scandoubler_disable(scandoublerD), + .scanlines(scanlines), + .ypbpr(ypbpr) + ); + +dac #(16) dacl( + .clk_i(clk_72), + .res_n_i(1), + .dac_i({~laudio[15], laudio[14:0]}), + .dac_o(AUDIO_L) + ); + +dac #(16) dacr( + .clk_i(clk_72), + .res_n_i(1), + .dac_i({~raudio[15], raudio[14:0]}), + .dac_o(AUDIO_R) + ); + +// Common inputs +wire m_up1, m_down1, m_left1, m_right1, m_up1B, m_down1B, m_left1B, m_right1B; +wire m_up2, m_down2, m_left2, m_right2, m_up2B, m_down2B, m_left2B, m_right2B; +wire m_up3, m_down3, m_left3, m_right3, m_up3B, m_down3B, m_left3B, m_right3B; +wire m_up4, m_down4, m_left4, m_right4, m_up4B, m_down4B, m_left4B, m_right4B; +wire m_tilt, m_coin1, m_coin2, m_coin3, m_coin4, m_one_player, m_two_players, m_three_players, m_four_players; +wire [11:0] m_fire1, m_fire2, m_fire3, m_fire4; + +arcade_inputs inputs ( + .clk ( clk_72 ), + .key_strobe ( key_strobe ), + .key_pressed ( key_pressed ), + .key_code ( key_code ), + .joystick_0 ( joystick_0 ), + .joystick_1 ( joystick_1 ), + .rotate ( rotate ), + .orientation ( {~flipped, 1'b0} ), + .joyswap ( joyswap ), + .oneplayer ( 1'b0 ), + .controls ( {m_tilt, m_coin4, m_coin3, m_coin2, m_coin1, m_four_players, m_three_players, m_two_players, m_one_player} ), + .player1 ( {m_up1B, m_down1B, m_left1B, m_right1B, m_fire1, m_up1, m_down1, m_left1, m_right1} ), + .player2 ( {m_up2B, m_down2B, m_left2B, m_right2B, m_fire2, m_up2, m_down2, m_left2, m_right2} ), + .player3 ( {m_up3B, m_down3B, m_left3B, m_right3B, m_fire3, m_up3, m_down3, m_left3, m_right3} ), + .player4 ( {m_up4B, m_down4B, m_left4B, m_right4B, m_fire4, m_up4, m_down4, m_left4, m_right4} ) ); endmodule - - -module cc_shifter -( - input clk_out, - input i, - output o -); - -// We use a two-stages shift-register to synchronize SignalIn_clkA to the clkB clock domain -reg [1:0] r; - -assign o = r[1]; // new signal synchronized to (=ready to be used in) clkB domain - -always @(posedge clk_out) begin - r[0] <= i; - r[1] <= r[0]; // notice that we use clkB -end - -endmodule - - diff --git a/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_zerowing/zerowing0.sv b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_zerowing/zerowing0.sv new file mode 100644 index 00000000..2fba241f --- /dev/null +++ b/Arcade_MiST/Toaplan v1 Hardware/rtl/rtl_zerowing/zerowing0.sv @@ -0,0 +1,2038 @@ +//============================================================================ +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +//============================================================================ + +`default_nettype none + +module emu +( + //Master input clock + input CLK_50M, + + //Async reset from top-level module. + //Can be used as initial reset. + input RESET, + + //Must be passed to hps_io module + inout [48:0] HPS_BUS, + + //Base video clock. Usually equals to CLK_SYS. + output CLK_VIDEO, + + //Multiple resolutions are supported using different CE_PIXEL rates. + //Must be based on CLK_VIDEO + output CE_PIXEL, + + //Video aspect ratio for HDMI. Most retro systems have ratio 4:3. + //if VIDEO_ARX[12] or VIDEO_ARY[12] is set then [11:0] contains scaled size instead of aspect ratio. + output [12:0] VIDEO_ARX, + output [12:0] VIDEO_ARY, + + output [7:0] VGA_R, + output [7:0] VGA_G, + output [7:0] VGA_B, + output VGA_HS, + output VGA_VS, + output VGA_DE, // = ~(VBlank | HBlank) + output VGA_F1, + output [2:0] VGA_SL, + output VGA_SCALER, // Force VGA scaler + + input [11:0] HDMI_WIDTH, + input [11:0] HDMI_HEIGHT, + output HDMI_FREEZE, + +`ifdef MISTER_FB + // Use framebuffer in DDRAM (USE_FB=1 in qsf) + // FB_FORMAT: + // [2:0] : 011=8bpp(palette) 100=16bpp 101=24bpp 110=32bpp + // [3] : 0=16bits 565 1=16bits 1555 + // [4] : 0=RGB 1=BGR (for 16/24/32 modes) + // + // FB_STRIDE either 0 (rounded to 256 bytes) or multiple of pixel size (in bytes) + output FB_EN, + output [4:0] FB_FORMAT, + output [11:0] FB_WIDTH, + output [11:0] FB_HEIGHT, + output [31:0] FB_BASE, + output [13:0] FB_STRIDE, + input FB_VBL, + input FB_LL, + output FB_FORCE_BLANK, + +`ifdef MISTER_FB_PALETTE + // Palette control for 8bit modes. + // Ignored for other video modes. + output FB_PAL_CLK, + output [7:0] FB_PAL_ADDR, + output [23:0] FB_PAL_DOUT, + input [23:0] FB_PAL_DIN, + output FB_PAL_WR, +`endif +`endif + + output LED_USER, // 1 - ON, 0 - OFF. + + // b[1]: 0 - LED status is system status OR'd with b[0] + // 1 - LED status is controled solely by b[0] + // hint: supply 2'b00 to let the system control the LED. + output [1:0] LED_POWER, + output [1:0] LED_DISK, + + // I/O board button press simulation (active high) + // b[1]: user button + // b[0]: osd button + output [1:0] BUTTONS, + + //Audio + input CLK_AUDIO, // 24.576 MHz + output [15:0] AUDIO_L, + output [15:0] AUDIO_R, + output AUDIO_S, // 1 - signed audio samples, 0 - unsigned + output [1:0] AUDIO_MIX, // 0 - no mix, 1 - 25%, 2 - 50%, 3 - 100% (mono) + + //ADC + inout [3:0] ADC_BUS, + + //SD-SPI + output SD_SCK, + output SD_MOSI, + input SD_MISO, + output SD_CS, + input SD_CD, + + //High latency DDR3 RAM interface + //Use for non-critical time purposes + output DDRAM_CLK, + input DDRAM_BUSY, + output [7:0] DDRAM_BURSTCNT, + output [28:0] DDRAM_ADDR, + input [63:0] DDRAM_DOUT, + input DDRAM_DOUT_READY, + output DDRAM_RD, + output [63:0] DDRAM_DIN, + output [7:0] DDRAM_BE, + output DDRAM_WE, + + //SDRAM interface with lower latency + output SDRAM_CLK, + output SDRAM_CKE, + output [12:0] SDRAM_A, + output [1:0] SDRAM_BA, + inout [15:0] SDRAM_DQ, + output SDRAM_DQML, + output SDRAM_DQMH, + output SDRAM_nCS, + output SDRAM_nCAS, + output SDRAM_nRAS, + output SDRAM_nWE, + +`ifdef MISTER_DUAL_SDRAM + //Secondary SDRAM + //Set all output SDRAM_* signals to Z ASAP if SDRAM2_EN is 0 + input SDRAM2_EN, + output SDRAM2_CLK, + output [12:0] SDRAM2_A, + output [1:0] SDRAM2_BA, + inout [15:0] SDRAM2_DQ, + output SDRAM2_nCS, + output SDRAM2_nCAS, + output SDRAM2_nRAS, + output SDRAM2_nWE, +`endif + + input UART_CTS, + output UART_RTS, + input UART_RXD, + output UART_TXD, + output UART_DTR, + input UART_DSR, + +`ifdef MISTER_ENABLE_YC + output [39:0] CHROMA_PHASE_INC, + output YC_EN, + output PALFLAG, +`endif + + // Open-drain User port. + // 0 - D+/RX + // 1 - D-/TX + // 2..6 - USR2..USR6 + // Set USER_OUT to 1 to read from USER_IN. + input [6:0] USER_IN, + output [6:0] USER_OUT, + + input OSD_STATUS +); + +///////// Default values for ports not used in this core ///////// + +assign ADC_BUS = 'Z; +assign USER_OUT = 0; +assign {UART_RTS, UART_TXD, UART_DTR} = 0; +assign {SD_SCK, SD_MOSI, SD_CS} = 'Z; +//assign {SDRAM_DQ, SDRAM_A, SDRAM_BA, SDRAM_CLK, SDRAM_CKE, SDRAM_DQML, SDRAM_DQMH, SDRAM_nWE, SDRAM_nCAS, SDRAM_nRAS, SDRAM_nCS} = 'Z; +//assign {DDRAM_CLK, DDRAM_BURSTCNT, DDRAM_ADDR, DDRAM_DIN, DDRAM_BE, DDRAM_RD, DDRAM_WE} = '0; +assign VGA_F1 = 0; +assign VGA_SCALER = 0; +assign HDMI_FREEZE = 0; + +assign AUDIO_MIX = 0; +assign LED_USER = ioctl_download & cpu_a[0]; +assign LED_DISK = 0; +assign LED_POWER = 0; +assign BUTTONS = 0; + +// Status Bit Map: +// Upper Case Lower Case +// 0 1 2 3 4 5 6 +// 01234567890123456789012345678901 23456789012345678901234567890123 +// 0123456789ABCDEFGHIJKLMNOPQRSTUV 0123456789ABCDEFGHIJKLMNOPQRSTUV +// X XXXXXXXXXXX X X XXXXXXXX XX XX XXXXXXXX + +wire [1:0] aspect_ratio = status[9:8]; +wire orientation = ~status[3]; +wire [2:0] scan_lines = status[6:4]; +reg refresh_mod; +reg new_vmode; + +always @(posedge clk_sys) begin + if (refresh_mod != status[19]) begin + refresh_mod <= status[19]; + new_vmode <= ~new_vmode; + end +end + +wire [3:0] hs_offset = status[27:24]; +wire [3:0] vs_offset = status[31:28]; +wire [3:0] hs_width = status[59:56]; +wire [3:0] vs_width = status[63:60]; + +assign VIDEO_ARX = (!aspect_ratio) ? (orientation ? 8'd4 : 8'd3) : (aspect_ratio - 1'd1); +assign VIDEO_ARY = (!aspect_ratio) ? (orientation ? 8'd3 : 8'd4) : 12'd0; + +`include "build_id.v" +localparam CONF_STR = { + "Toaplan V1;;", + "-;", + "P1,Video Settings;", + "P1-;", + "P1O89,Aspect Ratio,Original,Full Screen,[ARC1],[ARC2];", + "P1O3,Orientation,Horz,Vert;", + "P1-;", + "P1O46,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%,CRT 75%,CRT 100%;", + "P1OA,Force Scandoubler,Off,On;", + "P1-;", + "P1O7,Video Mode,NTSC,PAL;", + "P1OM,Video Signal,RGBS/YPbPr,Y/C;", + "P1OJ,Refresh Rate,Native,NTSC;", + "P1-;", + "P1OOR,H-sync Pos Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", + "P1OSV,V-sync Pos Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", + "P1-;", + "P1oOR,H-sync Width Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", + "P1oSV,V-sync Width Adj,0,1,2,3,4,5,6,7,-8,-7,-6,-5,-4,-3,-2,-1;", + "P1-;", + "P2,Audio Settings;", + "P2-;", + "P2oBC,OPL2 Volume,Default,50%,25%,0%;", + "P2-;", + "-;", + "P3,Core Options;", + "P3-;", + "P3o6,Swap P1/P2 Joystick,Off,On;", + "P3-;", + "P3OF,68k Freq.,10Mhz,17.5MHz;", + "P3-;", + "P3o0,Scroll Debug,Off,On;", + "P3-;", + "DIP;", + "-;", + "OK,Pause OSD,Off,When Open;", + "OL,Dim Video,Off,10s;", + "-;", + "R0,Reset;", + "V,v",`BUILD_DATE +}; + +wire hps_forced_scandoubler; +wire forced_scandoubler = hps_forced_scandoubler | status[10]; + +wire [1:0] buttons; +wire [63:0] status; +wire [10:0] ps2_key; +wire [15:0] joy0, joy1; + +hps_io #(.CONF_STR(CONF_STR)) hps_io +( + .clk_sys(clk_sys), + .HPS_BUS(HPS_BUS), + + .buttons(buttons), + .ps2_key(ps2_key), + .status(status), + .status_menumask(direct_video), + .forced_scandoubler(hps_forced_scandoubler), + .gamma_bus(gamma_bus), + .new_vmode(new_vmode), + .direct_video(direct_video), + .video_rotated(video_rotated), + + .ioctl_download(ioctl_download), + .ioctl_upload(ioctl_upload), + .ioctl_wr(ioctl_wr), + .ioctl_addr(ioctl_addr), + .ioctl_dout(ioctl_dout), + .ioctl_din(ioctl_din), + .ioctl_index(ioctl_index), + .ioctl_wait(ioctl_wait), + + .joystick_0(joy0), + .joystick_1(joy1) +); + +// INPUT + +// 8 dip switches of 8 bits +reg [7:0] sw[8]; +always @(posedge clk_sys) begin + if (ioctl_wr && (ioctl_index==254) && !ioctl_addr[24:3]) begin + sw[ioctl_addr[2:0]] <= ioctl_dout; + end +end + +always @(posedge clk_sys) begin + if (ioctl_wr && ioctl_index==1) begin + pcb <= ioctl_dout; + end +end + +wire direct_video; + +wire ioctl_download; +wire ioctl_upload; +wire ioctl_upload_req; +wire ioctl_wait; +wire ioctl_wr; +wire [15:0] ioctl_index; +wire [26:0] ioctl_addr; +wire [15:0] ioctl_dout; +wire [15:0] ioctl_din; + +reg [3:0] pcb; +wire tile_priority_type; +wire [15:0] scroll_y_offset; + +localparam pcb_zero_wing = 0; +localparam pcb_out_zone_conv = 1; +localparam pcb_out_zone = 2; +localparam pcb_hellfire = 3; +localparam pcb_truxton = 4; + +wire [21:0] gamma_bus; + +// +// Inputs tied to z80_din +reg [7:0] p1; +reg [7:0] p2; +reg [7:0] z80_dswa; +reg [7:0] z80_dswb; +reg [7:0] z80_tjump; +reg [7:0] system; + +always @ ( posedge clk_sys ) begin + p1 <= { 1'b0, p1_buttons[2:0], p1_right, p1_left, p1_down, p1_up }; + p2 <= { 1'b0, p2_buttons[2:0], p2_right, p2_left, p2_down, p2_up }; + z80_tjump <= sw[2]; + + if ( pcb == 0 || pcb == 1 || pcb == 2 || pcb == 3 && status[32] == 1 ) begin + // zerowing, hellfire, outzone, outzone conversion debug options + z80_dswa <= sw[0]; + z80_dswb <= { sw[1][7], sw[1][6] | status[32], sw[1][5:0] }; + system <= { vbl, start2 | p1_buttons[3], start1 | p1_buttons[3], coin_b, coin_a, service, key_tilt, key_service }; + end else if ( pcb == 4 && status[32] == 1 ) begin + // truxton debug options + z80_dswa <= { sw[0][7:3], sw[0][2] | status[32], sw[0][1:0] }; + z80_dswb <= sw[1]; + system <= { vbl, start2, start1, coin_b, coin_a, service, key_tilt, key_service }; + end else begin + // default + z80_dswa <= sw[0]; + z80_dswb <= sw[1]; + system <= { vbl, start2, start1, coin_b, coin_a, service, key_tilt, key_service }; + end +end + +reg p1_swap; + +reg p1_right; +reg p1_left; +reg p1_down; +reg p1_up; +reg [3:0] p1_buttons; + +reg p2_right; +reg p2_left; +reg p2_down; +reg p2_up; +reg [3:0] p2_buttons; + +reg start1; +reg start2; +reg coin_a; +reg coin_b; +reg b_pause; +reg service; + +always @ * begin + p1_swap <= status[38]; + + if ( status[38] == 0 ) begin + p1_right <= joy0[0] | key_p1_right; + p1_left <= joy0[1] | key_p1_left; + p1_down <= joy0[2] | key_p1_down; + p1_up <= joy0[3] | key_p1_up; + p1_buttons <= joy0[7:4] | {key_p1_c, key_p1_b, key_p1_a}; + + p2_right <= joy1[0] | key_p2_right; + p2_left <= joy1[1] | key_p2_left; + p2_down <= joy1[2] | key_p2_down; + p2_up <= joy1[3] | key_p2_up; + p2_buttons <= joy1[7:4] | {key_p2_c, key_p2_b, key_p2_a}; + end else begin + p2_right <= joy0[0] | key_p1_right; + p2_left <= joy0[1] | key_p1_left; + p2_down <= joy0[2] | key_p1_down; + p2_up <= joy0[3] | key_p1_up; + p2_buttons <= joy0[7:4] | {key_p1_c, key_p1_b, key_p1_a}; + + p1_right <= joy1[0] | key_p2_right; + p1_left <= joy1[1] | key_p2_left; + p1_down <= joy1[2] | key_p2_down; + p1_up <= joy1[3] | key_p2_up; + p1_buttons <= joy1[7:4] | {key_p2_c, key_p2_b, key_p2_a}; + end +end + +always @ * begin + start1 <= joy0[8] | joy1[8] | key_start_1p; + start2 <= joy0[9] | joy1[9] | key_start_2p; + + coin_a <= joy0[10] | joy1[10] | key_coin_a; + coin_b <= joy0[11] | joy1[11] | key_coin_b; + + b_pause <= joy0[12] | key_pause; + service <= key_test; +end + +// Keyboard handler + +reg key_start_1p, key_start_2p, key_coin_a, key_coin_b; +reg key_tilt, key_test, key_reset, key_service, key_pause; + +reg key_p1_up, key_p1_left, key_p1_down, key_p1_right, key_p1_a, key_p1_b, key_p1_c; +reg key_p2_up, key_p2_left, key_p2_down, key_p2_right, key_p2_a, key_p2_b, key_p2_c; + +wire pressed = ps2_key[9]; + +always @(posedge clk_sys) begin + reg old_state; + old_state <= ps2_key[10]; + if ( old_state ^ ps2_key[10] ) begin + casex ( ps2_key[8:0] ) + 'h016 : key_start_1p <= pressed; // 1 + 'h01E : key_start_2p <= pressed; // 2 + 'h02E : key_coin_a <= pressed; // 5 + 'h036 : key_coin_b <= pressed; // 6 + 'h006 : key_test <= key_test ^ pressed; // f2 + 'h004 : key_reset <= pressed; // f3 + 'h046 : key_service <= pressed; // 9 + 'h02C : key_tilt <= pressed; // t + 'h04D : key_pause <= pressed; // p + + 'h175 : key_p1_up <= pressed; // up + 'h172 : key_p1_down <= pressed; // down + 'h16B : key_p1_left <= pressed; // left + 'h174 : key_p1_right <= pressed; // right + 'h014 : key_p1_a <= pressed; // lctrl + 'h011 : key_p1_b <= pressed; // lalt + 'h029 : key_p1_c <= pressed; // spacebar + + 'h02D : key_p2_up <= pressed; // r + 'h02B : key_p2_down <= pressed; // f + 'h023 : key_p2_left <= pressed; // d + 'h034 : key_p2_right <= pressed; // g + 'h01C : key_p2_a <= pressed; // a + 'h01B : key_p2_b <= pressed; // s + 'h015 : key_p2_c <= pressed; // q + endcase + end +end + +wire pll_locked; + +wire clk_sys; +wire turbo_68k = status[15]; +reg clk_3_5M, clk_7M, clk_10M, clk_14M; + +wire clk_70M; + +pll pll +( + .refclk(CLK_50M), + .rst(0), + .outclk_0(clk_sys), + .outclk_1(clk_70M), + .locked(pll_locked) +); + +assign SDRAM_CLK = clk_70M; + +localparam CLKSYS=70; + +reg [5:0] clk14_count; +reg [5:0] clk10_count; +reg [5:0] clk7_count; +reg [5:0] clk_3_5_count; + +always @ (posedge clk_sys ) begin + clk_10M <= 0; + if ( turbo_68k == 0 ) begin + // standard speed 20MHz = 10MHz 68k + case (clk10_count) + 1: clk_10M <= 1; + 3: clk_10M <= 1; + endcase + if ( clk10_count == 6 ) begin + clk10_count <= 0; + end else if ( pause_cpu == 0 ) begin + clk10_count <= clk10_count + 1; + end + end else begin + // standard speed 35MHz = 17.5MHz 68k + case (clk10_count) + 1: clk_10M <= 1; + endcase + if ( clk10_count == 1 ) begin + clk10_count <= 0; + end else if ( pause_cpu == 0 ) begin + clk10_count <= clk10_count + 1; + end + end + clk_7M <= ( clk7_count == 0); + if ( clk7_count == 9 ) begin + clk7_count <= 0; + end else begin + clk7_count <= clk7_count + 1; + end + clk_14M <= ( clk14_count == 0); + if ( clk14_count == 4 ) begin + clk14_count <= 0; + end else begin + clk14_count <= clk14_count + 1; + end + clk_3_5M <= ( clk_3_5_count == 0); + if ( clk_3_5_count == 19 ) begin + clk_3_5_count <= 0; + end else if ( pause_cpu == 0 ) begin + clk_3_5_count <= clk_3_5_count + 1; + end +end + +wire reset; +assign reset = RESET | status[0] | (ioctl_download & !ioctl_index) | buttons[1] | key_reset; + +////////////////////////////////////////////////////////////////// +wire rotate_ccw = 1; +wire no_rotate = orientation | direct_video; +wire video_rotated; + +reg [23:0] rgb; + +wire hbl; +wire vbl; + +wire [8:0] hc; +wire [8:0] vc; + +wire hsync; +wire vsync; + +reg hbl_delay, vbl_delay; + +always @ ( posedge clk_7M ) begin + hbl_delay <= hbl; + vbl_delay <= vbl; +end + +video_timing video_timing ( + .clk(clk_7M), + .reset(reset), + .crtc0(crtc[0]), + .crtc1(crtc[1]), + .crtc2(crtc[2]), + .crtc3(crtc[3]), + .hs_offset(hs_offset), + .vs_offset(vs_offset), + .hs_width(hs_width), + .vs_width(vs_width), + .refresh_mod(refresh_mod), + .hc(hc), + .vc(vc), + .hbl_delay(hbl), + .vbl(vbl), + .hsync(hsync), + .vsync(vsync) +); + +// PAUSE SYSTEM +wire pause_cpu; +wire hs_pause; + +// 8 bits per colour, 70MHz sys clk +pause #(8,8,8,70) pause +( + .clk_sys(clk_sys), + .reset(reset), + .user_button(b_pause), + .pause_request(hs_pause), + .options(status[21:20]), + .pause_cpu(pause_cpu), + .dim_video(dim_video), + .OSD_STATUS(OSD_STATUS), + .r(rgb[23:16]), + .g(rgb[15:8]), + .b(rgb[7:0]), + .rgb_out(rgb_pause_out) +); + +wire [23:0] rgb_pause_out; +wire dim_video; + +arcade_video #(320,24) arcade_video +( + .*, + + .clk_video(clk_sys), + .ce_pix(clk_7M), + + .RGB_in(rgb_pause_out), + + .HBlank(hbl), + .VBlank(vbl), + .HSync(hsync), + .VSync(vsync), + + .fx(scan_lines) +); + +/* + Phase Accumulator Increments (Fractional Size 32, look up size 8 bit, total 40 bits) + Increment Calculation - (Output Clock * 2 ^ Word Size) / Reference Clock + Example + NTSC = 3.579545 + PAL = 4.43361875 + W = 40 ( 32 bit fraction, 8 bit look up reference) + Ref CLK = 42.954544 (This could us any clock) + NTSC_Inc = 3.579545333 * 2 ^ 40 / 96 = 40997413706 +*/ + +// SET PAL and NTSC TIMING +`ifdef MISTER_ENABLE_YC + assign CHROMA_PHASE_INC = PALFLAG ? 40'd56225080500: 40'd56225080500; + assign YC_EN = status[22]; + assign PALFLAG = status[7]; +`endif + +screen_rotate screen_rotate (.*); + +wire [9:0] sprite_adj_x = 0; +wire [9:0] sprite_adj_y = 0; +wire bcu_flip_cs; +wire fcu_flip_cs; + +reg [1:0] adj_layer; +reg [15:0] scroll_adj_x [3:0]; +reg [15:0] scroll_adj_y [3:0]; +reg layer_en [3:0]; + +reg ce_pix; + +// flip is done in the rendering so leave screen_rotate flip off +wire flip = 0; + +reg tile_flip; +reg sprite_flip; + +//assign vc = vcx - vs_offset; + +// =============================================================== +// 68000 CPU +// =============================================================== + +// clock generation +reg fx68_phi1 = 0; +wire fx68_phi2 = !fx68_phi1; + +// phases for 68k clock +always @(posedge clk_sys) begin + if ( clk_10M == 1 ) begin + fx68_phi1 <= ~fx68_phi1; + end +end + +// CPU outputs +wire cpu_rw; // Read = 1, Write = 0 +wire cpu_as_n; // Address strobe +wire cpu_lds_n; // Lower byte strobe +wire cpu_uds_n; // Upper byte strobe +wire cpu_E; +wire [2:0]cpu_fc; // Processor state +wire cpu_reset_n_o; // Reset output signal +wire cpu_halted_n; // Halt output + +// CPU busses +wire [15:0] cpu_dout; +wire [23:0] cpu_a /* synthesis keep */; +reg [15:0] cpu_din; + +// CPU inputs +reg dtack_n; // Data transfer ack (always ready) +reg ipl2_n; + +wire reset_n; +wire vpa_n = ~ ( cpu_lds_n == 0 && cpu_fc == 3'b111 ); // from outzone schematic + +assign cpu_a[0] = reset; // debug hack odd memory address should cause cpu exception + +cc_shifter cc_reset ( + .clk_out(clk_10M), + .i(reset_z80_n), + .o(reset_n) +); + +fx68k fx68k ( + // input + .clk( clk_10M ), + .enPhi1(fx68_phi1), + .enPhi2(fx68_phi2), + .extReset(reset), + .pwrUp(reset), + + // output + .eRWn(cpu_rw), + .ASn( cpu_as_n), + .LDSn(cpu_lds_n), + .UDSn(cpu_uds_n), +// .E(cpu_E), +// .VMAn(), + .FC0(cpu_fc[0]), + .FC1(cpu_fc[1]), + .FC2(cpu_fc[2]), +// .BGn(), + .oRESETn(cpu_reset_n_o), + .oHALTEDn(cpu_halted_n), + + // input + .VPAn( vpa_n ), + .DTACKn(dtack_n ), + .BERRn(1'b1), + .BRn(1'b1), + .BGACKn(1'b1), + + .IPL0n(1'b1), + .IPL1n(1'b1), + .IPL2n(ipl2_n), + + // busses + .iEdb(cpu_din), + .oEdb(cpu_dout), + .eab(cpu_a[23:1]) +); + +always @ (posedge clk_sys) begin + if ( clk_10M == 1 ) begin + // tell 68k to wait for valid data. 0=ready 1=wait + // always ack when it's not program rom + dtack_n <= prog_rom_cs ? !prog_rom_data_valid : 0; + // add dsp_ctrl_cs to cpu_din + // select cpu data input based on what is active + cpu_din <= prog_rom_cs ? prog_rom_data : + ram_cs ? ram_dout : + tile_palette_cs ? tile_palette_cpu_dout : + sprite_palette_cs ? sprite_palette_cpu_dout : + shared_ram_cs ? cpu_shared_dout : + tile_ofs_cs ? curr_tile_ofs : + sprite_ofs_cs ? curr_sprite_ofs : + tile_attr_cs ? cpu_tile_dout_attr : + tile_num_cs ? cpu_tile_dout_num : + sprite_0_cs ? sprite_0_dout : + sprite_1_cs ? sprite_1_dout : + sprite_2_cs ? sprite_2_dout : + sprite_3_cs ? sprite_3_dout : + sprite_size_cs ? sprite_size_cpu_dout : + frame_done_cs ? { 16 { vbl } } : // get vblank state + vblank_cs ? { 15'b0, vbl } : + int_en_cs ? 16'hffff : + 16'd0; + end +end + +wire [15:0] cpu_shared_dout; +wire [7:0] z80_shared_dout; +reg [15:0] z80_a; + +wire [15:0] z80_addr; +reg [7:0] z80_din; +wire [7:0] z80_dout; + +wire z80_wr_n; +wire z80_rd_n; +reg z80_wait_n; + +wire IORQ_n; +wire MREQ_n; + +always @ (posedge clk_sys) begin + if ( reset == 1 ) begin + z80_wait_n <= 0; + sound_wr <= 0; + end else if ( clk_3_5M == 1 ) begin + z80_wait_n <= 1; + if ( ioctl_download | ( z80_rd_n == 0 && sound_rom_1_data_valid == 0 && sound_rom_1_cs == 1 ) ) begin + // wait if rom is selected and data is not yet available + z80_wait_n <= 0; + end + if ( z80_rd_n == 0 ) begin + if ( sound_rom_1_cs ) begin + if ( sound_rom_1_data_valid ) begin + z80_din <= sound_rom_1_data; + end else begin + z80_wait_n <= 0; + end + end else if ( sound_ram_1_cs ) begin + z80_din <= z80_shared_dout; + end else if ( z80_p1_cs ) begin + z80_din <= p1; + end else if ( z80_p2_cs ) begin + z80_din <= p2; + end else if ( z80_dswa_cs ) begin + z80_din <= z80_dswa; + end else if ( z80_dswb_cs ) begin + z80_din <= z80_dswb; + end else if ( z80_tjump_cs ) begin + z80_din <= z80_tjump; + end else if ( z80_system_cs ) begin + z80_din <= system; + end else if ( z80_sound0_cs ) begin + z80_din <= opl_dout; + end else begin + z80_din <= 8'h00; + end + end + sound_wr <= 0; + if ( z80_wr_n == 0 ) begin + if ( z80_sound0_cs | z80_sound1_cs ) begin + sound_data <= z80_dout; + sound_addr <= { 1'b0, z80_sound1_cs }; // pad for opl3. opl2 is single bit address + sound_wr <= 1; + end + end + end +end + +reg [1:0] sound_addr; +reg [7:0] sound_data; +reg sound_wr; + +wire [7:0] opl_dout; +wire opl_irq_n; + +reg signed [15:0] sample; + +assign AUDIO_S = 1'b1; + +wire opl_sample_clk; + +jtopl #(.OPL_TYPE(2)) jtopl2 +( + .rst(~reset_n), + .clk(clk_sys), + .cen(clk_3_5M), + .din(sound_data), + .addr(sound_addr), + .cs_n('0), + .wr_n(~sound_wr), + .dout(opl_dout), + .irq_n(opl_irq_n), + .snd(sample), + .sample(opl_sample_clk) +); + +wire [1:0] opl2_level = status[44:43]; // opl2 audio mix + +reg [7:0] opl2_mult; + +// set the multiplier for each channel from menu + +always @( posedge clk_sys, posedge reset ) begin + if (reset) begin + opl2_mult<=0; + end else begin + case( opl2_level ) + 0: opl2_mult <= 8'h0c; // 75% + 1: opl2_mult <= 8'h08; // 50% + 2: opl2_mult <= 8'h04; // 25% + 3: opl2_mult <= 8'h00; // 0% + endcase + end +end + +wire signed [15:0] mono; + +jtframe_mixer #(.W0(16), .WOUT(16)) u_mix_mono( + .rst ( reset ), + .clk ( clk_sys ), + .cen ( 1'b1 ), + // input signals + .ch0 ( sample ), + .ch1 ( 16'd0 ), + .ch2 ( 16'd0 ), + .ch3 ( 16'd0 ), + // gain for each channel in 4.4 fixed point format + .gain0 ( opl2_mult ), + .gain1 ( 8'd0 ), + .gain2 ( 8'd0 ), + .gain3 ( 8'd0 ), + .mixed ( mono ), + .peak ( ) +); + +always @ (posedge clk_sys ) begin + if ( pause_cpu == 1 ) begin + AUDIO_L <= 0; + AUDIO_R <= 0; + end else if ( pause_cpu == 0 ) begin + // mix audio + AUDIO_L <= mono; + AUDIO_R <= mono; + end +end + +T80pa u_cpu( + .RESET_n ( reset_n ), + .CLK ( clk_sys ), + .CEN_p ( clk_3_5M ), + .CEN_n ( ~clk_3_5M ), + + .WAIT_n ( z80_wait_n ), // don't wait if data is valid or rom access isn't selected + .INT_n ( opl_irq_n ), // opl timer + .NMI_n ( 1'b1 ), + .BUSRQ_n ( 1'b1 ), + .RD_n ( z80_rd_n ), + .WR_n ( z80_wr_n ), + .A ( z80_addr ), + .DI ( z80_din ), + .DO ( z80_dout ), + // unused + .DIRSET ( 1'b0 ), + .DIR ( 212'b0 ), + .OUT0 ( 1'b0 ), + .RFSH_n (), + .IORQ_n ( IORQ_n ), + .M1_n (), + .BUSAK_n (), + .HALT_n ( 1'b1 ), + .MREQ_n ( MREQ_n ), + .Stop (), + .REG () +); + +// Chip select mux +wire prog_rom_cs; +wire scroll_ofs_x_cs; +wire scroll_ofs_y_cs; +wire ram_cs; +wire vblank_cs; +wire int_en_cs; +wire crtc_cs; +wire tile_ofs_cs; +wire tile_attr_cs; +wire tile_num_cs; +wire scroll_cs; +wire shared_ram_cs; +wire frame_done_cs; // word +wire tile_palette_cs; +wire sprite_palette_cs; +wire sprite_ofs_cs; +wire sprite_cs; // *** offset needs to be auto-incremented +wire sprite_size_cs; // *** offset needs to be auto-incremented +wire sprite_ram_cs; + +wire z80_p1_cs; +wire z80_p2_cs; +wire z80_dswa_cs; +wire z80_dswb_cs; +wire z80_system_cs; +wire z80_tjump_cs; +wire z80_sound0_cs; +wire z80_sound1_cs; + +chip_select cs (.*); + +wire sprite_0_cs = ( curr_sprite_ofs[1:0] == 2'b00 ) & sprite_cs; +wire sprite_1_cs = ( curr_sprite_ofs[1:0] == 2'b01 ) & sprite_cs; +wire sprite_2_cs = ( curr_sprite_ofs[1:0] == 2'b10 ) & sprite_cs; +wire sprite_3_cs = ( curr_sprite_ofs[1:0] == 2'b11 ) & sprite_cs; + +reg reset_z80_n; +wire reset_z80_cs; +wire sound_rom_1_cs = ( MREQ_n == 0 && z80_addr <= 16'h7fff ); +wire sound_ram_1_cs = ( MREQ_n == 0 && z80_addr >= 16'h8000 && z80_addr <= 16'h87ff ); + +reg int_en; +reg int_ack; + +reg [1:0] vbl_sr; + +// vblank interrupt on rising vbl +always @ (posedge clk_sys ) begin + if ( reset == 1 ) begin + ipl2_n <= 1; + int_ack <= 0; + end else begin + vbl_sr <= { vbl_sr[0], vbl }; + if ( clk_10M == 1 ) begin + int_ack <= ( cpu_as_n == 0 ) && ( cpu_fc == 3'b111 ); // cpu acknowledged the interrupt + end + if ( vbl_sr == 2'b01 ) begin// rising edge + ipl2_n <= ~int_en; + end else if ( int_ack == 1 || vbl_sr == 2'b10 ) begin + ipl2_n <= 1; + end + end +end + +reg [15:0] scroll_x [3:0]; +reg [15:0] scroll_y [3:0]; + +reg [15:0] scroll_x_latch [3:0]; +reg [15:0] scroll_y_latch [3:0]; + +reg inc_sprite_ofs; + +reg [15:0] crtc[4]; + +always @ (posedge clk_sys) begin + if ( reset == 1 ) begin + int_en <= 0; + reset_z80_n <= 0; + end else begin + if ( pcb != 3 && pcb != 4 ) begin + // if the pcb uses the 68k reset pin to drive the reset line + reset_z80_n <= cpu_reset_n_o; + end + // write asserted and rising cpu clock + if ( clk_10M == 1 && cpu_rw == 0 ) begin + if ( tile_ofs_cs ) begin + curr_tile_ofs <= cpu_dout; + end + if ( int_en_cs ) begin + int_en <= cpu_dout[0]; + end + if ( crtc_cs ) begin + crtc[ cpu_a[2:1] ] <= cpu_dout; + end + if ( bcu_flip_cs ) begin + tile_flip <= cpu_dout[0]; + end + if ( fcu_flip_cs ) begin + sprite_flip <= cpu_dout[15]; + end + if ( sprite_ofs_cs ) begin + // mask out valid range + curr_sprite_ofs <= { 6'b0, cpu_dout[9:0] }; + end + if ( scroll_ofs_x_cs ) begin + scroll_ofs_x <= cpu_dout; + end + if ( scroll_ofs_y_cs ) begin + scroll_ofs_y <= cpu_dout; + end + // x layer values are even addresses + if ( scroll_cs ) begin + if ( cpu_a[1] == 0 ) begin + scroll_x[ cpu_a[3:2] ] <= cpu_dout[15:7]; + end else begin + scroll_y[ cpu_a[3:2] ] <= cpu_dout[15:7]; + end + end + // offset needs to be auto-incremented + if ( sprite_cs | sprite_size_cs ) begin + inc_sprite_ofs <= 1; + end + if ( reset_z80_cs ) begin + // the pcb writes to a latch to control the reset + reset_z80_n <= cpu_dout[0]; + end + end + // write lasts multiple cpu clocks so limit to one increment per write signal + if ( inc_sprite_ofs == 1 && cpu_rw == 1 ) begin + curr_sprite_ofs <= curr_sprite_ofs + 1; + inc_sprite_ofs <= 0; + end + end +end + +reg [15:0] scroll_x_total [3:0]; +reg [15:0] scroll_y_total [3:0]; + +wire [15:0] ram_dout; +wire [9:0] tile_palette_addr; +wire [15:0] tile_palette_cpu_dout; +wire [15:0] tile_palette_dout; + +wire [9:0] sprite_palette_addr; +wire [15:0] sprite_palette_cpu_dout; +wire [15:0] sprite_palette_dout; + +reg [15:0] curr_tile_ofs; +reg [15:0] curr_sprite_ofs; + +reg [15:0] scroll_ofs_x; +reg [15:0] scroll_ofs_y; + +wire [15:0] cpu_tile_dout_attr; +wire [15:0] cpu_tile_dout_num; + +wire [15:0] sprite_0_dout; +wire [15:0] sprite_1_dout; +wire [15:0] sprite_2_dout; +wire [15:0] sprite_3_dout; +wire [15:0] sprite_size_dout; +wire [15:0] sprite_size_cpu_dout; + +wire [31:0] tile_attr_dout; +wire [15:0] sprite_attr_0_dout; +wire [15:0] sprite_attr_1_dout; +wire [15:0] sprite_attr_2_dout; +wire [15:0] sprite_attr_3_dout; + +wire [15:0] sprite_size_buf_dout; +wire [15:0] sprite_attr_0_buf_dout; +wire [15:0] sprite_attr_1_buf_dout; +wire [15:0] sprite_attr_2_buf_dout; +wire [15:0] sprite_attr_3_buf_dout; + +reg [15:0] sprite_buf_din; + +reg [14:0] tile; + +reg [7:0] sprite_num; +reg [7:0] sprite_num_copy; + +reg [3:0] tile_draw_state; + +reg [2:0] layer; // 4 layers + 1 for initial background + +wire [14:0] tile_idx = tile_attr[14:0]; +wire [3:0] tile_priority = tile_attr[31:28]; +wire [5:0] tile_palette_idx = tile_attr[21:16]; +wire tile_hidden = tile_attr[15]; + +reg [15:0] fb_dout; +wire [15:0] tile_fb_out; +wire [15:0] sprite_fb_out; +reg [15:0] fb_din; +reg [15:0] sprite_fb_din; + +reg tile_fb_w; +reg sprite_fb_w; +reg sprite_buf_w; +reg sprite_size_buf_w; + +dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) tile_line_buffer ( + .clock_a ( clk_sys ), + .address_a ( tile_fb_addr_w ), + .wren_a ( tile_fb_w ), + .data_a ( fb_din ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( fb_addr_r ), + .wren_b ( 0 ), +// .data_b ( ), + .q_b ( tile_fb_out ) +); + +dual_port_ram #(.LEN(1024), .DATA_WIDTH(16)) sprite_line_buffer ( + .clock_a ( clk_sys ), + .address_a ( sprite_fb_addr_w ), + .wren_a ( sprite_fb_w ), + .data_a ( sprite_fb_din ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( fb_addr_r ), + .wren_b ( 0 ), +// .data_b ( ), + .q_b ( sprite_fb_out ) +); + +reg [9:0] x_ofs; +reg [9:0] x; + +reg [9:0] y_ofs; + +// y needs to be one line ahaed of the visible line +// render the first line at the end of the previous frame +// this depends on the timing that the sprite list is valid +// sprites values are copied at the start of vblank (line 240) + +// global offsets +wire [9:0] x_ofs_dx = 495 + { ~layer[1:0], 1'b0 }; +wire [9:0] y_ofs_dx = 257; +wire [9:0] x_ofs_dx_flipped = 17 - { ~layer[1:0], 1'b0 }; +wire [9:0] y_ofs_dx_flipped = 255; + +// calculate scrolling +wire [9:0] tile_x_unflipped = scroll_x_latch[layer[1:0]] + x_ofs_dx; +wire [9:0] tile_y_unflipped = scroll_y_latch[layer[1:0]] + y_ofs_dx + scroll_y_offset; +wire [9:0] tile_x_flipped = 319 + scroll_x_latch[layer[1:0]] + x_ofs_dx_flipped; +wire [9:0] tile_y_flipped = 239 + scroll_y_latch[layer[1:0]] + y_ofs_dx_flipped + scroll_y_offset; + +// reverse tiles when flipped +wire [9:0] curr_x = tile_flip ? tile_x_flipped - x : tile_x_unflipped + x; +wire [9:0] curr_y = tile_flip ? tile_y_flipped - y : tile_y_unflipped + y; + +reg [9:0] y; +wire [9:0] y_flipped = ( sprite_flip ? (240 - y ) + scroll_y_offset : y + scroll_y_offset); +wire [9:0] sprite_buf_x = sprite_flip ? 320 - (sprite_x + sprite_pos_x ) : sprite_x + sprite_pos_x; // offset from left of frame + +reg [3:0] draw_state; +reg [3:0] sprite_state; +reg [3:0] tile_copy_state; +reg [3:0] sprite_copy_state; + +// pixel 4 bit colour +wire [3:0] tile_pix; +assign tile_pix = { tile_data[7-curr_x[2:0]], tile_data[15-curr_x[2:0]], tile_data[23-curr_x[2:0]], tile_data[31-curr_x[2:0]] }; + +wire [2:0] sprite_bit = sprite_x[2:0]; +wire [3:0] sprite_pix; +assign sprite_pix = { sprite_data[7-sprite_bit], sprite_data[15-sprite_bit], sprite_data[23-sprite_bit], sprite_data[31-sprite_bit] }; + +// two lines of buffer alternate +reg [9:0] tile_fb_addr_w; +wire [9:0] fb_addr_r = {vc[0], 9'b0 } + hc; + +reg [9:0] sprite_fb_addr_w; + +reg [31:0] tile_attr; + +// two lines worth for 4 layers (~8k) +// [15:14] = layer. +// [13:10] = prioity +// [9:4] = palette offset +// [3:0] = tile colour index. + +reg [3:0] tile_priority_buf [327:0]; +reg [3:0] sprite_priority_buf [327:0]; + +reg [9:0] sprite_x; // offset from left side of sprite +reg [9:0] sprite_y; + +wire [14:0] sprite_index = sprite_attr_0_buf_dout[14:0] /* synthesis keep */; +wire sprite_hidden = sprite_attr_0_buf_dout[15] /* synthesis keep */; + +wire [5:0] sprite_pal_addr = sprite_attr_1_buf_dout[5:0] /* synthesis keep */; +wire [5:0] sprite_size_addr = sprite_attr_1_buf_dout[11:6] /* synthesis keep */; +wire [3:0] sprite_priority = sprite_attr_1_buf_dout[15:12] /* synthesis keep */; + +wire [9:0] sprite_pos_x = sprite_adj_x + (( sprite_attr_2_buf_dout[15:7] < 9'h180 ) ? sprite_attr_2_buf_dout[15:7] : ( sprite_attr_2_buf_dout[15:7] - 10'h200)); +wire [9:0] sprite_pos_y = sprite_adj_y + (( sprite_attr_3_buf_dout[15:7] < 9'h180 ) ? sprite_attr_3_buf_dout[15:7] : ( sprite_attr_3_buf_dout[15:7] - 10'h200)); + +// valid 1 cycle after sprite attr ready +wire [8:0] sprite_height = { sprite_size_buf_dout[7:4], 3'b0 } /* synthesis keep */; // in pixels +wire [8:0] sprite_width = { sprite_size_buf_dout[3:0], 3'b0 } /* synthesis keep */; + +reg [7:0] sprite_buf_num; + +reg [1:0] vtotal_282_flag; + +always @ (posedge clk_sys) begin // Check System Vcount flag for 60Hz mode + if ({crtc[2][7:0], 1'b1 } == 269) + vtotal_282_flag <= 0; + else + vtotal_282_flag <= 1; +end + +always @ (posedge clk_sys) begin + if ( reset == 1 ) begin + sprite_state <= 0; + draw_state <= 0; + sprite_rom_cs <= 0; + tile_rom_cs <= 0; + tile_copy_state <= 0; + sprite_copy_state <= 0; + tile_draw_state <= 0; + end else begin + // render sprites + // triggered when the tile rendering starts + if ( sprite_state == 0 && draw_state > 0 ) begin + sprite_num <= 8'h00; + sprite_x <= 0; + sprite_fb_w <= 1; + sprite_state <= 1; + sprite_fb_din <= 0; + sprite_fb_addr_w <= { y[0], 9'b0 }; + end else if ( sprite_state == 1 ) begin + // erase line buffer + sprite_fb_addr_w <= { y[0], 9'b0 } + sprite_x; + sprite_priority_buf[sprite_x] <= 0; + if ( sprite_x < 320 ) begin + sprite_x <= sprite_x + 1; + end else begin + sprite_x <= 0; + sprite_fb_w <= 0; + sprite_state <= 2; + end + end else if ( sprite_state == 2 ) begin + // sprite num is valid now + sprite_state <= 3; + end else if ( sprite_state == 3 ) begin + // sprite attr valid now. + // delay one more cycle to read sprite size + sprite_state <= 4; + end else if ( sprite_state == 4 ) begin + // start loop + sprite_rom_cs <= 0; + sprite_fb_w <= 0; + sprite_y <= y_flipped - sprite_pos_y; + // is sprite visible and is current y in sprite y range + // sprite pos can be negative? + if ( sprite_hidden == 0 && sprite_width > 0 && ( $signed(y_flipped) >= $signed(sprite_pos_y) ) && $signed(y_flipped) < ( $signed(sprite_pos_y) + $signed(sprite_height) ) ) begin + sprite_state <= 5; + end else if ( sprite_num < 8'hff ) begin + sprite_num <= sprite_num + 1; + sprite_state <= 2; + end else begin + sprite_state <= 15; + end + end else if ( sprite_state == 5 ) begin + sprite_rom_addr <= { sprite_index, 3'b0 } + { sprite_x[8:3], 3'b0 } + ( sprite_y[8:3] * sprite_width ) + sprite_y[2:0]; + sprite_rom_cs <= 1; + sprite_state <= 6; + end else if ( sprite_state == 6 ) begin + // wait for sprite bitmap ready + if ( sprite_rom_data_valid ) begin + // latch data and deassert cs + sprite_data <= sprite_rom_data; + sprite_rom_cs <= 0; + sprite_state <= 7; + end + end else if ( sprite_state == 7 ) begin + sprite_fb_w <= 0; + // draw if pixel value not zero and priority >= previous sprite data +// if ( sprite_pix > 0 && sprite_priority_buf[sprite_buf_x] == 0 ) begin +// if ( sprite_pix != 0 && ( sprite_priority == 0 || sprite_priority >= sprite_priority_buf[sprite_buf_x] ) ) begin + if ( sprite_pix != 0 ) begin + sprite_fb_din <= { 2'b11, sprite_priority, sprite_pal_addr, sprite_pix }; +// if ( sprite_priority == 0 ) begin +// sprite_priority_buf[sprite_buf_x] <= { 1'b1, sprite_priority }; +// end else begin + sprite_fb_addr_w <= { y[0], 9'b0 } + sprite_buf_x; + sprite_priority_buf[sprite_buf_x] <= sprite_priority; + sprite_fb_w <= 1; + end + if ( sprite_x < ( sprite_width - 1 ) ) begin + sprite_x <= sprite_x + 1; + if ( sprite_x[2:0] == 7 ) begin + // do recalc bitmap address + sprite_state <= 5; + end + end else if ( sprite_num < 8'hff ) begin + sprite_num <= sprite_num + 1; + sprite_x <= 0; + // need to load new attributes and size + sprite_state <= 2; + end else begin + // tile state machine will reset sprite_state when line completes. + sprite_state <= 15; // done + end + end + // copy tile ram and scroll info + // not sure if this is needed. need to check to see when tile ram is updated. + if ( tile_copy_state == 0 && vc == 256 ) begin + tile_copy_state <= 1; + end else begin + // copy scroll registers + scroll_x_latch[0] <= scroll_x[0] - scroll_ofs_x; + scroll_x_latch[1] <= scroll_x[1] - scroll_ofs_x; + scroll_x_latch[2] <= scroll_x[2] - scroll_ofs_x; + scroll_x_latch[3] <= scroll_x[3] - scroll_ofs_x; + scroll_y_latch[0] <= scroll_y[0] - scroll_ofs_y; + scroll_y_latch[1] <= scroll_y[1] - scroll_ofs_y; + scroll_y_latch[2] <= scroll_y[2] - scroll_ofs_y; + scroll_y_latch[3] <= scroll_y[3] - scroll_ofs_y; + end + // copy sprite attr/size to buffer + if ( sprite_copy_state == 0 && vc == 240 ) begin + sprite_copy_state <= 1; + sprite_buf_w <= 0; + sprite_num_copy <= 8'h00; + end else if ( sprite_copy_state == 1 ) begin + sprite_num_copy <= sprite_num_copy + 1; + sprite_buf_num <= sprite_num_copy; + sprite_buf_w <= 1; + // wait for read from source + if ( sprite_num_copy == 8'hff ) begin + sprite_copy_state <= 2; + end + end else if ( sprite_copy_state == 2 ) begin + sprite_buf_w <= 0; + sprite_copy_state <= 0; + end + // tile state machine + if ( draw_state == 0 && vc == ({ crtc[2][7:0], 1'b1 } - (status[19] ? (vtotal_282_flag ? 5'd19 : 4'd7) : 3'd0)) ) begin // 282 Lines standard (263 Lines for 60Hz) + layer <= 4; // layer 4 is layer 0 but draws hidden and transparent + y <= 0; + draw_state <= 2; + sprite_state <= 0; + end else if ( draw_state == 2 ) begin + x <= 0; + x_ofs <= scroll_x_latch[layer[1:0]]; + y_ofs <= scroll_y_latch[layer[1:0]]; + // latch offset info + draw_state <= 3; + tile_draw_state <= 0; + end else if ( draw_state == 3 ) begin + if ( tile_draw_state == 0 ) begin + tile <= { layer[1:0], curr_y[8:3], curr_x[8:3] }; // works + tile_draw_state <= 4'h1; + end else if ( tile_draw_state == 1 ) begin + tile_draw_state <= 2; + end else if ( tile_draw_state == 2 ) begin + // latch attribute + tile_attr <= tile_attr_dout; + if ( layer == 4 || tile_attr_dout[15] == 0 ) begin + tile_draw_state <= 3; + end else begin + if ( x < 320 ) begin// 319 + tile_draw_state <= 3; + // do we need to read another tile? + // last pixel of this tile changes based on flip direction + if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin + draw_state <= 3; + tile_draw_state <= 0; + end + x <= x + 1; + end else if ( layer > 0 ) begin + layer <= layer - 1; + tile_fb_w <= 0; + draw_state <= 2; + end else begin + // done + tile_draw_state <= 7; + tile_fb_w <= 0; + end + end + end else if ( tile_draw_state == 3 ) begin + // read bitmap info + tile_rom_cs <= 1; + tile_rom_addr <= { tile_idx, curr_y[2:0] }; + tile_draw_state <= 4; + end else if ( tile_draw_state == 4 ) begin + // wait for bitmap ram ready + if ( tile_rom_data_valid ) begin + // latch data and deassert cs + tile_data <= tile_rom_data; + tile_draw_state <= 5; + tile_rom_cs <= 0; + end + end else if ( tile_draw_state == 5 ) begin + tile_fb_w <= 0; + tile_fb_addr_w <= { y[0], 9'b0 } + x; + // force render of first layer. + // if layer == 4 then tile_pix == 0 is not transparent + // layer 4 is really layer 0 + if ( layer == 4 ) begin + tile_priority_buf[x] <= 0; //tile_pix == 0 ? 0 : tile_priority; + //fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; + fb_din <= { layer[1:0], 4'b0, tile_palette_idx, tile_pix }; + tile_fb_w <= 1; + end else if (tile_hidden == 0 && tile_pix > 0 && tile_priority > 0 && tile_priority >= tile_priority_buf[x] ) begin + tile_priority_buf[x] <= tile_priority; + // if tile hidden then make the pallette index 0. ie transparent + fb_din <= { layer[1:0], tile_priority, tile_palette_idx, tile_pix }; + tile_fb_w <= 1; + end + if ( x < 320 ) begin// 319 + // do we need to read another tile? + // last pixel of this tile changes based on flip direction + if ( curr_x[2:0] == ( tile_flip ? 0 : 7) ) begin + draw_state <= 3; + tile_draw_state <= 0; + end + x <= x + 1; + end else if ( layer > 0 ) begin + layer <= layer - 1; + tile_fb_w <= 0; + draw_state <= 2; + end else begin + // done + tile_draw_state <= 7; + tile_fb_w <= 0; + end + end else if ( tile_draw_state == 7 ) begin + // wait for next line or quit + if ( y == 239 ) begin + draw_state <= 0; + end else if ( hc == (status[19] ? 9'd444 : 9'd449) ) begin // 450 Lines standard (445 Lines for NTSC standard 15.73kHz line freq) + y <= y + 1; + draw_state <= 2; + sprite_state <= 0; + layer <= 4; + end + end + end + end +end + +// render +reg draw_sprite; + +// two lines worth for 4 layers (~8k) +// [15:14] = layer. +// [13:10] = prioity +// [9:4] = palette offset +// [3:0] = tile colour index. + +// there are 10 70MHz cycles per pixel. clk7_count from 0-9 + +// dac values based on 120 ohm driver for the resistor dac and 75 ohm output. 4.7k, 2.2k, 1k, 470, 220 +// modeled in spice +wire [7:0] dac [0:31] = '{0,12,25,36,50,61,73,83,91,100,111,120,131,139,149,157,145,154,162,170,180,187,195,202,208,214,222,228,236,242,249,255}; + +always @ (posedge clk_sys) begin + if ( clk7_count == 4 ) begin + tile_palette_addr <= tile_fb_out[9:0]; + sprite_palette_addr <= sprite_fb_out[9:0]; + end else if ( clk7_count == 6 ) begin + // if palette index is zero then it's from layer 3 and is transparent render as blank (black). + rgb <= { dac[tile_palette_dout[4:0]], dac[tile_palette_dout[9:5]], dac[tile_palette_dout[14:10]] }; + + // if not transparent and sprite is higher priority + if ( sprite_fb_out[3:0] > 0 && (sprite_fb_out[13:10] > tile_fb_out[13:10]) ) begin + // draw sprite + rgb <= { dac[sprite_palette_dout[4:0]], dac[sprite_palette_dout[9:5]], dac[sprite_palette_dout[14:10]] }; + end + end +end + +// tile data buffer + +reg tile_buf_w; +reg [31:0] tile_buf_din; +reg [31:0] tile_buf_dout; +reg [13:0] tile_buf_addr; + +dual_port_ram #(.LEN(16384), .DATA_WIDTH(32)) ram_tile_buf ( + .clock_a ( clk_sys ), + .address_a ( tile[13:0] ), + .wren_a ( tile_buf_w ), + .data_a ( tile_attr_dout ), + + .clock_b ( clk_sys ), + .address_b ( tile[13:0] ), // only read the tile # for now + .wren_b ( 0 ), + .q_b ( tile_buf_dout ) +); + +// tile attribute ram. each tile attribute is 2 16bit words +// pppp ---- --cc cccc httt tttt tttt tttt = Tile number (0 - $7fff) +// indirect access through offset register +dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_h ( + .clock_a ( clk_10M ), + .address_a ( curr_tile_ofs ), + .wren_a ( tile_attr_cs & !cpu_rw ), + .data_a ( cpu_dout ), + .q_a ( cpu_tile_dout_attr ), + + .clock_b ( clk_sys ), + .address_b ( tile[13:0] ), // only read the tile # for now + .wren_b ( 0 ), + .q_b ( tile_attr_dout[31:16] ) +); + +dual_port_ram #(.LEN(16384), .DATA_WIDTH(16)) ram_tile_l ( + .clock_a ( clk_10M ), + .address_a ( curr_tile_ofs ), + .wren_a ( tile_num_cs & !cpu_rw ), + .data_a ( cpu_dout ), + .q_a ( cpu_tile_dout_num ), + + .clock_b ( clk_sys ), + .address_b ( tile[13:0] ), // only read the tile # for now + .wren_b ( 0 ), + .q_b ( tile_attr_dout[15:0] ) +); + +// sprite attribute ram. each tile attribute is 4 16bit words +// indirect access through offset register +// split up so 64 bits can be read in a single clock +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_0 ( + .clock_a ( clk_10M ), + .address_a ( curr_sprite_ofs[9:2] ), + .wren_a ( sprite_0_cs & !cpu_rw), + .data_a ( cpu_dout ), + .q_a ( sprite_0_dout ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num_copy ), + .wren_b ( 0 ), + .q_b ( sprite_attr_0_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_0_buf ( + .clock_a ( clk_sys ), + .address_a ( sprite_buf_num ), + .wren_a ( sprite_buf_w ), + .data_a ( sprite_attr_0_dout[15:0] ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num ), + .wren_b ( 0 ), + .q_b ( sprite_attr_0_buf_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_1 ( + .clock_a ( clk_10M ), + .address_a ( curr_sprite_ofs[9:2] ), + .wren_a ( sprite_1_cs & !cpu_rw ), + .data_a ( cpu_dout ), + .q_a ( sprite_1_dout ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num_copy ), + .wren_b ( 0 ), + .q_b ( sprite_attr_1_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_1_buf ( + .clock_a ( clk_sys ), + .address_a ( sprite_buf_num ), + .wren_a ( sprite_buf_w ), + .data_a ( sprite_attr_1_dout[15:0] ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num ), + .wren_b ( 0 ), + .q_b ( sprite_attr_1_buf_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_2 ( + .clock_a ( clk_10M ), + .address_a ( curr_sprite_ofs[9:2] ), + .wren_a ( sprite_2_cs & !cpu_rw ), + .data_a ( cpu_dout ), + .q_a ( sprite_2_dout ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num_copy ), + .wren_b ( 0 ), + .q_b ( sprite_attr_2_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_2_buf ( + .clock_a ( clk_sys ), + .address_a ( sprite_buf_num ), + .wren_a ( sprite_buf_w ), + .data_a ( sprite_attr_2_dout[15:0] ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num ), + .wren_b ( 0 ), + .q_b ( sprite_attr_2_buf_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_3 ( + .clock_a ( clk_10M ), + .address_a ( curr_sprite_ofs[9:2] ), + .wren_a ( sprite_3_cs & !cpu_rw ), + .data_a ( cpu_dout ), + .q_a ( sprite_3_dout ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num_copy ), + .wren_b ( 0 ), + .q_b ( sprite_attr_3_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_3_buf ( + .clock_a ( clk_sys ), + .address_a ( sprite_buf_num ), + .wren_a ( sprite_buf_w ), + .data_a ( sprite_attr_3_dout[15:0] ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num ), + .wren_b ( 0 ), + .q_b ( sprite_attr_3_buf_dout[15:0] ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_size ( + .clock_a ( clk_10M ), + .address_a ( curr_sprite_ofs ), + .wren_a ( sprite_size_cs & !cpu_rw), + .data_a ( cpu_dout ), + .q_a ( sprite_size_cpu_dout ), + + .clock_b ( clk_sys ), + .address_b ( sprite_num_copy ), + .wren_b ( 0 ), + .q_b ( sprite_size_dout ) +); + +dual_port_ram #(.LEN(256), .DATA_WIDTH(16)) sprite_ram_size_buf ( + .clock_a ( clk_sys ), + .address_a ( sprite_buf_num ), + .wren_a ( sprite_buf_w ), + .data_a ( sprite_size_dout ), + .q_a ( ), + + .clock_b ( clk_sys ), + .address_b ( sprite_size_addr ), + .wren_b ( 0 ), + .q_b ( sprite_size_buf_dout ) +); + + +// tiles 1024 15 bit values. index is ( 6 bits from tile attribute, 4 bits from bitmap ) +// background palette ram low +// does this need to be byte addressable? +dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_l ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[10:1] ), + .wren_a ( tile_palette_cs & !cpu_rw & !cpu_lds_n), + .data_a ( cpu_dout[7:0] ), + .q_a ( tile_palette_cpu_dout[7:0] ), + + .clock_b ( clk_sys ), + .address_b ( tile_palette_addr ), + .wren_b ( 0 ), + .q_b ( tile_palette_dout[7:0] ) +); + +// background palette ram high +dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) tile_palram_h ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[10:1] ), + .wren_a ( tile_palette_cs & !cpu_rw & !cpu_uds_n), + .data_a ( cpu_dout[15:8] ), + .q_a ( tile_palette_cpu_dout[15:8] ), + + .clock_b ( clk_sys ), + .address_b ( tile_palette_addr ), + .wren_b ( 0 ), + .q_b ( tile_palette_dout[15:8] ) +); + +// sprite palette ram low +// does this need to be byte addressable? +dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_l ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[10:1] ), + .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_lds_n), + .data_a ( cpu_dout[7:0] ), + .q_a ( sprite_palette_cpu_dout[7:0] ), + + .clock_b ( clk_sys ), + .address_b ( sprite_palette_addr ), + .wren_b ( 0 ), + .q_b ( sprite_palette_dout[7:0] ) +); + +// background palette ram high +dual_port_ram #(.LEN(1024), .DATA_WIDTH(8)) sprite_palram_h ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[10:1] ), + .wren_a ( sprite_palette_cs & !cpu_rw & !cpu_uds_n), + .data_a ( cpu_dout[15:8] ), + .q_a ( sprite_palette_cpu_dout[15:8] ), + + .clock_b ( clk_sys ), + .address_b ( sprite_palette_addr ), + .wren_b ( 0 ), + .q_b ( sprite_palette_dout[15:8] ) +); + + +// main 68k ram low +dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_L ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[14:1] ), + .wren_a ( !cpu_rw & ram_cs & !cpu_lds_n ), + .data_a ( cpu_dout[7:0] ), + .q_a ( ram_dout[7:0] ) + ); + +// main 68k ram high +dual_port_ram #(.LEN(16384), .DATA_WIDTH(8)) ram16kx8_H ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[14:1] ), + .wren_a ( !cpu_rw & ram_cs & !cpu_uds_n ), + .data_a ( cpu_dout[15:8] ), + .q_a ( ram_dout[15:8] ) +); + + +//wire [15:0] z80_shared_addr = z80_addr - 16'h8000; +//wire [23:0] m68k_shard_addr = cpu_a - 24'h040000; + +// z80 and 68k shared ram +// 4k +dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) shared_ram ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[12:1] ), + .wren_a ( shared_ram_cs & !cpu_rw & !cpu_lds_n), + .data_a ( cpu_dout[7:0] ), + .q_a ( cpu_shared_dout[7:0] ), + + .clock_b ( clk_3_5M ), // z80 clock is 3.5M + .address_b ( z80_addr[11:0] ), + .data_b ( z80_dout ), + .wren_b ( sound_ram_1_cs & ~z80_wr_n ), + .q_b ( z80_shared_dout ) +); + +reg [11:0] sprite_rb_addr; +wire [15:0] sprite_rb_dout; + +dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) sprite_ram_rb_l ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[12:1] ), + .wren_a ( sprite_ram_cs & !cpu_rw & !cpu_lds_n), + .data_a ( cpu_dout[7:0] ), + .q_a ( sprite_rb_dout[7:0] ), + + .clock_b ( clk_sys ), + .address_b ( sprite_rb_addr ), + .wren_b ( 0 ), + .q_b ( sprite_rb_dout[7:0] ) +); + +dual_port_ram #(.LEN(4096), .DATA_WIDTH(8)) sprite_ram_rb_h ( + .clock_a ( clk_10M ), + .address_a ( cpu_a[12:1] ), + .wren_a ( sprite_ram_cs & !cpu_rw & !cpu_uds_n), + .data_a ( cpu_dout[15:8] ), + .q_a ( cpu_shared_dout[15:8] ), + + .clock_b ( clk_sys ), + .address_b ( sprite_rb_addr ), + .wren_b ( 0 ), + .q_b ( sprite_rb_dout[15:8] ) +); + +reg [22:0] sdram_addr; +reg [31:0] sdram_data; +reg sdram_we; +reg sdram_req; + +wire sdram_ack; +wire sdram_valid; +wire [31:0] sdram_q; + +sdram #(.CLK_FREQ(70.0)) sdram +( + .reset(~pll_locked), + .clk(clk_sys), + + // controller interface + .addr(sdram_addr), + .data(sdram_data), + .we(sdram_we), + .req(sdram_req), + + .ack(sdram_ack), + .valid(sdram_valid), + .q(sdram_q), + + // SDRAM interface + .sdram_a(SDRAM_A), + .sdram_ba(SDRAM_BA), + .sdram_dq(SDRAM_DQ), + .sdram_cke(SDRAM_CKE), + .sdram_cs_n(SDRAM_nCS), + .sdram_ras_n(SDRAM_nRAS), + .sdram_cas_n(SDRAM_nCAS), + .sdram_we_n(SDRAM_nWE), + .sdram_dqml(SDRAM_DQML), + .sdram_dqmh(SDRAM_DQMH) +); + +wire prog_cache_rom_cs; +wire [22:0] prog_cache_addr; +wire [15:0] prog_cache_data; +wire prog_cache_valid; + +wire [15:0] prog_rom_data; +wire prog_rom_data_valid; + +reg tile_rom_cs; +reg [17:0] tile_rom_addr; +wire [31:0] tile_rom_data; +wire tile_rom_data_valid; + +wire tile_cache_cs; +wire [17:0] tile_cache_addr; +wire [31:0] tile_cache_data; +wire tile_cache_valid; + +reg [31:0] tile_data; + +wire sprite_rom_cs; +wire [17:0] sprite_rom_addr; +wire [31:0] sprite_rom_data; +wire sprite_rom_data_valid; + +reg [31:0] sprite_data; + +wire [15:0] sound_rom_1_addr; +wire [7:0] sound_rom_1_data; +wire sound_rom_1_data_valid; + +// sdram priority based rom controller +// is a oe needed? +rom_controller rom_controller +( + .reset(reset), + + // clock + .clk(clk_sys), + + // program ROM interface + .prog_rom_cs(prog_cache_rom_cs), + .prog_rom_oe(1), + .prog_rom_addr(prog_cache_addr), + .prog_rom_data(prog_cache_data), + .prog_rom_data_valid(prog_cache_valid), + + // character ROM interface + .tile_rom_cs(tile_cache_cs), + .tile_rom_oe(1), + .tile_rom_addr(tile_cache_addr), + .tile_rom_data(tile_cache_data), + .tile_rom_data_valid(tile_cache_valid), + + + // sprite ROM interface + .sprite_rom_cs(sprite_rom_cs), + .sprite_rom_oe(1), + .sprite_rom_addr(sprite_rom_addr), + .sprite_rom_data(sprite_rom_data), + .sprite_rom_data_valid(sprite_rom_data_valid), + + // sound ROM #1 interface + .sound_rom_1_cs(sound_rom_1_cs), + .sound_rom_1_oe(1), + .sound_rom_1_addr(z80_addr), + .sound_rom_1_data(sound_rom_1_data), + .sound_rom_1_data_valid(sound_rom_1_data_valid), + + // IOCTL interface + .ioctl_addr(ioctl_addr), + .ioctl_data(ioctl_dout), + .ioctl_index(ioctl_index), + .ioctl_wr(ioctl_wr), + .ioctl_download(ioctl_download), + + // SDRAM interface + .sdram_addr(sdram_addr), + .sdram_data(sdram_data), + .sdram_we(sdram_we), + .sdram_req(sdram_req), + .sdram_ack(sdram_ack), + .sdram_valid(sdram_valid), + .sdram_q(sdram_q) +); + + +cache prog_cache +( + .reset(reset), + .clk(clk_sys), + + // client + .cache_req(prog_rom_cs), + .cache_addr(cpu_a[23:1]), + .cache_valid(prog_rom_data_valid), + .cache_data(prog_rom_data), + + // to rom controller + .rom_req(prog_cache_rom_cs), + .rom_addr(prog_cache_addr), + .rom_valid(prog_cache_valid), + .rom_data(prog_cache_data) +); + +tile_cache tile_cache +( + .reset(reset), + .clk(clk_sys), + + // client + .cache_req(tile_rom_cs), + .cache_addr(tile_rom_addr), + .cache_data(tile_rom_data), + .cache_valid(tile_rom_data_valid), + + // to rom controller + .rom_req(tile_cache_cs), + .rom_addr(tile_cache_addr), + .rom_data(tile_cache_data), + .rom_valid(tile_cache_valid) +); + +endmodule + + +module cc_shifter +( + input clk_out, + input i, + output o +); + +// We use a two-stages shift-register to synchronize SignalIn_clkA to the clkB clock domain +reg [1:0] r; + +assign o = r[1]; // new signal synchronized to (=ready to be used in) clkB domain + +always @(posedge clk_out) begin + r[0] <= i; + r[1] <= r[0]; // notice that we use clkB +end + +endmodule + +