From 63e9d957d3802c131b5e5624f05cde78ca0d19ae Mon Sep 17 00:00:00 2001 From: Gehstock Date: Wed, 25 Dec 2019 15:56:02 +0100 Subject: [PATCH] Sync --- .../LunarLander_MiST/LunarLander.qpf | 6 + .../LunarLander_MiST/LunarLander.qsf | 212 ++ .../Atari Vector/LunarLander_MiST/clean.bat | 38 + .../LunarLander_MiST/rtl/LunarLander_MiST.sv | 297 +++ .../LunarLander_MiST/rtl/base_pack.vhd | 593 +++++ .../LunarLander_MiST}/rtl/build_id.tcl | 0 .../LunarLander_MiST/rtl/dpram.vhd | 75 + .../LunarLander_MiST}/rtl/gen_ram.vhd | 0 .../LunarLander_MiST/rtl/llander.vhd | 648 ++++++ .../LunarLander_MiST/rtl/llander_dw.vhd | 450 ++++ .../LunarLander_MiST/rtl/llander_ram.vhd | 99 + .../LunarLander_MiST/rtl/llander_top.vhd | 241 ++ .../LunarLander_MiST/rtl/llander_vg.vhd | 741 +++++++ .../Atari Vector/LunarLander_MiST/rtl/ovo.vhd | 180 ++ .../LunarLander_MiST/rtl/p2ram.v} | 220 +- .../Atari Vector/LunarLander_MiST/rtl/pll.v | 365 ++++ .../rtl/rom/LLANDER_DVG_ROM.vhd | 38 + .../rtl/rom/LLANDER_PROG_ROM_0.vhd | 150 ++ .../rtl/rom/LLANDER_PROG_ROM_1.vhd | 150 ++ .../rtl/rom/LLANDER_PROG_ROM_2.vhd | 150 ++ .../rtl/rom/LLANDER_PROG_ROM_3.vhd | 150 ++ .../rtl/rom/LLANDER_VEC_ROM_0.vhd | 150 ++ .../rtl/rom/LLANDER_VEC_ROM_1.vhd | 150 ++ .../rtl/rom/LLANDER_VEC_ROM_2.vhd | 150 ++ .../NinjaKun_MiST/Snapshot/NinjaKun_MiST.rbf | Bin 315864 -> 0 bytes .../NinjaKun_MiST/mister/Arcade-NinjaKun.sv | 358 --- Arcade_MiST/NinjaKun_MiST/mister/LICENSE | 674 ------ Arcade_MiST/NinjaKun_MiST/mister/README.txt | 74 - .../NinjaKun_MiST/mister/build_rom.bat | 45 - .../NinjaKun_MiST/mister/build_rom.ini | 4 - Arcade_MiST/NinjaKun_MiST/mister/build_rom.sh | 100 - .../NinjaKun_MiST/mister/ninjakun_romarb.v | 80 - Arcade_MiST/NinjaKun_MiST/mister/rommap.txt | 7 - Arcade_MiST/NinjaKun_MiST/mister/roms.v | 103 - Arcade_MiST/NinjaKun_MiST/rtl/DPRAM1024.v | 246 --- Arcade_MiST/NinjaKun_MiST/rtl/cpu/T80.vhd | 1073 --------- Arcade_MiST/NinjaKun_MiST/rtl/cpu/T80_ALU.vhd | 351 --- .../NinjaKun_MiST/rtl/cpu/T80_MCode.vhd | 1934 ----------------- .../NinjaKun_MiST/rtl/cpu/T80_Pack.vhd | 208 -- Arcade_MiST/NinjaKun_MiST/rtl/cpu/T80_Reg.vhd | 105 - Arcade_MiST/NinjaKun_MiST/rtl/cpu/T80s.vhd | 190 -- Arcade_MiST/NinjaKun_MiST/rtl/dpram_1r1w.vhd | 101 - Arcade_MiST/NinjaKun_MiST/rtl/mems.v | 116 - .../NinjaKun_MiST/rtl/ninjakun_video.v | 164 -- .../NinjaKun_MiST/rtl/rom/NINJAKUN.ROM | Bin 98304 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/bg.bin | Bin 32768 -> 0 bytes .../NinjaKun_MiST/rtl/rom/cpu1_rom.bin | Bin 32768 -> 0 bytes .../NinjaKun_MiST/rtl/rom/cpu2_rom.bin | Bin 32768 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/fg1_rom.vhd | 534 ----- Arcade_MiST/NinjaKun_MiST/rtl/rom/fg2_rom.vhd | 534 ----- Arcade_MiST/NinjaKun_MiST/rtl/rom/fg3_rom.vhd | 534 ----- Arcade_MiST/NinjaKun_MiST/rtl/rom/fg4_rom.vhd | 534 ----- Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-1.7a | Bin 8192 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-10.2c | Bin 8192 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-11.2d | Bin 8192 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-12.4c | Bin 8192 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-13.4d | Bin 8192 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-2.7b | Bin 8192 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-3.7d | Bin 8192 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-4.7e | Bin 8192 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-5.7h | Bin 8192 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-6.7n | Bin 8192 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-7.7p | Bin 8192 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-8.7s | Bin 8192 -> 0 bytes Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-9.7t | Bin 8192 -> 0 bytes .../NinjaKun_MiST/NinjaKun_MiST.qpf | 0 .../NinjaKun_MiST/NinjaKun_MiST.qsf | 12 +- .../NinjaKun_MiST/Snapshot/NINJAKUN.ROM | Bin .../NinjaKun_MiST/clean.bat | 0 .../NinjaKun_MiST/rtl/NinjaKun_MiST.sv | 0 .../NinjaKun_MiST/rtl/YM2149_linmix_sep.vhd | 0 .../NinjaKun_MiST}/rtl/build_id.tcl | 0 .../NinjaKun_MiST/rtl/dataselector_3D_8B.v | 0 .../NinjaKun_MiST/rtl/dataselector_4D_9B.v | 0 .../NinjaKun_MiST/rtl/dataselector_5D_8B.v | 0 .../NinjaKun_MiST/rtl/dpram.vhd | 0 .../NinjaKun_MiST/rtl/hvgen.v | 0 .../NinjaKun_MiST/rtl/mems.v | 305 +++ .../NinjaKun_MiST/rtl/ninjakun_adec.v | 0 .../NinjaKun_MiST/rtl/ninjakun_bg.v | 0 .../NinjaKun_MiST/rtl/ninjakun_clkgen.v | 0 .../NinjaKun_MiST/rtl/ninjakun_cpumux.v | 0 .../NinjaKun_MiST/rtl/ninjakun_fg.v | 0 .../NinjaKun_MiST/rtl/ninjakun_input.v | 0 .../NinjaKun_MiST/rtl/ninjakun_io_video.v | 0 .../NinjaKun_MiST/rtl/ninjakun_irqgen.v | 0 .../NinjaKun_MiST/rtl/ninjakun_main.v | 3 +- .../NinjaKun_MiST/rtl/ninjakun_psg.v | 0 .../NinjaKun_MiST/rtl/ninjakun_sadec.v | 0 .../NinjaKun_MiST/rtl/ninjakun_sp.v | 0 .../NinjaKun_MiST/rtl/ninjakun_top.v | 0 .../NinjaKun_MiST/rtl/ninjakun_video.v | 0 .../NinjaKun_MiST/rtl/pll.v | 10 +- .../NinjaKun_MiST/rtl/rom/gfx1.hex | 0 .../NinjaKun_MiST/rtl/rom/make_rom.bat | 10 +- .../NinjaKun_MiST/rtl/rom/make_vhdl_prom.exe | Bin .../NinjaKun_MiST/rtl/rom/ninjakun.zip | Bin .../NinjaKun_MiST/rtl/rom/srec_cat.exe | Bin 0 -> 1440270 bytes .../NinjaKun_MiST/rtl/sdram.sv | 0 .../NinjaKun_MiST/rtl/spram.vhd | 0 .../NinjaKun_MiST/rtl/z80ip.v | 2 +- .../{ => Zaxxon_MiST}/README.txt | 0 .../Zaxxon_MiST/Release/ZAXXON.ROM | Bin 0 -> 115200 bytes .../Zaxxon_MiST/Release/Zaxxon.rbf | Bin 0 -> 251476 bytes .../{ => Zaxxon_MiST}/Zaxxon.qpf | 0 .../{ => Zaxxon_MiST}/Zaxxon.qsf | 11 +- .../{ => Zaxxon_MiST}/Zaxxon.sdc | 0 .../Zaxxon_MiST/clean.bat | 37 + .../{ => Zaxxon_MiST}/rtl/Zaxxon_MiST.sv | 0 .../Zaxxon_MiST/rtl/build_id.tcl | 35 + .../{ => Zaxxon_MiST}/rtl/dpram.vhd | 0 .../Zaxxon_MiST/rtl/gen_ram.vhd | 84 + .../{ => Zaxxon_MiST}/rtl/pll_mist.v | 0 .../{ => Zaxxon_MiST}/rtl/sdram.sv | 0 .../{ => Zaxxon_MiST}/rtl/zaxxon.vhd | 0 common/mist/mist2.qip | 16 - 116 files changed, 5611 insertions(+), 8236 deletions(-) create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/LunarLander.qpf create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/LunarLander.qsf create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/clean.bat create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/LunarLander_MiST.sv create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/base_pack.vhd rename Arcade_MiST/{NinjaKun_MiST => Atari Vector/LunarLander_MiST}/rtl/build_id.tcl (100%) create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/dpram.vhd rename Arcade_MiST/{Sega Zaxxon Hardware => Atari Vector/LunarLander_MiST}/rtl/gen_ram.vhd (100%) create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander.vhd create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_dw.vhd create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_ram.vhd create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_top.vhd create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_vg.vhd create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/ovo.vhd rename Arcade_MiST/{Nova2001_MiST/NinjaKun_MiST/rtl/fg_sp_dulport_rom.v => Atari Vector/LunarLander_MiST/rtl/p2ram.v} (50%) create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/pll.v create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/rom/LLANDER_DVG_ROM.vhd create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/rom/LLANDER_PROG_ROM_0.vhd create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/rom/LLANDER_PROG_ROM_1.vhd create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/rom/LLANDER_PROG_ROM_2.vhd create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/rom/LLANDER_PROG_ROM_3.vhd create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/rom/LLANDER_VEC_ROM_0.vhd create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/rom/LLANDER_VEC_ROM_1.vhd create mode 100644 Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/rom/LLANDER_VEC_ROM_2.vhd delete mode 100644 Arcade_MiST/NinjaKun_MiST/Snapshot/NinjaKun_MiST.rbf delete mode 100644 Arcade_MiST/NinjaKun_MiST/mister/Arcade-NinjaKun.sv delete mode 100644 Arcade_MiST/NinjaKun_MiST/mister/LICENSE delete mode 100644 Arcade_MiST/NinjaKun_MiST/mister/README.txt delete mode 100644 Arcade_MiST/NinjaKun_MiST/mister/build_rom.bat delete mode 100644 Arcade_MiST/NinjaKun_MiST/mister/build_rom.ini delete mode 100644 Arcade_MiST/NinjaKun_MiST/mister/build_rom.sh delete mode 100644 Arcade_MiST/NinjaKun_MiST/mister/ninjakun_romarb.v delete mode 100644 Arcade_MiST/NinjaKun_MiST/mister/rommap.txt delete mode 100644 Arcade_MiST/NinjaKun_MiST/mister/roms.v delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/DPRAM1024.v delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/cpu/T80.vhd delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/cpu/T80_ALU.vhd delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/cpu/T80_MCode.vhd delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/cpu/T80_Pack.vhd delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/cpu/T80_Reg.vhd delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/cpu/T80s.vhd delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/dpram_1r1w.vhd delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/mems.v delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/ninjakun_video.v delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/NINJAKUN.ROM delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/bg.bin delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/cpu1_rom.bin delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/cpu2_rom.bin delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/fg1_rom.vhd delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/fg2_rom.vhd delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/fg3_rom.vhd delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/fg4_rom.vhd delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-1.7a delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-10.2c delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-11.2d delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-12.4c delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-13.4d delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-2.7b delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-3.7d delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-4.7e delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-5.7h delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-6.7n delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-7.7p delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-8.7s delete mode 100644 Arcade_MiST/NinjaKun_MiST/rtl/rom/ninja-9.7t rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/NinjaKun_MiST.qpf (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/NinjaKun_MiST.qsf (95%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/Snapshot/NINJAKUN.ROM (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/clean.bat (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/NinjaKun_MiST.sv (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/YM2149_linmix_sep.vhd (100%) rename Arcade_MiST/{Sega Zaxxon Hardware => Nova2001_Hardware/NinjaKun_MiST}/rtl/build_id.tcl (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/dataselector_3D_8B.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/dataselector_4D_9B.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/dataselector_5D_8B.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/dpram.vhd (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/hvgen.v (100%) create mode 100644 Arcade_MiST/Nova2001_Hardware/NinjaKun_MiST/rtl/mems.v rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_adec.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_bg.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_clkgen.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_cpumux.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_fg.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_input.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_io_video.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_irqgen.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_main.v (98%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_psg.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_sadec.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_sp.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_top.v (100%) rename Arcade_MiST/{Nova2001_MiST => Nova2001_Hardware}/NinjaKun_MiST/rtl/ninjakun_video.v (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/pll.v (98%) rename Arcade_MiST/{Nova2001_MiST => Nova2001_Hardware}/NinjaKun_MiST/rtl/rom/gfx1.hex (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/rom/make_rom.bat (53%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/rom/make_vhdl_prom.exe (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/rom/ninjakun.zip (100%) create mode 100644 Arcade_MiST/Nova2001_Hardware/NinjaKun_MiST/rtl/rom/srec_cat.exe rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/sdram.sv (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/spram.vhd (100%) rename Arcade_MiST/{ => Nova2001_Hardware}/NinjaKun_MiST/rtl/z80ip.v (97%) rename Arcade_MiST/Sega Zaxxon Hardware/{ => Zaxxon_MiST}/README.txt (100%) create mode 100644 Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/Release/ZAXXON.ROM create mode 100644 Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/Release/Zaxxon.rbf rename Arcade_MiST/Sega Zaxxon Hardware/{ => Zaxxon_MiST}/Zaxxon.qpf (100%) rename Arcade_MiST/Sega Zaxxon Hardware/{ => Zaxxon_MiST}/Zaxxon.qsf (97%) rename Arcade_MiST/Sega Zaxxon Hardware/{ => Zaxxon_MiST}/Zaxxon.sdc (100%) create mode 100644 Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/clean.bat rename Arcade_MiST/Sega Zaxxon Hardware/{ => Zaxxon_MiST}/rtl/Zaxxon_MiST.sv (100%) create mode 100644 Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/build_id.tcl rename Arcade_MiST/Sega Zaxxon Hardware/{ => Zaxxon_MiST}/rtl/dpram.vhd (100%) create mode 100644 Arcade_MiST/Sega Zaxxon Hardware/Zaxxon_MiST/rtl/gen_ram.vhd rename Arcade_MiST/Sega Zaxxon Hardware/{ => Zaxxon_MiST}/rtl/pll_mist.v (100%) rename Arcade_MiST/Sega Zaxxon Hardware/{ => Zaxxon_MiST}/rtl/sdram.sv (100%) rename Arcade_MiST/Sega Zaxxon Hardware/{ => Zaxxon_MiST}/rtl/zaxxon.vhd (100%) delete mode 100644 common/mist/mist2.qip diff --git a/Arcade_MiST/Atari Vector/LunarLander_MiST/LunarLander.qpf b/Arcade_MiST/Atari Vector/LunarLander_MiST/LunarLander.qpf new file mode 100644 index 00000000..2a9f7422 --- /dev/null +++ b/Arcade_MiST/Atari Vector/LunarLander_MiST/LunarLander.qpf @@ -0,0 +1,6 @@ +DATE = "19:48:06 May 24, 2017" +QUARTUS_VERSION = "16.0.2" + +# Revisions + +PROJECT_REVISION = "LunarLander" diff --git a/Arcade_MiST/Atari Vector/LunarLander_MiST/LunarLander.qsf b/Arcade_MiST/Atari Vector/LunarLander_MiST/LunarLander.qsf new file mode 100644 index 00000000..52ac2de8 --- /dev/null +++ b/Arcade_MiST/Atari Vector/LunarLander_MiST/LunarLander.qsf @@ -0,0 +1,212 @@ +# -------------------------------------------------------------------------- # +# +# Copyright (C) 1991-2014 Altera Corporation +# Your use of Altera Corporation's design tools, logic functions +# and other software and tools, and its AMPP partner logic +# functions, and any output files from any of the foregoing +# (including device programming or simulation files), and any +# associated documentation or information are expressly subject +# to the terms and conditions of the Altera Program License +# Subscription Agreement, Altera MegaCore Function License +# Agreement, or other applicable license agreement, including, +# without limitation, that your use is for the sole purpose of +# programming logic devices manufactured by Altera and sold by +# Altera or its authorized distributors. Please refer to the +# applicable agreement for further details. +# +# -------------------------------------------------------------------------- # +# +# Quartus II 64-Bit +# Version 13.1.4 Build 182 03/12/2014 SJ Web Edition +# Date created = 16:03:28 October 01, 2019 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# DigDugII_assignment_defaults.qdf +# If this file doesn't exist, see file: +# assignment_defaults.qdf +# +# 2) Altera recommends that you do not modify this file. This +# file is updated automatically by the Quartus II software +# and any changes you make may be lost or overwritten. +# +# -------------------------------------------------------------------------- # + + + +# Project-Wide Assignments +# ======================== +set_global_assignment -name ORIGINAL_QUARTUS_VERSION 16.0.2 +set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name PROJECT_CREATION_TIME_DATE "19:48:06 MAY 24,2017" +set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:rtl/build_id.tcl" +set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files + +# Pin & Location Assignments +# ========================== +set_location_assignment PIN_7 -to LED +set_location_assignment PIN_54 -to CLOCK_27 +set_location_assignment PIN_144 -to VGA_R[5] +set_location_assignment PIN_143 -to VGA_R[4] +set_location_assignment PIN_142 -to VGA_R[3] +set_location_assignment PIN_141 -to VGA_R[2] +set_location_assignment PIN_137 -to VGA_R[1] +set_location_assignment PIN_135 -to VGA_R[0] +set_location_assignment PIN_133 -to VGA_B[5] +set_location_assignment PIN_132 -to VGA_B[4] +set_location_assignment PIN_125 -to VGA_B[3] +set_location_assignment PIN_121 -to VGA_B[2] +set_location_assignment PIN_120 -to VGA_B[1] +set_location_assignment PIN_115 -to VGA_B[0] +set_location_assignment PIN_114 -to VGA_G[5] +set_location_assignment PIN_113 -to VGA_G[4] +set_location_assignment PIN_112 -to VGA_G[3] +set_location_assignment PIN_111 -to VGA_G[2] +set_location_assignment PIN_110 -to VGA_G[1] +set_location_assignment PIN_106 -to VGA_G[0] +set_location_assignment PIN_136 -to VGA_VS +set_location_assignment PIN_119 -to VGA_HS +set_location_assignment PIN_65 -to AUDIO_L +set_location_assignment PIN_80 -to AUDIO_R +set_location_assignment PIN_105 -to SPI_DO +set_location_assignment PIN_88 -to SPI_DI +set_location_assignment PIN_126 -to SPI_SCK +set_location_assignment PIN_127 -to SPI_SS2 +set_location_assignment PIN_91 -to SPI_SS3 +set_location_assignment PIN_90 -to SPI_SS4 +set_location_assignment PIN_13 -to CONF_DATA0 +set_location_assignment PIN_49 -to SDRAM_A[0] +set_location_assignment PIN_44 -to SDRAM_A[1] +set_location_assignment PIN_42 -to SDRAM_A[2] +set_location_assignment PIN_39 -to SDRAM_A[3] +set_location_assignment PIN_4 -to SDRAM_A[4] +set_location_assignment PIN_6 -to SDRAM_A[5] +set_location_assignment PIN_8 -to SDRAM_A[6] +set_location_assignment PIN_10 -to SDRAM_A[7] +set_location_assignment PIN_11 -to SDRAM_A[8] +set_location_assignment PIN_28 -to SDRAM_A[9] +set_location_assignment PIN_50 -to SDRAM_A[10] +set_location_assignment PIN_30 -to SDRAM_A[11] +set_location_assignment PIN_32 -to SDRAM_A[12] +set_location_assignment PIN_83 -to SDRAM_DQ[0] +set_location_assignment PIN_79 -to SDRAM_DQ[1] +set_location_assignment PIN_77 -to SDRAM_DQ[2] +set_location_assignment PIN_76 -to SDRAM_DQ[3] +set_location_assignment PIN_72 -to SDRAM_DQ[4] +set_location_assignment PIN_71 -to SDRAM_DQ[5] +set_location_assignment PIN_69 -to SDRAM_DQ[6] +set_location_assignment PIN_68 -to SDRAM_DQ[7] +set_location_assignment PIN_86 -to SDRAM_DQ[8] +set_location_assignment PIN_87 -to SDRAM_DQ[9] +set_location_assignment PIN_98 -to SDRAM_DQ[10] +set_location_assignment PIN_99 -to SDRAM_DQ[11] +set_location_assignment PIN_100 -to SDRAM_DQ[12] +set_location_assignment PIN_101 -to SDRAM_DQ[13] +set_location_assignment PIN_103 -to SDRAM_DQ[14] +set_location_assignment PIN_104 -to SDRAM_DQ[15] +set_location_assignment PIN_58 -to SDRAM_BA[0] +set_location_assignment PIN_51 -to SDRAM_BA[1] +set_location_assignment PIN_85 -to SDRAM_DQMH +set_location_assignment PIN_67 -to SDRAM_DQML +set_location_assignment PIN_60 -to SDRAM_nRAS +set_location_assignment PIN_64 -to SDRAM_nCAS +set_location_assignment PIN_66 -to SDRAM_nWE +set_location_assignment PIN_59 -to SDRAM_nCS +set_location_assignment PIN_33 -to SDRAM_CKE +set_location_assignment PIN_43 -to SDRAM_CLK + +# Classic Timing Assignments +# ========================== +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 +set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON +set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON + +# Analysis & Synthesis Assignments +# ================================ +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 TOP_LEVEL_ENTITY LunarLander_MiST +set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005 +set_global_assignment -name VERILOG_SHOW_LMF_MAPPING_MESSAGES OFF + +# Fitter Assignments +# ================== +set_global_assignment -name DEVICE EP3C25E144C8 +set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF +set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" +set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO" + +# Assembler Assignments +# ===================== +set_global_assignment -name USE_CONFIGURATION_DEVICE OFF +set_global_assignment -name GENERATE_RBF_FILE ON + +# SignalTap II Assignments +# ======================== +set_global_assignment -name ENABLE_SIGNALTAP OFF +set_global_assignment -name USE_SIGNALTAP_FILE stp1.stp + +# Power Estimation Assignments +# ============================ +set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW" +set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)" + +# Advanced I/O Timing Assignments +# =============================== +set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise +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(DigDugII_mist) + + # start DESIGN_PARTITION(Top) + # --------------------------- + + # Incremental Compilation Assignments + # =================================== + + # end DESIGN_PARTITION(Top) + # ------------------------- + +# end ENTITY(DigDugII_mist) +# ------------------------- +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_global_assignment -name SYSTEMVERILOG_FILE rtl/LunarLander_MiST.sv +set_global_assignment -name VHDL_FILE rtl/llander_top.vhd +set_global_assignment -name VHDL_FILE rtl/llander.vhd +set_global_assignment -name VHDL_FILE rtl/llander_vg.vhd +set_global_assignment -name VHDL_FILE rtl/llander_ram.vhd +set_global_assignment -name VHDL_FILE rtl/llander_dw.vhd +set_global_assignment -name VHDL_FILE rtl/rom/LLANDER_VEC_ROM_2.vhd +set_global_assignment -name VHDL_FILE rtl/rom/LLANDER_VEC_ROM_1.vhd +set_global_assignment -name VHDL_FILE rtl/rom/LLANDER_VEC_ROM_0.vhd +set_global_assignment -name VHDL_FILE rtl/rom/LLANDER_PROG_ROM_3.vhd +set_global_assignment -name VHDL_FILE rtl/rom/LLANDER_PROG_ROM_2.vhd +set_global_assignment -name VHDL_FILE rtl/rom/LLANDER_PROG_ROM_1.vhd +set_global_assignment -name VHDL_FILE rtl/rom/LLANDER_PROG_ROM_0.vhd +set_global_assignment -name VHDL_FILE rtl/rom/LLANDER_DVG_ROM.vhd +set_global_assignment -name VHDL_FILE rtl/gen_ram.vhd +set_global_assignment -name VHDL_FILE rtl/dpram.vhd +set_global_assignment -name VHDL_FILE rtl/ovo.vhd +set_global_assignment -name VHDL_FILE rtl/base_pack.vhd +set_global_assignment -name SYSTEMVERILOG_FILE rtl/sdram.sv +set_global_assignment -name VERILOG_FILE rtl/p2ram.v +set_global_assignment -name VERILOG_FILE rtl/pll.v +set_global_assignment -name QIP_FILE ../../../common/CPU/T65/T65.qip +set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/Arcade_MiST/Atari Vector/LunarLander_MiST/clean.bat b/Arcade_MiST/Atari Vector/LunarLander_MiST/clean.bat new file mode 100644 index 00000000..59a9a059 --- /dev/null +++ b/Arcade_MiST/Atari Vector/LunarLander_MiST/clean.bat @@ -0,0 +1,38 @@ +@echo off +del /s *.bak +del /s *.orig +del /s *.rej +del /s *~ +rmdir /s /q db +rmdir /s /q incremental_db +rmdir /s /q output_files +rmdir /s /q simulation +rmdir /s /q greybox_tmp +rmdir /s /q hc_output +rmdir /s /q .qsys_edit +rmdir /s /q hps_isw_handoff +rmdir /s /q sys\.qsys_edit +rmdir /s /q sys\vip +cd sys +for /d %%i in (*_sim) do rmdir /s /q "%%~nxi" +cd .. +for /d %%i in (*_sim) do rmdir /s /q "%%~nxi" +del build_id.v +del c5_pin_model_dump.txt +del PLLJ_PLLSPE_INFO.txt +del /s *.qws +del /s *.ppf +del /s *.ddb +del /s *.csv +del /s *.cmp +del /s *.sip +del /s *.spd +del /s *.bsf +del /s *.f +del /s *.sopcinfo +del /s *.xml +del /s new_rtl_netlist +del /s old_rtl_netlist +del /s PLLJ_PLLSPE_INFO.txt + +pause diff --git a/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/LunarLander_MiST.sv b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/LunarLander_MiST.sv new file mode 100644 index 00000000..ea39ecca --- /dev/null +++ b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/LunarLander_MiST.sv @@ -0,0 +1,297 @@ +module LunarLander_MiST( + 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, + output SPI_DO, + input SPI_DI, + input SPI_SS2, + input SPI_SS3, + 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 "rtl\build_id.v" + +localparam CONF_STR = { + "LunarLander;;", + "O12,Scanlines,None,CRT 25%,CRT 50%,CRT 75%;", + "O3,Test,Off,On;", + "O45,Language,English,Spanish,French,German;", + "O68,Fuel,450,600,750,900,1100,1300,1550,1800;", + "T0,Reset;", + "V,v1.00.",`BUILD_DATE +}; + +assign LED = 1; +assign AUDIO_R = AUDIO_L; + +wire clk_50, clk_25, clk_6, locked; +pll pll( + .inclk0(CLOCK_27), + .c0(clk_50), + .c1(clk_25), + .c2(clk_6), + .locked(locked) +); + +wire [31:0] status; +wire [1:0] buttons; +wire [1:0] switches; +wire [7:0] joystick_0; +wire [7:0] joystick_1; +wire scandoublerD; +wire ypbpr; +wire hs, vs, hso, vso; +wire hb, vb; +wire blankn = ~(hb | vb); +wire [3:0] r, g, b; +wire [7:0] ro, go, bo; +wire vgade; +wire [7:0] audio; +wire key_strobe; +wire key_pressed; +wire [7:0] key_code; +//this must go to sdram +wire [18:0] vram_write_addr; +wire [3:0] vram_write_data; +wire [18:0] vram_read_addr; +wire [3:0] vram_read_data; +wire vram_wren; +/* +sdram sdram ( + .SDRAM_DQ(SDRAM_DQ), + .SDRAM_A(SDRAM_A), + .SDRAM_DQML(SDRAM_DQML), + .SDRAM_DQMH(SDRAM_DQMH), + .SDRAM_BA(SDRAM_BA), + .SDRAM_nCS(SDRAM_nCS), + .SDRAM_nWE(SDRAM_nWE), + .SDRAM_nRAS(SDRAM_nRAS), + .SDRAM_nCAS(SDRAM_nCAS), + .SDRAM_CKE(SDRAM_CKE), + .init(~locked), // init signal after FPGA config to initialize RAM + .clk(clk_50), // sdram is accessed at up to 128MHz + .clkref(clk_25), // reference clock to sync to + .din(vram_write_data), // data input from chipset/cpu + .dout(vram_read_data), // data output to chipset/cpu + .raddr(vram_read_addr), // 25 bit byte address + .waddr(vram_write_addr), // 25 bit byte address + .rd(~vram_wren), // cpu/chipset requests read + .we(vram_wren) +);*/ + +//reduced ram size + +p2ram p2ram ( + .clock(clk_25), + .data(vram_write_data), + .rdaddress(vram_read_addr[15:0]), + .wraddress(vram_write_addr[15:0]), + .wren(vram_wren), + .q(vram_read_data) + ); + +LLANDER_TOP LLANDER_TOP ( + .ROT_LEFT_L(~m_left), + .ROT_RIGHT_L(~m_right), + .ABORT_L(~m_fire2), + .GAME_SEL_L(~m_fire1), + .START_L(~btn_one_player), + .COIN1_L(~btn_coin), + .COIN2_L(1'b1), + .THRUST(thrust), + .DIAG_STEP_L(1'b1), + .SLAM_L(1'b1), + .SELF_TEST_L(~status[3]), + .START_SEL_L(1'b1), + .AUDIO_OUT(audio), + .VIDEO_R_OUT(r), + .VIDEO_G_OUT(g), + .VIDEO_B_OUT(b), + .LAMP2(lamp2), + .LAMP3(lamp3), + .LAMP4(lamp4), + .LAMP5(lamp5), + .HSYNC_OUT(hs), + .VSYNC_OUT(vs), + .VID_HBLANK(hb), + .VID_VBLANK(vb), + .VGA_DE(vgade), + .DIP({1'b0,1'b0,status[4],status[5],~status[6],1'b1,status[7],status[8]}),//todo dip full + .RESET_L(~(status[0] | buttons[1])), + .clk_6(clk_6), + .clk_25(clk_25), + .vram_write_addr(vram_write_addr), + .vram_write_data(vram_write_data), + .vram_read_addr(vram_read_addr), + .vram_read_data(vram_read_data), + .vram_wren(vram_wren) + ); + +ovo #( + .COLS(1), + .LINES(1), + .RGB(24'hFF00FF)) +diff ( + .i_r({r,r}), + .i_g({g,g}), + .i_b({b,b}), + .i_hs(~hs), + .i_vs(~vs), + .i_de(vgade), + .i_en(1), + .i_clk(clk_25), + + .o_r(ro), + .o_g(go), + .o_b(bo), + .o_hs(hso), + .o_vs(vso), + .o_de(), + .ena(diff_count > 0), + .in0(difficulty), + .in1() +); + +reg [7:0] thrust = 0; + +// 1 second = 50,000,000 cycles (duh) +// If we want to go from zero to full throttle in 1 second we tick every +// 196,850 cycles. +always @(posedge clk_50) begin :thrust_count + int thrust_count; + thrust_count <= thrust_count + 1'd1; + if (thrust_count == 'd196_850) begin + thrust_count <= 0; + if (m_down && thrust > 0) + thrust <= thrust - 1'd1; + + if (m_up && thrust < 'd254) + thrust <= thrust + 1'd1; + end +end + +int diff_count = 0; +always @(posedge clk_50) begin + if (diff_count > 0) + diff_count <= diff_count - 1; + if (~m_fire2) + diff_count <= 'd500_000_000; // 10 seconds +end + +wire lamp2, lamp3, lamp4, lamp5; +wire [1:0] difficulty; +always_comb begin + if(lamp5) + difficulty = 2'd3; + else if(lamp4) + difficulty = 2'd2; + else if(lamp3) + difficulty = 2'd1; + else + difficulty = 2'd0; +end + +mist_video #(.COLOR_DEPTH(6), .SD_HCNT_WIDTH(10)) mist_video( + .clk_sys ( clk_25 ), + .SPI_SCK ( SPI_SCK ), + .SPI_SS3 ( SPI_SS3 ), + .SPI_DI ( SPI_DI ), + .R ( blankn ? ro[7:2] : 0 ), + .G ( blankn ? go[7:2] : 0 ), + .B ( blankn ? bo[7:2] : 0 ), + .HSync ( hso ), + .VSync ( vso ), + .VGA_R ( VGA_R ), + .VGA_G ( VGA_G ), + .VGA_B ( VGA_B ), + .VGA_VS ( VGA_VS ), + .VGA_HS ( VGA_HS ), + .scandoubler_disable(1),//scandoublerD ), + .scanlines ( status[2:1] ), + .ypbpr ( ypbpr ) + ); + +user_io #(.STRLEN(($size(CONF_STR)>>3)))user_io( + .clk_sys (clk_25 ), + .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 ), + .key_strobe (key_strobe ), + .key_pressed (key_pressed ), + .key_code (key_code ), + .joystick_0 (joystick_0 ), + .joystick_1 (joystick_1 ), + .status (status ) + ); + +dac #( + .C_bits(8)) +dac( + .clk_i(clk_25), + .res_n_i(1), + .dac_i(audio), + .dac_o(AUDIO_L) + ); + +wire m_up = btn_up | joystick_0[3] | joystick_1[3]; +wire m_down = btn_down | joystick_0[2] | joystick_1[2]; +wire m_left = btn_left | joystick_0[1] | joystick_1[1]; +wire m_right = btn_right | joystick_0[0] | joystick_1[0]; +wire m_fire1 = btn_fire1 | joystick_0[4] | joystick_1[4]; +wire m_fire2 = btn_fire2 | joystick_0[5] | joystick_1[5]; +//wire m_fire3 = btn_fire3 | joystick_0[6] | joystick_1[6]; +reg btn_one_player = 0; +reg btn_left = 0; +reg btn_right = 0; +reg btn_down = 0; +reg btn_up = 0; +reg btn_fire1 = 0; +reg btn_fire2 = 0; +//reg btn_fire3 = 0; +reg btn_coin = 0; + +always @(posedge clk_25) begin + reg old_state; + old_state <= key_strobe; + if(old_state != key_strobe) begin + case(key_code) + 'h75: btn_up <= key_pressed; // up + 'h72: btn_down <= key_pressed; // down + 'h6B: btn_left <= key_pressed; // left + 'h74: btn_right <= key_pressed; // right + 'h76: btn_coin <= key_pressed; // ESC + 'h05: btn_one_player <= key_pressed; // F1 +// 'h14: btn_fire3 <= key_pressed; // ctrl + 'h11: btn_fire2 <= key_pressed; // alt + 'h29: btn_fire1 <= key_pressed; // Space + endcase + end +end + +endmodule \ No newline at end of file diff --git a/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/base_pack.vhd b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/base_pack.vhd new file mode 100644 index 00000000..6fcd2338 --- /dev/null +++ b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/base_pack.vhd @@ -0,0 +1,593 @@ +-------------------------------------------------------------------------------- +-- BASE +-- Definitions +-------------------------------------------------------------------------------- +-- DO 3/2009 +-------------------------------------------------------------------------------- +-- Base +-------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +PACKAGE base_pack IS + -------------------------------------- + SUBTYPE uv IS unsigned; + SUBTYPE sv IS signed; + + SUBTYPE uv1_0 IS unsigned(1 DOWNTO 0); + SUBTYPE uv0_1 IS unsigned(0 TO 1); + SUBTYPE uv3_0 IS unsigned(3 DOWNTO 0); + SUBTYPE uv0_3 IS unsigned(0 TO 3); + SUBTYPE uv7_0 IS unsigned(7 DOWNTO 0); + SUBTYPE uv0_7 IS unsigned(0 TO 7); + + SUBTYPE uv2 IS unsigned(1 DOWNTO 0); + SUBTYPE uv3 IS unsigned(2 DOWNTO 0); + SUBTYPE uv4 IS unsigned(3 DOWNTO 0); + SUBTYPE uv5 IS unsigned(4 DOWNTO 0); + SUBTYPE uv6 IS unsigned(5 DOWNTO 0); + SUBTYPE uv7 IS unsigned(6 DOWNTO 0); + SUBTYPE uv8 IS unsigned(7 DOWNTO 0); + SUBTYPE uv9 IS unsigned(8 DOWNTO 0); + SUBTYPE uv10 IS unsigned(9 DOWNTO 0); + SUBTYPE uv11 IS unsigned(10 DOWNTO 0); + SUBTYPE uv12 IS unsigned(11 DOWNTO 0); + SUBTYPE uv13 IS unsigned(12 DOWNTO 0); + SUBTYPE uv14 IS unsigned(13 DOWNTO 0); + SUBTYPE uv15 IS unsigned(14 DOWNTO 0); + SUBTYPE uv16 IS unsigned(15 DOWNTO 0); + SUBTYPE uv24 IS unsigned(23 DOWNTO 0); + SUBTYPE uv32 IS unsigned(31 DOWNTO 0); + SUBTYPE uv64 IS unsigned(63 DOWNTO 0); + SUBTYPE uv128 IS unsigned(127 DOWNTO 0); + + SUBTYPE sv2 IS signed(1 DOWNTO 0); + SUBTYPE sv4 IS signed(3 DOWNTO 0); + SUBTYPE sv8 IS signed(7 DOWNTO 0); + SUBTYPE sv16 IS signed(15 DOWNTO 0); + SUBTYPE sv32 IS signed(31 DOWNTO 0); + SUBTYPE sv64 IS signed(63 DOWNTO 0); + SUBTYPE sv128 IS signed(127 DOWNTO 0); + + TYPE arr_uv0_3 IS ARRAY(natural RANGE <>) OF uv0_3; + TYPE arr_uv0_7 IS ARRAY(natural RANGE <>) OF uv0_7; + + TYPE arr_uv4 IS ARRAY(natural RANGE <>) OF uv4; + TYPE arr_uv8 IS ARRAY(natural RANGE <>) OF uv8; + TYPE arr_uv16 IS ARRAY(natural RANGE <>) OF uv16; + TYPE arr_uv32 IS ARRAY(natural RANGE <>) OF uv32; + TYPE arr_uv64 IS ARRAY(natural RANGE <>) OF uv64; + + SUBTYPE uint1 IS natural RANGE 0 TO 1; + SUBTYPE uint2 IS natural RANGE 0 TO 3; + SUBTYPE uint3 IS natural RANGE 0 TO 7; + SUBTYPE uint4 IS natural RANGE 0 TO 15; + SUBTYPE uint5 IS natural RANGE 0 TO 31; + SUBTYPE uint6 IS natural RANGE 0 TO 63; + SUBTYPE uint7 IS natural RANGE 0 TO 127; + SUBTYPE uint8 IS natural RANGE 0 TO 255; + SUBTYPE uint12 IS natural RANGE 0 TO 4095; + SUBTYPE uint16 IS natural RANGE 0 TO 65535; + SUBTYPE uint24 IS natural RANGE 0 TO 16777215; + + ------------------------------------------------------------- + FUNCTION v_or (CONSTANT v : unsigned) RETURN std_logic; + FUNCTION v_and (CONSTANT v : unsigned) RETURN std_logic; + FUNCTION vv (CONSTANT s : std_logic; + CONSTANT N : natural) RETURN unsigned; + + -------------------------------------- + FUNCTION to_std_logic (a : boolean) RETURN std_logic; + -------------------------------------- + FUNCTION mux ( + s : std_logic; + a : unsigned; + b : unsigned) RETURN unsigned; + -------------------------------------- + FUNCTION mux ( + s : boolean; + a : unsigned; + b : unsigned) RETURN unsigned; + -------------------------------------- + FUNCTION mux ( + s : std_logic; + a : std_logic; + b : std_logic) RETURN std_logic; + -------------------------------------- + FUNCTION mux ( + s : boolean; + a : std_logic; + b : std_logic) RETURN std_logic; + -------------------------------------- + FUNCTION mux ( + s : boolean; + a : boolean; + b : boolean) RETURN boolean; + -------------------------------------- + FUNCTION mux ( + s : boolean; + a : natural; + b : natural) RETURN natural; + -------------------------------------- + FUNCTION mux ( + s : std_logic; + a : character; + b : character) RETURN character; + -------------------------------------- + FUNCTION mux ( + s : boolean; + a : character; + b : character) RETURN character; + -------------------------------------- + FUNCTION sext ( + e : unsigned; + l : natural) RETURN unsigned; + -------------------------------------- + FUNCTION sext ( + e : std_logic; + l : natural) RETURN unsigned; + -------------------------------------- + FUNCTION uext ( + e : unsigned; + l : natural) RETURN unsigned; + -------------------------------------- + FUNCTION uext ( + e : std_logic; + l : natural) RETURN unsigned; + -------------------------------------- + PROCEDURE wure ( + SIGNAL clk : IN std_logic; + CONSTANT n : IN natural:=1); + -------------------------------------- + PROCEDURE wufe ( + SIGNAL clk : IN std_logic; + CONSTANT n : IN natural:=1); + -------------------------------------- + FUNCTION To_HString (v : unsigned) RETURN string; + FUNCTION To_String (v : unsigned) RETURN string; + -------------------------------------- + FUNCTION To_Upper (c : character) RETURN character; + FUNCTION To_Upper (s : string) RETURN string; + FUNCTION To_String (i : natural; b : integer) RETURN string; + FUNCTION To_Natural (s : string; b : integer) RETURN natural; + + FUNCTION ilog2 (CONSTANT v : natural) RETURN natural; + +END PACKAGE base_pack; + +-------------------------------------------------------------------------------- + +PACKAGE BODY base_pack IS + + ------------------------------------------------------------- + FUNCTION vv (CONSTANT s : std_logic; + CONSTANT N : natural) RETURN unsigned IS + VARIABLE v : unsigned(N-1 DOWNTO 0); + BEGIN + v:=(OTHERS => s); + RETURN v; + END FUNCTION vv; + + ------------------------------------------------------------- + -- Vector OR (reduce) + FUNCTION v_or (CONSTANT v : unsigned) RETURN std_logic IS + VARIABLE r : std_logic := '0'; + VARIABLE Z : unsigned(v'range) := (OTHERS =>'0'); + BEGIN +--pragma synthesis_off + IF 1=1 THEN + FOR I IN v'range LOOP + r:=r OR v(I); + END LOOP; + RETURN r; + ELSE +--pragma synthesis_on + IF v/=Z THEN + RETURN '1'; + ELSE + RETURN '0'; + END IF; +--pragma synthesis_off + END IF; +--pragma synthesis_on + END FUNCTION v_or; + + ------------------------------------------------------------- + -- Vector AND (reduce) + FUNCTION v_and (CONSTANT v : unsigned) RETURN std_logic IS + VARIABLE r : std_logic := '1'; + VARIABLE U : unsigned(v'range) := (OTHERS =>'1'); + BEGIN +--pragma synthesis_off + IF 1=1 THEN + FOR I IN v'range LOOP + r:=r AND v(I); + END LOOP; + RETURN r; + ELSE +--pragma synthesis_on + IF v/=U THEN + RETURN '0'; + ELSE + RETURN '1'; + END IF; +--pragma synthesis_off + END IF; +--pragma synthesis_on + END FUNCTION v_and; + + -------------------------------------- + FUNCTION to_std_logic (a : boolean) RETURN std_logic IS + BEGIN + IF a THEN RETURN '1'; + ELSE RETURN '0'; + END IF; + END FUNCTION to_std_logic; + + -------------------------------------- + -- Sélection/Multiplexage s=1:a, s=0:b + FUNCTION mux ( + s : std_logic; + a : unsigned; + b : unsigned) RETURN unsigned IS + VARIABLE x : unsigned(a'range) :=(OTHERS => 'X'); + BEGIN + ASSERT a'length=b'length + REPORT "mux(): Different lengths" SEVERITY failure; + IF s='1' THEN + RETURN a; + ELSIF s='0' THEN + RETURN b; + ELSE + RETURN x; + END IF; + END FUNCTION mux; + + -------------------------------------- + -- Sélection/Multiplexage s=true:a, s=false:b + FUNCTION mux ( + s : boolean; + a : unsigned; + b : unsigned) RETURN unsigned IS + BEGIN + ASSERT a'length=b'length + REPORT "mux(): Different lengths" SEVERITY failure; + IF s THEN + RETURN a; + ELSE + RETURN b; + END IF; + END FUNCTION mux; + + -------------------------------------- + -- Sélection/Multiplexage s=1:a, s=0:b + FUNCTION mux ( + s : std_logic; + a : std_logic; + b : std_logic) + RETURN std_logic IS + BEGIN + RETURN (S AND A) OR (NOT S AND B); + END FUNCTION mux; + + -------------------------------------- + -- Sélection/Multiplexage s=true:a, s=false:b + FUNCTION mux ( + s : boolean; + a : std_logic; + b : std_logic) + RETURN std_logic IS + BEGIN + IF s THEN + RETURN a; + ELSE + RETURN b; + END IF; + END FUNCTION mux; + + -------------------------------------- + -- Sélection/Multiplexage s=true:a, s=false:b + FUNCTION mux ( + s : boolean; + a : boolean; + b : boolean) + RETURN boolean IS + BEGIN + IF s THEN + RETURN a; + ELSE + RETURN b; + END IF; + END FUNCTION mux; + + -------------------------------------- + -- Sélection/Multiplexage s=1:a, s=0:b + FUNCTION mux ( + s : boolean; + a : natural; + b : natural) + RETURN natural IS + BEGIN + IF s THEN + RETURN a; + ELSE + RETURN b; + END IF; + END FUNCTION mux; + + -------------------------------------- + -- Sélection/Multiplexage s=true:a, s=false:b + FUNCTION mux ( + s : std_logic; + a : character; + b : character) + RETURN character IS + BEGIN + IF s='1' THEN + RETURN a; + ELSE + RETURN b; + END IF; + END FUNCTION mux; + + -------------------------------------- + -- Sélection/Multiplexage s=true:a, s=false:b + FUNCTION mux ( + s : boolean; + a : character; + b : character) + RETURN character IS + BEGIN + IF s THEN + RETURN a; + ELSE + RETURN b; + END IF; + END FUNCTION mux; + + -------------------------------------- + -- Étend un vecteur avec extension de signe + FUNCTION sext ( + e : unsigned; + l : natural) RETURN unsigned IS + VARIABLE t : unsigned(l-1 DOWNTO 0); + BEGIN + -- Vérifier numeric_std.resize ... + t:=(OTHERS => e(e'left)); + t(e'length-1 DOWNTO 0):=e; + RETURN t; + END FUNCTION sext; + + -------------------------------------- + -- Étend un vecteur avec extension de signe + FUNCTION sext ( + e : std_logic; + l : natural) RETURN unsigned IS + VARIABLE t : unsigned(l-1 DOWNTO 0); + BEGIN + -- Vérifier numeric_std.resize ... + t:=(OTHERS => e); + RETURN t; + END FUNCTION sext; + + -------------------------------------- + -- Étend un vecteur sans extension de signe + FUNCTION uext ( + e : unsigned; + l : natural) RETURN unsigned IS + VARIABLE t : unsigned(l-1 DOWNTO 0); + BEGIN + -- Vérifier numeric_std.resize ... + t:=(OTHERS => '0'); + t(e'length-1 DOWNTO 0):=e; + RETURN t; + END FUNCTION uext; + + -------------------------------------- + -- Étend un vecteur sans extension de signe + FUNCTION uext ( + e : std_logic; + l : natural) RETURN unsigned IS + VARIABLE t : unsigned(l-1 DOWNTO 0); + BEGIN + -- Vérifier numeric_std.resize ... + t:=(OTHERS => '0'); + t(0):=e; + RETURN t; + END FUNCTION uext; + + -------------------------------------- + -- Wait Until Rising Edge + PROCEDURE wure( + SIGNAL clk : IN std_logic; + CONSTANT n : IN natural:=1) IS + BEGIN + FOR i IN 1 TO n LOOP + WAIT UNTIL rising_edge(clk); + END LOOP; + END PROCEDURE wure; + + -------------------------------------- + -- Wait Until Rising Edge + PROCEDURE wufe( + SIGNAL clk : IN std_logic; + CONSTANT n : IN natural:=1) IS + BEGIN + FOR i IN 1 TO n LOOP + WAIT UNTIL falling_edge(clk); + END LOOP; + END PROCEDURE wufe; + + -------------------------------------- + CONSTANT HexString : string(1 TO 16):="0123456789ABCDEF"; + + -- Conversion unsigned -> Chaîne hexadécimale + FUNCTION To_HString(v : unsigned) RETURN string IS + VARIABLE r : string(1 TO ((v'length)+3)/4); + VARIABLE x : unsigned(1 TO v'length); + VARIABLE i,j : integer; + BEGIN + x:=v; + i:=1; + j:=1; + r:=(OTHERS =>' '); + WHILE i Chaîne binaire + FUNCTION To_String(v : unsigned) RETURN string IS + VARIABLE r : string(1 TO v'length); + VARIABLE x : unsigned(1 TO v'length); + BEGIN + x:=v; + FOR i IN 1 TO v'length LOOP + CASE x(i) IS + WHEN '0' => r(i):='0'; + WHEN '1' => r(i):='1'; + WHEN 'X' => r(i):='X'; + WHEN 'Z' => r(i):='Z'; + WHEN 'U' => r(i):='U'; + WHEN 'H' => r(i):='H'; + WHEN 'L' => r(i):='L'; + WHEN '-' => r(i):='-'; + WHEN 'W' => r(i):='W'; + END CASE; + -- r(i):=std_logic'image(x(i))(1); + END LOOP; + RETURN r; + END FUNCTION To_String; + + -------------------------------------- + -- Conversion majuscules caractère + FUNCTION To_Upper(c : character) RETURN character IS + VARIABLE r : character; + BEGIN + CASE c IS + WHEN 'a' => r := 'A'; + WHEN 'b' => r := 'B'; + WHEN 'c' => r := 'C'; + WHEN 'd' => r := 'D'; + WHEN 'e' => r := 'E'; + WHEN 'f' => r := 'F'; + WHEN 'g' => r := 'G'; + WHEN 'h' => r := 'H'; + WHEN 'i' => r := 'I'; + WHEN 'j' => r := 'J'; + WHEN 'k' => r := 'K'; + WHEN 'l' => r := 'L'; + WHEN 'm' => r := 'M'; + WHEN 'n' => r := 'N'; + WHEN 'o' => r := 'O'; + WHEN 'p' => r := 'P'; + WHEN 'q' => r := 'Q'; + WHEN 'r' => r := 'R'; + WHEN 's' => r := 'S'; + WHEN 't' => r := 'T'; + WHEN 'u' => r := 'U'; + WHEN 'v' => r := 'V'; + WHEN 'w' => r := 'W'; + WHEN 'x' => r := 'X'; + WHEN 'y' => r := 'Y'; + WHEN 'z' => r := 'Z'; + WHEN OTHERS => r := c; + END CASE; + RETURN r; + END To_Upper; + + -------------------------------------- + -- Conversion majuscules chaîne + FUNCTION To_Upper(s: string) RETURN string IS + VARIABLE r: string (s'range); + BEGIN + FOR i IN s'range LOOP + r(i):= to_upper(s(i)); + END LOOP; + RETURN r; + END To_Upper; + + -------------------------------------- + -- Conversion entier -> chaîne + FUNCTION To_String(i: natural; b: integer) RETURN string IS + VARIABLE r : string(1 TO 10); + VARIABLE j,k : natural; + VARIABLE t : character; + BEGIN + j:=i; + k:=10; + WHILE j>=b LOOP + r(k):=HexString(j MOD b); + j:=j/b; + k:=k-1; + END LOOP; + + RETURN r(k TO 10); + END FUNCTION To_String; + + -------------------------------------- + -- Conversion chaîne -> entier + FUNCTION To_Natural (s : string; b : integer) RETURN natural IS + VARIABLE v,r : natural; + BEGIN + r:=0; + FOR i IN s'range LOOP + CASE s(i) IS + WHEN '0' => v:=0; + WHEN '1' => v:=1; + WHEN '2' => v:=2; + WHEN '3' => v:=3; + WHEN '4' => v:=4; + WHEN '5' => v:=5; + WHEN '6' => v:=6; + WHEN '7' => v:=7; + WHEN '8' => v:=8; + WHEN '9' => v:=9; + WHEN 'a' | 'A' => v:=10; + WHEN 'b' | 'B' => v:=11; + WHEN 'c' | 'C' => v:=12; + WHEN 'd' | 'D' => v:=13; + WHEN 'e' | 'E' => v:=14; + WHEN 'f' | 'F' => v:=15; + WHEN OTHERS => + v:=1000; + END CASE; + ASSERT vr LOOP + n:=n+1; + r:=r*2; + END LOOP; + RETURN n; + END FUNCTION ilog2; + +END PACKAGE BODY base_pack; diff --git a/Arcade_MiST/NinjaKun_MiST/rtl/build_id.tcl b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/build_id.tcl similarity index 100% rename from Arcade_MiST/NinjaKun_MiST/rtl/build_id.tcl rename to Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/build_id.tcl diff --git a/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/dpram.vhd b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/dpram.vhd new file mode 100644 index 00000000..fb0bfc8b --- /dev/null +++ b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/dpram.vhd @@ -0,0 +1,75 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +LIBRARY altera_mf; +USE altera_mf.altera_mf_components.all; + +entity dpram is + generic ( + addr_width_g : integer := 8; + data_width_g : integer := 8 + ); + PORT + ( + address_a : IN STD_LOGIC_VECTOR (addr_width_g-1 DOWNTO 0); + address_b : IN STD_LOGIC_VECTOR (addr_width_g-1 DOWNTO 0); + clock_a : IN STD_LOGIC := '1'; + clock_b : IN STD_LOGIC ; + data_a : IN STD_LOGIC_VECTOR (data_width_g-1 DOWNTO 0); + data_b : IN STD_LOGIC_VECTOR (data_width_g-1 DOWNTO 0) := (others => '0'); + enable_a : IN STD_LOGIC := '1'; + enable_b : IN STD_LOGIC := '1'; + wren_a : IN STD_LOGIC := '0'; + wren_b : IN STD_LOGIC := '0'; + q_a : OUT STD_LOGIC_VECTOR (data_width_g-1 DOWNTO 0); + q_b : OUT STD_LOGIC_VECTOR (data_width_g-1 DOWNTO 0) + ); +END dpram; + + +ARCHITECTURE SYN OF dpram IS +BEGIN + altsyncram_component : altsyncram + GENERIC MAP ( + address_reg_b => "CLOCK1", + clock_enable_input_a => "NORMAL", + clock_enable_input_b => "NORMAL", + clock_enable_output_a => "BYPASS", + clock_enable_output_b => "BYPASS", + indata_reg_b => "CLOCK1", + intended_device_family => "Cyclone III", + lpm_type => "altsyncram", + numwords_a => 2**addr_width_g, + numwords_b => 2**addr_width_g, + operation_mode => "BIDIR_DUAL_PORT", + outdata_aclr_a => "NONE", + outdata_aclr_b => "NONE", + outdata_reg_a => "UNREGISTERED", + outdata_reg_b => "UNREGISTERED", + power_up_uninitialized => "FALSE", + read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ", + read_during_write_mode_port_b => "NEW_DATA_NO_NBE_READ", + widthad_a => addr_width_g, + widthad_b => addr_width_g, + width_a => data_width_g, + width_b => data_width_g, + width_byteena_a => 1, + width_byteena_b => 1, + wrcontrol_wraddress_reg_b => "CLOCK1" + ) + PORT MAP ( + address_a => address_a, + address_b => address_b, + clock0 => clock_a, + clock1 => clock_b, + clocken0 => enable_a, + clocken1 => enable_b, + data_a => data_a, + data_b => data_b, + wren_a => wren_a, + wren_b => wren_b, + q_a => q_a, + q_b => q_b + ); + +END SYN; diff --git a/Arcade_MiST/Sega Zaxxon Hardware/rtl/gen_ram.vhd b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/gen_ram.vhd similarity index 100% rename from Arcade_MiST/Sega Zaxxon Hardware/rtl/gen_ram.vhd rename to Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/gen_ram.vhd diff --git a/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander.vhd b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander.vhd new file mode 100644 index 00000000..7ae44809 --- /dev/null +++ b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander.vhd @@ -0,0 +1,648 @@ +-- +-- A simulation model of Lunar Lander hardware +-- James Sweet 2019 +-- This is not endorsed by fpgaarcade, please do not bother MikeJ with support requests +-- +-- Built upon model of Asteroids Deluxe hardware +-- Copyright (c) MikeJ - May 2004 +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- You are responsible for any legal issues arising from your use of this code. +-- +-- The latest version of this file can be found at: www.fpgaarcade.com +-- +-- Email support@fpgaarcade.com +-- +-- Revision list +-- +-- version 001 initial release +-- +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +entity LLander is + port ( + CLK_6 : in std_logic; + CLK_25 : in std_logic; + RESET_6_L : in std_logic; + -- + DIP : in std_logic_vector(7 downto 0); + -- + ROT_LEFT_L : in std_logic; + ROT_RIGHT_L : in std_logic; + ABORT_L : in std_logic; + GAME_SEL_L : in std_logic; + START_L : in std_logic; + COIN1_L : in std_logic; + COIN2_L : in std_logic; + -- + THRUST : in std_logic_vector(7 downto 0); + -- + DIAG_STEP_L : in std_logic; + SLAM_L : in std_logic; + SELF_TEST_L : in std_logic; + -- + START_SEL_L : out std_logic; + LAMP2 : out std_logic; + LAMP3 : out std_logic; + LAMP4 : out std_logic; + LAMP5 : out std_logic; + COIN_CTR : out std_logic; + -- + AUDIO_OUT : out std_logic_vector(7 downto 0); + -- + X_VECTOR : out std_logic_vector(9 downto 0); + Y_VECTOR : out std_logic_vector(9 downto 0); + Z_VECTOR : out std_logic_vector(3 downto 0); + BEAM_ON : out std_logic; + BEAM_ENA : out std_logic + ); +end; + +architecture RTL of LLander is + + + signal ena_count : std_logic_vector(10 downto 0) := (others => '0'); + signal ena_3M : std_ulogic; + signal ena_1_5M : std_ulogic; + signal ena_1_5M_e : std_ulogic; + signal ena_3K : std_ulogic; + signal ena_12k : std_ulogic; + signal clk_3k : std_ulogic; + signal clk_6K : std_ulogic; + signal clk_12K : std_ulogic; + + -- cpu + signal c_addr : std_logic_vector(23 downto 0); + signal c_din : std_logic_vector(7 downto 0); + signal c_dout : std_logic_vector(7 downto 0); + signal c_rw_l : std_logic; + signal c_irq_l : std_logic; + signal c_nmi_l : std_logic; + signal reset_l : std_logic; + signal wd_cnt : std_logic_vector(7 downto 0); + -- + signal nmi_count : std_logic_vector(3 downto 0); + -- addr decode + signal zpage_l : std_logic; + signal io_l : std_logic; + signal vmem_l : std_logic; + signal pmem_l : std_logic; + -- + signal sinp0_l : std_logic; + signal sinp1_l : std_logic; + signal opts_l : std_logic; + signal pot_l : std_logic; + -- + signal dma_go_l : std_logic; + signal outck_l : std_logic; + signal wdclr_l : std_logic; + signal explode_l : std_logic; + signal dma_reset_l : std_logic; + signal audio_l : std_logic; + signal noiserst_l : std_logic; + -- + signal shipthrusten : std_logic; + -- + signal test_l : std_logic; + signal halt : std_logic; + + -- memory + signal rom0_dout : std_logic_vector(7 downto 0); + signal rom1_dout : std_logic_vector(7 downto 0); + signal rom2_dout : std_logic_vector(7 downto 0); + signal rom3_dout : std_logic_vector(7 downto 0); + signal rom_dout : std_logic_vector(7 downto 0); + signal ram_addr : std_logic_vector(9 downto 0); + signal ram_dout : std_logic_vector(7 downto 0); + signal vg_dout : std_logic_vector(7 downto 0); + signal ram_we : std_logic; + + -- io + signal dips_p6_l : std_logic_vector(7 downto 0); + signal dips_ip_sel : std_logic_vector(1 downto 0); + + signal control_ip0_l : std_logic_vector(7 downto 0); + signal control_ip0_sel : std_logic; + signal control_ip1_l : std_logic_vector(7 downto 0); + signal control_ip1_sel : std_logic; + + -- sound + signal aud : std_logic_vector(5 downto 0); + signal tone3khz : std_logic_vector(3 downto 0); + signal tone6khz : std_logic_vector(3 downto 0); + + signal t_e_vol : std_logic_vector(2 downto 0); + + signal noise_shift : std_logic_vector(15 downto 0); + signal noise : std_logic; + signal shpsnd : std_logic_vector(3 downto 0); + signal lifesnd : std_logic_vector(3 downto 0); + + + signal lifeen : std_logic; + signal shpsnd_prefilter : std_logic; + signal shpsnd_filter_t1 : std_logic_vector(3 downto 0); + signal shpsnd_filter_t2 : std_logic_vector(3 downto 0); + signal shpsnd_filter_t3 : std_logic_vector(3 downto 0); + signal shpsnd_filtered : std_logic_vector(5 downto 0); + signal expaud : std_logic_vector(2 downto 0); + signal expitch : std_logic_vector(1 downto 0); + signal noise_cnt : std_logic_vector(3 downto 0); + signal expld_snd : std_logic_vector(3 downto 0); + + + signal clkdiv2 : std_logic_vector(3 downto 0); + signal audio_out2 : std_logic_vector(7 downto 0); + +begin + + + + p_ena : process -- clock divider + begin + wait until rising_edge(CLK_6); + ena_count <= ena_count + "1"; + ena_3M <= not ena_count(0); -- 3 Mhz; + + ena_1_5M <= '0'; + ena_1_5M_e <= '0'; + if (ena_count(1 downto 0) = "00") then + ena_1_5M <= '1'; -- 1.5 Mhz + end if; + if (ena_count(1 downto 0) = "10") then + ena_1_5M_e <= '1'; -- 1.5 Mhz (early) + end if; + ena_12k <= '0'; + if (ena_count(8 downto 0) = "000000000") then + ena_12k <= '1'; + end if; + + ena_3k <= '0'; + if (ena_count(10 downto 0) = "00000000000") then + ena_3k <= '1'; + end if; + + clk_3k <= ena_count(10); + end process; + + + cpu : entity work.T65 -- main cpu + port map ( + Mode => "00", + Res_n => reset_l, + Enable => ena_1_5M, + Clk => CLK_6, + Rdy => '1', + Abort_n => '1', + IRQ_n => '1', + NMI_n => c_nmi_l, + SO_n => '1', + R_W_n => c_rw_l, + Sync => open, + EF => open, + MF => open, + XF => open, + ML_n => open, + VP_n => open, + VDA => open, + VPA => open, + A => c_addr, + DI => c_din, + DO => c_dout + ); + + + p_nmi : process(reset_l, CLK_6) + variable carry : boolean; + begin + if (reset_l = '0') then + c_nmi_l <= '1'; + nmi_count <= "0000"; + elsif rising_edge(CLK_6) then + -- divide 3k signal by 12 + carry := (nmi_count = "1111"); + + c_nmi_l <= '1'; + if (test_l = '1') and carry then + c_nmi_l <= '0'; + end if; + + if (ena_3K = '1') then + if carry then + nmi_count <= "0100"; + else + nmi_count <= nmi_count + "1"; + end if; + end if; + + end if; + end process; + + p_wd_reset : process(RESET_6_L, CLK_6) + begin + if (RESET_6_L = '0') then + wd_cnt <= "00000000"; + reset_l <= '0'; + elsif rising_edge(CLK_6) then + + if (wdclr_l = '0') then + wd_cnt <= "00000000"; + elsif (ena_3K = '1') then + wd_cnt <= wd_cnt + "1"; + end if; + + if (ena_3k = '1') and (wd_cnt = "01111111") then + reset_l <= not reset_l; + end if; + -- simulation + -- reset_l <= reset_6_l; + end if; + end process; + + p_addr_decode1 : process(c_addr, c_rw_l, ena_1_5M, reset_l) + variable deca : std_logic_vector(3 downto 0); + variable decb : std_logic_vector(3 downto 0); + variable decc : std_logic_vector(7 downto 0); + variable input_read : std_logic; + variable control_write : std_logic; + begin + -- cpu address bit 15 is tied to ground + -- as far as the rest of the system is concerned + deca := "1111"; + case c_addr(14 downto 13) is + when "00" => deca := "1110"; + when "01" => deca := "1101"; + when "10" => deca := "1011"; + when "11" => deca := "0111"; + when others => null; + end case; + zpage_l <= deca(0); + io_l <= deca(1); + vmem_l <= deca(2); + pmem_l <= deca(3); + + + input_read := (not deca(1)) and (not c_addr(12)) and c_rw_l; + decb := "1111"; + if (input_read = '1') then + case c_addr(11 downto 10) is + when "00" => decb := "1110"; + when "01" => decb := "1101"; + when "10" => decb := "1011"; + when "11" => decb := "0111"; + when others => null; + end case; + end if; + sinp0_l <= decb(0); + sinp1_l <= decb(1); + opts_l <= decb(2); + pot_l <= decb(3); + + control_write := (not deca(1)) and c_addr(12) and (not c_rw_l);-- and ena_1_5M; + decc := "11111111"; + if (control_write = '1') then + case c_addr(11 downto 9) is + when "000" => decc := "11111110"; + when "001" => decc := "11111101"; + when "010" => decc := "11111011"; + when "011" => decc := "11110111"; + when "100" => decc := "11101111"; + when "101" => decc := "11011111"; + when "110" => decc := "10111111"; + when "111" => decc := "01111111"; + when others => null; + end case; + end if; + dma_go_l <= decc(0); + outck_l <= decc(1); + wdclr_l <= decc(2); + dma_reset_l <= decc(4); + audio_l <= decc(6); + noiserst_l <= decc(7); + end process; + + + lamp_reg : process(reset_l, clk_6) + begin + if (reset_l = '0') then + lamp5 <= '0'; + lamp4 <= '0'; + lamp3 <= '0'; + lamp2 <= '0'; + start_sel_l <= '0'; + coin_ctr <= '0'; + elsif rising_edge(CLK_6) then + if (ena_1_5M = '1') then + if (outck_l = '0') then + lamp5 <= c_dout(0); + lamp4 <= c_dout(1); + lamp3 <= c_dout(2); + lamP2 <= c_dout(3); + start_sel_l <= c_dout(4); + coin_ctr <= c_dout(5); + end if; + end if; + end if; + end process; + + + p_input_registers : process + begin + wait until rising_edge(CLK_6); + dips_p6_l <= DIP; + + -- diag step, self test, slam, halt + control_ip0_l(7) <= DIAG_STEP_L; + control_ip0_l(6) <= clk_3k; + control_ip0_l(5) <= '1'; + control_ip0_l(4) <= '1'; + control_ip0_l(3) <= '1'; + control_ip0_l(2) <= SLAM_L; + control_ip0_l(1) <= test_l; + control_ip0_l(0) <= halt; + + test_l <= SELF_TEST_L; + + -- left, right, abort, game select, coin11, coin2, start + control_ip1_l(7) <= ROT_LEFT_L; + control_ip1_l(6) <= ROT_RIGHT_L; + control_ip1_l(5) <= ABORT_L; + control_ip1_l(4) <= GAME_SEL_L; + control_ip1_l(3) <= not COIN1_L; + control_ip1_l(2) <= '1'; + control_ip1_l(1) <= not COIN2_L; + control_ip1_l(0) <= START_L; + end process; + + + p_input_sel : process(c_addr, dips_p6_l, control_ip0_l, control_ip1_l, clk_3k, halt) + begin + control_ip1_sel <= '0'; + case c_addr(2 downto 0) is + when "000" => control_ip1_sel <= not control_ip1_l(0); + when "001" => control_ip1_sel <= not control_ip1_l(1); + when "010" => control_ip1_sel <= not control_ip1_l(2); + when "011" => control_ip1_sel <= not control_ip1_l(3); + when "100" => control_ip1_sel <= not control_ip1_l(4); + when "101" => control_ip1_sel <= not control_ip1_l(5); + when "110" => control_ip1_sel <= not control_ip1_l(6); + when "111" => control_ip1_sel <= not control_ip1_l(7); + when others => null; + end case; + + dips_ip_sel <= "00"; + case c_addr(1 downto 0) is + when "00" => dips_ip_sel <= dips_p6_l(1) & dips_p6_l(0); + when "01" => dips_ip_sel <= dips_p6_l(3) & dips_p6_l(2); + when "10" => dips_ip_sel <= dips_p6_l(5) & dips_p6_l(4); + when "11" => dips_ip_sel <= dips_p6_l(7) & dips_p6_l(6); + when others => null; + end case; + end process; + + rom0 : entity work.LLANDER_PROG_ROM_0 + port map ( + addr => c_addr(10 downto 0), + data => rom0_dout, + clk => CLK_6 + ); + + rom1 : entity work.LLANDER_PROG_ROM_1 + port map ( + addr => c_addr(10 downto 0), + data => rom1_dout, + clk => CLK_6 + ); + + rom2 : entity work.LLANDER_PROG_ROM_2 + port map ( + addr => c_addr(10 downto 0), + data => rom2_dout, + clk => CLK_6 + ); + + rom3 : entity work.LLANDER_PROG_ROM_3 + port map ( + addr => c_addr(10 downto 0), + data => rom3_dout, + clk => CLK_6 + ); + + p_rom_mux : process(c_addr, rom0_dout, rom1_dout, rom2_dout, rom3_dout) + begin + rom_dout <= (others => '0'); + case c_addr(12 downto 11) is + when "00" => rom_dout <= rom0_dout; + when "01" => rom_dout <= rom1_dout; + when "10" => rom_dout <= rom2_dout; + when "11" => rom_dout <= rom3_dout; + when others => null; + end case; + end process; + + +-- Zero-page RAM +--RAM: Entity work.RAM256 +--port map( +-- clock => clk_6, +-- address => c_addr(7 downto 0), +-- data => c_dout, +-- wren => ram_we, +-- q => ram_dout +-- ); + +RAM: Entity work.gen_ram + generic map( + dWidth => 8, + aWidth => 8) + port map( + clk => clk_6, + we => ram_we, + addr => c_addr(7 downto 0), + d => c_dout, + q => ram_dout + ); + +ram_we <= (not zpage_l) and (not c_rw_l) and ena_1_5M; + + +-- CPU Data in mux controlled by address decoder +p_cpu_data_mux : process(c_addr, ram_dout, rom_dout, vg_dout, zpage_l, pmem_l, vmem_l, + sinp0_l, control_ip0_l, sinp1_l, control_ip1_sel, + opts_l, dips_ip_sel, pot_l, thrust) +begin + c_din <= (others => '0'); + if (sinp0_l = '0') then + c_din <= control_ip0_l; + elsif (sinp1_l = '0') then + c_din <= control_ip1_sel & "1111111"; + elsif (opts_l = '0') then + c_din <= "111111" & dips_ip_sel; + elsif (pot_l = '0') then + c_din <= thrust ; + elsif (zpage_l = '0') then + c_din <= ram_dout; + elsif (pmem_l = '0') then + c_din <= rom_dout; + elsif (vmem_l = '0') then + c_din <= vg_dout; + end if; +end process; + + + -- + -- audio + -- + + -- Thrust Aud0 through Aud 2 - volume + -- Explosion - Aud 3, volume by Aud 0 through Aud 2 + -- 3k - Aud 4 + -- 6k - Aud 5 + + -- Output register for audio control + p_aud_reg : process(RESET_L, CLK_6) + begin + if (reset_l = '0') then + aud <= "000000"; + elsif rising_edge(CLK_6) then + if (ena_1_5M = '1') then + if (audio_l = '0') then + aud <= c_dout(5 downto 0); + end if; + end if; + end if; + end process; + + + tone3khz <= "1111" when clk_3k = '1' and aud(4) = '1' else "0000"; + tone6khz <= "1111" when clk_6k = '1' and aud(5) = '1' else "0000"; + t_e_vol <= aud(2 downto 0); + shipthrusten <= aud(0) or aud(1) or aud(2); + + + -- LFSR to generate noise used in the ship thrust and explosion sounds + p_noise_gen : process(RESET_L, CLK_6) + variable shift_in : std_logic; + begin + if (reset_l = '0') then + noise_shift <= (others => '0'); + noise <= '0'; + elsif rising_edge(CLK_6) then + if (ena_12k = '1') then + shift_in := not(noise_shift(6) xor noise_shift(14)); + noise_shift <= noise_shift(14 downto 0) & shift_in; + noise <= shift_in; -- one clock late + end if; + end if; + end process; + + -- Ship thrust sound, passes noise through a low pass filter + p_ship_snd : process + begin + wait until rising_edge(CLK_6); + shpsnd_prefilter <= noise and shipthrusten; + -- simple low pass filter + if (ena_3k = '1') then + if (shpsnd_prefilter = '1') then + shpsnd_filter_t1 <= t_e_vol & '0'; + else + shpsnd_filter_t1 <= "0000"; + end if; + shpsnd_filter_t2 <= shpsnd_filter_t1; + shpsnd_filter_t3 <= shpsnd_filter_t2; + end if; + shpsnd_filtered <= ("00" & shpsnd_filter_t1 ) + + ('0' & shpsnd_filter_t2 & '0') + + ("00" & shpsnd_filter_t3 ); + end process; + + + p_expld_gen : process(reset_l, clk_6, aud) + begin + if reset_l = '0' then + expaud <= "000"; + elsif (aud(3) = '1') and (noise = '1') then + expaud <= aud(2 downto 0); + else + expaud <= "000"; + end if; + end process; + + + p_audio_output_reg : process + variable sum : std_logic_vector(8 downto 0); + begin + wait until rising_edge(clk_6); + + sum := ('0' & tone6khz)+ ('0' & tone3khz)+ ("00" & expaud & "000") + ('0' & shpsnd_filtered & "00"); + + if (sum(8) = '0') then + AUDIO_OUT <= sum(7 downto 0); + else -- clip + AUDIO_OUT <= "11111111"; + end if; + end process; + + + -- + -- vector generator + -- + + vg : entity work.LLANDER_VG + port map ( + C_ADDR => c_addr(15 downto 0), + C_DIN => c_dout, + C_DOUT => vg_dout, + C_RW_L => c_rw_l, + VMEM_L => vmem_l, + + DMA_GO_L => dma_go_l, + DMA_RESET_L => dma_reset_l, + HALT_OP => halt, + + X_VECTOR => X_VECTOR, + Y_VECTOR => Y_VECTOR, + Z_VECTOR => Z_VECTOR, + BEAM_ON => BEAM_ON, + -- + ENA_1_5M => ena_1_5m, + ENA_1_5M_E => ena_1_5m_e, + RESET_L => reset_l, + CLK_6 => CLK_6, + CLK_25 => CLK_25 + ); + + BEAM_ENA <= ena_1_5m; + + +end RTL; diff --git a/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_dw.vhd b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_dw.vhd new file mode 100644 index 00000000..7fb8a131 --- /dev/null +++ b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_dw.vhd @@ -0,0 +1,450 @@ +-- +-- A simulation model of Asteroids Deluxe hardware +-- Copyright (c) MikeJ - May 2004 +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- You are responsible for any legal issues arising from your use of this code. +-- +-- The latest version of this file can be found at: www.fpgaarcade.com +-- +-- Email support@fpgaarcade.com +-- +-- Revision list +-- +-- version 001 initial release +-- +-- This code is not part of the original game. + +-- Dave Wood (oldgit) Feb 2019 + +-- My smaller version (512 x 512 screen). This module takes the Vectors and beam intensisty and +-- produces a double buffered raster graphics screen. The intensity was used to give a 'blue hue' as per the original game +-- to the rocks and text but produces white for the ships. + +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_arith.all; + use ieee.std_logic_unsigned.all; + +--use work.pkg_asteroids.all; + +entity LLANDER_DW is + port ( + RESET : in std_logic; + clk_25 : in std_logic; + clk_6 : in std_logic; + + X_VECTOR : in std_logic_vector(9 downto 0); + Y_VECTOR : in std_logic_vector(9 downto 0); + Z_VECTOR : in std_logic_vector(3 downto 0); + BEAM_ON : in std_logic; + BEAM_ENA : in std_logic; + + VIDEO_R_OUT : out std_logic_vector(3 downto 0); + VIDEO_G_OUT : out std_logic_vector(3 downto 0); + VIDEO_B_OUT : out std_logic_vector(3 downto 0); + HSYNC_OUT : out std_logic; + VSYNC_OUT : out std_logic; + VID_DE : out std_logic; + VID_HBLANK : out std_logic; + VID_VBLANK : out std_logic; + + vram_write_addr : out std_logic_vector(18 downto 0); + vram_write_data : out std_logic_vector(3 downto 0); + vram_read_addr : out std_logic_vector(18 downto 0); + vram_read_data : in std_logic_vector(3 downto 0); + vram_wren : out std_logic + ); +end; + +architecture RTL of LLANDER_DW is + -- types & constants + subtype Bus12 is std_logic_vector (11 downto 0); + + constant V_FRONT_PORCH_START : Bus12 := x"1e0"; -- line 480 + constant V_SYNC_START : Bus12 := x"1ea"; -- line 490 + constant V_BACK_PORCH_START : Bus12 := x"1ec"; -- line 492 + constant LINE_PER_FRAME : Bus12 := x"20d"; -- 525 lines + + constant H_FRONT_PORCH_START : Bus12 := x"280"; -- pixel 640 + constant H_SYNC_START : Bus12 := x"290"; -- pixel 656 + constant H_BACK_PORCH_START : Bus12 := x"2f0"; -- pixel 752 + constant PIXEL_PER_LINE : Bus12 := x"320"; -- 800 pixels + + signal lcount : std_logic_vector(9 downto 0); + signal pcount : std_logic_vector(10 downto 0); + + signal hterm : boolean; + signal vterm : boolean; + signal v_sync : std_logic; + signal h_sync : std_logic; + signal v_blank : std_logic; + signal h_blank : std_logic; + signal raster_active : std_logic; + + -- + signal beam_ena_t : std_logic_vector(2 downto 0); + signal beam_load : std_logic; + signal video_r : std_logic_vector(3 downto 0); + signal video_g : std_logic_vector(3 downto 0); + signal video_b : std_logic_vector(3 downto 0); + + signal dw_addr : std_logic_vector(18 downto 0); + + signal up_addr : std_logic_vector(17 downto 0); + signal vid_out : std_logic_vector(3 downto 0); + signal Y_Vid : std_logic_vector(8 downto 0); + signal X_Vid : std_logic_vector(8 downto 0); + signal Vid_data : std_logic_vector(3 downto 0); + + signal dcount : std_logic_vector(2 downto 0); + signal screen : std_logic_vector(0 downto 0); + signal vcount : std_logic_vector(8 downto 0); + signal hcount : std_logic_vector(8 downto 0); + signal pxcount : std_logic_vector(8 downto 0); +-- signal vram_wren : std_logic; + + + + + +begin + + pixel_cnt : process(clk_25, RESET) + variable vcnt_front_porch_start : boolean; + variable hcnt_front_porch_start : boolean; + begin + if (RESET = '1') then + hcount <= (others => '0'); + vcount <= (others => '0'); + + elsif rising_edge(clk_25) then + + vcnt_front_porch_start := (vcount = 511); + hcnt_front_porch_start := (hcount = 511); + + if hcnt_front_porch_start then + hcount <= (others => '0'); + else + hcount <= hcount + "1"; + end if; + + if hcnt_front_porch_start then + if vcnt_front_porch_start then + vcount <= (others => '0'); + + else + vcount <= vcount + "1"; + end if; + end if; + + end if; + end process; + + -- basic raster gen + p_cnt_compare_comb : process(pcount,lcount) + begin + hterm <= (pcount = (PIXEL_PER_LINE(10 downto 0) - "1")); + vterm <= (lcount = (LINE_PER_FRAME( 9 downto 0) - "1")); + end process; + + p_display_cnt : process(clk_25, RESET) + begin + if (RESET = '1') then + pcount <= (others => '0'); + lcount <= (others => '0'); + dcount <= (others => '0'); + elsif rising_edge(clk_25) then + if hterm then + pcount <= (others => '0'); + else + pcount <= pcount + "1"; + end if; + + if pcount > 63 then + pxcount <= pxcount + "1"; + raster_active <= '1'; + end if; + if pcount > 575 then + raster_active <= '0'; + pxcount <= "111111111"; + end if; + + + if hterm then + if vterm then + lcount <= (others => '0'); + dcount <= dcount + "1" ; + else + lcount <= lcount + "1"; + end if; + end if; + + end if; + end process; + + p_vsync : process(clk_25, RESET) + variable vcnt_eq_front_porch_start : boolean; + variable vcnt_eq_sync_start : boolean; + variable vcnt_eq_back_porch_start : boolean; + begin + if (RESET = '1') then + v_sync <= '1'; + v_blank <= '0'; + elsif rising_edge(clk_25) then + + vcnt_eq_front_porch_start := (lcount = (V_FRONT_PORCH_START(9 downto 0) - "1")); + vcnt_eq_sync_start := (lcount = ( V_SYNC_START(9 downto 0) - "1")); + vcnt_eq_back_porch_start := (lcount = ( V_BACK_PORCH_START(9 downto 0) - "1")); + + if vcnt_eq_sync_start and hterm then + v_sync <= '0'; + elsif vcnt_eq_back_porch_start and hterm then + v_sync <= '1'; + end if; + + if vcnt_eq_front_porch_start and hterm then + v_blank <= '1'; + elsif vterm and hterm then + v_blank <= '0'; + end if; + + end if; + end process; + + p_hsync : process(clk_25, RESET) + variable hcnt_eq_front_porch_start : boolean; + variable hcnt_eq_sync_start : boolean; + variable hcnt_eq_back_porch_start : boolean; + begin + if (RESET = '1') then + h_sync <= '1'; + h_blank <= '1'; -- 0 + elsif rising_edge(clk_25) then + hcnt_eq_front_porch_start := (pcount = ( H_FRONT_PORCH_START(10 downto 0) - "1")); + hcnt_eq_sync_start := (pcount = ( H_SYNC_START(10 downto 0) - "1")); + hcnt_eq_back_porch_start := (pcount = ( H_BACK_PORCH_START(10 downto 0) - "1")); + + if hcnt_eq_sync_start then + h_sync <= '0'; + elsif hcnt_eq_back_porch_start then + h_sync <= '1'; + end if; + + if hcnt_eq_front_porch_start then + h_blank <= '1'; + elsif hterm then + h_blank <= '0'; + end if; + + end if; + end process; + + p_active_video : process(h_blank, v_blank, raster_active, lcount, pxcount) + begin +-- raster_active <= not(h_blank or v_blank); + if raster_active = '1' then + Y_Vid <= not (lcount(8 downto 0) and lcount(8 downto 0)) ; + else + Y_Vid <= "111111111"; + end if; + if raster_active = '1' then + X_Vid <= pxcount(8 downto 0); + else + X_Vid <= "111111111"; + end if; + + end process; + + p_video_out : process + begin + wait until rising_edge(clk_25); + if raster_active = '1' then + case vid_out is + when "0000" => video_r <= "0000";video_g <= "0000";video_b <= "0000"; + when "0001" => video_r <= "0001";video_g <= "0001";video_b <= "0001"; + when "0010" => video_r <= "0011";video_g <= "0011";video_b <= "0011"; + when "0011" => video_r <= "0011";video_g <= "0011";video_b <= "0011"; + when "0100" => video_r <= "0011";video_g <= "0011";video_b <= "0111"; + when "0101" => video_r <= "0011";video_g <= "0011";video_b <= "0111"; + when "0110" => video_r <= "0011";video_g <= "0011";video_b <= "0111"; + when "0111" => video_r <= "0011";video_g <= "0011";video_b <= "0111"; + -- when "1000" => video_r <= "0111";video_g <= "0111";video_b <= "0111"; + when "1000" => video_r <= "0011";video_g <= "0011";video_b <= "0111"; + --when "1001" => video_r <= "0111";video_g <= "0111";video_b <= "0111"; + when "1001" => video_r <= "0011";video_g <= "0011";video_b <= "0111"; + when "1010" => video_r <= "0111";video_g <= "0111";video_b <= "0111"; + when "1011" => video_r <= "0111";video_g <= "0111";video_b <= "0111"; + when "1100" => video_r <= "1111";video_g <= "1111";video_b <= "1111"; + when "1101" => video_r <= "1111";video_g <= "1111";video_b <= "1111"; + when "1110" => video_r <= "1111";video_g <= "1111";video_b <= "1111"; + when others => video_r <= "1111";video_g <= "1111";video_b <= "1111"; + end case; + VIDEO_R_OUT <= video_r; + VIDEO_G_OUT <= video_g; + VIDEO_B_OUT <= video_b; + else -- blank + VIDEO_R_OUT <= "0000"; + VIDEO_G_OUT <= "0000"; + VIDEO_B_OUT <= "0000"; + end if; + VID_DE <= not(v_blank or h_blank); + VSYNC_OUT <= v_sync; + HSYNC_OUT <= h_sync; + VID_HBLANK <= h_blank; + VID_VBLANK <= v_blank; + + end process; + + up_addr <= (Y_Vid(8 downto 0) & X_Vid(8 downto 0)); + + clear_ram : process(clk_25, RESET) + variable state : integer range 0 to 4; + variable beam_ena_r : std_logic := '0'; + + begin + if RESET = '1' then + beam_ena_r := '0'; + + elsif rising_edge(clk_25) then + vram_wren <= '0' after 2 ns; + + if dcount = "000" then + screen <= "0"; + dw_addr <= "0" & ((Y_VECTOR(9 downto 1) ) & X_VECTOR(9 downto 1)); + if BEAM_ON = '1' and beam_ena_r = '0' and BEAM_ENA = '1' then + if Z_VECTOR(3 downto 0) = "0000" then + vid_data <= "0000"; + vram_wren <= '0'; + else + vid_data <= Z_VECTOR(3 downto 0); + vram_wren <= '1'; + end if; + end if; + end if; + if dcount = "001" then + screen <= "0"; + dw_addr <= "1" & (vcount ) & hcount; + vid_data <= "0000"; + vram_wren <= '1'; + end if; + if dcount = "010" then + screen <= "0"; + dw_addr <= "0" & ((Y_VECTOR(9 downto 1) ) & X_VECTOR(9 downto 1)); + if BEAM_ON = '1' and beam_ena_r = '0' and BEAM_ENA = '1' then + if Z_VECTOR(3 downto 0) = "0000" then + vid_data <= "0000"; + vram_wren <= '0'; + else + vid_data <= Z_VECTOR(3 downto 0); + vram_wren <= '1'; + end if; + end if; + end if; + if dcount = "011" then + screen <= "0"; + dw_addr <= "1" & ((Y_VECTOR(9 downto 1) ) & X_VECTOR(9 downto 1)); + if BEAM_ON = '1' and beam_ena_r = '0' and BEAM_ENA = '1' then + if Z_VECTOR(3 downto 0) = "0000" then + vid_data <= "0000"; + vram_wren <= '0'; + else + vid_data <= Z_VECTOR(3 downto 0); + vram_wren <= '1'; + end if; + end if; + end if; + if dcount = "100" then + screen <= "1"; + dw_addr <= "1" & ((Y_VECTOR(9 downto 1) ) & X_VECTOR(9 downto 1)); + if BEAM_ON = '1' and beam_ena_r = '0' and BEAM_ENA = '1' then + if Z_VECTOR(3 downto 0) = "0000" then + vid_data <= "0000"; + vram_wren <= '0'; + else + vid_data <= Z_VECTOR(3 downto 0); + vram_wren <= '1'; + end if; + end if; + end if; + if dcount = "101" then + screen <= "1"; + dw_addr <= "0" & (vcount ) & hcount; + vid_data <= "0000"; + vram_wren <= '1'; + end if; + if dcount = "110" then + screen <= "1"; + dw_addr <= "1" & ((Y_VECTOR(9 downto 1) ) & X_VECTOR(9 downto 1)); + if BEAM_ON = '1' and beam_ena_r = '0' and BEAM_ENA = '1' then + if Z_VECTOR(3 downto 0) = "0000" then + vid_data <= "0000"; + vram_wren <= '0'; + else + vid_data <= Z_VECTOR(3 downto 0); + vram_wren <= '1'; + end if; + end if; + end if; + if dcount = "111" then + screen <= "1"; + dw_addr <= "0" & ((Y_VECTOR(9 downto 1) ) & X_VECTOR(9 downto 1)); + if BEAM_ON = '1' and beam_ena_r = '0' and BEAM_ENA = '1' then + if Z_VECTOR(3 downto 0) = "0000" then + vid_data <= "0000"; + vram_wren <= '0'; + else + vid_data <= Z_VECTOR(3 downto 0); + vram_wren <= '1'; + end if; + end if; + end if; + beam_ena_r := beam_ena; + end if; + end process; + + +--video_rgb : work.dpram generic map (19,4) +--port map( +-- clock_a => clk_25, +-- wren_a => vram_wren, +-- address_a => dw_addr(18 downto 0), +-- data_a => vid_data, + +-- clock_b => clk_25, +-- address_b => (screen & up_addr(17 downto 0)), +--); +vram_write_addr <= dw_addr(18 downto 0); +vram_write_data <= vid_data; +vram_read_addr <= screen & up_addr(17 downto 0); +vid_out <= vram_read_data; + + -- job done ! +end architecture RTL; diff --git a/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_ram.vhd b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_ram.vhd new file mode 100644 index 00000000..a60adcb6 --- /dev/null +++ b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_ram.vhd @@ -0,0 +1,99 @@ +-- +-- A simulation model of Lunar Lander hardware +-- James Sweet 2019 +-- This is not endorsed by fpgaarcade, please do not bother MikeJ with support requests +-- +-- Built upon model of Asteroids Deluxe hardware +-- Copyright (c) MikeJ - May 2004 +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- You are responsible for any legal issues arising from your use of this code. +-- +-- The latest version of this file can be found at: www.fpgaarcade.com +-- +-- Email support@fpgaarcade.com +-- +-- Revision list +-- +-- version 001 initial release +-- +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_arith.all; + use ieee.std_logic_unsigned.all; + + +entity LLANDER_RAM is + port ( + ADDR : in std_logic_vector(9 downto 0); + DIN : in std_logic_vector(7 downto 0); + DOUT : out std_logic_vector(7 downto 0); + RW_L : in std_logic; + CS_L : in std_logic; -- used for write enable gate only + ENA : in std_logic; -- ditto + CLK : in std_logic + ); +end; + +architecture RTL of LLANDER_RAM is + + signal we : std_logic; + +begin +r1 : Entity work.gen_ram + generic map( + dWidth => 4, + aWidth => 10) + port map( + clk => clk, + we => we, + addr => ADDR(9 downto 0), + d => DIN(7 downto 4), + q => DOUT(7 downto 4) + ); + +r0 : Entity work.gen_ram + generic map( + dWidth => 4, + aWidth => 10) + port map( + clk => clk, + we => we, + addr => ADDR(9 downto 0), + d => DIN(3 downto 0), + q => DOUT(3 downto 0) + ); + + p_we : process(RW_L, CS_L, ENA) + begin + we <= (not CS_L) and (not RW_L) and ENA; + end process; + +end architecture RTL; diff --git a/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_top.vhd b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_top.vhd new file mode 100644 index 00000000..033c390c --- /dev/null +++ b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_top.vhd @@ -0,0 +1,241 @@ +-- +-- A simulation model of Lunar Lander hardware +-- James Sweet 2019 +-- This is not endorsed by fpgaarcade, please do not bother MikeJ with support requests +-- +-- Built upon model of Asteroids Deluxe hardware +-- Copyright (c) MikeJ - May 2004 +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- You are responsible for any legal issues arising from your use of this code. +-- +-- The latest version of this file can be found at: www.fpgaarcade.com +-- +-- Email support@fpgaarcade.com +-- +-- Revision list +-- +-- version 001 initial release +-- + + -- + -- Notes : + -- + -- Button shorts input to ground when pressed + -- + -- ToDo: + -- Model sound effects for thump-thump, ship and saucer fire and saucer warble + -- Add player control switching and screen flip for cocktail mode + -- General cleanup + + + +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_arith.all; + use ieee.std_logic_unsigned.all; + +entity LLANDER_TOP is + port ( + + ROT_LEFT_L : in std_logic; + ROT_RIGHT_L : in std_logic; + ABORT_L : in std_logic; + GAME_SEL_L : in std_logic; + START_L : in std_logic; + COIN1_L : in std_logic; + COIN2_L : in std_logic; + -- + THRUST : in std_logic_vector(7 downto 0); + -- + DIAG_STEP_L : in std_logic; + SLAM_L : in std_logic; + SELF_TEST_L : in std_logic; + -- + START_SEL_L : out std_logic; + LAMP2 : out std_logic; + LAMP3 : out std_logic; + LAMP4 : out std_logic; + LAMP5 : out std_logic; + + + AUDIO_OUT : out std_logic_vector(7 downto 0); + VIDEO_R_OUT : out std_logic_vector(3 downto 0); + VIDEO_G_OUT : out std_logic_vector(3 downto 0); + VIDEO_B_OUT : out std_logic_vector(3 downto 0); + + HSYNC_OUT : out std_logic; + VSYNC_OUT : out std_logic; + VGA_DE : out std_logic; + VID_HBLANK : out std_logic; + VID_VBLANK : out std_logic; + + DIP : in std_logic_vector(7 downto 0); + + RESET_L : in std_logic; + + -- ref clock in + clk_6 : in std_logic; + clk_25 : in std_logic; + vram_write_addr : out std_logic_vector(18 downto 0); + vram_write_data : out std_logic_vector(3 downto 0); + vram_read_addr : out std_logic_vector(18 downto 0); + vram_read_data : in std_logic_vector(3 downto 0); + vram_wren : out std_logic + ); +end; + +architecture RTL of LLANDER_TOP is + + signal RAM_ADDR_A : std_logic_vector(18 downto 0); + signal RAM_ADDR_B : std_logic_vector(15 downto 0); -- same as above + signal RAM_WE_L : std_logic; + signal RAM_ADV_L : std_logic; + signal RAM_OE_L : std_logic; + signal RAM_DO : std_logic_vector(31 downto 0); + signal RAM_DI : std_logic_vector(31 downto 0); + signal ram_we : std_logic; + + signal reset_dll_h : std_logic; + + signal delay_count : std_logic_vector(7 downto 0) := (others => '0'); + signal reset_6_l : std_logic; + signal reset_6 : std_logic; + + signal clk_cnt : std_logic_vector(2 downto 0) := "000"; + + signal x_vector : std_logic_vector(9 downto 0); + signal y_vector : std_logic_vector(9 downto 0); + signal y_vector_w_offset : std_logic_vector(9 downto 0); + signal z_vector : std_logic_vector(3 downto 0); + signal beam_on : std_logic; + signal beam_ena : std_logic; + + signal ram_addr_int : std_logic_vector(18 downto 0); + signal ram_we_l_int : std_logic; + signal ram_adv_l_int : std_logic; + signal ram_oe_l_int : std_logic; + signal ram_dout_oe_l : std_logic; + signal ram_dout_oe_l_reg : std_logic; + signal ram_dout : std_logic_vector(31 downto 0); + signal ram_dout_reg : std_logic_vector(31 downto 0); + signal ram_din : std_logic_vector(31 downto 0); + +begin + + -- + -- Note about clocks + -- + -- (the original uses a 6.048 MHz clock, so 40 / 6 - slightly slower) + -- + + reset_dll_h <= not RESET_L; + reset_6 <= reset_dll_h; + + p_delay : process(RESET_L, clk_6) + begin + if (RESET_L = '0') then + delay_count <= x"00"; -- longer delay for cpu + reset_6_l <= '0'; + elsif rising_edge(clk_6) then + if (delay_count(7 downto 0) = (x"FF")) then + delay_count <= (x"FF"); + reset_6_l <= '1'; + else + delay_count <= delay_count + "1"; + reset_6_l <= '0'; + end if; + end if; + end process; + + LLander: entity work.llander +port map( + clk_6 => clk_6, + clk_25 => clk_25, + reset_6_l => reset_6_l, + dip => DIP, + rot_left_l => rot_left_l, + rot_right_l => rot_right_l, + abort_l => abort_l, + game_sel_l => game_sel_l, + start_l => start_l, + coin1_l => coin1_l, + coin2_l => coin2_l, + thrust => thrust, + diag_step_l => diag_step_l, + slam_l => '1', --switches(15), + self_test_l =>self_test_l, + start_sel_l => start_sel_l, + lamp2 => lamp2, + lamp3 => lamp3, + lamp4 => lamp4, + lamp5 => lamp5, + coin_ctr => open, + audio_out => AUDIO_OUT, + x_vector => x_vector, + y_vector => y_vector, + z_vector => z_vector, + beam_on => beam_on, + BEAM_ENA => beam_ena + ); + + y_vector_w_offset<= y_vector+100; + + u_DW : entity work.LLANDER_DW + port map ( + RESET => reset_6, + clk_25 => clk_25, + clk_6 => clk_6, + + X_VECTOR => x_vector, + Y_VECTOR => y_vector_w_offset,-- AJS move up y_vector, + Z_VECTOR => z_vector, + + BEAM_ON => beam_on, + BEAM_ENA => beam_ena, + + VIDEO_R_OUT => VIDEO_R_OUT, + VIDEO_G_OUT => VIDEO_G_OUT, + VIDEO_B_OUT => VIDEO_B_OUT, + HSYNC_OUT => HSYNC_OUT, + VSYNC_OUT => VSYNC_OUT, + VID_DE => VGA_DE, + VID_HBLANK => VID_HBLANK, + VID_VBLANK => VID_VBLANK, + + vram_write_addr => vram_write_addr, + vram_write_data => vram_write_data, + vram_read_addr => vram_read_addr, + vram_read_data => vram_read_data, + vram_wren => vram_wren + ); + + +end RTL; diff --git a/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_vg.vhd b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_vg.vhd new file mode 100644 index 00000000..7d7a85ad --- /dev/null +++ b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/llander_vg.vhd @@ -0,0 +1,741 @@ +-- +-- A simulation model of Lunar Lander hardware +-- James Sweet 2019 +-- This is not endorsed by fpgaarcade, please do not bother MikeJ with support requests +-- +-- Built upon model of Asteroids Deluxe hardware +-- Copyright (c) MikeJ - May 2004 +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- You are responsible for any legal issues arising from your use of this code. +-- +-- The latest version of this file can be found at: www.fpgaarcade.com +-- +-- Email support@fpgaarcade.com +-- +-- Revision list +-- +-- version 001 initial release +-- +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_unsigned.all; + use ieee.numeric_std.all; + + +entity LLANDER_VG is + port ( + C_ADDR : in std_logic_vector(15 downto 0); + C_DIN : in std_logic_vector( 7 downto 0); + C_DOUT : out std_logic_vector( 7 downto 0); + C_RW_L : in std_logic; + VMEM_L : in std_logic; + + DMA_GO_L : in std_logic; + DMA_RESET_L : in std_logic; + HALT_OP : out std_logic; + + X_VECTOR : out std_logic_vector(9 downto 0); + Y_VECTOR : out std_logic_vector(9 downto 0); + Z_VECTOR : out std_logic_vector(3 downto 0); + BEAM_ON : out std_logic; + + ENA_1_5M : in std_logic; + ENA_1_5M_E : in std_logic; + RESET_L : in std_logic; + CLK_6 : in std_logic; + Clk_25 : in std_logic + ); +end; + +architecture RTL of LLANDER_VG is + type slv_array12 is array (natural range <>) of std_logic_vector(11 downto 0); + + signal state : std_logic_vector(3 downto 0); + signal next_state : std_logic_vector(3 downto 0); + signal state_halt : std_logic; + -- + signal dma_ld_l : std_logic; + signal dma_ld_l_t1 : std_logic; + signal dma_push_l : std_logic; + signal blank_l : std_logic; + signal latch_l : std_logic_vector(3 downto 0); + signal halt_strobe_l : std_logic; + signal go_strobe_l : std_logic; + -- + signal stop : std_logic; + signal go : std_logic; + signal halt : std_logic; + + signal offset : std_logic_vector(3 downto 0); + signal timer : std_logic_vector(3 downto 0); + signal scale : std_logic_vector(3 downto 0); + signal scale_reg : std_logic_vector(3 downto 0); + signal reg_addr : std_logic_vector(3 downto 0); + signal new_reg_addr : std_logic_vector(3 downto 0); + signal alphanum_l : std_logic; + signal timer_load : std_logic_vector(9 downto 0); + signal timer_counter : std_logic_vector(11 downto 0); + + signal dvx_bus : std_logic_vector(11 downto 0); + signal dvy_bus : std_logic_vector(11 downto 0); + -- + signal xpos_bus : std_logic_vector(11 downto 0); + signal ypos_bus : std_logic_vector(11 downto 0); + + + signal adma_bus : std_logic_vector(12 downto 1); + signal adma0 : std_logic; + signal load_bus : std_logic_vector(12 downto 1); + + signal vram1_l : std_logic; + signal vram2_l : std_logic; + signal vrom1_l : std_logic; + signal vrom2_l : std_logic; + signal vrom3_l : std_logic; + signal vram1_t1_l : std_logic; + signal vram2_t1_l : std_logic; + signal vrom1_t1_l : std_logic; + signal vrom2_t1_l : std_logic; + signal vrom3_t1_l : std_logic; + signal am_bus : std_logic_vector(12 downto 0); + signal vw_l : std_logic; + + -- ratemul + signal ratemul_reg : std_logic_vector(9 downto 0); + signal ratemulx_op : std_logic; + signal ratemulx_reg_and : std_logic_vector(9 downto 0); + signal ratemulx_clock_g : std_logic; + signal ratemulx_rate_out : std_logic_vector(9 downto 0); + -- + signal ratemuly_op : std_logic; + signal ratemuly_reg_and : std_logic_vector(9 downto 0); + signal ratemuly_clock_g : std_logic; + signal ratemuly_rate_out : std_logic_vector(9 downto 0); + -- + signal stack_reg : slv_array12(3 downto 0) := (others => (others => '0')); + signal ram_din : std_logic_vector(7 downto 0); + signal ram_dout_1 : std_logic_vector(7 downto 0); + signal ram_dout_2 : std_logic_vector(7 downto 0); + signal rom_dout_1 : std_logic_vector(7 downto 0); + signal rom_dout_2 : std_logic_vector(7 downto 0); + signal rom_dout_3 : std_logic_vector(7 downto 0); + signal memory_dout : std_logic_vector(7 downto 0); + +begin + + p_halt_go : process(RESET_L, CLK_6) + begin + if (RESET_L = '0') then + halt <= '1'; + go <= '0'; + elsif rising_edge(CLK_6) then + -- slight rejig here from j-k of original + if (DMA_RESET_L = '0') then + halt <= '1'; + elsif (DMA_GO_L = '0') then + halt <= '0'; + elsif (halt_strobe_l = '0') then + halt <= timer(0); + end if; + + if (halt = '1') then + go <= '0'; + elsif (go_strobe_l = '0') then + go <= '1'; + elsif (stop = '1') then + go <= '0'; + end if; + end if; + end process; + HALT_OP <= halt; + -- + -- state machine + -- + p_next_state : process(state, timer, go, halt) + variable go_halt : std_logic; + begin + -- this lot used to be in a rom with + -- + --addr(7) := not( go or halt); + --addr(6) := timer(2) and timer(3); + --addr(5) := timer(1) and timer(3); + --addr(4) := timer(0) and timer(3); + --addr(3 downto 0) := state; + + go_halt := go or halt; + + next_state <= x"0"; + case state is + when x"0" => if (go_halt = '1') then + next_state <= x"0"; + else + next_state <= x"9"; + end if; + + when x"1" => if (go_halt = '1') then + next_state <= x"1"; + else + next_state <= x"2"; + end if; + + when x"2" => next_state <= x"D"; + when x"3" => next_state <= x"D"; + when x"4" => next_state <= x"5"; + when x"5" => next_state <= x"6"; + when x"6" => next_state <= x"7"; + when x"7" => next_state <= x"D"; + + when x"8" => if (timer = x"B") then + next_state <= x"B"; + else + next_state <= x"9"; + end if; + + when x"9" => next_state <= x"D"; + when x"A" => next_state <= x"1"; + + when x"B" => if (timer = x"A") then + next_state <= x"D"; + else + next_state <= x"0"; + end if; + + when x"C" => if (timer = x"B") or (timer = x"C") then + next_state <= x"8"; + elsif (timer = x"D") or (timer = x"E") then + next_state <= x"9"; + elsif (timer = x"F") then + next_state <= x"A"; + else + next_state <= x"F"; + end if; + + when x"D" => next_state <= x"C"; + + when x"E" => if (timer = x"A") then + next_state <= x"B"; + else + next_state <= x"A"; + end if; + + when x"F" => next_state <= x"E"; + when others => null; + end case; + end process; + + p_state_machine : process(RESET_L, CLK_6) + begin + if (RESET_L = '0') then + state <= "0000"; + state_halt <= '0'; + elsif rising_edge(CLK_6) then + + if (DMA_RESET_L = '0') then + state <= "0000"; + state_halt <= '0'; + elsif (ENA_1_5M = '1') then + if (vmem_l = '1') or (state(2) = '0') then + state <= next_state; + state_halt <= halt; + end if; + end if; + end if; + end process; + + p_state_decode : process(state, state_halt, vmem_l, ENA_1_5M_E) + variable dec : std_logic_vector(7 downto 0); + begin + dec := "11111111"; + -- if start(2) is low, ignore vmem_l + if (state(3) = '1') and ((vmem_l = '1') or (state(2) = '0')) and (ENA_1_5M_E = '1') then + case state(2 downto 0) is + when "000" => dec := "11111110"; + when "001" => dec := "11111101"; + when "010" => dec := "11111011"; + when "011" => dec := "11110111"; + when "100" => dec := "11101111"; + when "101" => dec := "11011111"; + when "110" => dec := "10111111"; + when "111" => dec := "01111111"; + when others => null; + end case; + end if; + adma0 <= state(0); + blank_l <= not (state(3) or state_halt); + + -- following stobes are used on ena_1_5 early, so must not be clock enables on ena_1_5. + latch_l(3) <= dec(7); + latch_l(2) <= dec(6); + latch_l(1) <= dec(5); + latch_l(0) <= dec(4); + halt_strobe_l <= dec(3); + go_strobe_l <= dec(2); + dma_ld_l <= dec(1); + dma_push_l <= dec(0); + end process; + -- + -- Program counter / stack + -- + p_dmald : process(timer, CLK_6) + begin + if (timer(0) = '0') then + dma_ld_l_t1 <= '0'; + elsif rising_edge(CLK_6) then + dma_ld_l_t1 <= dma_ld_l; + end if; + end process; + + p_regaddr_calc : process(timer, reg_addr, dma_ld_l, dma_ld_l_t1, dma_push_l) + variable offset : std_logic_vector(3 downto 0); + begin + -- we need the address early + + -- dma_push_l = '0' => store, then inc + -- dma_ld dec, then load pc from stack + if (timer(0) = '1') then -- down + offset := "1111"; + else + offset := "0001"; + end if; + + if ((dma_ld_l = '0') and (dma_ld_l_t1 = '1')) or (dma_push_l = '0') then + new_reg_addr <= reg_addr + offset; + else + new_reg_addr <= reg_addr; + end if; + end process; + + p_regaddr : process + begin + wait until rising_edge(CLK_6); + + if (DMA_GO_L = '0') then -- reset not in original + reg_addr <= "0000"; + else + reg_addr <= new_reg_addr ; + end if; + end process; + + p_reg_write : process + begin + wait until rising_edge(CLK_6); + if (dma_push_l = '0') then + case reg_addr(1 downto 0) is + when "00" => stack_reg(0) <= adma_bus; + when "01" => stack_reg(1) <= adma_bus; + when "10" => stack_reg(2) <= adma_bus; + when "11" => stack_reg(3) <= adma_bus; + when others => null; + end case; + end if; + end process; + + p_reg_read : process(timer(0), new_reg_addr, dvy_bus, stack_reg) + begin + if (timer(0) = '1') then -- load + load_bus <= stack_reg(0); -- default + case new_reg_addr(1 downto 0) is + when "00" => load_bus <= stack_reg(0); + when "01" => load_bus <= stack_reg(1); + when "10" => load_bus <= stack_reg(2); + when "11" => load_bus <= stack_reg(3); + when others => null; + end case; + else + load_bus <= dvy_bus; + end if; + end process; + + p_pc : process + begin + wait until rising_edge(CLK_6); + if (dma_ld_l = '0') then + adma_bus <= load_bus; + else + if (latch_l(0) = '0') or (latch_l(2) = '0') then + adma_bus <= adma_bus + "1"; + end if; + end if; + end process; + -- + -- address decoder + -- + p_addr_sel : process(VMEM_L, adma_bus, adma0, C_ADDR, C_RW_L) + begin + if (VMEM_L = '0') then + am_bus <= C_ADDR(12 downto 0); + vw_l <= C_RW_L; + else + am_bus <= adma_bus & adma0; + vw_l <= '1'; + end if; + end process; + + p_am_decode : process(am_bus) + begin + vram1_l <= '1'; + vram2_l <= '1'; + vrom1_l <= '1'; + vrom2_l <= '1'; + vrom3_l <= '1'; + case am_bus(12 downto 10) is + when "000" => vram1_l <= '0'; + when "001" => vram2_l <= '0'; + when "010" => vrom1_l <= '0'; + when "011" => vrom1_l <= '0'; + when "100" => vrom2_l <= '0'; + when "101" => vrom2_l <= '0'; + when "110" => vrom3_l <= '0'; -- AJS? + when "111" => vrom3_l <= '0'; + + when others => null; + end case; + end process; + + p_am_reg : process + begin + wait until rising_edge(CLK_6); + vram1_t1_l <= vram1_l; + vram2_t1_l <= vram2_l; + vrom1_t1_l <= vrom1_l; + vrom2_t1_l <= vrom2_l; + vrom3_t1_l <= vrom3_l; + end process; + + -- only cpu can write to vector ram + ram_din <= C_DIN; + C_DOUT <= memory_dout; + + -- vector memory + u_vector_ram_1 : entity work.LLANDER_RAM + port map ( + ADDR => am_bus(9 downto 0), + DIN => ram_din, + DOUT => ram_dout_1, + RW_L => vw_l, + CS_L => vram1_l, + ENA => ena_1_5M, + CLK => CLK_6 + ); + + u_vector_ram_2 : entity work.LLANDER_RAM + port map ( + ADDR => am_bus(9 downto 0), + DIN => ram_din, + DOUT => ram_dout_2, + RW_L => vw_l, + CS_L => vram2_l, + ENA => ena_1_5M, + CLK => CLK_6 + ); + +u_vector_rom_0 : entity work.LLANDER_VEC_ROM_0 + port map ( + addr => am_bus(10 downto 0), + data => rom_dout_1, + clk => CLK_6 + ); + +u_vector_rom_1 : entity work.LLANDER_VEC_ROM_1 + port map ( + addr => am_bus(10 downto 0), + data => rom_dout_2, + clk => CLK_6 + ); + +u_vector_rom_2 : entity work.LLANDER_VEC_ROM_2 + port map ( + addr => am_bus(10 downto 0), + data => rom_dout_3, + clk => CLK_6 + ); + + p_memory_data_mux : process(vram1_t1_l, vram2_t1_l, vrom1_t1_l, vrom2_t1_l, vrom3_t1_l,ram_dout_1, ram_dout_2, rom_dout_1, rom_dout_2,rom_dout_3) + begin + -- cpu buffer enabled when VMEM_L = 0 + memory_dout <= (others => '0'); + if (vram1_t1_l = '0') then + memory_dout <= ram_dout_1; + elsif (vram2_t1_l = '0') then + memory_dout <= ram_dout_2; + elsif (vrom1_t1_l = '0') then + memory_dout <= rom_dout_1; -- AJS?? + elsif (vrom2_t1_l = '0') then + memory_dout <= rom_dout_2; -- AJS?? + elsif (vrom3_t1_l = '0') then + memory_dout <= rom_dout_3; -- AJS?? + else + memory_dout <= (others => 'X'); + end if; + end process; + -- + -- data memory latches + -- + p_latch : process + begin + wait until rising_edge(CLK_6); + -- latch3 + if ((alphanum_l = '0') and (latch_l(0) = '0')) or (latch_l(3) ='0') then + scale <= memory_dout(7 downto 4); + dvx_bus(11 downto 8) <= memory_dout(3 downto 0); + end if; + + -- latch2 + if (alphanum_l = '0') then + dvx_bus(7 downto 0) <= x"00"; + elsif (latch_l(2) = '0') then + dvx_bus(7 downto 0) <= memory_dout(7 downto 0); + end if; + + -- we know we have a sync reset + -- latch1 + if (DMA_RESET_L = '0') or (RESET_L = '0') or (dma_go_l = '0') then + timer <= x"0"; + dvy_bus(11 downto 8) <= x"0"; + elsif (latch_l(1) = '0') then + timer <= memory_dout(7 downto 4); + dvy_bus(11 downto 8) <= memory_dout(3 downto 0); + end if; + + -- latch0 + if (DMA_RESET_L = '0') or (RESET_L = '0') or (dma_go_l = '0') or (alphanum_l = '0') then + dvy_bus(7 downto 0) <= x"00"; + elsif (latch_l(0) = '0') then + dvy_bus(7 downto 0) <= memory_dout(7 downto 0); + end if; + end process; + + -- + -- vector timer + -- + p_scale_reg : process + begin + wait until rising_edge(CLK_6); + if (latch_l(2) = '0') and (timer(3) = '1') and (timer(1) = '1') then + scale_reg <= scale; + end if; + end process; + + p_vector_timer : process(timer, dvx_bus, dvy_bus, scale_reg) + variable sel : std_logic; + variable mux : std_logic_vector(3 downto 0); + variable add : std_logic_vector(3 downto 0); + variable dec : std_logic_vector(9 downto 0); + begin + sel := '1'; + if (timer = "1111") then + sel := '0'; + end if; + alphanum_l <= sel; + + if (sel = '0') then + mux := '0' & dvx_bus(11) & not dvx_bus(11) & dvy_bus(11); + else + mux := timer; + end if; + + + add := scale_reg + mux; + + timer_load <= "1111111111"; + case add is + when "0000" => timer_load <= "1111111110"; + when "0001" => timer_load <= "1111111101"; + when "0010" => timer_load <= "1111111011"; + when "0011" => timer_load <= "1111110111"; + when "0100" => timer_load <= "1111101111"; + when "0101" => timer_load <= "1111011111"; + when "0110" => timer_load <= "1110111111"; + when "0111" => timer_load <= "1101111111"; + when "1000" => timer_load <= "1011111111"; + when "1001" => timer_load <= "0111111111"; + when others => timer_load <= "1111111111"; + end case; + + end process; + + p_vector_timer_counter : process + begin + wait until rising_edge(CLK_6); + if (go = '0') then + timer_counter <= "1" & timer_load & '1'; + elsif (ENA_1_5M = '1') then + timer_counter <= timer_counter + "1"; + end if; + + end process; + + p_stop : process(timer_counter) + begin + stop <= '0'; + if (timer_counter = x"FFF") then + stop <= '1'; + end if; + end process; + + -- + -- Rate Multipliers + -- vgck is 1.5Mhz clock + -- + p_ratemul_reg : process(go, CLK_6) + begin + -- share a reg here + if (go = '0') then + ratemul_reg <= (others => '0'); + elsif rising_edge(CLK_6) then + if (ENA_1_5M = '1') then + ratemul_reg <= ratemul_reg + "1"; + end if; + end if; + end process; + + p_ratemulx_and : process(ratemul_reg, ratemulx_reg_and) + begin + ratemulx_reg_and(0) <= ratemul_reg(0); + for i in 1 to 9 loop + ratemulx_reg_and(i) <= ratemul_reg(i) and ratemulx_reg_and(i-1); + end loop; + end process; + + p_ratemuly_and : process(ratemul_reg, ratemuly_reg_and) + begin + ratemuly_reg_and(0) <= ratemul_reg(0); + for i in 1 to 9 loop + ratemuly_reg_and(i) <= ratemul_reg(i) and ratemuly_reg_and(i-1); + end loop; + end process; + + p_ratemulx_rate : process(ratemulx_reg_and, ratemul_reg, dvx_bus) + begin + ratemulx_rate_out(0) <= (not ratemul_reg(0)) and dvx_bus(9); + for i in 1 to 9 loop + ratemulx_rate_out(i) <= (not ratemul_reg(i)) and ratemulx_reg_and(i-1) and dvx_bus(9-i); + end loop; + end process; + + p_ratemuly_rate : process(ratemuly_reg_and, ratemul_reg, dvy_bus) + begin + ratemuly_rate_out(0) <= (not ratemul_reg(0)) and dvy_bus(9); + for i in 1 to 9 loop + ratemuly_rate_out(i) <= (not ratemul_reg(i)) and ratemuly_reg_and(i-1) and dvy_bus(9-i); + end loop; + end process; + + p_ratemul_op : process + begin + wait until rising_edge(CLK_6); + -- we can afford a register here as the enables are every 4 clocks + if (go = '0') then -- clear + ratemulx_op <= '0'; + ratemuly_op <= '0'; + else + ratemulx_op <= '1'; + if (ratemulx_rate_out = "0000000000") then + ratemulx_op <= '0'; + end if; + + ratemuly_op <= '1'; + if (ratemuly_rate_out = "0000000000") then + ratemuly_op <= '0'; + end if; + end if; + end process; + -- + -- x/y position counter + -- + p_x_pos : process + begin + wait until rising_edge(CLK_6); + if (timer(0) = '0') and (halt_strobe_l = '0') then + xpos_bus <= dvx_bus(11 downto 0); + elsif (ENA_1_5M = '1') and (go = '1') and (ratemulx_op = '1') then + if (dvx_bus(10) = '0') then + xpos_bus <= xpos_bus + "1"; + else + xpos_bus <= xpos_bus - "1"; + end if; + end if; + end process; + + p_y_pos : process + begin + wait until rising_edge(CLK_6); + if (timer(0) = '0') and (halt_strobe_l = '0') then + ypos_bus <= dvy_bus(11 downto 0); + elsif (ENA_1_5M = '1') and (go = '1') and (ratemuly_op = '1') then + if (dvy_bus(10) = '0') then + ypos_bus <= ypos_bus + "1"; + else + ypos_bus <= ypos_bus - "1"; + end if; + end if; + end process; + -- + -- output stages + -- + p_output : process(RESET_L, CLK_6) + begin + if (RESET_L = '0') then + X_VECTOR <= "1000000000"; + Y_VECTOR <= "1000000000"; + Z_VECTOR <= "0000"; + BEAM_ON <= '0'; + elsif rising_edge(CLK_6) then + -- clamp beam at edges + if (xpos_bus(10) = '0') then + X_VECTOR <= xpos_bus(9 downto 0); + else + for i in 0 to 9 loop + X_VECTOR(i) <= not xpos_bus(11); + end loop; + end if; + + if (ypos_bus(10) = '0') then + Y_VECTOR <= ypos_bus(9 downto 0); + else + for i in 0 to 9 loop + Y_VECTOR(i) <= not ypos_bus(11); + end loop; + end if; + + BEAM_ON <= '0'; + Z_VECTOR <= "0000"; + if (xpos_bus(11 downto 10) = "00") and + (ypos_bus(11 downto 10) = "00") then + BEAM_ON <= '1'; + if (blank_l = '1') then + Z_VECTOR <= scale; + end if; + end if; + end if; + end process; + +end architecture RTL; diff --git a/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/ovo.vhd b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/ovo.vhd new file mode 100644 index 00000000..6b2c340e --- /dev/null +++ b/Arcade_MiST/Atari Vector/LunarLander_MiST/rtl/ovo.vhd @@ -0,0 +1,180 @@ +-------------------------------------------------------------------------------- +-- Overlay +-------------------------------------------------------------------------------- +-- DO 10/2017 +-------------------------------------------------------------------------------- + +-------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +LIBRARY work; +USE work.base_pack.ALL; + +ENTITY ovo IS + GENERIC ( + COLS : natural :=32; + LINES : natural :=2; + RGB : unsigned(23 DOWNTO 0) :=x"FFFFFF"); + PORT ( + -- VGA IN + i_r : IN uv8; + i_g : IN uv8; + i_b : IN uv8; + i_hs : IN std_logic; + i_vs : IN std_logic; + i_de : IN std_logic; + i_en : IN std_logic; + i_clk : IN std_logic; + + -- VGA_OUT + o_r : OUT uv8; + o_g : OUT uv8; + o_b : OUT uv8; + o_hs : OUT std_logic; + o_vs : OUT std_logic; + o_de : OUT std_logic; + + -- Control + ena : IN std_logic; -- Overlay ON/OFF + + -- Probes + in0 : IN unsigned(0 TO COLS*5-1); + in1 : IN unsigned(0 TO COLS*5-1) + ); +END ENTITY ovo; + +--############################################################################## + +ARCHITECTURE rtl OF ovo IS + TYPE arr_slv8 IS ARRAY (natural RANGE <>) OF uv8; + CONSTANT chars : arr_slv8 :=( + x"3E", x"63", x"73", x"7B", x"6F", x"67", x"3E", x"00", -- 0 + x"0C", x"0E", x"0C", x"0C", x"0C", x"0C", x"3F", x"00", -- 1 + x"1E", x"33", x"30", x"1C", x"06", x"33", x"3F", x"00", -- 2 + x"1E", x"33", x"30", x"1C", x"30", x"33", x"1E", x"00", -- 3 + x"38", x"3C", x"36", x"33", x"7F", x"30", x"78", x"00", -- 4 + x"3F", x"03", x"1F", x"30", x"30", x"33", x"1E", x"00", -- 5 + x"1C", x"06", x"03", x"1F", x"33", x"33", x"1E", x"00", -- 6 + x"3F", x"33", x"30", x"18", x"0C", x"0C", x"0C", x"00", -- 7 + x"1E", x"33", x"33", x"1E", x"33", x"33", x"1E", x"00", -- 8 + x"1E", x"33", x"33", x"3E", x"30", x"18", x"0E", x"00", -- 9 + x"0C", x"1E", x"33", x"33", x"3F", x"33", x"33", x"00", -- A + x"3F", x"66", x"66", x"3E", x"66", x"66", x"3F", x"00", -- B + x"3C", x"66", x"03", x"03", x"03", x"66", x"3C", x"00", -- C + x"1F", x"36", x"66", x"66", x"66", x"36", x"1F", x"00", -- D + x"7F", x"46", x"16", x"1E", x"16", x"46", x"7F", x"00", -- E + x"7F", x"46", x"16", x"1E", x"16", x"06", x"0F", x"00", -- F + x"00", x"00", x"00", x"00", x"00", x"00", x"00", x"00", --' ' 10 + x"00", x"00", x"3F", x"00", x"00", x"3F", x"00", x"00", -- = 11 + x"00", x"0C", x"0C", x"3F", x"0C", x"0C", x"00", x"00", -- + 12 + x"00", x"00", x"00", x"3F", x"00", x"00", x"00", x"00", -- - 13 + x"18", x"0C", x"06", x"03", x"06", x"0C", x"18", x"00", -- < 14 + x"06", x"0C", x"18", x"30", x"18", x"0C", x"06", x"00", -- > 15 + x"08", x"1C", x"36", x"63", x"41", x"00", x"00", x"00", -- ^ 16 + x"08", x"1C", x"36", x"63", x"41", x"00", x"00", x"00", -- v 17 + x"18", x"0C", x"06", x"06", x"06", x"0C", x"18", x"00", -- ( 18 + x"06", x"0C", x"18", x"18", x"18", x"0C", x"06", x"00", -- ) 19 + x"00", x"0C", x"0C", x"00", x"00", x"0C", x"0C", x"00", -- : 1A + x"00", x"00", x"00", x"00", x"00", x"0C", x"0C", x"00", -- . 1B + x"00", x"00", x"00", x"00", x"00", x"0C", x"0C", x"06", -- , 1C + x"1E", x"33", x"30", x"18", x"0C", x"00", x"0C", x"00", -- ? 1D + x"18", x"18", x"18", x"00", x"18", x"18", x"18", x"00", -- | 1E + x"36", x"36", x"7F", x"36", x"7F", x"36", x"36", x"00"); -- # 1F + + SIGNAL vcpt,hcpt,hcpt2 : natural RANGE 0 TO 4095; + SIGNAL vin0,vin1 : unsigned(0 TO COLS*5-1); + + SIGNAL t_r,t_g,t_b : uv8; + SIGNAL t_hs,t_vs,t_de : std_logic; + + SIGNAL col : uv8; + SIGNAL de : std_logic; + + SIGNAL in0s,in1s : unsigned(in0'range); +BEGIN + + in0s<=in0 WHEN rising_edge(i_clk); + in1s<=in1 WHEN rising_edge(i_clk); + + ---------------------------------------------------------- + Megamix:PROCESS(i_clk) IS + VARIABLE vin_v : unsigned(0 TO COLS*5-1); + VARIABLE char_v : unsigned(4 DOWNTO 0); + BEGIN + IF rising_edge(i_clk) THEN + IF i_en='1' THEN + ---------------------------------- + -- Propagate VGA signals. 2 cycles delay + t_r<=i_r; + t_g<=i_g; + t_b<=i_b; + t_hs<=i_hs; + t_vs<=i_vs; + t_de<=i_de; + + o_r<=t_r; + o_g<=t_g; + o_b<=t_b; + o_hs<=t_hs; + o_vs<=t_vs; + o_de<=t_de; + + ---------------------------------- + -- Latch sampled values during vertical sync + IF i_vs='1' THEN + vin0<=in0s; + vin1<=in1s; + END IF; + + ---------------------------------- + IF i_vs='1' THEN + vcpt<=0; + de<='0'; + ELSIF i_hs='1' AND t_hs='0' AND de='1' THEN + vcpt<=(vcpt+1) MOD 4096; + END IF; + + ---------------------------------- + IF (vcpt/8) MOD 2=0 THEN + vin_v:=vin0; + ELSE + vin_v:=vin1; + END IF; + + IF i_hs='1' THEN + hcpt<=0; + ELSIF i_de='1' THEN + hcpt<=(hcpt+1) MOD 4096; + de<='1'; + END IF; + hcpt2<=hcpt; + + ---------------------------------- + -- Pick characters + IF hcpt8T>~a2mx}Loor&^Vn&yV?Kt^j-nKp1?$VsKt;8R7*&f`@oP z(A+1YB>=>CW{;FlKsm`dxjVmng8wxDn%e|P9-WCdZ2(Gt6hL_L00E$Ux=+_6$LE8M z0J@*6LqZRo8DLc%Qu81SpsZpYl5$k%QNS($-6DFbb@+2YbGrFD$xqG+9sK~p*(`t5 zXSz@43_u4^e+eirfjB2V5*?IE&eUg0)0y%KC{1|@P+meu(jMI-{0Tdfwwli*3q%(| zQlIYA7*c)8`zwGH1{|o*Nx9^l@S*u$v&;}}iOkVCfrKvNS2CBWZK^v1p!_Mo#{kCx z{~bX21k_fXnmtn9a{xM1ZbBcOw*jm=P#eua*>wF`KpD^pAlj(T2|$uh_vrfX>pt$Ab& znE;Zl`{l$QWqQ`>g{h#neulE>!$&rh$eLy}K@ zxDl`hK({^#plfP_bQ?i)I?l=GzXSLeKyr`TA8UecfZYT{W7DPmhk*M5y#UIm@{~vX zARvCw`HKMJ9r23tXr53$0rj8grF;U)BYq@vn8usrF`2h?rnZ{Tp8yaYlt=Jx0Lei@ z-{$}{f2p6;9s#9^o&=IS$|s;};zu(i{Un+aAX*Zjb_kMdVkPlcX5#Q?0J={2o}}Xz zXODEhSyr2Apfrtp(mtJ&_L96k0BSSIr*R{k2_1B%>kC0bLvl{$N^(xxTj-p$m)s}X zsn1D1@q=ifyaX;p6WveRPtHFKNag~aX^l6Rio2bWQ7iGfi}lt`i`=pXe0IBYC7e zYK!v!2taf_0HAyV%A>XuSP!_i3Fx|+4r=pW0L?#26VQ4@{8$Jc2kZrqv{D&rH_4-X z!uJS(>=6QD36XGl3uw+K8VHC613+}11{|nE2|(*`0(37))A?(4n4ec4lK0a15M0>= zO{{4oiFSe{gXkdnm&D;fGMmf?I?vA9)+us+yZ|8CPk?A@BBN!J#+86>5-n7R@Wj+T z@(A&Mev8fYketrHPuB?zq+bb$uOyE&?y>fakEH8p4eSDt9Z$KGN4oi4fc83&j{OMW z8vx3ub%*E}slz(~lq5Y%`6Rz&KPGe#e<_{J7ZQ_X{!*Jn7uiFJ{hZiG+X2S_9|zFh zhIAfX|4#s&{}u3cz&`@M450Z#knn``2+@?ZPxy!q;zctgc|;2V@tvTVUu1vKxO^Hw zV@B5mlt(rYVS6k~spRhvve60yNuaL?h8b`i;(s&Y&@B zri1dS{e%wESGxhEGbrzQ09_M&2|zTEKBF@v!u`Lqr|_maG1&7^$N1!P;$nb!F003;{LdQbC|(nJ&G|1N;$ zX~GMVC7KI|0VHQM?#bMsGXc$$I5m4Dxg{Nx+#@_hLjp8@)LsI_k0ecJ8n+(>By=Tt zv_~VLzSH?r0FpJ5FUli*LHPufro03wkH&?7=%GH6{haKx=}conkmS7{Kt7Q;_wvhW zJZ}O}9s!LxU6Z~deMUg(p8>>I@iEaQbf$5l_M3s)p*9n~(>bAm&LlqsNgnm#uK_X> z2cmy@WU-kB(x(JT9`Ta&XPlc#5kCkg%@4{apmr&* z87MCS%8x0SJ<^;_^aq`j_U50-w?cZnIiK1lXq89#NxPI@3N+(;CH)EqUg5wi99S#| zNXL<0ol`y}6U>YKsTn%)j5?KbKbfv)r7Vi@Lb$4VPS0{pQNGpWNDf z8K?QVS+hCeIX$1f_f#~;R-L`Ej1*DkELabtV5K}wnxu0It<~%~*RvN_eEQYi!n89* z(OVCzwLqoXGrzSUfxy-e@~%?PA#u{T)N_R=rjjXFY(`@t7HuCnlfL2Nl)+_^X;Lx< z*%!29LcBs1v{SZclXO}*SS1aWOBvOMv^t8dJo437#}%875NX^7l7%2lnYz4Zr9hU| znQ9_HdHmVe(cM96@@jwMJ)OX%yaCj5rgRrNQ$u`;D=3i@j!1Q+JY$3kc)AKt38m|@^Cqrzbf%Q491!atEji*!JEfNjSE=2q;*B_+Q$Uf^YJc%fVm-

d2>QtTiok*fRk{87Wy9^LepRQEBWRb`eoDkWpGgNC2|08l&2pV(M zqekaIM&lVx2a)U?dB_wBT4&67RB7fpDU)CSn>l#qTwq?1K+MUbi%>M$4>3Ybz)t?6 zd~nv3b)jU&*8K*$d4+55$kuZ(Ko<+OtAFwWC>(`GcP`B9VB==($B#DB=O!RH=Yn-E zCzC=C99)nG@lpYiTRc4Qk=M59iL4K)r8&A3cGmu7SF5ID8Pr*F?;JUqZKF{}mi_eR zq{{rWB+g=Uq(RO}6ome1z#L}WRatNWV{-6j>1ZIBlaQ?@Ikj6KNRqSXIql76Uocg> z_H7p|v*-ei$=_7tJQ5{KS#wy~RPp3NExx)Ca~gFp+zXWDO6@!Q>g8zu_>DTP6SmA= z02v8qZTwrUYM!Iml7S1Um!_2Xgdub0U+whIw8AItu=zLURGfcPp_XdD_Alq;FFT{v zpaNN;6~cxJZ*^17k9&XOHOaj>g{2q}`;eIBA{N#}*}SI){>;Ww?X)9FW8hkV)|_owsmsOVuz$=cZ6V860fQ`U50(LbkHqI+P&sJ`r|I=?@kmHLk@I9^oAQ_6>_ChX{x>(2^@kM0T{zO_QSiwBV zV!ZXMOCoKqE++Gl-+w(V8W)MBW%bKnuV3B&MyI>;iQdD^w&{4~QE{t#m~|d4-sRrk zuHSgJXy4NL#2sHec2GyzpYG{?hMm2e>dZUaYs9U6-?P1)qATVQHPWT=Px4`Jy>})8nr#HD50x?JiiRcC^I?Mpc)loUHkN|l@&8ZvCg0-9*$bNGwQD}S(9kVCe+8w`P#$Q1^~H~Ky$>s{QkKq}1!{a3v_SZZ{as(z zUa`Md-u@=(Y7GmT+AWLM{`q&$t1ns0S}im2xGH6~r zc{VpnVE>BAn6eyy&O+3IW#?T^7OK}W|KtOt`u{H&-@p2?mhCSq zbERj-N{#am)|0fBe&CDDgohduL59~wc+gu`hg+Q#P0M>1nQ2_t_KNd+<(%K%nZN(p zC98!w@d(YeYajh;SX!wE@0l~(ztD{Q;?huKvDLN=G?-^|p|<^tt@i|Ti(T+44v6~{ z1)r5#6mF#|&!MHMp0ri3Ka8gtE460rEi4$1)zt26vTnDQ;y_cVfI0Bs+E>lFUfcyV ziQl4R?LEg^Iu_exsdKUgc~LL6OM{!#_weArji{Qg0T zJ!z!}&&TKm?s=)~Q=3!JvZ;k69eesV&!DYR2ZXK8K2WZCNzwD=w@#Ez{k3IZuCNMIvfrtY3KxwNRkL zMFRTvtE0dnS#nXhKpB2({I12Lf`)I5eap6MeE;IHwZzbrS$ivWbkVRNWo{glf5p9v zMs>lFs$DOq*5VPKuOw|EOHn*I&2y&I`D)I;7vejSn08OSO@8id{@rC=*OiET`E6MU znk&_Q>(S=R<)=xt)P8AT`3UCM#2A=XJOp?xaQ@vTUAq{8+5>;Fq&nvo^VavjrUMj$ z%&9EGz&lobSK`A%u)|hvduy87f`NpSOr3|o^WU-#+N8N2|C{uG=}gzxw)5Axz+FPv z4J!Bk>t!9C=>_%W1+X;VcDuo0+e_X1rFgNN%3kEcg#J$1O6__hc3lA^CN>y|HS>QyPb6U$c~Jp_y+WbmE_Gdb;TK;`eWoe3;turt#u{|nD@V7bf)Qta z{zt5D7Jjhf$6tJEn1mu04S8PX!G>iPs>Uz<@-pkUsD?$PB(tGa7Y8(~fR<_^`|@YC z!s5_epcJ)Idu#oDUlRI7K^W6!k{xgkJo2emuZSNVq}ht{$cI#VmGy(X;3>6?+q5JbPhAmV{HtcV+4lDcx% z2i`C}xpAd>iLd6opf3+ui_uqcwW3&yo~{qxc(Sg6JdTYn2Rv-JE| z2wN)8Ug6mPUmTNf%HR6Kq+Wm)z0}X$vpgbN)mlNq zR_dLnn9P{4?~-*)O?>~E^sgA+tt5DPdGq9c5f*(*H+9^2?N_7aQPHAS=FGbmsduco zzU!k2@dVgCAX~&$!WYr)$UkMnHN#`3a$V8*iL268z(Th=Q-3pRv# z`Mpcoq7>?aU2D3LdE#?vTz(%}-bDOL>&%rJ=pU>XQNI7|V~F~9W54jqtDA!>`Q4Ni z*W-)TmTr?`q_~T7A#>(;H=LV0H>VyLGB>j&Hs$e`TAIsqtIDfIIMi>wT5VBru~~Ea zjt{rpvfTLHd5Ea}xBd8HshC$T?)6;Wz5MNE1;YT93}u|x!lpatWi0NJqNC0&`5(v5 z&0B8HMJ#dWl6KS2#ZPLML5!u!*mWEbwONPS7eta=+Sv{3IB>RXwN9u}d$MC`c+OXP zxs0Q3Ht1_KQ0pIQq?eJP9@cwFwSW3u%fKP4*m1>XxvM?(iREHTkj>Vw{g1cKUR-3# zJM)Q)_dmvOOb{iX+Pyq_Trl1aN#GDN>$*79nP}{NV0p1&^|1_9tDuJXU)>49TIWN{ zBav#6z9dSKki_EKTvxo00yq8KMo=bI*yySz#SLXmKPt^zOh0iZD!jJ;*8$%9+F@0X@kIJa| z2AX2cZ6yhDdHGA!{gtq)iSD%yIGcO|z4qP}{DwJj!`7M+F~hwxH~z%;bC}9?6kxMv z`c|Crn(4RhKi^xb3%=;NW!Lf~*LIViSausnU5Aso z58=H4Boiqq2Jvqw)HpBm&_|L8ht}vile)>dnJ{TQ+R2?v8mTR2!oTLPW+X-Cp6AhW z4iBI>Keumgl@?djKFz>*hRd~s`Yp{CIp1+p(kL(7o3crVTi{BvsHknJ(3J{SOt%TY zn=~UACW%t1ef5^4;(}+1gH~Ru5~@H@`@)fD_T40N_AOaTEr~_e&AxTMmaaMrQ`Cn_oxldD)@^o&( z)Rdg1Eh*c$S$luW#}P@n`ngU*qgLbgyqwxczSy|6a3by)s@BIiE-Bln_nC%*p!QqU zIC1_XsuCfD0cTW>(bSJ5lysW_Z)g4aVq&PMJZvjMN%JkCN8*^3MtQjo{tMSwtm-6HW5Fu=E4}2$t#7*KS+B?;lMW|> z>|Ia1-b=Us$V(=TEqSXQ!<4<-_FPrby9=pqHS47m`~#vljnRK5S~m^!54)&I98M zBTnuBF9rffFfGm_#4!@tro;xUvll2<8+qRaU#AB}vFt#WPz5c-h-n)^)S}shQrrQ4 zIs(3!mZ$R`fB`sMLP;P`$e;uvm#KO}UfuQXMQj03fe4lLu&PQ2Ky0$jOwA=FRzy!!6e#I|a|OS{xtY=W9P z0CvqM(zWFVhUmHVk6+z>>TQSFvxVEuQ*SxU#tOUG&%suI%jrOVQsynEN9mg~+oL`5 zqcZKMe}(?9QTyrZ{Ffv8H%%Y&2jkx0 zdds293SiXvp;-v!?2NU$)Vdgp0@Nt20ChE~-1e14XyMrwo3NK=bCc9DR{}o#iBzN~@{L1J5tUxlSl)WwBH_(Q#SAA8^qsJ0IniEsHSq2_w-Z z0gD*@yKI6+UVMpT?X9sFC;lJXp4PZAFJTk&XgbJ~#Dn3W5y9ey6YhXFlpi-$+q}Pl zVc~G8I>LE`QBxq5u%SI1Wk&6XBZ)EI((wlNxrunOmRv){q%LI1wn3<5rc1oW0mvo6 zit_l&=cwVSPGWrwat}yqjWPn67axgAnT6C!0^a|3=nSdFrECO3+lJVTvcXlzK=DKW#FFd!MqKGd<)iIYgK zkN*Qu>m7G9js^vdOd6PZP`mtcTFJxIy!-_&8})%a9@K*}MfbO{qJ`1gvoTaFqL8m%5<9j$ha&#^$nu<1(4MZ_5*8CdrM3co|zG^W$&N^n$ z(!{o;IkX0S5JPSAos_UHEO}G|e^4gztVnhXF&@_{Kg%`w1BuWf1`g5AMY1bj|;ae!1MirPdt+p5O=AhL- zJ?+-hV#-!J4%(*Dt)~nn^lkC5eJLze{8Q9Jz>kedsi01E!aQ@cUIati@!dE13Z72P z2-s@acfjsG^Z13mYjvX+imvKbH?C^$`|EQ$eoh9;(R^48 z>d=nI01ZF>!s{+Pv=TL$?lOUmb+ zKWv>S8(oO=sV_0qer`}0X zKuUSgu5Thp_?5f9MqBLGIG50Tb5U$48(W1(PQPYJdy#sdK~dw4;|3$@nX|}m{oLzc z*@w(-tCqVD0bk>N2KE}*cGz=%VDip-a1_kfL>bVutG)4Bs=O$$FI4L3k87m`%h2qe zhd~lTCTTMBX(GkCy*`nq{$xRXq%&qAzK};$O>Wh(G?w(*Z(cuJr9~>K7vI8_B)E|q zufz?cFf^hs)v+XIB#AnG3tm=??L-U4dpK5z$%;`(okt@kH&Iv=WXF*kuj(j@#j@`K z!cB;+WNptlAjzVBTRJraK-qeCJq?K%1x8$!q5|0LNTMhWsQs;EK|(KbaF>b`B1(r6 zJyd)zk%v52;g*U5bODc|3*C?FI?=8ou*Op{9FYA&-|Tj;L7GLYkL7FB0>H)}+OrB{ z1q&Z#qz*w6NOa>fEiNz}s92_iw#c^`GYI4l|1qJEfO?5Y5ehxQPd8&O$zpQz8xIH? z0B%e5O0qYRybq+;xA>TpHWUFWP>W4KgAyaB zqin6YM4TDt-1diRp{eGaB(O-pC`)XyKB{9vjzml);=7chn@^p6Rf9HMT8XU3cwo)D^q`w%Xu0NlqqOXpbrshmv8c|y(A z9=j<_%ddVC`Ve0fjpYKPP6H1SrONSD(~+G0&9|h5jhx0WYQ<&ZoYxBnkA6332CMO#0xGxSkk?4R?l9u#YUd!1e+ln!w zL13G+$DqcN97&k$n_|>%|1h{(Z-L4r>v?=%;**bYaE&>PMsSopmRRC+JjLmzyd%3I z>r0wyKY<{p1TCgTJV&T>3{(;q_ywE5Iyq|boF+`jk>%pCnXM8dsO1qN+KT=<^5lg1 zM(q&pcsfcVle@F(h;nLIyvZY#0h+xCl_q`A+}Os<=AtO3gry215j%X^RE6>Z%)+JR zvy@u-Nr<)C)If~toChruk8KMO3m*ef1G8h&r*S}>7rN5euVJRo-6lQwWD2`28FI3S zPK36fhTU*bpY6q^NG{lENvW}=d(|tOu0?OUVy#UA7SD8u3PzALIHne*Fv^W1@}wPC z&%?4Ii^T_g2==QF<5MqG{K5dyzX04-ytEWTmjfX73B>j2`8@#<0-|XCBN@U(wxMDq zc{s~^^@?$MTx7rYWP-10`U6kW)%w{cTbeMSMIfYo0hMV6;NMR4b-;WgU0Qo_w})&vdyJq3lrV8lPyAqo-jdqIrXnM z#a)nQ1!(Zj-Y}tLB$DRFSo4L_A@5UDR=s&)N%V6*2<6x7yikPGHz`OOgdpCs#MH`+ zc+_A>%s%Ik!#P%OT3#qVnJG3Z-1IM(D)=HhWK2@fgvd*8V^qSD!fHX$NxLL27-ON^ zR6^2BPop6txIzs@x#72P0J_=nkFQa@lkUr_M8n6|%}4nFsyUFD;dxh08DZ&8Jovzt7}Es?%2ekSg#T zwbUqCyQ5vEt$1x|sLnWeCn@Xr-u>x%ktTg04HS|(>;x} zd6(t|JgtBfTiVWEdXgSG3Zm3gBzzZ}*WUzXTP(oo5PzcM0Qxq)j z3PuHPazVdLQI4w0B+QghjTCpx3(}Q-xM!u6MZBP;7uD?WMRA>#<$Z?2Os{H0H<)1x z{L?3m4>HY5XS4y`FsK_r8|REhRe)?^!Ny0sc`V`sM|waXH$Lcdkuwb~)Lm8Shqa_+ z(qTb2kGnHHZds+Ek9Z{qJs_i8u>G^|3BbuPRb?D@2oITtp4r~&w1VCelo{7;!U*X}6TV-ff%j}3UfjKG|X)4?1*t3Q}Yn0$YM~m&? zNM;8EmW<|Uo(mqM71M<418C3`+Pd}E;UeWqCF7(pb#zYsk*zRzY&c{}0*xukyPiYB z$xz$VOwdPYFwn`|iiH~`2rRYsAqt!}Q64`)%QESH6=yVvV?+eV3wcCKHgzsk;loy< zOgd6vFafzuZNO;`5Fi{>3L0i56QpaOdkF2MXnZ)>q2w`0N)_lmjefyAP2%>_z)sd9 zYAReH8@ou?ja*Bowjgd?0HbH5QOA{4sB0*!M71ycdd4vc4`d%~L}PklFj1%K5P_yl zdV)j?0gMrbnq>@AtJvJz;DmZQ94ib73|dCRfn@?bFGq{=B_^7EXw+~Ye`gBhWdx1{ zOwVVjU62x=kfL73gn2+@k(J-CvY|jQ@CGvwMTBG%U4d}{RR@otR4nz1A8Yap!@E{a zpz9(wL>UQC}n=L8E{2K6+AOnp~%GFfbi8 z5(5IvM@Sg8!tp2QVELE?nFEBBMe;TcGp_I`1JzK(Gtn>}{~!;5lY7N)rxddItrWNd z>@1%mR2j5I14n(8KmrN0GtFKGl-yGQ zFNP9r#k2qg2^{MuR?z2Z-1XdZ>A7toC<5X<;V8ZE9lj zW5yYp&ib!0gdAJXz$7#@CdWY%h8YU=ls;Op@ifm;`T8DL94+YFF!#GRxD)#v`v$kT z!L2=)7I4wwCpVPJ9Q6AHe_lzHLD@XUaWuI5E5P>21ROtfwdsu2Tni#-1D!;h+KjH=SHm6PXq>n7iDb0d64?;qiCX>Tp( zv|XhcF~oCPW~8dHoRj)XGp9w_F8)MmxRlczKeyi>I-b)WEftT8p;8s@&7rE@?FZ9W z?zZ==p0X!~bKHoIJ@3N{zDaDh*S3$Aw&3E?l2|uQ6~*8OZ@xQqt(xNMW}1p?F`?=GOh&F~EuiD|?97U4>)mZhaJWilgNz zTL?B(0%0;tWw=yq1NXouuy7h;aV$@~E2f8tcOV5+$;6bMF%Mz>6ZXe{`LZ>}-P%-^ zs0dSW;}C$UY{%9T=4?zJ7z?T}!cmT+WhB7BVnF0#jgrHRc8eIkJ#O(v-mRNjX7sqL zMBF3hNv}7mP1!>neK|J5iRs6gX?try-qQka}vT#*~vBb`G?t zlHr=ka?@Ee*M`{uK2kRQ-pDhfVAyC0^JD0^5*48@Tv|bkX;4JmAi|^ES;tXweU5UQ zBfu>e<5~Qy4GcpkKq%z4NGgI<=}-y6F$Mqpa7n4X=O$=9m?TqK(tbJ2QE^}PSY07f z?Ytt8JDR6agPCZihd8EJPP2w_t#$k62+#*87{IPlhf1#OtC|5z8SGy)2C_?a-Kj_o zId<<5#5L|7wHm^`?m=7t$OJ^NmZj*>z){vQ-cuOn#~d8EP4jlrWlF@h_yxSq10m*{ ze3#Zg(54izsFUy^K|+9T)2~S^E1K!ro*x>jg13;<6q<`5-;*2B5kYTwlg6)S6LtH2 zq9>0YGxT`1YY%e<>Biti>JYax2Yh!3qL#;ENop%nCbp9F7%mzYYe|-r;_2g{LSPcR zMVMk={a-_Z=4yD2VWoftjr;UJ0f|Wfw4LEa70lsR%PE~tV_nS{qTn0OL7n>UMYg}e z@zQG@-xRi5LJs)j7LE{8oU$o z5{uuWz&|=$XU6Y>I9+G)a>y56V&{FcBtf%VqLFWqH@#Z&g~J2!t0kM0_fxLm+sF45 z?>cmUdpl9nU8hFApz_i&xBHpO*^kkGTccMxW{LUjn3%r91MiicI?N;%w~i(56aIH{ z+$D*`AEf`C`~t$V;tu(PPi}o}A+|;^92V_XTR|Lx1qNfwSWr0?E%egH41fiX?A!=k zw<#a$0VYqOK(cY>x_7ri7w6TDoW%TMb)#su0x-^lr+(`)$SavmI_z*JvSJl9SBYt` z=eckzFzsM>!~E0)Oe$a zcp?R4^b4gFl#RVdR^VVjcbn#X90LSD|7s)piKxx}yrO z@NND!A9jGHYp|ubTh;`&DOO<&-LsW}f{!ikzR!5RNSW=}>ZeRI!$m5JzN8C~5=AJ+ zEVWv}P6+Y?G}y$-_zD+35lih?xi#k7+|oBVkv(qgIO;MVDq?3D15F(qP!(mIIjLy9 zyWWWu8~Zy0<~jqu%mH`;u78g@WX8#8U0VMz^*Enu zPkTXWSO~~T#@*-oLg8I$J8y%PV&KJJ{!s@z)(zZS4FVhn!@SCv-aaB2a~SL?qwMdW z<`LxAh2efe#hQ1(?MlNzA<8Kos){*BaK~QX1En~2BoYy`T~>_{)d5@8*uT?)VupFG zb?t!BWd!M>2-?P(c>uY=aTl8|F4j1n%U1WfqHEe6e7J|*X}HF>zj7+0G9~b|iE9jq zT$ti|h8rV6Cw7t}!hO(zBtkf%Q03U1=zT7t_(TNL8-u{XHBUetcv@Icz4UHBgmM?- z7#doqY`!g$vfG8tFB2v%Oh`!j=sSY;bZ+N+Ft;J;ayRdB4P{ZS4$`GV=_+}d7!~UG zg$l>iglee*ytVCiu0h6WK5|e3zY}JOE+91~cHugPlxC`>c|yD5tZIT>SRY(BImcXq ztl^htFE$wwVg##7QS-2ham*vQJVKS(J_ZtVPxBygn2Go|tts3SSm;ti0*VQJq+Tk> z_kuuRYAQeaoAiJ*eng0cj&9NND^KwyXdZwApEJiCw`4?d@x63rJo(a!Nu2a-=HI%UF$}gam#O_XDAF zvEiI_#kK;xl|qdy^n+Cfbum`hXlVVK_XVyF*cwy@kDyE#W6%Z^Z-_k^#gvz|1(Z?&hf?}kWw*q6dB6KFC4s=?t5 z=Pu^+^&eb?PO$-KEy9=lf)AtyNx>o5Xg1XIMnm|nqh-qbc-ew(37&;(IKb^fng?P%PfM$anFO0Db2PMp0 z_$z6Vx3F%)b4JT2vhomX^fFL<7N#<;Hm+`j*_+Wex_%n&DKrD~jyo#&B3x<-7A~4% zSZ6WvFMaU^E3hkuqI1O@NM)R?NO^7wSJ?3+eI!R8jWZ@NBd6Jb3febTT_3*2yrx)} zf(L$N3*X-6`(O#yMpAT9l?|vx4Pq@6F2D{S>*Ky2Xzer4T4Lje*7 z^bpwWpLpT6eTD6vd>b<}8;o{jLvnPbQiNxPw<#60V6z!GvI}Z;;s}=8x4K<-I%Z!_ zwZGTNjSAk?=Z+t7Cu|!o7}ixDyL%6RyBll~y>7IQ_hX6Jv*T!W=WZw1?QDwrdv|t! zc;~e5@AgIRK+g#d7m%nz0IQYasX&KoqPXA1(}8pa{-bo}xC=4eQGoHXNq=NIcZadh zpyjwfrEg>HPA68z&dzL!l^7f|7`!fQUToVAb$DmUEi)1nMd8U{tkB=c9B+K{dbG-?edFFmS(rgZq}Z_TB8*!(z9; zv*rYqT|OJo^2UaI6*iH^L@pQ!MArtVQptf*N9Q++YN+o#A_nv}#!u{XqZ{1(i>FpU z&3>wDD!ayD`i#NMjudz@R}HZfg(rq>D-^MDf$PR5|4sd1mTZ4@ z`Jm0E|7HLtv0L2F2X7uP9(J56(mTea%O`g_ILvMTK;YWdii_etR##2Bd<4+WprnHZ zS01EatX`~ptbkRx^MSv8HM}ir4rV*D8XPEy5qswbXHB+`v5sdtugSAFZQUDXSHrav zrYq2nEO!Woi<272YC}cu9{1R^?fpu=ZLNWgIGi(i7dz+OHWQO>G5ssk_QZYMU)T5L z5pKY7(S7jd;&s6m|KZ-@(xZHfe|K+r;yKv6{L!lP#=JeRqfb2qMI;*1t_hobD zG&~w*%xo<;T88h6sK>Su(?jGwYiCBQn{7A{xDA&_DVieGt{CEj;BPvBLnV)`YOu+N zKR~Q=+~R4zVF$cV+|HdkF?};RT(pSer8W?xBH-lMOOAu0IS>tJ4ZI{Y%Geo`e}i}5 z;ij2;uel0skjDUZb#FTBaVN!j$3rHAiv^mO!wcr4!#3xZkMR;f6Xn&R6X*hw0mTh7 zN*St7aW^wPcHMA(qZS?O0c)j8?b-;8RpEvb!~BN)E%)0fdZJDt8YZ8R0w#2;Sb&K- zioMKWt(MjiRo$bZnSq9ZWuBw^y1 zDER2xF>O#QYPZ<_epm+B#oXphX9ZeITNr6_1Wln#+Z3?`s|h)N@ORKw>ikmSu!0L= zSHX*3{Ow`#k&$B(w0A@)4$TNlx#Ns!76ZvH_?~QU+8!!#@JGRLP=DGKxTVO;r`YiS z43%IyOm%guo4B9pxqqyfhU@W4Ws83)d{9_^7_h@c08#KqAp8*=gLi^F6y)jyDSHdU zRo?yLd*3$19r((KKPHNkJ|%xy8QPhFmlzc+WK6N4@4w)vP}`X=I0tRmX2-}S#1L2+ z*buAnRZ^;4JM&=&PMl2}l__o)jcKm1L5%~KQd~_Q67&Rpf+r1xAzgFboL2ksz2p`n zj&SJ_1HXArq##U~yr7%hutvQmLl1vLxyWg zN8$%ik9o(1^d448`i~jYHeALTa--1fP#N4I5uDc1o-#2XBX%2~=G|LM*0i3hvcY$i zrgn6zwJygq9d!oQ$AMr_6I0yN!W4ru2Tntb($9fBkK9ODOfhy`x%b-3+5>IUfU3ow ziRB`d!!0E~pqU&VQ+VC-8mtyIXToK~uv6oaAHdz4dCA5EW?kBhfOIQ%)lyk_KX#qq z$bF6-bqkGM&Aa=9LtQprNTm&uG{eFa&jk5M6|ltCYA_^b%5bE?PQ`czf%f>R%kI9> z4m-2dyb0$Qnb~UvEdl5fEz~e&QkXxW6DnIo3NbcbJOvvK zPX(xyT0G2Ev8U?7Pvx!F;7crT4aj9D3-AwMdC|zp1v|xSbGrg<^@|_;@;3H$>6?)s z9&x(vl;0s)z%v7{)BF#Ryu{$=nd9GiW8&Xo3t%Ci)m;D1xlW>4B>ymes^zy(-qlRX z@Xy5GLK*&ef`GW(+dG zuQ4Jvp4}0VjXdK-AZ|eI9}YNPE%y;}Ku`Jbzz8KFi`K(Vq-)HA{pRYzj@CPH%6JDH zTZbj}a6o%U26d4$ORAV4y7dTVBw4H~soBh#_ZP7>giVIY2#j23iU_cw0EIAx;f)}z zn$aSV5_t}u3ZN3!n}KmWLE~1htMotOX;2=@-GIN+n5m&IS;gfKUz@L)o!=3ZB2X z>lJnu{4};ZsCoh>qZ0bC+&Lm-BKep%gi@oi5egp6Vmp9)`mKBMh1f!vE){4<)X#2*7}uo8?{ZQJ851$+8^BGu0_er zS(NNZ1LZm)l>hv3-`RL*Ustu$*{E$XkGk+c2X8p=i%Q=0QE-p&O3y}mMZCG7xj)?L zkBI}`_OZOW#oR6i)wLT$SBx}zP_Isd%$ez{1NY_MOtW^Of8cm~->`l8+w7j>=DW=u z*)2||`nl|89!;)0I5P2vd`IVGVIq5K_&HWm+e?>M4qtW1SM;x>}ma&*sXgd&~xSQu;_;hfm80h_VC8rPuXhML)`g%>8I`<^xr3b z_W5$E)V)<)&G+oL+drTSBmew0y`x>dtlb^E&)+=0VbhOxr$3hM-w;gxeE(qTckI;e zXZ&}b_CIW1rM|87iB!JN4!(^EwL*a4IBUC)IjB@j&&m4!e#lC(tq&FS$VyEbomg?w(fZYB9X-X4vFp-F zCxQxKLy(I+CPw*5fjdmc+=0!a1wM;zNhtx}c)($P7#Trn)q2x9(l>lG%LP4@SJvSn zy&LdJj+moJjHeKigb*$>txr5`6l@JUphDM6UoFk7Gkdb7l)}xNYOWn;ZDPh~9~H`` zPLH0UyP4x%Sn}X##nzYURpDusJx-?TaAkdusZ69WWBl;hsBmf6yCdgrK_YSKkz^-;k+twvCAaHX48}77zMNH!5d&py`>NA}X({wrlSAdkYzJf6ohp zK`+dK$Br1eGz%+k{vJ~(oAuo~{F+cfN_%?J8SwEif7=n33s!3!j!mqnI|_MyLr+(q z-7jO}^J;f0!W=%qr=4xwHAAkkjV1L4a!mT=$Pt~Vf`6S{) zxGB9ujl{hh@Vr3i2vsA`4Sum5wV+2C95XU7kd_N_S3+`+I9wpNi({FAWe8)_gl6W- zj4K8X`r(G1;FPC@nvXoJ5AaXfa!F(r$`Xcs&^(uKXSJ1Qz z`J?VKp>U29FOE2H$@{Jf@1i%t&LE zvZ7A@ zC{o+|R&&N5({?hb+>`)+VF##PuDS~=@X7aI>fOzZQ5sxS>{k(%h$bPi)KgAhpHw`) zqfo^o0FrMG<(Ps;J|hgS@ofn55r_Ff$BaB}#(}%lFQ?2&gPw-upj4)G1<4tcmg)X1 z+_pX2k3u9S-Dv!!_x+KQc?}wZ3k}?uz+FYa3XpDWG!(+sPfr7@0~i2dx>l!ON-<`s zVG91cNs_I0bc1^bg3#{NHaa)`eQM6{V9c``Orw!N zGPDf>4Oe)CKuOnzHyg}jyvj1Gq0h0=wR}f~$~576RPYggP@dVzLp*5ap&Bvkj==P#S37nRxAX*<_8>L`Ph(u;JOd~d7r`%12 zn?AMbAiT=(u4^H~ZgN}2+sXP7!WD1XJ2es?A|U z!NOt_RaY6q-fO)Jy}==YO!0N_Jiro^*^kE*D(HuCsVmze&|swy75A9Us+}*tQ@aY1 zqwHejI#(b-c;XJQr2`rBu}jKT6{?Aauy1h-R0Kgu+XiPpg)ee^&BfV)$EWFW9;63T zEZFG6Z)%DxIOKt!CVGm6I-lxS@lZ(_JhSy5oh@ta%Xdac`%ejfM^x=61 zD@0uyYp-q?KhiUCm{<57M{E+iHlEN&g7OC5z5mADzFRb4xa2nmMC-Z}1JIYqk38Ev_*A6c&(XgK*5<*fEF;l>~Td8#ScJkbzF2c^<=z~OU+u*D(&%j|aO%Y3n;vlXo z_ZFUn+WR>CphL$I&*R_05s)`FBsSaEeSZJeQvQ&=g>60Ft)J%Xv-a+5_eM`}xCqN{ z=iUEQ(0^gaa|XPa&u_f{eZ|2;@Shg%3|`u?qr11fC&;Jymg+Q*axd}xpaC~}v27~* zm0a9(JLyy&3~F@ z5s)=yzpZa?bUSzMvyXk7b2x!&oclwi%{LFelU%9x$_?+mZdGLmo+SOoQP-ads2K)f^(mpu^w_RENkzc-`-0L-p~>))Vj-A*$|0 z!?*!`EC%Aag6@KK>7RFg<(;M6A^7XSYtjj109uj9%s_rDXqMX+DpgQ(GN-PM%M zT*(P%q(quE8X%AN6feTnv@3$65q>suqmCdnFvlSK3GTgXR+@xG_oM#`YHc zKJFKT<6Msf{Dl^r>;BmwP;$?47+!%C(yCR+KF2lkZ5s%!BbPZA%&BZ-LC$iJ&XV=w z-~EM^s=4saBGwKbN|i)23a`bNzE(*uvBEKGU|or38Y;ro;lVA6kx6IZQe0zH;9DWy zQ!pU{Ct+l6=G~Abd;(%m;AbRFhiNB|g+^e#f$ccxz!MGIT#2T#9D~K}D12`7svFv; zZ2ef;h4&b)+-{h7@XB5}RI;y&U)@J=Cl+iltIWdTYKS4ieh(9eBKMdLBH)rf2D3pm z^V5(RKfqXFkkF>3)f`CbAsD1W%Lxs!doZQUXi&qFcP!nJB7s5@j_ecsmY1%*ds{SR zm!Bx5;K}Y!>+-|PQ@!ToSobQ-;giSHaO~hpxI;;rSCgT9i z@Re}{FI00oJ#353Px^Ld$3{EKyIKV%>S>6FhtYsVWw@R@?F)1QF5)1q=UGYRVd3($ zd&7@zn|Pnvy)|HA7H=W(6wH`y5nl_hDcq~n-4IRVNu1J+@I6d6xK;N%cs#fEQZeZO z8N3>++u*O;lsK9q3S<~owJ{) zf9?7c{u?Q_@tZM{kKg1zyz^W?u|F>kaCq>^TQAuMuYPxA7wp271uQPnL73V2iL)Sa zO@Nq$P$dT~_Dr@*A@}&T3bxP`_+70Oj7hR1trTs4q4Z=`_$_UGie-yV?}^j_^L);W z>79z5+)@-$n3!h3gM*mOPf{Kv8}R;-8PVU5EjjiOSM7}W$)IymM?uUu(Kb8S)UmV zbiPFts*XFwHXhQ4`_Nx;}>tPBPB2A+x(1lYK#P$SdZ?q=Eq z6khGe?s8an_AML2{)cf< zo>|hXJ=jqh9HB@vPEn+es^hASt!Lgi;ZC|;+Q~r`V+e16x!%A=K#wpllr;{Yz@BuY zshQz#@bxBG%%JGC%C-ovfokwNAkTGcg_o@(z4k8F@B6omL*lpR)E&_dmlaib7&;wj z=Ps^=`<&v4=vTSVB5aG(411>xB18C>bo;0pL6K+h*kQ6~kF%|?sc@Uq(c`xXOyX2k zY3EfQ4hLqRZVuQF88@>vZhzL<3J)aL^}feadRTlSV1~%`G*a9DVKZne^mH>{$vT44wYVR_Z7_TW8B&fn6Zc^Y@C z2zJ@sX+L(410Idr``mGr?^LWmM|$`XL}Hk=p&*Jn>SPRZDZpf z+OV@CM0L_+?K?&L>45DlvivhgQeCUtG9{KSv$l!bjYFOMEg}{E(Ahuz+Il<>1kI4> zN@loV^UO}{9W^1aWk1r5Cz7xdJe_MrtzCtni(xpMcm&^|({A>`k7&bJqA7^@Q7kOP zA>*ZY(1tqN7J=1@w;ykjVtE3;#Q@yWKZ#JrEFJRd%YQL^D!}PybgzL zOImr0X1eY4D6*7_CQW^E6tfazbR4e=>jL?qURt%~ zhhBphd{a!|ePu6?2SaHlhHTL(hTsFEDbIl!qDApre83Mhtos-jcn^A1n(bv3LH&3* zrW@%f?+dIr=n#Y+ehb)Lpi#->(?S_QB+`z^N|jT{+1=@Sr~i9e>1rESp#Z?;$U!z) ziR55Z!eIeQ!@_U?1qNdoA(cmvjXro><6RmR;)nxGqr-S@@*aeR4hQ{F$`hU0HV6WY ztWo%q@!GBxG0;5$U;8+u30r87r(V9Njd^hHAOJAUxxzYGbQNM1d@#$#ltwcHDyt%t zQc)^-HHsprb($2UUZI}Af^7x7Eddgs;et}HsfX-e%u!>jKJcmfi zYGtT$9)Xkj6w9Rd%Ky=Z#3o>&Xv*|7`%7?g$c^rU*^TC_SS;bL#ZwR@FdpD&s9Lse zVgZEf2=WKx9uM#`+%#NOx9}b|)H}6p@&PPg<5B81vuZ-VXz}(OuzWnLU411kqWdU{ zk46u%ZonPcURx)w380)XuXx^8BO6Vk7kF0asN|D$`Gk(e1d@kW@l=z;t=6vbxE9_K z!3_n{54RUEpDk?&eWMo+vZ9I^SJW`Jog!|8BMpeq$ugE|5-$unRt5&2m4CodFxZG_ z#tXfe_AbKE^8NvM+o=J8=0y%qRdh@v4!{Nm%5;AVXJ`AosJ;c zgXV`1s|_9IBt-9(n_hMx{)ecy`Rg z6hird1fKOD;oxE?!;=ye^*d%_YVFqpR9#*mVxu6`vB3u#TK6Rt4 z4hdKYP64k)BMj4K)_t8iMwNRbf}EHf%tJ}YDE3zoSl%yE%F(UH3vYj&V!~R$YJrhJ zIhYHcDtXHwP+0IuVsHoZ5_RqRH!wj1Qh2;P03RBSqJV*e{@|ewHm8`Fd_>?)Pw>ke z2^7SLm&mcG)PCj{GTNrXRYrb9M6mh!ueqGV(PJEUqUUn&4yJec?+eTh9dYLo9ET{i z3#yKBabm0>!~_C1k2rSK+u)qI!`cKzj0SiebW`DkTFIRj2#((6 zBNDMZ=I?PP5Sd?o(KUJ_+g!g|@OI2<2hsl3N>#tX9M~$#*%M}EkI{a>oM1PKJqCP8 zn=l{XfikMPw}X|R2nuXu^rnGJc+UTbX$0nt0X%j6`sy2ZV&bTuF@D}=HoRPzWcF}? zVPwUs%Mg(WPGQ4t^ymkADnkLDG~(6Jl7334M{QV6@P2_mN1qJv()6anfIccFdhv>a zV&CAx<@Z>xtM~TWAQ2|ZNr=ZzmMOCj!}g2#c*UqhmB;WPPOnt@w@2gGnC+(V!HU`2 zUorG{c+A+@-f3^dc{7rp^&%``fJpPS62xYlcy6$KbhD5(w z4_O@HwoD-y0r8L&9A_W`98S07AVVBaaU00u&`G?OWR`GP-9~|<<=f$p1%Y^E(&}KQ zO%&|j&e+rV*F1*t%pb1G@lV@u(7{xMhiKA$!%q9ECrbWtd+l&(lb9NV_hc=-x%wG; z)fHYT=tqQRv8gLhmQpkB8%!PzpJ4X%M&q#kF1&ns&@SLj&EK<&s}I?`?V&2%UMHrm z+~ZD||wc(Fix_e+~|h{CdWUoI@$Pb1j# z7}pWz)oa_ucjvqH;X|M4R;P>q%|2)sN8!xE`-;P`xjBM2@lK(u7R?(G#FV}PZaNLl zA~?bjwk2OMEt5L~PL04CE^YInZccHElB0KJa}@t*r+D`mV-)aO-g+X3?Z;GhSCliR z;Uk2PV^>s6!@p8Aooh@uOm0|RY`bn1qNYZ8ZPQbVbEWNbrxya--HSH}<@G3e42$o! z?V&?px8yk@@QCN232|t*xfBeRccIYX=qf@)py+V}@}gPrC~FkIM;;ght}Wgr@Um_} z&ArvR?qQQ1vh_`@nC`g8Kq%i|u7<pLl0eBYN;MDg(pufU#u5<>FDrvVeYww;XDoq58YL$pidLnj;;fTqhkndgvi1RDK`1~ zL<#~vkfL?^n5H12Rpbl@(V53?t}&G2od|TS{jCEky9zAm z#h`W~c2);Y_q{6l+@{~xqdGLuCvqL=0gx*AR4Sfa9s8_JudhOi(4Au1&fQqT&Hs!es5lR+v=n_O=8CI&{n?lA`u>ZEhpUOi$f) zcWp(c2jTKG~(t znj>jpgy763r>DnVa* zyM_)rRf|H4*F^OfY=-nEpPQTp;D!vMfYVtLewj_6+iCcKk};6iEKt}F>v;c!BTA?} z1Tnctn{_F2A5*^i{w9%jvEneRno`WF${hJ5F_R)D+dUNEoaa&&ga|^|{t1Bx${ngV z{R#lzCMZNNC7(12+>H5F1%Ta@xST}xD>)~Ta4;*pirE+(IKfJX5j@~7SJ<3U4z&`S zzm$Pe1^^;5-ja>z)k%?CUtdXXf}{)p!>Hu!$FTsS+~Om9O&j&3k|`r?59$6IGX%jW(o_hEyB1lNaCL`1gRlBj(@dT^{cG^E(^A9aitie4oaaZy;XYH1BTx zcGmnrS-aC$#r{+Fe)~W!{IvG}X9qd|-9Hx{|KkMCNB^PZ_+KpkV=U0W`9Qh+_dnzx zqI)!VbKheK`}_ylYwk5$z(K9@Ba3|GyEFejN>N{S=s|V{YX>y=A0$U zTCP|jKT(nFLl%r~Ort!=TNrT%1?D3M_z$c~WX3AUGaUP5JIw3vW%3mLTfs!SLxs1SxFFh15lf9Od0$Um=oh3dCD_AO5R0AcHxjmrSK(Tchrz znhQYss}DK9^Pe`_(A`pSphuF+E2-&C(V+aJl6^Y4-}mVBPrZa(XK}W&Ae=mxQ1jhw4ktSz`2%*RRRiu zbCPj1v%^9j1iGes9oao@nT>i1#7L&Fq~-)IO}DE;wX(=gqk#x(4?qGHR>EM#RBaDP zniJxdQVNJza4>lqLs$CFuiTS7I_3gJYTHnjaZ9Nsy7`vCgpm#+s^3}{C;2vH>sHc~ zGXzB=n=TQnOSG`2W!e%_f2Ha3BzNkTpFA|WnioVtm`t41hm*lxazQ*QZ2ban@TzUy zqxw^N$xu>Fy}z|I#Hn*U6qE$<_px0Dd({`IZh+ZAuP)uA;D}{YX@i_6ErV_Sbf$C9V53{ zqTkAn6SW&W+zw7f{1hv@4RV6d)Bbi=UbODFnk3Q8&x_PM)KJa?Ravw`p1Ey+moJNz zvCO-++~e4eU3-DkaIh9SjeSeI!(;AX)%o!=2Z4RZLkgj$8ST2Qc)m73mqhionDIZ}2^m1p?t|)$lRdNH8xrUZ%6(hDpF)L!Kcao=dFy5^IDuV$O zJ z?_gUDXo>_eO~xV$mNL%E0Sb5;g0-^2#zM{mf00+Qj1nA`CCA8K4kqMNuESIdouMKq zZa?Y@K%4xj$nP9}p$SoL$&>|ivH?*FNGZm_%jEbw&{(ufa#Pd>)ev+|OIaJ@U~%c5 z0t%VFq`lPuvdNUN@;mPYk}8m(xfpJz-JvBl4e>$CMu8>TPRhhFe4j=f3{?y{skERF zrY`9%n&kuEHYmv@g4qLhXW=b=H#Y~(yvFD6@poS!mua@*e8Fop~aP>0pOyW zh(o0I0E$);uFN(ZQuGh(KbS3SydG=DEQbQ80w>pwTv(ZVf$n1e1!d zr@?6}KtfrBP{n!g^gL8un!q*9s>TJu#$19fk`88qLP+Q%xcyBl83Y{=8LEWW;Zyyu zMHW?@5*A(!sX>~1Ajl^bikGJ_mZTC>P*Sbh*c`OenyBTtz zPU15<7rivIiu>BfRghRgT+RPf!YSKOMfX&kjMu5_gL;qC&i1#p)S@-O--dFgr;_?tAXY!Z z*m*goIOS)@y2tcSShZLu&or?F7SmCqdzcSqPUoFUx87tarP|$EZsvQ$q+RJAN@?#l zjtAP#Zhmpd(U zv$lVp+<`DZ{F1^e!6>O{broO4VPNM9=!bwNHQ{dr4*FmL{KITr+XcYW1Y2*B#Hi0d zjI$3#-PCNpMHH4L4DhD^1qZzQ1V0@^j*FUOH`BpX%m~mAKV&K*G!OlofA>p!M(r;H zt9xH>CEI%{SI9tYJ3ZkJd?|Ga^u9;mjW5#6UMB!AsZeJNdJ zQUeIIs=r#as)iCTALg4-j$oyW%&9YAQB0rGarcJ+<>e{^YfLX6&VLWO@Dq-qfL{li zTaRrYyk$Z4P^W)f{iQwjsI}dkRNoHe>KO=O&zg%?ApIf*sM9vwyDEHuPUhu z#LanSF9S|3r;n04Fy#{3tJKhJoW7w*r3Q4zP>URo+W z56k^nw>GzGxtot4PHwp1rPhfCpTc+dchM@{N45-k>3zlRKx`qa{-GX00!fTnGd+kC z2LCfWx@8fj2Y~g`(4zb1j{g52K!RxnzIRd|Y&i8E8y=DmfjPx96f(BzS8_5jO0 zt1pCR$-nQ%O`9m&{h1saUL}z>RX;PZ*W3S%!H;`(ngk4Pl2<@J<+BB!w@Tn|unK1Y zK&~r_PbPIxzC>98D4*10mrTcpc5%mZn3pin6VPT4c@^mSXTfb{1Z9cYEqn7=wMLxE z0-7pn59jTD3X9%b398^LqTH`fG@Q6;fYCeXsk8LN|NRjlz`K8_w?f=Kxc+Ij@As`o zt?g{zE1~u6ce3&b|29-H$SIu-;V}q|d#wh3udEpMkg5e^Y%ucIKfA z)aR*QDx51Q7sw)2L7a9=>}fv1A`Bhw5Zs!4d6e3_Y`2v@Xz>3MR`4MNkghMggbPV^E9uXeHwEk`6ad zB@y;#M8MEed|(wPj=J;^H33YAJxo**=+#TQ%9r#c2G3qCff$6mps&1y{>QmGD>y1% zaq?Y(sY|z7>h#mukyWgb4itb;b4it+CL96QcMBe(RsRlGG*>Acqn{UH`fN)tL3OI^d|j ze$>80An?UjCVs_Cc9r>dPIr)5BzFL4Z9jwxgALh_)3JvudlnWf!rd>I?xNOcfJAZ@Q&fvx!s+}U*ees13-@jBDBpVRwXYRsXzv*Kosz+A*e&}hOF~2Vpgr9H31=& zLt}P+zgwNr^i2Gk{vJRHamOk1vunQ9Oo?FuwxPK;{Z zENaRv+Kq;~fND!@lO!&1s0WFKbZ5yLah$557HP_Ou?P&2HX>cRXyoL6y<-@Fm@E!~ z&VxAz_y9+-5E27q*gUD^4-a`pQ_pv4j_o@jf;!O6vw=Z@T=Cam3+Tp$oGL!A*L&d3 z;Z5t`jEO$|smsEku44qGC1i>_EIalspko$ynmb{E1r&o!F&oy~W>VGRvOe1u{{anj)#R#sdAf&+OKzYX0AX#ko>HPm0AtQ*R$Atpd3K1Cc6S%f zYILb+6vdd1dk|~JY}6q#iZhlR;ynPj_RGZ)M>q1eCKNAA>tRRD&ug<<2k*18=rNX* z(uTxNKH^4~hY(N7)rwM5d{zrly;H+%M8qBCt$UHEE7B=4tEL2T$j$$(6Fqv^T+_O0 z(|Sy;muoME`Gv93{pI_h-a*&Svl;GeC+*YB{vtJ=F~ub@O|9@#%M8ADs@!Dh(^k$6 zVR_AKY(e{uK~nLq1To_c(x(>eRFgpCN8W+Pm9s(6mh%sxka$HbGrP9PT|&VQl^98% zvpUB*NLERL7H=p=Y<*Ib0Gf`95pmTnR+jW7qa9R{c%7<+v7hbQ7+dbHjyBBHQS(?~ zf$EdwK)A`S?Gc83dF;T%T1qRrZ$T^n?Xk?NWv<;c^6Bd=LG;j0HJKNy?G$gJyt7Jv9@s9tUYA)xQ(3}oDs;c zagjjruE*J2Oa-9mDGeI2t7PSdYDi#E(rPzSQM%>+qg=@9kxTMGG^bp<9M$|D|BAH-mgP?PnO^2+a8^O3FsA$#{=MeE|^D*fOQ%;71 z%xC>rNeuTPF=<%kP;jZM#)2`vU`rI(MvvR9;0DLMAajyhZ~+#1@ZCVvlkZVDWsbuI z&bh>na?+{oaj&sc8t9u%Jwu2QXifkaY+F#(#;|LD@>;-b6M<|On}c+5Qgy5?U0U7= zNYt^JX^b(`F_X)Hdt4F_%m6u3NK?##v>m-4aGh!*PnSzU(2H5gMM)$XJig&73qZ#Y zps^ajIZ07x4wJl=;A)n8K`baB$SOJq<#c$~j_X9JDI-qx=Fb1C!*xk5V1S-k0I&m= zWPiA2RV&LVMpk5tV?{GsE?Y8lU=51ZE(sdAVlUCu%$U@adWjSrx0UFSh$&1e*<_g@ zSsq)Knh3M7hS?&b@g@fr09`U}bJ)3N65g>yCv z-MXVMS!%BVe%^@74KO1|Q(=k*#%dLHm8d2+eXX(F<6zYQOR|l#%X9-n{S2E9EGHZ` zMX-e8R=^~{DcnJ;$^i$TFMv;$6$F|M+>jP)PNU|pG2PPpjrYC^1k_N;64;8v)DayP z!Ms;d1eSaPTA3~<3H3ysl13Y_)}Uca+q4<7WOl@tbV49zQ!Ra4r@9x@m03bb-t@iu zP*uAV2xJv|gqC~(^b!&VP!ooen1vXYnHjiSh!)|_6JR_w`Mpz*MlX_J(`bN(-c<@f zDZSLWt$vjWCNPb zir3MKT#{&5C~&L-?5&ne<|$PLXQh;sw-g~pfP67jQXk_ARux5x-fS#K2Thwy5Ufd6 zb+sER0+c(|b=MB!Y&R2XmDJOS^<|SJhfIl;D16QDc-#Rg1@K06u_!3vn@uQ<~v&pA{p#pHX1$E*2$x?g`)?{ z4#+D~{1g_d%2A79Xdo6q{8Ohk$^n244SW8A*>(-smZ*e9fRx~7p2FPL#l$$Y^fU-aPkos&4Au(p)F#b zf?H715MCvfLBAN$Ol|^gfvZlLn1PxI2y@ThZpzzl>R;q-o35pniM6evpL|@+U$bw< zwYLgye(Ao|MESd%F6NI|XZhg#TbJCk+&ogy-Xx>O+w{Nz(>FVTUVJQdxjw{qSZz1z z)1+E(o6St(+4IxSm1p!WR7c6D$#(K7b2FJs9ayf)<$3i48x&>jDV83a*mWC3pJ^`4 zmTtx}!Dl^FZrZ8yL@K{;vB$^^D-ZELot4=+O_?fA(jJjP*@g{^yyk_@@zIs)sG~>f zslm6^>UH`fon+qs58bbm0s0yJuYOBIot2HBd%R26)wc%t336@zjp9Yo(09QYdP