From 0f8acdc06aa6bef4a7881bd831a3e9541b30609d Mon Sep 17 00:00:00 2001 From: Till Harbaum Date: Fri, 29 Jul 2016 11:14:39 +0200 Subject: [PATCH] Add c16/c264 source --- cores/c16/README.txt | 117 + cores/c16/basic.hex | 16384 +++++++++++++++++++++++++++++++++++ cores/c16/basic_rom.v | 63 + cores/c16/c16.v | 263 + cores/c16/c16_keymatrix.v | 174 + cores/c16/c16_mist.qpf | 30 + cores/c16/c16_mist.qsf | 343 + cores/c16/c16_mist.v | 601 ++ cores/c16/colors_to_rgb.v | 183 + cores/c16/cpu65xx_e.vhd | 48 + cores/c16/cpu65xx_fast.vhd | 1565 ++++ cores/c16/data_io.v | 127 + cores/c16/gpl-3.0.txt | 674 ++ cores/c16/kernal_PAL.hex | 16384 +++++++++++++++++++++++++++++++++++ cores/c16/kernal_rom.v | 78 + cores/c16/mos6529.v | 54 + cores/c16/mos8501.v | 188 + cores/c16/osd.v | 204 + cores/c16/pll.ppf | 11 + cores/c16/pll_ntsc.qip | 4 + cores/c16/pll_ntsc.v | 309 + cores/c16/pll_pal.qip | 4 + cores/c16/pll_pal.v | 309 + cores/c16/ps2receiver.v | 76 + cores/c16/scandoubler.v | 177 + cores/c16/sdram.v | 150 + cores/c16/stp1.stp | 1186 +++ cores/c16/ted.v | 1752 ++++ cores/c16/user_io.v | 418 + 29 files changed, 41876 insertions(+) create mode 100644 cores/c16/README.txt create mode 100644 cores/c16/basic.hex create mode 100644 cores/c16/basic_rom.v create mode 100644 cores/c16/c16.v create mode 100644 cores/c16/c16_keymatrix.v create mode 100644 cores/c16/c16_mist.qpf create mode 100644 cores/c16/c16_mist.qsf create mode 100644 cores/c16/c16_mist.v create mode 100644 cores/c16/colors_to_rgb.v create mode 100644 cores/c16/cpu65xx_e.vhd create mode 100644 cores/c16/cpu65xx_fast.vhd create mode 100644 cores/c16/data_io.v create mode 100644 cores/c16/gpl-3.0.txt create mode 100644 cores/c16/kernal_PAL.hex create mode 100644 cores/c16/kernal_rom.v create mode 100644 cores/c16/mos6529.v create mode 100644 cores/c16/mos8501.v create mode 100644 cores/c16/osd.v create mode 100644 cores/c16/pll.ppf create mode 100644 cores/c16/pll_ntsc.qip create mode 100644 cores/c16/pll_ntsc.v create mode 100644 cores/c16/pll_pal.qip create mode 100644 cores/c16/pll_pal.v create mode 100644 cores/c16/ps2receiver.v create mode 100644 cores/c16/scandoubler.v create mode 100644 cores/c16/sdram.v create mode 100644 cores/c16/stp1.stp create mode 100644 cores/c16/ted.v create mode 100644 cores/c16/user_io.v diff --git a/cores/c16/README.txt b/cores/c16/README.txt new file mode 100644 index 0000000..914251f --- /dev/null +++ b/cores/c16/README.txt @@ -0,0 +1,117 @@ +FPGATED v1.0 +Copyright 2013-2016 Istvan Hegedus +MiST port by Till Harbaum + +FPGATED is a cycle exact FPGA core for the MOS 7360/8360 TED chip written in verilog language. +MOS 7360/8360 is complex chip providing graphic, sound, bus and memory control for the Commodore 264 +series 8 bit computers, namely the Commodore Plus4, Commodore 16 and Commodore 116. + +In addition to the TED core modul FPGATED contains a simple C16 implementation using TED core and Gadget Factory's +Papilio One 500k platform with a customized IO wing called Papilio TEDWing. The 6502 CPU core of C16 is created by +Peter Wendrich in vhdl and is taken from the FPGA64 project with the permission of the author. + +For more technical details and building Papilio TEDWing module visit https://hackaday.io/project/11460-fpgated + +Files + +basic_rom.v C16/Plus4 Basic rom module +c16.v This is the TOP module of FPGATED implementing a C16 computer +c16_testbench.v C16 testbench for simulation +c16_keymatrix.v C16/Plus4 keyboard matrix emulation module +colors_to_rgb.v TED color code conversion module to 12bit RGB values +cpu65xx_e.vhd 6502 core vhdl header +cpu65xx_fast.vhd 6502 core vhdl code +dram.v DRAM module for internal FPGA SRAM memory implementation +kernal_rom.v C16/Plus4 Kernal rom module +mos6529.v MOS 6529 IO chip emulation module +mos8501.v MOS 8501 CPU shell for 6502 core +palclockgen.v Xilinx DCM module for PAL system clock signal +ps2receiver.v PS2 keyboard receiver module +ram.v Simulated RAM for testbench +ted.v MOS 7360/8360 FPGA core + +basic.hex C16/Plus4 BASIC rom hexadecimal dump +Diag264_NTSC.hex Diag264 NTSC kernal hexadecimal dump +Diag264_PAL.hex Diag264 PAL kernal hexadecimal dump +kernal_NTSC.hex C16/Plus4 NTSC Kernal rom hexadecimal dump +kernal_PAL.hex C16/PLus4 PAL Kernal rom hexadecimal dump + +TEDwing.ucf Xilinx ucf file for Papilio TEDwing +bin2hex.pl Perl script for creating hex dump of binary rom image files + +c16_PAL.bit A compiled PAL FPGATED core for Papilio platform using FPGATED wing + + +Installation instructions are for Xilinx FPGA platforms but the source files with the exception of palclockgen.v +and Xilinx ucf files can be used for other vendor's FPGAs. +Some modules are using Xilinx specific (* RAM_STYLE="BLOCK" *) directive for forcing the synthesis tool to +use FPGA internal block ram for certain arrays. In case of other vendor's FPGAs see vendor specific documentation +for generating block ram. + +Building FPGATED on the Papilio Platform requires a suitable wing. One can use the Arcade megawing but it lacks +external memory and IEC bus for peripherial connections. Thus I recommend to build TEDwing designed by me. Look for +eagle PCB and schematic files in FPGATED source package. +Although FPGATED can be synthetised to a Papilio One board using Spartan3E chip, I recommend to go for Papilio Pro +platform which has external 8Mbyte SDRAM and a Spartan 6 LX9 FPGA which has more internal sram. In both cases there +are plenty of free resources on the FPGA for FPGATED (if you use external 64k ram). + +Installation instructions: + +1. Create a new project in Xilinx ISE Webpack and choose the proper FPGA family for the implementation. +2. Choose to use HDL verilog and vhdl for the design. +3. Add all *.v files to the project +4. Using ISE DCM wizard create a clock generator for FPGATED. + Use CLKFX output of DCM and specify 28.37515MHz PAL or 28.63636MHz for NTSC system + This will be the main FPGA clock connected to the clk signal of all modules + Modify C16.v to use proper DCM instantiation (out of scope of this document) +5. Open kernal_rom.v and uncomment the proper Kernal file (Kernal_NTSC.hex or Kernal_PAL.hex) to use. + You can even use a custom rom or JiffyDos if you own it (JiffyDos is working fine, I have tested). + Diag264 roms are included for testing purposes. +6. If you don't use TEDwing modify or replace TEDwing.ucf file for proper pinout setup +7. Video output of FPGATED is a PAL/NTSC RGBS signal so you will need a VGA->scart custom cable to + hook it up to a monitor or television. The cable is identical to minimig scart cables (see internet for wiring diagram) + +Enjoy FPGATED. + +See https://hackaday.io/project/11460-fpgated for detailed installation instructions. + +TED module signals: + + input wire clk main FPGA clock must be 4*dot clk so 28.375152MHz for PAL and 28.63636 for NTSC + input wire [15:0] addr_in 16 bits address bus in + output wire [15:0] addr_out 16 bits address bus out + input wire [7:0] data_in 8 bits data bus in + output wire [7:0] data_out 8 bits data bus out + input wire rw RW signal to TED, low during write, high during read (real TED pulls it high during reads) + output wire cpuclk this is a CPU clock out for external real CPU + output wire [6:0] color 7 bits color code using TED's color palette values + output wire csync composite sync signal for PAL/NTSC displays + output wire irq active low IRQ signal to CPU + output wire ba BA (or with other name RDY) signal to 8501 CPU + output reg mux MUX signal, identical to original + output reg ras RAS signal, identical to original + output reg cas CAS signal, identical to original + output reg cs0 CS0 signal, identical to original + output reg cs1 CS1 signal, identical to original + output reg aec AEC signal, identical to original + output wire snd Sound output. PWM modulated sound, needs a low pass filter outside the FPGA + input wire [7:0] k Keyport in, same as in original TED + output wire cpuenable a short enable signal used for synchronous FPGA 6502 CPU clocking + + +Still to do: + +FPGATED is not ready yet. I just released it in this state because I did not want to keep it in a secret longer before someone else +creates it. I have plans to continue. + +- write a plus4 shell using Papilio Pro platform +- Jostick emulation on keyboard (as TEDwing doesn't have joystick ports) +- scandoubler for VGA displays +- fix internal video shift mechanism for proper FLI emulation +- Chorma/Luma signal generation +- Try it in a real C16 or Plus4! + +Contact: hegedusis@t-online.hu + +Special Thanks to Levente Harsfalvi for the technical information on TED sound generators and for some other important hints! +Thanks to Laszlo Jozsef for the color conversion table and the Spartan6 board that I have never had time to build... diff --git a/cores/c16/basic.hex b/cores/c16/basic.hex new file mode 100644 index 0000000..9711fc1 --- /dev/null +++ b/cores/c16/basic.hex @@ -0,0 +1,16384 @@ +4c +19 +80 +4c +0a +80 +00 +43 +42 +4d +20 +cc +ff +20 +d8 +8a +85 +13 +20 +c9 +c7 +58 +4c +7e +86 +20 +17 +81 +20 +2e +80 +20 +c2 +80 +20 +f4 +fc +a2 +fb +9a +d0 +ec +71 +98 +71 +94 +a9 +4c +85 +54 +8d +00 +05 +a9 +1c +a0 +99 +8d +01 +05 +8c +02 +05 +a2 +03 +bd +2a +80 +9d +f2 +02 +ca +10 +f7 +a2 +32 +bd +22 +81 +9d +72 +04 +ca +d0 +f7 +86 +68 +86 +13 +86 +18 +8e +eb +02 +8e +00 +10 +8a +a2 +03 +95 +72 +9d +e5 +02 +ca +d0 +f8 +ea +8e +03 +05 +e8 +8e +fd +01 +8e +fc +01 +ae +3b +05 +86 +86 +a2 +36 +86 +85 +a2 +19 +86 +16 +a2 +01 +a0 +10 +86 +2b +84 +2c +a2 +05 +86 +22 +a9 +d0 +8d +e4 +02 +a2 +02 +bd +32 +05 +95 +36 +95 +32 +ca +d0 +f6 +a0 +00 +b9 +47 +81 +9d +a5 +04 +e8 +c8 +c0 +0b +90 +f4 +a4 +22 +b9 +bc +80 +9d +9f +04 +c6 +22 +10 +e6 +60 +64 +5f +6f +24 +22 +3b +a5 +2b +a4 +2c +20 +23 +89 +20 +4f +ff +93 +0d +20 +43 +4f +4d +4d +4f +44 +4f +52 +45 +20 +42 +41 +53 +49 +43 +20 +56 +33 +2e +35 +20 +00 +a5 +37 +38 +e5 +2b +aa +a5 +38 +e5 +2c +20 +5f +a4 +20 +4f +ff +20 +42 +59 +54 +45 +53 +20 +46 +52 +45 +45 +0d +00 +4c +7b +8a +86 +86 +12 +87 +56 +89 +6e +8b +d6 +8b +17 +94 +6a +89 +88 +8b +8b +8c +a2 +11 +bd +05 +81 +9d +00 +03 +ca +10 +f7 +60 +e6 +3b +d0 +02 +e6 +3c +78 +8d +3f +ff +a0 +00 +b1 +3b +8d +3e +ff +58 +c9 +3a +b0 +0a +c9 +20 +f0 +e6 +38 +e9 +30 +38 +e9 +d0 +60 +8d +9c +04 +78 +8d +3f +ff +b1 +00 +8d +3e +ff +58 +60 +00 +00 +00 +a9 +43 +d0 +32 +a9 +4e +d0 +2e +a9 +14 +d0 +2a +a9 +47 +d0 +26 +a9 +4e +d0 +22 +a9 +5c +d0 +1e +a9 +5f +d0 +1a +a9 +3d +d0 +16 +a9 +57 +d0 +12 +a9 +59 +d0 +0e +a9 +62 +d0 +0a +a9 +50 +d0 +06 +a9 +6c +d0 +02 +a9 +5a +4c +94 +04 +45 +4e +c4 +46 +4f +d2 +4e +45 +58 +d4 +44 +41 +54 +c1 +49 +4e +50 +55 +54 +a3 +49 +4e +50 +55 +d4 +44 +49 +cd +52 +45 +41 +c4 +4c +45 +d4 +47 +4f +54 +cf +52 +55 +ce +49 +c6 +52 +45 +53 +54 +4f +52 +c5 +47 +4f +53 +55 +c2 +52 +45 +54 +55 +52 +ce +52 +45 +cd +53 +54 +4f +d0 +4f +ce +57 +41 +49 +d4 +4c +4f +41 +c4 +53 +41 +56 +c5 +56 +45 +52 +49 +46 +d9 +44 +45 +c6 +50 +4f +4b +c5 +50 +52 +49 +4e +54 +a3 +50 +52 +49 +4e +d4 +43 +4f +4e +d4 +4c +49 +53 +d4 +43 +4c +d2 +43 +4d +c4 +53 +59 +d3 +4f +50 +45 +ce +43 +4c +4f +53 +c5 +47 +45 +d4 +4e +45 +d7 +54 +41 +42 +a8 +54 +cf +46 +ce +53 +50 +43 +a8 +54 +48 +45 +ce +4e +4f +d4 +53 +54 +45 +d0 +ab +ad +aa +af +de +41 +4e +c4 +4f +d2 +be +bd +bc +53 +47 +ce +49 +4e +d4 +41 +42 +d3 +55 +53 +d2 +46 +52 +c5 +50 +4f +d3 +53 +51 +d2 +52 +4e +c4 +4c +4f +c7 +45 +58 +d0 +43 +4f +d3 +53 +49 +ce +54 +41 +ce +41 +54 +ce +50 +45 +45 +cb +4c +45 +ce +53 +54 +52 +a4 +56 +41 +cc +41 +53 +c3 +43 +48 +52 +a4 +4c +45 +46 +54 +a4 +52 +49 +47 +48 +54 +a4 +4d +49 +44 +a4 +47 +cf +52 +47 +d2 +52 +43 +4c +d2 +52 +4c +55 +cd +4a +4f +d9 +52 +44 +4f +d4 +44 +45 +c3 +48 +45 +58 +a4 +45 +52 +52 +a4 +49 +4e +53 +54 +d2 +45 +4c +53 +c5 +52 +45 +53 +55 +4d +c5 +54 +52 +41 +d0 +54 +52 +4f +ce +54 +52 +4f +46 +c6 +53 +4f +55 +4e +c4 +56 +4f +cc +41 +55 +54 +cf +50 +55 +44 +45 +c6 +47 +52 +41 +50 +48 +49 +c3 +50 +41 +49 +4e +d4 +43 +48 +41 +d2 +42 +4f +d8 +43 +49 +52 +43 +4c +c5 +47 +53 +48 +41 +50 +c5 +53 +53 +48 +41 +50 +c5 +44 +52 +41 +d7 +4c +4f +43 +41 +54 +c5 +43 +4f +4c +4f +d2 +53 +43 +4e +43 +4c +d2 +53 +43 +41 +4c +c5 +48 +45 +4c +d0 +44 +cf +4c +4f +4f +d0 +45 +58 +49 +d4 +44 +49 +52 +45 +43 +54 +4f +52 +d9 +44 +53 +41 +56 +c5 +44 +4c +4f +41 +c4 +48 +45 +41 +44 +45 +d2 +53 +43 +52 +41 +54 +43 +c8 +43 +4f +4c +4c +45 +43 +d4 +43 +4f +50 +d9 +52 +45 +4e +41 +4d +c5 +42 +41 +43 +4b +55 +d0 +44 +45 +4c +45 +54 +c5 +52 +45 +4e +55 +4d +42 +45 +d2 +4b +45 +d9 +4d +4f +4e +49 +54 +4f +d2 +55 +53 +49 +4e +c7 +55 +4e +54 +49 +cc +57 +48 +49 +4c +c5 +00 +d9 +8c +c9 +ad +93 +92 +af +8d +ed +90 +07 +91 +9a +96 +4e +91 +7b +8e +4c +8d +bb +8b +e0 +8d +99 +8c +2b +8d +82 +8d +0a +8e +d7 +8c +1a +8e +69 +9e +f2 +a7 +dd +a7 +ef +a7 +9c +9a +11 +9e +df +8f +ff +8f +02 +8d +fe +8a +97 +8a +e5 +8f +b4 +a7 +4c +a8 +59 +a8 +b7 +90 +78 +8a +0a +8e +3f +b4 +2a +b4 +51 +b6 +54 +b6 +48 +b8 +bc +b8 +cc +b6 +43 +b5 +c2 +c5 +d0 +b8 +d3 +b9 +e1 +ba +1d +c0 +34 +bd +28 +be +d8 +c4 +0e +c5 +19 +c5 +66 +c5 +b7 +c5 +e7 +b6 +56 +b5 +02 +b6 +ab +b5 +bb +c8 +40 +c9 +50 +c9 +67 +c9 +9b +c9 +cb +c9 +d9 +c9 +f3 +c9 +ff +c9 +59 +ae +8e +ab +28 +b7 +51 +ff +be +a2 +58 +a3 +dd +a2 +00 +05 +62 +9a +7d +9a +e4 +a5 +07 +a7 +1e +a0 +60 +a6 +70 +aa +77 +aa +c0 +aa +1a +ab +fa +9d +61 +9d +66 +9b +93 +9d +70 +9d +bb +9c +cf +9c +03 +9d +15 +9d +79 +bf +85 +bf +87 +bf +c1 +bf +fd +bf +1b +9e +07 +b5 +be +b4 +79 +9d +9e +79 +86 +9e +7b +7a +a0 +7b +96 +a1 +7f +ed +a5 +50 +fa +95 +46 +f7 +95 +7d +26 +a6 +5a +64 +94 +64 +27 +96 +54 +4f +4f +20 +4d +41 +4e +59 +20 +46 +49 +4c +45 +d3 +46 +49 +4c +45 +20 +4f +50 +45 +ce +46 +49 +4c +45 +20 +4e +4f +54 +20 +4f +50 +45 +ce +46 +49 +4c +45 +20 +4e +4f +54 +20 +46 +4f +55 +4e +c4 +44 +45 +56 +49 +43 +45 +20 +4e +4f +54 +20 +50 +52 +45 +53 +45 +4e +d4 +4e +4f +54 +20 +49 +4e +50 +55 +54 +20 +46 +49 +4c +c5 +4e +4f +54 +20 +4f +55 +54 +50 +55 +54 +20 +46 +49 +4c +c5 +4d +49 +53 +53 +49 +4e +47 +20 +46 +49 +4c +45 +20 +4e +41 +4d +c5 +49 +4c +4c +45 +47 +41 +4c +20 +44 +45 +56 +49 +43 +45 +20 +4e +55 +4d +42 +45 +d2 +4e +45 +58 +54 +20 +57 +49 +54 +48 +4f +55 +54 +20 +46 +4f +d2 +53 +59 +4e +54 +41 +d8 +52 +45 +54 +55 +52 +4e +20 +57 +49 +54 +48 +4f +55 +54 +20 +47 +4f +53 +55 +c2 +4f +55 +54 +20 +4f +46 +20 +44 +41 +54 +c1 +49 +4c +4c +45 +47 +41 +4c +20 +51 +55 +41 +4e +54 +49 +54 +d9 +4f +56 +45 +52 +46 +4c +4f +d7 +4f +55 +54 +20 +4f +46 +20 +4d +45 +4d +4f +52 +d9 +55 +4e +44 +45 +46 +27 +44 +20 +53 +54 +41 +54 +45 +4d +45 +4e +d4 +42 +41 +44 +20 +53 +55 +42 +53 +43 +52 +49 +50 +d4 +52 +45 +44 +49 +4d +27 +44 +20 +41 +52 +52 +41 +d9 +44 +49 +56 +49 +53 +49 +4f +4e +20 +42 +59 +20 +5a +45 +52 +cf +49 +4c +4c +45 +47 +41 +4c +20 +44 +49 +52 +45 +43 +d4 +54 +59 +50 +45 +20 +4d +49 +53 +4d +41 +54 +43 +c8 +53 +54 +52 +49 +4e +47 +20 +54 +4f +4f +20 +4c +4f +4e +c7 +46 +49 +4c +45 +20 +44 +41 +54 +c1 +46 +4f +52 +4d +55 +4c +41 +20 +54 +4f +4f +20 +43 +4f +4d +50 +4c +45 +d8 +43 +41 +4e +27 +54 +20 +43 +4f +4e +54 +49 +4e +55 +c5 +55 +4e +44 +45 +46 +27 +44 +20 +46 +55 +4e +43 +54 +49 +4f +ce +56 +45 +52 +49 +46 +d9 +4c +4f +41 +c4 +42 +52 +45 +41 +4b +00 +a0 +43 +41 +4e +27 +54 +20 +52 +45 +53 +55 +4d +c5 +4c +4f +4f +50 +20 +4e +4f +54 +20 +46 +4f +55 +4e +c4 +4c +4f +4f +50 +20 +57 +49 +54 +48 +4f +55 +54 +20 +44 +cf +44 +49 +52 +45 +43 +54 +20 +4d +4f +44 +45 +20 +4f +4e +4c +d9 +4e +4f +20 +47 +52 +41 +50 +48 +49 +43 +53 +20 +41 +52 +45 +c1 +42 +41 +44 +20 +44 +49 +53 +cb +aa +a0 +00 +a9 +71 +85 +24 +a9 +84 +85 +25 +ca +30 +1c +b1 +24 +48 +e6 +24 +d0 +02 +e6 +25 +68 +10 +f4 +30 +ef +20 +4f +ff +0d +0a +52 +45 +41 +44 +59 +2e +0d +0a +00 +60 +a2 +80 +2c +a2 +10 +6c +00 +03 +8a +30 +7a +8e +ef +04 +24 +81 +10 +35 +a0 +01 +b9 +39 +00 +99 +f0 +04 +b9 +5b +02 +99 +f5 +04 +88 +10 +f1 +e0 +11 +f0 +20 +ac +f3 +04 +c8 +f0 +1a +88 +84 +15 +8c +f4 +04 +ac +f2 +04 +84 +14 +a2 +ff +8e +f3 +04 +ae +f7 +04 +9a +20 +69 +8d +4c +dc +8b +ca +8a +48 +a9 +00 +85 +83 +20 +c9 +c7 +68 +20 +53 +86 +20 +cc +ff +a9 +00 +85 +13 +20 +3e +90 +20 +b0 +90 +a0 +00 +b1 +24 +48 +29 +7f +20 +b2 +90 +c8 +68 +10 +f4 +20 +d8 +8a +20 +4f +ff +20 +45 +52 +52 +4f +52 +00 +a4 +3a +c8 +f0 +03 +20 +53 +a4 +20 +6f +86 +a9 +80 +20 +90 +ff +a9 +00 +85 +81 +6c +02 +03 +a2 +ff +86 +3a +20 +5a +88 +86 +3b +84 +3c +20 +73 +04 +aa +f0 +ec +90 +09 +20 +53 +89 +20 +79 +04 +4c +d9 +8b +20 +3e +8e +20 +53 +89 +84 +0b +20 +3d +8a +90 +4a +a0 +01 +20 +d1 +04 +85 +23 +a5 +2d +85 +22 +a5 +60 +85 +25 +88 +20 +d1 +04 +18 +e5 +5f +49 +ff +18 +65 +2d +85 +2d +85 +24 +a5 +2e +69 +ff +85 +2e +e5 +60 +aa +38 +a5 +5f +e5 +2d +a8 +b0 +03 +e8 +c6 +25 +18 +65 +22 +90 +03 +c6 +23 +18 +20 +b0 +04 +91 +24 +c8 +d0 +f8 +e6 +23 +e6 +25 +ca +d0 +f1 +20 +9a +8a +20 +18 +88 +a0 +00 +20 +a5 +04 +f0 +8f +18 +a5 +2d +a4 +2e +85 +5a +84 +5b +65 +0b +90 +01 +c8 +18 +69 +04 +90 +01 +c8 +85 +58 +84 +59 +20 +c0 +88 +a0 +00 +a9 +01 +91 +5f +c8 +91 +5f +c8 +a5 +14 +91 +5f +a5 +15 +c8 +91 +5f +c8 +98 +18 +65 +5f +85 +5f +90 +02 +e6 +60 +a5 +31 +a4 +32 +85 +2d +84 +2e +a4 +0b +88 +20 +a5 +04 +91 +5f +88 +10 +f8 +20 +18 +88 +20 +93 +8a +a5 +73 +05 +74 +f0 +2b +a5 +14 +18 +65 +73 +85 +63 +a5 +15 +65 +74 +85 +62 +a2 +90 +38 +20 +ce +a2 +20 +6f +a4 +a2 +00 +bd +01 +01 +f0 +06 +9d +27 +05 +e8 +d0 +f5 +a9 +1d +9d +27 +05 +e8 +86 +ef +4c +0f +87 +a5 +2b +a4 +2c +85 +22 +84 +23 +18 +a0 +00 +20 +b0 +04 +d0 +06 +c8 +20 +b0 +04 +f0 +2b +a0 +04 +c8 +20 +b0 +04 +d0 +fa +c8 +98 +65 +22 +aa +a0 +00 +91 +22 +98 +65 +23 +c8 +91 +22 +86 +22 +85 +23 +90 +d6 +18 +a5 +22 +a4 +23 +69 +02 +90 +01 +c8 +85 +2d +84 +2e +60 +a2 +00 +20 +91 +a7 +c9 +0d +f0 +0b +9d +00 +02 +e8 +e0 +59 +90 +f1 +4c +4c +cc +4c +31 +90 +20 +60 +a7 +a5 +3d +c9 +b0 +d0 +06 +a5 +3e +c9 +07 +f0 +3d +a0 +00 +a5 +02 +c9 +81 +d0 +1b +d1 +3d +d0 +33 +a0 +02 +a5 +4a +c9 +ff +f0 +2b +d1 +3d +d0 +07 +88 +a5 +49 +d1 +3d +f0 +20 +a2 +12 +d0 +0e +b1 +3d +c5 +02 +f0 +16 +a2 +12 +c9 +81 +f0 +02 +a2 +05 +8a +18 +65 +3d +85 +3d +90 +bb +e6 +3e +d0 +b7 +a0 +01 +60 +20 +23 +89 +85 +31 +84 +32 +38 +a5 +5a +e5 +5f +85 +22 +a8 +a5 +5b +e5 +60 +aa +e8 +98 +f0 +25 +a5 +5a +38 +e5 +22 +85 +5a +b0 +03 +c6 +5b +38 +a5 +58 +e5 +22 +85 +58 +b0 +09 +c6 +59 +90 +05 +20 +89 +81 +91 +58 +88 +d0 +f8 +20 +89 +81 +91 +58 +c6 +5b +c6 +59 +ca +d0 +f1 +60 +8c +f4 +07 +38 +a5 +7c +ed +f4 +07 +85 +7c +a5 +7d +e9 +00 +85 +7d +c9 +06 +90 +36 +d0 +06 +a5 +7c +c9 +ec +90 +2e +60 +c4 +34 +90 +28 +d0 +04 +c5 +33 +90 +22 +48 +a2 +09 +98 +48 +b5 +57 +ca +10 +fa +20 +54 +a9 +a2 +f7 +68 +95 +61 +e8 +30 +fa +68 +a8 +68 +c4 +34 +90 +06 +d0 +05 +c5 +33 +b0 +01 +60 +4c +81 +86 +6c +04 +03 +a5 +3b +48 +a5 +3c +48 +20 +79 +04 +4c +65 +89 +20 +73 +04 +90 +fb +6c +0c +03 +90 +68 +c9 +00 +f0 +55 +c9 +3a +f0 +ee +c9 +3f +d0 +04 +a9 +99 +d0 +2e +c9 +80 +90 +0b +c9 +ff +f0 +de +a0 +01 +20 +ea +89 +f0 +d1 +c9 +22 +d0 +0d +20 +73 +04 +c9 +00 +f0 +2f +c9 +22 +f0 +c8 +d0 +f3 +20 +03 +8a +90 +c1 +c0 +00 +f0 +03 +20 +ea +89 +a5 +0b +a0 +00 +91 +3b +c9 +8f +f0 +0d +c9 +83 +d0 +ac +20 +73 +04 +20 +b0 +8d +4c +5c +89 +20 +73 +04 +20 +0b +8e +a6 +3b +68 +85 +3c +68 +85 +3b +38 +8a +e5 +3b +a8 +c8 +60 +48 +88 +88 +20 +ea +89 +a0 +00 +a9 +fe +91 +3b +c8 +68 +91 +3b +20 +73 +04 +4c +62 +89 +18 +98 +65 +3b +85 +22 +a5 +3c +69 +00 +85 +23 +a0 +00 +20 +b0 +04 +91 +3b +c8 +c9 +00 +d0 +f6 +60 +a9 +81 +a0 +8e +85 +23 +84 +22 +a0 +00 +84 +0b +88 +c8 +20 +a5 +04 +38 +f1 +22 +f0 +f7 +c9 +80 +f0 +1b +b1 +22 +30 +03 +c8 +d0 +f9 +c8 +e6 +0b +18 +98 +65 +22 +85 +22 +90 +02 +e6 +23 +18 +a0 +00 +b1 +22 +d0 +d9 +05 +0b +85 +0b +60 +a5 +2b +a6 +2c +a0 +01 +85 +5f +86 +60 +20 +d1 +04 +f0 +2b +c8 +c8 +20 +d1 +04 +85 +78 +a5 +15 +c5 +78 +90 +1f +f0 +03 +88 +d0 +0e +88 +20 +d1 +04 +85 +78 +a5 +14 +c5 +78 +90 +0e +f0 +0c +88 +20 +d1 +04 +aa +88 +20 +d1 +04 +b0 +ca +18 +60 +d0 +fd +a9 +00 +a8 +91 +2b +c8 +91 +2b +8d +eb +02 +a5 +2b +18 +69 +02 +85 +2d +a5 +2c +69 +00 +85 +2e +20 +f1 +8a +a9 +00 +d0 +52 +20 +e7 +ff +a0 +00 +84 +79 +88 +8c +f3 +04 +8c +f0 +04 +8c +f1 +04 +8c +ef +04 +a5 +37 +a4 +38 +85 +33 +84 +34 +a9 +b0 +a0 +07 +85 +7c +84 +7d +a5 +2d +a4 +2e +85 +2f +84 +30 +85 +31 +84 +32 +a2 +03 +bd +ed +8a +9d +e7 +04 +ca +10 +f7 +20 +b1 +8c +a2 +19 +86 +16 +68 +a8 +68 +a2 +fa +9a +48 +98 +48 +a9 +00 +8d +5c +02 +85 +10 +60 +20 +2c +2e +24 +18 +a5 +2b +69 +ff +85 +3b +a5 +2c +69 +ff +85 +3c +60 +20 +ca +ae +a0 +01 +20 +d1 +04 +d0 +06 +88 +20 +d1 +04 +f0 +2e +20 +c0 +8c +20 +3e +90 +a0 +02 +20 +d1 +04 +aa +c8 +20 +d1 +04 +c5 +15 +d0 +04 +e4 +14 +f0 +02 +b0 +14 +20 +40 +8b +a0 +00 +20 +d1 +04 +aa +c8 +20 +d1 +04 +86 +5f +85 +60 +4c +02 +8b +4c +3e +90 +a0 +03 +84 +49 +84 +0f +20 +5f +a4 +a9 +20 +a4 +49 +29 +7f +20 +b2 +90 +c9 +22 +d0 +06 +a5 +0f +49 +ff +85 +0f +c8 +f0 +de +24 +53 +10 +03 +20 +0c +b7 +20 +d1 +04 +f0 +50 +6c +06 +03 +10 +df +c9 +ff +f0 +db +24 +0f +30 +d7 +c9 +fe +d0 +17 +c8 +20 +d1 +04 +f0 +0c +84 +49 +38 +6c +0e +03 +b0 +c5 +a0 +00 +f0 +24 +88 +a9 +fe +d0 +bc +aa +84 +49 +a0 +81 +84 +23 +a0 +8e +84 +22 +a0 +00 +ca +10 +0f +b1 +22 +48 +e6 +22 +d0 +02 +e6 +23 +68 +10 +f4 +30 +ef +c8 +b1 +22 +30 +95 +20 +b2 +90 +d0 +f6 +60 +d0 +06 +20 +20 +8d +4c +93 +8a +20 +9a +8a +20 +79 +04 +20 +4d +8d +20 +20 +8d +4c +dc +8b +6c +08 +03 +20 +73 +04 +20 +25 +8c +20 +c0 +8c +24 +81 +10 +07 +20 +1a +8c +ba +8e +f7 +04 +a0 +00 +20 +a5 +04 +f0 +03 +4c +93 +8c +24 +81 +10 +1f +a0 +02 +20 +a5 +04 +f0 +18 +c8 +20 +a5 +04 +85 +39 +c8 +20 +a5 +04 +85 +3a +98 +18 +65 +3b +85 +3b +90 +c0 +e6 +3c +d0 +bc +4c +7e +86 +a5 +3b +a4 +3c +8d +5b +02 +8c +5c +02 +60 +f0 +fd +2c +eb +02 +10 +13 +24 +81 +10 +0f +48 +a9 +5b +20 +b2 +90 +20 +5b +a4 +a9 +5d +20 +b2 +90 +68 +c9 +fe +f0 +3f +c9 +cb +f0 +2d +c9 +ca +f0 +20 +c9 +fb +b0 +3e +c9 +a3 +90 +06 +c9 +d5 +90 +36 +e9 +32 +38 +e9 +80 +90 +32 +0a +a8 +b9 +84 +83 +48 +b9 +83 +83 +48 +4c +73 +04 +a9 +b6 +48 +a9 +5a +48 +4c +73 +04 +20 +73 +04 +c9 +a4 +d0 +12 +20 +73 +04 +4c +4d +8d +00 +20 +73 +04 +f0 +06 +38 +6c +10 +03 +90 +e4 +4c +a1 +94 +4c +7c +8e +c9 +3a +d0 +f6 +4c +d3 +8b +f0 +15 +20 +e1 +9d +84 +14 +85 +15 +20 +3d +8a +b0 +03 +4c +8f +8d +a5 +5f +a4 +60 +b0 +05 +38 +a5 +2b +a4 +2c +e9 +01 +b0 +01 +88 +85 +41 +84 +42 +60 +20 +e1 +ff +d0 +fa +08 +ac +f3 +04 +c8 +f0 +0b +20 +e1 +ff +f0 +fb +28 +a2 +1e +4c +83 +86 +28 +b0 +01 +18 +d0 +e2 +24 +81 +10 +0d +20 +1a +8c +a5 +39 +a4 +3a +8d +59 +02 +8c +5a +02 +68 +68 +90 +0e +20 +4f +ff +0d +0a +42 +52 +45 +41 +4b +00 +4c +fb +86 +4c +7e +86 +d0 +ba +a2 +1a +ac +5c +02 +d0 +03 +4c +83 +86 +ad +5b +02 +85 +3b +84 +3c +ad +59 +02 +ac +5a +02 +85 +39 +84 +3a +a9 +80 +85 +81 +0a +85 +73 +85 +74 +4c +90 +ff +a0 +05 +20 +05 +89 +88 +a5 +3c +91 +7c +88 +a5 +3b +91 +7c +88 +a5 +3a +91 +7c +88 +a5 +39 +91 +7c +88 +a9 +8d +91 +7c +20 +79 +04 +20 +3e +8e +20 +c1 +8d +38 +a5 +39 +e5 +14 +a5 +3a +e5 +15 +b0 +0b +98 +38 +65 +3b +a6 +3c +90 +07 +e8 +b0 +04 +a5 +2b +a6 +2c +20 +41 +8a +90 +1d +a5 +5f +e9 +01 +85 +3b +a5 +60 +e9 +00 +85 +3c +24 +81 +10 +9e +60 +a9 +8d +85 +02 +20 +71 +88 +f0 +08 +a2 +0c +2c +a2 +11 +4c +83 +86 +20 +69 +a7 +a0 +05 +20 +72 +a7 +88 +b1 +3d +85 +3c +88 +b1 +3d +85 +3b +88 +b1 +3d +20 +7f +cd +b1 +3d +85 +39 +20 +be +8d +98 +18 +65 +3b +85 +3b +90 +02 +e6 +3c +60 +a2 +3a +2c +a2 +00 +86 +07 +a0 +00 +84 +08 +a5 +08 +a6 +07 +85 +07 +86 +08 +20 +a5 +04 +f0 +e7 +c5 +08 +f0 +e3 +c8 +c9 +22 +d0 +f2 +f0 +e8 +20 +2c +93 +20 +79 +04 +c9 +89 +f0 +05 +a9 +a7 +20 +93 +94 +a5 +61 +d0 +1c +20 +b0 +8d +a0 +00 +20 +a5 +04 +f0 +0d +20 +73 +04 +c9 +d5 +d0 +ef +20 +73 +04 +4c +10 +8e +20 +c1 +8d +f0 +a3 +20 +79 +04 +b0 +03 +4c +4d +8d +4c +25 +8c +20 +84 +9d +48 +c9 +8d +f0 +07 +c9 +89 +f0 +03 +4c +a1 +94 +c6 +65 +d0 +04 +68 +4c +3f +8c +20 +73 +04 +20 +3e +8e +c9 +2c +f0 +ee +68 +60 +a2 +00 +86 +08 +86 +14 +86 +15 +b0 +f5 +e6 +08 +e9 +2f +85 +07 +a5 +15 +85 +22 +c9 +19 +b0 +cd +a5 +14 +0a +26 +22 +0a +26 +22 +65 +14 +85 +14 +a5 +22 +65 +15 +85 +15 +06 +14 +26 +15 +a5 +14 +65 +07 +85 +14 +90 +02 +e6 +15 +20 +73 +04 +4c +46 +8e +20 +a5 +96 +85 +49 +84 +4a +a9 +b2 +20 +93 +94 +a5 +0e +48 +a5 +0d +48 +20 +2c +93 +68 +2a +20 +1b +93 +d0 +18 +68 +10 +12 +20 +a0 +a2 +20 +86 +98 +a0 +00 +a5 +64 +91 +49 +c8 +a5 +65 +91 +49 +60 +4c +55 +a2 +68 +a4 +4a +c0 +04 +d0 +72 +20 +4e +9c +c9 +06 +d0 +3e +a0 +00 +84 +61 +84 +66 +84 +71 +20 +f4 +8e +20 +62 +a1 +e6 +71 +a4 +71 +20 +f4 +8e +20 +91 +a2 +aa +f0 +05 +e8 +8a +20 +6d +a1 +a4 +71 +c8 +c0 +06 +d0 +df +20 +62 +a1 +20 +27 +a3 +a6 +64 +a4 +63 +a5 +65 +4c +db +ff +20 +b0 +04 +20 +85 +04 +90 +03 +4c +1c +99 +e9 +2f +4c +0a +a4 +68 +c8 +c5 +34 +90 +18 +d0 +08 +88 +20 +dc +04 +c5 +33 +90 +0e +a4 +65 +c4 +2e +90 +08 +d0 +24 +a5 +64 +c5 +2d +b0 +1e +a5 +64 +a4 +65 +4c +5e +8f +a0 +02 +20 +dc +04 +c5 +7b +d0 +d4 +48 +88 +20 +dc +04 +c5 +7a +d0 +c9 +a5 +79 +f0 +c5 +68 +a0 +00 +20 +dc +04 +20 +54 +9b +a5 +50 +a4 +51 +85 +6f +84 +70 +20 +1b +9c +a5 +6f +a4 +70 +20 +aa +9c +a9 +61 +a0 +00 +85 +50 +84 +51 +85 +22 +84 +23 +20 +aa +9c +20 +9c +8f +90 +0b +a0 +00 +a5 +49 +91 +22 +c8 +a5 +4a +91 +22 +a5 +49 +85 +22 +a5 +4a +85 +23 +20 +9c +8f +90 +09 +88 +a9 +ff +91 +22 +88 +8a +91 +22 +a0 +02 +a9 +50 +20 +94 +04 +91 +49 +88 +10 +f6 +60 +a0 +00 +20 +b0 +04 +48 +f0 +39 +c8 +20 +b0 +04 +aa +c8 +20 +b0 +04 +c5 +38 +90 +06 +d0 +2a +e4 +37 +b0 +26 +20 +b0 +04 +c5 +34 +90 +1f +d0 +04 +e4 +33 +90 +19 +c5 +7b +d0 +04 +e4 +7a +f0 +11 +86 +22 +85 +23 +68 +aa +18 +65 +22 +85 +22 +90 +02 +e6 +23 +38 +60 +68 +18 +60 +20 +e6 +8f +4c +fe +90 +20 +84 +9d +f0 +05 +a9 +2c +20 +93 +94 +08 +86 +13 +20 +97 +a7 +28 +4c +00 +90 +20 +8b +90 +20 +79 +04 +f0 +3c +c9 +fb +d0 +03 +4c +f7 +ae +f0 +43 +c9 +a3 +f0 +50 +c9 +a6 +18 +f0 +4b +c9 +2c +f0 +37 +c9 +3b +f0 +5e +20 +2c +93 +24 +0d +30 +d7 +20 +6f +a4 +20 +74 +9b +20 +8b +90 +20 +a6 +90 +d0 +cc +a9 +00 +9d +00 +02 +a2 +ff +a0 +01 +a5 +13 +d0 +10 +a9 +0d +20 +b2 +90 +24 +13 +10 +05 +a9 +0a +20 +b2 +90 +49 +ff +60 +38 +20 +f0 +ff +98 +38 +e9 +0a +b0 +fc +49 +ff +69 +01 +d0 +16 +08 +38 +20 +f0 +ff +84 +09 +20 +81 +9d +c9 +29 +d0 +13 +28 +90 +06 +8a +e5 +09 +90 +05 +aa +e8 +ca +d0 +09 +20 +73 +04 +4c +09 +90 +4c +a1 +94 +20 +a6 +90 +d0 +ef +20 +74 +9b +20 +4e +9c +aa +a0 +00 +e8 +ca +f0 +b9 +20 +b0 +04 +20 +b2 +90 +c8 +c9 +0d +d0 +f2 +20 +4c +90 +4c +92 +90 +a5 +13 +f0 +03 +a9 +20 +2c +a9 +1d +2c +a9 +3f +20 +8b +a7 +29 +ff +60 +20 +86 +9a +85 +80 +c9 +23 +f0 +0a +c9 +f9 +d0 +16 +20 +73 +04 +4c +db +90 +20 +73 +04 +20 +84 +9d +a9 +2c +20 +93 +94 +86 +13 +20 +a6 +a7 +a2 +01 +a0 +02 +a9 +00 +8d +01 +02 +a9 +40 +20 +58 +91 +a6 +13 +d0 +13 +60 +20 +84 +9d +a9 +2c +20 +93 +94 +86 +13 +20 +a6 +a7 +20 +17 +91 +a5 +13 +20 +cc +ff +a2 +00 +86 +13 +60 +c9 +22 +d0 +0b +20 +4e +94 +a9 +3b +20 +93 +94 +20 +8b +90 +20 +86 +9a +a9 +2c +8d +ff +01 +20 +42 +91 +a5 +13 +f0 +0d +20 +b7 +ff +29 +02 +f0 +06 +20 +fe +90 +4c +b0 +8d +ad +00 +02 +d0 +1e +a5 +13 +d0 +e3 +20 +be +8d +4c +b3 +8d +a5 +13 +d0 +06 +20 +b0 +90 +20 +aa +90 +4c +5a +88 +a6 +41 +a4 +42 +a9 +98 +2c +a9 +00 +85 +11 +86 +43 +84 +44 +20 +a5 +96 +85 +49 +84 +4a +a2 +01 +b5 +3b +95 +4b +b5 +43 +95 +3b +ca +10 +f5 +20 +79 +04 +d0 +31 +24 +11 +50 +1a +a5 +80 +c9 +f9 +d0 +08 +20 +af +a7 +aa +f0 +fa +d0 +03 +20 +af +a7 +8d +00 +02 +a2 +ff +a0 +01 +d0 +0f +10 +03 +4c +40 +92 +a5 +13 +d0 +03 +20 +b0 +90 +20 +42 +91 +86 +3b +84 +3c +20 +73 +04 +24 +0d +10 +31 +24 +11 +50 +09 +e8 +86 +3b +a9 +00 +85 +07 +f0 +0c +85 +07 +c9 +22 +f0 +07 +a9 +3a +85 +07 +a9 +2c +18 +85 +08 +a5 +3b +a4 +3c +69 +00 +90 +01 +c8 +20 +7a +9b +20 +c6 +9d +20 +b1 +8e +4c +e8 +91 +20 +7f +a3 +a5 +0e +20 +99 +8e +20 +79 +04 +f0 +3b +c9 +2c +f0 +37 +a5 +11 +f0 +0a +30 +04 +a6 +13 +d0 +08 +a2 +16 +d0 +06 +a5 +13 +f0 +05 +a2 +18 +4c +83 +86 +20 +4f +ff +3f +52 +45 +44 +4f +20 +46 +52 +4f +4d +20 +53 +54 +41 +52 +54 +0d +00 +ad +5b +02 +ac +5c +02 +85 +3b +84 +3c +60 +a2 +01 +b5 +3b +95 +43 +b5 +4b +95 +3b +ca +10 +f5 +20 +79 +04 +f0 +30 +20 +91 +94 +4c +5e +91 +20 +be +8d +c8 +aa +d0 +15 +a2 +0d +c8 +20 +a5 +04 +f0 +6c +c8 +20 +a5 +04 +85 +3f +c8 +20 +a5 +04 +c8 +85 +40 +20 +b3 +8d +20 +79 +04 +aa +e0 +83 +d0 +d9 +4c +a8 +91 +a5 +43 +a4 +44 +a6 +11 +10 +03 +4c +bb +8c +a0 +00 +20 +55 +81 +f0 +17 +a5 +13 +d0 +13 +20 +4f +ff +3f +45 +58 +54 +52 +41 +20 +49 +47 +4e +4f +52 +45 +44 +0d +00 +60 +d0 +13 +a0 +ff +d0 +14 +a0 +12 +20 +72 +a7 +20 +79 +04 +c9 +2c +d0 +6d +20 +73 +04 +20 +a5 +96 +85 +49 +84 +4a +a0 +81 +84 +02 +20 +71 +88 +f0 +05 +a2 +0a +4c +83 +86 +20 +69 +a7 +a5 +3d +18 +69 +03 +a4 +3e +90 +01 +c8 +20 +1f +a2 +a0 +08 +b1 +3d +85 +66 +a0 +01 +b1 +3d +48 +aa +c8 +b1 +3d +48 +a8 +8a +20 +9b +9e +68 +a8 +68 +aa +20 +59 +a2 +a5 +3d +18 +69 +09 +a4 +3e +90 +01 +c8 +20 +e0 +a2 +a0 +08 +38 +f1 +3d +f0 +9c +a0 +11 +b1 +3d +85 +3b +88 +b1 +3d +85 +3c +88 +b1 +3d +85 +3a +88 +b1 +3d +85 +39 +60 +20 +2c +93 +18 +90 +01 +38 +24 +0d +30 +03 +b0 +03 +60 +b0 +fd +a2 +16 +2c +a2 +19 +4c +83 +86 +a6 +3b +d0 +02 +c6 +3c +c6 +3b +a2 +00 +24 +48 +8a +48 +ba +e0 +28 +90 +e8 +20 +14 +94 +a9 +00 +85 +4d +20 +79 +04 +38 +e9 +b1 +90 +17 +c9 +03 +b0 +13 +c9 +01 +2a +49 +01 +45 +4d +c5 +4d +90 +61 +85 +4d +20 +73 +04 +4c +49 +93 +a6 +4d +d0 +2c +b0 +7e +69 +07 +90 +7a +65 +0d +d0 +03 +4c +da +9b +69 +ff +85 +22 +0a +65 +22 +a8 +68 +d9 +53 +84 +b0 +6a +20 +17 +93 +48 +20 +ae +93 +68 +a4 +4b +10 +17 +aa +f0 +59 +d0 +62 +46 +0d +8a +2a +a6 +3b +d0 +02 +c6 +3c +c6 +3b +a0 +1b +85 +4d +d0 +d7 +d9 +53 +84 +b0 +4b +90 +d9 +b9 +55 +84 +48 +b9 +54 +84 +48 +20 +c1 +93 +a5 +4d +4c +37 +93 +4c +a1 +94 +a5 +66 +be +53 +84 +a8 +18 +68 +69 +01 +85 +22 +68 +69 +00 +85 +23 +98 +48 +20 +a0 +a2 +a5 +65 +48 +a5 +64 +48 +a5 +63 +48 +a5 +62 +48 +a5 +61 +48 +6c +22 +00 +a0 +ff +68 +f0 +23 +c9 +64 +f0 +03 +20 +17 +93 +84 +4b +68 +4a +85 +12 +68 +85 +69 +68 +85 +6a +68 +85 +6b +68 +85 +6c +68 +85 +6d +68 +85 +6e +45 +66 +85 +6f +a5 +61 +60 +6c +0a +03 +a9 +00 +85 +0d +20 +73 +04 +b0 +03 +4c +7f +a3 +20 +3a +97 +90 +03 +4c +ad +94 +c9 +ff +d0 +0f +a9 +39 +a0 +94 +20 +21 +a2 +4c +73 +04 +82 +49 +0f +da +a1 +c9 +2e +f0 +de +c9 +ab +f0 +60 +c9 +aa +f0 +d1 +c9 +22 +d0 +0f +a5 +3b +a4 +3c +69 +00 +90 +01 +c8 +20 +74 +9b +4c +c6 +9d +c9 +a8 +d0 +16 +a0 +18 +d0 +43 +20 +86 +98 +a5 +65 +49 +ff +a8 +a5 +64 +49 +ff +20 +92 +9a +4c +c9 +a2 +c9 +a5 +d0 +03 +4c +de +9a +c9 +b4 +90 +03 +4c +99 +95 +20 +8e +94 +20 +2c +93 +a9 +29 +2c +a9 +28 +2c +a9 +2c +a0 +00 +85 +78 +20 +a5 +04 +c5 +78 +d0 +03 +4c +73 +04 +a2 +0b +4c +83 +86 +a0 +15 +68 +68 +4c +88 +93 +20 +a5 +96 +85 +64 +84 +65 +a6 +45 +a4 +46 +a5 +0d +f0 +45 +a9 +00 +85 +70 +e0 +54 +d0 +24 +c0 +c9 +d0 +76 +a5 +64 +c9 +a2 +d0 +70 +a5 +65 +c9 +04 +d0 +6a +20 +31 +95 +84 +5e +88 +84 +71 +a0 +06 +84 +5d +a0 +24 +20 +fa +a4 +4c +70 +9b +e0 +44 +d0 +52 +c0 +d3 +d0 +4e +20 +fa +94 +a5 +7a +a4 +7b +4c +74 +9b +a5 +79 +d0 +40 +4c +cf +cc +24 +0e +10 +0f +a0 +00 +20 +dc +04 +aa +c8 +20 +dc +04 +a8 +8a +4c +71 +94 +a5 +65 +c9 +04 +d0 +78 +a5 +64 +c9 +a2 +d0 +72 +e0 +54 +d0 +1b +c0 +49 +d0 +6a +20 +31 +95 +98 +a2 +a0 +4c +d4 +a2 +20 +de +ff +86 +64 +84 +63 +85 +65 +a0 +00 +84 +62 +60 +e0 +53 +d0 +0a +c0 +54 +d0 +4b +20 +b7 +ff +4c +c1 +a2 +e0 +44 +d0 +26 +c0 +53 +d0 +3d +20 +fa +94 +a0 +00 +a9 +7a +20 +94 +04 +29 +0f +0a +85 +0f +0a +0a +65 +0f +85 +0f +c8 +a9 +7a +20 +94 +04 +29 +0f +65 +0f +4c +c1 +a2 +e0 +45 +d0 +17 +c0 +52 +f0 +0d +c0 +4c +d0 +0f +ad +f1 +04 +ac +f0 +04 +4c +76 +9a +ad +ef +04 +4c +c1 +a2 +a5 +64 +a4 +65 +4c +1f +a2 +c9 +d5 +b0 +58 +c9 +cb +90 +02 +e9 +01 +48 +aa +20 +73 +04 +e0 +d3 +f0 +08 +e0 +cb +b0 +29 +e0 +c8 +90 +25 +20 +8e +94 +20 +2c +93 +20 +91 +94 +20 +1a +93 +68 +c9 +d3 +f0 +2d +aa +a5 +65 +48 +a5 +64 +48 +8a +48 +20 +84 +9d +68 +a8 +8a +48 +98 +4c +dd +95 +20 +85 +94 +68 +38 +e9 +b4 +0a +a8 +b9 +16 +84 +85 +56 +b9 +15 +84 +85 +55 +20 +54 +00 +4c +17 +93 +4c +86 +b3 +4c +a1 +94 +a0 +ff +2c +a0 +00 +84 +0b +20 +86 +98 +a5 +64 +45 +0b +85 +07 +a5 +65 +45 +0b +85 +08 +20 +81 +a2 +20 +86 +98 +a5 +65 +45 +0b +25 +08 +45 +0b +a8 +a5 +64 +45 +0b +25 +07 +45 +0b +4c +71 +94 +20 +1b +93 +b0 +13 +a5 +6e +09 +7f +25 +6a +85 +6a +a9 +69 +a0 +00 +20 +e0 +a2 +aa +4c +73 +96 +a9 +00 +85 +0d +c6 +4d +20 +4e +9c +85 +61 +86 +62 +84 +63 +a5 +6c +a4 +6d +20 +52 +9c +86 +6c +84 +6d +aa +38 +e5 +61 +f0 +08 +a9 +01 +90 +04 +a6 +61 +a9 +ff +85 +66 +a0 +ff +e8 +c8 +ca +d0 +07 +a6 +66 +30 +17 +18 +90 +14 +20 +85 +81 +48 +20 +7d +81 +85 +78 +68 +c5 +78 +f0 +e7 +a2 +ff +b0 +02 +a2 +01 +e8 +8a +2a +25 +12 +f0 +02 +a9 +ff +4c +c1 +a2 +20 +91 +94 +aa +20 +aa +96 +20 +79 +04 +d0 +f4 +60 +a2 +00 +20 +79 +04 +86 +0c +85 +45 +20 +79 +04 +20 +3a +97 +b0 +03 +4c +a1 +94 +a2 +00 +86 +0d +86 +0e +20 +73 +04 +90 +05 +20 +3a +97 +90 +0b +aa +20 +73 +04 +90 +fb +20 +3a +97 +b0 +f6 +c9 +24 +d0 +06 +a9 +ff +85 +0d +d0 +10 +c9 +25 +d0 +13 +a5 +10 +d0 +d0 +a9 +80 +85 +0e +05 +45 +85 +45 +8a +09 +80 +aa +20 +73 +04 +86 +46 +38 +05 +10 +e9 +28 +d0 +03 +4c +9b +98 +a0 +00 +84 +10 +a5 +2d +a6 +2e +86 +60 +85 +5f +e4 +30 +d0 +04 +c5 +2f +f0 +2f +20 +d1 +04 +85 +78 +a5 +45 +c5 +78 +d0 +10 +c8 +20 +d1 +04 +85 +78 +a5 +46 +c5 +78 +d0 +03 +4c +4c +98 +88 +18 +a5 +5f +69 +07 +90 +d4 +e8 +d0 +cf +c9 +41 +90 +05 +e9 +5b +38 +e9 +a5 +60 +68 +48 +c9 +af +d0 +2a +a9 +a2 +a0 +04 +60 +c0 +c9 +f0 +f7 +c0 +49 +d0 +31 +f0 +18 +c0 +d3 +f0 +14 +c0 +53 +d0 +27 +f0 +0e +c0 +54 +d0 +21 +f0 +08 +c0 +52 +f0 +04 +c0 +4c +d0 +17 +4c +a1 +94 +a5 +45 +a4 +46 +c9 +54 +f0 +d3 +c9 +53 +f0 +e3 +c9 +45 +f0 +e5 +c9 +44 +f0 +d1 +a5 +2f +a4 +30 +85 +5f +84 +60 +a5 +31 +a4 +32 +85 +5a +84 +5b +18 +69 +07 +90 +01 +c8 +85 +58 +84 +59 +20 +c0 +88 +a5 +58 +a4 +59 +c8 +85 +2f +84 +30 +85 +58 +84 +59 +a5 +58 +a6 +59 +e4 +32 +d0 +06 +c5 +31 +d0 +02 +f0 +78 +85 +22 +86 +23 +a0 +00 +20 +b0 +04 +aa +c8 +20 +b0 +04 +08 +c8 +20 +b0 +04 +65 +58 +85 +58 +c8 +20 +b0 +04 +65 +59 +85 +59 +28 +10 +d0 +8a +30 +cd +c8 +20 +b0 +04 +a0 +00 +0a +69 +05 +65 +22 +85 +22 +90 +02 +e6 +23 +a6 +23 +e4 +59 +d0 +04 +c5 +58 +f0 +b6 +a0 +00 +20 +b0 +04 +f0 +24 +85 +78 +c8 +20 +b0 +04 +18 +65 +78 +85 +5a +c8 +20 +b0 +04 +69 +00 +85 +5b +a0 +00 +20 +89 +81 +69 +07 +91 +5a +c8 +20 +89 +81 +69 +00 +91 +5a +a9 +03 +18 +65 +22 +85 +22 +90 +c2 +e6 +23 +d0 +be +a0 +00 +a5 +45 +91 +5f +c8 +a5 +46 +91 +5f +a9 +00 +c8 +91 +5f +c0 +06 +d0 +f9 +a5 +5f +18 +69 +02 +a4 +60 +90 +01 +c8 +85 +47 +84 +48 +60 +a5 +0b +0a +69 +05 +65 +5f +a4 +60 +90 +01 +c8 +85 +58 +84 +59 +60 +90 +80 +00 +00 +00 +20 +86 +98 +a5 +64 +a4 +65 +60 +20 +73 +04 +20 +2c +93 +20 +17 +93 +a5 +66 +30 +0d +a5 +61 +c9 +90 +90 +0c +a9 +6c +a0 +98 +20 +e0 +a2 +d0 +03 +4c +1c +99 +4c +27 +a3 +a5 +0c +05 +0e +48 +a5 +0d +48 +a0 +00 +98 +48 +a5 +46 +48 +a5 +45 +48 +20 +79 +98 +68 +85 +45 +68 +85 +46 +68 +a8 +ba +bd +02 +01 +48 +bd +01 +01 +48 +a5 +64 +9d +02 +01 +a5 +65 +9d +01 +01 +c8 +84 +0b +20 +79 +04 +a4 +0b +c9 +2c +f0 +ce +20 +8b +94 +68 +85 +0d +68 +85 +0e +29 +7f +85 +0c +a6 +2f +a5 +30 +86 +5f +85 +60 +c5 +32 +d0 +04 +e4 +31 +f0 +46 +a0 +00 +20 +d1 +04 +c8 +c5 +45 +d0 +0b +20 +d1 +04 +85 +78 +a5 +46 +c5 +78 +f0 +18 +c8 +20 +d1 +04 +18 +65 +5f +aa +c8 +20 +d1 +04 +65 +60 +90 +cf +a2 +12 +2c +a2 +0e +4c +83 +86 +a2 +13 +a5 +0c +d0 +f7 +20 +5b +98 +a0 +04 +20 +d1 +04 +85 +78 +a5 +0b +c5 +78 +d0 +e2 +4c +c3 +99 +20 +5b +98 +20 +23 +89 +a0 +00 +84 +72 +a2 +05 +a5 +45 +91 +5f +10 +01 +ca +c8 +a5 +46 +91 +5f +10 +02 +ca +ca +86 +71 +a5 +0b +c8 +c8 +c8 +91 +5f +a2 +0b +a9 +00 +24 +0c +50 +08 +68 +18 +69 +01 +aa +68 +69 +00 +c8 +91 +5f +c8 +8a +91 +5f +20 +2f +9a +86 +71 +85 +72 +a4 +22 +c6 +0b +d0 +dc +65 +59 +b0 +67 +85 +59 +a8 +8a +65 +58 +90 +03 +c8 +f0 +5c +20 +23 +89 +85 +31 +84 +32 +a9 +00 +e6 +72 +a4 +71 +f0 +05 +88 +91 +58 +d0 +fb +c6 +59 +c6 +72 +d0 +f5 +e6 +59 +38 +a5 +31 +e5 +5f +a0 +02 +91 +5f +a5 +32 +c8 +e5 +60 +91 +5f +a5 +0c +d0 +6c +c8 +20 +d1 +04 +85 +0b +a9 +00 +85 +71 +85 +72 +c8 +68 +aa +85 +64 +20 +d1 +04 +85 +78 +68 +85 +65 +c5 +78 +90 +12 +d0 +0a +c8 +20 +d1 +04 +85 +78 +e4 +78 +90 +07 +4c +19 +99 +4c +81 +86 +c8 +a5 +72 +05 +71 +18 +f0 +0a +20 +2f +9a +8a +65 +64 +aa +98 +a4 +22 +65 +65 +86 +71 +c6 +0b +d0 +c1 +85 +72 +a2 +05 +a5 +45 +10 +01 +ca +a5 +46 +10 +02 +ca +ca +86 +28 +a9 +00 +20 +3a +9a +8a +65 +58 +85 +47 +98 +65 +59 +85 +48 +a8 +a5 +47 +60 +84 +22 +20 +d1 +04 +85 +28 +88 +20 +d1 +04 +85 +29 +a9 +10 +85 +5d +a2 +00 +a0 +00 +8a +0a +aa +98 +2a +a8 +b0 +a2 +06 +71 +26 +72 +90 +0b +18 +8a +65 +28 +aa +98 +65 +29 +a8 +b0 +91 +c6 +5d +d0 +e3 +60 +a5 +0d +f0 +03 +20 +4e +9c +20 +54 +a9 +38 +a5 +33 +e5 +31 +a8 +a5 +34 +e5 +32 +20 +92 +9a +38 +4c +ce +a2 +38 +20 +f0 +ff +a9 +00 +4c +71 +94 +24 +81 +30 +a4 +a2 +15 +2c +a2 +1b +4c +83 +86 +a2 +00 +86 +0d +85 +62 +84 +63 +a2 +90 +60 +20 +cb +9a +20 +86 +9a +20 +8e +94 +a9 +80 +85 +10 +20 +a5 +96 +20 +17 +93 +20 +8b +94 +a9 +b2 +20 +93 +94 +48 +a5 +48 +48 +a5 +47 +48 +a5 +3c +48 +a5 +3b +48 +20 +b0 +8d +4c +3e +9b +a9 +a5 +20 +93 +94 +09 +80 +85 +10 +20 +ac +96 +85 +4e +84 +4f +4c +17 +93 +20 +cb +9a +a5 +4f +48 +a5 +4e +48 +20 +85 +94 +20 +17 +93 +68 +85 +4e +68 +85 +4f +a0 +02 +20 +59 +81 +85 +47 +aa +c8 +20 +59 +81 +f0 +8c +85 +48 +c8 +20 +61 +81 +48 +88 +10 +f9 +a4 +48 +20 +59 +a2 +a5 +3c +48 +a5 +3b +48 +20 +59 +81 +85 +3b +c8 +20 +59 +81 +85 +3c +a5 +48 +48 +a5 +47 +48 +20 +14 +93 +68 +85 +4e +68 +85 +4f +20 +79 +04 +f0 +03 +4c +a1 +94 +68 +85 +3b +68 +85 +3c +a0 +00 +68 +91 +4e +68 +c8 +91 +4e +68 +c8 +91 +4e +68 +c8 +91 +4e +68 +c8 +91 +4e +60 +a6 +64 +a4 +65 +86 +50 +84 +51 +20 +06 +a9 +86 +62 +84 +63 +85 +61 +60 +20 +17 +93 +a0 +00 +20 +71 +a4 +68 +68 +a9 +ff +a0 +00 +a2 +22 +86 +07 +86 +08 +85 +6f +84 +70 +85 +62 +84 +63 +a0 +ff +c8 +20 +c6 +04 +f0 +0c +c5 +07 +f0 +04 +c5 +08 +d0 +f2 +c9 +22 +f0 +01 +18 +84 +61 +98 +65 +6f +85 +71 +a6 +70 +90 +01 +e8 +86 +72 +98 +20 +54 +9b +a6 +6f +a4 +70 +20 +2c +9c +a6 +16 +e0 +22 +d0 +05 +a2 +19 +4c +83 +86 +a5 +61 +95 +00 +a5 +62 +95 +01 +a5 +63 +95 +02 +a0 +00 +86 +64 +84 +65 +84 +70 +88 +84 +0d +86 +17 +e8 +e8 +e8 +86 +16 +60 +a5 +65 +48 +a5 +64 +48 +20 +14 +94 +20 +1a +93 +68 +85 +6f +68 +85 +70 +a0 +00 +20 +c6 +04 +85 +78 +20 +dc +04 +18 +65 +78 +90 +03 +4c +4c +cc +20 +54 +9b +20 +1b +9c +a5 +50 +a4 +51 +20 +52 +9c +20 +30 +9c +a5 +6f +a4 +70 +20 +52 +9c +20 +b0 +9b +4c +46 +93 +a0 +00 +20 +c6 +04 +48 +c8 +20 +c6 +04 +aa +c8 +20 +c6 +04 +a8 +68 +86 +22 +84 +23 +a8 +f0 +0b +48 +88 +20 +b0 +04 +91 +35 +98 +d0 +f7 +68 +18 +65 +35 +85 +35 +90 +02 +e6 +36 +60 +20 +2c +93 +20 +1a +93 +a5 +64 +a4 +65 +85 +22 +84 +23 +20 +aa +9c +d0 +39 +20 +9c +8f +90 +34 +88 +a9 +ff +91 +22 +88 +8a +91 +22 +48 +49 +ff +38 +65 +22 +a4 +23 +b0 +01 +88 +85 +22 +84 +23 +aa +68 +c4 +34 +d0 +3c +e4 +33 +d0 +38 +48 +38 +65 +33 +85 +33 +90 +02 +e6 +34 +e6 +33 +d0 +02 +e6 +34 +68 +60 +a0 +00 +20 +b0 +04 +48 +c8 +20 +b0 +04 +aa +c8 +20 +b0 +04 +a8 +86 +22 +84 +23 +68 +60 +c4 +18 +d0 +0c +c5 +17 +d0 +08 +85 +16 +e9 +03 +85 +17 +a0 +00 +60 +20 +87 +9d +8a +48 +a9 +01 +20 +5c +9b +68 +a0 +00 +91 +62 +68 +68 +4c +b0 +9b +20 +46 +9d +48 +20 +81 +81 +85 +78 +68 +c5 +78 +98 +90 +05 +20 +81 +81 +aa +98 +48 +8a +48 +20 +5c +9b +a5 +50 +a4 +51 +20 +52 +9c +68 +a8 +68 +18 +65 +22 +85 +22 +90 +02 +e6 +23 +98 +20 +30 +9c +4c +b0 +9b +20 +46 +9d +48 +20 +81 +81 +85 +78 +68 +18 +e5 +78 +49 +ff +4c +dc +9c +a9 +ff +85 +65 +20 +79 +04 +c9 +29 +f0 +06 +20 +91 +94 +20 +84 +9d +20 +46 +9d +f0 +53 +ca +8a +48 +a2 +00 +48 +20 +81 +81 +85 +78 +68 +18 +e5 +78 +b0 +a8 +49 +ff +c5 +65 +90 +a3 +a5 +65 +b0 +9f +20 +8b +94 +68 +a8 +68 +85 +55 +68 +68 +68 +aa +68 +85 +50 +68 +85 +51 +a5 +55 +48 +98 +48 +a0 +00 +8a +60 +20 +67 +9d +4c +81 +9a +20 +4b +9c +a2 +00 +86 +0d +a8 +60 +20 +67 +9d +f0 +06 +a0 +00 +20 +b0 +04 +a8 +4c +81 +9a +4c +1c +99 +20 +73 +04 +20 +14 +93 +20 +7f +98 +a6 +64 +d0 +f0 +a6 +65 +4c +79 +04 +20 +67 +9d +f0 +37 +a6 +3b +a4 +3c +86 +71 +84 +72 +a6 +22 +86 +3b +18 +65 +22 +85 +24 +a6 +23 +86 +3c +90 +01 +e8 +86 +25 +a0 +00 +20 +bb +04 +48 +98 +91 +24 +20 +79 +04 +20 +7f +a3 +68 +a0 +00 +91 +24 +a6 +71 +a4 +72 +86 +3b +84 +3c +60 +4c +2b +9f +20 +14 +93 +20 +e4 +9d +20 +91 +94 +4c +84 +9d +20 +91 +94 +20 +14 +93 +a5 +66 +30 +96 +a5 +61 +c9 +91 +b0 +90 +20 +27 +a3 +a5 +64 +a4 +65 +84 +14 +85 +15 +60 +a5 +15 +48 +a5 +14 +48 +20 +e4 +9d +a0 +00 +20 +5d +81 +a8 +68 +85 +14 +68 +85 +15 +4c +81 +9a +20 +d2 +9d +8a +a0 +00 +91 +14 +60 +20 +67 +9d +85 +24 +a0 +00 +84 +25 +84 +71 +84 +72 +c4 +24 +f0 +34 +20 +b0 +04 +c8 +c9 +20 +f0 +f4 +e6 +25 +a6 +25 +e0 +05 +f0 +2b +c9 +30 +90 +27 +c9 +3a +90 +0a +c9 +41 +90 +1f +c9 +47 +b0 +1b +e9 +07 +e9 +2f +0a +0a +0a +0a +a2 +04 +0a +26 +71 +26 +72 +ca +d0 +f8 +f0 +c8 +a4 +71 +a5 +72 +4c +76 +9a +4c +1c +99 +20 +d2 +9d +86 +49 +a2 +00 +20 +79 +04 +f0 +03 +20 +d8 +9d +86 +4a +a0 +00 +20 +5d +81 +45 +4a +25 +49 +f0 +f7 +60 +a5 +66 +49 +ff +85 +66 +45 +6e +85 +6f +a5 +61 +4c +9e +9e +20 +cd +9f +90 +3c +20 +07 +a1 +d0 +03 +4c +81 +a2 +a6 +70 +86 +56 +a2 +69 +a5 +69 +a8 +f0 +d8 +38 +e5 +61 +f0 +24 +90 +12 +84 +61 +a4 +6e +84 +66 +49 +ff +69 +00 +a0 +00 +84 +56 +a2 +61 +d0 +04 +a0 +00 +84 +70 +c9 +f9 +30 +c7 +a8 +a5 +70 +56 +01 +20 +e4 +9f +24 +6f +10 +57 +a0 +61 +e0 +69 +f0 +02 +a0 +69 +38 +49 +ff +65 +56 +85 +70 +b9 +04 +00 +f5 +04 +85 +65 +b9 +03 +00 +f5 +03 +85 +64 +b9 +02 +00 +f5 +02 +85 +63 +b9 +01 +00 +f5 +01 +85 +62 +b0 +03 +20 +7b +9f +a0 +00 +98 +18 +a6 +62 +d0 +4a +a6 +63 +86 +62 +a6 +64 +86 +63 +a6 +65 +86 +64 +a6 +70 +86 +65 +84 +70 +69 +08 +c9 +20 +d0 +e4 +a9 +00 +85 +61 +85 +66 +60 +65 +56 +85 +70 +a5 +65 +65 +6d +85 +65 +a5 +64 +65 +6c +85 +64 +a5 +63 +65 +6b +85 +63 +a5 +62 +65 +6a +85 +62 +4c +6a +9f +69 +01 +06 +70 +26 +65 +26 +64 +26 +63 +26 +62 +10 +f2 +38 +e5 +61 +b0 +c7 +49 +ff +69 +01 +85 +61 +90 +0e +e6 +61 +f0 +42 +66 +62 +66 +63 +66 +64 +66 +65 +66 +70 +60 +a5 +66 +49 +ff +85 +66 +a5 +62 +49 +ff +85 +62 +a5 +63 +49 +ff +85 +63 +a5 +64 +49 +ff +85 +64 +a5 +65 +49 +ff +85 +65 +a5 +70 +49 +ff +85 +70 +e6 +70 +d0 +0e +e6 +65 +d0 +0a +e6 +64 +d0 +06 +e6 +63 +d0 +02 +e6 +62 +60 +a2 +0f +4c +83 +86 +a2 +25 +b4 +04 +84 +70 +b4 +03 +94 +04 +b4 +02 +94 +03 +b4 +01 +94 +02 +a4 +68 +94 +01 +69 +08 +30 +e8 +f0 +e6 +e9 +08 +a8 +a5 +70 +b0 +14 +16 +01 +90 +02 +f6 +01 +76 +01 +76 +01 +76 +02 +76 +03 +76 +04 +6a +c8 +d0 +ec +18 +60 +81 +00 +00 +00 +00 +03 +7f +5e +56 +cb +79 +80 +13 +9b +0b +64 +80 +76 +38 +93 +16 +82 +38 +aa +3b +20 +80 +35 +04 +f3 +34 +81 +35 +04 +f3 +34 +80 +80 +00 +00 +00 +80 +31 +72 +17 +f8 +20 +b0 +a2 +f0 +02 +10 +03 +4c +1c +99 +a5 +61 +e9 +7f +48 +a9 +80 +85 +61 +a9 +0a +a0 +a0 +20 +66 +a0 +a9 +0f +a0 +a0 +20 +72 +a0 +a9 +f0 +a0 +9f +20 +6c +a0 +a9 +f5 +a0 +9f +20 +b3 +a6 +a9 +14 +a0 +a0 +20 +66 +a0 +68 +20 +0a +a4 +a9 +19 +a0 +a0 +20 +dc +a0 +4c +7b +a0 +a9 +a3 +a0 +a5 +20 +dc +a0 +4c +9e +9e +20 +dc +a0 +4c +87 +9e +20 +dc +a0 +4c +97 +a1 +20 +07 +a1 +d0 +03 +4c +db +a0 +20 +37 +a1 +a9 +00 +85 +26 +85 +27 +85 +28 +85 +29 +a5 +70 +20 +a9 +a0 +a5 +65 +20 +a9 +a0 +a5 +64 +20 +a9 +a0 +a5 +63 +20 +a9 +a0 +a5 +62 +20 +ae +a0 +4c +0c +a2 +d0 +03 +4c +b7 +9f +4a +09 +80 +a8 +90 +19 +18 +a5 +29 +65 +6d +85 +29 +a5 +28 +65 +6c +85 +28 +a5 +27 +65 +6b +85 +27 +a5 +26 +65 +6a +85 +26 +66 +26 +66 +27 +66 +28 +66 +29 +66 +70 +98 +4a +d0 +d6 +60 +85 +22 +84 +23 +a0 +04 +b1 +22 +85 +6d +88 +b1 +22 +85 +6c +88 +b1 +22 +85 +6b +88 +b1 +22 +85 +6e +45 +66 +85 +6f +a5 +6e +09 +80 +85 +6a +88 +b1 +22 +85 +69 +a5 +61 +60 +85 +22 +84 +23 +a0 +04 +20 +b0 +04 +85 +6d +88 +20 +b0 +04 +85 +6c +88 +20 +b0 +04 +85 +6b +88 +20 +b0 +04 +85 +6e +45 +66 +85 +6f +a5 +6e +09 +80 +85 +6a +88 +20 +b0 +04 +85 +69 +a5 +61 +60 +a5 +69 +f0 +1f +18 +65 +61 +90 +04 +30 +1d +18 +2c +10 +14 +69 +80 +85 +61 +d0 +03 +4c +2f +9f +a5 +6f +85 +66 +60 +a5 +66 +49 +ff +30 +05 +68 +68 +4c +2b +9f +4c +b2 +9f +20 +91 +a2 +aa +f0 +10 +18 +69 +02 +b0 +f2 +a2 +00 +86 +6f +20 +ab +9e +e6 +61 +f0 +e7 +60 +84 +20 +00 +00 +00 +a2 +14 +4c +83 +86 +20 +91 +a2 +a9 +79 +a0 +a1 +a2 +00 +86 +6f +20 +21 +a2 +4c +97 +a1 +20 +07 +a1 +f0 +e5 +20 +a0 +a2 +a9 +00 +38 +e5 +61 +85 +61 +20 +37 +a1 +e6 +61 +f0 +b5 +a2 +fc +a9 +01 +a4 +6a +c4 +62 +d0 +10 +a4 +6b +c4 +63 +d0 +0a +a4 +6c +c4 +64 +d0 +04 +a4 +6d +c4 +65 +08 +2a +90 +09 +e8 +95 +29 +f0 +32 +10 +34 +a9 +01 +28 +b0 +0e +06 +6d +26 +6c +26 +6b +26 +6a +b0 +e6 +30 +ce +10 +e2 +a8 +a5 +6d +e5 +65 +85 +6d +a5 +6c +e5 +64 +85 +6c +a5 +6b +e5 +63 +85 +6b +a5 +6a +e5 +62 +85 +6a +98 +4c +d4 +a1 +a9 +40 +d0 +ce +0a +0a +0a +0a +0a +0a +85 +70 +28 +a5 +26 +85 +62 +a5 +27 +85 +63 +a5 +28 +85 +64 +a5 +29 +85 +65 +4c +0b +9f +18 +24 +38 +85 +22 +84 +23 +a0 +04 +20 +20 +a3 +85 +65 +88 +20 +20 +a3 +85 +64 +88 +20 +20 +a3 +85 +63 +88 +20 +20 +a3 +85 +66 +09 +80 +85 +62 +88 +20 +20 +a3 +85 +61 +84 +70 +60 +a2 +5c +2c +a2 +57 +a0 +00 +f0 +04 +a6 +49 +a4 +4a +20 +a0 +a2 +86 +22 +84 +23 +a0 +04 +a5 +65 +91 +22 +88 +a5 +64 +91 +22 +88 +a5 +63 +91 +22 +88 +a5 +66 +09 +7f +25 +62 +91 +22 +88 +a5 +61 +91 +22 +84 +70 +60 +a5 +6e +85 +66 +a2 +05 +b5 +68 +95 +60 +ca +d0 +f9 +86 +70 +60 +20 +a0 +a2 +a2 +06 +b5 +60 +95 +68 +ca +d0 +f9 +86 +70 +60 +a5 +61 +f0 +fb +06 +70 +90 +f7 +20 +a3 +9f +d0 +f2 +4c +6c +9f +a5 +61 +f0 +09 +a5 +66 +2a +a9 +ff +b0 +02 +a9 +01 +60 +20 +b0 +a2 +85 +62 +a9 +00 +85 +63 +a2 +88 +a5 +62 +49 +ff +2a +a9 +00 +85 +65 +85 +64 +86 +61 +85 +70 +85 +66 +4c +06 +9f +46 +66 +60 +85 +24 +84 +25 +a0 +00 +b1 +24 +c8 +aa +f0 +c4 +b1 +24 +45 +66 +30 +c2 +e4 +61 +d0 +21 +b1 +24 +09 +80 +c5 +62 +d0 +19 +c8 +b1 +24 +c5 +63 +d0 +12 +c8 +b1 +24 +c5 +64 +d0 +0b +c8 +a9 +7f +c5 +70 +b1 +24 +e5 +65 +f0 +2f +a5 +66 +90 +02 +49 +ff +4c +b6 +a2 +b1 +22 +b0 +22 +4c +b0 +04 +a5 +61 +f0 +4a +38 +e9 +a0 +24 +66 +10 +09 +aa +a9 +ff +85 +68 +20 +81 +9f +8a +a2 +61 +c9 +f9 +10 +06 +20 +cd +9f +84 +68 +60 +a8 +a5 +66 +29 +80 +46 +62 +05 +62 +85 +62 +20 +e4 +9f +84 +68 +60 +a5 +61 +c9 +a0 +b0 +20 +20 +27 +a3 +84 +70 +a5 +66 +84 +66 +49 +80 +2a +a9 +a0 +85 +61 +a5 +65 +85 +07 +4c +06 +9f +85 +62 +85 +63 +85 +64 +85 +65 +a8 +60 +a0 +00 +a2 +0a +94 +5d +ca +10 +fb +90 +0f +c9 +2d +d0 +04 +86 +67 +f0 +04 +c9 +2b +d0 +05 +20 +73 +04 +90 +5b +c9 +2e +f0 +2e +c9 +45 +d0 +30 +20 +73 +04 +90 +17 +c9 +ab +f0 +0e +c9 +2d +f0 +0a +c9 +aa +f0 +08 +c9 +2b +f0 +04 +d0 +07 +66 +60 +20 +73 +04 +90 +5c +24 +60 +10 +0e +a9 +00 +38 +e5 +5e +4c +d5 +a3 +66 +5f +24 +5f +50 +c3 +a5 +5e +38 +e5 +5d +85 +5e +f0 +12 +10 +09 +20 +83 +a1 +e6 +5e +d0 +f9 +f0 +07 +20 +62 +a1 +c6 +5e +d0 +f9 +a5 +67 +30 +01 +60 +4c +27 +a6 +48 +24 +5f +10 +02 +e6 +5d +20 +62 +a1 +68 +38 +e9 +30 +20 +0a +a4 +4c +96 +a3 +48 +20 +91 +a2 +68 +20 +c1 +a2 +a5 +6e +45 +66 +85 +6f +a6 +61 +4c +9e +9e +a5 +5e +c9 +0a +90 +09 +a9 +64 +24 +60 +30 +16 +4c +b2 +9f +0a +0a +18 +65 +5e +0a +18 +a0 +00 +85 +78 +20 +a5 +04 +65 +78 +38 +e9 +30 +85 +5e +4c +bc +a3 +9b +3e +bc +1f +fd +9e +6e +6b +27 +fd +9e +6e +6b +28 +00 +20 +4f +ff +20 +49 +4e +20 +00 +a5 +3a +a6 +39 +85 +62 +86 +63 +a2 +90 +38 +20 +ce +a2 +20 +71 +a4 +4c +88 +90 +a0 +01 +a9 +20 +24 +66 +10 +02 +a9 +2d +99 +ff +00 +85 +66 +84 +71 +c8 +a9 +30 +a6 +61 +d0 +03 +4c +96 +a5 +a9 +00 +e0 +80 +f0 +02 +b0 +09 +a9 +4e +a0 +a4 +20 +5c +a0 +a9 +f7 +85 +5d +a9 +49 +a0 +a4 +20 +e0 +a2 +f0 +1e +10 +12 +a9 +44 +a0 +a4 +20 +e0 +a2 +f0 +02 +10 +0e +20 +62 +a1 +c6 +5d +d0 +ee +20 +83 +a1 +e6 +5d +d0 +dc +20 +62 +a0 +20 +27 +a3 +a2 +01 +a5 +5d +18 +69 +0a +30 +09 +c9 +0b +b0 +06 +69 +ff +aa +a9 +02 +38 +e9 +02 +85 +5e +86 +5d +8a +f0 +02 +10 +13 +a4 +71 +a9 +2e +c8 +99 +ff +00 +8a +f0 +06 +a9 +30 +c8 +99 +ff +00 +84 +71 +a0 +00 +a2 +80 +a5 +65 +18 +79 +ab +a5 +85 +65 +a5 +64 +79 +aa +a5 +85 +64 +a5 +63 +79 +a9 +a5 +85 +63 +a5 +62 +79 +a8 +a5 +85 +62 +e8 +b0 +04 +10 +de +30 +02 +30 +da +8a +90 +04 +49 +ff +69 +0a +69 +2f +c8 +c8 +c8 +c8 +84 +47 +a4 +71 +c8 +aa +29 +7f +99 +ff +00 +c6 +5d +d0 +06 +a9 +2e +c8 +99 +ff +00 +84 +71 +a4 +47 +8a +49 +ff +29 +80 +aa +c0 +24 +f0 +04 +c0 +3c +d0 +a6 +a4 +71 +b9 +ff +00 +88 +c9 +30 +f0 +f8 +c9 +2e +f0 +01 +c8 +a9 +2b +a6 +5e +f0 +2e +10 +08 +a9 +00 +38 +e5 +5e +aa +a9 +2d +99 +01 +01 +a9 +45 +99 +00 +01 +8a +a2 +2f +38 +e8 +e9 +0a +b0 +fb +69 +3a +99 +03 +01 +8a +99 +02 +01 +a9 +00 +99 +04 +01 +f0 +08 +99 +ff +00 +a9 +00 +99 +00 +01 +a9 +00 +a0 +01 +60 +80 +00 +00 +00 +00 +fa +0a +1f +00 +00 +98 +96 +80 +ff +f0 +bd +c0 +00 +01 +86 +a0 +ff +ff +d8 +f0 +00 +00 +03 +e8 +ff +ff +ff +9c +00 +00 +00 +0a +ff +ff +ff +ff +ff +df +0a +80 +00 +03 +4b +c0 +ff +ff +73 +60 +00 +00 +0e +10 +ff +ff +fd +a8 +00 +00 +00 +3c +20 +91 +a2 +a9 +a3 +a0 +a5 +20 +21 +a2 +f0 +70 +a5 +69 +d0 +03 +4c +2d +9f +a2 +4e +a0 +00 +20 +59 +a2 +a5 +6e +10 +0f +20 +58 +a3 +a9 +4e +a0 +00 +20 +e0 +a2 +d0 +03 +98 +a4 +07 +20 +83 +a2 +98 +48 +20 +1e +a0 +a9 +4e +a0 +00 +20 +78 +a0 +20 +60 +a6 +68 +4a +90 +0a +a5 +61 +f0 +06 +a5 +66 +49 +ff +85 +66 +60 +81 +38 +aa +3b +29 +07 +71 +34 +58 +3e +56 +74 +16 +7e +b3 +1b +77 +2f +ee +e3 +85 +7a +1d +84 +1c +2a +7c +63 +59 +58 +0a +7e +75 +fd +e7 +c6 +80 +31 +72 +18 +10 +81 +00 +00 +00 +00 +a9 +32 +a0 +a6 +20 +5c +a0 +a5 +70 +69 +50 +90 +03 +20 +a8 +a2 +85 +56 +20 +94 +a2 +a5 +61 +c9 +88 +90 +03 +20 +54 +a1 +20 +58 +a3 +a5 +07 +18 +69 +81 +f0 +f3 +38 +e9 +01 +48 +a2 +05 +b5 +69 +b4 +61 +95 +61 +94 +69 +ca +10 +f5 +a5 +56 +85 +70 +20 +87 +9e +20 +27 +a6 +a9 +37 +a0 +a6 +20 +c9 +a6 +a9 +00 +85 +6f +68 +20 +39 +a1 +60 +85 +71 +84 +72 +20 +4f +a2 +a9 +57 +20 +78 +a0 +20 +cd +a6 +a9 +57 +a0 +00 +4c +78 +a0 +85 +71 +84 +72 +20 +4c +a2 +b1 +71 +85 +67 +a4 +71 +c8 +98 +d0 +02 +e6 +72 +85 +71 +a4 +72 +20 +5c +a0 +a5 +71 +a4 +72 +18 +69 +05 +90 +01 +c8 +85 +71 +84 +72 +20 +66 +a0 +a9 +5c +a0 +00 +c6 +67 +d0 +e4 +60 +98 +35 +44 +7a +00 +68 +28 +b1 +46 +00 +20 +b0 +a2 +30 +2e +d0 +17 +ad +00 +ff +85 +62 +ad +01 +ff +85 +64 +ad +02 +ff +85 +63 +ad +03 +ff +85 +65 +4c +4a +a7 +a9 +03 +a0 +05 +20 +21 +a2 +a9 +fd +a0 +a6 +20 +5c +a0 +a9 +02 +a0 +a7 +20 +66 +a0 +a6 +65 +a5 +62 +85 +65 +86 +62 +a6 +63 +a5 +64 +85 +63 +86 +64 +a9 +00 +85 +66 +a5 +61 +85 +70 +a9 +80 +85 +61 +20 +0b +9f +a2 +03 +a0 +05 +4c +59 +a2 +a5 +7c +85 +3d +a5 +7d +85 +3e +60 +a5 +3d +85 +7c +a5 +3e +85 +7d +60 +98 +18 +65 +7c +85 +7c +90 +02 +e6 +7d +60 +aa +d0 +02 +a2 +1e +4c +83 +86 +20 +c0 +ff +b0 +f3 +60 +20 +d2 +ff +b0 +ed +60 +20 +cf +ff +b0 +e7 +60 +48 +20 +c9 +ff +20 +f8 +a8 +aa +68 +90 +03 +8a +b0 +d8 +60 +20 +c6 +ff +20 +f8 +a8 +b0 +cf +60 +20 +e4 +ff +b0 +c9 +60 +20 +e1 +9d +a9 +a7 +48 +a9 +ce +48 +ad +f5 +07 +48 +ad +f2 +07 +ae +f3 +07 +ac +f4 +07 +28 +6c +14 +00 +08 +8d +f2 +07 +8e +f3 +07 +8c +f4 +07 +68 +8d +f5 +07 +60 +20 +6b +a8 +a6 +2d +a4 +2e +a9 +2b +20 +d8 +ff +20 +f8 +a8 +b0 +8e +60 +a9 +01 +2c +a9 +00 +85 +0a +20 +6b +a8 +a5 +0a +a6 +2b +a4 +2c +20 +d5 +ff +08 +20 +f8 +a8 +28 +b0 +5e +a5 +0a +f0 +16 +a2 +1c +20 +b7 +ff +29 +10 +d0 +16 +24 +81 +30 +08 +20 +4f +ff +0d +4f +4b +0d +00 +60 +20 +b7 +ff +29 +bf +f0 +05 +a2 +1d +4c +83 +86 +24 +81 +30 +10 +86 +2d +84 +2e +20 +6f +86 +20 +18 +88 +20 +93 +8a +4c +0f +87 +20 +f1 +8a +20 +18 +88 +4c +d5 +8a +20 +b0 +a8 +18 +20 +85 +a7 +20 +f8 +a8 +b0 +0f +60 +20 +b0 +a8 +a5 +49 +18 +20 +c3 +ff +20 +f8 +a8 +90 +bb +4c +7d +a7 +a9 +00 +20 +bd +ff +a2 +01 +a0 +00 +20 +ba +ff +20 +9d +a8 +20 +ee +a8 +20 +9d +a8 +20 +97 +a8 +a0 +00 +86 +49 +20 +ba +ff +20 +9d +a8 +20 +97 +a8 +8a +a8 +a6 +49 +4c +ba +ff +20 +a5 +a8 +4c +84 +9d +20 +79 +04 +d0 +02 +68 +68 +60 +20 +91 +94 +20 +79 +04 +d0 +f7 +4c +a1 +94 +a9 +00 +20 +bd +ff +20 +a8 +a8 +20 +84 +9d +86 +49 +8a +a2 +01 +a0 +00 +20 +ba +ff +20 +9d +a8 +20 +97 +a8 +86 +4a +a0 +00 +a5 +49 +e0 +03 +90 +01 +88 +20 +ba +ff +20 +9d +a8 +20 +97 +a8 +8a +a8 +a6 +4a +a5 +49 +20 +ba +ff +20 +9d +a8 +20 +a5 +a8 +20 +48 +9c +a6 +22 +a4 +23 +4c +bd +ff +08 +48 +a5 +ae +c9 +04 +90 +03 +20 +57 +cd +68 +28 +60 +46 +0f +aa +f0 +38 +48 +a5 +33 +38 +e9 +02 +a4 +34 +b0 +01 +88 +85 +22 +84 +23 +8a +49 +ff +38 +65 +22 +b0 +01 +88 +c4 +32 +90 +1d +d0 +04 +c5 +31 +90 +17 +85 +35 +84 +36 +a0 +01 +a9 +ff +91 +22 +88 +68 +91 +22 +a6 +35 +a4 +36 +86 +33 +84 +34 +60 +a5 +0f +30 +09 +20 +54 +a9 +38 +66 +0f +68 +d0 +b7 +4c +81 +86 +a6 +16 +e0 +19 +f0 +10 +20 +57 +aa +f0 +f7 +8a +a0 +00 +91 +5c +98 +c8 +91 +5c +d0 +ec +a0 +00 +84 +58 +a6 +37 +a4 +38 +86 +5f +86 +4e +86 +35 +84 +60 +84 +4f +84 +36 +8a +20 +ea +a9 +d0 +0c +88 +20 +65 +81 +20 +39 +aa +38 +66 +58 +d0 +ef +24 +58 +10 +42 +a2 +00 +86 +58 +a9 +02 +a0 +01 +20 +65 +81 +91 +5f +88 +20 +65 +81 +91 +5f +20 +b0 +04 +aa +20 +48 +aa +85 +35 +84 +36 +8a +20 +39 +aa +8a +a8 +88 +20 +65 +81 +91 +5f +ca +d0 +f7 +a0 +02 +b9 +5e +00 +91 +22 +88 +d0 +f8 +a5 +4e +a4 +4f +20 +ea +a9 +f0 +b0 +d0 +c4 +a0 +00 +20 +b0 +04 +aa +20 +48 +aa +85 +35 +84 +36 +8a +20 +39 +aa +4c +7f +a9 +c4 +34 +90 +2a +d0 +06 +c5 +33 +f0 +24 +90 +22 +24 +58 +30 +05 +a9 +02 +20 +48 +aa +a9 +02 +20 +39 +aa +a0 +01 +20 +65 +81 +c9 +ff +d0 +01 +60 +20 +65 +81 +99 +22 +00 +88 +10 +f7 +60 +a6 +16 +e0 +19 +f0 +10 +20 +57 +aa +f0 +f7 +a0 +00 +91 +5c +c8 +a9 +ff +91 +5c +d0 +ec +68 +68 +a5 +35 +a4 +36 +85 +33 +84 +34 +60 +49 +ff +38 +65 +4e +a4 +4f +b0 +01 +88 +85 +4e +84 +4f +60 +49 +ff +38 +65 +5f +a4 +60 +b0 +01 +88 +85 +5f +84 +60 +60 +ca +b5 +00 +85 +5d +ca +b5 +00 +85 +5c +ca +b5 +00 +48 +18 +65 +5c +85 +5c +90 +02 +e6 +5d +68 +60 +a9 +ec +a0 +aa +20 +66 +a0 +20 +91 +a2 +a9 +f1 +a0 +aa +a6 +6e +20 +8c +a1 +20 +91 +a2 +20 +58 +a3 +a9 +00 +85 +6f +20 +87 +9e +a9 +f6 +a0 +aa +20 +6c +a0 +a5 +66 +48 +10 +0d +20 +62 +a0 +a5 +66 +30 +09 +a5 +12 +49 +ff +85 +12 +20 +27 +a6 +a9 +f6 +a0 +aa +20 +66 +a0 +68 +10 +03 +20 +27 +a6 +a9 +fb +a0 +aa +4c +b3 +a6 +20 +4f +a2 +a9 +00 +85 +12 +20 +77 +aa +a2 +4e +a0 +00 +20 +5d +a7 +a9 +57 +a0 +00 +20 +21 +a2 +a9 +00 +85 +66 +a5 +12 +20 +e8 +aa +a9 +4e +a0 +00 +4c +94 +a1 +48 +4c +a9 +aa +81 +49 +0f +da +a2 +83 +49 +0f +da +a2 +7f +00 +00 +00 +00 +05 +84 +e6 +1a +2d +1b +86 +28 +07 +fb +f8 +87 +99 +68 +89 +01 +87 +23 +35 +df +e1 +86 +a5 +5d +e7 +28 +83 +49 +0f +da +a2 +a5 +66 +48 +10 +03 +20 +27 +a6 +a5 +61 +48 +c9 +81 +90 +07 +a9 +f0 +a0 +9f +20 +72 +a0 +a9 +4a +a0 +ab +20 +b3 +a6 +68 +c9 +81 +90 +07 +a9 +ec +a0 +aa +20 +6c +a0 +68 +10 +03 +4c +27 +a6 +60 +0b +76 +b3 +83 +bd +d3 +79 +1e +f4 +a6 +f5 +7b +83 +fc +b0 +10 +7c +0c +1f +67 +ca +7c +de +53 +cb +c1 +7d +14 +64 +70 +4c +7d +b7 +ea +51 +7a +7d +63 +30 +88 +7e +7e +92 +44 +99 +3a +7e +4c +cc +91 +c7 +7f +aa +aa +aa +13 +81 +00 +00 +00 +00 +89 +8a +8d +a7 +8c +d6 +d7 +d5 +20 +de +b6 +a9 +00 +a2 +0a +86 +03 +85 +04 +86 +05 +85 +06 +85 +5a +85 +5b +20 +79 +04 +f0 +66 +20 +3e +8e +a5 +08 +f0 +08 +a5 +14 +a6 +15 +85 +03 +86 +04 +20 +79 +04 +f0 +52 +20 +91 +94 +20 +3e +8e +a5 +08 +f0 +10 +a5 +14 +a6 +15 +85 +05 +86 +06 +d0 +06 +aa +d0 +03 +4c +1c +99 +20 +79 +04 +f0 +33 +20 +91 +94 +20 +3e +8e +a5 +14 +a6 +15 +85 +5a +86 +5b +20 +3d +8a +a5 +5f +a6 +60 +85 +58 +86 +59 +a5 +03 +a6 +04 +85 +14 +86 +15 +20 +3d +8a +a5 +60 +38 +e5 +59 +90 +cd +d0 +06 +a5 +5f +e5 +58 +90 +c5 +20 +f1 +8a +20 +86 +ad +20 +86 +ad +d0 +3d +20 +59 +ad +20 +86 +ad +20 +86 +ad +d0 +03 +4c +b3 +ae +20 +86 +ad +85 +14 +c8 +20 +a5 +04 +38 +e5 +5b +90 +19 +d0 +06 +a5 +14 +e5 +5a +90 +11 +a5 +62 +91 +3b +88 +a5 +63 +91 +3b +20 +86 +ad +20 +73 +ad +f0 +ce +20 +86 +ad +20 +80 +ad +f0 +c6 +20 +86 +ad +20 +86 +ad +20 +86 +ad +c9 +22 +d0 +0b +20 +86 +ad +f0 +a9 +c9 +22 +d0 +f7 +f0 +ee +aa +f0 +a0 +10 +e9 +a2 +08 +dd +86 +ab +f0 +10 +ca +d0 +f8 +c9 +cb +d0 +db +20 +73 +04 +f0 +8b +c9 +a4 +d0 +d2 +a5 +3b +8d +59 +02 +a5 +3c +8d +5a +02 +20 +73 +04 +b0 +c6 +20 +3e +8e +20 +ee +ac +ad +59 +02 +85 +3b +ad +5a +02 +85 +3c +a0 +00 +a2 +00 +bd +01 +01 +f0 +1c +48 +20 +73 +04 +90 +0e +20 +42 +ad +e6 +6c +20 +bb +ad +e6 +2d +d0 +02 +e6 +2e +68 +a0 +00 +91 +3b +e8 +d0 +df +20 +73 +04 +b0 +15 +20 +42 +ad +c6 +6c +20 +a2 +ad +a5 +2d +d0 +02 +c6 +2e +c6 +2d +20 +79 +04 +90 +eb +c9 +2c +f0 +9e +4c +5e +ac +20 +59 +ad +20 +86 +ad +d0 +0d +20 +86 +ad +d0 +0b +a9 +ff +85 +62 +85 +63 +30 +2a +20 +86 +ad +20 +86 +ad +85 +58 +c5 +14 +d0 +27 +20 +86 +ad +85 +59 +c5 +15 +d0 +23 +38 +e5 +5b +90 +08 +d0 +0e +a5 +14 +e5 +5a +b0 +08 +a5 +14 +85 +63 +a5 +15 +85 +62 +a2 +90 +38 +20 +ce +a2 +4c +6f +a4 +20 +86 +ad +85 +59 +20 +64 +ad +f0 +b1 +d9 +ea +a5 +3b +85 +22 +a5 +3c +85 +23 +a5 +2d +85 +24 +a5 +2e +85 +25 +a0 +00 +84 +0b +84 +6c +60 +a5 +03 +85 +63 +a5 +04 +85 +62 +4c +f1 +8a +a5 +59 +38 +e5 +5b +90 +15 +d0 +06 +a5 +58 +e5 +5a +90 +0d +a5 +63 +18 +65 +05 +85 +63 +a5 +62 +65 +06 +85 +62 +20 +86 +ad +d0 +fb +60 +a0 +00 +e6 +3b +d0 +02 +e6 +3c +4c +a5 +04 +a5 +22 +c5 +24 +d0 +04 +a5 +23 +c5 +25 +60 +e6 +22 +d0 +02 +e6 +23 +a4 +0b +c8 +20 +b0 +04 +a4 +6c +c8 +91 +22 +20 +91 +ad +d0 +ea +60 +a5 +24 +d0 +02 +c6 +25 +c6 +24 +a4 +0b +20 +bb +04 +a4 +6c +91 +24 +20 +91 +ad +d0 +ea +60 +a9 +80 +85 +10 +20 +7c +8e +a9 +81 +85 +02 +20 +71 +88 +f0 +08 +a0 +12 +20 +05 +89 +20 +60 +a7 +20 +69 +a7 +20 +be +8d +98 +a0 +11 +18 +65 +3b +91 +7c +a5 +3c +69 +00 +88 +91 +7c +a5 +3a +88 +91 +7c +a5 +39 +88 +91 +7c +a9 +a4 +20 +93 +94 +20 +17 +93 +20 +14 +93 +a5 +66 +09 +7f +25 +62 +85 +62 +a2 +04 +a0 +0d +b5 +61 +91 +7c +ca +88 +10 +f8 +a9 +f0 +a0 +9f +20 +21 +a2 +20 +79 +04 +c9 +a9 +d0 +06 +20 +73 +04 +20 +14 +93 +20 +b0 +a2 +48 +20 +a0 +a2 +68 +a0 +08 +a2 +05 +91 +7c +b5 +60 +88 +ca +10 +f8 +a5 +4a +91 +7c +a5 +49 +88 +91 +7c +a9 +81 +88 +91 +7c +60 +4c +a1 +94 +20 +de +b6 +20 +79 +04 +f0 +f5 +20 +ca +ae +a5 +5f +a6 +60 +85 +24 +86 +25 +20 +3d +8a +90 +15 +a0 +01 +20 +d1 +04 +88 +aa +d0 +05 +20 +d1 +04 +f0 +07 +20 +d1 +04 +85 +5f +86 +60 +a5 +24 +38 +e5 +5f +aa +a5 +25 +e5 +60 +a8 +b0 +1f +8a +18 +65 +2d +85 +2d +98 +65 +2e +85 +2e +a0 +00 +20 +d1 +04 +91 +24 +c8 +d0 +f8 +e6 +60 +e6 +25 +a5 +2e +c5 +25 +b0 +ee +20 +18 +88 +a5 +22 +a6 +23 +18 +69 +02 +85 +2d +90 +01 +e8 +86 +2e +20 +93 +8a +4c +7e +86 +f0 +06 +90 +04 +c9 +ab +d0 +22 +20 +3e +8e +20 +3d +8a +20 +79 +04 +f0 +0c +c9 +ab +d0 +13 +20 +73 +04 +20 +3e +8e +d0 +0b +a5 +08 +d0 +06 +a9 +ff +85 +14 +85 +15 +60 +4c +a1 +94 +a2 +ff +8e +e0 +02 +20 +73 +04 +20 +2c +93 +20 +1a +93 +a5 +64 +48 +a5 +65 +48 +a0 +02 +20 +dc +04 +88 +99 +3d +00 +d0 +f7 +20 +dc +04 +8d +df +02 +a8 +f0 +0b +88 +20 +71 +81 +c9 +23 +f0 +06 +98 +d0 +f5 +4c +a1 +94 +a9 +3b +20 +93 +94 +84 +76 +8c +cd +02 +20 +2c +93 +24 +0d +10 +39 +20 +70 +b1 +20 +b7 +b2 +ae +d5 +02 +f0 +15 +a2 +00 +38 +ad +db +02 +e5 +77 +90 +0b +a2 +3d +ec +d5 +02 +d0 +03 +4a +69 +00 +aa +a0 +00 +8a +f0 +05 +ca +a9 +20 +d0 +08 +c4 +77 +b0 +f8 +20 +b0 +04 +c8 +20 +b0 +b2 +d0 +eb +f0 +24 +20 +6f +a4 +a0 +ff +c8 +b9 +00 +01 +d0 +fa +98 +20 +5c +9b +a0 +00 +b9 +00 +01 +f0 +05 +91 +62 +c8 +d0 +f6 +20 +b0 +9b +20 +70 +b1 +20 +bb +af +20 +79 +04 +c9 +2c +f0 +8d +38 +66 +76 +20 +b7 +b2 +68 +a8 +68 +20 +52 +9c +20 +79 +04 +c9 +3b +f0 +03 +4c +3e +90 +4c +73 +04 +ad +e7 +04 +8d +dd +02 +a9 +ff +8d +dc +02 +4c +cb +af +86 +82 +c4 +77 +f0 +33 +b9 +00 +01 +c8 +c9 +20 +f0 +f4 +c9 +2d +f0 +e8 +c9 +2e +f0 +ea +c9 +45 +f0 +11 +9d +00 +01 +8e +ce +02 +e8 +24 +82 +10 +dd +ee +d4 +02 +4c +cb +af +b9 +00 +01 +c9 +2d +d0 +03 +6e +d2 +02 +c8 +8c +d3 +02 +a5 +82 +10 +02 +86 +82 +20 +b7 +b2 +ad +d6 +02 +c9 +ff +f0 +29 +ad +d9 +02 +f0 +3f +ad +d3 +02 +d0 +12 +ae +ce +02 +20 +45 +b1 +de +02 +01 +e8 +8e +d3 +02 +20 +cc +b1 +f0 +25 +ac +d8 +02 +d0 +17 +ac +dc +02 +30 +12 +ad +d6 +02 +f0 +6a +ce +d6 +02 +d0 +05 +ad +d7 +02 +f0 +60 +ee +d1 +02 +20 +bf +b0 +20 +8a +b1 +20 +bf +b0 +4c +ed +b1 +ac +d3 +02 +f0 +16 +85 +77 +38 +6e +da +02 +a4 +82 +ad +d2 +02 +10 +06 +20 +f8 +b0 +4c +7a +b0 +20 +d9 +b0 +a4 +82 +f0 +05 +20 +d0 +b1 +f0 +06 +20 +8a +b1 +4c +83 +b0 +ce +d4 +02 +38 +ad +d6 +02 +ed +d4 +02 +90 +1b +8d +d1 +02 +ac +d8 +02 +d0 +1b +ac +dc +02 +30 +16 +a8 +f0 +0b +88 +d0 +13 +ad +d7 +02 +0d +d4 +02 +d0 +ac +a9 +2a +20 +b0 +b2 +d0 +fb +60 +a8 +f0 +a1 +ad +d4 +02 +d0 +9c +ce +d1 +02 +e6 +76 +4c +53 +b0 +38 +ad +d6 +02 +ed +d4 +02 +f0 +39 +a4 +82 +90 +16 +85 +77 +cc +ce +02 +f0 +02 +b0 +01 +c8 +ee +d4 +02 +20 +0e +b1 +c6 +77 +d0 +ee +f0 +1d +49 +ff +69 +01 +85 +77 +cc +cd +02 +f0 +07 +88 +ce +d4 +02 +4c +f6 +b0 +e6 +76 +a9 +80 +20 +10 +b1 +c6 +77 +d0 +e9 +84 +82 +60 +d0 +39 +49 +09 +9d +00 +01 +ca +ec +d3 +02 +60 +a9 +00 +ae +d3 +02 +e8 +2c +da +02 +30 +10 +4d +d2 +02 +f0 +0b +20 +53 +b1 +20 +02 +b1 +b0 +f8 +4c +b2 +9f +bd +00 +01 +de +00 +01 +c9 +30 +20 +02 +b1 +b0 +f3 +2c +da +02 +10 +05 +84 +82 +68 +68 +60 +ad +d2 +02 +49 +80 +8d +d2 +02 +a9 +30 +9d +01 +01 +a9 +31 +9d +02 +01 +60 +bd +00 +01 +fe +00 +01 +c9 +39 +60 +18 +c8 +f0 +05 +cc +df +02 +90 +04 +a4 +76 +d0 +d4 +20 +71 +81 +ee +db +02 +60 +20 +4e +9c +85 +77 +a2 +0a +a9 +00 +9d +d1 +02 +ca +10 +fa +8e +d0 +02 +86 +82 +8e +cf +02 +aa +a8 +60 +18 +a5 +82 +6d +d7 +02 +b0 +39 +38 +e5 +76 +90 +34 +cd +ce +02 +f0 +02 +b0 +2d +cd +cd +02 +90 +28 +aa +bd +00 +01 +c9 +35 +90 +20 +ec +cd +02 +f0 +0a +ca +20 +53 +b1 +8e +ce +02 +f0 +f2 +60 +a9 +31 +9d +00 +01 +e8 +86 +82 +c6 +76 +10 +05 +e6 +76 +ee +d4 +02 +60 +a4 +82 +f0 +17 +ac +cd +02 +b9 +00 +01 +c9 +30 +60 +e6 +82 +20 +0e +b1 +ee +cd +02 +cc +ce +02 +f0 +e5 +c8 +20 +d3 +b1 +f0 +ed +60 +ad +cf +02 +30 +02 +e6 +76 +ae +cd +02 +ca +ac +de +02 +20 +71 +81 +c8 +c9 +2c +d0 +11 +2c +d0 +02 +30 +06 +ad +e8 +04 +4c +76 +b2 +ad +dd +02 +4c +76 +b2 +c9 +2e +d0 +06 +ad +e9 +04 +4c +76 +b2 +c9 +2b +f0 +3b +c9 +2d +f0 +32 +c9 +5e +d0 +63 +a9 +45 +20 +b0 +b2 +ac +d3 +02 +20 +d3 +b1 +d0 +06 +c8 +20 +d3 +b1 +f0 +07 +a9 +2d +2c +d2 +02 +30 +02 +a9 +2b +20 +b0 +b2 +ae +d3 +02 +bd +00 +01 +20 +b0 +b2 +ac +e0 +02 +4c +6c +b2 +ad +dc +02 +30 +b1 +ad +dc +02 +4c +76 +b2 +a5 +76 +d0 +15 +ec +ce +02 +f0 +05 +e8 +bd +00 +01 +2c +a9 +30 +4e +d0 +02 +20 +b0 +b2 +d0 +80 +60 +c6 +76 +ad +cf +02 +30 +ee +38 +6e +cf +02 +ad +ea +04 +4c +73 +b2 +ad +d1 +02 +f0 +d1 +ce +d1 +02 +f0 +03 +4c +0e +b2 +ad +d8 +02 +30 +f6 +20 +71 +81 +c9 +2c +d0 +b2 +ad +dd +02 +20 +b0 +b2 +c8 +4c +9f +b2 +20 +b2 +90 +ce +db +02 +60 +ac +e0 +02 +20 +5c +b1 +20 +6c +b3 +d0 +14 +8c +de +02 +90 +1a +aa +20 +5c +b1 +b0 +05 +20 +74 +b3 +f0 +0a +ac +de +02 +8a +20 +b2 +90 +4c +ba +b2 +b0 +ea +ac +de +02 +a6 +76 +d0 +7a +8e +db +02 +88 +ce +db +02 +20 +5c +b1 +b0 +74 +c9 +2c +f0 +f7 +20 +43 +b3 +90 +ef +c9 +2e +d0 +08 +e8 +e0 +02 +90 +e9 +4c +a1 +94 +20 +78 +b3 +d0 +0b +90 +03 +8d +d5 +02 +fe +d6 +02 +4c +ec +b2 +c9 +24 +d0 +0f +2c +cf +02 +10 +f1 +18 +6e +cf +02 +ce +d6 +02 +4c +10 +b3 +c9 +5e +d0 +16 +a2 +02 +20 +5c +b1 +b0 +cf +c9 +5e +d0 +cb +ca +10 +f4 +ee +d9 +02 +20 +5c +b1 +b0 +22 +c9 +2b +d0 +19 +ad +dc +02 +10 +05 +a9 +2b +8d +dc +02 +ad +d8 +02 +d0 +ad +6e +d8 +02 +8c +e0 +02 +ee +db +02 +60 +c9 +2d +f0 +ed +38 +8c +e0 +02 +ce +e0 +02 +60 +c9 +2b +f0 +15 +c9 +2d +f0 +11 +c9 +2e +f0 +0d +c9 +3d +f0 +09 +c9 +3e +f0 +05 +c9 +23 +d0 +01 +18 +60 +a5 +64 +8d +eb +04 +a5 +65 +8d +ec +04 +20 +2c +93 +20 +1a +93 +a5 +64 +8d +ed +04 +a5 +65 +8d +ee +04 +a2 +01 +86 +65 +20 +79 +04 +c9 +29 +f0 +03 +20 +d8 +9d +20 +8b +94 +a6 +65 +d0 +03 +4c +1c +99 +ca +86 +61 +a2 +03 +bd +eb +04 +95 +57 +ca +10 +f8 +a0 +02 +20 +75 +81 +99 +5b +00 +20 +79 +81 +99 +5e +00 +88 +10 +f1 +a5 +5e +f0 +37 +a9 +00 +85 +62 +18 +a5 +5e +65 +61 +b0 +2c +c5 +5b +90 +02 +d0 +26 +a4 +62 +c4 +5e +f0 +1b +98 +18 +65 +61 +a8 +20 +69 +81 +85 +78 +a4 +62 +20 +6d +81 +c5 +78 +f0 +04 +e6 +61 +d0 +d2 +e6 +62 +d0 +df +e6 +61 +a5 +61 +2c +a9 +00 +48 +ad +ed +04 +ac +ee +04 +20 +52 +9c +ad +eb +04 +ac +ec +04 +20 +52 +9c +68 +a8 +4c +81 +9a +20 +86 +9a +20 +79 +04 +f0 +07 +20 +e1 +9d +8c +f2 +04 +2c +a9 +ff +8d +f3 +04 +60 +20 +86 +9a +ae +f1 +04 +e8 +f0 +70 +20 +79 +04 +f0 +47 +90 +3a +c9 +82 +d0 +62 +20 +95 +b4 +a0 +00 +20 +a5 +04 +d0 +26 +c8 +20 +a5 +04 +d0 +09 +c8 +20 +a5 +04 +d0 +03 +4c +7e +86 +a0 +03 +20 +a5 +04 +85 +39 +c8 +20 +a5 +04 +85 +3a +98 +18 +65 +3b +85 +3b +90 +02 +e6 +3c +20 +73 +04 +4c +b0 +8d +20 +e1 +9d +85 +15 +20 +a4 +b4 +4c +69 +8d +a2 +01 +bd +f0 +04 +95 +39 +bd +f5 +04 +95 +3b +ca +10 +f3 +a2 +ff +8e +ef +04 +8e +f0 +04 +8e +f1 +04 +ae +f4 +04 +8e +f3 +04 +60 +4c +a1 +94 +a2 +1f +4c +83 +86 +20 +87 +9d +ca +8a +c9 +24 +b0 +34 +20 +53 +86 +a0 +ff +a2 +00 +e8 +c8 +b1 +24 +30 +06 +c9 +20 +90 +f7 +b0 +f4 +8a +20 +5c +9b +a2 +00 +a0 +ff +c8 +b1 +24 +c9 +20 +90 +f9 +20 +fe +b4 +48 +29 +7f +91 +62 +20 +fe +b4 +e8 +68 +10 +ea +4c +ca +9c +4c +1c +99 +48 +8a +48 +98 +aa +68 +a8 +68 +60 +20 +17 +93 +a5 +14 +48 +a5 +15 +48 +20 +e4 +9d +a9 +04 +20 +5c +9b +a0 +00 +a5 +15 +20 +2d +b5 +a5 +14 +20 +2d +b5 +68 +85 +15 +68 +85 +14 +4c +ca +9c +48 +4a +4a +4a +4a +20 +36 +b5 +68 +29 +0f +c9 +0a +90 +02 +69 +06 +69 +30 +91 +62 +c8 +60 +20 +48 +9c +a8 +88 +c0 +04 +b0 +ae +20 +b0 +04 +99 +e7 +04 +88 +10 +f7 +60 +a0 +01 +b9 +3b +00 +99 +f8 +04 +b9 +39 +00 +99 +fa +04 +88 +10 +f1 +20 +79 +04 +f0 +1c +c9 +fc +f0 +11 +c9 +fd +d0 +3f +20 +4c +b6 +a5 +61 +d0 +0d +20 +79 +04 +4c +ba +b5 +20 +4c +b6 +a5 +61 +d0 +f3 +a0 +05 +20 +05 +89 +88 +ad +f9 +04 +91 +7c +88 +ad +f8 +04 +91 +7c +88 +ad +fb +04 +91 +7c +88 +ad +fa +04 +91 +7c +88 +a9 +eb +91 +7c +60 +20 +14 +b6 +20 +79 +04 +f0 +06 +4c +a1 +94 +20 +73 +04 +f0 +1d +c9 +ec +f0 +40 +c9 +22 +f0 +0a +c9 +eb +d0 +ef +20 +b7 +b5 +4c +7c +b5 +20 +73 +04 +f0 +06 +c9 +22 +d0 +f7 +f0 +de +c9 +3a +f0 +da +24 +81 +10 +44 +a0 +02 +20 +a5 +04 +f0 +3d +c8 +20 +a5 +04 +85 +39 +c8 +20 +a5 +04 +85 +3a +98 +18 +65 +3b +85 +3b +90 +bb +e6 +3c +d0 +b7 +4c +b0 +8d +f0 +2d +c9 +fd +f0 +24 +c9 +fc +d0 +a7 +20 +4c +b6 +a5 +61 +f0 +1e +a9 +eb +85 +02 +20 +71 +88 +d0 +0b +20 +69 +a7 +a0 +05 +4c +72 +a7 +a2 +20 +2c +a2 +21 +4c +83 +86 +20 +4c +b6 +f0 +e2 +20 +14 +b6 +88 +b1 +3d +85 +3c +88 +b1 +3d +85 +3b +88 +b1 +3d +20 +7f +cd +b1 +3d +85 +39 +4c +57 +b5 +20 +73 +04 +4c +2c +93 +a9 +ff +2c +a9 +00 +8d +eb +02 +60 +20 +8e +94 +20 +a5 +96 +85 +49 +84 +4a +20 +1a +93 +20 +d8 +9d +ca +86 +77 +c9 +29 +f0 +04 +20 +d8 +9d +2c +a2 +ff +86 +78 +20 +8b +94 +a9 +b2 +20 +93 +94 +20 +2c +93 +20 +1a +93 +a0 +02 +a9 +49 +20 +94 +04 +99 +5b +00 +20 +dc +04 +99 +5e +00 +88 +10 +ef +38 +a5 +5f +e5 +77 +85 +5f +b0 +02 +c6 +60 +a5 +78 +c5 +5e +90 +02 +a5 +5e +aa +f0 +16 +18 +65 +77 +b0 +14 +c5 +5b +90 +02 +d0 +0e +a4 +77 +20 +6d +81 +91 +5c +c8 +ca +d0 +f7 +4c +4e +9c +4c +1c +99 +20 +de +b6 +20 +3e +8e +a5 +14 +85 +73 +a5 +15 +85 +74 +4c +7e +86 +24 +81 +30 +01 +60 +a2 +22 +4c +83 +86 +ae +ef +04 +e8 +f0 +1b +ad +f0 +04 +ac +f1 +04 +85 +14 +84 +15 +20 +3d +8a +90 +0c +66 +53 +20 +3e +90 +a6 +14 +a5 +15 +20 +40 +8b +4c +3e +90 +a6 +60 +98 +18 +65 +5f +90 +01 +e8 +ec +f6 +04 +d0 +0e +cd +f5 +04 +90 +09 +f0 +07 +46 +53 +a9 +82 +4c +b2 +90 +60 +d0 +7c +a2 +00 +a0 +00 +e8 +bd +5e +05 +f0 +53 +85 +77 +86 +76 +a2 +05 +bd +6e +cd +ca +d0 +02 +05 +76 +20 +d2 +ff +8a +10 +f2 +a2 +07 +b9 +67 +05 +c8 +48 +86 +80 +a2 +04 +dd +39 +b8 +f0 +34 +ca +d0 +f8 +a6 +80 +e0 +08 +90 +07 +d0 +0a +a9 +2b +20 +d2 +ff +a9 +22 +20 +d2 +ff +68 +20 +d2 +ff +a2 +09 +c6 +77 +d0 +d3 +e0 +09 +90 +05 +a9 +22 +20 +d2 +ff +a9 +8d +20 +d2 +ff +a6 +76 +e0 +08 +d0 +a3 +60 +a6 +80 +bd +30 +b8 +20 +d2 +ff +ca +e0 +03 +b0 +f5 +68 +20 +74 +cd +a9 +29 +20 +d2 +ff +a2 +08 +d0 +cd +20 +84 +9d +ca +e0 +08 +90 +03 +4c +1c +99 +86 +76 +20 +91 +94 +20 +48 +9c +20 +c2 +b7 +90 +72 +4c +81 +86 +85 +77 +a2 +08 +20 +3e +b8 +8d +cd +02 +a6 +76 +e8 +20 +3e +b8 +8d +ce +02 +a6 +76 +a5 +77 +38 +fd +5f +05 +f0 +35 +90 +1d +18 +6d +cd +02 +b0 +4b +c9 +81 +b0 +47 +aa +ac +cd +02 +cc +ce +02 +f0 +20 +88 +ca +b9 +67 +05 +9d +67 +05 +b0 +f1 +6d +ce +02 +aa +ac +ce +02 +cc +cd +02 +b0 +0a +b9 +67 +05 +9d +67 +05 +c8 +e8 +90 +f1 +a6 +76 +20 +3e +b8 +aa +a4 +76 +a5 +77 +99 +5f +05 +a0 +00 +20 +b0 +04 +c6 +77 +30 +07 +9d +67 +05 +e8 +c8 +d0 +f2 +18 +60 +28 +24 +52 +48 +43 +2b +22 +0d +8d +22 +1b +a9 +00 +18 +ca +30 +ee +7d +5f +05 +90 +f8 +20 +84 +9d +ca +e0 +03 +b0 +64 +86 +80 +20 +de +9d +c9 +04 +b0 +5b +84 +7e +85 +7f +20 +de +9d +a6 +80 +e0 +02 +d0 +01 +ca +48 +c0 +00 +d0 +07 +c9 +00 +d0 +03 +c8 +d0 +0f +98 +48 +20 +c0 +8c +bd +fe +04 +1d +fc +04 +d0 +f5 +68 +a8 +98 +49 +ff +18 +69 +01 +78 +9d +fc +04 +68 +49 +ff +69 +00 +9d +fe +04 +a5 +7e +9d +0e +ff +bd +b8 +b8 +aa +bd +10 +ff +29 +fc +05 +7f +9d +10 +ff +a6 +80 +bd +ba +b8 +0d +11 +ff +8d +11 +ff +58 +60 +4c +1c +99 +02 +00 +10 +20 +40 +20 +84 +9d +e0 +09 +b0 +f1 +86 +80 +ad +11 +ff +29 +f0 +05 +80 +8d +11 +ff +60 +20 +b6 +c3 +a2 +04 +20 +d9 +c3 +20 +7b +c3 +20 +a5 +c3 +e0 +02 +90 +03 +4c +1c +99 +8a +4a +6a +85 +8b +10 +04 +a5 +84 +f0 +07 +20 +f3 +c1 +b0 +02 +d0 +01 +60 +20 +54 +a9 +a5 +31 +85 +22 +a5 +32 +85 +23 +38 +a5 +33 +e9 +03 +85 +19 +a5 +34 +e9 +00 +85 +1a +a2 +00 +86 +89 +86 +8a +ae +af +02 +d0 +03 +ce +b0 +02 +ce +af +02 +20 +f3 +c1 +b0 +02 +d0 +ee +ee +af +02 +d0 +03 +ee +b0 +02 +20 +c3 +c1 +ae +ad +02 +d0 +03 +ce +ae +02 +ce +ad +02 +a5 +89 +20 +9f +b9 +85 +89 +18 +ad +ad +02 +69 +02 +8d +ad +02 +90 +03 +ee +ae +02 +a5 +8a +20 +9f +b9 +85 +8a +ae +ad +02 +d0 +03 +ce +ae +02 +ce +ad +02 +ee +af +02 +d0 +03 +ee +b0 +02 +20 +f3 +c1 +b0 +02 +d0 +bc +a2 +03 +a0 +00 +a5 +23 +c5 +32 +d0 +06 +a5 +22 +c5 +31 +f0 +17 +a5 +22 +d0 +02 +c6 +23 +c6 +22 +20 +b0 +04 +9d +ad +02 +ca +10 +ef +20 +c0 +8c +4c +11 +b9 +4c +7b +c3 +48 +20 +f3 +c1 +b0 +2b +f0 +29 +68 +d0 +29 +aa +a8 +a5 +23 +c5 +1a +90 +0b +d0 +06 +a5 +22 +c5 +19 +90 +03 +4c +81 +86 +bd +ad +02 +91 +22 +e6 +22 +d0 +02 +e6 +23 +e8 +e0 +04 +d0 +f0 +a9 +80 +60 +68 +a9 +00 +60 +20 +b9 +c3 +20 +d8 +9d +e0 +28 +b0 +0a +8e +da +02 +20 +d8 +9d +e0 +19 +90 +03 +4c +1c +99 +8e +db +02 +20 +91 +94 +20 +48 +9c +8d +ea +02 +98 +48 +8a +48 +20 +a5 +c3 +8a +6a +6e +b9 +02 +68 +85 +22 +68 +85 +23 +a5 +83 +d0 +1b +ae +db +02 +ac +da +02 +18 +20 +f0 +ff +a0 +00 +cc +ea +02 +f0 +09 +20 +b0 +04 +20 +4c +ff +c8 +d0 +f2 +60 +20 +bf +c7 +a5 +86 +48 +a5 +84 +48 +24 +83 +10 +0f +68 +f0 +12 +4a +f0 +0f +a6 +85 +90 +0d +ae +16 +ff +b0 +08 +ae +15 +ff +68 +f0 +02 +a6 +86 +86 +86 +ae +db +02 +a0 +00 +8c +dc +02 +ac +dc +02 +ee +dc +02 +20 +b0 +04 +ce +ea +02 +30 +17 +ac +da +02 +20 +7f +ba +ee +da +02 +c0 +27 +90 +e5 +a0 +00 +8c +da +02 +e8 +e0 +18 +90 +db +68 +85 +86 +60 +48 +20 +1a +c2 +20 +91 +c2 +a9 +00 +85 +7e +68 +48 +0a +26 +7e +0a +0a +26 +7e +85 +24 +a5 +7e +6d +e4 +02 +85 +25 +98 +48 +a0 +07 +ad +b9 +02 +0a +b1 +24 +90 +02 +49 +ff +24 +83 +10 +2b +29 +aa +85 +7e +a5 +84 +d0 +0f +a5 +7e +b0 +07 +4a +45 +7e +49 +aa +d0 +18 +09 +55 +d0 +14 +c9 +02 +d0 +04 +a5 +7e +b0 +0c +90 +07 +a5 +7e +4a +45 +7e +90 +03 +a5 +7e +4a +91 +8c +88 +10 +c2 +68 +a8 +68 +60 +20 +b6 +c3 +a2 +1f +20 +f4 +c3 +a2 +2b +20 +d9 +c3 +20 +8f +c3 +8c +d0 +02 +8d +d1 +02 +20 +a5 +c3 +e0 +02 +90 +03 +4c +1c +99 +8e +e8 +02 +8a +48 +20 +b4 +bb +68 +d0 +1c +f0 +03 +20 +36 +bc +20 +da +c0 +ad +ca +02 +d0 +f5 +a2 +04 +bd +d7 +02 +9d +ac +02 +ca +d0 +f7 +8e +e8 +02 +60 +a2 +00 +ad +c5 +02 +4a +90 +02 +a2 +02 +bd +dc +02 +8d +d6 +02 +bd +dd +02 +8d +d7 +02 +a9 +00 +a2 +03 +9d +d2 +02 +ca +10 +fa +a2 +07 +bd +ad +02 +48 +ca +10 +f9 +20 +da +c0 +a2 +00 +68 +9d +ad +02 +e8 +e0 +08 +d0 +f7 +ad +d6 +02 +d0 +05 +ce +d7 +02 +30 +b0 +ce +d6 +02 +a2 +25 +a0 +1b +ad +c5 +02 +4a +90 +02 +a0 +19 +a9 +00 +4a +48 +20 +f6 +c2 +9d +ad +02 +98 +9d +ae +02 +68 +90 +02 +09 +a0 +e8 +e8 +a0 +19 +4e +c5 +02 +90 +02 +a0 +1b +2e +c5 +02 +e0 +27 +f0 +dd +a2 +06 +0a +f0 +bd +90 +08 +fe +ad +02 +d0 +03 +fe +ae +02 +0a +ca +ca +10 +f1 +30 +95 +a0 +23 +20 +56 +bc +a2 +1f +a0 +2b +98 +48 +20 +22 +c3 +9d +b1 +02 +9d +b5 +02 +9d +bd +02 +98 +9d +b2 +02 +9d +b6 +02 +9d +be +02 +68 +a8 +20 +f6 +c2 +9d +ad +02 +98 +9d +ae +02 +a0 +2d +e8 +e8 +e0 +21 +f0 +d4 +a9 +90 +20 +d5 +bc +ad +c5 +02 +29 +03 +8d +c5 +02 +aa +bd +18 +bc +20 +36 +bc +20 +7b +c3 +ad +ca +02 +20 +36 +bc +ae +c5 +02 +bd +18 +bc +29 +f0 +8d +cb +02 +bd +1c +bc +8d +ca +02 +60 +be +e4 +41 +1b +41 +1b +be +e4 +46 +52 +45 +44 +20 +42 +0d +54 +45 +52 +52 +59 +20 +52 +0d +4d +49 +4b +45 +20 +49 +0d +20 +05 +bd +a2 +04 +bd +ae +02 +0a +7e +ae +02 +7e +ad +02 +90 +08 +fe +ad +02 +d0 +03 +fe +ae +02 +e8 +e8 +e0 +06 +f0 +e6 +60 +20 +18 +c3 +a2 +00 +e8 +38 +e9 +5a +b0 +fa +88 +10 +f7 +8e +c5 +02 +48 +69 +5a +20 +76 +bc +68 +18 +49 +ff +69 +01 +ce +c5 +02 +a2 +ff +e8 +38 +e9 +0a +b0 +fa +69 +0a +85 +8e +8a +0a +aa +bd +b4 +c4 +bc +b3 +c4 +18 +c6 +8e +30 +0c +7d +c8 +c4 +48 +98 +7d +c7 +c4 +a8 +68 +90 +ef +48 +a2 +00 +ad +c5 +02 +4a +b0 +02 +a2 +02 +68 +9d +c6 +02 +98 +9d +c7 +02 +60 +a0 +19 +90 +02 +a0 +1b +ad +c5 +02 +69 +02 +4a +4a +08 +20 +18 +c3 +c0 +ff +90 +07 +8a +a8 +20 +18 +c3 +b0 +03 +20 +37 +c3 +28 +b0 +1b +4c +27 +c3 +8d +ca +02 +a2 +23 +0e +ca +02 +20 +b0 +bc +9d +ad +02 +98 +9d +ae +02 +e8 +e8 +e0 +2b +90 +ed +60 +a0 +2b +20 +56 +bc +a2 +07 +bd +dc +02 +9d +d0 +02 +ca +10 +f7 +a9 +50 +20 +d5 +bc +a9 +10 +8d +ca +02 +a0 +1f +a2 +23 +0e +cb +02 +2e +ca +02 +20 +f4 +c2 +e8 +e8 +0e +cb +02 +2e +ca +02 +20 +f0 +c2 +48 +98 +48 +a0 +21 +e8 +e8 +e0 +27 +f0 +e1 +a2 +03 +68 +9d +b1 +02 +ca +10 +f9 +60 +20 +bf +c7 +20 +48 +9c +8d +cf +02 +86 +24 +84 +25 +a2 +04 +20 +d9 +c3 +20 +a5 +c3 +e0 +05 +90 +03 +4c +1c +99 +8e +d0 +02 +a2 +03 +ac +cf +02 +c0 +05 +b0 +01 +60 +88 +20 +bb +04 +9d +d5 +02 +ca +10 +f6 +8e +d1 +02 +20 +7b +c3 +ad +d5 +02 +8d +d9 +02 +ad +d6 +02 +8d +da +02 +a9 +08 +8d +e5 +02 +ee +d1 +02 +ac +d1 +02 +20 +bb +04 +8d +d3 +02 +20 +f3 +c1 +8d +d2 +02 +0e +d3 +02 +2a +ce +e5 +02 +24 +83 +10 +07 +0e +d3 +02 +2a +ce +e5 +02 +ae +d0 +02 +e0 +03 +90 +0c +f0 +05 +4d +d2 +02 +b0 +11 +2d +d2 +02 +b0 +0c +e0 +01 +90 +08 +f0 +04 +0d +d2 +02 +2c +49 +ff +29 +03 +24 +83 +30 +02 +29 +01 +85 +84 +20 +c3 +c1 +ee +ad +02 +d0 +03 +ee +ae +02 +38 +ad +d9 +02 +24 +83 +10 +03 +e9 +02 +2c +e9 +01 +8d +d9 +02 +ad +da +02 +e9 +00 +8d +da +02 +b0 +2d +a2 +01 +bd +d5 +02 +9d +d9 +02 +bd +b1 +02 +9d +ad +02 +ca +10 +f1 +ee +af +02 +d0 +03 +ee +b0 +02 +38 +ad +d7 +02 +e9 +01 +8d +d7 +02 +ad +d8 +02 +e9 +00 +8d +d8 +02 +b0 +09 +60 +ad +e5 +02 +f0 +03 +4c +8b +bd +4c +7a +bd +20 +bf +c7 +20 +a5 +96 +8d +db +02 +8c +dc +02 +24 +0d +30 +03 +4c +24 +93 +a2 +28 +20 +f4 +c3 +a2 +04 +20 +d9 +c3 +a2 +2a +a0 +06 +a9 +02 +85 +8e +20 +22 +c3 +aa +98 +48 +a4 +8e +20 +82 +c3 +90 +0c +b9 +d5 +02 +99 +ad +02 +b9 +d6 +02 +99 +ae +02 +8a +99 +d5 +02 +99 +de +02 +68 +99 +d6 +02 +99 +df +02 +a2 +28 +a0 +04 +c6 +8e +c6 +8e +f0 +cf +a0 +ff +8c +d1 +02 +ad +ad +02 +8d +d9 +02 +ad +ae +02 +8d +da +02 +98 +20 +5c +9b +20 +64 +c2 +b1 +8c +90 +0e +ad +ad +02 +24 +83 +10 +02 +38 +2a +29 +07 +aa +a9 +00 +24 +83 +10 +01 +ca +8e +dd +02 +0a +ca +10 +fc +6a +85 +8e +a9 +08 +24 +83 +10 +01 +4a +18 +6d +ad +02 +8d +ad +02 +90 +03 +ee +ae +02 +20 +64 +c2 +a9 +00 +b0 +02 +b1 +8c +85 +8f +ae +dd +02 +4a +e8 +e0 +08 +d0 +fa +05 +8e +ee +d1 +02 +ac +d1 +02 +c0 +fc +90 +03 +4c +4c +cc +91 +62 +ae +dd +02 +ad +d5 +02 +38 +24 +83 +10 +03 +e9 +04 +2c +e9 +08 +8d +d5 +02 +a5 +8f +b0 +aa +ce +d6 +02 +10 +a5 +ae +d7 +02 +d0 +42 +ce +d8 +02 +10 +3d +24 +83 +10 +06 +0e +de +02 +2e +df +02 +a2 +00 +bd +de +02 +c8 +91 +62 +e8 +e0 +04 +d0 +f5 +c8 +8c +de +02 +a5 +62 +8d +df +02 +a5 +63 +8d +e0 +02 +a9 +de +85 +64 +a9 +02 +85 +65 +ad +db +02 +85 +49 +ad +dc +02 +85 +4a +20 +40 +8f +4c +7b +c3 +ce +d7 +02 +ee +af +02 +d0 +03 +ee +b0 +02 +ad +d9 +02 +8d +ad +02 +ad +da +02 +8d +ae +02 +ad +de +02 +8d +d5 +02 +ad +df +02 +8d +d6 +02 +4c +94 +be +a5 +83 +18 +2a +2a +2a +69 +00 +a8 +4c +81 +9a +38 +24 +18 +08 +20 +87 +9d +ad +19 +ff +29 +7f +e0 +04 +f0 +19 +b0 +27 +ad +15 +ff +29 +7f +ca +30 +0f +a5 +86 +ca +30 +0a +a5 +85 +ca +30 +05 +ad +16 +ff +29 +7f +28 +b0 +05 +4a +4a +4a +4a +18 +69 +00 +29 +0f +a8 +4c +81 +9a +4c +1c +99 +20 +87 +9d +ca +e0 +02 +b0 +f5 +bd +fb +bf +aa +78 +8e +08 +ff +ad +08 +ff +8e +08 +ff +cd +08 +ff +d0 +f2 +58 +49 +ff +a8 +29 +0f +aa +bd +f0 +bf +c0 +0f +90 +02 +09 +80 +a8 +4c +81 +9a +00 +01 +05 +00 +07 +08 +06 +00 +03 +02 +04 +fa +fd +20 +87 +9d diff --git a/cores/c16/basic_rom.v b/cores/c16/basic_rom.v new file mode 100644 index 0000000..321597e --- /dev/null +++ b/cores/c16/basic_rom.v @@ -0,0 +1,63 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Copyright 2013-2016 Istvan Hegedus +// +// FPGATED is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// FPGATED is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Create Date: 22:20:09 12/09/2014 +// Module Name: basic_rom.v +// Project Name: FPGATED +// Target Devices: Xilinx Spartan 3E +// +// Description: +// Basic ROM synthetised to FPGA's internal SRAM. Xilinx ISE requires +// ROM_STYLE="BLOCK" parameter next to kernal array. For other vendor's +// device syntax refer to the FPGA vendor's documentation. +// +// +// Dependencies: +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module basic_rom( + input wire clk, + input wire [13:0] address_in, + output wire [7:0] data_out, + input wire cs + ); + +(* ROM_STYLE="BLOCK" *) +reg [7:0] basic [0:16383]; +reg [7:0] data; +reg cs_prev=1'b1; +wire enable; + +always@(posedge clk) + if(enable) + data<=basic[address_in]; + +always@(posedge clk) + cs_prev<=cs; + +assign enable=~cs&cs_prev; // cs falling edge detection +assign data_out=(~cs)?data:8'hff; + +initial begin +$readmemh("basic.hex",basic); +end + +endmodule diff --git a/cores/c16/c16.v b/cores/c16/c16.v new file mode 100644 index 0000000..193109a --- /dev/null +++ b/cores/c16/c16.v @@ -0,0 +1,263 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Copyright 2013-2016 Istvan Hegedus +// +// FPGATED is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// FPGATED is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// +// Create Date: 12:02:05 10/24/2014 +// Design Name: Commodore 16 +// Module Name: C16.v +// Project Name: FPGATED +// +// Description: +// This module provides the top level framework for FPGATED. It implements a Commodore 16 computer without expansion port. +// It is written for Papilio FPGATED wing 1.x but can be easily modified for any other platforms. +// +// Revision: +// Revision 0.01 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module C16( + input wire CLK28, + input wire RESET, + input wire WAIT, + + output wire HSYNC, + output wire VSYNC, + output wire CSYNC, + output wire [3:0] RED, + output wire [3:0] GREEN, + output wire [3:0] BLUE, + + output wire RAS, + output wire CAS, + output wire RW, + output wire [7:0] A, + input wire [7:0] DIN, + output wire [7:0] DOUT, + + input [4:0] JOY0, + input [4:0] JOY1, + + input PS2DAT, + input PS2CLK, + + output IEC_DATAOUT, + input IEC_DATAIN, + output IEC_CLKOUT, + input IEC_CLKIN, + output IEC_ATNOUT, + //input IEC_ATNIN, + output IEC_RESET, + + output AUDIO_L, + output AUDIO_R, + + input [13:0] kernal_dl_addr, + input [7:0] kernal_dl_data, + input kernal_dl_write, + + output PAL, + + output RS232_TX, + output RGBS + ); + +wire [15:0] c16_addr; +wire [15:0] ted_addr; +wire [15:0] cpu_addr; +wire [7:0] c16_data,ted_data,ram_data,cpu_data,basic_data,kernal_data,port_in,port_out,keyport_data; +wire [7:0] keyboard_row,kbus,kbus_kbd; +wire [7:0] keyscancode; +wire keyreceived; +wire [6:0] c16_color; +wire mux,cpuenable; +wire aec,rdy; +wire keyboardio; +wire sound; +reg [7:0] c16_datalatch=8'b0; +reg sreset=1'b0; +reg [23:0] resetcounter=24'b0; +reg [15:0] c16_addrlatch=16'b0; +wire irq1; +wire keyreset; + +// wire joysticks +wire [4:0] joy0_sel = (!c16_data[2])?{!JOY0[4],!JOY0[0],!JOY0[1],!JOY0[2],!JOY0[3]}:5'h1f; +wire [4:0] joy1_sel = (!c16_data[1])?{!JOY1[4],!JOY1[0],!JOY1[1],!JOY1[2],!JOY1[3]}:5'h1f; +assign kbus[3:0] = kbus_kbd[3:0] & joy0_sel[3:0] & joy1_sel[3:0]; +assign kbus[5:4] = kbus_kbd[5:4]; // no joystick line connected here +assign kbus[6] = kbus_kbd[6] & joy0_sel[4]; +assign kbus[7] = kbus_kbd[7] & joy1_sel[4]; + +// 8501 CPU + mos8501 cpu ( + .clk(CLK28), + .reset(sreset), + .enable(cpuenable && !WAIT), + .irq_n(irq_n), + .data_in(c16_data), + .data_out(cpu_data), + .address(cpu_addr), + .gate_in(mux), + .rw(RW), // rw=high read, rw=low write + .port_in(port_in), + .port_out(port_out), + .rdy(rdy), + .aec(aec) + ); + +// TED 8360 instance + +ted mos8360( + .clk(CLK28), + .addr_in(c16_addr), + .addr_out(ted_addr), + .data_in(c16_data), + .data_out(ted_data), + .rw(RW), + .cpuclk(cpuclk), + .color(c16_color), + .csync(CSYNC), + .hsync(HSYNC), + .vsync(VSYNC), + .irq(irq_n), + .ba(rdy), + .mux(mux), + .ras(RAS), + .cas(CAS), + .cs0(cs0), + .cs1(cs1), + .aec(aec), + .k(kbus), + .snd(sound), + .pal(PAL), + .cpuenable(cpuenable) + ); + +// Kernal rom + + kernal_rom kernal( + .clk(CLK28), + .address_in(sreset?kernal_dl_addr:c16_addr[13:0]), + .data_out(kernal_data), + .data_in(kernal_dl_data), + .wr(kernal_dl_write), + .cs(cs1) + ); + +// Basic rom + + basic_rom basic( + .clk(CLK28), + .address_in(c16_addr[13:0]), + .data_out(basic_data), + .cs(cs0) + ); + +// Color decoder to 12bit RGB + +colors_to_rgb colordecode ( + .clk(CLK28), + .color(c16_color), + .red(RED), + .green(GREEN), + .blue(BLUE) + ); + +// keyboard part + +ps2receiver ps2rcv( + .clk(CLK28), + .ps2_clk(PS2CLK), + .ps2_data(PS2DAT), + .rx_done(keyreceived), + .ps2scancode(keyscancode) + ); + +c16_keymatrix keyboard( + .clk(CLK28), + .scancode(keyscancode), + .receiveflag(keyreceived), + .row(keyboard_row), + .kbus(kbus_kbd), + .keyreset(keyreset) + ); + +mos6529 keyport( + .clk(CLK28), + .data_in(c16_data), + .data_out(keyport_data), + .port_in(keyboard_row), // keyport 6529 in C16 is unidirectional however if we read it the last written data is read back so we feed back its output. + .port_out(keyboard_row), + .rw(RW), + .cs(keyboardio) + ); + +assign AUDIO_R=sound; +assign AUDIO_L=sound; +assign RGBS=1'bz; // VGA/RGBS jumper is not implemented in current version +assign RS232_TX=1'bz; // RS232 is not implemented in current version + +assign keyboardio=(c16_addr[15:4]==12'hfd3)?1'b1:1'b0; // as we don't have PLA, keyport is identified here + +// C16 additional motherboard functions + + +always @(posedge CLK28) // reset tries to emulate the length of a real reset + begin + if(RESET|keyreset) begin // reset can be triggered by reset button or CTRL+ALT+DEL from keyboard + resetcounter<=0; + sreset<=1; + end else begin + if(resetcounter==24'd16777215) + sreset<=0; + else begin + resetcounter<=resetcounter+1; + sreset<=1; + end + end + end + +// assign VSYNC=1'b1; // set scart mode to RGB for TV + +assign c16_addr=(~mux)?c16_addrlatch:cpu_addr&ted_addr; // C16 address bus +assign c16_data=(mux)?c16_datalatch:cpu_data&ted_data&ram_data&kernal_data&basic_data&keyport_data; // C16 data bus + +always @(posedge CLK28) // addres and data bus latching emulates dynamic memory behaviour of these buses + begin + c16_datalatch<=c16_data; + c16_addrlatch<=c16_addr; + end + +// external 4464 DRAM signal connections on Papilio FPGATED wing + +assign A=(~mux)?c16_addr[15:8]:c16_addr[7:0]; // DRAM address multiplexer for TMS4464 address lines +assign DOUT=c16_data; // only drive external TMS4464 data lines when there is a write cycle + +assign ram_data=(RW & ~CAS)?DIN:8'hff; // internal ram_data should be 0xff when external RAM's data line is in high impedance state + +// connect IEC bus + +assign IEC_DATAOUT=port_out[0]; +assign port_in[7]=IEC_DATAIN; +assign IEC_CLKOUT=port_out[1]; +assign port_in[6]=IEC_CLKIN; +assign IEC_ATNOUT=port_out[2]; +//assign ATN=IEC_ATNIN; +assign IEC_RESET=sreset; + +endmodule diff --git a/cores/c16/c16_keymatrix.v b/cores/c16/c16_keymatrix.v new file mode 100644 index 0000000..e8837e7 --- /dev/null +++ b/cores/c16/c16_keymatrix.v @@ -0,0 +1,174 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Copyright 2013-2016 Istvan Hegedus +// +// FPGATED is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// FPGATED is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Create Date: 19:38:44 12/16/2015 +// Module Name: c16_keymatrix.v +// Project Name: FPGATED +// +// Description: C16/Plus4 keyboard matrix emulation for PS2 keyboards. +// +// Revisions: +// 1.0 first release +// +////////////////////////////////////////////////////////////////////////////////// +module c16_keymatrix( + input clk, + input [7:0] scancode, + input receiveflag, + input [7:0] row, + output [7:0] kbus, + output keyreset + ); + +reg releaseflag=0; +reg extendedflag=0; +reg [7:0] colsel=0; +reg key_A=0,key_B=0,key_C=0,key_D=0,key_E=0,key_F=0,key_G=0,key_H=0,key_I=0,key_J=0,key_K=0,key_L=0,key_M=0,key_N=0,key_O=0,key_P=0,key_Q=0,key_R=0,key_S=0,key_T=0,key_U=0,key_V=0,key_W=0,key_X=0,key_Y=0,key_Z=0; +reg key_1=0,key_2=0,key_3=0,key_4=0,key_5=0,key_6=0,key_7=0,key_8=0,key_9=0,key_0=0,key_del=0,key_return=0,key_help=0,key_F1=0,key_F2=0,key_F3=0,key_AT=0,key_shift=0,key_comma=0,key_dot=0; +reg key_minus=0,key_colon=0,key_star=0,key_semicolon=0,key_esc=0,key_equal=0,key_plus=0,key_slash=0,key_control=0,key_space=0,key_runstop=0; +reg key_pound=0,key_down=0,key_up=0,key_left=0,key_right=0,key_home=0,key_commodore=0,key_alt=0; +wire [7:0] rowsel; + +assign rowsel=~row; +assign keyreset=key_control&key_alt&key_del; + +always @(posedge clk) + begin + if(receiveflag) + begin + if(scancode==8'hF0) + releaseflag<=1; + else if (scancode==8'hE0) + extendedflag<=1; + else + begin + releaseflag<=0; + if (~extendedflag) // base code keys + begin + case(scancode) + 8'h1C: key_A<=~releaseflag; + 8'h32: key_B<=~releaseflag; + 8'h21: key_C<=~releaseflag; + 8'h23: key_D<=~releaseflag; + 8'h24: key_E<=~releaseflag; + 8'h2B: key_F<=~releaseflag; + 8'h34: key_G<=~releaseflag; + 8'h33: key_H<=~releaseflag; + 8'h43: key_I<=~releaseflag; + 8'h3B: key_J<=~releaseflag; + 8'h42: key_K<=~releaseflag; + 8'h4B: key_L<=~releaseflag; + 8'h3A: key_M<=~releaseflag; + 8'h31: key_N<=~releaseflag; + 8'h44: key_O<=~releaseflag; + 8'h4D: key_P<=~releaseflag; + 8'h15: key_Q<=~releaseflag; + 8'h2D: key_R<=~releaseflag; + 8'h1B: key_S<=~releaseflag; + 8'h2C: key_T<=~releaseflag; + 8'h3C: key_U<=~releaseflag; + 8'h2A: key_V<=~releaseflag; + 8'h1D: key_W<=~releaseflag; + 8'h22: key_X<=~releaseflag; + 8'h35: key_Y<=~releaseflag; + 8'h1A: key_Z<=~releaseflag; + 8'h69, + 8'h16: key_1<=~releaseflag; + 8'h72, + 8'h1E: key_2<=~releaseflag; + 8'h7A, + 8'h26: key_3<=~releaseflag; + 8'h6B, + 8'h25: key_4<=~releaseflag; + 8'h73, + 8'h2E: key_5<=~releaseflag; + 8'h74, + 8'h36: key_6<=~releaseflag; + 8'h6C, + 8'h3D: key_7<=~releaseflag; + 8'h75, + 8'h3E: key_8<=~releaseflag; + 8'h7D, + 8'h46: key_9<=~releaseflag; + 8'h70, + 8'h45: key_0<=~releaseflag; + 8'h66: key_del<=~releaseflag; + 8'h5A: key_return<=~releaseflag; + 8'h0C: key_help<=~releaseflag; + 8'h05: key_F1<=~releaseflag; + 8'h06: key_F2<=~releaseflag; + 8'h04: key_F3<=~releaseflag; + 8'h54: key_AT<=~releaseflag; + 8'h12, + 8'h59: key_shift<=~releaseflag; + 8'h41: key_comma<=~releaseflag; + 8'h49: key_dot<=~releaseflag; + 8'h7B, + 8'h4E: key_minus<=~releaseflag; + 8'h4C: key_colon<=~releaseflag; + 8'h7C, + 8'h5B: key_star<=~releaseflag; + 8'h52: key_semicolon<=~releaseflag; + 8'h76: key_esc<=~releaseflag; + 8'h5D: key_equal<=~releaseflag; + 8'h79, + 8'h55: key_plus<=~releaseflag; + 8'h4A: key_slash<=~releaseflag; + 8'h14: key_control<=~releaseflag; + 8'h29: key_space<=~releaseflag; + 8'h0D: key_runstop<=~releaseflag; + 8'h11: key_alt<=~releaseflag; + default:; + endcase + end + else begin // extended code keys + extendedflag<=0; + case(scancode) + 8'h2F: key_pound<=~releaseflag; + 8'h72: key_down<=~releaseflag; + 8'h75: key_up<=~releaseflag; + 8'h6B: key_left<=~releaseflag; + 8'h74: key_right<=~releaseflag; + 8'h6C: key_home<=~releaseflag; + 8'h14: key_control<=~releaseflag; + 8'h1F: key_commodore<=~releaseflag; + 8'h4A: key_slash<=~releaseflag; + 8'h5A: key_return<=~releaseflag; + 8'h71: key_del<=~releaseflag; + 8'h11: key_alt<=~releaseflag; + default:; + endcase + end + end + end + end + +always @(posedge clk) + begin + colsel[0]<=(key_del & rowsel[0]) | (key_3 & rowsel[1]) | (key_5 & rowsel[2]) | (key_7 & rowsel[3]) | (key_9 & rowsel[4]) | (key_down & rowsel[5]) | (key_left & rowsel[6]) | (key_1 & rowsel[7]); + colsel[1]<=(key_return & rowsel[0]) | (key_W & rowsel[1]) | (key_R & rowsel[2]) | (key_Y & rowsel[3]) | (key_I & rowsel[4]) | (key_P & rowsel[5]) | (key_star & rowsel[6]) | (key_home & rowsel[7]); + colsel[2]<=(key_pound & rowsel[0]) | (key_A & rowsel[1]) | (key_D & rowsel[2]) | (key_G & rowsel[3]) | (key_J & rowsel[4]) | (key_L & rowsel[5]) | (key_semicolon & rowsel[6]) | (key_control & rowsel[7]); + colsel[3]<=(key_help & rowsel[0]) | (key_4 & rowsel[1]) | (key_6 & rowsel[2]) | (key_8 & rowsel[3]) | (key_0 & rowsel[4]) | (key_up & rowsel[5]) | (key_right & rowsel[6]) | (key_2 & rowsel[7]); + colsel[4]<=(key_F1 & rowsel[0]) | (key_Z & rowsel[1]) | (key_C & rowsel[2]) | (key_B & rowsel[3]) | (key_M & rowsel[4]) | (key_dot & rowsel[5]) | (key_esc & rowsel[6]) | (key_space & rowsel[7]); + colsel[5]<=(key_F2 & rowsel[0]) | (key_S & rowsel[1]) | (key_F & rowsel[2]) | (key_H & rowsel[3]) | (key_K & rowsel[4]) | (key_colon & rowsel[5]) | (key_equal & rowsel[6]) | (key_commodore & rowsel[7]); + colsel[6]<=(key_F3 & rowsel[0]) | (key_E & rowsel[1]) | (key_T & rowsel[2]) | (key_U & rowsel[3]) | (key_O & rowsel[4]) | (key_minus & rowsel[5]) | (key_plus & rowsel[6]) | (key_Q & rowsel[7]); + colsel[7]<=(key_AT & rowsel[0]) | (key_shift & rowsel[1]) | (key_X & rowsel[2]) | (key_V & rowsel[3]) | (key_N & rowsel[4]) | (key_comma & rowsel[5]) | (key_slash & rowsel[6]) | (key_runstop & rowsel[7]); + end + +assign kbus=~colsel; + +endmodule diff --git a/cores/c16/c16_mist.qpf b/cores/c16/c16_mist.qpf new file mode 100644 index 0000000..b724044 --- /dev/null +++ b/cores/c16/c16_mist.qpf @@ -0,0 +1,30 @@ +# -------------------------------------------------------------------------- # +# +# 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 = 09:30:37 July 09, 2015 +# +# -------------------------------------------------------------------------- # + +QUARTUS_VERSION = "13.1" +DATE = "09:30:37 July 09, 2015" + +# Revisions + +PROJECT_REVISION = "c16_mist" diff --git a/cores/c16/c16_mist.qsf b/cores/c16/c16_mist.qsf new file mode 100644 index 0000000..a6389c0 --- /dev/null +++ b/cores/c16/c16_mist.qsf @@ -0,0 +1,343 @@ +# -------------------------------------------------------------------------- # +# +# 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 Full Version +# Date created = 01:27:30 May 03, 2016 +# +# -------------------------------------------------------------------------- # +# +# Notes: +# +# 1) The default values for assignments are stored in the file: +# C64_MiST_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 13.1 +set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:40:24 MAY 17, 2014" +set_global_assignment -name LAST_QUARTUS_VERSION 13.1 +set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files +set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL +set_global_assignment -name SMART_RECOMPILE ON +set_global_assignment -name FLOW_ENABLE_IO_ASSIGNMENT_ANALYSIS ON + +# 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_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 +set_location_assignment PLL_1 -to "pll:pll|altpll:altpll_component" + +# Classic Timing Assignments +# ========================== +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 + +# Analysis & Synthesis Assignments +# ================================ +set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE SPEED +set_global_assignment -name FAMILY "Cyclone III" +set_global_assignment -name TOP_LEVEL_ENTITY c16_mist +set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP +set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144 +set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON +set_global_assignment -name SAVE_DISK_SPACE OFF + +# Fitter Assignments +# ================== +set_global_assignment -name FITTER_EARLY_TIMING_ESTIMATE_MODE OPTIMISTIC +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON +set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON +set_global_assignment -name PHYSICAL_SYNTHESIS_MAP_LOGIC_TO_MEMORY_FOR_AREA ON +set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT EXTRA +set_global_assignment -name DEVICE EP3C25E144C8 +set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL" +set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON +set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL" +set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF +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" +set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO" +set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS" +set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON +set_global_assignment -name FITTER_EFFORT "AUTO FIT" + +# Assembler Assignments +# ===================== +set_global_assignment -name GENERATE_RBF_FILE ON +set_global_assignment -name USE_CONFIGURATION_DEVICE OFF + +# 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(C64_MiST) + +# Pin & Location Assignments +# ========================== + +# Fitter Assignments +# ================== + +# start DESIGN_PARTITION(Top) +# --------------------------- + +# Incremental Compilation Assignments +# =================================== + +# end DESIGN_PARTITION(Top) +# ------------------------- + +# end ENTITY(C64_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_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[2] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[3] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[4] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[5] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[6] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[7] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[8] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[9] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[10] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[11] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[12] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[13] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[14] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[15] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[2] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[3] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[4] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[5] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[6] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[7] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[8] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[9] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[10] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[11] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[12] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[0] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[1] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[2] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[3] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[4] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[5] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[6] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[7] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[8] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[9] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[10] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[11] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[12] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[13] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[14] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[15] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[2] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[3] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[4] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[5] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[6] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[7] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[8] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[9] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[10] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[11] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_A[12] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[2] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[3] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[4] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[5] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[6] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[7] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[8] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[9] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[10] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[11] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[12] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[13] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[14] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQ[15] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_BA[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_BA[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQML +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_DQMH +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_nRAS +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_nCAS +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_nWE +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_nCS +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SDRAM_CKE +set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[5] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[4] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[3] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[2] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[5] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[4] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[3] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[2] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[5] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[4] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[3] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[2] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_HS +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_VS +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to LED +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to CONF_DATA0 +set_global_assignment -name QIP_FILE pll_ntsc.qip +set_global_assignment -name QIP_FILE pll_pal.qip +set_global_assignment -name VERILOG_FILE data_io.v +set_global_assignment -name VERILOG_FILE sdram.v +set_global_assignment -name VERILOG_FILE osd.v +set_global_assignment -name VERILOG_FILE scandoubler.v +set_global_assignment -name VHDL_FILE cpu65xx_fast.vhd +set_global_assignment -name VHDL_FILE cpu65xx_e.vhd +set_global_assignment -name VERILOG_FILE user_io.v +set_global_assignment -name VERILOG_FILE ted.v +set_global_assignment -name VERILOG_FILE mos8501.v +set_global_assignment -name VERILOG_FILE mos6529.v +set_global_assignment -name VERILOG_FILE kernal_rom.v +set_global_assignment -name VERILOG_FILE colors_to_rgb.v +set_global_assignment -name VERILOG_FILE c16_mist.v +set_global_assignment -name VERILOG_FILE c16_keymatrix.v +set_global_assignment -name VERILOG_FILE c16.v +set_global_assignment -name VERILOG_FILE basic_rom.v +set_global_assignment -name SIGNALTAP_FILE stp1.stp +set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/cores/c16/c16_mist.v b/cores/c16/c16_mist.v new file mode 100644 index 0000000..a62690a --- /dev/null +++ b/cores/c16/c16_mist.v @@ -0,0 +1,601 @@ +// +// c16_mist.v - C16 for the MiST +// +// https://github.com/mist-devel +// +// Copyright (c) 2015 Till Harbaum +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +module c16_mist ( + input CLOCK_27, + + // LED outputs + output LED, // LED Yellow + + // SDRAM interface + inout [15:0] SDRAM_DQ, // SDRAM Data bus 16 Bits + output [12:0] SDRAM_A, // SDRAM Address bus 13 Bits + output SDRAM_DQML, // SDRAM Low-byte Data Mask + output SDRAM_DQMH, // SDRAM High-byte Data Mask + output SDRAM_nWE, // SDRAM Write Enable + output SDRAM_nCAS, // SDRAM Column Address Strobe + output SDRAM_nRAS, // SDRAM Row Address Strobe + output SDRAM_nCS, // SDRAM Chip Select + output [1:0] SDRAM_BA, // SDRAM Bank Address + output SDRAM_CLK, // SDRAM Clock + output SDRAM_CKE, // SDRAM Clock Enable + + // SPI interface to arm io controller + output SPI_DO, + input SPI_DI, + input SPI_SCK, + input SPI_SS2, + input SPI_SS3, + input SPI_SS4, + input CONF_DATA0, + + output AUDIO_L, // sigma-delta DAC output left + output AUDIO_R, // sigma-delta DAC output right + + output VGA_HS, + output VGA_VS, + output [5:0] VGA_R, + output [5:0] VGA_G, + output [5:0] VGA_B +); + +// ------------------------------------------------------------------------- +// ------------------------------ user_io ---------------------------------- +// ------------------------------------------------------------------------- + +// user_io implements a connection to the io controller and receives various +// kind of user input from there (keyboard, buttons, mouse). It is also used +// by the fake SD card to exchange data with the real sd card connected to the +// io controller + +// the configuration string is returned to the io controller to allow +// it to control the menu on the OSD +parameter CONF_STR = { + "C16;PRG;", + "O2,Scanlines,Off,On;", + "O3,Joysticks,Normal,Swapped;", + "T4,Reset" +}; + +parameter CONF_STR_LEN = 8+20+28+8; + +// the status register is controlled by the on screen display (OSD) +wire [7:0] status; +wire tv15khz; +wire scanlines = status[2]; +wire joystick_swap = status[3]; +wire osd_reset = status[4]; +wire [1:0] buttons; + +wire [7:0] js0, js1; +wire [7:0] jsA = joystick_swap?js1:js0; +wire [7:0] jsB = joystick_swap?js0:js1; + +wire ps2_kbd_clk, ps2_kbd_data; +wire ps2_mouse_clk, ps2_mouse_data; + +// generate ps2_clock +wire ps2_clock = ps2_clk_div[10]; // ~12khz +reg [10:0] ps2_clk_div; +always @(posedge clk28) + ps2_clk_div <= ps2_clk_div + 7'd1; + +// ------------------------------------------------------------------------- +// ---------------- interface to the external sdram ------------------------ +// ------------------------------------------------------------------------- + +// SDRAM control signals +assign SDRAM_CKE = 1'b1; + +// ram access signals from c16 +wire [15:0] c16_sdram_addr = { c16_a_hi, c16_a_low }; +wire [7:0] c16_sdram_data = c16_dout; +wire c16_sdram_wr = !c16_cas && !c16_rw; +wire c16_sdram_oe = !c16_cas && c16_rw; + +// ram access signals from io controller +// ioctl_sdram_write +// ioctl_sdram_addr +// ioctl_sdram_data + +// multiplex c16 and ioctl signals +wire [15:0] mux_sdram_addr = c16_wait?ioctl_sdram_addr:c16_sdram_addr; +wire [7:0] mux_sdram_data = c16_wait?ioctl_sdram_data:c16_sdram_data; +wire mux_sdram_wr = c16_wait?ioctl_sdram_write:c16_sdram_wr; +wire mux_sdram_oe = c16_wait?1'b0:c16_sdram_oe; + +wire [15:0] sdram_din = { mux_sdram_data, mux_sdram_data }; +wire [24:0] sdram_addr = { 10'h00, mux_sdram_addr[15:1] }; // 64k mapping +// wire [24:0] sdram_addr = { 12'h00, mux_sdram_addr[13:1] }; // 16k mapping +wire sdram_wr = mux_sdram_wr; +wire sdram_oe = mux_sdram_oe; +wire [1:0] sdram_ds = { mux_sdram_addr[0], !mux_sdram_addr[0] }; + +// only c16 reads from sdram +wire [15:0] sdram_dout; +wire [7:0] c16_din = zp_overwrite?zp_ovl_dout: + (c16_a_low[0]?sdram_dout[15:8]:sdram_dout[7:0]); + +assign SDRAM_CLK = ~clk28; + +// synchronize sdram state machine with the ras/cas phases of the c16 +reg last_ras; +reg [3:0] clkdiv; +wire clkref = clkdiv[3]; +always @(posedge clk28) begin + if(!c16_ras && last_ras) begin + clkdiv <= 4'd0; + last_ras <= c16_ras; + end else + clkdiv <= clkdiv + 4'd1; +end + +// latch/demultiplex dram address +reg [7:0] c16_a_low; +always @(negedge c16_ras) + c16_a_low <= c16_a; + +reg [7:0] c16_a_hi; +always @(negedge c16_cas) + c16_a_hi <= c16_a; + +sdram sdram ( + // interface to the MT48LC16M16 chip + .sd_data ( SDRAM_DQ ), + .sd_addr ( SDRAM_A ), + .sd_dqm ( {SDRAM_DQMH, SDRAM_DQML} ), + .sd_cs ( SDRAM_nCS ), + .sd_ba ( SDRAM_BA ), + .sd_we ( SDRAM_nWE ), + .sd_ras ( SDRAM_nRAS ), + .sd_cas ( SDRAM_nCAS ), + + // system interface + .clk ( clk28 ), + .clkref ( clkref ), + .init ( !pll_locked ), + + // cpu interface + .din ( sdram_din ), + .addr ( sdram_addr ), + .we ( sdram_wr ), + .oe ( sdram_oe ), + .ds ( sdram_ds ), + .dout ( sdram_dout ) +); + + +// --------------------------------------------------------------------------------- +// -------------------------------------- reset ------------------------------------ +// --------------------------------------------------------------------------------- + +reg [31:0] reset_cnt; +wire reset = (reset_cnt != 0); +always @(posedge clk28) begin + // long reset on startup and when io controller reboots + if(status[0] || !pll_locked) + reset_cnt <= 32'd28000000; + // short reset on reset button, reset osd or when io controller is + // done downloading + else if(buttons[1] || osd_reset || rom_download) + reset_cnt <= 32'd65536; + else if(reset_cnt != 0) + reset_cnt <= reset_cnt - 32'd1; +end + +// include user_io module for arm controller communication +user_io #(.STRLEN(CONF_STR_LEN)) user_io ( + .conf_str ( CONF_STR ), + + .SPI_CLK ( SPI_SCK ), + .SPI_SS_IO ( CONF_DATA0 ), + .SPI_MISO ( SPI_DO ), + .SPI_MOSI ( SPI_DI ), + + .scandoubler_disable ( tv15khz ), + .buttons ( buttons ), + + .joystick_0 ( js0 ), + .joystick_1 ( js1 ), + + // ps2 interface + .ps2_clk ( ps2_clock ), + .ps2_kbd_clk ( ps2_kbd_clk ), + .ps2_kbd_data ( ps2_kbd_data ), + .ps2_mouse_clk ( ps2_mouse_clk ), + .ps2_mouse_data ( ps2_mouse_data ), + + .status ( status ) +); + + +// --------------------------------------------------------------------------------- +// ------------------------------ prg memory injection ----------------------------- +// --------------------------------------------------------------------------------- + +wire ioctl_wr; +wire [15:0] ioctl_addr; +wire [7:0] ioctl_data; +wire [4:0] ioctl_index; +wire ioctl_downloading; + +wire rom_download = ioctl_downloading && (ioctl_index == 5'd0); +wire prg_download = ioctl_downloading && (ioctl_index == 5'd1); + +// halt cpu when it's done with the current cycle +reg c16_wait; +always @(posedge c16_ras) + c16_wait <= prg_download; + +data_io data_io ( + // SPI interface + .sck ( SPI_SCK ), + .ss ( SPI_SS2 ), + .sdi ( SPI_DI ), + + // ram interface + .downloading ( ioctl_downloading ), + .index ( ioctl_index ), + .clk ( clk28 ), + .wr ( ioctl_wr ), + .a ( ioctl_addr ), + .d ( ioctl_data ) +); + +// magic zero page shadow registers to allow the injector to set the +// basic program end pointers automagically after injection +reg [15:0] reg_2d; +reg [15:0] reg_2f; +reg [15:0] reg_31; +reg [15:0] reg_ae; + +wire zp_2d_sel = c16_sdram_addr == 16'h002d; +wire zp_2e_sel = c16_sdram_addr == 16'h002e; +wire zp_2f_sel = c16_sdram_addr == 16'h002f; +wire zp_30_sel = c16_sdram_addr == 16'h0030; +wire zp_31_sel = c16_sdram_addr == 16'h0031; +wire zp_32_sel = c16_sdram_addr == 16'h0032; +wire zp_ae_sel = c16_sdram_addr == 16'h00ae; +wire zp_af_sel = c16_sdram_addr == 16'h00af; + +wire zp_overwrite = + zp_2d_sel || zp_2e_sel || zp_2f_sel || zp_30_sel || + zp_31_sel || zp_32_sel || zp_ae_sel || zp_af_sel; + +reg zp_cas_delay, zp_sel; +reg zp_dl_delay, zp_dl; + +always @(posedge clk28) begin + // write pulse one cycle after falling edge of cas to make sure address + // is stable + zp_cas_delay <= c16_cas; + zp_sel <= !c16_cas && zp_cas_delay; + zp_dl_delay <= prg_download; + zp_dl <= !prg_download && zp_dl_delay; + + if(zp_dl) begin + // registers are automatically adjusted at the end of the + // download/injection + // the registers to be set have been taken from the vice emulator + reg_2d <= ioctl_sdram_addr + 16'd1; + reg_2f <= ioctl_sdram_addr + 16'd1; + reg_31 <= ioctl_sdram_addr + 16'd1; + reg_ae <= ioctl_sdram_addr + 16'd1; + end else if(zp_sel && !c16_rw) begin + // cpu writes registers + if(zp_2d_sel) reg_2d[ 7:0] <= c16_dout; + if(zp_2e_sel) reg_2d[15:8] <= c16_dout; + if(zp_2f_sel) reg_2f[ 7:0] <= c16_dout; + if(zp_30_sel) reg_2f[15:8] <= c16_dout; + if(zp_31_sel) reg_31[ 7:0] <= c16_dout; + if(zp_32_sel) reg_31[15:8] <= c16_dout; + if(zp_ae_sel) reg_ae[ 7:0] <= c16_dout; + if(zp_af_sel) reg_ae[15:8] <= c16_dout; + end +end + +wire [7:0] zp_ovl_dout = + zp_2d_sel?reg_2d[7:0]:zp_2e_sel?reg_2d[15:8]: + zp_2f_sel?reg_2f[7:0]:zp_30_sel?reg_2f[15:8]: + zp_31_sel?reg_31[7:0]:zp_32_sel?reg_31[15:8]: + zp_ae_sel?reg_ae[7:0]:zp_af_sel?reg_ae[15:8]: + 8'hff; + +// the address taken from the first to bytes of a prg file tell +// us where the file is to go in memory +reg [15:0] ioctl_load_addr /* synthesis noprune */; +reg ioctl_ram_wr /* synthesis noprune */; +reg ioctl_sdram_write /* synthesis noprune */; +reg [15:0] ioctl_sdram_addr /* synthesis noprune */; +reg [7:0] ioctl_sdram_data /* synthesis noprune */; + +always @(negedge c16_ras) begin + ioctl_sdram_write <= ioctl_ram_wr; + + if(ioctl_ram_wr) begin + ioctl_sdram_addr <= ioctl_load_addr + ioctl_addr - 16'd2; + ioctl_sdram_data <= ioctl_data; + end +end + +// address starts counting with 0 +always @(negedge clk28) begin + if(ioctl_sdram_write) + ioctl_ram_wr <= 1'b0; + + // data io has a byte for us + if(ioctl_wr) begin + if(ioctl_addr == 16'h0000) + ioctl_load_addr[7:0] <= ioctl_data; + else if (ioctl_addr == 16'h0001) + ioctl_load_addr[15:8] <= ioctl_data; + else + // io controller sent a new byte. Store it until it can be + // saved in RAM + ioctl_ram_wr <= 1'b1; + end +end + + +// --------------------------------------------------------------------------------- +// ------------------------------ the on screen display ---------------------------- +// --------------------------------------------------------------------------------- + +// in 15khz mode feed the c16 video directly into the OSD, +// bypassing the scan doubler +wire [5:0] osd_r_in = tv15khz?{c16_r, 2'b00}:video_r; +wire [5:0] osd_g_in = tv15khz?{c16_g, 2'b00}:video_g; +wire [5:0] osd_b_in = tv15khz?{c16_b, 2'b00}:video_b; +wire osd_hs_in = tv15khz?!c16_hs:video_hs; +wire osd_vs_in = tv15khz?!c16_vs:video_vs; + +wire osd_clk = tv15khz?clk7:clk28; + +// include the on screen display +osd #(11,0,5) osd ( + .pclk ( osd_clk ), + + // spi for OSD + .sdi ( SPI_DI ), + .sck ( SPI_SCK ), + .ss ( SPI_SS3 ), + + .red_in ( osd_r_in ), + .green_in ( osd_g_in ), + .blue_in ( osd_b_in ), + .hs_in ( osd_hs_in ), + .vs_in ( osd_vs_in ), + + .red_out ( VGA_R ), + .green_out ( VGA_G ), + .blue_out ( VGA_B ) +); + +// in 15khz tv mode directly use the c16's composite sync. Otherwise the VGA +// output is driven from the sync signals generated by the scan doubler. In +// 15khz mode the VS signal is used as the RGB detect signal on the SCART +// connector and thus needs to be driven to 1 +assign VGA_HS = tv15khz?c16_cs:video_hs; +assign VGA_VS = tv15khz?1'b1:video_vs; + +wire video_hs, video_vs; +wire [5:0] video_r; +wire [5:0] video_g; +wire [5:0] video_b; + +scandoubler scandoubler ( + // system interface + .clk_sys ( clk28 ), + + // scanlines (00-none 01-25% 10-50% 11-75%) + .scanlines ( scanlines?2'b10:2'b00 ), + + // shifter video interface + .hs_in ( !c16_hs ), + .vs_in ( !c16_vs ), + .r_in ( c16_r ), + .g_in ( c16_g ), + .b_in ( c16_b ), + + // output interface + .hs_out ( video_hs ), + .vs_out ( video_vs ), + .r_out ( video_r ), + .g_out ( video_g ), + .b_out ( video_b ) +); + +// --------------------------------------------------------------------------------- +// ------------------------------------ c16 core ----------------------------------- +// --------------------------------------------------------------------------------- + +// c16 generated video signals +wire c16_hs, c16_vs, c16_cs; +wire [3:0] c16_r; +wire [3:0] c16_g; +wire [3:0] c16_b; +wire c16_pal; + +// c16 generated ram access signals +wire c16_ras; +wire c16_cas; +wire c16_rw; +wire [7:0] c16_a; +wire [7:0] c16_dout; + +reg kernal_dl_wr; +reg [7:0] kernal_dl_data; +reg [13:0] kernal_dl_addr; + +wire ioctl_kernal_wr = rom_download && ioctl_wr; + +reg last_ioctl_wr; +always @(negedge clk28) begin + last_ioctl_wr <= ioctl_kernal_wr; + if(ioctl_kernal_wr && !last_ioctl_wr) begin + kernal_dl_data <= ioctl_data; + kernal_dl_addr <= ioctl_addr[13:0]; + kernal_dl_wr <= 1'b1; + end else + kernal_dl_wr <= 1'b0; +end + +// include the c16 itself +C16 c16 ( + .CLK28 ( clk28 ), + .RESET ( reset ), + .WAIT ( c16_wait ), + .HSYNC ( c16_hs ), + .VSYNC ( c16_vs ), + .CSYNC ( c16_cs ), + .RED ( c16_r ), + .GREEN ( c16_g ), + .BLUE ( c16_b ), + + .RAS ( c16_ras ), + .CAS ( c16_cas ), + .RW ( c16_rw ), + .A ( c16_a ), + .DOUT ( c16_dout ), + .DIN ( c16_din ), + + .JOY0 ( jsB[4:0] ), + .JOY1 ( jsA[4:0] ), + + .PS2DAT ( ps2_kbd_data ), + .PS2CLK ( ps2_kbd_clk ), + + .kernal_dl_addr ( kernal_dl_addr ), + .kernal_dl_data ( kernal_dl_data ), + .kernal_dl_write ( kernal_dl_wr), + +/* + .IEC_DATAOUT ( c16_iec_data_o ), + .IEC_DATAIN ( c16_iec_data_i ), + .IEC_CLKOUT ( c16_iec_clk_o ), + .IEC_CLKIN ( c16_iec_clk_i ), + .IEC_ATNOUT ( c16_iec_atn_o ), + // .IEC_ATNIN, + .IEC_RESET ( ), +*/ + .IEC_DATAIN ( 1'b1 ), + .IEC_CLKIN ( 1'b1 ), + + .AUDIO_L ( AUDIO_L ), + .AUDIO_R ( AUDIO_R ), + + .PAL ( c16_pal ), + + .RS232_TX (), + .RGBS () +); + + +// --------------------------------------------------------------------------------- +// ------------------------------- clock generation -------------------------------- +// --------------------------------------------------------------------------------- + +// the FPGATED uses two different clocks for NTSC and PAL mode. +// Switching the clocks may crash the system. We might need to force a reset it. +wire clk28 = c16_pal?clk28_pal:clk28_ntsc; +wire pll_locked = pll_pal_locked && pll_ntsc_locked; + +// tv15hkz has quarter the pixel rate, so we need a 7mhz clock for the OSD +reg clk7; +always @(posedge clk14) + clk7 <= !clk7; + +reg clk14; +always @(posedge clk28) + clk14 <= !clk14; + +// A PLL to derive the system clock from the MiSTs 27MHz +wire pll_pal_locked, clk28_pal; +pll_pal pll_pal ( + .inclk0( CLOCK_27 ), + .c0( clk28_pal ), + .locked( pll_pal_locked ) +); + +wire pll_ntsc_locked, clk28_ntsc; +pll_ntsc pll_ntsc ( + .inclk0( CLOCK_27 ), + .c0( clk28_ntsc ), + .locked( pll_ntsc_locked ) +); + + + +/* +// --------------------------------------------------------------------------------- +// ----------------------------------- floppy 1541 --------------------------------- +// --------------------------------------------------------------------------------- + +wire [7:0] led_disk; +assign LED = !led_disk[6]; + +wire c16_iec_atn_o; +wire c16_iec_data_o; +wire c16_iec_clk_o; + +wire c16_iec_atn_i = !((!c16_iec_atn_o) & (!c1541_iec_atn_o) ); +wire c16_iec_data_i = !((!c16_iec_data_o) & (!c1541_iec_data_o)); +wire c16_iec_clk_i = !((!c16_iec_clk_o) & (!c1541_iec_clk_o) ); + +wire c1541_iec_atn_o; +wire c1541_iec_data_o; +wire c1541_iec_clk_o; + +wire c1541_iec_atn_i = c16_iec_atn_i; +wire c1541_iec_data_i = c16_iec_data_i; +wire c1541_iec_clk_i = c16_iec_clk_i; + + +c1541_sd c1541_sd ( + .clk32 ( clk32 ), + .clk18 ( clk28 ), // MiST uses virtual SPI SD, so any clock can be used. + .reset ( reset ), + + .c1541rom_addr ( 14'h0000 ), + .c1541rom_data ( 8'h00 ), + .c1541rom_wr ( 1'b0 ), + + .disk_change (), + .disk_num ( 10'd0 ), // not seletable by f8 or similar + + .iec_atn_i ( c1541_iec_atn_i ), + .iec_data_i ( c1541_iec_data_i ), + .iec_clk_i ( c1541_iec_clk_i ), + + .iec_atn_o ( c1541_iec_atn_o ), + .iec_data_o ( c1541_iec_data_o ), + .iec_clk_o ( c1541_iec_clk_o ), + + .sd_dat ( 1'b1 ), + .sd_dat3 (), + .sd_cmd (), + .sd_clk (), + + .led ( led_disk ) +); +*/ + +endmodule diff --git a/cores/c16/colors_to_rgb.v b/cores/c16/colors_to_rgb.v new file mode 100644 index 0000000..5c97822 --- /dev/null +++ b/cores/c16/colors_to_rgb.v @@ -0,0 +1,183 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Copyright 2013-2016 Istvan Hegedus +// +// FPGATED is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// FPGATED is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Create Date: 22:03:30 11/20/2014 +// Design Name: Commodore Plus/4 color value conversion to 12bit RGB values +// Module Name: colors_to_rgb.v +// Project Name: FPGATED +// Target Devices: Xilinx Spartan 3E +// +// Description: +// Converts TED's 7 bit color codes to 12 bit RGB values used by video DAC. +// 12 bit DAC values from Jozsef Laszlo +// +// Revisions: +// Revision 0.1 - File Created +// +////////////////////////////////////////////////////////////////////////////////// +module colors_to_rgb( + input clk, + input [6:0] color, + output [3:0] red, + output [3:0] green, + output [3:0] blue + ); +reg [11:0] color_lut [127:0]; +reg [11:0] rgbcolor; + +initial + begin + color_lut[0]=12'b0000_0000_0000; + color_lut[1]=12'b0010_0010_0010; + color_lut[2]=12'b0101_0000_0000; + color_lut[3]=12'b0000_0011_0011; + color_lut[4]=12'b0100_0000_0101; + color_lut[5]=12'b0000_0100_0000; + color_lut[6]=12'b0001_0001_0111; + color_lut[7]=12'b0010_0010_0000; + color_lut[8]=12'b0100_0001_0000; + color_lut[9]=12'b0011_0010_0000; + color_lut[10]=12'b0001_0011_0000; + color_lut[11]=12'b0101_0000_0010; + color_lut[12]=12'b0000_0011_0001; + color_lut[13]=12'b0000_0010_0110; + color_lut[14]=12'b0001_0001_0111; + color_lut[15]=12'b0000_0011_0000; + color_lut[16]=12'b0000_0000_0000; + color_lut[17]=12'b0010_0010_0010; + color_lut[18]=12'b0110_0001_0001; + color_lut[19]=12'b0000_0100_0100; + color_lut[20]=12'b0101_0000_0110; + color_lut[21]=12'b0000_0100_0000; + color_lut[22]=12'b0010_0010_1000; + color_lut[23]=12'b0011_0011_0000; + color_lut[24]=12'b0101_0010_0000; + color_lut[25]=12'b0100_0010_0000; + color_lut[26]=12'b0010_0100_0000; + color_lut[27]=12'b0110_0001_0011; + color_lut[28]=12'b0000_0100_0010; + color_lut[29]=12'b0000_0011_0111; + color_lut[30]=12'b0010_0001_1000; + color_lut[31]=12'b0001_0100_0000; + color_lut[32]=12'b0000_0000_0000; + color_lut[33]=12'b0011_0011_0011; + color_lut[34]=12'b0110_0010_0010; + color_lut[35]=12'b0000_0101_0101; + color_lut[36]=12'b0110_0001_0111; + color_lut[37]=12'b0000_0101_0000; + color_lut[38]=12'b0010_0011_1001; + color_lut[39]=12'b0100_0100_0000; + color_lut[40]=12'b0110_0010_0000; + color_lut[41]=12'b0101_0011_0000; + color_lut[42]=12'b0010_0101_0000; + color_lut[43]=12'b0110_0001_0100; + color_lut[44]=12'b0000_0101_0011; + color_lut[45]=12'b0001_0011_1000; + color_lut[46]=12'b0011_0010_1001; + color_lut[47]=12'b0001_0101_0000; + color_lut[48]=12'b0000_0000_0000; + color_lut[49]=12'b0100_0100_0100; + color_lut[50]=12'b0111_0011_0011; + color_lut[51]=12'b0001_0110_0110; + color_lut[52]=12'b0111_0010_1000; + color_lut[53]=12'b0001_0110_0010; + color_lut[54]=12'b0100_0100_1010; + color_lut[55]=12'b0101_0101_0000; + color_lut[56]=12'b0111_0100_0001; + color_lut[57]=12'b0110_0100_0000; + color_lut[58]=12'b0011_0110_0000; + color_lut[59]=12'b0111_0011_0101; + color_lut[60]=12'b0001_0110_0100; + color_lut[61]=12'b0010_0100_1001; + color_lut[62]=12'b0100_0011_1010; + color_lut[63]=12'b0011_0110_0000; + color_lut[64]=12'b0000_0000_0000; + color_lut[65]=12'b0110_0110_0110; + color_lut[66]=12'b1010_0101_0101; + color_lut[67]=12'b0011_1000_1000; + color_lut[68]=12'b1001_0100_1010; + color_lut[69]=12'b0100_1000_0100; + color_lut[70]=12'b0110_0110_1100; + color_lut[71]=12'b0111_0111_0001; + color_lut[72]=12'b1001_0110_0011; + color_lut[73]=12'b1000_0110_0010; + color_lut[74]=12'b0110_1000_0001; + color_lut[75]=12'b1010_0101_0111; + color_lut[76]=12'b0011_1000_0110; + color_lut[77]=12'b0100_0111_1011; + color_lut[78]=12'b0110_0101_1100; + color_lut[79]=12'b0101_1000_0010; + color_lut[80]=12'b0000_0000_0000; + color_lut[81]=12'b1000_1000_1000; + color_lut[82]=12'b1011_0111_0111; + color_lut[83]=12'b0101_1001_1001; + color_lut[84]=12'b1011_0110_1011; + color_lut[85]=12'b0101_1010_0101; + color_lut[86]=12'b0111_0111_1110; + color_lut[87]=12'b1001_1001_0010; + color_lut[88]=12'b1011_0111_0101; + color_lut[89]=12'b1010_1000_0011; + color_lut[90]=12'b0111_1001_0010; + color_lut[91]=12'b1011_0110_1001; + color_lut[92]=12'b0101_1010_1000; + color_lut[93]=12'b0110_1000_1101; + color_lut[94]=12'b1000_0111_1110; + color_lut[95]=12'b0110_1010_0011; + color_lut[96]=12'b0000_0000_0000; + color_lut[97]=12'b1011_1011_1011; + color_lut[98]=12'b1110_1001_1001; + color_lut[99]=12'b1000_1100_1100; + color_lut[100]=12'b1101_1001_1110; + color_lut[101]=12'b1000_1101_1000; + color_lut[102]=12'b1010_1010_1111; + color_lut[103]=12'b1011_1011_0101; + color_lut[104]=12'b1101_1010_1000; + color_lut[105]=12'b1100_1011_0110; + color_lut[106]=12'b1010_1100_0101; + color_lut[107]=12'b1110_1001_1011; + color_lut[108]=12'b0111_1100_1010; + color_lut[109]=12'b1001_1011_1111; + color_lut[110]=12'b1010_1010_1111; + color_lut[111]=12'b1001_1100_0110; + color_lut[112]=12'b0000_0000_0000; + color_lut[113]=12'b1110_1110_1110; + color_lut[114]=12'b1111_1101_1101; + color_lut[115]=12'b1011_1111_1111; + color_lut[116]=12'b1111_1100_1111; + color_lut[117]=12'b1100_1111_1100; + color_lut[118]=12'b1110_1110_1111; + color_lut[119]=12'b1111_1111_1001; + color_lut[120]=12'b1111_1110_1011; + color_lut[121]=12'b1111_1110_1010; + color_lut[122]=12'b1110_1111_1001; + color_lut[123]=12'b1111_1101_1111; + color_lut[124]=12'b1011_1111_1110; + color_lut[125]=12'b1100_1110_1111; + color_lut[126]=12'b1110_1101_1111; + color_lut[127]=12'b1101_1111_1010; + end + +always @(posedge clk) + begin + rgbcolor<=color_lut[color]; + end + +assign red=rgbcolor[11:8]; +assign green=rgbcolor[7:4]; +assign blue=rgbcolor[3:0]; + +endmodule diff --git a/cores/c16/cpu65xx_e.vhd b/cores/c16/cpu65xx_e.vhd new file mode 100644 index 0000000..d15f0d8 --- /dev/null +++ b/cores/c16/cpu65xx_e.vhd @@ -0,0 +1,48 @@ +-- ----------------------------------------------------------------------- +-- +-- FPGA 64 +-- +-- A fully functional commodore 64 implementation in a single FPGA +-- +-- ----------------------------------------------------------------------- +-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) +-- http://www.syntiac.com/fpga64.html +-- ----------------------------------------------------------------------- +-- +-- Interface to 6502/6510 core +-- +-- ----------------------------------------------------------------------- + +library IEEE; +use ieee.std_logic_1164.ALL; +use ieee.numeric_std.ALL; + +-- ----------------------------------------------------------------------- + +entity cpu65xx is + generic ( + pipelineOpcode : boolean; + pipelineAluMux : boolean; + pipelineAluOut : boolean + ); + port ( + clk : in std_logic; + enable : in std_logic; + reset : in std_logic; + nmi_n : in std_logic; + irq_n : in std_logic; + so_n : in std_logic := '1'; + + di : in unsigned(7 downto 0); + do : out unsigned(7 downto 0); + addr : out unsigned(15 downto 0); + we : out std_logic; + + debugOpcode : out unsigned(7 downto 0); + debugPc : out unsigned(15 downto 0); + debugA : out unsigned(7 downto 0); + debugX : out unsigned(7 downto 0); + debugY : out unsigned(7 downto 0); + debugS : out unsigned(7 downto 0) + ); +end cpu65xx; diff --git a/cores/c16/cpu65xx_fast.vhd b/cores/c16/cpu65xx_fast.vhd new file mode 100644 index 0000000..190a2c6 --- /dev/null +++ b/cores/c16/cpu65xx_fast.vhd @@ -0,0 +1,1565 @@ +-- ----------------------------------------------------------------------- +-- +-- FPGA 64 +-- +-- A fully functional commodore 64 implementation in a single FPGA +-- +-- ----------------------------------------------------------------------- +-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com) +-- http://www.syntiac.com/fpga64.html +-- ----------------------------------------------------------------------- +-- +-- Table driven, cycle exact 6502/6510 core +-- +-- ----------------------------------------------------------------------- + +library IEEE; +use ieee.std_logic_1164.ALL; +use ieee.std_logic_unsigned.ALL; +use ieee.numeric_std.ALL; + +-- ----------------------------------------------------------------------- + +-- Store Zp (3) => fetch, cycle2, cycleEnd +-- Store Zp,x (4) => fetch, cycle2, preWrite, cycleEnd +-- Read Zp,x (4) => fetch, cycle2, cycleRead, cycleRead2 +-- Rmw Zp,x (6) => fetch, cycle2, cycleRead, cycleRead2, cycleRmw, cycleEnd +-- Store Abs (4) => fetch, cycle2, cycle3, cycleEnd +-- Store Abs,x (5) => fetch, cycle2, cycle3, preWrite, cycleEnd +-- Rts (6) => fetch, cycle2, cycle3, cycleRead, cycleJump, cycleIncrEnd +-- Rti (6) => fetch, cycle2, stack1, stack2, stack3, cycleJump +-- Jsr (6) => fetch, cycle2, .. cycle5, cycle6, cycleJump +-- Jmp abs (-) => fetch, cycle2, .., cycleJump +-- Jmp (ind) (-) => fetch, cycle2, .., cycleJump +-- Brk / irq (6) => fetch, cycle2, stack2, stack3, stack4 +-- ----------------------------------------------------------------------- + +architecture fast of cpu65xx is +-- Statemachine + type cpuCycles is ( + opcodeFetch, -- New opcode is read and registers updated + cycle2, + cycle3, + cyclePreIndirect, + cycleIndirect, + cycleBranchTaken, + cycleBranchPage, + cyclePreRead, -- Cycle before read while doing zeropage indexed addressing. + cycleRead, -- Read cycle + cycleRead2, -- Second read cycle after page-boundary crossing. + cycleRmw, -- Calculate ALU output for read-modify-write instr. + cyclePreWrite, -- Cycle before write when doing indexed addressing. + cycleWrite, -- Write cycle for zeropage or absolute addressing. + cycleStack1, + cycleStack2, + cycleStack3, + cycleStack4, + cycleJump, -- Last cycle of Jsr, Jmp. Next fetch address is target addr. + cycleEnd + ); + signal theCpuCycle : cpuCycles; + signal nextCpuCycle : cpuCycles; + signal updateRegisters : boolean; + signal processIrq : std_logic; + signal nmiReg: std_logic; + signal nmiEdge: std_logic; + signal irqReg : std_logic; -- Delay IRQ input with one clock cycle. + signal soReg : std_logic; -- SO pin edge detection + +-- Opcode decoding + constant opcUpdateA : integer := 0; + constant opcUpdateX : integer := 1; + constant opcUpdateY : integer := 2; + constant opcUpdateS : integer := 3; + constant opcUpdateN : integer := 4; + constant opcUpdateV : integer := 5; + constant opcUpdateD : integer := 6; + constant opcUpdateI : integer := 7; + constant opcUpdateZ : integer := 8; + constant opcUpdateC : integer := 9; + + constant opcSecondByte : integer := 10; + constant opcAbsolute : integer := 11; + constant opcZeroPage : integer := 12; + constant opcIndirect : integer := 13; + constant opcStackAddr : integer := 14; -- Push/Pop address + constant opcStackData : integer := 15; -- Push/Pop status/data + constant opcJump : integer := 16; + constant opcBranch : integer := 17; + constant indexX : integer := 18; + constant indexY : integer := 19; + constant opcStackUp : integer := 20; + constant opcWrite : integer := 21; + constant opcRmw : integer := 22; + constant opcIncrAfter : integer := 23; -- Insert extra cycle to increment PC (RTS) + constant opcRti : integer := 24; + constant opcIRQ : integer := 25; + + constant opcInA : integer := 26; + constant opcInE : integer := 27; + constant opcInX : integer := 28; + constant opcInY : integer := 29; + constant opcInS : integer := 30; + constant opcInT : integer := 31; + constant opcInH : integer := 32; + constant opcInClear : integer := 33; + constant aluMode1From : integer := 34; + -- + constant aluMode1To : integer := 37; + constant aluMode2From : integer := 38; + -- + constant aluMode2To : integer := 40; + -- + constant opcInCmp : integer := 41; + constant opcInCpx : integer := 42; + constant opcInCpy : integer := 43; + + + subtype addrDef is unsigned(0 to 15); + -- + -- is Interrupt -----------------+ + -- instruction is RTI ----------------+| + -- PC++ on last cycle (RTS) ---------------+|| + -- RMW --------------+||| + -- Write -------------+|||| + -- Pop/Stack up -------------+||||| + -- Branch ---------+ |||||| + -- Jump ----------+| |||||| + -- Push or Pop data -------+|| |||||| + -- Push or Pop addr ------+||| |||||| + -- Indirect -----+|||| |||||| + -- ZeroPage ----+||||| |||||| + -- Absolute ---+|||||| |||||| + -- PC++ on cycle2 --+||||||| |||||| + -- |AZI||JBXY|WM||| + constant immediate : addrDef := "1000000000000000"; + constant implied : addrDef := "0000000000000000"; + -- Zero page + constant readZp : addrDef := "1010000000000000"; + constant writeZp : addrDef := "1010000000010000"; + constant rmwZp : addrDef := "1010000000001000"; + -- Zero page indexed + constant readZpX : addrDef := "1010000010000000"; + constant writeZpX : addrDef := "1010000010010000"; + constant rmwZpX : addrDef := "1010000010001000"; + constant readZpY : addrDef := "1010000001000000"; + constant writeZpY : addrDef := "1010000001010000"; + constant rmwZpY : addrDef := "1010000001001000"; + -- Zero page indirect + constant readIndX : addrDef := "1001000010000000"; + constant writeIndX : addrDef := "1001000010010000"; + constant rmwIndX : addrDef := "1001000010001000"; + constant readIndY : addrDef := "1001000001000000"; + constant writeIndY : addrDef := "1001000001010000"; + constant rmwIndY : addrDef := "1001000001001000"; + -- |AZI||JBXY|WM|| + -- Absolute + constant readAbs : addrDef := "1100000000000000"; + constant writeAbs : addrDef := "1100000000010000"; + constant rmwAbs : addrDef := "1100000000001000"; + constant readAbsX : addrDef := "1100000010000000"; + constant writeAbsX : addrDef := "1100000010010000"; + constant rmwAbsX : addrDef := "1100000010001000"; + constant readAbsY : addrDef := "1100000001000000"; + constant writeAbsY : addrDef := "1100000001010000"; + constant rmwAbsY : addrDef := "1100000001001000"; + -- PHA PHP + constant push : addrDef := "0000010000000000"; + -- PLA PLP + constant pop : addrDef := "0000010000100000"; + -- Jumps + constant jsr : addrDef := "1000101000000000"; + constant jumpAbs : addrDef := "1000001000000000"; + constant jumpInd : addrDef := "1100001000000000"; + constant relative : addrDef := "1000000100000000"; + -- Specials + constant rts : addrDef := "0000101000100100"; + constant rti : addrDef := "0000111000100010"; + constant brk : addrDef := "1000111000000001"; +-- constant : unsigned(0 to 0) := "0"; + constant xxxxxxxx : addrDef := "----------0---00"; + + -- A = accu + -- E = Accu | 0xEE (for ANE, LXA) + -- X = index X + -- Y = index Y + -- S = Stack pointer + -- H = indexH + -- + -- AEXYSTHc + constant aluInA : unsigned(0 to 7) := "10000000"; + constant aluInE : unsigned(0 to 7) := "01000000"; + constant aluInEXT : unsigned(0 to 7) := "01100100"; + constant aluInET : unsigned(0 to 7) := "01000100"; + constant aluInX : unsigned(0 to 7) := "00100000"; + constant aluInXH : unsigned(0 to 7) := "00100010"; + constant aluInY : unsigned(0 to 7) := "00010000"; + constant aluInYH : unsigned(0 to 7) := "00010010"; + constant aluInS : unsigned(0 to 7) := "00001000"; + constant aluInT : unsigned(0 to 7) := "00000100"; + constant aluInAX : unsigned(0 to 7) := "10100000"; + constant aluInAXH : unsigned(0 to 7) := "10100010"; + constant aluInAT : unsigned(0 to 7) := "10000100"; + constant aluInXT : unsigned(0 to 7) := "00100100"; + constant aluInST : unsigned(0 to 7) := "00001100"; + constant aluInSet : unsigned(0 to 7) := "00000000"; + constant aluInClr : unsigned(0 to 7) := "00000001"; + constant aluInXXX : unsigned(0 to 7) := "--------"; + + -- Most of the aluModes are just like the opcodes. + -- aluModeInp -> input is output. calculate N and Z + -- aluModeCmp -> Compare for CMP, CPX, CPY + -- aluModeFlg -> input to flags needed for PLP, RTI and CLC, SEC, CLV + -- aluModeInc -> for INC but also INX, INY + -- aluModeDec -> for DEC but also DEX, DEY + + subtype aluMode1 is unsigned(0 to 3); + subtype aluMode2 is unsigned(0 to 2); + subtype aluMode is unsigned(0 to 9); + + -- Logic/Shift ALU + constant aluModeInp : aluMode1 := "0000"; + constant aluModeP : aluMode1 := "0001"; + constant aluModeInc : aluMode1 := "0010"; + constant aluModeDec : aluMode1 := "0011"; + constant aluModeFlg : aluMode1 := "0100"; + constant aluModeBit : aluMode1 := "0101"; + -- 0110 + -- 0111 + constant aluModeLsr : aluMode1 := "1000"; + constant aluModeRor : aluMode1 := "1001"; + constant aluModeAsl : aluMode1 := "1010"; + constant aluModeRol : aluMode1 := "1011"; + -- 1100 + -- 1101 + -- 1110 + constant aluModeAnc : aluMode1 := "1111"; + + -- Arithmetic ALU + constant aluModePss : aluMode2 := "000"; + constant aluModeCmp : aluMode2 := "001"; + constant aluModeAdc : aluMode2 := "010"; + constant aluModeSbc : aluMode2 := "011"; + constant aluModeAnd : aluMode2 := "100"; + constant aluModeOra : aluMode2 := "101"; + constant aluModeEor : aluMode2 := "110"; + constant aluModeArr : aluMode2 := "111"; + + + constant aluInp : aluMode := aluModeInp & aluModePss & "---"; + constant aluP : aluMode := aluModeP & aluModePss & "---"; + constant aluInc : aluMode := aluModeInc & aluModePss & "---"; + constant aluDec : aluMode := aluModeDec & aluModePss & "---"; + constant aluFlg : aluMode := aluModeFlg & aluModePss & "---"; + constant aluBit : aluMode := aluModeBit & aluModeAnd & "---"; + constant aluRor : aluMode := aluModeRor & aluModePss & "---"; + constant aluLsr : aluMode := aluModeLsr & aluModePss & "---"; + constant aluRol : aluMode := aluModeRol & aluModePss & "---"; + constant aluAsl : aluMode := aluModeAsl & aluModePss & "---"; + + constant aluCmp : aluMode := aluModeInp & aluModeCmp & "100"; + constant aluCpx : aluMode := aluModeInp & aluModeCmp & "010"; + constant aluCpy : aluMode := aluModeInp & aluModeCmp & "001"; + constant aluAdc : aluMode := aluModeInp & aluModeAdc & "---"; + constant aluSbc : aluMode := aluModeInp & aluModeSbc & "---"; + constant aluAnd : aluMode := aluModeInp & aluModeAnd & "---"; + constant aluOra : aluMode := aluModeInp & aluModeOra & "---"; + constant aluEor : aluMode := aluModeInp & aluModeEor & "---"; + + constant aluSlo : aluMode := aluModeAsl & aluModeOra & "---"; + constant aluSre : aluMode := aluModeLsr & aluModeEor & "---"; + constant aluRra : aluMode := aluModeRor & aluModeAdc & "---"; + constant aluRla : aluMode := aluModeRol & aluModeAnd & "---"; + constant aluDcp : aluMode := aluModeDec & aluModeCmp & "100"; + constant aluIsc : aluMode := aluModeInc & aluModeSbc & "---"; + constant aluAnc : aluMode := aluModeAnc & aluModeAnd & "---"; + constant aluArr : aluMode := aluModeRor & aluModeArr & "---"; + constant aluSbx : aluMode := aluModeInp & aluModeCmp & "110"; + + constant aluXXX : aluMode := (others => '-'); + + + -- Stack operations. Push/Pop/None + constant stackInc : unsigned(0 to 0) := "0"; + constant stackDec : unsigned(0 to 0) := "1"; + constant stackXXX : unsigned(0 to 0) := "-"; + + subtype decodedBitsDef is unsigned(0 to 43); + type opcodeInfoTableDef is array(0 to 255) of decodedBitsDef; + constant opcodeInfoTable : opcodeInfoTableDef := ( + -- +------- Update register A + -- |+------ Update register X + -- ||+----- Update register Y + -- |||+---- Update register S + -- |||| +-- Update Flags + -- |||| | + -- |||| _|__ + -- |||| / \ + -- AXYS NVDIZC addressing aluInput aluMode + "0000" & "000100" & brk & aluInXXX & aluP, -- 00 BRK + "1000" & "100010" & readIndX & aluInT & aluOra, -- 01 ORA (zp,x) + "----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- 02 *** JAM *** + "1000" & "100011" & rmwIndX & aluInT & aluSlo, -- 03 iSLO (zp,x) + "0000" & "000000" & readZp & aluInXXX & aluXXX, -- 04 iNOP zp + "1000" & "100010" & readZp & aluInT & aluOra, -- 05 ORA zp + "0000" & "100011" & rmwZp & aluInT & aluAsl, -- 06 ASL zp + "1000" & "100011" & rmwZp & aluInT & aluSlo, -- 07 iSLO zp + "0000" & "000000" & push & aluInXXX & aluP, -- 08 PHP + "1000" & "100010" & immediate & aluInT & aluOra, -- 09 ORA imm + "1000" & "100011" & implied & aluInA & aluAsl, -- 0A ASL accu + "1000" & "100011" & immediate & aluInT & aluAnc, -- 0B iANC imm + "0000" & "000000" & readAbs & aluInXXX & aluXXX, -- 0C iNOP abs + "1000" & "100010" & readAbs & aluInT & aluOra, -- 0D ORA abs + "0000" & "100011" & rmwAbs & aluInT & aluAsl, -- 0E ASL abs + "1000" & "100011" & rmwAbs & aluInT & aluSlo, -- 0F iSLO abs + "0000" & "000000" & relative & aluInXXX & aluXXX, -- 10 BPL + "1000" & "100010" & readIndY & aluInT & aluOra, -- 11 ORA (zp),y + "----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- 12 *** JAM *** + "1000" & "100011" & rmwIndY & aluInT & aluSlo, -- 13 iSLO (zp),y + "0000" & "000000" & readZpX & aluInXXX & aluXXX, -- 14 iNOP zp,x + "1000" & "100010" & readZpX & aluInT & aluOra, -- 15 ORA zp,x + "0000" & "100011" & rmwZpX & aluInT & aluAsl, -- 16 ASL zp,x + "1000" & "100011" & rmwZpX & aluInT & aluSlo, -- 17 iSLO zp,x + "0000" & "000001" & implied & aluInClr & aluFlg, -- 18 CLC + "1000" & "100010" & readAbsY & aluInT & aluOra, -- 19 ORA abs,y + "0000" & "000000" & implied & aluInXXX & aluXXX, -- 1A iNOP implied + "1000" & "100011" & rmwAbsY & aluInT & aluSlo, -- 1B iSLO abs,y + "0000" & "000000" & readAbsX & aluInXXX & aluXXX, -- 1C iNOP abs,x + "1000" & "100010" & readAbsX & aluInT & aluOra, -- 1D ORA abs,x + "0000" & "100011" & rmwAbsX & aluInT & aluAsl, -- 1E ASL abs,x + "1000" & "100011" & rmwAbsX & aluInT & aluSlo, -- 1F iSLO abs,x + -- AXYS NVDIZC addressing aluInput aluMode + "0000" & "000000" & jsr & aluInXXX & aluXXX, -- 20 JSR + "1000" & "100010" & readIndX & aluInT & aluAnd, -- 21 AND (zp,x) + "----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- 22 *** JAM *** + "1000" & "100011" & rmwIndX & aluInT & aluRla, -- 23 iRLA (zp,x) + "0000" & "110010" & readZp & aluInT & aluBit, -- 24 BIT zp + "1000" & "100010" & readZp & aluInT & aluAnd, -- 25 AND zp + "0000" & "100011" & rmwZp & aluInT & aluRol, -- 26 ROL zp + "1000" & "100011" & rmwZp & aluInT & aluRla, -- 27 iRLA zp + "0000" & "111111" & pop & aluInT & aluFlg, -- 28 PLP + "1000" & "100010" & immediate & aluInT & aluAnd, -- 29 AND imm + "1000" & "100011" & implied & aluInA & aluRol, -- 2A ROL accu + "1000" & "100011" & immediate & aluInT & aluAnc, -- 2B iANC imm + "0000" & "110010" & readAbs & aluInT & aluBit, -- 2C BIT abs + "1000" & "100010" & readAbs & aluInT & aluAnd, -- 2D AND abs + "0000" & "100011" & rmwAbs & aluInT & aluRol, -- 2E ROL abs + "1000" & "100011" & rmwAbs & aluInT & aluRla, -- 2F iRLA abs + "0000" & "000000" & relative & aluInXXX & aluXXX, -- 30 BMI + "1000" & "100010" & readIndY & aluInT & aluAnd, -- 31 AND (zp),y + "----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- 32 *** JAM *** + "1000" & "100011" & rmwIndY & aluInT & aluRla, -- 33 iRLA (zp),y + "0000" & "000000" & readZpX & aluInXXX & aluXXX, -- 34 iNOP zp,x + "1000" & "100010" & readZpX & aluInT & aluAnd, -- 35 AND zp,x + "0000" & "100011" & rmwZpX & aluInT & aluRol, -- 36 ROL zp,x + "1000" & "100011" & rmwZpX & aluInT & aluRla, -- 37 iRLA zp,x + "0000" & "000001" & implied & aluInSet & aluFlg, -- 38 SEC + "1000" & "100010" & readAbsY & aluInT & aluAnd, -- 39 AND abs,y + "0000" & "000000" & implied & aluInXXX & aluXXX, -- 3A iNOP implied + "1000" & "100011" & rmwAbsY & aluInT & aluRla, -- 3B iRLA abs,y + "0000" & "000000" & readAbsX & aluInXXX & aluXXX, -- 3C iNOP abs,x + "1000" & "100010" & readAbsX & aluInT & aluAnd, -- 3D AND abs,x + "0000" & "100011" & rmwAbsX & aluInT & aluRol, -- 3E ROL abs,x + "1000" & "100011" & rmwAbsX & aluInT & aluRla, -- 3F iRLA abs,x + -- AXYS NVDIZC addressing aluInput aluMode + "0000" & "111111" & rti & aluInT & aluFlg, -- 40 RTI + "1000" & "100010" & readIndX & aluInT & aluEor, -- 41 EOR (zp,x) + "----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- 42 *** JAM *** + "1000" & "100011" & rmwIndX & aluInT & aluSre, -- 43 iSRE (zp,x) + "0000" & "000000" & readZp & aluInXXX & aluXXX, -- 44 iNOP zp + "1000" & "100010" & readZp & aluInT & aluEor, -- 45 EOR zp + "0000" & "100011" & rmwZp & aluInT & aluLsr, -- 46 LSR zp + "1000" & "100011" & rmwZp & aluInT & aluSre, -- 47 iSRE zp + "0000" & "000000" & push & aluInA & aluInp, -- 48 PHA + "1000" & "100010" & immediate & aluInT & aluEor, -- 49 EOR imm + "1000" & "100011" & implied & aluInA & aluLsr, -- 4A LSR accu + "1000" & "100011" & immediate & aluInAT & aluLsr, -- 4B iALR imm + "0000" & "000000" & jumpAbs & aluInXXX & aluXXX, -- 4C JMP abs + "1000" & "100010" & readAbs & aluInT & aluEor, -- 4D EOR abs + "0000" & "100011" & rmwAbs & aluInT & aluLsr, -- 4E LSR abs + "1000" & "100011" & rmwAbs & aluInT & aluSre, -- 4F iSRE abs + "0000" & "000000" & relative & aluInXXX & aluXXX, -- 50 BVC + "1000" & "100010" & readIndY & aluInT & aluEor, -- 51 EOR (zp),y + "----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- 52 *** JAM *** + "1000" & "100011" & rmwIndY & aluInT & aluSre, -- 53 iSRE (zp),y + "0000" & "000000" & readZpX & aluInXXX & aluXXX, -- 54 iNOP zp,x + "1000" & "100010" & readZpX & aluInT & aluEor, -- 55 EOR zp,x + "0000" & "100011" & rmwZpX & aluInT & aluLsr, -- 56 LSR zp,x + "1000" & "100011" & rmwZpX & aluInT & aluSre, -- 57 SRE zp,x + "0000" & "000100" & implied & aluInClr & aluXXX, -- 58 CLI + "1000" & "100010" & readAbsY & aluInT & aluEor, -- 59 EOR abs,y + "0000" & "000000" & implied & aluInXXX & aluXXX, -- 5A iNOP implied + "1000" & "100011" & rmwAbsY & aluInT & aluSre, -- 5B iSRE abs,y + "0000" & "000000" & readAbsX & aluInXXX & aluXXX, -- 5C iNOP abs,x + "1000" & "100010" & readAbsX & aluInT & aluEor, -- 5D EOR abs,x + "0000" & "100011" & rmwAbsX & aluInT & aluLsr, -- 5E LSR abs,x + "1000" & "100011" & rmwAbsX & aluInT & aluSre, -- 5F SRE abs,x + -- AXYS NVDIZC addressing aluInput aluMode + "0000" & "000000" & rts & aluInXXX & aluXXX, -- 60 RTS + "1000" & "110011" & readIndX & aluInT & aluAdc, -- 61 ADC (zp,x) + "----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- 62 *** JAM *** + "1000" & "110011" & rmwIndX & aluInT & aluRra, -- 63 iRRA (zp,x) + "0000" & "000000" & readZp & aluInXXX & aluXXX, -- 64 iNOP zp + "1000" & "110011" & readZp & aluInT & aluAdc, -- 65 ADC zp + "0000" & "100011" & rmwZp & aluInT & aluRor, -- 66 ROR zp + "1000" & "110011" & rmwZp & aluInT & aluRra, -- 67 iRRA zp + "1000" & "100010" & pop & aluInT & aluInp, -- 68 PLA + "1000" & "110011" & immediate & aluInT & aluAdc, -- 69 ADC imm + "1000" & "100011" & implied & aluInA & aluRor, -- 6A ROR accu + "1000" & "110011" & immediate & aluInAT & aluArr, -- 6B iARR imm + "0000" & "000000" & jumpInd & aluInXXX & aluXXX, -- 6C JMP indirect + "1000" & "110011" & readAbs & aluInT & aluAdc, -- 6D ADC abs + "0000" & "100011" & rmwAbs & aluInT & aluRor, -- 6E ROR abs + "1000" & "110011" & rmwAbs & aluInT & aluRra, -- 6F iRRA abs + "0000" & "000000" & relative & aluInXXX & aluXXX, -- 70 BVS + "1000" & "110011" & readIndY & aluInT & aluAdc, -- 71 ADC (zp),y + "----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- 72 *** JAM *** + "1000" & "110011" & rmwIndY & aluInT & aluRra, -- 73 iRRA (zp),y + "0000" & "000000" & readZpX & aluInXXX & aluXXX, -- 74 iNOP zp,x + "1000" & "110011" & readZpX & aluInT & aluAdc, -- 75 ADC zp,x + "0000" & "100011" & rmwZpX & aluInT & aluRor, -- 76 ROR zp,x + "1000" & "110011" & rmwZpX & aluInT & aluRra, -- 77 iRRA zp,x + "0000" & "000100" & implied & aluInSet & aluXXX, -- 78 SEI + "1000" & "110011" & readAbsY & aluInT & aluAdc, -- 79 ADC abs,y + "0000" & "000000" & implied & aluInXXX & aluXXX, -- 7A iNOP implied + "1000" & "110011" & rmwAbsY & aluInT & aluRra, -- 7B iRRA abs,y + "0000" & "000000" & readAbsX & aluInXXX & aluXXX, -- 7C iNOP abs,x + "1000" & "110011" & readAbsX & aluInT & aluAdc, -- 7D ADC abs,x + "0000" & "100011" & rmwAbsX & aluInT & aluRor, -- 7E ROR abs,x + "1000" & "110011" & rmwAbsX & aluInT & aluRra, -- 7F iRRA abs,x + -- AXYS NVDIZC addressing aluInput aluMode + "0000" & "000000" & immediate & aluInXXX & aluXXX, -- 80 iNOP imm + "0000" & "000000" & writeIndX & aluInA & aluInp, -- 81 STA (zp,x) + "0000" & "000000" & immediate & aluInXXX & aluXXX, -- 82 iNOP imm + "0000" & "000000" & writeIndX & aluInAX & aluInp, -- 83 iSAX (zp,x) + "0000" & "000000" & writeZp & aluInY & aluInp, -- 84 STY zp + "0000" & "000000" & writeZp & aluInA & aluInp, -- 85 STA zp + "0000" & "000000" & writeZp & aluInX & aluInp, -- 86 STX zp + "0000" & "000000" & writeZp & aluInAX & aluInp, -- 87 iSAX zp + "0010" & "100010" & implied & aluInY & aluDec, -- 88 DEY + "0000" & "000000" & immediate & aluInXXX & aluXXX, -- 84 iNOP imm + "1000" & "100010" & implied & aluInX & aluInp, -- 8A TXA + "1000" & "100010" & immediate & aluInEXT & aluInp, -- 8B iANE imm + "0000" & "000000" & writeAbs & aluInY & aluInp, -- 8C STY abs + "0000" & "000000" & writeAbs & aluInA & aluInp, -- 8D STA abs + "0000" & "000000" & writeAbs & aluInX & aluInp, -- 8E STX abs + "0000" & "000000" & writeAbs & aluInAX & aluInp, -- 8F iSAX abs + "0000" & "000000" & relative & aluInXXX & aluXXX, -- 90 BCC + "0000" & "000000" & writeIndY & aluInA & aluInp, -- 91 STA (zp),y + "----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- 92 *** JAM *** + "0000" & "000000" & writeIndY & aluInAXH & aluInp, -- 93 iAHX (zp),y + "0000" & "000000" & writeZpX & aluInY & aluInp, -- 94 STY zp,x + "0000" & "000000" & writeZpX & aluInA & aluInp, -- 95 STA zp,x + "0000" & "000000" & writeZpY & aluInX & aluInp, -- 96 STX zp,y + "0000" & "000000" & writeZpY & aluInAX & aluInp, -- 97 iSAX zp,y + "1000" & "100010" & implied & aluInY & aluInp, -- 98 TYA + "0000" & "000000" & writeAbsY & aluInA & aluInp, -- 99 STA abs,y + "0001" & "000000" & implied & aluInX & aluInp, -- 9A TXS + "0001" & "000000" & writeAbsY & aluInAXH & aluInp, -- 9B iSHS abs,y + "0000" & "000000" & writeAbsX & aluInYH & aluInp, -- 9C iSHY abs,x + "0000" & "000000" & writeAbsX & aluInA & aluInp, -- 9D STA abs,x + "0000" & "000000" & writeAbsY & aluInXH & aluInp, -- 9E iSHX abs,y + "0000" & "000000" & writeAbsY & aluInAXH & aluInp, -- 9F iAHX abs,y + -- AXYS NVDIZC addressing aluInput aluMode + "0010" & "100010" & immediate & aluInT & aluInp, -- A0 LDY imm + "1000" & "100010" & readIndX & aluInT & aluInp, -- A1 LDA (zp,x) + "0100" & "100010" & immediate & aluInT & aluInp, -- A2 LDX imm + "1100" & "100010" & readIndX & aluInT & aluInp, -- A3 LAX (zp,x) + "0010" & "100010" & readZp & aluInT & aluInp, -- A4 LDY zp + "1000" & "100010" & readZp & aluInT & aluInp, -- A5 LDA zp + "0100" & "100010" & readZp & aluInT & aluInp, -- A6 LDX zp + "1100" & "100010" & readZp & aluInT & aluInp, -- A7 iLAX zp + "0010" & "100010" & implied & aluInA & aluInp, -- A8 TAY + "1000" & "100010" & immediate & aluInT & aluInp, -- A9 LDA imm + "0100" & "100010" & implied & aluInA & aluInp, -- AA TAX + "1100" & "100010" & immediate & aluInET & aluInp, -- AB iLXA imm + "0010" & "100010" & readAbs & aluInT & aluInp, -- AC LDY abs + "1000" & "100010" & readAbs & aluInT & aluInp, -- AD LDA abs + "0100" & "100010" & readAbs & aluInT & aluInp, -- AE LDX abs + "1100" & "100010" & readAbs & aluInT & aluInp, -- AF iLAX abs + "0000" & "000000" & relative & aluInXXX & aluXXX, -- B0 BCS + "1000" & "100010" & readIndY & aluInT & aluInp, -- B1 LDA (zp),y + "----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- B2 *** JAM *** + "1100" & "100010" & readIndY & aluInT & aluInp, -- B3 iLAX (zp),y + "0010" & "100010" & readZpX & aluInT & aluInp, -- B4 LDY zp,x + "1000" & "100010" & readZpX & aluInT & aluInp, -- B5 LDA zp,x + "0100" & "100010" & readZpY & aluInT & aluInp, -- B6 LDX zp,y + "1100" & "100010" & readZpY & aluInT & aluInp, -- B7 iLAX zp,y + "0000" & "010000" & implied & aluInClr & aluFlg, -- B8 CLV + "1000" & "100010" & readAbsY & aluInT & aluInp, -- B9 LDA abs,y + "0100" & "100010" & implied & aluInS & aluInp, -- BA TSX + "1101" & "100010" & readAbsY & aluInST & aluInp, -- BB iLAS abs,y + "0010" & "100010" & readAbsX & aluInT & aluInp, -- BC LDY abs,x + "1000" & "100010" & readAbsX & aluInT & aluInp, -- BD LDA abs,x + "0100" & "100010" & readAbsY & aluInT & aluInp, -- BE LDX abs,y + "1100" & "100010" & readAbsY & aluInT & aluInp, -- BF iLAX abs,y + -- AXYS NVDIZC addressing aluInput aluMode + "0000" & "100011" & immediate & aluInT & aluCpy, -- C0 CPY imm + "0000" & "100011" & readIndX & aluInT & aluCmp, -- C1 CMP (zp,x) + "0000" & "000000" & immediate & aluInXXX & aluXXX, -- C2 iNOP imm + "0000" & "100011" & rmwIndX & aluInT & aluDcp, -- C3 iDCP (zp,x) + "0000" & "100011" & readZp & aluInT & aluCpy, -- C4 CPY zp + "0000" & "100011" & readZp & aluInT & aluCmp, -- C5 CMP zp + "0000" & "100010" & rmwZp & aluInT & aluDec, -- C6 DEC zp + "0000" & "100011" & rmwZp & aluInT & aluDcp, -- C7 iDCP zp + "0010" & "100010" & implied & aluInY & aluInc, -- C8 INY + "0000" & "100011" & immediate & aluInT & aluCmp, -- C9 CMP imm + "0100" & "100010" & implied & aluInX & aluDec, -- CA DEX + "0100" & "100011" & immediate & aluInT & aluSbx, -- CB SBX imm + "0000" & "100011" & readAbs & aluInT & aluCpy, -- CC CPY abs + "0000" & "100011" & readAbs & aluInT & aluCmp, -- CD CMP abs + "0000" & "100010" & rmwAbs & aluInT & aluDec, -- CE DEC abs + "0000" & "100011" & rmwAbs & aluInT & aluDcp, -- CF iDCP abs + "0000" & "000000" & relative & aluInXXX & aluXXX, -- D0 BNE + "0000" & "100011" & readIndY & aluInT & aluCmp, -- D1 CMP (zp),y + "----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- D2 *** JAM *** + "0000" & "100011" & rmwIndY & aluInT & aluDcp, -- D3 iDCP (zp),y + "0000" & "000000" & readZpX & aluInXXX & aluXXX, -- D4 iNOP zp,x + "0000" & "100011" & readZpX & aluInT & aluCmp, -- D5 CMP zp,x + "0000" & "100010" & rmwZpX & aluInT & aluDec, -- D6 DEC zp,x + "0000" & "100011" & rmwZpX & aluInT & aluDcp, -- D7 iDCP zp,x + "0000" & "001000" & implied & aluInClr & aluXXX, -- D8 CLD + "0000" & "100011" & readAbsY & aluInT & aluCmp, -- D9 CMP abs,y + "0000" & "000000" & implied & aluInXXX & aluXXX, -- DA iNOP implied + "0000" & "100011" & rmwAbsY & aluInT & aluDcp, -- DB iDCP abs,y + "0000" & "000000" & readAbsX & aluInXXX & aluXXX, -- DC iNOP abs,x + "0000" & "100011" & readAbsX & aluInT & aluCmp, -- DD CMP abs,x + "0000" & "100010" & rmwAbsX & aluInT & aluDec, -- DE DEC abs,x + "0000" & "100011" & rmwAbsX & aluInT & aluDcp, -- DF iDCP abs,x + -- AXYS NVDIZC addressing aluInput aluMode + "0000" & "100011" & immediate & aluInT & aluCpx, -- E0 CPX imm + "1000" & "110011" & readIndX & aluInT & aluSbc, -- E1 SBC (zp,x) + "0000" & "000000" & immediate & aluInXXX & aluXXX, -- E2 iNOP imm + "1000" & "110011" & rmwIndX & aluInT & aluIsc, -- E3 iISC (zp,x) + "0000" & "100011" & readZp & aluInT & aluCpx, -- E4 CPX zp + "1000" & "110011" & readZp & aluInT & aluSbc, -- E5 SBC zp + "0000" & "100010" & rmwZp & aluInT & aluInc, -- E6 INC zp + "1000" & "110011" & rmwZp & aluInT & aluIsc, -- E7 iISC zp + "0100" & "100010" & implied & aluInX & aluInc, -- E8 INX + "1000" & "110011" & immediate & aluInT & aluSbc, -- E9 SBC imm + "0000" & "000000" & implied & aluInXXX & aluXXX, -- EA NOP + "1000" & "110011" & immediate & aluInT & aluSbc, -- EB SBC imm (illegal opc) + "0000" & "100011" & readAbs & aluInT & aluCpx, -- EC CPX abs + "1000" & "110011" & readAbs & aluInT & aluSbc, -- ED SBC abs + "0000" & "100010" & rmwAbs & aluInT & aluInc, -- EE INC abs + "1000" & "110011" & rmwAbs & aluInT & aluIsc, -- EF iISC abs + "0000" & "000000" & relative & aluInXXX & aluXXX, -- F0 BEQ + "1000" & "110011" & readIndY & aluInT & aluSbc, -- F1 SBC (zp),y + "----" & "------" & xxxxxxxx & aluInXXX & aluXXX, -- F2 *** JAM *** + "1000" & "110011" & rmwIndY & aluInT & aluIsc, -- F3 iISC (zp),y + "0000" & "000000" & readZpX & aluInXXX & aluXXX, -- F4 iNOP zp,x + "1000" & "110011" & readZpX & aluInT & aluSbc, -- F5 SBC zp,x + "0000" & "100010" & rmwZpX & aluInT & aluInc, -- F6 INC zp,x + "1000" & "110011" & rmwZpX & aluInT & aluIsc, -- F7 iISC zp,x + "0000" & "001000" & implied & aluInSet & aluXXX, -- F8 SED + "1000" & "110011" & readAbsY & aluInT & aluSbc, -- F9 SBC abs,y + "0000" & "000000" & implied & aluInXXX & aluXXX, -- FA iNOP implied + "1000" & "110011" & rmwAbsY & aluInT & aluIsc, -- FB iISC abs,y + "0000" & "000000" & readAbsX & aluInXXX & aluXXX, -- FC iNOP abs,x + "1000" & "110011" & readAbsX & aluInT & aluSbc, -- FD SBC abs,x + "0000" & "100010" & rmwAbsX & aluInT & aluInc, -- FE INC abs,x + "1000" & "110011" & rmwAbsX & aluInT & aluIsc -- FF iISC abs,x + ); + signal opcInfo : decodedBitsDef; + signal nextOpcInfo : decodedBitsDef; -- Next opcode (decoded) + signal nextOpcInfoReg : decodedBitsDef; -- Next opcode (decoded) pipelined + signal theOpcode : unsigned(7 downto 0); + signal nextOpcode : unsigned(7 downto 0); + +-- Program counter + signal PC : unsigned(15 downto 0); -- Program counter + +-- Address generation + type nextAddrDef is ( + nextAddrHold, + nextAddrIncr, + nextAddrIncrL, -- Increment low bits only (zeropage accesses) + nextAddrIncrH, -- Increment high bits only (page-boundary) + nextAddrDecrH, -- Decrement high bits (branch backwards) + nextAddrPc, + nextAddrIrq, + nextAddrReset, + nextAddrAbs, + nextAddrAbsIndexed, + nextAddrZeroPage, + nextAddrZPIndexed, + nextAddrStack, + nextAddrRelative + ); + signal nextAddr : nextAddrDef; + signal myAddr : unsigned(15 downto 0); + signal myAddrIncr : unsigned(15 downto 0); + signal myAddrIncrH : unsigned(7 downto 0); + signal myAddrDecrH : unsigned(7 downto 0); + signal theWe : std_logic; + + signal irqActive : std_logic; + +-- Output register + signal doReg : unsigned(7 downto 0); + +-- Buffer register + signal T : unsigned(7 downto 0); + +-- General registers + signal A: unsigned(7 downto 0); -- Accumulator + signal X: unsigned(7 downto 0); -- Index X + signal Y: unsigned(7 downto 0); -- Index Y + signal S: unsigned(7 downto 0); -- stack pointer + +-- Status register + signal C: std_logic; -- Carry + signal Z: std_logic; -- Zero flag + signal I: std_logic; -- Interrupt flag + signal D: std_logic; -- Decimal mode + signal V: std_logic; -- Overflow + signal N: std_logic; -- Negative + +-- ALU + -- ALU input + signal aluInput : unsigned(7 downto 0); + signal aluCmpInput : unsigned(7 downto 0); + -- ALU output + signal aluRegisterOut : unsigned(7 downto 0); + signal aluRmwOut : unsigned(7 downto 0); + signal aluC : std_logic; + signal aluZ : std_logic; + signal aluV : std_logic; + signal aluN : std_logic; + -- Pipeline registers + signal aluInputReg : unsigned(7 downto 0); + signal aluCmpInputReg : unsigned(7 downto 0); + signal aluRmwReg : unsigned(7 downto 0); + signal aluNineReg : unsigned(7 downto 0); + signal aluCReg : std_logic; + signal aluZReg : std_logic; + signal aluVReg : std_logic; + signal aluNReg : std_logic; + +-- Indexing + signal indexOut : unsigned(8 downto 0); + +begin +processAluInput: process(clk, opcInfo, A, X, Y, T, S) + variable temp : unsigned(7 downto 0); + begin + temp := (others => '1'); + if opcInfo(opcInA) = '1' then + temp := temp and A; + end if; + if opcInfo(opcInE) = '1' then + temp := temp and (A or X"EE"); + end if; + if opcInfo(opcInX) = '1' then + temp := temp and X; + end if; + if opcInfo(opcInY) = '1' then + temp := temp and Y; + end if; + if opcInfo(opcInS) = '1' then + temp := temp and S; + end if; + if opcInfo(opcInT) = '1' then + temp := temp and T; + end if; + if opcInfo(opcInClear) = '1' then + temp := (others => '0'); + end if; + if rising_edge(clk) then + aluInputReg <= temp; + end if; + + aluInput <= temp; + if pipelineAluMux then + aluInput <= aluInputReg; + end if; + end process; + +processCmpInput: process(clk, opcInfo, A, X, Y) + variable temp : unsigned(7 downto 0); + begin + temp := (others => '1'); + if opcInfo(opcInCmp) = '1' then + temp := temp and A; + end if; + if opcInfo(opcInCpx) = '1' then + temp := temp and X; + end if; + if opcInfo(opcInCpy) = '1' then + temp := temp and Y; + end if; + if rising_edge(clk) then + aluCmpInputReg <= temp; + end if; + + aluCmpInput <= temp; + if pipelineAluMux then + aluCmpInput <= aluCmpInputReg; + end if; + end process; + + -- ALU consists of two parts + -- Read-Modify-Write or index instructions: INC/DEC/ASL/LSR/ROR/ROL + -- Accumulator instructions: ADC, SBC, EOR, AND, EOR, ORA + -- Some instructions are both RMW and accumulator so for most + -- instructions the rmw results are routed through accu alu too. +processAlu: process(clk, opcInfo, aluInput, aluCmpInput, A, T, irqActive, N, V, D, I, Z, C) + variable lowBits: unsigned(5 downto 0); + variable nineBits: unsigned(8 downto 0); + variable rmwBits: unsigned(8 downto 0); + + variable varC : std_logic; + variable varZ : std_logic; + variable varV : std_logic; + variable varN : std_logic; + begin + lowBits := (others => '-'); + nineBits := (others => '-'); + rmwBits := (others => '-'); + varV := aluInput(6); -- Default for BIT / PLP / RTI + + -- Shift unit + case opcInfo(aluMode1From to aluMode1To) is + when aluModeInp => + rmwBits := C & aluInput; + when aluModeP => + rmwBits := C & N & V & '1' & (not irqActive) & D & I & Z & C; + when aluModeInc => + rmwBits := C & (aluInput + 1); + when aluModeDec => + rmwBits := C & (aluInput - 1); + when aluModeAsl => + rmwBits := aluInput & "0"; + when aluModeFlg => + rmwBits := aluInput(0) & aluInput; + when aluModeLsr => + rmwBits := aluInput(0) & "0" & aluInput(7 downto 1); + when aluModeRol => + rmwBits := aluInput & C; + when aluModeRoR => + rmwBits := aluInput(0) & C & aluInput(7 downto 1); + when aluModeAnc => + rmwBits := (aluInput(7) and A(7)) & aluInput; + when others => + rmwBits := C & aluInput; + end case; + + -- ALU + case opcInfo(aluMode2From to aluMode2To) is + when aluModeAdc => + lowBits := ("0" & A(3 downto 0) & rmwBits(8)) + ("0" & rmwBits(3 downto 0) & "1"); + ninebits := ("0" & A) + ("0" & rmwBits(7 downto 0)) + (B"00000000" & rmwBits(8)); + when aluModeSbc => + lowBits := ("0" & A(3 downto 0) & rmwBits(8)) + ("0" & (not rmwBits(3 downto 0)) & "1"); + ninebits := ("0" & A) + ("0" & (not rmwBits(7 downto 0))) + (B"00000000" & rmwBits(8)); + when aluModeCmp => + ninebits := ("0" & aluCmpInput) + ("0" & (not rmwBits(7 downto 0))) + "000000001"; + when aluModeAnd => + ninebits := rmwBits(8) & (A and rmwBits(7 downto 0)); + when aluModeEor => + ninebits := rmwBits(8) & (A xor rmwBits(7 downto 0)); + when aluModeOra => + ninebits := rmwBits(8) & (A or rmwBits(7 downto 0)); + when others => + ninebits := rmwBits; + end case; + + if (opcInfo(aluMode1From to aluMode1To) = aluModeFlg) then + varZ := rmwBits(1); + elsif ninebits(7 downto 0) = X"00" then + varZ := '1'; + else + varZ := '0'; + end if; + + case opcInfo(aluMode2From to aluMode2To) is + when aluModeAdc => + -- decimal mode low bits correction, is done after setting Z flag. + if D = '1' then + if lowBits(5 downto 1) > 9 then + ninebits(3 downto 0) := ninebits(3 downto 0) + 6; + if lowBits(5) = '0' then + ninebits(8 downto 4) := ninebits(8 downto 4) + 1; + end if; + end if; + end if; + when others => + null; + end case; + + if (opcInfo(aluMode1From to aluMode1To) = aluModeBit) + or (opcInfo(aluMode1From to aluMode1To) = aluModeFlg) then + varN := rmwBits(7); + else + varN := nineBits(7); + end if; + varC := ninebits(8); + if opcInfo(aluMode2From to aluMode2To) = aluModeArr then + varC := aluInput(7); + varV := aluInput(7) xor aluInput(6); + end if; + + case opcInfo(aluMode2From to aluMode2To) is + when aluModeAdc => + -- decimal mode high bits correction, is done after setting Z and N flags + varV := (A(7) xor ninebits(7)) and (rmwBits(7) xor ninebits(7)); + if D = '1' then + if ninebits(8 downto 4) > 9 then + ninebits(8 downto 4) := ninebits(8 downto 4) + 6; + varC := '1'; + end if; + end if; + when aluModeSbc => + varV := (A(7) xor ninebits(7)) and ((not rmwBits(7)) xor ninebits(7)); + if D = '1' then + -- Check for borrow (lower 4 bits) + if lowBits(5) = '0' then + ninebits(3 downto 0) := ninebits(3 downto 0) - 6; + end if; + -- Check for borrow (upper 4 bits) + if ninebits(8) = '0' then + ninebits(8 downto 4) := ninebits(8 downto 4) - 6; + end if; + end if; + when aluModeArr => + if D = '1' then + if (("0" & aluInput(3 downto 0)) + ("0000" & aluInput(0))) > 5 then + ninebits(3 downto 0) := ninebits(3 downto 0) + 6; + end if; + if (("0" & aluInput(7 downto 4)) + ("0000" & aluInput(4))) > 5 then + ninebits(8 downto 4) := ninebits(8 downto 4) + 6; + varC := '1'; + else + varC := '0'; + end if; + end if; + when others => + null; + end case; + + if rising_edge(clk) then + aluRmwReg <= rmwBits(7 downto 0); + aluNineReg <= ninebits(7 downto 0); + aluCReg <= varC; + aluZReg <= varZ; + aluVReg <= varV; + aluNReg <= varN; + end if; + + aluRmwOut <= rmwBits(7 downto 0); + aluRegisterOut <= ninebits(7 downto 0); + aluC <= varC; + aluZ <= varZ; + aluV <= varV; + aluN <= varN; + if pipelineAluOut then + aluRmwOut <= aluRmwReg; + aluRegisterOut <= aluNineReg; + aluC <= aluCReg; + aluZ <= aluZReg; + aluV <= aluVReg; + aluN <= aluNReg; + end if; + end process; + +calcInterrupt: process(clk) + begin + if rising_edge(clk) then + if enable = '1' then + if theCpuCycle = cycleStack4 + or reset = '1' then + nmiReg <= '1'; + end if; + + if nextCpuCycle /= cycleBranchTaken + and nextCpuCycle /= opcodeFetch then + irqReg <= irq_n; + nmiEdge <= nmi_n; + if (nmiEdge = '1') and (nmi_n = '0') then + nmiReg <= '0'; + end if; + end if; + -- The 'or opcInfo(opcSetI)' prevents NMI immediately after BRK or IRQ. + -- Presumably this is done in the real 6502/6510 to prevent a double IRQ. + processIrq <= not ((nmiReg and (irqReg or I)) or opcInfo(opcIRQ)); + end if; + end if; + end process; + +calcNextOpcode: process(clk, di, reset, processIrq) + variable myNextOpcode : unsigned(7 downto 0); + begin + -- Next opcode is read from input unless a reset or IRQ is pending. + myNextOpcode := di; + if reset = '1' then + myNextOpcode := X"4C"; + elsif processIrq = '1' then + myNextOpcode := X"00"; + end if; + + nextOpcode <= myNextOpcode; + end process; + + nextOpcInfo <= opcodeInfoTable(to_integer(nextOpcode)); + process(clk) + begin + if rising_edge(clk) then + nextOpcInfoReg <= nextOpcInfo; + end if; + end process; + + -- Read bits and flags from opcodeInfoTable and store in opcInfo. + -- This info is used to control the execution of the opcode. +calcOpcInfo: process(clk) + begin + if rising_edge(clk) then + if enable = '1' then + if (reset = '1') or (theCpuCycle = opcodeFetch) then + opcInfo <= nextOpcInfo; + if pipelineOpcode then + opcInfo <= nextOpcInfoReg; + end if; + end if; + end if; + end if; + end process; + +calcTheOpcode: process(clk) + begin + if rising_edge(clk) then + if enable = '1' then + if theCpuCycle = opcodeFetch then + irqActive <= '0'; + if processIrq = '1' then + irqActive <= '1'; + end if; + -- Fetch opcode + theOpcode <= nextOpcode; + end if; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- State machine +-- ----------------------------------------------------------------------- + process(enable, theCpuCycle, opcInfo) + begin + updateRegisters <= false; + if enable = '1' then + if opcInfo(opcRti) = '1' then + if theCpuCycle = cycleRead then + updateRegisters <= true; + end if; + elsif theCpuCycle = opcodeFetch then + updateRegisters <= true; + end if; + end if; + end process; + + debugOpcode <= theOpcode; + process(clk) + begin + if rising_edge(clk) then + if enable = '1' then + theCpuCycle <= nextCpuCycle; + end if; + if reset = '1' then + theCpuCycle <= cycle2; + end if; + end if; + end process; + + -- Determine the next cpu cycle. After the last cycle we always + -- go to opcodeFetch to get the next opcode. +calcNextCpuCycle: process(theCpuCycle, opcInfo, theOpcode, indexOut, T, N, V, C, Z) + begin + nextCpuCycle <= opcodeFetch; + + case theCpuCycle is + when opcodeFetch => + nextCpuCycle <= cycle2; + when cycle2 => + if opcInfo(opcBranch) = '1' then + if (N = theOpcode(5) and theOpcode(7 downto 6) = "00") + or (V = theOpcode(5) and theOpcode(7 downto 6) = "01") + or (C = theOpcode(5) and theOpcode(7 downto 6) = "10") + or (Z = theOpcode(5) and theOpcode(7 downto 6) = "11") then + -- Branch condition is true + nextCpuCycle <= cycleBranchTaken; + end if; + elsif (opcInfo(opcStackUp) = '1') then + nextCpuCycle <= cycleStack1; + elsif opcInfo(opcStackAddr) = '1' + and opcInfo(opcStackData) = '1' then + nextCpuCycle <= cycleStack2; + elsif opcInfo(opcStackAddr) = '1' then + nextCpuCycle <= cycleStack1; + elsif opcInfo(opcStackData) = '1' then + nextCpuCycle <= cycleWrite; + elsif opcInfo(opcAbsolute) = '1' then + nextCpuCycle <= cycle3; + elsif opcInfo(opcIndirect) = '1' then + if opcInfo(indexX) = '1' then + nextCpuCycle <= cyclePreIndirect; + else + nextCpuCycle <= cycleIndirect; + end if; + elsif opcInfo(opcZeroPage) = '1' then + if opcInfo(opcWrite) = '1' then + if (opcInfo(indexX) = '1') + or (opcInfo(indexY) = '1') then + nextCpuCycle <= cyclePreWrite; + else + nextCpuCycle <= cycleWrite; + end if; + else + if (opcInfo(indexX) = '1') + or (opcInfo(indexY) = '1') then + nextCpuCycle <= cyclePreRead; + else + nextCpuCycle <= cycleRead2; + end if; + end if; + elsif opcInfo(opcJump) = '1' then + nextCpuCycle <= cycleJump; + end if; + when cycle3 => + nextCpuCycle <= cycleRead; + if opcInfo(opcWrite) = '1' then + if (opcInfo(indexX) = '1') + or (opcInfo(indexY) = '1') then + nextCpuCycle <= cyclePreWrite; + else + nextCpuCycle <= cycleWrite; + end if; + end if; + if (opcInfo(opcIndirect) = '1') + and (opcInfo(indexX) = '1') then + if opcInfo(opcWrite) = '1' then + nextCpuCycle <= cycleWrite; + else + nextCpuCycle <= cycleRead2; + end if; + end if; + when cyclePreIndirect => + nextCpuCycle <= cycleIndirect; + when cycleIndirect => + nextCpuCycle <= cycle3; + when cycleBranchTaken => + if indexOut(8) /= T(7) then + -- Page boundary crossing during branch. + nextCpuCycle <= cycleBranchPage; + end if; + when cyclePreRead => + if opcInfo(opcZeroPage) = '1' then + nextCpuCycle <= cycleRead2; + end if; + when cycleRead => + if opcInfo(opcJump) = '1' then + nextCpuCycle <= cycleJump; + elsif indexOut(8) = '1' then + -- Page boundary crossing while indexed addressing. + nextCpuCycle <= cycleRead2; + elsif opcInfo(opcRmw) = '1' then + nextCpuCycle <= cycleRmw; + if opcInfo(indexX) = '1' + or opcInfo(indexY) = '1' then + -- 6510 needs extra cycle for indexed addressing + -- combined with RMW indexing + nextCpuCycle <= cycleRead2; + end if; + end if; + when cycleRead2 => + if opcInfo(opcRmw) = '1' then + nextCpuCycle <= cycleRmw; + end if; + when cycleRmw => + nextCpuCycle <= cycleWrite; + when cyclePreWrite => + nextCpuCycle <= cycleWrite; + when cycleStack1 => + nextCpuCycle <= cycleRead; + if opcInfo(opcStackAddr) = '1' then + nextCpuCycle <= cycleStack2; + end if; + when cycleStack2 => + nextCpuCycle <= cycleStack3; + if opcInfo(opcRti) = '1' then + nextCpuCycle <= cycleRead; + end if; + if opcInfo(opcStackData) = '0' + and opcInfo(opcStackUp) = '1' then + nextCpuCycle <= cycleJump; + end if; + when cycleStack3 => + nextCpuCycle <= cycleRead; + if opcInfo(opcStackData) = '0' + or opcInfo(opcStackUp) = '1' then + nextCpuCycle <= cycleJump; + elsif opcInfo(opcStackAddr) = '1' then + nextCpuCycle <= cycleStack4; + end if; + when cycleStack4 => + nextCpuCycle <= cycleRead; + when cycleJump => + if opcInfo(opcIncrAfter) = '1' then + -- Insert extra cycle + nextCpuCycle <= cycleEnd; + end if; + when others => + null; + end case; + end process; + +-- ----------------------------------------------------------------------- +-- T register +-- ----------------------------------------------------------------------- +calcT: process(clk) + begin + if rising_edge(clk) then + if enable = '1' then + case theCpuCycle is + when cycle2 => + T <= di; + when cycleStack1 | cycleStack2 => + if opcInfo(opcStackUp) = '1' then + -- Read from stack + T <= di; + end if; + when cycleIndirect | cycleRead | cycleRead2 => + T <= di; + when others => + null; + end case; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- A register +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then + if updateRegisters then + if opcInfo(opcUpdateA) = '1' then + A <= aluRegisterOut; + end if; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- X register +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then + if updateRegisters then + if opcInfo(opcUpdateX) = '1' then + X <= aluRegisterOut; + end if; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- Y register +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then + if updateRegisters then + if opcInfo(opcUpdateY) = '1' then + Y <= aluRegisterOut; + end if; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- C flag +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then + if updateRegisters then + if opcInfo(opcUpdateC) = '1' then + C <= aluC; + end if; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- Z flag +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then + if updateRegisters then + if opcInfo(opcUpdateZ) = '1' then + Z <= aluZ; + end if; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- I flag +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then + if updateRegisters then + if opcInfo(opcUpdateI) = '1' then + I <= aluInput(2); + end if; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- D flag +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then + if updateRegisters then + if opcInfo(opcUpdateD) = '1' then + D <= aluInput(3); + end if; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- V flag +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then + if updateRegisters then + if opcInfo(opcUpdateV) = '1' then + V <= aluV; + end if; + end if; + if enable = '1' then + if soReg = '1' and so_n = '0' then + V <= '1'; + end if; + soReg <= so_n; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- N flag +-- ----------------------------------------------------------------------- + process(clk) + begin + if rising_edge(clk) then + if updateRegisters then + if opcInfo(opcUpdateN) = '1' then + N <= aluN; + end if; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- Stack pointer +-- ----------------------------------------------------------------------- + process(clk) + variable sIncDec : unsigned(7 downto 0); + variable updateFlag : boolean; + begin + if rising_edge(clk) then + + if opcInfo(opcStackUp) = '1' then + sIncDec := S + 1; + else + sIncDec := S - 1; + end if; + + if enable = '1' then + updateFlag := false; + case nextCpuCycle is + when cycleStack1 => + if (opcInfo(opcStackUp) = '1') + or (opcInfo(opcStackData) = '1') then + updateFlag := true; + end if; + when cycleStack2 => + updateFlag := true; + when cycleStack3 => + updateFlag := true; + when cycleStack4 => + updateFlag := true; + when cycleRead => + if opcInfo(opcRti) = '1' then + updateFlag := true; + end if; + when cycleWrite => + if opcInfo(opcStackData) = '1' then + updateFlag := true; + end if; + when others => + null; + end case; + if updateFlag then + S <= sIncDec; + end if; + end if; + if updateRegisters then + if opcInfo(opcUpdateS) = '1' then + S <= aluRegisterOut; + end if; + end if; + end if; + end process; + +-- ----------------------------------------------------------------------- +-- Data out +-- ----------------------------------------------------------------------- +--calcDo: process(cpuNo, theCpuCycle, aluOut, PC, T) +calcDo: process(clk) + begin + if rising_edge(clk) then + if enable = '1' then + doReg <= aluRmwOut; + if opcInfo(opcInH) = '1' then + -- For illegal opcodes SHA, SHX, SHY, SHS + doReg <= aluRmwOut and myAddrIncrH; + end if; + + case nextCpuCycle is + when cycleStack2 => + if opcInfo(opcIRQ) = '1' + and irqActive = '0' then + doReg <= myAddrIncr(15 downto 8); + else + doReg <= PC(15 downto 8); + end if; + when cycleStack3 => + doReg <= PC(7 downto 0); + when cycleRmw => +-- do <= T; -- Read-modify-write write old value first. + doReg <= di; -- Read-modify-write write old value first. + when others => null; + end case; + end if; + end if; + end process; + do <= doReg; + + + +-- ----------------------------------------------------------------------- +-- Write enable +-- ----------------------------------------------------------------------- +calcWe: process(clk) + begin + if rising_edge(clk) then + if enable = '1' then + theWe <= '0'; + case nextCpuCycle is + when cycleStack1 => + if opcInfo(opcStackUp) = '0' + and ((opcInfo(opcStackAddr) = '0') + or (opcInfo(opcStackData) = '1')) then + theWe <= '1'; + end if; + when cycleStack2 | cycleStack3 | cycleStack4 => + if opcInfo(opcStackUp) = '0' then + theWe <= '1'; + end if; + when cycleRmw => + theWe <= '1'; + when cycleWrite => + theWe <= '1'; + when others => + null; + end case; + end if; + end if; + end process; + we <= theWe; + +-- ----------------------------------------------------------------------- +-- Program counter +-- ----------------------------------------------------------------------- +calcPC: process(clk) + begin + if rising_edge(clk) then + if enable = '1' then + case theCpuCycle is + when opcodeFetch => + PC <= myAddr; + when cycle2 => + if irqActive = '0' then + if opcInfo(opcSecondByte) = '1' then + PC <= myAddrIncr; + else + PC <= myAddr; + end if; + end if; + when cycle3 => + if opcInfo(opcAbsolute) = '1' then + PC <= myAddrIncr; + end if; + when others => + null; + end case; + end if; + end if; + end process; + debugPc <= PC; + +-- ----------------------------------------------------------------------- +-- Address generation +-- ----------------------------------------------------------------------- +calcNextAddr: process(theCpuCycle, opcInfo, indexOut, T, reset) + begin + nextAddr <= nextAddrIncr; + case theCpuCycle is + when cycle2 => + if opcInfo(opcStackAddr) = '1' + or opcInfo(opcStackData) = '1' then + nextAddr <= nextAddrStack; + elsif opcInfo(opcAbsolute) = '1' then + nextAddr <= nextAddrIncr; + elsif opcInfo(opcZeroPage) = '1' then + nextAddr <= nextAddrZeroPage; + elsif opcInfo(opcIndirect) = '1' then + nextAddr <= nextAddrZeroPage; + elsif opcInfo(opcSecondByte) = '1' then + nextAddr <= nextAddrIncr; + else + nextAddr <= nextAddrHold; + end if; + when cycle3 => + if (opcInfo(opcIndirect) = '1') + and (opcInfo(indexX) = '1') then + nextAddr <= nextAddrAbs; + else + nextAddr <= nextAddrAbsIndexed; + end if; + when cyclePreIndirect => + nextAddr <= nextAddrZPIndexed; + when cycleIndirect => + nextAddr <= nextAddrIncrL; + when cycleBranchTaken => + nextAddr <= nextAddrRelative; + when cycleBranchPage => + if T(7) = '0' then + nextAddr <= nextAddrIncrH; + else + nextAddr <= nextAddrDecrH; + end if; + when cyclePreRead => + nextAddr <= nextAddrZPIndexed; + when cycleRead => + nextAddr <= nextAddrPc; + if opcInfo(opcJump) = '1' then + -- Emulate 6510 bug, jmp(xxFF) fetches from same page. + -- Replace with nextAddrIncr if emulating 65C02 or later cpu. + nextAddr <= nextAddrIncrL; + elsif indexOut(8) = '1' then + nextAddr <= nextAddrIncrH; + elsif opcInfo(opcRmw) = '1' then + nextAddr <= nextAddrHold; + end if; + when cycleRead2 => + nextAddr <= nextAddrPc; + if opcInfo(opcRmw) = '1' then + nextAddr <= nextAddrHold; + end if; + when cycleRmw => + nextAddr <= nextAddrHold; + when cyclePreWrite => + nextAddr <= nextAddrHold; + if opcInfo(opcZeroPage) = '1' then + nextAddr <= nextAddrZPIndexed; + elsif indexOut(8) = '1' then + nextAddr <= nextAddrIncrH; + end if; + when cycleWrite => + nextAddr <= nextAddrPc; + when cycleStack1 => + nextAddr <= nextAddrStack; + when cycleStack2 => + nextAddr <= nextAddrStack; + when cycleStack3 => + nextAddr <= nextAddrStack; + if opcInfo(opcStackData) = '0' then + nextAddr <= nextAddrPc; + end if; + when cycleStack4 => + nextAddr <= nextAddrIrq; + when cycleJump => + nextAddr <= nextAddrAbs; + when others => + null; + end case; + if reset = '1' then + nextAddr <= nextAddrReset; + end if; + end process; + +indexAlu: process(opcInfo, myAddr, T, X, Y) + begin + if opcInfo(indexX) = '1' then + indexOut <= (B"0" & T) + (B"0" & X); + elsif opcInfo(indexY) = '1' then + indexOut <= (B"0" & T) + (B"0" & Y); + elsif opcInfo(opcBranch) = '1' then + indexOut <= (B"0" & T) + (B"0" & myAddr(7 downto 0)); + else + indexOut <= B"0" & T; + end if; + end process; + +calcAddr: process(clk) + begin + if rising_edge(clk) then + if enable = '1' then + case nextAddr is + when nextAddrIncr => myAddr <= myAddrIncr; + when nextAddrIncrL => myAddr(7 downto 0) <= myAddrIncr(7 downto 0); + when nextAddrIncrH => myAddr(15 downto 8) <= myAddrIncrH; + when nextAddrDecrH => myAddr(15 downto 8) <= myAddrDecrH; + when nextAddrPc => myAddr <= PC; + when nextAddrIrq => + myAddr <= X"FFFE"; + if nmiReg = '0' then + myAddr <= X"FFFA"; + end if; + when nextAddrReset => myAddr <= X"FFFC"; + when nextAddrAbs => myAddr <= di & T; + when nextAddrAbsIndexed => myAddr <= di & indexOut(7 downto 0); + when nextAddrZeroPage => myAddr <= "00000000" & di; + when nextAddrZPIndexed => myAddr <= "00000000" & indexOut(7 downto 0); + when nextAddrStack => myAddr <= "00000001" & S; + when nextAddrRelative => myAddr(7 downto 0) <= indexOut(7 downto 0); + when others => null; + end case; + end if; + end if; + end process; + + myAddrIncr <= myAddr + 1; + myAddrIncrH <= myAddr(15 downto 8) + 1; + myAddrDecrH <= myAddr(15 downto 8) - 1; + + addr <= myAddr; + + debugA <= A; + debugX <= X; + debugY <= Y; + debugS <= S; + +end architecture; + + diff --git a/cores/c16/data_io.v b/cores/c16/data_io.v new file mode 100644 index 0000000..b7c58f9 --- /dev/null +++ b/cores/c16/data_io.v @@ -0,0 +1,127 @@ +// +// data_io.v +// +// io controller writable ram for the MiST board +// http://code.google.com/p/mist-board/ +// +// Copyright (c) 2014 Till Harbaum +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +module data_io ( + // io controller spi interface + input sck, + input ss, + input sdi, + + output downloading, // signal indicating an active download + output [15:0] size, // number of bytes in input buffer + output reg [4:0] index, // menu index used to upload the file + + // external ram interface + input clk, + output reg wr, + output reg [15:0] a, + output [7:0] d +); + +assign d = data; + +parameter START_ADDR = 16'h0000; + +assign size = addr; + +// ********************************************************************************* +// spi client +// ********************************************************************************* + +// this core supports only the display related OSD commands +// of the minimig +reg [6:0] sbuf; +reg [7:0] cmd /* synthesis noprune */; +reg [7:0] data /* synthesis noprune */; +reg [4:0] cnt /* synthesis noprune */; + +reg [15:0] addr /* synthesis noprune */; +reg rclk /* synthesis noprune */; + +localparam UIO_FILE_TX = 8'h53; +localparam UIO_FILE_TX_DAT = 8'h54; +localparam UIO_FILE_INDEX = 8'h55; +localparam UIO_FILE_INFO = 8'h56; + +assign downloading = downloading_reg; +reg downloading_reg = 1'b0; + +// data_io has its own SPI interface to the io controller +always@(posedge sck, posedge ss) begin + if(ss == 1'b1) + cnt <= 5'd0; + else begin + rclk <= 1'b0; + + // don't shift in last bit. It is evaluated directly + // when writing to ram + if(cnt != 15) + sbuf <= { sbuf[5:0], sdi}; + + // increase target address after write + if(rclk) + addr <= addr + 16'd1; + + // count 0-7 8-15 8-15 ... + if(cnt < 15) cnt <= cnt + 4'd1; + else cnt <= 4'd8; + + // finished command byte + if(cnt == 7) + cmd <= {sbuf, sdi}; + + // prepare/end transmission + if((cmd == UIO_FILE_TX) && (cnt == 15)) begin + // prepare + if(sdi) begin + addr <= START_ADDR; + downloading_reg <= 1'b1; + end else + downloading_reg <= 1'b0; + end + + // command 0x54: UIO_FILE_TX + if((cmd == UIO_FILE_TX_DAT) && (cnt == 15)) begin + data <= {sbuf, sdi}; + rclk <= 1'b1; + a <= addr; + end + + // expose file (menu) index + if((cmd == UIO_FILE_INDEX) && (cnt == 15)) + index <= {sbuf[3:0], sdi}; + + end +end + +reg rclkD, rclkD2; +always@(posedge clk) begin + // bring rclk from spi clock domain into c64 clock domain + rclkD <= rclk; + rclkD2 <= rclkD; + wr <= 1'b0; + + if(rclkD && !rclkD2) + wr <= 1'b1; +end + +endmodule \ No newline at end of file diff --git a/cores/c16/gpl-3.0.txt b/cores/c16/gpl-3.0.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/cores/c16/gpl-3.0.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/cores/c16/kernal_PAL.hex b/cores/c16/kernal_PAL.hex new file mode 100644 index 0000000..310caaf --- /dev/null +++ b/cores/c16/kernal_PAL.hex @@ -0,0 +1,16384 @@ +e0 +02 +90 +0d +d0 +b8 +20 +f3 +c1 +a8 +90 +02 +a0 +00 +4c +81 +9a +8a +0a +aa +bd +ad +02 +a8 +bd +ae +02 +4c +71 +94 +20 +b6 +c3 +a2 +1f +20 +d9 +c3 +20 +8f +c3 +8c +d0 +02 +8d +d1 +02 +20 +8f +c3 +8c +d2 +02 +8d +d3 +02 +08 +a2 +23 +20 +d3 +c2 +28 +b0 +11 +ad +d0 +02 +8d +d2 +02 +ad +d1 +02 +24 +83 +10 +04 +0e +d2 +02 +2a +8d +d3 +02 +20 +8f +c3 +8c +d8 +02 +8d +d9 +02 +20 +8f +c3 +8c +da +02 +8d +db +02 +20 +8f +c3 +85 +80 +98 +a4 +80 +20 +59 +bc +a2 +2d +a0 +2b +20 +05 +c3 +90 +0e +a9 +68 +a0 +01 +20 +f9 +c2 +9d +ad +02 +98 +9d +ae +02 +a2 +03 +bd +d0 +02 +9d +d4 +02 +ca +10 +f7 +a9 +90 +20 +d5 +bc +a2 +07 +bd +d0 +02 +9d +dc +02 +ca +10 +f7 +20 +ee +bc +20 +7b +c3 +a2 +02 +20 +a7 +c3 +86 +e9 +18 +a5 +e9 +d0 +03 +4c +1c +99 +6d +d8 +02 +8d +d8 +02 +90 +03 +ee +d9 +02 +a2 +2d +a0 +2b +20 +05 +c3 +b0 +08 +20 +ee +bc +20 +da +c0 +90 +dd +a0 +2d +20 +f0 +bc +a2 +02 +a0 +06 +a9 +00 +9d +b9 +02 +9d +ba +02 +20 +22 +c3 +10 +08 +de +b9 +02 +de +ba +02 +d0 +0b +c9 +00 +d0 +04 +c0 +00 +f0 +03 +fe +b9 +02 +9d +b5 +02 +0a +9d +bd +02 +98 +9d +b6 +02 +2a +9d +be +02 +ca +ca +a0 +04 +e0 +00 +f0 +c9 +a2 +0a +a0 +08 +20 +05 +c3 +a9 +00 +2a +2a +8d +c3 +02 +49 +02 +8d +c4 +02 +18 +a9 +10 +6d +c3 +02 +a8 +48 +49 +02 +aa +20 +05 +c3 +9d +ad +02 +98 +9d +ae +02 +68 +a8 +18 +a9 +08 +6d +c4 +02 +aa +20 +05 +c3 +8d +c1 +02 +8c +c2 +02 +20 +a5 +c1 +ac +c4 +02 +38 +b9 +b5 +02 +e9 +01 +99 +b5 +02 +b0 +0b +b9 +b6 +02 +e9 +00 +99 +b6 +02 +b0 +01 +60 +ae +c3 +02 +ad +c2 +02 +30 +06 +20 +94 +c1 +ae +c4 +02 +18 +ad +c1 +02 +7d +bd +02 +8d +c1 +02 +ad +c2 +02 +7d +be +02 +8d +c2 +02 +ae +c4 +02 +20 +94 +c1 +f0 +bb +a0 +02 +18 +bd +ad +02 +7d +b9 +02 +9d +ad +02 +e8 +88 +d0 +f3 +60 +ad +e8 +02 +0d +e7 +02 +f0 +16 +ee +ad +02 +d0 +03 +ee +ae +02 +20 +c3 +c1 +ae +ad +02 +d0 +03 +ce +ae +02 +ce +ad +02 +20 +ad +c2 +b0 +24 +20 +1a +c2 +20 +69 +c2 +8d +e9 +02 +b1 +8c +0d +e9 +02 +24 +83 +10 +13 +48 +a6 +84 +ad +e9 +02 +3d +af +c4 +8d +e9 +02 +68 +4d +e9 +02 +91 +8c +60 +a6 +84 +d0 +f9 +f0 +f4 +20 +64 +c2 +b0 +21 +8d +e9 +02 +b1 +8c +2d +e9 +02 +2a +ca +10 +fc +2a +24 +8b +30 +06 +29 +03 +c5 +84 +18 +60 +18 +29 +03 +f0 +03 +a2 +00 +60 +a2 +ff +60 +bd +02 +d8 +85 +8c +bd +1b +d8 +29 +03 +48 +09 +1c +85 +8d +20 +38 +c2 +91 +8c +68 +09 +18 +85 +8d +20 +4e +c2 +91 +8c +a5 +86 +0a +0a +0a +0a +85 +7e +ad +15 +ff +24 +83 +10 +02 +a5 +85 +29 +0f +05 +7e +60 +a5 +86 +4a +4a +4a +4a +85 +7e +ad +15 +ff +24 +83 +10 +02 +a5 +85 +29 +f0 +05 +7e +60 +20 +ad +c2 +b0 +1f +20 +91 +c2 +ad +af +02 +29 +07 +a8 +ad +ad +02 +24 +83 +08 +10 +01 +0a +29 +07 +aa +bd +89 +c2 +28 +10 +04 +e8 +1d +89 +c2 +60 +80 +40 +20 +10 +08 +04 +02 +01 +98 +18 +7d +02 +d8 +85 +8c +bd +1b +d8 +29 +03 +69 +00 +06 +8c +2a +06 +8c +2a +06 +8c +2a +09 +20 +85 +8d +60 +ad +ae +02 +4a +d0 +1e +ad +ad +02 +6a +4a +24 +83 +30 +01 +4a +a8 +c0 +28 +b0 +0f +ad +b0 +02 +d0 +0a +ad +af +02 +4a +4a +4a +aa +c5 +88 +60 +38 +60 +ad +e6 +02 +f0 +17 +a5 +87 +20 +df +c2 +a5 +88 +0a +a8 +a9 +00 +20 +37 +c3 +9d +ad +02 +98 +e8 +9d +ad +02 +e8 +60 +90 +07 +b0 +14 +b0 +0f +20 +18 +c3 +18 +7d +ad +02 +48 +98 +7d +ae +02 +a8 +68 +60 +20 +18 +c3 +38 +fd +ad +02 +85 +57 +98 +fd +ae +02 +a8 +08 +a5 +57 +28 +60 +b9 +ad +02 +48 +b9 +ae +02 +a8 +68 +60 +20 +05 +c3 +10 +0f +08 +18 +49 +ff +69 +01 +48 +98 +49 +ff +69 +00 +a8 +68 +28 +60 +84 +8e +85 +8f +bd +ad +02 +bc +ae +02 +08 +20 +25 +c3 +9d +ad +02 +98 +9d +ae +02 +a9 +00 +8d +ef +02 +a0 +10 +46 +8e +66 +8f +90 +0f +18 +7d +ad +02 +48 +ad +ef +02 +7d +ae +02 +8d +ef +02 +68 +4e +ef +02 +6a +88 +d0 +e4 +69 +00 +ac +ef +02 +90 +01 +c8 +28 +4c +25 +c3 +a0 +00 +20 +82 +c3 +a0 +02 +b9 +b1 +02 +99 +ad +02 +b9 +b2 +02 +99 +ae +02 +60 +20 +79 +04 +f0 +0c +20 +91 +94 +c9 +2c +f0 +05 +20 +e1 +9d +38 +60 +a9 +00 +a8 +18 +60 +a2 +00 +20 +79 +04 +f0 +f8 +20 +91 +94 +c9 +2c +f0 +f1 +4c +84 +9d +20 +bf +c7 +a2 +01 +20 +79 +04 +f0 +13 +c9 +2c +f0 +0f +20 +84 +9d +e0 +04 +b0 +0b +e0 +02 +24 +83 +30 +02 +b0 +03 +86 +84 +60 +4c +1c +99 +20 +79 +04 +f0 +07 +20 +91 +94 +c9 +2c +d0 +12 +a0 +00 +b9 +ad +02 +9d +ad +02 +e8 +c8 +c0 +04 +d0 +f4 +60 +20 +91 +94 +8e +f0 +02 +20 +8f +c4 +20 +79 +04 +c9 +2c +f0 +56 +c9 +3b +f0 +03 +4c +a1 +94 +20 +73 +04 +20 +e1 +9d +85 +80 +98 +a4 +80 +20 +59 +bc +ae +f0 +02 +bd +ad +02 +9d +af +02 +bd +ae +02 +9d +b0 +02 +20 +d3 +c2 +a9 +0e +8d +f1 +02 +18 +ae +f0 +02 +20 +b0 +bc +9d +ad +02 +98 +9d +ae +02 +a0 +00 +4e +f1 +02 +90 +02 +a0 +02 +20 +f4 +c2 +9d +ad +02 +98 +9d +ae +02 +e8 +e8 +4e +f1 +02 +d0 +dc +18 +60 +20 +73 +04 +ee +f0 +02 +ee +f0 +02 +20 +8f +c4 +ae +f0 +02 +ca +ca +20 +d3 +c2 +a0 +02 +ae +f0 +02 +e8 +e8 +ca +ca +4e +f1 +02 +90 +0a +20 +f6 +c2 +9d +ad +02 +98 +9d +ae +02 +a0 +00 +ec +f0 +02 +f0 +e8 +18 +60 +20 +79 +04 +c9 +aa +f0 +05 +c9 +ab +f0 +01 +18 +2e +f1 +02 +20 +14 +93 +20 +e8 +9d +ae +f0 +02 +9d +ae +02 +98 +9d +ad +02 +60 +ff +aa +55 +00 +00 +00 +2c +71 +57 +8d +80 +00 +a4 +8f +c4 +19 +dd +b2 +f0 +90 +fc +1c +ff +ff +04 +72 +04 +50 +04 +0b +03 +a8 +03 +28 +02 +90 +01 +e3 +01 +28 +00 +63 +20 +bf +c7 +20 +79 +04 +f0 +12 +a2 +01 +c9 +a4 +20 +be +c3 +20 +79 +04 +c9 +2c +f0 +05 +c9 +a4 +f0 +01 +60 +48 +20 +73 +04 +a2 +04 +20 +f7 +c3 +68 +10 +06 +20 +da +c0 +4c +e8 +c4 +20 +7b +c3 +20 +a5 +c1 +4c +e8 +c4 +20 +bf +c7 +a2 +04 +20 +f7 +c3 +4c +7b +c3 +20 +84 +9d +e0 +05 +b0 +43 +86 +7e +20 +d8 +9d +ca +e0 +10 +b0 +39 +86 +7f +a2 +07 +20 +a7 +c3 +e0 +08 +b0 +2e +8a +0a +0a +0a +0a +05 +7f +a6 +7e +e0 +01 +f0 +07 +b0 +0c +8d +15 +ff +d0 +19 +85 +86 +8d +3b +05 +f0 +12 +e0 +03 +f0 +06 +b0 +09 +85 +85 +d0 +08 +8d +16 +ff +f0 +03 +8d +19 +ff +60 +4c +1c +99 +a5 +83 +d0 +05 +a9 +93 +4c +d2 +ff +29 +40 +f0 +0b +20 +6b +c5 +a2 +14 +a0 +00 +18 +20 +f0 +ff +a9 +00 +a0 +20 +a2 +20 +20 +a7 +c5 +20 +38 +c2 +a0 +1c +a2 +04 +20 +a7 +c5 +20 +4e +c2 +a0 +18 +a2 +04 +20 +a7 +c5 +a9 +00 +a2 +03 +9d +ad +02 +ca +10 +fa +60 +84 +8d +a0 +00 +84 +8c +91 +8c +88 +d0 +fb +e6 +8d +ca +d0 +f6 +60 +20 +84 +9d +e0 +02 +b0 +a5 +8e +e6 +02 +60 +c9 +9c +d0 +0a +20 +38 +c7 +20 +73 +04 +a9 +00 +f0 +0a +20 +84 +9d +e0 +05 +b0 +15 +bd +37 +c6 +c5 +83 +f0 +4b +85 +83 +aa +d0 +0c +20 +c9 +c7 +a9 +28 +a2 +19 +d0 +39 +4c +1c +99 +20 +3c +c6 +ad +06 +ff +09 +20 +8d +06 +ff +ad +07 +ff +29 +ef +24 +83 +10 +02 +09 +10 +8d +07 +ff +ad +12 +ff +29 +c3 +09 +08 +8d +12 +ff +ad +14 +ff +29 +03 +09 +18 +8d +14 +ff +a9 +28 +a2 +19 +24 +83 +10 +01 +4a +85 +87 +86 +88 +20 +a5 +c3 +8a +4a +d0 +bc +90 +03 +4c +67 +c5 +60 +00 +20 +60 +a0 +e0 +a5 +75 +f0 +01 +60 +a5 +38 +c9 +40 +b0 +34 +20 +54 +a9 +20 +6b +c8 +8a +18 +65 +31 +98 +65 +32 +c9 +18 +b0 +20 +c6 +75 +a9 +00 +85 +22 +a9 +18 +85 +23 +20 +f0 +c7 +a5 +22 +85 +33 +a5 +23 +85 +34 +a9 +00 +85 +37 +a9 +18 +85 +38 +4c +25 +c8 +4c +81 +86 +20 +54 +a9 +a4 +31 +84 +5f +a5 +32 +18 +69 +30 +b0 +ef +85 +60 +c5 +34 +90 +06 +d0 +e7 +c4 +33 +b0 +e3 +c6 +75 +a9 +00 +85 +4e +a9 +30 +85 +4f +20 +77 +c8 +a5 +5f +85 +22 +a5 +60 +85 +23 +a6 +31 +86 +24 +a5 +32 +85 +25 +38 +e9 +10 +a8 +20 +f8 +c7 +18 +a5 +32 +69 +30 +85 +32 +a5 +30 +69 +30 +85 +30 +a5 +2e +69 +30 +85 +2e +a5 +2c +69 +30 +85 +2c +a5 +42 +69 +30 +85 +42 +20 +18 +88 +20 +4b +88 +24 +81 +10 +2d +a2 +30 +24 +75 +30 +02 +a2 +d0 +8a +18 +65 +3c +85 +3c +8a +18 +6d +5c +02 +8d +5c +02 +8a +18 +6d +f6 +04 +8d +f6 +04 +20 +60 +a7 +a5 +3d +c9 +b0 +d0 +07 +a5 +3e +c9 +07 +d0 +01 +60 +a0 +00 +b1 +3d +c9 +81 +d0 +0e +a0 +02 +20 +ad +c7 +a0 +10 +20 +ad +c7 +a9 +12 +d0 +07 +a0 +04 +20 +ad +c7 +a9 +05 +18 +65 +3d +85 +3d +90 +cf +e6 +3e +d0 +cb +a5 +75 +d0 +01 +60 +a0 +00 +84 +75 +a5 +38 +30 +24 +20 +54 +a9 +20 +6b +c8 +ad +33 +05 +85 +22 +ad +34 +05 +85 +23 +20 +f0 +c7 +a2 +01 +bd +33 +05 +95 +37 +b5 +22 +95 +33 +ca +10 +f4 +4c +25 +c8 +a0 +00 +84 +75 +84 +22 +84 +24 +a9 +10 +85 +23 +a9 +40 +85 +25 +20 +bb +04 +91 +22 +c8 +d0 +f8 +e6 +23 +e6 +25 +a5 +32 +c5 +25 +b0 +ee +a5 +32 +38 +e9 +30 +85 +32 +a5 +2c +e9 +30 +85 +2c +a5 +2e +e9 +30 +85 +2e +a5 +30 +e9 +30 +85 +30 +a5 +42 +e9 +30 +85 +42 +4c +d8 +c6 +b1 +3d +24 +75 +d0 +06 +38 +e9 +30 +91 +3d +60 +18 +69 +30 +91 +3d +60 +a5 +75 +f0 +01 +60 +a2 +23 +4c +83 +86 +ad +06 +ff +29 +df +8d +06 +ff +ad +07 +ff +29 +ef +8d +07 +ff +ad +14 +ff +29 +07 +09 +08 +8d +14 +ff +ad +12 +ff +09 +04 +8d +12 +ff +a9 +00 +85 +83 +60 +a5 +37 +85 +24 +a5 +38 +85 +25 +8a +49 +ff +85 +4e +98 +49 +ff +85 +4f +a0 +00 +e6 +4e +d0 +04 +e6 +4f +f0 +18 +a5 +22 +d0 +02 +c6 +23 +c6 +22 +a5 +24 +d0 +02 +c6 +25 +c6 +24 +20 +bb +04 +91 +22 +4c +04 +c8 +60 +a5 +37 +a4 +38 +85 +22 +84 +23 +38 +a5 +33 +e5 +22 +a5 +34 +e5 +23 +b0 +ec +38 +a5 +22 +e9 +02 +85 +22 +b0 +02 +c6 +23 +a0 +01 +20 +b0 +04 +99 +24 +00 +88 +10 +f7 +c8 +20 +bb +04 +85 +80 +a5 +22 +38 +e5 +80 +85 +22 +b0 +02 +c6 +23 +a0 +02 +b9 +21 +00 +91 +24 +88 +d0 +f8 +f0 +c2 +38 +a5 +37 +e5 +33 +aa +a5 +38 +e5 +34 +a8 +60 +a5 +37 +85 +22 +a5 +38 +85 +23 +38 +a5 +33 +e5 +22 +a5 +34 +e5 +23 +b0 +31 +38 +a5 +22 +e9 +02 +85 +22 +b0 +02 +c6 +23 +18 +a0 +00 +20 +b0 +04 +99 +24 +00 +79 +4e +00 +91 +22 +c8 +c0 +01 +d0 +f0 +88 +20 +bb +04 +85 +80 +a5 +22 +38 +e5 +80 +85 +22 +b0 +c8 +c6 +23 +90 +c4 +60 +20 +1f +cb +29 +e6 +d0 +7b +a0 +00 +20 +3f +ca +a9 +00 +ae +77 +02 +a0 +60 +20 +ba +ff +38 +20 +c0 +ff +90 +09 +48 +20 +35 +c9 +68 +aa +4c +83 +86 +a2 +00 +20 +c6 +ff +a0 +03 +8c +ec +02 +20 +cf +ff +8d +ed +02 +20 +b7 +ff +d0 +3f +20 +cf +ff +8d +ee +02 +20 +b7 +ff +d0 +34 +ce +ec +02 +d0 +e5 +ae +ed +02 +ad +ee +02 +20 +5f +a4 +a9 +20 +20 +d2 +ff +20 +cf +ff +48 +20 +b7 +ff +d0 +17 +68 +f0 +06 +20 +d2 +ff +4c +14 +c9 +a9 +0d +20 +d2 +ff +20 +e1 +ff +f0 +05 +a0 +02 +d0 +b4 +68 +20 +cc +ff +a9 +00 +18 +4c +c3 +ff +4c +a1 +94 +a9 +66 +20 +21 +cb +20 +b5 +cc +a0 +04 +20 +3f +ca +4c +e1 +a7 +a9 +e6 +20 +21 +cb +20 +b5 +cc +a9 +00 +8d +78 +02 +85 +0a +a0 +05 +20 +3f +ca +4c +fa +a7 +20 +1f +cb +20 +af +cc +29 +11 +c9 +11 +f0 +03 +4c +a1 +94 +20 +e7 +ff +20 +2b +cd +d0 +17 +a0 +09 +20 +3f +ca +20 +cf +cc +24 +81 +30 +0b +a0 +00 +a9 +7a +20 +94 +04 +c9 +32 +b0 +01 +60 +a2 +24 +4c +83 +86 +20 +1f +cb +20 +af +cc +20 +2b +cd +d0 +ef +a0 +0f +20 +3f +ca +20 +cf +cc +24 +81 +30 +e3 +a9 +0d +20 +d2 +ff +a0 +00 +a9 +7a +20 +94 +04 +f0 +06 +20 +d2 +ff +c8 +d0 +f3 +a9 +0d +4c +d2 +ff +20 +1f +cb +29 +e7 +d0 +a1 +20 +e7 +ff +a0 +14 +d0 +65 +20 +1f +cb +29 +30 +c9 +30 +d0 +06 +a5 +82 +29 +c7 +f0 +07 +a5 +82 +20 +c0 +cc +a5 +82 +a0 +17 +d0 +4b +a9 +e4 +20 +21 +cb +20 +c6 +cc +a0 +1e +d0 +3f +a9 +c7 +20 +21 +cb +29 +30 +c9 +30 +f0 +03 +4c +a1 +94 +20 +e7 +ff +a0 +25 +4c +3f +ca +48 +ad +5d +02 +a2 +7c +a0 +02 +20 +bd +ff +ad +76 +02 +ae +77 +02 +ac +78 +02 +20 +ba +ff +68 +f0 +0e +ae +5d +02 +38 +20 +c0 +ff +ad +76 +02 +38 +4c +c3 +ff +60 +20 +57 +cd +a2 +00 +8e +5d +02 +b9 +f5 +ca +f0 +ca +c9 +80 +f0 +c6 +aa +ca +f0 +1e +ca +f0 +21 +ca +f0 +24 +ca +f0 +28 +ca +f0 +2d +ca +f0 +34 +ca +f0 +3f +ca +f0 +46 +ca +f0 +66 +20 +eb +ca +c8 +d0 +d5 +a5 +82 +29 +10 +f0 +f7 +ad +6f +02 +4c +81 +ca +ad +73 +02 +09 +30 +d0 +e7 +a9 +40 +24 +82 +30 +e1 +10 +e2 +ad +6e +02 +f0 +dd +a9 +3a +20 +eb +ca +98 +48 +ad +70 +02 +ac +71 +02 +ae +6e +02 +4c +ba +ca +ad +72 +02 +f0 +c5 +a9 +3a +20 +eb +ca +98 +48 +ad +74 +02 +ac +75 +02 +ae +72 +02 +85 +22 +84 +23 +86 +80 +a0 +00 +20 +b0 +04 +20 +eb +ca +c8 +c4 +80 +d0 +f5 +68 +a8 +4c +6f +ca +ad +79 +02 +f0 +98 +a9 +2c +20 +eb +ca +ad +79 +02 +20 +eb +ca +ad +7a +02 +20 +eb +ca +4c +6f +ca +ae +5d +02 +9d +7c +02 +ee +5d +02 +60 +24 +07 +05 +00 +04 +02 +3a +06 +00 +4e +02 +3a +06 +09 +80 +53 +02 +3a +06 +80 +56 +02 +80 +43 +03 +07 +3d +02 +05 +80 +52 +02 +3a +08 +3d +06 +80 +44 +03 +3d +02 +80 +a9 +00 +48 +a9 +00 +85 +82 +a2 +1e +9d +5e +02 +ca +d0 +fa +a2 +08 +8e +77 +02 +a2 +6f +8e +78 +02 +a2 +00 +8e +76 +02 +20 +79 +04 +d0 +07 +68 +20 +aa +cc +a5 +82 +60 +c9 +44 +f0 +1d +c9 +91 +f0 +4e +c9 +55 +f0 +0f +c9 +49 +f0 +2a +c9 +22 +f0 +48 +c9 +28 +f0 +44 +4c +a1 +94 +20 +58 +cc +4c +cd +cb +a9 +10 +20 +aa +cc +20 +97 +cc +e0 +02 +b0 +0a +8e +6f +02 +8e +73 +02 +a9 +10 +d0 +4d +4c +49 +cc +ad +7b +02 +d0 +d9 +20 +73 +04 +8d +79 +02 +20 +73 +04 +8d +7a +02 +a9 +ff +8d +7b +02 +20 +73 +04 +4c +d1 +cb +20 +51 +cc +4c +cd +cb +a9 +01 +20 +69 +cc +8d +6e +02 +8d +5d +02 +a9 +5e +8d +70 +02 +85 +24 +a9 +02 +8d +71 +02 +85 +25 +a0 +00 +20 +b0 +04 +91 +24 +c8 +cc +5d +02 +90 +f5 +a9 +01 +05 +82 +85 +82 +20 +79 +04 +d0 +03 +4c +42 +cb +c9 +2c +d0 +06 +20 +73 +04 +4c +49 +cb +c9 +91 +f0 +b8 +c9 +a4 +d0 +5b +20 +73 +04 +c9 +44 +f0 +10 +c9 +91 +f0 +1f +c9 +55 +f0 +21 +c9 +22 +f0 +23 +c9 +28 +f0 +1f +a9 +20 +20 +aa +cc +20 +97 +cc +e0 +02 +b0 +3b +8e +73 +02 +a9 +20 +d0 +1c +20 +51 +cc +4c +31 +cc +20 +58 +cc +4c +31 +cc +a9 +02 +20 +69 +cc +8d +72 +02 +8e +74 +02 +8c +75 +02 +a9 +02 +05 +82 +85 +82 +20 +79 +04 +f0 +9c +c9 +2c +f0 +ad +c9 +91 +f0 +d3 +c9 +55 +f0 +d5 +a2 +0b +2c +a2 +0e +2c +a2 +17 +4c +83 +86 +20 +73 +04 +c9 +55 +d0 +ee +20 +97 +cc +e0 +20 +b0 +ea +e0 +03 +90 +e6 +8e +77 +02 +a9 +08 +60 +20 +aa +cc +20 +48 +9c +aa +f0 +d7 +a0 +00 +20 +b0 +04 +c9 +40 +d0 +12 +a9 +80 +20 +aa +cc +a5 +82 +09 +80 +85 +82 +ca +e6 +22 +d0 +02 +e6 +23 +8a +c9 +11 +b0 +ba +a6 +22 +a4 +23 +60 +20 +73 +04 +f0 +aa +90 +09 +20 +8e +94 +20 +84 +9d +4c +8b +94 +4c +84 +9d +25 +82 +d0 +98 +60 +29 +e6 +f0 +02 +d0 +91 +a5 +82 +29 +01 +c9 +01 +d0 +f6 +a5 +82 +60 +29 +c4 +d0 +ef +a5 +82 +29 +03 +c9 +03 +d0 +e7 +a5 +82 +60 +a5 +79 +d0 +11 +a9 +28 +85 +79 +20 +06 +a9 +86 +7a +84 +7b +a0 +28 +20 +ba +cd +ea +ae +77 +02 +d0 +05 +a2 +08 +8e +77 +02 +a9 +00 +a0 +6f +20 +ba +ff +a9 +00 +20 +bd +ff +20 +c0 +ff +a2 +00 +20 +c6 +ff +b0 +1b +a0 +ff +c8 +20 +cf +ff +c9 +0d +f0 +04 +91 +7a +d0 +f4 +a9 +00 +91 +7a +20 +cc +ff +a9 +00 +38 +4c +c3 +ff +48 +20 +12 +cd +20 +57 +cd +68 +aa +4c +83 +86 +24 +81 +30 +25 +20 +4f +ff +41 +52 +45 +20 +59 +4f +55 +20 +53 +55 +52 +45 +3f +00 +20 +cc +ff +20 +cf +ff +48 +c9 +0d +f0 +05 +20 +cf +ff +d0 +f7 +68 +c9 +59 +60 +a9 +00 +60 +98 +48 +a5 +79 +f0 +0a +a0 +28 +98 +91 +7a +c8 +a9 +ff +91 +7a +a9 +00 +85 +79 +68 +a8 +60 +2c +30 +20 +59 +45 +4b +aa +98 +48 +a9 +00 +20 +5f +a4 +68 +a8 +60 +85 +3a +88 +aa +e8 +d0 +02 +86 +81 +60 +d8 +1b +14 +0c +07 +7b +01 +d7 +d8 +11 +07 +10 +1d +7b +17 +d8 +07 +10 +05 +1a +1a +16 +7b +1f +d8 +1b +10 +02 +1a +17 +7b +13 +47 +d8 +a0 +21 +b9 +89 +cd +49 +55 +20 +d2 +ff +88 +10 +f5 +60 +00 +a9 +79 +91 +7a +a9 +00 +c8 +91 +7a +60 +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ba +bd +04 +01 +29 +10 +d0 +03 +6c +14 +03 +6c +16 +03 +ad +09 +ff +29 +02 +f0 +03 +20 +60 +ce +2c +d8 +07 +10 +0e +ad +01 +fd +8d +d4 +07 +10 +06 +20 +95 +ea +20 +5b +ea +20 +e4 +e3 +ad +09 +ff +29 +02 +f0 +28 +8d +09 +ff +2c +0b +ff +a9 +cc +50 +1b +6c +12 +03 +20 +bf +cf +20 +cd +ce +a5 +fb +48 +a9 +00 +85 +fb +08 +58 +20 +11 +db +28 +68 +85 +fb +a9 +a1 +8d +0b +ff +4c +be +fc +ad +1c +ff +29 +01 +d0 +39 +ad +1d +ff +c9 +a3 +b0 +2e +24 +83 +50 +52 +a9 +08 +8d +14 +ff +ad +06 +ff +29 +df +a8 +ad +07 +ff +29 +ef +aa +ad +12 +ff +0d +fa +07 +48 +ad +1d +ff +c9 +a3 +90 +f9 +68 +8d +12 +ff +8c +06 +ff +8e +07 +ff +60 +c9 +cc +90 +24 +a6 +83 +f0 +20 +10 +08 +ad +07 +ff +09 +10 +8d +07 +ff +ad +06 +ff +09 +20 +8d +06 +ff +ad +12 +ff +29 +fb +8d +12 +ff +ad +fb +07 +8d +14 +ff +60 +ea +ea +ea +ea +ea +ea +ea +ea +a2 +01 +bd +fc +04 +1d +fe +04 +f0 +13 +fe +fc +04 +d0 +0e +fe +fe +04 +d0 +09 +bd +ee +ce +2d +11 +ff +8d +11 +ff +ca +10 +e2 +60 +ef +9f +e6 +a5 +d0 +06 +e6 +a4 +d0 +02 +e6 +a3 +38 +a5 +a5 +e9 +01 +a5 +a4 +e9 +1a +a5 +a3 +e9 +4f +90 +08 +a2 +00 +86 +a3 +86 +a4 +86 +a5 +a9 +7f +20 +70 +db +85 +ee +a9 +7f +20 +70 +db +c5 +ee +d0 +f0 +09 +7f +85 +91 +60 +78 +a5 +a5 +a6 +a4 +a4 +a3 +78 +85 +a5 +86 +a4 +84 +a3 +58 +60 +0d +4d +4f +4e +49 +54 +4f +52 +8d +0d +42 +52 +45 +41 +cb +0d +20 +20 +20 +50 +43 +20 +20 +53 +52 +20 +41 +43 +20 +58 +52 +20 +59 +52 +20 +53 +50 +0d +3b +a0 +41 +a0 +20 +45 +52 +52 +4f +d2 +bd +36 +cf +08 +29 +7f +20 +d2 +ff +e8 +28 +10 +f3 +60 +a9 +0d +a6 +98 +e0 +03 +f0 +06 +a6 +99 +e0 +03 +f0 +03 +20 +49 +dc +a9 +0d +4c +b0 +d9 +bd +13 +01 +2c +f9 +07 +10 +03 +bd +43 +e1 +60 +2c +f8 +07 +30 +03 +b1 +a1 +60 +a9 +a1 +8d +df +07 +4c +d9 +07 +a9 +09 +8d +20 +fd +09 +80 +8d +20 +fd +4c +1e +fc +08 +78 +8d +3f +ff +b1 +00 +8d +3e +ff +28 +60 +ad +10 +fd +29 +04 +d0 +1b +2c +fc +07 +30 +06 +a5 +01 +29 +f7 +85 +01 +ce +fd +07 +10 +08 +a9 +04 +8d +fd +07 +20 +f0 +ce +4c +f0 +ce +8d +fc +07 +20 +b0 +e3 +4c +d1 +cf +e8 +8e +c4 +fe +8e +c0 +fe +a9 +80 +8d +11 +ff +60 +ff +ff +ff +ff +ff +ff +ff +ff +ff +3c +66 +6e +6e +60 +62 +3c +00 +18 +3c +66 +7e +66 +66 +66 +00 +7c +66 +66 +7c +66 +66 +7c +00 +3c +66 +60 +60 +60 +66 +3c +00 +78 +6c +66 +66 +66 +6c +78 +00 +7e +60 +60 +78 +60 +60 +7e +00 +7e +60 +60 +78 +60 +60 +60 +00 +3c +66 +60 +6e +66 +66 +3c +00 +66 +66 +66 +7e +66 +66 +66 +00 +3c +18 +18 +18 +18 +18 +3c +00 +1e +0c +0c +0c +0c +6c +38 +00 +66 +6c +78 +70 +78 +6c +66 +00 +60 +60 +60 +60 +60 +60 +7e +00 +63 +77 +7f +6b +63 +63 +63 +00 +66 +76 +7e +7e +6e +66 +66 +00 +3c +66 +66 +66 +66 +66 +3c +00 +7c +66 +66 +7c +60 +60 +60 +00 +3c +66 +66 +66 +66 +3c +0e +00 +7c +66 +66 +7c +78 +6c +66 +00 +3c +66 +60 +3c +06 +66 +3c +00 +7e +18 +18 +18 +18 +18 +18 +00 +66 +66 +66 +66 +66 +66 +3c +00 +66 +66 +66 +66 +66 +3c +18 +00 +63 +63 +63 +6b +7f +77 +63 +00 +66 +66 +3c +18 +3c +66 +66 +00 +66 +66 +66 +3c +18 +18 +18 +00 +7e +06 +0c +18 +30 +60 +7e +00 +3c +30 +30 +30 +30 +30 +3c +00 +0c +12 +30 +7c +30 +62 +fc +00 +3c +0c +0c +0c +0c +0c +3c +00 +00 +18 +3c +7e +18 +18 +18 +18 +00 +10 +30 +7f +7f +30 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +18 +18 +18 +18 +00 +00 +18 +00 +66 +66 +66 +00 +00 +00 +00 +00 +66 +66 +ff +66 +ff +66 +66 +00 +18 +3e +60 +3c +06 +7c +18 +00 +62 +66 +0c +18 +30 +66 +46 +00 +3c +66 +3c +38 +67 +66 +3f +00 +06 +0c +18 +00 +00 +00 +00 +00 +0c +18 +30 +30 +30 +18 +0c +00 +30 +18 +0c +0c +0c +18 +30 +00 +00 +66 +3c +ff +3c +66 +00 +00 +00 +18 +18 +7e +18 +18 +00 +00 +00 +00 +00 +00 +00 +18 +18 +30 +00 +00 +00 +7e +00 +00 +00 +00 +00 +00 +00 +00 +00 +18 +18 +00 +00 +03 +06 +0c +18 +30 +60 +00 +3c +66 +6e +76 +66 +66 +3c +00 +18 +18 +38 +18 +18 +18 +7e +00 +3c +66 +06 +0c +30 +60 +7e +00 +3c +66 +06 +1c +06 +66 +3c +00 +06 +0e +1e +66 +7f +06 +06 +00 +7e +60 +7c +06 +06 +66 +3c +00 +3c +66 +60 +7c +66 +66 +3c +00 +7e +66 +0c +18 +18 +18 +18 +00 +3c +66 +66 +3c +66 +66 +3c +00 +3c +66 +66 +3e +06 +66 +3c +00 +00 +00 +18 +00 +00 +18 +00 +00 +00 +00 +18 +00 +00 +18 +18 +30 +0e +18 +30 +60 +30 +18 +0e +00 +00 +00 +7e +00 +7e +00 +00 +00 +70 +18 +0c +06 +0c +18 +70 +00 +3c +66 +06 +0c +18 +00 +18 +00 +00 +00 +00 +ff +ff +00 +00 +00 +08 +1c +3e +7f +7f +1c +3e +00 +18 +18 +18 +18 +18 +18 +18 +18 +00 +00 +00 +ff +ff +00 +00 +00 +00 +00 +ff +ff +00 +00 +00 +00 +00 +ff +ff +00 +00 +00 +00 +00 +00 +00 +00 +00 +ff +ff +00 +00 +30 +30 +30 +30 +30 +30 +30 +30 +0c +0c +0c +0c +0c +0c +0c +0c +00 +00 +00 +e0 +f0 +38 +18 +18 +18 +18 +1c +0f +07 +00 +00 +00 +18 +18 +38 +f0 +e0 +00 +00 +00 +c0 +c0 +c0 +c0 +c0 +c0 +ff +ff +c0 +e0 +70 +38 +1c +0e +07 +03 +03 +07 +0e +1c +38 +70 +e0 +c0 +ff +ff +c0 +c0 +c0 +c0 +c0 +c0 +ff +ff +03 +03 +03 +03 +03 +03 +00 +3c +7e +7e +7e +7e +3c +00 +00 +00 +00 +00 +00 +ff +ff +00 +36 +7f +7f +7f +3e +1c +08 +00 +60 +60 +60 +60 +60 +60 +60 +60 +00 +00 +00 +07 +0f +1c +18 +18 +c3 +e7 +7e +3c +3c +7e +e7 +c3 +00 +3c +7e +66 +66 +7e +3c +00 +18 +18 +66 +66 +18 +18 +3c +00 +06 +06 +06 +06 +06 +06 +06 +06 +08 +1c +3e +7f +3e +1c +08 +00 +18 +18 +18 +ff +ff +18 +18 +18 +c0 +c0 +30 +30 +c0 +c0 +30 +30 +18 +18 +18 +18 +18 +18 +18 +18 +00 +00 +03 +3e +76 +36 +36 +00 +ff +7f +3f +1f +0f +07 +03 +01 +00 +00 +00 +00 +00 +00 +00 +00 +f0 +f0 +f0 +f0 +f0 +f0 +f0 +f0 +00 +00 +00 +00 +ff +ff +ff +ff +ff +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ff +c0 +c0 +c0 +c0 +c0 +c0 +c0 +c0 +cc +cc +33 +33 +cc +cc +33 +33 +03 +03 +03 +03 +03 +03 +03 +03 +00 +00 +00 +00 +cc +cc +33 +33 +ff +fe +fc +f8 +f0 +e0 +c0 +80 +03 +03 +03 +03 +03 +03 +03 +03 +18 +18 +18 +1f +1f +18 +18 +18 +00 +00 +00 +00 +0f +0f +0f +0f +18 +18 +18 +1f +1f +00 +00 +00 +00 +00 +00 +f8 +f8 +18 +18 +18 +00 +00 +00 +00 +00 +00 +ff +ff +00 +00 +00 +1f +1f +18 +18 +18 +18 +18 +18 +ff +ff +00 +00 +00 +00 +00 +00 +ff +ff +18 +18 +18 +18 +18 +18 +f8 +f8 +18 +18 +18 +c0 +c0 +c0 +c0 +c0 +c0 +c0 +c0 +e0 +e0 +e0 +e0 +e0 +e0 +e0 +e0 +07 +07 +07 +07 +07 +07 +07 +07 +ff +ff +00 +00 +00 +00 +00 +00 +ff +ff +ff +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ff +ff +ff +03 +03 +03 +03 +03 +03 +ff +ff +00 +00 +00 +00 +f0 +f0 +f0 +f0 +0f +0f +0f +0f +00 +00 +00 +00 +18 +18 +18 +f8 +f8 +00 +00 +00 +f0 +f0 +f0 +f0 +00 +00 +00 +00 +f0 +f0 +f0 +f0 +0f +0f +0f +0f +3c +66 +6e +6e +60 +62 +3c +00 +00 +00 +3c +06 +3e +66 +3e +00 +60 +60 +7c +66 +66 +66 +7c +00 +00 +00 +3c +66 +60 +66 +3c +00 +06 +06 +3e +66 +66 +66 +3e +00 +00 +00 +3c +66 +7e +60 +3e +00 +1c +36 +30 +78 +30 +30 +30 +00 +00 +00 +3e +66 +66 +3e +06 +7c +60 +60 +7c +66 +66 +66 +66 +00 +18 +00 +18 +18 +18 +18 +18 +00 +06 +00 +06 +06 +06 +06 +66 +3c +60 +60 +66 +6c +78 +7c +66 +00 +38 +18 +18 +18 +18 +18 +3c +00 +00 +00 +6b +7f +7f +63 +63 +00 +00 +00 +7c +66 +66 +66 +66 +00 +00 +00 +3c +66 +66 +66 +3c +00 +00 +00 +7c +66 +66 +7c +60 +60 +00 +00 +3e +66 +66 +3e +06 +06 +00 +00 +7c +66 +60 +60 +60 +00 +00 +00 +3c +60 +3c +06 +7c +00 +30 +30 +fc +30 +30 +36 +1c +00 +00 +00 +66 +66 +66 +66 +3c +00 +00 +00 +66 +66 +66 +3c +18 +00 +00 +00 +63 +6b +7f +36 +22 +00 +00 +00 +66 +3c +18 +3c +66 +00 +00 +00 +66 +66 +66 +3e +06 +7c +00 +00 +7e +0c +18 +30 +7e +00 +3c +30 +30 +30 +30 +30 +3c +00 +0c +12 +30 +7c +30 +62 +fc +00 +3c +0c +0c +0c +0c +0c +3c +00 +00 +18 +3c +7e +18 +18 +18 +18 +00 +10 +30 +7f +7f +30 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +18 +18 +18 +18 +00 +00 +18 +00 +66 +66 +66 +00 +00 +00 +00 +00 +66 +66 +ff +66 +ff +66 +66 +00 +18 +3e +60 +3c +06 +7c +18 +00 +62 +66 +0c +18 +30 +66 +46 +00 +3c +66 +3c +38 +67 +66 +3f +00 +06 +0c +18 +00 +00 +00 +00 +00 +0c +18 +30 +30 +30 +18 +0c +00 +30 +18 +0c +0c +0c +18 +30 +00 +00 +66 +3c +ff +3c +66 +00 +00 +00 +18 +18 +7e +18 +18 +00 +00 +00 +00 +00 +00 +00 +18 +18 +30 +00 +00 +00 +7e +00 +00 +00 +00 +00 +00 +00 +00 +00 +18 +18 +00 +00 +03 +06 +0c +18 +30 +60 +00 +3c +66 +6e +76 +66 +66 +3c +00 +18 +18 +38 +18 +18 +18 +7e +00 +3c +66 +06 +0c +30 +60 +7e +00 +3c +66 +06 +1c +06 +66 +3c +00 +06 +0e +1e +66 +7f +06 +06 +00 +7e +60 +7c +06 +06 +66 +3c +00 +3c +66 +60 +7c +66 +66 +3c +00 +7e +66 +0c +18 +18 +18 +18 +00 +3c +66 +66 +3c +66 +66 +3c +00 +3c +66 +66 +3e +06 +66 +3c +00 +00 +00 +18 +00 +00 +18 +00 +00 +00 +00 +18 +00 +00 +18 +18 +30 +0e +18 +30 +60 +30 +18 +0e +00 +00 +00 +7e +00 +7e +00 +00 +00 +70 +18 +0c +06 +0c +18 +70 +00 +3c +66 +06 +0c +18 +00 +18 +00 +00 +00 +00 +ff +ff +00 +00 +00 +18 +3c +66 +7e +66 +66 +66 +00 +7c +66 +66 +7c +66 +66 +7c +00 +3c +66 +60 +60 +60 +66 +3c +00 +78 +6c +66 +66 +66 +6c +78 +00 +7e +60 +60 +78 +60 +60 +7e +00 +7e +60 +60 +78 +60 +60 +60 +00 +3c +66 +60 +6e +66 +66 +3c +00 +66 +66 +66 +7e +66 +66 +66 +00 +3c +18 +18 +18 +18 +18 +3c +00 +1e +0c +0c +0c +0c +6c +38 +00 +66 +6c +78 +70 +78 +6c +66 +00 +60 +60 +60 +60 +60 +60 +7e +00 +63 +77 +7f +6b +63 +63 +63 +00 +66 +76 +7e +7e +6e +66 +66 +00 +3c +66 +66 +66 +66 +66 +3c +00 +7c +66 +66 +7c +60 +60 +60 +00 +3c +66 +66 +66 +66 +3c +0e +00 +7c +66 +66 +7c +78 +6c +66 +00 +3c +66 +60 +3c +06 +66 +3c +00 +7e +18 +18 +18 +18 +18 +18 +00 +66 +66 +66 +66 +66 +66 +3c +00 +66 +66 +66 +66 +66 +3c +18 +00 +63 +63 +63 +6b +7f +77 +63 +00 +66 +66 +3c +18 +3c +66 +66 +00 +66 +66 +66 +3c +18 +18 +18 +00 +7e +06 +0c +18 +30 +60 +7e +00 +18 +18 +18 +ff +ff +18 +18 +18 +c0 +c0 +30 +30 +c0 +c0 +30 +30 +18 +18 +18 +18 +18 +18 +18 +18 +33 +33 +cc +cc +33 +33 +cc +cc +33 +99 +cc +66 +33 +99 +cc +66 +00 +00 +00 +00 +00 +00 +00 +00 +f0 +f0 +f0 +f0 +f0 +f0 +f0 +f0 +00 +00 +00 +00 +ff +ff +ff +ff +ff +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ff +c0 +c0 +c0 +c0 +c0 +c0 +c0 +c0 +cc +cc +33 +33 +cc +cc +33 +33 +03 +03 +03 +03 +03 +03 +03 +03 +00 +00 +00 +00 +cc +cc +33 +33 +cc +99 +33 +66 +cc +99 +33 +66 +03 +03 +03 +03 +03 +03 +03 +03 +18 +18 +18 +1f +1f +18 +18 +18 +00 +00 +00 +00 +0f +0f +0f +0f +18 +18 +18 +1f +1f +00 +00 +00 +00 +00 +00 +f8 +f8 +18 +18 +18 +00 +00 +00 +00 +00 +00 +ff +ff +00 +00 +00 +1f +1f +18 +18 +18 +18 +18 +18 +ff +ff +00 +00 +00 +00 +00 +00 +ff +ff +18 +18 +18 +18 +18 +18 +f8 +f8 +18 +18 +18 +c0 +c0 +c0 +c0 +c0 +c0 +c0 +c0 +e0 +e0 +e0 +e0 +e0 +e0 +e0 +e0 +07 +07 +07 +07 +07 +07 +07 +07 +ff +ff +00 +00 +00 +00 +00 +00 +ff +ff +ff +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ff +ff +ff +01 +03 +06 +6c +78 +70 +60 +00 +00 +00 +00 +00 +f0 +f0 +f0 +f0 +0f +0f +0f +0f +00 +00 +00 +00 +18 +18 +18 +f8 +f8 +00 +00 +00 +f0 +f0 +f0 +f0 +00 +00 +00 +00 +f0 +f0 +f0 +f0 +0f +0f +0f +0f +08 +09 +00 +28 +50 +78 +a0 +c8 +f0 +18 +40 +68 +90 +b8 +e0 +08 +30 +58 +80 +a8 +d0 +f8 +20 +48 +70 +98 +c0 +0c +0c +0c +0c +0c +0c +0c +0d +0d +0d +0d +0d +0d +0e +0e +0e +0e +0e +0e +0e +0f +0f +0f +0f +0f +a2 +28 +a0 +19 +60 +b0 +0e +86 +cd +86 +c4 +84 +ca +84 +c5 +20 +70 +de +20 +a8 +d8 +a6 +cd +a4 +ca +60 +a9 +0c +8d +3e +05 +a9 +03 +85 +99 +a9 +00 +85 +98 +8d +47 +05 +85 +83 +85 +ef +85 +f0 +a9 +7a +8d +45 +05 +a9 +db +8d +46 +05 +a9 +0a +8d +3f +05 +8d +4a +05 +8d +42 +05 +a9 +80 +8d +40 +05 +a9 +10 +8d +3b +05 +a9 +04 +8d +41 +05 +20 +70 +de +20 +9a +d8 +20 +aa +d8 +20 +f7 +da +ec +e5 +07 +e8 +90 +f4 +ae +e6 +07 +86 +cd +86 +c4 +ac +e7 +07 +84 +ca +84 +c5 +a6 +cd +bd +02 +d8 +85 +c8 +bd +1b +d8 +85 +c9 +a5 +c8 +85 +ea +a5 +c9 +29 +03 +09 +08 +85 +eb +60 +ae +5d +05 +f0 +0f +ac +5e +05 +b9 +67 +05 +ce +5d +05 +ee +5e +05 +58 +18 +60 +ac +27 +05 +ea +bd +28 +05 +9d +27 +05 +e8 +e4 +ef +d0 +f5 +c6 +ef +98 +58 +18 +60 +20 +49 +dc +20 +b4 +d8 +a4 +ca +b1 +ea +48 +ad +3b +05 +91 +ea +98 +18 +65 +c8 +8d +0d +ff +a5 +c9 +69 +00 +e9 +0b +8d +0c +ff +a5 +ef +0d +5d +05 +f0 +f9 +68 +91 +ea +a9 +ff +8d +0c +ff +8d +0d +ff +20 +c1 +d8 +c9 +83 +d0 +10 +a2 +09 +78 +86 +ef +bd +29 +e1 +9d +26 +05 +ca +d0 +f7 +f0 +ba +c9 +0d +d0 +b3 +85 +c7 +20 +95 +df +8e +49 +05 +20 +87 +df +a9 +00 +85 +cb +ac +e7 +07 +a5 +c4 +30 +13 +c5 +cd +90 +0f +a4 +c5 +cd +49 +05 +d0 +04 +c4 +c3 +f0 +02 +b0 +11 +85 +cd +84 +ca +4c +77 +d9 +98 +48 +8a +48 +a5 +c7 +f0 +c4 +10 +08 +a9 +00 +85 +c7 +4c +74 +cf +ea +20 +a8 +d8 +20 +2f +df +85 +ce +29 +3f +06 +ce +24 +ce +10 +02 +09 +80 +90 +04 +a6 +cb +d0 +04 +70 +02 +09 +40 +20 +ba +d9 +a4 +cd +cc +49 +05 +90 +0a +a4 +ca +c4 +c3 +90 +04 +66 +c7 +30 +03 +20 +bf +df +c9 +de +d0 +02 +a9 +ff +85 +ce +68 +aa +68 +a8 +a5 +ce +18 +60 +c9 +22 +d0 +08 +a5 +cb +49 +01 +85 +cb +a9 +22 +60 +a5 +ce +8d +eb +07 +68 +a8 +a5 +cf +f0 +02 +46 +cb +68 +aa +68 +18 +60 +09 +40 +a6 +c2 +f0 +02 +09 +80 +a6 +cf +f0 +02 +c6 +cf +2c +ea +07 +10 +09 +48 +20 +ce +dd +a2 +00 +86 +cf +68 +20 +01 +e0 +cc +e8 +07 +90 +0c +a6 +cd +ec +e5 +07 +90 +05 +2c +e9 +07 +30 +17 +20 +a8 +d8 +20 +bf +df +90 +0f +20 +39 +df +b0 +09 +38 +2c +e9 +07 +70 +04 +20 +5e +da +18 +60 +a6 +cd +ec +e5 +07 +90 +10 +2c +e9 +07 +10 +07 +ad +e6 +07 +85 +cd +b0 +06 +20 +89 +da +18 +e6 +cd +4c +a8 +d8 +bd +02 +d8 +85 +a9 +85 +c0 +bd +1b +d8 +85 +c1 +29 +03 +09 +08 +85 +aa +b1 +c0 +91 +c8 +b1 +a9 +91 +ea +cc +e8 +07 +c8 +90 +f2 +60 +a6 +c4 +30 +06 +e4 +cd +90 +02 +e6 +c4 +ae +e5 +07 +20 +aa +d8 +ac +e7 +07 +e4 +cd +f0 +0e +ca +20 +3b +df +e8 +20 +48 +df +ca +20 +3d +da +b0 +e8 +20 +f7 +da +4c +59 +df +ae +e6 +07 +e8 +20 +3b +df +90 +0c +ec +e5 +07 +90 +f5 +ae +e6 +07 +e8 +20 +4a +df +c6 +cd +24 +c4 +30 +02 +c6 +c4 +ae +e6 +07 +e4 +fe +b0 +02 +c6 +fe +20 +c5 +da +ae +e6 +07 +20 +3b +df +08 +20 +4a +df +28 +90 +05 +2c +ec +07 +30 +c5 +60 +20 +aa +d8 +ac +e7 +07 +ec +e5 +07 +b0 +0e +e8 +20 +3b +df +ca +20 +48 +df +e8 +20 +3d +da +b0 +e7 +20 +f7 +da +a9 +7f +20 +70 +db +c9 +df +d0 +09 +a0 +00 +ea +ca +d0 +fc +88 +d0 +f9 +60 +ea +ea +ea +ac +e7 +07 +20 +4a +df +20 +aa +d8 +88 +c8 +a9 +20 +91 +c8 +ad +3b +05 +91 +ea +cc +e8 +07 +d0 +f1 +60 +a9 +00 +8d +43 +05 +a0 +40 +84 +c6 +20 +70 +db +aa +e0 +ff +d0 +03 +4c +01 +dc +a0 +00 +a9 +26 +85 +ec +a9 +e0 +85 +ed +a9 +fe +a2 +08 +48 +68 +48 +20 +70 +db +85 +ee +68 +48 +20 +70 +db +c5 +ee +d0 +f0 +4a +b0 +16 +48 +b1 +ec +c9 +05 +b0 +0c +c9 +03 +f0 +08 +0d +43 +05 +8d +43 +05 +10 +02 +84 +c6 +68 +c8 +c0 +41 +b0 +08 +ca +d0 +df +38 +68 +2a +d0 +c7 +68 +a5 +c6 +6c +45 +05 +8d +30 +fd +8d +08 +ff +ad +08 +ff +60 +ad +43 +05 +c9 +03 +d0 +19 +ad +47 +05 +30 +34 +ad +44 +05 +d0 +2f +ad +13 +ff +49 +04 +8d +13 +ff +a9 +08 +8d +44 +05 +d0 +20 +0a +c9 +08 +90 +10 +a9 +06 +ae +f7 +07 +d0 +09 +a6 +c6 +e0 +0d +d0 +03 +86 +f0 +60 +aa +bd +1e +e0 +85 +ec +bd +1f +e0 +85 +ed +a4 +c6 +b1 +ec +aa +cc +f6 +07 +f0 +07 +a0 +10 +8c +42 +05 +d0 +36 +29 +7f +2c +40 +05 +30 +16 +70 +57 +c9 +7f +f0 +29 +c9 +14 +f0 +0c +c9 +20 +f0 +08 +c9 +1d +f0 +04 +c9 +11 +d0 +43 +ac +42 +05 +f0 +05 +ce +42 +05 +d0 +39 +ce +41 +05 +d0 +34 +a0 +04 +8c +41 +05 +a4 +ef +88 +10 +2a +ea +ea +4e +44 +05 +a4 +c6 +8c +f6 +07 +e0 +ff +f0 +1c +8a +a2 +00 +86 +f0 +a2 +07 +dd +41 +dc +f0 +11 +ca +10 +f8 +a6 +ef +ec +3f +05 +b0 +06 +9d +27 +05 +e8 +86 +ef +60 +bd +5f +05 +8d +5d +05 +a9 +00 +ca +30 +06 +18 +7d +5f +05 +90 +f7 +8d +5e +05 +60 +85 +89 +86 +8a +87 +8b +88 +8c +85 +ce +48 +8a +48 +98 +48 +a5 +f0 +d0 +fc +85 +c7 +a9 +d9 +48 +a9 +c6 +48 +a4 +ca +a5 +ce +c9 +0d +f0 +28 +c9 +8d +f0 +24 +ae +eb +07 +e0 +1b +d0 +03 +4c +06 +de +aa +30 +14 +c9 +20 +90 +2e +c9 +60 +90 +04 +29 +df +d0 +02 +29 +3f +20 +ba +d9 +4c +db +d9 +4c +47 +dd +20 +95 +df +e8 +20 +4a +df +ac +e7 +07 +84 +ca +20 +21 +da +a9 +00 +85 +cf +85 +c2 +85 +cb +8d +3c +05 +60 +c9 +1b +f0 +4e +a6 +cf +f0 +03 +4c +df +d9 +c9 +14 +d0 +03 +4c +99 +dd +a6 +cb +d0 +f2 +c9 +12 +d0 +02 +85 +c2 +c9 +13 +d0 +0b +cd +eb +07 +d0 +03 +20 +70 +de +4c +9a +d8 +c9 +1d +f0 +24 +c9 +11 +f0 +26 +c9 +0e +f0 +49 +c9 +08 +f0 +4c +c9 +09 +f0 +4f +a2 +0f +dd +33 +e1 +f0 +04 +ca +10 +f8 +60 +48 +20 +8a +cf +8d +3b +05 +68 +60 +20 +bf +df +b0 +04 +60 +20 +21 +da +20 +39 +df +b0 +03 +38 +66 +c4 +18 +60 +ae +e6 +07 +e4 +cd +b0 +f8 +20 +03 +dd +c6 +cd +4c +a8 +d8 +20 +d4 +df +b0 +eb +d0 +e8 +e6 +cd +d0 +ed +ad +13 +ff +09 +04 +d0 +15 +a9 +80 +0d +47 +05 +30 +05 +a9 +7f +2d +47 +05 +8d +47 +05 +60 +ad +13 +ff +29 +fb +8d +13 +ff +60 +29 +7f +c9 +7f +d0 +02 +a9 +5e +c9 +20 +90 +03 +4c +d9 +d9 +a6 +cb +f0 +05 +09 +40 +4c +df +d9 +c9 +14 +f0 +6b +a6 +cf +d0 +f3 +c9 +11 +f0 +a2 +c9 +12 +d0 +04 +a9 +00 +85 +c2 +c9 +1d +f0 +a5 +c9 +13 +d0 +03 +4c +8b +d8 +c9 +02 +d0 +05 +a9 +80 +8d +3c +05 +c9 +04 +d0 +05 +a9 +00 +8d +3c +05 +c9 +0e +f0 +aa +09 +80 +4c +e6 +dc +20 +1c +dd +20 +f6 +df +b0 +10 +cc +e8 +07 +90 +16 +a6 +cd +e8 +20 +3b +df +b0 +0e +20 +ff +df +a5 +cc +85 +ca +a5 +fe +85 +cd +4c +a8 +d8 +20 +bf +df +20 +2f +df +20 +d4 +df +20 +11 +e0 +20 +bf +df +4c +a1 +dd +20 +f6 +df +20 +95 +df +e4 +fe +d0 +02 +c4 +cc +90 +21 +20 +f8 +d9 +b0 +22 +20 +d4 +df +20 +2f +df +20 +bf +df +20 +11 +e0 +20 +d4 +df +a6 +cd +e4 +fe +d0 +eb +c4 +cc +d0 +e7 +20 +ff +df +e6 +cf +d0 +02 +c6 +cf +4c +b1 +dd +29 +7f +38 +e9 +41 +c9 +17 +b0 +0a +0a +aa +bd +1b +de +48 +bd +1a +de +48 +60 +28 +df +5f +de +25 +df +9f +de +18 +de +18 +de +18 +de +18 +de +8a +de +81 +df +94 +df +1c +df +1f +df +87 +d8 +9a +dc +e0 +de +ca +de +47 +de +18 +de +5d +de +18 +de +f5 +de +03 +df +20 +70 +de +20 +8b +d8 +a9 +01 +aa +20 +7a +de +a9 +17 +a2 +26 +20 +67 +de +4c +9a +d8 +18 +24 +38 +a6 +ca +a5 +cd +90 +13 +8d +e5 +07 +8e +e8 +07 +4c +80 +de +a9 +18 +a2 +27 +20 +67 +de +a9 +00 +aa +8d +e6 +07 +8e +e7 +07 +a9 +00 +a2 +04 +9d +ed +07 +ca +d0 +fa +60 +20 +5e +da +20 +a1 +d8 +e8 +20 +3b +df +08 +20 +46 +df +28 +b0 +03 +38 +66 +c4 +60 +20 +87 +df +ad +e6 +07 +48 +a5 +cd +8d +e6 +07 +ad +ec +07 +48 +a9 +80 +8d +ec +07 +20 +9e +da +68 +8d +ec +07 +ad +e6 +07 +85 +cd +68 +8d +e6 +07 +38 +66 +c4 +4c +a1 +d8 +20 +f6 +df +20 +fd +da +e6 +cd +20 +a8 +d8 +ac +e7 +07 +20 +39 +df +b0 +f0 +4c +b1 +dd +20 +f6 +df +20 +ff +df +cc +e7 +07 +d0 +05 +20 +39 +df +90 +ed +20 +d4 +df +90 +ee +20 +f6 +df +8a +48 +20 +89 +da +68 +85 +fe +4c +de +de +20 +f6 +df +20 +39 +df +b0 +03 +38 +66 +c4 +ad +e6 +07 +85 +cd +20 +5e +da +20 +4a +df +4c +de +de +a9 +00 +2c +a9 +80 +8d +e9 +07 +60 +a9 +00 +2c +a9 +ff +8d +ea +07 +60 +a4 +ca +b1 +ea +8d +ed +07 +b1 +c8 +60 +a6 +cd +20 +66 +df +3d +ee +07 +c9 +01 +4c +55 +df +a6 +cd +b0 +0f +20 +66 +df +49 +ff +3d +ee +07 +9d +ee +07 +ae +e9 +02 +60 +2c +e9 +07 +70 +dd +20 +66 +df +1d +ee +07 +d0 +ec +8e +e9 +02 +8a +29 +07 +aa +bd +7a +df +48 +ad +e9 +02 +4a +4a +4a +aa +68 +60 +80 +40 +20 +10 +08 +04 +02 +01 +ac +e7 +07 +84 +ca +20 +39 +df +90 +06 +c6 +cd +10 +f7 +e6 +cd +4c +a8 +d8 +e6 +cd +20 +39 +df +b0 +f9 +c6 +cd +20 +a8 +d8 +ac +e8 +07 +84 +ca +20 +2f +df +c9 +20 +d0 +0f +cc +e7 +07 +d0 +05 +20 +39 +df +90 +05 +20 +d4 +df +90 +ea +84 +c3 +60 +48 +a4 +ca +cc +e8 +07 +90 +08 +20 +21 +da +ac +e7 +07 +88 +38 +c8 +84 +ca +68 +60 +a4 +ca +88 +30 +05 +cc +e7 +07 +b0 +11 +ac +e6 +07 +c4 +cd +b0 +10 +c6 +cd +48 +20 +a8 +d8 +68 +ac +e8 +07 +84 +ca +cc +e8 +07 +18 +60 +a4 +ca +84 +cc +a6 +cd +86 +fe +60 +a9 +20 +a4 +ca +91 +c8 +20 +b4 +d8 +ad +3b +05 +0d +3c +05 +91 +ea +60 +a4 +ca +91 +c8 +20 +b4 +d8 +ad +ed +07 +91 +ea +60 +26 +e0 +67 +e0 +a8 +e0 +e9 +e0 +14 +0d +5c +8c +85 +89 +86 +40 +33 +57 +41 +34 +5a +53 +45 +01 +35 +52 +44 +36 +43 +46 +54 +58 +37 +59 +47 +38 +42 +48 +55 +56 +39 +49 +4a +30 +4d +4b +4f +4e +11 +50 +4c +91 +2e +3a +2d +2c +9d +2a +3b +1d +1b +3d +2b +2f +31 +13 +04 +32 +20 +02 +51 +03 +ff +94 +8d +a9 +88 +8a +87 +8b +ba +23 +d7 +c1 +24 +da +d3 +c5 +01 +25 +d2 +c4 +26 +c3 +c6 +d4 +d8 +27 +d9 +c7 +28 +c2 +c8 +d5 +d6 +29 +c9 +ca +5e +cd +cb +cf +ce +11 +d0 +cc +91 +3e +5b +dd +3c +9d +c0 +5d +1d +1b +5f +db +3f +21 +93 +04 +22 +a0 +02 +d1 +83 +ff +94 +8d +a8 +88 +8a +87 +8b +a4 +96 +b3 +b0 +97 +ad +ae +b1 +01 +98 +b2 +ac +99 +bc +bb +a3 +bd +9a +b7 +a5 +9b +bf +b4 +b8 +be +29 +a2 +b5 +30 +a7 +a1 +b9 +aa +11 +af +b6 +91 +3e +5b +dc +3c +9d +df +5d +1d +1b +de +a6 +3f +81 +93 +04 +95 +a0 +02 +ab +83 +ff +ff +ff +1c +ff +ff +ff +ff +ff +1c +17 +01 +9f +1a +13 +05 +ff +9c +12 +04 +1e +03 +06 +14 +18 +1f +19 +07 +9e +02 +08 +15 +16 +12 +09 +0a +92 +0d +0b +0f +0e +ff +10 +0c +ff +84 +1b +ff +82 +ff +ff +1d +ff +1b +06 +ff +ff +90 +ff +ff +05 +ff +ff +11 +ff +ff +44 +cc +22 +2a +0d +52 +55 +4e +0d +90 +05 +1c +9f +9c +1e +1f +9e +81 +95 +96 +97 +98 +99 +9a +9b +00 +71 +32 +63 +44 +35 +46 +77 +48 +29 +5a +6b +5c +6d +2e +5f +09 +40 +2c +09 +20 +48 +24 +94 +10 +0a +38 +66 +a6 +20 +81 +e1 +46 +94 +46 +a6 +68 +85 +95 +78 +20 +c6 +e2 +20 +bf +e2 +a5 +01 +09 +04 +85 +01 +78 +20 +bf +e2 +20 +c6 +e2 +20 +dc +e2 +78 +20 +c6 +e2 +20 +d4 +e2 +b0 +5f +20 +b8 +e2 +24 +a6 +10 +0e +20 +d4 +e2 +90 +fb +a5 +01 +c5 +01 +d0 +fa +0a +b0 +f7 +20 +d4 +e2 +90 +fb +20 +bf +e2 +a9 +08 +85 +aa +20 +d4 +e2 +90 +3e +66 +95 +b0 +05 +20 +cd +e2 +d0 +03 +20 +c6 +e2 +20 +11 +e3 +20 +b8 +e2 +20 +11 +e3 +a5 +01 +29 +fe +09 +02 +85 +01 +c6 +aa +d0 +da +8a +48 +a2 +78 +a5 +01 +c5 +01 +d0 +fa +0a +90 +07 +ca +d0 +f4 +68 +aa +b0 +09 +68 +aa +58 +60 +a9 +80 +4c +f0 +e1 +a9 +03 +20 +1e +f4 +58 +18 +90 +4b +85 +95 +20 +77 +e1 +a5 +01 +29 +fb +85 +01 +60 +85 +95 +20 +77 +e1 +24 +90 +30 +36 +78 +20 +cd +e2 +20 +fc +e1 +20 +b8 +e2 +24 +01 +70 +fc +58 +60 +ff +24 +94 +30 +05 +38 +66 +94 +d0 +05 +48 +20 +81 +e1 +68 +85 +95 +18 +60 +78 +20 +bf +e2 +a5 +01 +09 +04 +85 +01 +a9 +5f +d0 +02 +a9 +3f +20 +58 +e1 +20 +fc +e1 +8a +a2 +14 +ca +d0 +fd +aa +20 +b8 +e2 +4c +c6 +e2 +78 +a9 +00 +85 +aa +20 +b8 +e2 +8a +48 +20 +d4 +e2 +10 +fb +a2 +20 +20 +c6 +e2 +a5 +01 +c5 +01 +d0 +fa +0a +10 +1f +ca +d0 +f4 +a5 +aa +f0 +07 +68 +aa +a9 +02 +4c +f0 +e1 +20 +cd +e2 +a2 +40 +ca +d0 +fd +a9 +40 +20 +1e +f4 +e6 +aa +d0 +d3 +a2 +08 +a5 +01 +0a +10 +fb +66 +a8 +a5 +01 +c5 +01 +d0 +fa +0a +30 +f7 +ca +d0 +ed +86 +aa +68 +aa +20 +cd +e2 +a9 +40 +24 +90 +50 +03 +20 +45 +e2 +a5 +a8 +58 +18 +60 +a5 +01 +29 +fd +85 +01 +60 +a5 +01 +09 +02 +85 +01 +60 +a5 +01 +29 +fe +85 +01 +60 +a5 +01 +09 +01 +85 +01 +60 +a5 +01 +c5 +01 +d0 +fa +0a +60 +20 +f8 +e2 +a9 +10 +2c +09 +ff +f0 +fb +8d +09 +ff +60 +20 +fc +e2 +a9 +10 +2c +09 +ff +f0 +fb +8d +09 +ff +60 +a9 +04 +d0 +02 +a9 +40 +08 +48 +78 +a9 +00 +8d +02 +ff +68 +8d +03 +ff +a9 +10 +8d +09 +ff +28 +60 +8a +a2 +05 +ca +d0 +fd +aa +60 +38 +24 +18 +ad +10 +fd +29 +04 +f0 +3f +08 +20 +d8 +fb +0d +50 +52 +45 +53 +53 +20 +50 +4c +41 +59 +20 +00 +28 +90 +0d +20 +d8 +fb +26 +20 +52 +45 +43 +4f +52 +44 +20 +00 +20 +d8 +fb +4f +4e +20 +54 +41 +50 +45 +00 +20 +cb +fb +b0 +0f +ad +10 +fd +29 +04 +d0 +f4 +20 +d8 +fb +0d +4f +4b +00 +18 +60 +78 +ad +06 +ff +29 +ef +8d +06 +ff +ad +0a +ff +29 +fd +09 +08 +8d +0a +ff +60 +78 +ad +06 +ff +09 +10 +8d +06 +ff +ad +0a +ff +29 +f7 +09 +02 +8d +0a +ff +58 +60 +08 +38 +6e +fc +07 +a5 +01 +29 +f5 +85 +01 +a2 +1e +20 +ea +e2 +ca +d0 +fa +28 +60 +43 +31 +39 +38 +34 +43 +4f +4d +4d +4f +44 +4f +52 +45 +a5 +01 +09 +08 +85 +01 +60 +a0 +00 +a9 +20 +91 +b6 +c8 +c0 +c0 +d0 +f9 +60 +48 +a9 +33 +85 +b6 +a9 +03 +85 +b7 +68 +60 +20 +cb +fb +90 +10 +20 +b0 +e3 +20 +78 +e3 +ae +be +07 +9a +a9 +00 +8d +be +07 +38 +60 +ad +09 +ff +2d +0a +ff +29 +08 +d0 +01 +60 +8d +09 +ff +78 +a9 +90 +8d +00 +ff +a9 +33 +8d +01 +ff +ae +bf +07 +9a +38 +60 +a9 +a8 +8d +00 +ff +a9 +48 +8d +01 +ff +a9 +08 +8d +09 +ff +60 +38 +b0 +01 +18 +8c +ca +07 +8e +cb +07 +ac +c8 +07 +ae +c9 +07 +a9 +10 +2c +09 +ff +f0 +fb +8c +02 +ff +8e +03 +ff +8d +09 +ff +a5 +01 +49 +02 +85 +01 +08 +20 +ce +e3 +28 +ac +ca +07 +ae +cb +07 +b0 +d0 +60 +a9 +4e +8d +c8 +07 +a9 +03 +8d +c9 +07 +60 +a9 +d0 +8d +c8 +07 +a9 +00 +8d +c9 +07 +60 +a9 +a4 +8d +c8 +07 +a9 +01 +8d +c9 +07 +60 +20 +52 +e4 +20 +13 +e4 +20 +5d +e4 +4c +13 +e4 +20 +5d +e4 +20 +13 +e4 +20 +52 +e4 +4c +13 +e4 +20 +47 +e4 +20 +13 +e4 +20 +5d +e4 +4c +13 +e4 +85 +a7 +a9 +01 +8d +b1 +07 +20 +80 +e4 +a2 +08 +66 +a7 +b0 +09 +ee +b1 +07 +20 +68 +e4 +4c +a8 +e4 +20 +74 +e4 +ca +d0 +ed +6e +b1 +07 +b0 +06 +20 +68 +e4 +4c +b9 +e4 +20 +74 +e4 +60 +ba +8e +be +07 +a5 +01 +09 +02 +85 +01 +20 +52 +e4 +a0 +01 +8c +03 +ff +a9 +10 +8d +09 +ff +24 +f7 +10 +04 +a0 +40 +a2 +fe +20 +13 +e4 +ca +d0 +fa +88 +d0 +f7 +a0 +09 +98 +05 +f7 +20 +8c +e4 +88 +d0 +f7 +a5 +f8 +85 +f5 +f0 +03 +20 +8c +e4 +a0 +00 +a9 +ba +8d +df +07 +20 +d9 +07 +48 +45 +f5 +85 +f5 +68 +20 +8c +e4 +e6 +ba +d0 +02 +e6 +bb +ee +f3 +03 +d0 +e2 +ee +f4 +03 +d0 +dd +a5 +f5 +20 +8c +e4 +20 +5d +e4 +20 +13 +e4 +20 +52 +e4 +a0 +01 +a2 +c2 +20 +13 +e4 +ca +d0 +fa +88 +d0 +f7 +60 +20 +19 +e3 +20 +64 +e3 +20 +8d +e3 +b0 +26 +a9 +80 +85 +f7 +a5 +b6 +85 +ba +a5 +b7 +85 +bb +a9 +41 +8d +f3 +03 +a9 +ff +8d +f4 +03 +20 +ba +e4 +b0 +0b +a5 +f7 +10 +06 +a9 +00 +85 +f7 +10 +df +18 +20 +b0 +e3 +4c +78 +e3 +20 +c3 +e3 +20 +b7 +e3 +a0 +00 +a5 +b2 +91 +b6 +c8 +a5 +b3 +91 +b6 +c8 +a5 +9d +91 +b6 +c8 +a5 +9e +91 +b6 +c8 +8c +b3 +07 +a0 +00 +8c +b2 +07 +ac +b2 +07 +c4 +ab +f0 +16 +a9 +af +8d +df +07 +20 +d9 +07 +ac +b3 +07 +91 +b6 +ee +b2 +07 +ee +b3 +07 +4c +90 +e5 +4c +35 +e5 +20 +19 +e3 +20 +64 +e3 +20 +8d +e3 +b0 +2f +a9 +80 +85 +f7 +a5 +b2 +85 +ba +a5 +b3 +85 +bb +18 +a5 +9d +e5 +b2 +49 +ff +8d +f3 +03 +a5 +9e +e5 +b3 +49 +ff +8d +f4 +03 +20 +ba +e4 +b0 +0b +a5 +f7 +10 +06 +a9 +00 +85 +f7 +10 +d6 +18 +20 +b0 +e3 +4c +78 +e3 +20 +b7 +e3 +a9 +05 +85 +f8 +4c +35 +e5 +40 +00 +80 +ae +b8 +07 +ac +b9 +07 +ad +bb +07 +48 +ad +ba +07 +48 +a9 +10 +24 +01 +f0 +fc +24 +01 +d0 +fc +8e +02 +ff +8c +03 +ff +68 +8d +04 +ff +68 +8d +05 +ff +a9 +50 +8d +09 +ff +a5 +01 +c5 +01 +d0 +fa +29 +10 +d0 +d1 +20 +ce +e3 +a9 +10 +24 +01 +d0 +47 +2c +09 +ff +f0 +f7 +a5 +01 +c5 +01 +d0 +fa +29 +10 +d0 +38 +a9 +40 +2c +09 +ff +f0 +fb +a5 +01 +c5 +01 +d0 +fa +29 +10 +d0 +2c +ad +bc +07 +8d +02 +ff +ad +bd +07 +8d +03 +ff +a9 +10 +8d +09 +ff +a9 +10 +2c +09 +ff +f0 +fb +a5 +01 +c5 +01 +d0 +fa +29 +10 +f0 +0f +2c +fc +e5 +30 +08 +2c +fa +e5 +70 +03 +2c +fb +e5 +18 +60 +38 +60 +40 +00 +80 +20 +fd +e5 +b0 +3d +70 +12 +10 +02 +30 +27 +20 +fd +e5 +b0 +32 +70 +02 +50 +2e +2c +8f +e6 +18 +60 +20 +fd +e5 +70 +04 +10 +0d +30 +20 +20 +fd +e5 +b0 +1b +70 +f9 +10 +17 +30 +05 +2c +8e +e6 +18 +60 +20 +fd +e5 +b0 +0b +70 +09 +10 +02 +30 +05 +2c +90 +e6 +18 +60 +38 +60 +ba +8e +bf +07 +18 +6e +cc +07 +58 +20 +91 +e6 +b0 +fb +70 +f9 +10 +f7 +20 +03 +e4 +18 +60 +2c +cc +07 +30 +51 +20 +d5 +e6 +b0 +4c +a9 +01 +8d +b1 +07 +a2 +08 +8e +b5 +07 +38 +6e +cc +07 +20 +91 +e6 +b0 +39 +70 +04 +10 +0f +30 +33 +18 +66 +a7 +ee +b1 +07 +ce +b5 +07 +d0 +ea +f0 +08 +38 +66 +a7 +ce +b5 +07 +d0 +e0 +20 +91 +e6 +b0 +19 +70 +04 +10 +0b +30 +13 +ad +b1 +07 +29 +01 +d0 +0c +f0 +07 +ad +b1 +07 +29 +01 +f0 +03 +18 +90 +01 +38 +78 +08 +18 +6e +cc +07 +28 +60 +ba +8e +be +07 +a5 +93 +f0 +03 +38 +66 +93 +20 +8d +e3 +20 +64 +e3 +ad +c0 +07 +85 +b6 +ad +c1 +07 +85 +b7 +ad +c2 +07 +8d +f5 +03 +ad +c3 +07 +8d +f6 +03 +20 +1d +e9 +a0 +00 +8c +b6 +07 +8c +b7 +07 +84 +f5 +84 +b1 +84 +f8 +a9 +b6 +8d +df +07 +2c +b0 +07 +10 +13 +20 +ec +e6 +b0 +0b +a5 +a7 +85 +f8 +45 +f5 +85 +f5 +4c +a0 +e7 +38 +66 +f8 +20 +ec +e6 +b0 +19 +a0 +00 +20 +d9 +07 +ea +24 +93 +30 +02 +a5 +a7 +c5 +a7 +d0 +09 +91 +b6 +45 +f5 +85 +f5 +4c +dc +e7 +ac +b6 +07 +c0 +1e +b0 +12 +a5 +b6 +99 +37 +04 +a5 +b7 +99 +55 +04 +ee +b6 +07 +e6 +b1 +4c +dc +e7 +a9 +ff +8d +b6 +07 +e6 +b6 +d0 +02 +e6 +b7 +ee +f5 +03 +d0 +b9 +ee +f6 +03 +d0 +b4 +ad +b6 +07 +8d +b7 +07 +20 +ec +e6 +ad +b7 +07 +d0 +06 +a5 +a7 +c5 +f5 +d0 +03 +4c +0a +e8 +a5 +f7 +30 +03 +4c +b7 +e8 +a5 +f7 +30 +0b +ad +b7 +07 +f0 +03 +4c +b7 +e8 +4c +c7 +e8 +a9 +00 +8d +b6 +07 +85 +f5 +ad +c0 +07 +85 +b6 +ad +c1 +07 +85 +b7 +ad +c2 +07 +8d +f5 +03 +ad +c3 +07 +8d +f6 +03 +20 +1d +e9 +2c +b0 +07 +10 +15 +20 +ec +e6 +24 +f8 +10 +08 +a5 +a7 +85 +f8 +90 +02 +66 +f8 +a5 +f8 +45 +f5 +85 +f5 +20 +ec +e6 +6e +c4 +07 +a5 +a7 +45 +f5 +85 +f5 +2c +b7 +07 +30 +32 +ac +b6 +07 +cc +b7 +07 +f0 +2a +b9 +37 +04 +c5 +b6 +d0 +23 +b9 +55 +04 +c5 +b7 +d0 +1c +ee +b6 +07 +ad +c4 +07 +30 +14 +a0 +00 +20 +d9 +07 +ea +24 +93 +30 +02 +a5 +a7 +c5 +a7 +d0 +04 +c6 +b1 +91 +b6 +e6 +b6 +d0 +02 +e6 +b7 +ee +f5 +03 +d0 +b2 +ee +f6 +03 +d0 +ad +20 +ec +e6 +a9 +00 +85 +90 +a5 +f8 +a6 +b1 +f0 +14 +24 +93 +30 +08 +a9 +60 +85 +90 +38 +4c +c8 +e8 +a9 +10 +85 +90 +38 +4c +c8 +e8 +18 +20 +b0 +e3 +20 +78 +e3 +60 +33 +03 +41 +ff +a0 +03 +b9 +cf +e8 +99 +c0 +07 +88 +10 +f7 +8c +b0 +07 +a5 +93 +48 +c8 +84 +93 +8c +39 +05 +20 +4b +e7 +68 +85 +93 +4c +c3 +e3 +a5 +b2 +8d +c0 +07 +a5 +b3 +8d +c1 +07 +18 +a5 +9d +e5 +b2 +49 +ff +8d +c2 +07 +a5 +9e +e5 +b3 +49 +ff +8d +c3 +07 +18 +6e +b0 +07 +4c +4b +e7 +02 +01 +02 +02 +0d +02 +a2 +05 +bd +17 +e9 +9d +b8 +07 +ca +10 +f7 +a9 +0a +8d +c5 +07 +20 +fd +e5 +b0 +f6 +50 +f4 +ce +c5 +07 +d0 +f4 +a9 +00 +85 +ba +85 +bb +a0 +10 +a2 +00 +a9 +10 +24 +01 +f0 +fc +24 +01 +d0 +fc +e8 +f0 +e9 +24 +01 +f0 +f9 +e8 +f0 +e2 +24 +01 +d0 +f9 +8a +18 +65 +ba +85 +ba +a9 +00 +65 +bb +85 +bb +88 +d0 +d7 +46 +bb +66 +ba +46 +bb +66 +ba +a5 +ba +8d +b8 +07 +0a +8d +ba +07 +8d +bc +07 +a5 +bb +8d +b9 +07 +2a +8d +bb +07 +8d +bd +07 +20 +fd +e5 +b0 +fb +70 +f9 +10 +f7 +20 +fd +e5 +b0 +f2 +70 +f0 +30 +ee +18 +6e +cc +07 +20 +03 +e4 +a9 +03 +8d +c6 +07 +20 +f6 +e6 +90 +03 +ce +c6 +07 +20 +ec +e6 +90 +08 +ce +c6 +07 +d0 +03 +4c +1d +e9 +a5 +a7 +29 +0f +c9 +01 +d0 +eb +a5 +a7 +29 +80 +85 +f7 +60 +20 +d3 +e8 +b0 +4d +a5 +f8 +c9 +05 +f0 +43 +c9 +01 +f0 +08 +c9 +03 +f0 +04 +c9 +04 +d0 +e9 +aa +24 +9a +10 +2f +20 +d8 +fb +0d +46 +4f +55 +4e +44 +20 +00 +a0 +04 +b1 +b6 +20 +d2 +ff +c8 +c0 +15 +d0 +f6 +a2 +ff +20 +ea +e2 +20 +ea +e2 +ca +f0 +0d +a9 +7f +20 +70 +db +c9 +7f +f0 +0b +c9 +df +d0 +ea +18 +a5 +f8 +60 +ea +ea +ea +a9 +00 +60 +20 +cc +e9 +b0 +2d +c9 +05 +f0 +2b +a0 +ff +c8 +c4 +ab +f0 +26 +a9 +af +8d +df +07 +20 +d9 +07 +d9 +37 +03 +f0 +ee +46 +f8 +90 +df +a0 +ff +8c +c3 +07 +88 +8c +c2 +07 +a0 +01 +20 +d5 +e8 +4c +21 +ea +a9 +00 +38 +60 +18 +a5 +f8 +60 +ad +d4 +07 +29 +10 +f0 +32 +ad +10 +fd +29 +02 +f0 +2b +a2 +00 +2c +d0 +07 +10 +09 +ad +cf +07 +8e +d0 +07 +4c +89 +ea +2c +ce +07 +10 +16 +2c +d6 +07 +30 +11 +ad +cd +07 +8e +ce +07 +8d +00 +fd +ad +d4 +07 +29 +ef +8d +d4 +07 +60 +ad +d4 +07 +29 +08 +f0 +54 +ad +d4 +07 +29 +f7 +8d +d4 +07 +ad +00 +fd +f0 +19 +8d +d5 +07 +c5 +fc +d0 +07 +a9 +00 +8d +d6 +07 +f0 +39 +c5 +fd +d0 +07 +a9 +ff +8d +d6 +07 +d0 +2e +ad +d3 +07 +c9 +3f +f0 +27 +c9 +38 +d0 +0f +a5 +fd +f0 +0b +8d +cf +07 +a9 +ff +8d +d0 +07 +8d +d7 +07 +ae +d1 +07 +e8 +8a +29 +3f +8d +d1 +07 +aa +ad +d5 +07 +9d +f7 +03 +ee +d3 +07 +60 +ad +d3 +07 +f0 +34 +08 +78 +ae +d2 +07 +e8 +8a +29 +3f +8d +d2 +07 +28 +aa +bd +f7 +03 +48 +ce +d3 +07 +ad +d3 +07 +c9 +08 +d0 +19 +2c +d7 +07 +10 +14 +a5 +fc +f0 +10 +8d +cf +07 +38 +6e +d0 +07 +4e +d7 +07 +2c +d8 +07 +10 +0b +48 +ad +d4 +07 +29 +4f +49 +40 +85 +90 +68 +18 +60 +2c +ce +07 +30 +fb +8d +cd +07 +38 +6e +ce +07 +4c +2a +eb +a9 +00 +a2 +0b +9d +cd +07 +ca +10 +fa +8d +01 +fd +85 +fc +85 +fd +60 +0d +49 +2f +4f +20 +45 +52 +52 +4f +52 +20 +a3 +0d +53 +45 +41 +52 +43 +48 +49 +4e +47 +a0 +46 +4f +52 +a0 +0d +50 +52 +45 +53 +53 +20 +50 +4c +41 +59 +20 +4f +4e +20 +54 +41 +50 +c5 +50 +52 +45 +53 +53 +20 +52 +45 +43 +4f +52 +44 +20 +26 +20 +50 +4c +41 +59 +20 +4f +4e +20 +54 +41 +50 +c5 +0d +4c +4f +41 +44 +49 +4e +c7 +0d +53 +41 +56 +49 +4e +47 +a0 +0d +56 +45 +52 +49 +46 +59 +49 +4e +c7 +0d +46 +4f +55 +4e +44 +a0 +0d +4f +4b +8d +24 +9a +10 +0d +b9 +58 +eb +08 +29 +7f +20 +d2 +ff +c8 +28 +10 +f3 +18 +60 +a5 +98 +d0 +1a +a5 +ef +0d +5d +05 +f0 +3e +78 +4c +c1 +d8 +a5 +98 +d0 +0b +a5 +ca +85 +c5 +a5 +cd +85 +c4 +4c +65 +d9 +c9 +03 +d0 +1f +05 +c7 +85 +c7 +ad +e8 +07 +85 +c3 +4c +65 +d9 +20 +ba +fb +c9 +01 +d0 +06 +20 +24 +ec +4c +c4 +fb +20 +f1 +ea +4c +c4 +fb +90 +eb +a5 +90 +f0 +6b +a9 +0d +18 +60 +ac +39 +05 +c0 +bf +90 +06 +20 +d3 +e8 +90 +f4 +60 +ac +39 +05 +b1 +b6 +48 +c8 +c0 +bf +b0 +09 +b1 +b6 +d0 +05 +a9 +40 +20 +1e +f4 +ee +39 +05 +68 +18 +60 +48 +a5 +99 +c9 +03 +d0 +04 +68 +4c +49 +dc +90 +04 +68 +4c +df +ec +20 +b7 +fb +c9 +01 +d0 +21 +ac +39 +05 +c0 +bf +90 +0b +20 +35 +e5 +b0 +0f +a9 +02 +85 +f8 +a0 +00 +68 +91 +b6 +c8 +8c +39 +05 +90 +0a +68 +a9 +00 +4c +c4 +fb +68 +20 +37 +eb +4c +c1 +fb +86 +ba +24 +f9 +70 +05 +a6 +ba +4c +52 +e2 +a5 +f9 +29 +30 +aa +a9 +84 +9d +c0 +fe +bd +c2 +fe +30 +fb +a9 +00 +9d +c3 +fe +9d +c2 +fe +bd +c2 +fe +10 +fb +bd +c1 +fe +29 +03 +c9 +03 +d0 +02 +a9 +40 +20 +1e +f4 +bd +c0 +fe +48 +a9 +40 +9d +c2 +fe +bd +c2 +fe +30 +fb +a9 +ff +9d +c3 +fe +a9 +00 +9d +c0 +fe +9d +c2 +fe +4c +d4 +ed +ea +24 +f9 +30 +03 +4c +1d +e2 +48 +8d +e8 +05 +a9 +83 +86 +ba +48 +a5 +f9 +29 +30 +aa +68 +9d +c0 +fe +bd +c2 +fe +30 +fb +ad +e8 +05 +9d +c0 +fe +a9 +00 +9d +c2 +fe +bd +c2 +fe +10 +fb +bd +c1 +fe +29 +03 +20 +1e +f4 +4c +db +ed +20 +e8 +ee +f0 +03 +4c +79 +f2 +20 +f8 +ee +f0 +11 +c9 +03 +f0 +0d +b0 +0f +c9 +02 +d0 +28 +20 +25 +eb +b0 +05 +a5 +ae +85 +98 +18 +60 +aa +20 +fa +ed +24 +90 +30 +12 +a5 +ad +10 +06 +20 +13 +ee +4c +4f +ed +20 +1a +ee +8a +24 +90 +10 +e2 +4c +7f +f2 +a6 +ad +e0 +60 +f0 +d9 +4c +82 +f2 +20 +e8 +ee +f0 +03 +4c +79 +f2 +20 +f8 +ee +d0 +03 +4c +85 +f2 +c9 +03 +f0 +0d +b0 +0f +c9 +02 +d0 +27 +20 +25 +eb +b0 +05 +a5 +ae +85 +99 +18 +60 +aa +20 +2c +ee +24 +90 +30 +11 +a5 +ad +10 +05 +20 +45 +ee +d0 +03 +20 +4d +ee +8a +24 +90 +10 +e3 +4c +7f +f2 +a6 +ad +e0 +60 +f0 +c6 +d0 +d8 +48 +86 +ba +a2 +30 +a5 +ae +c9 +08 +f0 +06 +c9 +09 +d0 +17 +a2 +00 +a9 +55 +9d +c0 +fe +5d +c0 +fe +d0 +0b +bd +c1 +fe +29 +02 +d0 +04 +86 +f9 +18 +24 +38 +a6 +ba +68 +60 +bd +c2 +fe +10 +fb +30 +05 +a9 +00 +9d +c0 +fe +a9 +40 +9d +c2 +fe +a6 +ba +68 +18 +60 +8d +f2 +fe +8d +c5 +fe +8d +c2 +fe +ca +8e +c3 +fe +4c +ea +cf +20 +a9 +ed +90 +03 +4c +53 +e1 +48 +a9 +40 +8d +e8 +05 +a5 +f9 +09 +40 +85 +f9 +a9 +81 +4c +ec +ec +24 +f9 +70 +35 +4c +0c +e2 +24 +f9 +70 +03 +4c +03 +e2 +48 +ea +ea +8d +e8 +05 +a9 +82 +4c +ec +ec +20 +a9 +ed +90 +03 +4c +56 +e1 +48 +a9 +20 +8d +e8 +05 +a5 +f9 +09 +80 +85 +f9 +a9 +81 +4c +ec +ec +24 +f9 +30 +03 +4c +fc +e1 +60 +24 +f9 +30 +03 +4c +f7 +e1 +48 +8d +e8 +05 +a9 +82 +4c +ec +ec +66 +ba +20 +ed +ee +f0 +02 +18 +60 +20 +f8 +ee +8a +48 +a5 +ae +f0 +5b +c9 +03 +f0 +57 +b0 +40 +c9 +02 +d0 +08 +08 +78 +20 +46 +eb +28 +f0 +49 +a5 +ad +29 +0f +f0 +43 +ac +39 +05 +c0 +bf +90 +0e +20 +35 +e5 +b0 +12 +a9 +02 +85 +f8 +a0 +00 +8c +39 +05 +a9 +00 +91 +b6 +20 +35 +e5 +90 +04 +68 +a9 +00 +60 +a5 +ad +c9 +62 +d0 +1b +20 +f0 +e5 +4c +ca +ee +24 +ba +10 +0e +a5 +ae +c9 +08 +90 +08 +a5 +ad +29 +0f +c9 +0f +f0 +03 +20 +11 +f2 +68 +aa +c6 +97 +e4 +97 +f0 +14 +a4 +97 +b9 +09 +05 +9d +09 +05 +b9 +13 +05 +9d +13 +05 +b9 +1d +05 +9d +1d +05 +18 +60 +a9 +00 +85 +90 +8a +a6 +97 +ca +30 +15 +dd +09 +05 +d0 +f8 +60 +bd +09 +05 +85 +ac +bd +1d +05 +85 +ad +bd +13 +05 +85 +ae +60 +a9 +00 +85 +97 +a2 +03 +e4 +99 +b0 +03 +20 +23 +ef +e4 +98 +b0 +03 +20 +3b +ef +86 +99 +a9 +00 +85 +98 +60 +24 +f9 +30 +03 +4c +3d +e2 +48 +a9 +3f +8d +e8 +05 +a5 +f9 +29 +7f +85 +f9 +a9 +81 +4c +ec +ec +24 +f9 +70 +03 +4c +2f +e2 +48 +a9 +5f +8d +e8 +05 +a5 +f9 +29 +bf +85 +f9 +a9 +81 +4c +ec +ec +a6 +ac +20 +e8 +ee +d0 +03 +4c +76 +f2 +a6 +97 +e0 +0a +90 +03 +4c +73 +f2 +e6 +97 +a5 +ac +9d +09 +05 +a5 +ad +09 +60 +85 +ad +9d +1d +05 +a5 +ae +9d +13 +05 +f0 +09 +c9 +03 +f0 +05 +90 +05 +20 +05 +f0 +18 +60 +c9 +02 +d0 +2c +20 +46 +eb +aa +e8 +f0 +0b +8e +03 +fd +ec +03 +fd +f0 +f5 +4c +7f +f2 +38 +6e +d8 +07 +a9 +af +8d +df +07 +a0 +00 +20 +d9 +07 +8d +03 +fd +c8 +20 +d9 +07 +8d +02 +fd +18 +60 +a5 +ad +29 +0f +d0 +2c +20 +1b +e3 +b0 +26 +20 +60 +f1 +a5 +ab +f0 +0a +20 +21 +ea +90 +10 +f0 +18 +4c +7c +f2 +20 +cc +e9 +f0 +10 +b0 +f6 +c9 +05 +f0 +f2 +a0 +bf +8c +39 +05 +a9 +02 +85 +f8 +18 +60 +20 +19 +e3 +b0 +fa +a9 +04 +85 +f8 +20 +6c +e5 +b0 +0c +a9 +02 +85 +f8 +a0 +00 +8c +39 +05 +8c +37 +05 +60 +a5 +ad +30 +df +a4 +ab +f0 +db +a9 +00 +85 +90 +a5 +ae +20 +2c +ee +24 +90 +30 +0b +a5 +ad +09 +f0 +20 +4d +ee +a5 +90 +10 +05 +68 +68 +4c +7f +f2 +a5 +ab +f0 +12 +a0 +00 +a9 +af +8d +df +07 +20 +d9 +07 +20 +df +ec +c8 +c4 +ab +d0 +f0 +4c +23 +f2 +86 +b4 +84 +b5 +6c +2e +03 +85 +93 +a9 +00 +85 +90 +a5 +ae +d0 +03 +4c +8b +f2 +c9 +03 +f0 +f9 +b0 +07 +c9 +02 +f0 +f3 +4c +f0 +f0 +a4 +ab +d0 +03 +4c +88 +f2 +a6 +ad +20 +60 +f1 +a9 +60 +85 +ad +20 +05 +f0 +a5 +ae +20 +fa +ed +a5 +ad +20 +1a +ee +20 +8b +ec +85 +9d +a5 +90 +4a +4a +b0 +5c +20 +8b +ec +85 +9e +8a +d0 +08 +a5 +b4 +85 +9d +a5 +b5 +85 +9e +20 +89 +f1 +a9 +fd +25 +90 +85 +90 +20 +e1 +ff +d0 +03 +4c +ff +f1 +20 +8b +ec +aa +a5 +90 +4a +4a +b0 +e8 +8a +a4 +93 +f0 +18 +a0 +00 +8d +c7 +07 +a9 +9d +8d +df +07 +20 +d9 +07 +cd +c7 +07 +f0 +08 +a9 +10 +20 +1e +f4 +2c +91 +9d +e6 +9d +d0 +02 +e6 +9e +24 +90 +50 +bf +20 +3b +ef +20 +11 +f2 +90 +03 +4c +7c +f2 +a6 +9d +a4 +9e +60 +20 +1b +e3 +b0 +fa +20 +60 +f1 +a5 +ab +f0 +09 +20 +21 +ea +90 +0b +f0 +ec +b0 +e3 +20 +cc +e9 +f0 +e5 +b0 +dc +a5 +f8 +c9 +01 +f0 +12 +c9 +03 +d0 +e2 +a0 +00 +b1 +b6 +85 +b4 +c8 +b1 +b6 +85 +b5 +4c +28 +f1 +a5 +ad +d0 +ee +38 +a0 +02 +b1 +b6 +a0 +00 +f1 +b6 +aa +a0 +03 +b1 +b6 +a0 +01 +f1 +b6 +a8 +18 +8a +65 +b4 +85 +9d +98 +65 +b5 +85 +9e +a5 +b4 +85 +b2 +a5 +b5 +85 +b3 +20 +89 +f1 +20 +f3 +e8 +90 +95 +a9 +1d +24 +93 +10 +93 +a9 +1c +d0 +8f +a5 +9a +10 +24 +a0 +0c +20 +ca +eb +a5 +ab +f0 +1b +a0 +17 +20 +ca +eb +a4 +ab +f0 +12 +a0 +00 +a9 +af +8d +df +07 +20 +d9 +07 +20 +d2 +ff +c8 +c4 +ab +d0 +f0 +60 +a0 +49 +a5 +93 +f0 +02 +a0 +59 +4c +c6 +eb +86 +9d +84 +9e +aa +b5 +00 +85 +b2 +b5 +01 +85 +b3 +6c +30 +03 +a5 +ae +d0 +03 +4c +8b +f2 +c9 +03 +f0 +f9 +c9 +02 +f0 +f5 +90 +7f +a9 +61 +85 +ad +a4 +ab +d0 +03 +4c +88 +f2 +20 +05 +f0 +20 +28 +f2 +a5 +ae +20 +2c +ee +a5 +ad +20 +4d +ee +a0 +00 +a5 +b3 +85 +9c +a5 +b2 +85 +9b +a5 +9b +20 +df +ec +a5 +9c +20 +df +ec +38 +a5 +9b +e5 +9d +a5 +9c +e5 +9e +b0 +1f +a9 +9b +8d +df +07 +20 +d9 +07 +20 +df +ec +20 +e1 +ff +d0 +07 +20 +11 +f2 +a9 +00 +38 +60 +e6 +9b +d0 +da +e6 +9c +d0 +d6 +20 +23 +ef +24 +ad +30 +11 +a5 +ae +20 +2c +ee +a5 +ad +29 +ef +09 +e0 +20 +4d +ee +20 +23 +ef +18 +60 +a5 +9a +10 +38 +a0 +51 +20 +ca +eb +4c +72 +f1 +20 +19 +e3 +b0 +29 +20 +28 +f2 +a2 +03 +a5 +ad +29 +01 +d0 +02 +a2 +01 +86 +f8 +20 +6c +e5 +b0 +15 +a9 +00 +85 +f8 +20 +b0 +e5 +b0 +0c +a5 +ad +29 +02 +f0 +05 +20 +f0 +e5 +b0 +01 +18 +a9 +00 +60 +a5 +91 +c9 +7f +d0 +07 +08 +20 +cc +ff +85 +ef +28 +60 +a9 +01 +2c +a9 +02 +2c +a9 +03 +2c +a9 +04 +2c +a9 +05 +2c +a9 +06 +2c +a9 +07 +2c +a9 +08 +2c +a9 +09 +48 +20 +cc +ff +a0 +00 +24 +9a +50 +0a +20 +ca +eb +68 +48 +09 +30 +20 +d2 +ff +68 +38 +60 +a2 +ff +78 +9a +d8 +20 +a6 +cf +20 +0b +f3 +20 +11 +cf +08 +30 +07 +a9 +a5 +cd +08 +05 +f0 +03 +20 +52 +f3 +20 +ce +f2 +20 +4e +d8 +28 +30 +03 +4c +45 +f4 +4c +00 +80 +a2 +eb +a0 +f2 +18 +86 +b8 +84 +b9 +a0 +1f +b9 +12 +03 +b0 +02 +b1 +b8 +99 +12 +03 +90 +02 +91 +b8 +88 +10 +ef +60 +42 +ce +0e +ce +4c +f4 +53 +ef +5d +ee +18 +ed +60 +ed +0c +ef +e8 +eb +4b +ec +65 +f2 +d9 +eb +08 +ef +4c +f4 +4a +f0 +a4 +f1 +a9 +0f +85 +00 +a9 +08 +85 +01 +a2 +ff +8e +10 +fd +8e +f3 +fe +e8 +8e +f4 +fe +8e +f0 +fe +a9 +40 +8d +f5 +fe +20 +ea +ed +bd +38 +f3 +9d +00 +ff +e8 +e0 +1a +d0 +f5 +4c +46 +eb +f1 +39 +00 +00 +00 +00 +1b +08 +00 +00 +02 +cc +00 +00 +00 +00 +00 +00 +04 +d0 +08 +71 +5b +75 +77 +6e +a9 +00 +a8 +99 +02 +00 +99 +00 +02 +99 +00 +03 +99 +00 +04 +99 +00 +07 +c8 +d0 +ee +a2 +08 +86 +9f +bd +f5 +ff +9d +f5 +ff +dd +f5 +3f +d0 +01 +c8 +dd +f5 +7f +d0 +02 +c6 +9f +ca +d0 +ea +c0 +08 +f0 +07 +a5 +9f +d0 +08 +a0 +7f +2c +a0 +3f +a2 +f6 +2c +a0 +fd +18 +20 +2f +f4 +a9 +10 +8d +32 +05 +a2 +3a +bd +d1 +f3 +9d +5e +05 +ca +d0 +f7 +8e +5d +05 +a2 +0b +bd +b3 +cf +9d +d9 +07 +ca +10 +f7 +a2 +0f +bd +43 +e1 +9d +13 +01 +ca +10 +f7 +a9 +a5 +8d +08 +05 +a9 +04 +8d +fa +07 +a9 +18 +8d +fb +07 +60 +ea +ea +07 +06 +0a +07 +06 +04 +05 +05 +47 +52 +41 +50 +48 +49 +43 +44 +4c +4f +41 +44 +22 +44 +49 +52 +45 +43 +54 +4f +52 +59 +0d +53 +43 +4e +43 +4c +52 +0d +44 +53 +41 +56 +45 +22 +52 +55 +4e +0d +4c +49 +53 +54 +0d +48 +45 +4c +50 +0d +85 +ab +86 +af +84 +b0 +60 +85 +ac +86 +ae +84 +ad +60 +85 +9a +a5 +90 +05 +90 +85 +90 +60 +8d +35 +05 +60 +90 +06 +ae +33 +05 +ac +34 +05 +8e +33 +05 +8c +34 +05 +60 +90 +06 +ae +31 +05 +ac +32 +05 +8e +31 +05 +8c +32 +05 +60 +a2 +00 +8e +54 +05 +f0 +0c +d8 +a2 +05 +68 +9d +52 +05 +ca +10 +f9 +a2 +09 +8e +f4 +07 +a9 +c0 +85 +9a +ba +8e +58 +05 +ae +f4 +07 +20 +66 +cf +ad +06 +ff +09 +10 +8d +06 +ff +a9 +00 +85 +a1 +85 +a2 +58 +a2 +0f +20 +66 +cf +ad +52 +05 +20 +10 +fb +a0 +00 +b9 +53 +05 +20 +05 +fb +c8 +c0 +06 +90 +f5 +b0 +03 +20 +0b +fb +20 +3a +fb +a2 +00 +86 +f3 +20 +cf +ff +9d +00 +02 +e8 +c9 +0d +d0 +f5 +ca +86 +f4 +20 +3f +fb +f0 +e6 +c9 +20 +f0 +f7 +a2 +0f +dd +70 +f5 +f0 +05 +ca +10 +f8 +30 +d3 +e0 +0d +b0 +0e +8a +0a +aa +bd +81 +f5 +48 +bd +80 +f5 +48 +4c +ad +fa +8d +5b +05 +4c +6e +f6 +b0 +08 +20 +5b +fb +20 +ad +fa +90 +06 +a9 +0b +85 +f1 +d0 +0e +20 +64 +fb +4a +66 +f1 +4a +66 +f1 +4a +66 +f1 +85 +f2 +20 +e1 +ff +f0 +0d +20 +9a +f5 +a9 +08 +20 +96 +fb +20 +72 +fb +b0 +ee +4c +95 +f4 +b0 +fb +a5 +f1 +a4 +f2 +8d +53 +05 +8c +52 +05 +a0 +00 +20 +ad +fa +b0 +ea +a5 +f1 +99 +54 +05 +c8 +c0 +05 +90 +f1 +b0 +de +b0 +13 +20 +5b +fb +a0 +00 +20 +ad +fa +b0 +09 +a5 +f1 +91 +a1 +c8 +c0 +08 +90 +f2 +20 +d8 +fb +1b +4f +91 +00 +20 +9a +f5 +4c +95 +f4 +b0 +0a +a5 +f1 +8d +53 +05 +a5 +f2 +8d +52 +05 +ae +58 +05 +9a +a2 +00 +bd +52 +05 +48 +e8 +e0 +03 +d0 +f7 +ae +56 +05 +ac +57 +05 +ad +55 +05 +40 +58 +4d +52 +47 +54 +43 +44 +41 +2e +48 +46 +3e +3b +4c +53 +56 +02 +80 +d6 +f4 +77 +f4 +4a +f5 +d0 +f5 +cd +f5 +23 +f7 +1e +f9 +1e +f9 +0d +f6 +09 +f7 +28 +f5 +09 +f5 +20 +3a +fb +a9 +3e +20 +d2 +ff +20 +fb +fa +a0 +00 +20 +96 +cf +20 +05 +fb +c8 +c0 +08 +90 +f5 +20 +d8 +fb +3a +12 +00 +a0 +00 +20 +96 +cf +29 +7f +c9 +20 +b0 +02 +a9 +2e +20 +d2 +ff +c8 +c0 +08 +90 +ed +60 +a9 +00 +2c +a9 +80 +85 +bb +20 +a0 +fb +b0 +30 +20 +ad +fa +b0 +2b +20 +3a +fb +a0 +00 +20 +96 +cf +24 +bb +10 +02 +91 +f1 +d1 +f1 +f0 +08 +20 +e1 +ff +f0 +11 +20 +fb +fa +e6 +f1 +d0 +02 +e6 +f2 +20 +94 +fb +20 +86 +fb +b0 +dd +4c +95 +f4 +4c +92 +f4 +ea +20 +a0 +fb +b0 +f7 +a0 +00 +20 +3f +fb +c9 +27 +d0 +12 +20 +3f +fb +99 +5d +02 +c8 +20 +3f +fb +f0 +1b +c0 +20 +d0 +f3 +f0 +15 +8c +5c +05 +20 +ab +fa +a5 +f1 +99 +5d +02 +c8 +20 +ad +fa +b0 +04 +c0 +20 +d0 +f1 +8c +5b +05 +20 +3a +fb +a2 +00 +a0 +00 +20 +96 +cf +dd +5d +02 +d0 +0f +c8 +e8 +ec +5b +05 +d0 +f1 +20 +e1 +ff +f0 +a6 +20 +fb +fa +20 +94 +fb +20 +86 +fb +b0 +dd +90 +99 +a0 +01 +84 +ae +84 +ad +88 +84 +ab +84 +90 +84 +93 +a9 +02 +85 +b0 +a9 +5d +85 +af +20 +3f +fb +f0 +5e +c9 +20 +f0 +f7 +c9 +22 +d0 +17 +a6 +f3 +e4 +f4 +b0 +50 +bd +00 +02 +e8 +c9 +22 +f0 +0d +91 +af +e6 +ab +c8 +c0 +11 +90 +eb +4c +92 +f4 +ea +86 +f3 +20 +3f +fb +20 +ad +fa +b0 +31 +a5 +f1 +f0 +ee +c9 +03 +f0 +ea +85 +ae +20 +ad +fa +b0 +22 +20 +5b +fb +20 +ad +fa +b0 +db +20 +3a +fb +a6 +f1 +a4 +f2 +ad +5b +05 +c9 +53 +d0 +cd +a9 +00 +85 +ad +a9 +a1 +20 +d8 +ff +4c +95 +f4 +ad +5b +05 +c9 +56 +f0 +06 +c9 +4c +d0 +b6 +a9 +00 +20 +d5 +ff +a5 +90 +29 +10 +f0 +e7 +ad +5b +05 +c9 +4c +f0 +a4 +a2 +2a +20 +66 +cf +30 +d9 +20 +a0 +fb +b0 +98 +20 +ad +fa +b0 +93 +a0 +00 +a5 +f1 +91 +a1 +20 +94 +fb +20 +86 +fb +b0 +f4 +90 +bf +b0 +08 +20 +5b +fb +20 +ad +fa +90 +06 +a9 +14 +85 +f1 +d0 +03 +20 +64 +fb +20 +3a +fb +20 +e1 +ff +f0 +a4 +20 +52 +f7 +e6 +f6 +a5 +f6 +20 +96 +fb +a5 +f6 +20 +74 +fb +b0 +e7 +90 +91 +a9 +2e +20 +d2 +ff +20 +08 +fb +20 +fb +fa +20 +08 +fb +a0 +00 +20 +96 +cf +20 +d4 +f7 +48 +a6 +f6 +e8 +ca +10 +0b +20 +d8 +fb +20 +20 +20 +00 +4c +80 +f7 +ea +20 +96 +cf +20 +05 +fb +c8 +c0 +03 +90 +e7 +68 +a2 +03 +20 +1b +f8 +a2 +06 +e0 +03 +d0 +14 +a4 +f6 +f0 +10 +ad +4b +05 +c9 +e8 +20 +96 +cf +b0 +1d +20 +10 +fb +88 +d0 +f0 +0e +4b +05 +90 +0e +bd +8e +f8 +20 +d2 +ff +bd +94 +f8 +f0 +03 +20 +d2 +ff +ca +d0 +d2 +60 +20 +c8 +f7 +18 +69 +01 +d0 +01 +e8 +4c +ff +fa +a6 +a2 +a8 +10 +01 +ca +65 +a1 +90 +01 +e8 +60 +a8 +4a +90 +0b +4a +b0 +17 +c9 +22 +f0 +13 +29 +07 +09 +80 +4a +aa +bd +3d +f8 +b0 +04 +4a +4a +4a +4a +29 +0f +d0 +04 +a0 +80 +a9 +00 +aa +bd +81 +f8 +8d +4b +05 +29 +03 +85 +f6 +98 +29 +8f +aa +98 +a0 +03 +e0 +8a +f0 +0b +4a +90 +08 +4a +4a +09 +20 +88 +d0 +fa +c8 +88 +d0 +f2 +60 +a8 +b9 +9b +f8 +85 +9f +b9 +db +f8 +85 +a0 +a9 +00 +a0 +05 +06 +a0 +26 +9f +2a +88 +d0 +f8 +69 +3f +20 +d2 +ff +ca +d0 +ec +4c +08 +fb +40 +02 +45 +03 +d0 +08 +40 +09 +30 +22 +45 +33 +d0 +08 +40 +09 +40 +02 +45 +33 +d0 +08 +40 +09 +40 +02 +45 +b3 +d0 +08 +40 +09 +00 +22 +44 +33 +d0 +8c +44 +00 +11 +22 +44 +33 +d0 +8c +44 +9a +10 +22 +44 +33 +d0 +08 +40 +09 +10 +22 +44 +33 +d0 +08 +40 +09 +62 +13 +78 +a9 +00 +21 +81 +82 +00 +00 +59 +4d +91 +92 +86 +4a +85 +9d +2c +29 +2c +23 +28 +24 +59 +00 +58 +24 +24 +00 +1c +8a +1c +23 +5d +8b +1b +a1 +9d +8a +1d +23 +9d +8b +1d +a1 +00 +29 +19 +ae +69 +a8 +19 +23 +24 +53 +1b +23 +24 +53 +19 +a1 +00 +1a +5b +5b +a5 +69 +24 +24 +ae +ae +a8 +ad +29 +00 +7c +00 +15 +9c +6d +9c +a5 +69 +29 +53 +84 +13 +34 +11 +a5 +69 +23 +a0 +d8 +62 +5a +48 +26 +62 +94 +88 +54 +44 +c8 +54 +68 +44 +e8 +94 +00 +b4 +08 +84 +74 +b4 +28 +6e +74 +f4 +cc +4a +72 +f2 +a4 +8a +00 +aa +a2 +a2 +74 +74 +74 +72 +44 +68 +b2 +32 +b2 +00 +22 +00 +1a +1a +26 +26 +72 +72 +88 +c8 +c4 +ca +26 +48 +44 +44 +a2 +c8 +0d +20 +20 +20 +90 +03 +4c +92 +f4 +20 +5b +fb +a2 +00 +86 +78 +20 +3f +fb +d0 +07 +e0 +00 +d0 +03 +4c +95 +f4 +c9 +20 +f0 +ec +9d +4c +05 +e8 +e0 +03 +d0 +e8 +ca +30 +12 +bd +4c +05 +38 +e9 +3f +a0 +05 +4a +66 +78 +66 +77 +88 +d0 +f8 +f0 +eb +a2 +02 +20 +3f +fb +f0 +1e +c9 +20 +f0 +f7 +20 +7d +fa +b0 +0e +20 +8b +fa +a4 +f1 +84 +f2 +85 +f1 +a9 +30 +95 +77 +e8 +95 +77 +e8 +e0 +0a +90 +dd +86 +9f +a2 +00 +8e +4f +05 +a2 +00 +8e +50 +05 +ad +4f +05 +20 +d4 +f7 +ae +4b +05 +86 +a0 +aa +bd +db +f8 +20 +5e +fa +bd +9b +f8 +20 +5e +fa +a2 +06 +e0 +03 +d0 +13 +a4 +f6 +f0 +0f +ad +4b +05 +c9 +e8 +a9 +30 +b0 +1e +20 +5b +fa +88 +d0 +f1 +0e +4b +05 +90 +0e +bd +8e +f8 +20 +5e +fa +bd +94 +f8 +f0 +03 +20 +5e +fa +ca +d0 +d3 +f0 +06 +20 +5b +fa +20 +5b +fa +a5 +9f +cd +50 +05 +f0 +03 +4c +6a +fa +a4 +f6 +f0 +34 +a5 +a0 +c9 +9d +d0 +26 +a5 +f1 +e5 +a1 +8d +51 +05 +a5 +f2 +e5 +a2 +90 +09 +d0 +77 +ae +51 +05 +30 +72 +10 +09 +a8 +c8 +d0 +6c +ae +51 +05 +10 +67 +ca +ca +8a +a4 +f6 +d0 +03 +b9 +f0 +00 +91 +a1 +88 +d0 +f8 +ad +4f +05 +91 +a1 +20 +35 +fb +a2 +28 +20 +66 +cf +20 +5a +f7 +e6 +f6 +a5 +f6 +20 +96 +fb +a9 +41 +8d +27 +05 +a9 +20 +8d +28 +05 +8d +2d +05 +a5 +a2 +20 +20 +fb +8d +29 +05 +8e +2a +05 +a5 +a1 +20 +20 +fb +8d +2b +05 +8e +2c +05 +a9 +07 +85 +ef +4c +95 +f4 +20 +5e +fa +8e +f3 +07 +ae +50 +05 +d5 +77 +f0 +0d +68 +68 +ee +4f +05 +f0 +03 +4c +84 +f9 +4c +92 +f4 +e8 +8e +50 +05 +ae +f3 +07 +60 +c9 +41 +90 +03 +c9 +47 +60 +c9 +30 +90 +16 +c9 +3a +60 +20 +a0 +fa +0a +0a +0a +0a +8d +5c +05 +20 +3f +fb +20 +a0 +fa +0d +5c +05 +38 +60 +c9 +3a +08 +29 +0f +28 +90 +02 +69 +08 +60 +c6 +f3 +a9 +00 +85 +f1 +85 +f2 +8d +f4 +07 +20 +3f +fb +f0 +3a +c9 +20 +f0 +f7 +c9 +20 +f0 +2e +c9 +2c +f0 +2a +c9 +30 +90 +2b +c9 +47 +b0 +27 +c9 +3a +90 +06 +c9 +41 +90 +1f +e9 +08 +e9 +2f +0a +0a +0a +0a +a2 +04 +0a +26 +f1 +26 +f2 +ca +d0 +f8 +ee +f4 +07 +20 +3f +fb +d0 +ce +ad +f4 +07 +18 +60 +68 +68 +4c +92 +f4 +a5 +a1 +a6 +a2 +48 +8a +20 +10 +fb +68 +20 +10 +fb +a9 +20 +2c +a9 +3f +4c +d2 +ff +8e +f3 +07 +20 +20 +fb +20 +d2 +ff +8a +ae +f3 +07 +4c +d2 +ff +48 +20 +2a +fb +aa +68 +4a +4a +4a +4a +29 +0f +c9 +0a +90 +02 +69 +06 +69 +30 +60 +a9 +91 +20 +d2 +ff +a9 +0d +4c +d2 +ff +8e +f3 +07 +a6 +f3 +e4 +f4 +b0 +0f +bd +00 +02 +c9 +3a +f0 +08 +e6 +f3 +08 +ae +f3 +07 +28 +60 +a9 +00 +f0 +f6 +a5 +f1 +85 +a1 +a5 +f2 +85 +a2 +60 +38 +a5 +f1 +e5 +a1 +85 +f1 +a5 +f2 +e5 +a2 +85 +f2 +60 +a9 +01 +8d +f3 +07 +38 +a5 +f1 +ed +f3 +07 +85 +f1 +a5 +f2 +e9 +00 +85 +f2 +60 +38 +a5 +9f +e9 +01 +85 +9f +a5 +a0 +e9 +00 +85 +a0 +60 +a9 +01 +18 +65 +a1 +85 +a1 +90 +02 +e6 +a2 +60 +b0 +14 +20 +5b +fb +20 +ad +fa +b0 +0c +20 +64 +fb +a5 +f1 +85 +9f +a5 +f2 +85 +a0 +18 +60 +8d +10 +01 +8e +12 +01 +8c +11 +01 +60 +ad +10 +01 +ae +12 +01 +ac +11 +01 +60 +86 +fa +20 +11 +cf +a6 +fa +49 +80 +0a +a9 +00 +60 +48 +98 +48 +8a +48 +ba +e8 +e8 +e8 +e8 +bd +00 +01 +85 +bc +e8 +bd +00 +01 +85 +bd +e6 +bc +d0 +02 +e6 +bd +a0 +00 +b1 +bc +f0 +06 +20 +d2 +ff +c8 +d0 +f6 +98 +ba +e8 +e8 +e8 +e8 +18 +65 +bc +9d +00 +01 +a9 +00 +65 +bd +e8 +9d +00 +01 +68 +aa +68 +a8 +68 +60 +a2 +00 +a0 +fd +60 +a2 +03 +86 +96 +a9 +00 +9d +ec +05 +ca +10 +fa +a6 +96 +bd +7b +fc +aa +9d +d0 +fd +a0 +02 +b9 +07 +80 +d9 +56 +fc +d0 +14 +88 +10 +f5 +ad +06 +80 +a6 +96 +9d +ec +05 +c9 +01 +d0 +05 +86 +fb +20 +00 +80 +c6 +96 +10 +d5 +60 +43 +42 +4d +78 +a2 +03 +bd +ec +05 +f0 +10 +8a +48 +bd +7b +fc +aa +9d +d0 +fd +86 +fb +20 +00 +80 +68 +aa +ca +d0 +e8 +8d +d0 +fd +86 +fb +58 +60 +00 +05 +0a +0f +9d +d0 +fd +aa +b1 +be +9d +d0 +fd +60 +48 +86 +fb +9d +d0 +fd +ae +f3 +05 +ad +f4 +05 +48 +ad +f2 +05 +28 +20 +b0 +fc +8d +f2 +05 +08 +68 +8d +f4 +05 +8e +f3 +05 +68 +85 +fb +aa +9d +d0 +fd +60 +6c +f0 +05 +48 +8a +48 +98 +48 +8d +d0 +fd +4c +00 +ce +a6 +fb +9d +d0 +fd +68 +a8 +68 +aa +68 +40 +a6 +fb +9d +d0 +fd +6c +fe +02 +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +4c +c9 +fc +4c +59 +fc +4c +7f +fc +4c +89 +fc +4c +b8 +fc +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ff +ff +ff +ff +ff +ff +ff +ff +ff +4c +c2 +b7 +4c +49 +dc +4c +d8 +fb +4c +45 +f4 +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +ff +5e +85 +4c +4e +d8 +4c +0b +f3 +4c +52 +f3 +4c +ce +f2 +4c +d3 +f2 +4c +1a +f4 +4c +4d +ee +4c +1a +ee +4c +27 +f4 +4c +36 +f4 +4c +11 +db +4c +23 +f4 +4c +8b +ec +4c +df +ec +4c +3b +ef +4c +23 +ef +4c +2c +ee +4c +fa +ed +4c +1c +f4 +4c +13 +f4 +4c +0c +f4 +6c +18 +03 +6c +1a +03 +6c +1c +03 +6c +1e +03 +6c +20 +03 +6c +22 +03 +6c +24 +03 +4c +43 +f0 +4c +94 +f1 +4c +2d +cf +4c +26 +cf +6c +26 +03 +6c +28 +03 +6c +2a +03 +4c +f0 +ce +4c +34 +d8 +4c +39 +d8 +4c +19 +fc +8d +3e +ff +4c +a4 +f2 +f6 +ff +b3 +fc diff --git a/cores/c16/kernal_rom.v b/cores/c16/kernal_rom.v new file mode 100644 index 0000000..7131858 --- /dev/null +++ b/cores/c16/kernal_rom.v @@ -0,0 +1,78 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Copyright 2013-2016 Istvan Hegedus +// +// FPGATED is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// FPGATED is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Create Date: 17:12:57 12/05/2014 +// Design Name: Commodore 16/Plus 4 Kernal ROM +// Module Name: kernal_rom +// Project Name: FPGATED +// Description: +// Kernal ROM synthetised to FPGA's internal SRAM. Xilinx ISE requires +// ROM_STYLE="BLOCK" parameter next to kernal array. For other vendor's +// device syntax refer to the FPGA vendor's documentation. +// +// Choose the proper Kernal file version depending on NTSC or PAL system +// and comment out the ones which are not needed. +// If you want to convert your own kernal image to compatible version use +// bin2hex.pl perl script to convert it to .hex format. +////////////////////////////////////////////////////////////////////////////////// +module kernal_rom( + input wire clk, + input wire [13:0] address_in, + output wire [7:0] data_out, + input wire [7:0] data_in, + input wire wr, + input wire cs + ); + +(* ROM_STYLE="BLOCK" *) +reg [7:0] kernal [0:16383]; +reg [7:0] data; +reg cs_prev=1'b1; +wire enable; + +initial begin +// uncomment the Kernal version to use + +//$readmemh("Diag264_PAL.hex",kernal); + +//$readmemh("Diag264_NTSC.hex",kernal); + +$readmemh("kernal_PAL.hex",kernal); + +//$readmemh("kernal_NTSC.hex",kernal); + +//$readmemh("Jiffy_PAL.hex",kernal); +// Note that Jiffy DOS is not free so Jiffy_PAL.hex is not included with FPGATED source code + +end + +always@(posedge clk) begin + if (wr) + kernal[address_in] <= data_in; + + if(enable) + data<=kernal[address_in]; +end + +always@(posedge clk) + cs_prev<=cs; + +assign enable=~cs&cs_prev; // cs falling edge detection +assign data_out=(~cs)?data:8'hff; + + +endmodule diff --git a/cores/c16/mos6529.v b/cores/c16/mos6529.v new file mode 100644 index 0000000..40354e0 --- /dev/null +++ b/cores/c16/mos6529.v @@ -0,0 +1,54 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Copyright 2013-2016 Istvan Hegedus +// +// FPGATED is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// FPGATED is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Create Date: 09:08:17 12/17/2015 +// Design Name: FPGATED +// Module Name: mos6529.v +// Description: MOS 6529 IC emulation. +// +// Revision: +// 0.1 first release +// 1.0 chip read bug fixed 5/04/2016 +// +// Additional Comments: +// CS signal is high active while in real IC it is low active. +////////////////////////////////////////////////////////////////////////////////// + +module mos6529( + input clk, + input [7:0] data_in, + output wire [7:0] data_out, + input [7:0] port_in, + output wire [7:0] port_out, + input rw, + input cs + ); + +reg [7:0] iodata=0; + +assign port_out=iodata; +assign data_out=(cs & rw)?iodata:8'hff; + +always @(posedge clk) + begin + if(cs) + if(rw) + iodata<=port_in; + else + iodata<=data_in; + end +endmodule diff --git a/cores/c16/mos8501.v b/cores/c16/mos8501.v new file mode 100644 index 0000000..e6f7a8c --- /dev/null +++ b/cores/c16/mos8501.v @@ -0,0 +1,188 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Copyright 2013-2016 Istvan Hegedus +// +// FPGATED is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// FPGATED is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Create Date: 16:36:31 12/10/2014 +// Module Name: mos8501 +// Project Name: FPGATED +// Target Devices: Xilinx Spartan 3E +// +// Description: +// +// Dependencies: +// This module contains an instance of Peter Wendrich's 6502 CPU core from FPGA64 project. +// The CPU core is used and included with Peter's permission and not developed by me. +// The mos8501 shell around the CPU core is written by me, but inspired by fpga64 6510 CPU +// shell. It might shows certain similarities. +// +// Revision history: +// 0.1 first release using incorrect 6502 core from fpga64 project +// 1.0 CPU core replaced to cpu65xx_fast.vhd from fpga64 project +// +////////////////////////////////////////////////////////////////////////////////// +module mos8501( + input clk, + input reset, + input enable, + input irq_n, + input [7:0] data_in, + output wire [7:0] data_out, + output [15:0] address, + input gate_in, + output rw, + input [7:0] port_in, + output [7:0] port_out, + input rdy, + input aec + ); + +wire we,enable_cpu; +wire [15:0] core_address; +wire [7:0] core_data_out; +wire port_access; +reg [7:0] data_out_reg,core_data_in,port_io; +reg [7:0] port_dir=8'b0; +reg [7:0] port_data=8'b0; +reg rw_reg,aec_reg; + +// 6502 CPU core + + cpu65xx #(.pipelineOpcode("\false"),.pipelineAluMux("\false"),.pipelineAluOut("\false")) + cpu_core( + .clk(clk), + .reset(reset), + .enable(enable_cpu), + .nmi_n(1'b1), + .irq_n(irq_n), + .di(core_data_in), + .do(core_data_out), + .addr(core_address), + .we(we), + .so_n(1'b1), + .debugOpcode(), + .debugPc(), + .debugA(), + .debugX(), + .debugY(), + .debugS() + ); + +assign address=(aec)?core_address:16'hffff; // address tri state emulated for easy bus signal combining + +always @(posedge clk) + begin + if(gate_in) + begin + if(port_access==1'b1 && we==1'b1) + if(address[0]==1'b0) // when port direction register is written, data on bus is last read byte which is 0x00 + data_out_reg<=8'h00; + else // when port register is written, data on bus is last read byte which is 0x01 + data_out_reg<=8'h01; + else + data_out_reg<=core_data_out; // when mux is high, data out register is updated + end + else + begin + data_out_reg<=data_out_reg; // hold off data out during write cycle + end + end + +always @(posedge clk) + begin + if(gate_in) + rw_reg<=~we; + end + +always @(posedge clk) // registering aec for 1 clk cycle delay + begin + aec_reg<=aec; + end + +assign rw=(~aec_reg)?1'b1:rw_reg; + +assign data_out=(~aec_reg | gate_in | rw)?8'hff:data_out_reg; // when mux is low data out register is allowed to outside +assign port_access=(address[15:1]==0)?1'b1:1'b0; + +// IO port part of cpu + +always @(posedge clk) //writing port registers + begin + if(reset) + begin + port_dir<=0; + port_data<=0; + end + else if (enable) + if(port_access & we) + if(address[0]==0) + port_dir<=core_data_out; + else + port_data<=core_data_out; + end + +always @* // reading port registers + begin + core_data_in=data_in; + if (port_access & ~we) + if(address[0]==0) + core_data_in=port_dir; + else + core_data_in=port_io; + end + +// if direction bit is 0 then data is from chip's port +// if direction bit is 1 then data is from data port register filled earlier by CPU + +always @* + begin + if(port_dir[0]==1'b0) + port_io[0]=port_in[0]; + else + port_io[0]=port_data[0]; + if(port_dir[1]==1'b0) + port_io[1]=port_in[1]; + else + port_io[1]=port_data[1]; + if(port_dir[2]==1'b0) + port_io[2]=port_in[2]; + else + port_io[2]=port_data[2]; + if(port_dir[3]==1'b0) + port_io[3]=port_in[3]; + else + port_io[3]=port_data[3]; + if(port_dir[4]==1'b0) + port_io[4]=port_in[4]; + else + port_io[4]=port_data[4]; + if(port_dir[5]==1'b0) + port_io[5]=port_in[5]; + else + port_io[5]=port_data[5]; + if(port_dir[6]==1'b0) + port_io[6]=port_in[6]; + else + port_io[6]=port_data[6]; + if(port_dir[7]==1'b0) + port_io[7]=port_in[7]; + else + port_io[7]=port_data[7]; + end + +assign port_out=port_data; +assign enable_cpu=(~rdy & ~we)?1'b0:enable; // When RDY is low and cpu would do a read, halt cpu + +endmodule diff --git a/cores/c16/osd.v b/cores/c16/osd.v new file mode 100644 index 0000000..3c5ba47 --- /dev/null +++ b/cores/c16/osd.v @@ -0,0 +1,204 @@ +// +// osd.v +// +// A simple OSD implementation. Can be hooked up between a cores +// VGA output and the physical VGA pins +// +// Sinclair QL for the MiST +// https://github.com/mist-devel +// +// Copyright (c) 2015 Till Harbaum +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +module osd ( + // OSDs pixel clock, should be synchronous to cores pixel clock to + // avoid jitter. + input pclk, + + // SPI interface + input sck, + input ss, + input sdi, + + // VGA signals coming from core + input [5:0] red_in, + input [5:0] green_in, + input [5:0] blue_in, + input hs_in, + input vs_in, + + // VGA signals going to video connector + output [5:0] red_out, + output [5:0] green_out, + output [5:0] blue_out, + output hs_out, + output vs_out +); + +parameter OSD_X_OFFSET = 10'd0; +parameter OSD_Y_OFFSET = 10'd0; +parameter OSD_COLOR = 3'd0; + +localparam OSD_WIDTH = 10'd256; +localparam OSD_HEIGHT = 10'd128; + +// ********************************************************************************* +// spi client +// ********************************************************************************* + +// this core supports only the display related OSD commands +// of the minimig +reg [7:0] sbuf; +reg [7:0] cmd; +reg [4:0] cnt; +reg [10:0] bcnt; +reg osd_enable; + +reg [7:0] osd_buffer [2047:0]; // the OSD buffer itself + +// the OSD has its own SPI interface to the io controller +always@(posedge sck, posedge ss) begin + if(ss == 1'b1) begin + cnt <= 5'd0; + bcnt <= 11'd0; + end else begin + sbuf <= { sbuf[6:0], sdi}; + + // 0:7 is command, rest payload + if(cnt < 15) + cnt <= cnt + 4'd1; + else + cnt <= 4'd8; + + if(cnt == 7) begin + cmd <= {sbuf[6:0], sdi}; + + // lower three command bits are line address + bcnt <= { sbuf[1:0], sdi, 8'h00}; + + // command 0x40: OSDCMDENABLE, OSDCMDDISABLE + if(sbuf[6:3] == 4'b0100) + osd_enable <= sdi; + end + + // command 0x20: OSDCMDWRITE + if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin + osd_buffer[bcnt] <= {sbuf[6:0], sdi}; + bcnt <= bcnt + 11'd1; + end + end +end + +// ********************************************************************************* +// video timing and sync polarity anaylsis +// ********************************************************************************* + +// horizontal counter +reg [9:0] h_cnt; +reg hsD, hsD2; +reg [9:0] hs_low, hs_high; +wire hs_pol = hs_high < hs_low; +wire [9:0] h_dsp_width = hs_pol?hs_low:hs_high; +wire [9:0] h_dsp_ctr = { 1'b0, h_dsp_width[9:1] }; + +always @(posedge pclk) begin + // bring hsync into local clock domain + hsD <= hs_in; + hsD2 <= hsD; + + // falling edge of hs_in + if(!hsD && hsD2) begin + h_cnt <= 10'd0; + hs_high <= h_cnt; + end + + // rising edge of hs_in + else if(hsD && !hsD2) begin + h_cnt <= 10'd0; + hs_low <= h_cnt; + end + + else + h_cnt <= h_cnt + 10'd1; +end + +// vertical counter +reg [9:0] v_cnt; +reg vsD, vsD2; +reg [9:0] vs_low, vs_high; +wire vs_pol = vs_high < vs_low; +wire [9:0] v_dsp_width = vs_pol?vs_low:vs_high; +wire [9:0] v_dsp_ctr = { 1'b0, v_dsp_width[9:1] }; + +always @(posedge hs_in) begin + // bring vsync into local clock domain + vsD <= vs_in; + vsD2 <= vsD; + + // falling edge of vs_in + if(!vsD && vsD2) begin + v_cnt <= 10'd0; + vs_high <= v_cnt; + end + + // rising edge of vs_in + else if(vsD && !vsD2) begin + v_cnt <= 10'd0; + vs_low <= v_cnt; + end + + else + v_cnt <= v_cnt + 10'd1; +end + +// area in which OSD is being displayed +wire [9:0] h_osd_start = h_dsp_ctr + OSD_X_OFFSET - (OSD_WIDTH >> 1); +wire [9:0] h_osd_end = h_dsp_ctr + OSD_X_OFFSET + (OSD_WIDTH >> 1) - 1; +wire [9:0] v_osd_start = v_dsp_ctr + OSD_Y_OFFSET - (OSD_HEIGHT >> 1); +wire [9:0] v_osd_end = v_dsp_ctr + OSD_Y_OFFSET + (OSD_HEIGHT >> 1) - 1; + +reg h_osd_active, v_osd_active; +always @(posedge pclk) begin + if(hs_in != hs_pol) begin + if(h_cnt == h_osd_start) h_osd_active <= 1'b1; + if(h_cnt == h_osd_end) h_osd_active <= 1'b0; + end + if(vs_in != vs_pol) begin + if(v_cnt == v_osd_start) v_osd_active <= 1'b1; + if(v_cnt == v_osd_end) v_osd_active <= 1'b0; + end +end + +wire osd_de = osd_enable && h_osd_active && v_osd_active; + +wire [7:0] osd_hcnt = h_cnt - h_osd_start + 7'd1; // one pixel offset for osd_byte register +wire [6:0] osd_vcnt = v_cnt - v_osd_start; + +wire osd_pixel = osd_byte[osd_vcnt[3:1]]; + +reg [7:0] osd_byte; +always @(posedge pclk) + osd_byte <= osd_buffer[{osd_vcnt[6:4], osd_hcnt}]; + +wire [2:0] osd_color = OSD_COLOR; +assign red_out = !osd_de?red_in: {osd_pixel, osd_pixel, osd_color[2], red_in[5:3] }; +assign green_out = !osd_de?green_in:{osd_pixel, osd_pixel, osd_color[1], green_in[5:3]}; +assign blue_out = !osd_de?blue_in: {osd_pixel, osd_pixel, osd_color[0], blue_in[5:3] }; + +assign hs_out = hs_in; +assign vs_out = vs_in; + +endmodule diff --git a/cores/c16/pll.ppf b/cores/c16/pll.ppf new file mode 100644 index 0000000..b7fa3e1 --- /dev/null +++ b/cores/c16/pll.ppf @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/cores/c16/pll_ntsc.qip b/cores/c16/pll_ntsc.qip new file mode 100644 index 0000000..4a8f47e --- /dev/null +++ b/cores/c16/pll_ntsc.qip @@ -0,0 +1,4 @@ +set_global_assignment -name IP_TOOL_NAME "ALTPLL" +set_global_assignment -name IP_TOOL_VERSION "13.1" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll_ntsc.v"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_ntsc.ppf"] diff --git a/cores/c16/pll_ntsc.v b/cores/c16/pll_ntsc.v new file mode 100644 index 0000000..2a6abf2 --- /dev/null +++ b/cores/c16/pll_ntsc.v @@ -0,0 +1,309 @@ +// megafunction wizard: %ALTPLL% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altpll + +// ============================================================ +// File Name: pll_ntsc.v +// Megafunction Name(s): +// altpll +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 13.1.4 Build 182 03/12/2014 SJ Web Edition +// ************************************************************ + + +//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. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module pll_ntsc ( + inclk0, + c0, + locked); + + input inclk0; + output c0; + output locked; + + wire [4:0] sub_wire0; + wire sub_wire2; + wire [0:0] sub_wire5 = 1'h0; + wire [0:0] sub_wire1 = sub_wire0[0:0]; + wire c0 = sub_wire1; + wire locked = sub_wire2; + wire sub_wire3 = inclk0; + wire [1:0] sub_wire4 = {sub_wire5, sub_wire3}; + + altpll altpll_component ( + .inclk (sub_wire4), + .clk (sub_wire0), + .locked (sub_wire2), + .activeclock (), + .areset (1'b0), + .clkbad (), + .clkena ({6{1'b1}}), + .clkloss (), + .clkswitch (1'b0), + .configupdate (1'b0), + .enable0 (), + .enable1 (), + .extclk (), + .extclkena ({4{1'b1}}), + .fbin (1'b1), + .fbmimicbidir (), + .fbout (), + .fref (), + .icdrclk (), + .pfdena (1'b1), + .phasecounterselect ({4{1'b1}}), + .phasedone (), + .phasestep (1'b1), + .phaseupdown (1'b1), + .pllena (1'b1), + .scanaclr (1'b0), + .scanclk (1'b0), + .scanclkena (1'b1), + .scandata (1'b0), + .scandataout (), + .scandone (), + .scanread (1'b0), + .scanwrite (1'b0), + .sclkout0 (), + .sclkout1 (), + .vcooverrange (), + .vcounderrange ()); + defparam + altpll_component.bandwidth_type = "AUTO", + altpll_component.clk0_divide_by = 270000, + altpll_component.clk0_duty_cycle = 50, + altpll_component.clk0_multiply_by = 286363, + altpll_component.clk0_phase_shift = "0", + altpll_component.compensate_clock = "CLK0", + altpll_component.inclk0_input_frequency = 37037, + altpll_component.intended_device_family = "Cyclone III", + altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll_ntsc", + altpll_component.lpm_type = "altpll", + altpll_component.operation_mode = "NORMAL", + altpll_component.pll_type = "AUTO", + altpll_component.port_activeclock = "PORT_UNUSED", + altpll_component.port_areset = "PORT_UNUSED", + altpll_component.port_clkbad0 = "PORT_UNUSED", + altpll_component.port_clkbad1 = "PORT_UNUSED", + altpll_component.port_clkloss = "PORT_UNUSED", + altpll_component.port_clkswitch = "PORT_UNUSED", + altpll_component.port_configupdate = "PORT_UNUSED", + altpll_component.port_fbin = "PORT_UNUSED", + altpll_component.port_inclk0 = "PORT_USED", + altpll_component.port_inclk1 = "PORT_UNUSED", + altpll_component.port_locked = "PORT_USED", + altpll_component.port_pfdena = "PORT_UNUSED", + altpll_component.port_phasecounterselect = "PORT_UNUSED", + altpll_component.port_phasedone = "PORT_UNUSED", + altpll_component.port_phasestep = "PORT_UNUSED", + altpll_component.port_phaseupdown = "PORT_UNUSED", + altpll_component.port_pllena = "PORT_UNUSED", + altpll_component.port_scanaclr = "PORT_UNUSED", + altpll_component.port_scanclk = "PORT_UNUSED", + altpll_component.port_scanclkena = "PORT_UNUSED", + altpll_component.port_scandata = "PORT_UNUSED", + altpll_component.port_scandataout = "PORT_UNUSED", + altpll_component.port_scandone = "PORT_UNUSED", + altpll_component.port_scanread = "PORT_UNUSED", + altpll_component.port_scanwrite = "PORT_UNUSED", + altpll_component.port_clk0 = "PORT_USED", + altpll_component.port_clk1 = "PORT_UNUSED", + altpll_component.port_clk2 = "PORT_UNUSED", + altpll_component.port_clk3 = "PORT_UNUSED", + altpll_component.port_clk4 = "PORT_UNUSED", + altpll_component.port_clk5 = "PORT_UNUSED", + altpll_component.port_clkena0 = "PORT_UNUSED", + altpll_component.port_clkena1 = "PORT_UNUSED", + altpll_component.port_clkena2 = "PORT_UNUSED", + altpll_component.port_clkena3 = "PORT_UNUSED", + altpll_component.port_clkena4 = "PORT_UNUSED", + altpll_component.port_clkena5 = "PORT_UNUSED", + altpll_component.port_extclk0 = "PORT_UNUSED", + altpll_component.port_extclk1 = "PORT_UNUSED", + altpll_component.port_extclk2 = "PORT_UNUSED", + altpll_component.port_extclk3 = "PORT_UNUSED", + altpll_component.self_reset_on_loss_lock = "OFF", + altpll_component.width_clock = 5; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" +// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" +// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz" +// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low" +// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0" +// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" +// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0" +// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0" +// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0" +// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0" +// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0" +// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8" +// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "183" +// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "28.636299" +// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0" +// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0" +// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" +// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" +// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" +// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000" +// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1" +// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any" +// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" +// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "191" +// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "28.63630000" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" +// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0" +// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll_ntsc.mif" +// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0" +// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0" +// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000" +// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz" +// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.000" +// Retrieval info: PRIVATE: SPREAD_USE STRING "0" +// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0" +// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1" +// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1" +// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_CLK0 STRING "1" +// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" +// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0" +// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "270000" +// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "286363" +// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0" +// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" +// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF" +// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5" +// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" +// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" +// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked" +// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 +// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 +// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 +// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_ntsc.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_ntsc.ppf TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_ntsc.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_ntsc.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_ntsc.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_ntsc_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_ntsc_bb.v FALSE +// Retrieval info: LIB_FILE: altera_mf +// Retrieval info: CBX_MODULE_PREFIX: ON diff --git a/cores/c16/pll_pal.qip b/cores/c16/pll_pal.qip new file mode 100644 index 0000000..6c4dccc --- /dev/null +++ b/cores/c16/pll_pal.qip @@ -0,0 +1,4 @@ +set_global_assignment -name IP_TOOL_NAME "ALTPLL" +set_global_assignment -name IP_TOOL_VERSION "13.1" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll_pal.v"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll_pal.ppf"] diff --git a/cores/c16/pll_pal.v b/cores/c16/pll_pal.v new file mode 100644 index 0000000..4e0e7c0 --- /dev/null +++ b/cores/c16/pll_pal.v @@ -0,0 +1,309 @@ +// megafunction wizard: %ALTPLL% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altpll + +// ============================================================ +// File Name: pll_pal.v +// Megafunction Name(s): +// altpll +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 13.1.4 Build 182 03/12/2014 SJ Web Edition +// ************************************************************ + + +//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. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module pll_pal ( + inclk0, + c0, + locked); + + input inclk0; + output c0; + output locked; + + wire [4:0] sub_wire0; + wire sub_wire2; + wire [0:0] sub_wire5 = 1'h0; + wire [0:0] sub_wire1 = sub_wire0[0:0]; + wire c0 = sub_wire1; + wire locked = sub_wire2; + wire sub_wire3 = inclk0; + wire [1:0] sub_wire4 = {sub_wire5, sub_wire3}; + + altpll altpll_component ( + .inclk (sub_wire4), + .clk (sub_wire0), + .locked (sub_wire2), + .activeclock (), + .areset (1'b0), + .clkbad (), + .clkena ({6{1'b1}}), + .clkloss (), + .clkswitch (1'b0), + .configupdate (1'b0), + .enable0 (), + .enable1 (), + .extclk (), + .extclkena ({4{1'b1}}), + .fbin (1'b1), + .fbmimicbidir (), + .fbout (), + .fref (), + .icdrclk (), + .pfdena (1'b1), + .phasecounterselect ({4{1'b1}}), + .phasedone (), + .phasestep (1'b1), + .phaseupdown (1'b1), + .pllena (1'b1), + .scanaclr (1'b0), + .scanclk (1'b0), + .scanclkena (1'b1), + .scandata (1'b0), + .scandataout (), + .scandone (), + .scanread (1'b0), + .scanwrite (1'b0), + .sclkout0 (), + .sclkout1 (), + .vcooverrange (), + .vcounderrange ()); + defparam + altpll_component.bandwidth_type = "AUTO", + altpll_component.clk0_divide_by = 39, + altpll_component.clk0_duty_cycle = 50, + altpll_component.clk0_multiply_by = 41, + altpll_component.clk0_phase_shift = "0", + altpll_component.compensate_clock = "CLK0", + altpll_component.inclk0_input_frequency = 37037, + altpll_component.intended_device_family = "Cyclone III", + altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll_pal", + altpll_component.lpm_type = "altpll", + altpll_component.operation_mode = "NORMAL", + altpll_component.pll_type = "AUTO", + altpll_component.port_activeclock = "PORT_UNUSED", + altpll_component.port_areset = "PORT_UNUSED", + altpll_component.port_clkbad0 = "PORT_UNUSED", + altpll_component.port_clkbad1 = "PORT_UNUSED", + altpll_component.port_clkloss = "PORT_UNUSED", + altpll_component.port_clkswitch = "PORT_UNUSED", + altpll_component.port_configupdate = "PORT_UNUSED", + altpll_component.port_fbin = "PORT_UNUSED", + altpll_component.port_inclk0 = "PORT_USED", + altpll_component.port_inclk1 = "PORT_UNUSED", + altpll_component.port_locked = "PORT_USED", + altpll_component.port_pfdena = "PORT_UNUSED", + altpll_component.port_phasecounterselect = "PORT_UNUSED", + altpll_component.port_phasedone = "PORT_UNUSED", + altpll_component.port_phasestep = "PORT_UNUSED", + altpll_component.port_phaseupdown = "PORT_UNUSED", + altpll_component.port_pllena = "PORT_UNUSED", + altpll_component.port_scanaclr = "PORT_UNUSED", + altpll_component.port_scanclk = "PORT_UNUSED", + altpll_component.port_scanclkena = "PORT_UNUSED", + altpll_component.port_scandata = "PORT_UNUSED", + altpll_component.port_scandataout = "PORT_UNUSED", + altpll_component.port_scandone = "PORT_UNUSED", + altpll_component.port_scanread = "PORT_UNUSED", + altpll_component.port_scanwrite = "PORT_UNUSED", + altpll_component.port_clk0 = "PORT_USED", + altpll_component.port_clk1 = "PORT_UNUSED", + altpll_component.port_clk2 = "PORT_UNUSED", + altpll_component.port_clk3 = "PORT_UNUSED", + altpll_component.port_clk4 = "PORT_UNUSED", + altpll_component.port_clk5 = "PORT_UNUSED", + altpll_component.port_clkena0 = "PORT_UNUSED", + altpll_component.port_clkena1 = "PORT_UNUSED", + altpll_component.port_clkena2 = "PORT_UNUSED", + altpll_component.port_clkena3 = "PORT_UNUSED", + altpll_component.port_clkena4 = "PORT_UNUSED", + altpll_component.port_clkena5 = "PORT_UNUSED", + altpll_component.port_extclk0 = "PORT_UNUSED", + altpll_component.port_extclk1 = "PORT_UNUSED", + altpll_component.port_extclk2 = "PORT_UNUSED", + altpll_component.port_extclk3 = "PORT_UNUSED", + altpll_component.self_reset_on_loss_lock = "OFF", + altpll_component.width_clock = 5; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0" +// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000" +// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz" +// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low" +// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1" +// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0" +// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0" +// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0" +// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0" +// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0" +// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0" +// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0" +// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0" +// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8" +// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "39" +// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000" +// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "28.384615" +// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0" +// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0" +// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0" +// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575" +// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1" +// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000" +// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000" +// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1" +// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1" +// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available" +// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0" +// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any" +// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0" +// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "41" +// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1" +// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "28.37500000" +// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0" +// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz" +// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000" +// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0" +// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg" +// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1" +// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0" +// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0" +// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0" +// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll_pal.mif" +// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0" +// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0" +// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0" +// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0" +// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000" +// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz" +// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.000" +// Retrieval info: PRIVATE: SPREAD_USE STRING "0" +// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0" +// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1" +// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1" +// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_CLK0 STRING "1" +// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0" +// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0" +// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "39" +// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50" +// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "41" +// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0" +// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0" +// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL" +// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO" +// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED" +// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED" +// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF" +// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5" +// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]" +// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0" +// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0" +// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked" +// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0 +// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0 +// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0 +// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_pal.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_pal.ppf TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_pal.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_pal.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_pal.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_pal_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL pll_pal_bb.v FALSE +// Retrieval info: LIB_FILE: altera_mf +// Retrieval info: CBX_MODULE_PREFIX: ON diff --git a/cores/c16/ps2receiver.v b/cores/c16/ps2receiver.v new file mode 100644 index 0000000..e119f08 --- /dev/null +++ b/cores/c16/ps2receiver.v @@ -0,0 +1,76 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Copyright 2013-2016 Istvan Hegedus +// +// FPGATED is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// FPGATED is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Create Date: 11:30:06 12/14/2015 +// Module Name: ps2receiver.v +// Project Name: FPGATED +// Description: PS2 keyboard receiver +// +// +// +// Revision: +// Revision 1.0 - File Created +// Additional Comments: +// +////////////////////////////////////////////////////////////////////////////////// +module ps2receiver( + input clk, + input ps2_clk, + input ps2_data, + output reg rx_done, + output reg [7:0] ps2scancode + ); + +reg ps2clkreg=1'b0,prev_ps2clkreg=1'b0; +reg [3:0] receivedbits=4'b0; +reg [11:0] watchdog=12'd2900; // ~ 100us watchdog period with 28MHz clock +reg [7:0] ps2clkfilter; +reg [10:0] shiftreg; + +always @(posedge clk) // filtering ps2 clock line glitches + begin + ps2clkfilter<={ps2clkfilter[6:0],ps2_clk}; + if(ps2clkfilter==8'h00) + ps2clkreg<=0; + else if (ps2clkfilter==8'hff) + ps2clkreg<=1; + prev_ps2clkreg<=ps2clkreg; // this is needed for clock edge detection + end + +always @(posedge clk) + begin + rx_done<=0; // rx_done is active only for one clk cycle + if(watchdog==0) // when watchdog timer expires, reset received bits + receivedbits<=0; + else watchdog<=watchdog-1; + + if(prev_ps2clkreg & ~ps2clkreg) // falling edge of ps2 clock + begin + watchdog<=12'd2900; // reload watchdog timer + shiftreg<={ps2_data,shiftreg[10:1]}; + receivedbits<=receivedbits+1; + end + + if(receivedbits==4'd11) + begin + ps2scancode<=shiftreg[9:1]; + rx_done<=1; + receivedbits<=0; + end + end + +endmodule diff --git a/cores/c16/scandoubler.v b/cores/c16/scandoubler.v new file mode 100644 index 0000000..9915fd2 --- /dev/null +++ b/cores/c16/scandoubler.v @@ -0,0 +1,177 @@ +// +// scandoubler.v +// +// Copyright (c) 2015 Till Harbaum +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +// TODO: Delay vsync one line + +module scandoubler +( + // system interface + input clk_sys, + + // scanlines (00-none 01-25% 10-50% 11-75%) + input [1:0] scanlines, + + // shifter video interface + input hs_in, + input vs_in, + input [3:0] r_in, + input [3:0] g_in, + input [3:0] b_in, + + // output interface + output reg hs_out, + output reg vs_out, + output reg [5:0] r_out, + output reg [5:0] g_out, + output reg [5:0] b_out +); + + +// try to detect changes in input signal and lock input clock gate +// it +reg last_hs_in; +reg [1:0] i_div; +wire ce_x1 = (i_div == 2'b01); +wire ce_x2 = i_div[0]; + +always @(posedge clk_sys) begin + if(last_hs_in != hs_in) begin + i_div <= 2'b00; + last_hs_in <= hs_in; + end else begin + i_div <= i_div + 2'd1; + end +end + +// --------------------- create output signals ----------------- +// latch everything once more to make it glitch free and apply scanline effect +reg scanline; +always @(posedge clk_sys) begin + if(ce_x2) begin + hs_out <= hs_sd; + vs_out <= vs_in; + + // reset scanlines at every new screen + if(vs_out != vs_in) scanline <= 0; + + // toggle scanlines at begin of every hsync + if(hs_out && !hs_sd) scanline <= !scanline; + + // if no scanlines or not a scanline + if(!scanline || !scanlines) begin + r_out <= { sd_out[11:8], 2'b00 }; + g_out <= { sd_out[7:4], 2'b00 }; + b_out <= { sd_out[3:0], 2'b00 }; + end else begin + case(scanlines) + 1: begin // reduce 25% = 1/2 + 1/4 + r_out <= {1'b0, sd_out[11:8], 1'b0} + {2'b00, sd_out[11:8]}; + g_out <= {1'b0, sd_out[7:4], 1'b0} + {2'b00, sd_out[7:4] }; + b_out <= {1'b0, sd_out[3:0], 1'b0} + {2'b00, sd_out[3:0] }; + end + + 2: begin // reduce 50% = 1/2 + r_out <= {1'b0, sd_out[11:8], 1'b0}; + g_out <= {1'b0, sd_out[7:4], 1'b0}; + b_out <= {1'b0, sd_out[3:0], 1'b0}; + end + + 3: begin // reduce 75% = 1/4 + r_out <= {2'b00, sd_out[11:8]}; + g_out <= {2'b00, sd_out[7:4]}; + b_out <= {2'b00, sd_out[3:0]}; + end + endcase + end + end +end + +// scan doubler output register +reg [11:0] sd_out; + +// ================================================================== +// ======================== the line buffers ======================== +// ================================================================== + +// 2 lines of 512 pixels 3*4 bit RGB +(* ramstyle = "no_rw_check" *) reg [11:0] sd_buffer[1023:0]; + +// use alternating sd_buffers when storing/reading data +reg line_toggle; + +// total hsync time (in 16MHz cycles), hs_total reaches 1024 +reg [8:0] hs_max; +reg [8:0] hs_rise; +reg [8:0] hcnt; + +always @(posedge clk_sys) begin + reg hsD, vsD; + + if(ce_x1) begin + hsD <= hs_in; + + // falling edge of hsync indicates start of line + if(hsD && !hs_in) begin + hs_max <= hcnt; + hcnt <= 9'd0; + end else begin + hcnt <= hcnt + 9'd1; + end + + // save position of rising edge + if(!hsD && hs_in) hs_rise <= hcnt; + + vsD <= vs_in; + if(vsD != vs_in) line_toggle <= 0; + + // begin of incoming hsync + if(hsD && !hs_in) line_toggle <= !line_toggle; + + sd_buffer[{line_toggle, hcnt}] <= {r_in, g_in, b_in}; + end +end + +// ================================================================== +// ==================== output timing generation ==================== +// ================================================================== + +reg [8:0] sd_hcnt; +reg hs_sd; + +// timing generation runs 32 MHz (twice the input signal analysis speed) +always @(posedge clk_sys) begin + reg hsD; + + if(ce_x2) begin + hsD <= hs_in; + + // output counter synchronous to input and at twice the rate + sd_hcnt <= sd_hcnt + 9'd1; + if(hsD && !hs_in) sd_hcnt <= hs_max; + if(sd_hcnt == hs_max) sd_hcnt <= 0; + + // replicate horizontal sync at twice the speed + if(sd_hcnt == hs_max) hs_sd <= 0; + if(sd_hcnt == hs_rise) hs_sd <= 1; + + // read data from line sd_buffer + sd_out <= sd_buffer[{~line_toggle, sd_hcnt}]; + end +end + +endmodule diff --git a/cores/c16/sdram.v b/cores/c16/sdram.v new file mode 100644 index 0000000..d9fcb0b --- /dev/null +++ b/cores/c16/sdram.v @@ -0,0 +1,150 @@ +// +// sdram.v +// +// sdram controller implementation for the MiST board +// https://github.com/mist-devel +// +// Copyright (c) 2015 Till Harbaum +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +module sdram ( + + // interface to the MT48LC16M16 chip + inout [15:0] sd_data, // 16 bit bidirectional data bus + output reg [12:0] sd_addr, // 13 bit multiplexed address bus + output reg [1:0] sd_dqm, // two byte masks + output reg[1:0] sd_ba, // two banks + output sd_cs, // a single chip select + output sd_we, // write enable + output sd_ras, // row address select + output sd_cas, // columns address select + + // cpu/chipset interface + input init, // init signal after FPGA config to initialize RAM + input clk, // sdram is accessed at up to 128MHz + input clkref, // reference clock to sync to + + input [15:0] din, // data input from chipset/cpu + output [15:0] dout, // data output to chipset/cpu + input [24:0] addr, // 25 bit word address + input [1:0] ds, // data strobe for hi/low byte + input oe, // cpu/chipset requests read + input we // cpu/chipset requests write +); + +// no burst configured +localparam RASCAS_DELAY = 3'd2; // tRCD>=20ns -> 2 cycles@64MHz +localparam BURST_LENGTH = 3'b000; // 000=none, 001=2, 010=4, 011=8 +localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved +localparam CAS_LATENCY = 3'd3; // 2/3 allowed +localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed +localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write + +localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH}; + +// --------------------------------------------------------------------- +// ------------------------ cycle state machine ------------------------ +// --------------------------------------------------------------------- + +localparam STATE_IDLE = 4'd0; // first state in cycle +localparam STATE_CMD_START = 4'd1; // state in which a new command can be started +localparam STATE_CMD_CONT = STATE_CMD_START + RASCAS_DELAY - 3'd1; // 4 command can be continued +localparam STATE_LAST = 4'd15; // last state in cycle + +reg [3:0] q /* synthesis noprune */; +always @(posedge clk) begin + // 32Mhz counter synchronous to 4 Mhz clock + // force counter to pass state 5->6 exactly after the rising edge of clkref + // since clkref is two clocks early + if(((q == 14) && ( clkref == 0)) || + ((q == 15) && ( clkref == 1)) || + ((q != 14) && (q != 15))) + q <= q + 4'd1; +end + +// --------------------------------------------------------------------- +// --------------------------- startup/reset --------------------------- +// --------------------------------------------------------------------- + +// wait 1ms (32 clkref cycles) after FPGA config is done before going +// into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0) +reg [4:0] reset; +always @(posedge clk) begin + if(init) reset <= 5'h1f; + else if((q == STATE_LAST) && (reset != 0)) + reset <= reset - 5'd1; +end + +// --------------------------------------------------------------------- +// ------------------ generate ram control signals --------------------- +// --------------------------------------------------------------------- + +// all possible commands +localparam CMD_INHIBIT = 4'b1111; +localparam CMD_NOP = 4'b0111; +localparam CMD_ACTIVE = 4'b0011; +localparam CMD_READ = 4'b0101; +localparam CMD_WRITE = 4'b0100; +localparam CMD_BURST_TERMINATE = 4'b0110; +localparam CMD_PRECHARGE = 4'b0010; +localparam CMD_AUTO_REFRESH = 4'b0001; +localparam CMD_LOAD_MODE = 4'b0000; + +reg [3:0] sd_cmd; // current command sent to sd ram + +// drive control signals according to current command +assign sd_cs = sd_cmd[3]; +assign sd_ras = sd_cmd[2]; +assign sd_cas = sd_cmd[1]; +assign sd_we = sd_cmd[0]; + +assign sd_data = we?din:16'bZZZZZZZZZZZZZZZZ; + +assign dout = sd_data; + +always @(posedge clk) begin + sd_cmd <= CMD_INHIBIT; + + if(reset != 0) begin + sd_ba <= 2'b00; + sd_dqm <= 2'b00; + + if(reset == 13) sd_addr <= 13'b0010000000000; + else sd_addr <= MODE; + + if(q == STATE_IDLE) begin + if(reset == 13) sd_cmd <= CMD_PRECHARGE; + if(reset == 2) sd_cmd <= CMD_LOAD_MODE; + end + end else begin + if(q <= STATE_CMD_START) begin + sd_addr <= addr[20:8]; + sd_ba <= addr[22:21]; + sd_dqm <= { !ds[1], !ds[0] }; + end else + sd_addr <= { 4'b0010, addr[23], addr[7:0]}; + + if(q == STATE_IDLE) begin + if(we || oe) sd_cmd <= CMD_ACTIVE; + else sd_cmd <= CMD_AUTO_REFRESH; + end else if(q == STATE_CMD_CONT) begin + if(we) sd_cmd <= CMD_WRITE; + else if(oe) sd_cmd <= CMD_READ; + end + end +end + +endmodule diff --git a/cores/c16/stp1.stp b/cores/c16/stp1.stp new file mode 100644 index 0000000..1183210 --- /dev/null +++ b/cores/c16/stp1.stp @@ -0,0 +1,1186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 'C16:c16|kernal_dl_write' == rising edge + + + + + + + 111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000011111111111111111111111101000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000 + 111111111111111111111111111111111111111111111111111111111111111111111111111111111111110000011111111111111111111111101000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000 + + + + + + + + + + + + + + + + + + + 11111111101111111111000000001111111111111100111111010111111011111111110100001111110111111110011111111100111111011111111110111111111100000000111111111111110011111101011111101111111111010000111111111111111001111111110011111101111111111011111111110000000011111111111111001111110101111110111111111101000011111100001111100111111111001111110111111111101111111111000000001111111111111100111111010111111011111111110100001111111000111110011111111100111111011100000011111111111100000000111111111111110011111101100101110000001011010000111111010011111001111111110011111101110000001111111111110000000011111111111111001111110110010111000000101101000011111111001111100111111111001111110111000000111111111111000000001111111111111100111111011001011100000010110100001111110010111110011111111100111111011100000011111111111100000000111111111111110011111101100101110000001011010000111111101011111001111111110011111101110000001111111111110000000011111111111111001111110110010111000000101101000011111101101111100111111111001111110111000000101111111111000000001111111111111100111111011001011100000010110100001111111110111110011111111100111111011000101110111111111100000000111111111111110011111101100101110000001011010000111111000111111001111111110011111101100010111011111111110000000011111111111111001111110110010111000000101101000011111110011111100111111111001111110110001011101111111111000000001111111111111100111111011001011100000010110100001111110101111110011111111100111111011000101110111111111100000000111111111111110011111101100101110000001011010000111111110111111001111111110011111101100010111011111111110000000011111111111111001111110110010111000000101101000011111100110000000000000000000001110110001011101111111111000000001111111111111100111111011001011100000010110100001111111011000000000000000000000111011000101110111111111100000000000000000000000000011111100101110000001011010000111111011100000000000000000000011111100010111011111111110000000000000000000000000001110110010111000000101101000011111111110000000000000000000001110110001011101111111111000000000000000000000000000111011001011100000010110100001111110000000000000000000000000111011000101110111111111100000000000000000000000000011101100101110000001011010000111111100000000000000000000000011101001111111111111111110000000000000000000000000001110101111110111111111101000011111101000000000000000000000001110100111111111111111111000000000000000000000000000111010111111011111111110100001111111100000000000000000000000111010011111111111111111100000000000000000000000000011101011111101111111111010000111111001000000000000000000000011101001111111111111111110000000000000000000000000001110101111110111111111101000011111110100000000000000000000001110100111111111111111111000000000000000000000000000111010111111011111111110100001111110110000000000000000000000111010011111110111111111100000000000000000000000000011101011111101111111111010000111111111000000000000000000000011101111111111011111111110000000000000000000000000001110101111110111111111101000011111100010000000000000000000001110111111111101111111111000000000000000000000000000111010111111011111111110100000001111001000000000000000000000111011111111110111111111100000000000000000000000000011101011111101111111111010000000111010100000000000000000000011101111111111011111111110000000000000000000000000001110101111110111111111101000000011111010000000000000000000001110111111111101111111111000000000000000000000000000111010111111011111111110100000001110011000000000000000000000111011111111110111111111100000000000000000000000000011101011111101111111111010000000111101100000000000000000000011101111111111011111111110000000000000000000000000001110101111110111111111101000000011101110000000000000000000001110111111111101111111111000000000000000000000000000111010111111011111111110100000001111111000000000000000000000111011111111110111111111100000000000000000000000000011101011111101111111111010000000111000000000000000000000000011101111111111011111111110000000000000000000000000001110101111110111111111101000000011110000000000000000000000001110111000000111111111111000000000000000000000000000111011001011100000010110100000001110100000000000000000000000111011100000011111111111100000000000000000000000000011101100101110000001011010000000111110000000000000000000000011101110000001111111111110000000000000000000000000001110110010111000000101101000000011100100000000000000000000001110111000000111111111111000000000000000000000000000111011001011100000010110100000001111010000000000000000000000111011100000011111111111100000000000000000000000000011101100101110000001011010000000111011000000000000000000000011101110000001011111111110000000000000000000000000001110110010111000000101101000000011111100000000000000000000001110110001011101111111111000000000000000000000000000111011001011100000010110100000001110001000000000000000000000111011000101110111111111100000000000000000000000000011101100101110000001011010000000111100100000000000000000000011101100010111011111111110000000000000000000000000001110110010111000000101101000000011101010000000000000000000001110110001011101111111111000000000000000000000000000111011001011100000010110100000001111101000000000000000000000111011000101110111111111100000000000000000000000000011101100101110000001011010000000111001100000000000000000000011101100010111011111111110000000000000000000000000001110110010111000000101101000000011110110000000000000000000001110110001011101111111111000000000000000000000000000111011001011100000010110100000001110111000000000000000000000111011000101110111111111100000000000000000000000000011101100101110000001011010000000111111100000000000000000000011101100010111011111111110000000000000000000000000001110110010111000000101101000000011100000000000000000000000001110110001011101111111111000000000000000000000000000111011001011100000010110100000001111000000000000000000000000111010011111111111111111100000000000000000000000000011101011111101111111111010000000111010010000000000000000100000001001111111111111111110000000000000000000000000001110101111110111111111101000000011111001000000000000000010000000100111111111111111111000000001000000000000001000000110111111011111111110100000001110010100000000000000001000000110011111111111111111100000000100000000000000100000001011111101111111111010000000111101010000000000000000100000001001111111111111111110000000010000000000000010000000101111110111111111101000000011101101000000000000000010000000100111111101111111111000000001000000000000001000000010111111011111111110100000001111110100000000000000001000000011111111110111111111100000000100000000000000100000001011111101111111111010000000111000110000000000000000100000001111111111011111111110000000010000000000000010000000101111110111111111101000100000010011000000000000000010000000111111111101111111111000000001000000000000001000000010111111011111111110100010000000101100000000000000001000000011111111110111111111100000000100000000000000100000001011111101111111111010001000000110110000000000000000100000001111111111011111111110000000010000000000000010000000101111110111111111101000100000000111000000000000000010000000111111111101111111111000000001000000000000001000000010111111011111111110100010000001011100000000000000001000000011111111110111111111100000000100000000000000100000001011111101111111111010001000000011110000000000000000100000001111111111011111111110000000010000000000000010000000101111110111111111101000100000011111000000000000000010000000111111111101111111111000000001000000000000001000000010111111011111111110100010000000000100000000000000001000000011111111110111111111100000000100000000000000100000001011111101111111111010001000000100010000000000000000100000001110000001111111111110000000010000000000000010000000110010111000000101101000100000001001000000000000000010000000111000000111111111111000000001000000000000001000000011001011100000010110100010000001100100000000000000001000000011100000011111111111100000000100000000000000100000001100101110000001011010001000000001010000000000000000100000001110000001111111111110000000010000000000000010000000110010111000000101101000100000010101000000000000000010000000111000000111111111111000000001000000000000001000000011001011100000010110100010000000110100000000000000001000000011100000010111111111100000000100000000000000100000001100101110000001011010001000000111010000000000000000100000001100010111011111111110000000010000000000000010000000110010111000000101101000100000000011000000000000000010000000110001011101111111111000000001000000000000001000000011001011100000010110100010000001001100000000000000001000000011000101110111111111100000000100000000000000100000001100101110000001011010001000000010110000000000000000100000001100010111011111111110000000010000000000000010000000110010111000000101101000100000011011000000000000000010000000110001011101111111111000000001000000000000001000000011001011100000010110100010000000011100000000000000001000000011000101110111111111100000000100000000000000100000001100101110000001011010001000000101110000000000000000100000001100010111011111111110000000010000000000000010000000110010111000000101101000100000001111000000000000000010000000110001011101111111111000000001000000000000001000000011001011100000010110100010000001111100000000000000001000000011000101110111111111100000000100000000000000100000001100101110000001011010001000000000010000000000000000100000001100010111011111111110000000010000000000000010000000110010111000000101101000100000010001000000000000000010000000100111111111111111111000000001000000000000001000000010111111011111111110100010000000100100000000000000001000000010011111111111111111100000000100000000000000100000001011111101111111111010001000000110010000000000000000100000001001111111111111111110000000010000000000000010000000101111110111111111101000100000000101000000000000000010000000100111111111111111111000000001000000000000001000000010111111011111111110100010000001010100000000000000001000000010011111111111111111100000000100000000000000100000001011111101111111111010001000000011010000000000000000100000001001111111011111111110000000010000000000000010000000101111110111111111101000100000011101000000000000000010000000111111111101111111111000000001000000000000001000000010111111011111111110100010000000001000000010000000000001001011111111110111111111100000000100000000000000100000001011111101111111111010001000000100100000001000000000000100101111111111011111111110000000000000100000000000010011101111110111111111101000100000001010000000100000000000010011111111111101111111111000000000000010000000000001001010111111011111111110100010000001101000000010000000000001001011111111110111111111100000000000001000000000000100101011111101111111111010001000000001100000001000000000000100101111111111011111111110000000000000100000000000010010101111110111111111101000100000010110000000100000000000010010111111111101111111111000000000000010000000000001001010111111011111111110100010000000111000000010000000000001001011111111110111111111100000000000001000000000000100101011111101111111111010001000000111100000001000000000000100101111111111011111111110000000000000100000000000010010101111110111111111101000100000000000000000100000000000010010111111111101111111111000000000000010000000000001001010111111011111111110100010000001000000000010000000000001001011100000011111111111100000000000001000000000000100101100101110000001011010001000000010000000001000000000000100101110000001111111111110000000000000100000000000010010110010111000000101101000100000011000000000100000000000010010111000000111111111111000000000000010000000000001001011001011100000010110100010000000010000000010000000000001001011100000011111111111100000000000001000000000000100101100101110000001011010001000000101000000001000000000000100101110000001111111111110000000000000100000000000010010110010111000000101101000100000001100000000100000000000010010111000000101111111111000000000000010000000000001001011001011100000010110100010000001110000000010000000000001001011000101110111111111100000000000001000000000000100101100101110000001011010001000000000100000001000000000000100101100010111011111111110000000000000100000000000010010110010111000000101101000000100110010000000100000000000010010110001011101111111111000000000000010000000000001001011001011100000010110100000010010101000000010000000000001001011000101110111111111100000000000001000000000000100101100101110000001011010000001001110100000001000000000000100101100010111011111111110000000000000100000000000010010110010111000000101101000000100100110000000100000000000010010110001011101111111111000000000000010000000000001001011001011100000010110100000010011011000000010000000000001001011000101110111111111100000000000001000000000000100101100101110000001011010000001001011100000001000000000000100101100010111011111111110000000000000100000000000010010110010111000000101101000000100111110000000100000000000010010110001011101111111111000000000000010000000000001001011001011100000010110100000010010000000000010000000000001001011000101110111111111100000000000001000000000000100101100101110000001011010000001001100000000001000000000000100101001111111111111111110000000000000100000000000010010101111110111111111101000000100101000000000100000000000010010100111111111111111111000000000000010000000000001001010111111011111111110100000010011100000000010000000000001001010011111111111111111100000000000001000000000000100101011111101111111111010000001001001000000001000000000000100101001111111111111111110000000000000100000000000010010101111110111111111101000000100110100000000100000000000010010100111111111111111111000000000000010000000000001001010111111011111111110100000010010110000000010000000000001001010011111110111111111100000000000001000000000000100101011111101111111111010000001001111000000001000000000000100101111111111011111111110000000000000100000000000010010101111110111111111101000000100100010000000100000000000010010111111111101111111111000000000000010000000000001001010111111011111111110100000010011001000000010000000000001001011111111110111111111100000000000001000000000000100101011111101111111111010000001001010100000001000000000000100101111111111011111111110000000000000100000000000010010101111110111111111101000000100111010000000100000000000010010111111111101111111111000000000000010000000000001001010111111011111111110100000010010011000000010000000000001001011111111110111111111100000000000001000000000000100101011111101111111111010000001001101100000001000000000000100101 + 1111111111111111T111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 + + + + + + + + + + + + + + + + + + diff --git a/cores/c16/ted.v b/cores/c16/ted.v new file mode 100644 index 0000000..8841adf --- /dev/null +++ b/cores/c16/ted.v @@ -0,0 +1,1752 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Copyright 2013-2016 Istvan Hegedus +// +// FPGATED is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// FPGATED is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Create Date: 12/18/2013 - 31/03/2016 +// Design Name: MOS 8360 video chip +// Module Name: ted.v +// Project Name: FPGATED +// Description: Cycle exact MOS 8360 TED display chip +// +// Revision history: +// 0.2 12/11/2015 diag 264 runs, all screenmodes implemented, external dram works, scroll bug in diag264 +// 0.3 22/01/2016 DRAM resfresh horizontal events improved (increment start/stop, counter reset),vertical scroll bug in Invincible, FF1E write bug in New FLI, FLI incorrect +// 0.4 03/02/2016 VertSub counter fixed for Invincible start screen +// 0.5 22/02/2016 Raster interrupt fixed, Invincible does not freeze now +// 0.6 03/03/2016 Multicolor Character mode bug fixed in pixelgenerator. Majesty Of Sprites looks good now +// 0.7 30/03/2016 Audio sound generator and audio D/A implemented +// 1.0 14/07/2016 First public release, functionally equivalent to 0.7, code cleaned up, license information added +////////////////////////////////////////////////////////////////////////////////// + +module ted( + input wire clk, // clk must be 4*dot clk so 28.375152MHz for PAL (1.6*PAL system's clock) and 28.63636 for NTSC (2*NTSC system's clock) + input wire [15:0] addr_in, + output wire [15:0] addr_out, + input wire [7:0] data_in, + output wire [7:0] data_out, + input wire rw, + output wire cpuclk, // this is a CPU clock for external real CPU + output wire [6:0] color, // 7 bits color code + output wire csync, + output reg hsync, + output reg vsync, + output wire irq, + output wire ba, + output reg mux, + output reg ras, + output reg cas, + output reg cs0, + output reg cs1, + output reg aec, + output wire snd, + output wire pal, + input wire [7:0] k, + output wire cpuenable // this TED signals is needed only for FPGA bustiming and FPGA internal cpu. If external CPU is used, it is not needed. + ); + + + +// TED register addresses + +parameter TIMER1LO=6'h00; +parameter TIMER1HI=6'h01; +parameter TIMER2LO=6'h02; +parameter TIMER2HI=6'h03; +parameter TIMER3LO=6'h04; +parameter TIMER3HI=6'h05; +parameter CONTROL1=6'h06; +parameter CONTROL2=6'h07; +parameter KEYLATCH=6'h08; +parameter IRQ =6'h09; +parameter IRQEN =6'h0A; +parameter RASTER =6'h0B; +parameter CURPOSHI=6'h0C; +parameter CURPOSLO=6'h0D; +parameter CH1FREQLO=6'h0E; +parameter CH2FREQLO=6'h0F; +parameter CH2FREQHI=6'h10; +parameter SOUNDCTRL=6'h11; +parameter BMAPBASE=6'h12; +parameter CHARBASE=6'h13; +parameter VIDEOBASE=6'h14; +parameter BGCOLOR0=6'h15; +parameter BGCOLOR1=6'h16; +parameter BGCOLOR2=6'h17; +parameter BGCOLOR3=6'h18; +parameter EXCOLOR=6'h19; +parameter CHARPOSRELOADHI=6'h1A; +parameter CHARPOSRELOADLO=6'h1B; +parameter VSCANPOSHI=6'h1C; +parameter VSCANPOSLO=6'h1D; +parameter HSCANPOS=6'h1E; +parameter FLASH_VERTSUB=6'h1F; +parameter ROMEN=6'h3E; +parameter RAMEN=6'h3F; + +// DMA FSM states + +localparam IDLE=3'b000,THALT1=3'b001,THALT2=3'b010,THALT3=3'b011,TDMA=3'b100; +reg [2:0] dma_state=IDLE,dma_nextstate; // DMA FSM state register + +// TED user accessible registers +// These registers are the actual TED registers accessible by end users + +reg [15:0] timer1=16'b0,timer1_reload=16'b0; // $FF00/01 +reg [15:0] timer2=16'b0; // $FF02/03 +reg [15:0] timer3=16'b0; // $FF04/05 +reg test=1'b0,ecm=1'b0,bmm=1'b0,den=1'b0,rsel=1'b0; // $FF06 control1 register bits +reg [2:0] yscroll=3'b0; // $FF06 bits 0-2, vertical scroll register +reg bmm_reg=1'b0,ecm_reg=1'b0; // delayed registered values of BMM and ECM +reg reverse=1'b0,stop=1'b0,mcm=1'b0,csel=1'b0; // $FF07 control2 register bits +reg [2:0] xscroll=3'b0; // $FF07 bits 0-2, horizontal scroll regitser +reg reverse_reg=1'b0,mcm_reg=1'b0; // delayed registered values of REVERSE and ECM +reg [7:0] keylatch=8'hff; // $FF08 keyboard latch +reg Cnt1Irq=1'b0,Cnt2Irq=1'b0,Cnt3Irq=1'b0,RasterIrq=1'b0,LPIrq=1'b1; // $FF09 IRQ register +reg enCnt1Irq=1'b0,enCnt2Irq=1'b0,enCnt3Irq=1'b0,enRasterIrq=1'b0,enLPIrq=1'b0; // $FF0A IRQ enable register +reg [8:0] RasterCmp=9'b0; // $FF0B +reg [9:0] CursorPos=10'b0; // $FF0C/0D +reg [9:0] Ch1Freq=10'b0; // $FF0E, $FF12 bits 0-1 +reg [9:0] Ch2Freq=10'b0; // $FF0F, $FF10 bits 0-1 +reg damode=1'b0,ch2noise=1'b0,ch2en=1'b0,ch1en=1'b0; // $FF11 bits 4-7 +reg [3:0] volume=4'b0; // $FF11 bits 0-3 +reg [2:0] bmapbase=3'b0; // $FF12 bits 3-5, Bitmap base address +reg charrom=1'b0; // $FF12 bit 2 +reg [5:0] charbase=6'b0; // $FF13 bits 2-7, Character memory base address +reg clkmode=1'b0; // $FF13 bit 1, force single clock mode +reg [4:0] vmbase=5'b0; // $FF14 bits 3-7, Video RAM base address register +reg [6:0] bgcolor0=7'b0,bgcolor1=7'b0,bgcolor2=7'b0,bgcolor3=7'b0,excolor=7'b0; // $FF15-19 color registers +reg [9:0] CharPosReload=10'b0; // $FF1A/B, Character Position Reload increments by 40 for each character row completed +reg [8:0] vcounter=9'b0; // $FF1C/D, Vertical line counter +reg [8:0] hcounter=9'b0; // $FF1E, Horizontal dot counter. In real TED it is 11bit. Counts from 0 to 455 +reg [4:0] FlashCount=5'b0; // $FF1F bits 3-6, Flash counter's 5th bit is the actual flash state and is not user accessible +reg [2:0] VertSubCount=3'b0; // $FF1f bits 0-2, Vertical Character scan line position + +// TED internal operational registers +// These are needed for the internal operation + +reg [7:0] refreshcounter=8'h00; +reg refresh=1'b0; +reg [3:0] phicounter=4'b0; // CPU single clock generator counter +reg phi=1'b0; // CPU single clock +reg singleclock=1'b0; // signals single clock mode + +reg [8:0] hcounter_next; +reg [8:0] vcounter_next; +reg [8:0] videoline=9'b0; // vcounter latched at start of each scanline +reg [7:0] dataout_reg=8'hff; // TED's databus out register +reg [7:0] data_in_reg; // TED databus in register +reg [5:0] addr_in_reg; // TED address in register + +reg [6:0] colorreg=7'b0; // video out register +reg ramen=1'b0; // High memory address RAM enable register (above $8000) +reg t1stop=1'b0,t2stop=1'b0,t3stop=1'b0; // Timer disable signals +reg resetRasterIrq,resetLpIrq,resetCnt1Irq,resetCnt2Irq,resetCnt3Irq; // Interrupt reset signals +reg RasterIrqDone=1'b0; // Signals that raster interrupt has already happened in this line +reg enabledisplay=1'b0; // DEN register changes enabledisplay signal on first scanline only +reg badline2=1'b0; // signals 2nd badline (1st badline signal is a wire) +reg ext_fetch=1'b0; // signals external fetch window inside scanline +reg char_fetch=1'b0; // signals character fetch window inside scanline +reg dma_window=1'b0; // signals active dma range inside a scanline +reg char_window=1'b0; // signals when character/pixel data can be latched from data bus inside a scanline +reg inc_flashcount_window=1'b0; // signals flash counter increase window +reg inc_vertsub_window=1'b0; // active for one single clock cycle, signals vertsub register incrementation point (thus actual increment point is delayed with a single clock cycle) +reg inc_vertline_window=1'b0; // active for one single clock cycle, signals vertical line incrementation point (thus actual increment point is delayed with a single clock cycle) + +// horizontal event positions used for the horizontal event decoder. They don't necessarily reflect the values seen in documentation +reg hpos_0,hpos_8,hpos_154,hpos_172,hpos_288,hpos_295,hpos_296,hpos_303,hpos_304; +reg hpos_312,hpos_320,hpos_336,hpos_343,hpos_348,hpos_353,hpos_359,hpos_380,hpos_382; +reg hpos_384,hpos_391,hpos_392,hpos_400,hpos_407,hpos_423,hpos_431,hpos_432,hpos_440; + +reg inc_charpos=1'b0; // signals internal character position register (not user accessible) increment range inside scanline (not same as $FF1A/$FF1B) +reg [15:0] addr_out_reg; // TED's address out register +reg [15:0] tedaddress; // this is a non registered TED address (although register variable but used in combinational logic) +reg datahold=1'b0; // signals whether TED should hold its data on the databus +reg VertSubActive=1'b0; // signals the scanline ranges when Vertsub counter is active +reg tedwrite_delay=1'b0; // this signal was needed to emulate a one dot clock delay when TED writes data to its internal registers. Although most probably this delay exist at + // all TED register writes, in FPGATED we use it only for hcounter/vcounter and color register writes. This emulates white pixel bug too. +reg csyncreg=1'b0,palreg=1'b0,equalization=1'b0,eq1=1'b1,eq2=1'b1; // PAL/NTSC video screen signals +reg [9:0] videocounter=10'b0; // videocounter is the actual DMA counter. +reg inc_videocounter=1'b0; // signals videocounter increment window +reg [9:0] videocounter_reload=10'b0; // videocounter is reloaded with this value at the beginning of each displayed line +reg [9:0] CharPosition=10'b0; // CharPosition is loaded by $FF1A/$FF1B and is similar to videocounter. It is used for pixel data fetch from memory. +reg CharPosLatch=1'b0; // Signals latching position of CharPosition and videocounter +reg latch_window=1'b0; // CharPosition and videocounter latch delay window +reg latch_charposition=1'b0; // Charposition and videocounter latch position + +reg [7:0] attr_buf [0:39]; // TED internal videomatrix attribute memory +reg [7:0] char_buf [0:39]; // TED internal videomatrix character pointer memory +reg [7:0] nextchar=8'b0,currentchar=8'b0,waitingchar=8'b0,pixelchar=8'b0; // next...,current... is a 2 bytes shiftregister to keep data until rendering. waiting... is waiting to be loaded to rendering shiftregister +reg [7:0] nextattr=8'b0,currentattr=8'b0,waitingattr=8'b0,pixelattr=8'b0; +reg [7:0] nextpixels=8'b0,currentpixels=8'b0,waitingpixels=8'b0; +reg [7:0] pixelshiftreg=8'b0; // This register contains pixel data and shifts it during rendering +reg [5:0] shiftcount=6'b0; // Used by the videomatrix shift register to count number of shifts +reg verticalscreen=1'b0; // Signals which lines are in screen area (top/bottom border control) +reg widescreen=1'b0,narrowscreen=1'b0; // Signals horizontal screen area (left/right border control) +reg videoshift=1'b0; // Signals when vide shoft register is active +reg nextcursor=1'b0,currentcursor=1'b0,waitingcursor=1'b0; // cursor state internal storage for 3 signle clock cycles + +reg [6:0] pixelcolor; // Color of a pixel +reg doubleshift=1'b0; // During multicolor mode 2 pixels identify one pixel, so this register signals to pixel generator wheter to shift one or two pixels to get color data +reg dotfetch; // Signals when TED is fetching pixeldata from databus +reg dotfetch_reg=1'b0; // Registered version of dotfetch +reg [2:0] xscroll_latch=3'b0; // Registered version of xscroll register +reg [2:0] yscroll_latch=3'b0; // Registered version of yscroll register +reg hblank=1'b0,vblank=1'b0; // Signals blanking area +reg refresh_inc=1'b0; // Dram refresh counter increment window +reg stopreg=1'b0; // This is a latched version of stop register. Latched at single cycle end + +// audio part registers + +reg [1:0] audiocycle=2'b0; // Audio cycle counter divides single clock by 4 and generates audio clock +reg [9:0] ch1count=10'b0,ch2count=10'b0; // Audio channel1 and channel2 counters +reg ch1state=1'b0,ch2state=1'b0; // State register of audio channels +reg ch1stateclk_prev=1'b0,ch2stateclk_prev=1'b0; +reg [7:0] noisegen=8'b0; // Noise generator register +reg [4:0] pwmcounter1=5'b0,pwmcounter2=5'b0; // PWM D/A counters +reg ch1pwm=0,ch2pwm=0; // continous square wave with proportional duty cycle to volume +reg [4:0] digivolume=5'b0; // A digital value signaling at which pwmclock cycle PWM signal high value starts. A digitized version of volume level +reg [17:0] watchdog_ch1=18'b0,watchdog_ch2=18'b0; // Watchdog timer to emulate sound decay of TED's dynamic latch behaviour + + +integer i; +integer j; +integer n; + +// Internal wires, flags + +wire dphi; // double phi clock +wire [8:0] EOS,VS_START,VS_STOP,EQ_START,EQ_STOP,VBLANK_START,VBLANK_STOP; //video signal generation constants. Vertical Sync, Equalization, Blank +wire tick8; // enable tick for pixelclock (8MHz) +wire blanking; // screen blanking area flag +wire lowrom,highrom; // TED low and high rom area flags +wire irqpos; // IRQ position flag inside clock cycle. Emulates real TED's IRQ signal activation position +wire io,tedreg,tedwrite; // IO area flag, TED user registers area flag, TED write cycle flag (signals when TED register is written by CPU) +wire badline; // badline flag +wire attr_fetch_line; // Visible screen area flag (signals active window) +wire tedlatch; // tedlatch simulates at which exact position TED latches value into its internal register from the databus +wire [7:0] charpointer,attrpointer; +wire multicolor; // multicolor mode flag +wire pixelscreen; // visible pixelscreen area flag (excluding borders) +wire ch1clk,ch2clk; // Audio channel clocks +wire ch1stateclk,ch2stateclk; // Audio state register change clock +wire ch1audio,ch2audio; // Audio channel square waves not modulated by volume (before PWM) +wire noise; // Noise +wire watchdog_ch1max,watchdog_ch2max; // Audio watchdog timer maximum values. Actual value is taken from plus4emu + +// Initializing internal video matrix + +initial + begin + for(i=0;i<=39;i=i+1) + begin + char_buf[i]=0; + attr_buf[i]=0; + end + end + + +//----------------------------------------------------------------------- +// Often used combinational signals +//----------------------------------------------------------------------- + +assign cycle_end=(phicounter==15)?1'b1:1'b0; // high pulse at the end of each double clock cycle +assign single_cycle_end=(cycle_end & phi)?1'b1:1'b0; // high pulse at the end of each single clock cycle + +//----------------------------------------------------------------------- +// Clock signal driver phi=Single Clock dphi=Double Clock +//----------------------------------------------------------------------- + +always @(posedge clk) // Counting FPGA clock cycles during double clock. phicounter is mod16 counter, 16*clk=half phi + begin + phicounter<=phicounter+1; + end + +assign cpuclk = singleclock?phi:dphi; // Generated CPU clock. Used only when real 8501 CPU is connected to FPGA +assign dphi = phicounter[3]; // Internal double clock signal +assign cpuenable=(single_cycle_end)?1'b1: // Generated CPU enable signal. Used only when FPGA CPU is used + (cycle_end && !singleclock)?1'b1: + 1'b0; + +always @(posedge clk) // Internal single clock signal is always generated + begin + if (cycle_end) + phi<=~phi; + end + +always @(posedge clk) // clock mode controller. Single or double clock multiplex for the CPU. + begin + if(single_cycle_end) // clock mode change happens only at single clock boundary + singleclock<=((enabledisplay & ext_fetch) | refresh | clkmode | stop); // there are 4 criterias to generate single clock: display area,dram refresh,forced 1Mhz,TED stop + end + +always @(posedge clk) + begin + if(single_cycle_end) + stopreg<=stop; + end + +//-------------------------------------------------------------------------- +// Attribute Fetch +//-------------------------------------------------------------------------- + +always @(posedge clk) // flip flop to signal external fetch single clock window, delayed with 1 single clock cycle + begin + if(hpos_296) + ext_fetch<=0; + else if(hpos_400) + ext_fetch<=1; + end + +assign attr_fetch_line=(videoline>=0 && videoline<203); + +//-------------------------------------------------------------------------- +// DRAM Refresh +//-------------------------------------------------------------------------- + +always @(posedge clk) // refresh single clock control + begin + if(hpos_336) + refresh<=0; + else if(hpos_296) + refresh<=1; + end + +always @(posedge clk) // refresh counter increment control + begin + if(hpos_343) + refresh_inc<=0; + else if(hpos_303) + refresh_inc<=1; + end + +always @(posedge clk) + begin + if(single_cycle_end & (refresh_inc|stopreg)) + refreshcounter<=refreshcounter+1; + else if(hpos_431 & (videoline==0|refresh_inc|stopreg)) + refreshcounter<=8'h00; + end + +//------------------------------------------------------------------------------------------- +// Horizontal counter running on ~8Mhz and vertical counter qualified by horizontal counter +//------------------------------------------------------------------------------------------- + +assign tick8=(phicounter[1:0]==3)?1'b1:1'b0; //8Mhz clock tick for pixelclock. tick8 must activate one fastclk cycle earlier to use it for hcounter + + +always @(posedge clk) + begin + hcounter<=hcounter_next; + vcounter<=vcounter_next; + if(hpos_392) + videoline<=vcounter; + end + +always @* //horizontal counter next state logic + begin + hcounter_next=hcounter; + if (tedlatch & addr_in_reg[5:0]==HSCANPOS) // horizontal counter is written by CPU + begin + hcounter_next=hcounter+1; + hcounter_next[8:3]=~data_in_reg[7:2]; // bit 0-2 are not modified by user write to prevent clock phase change + end + else if (tick8 & ~stopreg) + begin + if (hcounter==9'd455) + hcounter_next=9'd0; + else + hcounter_next=hcounter+1; + end + end + +always @* //vertical counter next state logic + begin + vcounter_next=vcounter; + if(tedwrite & addr_in[5:1]==5'b01110) // $ff1c or $ff1d register write (VSCAN HI and LO) + begin + if(addr_in[0]==0) + vcounter_next={data_in[0],vcounter[7:0]}; + else vcounter_next={vcounter[8],data_in}; + end + else if(inc_vertline_window & single_cycle_end) + begin + if (vcounter==EOS) + vcounter_next=0; + else vcounter_next=vcounter+1; + end + end + +always @(posedge clk) + begin + if(hpos_384) + inc_vertline_window<=1; + else if (single_cycle_end) + inc_vertline_window<=0; + end + + +//--------------------------------------------------------------------------- +// Timer 1 +//--------------------------------------------------------------------------- +// timer 1 decrements during odd single clock cycle (phi=0) +// exact counter change position is unknown but can be estimated based on IRQ place and reading counter values every cycle on a real hardware +// timer 1 changes approximately at half of phi low cycle after IRQ position (IRQ position is 160ns after phi low cycle start). +// + +always @(posedge clk) + begin + if(tedwrite) // load timer 1 at cycle border + begin + if (addr_in[5:0]==TIMER1LO) + begin + timer1[7:0]<=data_in; + timer1_reload[7:0]<=data_in; + t1stop<=1; + end + if (addr_in[5:0]==TIMER1HI) + begin + timer1[15:8]<=data_in; + timer1_reload[15:8]<=data_in; + t1stop<=0; + end + end + if(phicounter==7 && ~phi & ~t1stop & ~stopreg) // decrement or reload timer 1 + begin + if(timer1==0) + timer1<=timer1_reload-1; + else + timer1<=timer1-1; + end + end + +//--------------------------------------------------------------------------- +// Timer 2 +//--------------------------------------------------------------------------- +// timer 2 decrements during even single clock cycle (phi=1) +// timer 2 changes approximately at odd-even single clock cycle boundary (phi low - high transition) + +always @(posedge clk) + begin + if(tedwrite) // load timer 2 at cycle border + begin + if (addr_in[5:0]==TIMER2LO) + begin + timer2[7:0]<=data_in; + t2stop<=1; + end + if (addr_in[5:0]==TIMER2HI) + begin + timer2[15:8]<=data_in; + t2stop<=0; + end + end + else if(phicounter==15 && phi==0 && t2stop==0 && stopreg==0) // if not loaded, decrement timer 2 at odd-even cycle border + begin + timer2<=timer2-1; + end + end + +//--------------------------------------------------------------------------- +// Timer 3 +//--------------------------------------------------------------------------- +// timer 3 decrements during even single clock cycle (phi=1) +// timer 3 changes approximately at half of phi high cycle (contrary to timer 1) + +always @(posedge clk) + begin + if(tedwrite) + begin + if (addr_in[5:0]==TIMER3LO) // load timer 3 at cycle border + begin + timer3[7:0]<=data_in; + t3stop<=1; + end + if (addr_in[5:0]==TIMER3HI) + begin + timer3[15:8]<=data_in; + t3stop<=0; + end + end + if(phicounter==7 && phi==1 && t3stop==0 && stopreg==0) // decrement timer 3 + begin + timer3<=timer3-1; + end + end + +//--------------------------------------------------------------------------- +// Timer IRQs +//--------------------------------------------------------------------------- +// + +assign irqpos=(phicounter==4 & ~phi)?1'b1:1'b0; + +always @(posedge clk) + begin + if(resetCnt1Irq) + Cnt1Irq<=0; + else if(irqpos && timer1==0) + Cnt1Irq<=1; + end + +always @(posedge clk) + begin + if(resetCnt2Irq) + Cnt2Irq<=0; + else if(irqpos && timer2==0) + Cnt2Irq<=1; + end + +always @(posedge clk) + begin + if(resetCnt3Irq) + Cnt3Irq<=0; + else if(irqpos && timer3==0) + Cnt3Irq<=1; + end + + +//--------------------------------------------------------------------------- +// Raster IRQ +//--------------------------------------------------------------------------- + +always @(posedge clk) + begin + if (resetRasterIrq) + RasterIrq<=0; + else if (RasterCmp==vcounter) + begin + if(~RasterIrqDone & tick8) // do raster interrupt only 1 time per raster line and interrupt happens when phi or dphi is low and about 170ns after cycle start + begin + RasterIrq<=1; + RasterIrqDone<=1; + end + end + else RasterIrqDone<=0; + end + +//--------------------------------------------------------------------------- +// IRQ signal +//--------------------------------------------------------------------------- + +assign irq=~((enCnt1Irq & Cnt1Irq)|(enCnt2Irq & Cnt2Irq)| (enCnt3Irq & Cnt3Irq) | (enRasterIrq & RasterIrq) | (enLPIrq & LPIrq)); + +//--------------------------------------------------------------------------- +// AEC signal generating +//--------------------------------------------------------------------------- + +always @(posedge clk) + begin + if((singleclock & ~phi) | (dma_state==TDMA)) + aec<=0; + else aec<=1; + end + +//--------------------------------------------------------------------------- +// BA signal (RDY) +//--------------------------------------------------------------------------- + +assign ba=(dma_state==IDLE)?1'b1:1'b0; + +//--------------------------------------------------------------------------- +// badline +//--------------------------------------------------------------------------- + +assign badline=((yscroll_latch==videoline[2:0]) & enabledisplay & attr_fetch_line)?1'b1:1'b0; // signal 1st badline + +always @(posedge clk) + begin + if(inc_vertline_window & single_cycle_end) + begin + if(badline) + badline2<=1; + else if(badline2) + badline2<=0; + end +/* else if(badline & ~hpos_392) //when yscroll changed to generate badline, abort an already started badline2 (except at start of line) + badline2<=0;*/ + end + +always @(posedge clk) // synchronize yscroll changes to single cycle border + begin + if(single_cycle_end) + yscroll_latch<=yscroll; + end + +//--------------------------------------------------------------------------- +// EnableDisplay signal +//--------------------------------------------------------------------------- + +always @(posedge clk) + begin + if(videoline==0 && den==1) + enabledisplay<=1; + if(videoline==204) + enabledisplay<=0; + end + +//--------------------------------------------------------------------------- +// Bitmapmask fetch signal +//--------------------------------------------------------------------------- + +always @(posedge clk) // character fetch window starts at first badline2 and stops at line 204. It signals that character fetches can happen in these lines. + begin + if(videoline==9'd204) + char_fetch<=0; + else if(badline2) + char_fetch<=1; + end +//---------------------------------------------------------------------------- +// Character Position register $FF1A/$FF1B +//---------------------------------------------------------------------------- + +always @(posedge clk) // character fetch position increase from horizontal count 432 to horizontal count 296 + begin + if(hpos_296) + inc_charpos<=0; + else if(hpos_432) + inc_charpos<=1; + end + +always @(posedge clk) // DMA and Charpos latch delay trick + begin + latch_charposition<=0; + if(hpos_288) + latch_window<=1; + else if(single_cycle_end & latch_window) + begin + latch_window<=0; + latch_charposition<=1; // 1 FPGA cycle long latch enable signal used for Character position and videocounter position reload latch + end + end + +always @(posedge clk) + begin + if(latch_charposition) + begin + if(VertSubCount==6) + CharPosLatch<=1; // CharPosLatch signal activates in line 6 and signals that videocounter (DMA counter) has been latched. It is used in line 7 for character position latch. + else + CharPosLatch<=0; + end + end + +always @(posedge clk) // Character Position Reload register $FF1A/$FF1B + begin + if(tedwrite & addr_in[5:0]==CHARPOSRELOADHI) + CharPosReload[9:8]<=data_in[1:0]; + else if(tedwrite & addr_in[5:0]==CHARPOSRELOADLO) + CharPosReload[7:0]<=data_in; + else if(hpos_392 & videoline==EOS) // clear character position reload at last line + CharPosReload<=0; + else if(CharPosLatch & latch_charposition & VertSubActive) // latch character position at 7th line of a character row if videocunter was latched in previous 6th row + CharPosReload<=CharPosition; + end + +always @(posedge clk) // Character Position counter (not user accessible) + begin + if(hpos_392) // clear character position in each line at 392 + CharPosition<=0; + else + begin + if(hpos_432 & enabledisplay & VertSubActive) // FIXME this might need delay + CharPosition<=CharPosReload; + else if(inc_charpos & single_cycle_end) + CharPosition<=CharPosition+1; + end + end + + +//--------------------------------------------------------------------------- +// Attribute fetch (DMA) +//--------------------------------------------------------------------------- +// DMA FSM + +always @(posedge clk) + begin + dma_state<=dma_nextstate; + end + +always @* + begin + dma_nextstate=dma_state; + case(dma_state) + IDLE: begin + if((badline|badline2) & dma_window) + dma_nextstate=THALT1; + end + THALT1: begin + if((badline|badline2) & dma_window & single_cycle_end) + dma_nextstate=THALT2; + else if (~dma_window | ~(badline|badline2)) + dma_nextstate=IDLE; + end + THALT2: begin + if((badline|badline2) & dma_window & single_cycle_end) + dma_nextstate=THALT3; + else if (~dma_window | ~(badline|badline2)) + dma_nextstate=IDLE; + end + THALT3: begin + if((badline|badline2) & dma_window & single_cycle_end) + dma_nextstate=TDMA; + else if (~dma_window | ~(badline|badline2)) + dma_nextstate=IDLE; + end + TDMA: begin + if (~dma_window | ~(badline|badline2)) + dma_nextstate=IDLE; + end + default: dma_nextstate=IDLE; + endcase + end + +always @(posedge clk) + begin + if(hpos_407 & tick8) + dma_window<=1; + else if(hpos_295 & tick8) + dma_window<=0; + end + + +//------------- +// Attribute fetch address generation (videocounter is DMA position counter) +//------------- + +always @(posedge clk) // videocounter increase window + begin + if(enabledisplay) + begin + if(hpos_296 | shiftcount==6'd40) + inc_videocounter<=0; + else if(hpos_432) + inc_videocounter<=1; + end + end + +always @(posedge clk) + begin + if(hpos_392 & videoline==EOS) // clear videocounter reload register at last line + videocounter_reload<=0; + else if(VertSubCount==6 && latch_charposition && VertSubActive) // Latch videocounter position at 6th line of a character row + videocounter_reload<=videocounter; + end + +always @(posedge clk) // videocounter used for attribute and character pointer fetches (DMA counter) + begin + if(enabledisplay) + begin + if(hpos_432) + videocounter<=videocounter_reload; + else if(inc_videocounter & single_cycle_end) // increase videocounter at cycle border + videocounter<=videocounter+1; + end + end + +//------------------------------------ +// Internal VideoMatrix (DMA buffers) +//------------------------------------ + + +always @(posedge clk) + begin + if(single_cycle_end) + begin + if(inc_videocounter) + begin + if(badline) begin // in 1st badline fetch attribute from databus and place to buffer's start + attr_buf[0]<=data_in; + end + else begin + attr_buf[0]<=attr_buf[39]; + end + for(i=1;i<40;i=i+1) begin + attr_buf[i]<=attr_buf[i-1]; + end + nextattr<=attr_buf[39]; + shiftcount<=shiftcount+1; + + if(((CursorPos==CharPosition) && VertSubActive) || (CursorPos==0 && CharPosition==0)) // cursor position must be checked here + nextcursor<=1; + else nextcursor<=0; + + end + else begin + nextattr<=0; + shiftcount<=0; + end + end + end + +always @(posedge clk) + begin + if(single_cycle_end) + begin + if(inc_videocounter) + begin + if(badline2) begin + char_buf[0]<=data_in; + nextchar<=data_in; + end + else begin + char_buf[0]<=char_buf[39]; + nextchar<=char_buf[39]; + end + for(j=1;j<40;j=j+1) begin + char_buf[j]<=char_buf[j-1]; + end + end + else begin + nextchar<=0; + end + end + end + + +always @(posedge clk) // character window flag is needed for fetching pixel data from bus + begin + if(hpos_304) + char_window<=0; + else if(hpos_440 & enabledisplay) + char_window<=1; + end + +always @(posedge clk) // latch pixel data from data bus at phi0 change from 0 to 1 + begin + if(char_window) + begin + if(hpos_440) + nextpixels<=0; + else if(cycle_end & ~phi) + nextpixels<=data_in; + end + end + +//--------------------------------------------------------------------------- +// Vertical Sub register represents actual raster line inside character +//--------------------------------------------------------------------------- + +always @(posedge clk) + begin + if(hpos_392) + inc_vertsub_window<=1; + else if(single_cycle_end) + inc_vertsub_window<=0; + + + if (hpos_380 & badline) // ... activates at 1st badline of the frame + VertSubActive<=1; + else if (~enabledisplay) // ... inactivates at line 204 + VertSubActive<=0; + end + +always @(posedge clk) + begin + if(tedwrite && addr_in[5:0]==FLASH_VERTSUB) // if it is written by user + VertSubCount<=data_in[2:0]; + else + if(inc_vertsub_window & single_cycle_end) // if it is time to change VertSub + if (videoline==0) // ... changes to 7 at line 0 FIXME: between cycle $C8 and $CA + VertSubCount<=3'd7; + else if(enabledisplay & VertSubActive) + VertSubCount<=VertSubCount+1; // ... increases between line 0 and 204 + end + +//--------------------------------------------------------------------------- +// Flash counter +// 5th bit of FlashCount contains flash status and not accessible via FF1F register +//--------------------------------------------------------------------------- + +always @(posedge clk) + begin + if(hpos_348) + inc_flashcount_window<=1; + else if(single_cycle_end) + inc_flashcount_window<=0; + + if(tedwrite && addr_in[5:0]==FLASH_VERTSUB) + FlashCount[3:0]<=data_in[6:3]; + else if(videoline==205 & inc_flashcount_window & single_cycle_end) + FlashCount<=FlashCount+1; + end + +//--------------------------------------------------------------------------- +// Horizontal event decodes +//--------------------------------------------------------------------------- + +always @(hcounter) + begin + hpos_0=0; + hpos_8=0; + hpos_154=0; + hpos_172=0; + hpos_288=0; + hpos_295=0; + hpos_296=0; + hpos_303=0; + hpos_304=0; + hpos_312=0; + hpos_320=0; + hpos_336=0; + hpos_343=0; + hpos_348=0; + hpos_353=0; + hpos_359=0; + hpos_380=0; + hpos_382=0; + hpos_384=0; + hpos_391=0; + hpos_392=0; + hpos_400=0; + hpos_407=0; + hpos_423=0; + hpos_431=0; + hpos_432=0; + hpos_440=0; + case (hcounter) + 0: hpos_0=1; // Start of 40 column screen + 8: hpos_8=1; // Start of 38 column screen + 154: hpos_154=1; // Equalization pulse 1 start + 172: hpos_172=1; // Equalization pulse 1 end + 288: hpos_288=1; // CharPosition and Videocounter latch position delayed by 1 cycle (starts at 296) + 295: hpos_295=1; // Attribute fetch (DMA) FSM stop + 296: hpos_296=1; // Stop external fetch single clock delayed by 1 cycle + // Start refresh singleclock delayed by 1 cycle (actual start at 304) + 303: hpos_303=1; // Start refresh counter increment (304 in real TED) + 304: hpos_304=1; // End of character window + 312: hpos_312=1; // End of 38 column screen + 320: hpos_320=1; // End of 40 column screen + 336: hpos_336=1; // Stop refresh singleclock but delayed by 2 cycle (actual stop at 344) + 343: hpos_343=1; // Stop refresh counter increment (344 in real TED) + 348: hpos_348=1; // Flash (blink) counter increment point delayed by 2 cycles (increments at 352) + 353: hpos_353=1; // Horizontal blanking start + 359: hpos_359=1; // Horizontal sync start (358 in real TED however line change takes time thus the delay) + 380: hpos_380=1; + 382: hpos_382=1; // Equalization pulse 2 start + 384: hpos_384=1; // End Of Screen. Clear vertical line,refresh counters and character reload register, increase vertical line after 1 cycle delay + 391: hpos_391=1; + 392: hpos_392=1; // VertSub register increment (delayed), Hsync end + 400: hpos_400=1; // Start external fetch single clock (delayed), Equalization pulse 2 end + 407: hpos_407=1; // Attribute fetch (DMA) FSM start + 423: hpos_423=1; // Horizontal blanking stop + 431: hpos_431=1; // Refresh counter reset point + 432: hpos_432=1; // Start videocounter increment + 440: hpos_440=1; // Start video shiftregister + endcase +end + +//--------------------------------------------------------------------------- +// Border control +//--------------------------------------------------------------------------- + +always @(posedge clk) // 25/24 row select and top/bottom borders + begin + if(rsel==1) begin + if(videoline==9'd4) // if 25 rows mode, screen starts at line 4 + verticalscreen<=1; + else if (videoline==9'd204) // stops at line 204 + verticalscreen<=0; + end + else begin + if(videoline==9'd8) // if 24 rows mode, screen starts at line 8 + verticalscreen<=1; + else if(videoline==9'd200) // stops at line 200 + verticalscreen<=0; + end + end + +always @(posedge clk) // 38/40 columns select and side borders + begin + if(enabledisplay & verticalscreen) + begin + if(hpos_320 & tick8) + widescreen<=0; + else if (hpos_0 & tick8) + widescreen<=1; + if(hpos_312 & tick8) + narrowscreen<=0; + else if (hpos_8 & tick8) + narrowscreen<=1; + end + end + + + + +//--------------------------------------------------------------------------- +// VideoShift Register +//--------------------------------------------------------------------------- + +always @(posedge clk) + begin + if (hpos_312) + videoshift<=0; + else if(enabledisplay & hpos_440) + videoshift<=1; + end + +always @(posedge clk) // video shift register stores fetched video data until pixelshiftregister is loaded + begin + if(hpos_440) + begin + waitingattr<=0; + waitingchar<=0; + waitingpixels<=0; + currentattr<=0; + currentchar<=0; + currentpixels<=0; + end + else if(cycle_end & videoshift) + begin + if(phi) + begin + currentchar<=nextchar; + waitingchar<=currentchar; + currentattr<=nextattr; + waitingattr<=currentattr; + waitingpixels<=currentpixels; + currentcursor<=nextcursor; + waitingcursor<=currentcursor; + end + else if(~phi) + currentpixels<=nextpixels; + end + end + +assign cursor=(waitingcursor & ~FlashCount[4]); + +//--------------------------------------------------------------------------- +// Pixel Generator +// Final screen is delayed by 2 pixels +//--------------------------------------------------------------------------- +always @(posedge clk) // synchronize xscroll and display mode changes to single cycle border + begin + if (single_cycle_end) + begin + xscroll_latch<=xscroll; + ecm<=ecm_reg; + bmm<=bmm_reg; + reverse<=reverse_reg; + mcm<=mcm_reg; + end + end + +always @(posedge clk) // video pixel shift tregister + begin + if(videoshift | widescreen) // shift register works only when beam is on wide screen area + begin + if(tick8) + begin + doubleshift<=~doubleshift; + if(hcounter[2:0] == xscroll_latch) // load register based on xscroll + begin + doubleshift<=0; + if(cursor & ~bmm & ~ecm & ~mcm) // when character is at cursor position and in Standard Character mode, load the invert of character mask + pixelshiftreg<=waitingpixels^8'hFF; + else pixelshiftreg<=waitingpixels; + pixelattr<=waitingattr; // latch attribute and charpointer for pixelgenerator + pixelchar<=waitingchar; + end + else + begin + if(~multicolor) + pixelshiftreg<={pixelshiftreg[6:0],1'b0}; + else if(doubleshift) // double pixel shifting + pixelshiftreg<={pixelshiftreg[5:0],2'b0}; + end + end + end + else pixelshiftreg<=0; // clear shiftreg at the end of screen line to avoid shifting in its content at next line + end + + +assign pixelscreen=(csel)?widescreen:narrowscreen; // change between narrow and wide screens plus 1 pixel delay due to latch + + +assign multicolor= mcm & (ecm | pixelattr[3] | bmm); // multicolor rendering is initiated when mcm=1 and either ecm,bmm or character attribute's 4th bit is 1 + + +always @* // video pixel color generator + begin + pixelcolor=bgcolor0; + if(pixelscreen & enabledisplay) + begin + if (~bmm & ~ecm) // Standard and Multicolor Character modes + begin + if(~multicolor) // Standard Character mode + begin + if((reverse|mcm)?pixelshiftreg[7]:(pixelshiftreg[7]& ~(pixelattr[7] & FlashCount[4]))^pixelchar[7]) + pixelcolor=pixelattr[6:0]; + end + else + begin // Multicolor Character mode + case(pixelshiftreg[7:6]) + 2'b00: pixelcolor=bgcolor0; + 2'b01: pixelcolor=bgcolor1; + 2'b10: pixelcolor=bgcolor2; + 2'b11: pixelcolor={pixelattr[6:4],1'b0,pixelattr[2:0]}; + endcase + end + end + else if (~mcm & ~bmm & ecm) // Extended Color Character mode + begin + if(pixelshiftreg[7]) + pixelcolor=pixelattr[6:0]; + else begin + case(pixelchar[7:6]) + 2'b00: pixelcolor=bgcolor0; + 2'b01: pixelcolor=bgcolor1; + 2'b10: pixelcolor=bgcolor2; + 2'b11: pixelcolor=bgcolor3; + endcase + end + end + else if(~mcm & bmm & ~ecm) // Standard Bitmap mode + begin + if(pixelshiftreg[7]) + pixelcolor={pixelattr[2:0],pixelchar[7:4]}; + else pixelcolor={pixelattr[6:4],pixelchar[3:0]}; + end + else if(mcm & bmm & ~ecm) // Multicolor bitmap mode + begin + case(pixelshiftreg[7:6]) + 2'b00: pixelcolor=bgcolor0; + 2'b01: pixelcolor={pixelattr[2:0],pixelchar[7:4]}; + 2'b10: pixelcolor={pixelattr[6:4],pixelchar[3:0]}; + 2'b11: pixelcolor=bgcolor1; + endcase + end + else // invalid mode + begin + pixelcolor=7'b0; + end + end + else + pixelcolor=excolor; + end + +always @(posedge clk) // latch pixelcolor and multiplex it with blank signal + begin + if (tick8) + if(~blanking) + colorreg<=pixelcolor; + else colorreg<=0; + end + + +//--------------------------------------------------------------------------- +// Screen signals generation +//--------------------------------------------------------------------------- + +// PAL/NTSC screen constants +assign pal = !palreg; + +assign EOS = pal?9'd311:9'd261; // End of Screen scanline +assign VS_START = pal?9'd254:9'd229; // Vertical sync start +assign VS_STOP = pal?9'd257:9'd232; // Vertical sync stop +assign EQ_START = pal?9'd251:9'd226; // Equalization start +assign EQ_STOP = pal?9'd260:9'd235; // Equalization stop +assign VBLANK_START = pal?9'd251:9'd226; // Screen blanking start +assign VBLANK_STOP = pal?9'd269:9'd244; // Screen blanking stop// Composite Sync signal + +always @(posedge clk) // composite synchron is either hsync or equalization+vsync + begin + csyncreg<=(equalization)?(eq1&eq2)^vsync:hsync; + end + +always @(posedge clk) // vsync signal inverts equalization signal + begin + if (videoline==VS_START && hpos_400) + vsync<=1; + else if (videoline==VS_STOP && hpos_400) + vsync<=0; + end + +always @(posedge clk) // equalization signal active during actual vsync+equalization window + begin + if(videoline==EQ_START && hpos_400) + equalization<=1; + else if (videoline==EQ_STOP && hpos_400) + equalization<=0; + end + +always @(posedge clk) // Equalization pulses generated by horizontal decoder events + begin + if(hpos_154) + eq1<=0; + else if (hpos_172) + eq1<=1; + if(hpos_382) + eq2<=0; + else if (hpos_400) + eq2<=1; + end + +always @(posedge clk) // Horizontal sync pulse (due to original HMOS technology signal change takes 2 pixels long thus these change positions differ from the specification) + begin + if(hpos_359) + hsync<=0; + else if (hpos_391) + hsync<=1; + end + +always @(posedge clk) // horizontal blanking zone + begin + if(hpos_423) + hblank<=0; + else if(hpos_353) // in real TED it starts at 352 but slew rate takes 2 pixels. 353 is at halfway. FIXME: Might be initiated at 344. + hblank<=1; + end + +always @(posedge clk) // vertical blanking zone + begin + if(videoline==VBLANK_STOP) + vblank<=0; + else if(videoline==VBLANK_START) + vblank<=1; + end + +assign blanking=hblank|vblank; +assign csync=csyncreg; +assign color=colorreg; + +//----------------------------------------------------------------------------------------------- +// Memory Controller +//----------------------------------------------------------------------------------------------- + +always @(posedge clk) // Generating RAS, internal CAS and MUX signals based on clk28 cycle numbers. Not 100% precise reproduction of original TED timing but still in dram specifications + case (phicounter) // one clk28 cycle is 35.35ns + 1: begin + ras<=1; + cas<=1; + mux<=1; + cs0<=1; + cs1<=1; + end + 6: ras<=0; // RAS goes low 35ns before MUX (20ns on real system) + 7: begin + mux<=0; // MUX goes low when double phi changes to high at half double clock cycle, CS0,CS1 changes together with MUX when needed + if(rw) // CS0,CS1 generation only on read cycles + begin + if((~ramen & ~dotfetch_reg) | (charrom & dotfetch_reg )) // ROM chip select is controlled by ramen register or by charrom register depending on whether dot data is fetched from bus + begin + if(lowrom) // Basic area + cs0<=0; + if(highrom & ~io & ~tedreg) // Kernal area + cs1<=0; + end + end + end +// TH: relax write timing a little bit +// 8: if (rw & cs0 & cs1 & ~io & ~tedreg) // when read cycle, CAS goes low 35ns after MUX (40ns on real system) +// cas<=0; +// 11: if (~rw & ~io & ~tedreg) // when write cycle, CAS goes low 160ns after MUX +// cas<=0; + 8: if ((rw & cs0 & cs1 & ~io & ~tedreg) || (~rw & ~io & ~tedreg)) + cas<=0; + + default: // otherwise they don't change + begin + ras<=ras; + mux<=mux; + cas<=cas; + cs0<=cs0; + cs1<=cs1; + end + endcase + + +// Generating memory area flags. + +assign lowrom=(addr_in[15:14]==2'b10)?1'b1:1'b0; //$8000-$bfff low rom area (Basic) +assign highrom=(addr_in[15:14]==2'b11)?1'b1:1'b0; //$c000-$ffff high rom area (Kernal, IO and TED area) +assign io=(addr_in[15:8]==8'hFD || addr_in[15:8]==8'hFE)?1'b1:1'b0; //$fd00-$feff IO space +assign tedreg=(addr_in[15:6]==10'b1111111100 && (addr_in[5]==0 || addr_in[5:1]==7'b11111))?1'b1:1'b0; //$ff00-$ff1f & $ff3e-$ff3f TED registers + +//----------------------------------------------------------------------------------------------- +// Generating TED address out +//----------------------------------------------------------------------------------------------- + +assign addr_out=(~aec)?addr_out_reg:16'hffff; + +always @(posedge clk) + begin + if(cycle_end) + begin + addr_out_reg<=tedaddress; + dotfetch_reg<=dotfetch; + end + end + +assign charpointer=(inc_videocounter)?((badline2)?data_in:char_buf[39]):0; +assign attrpointer=attr_buf[39]; + +always @* + begin + tedaddress=16'hffff; + dotfetch=0; + if(phi==0) // generating address for phi1 phase (will be clocked and valid in phi1) + begin + if(dma_state==TDMA) + tedaddress={vmbase,(badline)?1'b0:1'b1,videocounter}; // attribute or character pointer fetch address + end + else if(~test) + begin // generating address for phi0 phase (will be clocked and valid in phi0) + if(refresh_inc|stopreg) // dram refresh address + tedaddress={8'hff,refreshcounter}; + else if(inc_charpos & char_fetch) + begin + dotfetch=1; + if(~bmm) // Text mode fetch address + begin + tedaddress=(~reverse)?{charbase[5:0],charpointer[6:0],VertSubCount}:{charbase[5:1],charpointer,VertSubCount}; + tedaddress[10:9]=(ecm)?2'b00:tedaddress[10:9]; + end + else + tedaddress={bmapbase,CharPosition,VertSubCount}; // bitmap mode fetch address + end + end + else begin // IC test mode fetch addresses + dotfetch=1; + if(~bmm) + tedaddress={5'hF8,attrpointer,VertSubCount}; // test mode character screen + else tedaddress={3'b111,(CharPosition && {2'b11,attrpointer}),VertSubCount}; + end + end + +//----------------------------------------------------------------------------------------------- +// TED registers write +//----------------------------------------------------------------------------------------------- + +assign tedwrite=tedreg&~rw&cycle_end; // It signals TED register write which happens always when rw is low and end of double clock cycle +assign tedlatch=tedwrite_delay & (phicounter==3); // trying to simulate when exactly the hcounter is written by TED + +always @(posedge clk) + begin + if(tedwrite) + tedwrite_delay<=1; + else if (phicounter==3) + tedwrite_delay<=0; + end + +always @(posedge clk) + begin + resetRasterIrq<=1'b0; + resetLpIrq<=1'b0; + resetCnt1Irq<=1'b0; + resetCnt2Irq<=1'b0; + resetCnt3Irq<=1'b0; + if (tedwrite) // when TED registers are addressed + begin + data_in_reg<=data_in; + addr_in_reg<=addr_in[5:0]; + case(addr_in[5:0]) + CONTROL1: // $FF06 + begin + test<=data_in[7]; + ecm_reg<=data_in[6]; + bmm_reg<=data_in[5]; + den<=data_in[4]; + rsel<=data_in[3]; + yscroll<=data_in[2:0]; + end + CONTROL2: // $FF07 + begin + reverse_reg<=data_in[7]; + palreg<=data_in[6]; + stop<=data_in[5]; + mcm_reg<=data_in[4]; + csel<=data_in[3]; + xscroll<=data_in[2:0]; + end + KEYLATCH: // $FF08 + keylatch<=k[7:0]; + IRQ: // $FF09 + begin + resetCnt3Irq<=data_in[6]; + resetCnt2Irq<=data_in[4]; + resetCnt1Irq<=data_in[3]; + resetLpIrq<=data_in[2]; + resetRasterIrq<=data_in[1]; + end + IRQEN: // $FF0A + begin + enCnt3Irq<=data_in[6]; + enCnt2Irq<=data_in[4]; + enCnt1Irq<=data_in[3]; + enRasterIrq<=data_in[1]; + RasterCmp[8]<=data_in[0]; + end + RASTER: // $FF0B + RasterCmp[7:0]<=data_in; + CURPOSHI: // $FF0C + CursorPos[9:8]<=data_in[1:0]; + CURPOSLO: // $FF0D + CursorPos[7:0]<=data_in; + CH1FREQLO: // $FF0E + Ch1Freq[7:0]<=data_in; + CH2FREQLO: // $FF0F + Ch2Freq[7:0]<=data_in; + CH2FREQHI: // $FF10 + Ch2Freq[9:8]<=data_in[1:0]; + SOUNDCTRL: // $FF11 + begin + damode<=data_in[7]; + ch2noise<=data_in[6]; + ch2en<=data_in[5]; + ch1en<=data_in[4]; + volume<=data_in[3:0]; + end + BMAPBASE: // $FF12 + begin + bmapbase<=data_in[5:3]; + charrom<=data_in[2]; + Ch1Freq[9:8]<=data_in[1:0]; + end + CHARBASE: // $FF13 + begin + charbase<=data_in[7:2]; + clkmode<=data_in[1]; + end + VIDEOBASE: // $FF14 + vmbase<=data_in[7:3]; + BGCOLOR0: // $FF15 , color change at cycle start, emulating white pixel bug (for all 5 color registers) + bgcolor0<=8'hff; + BGCOLOR1: // $FF16 + bgcolor1<=8'hff; + BGCOLOR2: // $FF17 + bgcolor2<=8'hff; + BGCOLOR3: // $FF18 + bgcolor3<=8'hff; + EXCOLOR: // $FF19 + excolor<=8'hff; + ROMEN: ramen<=1'b0; + RAMEN: ramen<=1'b1; + default:; + endcase + end + // Color registers write (white pixel bug emulation) + else if (tedlatch) // these events happen 1 pixel later after cycle start, setting the proper color to color registers + case(addr_in_reg[5:0]) + BGCOLOR0: // $FF15 + bgcolor0<=data_in_reg[6:0]; + BGCOLOR1: // $FF16 + bgcolor1<=data_in_reg[6:0]; + BGCOLOR2: // $FF17 + bgcolor2<=data_in_reg[6:0]; + BGCOLOR3: // $FF18 + bgcolor3<=data_in_reg[6:0]; + EXCOLOR: // $FF19 + excolor<=data_in_reg[6:0]; + default:; + endcase + end + +// TED register read + +always @(posedge clk) + begin + if(tedreg & rw) + begin + if(phicounter==7) // latch register contents to dataout reg at mux change + begin + case(addr_in[5:0]) + TIMER1LO: // $FF00 + dataout_reg<=timer1[7:0]; + TIMER1HI: // $FF01 + dataout_reg<=timer1[15:8]; + TIMER2LO: // $FF02 + dataout_reg<=timer2[7:0]; + TIMER2HI: // $FF03 + dataout_reg<=timer2[15:8]; + TIMER3LO: // $FF04 + dataout_reg<=timer3[7:0]; + TIMER3HI: // $FF05 + dataout_reg<=timer3[15:8]; + CONTROL1: // $FF06 + begin + dataout_reg[7]<=test; + dataout_reg[6]<=ecm; + dataout_reg[5]<=bmm; + dataout_reg[4]<=den; + dataout_reg[3]<=rsel; + dataout_reg[2:0]<=yscroll; + end + CONTROL2: // $FF07 + begin + dataout_reg[7]<=reverse; + dataout_reg[6]<=palreg; + dataout_reg[5]<=stop; + dataout_reg[4]<=mcm; + dataout_reg[3]<=csel; + dataout_reg[2:0]<=xscroll; + end + KEYLATCH: // $FF08 + begin + dataout_reg<=keylatch; + end + + IRQ: // $FF09 + begin + dataout_reg[7]<=~irq; + dataout_reg[6]<=Cnt3Irq; + dataout_reg[4]<=Cnt2Irq; + dataout_reg[3]<=Cnt1Irq; + dataout_reg[2]<=LPIrq; // Lightpen irq is always 1 as it is not implemented in TED + dataout_reg[1]<=RasterIrq; + end + IRQEN: // $FF0A + begin + dataout_reg[6]<=enCnt3Irq; + dataout_reg[4]<=enCnt2Irq; + dataout_reg[3]<=enCnt1Irq; + dataout_reg[2]<=enLPIrq; // lightpen irq enable bit is implemented in TED + dataout_reg[1]<=enRasterIrq; + dataout_reg[0]<=RasterCmp[8]; + end + RASTER: // $FF0B + dataout_reg<=RasterCmp[7:0]; + CURPOSHI: // $FF0C + dataout_reg[1:0]<=CursorPos[9:8]; + CURPOSLO: // $FF0D + dataout_reg<=CursorPos[7:0]; + CH1FREQLO: // $FF0E + dataout_reg<=Ch1Freq[7:0]; + CH2FREQLO: // $FF0F + dataout_reg<=Ch2Freq[7:0]; + CH2FREQHI: // $FF10 + begin + dataout_reg[7]<=1'b0; // the 8th unused bit is always 0 + dataout_reg[1:0]<=Ch2Freq[9:8]; + end + SOUNDCTRL: //$FF11 + begin + dataout_reg[7]<=damode; + dataout_reg[6]<=ch2noise; + dataout_reg[5]<=ch2en; + dataout_reg[4]<=ch1en; + dataout_reg[3:0]<=volume; + end + BMAPBASE: // $FF12 + begin + dataout_reg[5:3]<=bmapbase; + dataout_reg[2]<=charrom; + dataout_reg[1:0]<=Ch1Freq[9:8]; + end + CHARBASE: // $FF13 + begin + dataout_reg[7:2]<=charbase; + dataout_reg[1]<=clkmode; + dataout_reg[0]<=~ramen; + end + VIDEOBASE: // $FF14 + dataout_reg[7:3]<=vmbase; + BGCOLOR0: // $FF15 + dataout_reg[6:0]<=bgcolor0; + BGCOLOR1: // $FF16 + dataout_reg[6:0]<=bgcolor1; + BGCOLOR2: // $FF17 + dataout_reg[6:0]<=bgcolor2; + BGCOLOR3: // $FF18 + dataout_reg[6:0]<=bgcolor3; + EXCOLOR: // $FF19 + dataout_reg[6:0]<=excolor; + CHARPOSRELOADHI: //$FF1A + dataout_reg[1:0]<=CharPosReload[9:8]; + CHARPOSRELOADLO: //$FF1B + dataout_reg<=CharPosReload[7:0]; + VSCANPOSHI: // $FF1C + dataout_reg[0]<=vcounter[8]; + VSCANPOSLO: // $FF1D + dataout_reg<=vcounter[7:0]; + HSCANPOS: // $FF1E + dataout_reg<={hcounter[8:2],1'b0}; + FLASH_VERTSUB: //$FF1F + begin + dataout_reg[6:3]<=FlashCount[3:0]; + dataout_reg[2:0]<=VertSubCount; + end + ROMEN: // $FF3E + dataout_reg<=8'h00; + RAMEN: // $FF3F + dataout_reg<=8'h00; + default:; + endcase + end + else if(phicounter==10) // put dataout register content to databus at this moment + datahold<=1; + end + if(phicounter==1) + begin + datahold<=0; + dataout_reg<=8'hff; + end + end + +assign data_out=(datahold)?dataout_reg:8'hff; + +//-------------------------------------------------------------------------------- +// TED audio generator +//-------------------------------------------------------------------------------- + +assign snd=(ch1audio&ch1pwm)|(ch2audio&ch2pwm); // mixing audio channel signals + + +always @(posedge clk) // audio cycle counter divides single clock by 4 + begin + if(single_cycle_end) + audiocycle<=audiocycle+1; + end + +assign ch1clk=single_cycle_end&(audiocycle==2'b11); // Channel1 clock +assign ch2clk=single_cycle_end&(audiocycle==2'b01); // Channel2 clock + +// Channel 1 + +always @(posedge clk) + begin + if(ch1clk) + begin + if((ch1count==10'h3ff) || damode) + ch1count<=Ch1Freq+1; + else ch1count<=ch1count+1; + end + end + +assign ch1stateclk=(ch1count==10'h3ff)?1'b1:1'b0; + +always @(posedge clk) // Channel 1 state clock rising edge detection + begin + ch1stateclk_prev<=ch1stateclk; + if(damode|watchdog_ch1max) // reset ch1state if damode is enabled or watchdog timer expires + ch1state<=0; + else if(~ch1stateclk_prev & ch1stateclk) // if rising edge + ch1state<=~ch1state; // change channel 1 state + end + +assign ch1audio=(ch1en)?~ch1state:1'b0; // ch1audio before D/A conversion + +always @(posedge clk) // emulating dynamic latch behaviour using watchdog timer (forgets setting after 188416 * audio clock cycles) + begin + if((~ch1stateclk_prev & ch1stateclk)|watchdog_ch1max) // reset watchdog timer at channel1 state change or when maximum time reached + watchdog_ch1<=0; + else if(ch1clk) // watchdog timer counts with audio clock cycles + watchdog_ch1<=watchdog_ch1+1; + end + +assign watchdog_ch1max=(watchdog_ch1==18'd188416)?1'b1:1'b0; + +// Channel 2 + +always @(posedge clk) + begin + if(ch2clk) + begin + if((ch2count==10'h3ff) || damode) + ch2count<=Ch2Freq+1; + else ch2count<=ch2count+1; + end + end + +assign ch2stateclk=(ch2count==10'h3ff)?1'b1:1'b0; + +always @(posedge clk) // Channel 2 state clock rising edge detection + begin + ch2stateclk_prev<=ch2stateclk; + if(damode) // reset ch2state if damode is enabled + ch2state<=0; + else if(~ch2stateclk_prev & ch2stateclk) // if rising edge + ch2state<=~ch2state; // change channel 2 state + end + +assign ch2audio=(ch2en)?~ch2state:noise; // ch2audio combined with noise before D/A conversion + +always @(posedge clk) // emulating dynamic latch behaviour using watchdog timer (forgets setting after 188416 * audio clock cycles) + begin + if((~ch2stateclk_prev & ch2stateclk)|watchdog_ch2max) // reset watchdog timer at channel1 state change or when maximum time reached + watchdog_ch2<=0; + else if(ch2clk) // watchdog timer counts with audio clock cycles + watchdog_ch2<=watchdog_ch2+1; + end + +assign watchdog_ch2max=(watchdog_ch2==18'd188416)?1'b1:1'b0; + + +// Noise generator + +always @(posedge clk) + begin + if(damode) + noisegen<=0; + else if(~ch2stateclk_prev & ch2stateclk) + begin + for(n=1;n<8;n=n+1) + begin + noisegen[n]<=noisegen[n-1]; + end + noisegen[0]<=1^noisegen[7]^noisegen[5]^noisegen[4]^noisegen[1]; + end + end + +assign noise=(ch2noise)?noisegen[0]:1'b0; // noise signal + +// D/A converter + +always @* // volume value conversion to pwmcounter numbers where PWM signal high value starts + begin + case (volume) + 0: digivolume=31; + 1: digivolume=30; + 2: digivolume=28; + 3: digivolume=26; + 4: digivolume=24; + 5: digivolume=22; + 6: digivolume=20; + 7: digivolume=18; + 8: digivolume=16; + default: digivolume=16; + endcase + end + +always @(posedge clk) // generating PWM pulses for channel1 + begin + if(tick8) + begin + if(ch1clk) // synchronizing channel1 PWM signal to channel1 audio + pwmcounter1<=0; + else pwmcounter1<=pwmcounter1+1; + + if ( pwmcounter1 < digivolume || pwmcounter1==31 ) // set pwm signal duty cycle based on modified volume value + ch1pwm<=0; + else ch1pwm<=1; + end + end + +always @(posedge clk) // generating PWM pulses for channel2 + begin + if(tick8) + begin + if(ch2clk) // synchronizing channel2 PWM signal to channel2 audio (it is shifted by 2 single clock cycles compared to channel1) + pwmcounter2<=0; + else pwmcounter2<=pwmcounter2+1; + + if ( pwmcounter2 < digivolume || pwmcounter2==31 ) // set pwm signal duty cycle based on modified volume value + ch2pwm<=0; + else ch2pwm<=1; + end + end + +endmodule \ No newline at end of file diff --git a/cores/c16/user_io.v b/cores/c16/user_io.v new file mode 100644 index 0000000..e679e00 --- /dev/null +++ b/cores/c16/user_io.v @@ -0,0 +1,418 @@ +// +// user_io.v - interface to MIST arm io controller +// +// Sinclair QL for the MiST +// https://github.com/mist-devel +// +// Copyright (c) 2015 Till Harbaum +// +// This source file is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This source file is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +// parameter STRLEN and the actual length of conf_str have to match + +module user_io #(parameter STRLEN=0) ( + input [(8*STRLEN)-1:0] conf_str, + + input SPI_CLK, + input SPI_SS_IO, + output reg SPI_MISO, + input SPI_MOSI, + + output reg [7:0] joystick_0, + output reg [7:0] joystick_1, + output reg [15:0] joystick_analog_0, + output reg [15:0] joystick_analog_1, + output [1:0] buttons, + output [1:0] switches, + output scandoubler_disable, + + output reg [7:0] status, + + // connection to sd card emulation + input [31:0] sd_lba, + input sd_rd, + input sd_wr, + output reg sd_ack, + input sd_conf, + input sd_sdhc, + output [7:0] sd_dout, // valid on rising edge of sd_dout_strobe + output reg sd_dout_strobe, + input [7:0] sd_din, + output reg sd_din_strobe, + output reg sd_change, + + // ps2 keyboard emulation + input ps2_clk, // 12-16khz provided by core + output ps2_kbd_clk, + output reg ps2_kbd_data, + output ps2_mouse_clk, + output reg ps2_mouse_data, + + // serial com port + input [7:0] serial_data, + input serial_strobe +); + +reg [6:0] sbuf; +reg [7:0] cmd; +reg [2:0] bit_cnt; // counts bits 0-7 0-7 ... +reg [7:0] byte_cnt; // counts bytes +reg [5:0] joystick0; +reg [5:0] joystick1; +reg [7:0] but_sw; +reg [2:0] stick_idx; + +assign buttons = but_sw[1:0]; +assign switches = but_sw[3:2]; +assign scandoubler_disable = but_sw[4]; +assign sd_dout = { sbuf, SPI_MOSI}; + +// this variant of user_io is for 8 bit cores (type == a4) only +wire [7:0] core_type = 8'ha4; + +// command byte read by the io controller +wire [7:0] sd_cmd = { 4'h5, sd_conf, sd_sdhc, sd_wr, sd_rd }; + +// filter spi clock. the 8 bit gate delay is ~2.5ns in total +wire [7:0] spi_sck_D = { spi_sck_D[6:0], SPI_CLK } /* synthesis keep */; +wire spi_sck = (spi_sck && spi_sck_D != 8'h00) || (!spi_sck && spi_sck_D == 8'hff); + +// drive MISO only when transmitting core id +always@(negedge spi_sck or posedge SPI_SS_IO) begin + if(SPI_SS_IO == 1) begin + SPI_MISO <= 1'bZ; + end else begin + + // first byte returned is always core type, further bytes are + // command dependent + if(byte_cnt == 0) begin + SPI_MISO <= core_type[~bit_cnt]; + + end else begin + // reading serial fifo + if(cmd == 8'h1b) begin + // send alternating flag byte and data + if(byte_cnt[0]) SPI_MISO <= serial_out_status[~bit_cnt]; + else SPI_MISO <= serial_out_byte[~bit_cnt]; + end + + // reading config string + else if(cmd == 8'h14) begin + // returning a byte from string + if(byte_cnt < STRLEN + 1) + SPI_MISO <= conf_str[{STRLEN - byte_cnt,~bit_cnt}]; + else + SPI_MISO <= 1'b0; + end + + // reading sd card status + else if(cmd == 8'h16) begin + if(byte_cnt == 1) + SPI_MISO <= sd_cmd[~bit_cnt]; + else if((byte_cnt >= 2) && (byte_cnt < 6)) + SPI_MISO <= sd_lba[{5-byte_cnt, ~bit_cnt}]; + else + SPI_MISO <= 1'b0; + end + + // reading sd card write data + else if(cmd == 8'h18) + SPI_MISO <= sd_din[~bit_cnt]; + + else + SPI_MISO <= 1'b0; + end + end +end + +// ---------------- PS2 --------------------- + +// 8 byte fifos to store ps2 bytes +localparam PS2_FIFO_BITS = 3; + +// keyboard +reg [7:0] ps2_kbd_fifo [(2**PS2_FIFO_BITS)-1:0]; +reg [PS2_FIFO_BITS-1:0] ps2_kbd_wptr; +reg [PS2_FIFO_BITS-1:0] ps2_kbd_rptr; + +// ps2 transmitter state machine +reg [3:0] ps2_kbd_tx_state; +reg [7:0] ps2_kbd_tx_byte; +reg ps2_kbd_parity; + +assign ps2_kbd_clk = ps2_clk || (ps2_kbd_tx_state == 0); + +// ps2 transmitter +// Takes a byte from the FIFO and sends it in a ps2 compliant serial format. +reg ps2_kbd_r_inc; +always@(posedge ps2_clk) begin + ps2_kbd_r_inc <= 1'b0; + + if(ps2_kbd_r_inc) + ps2_kbd_rptr <= ps2_kbd_rptr + 1; + + // transmitter is idle? + if(ps2_kbd_tx_state == 0) begin + // data in fifo present? + if(ps2_kbd_wptr != ps2_kbd_rptr) begin + // load tx register from fifo + ps2_kbd_tx_byte <= ps2_kbd_fifo[ps2_kbd_rptr]; + ps2_kbd_r_inc <= 1'b1; + + // reset parity + ps2_kbd_parity <= 1'b1; + + // start transmitter + ps2_kbd_tx_state <= 4'd1; + + // put start bit on data line + ps2_kbd_data <= 1'b0; // start bit is 0 + end + end else begin + + // transmission of 8 data bits + if((ps2_kbd_tx_state >= 1)&&(ps2_kbd_tx_state < 9)) begin + ps2_kbd_data <= ps2_kbd_tx_byte[0]; // data bits + ps2_kbd_tx_byte[6:0] <= ps2_kbd_tx_byte[7:1]; // shift down + if(ps2_kbd_tx_byte[0]) + ps2_kbd_parity <= !ps2_kbd_parity; + end + + // transmission of parity + if(ps2_kbd_tx_state == 9) + ps2_kbd_data <= ps2_kbd_parity; + + // transmission of stop bit + if(ps2_kbd_tx_state == 10) + ps2_kbd_data <= 1'b1; // stop bit is 1 + + // advance state machine + if(ps2_kbd_tx_state < 11) + ps2_kbd_tx_state <= ps2_kbd_tx_state + 4'd1; + else + ps2_kbd_tx_state <= 4'd0; + + end +end + +// mouse +reg [7:0] ps2_mouse_fifo [(2**PS2_FIFO_BITS)-1:0]; +reg [PS2_FIFO_BITS-1:0] ps2_mouse_wptr; +reg [PS2_FIFO_BITS-1:0] ps2_mouse_rptr; + +// ps2 transmitter state machine +reg [3:0] ps2_mouse_tx_state; +reg [7:0] ps2_mouse_tx_byte; +reg ps2_mouse_parity; + +assign ps2_mouse_clk = ps2_clk || (ps2_mouse_tx_state == 0); + +// ps2 transmitter +// Takes a byte from the FIFO and sends it in a ps2 compliant serial format. +reg ps2_mouse_r_inc; +always@(posedge ps2_clk) begin + ps2_mouse_r_inc <= 1'b0; + + if(ps2_mouse_r_inc) + ps2_mouse_rptr <= ps2_mouse_rptr + 1; + + // transmitter is idle? + if(ps2_mouse_tx_state == 0) begin + // data in fifo present? + if(ps2_mouse_wptr != ps2_mouse_rptr) begin + // load tx register from fifo + ps2_mouse_tx_byte <= ps2_mouse_fifo[ps2_mouse_rptr]; + ps2_mouse_r_inc <= 1'b1; + + // reset parity + ps2_mouse_parity <= 1'b1; + + // start transmitter + ps2_mouse_tx_state <= 4'd1; + + // put start bit on data line + ps2_mouse_data <= 1'b0; // start bit is 0 + end + end else begin + + // transmission of 8 data bits + if((ps2_mouse_tx_state >= 1)&&(ps2_mouse_tx_state < 9)) begin + ps2_mouse_data <= ps2_mouse_tx_byte[0]; // data bits + ps2_mouse_tx_byte[6:0] <= ps2_mouse_tx_byte[7:1]; // shift down + if(ps2_mouse_tx_byte[0]) + ps2_mouse_parity <= !ps2_mouse_parity; + end + + // transmission of parity + if(ps2_mouse_tx_state == 9) + ps2_mouse_data <= ps2_mouse_parity; + + // transmission of stop bit + if(ps2_mouse_tx_state == 10) + ps2_mouse_data <= 1'b1; // stop bit is 1 + + // advance state machine + if(ps2_mouse_tx_state < 11) + ps2_mouse_tx_state <= ps2_mouse_tx_state + 4'd1; + else + ps2_mouse_tx_state <= 4'd0; + + end +end + +// fifo to receive serial data from core to be forwarded to io controller + +// 16 byte fifo to store serial bytes +localparam SERIAL_OUT_FIFO_BITS = 6; +reg [7:0] serial_out_fifo [(2**SERIAL_OUT_FIFO_BITS)-1:0]; +reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_wptr; +reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_rptr; + +wire serial_out_data_available = serial_out_wptr != serial_out_rptr; +wire [7:0] serial_out_byte = serial_out_fifo[serial_out_rptr] /* synthesis keep */; +wire [7:0] serial_out_status = { 7'b1000000, serial_out_data_available}; + +// status[0] is reset signal from io controller and is thus used to flush +// the fifo +always @(posedge serial_strobe or posedge status[0]) begin + if(status[0] == 1) begin + serial_out_wptr <= 0; + end else begin + serial_out_fifo[serial_out_wptr] <= serial_data; + serial_out_wptr <= serial_out_wptr + 1; + end +end + +always@(negedge spi_sck or posedge status[0]) begin + if(status[0] == 1) begin + serial_out_rptr <= 0; + end else begin + if((byte_cnt != 0) && (cmd == 8'h1b)) begin + // read last bit -> advance read pointer + if((bit_cnt == 7) && !byte_cnt[0] && serial_out_data_available) + serial_out_rptr <= serial_out_rptr + 1; + end + end +end + +// SPI receiver +always@(posedge spi_sck or posedge SPI_SS_IO) begin + + if(SPI_SS_IO == 1) begin + bit_cnt <= 3'd0; + byte_cnt <= 8'd0; + sd_ack <= 1'b0; + sd_dout_strobe <= 1'b0; + sd_din_strobe <= 1'b0; + sd_change <= 1'b0; + end else begin + sd_dout_strobe <= 1'b0; + sd_din_strobe <= 1'b0; + + if(bit_cnt != 7) + sbuf[6:0] <= { sbuf[5:0], SPI_MOSI }; + + bit_cnt <= bit_cnt + 3'd1; + if((bit_cnt == 7)&&(byte_cnt != 8'd255)) + byte_cnt <= byte_cnt + 8'd1; + + // finished reading command byte + if(bit_cnt == 7) begin + if(byte_cnt == 0) begin + cmd <= { sbuf, SPI_MOSI}; + + // fetch first byte when sectore FPGA->IO command has been seen + if({ sbuf, SPI_MOSI} == 8'h18) + sd_din_strobe <= 1'b1; + + if(({ sbuf, SPI_MOSI} == 8'h17) || ({ sbuf, SPI_MOSI} == 8'h18)) + sd_ack <= 1'b1; + + end else begin + + // buttons and switches + if(cmd == 8'h01) + but_sw <= { sbuf, SPI_MOSI }; + + if(cmd == 8'h02) + joystick_0 <= { sbuf, SPI_MOSI }; + + if(cmd == 8'h03) + joystick_1 <= { sbuf, SPI_MOSI }; + + if(cmd == 8'h04) begin + // store incoming ps2 mouse bytes + ps2_mouse_fifo[ps2_mouse_wptr] <= { sbuf, SPI_MOSI }; + ps2_mouse_wptr <= ps2_mouse_wptr + 1; + end + + if(cmd == 8'h05) begin + // store incoming ps2 keyboard bytes + ps2_kbd_fifo[ps2_kbd_wptr] <= { sbuf, SPI_MOSI }; + ps2_kbd_wptr <= ps2_kbd_wptr + 1; + end + + if(cmd == 8'h15) + status <= { sbuf[6:0], SPI_MOSI }; + + // send sector IO -> FPGA + if(cmd == 8'h17) begin + // flag that download begins + sd_dout_strobe <= 1'b1; + end + + // send sector FPGA -> IO + if(cmd == 8'h18) + sd_din_strobe <= 1'b1; + + // send SD config IO -> FPGA + if(cmd == 8'h19) begin + // flag that download begins + // sd card knows data is config if sd_dout_strobe is asserted + // with sd_ack still being inactive (low) + sd_dout_strobe <= 1'b1; + end + + // joystick analog + if(cmd == 8'h1a) begin + // first byte is joystick indes + if(byte_cnt == 1) + stick_idx <= { sbuf[1:0], SPI_MOSI }; + else if(byte_cnt == 2) begin + // second byte is x axis + if(stick_idx == 0) + joystick_analog_0[15:8] <= { sbuf, SPI_MOSI }; + else if(stick_idx == 1) + joystick_analog_1[15:8] <= { sbuf, SPI_MOSI }; + end else if(byte_cnt == 3) begin + // third byte is y axis + if(stick_idx == 0) + joystick_analog_0[7:0] <= { sbuf, SPI_MOSI }; + else if(stick_idx == 1) + joystick_analog_1[7:0] <= { sbuf, SPI_MOSI }; + end + end + + // set sd card status. The fact that this register is being + // set by the arm controller indicates a possible disk change + if(cmd == 8'h1c) + sd_change <= 1'b1; + + end + end + end +end + +endmodule