From 275db15a8bb2ec99591fc577d61abda78d4a8040 Mon Sep 17 00:00:00 2001 From: RndMnkIII Date: Sat, 15 Aug 2026 11:45:32 +0200 Subject: [PATCH 1/3] Added experimental SNAC PS/2 Keyboard decoder --- pkg/pocket/Cores/boogermann.msx/core.json | 6 +- pkg/pocket/Cores/boogermann.msx/data.json | 12 ++ projects/msx_pocket.qsf | 75 +++++++- target/pocket/core_top.sv | 91 ++++++++-- target/pocket/ps2_host.sv | 206 ++++++++++++++++++++++ target/pocket/ps2_snac_decoder.sv | 115 ++++++++++++ tools/reverse_bitstream.py | 24 +++ 7 files changed, 506 insertions(+), 23 deletions(-) create mode 100644 target/pocket/ps2_host.sv create mode 100644 target/pocket/ps2_snac_decoder.sv create mode 100755 tools/reverse_bitstream.py diff --git a/pkg/pocket/Cores/boogermann.msx/core.json b/pkg/pocket/Cores/boogermann.msx/core.json index 004b89a..aadabca 100644 --- a/pkg/pocket/Cores/boogermann.msx/core.json +++ b/pkg/pocket/Cores/boogermann.msx/core.json @@ -2,9 +2,7 @@ "core": { "magic": "APF_VER_1", "metadata": { - "platform_ids": [ - "msx" - ], + "platform_ids": ["msx","analogizer"], "shortname": "msx", "description": "MSX is a standardized home computer architecture, announced by ASCII Corporation on June 16, 1983.", "author": "boogermann", @@ -22,7 +20,7 @@ }, "hardware": { "link_port": false, - "cartridge_adapter": -1 + "cartridge_adapter": 0 } }, "cores": [ diff --git a/pkg/pocket/Cores/boogermann.msx/data.json b/pkg/pocket/Cores/boogermann.msx/data.json index 7462848..7643178 100644 --- a/pkg/pocket/Cores/boogermann.msx/data.json +++ b/pkg/pocket/Cores/boogermann.msx/data.json @@ -33,6 +33,18 @@ "parameters": "0x109", "extensions": ["rom"], "address": "0x00000000" + }, + { + "name": "Analogizer config", + "id": 10, + "required": false, + "parameters": "0x1000000", + "filename": "analogizer.bin", + "extensions": [ + "bin" + ], + "address": "0xF7000000", + "nonvolatile": false } ] } diff --git a/projects/msx_pocket.qsf b/projects/msx_pocket.qsf index a3e6a04..8981f7d 100644 --- a/projects/msx_pocket.qsf +++ b/projects/msx_pocket.qsf @@ -10,7 +10,7 @@ # Project-Wide Assignments # ============================================================================== set_global_assignment -name ORIGINAL_QUARTUS_VERSION 17.0.0 -set_global_assignment -name LAST_QUARTUS_VERSION "17.1.0 Standard Edition" +set_global_assignment -name LAST_QUARTUS_VERSION "25.1std.0 Lite Edition" set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files set_global_assignment -name TOP_LEVEL_ENTITY apf_top @@ -54,19 +54,14 @@ set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION ON # ============================================================================== # Pin & Location Assignments # ============================================================================== -set_global_assignment -name SOURCE_TCL_SCRIPT_FILE ../platform/pocket/bsp/pocket/sys_assign.tcl # ============================================================================== # Platform Modules, Constrains and Chain Description File # ============================================================================== -set_global_assignment -name QIP_FILE msx_pocket.qip -set_global_assignment -name SDC_FILE msx_pocket.sdc -set_global_assignment -name CDF_FILE msx_pocket.cdf # ============================================================================== # Core RTL Assignments # ============================================================================== -set_global_assignment -name QIP_FILE ../rtl/index.qip # ============================================================================== # Incremental Compilation Assignments @@ -74,4 +69,72 @@ set_global_assignment -name QIP_FILE ../rtl/index.qip set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_global_assignment -name SYSTEMVERILOG_FILE ../target/pocket/ps2_snac_decoder.sv +set_global_assignment -name SOURCE_TCL_SCRIPT_FILE ../platform/pocket/bsp/pocket/sys_assign.tcl +set_global_assignment -name SOURCE_TCL_SCRIPT_FILE ../platform/pocket/bsp/setup.tcl +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/bsp/pocket/apf_top.sv +set_global_assignment -name SDC_FILE ../platform/pocket/bsp/pocket/sys_constr.sdc +set_global_assignment -name SOURCE_TCL_SCRIPT_FILE ../platform/pocket/pkgIndex.tcl +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/pocket_i2s.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/audio_mixer.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/arcade_filters.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/filter_loader.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/iir_filter.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/filters_rom.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/audio_mix.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/audio_filters.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/iir_filter_tap.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/dc_blocker.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/video/scanlines_generator.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/video/video_mixer.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/video/scanlines.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/video/shadowmask.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/gamepad.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/data_loader.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/usb_mouse.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/pause_crtl.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/joypad.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/mame_keymap_f.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/interact.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/data_unloader.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/mame_keymap.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/analog2dpad.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/key_ctl.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/key_arbiter.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/hid2ps2_key.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/usb_keyboard.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/key_mgr.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/kb_fifo.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/apf2hid.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/hid2ps2_mod.sv +set_global_assignment -name VERILOG_FILE ../platform/pocket/megafunctions/mf_audio_pll.v -library mf_audio_pll +set_global_assignment -name VERILOG_FILE ../platform/pocket/megafunctions/mf_datatable.v +set_global_assignment -name VERILOG_FILE ../platform/pocket/megafunctions/mf_ddio_bidir_12.v +set_global_assignment -name QIP_FILE ../platform/pocket/megafunctions/mf_audio_pll.qip +set_global_assignment -name QIP_FILE ../platform/pocket/megafunctions/mf_ddio_bidir_12.qip +set_global_assignment -name QIP_FILE ../platform/pocket/megafunctions/mf_datatable.qip +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/memory/spram_hs.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/memory/sram.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/memory/dpram_hs.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/peripherals/io_pad_controller.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/peripherals/core_bridge_cmd.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/peripherals/io_bridge_peripheral.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/data_io.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/save_io.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/hiscore.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/nvram.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/autofire.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/hiscore_io.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/helpers/synch_3.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/helpers/synch_2.sv +set_global_assignment -name QIP_FILE ../target/pocket/core.qip +set_global_assignment -name SOURCE_TCL_SCRIPT_FILE ../platform/pocket/bsp/pocket/pinouts/system.tcl +set_global_assignment -name QIP_FILE msx_pocket.qip +set_global_assignment -name SDC_FILE msx_pocket.sdc +set_global_assignment -name CDF_FILE msx_pocket.cdf +set_global_assignment -name QIP_FILE ../rtl/index.qip +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 +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)" set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/target/pocket/core_top.sv b/target/pocket/core_top.sv index 096b4b1..6785816 100644 --- a/target/pocket/core_top.sv +++ b/target/pocket/core_top.sv @@ -270,6 +270,9 @@ module core_top input wire [15:0] cont4_trig ); + //Analogizer settings + localparam [7:0] ADDRESS_ANALOGIZER_CONFIG = 8'hF7; + // not using the IR port, so turn off both the LED, and // disable the receive circuit to save power assign port_ir_tx = 0; @@ -280,19 +283,19 @@ module core_top // cart is unused, so set all level translators accordingly // directions are 0:IN, 1:OUT - assign cart_tran_bank3 = 8'hzz; - assign cart_tran_bank3_dir = 1'b0; - assign cart_tran_bank2 = 8'hzz; - assign cart_tran_bank2_dir = 1'b0; - assign cart_tran_bank1 = 8'hzz; - assign cart_tran_bank1_dir = 1'b0; - assign cart_tran_bank0 = 4'hf; - assign cart_tran_bank0_dir = 1'b1; - assign cart_tran_pin30 = 1'b0; // reset or cs2, we let the hw control it by itself - assign cart_tran_pin30_dir = 1'bz; - assign cart_pin30_pwroff_reset = 1'b0; // hardware can control this - assign cart_tran_pin31 = 1'bz; // input - assign cart_tran_pin31_dir = 1'b0; // input + // assign cart_tran_bank3 = 8'hzz; + // assign cart_tran_bank3_dir = 1'b0; + // assign cart_tran_bank2 = 8'hzz; + // assign cart_tran_bank2_dir = 1'b0; + // assign cart_tran_bank1 = 8'hzz; + // assign cart_tran_bank1_dir = 1'b0; + // assign cart_tran_bank0 = 4'hf; + // assign cart_tran_bank0_dir = 1'b1; + // assign cart_tran_pin30 = 1'b0; // reset or cs2, we let the hw control it by itself + // assign cart_tran_pin30_dir = 1'bz; + // assign cart_pin30_pwroff_reset = 1'b0; // hardware can control this + // assign cart_tran_pin31 = 1'bz; // input + // assign cart_tran_pin31_dir = 1'b0; // input // link port is input only assign port_tran_so = 1'bz; @@ -532,6 +535,8 @@ module core_top wire [31:0] int_bridge_rd_data; wire [31:0] nvm_bridge_rd_data, nvm_bridge_rd_data_s; + wire [31:0] analogizer_bridge_rd_data; + // Synchronize nvm_bridge_rd_data into clk_74a domain before usage synch_3 sync_nvm(nvm_bridge_rd_data, nvm_bridge_rd_data_s, clk_74a); @@ -548,6 +553,9 @@ module core_top 32'hFA000000: begin bridge_rd_data <= int_bridge_rd_data; end // Status Low [31:0] 32'hFB000000: begin bridge_rd_data <= int_bridge_rd_data; end // Status High [63:32] 32'hFE000000: begin bridge_rd_data <= {29'h0, mapper_info}; end + {ADDRESS_ANALOGIZER_CONFIG,24'h0}: begin + bridge_rd_data <= analogizer_bridge_rd_data; + end // Analogizer default: begin bridge_rd_data <= 0; end endcase end @@ -615,6 +623,13 @@ module core_top .reset_sw ( reset_sw ) ); + + logic ena_analogizer = 0; + + always @(posedge clk_74a) begin + if (bridge_wr && bridge_addr == 32'hf4000000) ena_analogizer <= bridge_wr_data[0]; + end + //! ------------------------------------------------------------------------ //! Audio //! ------------------------------------------------------------------------ @@ -1050,4 +1065,54 @@ module core_top // .rewind ( CAS_rewind ) // ); + + // ======================================================================== + // SNAC (Conf. A) PS/2 sobre cart_tran_pin30 (CLK) y cart_tran_pin31 (DATA) + // Solo recepcion: dir = 0 (los level-translators en modo cart->FPGA) + // ======================================================================== + logic ps2_clk_oe, ps2_dat_oe; + logic ps2_clk_out, ps2_dat_out; + logic ps2_clk_in, ps2_dat_in; + logic [10:0] snac_ps2_key; + + // --- Direccion de los translators: 0 = INPUT (leemos del teclado) + assign cart_tran_pin30_dir = ps2_clk_oe; // = 1'b0 constante + assign cart_tran_pin31_dir = ps2_dat_oe; // = 1'b0 constante + + // --- IMPRESCINDIBLE en pin30: habilitar el circuito del translator. + // Debe ir a '1' para que los level-translators e IO general + // puedan mover el pin. Si lo dejas bajo/debil, el pull GBC /RES + // se activa y el pin no funciona. + assign cart_pin30_pwroff_reset = (ena_analogizer) ? 1'b1 : 1'bz; + + // --- Como no conducimos, dejamos los inout en Z desde la FPGA. + // (dir=0 ya pone el translator en cart->FPGA; el 'z' evita + // que la FPGA pelee el bus si algun sintetizador lo tomara literal) + assign cart_tran_pin30 = (ena_analogizer) ? (ps2_clk_oe ? ps2_clk_out : 1'bz) : 1'bz; // -> queda 1'bz + assign cart_tran_pin31 = (ena_analogizer) ? (ps2_dat_oe ? ps2_dat_out : 1'bz) : 1'bz; // -> queda 1'bz + + // --- Lectura de las lineas hacia el decoder + assign ps2_clk_in = (ena_analogizer) ? cart_tran_pin30 : 1'b1; // CLK del teclado + assign ps2_dat_in = (ena_analogizer) ? cart_tran_pin31 : 1'b1; // DATA del teclado + + ps2_snac_decoder + #( + .CLK_HZ(5_369_317), //! Frecuencia de clk + . WD_US(120) //! Timeout de trama (us) para resync + ) + ps2_snac + ( + .clk(clk_vid), + .reset(msx_reset | reset_sw ), + // Interfaz hacia el transceptor SNAC (unidireccional + control de sentido) + .ps2_clk_in(ps2_clk_in), //! CLK leido del transceptor (modo RX) + .ps2_dat_in(ps2_dat_in), //! DATA leido del transceptor (modo RX) + .ps2_clk_oe(ps2_clk_oe), //! 1 = FPGA conduce CLK (aqui siempre 0) + .ps2_dat_oe(ps2_dat_oe), //! 1 = FPGA conduce DATA (aqui siempre 0) + .ps2_clk_out(ps2_clk_out ), //! valor a emitir si oe=1 (idle 1) + .ps2_dat_out(ps2_dat_out), //! valor a emitir si oe=1 (idle 1) + // Salida decodificada + .ps2_key(snac_ps2_key) //! {toggle, pressed, ext, sc[7:0]} + ); + endmodule diff --git a/target/pocket/ps2_host.sv b/target/pocket/ps2_host.sv new file mode 100644 index 0000000..98823d9 --- /dev/null +++ b/target/pocket/ps2_host.sv @@ -0,0 +1,206 @@ +// ===================================================================== +// ps2_host.sv +// Bidirectional PS/2 host controller for open-collector lines driven +// through tri-state (dir-controlled) FPGA pins, e.g. Analogue Pocket +// cart pins 30/31 via the Analogizer SNAC harness. +// +// The module NEVER drives a line high. Each line is only ever: +// released -> *_oe = 0 (pin = input / Hi-Z, external pull-up -> '1') +// driven low -> *_oe = 1 (pin = output, data hard-wired to 1'b0) +// +// Wiring in core_top (verify APF dir polarity: here 1 = OUTPUT): +// assign cart_tran_pin30 = 1'b0; +// assign cart_tran_pin30_dir = ps2_clk_oe; // 1 => drive '0' +// assign ps2_clk_i = cart_tran_pin30; // reads pin when Hi-Z +// assign cart_tran_pin31 = 1'b0; +// assign cart_tran_pin31_dir = ps2_dat_oe; +// assign ps2_dat_i = cart_tran_pin31; +// // Also gate with cart_pin30_pwroff_reset as needed. +// +// Frame format: +// device->host : start(0) d0..d7(LSB) parity(odd) stop(1) +// host->device : inhibit CLK >=100us, DATA low (start), release CLK, +// device clocks 8 data + parity + stop, then drives ACK. +// ===================================================================== +module ps2_host #( + parameter int CLK_HZ = 50_000_000 +)( + input logic clk, + input logic rst, // synchronous, active high + + // Open-collector line interface (to dir-controlled pins) + input logic ps2_clk_i, // raw pin value (valid when released) + input logic ps2_dat_i, + output logic ps2_clk_oe, // 1 => pull CLK low + output logic ps2_dat_oe, // 1 => pull DATA low + + // Receive (device -> host) + output logic [7:0] rx_data, + output logic rx_valid, // 1-cycle strobe + output logic rx_err, // 1-cycle strobe (parity/framing) + + // Transmit (host -> device) + input logic [7:0] tx_data, + input logic tx_send, // 1-cycle strobe to start + output logic tx_busy, + output logic tx_done, // 1-cycle strobe, ACK received + output logic tx_err // 1-cycle strobe, no ACK / timeout +); + + // ---------------- timing ---------------- + localparam int US = CLK_HZ / 1_000_000; + localparam int INHIBIT_CYC = US * 120; // ~120 us CLK-low inhibit + localparam int WATCHDOG_CYC= US * 200; // abort if line goes idle mid-frame + + // ---------------- input sync + debounce ---------------- + logic [1:0] clk_sync, dat_sync; + always_ff @(posedge clk) begin + clk_sync <= {clk_sync[0], ps2_clk_i}; + dat_sync <= {dat_sync[0], ps2_dat_i}; + end + wire clk_s = clk_sync[1]; + wire dat_bit = dat_sync[1]; + + localparam int FILT = 4; + logic [FILT-1:0] clk_filt; + logic clk_stable, clk_stable_d; + always_ff @(posedge clk) begin + clk_filt <= {clk_filt[FILT-2:0], clk_s}; + if (&clk_filt) clk_stable <= 1'b1; + else if (~|clk_filt) clk_stable <= 1'b0; + clk_stable_d <= clk_stable; + end + wire clk_fedge = clk_stable_d & ~clk_stable; + wire clk_redge = ~clk_stable_d & clk_stable; + + // ---------------- FSM ---------------- + typedef enum logic [3:0] { + S_IDLE, RX_BITS, + TX_INHIBIT, TX_BITS, TX_STOP, TX_ACK + } state_t; + + state_t state; + logic [3:0] bitcnt; + logic [7:0] rxbuf; + logic rx_par; + logic [8:0] tx_shift; // {parity, d7..d0}, shifted out from bit0 + logic [31:0] timer; + + always_ff @(posedge clk) begin + // default strobes low + rx_valid <= 1'b0; + rx_err <= 1'b0; + tx_done <= 1'b0; + tx_err <= 1'b0; + + if (rst) begin + state <= S_IDLE; + ps2_clk_oe <= 1'b0; + ps2_dat_oe <= 1'b0; + tx_busy <= 1'b0; + bitcnt <= '0; + timer <= '0; + end else begin + case (state) + // -------------------------------------------------- IDLE + S_IDLE: begin + ps2_clk_oe <= 1'b0; + ps2_dat_oe <= 1'b0; + tx_busy <= 1'b0; + bitcnt <= '0; + if (tx_send) begin + tx_busy <= 1'b1; + ps2_clk_oe <= 1'b1; // begin inhibit + timer <= INHIBIT_CYC; + tx_shift <= {~(^tx_data), tx_data}; // odd parity + state <= TX_INHIBIT; + end else if (clk_fedge && (dat_bit == 1'b0)) begin + // start bit of an incoming frame + bitcnt <= 4'd0; + timer <= WATCHDOG_CYC; + state <= RX_BITS; + end + end + // -------------------------------------------------- RX + RX_BITS: begin + // watchdog: reset while CLK toggles, abort if idle too long + if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; + else if (timer != 0) timer <= timer - 1; + + if (timer == 0) begin + rx_err <= 1'b1; + state <= S_IDLE; + end else if (clk_fedge) begin + case (bitcnt) + 4'd0,4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7: + rxbuf[bitcnt[2:0]] <= dat_bit; + 4'd8: rx_par <= dat_bit; // parity + default: ; // 4'd9 = stop + endcase + bitcnt <= bitcnt + 4'd1; + if (bitcnt == 4'd9) begin // stop bit now on dat_bit + // odd parity: XOR of 8 data + parity must be 1; stop==1 + if ((^{rxbuf, rx_par}) == 1'b1 && dat_bit == 1'b1) begin + rx_data <= rxbuf; + rx_valid <= 1'b1; + end else begin + rx_err <= 1'b1; + end + state <= S_IDLE; + end + end + end + // -------------------------------------------------- TX + TX_INHIBIT: begin + ps2_clk_oe <= 1'b1; // hold CLK low + if (timer != 0) timer <= timer - 1; + if (timer == 0) begin + ps2_dat_oe <= 1'b1; // DATA low = start/request + ps2_clk_oe <= 1'b0; // release CLK + bitcnt <= 4'd0; + timer <= WATCHDOG_CYC; + state <= TX_BITS; + end + end + TX_BITS: begin + if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; + else if (timer != 0) timer <= timer - 1; + + if (timer == 0) begin + ps2_dat_oe <= 1'b0; ps2_clk_oe <= 1'b0; + tx_err <= 1'b1; state <= S_IDLE; + end else if (clk_fedge) begin + ps2_dat_oe <= ~tx_shift[0]; // '0' => drive low, '1' => release + tx_shift <= {1'b0, tx_shift[8:1]}; + bitcnt <= bitcnt + 4'd1; + if (bitcnt == 4'd8) state <= TX_STOP; // presented d0..d7,parity + end + end + TX_STOP: begin + if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; + else if (timer != 0) timer <= timer - 1; + + if (timer == 0) begin + ps2_dat_oe <= 1'b0; tx_err <= 1'b1; state <= S_IDLE; + end else if (clk_fedge) begin + ps2_dat_oe <= 1'b0; // release DATA (stop) + state <= TX_ACK; + end + end + TX_ACK: begin + if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; + else if (timer != 0) timer <= timer - 1; + + if (timer == 0) begin + tx_err <= 1'b1; state <= S_IDLE; + end else if (clk_fedge) begin + if (dat_bit == 1'b0) tx_done <= 1'b1; // device pulled DATA low = ACK + else tx_err <= 1'b1; + state <= S_IDLE; + end + end + default: state <= S_IDLE; + endcase + end + end +endmodule \ No newline at end of file diff --git a/target/pocket/ps2_snac_decoder.sv b/target/pocket/ps2_snac_decoder.sv new file mode 100644 index 0000000..13e699d --- /dev/null +++ b/target/pocket/ps2_snac_decoder.sv @@ -0,0 +1,115 @@ +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +//------------------------------------------------------------------------------ +// ps2_snac_decoder — Host-side PS/2 (Set 2) via transceptores de bus SNAC. +// Sin tri-state en FPGA: por cada linea se exponen in / out / oe. +// Para teclado MSX solo se recibe => oe=0 permanente (transceptor en RX). +// Salida: ps2_key[10:0] formato MiSTer {toggle, pressed, ext, sc[7:0]} +//------------------------------------------------------------------------------ +`default_nettype none +`timescale 1ns/1ps + +module ps2_snac_decoder + #( + parameter int CLK_HZ = 50_000_000, //! Frecuencia de clk + parameter int WD_US = 120 //! Timeout de trama (us) para resync + ) + ( + input logic clk, + input logic reset, + // Interfaz hacia el transceptor SNAC (unidireccional + control de sentido) + input logic ps2_clk_in, //! CLK leido del transceptor (modo RX) + input logic ps2_dat_in, //! DATA leido del transceptor (modo RX) + output logic ps2_clk_oe, //! 1 = FPGA conduce CLK (aqui siempre 0) + output logic ps2_dat_oe, //! 1 = FPGA conduce DATA (aqui siempre 0) + output logic ps2_clk_out, //! valor a emitir si oe=1 (idle 1) + output logic ps2_dat_out, //! valor a emitir si oe=1 (idle 1) + // Salida decodificada + output logic [10:0] ps2_key //! {toggle, pressed, ext, sc[7:0]} + ); + + localparam int WD_MAX = (CLK_HZ/1_000_000)*WD_US; + + // Solo recepcion: nunca conducimos el bus. Idle alto por las pull-up a 5V. + assign ps2_clk_oe = 1'b0; + assign ps2_dat_oe = 1'b0; + assign ps2_clk_out = 1'b1; + assign ps2_dat_out = 1'b1; + + //! ---- Sync 2FF + flanco de bajada de PS2_CLK ------------------------- + logic [2:0] clk_sr; + logic [1:0] dat_sr; + always_ff @(posedge clk) begin + if (reset) begin clk_sr <= 3'b111; dat_sr <= 2'b11; end + else begin clk_sr <= {clk_sr[1:0], ps2_clk_in}; + dat_sr <= {dat_sr[0], ps2_dat_in}; end + end + wire ps2_clk_fall = (clk_sr[2:1] == 2'b10); + wire ps2_data_s = dat_sr[1]; + + //! ---- Recepcion trama 11 bits (start,8 LSB-first,parity impar,stop) --- + logic [10:0] shreg; + logic [3:0] bit_cnt; + logic rx_busy; + logic [$clog2(WD_MAX+1)-1:0] wd_free; + logic byte_valid; + logic [7:0] byte_data; + + always_ff @(posedge clk) begin + if (reset) begin + bit_cnt<=0; rx_busy<=0; shreg<=11'h7FF; wd_free<='0; + byte_valid<=0; byte_data<=8'h00; + end else begin + byte_valid <= 1'b0; + if (rx_busy) begin + wd_free <= wd_free + 1'b1; + if (wd_free >= WD_MAX[$bits(wd_free)-1:0]) begin + rx_busy<=0; bit_cnt<=0; + end + end else wd_free <= '0; + + if (ps2_clk_fall) begin + wd_free <= '0; + if (!rx_busy) begin + if (ps2_data_s == 1'b0) begin // start valido + rx_busy<=1'b1; bit_cnt<=4'd1; shreg<={ps2_data_s,10'h000}; + end + end else begin + shreg <= {ps2_data_s, shreg[10:1]}; + bit_cnt <= bit_cnt + 4'd1; + if (bit_cnt == 4'd10) begin + rx_busy<=1'b0; bit_cnt<=4'd0; + if ((^{shreg[9],shreg[8:1]}==1'b1) && (shreg[10]==1'b1)) begin + byte_valid<=1'b1; byte_data<=shreg[8:1]; + end + end + end + end + end + end + + //! ---- FSM Set 2: E0 (extendido) + F0 (break) -------------------------- + logic ext_f, brk_f, tgl; + logic out_pressed, out_ext; + logic [7:0] out_sc; + + always_ff @(posedge clk) begin + if (reset) begin + ext_f<=0; brk_f<=0; tgl<=0; + out_pressed<=0; out_ext<=0; out_sc<=8'h00; + end else if (byte_valid) begin + case (byte_data) + 8'hE0: ext_f<=1'b1; + 8'hF0: brk_f<=1'b1; + 8'hE1: begin ext_f<=1'b0; brk_f<=1'b0; end // Pause: ignorado + default: begin + out_sc<=byte_data; out_ext<=ext_f; out_pressed<=~brk_f; + tgl<=~tgl; ext_f<=1'b0; brk_f<=1'b0; + end + endcase + end + end + + assign ps2_key = {tgl, out_pressed, out_ext, out_sc}; + +endmodule \ No newline at end of file diff --git a/tools/reverse_bitstream.py b/tools/reverse_bitstream.py new file mode 100755 index 0000000..a2bd6e4 --- /dev/null +++ b/tools/reverse_bitstream.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +"""Reverse bits in each byte of an RBF file for Analogue Pocket.""" +import sys + +# bit-reversal lookup table; bytes.translate does the file in one C-level pass +REVERSE_TABLE = bytes(int(f'{i:08b}'[::-1], 2) for i in range(256)) + + +def main(): + if len(sys.argv) != 3: + print(f"Usage: {sys.argv[0]} input.rbf output.rbf_r") + sys.exit(1) + + with open(sys.argv[1], 'rb') as f: + data = f.read() + + with open(sys.argv[2], 'wb') as f: + f.write(data.translate(REVERSE_TABLE)) + + print(f"Reversed {len(data)} bytes: {sys.argv[1]} -> {sys.argv[2]}") + + +if __name__ == '__main__': + main() From aae3e85ad2063b3bff95a05a577f65d19f89675d Mon Sep 17 00:00:00 2001 From: RndMnkIII Date: Fri, 21 Aug 2026 20:04:19 +0200 Subject: [PATCH 2/3] added Analogizer adapter support with PS/2 keyboard + NES/SNES/DB15 SNAC game controllers --- .github/FUNDING.yml | 12 +- .github/ISSUE_TEMPLATE/BUG_REPORT.yml | 164 +- .github/ISSUE_TEMPLATE/QUESTION.yml | 58 +- .github/PULL_REQUEST_TEMPLATE.md | 88 +- .github/workflows/build.yml | 98 +- .gitignore | 138 +- ANALOGIZER.md | 103 + LICENSE | 1348 ++--- docs/CODE_OF_CONDUCT.md | 128 +- docs/README.md | 274 +- gateware.json | 90 +- modules/cpu-t80/GBse.vhd | 410 +- modules/cpu-t80/README.md | 110 +- modules/cpu-t80/T16450.vhd | 918 ++-- modules/cpu-t80/T80.vhd | 2676 +++++----- modules/cpu-t80/T8080se.vhd | 388 +- modules/cpu-t80/T80_ALU.vhd | 818 +-- modules/cpu-t80/T80_MCode.vhd | 4578 ++++++++--------- modules/cpu-t80/T80_Pack.vhd | 496 +- modules/cpu-t80/T80_Reg.vhd | 304 +- modules/cpu-t80/T80a.vhd | 684 +-- modules/cpu-t80/T80as.vhd | 578 +-- modules/cpu-t80/T80pa.vhd | 428 +- modules/cpu-t80/T80s.vhd | 386 +- modules/cpu-t80/T80se.vhd | 384 +- modules/cpu-t80/T80sed.vhd | 358 +- modules/cpu-t80/Z80.vhd | 270 +- modules/cpu-t80/index.qip | 24 +- modules/sound-jt49/filter/jt49_dcrm.v | 110 +- modules/sound-jt49/filter/jt49_dcrm2.v | 126 +- modules/sound-jt49/filter/jt49_dly.v | 132 +- modules/sound-jt49/filter/jt49_mave.v | 118 +- modules/sound-jt49/index.qip | 14 +- modules/sound-jt49/jt49.v | 504 +- modules/sound-jt49/jt49_bus.v | 200 +- modules/sound-jt49/jt49_cen.v | 110 +- modules/sound-jt49/jt49_div.v | 104 +- modules/sound-jt49/jt49_eg.v | 176 +- modules/sound-jt49/jt49_exp.v | 348 +- modules/sound-jt49/jt49_noise.v | 122 +- modules/video-vdp18/COPYING | 680 +-- modules/video-vdp18/README | 402 +- modules/video-vdp18/index.qip | 28 +- modules/video-vdp18/vdp18_addr_mux.vhd | 456 +- modules/video-vdp18/vdp18_clk_gen.vhd | 308 +- modules/video-vdp18/vdp18_col_mux.vhd | 396 +- modules/video-vdp18/vdp18_col_pack-p.vhd | 166 +- modules/video-vdp18/vdp18_core.vhd | 808 +-- modules/video-vdp18/vdp18_cpuio.vhd | 1140 ++-- modules/video-vdp18/vdp18_ctrl.vhd | 748 +-- modules/video-vdp18/vdp18_hor_vert.vhd | 408 +- modules/video-vdp18/vdp18_pack-p.vhd | 480 +- modules/video-vdp18/vdp18_pattern.vhd | 466 +- modules/video-vdp18/vdp18_sprite.vhd | 884 ++-- pkg/pocket/Cores/boogermann.msx/audio.json | 8 +- pkg/pocket/Cores/boogermann.msx/core.json | 66 +- pkg/pocket/Cores/boogermann.msx/data.json | 100 +- pkg/pocket/Cores/boogermann.msx/info.txt | 8 +- pkg/pocket/Cores/boogermann.msx/input.json | 42 +- pkg/pocket/Cores/boogermann.msx/interact.json | 439 +- pkg/pocket/Cores/boogermann.msx/variants.json | 10 +- pkg/pocket/Cores/boogermann.msx/video.json | 54 +- pkg/pocket/Platforms/msx.json | 14 +- platform/pocket/audio/audio_mixer.sv | 314 +- .../pocket/audio/filters/arcade_filters.sv | 282 +- .../pocket/audio/filters/audio_filters.sv | 408 +- platform/pocket/audio/filters/audio_mix.sv | 134 +- platform/pocket/audio/filters/dc_blocker.sv | 142 +- .../pocket/audio/filters/filter_loader.sv | 222 +- platform/pocket/audio/filters/filters_rom.sv | 346 +- platform/pocket/audio/filters/iir_filter.sv | 330 +- .../pocket/audio/filters/iir_filter_tap.sv | 180 +- platform/pocket/audio/pocket_i2s.sv | 140 +- platform/pocket/bsp/pocket/apf_top.sv | 928 ++-- platform/pocket/bsp/pocket/pinouts/system.tcl | 1518 +++--- platform/pocket/bsp/pocket/sys_assign.tcl | 142 +- platform/pocket/bsp/pocket/sys_constr.sdc | 200 +- platform/pocket/bsp/setup.tcl | 110 +- platform/pocket/helpers/synch_2.sv | 142 +- platform/pocket/helpers/synch_3.sv | 142 +- platform/pocket/interface/analog2dpad.sv | 156 +- platform/pocket/interface/data_loader.sv | 426 +- platform/pocket/interface/data_unloader.sv | 508 +- platform/pocket/interface/gamepad.sv | 574 +-- platform/pocket/interface/interact.sv | 342 +- platform/pocket/interface/joypad.sv | 254 +- platform/pocket/interface/keyboard/apf2hid.sv | 166 +- .../pocket/interface/keyboard/hid2ps2_key.sv | 464 +- .../pocket/interface/keyboard/hid2ps2_mod.sv | 104 +- platform/pocket/interface/keyboard/kb_fifo.sv | 266 +- .../pocket/interface/keyboard/key_arbiter.sv | 230 +- platform/pocket/interface/keyboard/key_ctl.sv | 222 +- platform/pocket/interface/keyboard/key_mgr.sv | 338 +- .../pocket/interface/keyboard/usb_keyboard.sv | 290 +- platform/pocket/interface/mame_keymap.sv | 266 +- platform/pocket/interface/mame_keymap_f.sv | 312 +- platform/pocket/interface/pause_crtl.sv | 96 +- platform/pocket/interface/usb_mouse.sv | 190 +- .../pocket/megafunctions/mf_audio_pll.qip | 674 +-- platform/pocket/megafunctions/mf_audio_pll.v | 510 +- .../mf_audio_pll/mf_audio_pll_0002.qip | 8 +- .../mf_audio_pll/mf_audio_pll_0002.v | 180 +- .../pocket/megafunctions/mf_datatable.qip | 8 +- platform/pocket/megafunctions/mf_datatable.v | 492 +- .../pocket/megafunctions/mf_ddio_bidir_12.qip | 10 +- .../pocket/megafunctions/mf_ddio_bidir_12.v | 268 +- platform/pocket/memory/dpram_hs.sv | 160 +- platform/pocket/memory/spram_hs.sv | 126 +- platform/pocket/memory/sram.sv | 130 +- .../pocket/peripherals/core_bridge_cmd.sv | 1214 ++--- .../peripherals/io_bridge_peripheral.sv | 638 +-- .../pocket/peripherals/io_pad_controller.sv | 632 +-- platform/pocket/pkgIndex.tcl | 136 +- platform/pocket/scripts/functions.tcl | 750 +-- platform/pocket/scripts/post_flow.tcl | 70 +- platform/pocket/scripts/pre_flow.tcl | 24 +- platform/pocket/support/autofire.sv | 150 +- platform/pocket/support/data_io.sv | 214 +- platform/pocket/support/hiscore.sv | 1478 +++--- platform/pocket/support/hiscore_io.sv | 514 +- platform/pocket/support/nvram.sv | 514 +- platform/pocket/support/save_io.sv | 278 +- platform/pocket/video/scanlines.sv | 222 +- platform/pocket/video/scanlines_generator.sv | 242 +- platform/pocket/video/shadowmask.sv | 364 +- platform/pocket/video/video_mixer.sv | 432 +- projects/dbg_snac_ps2_scancodes.stp | 179 + projects/msx_pocket.qip | 18 +- projects/msx_pocket.qpf | 22 +- projects/msx_pocket.qsf | 281 +- projects/msx_pocket.sdc | 122 +- rtl/bram.vhd | 382 +- rtl/cart/ascii16.v | 150 +- rtl/cart/ascii8.v | 146 +- rtl/cart/gamemaster2.v | 134 +- rtl/cart/konami.v | 126 +- rtl/cart/konami_scc.v | 226 +- rtl/cart/ram.vhd | 126 +- rtl/cart/rom.v | 470 +- rtl/cart/rom_detect.v | 256 +- rtl/cart/scc_wave.vhd | 966 ++-- rtl/cart/vy0010.v | 308 +- rtl/cart/wd1793.sv | 1828 +++---- rtl/cv_clock.vhd | 186 +- rtl/index.qip | 76 +- rtl/io_decoder.v | 86 +- rtl/joy2ps2.sv | 484 +- rtl/jt8255.v | 524 +- rtl/keyboard.vhd | 346 +- rtl/ls74.sv | 80 +- rtl/memory_mapper.v | 152 +- rtl/msx1.sv | 894 ++-- rtl/rom/cbios_main_msx1.mif | 2764 +++++----- rtl/rom/cbios_main_msx1_eu.mif | 2764 +++++----- rtl/rom/vy0010.mif | 1392 ++--- rtl/sdram.sv | 472 +- rtl/slots.sv | 542 +- rtl/tape.sv | 472 +- target/pocket/analogizer/analogizer.qip | 14 + target/pocket/analogizer/analogizer_psx.sv | 210 + .../pocket/analogizer/clock_divider_fract.v | 17 + target/pocket/analogizer/csync.v | 34 + .../pocket/analogizer/dualshock_controller.v | 365 ++ target/pocket/analogizer/hq2x.sv | 371 ++ .../analogizer/openFPGA_Pocket_Analogizer.v | 531 ++ .../openFPGA_Pocket_Analogizer_SNAC.sv | 584 +++ .../pcengine_game_controller_multitap.v | 233 + target/pocket/analogizer/pcengine_gc.v | 195 + target/pocket/analogizer/psPAD_top.v | 664 +++ target/pocket/analogizer/psx_control.v | 123 + target/pocket/analogizer/scandoubler.v | 289 ++ target/pocket/analogizer/scandoubler_2.v | 211 + target/pocket/analogizer/scanlines.v | 68 + .../pocket/analogizer/scanlines_analogizer.v | 68 + target/pocket/analogizer/serlatch_gc.v | 367 ++ target/pocket/analogizer/sine_lut.mem | 256 + target/pocket/analogizer/sync_fix.v | 28 + .../analogizer/two_button_press_detector.v | 53 + target/pocket/analogizer/uart_tx.v | 147 + target/pocket/analogizer/vga_out_sw.v | 72 + target/pocket/analogizer/yc_out.sv | 275 + target/pocket/analogizer/yc_out_legacy.sv | 239 + target/pocket/core.qip | 10 +- target/pocket/core_pll/core_pll.ppf | 32 +- target/pocket/core_pll/core_pll.qip | 674 +-- target/pocket/core_pll/core_pll.v | 518 +- .../core_pll/core_pll/core_pll_0002.qip | 8 +- .../pocket/core_pll/core_pll/core_pll_0002.v | 192 +- target/pocket/core_top.sv | 2478 +++++---- target/pocket/debounce.vhd | 58 + target/pocket/ps2_host.sv | 410 +- target/pocket/ps2_keyboard.vhd | 108 + target/pocket/ps2_mouse.vhd | 172 + target/pocket/ps2_snac_decoder.sv | 231 +- target/pocket/ps2_to_key.sv | 96 + target/pocket/ps2_transceiver.vhd | 181 + tools/reverse_bitstream.py | 48 +- 197 files changed, 40980 insertions(+), 34432 deletions(-) create mode 100644 ANALOGIZER.md create mode 100644 projects/dbg_snac_ps2_scancodes.stp create mode 100644 target/pocket/analogizer/analogizer.qip create mode 100644 target/pocket/analogizer/analogizer_psx.sv create mode 100644 target/pocket/analogizer/clock_divider_fract.v create mode 100644 target/pocket/analogizer/csync.v create mode 100644 target/pocket/analogizer/dualshock_controller.v create mode 100644 target/pocket/analogizer/hq2x.sv create mode 100644 target/pocket/analogizer/openFPGA_Pocket_Analogizer.v create mode 100644 target/pocket/analogizer/openFPGA_Pocket_Analogizer_SNAC.sv create mode 100644 target/pocket/analogizer/pcengine_game_controller_multitap.v create mode 100644 target/pocket/analogizer/pcengine_gc.v create mode 100644 target/pocket/analogizer/psPAD_top.v create mode 100644 target/pocket/analogizer/psx_control.v create mode 100644 target/pocket/analogizer/scandoubler.v create mode 100644 target/pocket/analogizer/scandoubler_2.v create mode 100644 target/pocket/analogizer/scanlines.v create mode 100644 target/pocket/analogizer/scanlines_analogizer.v create mode 100644 target/pocket/analogizer/serlatch_gc.v create mode 100644 target/pocket/analogizer/sine_lut.mem create mode 100644 target/pocket/analogizer/sync_fix.v create mode 100644 target/pocket/analogizer/two_button_press_detector.v create mode 100644 target/pocket/analogizer/uart_tx.v create mode 100644 target/pocket/analogizer/vga_out_sw.v create mode 100644 target/pocket/analogizer/yc_out.sv create mode 100644 target/pocket/analogizer/yc_out_legacy.sv create mode 100644 target/pocket/debounce.vhd create mode 100644 target/pocket/ps2_keyboard.vhd create mode 100644 target/pocket/ps2_mouse.vhd create mode 100644 target/pocket/ps2_to_key.sv create mode 100644 target/pocket/ps2_transceiver.vhd diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 3fbbe35..6d0e636 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,6 +1,6 @@ -##################################################################### -# SPDX-License-Identifier: CC0-1.0 -# SPDX-FileType: OTHER -# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors -##################################################################### -ko_fi: boogermann +##################################################################### +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileType: OTHER +# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors +##################################################################### +ko_fi: boogermann diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.yml b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml index 194e532..28ae35a 100644 --- a/.github/ISSUE_TEMPLATE/BUG_REPORT.yml +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.yml @@ -1,82 +1,82 @@ -##################################################################### -# SPDX-License-Identifier: CC0-1.0 -# SPDX-FileType: OTHER -# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors -##################################################################### -name: "Bug Report" -description: "Let us know about an unexpected error, a crash, or an incorrect behavior." -title: 'Title of your Bug Report' -labels: - - bug -assignees: - - boogermann -body: - - type: markdown - attributes: - value: | - Hi there, - - Thank you for opening an issue. Please note that we try to keep the issue tracker reserved for bug reports. - Make sure to [search for existing issues](https://github.com/opengateware/computer-msx/issues?q=label%3Abug) before filing a new one! - - - type: input - id: version - attributes: - label: Version (or build number) - placeholder: "1.0.0" - description: | - You can find the version in the about dialog. - - If you are not running the latest version, please try upgrading because your issue may have already been fixed. - validations: - required: true - - - type: textarea - id: steps - attributes: - label: Steps to reproduce - description: | - Please list the full steps required to reproduce the issue - placeholder: | - - Be precise - - Include exact data used during testing for easy reference - - The steps have to be in the exact order - - Mention pre-requisites when applicable - validations: - required: false - - - type: textarea - id: expected_behavior - attributes: - label: Expected Behavior - description: If you want to include screenshots, paste them into the markdown editor below or follow up with a separate comment. - placeholder: What were you expecting? - validations: - required: false - - - type: textarea - id: actual_behavior - attributes: - label: Actual Behavior - placeholder: What happened instead? - validations: - required: true - - - type: textarea - id: bug_context - attributes: - label: Additional Context - description: | - Are there anything atypical about your situation that we should know? - validations: - required: false - - - type: input - id: bug_firmware - attributes: - label: Opened Issues and Pull Requests - placeholder: "#1234" - description: | - Are there any other GitHub issues (open or closed) or Pull Requests that should be linked here? For example: #1234 - validations: - required: false +##################################################################### +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileType: OTHER +# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors +##################################################################### +name: "Bug Report" +description: "Let us know about an unexpected error, a crash, or an incorrect behavior." +title: 'Title of your Bug Report' +labels: + - bug +assignees: + - boogermann +body: + - type: markdown + attributes: + value: | + Hi there, + + Thank you for opening an issue. Please note that we try to keep the issue tracker reserved for bug reports. + Make sure to [search for existing issues](https://github.com/opengateware/computer-msx/issues?q=label%3Abug) before filing a new one! + + - type: input + id: version + attributes: + label: Version (or build number) + placeholder: "1.0.0" + description: | + You can find the version in the about dialog. + + If you are not running the latest version, please try upgrading because your issue may have already been fixed. + validations: + required: true + + - type: textarea + id: steps + attributes: + label: Steps to reproduce + description: | + Please list the full steps required to reproduce the issue + placeholder: | + - Be precise + - Include exact data used during testing for easy reference + - The steps have to be in the exact order + - Mention pre-requisites when applicable + validations: + required: false + + - type: textarea + id: expected_behavior + attributes: + label: Expected Behavior + description: If you want to include screenshots, paste them into the markdown editor below or follow up with a separate comment. + placeholder: What were you expecting? + validations: + required: false + + - type: textarea + id: actual_behavior + attributes: + label: Actual Behavior + placeholder: What happened instead? + validations: + required: true + + - type: textarea + id: bug_context + attributes: + label: Additional Context + description: | + Are there anything atypical about your situation that we should know? + validations: + required: false + + - type: input + id: bug_firmware + attributes: + label: Opened Issues and Pull Requests + placeholder: "#1234" + description: | + Are there any other GitHub issues (open or closed) or Pull Requests that should be linked here? For example: #1234 + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/QUESTION.yml b/.github/ISSUE_TEMPLATE/QUESTION.yml index c0f6730..27524e7 100644 --- a/.github/ISSUE_TEMPLATE/QUESTION.yml +++ b/.github/ISSUE_TEMPLATE/QUESTION.yml @@ -1,29 +1,29 @@ -##################################################################### -# SPDX-License-Identifier: CC0-1.0 -# SPDX-FileType: OTHER -# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors -##################################################################### -name: "Question" -description: "Ask a question about the project." -title: 'Title of your Question' -labels: - - question -assignees: - - boogermann -body: - - type: markdown - attributes: - value: | - Hi there, - - Please note that we try to keep the issue tracker reserved for bug reports. - Make sure to [search for existing questions](https://github.com/opengateware/computer-msx/issues?q=label%3Aquestion) before filing a new one! - - - type: textarea - id: question - attributes: - label: Ask a question about MSX Compatible Gateware IP Core - placeholder: | - Ask your question here! Please keep the questions related to the FPGA Core only. - validations: - required: true +##################################################################### +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileType: OTHER +# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors +##################################################################### +name: "Question" +description: "Ask a question about the project." +title: 'Title of your Question' +labels: + - question +assignees: + - boogermann +body: + - type: markdown + attributes: + value: | + Hi there, + + Please note that we try to keep the issue tracker reserved for bug reports. + Make sure to [search for existing questions](https://github.com/opengateware/computer-msx/issues?q=label%3Aquestion) before filing a new one! + + - type: textarea + id: question + attributes: + label: Ask a question about MSX Compatible Gateware IP Core + placeholder: | + Ask your question here! Please keep the questions related to the FPGA Core only. + validations: + required: true diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3113e01..5563d56 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,44 +1,44 @@ - - - - - - -## What does this do / why do we need it? - - - -{Please write here} - -Fixes # (issue) - -## Type of change - - - -- [ ] Bug fix (non-breaking change which fixes an issue) -- [ ] New feature (non-breaking change which adds functionality) -- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) -- [ ] This change requires a documentation update -- [ ] Coding style (indentation, etc) -- [ ] {Please write custom change here} - -## What should a reviewer look out for in this PR? - - - -{Please write here} - -## Additional Comments (if any) - -{Please write here} + + + + + + +## What does this do / why do we need it? + + + +{Please write here} + +Fixes # (issue) + +## Type of change + + + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update +- [ ] Coding style (indentation, etc) +- [ ] {Please write custom change here} + +## What should a reviewer look out for in this PR? + + + +{Please write here} + +## Additional Comments (if any) + +{Please write here} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9f50dab..ec51424 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,49 +1,49 @@ -################################################################################ -# SPDX-License-Identifier: CC0-1.0 -# SPDX-FileType: OTHER -# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors -################################################################################ -name: Build/Release -################################################################################ -# How to create a tag to launch the workflow -# git tag -a "0.1.0" -m "Release v0.1.0" -# git push origin --tags -################################################################################ -on: - push: - tags: - - "[0-9]+.[0-9]+.[0-9]+" - -jobs: - synthesis: - runs-on: ubuntu-latest - strategy: - matrix: - target: - - pocket - env: - CORE: msx - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - steps: - - name: "🧰 Checkout Repository" - uses: actions/checkout@v4 - - - name: "🧰 Checkout Packybara" - uses: actions/checkout@v4 - with: - repository: "boogermann/publish" - path: ".github/publish" - - - name: "🏗️ Compile Design" - uses: raetro/quartus-flow@v1 - with: - project: "${{ env.CORE }}_${{ matrix.target }}" - version: "${{ matrix.target }}" - - - name: "🏗️ Create Packages and Release" - env: - TARGET: ${{ matrix.target }} - run: | - pip3 install -r .github/publish/requirements.txt - python3 .github/publish/${{ matrix.TARGET }}.py +################################################################################ +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileType: OTHER +# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors +################################################################################ +name: Build/Release +################################################################################ +# How to create a tag to launch the workflow +# git tag -a "0.1.0" -m "Release v0.1.0" +# git push origin --tags +################################################################################ +on: + push: + tags: + - "[0-9]+.[0-9]+.[0-9]+" + +jobs: + synthesis: + runs-on: ubuntu-latest + strategy: + matrix: + target: + - pocket + env: + CORE: msx + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + steps: + - name: "🧰 Checkout Repository" + uses: actions/checkout@v4 + + - name: "🧰 Checkout Packybara" + uses: actions/checkout@v4 + with: + repository: "boogermann/publish" + path: ".github/publish" + + - name: "🏗️ Compile Design" + uses: raetro/quartus-flow@v1 + with: + project: "${{ env.CORE }}_${{ matrix.target }}" + version: "${{ matrix.target }}" + + - name: "🏗️ Create Packages and Release" + env: + TARGET: ${{ matrix.target }} + run: | + pip3 install -r .github/publish/requirements.txt + python3 .github/publish/${{ matrix.TARGET }}.py diff --git a/.gitignore b/.gitignore index 5629ca8..995c445 100644 --- a/.gitignore +++ b/.gitignore @@ -1,69 +1,69 @@ -# Quartus directories and files -db -greybox_tmp -hps_isw_handoff -incremental_db -output_files -PLLJ_PLLSPE_INFO.txt -simulation -vip -.qsys_edit -*_netlist -*_sim -*.bak -*.bsf -*.cdf -*.cmp -*.csv -*.done -*.f -*.pin -*.pof -*.ptf.* -*.qar -*.qarlog -*.qdf -*.qws -*.rbf -*.rbf_r -*.rpt -*.sip -*.sld -*.smsg -*.sof -*.sopc_builder -*.sopcinfo -*.spd -*.summary -*.txt -*.xml -*~ -**/.DS_Store -build_id.mif -build_id.v -c5_pin_model_dump.txt -cr_ie_info.json -# Gateman directories and files -!.gateman/* -!gateware.json -!/pkg/* -/pkg/**/*.rom -/pkg/**/*.zip -/staging/* -/release/* -# Editor directories and files -.vscode -.idea -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? -# Pocket directories and files -!info.txt -# ROMS Checklist -!checklist.sha1 -!checklist.md5 -a.out -.build -_tmp +# Quartus directories and files +db +greybox_tmp +hps_isw_handoff +incremental_db +output_files +PLLJ_PLLSPE_INFO.txt +simulation +vip +.qsys_edit +*_netlist +*_sim +*.bak +*.bsf +*.cdf +*.cmp +*.csv +*.done +*.f +*.pin +*.pof +*.ptf.* +*.qar +*.qarlog +*.qdf +*.qws +*.rbf +*.rbf_r +*.rpt +*.sip +*.sld +*.smsg +*.sof +*.sopc_builder +*.sopcinfo +*.spd +*.summary +*.txt +*.xml +*~ +**/.DS_Store +build_id.mif +build_id.v +c5_pin_model_dump.txt +cr_ie_info.json +# Gateman directories and files +!.gateman/* +!gateware.json +!/pkg/* +/pkg/**/*.rom +/pkg/**/*.zip +/staging/* +/release/* +# Editor directories and files +.vscode +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +# Pocket directories and files +!info.txt +# ROMS Checklist +!checklist.sha1 +!checklist.md5 +a.out +.build +_tmp diff --git a/ANALOGIZER.md b/ANALOGIZER.md new file mode 100644 index 0000000..4b255b8 --- /dev/null +++ b/ANALOGIZER.md @@ -0,0 +1,103 @@ +# Analogizer + +Analogizer is a cartridge-slot adapter for the Analogue Pocket that adds analog +video output and SNAC controller support. This core supports it through +RndMnkIII's [Analogizer](https://github.com/RndMnkIII/Analogizer) project, whose +wiki is the authority on the adapter itself. + +## What we can and cannot answer + +The capability lists below are RndMnkIII's, verified against his hardware. We +have not re-tested them, because no maintainer of this core owns the adapter, a +CRT, or the SNAC harnesses. Send analog video and SNAC problems to the +[Analogizer project](https://github.com/RndMnkIII/Analogizer), not to this repo. + +Three things are ours, and they're the ones worth reporting here: + +- **Rally-X is single player.** all Analogizer second player functionality was supressed (commented) +- **Blank the Pocket Screen** The core reads the setting out of + `analogizer.bin` and then enable/disable blanking Pocket screen output based on this setting. +- **Cart power is on for everyone.** The adapter draws power from the cartridge + slot, so `cartridge_adapter` in `core.json` enables it for every user whether + they own an adapter or not. The menu option does not gate it. Do not leave a + cartridge in the slot while running this core. + +## Configuration lives in a file, not the menu + +Everything except the on/off switch comes from `analogizer.bin`, not from the +Pocket's menu system. Generate it with +[Pupdate 5.6.0 or newer](https://github.com/mattpannella/pupdate/releases) or +[AnalogizerConfigurator 0.7 or newer](https://github.com/RndMnkIII/AnalogizerConfigurator/releases), +then copy it to `/Assets/analogizer/common` on the SD card, creating that folder +if it does not exist. Those utilities are where you choose the SNAC controller +type, the SNAC controller assignments that map physical pads onto the Pocket's +PAD format, the video output mode, and Blank the Pocket Screen. + +Turn it on with **ANALOGIZER ENABLE OPTIONS: ON ** in Analogizer Configurator/Pupdate menu. With it off, the core +disables every Analogizer code path. + +## Video output + +The core can output RGBS, RGsB, YPbPr, Y/C NTSC, Y/C PAL, and an SVGA +scandoubler with 50% scanlines. The SOG switch position applies to R2 and R3 +adapters only. + +- **RGBS.** Supported. SOG switch off. +- **RGsB.** Supported. SOG switch on. +- **YPbPr.** Supported, tested on a Sony PVM-9044D. SOG switch on. +- **Y/C NTSC.** Supported. SOG switch off. +- **Y/C PAL.** Supported. SOG switch off. +- **Scandoubler.** Supported. SOG switch off. + +Analogizer generates the encoded Y/C signal from RGB and drives it out of the +VGA port's R and G pins, redirecting CSync to the VGA HSync pin. Turning that +into S-Video or composite is the job of an external Y/C adapter on the VGA port, +which takes its 5V from VGA pin 9. Only Mike Simone's active designs have +official support: + +- [MiSTerAddons Active Y/C Adapter](https://misteraddons.com/collections/parts/products/yc-active-encoder-board/) +- [MikeS11 Active VGA to Composite / S-Video](https://ultimatemister.com/product/mikes11-active-composite-svideo/) +- [Active VGA to Composite/S-Video adapter](https://antoniovillena.com/product/mikes1-vga-composite-adapter/) + +Passive adapters may work to varying degrees depending on the screen. Anything +not tested against Analogizer gets no official support. Thanks to +[Mike Simone](https://github.com/MikeS11/MiSTerFPGA_YC_Encoder) for the Y/C +encoder project this builds on. + +## SNAC controllers + +SNAC lets you mix inputs from a real gamepad and PS/2 keyboard and mouse with the Pocket's built-in controls, +or with a USB or wireless controller on the Dock. Supported pads, with the A/B +switch position each one needs: + +- **DB15 Neo Geo.** Switch A. +- **NES.** Switch A. +- **SNES.** Switch A. +- **PC Engine.** Switch A. +- **PC Engine multitap.** Switch A. Native 2-button and 6-button pads, up to 5 + players, over the Analogizer-specific PC Engine cable harness. +- **PS/2 Keyboard & Mouse + NES One Player** Switch A. +- **PS/2 Keyboard & Mouse + SNES One Player** Switch A. +- **PS/2 Keyboard & Mouse + DB15 Two Players** Switch A. +- **PS/2 Keyboard & Mouse + No SNAC game controller** Switch A. +- **PSX DualShock / DualShock 2, digital d-pad.** Switch B. +- **PSX DualShock / DualShock 2, analog d-pad.** Switch B. + +"PS/2 Keyboard & Mouse + ..." options will require a specific Analogizer PS/2 SNAC adapter that will be available soon. + +Every adapter version (v1, v2, v3) has a side slide switch labelled `A B` that +has to match the controller you plugged in. PSX DualShock and DualShock 2 pads +need the B side; everything else needs the A side. + +Handle that switch carefully. Use something thin and flat, like a precision +screwdriver with a 2.0 mm blade. Rest the tip on the lever and press gently until +it slides over. + +``` + --- + B|O |A A/B switch on position B + --- + --- + B| O|A A/B switch on position A + --- +``` diff --git a/LICENSE b/LICENSE index 745e604..cac3579 100644 --- a/LICENSE +++ b/LICENSE @@ -1,674 +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 init, 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. - - {one line to give the program's name and a brief idea of what it does.} - Copyright (C) {year} {name of author} - - 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: - - {project} Copyright (C) {year} {fullname} - 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 -. + 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 init, 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. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + 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: + + {project} Copyright (C) {year} {fullname} + 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/docs/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md index 43aeed4..0f75993 100644 --- a/docs/CODE_OF_CONDUCT.md +++ b/docs/CODE_OF_CONDUCT.md @@ -1,64 +1,64 @@ -# Code Of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as contributors and leaders pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level or type of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. -Note, however, that religion, political party, or other ideological affiliation provide no exemptions for the behavior we outline as unacceptable in this Code of Conduct. - -## Our Standards - -We are committed to providing a friendly, safe and welcoming environment for all. - -Examples of behavior that contributes to creating a positive environment include: - -- Be kind and courteous to others -- Using welcoming and inclusive language -- Being respectful of differing viewpoints and experiences -- Collaborating with other community members -- Gracefully accepting constructive criticism -- Focusing on what is best for the community -- Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -- The use of sexualized language or imagery and sexual attention or advances -- The use of inappropriate images, including in a community member's avatar -- The use of inappropriate language, including in a community member's nickname -- Any spamming, flaming, baiting or other attention-stealing behavior -- Excessive or unwelcome helping; answering outside the scope of the question asked -- Trolling, insulting/derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or electronic address, without explicit permission -- Other conduct which could reasonably be considered inappropriate - -The goal of the standards and moderation guidelines outlined here is to build and maintain a respectful community. We ask that you don’t just aim to be "technically unimpeachable", but rather try to be your best self. - -We value many things beyond technical expertise, including collaboration and supporting others within our community. Providing a positive experience for other community members can have a much more significant impact than simply providing the correct answer. - -## Our Responsibilities - -Project leaders are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. - -Project leaders respect all people who contribute through reporting issues, posting feature requests, updating documentation, metadata, artwork, manuals, videos, submitting pull requests or patches, and other activities. But also have the right and responsibility to remove, edit, or reject messages, comments, commits, code, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any community member for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -## Scope - -This Code of Conduct and the enforcement policies listed above apply to all Rætro Community venues. This includes but is not limited to any community spaces (both public and private), the entire Rætro Discord server, and all Rætro associated GitHub repositories. Examples of Rætro Community spaces include but are not limited to meet-ups, audio chats on the Rætro Discord, or interaction at a conference. - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. As a community member, you are representing our community, and are expected to behave accordingly. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at or contact [community@raetro.org][conduct-email]. -All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. -The project team is obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html, and the Rust Code of Conduct, available at https://www.rust-lang.org/en-US/conduct.html and the Adafruit Community Code of Conduct, available at https://github.com/adafruit/Adafruit_Community_Code_of_Conduct. - -[homepage]: https://www.contributor-covenant.org -[conduct-email]: mailto:community@raetro.org +# Code Of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and leaders pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level or type of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. +Note, however, that religion, political party, or other ideological affiliation provide no exemptions for the behavior we outline as unacceptable in this Code of Conduct. + +## Our Standards + +We are committed to providing a friendly, safe and welcoming environment for all. + +Examples of behavior that contributes to creating a positive environment include: + +- Be kind and courteous to others +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Collaborating with other community members +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and sexual attention or advances +- The use of inappropriate images, including in a community member's avatar +- The use of inappropriate language, including in a community member's nickname +- Any spamming, flaming, baiting or other attention-stealing behavior +- Excessive or unwelcome helping; answering outside the scope of the question asked +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate + +The goal of the standards and moderation guidelines outlined here is to build and maintain a respectful community. We ask that you don’t just aim to be "technically unimpeachable", but rather try to be your best self. + +We value many things beyond technical expertise, including collaboration and supporting others within our community. Providing a positive experience for other community members can have a much more significant impact than simply providing the correct answer. + +## Our Responsibilities + +Project leaders are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project leaders respect all people who contribute through reporting issues, posting feature requests, updating documentation, metadata, artwork, manuals, videos, submitting pull requests or patches, and other activities. But also have the right and responsibility to remove, edit, or reject messages, comments, commits, code, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any community member for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct and the enforcement policies listed above apply to all Rætro Community venues. This includes but is not limited to any community spaces (both public and private), the entire Rætro Discord server, and all Rætro associated GitHub repositories. Examples of Rætro Community spaces include but are not limited to meet-ups, audio chats on the Rætro Discord, or interaction at a conference. + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. As a community member, you are representing our community, and are expected to behave accordingly. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at or contact [community@raetro.org][conduct-email]. +All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. +The project team is obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html, and the Rust Code of Conduct, available at https://www.rust-lang.org/en-US/conduct.html and the Adafruit Community Code of Conduct, available at https://github.com/adafruit/Adafruit_Community_Code_of_Conduct. + +[homepage]: https://www.contributor-covenant.org +[conduct-email]: mailto:community@raetro.org diff --git a/docs/README.md b/docs/README.md index bb06bcc..8817209 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,137 +1,137 @@ -[![MSX](msx-logo.png)](#) - ---- - -[![Active Development](https://img.shields.io/badge/Maintenance%20Level-Actively%20Developed-brightgreen.svg)](#status-of-features) -[![Build](https://github.com/opengateware/computer-msx/actions/workflows/build-pocket.yml/badge.svg)](https://github.com/opengateware/computer-msx/actions/workflows/build-pocket.yml) -[![release](https://img.shields.io/github/release/opengateware/computer-msx.svg)](https://github.com/opengateware/computer-msx/releases) -[![license](https://img.shields.io/github/license/opengateware/computer-msx.svg?label=License&color=yellow)](#legal-notices) -[![issues](https://img.shields.io/github/issues/opengateware/computer-msx.svg?label=Issues&color=red)](https://github.com/opengateware/computer-msx/issues) -[![stars](https://img.shields.io/github/stars/opengateware/computer-msx.svg?label=Project%20Stars)](https://github.com/opengateware/computer-msx/stargazers) -[![discord](https://img.shields.io/discord/676418475635507210.svg?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://chat.raetro.org) -[![Twitter Follow](https://img.shields.io/twitter/follow/marcusjordan?style=social)](https://twitter.com/marcusjordan) - -## MSX Compatible Gateware IP Core - -This Implementation of a compatible [MSX] home computer hardware in HDL is the work of [Molekula]. - -## Overview - -The MSX, launched by ASCII Corporation and Microsoft in 1983, aimed to standardize the home computer market, akin to the VHS format for video. Despite its ambitious goals, the MSX found regional success, particularly in Asia, South America, Europe, and the former Soviet Union, but remained largely unknown in the United States. Its architecture, featuring a Zilog Z80A CPU and TMS9918 video processor, made it a versatile platform for both education and gaming. - -The acronym "MSX" has sparked much debate over its meaning. Initially, many interpreted it as "Microsoft Extended," a nod to its built-in Microsoft eXtended BASIC. However, Kazuhiko Nishi, a key figure behind the MSX, offered various interpretations over the years, including "Machines with Software Exchangeability" and references to major electronics companies Matsushita (Panasonic) and Sony. Nishi's vision was for a name that signified the system's next-generation capabilities and its association with leading tech giants. - -Despite not achieving its goal of global standardization, the MSX left a lasting legacy in the realms of computing and gaming. Before the dominance of Nintendo's gaming consoles, the MSX was a preferred platform for pioneering game developers. The system's versatile architecture and software library made it a beloved platform among enthusiasts, maintaining a dedicated community and influencing generations of users and creators. - -## Technical specifications - -- **Main CPU:** Zilog Z80 @ 3.579545 MHz -- **Sound Chip:** AY-3-8912 @ 1.789772 MHz -- **Video Resolution:** 256×192 pixels @ 5.369317 MHz -- **Aspect Ratio:** 4:3 -- **Video Processor:** TMS9918 or TMS9928 Video Display Processor (VDP) -- **Memory:** 64kB of RAM, expandable through the use of cartridge slots and external peripherals -- **Storage:** Supports floppy disk, cassette tape and cartridge-based storage - -## Features - -- Reference Model: Philips VG8020/00 -- Video Support: NTSC/PAL -- Input: Joystick, Joy2Key and Keyboard -- Sound: Yamaha YM2149 (SSG) -- Memory: 64kB RAM in Slot 3 -- Expansion: 2 Cartridge Slots (`.ROM`) -- Supported Mappers: - - Auto/Mirrored - - GameMaster2 - - Konami - - Konami SCC - - ASCII8 - - ASCII16 - - Linear64k - - R-TYPE -- BIOS: Supports different BIOS and Hangul BASIC via FWBIOS, by default will use [C-BIOS] - -### Status of Features (Not Yet Implemented) - -- [ ] Floppy Disk Support (`.DSK`) -- [ ] Cassette Support (`.CAS`) -- [ ] On-Screen Keyboard - -## Compatible Platforms - -- Analogue Pocket - -## Usage - -MSX1 ROMs and BIOS should be placed in `/Assets/msx/common`. - -C-BIOS is not a real BIOS rom and has certain restrictions, such as no support for anything other then cartridges (ROMs). So there is no support for disk, cassette or games that required BASIC. - -## Memory limitations - -- Slot 1 ROM image max size 4MB -- Slot 2 ROM image max size 4MB -- Slot 3 64Kb RAM - -## Credits and acknowledgment - -- [Molekula] -- [Daniel Wallner](https://opencores.org/projects/t80) -- [Jose Tejada](https://github.com/jotego) -- Arnim Laeuger -- Kazuhiro Tsujikawa -- Alexey Melnikov -- Viacheslav Slavinsky -- Patrick van Arkel - -## Powered by Open-Source Software - -This project borrowed and use code from several other projects. A great thanks to their efforts! - -| Modules | Copyright/Developer | -| :-------- | :---------------------- | -| [MSX RTL] | 2022 (c) Molekula | -| [T80] | 2001 (c) Daniel Wallner | -| VDP18 | 2006 (c) Arnim Laeuger | -| [JT49] | 2018 (c) Jose Tejada | -| [JT8255] | 2021 (c) Jose Tejada | -| [C-BIOS] | 2001 (c) C-BIOS Team | - -## License - -This work is licensed under multiple licenses. - -- All original source code is licensed under [GNU General Public License v3.0 or later] unless implicit indicated. -- All documentation is licensed under [Creative Commons Attribution Share Alike 4.0 International] Public License. -- Some configuration and data files are licensed under [Creative Commons Zero v1.0 Universal]. - -Open Gateware and any contributors reserve all others rights, whether under their respective copyrights, patents, or trademarks, whether by implication, estoppel or otherwise. - -Individual files may contain the following SPDX license tags as a shorthand for the above copyright and warranty notices: - -```text -SPDX-License-Identifier: GPL-3.0-or-later -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-License-Identifier: CC0-1.0 -``` - -This eases machine processing of licensing information based on the SPDX License Identifiers that are available at . - -## Legal Notices - -The Open Gateware authors and contributors or any of its maintainers are in no way associated with or endorsed by ASCII Corporation, Microsoft or any other company not implicit indicated. -All other brands or product names are the property of their respective holders. - -[Molekula]: https://github.com/tdlabac -[MSX]: https://en.wikipedia.org/wiki/MSX - -[MSX RTL]: https://github.com/tdlabac/MSX1_MiSTer -[T80]: https://opencores.org/projects/t80 -[JT49]: https://github.com/jotego/jt49 -[JT8255]: https://github.com/jotego/jt8255/ -[C-BIOS]: https://cbios.sourceforge.net/ - -[GNU General Public License v3.0 or later]: https://spdx.org/licenses/GPL-3.0-or-later.html -[Creative Commons Attribution Share Alike 4.0 International]: https://spdx.org/licenses/CC-BY-SA-4.0.html -[Creative Commons Zero v1.0 Universal]: https://spdx.org/licenses/CC0-1.0.html +[![MSX](msx-logo.png)](#) + +--- + +[![Active Development](https://img.shields.io/badge/Maintenance%20Level-Actively%20Developed-brightgreen.svg)](#status-of-features) +[![Build](https://github.com/opengateware/computer-msx/actions/workflows/build-pocket.yml/badge.svg)](https://github.com/opengateware/computer-msx/actions/workflows/build-pocket.yml) +[![release](https://img.shields.io/github/release/opengateware/computer-msx.svg)](https://github.com/opengateware/computer-msx/releases) +[![license](https://img.shields.io/github/license/opengateware/computer-msx.svg?label=License&color=yellow)](#legal-notices) +[![issues](https://img.shields.io/github/issues/opengateware/computer-msx.svg?label=Issues&color=red)](https://github.com/opengateware/computer-msx/issues) +[![stars](https://img.shields.io/github/stars/opengateware/computer-msx.svg?label=Project%20Stars)](https://github.com/opengateware/computer-msx/stargazers) +[![discord](https://img.shields.io/discord/676418475635507210.svg?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://chat.raetro.org) +[![Twitter Follow](https://img.shields.io/twitter/follow/marcusjordan?style=social)](https://twitter.com/marcusjordan) + +## MSX Compatible Gateware IP Core + +This Implementation of a compatible [MSX] home computer hardware in HDL is the work of [Molekula]. + +## Overview + +The MSX, launched by ASCII Corporation and Microsoft in 1983, aimed to standardize the home computer market, akin to the VHS format for video. Despite its ambitious goals, the MSX found regional success, particularly in Asia, South America, Europe, and the former Soviet Union, but remained largely unknown in the United States. Its architecture, featuring a Zilog Z80A CPU and TMS9918 video processor, made it a versatile platform for both education and gaming. + +The acronym "MSX" has sparked much debate over its meaning. Initially, many interpreted it as "Microsoft Extended," a nod to its built-in Microsoft eXtended BASIC. However, Kazuhiko Nishi, a key figure behind the MSX, offered various interpretations over the years, including "Machines with Software Exchangeability" and references to major electronics companies Matsushita (Panasonic) and Sony. Nishi's vision was for a name that signified the system's next-generation capabilities and its association with leading tech giants. + +Despite not achieving its goal of global standardization, the MSX left a lasting legacy in the realms of computing and gaming. Before the dominance of Nintendo's gaming consoles, the MSX was a preferred platform for pioneering game developers. The system's versatile architecture and software library made it a beloved platform among enthusiasts, maintaining a dedicated community and influencing generations of users and creators. + +## Technical specifications + +- **Main CPU:** Zilog Z80 @ 3.579545 MHz +- **Sound Chip:** AY-3-8912 @ 1.789772 MHz +- **Video Resolution:** 256×192 pixels @ 5.369317 MHz +- **Aspect Ratio:** 4:3 +- **Video Processor:** TMS9918 or TMS9928 Video Display Processor (VDP) +- **Memory:** 64kB of RAM, expandable through the use of cartridge slots and external peripherals +- **Storage:** Supports floppy disk, cassette tape and cartridge-based storage + +## Features + +- Reference Model: Philips VG8020/00 +- Video Support: NTSC/PAL +- Input: Joystick, Joy2Key and Keyboard +- Sound: Yamaha YM2149 (SSG) +- Memory: 64kB RAM in Slot 3 +- Expansion: 2 Cartridge Slots (`.ROM`) +- Supported Mappers: + - Auto/Mirrored + - GameMaster2 + - Konami + - Konami SCC + - ASCII8 + - ASCII16 + - Linear64k + - R-TYPE +- BIOS: Supports different BIOS and Hangul BASIC via FWBIOS, by default will use [C-BIOS] + +### Status of Features (Not Yet Implemented) + +- [ ] Floppy Disk Support (`.DSK`) +- [ ] Cassette Support (`.CAS`) +- [ ] On-Screen Keyboard + +## Compatible Platforms + +- Analogue Pocket + +## Usage + +MSX1 ROMs and BIOS should be placed in `/Assets/msx/common`. + +C-BIOS is not a real BIOS rom and has certain restrictions, such as no support for anything other then cartridges (ROMs). So there is no support for disk, cassette or games that required BASIC. + +## Memory limitations + +- Slot 1 ROM image max size 4MB +- Slot 2 ROM image max size 4MB +- Slot 3 64Kb RAM + +## Credits and acknowledgment + +- [Molekula] +- [Daniel Wallner](https://opencores.org/projects/t80) +- [Jose Tejada](https://github.com/jotego) +- Arnim Laeuger +- Kazuhiro Tsujikawa +- Alexey Melnikov +- Viacheslav Slavinsky +- Patrick van Arkel + +## Powered by Open-Source Software + +This project borrowed and use code from several other projects. A great thanks to their efforts! + +| Modules | Copyright/Developer | +| :-------- | :---------------------- | +| [MSX RTL] | 2022 (c) Molekula | +| [T80] | 2001 (c) Daniel Wallner | +| VDP18 | 2006 (c) Arnim Laeuger | +| [JT49] | 2018 (c) Jose Tejada | +| [JT8255] | 2021 (c) Jose Tejada | +| [C-BIOS] | 2001 (c) C-BIOS Team | + +## License + +This work is licensed under multiple licenses. + +- All original source code is licensed under [GNU General Public License v3.0 or later] unless implicit indicated. +- All documentation is licensed under [Creative Commons Attribution Share Alike 4.0 International] Public License. +- Some configuration and data files are licensed under [Creative Commons Zero v1.0 Universal]. + +Open Gateware and any contributors reserve all others rights, whether under their respective copyrights, patents, or trademarks, whether by implication, estoppel or otherwise. + +Individual files may contain the following SPDX license tags as a shorthand for the above copyright and warranty notices: + +```text +SPDX-License-Identifier: GPL-3.0-or-later +SPDX-License-Identifier: CC-BY-SA-4.0 +SPDX-License-Identifier: CC0-1.0 +``` + +This eases machine processing of licensing information based on the SPDX License Identifiers that are available at . + +## Legal Notices + +The Open Gateware authors and contributors or any of its maintainers are in no way associated with or endorsed by ASCII Corporation, Microsoft or any other company not implicit indicated. +All other brands or product names are the property of their respective holders. + +[Molekula]: https://github.com/tdlabac +[MSX]: https://en.wikipedia.org/wiki/MSX + +[MSX RTL]: https://github.com/tdlabac/MSX1_MiSTer +[T80]: https://opencores.org/projects/t80 +[JT49]: https://github.com/jotego/jt49 +[JT8255]: https://github.com/jotego/jt8255/ +[C-BIOS]: https://cbios.sourceforge.net/ + +[GNU General Public License v3.0 or later]: https://spdx.org/licenses/GPL-3.0-or-later.html +[Creative Commons Attribution Share Alike 4.0 International]: https://spdx.org/licenses/CC-BY-SA-4.0.html +[Creative Commons Zero v1.0 Universal]: https://spdx.org/licenses/CC0-1.0.html diff --git a/gateware.json b/gateware.json index 2d0b7a4..427828d 100644 --- a/gateware.json +++ b/gateware.json @@ -1,46 +1,46 @@ -{ - "name": "msx", - "displayName": "msx", - "description": "MSX Compatible Gateware IP Core", - "author": "boogermann", - "version": "0.1.0", - "license": "GPL-3.0-or-later", - "repository": "https://github.com/opengateware/computer-msx", - "keywords": [ - "ecosystem:gateman" - ], - "scripts": { - "verilator": "echo \"Error: no simulation specified\" && exit 1", - "build:pocket": "quartus_sh --flow compile projects/msx_pocket.qpf", - "program:pocket": "quartus_pgm -m jtag -c 1 -o \"p;projects/output_files/msx_pocket.sof@1\"" - }, - "hardware": { - "id": "msx", - "name": "MSX", - "year": 1983, - "manufacturer": "Microsoft" - }, - "release": { - "image": "docs/git-social.png", - "folders": { - "output_folder": "projects/output_files", - "pkg_folder": "pkg", - "meta_folder": "pkg/meta", - "stage_folder": "staging", - "release_folder": "release" - }, - "target": { - "pocket": { - "release_file": "{author}.{core}_{version}_{date}-{target}" - } - } - }, - "platforms": { - "pocket": "2.0.0" - }, - "modules": { - "cpu-t80": "1.0.0", - "sound-jt49": "1.0.0", - "video-vdp18": "1.0.0" - } +{ + "name": "msx", + "displayName": "msx", + "description": "MSX Compatible Gateware IP Core", + "author": "boogermann", + "version": "0.1.0", + "license": "GPL-3.0-or-later", + "repository": "https://github.com/opengateware/computer-msx", + "keywords": [ + "ecosystem:gateman" + ], + "scripts": { + "verilator": "echo \"Error: no simulation specified\" && exit 1", + "build:pocket": "quartus_sh --flow compile projects/msx_pocket.qpf", + "program:pocket": "quartus_pgm -m jtag -c 1 -o \"p;projects/output_files/msx_pocket.sof@1\"" + }, + "hardware": { + "id": "msx", + "name": "MSX", + "year": 1983, + "manufacturer": "Microsoft" + }, + "release": { + "image": "docs/git-social.png", + "folders": { + "output_folder": "projects/output_files", + "pkg_folder": "pkg", + "meta_folder": "pkg/meta", + "stage_folder": "staging", + "release_folder": "release" + }, + "target": { + "pocket": { + "release_file": "{author}.{core}_{version}_{date}-{target}" + } + } + }, + "platforms": { + "pocket": "2.0.0" + }, + "modules": { + "cpu-t80": "1.0.0", + "sound-jt49": "1.0.0", + "video-vdp18": "1.0.0" + } } \ No newline at end of file diff --git a/modules/cpu-t80/GBse.vhd b/modules/cpu-t80/GBse.vhd index 102ccbf..00a892e 100644 --- a/modules/cpu-t80/GBse.vhd +++ b/modules/cpu-t80/GBse.vhd @@ -1,205 +1,205 @@ --- **** --- T80(b) core. In an effort to merge and maintain bug fixes .... --- --- --- Ver 300 started tidyup --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) --- --- **** --- --- Z80 compatible microprocessor core, synchronous top level with clock enable --- Different timing than the original z80 --- Inputs needs to be synchronous and outputs may glitch --- --- Version : 0240 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0235 : First release --- --- 0236 : Added T2Write generic --- --- 0237 : Fixed T2Write with wait state --- --- 0238 : Updated for T80 interface change --- --- 0240 : Updated for T80 interface change --- --- 0242 : Updated for T80 interface change --- -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity GBse is - generic( - T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 - IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle - ); - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - CLKEN : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - MREQ_n : out std_logic; - IORQ_n : out std_logic; - RD_n : out std_logic; - WR_n : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - STOP : out std_logic; - A : out std_logic_vector(15 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0) - ); -end GBse; - -architecture rtl of GBse is - - signal IntCycle_n : std_logic; - signal NoRead : std_logic; - signal Write : std_logic; - signal IORQ : std_logic; - signal DI_Reg : std_logic_vector(7 downto 0); - signal MCycle : std_logic_vector(2 downto 0); - signal TState : std_logic_vector(2 downto 0); - -begin - - u0 : T80 - generic map( - Mode => 3, - IOWait => IOWait, - Flag_S => 0, - Flag_P => 0, - Flag_X => 0, - Flag_Y => 0, - Flag_C => 4, - Flag_H => 5, - Flag_N => 6, - Flag_Z => 7 - ) - port map( - CEN => CLKEN, - M1_n => M1_n, - IORQ => IORQ, - NoRead => NoRead, - Write => Write, - RFSH_n => RFSH_n, - HALT_n => HALT_n, - Stop => STOP, - WAIT_n => Wait_n, - INT_n => INT_n, - NMI_n => NMI_n, - RESET_n => RESET_n, - BUSRQ_n => BUSRQ_n, - BUSAK_n => BUSAK_n, - CLK_n => CLK_n, - A => A, - DInst => DI, - DI => DI_Reg, - DO => DO, - MC => MCycle, - TS => TState, - IntCycle_n => IntCycle_n); - - process (RESET_n, CLK_n) - begin - if RESET_n = '0' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - DI_Reg <= "00000000"; - elsif CLK_n'event and CLK_n = '1' then - if CLKEN = '1' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - if MCycle = "001" then - if TState = "001" or (TState = "010" and Wait_n = '0') then - RD_n <= not IntCycle_n; - MREQ_n <= not IntCycle_n; - end if; - if TState = "011" then - MREQ_n <= '0'; - end if; - elsif MCycle = "011" and IntCycle_n = '0' then - if TState = "001" then - IORQ_n <= '0'; -- Acknowledge IRQ - end if; - else - if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then - RD_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - if T2Write = 0 then - if TState = "010" and Write = '1' then - WR_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - else - if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then - WR_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - end if; - end if; - if TState = "010" and Wait_n = '1' then - DI_Reg <= DI; - end if; - end if; - end if; - end process; - -end; +-- **** +-- T80(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 300 started tidyup +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- Z80 compatible microprocessor core, synchronous top level with clock enable +-- Different timing than the original z80 +-- Inputs needs to be synchronous and outputs may glitch +-- +-- Version : 0240 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0235 : First release +-- +-- 0236 : Added T2Write generic +-- +-- 0237 : Fixed T2Write with wait state +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity GBse is + generic( + T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 + IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CLKEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + STOP : out std_logic; + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0) + ); +end GBse; + +architecture rtl of GBse is + + signal IntCycle_n : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal IORQ : std_logic; + signal DI_Reg : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + +begin + + u0 : T80 + generic map( + Mode => 3, + IOWait => IOWait, + Flag_S => 0, + Flag_P => 0, + Flag_X => 0, + Flag_Y => 0, + Flag_C => 4, + Flag_H => 5, + Flag_N => 6, + Flag_Z => 7 + ) + port map( + CEN => CLKEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n, + HALT_n => HALT_n, + Stop => STOP, + WAIT_n => Wait_n, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => RESET_n, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n, + CLK_n => CLK_n, + A => A, + DInst => DI, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n); + + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + DI_Reg <= "00000000"; + elsif CLK_n'event and CLK_n = '1' then + if CLKEN = '1' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + if MCycle = "001" then + if TState = "001" or (TState = "010" and Wait_n = '0') then + RD_n <= not IntCycle_n; + MREQ_n <= not IntCycle_n; + end if; + if TState = "011" then + MREQ_n <= '0'; + end if; + elsif MCycle = "011" and IntCycle_n = '0' then + if TState = "001" then + IORQ_n <= '0'; -- Acknowledge IRQ + end if; + else + if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then + RD_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + if T2Write = 0 then + if TState = "010" and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + else + if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + end if; + end if; + if TState = "010" and Wait_n = '1' then + DI_Reg <= DI; + end if; + end if; + end if; + end process; + +end; diff --git a/modules/cpu-t80/README.md b/modules/cpu-t80/README.md index 9bb959c..55290a6 100644 --- a/modules/cpu-t80/README.md +++ b/modules/cpu-t80/README.md @@ -1,55 +1,55 @@ -# T80 a Z80 Compatible Microprocessor Gateware IP Core - -Attempt to finish all undocumented features and provide accurate timings. - -## Changelog - -- 3.5.1 - - Merged Gameboy fixes from Bruno Duarte Gouveia (brNX) - - Passes Blargg's test ROMs -- 3.5.0 - - Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr - - (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as correct implementation is still unclear. -- 3.0.3 - - Add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010 -- 3.0.1 - - Parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle -- 3.0.0 - - Started tidyup -- 2.5.0 - - Unknown History before this point - -Contributors: - -```txt -Copyright (c) 2021 Bruno Duarte Gouveia -Copyright (c) 2018 Sorgelig -Copyright (c) 2010 TobiFlex -Copyright (c) 20xx Sean Riddle -Copyright (c) 2005 MikeJ -``` - -```txt -Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) -All rights reserved. - -Redistributions in synthesized form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. - -Neither the name of the author nor the names of other contributors may -be used to endorse or promote products derived from this software without -specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -``` +# T80 a Z80 Compatible Microprocessor Gateware IP Core + +Attempt to finish all undocumented features and provide accurate timings. + +## Changelog + +- 3.5.1 + - Merged Gameboy fixes from Bruno Duarte Gouveia (brNX) + - Passes Blargg's test ROMs +- 3.5.0 + - Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr + - (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as correct implementation is still unclear. +- 3.0.3 + - Add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010 +- 3.0.1 + - Parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle +- 3.0.0 + - Started tidyup +- 2.5.0 + - Unknown History before this point + +Contributors: + +```txt +Copyright (c) 2021 Bruno Duarte Gouveia +Copyright (c) 2018 Sorgelig +Copyright (c) 2010 TobiFlex +Copyright (c) 20xx Sean Riddle +Copyright (c) 2005 MikeJ +``` + +```txt +Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +All rights reserved. + +Redistributions in synthesized form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +Neither the name of the author nor the names of other contributors may +be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +``` diff --git a/modules/cpu-t80/T16450.vhd b/modules/cpu-t80/T16450.vhd index ad266c2..0ba4e08 100644 --- a/modules/cpu-t80/T16450.vhd +++ b/modules/cpu-t80/T16450.vhd @@ -1,459 +1,459 @@ --- --- 16450 compatible UART with synchronous bus interface --- RClk/BaudOut is XIn enable instead of actual clock --- --- Version : 0249b --- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0208 : First release --- --- 0249 : Fixed interrupt and baud rate bugs found by Andy Dyer --- Added modem status and break detection --- Added support for 1.5 and 2 stop bits --- --- 0249b : Fixed loopback break generation bugs found by Andy Dyer --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity T16450 is - port( - MR_n : in std_logic; - XIn : in std_logic; - RClk : in std_logic; - CS_n : in std_logic; - Rd_n : in std_logic; - Wr_n : in std_logic; - A : in std_logic_vector(2 downto 0); - D_In : in std_logic_vector(7 downto 0); - D_Out : out std_logic_vector(7 downto 0); - SIn : in std_logic; - CTS_n : in std_logic; - DSR_n : in std_logic; - RI_n : in std_logic; - DCD_n : in std_logic; - SOut : out std_logic; - RTS_n : out std_logic; - DTR_n : out std_logic; - OUT1_n : out std_logic; - OUT2_n : out std_logic; - BaudOut : out std_logic; - Intr : out std_logic - ); -end T16450; - -architecture rtl of T16450 is - - signal RBR : std_logic_vector(7 downto 0); -- Reciever Buffer Register - signal THR : std_logic_vector(7 downto 0); -- Transmitter Holding Register - signal IER : std_logic_vector(7 downto 0); -- Interrupt Enable Register - signal IIR : std_logic_vector(7 downto 0); -- Interrupt Ident. Register - signal LCR : std_logic_vector(7 downto 0); -- Line Control Register - signal MCR : std_logic_vector(7 downto 0); -- MODEM Control Register - signal LSR : std_logic_vector(7 downto 0); -- Line Status Register - signal MSR : std_logic_vector(7 downto 0); -- MODEM Status Register - signal SCR : std_logic_vector(7 downto 0); -- Scratch Register - signal DLL : std_logic_vector(7 downto 0); -- Divisor Latch (LS) - signal DLM : std_logic_vector(7 downto 0); -- Divisor Latch (MS) - - signal DM0 : std_logic_vector(7 downto 0); - signal DM1 : std_logic_vector(7 downto 0); - - signal MSR_In : std_logic_vector(3 downto 0); - - signal Bit_Phase : unsigned(3 downto 0); - signal Brk_Cnt : unsigned(3 downto 0); - signal RX_Filtered : std_logic; - signal RX_ShiftReg : std_logic_vector(7 downto 0); - signal RX_Bit_Cnt : integer range 0 to 11; - signal RX_Parity : std_logic; - signal RXD : std_logic; - - signal TX_Tick : std_logic; - signal TX_ShiftReg : std_logic_vector(7 downto 0); - signal TX_Bit_Cnt : integer range 0 to 11; - signal TX_Parity : std_logic; - signal TX_Next_Is_Stop : std_logic; - signal TX_Stop_Bit : std_logic; - signal TXD : std_logic; - -begin - - DTR_n <= MCR(4) or not MCR(0); - RTS_n <= MCR(4) or not MCR(1); - OUT1_n <= MCR(4) or not MCR(2); - OUT2_n <= MCR(4) or not MCR(3); - SOut <= MCR(4) or (TXD and not LCR(6)); - RXD <= SIn when MCR(4) = '0' else (TXD and not LCR(6)); - - Intr <= not IIR(0); - - -- Registers - DM0 <= DLL when LCR(7) = '1' else RBR; - DM1 <= DLM when LCR(7) = '1' else IER; - with A select - D_Out <= - DM0 when "000", - DM1 when "001", - IIR when "010", - LCR when "011", - MCR when "100", - LSR when "101", - MSR when "110", - SCR when others; - process (MR_n, XIn) - begin - if MR_n = '0' then - THR <= "00000000"; - IER <= "00000000"; - LCR <= "00000000"; - MCR <= "00000000"; - MSR(3 downto 0) <= "0000"; - SCR <= "00000000"; -- ?? - DLL <= "00000000"; -- ?? - DLM <= "00000000"; -- ?? - elsif XIn'event and XIn = '1' then - if Wr_n = '0' and CS_n = '0' then - case A is - when "000" => - if LCR(7) = '1' then - DLL <= D_In; - else - THR <= D_In; - end if; - when "001" => - if LCR(7) = '1' then - DLM <= D_In; - else - IER(3 downto 0) <= D_In(3 downto 0); - end if; - when "011" => - LCR <= D_In; - when "100" => - MCR <= D_In; - when "111" => - SCR <= D_In; - when others => - end case; - end if; - if Rd_n = '0' and CS_n = '0' and A = "110" then - MSR(3 downto 0) <= "0000"; - end if; - if MSR(4) /= MSR_In(0) then - MSR(0) <= '1'; - end if; - if MSR(5) /= MSR_In(1) then - MSR(1) <= '1'; - end if; - if MSR(6) = '0' and MSR_In(2) = '1' then - MSR(2) <= '1'; - end if; - if MSR(7) /= MSR_In(3) then - MSR(3) <= '1'; - end if; - end if; - end process; - process (XIn) - begin - if XIn'event and XIn = '1' then - if MCR(4) = '0' then - MSR(4) <= MSR_In(0); - MSR(5) <= MSR_In(1); - MSR(6) <= MSR_In(2); - MSR(7) <= MSR_In(3); - else - MSR(4) <= MCR(1); - MSR(5) <= MCR(0); - MSR(6) <= MCR(2); - MSR(7) <= MCR(3); - end if; - MSR_In(0) <= CTS_n; - MSR_In(1) <= DSR_n; - MSR_In(2) <= RI_n; - MSR_In(3) <= DCD_n; - end if; - end process; - - IIR(7 downto 3) <= "00000"; - IIR(2 downto 0) <= - "110" when IER(2) = '1' and LSR(4 downto 1) /= "0000" else - "100" when (IER(0) and LSR(0)) = '1' else - "010" when (IER(1) and LSR(5)) = '1' else - "000" when IER(3) = '1' and ((MCR(4) = '0' and MSR(3 downto 0) /= "0000") or - (MCR(4) = '1' and MCR(3 downto 0) /= "0000")) else - "001"; - - -- Baud x 16 clock generator - process (MR_n, XIn) - variable Baud_Cnt : unsigned(15 downto 0); - begin - if MR_n = '0' then - Baud_Cnt := "0000000000000000"; - BaudOut <= '0'; - elsif XIn'event and XIn = '1' then - if Baud_Cnt(15 downto 1) = "000000000000000" or (Wr_n = '0' and CS_n = '0' and A(2 downto 1) = "00" and LCR(7) = '1') then - Baud_Cnt(15 downto 8) := unsigned(DLM); - Baud_Cnt(7 downto 0) := unsigned(DLL); - BaudOut <= '1'; - else - Baud_Cnt := Baud_Cnt - 1; - BaudOut <= '0'; - end if; - end if; - end process; - - -- Input filter - process (MR_n, XIn) - variable Samples : std_logic_vector(1 downto 0); - begin - if MR_n = '0' then - Samples := "11"; - RX_Filtered <= '1'; - elsif XIn'event and XIn = '1' then - if RClk = '1' then - Samples(1) := Samples(0); - Samples(0) := RXD; - end if; - if Samples = "00" then - RX_Filtered <= '0'; - end if; - if Samples = "11" then - RX_Filtered <= '1'; - end if; - end if; - end process; - - -- Receive state machine - process (MR_n, XIn) - begin - if MR_n = '0' then - RBR <= "00000000"; - LSR(4 downto 0) <= "00000"; - Bit_Phase <= "0000"; - Brk_Cnt <= "0000"; - RX_ShiftReg(7 downto 0) <= "00000000"; - RX_Bit_Cnt <= 0; - RX_Parity <= '0'; - elsif XIn'event and XIn = '1' then - if A = "000" and LCR(7) = '0' and Rd_n = '0' and CS_n = '0' then - LSR(0) <= '0'; -- DR - end if; - if A = "101" and Rd_n = '0' and CS_n = '0' then - LSR(4) <= '0'; -- BI - LSR(3) <= '0'; -- FE - LSR(2) <= '0'; -- PE - LSR(1) <= '0'; -- OE - end if; - if RClk = '1' then - if RX_Bit_Cnt = 0 and (RX_Filtered = '1' or Bit_Phase = "0111") then - Bit_Phase <= "0000"; - else - Bit_Phase <= Bit_Phase + 1; - end if; - if Bit_Phase = "1111" then - if RX_Filtered = '1' then - Brk_Cnt <= "0000"; - else - Brk_Cnt <= Brk_Cnt + 1; - end if; - if Brk_Cnt = "1100" then - LSR(4) <= '1'; -- BI - end if; - end if; - if RX_Bit_Cnt = 0 then - if Bit_Phase = "0111" then - RX_Bit_Cnt <= RX_Bit_Cnt + 1; - RX_Parity <= not LCR(4); -- EPS - end if; - elsif Bit_Phase = "1111" then - RX_Bit_Cnt <= RX_Bit_Cnt + 1; - if RX_Bit_Cnt = 10 then -- Parity stop bit - RX_Bit_Cnt <= 0; - LSR(0) <= '1'; -- UART Receive complete - LSR(3) <= not RX_Filtered; -- Framing error - elsif (RX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or - (RX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or - (RX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or - (RX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then -- Stop bit/Parity - RX_Bit_Cnt <= 0; - if LCR(3) = '1' then -- PEN - RX_Bit_Cnt <= 10; - if LCR(5) = '1' then -- Stick parity - if RX_Filtered = LCR(4) then - LSR(2) <= '1'; - end if; - else - if RX_Filtered /= RX_Parity then - LSR(2) <= '1'; - end if; - end if; - else - LSR(0) <= '1'; -- UART Receive complete - LSR(3) <= not RX_Filtered; -- Framing error - end if; - RBR <= RX_ShiftReg(7 downto 0); - LSR(1) <= LSR(0); - if A = "101" and Rd_n = '0' and CS_n = '0' then - LSR(1) <= '0'; - end if; - else - RX_ShiftReg(6 downto 0) <= RX_ShiftReg(7 downto 1); - RX_ShiftReg(7) <= RX_Filtered; - if LCR(1 downto 0) = "10" then - RX_ShiftReg(7) <= '0'; - RX_ShiftReg(6) <= RX_Filtered; - end if; - if LCR(1 downto 0) = "01" then - RX_ShiftReg(7) <= '0'; - RX_ShiftReg(6) <= '0'; - RX_ShiftReg(5) <= RX_Filtered; - end if; - if LCR(1 downto 0) = "00" then - RX_ShiftReg(7) <= '0'; - RX_ShiftReg(6) <= '0'; - RX_ShiftReg(5) <= '0'; - RX_ShiftReg(4) <= RX_Filtered; - end if; - RX_Parity <= RX_Filtered xor RX_Parity; - end if; - end if; - end if; - end if; - end process; - - -- Transmit bit tick - process (MR_n, XIn) - variable TX_Cnt : unsigned(4 downto 0); - begin - if MR_n = '0' then - TX_Cnt := "00000"; - TX_Tick <= '0'; - elsif XIn'event and XIn = '1' then - TX_Tick <= '0'; - if RClk = '1' then - TX_Cnt := TX_Cnt + 1; - if LCR(2) = '1' and TX_Stop_Bit = '1' then - if LCR(1 downto 0) = "00" then - if TX_Cnt = "10111" then - TX_Tick <= '1'; - TX_Cnt(3 downto 0) := "0000"; - end if; - else - if TX_Cnt = "11111" then - TX_Tick <= '1'; - TX_Cnt(3 downto 0) := "0000"; - end if; - end if; - else - TX_Cnt(4) := '1'; - if TX_Cnt(3 downto 0) = "1111" then - TX_Tick <= '1'; - end if; - end if; - end if; - end if; - end process; - - -- Transmit state machine - process (MR_n, XIn) - begin - if MR_n = '0' then - LSR(7 downto 5) <= "011"; - TX_Bit_Cnt <= 0; - TX_ShiftReg <= (others => '0'); - TXD <= '1'; - TX_Parity <= '0'; - TX_Next_Is_Stop <= '0'; - TX_Stop_Bit <= '0'; - elsif XIn'event and XIn = '1' then - if TX_Tick = '1' then - TX_Next_Is_Stop <= '0'; - TX_Stop_Bit <= TX_Next_Is_Stop; - case TX_Bit_Cnt is - when 0 => - if LSR(5) <= '0' then -- THRE - TX_Bit_Cnt <= 1; - end if; - TXD <= '1'; - when 1 => -- Start bit - TX_ShiftReg(7 downto 0) <= THR; - LSR(5) <= '1'; -- THRE - TXD <= '0'; - TX_Parity <= not LCR(4); -- EPS - TX_Bit_Cnt <= TX_Bit_Cnt + 1; - when 10 => -- Parity bit - TXD <= TX_Parity; - if LCR(5) = '1' then -- Stick parity - TXD <= not LCR(4); - end if; - TX_Bit_Cnt <= 0; - TX_Next_Is_Stop <= '1'; - when others => - TX_Bit_Cnt <= TX_Bit_Cnt + 1; - if (TX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or - (TX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or - (TX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or - (TX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then - TX_Bit_Cnt <= 0; - if LCR(3) = '1' then -- PEN - TX_Bit_Cnt <= 10; - else - TX_Next_Is_Stop <= '1'; - end if; - LSR(6) <= '1'; -- TEMT - end if; - TXD <= TX_ShiftReg(0); - TX_ShiftReg(6 downto 0) <= TX_ShiftReg(7 downto 1); - TX_Parity <= TX_ShiftReg(0) xor TX_Parity; - end case; - end if; - if Wr_n = '0' and CS_n = '0' and A = "000" and LCR(7) = '0' then - LSR(5) <= '0'; -- THRE - LSR(6) <= '0'; -- TEMT - end if; - end if; - end process; - -end; +-- +-- 16450 compatible UART with synchronous bus interface +-- RClk/BaudOut is XIn enable instead of actual clock +-- +-- Version : 0249b +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First release +-- +-- 0249 : Fixed interrupt and baud rate bugs found by Andy Dyer +-- Added modem status and break detection +-- Added support for 1.5 and 2 stop bits +-- +-- 0249b : Fixed loopback break generation bugs found by Andy Dyer +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T16450 is + port( + MR_n : in std_logic; + XIn : in std_logic; + RClk : in std_logic; + CS_n : in std_logic; + Rd_n : in std_logic; + Wr_n : in std_logic; + A : in std_logic_vector(2 downto 0); + D_In : in std_logic_vector(7 downto 0); + D_Out : out std_logic_vector(7 downto 0); + SIn : in std_logic; + CTS_n : in std_logic; + DSR_n : in std_logic; + RI_n : in std_logic; + DCD_n : in std_logic; + SOut : out std_logic; + RTS_n : out std_logic; + DTR_n : out std_logic; + OUT1_n : out std_logic; + OUT2_n : out std_logic; + BaudOut : out std_logic; + Intr : out std_logic + ); +end T16450; + +architecture rtl of T16450 is + + signal RBR : std_logic_vector(7 downto 0); -- Reciever Buffer Register + signal THR : std_logic_vector(7 downto 0); -- Transmitter Holding Register + signal IER : std_logic_vector(7 downto 0); -- Interrupt Enable Register + signal IIR : std_logic_vector(7 downto 0); -- Interrupt Ident. Register + signal LCR : std_logic_vector(7 downto 0); -- Line Control Register + signal MCR : std_logic_vector(7 downto 0); -- MODEM Control Register + signal LSR : std_logic_vector(7 downto 0); -- Line Status Register + signal MSR : std_logic_vector(7 downto 0); -- MODEM Status Register + signal SCR : std_logic_vector(7 downto 0); -- Scratch Register + signal DLL : std_logic_vector(7 downto 0); -- Divisor Latch (LS) + signal DLM : std_logic_vector(7 downto 0); -- Divisor Latch (MS) + + signal DM0 : std_logic_vector(7 downto 0); + signal DM1 : std_logic_vector(7 downto 0); + + signal MSR_In : std_logic_vector(3 downto 0); + + signal Bit_Phase : unsigned(3 downto 0); + signal Brk_Cnt : unsigned(3 downto 0); + signal RX_Filtered : std_logic; + signal RX_ShiftReg : std_logic_vector(7 downto 0); + signal RX_Bit_Cnt : integer range 0 to 11; + signal RX_Parity : std_logic; + signal RXD : std_logic; + + signal TX_Tick : std_logic; + signal TX_ShiftReg : std_logic_vector(7 downto 0); + signal TX_Bit_Cnt : integer range 0 to 11; + signal TX_Parity : std_logic; + signal TX_Next_Is_Stop : std_logic; + signal TX_Stop_Bit : std_logic; + signal TXD : std_logic; + +begin + + DTR_n <= MCR(4) or not MCR(0); + RTS_n <= MCR(4) or not MCR(1); + OUT1_n <= MCR(4) or not MCR(2); + OUT2_n <= MCR(4) or not MCR(3); + SOut <= MCR(4) or (TXD and not LCR(6)); + RXD <= SIn when MCR(4) = '0' else (TXD and not LCR(6)); + + Intr <= not IIR(0); + + -- Registers + DM0 <= DLL when LCR(7) = '1' else RBR; + DM1 <= DLM when LCR(7) = '1' else IER; + with A select + D_Out <= + DM0 when "000", + DM1 when "001", + IIR when "010", + LCR when "011", + MCR when "100", + LSR when "101", + MSR when "110", + SCR when others; + process (MR_n, XIn) + begin + if MR_n = '0' then + THR <= "00000000"; + IER <= "00000000"; + LCR <= "00000000"; + MCR <= "00000000"; + MSR(3 downto 0) <= "0000"; + SCR <= "00000000"; -- ?? + DLL <= "00000000"; -- ?? + DLM <= "00000000"; -- ?? + elsif XIn'event and XIn = '1' then + if Wr_n = '0' and CS_n = '0' then + case A is + when "000" => + if LCR(7) = '1' then + DLL <= D_In; + else + THR <= D_In; + end if; + when "001" => + if LCR(7) = '1' then + DLM <= D_In; + else + IER(3 downto 0) <= D_In(3 downto 0); + end if; + when "011" => + LCR <= D_In; + when "100" => + MCR <= D_In; + when "111" => + SCR <= D_In; + when others => + end case; + end if; + if Rd_n = '0' and CS_n = '0' and A = "110" then + MSR(3 downto 0) <= "0000"; + end if; + if MSR(4) /= MSR_In(0) then + MSR(0) <= '1'; + end if; + if MSR(5) /= MSR_In(1) then + MSR(1) <= '1'; + end if; + if MSR(6) = '0' and MSR_In(2) = '1' then + MSR(2) <= '1'; + end if; + if MSR(7) /= MSR_In(3) then + MSR(3) <= '1'; + end if; + end if; + end process; + process (XIn) + begin + if XIn'event and XIn = '1' then + if MCR(4) = '0' then + MSR(4) <= MSR_In(0); + MSR(5) <= MSR_In(1); + MSR(6) <= MSR_In(2); + MSR(7) <= MSR_In(3); + else + MSR(4) <= MCR(1); + MSR(5) <= MCR(0); + MSR(6) <= MCR(2); + MSR(7) <= MCR(3); + end if; + MSR_In(0) <= CTS_n; + MSR_In(1) <= DSR_n; + MSR_In(2) <= RI_n; + MSR_In(3) <= DCD_n; + end if; + end process; + + IIR(7 downto 3) <= "00000"; + IIR(2 downto 0) <= + "110" when IER(2) = '1' and LSR(4 downto 1) /= "0000" else + "100" when (IER(0) and LSR(0)) = '1' else + "010" when (IER(1) and LSR(5)) = '1' else + "000" when IER(3) = '1' and ((MCR(4) = '0' and MSR(3 downto 0) /= "0000") or + (MCR(4) = '1' and MCR(3 downto 0) /= "0000")) else + "001"; + + -- Baud x 16 clock generator + process (MR_n, XIn) + variable Baud_Cnt : unsigned(15 downto 0); + begin + if MR_n = '0' then + Baud_Cnt := "0000000000000000"; + BaudOut <= '0'; + elsif XIn'event and XIn = '1' then + if Baud_Cnt(15 downto 1) = "000000000000000" or (Wr_n = '0' and CS_n = '0' and A(2 downto 1) = "00" and LCR(7) = '1') then + Baud_Cnt(15 downto 8) := unsigned(DLM); + Baud_Cnt(7 downto 0) := unsigned(DLL); + BaudOut <= '1'; + else + Baud_Cnt := Baud_Cnt - 1; + BaudOut <= '0'; + end if; + end if; + end process; + + -- Input filter + process (MR_n, XIn) + variable Samples : std_logic_vector(1 downto 0); + begin + if MR_n = '0' then + Samples := "11"; + RX_Filtered <= '1'; + elsif XIn'event and XIn = '1' then + if RClk = '1' then + Samples(1) := Samples(0); + Samples(0) := RXD; + end if; + if Samples = "00" then + RX_Filtered <= '0'; + end if; + if Samples = "11" then + RX_Filtered <= '1'; + end if; + end if; + end process; + + -- Receive state machine + process (MR_n, XIn) + begin + if MR_n = '0' then + RBR <= "00000000"; + LSR(4 downto 0) <= "00000"; + Bit_Phase <= "0000"; + Brk_Cnt <= "0000"; + RX_ShiftReg(7 downto 0) <= "00000000"; + RX_Bit_Cnt <= 0; + RX_Parity <= '0'; + elsif XIn'event and XIn = '1' then + if A = "000" and LCR(7) = '0' and Rd_n = '0' and CS_n = '0' then + LSR(0) <= '0'; -- DR + end if; + if A = "101" and Rd_n = '0' and CS_n = '0' then + LSR(4) <= '0'; -- BI + LSR(3) <= '0'; -- FE + LSR(2) <= '0'; -- PE + LSR(1) <= '0'; -- OE + end if; + if RClk = '1' then + if RX_Bit_Cnt = 0 and (RX_Filtered = '1' or Bit_Phase = "0111") then + Bit_Phase <= "0000"; + else + Bit_Phase <= Bit_Phase + 1; + end if; + if Bit_Phase = "1111" then + if RX_Filtered = '1' then + Brk_Cnt <= "0000"; + else + Brk_Cnt <= Brk_Cnt + 1; + end if; + if Brk_Cnt = "1100" then + LSR(4) <= '1'; -- BI + end if; + end if; + if RX_Bit_Cnt = 0 then + if Bit_Phase = "0111" then + RX_Bit_Cnt <= RX_Bit_Cnt + 1; + RX_Parity <= not LCR(4); -- EPS + end if; + elsif Bit_Phase = "1111" then + RX_Bit_Cnt <= RX_Bit_Cnt + 1; + if RX_Bit_Cnt = 10 then -- Parity stop bit + RX_Bit_Cnt <= 0; + LSR(0) <= '1'; -- UART Receive complete + LSR(3) <= not RX_Filtered; -- Framing error + elsif (RX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or + (RX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or + (RX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or + (RX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then -- Stop bit/Parity + RX_Bit_Cnt <= 0; + if LCR(3) = '1' then -- PEN + RX_Bit_Cnt <= 10; + if LCR(5) = '1' then -- Stick parity + if RX_Filtered = LCR(4) then + LSR(2) <= '1'; + end if; + else + if RX_Filtered /= RX_Parity then + LSR(2) <= '1'; + end if; + end if; + else + LSR(0) <= '1'; -- UART Receive complete + LSR(3) <= not RX_Filtered; -- Framing error + end if; + RBR <= RX_ShiftReg(7 downto 0); + LSR(1) <= LSR(0); + if A = "101" and Rd_n = '0' and CS_n = '0' then + LSR(1) <= '0'; + end if; + else + RX_ShiftReg(6 downto 0) <= RX_ShiftReg(7 downto 1); + RX_ShiftReg(7) <= RX_Filtered; + if LCR(1 downto 0) = "10" then + RX_ShiftReg(7) <= '0'; + RX_ShiftReg(6) <= RX_Filtered; + end if; + if LCR(1 downto 0) = "01" then + RX_ShiftReg(7) <= '0'; + RX_ShiftReg(6) <= '0'; + RX_ShiftReg(5) <= RX_Filtered; + end if; + if LCR(1 downto 0) = "00" then + RX_ShiftReg(7) <= '0'; + RX_ShiftReg(6) <= '0'; + RX_ShiftReg(5) <= '0'; + RX_ShiftReg(4) <= RX_Filtered; + end if; + RX_Parity <= RX_Filtered xor RX_Parity; + end if; + end if; + end if; + end if; + end process; + + -- Transmit bit tick + process (MR_n, XIn) + variable TX_Cnt : unsigned(4 downto 0); + begin + if MR_n = '0' then + TX_Cnt := "00000"; + TX_Tick <= '0'; + elsif XIn'event and XIn = '1' then + TX_Tick <= '0'; + if RClk = '1' then + TX_Cnt := TX_Cnt + 1; + if LCR(2) = '1' and TX_Stop_Bit = '1' then + if LCR(1 downto 0) = "00" then + if TX_Cnt = "10111" then + TX_Tick <= '1'; + TX_Cnt(3 downto 0) := "0000"; + end if; + else + if TX_Cnt = "11111" then + TX_Tick <= '1'; + TX_Cnt(3 downto 0) := "0000"; + end if; + end if; + else + TX_Cnt(4) := '1'; + if TX_Cnt(3 downto 0) = "1111" then + TX_Tick <= '1'; + end if; + end if; + end if; + end if; + end process; + + -- Transmit state machine + process (MR_n, XIn) + begin + if MR_n = '0' then + LSR(7 downto 5) <= "011"; + TX_Bit_Cnt <= 0; + TX_ShiftReg <= (others => '0'); + TXD <= '1'; + TX_Parity <= '0'; + TX_Next_Is_Stop <= '0'; + TX_Stop_Bit <= '0'; + elsif XIn'event and XIn = '1' then + if TX_Tick = '1' then + TX_Next_Is_Stop <= '0'; + TX_Stop_Bit <= TX_Next_Is_Stop; + case TX_Bit_Cnt is + when 0 => + if LSR(5) <= '0' then -- THRE + TX_Bit_Cnt <= 1; + end if; + TXD <= '1'; + when 1 => -- Start bit + TX_ShiftReg(7 downto 0) <= THR; + LSR(5) <= '1'; -- THRE + TXD <= '0'; + TX_Parity <= not LCR(4); -- EPS + TX_Bit_Cnt <= TX_Bit_Cnt + 1; + when 10 => -- Parity bit + TXD <= TX_Parity; + if LCR(5) = '1' then -- Stick parity + TXD <= not LCR(4); + end if; + TX_Bit_Cnt <= 0; + TX_Next_Is_Stop <= '1'; + when others => + TX_Bit_Cnt <= TX_Bit_Cnt + 1; + if (TX_Bit_Cnt = 9 and LCR(1 downto 0) = "11") or + (TX_Bit_Cnt = 8 and LCR(1 downto 0) = "10") or + (TX_Bit_Cnt = 7 and LCR(1 downto 0) = "01") or + (TX_Bit_Cnt = 6 and LCR(1 downto 0) = "00") then + TX_Bit_Cnt <= 0; + if LCR(3) = '1' then -- PEN + TX_Bit_Cnt <= 10; + else + TX_Next_Is_Stop <= '1'; + end if; + LSR(6) <= '1'; -- TEMT + end if; + TXD <= TX_ShiftReg(0); + TX_ShiftReg(6 downto 0) <= TX_ShiftReg(7 downto 1); + TX_Parity <= TX_ShiftReg(0) xor TX_Parity; + end case; + end if; + if Wr_n = '0' and CS_n = '0' and A = "000" and LCR(7) = '0' then + LSR(5) <= '0'; -- THRE + LSR(6) <= '0'; -- TEMT + end if; + end if; + end process; + +end; diff --git a/modules/cpu-t80/T80.vhd b/modules/cpu-t80/T80.vhd index 641ed7a..99bedd9 100644 --- a/modules/cpu-t80/T80.vhd +++ b/modules/cpu-t80/T80.vhd @@ -1,1338 +1,1338 @@ --------------------------------------------------------------------------------- --- **** --- T80(c) core. Attempt to finish all undocumented features and provide --- accurate timings. --- Version 350. --- Copyright (c) 2018 Sorgelig --- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr --- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as --- correct implementation is still unclear. --- --- **** --- T80(b) core. In an effort to merge and maintain bug fixes .... --- --- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010 --- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle --- Ver 300 started tidyup. --- --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) --- --- **** --- Z80 compatible microprocessor core --- --- Version : 0250 --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0208 : First complete release --- 0210 : Fixed wait and halt --- 0211 : Fixed Refresh addition and IM 1 --- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test --- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson --- 0235 : Added clock enable and IM 2 fix by Mike Johnson --- 0237 : Changed 8080 I/O address output, added IntE output --- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag --- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode --- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM --- 0247 : Fixed bus req/ack cycle --- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15 --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use IEEE.STD_LOGIC_UNSIGNED.all; -use work.T80_Pack.all; - -entity T80 is - generic( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - IOWait : integer := 0; -- 0 => Single cycle I/O, 1 => Std I/O cycle - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - CEN : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - IORQ : out std_logic; - NoRead : out std_logic; - Write : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DInst : in std_logic_vector(7 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0); - MC : out std_logic_vector(2 downto 0); - TS : out std_logic_vector(2 downto 0); - IntCycle_n : out std_logic; - IntE : out std_logic; - Stop : out std_logic; - R800_mode : in std_logic := '0'; - out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 - REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A - - DIRSet : in std_logic := '0'; - DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A - ); -end T80; - -architecture rtl of T80 is - - -- Registers - signal ACC, F : std_logic_vector(7 downto 0); - signal Ap, Fp : std_logic_vector(7 downto 0); - signal I : std_logic_vector(7 downto 0); - signal R : unsigned(7 downto 0); - signal SP, PC : unsigned(15 downto 0); - - signal RegDIH : std_logic_vector(7 downto 0); - signal RegDIL : std_logic_vector(7 downto 0); - signal RegBusA : std_logic_vector(15 downto 0); - signal RegBusB : std_logic_vector(15 downto 0); - signal RegBusC : std_logic_vector(15 downto 0); - signal RegAddrA_r : std_logic_vector(2 downto 0); - signal RegAddrA : std_logic_vector(2 downto 0); - signal RegAddrB_r : std_logic_vector(2 downto 0); - signal RegAddrB : std_logic_vector(2 downto 0); - signal RegAddrC : std_logic_vector(2 downto 0); - signal RegWEH : std_logic; - signal RegWEL : std_logic; - signal Alternate : std_logic; - - -- Help Registers - signal WZ : std_logic_vector(15 downto 0); -- MEMPTR register - signal TmpAddr2 : std_logic_vector(15 downto 0); -- Temporary address register - signal IR : std_logic_vector(7 downto 0); -- Instruction register - signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector - signal RegBusA_r : std_logic_vector(15 downto 0); - signal MULU_Prod32 : std_logic_vector(31 downto 0); - signal MULU_tmp : std_logic_vector(31 downto 0); - signal MULU_Fakt1 : std_logic_vector(15 downto 0); - - signal ID16 : signed(15 downto 0); - signal Save_Mux : std_logic_vector(7 downto 0); - - signal TState : unsigned(2 downto 0); - signal MCycle : std_logic_vector(2 downto 0); - signal IntE_FF1 : std_logic; - signal IntE_FF2 : std_logic; - signal Halt_FF : std_logic; - signal BusReq_s : std_logic := '0'; - signal BusAck : std_logic := '0'; - signal ClkEn : std_logic; - signal NMI_s : std_logic; - signal IStatus : std_logic_vector(1 downto 0); - - signal DI_Reg : std_logic_vector(7 downto 0); - signal T_Res : std_logic; - signal XY_State : std_logic_vector(1 downto 0); - signal Pre_XY_F_M : std_logic_vector(2 downto 0); - signal NextIs_XY_Fetch : std_logic; - signal XY_Ind : std_logic; - signal No_BTR : std_logic; - signal BTR_r : std_logic; - signal Auto_Wait : std_logic; - signal Auto_Wait_t1 : std_logic; - signal Auto_Wait_t2 : std_logic; - signal IncDecZ : std_logic; - - -- ALU signals - signal BusB : std_logic_vector(7 downto 0); - signal BusA : std_logic_vector(7 downto 0); - signal ALU_Q : std_logic_vector(7 downto 0); - signal F_Out : std_logic_vector(7 downto 0); - - -- Registered micro code outputs - signal Read_To_Reg_r : std_logic_vector(4 downto 0); - signal Arith16_r : std_logic; - signal Z16_r : std_logic; - signal ALU_Op_r : std_logic_vector(3 downto 0); - signal Save_ALU_r : std_logic; - signal PreserveC_r : std_logic; - signal MCycles : std_logic_vector(2 downto 0); - - -- Micro code outputs - signal MCycles_d : std_logic_vector(2 downto 0); - signal TStates : std_logic_vector(2 downto 0); - signal IntCycle : std_logic; - signal NMICycle : std_logic; - signal Inc_PC : std_logic; - signal Inc_WZ : std_logic; - signal IncDec_16 : std_logic_vector(3 downto 0); - signal Prefix : std_logic_vector(1 downto 0); - signal Read_To_Acc : std_logic; - signal Read_To_Reg : std_logic; - signal Set_BusB_To : std_logic_vector(3 downto 0); - signal Set_BusA_To : std_logic_vector(3 downto 0); - signal ALU_Op : std_logic_vector(3 downto 0); - signal Save_ALU : std_logic; - signal Rot_Akku : std_logic; - signal PreserveC : std_logic; - signal Arith16 : std_logic; - signal Set_Addr_To : std_logic_vector(2 downto 0); - signal Jump : std_logic; - signal JumpE : std_logic; - signal JumpXY : std_logic; - signal Call : std_logic; - signal RstP : std_logic; - signal LDZ : std_logic; - signal LDW : std_logic; - signal LDSPHL : std_logic; - signal LDHLSP : std_logic; - signal ADDSPdd : std_logic; - signal IORQ_i : std_logic; - signal Special_LD : std_logic_vector(2 downto 0); - signal ExchangeDH : std_logic; - signal ExchangeRp : std_logic; - signal ExchangeAF : std_logic; - signal ExchangeRS : std_logic; - signal ExchangeWH : std_logic; - signal I_DJNZ : std_logic; - signal I_CPL : std_logic; - signal I_CCF : std_logic; - signal I_SCF : std_logic; - signal I_RETN : std_logic; - signal I_BT : std_logic; - signal I_BC : std_logic; - signal I_BTR : std_logic; - signal I_RLD : std_logic; - signal I_RRD : std_logic; - signal I_RXDD : std_logic; - signal I_INRC : std_logic; - signal I_MULUB : std_logic; - signal I_MULU : std_logic; - signal SetWZ : std_logic_vector(1 downto 0); - signal SetDI : std_logic; - signal SetEI : std_logic; - signal IMode : std_logic_vector(1 downto 0); - signal Halt : std_logic; - signal XYbit_undoc : std_logic; - signal No_PC : std_logic; - signal DOR : std_logic_vector(127 downto 0); - -begin - - REG <= IntE_FF2 & IntE_FF1 & IStatus & DOR & std_logic_vector(PC) & std_logic_vector(SP) & std_logic_vector(R) & I & Fp & Ap & F & ACC when Alternate = '0' - else IntE_FF2 & IntE_FF1 & IStatus & DOR(127 downto 112) & DOR(47 downto 0) & DOR(63 downto 48) & DOR(111 downto 64) & - std_logic_vector(PC) & std_logic_vector(SP) & std_logic_vector(R) & I & Fp & Ap & F & ACC; - - mcode : T80_MCode - generic map( - Mode => Mode, - Flag_C => Flag_C, - Flag_N => Flag_N, - Flag_P => Flag_P, - Flag_X => Flag_X, - Flag_H => Flag_H, - Flag_Y => Flag_Y, - Flag_Z => Flag_Z, - Flag_S => Flag_S) - port map( - IR => IR, - ISet => ISet, - MCycle => MCycle, - F => F, - NMICycle => NMICycle, - IntCycle => IntCycle, - XY_State => XY_State, - MCycles => MCycles_d, - TStates => TStates, - Prefix => Prefix, - Inc_PC => Inc_PC, - Inc_WZ => Inc_WZ, - IncDec_16 => IncDec_16, - Read_To_Acc => Read_To_Acc, - Read_To_Reg => Read_To_Reg, - Set_BusB_To => Set_BusB_To, - Set_BusA_To => Set_BusA_To, - ALU_Op => ALU_Op, - Save_ALU => Save_ALU, - Rot_Akku => Rot_Akku, - PreserveC => PreserveC, - Arith16 => Arith16, - Set_Addr_To => Set_Addr_To, - IORQ => IORQ_i, - Jump => Jump, - JumpE => JumpE, - JumpXY => JumpXY, - Call => Call, - RstP => RstP, - LDZ => LDZ, - LDW => LDW, - LDSPHL => LDSPHL, - LDHLSP => LDHLSP, - ADDSPdd => ADDSPdd, - Special_LD => Special_LD, - ExchangeDH => ExchangeDH, - ExchangeRp => ExchangeRp, - ExchangeAF => ExchangeAF, - ExchangeRS => ExchangeRS, - ExchangeWH => ExchangeWH, - I_DJNZ => I_DJNZ, - I_CPL => I_CPL, - I_CCF => I_CCF, - I_SCF => I_SCF, - I_RETN => I_RETN, - I_BT => I_BT, - I_BC => I_BC, - I_BTR => I_BTR, - I_RLD => I_RLD, - I_RRD => I_RRD, - I_INRC => I_INRC, - I_MULUB => I_MULUB, - I_MULU => I_MULU, - SetWZ => SetWZ, - SetDI => SetDI, - SetEI => SetEI, - IMode => IMode, - Halt => Halt, - NoRead => NoRead, - Write => Write, - R800_mode => R800_mode, - No_PC => No_PC, - XYbit_undoc => XYbit_undoc); - - alu : T80_ALU - generic map( - Mode => Mode, - Flag_C => Flag_C, - Flag_N => Flag_N, - Flag_P => Flag_P, - Flag_X => Flag_X, - Flag_H => Flag_H, - Flag_Y => Flag_Y, - Flag_Z => Flag_Z, - Flag_S => Flag_S) - port map( - Arith16 => Arith16_r, - Z16 => Z16_r, - WZ => WZ, - XY_State=> XY_State, - ALU_Op => ALU_Op_r, - Rot_Akku => Rot_Akku, - IR => IR(5 downto 0), - ISet => ISet, - BusA => BusA, - BusB => BusB, - F_In => F, - Q => ALU_Q, - F_Out => F_Out); - - ClkEn <= CEN and not BusAck; - - T_Res <= '1' when TState = unsigned(TStates) else '0'; - - NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and - ((Set_Addr_To = aXY) or - (MCycle = "001" and IR = "11001011") or - (MCycle = "001" and IR = "00110110")) else '0'; - - Save_Mux <= BusB when ExchangeRp = '1' else - DI_Reg when Save_ALU_r = '0' else - ALU_Q; - - process (RESET_n, CLK_n) - variable n : std_logic_vector(7 downto 0); - variable ioq : std_logic_vector(8 downto 0); - variable temp_c : unsigned(8 downto 0); - variable temp_h : unsigned(4 downto 0); - begin - if RESET_n = '0' then - PC <= (others => '0'); -- Program Counter - A <= (others => '0'); - WZ <= (others => '0'); - IR <= "00000000"; - ISet <= "00"; - XY_State <= "00"; - IStatus <= "00"; - MCycles <= "000"; - DO <= "00000000"; - - ACC <= (others => '1'); - F <= (others => '1'); - if Mode = 3 then - ACC <= (others => '0'); - F <= "11110000"; - end if; - - Ap <= (others => '1'); - Fp <= (others => '1'); - I <= (others => '0'); - R <= (others => '0'); - SP <= (others => '1'); - Alternate <= '0'; - - Read_To_Reg_r <= "00000"; - Arith16_r <= '0'; - BTR_r <= '0'; - Z16_r <= '0'; - ALU_Op_r <= "0000"; - Save_ALU_r <= '0'; - PreserveC_r <= '0'; - XY_Ind <= '0'; - I_RXDD <= '0'; - - elsif rising_edge(CLK_n) then - - if DIRSet = '1' then - ACC <= DIR( 7 downto 0); - F <= DIR(15 downto 8); - Ap <= DIR(23 downto 16); - Fp <= DIR(31 downto 24); - I <= DIR(39 downto 32); - R <= unsigned(DIR(47 downto 40)); - SP <= unsigned(DIR(63 downto 48)); - PC <= unsigned(DIR(79 downto 64)); - A <= DIR(79 downto 64); - IStatus <= DIR(209 downto 208); - - elsif ClkEn = '1' then - ALU_Op_r <= "0000"; - Save_ALU_r <= '0'; - Read_To_Reg_r <= "00000"; - - MCycles <= MCycles_d; - - if LDHLSP = '1' and MCycle = "011" and TState = 1 then - temp_c := unsigned('0'&SP(7 downto 0))+unsigned('0'&Save_Mux); - temp_h := unsigned('0'&SP(3 downto 0))+unsigned('0'&Save_Mux(3 downto 0)); - F(Flag_Z) <= '0'; - F(Flag_N) <= '0'; - F(Flag_H) <= temp_h(4); - F(Flag_C) <= temp_c(8); - end if; - - if ADDSPdd = '1' and TState = 1 then - temp_c := unsigned('0'&SP(7 downto 0))+unsigned('0'&Save_Mux); - temp_h := unsigned('0'&SP(3 downto 0))+unsigned('0'&Save_Mux(3 downto 0)); - F(Flag_Z) <= '0'; - F(Flag_N) <= '0'; - F(Flag_H) <= temp_h(4); - F(Flag_C) <= temp_c(8); - end if; - - if Mode = 3 then - IStatus <= "10"; - elsif IMode /= "11" then - IStatus <= IMode; - end if; - - Arith16_r <= Arith16; - PreserveC_r <= PreserveC; - if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then - Z16_r <= '1'; - else - Z16_r <= '0'; - end if; - - if MCycle = "001" and TState(2) = '0' then - -- MCycle = 1 and TState = 1, 2, or 3 - - if TState = 2 and Wait_n = '1' then - if Mode < 2 then - A(7 downto 0) <= std_logic_vector(R); - A(15 downto 8) <= I; - R(6 downto 0) <= R(6 downto 0) + 1; - end if; - - if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then - PC <= PC + 1; - end if; - - if IntCycle = '1' and IStatus = "01" then - IR <= "11111111"; - elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then - IR <= "00000000"; - else - IR <= DInst; - end if; - - if Mode <= 1 and IntCycle = '1' and IStatus = "10" then - -- IM2 vector address low byte from bus - WZ(7 downto 0) <= DInst; - end if; - - ISet <= "00"; - if Prefix /= "00" then - if Prefix = "11" then - if IR(5) = '1' then - XY_State <= "10"; - else - XY_State <= "01"; - end if; - else - if Prefix = "10" then - XY_State <= "00"; - XY_Ind <= '0'; - end if; - ISet <= Prefix; - end if; - else - XY_State <= "00"; - XY_Ind <= '0'; - end if; - end if; - - else - -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3) - - if MCycle = "110" then - XY_Ind <= '1'; - if Prefix = "01" then - ISet <= "01"; - end if; - end if; - - if T_Res = '1' then - BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR; - if Jump = '1' then - A(15 downto 8) <= DI_Reg; - A(7 downto 0) <= WZ(7 downto 0); - PC(15 downto 8) <= unsigned(DI_Reg); - PC(7 downto 0) <= unsigned(WZ(7 downto 0)); - elsif JumpXY = '1' then - A <= RegBusC; - PC <= unsigned(RegBusC); - elsif Call = '1' or RstP = '1' then - A <= WZ; - PC <= unsigned(WZ); - elsif MCycle = MCycles and NMICycle = '1' then - A <= "0000000001100110"; - PC <= "0000000001100110"; - elsif ((Mode /= 3 and MCycle = "011") or (Mode = 3 and MCycle = "100")) - and IntCycle = '1' and IStatus = "10" then - A(15 downto 8) <= I; - A(7 downto 0) <= WZ(7 downto 0); - PC(15 downto 8) <= unsigned(I); - PC(7 downto 0) <= unsigned(WZ(7 downto 0)); - else - case Set_Addr_To is - when aXY => - if XY_State = "00" then - A <= RegBusC; - else - if NextIs_XY_Fetch = '1' then - A <= std_logic_vector(PC); - else - A <= WZ; - end if; - end if; - when aIOA => - if Mode = 3 then - -- Memory map I/O on GBZ80 - A(15 downto 8) <= (others => '1'); - elsif Mode = 2 then - -- Duplicate I/O address on 8080 - A(15 downto 8) <= DI_Reg; - else - A(15 downto 8) <= ACC; - end if; - A(7 downto 0) <= DI_Reg; - WZ <= (ACC & DI_Reg) + "1"; - when aSP => - A <= std_logic_vector(SP); - when aBC => - if Mode = 3 and IORQ_i = '1' then - -- Memory map I/O on GBZ80 - A(15 downto 8) <= (others => '1'); - A(7 downto 0) <= RegBusC(7 downto 0); - else - A <= RegBusC; - if SetWZ = "01" then - WZ <= RegBusC + "1"; - end if; - if SetWZ = "10" then - WZ(7 downto 0) <= RegBusC(7 downto 0) + "1"; - WZ(15 downto 8) <= ACC; - end if; - end if; - when aDE => - A <= RegBusC; - if SetWZ = "10" then - WZ(7 downto 0) <= RegBusC(7 downto 0) + "1"; - WZ(15 downto 8) <= ACC; - end if; - when aZI => - if Inc_WZ = '1' then - A <= std_logic_vector(unsigned(WZ) + 1); - else - A(15 downto 8) <= DI_Reg; - A(7 downto 0) <= WZ(7 downto 0); - if SetWZ = "10" then - WZ(7 downto 0) <= WZ(7 downto 0) + "1"; - WZ(15 downto 8) <= ACC; - end if; - end if; - when others => - if ISet = "10" and IR(7 downto 4) = x"B" and IR(2 downto 1) = "01" and MCycle = 3 and No_BTR = '0' then - -- INIR, INDR, OTIR, OTDR - A <= RegBusA_r; - elsif No_PC = '0' or No_BTR = '1' or (I_DJNZ = '1' and IncDecZ = '1') or Mode > 1 then - A <= std_logic_vector(PC); - end if; - end case; - end if; - - if SetWZ = "11" then - WZ <= std_logic_vector(ID16); - end if; - - Save_ALU_r <= Save_ALU; - ALU_Op_r <= ALU_Op; - - if Mode = 3 then - if I_CPL = '1' then - -- CPL - ACC <= not ACC; - F(Flag_H) <= '1'; - F(Flag_N) <= '1'; - end if; - if I_CCF = '1' then - -- CCF - F(Flag_C) <= not F(Flag_C); - F(Flag_H) <= '0'; - F(Flag_N) <= '0'; - end if; - if I_SCF = '1' then - -- SCF - F(Flag_C) <= '1'; - F(Flag_H) <= '0'; - F(Flag_N) <= '0'; - end if; - else - if I_CPL = '1' then - -- CPL - ACC <= not ACC; - F(Flag_Y) <= not ACC(5); - F(Flag_H) <= '1'; - F(Flag_X) <= not ACC(3); - F(Flag_N) <= '1'; - end if; - if I_CCF = '1' then - -- CCF - F(Flag_C) <= not F(Flag_C); - F(Flag_Y) <= ACC(5); - F(Flag_H) <= F(Flag_C); - F(Flag_X) <= ACC(3); - F(Flag_N) <= '0'; - end if; - if I_SCF = '1' then - -- SCF - F(Flag_C) <= '1'; - F(Flag_Y) <= ACC(5); - F(Flag_H) <= '0'; - F(Flag_X) <= ACC(3); - F(Flag_N) <= '0'; - end if; - end if; - end if; - - if (TState = 2 and I_BTR = '1' and IR(0) = '1') or (TState = 1 and I_BTR = '1' and IR(0) = '0') then - ioq := ('0' & DI_Reg) + ('0' & std_logic_vector(ID16(7 downto 0))); - F(Flag_N) <= DI_Reg(7); - F(Flag_C) <= ioq(8); - F(Flag_H) <= ioq(8); - ioq := (ioq and "000000111") xor ('0'&BusA); - F(Flag_P) <= not (ioq(0) xor ioq(1) xor ioq(2) xor ioq(3) xor ioq(4) xor ioq(5) xor ioq(6) xor ioq(7)); - end if; - - if TState = 2 and Wait_n = '1' then - if ISet = "01" and MCycle = "111" then - IR <= DInst; - end if; - if JumpE = '1' then - PC <= unsigned(signed(PC) + signed(DI_Reg)); - WZ <= std_logic_vector(signed(PC) + signed(DI_Reg)); - elsif Inc_PC = '1' then - PC <= PC + 1; - end if; - if BTR_r = '1' then - PC <= PC - 2; - end if; - if RstP = '1' then - WZ <= (others =>'0'); - WZ(5 downto 3) <= IR(5 downto 3); - end if; - end if; - if TState = 3 and MCycle = "110" then - WZ <= std_logic_vector(signed(RegBusC) + signed(DI_Reg)); - end if; - - if MCycle = "011" and TState = 4 and No_BTR = '0' then - if I_BT = '1' or I_BC = '1' then - WZ <= std_logic_vector(PC)-"1"; - end if; - end if; - - if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then - if IncDec_16(2 downto 0) = "111" then - if IncDec_16(3) = '1' then - SP <= SP - 1; - else - SP <= SP + 1; - end if; - end if; - end if; - - if ADDSPdd = '1' and TState = 2 then - WZ <= std_logic_vector(SP); - SP <= unsigned(signed(SP)+signed(Save_Mux)); - end if; - - if LDSPHL = '1' then - SP <= unsigned(RegBusC); - end if; - if ExchangeAF = '1' then - Ap <= ACC; - ACC <= Ap; - Fp <= F; - F <= Fp; - end if; - if ExchangeRS = '1' then - Alternate <= not Alternate; - end if; - end if; - - if TState = 3 then - if LDZ = '1' then - WZ(7 downto 0) <= DI_Reg; - end if; - if LDW = '1' then - WZ(15 downto 8) <= DI_Reg; - end if; - - if Special_LD(2) = '1' then - case Special_LD(1 downto 0) is - when "00" => - ACC <= I; - F(Flag_P) <= IntE_FF2; - F(Flag_S) <= I(7); - - if I = x"00" then - F(Flag_Z) <= '1'; - else - F(Flag_Z) <= '0'; - end if; - - F(Flag_Y) <= I(5); - F(Flag_H) <= '0'; - F(Flag_X) <= I(3); - F(Flag_N) <= '0'; - - - when "01" => - ACC <= std_logic_vector(R); - F(Flag_P) <= IntE_FF2; - F(Flag_S) <= R(7); - - if R = x"00" then - F(Flag_Z) <= '1'; - else - F(Flag_Z) <= '0'; - end if; - - F(Flag_Y) <= R(5); - F(Flag_H) <= '0'; - F(Flag_X) <= R(3); - F(Flag_N) <= '0'; - - when "10" => - I <= ACC; - when others => - R <= unsigned(ACC); - end case; - end if; - end if; - - if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then - if Mode = 3 then - F(6) <= F_Out(6); - F(5) <= F_Out(5); - F(7) <= F_Out(7); - if PreserveC_r = '0' then - F(4) <= F_Out(4); - end if; - else - F(7 downto 1) <= F_Out(7 downto 1); - if PreserveC_r = '0' then - F(Flag_C) <= F_Out(0); - end if; - end if; - end if; - if T_Res = '1' and I_INRC = '1' then - F(Flag_H) <= '0'; - F(Flag_N) <= '0'; - F(Flag_X) <= DI_Reg(3); - F(Flag_Y) <= DI_Reg(5); - if DI_Reg(7 downto 0) = "00000000" then - F(Flag_Z) <= '1'; - else - F(Flag_Z) <= '0'; - end if; - F(Flag_S) <= DI_Reg(7); - F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor - DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7)); - end if; - - if TState = 1 and Auto_Wait_t1 = '0' then - -- Keep D0 from M3 for RLD/RRD (Sorgelig) - I_RXDD <= I_RLD or I_RRD; - if I_RXDD='0' then - DO <= BusB; - end if; - if I_RLD = '1' then - DO(3 downto 0) <= BusA(3 downto 0); - DO(7 downto 4) <= BusB(3 downto 0); - end if; - if I_RRD = '1' then - DO(3 downto 0) <= BusB(7 downto 4); - DO(7 downto 4) <= BusA(3 downto 0); - end if; - end if; - - if T_Res = '1' then - Read_To_Reg_r(3 downto 0) <= Set_BusA_To; - Read_To_Reg_r(4) <= Read_To_Reg; - if Read_To_Acc = '1' then - Read_To_Reg_r(3 downto 0) <= "0111"; - Read_To_Reg_r(4) <= '1'; - end if; - end if; - - if TState = 1 and I_BT = '1' then - F(Flag_X) <= ALU_Q(3); - F(Flag_Y) <= ALU_Q(1); - F(Flag_H) <= '0'; - F(Flag_N) <= '0'; - end if; - if TState = 1 and I_BC = '1' then - n := ALU_Q - ("0000000" & F_Out(Flag_H)); - F(Flag_X) <= n(3); - F(Flag_Y) <= n(1); - end if; - if I_BC = '1' or I_BT = '1' then - F(Flag_P) <= IncDecZ; - end if; - - if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or - (Save_ALU_r = '1' and ALU_OP_r /= "0111") then - case Read_To_Reg_r is - when "10111" => - ACC <= Save_Mux; - when "10110" => - DO <= Save_Mux; - when "11000" => - SP(7 downto 0) <= unsigned(Save_Mux); - when "11001" => - SP(15 downto 8) <= unsigned(Save_Mux); - when "11011" => - if Mode = 3 then - F(7 downto 4) <= Save_Mux(7 downto 4); - F(3 downto 0) <= "0000"; -- bit 3 to 0 always return 0 - else - F <= Save_Mux; - end if; - when others => - end case; - if XYbit_undoc='1' then - DO <= ALU_Q; - end if; - end if; - end if; - end if; - end process; - ---------------------------------------------------------------------------- --- --- Multiply --- ---------------------------------------------------------------------------- - process (CLK_n, ACC, RegBusB, MULU_tmp, MULU_Fakt1, MULU_Prod32) - begin - - MULU_tmp(31 downto 12) <= std_logic_vector((unsigned(MULU_Fakt1)*unsigned(MULU_Prod32(3 downto 0)))+unsigned("0000"&MULU_Prod32(31 downto 16))); - MULU_tmp(11 downto 0) <= MULU_Prod32(15 downto 4); - - if rising_edge(CLK_n) then - if ClkEn = '1' then - if T_Res='1' then - if I_MULUB='1' then - MULU_Prod32(7 downto 0) <= ACC; - MULU_Prod32(15 downto 8) <= "--------"; - MULU_Prod32(31 downto 16) <= X"0000"; - MULU_Fakt1(7 downto 0) <= "00000000"; - if Set_BusB_To(0) = '1' then - MULU_Fakt1(15 downto 8) <= RegBusB(7 downto 0); - else - MULU_Fakt1(15 downto 8) <= RegBusB(15 downto 8); - end if; - else - MULU_Prod32(15 downto 0) <= RegBusA; - MULU_Prod32(31 downto 16) <= X"0000"; - MULU_Fakt1 <= RegBusB; - end if; - else - MULU_Prod32 <= MULU_tmp; - end if; - end if; - end if; - end process; - ---------------------------------------------------------------------------- --- --- BC('), DE('), HL('), IX and IY --- ---------------------------------------------------------------------------- - process (CLK_n) - begin - if rising_edge(CLK_n) then - if ClkEn = '1' then - -- Bus A / Write - RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1); - if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then - RegAddrA_r <= XY_State(1) & "11"; - end if; - - -- Bus B - RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1); - if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then - RegAddrB_r <= XY_State(1) & "11"; - end if; - - -- Address from register - RegAddrC <= Alternate & Set_Addr_To(1 downto 0); - -- Jump (HL), LD SP,HL - if (JumpXY = '1' or LDSPHL = '1') then - RegAddrC <= Alternate & "10"; - end if; - if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then - RegAddrC <= XY_State(1) & "11"; - end if; - - if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then - IncDecZ <= F_Out(Flag_Z); - end if; - if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then - if ID16 = 0 then - IncDecZ <= '0'; - else - IncDecZ <= '1'; - end if; - end if; - - RegBusA_r <= RegBusA; - end if; - end if; - end process; - - RegAddrA <= - -- 16 bit increment/decrement - Alternate & IncDec_16(1 downto 0) when (TState = 2 or - (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else - XY_State(1) & "11" when (TState = 2 or - (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else - -- EX HL,DL - Alternate & "10" when ExchangeDH = '1' and TState = 3 else - Alternate & "01" when (ExchangeDH = '1' or I_MULU = '1') and TState = 4 else - -- EX (SP),HL (HL(IX,IY) <= WZ) - Alternate & "10" when ExchangeWH = '1' and XY_State = "00" and TState = 4 else - XY_State(1) & "11" when ExchangeWH = '1' and TState = 4 else - -- LDHLSP - "010" when LDHLSP = '1' and TState = 4 else - - -- Bus A / Write - RegAddrA_r; - - RegAddrB <= - -- EX HL,DL - Alternate & "01" when ExchangeDH = '1' and TState = 3 else - -- Bus B - RegAddrB_r; - - ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else - signed(RegBusA) + 1; - - process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, I_MULU, T_Res, - ExchangeDH, ExchangeWH, IncDec_16, MCycle, TState, Wait_n, LDHLSP) - begin - RegWEH <= '0'; - RegWEL <= '0'; - if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or - (Save_ALU_r = '1' and ALU_OP_r /= "0111") then - case Read_To_Reg_r is - when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" => - RegWEH <= not Read_To_Reg_r(0); - RegWEL <= Read_To_Reg_r(0); - when others => - end case; - end if; - - if I_MULU = '1' and (T_Res = '1' or TState = 4) then -- TState = 4 DE write - RegWEH <= '1'; - RegWEL <= '1'; - end if; - - if ExchangeDH = '1' and (TState = 3 or TState = 4) then - RegWEH <= '1'; - RegWEL <= '1'; - end if; - - if ((LDHLSP = '1' and MCycle = "010") or ExchangeWH = '1') and TState = 4 then - RegWEH <= '1'; - RegWEL <= '1'; - end if; - - if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then - case IncDec_16(1 downto 0) is - when "00" | "01" | "10" => - RegWEH <= '1'; - RegWEL <= '1'; - when others => - end case; - end if; - end process; - - TmpAddr2 <= std_logic_vector(unsigned(signed(SP) + signed(Save_Mux))); - - process (Save_Mux, RegBusB, RegBusA_r, ID16, I_MULU, MULU_Prod32, MULU_tmp, T_Res, - ExchangeDH, ExchangeWH, IncDec_16, MCycle, TState, Wait_n, LDHLSP, TmpAddr2, WZ) - begin - RegDIH <= Save_Mux; - RegDIL <= Save_Mux; - - if I_MULU = '1' then - if T_Res = '1' then - RegDIH <= MULU_Prod32(31 downto 24); - RegDIL <= MULU_Prod32(23 downto 16); - else - RegDIH <= MULU_tmp(15 downto 8); -- TState = 4 DE write - RegDIL <= MULU_tmp(7 downto 0); - end if; - end if; - - if LDHLSP = '1' and MCycle = "010" and TState = 4 then - RegDIH <= TmpAddr2(15 downto 8); - RegDIL <= TmpAddr2(7 downto 0); - end if; - - if ExchangeDH = '1' and TState = 3 then - RegDIH <= RegBusB(15 downto 8); - RegDIL <= RegBusB(7 downto 0); - end if; - if ExchangeDH = '1' and TState = 4 then - RegDIH <= RegBusA_r(15 downto 8); - RegDIL <= RegBusA_r(7 downto 0); - end if; - if ExchangeWH = '1' and TState = 4 then - RegDIH <= WZ(15 downto 8); - RegDIL <= WZ(7 downto 0); - end if; - if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then - RegDIH <= std_logic_vector(ID16(15 downto 8)); - RegDIL <= std_logic_vector(ID16(7 downto 0)); - end if; - end process; - - Regs : T80_Reg - port map( - Clk => CLK_n, - CEN => ClkEn, - WEH => RegWEH, - WEL => RegWEL, - AddrA => RegAddrA, - AddrB => RegAddrB, - AddrC => RegAddrC, - DIH => RegDIH, - DIL => RegDIL, - DOAH => RegBusA(15 downto 8), - DOAL => RegBusA(7 downto 0), - DOBH => RegBusB(15 downto 8), - DOBL => RegBusB(7 downto 0), - DOCH => RegBusC(15 downto 8), - DOCL => RegBusC(7 downto 0), - DOR => DOR, - DIRSet => DIRSet, - DIR => DIR(207 downto 80)); - ---------------------------------------------------------------------------- --- --- Buses --- ---------------------------------------------------------------------------- - process (CLK_n) - begin - if rising_edge(CLK_n) then - if ClkEn = '1' then - case Set_BusB_To is - when "0111" => - BusB <= ACC; - when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => - if Set_BusB_To(0) = '1' then - BusB <= RegBusB(7 downto 0); - else - BusB <= RegBusB(15 downto 8); - end if; - when "0110" => - BusB <= DI_Reg; - when "1000" => - BusB <= std_logic_vector(SP(7 downto 0)); - when "1001" => - BusB <= std_logic_vector(SP(15 downto 8)); - when "1010" => - BusB <= "00000001"; - when "1011" => - BusB <= F; - when "1100" => - BusB <= std_logic_vector(PC(7 downto 0)); - when "1101" => - BusB <= std_logic_vector(PC(15 downto 8)); - when "1110" => - if IR = x"71" and out0 = '1' then - BusB <= "11111111"; - else - BusB <= "00000000"; - end if; - when others => - BusB <= "--------"; - end case; - - case Set_BusA_To is - when "0111" => - BusA <= ACC; - when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => - if Set_BusA_To(0) = '1' then - BusA <= RegBusA(7 downto 0); - else - BusA <= RegBusA(15 downto 8); - end if; - when "0110" => - BusA <= DI_Reg; - when "1000" => - BusA <= std_logic_vector(SP(7 downto 0)); - when "1001" => - BusA <= std_logic_vector(SP(15 downto 8)); - when "1010" => - BusA <= "00000000"; - when others => - BusA <= "--------"; - end case; - if XYbit_undoc='1' then - BusA <= DI_Reg; - BusB <= DI_Reg; - end if; - end if; - end if; - end process; - ---------------------------------------------------------------------------- --- --- Generate external control signals --- ---------------------------------------------------------------------------- - process (RESET_n,CLK_n) - begin - if RESET_n = '0' then - RFSH_n <= '1'; - elsif rising_edge(CLK_n) then - if DIRSet = '0' and CEN = '1' then - if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then - RFSH_n <= '0'; - else - RFSH_n <= '1'; - end if; - end if; - end if; - end process; - - MC <= std_logic_vector(MCycle); - TS <= std_logic_vector(TState); - DI_Reg <= DI; - HALT_n <= not Halt_FF; - BUSAK_n <= not (BusAck and RESET_n); - IntCycle_n <= not IntCycle; - IntE <= IntE_FF1; - IORQ <= IORQ_i; - Stop <= I_DJNZ; -------------------------------------------------------------------------- --- --- Main state machine --- -------------------------------------------------------------------------- - process (RESET_n, CLK_n) - variable OldNMI_n : std_logic; - begin - if RESET_n = '0' then - MCycle <= "001"; - TState <= "000"; - Pre_XY_F_M <= "000"; - Halt_FF <= '0'; - --BusAck <= '0'; - NMICycle <= '0'; - IntCycle <= '0'; - IntE_FF1 <= '0'; - IntE_FF2 <= '0'; - No_BTR <= '0'; - Auto_Wait_t1 <= '0'; - Auto_Wait_t2 <= '0'; - M1_n <= '1'; - --BusReq_s <= '0'; - NMI_s <= '0'; - elsif rising_edge(CLK_n) then - if DIRSet = '1' then - IntE_FF2 <= DIR(211); - IntE_FF1 <= DIR(210); - else - if NMI_n = '0' and OldNMI_n = '1' then - NMI_s <= '1'; - end if; - OldNMI_n := NMI_n; - - if CEN = '1' then - BusReq_s <= not BUSRQ_n; - Auto_Wait_t2 <= Auto_Wait_t1; - if T_Res = '1' then - Auto_Wait_t1 <= '0'; - Auto_Wait_t2 <= '0'; - else - Auto_Wait_t1 <= Auto_Wait or IORQ_i; - end if; - No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or - (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or - (I_BTR and (not IR(4) or F(Flag_Z))); - if TState = 2 then - if SetEI = '1' then - IntE_FF1 <= '1'; - IntE_FF2 <= '1'; - end if; - if I_RETN = '1' then - IntE_FF1 <= IntE_FF2; - end if; - end if; - if TState = 3 then - if SetDI = '1' then - IntE_FF1 <= '0'; - IntE_FF2 <= '0'; - end if; - end if; - if IntCycle = '1' or NMICycle = '1' then - Halt_FF <= '0'; - end if; - if MCycle = "001" and TState = 2 and Wait_n = '1' then - M1_n <= '1'; - end if; - if BusReq_s = '1' and BusAck = '1' then - else - BusAck <= '0'; - if TState = 2 and Wait_n = '0' then - elsif T_Res = '1' then - if Halt = '1' and ( not(Mode = 3 and INT_n = '0' and IntE_FF1 = '0')) then -- halt bug when Mode = 3 , INT_n = '0' and IME=0 - Halt_FF <= '1'; - end if; - if BusReq_s = '1' then - BusAck <= '1'; - else - TState <= "001"; - if (IntCycle = '1' and Mode = 3) then -- GB: read interrupt at MCycle 3 - if (MCycle = "010") then - M1_n <= '0'; - else - M1_n <= '1'; - end if; - end if; - if NextIs_XY_Fetch = '1' then - MCycle <= "110"; - Pre_XY_F_M <= MCycle; - if IR = "00110110" and Mode = 0 then - Pre_XY_F_M <= "010"; - end if; - elsif (MCycle = "111") or (MCycle = "110" and Mode = 1 and ISet /= "01") then - MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1); - elsif (MCycle = MCycles) or No_BTR = '1' or (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then - M1_n <= '0'; - MCycle <= "001"; - IntCycle <= '0'; - NMICycle <= '0'; - if NMI_s = '1' and Prefix = "00" then - NMI_s <= '0'; - NMICycle <= '1'; - IntE_FF1 <= '0'; - elsif IntE_FF1 = '1' and INT_n='0' and Prefix = "00" and SetEI = '0' then - IntCycle <= '1'; - IntE_FF1 <= '0'; - IntE_FF2 <= '0'; - elsif (Halt_FF = '1' and INT_n = '0' and Mode = 3) then - Halt_FF <= '0'; - end if; - else - MCycle <= std_logic_vector(unsigned(MCycle) + 1); - end if; - end if; - else - if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor - (IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then - TState <= TState + 1; - end if; - end if; - end if; - if TState = 0 then - M1_n <= '0'; - end if; - end if; - end if; - end if; - end process; - - Auto_Wait <= '1' when IntCycle = '1' and MCycle = "001" else '0'; -end; +-------------------------------------------------------------------------------- +-- **** +-- T80(c) core. Attempt to finish all undocumented features and provide +-- accurate timings. +-- Version 350. +-- Copyright (c) 2018 Sorgelig +-- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr +-- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as +-- correct implementation is still unclear. +-- +-- **** +-- T80(b) core. In an effort to merge and maintain bug fixes .... +-- +-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010 +-- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle +-- Ver 300 started tidyup. +-- +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- Z80 compatible microprocessor core +-- +-- Version : 0250 +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- 0210 : Fixed wait and halt +-- 0211 : Fixed Refresh addition and IM 1 +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- 0232 : Removed refresh address output for Mode > 1 and added DJNZ M1_n fix by Mike Johnson +-- 0235 : Added clock enable and IM 2 fix by Mike Johnson +-- 0237 : Changed 8080 I/O address output, added IntE output +-- 0238 : Fixed (IX/IY+d) timing and 16 bit ADC and SBC zero flag +-- 0240 : Added interrupt ack fix by Mike Johnson, changed (IX/IY+d) timing and changed flags in GB mode +-- 0242 : Added I/O wait, fixed refresh address, moved some registers to RAM +-- 0247 : Fixed bus req/ack cycle +-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15 +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use IEEE.STD_LOGIC_UNSIGNED.all; +use work.T80_Pack.all; + +entity T80 is + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + IOWait : integer := 0; -- 0 => Single cycle I/O, 1 => Std I/O cycle + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + IORQ : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DInst : in std_logic_vector(7 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + MC : out std_logic_vector(2 downto 0); + TS : out std_logic_vector(2 downto 0); + IntCycle_n : out std_logic; + IntE : out std_logic; + Stop : out std_logic; + R800_mode : in std_logic := '0'; + out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 + REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A + + DIRSet : in std_logic := '0'; + DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A + ); +end T80; + +architecture rtl of T80 is + + -- Registers + signal ACC, F : std_logic_vector(7 downto 0); + signal Ap, Fp : std_logic_vector(7 downto 0); + signal I : std_logic_vector(7 downto 0); + signal R : unsigned(7 downto 0); + signal SP, PC : unsigned(15 downto 0); + + signal RegDIH : std_logic_vector(7 downto 0); + signal RegDIL : std_logic_vector(7 downto 0); + signal RegBusA : std_logic_vector(15 downto 0); + signal RegBusB : std_logic_vector(15 downto 0); + signal RegBusC : std_logic_vector(15 downto 0); + signal RegAddrA_r : std_logic_vector(2 downto 0); + signal RegAddrA : std_logic_vector(2 downto 0); + signal RegAddrB_r : std_logic_vector(2 downto 0); + signal RegAddrB : std_logic_vector(2 downto 0); + signal RegAddrC : std_logic_vector(2 downto 0); + signal RegWEH : std_logic; + signal RegWEL : std_logic; + signal Alternate : std_logic; + + -- Help Registers + signal WZ : std_logic_vector(15 downto 0); -- MEMPTR register + signal TmpAddr2 : std_logic_vector(15 downto 0); -- Temporary address register + signal IR : std_logic_vector(7 downto 0); -- Instruction register + signal ISet : std_logic_vector(1 downto 0); -- Instruction set selector + signal RegBusA_r : std_logic_vector(15 downto 0); + signal MULU_Prod32 : std_logic_vector(31 downto 0); + signal MULU_tmp : std_logic_vector(31 downto 0); + signal MULU_Fakt1 : std_logic_vector(15 downto 0); + + signal ID16 : signed(15 downto 0); + signal Save_Mux : std_logic_vector(7 downto 0); + + signal TState : unsigned(2 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal IntE_FF1 : std_logic; + signal IntE_FF2 : std_logic; + signal Halt_FF : std_logic; + signal BusReq_s : std_logic := '0'; + signal BusAck : std_logic := '0'; + signal ClkEn : std_logic; + signal NMI_s : std_logic; + signal IStatus : std_logic_vector(1 downto 0); + + signal DI_Reg : std_logic_vector(7 downto 0); + signal T_Res : std_logic; + signal XY_State : std_logic_vector(1 downto 0); + signal Pre_XY_F_M : std_logic_vector(2 downto 0); + signal NextIs_XY_Fetch : std_logic; + signal XY_Ind : std_logic; + signal No_BTR : std_logic; + signal BTR_r : std_logic; + signal Auto_Wait : std_logic; + signal Auto_Wait_t1 : std_logic; + signal Auto_Wait_t2 : std_logic; + signal IncDecZ : std_logic; + + -- ALU signals + signal BusB : std_logic_vector(7 downto 0); + signal BusA : std_logic_vector(7 downto 0); + signal ALU_Q : std_logic_vector(7 downto 0); + signal F_Out : std_logic_vector(7 downto 0); + + -- Registered micro code outputs + signal Read_To_Reg_r : std_logic_vector(4 downto 0); + signal Arith16_r : std_logic; + signal Z16_r : std_logic; + signal ALU_Op_r : std_logic_vector(3 downto 0); + signal Save_ALU_r : std_logic; + signal PreserveC_r : std_logic; + signal MCycles : std_logic_vector(2 downto 0); + + -- Micro code outputs + signal MCycles_d : std_logic_vector(2 downto 0); + signal TStates : std_logic_vector(2 downto 0); + signal IntCycle : std_logic; + signal NMICycle : std_logic; + signal Inc_PC : std_logic; + signal Inc_WZ : std_logic; + signal IncDec_16 : std_logic_vector(3 downto 0); + signal Prefix : std_logic_vector(1 downto 0); + signal Read_To_Acc : std_logic; + signal Read_To_Reg : std_logic; + signal Set_BusB_To : std_logic_vector(3 downto 0); + signal Set_BusA_To : std_logic_vector(3 downto 0); + signal ALU_Op : std_logic_vector(3 downto 0); + signal Save_ALU : std_logic; + signal Rot_Akku : std_logic; + signal PreserveC : std_logic; + signal Arith16 : std_logic; + signal Set_Addr_To : std_logic_vector(2 downto 0); + signal Jump : std_logic; + signal JumpE : std_logic; + signal JumpXY : std_logic; + signal Call : std_logic; + signal RstP : std_logic; + signal LDZ : std_logic; + signal LDW : std_logic; + signal LDSPHL : std_logic; + signal LDHLSP : std_logic; + signal ADDSPdd : std_logic; + signal IORQ_i : std_logic; + signal Special_LD : std_logic_vector(2 downto 0); + signal ExchangeDH : std_logic; + signal ExchangeRp : std_logic; + signal ExchangeAF : std_logic; + signal ExchangeRS : std_logic; + signal ExchangeWH : std_logic; + signal I_DJNZ : std_logic; + signal I_CPL : std_logic; + signal I_CCF : std_logic; + signal I_SCF : std_logic; + signal I_RETN : std_logic; + signal I_BT : std_logic; + signal I_BC : std_logic; + signal I_BTR : std_logic; + signal I_RLD : std_logic; + signal I_RRD : std_logic; + signal I_RXDD : std_logic; + signal I_INRC : std_logic; + signal I_MULUB : std_logic; + signal I_MULU : std_logic; + signal SetWZ : std_logic_vector(1 downto 0); + signal SetDI : std_logic; + signal SetEI : std_logic; + signal IMode : std_logic_vector(1 downto 0); + signal Halt : std_logic; + signal XYbit_undoc : std_logic; + signal No_PC : std_logic; + signal DOR : std_logic_vector(127 downto 0); + +begin + + REG <= IntE_FF2 & IntE_FF1 & IStatus & DOR & std_logic_vector(PC) & std_logic_vector(SP) & std_logic_vector(R) & I & Fp & Ap & F & ACC when Alternate = '0' + else IntE_FF2 & IntE_FF1 & IStatus & DOR(127 downto 112) & DOR(47 downto 0) & DOR(63 downto 48) & DOR(111 downto 64) & + std_logic_vector(PC) & std_logic_vector(SP) & std_logic_vector(R) & I & Fp & Ap & F & ACC; + + mcode : T80_MCode + generic map( + Mode => Mode, + Flag_C => Flag_C, + Flag_N => Flag_N, + Flag_P => Flag_P, + Flag_X => Flag_X, + Flag_H => Flag_H, + Flag_Y => Flag_Y, + Flag_Z => Flag_Z, + Flag_S => Flag_S) + port map( + IR => IR, + ISet => ISet, + MCycle => MCycle, + F => F, + NMICycle => NMICycle, + IntCycle => IntCycle, + XY_State => XY_State, + MCycles => MCycles_d, + TStates => TStates, + Prefix => Prefix, + Inc_PC => Inc_PC, + Inc_WZ => Inc_WZ, + IncDec_16 => IncDec_16, + Read_To_Acc => Read_To_Acc, + Read_To_Reg => Read_To_Reg, + Set_BusB_To => Set_BusB_To, + Set_BusA_To => Set_BusA_To, + ALU_Op => ALU_Op, + Save_ALU => Save_ALU, + Rot_Akku => Rot_Akku, + PreserveC => PreserveC, + Arith16 => Arith16, + Set_Addr_To => Set_Addr_To, + IORQ => IORQ_i, + Jump => Jump, + JumpE => JumpE, + JumpXY => JumpXY, + Call => Call, + RstP => RstP, + LDZ => LDZ, + LDW => LDW, + LDSPHL => LDSPHL, + LDHLSP => LDHLSP, + ADDSPdd => ADDSPdd, + Special_LD => Special_LD, + ExchangeDH => ExchangeDH, + ExchangeRp => ExchangeRp, + ExchangeAF => ExchangeAF, + ExchangeRS => ExchangeRS, + ExchangeWH => ExchangeWH, + I_DJNZ => I_DJNZ, + I_CPL => I_CPL, + I_CCF => I_CCF, + I_SCF => I_SCF, + I_RETN => I_RETN, + I_BT => I_BT, + I_BC => I_BC, + I_BTR => I_BTR, + I_RLD => I_RLD, + I_RRD => I_RRD, + I_INRC => I_INRC, + I_MULUB => I_MULUB, + I_MULU => I_MULU, + SetWZ => SetWZ, + SetDI => SetDI, + SetEI => SetEI, + IMode => IMode, + Halt => Halt, + NoRead => NoRead, + Write => Write, + R800_mode => R800_mode, + No_PC => No_PC, + XYbit_undoc => XYbit_undoc); + + alu : T80_ALU + generic map( + Mode => Mode, + Flag_C => Flag_C, + Flag_N => Flag_N, + Flag_P => Flag_P, + Flag_X => Flag_X, + Flag_H => Flag_H, + Flag_Y => Flag_Y, + Flag_Z => Flag_Z, + Flag_S => Flag_S) + port map( + Arith16 => Arith16_r, + Z16 => Z16_r, + WZ => WZ, + XY_State=> XY_State, + ALU_Op => ALU_Op_r, + Rot_Akku => Rot_Akku, + IR => IR(5 downto 0), + ISet => ISet, + BusA => BusA, + BusB => BusB, + F_In => F, + Q => ALU_Q, + F_Out => F_Out); + + ClkEn <= CEN and not BusAck; + + T_Res <= '1' when TState = unsigned(TStates) else '0'; + + NextIs_XY_Fetch <= '1' when XY_State /= "00" and XY_Ind = '0' and + ((Set_Addr_To = aXY) or + (MCycle = "001" and IR = "11001011") or + (MCycle = "001" and IR = "00110110")) else '0'; + + Save_Mux <= BusB when ExchangeRp = '1' else + DI_Reg when Save_ALU_r = '0' else + ALU_Q; + + process (RESET_n, CLK_n) + variable n : std_logic_vector(7 downto 0); + variable ioq : std_logic_vector(8 downto 0); + variable temp_c : unsigned(8 downto 0); + variable temp_h : unsigned(4 downto 0); + begin + if RESET_n = '0' then + PC <= (others => '0'); -- Program Counter + A <= (others => '0'); + WZ <= (others => '0'); + IR <= "00000000"; + ISet <= "00"; + XY_State <= "00"; + IStatus <= "00"; + MCycles <= "000"; + DO <= "00000000"; + + ACC <= (others => '1'); + F <= (others => '1'); + if Mode = 3 then + ACC <= (others => '0'); + F <= "11110000"; + end if; + + Ap <= (others => '1'); + Fp <= (others => '1'); + I <= (others => '0'); + R <= (others => '0'); + SP <= (others => '1'); + Alternate <= '0'; + + Read_To_Reg_r <= "00000"; + Arith16_r <= '0'; + BTR_r <= '0'; + Z16_r <= '0'; + ALU_Op_r <= "0000"; + Save_ALU_r <= '0'; + PreserveC_r <= '0'; + XY_Ind <= '0'; + I_RXDD <= '0'; + + elsif rising_edge(CLK_n) then + + if DIRSet = '1' then + ACC <= DIR( 7 downto 0); + F <= DIR(15 downto 8); + Ap <= DIR(23 downto 16); + Fp <= DIR(31 downto 24); + I <= DIR(39 downto 32); + R <= unsigned(DIR(47 downto 40)); + SP <= unsigned(DIR(63 downto 48)); + PC <= unsigned(DIR(79 downto 64)); + A <= DIR(79 downto 64); + IStatus <= DIR(209 downto 208); + + elsif ClkEn = '1' then + ALU_Op_r <= "0000"; + Save_ALU_r <= '0'; + Read_To_Reg_r <= "00000"; + + MCycles <= MCycles_d; + + if LDHLSP = '1' and MCycle = "011" and TState = 1 then + temp_c := unsigned('0'&SP(7 downto 0))+unsigned('0'&Save_Mux); + temp_h := unsigned('0'&SP(3 downto 0))+unsigned('0'&Save_Mux(3 downto 0)); + F(Flag_Z) <= '0'; + F(Flag_N) <= '0'; + F(Flag_H) <= temp_h(4); + F(Flag_C) <= temp_c(8); + end if; + + if ADDSPdd = '1' and TState = 1 then + temp_c := unsigned('0'&SP(7 downto 0))+unsigned('0'&Save_Mux); + temp_h := unsigned('0'&SP(3 downto 0))+unsigned('0'&Save_Mux(3 downto 0)); + F(Flag_Z) <= '0'; + F(Flag_N) <= '0'; + F(Flag_H) <= temp_h(4); + F(Flag_C) <= temp_c(8); + end if; + + if Mode = 3 then + IStatus <= "10"; + elsif IMode /= "11" then + IStatus <= IMode; + end if; + + Arith16_r <= Arith16; + PreserveC_r <= PreserveC; + if ISet = "10" and ALU_OP(2) = '0' and ALU_OP(0) = '1' and MCycle = "011" then + Z16_r <= '1'; + else + Z16_r <= '0'; + end if; + + if MCycle = "001" and TState(2) = '0' then + -- MCycle = 1 and TState = 1, 2, or 3 + + if TState = 2 and Wait_n = '1' then + if Mode < 2 then + A(7 downto 0) <= std_logic_vector(R); + A(15 downto 8) <= I; + R(6 downto 0) <= R(6 downto 0) + 1; + end if; + + if Jump = '0' and Call = '0' and NMICycle = '0' and IntCycle = '0' and not (Halt_FF = '1' or Halt = '1') then + PC <= PC + 1; + end if; + + if IntCycle = '1' and IStatus = "01" then + IR <= "11111111"; + elsif Halt_FF = '1' or (IntCycle = '1' and IStatus = "10") or NMICycle = '1' then + IR <= "00000000"; + else + IR <= DInst; + end if; + + if Mode <= 1 and IntCycle = '1' and IStatus = "10" then + -- IM2 vector address low byte from bus + WZ(7 downto 0) <= DInst; + end if; + + ISet <= "00"; + if Prefix /= "00" then + if Prefix = "11" then + if IR(5) = '1' then + XY_State <= "10"; + else + XY_State <= "01"; + end if; + else + if Prefix = "10" then + XY_State <= "00"; + XY_Ind <= '0'; + end if; + ISet <= Prefix; + end if; + else + XY_State <= "00"; + XY_Ind <= '0'; + end if; + end if; + + else + -- either (MCycle > 1) OR (MCycle = 1 AND TState > 3) + + if MCycle = "110" then + XY_Ind <= '1'; + if Prefix = "01" then + ISet <= "01"; + end if; + end if; + + if T_Res = '1' then + BTR_r <= (I_BT or I_BC or I_BTR) and not No_BTR; + if Jump = '1' then + A(15 downto 8) <= DI_Reg; + A(7 downto 0) <= WZ(7 downto 0); + PC(15 downto 8) <= unsigned(DI_Reg); + PC(7 downto 0) <= unsigned(WZ(7 downto 0)); + elsif JumpXY = '1' then + A <= RegBusC; + PC <= unsigned(RegBusC); + elsif Call = '1' or RstP = '1' then + A <= WZ; + PC <= unsigned(WZ); + elsif MCycle = MCycles and NMICycle = '1' then + A <= "0000000001100110"; + PC <= "0000000001100110"; + elsif ((Mode /= 3 and MCycle = "011") or (Mode = 3 and MCycle = "100")) + and IntCycle = '1' and IStatus = "10" then + A(15 downto 8) <= I; + A(7 downto 0) <= WZ(7 downto 0); + PC(15 downto 8) <= unsigned(I); + PC(7 downto 0) <= unsigned(WZ(7 downto 0)); + else + case Set_Addr_To is + when aXY => + if XY_State = "00" then + A <= RegBusC; + else + if NextIs_XY_Fetch = '1' then + A <= std_logic_vector(PC); + else + A <= WZ; + end if; + end if; + when aIOA => + if Mode = 3 then + -- Memory map I/O on GBZ80 + A(15 downto 8) <= (others => '1'); + elsif Mode = 2 then + -- Duplicate I/O address on 8080 + A(15 downto 8) <= DI_Reg; + else + A(15 downto 8) <= ACC; + end if; + A(7 downto 0) <= DI_Reg; + WZ <= (ACC & DI_Reg) + "1"; + when aSP => + A <= std_logic_vector(SP); + when aBC => + if Mode = 3 and IORQ_i = '1' then + -- Memory map I/O on GBZ80 + A(15 downto 8) <= (others => '1'); + A(7 downto 0) <= RegBusC(7 downto 0); + else + A <= RegBusC; + if SetWZ = "01" then + WZ <= RegBusC + "1"; + end if; + if SetWZ = "10" then + WZ(7 downto 0) <= RegBusC(7 downto 0) + "1"; + WZ(15 downto 8) <= ACC; + end if; + end if; + when aDE => + A <= RegBusC; + if SetWZ = "10" then + WZ(7 downto 0) <= RegBusC(7 downto 0) + "1"; + WZ(15 downto 8) <= ACC; + end if; + when aZI => + if Inc_WZ = '1' then + A <= std_logic_vector(unsigned(WZ) + 1); + else + A(15 downto 8) <= DI_Reg; + A(7 downto 0) <= WZ(7 downto 0); + if SetWZ = "10" then + WZ(7 downto 0) <= WZ(7 downto 0) + "1"; + WZ(15 downto 8) <= ACC; + end if; + end if; + when others => + if ISet = "10" and IR(7 downto 4) = x"B" and IR(2 downto 1) = "01" and MCycle = 3 and No_BTR = '0' then + -- INIR, INDR, OTIR, OTDR + A <= RegBusA_r; + elsif No_PC = '0' or No_BTR = '1' or (I_DJNZ = '1' and IncDecZ = '1') or Mode > 1 then + A <= std_logic_vector(PC); + end if; + end case; + end if; + + if SetWZ = "11" then + WZ <= std_logic_vector(ID16); + end if; + + Save_ALU_r <= Save_ALU; + ALU_Op_r <= ALU_Op; + + if Mode = 3 then + if I_CPL = '1' then + -- CPL + ACC <= not ACC; + F(Flag_H) <= '1'; + F(Flag_N) <= '1'; + end if; + if I_CCF = '1' then + -- CCF + F(Flag_C) <= not F(Flag_C); + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + end if; + if I_SCF = '1' then + -- SCF + F(Flag_C) <= '1'; + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + end if; + else + if I_CPL = '1' then + -- CPL + ACC <= not ACC; + F(Flag_Y) <= not ACC(5); + F(Flag_H) <= '1'; + F(Flag_X) <= not ACC(3); + F(Flag_N) <= '1'; + end if; + if I_CCF = '1' then + -- CCF + F(Flag_C) <= not F(Flag_C); + F(Flag_Y) <= ACC(5); + F(Flag_H) <= F(Flag_C); + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; + if I_SCF = '1' then + -- SCF + F(Flag_C) <= '1'; + F(Flag_Y) <= ACC(5); + F(Flag_H) <= '0'; + F(Flag_X) <= ACC(3); + F(Flag_N) <= '0'; + end if; + end if; + end if; + + if (TState = 2 and I_BTR = '1' and IR(0) = '1') or (TState = 1 and I_BTR = '1' and IR(0) = '0') then + ioq := ('0' & DI_Reg) + ('0' & std_logic_vector(ID16(7 downto 0))); + F(Flag_N) <= DI_Reg(7); + F(Flag_C) <= ioq(8); + F(Flag_H) <= ioq(8); + ioq := (ioq and "000000111") xor ('0'&BusA); + F(Flag_P) <= not (ioq(0) xor ioq(1) xor ioq(2) xor ioq(3) xor ioq(4) xor ioq(5) xor ioq(6) xor ioq(7)); + end if; + + if TState = 2 and Wait_n = '1' then + if ISet = "01" and MCycle = "111" then + IR <= DInst; + end if; + if JumpE = '1' then + PC <= unsigned(signed(PC) + signed(DI_Reg)); + WZ <= std_logic_vector(signed(PC) + signed(DI_Reg)); + elsif Inc_PC = '1' then + PC <= PC + 1; + end if; + if BTR_r = '1' then + PC <= PC - 2; + end if; + if RstP = '1' then + WZ <= (others =>'0'); + WZ(5 downto 3) <= IR(5 downto 3); + end if; + end if; + if TState = 3 and MCycle = "110" then + WZ <= std_logic_vector(signed(RegBusC) + signed(DI_Reg)); + end if; + + if MCycle = "011" and TState = 4 and No_BTR = '0' then + if I_BT = '1' or I_BC = '1' then + WZ <= std_logic_vector(PC)-"1"; + end if; + end if; + + if (TState = 2 and Wait_n = '1') or (TState = 4 and MCycle = "001") then + if IncDec_16(2 downto 0) = "111" then + if IncDec_16(3) = '1' then + SP <= SP - 1; + else + SP <= SP + 1; + end if; + end if; + end if; + + if ADDSPdd = '1' and TState = 2 then + WZ <= std_logic_vector(SP); + SP <= unsigned(signed(SP)+signed(Save_Mux)); + end if; + + if LDSPHL = '1' then + SP <= unsigned(RegBusC); + end if; + if ExchangeAF = '1' then + Ap <= ACC; + ACC <= Ap; + Fp <= F; + F <= Fp; + end if; + if ExchangeRS = '1' then + Alternate <= not Alternate; + end if; + end if; + + if TState = 3 then + if LDZ = '1' then + WZ(7 downto 0) <= DI_Reg; + end if; + if LDW = '1' then + WZ(15 downto 8) <= DI_Reg; + end if; + + if Special_LD(2) = '1' then + case Special_LD(1 downto 0) is + when "00" => + ACC <= I; + F(Flag_P) <= IntE_FF2; + F(Flag_S) <= I(7); + + if I = x"00" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; + end if; + + F(Flag_Y) <= I(5); + F(Flag_H) <= '0'; + F(Flag_X) <= I(3); + F(Flag_N) <= '0'; + + + when "01" => + ACC <= std_logic_vector(R); + F(Flag_P) <= IntE_FF2; + F(Flag_S) <= R(7); + + if R = x"00" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; + end if; + + F(Flag_Y) <= R(5); + F(Flag_H) <= '0'; + F(Flag_X) <= R(3); + F(Flag_N) <= '0'; + + when "10" => + I <= ACC; + when others => + R <= unsigned(ACC); + end case; + end if; + end if; + + if (I_DJNZ = '0' and Save_ALU_r = '1') or ALU_Op_r = "1001" then + if Mode = 3 then + F(6) <= F_Out(6); + F(5) <= F_Out(5); + F(7) <= F_Out(7); + if PreserveC_r = '0' then + F(4) <= F_Out(4); + end if; + else + F(7 downto 1) <= F_Out(7 downto 1); + if PreserveC_r = '0' then + F(Flag_C) <= F_Out(0); + end if; + end if; + end if; + if T_Res = '1' and I_INRC = '1' then + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + F(Flag_X) <= DI_Reg(3); + F(Flag_Y) <= DI_Reg(5); + if DI_Reg(7 downto 0) = "00000000" then + F(Flag_Z) <= '1'; + else + F(Flag_Z) <= '0'; + end if; + F(Flag_S) <= DI_Reg(7); + F(Flag_P) <= not (DI_Reg(0) xor DI_Reg(1) xor DI_Reg(2) xor DI_Reg(3) xor + DI_Reg(4) xor DI_Reg(5) xor DI_Reg(6) xor DI_Reg(7)); + end if; + + if TState = 1 and Auto_Wait_t1 = '0' then + -- Keep D0 from M3 for RLD/RRD (Sorgelig) + I_RXDD <= I_RLD or I_RRD; + if I_RXDD='0' then + DO <= BusB; + end if; + if I_RLD = '1' then + DO(3 downto 0) <= BusA(3 downto 0); + DO(7 downto 4) <= BusB(3 downto 0); + end if; + if I_RRD = '1' then + DO(3 downto 0) <= BusB(7 downto 4); + DO(7 downto 4) <= BusA(3 downto 0); + end if; + end if; + + if T_Res = '1' then + Read_To_Reg_r(3 downto 0) <= Set_BusA_To; + Read_To_Reg_r(4) <= Read_To_Reg; + if Read_To_Acc = '1' then + Read_To_Reg_r(3 downto 0) <= "0111"; + Read_To_Reg_r(4) <= '1'; + end if; + end if; + + if TState = 1 and I_BT = '1' then + F(Flag_X) <= ALU_Q(3); + F(Flag_Y) <= ALU_Q(1); + F(Flag_H) <= '0'; + F(Flag_N) <= '0'; + end if; + if TState = 1 and I_BC = '1' then + n := ALU_Q - ("0000000" & F_Out(Flag_H)); + F(Flag_X) <= n(3); + F(Flag_Y) <= n(1); + end if; + if I_BC = '1' or I_BT = '1' then + F(Flag_P) <= IncDecZ; + end if; + + if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or + (Save_ALU_r = '1' and ALU_OP_r /= "0111") then + case Read_To_Reg_r is + when "10111" => + ACC <= Save_Mux; + when "10110" => + DO <= Save_Mux; + when "11000" => + SP(7 downto 0) <= unsigned(Save_Mux); + when "11001" => + SP(15 downto 8) <= unsigned(Save_Mux); + when "11011" => + if Mode = 3 then + F(7 downto 4) <= Save_Mux(7 downto 4); + F(3 downto 0) <= "0000"; -- bit 3 to 0 always return 0 + else + F <= Save_Mux; + end if; + when others => + end case; + if XYbit_undoc='1' then + DO <= ALU_Q; + end if; + end if; + end if; + end if; + end process; + +--------------------------------------------------------------------------- +-- +-- Multiply +-- +--------------------------------------------------------------------------- + process (CLK_n, ACC, RegBusB, MULU_tmp, MULU_Fakt1, MULU_Prod32) + begin + + MULU_tmp(31 downto 12) <= std_logic_vector((unsigned(MULU_Fakt1)*unsigned(MULU_Prod32(3 downto 0)))+unsigned("0000"&MULU_Prod32(31 downto 16))); + MULU_tmp(11 downto 0) <= MULU_Prod32(15 downto 4); + + if rising_edge(CLK_n) then + if ClkEn = '1' then + if T_Res='1' then + if I_MULUB='1' then + MULU_Prod32(7 downto 0) <= ACC; + MULU_Prod32(15 downto 8) <= "--------"; + MULU_Prod32(31 downto 16) <= X"0000"; + MULU_Fakt1(7 downto 0) <= "00000000"; + if Set_BusB_To(0) = '1' then + MULU_Fakt1(15 downto 8) <= RegBusB(7 downto 0); + else + MULU_Fakt1(15 downto 8) <= RegBusB(15 downto 8); + end if; + else + MULU_Prod32(15 downto 0) <= RegBusA; + MULU_Prod32(31 downto 16) <= X"0000"; + MULU_Fakt1 <= RegBusB; + end if; + else + MULU_Prod32 <= MULU_tmp; + end if; + end if; + end if; + end process; + +--------------------------------------------------------------------------- +-- +-- BC('), DE('), HL('), IX and IY +-- +--------------------------------------------------------------------------- + process (CLK_n) + begin + if rising_edge(CLK_n) then + if ClkEn = '1' then + -- Bus A / Write + RegAddrA_r <= Alternate & Set_BusA_To(2 downto 1); + if XY_Ind = '0' and XY_State /= "00" and Set_BusA_To(2 downto 1) = "10" then + RegAddrA_r <= XY_State(1) & "11"; + end if; + + -- Bus B + RegAddrB_r <= Alternate & Set_BusB_To(2 downto 1); + if XY_Ind = '0' and XY_State /= "00" and Set_BusB_To(2 downto 1) = "10" then + RegAddrB_r <= XY_State(1) & "11"; + end if; + + -- Address from register + RegAddrC <= Alternate & Set_Addr_To(1 downto 0); + -- Jump (HL), LD SP,HL + if (JumpXY = '1' or LDSPHL = '1') then + RegAddrC <= Alternate & "10"; + end if; + if ((JumpXY = '1' or LDSPHL = '1') and XY_State /= "00") or (MCycle = "110") then + RegAddrC <= XY_State(1) & "11"; + end if; + + if I_DJNZ = '1' and Save_ALU_r = '1' and Mode < 2 then + IncDecZ <= F_Out(Flag_Z); + end if; + if (TState = 2 or (TState = 3 and MCycle = "001")) and IncDec_16(2 downto 0) = "100" then + if ID16 = 0 then + IncDecZ <= '0'; + else + IncDecZ <= '1'; + end if; + end if; + + RegBusA_r <= RegBusA; + end if; + end if; + end process; + + RegAddrA <= + -- 16 bit increment/decrement + Alternate & IncDec_16(1 downto 0) when (TState = 2 or + (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and XY_State = "00" else + XY_State(1) & "11" when (TState = 2 or + (TState = 3 and MCycle = "001" and IncDec_16(2) = '1')) and IncDec_16(1 downto 0) = "10" else + -- EX HL,DL + Alternate & "10" when ExchangeDH = '1' and TState = 3 else + Alternate & "01" when (ExchangeDH = '1' or I_MULU = '1') and TState = 4 else + -- EX (SP),HL (HL(IX,IY) <= WZ) + Alternate & "10" when ExchangeWH = '1' and XY_State = "00" and TState = 4 else + XY_State(1) & "11" when ExchangeWH = '1' and TState = 4 else + -- LDHLSP + "010" when LDHLSP = '1' and TState = 4 else + + -- Bus A / Write + RegAddrA_r; + + RegAddrB <= + -- EX HL,DL + Alternate & "01" when ExchangeDH = '1' and TState = 3 else + -- Bus B + RegAddrB_r; + + ID16 <= signed(RegBusA) - 1 when IncDec_16(3) = '1' else + signed(RegBusA) + 1; + + process (Save_ALU_r, Auto_Wait_t1, ALU_OP_r, Read_To_Reg_r, I_MULU, T_Res, + ExchangeDH, ExchangeWH, IncDec_16, MCycle, TState, Wait_n, LDHLSP) + begin + RegWEH <= '0'; + RegWEL <= '0'; + if (TState = 1 and Save_ALU_r = '0' and Auto_Wait_t1 = '0') or + (Save_ALU_r = '1' and ALU_OP_r /= "0111") then + case Read_To_Reg_r is + when "10000" | "10001" | "10010" | "10011" | "10100" | "10101" => + RegWEH <= not Read_To_Reg_r(0); + RegWEL <= Read_To_Reg_r(0); + when others => + end case; + end if; + + if I_MULU = '1' and (T_Res = '1' or TState = 4) then -- TState = 4 DE write + RegWEH <= '1'; + RegWEL <= '1'; + end if; + + if ExchangeDH = '1' and (TState = 3 or TState = 4) then + RegWEH <= '1'; + RegWEL <= '1'; + end if; + + if ((LDHLSP = '1' and MCycle = "010") or ExchangeWH = '1') and TState = 4 then + RegWEH <= '1'; + RegWEL <= '1'; + end if; + + if IncDec_16(2) = '1' and ((TState = 2 and Wait_n = '1' and MCycle /= "001") or (TState = 3 and MCycle = "001")) then + case IncDec_16(1 downto 0) is + when "00" | "01" | "10" => + RegWEH <= '1'; + RegWEL <= '1'; + when others => + end case; + end if; + end process; + + TmpAddr2 <= std_logic_vector(unsigned(signed(SP) + signed(Save_Mux))); + + process (Save_Mux, RegBusB, RegBusA_r, ID16, I_MULU, MULU_Prod32, MULU_tmp, T_Res, + ExchangeDH, ExchangeWH, IncDec_16, MCycle, TState, Wait_n, LDHLSP, TmpAddr2, WZ) + begin + RegDIH <= Save_Mux; + RegDIL <= Save_Mux; + + if I_MULU = '1' then + if T_Res = '1' then + RegDIH <= MULU_Prod32(31 downto 24); + RegDIL <= MULU_Prod32(23 downto 16); + else + RegDIH <= MULU_tmp(15 downto 8); -- TState = 4 DE write + RegDIL <= MULU_tmp(7 downto 0); + end if; + end if; + + if LDHLSP = '1' and MCycle = "010" and TState = 4 then + RegDIH <= TmpAddr2(15 downto 8); + RegDIL <= TmpAddr2(7 downto 0); + end if; + + if ExchangeDH = '1' and TState = 3 then + RegDIH <= RegBusB(15 downto 8); + RegDIL <= RegBusB(7 downto 0); + end if; + if ExchangeDH = '1' and TState = 4 then + RegDIH <= RegBusA_r(15 downto 8); + RegDIL <= RegBusA_r(7 downto 0); + end if; + if ExchangeWH = '1' and TState = 4 then + RegDIH <= WZ(15 downto 8); + RegDIL <= WZ(7 downto 0); + end if; + if IncDec_16(2) = '1' and ((TState = 2 and MCycle /= "001") or (TState = 3 and MCycle = "001")) then + RegDIH <= std_logic_vector(ID16(15 downto 8)); + RegDIL <= std_logic_vector(ID16(7 downto 0)); + end if; + end process; + + Regs : T80_Reg + port map( + Clk => CLK_n, + CEN => ClkEn, + WEH => RegWEH, + WEL => RegWEL, + AddrA => RegAddrA, + AddrB => RegAddrB, + AddrC => RegAddrC, + DIH => RegDIH, + DIL => RegDIL, + DOAH => RegBusA(15 downto 8), + DOAL => RegBusA(7 downto 0), + DOBH => RegBusB(15 downto 8), + DOBL => RegBusB(7 downto 0), + DOCH => RegBusC(15 downto 8), + DOCL => RegBusC(7 downto 0), + DOR => DOR, + DIRSet => DIRSet, + DIR => DIR(207 downto 80)); + +--------------------------------------------------------------------------- +-- +-- Buses +-- +--------------------------------------------------------------------------- + process (CLK_n) + begin + if rising_edge(CLK_n) then + if ClkEn = '1' then + case Set_BusB_To is + when "0111" => + BusB <= ACC; + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => + if Set_BusB_To(0) = '1' then + BusB <= RegBusB(7 downto 0); + else + BusB <= RegBusB(15 downto 8); + end if; + when "0110" => + BusB <= DI_Reg; + when "1000" => + BusB <= std_logic_vector(SP(7 downto 0)); + when "1001" => + BusB <= std_logic_vector(SP(15 downto 8)); + when "1010" => + BusB <= "00000001"; + when "1011" => + BusB <= F; + when "1100" => + BusB <= std_logic_vector(PC(7 downto 0)); + when "1101" => + BusB <= std_logic_vector(PC(15 downto 8)); + when "1110" => + if IR = x"71" and out0 = '1' then + BusB <= "11111111"; + else + BusB <= "00000000"; + end if; + when others => + BusB <= "--------"; + end case; + + case Set_BusA_To is + when "0111" => + BusA <= ACC; + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" => + if Set_BusA_To(0) = '1' then + BusA <= RegBusA(7 downto 0); + else + BusA <= RegBusA(15 downto 8); + end if; + when "0110" => + BusA <= DI_Reg; + when "1000" => + BusA <= std_logic_vector(SP(7 downto 0)); + when "1001" => + BusA <= std_logic_vector(SP(15 downto 8)); + when "1010" => + BusA <= "00000000"; + when others => + BusA <= "--------"; + end case; + if XYbit_undoc='1' then + BusA <= DI_Reg; + BusB <= DI_Reg; + end if; + end if; + end if; + end process; + +--------------------------------------------------------------------------- +-- +-- Generate external control signals +-- +--------------------------------------------------------------------------- + process (RESET_n,CLK_n) + begin + if RESET_n = '0' then + RFSH_n <= '1'; + elsif rising_edge(CLK_n) then + if DIRSet = '0' and CEN = '1' then + if MCycle = "001" and ((TState = 2 and Wait_n = '1') or TState = 3) then + RFSH_n <= '0'; + else + RFSH_n <= '1'; + end if; + end if; + end if; + end process; + + MC <= std_logic_vector(MCycle); + TS <= std_logic_vector(TState); + DI_Reg <= DI; + HALT_n <= not Halt_FF; + BUSAK_n <= not (BusAck and RESET_n); + IntCycle_n <= not IntCycle; + IntE <= IntE_FF1; + IORQ <= IORQ_i; + Stop <= I_DJNZ; +------------------------------------------------------------------------- +-- +-- Main state machine +-- +------------------------------------------------------------------------- + process (RESET_n, CLK_n) + variable OldNMI_n : std_logic; + begin + if RESET_n = '0' then + MCycle <= "001"; + TState <= "000"; + Pre_XY_F_M <= "000"; + Halt_FF <= '0'; + --BusAck <= '0'; + NMICycle <= '0'; + IntCycle <= '0'; + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + No_BTR <= '0'; + Auto_Wait_t1 <= '0'; + Auto_Wait_t2 <= '0'; + M1_n <= '1'; + --BusReq_s <= '0'; + NMI_s <= '0'; + elsif rising_edge(CLK_n) then + if DIRSet = '1' then + IntE_FF2 <= DIR(211); + IntE_FF1 <= DIR(210); + else + if NMI_n = '0' and OldNMI_n = '1' then + NMI_s <= '1'; + end if; + OldNMI_n := NMI_n; + + if CEN = '1' then + BusReq_s <= not BUSRQ_n; + Auto_Wait_t2 <= Auto_Wait_t1; + if T_Res = '1' then + Auto_Wait_t1 <= '0'; + Auto_Wait_t2 <= '0'; + else + Auto_Wait_t1 <= Auto_Wait or IORQ_i; + end if; + No_BTR <= (I_BT and (not IR(4) or not F(Flag_P))) or + (I_BC and (not IR(4) or F(Flag_Z) or not F(Flag_P))) or + (I_BTR and (not IR(4) or F(Flag_Z))); + if TState = 2 then + if SetEI = '1' then + IntE_FF1 <= '1'; + IntE_FF2 <= '1'; + end if; + if I_RETN = '1' then + IntE_FF1 <= IntE_FF2; + end if; + end if; + if TState = 3 then + if SetDI = '1' then + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + end if; + end if; + if IntCycle = '1' or NMICycle = '1' then + Halt_FF <= '0'; + end if; + if MCycle = "001" and TState = 2 and Wait_n = '1' then + M1_n <= '1'; + end if; + if BusReq_s = '1' and BusAck = '1' then + else + BusAck <= '0'; + if TState = 2 and Wait_n = '0' then + elsif T_Res = '1' then + if Halt = '1' and ( not(Mode = 3 and INT_n = '0' and IntE_FF1 = '0')) then -- halt bug when Mode = 3 , INT_n = '0' and IME=0 + Halt_FF <= '1'; + end if; + if BusReq_s = '1' then + BusAck <= '1'; + else + TState <= "001"; + if (IntCycle = '1' and Mode = 3) then -- GB: read interrupt at MCycle 3 + if (MCycle = "010") then + M1_n <= '0'; + else + M1_n <= '1'; + end if; + end if; + if NextIs_XY_Fetch = '1' then + MCycle <= "110"; + Pre_XY_F_M <= MCycle; + if IR = "00110110" and Mode = 0 then + Pre_XY_F_M <= "010"; + end if; + elsif (MCycle = "111") or (MCycle = "110" and Mode = 1 and ISet /= "01") then + MCycle <= std_logic_vector(unsigned(Pre_XY_F_M) + 1); + elsif (MCycle = MCycles) or No_BTR = '1' or (MCycle = "010" and I_DJNZ = '1' and IncDecZ = '1') then + M1_n <= '0'; + MCycle <= "001"; + IntCycle <= '0'; + NMICycle <= '0'; + if NMI_s = '1' and Prefix = "00" then + NMI_s <= '0'; + NMICycle <= '1'; + IntE_FF1 <= '0'; + elsif IntE_FF1 = '1' and INT_n='0' and Prefix = "00" and SetEI = '0' then + IntCycle <= '1'; + IntE_FF1 <= '0'; + IntE_FF2 <= '0'; + elsif (Halt_FF = '1' and INT_n = '0' and Mode = 3) then + Halt_FF <= '0'; + end if; + else + MCycle <= std_logic_vector(unsigned(MCycle) + 1); + end if; + end if; + else + if (Auto_Wait = '1' and Auto_Wait_t2 = '0') nor + (IOWait = 1 and IORQ_i = '1' and Auto_Wait_t1 = '0') then + TState <= TState + 1; + end if; + end if; + end if; + if TState = 0 then + M1_n <= '0'; + end if; + end if; + end if; + end if; + end process; + + Auto_Wait <= '1' when IntCycle = '1' and MCycle = "001" else '0'; +end; diff --git a/modules/cpu-t80/T8080se.vhd b/modules/cpu-t80/T8080se.vhd index b18b47a..1264696 100644 --- a/modules/cpu-t80/T8080se.vhd +++ b/modules/cpu-t80/T8080se.vhd @@ -1,194 +1,194 @@ --- **** --- T80(b) core. In an effort to merge and maintain bug fixes .... --- --- --- Ver 300 started tidyup --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) --- --- **** --- --- 8080 compatible microprocessor core, synchronous top level with clock enable --- Different timing than the original 8080 --- Inputs needs to be synchronous and outputs may glitch --- --- Version : 0242 --- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- STACK status output not supported --- --- File history : --- --- 0237 : First version --- --- 0238 : Updated for T80 interface change --- --- 0240 : Updated for T80 interface change --- --- 0242 : Updated for T80 interface change --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity T8080se is - generic( - Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2 - ); - port( - RESET_n : in std_logic; - CLK : in std_logic; - CLKEN : in std_logic; - READY : in std_logic; - HOLD : in std_logic; - INT : in std_logic; - INTE : out std_logic; - DBIN : out std_logic; - SYNC : out std_logic; - VAIT : out std_logic; - HLDA : out std_logic; - WR_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0) - ); -end T8080se; - -architecture rtl of T8080se is - - signal IntCycle_n : std_logic; - signal NoRead : std_logic; - signal Write : std_logic; - signal IORQ : std_logic; - signal INT_n : std_logic; - signal HALT_n : std_logic; - signal BUSRQ_n : std_logic; - signal BUSAK_n : std_logic; - signal DO_i : std_logic_vector(7 downto 0); - signal DI_Reg : std_logic_vector(7 downto 0); - signal MCycle : std_logic_vector(2 downto 0); - signal TState : std_logic_vector(2 downto 0); - signal One : std_logic; - -begin - - INT_n <= not INT; - BUSRQ_n <= HOLD; - HLDA <= not BUSAK_n; - SYNC <= '1' when TState = "001" else '0'; - VAIT <= '1' when TState = "010" else '0'; - One <= '1'; - - DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA - DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n - DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!! - DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA - DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT - DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1 - DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP - DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR - - u0 : T80 - generic map( - Mode => Mode, - IOWait => 0) - port map( - CEN => CLKEN, - M1_n => open, - IORQ => IORQ, - NoRead => NoRead, - Write => Write, - RFSH_n => open, - HALT_n => HALT_n, - WAIT_n => READY, - INT_n => INT_n, - NMI_n => One, - RESET_n => RESET_n, - BUSRQ_n => One, - BUSAK_n => BUSAK_n, - CLK_n => CLK, - A => A, - DInst => DI, - DI => DI_Reg, - DO => DO_i, - MC => MCycle, - TS => TState, - IntCycle_n => IntCycle_n, - IntE => INTE); - - process (RESET_n, CLK) - begin - if RESET_n = '0' then - DBIN <= '0'; - WR_n <= '1'; - DI_Reg <= "00000000"; - elsif CLK'event and CLK = '1' then - if CLKEN = '1' then - DBIN <= '0'; - WR_n <= '1'; - if MCycle = "001" then - if TState = "001" or (TState = "010" and READY = '0') then - DBIN <= IntCycle_n; - end if; - else - if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then - DBIN <= '1'; - end if; - if T2Write = 0 then - if TState = "010" and Write = '1' then - WR_n <= '0'; - end if; - else - if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then - WR_n <= '0'; - end if; - end if; - end if; - if TState = "010" and READY = '1' then - DI_Reg <= DI; - end if; - end if; - end if; - end process; - -end; +-- **** +-- T80(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 300 started tidyup +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- 8080 compatible microprocessor core, synchronous top level with clock enable +-- Different timing than the original 8080 +-- Inputs needs to be synchronous and outputs may glitch +-- +-- Version : 0242 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- STACK status output not supported +-- +-- File history : +-- +-- 0237 : First version +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T8080se is + generic( + Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2 + ); + port( + RESET_n : in std_logic; + CLK : in std_logic; + CLKEN : in std_logic; + READY : in std_logic; + HOLD : in std_logic; + INT : in std_logic; + INTE : out std_logic; + DBIN : out std_logic; + SYNC : out std_logic; + VAIT : out std_logic; + HLDA : out std_logic; + WR_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0) + ); +end T8080se; + +architecture rtl of T8080se is + + signal IntCycle_n : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal IORQ : std_logic; + signal INT_n : std_logic; + signal HALT_n : std_logic; + signal BUSRQ_n : std_logic; + signal BUSAK_n : std_logic; + signal DO_i : std_logic_vector(7 downto 0); + signal DI_Reg : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + signal One : std_logic; + +begin + + INT_n <= not INT; + BUSRQ_n <= HOLD; + HLDA <= not BUSAK_n; + SYNC <= '1' when TState = "001" else '0'; + VAIT <= '1' when TState = "010" else '0'; + One <= '1'; + + DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA + DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n + DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!! + DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA + DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT + DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1 + DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP + DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR + + u0 : T80 + generic map( + Mode => Mode, + IOWait => 0) + port map( + CEN => CLKEN, + M1_n => open, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => open, + HALT_n => HALT_n, + WAIT_n => READY, + INT_n => INT_n, + NMI_n => One, + RESET_n => RESET_n, + BUSRQ_n => One, + BUSAK_n => BUSAK_n, + CLK_n => CLK, + A => A, + DInst => DI, + DI => DI_Reg, + DO => DO_i, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n, + IntE => INTE); + + process (RESET_n, CLK) + begin + if RESET_n = '0' then + DBIN <= '0'; + WR_n <= '1'; + DI_Reg <= "00000000"; + elsif CLK'event and CLK = '1' then + if CLKEN = '1' then + DBIN <= '0'; + WR_n <= '1'; + if MCycle = "001" then + if TState = "001" or (TState = "010" and READY = '0') then + DBIN <= IntCycle_n; + end if; + else + if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then + DBIN <= '1'; + end if; + if T2Write = 0 then + if TState = "010" and Write = '1' then + WR_n <= '0'; + end if; + else + if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then + WR_n <= '0'; + end if; + end if; + end if; + if TState = "010" and READY = '1' then + DI_Reg <= DI; + end if; + end if; + end if; + end process; + +end; diff --git a/modules/cpu-t80/T80_ALU.vhd b/modules/cpu-t80/T80_ALU.vhd index 1192e0b..7343206 100644 --- a/modules/cpu-t80/T80_ALU.vhd +++ b/modules/cpu-t80/T80_ALU.vhd @@ -1,409 +1,409 @@ --------------------------------------------------------------------------------- --- **** --- T80(c) core. Attempt to finish all undocumented features and provide --- accurate timings. --- Version 350. --- Copyright (c) 2018 Sorgelig --- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr --- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as --- correct implementation is still unclear. --- --- **** --- T80(b) core. In an effort to merge and maintain bug fixes .... --- --- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle --- Ver 300 started tidyup --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) --- --- **** --- Z80 compatible microprocessor core --- --- Version : 0247 --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test --- 0238 : Fixed zero flag for 16 bit SBC and ADC --- 0240 : Added GB operations --- 0242 : Cleanup --- 0247 : Cleanup --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity T80_ALU is - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - Arith16 : in std_logic; - Z16 : in std_logic; - WZ : in std_logic_vector(15 downto 0); - XY_State : in std_logic_vector(1 downto 0); - ALU_Op : in std_logic_vector(3 downto 0); - Rot_Akku : in std_logic; - IR : in std_logic_vector(5 downto 0); - ISet : in std_logic_vector(1 downto 0); - BusA : in std_logic_vector(7 downto 0); - BusB : in std_logic_vector(7 downto 0); - F_In : in std_logic_vector(7 downto 0); - Q : out std_logic_vector(7 downto 0); - F_Out : out std_logic_vector(7 downto 0) - ); -end T80_ALU; - -architecture rtl of T80_ALU is - - procedure AddSub(A : std_logic_vector; - B : std_logic_vector; - Sub : std_logic; - Carry_In : std_logic; - signal Res : out std_logic_vector; - signal Carry : out std_logic) is - - variable B_i : unsigned(A'length - 1 downto 0); - variable Res_i : unsigned(A'length + 1 downto 0); - begin - if Sub = '1' then - B_i := not unsigned(B); - else - B_i := unsigned(B); - end if; - - Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1"); - Carry <= Res_i(A'length + 1); - Res <= std_logic_vector(Res_i(A'length downto 1)); - end; - - -- AddSub variables (temporary signals) - signal UseCarry : std_logic; - signal Carry7_v : std_logic; - signal Overflow_v : std_logic; - signal HalfCarry_v : std_logic; - signal Carry_v : std_logic; - signal Q_v : std_logic_vector(7 downto 0); - - signal BitMask : std_logic_vector(7 downto 0); - -begin - - with IR(5 downto 3) select BitMask <= "00000001" when "000", - "00000010" when "001", - "00000100" when "010", - "00001000" when "011", - "00010000" when "100", - "00100000" when "101", - "01000000" when "110", - "10000000" when others; - - UseCarry <= not ALU_Op(2) and ALU_Op(0); - AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v); - AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v); - AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v); - - -- bug fix - parity flag is just parity for 8080, also overflow for Z80 - process (Carry_v, Carry7_v, Q_v) - begin - if(Mode=2) then - OverFlow_v <= not (Q_v(0) xor Q_v(1) xor Q_v(2) xor Q_v(3) xor - Q_v(4) xor Q_v(5) xor Q_v(6) xor Q_v(7)); else - OverFlow_v <= Carry_v xor Carry7_v; - end if; - end process; - - process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16, Rot_Akku, WZ, XY_State) - variable Q_t : std_logic_vector(7 downto 0); - variable DAA_Q : unsigned(8 downto 0); - begin - Q_t := "--------"; - F_Out <= F_In; - DAA_Q := "---------"; - case ALU_Op is - when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" => - F_Out(Flag_N) <= '0'; - F_Out(Flag_C) <= '0'; - case ALU_OP(2 downto 0) is - when "000" | "001" => -- ADD, ADC - Q_t := Q_v; - F_Out(Flag_C) <= Carry_v; - F_Out(Flag_H) <= HalfCarry_v; - F_Out(Flag_P) <= OverFlow_v; - when "010" | "011" | "111" => -- SUB, SBC, CP - Q_t := Q_v; - F_Out(Flag_N) <= '1'; - F_Out(Flag_C) <= not Carry_v; - F_Out(Flag_H) <= not HalfCarry_v; - F_Out(Flag_P) <= OverFlow_v; - when "100" => -- AND - Q_t(7 downto 0) := BusA and BusB; - F_Out(Flag_H) <= '1'; - when "101" => -- XOR - Q_t(7 downto 0) := BusA xor BusB; - F_Out(Flag_H) <= '0'; - when others => -- OR "110" - Q_t(7 downto 0) := BusA or BusB; - F_Out(Flag_H) <= '0'; - end case; - if ALU_Op(2 downto 0) = "111" then -- CP - F_Out(Flag_X) <= BusB(3); - F_Out(Flag_Y) <= BusB(5); - else - F_Out(Flag_X) <= Q_t(3); - F_Out(Flag_Y) <= Q_t(5); - end if; - if Q_t(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - if Z16 = '1' then - F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC - end if; - else - F_Out(Flag_Z) <= '0'; - end if; - F_Out(Flag_S) <= Q_t(7); - case ALU_Op(2 downto 0) is - when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP - when others => - F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor - Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); - end case; - if Arith16 = '1' then - F_Out(Flag_S) <= F_In(Flag_S); - F_Out(Flag_Z) <= F_In(Flag_Z); - F_Out(Flag_P) <= F_In(Flag_P); - end if; - when "1100" => - -- DAA - if Mode = 3 then - F_Out(Flag_H) <= '0'; - F_Out(Flag_C) <= F_In(Flag_C); - DAA_Q(7 downto 0) := unsigned(BusA); - DAA_Q(8) := '0'; - if F_In(Flag_N) = '0' then - -- After addition - -- Alow > 9 or H = 1 - if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then - DAA_Q := DAA_Q + 6; - end if; - -- new Ahigh > 9 or C = 1 - if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then - DAA_Q := DAA_Q + 96; -- 0x60 - end if; - else - -- After subtraction - if F_In(Flag_H) = '1' then - DAA_Q := DAA_Q - 6; - if F_In(Flag_C) = '0' then - DAA_Q(8) := '0'; - end if; - end if; - if F_In(Flag_C) = '1' then - DAA_Q := DAA_Q - 96; -- 0x60 - end if; - end if; - else - F_Out(Flag_H) <= F_In(Flag_H); - F_Out(Flag_C) <= F_In(Flag_C); - DAA_Q(7 downto 0) := unsigned(BusA); - DAA_Q(8) := '0'; - if F_In(Flag_N) = '0' then - -- After addition - -- Alow > 9 or H = 1 - if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then - if (DAA_Q(3 downto 0) > 9) then - F_Out(Flag_H) <= '1'; - else - F_Out(Flag_H) <= '0'; - end if; - DAA_Q := DAA_Q + 6; - end if; - -- new Ahigh > 9 or C = 1 - if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then - DAA_Q := DAA_Q + 96; -- 0x60 - end if; - else - -- After subtraction - if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then - if DAA_Q(3 downto 0) > 5 then - F_Out(Flag_H) <= '0'; - end if; - DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; - end if; - if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then - DAA_Q := DAA_Q - 352; -- 0x160 - end if; - end if; - end if; - F_Out(Flag_X) <= DAA_Q(3); - F_Out(Flag_Y) <= DAA_Q(5); - F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8); - Q_t := std_logic_vector(DAA_Q(7 downto 0)); - if DAA_Q(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - else - F_Out(Flag_Z) <= '0'; - end if; - F_Out(Flag_S) <= DAA_Q(7); - F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor - DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7)); - when "1101" | "1110" => - -- RLD, RRD - Q_t(7 downto 4) := BusA(7 downto 4); - if ALU_Op(0) = '1' then - Q_t(3 downto 0) := BusB(7 downto 4); - else - Q_t(3 downto 0) := BusB(3 downto 0); - end if; - F_Out(Flag_H) <= '0'; - F_Out(Flag_N) <= '0'; - F_Out(Flag_X) <= Q_t(3); - F_Out(Flag_Y) <= Q_t(5); - if Q_t(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - else - F_Out(Flag_Z) <= '0'; - end if; - F_Out(Flag_S) <= Q_t(7); - F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor - Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); - when "1001" => - -- BIT - Q_t(7 downto 0) := BusB and BitMask; - F_Out(Flag_S) <= Q_t(7); - if Q_t(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - F_Out(Flag_P) <= '1'; - else - F_Out(Flag_Z) <= '0'; - F_Out(Flag_P) <= '0'; - end if; - F_Out(Flag_H) <= '1'; - F_Out(Flag_N) <= '0'; - if IR(2 downto 0) = "110" or XY_State /= "00" then - F_Out(Flag_X) <= WZ(11); - F_Out(Flag_Y) <= WZ(13); - else - F_Out(Flag_X) <= BusB(3); - F_Out(Flag_Y) <= BusB(5); - end if; - when "1010" => - -- SET - Q_t(7 downto 0) := BusB or BitMask; - when "1011" => - -- RES - Q_t(7 downto 0) := BusB and not BitMask; - when "1000" => - -- ROT - case IR(5 downto 3) is - when "000" => -- RLC - Q_t(7 downto 1) := BusA(6 downto 0); - Q_t(0) := BusA(7); - F_Out(Flag_C) <= BusA(7); - when "010" => -- RL - Q_t(7 downto 1) := BusA(6 downto 0); - Q_t(0) := F_In(Flag_C); - F_Out(Flag_C) <= BusA(7); - when "001" => -- RRC - Q_t(6 downto 0) := BusA(7 downto 1); - Q_t(7) := BusA(0); - F_Out(Flag_C) <= BusA(0); - when "011" => -- RR - Q_t(6 downto 0) := BusA(7 downto 1); - Q_t(7) := F_In(Flag_C); - F_Out(Flag_C) <= BusA(0); - when "100" => -- SLA - Q_t(7 downto 1) := BusA(6 downto 0); - Q_t(0) := '0'; - F_Out(Flag_C) <= BusA(7); - when "110" => -- SLL (Undocumented) / SWAP - if Mode = 3 then - Q_t(7 downto 4) := BusA(3 downto 0); - Q_t(3 downto 0) := BusA(7 downto 4); - F_Out(Flag_C) <= '0'; - else - Q_t(7 downto 1) := BusA(6 downto 0); - Q_t(0) := '1'; - F_Out(Flag_C) <= BusA(7); - end if; - when "101" => -- SRA - Q_t(6 downto 0) := BusA(7 downto 1); - Q_t(7) := BusA(7); - F_Out(Flag_C) <= BusA(0); - when others => -- SRL - Q_t(6 downto 0) := BusA(7 downto 1); - Q_t(7) := '0'; - F_Out(Flag_C) <= BusA(0); - end case; - F_Out(Flag_H) <= '0'; - F_Out(Flag_N) <= '0'; - F_Out(Flag_X) <= Q_t(3); - F_Out(Flag_Y) <= Q_t(5); - F_Out(Flag_S) <= Q_t(7); - if Q_t(7 downto 0) = "00000000" then - F_Out(Flag_Z) <= '1'; - else - F_Out(Flag_Z) <= '0'; - end if; - F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor - Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); - if ISet = "00" then - F_Out(Flag_P) <= F_In(Flag_P); - F_Out(Flag_S) <= F_In(Flag_S); - F_Out(Flag_Z) <= F_In(Flag_Z); - end if; - if Mode = 3 and Rot_Akku = '1' then - F_Out(Flag_Z) <= '0'; - end if; - when others => - null; - end case; - Q <= Q_t; - end process; -end; +-------------------------------------------------------------------------------- +-- **** +-- T80(c) core. Attempt to finish all undocumented features and provide +-- accurate timings. +-- Version 350. +-- Copyright (c) 2018 Sorgelig +-- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr +-- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as +-- correct implementation is still unclear. +-- +-- **** +-- T80(b) core. In an effort to merge and maintain bug fixes .... +-- +-- Ver 301 parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle +-- Ver 300 started tidyup +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- Z80 compatible microprocessor core +-- +-- Version : 0247 +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- 0238 : Fixed zero flag for 16 bit SBC and ADC +-- 0240 : Added GB operations +-- 0242 : Cleanup +-- 0247 : Cleanup +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_ALU is + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + Arith16 : in std_logic; + Z16 : in std_logic; + WZ : in std_logic_vector(15 downto 0); + XY_State : in std_logic_vector(1 downto 0); + ALU_Op : in std_logic_vector(3 downto 0); + Rot_Akku : in std_logic; + IR : in std_logic_vector(5 downto 0); + ISet : in std_logic_vector(1 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + F_In : in std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0); + F_Out : out std_logic_vector(7 downto 0) + ); +end T80_ALU; + +architecture rtl of T80_ALU is + + procedure AddSub(A : std_logic_vector; + B : std_logic_vector; + Sub : std_logic; + Carry_In : std_logic; + signal Res : out std_logic_vector; + signal Carry : out std_logic) is + + variable B_i : unsigned(A'length - 1 downto 0); + variable Res_i : unsigned(A'length + 1 downto 0); + begin + if Sub = '1' then + B_i := not unsigned(B); + else + B_i := unsigned(B); + end if; + + Res_i := unsigned("0" & A & Carry_In) + unsigned("0" & B_i & "1"); + Carry <= Res_i(A'length + 1); + Res <= std_logic_vector(Res_i(A'length downto 1)); + end; + + -- AddSub variables (temporary signals) + signal UseCarry : std_logic; + signal Carry7_v : std_logic; + signal Overflow_v : std_logic; + signal HalfCarry_v : std_logic; + signal Carry_v : std_logic; + signal Q_v : std_logic_vector(7 downto 0); + + signal BitMask : std_logic_vector(7 downto 0); + +begin + + with IR(5 downto 3) select BitMask <= "00000001" when "000", + "00000010" when "001", + "00000100" when "010", + "00001000" when "011", + "00010000" when "100", + "00100000" when "101", + "01000000" when "110", + "10000000" when others; + + UseCarry <= not ALU_Op(2) and ALU_Op(0); + AddSub(BusA(3 downto 0), BusB(3 downto 0), ALU_Op(1), ALU_Op(1) xor (UseCarry and F_In(Flag_C)), Q_v(3 downto 0), HalfCarry_v); + AddSub(BusA(6 downto 4), BusB(6 downto 4), ALU_Op(1), HalfCarry_v, Q_v(6 downto 4), Carry7_v); + AddSub(BusA(7 downto 7), BusB(7 downto 7), ALU_Op(1), Carry7_v, Q_v(7 downto 7), Carry_v); + + -- bug fix - parity flag is just parity for 8080, also overflow for Z80 + process (Carry_v, Carry7_v, Q_v) + begin + if(Mode=2) then + OverFlow_v <= not (Q_v(0) xor Q_v(1) xor Q_v(2) xor Q_v(3) xor + Q_v(4) xor Q_v(5) xor Q_v(6) xor Q_v(7)); else + OverFlow_v <= Carry_v xor Carry7_v; + end if; + end process; + + process (Arith16, ALU_OP, F_In, BusA, BusB, IR, Q_v, Carry_v, HalfCarry_v, OverFlow_v, BitMask, ISet, Z16, Rot_Akku, WZ, XY_State) + variable Q_t : std_logic_vector(7 downto 0); + variable DAA_Q : unsigned(8 downto 0); + begin + Q_t := "--------"; + F_Out <= F_In; + DAA_Q := "---------"; + case ALU_Op is + when "0000" | "0001" | "0010" | "0011" | "0100" | "0101" | "0110" | "0111" => + F_Out(Flag_N) <= '0'; + F_Out(Flag_C) <= '0'; + case ALU_OP(2 downto 0) is + when "000" | "001" => -- ADD, ADC + Q_t := Q_v; + F_Out(Flag_C) <= Carry_v; + F_Out(Flag_H) <= HalfCarry_v; + F_Out(Flag_P) <= OverFlow_v; + when "010" | "011" | "111" => -- SUB, SBC, CP + Q_t := Q_v; + F_Out(Flag_N) <= '1'; + F_Out(Flag_C) <= not Carry_v; + F_Out(Flag_H) <= not HalfCarry_v; + F_Out(Flag_P) <= OverFlow_v; + when "100" => -- AND + Q_t(7 downto 0) := BusA and BusB; + F_Out(Flag_H) <= '1'; + when "101" => -- XOR + Q_t(7 downto 0) := BusA xor BusB; + F_Out(Flag_H) <= '0'; + when others => -- OR "110" + Q_t(7 downto 0) := BusA or BusB; + F_Out(Flag_H) <= '0'; + end case; + if ALU_Op(2 downto 0) = "111" then -- CP + F_Out(Flag_X) <= BusB(3); + F_Out(Flag_Y) <= BusB(5); + else + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + end if; + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + if Z16 = '1' then + F_Out(Flag_Z) <= F_In(Flag_Z); -- 16 bit ADC,SBC + end if; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= Q_t(7); + case ALU_Op(2 downto 0) is + when "000" | "001" | "010" | "011" | "111" => -- ADD, ADC, SUB, SBC, CP + when others => + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + end case; + if Arith16 = '1' then + F_Out(Flag_S) <= F_In(Flag_S); + F_Out(Flag_Z) <= F_In(Flag_Z); + F_Out(Flag_P) <= F_In(Flag_P); + end if; + when "1100" => + -- DAA + if Mode = 3 then + F_Out(Flag_H) <= '0'; + F_Out(Flag_C) <= F_In(Flag_C); + DAA_Q(7 downto 0) := unsigned(BusA); + DAA_Q(8) := '0'; + if F_In(Flag_N) = '0' then + -- After addition + -- Alow > 9 or H = 1 + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + DAA_Q := DAA_Q + 6; + end if; + -- new Ahigh > 9 or C = 1 + if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q + 96; -- 0x60 + end if; + else + -- After subtraction + if F_In(Flag_H) = '1' then + DAA_Q := DAA_Q - 6; + if F_In(Flag_C) = '0' then + DAA_Q(8) := '0'; + end if; + end if; + if F_In(Flag_C) = '1' then + DAA_Q := DAA_Q - 96; -- 0x60 + end if; + end if; + else + F_Out(Flag_H) <= F_In(Flag_H); + F_Out(Flag_C) <= F_In(Flag_C); + DAA_Q(7 downto 0) := unsigned(BusA); + DAA_Q(8) := '0'; + if F_In(Flag_N) = '0' then + -- After addition + -- Alow > 9 or H = 1 + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if (DAA_Q(3 downto 0) > 9) then + F_Out(Flag_H) <= '1'; + else + F_Out(Flag_H) <= '0'; + end if; + DAA_Q := DAA_Q + 6; + end if; + -- new Ahigh > 9 or C = 1 + if DAA_Q(8 downto 4) > 9 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q + 96; -- 0x60 + end if; + else + -- After subtraction + if DAA_Q(3 downto 0) > 9 or F_In(Flag_H) = '1' then + if DAA_Q(3 downto 0) > 5 then + F_Out(Flag_H) <= '0'; + end if; + DAA_Q(7 downto 0) := DAA_Q(7 downto 0) - 6; + end if; + if unsigned(BusA) > 153 or F_In(Flag_C) = '1' then + DAA_Q := DAA_Q - 352; -- 0x160 + end if; + end if; + end if; + F_Out(Flag_X) <= DAA_Q(3); + F_Out(Flag_Y) <= DAA_Q(5); + F_Out(Flag_C) <= F_In(Flag_C) or DAA_Q(8); + Q_t := std_logic_vector(DAA_Q(7 downto 0)); + if DAA_Q(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= DAA_Q(7); + F_Out(Flag_P) <= not (DAA_Q(0) xor DAA_Q(1) xor DAA_Q(2) xor DAA_Q(3) xor + DAA_Q(4) xor DAA_Q(5) xor DAA_Q(6) xor DAA_Q(7)); + when "1101" | "1110" => + -- RLD, RRD + Q_t(7 downto 4) := BusA(7 downto 4); + if ALU_Op(0) = '1' then + Q_t(3 downto 0) := BusB(7 downto 4); + else + Q_t(3 downto 0) := BusB(3 downto 0); + end if; + F_Out(Flag_H) <= '0'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_S) <= Q_t(7); + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + when "1001" => + -- BIT + Q_t(7 downto 0) := BusB and BitMask; + F_Out(Flag_S) <= Q_t(7); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + F_Out(Flag_P) <= '1'; + else + F_Out(Flag_Z) <= '0'; + F_Out(Flag_P) <= '0'; + end if; + F_Out(Flag_H) <= '1'; + F_Out(Flag_N) <= '0'; + if IR(2 downto 0) = "110" or XY_State /= "00" then + F_Out(Flag_X) <= WZ(11); + F_Out(Flag_Y) <= WZ(13); + else + F_Out(Flag_X) <= BusB(3); + F_Out(Flag_Y) <= BusB(5); + end if; + when "1010" => + -- SET + Q_t(7 downto 0) := BusB or BitMask; + when "1011" => + -- RES + Q_t(7 downto 0) := BusB and not BitMask; + when "1000" => + -- ROT + case IR(5 downto 3) is + when "000" => -- RLC + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := BusA(7); + F_Out(Flag_C) <= BusA(7); + when "010" => -- RL + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := F_In(Flag_C); + F_Out(Flag_C) <= BusA(7); + when "001" => -- RRC + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := BusA(0); + F_Out(Flag_C) <= BusA(0); + when "011" => -- RR + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := F_In(Flag_C); + F_Out(Flag_C) <= BusA(0); + when "100" => -- SLA + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := '0'; + F_Out(Flag_C) <= BusA(7); + when "110" => -- SLL (Undocumented) / SWAP + if Mode = 3 then + Q_t(7 downto 4) := BusA(3 downto 0); + Q_t(3 downto 0) := BusA(7 downto 4); + F_Out(Flag_C) <= '0'; + else + Q_t(7 downto 1) := BusA(6 downto 0); + Q_t(0) := '1'; + F_Out(Flag_C) <= BusA(7); + end if; + when "101" => -- SRA + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := BusA(7); + F_Out(Flag_C) <= BusA(0); + when others => -- SRL + Q_t(6 downto 0) := BusA(7 downto 1); + Q_t(7) := '0'; + F_Out(Flag_C) <= BusA(0); + end case; + F_Out(Flag_H) <= '0'; + F_Out(Flag_N) <= '0'; + F_Out(Flag_X) <= Q_t(3); + F_Out(Flag_Y) <= Q_t(5); + F_Out(Flag_S) <= Q_t(7); + if Q_t(7 downto 0) = "00000000" then + F_Out(Flag_Z) <= '1'; + else + F_Out(Flag_Z) <= '0'; + end if; + F_Out(Flag_P) <= not (Q_t(0) xor Q_t(1) xor Q_t(2) xor Q_t(3) xor + Q_t(4) xor Q_t(5) xor Q_t(6) xor Q_t(7)); + if ISet = "00" then + F_Out(Flag_P) <= F_In(Flag_P); + F_Out(Flag_S) <= F_In(Flag_S); + F_Out(Flag_Z) <= F_In(Flag_Z); + end if; + if Mode = 3 and Rot_Akku = '1' then + F_Out(Flag_Z) <= '0'; + end if; + when others => + null; + end case; + Q <= Q_t; + end process; +end; diff --git a/modules/cpu-t80/T80_MCode.vhd b/modules/cpu-t80/T80_MCode.vhd index 554ec9b..871bda8 100644 --- a/modules/cpu-t80/T80_MCode.vhd +++ b/modules/cpu-t80/T80_MCode.vhd @@ -1,2289 +1,2289 @@ --------------------------------------------------------------------------------- --- **** --- T80(c) core. Attempt to finish all undocumented features and provide --- accurate timings. --- Version 350. --- Copyright (c) 2018 Sorgelig --- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr --- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as --- correct implementation is still unclear. --- --- **** --- T80(b) core. In an effort to merge and maintain bug fixes .... --- --- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010 --- Ver 300 started tidyup --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) --- --- **** --- Z80 compatible microprocessor core --- --- Version : 0250 --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0208 : First complete release --- 0211 : Fixed IM 1 --- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test --- 0235 : Added IM 2 fix by Mike Johnson --- 0238 : Added NoRead signal --- 0238b: Fixed instruction timing for POP and DJNZ --- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes --- 0240mj1 fix for HL inc/dec for INI, IND, INIR, INDR, OUTI, OUTD, OTIR, OTDR --- 0242 : Fixed I/O instruction timing, cleanup --- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15 --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity T80_MCode is - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - IR : in std_logic_vector(7 downto 0); - ISet : in std_logic_vector(1 downto 0); - MCycle : in std_logic_vector(2 downto 0); - F : in std_logic_vector(7 downto 0); - NMICycle : in std_logic; - IntCycle : in std_logic; - XY_State : in std_logic_vector(1 downto 0); - MCycles : out std_logic_vector(2 downto 0); - TStates : out std_logic_vector(2 downto 0); - Prefix : out std_logic_vector(1 downto 0); -- None,CB,ED,DD/FD - Inc_PC : out std_logic; - Inc_WZ : out std_logic; - IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc - Read_To_Reg : out std_logic; - Read_To_Acc : out std_logic; - Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F - Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 - ALU_Op : out std_logic_vector(3 downto 0); - -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None - Save_ALU : out std_logic; - Rot_Akku : out std_logic; - PreserveC : out std_logic; - Arith16 : out std_logic; - Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI - IORQ : out std_logic; - Jump : out std_logic; - JumpE : out std_logic; - JumpXY : out std_logic; - Call : out std_logic; - RstP : out std_logic; - LDZ : out std_logic; - LDW : out std_logic; - LDSPHL : out std_logic; - LDHLSP : out std_logic; - ADDSPdd : out std_logic; - Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None - ExchangeDH : out std_logic; - ExchangeRp : out std_logic; - ExchangeAF : out std_logic; - ExchangeRS : out std_logic; - ExchangeWH : out std_logic; - I_DJNZ : out std_logic; - I_CPL : out std_logic; - I_CCF : out std_logic; - I_SCF : out std_logic; - I_RETN : out std_logic; - I_BT : out std_logic; - I_BC : out std_logic; - I_BTR : out std_logic; - I_RLD : out std_logic; - I_RRD : out std_logic; - I_INRC : out std_logic; - I_MULUB : out std_logic; - I_MULU : out std_logic; - SetWZ : out std_logic_vector(1 downto 0); - SetDI : out std_logic; - SetEI : out std_logic; - IMode : out std_logic_vector(1 downto 0); - Halt : out std_logic; - NoRead : out std_logic; - Write : out std_logic; - R800_mode : in std_logic; - No_PC : out std_logic; - XYbit_undoc : out std_logic - ); -end T80_MCode; - -architecture rtl of T80_MCode is - - function is_cc_true( - F : std_logic_vector(7 downto 0); - cc : bit_vector(2 downto 0) - ) return boolean is - begin - if Mode = 3 then - case cc is - when "000" => return F(Flag_Z) = '0'; -- NZ - when "001" => return F(Flag_Z) = '1'; -- Z - when "010" => return F(Flag_C) = '0'; -- NC - when "011" => return F(Flag_C) = '1'; -- C - when "100" => return false; - when "101" => return false; - when "110" => return false; - when "111" => return false; - end case; - else - case cc is - when "000" => return F(Flag_Z) = '0'; -- NZ - when "001" => return F(Flag_Z) = '1'; -- Z - when "010" => return F(Flag_C) = '0'; -- NC - when "011" => return F(Flag_C) = '1'; -- C - when "100" => return F(Flag_P) = '0'; -- PO - when "101" => return F(Flag_P) = '1'; -- PE - when "110" => return F(Flag_S) = '0'; -- P - when "111" => return F(Flag_S) = '1'; -- M - end case; - end if; - end; - -begin - - process (IR, ISet, MCycle, F, NMICycle, IntCycle, XY_State, R800_mode) - variable DDD : std_logic_vector(2 downto 0); - variable SSS : std_logic_vector(2 downto 0); - variable DPair : std_logic_vector(1 downto 0); - variable IRB : bit_vector(7 downto 0); - begin - DDD := IR(5 downto 3); - SSS := IR(2 downto 0); - DPair := IR(5 downto 4); - IRB := to_bitvector(IR); - - MCycles <= "001"; - if MCycle = "001" then - TStates <= "100"; - else - TStates <= "011"; - end if; - Prefix <= "00"; - Inc_PC <= '0'; - Inc_WZ <= '0'; - IncDec_16 <= "0000"; - Read_To_Acc <= '0'; - Read_To_Reg <= '0'; - Set_BusB_To <= "0000"; - Set_BusA_To <= "0000"; - ALU_Op <= "0" & IR(5 downto 3); - Save_ALU <= '0'; - Rot_Akku <= '0'; - PreserveC <= '0'; - Arith16 <= '0'; - IORQ <= '0'; - Set_Addr_To <= aNone; - Jump <= '0'; - JumpE <= '0'; - JumpXY <= '0'; - Call <= '0'; - RstP <= '0'; - LDZ <= '0'; - LDW <= '0'; - LDSPHL <= '0'; - LDHLSP <= '0'; - ADDSPdd <= '0'; - Special_LD <= "000"; - ExchangeDH <= '0'; - ExchangeRp <= '0'; - ExchangeAF <= '0'; - ExchangeRS <= '0'; - ExchangeWH <= '0'; - I_DJNZ <= '0'; - I_CPL <= '0'; - I_CCF <= '0'; - I_SCF <= '0'; - I_RETN <= '0'; - I_BT <= '0'; - I_BC <= '0'; - I_BTR <= '0'; - I_RLD <= '0'; - I_RRD <= '0'; - I_INRC <= '0'; - I_MULUB <= '0'; - I_MULU <= '0'; - SetDI <= '0'; - SetEI <= '0'; - IMode <= "11"; - Halt <= '0'; - NoRead <= '0'; - Write <= '0'; - No_PC <= '0'; - XYbit_undoc <= '0'; - SetWZ <= "00"; - - case ISet is - when "00" => - ------------------------------------------------------------------------------- --- --- Unprefixed instructions --- ------------------------------------------------------------------------------- - - case IRB is --- 8 BIT LOAD GROUP - when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" - |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" - |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" - |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" - |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" - |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" - |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => - -- LD r,r' - Set_BusB_To(2 downto 0) <= SSS; - ExchangeRp <= '1'; - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" => - -- LD r,n - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - when others => null; - end case; - when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" => - -- LD r,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - when others => null; - end case; - when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" => - -- LD (HL),r - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusB_To(3) <= '0'; - when 2 => - Write <= '1'; - when others => null; - end case; - when "00110110" => - -- LD (HL),n - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aXY; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusB_To(3) <= '0'; - when 3 => - Write <= '1'; - when others => null; - end case; - when "00001010" => - -- LD A,(BC) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - when 2 => - Read_To_Acc <= '1'; - when others => null; - end case; - when "00011010" => - -- LD A,(DE) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aDE; - when 2 => - Read_To_Acc <= '1'; - when others => null; - end case; - when "00111010" => - if Mode = 3 then - -- LDD A,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Read_To_Acc <= '1'; - IncDec_16 <= "1110"; - when others => null; - end case; - else - -- LD A,(nn) - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - when 4 => - Read_To_Acc <= '1'; - when others => null; - end case; - end if; - when "00000010" => - -- LD (BC),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - Set_BusB_To <= "0111"; - SetWZ <= "10"; - when 2 => - Write <= '1'; - when others => null; - end case; - when "00010010" => - -- LD (DE),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aDE; - Set_BusB_To <= "0111"; - SetWZ <= "10"; - when 2 => - Write <= '1'; - when others => null; - end case; - when "00110010" => - if Mode = 3 then - -- LDD (HL),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - Set_BusB_To <= "0111"; - when 2 => - Write <= '1'; - IncDec_16 <= "1110"; - when others => null; - end case; - else - -- LD (nn),A - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - SetWZ <= "10"; - Inc_PC <= '1'; - Set_BusB_To <= "0111"; - when 4 => - Write <= '1'; - when others => null; - end case; - end if; - --- 16 BIT LOAD GROUP - when "00000001"|"00010001"|"00100001"|"00110001" => - -- LD dd,nn - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Read_To_Reg <= '1'; - if DPAIR = "11" then - Set_BusA_To(3 downto 0) <= "1000"; - else - Set_BusA_To(2 downto 1) <= DPAIR; - Set_BusA_To(0) <= '1'; - end if; - when 3 => - Inc_PC <= '1'; - Read_To_Reg <= '1'; - if DPAIR = "11" then - Set_BusA_To(3 downto 0) <= "1001"; - else - Set_BusA_To(2 downto 1) <= DPAIR; - Set_BusA_To(0) <= '0'; - end if; - when others => null; - end case; - when "00101010" => - if Mode = 3 then - -- LDI A,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Read_To_Acc <= '1'; - IncDec_16 <= "0110"; - when others => null; - end case; - else - -- LD HL,(nn) - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - when 4 => - Set_BusA_To(2 downto 0) <= "101"; -- L - Read_To_Reg <= '1'; - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - when 5 => - Set_BusA_To(2 downto 0) <= "100"; -- H - Read_To_Reg <= '1'; - when others => null; - end case; - end if; - when "00100010" => - if Mode = 3 then - -- LDI (HL),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - Set_BusB_To <= "0111"; - when 2 => - Write <= '1'; - IncDec_16 <= "0110"; - when others => null; - end case; - else - -- LD (nn),HL - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - Set_BusB_To <= "0101"; -- L - when 4 => - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - Write <= '1'; - Set_BusB_To <= "0100"; -- H - when 5 => - Write <= '1'; - when others => null; - end case; - end if; - when "11111001" => - -- LD SP,HL - if Mode = 3 then - MCycles <= "010"; - if MCycle = "010" then - LDSPHL <= '1'; - end if; - else - TStates <= "110"; - LDSPHL <= '1'; - end if; - when "11000101"|"11010101"|"11100101"|"11110101" => - -- PUSH qq - if Mode = 3 then - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_TO <= aSP; - if DPAIR = "11" then - Set_BusB_To <= "0111"; - else - Set_BusB_To(2 downto 1) <= DPAIR; - Set_BusB_To(0) <= '0'; - Set_BusB_To(3) <= '0'; - end if; - when 3 => - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - if DPAIR = "11" then - Set_BusB_To <= "1011"; - else - Set_BusB_To(2 downto 1) <= DPAIR; - Set_BusB_To(0) <= '1'; - Set_BusB_To(3) <= '0'; - end if; - Write <= '1'; - when 4 => - Write <= '1'; - when others => null; - end case; - else - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_TO <= aSP; - if DPAIR = "11" then - Set_BusB_To <= "0111"; - else - Set_BusB_To(2 downto 1) <= DPAIR; - Set_BusB_To(0) <= '0'; - Set_BusB_To(3) <= '0'; - end if; - when 2 => - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - if DPAIR = "11" then - Set_BusB_To <= "1011"; - else - Set_BusB_To(2 downto 1) <= DPAIR; - Set_BusB_To(0) <= '1'; - Set_BusB_To(3) <= '0'; - end if; - Write <= '1'; - when 3 => - Write <= '1'; - when others => null; - end case; - end if; - when "11000001"|"11010001"|"11100001"|"11110001" => - -- POP qq - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - Read_To_Reg <= '1'; - if DPAIR = "11" then - Set_BusA_To(3 downto 0) <= "1011"; - else - Set_BusA_To(2 downto 1) <= DPAIR; - Set_BusA_To(0) <= '1'; - end if; - when 3 => - IncDec_16 <= "0111"; - Read_To_Reg <= '1'; - if DPAIR = "11" then - Set_BusA_To(3 downto 0) <= "0111"; - else - Set_BusA_To(2 downto 1) <= DPAIR; - Set_BusA_To(0) <= '0'; - end if; - when others => null; - end case; - --- EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP - when "11101011" => - if Mode /= 3 then - -- EX DE,HL - ExchangeDH <= '1'; - end if; - when "00001000" => - if Mode = 3 then - -- LD (nn),SP - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - Set_BusB_To <= "1000"; - when 4 => - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - Write <= '1'; - Set_BusB_To <= "1001"; - when 5 => - Write <= '1'; - when others => null; - end case; - elsif Mode < 2 then - -- EX AF,AF' - ExchangeAF <= '1'; - end if; - when "11011001" => - if Mode = 3 then - -- RETI - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_TO <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - --I_RETN <= '1'; - SetEI <= '1'; - when others => null; - end case; - elsif Mode < 2 then - -- EXX - ExchangeRS <= '1'; - end if; - when "11100011" => - if Mode /= 3 then - -- EX (SP),HL - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aSP; - when 2 => - Set_Addr_To <= aSP; - LDZ <= '1'; - IncDec_16 <= "0111"; -- SP <= SP+1 - when 3 => - TStates <= "100"; - Set_BusB_To <= "0100"; - Set_Addr_To <= aSP; - LDW <= '1'; - when 4 => - Set_BusB_To <= "0101"; - Write <= '1'; - IncDec_16 <= "1111"; -- SP <= SP-1 - Set_Addr_To <= aSP; - when 5 => - ExchangeWH <= '1'; -- save WZ to HL - TStates <= "101"; - Write <= '1'; - when others => null; - end case; - end if; - --- 8 BIT ARITHMETIC AND LOGICAL GROUP - when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" - |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" - |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" - |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" - |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" - |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" - |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" - |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => - -- ADD A,r - -- ADC A,r - -- SUB A,r - -- SBC A,r - -- AND A,r - -- OR A,r - -- XOR A,r - -- CP A,r - Set_BusB_To(2 downto 0) <= SSS; - Set_BusA_To(2 downto 0) <= "111"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => - -- ADD A,(HL) - -- ADC A,(HL) - -- SUB A,(HL) - -- SBC A,(HL) - -- AND A,(HL) - -- OR A,(HL) - -- XOR A,(HL) - -- CP A,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusA_To(2 downto 0) <= "111"; - when others => null; - end case; - when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => - -- ADD A,n - -- ADC A,n - -- SUB A,n - -- SBC A,n - -- AND A,n - -- OR A,n - -- XOR A,n - -- CP A,n - MCycles <= "010"; - if MCycle = "010" then - Inc_PC <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusA_To(2 downto 0) <= "111"; - end if; - when "00000100"|"00001100"|"00010100"|"00011100"|"00100100"|"00101100"|"00111100" => - -- INC r - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - PreserveC <= '1'; - ALU_Op <= "0000"; - when "00110100" => - -- INC (HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - TStates <= "100"; - Set_Addr_To <= aXY; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - PreserveC <= '1'; - ALU_Op <= "0000"; - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= DDD; - when 3 => - Write <= '1'; - when others => null; - end case; - when "00000101"|"00001101"|"00010101"|"00011101"|"00100101"|"00101101"|"00111101" => - -- DEC r - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= DDD; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - PreserveC <= '1'; - ALU_Op <= "0010"; - when "00110101" => - -- DEC (HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - TStates <= "100"; - Set_Addr_To <= aXY; - ALU_Op <= "0010"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - PreserveC <= '1'; - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= DDD; - when 3 => - Write <= '1'; - when others => null; - end case; - --- GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS - when "00100111" => - -- DAA - Set_BusA_To(2 downto 0) <= "111"; - Read_To_Reg <= '1'; - ALU_Op <= "1100"; - Save_ALU <= '1'; - when "00101111" => - -- CPL - I_CPL <= '1'; - when "00111111" => - -- CCF - I_CCF <= '1'; - when "00110111" => - -- SCF - I_SCF <= '1'; - when "00000000" => - if NMICycle = '1' then - -- NMI - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 3 => - Write <= '1'; - when others => null; - end case; - elsif IntCycle = '1' then - -- INT (IM 2) - if Mode = 3 then - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "110"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - Write <= '1'; - when 3 => -- GB: interrupt is acknowledged on MCycle 3 - LDZ <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 4 => - Write <= '1'; - when others => null; - end case; - else - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - --TStates <= "100"; - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 3 => - --TStates <= "100"; - Write <= '1'; - when 4 => - Inc_PC <= '1'; - LDZ <= '1'; - when 5 => - Jump <= '1'; - when others => null; - end case; - end if; - else - -- NOP - end if; - when "01110110" => - -- HALT - Halt <= '1'; - when "11110011" => - -- DI - SetDI <= '1'; - when "11111011" => - -- EI - SetEI <= '1'; - --- 16 BIT ARITHMETIC GROUP - when "00001001"|"00011001"|"00101001"|"00111001" => - -- ADD HL,ss - if Mode = 3 then - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - NoRead <= '1'; - ALU_Op <= "0000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "101"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; - when others => - Set_BusB_To <= "1000"; - end case; - TStates <= "100"; - Arith16 <= '1'; - SetWZ <= "11"; - when 2 => - NoRead <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0001"; - Set_BusA_To(2 downto 0) <= "100"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - when others => - Set_BusB_To <= "1001"; - end case; - Arith16 <= '1'; - when others => - end case; - else - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - No_PC <= '1'; - when 2 => - NoRead <= '1'; - ALU_Op <= "0000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "101"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; - when others => - Set_BusB_To <= "1000"; - end case; - TStates <= "100"; - Arith16 <= '1'; - SetWZ <= "11"; - No_PC <= '1'; - when 3 => - NoRead <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0001"; - Set_BusA_To(2 downto 0) <= "100"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - when others => - Set_BusB_To <= "1001"; - end case; - Arith16 <= '1'; - when others => - end case; - end if; - when "00000011"|"00010011"|"00100011"|"00110011" => - -- INC ss - if Mode = 3 then - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 2 => - IncDec_16(3 downto 2) <= "01"; - IncDec_16(1 downto 0) <= DPair; - when others => - end case; - else - TStates <= "110"; - IncDec_16(3 downto 2) <= "01"; - IncDec_16(1 downto 0) <= DPair; - end if; - when "00001011"|"00011011"|"00101011"|"00111011" => - -- DEC ss - if Mode = 3 then - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 2 => - IncDec_16(3 downto 2) <= "11"; - IncDec_16(1 downto 0) <= DPair; - when others => - end case; - else - TStates <= "110"; - IncDec_16(3 downto 2) <= "11"; - IncDec_16(1 downto 0) <= DPair; - end if; - --- ROTATE AND SHIFT GROUP - when "00000111" - -- RLCA - |"00010111" - -- RLA - |"00001111" - -- RRCA - |"00011111" => - -- RRA - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "1000"; - Read_To_Reg <= '1'; - Rot_Akku <= '1'; - Save_ALU <= '1'; - --- JUMP GROUP - when "11000011" => - -- JP nn - if Mode = 3 then - MCycles <= "100"; - else - MCycles <= "011"; - end if; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Inc_PC <= '1'; - Jump <= '1'; - if Mode /= 3 then - LDW <= '1'; - end if; - when others => null; - end case; - when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" => - if IR(5) = '1' and Mode = 3 then - case IRB(4 downto 3) is - when "00" => - -- LD ($FF00+C),A - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - Set_BusB_To <= "0111"; - IORQ <= '1'; --TH must be earlier to be stable when address is generated - when 2 => - Write <= '1'; - when others => - end case; - when "01" => - -- LD (nn),A - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - Set_BusB_To <= "0111"; - when 4 => - Write <= '1'; - when others => null; - end case; - when "10" => - -- LD A,($FF00+C) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - IORQ <= '1'; --TH must be earlier to be stable when address is generated - when 2 => - Read_To_Acc <= '1'; - when others => - end case; - when "11" => - -- LD A,(nn) - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - when 4 => - Read_To_Acc <= '1'; - when others => null; - end case; - end case; - else - -- JP cc,nn - if Mode = 3 then - MCycles <= "100"; - else - MCycles <= "011"; - end if; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - if Mode /= 3 then - LDW <= '1'; - end if; - Inc_PC <= '1'; - if is_cc_true(F, to_bitvector(IR(5 downto 3))) then - Jump <= '1'; - elsif Mode = 3 then - MCycles <= "011"; - end if; - when others => null; - end case; - end if; - when "00011000" => - if Mode /= 2 then - -- JR e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - No_PC <= '1'; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "00111000" => - if Mode /= 2 then - -- JR C,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - if F(Flag_C) = '0' then - MCycles <= "010"; - else - No_PC <= '1'; - end if; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "00110000" => - if Mode /= 2 then - -- JR NC,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - if F(Flag_C) = '1' then - MCycles <= "010"; - else - No_PC <= '1'; - end if; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "00101000" => - if Mode /= 2 then - -- JR Z,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - if F(Flag_Z) = '0' then - MCycles <= "010"; - else - No_PC <= '1'; - end if; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "00100000" => - if Mode /= 2 then - -- JR NZ,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - if F(Flag_Z) = '1' then - MCycles <= "010"; - else - No_PC <= '1'; - end if; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - when "11101001" => - -- JP (HL) - JumpXY <= '1'; - when "00010000" => - if Mode = 3 then -- STOP and skip next byte - MCycles <= "010"; - I_DJNZ <= '1'; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - when others => null; - end case; - elsif Mode < 2 then - -- DJNZ,e - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - I_DJNZ <= '1'; - Set_BusB_To <= "1010"; - Set_BusA_To(2 downto 0) <= "000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0010"; - when 2 => - I_DJNZ <= '1'; - Inc_PC <= '1'; - No_PC <= '1'; - when 3 => - NoRead <= '1'; - JumpE <= '1'; - TStates <= "101"; - when others => null; - end case; - end if; - --- CALL AND RETURN GROUP - when "11001101" => - -- CALL nn - if Mode = 3 then - MCycles <= "110"; - else - MCycles <= "101"; - end if; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - IncDec_16 <= "1111"; - Inc_PC <= '1'; - TStates <= "100"; - Set_Addr_To <= aSP; - LDW <= '1'; - Set_BusB_To <= "1101"; - when 4 => - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 5 => - Write <= '1'; - Call <= '1'; - when others => null; - end case; - when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" => - if IR(5) = '0' or Mode /= 3 then - -- CALL cc,nn - if Mode = 3 then - MCycles <= "110"; - else - MCycles <= "101"; - end if; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Inc_PC <= '1'; - LDW <= '1'; - if is_cc_true(F, to_bitvector(IR(5 downto 3))) then - IncDec_16 <= "1111"; - Set_Addr_TO <= aSP; - TStates <= "100"; - Set_BusB_To <= "1101"; - else - MCycles <= "011"; - end if; - when 4 => - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 5 => - Write <= '1'; - Call <= '1'; - when others => null; - end case; - end if; - when "11001001" => - -- RET - if Mode = 3 then - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - Set_Addr_TO <= aSP; - when 3 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 4 => - Jump <= '1'; - IncDec_16 <= "0111"; - when others => null; - end case; - else - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - --TStates <= "101"; - Set_Addr_TO <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - when others => null; - end case; - end if; - when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" => - if IR(5) = '1' and Mode = 3 then - case IRB(4 downto 3) is - when "00" => - -- LD ($FF00+nn),A - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aIOA; - Set_BusB_To <= "0111"; - when 3 => - Write <= '1'; - when others => null; - end case; - when "01" => - -- ADD SP,n - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 3 => - Inc_PC <= '1'; - ADDSPdd <= '1'; - when others => - end case; - when "10" => - -- LD A,($FF00+nn) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aIOA; - when 3 => - Read_To_Acc <= '1'; - when others => null; - end case; - when "11" => - -- LD HL,SP+n - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Inc_PC <= '1'; - when 2 => - LDHLSP <= '1'; - Inc_PC <= '1'; - when 3 => - LDHLSP <= '1'; - when others => null; - end case; - end case; - else - -- RET cc - if Mode = 3 then - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - if is_cc_true(F, to_bitvector(IR(5 downto 3))) then - Set_Addr_TO <= aSP; - else - MCycles <= "010"; - end if; - TStates <= "101"; - when 3 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 4 => - Jump <= '1'; - IncDec_16 <= "0111"; - when others => null; - end case; - else - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - if is_cc_true(F, to_bitvector(IR(5 downto 3))) then - Set_Addr_TO <= aSP; - else - MCycles <= "001"; - end if; - TStates <= "101"; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - when others => null; - end case; - end if; - end if; - when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" => - -- RST p - if Mode = 3 then - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 2 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 3 => - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 4 => - Write <= '1'; - RstP <= '1'; - when others => null; - end case; - else - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1101"; - when 2 => - Write <= '1'; - IncDec_16 <= "1111"; - Set_Addr_To <= aSP; - Set_BusB_To <= "1100"; - when 3 => - Write <= '1'; - RstP <= '1'; - when others => null; - end case; - end if; - --- INPUT AND OUTPUT GROUP - when "11011011" => - if Mode /= 3 then - -- IN A,(n) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aIOA; - when 3 => - Read_To_Acc <= '1'; - IORQ <= '1'; - when others => null; - end case; - end if; - when "11010011" => - if Mode /= 3 then - -- OUT (n),A - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - Set_Addr_To <= aIOA; - Set_BusB_To <= "0111"; - when 3 => - Write <= '1'; - IORQ <= '1'; - when others => null; - end case; - end if; - ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- --- MULTIBYTE INSTRUCTIONS ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- - - when "11001011" => - if Mode /= 2 then - Prefix <= "01"; - end if; - - when "11101101" => - if Mode < 2 then - Prefix <= "10"; - end if; - - when "11011101"|"11111101" => - if Mode < 2 then - Prefix <= "11"; - end if; - - end case; - - when "01" => - ------------------------------------------------------------------------------- --- --- CB prefixed instructions --- ------------------------------------------------------------------------------- - - Set_BusA_To(2 downto 0) <= IR(2 downto 0); - Set_BusB_To(2 downto 0) <= IR(2 downto 0); - - case IRB is - when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000111" - |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010111" - |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001111" - |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011111" - |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100111" - |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101111" - |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110111" - |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111111" => - -- RLC r - -- RL r - -- RRC r - -- RR r - -- SLA r - -- SRA r - -- SRL r - -- SLL r (Undocumented) / SWAP r - if XY_State="00" then - if MCycle = "001" then - ALU_Op <= "1000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - end if; - else - -- R/S (IX+d),Reg, undocumented - MCycles <= "011"; - XYbit_undoc <= '1'; - case to_integer(unsigned(MCycle)) is - when 1 | 7=> - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_Addr_To <= aXY; - TStates <= "100"; - when 3 => - Write <= '1'; - when others => null; - end case; - end if; - - when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" => - -- RLC (HL) - -- RL (HL) - -- RRC (HL) - -- RR (HL) - -- SRA (HL) - -- SRL (HL) - -- SLA (HL) - -- SLL (HL) (Undocumented) / SWAP (HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 | 7 => - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_Addr_To <= aXY; - TStates <= "100"; - when 3 => - Write <= '1'; - when others => - end case; - when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" - |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" - |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" - |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" - |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" - |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" - |"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" - |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => - -- BIT b,r - if XY_State="00" then - if MCycle = "001" then - Set_BusB_To(2 downto 0) <= IR(2 downto 0); - ALU_Op <= "1001"; - end if; - else - -- BIT b,(IX+d), undocumented - MCycles <= "010"; - XYbit_undoc <= '1'; - case to_integer(unsigned(MCycle)) is - when 1 | 7=> - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1001"; - TStates <= "100"; - when others => null; - end case; - end if; - - when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" => - -- BIT b,(HL) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 | 7 => - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1001"; - TStates <= "100"; - when others => null; - end case; - when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111" - |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111" - |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010111" - |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011111" - |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100111" - |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101111" - |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111" - |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" => - -- SET b,r - if XY_State="00" then - if MCycle = "001" then - ALU_Op <= "1010"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - end if; - else - -- SET b,(IX+d),Reg, undocumented - MCycles <= "011"; - XYbit_undoc <= '1'; - case to_integer(unsigned(MCycle)) is - when 1 | 7=> - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1010"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_Addr_To <= aXY; - TStates <= "100"; - when 3 => - Write <= '1'; - when others => null; - end case; - end if; - - when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => - -- SET b,(HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 | 7 => - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1010"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_Addr_To <= aXY; - TStates <= "100"; - when 3 => - Write <= '1'; - when others => null; - end case; - when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" - |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" - |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" - |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" - |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" - |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" - |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" - |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => - -- RES b,r - if XY_State="00" then - if MCycle = "001" then - ALU_Op <= "1011"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - end if; - else - -- RES b,(IX+d),Reg, undocumented - MCycles <= "011"; - XYbit_undoc <= '1'; - case to_integer(unsigned(MCycle)) is - when 1 | 7=> - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1011"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_Addr_To <= aXY; - TStates <= "100"; - when 3 => - Write <= '1'; - when others => null; - end case; - end if; - - when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => - -- RES b,(HL) - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 | 7 => - Set_Addr_To <= aXY; - when 2 => - ALU_Op <= "1011"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_Addr_To <= aXY; - TStates <= "100"; - when 3 => - Write <= '1'; - when others => null; - end case; - end case; - - when others => - ------------------------------------------------------------------------------- --- --- ED prefixed instructions --- ------------------------------------------------------------------------------- - - case IRB is - when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000110"|"00000111" - |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001110"|"00001111" - |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010110"|"00010111" - |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011110"|"00011111" - |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100110"|"00100111" - |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101110"|"00101111" - |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110110"|"00110111" - |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111110"|"00111111" - - - |"10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000110"|"10000111" - |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001110"|"10001111" - |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010110"|"10010111" - |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011110"|"10011111" - | "10100100"|"10100101"|"10100110"|"10100111" - | "10101100"|"10101101"|"10101110"|"10101111" - | "10110100"|"10110101"|"10110110"|"10110111" - | "10111100"|"10111101"|"10111110"|"10111111" - |"11000000"| "11000010" |"11000100"|"11000101"|"11000110"|"11000111" - |"11001000"| "11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" - |"11010000"| "11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" - |"11011000"| "11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" - |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111" - |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111" - |"11110000"|"11110001"|"11110010" |"11110100"|"11110101"|"11110110"|"11110111" - |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" => - null; -- NOP, undocumented - when "01110111"|"01111111" => - -- NOP, undocumented - null; --- 8 BIT LOAD GROUP - when "01010111" => - -- LD A,I - Special_LD <= "100"; - TStates <= "101"; - when "01011111" => - -- LD A,R - Special_LD <= "101"; - TStates <= "101"; - when "01000111" => - -- LD I,A - Special_LD <= "110"; - TStates <= "101"; - when "01001111" => - -- LD R,A - Special_LD <= "111"; - TStates <= "101"; --- 16 BIT LOAD GROUP - when "01001011"|"01011011"|"01101011"|"01111011" => - -- LD dd,(nn) - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - when 4 => - Read_To_Reg <= '1'; - if IR(5 downto 4) = "11" then - Set_BusA_To <= "1000"; - else - Set_BusA_To(2 downto 1) <= IR(5 downto 4); - Set_BusA_To(0) <= '1'; - end if; - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - when 5 => - Read_To_Reg <= '1'; - if IR(5 downto 4) = "11" then - Set_BusA_To <= "1001"; - else - Set_BusA_To(2 downto 1) <= IR(5 downto 4); - Set_BusA_To(0) <= '0'; - end if; - when others => null; - end case; - when "01000011"|"01010011"|"01100011"|"01110011" => - -- LD (nn),dd - MCycles <= "101"; - case to_integer(unsigned(MCycle)) is - when 2 => - Inc_PC <= '1'; - LDZ <= '1'; - when 3 => - Set_Addr_To <= aZI; - Inc_PC <= '1'; - LDW <= '1'; - if IR(5 downto 4) = "11" then - Set_BusB_To <= "1000"; - else - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; - Set_BusB_To(3) <= '0'; - end if; - when 4 => - Inc_WZ <= '1'; - Set_Addr_To <= aZI; - Write <= '1'; - if IR(5 downto 4) = "11" then - Set_BusB_To <= "1001"; - else - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '0'; - Set_BusB_To(3) <= '0'; - end if; - when 5 => - Write <= '1'; - when others => null; - end case; - when "10100000" | "10101000" | "10110000" | "10111000" => - -- LDI, LDD, LDIR, LDDR - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - IncDec_16 <= "1100"; -- BC - when 2 => - Set_BusB_To <= "0110"; - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "0000"; - Set_Addr_To <= aDE; - if IR(3) = '0' then - IncDec_16 <= "0110"; -- IX - else - IncDec_16 <= "1110"; - end if; - when 3 => - I_BT <= '1'; - TStates <= "101"; - Write <= '1'; - if IR(3) = '0' then - IncDec_16 <= "0101"; -- DE - else - IncDec_16 <= "1101"; - end if; - No_PC <= '1'; - when 4 => - NoRead <= '1'; - TStates <= "101"; - when others => null; - end case; - when "10100001" | "10101001" | "10110001" | "10111001" => - -- CPI, CPD, CPIR, CPDR - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - IncDec_16 <= "1100"; -- BC - when 2 => - Set_BusB_To <= "0110"; - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "0111"; - Save_ALU <= '1'; - PreserveC <= '1'; - if IR(3) = '0' then - IncDec_16 <= "0110"; - else - IncDec_16 <= "1110"; - end if; - No_PC <= '1'; - when 3 => - NoRead <= '1'; - I_BC <= '1'; - TStates <= "101"; - No_PC <= '1'; - when 4 => - NoRead <= '1'; - TStates <= "101"; - when others => null; - end case; - when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" => - -- NEG - Alu_OP <= "0010"; - Set_BusB_To <= "0111"; - Set_BusA_To <= "1010"; - Read_To_Acc <= '1'; - Save_ALU <= '1'; - when "01000110"|"01001110"|"01100110"|"01101110" => - -- IM 0 - IMode <= "00"; - when "01010110"|"01110110" => - -- IM 1 - IMode <= "01"; - when "01011110"|"01111110" => - -- IM 2 - IMode <= "10"; --- 16 bit arithmetic - when "01001010"|"01011010"|"01101010"|"01111010" => - -- ADC HL,ss - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - No_PC <= '1'; - when 2 => - NoRead <= '1'; - ALU_Op <= "0001"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "101"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; - when others => - Set_BusB_To <= "1000"; - end case; - TStates <= "100"; - SetWZ <= "11"; - No_PC <= '1'; - when 3 => - NoRead <= '1'; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0001"; - Set_BusA_To(2 downto 0) <= "100"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '0'; - when others => - Set_BusB_To <= "1001"; - end case; - when others => - end case; - when "01000010"|"01010010"|"01100010"|"01110010" => - -- SBC HL,ss - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - No_PC <= '1'; - when 2 => - NoRead <= '1'; - ALU_Op <= "0011"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "101"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - Set_BusB_To(0) <= '1'; - when others => - Set_BusB_To <= "1000"; - end case; - TStates <= "100"; - SetWZ <= "11"; - No_PC <= '1'; - when 3 => - NoRead <= '1'; - ALU_Op <= "0011"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - Set_BusA_To(2 downto 0) <= "100"; - case to_integer(unsigned(IR(5 downto 4))) is - when 0|1|2 => - Set_BusB_To(2 downto 1) <= IR(5 downto 4); - when others => - Set_BusB_To <= "1001"; - end case; - when others => - end case; - when "01101111" => - -- RLD -- Read in M2, not M3! fixed by Sorgelig - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Read_To_Reg <= '1'; - Set_BusB_To(2 downto 0) <= "110"; - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "1101"; - Save_ALU <= '1'; - No_PC <= '1'; - when 3 => - TStates <= "100"; - I_RLD <= '1'; - NoRead <= '1'; - Set_Addr_To <= aXY; - when 4 => - Write <= '1'; - when others => - end case; - when "01100111" => - -- RRD -- Read in M2, not M3! fixed by Sorgelig - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aXY; - when 2 => - Read_To_Reg <= '1'; - Set_BusB_To(2 downto 0) <= "110"; - Set_BusA_To(2 downto 0) <= "111"; - ALU_Op <= "1110"; - Save_ALU <= '1'; - No_PC <= '1'; - when 3 => - TStates <= "100"; - I_RRD <= '1'; - NoRead <= '1'; - Set_Addr_To <= aXY; - when 4 => - Write <= '1'; - when others => - end case; - when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" => - -- RETI/RETN - MCycles <= "011"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_TO <= aSP; - when 2 => - IncDec_16 <= "0111"; - Set_Addr_To <= aSP; - LDZ <= '1'; - when 3 => - Jump <= '1'; - IncDec_16 <= "0111"; - LDW <= '1'; - I_RETN <= '1'; - when others => null; - end case; - when "01000000"|"01001000"|"01010000"|"01011000"|"01100000"|"01101000"|"01110000"|"01111000" => - -- IN r,(C) - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - SetWZ <= "01"; - when 2 => - IORQ <= '1'; - if IR(5 downto 3) /= "110" then - Read_To_Reg <= '1'; - Set_BusA_To(2 downto 0) <= IR(5 downto 3); - end if; - I_INRC <= '1'; - when others => - end case; - when "01000001"|"01001001"|"01010001"|"01011001"|"01100001"|"01101001"|"01110001"|"01111001" => - -- OUT (C),r - -- OUT (C),0 - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - Set_Addr_To <= aBC; - SetWZ <= "01"; - Set_BusB_To(2 downto 0) <= IR(5 downto 3); - if IR(5 downto 3) = "110" then - Set_BusB_To(3) <= '1'; - end if; - when 2 => - Write <= '1'; - IORQ <= '1'; - when others => - end case; - when "10100010" | "10101010" | "10110010" | "10111010" => - -- INI, IND, INIR, INDR - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - Set_Addr_To <= aBC; - Set_BusB_To <= "1010"; - Set_BusA_To <= "0000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0010"; - SetWZ <= "11"; - IncDec_16(3) <= IR(3); - when 2 => - IORQ <= '1'; - Set_BusB_To <= "0110"; - Set_Addr_To <= aXY; - when 3 => - if IR(3) = '0' then - IncDec_16 <= "0110"; - else - IncDec_16 <= "1110"; - end if; - Write <= '1'; - I_BTR <= '1'; - when 4 => - NoRead <= '1'; - TStates <= "101"; - when others => null; - end case; - when "10100011" | "10101011" | "10110011" | "10111011" => - -- OUTI, OUTD, OTIR, OTDR - MCycles <= "100"; - case to_integer(unsigned(MCycle)) is - when 1 => - TStates <= "101"; - Set_Addr_To <= aXY; - Set_BusB_To <= "1010"; - Set_BusA_To <= "0000"; - Read_To_Reg <= '1'; - Save_ALU <= '1'; - ALU_Op <= "0010"; - when 2 => - Set_BusB_To <= "0110"; - Set_Addr_To <= aBC; - SetWZ <= "11"; - IncDec_16(3) <= IR(3); - when 3 => - if IR(3) = '0' then - IncDec_16 <= "0110"; - else - IncDec_16 <= "1110"; - end if; - IORQ <= '1'; - Write <= '1'; - I_BTR <= '1'; - when 4 => - NoRead <= '1'; - TStates <= "101"; - when others => null; - end case; - when "11000001"|"11001001"|"11010001"|"11011001" => - --R800 MULUB - if R800_mode = '1' then - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - NoRead <= '1'; - I_MULUB <= '1'; - Set_BusB_To(2 downto 0) <= IR(5 downto 3); - Set_BusB_To(3) <= '0'; - when 2 => - NoRead <= '1'; - I_MULU <= '1'; - Set_BusA_To(2 downto 0) <= "100"; - when others => null; - end case; - end if; - when "11000011"|"11110011" => - --R800 MULUW - if R800_mode = '1' then - MCycles <= "010"; - case to_integer(unsigned(MCycle)) is - when 1 => - NoRead <= '1'; - if DPAIR = "11" then - Set_BusB_To(3 downto 0) <= "1000"; - else - Set_BusB_To(2 downto 1) <= DPAIR; - Set_BusB_To(0) <= '0'; - Set_BusB_To(3) <= '0'; - end if; - Set_BusA_To(2 downto 0) <= "100"; - when 2 => - TStates <= "101"; - NoRead <= '1'; - I_MULU <= '1'; - Set_BusA_To(2 downto 0) <= "100"; - when others => null; - end case; - end if; - end case; - - end case; - - if Mode = 1 then - if MCycle = "001" then --- TStates <= "100"; - else - TStates <= "011"; - end if; - end if; - - if Mode = 3 then - if MCycle = "001" then --- TStates <= "100"; - else - TStates <= "100"; - end if; - end if; - - if Mode < 2 then - if MCycle = "110" then - Inc_PC <= '1'; - if Mode = 1 then - Set_Addr_To <= aXY; - TStates <= "100"; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusB_To(3) <= '0'; - end if; - if IRB = "00110110" or IRB = "11001011" then - Set_Addr_To <= aNone; - end if; - if not (IRB = "00110110" or ISet = "01") then - No_PC <= '1'; - end if; - end if; - if MCycle = "111" then - if Mode = 0 then - TStates <= "101"; - end if; - if ISet /= "01" then - Set_Addr_To <= aXY; - end if; - Set_BusB_To(2 downto 0) <= SSS; - Set_BusB_To(3) <= '0'; - if IRB = "00110110" or ISet = "01" then - -- LD (HL),n - Inc_PC <= '1'; - else - NoRead <= '1'; - end if; - end if; - end if; - - end process; - -end; +-------------------------------------------------------------------------------- +-- **** +-- T80(c) core. Attempt to finish all undocumented features and provide +-- accurate timings. +-- Version 350. +-- Copyright (c) 2018 Sorgelig +-- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr +-- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as +-- correct implementation is still unclear. +-- +-- **** +-- T80(b) core. In an effort to merge and maintain bug fixes .... +-- +-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010 +-- Ver 300 started tidyup +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- Z80 compatible microprocessor core +-- +-- Version : 0250 +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- 0211 : Fixed IM 1 +-- 0214 : Fixed mostly flags, only the block instructions now fail the zex regression test +-- 0235 : Added IM 2 fix by Mike Johnson +-- 0238 : Added NoRead signal +-- 0238b: Fixed instruction timing for POP and DJNZ +-- 0240 : Added (IX/IY+d) states, removed op-codes from mode 2 and added all remaining mode 3 op-codes +-- 0240mj1 fix for HL inc/dec for INI, IND, INIR, INDR, OUTI, OUTD, OTIR, OTDR +-- 0242 : Fixed I/O instruction timing, cleanup +-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15 +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80_MCode is + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + IR : in std_logic_vector(7 downto 0); + ISet : in std_logic_vector(1 downto 0); + MCycle : in std_logic_vector(2 downto 0); + F : in std_logic_vector(7 downto 0); + NMICycle : in std_logic; + IntCycle : in std_logic; + XY_State : in std_logic_vector(1 downto 0); + MCycles : out std_logic_vector(2 downto 0); + TStates : out std_logic_vector(2 downto 0); + Prefix : out std_logic_vector(1 downto 0); -- None,CB,ED,DD/FD + Inc_PC : out std_logic; + Inc_WZ : out std_logic; + IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc + Read_To_Reg : out std_logic; + Read_To_Acc : out std_logic; + Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F + Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 + ALU_Op : out std_logic_vector(3 downto 0); + -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None + Save_ALU : out std_logic; + Rot_Akku : out std_logic; + PreserveC : out std_logic; + Arith16 : out std_logic; + Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI + IORQ : out std_logic; + Jump : out std_logic; + JumpE : out std_logic; + JumpXY : out std_logic; + Call : out std_logic; + RstP : out std_logic; + LDZ : out std_logic; + LDW : out std_logic; + LDSPHL : out std_logic; + LDHLSP : out std_logic; + ADDSPdd : out std_logic; + Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None + ExchangeDH : out std_logic; + ExchangeRp : out std_logic; + ExchangeAF : out std_logic; + ExchangeRS : out std_logic; + ExchangeWH : out std_logic; + I_DJNZ : out std_logic; + I_CPL : out std_logic; + I_CCF : out std_logic; + I_SCF : out std_logic; + I_RETN : out std_logic; + I_BT : out std_logic; + I_BC : out std_logic; + I_BTR : out std_logic; + I_RLD : out std_logic; + I_RRD : out std_logic; + I_INRC : out std_logic; + I_MULUB : out std_logic; + I_MULU : out std_logic; + SetWZ : out std_logic_vector(1 downto 0); + SetDI : out std_logic; + SetEI : out std_logic; + IMode : out std_logic_vector(1 downto 0); + Halt : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + R800_mode : in std_logic; + No_PC : out std_logic; + XYbit_undoc : out std_logic + ); +end T80_MCode; + +architecture rtl of T80_MCode is + + function is_cc_true( + F : std_logic_vector(7 downto 0); + cc : bit_vector(2 downto 0) + ) return boolean is + begin + if Mode = 3 then + case cc is + when "000" => return F(Flag_Z) = '0'; -- NZ + when "001" => return F(Flag_Z) = '1'; -- Z + when "010" => return F(Flag_C) = '0'; -- NC + when "011" => return F(Flag_C) = '1'; -- C + when "100" => return false; + when "101" => return false; + when "110" => return false; + when "111" => return false; + end case; + else + case cc is + when "000" => return F(Flag_Z) = '0'; -- NZ + when "001" => return F(Flag_Z) = '1'; -- Z + when "010" => return F(Flag_C) = '0'; -- NC + when "011" => return F(Flag_C) = '1'; -- C + when "100" => return F(Flag_P) = '0'; -- PO + when "101" => return F(Flag_P) = '1'; -- PE + when "110" => return F(Flag_S) = '0'; -- P + when "111" => return F(Flag_S) = '1'; -- M + end case; + end if; + end; + +begin + + process (IR, ISet, MCycle, F, NMICycle, IntCycle, XY_State, R800_mode) + variable DDD : std_logic_vector(2 downto 0); + variable SSS : std_logic_vector(2 downto 0); + variable DPair : std_logic_vector(1 downto 0); + variable IRB : bit_vector(7 downto 0); + begin + DDD := IR(5 downto 3); + SSS := IR(2 downto 0); + DPair := IR(5 downto 4); + IRB := to_bitvector(IR); + + MCycles <= "001"; + if MCycle = "001" then + TStates <= "100"; + else + TStates <= "011"; + end if; + Prefix <= "00"; + Inc_PC <= '0'; + Inc_WZ <= '0'; + IncDec_16 <= "0000"; + Read_To_Acc <= '0'; + Read_To_Reg <= '0'; + Set_BusB_To <= "0000"; + Set_BusA_To <= "0000"; + ALU_Op <= "0" & IR(5 downto 3); + Save_ALU <= '0'; + Rot_Akku <= '0'; + PreserveC <= '0'; + Arith16 <= '0'; + IORQ <= '0'; + Set_Addr_To <= aNone; + Jump <= '0'; + JumpE <= '0'; + JumpXY <= '0'; + Call <= '0'; + RstP <= '0'; + LDZ <= '0'; + LDW <= '0'; + LDSPHL <= '0'; + LDHLSP <= '0'; + ADDSPdd <= '0'; + Special_LD <= "000"; + ExchangeDH <= '0'; + ExchangeRp <= '0'; + ExchangeAF <= '0'; + ExchangeRS <= '0'; + ExchangeWH <= '0'; + I_DJNZ <= '0'; + I_CPL <= '0'; + I_CCF <= '0'; + I_SCF <= '0'; + I_RETN <= '0'; + I_BT <= '0'; + I_BC <= '0'; + I_BTR <= '0'; + I_RLD <= '0'; + I_RRD <= '0'; + I_INRC <= '0'; + I_MULUB <= '0'; + I_MULU <= '0'; + SetDI <= '0'; + SetEI <= '0'; + IMode <= "11"; + Halt <= '0'; + NoRead <= '0'; + Write <= '0'; + No_PC <= '0'; + XYbit_undoc <= '0'; + SetWZ <= "00"; + + case ISet is + when "00" => + +------------------------------------------------------------------------------ +-- +-- Unprefixed instructions +-- +------------------------------------------------------------------------------ + + case IRB is +-- 8 BIT LOAD GROUP + when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" + |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" + |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" + |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" + |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" + |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" + |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => + -- LD r,r' + Set_BusB_To(2 downto 0) <= SSS; + ExchangeRp <= '1'; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when "00000110"|"00001110"|"00010110"|"00011110"|"00100110"|"00101110"|"00111110" => + -- LD r,n + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when others => null; + end case; + when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01111110" => + -- LD r,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + when others => null; + end case; + when "01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" => + -- LD (HL),r + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00110110" => + -- LD (HL),n + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aXY; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + when 3 => + Write <= '1'; + when others => null; + end case; + when "00001010" => + -- LD A,(BC) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + when 2 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "00011010" => + -- LD A,(DE) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aDE; + when 2 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "00111010" => + if Mode = 3 then + -- LDD A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Acc <= '1'; + IncDec_16 <= "1110"; + when others => null; + end case; + else + -- LD A,(nn) + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + when 4 => + Read_To_Acc <= '1'; + when others => null; + end case; + end if; + when "00000010" => + -- LD (BC),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To <= "0111"; + SetWZ <= "10"; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00010010" => + -- LD (DE),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aDE; + Set_BusB_To <= "0111"; + SetWZ <= "10"; + when 2 => + Write <= '1'; + when others => null; + end case; + when "00110010" => + if Mode = 3 then + -- LDD (HL),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IncDec_16 <= "1110"; + when others => null; + end case; + else + -- LD (nn),A + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + SetWZ <= "10"; + Inc_PC <= '1'; + Set_BusB_To <= "0111"; + when 4 => + Write <= '1'; + when others => null; + end case; + end if; + +-- 16 BIT LOAD GROUP + when "00000001"|"00010001"|"00100001"|"00110001" => + -- LD dd,nn + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1000"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '1'; + end if; + when 3 => + Inc_PC <= '1'; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1001"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + when "00101010" => + if Mode = 3 then + -- LDI A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Acc <= '1'; + IncDec_16 <= "0110"; + when others => null; + end case; + else + -- LD HL,(nn) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Set_BusA_To(2 downto 0) <= "101"; -- L + Read_To_Reg <= '1'; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Set_BusA_To(2 downto 0) <= "100"; -- H + Read_To_Reg <= '1'; + when others => null; + end case; + end if; + when "00100010" => + if Mode = 3 then + -- LDI (HL),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + Set_BusB_To <= "0111"; + when 2 => + Write <= '1'; + IncDec_16 <= "0110"; + when others => null; + end case; + else + -- LD (nn),HL + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + Set_BusB_To <= "0101"; -- L + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + Set_BusB_To <= "0100"; -- H + when 5 => + Write <= '1'; + when others => null; + end case; + end if; + when "11111001" => + -- LD SP,HL + if Mode = 3 then + MCycles <= "010"; + if MCycle = "010" then + LDSPHL <= '1'; + end if; + else + TStates <= "110"; + LDSPHL <= '1'; + end if; + when "11000101"|"11010101"|"11100101"|"11110101" => + -- PUSH qq + if Mode = 3 then + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "0111"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 3 => + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "1011"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + Write <= '1'; + when 4 => + Write <= '1'; + when others => null; + end case; + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "0111"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 2 => + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + if DPAIR = "11" then + Set_BusB_To <= "1011"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + Write <= '1'; + when 3 => + Write <= '1'; + when others => null; + end case; + end if; + when "11000001"|"11010001"|"11100001"|"11110001" => + -- POP qq + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "1011"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '1'; + end if; + when 3 => + IncDec_16 <= "0111"; + Read_To_Reg <= '1'; + if DPAIR = "11" then + Set_BusA_To(3 downto 0) <= "0111"; + else + Set_BusA_To(2 downto 1) <= DPAIR; + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + +-- EXCHANGE, BLOCK TRANSFER AND SEARCH GROUP + when "11101011" => + if Mode /= 3 then + -- EX DE,HL + ExchangeDH <= '1'; + end if; + when "00001000" => + if Mode = 3 then + -- LD (nn),SP + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + Set_BusB_To <= "1000"; + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + Set_BusB_To <= "1001"; + when 5 => + Write <= '1'; + when others => null; + end case; + elsif Mode < 2 then + -- EX AF,AF' + ExchangeAF <= '1'; + end if; + when "11011001" => + if Mode = 3 then + -- RETI + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + --I_RETN <= '1'; + SetEI <= '1'; + when others => null; + end case; + elsif Mode < 2 then + -- EXX + ExchangeRS <= '1'; + end if; + when "11100011" => + if Mode /= 3 then + -- EX (SP),HL + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aSP; + when 2 => + Set_Addr_To <= aSP; + LDZ <= '1'; + IncDec_16 <= "0111"; -- SP <= SP+1 + when 3 => + TStates <= "100"; + Set_BusB_To <= "0100"; + Set_Addr_To <= aSP; + LDW <= '1'; + when 4 => + Set_BusB_To <= "0101"; + Write <= '1'; + IncDec_16 <= "1111"; -- SP <= SP-1 + Set_Addr_To <= aSP; + when 5 => + ExchangeWH <= '1'; -- save WZ to HL + TStates <= "101"; + Write <= '1'; + when others => null; + end case; + end if; + +-- 8 BIT ARITHMETIC AND LOGICAL GROUP + when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" + |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" + |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" + |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" + |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => + -- ADD A,r + -- ADC A,r + -- SUB A,r + -- SBC A,r + -- AND A,r + -- OR A,r + -- XOR A,r + -- CP A,r + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => + -- ADD A,(HL) + -- ADC A,(HL) + -- SUB A,(HL) + -- SBC A,(HL) + -- AND A,(HL) + -- OR A,(HL) + -- XOR A,(HL) + -- CP A,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + when others => null; + end case; + when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => + -- ADD A,n + -- ADC A,n + -- SUB A,n + -- SBC A,n + -- AND A,n + -- OR A,n + -- XOR A,n + -- CP A,n + MCycles <= "010"; + if MCycle = "010" then + Inc_PC <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusA_To(2 downto 0) <= "111"; + end if; + when "00000100"|"00001100"|"00010100"|"00011100"|"00100100"|"00101100"|"00111100" => + -- INC r + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0000"; + when "00110100" => + -- INC (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + TStates <= "100"; + Set_Addr_To <= aXY; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0000"; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + when 3 => + Write <= '1'; + when others => null; + end case; + when "00000101"|"00001101"|"00010101"|"00011101"|"00100101"|"00101101"|"00111101" => + -- DEC r + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + ALU_Op <= "0010"; + when "00110101" => + -- DEC (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + TStates <= "100"; + Set_Addr_To <= aXY; + ALU_Op <= "0010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + PreserveC <= '1'; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= DDD; + when 3 => + Write <= '1'; + when others => null; + end case; + +-- GENERAL PURPOSE ARITHMETIC AND CPU CONTROL GROUPS + when "00100111" => + -- DAA + Set_BusA_To(2 downto 0) <= "111"; + Read_To_Reg <= '1'; + ALU_Op <= "1100"; + Save_ALU <= '1'; + when "00101111" => + -- CPL + I_CPL <= '1'; + when "00111111" => + -- CCF + I_CCF <= '1'; + when "00110111" => + -- SCF + I_SCF <= '1'; + when "00000000" => + if NMICycle = '1' then + -- NMI + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + Write <= '1'; + when others => null; + end case; + elsif IntCycle = '1' then + -- INT (IM 2) + if Mode = 3 then + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "110"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + Write <= '1'; + when 3 => -- GB: interrupt is acknowledged on MCycle 3 + LDZ <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 4 => + Write <= '1'; + when others => null; + end case; + else + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + --TStates <= "100"; + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + --TStates <= "100"; + Write <= '1'; + when 4 => + Inc_PC <= '1'; + LDZ <= '1'; + when 5 => + Jump <= '1'; + when others => null; + end case; + end if; + else + -- NOP + end if; + when "01110110" => + -- HALT + Halt <= '1'; + when "11110011" => + -- DI + SetDI <= '1'; + when "11111011" => + -- EI + SetEI <= '1'; + +-- 16 BIT ARITHMETIC GROUP + when "00001001"|"00011001"|"00101001"|"00111001" => + -- ADD HL,ss + if Mode = 3 then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + NoRead <= '1'; + ALU_Op <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + Arith16 <= '1'; + SetWZ <= "11"; + when 2 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + Arith16 <= '1'; + when others => + end case; + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + No_PC <= '1'; + when 2 => + NoRead <= '1'; + ALU_Op <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + Arith16 <= '1'; + SetWZ <= "11"; + No_PC <= '1'; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + Arith16 <= '1'; + when others => + end case; + end if; + when "00000011"|"00010011"|"00100011"|"00110011" => + -- INC ss + if Mode = 3 then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 2 => + IncDec_16(3 downto 2) <= "01"; + IncDec_16(1 downto 0) <= DPair; + when others => + end case; + else + TStates <= "110"; + IncDec_16(3 downto 2) <= "01"; + IncDec_16(1 downto 0) <= DPair; + end if; + when "00001011"|"00011011"|"00101011"|"00111011" => + -- DEC ss + if Mode = 3 then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 2 => + IncDec_16(3 downto 2) <= "11"; + IncDec_16(1 downto 0) <= DPair; + when others => + end case; + else + TStates <= "110"; + IncDec_16(3 downto 2) <= "11"; + IncDec_16(1 downto 0) <= DPair; + end if; + +-- ROTATE AND SHIFT GROUP + when "00000111" + -- RLCA + |"00010111" + -- RLA + |"00001111" + -- RRCA + |"00011111" => + -- RRA + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Rot_Akku <= '1'; + Save_ALU <= '1'; + +-- JUMP GROUP + when "11000011" => + -- JP nn + if Mode = 3 then + MCycles <= "100"; + else + MCycles <= "011"; + end if; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + Jump <= '1'; + if Mode /= 3 then + LDW <= '1'; + end if; + when others => null; + end case; + when "11000010"|"11001010"|"11010010"|"11011010"|"11100010"|"11101010"|"11110010"|"11111010" => + if IR(5) = '1' and Mode = 3 then + case IRB(4 downto 3) is + when "00" => + -- LD ($FF00+C),A + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + Set_BusB_To <= "0111"; + IORQ <= '1'; --TH must be earlier to be stable when address is generated + when 2 => + Write <= '1'; + when others => + end case; + when "01" => + -- LD (nn),A + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + Set_BusB_To <= "0111"; + when 4 => + Write <= '1'; + when others => null; + end case; + when "10" => + -- LD A,($FF00+C) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + IORQ <= '1'; --TH must be earlier to be stable when address is generated + when 2 => + Read_To_Acc <= '1'; + when others => + end case; + when "11" => + -- LD A,(nn) + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + when 4 => + Read_To_Acc <= '1'; + when others => null; + end case; + end case; + else + -- JP cc,nn + if Mode = 3 then + MCycles <= "100"; + else + MCycles <= "011"; + end if; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + if Mode /= 3 then + LDW <= '1'; + end if; + Inc_PC <= '1'; + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Jump <= '1'; + elsif Mode = 3 then + MCycles <= "011"; + end if; + when others => null; + end case; + end if; + when "00011000" => + if Mode /= 2 then + -- JR e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + No_PC <= '1'; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00111000" => + if Mode /= 2 then + -- JR C,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_C) = '0' then + MCycles <= "010"; + else + No_PC <= '1'; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00110000" => + if Mode /= 2 then + -- JR NC,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_C) = '1' then + MCycles <= "010"; + else + No_PC <= '1'; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00101000" => + if Mode /= 2 then + -- JR Z,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_Z) = '0' then + MCycles <= "010"; + else + No_PC <= '1'; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "00100000" => + if Mode /= 2 then + -- JR NZ,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + if F(Flag_Z) = '1' then + MCycles <= "010"; + else + No_PC <= '1'; + end if; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + when "11101001" => + -- JP (HL) + JumpXY <= '1'; + when "00010000" => + if Mode = 3 then -- STOP and skip next byte + MCycles <= "010"; + I_DJNZ <= '1'; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + when others => null; + end case; + elsif Mode < 2 then + -- DJNZ,e + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + I_DJNZ <= '1'; + Set_BusB_To <= "1010"; + Set_BusA_To(2 downto 0) <= "000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + I_DJNZ <= '1'; + Inc_PC <= '1'; + No_PC <= '1'; + when 3 => + NoRead <= '1'; + JumpE <= '1'; + TStates <= "101"; + when others => null; + end case; + end if; + +-- CALL AND RETURN GROUP + when "11001101" => + -- CALL nn + if Mode = 3 then + MCycles <= "110"; + else + MCycles <= "101"; + end if; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + IncDec_16 <= "1111"; + Inc_PC <= '1'; + TStates <= "100"; + Set_Addr_To <= aSP; + LDW <= '1'; + Set_BusB_To <= "1101"; + when 4 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 5 => + Write <= '1'; + Call <= '1'; + when others => null; + end case; + when "11000100"|"11001100"|"11010100"|"11011100"|"11100100"|"11101100"|"11110100"|"11111100" => + if IR(5) = '0' or Mode /= 3 then + -- CALL cc,nn + if Mode = 3 then + MCycles <= "110"; + else + MCycles <= "101"; + end if; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Inc_PC <= '1'; + LDW <= '1'; + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + IncDec_16 <= "1111"; + Set_Addr_TO <= aSP; + TStates <= "100"; + Set_BusB_To <= "1101"; + else + MCycles <= "011"; + end if; + when 4 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 5 => + Write <= '1'; + Call <= '1'; + when others => null; + end case; + end if; + when "11001001" => + -- RET + if Mode = 3 then + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + Set_Addr_TO <= aSP; + when 3 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 4 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + --TStates <= "101"; + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + end if; + when "11000000"|"11001000"|"11010000"|"11011000"|"11100000"|"11101000"|"11110000"|"11111000" => + if IR(5) = '1' and Mode = 3 then + case IRB(4 downto 3) is + when "00" => + -- LD ($FF00+nn),A + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + Set_BusB_To <= "0111"; + when 3 => + Write <= '1'; + when others => null; + end case; + when "01" => + -- ADD SP,n + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 3 => + Inc_PC <= '1'; + ADDSPdd <= '1'; + when others => + end case; + when "10" => + -- LD A,($FF00+nn) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + when 3 => + Read_To_Acc <= '1'; + when others => null; + end case; + when "11" => + -- LD HL,SP+n + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Inc_PC <= '1'; + when 2 => + LDHLSP <= '1'; + Inc_PC <= '1'; + when 3 => + LDHLSP <= '1'; + when others => null; + end case; + end case; + else + -- RET cc + if Mode = 3 then + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Set_Addr_TO <= aSP; + else + MCycles <= "010"; + end if; + TStates <= "101"; + when 3 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 4 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + if is_cc_true(F, to_bitvector(IR(5 downto 3))) then + Set_Addr_TO <= aSP; + else + MCycles <= "001"; + end if; + TStates <= "101"; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + when others => null; + end case; + end if; + end if; + when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" => + -- RST p + if Mode = 3 then + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 2 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 3 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 4 => + Write <= '1'; + RstP <= '1'; + when others => null; + end case; + else + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1101"; + when 2 => + Write <= '1'; + IncDec_16 <= "1111"; + Set_Addr_To <= aSP; + Set_BusB_To <= "1100"; + when 3 => + Write <= '1'; + RstP <= '1'; + when others => null; + end case; + end if; + +-- INPUT AND OUTPUT GROUP + when "11011011" => + if Mode /= 3 then + -- IN A,(n) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + when 3 => + Read_To_Acc <= '1'; + IORQ <= '1'; + when others => null; + end case; + end if; + when "11010011" => + if Mode /= 3 then + -- OUT (n),A + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + Set_Addr_To <= aIOA; + Set_BusB_To <= "0111"; + when 3 => + Write <= '1'; + IORQ <= '1'; + when others => null; + end case; + end if; + +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +-- MULTIBYTE INSTRUCTIONS +------------------------------------------------------------------------------ +------------------------------------------------------------------------------ + + when "11001011" => + if Mode /= 2 then + Prefix <= "01"; + end if; + + when "11101101" => + if Mode < 2 then + Prefix <= "10"; + end if; + + when "11011101"|"11111101" => + if Mode < 2 then + Prefix <= "11"; + end if; + + end case; + + when "01" => + +------------------------------------------------------------------------------ +-- +-- CB prefixed instructions +-- +------------------------------------------------------------------------------ + + Set_BusA_To(2 downto 0) <= IR(2 downto 0); + Set_BusB_To(2 downto 0) <= IR(2 downto 0); + + case IRB is + when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000111" + |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010111" + |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001111" + |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011111" + |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100111" + |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101111" + |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110111" + |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111111" => + -- RLC r + -- RL r + -- RRC r + -- RR r + -- SLA r + -- SRA r + -- SRL r + -- SLL r (Undocumented) / SWAP r + if XY_State="00" then + if MCycle = "001" then + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + end if; + else + -- R/S (IX+d),Reg, undocumented + MCycles <= "011"; + XYbit_undoc <= '1'; + case to_integer(unsigned(MCycle)) is + when 1 | 7=> + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => null; + end case; + end if; + + when "00000110"|"00010110"|"00001110"|"00011110"|"00101110"|"00111110"|"00100110"|"00110110" => + -- RLC (HL) + -- RL (HL) + -- RRC (HL) + -- RR (HL) + -- SRA (HL) + -- SRL (HL) + -- SLA (HL) + -- SLL (HL) (Undocumented) / SWAP (HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => + end case; + when "01000000"|"01000001"|"01000010"|"01000011"|"01000100"|"01000101"|"01000111" + |"01001000"|"01001001"|"01001010"|"01001011"|"01001100"|"01001101"|"01001111" + |"01010000"|"01010001"|"01010010"|"01010011"|"01010100"|"01010101"|"01010111" + |"01011000"|"01011001"|"01011010"|"01011011"|"01011100"|"01011101"|"01011111" + |"01100000"|"01100001"|"01100010"|"01100011"|"01100100"|"01100101"|"01100111" + |"01101000"|"01101001"|"01101010"|"01101011"|"01101100"|"01101101"|"01101111" + |"01110000"|"01110001"|"01110010"|"01110011"|"01110100"|"01110101"|"01110111" + |"01111000"|"01111001"|"01111010"|"01111011"|"01111100"|"01111101"|"01111111" => + -- BIT b,r + if XY_State="00" then + if MCycle = "001" then + Set_BusB_To(2 downto 0) <= IR(2 downto 0); + ALU_Op <= "1001"; + end if; + else + -- BIT b,(IX+d), undocumented + MCycles <= "010"; + XYbit_undoc <= '1'; + case to_integer(unsigned(MCycle)) is + when 1 | 7=> + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1001"; + TStates <= "100"; + when others => null; + end case; + end if; + + when "01000110"|"01001110"|"01010110"|"01011110"|"01100110"|"01101110"|"01110110"|"01111110" => + -- BIT b,(HL) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1001"; + TStates <= "100"; + when others => null; + end case; + when "11000000"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000111" + |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001111" + |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010111" + |"11011000"|"11011001"|"11011010"|"11011011"|"11011100"|"11011101"|"11011111" + |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100111" + |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101111" + |"11110000"|"11110001"|"11110010"|"11110011"|"11110100"|"11110101"|"11110111" + |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111111" => + -- SET b,r + if XY_State="00" then + if MCycle = "001" then + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + end if; + else + -- SET b,(IX+d),Reg, undocumented + MCycles <= "011"; + XYbit_undoc <= '1'; + case to_integer(unsigned(MCycle)) is + when 1 | 7=> + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => null; + end case; + end if; + + when "11000110"|"11001110"|"11010110"|"11011110"|"11100110"|"11101110"|"11110110"|"11111110" => + -- SET b,(HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1010"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => null; + end case; + when "10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011111" + |"10100000"|"10100001"|"10100010"|"10100011"|"10100100"|"10100101"|"10100111" + |"10101000"|"10101001"|"10101010"|"10101011"|"10101100"|"10101101"|"10101111" + |"10110000"|"10110001"|"10110010"|"10110011"|"10110100"|"10110101"|"10110111" + |"10111000"|"10111001"|"10111010"|"10111011"|"10111100"|"10111101"|"10111111" => + -- RES b,r + if XY_State="00" then + if MCycle = "001" then + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + end if; + else + -- RES b,(IX+d),Reg, undocumented + MCycles <= "011"; + XYbit_undoc <= '1'; + case to_integer(unsigned(MCycle)) is + when 1 | 7=> + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => null; + end case; + end if; + + when "10000110"|"10001110"|"10010110"|"10011110"|"10100110"|"10101110"|"10110110"|"10111110" => + -- RES b,(HL) + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 | 7 => + Set_Addr_To <= aXY; + when 2 => + ALU_Op <= "1011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_Addr_To <= aXY; + TStates <= "100"; + when 3 => + Write <= '1'; + when others => null; + end case; + end case; + + when others => + +------------------------------------------------------------------------------ +-- +-- ED prefixed instructions +-- +------------------------------------------------------------------------------ + + case IRB is + when "00000000"|"00000001"|"00000010"|"00000011"|"00000100"|"00000101"|"00000110"|"00000111" + |"00001000"|"00001001"|"00001010"|"00001011"|"00001100"|"00001101"|"00001110"|"00001111" + |"00010000"|"00010001"|"00010010"|"00010011"|"00010100"|"00010101"|"00010110"|"00010111" + |"00011000"|"00011001"|"00011010"|"00011011"|"00011100"|"00011101"|"00011110"|"00011111" + |"00100000"|"00100001"|"00100010"|"00100011"|"00100100"|"00100101"|"00100110"|"00100111" + |"00101000"|"00101001"|"00101010"|"00101011"|"00101100"|"00101101"|"00101110"|"00101111" + |"00110000"|"00110001"|"00110010"|"00110011"|"00110100"|"00110101"|"00110110"|"00110111" + |"00111000"|"00111001"|"00111010"|"00111011"|"00111100"|"00111101"|"00111110"|"00111111" + + + |"10000000"|"10000001"|"10000010"|"10000011"|"10000100"|"10000101"|"10000110"|"10000111" + |"10001000"|"10001001"|"10001010"|"10001011"|"10001100"|"10001101"|"10001110"|"10001111" + |"10010000"|"10010001"|"10010010"|"10010011"|"10010100"|"10010101"|"10010110"|"10010111" + |"10011000"|"10011001"|"10011010"|"10011011"|"10011100"|"10011101"|"10011110"|"10011111" + | "10100100"|"10100101"|"10100110"|"10100111" + | "10101100"|"10101101"|"10101110"|"10101111" + | "10110100"|"10110101"|"10110110"|"10110111" + | "10111100"|"10111101"|"10111110"|"10111111" + |"11000000"| "11000010" |"11000100"|"11000101"|"11000110"|"11000111" + |"11001000"| "11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111" + |"11010000"| "11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111" + |"11011000"| "11011010"|"11011011"|"11011100"|"11011101"|"11011110"|"11011111" + |"11100000"|"11100001"|"11100010"|"11100011"|"11100100"|"11100101"|"11100110"|"11100111" + |"11101000"|"11101001"|"11101010"|"11101011"|"11101100"|"11101101"|"11101110"|"11101111" + |"11110000"|"11110001"|"11110010" |"11110100"|"11110101"|"11110110"|"11110111" + |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" => + null; -- NOP, undocumented + when "01110111"|"01111111" => + -- NOP, undocumented + null; +-- 8 BIT LOAD GROUP + when "01010111" => + -- LD A,I + Special_LD <= "100"; + TStates <= "101"; + when "01011111" => + -- LD A,R + Special_LD <= "101"; + TStates <= "101"; + when "01000111" => + -- LD I,A + Special_LD <= "110"; + TStates <= "101"; + when "01001111" => + -- LD R,A + Special_LD <= "111"; + TStates <= "101"; +-- 16 BIT LOAD GROUP + when "01001011"|"01011011"|"01101011"|"01111011" => + -- LD dd,(nn) + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + when 4 => + Read_To_Reg <= '1'; + if IR(5 downto 4) = "11" then + Set_BusA_To <= "1000"; + else + Set_BusA_To(2 downto 1) <= IR(5 downto 4); + Set_BusA_To(0) <= '1'; + end if; + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + when 5 => + Read_To_Reg <= '1'; + if IR(5 downto 4) = "11" then + Set_BusA_To <= "1001"; + else + Set_BusA_To(2 downto 1) <= IR(5 downto 4); + Set_BusA_To(0) <= '0'; + end if; + when others => null; + end case; + when "01000011"|"01010011"|"01100011"|"01110011" => + -- LD (nn),dd + MCycles <= "101"; + case to_integer(unsigned(MCycle)) is + when 2 => + Inc_PC <= '1'; + LDZ <= '1'; + when 3 => + Set_Addr_To <= aZI; + Inc_PC <= '1'; + LDW <= '1'; + if IR(5 downto 4) = "11" then + Set_BusB_To <= "1000"; + else + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + Set_BusB_To(3) <= '0'; + end if; + when 4 => + Inc_WZ <= '1'; + Set_Addr_To <= aZI; + Write <= '1'; + if IR(5 downto 4) = "11" then + Set_BusB_To <= "1001"; + else + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + when 5 => + Write <= '1'; + when others => null; + end case; + when "10100000" | "10101000" | "10110000" | "10111000" => + -- LDI, LDD, LDIR, LDDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + IncDec_16 <= "1100"; -- BC + when 2 => + Set_BusB_To <= "0110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "0000"; + Set_Addr_To <= aDE; + if IR(3) = '0' then + IncDec_16 <= "0110"; -- IX + else + IncDec_16 <= "1110"; + end if; + when 3 => + I_BT <= '1'; + TStates <= "101"; + Write <= '1'; + if IR(3) = '0' then + IncDec_16 <= "0101"; -- DE + else + IncDec_16 <= "1101"; + end if; + No_PC <= '1'; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "10100001" | "10101001" | "10110001" | "10111001" => + -- CPI, CPD, CPIR, CPDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + IncDec_16 <= "1100"; -- BC + when 2 => + Set_BusB_To <= "0110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "0111"; + Save_ALU <= '1'; + PreserveC <= '1'; + if IR(3) = '0' then + IncDec_16 <= "0110"; + else + IncDec_16 <= "1110"; + end if; + No_PC <= '1'; + when 3 => + NoRead <= '1'; + I_BC <= '1'; + TStates <= "101"; + No_PC <= '1'; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "01000100"|"01001100"|"01010100"|"01011100"|"01100100"|"01101100"|"01110100"|"01111100" => + -- NEG + Alu_OP <= "0010"; + Set_BusB_To <= "0111"; + Set_BusA_To <= "1010"; + Read_To_Acc <= '1'; + Save_ALU <= '1'; + when "01000110"|"01001110"|"01100110"|"01101110" => + -- IM 0 + IMode <= "00"; + when "01010110"|"01110110" => + -- IM 1 + IMode <= "01"; + when "01011110"|"01111110" => + -- IM 2 + IMode <= "10"; +-- 16 bit arithmetic + when "01001010"|"01011010"|"01101010"|"01111010" => + -- ADC HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + No_PC <= '1'; + when 2 => + NoRead <= '1'; + ALU_Op <= "0001"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + SetWZ <= "11"; + No_PC <= '1'; + when 3 => + NoRead <= '1'; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0001"; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '0'; + when others => + Set_BusB_To <= "1001"; + end case; + when others => + end case; + when "01000010"|"01010010"|"01100010"|"01110010" => + -- SBC HL,ss + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + No_PC <= '1'; + when 2 => + NoRead <= '1'; + ALU_Op <= "0011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "101"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + Set_BusB_To(0) <= '1'; + when others => + Set_BusB_To <= "1000"; + end case; + TStates <= "100"; + SetWZ <= "11"; + No_PC <= '1'; + when 3 => + NoRead <= '1'; + ALU_Op <= "0011"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + Set_BusA_To(2 downto 0) <= "100"; + case to_integer(unsigned(IR(5 downto 4))) is + when 0|1|2 => + Set_BusB_To(2 downto 1) <= IR(5 downto 4); + when others => + Set_BusB_To <= "1001"; + end case; + when others => + end case; + when "01101111" => + -- RLD -- Read in M2, not M3! fixed by Sorgelig + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Reg <= '1'; + Set_BusB_To(2 downto 0) <= "110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1101"; + Save_ALU <= '1'; + No_PC <= '1'; + when 3 => + TStates <= "100"; + I_RLD <= '1'; + NoRead <= '1'; + Set_Addr_To <= aXY; + when 4 => + Write <= '1'; + when others => + end case; + when "01100111" => + -- RRD -- Read in M2, not M3! fixed by Sorgelig + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aXY; + when 2 => + Read_To_Reg <= '1'; + Set_BusB_To(2 downto 0) <= "110"; + Set_BusA_To(2 downto 0) <= "111"; + ALU_Op <= "1110"; + Save_ALU <= '1'; + No_PC <= '1'; + when 3 => + TStates <= "100"; + I_RRD <= '1'; + NoRead <= '1'; + Set_Addr_To <= aXY; + when 4 => + Write <= '1'; + when others => + end case; + when "01000101"|"01001101"|"01010101"|"01011101"|"01100101"|"01101101"|"01110101"|"01111101" => + -- RETI/RETN + MCycles <= "011"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_TO <= aSP; + when 2 => + IncDec_16 <= "0111"; + Set_Addr_To <= aSP; + LDZ <= '1'; + when 3 => + Jump <= '1'; + IncDec_16 <= "0111"; + LDW <= '1'; + I_RETN <= '1'; + when others => null; + end case; + when "01000000"|"01001000"|"01010000"|"01011000"|"01100000"|"01101000"|"01110000"|"01111000" => + -- IN r,(C) + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + SetWZ <= "01"; + when 2 => + IORQ <= '1'; + if IR(5 downto 3) /= "110" then + Read_To_Reg <= '1'; + Set_BusA_To(2 downto 0) <= IR(5 downto 3); + end if; + I_INRC <= '1'; + when others => + end case; + when "01000001"|"01001001"|"01010001"|"01011001"|"01100001"|"01101001"|"01110001"|"01111001" => + -- OUT (C),r + -- OUT (C),0 + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + Set_Addr_To <= aBC; + SetWZ <= "01"; + Set_BusB_To(2 downto 0) <= IR(5 downto 3); + if IR(5 downto 3) = "110" then + Set_BusB_To(3) <= '1'; + end if; + when 2 => + Write <= '1'; + IORQ <= '1'; + when others => + end case; + when "10100010" | "10101010" | "10110010" | "10111010" => + -- INI, IND, INIR, INDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + Set_Addr_To <= aBC; + Set_BusB_To <= "1010"; + Set_BusA_To <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + SetWZ <= "11"; + IncDec_16(3) <= IR(3); + when 2 => + IORQ <= '1'; + Set_BusB_To <= "0110"; + Set_Addr_To <= aXY; + when 3 => + if IR(3) = '0' then + IncDec_16 <= "0110"; + else + IncDec_16 <= "1110"; + end if; + Write <= '1'; + I_BTR <= '1'; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "10100011" | "10101011" | "10110011" | "10111011" => + -- OUTI, OUTD, OTIR, OTDR + MCycles <= "100"; + case to_integer(unsigned(MCycle)) is + when 1 => + TStates <= "101"; + Set_Addr_To <= aXY; + Set_BusB_To <= "1010"; + Set_BusA_To <= "0000"; + Read_To_Reg <= '1'; + Save_ALU <= '1'; + ALU_Op <= "0010"; + when 2 => + Set_BusB_To <= "0110"; + Set_Addr_To <= aBC; + SetWZ <= "11"; + IncDec_16(3) <= IR(3); + when 3 => + if IR(3) = '0' then + IncDec_16 <= "0110"; + else + IncDec_16 <= "1110"; + end if; + IORQ <= '1'; + Write <= '1'; + I_BTR <= '1'; + when 4 => + NoRead <= '1'; + TStates <= "101"; + when others => null; + end case; + when "11000001"|"11001001"|"11010001"|"11011001" => + --R800 MULUB + if R800_mode = '1' then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + NoRead <= '1'; + I_MULUB <= '1'; + Set_BusB_To(2 downto 0) <= IR(5 downto 3); + Set_BusB_To(3) <= '0'; + when 2 => + NoRead <= '1'; + I_MULU <= '1'; + Set_BusA_To(2 downto 0) <= "100"; + when others => null; + end case; + end if; + when "11000011"|"11110011" => + --R800 MULUW + if R800_mode = '1' then + MCycles <= "010"; + case to_integer(unsigned(MCycle)) is + when 1 => + NoRead <= '1'; + if DPAIR = "11" then + Set_BusB_To(3 downto 0) <= "1000"; + else + Set_BusB_To(2 downto 1) <= DPAIR; + Set_BusB_To(0) <= '0'; + Set_BusB_To(3) <= '0'; + end if; + Set_BusA_To(2 downto 0) <= "100"; + when 2 => + TStates <= "101"; + NoRead <= '1'; + I_MULU <= '1'; + Set_BusA_To(2 downto 0) <= "100"; + when others => null; + end case; + end if; + end case; + + end case; + + if Mode = 1 then + if MCycle = "001" then +-- TStates <= "100"; + else + TStates <= "011"; + end if; + end if; + + if Mode = 3 then + if MCycle = "001" then +-- TStates <= "100"; + else + TStates <= "100"; + end if; + end if; + + if Mode < 2 then + if MCycle = "110" then + Inc_PC <= '1'; + if Mode = 1 then + Set_Addr_To <= aXY; + TStates <= "100"; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + end if; + if IRB = "00110110" or IRB = "11001011" then + Set_Addr_To <= aNone; + end if; + if not (IRB = "00110110" or ISet = "01") then + No_PC <= '1'; + end if; + end if; + if MCycle = "111" then + if Mode = 0 then + TStates <= "101"; + end if; + if ISet /= "01" then + Set_Addr_To <= aXY; + end if; + Set_BusB_To(2 downto 0) <= SSS; + Set_BusB_To(3) <= '0'; + if IRB = "00110110" or ISet = "01" then + -- LD (HL),n + Inc_PC <= '1'; + else + NoRead <= '1'; + end if; + end if; + end if; + + end process; + +end; diff --git a/modules/cpu-t80/T80_Pack.vhd b/modules/cpu-t80/T80_Pack.vhd index 3ac1522..5306599 100644 --- a/modules/cpu-t80/T80_Pack.vhd +++ b/modules/cpu-t80/T80_Pack.vhd @@ -1,248 +1,248 @@ --- **** --- T80(b) core. In an effort to merge and maintain bug fixes .... --- --- --- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010 --- Ver 300 started tidyup --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) --- --- **** --- --- Z80 compatible microprocessor core --- --- Version : 0250 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- - -library IEEE; -use IEEE.std_logic_1164.all; - -package T80_Pack is - - constant aNone : std_logic_vector(2 downto 0) := "111"; - constant aBC : std_logic_vector(2 downto 0) := "000"; - constant aDE : std_logic_vector(2 downto 0) := "001"; - constant aXY : std_logic_vector(2 downto 0) := "010"; - constant aIOA : std_logic_vector(2 downto 0) := "100"; - constant aSP : std_logic_vector(2 downto 0) := "101"; - constant aZI : std_logic_vector(2 downto 0) := "110"; - - component T80 - generic( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - CEN : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - IORQ : out std_logic; - NoRead : out std_logic; - Write : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DInst : in std_logic_vector(7 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0); - MC : out std_logic_vector(2 downto 0); - TS : out std_logic_vector(2 downto 0); - IntCycle_n : out std_logic; - IntE : out std_logic; - Stop : out std_logic; - R800_mode : in std_logic := '0'; - out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 - REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A - DIRSet : in std_logic := '0'; - DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A - ); - end component; - - component T80_Reg - port( - Clk : in std_logic; - CEN : in std_logic; - WEH : in std_logic; - WEL : in std_logic; - AddrA : in std_logic_vector(2 downto 0); - AddrB : in std_logic_vector(2 downto 0); - AddrC : in std_logic_vector(2 downto 0); - DIH : in std_logic_vector(7 downto 0); - DIL : in std_logic_vector(7 downto 0); - DOAH : out std_logic_vector(7 downto 0); - DOAL : out std_logic_vector(7 downto 0); - DOBH : out std_logic_vector(7 downto 0); - DOBL : out std_logic_vector(7 downto 0); - DOCH : out std_logic_vector(7 downto 0); - DOCL : out std_logic_vector(7 downto 0); - DOR : out std_logic_vector(127 downto 0); - DIRSet : in std_logic; - DIR : in std_logic_vector(127 downto 0) - ); - end component; - - component T80_MCode - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - IR : in std_logic_vector(7 downto 0); - ISet : in std_logic_vector(1 downto 0); - MCycle : in std_logic_vector(2 downto 0); - F : in std_logic_vector(7 downto 0); - NMICycle : in std_logic; - IntCycle : in std_logic; - XY_State : in std_logic_vector(1 downto 0); - MCycles : out std_logic_vector(2 downto 0); - TStates : out std_logic_vector(2 downto 0); - Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD - Inc_PC : out std_logic; - Inc_WZ : out std_logic; - IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc - Read_To_Reg : out std_logic; - Read_To_Acc : out std_logic; - Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F - Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 - ALU_Op : out std_logic_vector(3 downto 0); - -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None - Save_ALU : out std_logic; - Rot_Akku : out std_logic; - PreserveC : out std_logic; - Arith16 : out std_logic; - Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI - IORQ : out std_logic; - Jump : out std_logic; - JumpE : out std_logic; - JumpXY : out std_logic; - Call : out std_logic; - RstP : out std_logic; - LDZ : out std_logic; - LDW : out std_logic; - LDSPHL : out std_logic; - LDHLSP : out std_logic; - ADDSPdd : out std_logic; - Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None - ExchangeDH : out std_logic; - ExchangeRp : out std_logic; - ExchangeAF : out std_logic; - ExchangeRS : out std_logic; - ExchangeWH : out std_logic; - I_DJNZ : out std_logic; - I_CPL : out std_logic; - I_CCF : out std_logic; - I_SCF : out std_logic; - I_RETN : out std_logic; - I_BT : out std_logic; - I_BC : out std_logic; - I_BTR : out std_logic; - I_RLD : out std_logic; - I_RRD : out std_logic; - I_INRC : out std_logic; - I_MULUB : out std_logic; - I_MULU : out std_logic; - SetWZ : out std_logic_vector(1 downto 0); - SetDI : out std_logic; - SetEI : out std_logic; - IMode : out std_logic_vector(1 downto 0); - Halt : out std_logic; - NoRead : out std_logic; - Write : out std_logic; - R800_mode : in std_logic; - No_PC : out std_logic; - XYbit_undoc : out std_logic - ); - end component; - - component T80_ALU - generic( - Mode : integer := 0; - Flag_C : integer := 0; - Flag_N : integer := 1; - Flag_P : integer := 2; - Flag_X : integer := 3; - Flag_H : integer := 4; - Flag_Y : integer := 5; - Flag_Z : integer := 6; - Flag_S : integer := 7 - ); - port( - Arith16 : in std_logic; - Z16 : in std_logic; - WZ : in std_logic_vector(15 downto 0); - XY_State : in std_logic_vector(1 downto 0); - ALU_Op : in std_logic_vector(3 downto 0); - Rot_Akku : in std_logic; - IR : in std_logic_vector(5 downto 0); - ISet : in std_logic_vector(1 downto 0); - BusA : in std_logic_vector(7 downto 0); - BusB : in std_logic_vector(7 downto 0); - F_In : in std_logic_vector(7 downto 0); - Q : out std_logic_vector(7 downto 0); - F_Out : out std_logic_vector(7 downto 0) - ); - end component; - -end; +-- **** +-- T80(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 303 add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010 +-- Ver 300 started tidyup +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- Z80 compatible microprocessor core +-- +-- Version : 0250 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- + +library IEEE; +use IEEE.std_logic_1164.all; + +package T80_Pack is + + constant aNone : std_logic_vector(2 downto 0) := "111"; + constant aBC : std_logic_vector(2 downto 0) := "000"; + constant aDE : std_logic_vector(2 downto 0) := "001"; + constant aXY : std_logic_vector(2 downto 0) := "010"; + constant aIOA : std_logic_vector(2 downto 0) := "100"; + constant aSP : std_logic_vector(2 downto 0) := "101"; + constant aZI : std_logic_vector(2 downto 0) := "110"; + + component T80 + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + IOWait : integer := 0; -- 1 => Single cycle I/O, 1 => Std I/O cycle + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + IORQ : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DInst : in std_logic_vector(7 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + MC : out std_logic_vector(2 downto 0); + TS : out std_logic_vector(2 downto 0); + IntCycle_n : out std_logic; + IntE : out std_logic; + Stop : out std_logic; + R800_mode : in std_logic := '0'; + out0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 + REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A + DIRSet : in std_logic := '0'; + DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A + ); + end component; + + component T80_Reg + port( + Clk : in std_logic; + CEN : in std_logic; + WEH : in std_logic; + WEL : in std_logic; + AddrA : in std_logic_vector(2 downto 0); + AddrB : in std_logic_vector(2 downto 0); + AddrC : in std_logic_vector(2 downto 0); + DIH : in std_logic_vector(7 downto 0); + DIL : in std_logic_vector(7 downto 0); + DOAH : out std_logic_vector(7 downto 0); + DOAL : out std_logic_vector(7 downto 0); + DOBH : out std_logic_vector(7 downto 0); + DOBL : out std_logic_vector(7 downto 0); + DOCH : out std_logic_vector(7 downto 0); + DOCL : out std_logic_vector(7 downto 0); + DOR : out std_logic_vector(127 downto 0); + DIRSet : in std_logic; + DIR : in std_logic_vector(127 downto 0) + ); + end component; + + component T80_MCode + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + IR : in std_logic_vector(7 downto 0); + ISet : in std_logic_vector(1 downto 0); + MCycle : in std_logic_vector(2 downto 0); + F : in std_logic_vector(7 downto 0); + NMICycle : in std_logic; + IntCycle : in std_logic; + XY_State : in std_logic_vector(1 downto 0); + MCycles : out std_logic_vector(2 downto 0); + TStates : out std_logic_vector(2 downto 0); + Prefix : out std_logic_vector(1 downto 0); -- None,BC,ED,DD/FD + Inc_PC : out std_logic; + Inc_WZ : out std_logic; + IncDec_16 : out std_logic_vector(3 downto 0); -- BC,DE,HL,SP 0 is inc + Read_To_Reg : out std_logic; + Read_To_Acc : out std_logic; + Set_BusA_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI/DB,A,SP(L),SP(M),0,F + Set_BusB_To : out std_logic_vector(3 downto 0); -- B,C,D,E,H,L,DI,A,SP(L),SP(M),1,F,PC(L),PC(M),0 + ALU_Op : out std_logic_vector(3 downto 0); + -- ADD, ADC, SUB, SBC, AND, XOR, OR, CP, ROT, BIT, SET, RES, DAA, RLD, RRD, None + Save_ALU : out std_logic; + Rot_Akku : out std_logic; + PreserveC : out std_logic; + Arith16 : out std_logic; + Set_Addr_To : out std_logic_vector(2 downto 0); -- aNone,aXY,aIOA,aSP,aBC,aDE,aZI + IORQ : out std_logic; + Jump : out std_logic; + JumpE : out std_logic; + JumpXY : out std_logic; + Call : out std_logic; + RstP : out std_logic; + LDZ : out std_logic; + LDW : out std_logic; + LDSPHL : out std_logic; + LDHLSP : out std_logic; + ADDSPdd : out std_logic; + Special_LD : out std_logic_vector(2 downto 0); -- A,I;A,R;I,A;R,A;None + ExchangeDH : out std_logic; + ExchangeRp : out std_logic; + ExchangeAF : out std_logic; + ExchangeRS : out std_logic; + ExchangeWH : out std_logic; + I_DJNZ : out std_logic; + I_CPL : out std_logic; + I_CCF : out std_logic; + I_SCF : out std_logic; + I_RETN : out std_logic; + I_BT : out std_logic; + I_BC : out std_logic; + I_BTR : out std_logic; + I_RLD : out std_logic; + I_RRD : out std_logic; + I_INRC : out std_logic; + I_MULUB : out std_logic; + I_MULU : out std_logic; + SetWZ : out std_logic_vector(1 downto 0); + SetDI : out std_logic; + SetEI : out std_logic; + IMode : out std_logic_vector(1 downto 0); + Halt : out std_logic; + NoRead : out std_logic; + Write : out std_logic; + R800_mode : in std_logic; + No_PC : out std_logic; + XYbit_undoc : out std_logic + ); + end component; + + component T80_ALU + generic( + Mode : integer := 0; + Flag_C : integer := 0; + Flag_N : integer := 1; + Flag_P : integer := 2; + Flag_X : integer := 3; + Flag_H : integer := 4; + Flag_Y : integer := 5; + Flag_Z : integer := 6; + Flag_S : integer := 7 + ); + port( + Arith16 : in std_logic; + Z16 : in std_logic; + WZ : in std_logic_vector(15 downto 0); + XY_State : in std_logic_vector(1 downto 0); + ALU_Op : in std_logic_vector(3 downto 0); + Rot_Akku : in std_logic; + IR : in std_logic_vector(5 downto 0); + ISet : in std_logic_vector(1 downto 0); + BusA : in std_logic_vector(7 downto 0); + BusB : in std_logic_vector(7 downto 0); + F_In : in std_logic_vector(7 downto 0); + Q : out std_logic_vector(7 downto 0); + F_Out : out std_logic_vector(7 downto 0) + ); + end component; + +end; diff --git a/modules/cpu-t80/T80_Reg.vhd b/modules/cpu-t80/T80_Reg.vhd index e7e8645..5bf853e 100644 --- a/modules/cpu-t80/T80_Reg.vhd +++ b/modules/cpu-t80/T80_Reg.vhd @@ -1,152 +1,152 @@ --------------------------------------------------------------------------------- --- **** --- T80(c) core. Attempt to finish all undocumented features and provide --- accurate timings. --- Version 350. --- Copyright (c) 2018 Sorgelig --- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr --- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as --- correct implementation is still unclear. --- --- **** --- T80(b) core. In an effort to merge and maintain bug fixes .... --- --- --- Ver 300 started tidyup --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) --- --- **** --- --- T80 Registers, technology independent --- --- Version : 0244 --- --- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t51/ --- --- Limitations : --- --- File history : --- --- 0242 : Initial release --- --- 0244 : Changed to single register file --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity T80_Reg is - port( - Clk : in std_logic; - CEN : in std_logic; - WEH : in std_logic; - WEL : in std_logic; - AddrA : in std_logic_vector(2 downto 0); - AddrB : in std_logic_vector(2 downto 0); - AddrC : in std_logic_vector(2 downto 0); - DIH : in std_logic_vector(7 downto 0); - DIL : in std_logic_vector(7 downto 0); - DOAH : out std_logic_vector(7 downto 0); - DOAL : out std_logic_vector(7 downto 0); - DOBH : out std_logic_vector(7 downto 0); - DOBL : out std_logic_vector(7 downto 0); - DOCH : out std_logic_vector(7 downto 0); - DOCL : out std_logic_vector(7 downto 0); - DOR : out std_logic_vector(127 downto 0); - DIRSet : in std_logic; - DIR : in std_logic_vector(127 downto 0) - ); -end T80_Reg; - -architecture rtl of T80_Reg is - - type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0); - signal RegsH : Register_Image(0 to 7); - signal RegsL : Register_Image(0 to 7); - -begin - - process (Clk) - begin - if rising_edge(Clk) then - if DIRSet = '1' then - RegsL(0) <= DIR( 7 downto 0); - RegsH(0) <= DIR( 15 downto 8); - - RegsL(1) <= DIR( 23 downto 16); - RegsH(1) <= DIR( 31 downto 24); - - RegsL(2) <= DIR( 39 downto 32); - RegsH(2) <= DIR( 47 downto 40); - - RegsL(3) <= DIR( 55 downto 48); - RegsH(3) <= DIR( 63 downto 56); - - RegsL(4) <= DIR( 71 downto 64); - RegsH(4) <= DIR( 79 downto 72); - - RegsL(5) <= DIR( 87 downto 80); - RegsH(5) <= DIR( 95 downto 88); - - RegsL(6) <= DIR(103 downto 96); - RegsH(6) <= DIR(111 downto 104); - - RegsL(7) <= DIR(119 downto 112); - RegsH(7) <= DIR(127 downto 120); - elsif CEN = '1' then - if WEH = '1' then - RegsH(to_integer(unsigned(AddrA))) <= DIH; - end if; - if WEL = '1' then - RegsL(to_integer(unsigned(AddrA))) <= DIL; - end if; - end if; - end if; - end process; - - DOAH <= RegsH(to_integer(unsigned(AddrA))); - DOAL <= RegsL(to_integer(unsigned(AddrA))); - DOBH <= RegsH(to_integer(unsigned(AddrB))); - DOBL <= RegsL(to_integer(unsigned(AddrB))); - DOCH <= RegsH(to_integer(unsigned(AddrC))); - DOCL <= RegsL(to_integer(unsigned(AddrC))); - DOR <= RegsH(7) & RegsL(7) & RegsH(6) & RegsL(6) & RegsH(5) & RegsL(5) & RegsH(4) & RegsL(4) & RegsH(3) & RegsL(3) & RegsH(2) & RegsL(2) & RegsH(1) & RegsL(1) & RegsH(0) & RegsL(0); - -end; +-------------------------------------------------------------------------------- +-- **** +-- T80(c) core. Attempt to finish all undocumented features and provide +-- accurate timings. +-- Version 350. +-- Copyright (c) 2018 Sorgelig +-- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr +-- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as +-- correct implementation is still unclear. +-- +-- **** +-- T80(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 300 started tidyup +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- T80 Registers, technology independent +-- +-- Version : 0244 +-- +-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t51/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0242 : Initial release +-- +-- 0244 : Changed to single register file +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity T80_Reg is + port( + Clk : in std_logic; + CEN : in std_logic; + WEH : in std_logic; + WEL : in std_logic; + AddrA : in std_logic_vector(2 downto 0); + AddrB : in std_logic_vector(2 downto 0); + AddrC : in std_logic_vector(2 downto 0); + DIH : in std_logic_vector(7 downto 0); + DIL : in std_logic_vector(7 downto 0); + DOAH : out std_logic_vector(7 downto 0); + DOAL : out std_logic_vector(7 downto 0); + DOBH : out std_logic_vector(7 downto 0); + DOBL : out std_logic_vector(7 downto 0); + DOCH : out std_logic_vector(7 downto 0); + DOCL : out std_logic_vector(7 downto 0); + DOR : out std_logic_vector(127 downto 0); + DIRSet : in std_logic; + DIR : in std_logic_vector(127 downto 0) + ); +end T80_Reg; + +architecture rtl of T80_Reg is + + type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0); + signal RegsH : Register_Image(0 to 7); + signal RegsL : Register_Image(0 to 7); + +begin + + process (Clk) + begin + if rising_edge(Clk) then + if DIRSet = '1' then + RegsL(0) <= DIR( 7 downto 0); + RegsH(0) <= DIR( 15 downto 8); + + RegsL(1) <= DIR( 23 downto 16); + RegsH(1) <= DIR( 31 downto 24); + + RegsL(2) <= DIR( 39 downto 32); + RegsH(2) <= DIR( 47 downto 40); + + RegsL(3) <= DIR( 55 downto 48); + RegsH(3) <= DIR( 63 downto 56); + + RegsL(4) <= DIR( 71 downto 64); + RegsH(4) <= DIR( 79 downto 72); + + RegsL(5) <= DIR( 87 downto 80); + RegsH(5) <= DIR( 95 downto 88); + + RegsL(6) <= DIR(103 downto 96); + RegsH(6) <= DIR(111 downto 104); + + RegsL(7) <= DIR(119 downto 112); + RegsH(7) <= DIR(127 downto 120); + elsif CEN = '1' then + if WEH = '1' then + RegsH(to_integer(unsigned(AddrA))) <= DIH; + end if; + if WEL = '1' then + RegsL(to_integer(unsigned(AddrA))) <= DIL; + end if; + end if; + end if; + end process; + + DOAH <= RegsH(to_integer(unsigned(AddrA))); + DOAL <= RegsL(to_integer(unsigned(AddrA))); + DOBH <= RegsH(to_integer(unsigned(AddrB))); + DOBL <= RegsL(to_integer(unsigned(AddrB))); + DOCH <= RegsH(to_integer(unsigned(AddrC))); + DOCL <= RegsL(to_integer(unsigned(AddrC))); + DOR <= RegsH(7) & RegsL(7) & RegsH(6) & RegsL(6) & RegsH(5) & RegsL(5) & RegsH(4) & RegsL(4) & RegsH(3) & RegsL(3) & RegsH(2) & RegsL(2) & RegsH(1) & RegsL(1) & RegsH(0) & RegsL(0); + +end; diff --git a/modules/cpu-t80/T80a.vhd b/modules/cpu-t80/T80a.vhd index fdd84d1..22bb9f4 100644 --- a/modules/cpu-t80/T80a.vhd +++ b/modules/cpu-t80/T80a.vhd @@ -1,342 +1,342 @@ --- **** --- T80(b) core. In an effort to merge and maintain bug fixes .... --- --- --- Ver 300 started tidyup --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) --- --- **** --- --- Z80 compatible microprocessor core, asynchronous top level --- --- Version : 0250 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0208 : First complete release --- --- 0211 : Fixed interrupt cycle --- --- 0235 : Updated for T80 interface change --- --- 0238 : Updated for T80 interface change --- --- 0240 : Updated for T80 interface change --- --- 0242 : Updated for T80 interface change --- --- 0247 : Fixed bus req/ack cycle --- --- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15 --- --- Bus signal logic changes from the ZX Spectrum Next were made by: --- --- Fabio Belavenuto, Charlie Ingley --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity T80a is - generic( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - IOWait : integer := 1 -- 0 => Single I/O cycle, 1 => Std I/O cycle - ); - port( - RESET_n : in std_logic; - R800_mode : in std_logic; - CLK_n : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - MREQ_n : out std_logic; - IORQ_n : out std_logic; - RD_n : out std_logic; - WR_n : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - D : inout std_logic_vector(7 downto 0) - ); -end T80a; - -architecture rtl of T80a is - - signal CEN : std_logic; - signal Reset_s : std_logic; - signal IntCycle_n : std_logic; - signal IORQ : std_logic; - signal NoRead : std_logic; - signal Write : std_logic; - signal MREQ : std_logic; - signal MReq_Inhibit : std_logic; - signal Req_Inhibit : std_logic; - signal RD : std_logic; - signal MREQ_n_i : std_logic; - signal MREQ_rw : std_logic; -- 30/10/19 Charlie Ingley-- add MREQ control - signal IORQ_n_i : std_logic; - signal IORQ_t1 : std_logic; -- 30/10/19 Charlie Ingley-- add IORQ control - signal IORQ_t2 : std_logic; -- 30/10/19 Charlie Ingley-- add IORQ control - signal IORQ_rw : std_logic; -- 30/10/19 Charlie Ingley-- add IORQ control - signal IORQ_int : std_logic; -- 30/10/19 Charlie Ingley-- add IORQ interrupt control - signal IORQ_int_inhibit : std_logic_vector(2 downto 0); - signal RD_n_i : std_logic; - signal WR_n_i : std_logic; - signal WR_t2 : std_logic; -- 30/10/19 Charlie Ingley-- add WR control - signal RFSH_n_i : std_logic; - signal BUSAK_n_i : std_logic; - signal A_i : std_logic_vector(15 downto 0); - signal DO : std_logic_vector(7 downto 0); - signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser - signal Wait_s : std_logic; - signal MCycle : std_logic_vector(2 downto 0); - signal TState : std_logic_vector(2 downto 0); - -begin - - CEN <= '1'; - - BUSAK_n <= BUSAK_n_i; -- 30/10/19 Charlie Ingley - IORQ/RD/WR changes - MREQ_rw <= MREQ and (Req_Inhibit or MReq_Inhibit); -- added MREQ timing control - MREQ_n_i <= not MREQ_rw; -- changed MREQ generation - IORQ_rw <= IORQ and not (IORQ_t1 or IORQ_t2); -- added IORQ generation timing control - IORQ_n_i <= not ((IORQ_int and not IORQ_int_inhibit(2)) or IORQ_rw); -- changed IORQ generation - RD_n_i <= not (RD and (MREQ_rw or IORQ_rw)); -- changed RD/IORQ generation - WR_n_i <= not (Write and ((WR_t2 and MREQ_rw) or IORQ_rw)); -- added WR/IORQ timing control - - MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z'; - IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z'; - RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z'; - WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z'; - RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z'; - A <= A_i when BUSAK_n_i = '1' else (others => 'Z'); - D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z'); - - process (RESET_n, CLK_n) - begin - if RESET_n = '0' then - Reset_s <= '0'; - elsif CLK_n'event and CLK_n = '1' then - Reset_s <= '1'; - end if; - end process; - - u0 : T80 - generic map( - Mode => Mode, - IOWait => IOWait) - port map( - R800_mode => R800_mode, - CEN => CEN, - M1_n => M1_n, - IORQ => IORQ, - NoRead => NoRead, - Write => Write, - RFSH_n => RFSH_n_i, - HALT_n => HALT_n, - WAIT_n => Wait_s, - INT_n => INT_n, - NMI_n => NMI_n, - RESET_n => Reset_s, - BUSRQ_n => BUSRQ_n, - BUSAK_n => BUSAK_n_i, - CLK_n => CLK_n, - A => A_i, - DInst => D, - DI => DI_Reg, - DO => DO, - MC => MCycle, - TS => TState, - IntCycle_n => IntCycle_n); - - process (CLK_n) - begin - if CLK_n'event and CLK_n = '0' then - Wait_s <= WAIT_n; - if TState = "011" and BUSAK_n_i = '1' then - DI_Reg <= to_x01(D); - end if; - end if; - end process; - --- 30/10/19 Charlie Ingley - Generate WR_t2 to correct MREQ/WR timing - process (Reset_s,CLK_n) - begin - if Reset_s = '0' then - WR_t2 <= '0'; - elsif CLK_n'event and CLK_n = '0' then - if MCycle /= "001" then - if TState = "010" then -- WR starts on falling edge of T2 for MREQ - WR_t2 <= Write; - end if; - end if; - if TState = "011" then -- end WR - WR_t2 <= '0'; - end if; - end if; - end process; - --- Generate Req_Inhibit - process (Reset_s,CLK_n) - begin - if Reset_s = '0' then - Req_Inhibit <= '1'; -- Charlie Ingley 30/10/19 - changed Req_Inhibit polarity - elsif CLK_n'event and CLK_n = '1' then - if MCycle = "001" and TState = "010" and WAIT_n = '1' then -- by Fabio Belavenuto - fix behavior of Wait_n - Req_Inhibit <= '0'; - else - Req_Inhibit <= '1'; - end if; - end if; - end process; - --- Generate MReq_Inhibit - process (Reset_s, CLK_n) - begin - if Reset_s = '0' then - MReq_Inhibit <= '1'; -- Charlie Ingley 30/10/19 - changed Req_Inhibit polarity - elsif CLK_n'event and CLK_n = '0' then - if MCycle = "001" and TState = "010" and WAIT_n = '1' then -- by Fabio Belavenuto - fix behavior of Wait_n - MReq_Inhibit <= '0'; - else - MReq_Inhibit <= '1'; - end if; - end if; - end process; - --- Generate RD for MREQ - process(Reset_s,CLK_n) - begin - if Reset_s = '0' then - RD <= '0'; - MREQ <= '0'; - elsif CLK_n'event and CLK_n = '0' then - if MCycle = "001" then - if TState = "001" then - RD <= IntCycle_n; - MREQ <= IntCycle_n; - end if; - if TState = "011" then - RD <= '0'; - MREQ <= '1'; - end if; - if TState = "100" then - MREQ <= '0'; - end if; - else - if TState = "001" and NoRead = '0' then - RD <= not Write; - MREQ <= not IORQ; - end if; - if TState = "011" then - RD <= '0'; - MREQ <= '0'; - end if; - end if; - end if; - end process; - - -- 30/10/19 Charlie Ingley - Generate IORQ_int for IORQ interrupt timing control - process(Reset_s,CLK_n) - begin - if Reset_s = '0' then - IORQ_int <= '0'; - elsif CLK_n'event and CLK_n = '1' then - if MCycle = "001" then - if TState = "001" then - IORQ_int <= not IntCycle_n; - end if; - if TState = "010" then - IORQ_int <= '0'; - end if; - end if; - end if; - end process; - - process(Reset_s,CLK_n) - begin - if Reset_s = '0' then - IORQ_int_inhibit <= "111"; - elsif CLK_n'event and CLK_n = '0' then - if IntCycle_n = '0' then - if MCycle = "001" then - IORQ_int_inhibit <= IORQ_int_inhibit(1 downto 0) & '0'; - end if; - if MCycle = "010" then - IORQ_int_inhibit <= "111"; - end if; - end if; - end if; - end process; - --- 30/10/19 Charlie Ingley - Generate IORQ_t1 for IORQ timing control - process(Reset_s, CLK_n) - begin - if Reset_s = '0' then - IORQ_t1 <= '1'; - elsif CLK_n'event and CLK_n = '0' then - if TState = "001" then - IORQ_t1 <= not IntCycle_n; - end if; - if TState = "011" then - IORQ_t1 <= '1'; - end if; - end if; - end process; - --- 30/10/19 Charlie Ingley - Generate IORQ_t2 for IORQ timing control - process (RESET_n, CLK_n) - begin - if RESET_n = '0' then - IORQ_t2 <= '1'; - elsif CLK_n'event and CLK_n = '1' then - IORQ_t2 <= IORQ_t1; - end if; - end process; - -end; +-- **** +-- T80(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 300 started tidyup +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- Z80 compatible microprocessor core, asynchronous top level +-- +-- Version : 0250 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0211 : Fixed interrupt cycle +-- +-- 0235 : Updated for T80 interface change +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- +-- 0247 : Fixed bus req/ack cycle +-- +-- 0250 : Added R800 Multiplier by TobiFlex 2017.10.15 +-- +-- Bus signal logic changes from the ZX Spectrum Next were made by: +-- +-- Fabio Belavenuto, Charlie Ingley +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80a is + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + IOWait : integer := 1 -- 0 => Single I/O cycle, 1 => Std I/O cycle + ); + port( + RESET_n : in std_logic; + R800_mode : in std_logic; + CLK_n : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + D : inout std_logic_vector(7 downto 0) + ); +end T80a; + +architecture rtl of T80a is + + signal CEN : std_logic; + signal Reset_s : std_logic; + signal IntCycle_n : std_logic; + signal IORQ : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal MREQ : std_logic; + signal MReq_Inhibit : std_logic; + signal Req_Inhibit : std_logic; + signal RD : std_logic; + signal MREQ_n_i : std_logic; + signal MREQ_rw : std_logic; -- 30/10/19 Charlie Ingley-- add MREQ control + signal IORQ_n_i : std_logic; + signal IORQ_t1 : std_logic; -- 30/10/19 Charlie Ingley-- add IORQ control + signal IORQ_t2 : std_logic; -- 30/10/19 Charlie Ingley-- add IORQ control + signal IORQ_rw : std_logic; -- 30/10/19 Charlie Ingley-- add IORQ control + signal IORQ_int : std_logic; -- 30/10/19 Charlie Ingley-- add IORQ interrupt control + signal IORQ_int_inhibit : std_logic_vector(2 downto 0); + signal RD_n_i : std_logic; + signal WR_n_i : std_logic; + signal WR_t2 : std_logic; -- 30/10/19 Charlie Ingley-- add WR control + signal RFSH_n_i : std_logic; + signal BUSAK_n_i : std_logic; + signal A_i : std_logic_vector(15 downto 0); + signal DO : std_logic_vector(7 downto 0); + signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser + signal Wait_s : std_logic; + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + +begin + + CEN <= '1'; + + BUSAK_n <= BUSAK_n_i; -- 30/10/19 Charlie Ingley - IORQ/RD/WR changes + MREQ_rw <= MREQ and (Req_Inhibit or MReq_Inhibit); -- added MREQ timing control + MREQ_n_i <= not MREQ_rw; -- changed MREQ generation + IORQ_rw <= IORQ and not (IORQ_t1 or IORQ_t2); -- added IORQ generation timing control + IORQ_n_i <= not ((IORQ_int and not IORQ_int_inhibit(2)) or IORQ_rw); -- changed IORQ generation + RD_n_i <= not (RD and (MREQ_rw or IORQ_rw)); -- changed RD/IORQ generation + WR_n_i <= not (Write and ((WR_t2 and MREQ_rw) or IORQ_rw)); -- added WR/IORQ timing control + + MREQ_n <= MREQ_n_i when BUSAK_n_i = '1' else 'Z'; + IORQ_n <= IORQ_n_i when BUSAK_n_i = '1' else 'Z'; + RD_n <= RD_n_i when BUSAK_n_i = '1' else 'Z'; + WR_n <= WR_n_i when BUSAK_n_i = '1' else 'Z'; + RFSH_n <= RFSH_n_i when BUSAK_n_i = '1' else 'Z'; + A <= A_i when BUSAK_n_i = '1' else (others => 'Z'); + D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z'); + + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + Reset_s <= '0'; + elsif CLK_n'event and CLK_n = '1' then + Reset_s <= '1'; + end if; + end process; + + u0 : T80 + generic map( + Mode => Mode, + IOWait => IOWait) + port map( + R800_mode => R800_mode, + CEN => CEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n_i, + HALT_n => HALT_n, + WAIT_n => Wait_s, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => Reset_s, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n_i, + CLK_n => CLK_n, + A => A_i, + DInst => D, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n); + + process (CLK_n) + begin + if CLK_n'event and CLK_n = '0' then + Wait_s <= WAIT_n; + if TState = "011" and BUSAK_n_i = '1' then + DI_Reg <= to_x01(D); + end if; + end if; + end process; + +-- 30/10/19 Charlie Ingley - Generate WR_t2 to correct MREQ/WR timing + process (Reset_s,CLK_n) + begin + if Reset_s = '0' then + WR_t2 <= '0'; + elsif CLK_n'event and CLK_n = '0' then + if MCycle /= "001" then + if TState = "010" then -- WR starts on falling edge of T2 for MREQ + WR_t2 <= Write; + end if; + end if; + if TState = "011" then -- end WR + WR_t2 <= '0'; + end if; + end if; + end process; + +-- Generate Req_Inhibit + process (Reset_s,CLK_n) + begin + if Reset_s = '0' then + Req_Inhibit <= '1'; -- Charlie Ingley 30/10/19 - changed Req_Inhibit polarity + elsif CLK_n'event and CLK_n = '1' then + if MCycle = "001" and TState = "010" and WAIT_n = '1' then -- by Fabio Belavenuto - fix behavior of Wait_n + Req_Inhibit <= '0'; + else + Req_Inhibit <= '1'; + end if; + end if; + end process; + +-- Generate MReq_Inhibit + process (Reset_s, CLK_n) + begin + if Reset_s = '0' then + MReq_Inhibit <= '1'; -- Charlie Ingley 30/10/19 - changed Req_Inhibit polarity + elsif CLK_n'event and CLK_n = '0' then + if MCycle = "001" and TState = "010" and WAIT_n = '1' then -- by Fabio Belavenuto - fix behavior of Wait_n + MReq_Inhibit <= '0'; + else + MReq_Inhibit <= '1'; + end if; + end if; + end process; + +-- Generate RD for MREQ + process(Reset_s,CLK_n) + begin + if Reset_s = '0' then + RD <= '0'; + MREQ <= '0'; + elsif CLK_n'event and CLK_n = '0' then + if MCycle = "001" then + if TState = "001" then + RD <= IntCycle_n; + MREQ <= IntCycle_n; + end if; + if TState = "011" then + RD <= '0'; + MREQ <= '1'; + end if; + if TState = "100" then + MREQ <= '0'; + end if; + else + if TState = "001" and NoRead = '0' then + RD <= not Write; + MREQ <= not IORQ; + end if; + if TState = "011" then + RD <= '0'; + MREQ <= '0'; + end if; + end if; + end if; + end process; + + -- 30/10/19 Charlie Ingley - Generate IORQ_int for IORQ interrupt timing control + process(Reset_s,CLK_n) + begin + if Reset_s = '0' then + IORQ_int <= '0'; + elsif CLK_n'event and CLK_n = '1' then + if MCycle = "001" then + if TState = "001" then + IORQ_int <= not IntCycle_n; + end if; + if TState = "010" then + IORQ_int <= '0'; + end if; + end if; + end if; + end process; + + process(Reset_s,CLK_n) + begin + if Reset_s = '0' then + IORQ_int_inhibit <= "111"; + elsif CLK_n'event and CLK_n = '0' then + if IntCycle_n = '0' then + if MCycle = "001" then + IORQ_int_inhibit <= IORQ_int_inhibit(1 downto 0) & '0'; + end if; + if MCycle = "010" then + IORQ_int_inhibit <= "111"; + end if; + end if; + end if; + end process; + +-- 30/10/19 Charlie Ingley - Generate IORQ_t1 for IORQ timing control + process(Reset_s, CLK_n) + begin + if Reset_s = '0' then + IORQ_t1 <= '1'; + elsif CLK_n'event and CLK_n = '0' then + if TState = "001" then + IORQ_t1 <= not IntCycle_n; + end if; + if TState = "011" then + IORQ_t1 <= '1'; + end if; + end if; + end process; + +-- 30/10/19 Charlie Ingley - Generate IORQ_t2 for IORQ timing control + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + IORQ_t2 <= '1'; + elsif CLK_n'event and CLK_n = '1' then + IORQ_t2 <= IORQ_t1; + end if; + end process; + +end; diff --git a/modules/cpu-t80/T80as.vhd b/modules/cpu-t80/T80as.vhd index 9a34c64..ed46bfe 100644 --- a/modules/cpu-t80/T80as.vhd +++ b/modules/cpu-t80/T80as.vhd @@ -1,289 +1,289 @@ ------------------------------------------------------------------------------- --- 2004.10.18 WR_n active was changed from T2 to T3. --- modification by Katsumi Degawa ------------------------------------------------------------------------------- --- t80as.vhd : The non-tristate signal edition of t80a.vhd --- --- 2003.2.7 non-tristate modification by Tatsuyuki Satoh --- --- 1.separate 'D' to 'DO' and 'DI'. --- 2.added 'DOE' to 'DO' enable signal.(data direction) --- 3.MREQ_n,IORQ_n,RD_n,WR_n,RFSH_n,A doesn't become the condition of 'Z'. --- --- There is a mark of "--AS" in all the change points. --- ------------------------------------------------------------------------------- - --- --- Z80 compatible microprocessor core, asynchronous top level --- --- Version : 0247 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0208 : First complete release --- --- 0211 : Fixed interrupt cycle --- --- 0235 : Updated for T80 interface change --- --- 0238 : Updated for T80 interface change --- --- 0240 : Updated for T80 interface change --- --- 0242 : Updated for T80 interface change --- --- 0247 : Fixed bus req/ack cycle --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity T80as is - generic( - Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - ); - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - MREQ_n : out std_logic; - IORQ_n : out std_logic; - RD_n : out std_logic; - WR_n : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); ---AS-- D : inout std_logic_vector(7 downto 0) ---AS>> - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0); - DOE : out std_logic ---< 'Z'); ---AS-- D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z'); ---AS>> - MREQ_n <= MREQ_n_i; - IORQ_n <= IORQ_n_i; - RD_n <= RD_n_i; - WR_n <= WR_n_i; - RFSH_n <= RFSH_n_i; - A <= A_i; - DOE <= Write when BUSAK_n_i = '1' else '0'; ---< Mode, - IOWait => 1) - port map( - CEN => CEN, - M1_n => M1_n, - IORQ => IORQ, - NoRead => NoRead, - Write => Write, - RFSH_n => RFSH_n_i, - HALT_n => HALT_n, - WAIT_n => Wait_s, - INT_n => INT_n, - NMI_n => NMI_n, - RESET_n => Reset_s, - BUSRQ_n => BUSRQ_n, - BUSAK_n => BUSAK_n_i, - CLK_n => CLK_n, - A => A_i, --- DInst => D, - DInst => DI, - DI => DI_Reg, - DO => DO, - MC => MCycle, - TS => TState, - IntCycle_n => IntCycle_n); - - process (CLK_n) - begin - if CLK_n'event and CLK_n = '0' then - Wait_s <= WAIT_n; - if TState = "011" and BUSAK_n_i = '1' then ---AS-- DI_Reg <= to_x01(D); ---AS>> - DI_Reg <= to_x01(DI); ---< Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); +--AS-- D : inout std_logic_vector(7 downto 0) +--AS>> + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + DOE : out std_logic +--< 'Z'); +--AS-- D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z'); +--AS>> + MREQ_n <= MREQ_n_i; + IORQ_n <= IORQ_n_i; + RD_n <= RD_n_i; + WR_n <= WR_n_i; + RFSH_n <= RFSH_n_i; + A <= A_i; + DOE <= Write when BUSAK_n_i = '1' else '0'; +--< Mode, + IOWait => 1) + port map( + CEN => CEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n_i, + HALT_n => HALT_n, + WAIT_n => Wait_s, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => Reset_s, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n_i, + CLK_n => CLK_n, + A => A_i, +-- DInst => D, + DInst => DI, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n); + + process (CLK_n) + begin + if CLK_n'event and CLK_n = '0' then + Wait_s <= WAIT_n; + if TState = "011" and BUSAK_n_i = '1' then +--AS-- DI_Reg <= to_x01(D); +--AS>> + DI_Reg <= to_x01(DI); +--< Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - ); - port( - RESET_n : in std_logic; - CLK : in std_logic; - CEN_p : in std_logic := '1'; - CEN_n : in std_logic := '1'; - WAIT_n : in std_logic := '1'; - INT_n : in std_logic := '1'; - NMI_n : in std_logic := '1'; - BUSRQ_n : in std_logic := '1'; - M1_n : out std_logic; - MREQ_n : out std_logic; - IORQ_n : out std_logic; - RD_n : out std_logic; - WR_n : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - OUT0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 - A : out std_logic_vector(15 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0); - R800_mode : in std_logic := '0'; - REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A - DIRSet : in std_logic := '0'; - DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A - ); -end T80pa; - -architecture rtl of T80pa is - - signal IntCycle_n : std_logic; - signal IntCycleD_n : std_logic_vector(1 downto 0); - signal IORQ : std_logic; - signal NoRead : std_logic; - signal Write : std_logic; - signal BUSAK : std_logic; - signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser - signal MCycle : std_logic_vector(2 downto 0); - signal TState : std_logic_vector(2 downto 0); - signal CEN_pol : std_logic; - signal CEN : std_logic; -begin - - CEN <= CEN_p and not CEN_pol; - BUSAK_n <= BUSAK; - - u0 : T80 - generic map( - Mode => Mode, - IOWait => 1 - ) - port map( - CEN => CEN, - M1_n => M1_n, - IORQ => IORQ, - NoRead => NoRead, - Write => Write, - RFSH_n => RFSH_n, - HALT_n => HALT_n, - WAIT_n => '1', - INT_n => INT_n, - NMI_n => NMI_n, - RESET_n => RESET_n, - BUSRQ_n => BUSRQ_n, - BUSAK_n => BUSAK, - CLK_n => CLK, - A => A, - DInst => DI, -- valid at beginning of T3 - DI => DI_Reg, -- latched at middle of T3 - DO => DO, - REG => REG, - MC => MCycle, - TS => TState, - OUT0 => OUT0, - R800_mode => R800_mode, - IntCycle_n => IntCycle_n, - DIRSet => DIRSet, - DIR => DIR - ); - - process(CLK) - begin - if rising_edge(CLK) then - if RESET_n = '0' then - WR_n <= '1'; - RD_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - DI_Reg <= "00000000"; - CEN_pol <= '0'; - elsif CEN_p = '1' and CEN_pol = '0' then - CEN_pol <= '1'; - if MCycle = "001" then - if TState = "010" then - IORQ_n <= '1'; - MREQ_n <= '1'; - RD_n <= '1'; - end if; - else - if TState = "001" and IORQ = '1' then - WR_n <= not Write; - RD_n <= Write; - IORQ_n <= '0'; - end if; - end if; - elsif CEN_n = '1' and CEN_pol = '1' then - if TState = "010" then - CEN_pol <= not WAIT_n; - else - CEN_pol <= '0'; - end if; - if TState = "011" and BUSAK = '1' then - DI_Reg <= DI; - end if; - if MCycle = "001" then - if TState = "001" then - IntCycleD_n <= IntCycleD_n(0) & IntCycle_n; - RD_n <= not IntCycle_n; - MREQ_n <= not IntCycle_n; - IORQ_n <= IntCycleD_n(1); - end if; - if TState = "011" then - IntCycleD_n <= "11"; - RD_n <= '1'; - MREQ_n <= '0'; - end if; - if TState = "100" then - MREQ_n <= '1'; - end if; - else - if NoRead = '0' and IORQ = '0' then - if TState = "001" then - RD_n <= Write; - MREQ_n <= '0'; - end if; - end if; - if TState = "010" then - WR_n <= not Write; - end if; - if TState = "011" then - WR_n <= '1'; - RD_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - end if; - end if; - end if; - end if; - end process; -end; +-- +-- Z80 compatible microprocessor core, preudo-asynchronous top level (by Sorgelig) +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- File history : +-- +-- v1.0: convert to preudo-asynchronous model with original Z80 timings. +-- +-- v2.0: rewritten for more precise timings. +-- support for both CEN_n and CEN_p set to 1. Effective clock will be CLK/2. +-- +-- v2.1: Output Address 0 during non-bus MCycle (fix ZX contention) +-- +-- v2.2: Interrupt acknowledge cycle has been corrected +-- WAIT_n is broken in T80.vhd. Simulate correct WAIT_n locally. +-- +-- v2.3: Output last used Address during non-bus MCycle seems more correct. +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80pa is + generic( + Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + ); + port( + RESET_n : in std_logic; + CLK : in std_logic; + CEN_p : in std_logic := '1'; + CEN_n : in std_logic := '1'; + WAIT_n : in std_logic := '1'; + INT_n : in std_logic := '1'; + NMI_n : in std_logic := '1'; + BUSRQ_n : in std_logic := '1'; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + OUT0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0); + R800_mode : in std_logic := '0'; + REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A + DIRSet : in std_logic := '0'; + DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A + ); +end T80pa; + +architecture rtl of T80pa is + + signal IntCycle_n : std_logic; + signal IntCycleD_n : std_logic_vector(1 downto 0); + signal IORQ : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal BUSAK : std_logic; + signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + signal CEN_pol : std_logic; + signal CEN : std_logic; +begin + + CEN <= CEN_p and not CEN_pol; + BUSAK_n <= BUSAK; + + u0 : T80 + generic map( + Mode => Mode, + IOWait => 1 + ) + port map( + CEN => CEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n, + HALT_n => HALT_n, + WAIT_n => '1', + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => RESET_n, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK, + CLK_n => CLK, + A => A, + DInst => DI, -- valid at beginning of T3 + DI => DI_Reg, -- latched at middle of T3 + DO => DO, + REG => REG, + MC => MCycle, + TS => TState, + OUT0 => OUT0, + R800_mode => R800_mode, + IntCycle_n => IntCycle_n, + DIRSet => DIRSet, + DIR => DIR + ); + + process(CLK) + begin + if rising_edge(CLK) then + if RESET_n = '0' then + WR_n <= '1'; + RD_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + DI_Reg <= "00000000"; + CEN_pol <= '0'; + elsif CEN_p = '1' and CEN_pol = '0' then + CEN_pol <= '1'; + if MCycle = "001" then + if TState = "010" then + IORQ_n <= '1'; + MREQ_n <= '1'; + RD_n <= '1'; + end if; + else + if TState = "001" and IORQ = '1' then + WR_n <= not Write; + RD_n <= Write; + IORQ_n <= '0'; + end if; + end if; + elsif CEN_n = '1' and CEN_pol = '1' then + if TState = "010" then + CEN_pol <= not WAIT_n; + else + CEN_pol <= '0'; + end if; + if TState = "011" and BUSAK = '1' then + DI_Reg <= DI; + end if; + if MCycle = "001" then + if TState = "001" then + IntCycleD_n <= IntCycleD_n(0) & IntCycle_n; + RD_n <= not IntCycle_n; + MREQ_n <= not IntCycle_n; + IORQ_n <= IntCycleD_n(1); + end if; + if TState = "011" then + IntCycleD_n <= "11"; + RD_n <= '1'; + MREQ_n <= '0'; + end if; + if TState = "100" then + MREQ_n <= '1'; + end if; + else + if NoRead = '0' and IORQ = '0' then + if TState = "001" then + RD_n <= Write; + MREQ_n <= '0'; + end if; + end if; + if TState = "010" then + WR_n <= not Write; + end if; + if TState = "011" then + WR_n <= '1'; + RD_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + end if; + end if; + end if; + end if; + end process; +end; diff --git a/modules/cpu-t80/T80s.vhd b/modules/cpu-t80/T80s.vhd index 6967292..d25a650 100644 --- a/modules/cpu-t80/T80s.vhd +++ b/modules/cpu-t80/T80s.vhd @@ -1,193 +1,193 @@ --- --- Z80 compatible microprocessor core, synchronous top level --- Different timing than the original z80 --- Inputs needs to be synchronous and outputs may glitch --- --- Version : 0242 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0208 : First complete release --- --- 0210 : Fixed read with wait --- --- 0211 : Fixed interrupt cycle --- --- 0235 : Updated for T80 interface change --- --- 0236 : Added T2Write generic --- --- 0237 : Fixed T2Write with wait state --- --- 0238 : Updated for T80 interface change --- --- 0240 : Updated for T80 interface change --- --- 0242 : Updated for T80 interface change --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use IEEE.STD_LOGIC_UNSIGNED.all; -use work.T80_Pack.all; - -entity T80s is - generic( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 - IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle - ); - port( - RESET_n : in std_logic; - CLK : in std_logic; - CEN : in std_logic := '1'; - WAIT_n : in std_logic := '1'; - INT_n : in std_logic := '1'; - NMI_n : in std_logic := '1'; - BUSRQ_n : in std_logic := '1'; - M1_n : out std_logic; - MREQ_n : out std_logic; - IORQ_n : out std_logic; - RD_n : out std_logic; - WR_n : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - OUT0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 - A : out std_logic_vector(15 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0) - ); -end T80s; - -architecture rtl of T80s is - - signal IntCycle_n : std_logic; - signal NoRead : std_logic; - signal Write : std_logic; - signal IORQ : std_logic; - signal DI_Reg : std_logic_vector(7 downto 0); - signal MCycle : std_logic_vector(2 downto 0); - signal TState : std_logic_vector(2 downto 0); - -begin - - u0 : T80 - generic map( - Mode => Mode, - IOWait => IOWait) - port map( - CEN => CEN, - M1_n => M1_n, - IORQ => IORQ, - NoRead => NoRead, - Write => Write, - RFSH_n => RFSH_n, - HALT_n => HALT_n, - WAIT_n => Wait_n, - INT_n => INT_n, - NMI_n => NMI_n, - RESET_n => RESET_n, - BUSRQ_n => BUSRQ_n, - BUSAK_n => BUSAK_n, - CLK_n => CLK, - A => A, - DInst => DI, - DI => DI_Reg, - DO => DO, - MC => MCycle, - TS => TState, - OUT0 => OUT0, - IntCycle_n => IntCycle_n - ); - - process (RESET_n, CLK) - begin - if RESET_n = '0' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - DI_Reg <= "00000000"; - elsif rising_edge(CLK) then - if CEN = '1' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - if MCycle = 1 then - if TState = 1 or (TState = 2 and Wait_n = '0') then - RD_n <= not IntCycle_n; - MREQ_n <= not IntCycle_n; - IORQ_n <= IntCycle_n; - end if; - if TState = 3 then - MREQ_n <= '0'; - end if; - else - if (TState = 1 or (TState = 2 and Wait_n = '0')) and NoRead = '0' and Write = '0' then - RD_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - if T2Write = 0 then - if TState = 2 and Write = '1' then - WR_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - else - if (TState = 1 or (TState = 2 and Wait_n = '0')) and Write = '1' then - WR_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - end if; - end if; - if TState = 2 and Wait_n = '1' then - DI_Reg <= DI; - end if; - end if; - end if; - end process; -end; +-- +-- Z80 compatible microprocessor core, synchronous top level +-- Different timing than the original z80 +-- Inputs needs to be synchronous and outputs may glitch +-- +-- Version : 0242 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0208 : First complete release +-- +-- 0210 : Fixed read with wait +-- +-- 0211 : Fixed interrupt cycle +-- +-- 0235 : Updated for T80 interface change +-- +-- 0236 : Added T2Write generic +-- +-- 0237 : Fixed T2Write with wait state +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use IEEE.STD_LOGIC_UNSIGNED.all; +use work.T80_Pack.all; + +entity T80s is + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 + IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle + ); + port( + RESET_n : in std_logic; + CLK : in std_logic; + CEN : in std_logic := '1'; + WAIT_n : in std_logic := '1'; + INT_n : in std_logic := '1'; + NMI_n : in std_logic := '1'; + BUSRQ_n : in std_logic := '1'; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + OUT0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0) + ); +end T80s; + +architecture rtl of T80s is + + signal IntCycle_n : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal IORQ : std_logic; + signal DI_Reg : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + +begin + + u0 : T80 + generic map( + Mode => Mode, + IOWait => IOWait) + port map( + CEN => CEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n, + HALT_n => HALT_n, + WAIT_n => Wait_n, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => RESET_n, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n, + CLK_n => CLK, + A => A, + DInst => DI, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + OUT0 => OUT0, + IntCycle_n => IntCycle_n + ); + + process (RESET_n, CLK) + begin + if RESET_n = '0' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + DI_Reg <= "00000000"; + elsif rising_edge(CLK) then + if CEN = '1' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + if MCycle = 1 then + if TState = 1 or (TState = 2 and Wait_n = '0') then + RD_n <= not IntCycle_n; + MREQ_n <= not IntCycle_n; + IORQ_n <= IntCycle_n; + end if; + if TState = 3 then + MREQ_n <= '0'; + end if; + else + if (TState = 1 or (TState = 2 and Wait_n = '0')) and NoRead = '0' and Write = '0' then + RD_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + if T2Write = 0 then + if TState = 2 and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + else + if (TState = 1 or (TState = 2 and Wait_n = '0')) and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + end if; + end if; + if TState = 2 and Wait_n = '1' then + DI_Reg <= DI; + end if; + end if; + end if; + end process; +end; diff --git a/modules/cpu-t80/T80se.vhd b/modules/cpu-t80/T80se.vhd index 1b0cb9b..1ee5910 100644 --- a/modules/cpu-t80/T80se.vhd +++ b/modules/cpu-t80/T80se.vhd @@ -1,192 +1,192 @@ --- **** --- T80(b) core. In an effort to merge and maintain bug fixes .... --- --- --- Ver 300 started tidyup --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) --- --- **** --- --- Z80 compatible microprocessor core, synchronous top level with clock enable --- Different timing than the original z80 --- Inputs needs to be synchronous and outputs may glitch --- --- Version : 0240 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0235 : First release --- --- 0236 : Added T2Write generic --- --- 0237 : Fixed T2Write with wait state --- --- 0238 : Updated for T80 interface change --- --- 0240 : Updated for T80 interface change --- --- 0242 : Updated for T80 interface change --- -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity T80se is - generic( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 - IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle - ); - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - CLKEN : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - MREQ_n : out std_logic; - IORQ_n : out std_logic; - RD_n : out std_logic; - WR_n : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0) - ); -end T80se; - -architecture rtl of T80se is - - signal IntCycle_n : std_logic; - signal NoRead : std_logic; - signal Write : std_logic; - signal IORQ : std_logic; - signal DI_Reg : std_logic_vector(7 downto 0); - signal MCycle : std_logic_vector(2 downto 0); - signal TState : std_logic_vector(2 downto 0); - -begin - - u0 : T80 - generic map( - Mode => Mode, - IOWait => IOWait) - port map( - CEN => CLKEN, - M1_n => M1_n, - IORQ => IORQ, - NoRead => NoRead, - Write => Write, - RFSH_n => RFSH_n, - HALT_n => HALT_n, - WAIT_n => Wait_n, - INT_n => INT_n, - NMI_n => NMI_n, - RESET_n => RESET_n, - BUSRQ_n => BUSRQ_n, - BUSAK_n => BUSAK_n, - CLK_n => CLK_n, - A => A, - DInst => DI, - DI => DI_Reg, - DO => DO, - MC => MCycle, - TS => TState, - IntCycle_n => IntCycle_n); - - process (RESET_n, CLK_n) - begin - if RESET_n = '0' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - DI_Reg <= "00000000"; - elsif CLK_n'event and CLK_n = '1' then - if CLKEN = '1' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - if MCycle = "001" then - if TState = "001" or (TState = "010" and Wait_n = '0') then - RD_n <= not IntCycle_n; - MREQ_n <= not IntCycle_n; - IORQ_n <= IntCycle_n; - end if; - if TState = "011" then - MREQ_n <= '0'; - end if; - else - if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then - RD_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - if T2Write = 0 then - if TState = "010" and Write = '1' then - WR_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - else - if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then - WR_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - end if; - end if; - if TState = "010" and Wait_n = '1' then - DI_Reg <= DI; - end if; - end if; - end if; - end process; - -end; +-- **** +-- T80(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 300 started tidyup +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- +-- Z80 compatible microprocessor core, synchronous top level with clock enable +-- Different timing than the original z80 +-- Inputs needs to be synchronous and outputs may glitch +-- +-- Version : 0240 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0235 : First release +-- +-- 0236 : Added T2Write generic +-- +-- 0237 : Fixed T2Write with wait state +-- +-- 0238 : Updated for T80 interface change +-- +-- 0240 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80se is + generic( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 + IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle + ); + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CLKEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0) + ); +end T80se; + +architecture rtl of T80se is + + signal IntCycle_n : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal IORQ : std_logic; + signal DI_Reg : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + +begin + + u0 : T80 + generic map( + Mode => Mode, + IOWait => IOWait) + port map( + CEN => CLKEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n, + HALT_n => HALT_n, + WAIT_n => Wait_n, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => RESET_n, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n, + CLK_n => CLK_n, + A => A, + DInst => DI, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n); + + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + DI_Reg <= "00000000"; + elsif CLK_n'event and CLK_n = '1' then + if CLKEN = '1' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + if MCycle = "001" then + if TState = "001" or (TState = "010" and Wait_n = '0') then + RD_n <= not IntCycle_n; + MREQ_n <= not IntCycle_n; + IORQ_n <= IntCycle_n; + end if; + if TState = "011" then + MREQ_n <= '0'; + end if; + else + if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then + RD_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + if T2Write = 0 then + if TState = "010" and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + else + if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + end if; + end if; + if TState = "010" and Wait_n = '1' then + DI_Reg <= DI; + end if; + end if; + end if; + end process; + +end; diff --git a/modules/cpu-t80/T80sed.vhd b/modules/cpu-t80/T80sed.vhd index 0c28ec2..3f301ec 100644 --- a/modules/cpu-t80/T80sed.vhd +++ b/modules/cpu-t80/T80sed.vhd @@ -1,179 +1,179 @@ --- **** --- T80(b) core. In an effort to merge and maintain bug fixes .... --- --- --- Ver 300 started tidyup --- MikeJ March 2005 --- Latest version from www.fpgaarcade.com (original www.opencores.org) --- --- **** --- ** CUSTOM 2 CLOCK MEMORY ACCESS FOR PACMAN, MIKEJ ** --- --- Z80 compatible microprocessor core, synchronous top level with clock enable --- Different timing than the original z80 --- Inputs needs to be synchronous and outputs may glitch --- --- Version : 0238 --- --- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- --- The latest version of this file can be found at: --- http://www.opencores.org/cvsweb.shtml/t80/ --- --- Limitations : --- --- File history : --- --- 0235 : First release --- --- 0236 : Added T2Write generic --- --- 0237 : Fixed T2Write with wait state --- --- 0238 : Updated for T80 interface change --- --- 0242 : Updated for T80 interface change --- - -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.numeric_std.all; -use work.T80_Pack.all; - -entity T80sed is - port( - RESET_n : in std_logic; - CLK_n : in std_logic; - CLKEN : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - MREQ_n : out std_logic; - IORQ_n : out std_logic; - RD_n : out std_logic; - WR_n : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0) - ); -end T80sed; - -architecture rtl of T80sed is - - signal IntCycle_n : std_logic; - signal NoRead : std_logic; - signal Write : std_logic; - signal IORQ : std_logic; - signal DI_Reg : std_logic_vector(7 downto 0); - signal MCycle : std_logic_vector(2 downto 0); - signal TState : std_logic_vector(2 downto 0); - -begin - - u0 : T80 - generic map( - Mode => 0, - IOWait => 1) - port map( - CEN => CLKEN, - M1_n => M1_n, - IORQ => IORQ, - NoRead => NoRead, - Write => Write, - RFSH_n => RFSH_n, - HALT_n => HALT_n, - WAIT_n => Wait_n, - INT_n => INT_n, - NMI_n => NMI_n, - RESET_n => RESET_n, - BUSRQ_n => BUSRQ_n, - BUSAK_n => BUSAK_n, - CLK_n => CLK_n, - A => A, - DInst => DI, - DI => DI_Reg, - DO => DO, - MC => MCycle, - TS => TState, - IntCycle_n => IntCycle_n); - - process (RESET_n, CLK_n) - begin - if RESET_n = '0' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - DI_Reg <= "00000000"; - elsif CLK_n'event and CLK_n = '1' then - if CLKEN = '1' then - RD_n <= '1'; - WR_n <= '1'; - IORQ_n <= '1'; - MREQ_n <= '1'; - if MCycle = "001" then - if TState = "001" or (TState = "010" and Wait_n = '0') then - RD_n <= not IntCycle_n; - MREQ_n <= not IntCycle_n; - IORQ_n <= IntCycle_n; - end if; - if TState = "011" then - MREQ_n <= '0'; - end if; - else - if (TState = "001" or TState = "010") and NoRead = '0' and Write = '0' then - RD_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - if ((TState = "001") or (TState = "010")) and Write = '1' then - WR_n <= '0'; - IORQ_n <= not IORQ; - MREQ_n <= IORQ; - end if; - end if; - if TState = "010" and Wait_n = '1' then - DI_Reg <= DI; - end if; - end if; - end if; - end process; - -end; +-- **** +-- T80(b) core. In an effort to merge and maintain bug fixes .... +-- +-- +-- Ver 300 started tidyup +-- MikeJ March 2005 +-- Latest version from www.fpgaarcade.com (original www.opencores.org) +-- +-- **** +-- ** CUSTOM 2 CLOCK MEMORY ACCESS FOR PACMAN, MIKEJ ** +-- +-- Z80 compatible microprocessor core, synchronous top level with clock enable +-- Different timing than the original z80 +-- Inputs needs to be synchronous and outputs may glitch +-- +-- Version : 0238 +-- +-- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +-- The latest version of this file can be found at: +-- http://www.opencores.org/cvsweb.shtml/t80/ +-- +-- Limitations : +-- +-- File history : +-- +-- 0235 : First release +-- +-- 0236 : Added T2Write generic +-- +-- 0237 : Fixed T2Write with wait state +-- +-- 0238 : Updated for T80 interface change +-- +-- 0242 : Updated for T80 interface change +-- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use work.T80_Pack.all; + +entity T80sed is + port( + RESET_n : in std_logic; + CLK_n : in std_logic; + CLKEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0) + ); +end T80sed; + +architecture rtl of T80sed is + + signal IntCycle_n : std_logic; + signal NoRead : std_logic; + signal Write : std_logic; + signal IORQ : std_logic; + signal DI_Reg : std_logic_vector(7 downto 0); + signal MCycle : std_logic_vector(2 downto 0); + signal TState : std_logic_vector(2 downto 0); + +begin + + u0 : T80 + generic map( + Mode => 0, + IOWait => 1) + port map( + CEN => CLKEN, + M1_n => M1_n, + IORQ => IORQ, + NoRead => NoRead, + Write => Write, + RFSH_n => RFSH_n, + HALT_n => HALT_n, + WAIT_n => Wait_n, + INT_n => INT_n, + NMI_n => NMI_n, + RESET_n => RESET_n, + BUSRQ_n => BUSRQ_n, + BUSAK_n => BUSAK_n, + CLK_n => CLK_n, + A => A, + DInst => DI, + DI => DI_Reg, + DO => DO, + MC => MCycle, + TS => TState, + IntCycle_n => IntCycle_n); + + process (RESET_n, CLK_n) + begin + if RESET_n = '0' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + DI_Reg <= "00000000"; + elsif CLK_n'event and CLK_n = '1' then + if CLKEN = '1' then + RD_n <= '1'; + WR_n <= '1'; + IORQ_n <= '1'; + MREQ_n <= '1'; + if MCycle = "001" then + if TState = "001" or (TState = "010" and Wait_n = '0') then + RD_n <= not IntCycle_n; + MREQ_n <= not IntCycle_n; + IORQ_n <= IntCycle_n; + end if; + if TState = "011" then + MREQ_n <= '0'; + end if; + else + if (TState = "001" or TState = "010") and NoRead = '0' and Write = '0' then + RD_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + if ((TState = "001") or (TState = "010")) and Write = '1' then + WR_n <= '0'; + IORQ_n <= not IORQ; + MREQ_n <= IORQ; + end if; + end if; + if TState = "010" and Wait_n = '1' then + DI_Reg <= DI; + end if; + end if; + end if; + end process; + +end; diff --git a/modules/cpu-t80/Z80.vhd b/modules/cpu-t80/Z80.vhd index db1ad94..22a5f81 100644 --- a/modules/cpu-t80/Z80.vhd +++ b/modules/cpu-t80/Z80.vhd @@ -1,135 +1,135 @@ -library IEEE; -use IEEE.std_logic_1164.all; -library work; -use work.T80_Pack.all; - -entity Z80 is port - ( - clk : in std_logic; - clk_en : in std_logic; - reset : in std_logic; - - addr : out std_logic_vector(15 downto 0); - datai : in std_logic_vector(7 downto 0); - datao : out std_logic_vector(7 downto 0); - - m1 : out std_logic; - mem_rd : out std_logic; - mem_wr : out std_logic; - io_rd : out std_logic; - io_wr : out std_logic; - - wait_n : in std_logic := '1'; - busrq_n : in std_logic := '1'; - intreq : in std_logic := '0'; - intvec : in std_logic_vector(7 downto 0); - intack : out std_logic; - nmi : in std_logic := '0' - ); -end Z80; - -architecture SYN of Z80 is - - component T80se is - generic - ( - Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB - T2Write : integer := 1 -- 0 => WR_n active in T3, /=0 => WR_n active in T2 - ); - port - ( - RESET_n : in std_logic; - CLK_n : in std_logic; - CLKEN : in std_logic; - WAIT_n : in std_logic; - INT_n : in std_logic; - NMI_n : in std_logic; - BUSRQ_n : in std_logic; - M1_n : out std_logic; - MREQ_n : out std_logic; - IORQ_n : out std_logic; - RD_n : out std_logic; - WR_n : out std_logic; - RFSH_n : out std_logic; - HALT_n : out std_logic; - BUSAK_n : out std_logic; - A : out std_logic_vector(15 downto 0); - DI : in std_logic_vector(7 downto 0); - DO : out std_logic_vector(7 downto 0) - ); - end component T80se; - - -- Signal Declarations - - signal reset_n : std_logic; - signal int_n : std_logic; - signal nmi_n : std_logic; - - signal z80_m1 : std_logic; - signal z80_memreq : std_logic; - signal z80_ioreq : std_logic; - signal z80_rd : std_logic; - signal z80_wr : std_logic; - signal z80_datai : std_logic_vector(7 downto 0); - - -- derived signals (outputs we need to read) - signal z80_memrd : std_logic; - signal z80_iord : std_logic; - signal fetch : std_logic; - - begin - - -- simple inversions - reset_n <= not reset; - int_n <= not intreq; - nmi_n <= not nmi; - - -- direct-connect (outputs we need to read) - m1 <= z80_m1; - mem_rd <= z80_memrd; - io_rd <= z80_iord; - - -- memory signals - z80_memrd <= z80_memreq nor z80_rd; - mem_wr <= z80_memreq nor z80_wr; - - -- io signals - z80_iord <= z80_ioreq nor z80_rd; - io_wr <= z80_ioreq nor z80_wr; - - -- other signals - fetch <= z80_m1 nor z80_memreq; - intack <= z80_m1 nor z80_ioreq; - - -- data in mux - z80_datai <= intvec when ((z80_memrd or z80_iord) = '0') else - datai; - - Z80_uP : T80se - generic map - ( - Mode => 0 -- Z80 - ) - port map - ( - RESET_n => reset_n, - CLK_n => clk, - CLKEN => clk_en, - WAIT_n => wait_n, - INT_n => int_n, - NMI_n => nmi_n, - BUSRQ_n => busrq_n, - M1_n => z80_m1, - MREQ_n => z80_memreq, - IORQ_n => z80_ioreq, - RD_n => z80_rd, - WR_n => z80_wr, - RFSH_n => open, - HALT_n => open, - BUSAK_n => open, - A => addr, - DI => z80_datai, - DO => datao - ); - -end architecture SYN; +library IEEE; +use IEEE.std_logic_1164.all; +library work; +use work.T80_Pack.all; + +entity Z80 is port + ( + clk : in std_logic; + clk_en : in std_logic; + reset : in std_logic; + + addr : out std_logic_vector(15 downto 0); + datai : in std_logic_vector(7 downto 0); + datao : out std_logic_vector(7 downto 0); + + m1 : out std_logic; + mem_rd : out std_logic; + mem_wr : out std_logic; + io_rd : out std_logic; + io_wr : out std_logic; + + wait_n : in std_logic := '1'; + busrq_n : in std_logic := '1'; + intreq : in std_logic := '0'; + intvec : in std_logic_vector(7 downto 0); + intack : out std_logic; + nmi : in std_logic := '0' + ); +end Z80; + +architecture SYN of Z80 is + + component T80se is + generic + ( + Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB + T2Write : integer := 1 -- 0 => WR_n active in T3, /=0 => WR_n active in T2 + ); + port + ( + RESET_n : in std_logic; + CLK_n : in std_logic; + CLKEN : in std_logic; + WAIT_n : in std_logic; + INT_n : in std_logic; + NMI_n : in std_logic; + BUSRQ_n : in std_logic; + M1_n : out std_logic; + MREQ_n : out std_logic; + IORQ_n : out std_logic; + RD_n : out std_logic; + WR_n : out std_logic; + RFSH_n : out std_logic; + HALT_n : out std_logic; + BUSAK_n : out std_logic; + A : out std_logic_vector(15 downto 0); + DI : in std_logic_vector(7 downto 0); + DO : out std_logic_vector(7 downto 0) + ); + end component T80se; + + -- Signal Declarations + + signal reset_n : std_logic; + signal int_n : std_logic; + signal nmi_n : std_logic; + + signal z80_m1 : std_logic; + signal z80_memreq : std_logic; + signal z80_ioreq : std_logic; + signal z80_rd : std_logic; + signal z80_wr : std_logic; + signal z80_datai : std_logic_vector(7 downto 0); + + -- derived signals (outputs we need to read) + signal z80_memrd : std_logic; + signal z80_iord : std_logic; + signal fetch : std_logic; + + begin + + -- simple inversions + reset_n <= not reset; + int_n <= not intreq; + nmi_n <= not nmi; + + -- direct-connect (outputs we need to read) + m1 <= z80_m1; + mem_rd <= z80_memrd; + io_rd <= z80_iord; + + -- memory signals + z80_memrd <= z80_memreq nor z80_rd; + mem_wr <= z80_memreq nor z80_wr; + + -- io signals + z80_iord <= z80_ioreq nor z80_rd; + io_wr <= z80_ioreq nor z80_wr; + + -- other signals + fetch <= z80_m1 nor z80_memreq; + intack <= z80_m1 nor z80_ioreq; + + -- data in mux + z80_datai <= intvec when ((z80_memrd or z80_iord) = '0') else + datai; + + Z80_uP : T80se + generic map + ( + Mode => 0 -- Z80 + ) + port map + ( + RESET_n => reset_n, + CLK_n => clk, + CLKEN => clk_en, + WAIT_n => wait_n, + INT_n => int_n, + NMI_n => nmi_n, + BUSRQ_n => busrq_n, + M1_n => z80_m1, + MREQ_n => z80_memreq, + IORQ_n => z80_ioreq, + RD_n => z80_rd, + WR_n => z80_wr, + RFSH_n => open, + HALT_n => open, + BUSAK_n => open, + A => addr, + DI => z80_datai, + DO => datao + ); + +end architecture SYN; diff --git a/modules/cpu-t80/index.qip b/modules/cpu-t80/index.qip index cbae7f7..6a1c62a 100644 --- a/modules/cpu-t80/index.qip +++ b/modules/cpu-t80/index.qip @@ -1,13 +1,13 @@ -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "GBse.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80pa.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80s.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80se.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80a.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80as.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80sed.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T8080se.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80_Reg.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80_MCode.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80_ALU.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "GBse.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80pa.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80s.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80se.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80a.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80as.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80sed.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T8080se.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80_Reg.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80_MCode.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80_ALU.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80.vhd"] set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80_Pack.vhd"] \ No newline at end of file diff --git a/modules/sound-jt49/filter/jt49_dcrm.v b/modules/sound-jt49/filter/jt49_dcrm.v index e84f2b1..1ec891d 100644 --- a/modules/sound-jt49/filter/jt49_dcrm.v +++ b/modules/sound-jt49/filter/jt49_dcrm.v @@ -1,56 +1,56 @@ -/* This file is part of JT49. - - JT49 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. - - JT49 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 JT49. If not, see . - - Author: Jose Tejada Gomez. Twitter: @topapate - Version: 1.0 - Date: 15-Jan-2019 - - */ - -// DC removal filter -// input is unsigned -// output is signed - -module jt49_dcrm( - input clk, - input cen, - input rst, - input [7:0] din, - output reg signed [7:0] dout -); - -wire signed [7:0] ave0, ave1; - -jt49_mave u_mave0( - .clk ( clk ), - .cen ( cen ), - .rst ( rst ), - .din ( {1'b0, din[7:1] } ), - .dout ( ave0 ) -); - -jt49_mave u_mave1( - .clk ( clk ), - .cen ( cen ), - .rst ( rst ), - .din ( ave0 ), - .dout ( ave1 ) -); - -always @(posedge clk) - if( cen ) - dout <= ({1'b0,din} - {ave1,1'b0})>>>1; - +/* This file is part of JT49. + + JT49 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. + + JT49 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 JT49. If not, see . + + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 15-Jan-2019 + + */ + +// DC removal filter +// input is unsigned +// output is signed + +module jt49_dcrm( + input clk, + input cen, + input rst, + input [7:0] din, + output reg signed [7:0] dout +); + +wire signed [7:0] ave0, ave1; + +jt49_mave u_mave0( + .clk ( clk ), + .cen ( cen ), + .rst ( rst ), + .din ( {1'b0, din[7:1] } ), + .dout ( ave0 ) +); + +jt49_mave u_mave1( + .clk ( clk ), + .cen ( cen ), + .rst ( rst ), + .din ( ave0 ), + .dout ( ave1 ) +); + +always @(posedge clk) + if( cen ) + dout <= ({1'b0,din} - {ave1,1'b0})>>>1; + endmodule \ No newline at end of file diff --git a/modules/sound-jt49/filter/jt49_dcrm2.v b/modules/sound-jt49/filter/jt49_dcrm2.v index 6646a30..1668225 100644 --- a/modules/sound-jt49/filter/jt49_dcrm2.v +++ b/modules/sound-jt49/filter/jt49_dcrm2.v @@ -1,64 +1,64 @@ -/* This file is part of JT49. - - JT49 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. - - JT49 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 JT49. If not, see . - - Author: Jose Tejada Gomez. Twitter: @topapate - Version: 1.0 - Date: 15-Jan-2019 - - */ - -// DC removal filter -// input is unsigned -// output is signed - -module jt49_dcrm2 #(parameter sw=8) ( - input clk, - input cen, - input rst, - input [sw-1:0] din, - output signed [sw-1:0] dout -); - -localparam dw=10; // width of the decimal portion - -reg signed [sw+dw:0] integ, exact, error; -//reg signed [2*(9+dw)-1:0] mult; -// wire signed [sw+dw:0] plus1 = { {sw+dw{1'b0}},1'b1}; -reg signed [sw:0] pre_dout; -// reg signed [sw+dw:0] dout_ext; -reg signed [sw:0] q; - -always @(*) begin - exact = integ+error; - q = exact[sw+dw:dw]; - pre_dout = { 1'b0, din } - q; - //dout_ext = { pre_dout, {dw{1'b0}} }; - //mult = dout_ext; -end - -assign dout = pre_dout[sw-1:0]; - -always @(posedge clk) - if( rst ) begin - integ <= {sw+dw+1{1'b0}}; - error <= {sw+dw+1{1'b0}}; - end else if( cen ) begin - /* verilator lint_off WIDTH */ - integ <= integ + pre_dout; //mult[sw+dw*2:dw]; - /* verilator lint_on WIDTH */ - error <= exact-{q, {dw{1'b0}}}; - end - +/* This file is part of JT49. + + JT49 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. + + JT49 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 JT49. If not, see . + + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 15-Jan-2019 + + */ + +// DC removal filter +// input is unsigned +// output is signed + +module jt49_dcrm2 #(parameter sw=8) ( + input clk, + input cen, + input rst, + input [sw-1:0] din, + output signed [sw-1:0] dout +); + +localparam dw=10; // width of the decimal portion + +reg signed [sw+dw:0] integ, exact, error; +//reg signed [2*(9+dw)-1:0] mult; +// wire signed [sw+dw:0] plus1 = { {sw+dw{1'b0}},1'b1}; +reg signed [sw:0] pre_dout; +// reg signed [sw+dw:0] dout_ext; +reg signed [sw:0] q; + +always @(*) begin + exact = integ+error; + q = exact[sw+dw:dw]; + pre_dout = { 1'b0, din } - q; + //dout_ext = { pre_dout, {dw{1'b0}} }; + //mult = dout_ext; +end + +assign dout = pre_dout[sw-1:0]; + +always @(posedge clk) + if( rst ) begin + integ <= {sw+dw+1{1'b0}}; + error <= {sw+dw+1{1'b0}}; + end else if( cen ) begin + /* verilator lint_off WIDTH */ + integ <= integ + pre_dout; //mult[sw+dw*2:dw]; + /* verilator lint_on WIDTH */ + error <= exact-{q, {dw{1'b0}}}; + end + endmodule \ No newline at end of file diff --git a/modules/sound-jt49/filter/jt49_dly.v b/modules/sound-jt49/filter/jt49_dly.v index 7142ec9..40e3c72 100644 --- a/modules/sound-jt49/filter/jt49_dly.v +++ b/modules/sound-jt49/filter/jt49_dly.v @@ -1,67 +1,67 @@ -/* This file is part of JT49. - - JT49 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. - - JT49 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 JT49. If not, see . - - Author: Jose Tejada Gomez. Twitter: @topapate - Version: 1.0 - Date: 15-Jan-2019 - - */ - -// Delay stage -// use for long delays - -module jt49_dly #(parameter dw=8, depth=10)( - input clk, - input cen, - input rst, - input [7:0] din, - output reg [7:0] dout, - output reg [7:0] pre_dout - -); - -reg [depth-1:0] rdpos, wrpos; - - -// memory -reg [dw-1:0] ram[0:2**depth-1]; -always @(posedge clk) - if(rst) - pre_dout <= {dw{1'b0}}; - else begin - pre_dout <= ram[rdpos]; - if( cen ) ram[wrpos] <= din; - end - -`ifdef SIMULATION -integer k; -initial begin - for(k=0;k<=2**depth-1;k=k+1) - ram[k] = 0; -end -`endif - -always @(posedge clk) - if( rst ) begin - rdpos <= { {depth-1{1'b0}}, 1'b1}; - wrpos <= {depth{1'b1}}; - dout <= {dw{1'b0}}; - end else if(cen) begin - dout <= pre_dout; - rdpos <= rdpos+1'b1; - wrpos <= wrpos+1'b1; - end - +/* This file is part of JT49. + + JT49 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. + + JT49 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 JT49. If not, see . + + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 15-Jan-2019 + + */ + +// Delay stage +// use for long delays + +module jt49_dly #(parameter dw=8, depth=10)( + input clk, + input cen, + input rst, + input [7:0] din, + output reg [7:0] dout, + output reg [7:0] pre_dout + +); + +reg [depth-1:0] rdpos, wrpos; + + +// memory +reg [dw-1:0] ram[0:2**depth-1]; +always @(posedge clk) + if(rst) + pre_dout <= {dw{1'b0}}; + else begin + pre_dout <= ram[rdpos]; + if( cen ) ram[wrpos] <= din; + end + +`ifdef SIMULATION +integer k; +initial begin + for(k=0;k<=2**depth-1;k=k+1) + ram[k] = 0; +end +`endif + +always @(posedge clk) + if( rst ) begin + rdpos <= { {depth-1{1'b0}}, 1'b1}; + wrpos <= {depth{1'b1}}; + dout <= {dw{1'b0}}; + end else if(cen) begin + dout <= pre_dout; + rdpos <= rdpos+1'b1; + wrpos <= wrpos+1'b1; + end + endmodule // jt49_dly \ No newline at end of file diff --git a/modules/sound-jt49/filter/jt49_mave.v b/modules/sound-jt49/filter/jt49_mave.v index 2d02393..e109335 100644 --- a/modules/sound-jt49/filter/jt49_mave.v +++ b/modules/sound-jt49/filter/jt49_mave.v @@ -1,60 +1,60 @@ -/* This file is part of JT49. - - JT49 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. - - JT49 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 JT49. If not, see . - - Author: Jose Tejada Gomez. Twitter: @topapate - Version: 1.0 - Date: 15-Jan-2019 - - */ - -// Moving averager - -module jt49_mave #(parameter depth=8, dw=8)( - input clk, - input cen, - input rst, - input signed [dw-1:0] din, - output signed [dw-1:0] dout -); - -wire [dw-1:0] dly0; -wire [dw-1:0] pre_dly0; - -jt49_dly #(.depth(depth),.dw(dw)) u_dly0( - .clk ( clk ), - .cen ( cen ), - .rst ( rst ), - .din ( din ), - .dout ( dly0 ), - .pre_dout ( pre_dly0 ) -); - -// moving average -// D=2048 -reg signed [dw:0] diff; -reg signed [dw+depth-1:0] sum; - - -always @(posedge clk) - if( rst ) begin - diff <= {dw+1{1'd0}}; - sum <= {dw+depth+1{1'd0}}; - end else if(cen) begin - diff <= {1'b0,din } - { 1'b0, dly0 }; - sum <= { {depth{diff[dw]}}, diff } + sum; - end -assign dout = sum[dw+depth-1:depth]; - +/* This file is part of JT49. + + JT49 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. + + JT49 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 JT49. If not, see . + + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 15-Jan-2019 + + */ + +// Moving averager + +module jt49_mave #(parameter depth=8, dw=8)( + input clk, + input cen, + input rst, + input signed [dw-1:0] din, + output signed [dw-1:0] dout +); + +wire [dw-1:0] dly0; +wire [dw-1:0] pre_dly0; + +jt49_dly #(.depth(depth),.dw(dw)) u_dly0( + .clk ( clk ), + .cen ( cen ), + .rst ( rst ), + .din ( din ), + .dout ( dly0 ), + .pre_dout ( pre_dly0 ) +); + +// moving average +// D=2048 +reg signed [dw:0] diff; +reg signed [dw+depth-1:0] sum; + + +always @(posedge clk) + if( rst ) begin + diff <= {dw+1{1'd0}}; + sum <= {dw+depth+1{1'd0}}; + end else if(cen) begin + diff <= {1'b0,din } - { 1'b0, dly0 }; + sum <= { {depth{diff[dw]}}, diff } + sum; + end +assign dout = sum[dw+depth-1:depth]; + endmodule \ No newline at end of file diff --git a/modules/sound-jt49/index.qip b/modules/sound-jt49/index.qip index 6568ae9..c4c9a93 100644 --- a/modules/sound-jt49/index.qip +++ b/modules/sound-jt49/index.qip @@ -1,7 +1,7 @@ -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_bus.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_div.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_cen.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_eg.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_exp.v ] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_noise.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_bus.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_div.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_cen.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_eg.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_exp.v ] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) jt49_noise.v ] diff --git a/modules/sound-jt49/jt49.v b/modules/sound-jt49/jt49.v index ae30327..b431798 100644 --- a/modules/sound-jt49/jt49.v +++ b/modules/sound-jt49/jt49.v @@ -1,252 +1,252 @@ -/* This file is part of JT49. - - JT49 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. - - JT49 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 JT49. If not, see . - - Author: Jose Tejada Gomez. Twitter: @topapate - Version: 1.0 - Date: 10-Nov-2018 - - Based on sqmusic, by the same author - - */ - -module jt49 ( // note that input ports are not multiplexed - input rst_n, - input clk, // signal on positive edge - input clk_en /* synthesis direct_enable = 1 */, - input [3:0] addr, - input cs_n, - input wr_n, // write - input [7:0] din, - input sel, // if sel is low, the clock is divided by 2 - output reg [7:0] dout, - output reg [9:0] sound, // combined channel output - output reg [7:0] A, // linearised channel output - output reg [7:0] B, - output reg [7:0] C, - output sample, - - input [7:0] IOA_in, - output [7:0] IOA_out, - - input [7:0] IOB_in, - output [7:0] IOB_out -); - -parameter [1:0] COMP=2'b00; -parameter CLKDIV=3; -wire [1:0] comp = COMP; - -reg [7:0] regarray[15:0]; -wire [7:0] port_A, port_B; - -wire [4:0] envelope; -wire bitA, bitB, bitC; -wire noise; -reg Amix, Bmix, Cmix; - -wire cen16, cen256; - -assign IOA_out = regarray[7][6] ? regarray[14] : 8'hFF; -assign IOB_out = regarray[7][7] ? regarray[15] : 8'hFF; -assign port_A = !regarray[7][6] ? IOA_in : IOA_out & IOA_in; -assign port_B = !regarray[7][7] ? IOB_in : IOB_out & IOB_in; -assign sample = cen16; - -jt49_cen #(.CLKDIV(CLKDIV)) u_cen( - .clk ( clk ), - .rst_n ( rst_n ), - .cen ( clk_en ), - .sel ( sel ), - .cen16 ( cen16 ), - .cen256 ( cen256 ) -); - -// internal modules operate at clk/16 -jt49_div #(12) u_chA( - .clk ( clk ), - .rst_n ( rst_n ), - .cen ( cen16 ), - .period ( {regarray[1][3:0], regarray[0][7:0] } ), - .div ( bitA ) -); - -jt49_div #(12) u_chB( - .clk ( clk ), - .rst_n ( rst_n ), - .cen ( cen16 ), - .period ( {regarray[3][3:0], regarray[2][7:0] } ), - .div ( bitB ) -); - -jt49_div #(12) u_chC( - .clk ( clk ), - .rst_n ( rst_n ), - .cen ( cen16 ), - .period ( {regarray[5][3:0], regarray[4][7:0] } ), - .div ( bitC ) -); - -jt49_noise u_ng( - .clk ( clk ), - .cen ( cen16 ), - .rst_n ( rst_n ), - .period ( regarray[6][4:0] ), - .noise ( noise ) -); - -// envelope generator -wire eg_step; -wire [15:0] eg_period = {regarray[4'hc],regarray[4'hb]}; -wire null_period = eg_period == 16'h0; - -jt49_div #(16) u_envdiv( - .clk ( clk ), - .cen ( cen256 ), - .rst_n ( rst_n ), - .period ( eg_period ), - .div ( eg_step ) -); - -reg eg_restart; - -jt49_eg u_env( - .clk ( clk ), - .cen ( cen256 ), - .step ( eg_step ), - .rst_n ( rst_n ), - .restart ( eg_restart ), - .null_period( null_period ), - .ctrl ( regarray[4'hD][3:0] ), - .env ( envelope ) -); - -reg [4:0] logA, logB, logC, log; -wire [7:0] lin; - -jt49_exp u_exp( - .clk ( clk ), - .comp ( comp ), - .din ( log ), - .dout ( lin ) -); - -wire [4:0] volA = { regarray[ 8][3:0], regarray[ 8][3] }; -wire [4:0] volB = { regarray[ 9][3:0], regarray[ 9][3] }; -wire [4:0] volC = { regarray[10][3:0], regarray[10][3] }; -wire use_envA = regarray[ 8][4]; -wire use_envB = regarray[ 9][4]; -wire use_envC = regarray[10][4]; -wire use_noA = regarray[ 7][3]; -wire use_noB = regarray[ 7][4]; -wire use_noC = regarray[ 7][5]; - -reg [3:0] acc_st; - -always @(posedge clk) if( clk_en ) begin - Amix <= (noise|use_noA) & (bitA|regarray[7][0]); - Bmix <= (noise|use_noB) & (bitB|regarray[7][1]); - Cmix <= (noise|use_noC) & (bitC|regarray[7][2]); - - logA <= !Amix ? 5'd0 : (use_envA ? envelope : volA ); - logB <= !Bmix ? 5'd0 : (use_envB ? envelope : volB ); - logC <= !Cmix ? 5'd0 : (use_envC ? envelope : volC ); -end - -reg [9:0] acc; - -always @(posedge clk, negedge rst_n) begin - if( !rst_n ) begin - acc_st <= 4'b1; - acc <= 10'd0; - A <= 8'd0; - B <= 8'd0; - C <= 8'd0; - sound <= 10'd0; - end else if(clk_en) begin - acc_st <= { acc_st[2:0], acc_st[3] }; - acc <= acc + {2'b0,lin}; - case( acc_st ) - 4'b0001: begin - log <= logA; - acc <= 10'd0; - sound <= acc; - end - 4'b0010: begin - A <= lin; - log <= logB; - end - 4'b0100: begin - B <= lin; - log <= logC; - end - 4'b1000: begin // last sum - C <= lin; - end - default:; - endcase - end -end - -reg [7:0] read_mask; - -always @(*) - case(addr) - 4'h0,4'h2,4'h4,4'h7,4'hb,4'hc,4'he,4'hf: - read_mask = 8'hff; - 4'h1,4'h3,4'h5,4'hd: - read_mask = 8'h0f; - 4'h6,4'h8,4'h9,4'ha: - read_mask = 8'h1f; - endcase // addr - -// register array -wire write; -reg last_write; -wire wr_edge = write & ~last_write; - -assign write = !wr_n && !cs_n; - -always @(posedge clk, negedge rst_n) begin - if( !rst_n ) begin - dout <= 8'd0; - last_write <= 0; - eg_restart <= 0; - regarray[0]<=8'd0; regarray[4]<=8'd0; regarray[ 8]<=8'd0; regarray[12]<=8'd0; - regarray[1]<=8'd0; regarray[5]<=8'd0; regarray[ 9]<=8'd0; regarray[13]<=8'd0; - regarray[2]<=8'd0; regarray[6]<=8'd0; regarray[10]<=8'd0; regarray[14]<=8'hFF; - regarray[3]<=8'd0; regarray[7]<=8'hFF; regarray[11]<=8'd0; regarray[15]<=8'hFF; - end else begin - last_write <= write; - // Data read - case( addr ) - 4'he: dout <= port_A; - 4'hf: dout <= port_B; - default: dout <= regarray[ addr ] & read_mask; - endcase - // Data write - if( write ) begin - case( addr ) - 4'he: ; - 4'hf: if (regarray[7][7]) regarray[addr] <= din; - default: regarray[addr] <= din; - endcase - if ( addr == 4'hD && wr_edge ) eg_restart <= 1; - end else begin - eg_restart <= 0; - end - end -end - -endmodule +/* This file is part of JT49. + + JT49 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. + + JT49 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 JT49. If not, see . + + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 10-Nov-2018 + + Based on sqmusic, by the same author + + */ + +module jt49 ( // note that input ports are not multiplexed + input rst_n, + input clk, // signal on positive edge + input clk_en /* synthesis direct_enable = 1 */, + input [3:0] addr, + input cs_n, + input wr_n, // write + input [7:0] din, + input sel, // if sel is low, the clock is divided by 2 + output reg [7:0] dout, + output reg [9:0] sound, // combined channel output + output reg [7:0] A, // linearised channel output + output reg [7:0] B, + output reg [7:0] C, + output sample, + + input [7:0] IOA_in, + output [7:0] IOA_out, + + input [7:0] IOB_in, + output [7:0] IOB_out +); + +parameter [1:0] COMP=2'b00; +parameter CLKDIV=3; +wire [1:0] comp = COMP; + +reg [7:0] regarray[15:0]; +wire [7:0] port_A, port_B; + +wire [4:0] envelope; +wire bitA, bitB, bitC; +wire noise; +reg Amix, Bmix, Cmix; + +wire cen16, cen256; + +assign IOA_out = regarray[7][6] ? regarray[14] : 8'hFF; +assign IOB_out = regarray[7][7] ? regarray[15] : 8'hFF; +assign port_A = !regarray[7][6] ? IOA_in : IOA_out & IOA_in; +assign port_B = !regarray[7][7] ? IOB_in : IOB_out & IOB_in; +assign sample = cen16; + +jt49_cen #(.CLKDIV(CLKDIV)) u_cen( + .clk ( clk ), + .rst_n ( rst_n ), + .cen ( clk_en ), + .sel ( sel ), + .cen16 ( cen16 ), + .cen256 ( cen256 ) +); + +// internal modules operate at clk/16 +jt49_div #(12) u_chA( + .clk ( clk ), + .rst_n ( rst_n ), + .cen ( cen16 ), + .period ( {regarray[1][3:0], regarray[0][7:0] } ), + .div ( bitA ) +); + +jt49_div #(12) u_chB( + .clk ( clk ), + .rst_n ( rst_n ), + .cen ( cen16 ), + .period ( {regarray[3][3:0], regarray[2][7:0] } ), + .div ( bitB ) +); + +jt49_div #(12) u_chC( + .clk ( clk ), + .rst_n ( rst_n ), + .cen ( cen16 ), + .period ( {regarray[5][3:0], regarray[4][7:0] } ), + .div ( bitC ) +); + +jt49_noise u_ng( + .clk ( clk ), + .cen ( cen16 ), + .rst_n ( rst_n ), + .period ( regarray[6][4:0] ), + .noise ( noise ) +); + +// envelope generator +wire eg_step; +wire [15:0] eg_period = {regarray[4'hc],regarray[4'hb]}; +wire null_period = eg_period == 16'h0; + +jt49_div #(16) u_envdiv( + .clk ( clk ), + .cen ( cen256 ), + .rst_n ( rst_n ), + .period ( eg_period ), + .div ( eg_step ) +); + +reg eg_restart; + +jt49_eg u_env( + .clk ( clk ), + .cen ( cen256 ), + .step ( eg_step ), + .rst_n ( rst_n ), + .restart ( eg_restart ), + .null_period( null_period ), + .ctrl ( regarray[4'hD][3:0] ), + .env ( envelope ) +); + +reg [4:0] logA, logB, logC, log; +wire [7:0] lin; + +jt49_exp u_exp( + .clk ( clk ), + .comp ( comp ), + .din ( log ), + .dout ( lin ) +); + +wire [4:0] volA = { regarray[ 8][3:0], regarray[ 8][3] }; +wire [4:0] volB = { regarray[ 9][3:0], regarray[ 9][3] }; +wire [4:0] volC = { regarray[10][3:0], regarray[10][3] }; +wire use_envA = regarray[ 8][4]; +wire use_envB = regarray[ 9][4]; +wire use_envC = regarray[10][4]; +wire use_noA = regarray[ 7][3]; +wire use_noB = regarray[ 7][4]; +wire use_noC = regarray[ 7][5]; + +reg [3:0] acc_st; + +always @(posedge clk) if( clk_en ) begin + Amix <= (noise|use_noA) & (bitA|regarray[7][0]); + Bmix <= (noise|use_noB) & (bitB|regarray[7][1]); + Cmix <= (noise|use_noC) & (bitC|regarray[7][2]); + + logA <= !Amix ? 5'd0 : (use_envA ? envelope : volA ); + logB <= !Bmix ? 5'd0 : (use_envB ? envelope : volB ); + logC <= !Cmix ? 5'd0 : (use_envC ? envelope : volC ); +end + +reg [9:0] acc; + +always @(posedge clk, negedge rst_n) begin + if( !rst_n ) begin + acc_st <= 4'b1; + acc <= 10'd0; + A <= 8'd0; + B <= 8'd0; + C <= 8'd0; + sound <= 10'd0; + end else if(clk_en) begin + acc_st <= { acc_st[2:0], acc_st[3] }; + acc <= acc + {2'b0,lin}; + case( acc_st ) + 4'b0001: begin + log <= logA; + acc <= 10'd0; + sound <= acc; + end + 4'b0010: begin + A <= lin; + log <= logB; + end + 4'b0100: begin + B <= lin; + log <= logC; + end + 4'b1000: begin // last sum + C <= lin; + end + default:; + endcase + end +end + +reg [7:0] read_mask; + +always @(*) + case(addr) + 4'h0,4'h2,4'h4,4'h7,4'hb,4'hc,4'he,4'hf: + read_mask = 8'hff; + 4'h1,4'h3,4'h5,4'hd: + read_mask = 8'h0f; + 4'h6,4'h8,4'h9,4'ha: + read_mask = 8'h1f; + endcase // addr + +// register array +wire write; +reg last_write; +wire wr_edge = write & ~last_write; + +assign write = !wr_n && !cs_n; + +always @(posedge clk, negedge rst_n) begin + if( !rst_n ) begin + dout <= 8'd0; + last_write <= 0; + eg_restart <= 0; + regarray[0]<=8'd0; regarray[4]<=8'd0; regarray[ 8]<=8'd0; regarray[12]<=8'd0; + regarray[1]<=8'd0; regarray[5]<=8'd0; regarray[ 9]<=8'd0; regarray[13]<=8'd0; + regarray[2]<=8'd0; regarray[6]<=8'd0; regarray[10]<=8'd0; regarray[14]<=8'hFF; + regarray[3]<=8'd0; regarray[7]<=8'hFF; regarray[11]<=8'd0; regarray[15]<=8'hFF; + end else begin + last_write <= write; + // Data read + case( addr ) + 4'he: dout <= port_A; + 4'hf: dout <= port_B; + default: dout <= regarray[ addr ] & read_mask; + endcase + // Data write + if( write ) begin + case( addr ) + 4'he: ; + 4'hf: if (regarray[7][7]) regarray[addr] <= din; + default: regarray[addr] <= din; + endcase + if ( addr == 4'hD && wr_edge ) eg_restart <= 1; + end else begin + eg_restart <= 0; + end + end +end + +endmodule diff --git a/modules/sound-jt49/jt49_bus.v b/modules/sound-jt49/jt49_bus.v index b7639d9..8966c2a 100644 --- a/modules/sound-jt49/jt49_bus.v +++ b/modules/sound-jt49/jt49_bus.v @@ -1,101 +1,101 @@ -/* This file is part of JT49. - - JT49 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. - - JT49 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 JT49. If not, see . - - Author: Jose Tejada Gomez. Twitter: @topapate - Version: 1.0 - Date: 28-Jan-2019 - - Based on sqmusic, by the same author - - */ - -// This is a wrapper with the BDIR/BC1 pins - -module jt49_bus ( // note that input ports are not multiplexed - input rst_n, - input clk, // signal on positive edge - input clk_en /* synthesis direct_enable = 1 */, - // bus control pins of original chip - input bdir, - input bc1, - input [7:0] din, - - input sel, // if sel is low, the clock is divided by 2 - output [7:0] dout, - output [9:0] sound, // combined channel output - output [7:0] A, // linearised channel output - output [7:0] B, - output [7:0] C, - output sample, - - input [7:0] IOA_in, - output [7:0] IOA_out, - - input [7:0] IOB_in, - output [7:0] IOB_out -); - -parameter [1:0] COMP=2'b00; - -reg wr_n, cs_n; -reg [3:0] addr; -reg addr_ok; -reg [7:0] din_latch; - -always @(posedge clk) - if( !rst_n ) begin - wr_n <= 1'b1; - cs_n <= 1'b1; - addr <= 4'd0; - addr_ok <= 1'b1; - end else begin // I/O cannot use clk_en - // addr must be - case( {bdir,bc1} ) - 2'b00: { wr_n, cs_n } <= 2'b11; - 2'b01: { wr_n, cs_n } <= addr_ok ? 2'b10 : 2'b11; - 2'b10: begin - { wr_n, cs_n } <= addr_ok ? 2'b00 : 2'b11; - din_latch <= din; - end - 2'b11: begin - { wr_n, cs_n } <= 2'b11; - addr <= din[3:0]; - addr_ok <= din[7:4] == 4'd0; - end - endcase // {bdir,bc1} - end - -jt49 #(.COMP(COMP)) u_jt49( // note that input ports are not multiplexed - .rst_n ( rst_n ), - .clk ( clk ), // signal on positive edge - .clk_en ( clk_en ), // clock enable on negative edge - .addr ( addr[3:0] ), - .cs_n ( cs_n ), - .wr_n ( wr_n ), // write - .din ( din_latch ), - .sel ( sel ), // if sel is low, the clock is divided by 2 - .dout ( dout ), - .sound ( sound ), // combined channel output - .sample ( sample ), - .A ( A ), // linearised channel output - .B ( B ), - .C ( C ), - .IOA_in ( IOA_in ), - .IOA_out( IOA_out ), - .IOB_in ( IOB_in ), - .IOB_out( IOB_out ) -); - +/* This file is part of JT49. + + JT49 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. + + JT49 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 JT49. If not, see . + + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 28-Jan-2019 + + Based on sqmusic, by the same author + + */ + +// This is a wrapper with the BDIR/BC1 pins + +module jt49_bus ( // note that input ports are not multiplexed + input rst_n, + input clk, // signal on positive edge + input clk_en /* synthesis direct_enable = 1 */, + // bus control pins of original chip + input bdir, + input bc1, + input [7:0] din, + + input sel, // if sel is low, the clock is divided by 2 + output [7:0] dout, + output [9:0] sound, // combined channel output + output [7:0] A, // linearised channel output + output [7:0] B, + output [7:0] C, + output sample, + + input [7:0] IOA_in, + output [7:0] IOA_out, + + input [7:0] IOB_in, + output [7:0] IOB_out +); + +parameter [1:0] COMP=2'b00; + +reg wr_n, cs_n; +reg [3:0] addr; +reg addr_ok; +reg [7:0] din_latch; + +always @(posedge clk) + if( !rst_n ) begin + wr_n <= 1'b1; + cs_n <= 1'b1; + addr <= 4'd0; + addr_ok <= 1'b1; + end else begin // I/O cannot use clk_en + // addr must be + case( {bdir,bc1} ) + 2'b00: { wr_n, cs_n } <= 2'b11; + 2'b01: { wr_n, cs_n } <= addr_ok ? 2'b10 : 2'b11; + 2'b10: begin + { wr_n, cs_n } <= addr_ok ? 2'b00 : 2'b11; + din_latch <= din; + end + 2'b11: begin + { wr_n, cs_n } <= 2'b11; + addr <= din[3:0]; + addr_ok <= din[7:4] == 4'd0; + end + endcase // {bdir,bc1} + end + +jt49 #(.COMP(COMP)) u_jt49( // note that input ports are not multiplexed + .rst_n ( rst_n ), + .clk ( clk ), // signal on positive edge + .clk_en ( clk_en ), // clock enable on negative edge + .addr ( addr[3:0] ), + .cs_n ( cs_n ), + .wr_n ( wr_n ), // write + .din ( din_latch ), + .sel ( sel ), // if sel is low, the clock is divided by 2 + .dout ( dout ), + .sound ( sound ), // combined channel output + .sample ( sample ), + .A ( A ), // linearised channel output + .B ( B ), + .C ( C ), + .IOA_in ( IOA_in ), + .IOA_out( IOA_out ), + .IOB_in ( IOB_in ), + .IOB_out( IOB_out ) +); + endmodule // jt49_bus \ No newline at end of file diff --git a/modules/sound-jt49/jt49_cen.v b/modules/sound-jt49/jt49_cen.v index 671eceb..d577b90 100644 --- a/modules/sound-jt49/jt49_cen.v +++ b/modules/sound-jt49/jt49_cen.v @@ -1,55 +1,55 @@ -/* This file is part of JT49. - - JT49 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. - - JT49 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 JT49. If not, see . - - Author: Jose Tejada Gomez. Twitter: @topapate - Version: 1.0 - Date: 10-Nov-2018 - - Based on sqmusic, by the same author - - */ - -module jt49_cen( - input clk, - input rst_n, - input cen, // base clock enable signal - input sel, // when low, divide by 2 once more - output reg cen16, - output reg cen256 -); - -reg [9:0] cencnt; -parameter CLKDIV = 3; // use 3 for standalone JT49 or 2 -localparam eg = CLKDIV; //8; - -wire toggle16 = sel ? ~|cencnt[CLKDIV-1:0] : ~|cencnt[CLKDIV:0]; -wire toggle256= sel ? ~|cencnt[eg-2:0] : ~|cencnt[eg-1:0]; - - -always @(posedge clk, negedge rst_n) begin - if(!rst_n) - cencnt <= 10'd0; - else begin - if(cen) cencnt <= cencnt+10'd1; - end -end - -always @(posedge clk) begin - cen16 <= cen & toggle16; - cen256 <= cen & toggle256; -end - - -endmodule // jt49_cen +/* This file is part of JT49. + + JT49 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. + + JT49 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 JT49. If not, see . + + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 10-Nov-2018 + + Based on sqmusic, by the same author + + */ + +module jt49_cen( + input clk, + input rst_n, + input cen, // base clock enable signal + input sel, // when low, divide by 2 once more + output reg cen16, + output reg cen256 +); + +reg [9:0] cencnt; +parameter CLKDIV = 3; // use 3 for standalone JT49 or 2 +localparam eg = CLKDIV; //8; + +wire toggle16 = sel ? ~|cencnt[CLKDIV-1:0] : ~|cencnt[CLKDIV:0]; +wire toggle256= sel ? ~|cencnt[eg-2:0] : ~|cencnt[eg-1:0]; + + +always @(posedge clk, negedge rst_n) begin + if(!rst_n) + cencnt <= 10'd0; + else begin + if(cen) cencnt <= cencnt+10'd1; + end +end + +always @(posedge clk) begin + cen16 <= cen & toggle16; + cen256 <= cen & toggle256; +end + + +endmodule // jt49_cen diff --git a/modules/sound-jt49/jt49_div.v b/modules/sound-jt49/jt49_div.v index ac4564c..b640315 100644 --- a/modules/sound-jt49/jt49_div.v +++ b/modules/sound-jt49/jt49_div.v @@ -1,52 +1,52 @@ -/* This file is part of JT49. - - JT49 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. - - JT49 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 JT49. If not, see . - - Author: Jose Tejada Gomez. Twitter: @topapate - Version: 1.0 - Date: 10-Nov-2018 - - Based on sqmusic, by the same author - - */ - - -module jt49_div #(parameter W=12 )( - (* direct_enable *) input cen, - input clk, // this is the divided down clock from the core - input rst_n, - input [W-1:0] period, - output reg div -); - -reg [W-1:0]count; - -wire [W-1:0] one = { {W-1{1'b0}}, 1'b1}; - -always @(posedge clk, negedge rst_n ) begin - if( !rst_n) begin - count <= one; - div <= 1'b0; - end - else if(cen) begin - if( count>=period ) begin - count <= one; - div <= ~div; - end - else - /*if( period!={W{1'b0}} )*/ count <= count + one ; - end -end - -endmodule +/* This file is part of JT49. + + JT49 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. + + JT49 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 JT49. If not, see . + + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 10-Nov-2018 + + Based on sqmusic, by the same author + + */ + + +module jt49_div #(parameter W=12 )( + (* direct_enable *) input cen, + input clk, // this is the divided down clock from the core + input rst_n, + input [W-1:0] period, + output reg div +); + +reg [W-1:0]count; + +wire [W-1:0] one = { {W-1{1'b0}}, 1'b1}; + +always @(posedge clk, negedge rst_n ) begin + if( !rst_n) begin + count <= one; + div <= 1'b0; + end + else if(cen) begin + if( count>=period ) begin + count <= one; + div <= ~div; + end + else + /*if( period!={W{1'b0}} )*/ count <= count + one ; + end +end + +endmodule diff --git a/modules/sound-jt49/jt49_eg.v b/modules/sound-jt49/jt49_eg.v index 46dd62a..1eb7c23 100644 --- a/modules/sound-jt49/jt49_eg.v +++ b/modules/sound-jt49/jt49_eg.v @@ -1,88 +1,88 @@ -/* This file is part of JT49. - - JT49 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. - - JT49 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 JT49. If not, see . - - Author: Jose Tejada Gomez. Twitter: @topapate - Version: 1.0 - Date: 10-Nov-2018 - - Based on sqmusic, by the same author - - */ - -module jt49_eg( - (* direct_enable *) input cen, - input clk, // this is the divided down clock from the core - input step, - input null_period, - input rst_n, - input restart, - input [3:0] ctrl, - output reg [4:0]env -); - -reg inv, stop; -reg [4:0] gain; - -wire CONT = ctrl[3]; -wire ATT = ctrl[2]; -wire ALT = ctrl[1]; -wire HOLD = ctrl[0]; - -wire will_hold = !CONT || HOLD; - -always @(posedge clk) - if( cen ) env <= inv ? ~gain : gain; - -reg last_step; -wire step_edge = (step && !last_step) || null_period; -wire will_invert = (!CONT&&ATT) || (CONT&&ALT); -reg rst_latch, rst_clr; - -always @(posedge clk) begin - if( restart ) rst_latch <= 1; - else if(rst_clr ) rst_latch <= 0; -end - -always @( posedge clk, negedge rst_n ) - if( !rst_n) begin - gain <= 5'h1F; - inv <= 0; - stop <= 0; - rst_clr <= 0; - end - else if( cen ) begin - last_step <= step; - if( rst_latch ) begin - gain <= 5'h1F; - inv <= ATT; - stop <= 1'b0; - rst_clr <= 1; - end - else begin - rst_clr <= 0; - if (step_edge && !stop) begin - if( gain==5'h00 ) begin - if( will_hold ) - stop <= 1'b1; - else - gain <= gain-5'b1; - if( will_invert ) inv<=~inv; - end - else gain <= gain-5'b1; - end - end - end - -endmodule +/* This file is part of JT49. + + JT49 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. + + JT49 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 JT49. If not, see . + + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 10-Nov-2018 + + Based on sqmusic, by the same author + + */ + +module jt49_eg( + (* direct_enable *) input cen, + input clk, // this is the divided down clock from the core + input step, + input null_period, + input rst_n, + input restart, + input [3:0] ctrl, + output reg [4:0]env +); + +reg inv, stop; +reg [4:0] gain; + +wire CONT = ctrl[3]; +wire ATT = ctrl[2]; +wire ALT = ctrl[1]; +wire HOLD = ctrl[0]; + +wire will_hold = !CONT || HOLD; + +always @(posedge clk) + if( cen ) env <= inv ? ~gain : gain; + +reg last_step; +wire step_edge = (step && !last_step) || null_period; +wire will_invert = (!CONT&&ATT) || (CONT&&ALT); +reg rst_latch, rst_clr; + +always @(posedge clk) begin + if( restart ) rst_latch <= 1; + else if(rst_clr ) rst_latch <= 0; +end + +always @( posedge clk, negedge rst_n ) + if( !rst_n) begin + gain <= 5'h1F; + inv <= 0; + stop <= 0; + rst_clr <= 0; + end + else if( cen ) begin + last_step <= step; + if( rst_latch ) begin + gain <= 5'h1F; + inv <= ATT; + stop <= 1'b0; + rst_clr <= 1; + end + else begin + rst_clr <= 0; + if (step_edge && !stop) begin + if( gain==5'h00 ) begin + if( will_hold ) + stop <= 1'b1; + else + gain <= gain-5'b1; + if( will_invert ) inv<=~inv; + end + else gain <= gain-5'b1; + end + end + end + +endmodule diff --git a/modules/sound-jt49/jt49_exp.v b/modules/sound-jt49/jt49_exp.v index 412a3f8..ac5c36f 100644 --- a/modules/sound-jt49/jt49_exp.v +++ b/modules/sound-jt49/jt49_exp.v @@ -1,174 +1,174 @@ -/* This file is part of JT49. - - JT49 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. - - JT49 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 JT49. If not, see . - - Author: Jose Tejada Gomez. Twitter: @topapate - Version: 1.0 - Date: 10-Nov-2018 - - Based on sqmusic, by the same author - - */ - - -// Compression vs dynamic range -// 0 -> 43.6dB -// 1 -> 29.1 -// 2 -> 21.8 -// 3 -> 13.4 - -module jt49_exp( - input clk, - input [1:0] comp, // compression - input [4:0] din, - output reg [7:0] dout -); - -reg [7:0] lut[0:127]; - -always @(posedge clk) - dout <= lut[ {comp,din} ]; - -initial begin - lut[0] = 8'd0; - lut[1] = 8'd1; - lut[2] = 8'd1; - lut[3] = 8'd1; - lut[4] = 8'd2; - lut[5] = 8'd2; - lut[6] = 8'd3; - lut[7] = 8'd3; - lut[8] = 8'd4; - lut[9] = 8'd5; - lut[10] = 8'd6; - lut[11] = 8'd7; - lut[12] = 8'd9; - lut[13] = 8'd11; - lut[14] = 8'd13; - lut[15] = 8'd15; - lut[16] = 8'd18; - lut[17] = 8'd22; - lut[18] = 8'd26; - lut[19] = 8'd31; - lut[20] = 8'd37; - lut[21] = 8'd45; - lut[22] = 8'd53; - lut[23] = 8'd63; - lut[24] = 8'd75; - lut[25] = 8'd90; - lut[26] = 8'd107; - lut[27] = 8'd127; - lut[28] = 8'd151; - lut[29] = 8'd180; - lut[30] = 8'd214; - lut[31] = 8'd255; - lut[32] = 8'd0; - lut[33] = 8'd7; - lut[34] = 8'd8; - lut[35] = 8'd10; - lut[36] = 8'd11; - lut[37] = 8'd12; - lut[38] = 8'd14; - lut[39] = 8'd15; - lut[40] = 8'd17; - lut[41] = 8'd20; - lut[42] = 8'd22; - lut[43] = 8'd25; - lut[44] = 8'd28; - lut[45] = 8'd31; - lut[46] = 8'd35; - lut[47] = 8'd40; - lut[48] = 8'd45; - lut[49] = 8'd50; - lut[50] = 8'd56; - lut[51] = 8'd63; - lut[52] = 8'd71; - lut[53] = 8'd80; - lut[54] = 8'd90; - lut[55] = 8'd101; - lut[56] = 8'd113; - lut[57] = 8'd127; - lut[58] = 8'd143; - lut[59] = 8'd160; - lut[60] = 8'd180; - lut[61] = 8'd202; - lut[62] = 8'd227; - lut[63] = 8'd255; - lut[64] = 8'd0; - lut[65] = 8'd18; - lut[66] = 8'd20; - lut[67] = 8'd22; - lut[68] = 8'd24; - lut[69] = 8'd26; - lut[70] = 8'd29; - lut[71] = 8'd31; - lut[72] = 8'd34; - lut[73] = 8'd37; - lut[74] = 8'd41; - lut[75] = 8'd45; - lut[76] = 8'd49; - lut[77] = 8'd53; - lut[78] = 8'd58; - lut[79] = 8'd63; - lut[80] = 8'd69; - lut[81] = 8'd75; - lut[82] = 8'd82; - lut[83] = 8'd90; - lut[84] = 8'd98; - lut[85] = 8'd107; - lut[86] = 8'd116; - lut[87] = 8'd127; - lut[88] = 8'd139; - lut[89] = 8'd151; - lut[90] = 8'd165; - lut[91] = 8'd180; - lut[92] = 8'd196; - lut[93] = 8'd214; - lut[94] = 8'd233; - lut[95] = 8'd255; - lut[96] = 8'd0; - lut[97] = 8'd51; - lut[98] = 8'd54; - lut[99] = 8'd57; - lut[100] = 8'd60; - lut[101] = 8'd63; - lut[102] = 8'd67; - lut[103] = 8'd70; - lut[104] = 8'd74; - lut[105] = 8'd78; - lut[106] = 8'd83; - lut[107] = 8'd87; - lut[108] = 8'd92; - lut[109] = 8'd97; - lut[110] = 8'd103; - lut[111] = 8'd108; - lut[112] = 8'd114; - lut[113] = 8'd120; - lut[114] = 8'd127; - lut[115] = 8'd134; - lut[116] = 8'd141; - lut[117] = 8'd149; - lut[118] = 8'd157; - lut[119] = 8'd166; - lut[120] = 8'd175; - lut[121] = 8'd185; - lut[122] = 8'd195; - lut[123] = 8'd206; - lut[124] = 8'd217; - lut[125] = 8'd229; - lut[126] = 8'd241; - lut[127] = 8'd255; - -end -endmodule +/* This file is part of JT49. + + JT49 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. + + JT49 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 JT49. If not, see . + + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 10-Nov-2018 + + Based on sqmusic, by the same author + + */ + + +// Compression vs dynamic range +// 0 -> 43.6dB +// 1 -> 29.1 +// 2 -> 21.8 +// 3 -> 13.4 + +module jt49_exp( + input clk, + input [1:0] comp, // compression + input [4:0] din, + output reg [7:0] dout +); + +reg [7:0] lut[0:127]; + +always @(posedge clk) + dout <= lut[ {comp,din} ]; + +initial begin + lut[0] = 8'd0; + lut[1] = 8'd1; + lut[2] = 8'd1; + lut[3] = 8'd1; + lut[4] = 8'd2; + lut[5] = 8'd2; + lut[6] = 8'd3; + lut[7] = 8'd3; + lut[8] = 8'd4; + lut[9] = 8'd5; + lut[10] = 8'd6; + lut[11] = 8'd7; + lut[12] = 8'd9; + lut[13] = 8'd11; + lut[14] = 8'd13; + lut[15] = 8'd15; + lut[16] = 8'd18; + lut[17] = 8'd22; + lut[18] = 8'd26; + lut[19] = 8'd31; + lut[20] = 8'd37; + lut[21] = 8'd45; + lut[22] = 8'd53; + lut[23] = 8'd63; + lut[24] = 8'd75; + lut[25] = 8'd90; + lut[26] = 8'd107; + lut[27] = 8'd127; + lut[28] = 8'd151; + lut[29] = 8'd180; + lut[30] = 8'd214; + lut[31] = 8'd255; + lut[32] = 8'd0; + lut[33] = 8'd7; + lut[34] = 8'd8; + lut[35] = 8'd10; + lut[36] = 8'd11; + lut[37] = 8'd12; + lut[38] = 8'd14; + lut[39] = 8'd15; + lut[40] = 8'd17; + lut[41] = 8'd20; + lut[42] = 8'd22; + lut[43] = 8'd25; + lut[44] = 8'd28; + lut[45] = 8'd31; + lut[46] = 8'd35; + lut[47] = 8'd40; + lut[48] = 8'd45; + lut[49] = 8'd50; + lut[50] = 8'd56; + lut[51] = 8'd63; + lut[52] = 8'd71; + lut[53] = 8'd80; + lut[54] = 8'd90; + lut[55] = 8'd101; + lut[56] = 8'd113; + lut[57] = 8'd127; + lut[58] = 8'd143; + lut[59] = 8'd160; + lut[60] = 8'd180; + lut[61] = 8'd202; + lut[62] = 8'd227; + lut[63] = 8'd255; + lut[64] = 8'd0; + lut[65] = 8'd18; + lut[66] = 8'd20; + lut[67] = 8'd22; + lut[68] = 8'd24; + lut[69] = 8'd26; + lut[70] = 8'd29; + lut[71] = 8'd31; + lut[72] = 8'd34; + lut[73] = 8'd37; + lut[74] = 8'd41; + lut[75] = 8'd45; + lut[76] = 8'd49; + lut[77] = 8'd53; + lut[78] = 8'd58; + lut[79] = 8'd63; + lut[80] = 8'd69; + lut[81] = 8'd75; + lut[82] = 8'd82; + lut[83] = 8'd90; + lut[84] = 8'd98; + lut[85] = 8'd107; + lut[86] = 8'd116; + lut[87] = 8'd127; + lut[88] = 8'd139; + lut[89] = 8'd151; + lut[90] = 8'd165; + lut[91] = 8'd180; + lut[92] = 8'd196; + lut[93] = 8'd214; + lut[94] = 8'd233; + lut[95] = 8'd255; + lut[96] = 8'd0; + lut[97] = 8'd51; + lut[98] = 8'd54; + lut[99] = 8'd57; + lut[100] = 8'd60; + lut[101] = 8'd63; + lut[102] = 8'd67; + lut[103] = 8'd70; + lut[104] = 8'd74; + lut[105] = 8'd78; + lut[106] = 8'd83; + lut[107] = 8'd87; + lut[108] = 8'd92; + lut[109] = 8'd97; + lut[110] = 8'd103; + lut[111] = 8'd108; + lut[112] = 8'd114; + lut[113] = 8'd120; + lut[114] = 8'd127; + lut[115] = 8'd134; + lut[116] = 8'd141; + lut[117] = 8'd149; + lut[118] = 8'd157; + lut[119] = 8'd166; + lut[120] = 8'd175; + lut[121] = 8'd185; + lut[122] = 8'd195; + lut[123] = 8'd206; + lut[124] = 8'd217; + lut[125] = 8'd229; + lut[126] = 8'd241; + lut[127] = 8'd255; + +end +endmodule diff --git a/modules/sound-jt49/jt49_noise.v b/modules/sound-jt49/jt49_noise.v index ffc1fb9..80503fc 100644 --- a/modules/sound-jt49/jt49_noise.v +++ b/modules/sound-jt49/jt49_noise.v @@ -1,62 +1,62 @@ -/* This file is part of JT49. - - JT49 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. - - JT49 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 JT49. If not, see . - - Author: Jose Tejada Gomez. Twitter: @topapate - Version: 1.0 - Date: 10-Nov-2018 - - Based on sqmusic, by the same author - - */ - - -module jt49_noise( - (* direct_enable *) input cen, - input clk, - input rst_n, - input [4:0] period, - output reg noise -); - -reg [5:0]count; -reg [16:0]poly17; -wire poly17_zero = poly17==17'b0; -wire noise_en; -reg last_en; - -wire noise_up = noise_en && !last_en; - -always @(posedge clk ) if(cen) begin - noise <= ~poly17[0]; -end - -always @( posedge clk, negedge rst_n ) - if( !rst_n ) - poly17 <= 17'd0; - else if( cen ) begin - last_en <= noise_en; - if( noise_up ) - poly17 <= { poly17[0] ^ poly17[3] ^ poly17_zero, poly17[16:1] }; - end - -jt49_div #(5) u_div( - .clk ( clk ), - .cen ( cen ), - .rst_n ( rst_n ), - .period ( period ), - .div ( noise_en ) -); - +/* This file is part of JT49. + + JT49 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. + + JT49 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 JT49. If not, see . + + Author: Jose Tejada Gomez. Twitter: @topapate + Version: 1.0 + Date: 10-Nov-2018 + + Based on sqmusic, by the same author + + */ + + +module jt49_noise( + (* direct_enable *) input cen, + input clk, + input rst_n, + input [4:0] period, + output reg noise +); + +reg [5:0]count; +reg [16:0]poly17; +wire poly17_zero = poly17==17'b0; +wire noise_en; +reg last_en; + +wire noise_up = noise_en && !last_en; + +always @(posedge clk ) if(cen) begin + noise <= ~poly17[0]; +end + +always @( posedge clk, negedge rst_n ) + if( !rst_n ) + poly17 <= 17'd0; + else if( cen ) begin + last_en <= noise_en; + if( noise_up ) + poly17 <= { poly17[0] ^ poly17[3] ^ poly17_zero, poly17[16:1] }; + end + +jt49_div #(5) u_div( + .clk ( clk ), + .cen ( cen ), + .rst_n ( rst_n ), + .period ( period ), + .div ( noise_en ) +); + endmodule \ No newline at end of file diff --git a/modules/video-vdp18/COPYING b/modules/video-vdp18/COPYING index 60549be..f89b4fa 100644 --- a/modules/video-vdp18/COPYING +++ b/modules/video-vdp18/COPYING @@ -1,340 +1,340 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) 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 -this service 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 make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. 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. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -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 -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the 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 a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE 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. - - 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 -convey 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) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision 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, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This 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 Library General -Public License instead of this License. + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +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 +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE 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. + + 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 +convey 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) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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 Library General +Public License instead of this License. diff --git a/modules/video-vdp18/README b/modules/video-vdp18/README index 4576b2e..a26ff62 100644 --- a/modules/video-vdp18/README +++ b/modules/video-vdp18/README @@ -1,201 +1,201 @@ - -A Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A -========================================================== -Version: $Date: 2006/06/18 19:28:06 $ - -Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) -See the file COPYING. - - -Integration ------------ - -The vdp18 design exhibits a set of interface signals that is compatible to the -original chips. It mainly differs in the video and VRAM interfaces, which are -tailored to better fit a modern SoC. - - generic ( - is_pal_g : integer := 0; - -- Select PAL or NTSC video timing. - -- 0 = NTSC - -- 1 = PAL - - compat_rgb_g : integer := 0 - -- Select full or compatibility RGB palettes. - -- Refer to vdp18_col_pack-p.vhd for details. - - ); - port ( - -- Global Interface ------------------------------------------------------- - clk_i : in std_logic; - -- Global clock input - -- Equivalent to XTAL1/2 on TMS9918A. - -- Drive with the target frequency of 10.7 MHz or any integer multiple. - - clk_en_10m7_i : in std_logic; - -- Clock enable - -- A '1' on this input qualifies a valid rising edge on clk_i. A '0' - -- disables the next rising clock edge, effectivley halting the design - -- until the next enabled rising clock edge. - -- Can be used to run the core at lower frequencies than applied on - -- clk_i. - - reset_n_i : in std_logic; - -- Asynchronous low active reset input - -- Sets all sequential elements to a known state. - -- NOTE: SYNC operation not supported. - - -- CPU Interface ---------------------------------------------------------- - csr_n_i : in std_logic; - -- CPU-VDP read strobe, low active - - csw_n_i : in std_logic; - -- CPU-VDP write strobe, low active - - mode_i : in std_logic; - -- CPU interface mode select - - int_n_o : out std_logic; - -- CPU interrupt output, low active - - cd_i : in std_logic_vector(0 to 7); - -- CPU data bus input - -- MSB 0 ... 7 LSB - - cd_o : out std_logic_vector(0 to 7); - -- CPU data bus output - -- MSB 0 ... 7 LSB - - -- VRAM Interface --------------------------------------------------------- - vram_we_o : out std_logic; - -- VRAM write enable - - vram_a_o : out std_logic_vector(0 to 13); - -- VRAM address output - -- MSB 0 ... 13 LSB - - vram_d_o : out std_logic_vector(0 to 7); - -- VRAM data output - -- MSB 0 ... 7 LSB - - vram_d_i : in std_logic_vector(0 to 7); - -- VRAM data input - -- MSB 0 ... 7 LSB - - -- Video Interface -------------------------------------------------------- - col_o : out std_logic_vector(0 to 3); - -- Color code output - -- Encoded pixel color information - - rgb_r_o : out std_logic_vector(0 to 7); - -- Red color information - - rgb_g_o : out std_logic_vector(0 to 7); - -- Green color information - - rgb_b_o : out std_logic_vector(0 to 7); - -- Blue color information - - hsync_n_o : out std_logic; - -- Horizontal synchronization pulse, active low - - vsync_n_o : out std_logic; - -- Vertical synchronization pulse, active low - - comp_sync_n_o : out std_logic - -- Composite synchronization pulse, active low - ); - - -All 8 bit vector ports are defined (0 to 7) which declares bit 0 to be the MSB -and bit 7 to be the LSB. This has been implemented according to TI's data -sheet, thus all register/data format figures apply 1:1 for this design. -Many systems will flip the system data bus bit wise before it is connected to -this PSG. This is simply achieved with the following VHDL construct: - - signal data_s : std_logic_vector(7 downto 0); - - ... - cd_i => data_s, - ... - -d_i and data_s will be assigned from left to right, resulting in the expected -bit assignment: - - cd_i data_s - 0 7 - 1 6 - ... - 6 1 - 7 0 - - -As this design is fully synchronous, care has to be taken when the design -replaces an TMS99x8 in asynchronous mode. No problems are expected when -interfacing the code to other synchronous components. - - -Design Hierarchy ----------------- - - vdp18_core - | - +-- vdp18_clk_gen - | - +-- vdp18_hor_vert - | - +-- vdp18_ctrl - | - +-- vdp18_cpuio - | - +-- vdp18_addr_mux - | - +-- vdp18_pattern - | - +-- vdp18_sprite - | - \-- vdp18_col_mux - -Resulting compolation sequence: - - vdp18_pack-p.vhd - vdp18_comp_pack-p.vhd - vdp18_core.vhd - vdp18_clk_gen.vhd - vdp18_clk_gen-c.vhd - vdp18_hor_vert.vhd - vdp18_hor_vert-c.vhd - vdp18_ctrl.vhd - vdp18_ctrl-c.vhd - vdp18_cpuio.vhd - vdp18_cpuio-c.vhd - vdp18_addr_mux.vhd - vdp18_addr_mux-c.vhd - vdp18_pattern.vhd - vdp18_pattern-c.vhd - vdp18_sprite.vhd - vdp18_sprite-c.vhd - vdp18_col_mux.vhd - vdp18_col_mux-c.vhd - vdp18_core-c.vhd - vdp18_core_com_pack-p.vhd - -Skip the files containing VHDL configurations when analyzing the code for -synthesis. - - -References ----------- - -* TI Data book TMS9918.pdf - http://www.bitsavers.org/pdf/ti/_dataBooks/TMS9918.pdf - -* Sean Young's tech article: - http://bifi.msxnet.org/msxnet/tech/tms9918a.txt - -* Paul Urbanus' discussion of the timing details - http://bifi.msxnet.org/msxnet/tech/tmsposting.txt - -* Richard F. Drushel's article series - "This Week With My Coleco ADAM" - http://junior.apk.net/~drushel/pub/coleco/twwmca/index.html + +A Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A +========================================================== +Version: $Date: 2006/06/18 19:28:06 $ + +Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +See the file COPYING. + + +Integration +----------- + +The vdp18 design exhibits a set of interface signals that is compatible to the +original chips. It mainly differs in the video and VRAM interfaces, which are +tailored to better fit a modern SoC. + + generic ( + is_pal_g : integer := 0; + -- Select PAL or NTSC video timing. + -- 0 = NTSC + -- 1 = PAL + + compat_rgb_g : integer := 0 + -- Select full or compatibility RGB palettes. + -- Refer to vdp18_col_pack-p.vhd for details. + + ); + port ( + -- Global Interface ------------------------------------------------------- + clk_i : in std_logic; + -- Global clock input + -- Equivalent to XTAL1/2 on TMS9918A. + -- Drive with the target frequency of 10.7 MHz or any integer multiple. + + clk_en_10m7_i : in std_logic; + -- Clock enable + -- A '1' on this input qualifies a valid rising edge on clk_i. A '0' + -- disables the next rising clock edge, effectivley halting the design + -- until the next enabled rising clock edge. + -- Can be used to run the core at lower frequencies than applied on + -- clk_i. + + reset_n_i : in std_logic; + -- Asynchronous low active reset input + -- Sets all sequential elements to a known state. + -- NOTE: SYNC operation not supported. + + -- CPU Interface ---------------------------------------------------------- + csr_n_i : in std_logic; + -- CPU-VDP read strobe, low active + + csw_n_i : in std_logic; + -- CPU-VDP write strobe, low active + + mode_i : in std_logic; + -- CPU interface mode select + + int_n_o : out std_logic; + -- CPU interrupt output, low active + + cd_i : in std_logic_vector(0 to 7); + -- CPU data bus input + -- MSB 0 ... 7 LSB + + cd_o : out std_logic_vector(0 to 7); + -- CPU data bus output + -- MSB 0 ... 7 LSB + + -- VRAM Interface --------------------------------------------------------- + vram_we_o : out std_logic; + -- VRAM write enable + + vram_a_o : out std_logic_vector(0 to 13); + -- VRAM address output + -- MSB 0 ... 13 LSB + + vram_d_o : out std_logic_vector(0 to 7); + -- VRAM data output + -- MSB 0 ... 7 LSB + + vram_d_i : in std_logic_vector(0 to 7); + -- VRAM data input + -- MSB 0 ... 7 LSB + + -- Video Interface -------------------------------------------------------- + col_o : out std_logic_vector(0 to 3); + -- Color code output + -- Encoded pixel color information + + rgb_r_o : out std_logic_vector(0 to 7); + -- Red color information + + rgb_g_o : out std_logic_vector(0 to 7); + -- Green color information + + rgb_b_o : out std_logic_vector(0 to 7); + -- Blue color information + + hsync_n_o : out std_logic; + -- Horizontal synchronization pulse, active low + + vsync_n_o : out std_logic; + -- Vertical synchronization pulse, active low + + comp_sync_n_o : out std_logic + -- Composite synchronization pulse, active low + ); + + +All 8 bit vector ports are defined (0 to 7) which declares bit 0 to be the MSB +and bit 7 to be the LSB. This has been implemented according to TI's data +sheet, thus all register/data format figures apply 1:1 for this design. +Many systems will flip the system data bus bit wise before it is connected to +this PSG. This is simply achieved with the following VHDL construct: + + signal data_s : std_logic_vector(7 downto 0); + + ... + cd_i => data_s, + ... + +d_i and data_s will be assigned from left to right, resulting in the expected +bit assignment: + + cd_i data_s + 0 7 + 1 6 + ... + 6 1 + 7 0 + + +As this design is fully synchronous, care has to be taken when the design +replaces an TMS99x8 in asynchronous mode. No problems are expected when +interfacing the code to other synchronous components. + + +Design Hierarchy +---------------- + + vdp18_core + | + +-- vdp18_clk_gen + | + +-- vdp18_hor_vert + | + +-- vdp18_ctrl + | + +-- vdp18_cpuio + | + +-- vdp18_addr_mux + | + +-- vdp18_pattern + | + +-- vdp18_sprite + | + \-- vdp18_col_mux + +Resulting compolation sequence: + + vdp18_pack-p.vhd + vdp18_comp_pack-p.vhd + vdp18_core.vhd + vdp18_clk_gen.vhd + vdp18_clk_gen-c.vhd + vdp18_hor_vert.vhd + vdp18_hor_vert-c.vhd + vdp18_ctrl.vhd + vdp18_ctrl-c.vhd + vdp18_cpuio.vhd + vdp18_cpuio-c.vhd + vdp18_addr_mux.vhd + vdp18_addr_mux-c.vhd + vdp18_pattern.vhd + vdp18_pattern-c.vhd + vdp18_sprite.vhd + vdp18_sprite-c.vhd + vdp18_col_mux.vhd + vdp18_col_mux-c.vhd + vdp18_core-c.vhd + vdp18_core_com_pack-p.vhd + +Skip the files containing VHDL configurations when analyzing the code for +synthesis. + + +References +---------- + +* TI Data book TMS9918.pdf + http://www.bitsavers.org/pdf/ti/_dataBooks/TMS9918.pdf + +* Sean Young's tech article: + http://bifi.msxnet.org/msxnet/tech/tms9918a.txt + +* Paul Urbanus' discussion of the timing details + http://bifi.msxnet.org/msxnet/tech/tmsposting.txt + +* Richard F. Drushel's article series + "This Week With My Coleco ADAM" + http://junior.apk.net/~drushel/pub/coleco/twwmca/index.html diff --git a/modules/video-vdp18/index.qip b/modules/video-vdp18/index.qip index df5a386..0d6bb47 100644 --- a/modules/video-vdp18/index.qip +++ b/modules/video-vdp18/index.qip @@ -1,14 +1,14 @@ -# ============================================================================== -# Quartus Prime QIP Index File -# ============================================================================== -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_addr_mux.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_clk_gen.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_col_mux.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_col_pack-p.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_core.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_cpuio.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_ctrl.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_hor_vert.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_pack-p.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_pattern.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_sprite.vhd"] +# ============================================================================== +# Quartus Prime QIP Index File +# ============================================================================== +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_addr_mux.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_clk_gen.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_col_mux.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_col_pack-p.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_core.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_cpuio.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_ctrl.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_hor_vert.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_pack-p.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_pattern.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "vdp18_sprite.vhd"] diff --git a/modules/video-vdp18/vdp18_addr_mux.vhd b/modules/video-vdp18/vdp18_addr_mux.vhd index 9ff8c8f..6ca0818 100644 --- a/modules/video-vdp18/vdp18_addr_mux.vhd +++ b/modules/video-vdp18/vdp18_addr_mux.vhd @@ -1,228 +1,228 @@ -------------------------------------------------------------------------------- --- --- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. --- --- $Id: vdp18_addr_mux.vhd,v 1.10 2006/06/18 10:47:01 arnim Exp $ --- --- Address Multiplexer / Generator --- -------------------------------------------------------------------------------- --- --- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; - -use work.vdp18_pack.access_t; -use work.vdp18_pack.opmode_t; -use work.vdp18_pack.hv_t; - -entity vdp18_addr_mux is - - port ( - access_type_i : in access_t; - opmode_i : in opmode_t; - num_line_i : in hv_t; - reg_ntb_i : in std_logic_vector(0 to 3); - reg_ctb_i : in std_logic_vector(0 to 7); - reg_pgb_i : in std_logic_vector(0 to 2); - reg_satb_i : in std_logic_vector(0 to 6); - reg_spgb_i : in std_logic_vector(0 to 2); - reg_size1_i : in boolean; - cpu_vram_a_i : in std_logic_vector(0 to 13); - pat_table_i : in std_logic_vector(0 to 9); - pat_name_i : in std_logic_vector(0 to 7); - spr_num_i : in std_logic_vector(0 to 4); - spr_line_i : in std_logic_vector(0 to 3); - spr_name_i : in std_logic_vector(0 to 7); - vram_a_o : out std_logic_vector(0 to 13) - ); - -end vdp18_addr_mux; - - -use work.vdp18_pack.all; - -architecture rtl of vdp18_addr_mux is - -begin - - ----------------------------------------------------------------------------- - -- Process mux - -- - -- Purpose: - -- Generates the VRAM address based on the current access type. - -- - mux: process (access_type_i, opmode_i, - num_line_i, - reg_ntb_i, reg_ctb_i, reg_pgb_i, - reg_satb_i, reg_spgb_i, - reg_size1_i, - cpu_vram_a_i, - pat_table_i, pat_name_i, - spr_num_i, spr_name_i, - spr_line_i) - variable num_line_v : std_logic_vector(num_line_i'range); - begin - -- default assignment - vram_a_o <= (others => '0'); - num_line_v := std_logic_vector(num_line_i); - - case access_type_i is - -- CPU Access ----------------------------------------------------------- - when AC_CPU => - vram_a_o <= cpu_vram_a_i; - - -- Pattern Name Table Access -------------------------------------------- - when AC_PNT => - vram_a_o(0 to 3) <= reg_ntb_i; - vram_a_o(4 to 13) <= pat_table_i; - - -- Pattern Color Table Access ------------------------------------------- - when AC_PCT => - case opmode_i is - when OPMODE_GRAPH1 => - vram_a_o( 0 to 7) <= reg_ctb_i; - vram_a_o( 8) <= '0'; - vram_a_o( 9 to 13) <= pat_name_i(0 to 4); - - when OPMODE_GRAPH2 => - vram_a_o( 0) <= reg_ctb_i(0); - vram_a_o( 1 to 2) <= num_line_v(1 to 2) and - -- remaining bits in CTB mask color - -- lookups - (reg_ctb_i(1) & reg_ctb_i(2)); - vram_a_o( 3 to 10) <= pat_name_i and - -- remaining bits in CTB mask color - -- lookups - (reg_ctb_i(3) & reg_ctb_i(4) & - reg_ctb_i(5) & reg_ctb_i(6) & - reg_ctb_i(7) & "111"); - vram_a_o(11 to 13) <= num_line_v(6 to 8); - - when others => - null; - end case; - - -- Pattern Generator Table Access --------------------------------------- - when AC_PGT => - case opmode_i is - when OPMODE_TEXTM | - OPMODE_GRAPH1 => - vram_a_o( 0 to 2) <= reg_pgb_i; - vram_a_o( 3 to 10) <= pat_name_i; - vram_a_o(11 to 13) <= num_line_v(6 to 8); - - when OPMODE_MULTIC => - vram_a_o( 0 to 2) <= reg_pgb_i; - vram_a_o( 3 to 10) <= pat_name_i; - vram_a_o(11 to 13) <= num_line_v(4 to 6); - - when OPMODE_GRAPH2 => - vram_a_o( 0) <= reg_pgb_i(0); - vram_a_o( 1 to 2) <= num_line_v(1 to 2) and - -- remaining bits in PGB mask pattern - -- lookups - (reg_pgb_i(1) & reg_pgb_i(2)); - vram_a_o( 3 to 10) <= pat_name_i and - -- remaining bits in CTB mask pattern - -- lookups - (reg_ctb_i(3) & reg_ctb_i(4) & - reg_ctb_i(5) & reg_ctb_i(6) & - reg_ctb_i(7) & "111"); - vram_a_o(11 to 13) <= num_line_v(6 to 8); - - when others => - null; - end case; - - -- Sprite Test ---------------------------------------------------------- - when AC_STST | - AC_SATY => - vram_a_o( 0 to 6) <= reg_satb_i; - vram_a_o( 7 to 11) <= spr_num_i; - vram_a_o(12 to 13) <= "00"; - - -- Sprite Attribute Table: X -------------------------------------------- - when AC_SATX => - vram_a_o( 0 to 6) <= reg_satb_i; - vram_a_o( 7 to 11) <= spr_num_i; - vram_a_o(12 to 13) <= "01"; - - -- Sprite Attribute Table: Name ----------------------------------------- - when AC_SATN => - vram_a_o( 0 to 6) <= reg_satb_i; - vram_a_o( 7 to 11) <= spr_num_i; - vram_a_o(12 to 13) <= "10"; - - -- Sprite Attribute Table: Color ---------------------------------------- - when AC_SATC => - vram_a_o( 0 to 6) <= reg_satb_i; - vram_a_o( 7 to 11) <= spr_num_i; - vram_a_o(12 to 13) <= "11"; - - -- Sprite Pattern, Upper Part ------------------------------------------- - when AC_SPTH => - vram_a_o( 0 to 2) <= reg_spgb_i; - if not reg_size1_i then - -- 8x8 sprite - vram_a_o( 3 to 10) <= spr_name_i; - vram_a_o(11 to 13) <= spr_line_i(1 to 3); - else - -- 16x16 sprite - vram_a_o( 3 to 8) <= spr_name_i(0 to 5); - vram_a_o( 9) <= '0'; - vram_a_o(10 to 13) <= spr_line_i; - end if; - - -- Sprite Pattern, Lower Part ------------------------------------------- - when AC_SPTL => - vram_a_o( 0 to 2) <= reg_spgb_i; - vram_a_o( 3 to 8) <= spr_name_i(0 to 5); - vram_a_o( 9) <= '1'; - vram_a_o(10 to 13) <= spr_line_i; - - when others => - null; - - end case; - - end process mux; - -- - ----------------------------------------------------------------------------- - -end rtl; +------------------------------------------------------------------------------- +-- +-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. +-- +-- $Id: vdp18_addr_mux.vhd,v 1.10 2006/06/18 10:47:01 arnim Exp $ +-- +-- Address Multiplexer / Generator +-- +------------------------------------------------------------------------------- +-- +-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; + +use work.vdp18_pack.access_t; +use work.vdp18_pack.opmode_t; +use work.vdp18_pack.hv_t; + +entity vdp18_addr_mux is + + port ( + access_type_i : in access_t; + opmode_i : in opmode_t; + num_line_i : in hv_t; + reg_ntb_i : in std_logic_vector(0 to 3); + reg_ctb_i : in std_logic_vector(0 to 7); + reg_pgb_i : in std_logic_vector(0 to 2); + reg_satb_i : in std_logic_vector(0 to 6); + reg_spgb_i : in std_logic_vector(0 to 2); + reg_size1_i : in boolean; + cpu_vram_a_i : in std_logic_vector(0 to 13); + pat_table_i : in std_logic_vector(0 to 9); + pat_name_i : in std_logic_vector(0 to 7); + spr_num_i : in std_logic_vector(0 to 4); + spr_line_i : in std_logic_vector(0 to 3); + spr_name_i : in std_logic_vector(0 to 7); + vram_a_o : out std_logic_vector(0 to 13) + ); + +end vdp18_addr_mux; + + +use work.vdp18_pack.all; + +architecture rtl of vdp18_addr_mux is + +begin + + ----------------------------------------------------------------------------- + -- Process mux + -- + -- Purpose: + -- Generates the VRAM address based on the current access type. + -- + mux: process (access_type_i, opmode_i, + num_line_i, + reg_ntb_i, reg_ctb_i, reg_pgb_i, + reg_satb_i, reg_spgb_i, + reg_size1_i, + cpu_vram_a_i, + pat_table_i, pat_name_i, + spr_num_i, spr_name_i, + spr_line_i) + variable num_line_v : std_logic_vector(num_line_i'range); + begin + -- default assignment + vram_a_o <= (others => '0'); + num_line_v := std_logic_vector(num_line_i); + + case access_type_i is + -- CPU Access ----------------------------------------------------------- + when AC_CPU => + vram_a_o <= cpu_vram_a_i; + + -- Pattern Name Table Access -------------------------------------------- + when AC_PNT => + vram_a_o(0 to 3) <= reg_ntb_i; + vram_a_o(4 to 13) <= pat_table_i; + + -- Pattern Color Table Access ------------------------------------------- + when AC_PCT => + case opmode_i is + when OPMODE_GRAPH1 => + vram_a_o( 0 to 7) <= reg_ctb_i; + vram_a_o( 8) <= '0'; + vram_a_o( 9 to 13) <= pat_name_i(0 to 4); + + when OPMODE_GRAPH2 => + vram_a_o( 0) <= reg_ctb_i(0); + vram_a_o( 1 to 2) <= num_line_v(1 to 2) and + -- remaining bits in CTB mask color + -- lookups + (reg_ctb_i(1) & reg_ctb_i(2)); + vram_a_o( 3 to 10) <= pat_name_i and + -- remaining bits in CTB mask color + -- lookups + (reg_ctb_i(3) & reg_ctb_i(4) & + reg_ctb_i(5) & reg_ctb_i(6) & + reg_ctb_i(7) & "111"); + vram_a_o(11 to 13) <= num_line_v(6 to 8); + + when others => + null; + end case; + + -- Pattern Generator Table Access --------------------------------------- + when AC_PGT => + case opmode_i is + when OPMODE_TEXTM | + OPMODE_GRAPH1 => + vram_a_o( 0 to 2) <= reg_pgb_i; + vram_a_o( 3 to 10) <= pat_name_i; + vram_a_o(11 to 13) <= num_line_v(6 to 8); + + when OPMODE_MULTIC => + vram_a_o( 0 to 2) <= reg_pgb_i; + vram_a_o( 3 to 10) <= pat_name_i; + vram_a_o(11 to 13) <= num_line_v(4 to 6); + + when OPMODE_GRAPH2 => + vram_a_o( 0) <= reg_pgb_i(0); + vram_a_o( 1 to 2) <= num_line_v(1 to 2) and + -- remaining bits in PGB mask pattern + -- lookups + (reg_pgb_i(1) & reg_pgb_i(2)); + vram_a_o( 3 to 10) <= pat_name_i and + -- remaining bits in CTB mask pattern + -- lookups + (reg_ctb_i(3) & reg_ctb_i(4) & + reg_ctb_i(5) & reg_ctb_i(6) & + reg_ctb_i(7) & "111"); + vram_a_o(11 to 13) <= num_line_v(6 to 8); + + when others => + null; + end case; + + -- Sprite Test ---------------------------------------------------------- + when AC_STST | + AC_SATY => + vram_a_o( 0 to 6) <= reg_satb_i; + vram_a_o( 7 to 11) <= spr_num_i; + vram_a_o(12 to 13) <= "00"; + + -- Sprite Attribute Table: X -------------------------------------------- + when AC_SATX => + vram_a_o( 0 to 6) <= reg_satb_i; + vram_a_o( 7 to 11) <= spr_num_i; + vram_a_o(12 to 13) <= "01"; + + -- Sprite Attribute Table: Name ----------------------------------------- + when AC_SATN => + vram_a_o( 0 to 6) <= reg_satb_i; + vram_a_o( 7 to 11) <= spr_num_i; + vram_a_o(12 to 13) <= "10"; + + -- Sprite Attribute Table: Color ---------------------------------------- + when AC_SATC => + vram_a_o( 0 to 6) <= reg_satb_i; + vram_a_o( 7 to 11) <= spr_num_i; + vram_a_o(12 to 13) <= "11"; + + -- Sprite Pattern, Upper Part ------------------------------------------- + when AC_SPTH => + vram_a_o( 0 to 2) <= reg_spgb_i; + if not reg_size1_i then + -- 8x8 sprite + vram_a_o( 3 to 10) <= spr_name_i; + vram_a_o(11 to 13) <= spr_line_i(1 to 3); + else + -- 16x16 sprite + vram_a_o( 3 to 8) <= spr_name_i(0 to 5); + vram_a_o( 9) <= '0'; + vram_a_o(10 to 13) <= spr_line_i; + end if; + + -- Sprite Pattern, Lower Part ------------------------------------------- + when AC_SPTL => + vram_a_o( 0 to 2) <= reg_spgb_i; + vram_a_o( 3 to 8) <= spr_name_i(0 to 5); + vram_a_o( 9) <= '1'; + vram_a_o(10 to 13) <= spr_line_i; + + when others => + null; + + end case; + + end process mux; + -- + ----------------------------------------------------------------------------- + +end rtl; diff --git a/modules/video-vdp18/vdp18_clk_gen.vhd b/modules/video-vdp18/vdp18_clk_gen.vhd index 222e9da..3bbd7cd 100644 --- a/modules/video-vdp18/vdp18_clk_gen.vhd +++ b/modules/video-vdp18/vdp18_clk_gen.vhd @@ -1,154 +1,154 @@ -------------------------------------------------------------------------------- --- --- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. --- --- $Id: vdp18_clk_gen.vhd,v 1.8 2006/06/18 10:47:01 arnim Exp $ --- --- Clock Generator --- -------------------------------------------------------------------------------- --- --- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; - -entity vdp18_clk_gen is - - port ( - clk_i : in std_logic; - clk_en_10m7_i : in std_logic; - reset_i : in boolean; - clk_en_5m37_o : out boolean; - clk_en_3m58_o : out boolean; - clk_en_2m68_o : out boolean - ); - -end vdp18_clk_gen; - - -library ieee; -use ieee.numeric_std.all; - -architecture rtl of vdp18_clk_gen is - - signal cnt_q : unsigned(3 downto 0); - -begin - - ----------------------------------------------------------------------------- - -- Process seq - -- - -- Purpose: - -- Implements the sequential elements. - -- * clock counter - -- - seq: process (clk_i, reset_i) - variable cnt_v : integer range -256 to 255; - begin - if reset_i then - cnt_q <= (others => '0'); - - elsif clk_i'event and clk_i = '1' then - if clk_en_10m7_i = '1' then - if cnt_q = 11 then - -- wrap after counting 12 clocks - cnt_q <= (others => '0'); - else - cnt_q <= cnt_q + 1; - end if; - end if; - - end if; - end process seq; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process clk_en - -- - -- Purpose: - -- Generates the derived clock enable signals. - -- - clk_en: process (clk_en_10m7_i, - cnt_q) - variable cnt_v : integer range -256 to 255; - begin - cnt_v := to_integer(cnt_q); - - -- 5.37 MHz clock enable -------------------------------------------------- - if clk_en_10m7_i = '1' then - case cnt_v is - when 1 | 3 | 5 | 7 | 9 | 11 => - clk_en_5m37_o <= true; - when others => - clk_en_5m37_o <= false; - end case; - else - clk_en_5m37_o <= false; - end if; - - -- 3.58 MHz clock enable -------------------------------------------------- - if clk_en_10m7_i = '1' then - case cnt_v is - when 2 | 5 | 8 | 11 => - clk_en_3m58_o <= true; - when others => - clk_en_3m58_o <= false; - end case; - else - clk_en_3m58_o <= false; - end if; - - -- 2.68 MHz clock enable -------------------------------------------------- - if clk_en_10m7_i = '1' then - case cnt_v is - when 3 | 7 | 11 => - clk_en_2m68_o <= true; - when others => - clk_en_2m68_o <= false; - end case; - else - clk_en_2m68_o <= false; - end if; - - end process clk_en; - -- - ----------------------------------------------------------------------------- - -end rtl; +------------------------------------------------------------------------------- +-- +-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. +-- +-- $Id: vdp18_clk_gen.vhd,v 1.8 2006/06/18 10:47:01 arnim Exp $ +-- +-- Clock Generator +-- +------------------------------------------------------------------------------- +-- +-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; + +entity vdp18_clk_gen is + + port ( + clk_i : in std_logic; + clk_en_10m7_i : in std_logic; + reset_i : in boolean; + clk_en_5m37_o : out boolean; + clk_en_3m58_o : out boolean; + clk_en_2m68_o : out boolean + ); + +end vdp18_clk_gen; + + +library ieee; +use ieee.numeric_std.all; + +architecture rtl of vdp18_clk_gen is + + signal cnt_q : unsigned(3 downto 0); + +begin + + ----------------------------------------------------------------------------- + -- Process seq + -- + -- Purpose: + -- Implements the sequential elements. + -- * clock counter + -- + seq: process (clk_i, reset_i) + variable cnt_v : integer range -256 to 255; + begin + if reset_i then + cnt_q <= (others => '0'); + + elsif clk_i'event and clk_i = '1' then + if clk_en_10m7_i = '1' then + if cnt_q = 11 then + -- wrap after counting 12 clocks + cnt_q <= (others => '0'); + else + cnt_q <= cnt_q + 1; + end if; + end if; + + end if; + end process seq; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process clk_en + -- + -- Purpose: + -- Generates the derived clock enable signals. + -- + clk_en: process (clk_en_10m7_i, + cnt_q) + variable cnt_v : integer range -256 to 255; + begin + cnt_v := to_integer(cnt_q); + + -- 5.37 MHz clock enable -------------------------------------------------- + if clk_en_10m7_i = '1' then + case cnt_v is + when 1 | 3 | 5 | 7 | 9 | 11 => + clk_en_5m37_o <= true; + when others => + clk_en_5m37_o <= false; + end case; + else + clk_en_5m37_o <= false; + end if; + + -- 3.58 MHz clock enable -------------------------------------------------- + if clk_en_10m7_i = '1' then + case cnt_v is + when 2 | 5 | 8 | 11 => + clk_en_3m58_o <= true; + when others => + clk_en_3m58_o <= false; + end case; + else + clk_en_3m58_o <= false; + end if; + + -- 2.68 MHz clock enable -------------------------------------------------- + if clk_en_10m7_i = '1' then + case cnt_v is + when 3 | 7 | 11 => + clk_en_2m68_o <= true; + when others => + clk_en_2m68_o <= false; + end case; + else + clk_en_2m68_o <= false; + end if; + + end process clk_en; + -- + ----------------------------------------------------------------------------- + +end rtl; diff --git a/modules/video-vdp18/vdp18_col_mux.vhd b/modules/video-vdp18/vdp18_col_mux.vhd index fb16eaf..238c87b 100644 --- a/modules/video-vdp18/vdp18_col_mux.vhd +++ b/modules/video-vdp18/vdp18_col_mux.vhd @@ -1,198 +1,198 @@ -------------------------------------------------------------------------------- --- --- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. --- --- $Id: vdp18_col_mux.vhd,v 1.10 2006/06/18 10:47:01 arnim Exp $ --- --- Color Information Multiplexer --- -------------------------------------------------------------------------------- --- --- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; - -entity vdp18_col_mux is - - generic ( - compat_rgb_g : integer := 0 - ); - port ( - clk_i : in std_logic; - clk_en_5m37_i : in boolean; - reset_i : in boolean; - vert_active_i : in boolean; - hor_active_i : in boolean; - border_i : in std_logic; - blank_i : in boolean; - hblank_i : in boolean; - vblank_i : in boolean; - blank_n_o : out boolean; - hblank_n_o : out boolean; - vblank_n_o : out boolean; - reg_col0_i : in std_logic_vector(0 to 3); - pat_col_i : in std_logic_vector(0 to 3); - spr0_col_i : in std_logic_vector(0 to 3); - spr1_col_i : in std_logic_vector(0 to 3); - spr2_col_i : in std_logic_vector(0 to 3); - spr3_col_i : in std_logic_vector(0 to 3); - col_o : out std_logic_vector(0 to 3); - rgb_r_o : out std_logic_vector(0 to 7); - rgb_g_o : out std_logic_vector(0 to 7); - rgb_b_o : out std_logic_vector(0 to 7) - ); - -end vdp18_col_mux; - - -library ieee; -use ieee.numeric_std.all; - -use work.vdp18_col_pack.all; - -architecture rtl of vdp18_col_mux is - - signal col_s : std_logic_vector(0 to 3); - -begin - - ----------------------------------------------------------------------------- - -- Process col_mux - -- - -- Purpose: - -- Multiplexes the color information from different sources. - -- - col_mux: process (blank_i, - hor_active_i, vert_active_i, - spr0_col_i, spr1_col_i, - spr2_col_i, spr3_col_i, - pat_col_i, - reg_col0_i) - begin - if not blank_i then - if hor_active_i and vert_active_i then - -- priority decoder - if spr0_col_i /= "0000" then - col_s <= spr0_col_i; - elsif spr1_col_i /= "0000" then - col_s <= spr1_col_i; - elsif spr2_col_i /= "0000" then - col_s <= spr2_col_i; - elsif spr3_col_i /= "0000" then - col_s <= spr3_col_i; - elsif pat_col_i /= "0000" then - col_s <= pat_col_i; - else - col_s <= reg_col0_i; - end if; - - else - -- display border - col_s <= reg_col0_i; - end if; - - else - -- blank color channels during horizontal and vertical - -- trace back - -- required to initialize colors for each new scan line - col_s <= (others => '0'); - end if; - end process col_mux; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process rgb_reg - -- - -- Purpose: - -- Converts the color information to simple RGB and saves these in - -- output registers. - -- - rgb_reg: process (clk_i, reset_i) - variable col_v : natural range 0 to 15; - variable rgb_r_v, - rgb_g_v, - rgb_b_v : rgb_val_t; - variable rgb_table_v : rgb_table_t; - begin - if reset_i then - rgb_r_o <= (others => '0'); - rgb_g_o <= (others => '0'); - rgb_b_o <= (others => '0'); - - elsif clk_i'event and clk_i = '1' then - if clk_en_5m37_i then - -- select requested RGB table - if compat_rgb_g = 1 then - rgb_table_v := compat_rgb_table_c; - else - rgb_table_v := full_rgb_table_c; - end if; - - -- assign color to RGB channels - col_v := to_integer(unsigned(col_s)); - rgb_r_v := rgb_table_v(col_v)(r_c); - rgb_g_v := rgb_table_v(col_v)(g_c); - rgb_b_v := rgb_table_v(col_v)(b_c); - -- - rgb_r_o <= std_logic_vector(to_unsigned(rgb_r_v, 8)); - rgb_g_o <= std_logic_vector(to_unsigned(rgb_g_v, 8)); - rgb_b_o <= std_logic_vector(to_unsigned(rgb_b_v, 8)); - blank_n_o <= not blank_i; - if border_i = '0' then - hblank_n_o <= hor_active_i; - vblank_n_o <= vert_active_i; - else - hblank_n_o <= not hblank_i; - vblank_n_o <= not vblank_i; - end if; - end if; - - end if; - end process rgb_reg; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Output mapping - ----------------------------------------------------------------------------- - col_o <= col_s; - -end rtl; +------------------------------------------------------------------------------- +-- +-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. +-- +-- $Id: vdp18_col_mux.vhd,v 1.10 2006/06/18 10:47:01 arnim Exp $ +-- +-- Color Information Multiplexer +-- +------------------------------------------------------------------------------- +-- +-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; + +entity vdp18_col_mux is + + generic ( + compat_rgb_g : integer := 0 + ); + port ( + clk_i : in std_logic; + clk_en_5m37_i : in boolean; + reset_i : in boolean; + vert_active_i : in boolean; + hor_active_i : in boolean; + border_i : in std_logic; + blank_i : in boolean; + hblank_i : in boolean; + vblank_i : in boolean; + blank_n_o : out boolean; + hblank_n_o : out boolean; + vblank_n_o : out boolean; + reg_col0_i : in std_logic_vector(0 to 3); + pat_col_i : in std_logic_vector(0 to 3); + spr0_col_i : in std_logic_vector(0 to 3); + spr1_col_i : in std_logic_vector(0 to 3); + spr2_col_i : in std_logic_vector(0 to 3); + spr3_col_i : in std_logic_vector(0 to 3); + col_o : out std_logic_vector(0 to 3); + rgb_r_o : out std_logic_vector(0 to 7); + rgb_g_o : out std_logic_vector(0 to 7); + rgb_b_o : out std_logic_vector(0 to 7) + ); + +end vdp18_col_mux; + + +library ieee; +use ieee.numeric_std.all; + +use work.vdp18_col_pack.all; + +architecture rtl of vdp18_col_mux is + + signal col_s : std_logic_vector(0 to 3); + +begin + + ----------------------------------------------------------------------------- + -- Process col_mux + -- + -- Purpose: + -- Multiplexes the color information from different sources. + -- + col_mux: process (blank_i, + hor_active_i, vert_active_i, + spr0_col_i, spr1_col_i, + spr2_col_i, spr3_col_i, + pat_col_i, + reg_col0_i) + begin + if not blank_i then + if hor_active_i and vert_active_i then + -- priority decoder + if spr0_col_i /= "0000" then + col_s <= spr0_col_i; + elsif spr1_col_i /= "0000" then + col_s <= spr1_col_i; + elsif spr2_col_i /= "0000" then + col_s <= spr2_col_i; + elsif spr3_col_i /= "0000" then + col_s <= spr3_col_i; + elsif pat_col_i /= "0000" then + col_s <= pat_col_i; + else + col_s <= reg_col0_i; + end if; + + else + -- display border + col_s <= reg_col0_i; + end if; + + else + -- blank color channels during horizontal and vertical + -- trace back + -- required to initialize colors for each new scan line + col_s <= (others => '0'); + end if; + end process col_mux; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process rgb_reg + -- + -- Purpose: + -- Converts the color information to simple RGB and saves these in + -- output registers. + -- + rgb_reg: process (clk_i, reset_i) + variable col_v : natural range 0 to 15; + variable rgb_r_v, + rgb_g_v, + rgb_b_v : rgb_val_t; + variable rgb_table_v : rgb_table_t; + begin + if reset_i then + rgb_r_o <= (others => '0'); + rgb_g_o <= (others => '0'); + rgb_b_o <= (others => '0'); + + elsif clk_i'event and clk_i = '1' then + if clk_en_5m37_i then + -- select requested RGB table + if compat_rgb_g = 1 then + rgb_table_v := compat_rgb_table_c; + else + rgb_table_v := full_rgb_table_c; + end if; + + -- assign color to RGB channels + col_v := to_integer(unsigned(col_s)); + rgb_r_v := rgb_table_v(col_v)(r_c); + rgb_g_v := rgb_table_v(col_v)(g_c); + rgb_b_v := rgb_table_v(col_v)(b_c); + -- + rgb_r_o <= std_logic_vector(to_unsigned(rgb_r_v, 8)); + rgb_g_o <= std_logic_vector(to_unsigned(rgb_g_v, 8)); + rgb_b_o <= std_logic_vector(to_unsigned(rgb_b_v, 8)); + blank_n_o <= not blank_i; + if border_i = '0' then + hblank_n_o <= hor_active_i; + vblank_n_o <= vert_active_i; + else + hblank_n_o <= not hblank_i; + vblank_n_o <= not vblank_i; + end if; + end if; + + end if; + end process rgb_reg; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Output mapping + ----------------------------------------------------------------------------- + col_o <= col_s; + +end rtl; diff --git a/modules/video-vdp18/vdp18_col_pack-p.vhd b/modules/video-vdp18/vdp18_col_pack-p.vhd index 701a00d..1f7a29e 100644 --- a/modules/video-vdp18/vdp18_col_pack-p.vhd +++ b/modules/video-vdp18/vdp18_col_pack-p.vhd @@ -1,83 +1,83 @@ -------------------------------------------------------------------------------- --- --- $Id: vdp18_col_pack-p.vhd,v 1.3 2006/02/28 22:30:41 arnim Exp $ --- --- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) --- --- All rights reserved --- -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; - -package vdp18_col_pack is - - constant r_c : natural := 0; - constant g_c : natural := 1; - constant b_c : natural := 2; - - subtype rgb_val_t is natural range 0 to 255; - type rgb_triple_t is array (natural range 0 to 2) of - rgb_val_t; - type rgb_table_t is array (natural range 0 to 15) of - rgb_triple_t; - - ----------------------------------------------------------------------------- - -- Simple RGB Value Array - -- - -- Refer to http://junior.apk.net/~drushel/pub/coleco/twwmca/wk970202.html - -- This is the MF & MdK variant. Note: only the upper three bits are used. - -- - -- - constant compat_rgb_table_c : rgb_table_t := ( - -- R G B - ( 0, 0, 0), -- Transparent - ( 0, 0, 0), -- Black - ( 32, 192, 32), -- Medium Green - ( 96, 224, 96), -- Light Green - ( 32, 32, 224), -- Dark Blue - ( 64, 96, 224), -- Light Blue - (160, 32, 32), -- Dark Red - ( 64, 192, 224), -- Cyan - (224, 32, 32), -- Medium Red - (224, 96, 96), -- Light Red - (192, 192, 32), -- Dark Yellow - (192, 192, 128), -- Light Yellow - ( 32, 128, 32), -- Dark Green - (192, 64, 160), -- Magenta - (160, 160, 160), -- Gray - (224, 224, 224) -- White - ); - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Full RGB Value Array - -- - -- Refer to tms9928a.c of the MAME source distribution. - -- - constant full_rgb_table_c : rgb_table_t := ( - -- R G B - ( 0, 0, 0), -- Transparent - ( 0, 0, 0), -- Black - ( 33, 200, 66), -- Medium Green - ( 94, 220, 120), -- Light Green - ( 84, 85, 237), -- Dark Blue - (125, 118, 252), -- Light Blue - (212, 82, 77), -- Dark Red - ( 66, 235, 245), -- Cyan - (252, 85, 84), -- Medium Red - (255, 121, 120), -- Light Red - (212, 193, 84), -- Dark Yellow - (230, 206, 128), -- Light Yellow - ( 33, 176, 59), -- Dark Green - (201, 91, 186), -- Magenta - (204, 204, 204), -- Gray - (255, 255, 255) -- White - ); - -- - ----------------------------------------------------------------------------- - -end vdp18_col_pack; +------------------------------------------------------------------------------- +-- +-- $Id: vdp18_col_pack-p.vhd,v 1.3 2006/02/28 22:30:41 arnim Exp $ +-- +-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +-- +-- All rights reserved +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; + +package vdp18_col_pack is + + constant r_c : natural := 0; + constant g_c : natural := 1; + constant b_c : natural := 2; + + subtype rgb_val_t is natural range 0 to 255; + type rgb_triple_t is array (natural range 0 to 2) of + rgb_val_t; + type rgb_table_t is array (natural range 0 to 15) of + rgb_triple_t; + + ----------------------------------------------------------------------------- + -- Simple RGB Value Array + -- + -- Refer to http://junior.apk.net/~drushel/pub/coleco/twwmca/wk970202.html + -- This is the MF & MdK variant. Note: only the upper three bits are used. + -- + -- + constant compat_rgb_table_c : rgb_table_t := ( + -- R G B + ( 0, 0, 0), -- Transparent + ( 0, 0, 0), -- Black + ( 32, 192, 32), -- Medium Green + ( 96, 224, 96), -- Light Green + ( 32, 32, 224), -- Dark Blue + ( 64, 96, 224), -- Light Blue + (160, 32, 32), -- Dark Red + ( 64, 192, 224), -- Cyan + (224, 32, 32), -- Medium Red + (224, 96, 96), -- Light Red + (192, 192, 32), -- Dark Yellow + (192, 192, 128), -- Light Yellow + ( 32, 128, 32), -- Dark Green + (192, 64, 160), -- Magenta + (160, 160, 160), -- Gray + (224, 224, 224) -- White + ); + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Full RGB Value Array + -- + -- Refer to tms9928a.c of the MAME source distribution. + -- + constant full_rgb_table_c : rgb_table_t := ( + -- R G B + ( 0, 0, 0), -- Transparent + ( 0, 0, 0), -- Black + ( 33, 200, 66), -- Medium Green + ( 94, 220, 120), -- Light Green + ( 84, 85, 237), -- Dark Blue + (125, 118, 252), -- Light Blue + (212, 82, 77), -- Dark Red + ( 66, 235, 245), -- Cyan + (252, 85, 84), -- Medium Red + (255, 121, 120), -- Light Red + (212, 193, 84), -- Dark Yellow + (230, 206, 128), -- Light Yellow + ( 33, 176, 59), -- Dark Green + (201, 91, 186), -- Magenta + (204, 204, 204), -- Gray + (255, 255, 255) -- White + ); + -- + ----------------------------------------------------------------------------- + +end vdp18_col_pack; diff --git a/modules/video-vdp18/vdp18_core.vhd b/modules/video-vdp18/vdp18_core.vhd index 836334e..6e448fe 100644 --- a/modules/video-vdp18/vdp18_core.vhd +++ b/modules/video-vdp18/vdp18_core.vhd @@ -1,404 +1,404 @@ -------------------------------------------------------------------------------- --- --- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. --- --- $Id: vdp18_core.vhd,v 1.28 2006/06/18 10:47:01 arnim Exp $ --- --- Core Toplevel --- --- Notes: --- This core implements a simple VRAM interface which is suitable for a --- synchronous SRAM component. There is currently no support of the --- original DRAM interface. --- --- Please be aware that the colors might me slightly different from the --- original TMS9918. It is assumed that the simplified conversion to RGB --- encoding is equivalent to the compatability mode of the V9938. --- Implementing a 100% correct color encoding for RGB would require --- significantly more logic and 8-bit wide RGB DACs. --- --- References: --- --- * TI Data book TMS9918.pdf --- http://www.bitsavers.org/pdf/ti/_dataBooks/TMS9918.pdf --- --- * Sean Young's tech article: --- http://bifi.msxnet.org/msxnet/tech/tms9918a.txt --- --- * Paul Urbanus' discussion of the timing details --- http://bifi.msxnet.org/msxnet/tech/tmsposting.txt --- --- * Richard F. Drushel's article series --- "This Week With My Coleco ADAM" --- http://junior.apk.net/~drushel/pub/coleco/twwmca/index.html --- -------------------------------------------------------------------------------- --- --- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use work.vdp18_pack.all; - -entity vdp18_core is - - generic ( - compat_rgb_g : integer := 0 - ); - port ( - -- Global Interface ------------------------------------------------------- - clk_i : in std_logic; - clk_en_10m7_i : in std_logic; - reset_n_i : in std_logic; - -- CPU Interface ---------------------------------------------------------- - csr_n_i : in std_logic; - csw_n_i : in std_logic; - mode_i : in std_logic; - int_n_o : out std_logic; - cd_i : in std_logic_vector(0 to 7); - cd_o : out std_logic_vector(0 to 7); - -- VRAM Interface --------------------------------------------------------- - vram_we_o : out std_logic; - vram_a_o : out std_logic_vector(0 to 13); - vram_d_o : out std_logic_vector(0 to 7); - vram_d_i : in std_logic_vector(0 to 7); - -- Video Interface -------------------------------------------------------- - border_i : in std_logic; - is_pal_i : in std_logic; - col_o : out std_logic_vector(0 to 3); - rgb_r_o : out std_logic_vector(0 to 7); - rgb_g_o : out std_logic_vector(0 to 7); - rgb_b_o : out std_logic_vector(0 to 7); - hsync_n_o : out std_logic; - vsync_n_o : out std_logic; - blank_n_o : out std_logic; - hblank_o : out std_logic; - vblank_o : out std_logic; - comp_sync_n_o : out std_logic - ); - -end vdp18_core; - -architecture struct of vdp18_core is - - signal reset_s : boolean; - - signal clk_en_10m7_s, - clk_en_5m37_s, - clk_en_acc_s : boolean; - - signal opmode_s : opmode_t; - - signal access_type_s : access_t; - - signal num_pix_s, - num_line_s : hv_t; - signal hsync_n_s, - vsync_n_s : std_logic; - signal blank_s : boolean; - signal hblank_s : boolean; - signal vblank_s : boolean; - - signal vert_inc_s : boolean; - - signal reg_blank_s, - reg_size1_s, - reg_mag1_s : boolean; - - signal spr_5th_s : boolean; - signal spr_5th_num_s : std_logic_vector(0 to 4); - - signal stop_sprite_s : boolean; - signal vert_active_s, - hor_active_s : boolean; - - signal rd_s, - wr_s : boolean; - - signal reg_ntb_s : std_logic_vector(0 to 3); - signal reg_ctb_s : std_logic_vector(0 to 7); - signal reg_pgb_s : std_logic_vector(0 to 2); - signal reg_satb_s : std_logic_vector(0 to 6); - signal reg_spgb_s : std_logic_vector(0 to 2); - signal reg_col1_s, - reg_col0_s : std_logic_vector(0 to 3); - signal cpu_vram_a_s : std_logic_vector(0 to 13); - - signal pat_table_s : std_logic_vector(0 to 9); - signal pat_name_s : std_logic_vector(0 to 7); - signal pat_col_s : std_logic_vector(0 to 3); - - signal spr_num_s : std_logic_vector(0 to 4); - signal spr_line_s : std_logic_vector(0 to 3); - signal spr_name_s : std_logic_vector(0 to 7); - signal spr0_col_s, - spr1_col_s, - spr2_col_s, - spr3_col_s : std_logic_vector(0 to 3); - signal spr_coll_s : boolean; - - signal irq_s : boolean; - - signal blank_n : boolean; - signal hblank_n : boolean; - signal vblank_n : boolean; - -begin - - clk_en_10m7_s <= to_boolean_f(clk_en_10m7_i); - rd_s <= not to_boolean_f(csr_n_i); - wr_s <= not to_boolean_f(csw_n_i); - - reset_s <= reset_n_i = '0'; - - - ----------------------------------------------------------------------------- - -- Clock Generator - ----------------------------------------------------------------------------- - clk_gen_b : work.vdp18_clk_gen - port map ( - clk_i => clk_i, - clk_en_10m7_i => clk_en_10m7_i, - reset_i => reset_s, - clk_en_5m37_o => clk_en_5m37_s, - clk_en_2m68_o => open - ); - - - ----------------------------------------------------------------------------- - -- Horizontal and Vertical Timing Generator - ----------------------------------------------------------------------------- - hor_vert_b : work.vdp18_hor_vert - port map ( - clk_i => clk_i, - clk_en_5m37_i => clk_en_5m37_s, - reset_i => reset_s, - opmode_i => opmode_s, - num_pix_o => num_pix_s, - num_line_o => num_line_s, - vert_inc_o => vert_inc_s, - hsync_n_o => hsync_n_s, - vsync_n_o => vsync_n_s, - blank_o => blank_s, - hblank_o => hblank_s, - vblank_o => vblank_s, - is_pal_i => is_pal_i - ); - - hsync_n_o <= hsync_n_s; - vsync_n_o <= vsync_n_s; - comp_sync_n_o <= not (hsync_n_s xor vsync_n_s); - - - ----------------------------------------------------------------------------- - -- Control Module - ----------------------------------------------------------------------------- - ctrl_b : work.vdp18_ctrl - port map ( - clk_i => clk_i, - clk_en_5m37_i => clk_en_5m37_s, - reset_i => reset_s, - opmode_i => opmode_s, - num_pix_i => num_pix_s, - num_line_i => num_line_s, - vert_inc_i => vert_inc_s, - reg_blank_i => reg_blank_s, - reg_size1_i => reg_size1_s, - stop_sprite_i => stop_sprite_s, - clk_en_acc_o => clk_en_acc_s, - access_type_o => access_type_s, - vert_active_o => vert_active_s, - hor_active_o => hor_active_s, - irq_o => irq_s - ); - - - ----------------------------------------------------------------------------- - -- CPU I/O Module - ----------------------------------------------------------------------------- - cpu_io_b : work.vdp18_cpuio - port map ( - clk_i => clk_i, - clk_en_10m7_i => clk_en_10m7_s, - clk_en_acc_i => clk_en_acc_s, - reset_i => reset_s, - rd_i => rd_s, - wr_i => wr_s, - mode_i => mode_i, - cd_i => cd_i, - cd_o => cd_o, - cd_oe_o => open, - access_type_i => access_type_s, - opmode_o => opmode_s, - vram_we_o => vram_we_o, - vram_a_o => cpu_vram_a_s, - vram_d_o => vram_d_o, - vram_d_i => vram_d_i, - spr_coll_i => spr_coll_s, - spr_5th_i => spr_5th_s, - spr_5th_num_i => spr_5th_num_s, - reg_ev_o => open, - reg_16k_o => open, - reg_blank_o => reg_blank_s, - reg_size1_o => reg_size1_s, - reg_mag1_o => reg_mag1_s, - reg_ntb_o => reg_ntb_s, - reg_ctb_o => reg_ctb_s, - reg_pgb_o => reg_pgb_s, - reg_satb_o => reg_satb_s, - reg_spgb_o => reg_spgb_s, - reg_col1_o => reg_col1_s, - reg_col0_o => reg_col0_s, - irq_i => irq_s, - int_n_o => int_n_o - ); - - - ----------------------------------------------------------------------------- - -- VRAM Address Multiplexer - ----------------------------------------------------------------------------- - addr_mux_b : work.vdp18_addr_mux - port map ( - access_type_i => access_type_s, - opmode_i => opmode_s, - num_line_i => num_line_s, - reg_ntb_i => reg_ntb_s, - reg_ctb_i => reg_ctb_s, - reg_pgb_i => reg_pgb_s, - reg_satb_i => reg_satb_s, - reg_spgb_i => reg_spgb_s, - reg_size1_i => reg_size1_s, - cpu_vram_a_i => cpu_vram_a_s, - pat_table_i => pat_table_s, - pat_name_i => pat_name_s, - spr_num_i => spr_num_s, - spr_line_i => spr_line_s, - spr_name_i => spr_name_s, - vram_a_o => vram_a_o - ); - - - ----------------------------------------------------------------------------- - -- Pattern Generator - ----------------------------------------------------------------------------- - pattern_b : work.vdp18_pattern - port map ( - clk_i => clk_i, - clk_en_5m37_i => clk_en_5m37_s, - clk_en_acc_i => clk_en_acc_s, - reset_i => reset_s, - opmode_i => opmode_s, - access_type_i => access_type_s, - num_line_i => num_line_s, - vram_d_i => vram_d_i, - vert_inc_i => vert_inc_s, - vsync_n_i => vsync_n_s, - reg_col1_i => reg_col1_s, - reg_col0_i => reg_col0_s, - pat_table_o => pat_table_s, - pat_name_o => pat_name_s, - pat_col_o => pat_col_s - ); - - - ----------------------------------------------------------------------------- - -- Sprite Generator - ----------------------------------------------------------------------------- - sprite_b : work.vdp18_sprite - port map ( - clk_i => clk_i, - clk_en_5m37_i => clk_en_5m37_s, - clk_en_acc_i => clk_en_acc_s, - reset_i => reset_s, - access_type_i => access_type_s, - num_pix_i => num_pix_s, - num_line_i => num_line_s, - vram_d_i => vram_d_i, - vert_inc_i => vert_inc_s, - reg_size1_i => reg_size1_s, - reg_mag1_i => reg_mag1_s, - spr_5th_o => spr_5th_s, - spr_5th_num_o => spr_5th_num_s, - stop_sprite_o => stop_sprite_s, - spr_coll_o => spr_coll_s, - spr_num_o => spr_num_s, - spr_line_o => spr_line_s, - spr_name_o => spr_name_s, - spr0_col_o => spr0_col_s, - spr1_col_o => spr1_col_s, - spr2_col_o => spr2_col_s, - spr3_col_o => spr3_col_s - ); - - - ----------------------------------------------------------------------------- - -- Color Multiplexer - ----------------------------------------------------------------------------- - col_mux_b : work.vdp18_col_mux - generic map ( - compat_rgb_g => compat_rgb_g - ) - port map ( - clk_i => clk_i, - clk_en_5m37_i => clk_en_5m37_s, - reset_i => reset_s, - vert_active_i => vert_active_s, - hor_active_i => hor_active_s, - border_i => border_i, - blank_i => blank_s, - hblank_i => hblank_s, - vblank_i => vblank_s, - reg_col0_i => reg_col0_s, - pat_col_i => pat_col_s, - spr0_col_i => spr0_col_s, - spr1_col_i => spr1_col_s, - spr2_col_i => spr2_col_s, - spr3_col_i => spr3_col_s, - col_o => col_o, - blank_n_o => blank_n, - hblank_n_o => hblank_n, - vblank_n_o => vblank_n, - rgb_r_o => rgb_r_o, - rgb_g_o => rgb_g_o, - rgb_b_o => rgb_b_o - ); - - blank_n_o <= '1' when blank_n else '0'; - hblank_o <= '0' when hblank_n else '1'; - vblank_o <= '0' when vblank_n else '1'; - -end struct; +------------------------------------------------------------------------------- +-- +-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. +-- +-- $Id: vdp18_core.vhd,v 1.28 2006/06/18 10:47:01 arnim Exp $ +-- +-- Core Toplevel +-- +-- Notes: +-- This core implements a simple VRAM interface which is suitable for a +-- synchronous SRAM component. There is currently no support of the +-- original DRAM interface. +-- +-- Please be aware that the colors might me slightly different from the +-- original TMS9918. It is assumed that the simplified conversion to RGB +-- encoding is equivalent to the compatability mode of the V9938. +-- Implementing a 100% correct color encoding for RGB would require +-- significantly more logic and 8-bit wide RGB DACs. +-- +-- References: +-- +-- * TI Data book TMS9918.pdf +-- http://www.bitsavers.org/pdf/ti/_dataBooks/TMS9918.pdf +-- +-- * Sean Young's tech article: +-- http://bifi.msxnet.org/msxnet/tech/tms9918a.txt +-- +-- * Paul Urbanus' discussion of the timing details +-- http://bifi.msxnet.org/msxnet/tech/tmsposting.txt +-- +-- * Richard F. Drushel's article series +-- "This Week With My Coleco ADAM" +-- http://junior.apk.net/~drushel/pub/coleco/twwmca/index.html +-- +------------------------------------------------------------------------------- +-- +-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use work.vdp18_pack.all; + +entity vdp18_core is + + generic ( + compat_rgb_g : integer := 0 + ); + port ( + -- Global Interface ------------------------------------------------------- + clk_i : in std_logic; + clk_en_10m7_i : in std_logic; + reset_n_i : in std_logic; + -- CPU Interface ---------------------------------------------------------- + csr_n_i : in std_logic; + csw_n_i : in std_logic; + mode_i : in std_logic; + int_n_o : out std_logic; + cd_i : in std_logic_vector(0 to 7); + cd_o : out std_logic_vector(0 to 7); + -- VRAM Interface --------------------------------------------------------- + vram_we_o : out std_logic; + vram_a_o : out std_logic_vector(0 to 13); + vram_d_o : out std_logic_vector(0 to 7); + vram_d_i : in std_logic_vector(0 to 7); + -- Video Interface -------------------------------------------------------- + border_i : in std_logic; + is_pal_i : in std_logic; + col_o : out std_logic_vector(0 to 3); + rgb_r_o : out std_logic_vector(0 to 7); + rgb_g_o : out std_logic_vector(0 to 7); + rgb_b_o : out std_logic_vector(0 to 7); + hsync_n_o : out std_logic; + vsync_n_o : out std_logic; + blank_n_o : out std_logic; + hblank_o : out std_logic; + vblank_o : out std_logic; + comp_sync_n_o : out std_logic + ); + +end vdp18_core; + +architecture struct of vdp18_core is + + signal reset_s : boolean; + + signal clk_en_10m7_s, + clk_en_5m37_s, + clk_en_acc_s : boolean; + + signal opmode_s : opmode_t; + + signal access_type_s : access_t; + + signal num_pix_s, + num_line_s : hv_t; + signal hsync_n_s, + vsync_n_s : std_logic; + signal blank_s : boolean; + signal hblank_s : boolean; + signal vblank_s : boolean; + + signal vert_inc_s : boolean; + + signal reg_blank_s, + reg_size1_s, + reg_mag1_s : boolean; + + signal spr_5th_s : boolean; + signal spr_5th_num_s : std_logic_vector(0 to 4); + + signal stop_sprite_s : boolean; + signal vert_active_s, + hor_active_s : boolean; + + signal rd_s, + wr_s : boolean; + + signal reg_ntb_s : std_logic_vector(0 to 3); + signal reg_ctb_s : std_logic_vector(0 to 7); + signal reg_pgb_s : std_logic_vector(0 to 2); + signal reg_satb_s : std_logic_vector(0 to 6); + signal reg_spgb_s : std_logic_vector(0 to 2); + signal reg_col1_s, + reg_col0_s : std_logic_vector(0 to 3); + signal cpu_vram_a_s : std_logic_vector(0 to 13); + + signal pat_table_s : std_logic_vector(0 to 9); + signal pat_name_s : std_logic_vector(0 to 7); + signal pat_col_s : std_logic_vector(0 to 3); + + signal spr_num_s : std_logic_vector(0 to 4); + signal spr_line_s : std_logic_vector(0 to 3); + signal spr_name_s : std_logic_vector(0 to 7); + signal spr0_col_s, + spr1_col_s, + spr2_col_s, + spr3_col_s : std_logic_vector(0 to 3); + signal spr_coll_s : boolean; + + signal irq_s : boolean; + + signal blank_n : boolean; + signal hblank_n : boolean; + signal vblank_n : boolean; + +begin + + clk_en_10m7_s <= to_boolean_f(clk_en_10m7_i); + rd_s <= not to_boolean_f(csr_n_i); + wr_s <= not to_boolean_f(csw_n_i); + + reset_s <= reset_n_i = '0'; + + + ----------------------------------------------------------------------------- + -- Clock Generator + ----------------------------------------------------------------------------- + clk_gen_b : work.vdp18_clk_gen + port map ( + clk_i => clk_i, + clk_en_10m7_i => clk_en_10m7_i, + reset_i => reset_s, + clk_en_5m37_o => clk_en_5m37_s, + clk_en_2m68_o => open + ); + + + ----------------------------------------------------------------------------- + -- Horizontal and Vertical Timing Generator + ----------------------------------------------------------------------------- + hor_vert_b : work.vdp18_hor_vert + port map ( + clk_i => clk_i, + clk_en_5m37_i => clk_en_5m37_s, + reset_i => reset_s, + opmode_i => opmode_s, + num_pix_o => num_pix_s, + num_line_o => num_line_s, + vert_inc_o => vert_inc_s, + hsync_n_o => hsync_n_s, + vsync_n_o => vsync_n_s, + blank_o => blank_s, + hblank_o => hblank_s, + vblank_o => vblank_s, + is_pal_i => is_pal_i + ); + + hsync_n_o <= hsync_n_s; + vsync_n_o <= vsync_n_s; + comp_sync_n_o <= not (hsync_n_s xor vsync_n_s); + + + ----------------------------------------------------------------------------- + -- Control Module + ----------------------------------------------------------------------------- + ctrl_b : work.vdp18_ctrl + port map ( + clk_i => clk_i, + clk_en_5m37_i => clk_en_5m37_s, + reset_i => reset_s, + opmode_i => opmode_s, + num_pix_i => num_pix_s, + num_line_i => num_line_s, + vert_inc_i => vert_inc_s, + reg_blank_i => reg_blank_s, + reg_size1_i => reg_size1_s, + stop_sprite_i => stop_sprite_s, + clk_en_acc_o => clk_en_acc_s, + access_type_o => access_type_s, + vert_active_o => vert_active_s, + hor_active_o => hor_active_s, + irq_o => irq_s + ); + + + ----------------------------------------------------------------------------- + -- CPU I/O Module + ----------------------------------------------------------------------------- + cpu_io_b : work.vdp18_cpuio + port map ( + clk_i => clk_i, + clk_en_10m7_i => clk_en_10m7_s, + clk_en_acc_i => clk_en_acc_s, + reset_i => reset_s, + rd_i => rd_s, + wr_i => wr_s, + mode_i => mode_i, + cd_i => cd_i, + cd_o => cd_o, + cd_oe_o => open, + access_type_i => access_type_s, + opmode_o => opmode_s, + vram_we_o => vram_we_o, + vram_a_o => cpu_vram_a_s, + vram_d_o => vram_d_o, + vram_d_i => vram_d_i, + spr_coll_i => spr_coll_s, + spr_5th_i => spr_5th_s, + spr_5th_num_i => spr_5th_num_s, + reg_ev_o => open, + reg_16k_o => open, + reg_blank_o => reg_blank_s, + reg_size1_o => reg_size1_s, + reg_mag1_o => reg_mag1_s, + reg_ntb_o => reg_ntb_s, + reg_ctb_o => reg_ctb_s, + reg_pgb_o => reg_pgb_s, + reg_satb_o => reg_satb_s, + reg_spgb_o => reg_spgb_s, + reg_col1_o => reg_col1_s, + reg_col0_o => reg_col0_s, + irq_i => irq_s, + int_n_o => int_n_o + ); + + + ----------------------------------------------------------------------------- + -- VRAM Address Multiplexer + ----------------------------------------------------------------------------- + addr_mux_b : work.vdp18_addr_mux + port map ( + access_type_i => access_type_s, + opmode_i => opmode_s, + num_line_i => num_line_s, + reg_ntb_i => reg_ntb_s, + reg_ctb_i => reg_ctb_s, + reg_pgb_i => reg_pgb_s, + reg_satb_i => reg_satb_s, + reg_spgb_i => reg_spgb_s, + reg_size1_i => reg_size1_s, + cpu_vram_a_i => cpu_vram_a_s, + pat_table_i => pat_table_s, + pat_name_i => pat_name_s, + spr_num_i => spr_num_s, + spr_line_i => spr_line_s, + spr_name_i => spr_name_s, + vram_a_o => vram_a_o + ); + + + ----------------------------------------------------------------------------- + -- Pattern Generator + ----------------------------------------------------------------------------- + pattern_b : work.vdp18_pattern + port map ( + clk_i => clk_i, + clk_en_5m37_i => clk_en_5m37_s, + clk_en_acc_i => clk_en_acc_s, + reset_i => reset_s, + opmode_i => opmode_s, + access_type_i => access_type_s, + num_line_i => num_line_s, + vram_d_i => vram_d_i, + vert_inc_i => vert_inc_s, + vsync_n_i => vsync_n_s, + reg_col1_i => reg_col1_s, + reg_col0_i => reg_col0_s, + pat_table_o => pat_table_s, + pat_name_o => pat_name_s, + pat_col_o => pat_col_s + ); + + + ----------------------------------------------------------------------------- + -- Sprite Generator + ----------------------------------------------------------------------------- + sprite_b : work.vdp18_sprite + port map ( + clk_i => clk_i, + clk_en_5m37_i => clk_en_5m37_s, + clk_en_acc_i => clk_en_acc_s, + reset_i => reset_s, + access_type_i => access_type_s, + num_pix_i => num_pix_s, + num_line_i => num_line_s, + vram_d_i => vram_d_i, + vert_inc_i => vert_inc_s, + reg_size1_i => reg_size1_s, + reg_mag1_i => reg_mag1_s, + spr_5th_o => spr_5th_s, + spr_5th_num_o => spr_5th_num_s, + stop_sprite_o => stop_sprite_s, + spr_coll_o => spr_coll_s, + spr_num_o => spr_num_s, + spr_line_o => spr_line_s, + spr_name_o => spr_name_s, + spr0_col_o => spr0_col_s, + spr1_col_o => spr1_col_s, + spr2_col_o => spr2_col_s, + spr3_col_o => spr3_col_s + ); + + + ----------------------------------------------------------------------------- + -- Color Multiplexer + ----------------------------------------------------------------------------- + col_mux_b : work.vdp18_col_mux + generic map ( + compat_rgb_g => compat_rgb_g + ) + port map ( + clk_i => clk_i, + clk_en_5m37_i => clk_en_5m37_s, + reset_i => reset_s, + vert_active_i => vert_active_s, + hor_active_i => hor_active_s, + border_i => border_i, + blank_i => blank_s, + hblank_i => hblank_s, + vblank_i => vblank_s, + reg_col0_i => reg_col0_s, + pat_col_i => pat_col_s, + spr0_col_i => spr0_col_s, + spr1_col_i => spr1_col_s, + spr2_col_i => spr2_col_s, + spr3_col_i => spr3_col_s, + col_o => col_o, + blank_n_o => blank_n, + hblank_n_o => hblank_n, + vblank_n_o => vblank_n, + rgb_r_o => rgb_r_o, + rgb_g_o => rgb_g_o, + rgb_b_o => rgb_b_o + ); + + blank_n_o <= '1' when blank_n else '0'; + hblank_o <= '0' when hblank_n else '1'; + vblank_o <= '0' when vblank_n else '1'; + +end struct; diff --git a/modules/video-vdp18/vdp18_cpuio.vhd b/modules/video-vdp18/vdp18_cpuio.vhd index 41277d8..35a46c0 100644 --- a/modules/video-vdp18/vdp18_cpuio.vhd +++ b/modules/video-vdp18/vdp18_cpuio.vhd @@ -1,570 +1,570 @@ -------------------------------------------------------------------------------- --- --- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. --- --- $Id: vdp18_cpuio.vhd,v 1.17 2006/06/18 10:47:01 arnim Exp $ --- --- CPU I/O Interface Module --- -------------------------------------------------------------------------------- --- --- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; - -use work.vdp18_pack.access_t; -use work.vdp18_pack.opmode_t; - -entity vdp18_cpuio is - - port ( - clk_i : in std_logic; - clk_en_10m7_i : in boolean; - clk_en_acc_i : in boolean; - reset_i : in boolean; - rd_i : in boolean; - wr_i : in boolean; - mode_i : in std_logic; - cd_i : in std_logic_vector(0 to 7); - cd_o : out std_logic_vector(0 to 7); - cd_oe_o : out std_logic; - access_type_i : in access_t; - opmode_o : out opmode_t; - vram_we_o : out std_logic; - vram_a_o : out std_logic_vector(0 to 13); - vram_d_o : out std_logic_vector(0 to 7); - vram_d_i : in std_logic_vector(0 to 7); - spr_coll_i : in boolean; - spr_5th_i : in boolean; - spr_5th_num_i : in std_logic_vector(0 to 4); - reg_ev_o : out boolean; - reg_16k_o : out boolean; - reg_blank_o : out boolean; - reg_size1_o : out boolean; - reg_mag1_o : out boolean; - reg_ntb_o : out std_logic_vector(0 to 3); - reg_ctb_o : out std_logic_vector(0 to 7); - reg_pgb_o : out std_logic_vector(0 to 2); - reg_satb_o : out std_logic_vector(0 to 6); - reg_spgb_o : out std_logic_vector(0 to 2); - reg_col1_o : out std_logic_vector(0 to 3); - reg_col0_o : out std_logic_vector(0 to 3); - irq_i : in boolean; - int_n_o : out std_logic - ); - -end vdp18_cpuio; - - -library ieee; -use ieee.numeric_std.all; - -use work.vdp18_pack.all; - -architecture rtl of vdp18_cpuio is - - type state_t is (ST_IDLE, - ST_RD_MODE0, ST_WR_MODE0, - ST_RD_MODE1, - ST_WR_MODE1_1ST, ST_WR_MODE1_1ST_IDLE, - ST_WR_MODE1_2ND_VREAD, ST_WR_MODE1_2ND_VWRITE, - ST_WR_MODE1_2ND_RWRITE); - signal state_s, - state_q : state_t; - - signal buffer_q : std_logic_vector(0 to 7); - - signal addr_q : unsigned(0 to 13); - - signal incr_addr_s, - load_addr_s : boolean; - - signal wrbuf_cpu_s : boolean; - signal sched_rdvram_s, - rdvram_sched_q, - rdvram_q : boolean; - signal abort_wrvram_s, - sched_wrvram_s, - wrvram_sched_q, - wrvram_q : boolean; - - signal write_tmp_s : boolean; - signal tmp_q : std_logic_vector(0 to 7); - signal write_reg_s : boolean; - - -- control register bits ---------------------------------------------------- - type ctrl_reg_t is array (natural range 7 downto 0) of - std_logic_vector(0 to 7); - signal ctrl_reg_q : ctrl_reg_t; - - -- status register ---------------------------------------------------------- - signal status_reg_s : std_logic_vector(0 to 7); - signal destr_rd_status_s : boolean; - signal sprite_5th_q : boolean; - signal sprite_5th_num_q : std_logic_vector(0 to 4); - signal sprite_coll_q : boolean; - signal int_n_q : std_logic; - - - type read_mux_t is (RDMUX_STATUS, RDMUX_READAHEAD); - signal read_mux_s : read_mux_t; - -begin - - ----------------------------------------------------------------------------- - -- Process seq - -- - -- Purpose: - -- Implements the sequential elements. - -- - seq: process (clk_i, reset_i) - variable incr_addr_v : boolean; - begin - if reset_i then - state_q <= ST_IDLE; - buffer_q <= (others => '0'); - addr_q <= (others => '0'); - rdvram_sched_q <= false; - rdvram_q <= false; - wrvram_sched_q <= false; - wrvram_q <= false; - - elsif clk_i'event and clk_i = '1' then - -- default assignments - incr_addr_v := incr_addr_s; - - if clk_en_10m7_i then - -- update state vector ------------------------------------------------ - state_q <= state_s; - - -- buffer and flag control -------------------------------------------- - if wrbuf_cpu_s then - -- write read-ahead buffer from CPU bus - buffer_q <= cd_i; - -- immediately stop read-ahead - rdvram_sched_q <= false; - rdvram_q <= false; - elsif clk_en_acc_i and - rdvram_q and - access_type_i = AC_CPU then - -- write read-ahead buffer from VRAM during CPU access slot - buffer_q <= vram_d_i; - -- stop scanning for CPU data - rdvram_q <= false; - -- increment read-ahead address - incr_addr_v := true; - end if; - - if sched_rdvram_s then - -- immediately stop write-back - wrvram_sched_q <= false; - wrvram_q <= false; - -- schedule read-ahead - rdvram_sched_q <= true; - end if; - - if sched_wrvram_s then - -- schedule write-back - wrvram_sched_q <= true; - end if; - - if abort_wrvram_s then - -- stop scanning for write-back - wrvram_q <= false; - end if; - - if rdvram_sched_q and clk_en_acc_i then - -- align scheduled read-ahead with access slot phase - rdvram_sched_q <= false; - rdvram_q <= true; - end if; - if wrvram_sched_q and clk_en_acc_i then - -- align scheduled write-back with access slot phase - wrvram_sched_q <= false; - wrvram_q <= true; - end if; - - -- manage address ----------------------------------------------------- - if load_addr_s then - addr_q(6 to 13) <= unsigned(tmp_q); - addr_q(0 to 5) <= unsigned(cd_i(2 to 7)); - elsif incr_addr_v then - addr_q <= addr_q + 1; - end if; - - end if; - end if; - end process seq; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process wback_ctrl - -- - -- Purpose: - -- Write-back control. - -- - wback_ctrl: process (clk_en_acc_i, - access_type_i, - wrvram_q) - begin - -- default assignments - abort_wrvram_s <= false; - incr_addr_s <= false; - vram_we_o <= '0'; - - if wrvram_q then - if access_type_i = AC_CPU then - -- signal write access to VRAM - vram_we_o <= '1'; - - if clk_en_acc_i then - -- clear write-back flag and increment address - abort_wrvram_s <= true; - incr_addr_s <= true; - end if; - end if; - end if; - end process wback_ctrl; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process reg_if - -- - -- Purpose: - -- Implements the register interface. - -- - reg_if: process (clk_i, reset_i) - variable reg_addr_v : unsigned(0 to 2); - begin - if reset_i then - tmp_q <= (others => '0'); - ctrl_reg_q <= (others => (others => '0')); - sprite_coll_q <= false; - sprite_5th_q <= false; - sprite_5th_num_q <= (others => '0'); - int_n_q <= '1'; - - elsif clk_i'event and clk_i = '1' then - if clk_en_10m7_i then - -- Temporary register ------------------------------------------------- - if write_tmp_s then - tmp_q <= cd_i; - end if; - - -- Registers 0 to 7 --------------------------------------------------- - if write_reg_s then - reg_addr_v := unsigned(cd_i(5 to 7)); - ctrl_reg_q(to_integer(reg_addr_v)) <= tmp_q; - end if; - - end if; - - -- Fifth sprite handling ------------------------------------------------ - if not sprite_5th_q then - sprite_5th_q <= spr_5th_i; - sprite_5th_num_q <= spr_5th_num_i; - elsif destr_rd_status_s then - sprite_5th_q <= false; - end if; - - -- Sprite collision flag ------------------------------------------------ - if spr_coll_i then - sprite_coll_q <= true; - elsif destr_rd_status_s then - sprite_coll_q <= false; - end if; - - -- Interrupt ------------------------------------------------------------ - if irq_i then - int_n_q <= '0'; - elsif destr_rd_status_s then - int_n_q <= '1'; - end if; - end if; - end process reg_if; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process access_ctrl - -- - -- Purpose: - -- Implements the combinational logic for the CPU I/F FSM. - -- Decodes the CPU I/F FSM state and generates the control signals for the - -- register and VRAM logic. - -- - access_ctrl: process (state_q, - rd_i, wr_i, - mode_i, - cd_i) - type transfer_mode_t is (TM_NONE, - TM_RD_MODE0, TM_WR_MODE0, - TM_RD_MODE1, TM_WR_MODE1); - variable transfer_mode_v : transfer_mode_t; - begin - -- default assignments - state_s <= state_q; - sched_rdvram_s <= false; - sched_wrvram_s <= false; - wrbuf_cpu_s <= false; - write_tmp_s <= false; - write_reg_s <= false; - load_addr_s <= false; - read_mux_s <= RDMUX_STATUS; - destr_rd_status_s <= false; - - -- determine transfer mode - transfer_mode_v := TM_NONE; - if mode_i = '0' then - if rd_i then - transfer_mode_v := TM_RD_MODE0; - end if; - if wr_i then - transfer_mode_v := TM_WR_MODE0; - end if; - else - if rd_i then - transfer_mode_v := TM_RD_MODE1; - end if; - if wr_i then - transfer_mode_v := TM_WR_MODE1; - end if; - end if; - - -- FSM state transitions - case state_q is - -- ST_IDLE: waiting for CPU access -------------------------------------- - when ST_IDLE => - case transfer_mode_v is - when TM_RD_MODE0 => - state_s <= ST_RD_MODE0; - when TM_WR_MODE0 => - state_s <= ST_WR_MODE0; - when TM_RD_MODE1 => - state_s <= ST_RD_MODE1; - when TM_WR_MODE1 => - state_s <= ST_WR_MODE1_1ST; - when others => - null; - end case; - - -- ST_RD_MODE0: read from VRAM ------------------------------------------ - when ST_RD_MODE0 => - -- set read mux - read_mux_s <= RDMUX_READAHEAD; - - if transfer_mode_v = TM_NONE then - -- CPU finished read access: - -- schedule new read-ahead and return to idle - state_s <= ST_IDLE; - sched_rdvram_s <= true; - end if; - - -- ST_WR_MODE0: write to VRAM ------------------------------------------- - when ST_WR_MODE0 => - -- write data from CPU to write-back/read-ahead buffer - wrbuf_cpu_s <= true; - - if transfer_mode_v = TM_NONE then - -- CPU finished write access: - -- schedule new write-back and return to idle - state_s <= ST_IDLE; - sched_wrvram_s <= true; - end if; - - -- ST_RD_MODE1: read from status register ------------------------------- - when ST_RD_MODE1 => - -- set read mux - read_mux_s <= RDMUX_STATUS; - - if transfer_mode_v = TM_NONE then - -- CPU finished read access: - -- destructive read of status register and return to IDLE - destr_rd_status_s <= true; - state_s <= ST_IDLE; - end if; - - -- ST_WR_MODE1_1ST: save first byte ------------------------------------- - when ST_WR_MODE1_1ST => - -- update temp register - write_tmp_s <= true; - - if transfer_mode_v = TM_NONE then - -- CPU finished write access: - -- become idle but remember that the first byte of a paired write - -- has been written - state_s <= ST_WR_MODE1_1ST_IDLE; - end if; - - -- ST_WR_MODE1_1ST_IDLE: wait for next access --------------------------- - when ST_WR_MODE1_1ST_IDLE => - -- determine type of next access - case transfer_mode_v is - when TM_RD_MODE0 => - state_s <= ST_RD_MODE0; - when TM_WR_MODE0 => - state_s <= ST_WR_MODE0; - when TM_RD_MODE1 => - state_s <= ST_RD_MODE1; - when TM_WR_MODE1 => - case cd_i(0 to 1) is - when "00" => - state_s <= ST_WR_MODE1_2ND_VREAD; - when "01" => - state_s <= ST_WR_MODE1_2ND_VWRITE; - when "10" | "11" => - state_s <= ST_WR_MODE1_2ND_RWRITE; - when others => - null; - end case; - when others => - null; - end case; - - -- ST_WR_MODE1_2ND_VREAD: write second byte of address, then read ahead - - when ST_WR_MODE1_2ND_VREAD => - load_addr_s <= true; - - if transfer_mode_v = TM_NONE then - -- CPU finished write access: - -- schedule new read-ahead and return to idle - sched_rdvram_s <= true; - state_s <= ST_IDLE; - end if; - - -- ST_WR_MODE1_2ND_VWRITE: write second byte of address - when ST_WR_MODE1_2ND_VWRITE => - load_addr_s <= true; - - if transfer_mode_v = TM_NONE then - -- CPU finished write access: - -- return to idle - state_s <= ST_IDLE; - end if; - - -- ST_WR_MODE1_2ND_RWRITE: write to register ---------------------------- - when ST_WR_MODE1_2ND_RWRITE => - write_reg_s <= true; - - if transfer_mode_v = TM_NONE then - -- CPU finished write access: - -- return to idle - state_s <= ST_IDLE; - end if; - - when others => - null; - - end case; - - end process access_ctrl; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process mode_decode - -- - -- Purpose: - -- Decodes the display mode from the M1, M2, M3 bits. - -- - mode_decode: process (ctrl_reg_q) - variable mode_v : std_logic_vector(0 to 2); - begin - mode_v := ctrl_reg_q(1)(3) & -- M1 - ctrl_reg_q(1)(4) & -- M2 - ctrl_reg_q(0)(6); -- M3 - - case mode_v is - when "000" => - opmode_o <= OPMODE_GRAPH1; - when "001" => - opmode_o <= OPMODE_GRAPH2; - when "010" => - opmode_o <= OPMODE_MULTIC; - when "100" => - opmode_o <= OPMODE_TEXTM; - when others => - opmode_o <= OPMODE_TEXTM; - end case; - end process mode_decode; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Build status register - ----------------------------------------------------------------------------- - status_reg_s <= not int_n_q & - to_std_logic_f(sprite_5th_q) & - to_std_logic_f(sprite_coll_q) & - sprite_5th_num_q; - - ----------------------------------------------------------------------------- - -- Output mapping - ----------------------------------------------------------------------------- - vram_a_o <= std_logic_vector(addr_q); - vram_d_o <= buffer_q; - - cd_o <= buffer_q - when read_mux_s = RDMUX_READAHEAD else - status_reg_s; - cd_oe_o <= '1' - when rd_i else - '0'; - - reg_ev_o <= to_boolean_f(ctrl_reg_q(0)(7)); - reg_16k_o <= to_boolean_f(ctrl_reg_q(1)(0)); - reg_blank_o <= not to_boolean_f(ctrl_reg_q(1)(1)); - reg_size1_o <= to_boolean_f(ctrl_reg_q(1)(6)); - reg_mag1_o <= to_boolean_f(ctrl_reg_q(1)(7)); - reg_ntb_o <= ctrl_reg_q(2)(4 to 7); - reg_ctb_o <= ctrl_reg_q(3); - reg_pgb_o <= ctrl_reg_q(4)(5 to 7); - reg_satb_o <= ctrl_reg_q(5)(1 to 7); - reg_spgb_o <= ctrl_reg_q(6)(5 to 7); - reg_col1_o <= ctrl_reg_q(7)(0 to 3); - reg_col0_o <= ctrl_reg_q(7)(4 to 7); - int_n_o <= int_n_q or not ctrl_reg_q(1)(2); - -end rtl; +------------------------------------------------------------------------------- +-- +-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. +-- +-- $Id: vdp18_cpuio.vhd,v 1.17 2006/06/18 10:47:01 arnim Exp $ +-- +-- CPU I/O Interface Module +-- +------------------------------------------------------------------------------- +-- +-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; + +use work.vdp18_pack.access_t; +use work.vdp18_pack.opmode_t; + +entity vdp18_cpuio is + + port ( + clk_i : in std_logic; + clk_en_10m7_i : in boolean; + clk_en_acc_i : in boolean; + reset_i : in boolean; + rd_i : in boolean; + wr_i : in boolean; + mode_i : in std_logic; + cd_i : in std_logic_vector(0 to 7); + cd_o : out std_logic_vector(0 to 7); + cd_oe_o : out std_logic; + access_type_i : in access_t; + opmode_o : out opmode_t; + vram_we_o : out std_logic; + vram_a_o : out std_logic_vector(0 to 13); + vram_d_o : out std_logic_vector(0 to 7); + vram_d_i : in std_logic_vector(0 to 7); + spr_coll_i : in boolean; + spr_5th_i : in boolean; + spr_5th_num_i : in std_logic_vector(0 to 4); + reg_ev_o : out boolean; + reg_16k_o : out boolean; + reg_blank_o : out boolean; + reg_size1_o : out boolean; + reg_mag1_o : out boolean; + reg_ntb_o : out std_logic_vector(0 to 3); + reg_ctb_o : out std_logic_vector(0 to 7); + reg_pgb_o : out std_logic_vector(0 to 2); + reg_satb_o : out std_logic_vector(0 to 6); + reg_spgb_o : out std_logic_vector(0 to 2); + reg_col1_o : out std_logic_vector(0 to 3); + reg_col0_o : out std_logic_vector(0 to 3); + irq_i : in boolean; + int_n_o : out std_logic + ); + +end vdp18_cpuio; + + +library ieee; +use ieee.numeric_std.all; + +use work.vdp18_pack.all; + +architecture rtl of vdp18_cpuio is + + type state_t is (ST_IDLE, + ST_RD_MODE0, ST_WR_MODE0, + ST_RD_MODE1, + ST_WR_MODE1_1ST, ST_WR_MODE1_1ST_IDLE, + ST_WR_MODE1_2ND_VREAD, ST_WR_MODE1_2ND_VWRITE, + ST_WR_MODE1_2ND_RWRITE); + signal state_s, + state_q : state_t; + + signal buffer_q : std_logic_vector(0 to 7); + + signal addr_q : unsigned(0 to 13); + + signal incr_addr_s, + load_addr_s : boolean; + + signal wrbuf_cpu_s : boolean; + signal sched_rdvram_s, + rdvram_sched_q, + rdvram_q : boolean; + signal abort_wrvram_s, + sched_wrvram_s, + wrvram_sched_q, + wrvram_q : boolean; + + signal write_tmp_s : boolean; + signal tmp_q : std_logic_vector(0 to 7); + signal write_reg_s : boolean; + + -- control register bits ---------------------------------------------------- + type ctrl_reg_t is array (natural range 7 downto 0) of + std_logic_vector(0 to 7); + signal ctrl_reg_q : ctrl_reg_t; + + -- status register ---------------------------------------------------------- + signal status_reg_s : std_logic_vector(0 to 7); + signal destr_rd_status_s : boolean; + signal sprite_5th_q : boolean; + signal sprite_5th_num_q : std_logic_vector(0 to 4); + signal sprite_coll_q : boolean; + signal int_n_q : std_logic; + + + type read_mux_t is (RDMUX_STATUS, RDMUX_READAHEAD); + signal read_mux_s : read_mux_t; + +begin + + ----------------------------------------------------------------------------- + -- Process seq + -- + -- Purpose: + -- Implements the sequential elements. + -- + seq: process (clk_i, reset_i) + variable incr_addr_v : boolean; + begin + if reset_i then + state_q <= ST_IDLE; + buffer_q <= (others => '0'); + addr_q <= (others => '0'); + rdvram_sched_q <= false; + rdvram_q <= false; + wrvram_sched_q <= false; + wrvram_q <= false; + + elsif clk_i'event and clk_i = '1' then + -- default assignments + incr_addr_v := incr_addr_s; + + if clk_en_10m7_i then + -- update state vector ------------------------------------------------ + state_q <= state_s; + + -- buffer and flag control -------------------------------------------- + if wrbuf_cpu_s then + -- write read-ahead buffer from CPU bus + buffer_q <= cd_i; + -- immediately stop read-ahead + rdvram_sched_q <= false; + rdvram_q <= false; + elsif clk_en_acc_i and + rdvram_q and + access_type_i = AC_CPU then + -- write read-ahead buffer from VRAM during CPU access slot + buffer_q <= vram_d_i; + -- stop scanning for CPU data + rdvram_q <= false; + -- increment read-ahead address + incr_addr_v := true; + end if; + + if sched_rdvram_s then + -- immediately stop write-back + wrvram_sched_q <= false; + wrvram_q <= false; + -- schedule read-ahead + rdvram_sched_q <= true; + end if; + + if sched_wrvram_s then + -- schedule write-back + wrvram_sched_q <= true; + end if; + + if abort_wrvram_s then + -- stop scanning for write-back + wrvram_q <= false; + end if; + + if rdvram_sched_q and clk_en_acc_i then + -- align scheduled read-ahead with access slot phase + rdvram_sched_q <= false; + rdvram_q <= true; + end if; + if wrvram_sched_q and clk_en_acc_i then + -- align scheduled write-back with access slot phase + wrvram_sched_q <= false; + wrvram_q <= true; + end if; + + -- manage address ----------------------------------------------------- + if load_addr_s then + addr_q(6 to 13) <= unsigned(tmp_q); + addr_q(0 to 5) <= unsigned(cd_i(2 to 7)); + elsif incr_addr_v then + addr_q <= addr_q + 1; + end if; + + end if; + end if; + end process seq; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process wback_ctrl + -- + -- Purpose: + -- Write-back control. + -- + wback_ctrl: process (clk_en_acc_i, + access_type_i, + wrvram_q) + begin + -- default assignments + abort_wrvram_s <= false; + incr_addr_s <= false; + vram_we_o <= '0'; + + if wrvram_q then + if access_type_i = AC_CPU then + -- signal write access to VRAM + vram_we_o <= '1'; + + if clk_en_acc_i then + -- clear write-back flag and increment address + abort_wrvram_s <= true; + incr_addr_s <= true; + end if; + end if; + end if; + end process wback_ctrl; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process reg_if + -- + -- Purpose: + -- Implements the register interface. + -- + reg_if: process (clk_i, reset_i) + variable reg_addr_v : unsigned(0 to 2); + begin + if reset_i then + tmp_q <= (others => '0'); + ctrl_reg_q <= (others => (others => '0')); + sprite_coll_q <= false; + sprite_5th_q <= false; + sprite_5th_num_q <= (others => '0'); + int_n_q <= '1'; + + elsif clk_i'event and clk_i = '1' then + if clk_en_10m7_i then + -- Temporary register ------------------------------------------------- + if write_tmp_s then + tmp_q <= cd_i; + end if; + + -- Registers 0 to 7 --------------------------------------------------- + if write_reg_s then + reg_addr_v := unsigned(cd_i(5 to 7)); + ctrl_reg_q(to_integer(reg_addr_v)) <= tmp_q; + end if; + + end if; + + -- Fifth sprite handling ------------------------------------------------ + if not sprite_5th_q then + sprite_5th_q <= spr_5th_i; + sprite_5th_num_q <= spr_5th_num_i; + elsif destr_rd_status_s then + sprite_5th_q <= false; + end if; + + -- Sprite collision flag ------------------------------------------------ + if spr_coll_i then + sprite_coll_q <= true; + elsif destr_rd_status_s then + sprite_coll_q <= false; + end if; + + -- Interrupt ------------------------------------------------------------ + if irq_i then + int_n_q <= '0'; + elsif destr_rd_status_s then + int_n_q <= '1'; + end if; + end if; + end process reg_if; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process access_ctrl + -- + -- Purpose: + -- Implements the combinational logic for the CPU I/F FSM. + -- Decodes the CPU I/F FSM state and generates the control signals for the + -- register and VRAM logic. + -- + access_ctrl: process (state_q, + rd_i, wr_i, + mode_i, + cd_i) + type transfer_mode_t is (TM_NONE, + TM_RD_MODE0, TM_WR_MODE0, + TM_RD_MODE1, TM_WR_MODE1); + variable transfer_mode_v : transfer_mode_t; + begin + -- default assignments + state_s <= state_q; + sched_rdvram_s <= false; + sched_wrvram_s <= false; + wrbuf_cpu_s <= false; + write_tmp_s <= false; + write_reg_s <= false; + load_addr_s <= false; + read_mux_s <= RDMUX_STATUS; + destr_rd_status_s <= false; + + -- determine transfer mode + transfer_mode_v := TM_NONE; + if mode_i = '0' then + if rd_i then + transfer_mode_v := TM_RD_MODE0; + end if; + if wr_i then + transfer_mode_v := TM_WR_MODE0; + end if; + else + if rd_i then + transfer_mode_v := TM_RD_MODE1; + end if; + if wr_i then + transfer_mode_v := TM_WR_MODE1; + end if; + end if; + + -- FSM state transitions + case state_q is + -- ST_IDLE: waiting for CPU access -------------------------------------- + when ST_IDLE => + case transfer_mode_v is + when TM_RD_MODE0 => + state_s <= ST_RD_MODE0; + when TM_WR_MODE0 => + state_s <= ST_WR_MODE0; + when TM_RD_MODE1 => + state_s <= ST_RD_MODE1; + when TM_WR_MODE1 => + state_s <= ST_WR_MODE1_1ST; + when others => + null; + end case; + + -- ST_RD_MODE0: read from VRAM ------------------------------------------ + when ST_RD_MODE0 => + -- set read mux + read_mux_s <= RDMUX_READAHEAD; + + if transfer_mode_v = TM_NONE then + -- CPU finished read access: + -- schedule new read-ahead and return to idle + state_s <= ST_IDLE; + sched_rdvram_s <= true; + end if; + + -- ST_WR_MODE0: write to VRAM ------------------------------------------- + when ST_WR_MODE0 => + -- write data from CPU to write-back/read-ahead buffer + wrbuf_cpu_s <= true; + + if transfer_mode_v = TM_NONE then + -- CPU finished write access: + -- schedule new write-back and return to idle + state_s <= ST_IDLE; + sched_wrvram_s <= true; + end if; + + -- ST_RD_MODE1: read from status register ------------------------------- + when ST_RD_MODE1 => + -- set read mux + read_mux_s <= RDMUX_STATUS; + + if transfer_mode_v = TM_NONE then + -- CPU finished read access: + -- destructive read of status register and return to IDLE + destr_rd_status_s <= true; + state_s <= ST_IDLE; + end if; + + -- ST_WR_MODE1_1ST: save first byte ------------------------------------- + when ST_WR_MODE1_1ST => + -- update temp register + write_tmp_s <= true; + + if transfer_mode_v = TM_NONE then + -- CPU finished write access: + -- become idle but remember that the first byte of a paired write + -- has been written + state_s <= ST_WR_MODE1_1ST_IDLE; + end if; + + -- ST_WR_MODE1_1ST_IDLE: wait for next access --------------------------- + when ST_WR_MODE1_1ST_IDLE => + -- determine type of next access + case transfer_mode_v is + when TM_RD_MODE0 => + state_s <= ST_RD_MODE0; + when TM_WR_MODE0 => + state_s <= ST_WR_MODE0; + when TM_RD_MODE1 => + state_s <= ST_RD_MODE1; + when TM_WR_MODE1 => + case cd_i(0 to 1) is + when "00" => + state_s <= ST_WR_MODE1_2ND_VREAD; + when "01" => + state_s <= ST_WR_MODE1_2ND_VWRITE; + when "10" | "11" => + state_s <= ST_WR_MODE1_2ND_RWRITE; + when others => + null; + end case; + when others => + null; + end case; + + -- ST_WR_MODE1_2ND_VREAD: write second byte of address, then read ahead - + when ST_WR_MODE1_2ND_VREAD => + load_addr_s <= true; + + if transfer_mode_v = TM_NONE then + -- CPU finished write access: + -- schedule new read-ahead and return to idle + sched_rdvram_s <= true; + state_s <= ST_IDLE; + end if; + + -- ST_WR_MODE1_2ND_VWRITE: write second byte of address + when ST_WR_MODE1_2ND_VWRITE => + load_addr_s <= true; + + if transfer_mode_v = TM_NONE then + -- CPU finished write access: + -- return to idle + state_s <= ST_IDLE; + end if; + + -- ST_WR_MODE1_2ND_RWRITE: write to register ---------------------------- + when ST_WR_MODE1_2ND_RWRITE => + write_reg_s <= true; + + if transfer_mode_v = TM_NONE then + -- CPU finished write access: + -- return to idle + state_s <= ST_IDLE; + end if; + + when others => + null; + + end case; + + end process access_ctrl; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process mode_decode + -- + -- Purpose: + -- Decodes the display mode from the M1, M2, M3 bits. + -- + mode_decode: process (ctrl_reg_q) + variable mode_v : std_logic_vector(0 to 2); + begin + mode_v := ctrl_reg_q(1)(3) & -- M1 + ctrl_reg_q(1)(4) & -- M2 + ctrl_reg_q(0)(6); -- M3 + + case mode_v is + when "000" => + opmode_o <= OPMODE_GRAPH1; + when "001" => + opmode_o <= OPMODE_GRAPH2; + when "010" => + opmode_o <= OPMODE_MULTIC; + when "100" => + opmode_o <= OPMODE_TEXTM; + when others => + opmode_o <= OPMODE_TEXTM; + end case; + end process mode_decode; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Build status register + ----------------------------------------------------------------------------- + status_reg_s <= not int_n_q & + to_std_logic_f(sprite_5th_q) & + to_std_logic_f(sprite_coll_q) & + sprite_5th_num_q; + + ----------------------------------------------------------------------------- + -- Output mapping + ----------------------------------------------------------------------------- + vram_a_o <= std_logic_vector(addr_q); + vram_d_o <= buffer_q; + + cd_o <= buffer_q + when read_mux_s = RDMUX_READAHEAD else + status_reg_s; + cd_oe_o <= '1' + when rd_i else + '0'; + + reg_ev_o <= to_boolean_f(ctrl_reg_q(0)(7)); + reg_16k_o <= to_boolean_f(ctrl_reg_q(1)(0)); + reg_blank_o <= not to_boolean_f(ctrl_reg_q(1)(1)); + reg_size1_o <= to_boolean_f(ctrl_reg_q(1)(6)); + reg_mag1_o <= to_boolean_f(ctrl_reg_q(1)(7)); + reg_ntb_o <= ctrl_reg_q(2)(4 to 7); + reg_ctb_o <= ctrl_reg_q(3); + reg_pgb_o <= ctrl_reg_q(4)(5 to 7); + reg_satb_o <= ctrl_reg_q(5)(1 to 7); + reg_spgb_o <= ctrl_reg_q(6)(5 to 7); + reg_col1_o <= ctrl_reg_q(7)(0 to 3); + reg_col0_o <= ctrl_reg_q(7)(4 to 7); + int_n_o <= int_n_q or not ctrl_reg_q(1)(2); + +end rtl; diff --git a/modules/video-vdp18/vdp18_ctrl.vhd b/modules/video-vdp18/vdp18_ctrl.vhd index e9eb9fb..cf894d6 100644 --- a/modules/video-vdp18/vdp18_ctrl.vhd +++ b/modules/video-vdp18/vdp18_ctrl.vhd @@ -1,374 +1,374 @@ -------------------------------------------------------------------------------- --- --- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. --- --- $Id: vdp18_ctrl.vhd,v 1.26 2006/06/18 10:47:01 arnim Exp $ --- --- Timing Controller --- -------------------------------------------------------------------------------- --- --- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.vdp18_pack.opmode_t; -use work.vdp18_pack.hv_t; -use work.vdp18_pack.access_t; - -entity vdp18_ctrl is - - port ( - clk_i : in std_logic; - clk_en_5m37_i : in boolean; - reset_i : in boolean; - opmode_i : in opmode_t; - num_pix_i : in hv_t; - num_line_i : in hv_t; - vert_inc_i : in boolean; - reg_blank_i : in boolean; - reg_size1_i : in boolean; - stop_sprite_i : in boolean; - clk_en_acc_o : out boolean; - access_type_o : out access_t; - vert_active_o : out boolean; - hor_active_o : out boolean; - irq_o : out boolean - ); - -end vdp18_ctrl; - - -use work.vdp18_pack.all; - -architecture rtl of vdp18_ctrl is - - ----------------------------------------------------------------------------- - -- This enables a workaround for a bug in XST. - -- ISE 8.1.02i implements wrong functionality otherwise :-( - -- - constant xst_bug_wa_c : boolean := true; - -- - ----------------------------------------------------------------------------- - - signal access_type_s : access_t; - - -- pragma translate_off - -- Testbench signals -------------------------------------------------------- - -- - signal ac_s : std_logic_vector(3 downto 0); - -- - ----------------------------------------------------------------------------- - -- pragma translate_on - - signal vert_active_q, - hor_active_q : boolean; - signal sprite_active_q : boolean; - signal sprite_line_act_q : boolean; - -begin - - -- pragma translate_off - -- Testbench signals -------------------------------------------------------- - -- - ac_s <= enum_to_vec_f(access_type_s); - -- - ----------------------------------------------------------------------------- - -- pragma translate_on - - - ----------------------------------------------------------------------------- - -- Process decode_access - -- - -- Purpose: - -- Decode horizontal counter value to access type. - -- - decode_access: process (opmode_i, - num_pix_i, - vert_active_q, - sprite_line_act_q, - reg_size1_i) - variable num_pix_plus_6_v : hv_t; - variable mod_6_v : hv_t; - variable num_pix_plus_8_v : hv_t; - variable num_pix_plus_32_v : hv_t; - variable num_pix_spr_v : integer; - begin - -- default assignment - access_type_s <= AC_CPU; - - -- prepare number of pixels for pattern operations - num_pix_plus_6_v := num_pix_i + 6; - num_pix_plus_8_v := num_pix_i + 8; - num_pix_plus_32_v := num_pix_i + 32; - num_pix_spr_v := to_integer(num_pix_i and "111111110"); - - case opmode_i is - -- Graphics I, II and Multicolor Mode ----------------------------------- - when OPMODE_GRAPH1 | - OPMODE_GRAPH2 | - OPMODE_MULTIC => - -- - -- Patterns - -- - if vert_active_q then - if num_pix_plus_8_v(0) = '0' then - if not xst_bug_wa_c then - - -- original code, we want this - case num_pix_plus_8_v(6 to 7) is - when "01" => - access_type_s <= AC_PNT; - when "10" => - if opmode_i /= OPMODE_MULTIC then - -- no access to pattern color table in multicolor mode - access_type_s <= AC_PCT; - end if; - when "11" => - access_type_s <= AC_PGT; - when others => - null; - end case; - - else - - -- workaround for XST bug, we need this - if num_pix_plus_8_v(6 to 7) = "01" then - access_type_s <= AC_PNT; - elsif num_pix_plus_8_v(6 to 7) = "10" then - if opmode_i /= OPMODE_MULTIC then - access_type_s <= AC_PCT; - end if; - elsif num_pix_plus_8_v(6 to 7) = "11" then - access_type_s <= AC_PGT; - end if; - - end if; - end if; - end if; - - -- - -- Sprite test - -- - if sprite_line_act_q then - if num_pix_i(0) = '0' and - num_pix_i(0 to 5) /= "011111" and - num_pix_i(6 to 7) = "00" and - num_pix_i(4 to 5) /= "00" then - -- sprite test interleaved with pattern accesses - 23 slots - access_type_s <= AC_STST; - end if; - if num_pix_plus_32_v(0 to 4) = "00000" or - num_pix_plus_32_v(0 to 7) = "00001000" then - -- sprite tests before starting pattern phase - 9 slots - access_type_s <= AC_STST; - end if; - - -- - -- Sprite Attribute Table and Sprite Pattern Table - -- - case num_pix_spr_v is - when 250 | -78 | - -62 | -46 => - access_type_s <= AC_SATY; - when 254 | -76 | - -60 | -44 => - access_type_s <= AC_SATX; - when 252 | -74 | - -58 | -42 => - access_type_s <= AC_SATN; - when -86 | -70 | - -54 | -38 => - access_type_s <= AC_SATC; - when -84 | -68 | - -52 | -36 => - access_type_s <= AC_SPTH; - when -82 | -66 | - -50 | -34 => - if reg_size1_i then - access_type_s <= AC_SPTL; - end if; - when others => - null; - end case; - end if; - - -- Text Mode ------------------------------------------------------------ - when OPMODE_TEXTM => - if vert_active_q and - num_pix_plus_6_v(0) = '0' and - num_pix_plus_6_v(0 to 4) /= "01111" then - mod_6_v := mod_6_f(num_pix_plus_6_v); - case mod_6_v(6 to 7) is - when "00" => - access_type_s <= AC_PNT; - when "10" => - access_type_s <= AC_PGT; - when others => - null; - end case; - end if; - - -- Unknown -------------------------------------------------------------- - when others => - null; - - end case; - - end process decode_access; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process vert_flags - -- - -- Purpose: - -- Track the vertical position with flags. - -- - vert_flags: process (clk_i, reset_i) - begin - if reset_i then - vert_active_q <= false; - sprite_active_q <= false; - sprite_line_act_q <= false; - - elsif clk_i'event and clk_i = '1' then - if clk_en_5m37_i then - -- line-local sprite processing - if sprite_active_q then - -- sprites are globally enabled - if vert_inc_i then - -- reload at beginning of every new line - -- => scan with STST - sprite_line_act_q <= true; - end if; - - if num_pix_i = hv_sprite_start_c then - -- reload when access to sprite memory starts - sprite_line_act_q <= true; - end if; - end if; - - if vert_inc_i then - -- global sprite processing - if reg_blank_i then - sprite_active_q <= false; - sprite_line_act_q <= false; - elsif num_line_i = -2 then - -- start at line -1 - sprite_active_q <= true; - -- initialize immediately - sprite_line_act_q <= true; - elsif num_line_i = 191 then - -- stop at line 192 - sprite_active_q <= false; - -- force stop - sprite_line_act_q <= false; - end if; - - -- global vertical display - if reg_blank_i then - vert_active_q <= false; - elsif num_line_i = -1 then - -- start vertical display at line 0 - vert_active_q <= true; - elsif num_line_i = 191 then - -- stop at line 192 - vert_active_q <= false; - end if; - end if; - - if stop_sprite_i then - -- stop processing of sprites in this line - sprite_line_act_q <= false; - end if; - - end if; - end if; - end process vert_flags; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process hor_flags - -- - -- Purpose: - -- Track the horizontal position. - -- - hor_flags: process (clk_i, reset_i) - begin - if reset_i then - hor_active_q <= false; - - elsif clk_i'event and clk_i = '1' then - if clk_en_5m37_i then - if not reg_blank_i and - num_pix_i = -1 then - hor_active_q <= true; - end if; - - if opmode_i = OPMODE_TEXTM then - if num_pix_i = 239 then - hor_active_q <= false; - end if; - else - if num_pix_i = 255 then - hor_active_q <= false; - end if; - end if; - end if; - end if; - end process hor_flags; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Ouput mapping - ----------------------------------------------------------------------------- - -- generate clock enable for flip-flops working on access_type - clk_en_acc_o <= clk_en_5m37_i and num_pix_i(8) = '1'; - access_type_o <= access_type_s; - vert_active_o <= vert_active_q; - hor_active_o <= hor_active_q; - irq_o <= vert_inc_i and num_line_i = 191; - -end rtl; +------------------------------------------------------------------------------- +-- +-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. +-- +-- $Id: vdp18_ctrl.vhd,v 1.26 2006/06/18 10:47:01 arnim Exp $ +-- +-- Timing Controller +-- +------------------------------------------------------------------------------- +-- +-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.vdp18_pack.opmode_t; +use work.vdp18_pack.hv_t; +use work.vdp18_pack.access_t; + +entity vdp18_ctrl is + + port ( + clk_i : in std_logic; + clk_en_5m37_i : in boolean; + reset_i : in boolean; + opmode_i : in opmode_t; + num_pix_i : in hv_t; + num_line_i : in hv_t; + vert_inc_i : in boolean; + reg_blank_i : in boolean; + reg_size1_i : in boolean; + stop_sprite_i : in boolean; + clk_en_acc_o : out boolean; + access_type_o : out access_t; + vert_active_o : out boolean; + hor_active_o : out boolean; + irq_o : out boolean + ); + +end vdp18_ctrl; + + +use work.vdp18_pack.all; + +architecture rtl of vdp18_ctrl is + + ----------------------------------------------------------------------------- + -- This enables a workaround for a bug in XST. + -- ISE 8.1.02i implements wrong functionality otherwise :-( + -- + constant xst_bug_wa_c : boolean := true; + -- + ----------------------------------------------------------------------------- + + signal access_type_s : access_t; + + -- pragma translate_off + -- Testbench signals -------------------------------------------------------- + -- + signal ac_s : std_logic_vector(3 downto 0); + -- + ----------------------------------------------------------------------------- + -- pragma translate_on + + signal vert_active_q, + hor_active_q : boolean; + signal sprite_active_q : boolean; + signal sprite_line_act_q : boolean; + +begin + + -- pragma translate_off + -- Testbench signals -------------------------------------------------------- + -- + ac_s <= enum_to_vec_f(access_type_s); + -- + ----------------------------------------------------------------------------- + -- pragma translate_on + + + ----------------------------------------------------------------------------- + -- Process decode_access + -- + -- Purpose: + -- Decode horizontal counter value to access type. + -- + decode_access: process (opmode_i, + num_pix_i, + vert_active_q, + sprite_line_act_q, + reg_size1_i) + variable num_pix_plus_6_v : hv_t; + variable mod_6_v : hv_t; + variable num_pix_plus_8_v : hv_t; + variable num_pix_plus_32_v : hv_t; + variable num_pix_spr_v : integer; + begin + -- default assignment + access_type_s <= AC_CPU; + + -- prepare number of pixels for pattern operations + num_pix_plus_6_v := num_pix_i + 6; + num_pix_plus_8_v := num_pix_i + 8; + num_pix_plus_32_v := num_pix_i + 32; + num_pix_spr_v := to_integer(num_pix_i and "111111110"); + + case opmode_i is + -- Graphics I, II and Multicolor Mode ----------------------------------- + when OPMODE_GRAPH1 | + OPMODE_GRAPH2 | + OPMODE_MULTIC => + -- + -- Patterns + -- + if vert_active_q then + if num_pix_plus_8_v(0) = '0' then + if not xst_bug_wa_c then + + -- original code, we want this + case num_pix_plus_8_v(6 to 7) is + when "01" => + access_type_s <= AC_PNT; + when "10" => + if opmode_i /= OPMODE_MULTIC then + -- no access to pattern color table in multicolor mode + access_type_s <= AC_PCT; + end if; + when "11" => + access_type_s <= AC_PGT; + when others => + null; + end case; + + else + + -- workaround for XST bug, we need this + if num_pix_plus_8_v(6 to 7) = "01" then + access_type_s <= AC_PNT; + elsif num_pix_plus_8_v(6 to 7) = "10" then + if opmode_i /= OPMODE_MULTIC then + access_type_s <= AC_PCT; + end if; + elsif num_pix_plus_8_v(6 to 7) = "11" then + access_type_s <= AC_PGT; + end if; + + end if; + end if; + end if; + + -- + -- Sprite test + -- + if sprite_line_act_q then + if num_pix_i(0) = '0' and + num_pix_i(0 to 5) /= "011111" and + num_pix_i(6 to 7) = "00" and + num_pix_i(4 to 5) /= "00" then + -- sprite test interleaved with pattern accesses - 23 slots + access_type_s <= AC_STST; + end if; + if num_pix_plus_32_v(0 to 4) = "00000" or + num_pix_plus_32_v(0 to 7) = "00001000" then + -- sprite tests before starting pattern phase - 9 slots + access_type_s <= AC_STST; + end if; + + -- + -- Sprite Attribute Table and Sprite Pattern Table + -- + case num_pix_spr_v is + when 250 | -78 | + -62 | -46 => + access_type_s <= AC_SATY; + when 254 | -76 | + -60 | -44 => + access_type_s <= AC_SATX; + when 252 | -74 | + -58 | -42 => + access_type_s <= AC_SATN; + when -86 | -70 | + -54 | -38 => + access_type_s <= AC_SATC; + when -84 | -68 | + -52 | -36 => + access_type_s <= AC_SPTH; + when -82 | -66 | + -50 | -34 => + if reg_size1_i then + access_type_s <= AC_SPTL; + end if; + when others => + null; + end case; + end if; + + -- Text Mode ------------------------------------------------------------ + when OPMODE_TEXTM => + if vert_active_q and + num_pix_plus_6_v(0) = '0' and + num_pix_plus_6_v(0 to 4) /= "01111" then + mod_6_v := mod_6_f(num_pix_plus_6_v); + case mod_6_v(6 to 7) is + when "00" => + access_type_s <= AC_PNT; + when "10" => + access_type_s <= AC_PGT; + when others => + null; + end case; + end if; + + -- Unknown -------------------------------------------------------------- + when others => + null; + + end case; + + end process decode_access; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process vert_flags + -- + -- Purpose: + -- Track the vertical position with flags. + -- + vert_flags: process (clk_i, reset_i) + begin + if reset_i then + vert_active_q <= false; + sprite_active_q <= false; + sprite_line_act_q <= false; + + elsif clk_i'event and clk_i = '1' then + if clk_en_5m37_i then + -- line-local sprite processing + if sprite_active_q then + -- sprites are globally enabled + if vert_inc_i then + -- reload at beginning of every new line + -- => scan with STST + sprite_line_act_q <= true; + end if; + + if num_pix_i = hv_sprite_start_c then + -- reload when access to sprite memory starts + sprite_line_act_q <= true; + end if; + end if; + + if vert_inc_i then + -- global sprite processing + if reg_blank_i then + sprite_active_q <= false; + sprite_line_act_q <= false; + elsif num_line_i = -2 then + -- start at line -1 + sprite_active_q <= true; + -- initialize immediately + sprite_line_act_q <= true; + elsif num_line_i = 191 then + -- stop at line 192 + sprite_active_q <= false; + -- force stop + sprite_line_act_q <= false; + end if; + + -- global vertical display + if reg_blank_i then + vert_active_q <= false; + elsif num_line_i = -1 then + -- start vertical display at line 0 + vert_active_q <= true; + elsif num_line_i = 191 then + -- stop at line 192 + vert_active_q <= false; + end if; + end if; + + if stop_sprite_i then + -- stop processing of sprites in this line + sprite_line_act_q <= false; + end if; + + end if; + end if; + end process vert_flags; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process hor_flags + -- + -- Purpose: + -- Track the horizontal position. + -- + hor_flags: process (clk_i, reset_i) + begin + if reset_i then + hor_active_q <= false; + + elsif clk_i'event and clk_i = '1' then + if clk_en_5m37_i then + if not reg_blank_i and + num_pix_i = -1 then + hor_active_q <= true; + end if; + + if opmode_i = OPMODE_TEXTM then + if num_pix_i = 239 then + hor_active_q <= false; + end if; + else + if num_pix_i = 255 then + hor_active_q <= false; + end if; + end if; + end if; + end if; + end process hor_flags; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Ouput mapping + ----------------------------------------------------------------------------- + -- generate clock enable for flip-flops working on access_type + clk_en_acc_o <= clk_en_5m37_i and num_pix_i(8) = '1'; + access_type_o <= access_type_s; + vert_active_o <= vert_active_q; + hor_active_o <= hor_active_q; + irq_o <= vert_inc_i and num_line_i = 191; + +end rtl; diff --git a/modules/video-vdp18/vdp18_hor_vert.vhd b/modules/video-vdp18/vdp18_hor_vert.vhd index b1963ae..d3171b6 100644 --- a/modules/video-vdp18/vdp18_hor_vert.vhd +++ b/modules/video-vdp18/vdp18_hor_vert.vhd @@ -1,204 +1,204 @@ -------------------------------------------------------------------------------- --- --- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. --- --- $Id: vdp18_hor_vert.vhd,v 1.11 2006/06/18 10:47:01 arnim Exp $ --- --- Horizontal / Vertical Timing Generator --- -------------------------------------------------------------------------------- --- --- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -use work.vdp18_pack.opmode_t; -use work.vdp18_pack.hv_t; - -entity vdp18_hor_vert is - - port ( - clk_i : in std_logic; - clk_en_5m37_i : in boolean; - reset_i : in boolean; - opmode_i : in opmode_t; - num_pix_o : out hv_t; - num_line_o : out hv_t; - vert_inc_o : out boolean; - hsync_n_o : out std_logic; - vsync_n_o : out std_logic; - blank_o : out boolean; - hblank_o : out boolean; - vblank_o : out boolean; - is_pal_i : in std_logic - ); - -end vdp18_hor_vert; - - -use work.vdp18_pack.all; - -architecture rtl of vdp18_hor_vert is - - signal last_line_s : hv_t; - signal first_line_s : hv_t; - - signal first_pix_s : hv_t; - signal last_pix_s : hv_t; - - signal cnt_hor_q : hv_t; - signal cnt_vert_q : hv_t; - - signal vert_inc_s : boolean; - - signal hblank_q, - vblank_q : boolean; - -begin - - ----------------------------------------------------------------------------- - -- Prepare comparison signals for NTSC and PAL. - -- - first_line_s <= hv_first_line_pal_c when is_pal_i = '1' else hv_first_line_ntsc_c; - last_line_s <= hv_last_line_pal_c when is_pal_i = '1' else hv_last_line_ntsc_c; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process opmode_mux - -- - -- Purpose: - -- Generates the horizontal counter limits based on the current operating - -- mode. - -- - opmode_mux: process (opmode_i) - begin - if opmode_i = OPMODE_TEXTM then - first_pix_s <= hv_first_pix_text_c; - last_pix_s <= hv_last_pix_text_c; - else - first_pix_s <= hv_first_pix_graph_c; - last_pix_s <= hv_last_pix_graph_c; - end if; - end process opmode_mux; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process counters - -- - -- Purpose: - -- Implements the horizontal and vertical counters. - -- - counters: process (clk_i, reset_i, first_line_s) - begin - if reset_i then - cnt_hor_q <= hv_first_pix_text_c; - cnt_vert_q <= first_line_s; - hsync_n_o <= '1'; - vsync_n_o <= '1'; - hblank_q <= false; - vblank_q <= false; - - elsif clk_i'event and clk_i = '1' then - if clk_en_5m37_i then - -- The horizontal counter --------------------------------------------- - if cnt_hor_q = last_pix_s then - cnt_hor_q <= first_pix_s; - else - cnt_hor_q <= cnt_hor_q + 1; - end if; - - -- The vertical counter ----------------------------------------------- - if cnt_vert_q = last_line_s then - cnt_vert_q <= first_line_s; - elsif vert_inc_s then - -- increment when horizontal counter is at trigger position - cnt_vert_q <= cnt_vert_q + 1; - end if; - - -- Horizontal sync ---------------------------------------------------- - if cnt_hor_q = -64 then - hsync_n_o <= '0'; - elsif cnt_hor_q = -38 then - hsync_n_o <= '1'; - end if; - if cnt_hor_q = -72 then - hblank_q <= true; - elsif cnt_hor_q = -14 then - hblank_q <= false; - end if; - - -- Vertical sync ------------------------------------------------------ - - if cnt_vert_q = last_line_s - 3 then - vsync_n_o <= '0'; - elsif cnt_vert_q = last_line_s then - vsync_n_o <= '1'; - end if; - - if cnt_vert_q = last_line_s - 6 then - vblank_q <= true; - elsif cnt_vert_q = first_line_s + 14 then - vblank_q <= false; - end if; - end if; - end if; - end process counters; - -- - ----------------------------------------------------------------------------- - - - -- comparator for vertical line increment - vert_inc_s <= clk_en_5m37_i and cnt_hor_q = hv_vertical_inc_c; - - - ----------------------------------------------------------------------------- - -- Output mapping - ----------------------------------------------------------------------------- - num_pix_o <= cnt_hor_q; - num_line_o <= cnt_vert_q; - vert_inc_o <= vert_inc_s; - blank_o <= hblank_q or vblank_q; - vblank_o <= vblank_q; - hblank_o <= hblank_q; - -end rtl; +------------------------------------------------------------------------------- +-- +-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. +-- +-- $Id: vdp18_hor_vert.vhd,v 1.11 2006/06/18 10:47:01 arnim Exp $ +-- +-- Horizontal / Vertical Timing Generator +-- +------------------------------------------------------------------------------- +-- +-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +use work.vdp18_pack.opmode_t; +use work.vdp18_pack.hv_t; + +entity vdp18_hor_vert is + + port ( + clk_i : in std_logic; + clk_en_5m37_i : in boolean; + reset_i : in boolean; + opmode_i : in opmode_t; + num_pix_o : out hv_t; + num_line_o : out hv_t; + vert_inc_o : out boolean; + hsync_n_o : out std_logic; + vsync_n_o : out std_logic; + blank_o : out boolean; + hblank_o : out boolean; + vblank_o : out boolean; + is_pal_i : in std_logic + ); + +end vdp18_hor_vert; + + +use work.vdp18_pack.all; + +architecture rtl of vdp18_hor_vert is + + signal last_line_s : hv_t; + signal first_line_s : hv_t; + + signal first_pix_s : hv_t; + signal last_pix_s : hv_t; + + signal cnt_hor_q : hv_t; + signal cnt_vert_q : hv_t; + + signal vert_inc_s : boolean; + + signal hblank_q, + vblank_q : boolean; + +begin + + ----------------------------------------------------------------------------- + -- Prepare comparison signals for NTSC and PAL. + -- + first_line_s <= hv_first_line_pal_c when is_pal_i = '1' else hv_first_line_ntsc_c; + last_line_s <= hv_last_line_pal_c when is_pal_i = '1' else hv_last_line_ntsc_c; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process opmode_mux + -- + -- Purpose: + -- Generates the horizontal counter limits based on the current operating + -- mode. + -- + opmode_mux: process (opmode_i) + begin + if opmode_i = OPMODE_TEXTM then + first_pix_s <= hv_first_pix_text_c; + last_pix_s <= hv_last_pix_text_c; + else + first_pix_s <= hv_first_pix_graph_c; + last_pix_s <= hv_last_pix_graph_c; + end if; + end process opmode_mux; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process counters + -- + -- Purpose: + -- Implements the horizontal and vertical counters. + -- + counters: process (clk_i, reset_i, first_line_s) + begin + if reset_i then + cnt_hor_q <= hv_first_pix_text_c; + cnt_vert_q <= first_line_s; + hsync_n_o <= '1'; + vsync_n_o <= '1'; + hblank_q <= false; + vblank_q <= false; + + elsif clk_i'event and clk_i = '1' then + if clk_en_5m37_i then + -- The horizontal counter --------------------------------------------- + if cnt_hor_q = last_pix_s then + cnt_hor_q <= first_pix_s; + else + cnt_hor_q <= cnt_hor_q + 1; + end if; + + -- The vertical counter ----------------------------------------------- + if cnt_vert_q = last_line_s then + cnt_vert_q <= first_line_s; + elsif vert_inc_s then + -- increment when horizontal counter is at trigger position + cnt_vert_q <= cnt_vert_q + 1; + end if; + + -- Horizontal sync ---------------------------------------------------- + if cnt_hor_q = -64 then + hsync_n_o <= '0'; + elsif cnt_hor_q = -38 then + hsync_n_o <= '1'; + end if; + if cnt_hor_q = -72 then + hblank_q <= true; + elsif cnt_hor_q = -14 then + hblank_q <= false; + end if; + + -- Vertical sync ------------------------------------------------------ + + if cnt_vert_q = last_line_s - 3 then + vsync_n_o <= '0'; + elsif cnt_vert_q = last_line_s then + vsync_n_o <= '1'; + end if; + + if cnt_vert_q = last_line_s - 6 then + vblank_q <= true; + elsif cnt_vert_q = first_line_s + 14 then + vblank_q <= false; + end if; + end if; + end if; + end process counters; + -- + ----------------------------------------------------------------------------- + + + -- comparator for vertical line increment + vert_inc_s <= clk_en_5m37_i and cnt_hor_q = hv_vertical_inc_c; + + + ----------------------------------------------------------------------------- + -- Output mapping + ----------------------------------------------------------------------------- + num_pix_o <= cnt_hor_q; + num_line_o <= cnt_vert_q; + vert_inc_o <= vert_inc_s; + blank_o <= hblank_q or vblank_q; + vblank_o <= vblank_q; + hblank_o <= hblank_q; + +end rtl; diff --git a/modules/video-vdp18/vdp18_pack-p.vhd b/modules/video-vdp18/vdp18_pack-p.vhd index b29b304..1bc7539 100644 --- a/modules/video-vdp18/vdp18_pack-p.vhd +++ b/modules/video-vdp18/vdp18_pack-p.vhd @@ -1,240 +1,240 @@ -------------------------------------------------------------------------------- --- --- $Id: vdp18_pack-p.vhd,v 1.14 2006/02/22 23:07:05 arnim Exp $ --- --- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) --- --- All rights reserved --- -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -package vdp18_pack is - - ----------------------------------------------------------------------------- - -- Subtype for horizontal/vertical counters/positions. - -- - subtype hv_t is signed(0 to 8); - -- - ----------------------------------------------------------------------------- - ----------------------------------------------------------------------------- - -- Constants for first and last vertical line of NTSC and PAL mode. - -- - constant hv_first_line_ntsc_c : hv_t := to_signed(-40, hv_t'length); - constant hv_last_line_ntsc_c : hv_t := to_signed(222, hv_t'length); - -- - constant hv_first_line_pal_c : hv_t := to_signed(-65, hv_t'length); - constant hv_last_line_pal_c : hv_t := to_signed(248, hv_t'length); - -- - ----------------------------------------------------------------------------- - ----------------------------------------------------------------------------- - -- Constants for first and last horizontal pixel in text and graphics. - -- - constant hv_first_pix_text_c : hv_t := to_signed(-102, hv_t'length); - constant hv_last_pix_text_c : hv_t := to_signed(239, hv_t'length); - -- - constant hv_first_pix_graph_c : hv_t := to_signed(-86, hv_t'length); - constant hv_last_pix_graph_c : hv_t := to_signed(255, hv_t'length); - -- - ----------------------------------------------------------------------------- - ----------------------------------------------------------------------------- - -- Miscellaneous constants for horizontal phases. - -- - constant hv_vertical_inc_c : hv_t := to_signed(-32, hv_t'length); - constant hv_sprite_start_c : hv_t := to_signed(247, hv_t'length); - -- - ----------------------------------------------------------------------------- - ----------------------------------------------------------------------------- - -- Operating modes of the VDP18 core. - -- - type opmode_t is (OPMODE_GRAPH1, OPMODE_GRAPH2, - OPMODE_MULTIC, OPMODE_TEXTM); - -- - constant opmode_graph1_c : std_logic_vector(0 to 2) := "000"; - constant opmode_graph2_c : std_logic_vector(0 to 2) := "001"; - constant opmode_multic_c : std_logic_vector(0 to 2) := "010"; - constant opmode_textm_c : std_logic_vector(0 to 2) := "100"; - -- - ----------------------------------------------------------------------------- - ----------------------------------------------------------------------------- - -- Access types. - -- - type access_t is (-- pattern access - -- read Pattern Name Table - AC_PNT, - -- read Pattern Generator Table - AC_PGT, - -- read Pattern Color Table - AC_PCT, - -- sprite access - -- sprite test read (y coordinate) - AC_STST, - -- read Sprite Attribute Table/Y - AC_SATY, - -- read Sprite Attribute Table/X - AC_SATX, - -- read Sprite Attribute Table/N - AC_SATN, - -- read Sprite Attribute Table/C - AC_SATC, - -- read Sprite Pattern Table/high quadrant - AC_SPTH, - -- read Sprite Pattern Table/low quadrant - AC_SPTL, - -- - -- CPU access - AC_CPU, - -- - -- no access at all - AC_NONE - ); - -- - ----------------------------------------------------------------------------- - ----------------------------------------------------------------------------- - -- Function enum_to_vec_f - -- - -- Purpose: - -- Translate access_t enumeration type to std_logic_vector. - -- - function enum_to_vec_f(enum : in access_t) return std_logic_vector; - -- - ----------------------------------------------------------------------------- - ----------------------------------------------------------------------------- - -- Function to_boolean_f - -- - -- Purpose: - -- Converts a std_logic value to boolean. - -- - function to_boolean_f(val : in std_logic) return boolean; - -- - ----------------------------------------------------------------------------- - ----------------------------------------------------------------------------- - -- Function to_std_logic_f - -- - -- Purpose: - -- Converts a boolean value to std_logic. - -- - function to_std_logic_f(val : in boolean) return std_logic; - -- - ----------------------------------------------------------------------------- - ----------------------------------------------------------------------------- - -- Function mod_6_f - -- - -- Purpose: - -- Calculate the modulo of 6. - -- Only the positive part is considered. - -- - function mod_6_f(val : in hv_t) return hv_t; - -- - ----------------------------------------------------------------------------- - -end vdp18_pack; -package body vdp18_pack is - - ----------------------------------------------------------------------------- - -- Function enum_to_vec_f - -- - -- Purpose: - -- Translate access_t enumeration type to std_logic_vector. - -- - function enum_to_vec_f(enum : in access_t) return - std_logic_vector is - variable result_v : std_logic_vector(3 downto 0); - begin - case enum is - when AC_NONE => result_v := "0000"; - when AC_PNT => result_v := "0001"; - when AC_PGT => result_v := "0010"; - when AC_PCT => result_v := "0011"; - when AC_STST => result_v := "0100"; - when AC_SATY => result_v := "0101"; - when AC_SATX => result_v := "0110"; - when AC_SATN => result_v := "0111"; - when AC_SATC => result_v := "1000"; - when AC_SPTL => result_v := "1001"; - when AC_SPTH => result_v := "1010"; - when AC_CPU => result_v := "1111"; - when others => result_v := "UUUU"; - end case; - - return result_v; - end; - -- - ----------------------------------------------------------------------------- - ----------------------------------------------------------------------------- - -- Function to_boolean_f - -- - -- Purpose: - -- Converts a std_logic value to boolean. - -- - function to_boolean_f(val : in std_logic) return boolean is - variable result_v : boolean; - begin - case to_X01(val) is - when '1' => result_v := true; - when '0' => result_v := false; - when others => result_v := false; - end case; - - return result_v; - end; - -- - ----------------------------------------------------------------------------- - - ----------------------------------------------------------------------------- - -- Function to_std_logic_f - -- - -- Purpose: - -- Converts a boolean value to std_logic. - -- - function to_std_logic_f(val : in boolean) return std_logic is - variable result_v : std_logic; - begin - case val is - when true => result_v := '1'; - when false => result_v := '0'; - end case; - - return result_v; - end; - -- - ----------------------------------------------------------------------------- - - ----------------------------------------------------------------------------- - -- Function mod_6_f - -- - -- Purpose: - -- Calculate the modulo of 6. - -- Only the positive part is considered. - -- - function mod_6_f(val : in hv_t) return hv_t is - variable mod_v : natural; - variable result_v : hv_t; - begin - if val(0) = '0' then - result_v := (others => '0'); - mod_v := 0; - for idx in 0 to 255 loop - if val = idx then - result_v := to_signed(mod_v, hv_t'length); - end if; - - if mod_v < 5 then - mod_v := mod_v + 1; - else - mod_v := 0; - end if; - end loop; - else - result_v := (others => '-'); - end if; - - return result_v; - end; - -- - ----------------------------------------------------------------------------- - -end vdp18_pack; +------------------------------------------------------------------------------- +-- +-- $Id: vdp18_pack-p.vhd,v 1.14 2006/02/22 23:07:05 arnim Exp $ +-- +-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +-- +-- All rights reserved +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +package vdp18_pack is + + ----------------------------------------------------------------------------- + -- Subtype for horizontal/vertical counters/positions. + -- + subtype hv_t is signed(0 to 8); + -- + ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + -- Constants for first and last vertical line of NTSC and PAL mode. + -- + constant hv_first_line_ntsc_c : hv_t := to_signed(-40, hv_t'length); + constant hv_last_line_ntsc_c : hv_t := to_signed(222, hv_t'length); + -- + constant hv_first_line_pal_c : hv_t := to_signed(-65, hv_t'length); + constant hv_last_line_pal_c : hv_t := to_signed(248, hv_t'length); + -- + ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + -- Constants for first and last horizontal pixel in text and graphics. + -- + constant hv_first_pix_text_c : hv_t := to_signed(-102, hv_t'length); + constant hv_last_pix_text_c : hv_t := to_signed(239, hv_t'length); + -- + constant hv_first_pix_graph_c : hv_t := to_signed(-86, hv_t'length); + constant hv_last_pix_graph_c : hv_t := to_signed(255, hv_t'length); + -- + ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + -- Miscellaneous constants for horizontal phases. + -- + constant hv_vertical_inc_c : hv_t := to_signed(-32, hv_t'length); + constant hv_sprite_start_c : hv_t := to_signed(247, hv_t'length); + -- + ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + -- Operating modes of the VDP18 core. + -- + type opmode_t is (OPMODE_GRAPH1, OPMODE_GRAPH2, + OPMODE_MULTIC, OPMODE_TEXTM); + -- + constant opmode_graph1_c : std_logic_vector(0 to 2) := "000"; + constant opmode_graph2_c : std_logic_vector(0 to 2) := "001"; + constant opmode_multic_c : std_logic_vector(0 to 2) := "010"; + constant opmode_textm_c : std_logic_vector(0 to 2) := "100"; + -- + ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + -- Access types. + -- + type access_t is (-- pattern access + -- read Pattern Name Table + AC_PNT, + -- read Pattern Generator Table + AC_PGT, + -- read Pattern Color Table + AC_PCT, + -- sprite access + -- sprite test read (y coordinate) + AC_STST, + -- read Sprite Attribute Table/Y + AC_SATY, + -- read Sprite Attribute Table/X + AC_SATX, + -- read Sprite Attribute Table/N + AC_SATN, + -- read Sprite Attribute Table/C + AC_SATC, + -- read Sprite Pattern Table/high quadrant + AC_SPTH, + -- read Sprite Pattern Table/low quadrant + AC_SPTL, + -- + -- CPU access + AC_CPU, + -- + -- no access at all + AC_NONE + ); + -- + ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + -- Function enum_to_vec_f + -- + -- Purpose: + -- Translate access_t enumeration type to std_logic_vector. + -- + function enum_to_vec_f(enum : in access_t) return std_logic_vector; + -- + ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + -- Function to_boolean_f + -- + -- Purpose: + -- Converts a std_logic value to boolean. + -- + function to_boolean_f(val : in std_logic) return boolean; + -- + ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + -- Function to_std_logic_f + -- + -- Purpose: + -- Converts a boolean value to std_logic. + -- + function to_std_logic_f(val : in boolean) return std_logic; + -- + ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + -- Function mod_6_f + -- + -- Purpose: + -- Calculate the modulo of 6. + -- Only the positive part is considered. + -- + function mod_6_f(val : in hv_t) return hv_t; + -- + ----------------------------------------------------------------------------- + +end vdp18_pack; +package body vdp18_pack is + + ----------------------------------------------------------------------------- + -- Function enum_to_vec_f + -- + -- Purpose: + -- Translate access_t enumeration type to std_logic_vector. + -- + function enum_to_vec_f(enum : in access_t) return + std_logic_vector is + variable result_v : std_logic_vector(3 downto 0); + begin + case enum is + when AC_NONE => result_v := "0000"; + when AC_PNT => result_v := "0001"; + when AC_PGT => result_v := "0010"; + when AC_PCT => result_v := "0011"; + when AC_STST => result_v := "0100"; + when AC_SATY => result_v := "0101"; + when AC_SATX => result_v := "0110"; + when AC_SATN => result_v := "0111"; + when AC_SATC => result_v := "1000"; + when AC_SPTL => result_v := "1001"; + when AC_SPTH => result_v := "1010"; + when AC_CPU => result_v := "1111"; + when others => result_v := "UUUU"; + end case; + + return result_v; + end; + -- + ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + -- Function to_boolean_f + -- + -- Purpose: + -- Converts a std_logic value to boolean. + -- + function to_boolean_f(val : in std_logic) return boolean is + variable result_v : boolean; + begin + case to_X01(val) is + when '1' => result_v := true; + when '0' => result_v := false; + when others => result_v := false; + end case; + + return result_v; + end; + -- + ----------------------------------------------------------------------------- + + ----------------------------------------------------------------------------- + -- Function to_std_logic_f + -- + -- Purpose: + -- Converts a boolean value to std_logic. + -- + function to_std_logic_f(val : in boolean) return std_logic is + variable result_v : std_logic; + begin + case val is + when true => result_v := '1'; + when false => result_v := '0'; + end case; + + return result_v; + end; + -- + ----------------------------------------------------------------------------- + + ----------------------------------------------------------------------------- + -- Function mod_6_f + -- + -- Purpose: + -- Calculate the modulo of 6. + -- Only the positive part is considered. + -- + function mod_6_f(val : in hv_t) return hv_t is + variable mod_v : natural; + variable result_v : hv_t; + begin + if val(0) = '0' then + result_v := (others => '0'); + mod_v := 0; + for idx in 0 to 255 loop + if val = idx then + result_v := to_signed(mod_v, hv_t'length); + end if; + + if mod_v < 5 then + mod_v := mod_v + 1; + else + mod_v := 0; + end if; + end loop; + else + result_v := (others => '-'); + end if; + + return result_v; + end; + -- + ----------------------------------------------------------------------------- + +end vdp18_pack; diff --git a/modules/video-vdp18/vdp18_pattern.vhd b/modules/video-vdp18/vdp18_pattern.vhd index 0c97743..ac541d1 100644 --- a/modules/video-vdp18/vdp18_pattern.vhd +++ b/modules/video-vdp18/vdp18_pattern.vhd @@ -1,233 +1,233 @@ -------------------------------------------------------------------------------- --- --- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. --- --- $Id: vdp18_pattern.vhd,v 1.8 2006/06/18 10:47:06 arnim Exp $ --- --- Pattern Generation Controller --- -------------------------------------------------------------------------------- --- --- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; - -use work.vdp18_pack.opmode_t; -use work.vdp18_pack.access_t; -use work.vdp18_pack.hv_t; - -entity vdp18_pattern is - - port ( - clk_i : in std_logic; - clk_en_5m37_i : in boolean; - clk_en_acc_i : in boolean; - reset_i : in boolean; - opmode_i : in opmode_t; - access_type_i : in access_t; - num_line_i : in hv_t; - vram_d_i : in std_logic_vector(0 to 7); - vert_inc_i : in boolean; - vsync_n_i : in std_logic; - reg_col1_i : in std_logic_vector(0 to 3); - reg_col0_i : in std_logic_vector(0 to 3); - pat_table_o : out std_logic_vector(0 to 9); - pat_name_o : out std_logic_vector(0 to 7); - pat_col_o : out std_logic_vector(0 to 3) - ); - -end vdp18_pattern; - - -library ieee; -use ieee.numeric_std.all; - -use work.vdp18_pack.all; - -architecture rtl of vdp18_pattern is - - signal pat_cnt_q : unsigned(0 to 9); - signal pat_name_q, - pat_tmp_q, - pat_shift_q, - pat_col_q : std_logic_vector(0 to 7); - -begin - - ----------------------------------------------------------------------------- - -- Process seq - -- - -- Purpose: - -- Implements the sequential elements: - -- * pattern shift register - -- * pattern color register - -- * pattern counter - -- - seq: process (clk_i, reset_i) - begin - if reset_i then - pat_cnt_q <= (others => '0'); - pat_name_q <= (others => '0'); - pat_tmp_q <= (others => '0'); - pat_shift_q <= (others => '0'); - pat_col_q <= (others => '0'); - - elsif clk_i'event and clk_i = '1' then - if clk_en_5m37_i then - -- shift pattern with every pixel clock - pat_shift_q(0 to 6) <= pat_shift_q(1 to 7); - end if; - - if clk_en_acc_i then - -- determine register update based on current access type ------------- - case access_type_i is - when AC_PNT => - -- store pattern name - pat_name_q <= vram_d_i; - -- increment pattern counter - pat_cnt_q <= pat_cnt_q + 1; - - when AC_PCT => - -- store pattern color in temporary register - pat_tmp_q <= vram_d_i; - - when AC_PGT => - if opmode_i = OPMODE_MULTIC then - -- set shift register to constant value - -- this value generates 4 bits of color1 - -- followed by 4 bits of color0 - pat_shift_q <= "11110000"; - -- set pattern color from pattern generator memory - pat_col_q <= vram_d_i; - else - -- all other modes: - -- store pattern line in shift register - pat_shift_q <= vram_d_i; - -- move pattern color from temporary register to color register - pat_col_q <= pat_tmp_q; - end if; - - when others => - null; - - end case; - - end if; - - if vert_inc_i then - -- redo patterns of if there are more lines inside this pattern - if num_line_i(0) = '0' then - case opmode_i is - when OPMODE_TEXTM => - if num_line_i(6 to 8) /= "111" then - pat_cnt_q <= pat_cnt_q - 40; - end if; - - when OPMODE_GRAPH1 | - OPMODE_GRAPH2 | - OPMODE_MULTIC => - if num_line_i(6 to 8) /= "111" then - pat_cnt_q <= pat_cnt_q - 32; - end if; - end case; - end if; - end if; - - if vsync_n_i = '0' then - -- reset pattern counter at end of active display area - pat_cnt_q <= (others => '0'); - end if; - - end if; - end process seq; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process col_gen - -- - -- Purpose: - -- Generates the color of the current pattern pixel. - -- - col_gen: process (opmode_i, - pat_shift_q, - pat_col_q, - reg_col1_i, - reg_col0_i) - variable pix_v : std_logic; - begin - -- default assignment - pat_col_o <= "0000"; - pix_v := pat_shift_q(0); - - case opmode_i is - -- Text Mode ------------------------------------------------------------ - when OPMODE_TEXTM => - if pix_v = '1' then - pat_col_o <= reg_col1_i; - else - pat_col_o <= reg_col0_i; - end if; - - -- Graphics I, II and Multicolor Mode ----------------------------------- - when OPMODE_GRAPH1 | - OPMODE_GRAPH2 | - OPMODE_MULTIC => - if pix_v = '1' then - pat_col_o <= pat_col_q(0 to 3); - else - pat_col_o <= pat_col_q(4 to 7); - end if; - - when others => - null; - - end case; - end process col_gen; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Output Mapping - ----------------------------------------------------------------------------- - pat_table_o <= std_logic_vector(pat_cnt_q); - pat_name_o <= pat_name_q; - -end rtl; +------------------------------------------------------------------------------- +-- +-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. +-- +-- $Id: vdp18_pattern.vhd,v 1.8 2006/06/18 10:47:06 arnim Exp $ +-- +-- Pattern Generation Controller +-- +------------------------------------------------------------------------------- +-- +-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; + +use work.vdp18_pack.opmode_t; +use work.vdp18_pack.access_t; +use work.vdp18_pack.hv_t; + +entity vdp18_pattern is + + port ( + clk_i : in std_logic; + clk_en_5m37_i : in boolean; + clk_en_acc_i : in boolean; + reset_i : in boolean; + opmode_i : in opmode_t; + access_type_i : in access_t; + num_line_i : in hv_t; + vram_d_i : in std_logic_vector(0 to 7); + vert_inc_i : in boolean; + vsync_n_i : in std_logic; + reg_col1_i : in std_logic_vector(0 to 3); + reg_col0_i : in std_logic_vector(0 to 3); + pat_table_o : out std_logic_vector(0 to 9); + pat_name_o : out std_logic_vector(0 to 7); + pat_col_o : out std_logic_vector(0 to 3) + ); + +end vdp18_pattern; + + +library ieee; +use ieee.numeric_std.all; + +use work.vdp18_pack.all; + +architecture rtl of vdp18_pattern is + + signal pat_cnt_q : unsigned(0 to 9); + signal pat_name_q, + pat_tmp_q, + pat_shift_q, + pat_col_q : std_logic_vector(0 to 7); + +begin + + ----------------------------------------------------------------------------- + -- Process seq + -- + -- Purpose: + -- Implements the sequential elements: + -- * pattern shift register + -- * pattern color register + -- * pattern counter + -- + seq: process (clk_i, reset_i) + begin + if reset_i then + pat_cnt_q <= (others => '0'); + pat_name_q <= (others => '0'); + pat_tmp_q <= (others => '0'); + pat_shift_q <= (others => '0'); + pat_col_q <= (others => '0'); + + elsif clk_i'event and clk_i = '1' then + if clk_en_5m37_i then + -- shift pattern with every pixel clock + pat_shift_q(0 to 6) <= pat_shift_q(1 to 7); + end if; + + if clk_en_acc_i then + -- determine register update based on current access type ------------- + case access_type_i is + when AC_PNT => + -- store pattern name + pat_name_q <= vram_d_i; + -- increment pattern counter + pat_cnt_q <= pat_cnt_q + 1; + + when AC_PCT => + -- store pattern color in temporary register + pat_tmp_q <= vram_d_i; + + when AC_PGT => + if opmode_i = OPMODE_MULTIC then + -- set shift register to constant value + -- this value generates 4 bits of color1 + -- followed by 4 bits of color0 + pat_shift_q <= "11110000"; + -- set pattern color from pattern generator memory + pat_col_q <= vram_d_i; + else + -- all other modes: + -- store pattern line in shift register + pat_shift_q <= vram_d_i; + -- move pattern color from temporary register to color register + pat_col_q <= pat_tmp_q; + end if; + + when others => + null; + + end case; + + end if; + + if vert_inc_i then + -- redo patterns of if there are more lines inside this pattern + if num_line_i(0) = '0' then + case opmode_i is + when OPMODE_TEXTM => + if num_line_i(6 to 8) /= "111" then + pat_cnt_q <= pat_cnt_q - 40; + end if; + + when OPMODE_GRAPH1 | + OPMODE_GRAPH2 | + OPMODE_MULTIC => + if num_line_i(6 to 8) /= "111" then + pat_cnt_q <= pat_cnt_q - 32; + end if; + end case; + end if; + end if; + + if vsync_n_i = '0' then + -- reset pattern counter at end of active display area + pat_cnt_q <= (others => '0'); + end if; + + end if; + end process seq; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process col_gen + -- + -- Purpose: + -- Generates the color of the current pattern pixel. + -- + col_gen: process (opmode_i, + pat_shift_q, + pat_col_q, + reg_col1_i, + reg_col0_i) + variable pix_v : std_logic; + begin + -- default assignment + pat_col_o <= "0000"; + pix_v := pat_shift_q(0); + + case opmode_i is + -- Text Mode ------------------------------------------------------------ + when OPMODE_TEXTM => + if pix_v = '1' then + pat_col_o <= reg_col1_i; + else + pat_col_o <= reg_col0_i; + end if; + + -- Graphics I, II and Multicolor Mode ----------------------------------- + when OPMODE_GRAPH1 | + OPMODE_GRAPH2 | + OPMODE_MULTIC => + if pix_v = '1' then + pat_col_o <= pat_col_q(0 to 3); + else + pat_col_o <= pat_col_q(4 to 7); + end if; + + when others => + null; + + end case; + end process col_gen; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Output Mapping + ----------------------------------------------------------------------------- + pat_table_o <= std_logic_vector(pat_cnt_q); + pat_name_o <= pat_name_q; + +end rtl; diff --git a/modules/video-vdp18/vdp18_sprite.vhd b/modules/video-vdp18/vdp18_sprite.vhd index 3dcb36b..443b02b 100644 --- a/modules/video-vdp18/vdp18_sprite.vhd +++ b/modules/video-vdp18/vdp18_sprite.vhd @@ -1,442 +1,442 @@ -------------------------------------------------------------------------------- --- --- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. --- --- $Id: vdp18_sprite.vhd,v 1.11 2006/06/18 10:47:06 arnim Exp $ --- --- Sprite Generation Controller --- --- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) --- --- All rights reserved --- --- Redistribution and use in source and synthezised forms, with or without --- modification, are permitted provided that the following conditions are met: --- --- Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- --- Redistributions in synthesized form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- --- Neither the name of the author nor the names of other contributors may --- be used to endorse or promote products derived from this software without --- specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" --- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, --- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE --- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR --- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF --- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS --- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN --- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) --- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --- POSSIBILITY OF SUCH DAMAGE. --- --- Please report bugs to the author, but before you do so, please --- make sure that this is not a derivative work and that --- you have the latest version of this file. --- -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; - -use work.vdp18_pack.hv_t; -use work.vdp18_pack.access_t; - -entity vdp18_sprite is - - port ( - clk_i : in std_logic; - clk_en_5m37_i : in boolean; - clk_en_acc_i : in boolean; - reset_i : in boolean; - access_type_i : in access_t; - num_pix_i : in hv_t; - num_line_i : in hv_t; - vram_d_i : in std_logic_vector(0 to 7); - vert_inc_i : in boolean; - reg_size1_i : in boolean; - reg_mag1_i : in boolean; - spr_5th_o : out boolean; - spr_5th_num_o : out std_logic_vector(0 to 4); - stop_sprite_o : out boolean; - spr_coll_o : out boolean; - spr_num_o : out std_logic_vector(0 to 4); - spr_line_o : out std_logic_vector(0 to 3); - spr_name_o : out std_logic_vector(0 to 7); - spr0_col_o : out std_logic_vector(0 to 3); - spr1_col_o : out std_logic_vector(0 to 3); - spr2_col_o : out std_logic_vector(0 to 3); - spr3_col_o : out std_logic_vector(0 to 3) - ); - -end vdp18_sprite; - - -library ieee; -use ieee.numeric_std.all; - -use work.vdp18_pack.all; - -architecture rtl of vdp18_sprite is - - subtype sprite_number_t is unsigned(0 to 4); - type sprite_numbers_t is array (natural range 0 to 3) of sprite_number_t; - signal sprite_numbers_q : sprite_numbers_t; - - signal sprite_num_q : unsigned(0 to 4); - signal sprite_idx_q : unsigned(0 to 2); - signal sprite_name_q : std_logic_vector(0 to 7); - - subtype sprite_x_pos_t is unsigned(0 to 7); - type sprite_xpos_t is array (natural range 0 to 3) of sprite_x_pos_t; - signal sprite_xpos_q : sprite_xpos_t; - type sprite_ec_t is array (natural range 0 to 3) of std_logic; - signal sprite_ec_q : sprite_ec_t; - type sprite_xtog_t is array (natural range 0 to 3) of std_logic; - signal sprite_xtog_q : sprite_xtog_t; - - subtype sprite_col_t is std_logic_vector(0 to 3); - type sprite_cols_t is array (natural range 0 to 3) of sprite_col_t; - signal sprite_cols_q : sprite_cols_t; - - subtype sprite_pat_t is std_logic_vector(0 to 15); - type sprite_pats_t is array (natural range 0 to 3) of sprite_pat_t; - signal sprite_pats_q : sprite_pats_t; - - signal sprite_line_s, - sprite_line_q : std_logic_vector(0 to 3); - signal sprite_visible_s : boolean; - -begin - - ----------------------------------------------------------------------------- - -- Process seq - -- - -- Purpose: - -- Implements the sequential elements. - -- - seq: process (clk_i, reset_i) - variable sprite_idx_inc_v, - sprite_idx_dec_v : unsigned(sprite_idx_q'range); - variable sprite_idx_v : natural range 0 to 3; - begin - if reset_i then - sprite_numbers_q <= (others => (others => '0')); - sprite_num_q <= (others => '0'); - sprite_idx_q <= (others => '0'); - sprite_line_q <= (others => '0'); - sprite_name_q <= (others => '0'); - sprite_cols_q <= (others => (others => '0')); - sprite_xpos_q <= (others => (others => '0')); - sprite_ec_q <= (others => '0'); - sprite_xtog_q <= (others => '0'); - sprite_pats_q <= (others => (others => '0')); - - elsif clk_i'event and clk_i = '1' then - -- sprite index will be incremented during sprite tests - sprite_idx_inc_v := sprite_idx_q + 1; - -- sprite index will be decremented at end of sprite pattern data - sprite_idx_dec_v := sprite_idx_q - 1; - -- just save typing - sprite_idx_v := to_integer(sprite_idx_q(1 to 2)); - - if clk_en_5m37_i then - -- pre-decrement index counter when sprite reading starts - if num_pix_i = hv_sprite_start_c and sprite_idx_q > 0 then - sprite_idx_q <= sprite_idx_dec_v; - end if; - - ----------------------------------------------------------------------- - -- X position counters - ----------------------------------------------------------------------- - for idx in 0 to 3 loop - if num_pix_i(0) = '0' or - (sprite_ec_q(idx) = '1' and num_pix_i(0 to 3) = "1111") then - if sprite_xpos_q(idx) /= 0 then - -- decrement counter until 0 - sprite_xpos_q(idx) <= sprite_xpos_q(idx) - 1; - else - -- toggle magnification flag - sprite_xtog_q(idx) <= not sprite_xtog_q(idx); - end if; - end if; - end loop; - - ----------------------------------------------------------------------- - -- Sprite pattern shift registers - ----------------------------------------------------------------------- - for idx in 0 to 3 loop - if sprite_xpos_q(idx) = 0 then -- x counter elapsed - -- decide when to shift pattern information - -- case 1: pixel number is >= 0 - -- => active display area - -- case 2: early clock bit is set and pixel number is between - -- -32 and 0 - -- shift if - -- magnification not enbled - -- or - -- magnification enabled and toggle marker true - if (num_pix_i(0) = '0' or - (sprite_ec_q(idx) = '1' and num_pix_i(0 to 3) = "1111")) and - (sprite_xtog_q(idx) = '1' or not reg_mag1_i) then - -- - -- shift pattern left and fill vacated position with - -- transparent information - sprite_pats_q(idx)(0 to 14) <= sprite_pats_q(idx)(1 to 15); - sprite_pats_q(idx)(15) <= '0'; - end if; - end if; - - -- clear pattern at end of visible display - -- this removes "left-overs" when a sprite overlaps the right border - if num_pix_i = "011111111" then - sprite_pats_q(idx) <= (others => '0'); - end if; - end loop; - end if; - - - if vert_inc_i then - -- reset sprite num counter and sprite index counter - sprite_num_q <= (others => '0'); - sprite_idx_q <= (others => '0'); - - elsif clk_en_acc_i then - case access_type_i is - when AC_STST => - -- increment sprite number counter - sprite_num_q <= sprite_num_q + 1; - - if sprite_visible_s then - if sprite_idx_q < 4 then - -- store sprite number - sprite_numbers_q(sprite_idx_v) <= sprite_num_q; - -- and increment index counter - sprite_idx_q <= sprite_idx_inc_v; - end if; - end if; - - when AC_SATY => - -- store sprite line - sprite_line_q <= sprite_line_s; - - when AC_SATX => - -- save x position - sprite_xpos_q(sprite_idx_v) <= unsigned(vram_d_i); - -- reset toggle flag for magnified sprites - sprite_xtog_q(sprite_idx_v) <= '0'; - - when AC_SATN => - -- save sprite name - sprite_name_q <= vram_d_i; - - when AC_SATC => - -- save sprite color - sprite_cols_q(sprite_idx_v) <= vram_d_i(4 to 7); - -- and save early clock bit - sprite_ec_q(sprite_idx_v) <= vram_d_i(0); - - when AC_SPTH => - -- save upper pattern data - sprite_pats_q(sprite_idx_v)(0 to 7) - <= vram_d_i; - -- set lower part to transparent - sprite_pats_q(sprite_idx_v)(8 to 15) - <= (others => '0'); - - if not reg_size1_i then - -- decrement index counter in 8-bit mode - sprite_idx_q <= sprite_idx_dec_v; - end if; - - when AC_SPTL => - -- save lower pattern data - sprite_pats_q(sprite_idx_v)(8 to 15) <= vram_d_i; - - -- always decrement index counter - sprite_idx_q <= sprite_idx_dec_v; - - when others => - null; - end case; - - end if; - - end if; - end process seq; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process calc_vert - -- - -- Purpose: - -- Calculates the displayed line of the sprite and determines whether it - -- is visible on the current line or not. - -- - calc_vert: process (clk_en_acc_i, access_type_i, - vram_d_i, - num_pix_i, num_line_i, - sprite_num_q, sprite_idx_q, - reg_size1_i, reg_mag1_i) - variable sprite_line_v : signed(0 to 8); - variable vram_d_v : signed(0 to 8); - begin - -- default assignments - sprite_visible_s <= false; - stop_sprite_o <= false; - - vram_d_v := resize(signed(vram_d_i), 9); - -- determine if y information from VRAM should be treated - -- as a signed or unsigned number - if vram_d_v < -31 then - -- treat as unsigned number - vram_d_v(0) := '0'; - end if; - - sprite_line_v := num_line_i - vram_d_v; - if reg_mag1_i then - -- unmagnify line number - sprite_line_v := shift_right(sprite_line_v, 1); - end if; - - -- check result bounds - if sprite_line_v >= 0 then - if reg_size1_i then - -- double sized sprite: 16 data lines - if sprite_line_v < 16 then - sprite_visible_s <= true; - end if; - else - -- standard sized sprite: 8 data lines - if sprite_line_v < 8 then - sprite_visible_s <= true; - end if; - end if; - end if; - - -- finally: line number of current sprite - sprite_line_s <= std_logic_vector(sprite_line_v(5 to 8)); - - if clk_en_acc_i then - -- determine when to stop sprite scanning - if access_type_i = AC_STST then - if vram_d_v = 208 then - -- stop upon Y position 208 - stop_sprite_o <= true; - end if; - - if sprite_idx_q = 4 then - -- stop when all sprite positions have been vacated - stop_sprite_o <= true; - end if; - - if sprite_num_q = 31 then - -- stop when all sprites have been read - stop_sprite_o <= true; - end if; - end if; - - -- stop sprite reading when last active sprite has been processed - if sprite_idx_q = 0 and - ( access_type_i = AC_SPTL or - (access_type_i = AC_SPTH and not reg_size1_i)) then - stop_sprite_o <= true; - end if; - end if; - - -- stop sprite reading when no sprite is active on current line - if num_pix_i = hv_sprite_start_c and sprite_idx_q = 0 then - stop_sprite_o <= true; - end if; - end process calc_vert; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process fifth - -- - -- Purpose: - -- Detects the fifth sprite. - -- - fifth: process (clk_en_acc_i, access_type_i, - sprite_visible_s, - sprite_idx_q, - sprite_num_q) - begin - -- default assignments - spr_5th_o <= false; - spr_5th_num_o <= std_logic_vector(sprite_num_q); - - if clk_en_acc_i and access_type_i = AC_STST then - if sprite_visible_s and sprite_idx_q = 4 then - spr_5th_o <= true; - --Always output current sprite number. Latched elsewhere by spr_5th_o. - --spr_5th_num_o <= std_logic_vector(sprite_num_q); - end if; - end if; - end process fifth; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Process col_mux - -- - -- Purpose: - -- Implements the color multiplexers. - -- - col_mux: process (sprite_cols_q, - sprite_pats_q, - sprite_xpos_q) - variable num_spr_pix_v : unsigned(0 to 2); - begin - -- default assignments - -- sprite colors are set to transparent - spr0_col_o <= (others => '0'); - spr1_col_o <= (others => '0'); - spr2_col_o <= (others => '0'); - spr3_col_o <= (others => '0'); - num_spr_pix_v := (others => '0'); - - if sprite_xpos_q(0) = 0 and sprite_pats_q(0)(0) = '1' then - spr0_col_o <= sprite_cols_q(0); - num_spr_pix_v := num_spr_pix_v + 1; - end if; - if sprite_xpos_q(1) = 0 and sprite_pats_q(1)(0) = '1' then - spr1_col_o <= sprite_cols_q(1); - num_spr_pix_v := num_spr_pix_v + 1; - end if; - if sprite_xpos_q(2) = 0 and sprite_pats_q(2)(0) = '1' then - spr2_col_o <= sprite_cols_q(2); - num_spr_pix_v := num_spr_pix_v + 1; - end if; - if sprite_xpos_q(3) = 0 and sprite_pats_q(3)(0) = '1' then - spr3_col_o <= sprite_cols_q(3); - num_spr_pix_v := num_spr_pix_v + 1; - end if; - - spr_coll_o <= num_spr_pix_v > 1; - end process col_mux; - -- - ----------------------------------------------------------------------------- - - - ----------------------------------------------------------------------------- - -- Output mapping - ----------------------------------------------------------------------------- - spr_num_o <= std_logic_vector(sprite_num_q) - when access_type_i = AC_STST else - std_logic_vector(sprite_numbers_q(to_integer(sprite_idx_q(1 to 2)))); - spr_line_o <= sprite_line_q; - spr_name_o <= sprite_name_q; - -end rtl; +------------------------------------------------------------------------------- +-- +-- Synthesizable model of TI's TMS9918A, TMS9928A, TMS9929A. +-- +-- $Id: vdp18_sprite.vhd,v 1.11 2006/06/18 10:47:06 arnim Exp $ +-- +-- Sprite Generation Controller +-- +-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; + +use work.vdp18_pack.hv_t; +use work.vdp18_pack.access_t; + +entity vdp18_sprite is + + port ( + clk_i : in std_logic; + clk_en_5m37_i : in boolean; + clk_en_acc_i : in boolean; + reset_i : in boolean; + access_type_i : in access_t; + num_pix_i : in hv_t; + num_line_i : in hv_t; + vram_d_i : in std_logic_vector(0 to 7); + vert_inc_i : in boolean; + reg_size1_i : in boolean; + reg_mag1_i : in boolean; + spr_5th_o : out boolean; + spr_5th_num_o : out std_logic_vector(0 to 4); + stop_sprite_o : out boolean; + spr_coll_o : out boolean; + spr_num_o : out std_logic_vector(0 to 4); + spr_line_o : out std_logic_vector(0 to 3); + spr_name_o : out std_logic_vector(0 to 7); + spr0_col_o : out std_logic_vector(0 to 3); + spr1_col_o : out std_logic_vector(0 to 3); + spr2_col_o : out std_logic_vector(0 to 3); + spr3_col_o : out std_logic_vector(0 to 3) + ); + +end vdp18_sprite; + + +library ieee; +use ieee.numeric_std.all; + +use work.vdp18_pack.all; + +architecture rtl of vdp18_sprite is + + subtype sprite_number_t is unsigned(0 to 4); + type sprite_numbers_t is array (natural range 0 to 3) of sprite_number_t; + signal sprite_numbers_q : sprite_numbers_t; + + signal sprite_num_q : unsigned(0 to 4); + signal sprite_idx_q : unsigned(0 to 2); + signal sprite_name_q : std_logic_vector(0 to 7); + + subtype sprite_x_pos_t is unsigned(0 to 7); + type sprite_xpos_t is array (natural range 0 to 3) of sprite_x_pos_t; + signal sprite_xpos_q : sprite_xpos_t; + type sprite_ec_t is array (natural range 0 to 3) of std_logic; + signal sprite_ec_q : sprite_ec_t; + type sprite_xtog_t is array (natural range 0 to 3) of std_logic; + signal sprite_xtog_q : sprite_xtog_t; + + subtype sprite_col_t is std_logic_vector(0 to 3); + type sprite_cols_t is array (natural range 0 to 3) of sprite_col_t; + signal sprite_cols_q : sprite_cols_t; + + subtype sprite_pat_t is std_logic_vector(0 to 15); + type sprite_pats_t is array (natural range 0 to 3) of sprite_pat_t; + signal sprite_pats_q : sprite_pats_t; + + signal sprite_line_s, + sprite_line_q : std_logic_vector(0 to 3); + signal sprite_visible_s : boolean; + +begin + + ----------------------------------------------------------------------------- + -- Process seq + -- + -- Purpose: + -- Implements the sequential elements. + -- + seq: process (clk_i, reset_i) + variable sprite_idx_inc_v, + sprite_idx_dec_v : unsigned(sprite_idx_q'range); + variable sprite_idx_v : natural range 0 to 3; + begin + if reset_i then + sprite_numbers_q <= (others => (others => '0')); + sprite_num_q <= (others => '0'); + sprite_idx_q <= (others => '0'); + sprite_line_q <= (others => '0'); + sprite_name_q <= (others => '0'); + sprite_cols_q <= (others => (others => '0')); + sprite_xpos_q <= (others => (others => '0')); + sprite_ec_q <= (others => '0'); + sprite_xtog_q <= (others => '0'); + sprite_pats_q <= (others => (others => '0')); + + elsif clk_i'event and clk_i = '1' then + -- sprite index will be incremented during sprite tests + sprite_idx_inc_v := sprite_idx_q + 1; + -- sprite index will be decremented at end of sprite pattern data + sprite_idx_dec_v := sprite_idx_q - 1; + -- just save typing + sprite_idx_v := to_integer(sprite_idx_q(1 to 2)); + + if clk_en_5m37_i then + -- pre-decrement index counter when sprite reading starts + if num_pix_i = hv_sprite_start_c and sprite_idx_q > 0 then + sprite_idx_q <= sprite_idx_dec_v; + end if; + + ----------------------------------------------------------------------- + -- X position counters + ----------------------------------------------------------------------- + for idx in 0 to 3 loop + if num_pix_i(0) = '0' or + (sprite_ec_q(idx) = '1' and num_pix_i(0 to 3) = "1111") then + if sprite_xpos_q(idx) /= 0 then + -- decrement counter until 0 + sprite_xpos_q(idx) <= sprite_xpos_q(idx) - 1; + else + -- toggle magnification flag + sprite_xtog_q(idx) <= not sprite_xtog_q(idx); + end if; + end if; + end loop; + + ----------------------------------------------------------------------- + -- Sprite pattern shift registers + ----------------------------------------------------------------------- + for idx in 0 to 3 loop + if sprite_xpos_q(idx) = 0 then -- x counter elapsed + -- decide when to shift pattern information + -- case 1: pixel number is >= 0 + -- => active display area + -- case 2: early clock bit is set and pixel number is between + -- -32 and 0 + -- shift if + -- magnification not enbled + -- or + -- magnification enabled and toggle marker true + if (num_pix_i(0) = '0' or + (sprite_ec_q(idx) = '1' and num_pix_i(0 to 3) = "1111")) and + (sprite_xtog_q(idx) = '1' or not reg_mag1_i) then + -- + -- shift pattern left and fill vacated position with + -- transparent information + sprite_pats_q(idx)(0 to 14) <= sprite_pats_q(idx)(1 to 15); + sprite_pats_q(idx)(15) <= '0'; + end if; + end if; + + -- clear pattern at end of visible display + -- this removes "left-overs" when a sprite overlaps the right border + if num_pix_i = "011111111" then + sprite_pats_q(idx) <= (others => '0'); + end if; + end loop; + end if; + + + if vert_inc_i then + -- reset sprite num counter and sprite index counter + sprite_num_q <= (others => '0'); + sprite_idx_q <= (others => '0'); + + elsif clk_en_acc_i then + case access_type_i is + when AC_STST => + -- increment sprite number counter + sprite_num_q <= sprite_num_q + 1; + + if sprite_visible_s then + if sprite_idx_q < 4 then + -- store sprite number + sprite_numbers_q(sprite_idx_v) <= sprite_num_q; + -- and increment index counter + sprite_idx_q <= sprite_idx_inc_v; + end if; + end if; + + when AC_SATY => + -- store sprite line + sprite_line_q <= sprite_line_s; + + when AC_SATX => + -- save x position + sprite_xpos_q(sprite_idx_v) <= unsigned(vram_d_i); + -- reset toggle flag for magnified sprites + sprite_xtog_q(sprite_idx_v) <= '0'; + + when AC_SATN => + -- save sprite name + sprite_name_q <= vram_d_i; + + when AC_SATC => + -- save sprite color + sprite_cols_q(sprite_idx_v) <= vram_d_i(4 to 7); + -- and save early clock bit + sprite_ec_q(sprite_idx_v) <= vram_d_i(0); + + when AC_SPTH => + -- save upper pattern data + sprite_pats_q(sprite_idx_v)(0 to 7) + <= vram_d_i; + -- set lower part to transparent + sprite_pats_q(sprite_idx_v)(8 to 15) + <= (others => '0'); + + if not reg_size1_i then + -- decrement index counter in 8-bit mode + sprite_idx_q <= sprite_idx_dec_v; + end if; + + when AC_SPTL => + -- save lower pattern data + sprite_pats_q(sprite_idx_v)(8 to 15) <= vram_d_i; + + -- always decrement index counter + sprite_idx_q <= sprite_idx_dec_v; + + when others => + null; + end case; + + end if; + + end if; + end process seq; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process calc_vert + -- + -- Purpose: + -- Calculates the displayed line of the sprite and determines whether it + -- is visible on the current line or not. + -- + calc_vert: process (clk_en_acc_i, access_type_i, + vram_d_i, + num_pix_i, num_line_i, + sprite_num_q, sprite_idx_q, + reg_size1_i, reg_mag1_i) + variable sprite_line_v : signed(0 to 8); + variable vram_d_v : signed(0 to 8); + begin + -- default assignments + sprite_visible_s <= false; + stop_sprite_o <= false; + + vram_d_v := resize(signed(vram_d_i), 9); + -- determine if y information from VRAM should be treated + -- as a signed or unsigned number + if vram_d_v < -31 then + -- treat as unsigned number + vram_d_v(0) := '0'; + end if; + + sprite_line_v := num_line_i - vram_d_v; + if reg_mag1_i then + -- unmagnify line number + sprite_line_v := shift_right(sprite_line_v, 1); + end if; + + -- check result bounds + if sprite_line_v >= 0 then + if reg_size1_i then + -- double sized sprite: 16 data lines + if sprite_line_v < 16 then + sprite_visible_s <= true; + end if; + else + -- standard sized sprite: 8 data lines + if sprite_line_v < 8 then + sprite_visible_s <= true; + end if; + end if; + end if; + + -- finally: line number of current sprite + sprite_line_s <= std_logic_vector(sprite_line_v(5 to 8)); + + if clk_en_acc_i then + -- determine when to stop sprite scanning + if access_type_i = AC_STST then + if vram_d_v = 208 then + -- stop upon Y position 208 + stop_sprite_o <= true; + end if; + + if sprite_idx_q = 4 then + -- stop when all sprite positions have been vacated + stop_sprite_o <= true; + end if; + + if sprite_num_q = 31 then + -- stop when all sprites have been read + stop_sprite_o <= true; + end if; + end if; + + -- stop sprite reading when last active sprite has been processed + if sprite_idx_q = 0 and + ( access_type_i = AC_SPTL or + (access_type_i = AC_SPTH and not reg_size1_i)) then + stop_sprite_o <= true; + end if; + end if; + + -- stop sprite reading when no sprite is active on current line + if num_pix_i = hv_sprite_start_c and sprite_idx_q = 0 then + stop_sprite_o <= true; + end if; + end process calc_vert; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process fifth + -- + -- Purpose: + -- Detects the fifth sprite. + -- + fifth: process (clk_en_acc_i, access_type_i, + sprite_visible_s, + sprite_idx_q, + sprite_num_q) + begin + -- default assignments + spr_5th_o <= false; + spr_5th_num_o <= std_logic_vector(sprite_num_q); + + if clk_en_acc_i and access_type_i = AC_STST then + if sprite_visible_s and sprite_idx_q = 4 then + spr_5th_o <= true; + --Always output current sprite number. Latched elsewhere by spr_5th_o. + --spr_5th_num_o <= std_logic_vector(sprite_num_q); + end if; + end if; + end process fifth; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Process col_mux + -- + -- Purpose: + -- Implements the color multiplexers. + -- + col_mux: process (sprite_cols_q, + sprite_pats_q, + sprite_xpos_q) + variable num_spr_pix_v : unsigned(0 to 2); + begin + -- default assignments + -- sprite colors are set to transparent + spr0_col_o <= (others => '0'); + spr1_col_o <= (others => '0'); + spr2_col_o <= (others => '0'); + spr3_col_o <= (others => '0'); + num_spr_pix_v := (others => '0'); + + if sprite_xpos_q(0) = 0 and sprite_pats_q(0)(0) = '1' then + spr0_col_o <= sprite_cols_q(0); + num_spr_pix_v := num_spr_pix_v + 1; + end if; + if sprite_xpos_q(1) = 0 and sprite_pats_q(1)(0) = '1' then + spr1_col_o <= sprite_cols_q(1); + num_spr_pix_v := num_spr_pix_v + 1; + end if; + if sprite_xpos_q(2) = 0 and sprite_pats_q(2)(0) = '1' then + spr2_col_o <= sprite_cols_q(2); + num_spr_pix_v := num_spr_pix_v + 1; + end if; + if sprite_xpos_q(3) = 0 and sprite_pats_q(3)(0) = '1' then + spr3_col_o <= sprite_cols_q(3); + num_spr_pix_v := num_spr_pix_v + 1; + end if; + + spr_coll_o <= num_spr_pix_v > 1; + end process col_mux; + -- + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Output mapping + ----------------------------------------------------------------------------- + spr_num_o <= std_logic_vector(sprite_num_q) + when access_type_i = AC_STST else + std_logic_vector(sprite_numbers_q(to_integer(sprite_idx_q(1 to 2)))); + spr_line_o <= sprite_line_q; + spr_name_o <= sprite_name_q; + +end rtl; diff --git a/pkg/pocket/Cores/boogermann.msx/audio.json b/pkg/pocket/Cores/boogermann.msx/audio.json index ea8e2f4..78bee1c 100644 --- a/pkg/pocket/Cores/boogermann.msx/audio.json +++ b/pkg/pocket/Cores/boogermann.msx/audio.json @@ -1,5 +1,5 @@ -{ - "audio": { - "magic": "APF_VER_1" - } +{ + "audio": { + "magic": "APF_VER_1" + } } \ No newline at end of file diff --git a/pkg/pocket/Cores/boogermann.msx/core.json b/pkg/pocket/Cores/boogermann.msx/core.json index aadabca..81ba3e9 100644 --- a/pkg/pocket/Cores/boogermann.msx/core.json +++ b/pkg/pocket/Cores/boogermann.msx/core.json @@ -1,34 +1,34 @@ -{ - "core": { - "magic": "APF_VER_1", - "metadata": { - "platform_ids": ["msx","analogizer"], - "shortname": "msx", - "description": "MSX is a standardized home computer architecture, announced by ASCII Corporation on June 16, 1983.", - "author": "boogermann", - "url": "https://github.com/opengateware/computer-msx", - "version": "0.1.0", - "date_release": "2023-07-25" - }, - "framework": { - "target_product": "Analogue Pocket", - "version_required": "1.1", - "sleep_supported": false, - "dock": { - "supported": true, - "analog_output": false - }, - "hardware": { - "link_port": false, - "cartridge_adapter": 0 - } - }, - "cores": [ - { - "name": "default", - "id": 0, - "filename": "bitstream.rbf_r" - } - ] - } +{ + "core": { + "magic": "APF_VER_1", + "metadata": { + "platform_ids": ["msx","analogizer"], + "shortname": "msx", + "description": "MSX is a standardized home computer architecture, announced by ASCII Corporation on June 16, 1983.", + "author": "boogermann", + "url": "https://github.com/opengateware/computer-msx", + "version": "0.1.0", + "date_release": "2023-07-25" + }, + "framework": { + "target_product": "Analogue Pocket", + "version_required": "1.1", + "sleep_supported": false, + "dock": { + "supported": true, + "analog_output": false + }, + "hardware": { + "link_port": false, + "cartridge_adapter": 0 + } + }, + "cores": [ + { + "name": "default", + "id": 0, + "filename": "bitstream.rbf_r" + } + ] + } } \ No newline at end of file diff --git a/pkg/pocket/Cores/boogermann.msx/data.json b/pkg/pocket/Cores/boogermann.msx/data.json index 7643178..aacc0c7 100644 --- a/pkg/pocket/Cores/boogermann.msx/data.json +++ b/pkg/pocket/Cores/boogermann.msx/data.json @@ -1,51 +1,51 @@ -{ - "data": { - "magic": "APF_VER_1", - "data_slots": [ - { - "name": "Slot A", - "id": 0, - "required": false, - "parameters": "0x109", - "extensions": ["rom"], - "address": "0x00000000" - }, - { - "name": "Slot B", - "id": 1, - "required": false, - "parameters": "0x109", - "extensions": ["rom"], - "address": "0x00000000" - }, - { - "id": 2, - "name": "BIOS", - "required": false, - "parameters": "0x309", - "extensions": ["rom"], - "address": "0x00000000" - }, - { - "id": 3, - "name": "FW BIOS", - "required": false, - "parameters": "0x109", - "extensions": ["rom"], - "address": "0x00000000" - }, - { - "name": "Analogizer config", - "id": 10, - "required": false, - "parameters": "0x1000000", - "filename": "analogizer.bin", - "extensions": [ - "bin" - ], - "address": "0xF7000000", - "nonvolatile": false - } - ] - } +{ + "data": { + "magic": "APF_VER_1", + "data_slots": [ + { + "name": "Slot A", + "id": 0, + "required": false, + "parameters": "0x109", + "extensions": ["rom"], + "address": "0x00000000" + }, + { + "name": "Slot B", + "id": 1, + "required": false, + "parameters": "0x109", + "extensions": ["rom"], + "address": "0x00000000" + }, + { + "id": 2, + "name": "BIOS", + "required": false, + "parameters": "0x309", + "extensions": ["rom"], + "address": "0x00000000" + }, + { + "id": 3, + "name": "FW BIOS", + "required": false, + "parameters": "0x109", + "extensions": ["rom"], + "address": "0x00000000" + }, + { + "name": "Analogizer config", + "id": 10, + "required": false, + "parameters": "0x1000000", + "filename": "analogizer.bin", + "extensions": [ + "bin" + ], + "address": "0xF7000000", + "nonvolatile": false + } + ] + } } \ No newline at end of file diff --git a/pkg/pocket/Cores/boogermann.msx/info.txt b/pkg/pocket/Cores/boogermann.msx/info.txt index cd15c15..12db5ad 100644 --- a/pkg/pocket/Cores/boogermann.msx/info.txt +++ b/pkg/pocket/Cores/boogermann.msx/info.txt @@ -1,5 +1,5 @@ -MSX is a standardized home computer architecture, announced by ASCII Corporation on June 16, 1983. -It was initially conceived by Microsoft as a product for the Eastern sector, and jointly marketed by Kazuhiko Nishi, the director at ASCII Corporation. -Microsoft and Nishi conceived the project as an attempt to create unified standards among various home computing system manufacturers of the period, -in the same fashion as the VHS standard for home video tape machines. +MSX is a standardized home computer architecture, announced by ASCII Corporation on June 16, 1983. +It was initially conceived by Microsoft as a product for the Eastern sector, and jointly marketed by Kazuhiko Nishi, the director at ASCII Corporation. +Microsoft and Nishi conceived the project as an attempt to create unified standards among various home computing system manufacturers of the period, +in the same fashion as the VHS standard for home video tape machines. The first MSX computer sold to the public was a Mitsubishi ML-8000, released on October 21, 1983, thus marking its official release date \ No newline at end of file diff --git a/pkg/pocket/Cores/boogermann.msx/input.json b/pkg/pocket/Cores/boogermann.msx/input.json index f293817..1e3465f 100644 --- a/pkg/pocket/Cores/boogermann.msx/input.json +++ b/pkg/pocket/Cores/boogermann.msx/input.json @@ -1,22 +1,22 @@ -{ - "input": { - "magic": "APF_VER_1", - "controllers": [ - { - "type": "default", - "mappings": [ - { - "id": 0, - "name": "A Button", - "key": "pad_btn_a" - }, - { - "id": 1, - "name": "B Button", - "key": "pad_btn_b" - } - ] - } - ] - } +{ + "input": { + "magic": "APF_VER_1", + "controllers": [ + { + "type": "default", + "mappings": [ + { + "id": 0, + "name": "A Button", + "key": "pad_btn_a" + }, + { + "id": 1, + "name": "B Button", + "key": "pad_btn_b" + } + ] + } + ] + } } \ No newline at end of file diff --git a/pkg/pocket/Cores/boogermann.msx/interact.json b/pkg/pocket/Cores/boogermann.msx/interact.json index e8187f3..cf7f8e2 100644 --- a/pkg/pocket/Cores/boogermann.msx/interact.json +++ b/pkg/pocket/Cores/boogermann.msx/interact.json @@ -1,226 +1,215 @@ -{ - "interact": { - "magic": "APF_VER_1", - "variables": [ - { - "name": "Slot A Mapper", - "id": 0, - "type": "list", - "enabled": true, - "persist": true, - "address": "0xF1000000", - "defaultval": 0, - "mask": "0xFFFFFFF0", - "options": [ - { "name": "Auto", "value": "0x00" }, - { "name": "None", "value": "0x01" }, - { "name": "GameMaster2", "value": "0x02" }, - { "name": "Konami", "value": "0x03" }, - { "name": "KonamiSCC", "value": "0x04" }, - { "name": "ASCII8", "value": "0x05" }, - { "name": "ASCII16", "value": "0x06" }, - { "name": "Linear 64k", "value": "0x07" }, - { "name": "R-TYPE", "value": "0x08" } - ] - }, - { - "name": "Slot B Mapper", - "id": 1, - "type": "list", - "enabled": true, - "persist": true, - "address": "0xF1000000", - "defaultval": 0, - "mask": "0xFFFFFF0F", - "options": [ - { "name": "Auto", "value": "0x00" }, - { "name": "None", "value": "0x01" }, - { "name": "GameMaster2", "value": "0x02" }, - { "name": "Konami", "value": "0x03" }, - { "name": "KonamiSCC", "value": "0x04" }, - { "name": "ASCII8", "value": "0x05" }, - { "name": "ASCII16", "value": "0x06" }, - { "name": "Linear 64k", "value": "0x07" }, - { "name": "R-TYPE", "value": "0x08" } - ] - }, - { - "name": "Remove Cartridges", - "id": 5, - "type": "action", - "enabled": true, - "address": "0xF0000010", - "value": 1 - }, - { - "name": "Reset Core", - "id": 6, - "type": "action", - "enabled": true, - "address": "0xF0000000", - "value": 1 - }, - { - "name": "PAL Video", - "id": 3, - "type": "check", - "enabled": true, - "persist": true, - "address": "0xF1000000", - "defaultval": 0, - "mask": "0xFFFFFEFF", - "value": "0x00000100" - }, - { - "name": "Border", - "id": 4, - "type": "check", - "enabled": true, - "persist": true, - "address": "0xF1000000", - "defaultval": 0, - "mask": "0xFFFFFDFF", - "value": "0x00000200" - }, - { - "name": "Enable Joy2Key", - "id": 1000, - "type": "check", - "enabled": true, - "persist": true, - "address": "0xF1000000", - "defaultval": 0, - "mask": "0xFFFFFBFF", - "value": "0x00000400" - }, - { - "name": "Map Y to key", - "id": 1001, - "type": "list", - "enabled": true, - "persist": true, - "address": "0xF2000000", - "mask": "0xFFFFFFF0", - "defaultval": 0, - "options": [ - { "name": "Disable", "value": "0x0" }, - { "name": "Spacebar", "value": "0x1" }, - { "name": "Shift", "value": "0x2" }, - { "name": "M", "value": "0x3" }, - { "name": "N", "value": "0x4" }, - { "name": "1", "value": "0x5" }, - { "name": "2", "value": "0x6" }, - { "name": "3", "value": "0x7" }, - { "name": "4", "value": "0x8" }, - { "name": "Esc", "value": "0x9" }, - { "name": "Return", "value": "0xA" } - ] - }, - { - "name": "Map X to key", - "id": 1002, - "type": "list", - "enabled": true, - "persist": true, - "address": "0xF2000000", - "mask": "0xFFFFFF0F", - "defaultval": 0, - "options": [ - { "name": "Disable", "value": "0x00" }, - { "name": "Spacebar", "value": "0x10" }, - { "name": "Shift", "value": "0x20" }, - { "name": "M", "value": "0x30" }, - { "name": "N", "value": "0x40" }, - { "name": "1", "value": "0x50" }, - { "name": "2", "value": "0x60" }, - { "name": "3", "value": "0x70" }, - { "name": "4", "value": "0x80" }, - { "name": "Esc", "value": "0x90" }, - { "name": "Return", "value": "0xA0" } - ] - }, - { - "name": "Map L to key", - "id": 1003, - "type": "list", - "enabled": true, - "persist": true, - "address": "0xF2000000", - "mask": "0xFFFFF0FF", - "defaultval": 0, - "options": [ - { "name": "Disable", "value": "0x000" }, - { "name": "Select", "value": "0x100" }, - { "name": "Stop", "value": "0x200" }, - { "name": "Graph", "value": "0x300" }, - { "name": "Crtl", "value": "0x400" }, - { "name": "F1", "value": "0x500" } - ] - }, - { - "name": "Map R to key", - "id": 1004, - "type": "list", - "enabled": true, - "persist": true, - "address": "0xF2000000", - "mask": "0xFFFF0FFF", - "defaultval": 0, - "options": [ - { "name": "Disable", "value": "0x0000" }, - { "name": "Select", "value": "0x1000" }, - { "name": "Stop", "value": "0x2000" }, - { "name": "Graph", "value": "0x3000" }, - { "name": "Crtl", "value": "0x4000" }, - { "name": "F5", "value": "0x5000" } - ] - }, - { - "name": "Map Select to key", - "id": 1005, - "type": "list", - "enabled": true, - "persist": true, - "address": "0xF2000000", - "mask": "0xFFF0FFFF", - "defaultval": 0, - "options": [ - { "name": "Disable", "value": "0x00000" }, - { "name": "Spacebar", "value": "0x10000" }, - { "name": "F1", "value": "0x20000" }, - { "name": "F2", "value": "0x30000" }, - { "name": "F3", "value": "0x40000" }, - { "name": "F4", "value": "0x50000" }, - { "name": "F5", "value": "0x60000" } - ] - }, - { - "name": "Map Start to key", - "id": 1006, - "type": "list", - "enabled": true, - "persist": true, - "address": "0xF2000000", - "mask": "0xFF0FFFFF", - "defaultval": 0, - "options": [ - { "name": "Disable", "value": "0x000000" }, - { "name": "Spacebar", "value": "0x100000" }, - { "name": "F1", "value": "0x200000" }, - { "name": "F2", "value": "0x300000" }, - { "name": "F3", "value": "0x400000" }, - { "name": "F4", "value": "0x500000" }, - { "name": "F5", "value": "0x600000" } - ] - }, - { - "name": "Map", - "id": 100, - "type": "number_u32", - "enabled": false, - "address": "0xF2000000" - } - ], - "messages": [] - } +{ + "interact": { + "magic": "APF_VER_1", + "variables": [ + { + "name": "Slot A Mapper", + "id": 0, + "type": "list", + "enabled": true, + "persist": true, + "address": "0xF1000000", + "defaultval": 0, + "mask": "0xFFFFFFF0", + "options": [ + { "name": "Auto", "value": "0x00" }, + { "name": "None", "value": "0x01" }, + { "name": "GameMaster2", "value": "0x02" }, + { "name": "Konami", "value": "0x03" }, + { "name": "KonamiSCC", "value": "0x04" }, + { "name": "ASCII8", "value": "0x05" }, + { "name": "ASCII16", "value": "0x06" }, + { "name": "Linear 64k", "value": "0x07" }, + { "name": "R-TYPE", "value": "0x08" } + ] + }, + { + "name": "Slot B Mapper", + "id": 1, + "type": "list", + "enabled": true, + "persist": true, + "address": "0xF1000000", + "defaultval": 0, + "mask": "0xFFFFFF0F", + "options": [ + { "name": "Auto", "value": "0x00" }, + { "name": "None", "value": "0x01" }, + { "name": "GameMaster2", "value": "0x02" }, + { "name": "Konami", "value": "0x03" }, + { "name": "KonamiSCC", "value": "0x04" }, + { "name": "ASCII8", "value": "0x05" }, + { "name": "ASCII16", "value": "0x06" }, + { "name": "Linear 64k", "value": "0x07" }, + { "name": "R-TYPE", "value": "0x08" } + ] + }, + { + "name": "Remove Cartridges", + "id": 5, + "type": "action", + "enabled": true, + "address": "0xF0000010", + "value": 1 + }, + { + "name": "Reset Core", + "id": 6, + "type": "action", + "enabled": true, + "address": "0xF0000000", + "value": 1 + }, + { + "name": "PAL Video", + "id": 3, + "type": "check", + "enabled": true, + "persist": true, + "address": "0xF1000000", + "defaultval": 0, + "mask": "0xFFFFFEFF", + "value": "0x00000100" + }, + { + "name": "Enable Joy2Key", + "id": 1000, + "type": "check", + "enabled": true, + "persist": true, + "address": "0xF1000000", + "defaultval": 0, + "mask": "0xFFFFFBFF", + "value": "0x00000400" + }, + { + "name": "Map Y to key", + "id": 1001, + "type": "list", + "enabled": true, + "persist": true, + "address": "0xF2000000", + "mask": "0xFFFFFFF0", + "defaultval": 0, + "options": [ + { "name": "Disable", "value": "0x0" }, + { "name": "Spacebar", "value": "0x1" }, + { "name": "Shift", "value": "0x2" }, + { "name": "M", "value": "0x3" }, + { "name": "N", "value": "0x4" }, + { "name": "1", "value": "0x5" }, + { "name": "2", "value": "0x6" }, + { "name": "3", "value": "0x7" }, + { "name": "4", "value": "0x8" }, + { "name": "Esc", "value": "0x9" }, + { "name": "Return", "value": "0xA" } + ] + }, + { + "name": "Map X to key", + "id": 1002, + "type": "list", + "enabled": true, + "persist": true, + "address": "0xF2000000", + "mask": "0xFFFFFF0F", + "defaultval": 0, + "options": [ + { "name": "Disable", "value": "0x00" }, + { "name": "Spacebar", "value": "0x10" }, + { "name": "Shift", "value": "0x20" }, + { "name": "M", "value": "0x30" }, + { "name": "N", "value": "0x40" }, + { "name": "1", "value": "0x50" }, + { "name": "2", "value": "0x60" }, + { "name": "3", "value": "0x70" }, + { "name": "4", "value": "0x80" }, + { "name": "Esc", "value": "0x90" }, + { "name": "Return", "value": "0xA0" } + ] + }, + { + "name": "Map L to key", + "id": 1003, + "type": "list", + "enabled": true, + "persist": true, + "address": "0xF2000000", + "mask": "0xFFFFF0FF", + "defaultval": 0, + "options": [ + { "name": "Disable", "value": "0x000" }, + { "name": "Select", "value": "0x100" }, + { "name": "Stop", "value": "0x200" }, + { "name": "Graph", "value": "0x300" }, + { "name": "Crtl", "value": "0x400" }, + { "name": "F1", "value": "0x500" } + ] + }, + { + "name": "Map R to key", + "id": 1004, + "type": "list", + "enabled": true, + "persist": true, + "address": "0xF2000000", + "mask": "0xFFFF0FFF", + "defaultval": 0, + "options": [ + { "name": "Disable", "value": "0x0000" }, + { "name": "Select", "value": "0x1000" }, + { "name": "Stop", "value": "0x2000" }, + { "name": "Graph", "value": "0x3000" }, + { "name": "Crtl", "value": "0x4000" }, + { "name": "F5", "value": "0x5000" } + ] + }, + { + "name": "Map Select to key", + "id": 1005, + "type": "list", + "enabled": true, + "persist": true, + "address": "0xF2000000", + "mask": "0xFFF0FFFF", + "defaultval": 0, + "options": [ + { "name": "Disable", "value": "0x00000" }, + { "name": "Spacebar", "value": "0x10000" }, + { "name": "F1", "value": "0x20000" }, + { "name": "F2", "value": "0x30000" }, + { "name": "F3", "value": "0x40000" }, + { "name": "F4", "value": "0x50000" }, + { "name": "F5", "value": "0x60000" } + ] + }, + { + "name": "Map Start to key", + "id": 1006, + "type": "list", + "enabled": true, + "persist": true, + "address": "0xF2000000", + "mask": "0xFF0FFFFF", + "defaultval": 0, + "options": [ + { "name": "Disable", "value": "0x000000" }, + { "name": "Spacebar", "value": "0x100000" }, + { "name": "F1", "value": "0x200000" }, + { "name": "F2", "value": "0x300000" }, + { "name": "F3", "value": "0x400000" }, + { "name": "F4", "value": "0x500000" }, + { "name": "F5", "value": "0x600000" } + ] + }, + { + "name": "Map", + "id": 100, + "type": "number_u32", + "enabled": false, + "address": "0xF2000000" + } + ], + "messages": [] + } } \ No newline at end of file diff --git a/pkg/pocket/Cores/boogermann.msx/variants.json b/pkg/pocket/Cores/boogermann.msx/variants.json index c2dbd41..7cf52e5 100644 --- a/pkg/pocket/Cores/boogermann.msx/variants.json +++ b/pkg/pocket/Cores/boogermann.msx/variants.json @@ -1,6 +1,6 @@ -{ - "variants": { - "magic": "APF_VER_1", - "variant_list": [] - } +{ + "variants": { + "magic": "APF_VER_1", + "variant_list": [] + } } \ No newline at end of file diff --git a/pkg/pocket/Cores/boogermann.msx/video.json b/pkg/pocket/Cores/boogermann.msx/video.json index 662b864..f9ac039 100644 --- a/pkg/pocket/Cores/boogermann.msx/video.json +++ b/pkg/pocket/Cores/boogermann.msx/video.json @@ -1,28 +1,28 @@ -{ - "video": { - "magic": "APF_VER_1", - "scaler_modes": [ - { - "width": 256, - "height": 192, - "aspect_w": 4, - "aspect_h": 3, - "rotation": 0, - "mirror": 0 - }, - { - "width": 284, - "height": 240, - "aspect_w": 4, - "aspect_h": 3, - "rotation": 0, - "mirror": 0 - } - ], - "display_modes": [ - { - "id": "0x10" - } - ] - } +{ + "video": { + "magic": "APF_VER_1", + "scaler_modes": [ + { + "width": 256, + "height": 192, + "aspect_w": 4, + "aspect_h": 3, + "rotation": 0, + "mirror": 0 + }, + { + "width": 284, + "height": 240, + "aspect_w": 4, + "aspect_h": 3, + "rotation": 0, + "mirror": 0 + } + ], + "display_modes": [ + { + "id": "0x10" + } + ] + } } \ No newline at end of file diff --git a/pkg/pocket/Platforms/msx.json b/pkg/pocket/Platforms/msx.json index f502183..c33688d 100644 --- a/pkg/pocket/Platforms/msx.json +++ b/pkg/pocket/Platforms/msx.json @@ -1,8 +1,8 @@ -{ - "platform": { - "category": "Computer", - "name": "MSX", - "year": 1983, - "manufacturer": "Microsoft" - } +{ + "platform": { + "category": "Computer", + "name": "MSX", + "year": 1983, + "manufacturer": "Microsoft" + } } \ No newline at end of file diff --git a/platform/pocket/audio/audio_mixer.sv b/platform/pocket/audio/audio_mixer.sv index 707e068..e68ab95 100644 --- a/platform/pocket/audio/audio_mixer.sv +++ b/platform/pocket/audio/audio_mixer.sv @@ -1,157 +1,157 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket Audio Mixer -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module audio_mixer - #( - parameter DW = 16, - parameter STEREO = 1 - ) ( - // Clocks and Reset - input logic clk_74b, //! Clock 74.25Mhz - input logic reset, //! Reset - // Controls - input logic [3:0] afilter_sw, //! Predefined Audio Filter Switch - input logic [3:0] vol_att, //! Volume ([0] Max | [7] Min) - input logic [1:0] mix, //! [0] No Mix | [1] 25% | [2] 50% | [3] 100% (mono) - input logic pause_core, //! Mute Audio - // Audio From Core - input logic is_signed, //! Signed Audio - input logic [DW-1:0] core_l, //! Left Channel Audio from Core - input logic [DW-1:0] core_r, //! Right Channel Audio from Core - // Pocket I2S - output logic audio_mclk, //! Serial Master Clock - output logic audio_lrck, //! Left/Right clock - output logic audio_dac //! Serialized data - ); - - //! ------------------------------------------------------------------------ - //! Audio Clocks - //! MCLK: 12.288MHz (256*Fs, where Fs = 48000) - //! SCLK: 3.072mhz (MCLK/4) - //! ------------------------------------------------------------------------ - wire audio_sclk; - - mf_audio_pll audio_pll - ( - .refclk ( clk_74b ), - .rst ( 0 ), - .outclk_0 ( audio_mclk ), - .outclk_1 ( audio_sclk ) - ); - - //! ------------------------------------------------------------------------ - //! Pad core_l/core_r with zeros to maintain a consistent size of 16 bits - //! ------------------------------------------------------------------------ - logic [15:0] core_al, core_ar; - - always_comb begin - core_al = DW == 16 ? core_l : {core_l, {16-DW{1'b0}}}; - core_ar = STEREO ? DW == 16 ? core_r : {core_r, {16-DW{1'b0}}} : core_al; - end - - //! ------------------------------------------------------------------------ - //! Low Pass Filter - //! ------------------------------------------------------------------------ - reg [31:0] aflt_rate = 32'd7056000; // Sampling Frequency - reg [39:0] acx = 40'd4258969; // Base gain - reg [7:0] acx0 = 8'd3; // gain scale for X0 - reg [7:0] acx1 = 8'd3; // gain scale for X1 - reg [7:0] acx2 = 8'd1; // gain scale for X2 - reg [23:0] acy0 = -24'd6216759; // gain scale for Y0 - reg [23:0] acy1 = 24'd6143386; // gain scale for Y1 - reg [23:0] acy2 = -24'd2023767; // gain scale for Y2 - - // logic [31:0] aflt_rate; - // logic [39:0] acx; - // logic [7:0] acx0, acx1, acx2; - // logic [23:0] acy0, acy1, acy2; - - // arcade_filters arcade_filters - // ( - // .clk ( audio_mclk ), - // .afilter_sw ( afilter_sw ), - // .aflt_rate ( aflt_rate ), - // .acx ( acx ), - // .acx0 ( acx0 ), - // .acx1 ( acx1 ), - // .acx2 ( acx2 ), - // .acy0 ( acy0 ), - // .acy1 ( acy1 ), - // .acy2 ( acy2 ) - // ); - - //! ------------------------------------------------------------------------ - //! Audio Filters - //! ------------------------------------------------------------------------ - logic [15:0] audio_l, audio_r; - - audio_filters audio_filters - ( - .clk ( audio_mclk ), - .reset ( reset ), - // Controls - .att ( {pause_core, vol_att} ), - .mix ( mix ), - // Audio Filter - .flt_rate ( aflt_rate ), - .cx ( acx ), - .cx0 ( acx0 ), - .cx1 ( acx1 ), - .cx2 ( acx2 ), - .cy0 ( acy0 ), - .cy1 ( acy1 ), - .cy2 ( acy2 ), - // Audio from Core - .is_signed ( is_signed ), - .core_l ( core_al ), - .core_r ( core_ar ), - // Filtered Audio Output - .audio_l ( audio_l ), - .audio_r ( audio_r ) - ); - - //! ------------------------------------------------------------------------ - //! Pocket I2S Output - //! ------------------------------------------------------------------------ - pocket_i2s pocket_i2s - ( - // Serial Clock - .audio_sclk ( audio_sclk ), // [i] - // Audio Input - .audio_l ( audio_l ), // [i] - .audio_r ( audio_r ), // [i] - // Pocket I2S Interface - .audio_dac ( audio_dac ), // [o] - .audio_lrck ( audio_lrck ) // [o] - ); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket Audio Mixer +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module audio_mixer + #( + parameter DW = 16, + parameter STEREO = 1 + ) ( + // Clocks and Reset + input logic clk_74b, //! Clock 74.25Mhz + input logic reset, //! Reset + // Controls + input logic [3:0] afilter_sw, //! Predefined Audio Filter Switch + input logic [3:0] vol_att, //! Volume ([0] Max | [7] Min) + input logic [1:0] mix, //! [0] No Mix | [1] 25% | [2] 50% | [3] 100% (mono) + input logic pause_core, //! Mute Audio + // Audio From Core + input logic is_signed, //! Signed Audio + input logic [DW-1:0] core_l, //! Left Channel Audio from Core + input logic [DW-1:0] core_r, //! Right Channel Audio from Core + // Pocket I2S + output logic audio_mclk, //! Serial Master Clock + output logic audio_lrck, //! Left/Right clock + output logic audio_dac //! Serialized data + ); + + //! ------------------------------------------------------------------------ + //! Audio Clocks + //! MCLK: 12.288MHz (256*Fs, where Fs = 48000) + //! SCLK: 3.072mhz (MCLK/4) + //! ------------------------------------------------------------------------ + wire audio_sclk; + + mf_audio_pll audio_pll + ( + .refclk ( clk_74b ), + .rst ( 0 ), + .outclk_0 ( audio_mclk ), + .outclk_1 ( audio_sclk ) + ); + + //! ------------------------------------------------------------------------ + //! Pad core_l/core_r with zeros to maintain a consistent size of 16 bits + //! ------------------------------------------------------------------------ + logic [15:0] core_al, core_ar; + + always_comb begin + core_al = DW == 16 ? core_l : {core_l, {16-DW{1'b0}}}; + core_ar = STEREO ? DW == 16 ? core_r : {core_r, {16-DW{1'b0}}} : core_al; + end + + //! ------------------------------------------------------------------------ + //! Low Pass Filter + //! ------------------------------------------------------------------------ + reg [31:0] aflt_rate = 32'd7056000; // Sampling Frequency + reg [39:0] acx = 40'd4258969; // Base gain + reg [7:0] acx0 = 8'd3; // gain scale for X0 + reg [7:0] acx1 = 8'd3; // gain scale for X1 + reg [7:0] acx2 = 8'd1; // gain scale for X2 + reg [23:0] acy0 = -24'd6216759; // gain scale for Y0 + reg [23:0] acy1 = 24'd6143386; // gain scale for Y1 + reg [23:0] acy2 = -24'd2023767; // gain scale for Y2 + + // logic [31:0] aflt_rate; + // logic [39:0] acx; + // logic [7:0] acx0, acx1, acx2; + // logic [23:0] acy0, acy1, acy2; + + // arcade_filters arcade_filters + // ( + // .clk ( audio_mclk ), + // .afilter_sw ( afilter_sw ), + // .aflt_rate ( aflt_rate ), + // .acx ( acx ), + // .acx0 ( acx0 ), + // .acx1 ( acx1 ), + // .acx2 ( acx2 ), + // .acy0 ( acy0 ), + // .acy1 ( acy1 ), + // .acy2 ( acy2 ) + // ); + + //! ------------------------------------------------------------------------ + //! Audio Filters + //! ------------------------------------------------------------------------ + logic [15:0] audio_l, audio_r; + + audio_filters audio_filters + ( + .clk ( audio_mclk ), + .reset ( reset ), + // Controls + .att ( {pause_core, vol_att} ), + .mix ( mix ), + // Audio Filter + .flt_rate ( aflt_rate ), + .cx ( acx ), + .cx0 ( acx0 ), + .cx1 ( acx1 ), + .cx2 ( acx2 ), + .cy0 ( acy0 ), + .cy1 ( acy1 ), + .cy2 ( acy2 ), + // Audio from Core + .is_signed ( is_signed ), + .core_l ( core_al ), + .core_r ( core_ar ), + // Filtered Audio Output + .audio_l ( audio_l ), + .audio_r ( audio_r ) + ); + + //! ------------------------------------------------------------------------ + //! Pocket I2S Output + //! ------------------------------------------------------------------------ + pocket_i2s pocket_i2s + ( + // Serial Clock + .audio_sclk ( audio_sclk ), // [i] + // Audio Input + .audio_l ( audio_l ), // [i] + .audio_r ( audio_r ), // [i] + // Pocket I2S Interface + .audio_dac ( audio_dac ), // [o] + .audio_lrck ( audio_lrck ) // [o] + ); + +endmodule diff --git a/platform/pocket/audio/filters/arcade_filters.sv b/platform/pocket/audio/filters/arcade_filters.sv index aaa5a52..88f80a3 100644 --- a/platform/pocket/audio/filters/arcade_filters.sv +++ b/platform/pocket/audio/filters/arcade_filters.sv @@ -1,141 +1,141 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket Arcade Audio Filters -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module arcade_filters - ( - // Clock - input logic clk, - // Filter Switch - input logic [3:0] afilter_sw, - // Filter Config - output logic [31:0] flt_rate, // Sampling Frequency - output logic [39:0] cx, // Base gain - output logic [7:0] cx0, cx1, cx2, // gain scale for X0, X1, X2 - output logic [23:0] cy0, cy1, cy2 // gain scale for Y0, Y1, Y2 - ); - - always_ff @(posedge clk) begin - case(afilter_sw) - 1: begin // Arcade LPF 2khz 1st - flt_rate <= 32'd7056000; - cx <= 40'd425898; - cx0 <= 8'd3; - cx1 <= 8'd3; - cx2 <= 8'd1; - cy0 <= -24'd6234907; - cy1 <= 24'd6179109; - cy2 <= -24'd2041353; - end - 2: begin // Arcade LPF 2khz 2nd - flt_rate <= 32'd7056000; - cx <= 40'd2420697; - cx0 <= 8'd2; - cx1 <= 8'd1; - cx2 <= 8'd0; - cy0 <= -24'd4189022; - cy1 <= 24'd2091876; - cy2 <= 24'd0; - end - 3: begin // Arcade LPF 4khz 1st - flt_rate <= 32'd7056000; - cx <= 40'd851040; - cx0 <= 8'd3; - cx1 <= 8'd3; - cx2 <= 8'd1; - cy0 <= -24'd6231182; - cy1 <= 24'd6171753; - cy2 <= -24'd2037720; - end - 4: begin // Arcade LPF 4khz 2nd - flt_rate <= 32'd7056000; - cx <= 40'd9670619; - cx0 <= 8'd2; - cx1 <= 8'd1; - cx2 <= 8'd0; - cy0 <= -24'd4183740; - cy1 <= 24'd2086614; - cy2 <= 24'd0; - end - 5: begin // Arcade LPF 6khz 1st - flt_rate <= 32'd7056000; - cx <= 40'd1275428; - cx0 <= 8'd3; - cx1 <= 8'd3; - cx2 <= 8'd1; - cy0 <= -24'd6227464; - cy1 <= 24'd6164410; - cy2 <= -24'd2034094; - end - 6: begin // Arcade LPF 6khz 2nd - flt_rate <= 32'd7056000; - cx <= 40'd21731566; - cx0 <= 8'd2; - cx1 <= 8'd1; - cx2 <= 8'd0; - cy0 <= -24'd4178458; - cy1 <= 24'd2081365; - cy2 <= 24'd0; - end - 7: begin // Arcade LPF 8khz 1st - flt_rate <= 32'd7056000; - cx <= 40'd1699064; - cx0 <= 8'd3; - cx1 <= 8'd3; - cx2 <= 8'd1; - cy0 <= -24'd6223752; - cy1 <= 24'd6157080; - cy2 <= -24'd2030475; - end - 8: begin // Arcade LPF 8khz 2nd - flt_rate <= 32'd7056000; - cx <= 40'd38585417; - cx0 <= 8'd2; - cx1 <= 8'd1; - cx2 <= 8'd0; - cy0 <= -24'd4173176; - cy1 <= 24'd2076130; - cy2 <= 24'd0; - end - default: begin - flt_rate <= 7056000; - cx <= 4258969; - cx0 <= 3; - cx1 <= 3; - cx2 <= 1; - cy0 <= -24'd6216759; - cy1 <= 24'd6143386; - cy2 <= -24'd2023767; - end - endcase - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket Arcade Audio Filters +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module arcade_filters + ( + // Clock + input logic clk, + // Filter Switch + input logic [3:0] afilter_sw, + // Filter Config + output logic [31:0] flt_rate, // Sampling Frequency + output logic [39:0] cx, // Base gain + output logic [7:0] cx0, cx1, cx2, // gain scale for X0, X1, X2 + output logic [23:0] cy0, cy1, cy2 // gain scale for Y0, Y1, Y2 + ); + + always_ff @(posedge clk) begin + case(afilter_sw) + 1: begin // Arcade LPF 2khz 1st + flt_rate <= 32'd7056000; + cx <= 40'd425898; + cx0 <= 8'd3; + cx1 <= 8'd3; + cx2 <= 8'd1; + cy0 <= -24'd6234907; + cy1 <= 24'd6179109; + cy2 <= -24'd2041353; + end + 2: begin // Arcade LPF 2khz 2nd + flt_rate <= 32'd7056000; + cx <= 40'd2420697; + cx0 <= 8'd2; + cx1 <= 8'd1; + cx2 <= 8'd0; + cy0 <= -24'd4189022; + cy1 <= 24'd2091876; + cy2 <= 24'd0; + end + 3: begin // Arcade LPF 4khz 1st + flt_rate <= 32'd7056000; + cx <= 40'd851040; + cx0 <= 8'd3; + cx1 <= 8'd3; + cx2 <= 8'd1; + cy0 <= -24'd6231182; + cy1 <= 24'd6171753; + cy2 <= -24'd2037720; + end + 4: begin // Arcade LPF 4khz 2nd + flt_rate <= 32'd7056000; + cx <= 40'd9670619; + cx0 <= 8'd2; + cx1 <= 8'd1; + cx2 <= 8'd0; + cy0 <= -24'd4183740; + cy1 <= 24'd2086614; + cy2 <= 24'd0; + end + 5: begin // Arcade LPF 6khz 1st + flt_rate <= 32'd7056000; + cx <= 40'd1275428; + cx0 <= 8'd3; + cx1 <= 8'd3; + cx2 <= 8'd1; + cy0 <= -24'd6227464; + cy1 <= 24'd6164410; + cy2 <= -24'd2034094; + end + 6: begin // Arcade LPF 6khz 2nd + flt_rate <= 32'd7056000; + cx <= 40'd21731566; + cx0 <= 8'd2; + cx1 <= 8'd1; + cx2 <= 8'd0; + cy0 <= -24'd4178458; + cy1 <= 24'd2081365; + cy2 <= 24'd0; + end + 7: begin // Arcade LPF 8khz 1st + flt_rate <= 32'd7056000; + cx <= 40'd1699064; + cx0 <= 8'd3; + cx1 <= 8'd3; + cx2 <= 8'd1; + cy0 <= -24'd6223752; + cy1 <= 24'd6157080; + cy2 <= -24'd2030475; + end + 8: begin // Arcade LPF 8khz 2nd + flt_rate <= 32'd7056000; + cx <= 40'd38585417; + cx0 <= 8'd2; + cx1 <= 8'd1; + cx2 <= 8'd0; + cy0 <= -24'd4173176; + cy1 <= 24'd2076130; + cy2 <= 24'd0; + end + default: begin + flt_rate <= 7056000; + cx <= 4258969; + cx0 <= 3; + cx1 <= 3; + cx2 <= 1; + cy0 <= -24'd6216759; + cy1 <= 24'd6143386; + cy2 <= -24'd2023767; + end + endcase + end + +endmodule diff --git a/platform/pocket/audio/filters/audio_filters.sv b/platform/pocket/audio/filters/audio_filters.sv index fcc5b0b..18f7375 100644 --- a/platform/pocket/audio/filters/audio_filters.sv +++ b/platform/pocket/audio/filters/audio_filters.sv @@ -1,204 +1,204 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Audio Filters -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2020, Alexey Melnikov -// -// 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 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 . -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module audio_filters - #( - parameter CLK_RATE = 12288000 - ) ( - input wire clk, - input wire reset, - - input wire [31:0] flt_rate, - input wire [39:0] cx, - input wire [7:0] cx0, - input wire [7:0] cx1, - input wire [7:0] cx2, - input wire [23:0] cy0, - input wire [23:0] cy1, - input wire [23:0] cy2, - input wire [4:0] att, - - input wire is_signed, - input wire [1:0] mix, - - input wire [15:0] core_l, - input wire [15:0] core_r, - - // Audio Output - output wire [15:0] audio_l, - output wire [15:0] audio_r - ); - - reg sample_rate = 0; //0 - 48KHz, 1 - 96KHz - - reg sample_ce; - always @(posedge clk) begin - reg [8:0] div = 0; - reg [1:0] add = 0; - - div <= div + add; - if(!div) begin - div <= 2'd1 << sample_rate; - add <= 2'd1 << sample_rate; - end - - sample_ce <= !div; - end - - reg flt_ce; - always @(posedge clk) begin - reg [31:0] cnt = 0; - - flt_ce = 0; - cnt = cnt + {flt_rate[30:0],1'b0}; - if(cnt >= CLK_RATE) begin - cnt = cnt - CLK_RATE; - flt_ce = 1; - end - end - - reg [15:0] cl,cr; - always @(posedge clk) begin - reg [15:0] cl1, cl2; - reg [15:0] cr1, cr2; - - cl1 <= core_l; - cl2 <= cl1; - if(cl2 == cl1) - cl <= cl2; - - cr1 <= core_r; - cr2 <= cr1; - if(cr2 == cr1) - cr <= cr2; - end - - reg a_en1 = 0, a_en2 = 0; - always @(posedge clk, posedge reset) begin - reg [1:0] dly1; - reg [14:0] dly2; - - if(reset) begin - dly1 <= 0; - dly2 <= 0; - a_en1 <= 0; - a_en2 <= 0; - end - else begin - if(flt_ce) begin - if(~&dly1) - dly1 <= dly1 + 1'd1; - else - a_en1 <= 1; - end - - if(sample_ce) begin - if(!dly2[13+sample_rate]) - dly2 <= dly2 + 1'd1; - else - a_en2 <= 1; - end - end - end - - wire [15:0] acl, acr; - iir_filter #(.use_params(0)) iir_filter - ( - .clk ( clk ), - .reset ( reset ), - - .ce ( flt_ce & a_en1 ), - .sample_ce ( sample_ce ), - - .cx ( cx ), - .cx0 ( cx0 ), - .cx1 ( cx1 ), - .cx2 ( cx2 ), - .cy0 ( cy0 ), - .cy1 ( cy1 ), - .cy2 ( cy2 ), - - .input_l ( {~is_signed ^ cl[15], cl[14:0]} ), - .input_r ( {~is_signed ^ cr[15], cr[14:0]} ), - .output_l ( acl ), - .output_r ( acr ) - ); - - wire [15:0] adl; - dc_blocker dcb_l - ( - .clk ( clk ), - .ce ( sample_ce ), - .sample_rate ( sample_rate ), - .mute ( ~a_en2 ), - .din ( acl ), - .dout ( adl ) - ); - - wire [15:0] adr; - dc_blocker dcb_r - ( - .clk ( clk ), - .ce ( sample_ce ), - .sample_rate ( sample_rate ), - .mute ( ~a_en2 ), - .din ( acr ), - .dout ( adr ) - ); - - wire [15:0] audio_l_pre; - audio_mix audmix_l - ( - .clk ( clk ), - .ce ( sample_ce ), - .att ( att ), - .mix ( mix ), - - .core_audio ( adl ), - .pre_in ( audio_r_pre ), - - .pre_out ( audio_l_pre ), - .out ( audio_l ) - ); - - wire [15:0] audio_r_pre; - audio_mix audmix_r - ( - .clk ( clk ), - .ce ( sample_ce ), - .att ( att ), - .mix ( mix ), - - .core_audio ( adr ), - .pre_in ( audio_l_pre ), - - .pre_out ( audio_r_pre ), - .out ( audio_r ) - ); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Audio Filters +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2020, Alexey Melnikov +// +// 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 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 . +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module audio_filters + #( + parameter CLK_RATE = 12288000 + ) ( + input wire clk, + input wire reset, + + input wire [31:0] flt_rate, + input wire [39:0] cx, + input wire [7:0] cx0, + input wire [7:0] cx1, + input wire [7:0] cx2, + input wire [23:0] cy0, + input wire [23:0] cy1, + input wire [23:0] cy2, + input wire [4:0] att, + + input wire is_signed, + input wire [1:0] mix, + + input wire [15:0] core_l, + input wire [15:0] core_r, + + // Audio Output + output wire [15:0] audio_l, + output wire [15:0] audio_r + ); + + reg sample_rate = 0; //0 - 48KHz, 1 - 96KHz + + reg sample_ce; + always @(posedge clk) begin + reg [8:0] div = 0; + reg [1:0] add = 0; + + div <= div + add; + if(!div) begin + div <= 2'd1 << sample_rate; + add <= 2'd1 << sample_rate; + end + + sample_ce <= !div; + end + + reg flt_ce; + always @(posedge clk) begin + reg [31:0] cnt = 0; + + flt_ce = 0; + cnt = cnt + {flt_rate[30:0],1'b0}; + if(cnt >= CLK_RATE) begin + cnt = cnt - CLK_RATE; + flt_ce = 1; + end + end + + reg [15:0] cl,cr; + always @(posedge clk) begin + reg [15:0] cl1, cl2; + reg [15:0] cr1, cr2; + + cl1 <= core_l; + cl2 <= cl1; + if(cl2 == cl1) + cl <= cl2; + + cr1 <= core_r; + cr2 <= cr1; + if(cr2 == cr1) + cr <= cr2; + end + + reg a_en1 = 0, a_en2 = 0; + always @(posedge clk, posedge reset) begin + reg [1:0] dly1; + reg [14:0] dly2; + + if(reset) begin + dly1 <= 0; + dly2 <= 0; + a_en1 <= 0; + a_en2 <= 0; + end + else begin + if(flt_ce) begin + if(~&dly1) + dly1 <= dly1 + 1'd1; + else + a_en1 <= 1; + end + + if(sample_ce) begin + if(!dly2[13+sample_rate]) + dly2 <= dly2 + 1'd1; + else + a_en2 <= 1; + end + end + end + + wire [15:0] acl, acr; + iir_filter #(.use_params(0)) iir_filter + ( + .clk ( clk ), + .reset ( reset ), + + .ce ( flt_ce & a_en1 ), + .sample_ce ( sample_ce ), + + .cx ( cx ), + .cx0 ( cx0 ), + .cx1 ( cx1 ), + .cx2 ( cx2 ), + .cy0 ( cy0 ), + .cy1 ( cy1 ), + .cy2 ( cy2 ), + + .input_l ( {~is_signed ^ cl[15], cl[14:0]} ), + .input_r ( {~is_signed ^ cr[15], cr[14:0]} ), + .output_l ( acl ), + .output_r ( acr ) + ); + + wire [15:0] adl; + dc_blocker dcb_l + ( + .clk ( clk ), + .ce ( sample_ce ), + .sample_rate ( sample_rate ), + .mute ( ~a_en2 ), + .din ( acl ), + .dout ( adl ) + ); + + wire [15:0] adr; + dc_blocker dcb_r + ( + .clk ( clk ), + .ce ( sample_ce ), + .sample_rate ( sample_rate ), + .mute ( ~a_en2 ), + .din ( acr ), + .dout ( adr ) + ); + + wire [15:0] audio_l_pre; + audio_mix audmix_l + ( + .clk ( clk ), + .ce ( sample_ce ), + .att ( att ), + .mix ( mix ), + + .core_audio ( adl ), + .pre_in ( audio_r_pre ), + + .pre_out ( audio_l_pre ), + .out ( audio_l ) + ); + + wire [15:0] audio_r_pre; + audio_mix audmix_r + ( + .clk ( clk ), + .ce ( sample_ce ), + .att ( att ), + .mix ( mix ), + + .core_audio ( adr ), + .pre_in ( audio_l_pre ), + + .pre_out ( audio_r_pre ), + .out ( audio_r ) + ); + +endmodule diff --git a/platform/pocket/audio/filters/audio_mix.sv b/platform/pocket/audio/filters/audio_mix.sv index 6b70b7d..d7898cf 100644 --- a/platform/pocket/audio/filters/audio_mix.sv +++ b/platform/pocket/audio/filters/audio_mix.sv @@ -1,67 +1,67 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Audio Mix -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2020, Alexey Melnikov -// -// 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 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 . -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module audio_mix - ( - input wire clk, // system clock - input wire ce, // clock enable signal - - input wire [4:0] att, // attenuation value - input wire [1:0] mix, // mixing value - - input wire [15:0] core_audio, // audio input from core - input wire [15:0] pre_in, // audio input from preamp - - output reg [15:0] pre_out = 0, // preamp output - output reg [15:0] out = 0 // final mixed audio output - ); - - reg signed [16:0] a1, a2, a3; // signed registers for audio processing - - always @(posedge clk) begin - if (ce) begin - a1 <= {core_audio[15],core_audio}; // extend core_audio to 17 bits and store in a1 - pre_out <= a1[16:1]; // store the upper 16 bits of a1 in pre_out - - // select mixing options - case(mix) - 0: begin a2 <= a1; end // mix core_audio - 1: begin a2 <= $signed(a1) - $signed(a1[16:3]) + $signed(pre_in[15:2]); end // mix core_audio, and pre_in with attenuation - 2: begin a2 <= $signed(a1) - $signed(a1[16:2]) + $signed(pre_in[15:1]); end // mix core_audio, and pre_in with greater attenuation - 3: begin a2 <= {a1[16],a1[16:1]} + {pre_in[15],pre_in}; end // mix core_audio, and pre_in with clipping - endcase - - // if the highest bit of att is set, set a3 to 0 (Mute) else shift a2 right by att and store in a3 - a3 <= (att[4]) ? 0 : a2 >>> att[3:0]; - - // Clamping - out <= ^a3[16:15] ? {a3[16],{15{a3[15]}}} : a3[15:0]; // clamp the upper 16 bits of a3 and store in out - end - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Audio Mix +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2020, Alexey Melnikov +// +// 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 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 . +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module audio_mix + ( + input wire clk, // system clock + input wire ce, // clock enable signal + + input wire [4:0] att, // attenuation value + input wire [1:0] mix, // mixing value + + input wire [15:0] core_audio, // audio input from core + input wire [15:0] pre_in, // audio input from preamp + + output reg [15:0] pre_out = 0, // preamp output + output reg [15:0] out = 0 // final mixed audio output + ); + + reg signed [16:0] a1, a2, a3; // signed registers for audio processing + + always @(posedge clk) begin + if (ce) begin + a1 <= {core_audio[15],core_audio}; // extend core_audio to 17 bits and store in a1 + pre_out <= a1[16:1]; // store the upper 16 bits of a1 in pre_out + + // select mixing options + case(mix) + 0: begin a2 <= a1; end // mix core_audio + 1: begin a2 <= $signed(a1) - $signed(a1[16:3]) + $signed(pre_in[15:2]); end // mix core_audio, and pre_in with attenuation + 2: begin a2 <= $signed(a1) - $signed(a1[16:2]) + $signed(pre_in[15:1]); end // mix core_audio, and pre_in with greater attenuation + 3: begin a2 <= {a1[16],a1[16:1]} + {pre_in[15],pre_in}; end // mix core_audio, and pre_in with clipping + endcase + + // if the highest bit of att is set, set a3 to 0 (Mute) else shift a2 right by att and store in a3 + a3 <= (att[4]) ? 0 : a2 >>> att[3:0]; + + // Clamping + out <= ^a3[16:15] ? {a3[16],{15{a3[15]}}} : a3[15:0]; // clamp the upper 16 bits of a3 and store in out + end + end + +endmodule diff --git a/platform/pocket/audio/filters/dc_blocker.sv b/platform/pocket/audio/filters/dc_blocker.sv index 30cc92d..76821be 100644 --- a/platform/pocket/audio/filters/dc_blocker.sv +++ b/platform/pocket/audio/filters/dc_blocker.sv @@ -1,71 +1,71 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// DC blocker filter using a simplified IIR structure. -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2020, Alexey Melnikov -// -// 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 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 . -// -//------------------------------------------------------------------------------ -// -// It utilizes feedback to achieve filtering, operating on a delayed version of -// the input signal (x0), a delayed version of the output signal (y1), and the -// current input and output signals (x1 and y0, respectively). -// The filter coefficients are determined by the sample rate of the input signal. -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module dc_blocker - ( - input logic clk, // Input clock signal - input logic ce, // Control enable signal - input logic mute, // Mute output signal - - input logic sample_rate, // Sample rate input signal - input logic [15:0] din, // Input data signal - output logic [15:0] dout // Output data signal - ); - - // Pad the input signal with zeros - wire [39:0] x = {din[15], din, 23'd0}; - // Subtract previous input sample from current input sample - wire [39:0] x0 = x - (sample_rate ? {{11{x[39]}}, x[39:11]} : {{10{x[39]}}, x[39:10]}); - // Subtract previous output sample from current output sample - wire [39:0] y1 = y - (sample_rate ? {{10{y[39]}}, y[39:10]} : {{09{y[39]}}, y[39:09]}); - // Subtract difference between previous input and output sample from current input sample - wire [39:0] y0 = x0 - x1 + y1; - - // Registers to store previous input and output samples - reg [39:0] x1, y; - - always @(posedge clk) begin - if(ce) begin - // Update the previous input sample - x1 <= x0; - // Update the previous output sample - y <= ^y0[39:38] ? {{2{y0[39]}},{38{y0[38]}}} : y0; - end - end - - // Output the filtered sample, or zero if the mute signal is high - assign dout = mute ? 16'd0 : y[38:23]; - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// DC blocker filter using a simplified IIR structure. +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2020, Alexey Melnikov +// +// 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 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 . +// +//------------------------------------------------------------------------------ +// +// It utilizes feedback to achieve filtering, operating on a delayed version of +// the input signal (x0), a delayed version of the output signal (y1), and the +// current input and output signals (x1 and y0, respectively). +// The filter coefficients are determined by the sample rate of the input signal. +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module dc_blocker + ( + input logic clk, // Input clock signal + input logic ce, // Control enable signal + input logic mute, // Mute output signal + + input logic sample_rate, // Sample rate input signal + input logic [15:0] din, // Input data signal + output logic [15:0] dout // Output data signal + ); + + // Pad the input signal with zeros + wire [39:0] x = {din[15], din, 23'd0}; + // Subtract previous input sample from current input sample + wire [39:0] x0 = x - (sample_rate ? {{11{x[39]}}, x[39:11]} : {{10{x[39]}}, x[39:10]}); + // Subtract previous output sample from current output sample + wire [39:0] y1 = y - (sample_rate ? {{10{y[39]}}, y[39:10]} : {{09{y[39]}}, y[39:09]}); + // Subtract difference between previous input and output sample from current input sample + wire [39:0] y0 = x0 - x1 + y1; + + // Registers to store previous input and output samples + reg [39:0] x1, y; + + always @(posedge clk) begin + if(ce) begin + // Update the previous input sample + x1 <= x0; + // Update the previous output sample + y <= ^y0[39:38] ? {{2{y0[39]}},{38{y0[38]}}} : y0; + end + end + + // Output the filtered sample, or zero if the mute signal is high + assign dout = mute ? 16'd0 : y[38:23]; + +endmodule diff --git a/platform/pocket/audio/filters/filter_loader.sv b/platform/pocket/audio/filters/filter_loader.sv index 9e22768..00c4479 100644 --- a/platform/pocket/audio/filters/filter_loader.sv +++ b/platform/pocket/audio/filters/filter_loader.sv @@ -1,111 +1,111 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket Audio Filter Loader -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module filter_loader - ( - // Clocks and Reset - input logic clk_sys, - input logic afilter_wr, - input logic [7:0] afilter_addr, - input logic [7:0] afilter_din, - // Audio From Core - output logic [31:0] flt_rate, // Sampling Frequency - output logic [39:0] cx, // Base gain - output logic [7:0] cx0, cx1, cx2, // gain scale for X0, X1, X2 - output logic [23:0] cy0, cy1, cy2 // gain scale for Y0, Y1, Y2 - ); - - always_comb begin - flt_rate = r_flt_rate; - cx = r_cx; - cx0 = r_cx0; - cx1 = r_cx1; - cx2 = r_cx2; - cy0 = r_cy0; - cy1 = r_cy1; - cy2 = r_cy2; - end - - reg [31:0] r_flt_rate = 7056000; // Sampling Frequency - reg [39:0] r_cx = 4258969; // Base gain - reg [7:0] r_cx0 = 3; // gain scale for X0 - reg [7:0] r_cx1 = 3; // gain scale for X1 - reg [7:0] r_cx2 = 1; // gain scale for X2 - reg [23:0] r_cy0 = -24'd6216759; // gain scale for Y0 - reg [23:0] r_cy1 = 24'd6143386; // gain scale for Y1 - reg [23:0] r_cy2 = -24'd2023767; // gain scale for Y2 - - always_ff @(posedge clk_sys) begin - if (afilter_wr) begin - case(afilter_addr) - //! Sampling Frequency - 8'h00: r_flt_rate[7:0] <= afilter_din; - 8'h01: r_flt_rate[15:8] <= afilter_din; - 8'h02: r_flt_rate[23:16] <= afilter_din; - 8'h03: r_flt_rate[31:24] <= afilter_din; - //! Base gain - 8'h04: r_cx[7:0] <= afilter_din; - 8'h05: r_cx[15:8] <= afilter_din; - 8'h06: r_cx[23:16] <= afilter_din; - 8'h07: r_cx[31:24] <= afilter_din; - 8'h08: r_cx[39:32] <= afilter_din; - // 8'h09: _SKIP_ - // 8'h0a: _SKIP_ - // 8'h0b: _SKIP_ - //! gain scale for X0 - 8'h0c: r_cx0 <= afilter_din; - //! gain scale for X1 - 8'h0d: r_cx1 <= afilter_din; - //! gain scale for X2 - 8'h0e: r_cx2 <= afilter_din; - //! gain scale for Y0 - 8'h0f: r_cy0[7:0] <= afilter_din; - 8'h10: r_cy0[15:8] <= afilter_din; - 8'h11: r_cy0[23:16] <= afilter_din; - // 8'h12: _SKIP_ - //! gain scale for Y1 - 8'h13: r_cy1[7:0] <= afilter_din; - 8'h14: r_cy1[15:8] <= afilter_din; - 8'h15: r_cy1[23:16] <= afilter_din; - // 8'h16: _SKIP_ - //! gain scale for Y2 - 8'h17: r_cy2[7:0] <= afilter_din; - 8'h18: r_cy2[15:8] <= afilter_din; - 8'h19: r_cy2[23:16] <= afilter_din; - // 8'h1a: _SKIP_ - // 8'h1b: _SKIP_ - default:; - endcase - end - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket Audio Filter Loader +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module filter_loader + ( + // Clocks and Reset + input logic clk_sys, + input logic afilter_wr, + input logic [7:0] afilter_addr, + input logic [7:0] afilter_din, + // Audio From Core + output logic [31:0] flt_rate, // Sampling Frequency + output logic [39:0] cx, // Base gain + output logic [7:0] cx0, cx1, cx2, // gain scale for X0, X1, X2 + output logic [23:0] cy0, cy1, cy2 // gain scale for Y0, Y1, Y2 + ); + + always_comb begin + flt_rate = r_flt_rate; + cx = r_cx; + cx0 = r_cx0; + cx1 = r_cx1; + cx2 = r_cx2; + cy0 = r_cy0; + cy1 = r_cy1; + cy2 = r_cy2; + end + + reg [31:0] r_flt_rate = 7056000; // Sampling Frequency + reg [39:0] r_cx = 4258969; // Base gain + reg [7:0] r_cx0 = 3; // gain scale for X0 + reg [7:0] r_cx1 = 3; // gain scale for X1 + reg [7:0] r_cx2 = 1; // gain scale for X2 + reg [23:0] r_cy0 = -24'd6216759; // gain scale for Y0 + reg [23:0] r_cy1 = 24'd6143386; // gain scale for Y1 + reg [23:0] r_cy2 = -24'd2023767; // gain scale for Y2 + + always_ff @(posedge clk_sys) begin + if (afilter_wr) begin + case(afilter_addr) + //! Sampling Frequency + 8'h00: r_flt_rate[7:0] <= afilter_din; + 8'h01: r_flt_rate[15:8] <= afilter_din; + 8'h02: r_flt_rate[23:16] <= afilter_din; + 8'h03: r_flt_rate[31:24] <= afilter_din; + //! Base gain + 8'h04: r_cx[7:0] <= afilter_din; + 8'h05: r_cx[15:8] <= afilter_din; + 8'h06: r_cx[23:16] <= afilter_din; + 8'h07: r_cx[31:24] <= afilter_din; + 8'h08: r_cx[39:32] <= afilter_din; + // 8'h09: _SKIP_ + // 8'h0a: _SKIP_ + // 8'h0b: _SKIP_ + //! gain scale for X0 + 8'h0c: r_cx0 <= afilter_din; + //! gain scale for X1 + 8'h0d: r_cx1 <= afilter_din; + //! gain scale for X2 + 8'h0e: r_cx2 <= afilter_din; + //! gain scale for Y0 + 8'h0f: r_cy0[7:0] <= afilter_din; + 8'h10: r_cy0[15:8] <= afilter_din; + 8'h11: r_cy0[23:16] <= afilter_din; + // 8'h12: _SKIP_ + //! gain scale for Y1 + 8'h13: r_cy1[7:0] <= afilter_din; + 8'h14: r_cy1[15:8] <= afilter_din; + 8'h15: r_cy1[23:16] <= afilter_din; + // 8'h16: _SKIP_ + //! gain scale for Y2 + 8'h17: r_cy2[7:0] <= afilter_din; + 8'h18: r_cy2[15:8] <= afilter_din; + 8'h19: r_cy2[23:16] <= afilter_din; + // 8'h1a: _SKIP_ + // 8'h1b: _SKIP_ + default:; + endcase + end + end + +endmodule diff --git a/platform/pocket/audio/filters/filters_rom.sv b/platform/pocket/audio/filters/filters_rom.sv index e793ee2..0baa7b8 100644 --- a/platform/pocket/audio/filters/filters_rom.sv +++ b/platform/pocket/audio/filters/filters_rom.sv @@ -1,173 +1,173 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket Audio Filters ROM -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module filters_rom - ( - // Clock - input logic clk, - // Filter Switch - input logic [3:0] afilter_sw, - // Filter Config - output logic [31:0] aflt_rate, // Sampling Frequency - output logic [39:0] acx, // Base gain - output logic [7:0] acx0, acx1, acx2, // gain scale for X0, X1, X2 - output logic [23:0] acy0, acy1, acy2 // gain scale for Y0, Y1, Y2 - ); - - (* ramstyle = "no_rw_check" *) reg [31:0] flt_rate[9]; - (* ramstyle = "no_rw_check" *) reg [39:0] cx[9]; - (* ramstyle = "no_rw_check" *) reg [7:0] cx0[9]; - (* ramstyle = "no_rw_check" *) reg [7:0] cx1[9]; - (* ramstyle = "no_rw_check" *) reg [7:0] cx2[9]; - (* ramstyle = "no_rw_check" *) reg [23:0] cy0[9]; - (* ramstyle = "no_rw_check" *) reg [23:0] cy1[9]; - (* ramstyle = "no_rw_check" *) reg [23:0] cy2[9]; - - always @(posedge clk) begin - aflt_rate <= flt_rate[afilter_sw]; - acx <= cx[afilter_sw]; - acx0 <= cx0[afilter_sw]; - acx1 <= cx1[afilter_sw]; - acx2 <= cx2[afilter_sw]; - acy0 <= cy0[afilter_sw]; - acy1 <= cy1[afilter_sw]; - acy2 <= cy2[afilter_sw]; - end - //! Assign Outputs --------------------------------------------------------- - - //! Arcade Filters --------------------------------------------------------- - initial begin - // Default - flt_rate[0] = 7056000; - cx[0] = 4258969; - cx0[0] = 3; - cx1[0] = 3; - cx2[0] = 1; - cy0[0] = -24'd6216759; - cy1[0] = 24'd6143386; - cy2[0] = -24'd2023767; - - // Arcade LPF 2khz 1st - flt_rate[1] = 32'd7056000; - cx[1] = 40'd425898; - cx0[1] = 8'd3; - cx1[1] = 8'd3; - cx2[1] = 8'd1; - cy0[1] = -24'd6234907; - cy1[1] = 24'd6179109; - cy2[1] = -24'd2041353; - - // Arcade LPF 2khz 2nd - flt_rate[2] = 32'd7056000; - cx[2] = 40'd2420697; - cx0[2] = 8'd2; - cx1[2] = 8'd1; - cx2[2] = 8'd0; - cy0[2] = -24'd4189022; - cy1[2] = 24'd2091876; - cy2[2] = 24'd0; - - // Arcade LPF 4khz 1st - flt_rate[3] = 32'd7056000; - cx[3] = 40'd851040; - cx0[3] = 8'd3; - cx1[3] = 8'd3; - cx2[3] = 8'd1; - cy0[3] = -24'd6231182; - cy1[3] = 24'd6171753; - cy2[3] = -24'd2037720; - - // Arcade LPF 4khz 2nd - flt_rate[4] = 32'd7056000; - cx[4] = 40'd9670619; - cx0[4] = 8'd2; - cx1[4] = 8'd1; - cx2[4] = 8'd0; - cy0[4] = -24'd4183740; - cy1[4] = 24'd2086614; - cy2[4] = 24'd0; - - // Arcade LPF 6khz 1st - flt_rate[5] = 32'd7056000; - cx[5] = 40'd1275428; - cx0[5] = 8'd3; - cx1[5] = 8'd3; - cx2[5] = 8'd1; - cy0[5] = -24'd6227464; - cy1[5] = 24'd6164410; - cy2[5] = -24'd2034094; - - // Arcade LPF 6khz 2nd - flt_rate[6] = 32'd7056000; - cx[6] = 40'd21731566; - cx0[6] = 8'd2; - cx1[6] = 8'd1; - cx2[6] = 8'd0; - cy0[6] = -24'd4178458; - cy1[6] = 24'd2081365; - cy2[6] = 24'd0; - - // Arcade LPF 8khz 1st - flt_rate[7] = 32'd7056000; - cx[7] = 40'd1699064; - cx0[7] = 8'd3; - cx1[7] = 8'd3; - cx2[7] = 8'd1; - cy0[7] = -24'd6223752; - cy1[7] = 24'd6157080; - cy2[7] = -24'd2030475; - - // Arcade LPF 8khz 2nd - flt_rate[8] = 32'd7056000; - cx[8] = 40'd38585417; - cx0[8] = 8'd2; - cx1[8] = 8'd1; - cx2[8] = 8'd0; - cy0[8] = -24'd4173176; - cy1[8] = 24'd2076130; - cy2[8] = 24'd0; - - end - - // [ 9 ] LPF 10khz 1st + Aa - // [ 10 ] LPF 12khz 1st + Aa - // [ 11 ] LPF 14khz 1st + Aa - // [ 12 ] LPF 16khz 1st + Aa - // [ 13 ] LPF 16khz 3rd Ch 1db - // [ 14 ] LPF 18khz 3rd Ch 1db - // [ 15 ] LPF 20khz 2nd Bw - // [ 16 ] LPF 20khz 3rd Bw - // [ 17 ] LPF 20khz 3rd Ch 1db - - // [ 18 ] SNES Gpm-02 LPF - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket Audio Filters ROM +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module filters_rom + ( + // Clock + input logic clk, + // Filter Switch + input logic [3:0] afilter_sw, + // Filter Config + output logic [31:0] aflt_rate, // Sampling Frequency + output logic [39:0] acx, // Base gain + output logic [7:0] acx0, acx1, acx2, // gain scale for X0, X1, X2 + output logic [23:0] acy0, acy1, acy2 // gain scale for Y0, Y1, Y2 + ); + + (* ramstyle = "no_rw_check" *) reg [31:0] flt_rate[9]; + (* ramstyle = "no_rw_check" *) reg [39:0] cx[9]; + (* ramstyle = "no_rw_check" *) reg [7:0] cx0[9]; + (* ramstyle = "no_rw_check" *) reg [7:0] cx1[9]; + (* ramstyle = "no_rw_check" *) reg [7:0] cx2[9]; + (* ramstyle = "no_rw_check" *) reg [23:0] cy0[9]; + (* ramstyle = "no_rw_check" *) reg [23:0] cy1[9]; + (* ramstyle = "no_rw_check" *) reg [23:0] cy2[9]; + + always @(posedge clk) begin + aflt_rate <= flt_rate[afilter_sw]; + acx <= cx[afilter_sw]; + acx0 <= cx0[afilter_sw]; + acx1 <= cx1[afilter_sw]; + acx2 <= cx2[afilter_sw]; + acy0 <= cy0[afilter_sw]; + acy1 <= cy1[afilter_sw]; + acy2 <= cy2[afilter_sw]; + end + //! Assign Outputs --------------------------------------------------------- + + //! Arcade Filters --------------------------------------------------------- + initial begin + // Default + flt_rate[0] = 7056000; + cx[0] = 4258969; + cx0[0] = 3; + cx1[0] = 3; + cx2[0] = 1; + cy0[0] = -24'd6216759; + cy1[0] = 24'd6143386; + cy2[0] = -24'd2023767; + + // Arcade LPF 2khz 1st + flt_rate[1] = 32'd7056000; + cx[1] = 40'd425898; + cx0[1] = 8'd3; + cx1[1] = 8'd3; + cx2[1] = 8'd1; + cy0[1] = -24'd6234907; + cy1[1] = 24'd6179109; + cy2[1] = -24'd2041353; + + // Arcade LPF 2khz 2nd + flt_rate[2] = 32'd7056000; + cx[2] = 40'd2420697; + cx0[2] = 8'd2; + cx1[2] = 8'd1; + cx2[2] = 8'd0; + cy0[2] = -24'd4189022; + cy1[2] = 24'd2091876; + cy2[2] = 24'd0; + + // Arcade LPF 4khz 1st + flt_rate[3] = 32'd7056000; + cx[3] = 40'd851040; + cx0[3] = 8'd3; + cx1[3] = 8'd3; + cx2[3] = 8'd1; + cy0[3] = -24'd6231182; + cy1[3] = 24'd6171753; + cy2[3] = -24'd2037720; + + // Arcade LPF 4khz 2nd + flt_rate[4] = 32'd7056000; + cx[4] = 40'd9670619; + cx0[4] = 8'd2; + cx1[4] = 8'd1; + cx2[4] = 8'd0; + cy0[4] = -24'd4183740; + cy1[4] = 24'd2086614; + cy2[4] = 24'd0; + + // Arcade LPF 6khz 1st + flt_rate[5] = 32'd7056000; + cx[5] = 40'd1275428; + cx0[5] = 8'd3; + cx1[5] = 8'd3; + cx2[5] = 8'd1; + cy0[5] = -24'd6227464; + cy1[5] = 24'd6164410; + cy2[5] = -24'd2034094; + + // Arcade LPF 6khz 2nd + flt_rate[6] = 32'd7056000; + cx[6] = 40'd21731566; + cx0[6] = 8'd2; + cx1[6] = 8'd1; + cx2[6] = 8'd0; + cy0[6] = -24'd4178458; + cy1[6] = 24'd2081365; + cy2[6] = 24'd0; + + // Arcade LPF 8khz 1st + flt_rate[7] = 32'd7056000; + cx[7] = 40'd1699064; + cx0[7] = 8'd3; + cx1[7] = 8'd3; + cx2[7] = 8'd1; + cy0[7] = -24'd6223752; + cy1[7] = 24'd6157080; + cy2[7] = -24'd2030475; + + // Arcade LPF 8khz 2nd + flt_rate[8] = 32'd7056000; + cx[8] = 40'd38585417; + cx0[8] = 8'd2; + cx1[8] = 8'd1; + cx2[8] = 8'd0; + cy0[8] = -24'd4173176; + cy1[8] = 24'd2076130; + cy2[8] = 24'd0; + + end + + // [ 9 ] LPF 10khz 1st + Aa + // [ 10 ] LPF 12khz 1st + Aa + // [ 11 ] LPF 14khz 1st + Aa + // [ 12 ] LPF 16khz 1st + Aa + // [ 13 ] LPF 16khz 3rd Ch 1db + // [ 14 ] LPF 18khz 3rd Ch 1db + // [ 15 ] LPF 20khz 2nd Bw + // [ 16 ] LPF 20khz 3rd Bw + // [ 17 ] LPF 20khz 3rd Ch 1db + + // [ 18 ] SNES Gpm-02 LPF + +endmodule diff --git a/platform/pocket/audio/filters/iir_filter.sv b/platform/pocket/audio/filters/iir_filter.sv index 81e4b60..0ebe66b 100644 --- a/platform/pocket/audio/filters/iir_filter.sv +++ b/platform/pocket/audio/filters/iir_filter.sv @@ -1,165 +1,165 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// 3-tap IIR filter for 2 channels. -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2020, Alexey Melnikov -// -// 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 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 . -// -//------------------------------------------------------------------------------ -// -// Can be converted to: -// - 2-tap (coeff_x2 = 0, coeff_y2 = 0) -// - 1-tap (coeff_x1,2 = 0, coeff_y1,2 = 0) -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module iir_filter - #( - parameter use_params = 1, // set to 1 to use following parameters, 0 for input port variables. - parameter stereo = 1, // 0 for mono (input_l) - - parameter coeff_x = 0.00000774701983513660, // Base gain value for X. Float. Range: 0.0 ... 0.999(9) - parameter coeff_x0 = 3, // Gain scale factor for X0. Integer. Range -7 ... +7 - parameter coeff_x1 = 3, // Gain scale factor for X1. Integer. Range -7 ... +7 - parameter coeff_x2 = 1, // Gain scale factor for X2. Integer. Range -7 ... +7 - parameter coeff_y0 = -2.96438150626551080000, // Coefficient for Y0. Float. Range -3.999(9) ... 3.999(9) - parameter coeff_y1 = 2.92939452735121100000, // Coefficient for Y1. Float. Range -3.999(9) ... 3.999(9) - parameter coeff_y2 = -0.96500747158831091000 // Coefficient for Y2. Float. Range -3.999(9) ... 3.999(9) - ) ( - input clk, - input reset, - - input ce, // must be double of calculated rate for stereo! - input sample_ce, // desired output sample rate - - input [39:0] cx, - input [7:0] cx0, - input [7:0] cx1, - input [7:0] cx2, - input [23:0] cy0, - input [23:0] cy1, - input [23:0] cy2, - - input [15:0] input_l, input_r, // signed samples - output [15:0] output_l, output_r // signed samples - ); - - localparam [39:0] pcoeff_x = coeff_x * 40'h8000000000; - localparam [31:0] pcoeff_y0 = coeff_y0 * 24'h200000; - localparam [31:0] pcoeff_y1 = coeff_y1 * 24'h200000; - localparam [31:0] pcoeff_y2 = coeff_y2 * 24'h200000; - - wire [39:0] vcoeff = use_params ? pcoeff_x : cx; - wire [23:0] vcoeff_y0 = use_params ? pcoeff_y0[23:0] : cy0; - wire [23:0] vcoeff_y1 = use_params ? pcoeff_y1[23:0] : cy1; - wire [23:0] vcoeff_y2 = use_params ? pcoeff_y2[23:0] : cy2; - - wire [59:0] inp_mul = $signed(inp) * $signed(vcoeff); - - wire [39:0] x = inp_mul[59:20]; - wire [39:0] y = x + tap0; - - wire [39:0] tap0; - iir_filter_tap iir_tap_0 - ( - .clk ( clk ), - .reset ( reset ), - .ce ( ce ), - .ch ( ch ), - .cx ( use_params ? coeff_x0[7:0] : cx0 ), - .cy ( vcoeff_y0 ), - .x ( x ), - .y ( y ), - .z ( tap1 ), - .tap ( tap0 ) - ); - - wire [39:0] tap1; - iir_filter_tap iir_tap_1 - ( - .clk ( clk ), - .reset ( reset ), - .ce ( ce ), - .ch ( ch ), - .cx ( use_params ? coeff_x1[7:0] : cx1 ), - .cy ( vcoeff_y1 ), - .x ( x ), - .y ( y ), - .z ( tap2 ), - .tap ( tap1 ) - ); - - wire [39:0] tap2; - iir_filter_tap iir_tap_2 - ( - .clk ( clk ), - .reset ( reset ), - .ce ( ce ), - .ch ( ch ), - .cx ( use_params ? coeff_x2[7:0] : cx2 ), - .cy ( vcoeff_y2 ), - .x ( x ), - .y ( y ), - .z ( 0 ), - .tap ( tap2 ) - ); - - wire [15:0] y_clamp = (~y[39] & |y[38:35]) ? 16'h7FFF : (y[39] & ~&y[38:35]) ? 16'h8000 : y[35:20]; - - reg ch = 0; - reg [15:0] out_l, out_r, out_m; - reg [15:0] inp, inp_m; - - always @(posedge clk) begin - if (ce) begin - if(!stereo) begin - ch <= 0; - inp <= input_l; - out_l <= y_clamp; - out_r <= y_clamp; - end - else begin - ch <= ~ch; - if(ch) begin - out_m <= y_clamp; - inp <= inp_m; - end - else begin - out_l <= out_m; - out_r <= y_clamp; - inp <= input_l; - inp_m <= input_r; - end - end - end - end - - reg [31:0] out; - always @(posedge clk) begin - if (sample_ce) begin - out <= {out_l, out_r}; - end - end - - assign {output_l, output_r} = out; - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// 3-tap IIR filter for 2 channels. +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2020, Alexey Melnikov +// +// 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 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 . +// +//------------------------------------------------------------------------------ +// +// Can be converted to: +// - 2-tap (coeff_x2 = 0, coeff_y2 = 0) +// - 1-tap (coeff_x1,2 = 0, coeff_y1,2 = 0) +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module iir_filter + #( + parameter use_params = 1, // set to 1 to use following parameters, 0 for input port variables. + parameter stereo = 1, // 0 for mono (input_l) + + parameter coeff_x = 0.00000774701983513660, // Base gain value for X. Float. Range: 0.0 ... 0.999(9) + parameter coeff_x0 = 3, // Gain scale factor for X0. Integer. Range -7 ... +7 + parameter coeff_x1 = 3, // Gain scale factor for X1. Integer. Range -7 ... +7 + parameter coeff_x2 = 1, // Gain scale factor for X2. Integer. Range -7 ... +7 + parameter coeff_y0 = -2.96438150626551080000, // Coefficient for Y0. Float. Range -3.999(9) ... 3.999(9) + parameter coeff_y1 = 2.92939452735121100000, // Coefficient for Y1. Float. Range -3.999(9) ... 3.999(9) + parameter coeff_y2 = -0.96500747158831091000 // Coefficient for Y2. Float. Range -3.999(9) ... 3.999(9) + ) ( + input clk, + input reset, + + input ce, // must be double of calculated rate for stereo! + input sample_ce, // desired output sample rate + + input [39:0] cx, + input [7:0] cx0, + input [7:0] cx1, + input [7:0] cx2, + input [23:0] cy0, + input [23:0] cy1, + input [23:0] cy2, + + input [15:0] input_l, input_r, // signed samples + output [15:0] output_l, output_r // signed samples + ); + + localparam [39:0] pcoeff_x = coeff_x * 40'h8000000000; + localparam [31:0] pcoeff_y0 = coeff_y0 * 24'h200000; + localparam [31:0] pcoeff_y1 = coeff_y1 * 24'h200000; + localparam [31:0] pcoeff_y2 = coeff_y2 * 24'h200000; + + wire [39:0] vcoeff = use_params ? pcoeff_x : cx; + wire [23:0] vcoeff_y0 = use_params ? pcoeff_y0[23:0] : cy0; + wire [23:0] vcoeff_y1 = use_params ? pcoeff_y1[23:0] : cy1; + wire [23:0] vcoeff_y2 = use_params ? pcoeff_y2[23:0] : cy2; + + wire [59:0] inp_mul = $signed(inp) * $signed(vcoeff); + + wire [39:0] x = inp_mul[59:20]; + wire [39:0] y = x + tap0; + + wire [39:0] tap0; + iir_filter_tap iir_tap_0 + ( + .clk ( clk ), + .reset ( reset ), + .ce ( ce ), + .ch ( ch ), + .cx ( use_params ? coeff_x0[7:0] : cx0 ), + .cy ( vcoeff_y0 ), + .x ( x ), + .y ( y ), + .z ( tap1 ), + .tap ( tap0 ) + ); + + wire [39:0] tap1; + iir_filter_tap iir_tap_1 + ( + .clk ( clk ), + .reset ( reset ), + .ce ( ce ), + .ch ( ch ), + .cx ( use_params ? coeff_x1[7:0] : cx1 ), + .cy ( vcoeff_y1 ), + .x ( x ), + .y ( y ), + .z ( tap2 ), + .tap ( tap1 ) + ); + + wire [39:0] tap2; + iir_filter_tap iir_tap_2 + ( + .clk ( clk ), + .reset ( reset ), + .ce ( ce ), + .ch ( ch ), + .cx ( use_params ? coeff_x2[7:0] : cx2 ), + .cy ( vcoeff_y2 ), + .x ( x ), + .y ( y ), + .z ( 0 ), + .tap ( tap2 ) + ); + + wire [15:0] y_clamp = (~y[39] & |y[38:35]) ? 16'h7FFF : (y[39] & ~&y[38:35]) ? 16'h8000 : y[35:20]; + + reg ch = 0; + reg [15:0] out_l, out_r, out_m; + reg [15:0] inp, inp_m; + + always @(posedge clk) begin + if (ce) begin + if(!stereo) begin + ch <= 0; + inp <= input_l; + out_l <= y_clamp; + out_r <= y_clamp; + end + else begin + ch <= ~ch; + if(ch) begin + out_m <= y_clamp; + inp <= inp_m; + end + else begin + out_l <= out_m; + out_r <= y_clamp; + inp <= input_l; + inp_m <= input_r; + end + end + end + end + + reg [31:0] out; + always @(posedge clk) begin + if (sample_ce) begin + out <= {out_l, out_r}; + end + end + + assign {output_l, output_r} = out; + +endmodule diff --git a/platform/pocket/audio/filters/iir_filter_tap.sv b/platform/pocket/audio/filters/iir_filter_tap.sv index 7e9ca23..f1e7106 100644 --- a/platform/pocket/audio/filters/iir_filter_tap.sv +++ b/platform/pocket/audio/filters/iir_filter_tap.sv @@ -1,90 +1,90 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Infinite Impulse Response (IIR) filter tap. -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2020, Alexey Melnikov -// -// 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 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 . -// -//------------------------------------------------------------------------------ -// -// The iir_filter_tap module implements an infinite impulse response (IIR) filter -// with one tap. It takes in input data x, previous output data y, and an input z -// and calculates the output tap using a set of coefficients cx and cy. The -// coefficients are used to multiply the input data and previous output data, -// and the resulting values are then added together to produce the output tap. -// The module stores intermediate values in a logic RAM, and updates the values -// on each clock cycle based on the control signals ce and ch. The module uses -// a Verilog function to perform the multiplication of the input data with the -// coefficients. -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module iir_filter_tap - ( - input wire clk, // clock signal - input wire reset, // reset signal - - input wire ce, // control signal - input wire ch, // control signal - - input wire [7:0] cx, // coefficient value - input wire [23:0] cy, // coefficient value - - input wire [39:0] x, // input data - input wire [39:0] y, // previous output data - input wire [39:0] z, // input data - output wire [39:0] tap // output data - ); - - // multiply previous output y with coefficient cy - wire signed [60:0] y_mul = $signed(y[36:0]) * $signed(cy); - - // multiply input x with coefficient cx - function [39:0] x_mul; - input [39:0] x; - begin - x_mul = 0; - if(cx[0]) x_mul = x_mul + {{4{x[39]}}, x[39:4]}; // multiply x[39:36] with cx[0] - if(cx[1]) x_mul = x_mul + {{3{x[39]}}, x[39:3]}; // multiply x[39:35] with cx[1] - if(cx[2]) x_mul = x_mul + {{2{x[39]}}, x[39:2]}; // multiply x[39:34] with cx[2] - if(cx[7]) x_mul = ~x_mul; // negate result if cx[7] is set - end - endfunction - - // use logic RAM to store intermediate values - (* ramstyle = "logic" *) reg [39:0] intreg[2]; - always @(posedge clk, posedge reset) begin - if(reset) begin - {intreg[0],intreg[1]} <= 80'd0; - end - else if(ce) begin - // update intreg[ch] with new value - intreg[ch] <= x_mul(x) - y_mul[60:21] + z; - // multiply input x with cx, subtract a portion of previous output y (specified by cy), - // add input z, and store the result in intreg[ch] - end - end - - // assign output tap to value in intreg corresponding to ch signal - assign tap = intreg[ch]; - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Infinite Impulse Response (IIR) filter tap. +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2020, Alexey Melnikov +// +// 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 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 . +// +//------------------------------------------------------------------------------ +// +// The iir_filter_tap module implements an infinite impulse response (IIR) filter +// with one tap. It takes in input data x, previous output data y, and an input z +// and calculates the output tap using a set of coefficients cx and cy. The +// coefficients are used to multiply the input data and previous output data, +// and the resulting values are then added together to produce the output tap. +// The module stores intermediate values in a logic RAM, and updates the values +// on each clock cycle based on the control signals ce and ch. The module uses +// a Verilog function to perform the multiplication of the input data with the +// coefficients. +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module iir_filter_tap + ( + input wire clk, // clock signal + input wire reset, // reset signal + + input wire ce, // control signal + input wire ch, // control signal + + input wire [7:0] cx, // coefficient value + input wire [23:0] cy, // coefficient value + + input wire [39:0] x, // input data + input wire [39:0] y, // previous output data + input wire [39:0] z, // input data + output wire [39:0] tap // output data + ); + + // multiply previous output y with coefficient cy + wire signed [60:0] y_mul = $signed(y[36:0]) * $signed(cy); + + // multiply input x with coefficient cx + function [39:0] x_mul; + input [39:0] x; + begin + x_mul = 0; + if(cx[0]) x_mul = x_mul + {{4{x[39]}}, x[39:4]}; // multiply x[39:36] with cx[0] + if(cx[1]) x_mul = x_mul + {{3{x[39]}}, x[39:3]}; // multiply x[39:35] with cx[1] + if(cx[2]) x_mul = x_mul + {{2{x[39]}}, x[39:2]}; // multiply x[39:34] with cx[2] + if(cx[7]) x_mul = ~x_mul; // negate result if cx[7] is set + end + endfunction + + // use logic RAM to store intermediate values + (* ramstyle = "logic" *) reg [39:0] intreg[2]; + always @(posedge clk, posedge reset) begin + if(reset) begin + {intreg[0],intreg[1]} <= 80'd0; + end + else if(ce) begin + // update intreg[ch] with new value + intreg[ch] <= x_mul(x) - y_mul[60:21] + z; + // multiply input x with cx, subtract a portion of previous output y (specified by cy), + // add input z, and store the result in intreg[ch] + end + end + + // assign output tap to value in intreg corresponding to ch signal + assign tap = intreg[ch]; + +endmodule diff --git a/platform/pocket/audio/pocket_i2s.sv b/platform/pocket/audio/pocket_i2s.sv index 2133e44..836aa4f 100644 --- a/platform/pocket/audio/pocket_i2s.sv +++ b/platform/pocket/audio/pocket_i2s.sv @@ -1,70 +1,70 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket I2S Audio Interface -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module pocket_i2s - ( - input wire audio_sclk, //! Serial clock - // Core Audio - input wire [15:0] audio_l, //! Left channel - input wire [15:0] audio_r, //! Right channel - // Pocket I2S Interface - output reg audio_dac, //! Serialized data - output reg audio_lrck //! Left/Right clock - ); - - //! ------------------------------------------------------------------------ - //! Synchronize audio samples - //! ------------------------------------------------------------------------ - reg [31:0] audio_sd_s; //! Synced Audio Sample - synch_3 #(.WIDTH(32)) sync_sample({audio_l, audio_r}, audio_sd_s, audio_sclk); - - //! ------------------------------------------------------------------------ - //! Generate signals for digital-to-analog conversion. - //! ------------------------------------------------------------------------ - reg [31:0] audio_sample_sh; // Register for shifting audio samples - reg [4:0] audio_lrck_cnt; // Register for counting LRCK (left/right clock) cycles - - always_ff @(negedge audio_sclk) begin - audio_dac <= audio_sample_sh[31]; // Set DAC output to the MSB (most significant bit) of audio_sample_sh - audio_lrck_cnt <= audio_lrck_cnt + 1'b1; - if (audio_lrck_cnt == 31) begin - audio_lrck <= ~audio_lrck; // Toggle audio_lrck (switch channels) - if (~audio_lrck) begin - audio_sample_sh <= audio_sd_s; // Reload sample shifter with new audio sample - end - end - else if (audio_lrck_cnt < 16) begin - audio_sample_sh <= {audio_sample_sh[30:0], 1'b0}; // Only shift for 16 clocks per channel - end - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket I2S Audio Interface +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module pocket_i2s + ( + input wire audio_sclk, //! Serial clock + // Core Audio + input wire [15:0] audio_l, //! Left channel + input wire [15:0] audio_r, //! Right channel + // Pocket I2S Interface + output reg audio_dac, //! Serialized data + output reg audio_lrck //! Left/Right clock + ); + + //! ------------------------------------------------------------------------ + //! Synchronize audio samples + //! ------------------------------------------------------------------------ + reg [31:0] audio_sd_s; //! Synced Audio Sample + synch_3 #(.WIDTH(32)) sync_sample({audio_l, audio_r}, audio_sd_s, audio_sclk); + + //! ------------------------------------------------------------------------ + //! Generate signals for digital-to-analog conversion. + //! ------------------------------------------------------------------------ + reg [31:0] audio_sample_sh; // Register for shifting audio samples + reg [4:0] audio_lrck_cnt; // Register for counting LRCK (left/right clock) cycles + + always_ff @(negedge audio_sclk) begin + audio_dac <= audio_sample_sh[31]; // Set DAC output to the MSB (most significant bit) of audio_sample_sh + audio_lrck_cnt <= audio_lrck_cnt + 1'b1; + if (audio_lrck_cnt == 31) begin + audio_lrck <= ~audio_lrck; // Toggle audio_lrck (switch channels) + if (~audio_lrck) begin + audio_sample_sh <= audio_sd_s; // Reload sample shifter with new audio sample + end + end + else if (audio_lrck_cnt < 16) begin + audio_sample_sh <= {audio_sample_sh[30:0], 1'b0}; // Only shift for 16 clocks per channel + end + end + +endmodule diff --git a/platform/pocket/bsp/pocket/apf_top.sv b/platform/pocket/bsp/pocket/apf_top.sv index 3eda9ab..b132da1 100644 --- a/platform/pocket/bsp/pocket/apf_top.sv +++ b/platform/pocket/bsp/pocket/apf_top.sv @@ -1,464 +1,464 @@ -// Software License Agreement - -// The software supplied herewith by Analogue Enterprises Limited (the "Company”), -// the Analogue Pocket Framework (“APF”), is provided and licensed to you, the -// Company's customer, solely for use in designing, testing and creating -// applications for use with Company's Products or Services. The software is -// owned by the Company and/or its licensors, and is protected under applicable -// laws, including, but not limited to, U.S. copyright law. All rights are -// reserved. By using the APF code you are agreeing to the terms of the End User -// License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula] -// and incorporated herein by reference. To the extent any use of the APF requires -// application of the MIT License or the GNU General Public License and terms of -// this APF Software License Agreement and EULA are inconsistent with such license, -// the applicable terms of the MIT License or the GNU General Public License, as -// applicable, will prevail. - -// THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED -// WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO, -// ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR -// NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM -// DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE -// MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED, -// THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND -// DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING -// THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR -// ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY -// INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES, -// INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR -// INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY -// OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY -// CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION, -// WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU -// TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH -// YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE -// FULLEST EXTENT PERMITTED BY APPLICABLE LAW. -// -// 6515C - Analogue Pocket main unit -// SOCRATES FPGA -// -// 2022-08-17 Analogue - -`default_nettype none - -module apf_top ( - /////////////////////////////////////////////////// - // clock inputs 74.25mhz. not phase aligned, so treat these domains as asynchronous - - input wire clk_74a, // mainclk1 - input wire clk_74b, // mainclk1 - - /////////////////////////////////////////////////// - // cartridge interface - // switches between 3.3v and 5v mechanically - // output enable for multibit translators controlled by PIC32 - - // GBA AD[15:8] - inout wire [7:0] cart_tran_bank2, - output wire cart_tran_bank2_dir, - - // GBA AD[7:0] - inout wire [7:0] cart_tran_bank3, - output wire cart_tran_bank3_dir, - - // GBA A[23:16] - inout wire [7:0] cart_tran_bank1, - output wire cart_tran_bank1_dir, - - // GBA [7] PHI# - // GBA [6] WR# - // GBA [5] RD# - // GBA [4] CS1#/CS# - // [3:0] unwired - inout wire [7:4] cart_tran_bank0, - output wire cart_tran_bank0_dir, - - // GBA CS2#/RES# - inout wire cart_tran_pin30, - output wire cart_tran_pin30_dir, - // when GBC cart is inserted, this signal when low or weak will pull GBC /RES low with a special circuit - // the goal is that when unconfigured, the FPGA weak pullups won't interfere. - // thus, if GBC cart is inserted, FPGA must drive this high in order to let the level translators - // and general IO drive this pin. - output wire cart_pin30_pwroff_reset, - - // GBA IRQ/DRQ - inout wire cart_tran_pin31, - output wire cart_tran_pin31_dir, - - // infrared - // avoid driving the TX LED with DC or leaving it stuck on. pulsed usage is fine - input wire port_ir_rx, - output wire port_ir_tx, - output wire port_ir_rx_disable, - - // GBA link port - inout wire port_tran_si, - output wire port_tran_si_dir, - inout wire port_tran_so, - output wire port_tran_so_dir, - inout wire port_tran_sck, - output wire port_tran_sck_dir, - inout wire port_tran_sd, - output wire port_tran_sd_dir, - - /////////////////////////////////////////////////// - // video output to the scaler - - inout wire [11:0] scal_vid, - inout wire scal_clk, - inout wire scal_de, - inout wire scal_skip, - inout wire scal_vs, - inout wire scal_hs, - - output wire scal_audmclk, - input wire scal_audadc, - output wire scal_auddac, - output wire scal_audlrck, - - /////////////////////////////////////////////////// - // communication between main and scaler (aristotle) fpga. - // spi bus with aristotle as controller. - - inout wire bridge_spimosi, - inout wire bridge_spimiso, - inout wire bridge_spiclk, - input wire bridge_spiss, - inout wire bridge_1wire, - - /////////////////////////////////////////////////// - // cellular psram 0 and 1, two chips (64mbit x2 dual die per chip) - - output wire [21:16] cram0_a, - inout wire [15:0] cram0_dq, - input wire cram0_wait, - output wire cram0_clk, - output wire cram0_adv_n, - output wire cram0_cre, - output wire cram0_ce0_n, - output wire cram0_ce1_n, - output wire cram0_oe_n, - output wire cram0_we_n, - output wire cram0_ub_n, - output wire cram0_lb_n, - - output wire [21:16] cram1_a, - inout wire [15:0] cram1_dq, - input wire cram1_wait, - output wire cram1_clk, - output wire cram1_adv_n, - output wire cram1_cre, - output wire cram1_ce0_n, - output wire cram1_ce1_n, - output wire cram1_oe_n, - output wire cram1_we_n, - output wire cram1_ub_n, - output wire cram1_lb_n, - - /////////////////////////////////////////////////// - // sdram, 512mbit x16 - - output wire [12:0] dram_a, - output wire [1:0] dram_ba, - inout wire [15:0] dram_dq, - output wire [1:0] dram_dqm, - output wire dram_clk, - output wire dram_cke, - output wire dram_ras_n, - output wire dram_cas_n, - output wire dram_we_n, - - /////////////////////////////////////////////////// - // sram, 1mbit x16 - - output wire [16:0] sram_a, - inout wire [15:0] sram_dq, - output wire sram_oe_n, - output wire sram_we_n, - output wire sram_ub_n, - output wire sram_lb_n, - - /////////////////////////////////////////////////// - // vblank output to scaler - - input wire vblank, - - /////////////////////////////////////////////////// - // i/o to 6515D breakout usb uart - - output wire dbg_tx, - input wire dbg_rx, - - /////////////////////////////////////////////////// - // i/o pads near jtag connector user can solder to - - output wire user1, - input wire user2, - - /////////////////////////////////////////////////// - // powerup self test, do not use - - inout wire bist, - output wire vpll_feed, - - /////////////////////////////////////////////////// - // RFU internal i2c bus (DNU) - - inout wire aux_sda, - output wire aux_scl - - ); - - assign bist = 1'bZ; - - // reset generation - reg [24:0] count; - reg reset_n; - - initial begin - count <= 0; - reset_n <= 0; - end - always @(posedge clk_74a) begin - count <= count + 1'b1; - - if(count[15]) begin - // exit reset - reset_n <= 1; - end - end - - // convert 24-bit rgb data to 12-bit DDR for ARISTOTLE - wire [23:0] video_rgb; - wire video_rgb_clock; - wire video_rgb_clock_90; - wire video_de; - wire video_skip; - wire video_vs; - wire video_hs; - - mf_ddio_bidir_12 isco - ( - .oe ( 1'b1 ), - .datain_h ( video_rgb[23:12] ), - .datain_l ( video_rgb[11:0] ), - .outclock ( video_rgb_clock ), - .padio ( scal_ddio_12 ) - ); - - wire [11:0] scal_ddio_12; - assign scal_vid = scal_ddio_12; - - mf_ddio_bidir_12 iscc - ( - .oe ( 1'b1 ), - .datain_h ( {video_vs, video_hs, video_de, video_skip} ), - .datain_l ( {video_vs, video_hs, video_de, video_skip} ), - .outclock ( video_rgb_clock ), - .padio ( scal_ddio_ctrl ) - ); - - wire [3:0] scal_ddio_ctrl; - - assign scal_vs = scal_ddio_ctrl[3]; - assign scal_hs = scal_ddio_ctrl[2]; - assign scal_de = scal_ddio_ctrl[1]; - assign scal_skip = scal_ddio_ctrl[0]; - - mf_ddio_bidir_12 isclk - ( - .oe ( 1'b1 ), - .datain_h ( 1'b1 ), - .datain_l ( 1'b0 ), - .outclock ( video_rgb_clock_90 ), - .padio ( scal_clk ) - ); - - // controller data (pad) controller. - wire [31:0] cont1_key; - wire [31:0] cont2_key; - wire [31:0] cont3_key; - wire [31:0] cont4_key; - wire [31:0] cont1_joy; - wire [31:0] cont2_joy; - wire [31:0] cont3_joy; - wire [31:0] cont4_joy; - wire [15:0] cont1_trig; - wire [15:0] cont2_trig; - wire [15:0] cont3_trig; - wire [15:0] cont4_trig; - - io_pad_controller ipm - ( - .clk ( clk_74a ), - .reset_n ( reset_n ), - - .pad_1wire ( bridge_1wire ), - - .cont1_key ( cont1_key ), - .cont2_key ( cont2_key ), - .cont3_key ( cont3_key ), - .cont4_key ( cont4_key ), - .cont1_joy ( cont1_joy ), - .cont2_joy ( cont2_joy ), - .cont3_joy ( cont3_joy ), - .cont4_joy ( cont4_joy ), - .cont1_trig ( cont1_trig ), - .cont2_trig ( cont2_trig ), - .cont3_trig ( cont3_trig ), - .cont4_trig ( cont4_trig ) - ); - - // virtual pmp bridge - wire bridge_endian_little; - wire [31:0] bridge_addr; - wire bridge_rd; - wire [31:0] bridge_rd_data; - wire bridge_wr; - wire [31:0] bridge_wr_data; - - io_bridge_peripheral ibs - ( - .clk ( clk_74a ), - .reset_n ( reset_n ), - - .endian_little ( bridge_endian_little ), - - .pmp_addr ( bridge_addr ), - .pmp_rd ( bridge_rd ), - .pmp_rd_data ( bridge_rd_data ), - .pmp_wr ( bridge_wr ), - .pmp_wr_data ( bridge_wr_data ), - - .phy_spimosi ( bridge_spimosi ), - .phy_spimiso ( bridge_spimiso ), - .phy_spiclk ( bridge_spiclk ), - .phy_spiss ( bridge_spiss ) - ); - - /////////////////////////////////////////////////// - // instantiate the user core top-level - core_top ic - ( - // physical connections - .clk_74a ( clk_74a ), - .clk_74b ( clk_74b ), - - .cart_tran_bank2 ( cart_tran_bank2 ), - .cart_tran_bank2_dir ( cart_tran_bank2_dir ), - .cart_tran_bank3 ( cart_tran_bank3 ), - .cart_tran_bank3_dir ( cart_tran_bank3_dir ), - .cart_tran_bank1 ( cart_tran_bank1 ), - .cart_tran_bank1_dir ( cart_tran_bank1_dir ), - .cart_tran_bank0 ( cart_tran_bank0 ), - .cart_tran_bank0_dir ( cart_tran_bank0_dir ), - .cart_tran_pin30 ( cart_tran_pin30 ), - .cart_tran_pin30_dir ( cart_tran_pin30_dir ), - .cart_pin30_pwroff_reset ( cart_pin30_pwroff_reset ), - .cart_tran_pin31 ( cart_tran_pin31 ), - .cart_tran_pin31_dir ( cart_tran_pin31_dir ), - - .port_ir_rx ( port_ir_rx ), - .port_ir_tx ( port_ir_tx ), - .port_ir_rx_disable ( port_ir_rx_disable ), - - .port_tran_si ( port_tran_si ), - .port_tran_si_dir ( port_tran_si_dir ), - .port_tran_so ( port_tran_so ), - .port_tran_so_dir ( port_tran_so_dir ), - .port_tran_sck ( port_tran_sck ), - .port_tran_sck_dir ( port_tran_sck_dir ), - .port_tran_sd ( port_tran_sd ), - .port_tran_sd_dir ( port_tran_sd_dir ), - - .cram0_a ( cram0_a ), - .cram0_dq ( cram0_dq ), - .cram0_wait ( cram0_wait ), - .cram0_clk ( cram0_clk ), - .cram0_adv_n ( cram0_adv_n ), - .cram0_cre ( cram0_cre ), - .cram0_ce0_n ( cram0_ce0_n ), - .cram0_ce1_n ( cram0_ce1_n ), - .cram0_oe_n ( cram0_oe_n ), - .cram0_we_n ( cram0_we_n ), - .cram0_ub_n ( cram0_ub_n ), - .cram0_lb_n ( cram0_lb_n ), - .cram1_a ( cram1_a ), - .cram1_dq ( cram1_dq ), - .cram1_wait ( cram1_wait ), - .cram1_clk ( cram1_clk ), - .cram1_adv_n ( cram1_adv_n ), - .cram1_cre ( cram1_cre ), - .cram1_ce0_n ( cram1_ce0_n ), - .cram1_ce1_n ( cram1_ce1_n ), - .cram1_oe_n ( cram1_oe_n ), - .cram1_we_n ( cram1_we_n ), - .cram1_ub_n ( cram1_ub_n ), - .cram1_lb_n ( cram1_lb_n ), - - .dram_a ( dram_a ), - .dram_ba ( dram_ba ), - .dram_dq ( dram_dq ), - .dram_dqm ( dram_dqm ), - .dram_clk ( dram_clk ), - .dram_cke ( dram_cke ), - .dram_ras_n ( dram_ras_n ), - .dram_cas_n ( dram_cas_n ), - .dram_we_n ( dram_we_n ), - - .sram_a ( sram_a ), - .sram_dq ( sram_dq ), - .sram_oe_n ( sram_oe_n ), - .sram_we_n ( sram_we_n ), - .sram_ub_n ( sram_ub_n ), - .sram_lb_n ( sram_lb_n ), - - .vblank ( vblank ), - .vpll_feed ( vpll_feed ), - - .dbg_tx ( dbg_tx ), - .dbg_rx ( dbg_rx ), - .user1 ( user1 ), - .user2 ( user2 ), - - .aux_sda ( aux_sda ), - .aux_scl ( aux_scl ), - - // logical connections with user core - .video_rgb ( video_rgb ), - .video_rgb_clock ( video_rgb_clock ), - .video_rgb_clock_90 ( video_rgb_clock_90 ), - .video_de ( video_de ), - .video_skip ( video_skip ), - .video_vs ( video_vs ), - .video_hs ( video_hs ), - - .audio_mclk ( scal_audmclk ), - .audio_adc ( scal_audadc ), - .audio_dac ( scal_auddac ), - .audio_lrck ( scal_audlrck ), - - .bridge_endian_little ( bridge_endian_little ), - .bridge_addr ( bridge_addr ), - .bridge_rd ( bridge_rd ), - .bridge_rd_data ( bridge_rd_data ), - .bridge_wr ( bridge_wr ), - .bridge_wr_data ( bridge_wr_data ), - - .cont1_key ( cont1_key ), - .cont2_key ( cont2_key ), - .cont3_key ( cont3_key ), - .cont4_key ( cont4_key ), - .cont1_joy ( cont1_joy ), - .cont2_joy ( cont2_joy ), - .cont3_joy ( cont3_joy ), - .cont4_joy ( cont4_joy ), - .cont1_trig ( cont1_trig ), - .cont2_trig ( cont2_trig ), - .cont3_trig ( cont3_trig ), - .cont4_trig ( cont4_trig ) - ); - -endmodule - +// Software License Agreement + +// The software supplied herewith by Analogue Enterprises Limited (the "Company”), +// the Analogue Pocket Framework (“APF”), is provided and licensed to you, the +// Company's customer, solely for use in designing, testing and creating +// applications for use with Company's Products or Services. The software is +// owned by the Company and/or its licensors, and is protected under applicable +// laws, including, but not limited to, U.S. copyright law. All rights are +// reserved. By using the APF code you are agreeing to the terms of the End User +// License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula] +// and incorporated herein by reference. To the extent any use of the APF requires +// application of the MIT License or the GNU General Public License and terms of +// this APF Software License Agreement and EULA are inconsistent with such license, +// the applicable terms of the MIT License or the GNU General Public License, as +// applicable, will prevail. + +// THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED +// WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO, +// ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR +// NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM +// DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE +// MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED, +// THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND +// DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING +// THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR +// ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY +// INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES, +// INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR +// INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY +// OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY +// CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION, +// WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU +// TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH +// YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE +// FULLEST EXTENT PERMITTED BY APPLICABLE LAW. +// +// 6515C - Analogue Pocket main unit +// SOCRATES FPGA +// +// 2022-08-17 Analogue + +`default_nettype none + +module apf_top ( + /////////////////////////////////////////////////// + // clock inputs 74.25mhz. not phase aligned, so treat these domains as asynchronous + + input wire clk_74a, // mainclk1 + input wire clk_74b, // mainclk1 + + /////////////////////////////////////////////////// + // cartridge interface + // switches between 3.3v and 5v mechanically + // output enable for multibit translators controlled by PIC32 + + // GBA AD[15:8] + inout wire [7:0] cart_tran_bank2, + output wire cart_tran_bank2_dir, + + // GBA AD[7:0] + inout wire [7:0] cart_tran_bank3, + output wire cart_tran_bank3_dir, + + // GBA A[23:16] + inout wire [7:0] cart_tran_bank1, + output wire cart_tran_bank1_dir, + + // GBA [7] PHI# + // GBA [6] WR# + // GBA [5] RD# + // GBA [4] CS1#/CS# + // [3:0] unwired + inout wire [7:4] cart_tran_bank0, + output wire cart_tran_bank0_dir, + + // GBA CS2#/RES# + inout wire cart_tran_pin30, + output wire cart_tran_pin30_dir, + // when GBC cart is inserted, this signal when low or weak will pull GBC /RES low with a special circuit + // the goal is that when unconfigured, the FPGA weak pullups won't interfere. + // thus, if GBC cart is inserted, FPGA must drive this high in order to let the level translators + // and general IO drive this pin. + output wire cart_pin30_pwroff_reset, + + // GBA IRQ/DRQ + inout wire cart_tran_pin31, + output wire cart_tran_pin31_dir, + + // infrared + // avoid driving the TX LED with DC or leaving it stuck on. pulsed usage is fine + input wire port_ir_rx, + output wire port_ir_tx, + output wire port_ir_rx_disable, + + // GBA link port + inout wire port_tran_si, + output wire port_tran_si_dir, + inout wire port_tran_so, + output wire port_tran_so_dir, + inout wire port_tran_sck, + output wire port_tran_sck_dir, + inout wire port_tran_sd, + output wire port_tran_sd_dir, + + /////////////////////////////////////////////////// + // video output to the scaler + + inout wire [11:0] scal_vid, + inout wire scal_clk, + inout wire scal_de, + inout wire scal_skip, + inout wire scal_vs, + inout wire scal_hs, + + output wire scal_audmclk, + input wire scal_audadc, + output wire scal_auddac, + output wire scal_audlrck, + + /////////////////////////////////////////////////// + // communication between main and scaler (aristotle) fpga. + // spi bus with aristotle as controller. + + inout wire bridge_spimosi, + inout wire bridge_spimiso, + inout wire bridge_spiclk, + input wire bridge_spiss, + inout wire bridge_1wire, + + /////////////////////////////////////////////////// + // cellular psram 0 and 1, two chips (64mbit x2 dual die per chip) + + output wire [21:16] cram0_a, + inout wire [15:0] cram0_dq, + input wire cram0_wait, + output wire cram0_clk, + output wire cram0_adv_n, + output wire cram0_cre, + output wire cram0_ce0_n, + output wire cram0_ce1_n, + output wire cram0_oe_n, + output wire cram0_we_n, + output wire cram0_ub_n, + output wire cram0_lb_n, + + output wire [21:16] cram1_a, + inout wire [15:0] cram1_dq, + input wire cram1_wait, + output wire cram1_clk, + output wire cram1_adv_n, + output wire cram1_cre, + output wire cram1_ce0_n, + output wire cram1_ce1_n, + output wire cram1_oe_n, + output wire cram1_we_n, + output wire cram1_ub_n, + output wire cram1_lb_n, + + /////////////////////////////////////////////////// + // sdram, 512mbit x16 + + output wire [12:0] dram_a, + output wire [1:0] dram_ba, + inout wire [15:0] dram_dq, + output wire [1:0] dram_dqm, + output wire dram_clk, + output wire dram_cke, + output wire dram_ras_n, + output wire dram_cas_n, + output wire dram_we_n, + + /////////////////////////////////////////////////// + // sram, 1mbit x16 + + output wire [16:0] sram_a, + inout wire [15:0] sram_dq, + output wire sram_oe_n, + output wire sram_we_n, + output wire sram_ub_n, + output wire sram_lb_n, + + /////////////////////////////////////////////////// + // vblank output to scaler + + input wire vblank, + + /////////////////////////////////////////////////// + // i/o to 6515D breakout usb uart + + output wire dbg_tx, + input wire dbg_rx, + + /////////////////////////////////////////////////// + // i/o pads near jtag connector user can solder to + + output wire user1, + input wire user2, + + /////////////////////////////////////////////////// + // powerup self test, do not use + + inout wire bist, + output wire vpll_feed, + + /////////////////////////////////////////////////// + // RFU internal i2c bus (DNU) + + inout wire aux_sda, + output wire aux_scl + + ); + + assign bist = 1'bZ; + + // reset generation + reg [24:0] count; + reg reset_n; + + initial begin + count <= 0; + reset_n <= 0; + end + always @(posedge clk_74a) begin + count <= count + 1'b1; + + if(count[15]) begin + // exit reset + reset_n <= 1; + end + end + + // convert 24-bit rgb data to 12-bit DDR for ARISTOTLE + wire [23:0] video_rgb; + wire video_rgb_clock; + wire video_rgb_clock_90; + wire video_de; + wire video_skip; + wire video_vs; + wire video_hs; + + mf_ddio_bidir_12 isco + ( + .oe ( 1'b1 ), + .datain_h ( video_rgb[23:12] ), + .datain_l ( video_rgb[11:0] ), + .outclock ( video_rgb_clock ), + .padio ( scal_ddio_12 ) + ); + + wire [11:0] scal_ddio_12; + assign scal_vid = scal_ddio_12; + + mf_ddio_bidir_12 iscc + ( + .oe ( 1'b1 ), + .datain_h ( {video_vs, video_hs, video_de, video_skip} ), + .datain_l ( {video_vs, video_hs, video_de, video_skip} ), + .outclock ( video_rgb_clock ), + .padio ( scal_ddio_ctrl ) + ); + + wire [3:0] scal_ddio_ctrl; + + assign scal_vs = scal_ddio_ctrl[3]; + assign scal_hs = scal_ddio_ctrl[2]; + assign scal_de = scal_ddio_ctrl[1]; + assign scal_skip = scal_ddio_ctrl[0]; + + mf_ddio_bidir_12 isclk + ( + .oe ( 1'b1 ), + .datain_h ( 1'b1 ), + .datain_l ( 1'b0 ), + .outclock ( video_rgb_clock_90 ), + .padio ( scal_clk ) + ); + + // controller data (pad) controller. + wire [31:0] cont1_key; + wire [31:0] cont2_key; + wire [31:0] cont3_key; + wire [31:0] cont4_key; + wire [31:0] cont1_joy; + wire [31:0] cont2_joy; + wire [31:0] cont3_joy; + wire [31:0] cont4_joy; + wire [15:0] cont1_trig; + wire [15:0] cont2_trig; + wire [15:0] cont3_trig; + wire [15:0] cont4_trig; + + io_pad_controller ipm + ( + .clk ( clk_74a ), + .reset_n ( reset_n ), + + .pad_1wire ( bridge_1wire ), + + .cont1_key ( cont1_key ), + .cont2_key ( cont2_key ), + .cont3_key ( cont3_key ), + .cont4_key ( cont4_key ), + .cont1_joy ( cont1_joy ), + .cont2_joy ( cont2_joy ), + .cont3_joy ( cont3_joy ), + .cont4_joy ( cont4_joy ), + .cont1_trig ( cont1_trig ), + .cont2_trig ( cont2_trig ), + .cont3_trig ( cont3_trig ), + .cont4_trig ( cont4_trig ) + ); + + // virtual pmp bridge + wire bridge_endian_little; + wire [31:0] bridge_addr; + wire bridge_rd; + wire [31:0] bridge_rd_data; + wire bridge_wr; + wire [31:0] bridge_wr_data; + + io_bridge_peripheral ibs + ( + .clk ( clk_74a ), + .reset_n ( reset_n ), + + .endian_little ( bridge_endian_little ), + + .pmp_addr ( bridge_addr ), + .pmp_rd ( bridge_rd ), + .pmp_rd_data ( bridge_rd_data ), + .pmp_wr ( bridge_wr ), + .pmp_wr_data ( bridge_wr_data ), + + .phy_spimosi ( bridge_spimosi ), + .phy_spimiso ( bridge_spimiso ), + .phy_spiclk ( bridge_spiclk ), + .phy_spiss ( bridge_spiss ) + ); + + /////////////////////////////////////////////////// + // instantiate the user core top-level + core_top ic + ( + // physical connections + .clk_74a ( clk_74a ), + .clk_74b ( clk_74b ), + + .cart_tran_bank2 ( cart_tran_bank2 ), + .cart_tran_bank2_dir ( cart_tran_bank2_dir ), + .cart_tran_bank3 ( cart_tran_bank3 ), + .cart_tran_bank3_dir ( cart_tran_bank3_dir ), + .cart_tran_bank1 ( cart_tran_bank1 ), + .cart_tran_bank1_dir ( cart_tran_bank1_dir ), + .cart_tran_bank0 ( cart_tran_bank0 ), + .cart_tran_bank0_dir ( cart_tran_bank0_dir ), + .cart_tran_pin30 ( cart_tran_pin30 ), + .cart_tran_pin30_dir ( cart_tran_pin30_dir ), + .cart_pin30_pwroff_reset ( cart_pin30_pwroff_reset ), + .cart_tran_pin31 ( cart_tran_pin31 ), + .cart_tran_pin31_dir ( cart_tran_pin31_dir ), + + .port_ir_rx ( port_ir_rx ), + .port_ir_tx ( port_ir_tx ), + .port_ir_rx_disable ( port_ir_rx_disable ), + + .port_tran_si ( port_tran_si ), + .port_tran_si_dir ( port_tran_si_dir ), + .port_tran_so ( port_tran_so ), + .port_tran_so_dir ( port_tran_so_dir ), + .port_tran_sck ( port_tran_sck ), + .port_tran_sck_dir ( port_tran_sck_dir ), + .port_tran_sd ( port_tran_sd ), + .port_tran_sd_dir ( port_tran_sd_dir ), + + .cram0_a ( cram0_a ), + .cram0_dq ( cram0_dq ), + .cram0_wait ( cram0_wait ), + .cram0_clk ( cram0_clk ), + .cram0_adv_n ( cram0_adv_n ), + .cram0_cre ( cram0_cre ), + .cram0_ce0_n ( cram0_ce0_n ), + .cram0_ce1_n ( cram0_ce1_n ), + .cram0_oe_n ( cram0_oe_n ), + .cram0_we_n ( cram0_we_n ), + .cram0_ub_n ( cram0_ub_n ), + .cram0_lb_n ( cram0_lb_n ), + .cram1_a ( cram1_a ), + .cram1_dq ( cram1_dq ), + .cram1_wait ( cram1_wait ), + .cram1_clk ( cram1_clk ), + .cram1_adv_n ( cram1_adv_n ), + .cram1_cre ( cram1_cre ), + .cram1_ce0_n ( cram1_ce0_n ), + .cram1_ce1_n ( cram1_ce1_n ), + .cram1_oe_n ( cram1_oe_n ), + .cram1_we_n ( cram1_we_n ), + .cram1_ub_n ( cram1_ub_n ), + .cram1_lb_n ( cram1_lb_n ), + + .dram_a ( dram_a ), + .dram_ba ( dram_ba ), + .dram_dq ( dram_dq ), + .dram_dqm ( dram_dqm ), + .dram_clk ( dram_clk ), + .dram_cke ( dram_cke ), + .dram_ras_n ( dram_ras_n ), + .dram_cas_n ( dram_cas_n ), + .dram_we_n ( dram_we_n ), + + .sram_a ( sram_a ), + .sram_dq ( sram_dq ), + .sram_oe_n ( sram_oe_n ), + .sram_we_n ( sram_we_n ), + .sram_ub_n ( sram_ub_n ), + .sram_lb_n ( sram_lb_n ), + + .vblank ( vblank ), + .vpll_feed ( vpll_feed ), + + .dbg_tx ( dbg_tx ), + .dbg_rx ( dbg_rx ), + .user1 ( user1 ), + .user2 ( user2 ), + + .aux_sda ( aux_sda ), + .aux_scl ( aux_scl ), + + // logical connections with user core + .video_rgb ( video_rgb ), + .video_rgb_clock ( video_rgb_clock ), + .video_rgb_clock_90 ( video_rgb_clock_90 ), + .video_de ( video_de ), + .video_skip ( video_skip ), + .video_vs ( video_vs ), + .video_hs ( video_hs ), + + .audio_mclk ( scal_audmclk ), + .audio_adc ( scal_audadc ), + .audio_dac ( scal_auddac ), + .audio_lrck ( scal_audlrck ), + + .bridge_endian_little ( bridge_endian_little ), + .bridge_addr ( bridge_addr ), + .bridge_rd ( bridge_rd ), + .bridge_rd_data ( bridge_rd_data ), + .bridge_wr ( bridge_wr ), + .bridge_wr_data ( bridge_wr_data ), + + .cont1_key ( cont1_key ), + .cont2_key ( cont2_key ), + .cont3_key ( cont3_key ), + .cont4_key ( cont4_key ), + .cont1_joy ( cont1_joy ), + .cont2_joy ( cont2_joy ), + .cont3_joy ( cont3_joy ), + .cont4_joy ( cont4_joy ), + .cont1_trig ( cont1_trig ), + .cont2_trig ( cont2_trig ), + .cont3_trig ( cont3_trig ), + .cont4_trig ( cont4_trig ) + ); + +endmodule + diff --git a/platform/pocket/bsp/pocket/pinouts/system.tcl b/platform/pocket/bsp/pocket/pinouts/system.tcl index 42534de..8f655fe 100644 --- a/platform/pocket/bsp/pocket/pinouts/system.tcl +++ b/platform/pocket/bsp/pocket/pinouts/system.tcl @@ -1,760 +1,760 @@ -# ============================================================================== -# Clock Circuitry -# ============================================================================== -set_location_assignment PIN_V15 -to clk_74a -set_location_assignment PIN_H16 -to clk_74b - -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to clk_74a -set_instance_assignment -name IO_STANDARD "1.8 V" -to clk_74b - -# ============================================================================== -# SPI bus with Aristotle -# ============================================================================== -set_location_assignment PIN_T17 -to bridge_spiclk -set_location_assignment PIN_M21 -to bridge_spimiso -set_location_assignment PIN_M20 -to bridge_spimosi -set_location_assignment PIN_L19 -to bridge_1wire -set_location_assignment PIN_H14 -to bridge_spiss - -set_instance_assignment -name IO_STANDARD "1.8 V" -to bridge_spiclk -set_instance_assignment -name IO_STANDARD "1.8 V" -to bridge_spimiso -set_instance_assignment -name IO_STANDARD "1.8 V" -to bridge_spimosi -set_instance_assignment -name IO_STANDARD "1.8 V" -to bridge_1wire -set_instance_assignment -name IO_STANDARD "1.8 V" -to bridge_spiss - -set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to bridge_spiclk -set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to bridge_spimiso -set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to bridge_spimosi -set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to bridge_1wire - -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to bridge_spiclk -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to bridge_spimiso -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to bridge_spimosi -set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to bridge_1wire - -# ============================================================================== -# Cartridge interface -# ============================================================================== -set_location_assignment PIN_AA9 -to cart_tran_bank0[7] -set_location_assignment PIN_AB8 -to cart_tran_bank0[6] -set_location_assignment PIN_AA8 -to cart_tran_bank0[5] -set_location_assignment PIN_AB7 -to cart_tran_bank0[4] -set_location_assignment PIN_AB6 -to cart_tran_bank0_dir -set_location_assignment PIN_AA10 -to cart_tran_bank1[7] -set_location_assignment PIN_AB10 -to cart_tran_bank1[6] -set_location_assignment PIN_Y10 -to cart_tran_bank1[5] -set_location_assignment PIN_AB11 -to cart_tran_bank1[4] -set_location_assignment PIN_Y11 -to cart_tran_bank1[3] -set_location_assignment PIN_AB12 -to cart_tran_bank1[2] -set_location_assignment PIN_AA12 -to cart_tran_bank1[1] -set_location_assignment PIN_AB13 -to cart_tran_bank1[0] -set_location_assignment PIN_AA13 -to cart_tran_bank1_dir -set_location_assignment PIN_AB15 -to cart_tran_bank2[7] -set_location_assignment PIN_AA15 -to cart_tran_bank2[6] -set_location_assignment PIN_AB17 -to cart_tran_bank2[5] -set_location_assignment PIN_AA17 -to cart_tran_bank2[4] -set_location_assignment PIN_AB18 -to cart_tran_bank2[3] -set_location_assignment PIN_AB20 -to cart_tran_bank2[0] -set_location_assignment PIN_AA19 -to cart_tran_bank2[1] -set_location_assignment PIN_AA18 -to cart_tran_bank2[2] -set_location_assignment PIN_AA14 -to cart_tran_bank2_dir -set_location_assignment PIN_AA20 -to cart_tran_bank3[7] -set_location_assignment PIN_AB21 -to cart_tran_bank3[6] -set_location_assignment PIN_AB22 -to cart_tran_bank3[5] -set_location_assignment PIN_AA22 -to cart_tran_bank3[4] -set_location_assignment PIN_Y21 -to cart_tran_bank3[3] -set_location_assignment PIN_Y22 -to cart_tran_bank3[2] -set_location_assignment PIN_W21 -to cart_tran_bank3[1] -set_location_assignment PIN_W22 -to cart_tran_bank3[0] -set_location_assignment PIN_V21 -to cart_tran_bank3_dir - -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank0[4] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank0[5] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank0[6] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank0[7] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank0_dir -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[0] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[1] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[2] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[3] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[4] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[5] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[6] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[7] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1_dir -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[0] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[1] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[2] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[3] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[4] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[5] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[6] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[7] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2_dir -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[0] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[1] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[2] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[3] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[4] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[5] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[6] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[7] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3_dir - -# ============================================================================== -# GBA CS2#/RES# -# ============================================================================== -set_location_assignment PIN_AB5 -to cart_tran_pin30_dir -set_location_assignment PIN_L8 -to cart_tran_pin30 -set_location_assignment PIN_L17 -to cart_pin30_pwroff_reset - -set_instance_assignment -name IO_STANDARD "1.8 V" -to cart_pin30_pwroff_reset -set_instance_assignment -name IO_STANDARD "1.8 V" -to cart_tran_pin30 -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_pin30_dir - -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cart_pin30_pwroff_reset -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cart_tran_pin30 - -# ============================================================================== -# GBA IRQ/DRQ -# ============================================================================== -set_location_assignment PIN_K9 -to cart_tran_pin31 -set_location_assignment PIN_U22 -to cart_tran_pin31_dir - -set_instance_assignment -name IO_STANDARD "1.8 V" -to cart_tran_pin31 -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_pin31_dir - -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cart_tran_pin31 - -# ============================================================================== -# GBA link port -# ============================================================================== -set_location_assignment PIN_V10 -to port_tran_si -set_location_assignment PIN_V9 -to port_tran_si_dir -set_location_assignment PIN_J11 -to port_tran_so -set_location_assignment PIN_T13 -to port_tran_so_dir -set_location_assignment PIN_AA7 -to port_tran_sck -set_location_assignment PIN_Y9 -to port_tran_sck_dir -set_location_assignment PIN_R9 -to port_tran_sd -set_location_assignment PIN_T9 -to port_tran_sd_dir - -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_si -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_si_dir -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_so_dir -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_sck -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_sck_dir -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_sd -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_sd_dir - -set_instance_assignment -name IO_STANDARD "1.8 V" -to port_tran_so - -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to port_tran_so - -# ============================================================================== -# I/O to 6515D Breakout USB UART -# ============================================================================== -set_location_assignment PIN_K21 -to dbg_tx -set_location_assignment PIN_K22 -to dbg_rx - -set_instance_assignment -name IO_STANDARD "1.8 V" -to dbg_rx -set_instance_assignment -name IO_STANDARD "1.8 V" -to dbg_tx - -set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to dbg_tx - -# ============================================================================== -# Infrared -# ============================================================================== -set_location_assignment PIN_H10 -to port_ir_rx -set_location_assignment PIN_H11 -to port_ir_tx -set_location_assignment PIN_L18 -to port_ir_rx_disable - -set_instance_assignment -name IO_STANDARD "1.8 V" -to port_ir_tx -set_instance_assignment -name IO_STANDARD "1.8 V" -to port_ir_rx -set_instance_assignment -name IO_STANDARD "1.8 V" -to port_ir_rx_disable - -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to port_ir_tx -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to port_ir_rx_disable -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to port_ir_rx - -# ============================================================================== -# RFU internal I2C bus (DNU) -# ============================================================================== -set_location_assignment PIN_M16 -to aux_scl -set_location_assignment PIN_M18 -to aux_sda - -set_instance_assignment -name IO_STANDARD "1.8 V" -to aux_sda -set_instance_assignment -name IO_STANDARD "1.8 V" -to aux_scl - -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to aux_sda -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to aux_scl - -# ============================================================================== -# I/O pads near jtag connector user can solder to -# ============================================================================== -set_location_assignment PIN_M22 -to user1 -set_location_assignment PIN_L22 -to user2 - -set_instance_assignment -name IO_STANDARD "1.8 V" -to user1 -set_instance_assignment -name IO_STANDARD "1.8 V" -to user2 - -# ============================================================================== -# VBlank output to scaler -# ============================================================================== -set_location_assignment PIN_N19 -to vblank - -set_instance_assignment -name IO_STANDARD "1.8 V" -to vblank - -# ============================================================================== -# Video output to the scaler -# ============================================================================== -set_location_assignment PIN_H15 -to scal_audadc -set_location_assignment PIN_K19 -to scal_auddac -set_location_assignment PIN_K17 -to scal_audlrck -set_location_assignment PIN_K16 -to scal_audmclk -set_location_assignment PIN_R17 -to scal_clk -set_location_assignment PIN_N20 -to scal_de -set_location_assignment PIN_P17 -to scal_hs -set_location_assignment PIN_N21 -to scal_skip -set_location_assignment PIN_T15 -to scal_vs -set_location_assignment PIN_R16 -to scal_vid[11] -set_location_assignment PIN_R15 -to scal_vid[10] -set_location_assignment PIN_R22 -to scal_vid[9] -set_location_assignment PIN_T22 -to scal_vid[8] -set_location_assignment PIN_T18 -to scal_vid[7] -set_location_assignment PIN_T19 -to scal_vid[6] -set_location_assignment PIN_T20 -to scal_vid[5] -set_location_assignment PIN_P19 -to scal_vid[4] -set_location_assignment PIN_P18 -to scal_vid[3] -set_location_assignment PIN_N16 -to scal_vid[2] -set_location_assignment PIN_P22 -to scal_vid[1] -set_location_assignment PIN_R21 -to scal_vid[0] - -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_audadc -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_auddac -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_audlrck -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_audmclk -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_clk -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_de -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_hs -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_skip -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[0] -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[10] -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[11] -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[1] -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[2] -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[3] -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[4] -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[5] -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[6] -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[7] -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[8] -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[9] -set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vs - -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_auddac -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_audlrck -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_audmclk -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_clk -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_de -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_hs -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_skip -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[0] -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[10] -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[11] -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[1] -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[2] -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[3] -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[4] -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[5] -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[6] -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[7] -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[8] -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[9] -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vs - -# ============================================================================== -# SDRAM, 512mbit x16 -# ============================================================================== -set_location_assignment PIN_J17 -to dram_a[12] -set_location_assignment PIN_F15 -to dram_a[11] -set_location_assignment PIN_C13 -to dram_a[10] -set_location_assignment PIN_G17 -to dram_a[9] -set_location_assignment PIN_J18 -to dram_a[8] -set_location_assignment PIN_F14 -to dram_a[7] -set_location_assignment PIN_E15 -to dram_a[6] -set_location_assignment PIN_E16 -to dram_a[5] -set_location_assignment PIN_F13 -to dram_a[4] -set_location_assignment PIN_E14 -to dram_a[3] -set_location_assignment PIN_F12 -to dram_a[2] -set_location_assignment PIN_D12 -to dram_a[1] -set_location_assignment PIN_D17 -to dram_a[0] -set_location_assignment PIN_E12 -to dram_ba[1] -set_location_assignment PIN_C16 -to dram_ba[0] -set_location_assignment PIN_K20 -to dram_dq[15] -set_location_assignment PIN_G11 -to dram_dq[14] -set_location_assignment PIN_J19 -to dram_dq[13] -set_location_assignment PIN_H13 -to dram_dq[12] -set_location_assignment PIN_G13 -to dram_dq[11] -set_location_assignment PIN_G16 -to dram_dq[10] -set_location_assignment PIN_G15 -to dram_dq[9] -set_location_assignment PIN_J13 -to dram_dq[8] -set_location_assignment PIN_A12 -to dram_dq[7] -set_location_assignment PIN_A13 -to dram_dq[6] -set_location_assignment PIN_B12 -to dram_dq[5] -set_location_assignment PIN_A14 -to dram_dq[4] -set_location_assignment PIN_B13 -to dram_dq[3] -set_location_assignment PIN_A15 -to dram_dq[2] -set_location_assignment PIN_B15 -to dram_dq[1] -set_location_assignment PIN_C15 -to dram_dq[0] -set_location_assignment PIN_D13 -to dram_dqm[0] -set_location_assignment PIN_H18 -to dram_dqm[1] -set_location_assignment PIN_B16 -to dram_cas_n -set_location_assignment PIN_G18 -to dram_cke -set_location_assignment PIN_G12 -to dram_clk -set_location_assignment PIN_B11 -to dram_ras_n -set_location_assignment PIN_C11 -to dram_we_n - -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[12] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[11] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[10] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[9] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[8] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[7] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[6] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[5] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[4] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[3] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[2] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[1] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[0] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_ba[1] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_ba[0] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[15] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[14] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[13] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[12] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[11] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[10] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[9] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[8] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[7] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[6] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[5] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[4] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[3] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[2] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[1] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[0] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dqm[0] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dqm[1] -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_cas_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_cke -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_clk -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_ras_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_we_n - -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[12] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[11] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[10] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[9] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[8] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[7] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[6] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[5] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[4] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[3] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[2] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[1] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[0] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_ba[1] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_ba[0] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[15] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[14] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[13] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[12] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[11] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[10] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[9] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[8] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[7] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[6] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[5] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[4] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[3] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[2] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[1] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[0] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dqm[0] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dqm[1] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_cas_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_cke -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_ras_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_we_n - -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to dram_clk - -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[0] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[1] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[2] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[3] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[4] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[5] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[6] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[7] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[8] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[9] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[10] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[11] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[12] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[13] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[14] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[15] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[0] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[1] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[2] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[3] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[4] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[5] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[6] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[7] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[8] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[9] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[10] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[11] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[12] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_ba[0] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_ba[1] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dqm[0] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dqm[1] -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_ras_n -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_cas_n -set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_we_n -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[0] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[1] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[2] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[3] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[4] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[5] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[6] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[7] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[8] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[9] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[10] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[11] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[12] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[13] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[14] -set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[15] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[0] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[1] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[2] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[3] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[4] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[5] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[6] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[7] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[8] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[9] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[10] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[11] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[12] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[13] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[14] -set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[15] -set_instance_assignment -name ALLOW_SYNCH_CTRL_USAGE OFF -to *|dram_* - -# ============================================================================== -# Cellular PSRAM 0 - 64mbit x2 dual die per chip -# ============================================================================== -set_location_assignment PIN_H8 -to cram0_a[21] -set_location_assignment PIN_H9 -to cram0_a[20] -set_location_assignment PIN_B7 -to cram0_a[19] -set_location_assignment PIN_B6 -to cram0_a[18] -set_location_assignment PIN_C6 -to cram0_a[17] -set_location_assignment PIN_H6 -to cram0_a[16] -set_location_assignment PIN_J9 -to cram0_dq[15] -set_location_assignment PIN_L7 -to cram0_dq[14] -set_location_assignment PIN_F9 -to cram0_dq[13] -set_location_assignment PIN_E7 -to cram0_dq[12] -set_location_assignment PIN_A8 -to cram0_dq[11] -set_location_assignment PIN_D9 -to cram0_dq[10] -set_location_assignment PIN_A10 -to cram0_dq[9] -set_location_assignment PIN_C9 -to cram0_dq[8] -set_location_assignment PIN_J7 -to cram0_dq[7] -set_location_assignment PIN_G6 -to cram0_dq[6] -set_location_assignment PIN_F10 -to cram0_dq[5] -set_location_assignment PIN_E9 -to cram0_dq[4] -set_location_assignment PIN_D7 -to cram0_dq[3] -set_location_assignment PIN_A9 -to cram0_dq[2] -set_location_assignment PIN_C8 -to cram0_dq[1] -set_location_assignment PIN_B10 -to cram0_dq[0] -set_location_assignment PIN_J8 -to cram0_adv_n -set_location_assignment PIN_B5 -to cram0_ce0_n -set_location_assignment PIN_E10 -to cram0_ce1_n -set_location_assignment PIN_G10 -to cram0_clk -set_location_assignment PIN_F7 -to cram0_cre -set_location_assignment PIN_A5 -to cram0_lb_n -set_location_assignment PIN_D6 -to cram0_oe_n -set_location_assignment PIN_A7 -to cram0_ub_n -set_location_assignment PIN_K7 -to cram0_wait -set_location_assignment PIN_G8 -to cram0_we_n - -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[0] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[1] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[2] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[3] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[4] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[5] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[6] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[7] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[8] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[9] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[10] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[11] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[12] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[13] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[14] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[15] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_a[16] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_a[17] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_a[18] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_a[19] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_a[20] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_a[21] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_adv_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_ce0_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_ce1_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_clk -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_cre -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_lb_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_oe_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_ub_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_wait -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_we_n - -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[0] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[1] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[2] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[3] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[4] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[5] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[6] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[7] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[8] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[9] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[10] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[11] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[12] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[13] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[14] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[15] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_a[16] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_a[17] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_a[18] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_a[19] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_a[20] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_a[21] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_adv_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_ce0_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_ce1_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_cre -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_lb_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_oe_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_ub_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_wait -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_we_n - -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to cram0_clk - -# ============================================================================== -# Cellular PSRAM 1 - 64mbit x2 dual die per chip -# ============================================================================== -set_location_assignment PIN_Y3 -to cram1_a[21] -set_location_assignment PIN_AA2 -to cram1_a[20] -set_location_assignment PIN_L2 -to cram1_a[19] -set_location_assignment PIN_N1 -to cram1_a[18] -set_location_assignment PIN_U1 -to cram1_a[17] -set_location_assignment PIN_U2 -to cram1_a[16] -set_location_assignment PIN_W8 -to cram1_dq[15] -set_location_assignment PIN_U6 -to cram1_dq[14] -set_location_assignment PIN_R7 -to cram1_dq[13] -set_location_assignment PIN_R6 -to cram1_dq[12] -set_location_assignment PIN_P7 -to cram1_dq[11] -set_location_assignment PIN_N6 -to cram1_dq[10] -set_location_assignment PIN_C2 -to cram1_dq[9] -set_location_assignment PIN_D3 -to cram1_dq[8] -set_location_assignment PIN_V6 -to cram1_dq[7] -set_location_assignment PIN_U7 -to cram1_dq[6] -set_location_assignment PIN_M6 -to cram1_dq[5] -set_location_assignment PIN_R5 -to cram1_dq[4] -set_location_assignment PIN_P6 -to cram1_dq[3] -set_location_assignment PIN_E2 -to cram1_dq[2] -set_location_assignment PIN_G2 -to cram1_dq[1] -set_location_assignment PIN_C1 -to cram1_dq[0] -set_location_assignment PIN_U8 -to cram1_adv_n -set_location_assignment PIN_N2 -to cram1_ce0_n -set_location_assignment PIN_T8 -to cram1_ce1_n -set_location_assignment PIN_W2 -to cram1_clk -set_location_assignment PIN_T7 -to cram1_cre -set_location_assignment PIN_L1 -to cram1_lb_n -set_location_assignment PIN_M7 -to cram1_oe_n -set_location_assignment PIN_G1 -to cram1_ub_n -set_location_assignment PIN_W9 -to cram1_wait -set_location_assignment PIN_AA1 -to cram1_we_n - -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[0] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[1] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[2] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[3] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[4] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[5] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[6] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[7] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[8] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[9] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[10] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[11] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[12] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[13] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[14] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[15] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_a[16] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_a[17] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_a[18] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_a[19] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_a[20] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_a[21] -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_adv_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_ce0_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_ce1_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_clk -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_cre -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_lb_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_oe_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_ub_n -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_wait -set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_we_n - -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[0] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[1] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[2] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[3] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[4] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[5] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[6] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[7] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[8] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[9] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[10] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[11] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[12] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[13] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[14] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[15] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_a[16] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_a[17] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_a[18] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_a[19] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_a[20] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_a[21] -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_adv_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_ce0_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_ce1_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_cre -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_lb_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_oe_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_ub_n -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_wait -set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_we_n - -set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to cram1_clk - -# ============================================================================== -# SRAM, 1mbit x16 -# ============================================================================== -set_location_assignment PIN_V16 -to sram_a[16] -set_location_assignment PIN_U12 -to sram_a[15] -set_location_assignment PIN_U15 -to sram_a[14] -set_location_assignment PIN_R10 -to sram_a[13] -set_location_assignment PIN_V14 -to sram_a[12] -set_location_assignment PIN_T10 -to sram_a[11] -set_location_assignment PIN_U11 -to sram_a[10] -set_location_assignment PIN_Y14 -to sram_a[9] -set_location_assignment PIN_U13 -to sram_a[8] -set_location_assignment PIN_Y19 -to sram_a[7] -set_location_assignment PIN_P8 -to sram_a[6] -set_location_assignment PIN_V19 -to sram_a[5] -set_location_assignment PIN_N9 -to sram_a[4] -set_location_assignment PIN_U21 -to sram_a[3] -set_location_assignment PIN_M8 -to sram_a[2] -set_location_assignment PIN_M9 -to sram_a[1] -set_location_assignment PIN_T14 -to sram_a[0] -set_location_assignment PIN_Y15 -to sram_dq[15] -set_location_assignment PIN_W16 -to sram_dq[14] -set_location_assignment PIN_Y16 -to sram_dq[13] -set_location_assignment PIN_Y17 -to sram_dq[12] -set_location_assignment PIN_V20 -to sram_dq[11] -set_location_assignment PIN_V18 -to sram_dq[10] -set_location_assignment PIN_U20 -to sram_dq[9] -set_location_assignment PIN_U16 -to sram_dq[8] -set_location_assignment PIN_R12 -to sram_dq[7] -set_location_assignment PIN_V13 -to sram_dq[6] -set_location_assignment PIN_T12 -to sram_dq[5] -set_location_assignment PIN_W19 -to sram_dq[4] -set_location_assignment PIN_Y20 -to sram_dq[3] -set_location_assignment PIN_P14 -to sram_dq[2] -set_location_assignment PIN_P9 -to sram_dq[1] -set_location_assignment PIN_N8 -to sram_dq[0] -set_location_assignment PIN_U17 -to sram_ub_n -set_location_assignment PIN_R11 -to sram_we_n -set_location_assignment PIN_R14 -to sram_oe_n -set_location_assignment PIN_P12 -to sram_lb_n - -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[0] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[10] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[11] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[12] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[13] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[14] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[15] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[16] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[1] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[2] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[3] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[4] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[5] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[6] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[7] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[8] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[9] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[0] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[10] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[11] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[12] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[13] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[14] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[15] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[1] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[2] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[3] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[4] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[5] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[6] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[7] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[8] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[9] -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_lb_n -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_oe_n -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_ub_n -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_we_n - -# ============================================================================== -# Powerup self test (DO NOT USE) -# ============================================================================== -set_location_assignment PIN_P16 -to vpll_feed -set_location_assignment PIN_U10 -to bist - -set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to bist -set_instance_assignment -name IO_STANDARD "1.8 V" -to vpll_feed - +# ============================================================================== +# Clock Circuitry +# ============================================================================== +set_location_assignment PIN_V15 -to clk_74a +set_location_assignment PIN_H16 -to clk_74b + +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to clk_74a +set_instance_assignment -name IO_STANDARD "1.8 V" -to clk_74b + +# ============================================================================== +# SPI bus with Aristotle +# ============================================================================== +set_location_assignment PIN_T17 -to bridge_spiclk +set_location_assignment PIN_M21 -to bridge_spimiso +set_location_assignment PIN_M20 -to bridge_spimosi +set_location_assignment PIN_L19 -to bridge_1wire +set_location_assignment PIN_H14 -to bridge_spiss + +set_instance_assignment -name IO_STANDARD "1.8 V" -to bridge_spiclk +set_instance_assignment -name IO_STANDARD "1.8 V" -to bridge_spimiso +set_instance_assignment -name IO_STANDARD "1.8 V" -to bridge_spimosi +set_instance_assignment -name IO_STANDARD "1.8 V" -to bridge_1wire +set_instance_assignment -name IO_STANDARD "1.8 V" -to bridge_spiss + +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to bridge_spiclk +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to bridge_spimiso +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to bridge_spimosi +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to bridge_1wire + +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to bridge_spiclk +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to bridge_spimiso +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to bridge_spimosi +set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to bridge_1wire + +# ============================================================================== +# Cartridge interface +# ============================================================================== +set_location_assignment PIN_AA9 -to cart_tran_bank0[7] +set_location_assignment PIN_AB8 -to cart_tran_bank0[6] +set_location_assignment PIN_AA8 -to cart_tran_bank0[5] +set_location_assignment PIN_AB7 -to cart_tran_bank0[4] +set_location_assignment PIN_AB6 -to cart_tran_bank0_dir +set_location_assignment PIN_AA10 -to cart_tran_bank1[7] +set_location_assignment PIN_AB10 -to cart_tran_bank1[6] +set_location_assignment PIN_Y10 -to cart_tran_bank1[5] +set_location_assignment PIN_AB11 -to cart_tran_bank1[4] +set_location_assignment PIN_Y11 -to cart_tran_bank1[3] +set_location_assignment PIN_AB12 -to cart_tran_bank1[2] +set_location_assignment PIN_AA12 -to cart_tran_bank1[1] +set_location_assignment PIN_AB13 -to cart_tran_bank1[0] +set_location_assignment PIN_AA13 -to cart_tran_bank1_dir +set_location_assignment PIN_AB15 -to cart_tran_bank2[7] +set_location_assignment PIN_AA15 -to cart_tran_bank2[6] +set_location_assignment PIN_AB17 -to cart_tran_bank2[5] +set_location_assignment PIN_AA17 -to cart_tran_bank2[4] +set_location_assignment PIN_AB18 -to cart_tran_bank2[3] +set_location_assignment PIN_AB20 -to cart_tran_bank2[0] +set_location_assignment PIN_AA19 -to cart_tran_bank2[1] +set_location_assignment PIN_AA18 -to cart_tran_bank2[2] +set_location_assignment PIN_AA14 -to cart_tran_bank2_dir +set_location_assignment PIN_AA20 -to cart_tran_bank3[7] +set_location_assignment PIN_AB21 -to cart_tran_bank3[6] +set_location_assignment PIN_AB22 -to cart_tran_bank3[5] +set_location_assignment PIN_AA22 -to cart_tran_bank3[4] +set_location_assignment PIN_Y21 -to cart_tran_bank3[3] +set_location_assignment PIN_Y22 -to cart_tran_bank3[2] +set_location_assignment PIN_W21 -to cart_tran_bank3[1] +set_location_assignment PIN_W22 -to cart_tran_bank3[0] +set_location_assignment PIN_V21 -to cart_tran_bank3_dir + +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank0[4] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank0[5] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank0[6] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank0[7] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank0_dir +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[0] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[1] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[2] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[3] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[4] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[5] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[6] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1[7] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank1_dir +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[0] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[1] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[2] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[3] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[4] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[5] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[6] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2[7] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank2_dir +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[0] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[1] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[2] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[3] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[4] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[5] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[6] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3[7] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_bank3_dir + +# ============================================================================== +# GBA CS2#/RES# +# ============================================================================== +set_location_assignment PIN_AB5 -to cart_tran_pin30_dir +set_location_assignment PIN_L8 -to cart_tran_pin30 +set_location_assignment PIN_L17 -to cart_pin30_pwroff_reset + +set_instance_assignment -name IO_STANDARD "1.8 V" -to cart_pin30_pwroff_reset +set_instance_assignment -name IO_STANDARD "1.8 V" -to cart_tran_pin30 +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_pin30_dir + +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cart_pin30_pwroff_reset +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cart_tran_pin30 + +# ============================================================================== +# GBA IRQ/DRQ +# ============================================================================== +set_location_assignment PIN_K9 -to cart_tran_pin31 +set_location_assignment PIN_U22 -to cart_tran_pin31_dir + +set_instance_assignment -name IO_STANDARD "1.8 V" -to cart_tran_pin31 +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to cart_tran_pin31_dir + +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cart_tran_pin31 + +# ============================================================================== +# GBA link port +# ============================================================================== +set_location_assignment PIN_V10 -to port_tran_si +set_location_assignment PIN_V9 -to port_tran_si_dir +set_location_assignment PIN_J11 -to port_tran_so +set_location_assignment PIN_T13 -to port_tran_so_dir +set_location_assignment PIN_AA7 -to port_tran_sck +set_location_assignment PIN_Y9 -to port_tran_sck_dir +set_location_assignment PIN_R9 -to port_tran_sd +set_location_assignment PIN_T9 -to port_tran_sd_dir + +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_si +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_si_dir +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_so_dir +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_sck +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_sck_dir +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_sd +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to port_tran_sd_dir + +set_instance_assignment -name IO_STANDARD "1.8 V" -to port_tran_so + +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to port_tran_so + +# ============================================================================== +# I/O to 6515D Breakout USB UART +# ============================================================================== +set_location_assignment PIN_K21 -to dbg_tx +set_location_assignment PIN_K22 -to dbg_rx + +set_instance_assignment -name IO_STANDARD "1.8 V" -to dbg_rx +set_instance_assignment -name IO_STANDARD "1.8 V" -to dbg_tx + +set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to dbg_tx + +# ============================================================================== +# Infrared +# ============================================================================== +set_location_assignment PIN_H10 -to port_ir_rx +set_location_assignment PIN_H11 -to port_ir_tx +set_location_assignment PIN_L18 -to port_ir_rx_disable + +set_instance_assignment -name IO_STANDARD "1.8 V" -to port_ir_tx +set_instance_assignment -name IO_STANDARD "1.8 V" -to port_ir_rx +set_instance_assignment -name IO_STANDARD "1.8 V" -to port_ir_rx_disable + +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to port_ir_tx +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to port_ir_rx_disable +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to port_ir_rx + +# ============================================================================== +# RFU internal I2C bus (DNU) +# ============================================================================== +set_location_assignment PIN_M16 -to aux_scl +set_location_assignment PIN_M18 -to aux_sda + +set_instance_assignment -name IO_STANDARD "1.8 V" -to aux_sda +set_instance_assignment -name IO_STANDARD "1.8 V" -to aux_scl + +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to aux_sda +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to aux_scl + +# ============================================================================== +# I/O pads near jtag connector user can solder to +# ============================================================================== +set_location_assignment PIN_M22 -to user1 +set_location_assignment PIN_L22 -to user2 + +set_instance_assignment -name IO_STANDARD "1.8 V" -to user1 +set_instance_assignment -name IO_STANDARD "1.8 V" -to user2 + +# ============================================================================== +# VBlank output to scaler +# ============================================================================== +set_location_assignment PIN_N19 -to vblank + +set_instance_assignment -name IO_STANDARD "1.8 V" -to vblank + +# ============================================================================== +# Video output to the scaler +# ============================================================================== +set_location_assignment PIN_H15 -to scal_audadc +set_location_assignment PIN_K19 -to scal_auddac +set_location_assignment PIN_K17 -to scal_audlrck +set_location_assignment PIN_K16 -to scal_audmclk +set_location_assignment PIN_R17 -to scal_clk +set_location_assignment PIN_N20 -to scal_de +set_location_assignment PIN_P17 -to scal_hs +set_location_assignment PIN_N21 -to scal_skip +set_location_assignment PIN_T15 -to scal_vs +set_location_assignment PIN_R16 -to scal_vid[11] +set_location_assignment PIN_R15 -to scal_vid[10] +set_location_assignment PIN_R22 -to scal_vid[9] +set_location_assignment PIN_T22 -to scal_vid[8] +set_location_assignment PIN_T18 -to scal_vid[7] +set_location_assignment PIN_T19 -to scal_vid[6] +set_location_assignment PIN_T20 -to scal_vid[5] +set_location_assignment PIN_P19 -to scal_vid[4] +set_location_assignment PIN_P18 -to scal_vid[3] +set_location_assignment PIN_N16 -to scal_vid[2] +set_location_assignment PIN_P22 -to scal_vid[1] +set_location_assignment PIN_R21 -to scal_vid[0] + +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_audadc +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_auddac +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_audlrck +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_audmclk +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_clk +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_de +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_hs +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_skip +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[0] +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[10] +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[11] +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[1] +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[2] +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[3] +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[4] +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[5] +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[6] +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[7] +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[8] +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vid[9] +set_instance_assignment -name IO_STANDARD "1.8 V" -to scal_vs + +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_auddac +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_audlrck +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_audmclk +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_clk +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_de +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_hs +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_skip +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[0] +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[10] +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[11] +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[1] +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[2] +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[3] +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[4] +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[5] +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[6] +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[7] +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[8] +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vid[9] +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to scal_vs + +# ============================================================================== +# SDRAM, 512mbit x16 +# ============================================================================== +set_location_assignment PIN_J17 -to dram_a[12] +set_location_assignment PIN_F15 -to dram_a[11] +set_location_assignment PIN_C13 -to dram_a[10] +set_location_assignment PIN_G17 -to dram_a[9] +set_location_assignment PIN_J18 -to dram_a[8] +set_location_assignment PIN_F14 -to dram_a[7] +set_location_assignment PIN_E15 -to dram_a[6] +set_location_assignment PIN_E16 -to dram_a[5] +set_location_assignment PIN_F13 -to dram_a[4] +set_location_assignment PIN_E14 -to dram_a[3] +set_location_assignment PIN_F12 -to dram_a[2] +set_location_assignment PIN_D12 -to dram_a[1] +set_location_assignment PIN_D17 -to dram_a[0] +set_location_assignment PIN_E12 -to dram_ba[1] +set_location_assignment PIN_C16 -to dram_ba[0] +set_location_assignment PIN_K20 -to dram_dq[15] +set_location_assignment PIN_G11 -to dram_dq[14] +set_location_assignment PIN_J19 -to dram_dq[13] +set_location_assignment PIN_H13 -to dram_dq[12] +set_location_assignment PIN_G13 -to dram_dq[11] +set_location_assignment PIN_G16 -to dram_dq[10] +set_location_assignment PIN_G15 -to dram_dq[9] +set_location_assignment PIN_J13 -to dram_dq[8] +set_location_assignment PIN_A12 -to dram_dq[7] +set_location_assignment PIN_A13 -to dram_dq[6] +set_location_assignment PIN_B12 -to dram_dq[5] +set_location_assignment PIN_A14 -to dram_dq[4] +set_location_assignment PIN_B13 -to dram_dq[3] +set_location_assignment PIN_A15 -to dram_dq[2] +set_location_assignment PIN_B15 -to dram_dq[1] +set_location_assignment PIN_C15 -to dram_dq[0] +set_location_assignment PIN_D13 -to dram_dqm[0] +set_location_assignment PIN_H18 -to dram_dqm[1] +set_location_assignment PIN_B16 -to dram_cas_n +set_location_assignment PIN_G18 -to dram_cke +set_location_assignment PIN_G12 -to dram_clk +set_location_assignment PIN_B11 -to dram_ras_n +set_location_assignment PIN_C11 -to dram_we_n + +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[12] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[11] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[10] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[9] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[8] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[7] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[6] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[5] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[4] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[3] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[2] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[1] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_a[0] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_ba[1] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_ba[0] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[15] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[14] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[13] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[12] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[11] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[10] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[9] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[8] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[7] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[6] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[5] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[4] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[3] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[2] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[1] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dq[0] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dqm[0] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_dqm[1] +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_cas_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_cke +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_clk +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_ras_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to dram_we_n + +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[12] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[11] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[10] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[9] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[8] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[7] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[6] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[5] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[4] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[3] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[2] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_a[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_ba[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_ba[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[15] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[14] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[13] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[12] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[11] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[10] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[9] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[8] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[7] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[6] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[5] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[4] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[3] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[2] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dq[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dqm[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_dqm[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_cas_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_cke +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_ras_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to dram_we_n + +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to dram_clk + +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[2] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[3] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[4] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[5] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[6] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[7] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[8] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[9] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[10] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[11] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[12] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[13] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[14] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dq[15] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[2] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[3] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[4] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[5] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[6] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[7] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[8] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[9] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[10] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[11] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_a[12] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_ba[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_ba[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dqm[0] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_dqm[1] +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_ras_n +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_cas_n +set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to dram_we_n +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[0] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[1] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[2] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[3] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[4] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[5] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[6] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[7] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[8] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[9] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[10] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[11] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[12] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[13] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[14] +set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to dram_dq[15] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[0] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[1] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[2] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[3] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[4] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[5] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[6] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[7] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[8] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[9] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[10] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[11] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[12] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[13] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[14] +set_instance_assignment -name FAST_INPUT_REGISTER ON -to dram_dq[15] +set_instance_assignment -name ALLOW_SYNCH_CTRL_USAGE OFF -to *|dram_* + +# ============================================================================== +# Cellular PSRAM 0 - 64mbit x2 dual die per chip +# ============================================================================== +set_location_assignment PIN_H8 -to cram0_a[21] +set_location_assignment PIN_H9 -to cram0_a[20] +set_location_assignment PIN_B7 -to cram0_a[19] +set_location_assignment PIN_B6 -to cram0_a[18] +set_location_assignment PIN_C6 -to cram0_a[17] +set_location_assignment PIN_H6 -to cram0_a[16] +set_location_assignment PIN_J9 -to cram0_dq[15] +set_location_assignment PIN_L7 -to cram0_dq[14] +set_location_assignment PIN_F9 -to cram0_dq[13] +set_location_assignment PIN_E7 -to cram0_dq[12] +set_location_assignment PIN_A8 -to cram0_dq[11] +set_location_assignment PIN_D9 -to cram0_dq[10] +set_location_assignment PIN_A10 -to cram0_dq[9] +set_location_assignment PIN_C9 -to cram0_dq[8] +set_location_assignment PIN_J7 -to cram0_dq[7] +set_location_assignment PIN_G6 -to cram0_dq[6] +set_location_assignment PIN_F10 -to cram0_dq[5] +set_location_assignment PIN_E9 -to cram0_dq[4] +set_location_assignment PIN_D7 -to cram0_dq[3] +set_location_assignment PIN_A9 -to cram0_dq[2] +set_location_assignment PIN_C8 -to cram0_dq[1] +set_location_assignment PIN_B10 -to cram0_dq[0] +set_location_assignment PIN_J8 -to cram0_adv_n +set_location_assignment PIN_B5 -to cram0_ce0_n +set_location_assignment PIN_E10 -to cram0_ce1_n +set_location_assignment PIN_G10 -to cram0_clk +set_location_assignment PIN_F7 -to cram0_cre +set_location_assignment PIN_A5 -to cram0_lb_n +set_location_assignment PIN_D6 -to cram0_oe_n +set_location_assignment PIN_A7 -to cram0_ub_n +set_location_assignment PIN_K7 -to cram0_wait +set_location_assignment PIN_G8 -to cram0_we_n + +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[0] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[1] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[2] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[3] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[4] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[5] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[6] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[7] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[8] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[9] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[10] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[11] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[12] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[13] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[14] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_dq[15] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_a[16] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_a[17] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_a[18] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_a[19] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_a[20] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_a[21] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_adv_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_ce0_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_ce1_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_clk +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_cre +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_lb_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_oe_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_ub_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_wait +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram0_we_n + +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[2] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[3] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[4] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[5] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[6] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[7] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[8] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[9] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[10] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[11] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[12] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[13] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[14] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_dq[15] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_a[16] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_a[17] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_a[18] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_a[19] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_a[20] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_a[21] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_adv_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_ce0_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_ce1_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_cre +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_lb_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_oe_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_ub_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_wait +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram0_we_n + +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to cram0_clk + +# ============================================================================== +# Cellular PSRAM 1 - 64mbit x2 dual die per chip +# ============================================================================== +set_location_assignment PIN_Y3 -to cram1_a[21] +set_location_assignment PIN_AA2 -to cram1_a[20] +set_location_assignment PIN_L2 -to cram1_a[19] +set_location_assignment PIN_N1 -to cram1_a[18] +set_location_assignment PIN_U1 -to cram1_a[17] +set_location_assignment PIN_U2 -to cram1_a[16] +set_location_assignment PIN_W8 -to cram1_dq[15] +set_location_assignment PIN_U6 -to cram1_dq[14] +set_location_assignment PIN_R7 -to cram1_dq[13] +set_location_assignment PIN_R6 -to cram1_dq[12] +set_location_assignment PIN_P7 -to cram1_dq[11] +set_location_assignment PIN_N6 -to cram1_dq[10] +set_location_assignment PIN_C2 -to cram1_dq[9] +set_location_assignment PIN_D3 -to cram1_dq[8] +set_location_assignment PIN_V6 -to cram1_dq[7] +set_location_assignment PIN_U7 -to cram1_dq[6] +set_location_assignment PIN_M6 -to cram1_dq[5] +set_location_assignment PIN_R5 -to cram1_dq[4] +set_location_assignment PIN_P6 -to cram1_dq[3] +set_location_assignment PIN_E2 -to cram1_dq[2] +set_location_assignment PIN_G2 -to cram1_dq[1] +set_location_assignment PIN_C1 -to cram1_dq[0] +set_location_assignment PIN_U8 -to cram1_adv_n +set_location_assignment PIN_N2 -to cram1_ce0_n +set_location_assignment PIN_T8 -to cram1_ce1_n +set_location_assignment PIN_W2 -to cram1_clk +set_location_assignment PIN_T7 -to cram1_cre +set_location_assignment PIN_L1 -to cram1_lb_n +set_location_assignment PIN_M7 -to cram1_oe_n +set_location_assignment PIN_G1 -to cram1_ub_n +set_location_assignment PIN_W9 -to cram1_wait +set_location_assignment PIN_AA1 -to cram1_we_n + +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[0] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[1] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[2] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[3] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[4] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[5] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[6] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[7] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[8] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[9] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[10] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[11] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[12] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[13] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[14] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_dq[15] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_a[16] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_a[17] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_a[18] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_a[19] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_a[20] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_a[21] +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_adv_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_ce0_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_ce1_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_clk +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_cre +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_lb_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_oe_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_ub_n +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_wait +set_instance_assignment -name IO_STANDARD "1.8 V" -to cram1_we_n + +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[0] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[1] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[2] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[3] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[4] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[5] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[6] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[7] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[8] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[9] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[10] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[11] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[12] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[13] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[14] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_dq[15] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_a[16] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_a[17] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_a[18] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_a[19] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_a[20] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_a[21] +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_adv_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_ce0_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_ce1_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_cre +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_lb_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_oe_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_ub_n +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_wait +set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to cram1_we_n + +set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to cram1_clk + +# ============================================================================== +# SRAM, 1mbit x16 +# ============================================================================== +set_location_assignment PIN_V16 -to sram_a[16] +set_location_assignment PIN_U12 -to sram_a[15] +set_location_assignment PIN_U15 -to sram_a[14] +set_location_assignment PIN_R10 -to sram_a[13] +set_location_assignment PIN_V14 -to sram_a[12] +set_location_assignment PIN_T10 -to sram_a[11] +set_location_assignment PIN_U11 -to sram_a[10] +set_location_assignment PIN_Y14 -to sram_a[9] +set_location_assignment PIN_U13 -to sram_a[8] +set_location_assignment PIN_Y19 -to sram_a[7] +set_location_assignment PIN_P8 -to sram_a[6] +set_location_assignment PIN_V19 -to sram_a[5] +set_location_assignment PIN_N9 -to sram_a[4] +set_location_assignment PIN_U21 -to sram_a[3] +set_location_assignment PIN_M8 -to sram_a[2] +set_location_assignment PIN_M9 -to sram_a[1] +set_location_assignment PIN_T14 -to sram_a[0] +set_location_assignment PIN_Y15 -to sram_dq[15] +set_location_assignment PIN_W16 -to sram_dq[14] +set_location_assignment PIN_Y16 -to sram_dq[13] +set_location_assignment PIN_Y17 -to sram_dq[12] +set_location_assignment PIN_V20 -to sram_dq[11] +set_location_assignment PIN_V18 -to sram_dq[10] +set_location_assignment PIN_U20 -to sram_dq[9] +set_location_assignment PIN_U16 -to sram_dq[8] +set_location_assignment PIN_R12 -to sram_dq[7] +set_location_assignment PIN_V13 -to sram_dq[6] +set_location_assignment PIN_T12 -to sram_dq[5] +set_location_assignment PIN_W19 -to sram_dq[4] +set_location_assignment PIN_Y20 -to sram_dq[3] +set_location_assignment PIN_P14 -to sram_dq[2] +set_location_assignment PIN_P9 -to sram_dq[1] +set_location_assignment PIN_N8 -to sram_dq[0] +set_location_assignment PIN_U17 -to sram_ub_n +set_location_assignment PIN_R11 -to sram_we_n +set_location_assignment PIN_R14 -to sram_oe_n +set_location_assignment PIN_P12 -to sram_lb_n + +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[0] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[10] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[11] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[12] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[13] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[14] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[15] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[16] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[1] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[2] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[3] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[4] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[5] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[6] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[7] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[8] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_a[9] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[0] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[10] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[11] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[12] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[13] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[14] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[15] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[1] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[2] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[3] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[4] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[5] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[6] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[7] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[8] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_dq[9] +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_lb_n +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_oe_n +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_ub_n +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to sram_we_n + +# ============================================================================== +# Powerup self test (DO NOT USE) +# ============================================================================== +set_location_assignment PIN_P16 -to vpll_feed +set_location_assignment PIN_U10 -to bist + +set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to bist +set_instance_assignment -name IO_STANDARD "1.8 V" -to vpll_feed + set_instance_assignment -name OUTPUT_TERMINATION "SERIES 50 OHM WITHOUT CALIBRATION" -to vpll_feed \ No newline at end of file diff --git a/platform/pocket/bsp/pocket/sys_assign.tcl b/platform/pocket/bsp/pocket/sys_assign.tcl index 324f452..c9dc9cc 100644 --- a/platform/pocket/bsp/pocket/sys_assign.tcl +++ b/platform/pocket/bsp/pocket/sys_assign.tcl @@ -1,71 +1,71 @@ -# ============================================================================== -# SPDX-License-Identifier: CC0-1.0 -# SPDX-FileType: SOURCE -# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors -# ============================================================================== -# -# Platform Global/Location/Instance Assignments -# -# ============================================================================== -# Hardware Information -# ============================================================================== -set_global_assignment -name FAMILY "Cyclone V" -set_global_assignment -name DEVICE 5CEBA4F23C8 -set_global_assignment -name DEVICE_FILTER_PACKAGE FBGA -set_global_assignment -name DEVICE_FILTER_PIN_COUNT 484 -set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8 - -# ============================================================================== -# Hardware Parameters -# ============================================================================== -set_parameter -name NSX_DEVICE_ID "pocket" -set_parameter -name NSX_DEVICE_NAME "Analogue Pocket" -set_parameter -name NSX_DEVICE_PLATFORM "Intel" -set_parameter -name NSX_DEVICE_MAKER "Analogue" -set_parameter -name NSX_DEVICE_USE_HPS OFF - -# ============================================================================== -# Setup BSP -# ============================================================================== -set_global_assignment -name SOURCE_TCL_SCRIPT_FILE "../platform/pocket/bsp/setup.tcl" - -# ============================================================================== -# Classic Timing Assignments -# ============================================================================== -set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 -set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 - -# ============================================================================== -# Assembler Assignments -# ============================================================================== -set_global_assignment -name GENERATE_RBF_FILE ON -set_global_assignment -name USE_CONFIGURATION_DEVICE ON -set_global_assignment -name ENABLE_OCT_DONE OFF - -# ============================================================================== -# Fitter Assignments -# ============================================================================== -set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF -set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF -set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "PASSIVE SERIAL" -set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_100MHZ - -# ============================================================================== -# 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 - -# ============================================================================== -# Scripts -# ============================================================================== -set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:$PLATFORM_ROOT/scripts/pre_flow.tcl" -set_global_assignment -name POST_FLOW_SCRIPT_FILE "quartus_sh:$PLATFORM_ROOT/scripts/post_flow.tcl" +# ============================================================================== +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileType: SOURCE +# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors +# ============================================================================== +# +# Platform Global/Location/Instance Assignments +# +# ============================================================================== +# Hardware Information +# ============================================================================== +set_global_assignment -name FAMILY "Cyclone V" +set_global_assignment -name DEVICE 5CEBA4F23C8 +set_global_assignment -name DEVICE_FILTER_PACKAGE FBGA +set_global_assignment -name DEVICE_FILTER_PIN_COUNT 484 +set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8 + +# ============================================================================== +# Hardware Parameters +# ============================================================================== +set_parameter -name NSX_DEVICE_ID "pocket" +set_parameter -name NSX_DEVICE_NAME "Analogue Pocket" +set_parameter -name NSX_DEVICE_PLATFORM "Intel" +set_parameter -name NSX_DEVICE_MAKER "Analogue" +set_parameter -name NSX_DEVICE_USE_HPS OFF + +# ============================================================================== +# Setup BSP +# ============================================================================== +set_global_assignment -name SOURCE_TCL_SCRIPT_FILE "../platform/pocket/bsp/setup.tcl" + +# ============================================================================== +# Classic Timing Assignments +# ============================================================================== +set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 +set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 + +# ============================================================================== +# Assembler Assignments +# ============================================================================== +set_global_assignment -name GENERATE_RBF_FILE ON +set_global_assignment -name USE_CONFIGURATION_DEVICE ON +set_global_assignment -name ENABLE_OCT_DONE OFF + +# ============================================================================== +# Fitter Assignments +# ============================================================================== +set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF +set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF +set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "PASSIVE SERIAL" +set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_100MHZ + +# ============================================================================== +# 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 + +# ============================================================================== +# Scripts +# ============================================================================== +set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:$PLATFORM_ROOT/scripts/pre_flow.tcl" +set_global_assignment -name POST_FLOW_SCRIPT_FILE "quartus_sh:$PLATFORM_ROOT/scripts/post_flow.tcl" diff --git a/platform/pocket/bsp/pocket/sys_constr.sdc b/platform/pocket/bsp/pocket/sys_constr.sdc index a09e2ce..80a12ef 100644 --- a/platform/pocket/bsp/pocket/sys_constr.sdc +++ b/platform/pocket/bsp/pocket/sys_constr.sdc @@ -1,100 +1,100 @@ -# ============================================================================== -# Quartus Prime Synopsys Design Constraint File -# Generated by OpenGateware - Gateman CLI v0.1.0 -# ============================================================================== -# Analogue Pocket SDC settings -# -# Do not edit this file -# Add your own constraints in the sdc in the project directory -# ============================================================================== -# -# DEVICE "5CEBA4F23C8" -# -# ============================================================================== -# Time Information -# ============================================================================== -set_time_format -unit ns -decimal_places 3 - -# ============================================================================== -# Create Clock -# ============================================================================== -create_clock -name clk_74a -period 13.468 [get_ports clk_74a] -create_clock -name clk_74b -period 13.468 [get_ports clk_74b] -create_clock -name bridge_spiclk -period 13.468 [get_ports bridge_spiclk] - -# ============================================================================== -# Create Generated Clock -# ============================================================================== -derive_pll_clocks - -# ============================================================================== -# Set Clock Latency -# ============================================================================== - -# ============================================================================== -# Set Clock Uncertainty -# ============================================================================== -derive_clock_uncertainty - -# ============================================================================== -# Set Input Delay -# ============================================================================== - -# ============================================================================== -# Set Output Delay -# ============================================================================== -# tDH, hold time, spec is 0.8ns -set_output_delay -clock dram_clk -min -0.8 [get_ports {dram_a[*] dram_ba[*] dram_cke dram_dqm[*] dram_dq[*] dram_ras_n dram_cas_n dram_we_n}] -# tDS, setup time, spec is 1.5ns -set_output_delay -clock dram_clk -max 1.5 [get_ports {dram_a[*] dram_ba[*] dram_cke dram_dqm[*] dram_dq[*] dram_ras_n dram_cas_n dram_we_n}] - -# ============================================================================== -# Set Clock Groups -# ============================================================================== -set_clock_groups -asynchronous \ - -group { bridge_spiclk } \ - -group { clk_74a } \ - -group { clk_74b } \ - -group { ic|core_pll|core_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk } \ - -group { ic|core_pll|core_pll_inst|altera_pll_i|general[1].gpll~PLL_OUTPUT_COUNTER|divclk } \ - -group { ic|core_pll|core_pll_inst|altera_pll_i|general[2].gpll~PLL_OUTPUT_COUNTER|divclk } \ - -group { ic|core_pll|core_pll_inst|altera_pll_i|general[3].gpll~PLL_OUTPUT_COUNTER|divclk } \ - -group { ic|pocket_audio_mixer|audio_pll|mf_audio_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk } \ - -group { ic|pocket_audio_mixer|audio_pll|mf_audio_pll_inst|altera_pll_i|general[1].gpll~PLL_OUTPUT_COUNTER|divclk } - -# ============================================================================== -# Set False Path -# ============================================================================== -set_false_path -from [get_ports {bridge_1wire}] -set_false_path -from [get_ports {bridge_spimiso}] -set_false_path -from [get_ports {bridge_spimosi}] -set_false_path -from [get_ports {bridge_spiss}] - -set_false_path -to [get_ports {bridge_1wire}] -set_false_path -to [get_ports {bridge_spimiso}] -set_false_path -to [get_ports {bridge_spimosi}] -set_false_path -to [get_ports {scal_auddac}] -set_false_path -to [get_ports {scal_audlrck}] -set_false_path -to [get_ports {scal_audmclk}] -set_false_path -to [get_ports {scal_clk}] -set_false_path -to [get_ports {scal_de}] -set_false_path -to [get_ports {scal_hs}] -set_false_path -to [get_ports {scal_skip}] -set_false_path -to [get_ports {scal_vid[*]}] -set_false_path -to [get_ports {scal_vs}] - -# ============================================================================== -# Set Multicycle Path -# ============================================================================== - -# ============================================================================== -# Set Maximum Delay -# ============================================================================== - -# ============================================================================== -# Set Minimum Delay -# ============================================================================== - -# ============================================================================== -# Set Input Transition -# ============================================================================== +# ============================================================================== +# Quartus Prime Synopsys Design Constraint File +# Generated by OpenGateware - Gateman CLI v0.1.0 +# ============================================================================== +# Analogue Pocket SDC settings +# +# Do not edit this file +# Add your own constraints in the sdc in the project directory +# ============================================================================== +# +# DEVICE "5CEBA4F23C8" +# +# ============================================================================== +# Time Information +# ============================================================================== +set_time_format -unit ns -decimal_places 3 + +# ============================================================================== +# Create Clock +# ============================================================================== +create_clock -name clk_74a -period 13.468 [get_ports clk_74a] +create_clock -name clk_74b -period 13.468 [get_ports clk_74b] +create_clock -name bridge_spiclk -period 13.468 [get_ports bridge_spiclk] + +# ============================================================================== +# Create Generated Clock +# ============================================================================== +derive_pll_clocks + +# ============================================================================== +# Set Clock Latency +# ============================================================================== + +# ============================================================================== +# Set Clock Uncertainty +# ============================================================================== +derive_clock_uncertainty + +# ============================================================================== +# Set Input Delay +# ============================================================================== + +# ============================================================================== +# Set Output Delay +# ============================================================================== +# tDH, hold time, spec is 0.8ns +set_output_delay -clock dram_clk -min -0.8 [get_ports {dram_a[*] dram_ba[*] dram_cke dram_dqm[*] dram_dq[*] dram_ras_n dram_cas_n dram_we_n}] +# tDS, setup time, spec is 1.5ns +set_output_delay -clock dram_clk -max 1.5 [get_ports {dram_a[*] dram_ba[*] dram_cke dram_dqm[*] dram_dq[*] dram_ras_n dram_cas_n dram_we_n}] + +# ============================================================================== +# Set Clock Groups +# ============================================================================== +set_clock_groups -asynchronous \ + -group { bridge_spiclk } \ + -group { clk_74a } \ + -group { clk_74b } \ + -group { ic|core_pll|core_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk } \ + -group { ic|core_pll|core_pll_inst|altera_pll_i|general[1].gpll~PLL_OUTPUT_COUNTER|divclk } \ + -group { ic|core_pll|core_pll_inst|altera_pll_i|general[2].gpll~PLL_OUTPUT_COUNTER|divclk } \ + -group { ic|core_pll|core_pll_inst|altera_pll_i|general[3].gpll~PLL_OUTPUT_COUNTER|divclk } \ + -group { ic|pocket_audio_mixer|audio_pll|mf_audio_pll_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk } \ + -group { ic|pocket_audio_mixer|audio_pll|mf_audio_pll_inst|altera_pll_i|general[1].gpll~PLL_OUTPUT_COUNTER|divclk } + +# ============================================================================== +# Set False Path +# ============================================================================== +set_false_path -from [get_ports {bridge_1wire}] +set_false_path -from [get_ports {bridge_spimiso}] +set_false_path -from [get_ports {bridge_spimosi}] +set_false_path -from [get_ports {bridge_spiss}] + +set_false_path -to [get_ports {bridge_1wire}] +set_false_path -to [get_ports {bridge_spimiso}] +set_false_path -to [get_ports {bridge_spimosi}] +set_false_path -to [get_ports {scal_auddac}] +set_false_path -to [get_ports {scal_audlrck}] +set_false_path -to [get_ports {scal_audmclk}] +set_false_path -to [get_ports {scal_clk}] +set_false_path -to [get_ports {scal_de}] +set_false_path -to [get_ports {scal_hs}] +set_false_path -to [get_ports {scal_skip}] +set_false_path -to [get_ports {scal_vid[*]}] +set_false_path -to [get_ports {scal_vs}] + +# ============================================================================== +# Set Multicycle Path +# ============================================================================== + +# ============================================================================== +# Set Maximum Delay +# ============================================================================== + +# ============================================================================== +# Set Minimum Delay +# ============================================================================== + +# ============================================================================== +# Set Input Transition +# ============================================================================== diff --git a/platform/pocket/bsp/setup.tcl b/platform/pocket/bsp/setup.tcl index 9a5e63b..630502a 100644 --- a/platform/pocket/bsp/setup.tcl +++ b/platform/pocket/bsp/setup.tcl @@ -1,55 +1,55 @@ -# ============================================================================== -# SPDX-License-Identifier: CC0-1.0 -# SPDX-FileType: SOURCE -# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors -# ============================================================================== - -# ============================================================================== -# Parameters Assignments -# ============================================================================== -set FRAMEWORK_ID "pocket" -set FRAMEWORK_NAME "Analogue Pocket" -set DEVICE_FAMILY [get_global_assignment -name FAMILY] -set DEVICE_ID [get_parameter -name NSX_DEVICE_ID] - -set BUILD_ROOT "../.build" -set PKG_ROOT "../pkg" -set RTL_ROOT "../rtl" -set PLATFORM_ROOT "../platform/$FRAMEWORK_ID" -set TARGET_ROOT "../target/$FRAMEWORK_ID" -set BSP_ROOT "$PLATFORM_ROOT/bsp/$DEVICE_ID" - -# ============================================================================== -# System and Core Top Level, Pinout and Constrains -# ============================================================================== -set_global_assignment -name SYSTEMVERILOG_FILE "$BSP_ROOT/apf_top.sv" -set_global_assignment -name SDC_FILE "$BSP_ROOT/sys_constr.sdc" -set_global_assignment -name SOURCE_TCL_SCRIPT_FILE "$PLATFORM_ROOT/pkgIndex.tcl" -set_global_assignment -name QIP_FILE "$TARGET_ROOT/core.qip" -set BOARD_PINS [glob -nocomplain -types f [file join $BSP_ROOT/pinouts *.tcl]] -foreach pinout $BOARD_PINS { - set_global_assignment -name SOURCE_TCL_SCRIPT_FILE \"$pinout\" -} - -# Check if build_id.vh exists -checkBuildID - -# ============================================================================== -# Framework Assignments -# ============================================================================== - -# ============================================================================== -# Classic Timing Assignments -# ============================================================================== -set QUARTUS_VERSION [lindex $quartus(version) 1] -set VERSION_COMPONENTS [split $QUARTUS_VERSION "."] -set VERSION_MAJOR [lindex $VERSION_COMPONENTS 0] - -if {$VERSION_MAJOR > 17} { - set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS ON - set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS OFF - set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF -} else { - set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON - set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS OFF -} +# ============================================================================== +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileType: SOURCE +# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors +# ============================================================================== + +# ============================================================================== +# Parameters Assignments +# ============================================================================== +set FRAMEWORK_ID "pocket" +set FRAMEWORK_NAME "Analogue Pocket" +set DEVICE_FAMILY [get_global_assignment -name FAMILY] +set DEVICE_ID [get_parameter -name NSX_DEVICE_ID] + +set BUILD_ROOT "../.build" +set PKG_ROOT "../pkg" +set RTL_ROOT "../rtl" +set PLATFORM_ROOT "../platform/$FRAMEWORK_ID" +set TARGET_ROOT "../target/$FRAMEWORK_ID" +set BSP_ROOT "$PLATFORM_ROOT/bsp/$DEVICE_ID" + +# ============================================================================== +# System and Core Top Level, Pinout and Constrains +# ============================================================================== +set_global_assignment -name SYSTEMVERILOG_FILE "$BSP_ROOT/apf_top.sv" +set_global_assignment -name SDC_FILE "$BSP_ROOT/sys_constr.sdc" +set_global_assignment -name SOURCE_TCL_SCRIPT_FILE "$PLATFORM_ROOT/pkgIndex.tcl" +set_global_assignment -name QIP_FILE "$TARGET_ROOT/core.qip" +set BOARD_PINS [glob -nocomplain -types f [file join $BSP_ROOT/pinouts *.tcl]] +foreach pinout $BOARD_PINS { + set_global_assignment -name SOURCE_TCL_SCRIPT_FILE \"$pinout\" +} + +# Check if build_id.vh exists +checkBuildID + +# ============================================================================== +# Framework Assignments +# ============================================================================== + +# ============================================================================== +# Classic Timing Assignments +# ============================================================================== +set QUARTUS_VERSION [lindex $quartus(version) 1] +set VERSION_COMPONENTS [split $QUARTUS_VERSION "."] +set VERSION_MAJOR [lindex $VERSION_COMPONENTS 0] + +if {$VERSION_MAJOR > 17} { + set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS ON + set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS OFF + set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF +} else { + set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON + set_global_assignment -name TIMEQUEST_REPORT_WORST_CASE_TIMING_PATHS OFF +} diff --git a/platform/pocket/helpers/synch_2.sv b/platform/pocket/helpers/synch_2.sv index ab2477c..aa2dfb4 100644 --- a/platform/pocket/helpers/synch_2.sv +++ b/platform/pocket/helpers/synch_2.sv @@ -1,71 +1,71 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// 2-stage synchronizer -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2022, Analogue Enterprises Limited -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ -// This creates a pipeline where each signal holds the value of the signal that -// was one clock cycle earlier. -// -// It effectively delays the 'i' input by two clock cycles and propagates it -// to the 'o' output. -// -// Useful for tasks such as synchronizing data or creating a 2-stage pipeline -// register. -//------------------------------------------------------------------------------ - -`default_nettype none - -module synch_2 - #( - parameter WIDTH = 1 - ) ( - input logic [WIDTH-1:0] i, //! Input Signal - output logic [WIDTH-1:0] o, //! Synchronized Output - input logic clk, //! Clock To Synchronize On - output logic rise, //! One-Cycle Rising Edge Pulse - output logic fall //! One-Cycle Falling Edge Pulse - ); - - logic [WIDTH-1:0] s1, s2; - - always_ff @(posedge clk) begin - {s2, o, s1} <= {o, s1, i}; - end - - generate - if(WIDTH == 1) begin - assign rise = o & ~s2; - assign fall = ~o & s2; - end - else begin - assign rise = 1'b0; - assign fall = 1'b0; - end - endgenerate - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// 2-stage synchronizer +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2022, Analogue Enterprises Limited +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ +// This creates a pipeline where each signal holds the value of the signal that +// was one clock cycle earlier. +// +// It effectively delays the 'i' input by two clock cycles and propagates it +// to the 'o' output. +// +// Useful for tasks such as synchronizing data or creating a 2-stage pipeline +// register. +//------------------------------------------------------------------------------ + +`default_nettype none + +module synch_2 + #( + parameter WIDTH = 1 + ) ( + input logic [WIDTH-1:0] i, //! Input Signal + output logic [WIDTH-1:0] o, //! Synchronized Output + input logic clk, //! Clock To Synchronize On + output logic rise, //! One-Cycle Rising Edge Pulse + output logic fall //! One-Cycle Falling Edge Pulse + ); + + logic [WIDTH-1:0] s1, s2; + + always_ff @(posedge clk) begin + {s2, o, s1} <= {o, s1, i}; + end + + generate + if(WIDTH == 1) begin + assign rise = o & ~s2; + assign fall = ~o & s2; + end + else begin + assign rise = 1'b0; + assign fall = 1'b0; + end + endgenerate + +endmodule diff --git a/platform/pocket/helpers/synch_3.sv b/platform/pocket/helpers/synch_3.sv index 90b1e47..1caa577 100644 --- a/platform/pocket/helpers/synch_3.sv +++ b/platform/pocket/helpers/synch_3.sv @@ -1,71 +1,71 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// 3-stage synchronizer -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2022, Analogue Enterprises Limited -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ -// This creates a pipeline where each signal holds the value of the signal that -// was one clock cycle earlier. -// -// It effectively delays the 'i' input by three clock cycles and propagates it -// to the 'o' output. -// -// Useful for tasks such as synchronizing data or creating a 3-stage pipeline -// register. -//------------------------------------------------------------------------------ - -`default_nettype none - -module synch_3 - #( - parameter WIDTH = 1 - ) ( - input logic [WIDTH-1:0] i, //! Input Signal - output logic [WIDTH-1:0] o, //! Synchronized Output - input logic clk, //! Clock To Synchronize On - output logic rise, //! One-Cycle Rising Edge Pulse - output logic fall //! One-Cycle Falling Edge Pulse - ); - - logic [WIDTH-1:0] s1, s2, s3; - - always_ff @(posedge clk) begin - {s3, o, s2, s1} <= {o, s2, s1, i}; - end - - generate - if(WIDTH == 1) begin - assign rise = o & ~s3; - assign fall = ~o & s3; - end - else begin - assign rise = 1'b0; - assign fall = 1'b0; - end - endgenerate - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// 3-stage synchronizer +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2022, Analogue Enterprises Limited +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ +// This creates a pipeline where each signal holds the value of the signal that +// was one clock cycle earlier. +// +// It effectively delays the 'i' input by three clock cycles and propagates it +// to the 'o' output. +// +// Useful for tasks such as synchronizing data or creating a 3-stage pipeline +// register. +//------------------------------------------------------------------------------ + +`default_nettype none + +module synch_3 + #( + parameter WIDTH = 1 + ) ( + input logic [WIDTH-1:0] i, //! Input Signal + output logic [WIDTH-1:0] o, //! Synchronized Output + input logic clk, //! Clock To Synchronize On + output logic rise, //! One-Cycle Rising Edge Pulse + output logic fall //! One-Cycle Falling Edge Pulse + ); + + logic [WIDTH-1:0] s1, s2, s3; + + always_ff @(posedge clk) begin + {s3, o, s2, s1} <= {o, s2, s1, i}; + end + + generate + if(WIDTH == 1) begin + assign rise = o & ~s3; + assign fall = ~o & s3; + end + else begin + assign rise = 1'b0; + assign fall = 1'b0; + end + endgenerate + +endmodule diff --git a/platform/pocket/interface/analog2dpad.sv b/platform/pocket/interface/analog2dpad.sv index eee3c7f..5193b46 100644 --- a/platform/pocket/interface/analog2dpad.sv +++ b/platform/pocket/interface/analog2dpad.sv @@ -1,78 +1,78 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket Analogue Joystick to DPAD Controller -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ -// Uy | 0x00 -// Lx ++ Rx | 0x00 > 0x80 < 0xFF -// Dy | 0xFF -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module analog2dpad - #( - parameter [7:0] CENTER = 8'h80, //! Analog Center Value - parameter [7:0] DEADZONE = 8'h10 //! Set Controller Deadzone - ) ( - input logic clk_sys, //! System Clock - input logic [3:0] pad_type, //! System Clock - input logic [7:0] joy_lx, joy_ly, //! Left Analog X/Y - input logic [7:0] joy_rx, joy_ry, //! Right Analog X/Y - output logic joy_up, joy_down, //! D-PAD Signals - output logic joy_left, joy_right //! D-PAD Signals - ); - - //! ------------------------------------------------------------------------ - //! Analog Stick - //! ------------------------------------------------------------------------ - logic ljoy_u, ljoy_d, ljoy_l, ljoy_r; - logic rjoy_u, rjoy_d, rjoy_l, rjoy_r; - - always_ff @(posedge clk_sys) begin - //! Left Analog Stick - ljoy_l <= (joy_lx < (CENTER - DEADZONE)); - ljoy_r <= (joy_lx > (CENTER + DEADZONE)); - ljoy_u <= (joy_ly < (CENTER - DEADZONE)); - ljoy_d <= (joy_ly > (CENTER + DEADZONE)); - //! Right Analog Stick - rjoy_l <= (joy_rx < (CENTER - DEADZONE)); - rjoy_r <= (joy_rx > (CENTER + DEADZONE)); - rjoy_u <= (joy_ry < (CENTER - DEADZONE)); - rjoy_d <= (joy_ry > (CENTER + DEADZONE)); - end - - //! ------------------------------------------------------------------------ - //! Combine Left or Right Analog Stick into DPAD - //! ------------------------------------------------------------------------ - assign joy_left = (pad_type == 4'h3) ? (ljoy_l | rjoy_l) : 1'b0; - assign joy_right = (pad_type == 4'h3) ? (ljoy_r | rjoy_r) : 1'b0; - assign joy_up = (pad_type == 4'h3) ? (ljoy_u | rjoy_u) : 1'b0; - assign joy_down = (pad_type == 4'h3) ? (ljoy_d | rjoy_d) : 1'b0; - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket Analogue Joystick to DPAD Controller +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ +// Uy | 0x00 +// Lx ++ Rx | 0x00 > 0x80 < 0xFF +// Dy | 0xFF +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module analog2dpad + #( + parameter [7:0] CENTER = 8'h80, //! Analog Center Value + parameter [7:0] DEADZONE = 8'h10 //! Set Controller Deadzone + ) ( + input logic clk_sys, //! System Clock + input logic [3:0] pad_type, //! System Clock + input logic [7:0] joy_lx, joy_ly, //! Left Analog X/Y + input logic [7:0] joy_rx, joy_ry, //! Right Analog X/Y + output logic joy_up, joy_down, //! D-PAD Signals + output logic joy_left, joy_right //! D-PAD Signals + ); + + //! ------------------------------------------------------------------------ + //! Analog Stick + //! ------------------------------------------------------------------------ + logic ljoy_u, ljoy_d, ljoy_l, ljoy_r; + logic rjoy_u, rjoy_d, rjoy_l, rjoy_r; + + always_ff @(posedge clk_sys) begin + //! Left Analog Stick + ljoy_l <= (joy_lx < (CENTER - DEADZONE)); + ljoy_r <= (joy_lx > (CENTER + DEADZONE)); + ljoy_u <= (joy_ly < (CENTER - DEADZONE)); + ljoy_d <= (joy_ly > (CENTER + DEADZONE)); + //! Right Analog Stick + rjoy_l <= (joy_rx < (CENTER - DEADZONE)); + rjoy_r <= (joy_rx > (CENTER + DEADZONE)); + rjoy_u <= (joy_ry < (CENTER - DEADZONE)); + rjoy_d <= (joy_ry > (CENTER + DEADZONE)); + end + + //! ------------------------------------------------------------------------ + //! Combine Left or Right Analog Stick into DPAD + //! ------------------------------------------------------------------------ + assign joy_left = (pad_type == 4'h3) ? (ljoy_l | rjoy_l) : 1'b0; + assign joy_right = (pad_type == 4'h3) ? (ljoy_r | rjoy_r) : 1'b0; + assign joy_up = (pad_type == 4'h3) ? (ljoy_u | rjoy_u) : 1'b0; + assign joy_down = (pad_type == 4'h3) ? (ljoy_d | rjoy_d) : 1'b0; + +endmodule diff --git a/platform/pocket/interface/data_loader.sv b/platform/pocket/interface/data_loader.sv index 190a2e2..a43a295 100644 --- a/platform/pocket/interface/data_loader.sv +++ b/platform/pocket/interface/data_loader.sv @@ -1,213 +1,213 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket Data Loader -// -// Copyright (c) 2022, Adam Gastineau -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ -// Data loader: Takes APF bridge writes, sends them to storage. -// -// Takes 32-bit words from APF and splits them into four / OUTPUT_WORD_SIZE words. -// You can set the cycle delay by adjusting WRITE_MEM_CLOCK_DELAY. -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module data_loader - #( - // Upper 4 bits of address - parameter ADDRESS_MASK_UPPER_4 = 0, - parameter ADDRESS_SIZE = 28, - // Number of clk_memory cycles to delay each write output - // Min 4. Component will assert this value is within the valid range - // Be aware that APF sends data every ~75 74MHz cycles, so you cannot send data slower than this - parameter WRITE_MEM_CLOCK_DELAY = 4, - // Number of clk_memory cycles to hold the write_en signal high - // Min 1. Component will assert this value is within the valid range - parameter WRITE_MEM_EN_CYCLE_LENGTH = 1, - // Word size in number of bytes. Can either be 1 (output 8 bits), or 2 (output 16 bits) - // Component will assert this value is within the valid range - parameter OUTPUT_WORD_SIZE = 1 - ) ( - input wire clk_74a, - input wire clk_memory, - - input wire bridge_wr, - input wire bridge_endian_little, - input wire [31:0] bridge_addr, - input wire [31:0] bridge_wr_data, - - // These outputs are synced to the memory clock - output reg write_en = 0, - output reg [ADDRESS_SIZE-1:0] write_addr = 0, - output reg [8 * OUTPUT_WORD_SIZE - 1:0] write_data = 0 - ); - -`define MAX(x, y) ((x > y) ? x : y) - - localparam WORD_SIZE = 8 * OUTPUT_WORD_SIZE; - // Only use the lower 28 bits of the address - localparam FIFO_SIZE = WORD_SIZE + 28; - - wire mem_empty; - - wire [FIFO_SIZE - 1:0] fifo_out; - - reg read_req = 0; - reg write_req = 0; - reg [31:0] shift_data; - reg [27:0] buff_bridge_addr; - - wire [FIFO_SIZE - 1:0] fifo_in = {shift_data[WORD_SIZE-1:0], buff_bridge_addr[27:0]}; - - dcfifo #( - .clocks_are_synchronized ( "FALSE" ), - .intended_device_family ( "Cyclone V" ), - .lpm_numwords ( 4 ), - .lpm_showahead ( "OFF" ), - .lpm_type ( "dcfifo" ), - .lpm_width ( FIFO_SIZE ), - .lpm_widthu ( 2 ), - .overflow_checking ( "OFF" ), - .rdsync_delaypipe ( 5 ), - .underflow_checking ( "OFF" ), - .use_eab ( "OFF" ), - .wrsync_delaypipe ( 5 ) - ) dcfifo_component ( - .data ( fifo_in ), - .rdclk ( clk_memory ), - .rdreq ( read_req ), - .wrclk ( clk_74a ), - .wrreq ( write_req ), - .q ( fifo_out ), - .rdempty ( mem_empty ) - ); - - /// APF to Mem clock - reg prev_bridge_wr = 0; - reg [2:0] write_count = 0; - reg [2:0] write_state = 0; - - localparam WRITE_START = 1; - localparam WRITE_REQ_SHIFT = 2; - - // Receive APF writes and buffer them into the memory clock domain - always @(posedge clk_74a) begin - prev_bridge_wr <= bridge_wr; - - if (~prev_bridge_wr && bridge_wr && bridge_addr[31:28] == ADDRESS_MASK_UPPER_4) begin - // Beginning APF write to core - write_state <= WRITE_REQ_SHIFT; - write_req <= 1; - write_count <= 0; - shift_data <= bridge_endian_little ? bridge_wr_data : - {bridge_wr_data[7:0], bridge_wr_data[15:8], bridge_wr_data[23:16], bridge_wr_data[31:24]}; - buff_bridge_addr <= bridge_addr[27:0]; - end - - case (write_state) - WRITE_START: begin - write_req <= 1; - write_state <= WRITE_REQ_SHIFT; - end - WRITE_REQ_SHIFT: begin - write_req <= 0; - // We will be writing again in the next cycle - shift_data <= {8'h0, shift_data[31:WORD_SIZE]}; - buff_bridge_addr <= buff_bridge_addr + OUTPUT_WORD_SIZE; - write_count <= write_count + 1; - if (write_count == (4 / OUTPUT_WORD_SIZE) - 1) begin - // Finished write - write_state <= 0; - end - else begin - write_state <= WRITE_START; - end - end - endcase - end - - /// Mem clock to core - reg [5:0] read_state = 0; - - localparam READ_DELAY = 1; - localparam READ_WRITE = 2; - localparam READ_WRITE_EN_CYCLE_OFF = READ_WRITE + WRITE_MEM_EN_CYCLE_LENGTH; - localparam READ_WRITE_END_DEFAULT = WRITE_MEM_CLOCK_DELAY - 1; - // Must use max to prevent READ_WRITE_END from being the same as READ_WRITE_EN_CYCLE_OFF - localparam READ_WRITE_END = `MAX(READ_WRITE_END_DEFAULT, READ_WRITE_EN_CYCLE_OFF + 1); - localparam HAS_DELAY = READ_WRITE_END_DEFAULT > READ_WRITE_EN_CYCLE_OFF; - - always @(posedge clk_memory) begin - if (read_state != 0) begin - read_state <= read_state + 1; - end - else if (~mem_empty) begin - // Start read - read_state <= READ_DELAY; - read_req <= 1; - end - - case (read_state) - READ_DELAY: begin - read_req <= 0; - write_en <= 0; - end - READ_WRITE: begin - // Read data is available - write_en <= 1; - // Lowest 28 bits are the address - write_addr <= fifo_out[27:0]; - write_data <= fifo_out[WORD_SIZE+27:28]; - read_req <= 0; - end - READ_WRITE_EN_CYCLE_OFF: begin - write_en <= 0; - if (!HAS_DELAY) begin - // No extra delay, immediately go back to start - read_state <= 0; - end - end - READ_WRITE_END: begin - read_state <= 0; - end - endcase - end - - initial begin - // Verify parameters - if (WRITE_MEM_CLOCK_DELAY < 4) begin - $error("WRITE_MEM_CLOCK_DELAY has a minimum value of 4. Received %d", WRITE_MEM_CLOCK_DELAY); - end - if (WRITE_MEM_EN_CYCLE_LENGTH < 1 || WRITE_MEM_EN_CYCLE_LENGTH >= WRITE_MEM_CLOCK_DELAY - 2) begin - $error("WRITE_MEM_EN_CYCLE_LENGTH must be between 1 and %d (inclusive, based off of WRITE_MEM_CLOCK_DELAY). Received %d", WRITE_MEM_CLOCK_DELAY - 2 - 1, WRITE_MEM_EN_CYCLE_LENGTH); - end - if (OUTPUT_WORD_SIZE < 1 || OUTPUT_WORD_SIZE > 2) begin - $error("OUTPUT_WORD_SIZE must be 1 or 2. Received %d", OUTPUT_WORD_SIZE); - end - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket Data Loader +// +// Copyright (c) 2022, Adam Gastineau +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ +// Data loader: Takes APF bridge writes, sends them to storage. +// +// Takes 32-bit words from APF and splits them into four / OUTPUT_WORD_SIZE words. +// You can set the cycle delay by adjusting WRITE_MEM_CLOCK_DELAY. +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module data_loader + #( + // Upper 4 bits of address + parameter ADDRESS_MASK_UPPER_4 = 0, + parameter ADDRESS_SIZE = 28, + // Number of clk_memory cycles to delay each write output + // Min 4. Component will assert this value is within the valid range + // Be aware that APF sends data every ~75 74MHz cycles, so you cannot send data slower than this + parameter WRITE_MEM_CLOCK_DELAY = 4, + // Number of clk_memory cycles to hold the write_en signal high + // Min 1. Component will assert this value is within the valid range + parameter WRITE_MEM_EN_CYCLE_LENGTH = 1, + // Word size in number of bytes. Can either be 1 (output 8 bits), or 2 (output 16 bits) + // Component will assert this value is within the valid range + parameter OUTPUT_WORD_SIZE = 1 + ) ( + input wire clk_74a, + input wire clk_memory, + + input wire bridge_wr, + input wire bridge_endian_little, + input wire [31:0] bridge_addr, + input wire [31:0] bridge_wr_data, + + // These outputs are synced to the memory clock + output reg write_en = 0, + output reg [ADDRESS_SIZE-1:0] write_addr = 0, + output reg [8 * OUTPUT_WORD_SIZE - 1:0] write_data = 0 + ); + +`define MAX(x, y) ((x > y) ? x : y) + + localparam WORD_SIZE = 8 * OUTPUT_WORD_SIZE; + // Only use the lower 28 bits of the address + localparam FIFO_SIZE = WORD_SIZE + 28; + + wire mem_empty; + + wire [FIFO_SIZE - 1:0] fifo_out; + + reg read_req = 0; + reg write_req = 0; + reg [31:0] shift_data; + reg [27:0] buff_bridge_addr; + + wire [FIFO_SIZE - 1:0] fifo_in = {shift_data[WORD_SIZE-1:0], buff_bridge_addr[27:0]}; + + dcfifo #( + .clocks_are_synchronized ( "FALSE" ), + .intended_device_family ( "Cyclone V" ), + .lpm_numwords ( 4 ), + .lpm_showahead ( "OFF" ), + .lpm_type ( "dcfifo" ), + .lpm_width ( FIFO_SIZE ), + .lpm_widthu ( 2 ), + .overflow_checking ( "OFF" ), + .rdsync_delaypipe ( 5 ), + .underflow_checking ( "OFF" ), + .use_eab ( "OFF" ), + .wrsync_delaypipe ( 5 ) + ) dcfifo_component ( + .data ( fifo_in ), + .rdclk ( clk_memory ), + .rdreq ( read_req ), + .wrclk ( clk_74a ), + .wrreq ( write_req ), + .q ( fifo_out ), + .rdempty ( mem_empty ) + ); + + /// APF to Mem clock + reg prev_bridge_wr = 0; + reg [2:0] write_count = 0; + reg [2:0] write_state = 0; + + localparam WRITE_START = 1; + localparam WRITE_REQ_SHIFT = 2; + + // Receive APF writes and buffer them into the memory clock domain + always @(posedge clk_74a) begin + prev_bridge_wr <= bridge_wr; + + if (~prev_bridge_wr && bridge_wr && bridge_addr[31:28] == ADDRESS_MASK_UPPER_4) begin + // Beginning APF write to core + write_state <= WRITE_REQ_SHIFT; + write_req <= 1; + write_count <= 0; + shift_data <= bridge_endian_little ? bridge_wr_data : + {bridge_wr_data[7:0], bridge_wr_data[15:8], bridge_wr_data[23:16], bridge_wr_data[31:24]}; + buff_bridge_addr <= bridge_addr[27:0]; + end + + case (write_state) + WRITE_START: begin + write_req <= 1; + write_state <= WRITE_REQ_SHIFT; + end + WRITE_REQ_SHIFT: begin + write_req <= 0; + // We will be writing again in the next cycle + shift_data <= {8'h0, shift_data[31:WORD_SIZE]}; + buff_bridge_addr <= buff_bridge_addr + OUTPUT_WORD_SIZE; + write_count <= write_count + 1; + if (write_count == (4 / OUTPUT_WORD_SIZE) - 1) begin + // Finished write + write_state <= 0; + end + else begin + write_state <= WRITE_START; + end + end + endcase + end + + /// Mem clock to core + reg [5:0] read_state = 0; + + localparam READ_DELAY = 1; + localparam READ_WRITE = 2; + localparam READ_WRITE_EN_CYCLE_OFF = READ_WRITE + WRITE_MEM_EN_CYCLE_LENGTH; + localparam READ_WRITE_END_DEFAULT = WRITE_MEM_CLOCK_DELAY - 1; + // Must use max to prevent READ_WRITE_END from being the same as READ_WRITE_EN_CYCLE_OFF + localparam READ_WRITE_END = `MAX(READ_WRITE_END_DEFAULT, READ_WRITE_EN_CYCLE_OFF + 1); + localparam HAS_DELAY = READ_WRITE_END_DEFAULT > READ_WRITE_EN_CYCLE_OFF; + + always @(posedge clk_memory) begin + if (read_state != 0) begin + read_state <= read_state + 1; + end + else if (~mem_empty) begin + // Start read + read_state <= READ_DELAY; + read_req <= 1; + end + + case (read_state) + READ_DELAY: begin + read_req <= 0; + write_en <= 0; + end + READ_WRITE: begin + // Read data is available + write_en <= 1; + // Lowest 28 bits are the address + write_addr <= fifo_out[27:0]; + write_data <= fifo_out[WORD_SIZE+27:28]; + read_req <= 0; + end + READ_WRITE_EN_CYCLE_OFF: begin + write_en <= 0; + if (!HAS_DELAY) begin + // No extra delay, immediately go back to start + read_state <= 0; + end + end + READ_WRITE_END: begin + read_state <= 0; + end + endcase + end + + initial begin + // Verify parameters + if (WRITE_MEM_CLOCK_DELAY < 4) begin + $error("WRITE_MEM_CLOCK_DELAY has a minimum value of 4. Received %d", WRITE_MEM_CLOCK_DELAY); + end + if (WRITE_MEM_EN_CYCLE_LENGTH < 1 || WRITE_MEM_EN_CYCLE_LENGTH >= WRITE_MEM_CLOCK_DELAY - 2) begin + $error("WRITE_MEM_EN_CYCLE_LENGTH must be between 1 and %d (inclusive, based off of WRITE_MEM_CLOCK_DELAY). Received %d", WRITE_MEM_CLOCK_DELAY - 2 - 1, WRITE_MEM_EN_CYCLE_LENGTH); + end + if (OUTPUT_WORD_SIZE < 1 || OUTPUT_WORD_SIZE > 2) begin + $error("OUTPUT_WORD_SIZE must be 1 or 2. Received %d", OUTPUT_WORD_SIZE); + end + end + +endmodule diff --git a/platform/pocket/interface/data_unloader.sv b/platform/pocket/interface/data_unloader.sv index 836013e..13d5504 100644 --- a/platform/pocket/interface/data_unloader.sv +++ b/platform/pocket/interface/data_unloader.sv @@ -1,254 +1,254 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket Data Unloader -// -// Copyright (c) 2022, Adam Gastineau -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ -// Data unloader: Reads from memory, supplies to APF bridge. -// -// Takes four words (bytes or 16-bit words) and sends them as 32-bit words to APF. -// You can set the cycle delay by adjusting READ_MEM_CLOCK_DELAY. -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module data_unloader - #( - // Upper 4 bits of address - parameter ADDRESS_MASK_UPPER_4 = 0, - parameter ADDRESS_SIZE = 28, - // Number of memory clock cycles it takes for a read to complete - parameter READ_MEM_CLOCK_DELAY = 1, - // Word size in number of bytes. Can either be 1 (input 8 bits), or 2 (input 16 bits) - parameter INPUT_WORD_SIZE = 1 - ) ( - input wire clk_74a, - input wire clk_memory, - - input wire bridge_rd, - input wire bridge_endian_little, - input wire [31:0] bridge_addr, - output reg [31:0] bridge_rd_data = 0, - - // These outputs are synced to the memory clock - output reg read_en = 0, - output reg [ADDRESS_SIZE-1:0] read_addr = 0, - input wire [8 * INPUT_WORD_SIZE - 1:0] read_data - ); - - localparam WORD_SIZE = 8 * INPUT_WORD_SIZE; - - // APF address to memory FIFO - reg [27:0] fifo_address_in = 0; - reg address_read_req = 0; - reg address_write_req = 0; - wire address_empty; - - wire [27:0] fifo_address_out; - - dcfifo #( - .clocks_are_synchronized ( "FALSE" ), - .intended_device_family ( "Cyclone V" ), - .lpm_numwords ( 4 ), - .lpm_showahead ( "OFF" ), - .lpm_type ( "dcfifo" ), - .lpm_width ( 28 ), - .lpm_widthu ( 2 ), - .overflow_checking ( "OFF" ), - .rdsync_delaypipe ( 5 ), - .underflow_checking ( "OFF" ), - .use_eab ( "OFF" ), - .wrsync_delaypipe ( 5 ) - ) fifo_address_req ( - .data ( fifo_address_in ), - .rdclk ( clk_memory ), - .rdreq ( address_read_req ), - .wrclk ( clk_74a ), - .wrreq ( address_write_req ), - .q ( fifo_address_out ), - .rdempty ( address_empty ) - ); - - // Memory output to APF FIFO - reg data_read_req = 0; - reg data_write_req = 0; - wire data_empty; - - reg [WORD_SIZE - 1:0] fifo_data_in = 0; - wire [WORD_SIZE - 1:0] fifo_data_out; - - dcfifo #( - .clocks_are_synchronized ( "FALSE" ), - .intended_device_family ( "Cyclone V" ), - .lpm_numwords ( 4 ), - .lpm_showahead ( "OFF" ), - .lpm_type ( "dcfifo" ), - .lpm_width ( WORD_SIZE ), - .lpm_widthu ( 2 ), - .overflow_checking ( "OFF" ), - .rdsync_delaypipe ( 5 ), - .underflow_checking ( "OFF" ), - .use_eab ( "OFF" ), - .wrsync_delaypipe ( 5 ) - ) fifo_data_response ( - .data ( fifo_data_in ), - .rdclk ( clk_74a ), - .rdreq ( data_read_req ), - .wrclk ( clk_memory ), - .wrreq ( data_write_req ), - .q ( fifo_data_out ), - .rdempty ( data_empty ) - ); - - /// APF side - reg prev_bridge_rd = 0; - reg [2:0] addr_count = 0; - reg [2:0] addr_state = 0; - - localparam ADDR_START = 1; - localparam ADDR_REQ = 2; - - // Receive APF read addresses and buffer them into the memory clock domain - always @(posedge clk_74a) begin - prev_bridge_rd <= bridge_rd; - - if (~prev_bridge_rd && bridge_rd && bridge_addr[31:28] == ADDRESS_MASK_UPPER_4) begin - // Beginning APF read from core - addr_state <= ADDR_REQ; - address_write_req <= 1; - addr_count <= 0; - fifo_address_in <= bridge_addr[27:0]; - end - - case (addr_state) - ADDR_START: begin - address_write_req <= 1; - addr_state <= ADDR_REQ; - end - ADDR_REQ: begin - address_write_req <= 0; - fifo_address_in <= fifo_address_in + INPUT_WORD_SIZE; - addr_count <= addr_count + 1; - if (addr_count == (4 / INPUT_WORD_SIZE) - 1) begin - // Finished write - addr_count <= 0; - addr_state <= 0; - end - else begin - addr_state <= ADDR_START; - end - end - endcase - end - - reg [2:0] data_send_state = 0; - reg [2:0] apf_data_count = 0; - reg [31:0] apf_bridge_write_data = 0; - - wire [31:0] apf_final_data = {fifo_data_out, apf_bridge_write_data[31-WORD_SIZE:0]}; - - localparam READ_DATA_DELAY = 1; - localparam READ_DATA_WRITE = 2; - - // Receive data from memory and write to APF bridge - always @(posedge clk_74a) begin - if (data_send_state != 0) begin - data_send_state <= data_send_state + 1; - end - else if (~data_empty) begin - // Start data read - data_send_state <= READ_DATA_DELAY; - data_read_req <= 1; - apf_data_count <= 0; - end - - case (data_send_state) - READ_DATA_DELAY: begin - data_read_req <= 0; - // Shift current APF data - apf_bridge_write_data <= apf_bridge_write_data >> WORD_SIZE; - end - READ_DATA_WRITE: begin - // Data from memory is available - if (apf_data_count == (4 / INPUT_WORD_SIZE) - 1) begin - // We have all of the data we need, send to APF - bridge_rd_data <= bridge_endian_little ? apf_final_data : { - apf_final_data[7:0], apf_final_data[15:8], apf_final_data[23:16], apf_final_data[31:24] - }; - data_send_state <= 0; - end - else begin - apf_bridge_write_data <= apf_final_data; - data_read_req <= 1; - data_send_state <= READ_DATA_DELAY; - apf_data_count <= apf_data_count + 1; - end - end - endcase - end - - /// Mem side - reg [5:0] data_read_state = 0; - - localparam READ_ADDRESS_DELAY = 1; - localparam READ_MEM_START = 2; - localparam READ_MEM_COMPLETE = READ_MEM_START + READ_MEM_CLOCK_DELAY; - localparam READ_ADDRESS_END = READ_MEM_COMPLETE + 1; - - always @(posedge clk_memory) begin - if (data_read_state != 0) begin - data_read_state <= data_read_state + 1; - end - else if (~address_empty) begin - // Start address read - data_read_state <= READ_ADDRESS_DELAY; - address_read_req <= 1; - end - - case (data_read_state) - READ_ADDRESS_DELAY: begin - address_read_req <= 0; - end - READ_MEM_START: begin - // Address read data is available - read_en <= 1; - read_addr <= fifo_address_out[ADDRESS_SIZE-1:0]; - end - READ_MEM_COMPLETE: begin - // We have data to send to APF - read_en <= 0; - data_write_req <= 1; - fifo_data_in <= read_data; - end - READ_ADDRESS_END: begin - data_write_req <= 0; - data_read_state <= 0; - end - endcase - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket Data Unloader +// +// Copyright (c) 2022, Adam Gastineau +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ +// Data unloader: Reads from memory, supplies to APF bridge. +// +// Takes four words (bytes or 16-bit words) and sends them as 32-bit words to APF. +// You can set the cycle delay by adjusting READ_MEM_CLOCK_DELAY. +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module data_unloader + #( + // Upper 4 bits of address + parameter ADDRESS_MASK_UPPER_4 = 0, + parameter ADDRESS_SIZE = 28, + // Number of memory clock cycles it takes for a read to complete + parameter READ_MEM_CLOCK_DELAY = 1, + // Word size in number of bytes. Can either be 1 (input 8 bits), or 2 (input 16 bits) + parameter INPUT_WORD_SIZE = 1 + ) ( + input wire clk_74a, + input wire clk_memory, + + input wire bridge_rd, + input wire bridge_endian_little, + input wire [31:0] bridge_addr, + output reg [31:0] bridge_rd_data = 0, + + // These outputs are synced to the memory clock + output reg read_en = 0, + output reg [ADDRESS_SIZE-1:0] read_addr = 0, + input wire [8 * INPUT_WORD_SIZE - 1:0] read_data + ); + + localparam WORD_SIZE = 8 * INPUT_WORD_SIZE; + + // APF address to memory FIFO + reg [27:0] fifo_address_in = 0; + reg address_read_req = 0; + reg address_write_req = 0; + wire address_empty; + + wire [27:0] fifo_address_out; + + dcfifo #( + .clocks_are_synchronized ( "FALSE" ), + .intended_device_family ( "Cyclone V" ), + .lpm_numwords ( 4 ), + .lpm_showahead ( "OFF" ), + .lpm_type ( "dcfifo" ), + .lpm_width ( 28 ), + .lpm_widthu ( 2 ), + .overflow_checking ( "OFF" ), + .rdsync_delaypipe ( 5 ), + .underflow_checking ( "OFF" ), + .use_eab ( "OFF" ), + .wrsync_delaypipe ( 5 ) + ) fifo_address_req ( + .data ( fifo_address_in ), + .rdclk ( clk_memory ), + .rdreq ( address_read_req ), + .wrclk ( clk_74a ), + .wrreq ( address_write_req ), + .q ( fifo_address_out ), + .rdempty ( address_empty ) + ); + + // Memory output to APF FIFO + reg data_read_req = 0; + reg data_write_req = 0; + wire data_empty; + + reg [WORD_SIZE - 1:0] fifo_data_in = 0; + wire [WORD_SIZE - 1:0] fifo_data_out; + + dcfifo #( + .clocks_are_synchronized ( "FALSE" ), + .intended_device_family ( "Cyclone V" ), + .lpm_numwords ( 4 ), + .lpm_showahead ( "OFF" ), + .lpm_type ( "dcfifo" ), + .lpm_width ( WORD_SIZE ), + .lpm_widthu ( 2 ), + .overflow_checking ( "OFF" ), + .rdsync_delaypipe ( 5 ), + .underflow_checking ( "OFF" ), + .use_eab ( "OFF" ), + .wrsync_delaypipe ( 5 ) + ) fifo_data_response ( + .data ( fifo_data_in ), + .rdclk ( clk_74a ), + .rdreq ( data_read_req ), + .wrclk ( clk_memory ), + .wrreq ( data_write_req ), + .q ( fifo_data_out ), + .rdempty ( data_empty ) + ); + + /// APF side + reg prev_bridge_rd = 0; + reg [2:0] addr_count = 0; + reg [2:0] addr_state = 0; + + localparam ADDR_START = 1; + localparam ADDR_REQ = 2; + + // Receive APF read addresses and buffer them into the memory clock domain + always @(posedge clk_74a) begin + prev_bridge_rd <= bridge_rd; + + if (~prev_bridge_rd && bridge_rd && bridge_addr[31:28] == ADDRESS_MASK_UPPER_4) begin + // Beginning APF read from core + addr_state <= ADDR_REQ; + address_write_req <= 1; + addr_count <= 0; + fifo_address_in <= bridge_addr[27:0]; + end + + case (addr_state) + ADDR_START: begin + address_write_req <= 1; + addr_state <= ADDR_REQ; + end + ADDR_REQ: begin + address_write_req <= 0; + fifo_address_in <= fifo_address_in + INPUT_WORD_SIZE; + addr_count <= addr_count + 1; + if (addr_count == (4 / INPUT_WORD_SIZE) - 1) begin + // Finished write + addr_count <= 0; + addr_state <= 0; + end + else begin + addr_state <= ADDR_START; + end + end + endcase + end + + reg [2:0] data_send_state = 0; + reg [2:0] apf_data_count = 0; + reg [31:0] apf_bridge_write_data = 0; + + wire [31:0] apf_final_data = {fifo_data_out, apf_bridge_write_data[31-WORD_SIZE:0]}; + + localparam READ_DATA_DELAY = 1; + localparam READ_DATA_WRITE = 2; + + // Receive data from memory and write to APF bridge + always @(posedge clk_74a) begin + if (data_send_state != 0) begin + data_send_state <= data_send_state + 1; + end + else if (~data_empty) begin + // Start data read + data_send_state <= READ_DATA_DELAY; + data_read_req <= 1; + apf_data_count <= 0; + end + + case (data_send_state) + READ_DATA_DELAY: begin + data_read_req <= 0; + // Shift current APF data + apf_bridge_write_data <= apf_bridge_write_data >> WORD_SIZE; + end + READ_DATA_WRITE: begin + // Data from memory is available + if (apf_data_count == (4 / INPUT_WORD_SIZE) - 1) begin + // We have all of the data we need, send to APF + bridge_rd_data <= bridge_endian_little ? apf_final_data : { + apf_final_data[7:0], apf_final_data[15:8], apf_final_data[23:16], apf_final_data[31:24] + }; + data_send_state <= 0; + end + else begin + apf_bridge_write_data <= apf_final_data; + data_read_req <= 1; + data_send_state <= READ_DATA_DELAY; + apf_data_count <= apf_data_count + 1; + end + end + endcase + end + + /// Mem side + reg [5:0] data_read_state = 0; + + localparam READ_ADDRESS_DELAY = 1; + localparam READ_MEM_START = 2; + localparam READ_MEM_COMPLETE = READ_MEM_START + READ_MEM_CLOCK_DELAY; + localparam READ_ADDRESS_END = READ_MEM_COMPLETE + 1; + + always @(posedge clk_memory) begin + if (data_read_state != 0) begin + data_read_state <= data_read_state + 1; + end + else if (~address_empty) begin + // Start address read + data_read_state <= READ_ADDRESS_DELAY; + address_read_req <= 1; + end + + case (data_read_state) + READ_ADDRESS_DELAY: begin + address_read_req <= 0; + end + READ_MEM_START: begin + // Address read data is available + read_en <= 1; + read_addr <= fifo_address_out[ADDRESS_SIZE-1:0]; + end + READ_MEM_COMPLETE: begin + // We have data to send to APF + read_en <= 0; + data_write_req <= 1; + fifo_data_in <= read_data; + end + READ_ADDRESS_END: begin + data_write_req <= 0; + data_read_state <= 0; + end + endcase + end + +endmodule diff --git a/platform/pocket/interface/gamepad.sv b/platform/pocket/interface/gamepad.sv index 66d6683..f132b7a 100644 --- a/platform/pocket/interface/gamepad.sv +++ b/platform/pocket/interface/gamepad.sv @@ -1,287 +1,287 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket PAD Controller -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ -// Shifts the joystick input signal through two stages of registers, -// synchronizing it to the system clock signal, and outputs the synchronized -// joystick outputs -// -// key bitmap: -// [0] dpad_up | [ 8] trig_l1 -// [1] dpad_down | [ 9] trig_r1 -// [2] dpad_left | [10] trig_l2 -// [3] dpad_right | [11] trig_r2 -// [4] face_a | [12] trig_l3 -// [5] face_b | [13] trig_r3 -// [6] face_x | [14] face_select -// [7] face_y | [15] face_start -// [28:16] -// [31:29] type -// -// joy values - unsigned - 0x00 > 0x80 < 0xFF -// [7:0] lstick_x -// [15:8] lstick_y -// [23:16] rstick_x -// [31:24] rstick_y -// -// trigger values - unsigned - 0x00-0xFF -// [7:0] ltrig -// [15:8] rtrig -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module gamepad - #( - parameter JOY_PADS = 1, //! Total Number of Gamepads - parameter JOY_ALT = 0, //! 2 Players Alternate - parameter DEADZONE = 8'h10 //! Set Controller Deadzone - ) ( - input logic clk_sys, //! Clock to Sync To (eg: clk_sys) - //! Pocket PAD Interface - input logic [31:0] cont1_key, cont1_joy, //! Gamepad/Analog Joystick - input logic [31:0] cont2_key, cont2_joy, //! Gamepad/Analog Joystick - input logic [31:0] cont3_key, cont3_joy, //! Gamepad/Analog Joystick - input logic [31:0] cont4_key, cont4_joy, //! Gamepad/Analog Joystick - //! Player 1 - output logic p1_up, p1_down, p1_left, p1_right, //! D-PAD - output logic p1_a, p1_b, p1_x, p1_y, //! Face Buttons - output logic p1_l1, p1_l2, p1_l3, p1_se, //! Left Shoulder/Trigger/Analog Buttons/Select - output logic p1_r1, p1_r2, p1_r3, p1_st, //! Right Shoulder/Trigger/Analog Buttons/Start - output logic j1_up, j1_down, j1_left, j1_right, //! Analog 2 DPAD - output logic [7:0] j1_lx, j1_ly, j1_rx, j1_ry, //! Left/Right Analog Stick - //! Player 2 - output logic p2_up, p2_down, p2_left, p2_right, //! D-PAD - output logic p2_a, p2_b, p2_x, p2_y, //! Face Buttons - output logic p2_l1, p2_l2, p2_l3, p2_se, //! Left Shoulder/Trigger/Analog Buttons/Select - output logic p2_r1, p2_r2, p2_r3, p2_st, //! Right Shoulder/Trigger/Analog Buttons/Start - output logic j2_up, j2_down, j2_left, j2_right, //! Analog 2 DPAD - output logic [7:0] j2_lx, j2_ly, j2_rx, j2_ry, //! Left/Right Analog Stick - //! Player 3 - output logic p3_up, p3_down, p3_left, p3_right, //! D-PAD - output logic p3_a, p3_b, p3_x, p3_y, //! Face Buttons - output logic p3_l1, p3_l2, p3_l3, p3_se, //! Left Shoulder/Trigger/Analog Buttons/Select - output logic p3_r1, p3_r2, p3_r3, p3_st, //! Right Shoulder/Trigger/Analog Buttons/Start - output logic j3_up, j3_down, j3_left, j3_right, //! Analog 2 DPAD - output logic [7:0] j3_lx, j3_ly, j3_rx, j3_ry, //! Left/Right Analog Stick - //! Player 4 - output logic p4_up, p4_down, p4_left, p4_right, //! D-PAD - output logic p4_a, p4_b, p4_x, p4_y, //! Face Buttons - output logic p4_l1, p4_l2, p4_l3, p4_se, //! Left Shoulder/Trigger/Analog Buttons/Select - output logic p4_r1, p4_r2, p4_r3, p4_st, //! Right Shoulder/Trigger/Analog Buttons/Start - output logic j4_up, j4_down, j4_left, j4_right, //! Analog 2 DPAD - output logic [7:0] j4_lx, j4_ly, j4_rx, j4_ry, //! Left/Right Analog Stick - //! Single Player or Alternate 2 Players for Arcade - output logic m_up, m_down, m_left, m_right, //! Joystick - output logic m_btn1, m_btn2, m_btn3, m_btn4, //! Y/B/A/X - output logic m_btn5, m_btn6, m_btn7, m_btn8, //! L1/R1/L2/R2 - output logic m_coin, m_coin1, m_coin2, //! Coinage - output logic m_start1, m_start2, //! P1/P2 Start - //! Type - output logic [3:0] p1_type, p2_type, p3_type, p4_type //! Controller Type - ); - - //! ------------------------------------------------------------------------ - //! Player 1 - //! ------------------------------------------------------------------------ - joypad #(.DEADZONE(DEADZONE)) joypad_p1 - ( - .clk_sys ( clk_sys ), - // Pocket PAD Interface - .cont_key ( cont1_key ), - .cont_joy ( cont1_joy ), - // DPAD - .key_up ( p1_up ),.key_down ( p1_down ),.key_left ( p1_left ),.key_right ( p1_right ), - .key_a ( p1_a ),.key_b ( p1_b ),.key_x ( p1_x ),.key_y ( p1_y ), - .key_l1 ( p1_l1 ),.key_l2 ( p1_l2 ),.key_l3 ( p1_l3 ), - .key_r1 ( p1_r1 ),.key_r2 ( p1_r2 ),.key_r3 ( p1_r3 ), - .key_se ( p1_se ),.key_st ( p1_st ), - // Analog Stick - .joy_up ( j1_up ),.joy_down ( j1_down ),.joy_left ( j1_left ),.joy_right ( j1_right ), - .joy_lx ( j1_lx ),.joy_ly ( j1_ly ),.joy_rx ( j1_rx ),.joy_ry ( j1_ry ), - // Type - .pad_type ( p1_type ) - ); - - //! ------------------------------------------------------------------------ - //! Player 2 - //! ------------------------------------------------------------------------ - generate - if(JOY_PADS >= 2) begin - joypad #(.DEADZONE(DEADZONE)) joypad_p2 - ( - .clk_sys ( clk_sys ), - // Pocket PAD Interface - .cont_key ( cont2_key ), - .cont_joy ( cont2_joy ), - // DPAD - .key_up ( p2_up ),.key_down ( p2_down ),.key_left ( p2_left ),.key_right ( p2_right ), - .key_a ( p2_a ),.key_b ( p2_b ),.key_x ( p2_x ),.key_y ( p2_y ), - .key_l1 ( p2_l1 ),.key_l2 ( p2_l2 ),.key_l3 ( p2_l3 ), - .key_r1 ( p2_r1 ),.key_r2 ( p2_r2 ),.key_r3 ( p2_r3 ), - .key_se ( p2_se ),.key_st ( p2_st ), - // Analog Stick - .joy_up ( j2_up ),.joy_down ( j2_down ),.joy_left ( j2_left ),.joy_right ( j2_right ), - .joy_lx ( j2_lx ),.joy_ly ( j2_ly ),.joy_rx ( j2_rx ),.joy_ry ( j2_ry ), - // Type - .pad_type ( p2_type ) - ); - end - else begin - assign { p2_up, p2_down, p2_left, p2_right } = 4'h0; - assign { p2_y , p2_x , p2_b , p2_a } = 4'h0; - assign { p2_l1, p2_r1 , p2_l2 , p2_r2 } = 4'h0; - assign { p2_l3, p2_r3 , p2_se , p2_st } = 4'h0; - assign { j2_up, j2_down, j2_left, j2_right } = 4'h0; - assign { j2_lx, j2_ly , j2_rx , j2_ry } = 32'h0; - assign { p2_type } = 4'h0; - end - endgenerate - - //! ------------------------------------------------------------------------ - //! Player 3 - //! ------------------------------------------------------------------------ - generate - if(JOY_PADS >= 3) begin - joypad #(.DEADZONE(DEADZONE)) joypad_p3 - ( - .clk_sys ( clk_sys ), - // Pocket PAD Interface - .cont_key ( cont3_key ), - .cont_joy ( cont3_joy ), - // DPAD - .key_up ( p3_up ),.key_down ( p3_down ),.key_left ( p3_left ),.key_right ( p3_right ), - .key_a ( p3_a ),.key_b ( p3_b ),.key_x ( p3_x ),.key_y ( p3_y ), - .key_l1 ( p3_l1 ),.key_l2 ( p3_l2 ),.key_l3 ( p3_l3 ), - .key_r1 ( p3_r1 ),.key_r2 ( p3_r2 ),.key_r3 ( p3_r3 ), - .key_se ( p3_se ),.key_st ( p3_st ), - // Analog Stick - .joy_up ( j3_up ),.joy_down ( j3_down ),.joy_left ( j3_left ),.joy_right ( j3_right ), - .joy_lx ( j3_lx ),.joy_ly ( j3_ly ),.joy_rx ( j3_rx ),.joy_ry ( j3_ry ), - // Type - .pad_type ( p3_type ) - ); - end - else begin - assign { p3_up, p3_down, p3_left, p3_right } = 4'h0; - assign { p3_y , p3_x , p3_b , p3_a } = 4'h0; - assign { p3_l1, p3_r1 , p3_l2 , p3_r2 } = 4'h0; - assign { p3_l3, p3_r3 , p3_se , p3_st } = 4'h0; - assign { j3_up, j3_down, j3_left, j3_right } = 4'h0; - assign { j3_lx, j3_ly , j3_rx , j3_ry } = 32'h0; - assign { p3_type } = 4'h0; - end - endgenerate - - //! ------------------------------------------------------------------------ - //! Player 4 - //! ------------------------------------------------------------------------ - generate - if(JOY_PADS == 4) begin - joypad #(.DEADZONE(DEADZONE)) joypad_p4 - ( - .clk_sys ( clk_sys ), - // Pocket PAD Interface - .cont_key ( cont4_key ), - .cont_joy ( cont4_joy ), - // DPAD - .key_up ( p4_up ),.key_down ( p4_down ),.key_left ( p4_left ),.key_right ( p4_right ), - .key_a ( p4_a ),.key_b ( p4_b ),.key_x ( p4_x ),.key_y ( p4_y ), - .key_l1 ( p4_l1 ),.key_l2 ( p4_l2 ),.key_l3 ( p4_l3 ), - .key_r1 ( p4_r1 ),.key_r2 ( p4_r2 ),.key_r3 ( p4_r3 ), - .key_se ( p4_se ),.key_st ( p4_st ), - // Analog Stick - .joy_up ( j4_up ),.joy_down ( j4_down ),.joy_left ( j4_left ),.joy_right ( j4_right ), - .joy_lx ( j4_lx ),.joy_ly ( j4_ly ),.joy_rx ( j4_rx ),.joy_ry ( j4_ry ), - // Type - .pad_type ( p4_type ) - ); - end - else begin - assign { p4_up, p4_down, p4_left, p4_right } = 4'h0; - assign { p4_y , p4_x , p4_b , p4_a } = 4'h0; - assign { p4_l1, p4_r1 , p4_l2 , p4_r2 } = 4'h0; - assign { p4_l3, p4_r3 , p4_se , p4_st } = 4'h0; - assign { j4_up, j4_down, j4_left, j4_right } = 4'h0; - assign { j4_lx, j4_ly , j4_rx , j4_ry } = 32'h0; - assign { p4_type } = 4'h0; - end - endgenerate - - generate - // Alternate 2 Players for Arcade - if(JOY_PADS == 2 && JOY_ALT == 1) begin - assign m_start1 = p1_st; - assign m_start2 = p2_st; - assign m_coin1 = p1_se; - assign m_coin2 = p2_se; - assign m_coin = p1_se | p2_se; - assign m_up = p1_up | p2_up | j1_up | j2_up; - assign m_down = p1_down | p2_down | j1_down | j2_down; - assign m_left = p1_left | p2_left | j1_left | j2_left; - assign m_right = p1_right | p2_right | j1_right | j2_right; - assign m_btn1 = p1_y | p2_y; - assign m_btn2 = p1_b | p2_b; - assign m_btn3 = p1_a | p2_a; - assign m_btn4 = p1_x | p2_x; - assign m_btn5 = p1_l1 | p2_l1; - assign m_btn6 = p1_r1 | p2_r1; - assign m_btn7 = p1_l2 | p2_l2; - assign m_btn8 = p1_r2 | p2_r2; - end - // Single Players for Arcade - else if(JOY_PADS == 1 && JOY_ALT == 0) begin - assign m_start1 = p1_st; - assign m_coin1 = p1_se; - assign m_coin = p1_se; - assign m_up = p1_up | j1_up; - assign m_down = p1_down | j1_down; - assign m_left = p1_left | j1_left; - assign m_right = p1_right | j1_right; - assign m_btn1 = p1_y; - assign m_btn2 = p1_b; - assign m_btn3 = p1_a; - assign m_btn4 = p1_x; - assign m_btn5 = p1_l1; - assign m_btn6 = p1_r1; - assign m_btn7 = p1_l2; - assign m_btn8 = p1_r2; - assign { m_start2, m_coin2 } = 2'h0; - end - else begin - assign { m_coin } = 1'h0; - assign { m_up, m_down, m_left, m_right } = 4'h0; - assign { m_btn1, m_btn2, m_btn3, m_btn4 } = 4'h0; - assign { m_btn5, m_btn6, m_btn7, m_btn8 } = 4'h0; - assign { m_coin1, m_coin2 } = 2'h0; - assign { m_start1, m_start2 } = 2'h0; - end - endgenerate - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket PAD Controller +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ +// Shifts the joystick input signal through two stages of registers, +// synchronizing it to the system clock signal, and outputs the synchronized +// joystick outputs +// +// key bitmap: +// [0] dpad_up | [ 8] trig_l1 +// [1] dpad_down | [ 9] trig_r1 +// [2] dpad_left | [10] trig_l2 +// [3] dpad_right | [11] trig_r2 +// [4] face_a | [12] trig_l3 +// [5] face_b | [13] trig_r3 +// [6] face_x | [14] face_select +// [7] face_y | [15] face_start +// [28:16] +// [31:29] type +// +// joy values - unsigned - 0x00 > 0x80 < 0xFF +// [7:0] lstick_x +// [15:8] lstick_y +// [23:16] rstick_x +// [31:24] rstick_y +// +// trigger values - unsigned - 0x00-0xFF +// [7:0] ltrig +// [15:8] rtrig +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module gamepad + #( + parameter JOY_PADS = 1, //! Total Number of Gamepads + parameter JOY_ALT = 0, //! 2 Players Alternate + parameter DEADZONE = 8'h10 //! Set Controller Deadzone + ) ( + input logic clk_sys, //! Clock to Sync To (eg: clk_sys) + //! Pocket PAD Interface + input logic [31:0] cont1_key, cont1_joy, //! Gamepad/Analog Joystick + input logic [31:0] cont2_key, cont2_joy, //! Gamepad/Analog Joystick + input logic [31:0] cont3_key, cont3_joy, //! Gamepad/Analog Joystick + input logic [31:0] cont4_key, cont4_joy, //! Gamepad/Analog Joystick + //! Player 1 + output logic p1_up, p1_down, p1_left, p1_right, //! D-PAD + output logic p1_a, p1_b, p1_x, p1_y, //! Face Buttons + output logic p1_l1, p1_l2, p1_l3, p1_se, //! Left Shoulder/Trigger/Analog Buttons/Select + output logic p1_r1, p1_r2, p1_r3, p1_st, //! Right Shoulder/Trigger/Analog Buttons/Start + output logic j1_up, j1_down, j1_left, j1_right, //! Analog 2 DPAD + output logic [7:0] j1_lx, j1_ly, j1_rx, j1_ry, //! Left/Right Analog Stick + //! Player 2 + output logic p2_up, p2_down, p2_left, p2_right, //! D-PAD + output logic p2_a, p2_b, p2_x, p2_y, //! Face Buttons + output logic p2_l1, p2_l2, p2_l3, p2_se, //! Left Shoulder/Trigger/Analog Buttons/Select + output logic p2_r1, p2_r2, p2_r3, p2_st, //! Right Shoulder/Trigger/Analog Buttons/Start + output logic j2_up, j2_down, j2_left, j2_right, //! Analog 2 DPAD + output logic [7:0] j2_lx, j2_ly, j2_rx, j2_ry, //! Left/Right Analog Stick + //! Player 3 + output logic p3_up, p3_down, p3_left, p3_right, //! D-PAD + output logic p3_a, p3_b, p3_x, p3_y, //! Face Buttons + output logic p3_l1, p3_l2, p3_l3, p3_se, //! Left Shoulder/Trigger/Analog Buttons/Select + output logic p3_r1, p3_r2, p3_r3, p3_st, //! Right Shoulder/Trigger/Analog Buttons/Start + output logic j3_up, j3_down, j3_left, j3_right, //! Analog 2 DPAD + output logic [7:0] j3_lx, j3_ly, j3_rx, j3_ry, //! Left/Right Analog Stick + //! Player 4 + output logic p4_up, p4_down, p4_left, p4_right, //! D-PAD + output logic p4_a, p4_b, p4_x, p4_y, //! Face Buttons + output logic p4_l1, p4_l2, p4_l3, p4_se, //! Left Shoulder/Trigger/Analog Buttons/Select + output logic p4_r1, p4_r2, p4_r3, p4_st, //! Right Shoulder/Trigger/Analog Buttons/Start + output logic j4_up, j4_down, j4_left, j4_right, //! Analog 2 DPAD + output logic [7:0] j4_lx, j4_ly, j4_rx, j4_ry, //! Left/Right Analog Stick + //! Single Player or Alternate 2 Players for Arcade + output logic m_up, m_down, m_left, m_right, //! Joystick + output logic m_btn1, m_btn2, m_btn3, m_btn4, //! Y/B/A/X + output logic m_btn5, m_btn6, m_btn7, m_btn8, //! L1/R1/L2/R2 + output logic m_coin, m_coin1, m_coin2, //! Coinage + output logic m_start1, m_start2, //! P1/P2 Start + //! Type + output logic [3:0] p1_type, p2_type, p3_type, p4_type //! Controller Type + ); + + //! ------------------------------------------------------------------------ + //! Player 1 + //! ------------------------------------------------------------------------ + joypad #(.DEADZONE(DEADZONE)) joypad_p1 + ( + .clk_sys ( clk_sys ), + // Pocket PAD Interface + .cont_key ( cont1_key ), + .cont_joy ( cont1_joy ), + // DPAD + .key_up ( p1_up ),.key_down ( p1_down ),.key_left ( p1_left ),.key_right ( p1_right ), + .key_a ( p1_a ),.key_b ( p1_b ),.key_x ( p1_x ),.key_y ( p1_y ), + .key_l1 ( p1_l1 ),.key_l2 ( p1_l2 ),.key_l3 ( p1_l3 ), + .key_r1 ( p1_r1 ),.key_r2 ( p1_r2 ),.key_r3 ( p1_r3 ), + .key_se ( p1_se ),.key_st ( p1_st ), + // Analog Stick + .joy_up ( j1_up ),.joy_down ( j1_down ),.joy_left ( j1_left ),.joy_right ( j1_right ), + .joy_lx ( j1_lx ),.joy_ly ( j1_ly ),.joy_rx ( j1_rx ),.joy_ry ( j1_ry ), + // Type + .pad_type ( p1_type ) + ); + + //! ------------------------------------------------------------------------ + //! Player 2 + //! ------------------------------------------------------------------------ + generate + if(JOY_PADS >= 2) begin + joypad #(.DEADZONE(DEADZONE)) joypad_p2 + ( + .clk_sys ( clk_sys ), + // Pocket PAD Interface + .cont_key ( cont2_key ), + .cont_joy ( cont2_joy ), + // DPAD + .key_up ( p2_up ),.key_down ( p2_down ),.key_left ( p2_left ),.key_right ( p2_right ), + .key_a ( p2_a ),.key_b ( p2_b ),.key_x ( p2_x ),.key_y ( p2_y ), + .key_l1 ( p2_l1 ),.key_l2 ( p2_l2 ),.key_l3 ( p2_l3 ), + .key_r1 ( p2_r1 ),.key_r2 ( p2_r2 ),.key_r3 ( p2_r3 ), + .key_se ( p2_se ),.key_st ( p2_st ), + // Analog Stick + .joy_up ( j2_up ),.joy_down ( j2_down ),.joy_left ( j2_left ),.joy_right ( j2_right ), + .joy_lx ( j2_lx ),.joy_ly ( j2_ly ),.joy_rx ( j2_rx ),.joy_ry ( j2_ry ), + // Type + .pad_type ( p2_type ) + ); + end + else begin + assign { p2_up, p2_down, p2_left, p2_right } = 4'h0; + assign { p2_y , p2_x , p2_b , p2_a } = 4'h0; + assign { p2_l1, p2_r1 , p2_l2 , p2_r2 } = 4'h0; + assign { p2_l3, p2_r3 , p2_se , p2_st } = 4'h0; + assign { j2_up, j2_down, j2_left, j2_right } = 4'h0; + assign { j2_lx, j2_ly , j2_rx , j2_ry } = 32'h0; + assign { p2_type } = 4'h0; + end + endgenerate + + //! ------------------------------------------------------------------------ + //! Player 3 + //! ------------------------------------------------------------------------ + generate + if(JOY_PADS >= 3) begin + joypad #(.DEADZONE(DEADZONE)) joypad_p3 + ( + .clk_sys ( clk_sys ), + // Pocket PAD Interface + .cont_key ( cont3_key ), + .cont_joy ( cont3_joy ), + // DPAD + .key_up ( p3_up ),.key_down ( p3_down ),.key_left ( p3_left ),.key_right ( p3_right ), + .key_a ( p3_a ),.key_b ( p3_b ),.key_x ( p3_x ),.key_y ( p3_y ), + .key_l1 ( p3_l1 ),.key_l2 ( p3_l2 ),.key_l3 ( p3_l3 ), + .key_r1 ( p3_r1 ),.key_r2 ( p3_r2 ),.key_r3 ( p3_r3 ), + .key_se ( p3_se ),.key_st ( p3_st ), + // Analog Stick + .joy_up ( j3_up ),.joy_down ( j3_down ),.joy_left ( j3_left ),.joy_right ( j3_right ), + .joy_lx ( j3_lx ),.joy_ly ( j3_ly ),.joy_rx ( j3_rx ),.joy_ry ( j3_ry ), + // Type + .pad_type ( p3_type ) + ); + end + else begin + assign { p3_up, p3_down, p3_left, p3_right } = 4'h0; + assign { p3_y , p3_x , p3_b , p3_a } = 4'h0; + assign { p3_l1, p3_r1 , p3_l2 , p3_r2 } = 4'h0; + assign { p3_l3, p3_r3 , p3_se , p3_st } = 4'h0; + assign { j3_up, j3_down, j3_left, j3_right } = 4'h0; + assign { j3_lx, j3_ly , j3_rx , j3_ry } = 32'h0; + assign { p3_type } = 4'h0; + end + endgenerate + + //! ------------------------------------------------------------------------ + //! Player 4 + //! ------------------------------------------------------------------------ + generate + if(JOY_PADS == 4) begin + joypad #(.DEADZONE(DEADZONE)) joypad_p4 + ( + .clk_sys ( clk_sys ), + // Pocket PAD Interface + .cont_key ( cont4_key ), + .cont_joy ( cont4_joy ), + // DPAD + .key_up ( p4_up ),.key_down ( p4_down ),.key_left ( p4_left ),.key_right ( p4_right ), + .key_a ( p4_a ),.key_b ( p4_b ),.key_x ( p4_x ),.key_y ( p4_y ), + .key_l1 ( p4_l1 ),.key_l2 ( p4_l2 ),.key_l3 ( p4_l3 ), + .key_r1 ( p4_r1 ),.key_r2 ( p4_r2 ),.key_r3 ( p4_r3 ), + .key_se ( p4_se ),.key_st ( p4_st ), + // Analog Stick + .joy_up ( j4_up ),.joy_down ( j4_down ),.joy_left ( j4_left ),.joy_right ( j4_right ), + .joy_lx ( j4_lx ),.joy_ly ( j4_ly ),.joy_rx ( j4_rx ),.joy_ry ( j4_ry ), + // Type + .pad_type ( p4_type ) + ); + end + else begin + assign { p4_up, p4_down, p4_left, p4_right } = 4'h0; + assign { p4_y , p4_x , p4_b , p4_a } = 4'h0; + assign { p4_l1, p4_r1 , p4_l2 , p4_r2 } = 4'h0; + assign { p4_l3, p4_r3 , p4_se , p4_st } = 4'h0; + assign { j4_up, j4_down, j4_left, j4_right } = 4'h0; + assign { j4_lx, j4_ly , j4_rx , j4_ry } = 32'h0; + assign { p4_type } = 4'h0; + end + endgenerate + + generate + // Alternate 2 Players for Arcade + if(JOY_PADS == 2 && JOY_ALT == 1) begin + assign m_start1 = p1_st; + assign m_start2 = p2_st; + assign m_coin1 = p1_se; + assign m_coin2 = p2_se; + assign m_coin = p1_se | p2_se; + assign m_up = p1_up | p2_up | j1_up | j2_up; + assign m_down = p1_down | p2_down | j1_down | j2_down; + assign m_left = p1_left | p2_left | j1_left | j2_left; + assign m_right = p1_right | p2_right | j1_right | j2_right; + assign m_btn1 = p1_y | p2_y; + assign m_btn2 = p1_b | p2_b; + assign m_btn3 = p1_a | p2_a; + assign m_btn4 = p1_x | p2_x; + assign m_btn5 = p1_l1 | p2_l1; + assign m_btn6 = p1_r1 | p2_r1; + assign m_btn7 = p1_l2 | p2_l2; + assign m_btn8 = p1_r2 | p2_r2; + end + // Single Players for Arcade + else if(JOY_PADS == 1 && JOY_ALT == 0) begin + assign m_start1 = p1_st; + assign m_coin1 = p1_se; + assign m_coin = p1_se; + assign m_up = p1_up | j1_up; + assign m_down = p1_down | j1_down; + assign m_left = p1_left | j1_left; + assign m_right = p1_right | j1_right; + assign m_btn1 = p1_y; + assign m_btn2 = p1_b; + assign m_btn3 = p1_a; + assign m_btn4 = p1_x; + assign m_btn5 = p1_l1; + assign m_btn6 = p1_r1; + assign m_btn7 = p1_l2; + assign m_btn8 = p1_r2; + assign { m_start2, m_coin2 } = 2'h0; + end + else begin + assign { m_coin } = 1'h0; + assign { m_up, m_down, m_left, m_right } = 4'h0; + assign { m_btn1, m_btn2, m_btn3, m_btn4 } = 4'h0; + assign { m_btn5, m_btn6, m_btn7, m_btn8 } = 4'h0; + assign { m_coin1, m_coin2 } = 2'h0; + assign { m_start1, m_start2 } = 2'h0; + end + endgenerate + +endmodule diff --git a/platform/pocket/interface/interact.sv b/platform/pocket/interface/interact.sv index 1ad552d..3564c40 100644 --- a/platform/pocket/interface/interact.sv +++ b/platform/pocket/interface/interact.sv @@ -1,171 +1,171 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket Interact Controller for APF bridge -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module interact - ( - // Clocks and Reset - input logic clk_74a, - input logic clk_sync, - input logic reset_n, - // Pocket Bridge - input logic [31:0] bridge_addr, - input logic bridge_wr, - input logic [31:0] bridge_wr_data, - input logic bridge_rd, - output logic [31:0] bridge_rd_data = 32'h0, - // Dip Switches - output logic [7:0] dip_sw0, - output logic [7:0] dip_sw1, - output logic [7:0] dip_sw2, - output logic [7:0] dip_sw3, - // Extra DIP Switches - output logic [7:0] ext_sw0, - output logic [7:0] ext_sw1, - output logic [7:0] ext_sw2, - output logic [7:0] ext_sw3, - // Modifiers - output logic [7:0] mod_sw0, - output logic [7:0] mod_sw1, - output logic [7:0] mod_sw2, - output logic [7:0] mod_sw3, - // Status (Legacy Support) - output logic [63:0] status, - // Filters - output logic [3:0] scnl_sw, // Scanlines - output logic [3:0] smask_sw, // ShadowMask - output logic [3:0] afilter_sw, // Audio Filters - output logic [3:0] vol_att, // Volume Attenuation - // Service Mode Switch - output logic svc_sw, - // High Score NVRAM - output logic [15:0] nvram_size, // High Score Save Size - // Reset Core - output logic reset_sw - ); - - //! ------------------------------------------------------------------------ - //! Reset Handler - //! ------------------------------------------------------------------------ - reg [31:0] reset_counter; - reg reset_timer; - reg core_reset_n = 1'b1; - reg core_reset_r = 1'b1; - - always_ff @(posedge clk_74a) begin - if(reset_timer) begin - reset_counter <= 32'd8000; - core_reset_n <= 1'b0; - end - else begin - if (reset_counter == 32'h0) begin - core_reset_n <= 1'b1; - end - else begin - reset_counter <= reset_counter - 32'h1; - core_reset_n <= 1'b0; - end - end - end - - //! ------------------------------------------------------------------------ - //! Read/Write APF Bridge - //! ------------------------------------------------------------------------ - reg svc_mode = 1'h0; - reg [31:0] dip_switch = 32'h0; - reg [31:0] ext_switch = 32'h0; - reg [31:0] modifiers = 32'h0; - reg [31:0] filters = 32'h0; - reg [31:0] status_h = 32'h0; - reg [31:0] status_l = 32'h0; - reg [15:0] nvram_sz = 16'h0; - - always_ff @(posedge clk_74a) begin - reset_timer <= 0; //! Always default this to zero - if(bridge_wr) begin - case(bridge_addr) - 32'hF0000000: begin /* RESET ONLY */ reset_timer <= 1; end //! Reset Core Command - 32'hF0000010: begin svc_mode <= bridge_wr_data[0]; reset_timer <= 1; end //! Service Mode Switch - 32'hF1000000: begin dip_switch <= bridge_wr_data; reset_timer <= 1; end //! DIP Switches - 32'hF2000000: begin modifiers <= bridge_wr_data; end //! Modifiers - 32'hF3000000: begin filters <= bridge_wr_data; end //! A/V Filters - 32'hF4000000: begin ext_switch <= bridge_wr_data; reset_timer <= 1; end //! Extra DIP Switches - 32'hF5000000: begin nvram_sz <= bridge_wr_data[15:0]; end //! NVRAM Size - 32'hFA000000: begin status_l <= bridge_wr_data; end //! Status Low [31:0] - 32'hFB000000: begin status_h <= bridge_wr_data; end //! Status High [63:32] - endcase - end - if(bridge_rd) begin - case(bridge_addr) - 32'hF0000000: begin bridge_rd_data <= core_reset_r; end - 32'hF0000010: begin bridge_rd_data <= {31'h0, svc_mode}; end - 32'hF1000000: begin bridge_rd_data <= dip_switch; end - 32'hF2000000: begin bridge_rd_data <= modifiers; end - 32'hF3000000: begin bridge_rd_data <= filters; end - 32'hF4000000: begin bridge_rd_data <= ext_switch; end - 32'hF5000000: begin bridge_rd_data <= {16'h0, nvram_sz}; end - 32'hFA000000: begin bridge_rd_data <= status_l; end - 32'hFB000000: begin bridge_rd_data <= status_h; end - endcase - end - end - - //! ------------------------------------------------------------------------ - //! Sync and Assign Outputs - //! ------------------------------------------------------------------------ - wire [31:0] dip_switch_s, ext_switch_s, modifiers_s, filters_s, status_l_s, status_h_s, nvram_sz_s; - wire svc_mode_s, core_reset_s; - - synch_3 #(.WIDTH(32)) sync_dsw(dip_switch, dip_switch_s, clk_sync); - synch_3 #(.WIDTH(32)) sync_ext(ext_switch, ext_switch_s, clk_sync); - synch_3 #(.WIDTH(32)) sync_mod(modifiers, modifiers_s, clk_sync); - synch_3 #(.WIDTH(32)) sync_flr(filters, filters_s, clk_sync); - synch_3 #(.WIDTH(32)) sync_stl(status_l, status_l_s, clk_sync); - synch_3 #(.WIDTH(32)) sync_sth(status_h, status_h_s, clk_sync); - synch_3 sync_svc(svc_mode, svc_mode_s, clk_sync); - synch_3 sync_rst(core_reset_n, core_reset_s, clk_sync); - - always_comb begin - {dip_sw3, dip_sw2, dip_sw1, dip_sw0} = dip_switch_s; - {ext_sw3, ext_sw2, ext_sw1, ext_sw0} = ext_switch_s; - {mod_sw3, mod_sw2, mod_sw1, mod_sw0} = modifiers_s; - scnl_sw = filters_s[3:0]; - smask_sw = filters_s[7:4]; - afilter_sw = filters_s[11:8]; - vol_att = filters_s[15:12]; - nvram_size = nvram_sz; - svc_sw = svc_mode_s; - status = {status_h_s, status_l_s}; - reset_sw = ~(reset_n && core_reset_s); - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket Interact Controller for APF bridge +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module interact + ( + // Clocks and Reset + input logic clk_74a, + input logic clk_sync, + input logic reset_n, + // Pocket Bridge + input logic [31:0] bridge_addr, + input logic bridge_wr, + input logic [31:0] bridge_wr_data, + input logic bridge_rd, + output logic [31:0] bridge_rd_data = 32'h0, + // Dip Switches + output logic [7:0] dip_sw0, + output logic [7:0] dip_sw1, + output logic [7:0] dip_sw2, + output logic [7:0] dip_sw3, + // Extra DIP Switches + output logic [7:0] ext_sw0, + output logic [7:0] ext_sw1, + output logic [7:0] ext_sw2, + output logic [7:0] ext_sw3, + // Modifiers + output logic [7:0] mod_sw0, + output logic [7:0] mod_sw1, + output logic [7:0] mod_sw2, + output logic [7:0] mod_sw3, + // Status (Legacy Support) + output logic [63:0] status, + // Filters + output logic [3:0] scnl_sw, // Scanlines + output logic [3:0] smask_sw, // ShadowMask + output logic [3:0] afilter_sw, // Audio Filters + output logic [3:0] vol_att, // Volume Attenuation + // Service Mode Switch + output logic svc_sw, + // High Score NVRAM + output logic [15:0] nvram_size, // High Score Save Size + // Reset Core + output logic reset_sw + ); + + //! ------------------------------------------------------------------------ + //! Reset Handler + //! ------------------------------------------------------------------------ + reg [31:0] reset_counter; + reg reset_timer; + reg core_reset_n = 1'b1; + reg core_reset_r = 1'b1; + + always_ff @(posedge clk_74a) begin + if(reset_timer) begin + reset_counter <= 32'd8000; + core_reset_n <= 1'b0; + end + else begin + if (reset_counter == 32'h0) begin + core_reset_n <= 1'b1; + end + else begin + reset_counter <= reset_counter - 32'h1; + core_reset_n <= 1'b0; + end + end + end + + //! ------------------------------------------------------------------------ + //! Read/Write APF Bridge + //! ------------------------------------------------------------------------ + reg svc_mode = 1'h0; + reg [31:0] dip_switch = 32'h0; + reg [31:0] ext_switch = 32'h0; + reg [31:0] modifiers = 32'h0; + reg [31:0] filters = 32'h0; + reg [31:0] status_h = 32'h0; + reg [31:0] status_l = 32'h0; + reg [15:0] nvram_sz = 16'h0; + + always_ff @(posedge clk_74a) begin + reset_timer <= 0; //! Always default this to zero + if(bridge_wr) begin + case(bridge_addr) + 32'hF0000000: begin /* RESET ONLY */ reset_timer <= 1; end //! Reset Core Command + 32'hF0000010: begin svc_mode <= bridge_wr_data[0]; reset_timer <= 1; end //! Service Mode Switch + 32'hF1000000: begin dip_switch <= bridge_wr_data; reset_timer <= 1; end //! DIP Switches + 32'hF2000000: begin modifiers <= bridge_wr_data; end //! Modifiers + 32'hF3000000: begin filters <= bridge_wr_data; end //! A/V Filters + 32'hF4000000: begin ext_switch <= bridge_wr_data; reset_timer <= 1; end //! Extra DIP Switches + 32'hF5000000: begin nvram_sz <= bridge_wr_data[15:0]; end //! NVRAM Size + 32'hFA000000: begin status_l <= bridge_wr_data; end //! Status Low [31:0] + 32'hFB000000: begin status_h <= bridge_wr_data; end //! Status High [63:32] + endcase + end + if(bridge_rd) begin + case(bridge_addr) + 32'hF0000000: begin bridge_rd_data <= core_reset_r; end + 32'hF0000010: begin bridge_rd_data <= {31'h0, svc_mode}; end + 32'hF1000000: begin bridge_rd_data <= dip_switch; end + 32'hF2000000: begin bridge_rd_data <= modifiers; end + 32'hF3000000: begin bridge_rd_data <= filters; end + 32'hF4000000: begin bridge_rd_data <= ext_switch; end + 32'hF5000000: begin bridge_rd_data <= {16'h0, nvram_sz}; end + 32'hFA000000: begin bridge_rd_data <= status_l; end + 32'hFB000000: begin bridge_rd_data <= status_h; end + endcase + end + end + + //! ------------------------------------------------------------------------ + //! Sync and Assign Outputs + //! ------------------------------------------------------------------------ + wire [31:0] dip_switch_s, ext_switch_s, modifiers_s, filters_s, status_l_s, status_h_s, nvram_sz_s; + wire svc_mode_s, core_reset_s; + + synch_3 #(.WIDTH(32)) sync_dsw(dip_switch, dip_switch_s, clk_sync); + synch_3 #(.WIDTH(32)) sync_ext(ext_switch, ext_switch_s, clk_sync); + synch_3 #(.WIDTH(32)) sync_mod(modifiers, modifiers_s, clk_sync); + synch_3 #(.WIDTH(32)) sync_flr(filters, filters_s, clk_sync); + synch_3 #(.WIDTH(32)) sync_stl(status_l, status_l_s, clk_sync); + synch_3 #(.WIDTH(32)) sync_sth(status_h, status_h_s, clk_sync); + synch_3 sync_svc(svc_mode, svc_mode_s, clk_sync); + synch_3 sync_rst(core_reset_n, core_reset_s, clk_sync); + + always_comb begin + {dip_sw3, dip_sw2, dip_sw1, dip_sw0} = dip_switch_s; + {ext_sw3, ext_sw2, ext_sw1, ext_sw0} = ext_switch_s; + {mod_sw3, mod_sw2, mod_sw1, mod_sw0} = modifiers_s; + scnl_sw = filters_s[3:0]; + smask_sw = filters_s[7:4]; + afilter_sw = filters_s[11:8]; + vol_att = filters_s[15:12]; + nvram_size = nvram_sz; + svc_sw = svc_mode_s; + status = {status_h_s, status_l_s}; + reset_sw = ~(reset_n && core_reset_s); + end + +endmodule \ No newline at end of file diff --git a/platform/pocket/interface/joypad.sv b/platform/pocket/interface/joypad.sv index b29826a..b53298d 100644 --- a/platform/pocket/interface/joypad.sv +++ b/platform/pocket/interface/joypad.sv @@ -1,127 +1,127 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket Gamepad Controller -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ -// Shift joystick interface through 3-stages of registers and output the -// synchronized signal -// -// The value of cont_key is transferred to pkey_s1. -// The value of pkey_s1 (from the previous clock cycle) is transferred to pkey_s2. -// The value of pkey_s2 (from two clock cycles ago) is transferred to pkey_s, -// which is in the target clock domain. -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module joypad - #( - parameter DEADZONE = 8'h10 //! Set Controller Deadzone - ) ( - input wire clk_sys, //! Clock to Sync To (eg: clk_sys) - // Pocket PAD Interface - input wire [31:0] cont_key, cont_joy, //! Gamepad/Analog Joystick - // DPAD - output wire key_up, key_down, key_left, key_right, //! D-PAD - output wire key_a, key_b, key_x, key_y, //! Face Buttons - output wire key_l1, key_l2, key_l3, //! Left Shoulder/Trigger/Analog Buttons - output wire key_r1, key_r2, key_r3, //! Right Shoulder/Trigger/Analog Buttons - output wire key_se, key_st, //! Select and Start Buttons - // Analog Stick - output wire joy_up , joy_down, joy_left, joy_right, //! Analog 2 DPAD - output wire [7:0] joy_lx, joy_ly, joy_rx, joy_ry, //! Left/Right Analog Stick - // Type - output wire [3:0] pad_type //! Controller Type - ); - - //! ------------------------------------------------------------------------ - //! Gamepad - //! ------------------------------------------------------------------------ - reg [31:0] pkey_s; //! Synced Joystick Register - reg [31:0] pkey_s1, pkey_s2; //! Registers for Synchronization - - always_ff @(posedge clk_sys) begin : syncKey - {pkey_s, pkey_s2, pkey_s1} <= {pkey_s2, pkey_s1, cont_key}; - end - - // D-PAD - assign key_up = pkey_s[0]; - assign key_down = pkey_s[1]; - assign key_left = pkey_s[2]; - assign key_right = pkey_s[3]; - // Face Buttons - assign key_y = pkey_s[7]; - assign key_x = pkey_s[6]; - assign key_b = pkey_s[5]; - assign key_a = pkey_s[4]; - // Shoulder/Trigger Buttons - assign key_l1 = pkey_s[8]; - assign key_r1 = pkey_s[9]; - assign key_l2 = pkey_s[10]; - assign key_r2 = pkey_s[11]; - assign key_l3 = pkey_s[12]; - assign key_r3 = pkey_s[13]; - // Select and Start Buttons - assign key_se = pkey_s[14]; - assign key_st = pkey_s[15]; - // Controller Type - assign pad_type = pkey_s[31:28]; - - //! ------------------------------------------------------------------------ - //! Analog Stick - //! ------------------------------------------------------------------------ - reg [31:0] pjoy_s; //! Synced Analog Register - reg [31:0] pjoy_s1, pjoy_s2; //! 2-stage register for synchronization - - // Shift joystick interface through two stages of registers and output the synchronized signal - always_ff @(posedge clk_sys) begin : syncJoy - {pjoy_s, pjoy_s2, pjoy_s1} <= {pjoy_s2, pjoy_s1, cont_joy}; - end - - // Analog Stick | 0x00 > 0x80 < 0xFF - assign joy_lx = pjoy_s[7:0]; - assign joy_ly = pjoy_s[15:8]; - assign joy_rx = pjoy_s[23:16]; - assign joy_ry = pjoy_s[31:24]; - - // Analog to DPAD - analog2dpad #(.DEADZONE(DEADZONE)) analog2dpad - ( - .clk_sys ( clk_sys ), - .pad_type ( pad_type ), - .joy_lx ( joy_lx ), - .joy_ly ( joy_ly ), - .joy_rx ( joy_rx ), - .joy_ry ( joy_ry ), - .joy_left ( joy_left ), - .joy_right ( joy_right ), - .joy_up ( joy_up ), - .joy_down ( joy_down ) - ); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket Gamepad Controller +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ +// Shift joystick interface through 3-stages of registers and output the +// synchronized signal +// +// The value of cont_key is transferred to pkey_s1. +// The value of pkey_s1 (from the previous clock cycle) is transferred to pkey_s2. +// The value of pkey_s2 (from two clock cycles ago) is transferred to pkey_s, +// which is in the target clock domain. +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module joypad + #( + parameter DEADZONE = 8'h10 //! Set Controller Deadzone + ) ( + input wire clk_sys, //! Clock to Sync To (eg: clk_sys) + // Pocket PAD Interface + input wire [31:0] cont_key, cont_joy, //! Gamepad/Analog Joystick + // DPAD + output wire key_up, key_down, key_left, key_right, //! D-PAD + output wire key_a, key_b, key_x, key_y, //! Face Buttons + output wire key_l1, key_l2, key_l3, //! Left Shoulder/Trigger/Analog Buttons + output wire key_r1, key_r2, key_r3, //! Right Shoulder/Trigger/Analog Buttons + output wire key_se, key_st, //! Select and Start Buttons + // Analog Stick + output wire joy_up , joy_down, joy_left, joy_right, //! Analog 2 DPAD + output wire [7:0] joy_lx, joy_ly, joy_rx, joy_ry, //! Left/Right Analog Stick + // Type + output wire [3:0] pad_type //! Controller Type + ); + + //! ------------------------------------------------------------------------ + //! Gamepad + //! ------------------------------------------------------------------------ + reg [31:0] pkey_s; //! Synced Joystick Register + reg [31:0] pkey_s1, pkey_s2; //! Registers for Synchronization + + always_ff @(posedge clk_sys) begin : syncKey + {pkey_s, pkey_s2, pkey_s1} <= {pkey_s2, pkey_s1, cont_key}; + end + + // D-PAD + assign key_up = pkey_s[0]; + assign key_down = pkey_s[1]; + assign key_left = pkey_s[2]; + assign key_right = pkey_s[3]; + // Face Buttons + assign key_y = pkey_s[7]; + assign key_x = pkey_s[6]; + assign key_b = pkey_s[5]; + assign key_a = pkey_s[4]; + // Shoulder/Trigger Buttons + assign key_l1 = pkey_s[8]; + assign key_r1 = pkey_s[9]; + assign key_l2 = pkey_s[10]; + assign key_r2 = pkey_s[11]; + assign key_l3 = pkey_s[12]; + assign key_r3 = pkey_s[13]; + // Select and Start Buttons + assign key_se = pkey_s[14]; + assign key_st = pkey_s[15]; + // Controller Type + assign pad_type = pkey_s[31:28]; + + //! ------------------------------------------------------------------------ + //! Analog Stick + //! ------------------------------------------------------------------------ + reg [31:0] pjoy_s; //! Synced Analog Register + reg [31:0] pjoy_s1, pjoy_s2; //! 2-stage register for synchronization + + // Shift joystick interface through two stages of registers and output the synchronized signal + always_ff @(posedge clk_sys) begin : syncJoy + {pjoy_s, pjoy_s2, pjoy_s1} <= {pjoy_s2, pjoy_s1, cont_joy}; + end + + // Analog Stick | 0x00 > 0x80 < 0xFF + assign joy_lx = pjoy_s[7:0]; + assign joy_ly = pjoy_s[15:8]; + assign joy_rx = pjoy_s[23:16]; + assign joy_ry = pjoy_s[31:24]; + + // Analog to DPAD + analog2dpad #(.DEADZONE(DEADZONE)) analog2dpad + ( + .clk_sys ( clk_sys ), + .pad_type ( pad_type ), + .joy_lx ( joy_lx ), + .joy_ly ( joy_ly ), + .joy_rx ( joy_rx ), + .joy_ry ( joy_ry ), + .joy_left ( joy_left ), + .joy_right ( joy_right ), + .joy_up ( joy_up ), + .joy_down ( joy_down ) + ); + +endmodule diff --git a/platform/pocket/interface/keyboard/apf2hid.sv b/platform/pocket/interface/keyboard/apf2hid.sv index afa1c4e..02df0d4 100644 --- a/platform/pocket/interface/keyboard/apf2hid.sv +++ b/platform/pocket/interface/keyboard/apf2hid.sv @@ -1,83 +1,83 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module apf2hid - ( - // Clock and Reset - input logic clk, //! Clock - input logic reset, //! Reset - // APF Keyboard Port - input logic [31:0] cont3_key, //! Modifiers/Input Type - input logic [31:0] cont3_joy, //! Scan code 1-4 - input logic [15:0] cont3_trig, //! Scan code 5-6 - // USB Keyboard Output - output logic [63:0] usb_kb_hid, //! 64-bit HID Report - output logic [7:0] usb_kb_mod, //! Modifiers - output logic [7:0] usb_kb_sc1, //! Scan Code 1 - output logic [7:0] usb_kb_sc2, //! Scan Code 2 - output logic [7:0] usb_kb_sc3, //! Scan Code 3 - output logic [7:0] usb_kb_sc4, //! Scan Code 4 - output logic [7:0] usb_kb_sc5, //! Scan Code 5 - output logic [7:0] usb_kb_sc6 //! Scan Code 6 - ); - - // USB Keyboard Check - reg [3:0] key_type, key_type_s1, key_type_s2; - wire is_keyboard = (key_type == 4'h4) ? 1'b1 : 1'b0; // APF Keyboard Check - - always_ff @(posedge clk) begin : syncType - {key_type, key_type_s2, key_type_s1} <= {key_type_s2, key_type_s1, cont3_key[31:28]}; - end - - // USB HID Scancodes/Key Modifiers - wire [7:0] usb_kb_res = 8'h00; // HID Report Reserved - wire [63:0] apf_scancodes = {cont3_key[15:8], usb_kb_res, cont3_joy[31:0], cont3_trig[15:0]}; // APF HID Scancodes/Key Modifiers - reg [63:0] kb_scancodes, kb_scancodes_s1, kb_scancodes_s2; - - always_ff @(posedge clk) begin : syncKey - kb_scancodes <= kb_scancodes_s2; - kb_scancodes_s2 <= kb_scancodes_s1; - kb_scancodes_s1 <= apf_scancodes; - end - - // USB Keyboard Output - assign usb_kb_hid = is_keyboard ? kb_scancodes : 64'h00; // HID Report - assign usb_kb_mod = is_keyboard ? kb_scancodes[63:56] : 8'h00; // Modifier keys - assign usb_kb_sc1 = is_keyboard ? kb_scancodes[47:40] : 8'h00; // Keycode 1 - assign usb_kb_sc2 = is_keyboard ? kb_scancodes[39:32] : 8'h00; // Keycode 2 - assign usb_kb_sc3 = is_keyboard ? kb_scancodes[31:24] : 8'h00; // Keycode 3 - assign usb_kb_sc4 = is_keyboard ? kb_scancodes[23:16] : 8'h00; // Keycode 4 - assign usb_kb_sc5 = is_keyboard ? kb_scancodes[15:08] : 8'h00; // Keycode 5 - assign usb_kb_sc6 = is_keyboard ? kb_scancodes[07:00] : 8'h00; // Keycode 6 - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module apf2hid + ( + // Clock and Reset + input logic clk, //! Clock + input logic reset, //! Reset + // APF Keyboard Port + input logic [31:0] cont3_key, //! Modifiers/Input Type + input logic [31:0] cont3_joy, //! Scan code 1-4 + input logic [15:0] cont3_trig, //! Scan code 5-6 + // USB Keyboard Output + output logic [63:0] usb_kb_hid, //! 64-bit HID Report + output logic [7:0] usb_kb_mod, //! Modifiers + output logic [7:0] usb_kb_sc1, //! Scan Code 1 + output logic [7:0] usb_kb_sc2, //! Scan Code 2 + output logic [7:0] usb_kb_sc3, //! Scan Code 3 + output logic [7:0] usb_kb_sc4, //! Scan Code 4 + output logic [7:0] usb_kb_sc5, //! Scan Code 5 + output logic [7:0] usb_kb_sc6 //! Scan Code 6 + ); + + // USB Keyboard Check + reg [3:0] key_type, key_type_s1, key_type_s2; + wire is_keyboard = (key_type == 4'h4) ? 1'b1 : 1'b0; // APF Keyboard Check + + always_ff @(posedge clk) begin : syncType + {key_type, key_type_s2, key_type_s1} <= {key_type_s2, key_type_s1, cont3_key[31:28]}; + end + + // USB HID Scancodes/Key Modifiers + wire [7:0] usb_kb_res = 8'h00; // HID Report Reserved + wire [63:0] apf_scancodes = {cont3_key[15:8], usb_kb_res, cont3_joy[31:0], cont3_trig[15:0]}; // APF HID Scancodes/Key Modifiers + reg [63:0] kb_scancodes, kb_scancodes_s1, kb_scancodes_s2; + + always_ff @(posedge clk) begin : syncKey + kb_scancodes <= kb_scancodes_s2; + kb_scancodes_s2 <= kb_scancodes_s1; + kb_scancodes_s1 <= apf_scancodes; + end + + // USB Keyboard Output + assign usb_kb_hid = is_keyboard ? kb_scancodes : 64'h00; // HID Report + assign usb_kb_mod = is_keyboard ? kb_scancodes[63:56] : 8'h00; // Modifier keys + assign usb_kb_sc1 = is_keyboard ? kb_scancodes[47:40] : 8'h00; // Keycode 1 + assign usb_kb_sc2 = is_keyboard ? kb_scancodes[39:32] : 8'h00; // Keycode 2 + assign usb_kb_sc3 = is_keyboard ? kb_scancodes[31:24] : 8'h00; // Keycode 3 + assign usb_kb_sc4 = is_keyboard ? kb_scancodes[23:16] : 8'h00; // Keycode 4 + assign usb_kb_sc5 = is_keyboard ? kb_scancodes[15:08] : 8'h00; // Keycode 5 + assign usb_kb_sc6 = is_keyboard ? kb_scancodes[07:00] : 8'h00; // Keycode 6 + +endmodule diff --git a/platform/pocket/interface/keyboard/hid2ps2_key.sv b/platform/pocket/interface/keyboard/hid2ps2_key.sv index 304d7c7..bc4f5bd 100644 --- a/platform/pocket/interface/keyboard/hid2ps2_key.sv +++ b/platform/pocket/interface/keyboard/hid2ps2_key.sv @@ -1,232 +1,232 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module hid2ps2_key - ( - input logic clk, //! System Clock - input logic [7:0] usb, //! USB HID ID - output logic [8:0] ps2 //! PS/2 Scancode - ); - - // Set the ram style to control implementation. - (* ramstyle = "no_rw_check" *) - logic [8:0] rom[0:255]; - - always_ff @(posedge clk) begin : ps2Scancode - ps2 <= rom[usb]; - end - - // Initialize the lookup table with default values - initial begin : generateTable - for (int i = 0; i < 256; i = i + 1) begin : setDefaultValues - rom[i] = 9'h000; // Default value (no translation) - end - - // Define translations for specific USB HID codes - rom[8'h00] = 9'h000; // Reserved (no event indicated) - rom[8'h01] = 9'h000; // Keyboard Error Roll Over - used for all slots if too many keys are pressed ("Phantom key") - rom[8'h02] = 9'h000; // POST Fail - rom[8'h03] = 9'h000; // Error Undefined - rom[8'h04] = 9'h01C; // a and A - rom[8'h05] = 9'h032; // b and B - rom[8'h06] = 9'h021; // c and C - rom[8'h07] = 9'h023; // d and D - rom[8'h08] = 9'h024; // e and E - rom[8'h09] = 9'h02B; // f and F - rom[8'h0A] = 9'h034; // g and G - rom[8'h0B] = 9'h033; // h and H - rom[8'h0C] = 9'h043; // i and I - rom[8'h0D] = 9'h03B; // j and J - rom[8'h0E] = 9'h042; // k and K - rom[8'h0F] = 9'h04B; // l and L - rom[8'h10] = 9'h03A; // m and M - rom[8'h11] = 9'h031; // n and N - rom[8'h12] = 9'h044; // o and O - rom[8'h13] = 9'h04D; // p and P - rom[8'h14] = 9'h015; // q and Q - rom[8'h15] = 9'h02D; // r and R - rom[8'h16] = 9'h01B; // s and S - rom[8'h17] = 9'h02C; // t and T - rom[8'h18] = 9'h03C; // u and U - rom[8'h19] = 9'h02A; // v and V - rom[8'h1A] = 9'h01D; // w and W - rom[8'h1B] = 9'h022; // x and X - rom[8'h1C] = 9'h035; // y and Y - rom[8'h1D] = 9'h01A; // z and Z - rom[8'h1E] = 9'h016; // 1 and ! - rom[8'h1F] = 9'h01E; // 2 and @ - rom[8'h20] = 9'h026; // 3 and # - rom[8'h21] = 9'h025; // 4 and $ - rom[8'h22] = 9'h02E; // 5 and % - rom[8'h23] = 9'h036; // 6 and ^ - rom[8'h24] = 9'h03D; // 7 and & - rom[8'h25] = 9'h03E; // 8 and * - rom[8'h26] = 9'h046; // 9 and ( - rom[8'h27] = 9'h045; // 0 and ) - rom[8'h28] = 9'h05A; // Return (ENTER) - rom[8'h29] = 9'h076; // ESCAPE - rom[8'h2A] = 9'h066; // DELETE (Backspace) - rom[8'h2B] = 9'h00D; // Tab - rom[8'h2C] = 9'h029; // Spacebar - rom[8'h2D] = 9'h04E; // - and (underscore) - rom[8'h2E] = 9'h055; // = and + - rom[8'h2F] = 9'h054; // [ and { - rom[8'h30] = 9'h05B; // ] and } - rom[8'h31] = 9'h05D; // \ and | - rom[8'h32] = 9'h05D; // Non-US # and ~ - rom[8'h33] = 9'h04C; // ; and : - rom[8'h34] = 9'h052; // ' and " - rom[8'h35] = 9'h00E; // Grave Accent and Tilde - rom[8'h36] = 9'h041; // Keyboard, and < - rom[8'h37] = 9'h049; // . and > - rom[8'h38] = 9'h04A; // / and ? - rom[8'h39] = 9'h058; // Caps Lock - rom[8'h3A] = 9'h005; // F1 - rom[8'h3B] = 9'h006; // F2 - rom[8'h3C] = 9'h004; // F3 - rom[8'h3D] = 9'h00C; // F4 - rom[8'h3E] = 9'h003; // F5 - rom[8'h3F] = 9'h00B; // F6 - rom[8'h40] = 9'h083; // F7 - rom[8'h41] = 9'h00A; // F8 - rom[8'h42] = 9'h001; // F9 - rom[8'h43] = 9'h009; // F10 - rom[8'h44] = 9'h078; // F11 - rom[8'h45] = 9'h007; // F12 - rom[8'h46] = 9'h17C; // Print Screen - rom[8'h47] = 9'h07E; // Scroll Lock - rom[8'h48] = 9'h000; // Pause - rom[8'h49] = 9'h170; // Insert - rom[8'h4A] = 9'h16C; // Home - rom[8'h4B] = 9'h17D; // Page Up - rom[8'h4C] = 9'h171; // Delete Forward - rom[8'h4D] = 9'h169; // End - rom[8'h4E] = 9'h17A; // Page Down - rom[8'h4F] = 9'h174; // Right Arrow - rom[8'h50] = 9'h16B; // Left Arrow - rom[8'h51] = 9'h172; // Down Arrow - rom[8'h52] = 9'h175; // Up Arrow - rom[8'h53] = 9'h077; // Keypad Num Lock and Clear - rom[8'h54] = 9'h14A; // Keypad / - rom[8'h55] = 9'h07C; // Keypad * - rom[8'h56] = 9'h07B; // Keypad - - rom[8'h57] = 9'h079; // Keypad + - rom[8'h58] = 9'h15A; // Keypad ENTER - rom[8'h59] = 9'h069; // Keypad 1 and End - rom[8'h5A] = 9'h072; // Keypad 2 and Down Arrow - rom[8'h5B] = 9'h07A; // Keypad 3 and PageDn - rom[8'h5C] = 9'h06B; // Keypad 4 and Left Arrow - rom[8'h5D] = 9'h073; // Keypad 5 - rom[8'h5E] = 9'h074; // Keypad 6 and Right Arrow - rom[8'h5F] = 9'h06C; // Keypad 7 and Home - rom[8'h60] = 9'h075; // Keypad 8 and Up Arrow - rom[8'h61] = 9'h07D; // Keypad 9 and PageUp - rom[8'h62] = 9'h070; // Keypad 0 and Insert - rom[8'h63] = 9'h071; // Keypad . and Delete - // Extra Keys - rom[8'h64] = 9'h061; // Non-US \ and | - 102nd - rom[8'h65] = 9'h12F; // Application - rom[8'h66] = 9'h137; // Power - rom[8'h67] = 9'h00F; // Keypad = - rom[8'h68] = 9'h008; // F13 - rom[8'h69] = 9'h010; // F14 - rom[8'h6A] = 9'h018; // F15 - rom[8'h6B] = 9'h020; // F16 - rom[8'h6C] = 9'h028; // F17 - rom[8'h6D] = 9'h030; // F18 - rom[8'h6E] = 9'h038; // F19 - rom[8'h6F] = 9'h040; // F20 - rom[8'h70] = 9'h048; // F21 - rom[8'h71] = 9'h050; // F22 - rom[8'h72] = 9'h057; // F23 - rom[8'h73] = 9'h05F; // F24 - rom[8'h74] = 9'h000; // Execute - rom[8'h75] = 9'h000; // Help - rom[8'h76] = 9'h000; // Menu - rom[8'h77] = 9'h000; // Select - rom[8'h78] = 9'h000; // Stop - rom[8'h79] = 9'h000; // Again - rom[8'h7A] = 9'h000; // Undo - rom[8'h7B] = 9'h000; // Cut - rom[8'h7C] = 9'h000; // Copy - rom[8'h7D] = 9'h000; // Paste - rom[8'h7E] = 9'h000; // Find - rom[8'h7F] = 9'h000; // Mute - rom[8'h80] = 9'h000; // Volume Up - rom[8'h81] = 9'h000; // Volume Down - rom[8'h82] = 9'h000; // Locking Caps Lock - rom[8'h83] = 9'h000; // Locking Num Lock - rom[8'h84] = 9'h000; // Locking Scroll Lock - rom[8'h85] = 9'h06D; // Keypad Comma - rom[8'h86] = 9'h000; // Keypad Equal Sign - rom[8'h87] = 9'h051; // International1 - Ro - rom[8'h88] = 9'h013; // International2 - Katakana/Hiragana - rom[8'h89] = 9'h06A; // International3 - Yen - rom[8'h8A] = 9'h064; // International4 - Henkan - rom[8'h8B] = 9'h067; // International5 - Muhenkan - rom[8'h8C] = 9'h027; // International6 - Keypad JP Comma - rom[8'h8D] = 9'h000; // International7 - rom[8'h8E] = 9'h000; // International8 - rom[8'h8F] = 9'h000; // International9 - rom[8'h90] = 9'h0F2; // LANG1 - Hangeul - rom[8'h91] = 9'h0F1; // LANG2 - Hanja - rom[8'h92] = 9'h063; // LANG3 - Katakana - rom[8'h93] = 9'h062; // LANG4 - Hiragana - rom[8'h94] = 9'h05F; // LANG5 - Zenkaku/Hankaku - rom[8'h95] = 9'h000; // LANG6 - rom[8'h96] = 9'h000; // LANG7 - rom[8'h97] = 9'h000; // LANG8 - rom[8'h98] = 9'h000; // LANG9 - rom[8'h99] = 9'h000; // Alternate Erase - rom[8'h9A] = 9'h000; // SysReq/Attention - rom[8'h9B] = 9'h000; // Cancel - rom[8'h9C] = 9'h000; // Clear - rom[8'h9D] = 9'h000; // Prior - rom[8'h9E] = 9'h000; // Return - rom[8'h9F] = 9'h000; // Separator - rom[8'hA0] = 9'h000; // Out - rom[8'hA1] = 9'h000; // Oper - rom[8'hA2] = 9'h000; // Clear/Again - rom[8'hA3] = 9'h000; // CrSel/Props - rom[8'hA4] = 9'h000; // ExSel - rom[8'hE0] = 9'h014; // Left Control - rom[8'hE1] = 9'h012; // Left Shift - rom[8'hE2] = 9'h011; // Left Alt - rom[8'hE3] = 9'h11F; // Left GUI - rom[8'hE4] = 9'h114; // Right Control - rom[8'hE5] = 9'h059; // Right Shift - rom[8'hE6] = 9'h111; // Right Alt - rom[8'hE7] = 9'h127; // Right GUI - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module hid2ps2_key + ( + input logic clk, //! System Clock + input logic [7:0] usb, //! USB HID ID + output logic [8:0] ps2 //! PS/2 Scancode + ); + + // Set the ram style to control implementation. + (* ramstyle = "no_rw_check" *) + logic [8:0] rom[0:255]; + + always_ff @(posedge clk) begin : ps2Scancode + ps2 <= rom[usb]; + end + + // Initialize the lookup table with default values + initial begin : generateTable + for (int i = 0; i < 256; i = i + 1) begin : setDefaultValues + rom[i] = 9'h000; // Default value (no translation) + end + + // Define translations for specific USB HID codes + rom[8'h00] = 9'h000; // Reserved (no event indicated) + rom[8'h01] = 9'h000; // Keyboard Error Roll Over - used for all slots if too many keys are pressed ("Phantom key") + rom[8'h02] = 9'h000; // POST Fail + rom[8'h03] = 9'h000; // Error Undefined + rom[8'h04] = 9'h01C; // a and A + rom[8'h05] = 9'h032; // b and B + rom[8'h06] = 9'h021; // c and C + rom[8'h07] = 9'h023; // d and D + rom[8'h08] = 9'h024; // e and E + rom[8'h09] = 9'h02B; // f and F + rom[8'h0A] = 9'h034; // g and G + rom[8'h0B] = 9'h033; // h and H + rom[8'h0C] = 9'h043; // i and I + rom[8'h0D] = 9'h03B; // j and J + rom[8'h0E] = 9'h042; // k and K + rom[8'h0F] = 9'h04B; // l and L + rom[8'h10] = 9'h03A; // m and M + rom[8'h11] = 9'h031; // n and N + rom[8'h12] = 9'h044; // o and O + rom[8'h13] = 9'h04D; // p and P + rom[8'h14] = 9'h015; // q and Q + rom[8'h15] = 9'h02D; // r and R + rom[8'h16] = 9'h01B; // s and S + rom[8'h17] = 9'h02C; // t and T + rom[8'h18] = 9'h03C; // u and U + rom[8'h19] = 9'h02A; // v and V + rom[8'h1A] = 9'h01D; // w and W + rom[8'h1B] = 9'h022; // x and X + rom[8'h1C] = 9'h035; // y and Y + rom[8'h1D] = 9'h01A; // z and Z + rom[8'h1E] = 9'h016; // 1 and ! + rom[8'h1F] = 9'h01E; // 2 and @ + rom[8'h20] = 9'h026; // 3 and # + rom[8'h21] = 9'h025; // 4 and $ + rom[8'h22] = 9'h02E; // 5 and % + rom[8'h23] = 9'h036; // 6 and ^ + rom[8'h24] = 9'h03D; // 7 and & + rom[8'h25] = 9'h03E; // 8 and * + rom[8'h26] = 9'h046; // 9 and ( + rom[8'h27] = 9'h045; // 0 and ) + rom[8'h28] = 9'h05A; // Return (ENTER) + rom[8'h29] = 9'h076; // ESCAPE + rom[8'h2A] = 9'h066; // DELETE (Backspace) + rom[8'h2B] = 9'h00D; // Tab + rom[8'h2C] = 9'h029; // Spacebar + rom[8'h2D] = 9'h04E; // - and (underscore) + rom[8'h2E] = 9'h055; // = and + + rom[8'h2F] = 9'h054; // [ and { + rom[8'h30] = 9'h05B; // ] and } + rom[8'h31] = 9'h05D; // \ and | + rom[8'h32] = 9'h05D; // Non-US # and ~ + rom[8'h33] = 9'h04C; // ; and : + rom[8'h34] = 9'h052; // ' and " + rom[8'h35] = 9'h00E; // Grave Accent and Tilde + rom[8'h36] = 9'h041; // Keyboard, and < + rom[8'h37] = 9'h049; // . and > + rom[8'h38] = 9'h04A; // / and ? + rom[8'h39] = 9'h058; // Caps Lock + rom[8'h3A] = 9'h005; // F1 + rom[8'h3B] = 9'h006; // F2 + rom[8'h3C] = 9'h004; // F3 + rom[8'h3D] = 9'h00C; // F4 + rom[8'h3E] = 9'h003; // F5 + rom[8'h3F] = 9'h00B; // F6 + rom[8'h40] = 9'h083; // F7 + rom[8'h41] = 9'h00A; // F8 + rom[8'h42] = 9'h001; // F9 + rom[8'h43] = 9'h009; // F10 + rom[8'h44] = 9'h078; // F11 + rom[8'h45] = 9'h007; // F12 + rom[8'h46] = 9'h17C; // Print Screen + rom[8'h47] = 9'h07E; // Scroll Lock + rom[8'h48] = 9'h000; // Pause + rom[8'h49] = 9'h170; // Insert + rom[8'h4A] = 9'h16C; // Home + rom[8'h4B] = 9'h17D; // Page Up + rom[8'h4C] = 9'h171; // Delete Forward + rom[8'h4D] = 9'h169; // End + rom[8'h4E] = 9'h17A; // Page Down + rom[8'h4F] = 9'h174; // Right Arrow + rom[8'h50] = 9'h16B; // Left Arrow + rom[8'h51] = 9'h172; // Down Arrow + rom[8'h52] = 9'h175; // Up Arrow + rom[8'h53] = 9'h077; // Keypad Num Lock and Clear + rom[8'h54] = 9'h14A; // Keypad / + rom[8'h55] = 9'h07C; // Keypad * + rom[8'h56] = 9'h07B; // Keypad - + rom[8'h57] = 9'h079; // Keypad + + rom[8'h58] = 9'h15A; // Keypad ENTER + rom[8'h59] = 9'h069; // Keypad 1 and End + rom[8'h5A] = 9'h072; // Keypad 2 and Down Arrow + rom[8'h5B] = 9'h07A; // Keypad 3 and PageDn + rom[8'h5C] = 9'h06B; // Keypad 4 and Left Arrow + rom[8'h5D] = 9'h073; // Keypad 5 + rom[8'h5E] = 9'h074; // Keypad 6 and Right Arrow + rom[8'h5F] = 9'h06C; // Keypad 7 and Home + rom[8'h60] = 9'h075; // Keypad 8 and Up Arrow + rom[8'h61] = 9'h07D; // Keypad 9 and PageUp + rom[8'h62] = 9'h070; // Keypad 0 and Insert + rom[8'h63] = 9'h071; // Keypad . and Delete + // Extra Keys + rom[8'h64] = 9'h061; // Non-US \ and | - 102nd + rom[8'h65] = 9'h12F; // Application + rom[8'h66] = 9'h137; // Power + rom[8'h67] = 9'h00F; // Keypad = + rom[8'h68] = 9'h008; // F13 + rom[8'h69] = 9'h010; // F14 + rom[8'h6A] = 9'h018; // F15 + rom[8'h6B] = 9'h020; // F16 + rom[8'h6C] = 9'h028; // F17 + rom[8'h6D] = 9'h030; // F18 + rom[8'h6E] = 9'h038; // F19 + rom[8'h6F] = 9'h040; // F20 + rom[8'h70] = 9'h048; // F21 + rom[8'h71] = 9'h050; // F22 + rom[8'h72] = 9'h057; // F23 + rom[8'h73] = 9'h05F; // F24 + rom[8'h74] = 9'h000; // Execute + rom[8'h75] = 9'h000; // Help + rom[8'h76] = 9'h000; // Menu + rom[8'h77] = 9'h000; // Select + rom[8'h78] = 9'h000; // Stop + rom[8'h79] = 9'h000; // Again + rom[8'h7A] = 9'h000; // Undo + rom[8'h7B] = 9'h000; // Cut + rom[8'h7C] = 9'h000; // Copy + rom[8'h7D] = 9'h000; // Paste + rom[8'h7E] = 9'h000; // Find + rom[8'h7F] = 9'h000; // Mute + rom[8'h80] = 9'h000; // Volume Up + rom[8'h81] = 9'h000; // Volume Down + rom[8'h82] = 9'h000; // Locking Caps Lock + rom[8'h83] = 9'h000; // Locking Num Lock + rom[8'h84] = 9'h000; // Locking Scroll Lock + rom[8'h85] = 9'h06D; // Keypad Comma + rom[8'h86] = 9'h000; // Keypad Equal Sign + rom[8'h87] = 9'h051; // International1 - Ro + rom[8'h88] = 9'h013; // International2 - Katakana/Hiragana + rom[8'h89] = 9'h06A; // International3 - Yen + rom[8'h8A] = 9'h064; // International4 - Henkan + rom[8'h8B] = 9'h067; // International5 - Muhenkan + rom[8'h8C] = 9'h027; // International6 - Keypad JP Comma + rom[8'h8D] = 9'h000; // International7 + rom[8'h8E] = 9'h000; // International8 + rom[8'h8F] = 9'h000; // International9 + rom[8'h90] = 9'h0F2; // LANG1 - Hangeul + rom[8'h91] = 9'h0F1; // LANG2 - Hanja + rom[8'h92] = 9'h063; // LANG3 - Katakana + rom[8'h93] = 9'h062; // LANG4 - Hiragana + rom[8'h94] = 9'h05F; // LANG5 - Zenkaku/Hankaku + rom[8'h95] = 9'h000; // LANG6 + rom[8'h96] = 9'h000; // LANG7 + rom[8'h97] = 9'h000; // LANG8 + rom[8'h98] = 9'h000; // LANG9 + rom[8'h99] = 9'h000; // Alternate Erase + rom[8'h9A] = 9'h000; // SysReq/Attention + rom[8'h9B] = 9'h000; // Cancel + rom[8'h9C] = 9'h000; // Clear + rom[8'h9D] = 9'h000; // Prior + rom[8'h9E] = 9'h000; // Return + rom[8'h9F] = 9'h000; // Separator + rom[8'hA0] = 9'h000; // Out + rom[8'hA1] = 9'h000; // Oper + rom[8'hA2] = 9'h000; // Clear/Again + rom[8'hA3] = 9'h000; // CrSel/Props + rom[8'hA4] = 9'h000; // ExSel + rom[8'hE0] = 9'h014; // Left Control + rom[8'hE1] = 9'h012; // Left Shift + rom[8'hE2] = 9'h011; // Left Alt + rom[8'hE3] = 9'h11F; // Left GUI + rom[8'hE4] = 9'h114; // Right Control + rom[8'hE5] = 9'h059; // Right Shift + rom[8'hE6] = 9'h111; // Right Alt + rom[8'hE7] = 9'h127; // Right GUI + end + +endmodule diff --git a/platform/pocket/interface/keyboard/hid2ps2_mod.sv b/platform/pocket/interface/keyboard/hid2ps2_mod.sv index cde4692..92bb0b9 100644 --- a/platform/pocket/interface/keyboard/hid2ps2_mod.sv +++ b/platform/pocket/interface/keyboard/hid2ps2_mod.sv @@ -1,52 +1,52 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module hid2ps2_mod - ( - input logic clk, - input logic [7:0] usb, - output logic [71:0] ps2 - ); - - always_ff @(posedge clk) begin : modScancode - ps2[71:63] <= (usb[0]) ? 9'h014 : 9'h00; // Left Control - ps2[62:54] <= (usb[1]) ? 9'h012 : 9'h00; // Left Shift - ps2[53:45] <= (usb[2]) ? 9'h011 : 9'h00; // Left Alt - ps2[44:36] <= (usb[3]) ? 9'h11F : 9'h00; // Left GUI - ps2[35:27] <= (usb[4]) ? 9'h114 : 9'h00; // Right Control - ps2[26:18] <= (usb[5]) ? 9'h059 : 9'h00; // Right Shift - ps2[17:09] <= (usb[6]) ? 9'h111 : 9'h00; // Right Alt - ps2[08:00] <= (usb[7]) ? 9'h127 : 9'h00; // Right GUI - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module hid2ps2_mod + ( + input logic clk, + input logic [7:0] usb, + output logic [71:0] ps2 + ); + + always_ff @(posedge clk) begin : modScancode + ps2[71:63] <= (usb[0]) ? 9'h014 : 9'h00; // Left Control + ps2[62:54] <= (usb[1]) ? 9'h012 : 9'h00; // Left Shift + ps2[53:45] <= (usb[2]) ? 9'h011 : 9'h00; // Left Alt + ps2[44:36] <= (usb[3]) ? 9'h11F : 9'h00; // Left GUI + ps2[35:27] <= (usb[4]) ? 9'h114 : 9'h00; // Right Control + ps2[26:18] <= (usb[5]) ? 9'h059 : 9'h00; // Right Shift + ps2[17:09] <= (usb[6]) ? 9'h111 : 9'h00; // Right Alt + ps2[08:00] <= (usb[7]) ? 9'h127 : 9'h00; // Right GUI + end + +endmodule diff --git a/platform/pocket/interface/keyboard/kb_fifo.sv b/platform/pocket/interface/keyboard/kb_fifo.sv index d400a86..ffe910a 100644 --- a/platform/pocket/interface/keyboard/kb_fifo.sv +++ b/platform/pocket/interface/keyboard/kb_fifo.sv @@ -1,133 +1,133 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module kb_fifo - ( - // Global - input logic clk, //! Clock - input logic reset, //! Reset - // Enqueue side - input logic [125:0] din, //! Data Input - // Dequeue side - input logic rd_en, //! Read Enable - output logic empty, //! FIFO Empty State - output logic [125:0] dout //! Data Output - ); - - parameter INIT_REPEAT_DELAY = 4'hF; // Initial delay before repeating - parameter REPEAT_RATE = 4'h4; // Repeat rate - - //! ------------------------------------------------------------------------ - //! Internal Registers - //! ------------------------------------------------------------------------ - logic [125:0] fifo[6:0]; // FIFO buffer - logic [125:0] prev_din; // Previous FIFO Data - logic [2:0] wr_ptr = 3'h0; // Write pointer - logic [2:0] rd_ptr = 3'h0; // Read pointer - logic [2:0] counter = 3'h0; // Count of elements in FIFO - logic wr_en = 1'b0; // Write Enable - logic full; // FIFO is Full - logic [3:0] delay_counter = 4'h0; // Delay before key starts to repeat - logic [3:0] repeat_counter = 4'h0; // Counter for key repeat rate - logic repeat_request = 1'b0; // Write Enable - logic prev_repeat_request = 1'b0; // Previous state of repeat_request - - //! ------------------------------------------------------------------------ - //! FIFO State - //! ------------------------------------------------------------------------ - assign empty = (counter == 0) ? 1'b1 : 1'b0; - assign full = (counter == 7) ? 1'b1 : 1'b0; - - //! ------------------------------------------------------------------------ - //! Key Repeat Controller - //! ------------------------------------------------------------------------ - always_ff @(posedge clk) begin : fifoKeyRepeat - if (din != 'h0 && din == prev_din && !full) begin - if (delay_counter < INIT_REPEAT_DELAY) begin - delay_counter <= delay_counter + 4'h1; - end - else if (repeat_counter < REPEAT_RATE) begin - delay_counter <= 4'h0; // Reset delay_counter after reaching the initial delay - repeat_counter <= repeat_counter + 4'h1; - end - else begin - repeat_request <= ~repeat_request; - repeat_counter <= 0; - end - end - else if (din != prev_din || din == 'h0 || wr_en) begin - delay_counter <= 4'h0; - repeat_counter <= 4'h0; - repeat_request <= 1'b0; - end - end - - //! ------------------------------------------------------------------------ - //! FIFO Write Controller - //! ------------------------------------------------------------------------ - always_ff @(posedge clk) begin : fifoWriteControl - prev_din <= din; - prev_repeat_request <= repeat_request; - if ((din != prev_din) || (repeat_request && !prev_repeat_request)) begin - wr_en <= 1'b1; - end - else begin - wr_en <= 1'b0; - end - end - - //! ------------------------------------------------------------------------ - //! FIFO Buffer Controller - //! ------------------------------------------------------------------------ - always_ff @(posedge clk) begin : fifoControl - if (reset) begin - wr_ptr <= 0; - rd_ptr <= 0; - counter <= 0; - end - else begin - if (wr_en && !full) begin - fifo[wr_ptr] <= din; - wr_ptr <= (wr_ptr + 1) % 7; - counter <= counter + 1; - end - - if (rd_en && !empty) begin - dout <= fifo[rd_ptr]; - rd_ptr <= (rd_ptr + 1) % 7; - counter <= counter - 1; - end - end - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module kb_fifo + ( + // Global + input logic clk, //! Clock + input logic reset, //! Reset + // Enqueue side + input logic [125:0] din, //! Data Input + // Dequeue side + input logic rd_en, //! Read Enable + output logic empty, //! FIFO Empty State + output logic [125:0] dout //! Data Output + ); + + parameter INIT_REPEAT_DELAY = 4'hF; // Initial delay before repeating + parameter REPEAT_RATE = 4'h4; // Repeat rate + + //! ------------------------------------------------------------------------ + //! Internal Registers + //! ------------------------------------------------------------------------ + logic [125:0] fifo[6:0]; // FIFO buffer + logic [125:0] prev_din; // Previous FIFO Data + logic [2:0] wr_ptr = 3'h0; // Write pointer + logic [2:0] rd_ptr = 3'h0; // Read pointer + logic [2:0] counter = 3'h0; // Count of elements in FIFO + logic wr_en = 1'b0; // Write Enable + logic full; // FIFO is Full + logic [3:0] delay_counter = 4'h0; // Delay before key starts to repeat + logic [3:0] repeat_counter = 4'h0; // Counter for key repeat rate + logic repeat_request = 1'b0; // Write Enable + logic prev_repeat_request = 1'b0; // Previous state of repeat_request + + //! ------------------------------------------------------------------------ + //! FIFO State + //! ------------------------------------------------------------------------ + assign empty = (counter == 0) ? 1'b1 : 1'b0; + assign full = (counter == 7) ? 1'b1 : 1'b0; + + //! ------------------------------------------------------------------------ + //! Key Repeat Controller + //! ------------------------------------------------------------------------ + always_ff @(posedge clk) begin : fifoKeyRepeat + if (din != 'h0 && din == prev_din && !full) begin + if (delay_counter < INIT_REPEAT_DELAY) begin + delay_counter <= delay_counter + 4'h1; + end + else if (repeat_counter < REPEAT_RATE) begin + delay_counter <= 4'h0; // Reset delay_counter after reaching the initial delay + repeat_counter <= repeat_counter + 4'h1; + end + else begin + repeat_request <= ~repeat_request; + repeat_counter <= 0; + end + end + else if (din != prev_din || din == 'h0 || wr_en) begin + delay_counter <= 4'h0; + repeat_counter <= 4'h0; + repeat_request <= 1'b0; + end + end + + //! ------------------------------------------------------------------------ + //! FIFO Write Controller + //! ------------------------------------------------------------------------ + always_ff @(posedge clk) begin : fifoWriteControl + prev_din <= din; + prev_repeat_request <= repeat_request; + if ((din != prev_din) || (repeat_request && !prev_repeat_request)) begin + wr_en <= 1'b1; + end + else begin + wr_en <= 1'b0; + end + end + + //! ------------------------------------------------------------------------ + //! FIFO Buffer Controller + //! ------------------------------------------------------------------------ + always_ff @(posedge clk) begin : fifoControl + if (reset) begin + wr_ptr <= 0; + rd_ptr <= 0; + counter <= 0; + end + else begin + if (wr_en && !full) begin + fifo[wr_ptr] <= din; + wr_ptr <= (wr_ptr + 1) % 7; + counter <= counter + 1; + end + + if (rd_en && !empty) begin + dout <= fifo[rd_ptr]; + rd_ptr <= (rd_ptr + 1) % 7; + counter <= counter - 1; + end + end + end + +endmodule diff --git a/platform/pocket/interface/keyboard/key_arbiter.sv b/platform/pocket/interface/keyboard/key_arbiter.sv index 4262f2d..e1fb4d3 100644 --- a/platform/pocket/interface/keyboard/key_arbiter.sv +++ b/platform/pocket/interface/keyboard/key_arbiter.sv @@ -1,115 +1,115 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module key_arbiter - ( - input logic clk, //! Clock input - input logic reset, //! Reset input - input logic fifo_ready, //! FIFO is not empty - input logic [125:0] fifo_din, //! FIFO 126-bit input data - output logic fifo_rd, //! Read Request to FIFO when no data is being processed - output logic [3:0] key_idx, //! Key Index - output logic [8:0] scancode //! 9-bit output chunk - ); - - //! ------------------------------------------------------------------------ - //! Request new data when all chunks have been processed - //! ------------------------------------------------------------------------ - assign fifo_rd = !data_valid && fifo_ready; - - //! ------------------------------------------------------------------------ - //! State Machine Controller - //! ------------------------------------------------------------------------ - logic [3:0] cycle_counter; // Counter for clock cycles - logic data_valid; // Flag to indicate if the current data is valid - - always_ff @(posedge clk or posedge reset) begin - if (reset) begin - key_idx <= 4'h0; - cycle_counter <= 4'h0; - data_valid <= 1'b0; - end - else if(fifo_ready && !data_valid) begin - key_idx <= 4'h1; - cycle_counter <= 4'h0; - data_valid <= 1'b1; - end - else if(data_valid) begin - if (scancode == 9'h0) begin - if (key_idx < 4'hE) begin - key_idx <= key_idx + 4'b1; - end else begin - key_idx <= 4'h0; - data_valid <= 1'b0; - end - cycle_counter <= 4'h0; - end - else if (cycle_counter == 4'h4) begin - if (key_idx < 4'hE) begin - key_idx <= key_idx + 4'b1; - end else begin - key_idx <= 4'h0; - data_valid <= 1'b0; - end - cycle_counter <= 4'h0; - end - else begin - cycle_counter <= cycle_counter + 4'b1; - end - end - end - - //! ------------------------------------------------------------------------ - //! State Machine Logic - //! ------------------------------------------------------------------------ - always_comb begin - case (key_idx) - 4'h1: scancode = fifo_din[125:117]; // Scancode MOD 1 - 4'h2: scancode = fifo_din[116:108]; // Scancode MOD 2 - 4'h3: scancode = fifo_din[107:099]; // Scancode MOD 3 - 4'h4: scancode = fifo_din[098:090]; // Scancode MOD 4 - 4'h5: scancode = fifo_din[089:081]; // Scancode MOD 5 - 4'h6: scancode = fifo_din[080:072]; // Scancode MOD 6 - 4'h7: scancode = fifo_din[071:063]; // Scancode MOD 7 - 4'h8: scancode = fifo_din[062:054]; // Scancode MOD 8 - 4'h9: scancode = fifo_din[053:045]; // Scancode 1 - 4'hA: scancode = fifo_din[044:036]; // Scancode 2 - 4'hB: scancode = fifo_din[035:027]; // Scancode 3 - 4'hC: scancode = fifo_din[026:018]; // Scancode 4 - 4'hD: scancode = fifo_din[017:009]; // Scancode 5 - 4'hE: scancode = fifo_din[008:000]; // Scancode 6 - default: scancode = 9'h0; - endcase - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module key_arbiter + ( + input logic clk, //! Clock input + input logic reset, //! Reset input + input logic fifo_ready, //! FIFO is not empty + input logic [125:0] fifo_din, //! FIFO 126-bit input data + output logic fifo_rd, //! Read Request to FIFO when no data is being processed + output logic [3:0] key_idx, //! Key Index + output logic [8:0] scancode //! 9-bit output chunk + ); + + //! ------------------------------------------------------------------------ + //! Request new data when all chunks have been processed + //! ------------------------------------------------------------------------ + assign fifo_rd = !data_valid && fifo_ready; + + //! ------------------------------------------------------------------------ + //! State Machine Controller + //! ------------------------------------------------------------------------ + logic [3:0] cycle_counter; // Counter for clock cycles + logic data_valid; // Flag to indicate if the current data is valid + + always_ff @(posedge clk or posedge reset) begin + if (reset) begin + key_idx <= 4'h0; + cycle_counter <= 4'h0; + data_valid <= 1'b0; + end + else if(fifo_ready && !data_valid) begin + key_idx <= 4'h1; + cycle_counter <= 4'h0; + data_valid <= 1'b1; + end + else if(data_valid) begin + if (scancode == 9'h0) begin + if (key_idx < 4'hE) begin + key_idx <= key_idx + 4'b1; + end else begin + key_idx <= 4'h0; + data_valid <= 1'b0; + end + cycle_counter <= 4'h0; + end + else if (cycle_counter == 4'h4) begin + if (key_idx < 4'hE) begin + key_idx <= key_idx + 4'b1; + end else begin + key_idx <= 4'h0; + data_valid <= 1'b0; + end + cycle_counter <= 4'h0; + end + else begin + cycle_counter <= cycle_counter + 4'b1; + end + end + end + + //! ------------------------------------------------------------------------ + //! State Machine Logic + //! ------------------------------------------------------------------------ + always_comb begin + case (key_idx) + 4'h1: scancode = fifo_din[125:117]; // Scancode MOD 1 + 4'h2: scancode = fifo_din[116:108]; // Scancode MOD 2 + 4'h3: scancode = fifo_din[107:099]; // Scancode MOD 3 + 4'h4: scancode = fifo_din[098:090]; // Scancode MOD 4 + 4'h5: scancode = fifo_din[089:081]; // Scancode MOD 5 + 4'h6: scancode = fifo_din[080:072]; // Scancode MOD 6 + 4'h7: scancode = fifo_din[071:063]; // Scancode MOD 7 + 4'h8: scancode = fifo_din[062:054]; // Scancode MOD 8 + 4'h9: scancode = fifo_din[053:045]; // Scancode 1 + 4'hA: scancode = fifo_din[044:036]; // Scancode 2 + 4'hB: scancode = fifo_din[035:027]; // Scancode 3 + 4'hC: scancode = fifo_din[026:018]; // Scancode 4 + 4'hD: scancode = fifo_din[017:009]; // Scancode 5 + 4'hE: scancode = fifo_din[008:000]; // Scancode 6 + default: scancode = 9'h0; + endcase + end + +endmodule diff --git a/platform/pocket/interface/keyboard/key_ctl.sv b/platform/pocket/interface/keyboard/key_ctl.sv index 366c456..c6599a1 100644 --- a/platform/pocket/interface/keyboard/key_ctl.sv +++ b/platform/pocket/interface/keyboard/key_ctl.sv @@ -1,111 +1,111 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2023, Jacob Boline -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module key_ctl - ( - input logic clk, //! System Clock - input logic reset, //! Reset - input logic [3:0] key_idx, //! Key Index - input logic [8:0] scancode, //! Key Scan Code - output logic key_strobe, //! Key Data Valid - output logic key_pressed, //! 1: Make (Pressed) | 0: Break (Released) - output logic [8:0] key_code //! Key Scan Code - ); - - //! ------------------------------------------------------------------------ - //! Scancode Storage - //! ------------------------------------------------------------------------ - reg [8:0] scancode_last, scancode_saved; - reg save_scancode; - - always_ff @(posedge clk) begin : scancodeStorage - scancode_last <= scancode; - scancode_saved <= (save_scancode) ? scancode : scancode_saved; - end - - //! ------------------------------------------------------------------------ - //! Key State - //! ------------------------------------------------------------------------ - typedef enum {IDLE, SAVE, PRESS, HOLD_RELEASE} KeyState; - KeyState current_state, next_state; - - //! ------------------------------------------------------------------------ - //! Key Conditions - //! ------------------------------------------------------------------------ - wire key_make = (scancode != scancode_last) && (scancode != 9'h0) || ( |scancode & ~|scancode_last); - wire key_break = (scancode != scancode_last) && (scancode == 9'h0) || (~|scancode & |scancode_last); - wire key_changed = (scancode != scancode_last); - - //! ------------------------------------------------------------------------ - //! State Machine Controller - //! ------------------------------------------------------------------------ - always_ff @(posedge clk) begin : scancodeFSMControl - current_state <= (reset) ? IDLE : next_state; - end - - always_comb begin : scancodeFSM - next_state = current_state; - save_scancode = 1'b0; - key_code = 9'h0; - key_pressed = 1'b0; - key_strobe = 1'b0; - - case (current_state) - IDLE: begin - next_state = (key_make) ? SAVE : IDLE; - end - SAVE: begin - save_scancode = 1'b1; - next_state = PRESS; - end - PRESS: begin - key_code = scancode_saved; - key_pressed = 1'b1; - key_strobe = 1'b1; - next_state = HOLD_RELEASE; - end - HOLD_RELEASE: begin - key_code = scancode_saved; - key_pressed = ~(key_break || key_changed); - key_strobe = (key_break || key_changed); - next_state = (key_break) ? IDLE : - (key_changed) ? SAVE : HOLD_RELEASE; - end - default: begin - next_state = IDLE; - end - endcase - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2023, Jacob Boline +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module key_ctl + ( + input logic clk, //! System Clock + input logic reset, //! Reset + input logic [3:0] key_idx, //! Key Index + input logic [8:0] scancode, //! Key Scan Code + output logic key_strobe, //! Key Data Valid + output logic key_pressed, //! 1: Make (Pressed) | 0: Break (Released) + output logic [8:0] key_code //! Key Scan Code + ); + + //! ------------------------------------------------------------------------ + //! Scancode Storage + //! ------------------------------------------------------------------------ + reg [8:0] scancode_last, scancode_saved; + reg save_scancode; + + always_ff @(posedge clk) begin : scancodeStorage + scancode_last <= scancode; + scancode_saved <= (save_scancode) ? scancode : scancode_saved; + end + + //! ------------------------------------------------------------------------ + //! Key State + //! ------------------------------------------------------------------------ + typedef enum {IDLE, SAVE, PRESS, HOLD_RELEASE} KeyState; + KeyState current_state, next_state; + + //! ------------------------------------------------------------------------ + //! Key Conditions + //! ------------------------------------------------------------------------ + wire key_make = (scancode != scancode_last) && (scancode != 9'h0) || ( |scancode & ~|scancode_last); + wire key_break = (scancode != scancode_last) && (scancode == 9'h0) || (~|scancode & |scancode_last); + wire key_changed = (scancode != scancode_last); + + //! ------------------------------------------------------------------------ + //! State Machine Controller + //! ------------------------------------------------------------------------ + always_ff @(posedge clk) begin : scancodeFSMControl + current_state <= (reset) ? IDLE : next_state; + end + + always_comb begin : scancodeFSM + next_state = current_state; + save_scancode = 1'b0; + key_code = 9'h0; + key_pressed = 1'b0; + key_strobe = 1'b0; + + case (current_state) + IDLE: begin + next_state = (key_make) ? SAVE : IDLE; + end + SAVE: begin + save_scancode = 1'b1; + next_state = PRESS; + end + PRESS: begin + key_code = scancode_saved; + key_pressed = 1'b1; + key_strobe = 1'b1; + next_state = HOLD_RELEASE; + end + HOLD_RELEASE: begin + key_code = scancode_saved; + key_pressed = ~(key_break || key_changed); + key_strobe = (key_break || key_changed); + next_state = (key_break) ? IDLE : + (key_changed) ? SAVE : HOLD_RELEASE; + end + default: begin + next_state = IDLE; + end + endcase + end + +endmodule diff --git a/platform/pocket/interface/keyboard/key_mgr.sv b/platform/pocket/interface/keyboard/key_mgr.sv index e45c6d3..419e109 100644 --- a/platform/pocket/interface/keyboard/key_mgr.sv +++ b/platform/pocket/interface/keyboard/key_mgr.sv @@ -1,169 +1,169 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2023, Jacob Boline -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module key_mgr - ( - input wire clk, //! System Clock - input wire reset, //! Reset - input wire [3:0] key_idx, //! Key Index - input wire [8:0] scancode, //! Key Scan Code - output logic key_strobe, //! Key Data Valid - output logic key_pressed, //! 1: Make (Pressed) | 0: Break (Released) - output logic [8:0] key_code //! Key Scan Code - ); - - //! ------------------------------------------------------------------------ - //! Scancode Storage - //! ------------------------------------------------------------------------ - reg [8:0] scancode_last[0:15]; - reg [8:0] scancode_saved[0:15]; - reg [15:0] save_scancode; - - reg key_strobe_array[0:15]; - reg key_pressed_array[0:15]; - reg [8:0] key_code_array[0:15]; - reg key_strobe_array_reg[0:15]; - reg key_pressed_array_reg[0:15]; - reg [8:0] key_code_array_reg[0:15]; - reg [15:0] save_scancode_reg; - - always_ff @(posedge clk) begin - if (reset) begin - for (int i = 0; i < 16; i++) begin - scancode_last[i] <= 9'h0; - scancode_saved[i] <= 9'h0; - end - end - else begin - for (int i = 0; i < 16; i++) begin - if (key_idx == i[3:0]) begin - scancode_last[i] <= scancode; - scancode_saved[i] <= (save_scancode[i]) ? scancode : scancode_saved[i]; - end - end - end - end - - //! ------------------------------------------------------------------------ - //! Key State - //! ------------------------------------------------------------------------ - typedef enum {IDLE, SAVE, PRESS, HOLD_RELEASE} KeyState; - KeyState current_state[0:15], next_state[0:15]; - - //! ------------------------------------------------------------------------ - //! Key Conditions - //! ------------------------------------------------------------------------ - wire key_make = (scancode != scancode_last[key_idx]) && (scancode != 9'h0) || ( |scancode & ~|scancode_last[key_idx]); - wire key_break = (scancode != scancode_last[key_idx]) && (scancode == 9'h0) || (~|scancode & |scancode_last[key_idx]); - wire key_changed = (scancode != scancode_last[key_idx]); - - //! ------------------------------------------------------------------------ - //! State Machine Controller - //! ------------------------------------------------------------------------ - always_ff @(posedge clk) begin - if (reset) begin - for (int i = 0; i < 16; i++) begin - current_state[i] <= IDLE; - save_scancode_reg[i] <= 0; - key_code_array_reg[i] <= 0; - key_pressed_array_reg[i] <= 0; - key_strobe_array_reg[i] <= 0; - end - end - else begin - for (int i = 0; i < 16; i++) begin - if (key_idx == i[3:0]) begin - current_state[i] <= next_state[i]; - save_scancode_reg[i] <= save_scancode[i]; - key_code_array_reg[i] <= key_code_array[i]; - key_pressed_array_reg[i] <= key_pressed_array[i]; - key_strobe_array_reg[i] <= key_strobe_array[i]; - end - end - end - end - - //! ------------------------------------------------------------------------ - //! State Machine Logic - //! ------------------------------------------------------------------------ - always_comb begin - for (int i = 0; i < 16; i++) begin - if (key_idx == i[3:0]) begin - next_state[i] = current_state[i]; - save_scancode[i] = 1'b0; - key_code_array[i] = 9'h0; - key_pressed_array[i] = 1'b0; - key_strobe_array[i] = 1'b0; - - case (current_state[i]) - IDLE: begin - next_state[i] = (key_make) ? SAVE : IDLE; - end - SAVE: begin - save_scancode[i] = 1'b1; - next_state[i] = PRESS; - end - PRESS: begin - key_code_array[i] = scancode_saved[i]; - key_pressed_array[i] = 1'b1; - key_strobe_array[i] = 1'b1; - next_state[i] = HOLD_RELEASE; - end - HOLD_RELEASE: begin - key_code_array[i] = scancode_saved[i]; - key_pressed_array[i] = ~(key_break || key_changed); - key_strobe_array[i] = (key_break || key_changed); - next_state[i] = (key_break) ? IDLE : - (key_changed) ? SAVE : HOLD_RELEASE; - end - default: begin - next_state[i] = IDLE; - end - endcase - end - else begin - next_state[i] = current_state[i]; - save_scancode[i] = save_scancode_reg[i]; - key_code_array[i] = key_code_array_reg[i]; - key_pressed_array[i] = key_pressed_array_reg[i]; - key_strobe_array[i] = key_strobe_array_reg[i]; - end - end - end - - assign key_code = key_code_array[key_idx]; - assign key_pressed = key_pressed_array[key_idx]; - assign key_strobe = key_strobe_array[key_idx]; - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2023, Jacob Boline +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module key_mgr + ( + input wire clk, //! System Clock + input wire reset, //! Reset + input wire [3:0] key_idx, //! Key Index + input wire [8:0] scancode, //! Key Scan Code + output logic key_strobe, //! Key Data Valid + output logic key_pressed, //! 1: Make (Pressed) | 0: Break (Released) + output logic [8:0] key_code //! Key Scan Code + ); + + //! ------------------------------------------------------------------------ + //! Scancode Storage + //! ------------------------------------------------------------------------ + reg [8:0] scancode_last[0:15]; + reg [8:0] scancode_saved[0:15]; + reg [15:0] save_scancode; + + reg key_strobe_array[0:15]; + reg key_pressed_array[0:15]; + reg [8:0] key_code_array[0:15]; + reg key_strobe_array_reg[0:15]; + reg key_pressed_array_reg[0:15]; + reg [8:0] key_code_array_reg[0:15]; + reg [15:0] save_scancode_reg; + + always_ff @(posedge clk) begin + if (reset) begin + for (int i = 0; i < 16; i++) begin + scancode_last[i] <= 9'h0; + scancode_saved[i] <= 9'h0; + end + end + else begin + for (int i = 0; i < 16; i++) begin + if (key_idx == i[3:0]) begin + scancode_last[i] <= scancode; + scancode_saved[i] <= (save_scancode[i]) ? scancode : scancode_saved[i]; + end + end + end + end + + //! ------------------------------------------------------------------------ + //! Key State + //! ------------------------------------------------------------------------ + typedef enum {IDLE, SAVE, PRESS, HOLD_RELEASE} KeyState; + KeyState current_state[0:15], next_state[0:15]; + + //! ------------------------------------------------------------------------ + //! Key Conditions + //! ------------------------------------------------------------------------ + wire key_make = (scancode != scancode_last[key_idx]) && (scancode != 9'h0) || ( |scancode & ~|scancode_last[key_idx]); + wire key_break = (scancode != scancode_last[key_idx]) && (scancode == 9'h0) || (~|scancode & |scancode_last[key_idx]); + wire key_changed = (scancode != scancode_last[key_idx]); + + //! ------------------------------------------------------------------------ + //! State Machine Controller + //! ------------------------------------------------------------------------ + always_ff @(posedge clk) begin + if (reset) begin + for (int i = 0; i < 16; i++) begin + current_state[i] <= IDLE; + save_scancode_reg[i] <= 0; + key_code_array_reg[i] <= 0; + key_pressed_array_reg[i] <= 0; + key_strobe_array_reg[i] <= 0; + end + end + else begin + for (int i = 0; i < 16; i++) begin + if (key_idx == i[3:0]) begin + current_state[i] <= next_state[i]; + save_scancode_reg[i] <= save_scancode[i]; + key_code_array_reg[i] <= key_code_array[i]; + key_pressed_array_reg[i] <= key_pressed_array[i]; + key_strobe_array_reg[i] <= key_strobe_array[i]; + end + end + end + end + + //! ------------------------------------------------------------------------ + //! State Machine Logic + //! ------------------------------------------------------------------------ + always_comb begin + for (int i = 0; i < 16; i++) begin + if (key_idx == i[3:0]) begin + next_state[i] = current_state[i]; + save_scancode[i] = 1'b0; + key_code_array[i] = 9'h0; + key_pressed_array[i] = 1'b0; + key_strobe_array[i] = 1'b0; + + case (current_state[i]) + IDLE: begin + next_state[i] = (key_make) ? SAVE : IDLE; + end + SAVE: begin + save_scancode[i] = 1'b1; + next_state[i] = PRESS; + end + PRESS: begin + key_code_array[i] = scancode_saved[i]; + key_pressed_array[i] = 1'b1; + key_strobe_array[i] = 1'b1; + next_state[i] = HOLD_RELEASE; + end + HOLD_RELEASE: begin + key_code_array[i] = scancode_saved[i]; + key_pressed_array[i] = ~(key_break || key_changed); + key_strobe_array[i] = (key_break || key_changed); + next_state[i] = (key_break) ? IDLE : + (key_changed) ? SAVE : HOLD_RELEASE; + end + default: begin + next_state[i] = IDLE; + end + endcase + end + else begin + next_state[i] = current_state[i]; + save_scancode[i] = save_scancode_reg[i]; + key_code_array[i] = key_code_array_reg[i]; + key_pressed_array[i] = key_pressed_array_reg[i]; + key_strobe_array[i] = key_strobe_array_reg[i]; + end + end + end + + assign key_code = key_code_array[key_idx]; + assign key_pressed = key_pressed_array[key_idx]; + assign key_strobe = key_strobe_array[key_idx]; + +endmodule diff --git a/platform/pocket/interface/keyboard/usb_keyboard.sv b/platform/pocket/interface/keyboard/usb_keyboard.sv index c047d8e..05d60b5 100644 --- a/platform/pocket/interface/keyboard/usb_keyboard.sv +++ b/platform/pocket/interface/keyboard/usb_keyboard.sv @@ -1,145 +1,145 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module usb_keyboard - ( - // Clock and Reset - input logic clk, //! Clock - input logic clk_sync, //! Clock - input logic reset, //! Reset - // APF Keyboard Port - input logic [31:0] cont3_key, //! Modifiers/Input Type - input logic [31:0] cont3_joy, //! Scan code 1-4 - input logic [15:0] cont3_trig, //! Scan code 5-6 - // USB Keyboard Output - output logic [63:0] usb_kb_hid, //! 64-bit HID Report - output logic [7:0] usb_kb_mod, //! Modifiers - output logic [7:0] usb_kb_sc1, //! Scan Code 1 - output logic [7:0] usb_kb_sc2, //! Scan Code 2 - output logic [7:0] usb_kb_sc3, //! Scan Code 3 - output logic [7:0] usb_kb_sc4, //! Scan Code 4 - output logic [7:0] usb_kb_sc5, //! Scan Code 5 - output logic [7:0] usb_kb_sc6, //! Scan Code 6 - // PS/2 Keyboard Output - output logic [10:0] ps2_key = 11'h0 //! PS/2 Keyboard - ); - - //! ------------------------------------------------------------------------ - //! APF to USB HID - //! ------------------------------------------------------------------------ - apf2hid u_apf2hid - ( - .clk ( clk ), - .reset ( reset ), - .cont3_key ( cont3_key ), - .cont3_joy ( cont3_joy ), - .cont3_trig ( cont3_trig ), - .usb_kb_hid ( usb_kb_hid ), - .usb_kb_mod ( usb_kb_mod ), - .usb_kb_sc1 ( usb_kb_sc1 ), - .usb_kb_sc2 ( usb_kb_sc2 ), - .usb_kb_sc3 ( usb_kb_sc3 ), - .usb_kb_sc4 ( usb_kb_sc4 ), - .usb_kb_sc5 ( usb_kb_sc5 ), - .usb_kb_sc6 ( usb_kb_sc6 ) - ); - - //! ------------------------------------------------------------------------ - //! Translate USB HID ID to PS/2 Scancode - //! ------------------------------------------------------------------------ - logic [53:0] ps2_keys; - logic [71:0] ps2_mods; - - hid2ps2_mod u_key_mod (.clk(~clk), .usb(usb_kb_mod), .ps2(ps2_mods)); - hid2ps2_key u_key_sc1 (.clk(~clk), .usb(usb_kb_sc1), .ps2(ps2_keys[53:45])); - hid2ps2_key u_key_sc2 (.clk(~clk), .usb(usb_kb_sc2), .ps2(ps2_keys[44:36])); - hid2ps2_key u_key_sc3 (.clk(~clk), .usb(usb_kb_sc3), .ps2(ps2_keys[35:27])); - hid2ps2_key u_key_sc4 (.clk(~clk), .usb(usb_kb_sc4), .ps2(ps2_keys[26:18])); - hid2ps2_key u_key_sc5 (.clk(~clk), .usb(usb_kb_sc5), .ps2(ps2_keys[17:09])); - hid2ps2_key u_key_sc6 (.clk(~clk), .usb(usb_kb_sc6), .ps2(ps2_keys[08:00])); - - //! ------------------------------------------------------------------------ - //! PS/2 Keyboard FIFO - //! ------------------------------------------------------------------------ - logic [125:0] fifo_dout; - logic fifo_empty; - logic fifo_rd; - - kb_fifo u_fifo - ( - .clk ( clk ), - .reset ( reset ), - .din ( {ps2_mods, ps2_keys} ), - .rd_en ( fifo_rd ), - .empty ( fifo_empty ), - .dout ( fifo_dout ) - ); - - //! ------------------------------------------------------------------------ - //! PS/2 FIFO Scancode Arbiter - //! ------------------------------------------------------------------------ - logic [8:0] scancode; - logic [3:0] key_idx; - - key_arbiter u_key_arbiter - ( - .clk ( clk ), - .reset ( reset ), - .fifo_ready ( ~fifo_empty ), - .fifo_din ( fifo_dout ), - .fifo_rd ( fifo_rd ), - .key_idx ( key_idx ), - .scancode ( scancode ) - ); - - //! ------------------------------------------------------------------------ - //! PS/2 Key Controller - //! ------------------------------------------------------------------------ - logic strobe; - logic pressed; - logic [8:0] key_code; - - key_mgr u_key_ctl - ( - .clk ( clk ), - .reset ( reset ), - .key_idx ( key_idx ), - .scancode ( scancode ), - .key_strobe ( strobe ), - .key_pressed ( pressed ), - .key_code ( key_code ) - ); - - assign ps2_key = {strobe, pressed, key_code}; - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module usb_keyboard + ( + // Clock and Reset + input logic clk, //! Clock + input logic clk_sync, //! Clock + input logic reset, //! Reset + // APF Keyboard Port + input logic [31:0] cont3_key, //! Modifiers/Input Type + input logic [31:0] cont3_joy, //! Scan code 1-4 + input logic [15:0] cont3_trig, //! Scan code 5-6 + // USB Keyboard Output + output logic [63:0] usb_kb_hid, //! 64-bit HID Report + output logic [7:0] usb_kb_mod, //! Modifiers + output logic [7:0] usb_kb_sc1, //! Scan Code 1 + output logic [7:0] usb_kb_sc2, //! Scan Code 2 + output logic [7:0] usb_kb_sc3, //! Scan Code 3 + output logic [7:0] usb_kb_sc4, //! Scan Code 4 + output logic [7:0] usb_kb_sc5, //! Scan Code 5 + output logic [7:0] usb_kb_sc6, //! Scan Code 6 + // PS/2 Keyboard Output + output logic [10:0] ps2_key = 11'h0 //! PS/2 Keyboard + ); + + //! ------------------------------------------------------------------------ + //! APF to USB HID + //! ------------------------------------------------------------------------ + apf2hid u_apf2hid + ( + .clk ( clk ), + .reset ( reset ), + .cont3_key ( cont3_key ), + .cont3_joy ( cont3_joy ), + .cont3_trig ( cont3_trig ), + .usb_kb_hid ( usb_kb_hid ), + .usb_kb_mod ( usb_kb_mod ), + .usb_kb_sc1 ( usb_kb_sc1 ), + .usb_kb_sc2 ( usb_kb_sc2 ), + .usb_kb_sc3 ( usb_kb_sc3 ), + .usb_kb_sc4 ( usb_kb_sc4 ), + .usb_kb_sc5 ( usb_kb_sc5 ), + .usb_kb_sc6 ( usb_kb_sc6 ) + ); + + //! ------------------------------------------------------------------------ + //! Translate USB HID ID to PS/2 Scancode + //! ------------------------------------------------------------------------ + logic [53:0] ps2_keys; + logic [71:0] ps2_mods; + + hid2ps2_mod u_key_mod (.clk(~clk), .usb(usb_kb_mod), .ps2(ps2_mods)); + hid2ps2_key u_key_sc1 (.clk(~clk), .usb(usb_kb_sc1), .ps2(ps2_keys[53:45])); + hid2ps2_key u_key_sc2 (.clk(~clk), .usb(usb_kb_sc2), .ps2(ps2_keys[44:36])); + hid2ps2_key u_key_sc3 (.clk(~clk), .usb(usb_kb_sc3), .ps2(ps2_keys[35:27])); + hid2ps2_key u_key_sc4 (.clk(~clk), .usb(usb_kb_sc4), .ps2(ps2_keys[26:18])); + hid2ps2_key u_key_sc5 (.clk(~clk), .usb(usb_kb_sc5), .ps2(ps2_keys[17:09])); + hid2ps2_key u_key_sc6 (.clk(~clk), .usb(usb_kb_sc6), .ps2(ps2_keys[08:00])); + + //! ------------------------------------------------------------------------ + //! PS/2 Keyboard FIFO + //! ------------------------------------------------------------------------ + logic [125:0] fifo_dout; + logic fifo_empty; + logic fifo_rd; + + kb_fifo u_fifo + ( + .clk ( clk ), + .reset ( reset ), + .din ( {ps2_mods, ps2_keys} ), + .rd_en ( fifo_rd ), + .empty ( fifo_empty ), + .dout ( fifo_dout ) + ); + + //! ------------------------------------------------------------------------ + //! PS/2 FIFO Scancode Arbiter + //! ------------------------------------------------------------------------ + logic [8:0] scancode; + logic [3:0] key_idx; + + key_arbiter u_key_arbiter + ( + .clk ( clk ), + .reset ( reset ), + .fifo_ready ( ~fifo_empty ), + .fifo_din ( fifo_dout ), + .fifo_rd ( fifo_rd ), + .key_idx ( key_idx ), + .scancode ( scancode ) + ); + + //! ------------------------------------------------------------------------ + //! PS/2 Key Controller + //! ------------------------------------------------------------------------ + logic strobe; + logic pressed; + logic [8:0] key_code; + + key_mgr u_key_ctl + ( + .clk ( clk ), + .reset ( reset ), + .key_idx ( key_idx ), + .scancode ( scancode ), + .key_strobe ( strobe ), + .key_pressed ( pressed ), + .key_code ( key_code ) + ); + + assign ps2_key = {strobe, pressed, key_code}; + +endmodule diff --git a/platform/pocket/interface/mame_keymap.sv b/platform/pocket/interface/mame_keymap.sv index 989ce34..ab58be1 100644 --- a/platform/pocket/interface/mame_keymap.sv +++ b/platform/pocket/interface/mame_keymap.sv @@ -1,133 +1,133 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// PS/2 Keyboard to MAME Key Mapping -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ -// -// key bitmap: -// -// | Gamepad | Start | Coinage | -// | --------- | ----------- | ---------- | -// | [0] up | [0] start 1 | [0] coin 1 | -// | [1] down | [1] start 2 | [1] coin 2 | -// | [2] left | [2] start 3 | [2] coin 3 | -// | [3] right | [3] start 4 | [3] coin 4 | -// | [4] btn_1 | | | -// | [5] btn_2 | | | -// | [6] btn_3 | | | -// | [7] btn_4 | | | -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module mame_keymap - ( - // Clock and Reset - input wire clk, - input wire reset, - // PS/2 Interface - input wire [10:0] ps2_key, - // Gamepad Interface - output reg [3:0] start, //! Start 1,2,3,4 - output reg [3:0] coin, //! Coin 1,2,3,4 - output reg pause, //! Pause - output reg [7:0] player1, //! Player 1 - output reg [7:0] player2, //! Player 2 - output reg [7:0] player3, //! Player 3 - output reg [7:0] player4 //! Player 4 - ); - - wire pressed = ps2_key[9]; - - always_ff @(posedge clk) begin - reg old_state; - if (reset) begin - start <= 4'h0; - coin <= 4'h0; - pause <= 1'h0; - player1 <= 8'h0; - player2 <= 8'h0; - player3 <= 8'h0; - player4 <= 8'h0; - end - else begin - old_state <= ps2_key[10]; - if(old_state ^ ps2_key[10]) begin - case(ps2_key[8:0]) - 9'h016: start[0] <= pressed; // 1 - 9'h01E: start[1] <= pressed; // 2 - 9'h026: start[2] <= pressed; // 3 - 9'h025: start[3] <= pressed; // 4 - - 9'h02E: coin[0] <= pressed; // 5 - 9'h036: coin[1] <= pressed; // 6 - 9'h03D: coin[2] <= pressed; // 7 - 9'h03E: coin[2] <= pressed; // 8 - - 9'h04D: pause <= pressed; // P - - 9'h175: player1[0] <= pressed; // Up - 9'h172: player1[1] <= pressed; // Down - 9'h16B: player1[2] <= pressed; // Left - 9'h174: player1[3] <= pressed; // Right - 9'h014: player1[4] <= pressed; // Left Ctrl - 9'h011: player1[5] <= pressed; // Left Alt - 9'h029: player1[6] <= pressed; // Space - 9'h012: player1[7] <= pressed; // Left Shift - - 9'h02D: player2[0] <= pressed; // R - 9'h02B: player2[1] <= pressed; // F - 9'h023: player2[2] <= pressed; // D - 9'h034: player2[3] <= pressed; // G - 9'h01C: player2[4] <= pressed; // A - 9'h01B: player2[5] <= pressed; // S - 9'h015: player2[6] <= pressed; // Q - 9'h01D: player2[7] <= pressed; // W - - 9'h043: player3[0] <= pressed; // I - 9'h042: player3[1] <= pressed; // K - 9'h03B: player3[2] <= pressed; // J - 9'h04B: player3[3] <= pressed; // L - 9'h114: player3[4] <= pressed; // Right Ctrl - 9'h059: player3[5] <= pressed; // Right Shift - 9'h05A: player3[6] <= pressed; // Enter - - 9'h075: player4[0] <= pressed; // Keypad 8 and Up Arrow - 9'h072: player4[1] <= pressed; // Keypad 2 and Down Arrow - 9'h06B: player4[2] <= pressed; // Keypad 4 and Left Arrow - 9'h074: player4[3] <= pressed; // Keypad 6 and Right Arrow - 9'h070: player4[4] <= pressed; // Keypad 0 and Insert - 9'h071: player4[5] <= pressed; // Keypad . and Delete - 9'h15A: player4[6] <= pressed; // Keypad ENTER - endcase - end - end - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// PS/2 Keyboard to MAME Key Mapping +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ +// +// key bitmap: +// +// | Gamepad | Start | Coinage | +// | --------- | ----------- | ---------- | +// | [0] up | [0] start 1 | [0] coin 1 | +// | [1] down | [1] start 2 | [1] coin 2 | +// | [2] left | [2] start 3 | [2] coin 3 | +// | [3] right | [3] start 4 | [3] coin 4 | +// | [4] btn_1 | | | +// | [5] btn_2 | | | +// | [6] btn_3 | | | +// | [7] btn_4 | | | +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module mame_keymap + ( + // Clock and Reset + input wire clk, + input wire reset, + // PS/2 Interface + input wire [10:0] ps2_key, + // Gamepad Interface + output reg [3:0] start, //! Start 1,2,3,4 + output reg [3:0] coin, //! Coin 1,2,3,4 + output reg pause, //! Pause + output reg [7:0] player1, //! Player 1 + output reg [7:0] player2, //! Player 2 + output reg [7:0] player3, //! Player 3 + output reg [7:0] player4 //! Player 4 + ); + + wire pressed = ps2_key[9]; + + always_ff @(posedge clk) begin + reg old_state; + if (reset) begin + start <= 4'h0; + coin <= 4'h0; + pause <= 1'h0; + player1 <= 8'h0; + player2 <= 8'h0; + player3 <= 8'h0; + player4 <= 8'h0; + end + else begin + old_state <= ps2_key[10]; + if(old_state ^ ps2_key[10]) begin + case(ps2_key[8:0]) + 9'h016: start[0] <= pressed; // 1 + 9'h01E: start[1] <= pressed; // 2 + 9'h026: start[2] <= pressed; // 3 + 9'h025: start[3] <= pressed; // 4 + + 9'h02E: coin[0] <= pressed; // 5 + 9'h036: coin[1] <= pressed; // 6 + 9'h03D: coin[2] <= pressed; // 7 + 9'h03E: coin[2] <= pressed; // 8 + + 9'h04D: pause <= pressed; // P + + 9'h175: player1[0] <= pressed; // Up + 9'h172: player1[1] <= pressed; // Down + 9'h16B: player1[2] <= pressed; // Left + 9'h174: player1[3] <= pressed; // Right + 9'h014: player1[4] <= pressed; // Left Ctrl + 9'h011: player1[5] <= pressed; // Left Alt + 9'h029: player1[6] <= pressed; // Space + 9'h012: player1[7] <= pressed; // Left Shift + + 9'h02D: player2[0] <= pressed; // R + 9'h02B: player2[1] <= pressed; // F + 9'h023: player2[2] <= pressed; // D + 9'h034: player2[3] <= pressed; // G + 9'h01C: player2[4] <= pressed; // A + 9'h01B: player2[5] <= pressed; // S + 9'h015: player2[6] <= pressed; // Q + 9'h01D: player2[7] <= pressed; // W + + 9'h043: player3[0] <= pressed; // I + 9'h042: player3[1] <= pressed; // K + 9'h03B: player3[2] <= pressed; // J + 9'h04B: player3[3] <= pressed; // L + 9'h114: player3[4] <= pressed; // Right Ctrl + 9'h059: player3[5] <= pressed; // Right Shift + 9'h05A: player3[6] <= pressed; // Enter + + 9'h075: player4[0] <= pressed; // Keypad 8 and Up Arrow + 9'h072: player4[1] <= pressed; // Keypad 2 and Down Arrow + 9'h06B: player4[2] <= pressed; // Keypad 4 and Left Arrow + 9'h074: player4[3] <= pressed; // Keypad 6 and Right Arrow + 9'h070: player4[4] <= pressed; // Keypad 0 and Insert + 9'h071: player4[5] <= pressed; // Keypad . and Delete + 9'h15A: player4[6] <= pressed; // Keypad ENTER + endcase + end + end + end + +endmodule diff --git a/platform/pocket/interface/mame_keymap_f.sv b/platform/pocket/interface/mame_keymap_f.sv index 9f02465..95e6a45 100644 --- a/platform/pocket/interface/mame_keymap_f.sv +++ b/platform/pocket/interface/mame_keymap_f.sv @@ -1,156 +1,156 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// PS/2 Keyboard to MAME Key Mapping -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ -// -// key bitmap: -// -// | Gamepad | Start | Coinage | -// | --------- | ----------- | ---------- | -// | [0] up | [0] start 1 | [0] coin 1 | -// | [1] down | [1] start 2 | [1] coin 2 | -// | [2] left | [2] start 3 | [2] coin 3 | -// | [3] right | [3] start 4 | [3] coin 4 | -// | [4] btn_1 | | | -// | [5] btn_2 | | | -// | [6] btn_3 | | | -// | [7] btn_4 | | | -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module mame_keymap_f - ( - // Clock and Reset - input wire clk, - input wire reset, - // PS/2 Interface - input wire [10:0] ps2_key, - // Gamepad Interface - // Start 1,2,3,4 - output reg kb1_start, kb2_start, kb3_start, kb4_start, - // Coin 1,2,3,4 - output reg kb1_coin, kb2_coin, kb3_coin, kb4_coin, - // Service Control - output reg kb_pause, kb_tilt, kb_test, kb_reset, - output reg kb_service, - // Player 1 - output reg kb1_up, kb1_down, kb1_left, kb1_right, //! Directional Pad - output reg kb1_btn1, kb1_btn2, kb1_btn3, kb1_btn4, //! Y/B/A/X - output reg kb1_btn5, kb1_btn6, //! L/R / Coin P1 / P1 Start - // Player 2 - output reg kb2_up, kb2_down, kb2_left, kb2_right, //! Directional Pad - output reg kb2_btn1, kb2_btn2, kb2_btn3, kb2_btn4, //! Y/B/A/X - output reg kb2_btn5, kb2_btn6, //! L/R / Coin P2 / P2 Start - // Player 3 - output reg kb3_up, kb3_down, kb3_left, kb3_right, //! Directional Pad - output reg kb3_btn1, kb3_btn2, kb3_btn3, kb3_btn4, //! Y/B/A/X - output reg kb3_btn5, kb3_btn6, //! L/R / Coin P3 / P3 Start - // Player 4 - output reg kb4_up, kb4_down, kb4_left, kb4_right, //! Directional Pad - output reg kb4_btn1, kb4_btn2, kb4_btn3, kb4_btn4, //! Y/B/A/X - output reg kb4_btn5, kb4_btn6 //! L/R / Coin P4 / P4 Start - ); - - wire pressed = ps2_key[9]; - - always_ff @(posedge clk) begin - reg old_state; - if (reset) begin - // start <= 4'h0; - // coin <= 4'h0; - // pause <= 1'h0; - // player1 <= 8'h0; - // player2 <= 8'h0; - // player3 <= 8'h0; - // player4 <= 8'h0; - end - else begin - old_state <= ps2_key[10]; - if(old_state ^ ps2_key[10]) begin - case(ps2_key[8:0]) - // Service Control - 9'h04D: kb_pause <= pressed; // P - 9'h02C: kb_tilt <= pressed; // T - 9'h006: kb_test <= pressed; // F2 - 9'h004: kb_reset <= pressed; // F3 - 9'h046: kb_service <= pressed; // 9 - // Start - 9'h016: kb1_start <= pressed; // 1 - 9'h01E: kb2_start <= pressed; // 2 - 9'h026: kb3_start <= pressed; // 3 - 9'h025: kb4_start <= pressed; // 4 - // Coinage - 9'h02E: kb1_coin <= pressed; // 5 - 9'h036: kb2_coin <= pressed; // 6 - 9'h03D: kb3_coin <= pressed; // 7 - 9'h03E: kb4_coin <= pressed; // 8 - // Player 1 - 9'h175: kb1_up <= pressed; // Up - 9'h172: kb1_down <= pressed; // Down - 9'h16B: kb1_left <= pressed; // Left - 9'h174: kb1_right <= pressed; // Right - 9'h014: kb1_btn1 <= pressed; // Left Ctrl - 9'h011: kb1_btn2 <= pressed; // Left Alt - 9'h029: kb1_btn3 <= pressed; // Space - 9'h012: kb1_btn4 <= pressed; // Left Shift - 9'h01A: kb1_btn5 <= pressed; // Z - 9'h022: kb1_btn6 <= pressed; // X - // Player 2 - 9'h02D: kb2_up <= pressed; // R - 9'h02B: kb2_down <= pressed; // F - 9'h023: kb2_left <= pressed; // D - 9'h034: kb2_right <= pressed; // G - 9'h01C: kb2_btn1 <= pressed; // A - 9'h01B: kb2_btn2 <= pressed; // S - 9'h015: kb2_btn3 <= pressed; // Q - 9'h01D: kb2_btn4 <= pressed; // W - // Player 3 - 9'h043: kb3_up <= pressed; // I - 9'h042: kb3_down <= pressed; // K - 9'h03B: kb3_left <= pressed; // J - 9'h04B: kb3_right <= pressed; // L - 9'h114: kb3_btn1 <= pressed; // Right Ctrl - 9'h059: kb3_btn2 <= pressed; // Right Shift - 9'h05A: kb3_btn3 <= pressed; // Enter - // Player 4 - 9'h075: kb4_up <= pressed; // Keypad 8 and Up Arrow - 9'h072: kb4_down <= pressed; // Keypad 2 and Down Arrow - 9'h06B: kb4_left <= pressed; // Keypad 4 and Left Arrow - 9'h074: kb4_right <= pressed; // Keypad 6 and Right Arrow - 9'h070: kb4_btn1 <= pressed; // Keypad 0 and Insert - 9'h071: kb4_btn2 <= pressed; // Keypad . and Delete - 9'h15A: kb4_btn3 <= pressed; // Keypad ENTER - endcase - end - end - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// PS/2 Keyboard to MAME Key Mapping +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ +// +// key bitmap: +// +// | Gamepad | Start | Coinage | +// | --------- | ----------- | ---------- | +// | [0] up | [0] start 1 | [0] coin 1 | +// | [1] down | [1] start 2 | [1] coin 2 | +// | [2] left | [2] start 3 | [2] coin 3 | +// | [3] right | [3] start 4 | [3] coin 4 | +// | [4] btn_1 | | | +// | [5] btn_2 | | | +// | [6] btn_3 | | | +// | [7] btn_4 | | | +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module mame_keymap_f + ( + // Clock and Reset + input wire clk, + input wire reset, + // PS/2 Interface + input wire [10:0] ps2_key, + // Gamepad Interface + // Start 1,2,3,4 + output reg kb1_start, kb2_start, kb3_start, kb4_start, + // Coin 1,2,3,4 + output reg kb1_coin, kb2_coin, kb3_coin, kb4_coin, + // Service Control + output reg kb_pause, kb_tilt, kb_test, kb_reset, + output reg kb_service, + // Player 1 + output reg kb1_up, kb1_down, kb1_left, kb1_right, //! Directional Pad + output reg kb1_btn1, kb1_btn2, kb1_btn3, kb1_btn4, //! Y/B/A/X + output reg kb1_btn5, kb1_btn6, //! L/R / Coin P1 / P1 Start + // Player 2 + output reg kb2_up, kb2_down, kb2_left, kb2_right, //! Directional Pad + output reg kb2_btn1, kb2_btn2, kb2_btn3, kb2_btn4, //! Y/B/A/X + output reg kb2_btn5, kb2_btn6, //! L/R / Coin P2 / P2 Start + // Player 3 + output reg kb3_up, kb3_down, kb3_left, kb3_right, //! Directional Pad + output reg kb3_btn1, kb3_btn2, kb3_btn3, kb3_btn4, //! Y/B/A/X + output reg kb3_btn5, kb3_btn6, //! L/R / Coin P3 / P3 Start + // Player 4 + output reg kb4_up, kb4_down, kb4_left, kb4_right, //! Directional Pad + output reg kb4_btn1, kb4_btn2, kb4_btn3, kb4_btn4, //! Y/B/A/X + output reg kb4_btn5, kb4_btn6 //! L/R / Coin P4 / P4 Start + ); + + wire pressed = ps2_key[9]; + + always_ff @(posedge clk) begin + reg old_state; + if (reset) begin + // start <= 4'h0; + // coin <= 4'h0; + // pause <= 1'h0; + // player1 <= 8'h0; + // player2 <= 8'h0; + // player3 <= 8'h0; + // player4 <= 8'h0; + end + else begin + old_state <= ps2_key[10]; + if(old_state ^ ps2_key[10]) begin + case(ps2_key[8:0]) + // Service Control + 9'h04D: kb_pause <= pressed; // P + 9'h02C: kb_tilt <= pressed; // T + 9'h006: kb_test <= pressed; // F2 + 9'h004: kb_reset <= pressed; // F3 + 9'h046: kb_service <= pressed; // 9 + // Start + 9'h016: kb1_start <= pressed; // 1 + 9'h01E: kb2_start <= pressed; // 2 + 9'h026: kb3_start <= pressed; // 3 + 9'h025: kb4_start <= pressed; // 4 + // Coinage + 9'h02E: kb1_coin <= pressed; // 5 + 9'h036: kb2_coin <= pressed; // 6 + 9'h03D: kb3_coin <= pressed; // 7 + 9'h03E: kb4_coin <= pressed; // 8 + // Player 1 + 9'h175: kb1_up <= pressed; // Up + 9'h172: kb1_down <= pressed; // Down + 9'h16B: kb1_left <= pressed; // Left + 9'h174: kb1_right <= pressed; // Right + 9'h014: kb1_btn1 <= pressed; // Left Ctrl + 9'h011: kb1_btn2 <= pressed; // Left Alt + 9'h029: kb1_btn3 <= pressed; // Space + 9'h012: kb1_btn4 <= pressed; // Left Shift + 9'h01A: kb1_btn5 <= pressed; // Z + 9'h022: kb1_btn6 <= pressed; // X + // Player 2 + 9'h02D: kb2_up <= pressed; // R + 9'h02B: kb2_down <= pressed; // F + 9'h023: kb2_left <= pressed; // D + 9'h034: kb2_right <= pressed; // G + 9'h01C: kb2_btn1 <= pressed; // A + 9'h01B: kb2_btn2 <= pressed; // S + 9'h015: kb2_btn3 <= pressed; // Q + 9'h01D: kb2_btn4 <= pressed; // W + // Player 3 + 9'h043: kb3_up <= pressed; // I + 9'h042: kb3_down <= pressed; // K + 9'h03B: kb3_left <= pressed; // J + 9'h04B: kb3_right <= pressed; // L + 9'h114: kb3_btn1 <= pressed; // Right Ctrl + 9'h059: kb3_btn2 <= pressed; // Right Shift + 9'h05A: kb3_btn3 <= pressed; // Enter + // Player 4 + 9'h075: kb4_up <= pressed; // Keypad 8 and Up Arrow + 9'h072: kb4_down <= pressed; // Keypad 2 and Down Arrow + 9'h06B: kb4_left <= pressed; // Keypad 4 and Left Arrow + 9'h074: kb4_right <= pressed; // Keypad 6 and Right Arrow + 9'h070: kb4_btn1 <= pressed; // Keypad 0 and Insert + 9'h071: kb4_btn2 <= pressed; // Keypad . and Delete + 9'h15A: kb4_btn3 <= pressed; // Keypad ENTER + endcase + end + end + end + +endmodule diff --git a/platform/pocket/interface/pause_crtl.sv b/platform/pocket/interface/pause_crtl.sv index 961c443..b762c2b 100644 --- a/platform/pocket/interface/pause_crtl.sv +++ b/platform/pocket/interface/pause_crtl.sv @@ -1,48 +1,48 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket Generic Pause Handling -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module pause_crtl - ( - input logic clk_sys, //! Clock to Sync To (eg: clk_sys) - input logic os_inmenu, //! Menu Status (active-high when menu is open) - input logic pause_req, //! Pause Requested by another Module - output logic pause_core //! Pause signal to Core - ); - - // Synchronize Home/Analogue Button - reg inmenu_s; - synch_2 sync_inmenu(os_inmenu, inmenu_s, clk_sys); - - assign pause_core = (inmenu_s | pause_req); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket Generic Pause Handling +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module pause_crtl + ( + input logic clk_sys, //! Clock to Sync To (eg: clk_sys) + input logic os_inmenu, //! Menu Status (active-high when menu is open) + input logic pause_req, //! Pause Requested by another Module + output logic pause_core //! Pause signal to Core + ); + + // Synchronize Home/Analogue Button + reg inmenu_s; + synch_2 sync_inmenu(os_inmenu, inmenu_s, clk_sys); + + assign pause_core = (inmenu_s | pause_req); + +endmodule diff --git a/platform/pocket/interface/usb_mouse.sv b/platform/pocket/interface/usb_mouse.sv index c0fcd33..3aef6a9 100644 --- a/platform/pocket/interface/usb_mouse.sv +++ b/platform/pocket/interface/usb_mouse.sv @@ -1,95 +1,95 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ -// Analogue Pocket Dock USB Notes: -// -// Mouse: -// Because mouse input data is report/event based (using deltas instead of -// absolute coordinates), a 16-bit counter is used to identify each unique -// report, and incremented each time a new report is sent. -// A comparator can be used against the current and previous counter value -// to detect new events. -// -// In the mouse data are X position delta, Y position delta, -// up to 8 buttons, and the report counter. -// Buttons, starting at bit 0 with left, right, middle, etc. -// -// | Register bit range | Function | -// | :----------------- | :----------------------- | -// | cont4_joy[31:16] | Buttons | -// | cont4_joy[15:0] | Relative X movement (LE) | -// | cont4_key[15:0] | Report counter (LE) | -// | cont4_trig[15:0] | Relative Y movement (LE) | -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module usb_mouse - ( - // Clock and Reset - input logic clk, // System Clock - input logic reset, // Reset - // APF Mouse - input logic [31:0] cont4_key, // Keypad - input logic [31:0] cont4_joy, // Joystick - input logic [15:0] cont4_trig, // Trigger - // USB Mouse - output logic mouse_left_btn, // Mouse Left Button - output logic mouse_middle_btn, // Mouse Right Button - output logic mouse_right_btn, // Mouse Middle Button - output logic signed [15:0] mouse_dx, // Mouse X - output logic signed [15:0] mouse_dy, // Mouse Y - // PS/2 Interface - output logic [24:0] ps2_mouse = 25'h0 // [24] - toggles with every event - ); - - // Mouse Internal Logic - wire [15:0] mouse_report_counter = {cont4_key[7:0], cont4_key[15:8]}; - wire [7:0] mouse_buttons; - wire signed [15:0] mouse_pointer_x; - wire signed [15:0] mouse_pointer_y; - - // USB Mouse Check - wire [3:0] key_type; - wire is_mouse = (key_type == 4'h5) ? 1'b1 : 1'b0; // APF Input Type - - synch_3 #(.WIDTH(4)) sync_mt( cont4_key[31:28], key_type, clk); - synch_3 #(.WIDTH(8)) sync_mb( cont4_joy[23:16], mouse_buttons, clk); - synch_3 #(.WIDTH(16)) sync_mx({cont4_joy[7:0], cont4_joy[15:8]}, mouse_pointer_x, clk); - synch_3 #(.WIDTH(16)) sync_my({cont4_trig[7:0], cont4_trig[15:8]}, mouse_pointer_y, clk); - - assign mouse_left_btn = mouse_buttons[0]; - assign mouse_right_btn = mouse_buttons[1]; - assign mouse_middle_btn = mouse_buttons[2]; - assign mouse_dx = mouse_pointer_x; - assign mouse_dy = mouse_pointer_y; - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket USB HID Keyboard/Mouse and PS/2 Scan Code Translation +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ +// Analogue Pocket Dock USB Notes: +// +// Mouse: +// Because mouse input data is report/event based (using deltas instead of +// absolute coordinates), a 16-bit counter is used to identify each unique +// report, and incremented each time a new report is sent. +// A comparator can be used against the current and previous counter value +// to detect new events. +// +// In the mouse data are X position delta, Y position delta, +// up to 8 buttons, and the report counter. +// Buttons, starting at bit 0 with left, right, middle, etc. +// +// | Register bit range | Function | +// | :----------------- | :----------------------- | +// | cont4_joy[31:16] | Buttons | +// | cont4_joy[15:0] | Relative X movement (LE) | +// | cont4_key[15:0] | Report counter (LE) | +// | cont4_trig[15:0] | Relative Y movement (LE) | +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module usb_mouse + ( + // Clock and Reset + input logic clk, // System Clock + input logic reset, // Reset + // APF Mouse + input logic [31:0] cont4_key, // Keypad + input logic [31:0] cont4_joy, // Joystick + input logic [15:0] cont4_trig, // Trigger + // USB Mouse + output logic mouse_left_btn, // Mouse Left Button + output logic mouse_middle_btn, // Mouse Right Button + output logic mouse_right_btn, // Mouse Middle Button + output logic signed [15:0] mouse_dx, // Mouse X + output logic signed [15:0] mouse_dy, // Mouse Y + // PS/2 Interface + output logic [24:0] ps2_mouse = 25'h0 // [24] - toggles with every event + ); + + // Mouse Internal Logic + wire [15:0] mouse_report_counter = {cont4_key[7:0], cont4_key[15:8]}; + wire [7:0] mouse_buttons; + wire signed [15:0] mouse_pointer_x; + wire signed [15:0] mouse_pointer_y; + + // USB Mouse Check + wire [3:0] key_type; + wire is_mouse = (key_type == 4'h5) ? 1'b1 : 1'b0; // APF Input Type + + synch_3 #(.WIDTH(4)) sync_mt( cont4_key[31:28], key_type, clk); + synch_3 #(.WIDTH(8)) sync_mb( cont4_joy[23:16], mouse_buttons, clk); + synch_3 #(.WIDTH(16)) sync_mx({cont4_joy[7:0], cont4_joy[15:8]}, mouse_pointer_x, clk); + synch_3 #(.WIDTH(16)) sync_my({cont4_trig[7:0], cont4_trig[15:8]}, mouse_pointer_y, clk); + + assign mouse_left_btn = mouse_buttons[0]; + assign mouse_right_btn = mouse_buttons[1]; + assign mouse_middle_btn = mouse_buttons[2]; + assign mouse_dx = mouse_pointer_x; + assign mouse_dy = mouse_pointer_y; + +endmodule diff --git a/platform/pocket/megafunctions/mf_audio_pll.qip b/platform/pocket/megafunctions/mf_audio_pll.qip index efec938..c6e4883 100644 --- a/platform/pocket/megafunctions/mf_audio_pll.qip +++ b/platform/pocket/megafunctions/mf_audio_pll.qip @@ -1,337 +1,337 @@ -set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_TOOL_NAME "altera_pll" -set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_TOOL_VERSION "17.1" -set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_TOOL_ENV "mwpim" -set_global_assignment -library "mf_audio_pll" -name MISC_FILE [file join $::quartus(qip_path) "mf_audio_pll.cmp"] -set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_TARGETED_DEVICE_FAMILY "Cyclone V" -set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" -set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_QSYS_MODE "UNKNOWN" -set_global_assignment -name SYNTHESIS_ONLY_QIP ON -set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_NAME "bWZfYXVkaW9fcGxs" -set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTA==" -set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_REPORT_HIERARCHY "Off" -set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_INTERNAL "Off" -set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" -set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_VERSION "MTcuMQ==" -set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIChBTFRFUkFfUExMKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_NAME "bWZfYXVkaW9fcGxsXzAwMDI=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTA==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_REPORT_HIERARCHY "Off" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_INTERNAL "Off" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_VERSION "MTcuMQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIChBTFRFUkFfUExMKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZGVidWdfcHJpbnRfb3V0cHV0::ZmFsc2U=::ZGVidWdfcHJpbnRfb3V0cHV0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZGVidWdfdXNlX3JiY190YWZfbWV0aG9k::ZmFsc2U=::ZGVidWdfdXNlX3JiY190YWZfbWV0aG9k" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZGV2aWNl::NUNFQkEyRjE3QTc=::ZGV2aWNl" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9tb2Rl::RnJhY3Rpb25hbC1OIFBMTA==::UExMIE1vZGU=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZnJhY3Rpb25hbF92Y29fbXVsdGlwbGllcg==::dHJ1ZQ==::ZnJhY3Rpb25hbF92Y29fbXVsdGlwbGllcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3JlZmVyZW5jZV9jbG9ja19mcmVxdWVuY3k=::NzQuMjU=::UmVmZXJlbmNlIENsb2NrIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cmVmZXJlbmNlX2Nsb2NrX2ZyZXF1ZW5jeQ==::NzQuMjUgTUh6::cmVmZXJlbmNlX2Nsb2NrX2ZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2NoYW5uZWxfc3BhY2luZw==::MC4w::Q2hhbm5lbCBTcGFjaW5n" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX29wZXJhdGlvbl9tb2Rl::ZGlyZWN0::T3BlcmF0aW9uIE1vZGU=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZlZWRiYWNrX2Nsb2Nr::R2xvYmFsIENsb2Nr::RmVlZGJhY2sgQ2xvY2s=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWN0aW9uYWxfY291dA==::MzI=::RnJhY3Rpb25hbCBjYXJyeSBvdXQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RzbV9vdXRfc2Vs::MXN0X29yZGVy::RFNNIE9yZGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3BlcmF0aW9uX21vZGU=::ZGlyZWN0::b3BlcmF0aW9uX21vZGU=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9sb2NrZWQ=::dHJ1ZQ==::RW5hYmxlIGxvY2tlZCBvdXRwdXQgcG9ydA==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Fkdl9wYXJhbXM=::ZmFsc2U=::RW5hYmxlIHBoeXNpY2FsIG91dHB1dCBjbG9jayBwYXJhbWV0ZXJz" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX251bWJlcl9vZl9jbG9ja3M=::Mg==::TnVtYmVyIE9mIENsb2Nrcw==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "bnVtYmVyX29mX2Nsb2Nrcw==::Mg==::bnVtYmVyX29mX2Nsb2Nrcw==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX211bHRpcGx5X2ZhY3Rvcg==::MQ==::TXVsdGlwbHkgRmFjdG9yIChNLUNvdW50ZXIp" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWNfbXVsdGlwbHlfZmFjdG9y::MQ==::RnJhY3Rpb25hbCBNdWx0aXBseSBGYWN0b3IgKEsp" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3Jfbg==::MQ==::RGl2aWRlIEZhY3RvciAoTi1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjA=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kw::MTIuMjg4::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzA=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iw::OA==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjA=::NDY5MjM2MDIz::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMA==::NDk=::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MA==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzA=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDA=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUw::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kx::My4wNzI=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Ix::OA==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE=::NDY5MjM2MDIz::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMQ==::MTk2::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MQ==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUx::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjI=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3ky::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzI=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iy::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjI=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMg==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mg==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMg==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mg==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzI=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDI=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUy::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjM=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kz::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzM=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iz::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjM=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMw==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mw==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMw==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mw==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzM=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDM=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUz::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjQ=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k0::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzQ=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I0::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjQ=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNA==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5NA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0NA==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzQ=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDQ=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU0::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjU=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k1::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzU=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I1::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjU=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNQ==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5NQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0NQ==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzU=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDU=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU1::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjY=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k2::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzY=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I2::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjY=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNg==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Ng==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNg==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Ng==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzY=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDY=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU2::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjc=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k3::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzc=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I3::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjc=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNw==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Nw==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNw==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Nw==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzc=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDc=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU3::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjg=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k4::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzg=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I4::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjg=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yOA==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5OA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzOA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0OA==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzg=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDg=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU4::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjk=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k5::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzk=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I5::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjk=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yOQ==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5OQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzOQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0OQ==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzk=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDk=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU5::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEw::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMA==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEw::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMA==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEw::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTA=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTA=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTA=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTA=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEw::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEw::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMA==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEx::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMQ==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEx::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMQ==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEx::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTE=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTE=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTE=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTE=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEx::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEx::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMQ==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEy::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMg==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEy::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMg==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEy::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTI=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTI=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTI=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTI=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEy::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEy::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMg==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEz::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMw==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEz::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMw==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEz::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTM=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTM=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTM=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTM=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEz::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEz::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMw==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE0::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNA==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE0::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNA==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE0::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTQ=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTQ=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTQ=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTQ=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE0::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE0::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNA==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE1::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNQ==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE1::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNQ==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE1::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTU=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTU=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTU=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTU=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE1::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE1::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNQ==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE2::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNg==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE2::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNg==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE2::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTY=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTY=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTY=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTY=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE2::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE2::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNg==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE3::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNw==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE3::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNw==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE3::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTc=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTc=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTc=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTc=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE3::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE3::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNw==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA=::MTIuMjg4MDAwIE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQw::MCBwcw==::cGhhc2Vfc2hpZnQw" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTA=::NTA=::ZHV0eV9jeWNsZTA=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=::My4wNzIwMDAgTUh6::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQx::MCBwcw==::cGhhc2Vfc2hpZnQx" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE=::NTA=::ZHV0eV9jeWNsZTE=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQy::MCBwcw==::cGhhc2Vfc2hpZnQy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTI=::NTA=::ZHV0eV9jeWNsZTI=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQz::MCBwcw==::cGhhc2Vfc2hpZnQz" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTM=::NTA=::ZHV0eV9jeWNsZTM=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ0::MCBwcw==::cGhhc2Vfc2hpZnQ0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTQ=::NTA=::ZHV0eV9jeWNsZTQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ1::MCBwcw==::cGhhc2Vfc2hpZnQ1" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTU=::NTA=::ZHV0eV9jeWNsZTU=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTY=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTY=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ2::MCBwcw==::cGhhc2Vfc2hpZnQ2" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTY=::NTA=::ZHV0eV9jeWNsZTY=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTc=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTc=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ3::MCBwcw==::cGhhc2Vfc2hpZnQ3" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTc=::NTA=::ZHV0eV9jeWNsZTc=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTg=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTg=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ4::MCBwcw==::cGhhc2Vfc2hpZnQ4" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTg=::NTA=::ZHV0eV9jeWNsZTg=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTk=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTk=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ5::MCBwcw==::cGhhc2Vfc2hpZnQ5" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTk=::NTA=::ZHV0eV9jeWNsZTk=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEw::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEw" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMA==::MCBwcw==::cGhhc2Vfc2hpZnQxMA==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEw::NTA=::ZHV0eV9jeWNsZTEw" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEx::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEx" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMQ==::MCBwcw==::cGhhc2Vfc2hpZnQxMQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEx::NTA=::ZHV0eV9jeWNsZTEx" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEy::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMg==::MCBwcw==::cGhhc2Vfc2hpZnQxMg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEy::NTA=::ZHV0eV9jeWNsZTEy" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEz::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEz" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMw==::MCBwcw==::cGhhc2Vfc2hpZnQxMw==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEz::NTA=::ZHV0eV9jeWNsZTEz" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE0::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNA==::MCBwcw==::cGhhc2Vfc2hpZnQxNA==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE0::NTA=::ZHV0eV9jeWNsZTE0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE1::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE1" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNQ==::MCBwcw==::cGhhc2Vfc2hpZnQxNQ==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE1::NTA=::ZHV0eV9jeWNsZTE1" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE2::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE2" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNg==::MCBwcw==::cGhhc2Vfc2hpZnQxNg==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE2::NTA=::ZHV0eV9jeWNsZTE2" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE3::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE3" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNw==::MCBwcw==::cGhhc2Vfc2hpZnQxNw==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE3::NTA=::ZHV0eV9jeWNsZTE3" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9hdXRvX3Jlc2V0::T2Zm::UExMIEF1dG8gUmVzZXQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9iYW5kd2lkdGhfcHJlc2V0::QXV0bw==::UExMIEJhbmR3aWR0aCBQcmVzZXQ=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX3JlY29uZg==::ZmFsc2U=::RW5hYmxlIGR5bmFtaWMgcmVjb25maWd1cmF0aW9uIG9mIFBMTA==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Rwc19wb3J0cw==::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBkeW5hbWljIHBoYXNlIHNoaWZ0IHBvcnRz" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX3Bob3V0X3BvcnRz::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBQTEwgRFBBIG91dHB1dCBwb3J0" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGxsX3R5cGU=::R2VuZXJhbA==::UExMIFRZUEU=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGxsX3N1YnR5cGU=::R2VuZXJhbA==::UExMIFNVQlRZUEU=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl9saXN0::TS1Db3VudGVyIEhpIERpdmlkZSxNLUNvdW50ZXIgTG93IERpdmlkZSxOLUNvdW50ZXIgSGkgRGl2aWRlLE4tQ291bnRlciBMb3cgRGl2aWRlLE0tQ291bnRlciBCeXBhc3MgRW5hYmxlLE4tQ291bnRlciBCeXBhc3MgRW5hYmxlLE0tQ291bnRlciBPZGQgRGl2aWRlIEVuYWJsZSxOLUNvdW50ZXIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTAgSGkgRGl2aWRlLEMtQ291bnRlci0wIExvdyBEaXZpZGUsQy1Db3VudGVyLTAgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0wIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTAgSW5wdXQgU291cmNlLEMtQ291bnRlci0wIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTAgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTEgSGkgRGl2aWRlLEMtQ291bnRlci0xIExvdyBEaXZpZGUsQy1Db3VudGVyLTEgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0xIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTEgSW5wdXQgU291cmNlLEMtQ291bnRlci0xIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTEgT2RkIERpdmlkZSBFbmFibGUsVkNPIFBvc3QgRGl2aWRlIENvdW50ZXIgRW5hYmxlLENoYXJnZSBQdW1wIGN1cnJlbnQgKHVBKSxMb29wIEZpbHRlciBCYW5kd2lkdGggUmVzaXN0b3IgKE9obXMpICxQTEwgT3V0cHV0IFZDTyBGcmVxdWVuY3ksSy1GcmFjdGlvbmFsIERpdmlzaW9uIFZhbHVlIChEU00pLEZlZWRiYWNrIENsb2NrIFR5cGUsRmVlZGJhY2sgQ2xvY2sgTVVYIDEsRmVlZGJhY2sgQ2xvY2sgTVVYIDIsTSBDb3VudGVyIFNvdXJjZSBNVVgsUExMIEF1dG8gUmVzZXQ=::UGFyYW1ldGVyIE5hbWVz" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl92YWx1ZXM=::NCw0LDI1NiwyNTYsZmFsc2UsdHJ1ZSxmYWxzZSxmYWxzZSwyNSwyNCwxLDAscGhfbXV4X2NsayxmYWxzZSx0cnVlLDk4LDk4LDEsMCxwaF9tdXhfY2xrLGZhbHNlLGZhbHNlLDEsMzAsMjAwMCw2MDIuMTEyIE1Ieiw0NjkyMzYwMjMsbm9uZSxnbGIsbV9jbnQscGhfbXV4X2NsayxmYWxzZQ==::UGFyYW1ldGVyIFZhbHVlcw==" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX21pZl9nZW5lcmF0ZQ==::ZmFsc2U=::R2VuZXJhdGUgTUlGIGZpbGU=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9taWZfZHBz::ZmFsc2U=::RW5hYmxlIER5bmFtaWMgUGhhc2UgU2hpZnQgZm9yIE1JRiBzdHJlYW1pbmc=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19jbnRy::QzA=::RFBTIENvdW50ZXIgU2VsZWN0aW9u" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19udW0=::MQ==::TnVtYmVyIG9mIER5bmFtaWMgUGhhc2UgU2hpZnRz" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19kaXI=::UG9zaXRpdmU=::RHluYW1pYyBQaGFzZSBTaGlmdCBEaXJlY3Rpb24=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3JlZmNsa19zd2l0Y2g=::ZmFsc2U=::Q3JlYXRlIGEgc2Vjb25kIGlucHV0IGNsayAncmVmY2xrMSc=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9jYXNjYWRlX291dA==::ZmFsc2U=::Q3JlYXRlIGEgJ2Nhc2NhZGVfb3V0JyBzaWduYWwgdG8gY29ubmVjdCB3aXRoIGEgZG93bnN0cmVhbSBQTEw=" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9jYXNjYWRlX2lu::ZmFsc2U=::Q3JlYXRlIGFuIGFkanBsbGluIG9yIGNjbGsgc2lnbmFsIHRvIGNvbm5lY3Qgd2l0aCBhbiB1cHN0cmVhbSBQTEw=" - -set_global_assignment -library "mf_audio_pll" -name VERILOG_FILE [file join $::quartus(qip_path) "mf_audio_pll.v"] -set_global_assignment -library "mf_audio_pll" -name VERILOG_FILE [file join $::quartus(qip_path) "mf_audio_pll/mf_audio_pll_0002.v"] -set_global_assignment -library "mf_audio_pll" -name QIP_FILE [file join $::quartus(qip_path) "mf_audio_pll/mf_audio_pll_0002.qip"] - -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_TOOL_NAME "altera_pll" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_TOOL_VERSION "17.1" -set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_TOOL_ENV "mwpim" +set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_TOOL_NAME "altera_pll" +set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_TOOL_VERSION "17.1" +set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_TOOL_ENV "mwpim" +set_global_assignment -library "mf_audio_pll" -name MISC_FILE [file join $::quartus(qip_path) "mf_audio_pll.cmp"] +set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_TARGETED_DEVICE_FAMILY "Cyclone V" +set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" +set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_QSYS_MODE "UNKNOWN" +set_global_assignment -name SYNTHESIS_ONLY_QIP ON +set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_NAME "bWZfYXVkaW9fcGxs" +set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTA==" +set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" +set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_VERSION "MTcuMQ==" +set_global_assignment -entity "mf_audio_pll" -library "mf_audio_pll" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIChBTFRFUkFfUExMKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_NAME "bWZfYXVkaW9fcGxsXzAwMDI=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTA==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_VERSION "MTcuMQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIChBTFRFUkFfUExMKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZGVidWdfcHJpbnRfb3V0cHV0::ZmFsc2U=::ZGVidWdfcHJpbnRfb3V0cHV0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZGVidWdfdXNlX3JiY190YWZfbWV0aG9k::ZmFsc2U=::ZGVidWdfdXNlX3JiY190YWZfbWV0aG9k" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZGV2aWNl::NUNFQkEyRjE3QTc=::ZGV2aWNl" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9tb2Rl::RnJhY3Rpb25hbC1OIFBMTA==::UExMIE1vZGU=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZnJhY3Rpb25hbF92Y29fbXVsdGlwbGllcg==::dHJ1ZQ==::ZnJhY3Rpb25hbF92Y29fbXVsdGlwbGllcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3JlZmVyZW5jZV9jbG9ja19mcmVxdWVuY3k=::NzQuMjU=::UmVmZXJlbmNlIENsb2NrIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cmVmZXJlbmNlX2Nsb2NrX2ZyZXF1ZW5jeQ==::NzQuMjUgTUh6::cmVmZXJlbmNlX2Nsb2NrX2ZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2NoYW5uZWxfc3BhY2luZw==::MC4w::Q2hhbm5lbCBTcGFjaW5n" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX29wZXJhdGlvbl9tb2Rl::ZGlyZWN0::T3BlcmF0aW9uIE1vZGU=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZlZWRiYWNrX2Nsb2Nr::R2xvYmFsIENsb2Nr::RmVlZGJhY2sgQ2xvY2s=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWN0aW9uYWxfY291dA==::MzI=::RnJhY3Rpb25hbCBjYXJyeSBvdXQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RzbV9vdXRfc2Vs::MXN0X29yZGVy::RFNNIE9yZGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3BlcmF0aW9uX21vZGU=::ZGlyZWN0::b3BlcmF0aW9uX21vZGU=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9sb2NrZWQ=::dHJ1ZQ==::RW5hYmxlIGxvY2tlZCBvdXRwdXQgcG9ydA==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Fkdl9wYXJhbXM=::ZmFsc2U=::RW5hYmxlIHBoeXNpY2FsIG91dHB1dCBjbG9jayBwYXJhbWV0ZXJz" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX251bWJlcl9vZl9jbG9ja3M=::Mg==::TnVtYmVyIE9mIENsb2Nrcw==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "bnVtYmVyX29mX2Nsb2Nrcw==::Mg==::bnVtYmVyX29mX2Nsb2Nrcw==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX211bHRpcGx5X2ZhY3Rvcg==::MQ==::TXVsdGlwbHkgRmFjdG9yIChNLUNvdW50ZXIp" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWNfbXVsdGlwbHlfZmFjdG9y::MQ==::RnJhY3Rpb25hbCBNdWx0aXBseSBGYWN0b3IgKEsp" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3Jfbg==::MQ==::RGl2aWRlIEZhY3RvciAoTi1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjA=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kw::MTIuMjg4::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzA=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iw::OA==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjA=::NDY5MjM2MDIz::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMA==::NDk=::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MA==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzA=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDA=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUw::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kx::My4wNzI=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Ix::OA==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE=::NDY5MjM2MDIz::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMQ==::MTk2::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MQ==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUx::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjI=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3ky::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzI=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iy::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjI=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMg==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mg==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMg==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mg==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzI=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDI=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUy::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjM=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kz::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzM=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iz::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjM=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMw==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mw==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMw==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mw==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzM=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDM=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUz::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjQ=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k0::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzQ=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I0::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjQ=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNA==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5NA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0NA==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzQ=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDQ=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU0::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjU=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k1::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzU=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I1::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjU=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNQ==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5NQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0NQ==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzU=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDU=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU1::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjY=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k2::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzY=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I2::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjY=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNg==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Ng==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNg==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Ng==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzY=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDY=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU2::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjc=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k3::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzc=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I3::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjc=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNw==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Nw==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNw==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Nw==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzc=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDc=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU3::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjg=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k4::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzg=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I4::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjg=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yOA==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5OA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzOA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0OA==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzg=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDg=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU4::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjk=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k5::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzk=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I5::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjk=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yOQ==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5OQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzOQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0OQ==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzk=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDk=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU5::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEw::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMA==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEw::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMA==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEw::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTA=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTA=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTA=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTA=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEw::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEw::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMA==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEx::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMQ==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEx::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMQ==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEx::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTE=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTE=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTE=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTE=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEx::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEx::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMQ==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEy::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMg==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEy::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMg==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEy::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTI=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTI=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTI=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTI=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEy::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEy::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMg==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEz::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMw==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEz::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMw==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEz::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTM=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTM=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTM=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTM=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEz::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEz::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMw==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE0::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNA==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE0::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNA==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE0::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTQ=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTQ=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTQ=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTQ=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE0::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE0::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNA==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE1::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNQ==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE1::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNQ==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE1::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTU=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTU=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTU=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTU=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE1::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE1::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNQ==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE2::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNg==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE2::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNg==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE2::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTY=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTY=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTY=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTY=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE2::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE2::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNg==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE3::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNw==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE3::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNw==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE3::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTc=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTc=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTc=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTc=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE3::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE3::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNw==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA=::MTIuMjg4MDAwIE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQw::MCBwcw==::cGhhc2Vfc2hpZnQw" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTA=::NTA=::ZHV0eV9jeWNsZTA=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=::My4wNzIwMDAgTUh6::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQx::MCBwcw==::cGhhc2Vfc2hpZnQx" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE=::NTA=::ZHV0eV9jeWNsZTE=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQy::MCBwcw==::cGhhc2Vfc2hpZnQy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTI=::NTA=::ZHV0eV9jeWNsZTI=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQz::MCBwcw==::cGhhc2Vfc2hpZnQz" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTM=::NTA=::ZHV0eV9jeWNsZTM=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ0::MCBwcw==::cGhhc2Vfc2hpZnQ0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTQ=::NTA=::ZHV0eV9jeWNsZTQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ1::MCBwcw==::cGhhc2Vfc2hpZnQ1" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTU=::NTA=::ZHV0eV9jeWNsZTU=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTY=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTY=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ2::MCBwcw==::cGhhc2Vfc2hpZnQ2" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTY=::NTA=::ZHV0eV9jeWNsZTY=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTc=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTc=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ3::MCBwcw==::cGhhc2Vfc2hpZnQ3" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTc=::NTA=::ZHV0eV9jeWNsZTc=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTg=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTg=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ4::MCBwcw==::cGhhc2Vfc2hpZnQ4" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTg=::NTA=::ZHV0eV9jeWNsZTg=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTk=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTk=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ5::MCBwcw==::cGhhc2Vfc2hpZnQ5" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTk=::NTA=::ZHV0eV9jeWNsZTk=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEw::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEw" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMA==::MCBwcw==::cGhhc2Vfc2hpZnQxMA==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEw::NTA=::ZHV0eV9jeWNsZTEw" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEx::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEx" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMQ==::MCBwcw==::cGhhc2Vfc2hpZnQxMQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEx::NTA=::ZHV0eV9jeWNsZTEx" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEy::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMg==::MCBwcw==::cGhhc2Vfc2hpZnQxMg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEy::NTA=::ZHV0eV9jeWNsZTEy" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEz::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEz" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMw==::MCBwcw==::cGhhc2Vfc2hpZnQxMw==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEz::NTA=::ZHV0eV9jeWNsZTEz" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE0::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNA==::MCBwcw==::cGhhc2Vfc2hpZnQxNA==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE0::NTA=::ZHV0eV9jeWNsZTE0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE1::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE1" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNQ==::MCBwcw==::cGhhc2Vfc2hpZnQxNQ==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE1::NTA=::ZHV0eV9jeWNsZTE1" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE2::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE2" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNg==::MCBwcw==::cGhhc2Vfc2hpZnQxNg==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE2::NTA=::ZHV0eV9jeWNsZTE2" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE3::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE3" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNw==::MCBwcw==::cGhhc2Vfc2hpZnQxNw==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE3::NTA=::ZHV0eV9jeWNsZTE3" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9hdXRvX3Jlc2V0::T2Zm::UExMIEF1dG8gUmVzZXQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9iYW5kd2lkdGhfcHJlc2V0::QXV0bw==::UExMIEJhbmR3aWR0aCBQcmVzZXQ=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX3JlY29uZg==::ZmFsc2U=::RW5hYmxlIGR5bmFtaWMgcmVjb25maWd1cmF0aW9uIG9mIFBMTA==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Rwc19wb3J0cw==::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBkeW5hbWljIHBoYXNlIHNoaWZ0IHBvcnRz" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX3Bob3V0X3BvcnRz::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBQTEwgRFBBIG91dHB1dCBwb3J0" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGxsX3R5cGU=::R2VuZXJhbA==::UExMIFRZUEU=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "cGxsX3N1YnR5cGU=::R2VuZXJhbA==::UExMIFNVQlRZUEU=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl9saXN0::TS1Db3VudGVyIEhpIERpdmlkZSxNLUNvdW50ZXIgTG93IERpdmlkZSxOLUNvdW50ZXIgSGkgRGl2aWRlLE4tQ291bnRlciBMb3cgRGl2aWRlLE0tQ291bnRlciBCeXBhc3MgRW5hYmxlLE4tQ291bnRlciBCeXBhc3MgRW5hYmxlLE0tQ291bnRlciBPZGQgRGl2aWRlIEVuYWJsZSxOLUNvdW50ZXIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTAgSGkgRGl2aWRlLEMtQ291bnRlci0wIExvdyBEaXZpZGUsQy1Db3VudGVyLTAgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0wIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTAgSW5wdXQgU291cmNlLEMtQ291bnRlci0wIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTAgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTEgSGkgRGl2aWRlLEMtQ291bnRlci0xIExvdyBEaXZpZGUsQy1Db3VudGVyLTEgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0xIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTEgSW5wdXQgU291cmNlLEMtQ291bnRlci0xIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTEgT2RkIERpdmlkZSBFbmFibGUsVkNPIFBvc3QgRGl2aWRlIENvdW50ZXIgRW5hYmxlLENoYXJnZSBQdW1wIGN1cnJlbnQgKHVBKSxMb29wIEZpbHRlciBCYW5kd2lkdGggUmVzaXN0b3IgKE9obXMpICxQTEwgT3V0cHV0IFZDTyBGcmVxdWVuY3ksSy1GcmFjdGlvbmFsIERpdmlzaW9uIFZhbHVlIChEU00pLEZlZWRiYWNrIENsb2NrIFR5cGUsRmVlZGJhY2sgQ2xvY2sgTVVYIDEsRmVlZGJhY2sgQ2xvY2sgTVVYIDIsTSBDb3VudGVyIFNvdXJjZSBNVVgsUExMIEF1dG8gUmVzZXQ=::UGFyYW1ldGVyIE5hbWVz" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl92YWx1ZXM=::NCw0LDI1NiwyNTYsZmFsc2UsdHJ1ZSxmYWxzZSxmYWxzZSwyNSwyNCwxLDAscGhfbXV4X2NsayxmYWxzZSx0cnVlLDk4LDk4LDEsMCxwaF9tdXhfY2xrLGZhbHNlLGZhbHNlLDEsMzAsMjAwMCw2MDIuMTEyIE1Ieiw0NjkyMzYwMjMsbm9uZSxnbGIsbV9jbnQscGhfbXV4X2NsayxmYWxzZQ==::UGFyYW1ldGVyIFZhbHVlcw==" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX21pZl9nZW5lcmF0ZQ==::ZmFsc2U=::R2VuZXJhdGUgTUlGIGZpbGU=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9taWZfZHBz::ZmFsc2U=::RW5hYmxlIER5bmFtaWMgUGhhc2UgU2hpZnQgZm9yIE1JRiBzdHJlYW1pbmc=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19jbnRy::QzA=::RFBTIENvdW50ZXIgU2VsZWN0aW9u" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19udW0=::MQ==::TnVtYmVyIG9mIER5bmFtaWMgUGhhc2UgU2hpZnRz" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19kaXI=::UG9zaXRpdmU=::RHluYW1pYyBQaGFzZSBTaGlmdCBEaXJlY3Rpb24=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3JlZmNsa19zd2l0Y2g=::ZmFsc2U=::Q3JlYXRlIGEgc2Vjb25kIGlucHV0IGNsayAncmVmY2xrMSc=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9jYXNjYWRlX291dA==::ZmFsc2U=::Q3JlYXRlIGEgJ2Nhc2NhZGVfb3V0JyBzaWduYWwgdG8gY29ubmVjdCB3aXRoIGEgZG93bnN0cmVhbSBQTEw=" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9jYXNjYWRlX2lu::ZmFsc2U=::Q3JlYXRlIGFuIGFkanBsbGluIG9yIGNjbGsgc2lnbmFsIHRvIGNvbm5lY3Qgd2l0aCBhbiB1cHN0cmVhbSBQTEw=" + +set_global_assignment -library "mf_audio_pll" -name VERILOG_FILE [file join $::quartus(qip_path) "mf_audio_pll.v"] +set_global_assignment -library "mf_audio_pll" -name VERILOG_FILE [file join $::quartus(qip_path) "mf_audio_pll/mf_audio_pll_0002.v"] +set_global_assignment -library "mf_audio_pll" -name QIP_FILE [file join $::quartus(qip_path) "mf_audio_pll/mf_audio_pll_0002.qip"] + +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_TOOL_NAME "altera_pll" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_TOOL_VERSION "17.1" +set_global_assignment -entity "mf_audio_pll_0002" -library "mf_audio_pll" -name IP_TOOL_ENV "mwpim" diff --git a/platform/pocket/megafunctions/mf_audio_pll.v b/platform/pocket/megafunctions/mf_audio_pll.v index 6633406..7717852 100644 --- a/platform/pocket/megafunctions/mf_audio_pll.v +++ b/platform/pocket/megafunctions/mf_audio_pll.v @@ -1,255 +1,255 @@ -// megafunction wizard: %Altera PLL v17.1% -// GENERATION: XML -// mf_audio_pll.v - -// Generated using ACDS version 17.1 590 - -`timescale 1 ps / 1 ps -module mf_audio_pll ( - input wire refclk, // refclk.clk - input wire rst, // reset.reset - output wire outclk_0, // outclk0.clk - output wire outclk_1, // outclk1.clk - output wire locked // locked.export - ); - - mf_audio_pll_0002 mf_audio_pll_inst ( - .refclk (refclk), // refclk.clk - .rst (rst), // reset.reset - .outclk_0 (outclk_0), // outclk0.clk - .outclk_1 (outclk_1), // outclk1.clk - .locked (locked) // locked.export - ); - -endmodule -// Retrieval info: -// -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// IPFS_FILES : mf_audio_pll.vo -// RELATED_FILES: mf_audio_pll.v, mf_audio_pll_0002.v +// megafunction wizard: %Altera PLL v17.1% +// GENERATION: XML +// mf_audio_pll.v + +// Generated using ACDS version 17.1 590 + +`timescale 1 ps / 1 ps +module mf_audio_pll ( + input wire refclk, // refclk.clk + input wire rst, // reset.reset + output wire outclk_0, // outclk0.clk + output wire outclk_1, // outclk1.clk + output wire locked // locked.export + ); + + mf_audio_pll_0002 mf_audio_pll_inst ( + .refclk (refclk), // refclk.clk + .rst (rst), // reset.reset + .outclk_0 (outclk_0), // outclk0.clk + .outclk_1 (outclk_1), // outclk1.clk + .locked (locked) // locked.export + ); + +endmodule +// Retrieval info: +// +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// IPFS_FILES : mf_audio_pll.vo +// RELATED_FILES: mf_audio_pll.v, mf_audio_pll_0002.v diff --git a/platform/pocket/megafunctions/mf_audio_pll/mf_audio_pll_0002.qip b/platform/pocket/megafunctions/mf_audio_pll/mf_audio_pll_0002.qip index 916311f..4b55575 100644 --- a/platform/pocket/megafunctions/mf_audio_pll/mf_audio_pll_0002.qip +++ b/platform/pocket/megafunctions/mf_audio_pll/mf_audio_pll_0002.qip @@ -1,4 +1,4 @@ -set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*mf_audio_pll_0002*|altera_pll:altera_pll_i*|*" -set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*mf_audio_pll_0002*|altera_pll:altera_pll_i*|*" -set_instance_assignment -name PLL_AUTO_RESET OFF -to "*mf_audio_pll_0002*|altera_pll:altera_pll_i*|*" -set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*mf_audio_pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*mf_audio_pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*mf_audio_pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_AUTO_RESET OFF -to "*mf_audio_pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*mf_audio_pll_0002*|altera_pll:altera_pll_i*|*" diff --git a/platform/pocket/megafunctions/mf_audio_pll/mf_audio_pll_0002.v b/platform/pocket/megafunctions/mf_audio_pll/mf_audio_pll_0002.v index 86e4d75..19c7bea 100644 --- a/platform/pocket/megafunctions/mf_audio_pll/mf_audio_pll_0002.v +++ b/platform/pocket/megafunctions/mf_audio_pll/mf_audio_pll_0002.v @@ -1,90 +1,90 @@ -`timescale 1ns/10ps -module mf_audio_pll_0002( - - // interface 'refclk' - input wire refclk, - - // interface 'reset' - input wire rst, - - // interface 'outclk0' - output wire outclk_0, - - // interface 'outclk1' - output wire outclk_1, - - // interface 'locked' - output wire locked -); - - altera_pll #( - .fractional_vco_multiplier("true"), - .reference_clock_frequency("74.25 MHz"), - .operation_mode("direct"), - .number_of_clocks(2), - .output_clock_frequency0("12.288000 MHz"), - .phase_shift0("0 ps"), - .duty_cycle0(50), - .output_clock_frequency1("3.072000 MHz"), - .phase_shift1("0 ps"), - .duty_cycle1(50), - .output_clock_frequency2("0 MHz"), - .phase_shift2("0 ps"), - .duty_cycle2(50), - .output_clock_frequency3("0 MHz"), - .phase_shift3("0 ps"), - .duty_cycle3(50), - .output_clock_frequency4("0 MHz"), - .phase_shift4("0 ps"), - .duty_cycle4(50), - .output_clock_frequency5("0 MHz"), - .phase_shift5("0 ps"), - .duty_cycle5(50), - .output_clock_frequency6("0 MHz"), - .phase_shift6("0 ps"), - .duty_cycle6(50), - .output_clock_frequency7("0 MHz"), - .phase_shift7("0 ps"), - .duty_cycle7(50), - .output_clock_frequency8("0 MHz"), - .phase_shift8("0 ps"), - .duty_cycle8(50), - .output_clock_frequency9("0 MHz"), - .phase_shift9("0 ps"), - .duty_cycle9(50), - .output_clock_frequency10("0 MHz"), - .phase_shift10("0 ps"), - .duty_cycle10(50), - .output_clock_frequency11("0 MHz"), - .phase_shift11("0 ps"), - .duty_cycle11(50), - .output_clock_frequency12("0 MHz"), - .phase_shift12("0 ps"), - .duty_cycle12(50), - .output_clock_frequency13("0 MHz"), - .phase_shift13("0 ps"), - .duty_cycle13(50), - .output_clock_frequency14("0 MHz"), - .phase_shift14("0 ps"), - .duty_cycle14(50), - .output_clock_frequency15("0 MHz"), - .phase_shift15("0 ps"), - .duty_cycle15(50), - .output_clock_frequency16("0 MHz"), - .phase_shift16("0 ps"), - .duty_cycle16(50), - .output_clock_frequency17("0 MHz"), - .phase_shift17("0 ps"), - .duty_cycle17(50), - .pll_type("General"), - .pll_subtype("General") - ) altera_pll_i ( - .rst (rst), - .outclk ({outclk_1, outclk_0}), - .locked (locked), - .fboutclk ( ), - .fbclk (1'b0), - .refclk (refclk) - ); -endmodule - +`timescale 1ns/10ps +module mf_audio_pll_0002( + + // interface 'refclk' + input wire refclk, + + // interface 'reset' + input wire rst, + + // interface 'outclk0' + output wire outclk_0, + + // interface 'outclk1' + output wire outclk_1, + + // interface 'locked' + output wire locked +); + + altera_pll #( + .fractional_vco_multiplier("true"), + .reference_clock_frequency("74.25 MHz"), + .operation_mode("direct"), + .number_of_clocks(2), + .output_clock_frequency0("12.288000 MHz"), + .phase_shift0("0 ps"), + .duty_cycle0(50), + .output_clock_frequency1("3.072000 MHz"), + .phase_shift1("0 ps"), + .duty_cycle1(50), + .output_clock_frequency2("0 MHz"), + .phase_shift2("0 ps"), + .duty_cycle2(50), + .output_clock_frequency3("0 MHz"), + .phase_shift3("0 ps"), + .duty_cycle3(50), + .output_clock_frequency4("0 MHz"), + .phase_shift4("0 ps"), + .duty_cycle4(50), + .output_clock_frequency5("0 MHz"), + .phase_shift5("0 ps"), + .duty_cycle5(50), + .output_clock_frequency6("0 MHz"), + .phase_shift6("0 ps"), + .duty_cycle6(50), + .output_clock_frequency7("0 MHz"), + .phase_shift7("0 ps"), + .duty_cycle7(50), + .output_clock_frequency8("0 MHz"), + .phase_shift8("0 ps"), + .duty_cycle8(50), + .output_clock_frequency9("0 MHz"), + .phase_shift9("0 ps"), + .duty_cycle9(50), + .output_clock_frequency10("0 MHz"), + .phase_shift10("0 ps"), + .duty_cycle10(50), + .output_clock_frequency11("0 MHz"), + .phase_shift11("0 ps"), + .duty_cycle11(50), + .output_clock_frequency12("0 MHz"), + .phase_shift12("0 ps"), + .duty_cycle12(50), + .output_clock_frequency13("0 MHz"), + .phase_shift13("0 ps"), + .duty_cycle13(50), + .output_clock_frequency14("0 MHz"), + .phase_shift14("0 ps"), + .duty_cycle14(50), + .output_clock_frequency15("0 MHz"), + .phase_shift15("0 ps"), + .duty_cycle15(50), + .output_clock_frequency16("0 MHz"), + .phase_shift16("0 ps"), + .duty_cycle16(50), + .output_clock_frequency17("0 MHz"), + .phase_shift17("0 ps"), + .duty_cycle17(50), + .pll_type("General"), + .pll_subtype("General") + ) altera_pll_i ( + .rst (rst), + .outclk ({outclk_1, outclk_0}), + .locked (locked), + .fboutclk ( ), + .fbclk (1'b0), + .refclk (refclk) + ); +endmodule + diff --git a/platform/pocket/megafunctions/mf_datatable.qip b/platform/pocket/megafunctions/mf_datatable.qip index 9876cc0..8bd0843 100644 --- a/platform/pocket/megafunctions/mf_datatable.qip +++ b/platform/pocket/megafunctions/mf_datatable.qip @@ -1,4 +1,4 @@ -set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT" -set_global_assignment -name IP_TOOL_VERSION "17.1" -set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "mf_datatable.v"] +set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT" +set_global_assignment -name IP_TOOL_VERSION "17.1" +set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "mf_datatable.v"] diff --git a/platform/pocket/megafunctions/mf_datatable.v b/platform/pocket/megafunctions/mf_datatable.v index 0db807d..1727bb5 100644 --- a/platform/pocket/megafunctions/mf_datatable.v +++ b/platform/pocket/megafunctions/mf_datatable.v @@ -1,246 +1,246 @@ -// megafunction wizard: %RAM: 2-PORT% -// GENERATION: STANDARD -// VERSION: WM1.0 -// MODULE: altsyncram - -// ============================================================ -// File Name: mf_datatable.v -// Megafunction Name(s): -// altsyncram -// -// Simulation Library Files(s): -// altera_mf -// ============================================================ -// ************************************************************ -// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! -// -// 17.1.0 Build 590 10/25/2017 SJ Standard Edition -// ************************************************************ - - -//Copyright (C) 2017 Intel Corporation. All rights reserved. -//Your use of Intel 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 Intel Program License -//Subscription Agreement, the Intel Quartus Prime License Agreement, -//the Intel FPGA IP License Agreement, or other applicable license -//agreement, including, without limitation, that your use is for -//the sole purpose of programming logic devices manufactured by -//Intel and sold by Intel 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 mf_datatable ( - address_a, - address_b, - clock_a, - clock_b, - data_a, - data_b, - wren_a, - wren_b, - q_a, - q_b); - - input [7:0] address_a; - input [7:0] address_b; - input clock_a; - input clock_b; - input [31:0] data_a; - input [31:0] data_b; - input wren_a; - input wren_b; - output [31:0] q_a; - output [31:0] q_b; -`ifndef ALTERA_RESERVED_QIS -// synopsys translate_off -`endif - tri1 clock_a; - tri0 wren_a; - tri0 wren_b; -`ifndef ALTERA_RESERVED_QIS -// synopsys translate_on -`endif - - wire [31:0] sub_wire0; - wire [31:0] sub_wire1; - wire [31:0] q_a = sub_wire0[31:0]; - wire [31:0] q_b = sub_wire1[31:0]; - - altsyncram altsyncram_component ( - .address_a (address_a), - .address_b (address_b), - .clock0 (clock_a), - .clock1 (clock_b), - .data_a (data_a), - .data_b (data_b), - .wren_a (wren_a), - .wren_b (wren_b), - .q_a (sub_wire0), - .q_b (sub_wire1), - .aclr0 (1'b0), - .aclr1 (1'b0), - .addressstall_a (1'b0), - .addressstall_b (1'b0), - .byteena_a (1'b1), - .byteena_b (1'b1), - .clocken0 (1'b1), - .clocken1 (1'b1), - .clocken2 (1'b1), - .clocken3 (1'b1), - .eccstatus (), - .rden_a (1'b1), - .rden_b (1'b1)); - defparam - altsyncram_component.address_reg_b = "CLOCK1", - altsyncram_component.clock_enable_input_a = "BYPASS", - altsyncram_component.clock_enable_input_b = "BYPASS", - altsyncram_component.clock_enable_output_a = "BYPASS", - altsyncram_component.clock_enable_output_b = "BYPASS", - altsyncram_component.indata_reg_b = "CLOCK1", - altsyncram_component.init_file = "../target/pocket/build_id.mif", - altsyncram_component.intended_device_family = "Cyclone V", - altsyncram_component.lpm_type = "altsyncram", - altsyncram_component.numwords_a = 256, - altsyncram_component.numwords_b = 256, - altsyncram_component.operation_mode = "BIDIR_DUAL_PORT", - altsyncram_component.outdata_aclr_a = "NONE", - altsyncram_component.outdata_aclr_b = "NONE", - altsyncram_component.outdata_reg_a = "CLOCK0", - altsyncram_component.outdata_reg_b = "CLOCK1", - altsyncram_component.power_up_uninitialized = "FALSE", - altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ", - altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ", - altsyncram_component.widthad_a = 8, - altsyncram_component.widthad_b = 8, - altsyncram_component.width_a = 32, - altsyncram_component.width_b = 32, - altsyncram_component.width_byteena_a = 1, - altsyncram_component.width_byteena_b = 1, - altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK1"; - - -endmodule - -// ============================================================ -// CNX file retrieval info -// ============================================================ -// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" -// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" -// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" -// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" -// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" -// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" -// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" -// Retrieval info: PRIVATE: BlankMemory NUMERIC "0" -// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" -// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0" -// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" -// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" -// Retrieval info: PRIVATE: CLRdata NUMERIC "0" -// Retrieval info: PRIVATE: CLRq NUMERIC "0" -// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" -// Retrieval info: PRIVATE: CLRrren NUMERIC "0" -// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" -// Retrieval info: PRIVATE: CLRwren NUMERIC "0" -// Retrieval info: PRIVATE: Clock NUMERIC "5" -// Retrieval info: PRIVATE: Clock_A NUMERIC "0" -// Retrieval info: PRIVATE: Clock_B NUMERIC "0" -// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" -// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" -// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1" -// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" -// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" -// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V" -// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" -// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" -// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" -// Retrieval info: PRIVATE: MEMSIZE NUMERIC "8192" -// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" -// Retrieval info: PRIVATE: MIFfilename STRING "../target/pocket/build_id.mif" -// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3" -// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" -// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1" -// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" -// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" -// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" -// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" -// Retrieval info: PRIVATE: REGdata NUMERIC "1" -// Retrieval info: PRIVATE: REGq NUMERIC "1" -// Retrieval info: PRIVATE: REGrdaddress NUMERIC "0" -// Retrieval info: PRIVATE: REGrren NUMERIC "0" -// Retrieval info: PRIVATE: REGwraddress NUMERIC "1" -// Retrieval info: PRIVATE: REGwren NUMERIC "1" -// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" -// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" -// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" -// Retrieval info: PRIVATE: VarWidth NUMERIC "0" -// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "32" -// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "32" -// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "32" -// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "32" -// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" -// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "1" -// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" -// Retrieval info: PRIVATE: enable NUMERIC "0" -// Retrieval info: PRIVATE: rden NUMERIC "0" -// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all -// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1" -// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" -// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS" -// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" -// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS" -// Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK1" -// Retrieval info: CONSTANT: INIT_FILE STRING "../target/pocket/build_id.mif" -// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V" -// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" -// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256" -// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "256" -// Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT" -// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" -// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" -// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0" -// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK1" -// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" -// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ" -// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_B STRING "NEW_DATA_NO_NBE_READ" -// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8" -// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "8" -// Retrieval info: CONSTANT: WIDTH_A NUMERIC "32" -// Retrieval info: CONSTANT: WIDTH_B NUMERIC "32" -// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" -// Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1" -// Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK1" -// Retrieval info: USED_PORT: address_a 0 0 8 0 INPUT NODEFVAL "address_a[7..0]" -// Retrieval info: USED_PORT: address_b 0 0 8 0 INPUT NODEFVAL "address_b[7..0]" -// Retrieval info: USED_PORT: clock_a 0 0 0 0 INPUT VCC "clock_a" -// Retrieval info: USED_PORT: clock_b 0 0 0 0 INPUT NODEFVAL "clock_b" -// Retrieval info: USED_PORT: data_a 0 0 32 0 INPUT NODEFVAL "data_a[31..0]" -// Retrieval info: USED_PORT: data_b 0 0 32 0 INPUT NODEFVAL "data_b[31..0]" -// Retrieval info: USED_PORT: q_a 0 0 32 0 OUTPUT NODEFVAL "q_a[31..0]" -// Retrieval info: USED_PORT: q_b 0 0 32 0 OUTPUT NODEFVAL "q_b[31..0]" -// Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT GND "wren_a" -// Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT GND "wren_b" -// Retrieval info: CONNECT: @address_a 0 0 8 0 address_a 0 0 8 0 -// Retrieval info: CONNECT: @address_b 0 0 8 0 address_b 0 0 8 0 -// Retrieval info: CONNECT: @clock0 0 0 0 0 clock_a 0 0 0 0 -// Retrieval info: CONNECT: @clock1 0 0 0 0 clock_b 0 0 0 0 -// Retrieval info: CONNECT: @data_a 0 0 32 0 data_a 0 0 32 0 -// Retrieval info: CONNECT: @data_b 0 0 32 0 data_b 0 0 32 0 -// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0 -// Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0 -// Retrieval info: CONNECT: q_a 0 0 32 0 @q_a 0 0 32 0 -// Retrieval info: CONNECT: q_b 0 0 32 0 @q_b 0 0 32 0 -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable.v TRUE -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable.inc FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable.cmp FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable.bsf FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable_inst.v FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable_bb.v FALSE -// Retrieval info: LIB_FILE: altera_mf +// megafunction wizard: %RAM: 2-PORT% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: altsyncram + +// ============================================================ +// File Name: mf_datatable.v +// Megafunction Name(s): +// altsyncram +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 17.1.0 Build 590 10/25/2017 SJ Standard Edition +// ************************************************************ + + +//Copyright (C) 2017 Intel Corporation. All rights reserved. +//Your use of Intel 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 Intel Program License +//Subscription Agreement, the Intel Quartus Prime License Agreement, +//the Intel FPGA IP License Agreement, or other applicable license +//agreement, including, without limitation, that your use is for +//the sole purpose of programming logic devices manufactured by +//Intel and sold by Intel 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 mf_datatable ( + address_a, + address_b, + clock_a, + clock_b, + data_a, + data_b, + wren_a, + wren_b, + q_a, + q_b); + + input [7:0] address_a; + input [7:0] address_b; + input clock_a; + input clock_b; + input [31:0] data_a; + input [31:0] data_b; + input wren_a; + input wren_b; + output [31:0] q_a; + output [31:0] q_b; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_off +`endif + tri1 clock_a; + tri0 wren_a; + tri0 wren_b; +`ifndef ALTERA_RESERVED_QIS +// synopsys translate_on +`endif + + wire [31:0] sub_wire0; + wire [31:0] sub_wire1; + wire [31:0] q_a = sub_wire0[31:0]; + wire [31:0] q_b = sub_wire1[31:0]; + + altsyncram altsyncram_component ( + .address_a (address_a), + .address_b (address_b), + .clock0 (clock_a), + .clock1 (clock_b), + .data_a (data_a), + .data_b (data_b), + .wren_a (wren_a), + .wren_b (wren_b), + .q_a (sub_wire0), + .q_b (sub_wire1), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .eccstatus (), + .rden_a (1'b1), + .rden_b (1'b1)); + defparam + altsyncram_component.address_reg_b = "CLOCK1", + altsyncram_component.clock_enable_input_a = "BYPASS", + altsyncram_component.clock_enable_input_b = "BYPASS", + altsyncram_component.clock_enable_output_a = "BYPASS", + altsyncram_component.clock_enable_output_b = "BYPASS", + altsyncram_component.indata_reg_b = "CLOCK1", + altsyncram_component.init_file = "../target/pocket/build_id.mif", + altsyncram_component.intended_device_family = "Cyclone V", + altsyncram_component.lpm_type = "altsyncram", + altsyncram_component.numwords_a = 256, + altsyncram_component.numwords_b = 256, + altsyncram_component.operation_mode = "BIDIR_DUAL_PORT", + altsyncram_component.outdata_aclr_a = "NONE", + altsyncram_component.outdata_aclr_b = "NONE", + altsyncram_component.outdata_reg_a = "CLOCK0", + altsyncram_component.outdata_reg_b = "CLOCK1", + altsyncram_component.power_up_uninitialized = "FALSE", + altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ", + altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ", + altsyncram_component.widthad_a = 8, + altsyncram_component.widthad_b = 8, + altsyncram_component.width_a = 32, + altsyncram_component.width_b = 32, + altsyncram_component.width_byteena_a = 1, + altsyncram_component.width_byteena_b = 1, + altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK1"; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" +// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0" +// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" +// Retrieval info: PRIVATE: BlankMemory NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" +// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0" +// Retrieval info: PRIVATE: CLRdata NUMERIC "0" +// Retrieval info: PRIVATE: CLRq NUMERIC "0" +// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRrren NUMERIC "0" +// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0" +// Retrieval info: PRIVATE: CLRwren NUMERIC "0" +// Retrieval info: PRIVATE: Clock NUMERIC "5" +// Retrieval info: PRIVATE: Clock_A NUMERIC "0" +// Retrieval info: PRIVATE: Clock_B NUMERIC "0" +// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1" +// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" +// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V" +// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" +// Retrieval info: PRIVATE: JTAG_ID STRING "NONE" +// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" +// Retrieval info: PRIVATE: MEMSIZE NUMERIC "8192" +// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0" +// Retrieval info: PRIVATE: MIFfilename STRING "../target/pocket/build_id.mif" +// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3" +// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1" +// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" +// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3" +// Retrieval info: PRIVATE: REGdata NUMERIC "1" +// Retrieval info: PRIVATE: REGq NUMERIC "1" +// Retrieval info: PRIVATE: REGrdaddress NUMERIC "0" +// Retrieval info: PRIVATE: REGrren NUMERIC "0" +// Retrieval info: PRIVATE: REGwraddress NUMERIC "1" +// Retrieval info: PRIVATE: REGwren NUMERIC "1" +// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" +// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0" +// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1" +// Retrieval info: PRIVATE: VarWidth NUMERIC "0" +// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "32" +// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "32" +// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "32" +// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "32" +// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "1" +// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0" +// Retrieval info: PRIVATE: enable NUMERIC "0" +// Retrieval info: PRIVATE: rden NUMERIC "0" +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK1" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" +// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS" +// Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK1" +// Retrieval info: CONSTANT: INIT_FILE STRING "../target/pocket/build_id.mif" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" +// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256" +// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "256" +// Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT" +// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE" +// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0" +// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK1" +// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" +// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ" +// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_B STRING "NEW_DATA_NO_NBE_READ" +// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8" +// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "8" +// Retrieval info: CONSTANT: WIDTH_A NUMERIC "32" +// Retrieval info: CONSTANT: WIDTH_B NUMERIC "32" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" +// Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1" +// Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK1" +// Retrieval info: USED_PORT: address_a 0 0 8 0 INPUT NODEFVAL "address_a[7..0]" +// Retrieval info: USED_PORT: address_b 0 0 8 0 INPUT NODEFVAL "address_b[7..0]" +// Retrieval info: USED_PORT: clock_a 0 0 0 0 INPUT VCC "clock_a" +// Retrieval info: USED_PORT: clock_b 0 0 0 0 INPUT NODEFVAL "clock_b" +// Retrieval info: USED_PORT: data_a 0 0 32 0 INPUT NODEFVAL "data_a[31..0]" +// Retrieval info: USED_PORT: data_b 0 0 32 0 INPUT NODEFVAL "data_b[31..0]" +// Retrieval info: USED_PORT: q_a 0 0 32 0 OUTPUT NODEFVAL "q_a[31..0]" +// Retrieval info: USED_PORT: q_b 0 0 32 0 OUTPUT NODEFVAL "q_b[31..0]" +// Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT GND "wren_a" +// Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT GND "wren_b" +// Retrieval info: CONNECT: @address_a 0 0 8 0 address_a 0 0 8 0 +// Retrieval info: CONNECT: @address_b 0 0 8 0 address_b 0 0 8 0 +// Retrieval info: CONNECT: @clock0 0 0 0 0 clock_a 0 0 0 0 +// Retrieval info: CONNECT: @clock1 0 0 0 0 clock_b 0 0 0 0 +// Retrieval info: CONNECT: @data_a 0 0 32 0 data_a 0 0 32 0 +// Retrieval info: CONNECT: @data_b 0 0 32 0 data_b 0 0 32 0 +// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0 +// Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0 +// Retrieval info: CONNECT: q_a 0 0 32 0 @q_a 0 0 32 0 +// Retrieval info: CONNECT: q_b 0 0 32 0 @q_b 0 0 32 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable.v TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable.inc FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable.cmp FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable.bsf FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable_inst.v FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_datatable_bb.v FALSE +// Retrieval info: LIB_FILE: altera_mf diff --git a/platform/pocket/megafunctions/mf_ddio_bidir_12.qip b/platform/pocket/megafunctions/mf_ddio_bidir_12.qip index 40c4266..18ae54d 100644 --- a/platform/pocket/megafunctions/mf_ddio_bidir_12.qip +++ b/platform/pocket/megafunctions/mf_ddio_bidir_12.qip @@ -1,5 +1,5 @@ -set_global_assignment -name IP_TOOL_NAME "ALTDDIO_BIDIR" -set_global_assignment -name IP_TOOL_VERSION "18.1" -set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "mf_ddio_bidir_12.v"] -set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "mf_ddio_bidir_12.ppf"] +set_global_assignment -name IP_TOOL_NAME "ALTDDIO_BIDIR" +set_global_assignment -name IP_TOOL_VERSION "18.1" +set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "mf_ddio_bidir_12.v"] +set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "mf_ddio_bidir_12.ppf"] diff --git a/platform/pocket/megafunctions/mf_ddio_bidir_12.v b/platform/pocket/megafunctions/mf_ddio_bidir_12.v index 6bac1ab..6851f86 100644 --- a/platform/pocket/megafunctions/mf_ddio_bidir_12.v +++ b/platform/pocket/megafunctions/mf_ddio_bidir_12.v @@ -1,134 +1,134 @@ -// megafunction wizard: %ALTDDIO_BIDIR% -// GENERATION: STANDARD -// VERSION: WM1.0 -// MODULE: ALTDDIO_BIDIR - -// ============================================================ -// File Name: mf_ddio_bidir_12.v -// Megafunction Name(s): -// ALTDDIO_BIDIR -// -// Simulation Library Files(s): -// altera_mf -// ============================================================ -// ************************************************************ -// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! -// -// 18.1.1 Build 646 04/11/2019 SJ Lite Edition -// ************************************************************ - - -//Copyright (C) 2019 Intel Corporation. All rights reserved. -//Your use of Intel Corporation's design tools, logic functions -//and other software and tools, and any 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 Intel Program License -//Subscription Agreement, the Intel Quartus Prime License Agreement, -//the Intel FPGA IP License Agreement, or other applicable license -//agreement, including, without limitation, that your use is for -//the sole purpose of programming logic devices manufactured by -//Intel and sold by Intel or its authorized distributors. Please -//refer to the applicable agreement for further details, at -//https://fpgasoftware.intel.com/eula. - - -// synopsys translate_off -`timescale 1 ps / 1 ps -// synopsys translate_on -module mf_ddio_bidir_12 ( - datain_h, - datain_l, - inclock, - oe, - outclock, - dataout_h, - dataout_l, - padio); - - input [11:0] datain_h; - input [11:0] datain_l; - input inclock; - input oe; - input outclock; - output [11:0] dataout_h; - output [11:0] dataout_l; - inout [11:0] padio; - - wire [11:0] sub_wire0; - wire [11:0] sub_wire1; - wire [11:0] dataout_h = sub_wire0[11:0]; - wire [11:0] dataout_l = sub_wire1[11:0]; - - altddio_bidir ALTDDIO_BIDIR_component ( - .datain_h (datain_h), - .datain_l (datain_l), - .inclock (inclock), - .oe (oe), - .outclock (outclock), - .padio (padio), - .dataout_h (sub_wire0), - .dataout_l (sub_wire1), - .aclr (1'b0), - .aset (1'b0), - .combout (), - .dqsundelayedout (), - .inclocken (1'b1), - .oe_out (), - .outclocken (1'b1), - .sclr (1'b0), - .sset (1'b0)); - defparam - ALTDDIO_BIDIR_component.extend_oe_disable = "OFF", - ALTDDIO_BIDIR_component.implement_input_in_lcell = "OFF", - ALTDDIO_BIDIR_component.intended_device_family = "Cyclone V", - ALTDDIO_BIDIR_component.invert_output = "OFF", - ALTDDIO_BIDIR_component.lpm_hint = "UNUSED", - ALTDDIO_BIDIR_component.lpm_type = "altddio_bidir", - ALTDDIO_BIDIR_component.oe_reg = "UNREGISTERED", - ALTDDIO_BIDIR_component.power_up_high = "OFF", - ALTDDIO_BIDIR_component.width = 12; - - -endmodule - -// ============================================================ -// CNX file retrieval info -// ============================================================ -// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all -// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V" -// Retrieval info: CONSTANT: EXTEND_OE_DISABLE STRING "OFF" -// Retrieval info: CONSTANT: IMPLEMENT_INPUT_IN_LCELL STRING "OFF" -// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V" -// Retrieval info: CONSTANT: INVERT_OUTPUT STRING "OFF" -// Retrieval info: CONSTANT: LPM_HINT STRING "UNUSED" -// Retrieval info: CONSTANT: LPM_TYPE STRING "altddio_bidir" -// Retrieval info: CONSTANT: OE_REG STRING "UNREGISTERED" -// Retrieval info: CONSTANT: POWER_UP_HIGH STRING "OFF" -// Retrieval info: CONSTANT: WIDTH NUMERIC "12" -// Retrieval info: USED_PORT: datain_h 0 0 12 0 INPUT NODEFVAL "datain_h[11..0]" -// Retrieval info: CONNECT: @datain_h 0 0 12 0 datain_h 0 0 12 0 -// Retrieval info: USED_PORT: datain_l 0 0 12 0 INPUT NODEFVAL "datain_l[11..0]" -// Retrieval info: CONNECT: @datain_l 0 0 12 0 datain_l 0 0 12 0 -// Retrieval info: USED_PORT: dataout_h 0 0 12 0 OUTPUT NODEFVAL "dataout_h[11..0]" -// Retrieval info: CONNECT: dataout_h 0 0 12 0 @dataout_h 0 0 12 0 -// Retrieval info: USED_PORT: dataout_l 0 0 12 0 OUTPUT NODEFVAL "dataout_l[11..0]" -// Retrieval info: CONNECT: dataout_l 0 0 12 0 @dataout_l 0 0 12 0 -// Retrieval info: USED_PORT: inclock 0 0 0 0 INPUT_CLK_EXT NODEFVAL "inclock" -// Retrieval info: CONNECT: @inclock 0 0 0 0 inclock 0 0 0 0 -// Retrieval info: USED_PORT: oe 0 0 0 0 INPUT NODEFVAL "oe" -// Retrieval info: CONNECT: @oe 0 0 0 0 oe 0 0 0 0 -// Retrieval info: USED_PORT: outclock 0 0 0 0 INPUT_CLK_EXT NODEFVAL "outclock" -// Retrieval info: CONNECT: @outclock 0 0 0 0 outclock 0 0 0 0 -// Retrieval info: USED_PORT: padio 0 0 12 0 BIDIR NODEFVAL "padio[11..0]" -// Retrieval info: CONNECT: padio 0 0 12 0 @padio 0 0 12 0 -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.v TRUE FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.qip TRUE FALSE -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.bsf FALSE TRUE -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12_inst.v FALSE TRUE -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12_bb.v FALSE TRUE -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.inc FALSE TRUE -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.cmp FALSE TRUE -// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.ppf TRUE FALSE -// Retrieval info: LIB_FILE: altera_mf +// megafunction wizard: %ALTDDIO_BIDIR% +// GENERATION: STANDARD +// VERSION: WM1.0 +// MODULE: ALTDDIO_BIDIR + +// ============================================================ +// File Name: mf_ddio_bidir_12.v +// Megafunction Name(s): +// ALTDDIO_BIDIR +// +// Simulation Library Files(s): +// altera_mf +// ============================================================ +// ************************************************************ +// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! +// +// 18.1.1 Build 646 04/11/2019 SJ Lite Edition +// ************************************************************ + + +//Copyright (C) 2019 Intel Corporation. All rights reserved. +//Your use of Intel Corporation's design tools, logic functions +//and other software and tools, and any 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 Intel Program License +//Subscription Agreement, the Intel Quartus Prime License Agreement, +//the Intel FPGA IP License Agreement, or other applicable license +//agreement, including, without limitation, that your use is for +//the sole purpose of programming logic devices manufactured by +//Intel and sold by Intel or its authorized distributors. Please +//refer to the applicable agreement for further details, at +//https://fpgasoftware.intel.com/eula. + + +// synopsys translate_off +`timescale 1 ps / 1 ps +// synopsys translate_on +module mf_ddio_bidir_12 ( + datain_h, + datain_l, + inclock, + oe, + outclock, + dataout_h, + dataout_l, + padio); + + input [11:0] datain_h; + input [11:0] datain_l; + input inclock; + input oe; + input outclock; + output [11:0] dataout_h; + output [11:0] dataout_l; + inout [11:0] padio; + + wire [11:0] sub_wire0; + wire [11:0] sub_wire1; + wire [11:0] dataout_h = sub_wire0[11:0]; + wire [11:0] dataout_l = sub_wire1[11:0]; + + altddio_bidir ALTDDIO_BIDIR_component ( + .datain_h (datain_h), + .datain_l (datain_l), + .inclock (inclock), + .oe (oe), + .outclock (outclock), + .padio (padio), + .dataout_h (sub_wire0), + .dataout_l (sub_wire1), + .aclr (1'b0), + .aset (1'b0), + .combout (), + .dqsundelayedout (), + .inclocken (1'b1), + .oe_out (), + .outclocken (1'b1), + .sclr (1'b0), + .sset (1'b0)); + defparam + ALTDDIO_BIDIR_component.extend_oe_disable = "OFF", + ALTDDIO_BIDIR_component.implement_input_in_lcell = "OFF", + ALTDDIO_BIDIR_component.intended_device_family = "Cyclone V", + ALTDDIO_BIDIR_component.invert_output = "OFF", + ALTDDIO_BIDIR_component.lpm_hint = "UNUSED", + ALTDDIO_BIDIR_component.lpm_type = "altddio_bidir", + ALTDDIO_BIDIR_component.oe_reg = "UNREGISTERED", + ALTDDIO_BIDIR_component.power_up_high = "OFF", + ALTDDIO_BIDIR_component.width = 12; + + +endmodule + +// ============================================================ +// CNX file retrieval info +// ============================================================ +// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all +// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V" +// Retrieval info: CONSTANT: EXTEND_OE_DISABLE STRING "OFF" +// Retrieval info: CONSTANT: IMPLEMENT_INPUT_IN_LCELL STRING "OFF" +// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V" +// Retrieval info: CONSTANT: INVERT_OUTPUT STRING "OFF" +// Retrieval info: CONSTANT: LPM_HINT STRING "UNUSED" +// Retrieval info: CONSTANT: LPM_TYPE STRING "altddio_bidir" +// Retrieval info: CONSTANT: OE_REG STRING "UNREGISTERED" +// Retrieval info: CONSTANT: POWER_UP_HIGH STRING "OFF" +// Retrieval info: CONSTANT: WIDTH NUMERIC "12" +// Retrieval info: USED_PORT: datain_h 0 0 12 0 INPUT NODEFVAL "datain_h[11..0]" +// Retrieval info: CONNECT: @datain_h 0 0 12 0 datain_h 0 0 12 0 +// Retrieval info: USED_PORT: datain_l 0 0 12 0 INPUT NODEFVAL "datain_l[11..0]" +// Retrieval info: CONNECT: @datain_l 0 0 12 0 datain_l 0 0 12 0 +// Retrieval info: USED_PORT: dataout_h 0 0 12 0 OUTPUT NODEFVAL "dataout_h[11..0]" +// Retrieval info: CONNECT: dataout_h 0 0 12 0 @dataout_h 0 0 12 0 +// Retrieval info: USED_PORT: dataout_l 0 0 12 0 OUTPUT NODEFVAL "dataout_l[11..0]" +// Retrieval info: CONNECT: dataout_l 0 0 12 0 @dataout_l 0 0 12 0 +// Retrieval info: USED_PORT: inclock 0 0 0 0 INPUT_CLK_EXT NODEFVAL "inclock" +// Retrieval info: CONNECT: @inclock 0 0 0 0 inclock 0 0 0 0 +// Retrieval info: USED_PORT: oe 0 0 0 0 INPUT NODEFVAL "oe" +// Retrieval info: CONNECT: @oe 0 0 0 0 oe 0 0 0 0 +// Retrieval info: USED_PORT: outclock 0 0 0 0 INPUT_CLK_EXT NODEFVAL "outclock" +// Retrieval info: CONNECT: @outclock 0 0 0 0 outclock 0 0 0 0 +// Retrieval info: USED_PORT: padio 0 0 12 0 BIDIR NODEFVAL "padio[11..0]" +// Retrieval info: CONNECT: padio 0 0 12 0 @padio 0 0 12 0 +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.v TRUE FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.qip TRUE FALSE +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.bsf FALSE TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12_inst.v FALSE TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12_bb.v FALSE TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.inc FALSE TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.cmp FALSE TRUE +// Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.ppf TRUE FALSE +// Retrieval info: LIB_FILE: altera_mf diff --git a/platform/pocket/memory/dpram_hs.sv b/platform/pocket/memory/dpram_hs.sv index 32bf74d..1832abe 100644 --- a/platform/pocket/memory/dpram_hs.sv +++ b/platform/pocket/memory/dpram_hs.sv @@ -1,80 +1,80 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Generic Simple Dual-Port RAM (Single Clock) -// -// Copyright (c) 2022, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module dpram_hs - #( - parameter aWidth = 10, //! Address Port Width - parameter dWidth = 8, //! Data Port Width - // Used as attributes, not values - parameter rStyle = "no_rw_check" - ) ( - input logic clk, //! Clock - // Port A - input logic we_a, //! Write Enable - input logic [aWidth-1:0] addr_a, //! Address - input logic [dWidth-1:0] d_a, //! Input Data Bus - output logic [dWidth-1:0] q_a = 0, //! Output Data Bus - // Port B - input logic we_b, //! Write Enables - input logic [aWidth-1:0] addr_b, //! Address - input logic [dWidth-1:0] d_b, //! Input Data Bus - output logic [dWidth-1:0] q_b = 0 //! Output Data Bus - ); - - // Set the ram style to control implementation. - (* ramstyle = rStyle *) - logic [dWidth-1:0] ram[(1 << aWidth)-1:0]; //! Register to Hold Data - - // Read/Write from/to Memory on Port A - always_ff @(posedge clk) begin : portA - if(we_a) begin - ram[addr_a] <= d_a; - q_a <= d_a; - end - else begin - q_a <= ram[addr_a]; - end - end - - // Read/Write from/to Memory on Port B - always_ff @(posedge clk) begin : portB - if(we_b) begin - ram[addr_b] <= d_b; - q_b <= d_b; - end - else begin - q_b <= ram[addr_b]; - end - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Generic Simple Dual-Port RAM (Single Clock) +// +// Copyright (c) 2022, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module dpram_hs + #( + parameter aWidth = 10, //! Address Port Width + parameter dWidth = 8, //! Data Port Width + // Used as attributes, not values + parameter rStyle = "no_rw_check" + ) ( + input logic clk, //! Clock + // Port A + input logic we_a, //! Write Enable + input logic [aWidth-1:0] addr_a, //! Address + input logic [dWidth-1:0] d_a, //! Input Data Bus + output logic [dWidth-1:0] q_a = 0, //! Output Data Bus + // Port B + input logic we_b, //! Write Enables + input logic [aWidth-1:0] addr_b, //! Address + input logic [dWidth-1:0] d_b, //! Input Data Bus + output logic [dWidth-1:0] q_b = 0 //! Output Data Bus + ); + + // Set the ram style to control implementation. + (* ramstyle = rStyle *) + logic [dWidth-1:0] ram[(1 << aWidth)-1:0]; //! Register to Hold Data + + // Read/Write from/to Memory on Port A + always_ff @(posedge clk) begin : portA + if(we_a) begin + ram[addr_a] <= d_a; + q_a <= d_a; + end + else begin + q_a <= ram[addr_a]; + end + end + + // Read/Write from/to Memory on Port B + always_ff @(posedge clk) begin : portB + if(we_b) begin + ram[addr_b] <= d_b; + q_b <= d_b; + end + else begin + q_b <= ram[addr_b]; + end + end + +endmodule diff --git a/platform/pocket/memory/spram_hs.sv b/platform/pocket/memory/spram_hs.sv index df37299..f23f10c 100644 --- a/platform/pocket/memory/spram_hs.sv +++ b/platform/pocket/memory/spram_hs.sv @@ -1,63 +1,63 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Generic Simple Single-Port RAM (Single Clock) -// -// Copyright (c) 2022, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module spram_hs - #( - parameter aWidth = 10, //! Address Port Width - parameter dWidth = 8, //! Data Port Width - // Used as attributes, not values - parameter rStyle = "no_rw_check" - ) ( - input logic clk, //! Clock - input logic we, //! Write Enable - input logic [aWidth-1:0] addr, //! Address - input logic [dWidth-1:0] d, //! Input Data Bus - output logic [dWidth-1:0] q = 0 //! Output Data Bus - ); - - // Set the ram style to control implementation. - (* ramstyle = rStyle *) - logic [dWidth-1:0] ram[(1 << aWidth)-1:0]; //! Register to Hold Data - - // Read/Write from/to Memory - always_ff @(posedge clk) begin : singlePort - if(we) begin - ram[addr] <= d; - q <= d; - end - else begin - q <= ram[addr]; - end - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Generic Simple Single-Port RAM (Single Clock) +// +// Copyright (c) 2022, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module spram_hs + #( + parameter aWidth = 10, //! Address Port Width + parameter dWidth = 8, //! Data Port Width + // Used as attributes, not values + parameter rStyle = "no_rw_check" + ) ( + input logic clk, //! Clock + input logic we, //! Write Enable + input logic [aWidth-1:0] addr, //! Address + input logic [dWidth-1:0] d, //! Input Data Bus + output logic [dWidth-1:0] q = 0 //! Output Data Bus + ); + + // Set the ram style to control implementation. + (* ramstyle = rStyle *) + logic [dWidth-1:0] ram[(1 << aWidth)-1:0]; //! Register to Hold Data + + // Read/Write from/to Memory + always_ff @(posedge clk) begin : singlePort + if(we) begin + ram[addr] <= d; + q <= d; + end + else begin + q <= ram[addr]; + end + end + +endmodule diff --git a/platform/pocket/memory/sram.sv b/platform/pocket/memory/sram.sv index a035f5c..ac52f28 100644 --- a/platform/pocket/memory/sram.sv +++ b/platform/pocket/memory/sram.sv @@ -1,65 +1,65 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Async SRAM Controller -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module sram_async - #( - parameter AW = 17, //! Address Width - parameter DW = 16 //! Data Width - ) ( - // User Interface - input logic [AW-1:0] addr, //! Address - input logic [DW-1:0] din, //! Data In - output logic [DW-1:0] dout, //! Data Out - input logic we_n, //! Write Enable - input logic oe_n, //! Output Enable - input logic [1:0] be_n, //! Byte Enable - [1] Upper Byte Mask | [0] Lower Byte Mask - // SRAM Interface - output logic [AW-1:0] sram_addr, //! Address - inout logic [DW-1:0] sram_dq, //! Data In/Out - output logic sram_we_n, //! Write Enable - output logic sram_oe_n, //! Output Enable - output logic sram_ub_n, //! Upper Byte Mask - output logic sram_lb_n //! Lower Byte Mask - ); - - assign sram_addr = addr; - assign sram_dq = sram_we_n ? {DW{1'bZ}} : din; - assign dout = sram_dq; - assign sram_we_n = we_n; - assign sram_oe_n = oe_n; - assign sram_ub_n = be_n[1]; - assign sram_lb_n = be_n[0]; - -endmodule - - +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Async SRAM Controller +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module sram_async + #( + parameter AW = 17, //! Address Width + parameter DW = 16 //! Data Width + ) ( + // User Interface + input logic [AW-1:0] addr, //! Address + input logic [DW-1:0] din, //! Data In + output logic [DW-1:0] dout, //! Data Out + input logic we_n, //! Write Enable + input logic oe_n, //! Output Enable + input logic [1:0] be_n, //! Byte Enable - [1] Upper Byte Mask | [0] Lower Byte Mask + // SRAM Interface + output logic [AW-1:0] sram_addr, //! Address + inout logic [DW-1:0] sram_dq, //! Data In/Out + output logic sram_we_n, //! Write Enable + output logic sram_oe_n, //! Output Enable + output logic sram_ub_n, //! Upper Byte Mask + output logic sram_lb_n //! Lower Byte Mask + ); + + assign sram_addr = addr; + assign sram_dq = sram_we_n ? {DW{1'bZ}} : din; + assign dout = sram_dq; + assign sram_we_n = we_n; + assign sram_oe_n = oe_n; + assign sram_ub_n = be_n[1]; + assign sram_lb_n = be_n[0]; + +endmodule + + diff --git a/platform/pocket/peripherals/core_bridge_cmd.sv b/platform/pocket/peripherals/core_bridge_cmd.sv index 291e8ab..4886ae3 100644 --- a/platform/pocket/peripherals/core_bridge_cmd.sv +++ b/platform/pocket/peripherals/core_bridge_cmd.sv @@ -1,607 +1,607 @@ -// Software License Agreement - -// The software supplied herewith by Analogue Enterprises Limited (the "Company”), -// the Analogue Pocket Framework (“APF”), is provided and licensed to you, the -// Company's customer, solely for use in designing, testing and creating -// applications for use with Company's Products or Services. The software is -// owned by the Company and/or its licensors, and is protected under applicable -// laws, including, but not limited to, U.S. copyright law. All rights are -// reserved. By using the APF code you are agreeing to the terms of the End User -// License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula] -// and incorporated herein by reference. To the extent any use of the APF requires -// application of the MIT License or the GNU General Public License and terms of -// this APF Software License Agreement and EULA are inconsistent with such license, -// the applicable terms of the MIT License or the GNU General Public License, as -// applicable, will prevail. - -// THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED -// WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO, -// ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR -// NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM -// DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE -// MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED, -// THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND -// DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING -// THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR -// ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY -// INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES, -// INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR -// INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY -// OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY -// CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION, -// WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU -// TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH -// YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE -// FULLEST EXTENT PERMITTED BY APPLICABLE LAW. -// -// bridge host/target command handler -// 2022 Analogue -// - -// mapped to 0xF8xxxxxx on bridge -// the spec is loose enough to allow implementation with either -// block rams and a soft CPU, or simply hard logic with some case statements. -// -// the implementation spec is documented, and depending on your application you -// may want to completely replace this module. this is only one of many -// possible ways to accomplish the host/target command system and data table. -// -// this module should always be clocked by a direct clock input and never a PLL, -// because it should report PLL lock status -// - -`default_nettype none -`timescale 1ns/1ps - -module core_bridge_cmd - ( - input wire clk, - output reg reset_n, - - input wire bridge_endian_little, - input wire [31:0] bridge_addr, - input wire bridge_rd, - output reg [31:0] bridge_rd_data, - input wire bridge_wr, - input wire [31:0] bridge_wr_data, - - // all these signals should be synchronous to clk - // add synchronizers if these need to be used in other clock domains - input wire status_boot_done, // assert when PLLs lock and logic is ready - input wire status_setup_done, // assert when core is happy with what's been loaded into it - input wire status_running, // assert when pocket's taken core out of reset and is running - - output reg dataslot_requestread, - output reg [15:0] dataslot_requestread_id, - input wire dataslot_requestread_ack, - input wire dataslot_requestread_ok, - - output reg dataslot_requestwrite, - output reg [15:0] dataslot_requestwrite_id, - output reg [31:0] dataslot_requestwrite_size, - input wire dataslot_requestwrite_ack, - input wire dataslot_requestwrite_ok, - - output reg dataslot_update, - output reg [15:0] dataslot_update_id, - output reg [31:0] dataslot_update_size, - - output reg dataslot_allcomplete, - - output reg [31:0] rtc_epoch_seconds, - output reg [31:0] rtc_date_bcd, - output reg [31:0] rtc_time_bcd, - output reg rtc_valid, - - input wire savestate_supported, - input wire [31:0] savestate_addr, - input wire [31:0] savestate_size, - input wire [31:0] savestate_maxloadsize, - - output reg osnotify_inmenu, - output reg osnotify_docked, - - output reg savestate_start, // core should detect rising edge on this, - input wire savestate_start_ack, // and then assert ack for at least 1 cycle - input wire savestate_start_busy, // assert constantly while in progress after ack - input wire savestate_start_ok, // assert continuously when done, and clear when new process is started - input wire savestate_start_err, // assert continuously on error, and clear when new process is started - - output reg savestate_load, - input wire savestate_load_ack, - input wire savestate_load_busy, - input wire savestate_load_ok, - input wire savestate_load_err, - - input wire target_dataslot_read, // rising edge triggered - input wire target_dataslot_write, - input wire target_dataslot_getfile, - input wire target_dataslot_openfile, - - output reg target_dataslot_ack, // asserted upon command start until completion - output reg target_dataslot_done, // asserted upon command finish until next command is issued - output reg [2:0] target_dataslot_err, // contains result of command execution. zero is OK - - input wire [15:0] target_dataslot_id, // parameters for each of the read/reload/write commands - input wire [31:0] target_dataslot_slotoffset, - input wire [31:0] target_dataslot_bridgeaddr, - input wire [31:0] target_dataslot_length, - - input wire [31:0] target_buffer_param_struct, // bus address of the memory region APF will fetch additional parameter struct from - input wire [31:0] target_buffer_resp_struct, // bus address of the memory region APF will write its response struct to - // this should be mapped by the developer, the buffer is not implemented in this file - - input wire [9:0] datatable_addr, - input wire datatable_wren, - input wire [31:0] datatable_data, - output wire [31:0] datatable_q - ); - - // handle endianness - reg [31:0] bridge_wr_data_in; - reg [31:0] bridge_rd_data_out; - - wire endian_little_s; - synch_3 s01(bridge_endian_little, endian_little_s, clk); - - always @(*) begin - bridge_rd_data <= endian_little_s ? { - bridge_rd_data_out[7:0], - bridge_rd_data_out[15:8], - bridge_rd_data_out[23:16], - bridge_rd_data_out[31:24] - } : bridge_rd_data_out; - - bridge_wr_data_in <= endian_little_s ? { - bridge_wr_data[7:0], - bridge_wr_data[15:8], - bridge_wr_data[23:16], - bridge_wr_data[31:24] - } : bridge_wr_data; - end - - // minimalistic approach here - - // keep the commonly used registers in logic, but data table in BRAM. - // implementation could be changed quite a bit for a more advanced use case - - // host - reg [31:0] host_0; - reg [31:0] host_4 = 'h20; // host cmd parameter data at 0x20 - reg [31:0] host_8 = 'h40; // host cmd response data at 0x40 - - reg [31:0] host_20; // parameter data - reg [31:0] host_24; - reg [31:0] host_28; - reg [31:0] host_2C; - - reg [31:0] host_40; // response data - reg [31:0] host_44; - reg [31:0] host_48; - reg [31:0] host_4C; - - reg host_cmd_start; - reg [15:0] host_cmd_startval; - reg [15:0] host_cmd; - reg [15:0] host_resultcode; - - localparam [3:0] ST_IDLE = 'd0; - localparam [3:0] ST_PARSE = 'd1; - localparam [3:0] ST_WORK = 'd2; - localparam [3:0] ST_DONE_OK = 'd13; - localparam [3:0] ST_DONE_CODE = 'd14; - localparam [3:0] ST_DONE_ERR = 'd15; - reg [3:0] hstate; - - // target - reg [31:0] target_0; - reg [31:0] target_4 = 'h20; - reg [31:0] target_8 = 'h40; - - reg [31:0] target_20; // parameter data - reg [31:0] target_24; - reg [31:0] target_28; - reg [31:0] target_2C; - - reg [31:0] target_40; // response data - reg [31:0] target_44; - reg [31:0] target_48; - reg [31:0] target_4C; - - localparam [3:0] TARG_ST_IDLE = 'd0; - localparam [3:0] TARG_ST_READYTORUN = 'd1; - localparam [3:0] TARG_ST_DATASLOTOP = 'd2; - localparam [3:0] TARG_ST_WAITRESULT_RTR = 'd14; - localparam [3:0] TARG_ST_WAITRESULT_DSO = 'd15; - reg [3:0] tstate; - - reg status_setup_done_1, status_setup_done_queue; - reg target_dataslot_read_1, target_dataslot_read_queue; - reg target_dataslot_write_1, target_dataslot_write_queue; - reg target_dataslot_getfile_1, target_dataslot_getfile_queue; - reg target_dataslot_openfile_1, target_dataslot_openfile_queue; - - initial begin - reset_n <= 0; - dataslot_requestread <= 0; - dataslot_requestwrite <= 0; - dataslot_update <= 0; - dataslot_allcomplete <= 0; - rtc_valid <= 0; - savestate_start <= 0; - savestate_load <= 0; - osnotify_inmenu <= 0; - osnotify_docked <= 0; - - status_setup_done_queue <= 0; - target_dataslot_read_queue <= 0; - target_dataslot_write_queue <= 0; - target_dataslot_getfile_queue <= 0; - target_dataslot_openfile_queue <= 0; - target_dataslot_ack <= 0; - target_dataslot_done <= 0; - target_dataslot_err <= 0; - end - - always @(posedge clk) begin - // detect a rising edge on the input signal - // and flag a queue that will be cleared later - status_setup_done_1 <= status_setup_done; - target_dataslot_read_1 <= target_dataslot_read; - target_dataslot_write_1 <= target_dataslot_write; - target_dataslot_getfile_1 <= target_dataslot_getfile; - target_dataslot_openfile_1 <= target_dataslot_openfile; - - if(status_setup_done & ~status_setup_done_1) begin - status_setup_done_queue <= 1; - end - if(target_dataslot_read & ~target_dataslot_read_1) begin - target_dataslot_read_queue <= 1; - end - if(target_dataslot_write & ~target_dataslot_write_1) begin - target_dataslot_write_queue <= 1; - end - if(target_dataslot_getfile & ~target_dataslot_getfile_1) begin - target_dataslot_getfile_queue <= 1; - end - if(target_dataslot_openfile & ~target_dataslot_openfile_1) begin - target_dataslot_openfile_queue <= 1; - end - - b_datatable_wren <= 0; - b_datatable_addr <= bridge_addr >> 2; - - if(bridge_wr) begin - casex(bridge_addr) - 32'hF8xx00xx: begin - case(bridge_addr[7:0]) - 8'h0: begin - host_0 <= bridge_wr_data_in; // command/status - // check for command - if(bridge_wr_data_in[31:16] == 16'h434D) begin - // host wants us to do a command - host_cmd_startval <= bridge_wr_data_in[15:0]; - host_cmd_start <= 1; - end - end - 8'h20: host_20 <= bridge_wr_data_in; // parameter data regs - 8'h24: host_24 <= bridge_wr_data_in; - 8'h28: host_28 <= bridge_wr_data_in; - 8'h2C: host_2C <= bridge_wr_data_in; - endcase - end - 32'hF8xx10xx: begin - case(bridge_addr[7:0]) - 8'h0: target_0 <= bridge_wr_data_in; // command/status - 8'h4: target_4 <= bridge_wr_data_in; // parameter data pointer - 8'h8: target_8 <= bridge_wr_data_in; // response data pointer - 8'h40: target_40 <= bridge_wr_data_in; // response data regs - 8'h44: target_44 <= bridge_wr_data_in; - 8'h48: target_48 <= bridge_wr_data_in; - 8'h4C: target_4C <= bridge_wr_data_in; - endcase - end - 32'hF8xx2xxx: begin - b_datatable_wren <= 1; - end - endcase - end - if(bridge_rd) begin - casex(bridge_addr) - 32'hF8xx00xx: begin - case(bridge_addr[7:0]) - 8'h0: bridge_rd_data_out <= host_0; // command/status - 8'h4: bridge_rd_data_out <= host_4; // parameter data pointer - 8'h8: bridge_rd_data_out <= host_8; // response data pointer - 8'h40: bridge_rd_data_out <= host_40; // response data regs - 8'h44: bridge_rd_data_out <= host_44; - 8'h48: bridge_rd_data_out <= host_48; - 8'h4C: bridge_rd_data_out <= host_4C; - endcase - end - 32'hF8xx10xx: begin - case(bridge_addr[7:0]) - 8'h0: bridge_rd_data_out <= target_0; - 8'h4: bridge_rd_data_out <= target_4; - 8'h8: bridge_rd_data_out <= target_8; - 8'h20: bridge_rd_data_out <= target_20; // parameter data regs - 8'h24: bridge_rd_data_out <= target_24; - 8'h28: bridge_rd_data_out <= target_28; - 8'h2C: bridge_rd_data_out <= target_2C; - endcase - end - 32'hF8xx2xxx: begin - bridge_rd_data_out <= b_datatable_q; - end - endcase - end - - // host > target command executer - case(hstate) - ST_IDLE: begin - dataslot_requestread <= 0; - dataslot_requestwrite <= 0; - dataslot_update <= 0; - savestate_start <= 0; - savestate_load <= 0; - - // there is no queueing. pocket will always make sure any outstanding host - // commands are finished before starting another - if(host_cmd_start) begin - host_cmd_start <= 0; - // save the command in case it gets clobbered later - host_cmd <= host_cmd_startval; - hstate <= ST_PARSE; - end - end - ST_PARSE: begin - // overwrite command semaphore with busy flag - host_0 <= {16'h4255, host_cmd}; - - case(host_cmd) - 16'h0000: begin - // Request Status - host_resultcode <= 1; // default: booting - if(status_boot_done) begin - host_resultcode <= 2; // setup - if(status_setup_done) begin - host_resultcode <= 3; // idle - end - else if(status_running) begin - host_resultcode <= 4; // running - end - end - hstate <= ST_DONE_CODE; - end - 16'h0010: begin - // Reset Enter - reset_n <= 0; - hstate <= ST_DONE_OK; - end - 16'h0011: begin - // Reset Exit - reset_n <= 1; - hstate <= ST_DONE_OK; - end - 16'h0080: begin - // Data slot request read - dataslot_allcomplete <= 0; - dataslot_requestread <= 1; - dataslot_requestread_id <= host_20[15:0]; - if(dataslot_requestread_ack) begin - host_resultcode <= 0; - if(!dataslot_requestread_ok) host_resultcode <= 2; - hstate <= ST_DONE_CODE; - end - end - 16'h0082: begin - // Data slot request write - dataslot_allcomplete <= 0; - dataslot_requestwrite <= 1; - dataslot_requestwrite_id <= host_20[15:0]; - dataslot_requestwrite_size <= host_24; - if(dataslot_requestwrite_ack) begin - host_resultcode <= 0; - if(!dataslot_requestwrite_ok) host_resultcode <= 2; - hstate <= ST_DONE_CODE; - end - end - 16'h008A: begin - // Data slot update (sent on deferload marked slots only) - dataslot_update <= 1; - dataslot_update_id <= host_20[15:0]; - dataslot_update_size <= host_24; - hstate <= ST_DONE_OK; - end - 16'h008F: begin - // Data slot access all complete - dataslot_allcomplete <= 1; - hstate <= ST_DONE_OK; - end - 16'h0090: begin - // Real-time Clock Data - // user logic should detect rising edge, it is not continuously updated - rtc_valid <= 1; - rtc_epoch_seconds <= host_20; - rtc_date_bcd <= host_24; - rtc_time_bcd <= host_28; - hstate <= ST_DONE_OK; - end - 16'h00A0: begin - // Savestate: Start/Query - host_40 <= savestate_supported; - host_44 <= savestate_addr; - host_48 <= savestate_size; - - host_resultcode <= 0; - if(savestate_start_busy) host_resultcode <= 1; - if(savestate_start_ok) host_resultcode <= 2; - if(savestate_start_err) host_resultcode <= 3; - - if(host_20[0]) begin - // Request Start! - savestate_start <= 1; - // stay in this state until ack'd - if(savestate_start_ack) begin - hstate <= ST_DONE_CODE; - end - end - else begin - hstate <= ST_DONE_CODE; - end - end - 16'h00A4: begin - // Savestate: Load/Query - host_40 <= savestate_supported; - host_44 <= savestate_addr; - host_48 <= savestate_maxloadsize; - - host_resultcode <= 0; - if(savestate_load_busy) host_resultcode <= 1; - if(savestate_load_ok) host_resultcode <= 2; - if(savestate_load_err) host_resultcode <= 3; - - if(host_20[0]) begin - // Request Load! - savestate_load <= 1; - // stay in this state until ack'd - if(savestate_load_ack) begin - hstate <= ST_DONE_CODE; - end - end - else begin - hstate <= ST_DONE_CODE; - end - end - 16'h00B0: begin - // OS Notify: Menu State - osnotify_inmenu <= host_20[0]; - hstate <= ST_DONE_OK; - end - 16'h00B2: begin - // OS Notify: Docked State - osnotify_docked <= host_20[0]; - hstate <= ST_DONE_OK; - end - default: begin - hstate <= ST_DONE_ERR; - end - endcase - end - ST_WORK: begin - hstate <= ST_IDLE; - end - ST_DONE_OK: begin - host_0 <= 32'h4F4B0000; // result code 0 - hstate <= ST_IDLE; - end - ST_DONE_CODE: begin - host_0 <= {16'h4F4B, host_resultcode}; - hstate <= ST_IDLE; - end - ST_DONE_ERR: begin - host_0 <= 32'h4F4BFFFF; // result code FFFF = unknown command - hstate <= ST_IDLE; - end - endcase - - // target > host command executer - case(tstate) - TARG_ST_IDLE: begin - target_dataslot_ack <= 0; - if(status_setup_done_queue) begin - status_setup_done_queue <= 0; - tstate <= TARG_ST_READYTORUN; - end - else if(target_dataslot_read_queue) begin - target_dataslot_read_queue <= 0; - target_0[15:0] <= 16'h0180; - - target_20 <= target_dataslot_id; - target_24 <= target_dataslot_slotoffset; - target_28 <= target_dataslot_bridgeaddr; - target_2C <= target_dataslot_length; - - tstate <= TARG_ST_DATASLOTOP; - end - else if(target_dataslot_write_queue) begin - target_dataslot_write_queue <= 0; - target_0[15:0] <= 16'h0184; - - target_20 <= target_dataslot_id; - target_24 <= target_dataslot_slotoffset; - target_28 <= target_dataslot_bridgeaddr; - target_2C <= target_dataslot_length; - - tstate <= TARG_ST_DATASLOTOP; - end - else if(target_dataslot_getfile_queue) begin - target_dataslot_getfile_queue <= 0; - target_0[15:0] <= 16'h0190; - - target_20 <= target_dataslot_id; - target_24 <= target_buffer_resp_struct; // pointer to the bram that will hold the response struct - // which will contain the requested filename before command completion - tstate <= TARG_ST_DATASLOTOP; - end - else if(target_dataslot_openfile_queue) begin - target_dataslot_openfile_queue <= 0; - target_0[15:0] <= 16'h0192; - - target_20 <= target_dataslot_id; - target_24 <= target_buffer_param_struct; // pointer to the bram that will hold the parameter struct - // which must contain the desired filename and flag/size before command execution - tstate <= TARG_ST_DATASLOTOP; - end - end - TARG_ST_READYTORUN: begin - target_0 <= 32'h636D_0140; - tstate <= TARG_ST_WAITRESULT_RTR; - end - TARG_ST_DATASLOTOP: begin - target_0[31:16] <= 16'h636D; - - target_dataslot_done <= 0; - target_dataslot_err <= 0; - tstate <= TARG_ST_WAITRESULT_DSO; - end - TARG_ST_WAITRESULT_DSO: begin - if(target_0[31:16] == 16'h6275) begin - target_dataslot_ack <= 1; - end - if(target_0[31:16] == 16'h6F6B) begin - // done - // save result code - target_dataslot_err <= target_0[2:0]; - // assert done - target_dataslot_done <= 1; - tstate <= TARG_ST_IDLE; - end - end - TARG_ST_WAITRESULT_RTR: begin - if(target_0[31:16] == 16'h6F6B) begin - // done - tstate <= TARG_ST_IDLE; - end - end - endcase - end - - wire [31:0] b_datatable_q; - reg [9:0] b_datatable_addr; - reg b_datatable_wren; - - mf_datatable idt - ( - .address_a ( datatable_addr ), - .address_b ( b_datatable_addr ), - .clock_a ( clk ), - .clock_b ( clk ), - .data_a ( datatable_data ), - .data_b ( bridge_wr_data_in ), - .wren_a ( datatable_wren ), - .wren_b ( b_datatable_wren ), - .q_a ( datatable_q ), - .q_b ( b_datatable_q ) - ); - -endmodule +// Software License Agreement + +// The software supplied herewith by Analogue Enterprises Limited (the "Company”), +// the Analogue Pocket Framework (“APF”), is provided and licensed to you, the +// Company's customer, solely for use in designing, testing and creating +// applications for use with Company's Products or Services. The software is +// owned by the Company and/or its licensors, and is protected under applicable +// laws, including, but not limited to, U.S. copyright law. All rights are +// reserved. By using the APF code you are agreeing to the terms of the End User +// License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula] +// and incorporated herein by reference. To the extent any use of the APF requires +// application of the MIT License or the GNU General Public License and terms of +// this APF Software License Agreement and EULA are inconsistent with such license, +// the applicable terms of the MIT License or the GNU General Public License, as +// applicable, will prevail. + +// THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED +// WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO, +// ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR +// NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM +// DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE +// MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED, +// THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND +// DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING +// THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR +// ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY +// INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES, +// INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR +// INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY +// OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY +// CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION, +// WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU +// TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH +// YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE +// FULLEST EXTENT PERMITTED BY APPLICABLE LAW. +// +// bridge host/target command handler +// 2022 Analogue +// + +// mapped to 0xF8xxxxxx on bridge +// the spec is loose enough to allow implementation with either +// block rams and a soft CPU, or simply hard logic with some case statements. +// +// the implementation spec is documented, and depending on your application you +// may want to completely replace this module. this is only one of many +// possible ways to accomplish the host/target command system and data table. +// +// this module should always be clocked by a direct clock input and never a PLL, +// because it should report PLL lock status +// + +`default_nettype none +`timescale 1ns/1ps + +module core_bridge_cmd + ( + input wire clk, + output reg reset_n, + + input wire bridge_endian_little, + input wire [31:0] bridge_addr, + input wire bridge_rd, + output reg [31:0] bridge_rd_data, + input wire bridge_wr, + input wire [31:0] bridge_wr_data, + + // all these signals should be synchronous to clk + // add synchronizers if these need to be used in other clock domains + input wire status_boot_done, // assert when PLLs lock and logic is ready + input wire status_setup_done, // assert when core is happy with what's been loaded into it + input wire status_running, // assert when pocket's taken core out of reset and is running + + output reg dataslot_requestread, + output reg [15:0] dataslot_requestread_id, + input wire dataslot_requestread_ack, + input wire dataslot_requestread_ok, + + output reg dataslot_requestwrite, + output reg [15:0] dataslot_requestwrite_id, + output reg [31:0] dataslot_requestwrite_size, + input wire dataslot_requestwrite_ack, + input wire dataslot_requestwrite_ok, + + output reg dataslot_update, + output reg [15:0] dataslot_update_id, + output reg [31:0] dataslot_update_size, + + output reg dataslot_allcomplete, + + output reg [31:0] rtc_epoch_seconds, + output reg [31:0] rtc_date_bcd, + output reg [31:0] rtc_time_bcd, + output reg rtc_valid, + + input wire savestate_supported, + input wire [31:0] savestate_addr, + input wire [31:0] savestate_size, + input wire [31:0] savestate_maxloadsize, + + output reg osnotify_inmenu, + output reg osnotify_docked, + + output reg savestate_start, // core should detect rising edge on this, + input wire savestate_start_ack, // and then assert ack for at least 1 cycle + input wire savestate_start_busy, // assert constantly while in progress after ack + input wire savestate_start_ok, // assert continuously when done, and clear when new process is started + input wire savestate_start_err, // assert continuously on error, and clear when new process is started + + output reg savestate_load, + input wire savestate_load_ack, + input wire savestate_load_busy, + input wire savestate_load_ok, + input wire savestate_load_err, + + input wire target_dataslot_read, // rising edge triggered + input wire target_dataslot_write, + input wire target_dataslot_getfile, + input wire target_dataslot_openfile, + + output reg target_dataslot_ack, // asserted upon command start until completion + output reg target_dataslot_done, // asserted upon command finish until next command is issued + output reg [2:0] target_dataslot_err, // contains result of command execution. zero is OK + + input wire [15:0] target_dataslot_id, // parameters for each of the read/reload/write commands + input wire [31:0] target_dataslot_slotoffset, + input wire [31:0] target_dataslot_bridgeaddr, + input wire [31:0] target_dataslot_length, + + input wire [31:0] target_buffer_param_struct, // bus address of the memory region APF will fetch additional parameter struct from + input wire [31:0] target_buffer_resp_struct, // bus address of the memory region APF will write its response struct to + // this should be mapped by the developer, the buffer is not implemented in this file + + input wire [9:0] datatable_addr, + input wire datatable_wren, + input wire [31:0] datatable_data, + output wire [31:0] datatable_q + ); + + // handle endianness + reg [31:0] bridge_wr_data_in; + reg [31:0] bridge_rd_data_out; + + wire endian_little_s; + synch_3 s01(bridge_endian_little, endian_little_s, clk); + + always @(*) begin + bridge_rd_data <= endian_little_s ? { + bridge_rd_data_out[7:0], + bridge_rd_data_out[15:8], + bridge_rd_data_out[23:16], + bridge_rd_data_out[31:24] + } : bridge_rd_data_out; + + bridge_wr_data_in <= endian_little_s ? { + bridge_wr_data[7:0], + bridge_wr_data[15:8], + bridge_wr_data[23:16], + bridge_wr_data[31:24] + } : bridge_wr_data; + end + + // minimalistic approach here - + // keep the commonly used registers in logic, but data table in BRAM. + // implementation could be changed quite a bit for a more advanced use case + + // host + reg [31:0] host_0; + reg [31:0] host_4 = 'h20; // host cmd parameter data at 0x20 + reg [31:0] host_8 = 'h40; // host cmd response data at 0x40 + + reg [31:0] host_20; // parameter data + reg [31:0] host_24; + reg [31:0] host_28; + reg [31:0] host_2C; + + reg [31:0] host_40; // response data + reg [31:0] host_44; + reg [31:0] host_48; + reg [31:0] host_4C; + + reg host_cmd_start; + reg [15:0] host_cmd_startval; + reg [15:0] host_cmd; + reg [15:0] host_resultcode; + + localparam [3:0] ST_IDLE = 'd0; + localparam [3:0] ST_PARSE = 'd1; + localparam [3:0] ST_WORK = 'd2; + localparam [3:0] ST_DONE_OK = 'd13; + localparam [3:0] ST_DONE_CODE = 'd14; + localparam [3:0] ST_DONE_ERR = 'd15; + reg [3:0] hstate; + + // target + reg [31:0] target_0; + reg [31:0] target_4 = 'h20; + reg [31:0] target_8 = 'h40; + + reg [31:0] target_20; // parameter data + reg [31:0] target_24; + reg [31:0] target_28; + reg [31:0] target_2C; + + reg [31:0] target_40; // response data + reg [31:0] target_44; + reg [31:0] target_48; + reg [31:0] target_4C; + + localparam [3:0] TARG_ST_IDLE = 'd0; + localparam [3:0] TARG_ST_READYTORUN = 'd1; + localparam [3:0] TARG_ST_DATASLOTOP = 'd2; + localparam [3:0] TARG_ST_WAITRESULT_RTR = 'd14; + localparam [3:0] TARG_ST_WAITRESULT_DSO = 'd15; + reg [3:0] tstate; + + reg status_setup_done_1, status_setup_done_queue; + reg target_dataslot_read_1, target_dataslot_read_queue; + reg target_dataslot_write_1, target_dataslot_write_queue; + reg target_dataslot_getfile_1, target_dataslot_getfile_queue; + reg target_dataslot_openfile_1, target_dataslot_openfile_queue; + + initial begin + reset_n <= 0; + dataslot_requestread <= 0; + dataslot_requestwrite <= 0; + dataslot_update <= 0; + dataslot_allcomplete <= 0; + rtc_valid <= 0; + savestate_start <= 0; + savestate_load <= 0; + osnotify_inmenu <= 0; + osnotify_docked <= 0; + + status_setup_done_queue <= 0; + target_dataslot_read_queue <= 0; + target_dataslot_write_queue <= 0; + target_dataslot_getfile_queue <= 0; + target_dataslot_openfile_queue <= 0; + target_dataslot_ack <= 0; + target_dataslot_done <= 0; + target_dataslot_err <= 0; + end + + always @(posedge clk) begin + // detect a rising edge on the input signal + // and flag a queue that will be cleared later + status_setup_done_1 <= status_setup_done; + target_dataslot_read_1 <= target_dataslot_read; + target_dataslot_write_1 <= target_dataslot_write; + target_dataslot_getfile_1 <= target_dataslot_getfile; + target_dataslot_openfile_1 <= target_dataslot_openfile; + + if(status_setup_done & ~status_setup_done_1) begin + status_setup_done_queue <= 1; + end + if(target_dataslot_read & ~target_dataslot_read_1) begin + target_dataslot_read_queue <= 1; + end + if(target_dataslot_write & ~target_dataslot_write_1) begin + target_dataslot_write_queue <= 1; + end + if(target_dataslot_getfile & ~target_dataslot_getfile_1) begin + target_dataslot_getfile_queue <= 1; + end + if(target_dataslot_openfile & ~target_dataslot_openfile_1) begin + target_dataslot_openfile_queue <= 1; + end + + b_datatable_wren <= 0; + b_datatable_addr <= bridge_addr >> 2; + + if(bridge_wr) begin + casex(bridge_addr) + 32'hF8xx00xx: begin + case(bridge_addr[7:0]) + 8'h0: begin + host_0 <= bridge_wr_data_in; // command/status + // check for command + if(bridge_wr_data_in[31:16] == 16'h434D) begin + // host wants us to do a command + host_cmd_startval <= bridge_wr_data_in[15:0]; + host_cmd_start <= 1; + end + end + 8'h20: host_20 <= bridge_wr_data_in; // parameter data regs + 8'h24: host_24 <= bridge_wr_data_in; + 8'h28: host_28 <= bridge_wr_data_in; + 8'h2C: host_2C <= bridge_wr_data_in; + endcase + end + 32'hF8xx10xx: begin + case(bridge_addr[7:0]) + 8'h0: target_0 <= bridge_wr_data_in; // command/status + 8'h4: target_4 <= bridge_wr_data_in; // parameter data pointer + 8'h8: target_8 <= bridge_wr_data_in; // response data pointer + 8'h40: target_40 <= bridge_wr_data_in; // response data regs + 8'h44: target_44 <= bridge_wr_data_in; + 8'h48: target_48 <= bridge_wr_data_in; + 8'h4C: target_4C <= bridge_wr_data_in; + endcase + end + 32'hF8xx2xxx: begin + b_datatable_wren <= 1; + end + endcase + end + if(bridge_rd) begin + casex(bridge_addr) + 32'hF8xx00xx: begin + case(bridge_addr[7:0]) + 8'h0: bridge_rd_data_out <= host_0; // command/status + 8'h4: bridge_rd_data_out <= host_4; // parameter data pointer + 8'h8: bridge_rd_data_out <= host_8; // response data pointer + 8'h40: bridge_rd_data_out <= host_40; // response data regs + 8'h44: bridge_rd_data_out <= host_44; + 8'h48: bridge_rd_data_out <= host_48; + 8'h4C: bridge_rd_data_out <= host_4C; + endcase + end + 32'hF8xx10xx: begin + case(bridge_addr[7:0]) + 8'h0: bridge_rd_data_out <= target_0; + 8'h4: bridge_rd_data_out <= target_4; + 8'h8: bridge_rd_data_out <= target_8; + 8'h20: bridge_rd_data_out <= target_20; // parameter data regs + 8'h24: bridge_rd_data_out <= target_24; + 8'h28: bridge_rd_data_out <= target_28; + 8'h2C: bridge_rd_data_out <= target_2C; + endcase + end + 32'hF8xx2xxx: begin + bridge_rd_data_out <= b_datatable_q; + end + endcase + end + + // host > target command executer + case(hstate) + ST_IDLE: begin + dataslot_requestread <= 0; + dataslot_requestwrite <= 0; + dataslot_update <= 0; + savestate_start <= 0; + savestate_load <= 0; + + // there is no queueing. pocket will always make sure any outstanding host + // commands are finished before starting another + if(host_cmd_start) begin + host_cmd_start <= 0; + // save the command in case it gets clobbered later + host_cmd <= host_cmd_startval; + hstate <= ST_PARSE; + end + end + ST_PARSE: begin + // overwrite command semaphore with busy flag + host_0 <= {16'h4255, host_cmd}; + + case(host_cmd) + 16'h0000: begin + // Request Status + host_resultcode <= 1; // default: booting + if(status_boot_done) begin + host_resultcode <= 2; // setup + if(status_setup_done) begin + host_resultcode <= 3; // idle + end + else if(status_running) begin + host_resultcode <= 4; // running + end + end + hstate <= ST_DONE_CODE; + end + 16'h0010: begin + // Reset Enter + reset_n <= 0; + hstate <= ST_DONE_OK; + end + 16'h0011: begin + // Reset Exit + reset_n <= 1; + hstate <= ST_DONE_OK; + end + 16'h0080: begin + // Data slot request read + dataslot_allcomplete <= 0; + dataslot_requestread <= 1; + dataslot_requestread_id <= host_20[15:0]; + if(dataslot_requestread_ack) begin + host_resultcode <= 0; + if(!dataslot_requestread_ok) host_resultcode <= 2; + hstate <= ST_DONE_CODE; + end + end + 16'h0082: begin + // Data slot request write + dataslot_allcomplete <= 0; + dataslot_requestwrite <= 1; + dataslot_requestwrite_id <= host_20[15:0]; + dataslot_requestwrite_size <= host_24; + if(dataslot_requestwrite_ack) begin + host_resultcode <= 0; + if(!dataslot_requestwrite_ok) host_resultcode <= 2; + hstate <= ST_DONE_CODE; + end + end + 16'h008A: begin + // Data slot update (sent on deferload marked slots only) + dataslot_update <= 1; + dataslot_update_id <= host_20[15:0]; + dataslot_update_size <= host_24; + hstate <= ST_DONE_OK; + end + 16'h008F: begin + // Data slot access all complete + dataslot_allcomplete <= 1; + hstate <= ST_DONE_OK; + end + 16'h0090: begin + // Real-time Clock Data + // user logic should detect rising edge, it is not continuously updated + rtc_valid <= 1; + rtc_epoch_seconds <= host_20; + rtc_date_bcd <= host_24; + rtc_time_bcd <= host_28; + hstate <= ST_DONE_OK; + end + 16'h00A0: begin + // Savestate: Start/Query + host_40 <= savestate_supported; + host_44 <= savestate_addr; + host_48 <= savestate_size; + + host_resultcode <= 0; + if(savestate_start_busy) host_resultcode <= 1; + if(savestate_start_ok) host_resultcode <= 2; + if(savestate_start_err) host_resultcode <= 3; + + if(host_20[0]) begin + // Request Start! + savestate_start <= 1; + // stay in this state until ack'd + if(savestate_start_ack) begin + hstate <= ST_DONE_CODE; + end + end + else begin + hstate <= ST_DONE_CODE; + end + end + 16'h00A4: begin + // Savestate: Load/Query + host_40 <= savestate_supported; + host_44 <= savestate_addr; + host_48 <= savestate_maxloadsize; + + host_resultcode <= 0; + if(savestate_load_busy) host_resultcode <= 1; + if(savestate_load_ok) host_resultcode <= 2; + if(savestate_load_err) host_resultcode <= 3; + + if(host_20[0]) begin + // Request Load! + savestate_load <= 1; + // stay in this state until ack'd + if(savestate_load_ack) begin + hstate <= ST_DONE_CODE; + end + end + else begin + hstate <= ST_DONE_CODE; + end + end + 16'h00B0: begin + // OS Notify: Menu State + osnotify_inmenu <= host_20[0]; + hstate <= ST_DONE_OK; + end + 16'h00B2: begin + // OS Notify: Docked State + osnotify_docked <= host_20[0]; + hstate <= ST_DONE_OK; + end + default: begin + hstate <= ST_DONE_ERR; + end + endcase + end + ST_WORK: begin + hstate <= ST_IDLE; + end + ST_DONE_OK: begin + host_0 <= 32'h4F4B0000; // result code 0 + hstate <= ST_IDLE; + end + ST_DONE_CODE: begin + host_0 <= {16'h4F4B, host_resultcode}; + hstate <= ST_IDLE; + end + ST_DONE_ERR: begin + host_0 <= 32'h4F4BFFFF; // result code FFFF = unknown command + hstate <= ST_IDLE; + end + endcase + + // target > host command executer + case(tstate) + TARG_ST_IDLE: begin + target_dataslot_ack <= 0; + if(status_setup_done_queue) begin + status_setup_done_queue <= 0; + tstate <= TARG_ST_READYTORUN; + end + else if(target_dataslot_read_queue) begin + target_dataslot_read_queue <= 0; + target_0[15:0] <= 16'h0180; + + target_20 <= target_dataslot_id; + target_24 <= target_dataslot_slotoffset; + target_28 <= target_dataslot_bridgeaddr; + target_2C <= target_dataslot_length; + + tstate <= TARG_ST_DATASLOTOP; + end + else if(target_dataslot_write_queue) begin + target_dataslot_write_queue <= 0; + target_0[15:0] <= 16'h0184; + + target_20 <= target_dataslot_id; + target_24 <= target_dataslot_slotoffset; + target_28 <= target_dataslot_bridgeaddr; + target_2C <= target_dataslot_length; + + tstate <= TARG_ST_DATASLOTOP; + end + else if(target_dataslot_getfile_queue) begin + target_dataslot_getfile_queue <= 0; + target_0[15:0] <= 16'h0190; + + target_20 <= target_dataslot_id; + target_24 <= target_buffer_resp_struct; // pointer to the bram that will hold the response struct + // which will contain the requested filename before command completion + tstate <= TARG_ST_DATASLOTOP; + end + else if(target_dataslot_openfile_queue) begin + target_dataslot_openfile_queue <= 0; + target_0[15:0] <= 16'h0192; + + target_20 <= target_dataslot_id; + target_24 <= target_buffer_param_struct; // pointer to the bram that will hold the parameter struct + // which must contain the desired filename and flag/size before command execution + tstate <= TARG_ST_DATASLOTOP; + end + end + TARG_ST_READYTORUN: begin + target_0 <= 32'h636D_0140; + tstate <= TARG_ST_WAITRESULT_RTR; + end + TARG_ST_DATASLOTOP: begin + target_0[31:16] <= 16'h636D; + + target_dataslot_done <= 0; + target_dataslot_err <= 0; + tstate <= TARG_ST_WAITRESULT_DSO; + end + TARG_ST_WAITRESULT_DSO: begin + if(target_0[31:16] == 16'h6275) begin + target_dataslot_ack <= 1; + end + if(target_0[31:16] == 16'h6F6B) begin + // done + // save result code + target_dataslot_err <= target_0[2:0]; + // assert done + target_dataslot_done <= 1; + tstate <= TARG_ST_IDLE; + end + end + TARG_ST_WAITRESULT_RTR: begin + if(target_0[31:16] == 16'h6F6B) begin + // done + tstate <= TARG_ST_IDLE; + end + end + endcase + end + + wire [31:0] b_datatable_q; + reg [9:0] b_datatable_addr; + reg b_datatable_wren; + + mf_datatable idt + ( + .address_a ( datatable_addr ), + .address_b ( b_datatable_addr ), + .clock_a ( clk ), + .clock_b ( clk ), + .data_a ( datatable_data ), + .data_b ( bridge_wr_data_in ), + .wren_a ( datatable_wren ), + .wren_b ( b_datatable_wren ), + .q_a ( datatable_q ), + .q_b ( b_datatable_q ) + ); + +endmodule diff --git a/platform/pocket/peripherals/io_bridge_peripheral.sv b/platform/pocket/peripherals/io_bridge_peripheral.sv index bfb9d00..06585d4 100644 --- a/platform/pocket/peripherals/io_bridge_peripheral.sv +++ b/platform/pocket/peripherals/io_bridge_peripheral.sv @@ -1,319 +1,319 @@ -// Software License Agreement - -// The software supplied herewith by Analogue Enterprises Limited (the "Company”), -// the Analogue Pocket Framework (“APF”), is provided and licensed to you, the -// Company's customer, solely for use in designing, testing and creating -// applications for use with Company's Products or Services. The software is -// owned by the Company and/or its licensors, and is protected under applicable -// laws, including, but not limited to, U.S. copyright law. All rights are -// reserved. By using the APF code you are agreeing to the terms of the End User -// License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula] -// and incorporated herein by reference. To the extent any use of the APF requires -// application of the MIT License or the GNU General Public License and terms of -// this APF Software License Agreement and EULA are inconsistent with such license, -// the applicable terms of the MIT License or the GNU General Public License, as -// applicable, will prevail. - -// THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED -// WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO, -// ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR -// NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM -// DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE -// MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED, -// THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND -// DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING -// THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR -// ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY -// INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES, -// INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR -// INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY -// OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY -// CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION, -// WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU -// TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH -// YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE -// FULLEST EXTENT PERMITTED BY APPLICABLE LAW. -// -// bridge peripheral for socrates PMP bridge to heraclitus+aristotle -// 2020-2022 Analogue -// -// please note that while writes are immediate, -// reads are buffered by 1 word. this is necessary to maintain -// data throughput while reading from slower data sources like -// sdram. -// reads should always return the current bus value, and kickstart -// into the next read immediately. this way, you have the entire -// next word time to retrieve the data, instead of just a few -// cycles. -// -// the worst-case read/write timing is every 88 cycles @ 74.25mhz -// which is about 1180ns. - -`default_nettype none -`timescale 1ns/1ps - -module io_bridge_peripheral - ( - input wire clk, - input wire reset_n, - - input wire endian_little, - - output reg [31:0] pmp_addr, - output reg pmp_addr_valid, - output reg pmp_rd, - input wire [31:0] pmp_rd_data, - output reg pmp_wr, - output reg [31:0] pmp_wr_data, - - inout reg phy_spimosi, - inout reg phy_spimiso, - inout reg phy_spiclk, - input wire phy_spiss - ); - - // - // clock domain: clk (74.25mhz) rising edge - // - wire reset_n_s; - synch_3 s00(reset_n, reset_n_s, clk); - - wire endian_little_s; - synch_3 s01(endian_little, endian_little_s, clk); - - wire phy_spiss_s, phy_spiss_r, phy_spiss_f; - synch_3 s02(phy_spiss, phy_spiss_s, clk, phy_spiss_r, phy_spiss_f); - - reg [4:0] state; - localparam ST_RESET = 'd0; - localparam ST_IDLE = 'd1; - localparam ST_READ_0 = 'd2; - localparam ST_READ_1 = 'd3; - localparam ST_READ_2 = 'd4; - localparam ST_READ_3 = 'd5; - localparam ST_WRITE_0 = 'd6; - localparam ST_WRITE_1 = 'd7; - localparam ST_WRITE_2 = 'd8; - localparam ST_ADDR_0 = 'd9; - - reg [1:0] addr_cnt; - reg [1:0] data_cnt; - reg [6:0] read_cnt; - - // synchronize rd byte flag's rising edge into clk - wire rx_byte_done_s, rx_byte_done_r; - synch_3 s03(rx_byte_done, rx_byte_done_s, clk, rx_byte_done_r); - - reg [4:0] spis; - localparam ST_SIDLE = 'd1; - localparam ST_SEND_N = 'd6; - localparam ST_SEND_0 = 'd2; - localparam ST_SEND_1 = 'd3; - localparam ST_SEND_2 = 'd4; - localparam ST_SEND_3 = 'd5; - reg spis_tx; - reg [31:0] spis_word_tx; - reg [31:0] spis_word; - reg [4:0] spis_count; - reg spis_done; - - reg rx_byte_done_r_1, rx_byte_done_r_2; - reg [7:0] rx_byte_1, rx_byte_2; - - // handle reversing endianness on both ports - reg [31:0] pmp_wr_data_latch; - reg [31:0] pmp_rd_data_e; // asynchronous - reg [31:0] pmp_rd_data_buf; // buffer the last word for immediate response - always @(*) begin - pmp_wr_data <= endian_little_s ? { pmp_wr_data_latch[7:0], - pmp_wr_data_latch[15:8], - pmp_wr_data_latch[23:16], - pmp_wr_data_latch[31:24] - } : pmp_wr_data_latch; - - pmp_rd_data_e <= endian_little_s ? {pmp_rd_data[7:0], - pmp_rd_data[15:8], - pmp_rd_data[23:16], - pmp_rd_data[31:24] - } : pmp_rd_data; - end - - always @(posedge clk) begin - rx_byte_2 <= rx_byte_1; - rx_byte_1 <= rx_byte; - rx_byte_done_r_1 <= rx_byte_done_r; - rx_byte_done_r_2 <= rx_byte_done_r_1; - case(state) - ST_RESET: begin - addr_cnt <= 0; - data_cnt <= 0; - pmp_wr <= 0; - pmp_rd <= 0; - pmp_addr_valid <= 0; - spis_tx <= 0; - state <= ST_ADDR_0; - end - ST_ADDR_0: begin - // transaction has started - if(rx_byte_done_r_2) begin - case(addr_cnt) - 0: pmp_addr[31:24] <= rx_byte_2; - 1: pmp_addr[23:16] <= rx_byte_2; - 2: pmp_addr[15: 8] <= rx_byte_2; - 3: begin - pmp_addr[ 7: 0] <= {rx_byte_2[7:2], 2'b00}; - // address is latched - if( rx_byte_2[0] ) begin - data_cnt <= 0; - state <= ST_WRITE_0; - end - else begin - data_cnt <= 0; - read_cnt <= 0; - state <= ST_READ_0; - end - end - endcase - addr_cnt <= addr_cnt + 1'b1; - end - end - ST_WRITE_0: begin - // give notice, address has become valid - pmp_addr_valid <= 1; - if(rx_byte_done_r_2) begin - case(data_cnt) - 0: pmp_wr_data_latch[31:24] <= rx_byte_2; - 1: pmp_wr_data_latch[23:16] <= rx_byte_2; - 2: pmp_wr_data_latch[15: 8] <= rx_byte_2; - 3: begin - pmp_wr_data_latch[ 7: 0] <= rx_byte_2; - state <= ST_WRITE_1; - end - endcase - data_cnt <= data_cnt + 1'b1; - end - end - ST_WRITE_1: begin - pmp_wr <= 1; - state <= ST_WRITE_2; - end - ST_WRITE_2: begin - // exited upon new transaction - pmp_wr <= 0; - end - ST_READ_0: begin - pmp_addr_valid <= 1; - // delay a few cycles - read_cnt <= read_cnt + 1'b1; - if(read_cnt == 4-1) begin - // load the buffer with the current data - // and give the current buffer contents to bridge - spis_word_tx <= pmp_rd_data_e; - spis_tx <= 1; - state <= ST_READ_1; - end - end - ST_READ_1: begin - pmp_rd <= 1; - state <= ST_READ_2; - end - ST_READ_2: begin - pmp_rd <= 0; - if(spis_done) begin - spis_tx <= 0; - state <= ST_READ_3; - end - end - ST_READ_3: begin - // exited upon new transaction - end - endcase - - // - // word transmit - // - spis_done <= 0; - case(spis) - ST_SIDLE: begin - spis_count <= 0; - phy_spiclk <= 1'bZ; - phy_spimosi <= 1'bZ; - phy_spimiso <= 1'bZ; - if(spis_tx) begin - spis_word <= spis_word_tx; - spis <= ST_SEND_N; - end - end - // drive high first - ST_SEND_N: begin - phy_spiclk <= 1'b1; - phy_spimosi <= 1'b1; - phy_spimiso <= 1'b1; - spis <= ST_SEND_0; - end - // tx, shift out bits - ST_SEND_0: begin - phy_spiclk <= 0; - spis <= ST_SEND_1; - phy_spimosi <= spis_word[31]; - phy_spimiso <= spis_word[30]; - spis_word <= {spis_word[29:0], 2'b00}; - end - ST_SEND_1: begin - phy_spiclk <= 1; - spis <= ST_SEND_0; - spis_count <= spis_count + 1'b1; - if(spis_count == 15) begin - spis <= ST_SEND_2; - end - end - ST_SEND_2: begin - phy_spiclk <= 1'b1; - phy_spimosi <= 1'b1; - phy_spimiso <= 1'b1; - spis <= ST_SEND_3; - spis_done <= 1; - end - ST_SEND_3: begin - spis <= ST_SIDLE; - end - endcase - if(phy_spiss_s) begin - // select is high, go back to reset - state <= ST_RESET; - spis <= ST_SIDLE; - end - end - - // - // clock domain: phy_spiclk rising edge - // - reg [1:0] rx_latch_idx; - reg [7:0] rx_dat; - reg [7:0] rx_byte; // latched by clk, but upon a synchronized trigger - reg rx_byte_done; - - always @(posedge phy_spiclk or posedge phy_spiss) begin - if(phy_spiss) begin - // reset - rx_byte_done <= 0; - rx_latch_idx <= 0; - end - else begin - // spiclk rising edge, latch data - rx_byte_done <= 0; - case(rx_latch_idx) - 0: begin rx_dat[7:6] <= {phy_spimosi, phy_spimiso}; rx_latch_idx <= 1; end - 1: begin rx_dat[5:4] <= {phy_spimosi, phy_spimiso}; rx_latch_idx <= 2; end - 2: begin rx_dat[3:2] <= {phy_spimosi, phy_spimiso}; rx_latch_idx <= 3; end - 3: begin - // last bit of the byte - rx_byte <= {rx_dat[7:2], phy_spimosi, phy_spimiso}; - rx_latch_idx <= 0; - rx_byte_done <= 1; - end - endcase - end - end - -endmodule +// Software License Agreement + +// The software supplied herewith by Analogue Enterprises Limited (the "Company”), +// the Analogue Pocket Framework (“APF”), is provided and licensed to you, the +// Company's customer, solely for use in designing, testing and creating +// applications for use with Company's Products or Services. The software is +// owned by the Company and/or its licensors, and is protected under applicable +// laws, including, but not limited to, U.S. copyright law. All rights are +// reserved. By using the APF code you are agreeing to the terms of the End User +// License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula] +// and incorporated herein by reference. To the extent any use of the APF requires +// application of the MIT License or the GNU General Public License and terms of +// this APF Software License Agreement and EULA are inconsistent with such license, +// the applicable terms of the MIT License or the GNU General Public License, as +// applicable, will prevail. + +// THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED +// WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO, +// ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR +// NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM +// DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE +// MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED, +// THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND +// DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING +// THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR +// ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY +// INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES, +// INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR +// INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY +// OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY +// CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION, +// WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU +// TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH +// YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE +// FULLEST EXTENT PERMITTED BY APPLICABLE LAW. +// +// bridge peripheral for socrates PMP bridge to heraclitus+aristotle +// 2020-2022 Analogue +// +// please note that while writes are immediate, +// reads are buffered by 1 word. this is necessary to maintain +// data throughput while reading from slower data sources like +// sdram. +// reads should always return the current bus value, and kickstart +// into the next read immediately. this way, you have the entire +// next word time to retrieve the data, instead of just a few +// cycles. +// +// the worst-case read/write timing is every 88 cycles @ 74.25mhz +// which is about 1180ns. + +`default_nettype none +`timescale 1ns/1ps + +module io_bridge_peripheral + ( + input wire clk, + input wire reset_n, + + input wire endian_little, + + output reg [31:0] pmp_addr, + output reg pmp_addr_valid, + output reg pmp_rd, + input wire [31:0] pmp_rd_data, + output reg pmp_wr, + output reg [31:0] pmp_wr_data, + + inout reg phy_spimosi, + inout reg phy_spimiso, + inout reg phy_spiclk, + input wire phy_spiss + ); + + // + // clock domain: clk (74.25mhz) rising edge + // + wire reset_n_s; + synch_3 s00(reset_n, reset_n_s, clk); + + wire endian_little_s; + synch_3 s01(endian_little, endian_little_s, clk); + + wire phy_spiss_s, phy_spiss_r, phy_spiss_f; + synch_3 s02(phy_spiss, phy_spiss_s, clk, phy_spiss_r, phy_spiss_f); + + reg [4:0] state; + localparam ST_RESET = 'd0; + localparam ST_IDLE = 'd1; + localparam ST_READ_0 = 'd2; + localparam ST_READ_1 = 'd3; + localparam ST_READ_2 = 'd4; + localparam ST_READ_3 = 'd5; + localparam ST_WRITE_0 = 'd6; + localparam ST_WRITE_1 = 'd7; + localparam ST_WRITE_2 = 'd8; + localparam ST_ADDR_0 = 'd9; + + reg [1:0] addr_cnt; + reg [1:0] data_cnt; + reg [6:0] read_cnt; + + // synchronize rd byte flag's rising edge into clk + wire rx_byte_done_s, rx_byte_done_r; + synch_3 s03(rx_byte_done, rx_byte_done_s, clk, rx_byte_done_r); + + reg [4:0] spis; + localparam ST_SIDLE = 'd1; + localparam ST_SEND_N = 'd6; + localparam ST_SEND_0 = 'd2; + localparam ST_SEND_1 = 'd3; + localparam ST_SEND_2 = 'd4; + localparam ST_SEND_3 = 'd5; + reg spis_tx; + reg [31:0] spis_word_tx; + reg [31:0] spis_word; + reg [4:0] spis_count; + reg spis_done; + + reg rx_byte_done_r_1, rx_byte_done_r_2; + reg [7:0] rx_byte_1, rx_byte_2; + + // handle reversing endianness on both ports + reg [31:0] pmp_wr_data_latch; + reg [31:0] pmp_rd_data_e; // asynchronous + reg [31:0] pmp_rd_data_buf; // buffer the last word for immediate response + always @(*) begin + pmp_wr_data <= endian_little_s ? { pmp_wr_data_latch[7:0], + pmp_wr_data_latch[15:8], + pmp_wr_data_latch[23:16], + pmp_wr_data_latch[31:24] + } : pmp_wr_data_latch; + + pmp_rd_data_e <= endian_little_s ? {pmp_rd_data[7:0], + pmp_rd_data[15:8], + pmp_rd_data[23:16], + pmp_rd_data[31:24] + } : pmp_rd_data; + end + + always @(posedge clk) begin + rx_byte_2 <= rx_byte_1; + rx_byte_1 <= rx_byte; + rx_byte_done_r_1 <= rx_byte_done_r; + rx_byte_done_r_2 <= rx_byte_done_r_1; + case(state) + ST_RESET: begin + addr_cnt <= 0; + data_cnt <= 0; + pmp_wr <= 0; + pmp_rd <= 0; + pmp_addr_valid <= 0; + spis_tx <= 0; + state <= ST_ADDR_0; + end + ST_ADDR_0: begin + // transaction has started + if(rx_byte_done_r_2) begin + case(addr_cnt) + 0: pmp_addr[31:24] <= rx_byte_2; + 1: pmp_addr[23:16] <= rx_byte_2; + 2: pmp_addr[15: 8] <= rx_byte_2; + 3: begin + pmp_addr[ 7: 0] <= {rx_byte_2[7:2], 2'b00}; + // address is latched + if( rx_byte_2[0] ) begin + data_cnt <= 0; + state <= ST_WRITE_0; + end + else begin + data_cnt <= 0; + read_cnt <= 0; + state <= ST_READ_0; + end + end + endcase + addr_cnt <= addr_cnt + 1'b1; + end + end + ST_WRITE_0: begin + // give notice, address has become valid + pmp_addr_valid <= 1; + if(rx_byte_done_r_2) begin + case(data_cnt) + 0: pmp_wr_data_latch[31:24] <= rx_byte_2; + 1: pmp_wr_data_latch[23:16] <= rx_byte_2; + 2: pmp_wr_data_latch[15: 8] <= rx_byte_2; + 3: begin + pmp_wr_data_latch[ 7: 0] <= rx_byte_2; + state <= ST_WRITE_1; + end + endcase + data_cnt <= data_cnt + 1'b1; + end + end + ST_WRITE_1: begin + pmp_wr <= 1; + state <= ST_WRITE_2; + end + ST_WRITE_2: begin + // exited upon new transaction + pmp_wr <= 0; + end + ST_READ_0: begin + pmp_addr_valid <= 1; + // delay a few cycles + read_cnt <= read_cnt + 1'b1; + if(read_cnt == 4-1) begin + // load the buffer with the current data + // and give the current buffer contents to bridge + spis_word_tx <= pmp_rd_data_e; + spis_tx <= 1; + state <= ST_READ_1; + end + end + ST_READ_1: begin + pmp_rd <= 1; + state <= ST_READ_2; + end + ST_READ_2: begin + pmp_rd <= 0; + if(spis_done) begin + spis_tx <= 0; + state <= ST_READ_3; + end + end + ST_READ_3: begin + // exited upon new transaction + end + endcase + + // + // word transmit + // + spis_done <= 0; + case(spis) + ST_SIDLE: begin + spis_count <= 0; + phy_spiclk <= 1'bZ; + phy_spimosi <= 1'bZ; + phy_spimiso <= 1'bZ; + if(spis_tx) begin + spis_word <= spis_word_tx; + spis <= ST_SEND_N; + end + end + // drive high first + ST_SEND_N: begin + phy_spiclk <= 1'b1; + phy_spimosi <= 1'b1; + phy_spimiso <= 1'b1; + spis <= ST_SEND_0; + end + // tx, shift out bits + ST_SEND_0: begin + phy_spiclk <= 0; + spis <= ST_SEND_1; + phy_spimosi <= spis_word[31]; + phy_spimiso <= spis_word[30]; + spis_word <= {spis_word[29:0], 2'b00}; + end + ST_SEND_1: begin + phy_spiclk <= 1; + spis <= ST_SEND_0; + spis_count <= spis_count + 1'b1; + if(spis_count == 15) begin + spis <= ST_SEND_2; + end + end + ST_SEND_2: begin + phy_spiclk <= 1'b1; + phy_spimosi <= 1'b1; + phy_spimiso <= 1'b1; + spis <= ST_SEND_3; + spis_done <= 1; + end + ST_SEND_3: begin + spis <= ST_SIDLE; + end + endcase + if(phy_spiss_s) begin + // select is high, go back to reset + state <= ST_RESET; + spis <= ST_SIDLE; + end + end + + // + // clock domain: phy_spiclk rising edge + // + reg [1:0] rx_latch_idx; + reg [7:0] rx_dat; + reg [7:0] rx_byte; // latched by clk, but upon a synchronized trigger + reg rx_byte_done; + + always @(posedge phy_spiclk or posedge phy_spiss) begin + if(phy_spiss) begin + // reset + rx_byte_done <= 0; + rx_latch_idx <= 0; + end + else begin + // spiclk rising edge, latch data + rx_byte_done <= 0; + case(rx_latch_idx) + 0: begin rx_dat[7:6] <= {phy_spimosi, phy_spimiso}; rx_latch_idx <= 1; end + 1: begin rx_dat[5:4] <= {phy_spimosi, phy_spimiso}; rx_latch_idx <= 2; end + 2: begin rx_dat[3:2] <= {phy_spimosi, phy_spimiso}; rx_latch_idx <= 3; end + 3: begin + // last bit of the byte + rx_byte <= {rx_dat[7:2], phy_spimosi, phy_spimiso}; + rx_latch_idx <= 0; + rx_byte_done <= 1; + end + endcase + end + end + +endmodule diff --git a/platform/pocket/peripherals/io_pad_controller.sv b/platform/pocket/peripherals/io_pad_controller.sv index 478b22f..6797e72 100644 --- a/platform/pocket/peripherals/io_pad_controller.sv +++ b/platform/pocket/peripherals/io_pad_controller.sv @@ -1,316 +1,316 @@ -// Software License Agreement - -// The software supplied herewith by Analogue Enterprises Limited (the "Company”), -// the Analogue Pocket Framework (“APF”), is provided and licensed to you, the -// Company's customer, solely for use in designing, testing and creating -// applications for use with Company's Products or Services. The software is -// owned by the Company and/or its licensors, and is protected under applicable -// laws, including, but not limited to, U.S. copyright law. All rights are -// reserved. By using the APF code you are agreeing to the terms of the End User -// License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula] -// and incorporated herein by reference. To the extent any use of the APF requires -// application of the MIT License or the GNU General Public License and terms of -// this APF Software License Agreement and EULA are inconsistent with such license, -// the applicable terms of the MIT License or the GNU General Public License, as -// applicable, will prevail. - -// THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED -// WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO, -// ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR -// NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM -// DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE -// MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED, -// THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND -// DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING -// THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR -// ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY -// INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES, -// INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR -// INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY -// OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY -// CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION, -// WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU -// TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH -// YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE -// FULLEST EXTENT PERMITTED BY APPLICABLE LAW. -// -// pad controller -// 2020-08-17 Analogue -// - -`default_nettype none -`timescale 1ns/1ps - -module io_pad_controller - ( - input wire clk, - input wire reset_n, - - inout reg pad_1wire, - - output reg [31:0] cont1_key, - output reg [31:0] cont2_key, - output reg [31:0] cont3_key, - output reg [31:0] cont4_key, - output reg [31:0] cont1_joy, - output reg [31:0] cont2_joy, - output reg [31:0] cont3_joy, - output reg [31:0] cont4_joy, - output reg [15:0] cont1_trig, - output reg [15:0] cont2_trig, - output reg [15:0] cont3_trig, - output reg [15:0] cont4_trig, - - output reg rx_timed_out - ); - - wire reset_n_s; - synch_3 s00(reset_n, reset_n_s, clk); - - wire pad_1wire_s, pad_1wire_r, pad_1wire_f; - synch_3 s01(pad_1wire, pad_1wire_s, clk, pad_1wire_r, pad_1wire_f); - - // - // protocol fsm - // - reg [20:0] rx_timeout; // ~28ms - - reg [15:0] auto_poll_cnt; // 882us - reg auto_poll_queue; - - reg [18:0] heartbeat_cnt; // 7ms - reg heartbeat_queue; - - localparam ST_RESET = 'd0; - localparam ST_IDLE = 'd1; - localparam ST_RX_BUTTON_1 = 'd2; - localparam ST_RX_BUTTON_2 = 'd3; - localparam ST_TX_SCALER = 'd4; - localparam ST_END_TX = 'd5; - - reg [3:0] state; - reg [3:0] cnt; - - always @(posedge clk) begin - tx_word_start <= 0; - - auto_poll_cnt <= auto_poll_cnt + 1'b1; - heartbeat_cnt <= heartbeat_cnt + 1'b1; - - // increment rx timeout, override and reset when idle below - rx_timeout <= rx_timeout + 1'b1; - - case(state) - ST_RESET: begin - reset_tr_n <= 0; - rx_timed_out <= 0; - - if(&rx_timeout[19:0]) begin - state <= ST_IDLE; - end - end - ST_IDLE: begin - // idle state - reset_tr_n <= 1; - rx_timeout <= 0; - cnt <= 0; - if(auto_poll_queue) begin - auto_poll_queue <= 0; - - tx_word_start <= 1; - tx_word <= 32'h4A10000C; - - state <= ST_RX_BUTTON_1; - end - else if(heartbeat_queue) begin - heartbeat_queue <= 0; - - tx_word_start <= 1; - tx_word <= 32'h4AFE0000; - - state <= ST_END_TX; - end - end - // receive button words - ST_RX_BUTTON_1: begin - if(tx_word_done) begin - state <= ST_RX_BUTTON_2; - end - end - ST_RX_BUTTON_2: begin - if(rx_word_done) begin - cnt <= cnt + 1'b1; - case(cnt) - 0: cont1_key <= rx_word; - 1: cont1_joy <= rx_word; - 2: cont1_trig <= rx_word[15:0]; - - 3: cont2_key <= rx_word; - 4: cont2_joy <= rx_word; - 5: cont2_trig <= rx_word[15:0]; - - 6: cont3_key <= rx_word; - 7: cont3_joy <= rx_word; - 8: cont3_trig <= rx_word[15:0]; - - 9: cont4_key <= rx_word; - 10: cont4_joy <= rx_word; - 11: begin - cont4_trig <= rx_word[15:0]; - state <= ST_IDLE; - end - endcase - end - end - // do nothing - ST_END_TX: begin - // done sending, idle again - if(tx_word_done) begin - state <= ST_IDLE; - end - end - endcase - - if(&auto_poll_cnt) begin - auto_poll_queue <= 1; - end - - if(&heartbeat_cnt) begin - heartbeat_queue <= 1; - end - - if(&rx_timeout) begin - // reset protocol FSM which will also reset t/r engine - rx_timed_out <= 1; - rx_timeout <= 0; - state <= ST_RESET; - end - - if(~reset_n_s) begin - state <= ST_RESET; - end - end - - // - // word receive/transmit engine - // - reg reset_tr_n; - localparam BITLEN = 60; - - reg rx_word_done; - reg [31:0] rx_word_shift; - reg [31:0] rx_word; - - reg tx_word_start, tx_word_start_1; - reg tx_word_done; - reg [31:0] tx_word; - reg [31:0] tx_word_shift; - - reg [7:0] tr_cnt; - reg [5:0] tr_bit; - - localparam TR_IDLE = 'd1; - localparam TR_TX_START = 'd2; - localparam TR_TX_CONTINUE = 'd3; - localparam TR_TX_DONE = 'd4; - localparam TR_RX_START = 'd5; - localparam TR_RX_WAITEDGE = 'd6; - localparam TR_RX_DONE = 'd7; - - reg [3:0] tr_state; - - always @(posedge clk) begin - rx_word_done <= 0; - tx_word_done <= 0; - tx_word_start_1 <= tx_word_start; - case(tr_state) - TR_IDLE: begin - tr_bit <= 0; - tr_cnt <= 0; - pad_1wire <= 1'bZ; - if(tx_word_start & ~tx_word_start_1) begin - // transmit word - tx_word_shift <= tx_word; - tr_state <= TR_TX_START; - end - if(pad_1wire_f) begin - // receive word - tr_state <= TR_RX_START; - end - end - // transmit 32bit - TR_TX_START: begin - // insert delay - tr_cnt <= tr_cnt + 1'b1; - if(&tr_cnt) begin - // drive from tristate(high) to explicitly high to prevent glitching - pad_1wire <= 1'b1; - tr_state <= TR_TX_CONTINUE; - end - end - TR_TX_CONTINUE: begin - tr_cnt <= tr_cnt + 1'b1; - case(tr_cnt) - 0: begin - pad_1wire <= 1'b0; - end - (BITLEN/3): begin - pad_1wire <= tx_word_shift[31]; - end - (BITLEN*2/3): begin - pad_1wire <= 1'b1; - end - (BITLEN-1): begin - tr_cnt <= 0; - tx_word_shift <= {tx_word_shift[30:0], 1'b1}; - tr_bit <= tr_bit + 1'b1; - if(tr_bit == 31) begin - tr_state <= TR_TX_DONE; - end - end - endcase - end - TR_TX_DONE: begin - tx_word_done <= 1; - tr_state <= TR_IDLE; - end - // receive 32bit - TR_RX_START: begin - tr_cnt <= tr_cnt + 1'b1; - case(tr_cnt) - (BITLEN/2-4): begin - rx_word_shift <= {rx_word_shift[30:0], pad_1wire_s}; - end - (BITLEN*5/6): begin - tr_cnt <= 0; - // wait for next falling edge - tr_state <= TR_RX_WAITEDGE; - tr_bit <= tr_bit + 1'b1; - if(tr_bit == 31) begin - // if this is bit32, don't wait and finish - tr_state <= TR_RX_DONE; - end - end - endcase - end - TR_RX_WAITEDGE: begin - if(pad_1wire_f) begin - tr_state <= TR_RX_START; - end - end - TR_RX_DONE: begin - rx_word <= rx_word_shift; - rx_word_done <= 1; - tr_state <= TR_IDLE; - end - default: begin - tr_state <= TR_IDLE; - end - endcase - - if(~reset_n_s | ~reset_tr_n) begin - tr_state <= TR_IDLE; - end - end - -endmodule +// Software License Agreement + +// The software supplied herewith by Analogue Enterprises Limited (the "Company”), +// the Analogue Pocket Framework (“APF”), is provided and licensed to you, the +// Company's customer, solely for use in designing, testing and creating +// applications for use with Company's Products or Services. The software is +// owned by the Company and/or its licensors, and is protected under applicable +// laws, including, but not limited to, U.S. copyright law. All rights are +// reserved. By using the APF code you are agreeing to the terms of the End User +// License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula] +// and incorporated herein by reference. To the extent any use of the APF requires +// application of the MIT License or the GNU General Public License and terms of +// this APF Software License Agreement and EULA are inconsistent with such license, +// the applicable terms of the MIT License or the GNU General Public License, as +// applicable, will prevail. + +// THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED +// WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO, +// ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR +// NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM +// DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE +// MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED, +// THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND +// DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING +// THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR +// ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY +// INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES, +// INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR +// INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY +// OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY +// CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION, +// WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU +// TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH +// YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE +// FULLEST EXTENT PERMITTED BY APPLICABLE LAW. +// +// pad controller +// 2020-08-17 Analogue +// + +`default_nettype none +`timescale 1ns/1ps + +module io_pad_controller + ( + input wire clk, + input wire reset_n, + + inout reg pad_1wire, + + output reg [31:0] cont1_key, + output reg [31:0] cont2_key, + output reg [31:0] cont3_key, + output reg [31:0] cont4_key, + output reg [31:0] cont1_joy, + output reg [31:0] cont2_joy, + output reg [31:0] cont3_joy, + output reg [31:0] cont4_joy, + output reg [15:0] cont1_trig, + output reg [15:0] cont2_trig, + output reg [15:0] cont3_trig, + output reg [15:0] cont4_trig, + + output reg rx_timed_out + ); + + wire reset_n_s; + synch_3 s00(reset_n, reset_n_s, clk); + + wire pad_1wire_s, pad_1wire_r, pad_1wire_f; + synch_3 s01(pad_1wire, pad_1wire_s, clk, pad_1wire_r, pad_1wire_f); + + // + // protocol fsm + // + reg [20:0] rx_timeout; // ~28ms + + reg [15:0] auto_poll_cnt; // 882us + reg auto_poll_queue; + + reg [18:0] heartbeat_cnt; // 7ms + reg heartbeat_queue; + + localparam ST_RESET = 'd0; + localparam ST_IDLE = 'd1; + localparam ST_RX_BUTTON_1 = 'd2; + localparam ST_RX_BUTTON_2 = 'd3; + localparam ST_TX_SCALER = 'd4; + localparam ST_END_TX = 'd5; + + reg [3:0] state; + reg [3:0] cnt; + + always @(posedge clk) begin + tx_word_start <= 0; + + auto_poll_cnt <= auto_poll_cnt + 1'b1; + heartbeat_cnt <= heartbeat_cnt + 1'b1; + + // increment rx timeout, override and reset when idle below + rx_timeout <= rx_timeout + 1'b1; + + case(state) + ST_RESET: begin + reset_tr_n <= 0; + rx_timed_out <= 0; + + if(&rx_timeout[19:0]) begin + state <= ST_IDLE; + end + end + ST_IDLE: begin + // idle state + reset_tr_n <= 1; + rx_timeout <= 0; + cnt <= 0; + if(auto_poll_queue) begin + auto_poll_queue <= 0; + + tx_word_start <= 1; + tx_word <= 32'h4A10000C; + + state <= ST_RX_BUTTON_1; + end + else if(heartbeat_queue) begin + heartbeat_queue <= 0; + + tx_word_start <= 1; + tx_word <= 32'h4AFE0000; + + state <= ST_END_TX; + end + end + // receive button words + ST_RX_BUTTON_1: begin + if(tx_word_done) begin + state <= ST_RX_BUTTON_2; + end + end + ST_RX_BUTTON_2: begin + if(rx_word_done) begin + cnt <= cnt + 1'b1; + case(cnt) + 0: cont1_key <= rx_word; + 1: cont1_joy <= rx_word; + 2: cont1_trig <= rx_word[15:0]; + + 3: cont2_key <= rx_word; + 4: cont2_joy <= rx_word; + 5: cont2_trig <= rx_word[15:0]; + + 6: cont3_key <= rx_word; + 7: cont3_joy <= rx_word; + 8: cont3_trig <= rx_word[15:0]; + + 9: cont4_key <= rx_word; + 10: cont4_joy <= rx_word; + 11: begin + cont4_trig <= rx_word[15:0]; + state <= ST_IDLE; + end + endcase + end + end + // do nothing + ST_END_TX: begin + // done sending, idle again + if(tx_word_done) begin + state <= ST_IDLE; + end + end + endcase + + if(&auto_poll_cnt) begin + auto_poll_queue <= 1; + end + + if(&heartbeat_cnt) begin + heartbeat_queue <= 1; + end + + if(&rx_timeout) begin + // reset protocol FSM which will also reset t/r engine + rx_timed_out <= 1; + rx_timeout <= 0; + state <= ST_RESET; + end + + if(~reset_n_s) begin + state <= ST_RESET; + end + end + + // + // word receive/transmit engine + // + reg reset_tr_n; + localparam BITLEN = 60; + + reg rx_word_done; + reg [31:0] rx_word_shift; + reg [31:0] rx_word; + + reg tx_word_start, tx_word_start_1; + reg tx_word_done; + reg [31:0] tx_word; + reg [31:0] tx_word_shift; + + reg [7:0] tr_cnt; + reg [5:0] tr_bit; + + localparam TR_IDLE = 'd1; + localparam TR_TX_START = 'd2; + localparam TR_TX_CONTINUE = 'd3; + localparam TR_TX_DONE = 'd4; + localparam TR_RX_START = 'd5; + localparam TR_RX_WAITEDGE = 'd6; + localparam TR_RX_DONE = 'd7; + + reg [3:0] tr_state; + + always @(posedge clk) begin + rx_word_done <= 0; + tx_word_done <= 0; + tx_word_start_1 <= tx_word_start; + case(tr_state) + TR_IDLE: begin + tr_bit <= 0; + tr_cnt <= 0; + pad_1wire <= 1'bZ; + if(tx_word_start & ~tx_word_start_1) begin + // transmit word + tx_word_shift <= tx_word; + tr_state <= TR_TX_START; + end + if(pad_1wire_f) begin + // receive word + tr_state <= TR_RX_START; + end + end + // transmit 32bit + TR_TX_START: begin + // insert delay + tr_cnt <= tr_cnt + 1'b1; + if(&tr_cnt) begin + // drive from tristate(high) to explicitly high to prevent glitching + pad_1wire <= 1'b1; + tr_state <= TR_TX_CONTINUE; + end + end + TR_TX_CONTINUE: begin + tr_cnt <= tr_cnt + 1'b1; + case(tr_cnt) + 0: begin + pad_1wire <= 1'b0; + end + (BITLEN/3): begin + pad_1wire <= tx_word_shift[31]; + end + (BITLEN*2/3): begin + pad_1wire <= 1'b1; + end + (BITLEN-1): begin + tr_cnt <= 0; + tx_word_shift <= {tx_word_shift[30:0], 1'b1}; + tr_bit <= tr_bit + 1'b1; + if(tr_bit == 31) begin + tr_state <= TR_TX_DONE; + end + end + endcase + end + TR_TX_DONE: begin + tx_word_done <= 1; + tr_state <= TR_IDLE; + end + // receive 32bit + TR_RX_START: begin + tr_cnt <= tr_cnt + 1'b1; + case(tr_cnt) + (BITLEN/2-4): begin + rx_word_shift <= {rx_word_shift[30:0], pad_1wire_s}; + end + (BITLEN*5/6): begin + tr_cnt <= 0; + // wait for next falling edge + tr_state <= TR_RX_WAITEDGE; + tr_bit <= tr_bit + 1'b1; + if(tr_bit == 31) begin + // if this is bit32, don't wait and finish + tr_state <= TR_RX_DONE; + end + end + endcase + end + TR_RX_WAITEDGE: begin + if(pad_1wire_f) begin + tr_state <= TR_RX_START; + end + end + TR_RX_DONE: begin + rx_word <= rx_word_shift; + rx_word_done <= 1; + tr_state <= TR_IDLE; + end + default: begin + tr_state <= TR_IDLE; + end + endcase + + if(~reset_n_s | ~reset_tr_n) begin + tr_state <= TR_IDLE; + end + end + +endmodule diff --git a/platform/pocket/pkgIndex.tcl b/platform/pocket/pkgIndex.tcl index 177cb01..e1962c7 100644 --- a/platform/pocket/pkgIndex.tcl +++ b/platform/pocket/pkgIndex.tcl @@ -1,68 +1,68 @@ -# ============================================================================== -# SPDX-License-Identifier: CC0-1.0 -# SPDX-FileType: SOURCE -# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors -# ============================================================================== -# @file: pkgIndex.tcl -# @brief: Collection of TCL Functions for the Framework -# ============================================================================== - -source $PLATFORM_ROOT/scripts/functions.tcl - -set ignore_list {} -set pkg_proms {} -set pkg_modules [list \ - "audio" \ - "audio/filters" \ - "video" \ - "interface" \ - "interface/keyboard" \ - "megafunctions" \ - "memory" \ - "peripherals" \ - "support" \ - "helpers" -] - -switch $DEVICE_FAMILY { - "Cyclone V" { - puts "Cyclone V" - } - default { - puts "Unknown Device Family" - } -} - -switch $DEVICE_ID { - "pocket" { - puts "This is an Analogue Pocket - $PLATFORM_ROOT" - } - default { - puts "Unknown Device" - } -} - -foreach folder $pkg_modules { - set platform_files [getHDLFiles "$PLATFORM_ROOT/$folder"] - foreach file $platform_files { - if {$file in $ignore_list} { - continue - } else { - set ext [file extension $file] - set is_pll [string match "pll*" $file] - if {$is_pll && $ext eq ".v"} { - continue - } - set is_mf [string match "mf*" $file] - if {$is_mf && $ext eq ".v"} { - continue - } - switch $ext { - ".sv" { set_global_assignment -name SYSTEMVERILOG_FILE \"$file\" } - ".v" { set_global_assignment -name VERILOG_FILE \"$file\" } - ".vhd" { set_global_assignment -name VHDL_FILE \"$file\" } - ".qip" { set_global_assignment -name QIP_FILE \"$file\" } - } - } - } -} +# ============================================================================== +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileType: SOURCE +# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors +# ============================================================================== +# @file: pkgIndex.tcl +# @brief: Collection of TCL Functions for the Framework +# ============================================================================== + +source $PLATFORM_ROOT/scripts/functions.tcl + +set ignore_list {} +set pkg_proms {} +set pkg_modules [list \ + "audio" \ + "audio/filters" \ + "video" \ + "interface" \ + "interface/keyboard" \ + "megafunctions" \ + "memory" \ + "peripherals" \ + "support" \ + "helpers" +] + +switch $DEVICE_FAMILY { + "Cyclone V" { + puts "Cyclone V" + } + default { + puts "Unknown Device Family" + } +} + +switch $DEVICE_ID { + "pocket" { + puts "This is an Analogue Pocket - $PLATFORM_ROOT" + } + default { + puts "Unknown Device" + } +} + +foreach folder $pkg_modules { + set platform_files [getHDLFiles "$PLATFORM_ROOT/$folder"] + foreach file $platform_files { + if {$file in $ignore_list} { + continue + } else { + set ext [file extension $file] + set is_pll [string match "pll*" $file] + if {$is_pll && $ext eq ".v"} { + continue + } + set is_mf [string match "mf*" $file] + if {$is_mf && $ext eq ".v"} { + continue + } + switch $ext { + ".sv" { set_global_assignment -name SYSTEMVERILOG_FILE \"$file\" } + ".v" { set_global_assignment -name VERILOG_FILE \"$file\" } + ".vhd" { set_global_assignment -name VHDL_FILE \"$file\" } + ".qip" { set_global_assignment -name QIP_FILE \"$file\" } + } + } + } +} diff --git a/platform/pocket/scripts/functions.tcl b/platform/pocket/scripts/functions.tcl index dc0b1a3..41d971b 100644 --- a/platform/pocket/scripts/functions.tcl +++ b/platform/pocket/scripts/functions.tcl @@ -1,375 +1,375 @@ -# ============================================================================== -# SPDX-License-Identifier: CC0-1.0 -# SPDX-FileType: SOURCE -# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors -# ============================================================================== -# @file: functions.tcl -# @brief: Collection of TCL Functions for the Framework -# ============================================================================== -package require Tcl -package require json -package require fileutil - -puts "Functions Loaded!" - -# @brief: Make an HTTP Request -# Note: HTTP/TLS package is outdated use cURL instead -# Example: -# set http_data "[httpGet https://example.com]" -proc httpGet {url} { - set command "curl -s $url" - set http_data [exec {*}$command] - return $http_data -} - -# @brief: Get a JSON response via HTTP -# Example: -# set json_data "[httpGetJSON https://www.howsmyssl.com/a/check]" -# set tls_version [dict get $json_data tls_version] -proc httpGetJSON {url} { - set http_data "[httpGet $url]" - set json_data [json::json2dict $http_data] - return $json_data -} - -# @brief: Get a JSON response via HTTP -# Example: -# set tag_name "[gitLatestReleaseTag "opengateware" "arcade-congo"]" -proc gitLatestReleaseTag {owner repo} { - set json_data "[httpGetJSON https://api.github.com/repos/$owner/$repo/releases/latest]" - set tag_name [dict get $json_data tag_name] - return $tag_name -} - -# @brief: Get HDL Files (SV, V, VHD and QIP) -proc getHDLFiles {folder} { - set file_list [glob -nocomplain -types f [file join $folder *.{sv,v,vhd,qip}]] - if {[llength $file_list] == 0} { - puts "No files found with the specified extensions in directory: $PLATFORM_ROOT" - } else { - set result {} - foreach file $file_list { - lappend result $file - } - return $result - } -} - -# @brief: Get the current date in the format YYYYMMDD -# (see: https://www.intel.com/content/www/us/en/support/programmable/support-resources/design-examples/quartus/tcl-date-time-stamp.html) -proc getDate {} { - set buildDate [ clock format [ clock seconds ] -format %Y%m%d ] - return $buildDate -} - -# @brief: Get the current date in the format YYYY-MM-DD -proc getDateDashed {} { - set buildDate [ clock format [ clock seconds ] -format %Y-%m-%d ] - return $buildDate -} - -# @brief: Get the current time in the format HHMMSS -proc getTime {} { - set buildTime [ clock format [ clock seconds ] -format %H%M%S ] - return $buildTime -} - -# @brief: Get the git hashtag for this project -proc getDigest {} { - set buildHash "" - if {[catch {exec git rev-parse --short=8 HEAD}]} { - puts "No git version control in the project" - set buildHash FEEDC0DE - } else { - set buildHash [exec git rev-parse --short=8 HEAD] - } - return $buildHash -} - -# @brief: Get the git hashtag for this project -proc getLastTag {} { - set buildTag "" - if {[catch {exec git describe --abbrev=0 --tags}]} { - puts "No git tag in the project" - set buildTag "0.0.0" - } else { - set buildTag [exec git describe --abbrev=0 --tags] - } - return $buildTag -} - -# @brief: Creates a folder if it doesn't already exist -proc createFolder {folder_path} { - if {![file isdirectory $folder_path]} { - file mkdir $folder_path - } -} - -# @brief: Search and Replace a string -# Example: -# set my_string "hello world" -# set new_string [searchReplace $my_string "world" "TCL"] -proc searchReplace {string pattern replacement} { - set result [::tcl::string::map [list $pattern $replacement] $string] - return $result -} - -# @brief: Copies the input file to the output file -proc copyFile {input_path output_path} { - file copy -force $input_file $output_file -} - -# @brief: Generate a Build ID -# Create a build_id.vh file containing build date and git commit digest -proc generateBuildID {} { - # Set the metadata for this project - set buildDate [getDate] - set buildHash [getDigest] - - # Create a Verilog Header file for output - set outputFileName "../target/pocket/build_id.vh" - set outputFile [open $outputFileName "w"] - - # Output the Verilog source - puts $outputFile "// Build ID Verilog Module" - puts $outputFile "`define BUILD_DATE \"$buildDate\"" - puts $outputFile "`define BUILD_HASH \"$buildHash\"" - close $outputFile - - # Send confirmation message to the Messages window - post_message "Build ID Verilog Header File generated: [pwd]/$outputFileName" -} - -# @brief: Generate a JTAG Chain Description File. -# Create a .cdf file to be used with Quartus Prime Programmer -proc generateCDF {revision outpath device use_hps} { - set outputFileName "$revision.cdf" - set outputFile [open $outputFileName "w"] - - puts $outputFile "JedecChain;" - puts $outputFile " FileRevision(JESD32A);" - puts $outputFile " DefaultMfr(6E);" - puts $outputFile "" - if {$use_hps} { - puts $outputFile " P ActionCode(Ign)" - puts $outputFile " Device PartName(SOCVHPS) MfrSpec(OpMask(0));" - } - puts $outputFile " P ActionCode(Cfg)" - puts $outputFile " Device PartName($device) Path(\"$outpath/\") File(\"$revision.sof\") MfrSpec(OpMask(1));" - puts $outputFile "ChainEnd;" - puts $outputFile "" - puts $outputFile "AlteraBegin;" - puts $outputFile " ChainType(JTAG);" - puts $outputFile "AlteraEnd;" - close $outputFile - - # Send confirmation message to the Messages window - post_message "JTAG Chain Description File generated: [pwd]/$outputFileName" -} - -# @brief: Generate a Build ID -# Create a build_id.mif file containing build date, time and unique id -proc generateBuildID_MIF {} { - set buildDate [getDate] - set buildTime [getTime] - set buildUnique [expr {int(rand()*(4294967295))}] - - set buildDateNoLeadingZeros [string trimleft $buildDate "0"] - set buildTimeNoLeadingZeros [string trimleft $buildTime "0"] - set buildDate4Byte [format "%08d" $buildDateNoLeadingZeros] - set buildTime4Byte [format "%08d" $buildTimeNoLeadingZeros] - set buildUnique4Byte [format "%08x" $buildUnique] - - # Create a Memory Initialization File for output - set outputFileName "../target/pocket/build_id.mif" - set outputFile [open $outputFileName "w"] - - # Output the MIF file - puts $outputFile "-- begin_signature" - puts $outputFile "-- Build_ID" - puts $outputFile "-- end_signature" - puts $outputFile "DEPTH=256;" - puts $outputFile "WIDTH=32;" - puts $outputFile "" - puts $outputFile "ADDRESS_RADIX=HEX;" - puts $outputFile "DATA_RADIX=HEX;" - puts $outputFile "" - puts $outputFile "CONTENT" - puts $outputFile "BEGIN" - puts $outputFile "\t0E0 :\t$buildDate4Byte;" - puts $outputFile "\t0E1 :\t$buildTime4Byte;" - puts $outputFile "\t0E2 :\t$buildUnique4Byte;" - puts $outputFile "END;" - - # Close file to complete write - close $outputFile - - # Send confirmation message to the Messages window - post_message "Build ID Memory Initialization File generated: [pwd]/$outputFileName" -} - -# @brief: Generate build_id.vh if doesn't exists (avoid having to start compilation to execute pre-flow) -proc checkBuildID {} { - # set outputVerilog "../target/pocket/build_id.vh" - # if {![file exists $outputVerilog]} { generateBuildID } - set outputMIF "../target/pocket/build_id.mif" - if {![file exists $outputMIF]} { generateBuildID_MIF } -} - -# @brief: Open binary file and load into a Hex value string -proc readBinaryFile {file_path} { - set file [open $file_path rb] - set content [read $file] - close $file - - set bytes [list] - foreach byte [split $content ""] { - lappend bytes [format "%02X" [scan $byte %c]] - } - - return $bytes -} - -# @brief: Reverse bytes required for the Analogue Pocket -proc reverseBits {bytes} { - set reversed_values [list] - foreach byte $bytes { - set decimal_value [scan $byte %x] - set reversed_decimal_value 0 - for {set i 0} {$i < 8} {incr i} { - set bit [expr {($decimal_value >> $i) & 1}] - set reversed_decimal_value [expr {($reversed_decimal_value << 1) | $bit}] - } - lappend reversed_values [format "%02X" $reversed_decimal_value] - } - return $reversed_values -} - -# @brief: Convert hex values to binary and save into a file -proc saveBinaryFile {bytes output_file} { - set file [open $output_file wb] - foreach byte $bytes { - set byte [binary format c [scan $byte %x]] - puts -nonewline $file $byte - } - close $file - post_message "Reversed Bitstream File generated: [pwd]/$output_file." -} - -# @brief: Create a reversed RBF required for the Analogue Pocket -proc reverseRBF {revision outpath} { - global BUILD_ROOT - global DEVICE_ID - createFolder $BUILD_ROOT - set bytes [readBinaryFile "$outpath/$revision.rbf"] - set bytes_r [reverseBits $bytes] - set rbf_name [searchReplace $revision "_$DEVICE_ID" ""] - set target_dir [getCoreFolderName] - if {[string equal "" $target_dir]} { - saveBinaryFile $bytes_r "$BUILD_ROOT/$rbf_name.rbf_r" - } else { - saveBinaryFile $bytes_r "$BUILD_ROOT/Cores/$target_dir/$rbf_name.rbf_r" - } -} - -# @brief: Check if file contains a file extension that should be ignored -proc isExtIgnored {file_path} { - set ignore_extensions {.gitkeep .png .rom} - set file_extension [string tolower [file extension $file_path]] - if {[lsearch -exact $ignore_extensions $file_extension] != -1} { - return 1;# File is ignored - } else { - return 0;# File is not ignored - } -} - -# @brief: Create a reversed RBF required for the Analogue Pocket -proc getRelativePath {base_path path} { - set base_parts [split $base_path "/"] - set path_parts [split $path "/"] - - while {[llength $base_parts] > 0 && [llength $path_parts] > 0 && [lindex $base_parts 0] eq [lindex $path_parts 0]} { - set base_parts [lrange $base_parts 1 end] - set path_parts [lrange $path_parts 1 end] - } - - set relative_path [concat [lrepeat [llength $base_parts] ".."] $path_parts] - return [join $relative_path "/"] -} - -# @brief: Copy the entire directory structure and files from the source -# to the target directory recursively, creating any necessary folders -# along the way -proc copyDirectory {source_dir target_dir} { - if {![file isdirectory $target_dir]} { - file mkdir $target_dir - } - - set files [glob -nocomplain -directory $source_dir -type f *] - foreach file $files { - set relative_path [getRelativePath $source_dir $file] - set target_path [file join $target_dir $relative_path] - set target_dir_path [file dirname $target_path] - - if {![file isdirectory $target_dir_path]} { - file mkdir $target_dir_path - } - - if {[isExtIgnored $file]} { - puts "File ignored: $file" - continue - } else { - file copy -force $file $target_path - } - } - - set subdirs [glob -nocomplain -directory $source_dir -type d *] - foreach subdir $subdirs { - set relative_path [getRelativePath $source_dir $subdir] - set target_path [file join $target_dir $relative_path] - - copyDirectory $subdir $target_path - } -} - -# @brief: Get the folder from BUILD_ROOT/Cores -proc getCoreFolderName {} { - global BUILD_ROOT - set cores_path "$BUILD_ROOT/Cores" - set cores_folders [glob -nocomplain -directory $cores_path -type d *] - set num_cores [llength $cores_folders] - - if {$num_cores == 1} { - set folder_name [file tail [lindex $cores_folders 0]] - return $folder_name - } elseif {$num_cores == 0} { - post_message "No folder found inside $cores_path" - return "" - } else { - post_message "Multiple folders found inside $cores_path" - return "" - } -} - -# @brief: Update the core.json file with Version and Release Date -# Example: -# updateVersionReleaseDate "1.0.0" -proc updateVersionReleaseDate {version} { - set file_path "core.json" - set release_date [getDateDashed] - - if {[file exists $file_path]} { - set file_handle [open $file_path "r+"] - set file_content [read $file_handle] - - set updated_content [string map [list "<%- VERSION %>" $version "<%- RELEASE_DATE %>" $release_date] $file_content] - - seek $file_handle 0 - puts -nonewline $file_handle $updated_content - close $file_handle - - puts "Updated $file_path with version: $version and release date: $release_date." - } else { - puts "File $file_path does not exist." - } -} +# ============================================================================== +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileType: SOURCE +# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors +# ============================================================================== +# @file: functions.tcl +# @brief: Collection of TCL Functions for the Framework +# ============================================================================== +package require Tcl +package require json +package require fileutil + +puts "Functions Loaded!" + +# @brief: Make an HTTP Request +# Note: HTTP/TLS package is outdated use cURL instead +# Example: +# set http_data "[httpGet https://example.com]" +proc httpGet {url} { + set command "curl -s $url" + set http_data [exec {*}$command] + return $http_data +} + +# @brief: Get a JSON response via HTTP +# Example: +# set json_data "[httpGetJSON https://www.howsmyssl.com/a/check]" +# set tls_version [dict get $json_data tls_version] +proc httpGetJSON {url} { + set http_data "[httpGet $url]" + set json_data [json::json2dict $http_data] + return $json_data +} + +# @brief: Get a JSON response via HTTP +# Example: +# set tag_name "[gitLatestReleaseTag "opengateware" "arcade-congo"]" +proc gitLatestReleaseTag {owner repo} { + set json_data "[httpGetJSON https://api.github.com/repos/$owner/$repo/releases/latest]" + set tag_name [dict get $json_data tag_name] + return $tag_name +} + +# @brief: Get HDL Files (SV, V, VHD and QIP) +proc getHDLFiles {folder} { + set file_list [glob -nocomplain -types f [file join $folder *.{sv,v,vhd,qip}]] + if {[llength $file_list] == 0} { + puts "No files found with the specified extensions in directory: $PLATFORM_ROOT" + } else { + set result {} + foreach file $file_list { + lappend result $file + } + return $result + } +} + +# @brief: Get the current date in the format YYYYMMDD +# (see: https://www.intel.com/content/www/us/en/support/programmable/support-resources/design-examples/quartus/tcl-date-time-stamp.html) +proc getDate {} { + set buildDate [ clock format [ clock seconds ] -format %Y%m%d ] + return $buildDate +} + +# @brief: Get the current date in the format YYYY-MM-DD +proc getDateDashed {} { + set buildDate [ clock format [ clock seconds ] -format %Y-%m-%d ] + return $buildDate +} + +# @brief: Get the current time in the format HHMMSS +proc getTime {} { + set buildTime [ clock format [ clock seconds ] -format %H%M%S ] + return $buildTime +} + +# @brief: Get the git hashtag for this project +proc getDigest {} { + set buildHash "" + if {[catch {exec git rev-parse --short=8 HEAD}]} { + puts "No git version control in the project" + set buildHash FEEDC0DE + } else { + set buildHash [exec git rev-parse --short=8 HEAD] + } + return $buildHash +} + +# @brief: Get the git hashtag for this project +proc getLastTag {} { + set buildTag "" + if {[catch {exec git describe --abbrev=0 --tags}]} { + puts "No git tag in the project" + set buildTag "0.0.0" + } else { + set buildTag [exec git describe --abbrev=0 --tags] + } + return $buildTag +} + +# @brief: Creates a folder if it doesn't already exist +proc createFolder {folder_path} { + if {![file isdirectory $folder_path]} { + file mkdir $folder_path + } +} + +# @brief: Search and Replace a string +# Example: +# set my_string "hello world" +# set new_string [searchReplace $my_string "world" "TCL"] +proc searchReplace {string pattern replacement} { + set result [::tcl::string::map [list $pattern $replacement] $string] + return $result +} + +# @brief: Copies the input file to the output file +proc copyFile {input_path output_path} { + file copy -force $input_file $output_file +} + +# @brief: Generate a Build ID +# Create a build_id.vh file containing build date and git commit digest +proc generateBuildID {} { + # Set the metadata for this project + set buildDate [getDate] + set buildHash [getDigest] + + # Create a Verilog Header file for output + set outputFileName "../target/pocket/build_id.vh" + set outputFile [open $outputFileName "w"] + + # Output the Verilog source + puts $outputFile "// Build ID Verilog Module" + puts $outputFile "`define BUILD_DATE \"$buildDate\"" + puts $outputFile "`define BUILD_HASH \"$buildHash\"" + close $outputFile + + # Send confirmation message to the Messages window + post_message "Build ID Verilog Header File generated: [pwd]/$outputFileName" +} + +# @brief: Generate a JTAG Chain Description File. +# Create a .cdf file to be used with Quartus Prime Programmer +proc generateCDF {revision outpath device use_hps} { + set outputFileName "$revision.cdf" + set outputFile [open $outputFileName "w"] + + puts $outputFile "JedecChain;" + puts $outputFile " FileRevision(JESD32A);" + puts $outputFile " DefaultMfr(6E);" + puts $outputFile "" + if {$use_hps} { + puts $outputFile " P ActionCode(Ign)" + puts $outputFile " Device PartName(SOCVHPS) MfrSpec(OpMask(0));" + } + puts $outputFile " P ActionCode(Cfg)" + puts $outputFile " Device PartName($device) Path(\"$outpath/\") File(\"$revision.sof\") MfrSpec(OpMask(1));" + puts $outputFile "ChainEnd;" + puts $outputFile "" + puts $outputFile "AlteraBegin;" + puts $outputFile " ChainType(JTAG);" + puts $outputFile "AlteraEnd;" + close $outputFile + + # Send confirmation message to the Messages window + post_message "JTAG Chain Description File generated: [pwd]/$outputFileName" +} + +# @brief: Generate a Build ID +# Create a build_id.mif file containing build date, time and unique id +proc generateBuildID_MIF {} { + set buildDate [getDate] + set buildTime [getTime] + set buildUnique [expr {int(rand()*(4294967295))}] + + set buildDateNoLeadingZeros [string trimleft $buildDate "0"] + set buildTimeNoLeadingZeros [string trimleft $buildTime "0"] + set buildDate4Byte [format "%08d" $buildDateNoLeadingZeros] + set buildTime4Byte [format "%08d" $buildTimeNoLeadingZeros] + set buildUnique4Byte [format "%08x" $buildUnique] + + # Create a Memory Initialization File for output + set outputFileName "../target/pocket/build_id.mif" + set outputFile [open $outputFileName "w"] + + # Output the MIF file + puts $outputFile "-- begin_signature" + puts $outputFile "-- Build_ID" + puts $outputFile "-- end_signature" + puts $outputFile "DEPTH=256;" + puts $outputFile "WIDTH=32;" + puts $outputFile "" + puts $outputFile "ADDRESS_RADIX=HEX;" + puts $outputFile "DATA_RADIX=HEX;" + puts $outputFile "" + puts $outputFile "CONTENT" + puts $outputFile "BEGIN" + puts $outputFile "\t0E0 :\t$buildDate4Byte;" + puts $outputFile "\t0E1 :\t$buildTime4Byte;" + puts $outputFile "\t0E2 :\t$buildUnique4Byte;" + puts $outputFile "END;" + + # Close file to complete write + close $outputFile + + # Send confirmation message to the Messages window + post_message "Build ID Memory Initialization File generated: [pwd]/$outputFileName" +} + +# @brief: Generate build_id.vh if doesn't exists (avoid having to start compilation to execute pre-flow) +proc checkBuildID {} { + # set outputVerilog "../target/pocket/build_id.vh" + # if {![file exists $outputVerilog]} { generateBuildID } + set outputMIF "../target/pocket/build_id.mif" + if {![file exists $outputMIF]} { generateBuildID_MIF } +} + +# @brief: Open binary file and load into a Hex value string +proc readBinaryFile {file_path} { + set file [open $file_path rb] + set content [read $file] + close $file + + set bytes [list] + foreach byte [split $content ""] { + lappend bytes [format "%02X" [scan $byte %c]] + } + + return $bytes +} + +# @brief: Reverse bytes required for the Analogue Pocket +proc reverseBits {bytes} { + set reversed_values [list] + foreach byte $bytes { + set decimal_value [scan $byte %x] + set reversed_decimal_value 0 + for {set i 0} {$i < 8} {incr i} { + set bit [expr {($decimal_value >> $i) & 1}] + set reversed_decimal_value [expr {($reversed_decimal_value << 1) | $bit}] + } + lappend reversed_values [format "%02X" $reversed_decimal_value] + } + return $reversed_values +} + +# @brief: Convert hex values to binary and save into a file +proc saveBinaryFile {bytes output_file} { + set file [open $output_file wb] + foreach byte $bytes { + set byte [binary format c [scan $byte %x]] + puts -nonewline $file $byte + } + close $file + post_message "Reversed Bitstream File generated: [pwd]/$output_file." +} + +# @brief: Create a reversed RBF required for the Analogue Pocket +proc reverseRBF {revision outpath} { + global BUILD_ROOT + global DEVICE_ID + createFolder $BUILD_ROOT + set bytes [readBinaryFile "$outpath/$revision.rbf"] + set bytes_r [reverseBits $bytes] + set rbf_name [searchReplace $revision "_$DEVICE_ID" ""] + set target_dir [getCoreFolderName] + if {[string equal "" $target_dir]} { + saveBinaryFile $bytes_r "$BUILD_ROOT/$rbf_name.rbf_r" + } else { + saveBinaryFile $bytes_r "$BUILD_ROOT/Cores/$target_dir/$rbf_name.rbf_r" + } +} + +# @brief: Check if file contains a file extension that should be ignored +proc isExtIgnored {file_path} { + set ignore_extensions {.gitkeep .png .rom} + set file_extension [string tolower [file extension $file_path]] + if {[lsearch -exact $ignore_extensions $file_extension] != -1} { + return 1;# File is ignored + } else { + return 0;# File is not ignored + } +} + +# @brief: Create a reversed RBF required for the Analogue Pocket +proc getRelativePath {base_path path} { + set base_parts [split $base_path "/"] + set path_parts [split $path "/"] + + while {[llength $base_parts] > 0 && [llength $path_parts] > 0 && [lindex $base_parts 0] eq [lindex $path_parts 0]} { + set base_parts [lrange $base_parts 1 end] + set path_parts [lrange $path_parts 1 end] + } + + set relative_path [concat [lrepeat [llength $base_parts] ".."] $path_parts] + return [join $relative_path "/"] +} + +# @brief: Copy the entire directory structure and files from the source +# to the target directory recursively, creating any necessary folders +# along the way +proc copyDirectory {source_dir target_dir} { + if {![file isdirectory $target_dir]} { + file mkdir $target_dir + } + + set files [glob -nocomplain -directory $source_dir -type f *] + foreach file $files { + set relative_path [getRelativePath $source_dir $file] + set target_path [file join $target_dir $relative_path] + set target_dir_path [file dirname $target_path] + + if {![file isdirectory $target_dir_path]} { + file mkdir $target_dir_path + } + + if {[isExtIgnored $file]} { + puts "File ignored: $file" + continue + } else { + file copy -force $file $target_path + } + } + + set subdirs [glob -nocomplain -directory $source_dir -type d *] + foreach subdir $subdirs { + set relative_path [getRelativePath $source_dir $subdir] + set target_path [file join $target_dir $relative_path] + + copyDirectory $subdir $target_path + } +} + +# @brief: Get the folder from BUILD_ROOT/Cores +proc getCoreFolderName {} { + global BUILD_ROOT + set cores_path "$BUILD_ROOT/Cores" + set cores_folders [glob -nocomplain -directory $cores_path -type d *] + set num_cores [llength $cores_folders] + + if {$num_cores == 1} { + set folder_name [file tail [lindex $cores_folders 0]] + return $folder_name + } elseif {$num_cores == 0} { + post_message "No folder found inside $cores_path" + return "" + } else { + post_message "Multiple folders found inside $cores_path" + return "" + } +} + +# @brief: Update the core.json file with Version and Release Date +# Example: +# updateVersionReleaseDate "1.0.0" +proc updateVersionReleaseDate {version} { + set file_path "core.json" + set release_date [getDateDashed] + + if {[file exists $file_path]} { + set file_handle [open $file_path "r+"] + set file_content [read $file_handle] + + set updated_content [string map [list "<%- VERSION %>" $version "<%- RELEASE_DATE %>" $release_date] $file_content] + + seek $file_handle 0 + puts -nonewline $file_handle $updated_content + close $file_handle + + puts "Updated $file_path with version: $version and release date: $release_date." + } else { + puts "File $file_path does not exist." + } +} diff --git a/platform/pocket/scripts/post_flow.tcl b/platform/pocket/scripts/post_flow.tcl index 29abd4b..e73e6d1 100644 --- a/platform/pocket/scripts/post_flow.tcl +++ b/platform/pocket/scripts/post_flow.tcl @@ -1,36 +1,36 @@ -# ============================================================================== -# SPDX-License-Identifier: CC0-1.0 -# SPDX-FileType: SOURCE -# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors -# ============================================================================== -# @file: post-flow.tcl -# @brief: POST_FLOW_SCRIPT_FILE - Runs after a flow finishes -# ============================================================================== - -source ../platform/pocket/scripts/functions.tcl - -set project_name [lindex $quartus(args) 1] -set revision [lindex $quartus(args) 2] - -if {[project_exists $project_name]} { - if {[string equal "" $revision]} { - project_open $project_name -revision [get_current_revision $project_name] - } else { - project_open $project_name -revision $revision - } -} else { - post_message -type error "Project $project_name does not exist" - exit -} - -set device [get_global_assignment -name DEVICE] -set outpath [get_global_assignment -name PROJECT_OUTPUT_DIRECTORY] -set device_hps [get_parameter -name NSX_DEVICE_USE_HPS] -set use_hps [expr {$device_hps eq "ON" ? 1 : 0}] - -if [is_project_open] { - project_close -} - -generateCDF $revision $outpath $device $use_hps +# ============================================================================== +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileType: SOURCE +# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors +# ============================================================================== +# @file: post-flow.tcl +# @brief: POST_FLOW_SCRIPT_FILE - Runs after a flow finishes +# ============================================================================== + +source ../platform/pocket/scripts/functions.tcl + +set project_name [lindex $quartus(args) 1] +set revision [lindex $quartus(args) 2] + +if {[project_exists $project_name]} { + if {[string equal "" $revision]} { + project_open $project_name -revision [get_current_revision $project_name] + } else { + project_open $project_name -revision $revision + } +} else { + post_message -type error "Project $project_name does not exist" + exit +} + +set device [get_global_assignment -name DEVICE] +set outpath [get_global_assignment -name PROJECT_OUTPUT_DIRECTORY] +set device_hps [get_parameter -name NSX_DEVICE_USE_HPS] +set use_hps [expr {$device_hps eq "ON" ? 1 : 0}] + +if [is_project_open] { + project_close +} + +generateCDF $revision $outpath $device $use_hps reverseRBF $revision $outpath \ No newline at end of file diff --git a/platform/pocket/scripts/pre_flow.tcl b/platform/pocket/scripts/pre_flow.tcl index a4e157a..4009176 100644 --- a/platform/pocket/scripts/pre_flow.tcl +++ b/platform/pocket/scripts/pre_flow.tcl @@ -1,12 +1,12 @@ -# ============================================================================== -# SPDX-License-Identifier: CC0-1.0 -# SPDX-FileType: SOURCE -# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors -# ============================================================================== -# @file: pre-flow.tcl -# @brief: PRE_FLOW_SCRIPT_FILE - Runs before a flow starts -# ============================================================================== - -source ../platform/pocket/scripts/functions.tcl - -generateBuildID_MIF +# ============================================================================== +# SPDX-License-Identifier: CC0-1.0 +# SPDX-FileType: SOURCE +# SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors +# ============================================================================== +# @file: pre-flow.tcl +# @brief: PRE_FLOW_SCRIPT_FILE - Runs before a flow starts +# ============================================================================== + +source ../platform/pocket/scripts/functions.tcl + +generateBuildID_MIF diff --git a/platform/pocket/support/autofire.sv b/platform/pocket/support/autofire.sv index 1df90de..c5d14a8 100644 --- a/platform/pocket/support/autofire.sv +++ b/platform/pocket/support/autofire.sv @@ -1,75 +1,75 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Autofire/Turbo Button Controller -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ -// This module provides an "autofire" or "turbo" feature typically found in -// gaming controllers. When enabled, it automatically toggles the state of -// a button output at a user-defined rate, simulating rapid button presses -// without the need for manual input. -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module autofire - #( - parameter CLK = 12_000_000 //! System clock frequency in Hz. Default value is 12MHz. - ) ( - // Clock and Reset - input logic clk, //! System Clock - // Control - input logic enable, //! Control input to enable or disable the autofire feature - input logic [5:0] rate, //! User-defined rate input (0-63) indicating how many times the autofire should toggle per second - // Button In/Out - input logic btn_in, //! Input representing the original state of the button - output logic btn_out //! Output representing the toggled state when autofire is enabled or the original state when disabled - ); - - integer threshold = CLK / (2 * rate); - integer counter = 0; - logic btn_state = 0; - - always_ff @(posedge clk) begin : handleButton - if (enable) begin - if (counter >= threshold) begin - btn_state <= ~btn_state; // Toggle the state when we reach the threshold. - counter <= 0; // Reset the counter. - end - else begin - counter <= counter + 1; // Increment the counter. - end - end - else begin - counter <= 0; - btn_state <= btn_in; // Directly pass the button state if not in autofire mode. - end - end - - assign btn_out = btn_state; - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Autofire/Turbo Button Controller +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ +// This module provides an "autofire" or "turbo" feature typically found in +// gaming controllers. When enabled, it automatically toggles the state of +// a button output at a user-defined rate, simulating rapid button presses +// without the need for manual input. +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module autofire + #( + parameter CLK = 12_000_000 //! System clock frequency in Hz. Default value is 12MHz. + ) ( + // Clock and Reset + input logic clk, //! System Clock + // Control + input logic enable, //! Control input to enable or disable the autofire feature + input logic [5:0] rate, //! User-defined rate input (0-63) indicating how many times the autofire should toggle per second + // Button In/Out + input logic btn_in, //! Input representing the original state of the button + output logic btn_out //! Output representing the toggled state when autofire is enabled or the original state when disabled + ); + + integer threshold = CLK / (2 * rate); + integer counter = 0; + logic btn_state = 0; + + always_ff @(posedge clk) begin : handleButton + if (enable) begin + if (counter >= threshold) begin + btn_state <= ~btn_state; // Toggle the state when we reach the threshold. + counter <= 0; // Reset the counter. + end + else begin + counter <= counter + 1; // Increment the counter. + end + end + else begin + counter <= 0; + btn_state <= btn_in; // Directly pass the button state if not in autofire mode. + end + end + + assign btn_out = btn_state; + +endmodule diff --git a/platform/pocket/support/data_io.sv b/platform/pocket/support/data_io.sv index 7118d03..247ac4c 100644 --- a/platform/pocket/support/data_io.sv +++ b/platform/pocket/support/data_io.sv @@ -1,107 +1,107 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Generic Data I/O for APF bridge -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module data_io - #( - parameter MASK = 0, //! Upper 4 bits of address - parameter AW = 27, //! Address Width - parameter DW = 8, //! Data Width (8 or 16 bits) - parameter DELAY = 4, //! Number of clock cycles to delay each write output - parameter HOLD = 1 //! Number of clock cycles to hold the ioctl_wr signal high - ) ( - input logic clk_74a, - input logic clk_memory, - // Pocket Bridge Slots - input logic dataslot_requestwrite, - input logic [15:0] dataslot_requestwrite_id, - input logic dataslot_allcomplete, - // Pocket Bridge - input logic bridge_endian_little, - input logic [31:0] bridge_addr, - input logic bridge_wr, - input logic [31:0] bridge_wr_data, - // MPU <-> FPGA - output logic ioctl_download = 0, // signal indicating an active download - output logic [15:0] ioctl_index, // slot index used to upload the file - output logic ioctl_wr, - output logic [AW-1:0] ioctl_addr, - output logic [DW-1:0] ioctl_data - ); - - //! ------------------------------------------------------------------------ - //! Download Signal Handler - //! ------------------------------------------------------------------------ - reg ioctl_download_r = 0; - wire ioctl_download_s; - wire [15:0] ioctl_index_s; - - always_ff @(posedge clk_74a) begin - if (dataslot_requestwrite) begin ioctl_download_r <= 1; end - else if(dataslot_allcomplete) begin ioctl_download_r <= 0; end - end - - //! ------------------------------------------------------------------------ - //! Sync and Assign Outputs - //! ------------------------------------------------------------------------ - synch_3 sync_io_dl(ioctl_download_r, ioctl_download_s, clk_memory); - synch_3 #(.WIDTH(16)) sync_wr_id(dataslot_requestwrite_id, ioctl_index_s, clk_memory); - - assign ioctl_download = ioctl_download_s; - assign ioctl_index = ioctl_index_s; - - //! ------------------------------------------------------------------------ - //! MPU -> FPGA Download - //! ------------------------------------------------------------------------ - localparam WORD_SIZE = DW == 16 ? 2 : 1; - - data_loader #( - .ADDRESS_MASK_UPPER_4 ( MASK ), - .WRITE_MEM_CLOCK_DELAY ( DELAY ), - .WRITE_MEM_EN_CYCLE_LENGTH ( HOLD ), - .ADDRESS_SIZE ( AW ), - .OUTPUT_WORD_SIZE ( WORD_SIZE ) - ) data_loader_in ( - .clk_74a ( clk_74a ), - .clk_memory ( clk_memory ), - - .bridge_wr ( bridge_wr ), - .bridge_endian_little ( bridge_endian_little ), - .bridge_addr ( bridge_addr ), - .bridge_wr_data ( bridge_wr_data ), - - .write_en ( ioctl_wr ), - .write_addr ( ioctl_addr ), - .write_data ( ioctl_data ) - ); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Generic Data I/O for APF bridge +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module data_io + #( + parameter MASK = 0, //! Upper 4 bits of address + parameter AW = 27, //! Address Width + parameter DW = 8, //! Data Width (8 or 16 bits) + parameter DELAY = 4, //! Number of clock cycles to delay each write output + parameter HOLD = 1 //! Number of clock cycles to hold the ioctl_wr signal high + ) ( + input logic clk_74a, + input logic clk_memory, + // Pocket Bridge Slots + input logic dataslot_requestwrite, + input logic [15:0] dataslot_requestwrite_id, + input logic dataslot_allcomplete, + // Pocket Bridge + input logic bridge_endian_little, + input logic [31:0] bridge_addr, + input logic bridge_wr, + input logic [31:0] bridge_wr_data, + // MPU <-> FPGA + output logic ioctl_download = 0, // signal indicating an active download + output logic [15:0] ioctl_index, // slot index used to upload the file + output logic ioctl_wr, + output logic [AW-1:0] ioctl_addr, + output logic [DW-1:0] ioctl_data + ); + + //! ------------------------------------------------------------------------ + //! Download Signal Handler + //! ------------------------------------------------------------------------ + reg ioctl_download_r = 0; + wire ioctl_download_s; + wire [15:0] ioctl_index_s; + + always_ff @(posedge clk_74a) begin + if (dataslot_requestwrite) begin ioctl_download_r <= 1; end + else if(dataslot_allcomplete) begin ioctl_download_r <= 0; end + end + + //! ------------------------------------------------------------------------ + //! Sync and Assign Outputs + //! ------------------------------------------------------------------------ + synch_3 sync_io_dl(ioctl_download_r, ioctl_download_s, clk_memory); + synch_3 #(.WIDTH(16)) sync_wr_id(dataslot_requestwrite_id, ioctl_index_s, clk_memory); + + assign ioctl_download = ioctl_download_s; + assign ioctl_index = ioctl_index_s; + + //! ------------------------------------------------------------------------ + //! MPU -> FPGA Download + //! ------------------------------------------------------------------------ + localparam WORD_SIZE = DW == 16 ? 2 : 1; + + data_loader #( + .ADDRESS_MASK_UPPER_4 ( MASK ), + .WRITE_MEM_CLOCK_DELAY ( DELAY ), + .WRITE_MEM_EN_CYCLE_LENGTH ( HOLD ), + .ADDRESS_SIZE ( AW ), + .OUTPUT_WORD_SIZE ( WORD_SIZE ) + ) data_loader_in ( + .clk_74a ( clk_74a ), + .clk_memory ( clk_memory ), + + .bridge_wr ( bridge_wr ), + .bridge_endian_little ( bridge_endian_little ), + .bridge_addr ( bridge_addr ), + .bridge_wr_data ( bridge_wr_data ), + + .write_en ( ioctl_wr ), + .write_addr ( ioctl_addr ), + .write_data ( ioctl_data ) + ); + +endmodule diff --git a/platform/pocket/support/hiscore.sv b/platform/pocket/support/hiscore.sv index 36979ac..46136cf 100644 --- a/platform/pocket/support/hiscore.sv +++ b/platform/pocket/support/hiscore.sv @@ -1,739 +1,739 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MAME hiscore.dat support for arcade cores. -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2021, Alan Steremberg -// Copyright (c) 2021, Jim Gregory -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// -//------------------------------------------------------------------------------ -// -// Version history: -// 0001 - 2021-03-06 - First marked release -// 0002 - 2021-03-06 - Added HS_DUMPFORMAT localparam to identify dump version (for future use) -// Add HS_CONFIGINDEX and HS_DUMPINDEX parameters to configure ioctl_indexes -// 0003 - 2021-03-10 - Added WRITE_REPEATCOUNT and WRITE_REPEATWAIT to handle tricky write situations -// 0004 - 2021-03-15 - Fix ram_access assignment -// 0005 - 2021-03-18 - Add configurable score table width, clean up some stupid mistakes -// 0006 - 2021-03-27 - Move 'tweakable' parameters into MRA data header -// 0007 - 2021-04-15 - Improve state machine maintainability, add new 'pause padding' states -// 0008 - 2021-05-12 - Feed back core-level pause to halt startup timer -// 0009 - 2021-07-31 - Split hiscore extraction from upload (updates hiscore buffer on OSD open) -// 0010 - 2021-08-03 - Add hiscore buffer and change detection (ready for autosave!) -// 0011 - 2021-08-07 - Optional auto-save on OSD open -// 0012 - 2021-08-17 - Add variable length change detection mask -// 0013 - 2021-09-01 - Output configured signal for autosave option menu masking -// 0014 - 2021-09-09 - Fix turning on autosave w/o core reload -// 0015 - 2023-06-21 - Changes for the Analogue Pocket -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module hiscore - #( - parameter HS_ADDRESSWIDTH = 10, // Max size of game RAM address for highscores - parameter HS_SCOREWIDTH = 8, // Max size of capture RAM For highscore data (default 8 = 256 bytes max) - parameter HS_CONFIGINDEX = 3, // ioctl_index for config transfer - parameter HS_DUMPINDEX = 4, // ioctl_index for dump transfer - parameter CFG_ADDRESSWIDTH = 4, // Max size of RAM address for highscore.dat entries (default 4 = 16 entries max) - parameter CFG_LENGTHWIDTH = 1, // Max size of length for each highscore.dat entries (default 1 = 256 bytes max) - parameter TARGET_PLATFORM = 1 // Platform: [1] Analogue Pocket | [2] MiMiC - ) ( - input wire clk, - input wire reset, - - input wire paused, // Signal from core confirming CPU is paused - input wire autosave, // Auto-save enabled (active high) - - input wire ioctl_upload, - output reg ioctl_upload_req, - input wire ioctl_download, - input wire ioctl_wr, - input wire [24:0] ioctl_addr, - input wire [7:0] ioctl_index, - - input wire menu_status, - - input wire [7:0] data_from_mpu, // Incoming data from HPS ioctl_dout - input wire [7:0] data_from_ram, // Incoming data from game RAM - output wire [HS_ADDRESSWIDTH-1:0] ram_address, // Address in game RAM to read/write score data - output wire [7:0] data_to_mpu, // Data to send to HPS ioctl_din - output wire [7:0] data_to_ram, // Data to send to game RAM - output reg ram_write, // Write to game RAM (active high) - output wire ram_intent_read, // RAM read required (active high) - output wire ram_intent_write, // RAM write required (active high) - output reg pause_cpu, // Pause core CPU to prepare for/relax after RAM access - output wire configured // Hiscore module has valid configuration (active high) - ); - - // Parameters read from config header - reg [31:0] START_WAIT = 32'd0; // Delay before beginning check process - reg [15:0] CHECK_WAIT = 16'hFF; // Delay between start/end check attempts - reg [15:0] CHECK_HOLD = 16'd2; // Hold time for start/end check reads - reg [15:0] WRITE_HOLD = 16'd2; // Hold time for game RAM writes - reg [15:0] WRITE_REPEATCOUNT = 16'b1; // Number of times to write score to game RAM - reg [15:0] WRITE_REPEATWAIT = 16'b1111; // Delay between subsequent write attempts to game RAM - reg [7:0] ACCESS_PAUSEPAD = 8'd4; // Cycles to wait with paused CPU before and after RAM access - reg [7:0] CHANGEMASK = 1'b0; // Length of change mask - - // State machine constants - localparam SM_STATEWIDTH = 5; // Width of state machine net - - localparam SM_INIT_RESTORE = 0; - localparam SM_TIMER = 1; - - localparam SM_CHECKPREP = 2; - localparam SM_CHECKBEGIN = 3; - localparam SM_CHECKSTARTVAL = 4; - localparam SM_CHECKENDVAL = 5; - localparam SM_CHECKCANCEL = 6; - - localparam SM_WRITEPREP = 7; - localparam SM_WRITEBEGIN = 8; - localparam SM_WRITEREADY = 9; - localparam SM_WRITEDONE = 10; - localparam SM_WRITECOMPLETE = 11; - localparam SM_WRITERETRY = 12; - - localparam SM_COMPAREINIT = 16; - localparam SM_COMPAREBEGIN = 17; - localparam SM_COMPAREREADY = 18; - localparam SM_COMPAREREAD = 19; - localparam SM_COMPAREDONE = 20; - localparam SM_COMPARECOMPLETE = 21; - - localparam SM_EXTRACTINIT = 22; - localparam SM_EXTRACT = 23; - localparam SM_EXTRACTSAVE = 24; - localparam SM_EXTRACTCOMPLETE = 25; - - localparam SM_STOPPED = 30; - - /* - Hiscore config data structure (version 1) - ----------------------------------------- - [16 byte header] - [8 byte * no. of entries] - - - Header format - 00 00 FF FF 00 FF 00 02 00 02 00 01 11 11 00 00 - [ SW ] [ CW] [ CH] [ WH] [WRC] [WRW] [PAD] - 4 byte START_WAIT - 2 byte CHECK_WAIT - 2 byte CHECK_HOLD - 2 byte WRITE_HOLD - 2 byte WRITE_REPEATCOUNT - 2 byte WRITE_REPEATWAIT - 1 byte ACCESS_PAUSEPAD - 1 byte CHANGEMASK - - - Entry format (when CFG_LENGTHWIDTH=1) - 00 00 43 0b 0f 10 01 00 - 00 00 40 23 02 04 12 00 - [ ADDR ] LEN START END PAD - - 4 bytes Address of ram entry (in core memory map) - 1 byte Length of ram entry in bytes - 1 byte Start value to check for at start of address range before proceeding - 1 byte End value to check for at end of address range before proceeding - 1 byte (padding) - - - Entry format (when CFG_LENGTHWIDTH=2) - 00 00 43 0b 00 0f 10 01 - 00 00 40 23 00 02 04 12 - [ ADDR ] [LEN ] START END - - 4 bytes Address of ram entry (in core memory map) - 2 bytes Length of ram entry in bytes - 1 byte Start value to check for at start of address range before proceeding - 1 byte End value to check for at end of address range before proceeding - - */ - - localparam HS_VERSION = 14; // Version identifier for module - localparam HS_DUMPFORMAT = 1; // Version identifier for dump format - localparam HS_HEADERLENGTH = 16; // Size of header chunk (default=16 bytes) - - // HS_DUMPFORMAT = 1 --> No header, just the extracted hiscore data - - // Hiscore config tracking - wire downloading_config; // Is hiscore configuration currently being loaded from HPS? - reg downloaded_config = 1'b0; // Has hiscore configuration been loaded successfully - wire parsing_header; // Is hiscore configuration header currently being parsed? - wire parsing_mask; // Is hiscore configuration change mask currently being parsed? (optional 2nd line of config) - - // Hiscore data tracking - wire downloading_dump; // Is hiscore data currently being loaded from HPS? - reg downloaded_dump = 1'b0; // Has hiscore data been loaded successfully - wire uploading_dump; // Is hiscore data currently being sent to HPS? - reg extracting_dump = 1'b0; // Is hiscore data currently being extracted from game RAM? - reg restoring_dump = 1'b0; // Is hiscore data currently being (or waiting to) restore to game RAM - - reg checking_scores = 1'b0; // Is state machine currently checking game RAM for highscore restore readiness - reg reading_scores = 1'b0; // Is state machine currently reading game RAM for highscore dump - reg writing_scores = 1'b0; // Is state machine currently restoring hiscore data to game RAM - - reg [3:0] initialised; // Number of times state machine has been initialised (debug only) - - assign configured = downloaded_config; - assign downloading_config = ioctl_download && (ioctl_index == HS_CONFIGINDEX); - assign parsing_header = downloading_config && (ioctl_addr < HS_HEADERLENGTH); - assign parsing_mask = downloading_config && !parsing_header && (CHANGEMASK > 8'b0) && (ioctl_addr < HS_HEADERLENGTH + CHANGEMASK); - assign downloading_dump = ioctl_download && (ioctl_index == HS_DUMPINDEX); - assign uploading_dump = ioctl_upload && (ioctl_index == HS_DUMPINDEX); - assign ram_intent_read = reading_scores | checking_scores; - assign ram_intent_write = writing_scores; - assign ram_address = ram_addr[HS_ADDRESSWIDTH-1:0]; - - reg [(SM_STATEWIDTH-1):0] state = SM_INIT_RESTORE; // Current state machine index - reg [(SM_STATEWIDTH-1):0] next_state = SM_INIT_RESTORE; // Next state machine index to move to after wait timer expires - reg [31:0] wait_timer; // Wait timer for inital/read/write delays - - reg [CFG_ADDRESSWIDTH-1:0] counter = 1'b0; // Index for current config table entry - reg [CFG_ADDRESSWIDTH-1:0] total_entries = 1'b0; // Total count of config table entries - reg reset_last = 1'b0; // Last cycle reset - reg [7:0] write_counter = 1'b0; // Index of current game RAM write attempt - - reg [255:0] change_mask; // Bit mask for dump change check - - reg [7:0] last_ioctl_index; // Last cycle HPS IO index - reg last_ioctl_download = 0; // Last cycle HPS IO download - reg [7:0] last_data_from_mpu; // Last cycle HPS IO data out - reg [7:0] last_data_from_mpu2; // Last cycle +1 HPS IO data out - reg [7:0] last_data_from_mpu3; // Last cycle +2 HPS IO data out - reg last_menu_status; // Last cycle OSD status - - reg [24:0] ram_addr; // Target RAM address for hiscore read/write - reg [24:0] base_io_addr; - wire [23:0] addr_base /* synthesis keep */; - wire [(CFG_LENGTHWIDTH*8)-1:0] length; - wire [24:0] end_addr = (addr_base + length - 1'b1); - reg [HS_SCOREWIDTH-1:0] data_addr; - reg [HS_SCOREWIDTH-1:0] buffer_addr; - wire [7:0] start_val /* synthesis keep */; - wire [7:0] end_val /* synthesis keep */; - - wire check_mask = change_mask[compare_length]/* synthesis keep */; - wire [7:0] hiscore_data_out /* synthesis keep */; - wire [7:0] hiscore_buffer_out /* synthesis keep */; - reg [19:0] compare_length = 1'b0; - reg dump_write = 1'b0; - reg buffer_write = 1'b0; - reg compare_nonzero = 1'b1; // High after extract and compare if any byte returned is non-zero - reg compare_changed = 1'b1; // High after extract and compare if any byte is different to current hiscore data - reg dump_dirty = 1'b0; // High if dump has changed since last save (or first load if no save has occurred) - - wire [23:0] address_data_in; - wire [(CFG_LENGTHWIDTH*8)-1:0] length_data_in; - - assign address_data_in = {last_data_from_mpu2, last_data_from_mpu, data_from_mpu}; - assign length_data_in = (CFG_LENGTHWIDTH == 1'b1) ? data_from_mpu : {last_data_from_mpu, data_from_mpu}; - - wire parsing_config = ~(parsing_header | parsing_mask); // Hiscore config lines are being parsed - - wire [CFG_ADDRESSWIDTH-1:0] config_upload_addr = ioctl_addr[CFG_ADDRESSWIDTH+2:3] - (9'd2 + CHANGEMASK[7:3]) /* synthesis keep */; - - wire address_we = downloading_config & parsing_config & (ioctl_addr[2:0] == 3'd3); - wire length_we = downloading_config & parsing_config & (ioctl_addr[2:0] == 3'd3 + CFG_LENGTHWIDTH); - wire startdata_we = downloading_config & parsing_config & (ioctl_addr[2:0] == 3'd4 + CFG_LENGTHWIDTH); - wire enddata_we = downloading_config & parsing_config & (ioctl_addr[2:0] == 3'd5 + CFG_LENGTHWIDTH); - - // RAM chunks used to store configuration data - // - Address table - dpram_hs #(.aWidth(CFG_ADDRESSWIDTH),.dWidth(24)) address_table - ( - .clk ( clk ), - .addr_a ( config_upload_addr ), - .we_a ( address_we & ioctl_wr ), - .d_a ( address_data_in ), - .addr_b ( counter ), - .q_b ( addr_base ) - ); - // Length table - variable width depending on CFG_LENGTHWIDTH - dpram_hs #(.aWidth(CFG_ADDRESSWIDTH),.dWidth(CFG_LENGTHWIDTH*8)) length_table - ( - .clk ( clk ), - .addr_a ( config_upload_addr ), - .we_a ( length_we & ioctl_wr ), - .d_a ( length_data_in ), - .addr_b ( counter ), - .q_b ( length ) - ); - // - Start data table - dpram_hs #(.aWidth(CFG_ADDRESSWIDTH),.dWidth(8)) startdata_table - ( - .clk ( clk ), - .addr_a ( config_upload_addr ), - .we_a ( startdata_we & ioctl_wr ), - .d_a ( data_from_mpu ), - .addr_b ( counter ), - .q_b ( start_val ) - ); - // - End data table - dpram_hs #(.aWidth(CFG_ADDRESSWIDTH),.dWidth(8)) enddata_table - ( - .clk ( clk ), - .addr_a ( config_upload_addr ), - .we_a ( enddata_we & ioctl_wr ), - .d_a ( data_from_mpu ), - .addr_b ( counter ), - .q_b ( end_val ) - ); - - // RAM chunk used to store valid hiscore data - dpram_hs #(.aWidth(HS_SCOREWIDTH),.dWidth(8)) hiscore_data - ( - .clk ( clk ), - .addr_a ( ioctl_addr[(HS_SCOREWIDTH-1):0] ), - .we_a ( downloading_dump ), - .d_a ( data_from_mpu ), - .addr_b ( data_addr ), - .we_b ( dump_write ), - .d_b ( hiscore_buffer_out ), - .q_b ( hiscore_data_out ) - ); - // RAM chunk used to store temporary high score data - dpram_hs #(.aWidth(HS_SCOREWIDTH),.dWidth(8)) hiscore_buffer - ( - .clk ( clk ), - .addr_a ( buffer_addr ), - .we_a ( buffer_write ), - .d_a ( data_from_ram ), - .q_a ( hiscore_buffer_out ) - ); - - assign data_to_ram = hiscore_data_out; - assign data_to_mpu = hiscore_data_out; - - wire [3:0] header_chunk = ioctl_addr[3:0]; - wire [7:0] mask_chunk = ioctl_addr[7:0] - 5'd16; - wire [255:0] mask_load_index = mask_chunk * 8; - - always @(posedge clk) begin - - if (downloading_config) begin - // Get header chunk data - if(parsing_header) begin - if(ioctl_wr) begin - if(header_chunk == 4'd3) START_WAIT <= { last_data_from_mpu3, last_data_from_mpu2, last_data_from_mpu, data_from_mpu }; - if(header_chunk == 4'd5) CHECK_WAIT <= { last_data_from_mpu, data_from_mpu }; - if(header_chunk == 4'd7) CHECK_HOLD <= { last_data_from_mpu, data_from_mpu }; - if(header_chunk == 4'd9) WRITE_HOLD <= { last_data_from_mpu, data_from_mpu }; - if(header_chunk == 4'd11) WRITE_REPEATCOUNT <= { last_data_from_mpu, data_from_mpu }; - if(header_chunk == 4'd13) WRITE_REPEATWAIT <= { last_data_from_mpu, data_from_mpu }; - if(header_chunk == 4'd14) ACCESS_PAUSEPAD <= data_from_mpu; - if(header_chunk == 4'd15) CHANGEMASK <= data_from_mpu; - end - end - else - if(parsing_mask) begin - if(ioctl_wr == 1'b1) - change_mask[mask_load_index +: 8] <= data_from_mpu; - end - else begin - // Keep track of the largest entry during config download - total_entries <= config_upload_addr; - end - end - - // Track completion of configuration and dump download - if(TARGET_PLATFORM == 1) begin - if (~ioctl_download && last_ioctl_download) begin - downloaded_config <= 1'b1; - downloaded_dump <= 1'b1; - end - end - else begin - if ((last_ioctl_download != ioctl_download) && (ioctl_download == 1'b0)) begin - if (last_ioctl_index == HS_CONFIGINDEX) downloaded_config <= 1'b1; - if (last_ioctl_index == HS_DUMPINDEX) downloaded_dump <= 1'b1; - end - end - - // Track last cycle values - last_ioctl_download <= ioctl_download; - last_ioctl_index <= ioctl_index; - last_menu_status <= menu_status; - - // Cascade incoming data bytes from HPS - if(ioctl_download && ioctl_wr) begin - last_data_from_mpu3 = last_data_from_mpu2; - last_data_from_mpu2 = last_data_from_mpu; - last_data_from_mpu = data_from_mpu; - end - - // If we have a valid configuration then enable the hiscore system - if(downloaded_config) begin - - // Check for end of core reset to initialise state machine for restore - reset_last <= reset; - if (downloaded_dump == 1'b1 && reset_last == 1'b1 && reset == 1'b0) begin - wait_timer <= START_WAIT; - next_state <= SM_INIT_RESTORE; - state <= SM_TIMER; - counter <= 1'b0; - initialised <= initialised + 1'b1; - restoring_dump <= 1'b1; - end - else begin - // Upload scores if requested by HPS - // - Data is now sent from the hiscore data buffer rather than game RAM as in previous versions - if (uploading_dump == 1'b1) begin - // Set local address to read from hiscore data based on ioctl_address - data_addr <= ioctl_addr[HS_SCOREWIDTH-1:0]; - // Clear dump dirty flag - dump_dirty <= 1'b0; - end - - // Trigger hiscore extraction when OSD is opened - if(last_menu_status==1'b0 && menu_status==1'b1 && extracting_dump==1'b0 && uploading_dump==1'b0 && restoring_dump==1'b0) begin - extracting_dump <= 1'b1; - state <= SM_COMPAREINIT; - end - - // Extract hiscore data from game RAM and save in hiscore data buffer - if (extracting_dump == 1'b1) begin - case (state) - // Compare process states - SM_COMPAREINIT: // Initialise state machine for comparison - begin - // Setup addresses and comparison flags - buffer_addr <= 0; - data_addr <= 0; - counter <= 0; - compare_nonzero <= 1'b0; - compare_changed <= 1'b0; - compare_length <= 1'b0; - // Pause cpu and wait for next state - pause_cpu <= 1'b1; - state <= SM_TIMER; - next_state <= SM_COMPAREBEGIN; - wait_timer <= ACCESS_PAUSEPAD; - end - SM_COMPAREBEGIN: begin - // Get ready to read next line (wait until addr_base is updated) - reading_scores <= 1'b1; - state <= SM_COMPAREREADY; - end - SM_COMPAREREADY: begin - // Set ram address and wait for it to return correctly - ram_addr <= addr_base; - if(ram_addr == addr_base) begin - state <= SM_COMPAREREAD; - end - end - SM_COMPAREREAD: begin - // Setup next address and signal write enable to hiscore buffer - buffer_write <= 1'b1; - state <= SM_COMPAREDONE; - end - SM_COMPAREDONE: begin - // If RAM data has changed since last dump and there is either no mask or a 1 in the mask for this address - if (data_from_ram != hiscore_data_out && (CHANGEMASK==8'b0 || check_mask==1)) begin - // Hiscore data changed - compare_changed <= 1'b1; - end - if (data_from_ram != 8'b0) begin - // Hiscore data is not blank - compare_nonzero <= 1'b1; - end - compare_length <= compare_length + 20'b1; - // Move to next entry when last address is reached - if (ram_addr == end_addr) begin - // If this was the last entry then we are done - if (counter == total_entries) begin - state <= SM_TIMER; - reading_scores <= 1'b0; - next_state <= SM_COMPARECOMPLETE; - wait_timer <= ACCESS_PAUSEPAD; - end - else begin - // Next config line - counter <= counter + 1'b1; - state <= SM_COMPAREBEGIN; - end - end - else begin - // Keep extracting this section - state <= SM_COMPAREREAD; - ram_addr <= ram_addr + 1'b1; - end - // Always stop writing to hiscore dump ram and increment local address - buffer_addr <= buffer_addr + 1'b1; - data_addr <= data_addr + 1'b1; - buffer_write <= 1'b0; - end - SM_COMPARECOMPLETE: begin - pause_cpu <= 1'b0; - reading_scores <= 1'b0; - if (compare_changed == 1'b1 && compare_nonzero == 1'b1) begin - // If high scores have changed and are not blank, update the hiscore data from extract buffer - dump_dirty <= 1'b1; - state <= SM_EXTRACTINIT; - end - else begin - // If no change or scores are invalid leave the existing hiscore data in place - if(dump_dirty == 1'b1 && autosave == 1'b1) begin - state <= SM_EXTRACTSAVE; - end - else begin - extracting_dump <= 1'b0; - state <= SM_STOPPED; - end - end - end - SM_EXTRACTINIT: begin - // Setup address and counter - data_addr <= 0; - buffer_addr <= 0; - state <= SM_EXTRACT; - dump_write <= 1'b1; - end - SM_EXTRACT: begin - // Keep writing until end of buffer - if (buffer_addr == compare_length) begin - dump_write <= 1'b0; - state <= SM_EXTRACTSAVE; - end - // Increment buffer address and set data address to one behind - data_addr <= buffer_addr; - buffer_addr <= buffer_addr + 1'b1; - end - SM_EXTRACTSAVE: begin - if(autosave == 1'b1) begin - ioctl_upload_req <= 1'b1; - state <= SM_TIMER; - next_state <= SM_EXTRACTCOMPLETE; - wait_timer <= 4'd4; - end - else begin - extracting_dump <= 1'b0; - state <= SM_STOPPED; - end - end - SM_EXTRACTCOMPLETE: begin - ioctl_upload_req <= 1'b0; - extracting_dump <= 1'b0; - state <= SM_STOPPED; - end - endcase - end - - // If we are not uploading or resetting and valid hiscore data is available then start the state machine to write data to game RAM - if (uploading_dump == 1'b0 && downloaded_dump == 1'b1 && reset == 1'b0) begin - // State machine to write data to game RAM - case (state) - SM_INIT_RESTORE: // Start state machine - begin - // Setup base addresses - data_addr <= 0; - base_io_addr <= 25'b0; - // Reset entry counter and states - counter <= 0; - writing_scores <= 1'b0; - checking_scores <= 1'b0; - pause_cpu <= 1'b0; - state <= SM_CHECKPREP; - end - - // Start/end check states - // ---------------------- - SM_CHECKPREP: // Prepare start/end check run - pause CPU in readiness for RAM access - begin - state <= SM_TIMER; - next_state <= SM_CHECKBEGIN; - pause_cpu <= 1'b1; - wait_timer <= ACCESS_PAUSEPAD; - end - - SM_CHECKBEGIN: // Begin start/end check run - enable RAM access - begin - checking_scores <= 1'b1; - ram_addr <= {1'b0, addr_base}; - state <= SM_CHECKSTARTVAL; - wait_timer <= CHECK_HOLD; - end - - SM_CHECKSTARTVAL: // Start check - begin - // Check for matching start value - if(wait_timer != CHECK_HOLD && data_from_ram == start_val) begin - // Prepare end check - ram_addr <= end_addr; - state <= SM_CHECKENDVAL; - wait_timer <= CHECK_HOLD; - end - else begin - ram_addr <= {1'b0, addr_base}; - if (wait_timer > 1'b0) begin - wait_timer <= wait_timer - 1'b1; - end - else begin - // - If no match after read wait then stop check run and schedule restart of state machine - next_state <= SM_CHECKCANCEL; - state <= SM_TIMER; - checking_scores <= 1'b0; - wait_timer <= ACCESS_PAUSEPAD; - end - end - end - - SM_CHECKENDVAL: // End check - begin - // Check for matching end value - if (wait_timer != CHECK_HOLD & data_from_ram == end_val) begin - if (counter == total_entries) begin - // If this was the last entry then move on to writing scores to game ram - checking_scores <= 1'b0; - state <= SM_WRITEBEGIN; // Bypass SM_WRITEPREP as we are already paused - counter <= 1'b0; - write_counter <= 1'b0; - ram_write <= 1'b0; - ram_addr <= {1'b0, addr_base}; - end - else begin - // Increment counter and restart state machine to check next entry - counter <= counter + 1'b1; - state <= SM_CHECKBEGIN; - end - end - else begin - ram_addr <= end_addr; - if (wait_timer > 1'b0) begin - wait_timer <= wait_timer - 1'b1; - end - else begin - // - If no match after read wait then stop check run and schedule restart of state machine - next_state <= SM_CHECKCANCEL; - state <= SM_TIMER; - checking_scores <= 1'b0; - wait_timer <= ACCESS_PAUSEPAD; - end - end - end - - SM_CHECKCANCEL: // Cancel start/end check run - disable RAM access and keep CPU paused - begin - pause_cpu <= 1'b0; - next_state <= SM_INIT_RESTORE; - state <= SM_TIMER; - wait_timer <= CHECK_WAIT; - end - - // Write to game RAM states - // ---------------------- - SM_WRITEPREP: // Prepare to write scores - pause CPU in readiness for RAM access (only used on subsequent write attempts) - begin - state <= SM_TIMER; - next_state <= SM_WRITEBEGIN; - pause_cpu <= 1'b1; - wait_timer <= ACCESS_PAUSEPAD; - end - - SM_WRITEBEGIN: // Writing scores to game RAM begins - begin - writing_scores <= 1'b1; // Enable muxes if necessary - write_counter <= write_counter + 1'b1; - state <= SM_WRITEREADY; - end - - SM_WRITEREADY: // local ram should be correct, start write to game RAM - begin - ram_addr <= addr_base + (data_addr - base_io_addr); - state <= SM_TIMER; - next_state <= SM_WRITEDONE; - wait_timer <= WRITE_HOLD; - ram_write <= 1'b1; - end - - SM_WRITEDONE: begin - data_addr <= data_addr + 1'b1; // Increment to next byte of entry - if (ram_addr == end_addr) begin - // End of entry reached - if (counter == total_entries) begin - state <= SM_WRITECOMPLETE; - end - else begin - // Move to next entry - counter <= counter + 1'b1; - write_counter <= 1'b0; - base_io_addr <= data_addr + 1'b1; - state <= SM_WRITEBEGIN; - end - end - else begin - state <= SM_WRITEREADY; - end - ram_write <= 1'b0; - end - - SM_WRITECOMPLETE: // Hiscore write to RAM completed - begin - ram_write <= 1'b0; - writing_scores <= 1'b0; - restoring_dump <= 1'b0; - state <= SM_TIMER; - if(write_counter < WRITE_REPEATCOUNT) begin - // Schedule next write - next_state <= SM_WRITERETRY; - data_addr <= 0; - wait_timer <= WRITE_REPEATWAIT; - end - else begin - next_state <= SM_STOPPED; - wait_timer <= ACCESS_PAUSEPAD; - end - end - - SM_WRITERETRY: // Stop pause and schedule next write - begin - pause_cpu <= 1'b0; - state <= SM_TIMER; - next_state <= SM_WRITEPREP; - wait_timer <= WRITE_REPEATWAIT; - end - - SM_STOPPED: begin - pause_cpu <= 1'b0; - end - endcase - end - - if(state == SM_TIMER) // timer wait state - begin - // Do not progress timer if CPU is paused by source other than this module - // - Stops initial hiscore load delay being foiled by user pausing/entering OSD - if (paused == 1'b0 || pause_cpu == 1'b1) begin - if (wait_timer > 1'b0) begin - wait_timer <= wait_timer - 1'b1; - end - else begin - state <= next_state; - end - end - end - end - end - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MAME hiscore.dat support for arcade cores. +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2021, Alan Steremberg +// Copyright (c) 2021, Jim Gregory +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +//------------------------------------------------------------------------------ +// +// Version history: +// 0001 - 2021-03-06 - First marked release +// 0002 - 2021-03-06 - Added HS_DUMPFORMAT localparam to identify dump version (for future use) +// Add HS_CONFIGINDEX and HS_DUMPINDEX parameters to configure ioctl_indexes +// 0003 - 2021-03-10 - Added WRITE_REPEATCOUNT and WRITE_REPEATWAIT to handle tricky write situations +// 0004 - 2021-03-15 - Fix ram_access assignment +// 0005 - 2021-03-18 - Add configurable score table width, clean up some stupid mistakes +// 0006 - 2021-03-27 - Move 'tweakable' parameters into MRA data header +// 0007 - 2021-04-15 - Improve state machine maintainability, add new 'pause padding' states +// 0008 - 2021-05-12 - Feed back core-level pause to halt startup timer +// 0009 - 2021-07-31 - Split hiscore extraction from upload (updates hiscore buffer on OSD open) +// 0010 - 2021-08-03 - Add hiscore buffer and change detection (ready for autosave!) +// 0011 - 2021-08-07 - Optional auto-save on OSD open +// 0012 - 2021-08-17 - Add variable length change detection mask +// 0013 - 2021-09-01 - Output configured signal for autosave option menu masking +// 0014 - 2021-09-09 - Fix turning on autosave w/o core reload +// 0015 - 2023-06-21 - Changes for the Analogue Pocket +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module hiscore + #( + parameter HS_ADDRESSWIDTH = 10, // Max size of game RAM address for highscores + parameter HS_SCOREWIDTH = 8, // Max size of capture RAM For highscore data (default 8 = 256 bytes max) + parameter HS_CONFIGINDEX = 3, // ioctl_index for config transfer + parameter HS_DUMPINDEX = 4, // ioctl_index for dump transfer + parameter CFG_ADDRESSWIDTH = 4, // Max size of RAM address for highscore.dat entries (default 4 = 16 entries max) + parameter CFG_LENGTHWIDTH = 1, // Max size of length for each highscore.dat entries (default 1 = 256 bytes max) + parameter TARGET_PLATFORM = 1 // Platform: [1] Analogue Pocket | [2] MiMiC + ) ( + input wire clk, + input wire reset, + + input wire paused, // Signal from core confirming CPU is paused + input wire autosave, // Auto-save enabled (active high) + + input wire ioctl_upload, + output reg ioctl_upload_req, + input wire ioctl_download, + input wire ioctl_wr, + input wire [24:0] ioctl_addr, + input wire [7:0] ioctl_index, + + input wire menu_status, + + input wire [7:0] data_from_mpu, // Incoming data from HPS ioctl_dout + input wire [7:0] data_from_ram, // Incoming data from game RAM + output wire [HS_ADDRESSWIDTH-1:0] ram_address, // Address in game RAM to read/write score data + output wire [7:0] data_to_mpu, // Data to send to HPS ioctl_din + output wire [7:0] data_to_ram, // Data to send to game RAM + output reg ram_write, // Write to game RAM (active high) + output wire ram_intent_read, // RAM read required (active high) + output wire ram_intent_write, // RAM write required (active high) + output reg pause_cpu, // Pause core CPU to prepare for/relax after RAM access + output wire configured // Hiscore module has valid configuration (active high) + ); + + // Parameters read from config header + reg [31:0] START_WAIT = 32'd0; // Delay before beginning check process + reg [15:0] CHECK_WAIT = 16'hFF; // Delay between start/end check attempts + reg [15:0] CHECK_HOLD = 16'd2; // Hold time for start/end check reads + reg [15:0] WRITE_HOLD = 16'd2; // Hold time for game RAM writes + reg [15:0] WRITE_REPEATCOUNT = 16'b1; // Number of times to write score to game RAM + reg [15:0] WRITE_REPEATWAIT = 16'b1111; // Delay between subsequent write attempts to game RAM + reg [7:0] ACCESS_PAUSEPAD = 8'd4; // Cycles to wait with paused CPU before and after RAM access + reg [7:0] CHANGEMASK = 1'b0; // Length of change mask + + // State machine constants + localparam SM_STATEWIDTH = 5; // Width of state machine net + + localparam SM_INIT_RESTORE = 0; + localparam SM_TIMER = 1; + + localparam SM_CHECKPREP = 2; + localparam SM_CHECKBEGIN = 3; + localparam SM_CHECKSTARTVAL = 4; + localparam SM_CHECKENDVAL = 5; + localparam SM_CHECKCANCEL = 6; + + localparam SM_WRITEPREP = 7; + localparam SM_WRITEBEGIN = 8; + localparam SM_WRITEREADY = 9; + localparam SM_WRITEDONE = 10; + localparam SM_WRITECOMPLETE = 11; + localparam SM_WRITERETRY = 12; + + localparam SM_COMPAREINIT = 16; + localparam SM_COMPAREBEGIN = 17; + localparam SM_COMPAREREADY = 18; + localparam SM_COMPAREREAD = 19; + localparam SM_COMPAREDONE = 20; + localparam SM_COMPARECOMPLETE = 21; + + localparam SM_EXTRACTINIT = 22; + localparam SM_EXTRACT = 23; + localparam SM_EXTRACTSAVE = 24; + localparam SM_EXTRACTCOMPLETE = 25; + + localparam SM_STOPPED = 30; + + /* + Hiscore config data structure (version 1) + ----------------------------------------- + [16 byte header] + [8 byte * no. of entries] + + - Header format + 00 00 FF FF 00 FF 00 02 00 02 00 01 11 11 00 00 + [ SW ] [ CW] [ CH] [ WH] [WRC] [WRW] [PAD] + 4 byte START_WAIT + 2 byte CHECK_WAIT + 2 byte CHECK_HOLD + 2 byte WRITE_HOLD + 2 byte WRITE_REPEATCOUNT + 2 byte WRITE_REPEATWAIT + 1 byte ACCESS_PAUSEPAD + 1 byte CHANGEMASK + + - Entry format (when CFG_LENGTHWIDTH=1) + 00 00 43 0b 0f 10 01 00 + 00 00 40 23 02 04 12 00 + [ ADDR ] LEN START END PAD + + 4 bytes Address of ram entry (in core memory map) + 1 byte Length of ram entry in bytes + 1 byte Start value to check for at start of address range before proceeding + 1 byte End value to check for at end of address range before proceeding + 1 byte (padding) + + - Entry format (when CFG_LENGTHWIDTH=2) + 00 00 43 0b 00 0f 10 01 + 00 00 40 23 00 02 04 12 + [ ADDR ] [LEN ] START END + + 4 bytes Address of ram entry (in core memory map) + 2 bytes Length of ram entry in bytes + 1 byte Start value to check for at start of address range before proceeding + 1 byte End value to check for at end of address range before proceeding + + */ + + localparam HS_VERSION = 14; // Version identifier for module + localparam HS_DUMPFORMAT = 1; // Version identifier for dump format + localparam HS_HEADERLENGTH = 16; // Size of header chunk (default=16 bytes) + + // HS_DUMPFORMAT = 1 --> No header, just the extracted hiscore data + + // Hiscore config tracking + wire downloading_config; // Is hiscore configuration currently being loaded from HPS? + reg downloaded_config = 1'b0; // Has hiscore configuration been loaded successfully + wire parsing_header; // Is hiscore configuration header currently being parsed? + wire parsing_mask; // Is hiscore configuration change mask currently being parsed? (optional 2nd line of config) + + // Hiscore data tracking + wire downloading_dump; // Is hiscore data currently being loaded from HPS? + reg downloaded_dump = 1'b0; // Has hiscore data been loaded successfully + wire uploading_dump; // Is hiscore data currently being sent to HPS? + reg extracting_dump = 1'b0; // Is hiscore data currently being extracted from game RAM? + reg restoring_dump = 1'b0; // Is hiscore data currently being (or waiting to) restore to game RAM + + reg checking_scores = 1'b0; // Is state machine currently checking game RAM for highscore restore readiness + reg reading_scores = 1'b0; // Is state machine currently reading game RAM for highscore dump + reg writing_scores = 1'b0; // Is state machine currently restoring hiscore data to game RAM + + reg [3:0] initialised; // Number of times state machine has been initialised (debug only) + + assign configured = downloaded_config; + assign downloading_config = ioctl_download && (ioctl_index == HS_CONFIGINDEX); + assign parsing_header = downloading_config && (ioctl_addr < HS_HEADERLENGTH); + assign parsing_mask = downloading_config && !parsing_header && (CHANGEMASK > 8'b0) && (ioctl_addr < HS_HEADERLENGTH + CHANGEMASK); + assign downloading_dump = ioctl_download && (ioctl_index == HS_DUMPINDEX); + assign uploading_dump = ioctl_upload && (ioctl_index == HS_DUMPINDEX); + assign ram_intent_read = reading_scores | checking_scores; + assign ram_intent_write = writing_scores; + assign ram_address = ram_addr[HS_ADDRESSWIDTH-1:0]; + + reg [(SM_STATEWIDTH-1):0] state = SM_INIT_RESTORE; // Current state machine index + reg [(SM_STATEWIDTH-1):0] next_state = SM_INIT_RESTORE; // Next state machine index to move to after wait timer expires + reg [31:0] wait_timer; // Wait timer for inital/read/write delays + + reg [CFG_ADDRESSWIDTH-1:0] counter = 1'b0; // Index for current config table entry + reg [CFG_ADDRESSWIDTH-1:0] total_entries = 1'b0; // Total count of config table entries + reg reset_last = 1'b0; // Last cycle reset + reg [7:0] write_counter = 1'b0; // Index of current game RAM write attempt + + reg [255:0] change_mask; // Bit mask for dump change check + + reg [7:0] last_ioctl_index; // Last cycle HPS IO index + reg last_ioctl_download = 0; // Last cycle HPS IO download + reg [7:0] last_data_from_mpu; // Last cycle HPS IO data out + reg [7:0] last_data_from_mpu2; // Last cycle +1 HPS IO data out + reg [7:0] last_data_from_mpu3; // Last cycle +2 HPS IO data out + reg last_menu_status; // Last cycle OSD status + + reg [24:0] ram_addr; // Target RAM address for hiscore read/write + reg [24:0] base_io_addr; + wire [23:0] addr_base /* synthesis keep */; + wire [(CFG_LENGTHWIDTH*8)-1:0] length; + wire [24:0] end_addr = (addr_base + length - 1'b1); + reg [HS_SCOREWIDTH-1:0] data_addr; + reg [HS_SCOREWIDTH-1:0] buffer_addr; + wire [7:0] start_val /* synthesis keep */; + wire [7:0] end_val /* synthesis keep */; + + wire check_mask = change_mask[compare_length]/* synthesis keep */; + wire [7:0] hiscore_data_out /* synthesis keep */; + wire [7:0] hiscore_buffer_out /* synthesis keep */; + reg [19:0] compare_length = 1'b0; + reg dump_write = 1'b0; + reg buffer_write = 1'b0; + reg compare_nonzero = 1'b1; // High after extract and compare if any byte returned is non-zero + reg compare_changed = 1'b1; // High after extract and compare if any byte is different to current hiscore data + reg dump_dirty = 1'b0; // High if dump has changed since last save (or first load if no save has occurred) + + wire [23:0] address_data_in; + wire [(CFG_LENGTHWIDTH*8)-1:0] length_data_in; + + assign address_data_in = {last_data_from_mpu2, last_data_from_mpu, data_from_mpu}; + assign length_data_in = (CFG_LENGTHWIDTH == 1'b1) ? data_from_mpu : {last_data_from_mpu, data_from_mpu}; + + wire parsing_config = ~(parsing_header | parsing_mask); // Hiscore config lines are being parsed + + wire [CFG_ADDRESSWIDTH-1:0] config_upload_addr = ioctl_addr[CFG_ADDRESSWIDTH+2:3] - (9'd2 + CHANGEMASK[7:3]) /* synthesis keep */; + + wire address_we = downloading_config & parsing_config & (ioctl_addr[2:0] == 3'd3); + wire length_we = downloading_config & parsing_config & (ioctl_addr[2:0] == 3'd3 + CFG_LENGTHWIDTH); + wire startdata_we = downloading_config & parsing_config & (ioctl_addr[2:0] == 3'd4 + CFG_LENGTHWIDTH); + wire enddata_we = downloading_config & parsing_config & (ioctl_addr[2:0] == 3'd5 + CFG_LENGTHWIDTH); + + // RAM chunks used to store configuration data + // - Address table + dpram_hs #(.aWidth(CFG_ADDRESSWIDTH),.dWidth(24)) address_table + ( + .clk ( clk ), + .addr_a ( config_upload_addr ), + .we_a ( address_we & ioctl_wr ), + .d_a ( address_data_in ), + .addr_b ( counter ), + .q_b ( addr_base ) + ); + // Length table - variable width depending on CFG_LENGTHWIDTH + dpram_hs #(.aWidth(CFG_ADDRESSWIDTH),.dWidth(CFG_LENGTHWIDTH*8)) length_table + ( + .clk ( clk ), + .addr_a ( config_upload_addr ), + .we_a ( length_we & ioctl_wr ), + .d_a ( length_data_in ), + .addr_b ( counter ), + .q_b ( length ) + ); + // - Start data table + dpram_hs #(.aWidth(CFG_ADDRESSWIDTH),.dWidth(8)) startdata_table + ( + .clk ( clk ), + .addr_a ( config_upload_addr ), + .we_a ( startdata_we & ioctl_wr ), + .d_a ( data_from_mpu ), + .addr_b ( counter ), + .q_b ( start_val ) + ); + // - End data table + dpram_hs #(.aWidth(CFG_ADDRESSWIDTH),.dWidth(8)) enddata_table + ( + .clk ( clk ), + .addr_a ( config_upload_addr ), + .we_a ( enddata_we & ioctl_wr ), + .d_a ( data_from_mpu ), + .addr_b ( counter ), + .q_b ( end_val ) + ); + + // RAM chunk used to store valid hiscore data + dpram_hs #(.aWidth(HS_SCOREWIDTH),.dWidth(8)) hiscore_data + ( + .clk ( clk ), + .addr_a ( ioctl_addr[(HS_SCOREWIDTH-1):0] ), + .we_a ( downloading_dump ), + .d_a ( data_from_mpu ), + .addr_b ( data_addr ), + .we_b ( dump_write ), + .d_b ( hiscore_buffer_out ), + .q_b ( hiscore_data_out ) + ); + // RAM chunk used to store temporary high score data + dpram_hs #(.aWidth(HS_SCOREWIDTH),.dWidth(8)) hiscore_buffer + ( + .clk ( clk ), + .addr_a ( buffer_addr ), + .we_a ( buffer_write ), + .d_a ( data_from_ram ), + .q_a ( hiscore_buffer_out ) + ); + + assign data_to_ram = hiscore_data_out; + assign data_to_mpu = hiscore_data_out; + + wire [3:0] header_chunk = ioctl_addr[3:0]; + wire [7:0] mask_chunk = ioctl_addr[7:0] - 5'd16; + wire [255:0] mask_load_index = mask_chunk * 8; + + always @(posedge clk) begin + + if (downloading_config) begin + // Get header chunk data + if(parsing_header) begin + if(ioctl_wr) begin + if(header_chunk == 4'd3) START_WAIT <= { last_data_from_mpu3, last_data_from_mpu2, last_data_from_mpu, data_from_mpu }; + if(header_chunk == 4'd5) CHECK_WAIT <= { last_data_from_mpu, data_from_mpu }; + if(header_chunk == 4'd7) CHECK_HOLD <= { last_data_from_mpu, data_from_mpu }; + if(header_chunk == 4'd9) WRITE_HOLD <= { last_data_from_mpu, data_from_mpu }; + if(header_chunk == 4'd11) WRITE_REPEATCOUNT <= { last_data_from_mpu, data_from_mpu }; + if(header_chunk == 4'd13) WRITE_REPEATWAIT <= { last_data_from_mpu, data_from_mpu }; + if(header_chunk == 4'd14) ACCESS_PAUSEPAD <= data_from_mpu; + if(header_chunk == 4'd15) CHANGEMASK <= data_from_mpu; + end + end + else + if(parsing_mask) begin + if(ioctl_wr == 1'b1) + change_mask[mask_load_index +: 8] <= data_from_mpu; + end + else begin + // Keep track of the largest entry during config download + total_entries <= config_upload_addr; + end + end + + // Track completion of configuration and dump download + if(TARGET_PLATFORM == 1) begin + if (~ioctl_download && last_ioctl_download) begin + downloaded_config <= 1'b1; + downloaded_dump <= 1'b1; + end + end + else begin + if ((last_ioctl_download != ioctl_download) && (ioctl_download == 1'b0)) begin + if (last_ioctl_index == HS_CONFIGINDEX) downloaded_config <= 1'b1; + if (last_ioctl_index == HS_DUMPINDEX) downloaded_dump <= 1'b1; + end + end + + // Track last cycle values + last_ioctl_download <= ioctl_download; + last_ioctl_index <= ioctl_index; + last_menu_status <= menu_status; + + // Cascade incoming data bytes from HPS + if(ioctl_download && ioctl_wr) begin + last_data_from_mpu3 = last_data_from_mpu2; + last_data_from_mpu2 = last_data_from_mpu; + last_data_from_mpu = data_from_mpu; + end + + // If we have a valid configuration then enable the hiscore system + if(downloaded_config) begin + + // Check for end of core reset to initialise state machine for restore + reset_last <= reset; + if (downloaded_dump == 1'b1 && reset_last == 1'b1 && reset == 1'b0) begin + wait_timer <= START_WAIT; + next_state <= SM_INIT_RESTORE; + state <= SM_TIMER; + counter <= 1'b0; + initialised <= initialised + 1'b1; + restoring_dump <= 1'b1; + end + else begin + // Upload scores if requested by HPS + // - Data is now sent from the hiscore data buffer rather than game RAM as in previous versions + if (uploading_dump == 1'b1) begin + // Set local address to read from hiscore data based on ioctl_address + data_addr <= ioctl_addr[HS_SCOREWIDTH-1:0]; + // Clear dump dirty flag + dump_dirty <= 1'b0; + end + + // Trigger hiscore extraction when OSD is opened + if(last_menu_status==1'b0 && menu_status==1'b1 && extracting_dump==1'b0 && uploading_dump==1'b0 && restoring_dump==1'b0) begin + extracting_dump <= 1'b1; + state <= SM_COMPAREINIT; + end + + // Extract hiscore data from game RAM and save in hiscore data buffer + if (extracting_dump == 1'b1) begin + case (state) + // Compare process states + SM_COMPAREINIT: // Initialise state machine for comparison + begin + // Setup addresses and comparison flags + buffer_addr <= 0; + data_addr <= 0; + counter <= 0; + compare_nonzero <= 1'b0; + compare_changed <= 1'b0; + compare_length <= 1'b0; + // Pause cpu and wait for next state + pause_cpu <= 1'b1; + state <= SM_TIMER; + next_state <= SM_COMPAREBEGIN; + wait_timer <= ACCESS_PAUSEPAD; + end + SM_COMPAREBEGIN: begin + // Get ready to read next line (wait until addr_base is updated) + reading_scores <= 1'b1; + state <= SM_COMPAREREADY; + end + SM_COMPAREREADY: begin + // Set ram address and wait for it to return correctly + ram_addr <= addr_base; + if(ram_addr == addr_base) begin + state <= SM_COMPAREREAD; + end + end + SM_COMPAREREAD: begin + // Setup next address and signal write enable to hiscore buffer + buffer_write <= 1'b1; + state <= SM_COMPAREDONE; + end + SM_COMPAREDONE: begin + // If RAM data has changed since last dump and there is either no mask or a 1 in the mask for this address + if (data_from_ram != hiscore_data_out && (CHANGEMASK==8'b0 || check_mask==1)) begin + // Hiscore data changed + compare_changed <= 1'b1; + end + if (data_from_ram != 8'b0) begin + // Hiscore data is not blank + compare_nonzero <= 1'b1; + end + compare_length <= compare_length + 20'b1; + // Move to next entry when last address is reached + if (ram_addr == end_addr) begin + // If this was the last entry then we are done + if (counter == total_entries) begin + state <= SM_TIMER; + reading_scores <= 1'b0; + next_state <= SM_COMPARECOMPLETE; + wait_timer <= ACCESS_PAUSEPAD; + end + else begin + // Next config line + counter <= counter + 1'b1; + state <= SM_COMPAREBEGIN; + end + end + else begin + // Keep extracting this section + state <= SM_COMPAREREAD; + ram_addr <= ram_addr + 1'b1; + end + // Always stop writing to hiscore dump ram and increment local address + buffer_addr <= buffer_addr + 1'b1; + data_addr <= data_addr + 1'b1; + buffer_write <= 1'b0; + end + SM_COMPARECOMPLETE: begin + pause_cpu <= 1'b0; + reading_scores <= 1'b0; + if (compare_changed == 1'b1 && compare_nonzero == 1'b1) begin + // If high scores have changed and are not blank, update the hiscore data from extract buffer + dump_dirty <= 1'b1; + state <= SM_EXTRACTINIT; + end + else begin + // If no change or scores are invalid leave the existing hiscore data in place + if(dump_dirty == 1'b1 && autosave == 1'b1) begin + state <= SM_EXTRACTSAVE; + end + else begin + extracting_dump <= 1'b0; + state <= SM_STOPPED; + end + end + end + SM_EXTRACTINIT: begin + // Setup address and counter + data_addr <= 0; + buffer_addr <= 0; + state <= SM_EXTRACT; + dump_write <= 1'b1; + end + SM_EXTRACT: begin + // Keep writing until end of buffer + if (buffer_addr == compare_length) begin + dump_write <= 1'b0; + state <= SM_EXTRACTSAVE; + end + // Increment buffer address and set data address to one behind + data_addr <= buffer_addr; + buffer_addr <= buffer_addr + 1'b1; + end + SM_EXTRACTSAVE: begin + if(autosave == 1'b1) begin + ioctl_upload_req <= 1'b1; + state <= SM_TIMER; + next_state <= SM_EXTRACTCOMPLETE; + wait_timer <= 4'd4; + end + else begin + extracting_dump <= 1'b0; + state <= SM_STOPPED; + end + end + SM_EXTRACTCOMPLETE: begin + ioctl_upload_req <= 1'b0; + extracting_dump <= 1'b0; + state <= SM_STOPPED; + end + endcase + end + + // If we are not uploading or resetting and valid hiscore data is available then start the state machine to write data to game RAM + if (uploading_dump == 1'b0 && downloaded_dump == 1'b1 && reset == 1'b0) begin + // State machine to write data to game RAM + case (state) + SM_INIT_RESTORE: // Start state machine + begin + // Setup base addresses + data_addr <= 0; + base_io_addr <= 25'b0; + // Reset entry counter and states + counter <= 0; + writing_scores <= 1'b0; + checking_scores <= 1'b0; + pause_cpu <= 1'b0; + state <= SM_CHECKPREP; + end + + // Start/end check states + // ---------------------- + SM_CHECKPREP: // Prepare start/end check run - pause CPU in readiness for RAM access + begin + state <= SM_TIMER; + next_state <= SM_CHECKBEGIN; + pause_cpu <= 1'b1; + wait_timer <= ACCESS_PAUSEPAD; + end + + SM_CHECKBEGIN: // Begin start/end check run - enable RAM access + begin + checking_scores <= 1'b1; + ram_addr <= {1'b0, addr_base}; + state <= SM_CHECKSTARTVAL; + wait_timer <= CHECK_HOLD; + end + + SM_CHECKSTARTVAL: // Start check + begin + // Check for matching start value + if(wait_timer != CHECK_HOLD && data_from_ram == start_val) begin + // Prepare end check + ram_addr <= end_addr; + state <= SM_CHECKENDVAL; + wait_timer <= CHECK_HOLD; + end + else begin + ram_addr <= {1'b0, addr_base}; + if (wait_timer > 1'b0) begin + wait_timer <= wait_timer - 1'b1; + end + else begin + // - If no match after read wait then stop check run and schedule restart of state machine + next_state <= SM_CHECKCANCEL; + state <= SM_TIMER; + checking_scores <= 1'b0; + wait_timer <= ACCESS_PAUSEPAD; + end + end + end + + SM_CHECKENDVAL: // End check + begin + // Check for matching end value + if (wait_timer != CHECK_HOLD & data_from_ram == end_val) begin + if (counter == total_entries) begin + // If this was the last entry then move on to writing scores to game ram + checking_scores <= 1'b0; + state <= SM_WRITEBEGIN; // Bypass SM_WRITEPREP as we are already paused + counter <= 1'b0; + write_counter <= 1'b0; + ram_write <= 1'b0; + ram_addr <= {1'b0, addr_base}; + end + else begin + // Increment counter and restart state machine to check next entry + counter <= counter + 1'b1; + state <= SM_CHECKBEGIN; + end + end + else begin + ram_addr <= end_addr; + if (wait_timer > 1'b0) begin + wait_timer <= wait_timer - 1'b1; + end + else begin + // - If no match after read wait then stop check run and schedule restart of state machine + next_state <= SM_CHECKCANCEL; + state <= SM_TIMER; + checking_scores <= 1'b0; + wait_timer <= ACCESS_PAUSEPAD; + end + end + end + + SM_CHECKCANCEL: // Cancel start/end check run - disable RAM access and keep CPU paused + begin + pause_cpu <= 1'b0; + next_state <= SM_INIT_RESTORE; + state <= SM_TIMER; + wait_timer <= CHECK_WAIT; + end + + // Write to game RAM states + // ---------------------- + SM_WRITEPREP: // Prepare to write scores - pause CPU in readiness for RAM access (only used on subsequent write attempts) + begin + state <= SM_TIMER; + next_state <= SM_WRITEBEGIN; + pause_cpu <= 1'b1; + wait_timer <= ACCESS_PAUSEPAD; + end + + SM_WRITEBEGIN: // Writing scores to game RAM begins + begin + writing_scores <= 1'b1; // Enable muxes if necessary + write_counter <= write_counter + 1'b1; + state <= SM_WRITEREADY; + end + + SM_WRITEREADY: // local ram should be correct, start write to game RAM + begin + ram_addr <= addr_base + (data_addr - base_io_addr); + state <= SM_TIMER; + next_state <= SM_WRITEDONE; + wait_timer <= WRITE_HOLD; + ram_write <= 1'b1; + end + + SM_WRITEDONE: begin + data_addr <= data_addr + 1'b1; // Increment to next byte of entry + if (ram_addr == end_addr) begin + // End of entry reached + if (counter == total_entries) begin + state <= SM_WRITECOMPLETE; + end + else begin + // Move to next entry + counter <= counter + 1'b1; + write_counter <= 1'b0; + base_io_addr <= data_addr + 1'b1; + state <= SM_WRITEBEGIN; + end + end + else begin + state <= SM_WRITEREADY; + end + ram_write <= 1'b0; + end + + SM_WRITECOMPLETE: // Hiscore write to RAM completed + begin + ram_write <= 1'b0; + writing_scores <= 1'b0; + restoring_dump <= 1'b0; + state <= SM_TIMER; + if(write_counter < WRITE_REPEATCOUNT) begin + // Schedule next write + next_state <= SM_WRITERETRY; + data_addr <= 0; + wait_timer <= WRITE_REPEATWAIT; + end + else begin + next_state <= SM_STOPPED; + wait_timer <= ACCESS_PAUSEPAD; + end + end + + SM_WRITERETRY: // Stop pause and schedule next write + begin + pause_cpu <= 1'b0; + state <= SM_TIMER; + next_state <= SM_WRITEPREP; + wait_timer <= WRITE_REPEATWAIT; + end + + SM_STOPPED: begin + pause_cpu <= 1'b0; + end + endcase + end + + if(state == SM_TIMER) // timer wait state + begin + // Do not progress timer if CPU is paused by source other than this module + // - Stops initial hiscore load delay being foiled by user pausing/entering OSD + if (paused == 1'b0 || pause_cpu == 1'b1) begin + if (wait_timer > 1'b0) begin + wait_timer <= wait_timer - 1'b1; + end + else begin + state <= next_state; + end + end + end + end + end + end + +endmodule diff --git a/platform/pocket/support/hiscore_io.sv b/platform/pocket/support/hiscore_io.sv index beb0f6e..6e8079f 100644 --- a/platform/pocket/support/hiscore_io.sv +++ b/platform/pocket/support/hiscore_io.sv @@ -1,257 +1,257 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket HiScore NVRAM/SRAM I/O Controller for APF bridge -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module hiscore_io - #( - // HiScore - parameter HS_AW = 16, //! Max size of game RAM address for highscores - parameter HS_SW = 8, //! Max size of capture RAM For highscore data (default 8 = 256 bytes max) - parameter HS_CFG_AW = 2, //! Max size of RAM address for highscore.dat entries (default 4 = 16 entries max) - parameter HS_CFG_LW = 2, //! Max size of length for each highscore.dat entries (default 1 = 256 bytes max) - parameter HS_CONFIG = 2, //! Dataslot index for config transfer - parameter HS_DATA = 3, //! Dataslot index for save data transfer - // MPU <-> FPGA I/O - parameter HS_MASK = 4'h6, //! Upper 4 bits of address - parameter HS_WR_DELAY = 4, //! Number of clock cycles to delay each write output - parameter HS_WR_HOLD = 1, //! Number of clock cycles to hold the nvram_wr signal high - parameter HS_RD_DELAY = 4, //! Number of memory clock cycles it takes for a read to complete - // NVRAM HiScore - parameter HS_USE_NVRAM = 0, //! Use NVRAM HiScore Module - parameter HS_PAUSE_PAD = 4 //! Cycles to wait with paused CPU before and after NVRAM access - ) ( - input logic clk_74a, - input logic clk_memory, - input logic pll_core_locked, - input logic reset_sw, - input logic pause_core, - // Pocket Bridge Data Slots - input logic dataslot_requestwrite, - input logic [15:0] dataslot_requestwrite_id, - input logic dataslot_requestread, - input logic [15:0] dataslot_requestread_id, - input logic dataslot_allcomplete, - // Pocket Bridge - input logic bridge_endian_little, - input logic [31:0] bridge_addr, - input logic bridge_wr, - input logic [31:0] bridge_wr_data, - input logic bridge_rd, - output logic [31:0] bridge_rd_data = 0, - // Pocket Bridge Data Tables - output logic [9:0] datatable_addr, - output logic datatable_wren, - output logic [31:0] datatable_data, - // HiScore NVRAM Size - input logic [15:0] nvram_size, //! Number bytes required for Save - // HiScore Interface - output logic hs_write_en, - output logic [HS_AW-1:0] hs_address, - input logic [7:0] hs_data_out, - output logic [7:0] hs_data_in, - output logic hs_access_read, - output logic hs_access_write, - output logic hs_configured, - output logic hs_pause - ); - - //! ------------------------------------------------------------------------ - //! Internal Wires and Registers - //! ------------------------------------------------------------------------ - logic [HS_AW-1:0] nvram_rd_addr; - logic [HS_AW-1:0] nvram_wr_addr; - - logic nvram_download = 0; - logic [15:0] nvram_index; - logic nvram_wr; - logic [HS_AW-1:0] nvram_addr; - logic [7:0] nvram_dout; - - logic nvram_upload = 0; - logic nvram_upload_req; - logic [15:0] nvram_upload_index; - logic [7:0] nvram_din; - logic nvram_rd; - - //! ------------------------------------------------------------------------ - //! Sync and Assignments - //! ------------------------------------------------------------------------ - assign nvram_addr = nvram_wr ? nvram_wr_addr : nvram_rd_addr; - synch_3 #(.WIDTH(16)) sync_nvram_index(dataslot_requestwrite_id, nvram_index, clk_memory); - - //! ------------------------------------------------------------------------ - //! Download/Upload Signal Handler - //! ------------------------------------------------------------------------ - always_ff @(posedge clk_74a) begin - if (dataslot_requestwrite && (dataslot_requestwrite_id == HS_DATA) || (dataslot_requestwrite_id == HS_CONFIG)) begin - nvram_download <= 1; - end - else if(dataslot_requestread && (dataslot_requestread_id == HS_DATA)) begin - nvram_upload <= 1; - end - else if(dataslot_allcomplete) begin - nvram_download <= 0; - nvram_upload <= 0; - end - end - - //! ------------------------------------------------------------------------ - //! Configure Save Data Size - //! ------------------------------------------------------------------------ - always_ff @(posedge clk_74a or negedge pll_core_locked) begin - if (~pll_core_locked) begin - datatable_addr <= 0; - datatable_wren <= 0; - datatable_data <= 0; - end - else begin - datatable_addr <= HS_DATA * 2 + 1; // Data slot index, not id - datatable_wren <= 1; // Write nvram size - datatable_data <= nvram_size; // nvram size is the number bytes - end - end - - //! ------------------------------------------------------------------------ - //! MPU -> FPGA Download - //! ------------------------------------------------------------------------ - data_loader #( - .ADDRESS_MASK_UPPER_4 ( HS_MASK ), - .WRITE_MEM_CLOCK_DELAY ( HS_WR_DELAY ), - .WRITE_MEM_EN_CYCLE_LENGTH ( HS_WR_HOLD ), - .ADDRESS_SIZE ( HS_AW ) - ) hiscore_in ( - .clk_74a ( clk_74a ), - .clk_memory ( clk_memory ), - - .bridge_wr ( bridge_wr ), - .bridge_endian_little ( bridge_endian_little ), - .bridge_addr ( bridge_addr ), - .bridge_wr_data ( bridge_wr_data ), - - .write_en ( nvram_wr ), - .write_addr ( nvram_wr_addr ), - .write_data ( nvram_dout ) - ); - - //! ------------------------------------------------------------------------ - //! FPGA -> MPU Upload - //! ------------------------------------------------------------------------ - data_unloader #( - .ADDRESS_MASK_UPPER_4 ( HS_MASK ), - .READ_MEM_CLOCK_DELAY ( HS_RD_DELAY ), - .ADDRESS_SIZE ( HS_AW ) - ) hiscore_out ( - .clk_74a ( clk_74a ), - .clk_memory ( clk_memory ), - - .bridge_rd ( bridge_rd ), - .bridge_endian_little ( bridge_endian_little ), - .bridge_addr ( bridge_addr ), - .bridge_rd_data ( bridge_rd_data ), - - .read_en ( nvram_rd ), - .read_addr ( nvram_rd_addr ), - .read_data ( nvram_din ) - ); - - generate - if(HS_USE_NVRAM) begin - //! ------------------------------------------------------------------------ - //! NVRAM HiScore - //! ------------------------------------------------------------------------ - nvram #( - .DUMPWIDTH ( HS_SW ), - .CONFIGINDEX ( HS_CONFIG ), - .DUMPINDEX ( HS_DATA ), - .PAUSEPAD ( HS_PAUSE_PAD ) - ) nvram_hiscore_io ( - .clk ( clk_memory ), - .paused ( pause_core ), - .reset ( reset_sw ), - .autosave ( 1 ), - .OSD_STATUS ( pause_core ), - // I/O Interface - .ioctl_upload ( nvram_upload ), - .ioctl_upload_req ( nvram_upload_req ), - .ioctl_download ( nvram_download ), - .ioctl_wr ( nvram_wr ), - .ioctl_addr ( nvram_addr ), - .ioctl_index ( nvram_index ), - .ioctl_din ( nvram_din ), - .ioctl_dout ( nvram_dout ), - // Core Interface - .nvram_address ( hs_address ), - .nvram_data_out ( hs_data_out ), - .pause_cpu ( hs_pause ) - ); - end - else begin - //! ------------------------------------------------------------------------ - //! HiScore - //! ------------------------------------------------------------------------ - hiscore #( - .HS_ADDRESSWIDTH ( HS_AW ), - .HS_SCOREWIDTH ( HS_SW ), - .HS_CONFIGINDEX ( HS_CONFIG ), - .HS_DUMPINDEX ( HS_DATA ), - .CFG_ADDRESSWIDTH ( HS_CFG_AW ), - .CFG_LENGTHWIDTH ( HS_CFG_LW ) - ) hiscore_io ( - .clk ( clk_memory ), // [i] - .reset ( reset_sw ), // [i] - .autosave ( 1 ), // [i] - .paused ( pause_core ), // [i] - .menu_status ( pause_core ), // [i] - // I/O Interface - .ioctl_upload ( nvram_upload ), // [i] - .ioctl_upload_req ( nvram_upload_req ), // [o] - .ioctl_download ( nvram_download ), // [i] - .ioctl_wr ( nvram_wr ), // [i] - .ioctl_addr ( nvram_addr ), // [i] - .ioctl_index ( nvram_index ), // [i] - // Core Interface - .ram_address ( hs_address ), // [o] Address in game RAM to read/write score data - .data_from_ram ( hs_data_out ), // [i] Incoming data from game RAM - .data_to_ram ( hs_data_in ), // [o] Data to send to game RAM - .ram_write ( hs_write_en ), // [o] Write to game RAM (active high) - - .data_from_mpu ( nvram_dout ), // [i] Incoming data from MPU - .data_to_mpu ( nvram_din ), // [o] Data to send to MPU - .ram_intent_read ( hs_access_read ), // [o] RAM read required (active high) - .ram_intent_write ( hs_access_write ), // [o] RAM write required (active high) - .pause_cpu ( hs_pause ), // [o] Pause core CPU to prepare for/relax after RAM access - .configured ( hs_configured ) // [o] Hiscore module has valid configuration (active high) - ); - end - endgenerate - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket HiScore NVRAM/SRAM I/O Controller for APF bridge +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module hiscore_io + #( + // HiScore + parameter HS_AW = 16, //! Max size of game RAM address for highscores + parameter HS_SW = 8, //! Max size of capture RAM For highscore data (default 8 = 256 bytes max) + parameter HS_CFG_AW = 2, //! Max size of RAM address for highscore.dat entries (default 4 = 16 entries max) + parameter HS_CFG_LW = 2, //! Max size of length for each highscore.dat entries (default 1 = 256 bytes max) + parameter HS_CONFIG = 2, //! Dataslot index for config transfer + parameter HS_DATA = 3, //! Dataslot index for save data transfer + // MPU <-> FPGA I/O + parameter HS_MASK = 4'h6, //! Upper 4 bits of address + parameter HS_WR_DELAY = 4, //! Number of clock cycles to delay each write output + parameter HS_WR_HOLD = 1, //! Number of clock cycles to hold the nvram_wr signal high + parameter HS_RD_DELAY = 4, //! Number of memory clock cycles it takes for a read to complete + // NVRAM HiScore + parameter HS_USE_NVRAM = 0, //! Use NVRAM HiScore Module + parameter HS_PAUSE_PAD = 4 //! Cycles to wait with paused CPU before and after NVRAM access + ) ( + input logic clk_74a, + input logic clk_memory, + input logic pll_core_locked, + input logic reset_sw, + input logic pause_core, + // Pocket Bridge Data Slots + input logic dataslot_requestwrite, + input logic [15:0] dataslot_requestwrite_id, + input logic dataslot_requestread, + input logic [15:0] dataslot_requestread_id, + input logic dataslot_allcomplete, + // Pocket Bridge + input logic bridge_endian_little, + input logic [31:0] bridge_addr, + input logic bridge_wr, + input logic [31:0] bridge_wr_data, + input logic bridge_rd, + output logic [31:0] bridge_rd_data = 0, + // Pocket Bridge Data Tables + output logic [9:0] datatable_addr, + output logic datatable_wren, + output logic [31:0] datatable_data, + // HiScore NVRAM Size + input logic [15:0] nvram_size, //! Number bytes required for Save + // HiScore Interface + output logic hs_write_en, + output logic [HS_AW-1:0] hs_address, + input logic [7:0] hs_data_out, + output logic [7:0] hs_data_in, + output logic hs_access_read, + output logic hs_access_write, + output logic hs_configured, + output logic hs_pause + ); + + //! ------------------------------------------------------------------------ + //! Internal Wires and Registers + //! ------------------------------------------------------------------------ + logic [HS_AW-1:0] nvram_rd_addr; + logic [HS_AW-1:0] nvram_wr_addr; + + logic nvram_download = 0; + logic [15:0] nvram_index; + logic nvram_wr; + logic [HS_AW-1:0] nvram_addr; + logic [7:0] nvram_dout; + + logic nvram_upload = 0; + logic nvram_upload_req; + logic [15:0] nvram_upload_index; + logic [7:0] nvram_din; + logic nvram_rd; + + //! ------------------------------------------------------------------------ + //! Sync and Assignments + //! ------------------------------------------------------------------------ + assign nvram_addr = nvram_wr ? nvram_wr_addr : nvram_rd_addr; + synch_3 #(.WIDTH(16)) sync_nvram_index(dataslot_requestwrite_id, nvram_index, clk_memory); + + //! ------------------------------------------------------------------------ + //! Download/Upload Signal Handler + //! ------------------------------------------------------------------------ + always_ff @(posedge clk_74a) begin + if (dataslot_requestwrite && (dataslot_requestwrite_id == HS_DATA) || (dataslot_requestwrite_id == HS_CONFIG)) begin + nvram_download <= 1; + end + else if(dataslot_requestread && (dataslot_requestread_id == HS_DATA)) begin + nvram_upload <= 1; + end + else if(dataslot_allcomplete) begin + nvram_download <= 0; + nvram_upload <= 0; + end + end + + //! ------------------------------------------------------------------------ + //! Configure Save Data Size + //! ------------------------------------------------------------------------ + always_ff @(posedge clk_74a or negedge pll_core_locked) begin + if (~pll_core_locked) begin + datatable_addr <= 0; + datatable_wren <= 0; + datatable_data <= 0; + end + else begin + datatable_addr <= HS_DATA * 2 + 1; // Data slot index, not id + datatable_wren <= 1; // Write nvram size + datatable_data <= nvram_size; // nvram size is the number bytes + end + end + + //! ------------------------------------------------------------------------ + //! MPU -> FPGA Download + //! ------------------------------------------------------------------------ + data_loader #( + .ADDRESS_MASK_UPPER_4 ( HS_MASK ), + .WRITE_MEM_CLOCK_DELAY ( HS_WR_DELAY ), + .WRITE_MEM_EN_CYCLE_LENGTH ( HS_WR_HOLD ), + .ADDRESS_SIZE ( HS_AW ) + ) hiscore_in ( + .clk_74a ( clk_74a ), + .clk_memory ( clk_memory ), + + .bridge_wr ( bridge_wr ), + .bridge_endian_little ( bridge_endian_little ), + .bridge_addr ( bridge_addr ), + .bridge_wr_data ( bridge_wr_data ), + + .write_en ( nvram_wr ), + .write_addr ( nvram_wr_addr ), + .write_data ( nvram_dout ) + ); + + //! ------------------------------------------------------------------------ + //! FPGA -> MPU Upload + //! ------------------------------------------------------------------------ + data_unloader #( + .ADDRESS_MASK_UPPER_4 ( HS_MASK ), + .READ_MEM_CLOCK_DELAY ( HS_RD_DELAY ), + .ADDRESS_SIZE ( HS_AW ) + ) hiscore_out ( + .clk_74a ( clk_74a ), + .clk_memory ( clk_memory ), + + .bridge_rd ( bridge_rd ), + .bridge_endian_little ( bridge_endian_little ), + .bridge_addr ( bridge_addr ), + .bridge_rd_data ( bridge_rd_data ), + + .read_en ( nvram_rd ), + .read_addr ( nvram_rd_addr ), + .read_data ( nvram_din ) + ); + + generate + if(HS_USE_NVRAM) begin + //! ------------------------------------------------------------------------ + //! NVRAM HiScore + //! ------------------------------------------------------------------------ + nvram #( + .DUMPWIDTH ( HS_SW ), + .CONFIGINDEX ( HS_CONFIG ), + .DUMPINDEX ( HS_DATA ), + .PAUSEPAD ( HS_PAUSE_PAD ) + ) nvram_hiscore_io ( + .clk ( clk_memory ), + .paused ( pause_core ), + .reset ( reset_sw ), + .autosave ( 1 ), + .OSD_STATUS ( pause_core ), + // I/O Interface + .ioctl_upload ( nvram_upload ), + .ioctl_upload_req ( nvram_upload_req ), + .ioctl_download ( nvram_download ), + .ioctl_wr ( nvram_wr ), + .ioctl_addr ( nvram_addr ), + .ioctl_index ( nvram_index ), + .ioctl_din ( nvram_din ), + .ioctl_dout ( nvram_dout ), + // Core Interface + .nvram_address ( hs_address ), + .nvram_data_out ( hs_data_out ), + .pause_cpu ( hs_pause ) + ); + end + else begin + //! ------------------------------------------------------------------------ + //! HiScore + //! ------------------------------------------------------------------------ + hiscore #( + .HS_ADDRESSWIDTH ( HS_AW ), + .HS_SCOREWIDTH ( HS_SW ), + .HS_CONFIGINDEX ( HS_CONFIG ), + .HS_DUMPINDEX ( HS_DATA ), + .CFG_ADDRESSWIDTH ( HS_CFG_AW ), + .CFG_LENGTHWIDTH ( HS_CFG_LW ) + ) hiscore_io ( + .clk ( clk_memory ), // [i] + .reset ( reset_sw ), // [i] + .autosave ( 1 ), // [i] + .paused ( pause_core ), // [i] + .menu_status ( pause_core ), // [i] + // I/O Interface + .ioctl_upload ( nvram_upload ), // [i] + .ioctl_upload_req ( nvram_upload_req ), // [o] + .ioctl_download ( nvram_download ), // [i] + .ioctl_wr ( nvram_wr ), // [i] + .ioctl_addr ( nvram_addr ), // [i] + .ioctl_index ( nvram_index ), // [i] + // Core Interface + .ram_address ( hs_address ), // [o] Address in game RAM to read/write score data + .data_from_ram ( hs_data_out ), // [i] Incoming data from game RAM + .data_to_ram ( hs_data_in ), // [o] Data to send to game RAM + .ram_write ( hs_write_en ), // [o] Write to game RAM (active high) + + .data_from_mpu ( nvram_dout ), // [i] Incoming data from MPU + .data_to_mpu ( nvram_din ), // [o] Data to send to MPU + .ram_intent_read ( hs_access_read ), // [o] RAM read required (active high) + .ram_intent_write ( hs_access_write ), // [o] RAM write required (active high) + .pause_cpu ( hs_pause ), // [o] Pause core CPU to prepare for/relax after RAM access + .configured ( hs_configured ) // [o] Hiscore module has valid configuration (active high) + ); + end + endgenerate + +endmodule diff --git a/platform/pocket/support/nvram.sv b/platform/pocket/support/nvram.sv index ee128c0..a787eae 100644 --- a/platform/pocket/support/nvram.sv +++ b/platform/pocket/support/nvram.sv @@ -1,257 +1,257 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// NVRAM-style hiscore autosave support for arcade cores. -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2021, Jim Gregory -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. -// -// You should have received a copy of the GNU General Public License along -// with this program; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -// -//------------------------------------------------------------------------------ -// -// Version history: -// 0001 - 2021-10-01 - First marked release -// 0002 - 2021-10-09 - Add change mask support -// 0003 - 2023-06-21 - Changes for the Analogue Pocket -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module nvram - #( - parameter DUMPWIDTH = 8, // Address size of NVRAM for highscore data (default 8 = 256 bytes max) - parameter CONFIGINDEX = 2, // ioctl_index for config transfer - parameter DUMPINDEX = 3, // ioctl_index for dump transfer - parameter PAUSEPAD = 4, // Cycles to wait with paused CPU before and after NVRAM access - parameter TARGET_PLATFORM = 1 // Platform: [1] Analogue Pocket | [2] MiMiC - ) ( - input wire clk, - input wire paused, // Signal from core confirming CPU is paused - input wire reset, - input wire autosave, // Auto-save enabled (active high) - - input wire ioctl_upload, - output reg ioctl_upload_req, - input wire ioctl_download, - input wire ioctl_wr, - input wire [24:0] ioctl_addr, - input wire [7:0] ioctl_index, - output wire [7:0] ioctl_din, - input wire [7:0] ioctl_dout, - input wire OSD_STATUS, - - output wire [DUMPWIDTH-1:0] nvram_address, - input wire [7:0] nvram_data_out, - - output reg pause_cpu // Pause core CPU to prepare for/relax after NVRAM access - ); - - // Hiscore data tracking - reg downloaded_config = 1'b0; // Has hiscore config been loaded? - reg downloaded_dump = 1'b0; // Has hiscore data been loaded? - reg extracting_dump = 1'b0; // Is hiscore data currently extracted and checked for change? - wire downloading_config; // Is hiscore config currently being loaded? - wire downloading_dump; // Is hiscore data currently being loaded? - wire uploading_dump; // Is hiscore data currently being saved? - - assign downloading_config = ioctl_download && (ioctl_index == CONFIGINDEX); - assign downloading_dump = ioctl_download && (ioctl_index == DUMPINDEX); - assign uploading_dump = ioctl_upload && (ioctl_index == DUMPINDEX); - - // State machine constants - localparam SM_STATEWIDTH = 3; // Width of state machine net - localparam SM_IDLE = 0; - localparam SM_TIMER = 1; - localparam SM_EXTRACTINIT = 2; - localparam SM_EXTRACTREADY = 3; - localparam SM_EXTRACTNEXT = 4; - localparam SM_EXTRACTSAVE = 5; - localparam SM_EXTRACTCOMPLETE = 6; - - // State machine control - reg [(SM_STATEWIDTH-1):0] state = SM_IDLE; // Current state machine index - reg [(SM_STATEWIDTH-1):0] next_state = SM_IDLE; // Next state machine index to move to after wait timer expires - reg [31:0] wait_timer; // Wait timer for inital/read/write delays - - // Last cycle signals - reg last_reset = 1'b0; // Last cycle reset - reg last_OSD_STATUS; // Last cycle OSD status - reg [7:0] last_ioctl_index; // Last cycle HPS IO index - reg last_ioctl_download = 0; // Last cycle HPS IO download - - // Buffer RAM control signals - reg [DUMPWIDTH-1:0] buffer_addr; - reg [DUMPWIDTH-1:0] buffer_length; - wire [7:0] buffer_data_in; - reg buffer_write = 1'b0; - - assign nvram_address = buffer_addr; - - // Change detection signals - reg [DUMPWIDTH-1:0] compare_length = 1'b0; - reg compare_nonzero = 1'b1; // High after extract and compare if any byte returned is non-zero - reg compare_changed = 1'b1; // High after extract and compare if any byte is different to current hiscore data - wire [7:0] check_mask_out /* synthesis keep */; - wire check_mask = check_mask_out[buffer_addr[2:0]] /* synthesis keep */; - - // RAM used to store high score check mask - spram_hs #(.aWidth(DUMPWIDTH-3),.dWidth(8)) - mask_ram ( - .clk(clk), - .addr(downloading_config ? ioctl_addr[DUMPWIDTH-4:0] : buffer_addr[DUMPWIDTH-1:3]), - .we(downloading_config && ioctl_wr), - .d(ioctl_dout), - .q(check_mask_out) - ); - - // RAM used to store high score data buffer - spram_hs #(.aWidth(DUMPWIDTH),.dWidth(8)) - nvram_buffer ( - .clk(clk), - .addr((downloading_dump || uploading_dump) ? ioctl_addr[DUMPWIDTH-1:0] : buffer_addr), - .we(downloading_dump ? ioctl_wr : buffer_write), - .d(downloading_dump ? ioctl_dout : nvram_data_out), - .q(ioctl_din) - ); - - always @(posedge clk) begin - - // Track completion of configuration and dump download - if(TARGET_PLATFORM == 1) begin - if (~ioctl_download && last_ioctl_download) begin - downloaded_config <= 1'b1; - downloaded_dump <= 1'b1; - end - end - else begin - if ((last_ioctl_download != ioctl_download) && (ioctl_download == 1'b0)) begin - if (last_ioctl_index == CONFIGINDEX) downloaded_config <= 1'b1; - if (last_ioctl_index == DUMPINDEX) downloaded_dump <= 1'b1; - end - end - - // Track last cycle values - last_ioctl_download <= ioctl_download; - last_ioctl_index <= ioctl_index; - last_OSD_STATUS <= OSD_STATUS; - last_reset <= reset; - - // Check for end of core reset to initialise hiscore system state - if (last_reset == 1'b1 && reset == 1'b0) begin - next_state <= SM_IDLE; - state <= SM_IDLE; - extracting_dump <= 1'b0; - buffer_length <= (2**DUMPWIDTH) - 1'b1; - end - else begin - - // Trigger hiscore extraction when OSD is opened - if(last_OSD_STATUS==1'b0 && OSD_STATUS==1'b1 && extracting_dump==1'b0 && uploading_dump==1'b0) begin - extracting_dump <= 1'b1; - state <= SM_EXTRACTINIT; - end - - // Extract hiscore data from game RAM and save in hiscore data buffer - if (extracting_dump == 1'b1) begin - case (state) - SM_EXTRACTINIT: // Initialise state machine for extraction - begin - // Setup addresses and comparison flags - buffer_addr <= 1'b0; - buffer_write <= 1'b0; - compare_nonzero <= 1'b0; - compare_changed <= 1'b0; - compare_length <= 1'b0; - // Pause cpu and wait for next state - pause_cpu <= 1'b1; - state <= SM_TIMER; - next_state <= SM_EXTRACTREADY; - wait_timer <= PAUSEPAD; - ioctl_upload_req <= 1'b0; - end - SM_EXTRACTREADY: begin - // Schedule write for next cycle when addresses are ready - buffer_write <= 1'b1; - compare_length <= compare_length + 1'b1; - state <= SM_EXTRACTNEXT; - end - SM_EXTRACTNEXT: begin - if ((nvram_data_out != ioctl_din) && (downloaded_config == 1'b0 || check_mask == 1'b1)) begin - compare_changed <= 1'b1; // Hiscore data changed since last dump - end - - if (nvram_data_out != 8'b0) begin - compare_nonzero <= 1'b1; // Hiscore data is not blank - end - - // Always stop writing to hiscore dump ram and increment local address - buffer_write <= 1'b0; - buffer_addr <= buffer_addr + 1'b1; - - if (compare_length == buffer_length) begin - // Finish extract if last address is reached - state <= SM_TIMER; - next_state <= SM_EXTRACTSAVE; - wait_timer <= PAUSEPAD; - end - else begin - // Otherwise move to next byte - state <= SM_TIMER; - next_state <= SM_EXTRACTREADY; - wait_timer <= 1'b0; - end - - end - SM_EXTRACTSAVE: begin - // If high scores have changed and are not blank, then trigger autosave if enabled - if (compare_changed == 1'b1 && compare_nonzero == 1'b1 && autosave == 1'b1) begin - ioctl_upload_req <= 1'b1; - end - - // Release pause and schedule end of extraction process - pause_cpu <= 1'b0; - state <= SM_TIMER; - next_state <= SM_EXTRACTCOMPLETE; - wait_timer <= 4'd4; - end - SM_EXTRACTCOMPLETE: begin - // End extract, clear any upload request and move state machine to idle - extracting_dump <= 1'b0; - ioctl_upload_req <= 1'b0; - state <= SM_IDLE; - end - endcase - end - - if(state == SM_TIMER) // timer wait state - begin - // Do not progress timer if CPU is paused by source other than this module - if (paused == 1'b0 || pause_cpu == 1'b1) begin - if (wait_timer > 1'b0) - wait_timer <= wait_timer - 1'b1; - else - state <= next_state; - end - end - end - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// NVRAM-style hiscore autosave support for arcade cores. +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2021, Jim Gregory +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +//------------------------------------------------------------------------------ +// +// Version history: +// 0001 - 2021-10-01 - First marked release +// 0002 - 2021-10-09 - Add change mask support +// 0003 - 2023-06-21 - Changes for the Analogue Pocket +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module nvram + #( + parameter DUMPWIDTH = 8, // Address size of NVRAM for highscore data (default 8 = 256 bytes max) + parameter CONFIGINDEX = 2, // ioctl_index for config transfer + parameter DUMPINDEX = 3, // ioctl_index for dump transfer + parameter PAUSEPAD = 4, // Cycles to wait with paused CPU before and after NVRAM access + parameter TARGET_PLATFORM = 1 // Platform: [1] Analogue Pocket | [2] MiMiC + ) ( + input wire clk, + input wire paused, // Signal from core confirming CPU is paused + input wire reset, + input wire autosave, // Auto-save enabled (active high) + + input wire ioctl_upload, + output reg ioctl_upload_req, + input wire ioctl_download, + input wire ioctl_wr, + input wire [24:0] ioctl_addr, + input wire [7:0] ioctl_index, + output wire [7:0] ioctl_din, + input wire [7:0] ioctl_dout, + input wire OSD_STATUS, + + output wire [DUMPWIDTH-1:0] nvram_address, + input wire [7:0] nvram_data_out, + + output reg pause_cpu // Pause core CPU to prepare for/relax after NVRAM access + ); + + // Hiscore data tracking + reg downloaded_config = 1'b0; // Has hiscore config been loaded? + reg downloaded_dump = 1'b0; // Has hiscore data been loaded? + reg extracting_dump = 1'b0; // Is hiscore data currently extracted and checked for change? + wire downloading_config; // Is hiscore config currently being loaded? + wire downloading_dump; // Is hiscore data currently being loaded? + wire uploading_dump; // Is hiscore data currently being saved? + + assign downloading_config = ioctl_download && (ioctl_index == CONFIGINDEX); + assign downloading_dump = ioctl_download && (ioctl_index == DUMPINDEX); + assign uploading_dump = ioctl_upload && (ioctl_index == DUMPINDEX); + + // State machine constants + localparam SM_STATEWIDTH = 3; // Width of state machine net + localparam SM_IDLE = 0; + localparam SM_TIMER = 1; + localparam SM_EXTRACTINIT = 2; + localparam SM_EXTRACTREADY = 3; + localparam SM_EXTRACTNEXT = 4; + localparam SM_EXTRACTSAVE = 5; + localparam SM_EXTRACTCOMPLETE = 6; + + // State machine control + reg [(SM_STATEWIDTH-1):0] state = SM_IDLE; // Current state machine index + reg [(SM_STATEWIDTH-1):0] next_state = SM_IDLE; // Next state machine index to move to after wait timer expires + reg [31:0] wait_timer; // Wait timer for inital/read/write delays + + // Last cycle signals + reg last_reset = 1'b0; // Last cycle reset + reg last_OSD_STATUS; // Last cycle OSD status + reg [7:0] last_ioctl_index; // Last cycle HPS IO index + reg last_ioctl_download = 0; // Last cycle HPS IO download + + // Buffer RAM control signals + reg [DUMPWIDTH-1:0] buffer_addr; + reg [DUMPWIDTH-1:0] buffer_length; + wire [7:0] buffer_data_in; + reg buffer_write = 1'b0; + + assign nvram_address = buffer_addr; + + // Change detection signals + reg [DUMPWIDTH-1:0] compare_length = 1'b0; + reg compare_nonzero = 1'b1; // High after extract and compare if any byte returned is non-zero + reg compare_changed = 1'b1; // High after extract and compare if any byte is different to current hiscore data + wire [7:0] check_mask_out /* synthesis keep */; + wire check_mask = check_mask_out[buffer_addr[2:0]] /* synthesis keep */; + + // RAM used to store high score check mask + spram_hs #(.aWidth(DUMPWIDTH-3),.dWidth(8)) + mask_ram ( + .clk(clk), + .addr(downloading_config ? ioctl_addr[DUMPWIDTH-4:0] : buffer_addr[DUMPWIDTH-1:3]), + .we(downloading_config && ioctl_wr), + .d(ioctl_dout), + .q(check_mask_out) + ); + + // RAM used to store high score data buffer + spram_hs #(.aWidth(DUMPWIDTH),.dWidth(8)) + nvram_buffer ( + .clk(clk), + .addr((downloading_dump || uploading_dump) ? ioctl_addr[DUMPWIDTH-1:0] : buffer_addr), + .we(downloading_dump ? ioctl_wr : buffer_write), + .d(downloading_dump ? ioctl_dout : nvram_data_out), + .q(ioctl_din) + ); + + always @(posedge clk) begin + + // Track completion of configuration and dump download + if(TARGET_PLATFORM == 1) begin + if (~ioctl_download && last_ioctl_download) begin + downloaded_config <= 1'b1; + downloaded_dump <= 1'b1; + end + end + else begin + if ((last_ioctl_download != ioctl_download) && (ioctl_download == 1'b0)) begin + if (last_ioctl_index == CONFIGINDEX) downloaded_config <= 1'b1; + if (last_ioctl_index == DUMPINDEX) downloaded_dump <= 1'b1; + end + end + + // Track last cycle values + last_ioctl_download <= ioctl_download; + last_ioctl_index <= ioctl_index; + last_OSD_STATUS <= OSD_STATUS; + last_reset <= reset; + + // Check for end of core reset to initialise hiscore system state + if (last_reset == 1'b1 && reset == 1'b0) begin + next_state <= SM_IDLE; + state <= SM_IDLE; + extracting_dump <= 1'b0; + buffer_length <= (2**DUMPWIDTH) - 1'b1; + end + else begin + + // Trigger hiscore extraction when OSD is opened + if(last_OSD_STATUS==1'b0 && OSD_STATUS==1'b1 && extracting_dump==1'b0 && uploading_dump==1'b0) begin + extracting_dump <= 1'b1; + state <= SM_EXTRACTINIT; + end + + // Extract hiscore data from game RAM and save in hiscore data buffer + if (extracting_dump == 1'b1) begin + case (state) + SM_EXTRACTINIT: // Initialise state machine for extraction + begin + // Setup addresses and comparison flags + buffer_addr <= 1'b0; + buffer_write <= 1'b0; + compare_nonzero <= 1'b0; + compare_changed <= 1'b0; + compare_length <= 1'b0; + // Pause cpu and wait for next state + pause_cpu <= 1'b1; + state <= SM_TIMER; + next_state <= SM_EXTRACTREADY; + wait_timer <= PAUSEPAD; + ioctl_upload_req <= 1'b0; + end + SM_EXTRACTREADY: begin + // Schedule write for next cycle when addresses are ready + buffer_write <= 1'b1; + compare_length <= compare_length + 1'b1; + state <= SM_EXTRACTNEXT; + end + SM_EXTRACTNEXT: begin + if ((nvram_data_out != ioctl_din) && (downloaded_config == 1'b0 || check_mask == 1'b1)) begin + compare_changed <= 1'b1; // Hiscore data changed since last dump + end + + if (nvram_data_out != 8'b0) begin + compare_nonzero <= 1'b1; // Hiscore data is not blank + end + + // Always stop writing to hiscore dump ram and increment local address + buffer_write <= 1'b0; + buffer_addr <= buffer_addr + 1'b1; + + if (compare_length == buffer_length) begin + // Finish extract if last address is reached + state <= SM_TIMER; + next_state <= SM_EXTRACTSAVE; + wait_timer <= PAUSEPAD; + end + else begin + // Otherwise move to next byte + state <= SM_TIMER; + next_state <= SM_EXTRACTREADY; + wait_timer <= 1'b0; + end + + end + SM_EXTRACTSAVE: begin + // If high scores have changed and are not blank, then trigger autosave if enabled + if (compare_changed == 1'b1 && compare_nonzero == 1'b1 && autosave == 1'b1) begin + ioctl_upload_req <= 1'b1; + end + + // Release pause and schedule end of extraction process + pause_cpu <= 1'b0; + state <= SM_TIMER; + next_state <= SM_EXTRACTCOMPLETE; + wait_timer <= 4'd4; + end + SM_EXTRACTCOMPLETE: begin + // End extract, clear any upload request and move state machine to idle + extracting_dump <= 1'b0; + ioctl_upload_req <= 1'b0; + state <= SM_IDLE; + end + endcase + end + + if(state == SM_TIMER) // timer wait state + begin + // Do not progress timer if CPU is paused by source other than this module + if (paused == 1'b0 || pause_cpu == 1'b1) begin + if (wait_timer > 1'b0) + wait_timer <= wait_timer - 1'b1; + else + state <= next_state; + end + end + end + end + +endmodule diff --git a/platform/pocket/support/save_io.sv b/platform/pocket/support/save_io.sv index f986254..fde097d 100644 --- a/platform/pocket/support/save_io.sv +++ b/platform/pocket/support/save_io.sv @@ -1,139 +1,139 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Analogue Pocket Save I/O Controller for APF bridge -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module save_io - #( - // MPU <-> FPGA (NVRAM/SAVE I/O) - parameter MASK = 4'h6, //! Upper 4 bits of address - parameter AW = 27, //! Address Width - parameter DW = 8, //! Data Width (8 or 16 bits) - parameter WR_DELAY = 4, //! Number of clock cycles to delay each write output - parameter WR_HOLD = 1, //! Number of clock cycles to hold the ioctl_wr signal high - parameter RD_DELAY = 4, //! Number of memory clock cycles it takes for a read to complete - parameter SAVE_IDX = 3 //! Dataslot index for save data transfer - ) ( - input logic clk_74a, - input logic clk_memory, - // Pocket Bridge Slots - input logic dataslot_requestwrite, - input logic [15:0] dataslot_requestwrite_id, - input logic dataslot_requestread, - input logic [15:0] dataslot_requestread_id, - input logic dataslot_allcomplete, - // Pocket Bridge - input logic bridge_endian_little, - input logic [31:0] bridge_addr, - input logic bridge_wr, - input logic [31:0] bridge_wr_data, - input logic bridge_rd, - output logic [31:0] bridge_rd_data = 0, - // MPU <-> FPGA - output logic nvram_download = 0, - output logic [15:0] nvram_index, - output logic nvram_wr, - output logic [AW-1:0] nvram_addr, - output logic [DW-1:0] nvram_dout, - output logic nvram_upload = 0, - input logic nvram_upload_req, - input logic [15:0] nvram_upload_index, - input logic [DW-1:0] nvram_din, - output logic nvram_rd - ); - - localparam WORD_SIZE = DW == 16 ? 2 : 1; - - logic [AW-1:0] nvram_rd_addr; - logic [AW-1:0] nvram_wr_addr; - - assign nvram_addr = nvram_wr ? nvram_wr_addr : nvram_rd_addr; - synch_3 #(.WIDTH(16)) sync_nvram_index(dataslot_requestwrite_id, nvram_index, clk_memory); - - always_ff @(posedge clk_74a) begin - if (dataslot_requestwrite && (dataslot_requestwrite_id == SAVE_IDX)) begin - nvram_download <= 1; - end - else if(dataslot_requestread && (dataslot_requestread_id == SAVE_IDX)) begin - nvram_upload <= 1; - end - else if(dataslot_allcomplete) begin - nvram_download <= 0; - nvram_upload <= 0; - end - end - - //! ------------------------------------------------------------------------ - //! MPU -> FPGA Download - //! ------------------------------------------------------------------------ - data_loader #( - .ADDRESS_MASK_UPPER_4 ( MASK ), - .WRITE_MEM_CLOCK_DELAY ( WR_DELAY ), - .WRITE_MEM_EN_CYCLE_LENGTH ( WR_HOLD ), - .ADDRESS_SIZE ( AW ), - .OUTPUT_WORD_SIZE ( WORD_SIZE ) - ) save_data_in ( - .clk_74a ( clk_74a ), - .clk_memory ( clk_memory ), - - .bridge_wr ( bridge_wr ), - .bridge_endian_little ( bridge_endian_little ), - .bridge_addr ( bridge_addr ), - .bridge_wr_data ( bridge_wr_data ), - - .write_en ( nvram_wr ), - .write_addr ( nvram_wr_addr ), - .write_data ( nvram_dout ) - ); - - //! ------------------------------------------------------------------------ - //! FPGA -> MPU Upload - //! ------------------------------------------------------------------------ - data_unloader #( - .ADDRESS_MASK_UPPER_4 ( MASK ), - .READ_MEM_CLOCK_DELAY ( RD_DELAY ), - .ADDRESS_SIZE ( AW ), - .INPUT_WORD_SIZE ( WORD_SIZE ) - ) save_data_out ( - .clk_74a ( clk_74a ), - .clk_memory ( clk_memory ), - - .bridge_rd ( bridge_rd ), - .bridge_endian_little ( bridge_endian_little ), - .bridge_addr ( bridge_addr ), - .bridge_rd_data ( bridge_rd_data ), - - .read_en ( nvram_rd ), - .read_addr ( nvram_rd_addr ), - .read_data ( nvram_din ) - ); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Analogue Pocket Save I/O Controller for APF bridge +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module save_io + #( + // MPU <-> FPGA (NVRAM/SAVE I/O) + parameter MASK = 4'h6, //! Upper 4 bits of address + parameter AW = 27, //! Address Width + parameter DW = 8, //! Data Width (8 or 16 bits) + parameter WR_DELAY = 4, //! Number of clock cycles to delay each write output + parameter WR_HOLD = 1, //! Number of clock cycles to hold the ioctl_wr signal high + parameter RD_DELAY = 4, //! Number of memory clock cycles it takes for a read to complete + parameter SAVE_IDX = 3 //! Dataslot index for save data transfer + ) ( + input logic clk_74a, + input logic clk_memory, + // Pocket Bridge Slots + input logic dataslot_requestwrite, + input logic [15:0] dataslot_requestwrite_id, + input logic dataslot_requestread, + input logic [15:0] dataslot_requestread_id, + input logic dataslot_allcomplete, + // Pocket Bridge + input logic bridge_endian_little, + input logic [31:0] bridge_addr, + input logic bridge_wr, + input logic [31:0] bridge_wr_data, + input logic bridge_rd, + output logic [31:0] bridge_rd_data = 0, + // MPU <-> FPGA + output logic nvram_download = 0, + output logic [15:0] nvram_index, + output logic nvram_wr, + output logic [AW-1:0] nvram_addr, + output logic [DW-1:0] nvram_dout, + output logic nvram_upload = 0, + input logic nvram_upload_req, + input logic [15:0] nvram_upload_index, + input logic [DW-1:0] nvram_din, + output logic nvram_rd + ); + + localparam WORD_SIZE = DW == 16 ? 2 : 1; + + logic [AW-1:0] nvram_rd_addr; + logic [AW-1:0] nvram_wr_addr; + + assign nvram_addr = nvram_wr ? nvram_wr_addr : nvram_rd_addr; + synch_3 #(.WIDTH(16)) sync_nvram_index(dataslot_requestwrite_id, nvram_index, clk_memory); + + always_ff @(posedge clk_74a) begin + if (dataslot_requestwrite && (dataslot_requestwrite_id == SAVE_IDX)) begin + nvram_download <= 1; + end + else if(dataslot_requestread && (dataslot_requestread_id == SAVE_IDX)) begin + nvram_upload <= 1; + end + else if(dataslot_allcomplete) begin + nvram_download <= 0; + nvram_upload <= 0; + end + end + + //! ------------------------------------------------------------------------ + //! MPU -> FPGA Download + //! ------------------------------------------------------------------------ + data_loader #( + .ADDRESS_MASK_UPPER_4 ( MASK ), + .WRITE_MEM_CLOCK_DELAY ( WR_DELAY ), + .WRITE_MEM_EN_CYCLE_LENGTH ( WR_HOLD ), + .ADDRESS_SIZE ( AW ), + .OUTPUT_WORD_SIZE ( WORD_SIZE ) + ) save_data_in ( + .clk_74a ( clk_74a ), + .clk_memory ( clk_memory ), + + .bridge_wr ( bridge_wr ), + .bridge_endian_little ( bridge_endian_little ), + .bridge_addr ( bridge_addr ), + .bridge_wr_data ( bridge_wr_data ), + + .write_en ( nvram_wr ), + .write_addr ( nvram_wr_addr ), + .write_data ( nvram_dout ) + ); + + //! ------------------------------------------------------------------------ + //! FPGA -> MPU Upload + //! ------------------------------------------------------------------------ + data_unloader #( + .ADDRESS_MASK_UPPER_4 ( MASK ), + .READ_MEM_CLOCK_DELAY ( RD_DELAY ), + .ADDRESS_SIZE ( AW ), + .INPUT_WORD_SIZE ( WORD_SIZE ) + ) save_data_out ( + .clk_74a ( clk_74a ), + .clk_memory ( clk_memory ), + + .bridge_rd ( bridge_rd ), + .bridge_endian_little ( bridge_endian_little ), + .bridge_addr ( bridge_addr ), + .bridge_rd_data ( bridge_rd_data ), + + .read_en ( nvram_rd ), + .read_addr ( nvram_rd_addr ), + .read_data ( nvram_din ) + ); + +endmodule diff --git a/platform/pocket/video/scanlines.sv b/platform/pocket/video/scanlines.sv index 390c197..1c9412b 100644 --- a/platform/pocket/video/scanlines.sv +++ b/platform/pocket/video/scanlines.sv @@ -1,111 +1,111 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Video Scanlines Generator -// -// Copyright (c) 2023, Marcus Andrade -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ -// | Horizontal Lines | -// | Soft | 25% | 4'b0001 | 4'd1 | -// | Medium | 50% | 4'b0010 | 4'd2 | -// | Hard | 75% | 4'b0011 | 4'd3 | -// -// | Vertical Lines | -// | Soft | 25% | 4'b0100 | 4'd4 | -// | Medium | 50% | 4'b1000 | 4'd8 | -// | Hard | 75% | 4'b1100 | 4'd12 | -// -// | Horizontal and Vertical Lines | -// | Soft | 25% | 4'b0101 | 4'd5 | -// | Medium | 50% | 4'b1010 | 4'd10 | -// | Hard | 75% | 4'b1111 | 4'd15 | -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module scanlines - ( - // Clock - input clk_vid, //! Pixel Clock - // Scanline Control - input [3:0] scnl_sw, //! Scanlines - // Video Input - input [23:0] core_rgb, //! Core: RGB Video - input core_hs, //! Core: Hsync - input core_vs, //! Core: Vsync - input core_de, //! Core: Data Enable - // Video Output - output reg [23:0] scnl_rgb, //! Ouput: RGB Video - output reg scnl_hs, //! Ouput: Hsync - output reg scnl_vs, //! Ouput: Vsync - output reg scnl_de //! Ouput: Data Enable - ); - - //! ------------------------------------------------------------------------ - //! Horizontal Scanlines - //! ------------------------------------------------------------------------ - wire [23:0] h_video_rgb; - wire h_video_hs, h_video_vs, h_video_de; - - scanlines_generator #(.ORIENTATION(0)) scanlines_horizontal - ( - .clk_vid ( clk_vid ), - .scanlines ( scnl_sw[1:0] ), - .core_rgb ( core_rgb ), - .core_hs ( core_hs ), - .core_vs ( core_vs ), - .core_de ( core_de ), - .scnl_rgb ( h_video_rgb ), - .scnl_hs ( h_video_hs ), - .scnl_vs ( h_video_vs ), - .scnl_de ( h_video_de ) - ); - - //! ------------------------------------------------------------------------ - //! Vertical Scanlines - //! ------------------------------------------------------------------------ - wire [23:0] v_video_rgb; - wire v_video_hs, v_video_vs, v_video_de; - - scanlines_generator #(.ORIENTATION(1)) scanlines_vertical - ( - .clk_vid ( clk_vid ), - .scanlines ( scnl_sw[3:2] ), - .core_rgb ( h_video_rgb ), - .core_hs ( h_video_hs ), - .core_vs ( h_video_vs ), - .core_de ( h_video_de ), - .scnl_rgb ( v_video_rgb ), - .scnl_hs ( v_video_hs ), - .scnl_vs ( v_video_vs ), - .scnl_de ( v_video_de ) - ); - - //! ------------------------------------------------------------------------ - //! Video Output - //! ------------------------------------------------------------------------ - always_ff @(posedge clk_vid) begin - scnl_rgb <= v_video_rgb; - scnl_hs <= v_video_hs; - scnl_vs <= v_video_vs; - scnl_de <= v_video_de; - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Video Scanlines Generator +// +// Copyright (c) 2023, Marcus Andrade +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ +// | Horizontal Lines | +// | Soft | 25% | 4'b0001 | 4'd1 | +// | Medium | 50% | 4'b0010 | 4'd2 | +// | Hard | 75% | 4'b0011 | 4'd3 | +// +// | Vertical Lines | +// | Soft | 25% | 4'b0100 | 4'd4 | +// | Medium | 50% | 4'b1000 | 4'd8 | +// | Hard | 75% | 4'b1100 | 4'd12 | +// +// | Horizontal and Vertical Lines | +// | Soft | 25% | 4'b0101 | 4'd5 | +// | Medium | 50% | 4'b1010 | 4'd10 | +// | Hard | 75% | 4'b1111 | 4'd15 | +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module scanlines + ( + // Clock + input clk_vid, //! Pixel Clock + // Scanline Control + input [3:0] scnl_sw, //! Scanlines + // Video Input + input [23:0] core_rgb, //! Core: RGB Video + input core_hs, //! Core: Hsync + input core_vs, //! Core: Vsync + input core_de, //! Core: Data Enable + // Video Output + output reg [23:0] scnl_rgb, //! Ouput: RGB Video + output reg scnl_hs, //! Ouput: Hsync + output reg scnl_vs, //! Ouput: Vsync + output reg scnl_de //! Ouput: Data Enable + ); + + //! ------------------------------------------------------------------------ + //! Horizontal Scanlines + //! ------------------------------------------------------------------------ + wire [23:0] h_video_rgb; + wire h_video_hs, h_video_vs, h_video_de; + + scanlines_generator #(.ORIENTATION(0)) scanlines_horizontal + ( + .clk_vid ( clk_vid ), + .scanlines ( scnl_sw[1:0] ), + .core_rgb ( core_rgb ), + .core_hs ( core_hs ), + .core_vs ( core_vs ), + .core_de ( core_de ), + .scnl_rgb ( h_video_rgb ), + .scnl_hs ( h_video_hs ), + .scnl_vs ( h_video_vs ), + .scnl_de ( h_video_de ) + ); + + //! ------------------------------------------------------------------------ + //! Vertical Scanlines + //! ------------------------------------------------------------------------ + wire [23:0] v_video_rgb; + wire v_video_hs, v_video_vs, v_video_de; + + scanlines_generator #(.ORIENTATION(1)) scanlines_vertical + ( + .clk_vid ( clk_vid ), + .scanlines ( scnl_sw[3:2] ), + .core_rgb ( h_video_rgb ), + .core_hs ( h_video_hs ), + .core_vs ( h_video_vs ), + .core_de ( h_video_de ), + .scnl_rgb ( v_video_rgb ), + .scnl_hs ( v_video_hs ), + .scnl_vs ( v_video_vs ), + .scnl_de ( v_video_de ) + ); + + //! ------------------------------------------------------------------------ + //! Video Output + //! ------------------------------------------------------------------------ + always_ff @(posedge clk_vid) begin + scnl_rgb <= v_video_rgb; + scnl_hs <= v_video_hs; + scnl_vs <= v_video_vs; + scnl_de <= v_video_de; + end + +endmodule diff --git a/platform/pocket/video/scanlines_generator.sv b/platform/pocket/video/scanlines_generator.sv index 94a6536..13ea84a 100644 --- a/platform/pocket/video/scanlines_generator.sv +++ b/platform/pocket/video/scanlines_generator.sv @@ -1,121 +1,121 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Generic Video Scanlines -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2017, Alexey Melnikov -// Copyright (c) 2015, Till Harbaum -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module scanlines_generator - #( - parameter ORIENTATION = 0 //! Scanline Orientation [0]: Horizontal | [01] Vertical - ) ( - // Clock - input logic clk_vid, //! Pixel Clock - // Scanline Control - input logic [1:0] scanlines, //! Scanlines - [00]: None | [01]: 25% | [10]: 50% | [11]: 75% - // Video Input - input logic [23:0] core_rgb, //! Core: RGB Video - input logic core_hs, //! Core: Vsync - input logic core_vs, //! Core: Hsync - input logic core_de, //! Core: Data Enable - // Video Output - output logic [23:0] scnl_rgb, //! Ouput: RGB Video - output logic scnl_hs, //! Ouput: Vsync - output logic scnl_vs, //! Ouput: Hsync - output logic scnl_de //! Ouput: Data Enable - ); - - wire [7:0] r, g, b; //! RGB Signals - assign {r, g, b} = core_rgb; //! Concatenation the RGB Signals - - reg [1:0] scanline_r; //! Scanline Register - reg [23:0] rgb_r; //! RGB Data - - //! ------------------------------------------------------------------------ - //! Generate vertical or horizontal scanline based on ORIENTATION parameter - //! ------------------------------------------------------------------------ - generate - if (ORIENTATION) begin - always_ff @(posedge clk_vid) begin - reg rOLD_VS; - rOLD_VS <= core_vs; - // XOR scanline value with scanlines - scanline_r <= scanline_r ^ scanlines; - // Detect end of frame (Vsync falling edge) and reset scanline counter to 0 - if(rOLD_VS && ~core_vs) begin scanline_r <= 0; end - end - end - else begin - always_ff @(posedge clk_vid) begin - reg rOLD_HS, rOLD_VS; - rOLD_HS <= core_hs; - rOLD_VS <= core_vs; - // Detect end of line (Hsync falling edge) and XOR scanline value with scanlines - if(rOLD_HS && ~core_hs) begin scanline_r <= scanline_r ^ scanlines; end - // Detect end of frame (Vsync falling edge) and reset scanline counter to 0 - if(rOLD_VS && ~core_vs) begin scanline_r <= 0; end - end - end - endgenerate - - //! ------------------------------------------------------------------------ - //! Generate scanline effect on RGB data - //! ------------------------------------------------------------------------ - // 00: 00% - Set the output RGB data to be the same as the input RGB data. - // 01: 25% [1/2 + 1/4] - Concatenate the second and third bit of each color channel and add them to the first bit shifted left by one position, with an additional 0 in the least significant position. - // 10: 50% [1/2] - Keep only the first bit of each color channel. - // 11: 75% [1/4] - Keep only the second and third bits of each color channel, with an additional 0 in the most significant position. - always_comb begin - case(scanline_r) - 2'b00: begin rgb_r = {r, g, b}; end - 2'b01: begin rgb_r = {{1'b0, r[7:1]} + {2'b0, r[7:2]}, {1'b0, g[7:1]} + {2'b0, g[7:2]}, {1'b0, b[7:1]} + {2'b0, b[7:2]}}; end - 2'b10: begin rgb_r = {{1'b0, r[7:1]}, {1'b0, g[7:1]}, {1'b0, b[7:1]}}; end - 2'b11: begin rgb_r = {{2'b0, r[7:2]}, {2'b0, g[7:2]}, {2'b0, b[7:2]}}; end - endcase - end - - //! ------------------------------------------------------------------------ - //! Video Output - //! ------------------------------------------------------------------------ - always_ff @(posedge clk_vid) begin - // Declare registers to hold the previous and current values of the input signals - reg [23:0] rgb1, rgb2; // 24-bit RGB color values for current and previous cycles - reg hs1, hs2; // Horizontal Sync (HS) signal for current and previous cycles - reg vs1, vs2; // Vertical Sync (VS) signal for current and previous cycles - reg de1, de2; // Display Enable (DE) signal for current and previous cycles - - // Assign output signals to the values of the previous cycle - scnl_rgb <= rgb2; // Output RGB color value from two cycles ago - scnl_vs <= vs2; // Output VS signal from two cycles ago - scnl_hs <= hs2; // Output HS signal from two cycles ago - scnl_de <= de2; // Output DE signal from two cycles ago - - // Update the values of the registers with the current cycle's input signals - rgb2 <= rgb1; rgb1 <= rgb_r; // Shift the RGB values by one cycle and assign the current value - vs2 <= vs1; vs1 <= core_vs; // Shift the VS signal by one cycle and assign the current value - hs2 <= hs1; hs1 <= core_hs; // Shift the HS signal by one cycle and assign the current value - de2 <= de1; de1 <= core_de; // Shift the DE signal by one cycle and assign the current value - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Generic Video Scanlines +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2017, Alexey Melnikov +// Copyright (c) 2015, Till Harbaum +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module scanlines_generator + #( + parameter ORIENTATION = 0 //! Scanline Orientation [0]: Horizontal | [01] Vertical + ) ( + // Clock + input logic clk_vid, //! Pixel Clock + // Scanline Control + input logic [1:0] scanlines, //! Scanlines - [00]: None | [01]: 25% | [10]: 50% | [11]: 75% + // Video Input + input logic [23:0] core_rgb, //! Core: RGB Video + input logic core_hs, //! Core: Vsync + input logic core_vs, //! Core: Hsync + input logic core_de, //! Core: Data Enable + // Video Output + output logic [23:0] scnl_rgb, //! Ouput: RGB Video + output logic scnl_hs, //! Ouput: Vsync + output logic scnl_vs, //! Ouput: Hsync + output logic scnl_de //! Ouput: Data Enable + ); + + wire [7:0] r, g, b; //! RGB Signals + assign {r, g, b} = core_rgb; //! Concatenation the RGB Signals + + reg [1:0] scanline_r; //! Scanline Register + reg [23:0] rgb_r; //! RGB Data + + //! ------------------------------------------------------------------------ + //! Generate vertical or horizontal scanline based on ORIENTATION parameter + //! ------------------------------------------------------------------------ + generate + if (ORIENTATION) begin + always_ff @(posedge clk_vid) begin + reg rOLD_VS; + rOLD_VS <= core_vs; + // XOR scanline value with scanlines + scanline_r <= scanline_r ^ scanlines; + // Detect end of frame (Vsync falling edge) and reset scanline counter to 0 + if(rOLD_VS && ~core_vs) begin scanline_r <= 0; end + end + end + else begin + always_ff @(posedge clk_vid) begin + reg rOLD_HS, rOLD_VS; + rOLD_HS <= core_hs; + rOLD_VS <= core_vs; + // Detect end of line (Hsync falling edge) and XOR scanline value with scanlines + if(rOLD_HS && ~core_hs) begin scanline_r <= scanline_r ^ scanlines; end + // Detect end of frame (Vsync falling edge) and reset scanline counter to 0 + if(rOLD_VS && ~core_vs) begin scanline_r <= 0; end + end + end + endgenerate + + //! ------------------------------------------------------------------------ + //! Generate scanline effect on RGB data + //! ------------------------------------------------------------------------ + // 00: 00% - Set the output RGB data to be the same as the input RGB data. + // 01: 25% [1/2 + 1/4] - Concatenate the second and third bit of each color channel and add them to the first bit shifted left by one position, with an additional 0 in the least significant position. + // 10: 50% [1/2] - Keep only the first bit of each color channel. + // 11: 75% [1/4] - Keep only the second and third bits of each color channel, with an additional 0 in the most significant position. + always_comb begin + case(scanline_r) + 2'b00: begin rgb_r = {r, g, b}; end + 2'b01: begin rgb_r = {{1'b0, r[7:1]} + {2'b0, r[7:2]}, {1'b0, g[7:1]} + {2'b0, g[7:2]}, {1'b0, b[7:1]} + {2'b0, b[7:2]}}; end + 2'b10: begin rgb_r = {{1'b0, r[7:1]}, {1'b0, g[7:1]}, {1'b0, b[7:1]}}; end + 2'b11: begin rgb_r = {{2'b0, r[7:2]}, {2'b0, g[7:2]}, {2'b0, b[7:2]}}; end + endcase + end + + //! ------------------------------------------------------------------------ + //! Video Output + //! ------------------------------------------------------------------------ + always_ff @(posedge clk_vid) begin + // Declare registers to hold the previous and current values of the input signals + reg [23:0] rgb1, rgb2; // 24-bit RGB color values for current and previous cycles + reg hs1, hs2; // Horizontal Sync (HS) signal for current and previous cycles + reg vs1, vs2; // Vertical Sync (VS) signal for current and previous cycles + reg de1, de2; // Display Enable (DE) signal for current and previous cycles + + // Assign output signals to the values of the previous cycle + scnl_rgb <= rgb2; // Output RGB color value from two cycles ago + scnl_vs <= vs2; // Output VS signal from two cycles ago + scnl_hs <= hs2; // Output HS signal from two cycles ago + scnl_de <= de2; // Output DE signal from two cycles ago + + // Update the values of the registers with the current cycle's input signals + rgb2 <= rgb1; rgb1 <= rgb_r; // Shift the RGB values by one cycle and assign the current value + vs2 <= vs1; vs1 <= core_vs; // Shift the VS signal by one cycle and assign the current value + hs2 <= hs1; hs1 <= core_hs; // Shift the HS signal by one cycle and assign the current value + de2 <= de1; de1 <= core_de; // Shift the DE signal by one cycle and assign the current value + end + +endmodule diff --git a/platform/pocket/video/shadowmask.sv b/platform/pocket/video/shadowmask.sv index e062b2d..e9b80df 100644 --- a/platform/pocket/video/shadowmask.sv +++ b/platform/pocket/video/shadowmask.sv @@ -1,182 +1,182 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Video Shadow Mask -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2020, Alexey Melnikov -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module shadowmask - ( - // Clocks - input wire clk_vid, - input wire clk_sys, - // ShadowMask Config - input wire mask_wr, - input wire [15:0] mask_data, - // Input Controls - input wire mask_enable, - input wire mask_rotate, - input wire mask_2x, - input wire brd_in, - // Input Video - input wire [23:0] din, - input wire hs_in, - input wire vs_in, - input wire de_in, - // Output Video - output reg [23:0] dout, - output reg hs_out, - output reg vs_out, - output reg de_out - ); - - reg [3:0] vmax; - reg [3:0] hmax; - reg [7:0] mask_idx; - reg [10:0] mask_lut[256]; - - initial begin - vmax = 1; - hmax = 1; - mask_lut[0] = 11'h70f; - mask_lut[1] = 11'h00c; - mask_lut[2] = 11'h00c; - mask_lut[3] = 11'h70f; - end - - always_ff @(posedge clk_sys) begin - reg [7:0] idx; - - if (mask_wr) begin - case(mask_data[15:13]) - 3'b000: begin idx <= 0; end - 3'b001: begin vmax <= mask_data[3:0]; end - 3'b010: begin hmax <= mask_data[3:0]; end - 3'b011: begin mask_lut[idx] <= mask_data[10:0]; idx <= idx + 1; end - endcase - end - end - - always_ff @(posedge clk_vid) begin - reg [4:0] hcount; - reg [4:0] vcount; - reg [3:0] hindex; - reg [3:0] vindex; - reg [4:0] hmax2; - reg [4:0] vmax2; - reg [11:0] pcnt,pde; - reg old_hs, old_vs, old_brd; - reg next_v; - - old_hs <= hs_in; - old_vs <= vs_in; - old_brd <= brd_in; - - // hcount and vcount counts pixel rows and columns - // hindex and vindex half the value of the counters for double size patterns - // hindex2, vindex2 swap the h and v counters for drawing rotated masks - hindex <= mask_2x ? hcount[4:1] : hcount[3:0]; - vindex <= mask_2x ? vcount[4:1] : vcount[3:0]; - mask_idx <= mask_rotate ? {hindex,vindex} : {vindex,hindex}; - - // hmax and vmax store these sizes - // hmax2 and vmax2 swap the values to handle rotation - hmax2 <= ((mask_rotate ? vmax : hmax) << mask_2x) | mask_2x; - vmax2 <= ((mask_rotate ? hmax : vmax) << mask_2x) | mask_2x; - - pcnt <= pcnt+1'd1; - if(old_brd && ~brd_in) begin - pde <= pcnt - 4'd3; - end - - hcount <= hcount+1'b1; - if(hcount == hmax2 || pde == pcnt) begin - hcount <= 0; - end - - if(~old_brd && brd_in) begin - next_v <= 1; - end - if(old_vs && ~vs_in) begin - vcount <= 0; - end - if(old_hs && ~hs_in) begin - vcount <= vcount + next_v; - next_v <= 0; - pcnt <= 0; - if (vcount == vmax2) begin - vcount <= 0; - end - end - end - - reg [4:0] r_mul, g_mul, b_mul; // 1.4 fixed point multipliers - always_ff @(posedge clk_vid) begin - reg [10:0] lut; - - lut <= mask_lut[mask_idx]; - - r_mul <= 5'b10000; - g_mul <= 5'b10000; - b_mul <= 5'b10000; // default 100% to all channels - if (mask_enable) begin - r_mul <= lut[10] ? {1'b1,lut[7:4]} : {1'b0,lut[3:0]}; - g_mul <= lut[9] ? {1'b1,lut[7:4]} : {1'b0,lut[3:0]}; - b_mul <= lut[8] ? {1'b1,lut[7:4]} : {1'b0,lut[3:0]}; - end - end - - always_ff @(posedge clk_vid) begin - reg [11:0] vid; - reg [7:0] r1, g1, b1; - reg [7:0] r2, g2, b2; - reg [7:0] r3_x, g3_x, b3_x; // 6.25% + 12.5% - reg [8:0] r3_y, g3_y, b3_y; // 25% + 50% + 100% - reg [8:0] r4, g4, b4; - - // C1 - data input - {r1,g1,b1} <= din; - vid <= {vid[8:0],vs_in, hs_in, de_in}; - - // C2 - relax timings - {r2,g2,b2} <= {r1,g1,b1}; - - // C3 - perform multiplications - r3_x <= ({4{r_mul[0]}} & r2[7:4]) + ({8{r_mul[1]}} & r2[7:3]); - r3_y <= ({6{r_mul[2]}} & r2[7:2]) + ({7{r_mul[3]}} & r2[7:1]) + ({9{r_mul[4]}} & r2[7:0]); - g3_x <= ({4{g_mul[0]}} & g2[7:4]) + ({8{g_mul[1]}} & g2[7:3]); - g3_y <= ({6{g_mul[2]}} & g2[7:2]) + ({7{g_mul[3]}} & g2[7:1]) + ({9{g_mul[4]}} & g2[7:0]); - b3_x <= ({4{b_mul[0]}} & b2[7:4]) + ({8{b_mul[1]}} & b2[7:3]); - b3_y <= ({6{b_mul[2]}} & b2[7:2]) + ({7{b_mul[3]}} & b2[7:1]) + ({9{b_mul[4]}} & b2[7:0]); - - // C4 - combine results - r4 <= r3_x + r3_y; - g4 <= g3_x + g3_y; - b4 <= b3_x + b3_y; - - // C5 - clamp and output - dout <= {{8{r4[8]}} | r4[7:0], {8{g4[8]}} | g4[7:0], {8{b4[8]}} | b4[7:0]}; - {vs_out,hs_out,de_out} <= vid[11:9]; - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Video Shadow Mask +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2020, Alexey Melnikov +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module shadowmask + ( + // Clocks + input wire clk_vid, + input wire clk_sys, + // ShadowMask Config + input wire mask_wr, + input wire [15:0] mask_data, + // Input Controls + input wire mask_enable, + input wire mask_rotate, + input wire mask_2x, + input wire brd_in, + // Input Video + input wire [23:0] din, + input wire hs_in, + input wire vs_in, + input wire de_in, + // Output Video + output reg [23:0] dout, + output reg hs_out, + output reg vs_out, + output reg de_out + ); + + reg [3:0] vmax; + reg [3:0] hmax; + reg [7:0] mask_idx; + reg [10:0] mask_lut[256]; + + initial begin + vmax = 1; + hmax = 1; + mask_lut[0] = 11'h70f; + mask_lut[1] = 11'h00c; + mask_lut[2] = 11'h00c; + mask_lut[3] = 11'h70f; + end + + always_ff @(posedge clk_sys) begin + reg [7:0] idx; + + if (mask_wr) begin + case(mask_data[15:13]) + 3'b000: begin idx <= 0; end + 3'b001: begin vmax <= mask_data[3:0]; end + 3'b010: begin hmax <= mask_data[3:0]; end + 3'b011: begin mask_lut[idx] <= mask_data[10:0]; idx <= idx + 1; end + endcase + end + end + + always_ff @(posedge clk_vid) begin + reg [4:0] hcount; + reg [4:0] vcount; + reg [3:0] hindex; + reg [3:0] vindex; + reg [4:0] hmax2; + reg [4:0] vmax2; + reg [11:0] pcnt,pde; + reg old_hs, old_vs, old_brd; + reg next_v; + + old_hs <= hs_in; + old_vs <= vs_in; + old_brd <= brd_in; + + // hcount and vcount counts pixel rows and columns + // hindex and vindex half the value of the counters for double size patterns + // hindex2, vindex2 swap the h and v counters for drawing rotated masks + hindex <= mask_2x ? hcount[4:1] : hcount[3:0]; + vindex <= mask_2x ? vcount[4:1] : vcount[3:0]; + mask_idx <= mask_rotate ? {hindex,vindex} : {vindex,hindex}; + + // hmax and vmax store these sizes + // hmax2 and vmax2 swap the values to handle rotation + hmax2 <= ((mask_rotate ? vmax : hmax) << mask_2x) | mask_2x; + vmax2 <= ((mask_rotate ? hmax : vmax) << mask_2x) | mask_2x; + + pcnt <= pcnt+1'd1; + if(old_brd && ~brd_in) begin + pde <= pcnt - 4'd3; + end + + hcount <= hcount+1'b1; + if(hcount == hmax2 || pde == pcnt) begin + hcount <= 0; + end + + if(~old_brd && brd_in) begin + next_v <= 1; + end + if(old_vs && ~vs_in) begin + vcount <= 0; + end + if(old_hs && ~hs_in) begin + vcount <= vcount + next_v; + next_v <= 0; + pcnt <= 0; + if (vcount == vmax2) begin + vcount <= 0; + end + end + end + + reg [4:0] r_mul, g_mul, b_mul; // 1.4 fixed point multipliers + always_ff @(posedge clk_vid) begin + reg [10:0] lut; + + lut <= mask_lut[mask_idx]; + + r_mul <= 5'b10000; + g_mul <= 5'b10000; + b_mul <= 5'b10000; // default 100% to all channels + if (mask_enable) begin + r_mul <= lut[10] ? {1'b1,lut[7:4]} : {1'b0,lut[3:0]}; + g_mul <= lut[9] ? {1'b1,lut[7:4]} : {1'b0,lut[3:0]}; + b_mul <= lut[8] ? {1'b1,lut[7:4]} : {1'b0,lut[3:0]}; + end + end + + always_ff @(posedge clk_vid) begin + reg [11:0] vid; + reg [7:0] r1, g1, b1; + reg [7:0] r2, g2, b2; + reg [7:0] r3_x, g3_x, b3_x; // 6.25% + 12.5% + reg [8:0] r3_y, g3_y, b3_y; // 25% + 50% + 100% + reg [8:0] r4, g4, b4; + + // C1 - data input + {r1,g1,b1} <= din; + vid <= {vid[8:0],vs_in, hs_in, de_in}; + + // C2 - relax timings + {r2,g2,b2} <= {r1,g1,b1}; + + // C3 - perform multiplications + r3_x <= ({4{r_mul[0]}} & r2[7:4]) + ({8{r_mul[1]}} & r2[7:3]); + r3_y <= ({6{r_mul[2]}} & r2[7:2]) + ({7{r_mul[3]}} & r2[7:1]) + ({9{r_mul[4]}} & r2[7:0]); + g3_x <= ({4{g_mul[0]}} & g2[7:4]) + ({8{g_mul[1]}} & g2[7:3]); + g3_y <= ({6{g_mul[2]}} & g2[7:2]) + ({7{g_mul[3]}} & g2[7:1]) + ({9{g_mul[4]}} & g2[7:0]); + b3_x <= ({4{b_mul[0]}} & b2[7:4]) + ({8{b_mul[1]}} & b2[7:3]); + b3_y <= ({6{b_mul[2]}} & b2[7:2]) + ({7{b_mul[3]}} & b2[7:1]) + ({9{b_mul[4]}} & b2[7:0]); + + // C4 - combine results + r4 <= r3_x + r3_y; + g4 <= g3_x + g3_y; + b4 <= b3_x + b3_y; + + // C5 - clamp and output + dout <= {{8{r4[8]}} | r4[7:0], {8{g4[8]}} | g4[7:0], {8{b4[8]}} | b4[7:0]}; + {vs_out,hs_out,de_out} <= vid[11:9]; + end + +endmodule diff --git a/platform/pocket/video/video_mixer.sv b/platform/pocket/video/video_mixer.sv index 5b3a048..5c91422 100644 --- a/platform/pocket/video/video_mixer.sv +++ b/platform/pocket/video/video_mixer.sv @@ -1,216 +1,216 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Copyright (c) 2023, Marcus Andrade -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ -// Generic Video Interface for the Analogue Pocket Display -// -// Note: APF scaler requires HSync and VSync to last for a single clock, and -// video_rgb to be 0 when video_de is low -// -// RGB palettes -// -// | RGB Format | Bit Depth | Number of Colors | -// | ---------- | --------- | ---------------- | -// | RGB111 | 3 bits | 8 | -// | RGB222 | 6 bits | 64 | -// | RGB233 | 8 bits | 256 | -// | RGB332 | 8 bits | 256 | -// | RGB333 | 9 bits | 512 | -// | RGB444 | 12 bits | 4,096 | -// | RGB555 | 15 bits | 32,768 | -// | RGB565 | 16 bits | 65,536 | -// | RGB666 | 18 bits | 262,144 | -// | RGB888 | 24 bits | 16,777,216 | -// -//------------------------------------------------------------------------------ - -`default_nettype none - -module video_mixer - #( - parameter RW = 8, //! Bits Per Pixel Red - parameter GW = 8, //! Bits Per Pixel Green - parameter BW = 8 //! Bits Per Pixel Blue - ) ( - // Clocks - input logic clk_74a, //! APF: Main Clock - input logic clk_sys, //! Core: System Clock - input logic clk_vid, //! Core: Pixel Clock - input logic clk_vid_90deg, //! Core: Pixel Clock 90º Phase Shift - // Input Controls - input logic [2:0] video_preset, //! Video preset configurations (up to 8) - input logic [3:0] scnl_sw, //! Scanlines Switches - input logic [3:0] smask_sw, //! Shadow Mask Switches - // Input Video from Core - input logic [RW-1:0] core_r, //! Core: Video Red - input logic [GW-1:0] core_g, //! Core: Video Green - input logic [BW-1:0] core_b, //! Core: Video Blue - input logic core_vs, //! Core: Vsync - input logic core_hs, //! Core: Hsync - input logic core_de, //! Core: Data Enable - // Output to Display Connection - output logic [23:0] video_rgb, //! Display: RGB Color: Red[23:16] Green[15:8] Blue[7:0] - output logic video_vs, //! Display: Video Vertical Sync - output logic video_hs, //! Display: Video Horizontal Sync - output logic video_de, //! Display: Data Enable - output logic video_rgb_clock, //! Display: Pixel Clock - output logic video_rgb_clock_90, //! Display: Pixel Clock 90º Phase Shift - // Pocket Bridge Slots - input logic dataslot_requestwrite, - input logic [15:0] dataslot_requestwrite_id, - input logic dataslot_allcomplete, - // Pocket Bridge - input logic bridge_endian_little, - input logic [31:0] bridge_addr, - input logic bridge_wr, - input logic [31:0] bridge_wr_data - ); - - //! ------------------------------------------------------------------------ - //! Combine Colors to Create a Full RGB888 Color Space - //! ------------------------------------------------------------------------ - reg [7:0] R, G, B; - - always_comb begin - R = RW == 8 ? core_r : {core_r, {8-RW{1'b0}}}; - G = GW == 8 ? core_g : {core_g, {8-GW{1'b0}}}; - B = BW == 8 ? core_b : {core_b, {8-BW{1'b0}}}; - end - - //! ------------------------------------------------------------------------ - //! Scanlines - //! ------------------------------------------------------------------------ - wire [23:0] s_video_rgb; - wire s_video_hs, s_video_vs, s_video_de; - - scanlines video_scanlines - ( - .clk_vid ( clk_vid ), - .scnl_sw ( scnl_sw ), - .core_rgb ( {R, G, B} ), - .core_vs ( core_vs ), - .core_hs ( core_hs ), - .core_de ( core_de ), - .scnl_rgb ( s_video_rgb ), - .scnl_hs ( s_video_hs ), - .scnl_vs ( s_video_vs ), - .scnl_de ( s_video_de ) - ); - - //! ------------------------------------------------------------------------ - //! Shadow Mask - //! ------------------------------------------------------------------------ - wire [23:0] sm_video_rgb; - wire sm_video_hs, sm_video_vs, sm_video_de; - - shadowmask video_shadowmask - ( - .clk_vid ( clk_vid ), - .clk_sys ( clk_sys ), - - .mask_wr ( filter_wr ), - .mask_data ( filter_dout ), - - .mask_enable ( smask_sw[0] ), - .mask_rotate ( smask_sw[1] ), - .mask_2x ( smask_sw[2] ), - .brd_in ( 0 ), - - .din ( s_video_rgb ), - .hs_in ( s_video_hs ), - .vs_in ( s_video_vs ), - .de_in ( s_video_de ), - - .dout ( sm_video_rgb ), - .hs_out ( sm_video_hs ), - .vs_out ( sm_video_vs ), - .de_out ( sm_video_de ) - ); - - //! ------------------------------------------------------------------------ - //! Video Output - //! ------------------------------------------------------------------------ - reg [23:0] video_rgb_r; - reg video_hs_r, video_vs_r, video_de_r; - - always_ff @(posedge clk_vid) begin - video_de <= 0; - video_rgb <= {8'b0, video_preset, 13'b0}; - if (video_de_r) begin - video_de <= 1; - video_rgb <= video_rgb_r; - end - // Set HSync and VSync to be high for a single cycle on the rising edge - // of the HSync and VSync coming out of the core - video_hs <= ~video_hs_r && sm_video_hs; - video_vs <= ~video_vs_r && sm_video_vs; - video_hs_r <= sm_video_hs; - video_vs_r <= sm_video_vs; - video_de_r <= sm_video_de; - video_rgb_r <= sm_video_rgb; - end - - //! ------------------------------------------------------------------------ - //! Clock Output - //! ------------------------------------------------------------------------ - always_comb begin - video_rgb_clock = clk_vid; - video_rgb_clock_90 = clk_vid_90deg; - end - - //! ------------------------------------------------------------------------ - //! MPU -> FPGA Download - //! ------------------------------------------------------------------------ - wire filter_download; - wire [15:0] filter_index; - wire filter_wr; - wire [23:0] filter_addr; - wire [15:0] filter_dout; - - // data_io #(.MASK(4'h1),.AW(24),.DW(16),.DELAY(4),.HOLD(1)) video_config_io - // ( - // // Clocks and Reset - // .clk_74a ( clk_74a ), - // .clk_memory ( clk_sys ), - // // Pocket Bridge Slots - // .dataslot_requestwrite ( dataslot_requestwrite ), // [i] - // .dataslot_requestwrite_id ( dataslot_requestwrite_id ), // [i] - // .dataslot_allcomplete ( dataslot_allcomplete ), // [i] - // // MPU -> FPGA (MPU Write to FPGA) - // // Pocket Bridge - // .bridge_endian_little ( bridge_endian_little ), // [i] - // .bridge_addr ( bridge_addr ), // [i] - // .bridge_wr ( bridge_wr ), // [i] - // .bridge_wr_data ( bridge_wr_data ), // [i] - // // Controller Interface - // .ioctl_download ( filter_download ), // [o] - // .ioctl_index ( filter_index ), // [o] - // .ioctl_wr ( filter_wr ), // [o] - // .ioctl_addr ( filter_addr ), // [o] - // .ioctl_dout ( filter_dout ) // [o] - // ); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Copyright (c) 2023, Marcus Andrade +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ +// Generic Video Interface for the Analogue Pocket Display +// +// Note: APF scaler requires HSync and VSync to last for a single clock, and +// video_rgb to be 0 when video_de is low +// +// RGB palettes +// +// | RGB Format | Bit Depth | Number of Colors | +// | ---------- | --------- | ---------------- | +// | RGB111 | 3 bits | 8 | +// | RGB222 | 6 bits | 64 | +// | RGB233 | 8 bits | 256 | +// | RGB332 | 8 bits | 256 | +// | RGB333 | 9 bits | 512 | +// | RGB444 | 12 bits | 4,096 | +// | RGB555 | 15 bits | 32,768 | +// | RGB565 | 16 bits | 65,536 | +// | RGB666 | 18 bits | 262,144 | +// | RGB888 | 24 bits | 16,777,216 | +// +//------------------------------------------------------------------------------ + +`default_nettype none + +module video_mixer + #( + parameter RW = 8, //! Bits Per Pixel Red + parameter GW = 8, //! Bits Per Pixel Green + parameter BW = 8 //! Bits Per Pixel Blue + ) ( + // Clocks + input logic clk_74a, //! APF: Main Clock + input logic clk_sys, //! Core: System Clock + input logic clk_vid, //! Core: Pixel Clock + input logic clk_vid_90deg, //! Core: Pixel Clock 90º Phase Shift + // Input Controls + input logic [2:0] video_preset, //! Video preset configurations (up to 8) + input logic [3:0] scnl_sw, //! Scanlines Switches + input logic [3:0] smask_sw, //! Shadow Mask Switches + // Input Video from Core + input logic [RW-1:0] core_r, //! Core: Video Red + input logic [GW-1:0] core_g, //! Core: Video Green + input logic [BW-1:0] core_b, //! Core: Video Blue + input logic core_vs, //! Core: Vsync + input logic core_hs, //! Core: Hsync + input logic core_de, //! Core: Data Enable + // Output to Display Connection + output logic [23:0] video_rgb, //! Display: RGB Color: Red[23:16] Green[15:8] Blue[7:0] + output logic video_vs, //! Display: Video Vertical Sync + output logic video_hs, //! Display: Video Horizontal Sync + output logic video_de, //! Display: Data Enable + output logic video_rgb_clock, //! Display: Pixel Clock + output logic video_rgb_clock_90, //! Display: Pixel Clock 90º Phase Shift + // Pocket Bridge Slots + input logic dataslot_requestwrite, + input logic [15:0] dataslot_requestwrite_id, + input logic dataslot_allcomplete, + // Pocket Bridge + input logic bridge_endian_little, + input logic [31:0] bridge_addr, + input logic bridge_wr, + input logic [31:0] bridge_wr_data + ); + + //! ------------------------------------------------------------------------ + //! Combine Colors to Create a Full RGB888 Color Space + //! ------------------------------------------------------------------------ + reg [7:0] R, G, B; + + always_comb begin + R = RW == 8 ? core_r : {core_r, {8-RW{1'b0}}}; + G = GW == 8 ? core_g : {core_g, {8-GW{1'b0}}}; + B = BW == 8 ? core_b : {core_b, {8-BW{1'b0}}}; + end + + //! ------------------------------------------------------------------------ + //! Scanlines + //! ------------------------------------------------------------------------ + wire [23:0] s_video_rgb; + wire s_video_hs, s_video_vs, s_video_de; + + scanlines video_scanlines + ( + .clk_vid ( clk_vid ), + .scnl_sw ( scnl_sw ), + .core_rgb ( {R, G, B} ), + .core_vs ( core_vs ), + .core_hs ( core_hs ), + .core_de ( core_de ), + .scnl_rgb ( s_video_rgb ), + .scnl_hs ( s_video_hs ), + .scnl_vs ( s_video_vs ), + .scnl_de ( s_video_de ) + ); + + //! ------------------------------------------------------------------------ + //! Shadow Mask + //! ------------------------------------------------------------------------ + wire [23:0] sm_video_rgb; + wire sm_video_hs, sm_video_vs, sm_video_de; + + shadowmask video_shadowmask + ( + .clk_vid ( clk_vid ), + .clk_sys ( clk_sys ), + + .mask_wr ( filter_wr ), + .mask_data ( filter_dout ), + + .mask_enable ( smask_sw[0] ), + .mask_rotate ( smask_sw[1] ), + .mask_2x ( smask_sw[2] ), + .brd_in ( 0 ), + + .din ( s_video_rgb ), + .hs_in ( s_video_hs ), + .vs_in ( s_video_vs ), + .de_in ( s_video_de ), + + .dout ( sm_video_rgb ), + .hs_out ( sm_video_hs ), + .vs_out ( sm_video_vs ), + .de_out ( sm_video_de ) + ); + + //! ------------------------------------------------------------------------ + //! Video Output + //! ------------------------------------------------------------------------ + reg [23:0] video_rgb_r; + reg video_hs_r, video_vs_r, video_de_r; + + always_ff @(posedge clk_vid) begin + video_de <= 0; + video_rgb <= {8'b0, video_preset, 13'b0}; + if (video_de_r) begin + video_de <= 1; + video_rgb <= video_rgb_r; + end + // Set HSync and VSync to be high for a single cycle on the rising edge + // of the HSync and VSync coming out of the core + video_hs <= ~video_hs_r && sm_video_hs; + video_vs <= ~video_vs_r && sm_video_vs; + video_hs_r <= sm_video_hs; + video_vs_r <= sm_video_vs; + video_de_r <= sm_video_de; + video_rgb_r <= sm_video_rgb; + end + + //! ------------------------------------------------------------------------ + //! Clock Output + //! ------------------------------------------------------------------------ + always_comb begin + video_rgb_clock = clk_vid; + video_rgb_clock_90 = clk_vid_90deg; + end + + //! ------------------------------------------------------------------------ + //! MPU -> FPGA Download + //! ------------------------------------------------------------------------ + wire filter_download; + wire [15:0] filter_index; + wire filter_wr; + wire [23:0] filter_addr; + wire [15:0] filter_dout; + + // data_io #(.MASK(4'h1),.AW(24),.DW(16),.DELAY(4),.HOLD(1)) video_config_io + // ( + // // Clocks and Reset + // .clk_74a ( clk_74a ), + // .clk_memory ( clk_sys ), + // // Pocket Bridge Slots + // .dataslot_requestwrite ( dataslot_requestwrite ), // [i] + // .dataslot_requestwrite_id ( dataslot_requestwrite_id ), // [i] + // .dataslot_allcomplete ( dataslot_allcomplete ), // [i] + // // MPU -> FPGA (MPU Write to FPGA) + // // Pocket Bridge + // .bridge_endian_little ( bridge_endian_little ), // [i] + // .bridge_addr ( bridge_addr ), // [i] + // .bridge_wr ( bridge_wr ), // [i] + // .bridge_wr_data ( bridge_wr_data ), // [i] + // // Controller Interface + // .ioctl_download ( filter_download ), // [o] + // .ioctl_index ( filter_index ), // [o] + // .ioctl_wr ( filter_wr ), // [o] + // .ioctl_addr ( filter_addr ), // [o] + // .ioctl_dout ( filter_dout ) // [o] + // ); + +endmodule diff --git a/projects/dbg_snac_ps2_scancodes.stp b/projects/dbg_snac_ps2_scancodes.stp new file mode 100644 index 0000000..6987620 --- /dev/null +++ b/projects/dbg_snac_ps2_scancodes.stp @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 'core_top:ic|ps2_clk_in' == falling edge + + + + + + + 11111111111111 + 11111111111111 + + + + + + + + + + + + + + + + + + + 1101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000110101110110001101011101100011010111011000 + 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 + + + + + + + + + + + + + + + + + + diff --git a/projects/msx_pocket.qip b/projects/msx_pocket.qip index 546904e..a3aa7ef 100644 --- a/projects/msx_pocket.qip +++ b/projects/msx_pocket.qip @@ -1,9 +1,9 @@ -# ============================================================================== -# Quartus Prime Platform Specific Modules File -# Generated by OpenGateware - Gateman CLI v0.1.0 -# ============================================================================== -# A single file that contains paths to platform specific third-party modules. -# Quartus will use this file but won't edit it. -# You need to edit it manually to add/remove files here. -# ============================================================================== - +# ============================================================================== +# Quartus Prime Platform Specific Modules File +# Generated by OpenGateware - Gateman CLI v0.1.0 +# ============================================================================== +# A single file that contains paths to platform specific third-party modules. +# Quartus will use this file but won't edit it. +# You need to edit it manually to add/remove files here. +# ============================================================================== + diff --git a/projects/msx_pocket.qpf b/projects/msx_pocket.qpf index 381f6dc..18ebce7 100644 --- a/projects/msx_pocket.qpf +++ b/projects/msx_pocket.qpf @@ -1,11 +1,11 @@ -# ============================================================================== -# Quartus Prime Project File -# Generated by OpenGateware - Gateman CLI v0.1.0 -# ============================================================================== - -QUARTUS_VERSION = "18.1" -DATE = "02:12:19 July 25, 2023" - -# Revisions - -PROJECT_REVISION = "msx_pocket" +# ============================================================================== +# Quartus Prime Project File +# Generated by OpenGateware - Gateman CLI v0.1.0 +# ============================================================================== + +QUARTUS_VERSION = "18.1" +DATE = "02:12:19 July 25, 2023" + +# Revisions + +PROJECT_REVISION = "msx_pocket" diff --git a/projects/msx_pocket.qsf b/projects/msx_pocket.qsf index 8981f7d..ebc7191 100644 --- a/projects/msx_pocket.qsf +++ b/projects/msx_pocket.qsf @@ -1,140 +1,143 @@ -# ============================================================================== -# Quartus Prime Settings File -# Generated by OpenGateware - Gateman CLI v0.1.0 -# ============================================================================== -# WARNING: DO NOT ADD FILES TO THE PROJECT VIA THE QUARTUS IDE! -# Add them manually to msx_pocket.qip or Quartus will overwrite this file. -# ============================================================================== - -# ============================================================================== -# Project-Wide Assignments -# ============================================================================== -set_global_assignment -name ORIGINAL_QUARTUS_VERSION 17.0.0 -set_global_assignment -name LAST_QUARTUS_VERSION "25.1std.0 Lite Edition" -set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files -set_global_assignment -name TOP_LEVEL_ENTITY apf_top - -# ============================================================================== -# Compiler Assignments -# ============================================================================== -set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL -set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT" -set_global_assignment -name SAVE_DISK_SPACE OFF -set_global_assignment -name SMART_RECOMPILE ON -set_global_assignment -name SEED 1 - -# ============================================================================== -# Analysis & Synthesis Assignments -# ============================================================================== -set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON -set_global_assignment -name ALLOW_POWER_UP_DONT_CARE ON -set_global_assignment -name MUX_RESTRUCTURE OFF -set_global_assignment -name OPTIMIZATION_TECHNIQUE SPEED -set_global_assignment -name PRE_MAPPING_RESYNTHESIS ON -set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON -set_global_assignment -name SAFE_STATE_MACHINE ON -set_global_assignment -name SYNTH_GATED_CLOCK_CONVERSION ON -set_global_assignment -name SYNTH_PROTECT_SDC_CONSTRAINT ON - -# ============================================================================== -# Fitter Assignments -# ============================================================================== -set_global_assignment -name CRC_ERROR_OPEN_DRAIN ON -set_global_assignment -name ECO_OPTIMIZE_TIMING ON -set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 256 -set_global_assignment -name FITTER_EFFORT "AUTO FIT" -set_global_assignment -name PERIPHERY_TO_CORE_PLACEMENT_AND_ROUTING_OPTIMIZATION ON -set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON -set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON -set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON -set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON -set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON -set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION ON - -# ============================================================================== -# Pin & Location Assignments -# ============================================================================== - -# ============================================================================== -# Platform Modules, Constrains and Chain Description File -# ============================================================================== - -# ============================================================================== -# Core RTL Assignments -# ============================================================================== - -# ============================================================================== -# Incremental Compilation Assignments -# ============================================================================== -set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top -set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top -set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top -set_global_assignment -name SYSTEMVERILOG_FILE ../target/pocket/ps2_snac_decoder.sv -set_global_assignment -name SOURCE_TCL_SCRIPT_FILE ../platform/pocket/bsp/pocket/sys_assign.tcl -set_global_assignment -name SOURCE_TCL_SCRIPT_FILE ../platform/pocket/bsp/setup.tcl -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/bsp/pocket/apf_top.sv -set_global_assignment -name SDC_FILE ../platform/pocket/bsp/pocket/sys_constr.sdc -set_global_assignment -name SOURCE_TCL_SCRIPT_FILE ../platform/pocket/pkgIndex.tcl -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/pocket_i2s.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/audio_mixer.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/arcade_filters.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/filter_loader.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/iir_filter.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/filters_rom.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/audio_mix.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/audio_filters.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/iir_filter_tap.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/dc_blocker.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/video/scanlines_generator.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/video/video_mixer.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/video/scanlines.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/video/shadowmask.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/gamepad.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/data_loader.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/usb_mouse.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/pause_crtl.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/joypad.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/mame_keymap_f.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/interact.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/data_unloader.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/mame_keymap.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/analog2dpad.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/key_ctl.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/key_arbiter.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/hid2ps2_key.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/usb_keyboard.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/key_mgr.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/kb_fifo.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/apf2hid.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/hid2ps2_mod.sv -set_global_assignment -name VERILOG_FILE ../platform/pocket/megafunctions/mf_audio_pll.v -library mf_audio_pll -set_global_assignment -name VERILOG_FILE ../platform/pocket/megafunctions/mf_datatable.v -set_global_assignment -name VERILOG_FILE ../platform/pocket/megafunctions/mf_ddio_bidir_12.v -set_global_assignment -name QIP_FILE ../platform/pocket/megafunctions/mf_audio_pll.qip -set_global_assignment -name QIP_FILE ../platform/pocket/megafunctions/mf_ddio_bidir_12.qip -set_global_assignment -name QIP_FILE ../platform/pocket/megafunctions/mf_datatable.qip -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/memory/spram_hs.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/memory/sram.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/memory/dpram_hs.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/peripherals/io_pad_controller.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/peripherals/core_bridge_cmd.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/peripherals/io_bridge_peripheral.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/data_io.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/save_io.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/hiscore.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/nvram.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/autofire.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/hiscore_io.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/helpers/synch_3.sv -set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/helpers/synch_2.sv -set_global_assignment -name QIP_FILE ../target/pocket/core.qip -set_global_assignment -name SOURCE_TCL_SCRIPT_FILE ../platform/pocket/bsp/pocket/pinouts/system.tcl -set_global_assignment -name QIP_FILE msx_pocket.qip -set_global_assignment -name SDC_FILE msx_pocket.sdc -set_global_assignment -name CDF_FILE msx_pocket.cdf -set_global_assignment -name QIP_FILE ../rtl/index.qip -set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0 -set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85 -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)" +# ============================================================================== +# Quartus Prime Settings File +# Generated by OpenGateware - Gateman CLI v0.1.0 +# ============================================================================== +# WARNING: DO NOT ADD FILES TO THE PROJECT VIA THE QUARTUS IDE! +# Add them manually to msx_pocket.qip or Quartus will overwrite this file. +# ============================================================================== + +# ============================================================================== +# Project-Wide Assignments +# ============================================================================== +set_global_assignment -name ORIGINAL_QUARTUS_VERSION 17.0.0 +set_global_assignment -name LAST_QUARTUS_VERSION "25.1std.0 Lite Edition" +set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files +set_global_assignment -name TOP_LEVEL_ENTITY apf_top + +# ============================================================================== +# Compiler Assignments +# ============================================================================== +set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL +set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT" +set_global_assignment -name SAVE_DISK_SPACE OFF +set_global_assignment -name SMART_RECOMPILE ON +set_global_assignment -name SEED 1 + +# ============================================================================== +# Analysis & Synthesis Assignments +# ============================================================================== +set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON +set_global_assignment -name ALLOW_POWER_UP_DONT_CARE ON +set_global_assignment -name MUX_RESTRUCTURE OFF +set_global_assignment -name OPTIMIZATION_TECHNIQUE SPEED +set_global_assignment -name PRE_MAPPING_RESYNTHESIS ON +set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS ON +set_global_assignment -name SAFE_STATE_MACHINE ON +set_global_assignment -name SYNTH_GATED_CLOCK_CONVERSION ON +set_global_assignment -name SYNTH_PROTECT_SDC_CONSTRAINT ON + +# ============================================================================== +# Fitter Assignments +# ============================================================================== +set_global_assignment -name CRC_ERROR_OPEN_DRAIN ON +set_global_assignment -name ECO_OPTIMIZE_TIMING ON +set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 256 +set_global_assignment -name FITTER_EFFORT "AUTO FIT" +set_global_assignment -name PERIPHERY_TO_CORE_PLACEMENT_AND_ROUTING_OPTIMIZATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON +set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON +set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON +set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON +set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION ON + +# ============================================================================== +# Pin & Location Assignments +# ============================================================================== + +# ============================================================================== +# Platform Modules, Constrains and Chain Description File +# ============================================================================== + +# ============================================================================== +# Core RTL Assignments +# ============================================================================== + +# ============================================================================== +# Incremental Compilation Assignments +# ============================================================================== +set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top +set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top +set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top +set_global_assignment -name ENABLE_SIGNALTAP OFF +set_global_assignment -name USE_SIGNALTAP_FILE dbg_snac_ps2_scancodes.stp +set_global_assignment -name SYSTEMVERILOG_FILE ../target/pocket/analogizer/yc_out_legacy.sv +set_global_assignment -name QIP_FILE ../target/pocket/analogizer/analogizer.qip +set_global_assignment -name SYSTEMVERILOG_FILE ../target/pocket/ps2_to_key.sv +set_global_assignment -name VHDL_FILE ../target/pocket/ps2_keyboard.vhd +set_global_assignment -name VHDL_FILE ../target/pocket/debounce.vhd +set_global_assignment -name SOURCE_TCL_SCRIPT_FILE ../platform/pocket/bsp/pocket/sys_assign.tcl +set_global_assignment -name SOURCE_TCL_SCRIPT_FILE ../platform/pocket/bsp/setup.tcl +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/bsp/pocket/apf_top.sv +set_global_assignment -name SDC_FILE ../platform/pocket/bsp/pocket/sys_constr.sdc +set_global_assignment -name SOURCE_TCL_SCRIPT_FILE ../platform/pocket/pkgIndex.tcl +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/pocket_i2s.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/audio_mixer.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/arcade_filters.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/filter_loader.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/iir_filter.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/filters_rom.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/audio_mix.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/audio_filters.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/iir_filter_tap.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/audio/filters/dc_blocker.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/video/scanlines_generator.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/video/video_mixer.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/video/scanlines.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/video/shadowmask.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/gamepad.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/data_loader.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/usb_mouse.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/pause_crtl.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/joypad.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/mame_keymap_f.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/interact.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/data_unloader.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/mame_keymap.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/analog2dpad.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/key_ctl.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/key_arbiter.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/hid2ps2_key.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/usb_keyboard.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/key_mgr.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/kb_fifo.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/apf2hid.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/interface/keyboard/hid2ps2_mod.sv +set_global_assignment -name VERILOG_FILE ../platform/pocket/megafunctions/mf_audio_pll.v -library mf_audio_pll +set_global_assignment -name VERILOG_FILE ../platform/pocket/megafunctions/mf_datatable.v +set_global_assignment -name VERILOG_FILE ../platform/pocket/megafunctions/mf_ddio_bidir_12.v +set_global_assignment -name QIP_FILE ../platform/pocket/megafunctions/mf_audio_pll.qip +set_global_assignment -name QIP_FILE ../platform/pocket/megafunctions/mf_ddio_bidir_12.qip +set_global_assignment -name QIP_FILE ../platform/pocket/megafunctions/mf_datatable.qip +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/memory/spram_hs.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/memory/sram.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/memory/dpram_hs.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/peripherals/io_pad_controller.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/peripherals/core_bridge_cmd.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/peripherals/io_bridge_peripheral.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/data_io.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/save_io.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/hiscore.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/nvram.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/autofire.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/support/hiscore_io.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/helpers/synch_3.sv +set_global_assignment -name SYSTEMVERILOG_FILE ../platform/pocket/helpers/synch_2.sv +set_global_assignment -name QIP_FILE ../target/pocket/core.qip +set_global_assignment -name SOURCE_TCL_SCRIPT_FILE ../platform/pocket/bsp/pocket/pinouts/system.tcl +set_global_assignment -name QIP_FILE msx_pocket.qip +set_global_assignment -name SDC_FILE msx_pocket.sdc +set_global_assignment -name CDF_FILE msx_pocket.cdf +set_global_assignment -name QIP_FILE ../rtl/index.qip +set_global_assignment -name SIGNALTAP_FILE dbg_snac_ps2_scancodes.stp set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top \ No newline at end of file diff --git a/projects/msx_pocket.sdc b/projects/msx_pocket.sdc index 4b5d796..34f539c 100644 --- a/projects/msx_pocket.sdc +++ b/projects/msx_pocket.sdc @@ -1,61 +1,61 @@ -# ============================================================================== -# Quartus Prime Synopsys Design Constraint File -# Generated by OpenGateware - Gateman CLI v0.1.0 -# ============================================================================== -# pocket SDC settings -# Users are recommended to modify this file to match users logic. -# Put your clock groups in here as well as any net assignments. -# ============================================================================== - -# ============================================================================== -# Time Information -# ============================================================================== - -# ============================================================================== -# Create Clock -# ============================================================================== - -# ============================================================================== -# Create Generated Clock -# ============================================================================== - -# ============================================================================== -# Set Clock Latency -# ============================================================================== - -# ============================================================================== -# Set Clock Uncertainty -# ============================================================================== - -# ============================================================================== -# Set Input Delay -# ============================================================================== - -# ============================================================================== -# Set Output Delay -# ============================================================================== - -# ============================================================================== -# Set Clock Groups -# ============================================================================== - -# ============================================================================== -# Set False Path -# ============================================================================== - -# ============================================================================== -# Set Multicycle Path -# ============================================================================== - -# ============================================================================== -# Set Maximum Delay -# ============================================================================== - -# ============================================================================== -# Set Minimum Delay -# ============================================================================== - -# ============================================================================== -# Set Input Transition -# ============================================================================== - +# ============================================================================== +# Quartus Prime Synopsys Design Constraint File +# Generated by OpenGateware - Gateman CLI v0.1.0 +# ============================================================================== +# pocket SDC settings +# Users are recommended to modify this file to match users logic. +# Put your clock groups in here as well as any net assignments. +# ============================================================================== + +# ============================================================================== +# Time Information +# ============================================================================== + +# ============================================================================== +# Create Clock +# ============================================================================== + +# ============================================================================== +# Create Generated Clock +# ============================================================================== + +# ============================================================================== +# Set Clock Latency +# ============================================================================== + +# ============================================================================== +# Set Clock Uncertainty +# ============================================================================== + +# ============================================================================== +# Set Input Delay +# ============================================================================== + +# ============================================================================== +# Set Output Delay +# ============================================================================== + +# ============================================================================== +# Set Clock Groups +# ============================================================================== + +# ============================================================================== +# Set False Path +# ============================================================================== + +# ============================================================================== +# Set Multicycle Path +# ============================================================================== + +# ============================================================================== +# Set Maximum Delay +# ============================================================================== + +# ============================================================================== +# Set Minimum Delay +# ============================================================================== + +# ============================================================================== +# Set Input Transition +# ============================================================================== + diff --git a/rtl/bram.vhd b/rtl/bram.vhd index 4f191aa..a19846d 100644 --- a/rtl/bram.vhd +++ b/rtl/bram.vhd @@ -1,192 +1,192 @@ --------------------------------------------------------------- --- Single port Block RAM --------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; - -library altera_mf; -use altera_mf.altera_mf_components.all; - -entity spram is - generic ( - addr_width : integer := 8; - data_width : integer := 8; - mem_init_file : string := " "; - mem_name : string := "MEM" -- for InSystem Memory content editor. - ); - port ( - clock : in std_logic; - address : in std_logic_vector (addr_width - 1 downto 0); - data : in std_logic_vector (data_width - 1 downto 0) := (others => '0'); - enable : in std_logic := '1'; - wren : in std_logic := '0'; - q : out std_logic_vector (data_width - 1 downto 0); - cs : in std_logic := '1' - ); -end spram; -architecture SYN of spram is - signal q0 : std_logic_vector((data_width - 1) downto 0); - -begin - q <= q0 when cs = '1' else - (others => '1'); - - altsyncram_component : altsyncram - generic map( - clock_enable_input_a => "BYPASS", - clock_enable_output_a => "BYPASS", - intended_device_family => "Cyclone V", - lpm_hint => "ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME=" & mem_name, - lpm_type => "altsyncram", - numwords_a => 2 ** addr_width, - operation_mode => "SINGLE_PORT", - outdata_aclr_a => "NONE", - outdata_reg_a => "UNREGISTERED", - power_up_uninitialized => "FALSE", - read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ", - init_file => mem_init_file, - widthad_a => addr_width, - width_a => data_width, - width_byteena_a => 1 - ) - port map( - address_a => address, - clock0 => clock, - data_a => data, - wren_a => wren and cs, - q_a => q0 - ); - -end SYN; - --------------------------------------------------------------- --- Dual port Block RAM same parameters on both ports --------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; - -library altera_mf; -use altera_mf.altera_mf_components.all; - -entity dpram is - generic ( - addr_width : integer := 8; - data_width : integer := 8; - mem_init_file : string := " " - ); - port ( - clock : in std_logic; - - address_a : in std_logic_vector (addr_width - 1 downto 0); - data_a : in std_logic_vector (data_width - 1 downto 0) := (others => '0'); - enable_a : in std_logic := '1'; - wren_a : in std_logic := '0'; - q_a : out std_logic_vector (data_width - 1 downto 0); - cs_a : in std_logic := '1'; - - address_b : in std_logic_vector (addr_width - 1 downto 0) := (others => '0'); - data_b : in std_logic_vector (data_width - 1 downto 0) := (others => '0'); - enable_b : in std_logic := '1'; - wren_b : in std_logic := '0'; - q_b : out std_logic_vector (data_width - 1 downto 0); - cs_b : in std_logic := '1' - ); -end entity; -architecture SYN of dpram is -begin - ram : work.dpram_dif generic map(addr_width, data_width, addr_width, data_width, mem_init_file) - port map(clock, address_a, data_a, enable_a, wren_a, q_a, cs_a, address_b, data_b, enable_b, wren_b, q_b, cs_b); -end SYN; - --------------------------------------------------------------- --- Dual port Block RAM different parameters on ports --------------------------------------------------------------- -library ieee; -use ieee.std_logic_1164.all; - -library altera_mf; -use altera_mf.altera_mf_components.all; - -entity dpram_dif is - generic ( - addr_width_a : integer := 8; - data_width_a : integer := 8; - addr_width_b : integer := 8; - data_width_b : integer := 8; - mem_init_file : string := " " - ); - port ( - clock : in std_logic; - - address_a : in std_logic_vector (addr_width_a - 1 downto 0); - data_a : in std_logic_vector (data_width_a - 1 downto 0) := (others => '0'); - enable_a : in std_logic := '1'; - wren_a : in std_logic := '0'; - q_a : out std_logic_vector (data_width_a - 1 downto 0); - cs_a : in std_logic := '1'; - - address_b : in std_logic_vector (addr_width_b - 1 downto 0) := (others => '0'); - data_b : in std_logic_vector (data_width_b - 1 downto 0) := (others => '0'); - enable_b : in std_logic := '1'; - wren_b : in std_logic := '0'; - q_b : out std_logic_vector (data_width_b - 1 downto 0); - cs_b : in std_logic := '1' - ); -end entity; -architecture SYN of dpram_dif is - - signal q0 : std_logic_vector((data_width_a - 1) downto 0); - signal q1 : std_logic_vector((data_width_b - 1) downto 0); - -begin - q_a <= q0 when cs_a = '1' else - (others => '1'); - q_b <= q1 when cs_b = '1' else - (others => '1'); - - altsyncram_component : altsyncram - generic map( - address_reg_b => "CLOCK1", - clock_enable_input_a => "NORMAL", - clock_enable_input_b => "NORMAL", - clock_enable_output_a => "BYPASS", - clock_enable_output_b => "BYPASS", - indata_reg_b => "CLOCK1", - intended_device_family => "Cyclone V", - lpm_type => "altsyncram", - numwords_a => 2 ** addr_width_a, - numwords_b => 2 ** addr_width_b, - operation_mode => "BIDIR_DUAL_PORT", - outdata_aclr_a => "NONE", - outdata_aclr_b => "NONE", - outdata_reg_a => "UNREGISTERED", - outdata_reg_b => "UNREGISTERED", - power_up_uninitialized => "FALSE", - read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ", - read_during_write_mode_port_b => "NEW_DATA_NO_NBE_READ", - init_file => mem_init_file, - widthad_a => addr_width_a, - widthad_b => addr_width_b, - width_a => data_width_a, - width_b => data_width_b, - width_byteena_a => 1, - width_byteena_b => 1, - wrcontrol_wraddress_reg_b => "CLOCK1" - ) - port map( - address_a => address_a, - address_b => address_b, - clock0 => clock, - clock1 => clock, - clocken0 => enable_a, - clocken1 => enable_b, - data_a => data_a, - data_b => data_b, - wren_a => wren_a and cs_a, - wren_b => wren_b and cs_b, - q_a => q0, - q_b => q1 - ); - +-------------------------------------------------------------- +-- Single port Block RAM +-------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; + +library altera_mf; +use altera_mf.altera_mf_components.all; + +entity spram is + generic ( + addr_width : integer := 8; + data_width : integer := 8; + mem_init_file : string := " "; + mem_name : string := "MEM" -- for InSystem Memory content editor. + ); + port ( + clock : in std_logic; + address : in std_logic_vector (addr_width - 1 downto 0); + data : in std_logic_vector (data_width - 1 downto 0) := (others => '0'); + enable : in std_logic := '1'; + wren : in std_logic := '0'; + q : out std_logic_vector (data_width - 1 downto 0); + cs : in std_logic := '1' + ); +end spram; +architecture SYN of spram is + signal q0 : std_logic_vector((data_width - 1) downto 0); + +begin + q <= q0 when cs = '1' else + (others => '1'); + + altsyncram_component : altsyncram + generic map( + clock_enable_input_a => "BYPASS", + clock_enable_output_a => "BYPASS", + intended_device_family => "Cyclone V", + lpm_hint => "ENABLE_RUNTIME_MOD=YES,INSTANCE_NAME=" & mem_name, + lpm_type => "altsyncram", + numwords_a => 2 ** addr_width, + operation_mode => "SINGLE_PORT", + outdata_aclr_a => "NONE", + outdata_reg_a => "UNREGISTERED", + power_up_uninitialized => "FALSE", + read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ", + init_file => mem_init_file, + widthad_a => addr_width, + width_a => data_width, + width_byteena_a => 1 + ) + port map( + address_a => address, + clock0 => clock, + data_a => data, + wren_a => wren and cs, + q_a => q0 + ); + +end SYN; + +-------------------------------------------------------------- +-- Dual port Block RAM same parameters on both ports +-------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; + +library altera_mf; +use altera_mf.altera_mf_components.all; + +entity dpram is + generic ( + addr_width : integer := 8; + data_width : integer := 8; + mem_init_file : string := " " + ); + port ( + clock : in std_logic; + + address_a : in std_logic_vector (addr_width - 1 downto 0); + data_a : in std_logic_vector (data_width - 1 downto 0) := (others => '0'); + enable_a : in std_logic := '1'; + wren_a : in std_logic := '0'; + q_a : out std_logic_vector (data_width - 1 downto 0); + cs_a : in std_logic := '1'; + + address_b : in std_logic_vector (addr_width - 1 downto 0) := (others => '0'); + data_b : in std_logic_vector (data_width - 1 downto 0) := (others => '0'); + enable_b : in std_logic := '1'; + wren_b : in std_logic := '0'; + q_b : out std_logic_vector (data_width - 1 downto 0); + cs_b : in std_logic := '1' + ); +end entity; +architecture SYN of dpram is +begin + ram : work.dpram_dif generic map(addr_width, data_width, addr_width, data_width, mem_init_file) + port map(clock, address_a, data_a, enable_a, wren_a, q_a, cs_a, address_b, data_b, enable_b, wren_b, q_b, cs_b); +end SYN; + +-------------------------------------------------------------- +-- Dual port Block RAM different parameters on ports +-------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; + +library altera_mf; +use altera_mf.altera_mf_components.all; + +entity dpram_dif is + generic ( + addr_width_a : integer := 8; + data_width_a : integer := 8; + addr_width_b : integer := 8; + data_width_b : integer := 8; + mem_init_file : string := " " + ); + port ( + clock : in std_logic; + + address_a : in std_logic_vector (addr_width_a - 1 downto 0); + data_a : in std_logic_vector (data_width_a - 1 downto 0) := (others => '0'); + enable_a : in std_logic := '1'; + wren_a : in std_logic := '0'; + q_a : out std_logic_vector (data_width_a - 1 downto 0); + cs_a : in std_logic := '1'; + + address_b : in std_logic_vector (addr_width_b - 1 downto 0) := (others => '0'); + data_b : in std_logic_vector (data_width_b - 1 downto 0) := (others => '0'); + enable_b : in std_logic := '1'; + wren_b : in std_logic := '0'; + q_b : out std_logic_vector (data_width_b - 1 downto 0); + cs_b : in std_logic := '1' + ); +end entity; +architecture SYN of dpram_dif is + + signal q0 : std_logic_vector((data_width_a - 1) downto 0); + signal q1 : std_logic_vector((data_width_b - 1) downto 0); + +begin + q_a <= q0 when cs_a = '1' else + (others => '1'); + q_b <= q1 when cs_b = '1' else + (others => '1'); + + altsyncram_component : altsyncram + generic map( + address_reg_b => "CLOCK1", + clock_enable_input_a => "NORMAL", + clock_enable_input_b => "NORMAL", + clock_enable_output_a => "BYPASS", + clock_enable_output_b => "BYPASS", + indata_reg_b => "CLOCK1", + intended_device_family => "Cyclone V", + lpm_type => "altsyncram", + numwords_a => 2 ** addr_width_a, + numwords_b => 2 ** addr_width_b, + operation_mode => "BIDIR_DUAL_PORT", + outdata_aclr_a => "NONE", + outdata_aclr_b => "NONE", + outdata_reg_a => "UNREGISTERED", + outdata_reg_b => "UNREGISTERED", + power_up_uninitialized => "FALSE", + read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ", + read_during_write_mode_port_b => "NEW_DATA_NO_NBE_READ", + init_file => mem_init_file, + widthad_a => addr_width_a, + widthad_b => addr_width_b, + width_a => data_width_a, + width_b => data_width_b, + width_byteena_a => 1, + width_byteena_b => 1, + wrcontrol_wraddress_reg_b => "CLOCK1" + ) + port map( + address_a => address_a, + address_b => address_b, + clock0 => clock, + clock1 => clock, + clocken0 => enable_a, + clocken1 => enable_b, + data_a => data_a, + data_b => data_b, + wren_a => wren_a and cs_a, + wren_b => wren_b and cs_b, + q_a => q0, + q_b => q1 + ); + end SYN; \ No newline at end of file diff --git a/rtl/cart/ascii16.v b/rtl/cart/ascii16.v index ff19950..c505def 100644 --- a/rtl/cart/ascii16.v +++ b/rtl/cart/ascii16.v @@ -1,75 +1,75 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX Compatible Gateware IP Core -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -module cart_asci16 - ( - input clk, - input reset, - input [24:0] rom_size, - input [15:0] addr, - input [7:0] d_from_cpu, - input wr, - input cs, - input r_type, - output [24:0] mem_addr, - output [12:0] sram_addr, - output sram_we, - output sram_oe - ); - - reg [7:0] bank0, bank1; - wire [7:0] mask = rom_size[20:13] - 1'd1; - wire [7:0] sram_mask = rom_size[20:13] > 8'h10 ? rom_size[20:13] : 8'h10; - - always @(posedge reset, posedge clk) begin - if (reset) begin - bank0 <= r_type ? 8'h0f : 8'h00; - bank1 <= 8'h00; - end - else begin - if (cs && wr) begin - if (r_type) begin - if (addr[15:12] == 4'b0111) begin - bank1 <= d_from_cpu[4] ? {5'b00010,d_from_cpu[2:0]} : {3'b000,d_from_cpu[4:0]}; - end - end - else begin - case (addr[15:11]) - 5'b01100: bank0 <= d_from_cpu; // 6000-67ffh - 5'b01110: bank1 <= d_from_cpu; // 7000-77ffh - endcase - end - end - end - end - - wire [7:0] bank_base = addr[15] == 0 ? bank0 : bank1; - - assign mem_addr = {2'h0, (bank_base & mask), addr[13:0]}; - - assign sram_addr = addr[12:0]; - assign sram_we = cs && (bank1 & sram_mask) && addr[15:14] == 2'b10 && wr; - assign sram_oe = cs && (bank_base & sram_mask); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX Compatible Gateware IP Core +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +module cart_asci16 + ( + input clk, + input reset, + input [24:0] rom_size, + input [15:0] addr, + input [7:0] d_from_cpu, + input wr, + input cs, + input r_type, + output [24:0] mem_addr, + output [12:0] sram_addr, + output sram_we, + output sram_oe + ); + + reg [7:0] bank0, bank1; + wire [7:0] mask = rom_size[20:13] - 1'd1; + wire [7:0] sram_mask = rom_size[20:13] > 8'h10 ? rom_size[20:13] : 8'h10; + + always @(posedge reset, posedge clk) begin + if (reset) begin + bank0 <= r_type ? 8'h0f : 8'h00; + bank1 <= 8'h00; + end + else begin + if (cs && wr) begin + if (r_type) begin + if (addr[15:12] == 4'b0111) begin + bank1 <= d_from_cpu[4] ? {5'b00010,d_from_cpu[2:0]} : {3'b000,d_from_cpu[4:0]}; + end + end + else begin + case (addr[15:11]) + 5'b01100: bank0 <= d_from_cpu; // 6000-67ffh + 5'b01110: bank1 <= d_from_cpu; // 7000-77ffh + endcase + end + end + end + end + + wire [7:0] bank_base = addr[15] == 0 ? bank0 : bank1; + + assign mem_addr = {2'h0, (bank_base & mask), addr[13:0]}; + + assign sram_addr = addr[12:0]; + assign sram_we = cs && (bank1 & sram_mask) && addr[15:14] == 2'b10 && wr; + assign sram_oe = cs && (bank_base & sram_mask); + +endmodule diff --git a/rtl/cart/ascii8.v b/rtl/cart/ascii8.v index b7ea6f0..aa5f8a5 100644 --- a/rtl/cart/ascii8.v +++ b/rtl/cart/ascii8.v @@ -1,73 +1,73 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX Compatible Gateware IP Core -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -module cart_asci8 - ( - input clk, - input reset, - input [24:0] rom_size, - input [15:0] addr, - input [7:0] d_from_cpu, - input wr, - input cs, - output [24:0] mem_addr, - output [12:0] sram_addr, - output sram_we, - output sram_oe - ); - - reg [7:0] bank0, bank1, bank2, bank3; - wire [7:0] mask = rom_size[20:13] - 1'd1; - wire [7:0] sram_mask = rom_size[20:13]; - - always @(posedge reset, posedge clk) begin - if (reset) begin - bank0 <= 8'h00; - bank1 <= 8'h00; - bank2 <= 8'h00; - bank3 <= 8'h00; - end - else begin - if (cs && wr) begin - case (addr[15:11]) - 5'b01100: bank0 <= d_from_cpu; // 6000-67ffh - 5'b01101: bank1 <= d_from_cpu; // 6800-6fffh - 5'b01110: bank2 <= d_from_cpu; // 7000-77ffh - 5'b01111: bank3 <= d_from_cpu; // 7800-7fffh - endcase - end - end - end - - wire [7:0] bank_base = addr[15:13] == 3'b010 ? bank0 : - addr[15:13] == 3'b011 ? bank1 : - addr[15:13] == 3'b100 ? bank2 : bank3; - - assign mem_addr = {3'h0, (bank_base & mask), addr[12:0]}; - - assign sram_addr = addr[12:0]; - assign sram_we = cs && ((bank2 & sram_mask && addr[15:13] == 3'b100) || (bank3 & sram_mask && addr[15:13] == 3'b101)) && wr; - assign sram_oe = cs && (bank_base & sram_mask); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX Compatible Gateware IP Core +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +module cart_asci8 + ( + input clk, + input reset, + input [24:0] rom_size, + input [15:0] addr, + input [7:0] d_from_cpu, + input wr, + input cs, + output [24:0] mem_addr, + output [12:0] sram_addr, + output sram_we, + output sram_oe + ); + + reg [7:0] bank0, bank1, bank2, bank3; + wire [7:0] mask = rom_size[20:13] - 1'd1; + wire [7:0] sram_mask = rom_size[20:13]; + + always @(posedge reset, posedge clk) begin + if (reset) begin + bank0 <= 8'h00; + bank1 <= 8'h00; + bank2 <= 8'h00; + bank3 <= 8'h00; + end + else begin + if (cs && wr) begin + case (addr[15:11]) + 5'b01100: bank0 <= d_from_cpu; // 6000-67ffh + 5'b01101: bank1 <= d_from_cpu; // 6800-6fffh + 5'b01110: bank2 <= d_from_cpu; // 7000-77ffh + 5'b01111: bank3 <= d_from_cpu; // 7800-7fffh + endcase + end + end + end + + wire [7:0] bank_base = addr[15:13] == 3'b010 ? bank0 : + addr[15:13] == 3'b011 ? bank1 : + addr[15:13] == 3'b100 ? bank2 : bank3; + + assign mem_addr = {3'h0, (bank_base & mask), addr[12:0]}; + + assign sram_addr = addr[12:0]; + assign sram_we = cs && ((bank2 & sram_mask && addr[15:13] == 3'b100) || (bank3 & sram_mask && addr[15:13] == 3'b101)) && wr; + assign sram_oe = cs && (bank_base & sram_mask); + +endmodule diff --git a/rtl/cart/gamemaster2.v b/rtl/cart/gamemaster2.v index b967d89..945a53a 100644 --- a/rtl/cart/gamemaster2.v +++ b/rtl/cart/gamemaster2.v @@ -1,67 +1,67 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX Compatible Gateware IP Core -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -module cart_gamemaster2 - ( - input clk, - input reset, - input [15:0] addr, - input [7:0] d_from_cpu, - input wr, - input cs, - output [24:0] mem_addr, - output [12:0] sram_addr, - output sram_we, - output sram_oe - ); - - reg [7:0] bank1, bank2, bank3; - - always @(posedge reset, posedge clk) begin - if (reset) begin - bank1 <= 8'h01; - bank2 <= 8'h02; - bank3 <= 8'h03; - end - else begin - if (cs && wr) begin - case (addr[15:12]) - 4'b0110: bank1 <= d_from_cpu; // 6000-6fffh - 4'b1000: bank2 <= d_from_cpu; // 8000-8fffh - 4'b1010: bank3 <= d_from_cpu; // a000-afffh - endcase - end - end - end - - wire [7:0] bank_base = addr[15:13] == 3'b010 ? 8'h00 : - addr[15:13] == 3'b011 ? bank1 : - addr[15:13] == 3'b100 ? bank2 : bank3; - - assign mem_addr = {3'h0, (bank_base[3:0]), addr[12:0]}; - assign sram_addr = {bank_base[5], addr[11:0]}; - assign sram_oe = cs && bank_base[4]; - assign sram_we = cs && bank_base[4] && addr[15:12] == 4'b1011 && wr; - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX Compatible Gateware IP Core +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +module cart_gamemaster2 + ( + input clk, + input reset, + input [15:0] addr, + input [7:0] d_from_cpu, + input wr, + input cs, + output [24:0] mem_addr, + output [12:0] sram_addr, + output sram_we, + output sram_oe + ); + + reg [7:0] bank1, bank2, bank3; + + always @(posedge reset, posedge clk) begin + if (reset) begin + bank1 <= 8'h01; + bank2 <= 8'h02; + bank3 <= 8'h03; + end + else begin + if (cs && wr) begin + case (addr[15:12]) + 4'b0110: bank1 <= d_from_cpu; // 6000-6fffh + 4'b1000: bank2 <= d_from_cpu; // 8000-8fffh + 4'b1010: bank3 <= d_from_cpu; // a000-afffh + endcase + end + end + end + + wire [7:0] bank_base = addr[15:13] == 3'b010 ? 8'h00 : + addr[15:13] == 3'b011 ? bank1 : + addr[15:13] == 3'b100 ? bank2 : bank3; + + assign mem_addr = {3'h0, (bank_base[3:0]), addr[12:0]}; + assign sram_addr = {bank_base[5], addr[11:0]}; + assign sram_oe = cs && bank_base[4]; + assign sram_we = cs && bank_base[4] && addr[15:12] == 4'b1011 && wr; + +endmodule diff --git a/rtl/cart/konami.v b/rtl/cart/konami.v index f4c2d9f..fb9a63b 100644 --- a/rtl/cart/konami.v +++ b/rtl/cart/konami.v @@ -1,63 +1,63 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX Compatible Gateware IP Core -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -module cart_konami - ( - input clk, - input reset, - input [24:0] rom_size, - input [15:0] addr, - input [7:0] d_from_cpu, - input wr, - input cs, - output [24:0] mem_addr - ); - - reg [7:0] bank1, bank2, bank3; - wire [7:0] mask = rom_size[20:13] - 1'd1; - - always @(posedge reset, posedge clk) begin - if (reset) begin - bank1 <= 8'h01; - bank2 <= 8'h02; - bank3 <= 8'h03; - end - else begin - if (cs && wr) begin - case (addr[15:13]) - 3'b011: bank1 <= d_from_cpu; // 6000-7fffh - 3'b100: bank2 <= d_from_cpu; // 8000-9fffh - 3'b101: bank3 <= d_from_cpu; // a000-bfffh - endcase - end - end - end - - wire [7:0] bank_base = addr[15:13] == 3'b010 ? 8'h00 : - addr[15:13] == 3'b011 ? bank1 : - addr[15:13] == 3'b100 ? bank2 : bank3; - - assign mem_addr = {3'h0, (bank_base & mask), addr[12:0]}; - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX Compatible Gateware IP Core +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +module cart_konami + ( + input clk, + input reset, + input [24:0] rom_size, + input [15:0] addr, + input [7:0] d_from_cpu, + input wr, + input cs, + output [24:0] mem_addr + ); + + reg [7:0] bank1, bank2, bank3; + wire [7:0] mask = rom_size[20:13] - 1'd1; + + always @(posedge reset, posedge clk) begin + if (reset) begin + bank1 <= 8'h01; + bank2 <= 8'h02; + bank3 <= 8'h03; + end + else begin + if (cs && wr) begin + case (addr[15:13]) + 3'b011: bank1 <= d_from_cpu; // 6000-7fffh + 3'b100: bank2 <= d_from_cpu; // 8000-9fffh + 3'b101: bank3 <= d_from_cpu; // a000-bfffh + endcase + end + end + end + + wire [7:0] bank_base = addr[15:13] == 3'b010 ? 8'h00 : + addr[15:13] == 3'b011 ? bank1 : + addr[15:13] == 3'b100 ? bank2 : bank3; + + assign mem_addr = {3'h0, (bank_base & mask), addr[12:0]}; + +endmodule diff --git a/rtl/cart/konami_scc.v b/rtl/cart/konami_scc.v index 11dc660..935c48c 100644 --- a/rtl/cart/konami_scc.v +++ b/rtl/cart/konami_scc.v @@ -1,113 +1,113 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX Compatible Gateware IP Core -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -module cart_konami_scc - ( - input clk, - input clk_en, - input reset, - input [24:0] rom_size, - input [15:0] addr, - input [7:0] d_from_cpu, - output [7:0] d_to_cpu, - output ack, - input wr, - input rd, - input cs, - output [24:0] mem_addr, - output [14:0] scc_sound - ); - - reg [7:0] bank0, bank1, bank2, bank3; - wire [7:0] mask = rom_size[20:13] - 1'd1; - - always @(posedge reset, posedge clk) begin - if (reset) begin - bank0 <= 8'h00; - bank1 <= 8'h01; - bank2 <= 8'h02; - bank3 <= 8'h03; - end - else begin - if (cs && wr) begin - case (addr[15:11]) - 5'b01010: bank0 <= d_from_cpu; // 5000-57ffh - 5'b01110: bank1 <= d_from_cpu; // 7000-77ffh - 5'b10010: bank2 <= d_from_cpu; // 9000-97ffh - 5'b10110: bank3 <= d_from_cpu; // b000-b7ffh - endcase - end - end - end - - wire [7:0] bank_base = addr[15:13] == 3'b010 ? bank0 : - addr[15:13] == 3'b011 ? bank1 : - addr[15:13] == 3'b100 ? bank2 : bank3; - - assign mem_addr = {3'h0, (bank_base & mask), addr[12:0]}; - - wire scc_req = cs && addr[15:11] == 5'b10011 && bank2[5:0] == 6'b111111 && (rd || wr); - wire [7:0] d_to_cpu_scc; - wire [7:0] scc_addr = toCopy ? {3'b100,addr[4:0]} : - (~addr[13] && addr[7]) ? addr[7:0] ^ 8'h20 : - addr[7:0]; - - //Copy channel 5 - reg toCopy; - reg cp; - - always @(posedge clk) begin - if (reset) begin - toCopy <= 0; - cp <= 0; - end - else begin - if (scc_req && ack) begin - if (wr && addr[7:5] == 3'b011 && ~cp) begin - cp <= 1; - end - else begin - cp <= 0; - end - end - if (cp) begin toCopy <= 1; end - if (~wr) begin toCopy <= 0; end - end - end - - scc_wave k051649 - ( - .clk21m ( clk ), - .reset ( reset ), - .clkena ( clk_en ), - .req ( scc_req & (~(ack & cp) | toCopy) ), - .ack ( ack ), - .wrt ( wr ), - .adr ( scc_addr ), - .dbi ( d_to_cpu ), - .dbo ( d_from_cpu ), - .wave ( scc_sound ) - ); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX Compatible Gateware IP Core +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +module cart_konami_scc + ( + input clk, + input clk_en, + input reset, + input [24:0] rom_size, + input [15:0] addr, + input [7:0] d_from_cpu, + output [7:0] d_to_cpu, + output ack, + input wr, + input rd, + input cs, + output [24:0] mem_addr, + output [14:0] scc_sound + ); + + reg [7:0] bank0, bank1, bank2, bank3; + wire [7:0] mask = rom_size[20:13] - 1'd1; + + always @(posedge reset, posedge clk) begin + if (reset) begin + bank0 <= 8'h00; + bank1 <= 8'h01; + bank2 <= 8'h02; + bank3 <= 8'h03; + end + else begin + if (cs && wr) begin + case (addr[15:11]) + 5'b01010: bank0 <= d_from_cpu; // 5000-57ffh + 5'b01110: bank1 <= d_from_cpu; // 7000-77ffh + 5'b10010: bank2 <= d_from_cpu; // 9000-97ffh + 5'b10110: bank3 <= d_from_cpu; // b000-b7ffh + endcase + end + end + end + + wire [7:0] bank_base = addr[15:13] == 3'b010 ? bank0 : + addr[15:13] == 3'b011 ? bank1 : + addr[15:13] == 3'b100 ? bank2 : bank3; + + assign mem_addr = {3'h0, (bank_base & mask), addr[12:0]}; + + wire scc_req = cs && addr[15:11] == 5'b10011 && bank2[5:0] == 6'b111111 && (rd || wr); + wire [7:0] d_to_cpu_scc; + wire [7:0] scc_addr = toCopy ? {3'b100,addr[4:0]} : + (~addr[13] && addr[7]) ? addr[7:0] ^ 8'h20 : + addr[7:0]; + + //Copy channel 5 + reg toCopy; + reg cp; + + always @(posedge clk) begin + if (reset) begin + toCopy <= 0; + cp <= 0; + end + else begin + if (scc_req && ack) begin + if (wr && addr[7:5] == 3'b011 && ~cp) begin + cp <= 1; + end + else begin + cp <= 0; + end + end + if (cp) begin toCopy <= 1; end + if (~wr) begin toCopy <= 0; end + end + end + + scc_wave k051649 + ( + .clk21m ( clk ), + .reset ( reset ), + .clkena ( clk_en ), + .req ( scc_req & (~(ack & cp) | toCopy) ), + .ack ( ack ), + .wrt ( wr ), + .adr ( scc_addr ), + .dbi ( d_to_cpu ), + .dbo ( d_from_cpu ), + .wave ( scc_sound ) + ); + +endmodule diff --git a/rtl/cart/ram.vhd b/rtl/cart/ram.vhd index e4bb889..ccbff58 100644 --- a/rtl/cart/ram.vhd +++ b/rtl/cart/ram.vhd @@ -1,64 +1,64 @@ --- --- ram.vhd --- 256 bytes of block memory --- Revision 1.00 --- --- Copyright (c) 2006 Kazuhiro Tsujikawa (ESE Artists' factory) --- All rights reserved. --- --- Redistribution and use of this source code or any derivative works, are --- permitted provided that the following conditions are met: --- --- 1. Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- 2. Redistributions in binary form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- 3. Redistributions may not be sold, nor may they be used in a commercial --- product or activity without specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR --- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, --- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, --- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; --- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, --- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR --- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF --- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.std_logic_unsigned.all; - -entity ram is - port ( - adr : in std_logic_vector(7 downto 0); - clk : in std_logic; - we : in std_logic; - dbo : in std_logic_vector(7 downto 0); - dbi : out std_logic_vector(7 downto 0) - ); -end ram; - -architecture RTL of ram is - type typram is array (255 downto 0) of std_logic_vector(7 downto 0); - signal blkram : typram; - signal iadr : std_logic_vector(7 downto 0); -begin - process (clk) - begin - if (clk'event and clk = '1') then - if (we = '1') then - blkram(conv_integer(adr)) <= dbo; - end if; - iadr <= adr; - end if; - end process; - - dbi <= blkram(conv_integer(iadr)); - +-- +-- ram.vhd +-- 256 bytes of block memory +-- Revision 1.00 +-- +-- Copyright (c) 2006 Kazuhiro Tsujikawa (ESE Artists' factory) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity ram is + port ( + adr : in std_logic_vector(7 downto 0); + clk : in std_logic; + we : in std_logic; + dbo : in std_logic_vector(7 downto 0); + dbi : out std_logic_vector(7 downto 0) + ); +end ram; + +architecture RTL of ram is + type typram is array (255 downto 0) of std_logic_vector(7 downto 0); + signal blkram : typram; + signal iadr : std_logic_vector(7 downto 0); +begin + process (clk) + begin + if (clk'event and clk = '1') then + if (we = '1') then + blkram(conv_integer(adr)) <= dbo; + end if; + iadr <= adr; + end if; + end process; + + dbi <= blkram(conv_integer(iadr)); + end RTL; \ No newline at end of file diff --git a/rtl/cart/rom.v b/rtl/cart/rom.v index 160d13b..a2c26e5 100644 --- a/rtl/cart/rom.v +++ b/rtl/cart/rom.v @@ -1,235 +1,235 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX Compatible Gateware IP Core -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ -// Notes: https://www.msx.org/wiki/ROM_mappers -//------------------------------------------------------------------------------ - -module cart_rom - ( - input wire clk, - input wire clk_en, - input wire reset, - input wire [15:0] addr, - input wire wr, - input wire rd, - input wire CS1_n, - input wire CS2_n, - input wire CS12_n, - input wire SLTSL_n, - input wire [7:0] d_from_cpu, - output wire [7:0] d_to_cpu, - output wire [14:0] sound, - - input wire ioctl_wr, - input wire [24:0] ioctl_addr, - input wire [7:0] ioctl_dout, - input wire ioctl_isROM, - output wire ioctl_wait, - input wire [3:0] user_mapper, - output wire [2:0] detected_mapper, - input wire [7:0] ram_dout, - output wire [7:0] ram_din, - output wire [24:0] ram_addr, - output wire ram_we, - output wire ram_rd, - input wire ram_ready, - input wire rom_enabled - ); - - assign ram_din = ioctl_dout; - assign ram_rd = ~SLTSL_n & ~ioctl_isROM; - assign ram_we = rom_we; - assign detected_mapper = auto_mapper; - - assign d_to_cpu = mapper == 4 && scc_ack ? d_to_cpu_scc : - mapper == 2 && sram_oe_gamemaster2 ? d_to_cpu_sram : - mapper == 6 && sram_oe_ascii16 ? d_to_cpu_sram : - mapper == 5 && sram_oe_ascii8 ? d_to_cpu_sram : - ~rom_enabled ? 8'hFF : - ram_dout ; - - assign sound = mapper == 4 ? scc_sound : 14'h0; - - wire rom_we = ioctl_isROM & ioctl_wr; - - wire [7:0] d_to_cpu_sram; - wire [12:0] sram_addr; - wire sram_we; - spram #(.addr_width(13),.mem_name("CART_SRAM")) cart_sram - ( - .clock ( clk ), - .address ( sram_addr ), - .wren ( sram_we ), - .q ( d_to_cpu_sram ), - .data ( d_from_cpu ) - ); - - assign ioctl_wait = ~ram_ready && ioctl_isROM; - - wire [3:0] mapper; - - // 0 uknown - // 1 nomaper - // 2 gamemaster2 - // 3 konami - // 4 konami SCC - // 5 ASCII 8 - // 6 ASCII 16 - // 7 linear (nomaper) 64kb. Aligned ROM image is replicated to 64KB area. - // 8 R-TYPE - // 9 FDD VY0010 - - assign mapper = user_mapper[3:0] == 0 ? {1'b0,auto_mapper} : user_mapper[3:0]; - assign ram_addr = ioctl_isROM ? ioctl_addr : - mapper == 2 ? mem_addr_gamemaster2 : - mapper == 3 ? mem_addr_konami : - mapper == 4 ? mem_addr_konami_scc : - mapper == 5 ? mem_addr_ascii8 : - mapper == 6 ? mem_addr_ascii16 : - mapper == 8 ? mem_addr_ascii16 : - mapper == 7 ? addr & (rom_size - 1) : - addr - {offset,12'd0} ; // default nomaper - - assign sram_addr = mapper == 2 ? sram_addr_gamemaster2 : - mapper == 6 ? sram_addr_ascii16 : - mapper == 5 ? sram_addr_ascii8 : - 'h0; - - assign sram_we = mapper == 2 ? sram_we_gamemaster2 : - mapper == 6 ? sram_we_ascii16 : - mapper == 5 ? sram_we_ascii8 : - 'h0; - - wire [3:0] offset; - wire [24:0] rom_size; - wire [2:0] auto_mapper; - - rom_detect rom_detect - ( - .clk ( clk ), - .ioctl_isROM ( ioctl_isROM ), - .ioctl_addr ( ioctl_addr ), - .ioctl_dout ( ioctl_dout ), - .rom_we ( rom_we ), - .mapper ( auto_mapper ), - .offset ( offset ), - .rom_size ( rom_size ) - ); - - wire [24:0] mem_addr_konami; - - cart_konami konami - ( - .clk ( clk ), - .reset ( reset ), - .rom_size ( rom_size ), - .addr ( addr ), - .d_from_cpu ( d_from_cpu ), - .wr ( wr ), - .cs ( ~SLTSL_n ), - .mem_addr ( mem_addr_konami ) - ); - - wire [24:0] mem_addr_konami_scc; - wire [7:0] d_to_cpu_scc; - wire scc_ack; - wire [14:0] scc_sound; - - cart_konami_scc konami_scc - ( - .clk ( clk ), - .clk_en ( clk_en ), - .reset ( reset ), - .rom_size ( rom_size ), - .addr ( addr ), - .d_from_cpu ( d_from_cpu ), - .d_to_cpu ( d_to_cpu_scc ), - .ack ( scc_ack ), - .wr ( wr ), - .rd ( rd ), - .cs ( ~SLTSL_n ), - .mem_addr ( mem_addr_konami_scc ), - .scc_sound ( scc_sound ) - ); - - wire [24:0] mem_addr_ascii8; - wire [12:0] sram_addr_ascii8; - wire sram_we_ascii8; - wire sram_oe_ascii8; - - cart_asci8 ascii8 - ( - .clk ( clk ), - .reset ( reset ), - .rom_size ( rom_size ), - .addr ( addr ), - .d_from_cpu ( d_from_cpu ), - .wr ( wr ), - .cs ( ~SLTSL_n ), - .mem_addr ( mem_addr_ascii8 ), - .sram_addr ( sram_addr_ascii8 ), - .sram_we ( sram_we_ascii8 ), - .sram_oe ( sram_oe_ascii8 ) - ); - - wire [24:0] mem_addr_ascii16; - wire [12:0] sram_addr_ascii16; - wire sram_we_ascii16; - wire sram_oe_ascii16; - - cart_asci16 ascii16 - ( - .clk ( clk ), - .reset ( reset ), - .rom_size ( rom_size ), - .addr ( addr ), - .d_from_cpu ( d_from_cpu ), - .wr ( wr ), - .cs ( ~SLTSL_n ), - .mem_addr ( mem_addr_ascii16 ), - .r_type ( mapper == 8 ), - .sram_addr ( sram_addr_ascii16 ), - .sram_we ( sram_we_ascii16 ), - .sram_oe ( sram_oe_ascii16 ) - ); - - wire [24:0] mem_addr_gamemaster2; - wire [12:0] sram_addr_gamemaster2; - wire sram_we_gamemaster2; - wire sram_oe_gamemaster2; - - cart_gamemaster2 gamemaster2 - ( - .clk ( clk ), - .reset ( reset ), - .addr ( addr ), - .d_from_cpu ( d_from_cpu ), - .wr ( wr ), - .cs ( ~SLTSL_n ), - .mem_addr ( mem_addr_gamemaster2 ), - .sram_addr ( sram_addr_gamemaster2 ), - .sram_we ( sram_we_gamemaster2 ), - .sram_oe ( sram_oe_gamemaster2 ) - ); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX Compatible Gateware IP Core +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ +// Notes: https://www.msx.org/wiki/ROM_mappers +//------------------------------------------------------------------------------ + +module cart_rom + ( + input wire clk, + input wire clk_en, + input wire reset, + input wire [15:0] addr, + input wire wr, + input wire rd, + input wire CS1_n, + input wire CS2_n, + input wire CS12_n, + input wire SLTSL_n, + input wire [7:0] d_from_cpu, + output wire [7:0] d_to_cpu, + output wire [14:0] sound, + + input wire ioctl_wr, + input wire [24:0] ioctl_addr, + input wire [7:0] ioctl_dout, + input wire ioctl_isROM, + output wire ioctl_wait, + input wire [3:0] user_mapper, + output wire [2:0] detected_mapper, + input wire [7:0] ram_dout, + output wire [7:0] ram_din, + output wire [24:0] ram_addr, + output wire ram_we, + output wire ram_rd, + input wire ram_ready, + input wire rom_enabled + ); + + assign ram_din = ioctl_dout; + assign ram_rd = ~SLTSL_n & ~ioctl_isROM; + assign ram_we = rom_we; + assign detected_mapper = auto_mapper; + + assign d_to_cpu = mapper == 4 && scc_ack ? d_to_cpu_scc : + mapper == 2 && sram_oe_gamemaster2 ? d_to_cpu_sram : + mapper == 6 && sram_oe_ascii16 ? d_to_cpu_sram : + mapper == 5 && sram_oe_ascii8 ? d_to_cpu_sram : + ~rom_enabled ? 8'hFF : + ram_dout ; + + assign sound = mapper == 4 ? scc_sound : 14'h0; + + wire rom_we = ioctl_isROM & ioctl_wr; + + wire [7:0] d_to_cpu_sram; + wire [12:0] sram_addr; + wire sram_we; + spram #(.addr_width(13),.mem_name("CART_SRAM")) cart_sram + ( + .clock ( clk ), + .address ( sram_addr ), + .wren ( sram_we ), + .q ( d_to_cpu_sram ), + .data ( d_from_cpu ) + ); + + assign ioctl_wait = ~ram_ready && ioctl_isROM; + + wire [3:0] mapper; + + // 0 uknown + // 1 nomaper + // 2 gamemaster2 + // 3 konami + // 4 konami SCC + // 5 ASCII 8 + // 6 ASCII 16 + // 7 linear (nomaper) 64kb. Aligned ROM image is replicated to 64KB area. + // 8 R-TYPE + // 9 FDD VY0010 + + assign mapper = user_mapper[3:0] == 0 ? {1'b0,auto_mapper} : user_mapper[3:0]; + assign ram_addr = ioctl_isROM ? ioctl_addr : + mapper == 2 ? mem_addr_gamemaster2 : + mapper == 3 ? mem_addr_konami : + mapper == 4 ? mem_addr_konami_scc : + mapper == 5 ? mem_addr_ascii8 : + mapper == 6 ? mem_addr_ascii16 : + mapper == 8 ? mem_addr_ascii16 : + mapper == 7 ? addr & (rom_size - 1) : + addr - {offset,12'd0} ; // default nomaper + + assign sram_addr = mapper == 2 ? sram_addr_gamemaster2 : + mapper == 6 ? sram_addr_ascii16 : + mapper == 5 ? sram_addr_ascii8 : + 'h0; + + assign sram_we = mapper == 2 ? sram_we_gamemaster2 : + mapper == 6 ? sram_we_ascii16 : + mapper == 5 ? sram_we_ascii8 : + 'h0; + + wire [3:0] offset; + wire [24:0] rom_size; + wire [2:0] auto_mapper; + + rom_detect rom_detect + ( + .clk ( clk ), + .ioctl_isROM ( ioctl_isROM ), + .ioctl_addr ( ioctl_addr ), + .ioctl_dout ( ioctl_dout ), + .rom_we ( rom_we ), + .mapper ( auto_mapper ), + .offset ( offset ), + .rom_size ( rom_size ) + ); + + wire [24:0] mem_addr_konami; + + cart_konami konami + ( + .clk ( clk ), + .reset ( reset ), + .rom_size ( rom_size ), + .addr ( addr ), + .d_from_cpu ( d_from_cpu ), + .wr ( wr ), + .cs ( ~SLTSL_n ), + .mem_addr ( mem_addr_konami ) + ); + + wire [24:0] mem_addr_konami_scc; + wire [7:0] d_to_cpu_scc; + wire scc_ack; + wire [14:0] scc_sound; + + cart_konami_scc konami_scc + ( + .clk ( clk ), + .clk_en ( clk_en ), + .reset ( reset ), + .rom_size ( rom_size ), + .addr ( addr ), + .d_from_cpu ( d_from_cpu ), + .d_to_cpu ( d_to_cpu_scc ), + .ack ( scc_ack ), + .wr ( wr ), + .rd ( rd ), + .cs ( ~SLTSL_n ), + .mem_addr ( mem_addr_konami_scc ), + .scc_sound ( scc_sound ) + ); + + wire [24:0] mem_addr_ascii8; + wire [12:0] sram_addr_ascii8; + wire sram_we_ascii8; + wire sram_oe_ascii8; + + cart_asci8 ascii8 + ( + .clk ( clk ), + .reset ( reset ), + .rom_size ( rom_size ), + .addr ( addr ), + .d_from_cpu ( d_from_cpu ), + .wr ( wr ), + .cs ( ~SLTSL_n ), + .mem_addr ( mem_addr_ascii8 ), + .sram_addr ( sram_addr_ascii8 ), + .sram_we ( sram_we_ascii8 ), + .sram_oe ( sram_oe_ascii8 ) + ); + + wire [24:0] mem_addr_ascii16; + wire [12:0] sram_addr_ascii16; + wire sram_we_ascii16; + wire sram_oe_ascii16; + + cart_asci16 ascii16 + ( + .clk ( clk ), + .reset ( reset ), + .rom_size ( rom_size ), + .addr ( addr ), + .d_from_cpu ( d_from_cpu ), + .wr ( wr ), + .cs ( ~SLTSL_n ), + .mem_addr ( mem_addr_ascii16 ), + .r_type ( mapper == 8 ), + .sram_addr ( sram_addr_ascii16 ), + .sram_we ( sram_we_ascii16 ), + .sram_oe ( sram_oe_ascii16 ) + ); + + wire [24:0] mem_addr_gamemaster2; + wire [12:0] sram_addr_gamemaster2; + wire sram_we_gamemaster2; + wire sram_oe_gamemaster2; + + cart_gamemaster2 gamemaster2 + ( + .clk ( clk ), + .reset ( reset ), + .addr ( addr ), + .d_from_cpu ( d_from_cpu ), + .wr ( wr ), + .cs ( ~SLTSL_n ), + .mem_addr ( mem_addr_gamemaster2 ), + .sram_addr ( sram_addr_gamemaster2 ), + .sram_we ( sram_we_gamemaster2 ), + .sram_oe ( sram_oe_gamemaster2 ) + ); + +endmodule diff --git a/rtl/cart/rom_detect.v b/rtl/cart/rom_detect.v index 285aa66..30221a7 100644 --- a/rtl/cart/rom_detect.v +++ b/rtl/cart/rom_detect.v @@ -1,128 +1,128 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX Compatible Gateware IP Core -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -module rom_detect - ( - input clk, - input ioctl_isROM, - input [24:0] ioctl_addr, - input [7:0] ioctl_dout, - input rom_we, - output [2:0] mapper, - output [3:0] offset, - output reg [24:0] rom_size - ); - - reg last_isROM; - reg [7:0] head[0:7]; - reg [7:0] head2[0:7]; - reg signed [15:0] asc16, asc8, kon4, kon5; - reg game1, game2; - - always @(posedge clk) begin - last_isROM = ioctl_isROM; - end - - always @(posedge clk) begin - reg [7:0] a0,a1,a2; - - if (ioctl_isROM && ~last_isROM) begin - asc16 <= 0; - asc8 <= 0; - kon4 <= 0; - kon5 <= 0; - game1 <= 0; - game2 <= 0; - a0 <= 0; - a1 <= 0; - a2 <= 0; - end - if (rom_we) begin - rom_size <= ioctl_addr + 1'd1 ; - if (ioctl_addr[24:7] == 0) begin - if (ioctl_addr[5:3] == 0) begin - if (ioctl_addr[6] == 0) begin - head [ioctl_addr[2:0]] <= ioctl_dout; - head2 [ioctl_addr[2:0]] <= 0; - end - else begin - head2[ioctl_addr[2:0]] <= ioctl_dout; - end - end - if (ioctl_addr[6:1] == 6'b001000) begin - if (ioctl_addr[0] == 0 && ioctl_dout == "Y") game1 <= 1; - if (ioctl_addr[0] == 1 && ioctl_dout == "Z") game2 <= 1; - end - end - a0 <= a1; - a1 <= a2; - a2 <= ioctl_dout; - if (ioctl_addr > 2) begin - if (a0 == 8'h32 && a1 == 0) begin - case (a2) - 8'h60, 8'h70: begin asc16 <= asc16 + 1'd1; asc8 <= asc8 + 1'd1; end - 8'h68, 8'h78: begin asc8 <= asc8 + 1'd1; asc16 <= asc16 - 1'd1; end - endcase - case (a2) - 8'h60, 8'h80, 8'ha0: begin kon4 <= kon4 + 1'd1; end - 8'h50, 8'h70, 8'h90, 8'hb0: begin kon5 <= kon5 + 1'd1; end - endcase - end - end - end - end - - // 0 uknown - // 1 nomaper - // 2 gamemaster2 - // 3 konami - // 4 konami SCC - // 5 ASCII 8 - // 6 ASCII 16 - - wire [15:0] kon = kon4 > kon5 ? kon4 : kon5; - wire [15:0] ascii = asc8 > asc16 ? asc8 : asc16; - - assign mapper = rom_size < 25'h2000 ? 3'd0 : - rom_size < 25'h10000 ? 3'd1 : - rom_size && game1 && game2 > 25'h18000 ? 3'd2 : - kon > ascii ? (kon5 > kon4 ? 3'd4 : 3'd3) : - (asc8 > asc16 ? 3'd5 : 3'd6) ; - - wire [15:0] start = head[3] << 8 | head[2]; - wire [15:0] start4000 = head2[3] << 8 | head2[2]; - wire romSig_at_0000 = head [0] == "A" && head [1] == "B"; - wire romSig_at_4000 = head2[0] == "A" && head2[1] == "B"; - - wire [3:0] start_1 = start == 0 ? ((head[5] & 8'hC0) != 8'h40 ? 4'h8 : 4'h4) : ((start & 16'hC000) == 16'h8000 ? 4'h8 : 4'h4); - wire [3:0] start_2 = ( ~romSig_at_0000 && romSig_at_4000 ) ? ((start4000 == 0 && (head2[5] & 8'hC0) == 8'h40) || start4000 < 16'h8000 || start4000 >= 16'hC000) ? 4'h0 : 4'h4 : 4'h4; - wire [3:0] start_3 = (~(romSig_at_0000 && ~romSig_at_4000)) ? 4'h0 : 4'h4; - - assign offset = rom_size == 16'h1000 ? start_1 : - rom_size == 16'h2000 ? start_1 : - rom_size == 16'h4000 ? start_1 : - rom_size == 16'h8000 ? start_2 : - rom_size == 16'hC000 ? start_3 : 4'h0; - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX Compatible Gateware IP Core +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +module rom_detect + ( + input clk, + input ioctl_isROM, + input [24:0] ioctl_addr, + input [7:0] ioctl_dout, + input rom_we, + output [2:0] mapper, + output [3:0] offset, + output reg [24:0] rom_size + ); + + reg last_isROM; + reg [7:0] head[0:7]; + reg [7:0] head2[0:7]; + reg signed [15:0] asc16, asc8, kon4, kon5; + reg game1, game2; + + always @(posedge clk) begin + last_isROM = ioctl_isROM; + end + + always @(posedge clk) begin + reg [7:0] a0,a1,a2; + + if (ioctl_isROM && ~last_isROM) begin + asc16 <= 0; + asc8 <= 0; + kon4 <= 0; + kon5 <= 0; + game1 <= 0; + game2 <= 0; + a0 <= 0; + a1 <= 0; + a2 <= 0; + end + if (rom_we) begin + rom_size <= ioctl_addr + 1'd1 ; + if (ioctl_addr[24:7] == 0) begin + if (ioctl_addr[5:3] == 0) begin + if (ioctl_addr[6] == 0) begin + head [ioctl_addr[2:0]] <= ioctl_dout; + head2 [ioctl_addr[2:0]] <= 0; + end + else begin + head2[ioctl_addr[2:0]] <= ioctl_dout; + end + end + if (ioctl_addr[6:1] == 6'b001000) begin + if (ioctl_addr[0] == 0 && ioctl_dout == "Y") game1 <= 1; + if (ioctl_addr[0] == 1 && ioctl_dout == "Z") game2 <= 1; + end + end + a0 <= a1; + a1 <= a2; + a2 <= ioctl_dout; + if (ioctl_addr > 2) begin + if (a0 == 8'h32 && a1 == 0) begin + case (a2) + 8'h60, 8'h70: begin asc16 <= asc16 + 1'd1; asc8 <= asc8 + 1'd1; end + 8'h68, 8'h78: begin asc8 <= asc8 + 1'd1; asc16 <= asc16 - 1'd1; end + endcase + case (a2) + 8'h60, 8'h80, 8'ha0: begin kon4 <= kon4 + 1'd1; end + 8'h50, 8'h70, 8'h90, 8'hb0: begin kon5 <= kon5 + 1'd1; end + endcase + end + end + end + end + + // 0 uknown + // 1 nomaper + // 2 gamemaster2 + // 3 konami + // 4 konami SCC + // 5 ASCII 8 + // 6 ASCII 16 + + wire [15:0] kon = kon4 > kon5 ? kon4 : kon5; + wire [15:0] ascii = asc8 > asc16 ? asc8 : asc16; + + assign mapper = rom_size < 25'h2000 ? 3'd0 : + rom_size < 25'h10000 ? 3'd1 : + rom_size && game1 && game2 > 25'h18000 ? 3'd2 : + kon > ascii ? (kon5 > kon4 ? 3'd4 : 3'd3) : + (asc8 > asc16 ? 3'd5 : 3'd6) ; + + wire [15:0] start = head[3] << 8 | head[2]; + wire [15:0] start4000 = head2[3] << 8 | head2[2]; + wire romSig_at_0000 = head [0] == "A" && head [1] == "B"; + wire romSig_at_4000 = head2[0] == "A" && head2[1] == "B"; + + wire [3:0] start_1 = start == 0 ? ((head[5] & 8'hC0) != 8'h40 ? 4'h8 : 4'h4) : ((start & 16'hC000) == 16'h8000 ? 4'h8 : 4'h4); + wire [3:0] start_2 = ( ~romSig_at_0000 && romSig_at_4000 ) ? ((start4000 == 0 && (head2[5] & 8'hC0) == 8'h40) || start4000 < 16'h8000 || start4000 >= 16'hC000) ? 4'h0 : 4'h4 : 4'h4; + wire [3:0] start_3 = (~(romSig_at_0000 && ~romSig_at_4000)) ? 4'h0 : 4'h4; + + assign offset = rom_size == 16'h1000 ? start_1 : + rom_size == 16'h2000 ? start_1 : + rom_size == 16'h4000 ? start_1 : + rom_size == 16'h8000 ? start_2 : + rom_size == 16'hC000 ? start_3 : 4'h0; + +endmodule diff --git a/rtl/cart/scc_wave.vhd b/rtl/cart/scc_wave.vhd index 6c53ab0..fb53ce8 100644 --- a/rtl/cart/scc_wave.vhd +++ b/rtl/cart/scc_wave.vhd @@ -1,483 +1,483 @@ --- --- scc_wave.vhd --- Sound generator with wave table --- Revision 1.00 --- --- Copyright (c) 2006 Kazuhiro Tsujikawa (ESE Artists' factory) --- All rights reserved. --- --- Redistribution and use of this source code or any derivative works, are --- permitted provided that the following conditions are met: --- --- 1. Redistributions of source code must retain the above copyright notice, --- this list of conditions and the following disclaimer. --- 2. Redistributions in binary form must reproduce the above copyright --- notice, this list of conditions and the following disclaimer in the --- documentation and/or other materials provided with the distribution. --- 3. Redistributions may not be sold, nor may they be used in a commercial --- product or activity without specific prior written permission. --- --- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS --- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR --- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR --- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, --- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, --- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; --- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, --- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR --- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF --- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --- - --- 2007/01/31 modified by t.hara - -library ieee; - use ieee.std_logic_1164.all; - use ieee.std_logic_signed.all; - -entity scc_wave_mul is - port( - a : in std_logic_vector( 7 downto 0 ); -- 8bit �Q�̕␔ - b : in std_logic_vector( 3 downto 0 ); -- 4bit �o�C�i�� - c : out std_logic_vector( 11 downto 0 ) -- 12bit �Q�̕␔ - ); -end scc_wave_mul; - -architecture rtl of scc_wave_mul is - signal w_mul : std_logic_vector( 12 downto 0 ); -begin - w_mul <= a * ('0' & b); - c <= w_mul( 11 downto 0 ); -end rtl; - ------------------------------------------------------------------------- -library ieee; - use ieee.std_logic_1164.all; - use ieee.std_logic_signed.all; - -entity scc_mix_mul is - port( - a : in std_logic_vector( 15 downto 0 ); -- 16bit �Q�̕␔ - b : in std_logic_vector( 2 downto 0 ); -- 3bit �o�C�i�� - c : out std_logic_vector( 18 downto 0 ) -- 19bit �Q�̕␔ - ); -end scc_mix_mul; - -architecture rtl of scc_mix_mul is - signal w_mul : std_logic_vector( 19 downto 0 ); -begin - w_mul <= a * ('0' & b); - c <= w_mul( 18 downto 0 ); -end rtl; - ------------------------------------------------------------------------- -library ieee; - use ieee.std_logic_1164.all; - use ieee.std_logic_unsigned.all; - -entity scc_wave is - port( - clk21m : in std_logic; - reset : in std_logic; - clkena : in std_logic; - req : in std_logic; - ack : out std_logic; - wrt : in std_logic; - adr : in std_logic_vector( 7 downto 0 ); - dbi : out std_logic_vector( 7 downto 0 ); - dbo : in std_logic_vector( 7 downto 0 ); - wave : out std_logic_vector( 14 downto 0 ) - ); -end scc_wave; - -architecture rtl of scc_wave is - - -- wire signal - signal w_wave_ce : std_logic; - signal w_wave_we : std_logic; - signal w_wave_adr : std_logic_vector( 7 downto 0 ); - signal w_ch_dec : std_logic_vector( 4 downto 0 ); - signal w_ch_bit : std_logic; - signal w_ch_mask : std_logic_vector( 7 downto 0 ); - signal w_ch_vol : std_logic_vector( 3 downto 0 ); - signal w_wave : std_logic_vector( 7 downto 0 ); - signal w_mul : std_logic_vector( 11 downto 0 ); - signal ram_dbi : std_logic_vector( 7 downto 0 ); - signal lpf1_wave : std_logic_vector( 14 downto 0 ); - signal lpf2_wave : std_logic_vector( 14 downto 0 ); - signal lpf3_wave : std_logic_vector( 14 downto 0 ); - - -- scc resisters - signal reg_freq_ch_a : std_logic_vector( 11 downto 0 ); - signal reg_freq_ch_b : std_logic_vector( 11 downto 0 ); - signal reg_freq_ch_c : std_logic_vector( 11 downto 0 ); - signal reg_freq_ch_d : std_logic_vector( 11 downto 0 ); - signal reg_freq_ch_e : std_logic_vector( 11 downto 0 ); - signal reg_vol_ch_a : std_logic_vector( 3 downto 0 ); - signal reg_vol_ch_b : std_logic_vector( 3 downto 0 ); - signal reg_vol_ch_c : std_logic_vector( 3 downto 0 ); - signal reg_vol_ch_d : std_logic_vector( 3 downto 0 ); - signal reg_vol_ch_e : std_logic_vector( 3 downto 0 ); - signal reg_ch_sel : std_logic_vector( 4 downto 0 ); - signal reg_mode_sel : std_logic_vector( 7 downto 0 ); - - -- internal registers - signal ff_rst_ch_a : std_logic; - signal ff_rst_ch_b : std_logic; - signal ff_rst_ch_c : std_logic; - signal ff_rst_ch_d : std_logic; - signal ff_rst_ch_e : std_logic; - signal ff_ptr_ch_a : std_logic_vector( 4 downto 0 ); - signal ff_ptr_ch_b : std_logic_vector( 4 downto 0 ); - signal ff_ptr_ch_c : std_logic_vector( 4 downto 0 ); - signal ff_ptr_ch_d : std_logic_vector( 4 downto 0 ); - signal ff_ptr_ch_e : std_logic_vector( 4 downto 0 ); - signal ff_ch_num : std_logic_vector( 2 downto 0 ); - signal ff_ch_num_dl : std_logic_vector( 2 downto 0 ); - signal ff_mix : std_logic_vector( 14 downto 0 ); - signal ff_wave_ce : std_logic; - signal ff_wave_ce_dl : std_logic; - signal ff_req_dl : std_logic; - signal ff_wave_dat : std_logic_vector( 7 downto 0 ); - signal ff_wave : std_logic_vector( 14 downto 0 ); -begin - - ---------------------------------------------------------------- - -- scc register access - ---------------------------------------------------------------- - process(clk21m, reset) - begin - if (rising_edge(clk21m)) then - - if( reset = '1' )then - ff_req_dl <= '0'; - - reg_freq_ch_a <= (others => '0'); - reg_freq_ch_b <= (others => '0'); - reg_freq_ch_c <= (others => '0'); - reg_freq_ch_d <= (others => '0'); - reg_freq_ch_e <= (others => '0'); - - reg_vol_ch_a <= (others => '0'); - reg_vol_ch_b <= (others => '0'); - reg_vol_ch_c <= (others => '0'); - reg_vol_ch_d <= (others => '0'); - reg_vol_ch_e <= (others => '0'); - - reg_ch_sel <= (others => '0'); - reg_mode_sel <= (others => '0'); - - ff_rst_ch_a <= '0'; - ff_rst_ch_b <= '0'; - ff_rst_ch_c <= '0'; - ff_rst_ch_d <= '0'; - ff_rst_ch_e <= '0'; - - else - - -- mapped i/o port access on b8a0-b8afh (9880-988fh) ... register write - if( req = '1' and ff_req_dl = '0' and adr(7 downto 5) = "101" and wrt = '1' )then - case adr(3 downto 0) is - when "0000" => reg_freq_ch_a( 7 downto 0 ) <= dbo( 7 downto 0 ); ff_rst_ch_a <= reg_mode_sel(5); - when "0001" => reg_freq_ch_a( 11 downto 8 ) <= dbo( 3 downto 0 ); ff_rst_ch_a <= reg_mode_sel(5); - when "0010" => reg_freq_ch_b( 7 downto 0 ) <= dbo( 7 downto 0 ); ff_rst_ch_b <= reg_mode_sel(5); - when "0011" => reg_freq_ch_b( 11 downto 8 ) <= dbo( 3 downto 0 ); ff_rst_ch_b <= reg_mode_sel(5); - when "0100" => reg_freq_ch_c( 7 downto 0 ) <= dbo( 7 downto 0 ); ff_rst_ch_c <= reg_mode_sel(5); - when "0101" => reg_freq_ch_c( 11 downto 8 ) <= dbo( 3 downto 0 ); ff_rst_ch_c <= reg_mode_sel(5); - when "0110" => reg_freq_ch_d( 7 downto 0 ) <= dbo( 7 downto 0 ); ff_rst_ch_d <= reg_mode_sel(5); - when "0111" => reg_freq_ch_d( 11 downto 8 ) <= dbo( 3 downto 0 ); ff_rst_ch_d <= reg_mode_sel(5); - when "1000" => reg_freq_ch_e( 7 downto 0 ) <= dbo( 7 downto 0 ); ff_rst_ch_e <= reg_mode_sel(5); - when "1001" => reg_freq_ch_e( 11 downto 8 ) <= dbo( 3 downto 0 ); ff_rst_ch_e <= reg_mode_sel(5); - when "1010" => reg_vol_ch_a( 3 downto 0 ) <= dbo( 3 downto 0 ); - when "1011" => reg_vol_ch_b( 3 downto 0 ) <= dbo( 3 downto 0 ); - when "1100" => reg_vol_ch_c( 3 downto 0 ) <= dbo( 3 downto 0 ); - when "1101" => reg_vol_ch_d( 3 downto 0 ) <= dbo( 3 downto 0 ); - when "1110" => reg_vol_ch_e( 3 downto 0 ) <= dbo( 3 downto 0 ); - when others => reg_ch_sel( 4 downto 0 ) <= dbo( 4 downto 0 ); - end case; - elsif (clkena = '1') then - ff_rst_ch_a <= '0'; - ff_rst_ch_b <= '0'; - ff_rst_ch_c <= '0'; - ff_rst_ch_d <= '0'; - ff_rst_ch_e <= '0'; - end if; - - -- mapped i/o port access on b8c0-b8dfh (98e0-98ffh) ... register write - if( req = '1' and wrt = '1' and adr(7 downto 5) = "110" )then - reg_mode_sel <= dbo; - end if; - - ff_req_dl <= req; - end if; - end if; - end process; - - -- mapped i/o port access on b800-bfffh (9800-9fffh) ... wave memory access - w_wave_ce <= '1' when( req = '1' and ff_req_dl = '0' )else '0'; - w_wave_we <= wrt when( req = '1' and ff_req_dl = '0' )else '0'; - ack <= ff_req_dl; - - ---------------------------------------------------------------- - -- tone generator - ---------------------------------------------------------------- - process(clk21m, reset) - variable ff_cnt_ch_a : std_logic_vector( 11 downto 0 ); - variable ff_cnt_ch_b : std_logic_vector( 11 downto 0 ); - variable ff_cnt_ch_c : std_logic_vector( 11 downto 0 ); - variable ff_cnt_ch_d : std_logic_vector( 11 downto 0 ); - variable ff_cnt_ch_e : std_logic_vector( 11 downto 0 ); - begin - if (rising_edge(clk21m)) then - if (reset = '1') then - ff_cnt_ch_a := (others => '0'); - ff_cnt_ch_b := (others => '0'); - ff_cnt_ch_c := (others => '0'); - ff_cnt_ch_d := (others => '0'); - ff_cnt_ch_e := (others => '0'); - - ff_ptr_ch_a <= (others => '0'); - ff_ptr_ch_b <= (others => '0'); - ff_ptr_ch_c <= (others => '0'); - ff_ptr_ch_d <= (others => '0'); - ff_ptr_ch_e <= (others => '0'); - else - if (clkena = '1') then - - if (reg_freq_ch_a(11 downto 3) = "000000000" or ff_rst_ch_a = '1') then - ff_ptr_ch_a <= "00000"; - ff_cnt_ch_a := reg_freq_ch_a; - elsif (ff_cnt_ch_a = x"000") then - ff_ptr_ch_a <= ff_ptr_ch_a + 1; - ff_cnt_ch_a := reg_freq_ch_a; - else - ff_cnt_ch_a := ff_cnt_ch_a - 1; - end if; - - if (reg_freq_ch_b(11 downto 3) = "000000000" or ff_rst_ch_b = '1') then - ff_ptr_ch_b <= "00000"; - ff_cnt_ch_b := reg_freq_ch_b; - elsif (ff_cnt_ch_b = x"000") then - ff_ptr_ch_b <= ff_ptr_ch_b + 1; - ff_cnt_ch_b := reg_freq_ch_b; - else - ff_cnt_ch_b := ff_cnt_ch_b - 1; - end if; - - if (reg_freq_ch_c(11 downto 3) = "000000000" or ff_rst_ch_c = '1') then - ff_ptr_ch_c <= "00000"; - ff_cnt_ch_c := reg_freq_ch_c; - elsif (ff_cnt_ch_c = x"000") then - ff_ptr_ch_c <= ff_ptr_ch_c + 1; - ff_cnt_ch_c := reg_freq_ch_c; - else - ff_cnt_ch_c := ff_cnt_ch_c - 1; - end if; - - if (reg_freq_ch_d(11 downto 3) = "000000000" or ff_rst_ch_d = '1') then - ff_ptr_ch_d <= "00000"; - ff_cnt_ch_d := reg_freq_ch_d; - elsif (ff_cnt_ch_d = x"000") then - ff_ptr_ch_d <= ff_ptr_ch_d + 1; - ff_cnt_ch_d := reg_freq_ch_d; - else - ff_cnt_ch_d := ff_cnt_ch_d - 1; - end if; - - if (reg_freq_ch_e(11 downto 3) = "000000000" or ff_rst_ch_e = '1') then - ff_ptr_ch_e <= "00000"; - ff_cnt_ch_e := reg_freq_ch_e; - elsif (ff_cnt_ch_e = x"000") then - ff_ptr_ch_e <= ff_ptr_ch_e + 1; - ff_cnt_ch_e := reg_freq_ch_e; - else - ff_cnt_ch_e := ff_cnt_ch_e - 1; - end if; - - end if; - end if; - end if; - end process; - - ---------------------------------------------------------------- - -- wave memory control - ---------------------------------------------------------------- - w_wave_adr <= adr when( w_wave_ce = '1' )else - ("000" & ff_ptr_ch_a) when( ff_ch_num = "000" )else - ("001" & ff_ptr_ch_b) when( ff_ch_num = "001" )else - ("010" & ff_ptr_ch_c) when( ff_ch_num = "010" )else - ("011" & ff_ptr_ch_d) when( ff_ch_num = "011" )else - ("100" & ff_ptr_ch_e); - - wavemem : work.ram - port map( - adr => w_wave_adr , - clk => clk21m , - we => w_wave_we , - dbo => dbo , - dbi => ram_dbi - ); - - -- wave memory read - process( reset, clk21m ) - begin - if( rising_edge(clk21m) )then - if( reset = '1' )then - dbi <= (others => '1'); - else - -- mapped i/o port access on b800-bfffh (9800-9fffh) ... wave memory read data - if( ff_wave_ce = '1' )then - dbi <= ram_dbi; - end if; - end if; - end if; - end process; - - ---------------------------------------------------------------- - -- delay signal - ---------------------------------------------------------------- - process( reset, clk21m ) - begin - if( rising_edge(clk21m) ) then - if( reset = '1' )then - ff_wave_ce <= '0'; - ff_wave_ce_dl <= '0'; - ff_wave_dat <= (others => '0'); - ff_ch_num_dl <= (others => '0'); - else - ff_wave_ce <= w_wave_ce; - ff_wave_ce_dl <= ff_wave_ce; - ff_wave_dat <= ram_dbi; - ff_ch_num_dl <= ff_ch_num; - end if; - end if; - end process; - - ---------------------------------------------------------------- - -- mixer control - ---------------------------------------------------------------- - with ff_ch_num_dl select w_ch_dec <= - "00001" when "001", - "00010" when "010", - "00100" when "011", - "01000" when "100", - "10000" when "101", - "00000" when others; - - w_ch_bit <= (w_ch_dec(0) and reg_ch_sel(0)) or - (w_ch_dec(1) and reg_ch_sel(1)) or - (w_ch_dec(2) and reg_ch_sel(2)) or - (w_ch_dec(3) and reg_ch_sel(3)) or - (w_ch_dec(4) and reg_ch_sel(4)); - - w_ch_mask <= (others => w_ch_bit); - - with ff_ch_num_dl select w_ch_vol <= - reg_vol_ch_a when "001", - reg_vol_ch_b when "010", - reg_vol_ch_c when "011", - reg_vol_ch_d when "100", - reg_vol_ch_e when "101", - (others => '0') when others; - - w_wave <= (w_ch_mask and ff_wave_dat); -- 8bit ��̕␔ - - u_mul: work.scc_wave_mul - port map ( - a => w_wave , -- 8bit ��̕␔ - b => w_ch_vol , -- 4bit �o�C�i���i���������j - c => w_mul -- 12bit ��̕␔ - ); - - -- ------------------------------------------------------------- - -- ff_ch_num X 0 X 1 X 2 X 3 X 4 X 5 X 0 - -- ff_ch_num_dl X 0 X 1 X 2 X 3 X 4 X 5 X 0 - -- w_wave_adr X chA X chB X chC X chD X chE - -- ram_dbi X chA X chB X chC X chD X chE - -- ff_wave_dat X chA X chB X chC X chD X chE - -- ff_mix X a X ab X a-c X a-d X a-e X 0 - -- wave X a-e - -- ------------------------------------------------------------- - -- w_wave_ce X 0 X 1 X 0 - -- ff_wave_ce X 0 X 1 X 0 - -- ff_wave_ce_dl X 0 X 1 X 0 - -- - -- ff_ch_num X 0 X 1 X 2 X 3 X 4 X 5 X 0 - -- ff_ch_num_dl X 0 X 1 X 2 X 3 X 4 X 5 X 0 - -- w_wave_adr X chA X chB X chC X chD X chE - -- ram_dbi X chA X chB X chC X chD X chE - -- ff_wave_dat X chA X chB X chC X chD X chE - -- ff_mix X a X ab X a-c X a-d X a-e X 0 - -- wave X a-e - -- ------------------------------------------------------------- - -- w_wave_ce X 0 X 1 X 0 - -- ff_wave_ce X 0 X 1 X 0 - -- ff_wave_ce_dl X 0 X 1 X 0 X - -- ~~~~~ - -- ff_ch_num X 0 X 1 X 2 X 3 X 4 X 5 X 0 X 1 - -- ff_ch_num_dl X 0 X 1 X 2 X 3 X 4 X 5 X 0 X 1 X 2 X - -- ~~~~~~~~~~~ - -- w_wave_adr X chA X chB X chC X chD X chE X chA X chB X chC X - -- ram_dbi X chA X chB X chC X chD X chE X chA X chB X chC X - -- ff_wave_dat X chA X chB X chC X chD X chE X chA X chB X chC X - -- ff_mix X a X ab X a-c X a-d X a-e X 0 X a X ab X - -- wave X a-e - -- ~~~~~ - -- wave �́Aff_wave_ce_dl = 0 and ff_ch_num_dl = 0 �̂Ƃ� ff_mix ����荞�� - ---------------------------------------------------------------- - process( reset, clk21m ) - begin - if( rising_edge(clk21m) )then - if( reset = '1' )then - ff_ch_num <= "000"; - else - if( ff_wave_ce = '0' )then - if( ff_ch_num = "101" )then - ff_ch_num <= "000"; - else - ff_ch_num <= ff_ch_num + 1; - end if; - end if; - end if; - end if; - end process; - - -- mixer - process( reset, clk21m ) - begin - if( rising_edge(clk21m) )then - if( reset = '1' )then - ff_mix <= (others => '0'); - else - if( ff_wave_ce_dl = '0' )then - if( ff_ch_num_dl = "000" )then - ff_mix <= (others => '0'); - else - ff_mix <= (w_mul(11) & w_mul(11) & w_mul(11) & w_mul) + ff_mix; -- 15bit ��̕␔ - end if; - end if; - end if; - end if; - end process; - - -- wave out - process( reset, clk21m ) - begin - if( rising_edge(clk21m) )then - if( reset = '1' )then - ff_wave <= (others => '0'); - else - if( ff_wave_ce_dl = '0' )then - if( ff_ch_num_dl = "000" )then - ff_wave <= ff_mix; -- 15bit ��̕␔ - else - -- hold - end if; - end if; - end if; - end if; - end process; - - wave <= ff_wave; -end rtl; +-- +-- scc_wave.vhd +-- Sound generator with wave table +-- Revision 1.00 +-- +-- Copyright (c) 2006 Kazuhiro Tsujikawa (ESE Artists' factory) +-- All rights reserved. +-- +-- Redistribution and use of this source code or any derivative works, are +-- permitted provided that the following conditions are met: +-- +-- 1. Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- 3. Redistributions may not be sold, nor may they be used in a commercial +-- product or activity without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +-- OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +-- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +-- OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +-- ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-- + +-- 2007/01/31 modified by t.hara + +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_signed.all; + +entity scc_wave_mul is + port( + a : in std_logic_vector( 7 downto 0 ); -- 8bit �Q�̕␔ + b : in std_logic_vector( 3 downto 0 ); -- 4bit �o�C�i�� + c : out std_logic_vector( 11 downto 0 ) -- 12bit �Q�̕␔ + ); +end scc_wave_mul; + +architecture rtl of scc_wave_mul is + signal w_mul : std_logic_vector( 12 downto 0 ); +begin + w_mul <= a * ('0' & b); + c <= w_mul( 11 downto 0 ); +end rtl; + +------------------------------------------------------------------------ +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_signed.all; + +entity scc_mix_mul is + port( + a : in std_logic_vector( 15 downto 0 ); -- 16bit �Q�̕␔ + b : in std_logic_vector( 2 downto 0 ); -- 3bit �o�C�i�� + c : out std_logic_vector( 18 downto 0 ) -- 19bit �Q�̕␔ + ); +end scc_mix_mul; + +architecture rtl of scc_mix_mul is + signal w_mul : std_logic_vector( 19 downto 0 ); +begin + w_mul <= a * ('0' & b); + c <= w_mul( 18 downto 0 ); +end rtl; + +------------------------------------------------------------------------ +library ieee; + use ieee.std_logic_1164.all; + use ieee.std_logic_unsigned.all; + +entity scc_wave is + port( + clk21m : in std_logic; + reset : in std_logic; + clkena : in std_logic; + req : in std_logic; + ack : out std_logic; + wrt : in std_logic; + adr : in std_logic_vector( 7 downto 0 ); + dbi : out std_logic_vector( 7 downto 0 ); + dbo : in std_logic_vector( 7 downto 0 ); + wave : out std_logic_vector( 14 downto 0 ) + ); +end scc_wave; + +architecture rtl of scc_wave is + + -- wire signal + signal w_wave_ce : std_logic; + signal w_wave_we : std_logic; + signal w_wave_adr : std_logic_vector( 7 downto 0 ); + signal w_ch_dec : std_logic_vector( 4 downto 0 ); + signal w_ch_bit : std_logic; + signal w_ch_mask : std_logic_vector( 7 downto 0 ); + signal w_ch_vol : std_logic_vector( 3 downto 0 ); + signal w_wave : std_logic_vector( 7 downto 0 ); + signal w_mul : std_logic_vector( 11 downto 0 ); + signal ram_dbi : std_logic_vector( 7 downto 0 ); + signal lpf1_wave : std_logic_vector( 14 downto 0 ); + signal lpf2_wave : std_logic_vector( 14 downto 0 ); + signal lpf3_wave : std_logic_vector( 14 downto 0 ); + + -- scc resisters + signal reg_freq_ch_a : std_logic_vector( 11 downto 0 ); + signal reg_freq_ch_b : std_logic_vector( 11 downto 0 ); + signal reg_freq_ch_c : std_logic_vector( 11 downto 0 ); + signal reg_freq_ch_d : std_logic_vector( 11 downto 0 ); + signal reg_freq_ch_e : std_logic_vector( 11 downto 0 ); + signal reg_vol_ch_a : std_logic_vector( 3 downto 0 ); + signal reg_vol_ch_b : std_logic_vector( 3 downto 0 ); + signal reg_vol_ch_c : std_logic_vector( 3 downto 0 ); + signal reg_vol_ch_d : std_logic_vector( 3 downto 0 ); + signal reg_vol_ch_e : std_logic_vector( 3 downto 0 ); + signal reg_ch_sel : std_logic_vector( 4 downto 0 ); + signal reg_mode_sel : std_logic_vector( 7 downto 0 ); + + -- internal registers + signal ff_rst_ch_a : std_logic; + signal ff_rst_ch_b : std_logic; + signal ff_rst_ch_c : std_logic; + signal ff_rst_ch_d : std_logic; + signal ff_rst_ch_e : std_logic; + signal ff_ptr_ch_a : std_logic_vector( 4 downto 0 ); + signal ff_ptr_ch_b : std_logic_vector( 4 downto 0 ); + signal ff_ptr_ch_c : std_logic_vector( 4 downto 0 ); + signal ff_ptr_ch_d : std_logic_vector( 4 downto 0 ); + signal ff_ptr_ch_e : std_logic_vector( 4 downto 0 ); + signal ff_ch_num : std_logic_vector( 2 downto 0 ); + signal ff_ch_num_dl : std_logic_vector( 2 downto 0 ); + signal ff_mix : std_logic_vector( 14 downto 0 ); + signal ff_wave_ce : std_logic; + signal ff_wave_ce_dl : std_logic; + signal ff_req_dl : std_logic; + signal ff_wave_dat : std_logic_vector( 7 downto 0 ); + signal ff_wave : std_logic_vector( 14 downto 0 ); +begin + + ---------------------------------------------------------------- + -- scc register access + ---------------------------------------------------------------- + process(clk21m, reset) + begin + if (rising_edge(clk21m)) then + + if( reset = '1' )then + ff_req_dl <= '0'; + + reg_freq_ch_a <= (others => '0'); + reg_freq_ch_b <= (others => '0'); + reg_freq_ch_c <= (others => '0'); + reg_freq_ch_d <= (others => '0'); + reg_freq_ch_e <= (others => '0'); + + reg_vol_ch_a <= (others => '0'); + reg_vol_ch_b <= (others => '0'); + reg_vol_ch_c <= (others => '0'); + reg_vol_ch_d <= (others => '0'); + reg_vol_ch_e <= (others => '0'); + + reg_ch_sel <= (others => '0'); + reg_mode_sel <= (others => '0'); + + ff_rst_ch_a <= '0'; + ff_rst_ch_b <= '0'; + ff_rst_ch_c <= '0'; + ff_rst_ch_d <= '0'; + ff_rst_ch_e <= '0'; + + else + + -- mapped i/o port access on b8a0-b8afh (9880-988fh) ... register write + if( req = '1' and ff_req_dl = '0' and adr(7 downto 5) = "101" and wrt = '1' )then + case adr(3 downto 0) is + when "0000" => reg_freq_ch_a( 7 downto 0 ) <= dbo( 7 downto 0 ); ff_rst_ch_a <= reg_mode_sel(5); + when "0001" => reg_freq_ch_a( 11 downto 8 ) <= dbo( 3 downto 0 ); ff_rst_ch_a <= reg_mode_sel(5); + when "0010" => reg_freq_ch_b( 7 downto 0 ) <= dbo( 7 downto 0 ); ff_rst_ch_b <= reg_mode_sel(5); + when "0011" => reg_freq_ch_b( 11 downto 8 ) <= dbo( 3 downto 0 ); ff_rst_ch_b <= reg_mode_sel(5); + when "0100" => reg_freq_ch_c( 7 downto 0 ) <= dbo( 7 downto 0 ); ff_rst_ch_c <= reg_mode_sel(5); + when "0101" => reg_freq_ch_c( 11 downto 8 ) <= dbo( 3 downto 0 ); ff_rst_ch_c <= reg_mode_sel(5); + when "0110" => reg_freq_ch_d( 7 downto 0 ) <= dbo( 7 downto 0 ); ff_rst_ch_d <= reg_mode_sel(5); + when "0111" => reg_freq_ch_d( 11 downto 8 ) <= dbo( 3 downto 0 ); ff_rst_ch_d <= reg_mode_sel(5); + when "1000" => reg_freq_ch_e( 7 downto 0 ) <= dbo( 7 downto 0 ); ff_rst_ch_e <= reg_mode_sel(5); + when "1001" => reg_freq_ch_e( 11 downto 8 ) <= dbo( 3 downto 0 ); ff_rst_ch_e <= reg_mode_sel(5); + when "1010" => reg_vol_ch_a( 3 downto 0 ) <= dbo( 3 downto 0 ); + when "1011" => reg_vol_ch_b( 3 downto 0 ) <= dbo( 3 downto 0 ); + when "1100" => reg_vol_ch_c( 3 downto 0 ) <= dbo( 3 downto 0 ); + when "1101" => reg_vol_ch_d( 3 downto 0 ) <= dbo( 3 downto 0 ); + when "1110" => reg_vol_ch_e( 3 downto 0 ) <= dbo( 3 downto 0 ); + when others => reg_ch_sel( 4 downto 0 ) <= dbo( 4 downto 0 ); + end case; + elsif (clkena = '1') then + ff_rst_ch_a <= '0'; + ff_rst_ch_b <= '0'; + ff_rst_ch_c <= '0'; + ff_rst_ch_d <= '0'; + ff_rst_ch_e <= '0'; + end if; + + -- mapped i/o port access on b8c0-b8dfh (98e0-98ffh) ... register write + if( req = '1' and wrt = '1' and adr(7 downto 5) = "110" )then + reg_mode_sel <= dbo; + end if; + + ff_req_dl <= req; + end if; + end if; + end process; + + -- mapped i/o port access on b800-bfffh (9800-9fffh) ... wave memory access + w_wave_ce <= '1' when( req = '1' and ff_req_dl = '0' )else '0'; + w_wave_we <= wrt when( req = '1' and ff_req_dl = '0' )else '0'; + ack <= ff_req_dl; + + ---------------------------------------------------------------- + -- tone generator + ---------------------------------------------------------------- + process(clk21m, reset) + variable ff_cnt_ch_a : std_logic_vector( 11 downto 0 ); + variable ff_cnt_ch_b : std_logic_vector( 11 downto 0 ); + variable ff_cnt_ch_c : std_logic_vector( 11 downto 0 ); + variable ff_cnt_ch_d : std_logic_vector( 11 downto 0 ); + variable ff_cnt_ch_e : std_logic_vector( 11 downto 0 ); + begin + if (rising_edge(clk21m)) then + if (reset = '1') then + ff_cnt_ch_a := (others => '0'); + ff_cnt_ch_b := (others => '0'); + ff_cnt_ch_c := (others => '0'); + ff_cnt_ch_d := (others => '0'); + ff_cnt_ch_e := (others => '0'); + + ff_ptr_ch_a <= (others => '0'); + ff_ptr_ch_b <= (others => '0'); + ff_ptr_ch_c <= (others => '0'); + ff_ptr_ch_d <= (others => '0'); + ff_ptr_ch_e <= (others => '0'); + else + if (clkena = '1') then + + if (reg_freq_ch_a(11 downto 3) = "000000000" or ff_rst_ch_a = '1') then + ff_ptr_ch_a <= "00000"; + ff_cnt_ch_a := reg_freq_ch_a; + elsif (ff_cnt_ch_a = x"000") then + ff_ptr_ch_a <= ff_ptr_ch_a + 1; + ff_cnt_ch_a := reg_freq_ch_a; + else + ff_cnt_ch_a := ff_cnt_ch_a - 1; + end if; + + if (reg_freq_ch_b(11 downto 3) = "000000000" or ff_rst_ch_b = '1') then + ff_ptr_ch_b <= "00000"; + ff_cnt_ch_b := reg_freq_ch_b; + elsif (ff_cnt_ch_b = x"000") then + ff_ptr_ch_b <= ff_ptr_ch_b + 1; + ff_cnt_ch_b := reg_freq_ch_b; + else + ff_cnt_ch_b := ff_cnt_ch_b - 1; + end if; + + if (reg_freq_ch_c(11 downto 3) = "000000000" or ff_rst_ch_c = '1') then + ff_ptr_ch_c <= "00000"; + ff_cnt_ch_c := reg_freq_ch_c; + elsif (ff_cnt_ch_c = x"000") then + ff_ptr_ch_c <= ff_ptr_ch_c + 1; + ff_cnt_ch_c := reg_freq_ch_c; + else + ff_cnt_ch_c := ff_cnt_ch_c - 1; + end if; + + if (reg_freq_ch_d(11 downto 3) = "000000000" or ff_rst_ch_d = '1') then + ff_ptr_ch_d <= "00000"; + ff_cnt_ch_d := reg_freq_ch_d; + elsif (ff_cnt_ch_d = x"000") then + ff_ptr_ch_d <= ff_ptr_ch_d + 1; + ff_cnt_ch_d := reg_freq_ch_d; + else + ff_cnt_ch_d := ff_cnt_ch_d - 1; + end if; + + if (reg_freq_ch_e(11 downto 3) = "000000000" or ff_rst_ch_e = '1') then + ff_ptr_ch_e <= "00000"; + ff_cnt_ch_e := reg_freq_ch_e; + elsif (ff_cnt_ch_e = x"000") then + ff_ptr_ch_e <= ff_ptr_ch_e + 1; + ff_cnt_ch_e := reg_freq_ch_e; + else + ff_cnt_ch_e := ff_cnt_ch_e - 1; + end if; + + end if; + end if; + end if; + end process; + + ---------------------------------------------------------------- + -- wave memory control + ---------------------------------------------------------------- + w_wave_adr <= adr when( w_wave_ce = '1' )else + ("000" & ff_ptr_ch_a) when( ff_ch_num = "000" )else + ("001" & ff_ptr_ch_b) when( ff_ch_num = "001" )else + ("010" & ff_ptr_ch_c) when( ff_ch_num = "010" )else + ("011" & ff_ptr_ch_d) when( ff_ch_num = "011" )else + ("100" & ff_ptr_ch_e); + + wavemem : work.ram + port map( + adr => w_wave_adr , + clk => clk21m , + we => w_wave_we , + dbo => dbo , + dbi => ram_dbi + ); + + -- wave memory read + process( reset, clk21m ) + begin + if( rising_edge(clk21m) )then + if( reset = '1' )then + dbi <= (others => '1'); + else + -- mapped i/o port access on b800-bfffh (9800-9fffh) ... wave memory read data + if( ff_wave_ce = '1' )then + dbi <= ram_dbi; + end if; + end if; + end if; + end process; + + ---------------------------------------------------------------- + -- delay signal + ---------------------------------------------------------------- + process( reset, clk21m ) + begin + if( rising_edge(clk21m) ) then + if( reset = '1' )then + ff_wave_ce <= '0'; + ff_wave_ce_dl <= '0'; + ff_wave_dat <= (others => '0'); + ff_ch_num_dl <= (others => '0'); + else + ff_wave_ce <= w_wave_ce; + ff_wave_ce_dl <= ff_wave_ce; + ff_wave_dat <= ram_dbi; + ff_ch_num_dl <= ff_ch_num; + end if; + end if; + end process; + + ---------------------------------------------------------------- + -- mixer control + ---------------------------------------------------------------- + with ff_ch_num_dl select w_ch_dec <= + "00001" when "001", + "00010" when "010", + "00100" when "011", + "01000" when "100", + "10000" when "101", + "00000" when others; + + w_ch_bit <= (w_ch_dec(0) and reg_ch_sel(0)) or + (w_ch_dec(1) and reg_ch_sel(1)) or + (w_ch_dec(2) and reg_ch_sel(2)) or + (w_ch_dec(3) and reg_ch_sel(3)) or + (w_ch_dec(4) and reg_ch_sel(4)); + + w_ch_mask <= (others => w_ch_bit); + + with ff_ch_num_dl select w_ch_vol <= + reg_vol_ch_a when "001", + reg_vol_ch_b when "010", + reg_vol_ch_c when "011", + reg_vol_ch_d when "100", + reg_vol_ch_e when "101", + (others => '0') when others; + + w_wave <= (w_ch_mask and ff_wave_dat); -- 8bit ��̕␔ + + u_mul: work.scc_wave_mul + port map ( + a => w_wave , -- 8bit ��̕␔ + b => w_ch_vol , -- 4bit �o�C�i���i���������j + c => w_mul -- 12bit ��̕␔ + ); + + -- ------------------------------------------------------------- + -- ff_ch_num X 0 X 1 X 2 X 3 X 4 X 5 X 0 + -- ff_ch_num_dl X 0 X 1 X 2 X 3 X 4 X 5 X 0 + -- w_wave_adr X chA X chB X chC X chD X chE + -- ram_dbi X chA X chB X chC X chD X chE + -- ff_wave_dat X chA X chB X chC X chD X chE + -- ff_mix X a X ab X a-c X a-d X a-e X 0 + -- wave X a-e + -- ------------------------------------------------------------- + -- w_wave_ce X 0 X 1 X 0 + -- ff_wave_ce X 0 X 1 X 0 + -- ff_wave_ce_dl X 0 X 1 X 0 + -- + -- ff_ch_num X 0 X 1 X 2 X 3 X 4 X 5 X 0 + -- ff_ch_num_dl X 0 X 1 X 2 X 3 X 4 X 5 X 0 + -- w_wave_adr X chA X chB X chC X chD X chE + -- ram_dbi X chA X chB X chC X chD X chE + -- ff_wave_dat X chA X chB X chC X chD X chE + -- ff_mix X a X ab X a-c X a-d X a-e X 0 + -- wave X a-e + -- ------------------------------------------------------------- + -- w_wave_ce X 0 X 1 X 0 + -- ff_wave_ce X 0 X 1 X 0 + -- ff_wave_ce_dl X 0 X 1 X 0 X + -- ~~~~~ + -- ff_ch_num X 0 X 1 X 2 X 3 X 4 X 5 X 0 X 1 + -- ff_ch_num_dl X 0 X 1 X 2 X 3 X 4 X 5 X 0 X 1 X 2 X + -- ~~~~~~~~~~~ + -- w_wave_adr X chA X chB X chC X chD X chE X chA X chB X chC X + -- ram_dbi X chA X chB X chC X chD X chE X chA X chB X chC X + -- ff_wave_dat X chA X chB X chC X chD X chE X chA X chB X chC X + -- ff_mix X a X ab X a-c X a-d X a-e X 0 X a X ab X + -- wave X a-e + -- ~~~~~ + -- wave �́Aff_wave_ce_dl = 0 and ff_ch_num_dl = 0 �̂Ƃ� ff_mix ����荞�� + ---------------------------------------------------------------- + process( reset, clk21m ) + begin + if( rising_edge(clk21m) )then + if( reset = '1' )then + ff_ch_num <= "000"; + else + if( ff_wave_ce = '0' )then + if( ff_ch_num = "101" )then + ff_ch_num <= "000"; + else + ff_ch_num <= ff_ch_num + 1; + end if; + end if; + end if; + end if; + end process; + + -- mixer + process( reset, clk21m ) + begin + if( rising_edge(clk21m) )then + if( reset = '1' )then + ff_mix <= (others => '0'); + else + if( ff_wave_ce_dl = '0' )then + if( ff_ch_num_dl = "000" )then + ff_mix <= (others => '0'); + else + ff_mix <= (w_mul(11) & w_mul(11) & w_mul(11) & w_mul) + ff_mix; -- 15bit ��̕␔ + end if; + end if; + end if; + end if; + end process; + + -- wave out + process( reset, clk21m ) + begin + if( rising_edge(clk21m) )then + if( reset = '1' )then + ff_wave <= (others => '0'); + else + if( ff_wave_ce_dl = '0' )then + if( ff_ch_num_dl = "000" )then + ff_wave <= ff_mix; -- 15bit ��̕␔ + else + -- hold + end if; + end if; + end if; + end if; + end process; + + wave <= ff_wave; +end rtl; diff --git a/rtl/cart/vy0010.v b/rtl/cart/vy0010.v index e1d63d7..7ca6e5a 100644 --- a/rtl/cart/vy0010.v +++ b/rtl/cart/vy0010.v @@ -1,154 +1,154 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX Compatible Gateware IP Core -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -module vy0010 - ( - input clk, - input clk_en, - input reset, - input [15:0] addr, - input [7:0] d_from_cpu, - output [7:0] d_to_cpu, - input stlsl_n, - input wr_n, - input rd_n, - input CS1_n, - input img_mounted, - input [31:0] img_size, - input img_wp, - output [31:0] sd_lba, - output sd_rd, - output sd_wr, - input sd_ack, - input [8:0] sd_buff_addr, - input [7:0] sd_buff_dout, - output [7:0] sd_buff_din, - input sd_buff_wr, - input sd_din_strobe - ); - - reg side_select, m_on, in_use = 1'b0; - reg [1:0] ds = 2'b0; - reg type1, type0 = 1'b1; - - wire ic4 = ~&{addr[13:3], ~stlsl_n}; - wire r7ffc = ~ic4 && addr[2] && addr[1:0] == 2'b00; - wire r7ffd = ~ic4 && addr[2] && addr[1:0] == 2'b01; - wire r7fff = ~ic4 && addr[2] && addr[1:0] == 2'b11; - wire romce = addr[15:14] == 2'b01 && ic4 && ~stlsl_n && ~CS1_n; - wire csfdc = ~ic4 && ~addr[2]; - - assign d_to_cpu = romce ? d_from_rom : - r7ffc && ~rd_n ? {7'b1111111, ~side_select} : - r7ffd && ~rd_n ? {m_on, in_use, 4'b1110, ~ds[1], ds[0]} : - r7fff && ~rd_n ? {~drq, ~intrq, type1, type0, 4'b1111} : - csfdc && ~rd_n ? d_from_wd : 8'hFF; - - wire wr7ffc = r7ffc & ~wr_n; - always @(posedge reset, posedge wr7ffc) begin - if (reset) begin - side_select <= 1'b0; - end - else begin - if (~stlsl_n) begin - side_select <= d_from_cpu[0]; - end - end - end - - wire wr7ffd = r7ffd & ~wr_n; - always @(posedge reset, posedge wr7ffd) begin - if (reset) begin - m_on <= 1'b0; - in_use <= 1'b0; - ds <= 2'b00; - end - else begin - if (~stlsl_n) begin - ds[0] <= d_from_cpu[0]; - ds[1] <= ~d_from_cpu[1]; - in_use <= d_from_cpu[6]; - m_on <= d_from_cpu[7]; - end - end - end - - wire [7:0] d_from_wd; - wire drq, intrq; - reg img_load; - - always @(posedge clk) begin - if(img_mounted) begin - img_load <= |img_size; - end - end - - wire fdd_ready = img_load & ~ds[0] & ds[1]; - - wd1793 #(.RWMODE(1), .EDSK(0)) fdc - ( - .clk_sys ( clk ), - .ce ( clk_en ), - .reset ( reset ), - .io_en ( csfdc ), - .rd ( ~rd_n ), - .wr ( ~wr_n ), - .addr ( addr[1:0] ), - .din ( d_from_cpu ), - .dout ( d_from_wd ), - .drq ( drq ), - .intrq ( intrq ), - .ready ( fdd_ready ), - .layout ( 1'b0 ), - .size_code ( 3'h2 ), - .side ( side_select ), - .img_mounted ( img_mounted ), - .wp ( img_wp ), - .img_size ( img_size[19:0] ), - .sd_lba ( sd_lba ), - .sd_rd ( sd_rd ), - .sd_wr ( sd_wr ), - .sd_ack ( sd_ack ), - .sd_buff_addr ( sd_buff_addr ), - .sd_buff_dout ( sd_buff_dout ), - .sd_buff_din ( sd_buff_din ), - .sd_buff_wr ( sd_buff_wr ), - .input_active ( 1'b0 ), - .input_addr ( 20'h0 ), - .input_data ( 8'h0 ), - .input_wr ( 1'b0 ), - .buff_din ( 8'h0 ) - ); - - wire [7:0] d_from_rom; - - spram #(.addr_width(14), .mem_init_file("rom/vy0010.mif"), .mem_name("VY0010ROM")) vy0010_rom - ( - .clock ( clk ), - .address ( addr[13:0] ), - .wren ( 0 ), - .q ( d_from_rom ) - ); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX Compatible Gateware IP Core +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +module vy0010 + ( + input clk, + input clk_en, + input reset, + input [15:0] addr, + input [7:0] d_from_cpu, + output [7:0] d_to_cpu, + input stlsl_n, + input wr_n, + input rd_n, + input CS1_n, + input img_mounted, + input [31:0] img_size, + input img_wp, + output [31:0] sd_lba, + output sd_rd, + output sd_wr, + input sd_ack, + input [8:0] sd_buff_addr, + input [7:0] sd_buff_dout, + output [7:0] sd_buff_din, + input sd_buff_wr, + input sd_din_strobe + ); + + reg side_select, m_on, in_use = 1'b0; + reg [1:0] ds = 2'b0; + reg type1, type0 = 1'b1; + + wire ic4 = ~&{addr[13:3], ~stlsl_n}; + wire r7ffc = ~ic4 && addr[2] && addr[1:0] == 2'b00; + wire r7ffd = ~ic4 && addr[2] && addr[1:0] == 2'b01; + wire r7fff = ~ic4 && addr[2] && addr[1:0] == 2'b11; + wire romce = addr[15:14] == 2'b01 && ic4 && ~stlsl_n && ~CS1_n; + wire csfdc = ~ic4 && ~addr[2]; + + assign d_to_cpu = romce ? d_from_rom : + r7ffc && ~rd_n ? {7'b1111111, ~side_select} : + r7ffd && ~rd_n ? {m_on, in_use, 4'b1110, ~ds[1], ds[0]} : + r7fff && ~rd_n ? {~drq, ~intrq, type1, type0, 4'b1111} : + csfdc && ~rd_n ? d_from_wd : 8'hFF; + + wire wr7ffc = r7ffc & ~wr_n; + always @(posedge reset, posedge wr7ffc) begin + if (reset) begin + side_select <= 1'b0; + end + else begin + if (~stlsl_n) begin + side_select <= d_from_cpu[0]; + end + end + end + + wire wr7ffd = r7ffd & ~wr_n; + always @(posedge reset, posedge wr7ffd) begin + if (reset) begin + m_on <= 1'b0; + in_use <= 1'b0; + ds <= 2'b00; + end + else begin + if (~stlsl_n) begin + ds[0] <= d_from_cpu[0]; + ds[1] <= ~d_from_cpu[1]; + in_use <= d_from_cpu[6]; + m_on <= d_from_cpu[7]; + end + end + end + + wire [7:0] d_from_wd; + wire drq, intrq; + reg img_load; + + always @(posedge clk) begin + if(img_mounted) begin + img_load <= |img_size; + end + end + + wire fdd_ready = img_load & ~ds[0] & ds[1]; + + wd1793 #(.RWMODE(1), .EDSK(0)) fdc + ( + .clk_sys ( clk ), + .ce ( clk_en ), + .reset ( reset ), + .io_en ( csfdc ), + .rd ( ~rd_n ), + .wr ( ~wr_n ), + .addr ( addr[1:0] ), + .din ( d_from_cpu ), + .dout ( d_from_wd ), + .drq ( drq ), + .intrq ( intrq ), + .ready ( fdd_ready ), + .layout ( 1'b0 ), + .size_code ( 3'h2 ), + .side ( side_select ), + .img_mounted ( img_mounted ), + .wp ( img_wp ), + .img_size ( img_size[19:0] ), + .sd_lba ( sd_lba ), + .sd_rd ( sd_rd ), + .sd_wr ( sd_wr ), + .sd_ack ( sd_ack ), + .sd_buff_addr ( sd_buff_addr ), + .sd_buff_dout ( sd_buff_dout ), + .sd_buff_din ( sd_buff_din ), + .sd_buff_wr ( sd_buff_wr ), + .input_active ( 1'b0 ), + .input_addr ( 20'h0 ), + .input_data ( 8'h0 ), + .input_wr ( 1'b0 ), + .buff_din ( 8'h0 ) + ); + + wire [7:0] d_from_rom; + + spram #(.addr_width(14), .mem_init_file("rom/vy0010.mif"), .mem_name("VY0010ROM")) vy0010_rom + ( + .clock ( clk ), + .address ( addr[13:0] ), + .wren ( 0 ), + .q ( d_from_rom ) + ); + +endmodule diff --git a/rtl/cart/wd1793.sv b/rtl/cart/wd1793.sv index b32a94c..a1d87bd 100644 --- a/rtl/cart/wd1793.sv +++ b/rtl/cart/wd1793.sv @@ -1,914 +1,914 @@ - -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// WD1793, WD1772, WD1773 Floppy Disk Controller (With Write Capability) -// -// Copyright (c) 2016, Alexey Melnikov -// Copyright (C) 2007-2008 Viacheslav Slavinsky -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -module wd1793 #(parameter RWMODE=0, EDSK=1) -( - input clk_sys, // sys clock - input ce, // ce at CPU clock rate - input reset, // async reset - input io_en, - input rd, // i/o read - input wr, // i/o write - input [1:0] addr, // i/o port addr - input [7:0] din, // i/o data in - output [7:0] dout, // i/o data out - output drq, // DMA request - output intrq, - output busy, - - input wp, // write protect - - input [2:0] size_code, - input layout, // 0 = Track-Side-Sector, 1 - Side-Track-Sector - input side, - input ready, - - // SD access (RWMODE == 1) - input img_mounted, // signaling that new image has been mounted - input [19:0] img_size, // size of image in bytes. 1MB MAX! - output prepare, - output[31:0] sd_lba, - output reg sd_rd, - output reg sd_wr, - input sd_ack, - input [8:0] sd_buff_addr, - input [7:0] sd_buff_dout, - output [7:0] sd_buff_din, - input sd_buff_wr, - - // RAM access (RWMODE == 0) - input input_active, - input [19:0] input_addr, - input [7:0] input_data, - input input_wr, - output[19:0] buff_addr, // buffer RAM address - output buff_read, // buffer RAM read enable - input [7:0] buff_din // buffer RAM data input -); - -// Possible track configs: -// 0: 26 x 128 = 3.3KB -// 1: 16 x 256 = 4.0KB -// 2: 9 x 512 = 4.5KB -// 3: 5 x 1024 = 5.0KB -// 4: 10 x 512 = 5.0KB - -assign dout = q; -assign drq = s_drq; -assign busy = s_busy; -assign intrq = s_intrq; -assign sd_lba = scan_active ? scan_addr[19:9] : buff_a[19:9] + sd_block; -assign prepare = EDSK ? scan_active : img_mounted; -assign buff_addr = {buff_a[19:9], 9'd0} + byte_addr; -assign buff_read = ((addr == A_DATA) && buff_rd); - -reg [7:0] sectors_per_track, edsk_spt = 0; -wire [10:0] sector_size = 11'd128 << wd_size_code; -reg [10:0] byte_addr; -reg [19:0] buff_a; -reg [1:0] wd_size_code; - -wire [7:0] buff_dout; -reg [1:0] sd_block = 0; -reg format; -generate - if(RWMODE) begin - wd1793_dpram sbuf - ( - .clock(clk_sys), - - .address_a({sd_block, sd_buff_addr}), - .data_a(sd_buff_dout), - .wren_a(sd_buff_wr & sd_ack), - .q_a(sd_buff_din), - - .address_b(scan_active ? {2'b00, scan_addr[8:0]} : byte_addr), - .data_b(format ? 8'd0 : din), - .wren_b(wre & buff_wr & (addr == A_DATA) & ~scan_active), - .q_b(buff_dout) - ); - reg buff_wr; - end else begin - assign buff_dout = 0; - assign sd_buff_din = 0; - end -endgenerate - -reg var_size = 0; -reg [19:0] disk_size; -reg layout_r; -wire [19:0] hs = (layout_r & side) ? disk_size >> 1 : 20'd0; -wire [7:0] dts = {disk_track[6:0], side} >> layout_r; -always @(posedge clk_sys) begin - case({var_size,size_code}) - 0: buff_a <= hs + {{1'b0, dts, 4'b0000} + {dts, 3'b000} + {dts, 1'b0} + wdreg_sector - 1'd1, 7'd0}; - 1: buff_a <= hs + {{dts, 4'b0000} + wdreg_sector - 1'd1, 8'd0}; - 2: buff_a <= hs + {{dts, 3'b000} + dts + wdreg_sector - 1'd1, 9'd0}; - 3: buff_a <= hs + {{dts, 2'b00} + dts + wdreg_sector - 1'd1, 10'd0}; - 4: buff_a <= hs + {{dts, 3'b000} +{dts, 1'b0} + wdreg_sector - 1'd1, 9'd0}; - default: buff_a <= edsk_offset; - endcase - case({var_size,size_code}) - 0: sectors_per_track <= 26; - 1: sectors_per_track <= 16; - 2: sectors_per_track <= 9; - 3: sectors_per_track <= 5; - 4: sectors_per_track <= 10; - default: sectors_per_track <= edsk_spt; - endcase - case({var_size,size_code}) - 0: wd_size_code <= 0; - 1: wd_size_code <= 1; - 2: wd_size_code <= 2; - 3: wd_size_code <= 3; - 4: wd_size_code <= 2; - default: wd_size_code <= edsk_sizecode; - endcase -end - -reg [1:0] blk_size; -always @* begin - case(wd_size_code) - 0: blk_size = 0; - 1: blk_size = 0; - 2: blk_size = buff_a[8:0] ? 2'd1 : 2'd0; - 3: blk_size = buff_a[8:0] ? 2'd2 : 2'd1; - endcase -end - - -// Register addresses -localparam A_COMMAND = 0; -localparam A_STATUS = 0; -localparam A_TRACK = 1; -localparam A_SECTOR = 2; -localparam A_DATA = 3; - -// States -typedef enum -{ - STATE_IDLE, - - STATE_SEARCH, - STATE_SEARCH_1, - - STATE_WAIT_READ, - STATE_WAIT_READ_1, - STATE_WAIT_READ_2, - - STATE_READ, - STATE_READ_1, - STATE_READ_2, - STATE_READ_3, - - STATE_WAIT_WRITE, - STATE_WAIT_WRITE_1, - STATE_WAIT_WRITE_2, - - STATE_WRITE, - STATE_WRITE_1, - STATE_WRITE_2, - - STATE_ABORT, - STATE_WAIT, - STATE_WAIT_2, - STATE_ENDCOMMAND -} io_state_t; - - -// common status bits -wire s_readonly = (wp | !RWMODE); -reg s_crcerr; -reg s_headloaded, s_seekerr, s_index; // mode 1 -reg s_lostdata, s_wrfault; // mode 2,3 - -// Command mode 0/1 for status register -reg cmd_mode; - -// allow write protect flag -reg s_wpe; - -// DRQ/BUSY are always going together -reg [1:0] s_drq_busy; -wire s_drq = s_drq_busy[1]; -wire s_busy = s_drq_busy[0]; -reg s_intrq; - -reg [7:0] wdreg_track; -reg [7:0] wdreg_sector; -reg [7:0] wdreg_data; -wire [7:0] wdreg_status = cmd_mode == 0 ? - {~ready, s_readonly & s_wpe, s_headloaded, s_seekerr | ~ready, s_crcerr, !disk_track, s_index, s_busy}: - {~ready, s_readonly & s_wpe, s_wrfault, s_seekerr | ~ready, s_crcerr, s_lostdata, s_drq, s_busy}; - -reg [7:0] read_addr[6]; -reg [7:0] q; -always @* begin - case (addr) - A_STATUS: q = wdreg_status; - A_TRACK: q = wdreg_track; - A_SECTOR: q = wdreg_sector; - A_DATA: q = (state == STATE_IDLE) ? wdreg_data : buff_rd ? (RWMODE ? buff_dout : buff_din) : read_addr[byte_addr[2:0]]; - endcase -end - -reg buff_rd; -reg step_direction; // last step direction - -reg [7:0] disk_track; // "real" heads position -reg [10:0] data_length; // this many bytes to transfer during read/write ops -io_state_t state = STATE_IDLE; - -// Reusable expressions -wire [7:0] next_track = (din[6] ? din[5] : step_direction) ? disk_track - 1'd1 : disk_track + 1'd1; -wire [10:0] next_length = data_length - 1'b1; - -// Watchdog -reg watchdog_set; -wire watchdog_bark = (wd_timer == 0); -reg [15:0] wd_timer; -always @(posedge clk_sys) begin - if(ce) begin - if(watchdog_set) wd_timer <= 4096; - else if(wd_timer != 0) wd_timer <= wd_timer - 1'b1; - end -end - -always @(posedge clk_sys) begin - integer cnt; - if(ce) begin - if(ready) begin - if(cnt) cnt <= cnt - 1; - else cnt <= 35000; - end else cnt <= 0; - s_index <= (cnt < 100); - end -end - -wire rde = rd & io_en; -wire wre = wr & io_en; -always @(posedge clk_sys) begin - reg old_wr, old_rd; - - reg [2:0] cur_addr; - reg read_data; - reg write_data; - reg rw_type; - integer wait_time; - reg [3:0] read_timer; - reg [9:0] seektimer; - reg [7:0] ra_sector; - reg multisector; - reg write; - reg [5:0] ack; - reg sd_busy; - reg old_mounted; - reg [3:0] scan_state; - reg [1:0] scan_cnt; - reg [1:0] blk_max; - - if(RWMODE) begin - old_mounted <= img_mounted; - if(old_mounted && ~img_mounted) begin - if(EDSK) begin - scan_active<= 1; - scan_addr <= 0; - scan_state <= 0; - scan_wr <= 0; - sd_block <= 0; - end - disk_size <= img_size[19:0]; - layout_r <= layout; - end - end else begin - scan_active <= input_active; - scan_addr <= input_addr; - scan_wr <= input_wr; - if(scan_active & ~input_active) begin - disk_size <= input_addr + 1'd1; - layout_r <= layout; - end - end - - if(reset & ~scan_active) begin - read_data <= 0; - write_data <= 0; - multisector <= 0; - step_direction <= 0; - disk_track <= 0; - wdreg_track <= 0; - wdreg_sector <= 0; - wdreg_data <= 0; - data_length <= 0; - byte_addr <=0; - buff_rd <= 0; - if(RWMODE) buff_wr <= 0; - state <= STATE_IDLE; - cmd_mode <= 0; - s_wpe <= 1; - {s_headloaded, s_seekerr, s_crcerr, s_intrq} <= 0; - {s_wrfault, s_lostdata} <= 0; - s_drq_busy <= 0; - watchdog_set <= 0; - seektimer <= 'h3FF; - {ack, sd_wr, sd_rd, sd_busy} <= 0; - ra_sector <= 1; - end else if(ce) begin - - ack <= {ack[4:0], sd_ack}; - if(ack[5:4] == 'b01) {sd_rd,sd_wr} <= 0; - if(ack[5:4] == 'b10) sd_busy <= 0; - - if(RWMODE & scan_active) begin - if(scan_addr >= img_size) scan_active <= 0; - else begin - case(scan_state) - 0: begin - sd_rd <= 1; - sd_busy <= 1; - scan_wr <= 0; - scan_state <= 1; - end - 1: if(!sd_busy) begin - scan_wr <= 1; - scan_cnt <= 1; - scan_state <= 2; - end - 2: begin - scan_cnt <= scan_cnt + 1'd1; - if(!scan_cnt) begin - scan_wr <= ~scan_wr; - if(scan_wr) begin - scan_addr <= scan_addr + 1'b1; - if(&scan_addr[8:0]) begin - scan_active <= var_size; - scan_state <= 0; - end - end - end - end - endcase - end - end - - old_wr <=wre; - old_rd <=rde; - - if((!old_rd && rde) || (!old_wr && wre)) cur_addr <= addr; - - //Register read operations - if(old_rd && !rde && (cur_addr == A_STATUS)) s_intrq <= 0; - - //end of data reading - if(old_rd && !rde && (cur_addr == A_DATA)) read_data <=1; - - //end of data writing - if(old_wr && !wre && (cur_addr == A_DATA)) write_data <=1; - - case (state) - /* Idle state or buffer to host transfer */ - STATE_IDLE:; // do nothing - - STATE_SEARCH: - begin - if(!ready) begin - s_seekerr <= 1; - state <= STATE_ENDCOMMAND; - end else begin - seektimer <= seektimer - 1'b1; - if(!seektimer) begin - byte_addr <= 0; - if(var_size) begin - if(~format) edsk_addr <= edsk_start; - if(EDSK) spt_addr <= (side ? spt_size>>1 : 8'd0) + disk_track; - state <= STATE_SEARCH_1; - end else begin - if(!wdreg_sector || (wdreg_sector > sectors_per_track)) begin - if(~format) s_seekerr <= 1; - state <= STATE_ENDCOMMAND; - end else begin - state <= rw_type ? STATE_WAIT_READ : STATE_READ; - end - end - end - end - end - STATE_SEARCH_1: - begin - if(rw_type & (edsk_track == disk_track) & - (edsk_side == side) & - (format | (edsk_sector == wdreg_sector))) begin - state <= STATE_WAIT_READ; - end - else - if(~rw_type & (edsk_track == disk_track) & - (edsk_side == side)) begin - read_addr[0] <= edsk_trackf; - read_addr[1] <= edsk_sidef; - read_addr[2] <= edsk_sector; - read_addr[3] <= edsk_sizecode; - state <= STATE_READ; - end - else - if(edsk_next == edsk_start) begin - if(~format) s_seekerr <= 1; - state <= STATE_ENDCOMMAND; - end - else - begin - edsk_addr <= edsk_next; - end - end - // read before write in case if sector not aligned or smaller than 512b - STATE_WAIT_READ: - begin - data_length <= sector_size; - byte_addr <= buff_a[8:0]; - blk_max <= blk_size; - sd_block <= 0; - state <= RWMODE ? STATE_WAIT_READ_1 : write ? STATE_WRITE : STATE_READ; - end - STATE_WAIT_READ_1: - begin - sd_busy <= 1; - sd_rd <= 1; - state <= STATE_WAIT_READ_2; - end - STATE_WAIT_READ_2: - begin - if(!sd_busy) begin - sd_block <= sd_block + 1'd1; - state <= write ? STATE_WRITE : STATE_READ; - if(sd_block < blk_max) state <= STATE_WAIT_READ_1; - end - end - - STATE_READ: - begin - watchdog_set <= 1; - read_timer <= 15; - state <= STATE_READ_1; - end - STATE_READ_1: - begin - read_timer <= read_timer - 1'b1; - if(!read_timer) begin - read_data <= 0; - watchdog_set <= 0; - s_lostdata <= 0; - s_drq_busy <= 2'b11; - state <= STATE_READ_2; - end - end - STATE_READ_2: - begin - if(watchdog_bark | (read_data & s_drq)) begin - // reset drq until next byte is read, nothing is lost - s_drq_busy <= 2'b01; - s_lostdata <= watchdog_bark; - - if(next_length == 0) begin - // either read the next sector, or stop if this is track end - if(multisector) begin - wdreg_sector <= wdreg_sector + 1'b1; - state <= STATE_SEARCH; - end else begin - state <= STATE_ENDCOMMAND; - end - end else begin - byte_addr <= byte_addr + 1'd1; - data_length <= next_length; - state <= STATE_READ; - end - end - end - - STATE_WAIT_WRITE: - begin - if(!ready) begin - s_wrfault <= 1; - state <= STATE_ENDCOMMAND; - end else begin - sd_block <= 0; - state <= STATE_WAIT_WRITE_1; - end - end - STATE_WAIT_WRITE_1: - begin - sd_busy <= 1; - sd_wr <= 1; - state <= STATE_WAIT_WRITE_2; - end - STATE_WAIT_WRITE_2: - begin - if(!sd_busy) begin - sd_block <= sd_block + 1'd1; - if(sd_block < blk_max) state <= STATE_WAIT_WRITE_1; - else begin - if(format && var_size && !edsk_next) begin - state <= STATE_ENDCOMMAND; - end else if(multisector) begin - edsk_addr <= edsk_next; - wdreg_sector <= wdreg_sector + 1'b1; - state <= STATE_SEARCH; - end else begin - state <= STATE_ENDCOMMAND; - end - end - end - end - STATE_WRITE: - begin - watchdog_set <= 1; - read_timer <= 15; - state <= STATE_WRITE_1; - end - STATE_WRITE_1: - begin - read_timer <= read_timer - 1'b1; - if(!read_timer) begin - write_data <= 0; - watchdog_set <= 0; - s_lostdata <= 0; - s_drq_busy <= 2'b11; - state <= STATE_WRITE_2; - end - end - STATE_WRITE_2: - begin - if(watchdog_bark | (write_data & s_drq)) begin - s_drq_busy <= 2'b01; - s_lostdata <= watchdog_bark; - - if(!next_length) state <= STATE_WAIT_WRITE; - else begin - byte_addr <= byte_addr + 1'd1; - data_length <= next_length; - state <= STATE_WRITE; - end - end - end - - // Abort current operation ($D0) - STATE_ABORT: - begin - data_length <= 0; - {s_wrfault,s_seekerr,s_crcerr,s_lostdata} <= 0; - state <= STATE_ENDCOMMAND; - end - - STATE_WAIT: - begin - wait_time <= 4000; - state <= STATE_WAIT_2; - end - STATE_WAIT_2: - begin - if(wait_time) wait_time <= wait_time - 1; - else state <= STATE_ENDCOMMAND; - end - - // End any command. - STATE_ENDCOMMAND: - begin - format <= 0; - buff_rd <= 0; - if(RWMODE) buff_wr <=0; - state <= STATE_IDLE; - s_drq_busy <= 2'b00; - seektimer <= 'h3FF; - s_intrq <= 1; - end - endcase - - /* Register write operations */ - if (!old_wr & wre) begin - case (addr) - A_COMMAND: - begin - s_intrq <= 0; - if((state == STATE_IDLE) | (din[7:4] == 'hD)) begin - cmd_mode <= din[7]; - s_wpe <= ~din[7]; - case (din[7:4]) - 'h0: // RESTORE - begin - // head load as specified, index, track0 - s_headloaded <= din[3]; - wdreg_track <= 0; - disk_track <= 0; - - // some programs like it when FDC gets busy for a while - s_drq_busy <= 2'b01; - state <= STATE_WAIT; - end - 'h1: // SEEK - begin - // set real track to datareg - disk_track <= wdreg_data; - s_headloaded <= din[3]; - - wdreg_track <= wdreg_data; - - // get busy - s_drq_busy <= 2'b01; - state <= STATE_WAIT; - end - 'h2, // STEP - 'h3, // STEP & UPDATE - 'h4, // STEP-IN - 'h5, // STEP-IN & UPDATE - 'h6, // STEP-OUT - 'h7: // STEP-OUT & UPDATE - begin - // if direction is specified, store it for the next time - if (din[6] == 1) step_direction <= din[5]; // 0: forward/in - - // perform step - disk_track <= next_track; - - // update TRACK register too if asked to - if (din[4]) wdreg_track <= next_track; - - s_headloaded <= din[3]; - - // some programs like it when FDC gets busy for a while - s_drq_busy <= 2'b01; - state <= STATE_WAIT; - end - 'h8, 'h9, // READ SECTORS - 'hA, 'hB: // WRITE SECTORS - begin - // seek data - // 5: 0: read, 1: write - // 4: m: 0: one sector, 1: until the track ends - // 3: S: SIDE - // 2: E: some 15ms delay - // 1: C: check side matching? - // 0: 0 - - s_drq_busy <= 2'b01; - {s_wrfault,s_seekerr,s_crcerr,s_lostdata} <= 0; - - {write,buff_rd} <= din[5] ? 2'b10 : 2'b01; - if(RWMODE) buff_wr <= din[5]; - - if(din[6]) wdreg_sector <= 1; - - format <= din[6]; - multisector <= din[4]; - rw_type <= 1; - write_data <= 0; - read_data <= 0; - edsk_start <= 0; - edsk_addr <= 0; - state <= STATE_SEARCH; - s_wpe <= din[5]; - - if(s_readonly & din[5]) begin - s_wrfault <= 1; - state <= STATE_WAIT; - end - end - 'hC: // READ ADDRESS - begin - // track, side, sector, sector size code, 2-byte checksum (crc?) - s_drq_busy <= 2'b01; - {s_wrfault,s_seekerr,s_crcerr,s_lostdata} <= 0; - - {write,buff_rd} <= 0; - if(RWMODE) buff_wr <=0; - - format <= 0; - multisector <= 0; - rw_type <= 0; - read_data <= 0; - edsk_start <= edsk_next; - data_length <= 6; - - read_addr[0] <= disk_track; - read_addr[1] <= {7'b0, side}; - read_addr[2] <= ra_sector; - read_addr[3] <= wd_size_code; - read_addr[4] <= 0; - read_addr[5] <= 0; - - if(ra_sector >= sectors_per_track) ra_sector <= 1; - else ra_sector <= ra_sector + 1'd1; - state <= STATE_SEARCH; - end - 'hD: // interrupt - begin - cmd_mode <= 0; - if(state != STATE_IDLE) state <= STATE_ABORT; - else {s_wrfault,s_seekerr,s_crcerr,s_lostdata, s_drq_busy} <= 0; - end - 'hF: // WRITE TRACK - begin - s_wpe <= din[5]; - {s_wrfault,s_seekerr,s_crcerr,s_lostdata} <= 0; - s_drq_busy <= 2'b01; - state <= STATE_WAIT; - end - 'hE: // READ TRACK - begin - {s_wrfault,s_crcerr,s_lostdata} <= 0; - s_seekerr <= 1; - s_drq_busy <= 2'b01; - state <= STATE_WAIT; - end - endcase - end - end - - A_TRACK: if (!s_busy) wdreg_track <= din; - A_SECTOR: if (!s_busy) {ra_sector, wdreg_sector} <= {din,din}; - A_DATA: wdreg_data <= din; - endcase - end - end -end - -reg scan_active = 0; -reg [19:0] scan_addr; -reg scan_wr; - -reg [1:0] edsk_sizecode = 0; // sector size: 0=128K, 1=256K, 2=512K, 3=1024K -reg edsk_side = 0; // Side number (0 or 1) -reg [6:0] edsk_track = 0; // Track number -reg [7:0] edsk_sector = 0; // Sector number 0..15 -reg [19:0] edsk_offset = 0; -reg [7:0] edsk_trackf = 0, edsk_sidef = 0; - -reg [10:0] edsk_addr, edsk_start; - -reg [10:0] edsk_size = 0; -wire[10:0] edsk_next = ((edsk_addr + 1'd1) >= edsk_size) ? 11'd0 : edsk_addr + 1'd1; - -reg [7:0] spt_size = 0; - -generate - if(EDSK) begin - wire [7:0] scan_data = RWMODE ? buff_dout : input_data; - reg [53:0] edsk[1992]; - reg [7:0] spt[166]; - - reg [7:0] spt_addr; - always @(posedge clk_sys) begin - {edsk_track,edsk_side,edsk_trackf,edsk_sidef,edsk_sector,edsk_sizecode,edsk_offset} <= edsk[edsk_addr]; - edsk_spt <= spt[spt_addr]; - end - - reg [7:0] tpos; - reg [7:0] tsize; - reg [7:0] tsizes[166]; - always @(posedge clk_sys) tsize <= tsizes[tpos]; - - wire[127:0] edsk_sig = "EXTENDED CPC DSK"; - wire[127:0] sig_pos = edsk_sig >> (8'd120-(scan_addr[7:0]<<3)); - - always @(posedge clk_sys) begin - reg old_active, old_wr; - reg [13:0] hdr_pos, bcnt; - reg [7:0] idStatus; - reg [6:0] track; - reg side; - reg [7:0] sector; - reg [1:0] sizecode; - reg [7:0] crc1; - reg [7:0] crc2; - reg [7:0] sectors; - reg [15:0] track_size, track_pos; - reg [19:0] offset, offset1; - reg [7:0] size_lo; - reg [10:0] secpos; - reg [7:0] trackf, sidef; - - old_active <= scan_active; - if(scan_active & ~old_active) begin - edsk_size <=0; - spt_size <=0; - track_pos <=0; - var_size <=1; - end - - old_wr <= scan_wr; - if(scan_wr & ~old_wr & scan_active) begin - if((scan_addr[19:0] < 16) & (sig_pos[7:0] != scan_data)) var_size <= 0; - if(var_size) begin - if( scan_addr == 48) spt_size <= scan_data; else - if((scan_addr == 49) & (scan_data == 2)) spt_size <= spt_size << 1; else - if( scan_addr == 52) begin - track_size <= {scan_data, 8'd0}; - track_pos <= 0; - tpos <= 1; - end else - if((scan_addr > 52) & (scan_addr < 218)) begin - tsizes[scan_addr - 52] <= scan_data; - spt[scan_addr - 52] <= 0; - end else - if((scan_addr >= 256) && track_size) begin - track_pos <= track_pos + 1'd1; - case(track_pos) - 00: offset <= scan_addr + 9'd256; - 16: track <= scan_data[6:0]; - 17: side <= scan_data[0]; - 21: sectors <= scan_data; - 22: spt[(side ? (spt_size >> 1) : 8'd0) + track] <= sectors; - default: - if((track_pos >= 24) && sectors) begin - case(track_pos[2:0]) - 0: begin - trackf <= scan_data; - secpos <= edsk_size; - offset1 <= offset; - end - 1: sidef <= scan_data; - 2: sector <= scan_data; - 3: sizecode<= scan_data[1:0]; - 6: size_lo <= scan_data; - 7: begin - if({scan_data, size_lo}) begin - edsk[secpos] <= {track,side,trackf,sidef,sector,sizecode,offset1}; - edsk_size <= edsk_size + 1'd1; - offset <= offset + {scan_data, size_lo}; - end - sectors <= sectors - 1'd1; - end - default:; - endcase - end - endcase - if(track_pos >= (track_size - 1'd1)) begin - track_size <= {tsize, 8'd0}; - track_pos <= 0; - tpos <= tpos + 1'd1; - end - end - end - end - end - end -endgenerate - -endmodule - -module wd1793_dpram #(parameter DATAWIDTH=8, ADDRWIDTH=11) -( - input clock, - - input [ADDRWIDTH-1:0] address_a, - input [DATAWIDTH-1:0] data_a, - input wren_a, - output reg [DATAWIDTH-1:0] q_a, - - input [ADDRWIDTH-1:0] address_b, - input [DATAWIDTH-1:0] data_b, - input wren_b, - output reg [DATAWIDTH-1:0] q_b -); - -logic [DATAWIDTH-1:0] ram[0:(1< +// Copyright (C) 2007-2008 Viacheslav Slavinsky +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +module wd1793 #(parameter RWMODE=0, EDSK=1) +( + input clk_sys, // sys clock + input ce, // ce at CPU clock rate + input reset, // async reset + input io_en, + input rd, // i/o read + input wr, // i/o write + input [1:0] addr, // i/o port addr + input [7:0] din, // i/o data in + output [7:0] dout, // i/o data out + output drq, // DMA request + output intrq, + output busy, + + input wp, // write protect + + input [2:0] size_code, + input layout, // 0 = Track-Side-Sector, 1 - Side-Track-Sector + input side, + input ready, + + // SD access (RWMODE == 1) + input img_mounted, // signaling that new image has been mounted + input [19:0] img_size, // size of image in bytes. 1MB MAX! + output prepare, + output[31:0] sd_lba, + output reg sd_rd, + output reg sd_wr, + input sd_ack, + input [8:0] sd_buff_addr, + input [7:0] sd_buff_dout, + output [7:0] sd_buff_din, + input sd_buff_wr, + + // RAM access (RWMODE == 0) + input input_active, + input [19:0] input_addr, + input [7:0] input_data, + input input_wr, + output[19:0] buff_addr, // buffer RAM address + output buff_read, // buffer RAM read enable + input [7:0] buff_din // buffer RAM data input +); + +// Possible track configs: +// 0: 26 x 128 = 3.3KB +// 1: 16 x 256 = 4.0KB +// 2: 9 x 512 = 4.5KB +// 3: 5 x 1024 = 5.0KB +// 4: 10 x 512 = 5.0KB + +assign dout = q; +assign drq = s_drq; +assign busy = s_busy; +assign intrq = s_intrq; +assign sd_lba = scan_active ? scan_addr[19:9] : buff_a[19:9] + sd_block; +assign prepare = EDSK ? scan_active : img_mounted; +assign buff_addr = {buff_a[19:9], 9'd0} + byte_addr; +assign buff_read = ((addr == A_DATA) && buff_rd); + +reg [7:0] sectors_per_track, edsk_spt = 0; +wire [10:0] sector_size = 11'd128 << wd_size_code; +reg [10:0] byte_addr; +reg [19:0] buff_a; +reg [1:0] wd_size_code; + +wire [7:0] buff_dout; +reg [1:0] sd_block = 0; +reg format; +generate + if(RWMODE) begin + wd1793_dpram sbuf + ( + .clock(clk_sys), + + .address_a({sd_block, sd_buff_addr}), + .data_a(sd_buff_dout), + .wren_a(sd_buff_wr & sd_ack), + .q_a(sd_buff_din), + + .address_b(scan_active ? {2'b00, scan_addr[8:0]} : byte_addr), + .data_b(format ? 8'd0 : din), + .wren_b(wre & buff_wr & (addr == A_DATA) & ~scan_active), + .q_b(buff_dout) + ); + reg buff_wr; + end else begin + assign buff_dout = 0; + assign sd_buff_din = 0; + end +endgenerate + +reg var_size = 0; +reg [19:0] disk_size; +reg layout_r; +wire [19:0] hs = (layout_r & side) ? disk_size >> 1 : 20'd0; +wire [7:0] dts = {disk_track[6:0], side} >> layout_r; +always @(posedge clk_sys) begin + case({var_size,size_code}) + 0: buff_a <= hs + {{1'b0, dts, 4'b0000} + {dts, 3'b000} + {dts, 1'b0} + wdreg_sector - 1'd1, 7'd0}; + 1: buff_a <= hs + {{dts, 4'b0000} + wdreg_sector - 1'd1, 8'd0}; + 2: buff_a <= hs + {{dts, 3'b000} + dts + wdreg_sector - 1'd1, 9'd0}; + 3: buff_a <= hs + {{dts, 2'b00} + dts + wdreg_sector - 1'd1, 10'd0}; + 4: buff_a <= hs + {{dts, 3'b000} +{dts, 1'b0} + wdreg_sector - 1'd1, 9'd0}; + default: buff_a <= edsk_offset; + endcase + case({var_size,size_code}) + 0: sectors_per_track <= 26; + 1: sectors_per_track <= 16; + 2: sectors_per_track <= 9; + 3: sectors_per_track <= 5; + 4: sectors_per_track <= 10; + default: sectors_per_track <= edsk_spt; + endcase + case({var_size,size_code}) + 0: wd_size_code <= 0; + 1: wd_size_code <= 1; + 2: wd_size_code <= 2; + 3: wd_size_code <= 3; + 4: wd_size_code <= 2; + default: wd_size_code <= edsk_sizecode; + endcase +end + +reg [1:0] blk_size; +always @* begin + case(wd_size_code) + 0: blk_size = 0; + 1: blk_size = 0; + 2: blk_size = buff_a[8:0] ? 2'd1 : 2'd0; + 3: blk_size = buff_a[8:0] ? 2'd2 : 2'd1; + endcase +end + + +// Register addresses +localparam A_COMMAND = 0; +localparam A_STATUS = 0; +localparam A_TRACK = 1; +localparam A_SECTOR = 2; +localparam A_DATA = 3; + +// States +typedef enum +{ + STATE_IDLE, + + STATE_SEARCH, + STATE_SEARCH_1, + + STATE_WAIT_READ, + STATE_WAIT_READ_1, + STATE_WAIT_READ_2, + + STATE_READ, + STATE_READ_1, + STATE_READ_2, + STATE_READ_3, + + STATE_WAIT_WRITE, + STATE_WAIT_WRITE_1, + STATE_WAIT_WRITE_2, + + STATE_WRITE, + STATE_WRITE_1, + STATE_WRITE_2, + + STATE_ABORT, + STATE_WAIT, + STATE_WAIT_2, + STATE_ENDCOMMAND +} io_state_t; + + +// common status bits +wire s_readonly = (wp | !RWMODE); +reg s_crcerr; +reg s_headloaded, s_seekerr, s_index; // mode 1 +reg s_lostdata, s_wrfault; // mode 2,3 + +// Command mode 0/1 for status register +reg cmd_mode; + +// allow write protect flag +reg s_wpe; + +// DRQ/BUSY are always going together +reg [1:0] s_drq_busy; +wire s_drq = s_drq_busy[1]; +wire s_busy = s_drq_busy[0]; +reg s_intrq; + +reg [7:0] wdreg_track; +reg [7:0] wdreg_sector; +reg [7:0] wdreg_data; +wire [7:0] wdreg_status = cmd_mode == 0 ? + {~ready, s_readonly & s_wpe, s_headloaded, s_seekerr | ~ready, s_crcerr, !disk_track, s_index, s_busy}: + {~ready, s_readonly & s_wpe, s_wrfault, s_seekerr | ~ready, s_crcerr, s_lostdata, s_drq, s_busy}; + +reg [7:0] read_addr[6]; +reg [7:0] q; +always @* begin + case (addr) + A_STATUS: q = wdreg_status; + A_TRACK: q = wdreg_track; + A_SECTOR: q = wdreg_sector; + A_DATA: q = (state == STATE_IDLE) ? wdreg_data : buff_rd ? (RWMODE ? buff_dout : buff_din) : read_addr[byte_addr[2:0]]; + endcase +end + +reg buff_rd; +reg step_direction; // last step direction + +reg [7:0] disk_track; // "real" heads position +reg [10:0] data_length; // this many bytes to transfer during read/write ops +io_state_t state = STATE_IDLE; + +// Reusable expressions +wire [7:0] next_track = (din[6] ? din[5] : step_direction) ? disk_track - 1'd1 : disk_track + 1'd1; +wire [10:0] next_length = data_length - 1'b1; + +// Watchdog +reg watchdog_set; +wire watchdog_bark = (wd_timer == 0); +reg [15:0] wd_timer; +always @(posedge clk_sys) begin + if(ce) begin + if(watchdog_set) wd_timer <= 4096; + else if(wd_timer != 0) wd_timer <= wd_timer - 1'b1; + end +end + +always @(posedge clk_sys) begin + integer cnt; + if(ce) begin + if(ready) begin + if(cnt) cnt <= cnt - 1; + else cnt <= 35000; + end else cnt <= 0; + s_index <= (cnt < 100); + end +end + +wire rde = rd & io_en; +wire wre = wr & io_en; +always @(posedge clk_sys) begin + reg old_wr, old_rd; + + reg [2:0] cur_addr; + reg read_data; + reg write_data; + reg rw_type; + integer wait_time; + reg [3:0] read_timer; + reg [9:0] seektimer; + reg [7:0] ra_sector; + reg multisector; + reg write; + reg [5:0] ack; + reg sd_busy; + reg old_mounted; + reg [3:0] scan_state; + reg [1:0] scan_cnt; + reg [1:0] blk_max; + + if(RWMODE) begin + old_mounted <= img_mounted; + if(old_mounted && ~img_mounted) begin + if(EDSK) begin + scan_active<= 1; + scan_addr <= 0; + scan_state <= 0; + scan_wr <= 0; + sd_block <= 0; + end + disk_size <= img_size[19:0]; + layout_r <= layout; + end + end else begin + scan_active <= input_active; + scan_addr <= input_addr; + scan_wr <= input_wr; + if(scan_active & ~input_active) begin + disk_size <= input_addr + 1'd1; + layout_r <= layout; + end + end + + if(reset & ~scan_active) begin + read_data <= 0; + write_data <= 0; + multisector <= 0; + step_direction <= 0; + disk_track <= 0; + wdreg_track <= 0; + wdreg_sector <= 0; + wdreg_data <= 0; + data_length <= 0; + byte_addr <=0; + buff_rd <= 0; + if(RWMODE) buff_wr <= 0; + state <= STATE_IDLE; + cmd_mode <= 0; + s_wpe <= 1; + {s_headloaded, s_seekerr, s_crcerr, s_intrq} <= 0; + {s_wrfault, s_lostdata} <= 0; + s_drq_busy <= 0; + watchdog_set <= 0; + seektimer <= 'h3FF; + {ack, sd_wr, sd_rd, sd_busy} <= 0; + ra_sector <= 1; + end else if(ce) begin + + ack <= {ack[4:0], sd_ack}; + if(ack[5:4] == 'b01) {sd_rd,sd_wr} <= 0; + if(ack[5:4] == 'b10) sd_busy <= 0; + + if(RWMODE & scan_active) begin + if(scan_addr >= img_size) scan_active <= 0; + else begin + case(scan_state) + 0: begin + sd_rd <= 1; + sd_busy <= 1; + scan_wr <= 0; + scan_state <= 1; + end + 1: if(!sd_busy) begin + scan_wr <= 1; + scan_cnt <= 1; + scan_state <= 2; + end + 2: begin + scan_cnt <= scan_cnt + 1'd1; + if(!scan_cnt) begin + scan_wr <= ~scan_wr; + if(scan_wr) begin + scan_addr <= scan_addr + 1'b1; + if(&scan_addr[8:0]) begin + scan_active <= var_size; + scan_state <= 0; + end + end + end + end + endcase + end + end + + old_wr <=wre; + old_rd <=rde; + + if((!old_rd && rde) || (!old_wr && wre)) cur_addr <= addr; + + //Register read operations + if(old_rd && !rde && (cur_addr == A_STATUS)) s_intrq <= 0; + + //end of data reading + if(old_rd && !rde && (cur_addr == A_DATA)) read_data <=1; + + //end of data writing + if(old_wr && !wre && (cur_addr == A_DATA)) write_data <=1; + + case (state) + /* Idle state or buffer to host transfer */ + STATE_IDLE:; // do nothing + + STATE_SEARCH: + begin + if(!ready) begin + s_seekerr <= 1; + state <= STATE_ENDCOMMAND; + end else begin + seektimer <= seektimer - 1'b1; + if(!seektimer) begin + byte_addr <= 0; + if(var_size) begin + if(~format) edsk_addr <= edsk_start; + if(EDSK) spt_addr <= (side ? spt_size>>1 : 8'd0) + disk_track; + state <= STATE_SEARCH_1; + end else begin + if(!wdreg_sector || (wdreg_sector > sectors_per_track)) begin + if(~format) s_seekerr <= 1; + state <= STATE_ENDCOMMAND; + end else begin + state <= rw_type ? STATE_WAIT_READ : STATE_READ; + end + end + end + end + end + STATE_SEARCH_1: + begin + if(rw_type & (edsk_track == disk_track) & + (edsk_side == side) & + (format | (edsk_sector == wdreg_sector))) begin + state <= STATE_WAIT_READ; + end + else + if(~rw_type & (edsk_track == disk_track) & + (edsk_side == side)) begin + read_addr[0] <= edsk_trackf; + read_addr[1] <= edsk_sidef; + read_addr[2] <= edsk_sector; + read_addr[3] <= edsk_sizecode; + state <= STATE_READ; + end + else + if(edsk_next == edsk_start) begin + if(~format) s_seekerr <= 1; + state <= STATE_ENDCOMMAND; + end + else + begin + edsk_addr <= edsk_next; + end + end + // read before write in case if sector not aligned or smaller than 512b + STATE_WAIT_READ: + begin + data_length <= sector_size; + byte_addr <= buff_a[8:0]; + blk_max <= blk_size; + sd_block <= 0; + state <= RWMODE ? STATE_WAIT_READ_1 : write ? STATE_WRITE : STATE_READ; + end + STATE_WAIT_READ_1: + begin + sd_busy <= 1; + sd_rd <= 1; + state <= STATE_WAIT_READ_2; + end + STATE_WAIT_READ_2: + begin + if(!sd_busy) begin + sd_block <= sd_block + 1'd1; + state <= write ? STATE_WRITE : STATE_READ; + if(sd_block < blk_max) state <= STATE_WAIT_READ_1; + end + end + + STATE_READ: + begin + watchdog_set <= 1; + read_timer <= 15; + state <= STATE_READ_1; + end + STATE_READ_1: + begin + read_timer <= read_timer - 1'b1; + if(!read_timer) begin + read_data <= 0; + watchdog_set <= 0; + s_lostdata <= 0; + s_drq_busy <= 2'b11; + state <= STATE_READ_2; + end + end + STATE_READ_2: + begin + if(watchdog_bark | (read_data & s_drq)) begin + // reset drq until next byte is read, nothing is lost + s_drq_busy <= 2'b01; + s_lostdata <= watchdog_bark; + + if(next_length == 0) begin + // either read the next sector, or stop if this is track end + if(multisector) begin + wdreg_sector <= wdreg_sector + 1'b1; + state <= STATE_SEARCH; + end else begin + state <= STATE_ENDCOMMAND; + end + end else begin + byte_addr <= byte_addr + 1'd1; + data_length <= next_length; + state <= STATE_READ; + end + end + end + + STATE_WAIT_WRITE: + begin + if(!ready) begin + s_wrfault <= 1; + state <= STATE_ENDCOMMAND; + end else begin + sd_block <= 0; + state <= STATE_WAIT_WRITE_1; + end + end + STATE_WAIT_WRITE_1: + begin + sd_busy <= 1; + sd_wr <= 1; + state <= STATE_WAIT_WRITE_2; + end + STATE_WAIT_WRITE_2: + begin + if(!sd_busy) begin + sd_block <= sd_block + 1'd1; + if(sd_block < blk_max) state <= STATE_WAIT_WRITE_1; + else begin + if(format && var_size && !edsk_next) begin + state <= STATE_ENDCOMMAND; + end else if(multisector) begin + edsk_addr <= edsk_next; + wdreg_sector <= wdreg_sector + 1'b1; + state <= STATE_SEARCH; + end else begin + state <= STATE_ENDCOMMAND; + end + end + end + end + STATE_WRITE: + begin + watchdog_set <= 1; + read_timer <= 15; + state <= STATE_WRITE_1; + end + STATE_WRITE_1: + begin + read_timer <= read_timer - 1'b1; + if(!read_timer) begin + write_data <= 0; + watchdog_set <= 0; + s_lostdata <= 0; + s_drq_busy <= 2'b11; + state <= STATE_WRITE_2; + end + end + STATE_WRITE_2: + begin + if(watchdog_bark | (write_data & s_drq)) begin + s_drq_busy <= 2'b01; + s_lostdata <= watchdog_bark; + + if(!next_length) state <= STATE_WAIT_WRITE; + else begin + byte_addr <= byte_addr + 1'd1; + data_length <= next_length; + state <= STATE_WRITE; + end + end + end + + // Abort current operation ($D0) + STATE_ABORT: + begin + data_length <= 0; + {s_wrfault,s_seekerr,s_crcerr,s_lostdata} <= 0; + state <= STATE_ENDCOMMAND; + end + + STATE_WAIT: + begin + wait_time <= 4000; + state <= STATE_WAIT_2; + end + STATE_WAIT_2: + begin + if(wait_time) wait_time <= wait_time - 1; + else state <= STATE_ENDCOMMAND; + end + + // End any command. + STATE_ENDCOMMAND: + begin + format <= 0; + buff_rd <= 0; + if(RWMODE) buff_wr <=0; + state <= STATE_IDLE; + s_drq_busy <= 2'b00; + seektimer <= 'h3FF; + s_intrq <= 1; + end + endcase + + /* Register write operations */ + if (!old_wr & wre) begin + case (addr) + A_COMMAND: + begin + s_intrq <= 0; + if((state == STATE_IDLE) | (din[7:4] == 'hD)) begin + cmd_mode <= din[7]; + s_wpe <= ~din[7]; + case (din[7:4]) + 'h0: // RESTORE + begin + // head load as specified, index, track0 + s_headloaded <= din[3]; + wdreg_track <= 0; + disk_track <= 0; + + // some programs like it when FDC gets busy for a while + s_drq_busy <= 2'b01; + state <= STATE_WAIT; + end + 'h1: // SEEK + begin + // set real track to datareg + disk_track <= wdreg_data; + s_headloaded <= din[3]; + + wdreg_track <= wdreg_data; + + // get busy + s_drq_busy <= 2'b01; + state <= STATE_WAIT; + end + 'h2, // STEP + 'h3, // STEP & UPDATE + 'h4, // STEP-IN + 'h5, // STEP-IN & UPDATE + 'h6, // STEP-OUT + 'h7: // STEP-OUT & UPDATE + begin + // if direction is specified, store it for the next time + if (din[6] == 1) step_direction <= din[5]; // 0: forward/in + + // perform step + disk_track <= next_track; + + // update TRACK register too if asked to + if (din[4]) wdreg_track <= next_track; + + s_headloaded <= din[3]; + + // some programs like it when FDC gets busy for a while + s_drq_busy <= 2'b01; + state <= STATE_WAIT; + end + 'h8, 'h9, // READ SECTORS + 'hA, 'hB: // WRITE SECTORS + begin + // seek data + // 5: 0: read, 1: write + // 4: m: 0: one sector, 1: until the track ends + // 3: S: SIDE + // 2: E: some 15ms delay + // 1: C: check side matching? + // 0: 0 + + s_drq_busy <= 2'b01; + {s_wrfault,s_seekerr,s_crcerr,s_lostdata} <= 0; + + {write,buff_rd} <= din[5] ? 2'b10 : 2'b01; + if(RWMODE) buff_wr <= din[5]; + + if(din[6]) wdreg_sector <= 1; + + format <= din[6]; + multisector <= din[4]; + rw_type <= 1; + write_data <= 0; + read_data <= 0; + edsk_start <= 0; + edsk_addr <= 0; + state <= STATE_SEARCH; + s_wpe <= din[5]; + + if(s_readonly & din[5]) begin + s_wrfault <= 1; + state <= STATE_WAIT; + end + end + 'hC: // READ ADDRESS + begin + // track, side, sector, sector size code, 2-byte checksum (crc?) + s_drq_busy <= 2'b01; + {s_wrfault,s_seekerr,s_crcerr,s_lostdata} <= 0; + + {write,buff_rd} <= 0; + if(RWMODE) buff_wr <=0; + + format <= 0; + multisector <= 0; + rw_type <= 0; + read_data <= 0; + edsk_start <= edsk_next; + data_length <= 6; + + read_addr[0] <= disk_track; + read_addr[1] <= {7'b0, side}; + read_addr[2] <= ra_sector; + read_addr[3] <= wd_size_code; + read_addr[4] <= 0; + read_addr[5] <= 0; + + if(ra_sector >= sectors_per_track) ra_sector <= 1; + else ra_sector <= ra_sector + 1'd1; + state <= STATE_SEARCH; + end + 'hD: // interrupt + begin + cmd_mode <= 0; + if(state != STATE_IDLE) state <= STATE_ABORT; + else {s_wrfault,s_seekerr,s_crcerr,s_lostdata, s_drq_busy} <= 0; + end + 'hF: // WRITE TRACK + begin + s_wpe <= din[5]; + {s_wrfault,s_seekerr,s_crcerr,s_lostdata} <= 0; + s_drq_busy <= 2'b01; + state <= STATE_WAIT; + end + 'hE: // READ TRACK + begin + {s_wrfault,s_crcerr,s_lostdata} <= 0; + s_seekerr <= 1; + s_drq_busy <= 2'b01; + state <= STATE_WAIT; + end + endcase + end + end + + A_TRACK: if (!s_busy) wdreg_track <= din; + A_SECTOR: if (!s_busy) {ra_sector, wdreg_sector} <= {din,din}; + A_DATA: wdreg_data <= din; + endcase + end + end +end + +reg scan_active = 0; +reg [19:0] scan_addr; +reg scan_wr; + +reg [1:0] edsk_sizecode = 0; // sector size: 0=128K, 1=256K, 2=512K, 3=1024K +reg edsk_side = 0; // Side number (0 or 1) +reg [6:0] edsk_track = 0; // Track number +reg [7:0] edsk_sector = 0; // Sector number 0..15 +reg [19:0] edsk_offset = 0; +reg [7:0] edsk_trackf = 0, edsk_sidef = 0; + +reg [10:0] edsk_addr, edsk_start; + +reg [10:0] edsk_size = 0; +wire[10:0] edsk_next = ((edsk_addr + 1'd1) >= edsk_size) ? 11'd0 : edsk_addr + 1'd1; + +reg [7:0] spt_size = 0; + +generate + if(EDSK) begin + wire [7:0] scan_data = RWMODE ? buff_dout : input_data; + reg [53:0] edsk[1992]; + reg [7:0] spt[166]; + + reg [7:0] spt_addr; + always @(posedge clk_sys) begin + {edsk_track,edsk_side,edsk_trackf,edsk_sidef,edsk_sector,edsk_sizecode,edsk_offset} <= edsk[edsk_addr]; + edsk_spt <= spt[spt_addr]; + end + + reg [7:0] tpos; + reg [7:0] tsize; + reg [7:0] tsizes[166]; + always @(posedge clk_sys) tsize <= tsizes[tpos]; + + wire[127:0] edsk_sig = "EXTENDED CPC DSK"; + wire[127:0] sig_pos = edsk_sig >> (8'd120-(scan_addr[7:0]<<3)); + + always @(posedge clk_sys) begin + reg old_active, old_wr; + reg [13:0] hdr_pos, bcnt; + reg [7:0] idStatus; + reg [6:0] track; + reg side; + reg [7:0] sector; + reg [1:0] sizecode; + reg [7:0] crc1; + reg [7:0] crc2; + reg [7:0] sectors; + reg [15:0] track_size, track_pos; + reg [19:0] offset, offset1; + reg [7:0] size_lo; + reg [10:0] secpos; + reg [7:0] trackf, sidef; + + old_active <= scan_active; + if(scan_active & ~old_active) begin + edsk_size <=0; + spt_size <=0; + track_pos <=0; + var_size <=1; + end + + old_wr <= scan_wr; + if(scan_wr & ~old_wr & scan_active) begin + if((scan_addr[19:0] < 16) & (sig_pos[7:0] != scan_data)) var_size <= 0; + if(var_size) begin + if( scan_addr == 48) spt_size <= scan_data; else + if((scan_addr == 49) & (scan_data == 2)) spt_size <= spt_size << 1; else + if( scan_addr == 52) begin + track_size <= {scan_data, 8'd0}; + track_pos <= 0; + tpos <= 1; + end else + if((scan_addr > 52) & (scan_addr < 218)) begin + tsizes[scan_addr - 52] <= scan_data; + spt[scan_addr - 52] <= 0; + end else + if((scan_addr >= 256) && track_size) begin + track_pos <= track_pos + 1'd1; + case(track_pos) + 00: offset <= scan_addr + 9'd256; + 16: track <= scan_data[6:0]; + 17: side <= scan_data[0]; + 21: sectors <= scan_data; + 22: spt[(side ? (spt_size >> 1) : 8'd0) + track] <= sectors; + default: + if((track_pos >= 24) && sectors) begin + case(track_pos[2:0]) + 0: begin + trackf <= scan_data; + secpos <= edsk_size; + offset1 <= offset; + end + 1: sidef <= scan_data; + 2: sector <= scan_data; + 3: sizecode<= scan_data[1:0]; + 6: size_lo <= scan_data; + 7: begin + if({scan_data, size_lo}) begin + edsk[secpos] <= {track,side,trackf,sidef,sector,sizecode,offset1}; + edsk_size <= edsk_size + 1'd1; + offset <= offset + {scan_data, size_lo}; + end + sectors <= sectors - 1'd1; + end + default:; + endcase + end + endcase + if(track_pos >= (track_size - 1'd1)) begin + track_size <= {tsize, 8'd0}; + track_pos <= 0; + tpos <= tpos + 1'd1; + end + end + end + end + end + end +endgenerate + +endmodule + +module wd1793_dpram #(parameter DATAWIDTH=8, ADDRWIDTH=11) +( + input clock, + + input [ADDRWIDTH-1:0] address_a, + input [DATAWIDTH-1:0] data_a, + input wren_a, + output reg [DATAWIDTH-1:0] q_a, + + input [ADDRWIDTH-1:0] address_b, + input [DATAWIDTH-1:0] data_b, + input wren_b, + output reg [DATAWIDTH-1:0] q_b +); + +logic [DATAWIDTH-1:0] ram[0:(1< '0'); - - elsif clk_i'event and clk_i = '1' then - if clk_en_10m7_i = '1' then - if clk_cnt_q = 0 then - clk_cnt_q <= "10"; - else - clk_cnt_q <= clk_cnt_q - 1; - end if; - end if; - end if; - end process clk_cnt; - -- - ----------------------------------------------------------------------------- - - clk_en_3m58_p_o <= clk_en_10m7_i when clk_cnt_q = 0 else '0'; - clk_en_3m58_n_o <= clk_en_10m7_i when clk_cnt_q = "10" else '0'; - +------------------------------------------------------------------------------- +-- +-- FPGA Colecovision +-- +-- $Id: cv_clock.vhd,v 1.3 2006/01/05 22:22:29 arnim Exp $ +-- +-- Clock Generator +-- +------------------------------------------------------------------------------- +-- +-- Copyright (c) 2006, Arnim Laeuger (arnim.laeuger@gmx.net) +-- +-- All rights reserved +-- +-- Redistribution and use in source and synthezised forms, with or without +-- modification, are permitted provided that the following conditions are met: +-- +-- Redistributions of source code must retain the above copyright notice, +-- this list of conditions and the following disclaimer. +-- +-- Redistributions in synthesized form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- Neither the name of the author nor the names of other contributors may +-- be used to endorse or promote products derived from this software without +-- specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE +-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +-- POSSIBILITY OF SUCH DAMAGE. +-- +-- Please report bugs to the author, but before you do so, please +-- make sure that this is not a derivative work and that +-- you have the latest version of this file. +-- +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity cv_clock is + + port ( + clk_i : in std_logic; + clk_en_10m7_i : in std_logic; + reset_n_i : in std_logic; + clk_en_3m58_p_o : out std_logic; + clk_en_3m58_n_o : out std_logic + ); + +end cv_clock; +architecture rtl of cv_clock is + signal clk_cnt_q : unsigned(1 downto 0); +begin + + ----------------------------------------------------------------------------- + -- Process clk_cnt + -- + -- Purpose: + -- Implements the counter which is used to generate the clock enable + -- for the 3.58 MHz clock. + -- + clk_cnt : process (clk_i, reset_n_i) + begin + if reset_n_i = '0' then + clk_cnt_q <= (others => '0'); + + elsif clk_i'event and clk_i = '1' then + if clk_en_10m7_i = '1' then + if clk_cnt_q = 0 then + clk_cnt_q <= "10"; + else + clk_cnt_q <= clk_cnt_q - 1; + end if; + end if; + end if; + end process clk_cnt; + -- + ----------------------------------------------------------------------------- + + clk_en_3m58_p_o <= clk_en_10m7_i when clk_cnt_q = 0 else '0'; + clk_en_3m58_n_o <= clk_en_10m7_i when clk_cnt_q = "10" else '0'; + end rtl; \ No newline at end of file diff --git a/rtl/index.qip b/rtl/index.qip index dda558e..50f2b73 100644 --- a/rtl/index.qip +++ b/rtl/index.qip @@ -1,39 +1,39 @@ -# ============================================================================== -# RTL -# ============================================================================== -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "msx1.sv"] - -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "bram.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "cv_clock.vhd"] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "io_decoder.v"] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "jt8255.v"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "keyboard.vhd"] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "ls74.sv"] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "memory_mapper.v"] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "sdram.sv"] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "slots.sv"] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "tape.sv"] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "joy2ps2.sv"] - -set_global_assignment -name MIF_FILE [file join $::quartus(qip_path) "rom/cbios_main_msx1_eu.mif"] -set_global_assignment -name MIF_FILE [file join $::quartus(qip_path) "rom/cbios_main_msx1.mif"] -set_global_assignment -name MIF_FILE [file join $::quartus(qip_path) "rom/vy0010.mif"] - -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/rom.v"] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/rom_detect.v"] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/konami.v"] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/konami_scc.v"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "cart/scc_wave.vhd"] -set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "cart/ram.vhd"] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/ascii8.v"] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/ascii16.v"] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/gamemaster2.v"] -set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/vy0010.v"] -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "cart/wd1793.sv"] - -# ============================================================================== -# MODULES -# ============================================================================== -set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "../modules/video-vdp18/index.qip"] -set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "../modules/cpu-t80/index.qip"] +# ============================================================================== +# RTL +# ============================================================================== +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "msx1.sv"] + +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "bram.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "cv_clock.vhd"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "io_decoder.v"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "jt8255.v"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "keyboard.vhd"] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "ls74.sv"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "memory_mapper.v"] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "sdram.sv"] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "slots.sv"] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "tape.sv"] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "joy2ps2.sv"] + +set_global_assignment -name MIF_FILE [file join $::quartus(qip_path) "rom/cbios_main_msx1_eu.mif"] +set_global_assignment -name MIF_FILE [file join $::quartus(qip_path) "rom/cbios_main_msx1.mif"] +set_global_assignment -name MIF_FILE [file join $::quartus(qip_path) "rom/vy0010.mif"] + +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/rom.v"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/rom_detect.v"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/konami.v"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/konami_scc.v"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "cart/scc_wave.vhd"] +set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "cart/ram.vhd"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/ascii8.v"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/ascii16.v"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/gamemaster2.v"] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "cart/vy0010.v"] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "cart/wd1793.sv"] + +# ============================================================================== +# MODULES +# ============================================================================== +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "../modules/video-vdp18/index.qip"] +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "../modules/cpu-t80/index.qip"] set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "../modules/sound-jt49/index.qip"] \ No newline at end of file diff --git a/rtl/io_decoder.v b/rtl/io_decoder.v index dbabec9..8f0d3b9 100644 --- a/rtl/io_decoder.v +++ b/rtl/io_decoder.v @@ -1,43 +1,43 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX Compatible Gateware IP Core -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -module io_decoder - ( - input wire [7:0] addr, - input wire iorq_n, - input wire m1_n, - output wire vdp_n, - output wire psg_n, - output wire ppi_n, - output wire cen_n - ); - - wire io_en = ~iorq_n & m1_n; - - assign cen_n = ~((addr[7:3] == 5'b10010) & io_en); - assign vdp_n = ~((addr[7:3] == 5'b10011) & io_en); - assign psg_n = ~((addr[7:3] == 5'b10100) & io_en); - assign ppi_n = ~((addr[7:3] == 5'b10101) & io_en); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX Compatible Gateware IP Core +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +module io_decoder + ( + input wire [7:0] addr, + input wire iorq_n, + input wire m1_n, + output wire vdp_n, + output wire psg_n, + output wire ppi_n, + output wire cen_n + ); + + wire io_en = ~iorq_n & m1_n; + + assign cen_n = ~((addr[7:3] == 5'b10010) & io_en); + assign vdp_n = ~((addr[7:3] == 5'b10011) & io_en); + assign psg_n = ~((addr[7:3] == 5'b10100) & io_en); + assign ppi_n = ~((addr[7:3] == 5'b10101) & io_en); + +endmodule diff --git a/rtl/joy2ps2.sv b/rtl/joy2ps2.sv index 2789bc7..75d6a88 100644 --- a/rtl/joy2ps2.sv +++ b/rtl/joy2ps2.sv @@ -1,242 +1,242 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Joystick to PS/2 Keyboard -// -// Copyright (c) 2024, Marcus Andrade -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -`default_nettype none -`timescale 1ns/1ps - -module joy2ps2 - ( - input wire clk, - input wire reset, // Reset signal - input wire enable, // Reset signal - input wire [23:0] key_map, // Key Mapping - input wire [5:0] joy_key, // [5] Start, [4] Select, [3] R1, [2] L1, [1] X, [0] Y - output logic [10:0] ps2_key // [10] Strobe, [9] Pressed/Released, [8:0] Scancode - ); - - // Define states for the state machine - typedef enum logic [2:0] { - KEY_IDLE, - KEY_SAVE, - KEY_PRESSED, - KEY_HELD, - KEY_RELEASED_TO_IDLE, - KEY_RELEASED_TO_NEW - } KeyState; - - KeyState state, next_state; - - // PS/2 Keyboard Internal Logic - reg key_strobe; - reg key_pressed; - reg [8:0] key_code; - - // PS/2 Translation - reg [8:0] ps2_scancode, ps2_scancode_last; - reg [8:0] key_code_saved; - reg save_key; - - parameter SC_END = 9'h169, // SELECT - SC_PG_UP = 9'h17D, // STOP - SC_L_ALT = 9'h011, // GRAPH - SC_L_CRTL = 9'h014, // CRTL - SC_UP = 9'h175, // Arrow Up - SC_DOWN = 9'h172, // Arrow Down - SC_LEFT = 9'h16B, // Arrow Left - SC_RIGHT = 9'h174, // Arrow Right - SC_F1 = 9'h005, SC_1 = 9'h016, - SC_F2 = 9'h006, SC_2 = 9'h01E, - SC_F3 = 9'h004, SC_3 = 9'h026, - SC_F4 = 9'h00C, SC_4 = 9'h025, - SC_F5 = 9'h003, SC_5 = 9'h02E, - SC_M = 9'h03A, SC_N = 9'h031, - SC_SPACE = 9'h029, SC_SHIFT = 9'h012, - SC_ESC = 9'h076, SC_RETURN = 9'h05A, - SC_NONE = 9'h000; - - reg [8:0] MAP_Y, MAP_X; - reg [8:0] MAP_L, MAP_R; - reg [8:0] MAP_ST, MAP_SE; - - always_ff @(negedge clk) begin : assignMapping - case(key_map[3:0]) - 4'h1 : begin MAP_Y = SC_SPACE; end - 4'h2 : begin MAP_Y = SC_SHIFT; end - 4'h3 : begin MAP_Y = SC_M; end - 4'h4 : begin MAP_Y = SC_N; end - 4'h5 : begin MAP_Y = SC_1; end - 4'h6 : begin MAP_Y = SC_2; end - 4'h7 : begin MAP_Y = SC_3; end - 4'h8 : begin MAP_Y = SC_4; end - 4'h9 : begin MAP_Y = SC_ESC; end - 4'hA : begin MAP_Y = SC_RETURN; end - default: begin MAP_Y = SC_NONE; end - endcase - case(key_map[7:4]) - 4'h1 : begin MAP_X = SC_SPACE; end - 4'h2 : begin MAP_X = SC_SHIFT; end - 4'h3 : begin MAP_X = SC_M; end - 4'h4 : begin MAP_X = SC_N; end - 4'h5 : begin MAP_X = SC_1; end - 4'h6 : begin MAP_X = SC_2; end - 4'h7 : begin MAP_X = SC_3; end - 4'h8 : begin MAP_X = SC_4; end - 4'h9 : begin MAP_X = SC_ESC; end - 4'hA : begin MAP_X = SC_RETURN; end - default: begin MAP_X = SC_NONE; end - endcase - case(key_map[11:8]) - 4'h1 : begin MAP_L = SC_END; end - 4'h2 : begin MAP_L = SC_PG_UP; end - 4'h3 : begin MAP_L = SC_L_ALT; end - 4'h4 : begin MAP_L = SC_L_CRTL; end - 4'h5 : begin MAP_L = SC_F1; end - default: begin MAP_L = SC_NONE; end - endcase - case(key_map[15:12]) - 4'h1 : begin MAP_R = SC_END; end - 4'h2 : begin MAP_R = SC_PG_UP; end - 4'h3 : begin MAP_R = SC_L_ALT; end - 4'h4 : begin MAP_R = SC_L_CRTL; end - 4'h5 : begin MAP_R = SC_F5; end - default: begin MAP_R = SC_NONE; end - endcase - case(key_map[19:16]) - 4'h1 : begin MAP_SE = SC_SPACE; end - 4'h2 : begin MAP_SE = SC_F1; end - 4'h3 : begin MAP_SE = SC_F2; end - 4'h4 : begin MAP_SE = SC_F3; end - 4'h5 : begin MAP_SE = SC_F4; end - 4'h6 : begin MAP_SE = SC_F5; end - default: begin MAP_SE = SC_NONE; end - endcase - case(key_map[23:20]) - 4'h1 : begin MAP_ST = SC_SPACE; end - 4'h2 : begin MAP_ST = SC_F1; end - 4'h3 : begin MAP_ST = SC_F2; end - 4'h4 : begin MAP_ST = SC_F3; end - 4'h5 : begin MAP_ST = SC_F4; end - 4'h6 : begin MAP_ST = SC_F5; end - default: begin MAP_ST = SC_NONE; end - endcase - end - - always_ff @(posedge clk) begin : joy2scancode - if (reset) begin - ps2_scancode <= 9'h0; - end - else begin - if(joy_key != 6'h0) begin - case(joy_key) - 6'h01 : begin ps2_scancode <= MAP_Y; end // [0] Y - 6'h02 : begin ps2_scancode <= MAP_X; end // [1] X - 6'h04 : begin ps2_scancode <= MAP_L; end // [2] L - 6'h08 : begin ps2_scancode <= MAP_R; end // [3] R - 6'h10 : begin ps2_scancode <= MAP_SE; end // [4] Select - 6'h20 : begin ps2_scancode <= MAP_ST; end // [5] Start - default: begin /* DO NOTHING */ end - endcase - end - else begin - ps2_scancode <= 9'h0; - end - end - end - - // Save Scancode - always_ff @(posedge clk) begin : saveScancode - key_code_saved <= (save_key) ? ps2_scancode : key_code_saved; - end - - // State Machine Controller - always_ff @(posedge clk) begin : scancodeFSM - if (reset) begin - state <= KEY_IDLE; - end - else begin - ps2_scancode_last <= ps2_scancode; - state <= next_state; - end - end - - // PS/2 Translation - always_comb begin : scancodeTranslation - next_state = state; - key_code = 9'h000; - key_pressed = 1'b0; - key_strobe = 1'b0; - save_key = 1'b0; - - case (state) - KEY_IDLE: begin - key_code = 9'h000; - // Detect zero to non-zero transition - if(~|ps2_scancode_last & |ps2_scancode) begin - next_state = KEY_SAVE; - end - end - KEY_SAVE: begin - save_key = 1'b1; - next_state = KEY_PRESSED; - end - KEY_PRESSED: begin - key_code = key_code_saved; - key_pressed = 1'b1; - key_strobe = 1'b1; - next_state = KEY_HELD; - end - KEY_HELD: begin - key_code = key_code_saved; - key_pressed = 1'b1; - key_strobe = 1'b0; - // Detect non-zero to zero transition - if(|ps2_scancode_last & ~|ps2_scancode) begin - next_state = KEY_RELEASED_TO_IDLE; - end - else if (ps2_scancode_last != ps2_scancode) begin - next_state = KEY_RELEASED_TO_NEW; - end - end - KEY_RELEASED_TO_IDLE: begin - key_code = key_code_saved; - key_pressed = 1'b0; - key_strobe = 1'b1; - next_state = KEY_IDLE; - end - KEY_RELEASED_TO_NEW: begin - key_code = key_code_saved; - key_strobe = 1'b1; - key_pressed = 1'b0; - next_state = KEY_SAVE; - end - default: begin - next_state = KEY_IDLE; - end - endcase - end - - // PS/2 Keyboard Output - assign ps2_key = enable ? {key_strobe, key_pressed, key_code} : 11'h0; - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Joystick to PS/2 Keyboard +// +// Copyright (c) 2024, Marcus Andrade +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +`default_nettype none +`timescale 1ns/1ps + +module joy2ps2 + ( + input wire clk, + input wire reset, // Reset signal + input wire enable, // Reset signal + input wire [23:0] key_map, // Key Mapping + input wire [5:0] joy_key, // [5] Start, [4] Select, [3] R1, [2] L1, [1] X, [0] Y + output logic [10:0] ps2_key // [10] Strobe, [9] Pressed/Released, [8:0] Scancode + ); + + // Define states for the state machine + typedef enum logic [2:0] { + KEY_IDLE, + KEY_SAVE, + KEY_PRESSED, + KEY_HELD, + KEY_RELEASED_TO_IDLE, + KEY_RELEASED_TO_NEW + } KeyState; + + KeyState state, next_state; + + // PS/2 Keyboard Internal Logic + reg key_strobe; + reg key_pressed; + reg [8:0] key_code; + + // PS/2 Translation + reg [8:0] ps2_scancode, ps2_scancode_last; + reg [8:0] key_code_saved; + reg save_key; + + parameter SC_END = 9'h169, // SELECT + SC_PG_UP = 9'h17D, // STOP + SC_L_ALT = 9'h011, // GRAPH + SC_L_CRTL = 9'h014, // CRTL + SC_UP = 9'h175, // Arrow Up + SC_DOWN = 9'h172, // Arrow Down + SC_LEFT = 9'h16B, // Arrow Left + SC_RIGHT = 9'h174, // Arrow Right + SC_F1 = 9'h005, SC_1 = 9'h016, + SC_F2 = 9'h006, SC_2 = 9'h01E, + SC_F3 = 9'h004, SC_3 = 9'h026, + SC_F4 = 9'h00C, SC_4 = 9'h025, + SC_F5 = 9'h003, SC_5 = 9'h02E, + SC_M = 9'h03A, SC_N = 9'h031, + SC_SPACE = 9'h029, SC_SHIFT = 9'h012, + SC_ESC = 9'h076, SC_RETURN = 9'h05A, + SC_NONE = 9'h000; + + reg [8:0] MAP_Y, MAP_X; + reg [8:0] MAP_L, MAP_R; + reg [8:0] MAP_ST, MAP_SE; + + always_ff @(negedge clk) begin : assignMapping + case(key_map[3:0]) + 4'h1 : begin MAP_Y = SC_SPACE; end + 4'h2 : begin MAP_Y = SC_SHIFT; end + 4'h3 : begin MAP_Y = SC_M; end + 4'h4 : begin MAP_Y = SC_N; end + 4'h5 : begin MAP_Y = SC_1; end + 4'h6 : begin MAP_Y = SC_2; end + 4'h7 : begin MAP_Y = SC_3; end + 4'h8 : begin MAP_Y = SC_4; end + 4'h9 : begin MAP_Y = SC_ESC; end + 4'hA : begin MAP_Y = SC_RETURN; end + default: begin MAP_Y = SC_NONE; end + endcase + case(key_map[7:4]) + 4'h1 : begin MAP_X = SC_SPACE; end + 4'h2 : begin MAP_X = SC_SHIFT; end + 4'h3 : begin MAP_X = SC_M; end + 4'h4 : begin MAP_X = SC_N; end + 4'h5 : begin MAP_X = SC_1; end + 4'h6 : begin MAP_X = SC_2; end + 4'h7 : begin MAP_X = SC_3; end + 4'h8 : begin MAP_X = SC_4; end + 4'h9 : begin MAP_X = SC_ESC; end + 4'hA : begin MAP_X = SC_RETURN; end + default: begin MAP_X = SC_NONE; end + endcase + case(key_map[11:8]) + 4'h1 : begin MAP_L = SC_END; end + 4'h2 : begin MAP_L = SC_PG_UP; end + 4'h3 : begin MAP_L = SC_L_ALT; end + 4'h4 : begin MAP_L = SC_L_CRTL; end + 4'h5 : begin MAP_L = SC_F1; end + default: begin MAP_L = SC_NONE; end + endcase + case(key_map[15:12]) + 4'h1 : begin MAP_R = SC_END; end + 4'h2 : begin MAP_R = SC_PG_UP; end + 4'h3 : begin MAP_R = SC_L_ALT; end + 4'h4 : begin MAP_R = SC_L_CRTL; end + 4'h5 : begin MAP_R = SC_F5; end + default: begin MAP_R = SC_NONE; end + endcase + case(key_map[19:16]) + 4'h1 : begin MAP_SE = SC_SPACE; end + 4'h2 : begin MAP_SE = SC_F1; end + 4'h3 : begin MAP_SE = SC_F2; end + 4'h4 : begin MAP_SE = SC_F3; end + 4'h5 : begin MAP_SE = SC_F4; end + 4'h6 : begin MAP_SE = SC_F5; end + default: begin MAP_SE = SC_NONE; end + endcase + case(key_map[23:20]) + 4'h1 : begin MAP_ST = SC_SPACE; end + 4'h2 : begin MAP_ST = SC_F1; end + 4'h3 : begin MAP_ST = SC_F2; end + 4'h4 : begin MAP_ST = SC_F3; end + 4'h5 : begin MAP_ST = SC_F4; end + 4'h6 : begin MAP_ST = SC_F5; end + default: begin MAP_ST = SC_NONE; end + endcase + end + + always_ff @(posedge clk) begin : joy2scancode + if (reset) begin + ps2_scancode <= 9'h0; + end + else begin + if(joy_key != 6'h0) begin + case(joy_key) + 6'h01 : begin ps2_scancode <= MAP_Y; end // [0] Y + 6'h02 : begin ps2_scancode <= MAP_X; end // [1] X + 6'h04 : begin ps2_scancode <= MAP_L; end // [2] L + 6'h08 : begin ps2_scancode <= MAP_R; end // [3] R + 6'h10 : begin ps2_scancode <= MAP_SE; end // [4] Select + 6'h20 : begin ps2_scancode <= MAP_ST; end // [5] Start + default: begin /* DO NOTHING */ end + endcase + end + else begin + ps2_scancode <= 9'h0; + end + end + end + + // Save Scancode + always_ff @(posedge clk) begin : saveScancode + key_code_saved <= (save_key) ? ps2_scancode : key_code_saved; + end + + // State Machine Controller + always_ff @(posedge clk) begin : scancodeFSM + if (reset) begin + state <= KEY_IDLE; + end + else begin + ps2_scancode_last <= ps2_scancode; + state <= next_state; + end + end + + // PS/2 Translation + always_comb begin : scancodeTranslation + next_state = state; + key_code = 9'h000; + key_pressed = 1'b0; + key_strobe = 1'b0; + save_key = 1'b0; + + case (state) + KEY_IDLE: begin + key_code = 9'h000; + // Detect zero to non-zero transition + if(~|ps2_scancode_last & |ps2_scancode) begin + next_state = KEY_SAVE; + end + end + KEY_SAVE: begin + save_key = 1'b1; + next_state = KEY_PRESSED; + end + KEY_PRESSED: begin + key_code = key_code_saved; + key_pressed = 1'b1; + key_strobe = 1'b1; + next_state = KEY_HELD; + end + KEY_HELD: begin + key_code = key_code_saved; + key_pressed = 1'b1; + key_strobe = 1'b0; + // Detect non-zero to zero transition + if(|ps2_scancode_last & ~|ps2_scancode) begin + next_state = KEY_RELEASED_TO_IDLE; + end + else if (ps2_scancode_last != ps2_scancode) begin + next_state = KEY_RELEASED_TO_NEW; + end + end + KEY_RELEASED_TO_IDLE: begin + key_code = key_code_saved; + key_pressed = 1'b0; + key_strobe = 1'b1; + next_state = KEY_IDLE; + end + KEY_RELEASED_TO_NEW: begin + key_code = key_code_saved; + key_strobe = 1'b1; + key_pressed = 1'b0; + next_state = KEY_SAVE; + end + default: begin + next_state = KEY_IDLE; + end + endcase + end + + // PS/2 Keyboard Output + assign ps2_key = enable ? {key_strobe, key_pressed, key_code} : 11'h0; + +endmodule diff --git a/rtl/jt8255.v b/rtl/jt8255.v index 7ffde12..abd7464 100644 --- a/rtl/jt8255.v +++ b/rtl/jt8255.v @@ -1,263 +1,263 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// JT8255 -// Programmable peripheral interface compatible with Intel 8255 -// -// Copyright (c) 2021, Jose Tejada Gomez <@topapate> -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ - -module jt8255( - input rst, - input clk, - - // CPU interface - input [1:0] addr, - input [7:0] din, - output reg [7:0] dout, - input rdn, - input wrn, - input csn, - - // External pins to peripherals - input [7:0] porta_din, - input [7:0] portb_din, - input [7:0] portc_din, - - output reg [7:0] porta_dout, - output reg [7:0] portb_dout, - output [7:0] portc_dout -); - -localparam ISINA=4, ISINB=1, ISINCL=0, ISINCH=3; // Control word bits -localparam INTRA=3, OBFA=7, ACKA=6, STBA=4, IBFA=5, // PC bits, mode 2 - INTRB=0, OBFB=1, ACKB=2, STBB=2, IBFB=1; - -localparam INTEA_OBF=6, INTEA_IBF=4, INTEB=2; - -reg [6:0] ctrl; -reg [7:0] latch_a, latch_b, latch_c; - -wire mode_b, - isin_a, isin_b, isin_cl, isin_ch; // is input a,b,c... -wire [1:0] mode_a; - -wire write, read; -reg last_write, last_read; - -reg inte_a_obf, inte_a_ibf, inte_b; -wire acka, ackb, stba, stbb; - -reg last_acka, last_ackb, last_stba; -wire last_stbb; - -assign read = !rdn && !csn; -assign write = !wrn && !csn; -assign mode_b = ctrl[2]; -assign mode_a = ctrl[6:5]; - -assign isin_a = ctrl[ISINA]; -assign isin_b = ctrl[ISINB]; -assign isin_cl = ctrl[ISINCL]; -assign isin_ch = ctrl[ISINCH]; - -assign acka = portc_din[ACKA]; -assign stba = portc_din[STBA]; -assign ackb = portc_din[ACKB]; -assign stbb = portc_din[STBB]; // this is the same as ackb -assign last_stbb = last_ackb; - - -// Mode control -always @(posedge clk, posedge rst) begin - if( rst ) begin - ctrl <= 7'h1b; - latch_a <= 8'hff; - latch_b <= 8'hff; - latch_c <= 8'hff; - - inte_a_ibf <= 0; - inte_a_obf <= 0; - inte_b <= 0; - - last_write <= 0; - last_acka <= 0; - last_ackb <= 0; - last_stba <= 0; - end else begin - last_write <= write; - last_acka <= acka; - last_ackb <= ackb; - last_stba <= stba; - -// if( !write && last_write ) begin - if( write ) begin //Changed - case( addr ) - 2'd0: begin // Port A - if( !isin_a || mode_a[1] ) begin - latch_a <= din; // A is an output - if( mode_a!=0 ) begin - latch_c[OBFA] <= 0; - if(inte_a_obf) latch_c[INTRA] <= 0; // interrupt pin - end - end - end - 2'd1: begin // Port B - if( !isin_b ) begin - latch_b <= din; // B is an output - if( mode_b ) begin - latch_c[OBFB] <= 0; - if(inte_b) latch_c[INTRB] <= 0; // interrupt pin - end - end end - 2'd2: begin - if( mode_b ) - inte_b <= din[INTEB]; - else - latch_c[2:0] <= din[2:0]; - - if( (mode_a==0 || (mode_a[0]&&isin_a)) ) - latch_c[7:6] <= din[7:6]; - - if( mode_a==0 || (mode_a[0]&&!isin_a) ) - latch_c[5:4] <= din[5:4]; - - if( mode_a==0 ) - latch_c[3] <= din[3]; - - if( mode_a[1] || (mode_a[0] && isin_a) ) - inte_a_ibf <= din[INTEA_IBF]; - if( mode_a[1] || (mode_a[0] && !isin_a) ) - inte_a_obf <= din[INTEA_OBF]; - end - 2'd3: begin - if( din[7] ) begin - ctrl <= din[6:0]; - if( !din[ISINCL] ) latch_c[3:0] <= 0; - if( !din[ISINCH] ) latch_c[7:4] <= 0; - if( !din[ISINB] ) latch_b <= 0; - if( !din[ISINA] ) latch_a <= 0; - inte_a_ibf <= 0; - inte_a_obf <= 0; - inte_b <= 0; - if( din[2] ) begin - latch_c[IBFB] <= ~din[ISINB]; // start with safe IBF/OBF signals - latch_c[INTRB]<= ~din[ISINB]; - end - if( din[6:5]!=0 ) begin - latch_c[IBFA] <= 0; - latch_c[OBFA] <= 1; - latch_c[INTRA]<= 0; - end - end else begin - latch_c[ din[3:1] ] <= din[0]; - if( din[3:1]==INTEA_OBF ) inte_a_obf <= din[0]; - if( din[3:1]==INTEA_IBF ) inte_a_ibf <= din[0]; - if( din[3:1]==INTEB ) inte_b <= din[0]; - end - end - endcase - end else begin - // Input Buffer Full - if( mode_b && isin_b && stbb && !last_stbb ) begin - latch_c[IBFB] <= 1; - if( inte_b ) latch_c[INTRB] <= 1; - end - if( (mode_a[1] || (mode_a[0] && isin_a)) && stba && !last_stba ) begin - latch_c[IBFA] <= 1; - if( inte_a_ibf ) latch_c[INTRA] <= 1; - end - - if( mode_a!=2'd00 ) begin - // clears the interrupts - if(!inte_a_ibf && !inte_a_obf) latch_c[INTRA] <= 0; //Changed - // The peripheral reads - if( (!isin_a || mode_a[1]) && acka && !last_acka ) begin - latch_c[INTRA] <= 1; - latch_c[OBFA] <= 1; - end - // The CPU reads - if( (isin_a || mode_a[1]) && read && !last_read && addr==2'd0 ) begin - latch_c[INTRA] <= 0; - latch_c[IBFA] <= 0; - end - end - if( mode_b ) begin - // clears the interrupts - if(!inte_b) latch_c[INTRB] <= 0; //Changed - // The peripheral reads - if( !isin_b && ackb && !last_ackb ) begin - latch_c[INTRB] <= 1; - latch_c[OBFB] <= 1; - end - // The CPU reads - if( isin_b && read && !last_read && addr==2'd1 ) begin - latch_c[INTRB] <= 0; - latch_c[IBFB] <= 0; - end - end - end - end -end - -// CPU interface -always @(posedge clk, posedge rst) begin - if( rst ) begin - dout <= 8'hff; - last_read <= 0; - end else begin - last_read <= read; - if( read ) begin - case( addr ) - 2'd0: dout <= isin_a ? porta_din : latch_a; - 2'd1: dout <= isin_b ? portb_din : latch_b; - 2'd2: begin // Port C output depends on the mode - dout[7:4] <= isin_ch ? portc_din[7:4] : latch_c[7:4]; - dout[3:0] <= isin_cl ? portc_din[3:0] : latch_c[3:0]; - // Special modes - if( mode_b ) - dout[2:0] <= { ackb, latch_c[1:0] }; - if( mode_a!=0 ) - dout[3] <= latch_c[INTRA]; - if( (mode_a[0] && !isin_a) || mode_a[1] ) - dout[5:4] <= { acka, latch_c[4] }; - if( (mode_a[0] && isin_a) || mode_a[1] ) - dout[7:6] <= { latch_c[OBFA], acka }; - end - 2'd3: dout <= { 1'b1, ctrl }; - endcase - end - end -end - -// Output port registers -assign portc_dout = latch_c; - -always @(posedge clk) begin - porta_dout <= isin_a ? porta_din : latch_a; - portb_dout <= isin_b ? portb_din : latch_b; -end - +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// JT8255 +// Programmable peripheral interface compatible with Intel 8255 +// +// Copyright (c) 2021, Jose Tejada Gomez <@topapate> +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ + +module jt8255( + input rst, + input clk, + + // CPU interface + input [1:0] addr, + input [7:0] din, + output reg [7:0] dout, + input rdn, + input wrn, + input csn, + + // External pins to peripherals + input [7:0] porta_din, + input [7:0] portb_din, + input [7:0] portc_din, + + output reg [7:0] porta_dout, + output reg [7:0] portb_dout, + output [7:0] portc_dout +); + +localparam ISINA=4, ISINB=1, ISINCL=0, ISINCH=3; // Control word bits +localparam INTRA=3, OBFA=7, ACKA=6, STBA=4, IBFA=5, // PC bits, mode 2 + INTRB=0, OBFB=1, ACKB=2, STBB=2, IBFB=1; + +localparam INTEA_OBF=6, INTEA_IBF=4, INTEB=2; + +reg [6:0] ctrl; +reg [7:0] latch_a, latch_b, latch_c; + +wire mode_b, + isin_a, isin_b, isin_cl, isin_ch; // is input a,b,c... +wire [1:0] mode_a; + +wire write, read; +reg last_write, last_read; + +reg inte_a_obf, inte_a_ibf, inte_b; +wire acka, ackb, stba, stbb; + +reg last_acka, last_ackb, last_stba; +wire last_stbb; + +assign read = !rdn && !csn; +assign write = !wrn && !csn; +assign mode_b = ctrl[2]; +assign mode_a = ctrl[6:5]; + +assign isin_a = ctrl[ISINA]; +assign isin_b = ctrl[ISINB]; +assign isin_cl = ctrl[ISINCL]; +assign isin_ch = ctrl[ISINCH]; + +assign acka = portc_din[ACKA]; +assign stba = portc_din[STBA]; +assign ackb = portc_din[ACKB]; +assign stbb = portc_din[STBB]; // this is the same as ackb +assign last_stbb = last_ackb; + + +// Mode control +always @(posedge clk, posedge rst) begin + if( rst ) begin + ctrl <= 7'h1b; + latch_a <= 8'hff; + latch_b <= 8'hff; + latch_c <= 8'hff; + + inte_a_ibf <= 0; + inte_a_obf <= 0; + inte_b <= 0; + + last_write <= 0; + last_acka <= 0; + last_ackb <= 0; + last_stba <= 0; + end else begin + last_write <= write; + last_acka <= acka; + last_ackb <= ackb; + last_stba <= stba; + +// if( !write && last_write ) begin + if( write ) begin //Changed + case( addr ) + 2'd0: begin // Port A + if( !isin_a || mode_a[1] ) begin + latch_a <= din; // A is an output + if( mode_a!=0 ) begin + latch_c[OBFA] <= 0; + if(inte_a_obf) latch_c[INTRA] <= 0; // interrupt pin + end + end + end + 2'd1: begin // Port B + if( !isin_b ) begin + latch_b <= din; // B is an output + if( mode_b ) begin + latch_c[OBFB] <= 0; + if(inte_b) latch_c[INTRB] <= 0; // interrupt pin + end + end end + 2'd2: begin + if( mode_b ) + inte_b <= din[INTEB]; + else + latch_c[2:0] <= din[2:0]; + + if( (mode_a==0 || (mode_a[0]&&isin_a)) ) + latch_c[7:6] <= din[7:6]; + + if( mode_a==0 || (mode_a[0]&&!isin_a) ) + latch_c[5:4] <= din[5:4]; + + if( mode_a==0 ) + latch_c[3] <= din[3]; + + if( mode_a[1] || (mode_a[0] && isin_a) ) + inte_a_ibf <= din[INTEA_IBF]; + if( mode_a[1] || (mode_a[0] && !isin_a) ) + inte_a_obf <= din[INTEA_OBF]; + end + 2'd3: begin + if( din[7] ) begin + ctrl <= din[6:0]; + if( !din[ISINCL] ) latch_c[3:0] <= 0; + if( !din[ISINCH] ) latch_c[7:4] <= 0; + if( !din[ISINB] ) latch_b <= 0; + if( !din[ISINA] ) latch_a <= 0; + inte_a_ibf <= 0; + inte_a_obf <= 0; + inte_b <= 0; + if( din[2] ) begin + latch_c[IBFB] <= ~din[ISINB]; // start with safe IBF/OBF signals + latch_c[INTRB]<= ~din[ISINB]; + end + if( din[6:5]!=0 ) begin + latch_c[IBFA] <= 0; + latch_c[OBFA] <= 1; + latch_c[INTRA]<= 0; + end + end else begin + latch_c[ din[3:1] ] <= din[0]; + if( din[3:1]==INTEA_OBF ) inte_a_obf <= din[0]; + if( din[3:1]==INTEA_IBF ) inte_a_ibf <= din[0]; + if( din[3:1]==INTEB ) inte_b <= din[0]; + end + end + endcase + end else begin + // Input Buffer Full + if( mode_b && isin_b && stbb && !last_stbb ) begin + latch_c[IBFB] <= 1; + if( inte_b ) latch_c[INTRB] <= 1; + end + if( (mode_a[1] || (mode_a[0] && isin_a)) && stba && !last_stba ) begin + latch_c[IBFA] <= 1; + if( inte_a_ibf ) latch_c[INTRA] <= 1; + end + + if( mode_a!=2'd00 ) begin + // clears the interrupts + if(!inte_a_ibf && !inte_a_obf) latch_c[INTRA] <= 0; //Changed + // The peripheral reads + if( (!isin_a || mode_a[1]) && acka && !last_acka ) begin + latch_c[INTRA] <= 1; + latch_c[OBFA] <= 1; + end + // The CPU reads + if( (isin_a || mode_a[1]) && read && !last_read && addr==2'd0 ) begin + latch_c[INTRA] <= 0; + latch_c[IBFA] <= 0; + end + end + if( mode_b ) begin + // clears the interrupts + if(!inte_b) latch_c[INTRB] <= 0; //Changed + // The peripheral reads + if( !isin_b && ackb && !last_ackb ) begin + latch_c[INTRB] <= 1; + latch_c[OBFB] <= 1; + end + // The CPU reads + if( isin_b && read && !last_read && addr==2'd1 ) begin + latch_c[INTRB] <= 0; + latch_c[IBFB] <= 0; + end + end + end + end +end + +// CPU interface +always @(posedge clk, posedge rst) begin + if( rst ) begin + dout <= 8'hff; + last_read <= 0; + end else begin + last_read <= read; + if( read ) begin + case( addr ) + 2'd0: dout <= isin_a ? porta_din : latch_a; + 2'd1: dout <= isin_b ? portb_din : latch_b; + 2'd2: begin // Port C output depends on the mode + dout[7:4] <= isin_ch ? portc_din[7:4] : latch_c[7:4]; + dout[3:0] <= isin_cl ? portc_din[3:0] : latch_c[3:0]; + // Special modes + if( mode_b ) + dout[2:0] <= { ackb, latch_c[1:0] }; + if( mode_a!=0 ) + dout[3] <= latch_c[INTRA]; + if( (mode_a[0] && !isin_a) || mode_a[1] ) + dout[5:4] <= { acka, latch_c[4] }; + if( (mode_a[0] && isin_a) || mode_a[1] ) + dout[7:6] <= { latch_c[OBFA], acka }; + end + 2'd3: dout <= { 1'b1, ctrl }; + endcase + end + end +end + +// Output port registers +assign portc_dout = latch_c; + +always @(posedge clk) begin + porta_dout <= isin_a ? porta_din : latch_a; + portb_dout <= isin_b ? portb_din : latch_b; +end + endmodule \ No newline at end of file diff --git a/rtl/keyboard.vhd b/rtl/keyboard.vhd index d25cba6..64787bb 100644 --- a/rtl/keyboard.vhd +++ b/rtl/keyboard.vhd @@ -1,173 +1,173 @@ --------------------------------------------------------------------------------- --- SPDX-License-Identifier: GPL-3.0-or-later --- SPDX-FileType: SOURCE --- SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors --------------------------------------------------------------------------------- --- --- MSX Compatible Gateware IP Core --- Keyboard Matrix Maping --- --- Copyright (c) 2021, Molekula <@tdlabac> --- --- 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, version 3. --- --- 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 . --- --------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use IEEE.numeric_std.all; - -entity keyboard is - port ( - reset_n_i : in std_logic; - clk_i : in std_logic; - ps2_code_i : in std_logic_vector(10 downto 0); - kb_addr_i : in std_logic_vector(3 downto 0); - kb_data_o : out std_logic_vector(7 downto 0) - ); -end keyboard; -architecture rtl of keyboard is - type keyMatrixType is array(8 downto 0) of std_logic_vector(7 downto 0); - signal keyMatrix : keyMatrixType := (others => (others => '1')); - signal scancode : std_logic_vector(7 downto 0); - signal changed : std_logic := '0'; - signal release : std_logic := '1'; - signal shift : std_logic_vector(1 downto 0) := (others => '1'); - -begin - kb_data_o <= keyMatrix(to_integer(unsigned(kb_addr_i)))(7 downto 0) when to_integer(unsigned(kb_addr_i)) < 9 else (others => '1'); - - change : process (clk_i) - variable old_code : std_logic_vector(10 downto 0) := (others => '0'); - begin - if clk_i'event and clk_i = '1' then - if old_code /= ps2_code_i then - release <= not ps2_code_i(9); - scancode <= ps2_code_i(7 downto 0); - changed <= '1'; - else - changed <= '0'; - end if; - old_code := ps2_code_i; - end if; - end process; - - decode : process (clk_i) - begin - if clk_i'event and clk_i = '1' then - if changed = '1' then - if ps2_code_i(8) = '0' then - case scancode is - -- 0 - when x"45" => keyMatrix(0)(0) <= release; -- 0 - when x"16" => keyMatrix(0)(1) <= release; -- 1 - when x"1e" => keyMatrix(0)(2) <= release; -- 2 - when x"26" => keyMatrix(0)(3) <= release; -- 3 - when x"25" => keyMatrix(0)(4) <= release; -- 4 - when x"2e" => keyMatrix(0)(5) <= release; -- 5 - when x"36" => keyMatrix(0)(6) <= release; -- 6 - when x"3d" => keyMatrix(0)(7) <= release; -- 7 - -- 1 - when x"3e" => keyMatrix(1)(0) <= release; -- 8 - when x"46" => keyMatrix(1)(1) <= release; -- 9 - when x"4e" => keyMatrix(1)(2) <= release; -- - - when x"55" => keyMatrix(1)(3) <= release; -- = - when x"5d" => keyMatrix(1)(4) <= release; -- \ - when x"54" => keyMatrix(1)(5) <= release; -- [ - when x"5b" => keyMatrix(1)(6) <= release; -- ] - when x"4c" => keyMatrix(1)(7) <= release; -- ; - -- 2 - when x"52" => keyMatrix(2)(0) <= release; -- ' - when x"0e" => keyMatrix(2)(1) <= release; -- ` - when x"41" => keyMatrix(2)(2) <= release; -- , - when x"49" => keyMatrix(2)(3) <= release; -- . - when x"4a" => keyMatrix(2)(4) <= release; -- / - when x"01" => keyMatrix(2)(5) <= release; -- F11 (DEAD KEY) - when x"1c" => keyMatrix(2)(6) <= release; -- A - when x"32" => keyMatrix(2)(7) <= release; -- B - -- 3 - when x"21" => keyMatrix(3)(0) <= release; -- C - when x"23" => keyMatrix(3)(1) <= release; -- D - when x"24" => keyMatrix(3)(2) <= release; -- E - when x"2b" => keyMatrix(3)(3) <= release; -- F - when x"34" => keyMatrix(3)(4) <= release; -- G - when x"33" => keyMatrix(3)(5) <= release; -- H - when x"43" => keyMatrix(3)(6) <= release; -- I - when x"3b" => keyMatrix(3)(7) <= release; -- J - -- 4 - when x"42" => keyMatrix(4)(0) <= release; -- K - when x"4b" => keyMatrix(4)(1) <= release; -- L - when x"3a" => keyMatrix(4)(2) <= release; -- M - when x"31" => keyMatrix(4)(3) <= release; -- N - when x"44" => keyMatrix(4)(4) <= release; -- O - when x"4d" => keyMatrix(4)(5) <= release; -- P - when x"15" => keyMatrix(4)(6) <= release; -- Q - when x"2d" => keyMatrix(4)(7) <= release; -- R - -- 5 - when x"1b" => keyMatrix(5)(0) <= release; -- S - when x"2c" => keyMatrix(5)(1) <= release; -- T - when x"3c" => keyMatrix(5)(2) <= release; -- U - when x"2a" => keyMatrix(5)(3) <= release; -- V - when x"1d" => keyMatrix(5)(4) <= release; -- W - when x"22" => keyMatrix(5)(5) <= release; -- X - when x"35" => keyMatrix(5)(6) <= release; -- Y - when x"1a" => keyMatrix(5)(7) <= release; -- Z - -- 6 - when x"12" => shift(0) <= release; -- LEFT SHIFT - when x"59" => shift(1) <= release; -- RIGHT SHIFT - when x"14" => keyMatrix(6)(1) <= release; -- LEFT CTRL - -- when x"11" => keyMatrix(6)(2) <= release; -- RIGHT ALT (GRAPH) - when x"58" => keyMatrix(6)(3) <= release; -- CAPS LOCK - when x"09" => keyMatrix(6)(4) <= release; -- F10 (CODE) - when x"05" => keyMatrix(6)(5) <= release; -- F1 - when x"06" => keyMatrix(6)(6) <= release; -- F2 - when x"04" => keyMatrix(6)(7) <= release; -- F3 - -- 7 - when x"0c" => keyMatrix(7)(0) <= release; -- F4 - when x"03" => keyMatrix(7)(1) <= release; -- F5 - when x"76" => keyMatrix(7)(2) <= release; -- ESC - when x"0D" => keyMatrix(7)(3) <= release; -- TAB - -- when x"E1" => keyMatrix(7)(4) <= release; -- pause/break (STOP) - when x"66" => keyMatrix(7)(5) <= release; -- BACKSPACE - when x"78" => keyMatrix(7)(6) <= release; -- F11 (SELECT) - when x"5a" => keyMatrix(7)(7) <= release; -- ENTER - -- 8 - when x"29" => keyMatrix(8)(0) <= release; -- SPACE - -- when x"6c" => keyMatrix(8)(1) <= release; -- HOME - -- when x"70" => keyMatrix(8)(2) <= release; -- INS - -- when x"71" => keyMatrix(8)(3) <= release; -- DEL - -- when x"6B" => keyMatrix(8)(4) <= release; -- LEFT ARROW - -- when x"75" => keyMatrix(8)(5) <= release; -- UP ARROW - -- when x"72" => keyMatrix(8)(6) <= release; -- DOWN ARROW - -- when x"74" => keyMatrix(8)(7) <= release; -- RIGH ARROW - when others => null; - end case; - else - case scancode is - when x"11" => keyMatrix(6)(2) <= release; -- RIGHT ALT (GRAPH) - when x"7c" => keyMatrix(7)(4) <= release; -- Print Screen (STOP) - when x"6c" => keyMatrix(8)(1) <= release; -- HOME - when x"70" => keyMatrix(8)(2) <= release; -- INS - when x"71" => keyMatrix(8)(3) <= release; -- DEL - when x"6B" => keyMatrix(8)(4) <= release; -- LEFT ARROW - when x"75" => keyMatrix(8)(5) <= release; -- UP ARROW - when x"72" => keyMatrix(8)(6) <= release; -- DOWN ARROW - when x"74" => keyMatrix(8)(7) <= release; -- RIGH ARROW - when others => null; - end case; - end if; - end if; - end if; - keyMatrix(6)(0) <= shift(0) and shift(1); - end process; -end; +-------------------------------------------------------------------------------- +-- SPDX-License-Identifier: GPL-3.0-or-later +-- SPDX-FileType: SOURCE +-- SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +-------------------------------------------------------------------------------- +-- +-- MSX Compatible Gateware IP Core +-- Keyboard Matrix Maping +-- +-- Copyright (c) 2021, Molekula <@tdlabac> +-- +-- 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, version 3. +-- +-- 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 . +-- +-------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use IEEE.numeric_std.all; + +entity keyboard is + port ( + reset_n_i : in std_logic; + clk_i : in std_logic; + ps2_code_i : in std_logic_vector(10 downto 0); + kb_addr_i : in std_logic_vector(3 downto 0); + kb_data_o : out std_logic_vector(7 downto 0) + ); +end keyboard; +architecture rtl of keyboard is + type keyMatrixType is array(8 downto 0) of std_logic_vector(7 downto 0); + signal keyMatrix : keyMatrixType := (others => (others => '1')); + signal scancode : std_logic_vector(7 downto 0); + signal changed : std_logic := '0'; + signal release : std_logic := '1'; + signal shift : std_logic_vector(1 downto 0) := (others => '1'); + +begin + kb_data_o <= keyMatrix(to_integer(unsigned(kb_addr_i)))(7 downto 0) when to_integer(unsigned(kb_addr_i)) < 9 else (others => '1'); + + change : process (clk_i) + variable old_code : std_logic_vector(10 downto 0) := (others => '0'); + begin + if clk_i'event and clk_i = '1' then + if old_code /= ps2_code_i then + release <= not ps2_code_i(9); + scancode <= ps2_code_i(7 downto 0); + changed <= '1'; + else + changed <= '0'; + end if; + old_code := ps2_code_i; + end if; + end process; + + decode : process (clk_i) + begin + if clk_i'event and clk_i = '1' then + if changed = '1' then + if ps2_code_i(8) = '0' then + case scancode is + -- 0 + when x"45" => keyMatrix(0)(0) <= release; -- 0 + when x"16" => keyMatrix(0)(1) <= release; -- 1 + when x"1e" => keyMatrix(0)(2) <= release; -- 2 + when x"26" => keyMatrix(0)(3) <= release; -- 3 + when x"25" => keyMatrix(0)(4) <= release; -- 4 + when x"2e" => keyMatrix(0)(5) <= release; -- 5 + when x"36" => keyMatrix(0)(6) <= release; -- 6 + when x"3d" => keyMatrix(0)(7) <= release; -- 7 + -- 1 + when x"3e" => keyMatrix(1)(0) <= release; -- 8 + when x"46" => keyMatrix(1)(1) <= release; -- 9 + when x"4e" => keyMatrix(1)(2) <= release; -- - + when x"55" => keyMatrix(1)(3) <= release; -- = + when x"5d" => keyMatrix(1)(4) <= release; -- \ + when x"54" => keyMatrix(1)(5) <= release; -- [ + when x"5b" => keyMatrix(1)(6) <= release; -- ] + when x"4c" => keyMatrix(1)(7) <= release; -- ; + -- 2 + when x"52" => keyMatrix(2)(0) <= release; -- ' + when x"0e" => keyMatrix(2)(1) <= release; -- ` + when x"41" => keyMatrix(2)(2) <= release; -- , + when x"49" => keyMatrix(2)(3) <= release; -- . + when x"4a" => keyMatrix(2)(4) <= release; -- / + when x"01" => keyMatrix(2)(5) <= release; -- F11 (DEAD KEY) + when x"1c" => keyMatrix(2)(6) <= release; -- A + when x"32" => keyMatrix(2)(7) <= release; -- B + -- 3 + when x"21" => keyMatrix(3)(0) <= release; -- C + when x"23" => keyMatrix(3)(1) <= release; -- D + when x"24" => keyMatrix(3)(2) <= release; -- E + when x"2b" => keyMatrix(3)(3) <= release; -- F + when x"34" => keyMatrix(3)(4) <= release; -- G + when x"33" => keyMatrix(3)(5) <= release; -- H + when x"43" => keyMatrix(3)(6) <= release; -- I + when x"3b" => keyMatrix(3)(7) <= release; -- J + -- 4 + when x"42" => keyMatrix(4)(0) <= release; -- K + when x"4b" => keyMatrix(4)(1) <= release; -- L + when x"3a" => keyMatrix(4)(2) <= release; -- M + when x"31" => keyMatrix(4)(3) <= release; -- N + when x"44" => keyMatrix(4)(4) <= release; -- O + when x"4d" => keyMatrix(4)(5) <= release; -- P + when x"15" => keyMatrix(4)(6) <= release; -- Q + when x"2d" => keyMatrix(4)(7) <= release; -- R + -- 5 + when x"1b" => keyMatrix(5)(0) <= release; -- S + when x"2c" => keyMatrix(5)(1) <= release; -- T + when x"3c" => keyMatrix(5)(2) <= release; -- U + when x"2a" => keyMatrix(5)(3) <= release; -- V + when x"1d" => keyMatrix(5)(4) <= release; -- W + when x"22" => keyMatrix(5)(5) <= release; -- X + when x"35" => keyMatrix(5)(6) <= release; -- Y + when x"1a" => keyMatrix(5)(7) <= release; -- Z + -- 6 + when x"12" => shift(0) <= release; -- LEFT SHIFT + when x"59" => shift(1) <= release; -- RIGHT SHIFT + when x"14" => keyMatrix(6)(1) <= release; -- LEFT CTRL + -- when x"11" => keyMatrix(6)(2) <= release; -- RIGHT ALT (GRAPH) + when x"58" => keyMatrix(6)(3) <= release; -- CAPS LOCK + when x"09" => keyMatrix(6)(4) <= release; -- F10 (CODE) + when x"05" => keyMatrix(6)(5) <= release; -- F1 + when x"06" => keyMatrix(6)(6) <= release; -- F2 + when x"04" => keyMatrix(6)(7) <= release; -- F3 + -- 7 + when x"0c" => keyMatrix(7)(0) <= release; -- F4 + when x"03" => keyMatrix(7)(1) <= release; -- F5 + when x"76" => keyMatrix(7)(2) <= release; -- ESC + when x"0D" => keyMatrix(7)(3) <= release; -- TAB + -- when x"E1" => keyMatrix(7)(4) <= release; -- pause/break (STOP) + when x"66" => keyMatrix(7)(5) <= release; -- BACKSPACE + when x"78" => keyMatrix(7)(6) <= release; -- F11 (SELECT) + when x"5a" => keyMatrix(7)(7) <= release; -- ENTER + -- 8 + when x"29" => keyMatrix(8)(0) <= release; -- SPACE + -- when x"6c" => keyMatrix(8)(1) <= release; -- HOME + -- when x"70" => keyMatrix(8)(2) <= release; -- INS + -- when x"71" => keyMatrix(8)(3) <= release; -- DEL + -- when x"6B" => keyMatrix(8)(4) <= release; -- LEFT ARROW + -- when x"75" => keyMatrix(8)(5) <= release; -- UP ARROW + -- when x"72" => keyMatrix(8)(6) <= release; -- DOWN ARROW + -- when x"74" => keyMatrix(8)(7) <= release; -- RIGH ARROW + when others => null; + end case; + else + case scancode is + when x"11" => keyMatrix(6)(2) <= release; -- RIGHT ALT (GRAPH) + when x"7c" => keyMatrix(7)(4) <= release; -- Print Screen (STOP) + when x"6c" => keyMatrix(8)(1) <= release; -- HOME + when x"70" => keyMatrix(8)(2) <= release; -- INS + when x"71" => keyMatrix(8)(3) <= release; -- DEL + when x"6B" => keyMatrix(8)(4) <= release; -- LEFT ARROW + when x"75" => keyMatrix(8)(5) <= release; -- UP ARROW + when x"72" => keyMatrix(8)(6) <= release; -- DOWN ARROW + when x"74" => keyMatrix(8)(7) <= release; -- RIGH ARROW + when others => null; + end case; + end if; + end if; + end if; + keyMatrix(6)(0) <= shift(0) and shift(1); + end process; +end; diff --git a/rtl/ls74.sv b/rtl/ls74.sv index af8cb4f..f754a5b 100644 --- a/rtl/ls74.sv +++ b/rtl/ls74.sv @@ -1,40 +1,40 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX Compatible Gateware IP Core -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -module ls74 - ( - input wire clr, - input wire pre, - input wire clk, - input wire d, - output logic q - ); - - always_ff @(posedge clk, negedge clr, negedge pre) begin - if (!clr) q <= 1'b0; - else if (!pre) q <= 1'b1; - else q <= d; - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX Compatible Gateware IP Core +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +module ls74 + ( + input wire clr, + input wire pre, + input wire clk, + input wire d, + output logic q + ); + + always_ff @(posedge clk, negedge clr, negedge pre) begin + if (!clr) q <= 1'b0; + else if (!pre) q <= 1'b1; + else q <= d; + end + +endmodule diff --git a/rtl/memory_mapper.v b/rtl/memory_mapper.v index 971fefa..646312f 100644 --- a/rtl/memory_mapper.v +++ b/rtl/memory_mapper.v @@ -1,76 +1,76 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX Compatible Gateware IP Core -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -module memory_mapper - ( - input reset, - input ppi_n, - input [15:0] addr, - input [7:0] RAM_CS, - input mreq_n, - input rfrsh_n, - input rd_n, - output [3:0] SLTSL_n, - output CS1_n, - output CS01_n, - output CS12_n, - output CS2_n - ); - - wire ppi_en = ~ppi_n; - reg enable; - - initial begin - enable = 0; - end - - always @(posedge reset, posedge ppi_en) begin - if (reset) begin - enable = 0; - end - else if (ppi_en) begin - enable = 1; - end - end - - wire selmem = ~mreq_n & rfrsh_n; - - wire [1:0] sel = {addr[15:14]}; - wire [1:0] CS_n = ~enable ? 2'b00 : - sel == 2'b00 ? RAM_CS[1:0] : - sel == 2'b01 ? RAM_CS[3:2] : - sel == 2'b10 ? RAM_CS[5:4] : RAM_CS[7:6]; - - assign SLTSL_n[0] = ~(CS_n == 2'b00 & selmem); - assign SLTSL_n[1] = ~(CS_n == 2'b01 & selmem); - assign SLTSL_n[2] = ~(CS_n == 2'b10 & selmem); - assign SLTSL_n[3] = ~(CS_n == 2'b11 & selmem); - - wire CS0_n = ~(addr[15:14] == 2'b00 & ~rd_n); - assign CS1_n = ~(addr[15:14] == 2'b01 & ~rd_n); - assign CS2_n = ~(addr[15:14] == 2'b10 & ~rd_n); - assign CS01_n = CS0_n & CS1_n; - assign CS12_n = CS1_n & CS2_n; - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX Compatible Gateware IP Core +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +module memory_mapper + ( + input reset, + input ppi_n, + input [15:0] addr, + input [7:0] RAM_CS, + input mreq_n, + input rfrsh_n, + input rd_n, + output [3:0] SLTSL_n, + output CS1_n, + output CS01_n, + output CS12_n, + output CS2_n + ); + + wire ppi_en = ~ppi_n; + reg enable; + + initial begin + enable = 0; + end + + always @(posedge reset, posedge ppi_en) begin + if (reset) begin + enable = 0; + end + else if (ppi_en) begin + enable = 1; + end + end + + wire selmem = ~mreq_n & rfrsh_n; + + wire [1:0] sel = {addr[15:14]}; + wire [1:0] CS_n = ~enable ? 2'b00 : + sel == 2'b00 ? RAM_CS[1:0] : + sel == 2'b01 ? RAM_CS[3:2] : + sel == 2'b10 ? RAM_CS[5:4] : RAM_CS[7:6]; + + assign SLTSL_n[0] = ~(CS_n == 2'b00 & selmem); + assign SLTSL_n[1] = ~(CS_n == 2'b01 & selmem); + assign SLTSL_n[2] = ~(CS_n == 2'b10 & selmem); + assign SLTSL_n[3] = ~(CS_n == 2'b11 & selmem); + + wire CS0_n = ~(addr[15:14] == 2'b00 & ~rd_n); + assign CS1_n = ~(addr[15:14] == 2'b01 & ~rd_n); + assign CS2_n = ~(addr[15:14] == 2'b10 & ~rd_n); + assign CS01_n = CS0_n & CS1_n; + assign CS12_n = CS1_n & CS2_n; + +endmodule diff --git a/rtl/msx1.sv b/rtl/msx1.sv index c99edf3..c553d03 100644 --- a/rtl/msx1.sv +++ b/rtl/msx1.sv @@ -1,447 +1,447 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX Compatible Gateware IP Core -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -module msx1 - ( - input clk, - input ce_10m7, - input reset, - input border, - // Video - output [7:0] R, - output [7:0] G, - output [7:0] B, - output hsync_n, - output vsync_n, - output hblank, - output vblank, - input vdp_pal, - // Audio - output [15:0] audio, - // Keyboard - input [10:0] ps2_key, - // Gamepad/Joystick - input [5:0] joy0, - input [5:0] joy1, - // I/O Controller - input ioctl_download, - input [7:0] ioctl_index, - input ioctl_wr, - input [24:0] ioctl_addr, - input [7:0] ioctl_dout, - input ioctl_isROMA, - input ioctl_isROMB, - input ioctl_isBIOS, - input ioctl_isFWBIOS, - output ioctl_wait, - // Cassette - output cas_motor, - input cas_audio_in, - // User Mode - input [1:0] rom_enabled, - input [3:0] slot_A, - input [3:0] slot_B, - output [2:0] mapper_info, - // SDRAM - input [7:0] sdram_dout, - output [7:0] sdram_din, - output [24:0] sdram_addr, - output sdram_we, - output sdram_rd, - input sdram_ready, - input [1:0] sdram_size, - // VHD Image - input img_mounted, - input [31:0] img_size, - input img_wp, - output [31:0] sd_lba, - output sd_rd, - output sd_wr, - input sd_ack, - input [8:0] sd_buff_addr, - input [7:0] sd_buff_dout, - output [7:0] sd_buff_din, - input sd_buff_wr, - input sd_din_strobe - ); - - //-------------------------------------------------------------------------- - // Audio MIX - //-------------------------------------------------------------------------- - wire [9:0] audioPSG = ay_ch_mix + {keybeep, 5'b00000} + {(cas_audio_in & ~cas_motor), 4'b0000}; - wire [15:0] fm = {2'b0, audioPSG, 4'b0000}; - wire [16:0] audio_mix = {sound_slots[15], sound_slots} + {fm[15], fm}; - wire [15:0] compr[7:0] = '{{1'b1, audio_mix[13:0], 1'b0}, 16'h8000, 16'h8000, 16'h8000, 16'h7FFF, 16'h7FFF, 16'h7FFF, {1'b0, audio_mix[13:0], 1'b0}}; - - assign audio = compr[audio_mix[16:14]]; - - //-------------------------------------------------------------------------- - // Clock generation - //-------------------------------------------------------------------------- - wire clk_en_3m58_p, clk_en_3m58_n; - - cv_clock clock - ( - .clk_i ( clk ), - .clk_en_10m7_i ( ce_10m7 ), - .reset_n_i ( ~reset ), - .clk_en_3m58_p_o ( clk_en_3m58_p ), - .clk_en_3m58_n_o ( clk_en_3m58_n ) - ); - - //-------------------------------------------------------------------------- - // Z80 CPU - //-------------------------------------------------------------------------- - wire [15:0] a; - wire [7:0] d_to_cpu, d_from_cpu; - wire mreq_n, wr_n, m1_n, iorq_n, rd_n, rfrsh_n, wait_n; - - t80pa #(.Mode(0)) u_t80 - ( - .RESET_n ( ~reset ), - .CLK ( clk ), - .CEN_p ( clk_en_3m58_p ), - .CEN_n ( clk_en_3m58_n ), - .WAIT_n ( wait_n ), - .INT_n ( vdp_int_n ), - .NMI_n ( 1 ), - .BUSRQ_n ( 1 ), - .M1_n ( m1_n ), - .MREQ_n ( mreq_n ), - .IORQ_n ( iorq_n ), - .RD_n ( rd_n ), - .WR_n ( wr_n ), - .RFSH_n ( rfrsh_n ), - .HALT_n ( 1 ), - .BUSAK_n ( ), - .A ( a ), - .DI ( d_to_cpu ), - .DO ( d_from_cpu ) - ); - - //-------------------------------------------------------------------------- - // WAIT - //-------------------------------------------------------------------------- - wire u1_2_q; - wire exwait_n = 1; - reg wait_n2; - - ls74 u1_1 - ( - .clr ( exwait_n ), - .pre ( u1_2_q ), - .clk ( clk_en_3m58_p ), - .d ( m1_n ), - .q ( wait_n ) - ); - - ls74 u1_2 - ( - .clr ( 1 ), - .pre ( exwait_n ), - .clk ( clk_en_3m58_p ), - .d ( wait_n ), - .q ( u1_2_q ) - ); - - //-------------------------------------------------------------------------- - // BIOS ROM - //-------------------------------------------------------------------------- - wire [7:0] rom_q; - wire [7:0] fw_rom_q; - - spram #(.addr_width(15), .mem_init_file("rom/cbios_main_msx1.mif"), .mem_name("ROM")) rom - ( - .clock ( clk ), - .address ( ioctl_isBIOS ? ioctl_addr[14:0] : a[14:0] ), - .q ( rom_q ), - .wren ( ioctl_isBIOS ), - .data ( ioctl_dout ) - ); - - spram #(.addr_width(14), .mem_name("FWROM")) fw_rom - ( - .clock ( clk ), - .address ( ioctl_isFWBIOS ? ioctl_addr[13:0] : a[13:0] ), - .q ( fw_rom_q ), - .wren ( ioctl_isFWBIOS ), - .data ( ioctl_dout ) - ); - - //-------------------------------------------------------------------------- - // Video RAM 16k - //-------------------------------------------------------------------------- - wire [13:0] vram_a; - wire [7:0] vram_do; - wire [7:0] vram_di; - wire vram_we; - - spram #(.addr_width(14),.mem_name("VRAM")) vram - ( - .clock ( clk ), - .address ( vram_a ), - .wren ( vram_we ), - .data ( vram_do ), - .q ( vram_di ) - ); - - //-------------------------------------------------------------------------- - // TMS9928A Video Display Processor - //-------------------------------------------------------------------------- - wire [7:0] d_from_vdp; - wire vdp_int_n; - - vdp18_core #(.compat_rgb_g(0)) vdp18 - ( - .clk_i ( clk ), - .clk_en_10m7_i ( ce_10m7 ), - .reset_n_i ( ~reset ), - - .csr_n_i ( vdp_n | rd_n ), - .csw_n_i ( vdp_n | wr_n ), - .mode_i ( a[0] ), - .int_n_o ( vdp_int_n ), - .cd_i ( d_from_cpu ), - .cd_o ( d_from_vdp ), - - .vram_we_o ( vram_we ), - .vram_a_o ( vram_a ), - .vram_d_o ( vram_do ), - .vram_d_i ( vram_di ), - - .border_i ( border ), - .is_pal_i ( vdp_pal ), - .rgb_r_o ( R ), - .rgb_g_o ( G ), - .rgb_b_o ( B ), - .hsync_n_o ( hsync_n ), - .vsync_n_o ( vsync_n ), - .hblank_o ( hblank ), - .vblank_o ( vblank ), - ); - - //-------------------------------------------------------------------------- - // IO Decoder - //-------------------------------------------------------------------------- - wire vdp_n, psg_n, ppi_n, cen_n; - - io_decoder io_decoder - ( - .addr ( a ), - .iorq_n ( iorq_n ), - .m1_n ( m1_n ), - .vdp_n ( vdp_n ), - .psg_n ( psg_n ), - .ppi_n ( ppi_n ), - .cen_n ( cen_n ) - ); - - //-------------------------------------------------------------------------- - // 82C55 PPI - //-------------------------------------------------------------------------- - wire [7:0] d_from_8255; - wire [7:0] ppi_out_a, ppi_out_c; - wire keybeep = ppi_out_c[7]; - - assign cas_motor = ppi_out_c[4]; - - jt8255 PPI - ( - .rst ( reset ), - .clk ( clk ), - .addr ( a[1:0] ), - .din ( d_from_cpu ), - .dout ( d_from_8255 ), - .rdn ( rd_n ), - .wrn ( wr_n ), - .csn ( ppi_n ), - - .porta_din ( 8'h0 ), - .portb_din ( d_from_kb ), - .portc_din ( 8'h0 ), - - .porta_dout ( ppi_out_a ), - .portb_dout ( ), - .portc_dout ( ppi_out_c ) - ); - - //-------------------------------------------------------------------------- - // Memory mapper - //-------------------------------------------------------------------------- - wire [3:0] SLTSL_n; - wire CS1_n, CS01_n, CS12_n, CS2_n; - - memory_mapper memory_mapper - ( - .reset ( reset ), - .addr ( a ), - .ppi_n ( ppi_n ), - .RAM_CS ( ppi_out_a ), - .mreq_n ( mreq_n ), - .rfrsh_n ( rfrsh_n ), - .rd_n ( rd_n ), - .SLTSL_n ( SLTSL_n ), - .CS1_n ( CS1_n ), - .CS01_n ( CS01_n ), - .CS12_n ( CS12_n ), - .CS2_n ( CS2_n ) - ); - - //-------------------------------------------------------------------------- - // CPU data multiplex - //-------------------------------------------------------------------------- - assign d_to_cpu = ~(CS01_n | SLTSL_n[0]) ? rom_q : - ~(CS2_n | SLTSL_n[0]) ? fw_rom_q : - ~(SLTSL_n[1]) ? d_from_slots : - ~(SLTSL_n[2]) ? d_from_slots : - ~(SLTSL_n[3]) ? d_from_slots : - ~(vdp_n | rd_n) ? d_from_vdp : - ~(psg_n | rd_n) ? d_from_psg : - ~(ppi_n | rd_n) ? d_from_8255 : - 8'hFF; - - //-------------------------------------------------------------------------- - // Keyboard decoder - //-------------------------------------------------------------------------- - wire [7:0] d_from_kb; - - keyboard msx_key - ( - .reset_n_i ( ~reset ), - .clk_i ( clk ), - .ps2_code_i ( ps2_key ), - .kb_addr_i ( ppi_out_c[3:0] ), - .kb_data_o ( d_from_kb ) - ); - - //-------------------------------------------------------------------------- - // Sound AY-3-8910 - //-------------------------------------------------------------------------- - wire [7:0] d_from_psg, psg_ioa, psg_iob; - wire [5:0] joy_a = psg_iob[4] ? 6'b111111 : {~joy0[5], ~joy0[4], ~joy0[0], ~joy0[1], ~joy0[2], ~joy0[3]}; - wire [5:0] joy_b = psg_iob[5] ? 6'b111111 : {~joy1[5], ~joy1[4], ~joy1[0], ~joy1[1], ~joy1[2], ~joy1[3]}; - wire [5:0] joyA = joy_a & {psg_iob[0], psg_iob[1], 4'b1111}; - wire [5:0] joyB = joy_b & {psg_iob[2], psg_iob[3], 4'b1111}; - - assign psg_ioa = {cas_audio_in,1'b0, psg_iob[6] ? joyB : joyA}; - - wire [9:0] ay_ch_mix; - - wire u21_1_q; - ls74 u21_1 - ( - .clr ( !psg_n ), - .pre ( 1 ), - .clk ( clk_en_3m58_p ), - .d ( !psg_n ), - .q ( u21_1_q ) - ); - - wire u21_2_q; - ls74 u21_2 - ( - .clr ( !psg_n ), - .pre ( 1 ), - .clk ( clk_en_3m58_p ), - .d ( u21_1_q ), - .q ( u21_2_q ) - ); - - wire psg_e = !(!u21_2_q | clk_en_3m58_p) | psg_n; - wire psg_bc = !(a[0] | psg_e); - wire psg_bdir = !(a[1] | psg_e); - - jt49_bus PSG - ( - .rst_n ( ~reset ), - .clk ( clk ), - .clk_en ( clk_en_3m58_n ), - .bdir ( psg_bdir ), - .bc1 ( psg_bc ), - .din ( d_from_cpu ), - .sel ( 0 ), - .dout ( d_from_psg ), - .sound ( ay_ch_mix ), - .A ( ), - .B ( ), - .C ( ), - .IOA_in ( psg_ioa ), - .IOA_out ( ), - .IOB_in ( 8'hFF ), - .IOB_out ( psg_iob ) - ); - - //-------------------------------------------------------------------------- - // SLOTS - //-------------------------------------------------------------------------- - wire [7:0] d_from_slots; - wire [15:0] sound_slots; - - slots slots - ( - .clk ( clk ), - .clk_en ( clk_en_3m58_p ), - .reset ( reset ), - .addr ( a ), - .wr_n ( wr_n ), - .rd_n ( rd_n ), - .CS1_n ( CS1_n ), - .CS2_n ( CS2_n ), - .CS12_n ( CS12_n ), - .SLTSL_n ( SLTSL_n ), - .d_from_cpu ( d_from_cpu ), - .d_to_cpu ( d_from_slots ), - .sound ( sound_slots ), - .ioctl_wr ( ioctl_wr ), - .ioctl_addr ( ioctl_addr ), - .ioctl_dout ( ioctl_dout ), - .ioctl_isROMA ( ioctl_isROMA ), - .ioctl_isROMB ( ioctl_isROMB ), - .ioctl_wait ( ioctl_wait ), - .sdram_dout ( sdram_dout ), - .sdram_din ( sdram_din ), - .sdram_addr ( sdram_addr ), - .sdram_we ( sdram_we ), - .sdram_rd ( sdram_rd ), - .sdram_ready ( sdram_ready ), - .sdram_size ( sdram_size ), - .slot_A ( slot_A ), - .slot_B ( slot_B ), - .mapper_info ( mapper_info ), - .rom_enabled ( rom_enabled ), - .img_mounted ( img_mounted ), - .img_size ( img_size ), - .img_wp ( img_wp ), - .sd_lba ( sd_lba ), - .sd_rd ( sd_rd ), - .sd_wr ( sd_wr ), - .sd_ack ( sd_ack ), - .sd_buff_addr ( sd_buff_addr ), - .sd_buff_dout ( sd_buff_dout ), - .sd_buff_din ( sd_buff_din ), - .sd_buff_wr ( sd_buff_wr ), - .sd_din_strobe ( sd_din_strobe ) - ); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX Compatible Gateware IP Core +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +module msx1 + ( + input clk, + input ce_10m7, + input reset, + input border, + // Video + output [7:0] R, + output [7:0] G, + output [7:0] B, + output hsync_n, + output vsync_n, + output hblank, + output vblank, + input vdp_pal, + // Audio + output [15:0] audio, + // Keyboard + input [10:0] ps2_key, + // Gamepad/Joystick + input [5:0] joy0, + input [5:0] joy1, + // I/O Controller + input ioctl_download, + input [7:0] ioctl_index, + input ioctl_wr, + input [24:0] ioctl_addr, + input [7:0] ioctl_dout, + input ioctl_isROMA, + input ioctl_isROMB, + input ioctl_isBIOS, + input ioctl_isFWBIOS, + output ioctl_wait, + // Cassette + output cas_motor, + input cas_audio_in, + // User Mode + input [1:0] rom_enabled, + input [3:0] slot_A, + input [3:0] slot_B, + output [2:0] mapper_info, + // SDRAM + input [7:0] sdram_dout, + output [7:0] sdram_din, + output [24:0] sdram_addr, + output sdram_we, + output sdram_rd, + input sdram_ready, + input [1:0] sdram_size, + // VHD Image + input img_mounted, + input [31:0] img_size, + input img_wp, + output [31:0] sd_lba, + output sd_rd, + output sd_wr, + input sd_ack, + input [8:0] sd_buff_addr, + input [7:0] sd_buff_dout, + output [7:0] sd_buff_din, + input sd_buff_wr, + input sd_din_strobe + ); + + //-------------------------------------------------------------------------- + // Audio MIX + //-------------------------------------------------------------------------- + wire [9:0] audioPSG = ay_ch_mix + {keybeep, 5'b00000} + {(cas_audio_in & ~cas_motor), 4'b0000}; + wire [15:0] fm = {2'b0, audioPSG, 4'b0000}; + wire [16:0] audio_mix = {sound_slots[15], sound_slots} + {fm[15], fm}; + wire [15:0] compr[7:0] = '{{1'b1, audio_mix[13:0], 1'b0}, 16'h8000, 16'h8000, 16'h8000, 16'h7FFF, 16'h7FFF, 16'h7FFF, {1'b0, audio_mix[13:0], 1'b0}}; + + assign audio = compr[audio_mix[16:14]]; + + //-------------------------------------------------------------------------- + // Clock generation + //-------------------------------------------------------------------------- + wire clk_en_3m58_p, clk_en_3m58_n; + + cv_clock clock + ( + .clk_i ( clk ), + .clk_en_10m7_i ( ce_10m7 ), + .reset_n_i ( ~reset ), + .clk_en_3m58_p_o ( clk_en_3m58_p ), + .clk_en_3m58_n_o ( clk_en_3m58_n ) + ); + + //-------------------------------------------------------------------------- + // Z80 CPU + //-------------------------------------------------------------------------- + wire [15:0] a; + wire [7:0] d_to_cpu, d_from_cpu; + wire mreq_n, wr_n, m1_n, iorq_n, rd_n, rfrsh_n, wait_n; + + t80pa #(.Mode(0)) u_t80 + ( + .RESET_n ( ~reset ), + .CLK ( clk ), + .CEN_p ( clk_en_3m58_p ), + .CEN_n ( clk_en_3m58_n ), + .WAIT_n ( wait_n ), + .INT_n ( vdp_int_n ), + .NMI_n ( 1 ), + .BUSRQ_n ( 1 ), + .M1_n ( m1_n ), + .MREQ_n ( mreq_n ), + .IORQ_n ( iorq_n ), + .RD_n ( rd_n ), + .WR_n ( wr_n ), + .RFSH_n ( rfrsh_n ), + .HALT_n ( 1 ), + .BUSAK_n ( ), + .A ( a ), + .DI ( d_to_cpu ), + .DO ( d_from_cpu ) + ); + + //-------------------------------------------------------------------------- + // WAIT + //-------------------------------------------------------------------------- + wire u1_2_q; + wire exwait_n = 1; + reg wait_n2; + + ls74 u1_1 + ( + .clr ( exwait_n ), + .pre ( u1_2_q ), + .clk ( clk_en_3m58_p ), + .d ( m1_n ), + .q ( wait_n ) + ); + + ls74 u1_2 + ( + .clr ( 1 ), + .pre ( exwait_n ), + .clk ( clk_en_3m58_p ), + .d ( wait_n ), + .q ( u1_2_q ) + ); + + //-------------------------------------------------------------------------- + // BIOS ROM + //-------------------------------------------------------------------------- + wire [7:0] rom_q; + wire [7:0] fw_rom_q; + + spram #(.addr_width(15), .mem_init_file("rom/cbios_main_msx1.mif"), .mem_name("ROM")) rom + ( + .clock ( clk ), + .address ( ioctl_isBIOS ? ioctl_addr[14:0] : a[14:0] ), + .q ( rom_q ), + .wren ( ioctl_isBIOS ), + .data ( ioctl_dout ) + ); + + spram #(.addr_width(14), .mem_name("FWROM")) fw_rom + ( + .clock ( clk ), + .address ( ioctl_isFWBIOS ? ioctl_addr[13:0] : a[13:0] ), + .q ( fw_rom_q ), + .wren ( ioctl_isFWBIOS ), + .data ( ioctl_dout ) + ); + + //-------------------------------------------------------------------------- + // Video RAM 16k + //-------------------------------------------------------------------------- + wire [13:0] vram_a; + wire [7:0] vram_do; + wire [7:0] vram_di; + wire vram_we; + + spram #(.addr_width(14),.mem_name("VRAM")) vram + ( + .clock ( clk ), + .address ( vram_a ), + .wren ( vram_we ), + .data ( vram_do ), + .q ( vram_di ) + ); + + //-------------------------------------------------------------------------- + // TMS9928A Video Display Processor + //-------------------------------------------------------------------------- + wire [7:0] d_from_vdp; + wire vdp_int_n; + + vdp18_core #(.compat_rgb_g(0)) vdp18 + ( + .clk_i ( clk ), + .clk_en_10m7_i ( ce_10m7 ), + .reset_n_i ( ~reset ), + + .csr_n_i ( vdp_n | rd_n ), + .csw_n_i ( vdp_n | wr_n ), + .mode_i ( a[0] ), + .int_n_o ( vdp_int_n ), + .cd_i ( d_from_cpu ), + .cd_o ( d_from_vdp ), + + .vram_we_o ( vram_we ), + .vram_a_o ( vram_a ), + .vram_d_o ( vram_do ), + .vram_d_i ( vram_di ), + + .border_i ( border ), + .is_pal_i ( vdp_pal ), + .rgb_r_o ( R ), + .rgb_g_o ( G ), + .rgb_b_o ( B ), + .hsync_n_o ( hsync_n ), + .vsync_n_o ( vsync_n ), + .hblank_o ( hblank ), + .vblank_o ( vblank ), + ); + + //-------------------------------------------------------------------------- + // IO Decoder + //-------------------------------------------------------------------------- + wire vdp_n, psg_n, ppi_n, cen_n; + + io_decoder io_decoder + ( + .addr ( a ), + .iorq_n ( iorq_n ), + .m1_n ( m1_n ), + .vdp_n ( vdp_n ), + .psg_n ( psg_n ), + .ppi_n ( ppi_n ), + .cen_n ( cen_n ) + ); + + //-------------------------------------------------------------------------- + // 82C55 PPI + //-------------------------------------------------------------------------- + wire [7:0] d_from_8255; + wire [7:0] ppi_out_a, ppi_out_c; + wire keybeep = ppi_out_c[7]; + + assign cas_motor = ppi_out_c[4]; + + jt8255 PPI + ( + .rst ( reset ), + .clk ( clk ), + .addr ( a[1:0] ), + .din ( d_from_cpu ), + .dout ( d_from_8255 ), + .rdn ( rd_n ), + .wrn ( wr_n ), + .csn ( ppi_n ), + + .porta_din ( 8'h0 ), + .portb_din ( d_from_kb ), + .portc_din ( 8'h0 ), + + .porta_dout ( ppi_out_a ), + .portb_dout ( ), + .portc_dout ( ppi_out_c ) + ); + + //-------------------------------------------------------------------------- + // Memory mapper + //-------------------------------------------------------------------------- + wire [3:0] SLTSL_n; + wire CS1_n, CS01_n, CS12_n, CS2_n; + + memory_mapper memory_mapper + ( + .reset ( reset ), + .addr ( a ), + .ppi_n ( ppi_n ), + .RAM_CS ( ppi_out_a ), + .mreq_n ( mreq_n ), + .rfrsh_n ( rfrsh_n ), + .rd_n ( rd_n ), + .SLTSL_n ( SLTSL_n ), + .CS1_n ( CS1_n ), + .CS01_n ( CS01_n ), + .CS12_n ( CS12_n ), + .CS2_n ( CS2_n ) + ); + + //-------------------------------------------------------------------------- + // CPU data multiplex + //-------------------------------------------------------------------------- + assign d_to_cpu = ~(CS01_n | SLTSL_n[0]) ? rom_q : + ~(CS2_n | SLTSL_n[0]) ? fw_rom_q : + ~(SLTSL_n[1]) ? d_from_slots : + ~(SLTSL_n[2]) ? d_from_slots : + ~(SLTSL_n[3]) ? d_from_slots : + ~(vdp_n | rd_n) ? d_from_vdp : + ~(psg_n | rd_n) ? d_from_psg : + ~(ppi_n | rd_n) ? d_from_8255 : + 8'hFF; + + //-------------------------------------------------------------------------- + // Keyboard decoder + //-------------------------------------------------------------------------- + wire [7:0] d_from_kb; + + keyboard msx_key + ( + .reset_n_i ( ~reset ), + .clk_i ( clk ), + .ps2_code_i ( ps2_key ), + .kb_addr_i ( ppi_out_c[3:0] ), + .kb_data_o ( d_from_kb ) + ); + + //-------------------------------------------------------------------------- + // Sound AY-3-8910 + //-------------------------------------------------------------------------- + wire [7:0] d_from_psg, psg_ioa, psg_iob; + wire [5:0] joy_a = psg_iob[4] ? 6'b111111 : {~joy0[5], ~joy0[4], ~joy0[0], ~joy0[1], ~joy0[2], ~joy0[3]}; + wire [5:0] joy_b = psg_iob[5] ? 6'b111111 : {~joy1[5], ~joy1[4], ~joy1[0], ~joy1[1], ~joy1[2], ~joy1[3]}; + wire [5:0] joyA = joy_a & {psg_iob[0], psg_iob[1], 4'b1111}; + wire [5:0] joyB = joy_b & {psg_iob[2], psg_iob[3], 4'b1111}; + + assign psg_ioa = {cas_audio_in,1'b0, psg_iob[6] ? joyB : joyA}; + + wire [9:0] ay_ch_mix; + + wire u21_1_q; + ls74 u21_1 + ( + .clr ( !psg_n ), + .pre ( 1 ), + .clk ( clk_en_3m58_p ), + .d ( !psg_n ), + .q ( u21_1_q ) + ); + + wire u21_2_q; + ls74 u21_2 + ( + .clr ( !psg_n ), + .pre ( 1 ), + .clk ( clk_en_3m58_p ), + .d ( u21_1_q ), + .q ( u21_2_q ) + ); + + wire psg_e = !(!u21_2_q | clk_en_3m58_p) | psg_n; + wire psg_bc = !(a[0] | psg_e); + wire psg_bdir = !(a[1] | psg_e); + + jt49_bus PSG + ( + .rst_n ( ~reset ), + .clk ( clk ), + .clk_en ( clk_en_3m58_n ), + .bdir ( psg_bdir ), + .bc1 ( psg_bc ), + .din ( d_from_cpu ), + .sel ( 0 ), + .dout ( d_from_psg ), + .sound ( ay_ch_mix ), + .A ( ), + .B ( ), + .C ( ), + .IOA_in ( psg_ioa ), + .IOA_out ( ), + .IOB_in ( 8'hFF ), + .IOB_out ( psg_iob ) + ); + + //-------------------------------------------------------------------------- + // SLOTS + //-------------------------------------------------------------------------- + wire [7:0] d_from_slots; + wire [15:0] sound_slots; + + slots slots + ( + .clk ( clk ), + .clk_en ( clk_en_3m58_p ), + .reset ( reset ), + .addr ( a ), + .wr_n ( wr_n ), + .rd_n ( rd_n ), + .CS1_n ( CS1_n ), + .CS2_n ( CS2_n ), + .CS12_n ( CS12_n ), + .SLTSL_n ( SLTSL_n ), + .d_from_cpu ( d_from_cpu ), + .d_to_cpu ( d_from_slots ), + .sound ( sound_slots ), + .ioctl_wr ( ioctl_wr ), + .ioctl_addr ( ioctl_addr ), + .ioctl_dout ( ioctl_dout ), + .ioctl_isROMA ( ioctl_isROMA ), + .ioctl_isROMB ( ioctl_isROMB ), + .ioctl_wait ( ioctl_wait ), + .sdram_dout ( sdram_dout ), + .sdram_din ( sdram_din ), + .sdram_addr ( sdram_addr ), + .sdram_we ( sdram_we ), + .sdram_rd ( sdram_rd ), + .sdram_ready ( sdram_ready ), + .sdram_size ( sdram_size ), + .slot_A ( slot_A ), + .slot_B ( slot_B ), + .mapper_info ( mapper_info ), + .rom_enabled ( rom_enabled ), + .img_mounted ( img_mounted ), + .img_size ( img_size ), + .img_wp ( img_wp ), + .sd_lba ( sd_lba ), + .sd_rd ( sd_rd ), + .sd_wr ( sd_wr ), + .sd_ack ( sd_ack ), + .sd_buff_addr ( sd_buff_addr ), + .sd_buff_dout ( sd_buff_dout ), + .sd_buff_din ( sd_buff_din ), + .sd_buff_wr ( sd_buff_wr ), + .sd_din_strobe ( sd_din_strobe ) + ); + +endmodule diff --git a/rtl/rom/cbios_main_msx1.mif b/rtl/rom/cbios_main_msx1.mif index 629a685..9e644b7 100644 --- a/rtl/rom/cbios_main_msx1.mif +++ b/rtl/rom/cbios_main_msx1.mif @@ -1,1382 +1,1382 @@ --- http://srecord.sourceforge.net/ --- --- Generated automatically by srec_cat -o --mif --- -DEPTH = 32768; -WIDTH = 8; -ADDRESS_RADIX = HEX; -DATA_RADIX = HEX; -CONTENT BEGIN -0000: F3 C3 12 0D BF 1B 98 98 C3 ED 10 00 C3 BF 23 00 C3 FF 10 00 C3 00 24 00; -0018: C3 1B 11 00 C3 34 24 00 C3 21 11 00 C3 73 24 00 C3 27 11 21 02 00 00 00; -0030: C3 39 11 00 00 00 00 00 C3 E6 18 C3 4E 11 C3 58 11 C3 16 02 C3 22 02 C3; -0048: 2E 02 C3 45 02 C3 4D 02 C3 55 02 C3 60 02 C3 6D 02 C3 81 02 C3 97 02 C3; -0060: AD 02 C3 D4 02 00 C3 5E 19 C3 1E 03 C3 82 03 C3 C2 03 C3 05 04 C3 43 04; -0078: C3 8F 04 C3 B7 04 C3 E6 04 C3 19 05 C3 6F 05 C3 82 05 C3 8C 05 C3 97 05; -0090: C3 3A 17 C3 52 17 C3 5C 17 C3 6A 11 C3 7C 11 C3 8F 11 C3 B4 11 C3 D9 14; -00A8: C3 03 15 C3 11 15 C3 36 15 C3 54 15 C3 4B 15 C3 25 16 C3 41 16 C3 53 16; -00C0: C3 56 16 C3 B5 07 C3 66 16 C3 6A 16 C3 7B 16 C3 8D 16 C3 9F 16 C3 8F 17; -00D8: C3 02 18 C3 47 18 C3 59 18 C3 B2 16 C3 C5 16 C3 D7 16 C3 E9 16 C3 FC 16; -00F0: C3 0F 17 C3 21 17 C3 6A 18 C3 79 18 C3 44 08 C3 56 08 C3 67 08 C3 76 08; -0108: C3 86 08 C3 97 08 C3 A9 08 C3 B9 08 C3 F4 08 C3 02 09 C3 14 09 C3 26 09; -0120: C3 37 09 C3 47 09 C3 59 09 C3 6B 09 C3 7D 09 C3 8E 09 C3 A7 18 C3 61 17; -0138: C3 6A 17 C3 6D 17 C3 70 17 C3 73 17 C3 82 17 C3 86 17 C3 8A 17 C3 B3 18; -0150: C3 C5 18 C3 C9 18 C3 DF 18 C3 70 1A 00 00 00 C9 00 00 00 00 00 00 00 00; -0168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -01B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -01C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -01E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -01F8: 00 00 00 00 00 00 00 00 4F 06 00 09 09 C3 11 02 BE 23 28 05 23 23 10 F8; -0210: C9 4E 23 66 69 E9 3A E0 F3 E6 BF 47 0E 01 CD 2E 02 C9 3A E0 F3 F6 40 47; -0228: 0E 01 CD 2E 02 C9 F3 CB B9 78 D3 99 79 F6 80 D3 99 FB E5 21 DF F3 78 06; -0240: 00 09 77 E1 C9 CD 55 02 F6 00 DB 98 C9 F5 CD 60 02 F1 D3 98 C9 F3 7D D3; -0258: 99 7C E6 3F D3 99 FB C9 F3 7D D3 99 7C E6 3F F6 40 D3 99 FB C9 F5 CD 60; -0270: 02 0B 0C 78 41 4F 0C F1 D3 98 05 20 FB 0D 20 F8 C9 CD 55 02 E5 EB 0B 0C; -0288: 78 41 3C 0E 98 ED A2 C2 8D 02 3D 20 F8 E1 C9 EB CD 60 02 EB 0B 0C 78 41; -02A0: 3C 0E 98 ED A3 C2 A3 02 3D 20 F8 EB C9 FE 04 D0 21 B6 02 C3 00 02 82 03; -02B8: C2 03 05 04 43 04 F3 21 DF F3 01 99 08 16 80 ED A3 78 ED 51 14 B7 20 F7; -02D0: FB C3 22 02 3A AF FC FE 08 28 3A 3D F5 3A E9 F3 07 07 07 07 E6 F0 6F 3A; -02E8: EB F3 B5 47 0E 07 CD 2E 02 F1 C0 3A E9 F3 07 07 07 07 E6 F0 21 EA F3 B6; -0300: 2A BF F3 01 20 00 F5 CD 60 02 F1 D3 98 F5 0B 78 B1 20 F7 F1 C9 3A EB F3; -0318: 47 0E 07 C3 2E 02 3A AF FC B7 C8 CD 48 03 3A AF FC FE 04 38 10 2A 28 F9; -0330: 25 25 01 00 02 3A E9 F3 E6 0F CD 6D 02 2A 26 F9 01 00 08 AF CD 6D 02 C9; -0348: 3A AF FC FE 04 38 04 1E D9 18 02 1E D1 2A 28 F9 CD 60 02 3A E9 F3 57 01; -0360: 00 20 F3 7B D3 98 3E 00 00 00 D3 98 79 00 00 00 D3 98 0C CD 8C 05 30 03; -0378: 0C 0C 0C 7A D3 98 10 E3 FB C9 CD 16 02 3E 00 32 AF FC 32 B0 FC 3A AE F3; -0390: 32 B0 F3 3E 01 32 DC F3 32 DD F3 2A B3 F3 22 22 F9 2A B7 F3 22 24 F9 2A; -03A8: B9 F3 22 28 F9 2A BB F3 22 26 F9 CD D4 02 CD 8F 04 CD A8 07 CD CD 07 C3; -03C0: BE 02 CD 16 02 3E 01 32 AF FC 32 B0 FC 3E 01 32 DC F3 32 DD F3 CD D4 02; -03D8: 2A BD F3 22 22 F9 2A C1 F3 22 24 F9 2A C5 F3 22 26 F9 2A C3 F3 22 28 F9; -03F0: CD A8 07 3A AF F3 32 B0 F3 CD B7 04 CD 53 03 CD DC 07 C3 BE 02 CD 16 02; -0408: 3E 02 32 AF FC CD D4 02 2A C7 F3 22 22 F9 CD 60 02 06 03 AF F3 D3 98 3C; -0420: 20 FB 10 F9 FB 2A CB F3 22 24 F9 2A CD F3 22 28 F9 2A CF F3 22 26 F9 CD; -0438: E6 04 CD 53 03 CD F8 07 C3 BE 02 CD 16 02 3E 03 32 AF FC CD D4 02 2A D1; -0450: F3 22 22 F9 CD 60 02 AF 0E 06 F3 F5 1E 04 F5 06 20 D3 98 3C 10 FB F1 1D; -0468: 20 F4 F1 C6 20 0D 20 EB FB 2A D5 F3 22 24 F9 2A D7 F3 22 28 F9 2A D9 F3; -0480: 22 26 F9 CD 19 05 CD 53 03 CD 0E 08 C3 BE 02 3A DF F3 E6 F1 47 0E 00 CD; -0498: 2E 02 3A E0 F3 E6 E7 F6 10 47 0C CD 2E 02 11 B3 F3 0E 02 AF CD 4A 05 13; -04B0: 13 0C AF CD 4A 05 C9 3A DF F3 E6 F1 47 0E 00 CD 2E 02 3A E0 F3 E6 E7 47; -04C8: 0C CD 2E 02 11 BD F3 0E 02 AF CD 4A 05 AF CD 4A 05 AF CD 4A 05 AF CD 4A; -04E0: 05 AF CD 4A 05 C9 3A DF F3 E6 F1 F6 02 47 0E 00 CD 2E 02 3A E0 F3 E6 E7; -04F8: 47 0C CD 2E 02 11 C7 F3 0E 02 AF CD 4A 05 3E 7F CD 4A 05 3E 03 CD 4A 05; -0510: AF CD 4A 05 AF CD 4A 05 C9 3A DF F3 E6 F1 47 0E 00 CD 2E 02 3A E0 F3 E6; -0528: E7 F6 08 47 0C CD 2E 02 11 D1 F3 0E 02 AF CD 4A 05 AF CD 4A 05 AF CD 4A; -0540: 05 AF CD 4A 05 AF CD 4A 05 C9 D5 F5 21 68 05 06 00 09 46 EB 7E 23 66 6F; -0558: 29 8F 10 FC 47 F1 B0 47 CD 2E 02 D1 13 13 0C C9 00 00 06 0A 05 09 05 26; -0570: 00 6F 29 29 29 CD 8C 05 30 02 29 29 ED 5B 26 F9 19 C9 87 87 2A 28 F9 16; -0588: 00 5F 19 C9 3A E0 F3 0F 0F 3E 08 D0 3E 20 C9 F5 FE 20 38 0D 3A AF FC FE; -05A0: 02 28 22 FE 05 30 1C F1 C9 FE 0D 20 FA F1 E5 C5 2A B9 FC 01 08 00 09 22; -05B8: B9 FC 21 00 00 22 B7 FC C1 E1 C9 F1 C9 F1 E5 D5 C5 F5 CD 22 08 ED 5B B9; -05D0: FC ED 4B B7 FC CD B9 08 3A E9 F3 32 F2 F3 2A 2A F9 ED 4B CB F3 09 11 40; -05E8: FC 3A B9 FC E6 07 06 00 4F 09 CD 12 06 01 F0 00 09 3A B9 FC 2F E6 07 4F; -0600: CD 12 06 2A B7 FC 01 08 00 09 22 B7 FC F1 C1 D1 E1 C9 3A B7 FC E6 07 F5; -0618: C5 D5 E5 CD 9B 06 3A B7 FC E6 07 28 1A 3A 2C F9 2F 32 2C F9 E1 01 08 00; -0630: 09 D1 C1 F1 CD 9B 06 3A 2C F9 2F 32 2C F9 C9 C1 01 08 00 09 C1 C1 F1 C9; -0648: F5 E5 C5 D5 57 58 ED 4B C9 F3 09 4F 3A F2 F3 E6 0F 47 CD 45 02 F5 E6 0F; -0660: B8 28 11 F1 F5 0F 0F 0F 0F E6 0F B8 20 0D F1 D1 C1 E1 F1 C9 F1 D1 C1 E1; -0678: F1 2F C9 7A B3 FE FF 28 11 F1 CB 00 CB 00 CB 00 CB 00 E6 0F B0 CD 4D 02; -0690: 18 DD F1 E6 F0 B0 CD 4D 02 18 DA 41 3C 4F 3E 07 A8 3C 47 C5 CD 45 02 47; -06A8: 1A CD 48 06 0D 28 03 0F 18 FA 4F 3A 2C F9 A1 4F 78 B1 CD 4D 02 23 13 C1; -06C0: 10 E1 C9 47 52 50 50 52 54 00 3A AF FC FE 05 C9 F5 CD EF 06 0B 0C 78 41; -06D8: 4F 0C F1 F3 D3 98 10 FC 0D 20 F9 FB C9 CD FB 06 7C E6 3F D3 99 FB C9 CD; -06F0: FB 06 7C E6 3F F6 40 D3 99 FB C9 3A F6 FA B7 28; -0700: 10 3A AF FC FE 05 DA 60 02 FE 07 3A F6 FA 38 01 87 E5 E6 03 0F 6F E6 80; -0718: AC 17 CB 15 17 7D 17 F3 D3 99 3E 8E D3 99 E1 7D D3 99 C9 CD E5 06 DB 98; -0730: C9 F5 CD EF 06 F1 D3 98 C9 F3 D3 99 3E 8F D3 99 DB 99 F5 AF D3 99 3E 8F; -0748: D3 99 FB F1 C9 DB 99 01 00 00 CD 2E 02 01 01 E0 CD 2E 02 01 02 00 CD 2E; -0760: 02 01 03 80 CD 2E 02 01 04 01 CD 2E 02 01 08 08 CD 2E 02 3E 01 32 DC F3; -0778: 32 DD F3 CD DC 07 3E 00 21 00 08 01 00 08 CD 6D 02 3E F5 21 00 20 01 20; -0790: 00 CD 6D 02 01 07 F5 CD 2E 02 21 BF 1B 11 00 08 01 00 08 CD 97 02 C9 C9; -07A8: 21 BF 1B ED 5B 24 F9 01 00 08 C3 97 02 C0 3A AF FC FE 04 D0 E5 21 C5 07; -07C0: CD 00 02 E1 C9 CD 07 DC 07 F8 07 0E 08 3A B0 F3 FE 28 01 C0 03 38 08 01; -07D8: 80 07 18 03 01 00 03 2A 22 F9 3E 20 CD 6D 02 3E 01 21 B2 FB 77 11 B3 FB; -07F0: 01 17 00 ED B0 C3 45 12 AF 01 00 18 2A 24 F9 6F C5 CD 6D 02 C1 3A EA F3; -0808: 2A C9 F3 C3 6D 02 3A EA F3 E6 0F 47 07 07 07 07 B0 01 00 08 2A 24 F9 C3; -0820: 6D 02 ED 4B 20 F9 6F 26 00 29 29 29 09 06 08 11 40 FC C5 D5 E5 3A 1F F9; -0838: CD BF 23 E1 D1 C1 12 13 23 10 EF C9 E5 F5 21 4F 08 CD 9F 09 F1 E1 C9 52; -0850: 49 47 48 54 43 00 E5 F5 21 61 08 CD 9F 09 F1 E1 C9 4C 45 46 54 43 00 E5; -0868: F5 21 72 08 CD 9F 09 F1 E1 C9 55 50 43 00 E5 F5 21 81 08 CD 9F 09 F1 E1; -0880: C9 54 55 50 43 00 E5 F5 21 91 08 CD 9F 09 F1 E1 C9 44 4F 57 4E 43 00 E5; -0898: F5 21 A2 08 CD 9F 09 F1 E1 C9 54 44 4F 57 4E 43 00 ED 4B B7 FC ED 5B B9; -08B0: FC C9 53 43 41 4C 58 59 00 C5 ED 43 B7 FC ED 53 B9 FC 2A B9 FC 29 29 29; -08C8: 29 29 2E 00 06 00 3E FF 32 2C F9 79 E6 07 28 0A 47 3E FF A7 1F 10 FC 32; -08E0: 2C F9 79 E6 F8 4F 06 00 09 22 2A F9 C1 C9 4D 41 50 58 59 00 3A 2C F9 2A; -08F8: 2A F9 C9 46 45 54 43 48 43 00 E5 F5 21 0D 09 CD 9F 09 F1 E1 C9 53 54 4F; -0910: 52 45 43 00 E5 F5 21 1F 09 CD 9F 09 F1 E1 C9 53 45 54 41 54 52 00 E5 F5; -0928: 21 31 09 CD 9F 09 F1 E1 C9 52 45 41 44 43 00 E5 F5 21 42 09 CD 9F 09 F1; -0940: E1 C9 53 45 54 43 00 E5 F5 21 52 09 CD 9F 09 F1 E1 C9 4E 53 45 54 43 58; -0958: 00 E5 F5 21 64 09 CD 9F 09 F1 E1 C9 47 54 41 53 50 43 00 E5 F5 21 76 09; -0970: CD 9F 09 F1 E1 C9 50 4E 54 49 4E 49 00 E5 F5 21 88 09 CD 9F 09 F1 E1 C9; -0988: 53 43 41 4E 52 00 E5 F5 21 99 09 CD 9F 09 F1 E1 C9 53 43 41 4E 4C 00 3E; -09A0: 23 D3 2E CD AB 09 3E 00 D3 2E C9 7E 23 B7 C8 D3 2F 18 F8 E6 0F FE 0A 30; -09B8: 05 C6 30 D3 2F C9 C6 37 D3 2F C9 F5 0F 0F 0F 0F CD B3 09 F1 CD B3 09 C9; -09D0: 7C CD C3 09 7D CD C3 09 C9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -09E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0BC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0BF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0C10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0C28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0C40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0C58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0C70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0C88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0CA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0CB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0CD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0CE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0D00: 00 C9 DD E1 FD E1 F1 C1 D1 E1 D9 08 F1 C1 D1 E1 FB C9 3E 82 D3 AB 3E 50; -0D18: D3 AA AF D3 FF 3C D3 FE 3C D3 FD 3C D3 FC 21 FF FF D9 DB A8 F6 F0 47 78; -0D30: D3 A8 3A FF FF 2F F6 F0 4F 79 32 FF FF 21 00 FF 3E 0F 77 BE 20 08 2F 77; -0D48: BE 20 03 25 18 F2 24 7C B7 28 15 D9 BC 38 05 28 03 D9 18 0C 2E 00 67 D9; -0D60: 78 D9 47 D9 79 D9 4F D9 79 D6 10 4F 30 CB 78 D6 10 47 30 BB D9 7D B7 28; -0D78: 06 11 F5 25 C3 87 1A 78 D3 A8 79 32 FF FF D9 21 00 F3 F9 CD 17 0F CD 43; -0D90: 10 CD 4D 07 FB CD 4E 11 06 0F 11 13 0E 21 00 80 C5 E5 D5 3A C1 FC CD BF; -0DA8: 23 E1 D1 C1 BE 20 12 EB 13 23 10 EC DD 21 10 80 FD 2A C0 FC CD 34 24 18; -0DC0: 11 3E 05 32 EA F3 32 EB F3 CD C2 03 21 56 25 CD 8E 10 FB 06 78 CD 8A 10; -0DD8: 3E 04 32 EB F3 3E 04 32 EA F3 3E 0F 32 E9 F3 3E 1D 32 AF F3 CD C2 03 21; -0DF0: 56 25 CD 8E 10 CD 22 0E CD DA FE CD 01 0F 3E 01; -0E00: 32 99 FD AF 32 29 FB CD CB FE 21 2F 26 CD 8E 10 C3 65 1A 43 2D 42 49 4F; -0E18: 53 20 4C 6F 67 6F 20 52 4F 4D 21 C9 FC 11 CA FC 01 3F 00 36 00 ED B0 21; -0E30: C1 FC AF E5 B6 21 00 40 CD 69 0E CC 76 0E 21 00 80 CD 69 0E CC 76 0E CB; -0E48: 7F 28 06 C6 04 CB 67 28 E4 E1 23 3C E6 03 20 DB C9 47 CD BF 23 23 F5 78; -0E60: CD BF 23 23 57 F1 5F 78 C9 E5 CD 59 0E 21 41 42 CD 21 11 78 E1 C9 E5 F5; -0E78: 21 BD 25 CD 8E 10 F1 F5 47 E6 03 C6 30 CD B4 11 78 CB 78 28 0F 3E 2E CD; -0E90: B4 11 78 0F 0F E6 03 C6 30 CD B4 11 3E 0D CD B4 11 3E 0A CD B4 11 F1 E1; -0EA8: 23 23 CD F8 0E 28 15 4F D5 DD E1 F5 FD E1 DB 99 B7 FA B6 0E F5 E5 CD 34; -0EC0: 24 F3 E1 F1 0E 00 CD F8 0E 28 02 CB E9 CD F8 0E 28 02 CB F1 CD F8 0E 28; -0ED8: 02 CB F9 47 E6 0C 5F 78 07 07 07 07 E6 30 B3 5F 7C 07 07 E6 03 B3 21 C9; -0EF0: FC 16 00 5F 19 71 78 C9 C5 CD 59 0E 7A B3 78 C1 C9 21 C9 FC 06 40 7E CB; -0F08: 7F 28 08 E5 21 D0 25 CD 8E 10 E1 23 10 F0 C9 3E 00 21 80 F3 77 11 81 F3; -0F20: 01 7D 0C ED B0 3E C9 21 00 F3 77 11 01 F3 01 7F 00 ED B0 3E C9 21 9A FD; -0F38: 77 11 9B FD 01 4D 02 ED B0 3E FF 21 DA FB 77 11 DB FB 01 15 00 ED B0 3E; -0F50: 00 21 F0 FB 77 11 F1 FB 01 27 00 ED B0 21 F0 FB 22 F8 F3 22 FA F3 D9 22; -0F68: 48 FC D9 21 80 F3 22 4A FC 22 74 F6 21 3B 25 11 80 F3 01 1A 00 ED B0 21; -0F80: 00 00 22 B3 F3 21 00 08 22 B7 F3 21 00 18 22 BD F3 21 00 20 22 BF F3 21; -0F98: 00 00 22 C1 F3 21 00 1B 22 C3 F3 21 00 38 22 C5 F3 21 00 18 22 C7 F3 21; -0FB0: 00 20 22 C9 F3 21 00 00 22 CB F3 21 00 1B 22 CD F3 21 00 38 22 CF F3 21; -0FC8: 00 08 22 D1 F3 21 00 00 22 D5 F3 21 00 1B 22 D7 F3 21 00 38 22 D9 F3 21; -0FE0: 59 F9 22 F3 F3 21 75 F9 22 5D F9 21 F5 F9 22 63 F9 21 75 FA 22 69 F9 3E; -0FF8: 7F 32 5C F9 32 62 F9 32 68 F9 3E 27 32 AE F3 3E 20 32 AF F3 3A AF F3 32; -1010: B0 F3 3E 18 32 B1 F3 3E 04 32 EB F3 3E 04 32 EA F3 3E 0F 32 E9 F3 3E A0; -1028: 32 E0 F3 3A C1 FC 32 1F F9 2A 04 00 22 20 F9 3E C3 21 B4 11 22 E5 FE 32; -1040: E4 FE C9 F3 21 C1 FC DB A8 57 E6 3F 4F D3 A8 3A FF FF 2F 5F E6 0F 32 FF; -1058: FF 47 3A FF FF 2F B8 20 15 7B E6 0F F6 50 32 FF FF 47 3A FF FF 2F B8 20; -1070: 05 06 80 7B 18 04 06 00 7B 2F 32 FF FF 7A D3 A8 70 23 79 C6 40 4F 30 C5; -1088: FB C9 76 10 FD C9 3A AF FC FE 05 30 09 7E B7 C8 CD B4 11 23 18 F7 7E B7; -10A0: C8 DD 21 89 00 CD 3F 1A 23 18 F3 0E 20 3A AF FC B7 C0 0E 28 3A B0 F3 FE; -10B8: 29 D8 0E 50 C9 C5 F5 CD AB 10 3A B0 F3 ED 44 81 3C CB 3F 6F 3A DD F3 3D; -10D0: 85 6F 26 00 44 3A DC F3 3D CB 3F 30 01 09 CB 21 CB 10 B7 20 F4 ED 4B 22; -10E8: F9 09 F1 C1 C9 E5 F5 21 F8 10 CD 9F 09 F1 E1 C9 53 59 4E 43 48 52 00 CD; -1100: 48 FF 7E 23 FE 00 C8 FE 3A C8 FE 30 38 03 FE 3A D8 FE 20 28 ED FE 09 28; -1118: E9 B7 C9 F5 CD E4 FE F1 C9 7C BA C0 7D BB C9 E5 F5 21 32 11 CD 9F 09 F1; -1130: E1 C9 47 45 54 59 50 52 00 08 D9 E1 7E 23 5E 23 56 23 D5 DD E1 F5 FD E1; -1148: E5 08 D9 C3 34 24 1E 8F 3E 0F CD 52 17 C3 3A 17 E5 F5 21 63 11 CD 9F 09; -1160: F1 E1 C9 49 4E 49 46 4E 4B 00 E5 F5 21 75 11 CD 9F 09 F1 E1 C9 53 54 52; -1178: 54 4D 53 00 FB E5 D5 2A FA F3 ED 5B F8 F3 E7 3E FF 20 01 AF D1 E1 C9 CD; -1190: C2 FD E5 D5 2A FA F3 ED 5B F8 F3 E7 20 04 FB 76 18 F2 7E F5 23 7D FE 18; -11A8: 20 03 21 F0 FB 22 FA F3 F1 D1 E1 C9 E5 D5 C5 F5 CD A4 FD 3A AF FC FE 02; -11C0: 30 13 F1 F5 CD 04 14 F1 F5 CD DA 11 CD 19 14 3A DD F3 32 61 F6 F1 C1 D1; -11D8: E1 C9 CD 11 15 D0 28 12 F5 3A A7 FC B7 C2 BD 12 F1 FE 20 38 2A FE 7F CA; -11F0: F6 13 CD BD 10 CD 4D 02 2A DC F3 3A B0 F3 24 BC 38 04 22 DC F3 C9 11 B1; -1208: FB 26 00 19 AF 77 2A DC F3 CD 6C 12 C3 2E 12 06 0C 21 88 14 C3 08 02 3E; -1220: 20 CD F2 11 3A DD F3 E6 07 FE 01 20 F2 C9 2A DC F3 3A B1 F3 2C BD 30 09; -1238: E5 CD 45 12 CD 90 13 E1 2D 22 DC F3 C9 21 01 01 22 DC F3 C9 CD 2E 13 2A; -1250: DC F3 E5 CD 6C 12 3A DC F3 21 B1 F3 BE 30 08 CD 2E 12 CD 2E 13 18 EF E1; -1268: 22 DC F3 C9 3E 01 32 DD F3 C9 3E FF 32 A7 FC C9 3A DD F3 21 B0 F3 BE 30; -1280: 03 3C 18 1F 3A DC F3 21 B1 F3 BE D0 3C 32 DC F3 18 DA 3A DD F3 3D 20 0B; -1298: 3A DC F3 3D C8 32 DC F3 3A B0 F3 32 DD F3 C9 3A DC F3 3D C8 32 DC F3 C9; -12B0: 3A DC F3 21 B1 F3 BE D0 3C 32 DC F3 C9 47 3C 20 0C 32 A7 FC F1 06 0F 21; -12C8: AC 14 C3 08 02 F1 10 04 0E 00 18 04 10 18 0E 01 FE 34 28 06 FE 35 28 08; -12E0: 18 2E 79 32 AA FC 18 28 79 32 A9 FC 18 22 10 08 06 1F 90 32 DD F3 18 18; -12F8: 10 16 06 1F 90 32 DC F3 3E 03 18 0D 3E 01 18 09 3E 02 18 05 3E 04 18 01; -1310: AF 32 A7 FC C9 3A DD F3 21 B0 F3 BE D0 3C 32 DD F3 C9 3A DD F3 3D C8 32; -1328: DD F3 C9 CD 6C 12 21 B1 FB 3A DC F3 5F 16 00 19 77 3A B0 F3 3C 21 DD F3; -1340: 96 4F 06 00 3E 20 CD BD 10 C3 6D 02 CD 6C 12 2A DC F3 E5 45 3A B1 F3 32; -1358: DC F3 90 47 04 3A DC F3 18 0E CD BD 10 EB 3D 32 DC F3 CD BD 10 CD CE 13; -1370: 10 F0 E1 22 DC F3 26 00 3A B1 F3 57 1E 00 95 3D 4F 06 00 21 B1 FB 19 EB; -1388: 62 6B 2B ED B8 C3 2E 13 CD 6C 12 2A DC F3 E5 45 3A B1 F3 90 47 04 3A DC; -13A0: F3 18 0E CD BD 10 EB 3C 32 DC F3 CD BD 10 CD CE 13 10 F0 CD 2E 13 E1 22; -13B8: DC F3 26 00 3A B1 F3 95 3D 4F 06 00 11 B1 FB 19 54 5D 23 ED B0 C9 F5 C5; -13D0: 06 00 3A B0 F3 4F CD DC 13 C1 F1 C9 E5 D5 C5 11 18 FC CD 81 02 C1 D1 D5; -13E8: C5 21 18 FC CD 97 02 C1 E1 09 EB E1 09 C9 3A DD F3 FE 01 C8 3E 20 CD F2; -1400: 11 C3 92 12 3A A9 FC FE 01 C0 3A AF FC FE 02 D0 3A CC FB CD BD 10 C3 4D; -1418: 02 3A A9 FC FE 01 C0 3A AF FC FE 02 D0 CD BD 10 CD 45 02 32 CC FB A7 16; -1430: 00 5F CB 13 CB 12 CB 13 CB 12 CB 13 CB 12 AF 21 AF FC BE 20 05 2A B7 F3; -1448: 18 03 2A C1 F3 E5 19 11 18 FC 01 08 00 CD 81 02 3A AA FC FE 00 20 07 21; -1460: 18 FC 06 08 18 05 21 1E FC 06 02 7E 2F 77 23 10 FA E1 11 F8 07 19 EB 21; -1478: 18 FC 01 08 00 CD 97 02 CD BD 10 3E FF C3 4D 02 07 56 16 08 92 12 09 1F; -1490: 12 0A 2E 12 0B 45 12 0C B6 07 0D 6C 12 1B 72 12 1C 78 12 1D 92 12 1E A7; -14A8: 12 1F B0 12 6A B6 07 45 B6 07 4B 2E 13 4A 4C 12 6C 2B 13 4C 4C 13 4D 90; -14C0: 13 59 0C 13 41 A7 12 42 B0 12 43 15 13 44 22 13 48 45 12 78 04 13 79 08; -14D8: 13 CD B6 FF F5 CD 25 16 38 08 CD 03 15 28 F6 F1 18 0C 3E 0D CD F6 14 AF; -14F0: 32 15 F4 F1 37 C9 F5 D3 91 3E 00 D3 90 2F D3 90; -1500: F1 A7 C9 CD BB FF DB 90 1F 1F 3E FF 30 01 2F A7 C9 E5 F5 21 A6 FC AF BE; -1518: 77 20 08 F1 FE 01 20 13 77 18 11 F1 FE 40 38 09 FE 60 30 05 D6 40 BF 18; -1530: 02 FE 50 37 E1 C9 CD DB FD 3A AA F6 A7 CA 54 15 3E 01 32 DD F3 C3 54 15; -1548: 3F 20 00 CD E0 FD 21 48 15 CD 8E 10 2A DD F3 22 CA FB 11 B0 FB 26 00 7D; -1560: 19 77 CD 8F 11 FE 7F CA E4 15 FE 20 30 11 06 14 21 E5 15 CD 00 02 AF 32; -1578: A8 FC 32 AA FC 18 E3 F5 3A A8 FC A7 C4 8B 15 F1 DF 18 C9 CD 04 14 2A DC; -1590: F3 22 BC F6 3E 20 32 A7 F6 CD BD 10 CD 45 02 FE 20 20 28 2A DC F3 3A B0; -15A8: F3 BC 20 1D 26 00 11 B1 FB 19 7E B7 28 13 3A A7 F6 CD BD 10 CD 4D 02 2A; -15C0: BC F6 22 DC F3 C9 C3 19 14 3E 20 F5 3A A7 F6 DF F1 32 A7 F6 18 C3 C9 37; -15D8: E1 C9 C9 C9 C9 C9 AF E1 C9 C9 C9 C9 C9 18 00 18 00 D6 15 D7 15 18 00 DA; -15F0: 15 DB 15 18 00 DC 15 18 00 18 00 18 00 18 00 DD 15 DE 15 18 00 18 00 18; -1608: 00 E1 15 18 00 18 00 E2 15 18 00 18 00 18 00 18 00 18 00 E3 15 18 00 18; -1620: 00 18 00 18 00 DB AA E6 F0 F6 07 D3 AA DB A9 E6 10 C0 DB AA E6 F0 F6 06; -1638: D3 AA DB A9 E6 02 C0 37 C9 E5 F5 21 4C 16 CD 9F 09 F1 E1 C9 49 53 43 4E; -1650: 54 43 00 C3 41 16 E5 F5 21 61 16 CD 9F 09 F1 E1 C9 42 45 45 50 00 22 DC; -1668: F3 C9 E5 F5 21 75 16 CD 9F 09 F1 E1 C9 46 4E 4B 53 42 00 E5 F5 21 86 16; -1680: CD 9F 09 F1 E1 C9 45 52 41 46 4E 4B 00 E5 F5 21 98 16 CD 9F 09 F1 E1 C9; -1698: 44 53 50 46 4E 4B 00 3A AF FC FE 02 D8 3A B0 FC CD BD FD B7 CA 82 03 C3; -16B0: C2 03 E5 F5 21 BE 16 CD 9F 09 F1 E1 37 C9 54 41 50 49 4F 4E 00 E5 F5 21; -16C8: D1 16 CD 9F 09 F1 E1 37 C9 54 41 50 49 4E 00 E5 F5 21 E2 16 CD 9F 09 F1; -16E0: E1 C9 54 41 50 49 4F 46 00 E5 F5 21 F5 16 CD 9F 09 F1 E1 37 C9 54 41 50; -16F8: 4F 4F 4E 00 E5 F5 21 08 17 CD 9F 09 F1 E1 37 C9 54 41 50 4F 55 54 00 E5; -1710: F5 21 1A 17 CD 9F 09 F1 E1 C9 54 41 50 4F 4F 46 00 C5 47 DB AA 04 28 0C; -1728: CB E7 05 28 09 CB A7 05 28 04 C1 C9 EE 10 D3 AA C1 C9 1E 00 3E 08 CD 52; -1740: 17 3C CD 52 17 3C CD 52 17 3C 1E B8 3E 07 CD 52 17 C9 F3 D3 A0 F5 7B D3; -1758: A1 FB F1 C9 D3 A0 DB A2 C9 B7 3E 0E 28 01 3C D3 AB C9 DB A8 C9 D3 A8 C9; -1770: DB 99 C9 F3 C5 4F DB AA E6 F0 B1 D3 AA DB A9 C1 FB C9 CD A7 FF C9 CD AC; -1788: FF C9 3A 64 F8 A7 C9 C5 FE 00 20 19 3E 08 CD 73 17 0F 0F 0F 0F 2F E6 0F; -17A0: E5 21 F2 17 16 00 5F 19 7E E1 C1 A7 C9 E5 D5 1E 00 3D 28 02 CB F3 3E 0F; -17B8: F3 CD 5C 17 FB E6 BF B3 5F 3E 0F CD 52 17 3E 0E F3 CD 5C 17 FB 2F E6 0F; -17D0: 21 E2 17 06 00 4F 09 7E D1 E1 C1 A7 C9 3E 00 C1 A7 C9 00 01 05 00 07 08; -17E8: 06 07 03 02 04 03 00 01 05 00 00 07 01 08 05 06 00 07 03 00 02 01 04 05; -1800: 03 00 FE 05 30 03 B7 20 09 3E 08 CD 73 17 F6 FE 3C C9 F3 3D D5 1E 03 47; -1818: E6 01 28 02 1E 4C 3E 0F CD 5C 17 E6 BF B3 5F 3E 0F CD 52 17 78 06 10 E6; -1830: 02 28 02 06 20 3E 0E F3 CD 5C 17 FB D1 A0 28 02 18 03 3E FF C9 AF C9 E5; -1848: F5 21 53 18 CD 9F 09 F1 E1 AF C9 47 54 50 41 44 00 E5 F5 21 64 18 CD 9F; -1860: 09 F1 E1 C9 47 54 50 44 4C 00 CD 9A 18 46 04 23 7E 90 23 23 A6 6F 26 00; -1878: C9 CD 9A 18 7E 3C 47 23 96 C8 78 23 23 E5 A6 2B 2B 2B 77 E1 23 7E 23 66; -1890: 6F 05 48 06 00 09 73 F6 01 C9 2A F3 F3 47 07 07 80 80 4F 06 00 09 C9 B7; -18A8: DB AA CB B7 20 02 CB F7 D3 AA C9 E5 F5 21 BE 18 CD 9F 09 F1 E1 C9 4F 55; -18C0: 54 44 4C 50 00 2E 02 18 03 3A 38 FB D5 16 00 5D 21 41 FB 19 1E 25 B7 28; -18D8: 04 19 3D 18 F9 D1 C9 2A FA F3 22 F8 F3 C9 E5 D5 C5 F5 D9 08 E5 D5 C5 F5; -18F0: FD E5 DD E5 CD 9A FD DB 99 B7 32 E7 F3 F2 4E 19 CD 9F FD 2A 9E FC 23 22; -1908: 9E FC AF 32 D9 FB 3A F6 F3 3D 32 F6 F3 20 37 3E 03 32 F6 F3 AF CD 02 18; -1920: 2F E6 01 32 E8 F3 CD 63 19 2A F8 F3 ED 5B FA F3 E7 20 1B 3A F7 F3 3D 32; -1938: F7 F3 20 12 21 DA FB 01 FF 0B 71 23 10 FC CD 63 19 3E 01 32 F7 F3 DD E1; -1950: FD E1 F1 C1 D1 E1 D9 08 F1 C1 D1 E1 FB C9 CD D6 FD ED 45 DB AA E6 F0 4F; -1968: 06 0B 21 E5 FB 79 D3 AA DB A9 77 23 0C 10 F6 DD 21 DA FB 11 E5 FB 3A EB; -1980: FB 0F 21 BE 26 38 03 21 EE 26 0E 0B 1A DD BE 00 C4 B4 19 2F DD A6 00 08; -1998: 1A DD 77 00 08 06 08 0F 38 1A 23 10 FA DD 23 13 0D C8 79 FE 05 20 DD 21; -19B0: DE 27 18 D8 F5 3E 05 32 F7 F3 F1 C9 F5 79 FE 05 28 07 FE 04 28 1C C3 13; -19C8: 1A 78 FE 03 20 04 3E 00 18 21 FE 02 20 04 3E 01 18 19 FE 01 20 35 3E 02; -19E0: 18 11 78 FE 08 20 04 3E 03 18 08 FE 07 20 24 3E 04 18 00 E5 C5 D5 07 07; -19F8: 07 07 21 7F F8 16 00 5F 19 EB 1A A7 28 08 D5 CD 20 1A D1 13 18 F4 D1 C1; -1A10: E1 18 09 7E A7 28 05 E5 CD 20 1A E1 F1 C3 A2 19 2A F8 F3 77 23 7D FE 18; -1A28: 20 03 21 F0 FB D5 ED 5B FA F3 E7 D1 C8 22 F8 F3 C9 CD 3F 1A DD E1 C9 08; -1A40: D9 F5 C5 D5 E5 ED 57 F5 D9 FD E5 3A F8 FA F5 FD E1 08 CD 34 24 FD E1 08; -1A58: D9 F1 E2 5E 1A FB E1 D1 C1 F1 D9 08 C9 18 FE CD DA FE 11 22 26 C3 87 1A; -1A70: E5 F5 21 80 1A CD 9F 09 F1 E1 11 07 26 C3 87 1A 43 41 4C 42 41 53 00 DB; -1A88: 99 21 06 28 06 0C 0E 99 ED B3 01 00 08 AF D3 98 0B 78 B1 20 F8 21 BF 1B; -1AA0: 01 00 08 7E D3 98 23 0B 78 B1 20 F7 3E 00 D3 99 3E 40 D3 99 21 EE 25 7E; -1AB8: D3 98 23 7E A7 20 F9 1A D3 98 13 1A A7 20 F9 C3 65 1A 00 00 00 00 00 00; -1AD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1AE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1BA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1BC0: 00 00 00 00 00 00 00 3C 42 A5 A5 C3 BD 42 3C 3C 7E DB DB BD C3 7E 3C 6C; -1BD8: AA 92 44 44 28 10 00 10 28 44 82 44 28 10 00 10 38 38 D6 FE D6 38 00 10; -1BF0: 38 7C 7C FE D6 38 00 00 00 00 18 18 00 00 00 FF; -1C00: FF FF E7 E7 FF FF FF 3C 42 81 81 81 81 42 3C C3 BD 7E 7E 7E 7E BD C3 0C; -1C18: 04 08 70 88 88 70 00 00 70 88 88 70 20 70 20 20 30 28 28 20 E0 C0 00 38; -1C30: 3C 24 24 E4 DC 18 00 10 44 38 AA 38 44 10 00 10 10 10 38 10 10 10 10 10; -1C48: 10 10 EF 00 00 00 00 00 00 00 EF 10 10 10 10 10 10 10 E0 10 10 10 10 10; -1C60: 10 10 0F 10 10 10 10 10 10 10 EF 10 10 10 10 10 10 10 10 10 10 10 10 00; -1C78: 00 00 FF 00 00 00 00 00 00 00 0F 10 10 10 10 00 00 00 E0 10 10 10 10 10; -1C90: 10 10 0F 00 00 00 00 10 10 10 E0 00 00 00 00 81 42 24 18 18 24 42 81 01; -1CA8: 02 04 08 10 20 40 80 80 40 20 10 08 04 02 01 00 00 10 FF 10 00 00 00 00; -1CC0: 00 00 00 00 00 00 00 20 20 20 20 00 20 00 00 50 50 00 00 00 00 00 00 00; -1CD8: 50 F8 50 F8 50 00 00 20 70 A0 70 28 70 20 00 00 C8 D0 20 58 98 00 00 60; -1CF0: 90 60 A8 98 60 00 00 40 40 00 00 00 00 00 00 20 40 40 40 40 20 00 00 20; -1D08: 10 10 10 10 20 00 00 00 20 A8 70 50 88 00 00 00 20 20 F8 20 20 00 00 00; -1D20: 00 00 00 00 40 40 00 00 00 00 F8 00 00 00 00 00 00 00 00 00 40 00 00 00; -1D38: 08 10 20 40 80 00 00 70 88 A8 A8 88 70 00 00 20 60 20 20 20 70 00 00 70; -1D50: 88 08 70 80 F8 00 00 F8 08 30 08 88 70 00 00 10 30 50 F8 10 10 00 00 F8; -1D68: 80 70 08 88 70 00 00 30 40 70 88 88 70 00 00 F8 88 10 20 20 20 00 00 70; -1D80: 88 70 88 88 70 00 00 70 88 88 78 08 70 00 00 00 00 40 00 00 40 00 00 00; -1D98: 00 40 00 00 40 40 00 00 18 60 80 60 18 00 00 00 00 F8 00 F8 00 00 00 00; -1DB0: C0 30 08 30 C0 00 00 70 88 30 20 00 20 00 00 70 88 98 A8 A8 98 40 00 70; -1DC8: 88 88 F8 88 88 00 00 E0 90 E0 90 88 F0 00 00 70 88 80 80 88 70 00 00 F0; -1DE0: 48 48 48 48 F0 00 00 F8 80 E0 80 80 F8 00 00 F8 80 80 E0 80 80 00 00 70; -1DF8: 88 80 B8 88 70 00 00 88 88 F8 88 88 88 00 00 70 20 20 20 20 70 00 00 38; -1E10: 08 08 08 88 70 00 00 88 90 A0 E0 90 88 00 00 80 80 80 80 80 F8 00 00 D8; -1E28: A8 A8 88 88 88 00 00 C8 A8 A8 98 98 88 00 00 70 88 88 88 88 70 00 00 F0; -1E40: 88 88 F0 80 80 00 00 70 88 88 A8 90 68 00 00 F0 88 88 F0 A0 98 00 00 70; -1E58: 80 70 08 08 F0 00 00 F8 20 20 20 20 20 00 00 88 88 88 88 88 78 00 00 88; -1E70: 88 88 50 50 20 00 00 88 88 A8 A8 A8 D8 00 00 88 50 20 50 88 88 00 00 88; -1E88: 88 70 20 20 20 00 00 F8 10 20 40 80 F8 00 00 70 40 40 40 40 70 00 00 00; -1EA0: 80 40 20 10 08 00 00 70 10 10 10 10 70 00 00 40 A0 00 00 00 00 00 00 00; -1EB8: 00 00 00 00 00 F8 00 20 10 00 00 00 00 00 00 00 00 78 88 98 68 00 00 80; -1ED0: 80 F0 88 88 F0 00 00 00 00 78 80 80 78 00 00 08 08 78 88 88 78 00 00 00; -1EE8: 00 70 98 E0 78 00 00 30 48 40 40 E0 40 40 40 00 00 78 88 88 78 08 70 80; -1F00: 80 F0 88 88 88 00 00 20 00 60 20 20 70 00 00 10 00 30 10 10 10 10 60 80; -1F18: 80 98 A0 E0 98 00 00 C0 40 40 40 40 70 00 00 00 00 F0 A8 A8 A8 00 00 00; -1F30: 00 F0 88 88 88 00 00 00 00 70 88 88 70 00 00 00 00 F0 88 88 F0 80 80 00; -1F48: 00 78 88 88 78 08 08 00 00 B8 C0 80 80 00 00 00 00 78 F0 08 F0 00 00 40; -1F60: 40 F0 40 48 30 00 00 00 00 88 88 88 78 00 00 00 00 88 88 50 20 00 00 00; -1F78: 00 88 A8 A8 D8 00 00 00 00 C8 30 60 98 00 00 00 00 88 88 88 78 08 70 00; -1F90: 00 F8 30 40 F8 00 00 10 20 20 40 20 20 10 00 20 20 20 20 20 20 20 00 40; -1FA8: 20 20 10 20 20 40 00 50 A0 00 00 00 00 00 00 00 20 50 50 F8 00 00 00 70; -1FC0: 88 80 80 88 70 20 40 50 00 88 88 88 78 00 00 08 10 70 98 E0 78 00 00 20; -1FD8: 50 78 88 98 68 00 00 50 00 78 88 98 68 00 00 40 20 78 88 98 68 00 00 20; -1FF0: 00 78 88 98 68 00 00 00 00 78 80 80 78 20 40 20 50 70 98 E0 78 00 00 50; -2008: 00 70 98 E0 78 00 00 40 20 70 98 E0 78 00 00 50 00 60 20 20 70 00 00 20; -2020: 50 60 20 20 70 00 00 40 20 60 20 20 70 00 00 50 70 88 88 F8 88 00 00 20; -2038: 70 88 88 F8 88 00 00 18 F8 80 E0 80 F8 00 00 00 00 D0 68 B0 D8 00 00 78; -2050: A0 B0 E0 A0 B8 00 00 20 50 70 88 88 70 00 00 50 00 70 88 88 70 00 00 40; -2068: 20 70 88 88 70 00 00 20 50 88 88 88 78 00 00 40 20 88 88 88 78 00 00 50; -2080: 00 88 88 88 78 08 70 50 70 88 88 88 70 00 00 50 88 88 88 88 70 00 00 20; -2098: 20 78 80 80 78 20 20 20 50 40 E0 40 48 B0 00 88 88 50 F8 20 70 20 00 80; -20B0: D0 B0 B0 B8 D0 88 80 38 40 F0 40 F0 40 38 00 08 10 78 88 98 68 00 00 10; -20C8: 20 60 20 20 70 00 00 10 20 70 88 88 70 00 00 10 20 88 88 88 78 00 00 28; -20E0: 50 F0 88 88 88 00 00 28 D0 A8 A8 98 88 00 00 00 00 78 88 98 68 00 70 00; -20F8: 00 70 88 88 70 00 70 20 00 20 60 88 70 00 00 00 00 00 E0 80 00 00 00 00; -2110: 00 00 E0 20 00 00 00 40 48 50 30 48 90 38 00 40 48 50 28 58 B8 08 00 20; -2128: 00 20 20 20 20 00 00 00 00 00 48 90 48 00 00 00 00 00 90 48 90 00 00 28; -2140: 50 70 88 F8 88 00 00 28 50 78 88 98 68 00 00 28 50 70 20 20 70 00 00 28; -2158: 50 60 20 20 70 00 00 28 70 88 88 88 70 00 00 28 50 70 88 88 70 00 00 28; -2170: 50 88 88 88 78 00 00 28 50 00 88 88 78 00 00 FC 48 48 48 48 E8 08 30 48; -2188: 00 D8 48 48 E8 08 30 E0 68 30 E8 58 B8 08 00 50 28 00 00 00 00 00 00 00; -21A0: 20 50 88 50 20 00 00 00 48 50 20 68 A8 00 00 7C A8 A8 A8 68 28 28 44 70; -21B8: 80 70 88 70 08 88 70 00 00 00 00 00 00 FF FF F0 F0 F0 F0 0F 0F 0F 0F 00; -21D0: 00 FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 3C 3C 00 00 00 FF; -21E8: FF FF FF FF FF 00 00 C0 C0 C0 C0 C0 C0 C0 C0 0F 0F 0F 0F F0 F0 F0 F0 FC; -2200: FC FC FC FC FC FC FC 03 03 03 03 03 03 03 03 3F 3F 3F 3F 3F 3F 3F 3F 11; -2218: 22 44 88 11 22 44 88 88 44 22 11 88 44 22 11 FE 7C 38 10 00 00 00 00 00; -2230: 00 00 00 10 38 7C FE 80 C0 E0 F0 E0 C0 80 00 01 03 07 0F 07 03 01 00 FF; -2248: 7E 3C 18 18 3C 7E FF 81 C3 E7 FF FF E7 C3 81 F0 F0 F0 F0 00 00 00 00 00; -2260: 00 00 00 0F 0F 0F 0F 0F 0F 0F 0F 00 00 00 00 00 00 00 00 F0 F0 F0 F0 33; -2278: 33 CC CC 33 33 CC CC 00 10 28 28 7C 00 00 00 10 10 38 10 38 10 10 00 00; -2290: 00 50 88 A8 50 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 FF FF FF FF F0; -22A8: F0 F0 F0 F0 F0 F0 F0 0F 0F 0F 0F 0F 0F 0F 0F FF FF FF FF 00 00 00 00 00; -22C0: 00 68 90 90 68 00 00 60 90 E0 90 90 E0 80 00 F8 88 80 80 80 80 00 00 F8; -22D8: 50 50 50 50 48 80 00 F8 48 20 40 88 F8 00 00 00 00 78 90 88 70 00 00 00; -22F0: 00 88 88 C8 B0 80 80 00 00 50 50 20 50 50 20 70; -2300: 20 70 A8 A8 70 20 70 70 88 F8 88 88 70 00 00 70 88 88 88 50 D8 00 00 30; -2318: 40 30 48 48 30 00 00 00 00 50 A8 A8 50 00 00 00 10 70 A8 A8 70 40 00 00; -2330: 70 80 E0 80 70 00 00 70 88 88 88 88 88 00 00 00 F8 00 F8 00 F8 00 00 00; -2348: 20 20 F8 20 20 F8 00 00 C0 30 08 30 C0 F8 00 00 18 60 80 60 18 F8 00 00; -2360: 18 20 20 20 20 20 20 20 20 20 20 20 20 C0 00 00 20 00 F8 00 20 00 00 00; -2378: 68 B0 00 68 B0 00 00 00 30 48 48 30 00 00 00 00 30 78 78 30 00 00 00 00; -2390: 00 00 00 30 00 00 00 1C 10 10 90 50 30 10 00 E0 90 90 00 00 00 00 00 60; -23A8: 10 60 F0 00 00 00 00 00 70 70 70 70 70 70 00 AA 55 AA 55 AA 55 AA 55 C5; -23C0: E5 F5 57 A7 F3 FC DE 24 F1 E1 E5 D5 E5 F5 7C 07 07 E6 03 6F 47 3E FC CD; -23D8: F8 23 5F 45 F1 E6 03 CD F8 23 47 DB A8 57 A3 B0 E1 CD 80 F3 7B D1 F5 CB; -23F0: 7A C4 1A 25 F1 E1 C1 C9 04 05 C8 07 07 10 FC C9 E5 57 D5 A7 F3 FC DE 24; -2408: C1 E1 D5 E5 7C 07 07 E6 03 6F 47 3E FC CD F8 23 5F 45 7A E6 03 CD F8 23; -2420: 47 DB A8 57 A3 B0 E1 59 CD 85 F3 D1 E5 CB 7A C4 1A 25 E1 C9 08 D9 F3 FD; -2438: E5 F1 DD E5 E1 57 A7 FC DE 24 D5 7A E6 03 47 0E FC DD E5 F1 07 07 E6 03; -2450: 87 28 07 CB 00 CB 01 3D 20 F9 21 67 24 E5 DB A8 F5 A1 B0 D9 C3 8C F3 08; -2468: D9 F3 D1 CB 7A C4 1A 25 08 D9 C9 F3 E5 6F E6 03 47 3E AB C6 55 05 F2 7B; -2480: 24 57 7C 07 07 E6 03 67 47 3E C0 07 07 05 F2 8B 24 5F 2F 4F 7A A3 47 7D; -2498: A7 F2 D6 24 0F 0F E6 03 E5 C5 47 3E AB C6 55 05 F2 A5 24 A3 47 7A E6 C0; -24B0: 67 DB A8 6F E6 C0 B4 D3 A8 3A FF FF 2F A1 B0 4F 32 FF FF 7D D3 A8 21 C5; -24C8: FC 7A E6 03 85 6F 7C CE 00 67 79 77 C1 E1 DB A8 A1 B0 D3 A8 E1 C9 57 0F; -24E0: 0F 5F E6 C0 6F DB A8 4F E6 3F B5 D3 A8 7B E6 03 6F 7C 26 03 18 02 29 29; -24F8: D6 40 30 FA 7C 2F 67 3A FF FF 2F 5F A4 B5 32 FF FF 6F 79 D3 A8 7A E6 03; -2510: 4F 06 00 7D 21 C5 FC 09 77 C9 7A 0F 0F E6 C0 47 DB A8 4F E6 3F B0 D3 A8; -2528: 7B 32 FF FF 79 D3 A8 7A E6 03 4F 06 00 21 C5 FC 09 73 C9 D3 A8 5E 18 03; -2540: D3 A8 73 7A D3 A8 C9 D3 A8 08 CD 98 F3 08 F1 D3 A8 08 C9 DD E9 00 43 2D; -2558: 42 49 4F 53 20 30 2E 32 39 20 20 20 20 20 20 63 62 69 6F 73 2E 73 66 2E; -2570: 6E 65 74 0D 0A 43 68 61 72 61 63 74 65 72 20 73 65 74 3A 20 55 53 0D 0A; -2588: 49 6E 74 65 72 72 75 70 74 20 66 72 65 71 75 65 6E 63 79 3A 20 36 30 48; -25A0: 7A 0D 0A 4B 65 79 62 6F 61 72 64 20 74 79 70 65 3A 20 55 53 0D 0A 0D 0A; -25B8: 0D 0A 0D 0A 00 49 6E 69 74 20 52 4F 4D 20 69 6E 20 73 6C 6F 74 3A 20 00; -25D0: 43 61 6E 6E 6F 74 20 65 78 65 63 75 74 65 20 61 20 42 41 53 49 43 20 52; -25E8: 4F 4D 2E 0D 0A 00 45 52 52 4F 52 3A 00 4D 45 4D 4F 52 59 20 4E 4F 54 20; -2600: 46 4F 55 4E 44 2E 00 43 41 4C 4C 45 44 20 4E 4F 4E 20 45 58 49 53 54 49; -2618: 4E 47 20 42 41 53 49 43 2E 00 53 54 41 43 4B 20 45 52 52 4F 52 2E 00 0D; -2630: 0A 0D 0A 4E 6F 20 63 61 72 74 72 69 64 67 65 20 66 6F 75 6E 64 2E 0D 0A; -2648: 0D 0A 54 68 69 73 20 76 65 72 73 69 6F 6E 20 6F 66 20 43 2D 42 49 4F 53; -2660: 20 63 61 6E 0D 0A 6F 6E 6C 79 20 73 74 61 72 74 20 63 61 72 74 72 69 64; -2678: 67 65 73 2E 0D 0A 50 6C 65 61 73 65 20 72 65 73 74 61 72 74 20 79 6F 75; -2690: 72 20 4D 53 58 0D 0A 28 65 6D 75 6C 61 74 6F 72 29 20 77 69 74 68 20 61; -26A8: 20 63 61 72 74 72 69 64 67 65 0D 0A 69 6E 73 65 72 74 65 64 2E 00 30 31; -26C0: 32 33 34 35 36 37 38 39 2D 3D 5C 5B 5D 3B 27 60 2C 2E 2F 00 61 62 63 64; -26D8: 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 29 21; -26F0: 40 23 24 25 5E 26 2A 28 5F 2B 7C 7B 7D 3A 22 7E 3C 3E 3F 00 41 42 43 44; -2708: 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 09 AC; -2720: AB BA EF BD F4 FB EC 07 17 F1 1E 01 0D 06 05 BB F3 F2 1D 00 C4 11 BC C7; -2738: CD 14 15 13 DC C6 DD C8 0B 1B C2 DB CC 18 D2 12 C0 1A CF 1C 19 0F 0A 00; -2750: FD FC 00 00 F5 00 00 08 1F F0 16 02 0E 04 03 F7 AE AF F6 00 FE 00 FA C1; -2768: CE D4 10 D6 DF CA DE C9 0C D3 C3 D7 CB A9 D1 00 C5 D5 D0 F9 AA F8 EB 9F; -2780: D9 BF 9B 98 E0 E1 E7 87 EE E9 00 ED DA B7 B9 E5 86 A6 A7 00 84 97 8D 8B; -2798: 8C 94 81 B1 A1 91 B3 B5 E6 A4 A2 A3 83 93 89 96 82 95 88 8A A0 85 D8 AD; -27B0: 9E BE 9C 9D 00 00 E2 80 00 00 00 E8 EA B6 B8 E4 8F 00 A8 00 8E 00 00 00; -27C8: 00 99 9A B0 00 92 B2 B4 00 A5 00 E3 00 00 00 00 90 00 00 00 00 00 00 00; -27E0: 00 00 00 00 00 00 00 00 1B 09 00 08 00 0D 20 0C 00 00 1D 1E 1F 1C 2A 2B; -27F8: 2F 30 31 32 33 34 35 36 37 38 39 2D 2C 2E 00 80 70 81 00 82 01 84 F5 87; -2810: 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2828: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2858: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2888: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -28A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -28B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -28D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -28E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2918: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2948: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2978: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -29A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -29C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -29D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -29F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2BC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2BF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2C10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2C28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2C40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2C58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2C70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2C88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2CA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2CB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2CD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2CE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2DA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2DC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2DD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2EB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2EC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2EE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2EF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2F10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2F28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2F40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2F58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2F70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2F88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2FA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2FB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2FD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2FE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3018: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3078: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -30A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -30C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -30D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -30F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3118: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3148: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3178: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3190: 00 00 00 C5 E5 C1 1B 7B B2 28 03 09 18 F8 C1 C9 E5 F5 21 B5 31 CD 9F 09; -31A8: 3E 20 D3 2E 7A D3 2F 7B D3 2F F1 E1 C9 52 4F 4D 42 41 53 00 00 00 00 00; -31C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -31D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -31F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3208: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3238: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3268: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3298: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -32B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -32C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -32E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -32F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3328: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3358: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3388: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -33A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -33B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -33D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -33E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3418: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3478: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -34A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -34C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -34D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -34F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3508: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3538: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3568: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3598: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -35B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -35C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -35E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -35F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3628: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3658: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3688: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -36A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -36B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -36D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -36E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3748: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -37A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -37C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -37D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -37F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3818: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3848: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3878: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -38A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -38C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -38D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -38F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3908: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3938: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3950: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3968: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3980: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3998: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -39B0: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -39C8: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -39E0: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -39F8: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3A10: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3A28: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A E5 F5; -3A40: 21 49 3A CD 9F 09 F1 E1 C9 42 41 53 49 43 20 73 74 61 74 65 6D 65 6E 74; -3A58: 73 20 61 72 65 20 6E 6F 74 20 69 6D 70 6C 65 6D 65 6E 74 65 64 20 79 65; -3A70: 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3A88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3AA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3AB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3AD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3AE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3BA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3BC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3BD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3BF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3CB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3CC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3CE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3CF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3D10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3D28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3D40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3D58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3D70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3D88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3DA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3DB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3DD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3DE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3EA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3ED8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3EF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3FA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3FC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3FD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3FF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4008: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4038: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4068: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4098: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -40B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -40C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -40E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -40F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4128: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4158: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4188: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -41A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -41B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -41D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -41E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4218: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4248: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4278: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -42A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -42C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -42D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -42F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4308: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4338: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4368: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4398: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -43B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -43C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -43E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -43F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4428: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4458: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4488: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -44A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -44B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -44D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -44E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4518: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4548: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4578: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -45A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -45C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -45D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -45F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4618: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4678: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -46A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -46C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -46D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -46F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4708: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4738: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4768: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4798: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -47B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -47C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -47E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -47F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4828: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4858: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4888: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -48A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -48B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -48D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -48E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4918: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4948: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4978: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -49A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -49C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -49D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -49F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4AB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4AC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4AE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4AF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4B10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4B28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4B40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4B58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4B70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4B88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4BA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4BB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4BD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4BE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4CA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4CC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4CD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4CF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4DA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4DC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4DD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4EB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4EC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4EE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4EF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4F10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4F28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4F40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4F58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4F70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4F88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4FA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4FB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4FD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4FE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5018: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5078: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -50A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -50C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -50D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -50F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5108: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5138: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -51B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -51C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -51E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -51F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5228: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5258: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -52A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -52B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -52D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -52E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5318: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5348: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5378: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -53A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -53C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -53D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -53F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5418: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5478: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -54A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -54C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -54D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -54F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5508: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5538: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5568: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5598: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -55B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -55C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -55E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -55F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5628: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5658: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5688: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -56A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -56B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -56D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -56E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5748: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -57A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -57C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -57D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -57F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5808: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5838: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5868: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5898: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -58B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -58C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -58E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -58F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5928: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5958: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5988: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -59A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -59B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -59D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -59E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5BA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5BC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5BD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5BF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5CB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5CC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5CE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5CF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5D10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5D28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5D40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5D58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5D70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5D88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5DA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5DB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5DD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5DE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5EA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5ED8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5EF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5FB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5FC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5FE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5FF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6028: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6058: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6088: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -60A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -60B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -60D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -60E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6118: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6148: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6178: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -61A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -61C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -61D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -61F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6218: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6248: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6278: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -62A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -62C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -62D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -62F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6308: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6338: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6368: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6398: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -63B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -63C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -63E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -63F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6428: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6458: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6488: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -64A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -64B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -64D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -64E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6518: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6548: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6578: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -65A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -65C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -65D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -65F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6608: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6620: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6638: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6650: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6668: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 8E 10 00 00 00 00 00; -6680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6698: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -66B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -66C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -66E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -66F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6728: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6758: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6788: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -67A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -67B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -67D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -67E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6818: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6848: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6878: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -68A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -68C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -68D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -68F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6918: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6948: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6978: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -69A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -69C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -69D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -69F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6AB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6AC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6AE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6AF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6B10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6B28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6B40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6B58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6B70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6B88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6BA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6BB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6BD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6BE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6CA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6CC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6CD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6CF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6DB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6DC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6DE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6DF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6E10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6E28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6E40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6E58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6E70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6E88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6EA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6EB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6ED0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6EE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6FA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6FC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6FD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6FF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7018: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7078: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -70A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -70C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -70D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -70F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7108: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7138: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -71B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -71C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -71E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -71F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7228: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7258: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -72A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -72B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -72D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -72E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7318: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7348: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7378: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -73A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -73C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -73D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -73F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7408: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7438: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7468: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7498: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -74B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -74C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -74E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -74F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7528: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7558: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7588: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -75A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -75B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -75D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -75E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7618: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7678: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -76A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -76C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -76D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -76F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7748: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -77A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -77C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 C9 00 00 00 00 00 00 00 00 00 00; -77D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -77F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7808: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7838: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7868: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7898: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -78B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -78C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -78E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -78F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7928: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7958: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7988: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -79A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -79B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -79D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -79E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7BC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7BF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7C10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7C28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7C40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7C58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7C70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7C88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7CA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7CB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7CD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7CE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7D00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5; -7D18: F5 21 22 7D CD 9F 09 F1 E1 C9 75 6E 6B 6E 6F 77 6E 40 37 44 31 37 00 39; -7D30: 7D DD 21 89 01 CD 3F 1A C9 DD 21 85 01 C3 3F 1A 00 00 00 00 00 00 00 00; -7D48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7D60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7D78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7D90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7DA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7DC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7DD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5 F5 21 1F; -7E18: 7E CD 9F 09 F1 E1 C9 75 6E 6B 6E 6F 77 6E 40 37 45 31 34 00 00 00 00 00; -7E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7E48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7E60: 00 00 00 00 00 00 00 00 00 00 00 C9 00 00 00 00 00 00 00 00 00 00 00 00; -7E78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7EA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7ED8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7EF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7FB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7FC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7FE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7FF8: 00 00 00 00 00 00 00 00; -END; +-- http://srecord.sourceforge.net/ +-- +-- Generated automatically by srec_cat -o --mif +-- +DEPTH = 32768; +WIDTH = 8; +ADDRESS_RADIX = HEX; +DATA_RADIX = HEX; +CONTENT BEGIN +0000: F3 C3 12 0D BF 1B 98 98 C3 ED 10 00 C3 BF 23 00 C3 FF 10 00 C3 00 24 00; +0018: C3 1B 11 00 C3 34 24 00 C3 21 11 00 C3 73 24 00 C3 27 11 21 02 00 00 00; +0030: C3 39 11 00 00 00 00 00 C3 E6 18 C3 4E 11 C3 58 11 C3 16 02 C3 22 02 C3; +0048: 2E 02 C3 45 02 C3 4D 02 C3 55 02 C3 60 02 C3 6D 02 C3 81 02 C3 97 02 C3; +0060: AD 02 C3 D4 02 00 C3 5E 19 C3 1E 03 C3 82 03 C3 C2 03 C3 05 04 C3 43 04; +0078: C3 8F 04 C3 B7 04 C3 E6 04 C3 19 05 C3 6F 05 C3 82 05 C3 8C 05 C3 97 05; +0090: C3 3A 17 C3 52 17 C3 5C 17 C3 6A 11 C3 7C 11 C3 8F 11 C3 B4 11 C3 D9 14; +00A8: C3 03 15 C3 11 15 C3 36 15 C3 54 15 C3 4B 15 C3 25 16 C3 41 16 C3 53 16; +00C0: C3 56 16 C3 B5 07 C3 66 16 C3 6A 16 C3 7B 16 C3 8D 16 C3 9F 16 C3 8F 17; +00D8: C3 02 18 C3 47 18 C3 59 18 C3 B2 16 C3 C5 16 C3 D7 16 C3 E9 16 C3 FC 16; +00F0: C3 0F 17 C3 21 17 C3 6A 18 C3 79 18 C3 44 08 C3 56 08 C3 67 08 C3 76 08; +0108: C3 86 08 C3 97 08 C3 A9 08 C3 B9 08 C3 F4 08 C3 02 09 C3 14 09 C3 26 09; +0120: C3 37 09 C3 47 09 C3 59 09 C3 6B 09 C3 7D 09 C3 8E 09 C3 A7 18 C3 61 17; +0138: C3 6A 17 C3 6D 17 C3 70 17 C3 73 17 C3 82 17 C3 86 17 C3 8A 17 C3 B3 18; +0150: C3 C5 18 C3 C9 18 C3 DF 18 C3 70 1A 00 00 00 C9 00 00 00 00 00 00 00 00; +0168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01F8: 00 00 00 00 00 00 00 00 4F 06 00 09 09 C3 11 02 BE 23 28 05 23 23 10 F8; +0210: C9 4E 23 66 69 E9 3A E0 F3 E6 BF 47 0E 01 CD 2E 02 C9 3A E0 F3 F6 40 47; +0228: 0E 01 CD 2E 02 C9 F3 CB B9 78 D3 99 79 F6 80 D3 99 FB E5 21 DF F3 78 06; +0240: 00 09 77 E1 C9 CD 55 02 F6 00 DB 98 C9 F5 CD 60 02 F1 D3 98 C9 F3 7D D3; +0258: 99 7C E6 3F D3 99 FB C9 F3 7D D3 99 7C E6 3F F6 40 D3 99 FB C9 F5 CD 60; +0270: 02 0B 0C 78 41 4F 0C F1 D3 98 05 20 FB 0D 20 F8 C9 CD 55 02 E5 EB 0B 0C; +0288: 78 41 3C 0E 98 ED A2 C2 8D 02 3D 20 F8 E1 C9 EB CD 60 02 EB 0B 0C 78 41; +02A0: 3C 0E 98 ED A3 C2 A3 02 3D 20 F8 EB C9 FE 04 D0 21 B6 02 C3 00 02 82 03; +02B8: C2 03 05 04 43 04 F3 21 DF F3 01 99 08 16 80 ED A3 78 ED 51 14 B7 20 F7; +02D0: FB C3 22 02 3A AF FC FE 08 28 3A 3D F5 3A E9 F3 07 07 07 07 E6 F0 6F 3A; +02E8: EB F3 B5 47 0E 07 CD 2E 02 F1 C0 3A E9 F3 07 07 07 07 E6 F0 21 EA F3 B6; +0300: 2A BF F3 01 20 00 F5 CD 60 02 F1 D3 98 F5 0B 78 B1 20 F7 F1 C9 3A EB F3; +0318: 47 0E 07 C3 2E 02 3A AF FC B7 C8 CD 48 03 3A AF FC FE 04 38 10 2A 28 F9; +0330: 25 25 01 00 02 3A E9 F3 E6 0F CD 6D 02 2A 26 F9 01 00 08 AF CD 6D 02 C9; +0348: 3A AF FC FE 04 38 04 1E D9 18 02 1E D1 2A 28 F9 CD 60 02 3A E9 F3 57 01; +0360: 00 20 F3 7B D3 98 3E 00 00 00 D3 98 79 00 00 00 D3 98 0C CD 8C 05 30 03; +0378: 0C 0C 0C 7A D3 98 10 E3 FB C9 CD 16 02 3E 00 32 AF FC 32 B0 FC 3A AE F3; +0390: 32 B0 F3 3E 01 32 DC F3 32 DD F3 2A B3 F3 22 22 F9 2A B7 F3 22 24 F9 2A; +03A8: B9 F3 22 28 F9 2A BB F3 22 26 F9 CD D4 02 CD 8F 04 CD A8 07 CD CD 07 C3; +03C0: BE 02 CD 16 02 3E 01 32 AF FC 32 B0 FC 3E 01 32 DC F3 32 DD F3 CD D4 02; +03D8: 2A BD F3 22 22 F9 2A C1 F3 22 24 F9 2A C5 F3 22 26 F9 2A C3 F3 22 28 F9; +03F0: CD A8 07 3A AF F3 32 B0 F3 CD B7 04 CD 53 03 CD DC 07 C3 BE 02 CD 16 02; +0408: 3E 02 32 AF FC CD D4 02 2A C7 F3 22 22 F9 CD 60 02 06 03 AF F3 D3 98 3C; +0420: 20 FB 10 F9 FB 2A CB F3 22 24 F9 2A CD F3 22 28 F9 2A CF F3 22 26 F9 CD; +0438: E6 04 CD 53 03 CD F8 07 C3 BE 02 CD 16 02 3E 03 32 AF FC CD D4 02 2A D1; +0450: F3 22 22 F9 CD 60 02 AF 0E 06 F3 F5 1E 04 F5 06 20 D3 98 3C 10 FB F1 1D; +0468: 20 F4 F1 C6 20 0D 20 EB FB 2A D5 F3 22 24 F9 2A D7 F3 22 28 F9 2A D9 F3; +0480: 22 26 F9 CD 19 05 CD 53 03 CD 0E 08 C3 BE 02 3A DF F3 E6 F1 47 0E 00 CD; +0498: 2E 02 3A E0 F3 E6 E7 F6 10 47 0C CD 2E 02 11 B3 F3 0E 02 AF CD 4A 05 13; +04B0: 13 0C AF CD 4A 05 C9 3A DF F3 E6 F1 47 0E 00 CD 2E 02 3A E0 F3 E6 E7 47; +04C8: 0C CD 2E 02 11 BD F3 0E 02 AF CD 4A 05 AF CD 4A 05 AF CD 4A 05 AF CD 4A; +04E0: 05 AF CD 4A 05 C9 3A DF F3 E6 F1 F6 02 47 0E 00 CD 2E 02 3A E0 F3 E6 E7; +04F8: 47 0C CD 2E 02 11 C7 F3 0E 02 AF CD 4A 05 3E 7F CD 4A 05 3E 03 CD 4A 05; +0510: AF CD 4A 05 AF CD 4A 05 C9 3A DF F3 E6 F1 47 0E 00 CD 2E 02 3A E0 F3 E6; +0528: E7 F6 08 47 0C CD 2E 02 11 D1 F3 0E 02 AF CD 4A 05 AF CD 4A 05 AF CD 4A; +0540: 05 AF CD 4A 05 AF CD 4A 05 C9 D5 F5 21 68 05 06 00 09 46 EB 7E 23 66 6F; +0558: 29 8F 10 FC 47 F1 B0 47 CD 2E 02 D1 13 13 0C C9 00 00 06 0A 05 09 05 26; +0570: 00 6F 29 29 29 CD 8C 05 30 02 29 29 ED 5B 26 F9 19 C9 87 87 2A 28 F9 16; +0588: 00 5F 19 C9 3A E0 F3 0F 0F 3E 08 D0 3E 20 C9 F5 FE 20 38 0D 3A AF FC FE; +05A0: 02 28 22 FE 05 30 1C F1 C9 FE 0D 20 FA F1 E5 C5 2A B9 FC 01 08 00 09 22; +05B8: B9 FC 21 00 00 22 B7 FC C1 E1 C9 F1 C9 F1 E5 D5 C5 F5 CD 22 08 ED 5B B9; +05D0: FC ED 4B B7 FC CD B9 08 3A E9 F3 32 F2 F3 2A 2A F9 ED 4B CB F3 09 11 40; +05E8: FC 3A B9 FC E6 07 06 00 4F 09 CD 12 06 01 F0 00 09 3A B9 FC 2F E6 07 4F; +0600: CD 12 06 2A B7 FC 01 08 00 09 22 B7 FC F1 C1 D1 E1 C9 3A B7 FC E6 07 F5; +0618: C5 D5 E5 CD 9B 06 3A B7 FC E6 07 28 1A 3A 2C F9 2F 32 2C F9 E1 01 08 00; +0630: 09 D1 C1 F1 CD 9B 06 3A 2C F9 2F 32 2C F9 C9 C1 01 08 00 09 C1 C1 F1 C9; +0648: F5 E5 C5 D5 57 58 ED 4B C9 F3 09 4F 3A F2 F3 E6 0F 47 CD 45 02 F5 E6 0F; +0660: B8 28 11 F1 F5 0F 0F 0F 0F E6 0F B8 20 0D F1 D1 C1 E1 F1 C9 F1 D1 C1 E1; +0678: F1 2F C9 7A B3 FE FF 28 11 F1 CB 00 CB 00 CB 00 CB 00 E6 0F B0 CD 4D 02; +0690: 18 DD F1 E6 F0 B0 CD 4D 02 18 DA 41 3C 4F 3E 07 A8 3C 47 C5 CD 45 02 47; +06A8: 1A CD 48 06 0D 28 03 0F 18 FA 4F 3A 2C F9 A1 4F 78 B1 CD 4D 02 23 13 C1; +06C0: 10 E1 C9 47 52 50 50 52 54 00 3A AF FC FE 05 C9 F5 CD EF 06 0B 0C 78 41; +06D8: 4F 0C F1 F3 D3 98 10 FC 0D 20 F9 FB C9 CD FB 06 7C E6 3F D3 99 FB C9 CD; +06F0: FB 06 7C E6 3F F6 40 D3 99 FB C9 3A F6 FA B7 28; +0700: 10 3A AF FC FE 05 DA 60 02 FE 07 3A F6 FA 38 01 87 E5 E6 03 0F 6F E6 80; +0718: AC 17 CB 15 17 7D 17 F3 D3 99 3E 8E D3 99 E1 7D D3 99 C9 CD E5 06 DB 98; +0730: C9 F5 CD EF 06 F1 D3 98 C9 F3 D3 99 3E 8F D3 99 DB 99 F5 AF D3 99 3E 8F; +0748: D3 99 FB F1 C9 DB 99 01 00 00 CD 2E 02 01 01 E0 CD 2E 02 01 02 00 CD 2E; +0760: 02 01 03 80 CD 2E 02 01 04 01 CD 2E 02 01 08 08 CD 2E 02 3E 01 32 DC F3; +0778: 32 DD F3 CD DC 07 3E 00 21 00 08 01 00 08 CD 6D 02 3E F5 21 00 20 01 20; +0790: 00 CD 6D 02 01 07 F5 CD 2E 02 21 BF 1B 11 00 08 01 00 08 CD 97 02 C9 C9; +07A8: 21 BF 1B ED 5B 24 F9 01 00 08 C3 97 02 C0 3A AF FC FE 04 D0 E5 21 C5 07; +07C0: CD 00 02 E1 C9 CD 07 DC 07 F8 07 0E 08 3A B0 F3 FE 28 01 C0 03 38 08 01; +07D8: 80 07 18 03 01 00 03 2A 22 F9 3E 20 CD 6D 02 3E 01 21 B2 FB 77 11 B3 FB; +07F0: 01 17 00 ED B0 C3 45 12 AF 01 00 18 2A 24 F9 6F C5 CD 6D 02 C1 3A EA F3; +0808: 2A C9 F3 C3 6D 02 3A EA F3 E6 0F 47 07 07 07 07 B0 01 00 08 2A 24 F9 C3; +0820: 6D 02 ED 4B 20 F9 6F 26 00 29 29 29 09 06 08 11 40 FC C5 D5 E5 3A 1F F9; +0838: CD BF 23 E1 D1 C1 12 13 23 10 EF C9 E5 F5 21 4F 08 CD 9F 09 F1 E1 C9 52; +0850: 49 47 48 54 43 00 E5 F5 21 61 08 CD 9F 09 F1 E1 C9 4C 45 46 54 43 00 E5; +0868: F5 21 72 08 CD 9F 09 F1 E1 C9 55 50 43 00 E5 F5 21 81 08 CD 9F 09 F1 E1; +0880: C9 54 55 50 43 00 E5 F5 21 91 08 CD 9F 09 F1 E1 C9 44 4F 57 4E 43 00 E5; +0898: F5 21 A2 08 CD 9F 09 F1 E1 C9 54 44 4F 57 4E 43 00 ED 4B B7 FC ED 5B B9; +08B0: FC C9 53 43 41 4C 58 59 00 C5 ED 43 B7 FC ED 53 B9 FC 2A B9 FC 29 29 29; +08C8: 29 29 2E 00 06 00 3E FF 32 2C F9 79 E6 07 28 0A 47 3E FF A7 1F 10 FC 32; +08E0: 2C F9 79 E6 F8 4F 06 00 09 22 2A F9 C1 C9 4D 41 50 58 59 00 3A 2C F9 2A; +08F8: 2A F9 C9 46 45 54 43 48 43 00 E5 F5 21 0D 09 CD 9F 09 F1 E1 C9 53 54 4F; +0910: 52 45 43 00 E5 F5 21 1F 09 CD 9F 09 F1 E1 C9 53 45 54 41 54 52 00 E5 F5; +0928: 21 31 09 CD 9F 09 F1 E1 C9 52 45 41 44 43 00 E5 F5 21 42 09 CD 9F 09 F1; +0940: E1 C9 53 45 54 43 00 E5 F5 21 52 09 CD 9F 09 F1 E1 C9 4E 53 45 54 43 58; +0958: 00 E5 F5 21 64 09 CD 9F 09 F1 E1 C9 47 54 41 53 50 43 00 E5 F5 21 76 09; +0970: CD 9F 09 F1 E1 C9 50 4E 54 49 4E 49 00 E5 F5 21 88 09 CD 9F 09 F1 E1 C9; +0988: 53 43 41 4E 52 00 E5 F5 21 99 09 CD 9F 09 F1 E1 C9 53 43 41 4E 4C 00 3E; +09A0: 23 D3 2E CD AB 09 3E 00 D3 2E C9 7E 23 B7 C8 D3 2F 18 F8 E6 0F FE 0A 30; +09B8: 05 C6 30 D3 2F C9 C6 37 D3 2F C9 F5 0F 0F 0F 0F CD B3 09 F1 CD B3 09 C9; +09D0: 7C CD C3 09 7D CD C3 09 C9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +09E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0D00: 00 C9 DD E1 FD E1 F1 C1 D1 E1 D9 08 F1 C1 D1 E1 FB C9 3E 82 D3 AB 3E 50; +0D18: D3 AA AF D3 FF 3C D3 FE 3C D3 FD 3C D3 FC 21 FF FF D9 DB A8 F6 F0 47 78; +0D30: D3 A8 3A FF FF 2F F6 F0 4F 79 32 FF FF 21 00 FF 3E 0F 77 BE 20 08 2F 77; +0D48: BE 20 03 25 18 F2 24 7C B7 28 15 D9 BC 38 05 28 03 D9 18 0C 2E 00 67 D9; +0D60: 78 D9 47 D9 79 D9 4F D9 79 D6 10 4F 30 CB 78 D6 10 47 30 BB D9 7D B7 28; +0D78: 06 11 F5 25 C3 87 1A 78 D3 A8 79 32 FF FF D9 21 00 F3 F9 CD 17 0F CD 43; +0D90: 10 CD 4D 07 FB CD 4E 11 06 0F 11 13 0E 21 00 80 C5 E5 D5 3A C1 FC CD BF; +0DA8: 23 E1 D1 C1 BE 20 12 EB 13 23 10 EC DD 21 10 80 FD 2A C0 FC CD 34 24 18; +0DC0: 11 3E 05 32 EA F3 32 EB F3 CD C2 03 21 56 25 CD 8E 10 FB 06 78 CD 8A 10; +0DD8: 3E 04 32 EB F3 3E 04 32 EA F3 3E 0F 32 E9 F3 3E 1D 32 AF F3 CD C2 03 21; +0DF0: 56 25 CD 8E 10 CD 22 0E CD DA FE CD 01 0F 3E 01; +0E00: 32 99 FD AF 32 29 FB CD CB FE 21 2F 26 CD 8E 10 C3 65 1A 43 2D 42 49 4F; +0E18: 53 20 4C 6F 67 6F 20 52 4F 4D 21 C9 FC 11 CA FC 01 3F 00 36 00 ED B0 21; +0E30: C1 FC AF E5 B6 21 00 40 CD 69 0E CC 76 0E 21 00 80 CD 69 0E CC 76 0E CB; +0E48: 7F 28 06 C6 04 CB 67 28 E4 E1 23 3C E6 03 20 DB C9 47 CD BF 23 23 F5 78; +0E60: CD BF 23 23 57 F1 5F 78 C9 E5 CD 59 0E 21 41 42 CD 21 11 78 E1 C9 E5 F5; +0E78: 21 BD 25 CD 8E 10 F1 F5 47 E6 03 C6 30 CD B4 11 78 CB 78 28 0F 3E 2E CD; +0E90: B4 11 78 0F 0F E6 03 C6 30 CD B4 11 3E 0D CD B4 11 3E 0A CD B4 11 F1 E1; +0EA8: 23 23 CD F8 0E 28 15 4F D5 DD E1 F5 FD E1 DB 99 B7 FA B6 0E F5 E5 CD 34; +0EC0: 24 F3 E1 F1 0E 00 CD F8 0E 28 02 CB E9 CD F8 0E 28 02 CB F1 CD F8 0E 28; +0ED8: 02 CB F9 47 E6 0C 5F 78 07 07 07 07 E6 30 B3 5F 7C 07 07 E6 03 B3 21 C9; +0EF0: FC 16 00 5F 19 71 78 C9 C5 CD 59 0E 7A B3 78 C1 C9 21 C9 FC 06 40 7E CB; +0F08: 7F 28 08 E5 21 D0 25 CD 8E 10 E1 23 10 F0 C9 3E 00 21 80 F3 77 11 81 F3; +0F20: 01 7D 0C ED B0 3E C9 21 00 F3 77 11 01 F3 01 7F 00 ED B0 3E C9 21 9A FD; +0F38: 77 11 9B FD 01 4D 02 ED B0 3E FF 21 DA FB 77 11 DB FB 01 15 00 ED B0 3E; +0F50: 00 21 F0 FB 77 11 F1 FB 01 27 00 ED B0 21 F0 FB 22 F8 F3 22 FA F3 D9 22; +0F68: 48 FC D9 21 80 F3 22 4A FC 22 74 F6 21 3B 25 11 80 F3 01 1A 00 ED B0 21; +0F80: 00 00 22 B3 F3 21 00 08 22 B7 F3 21 00 18 22 BD F3 21 00 20 22 BF F3 21; +0F98: 00 00 22 C1 F3 21 00 1B 22 C3 F3 21 00 38 22 C5 F3 21 00 18 22 C7 F3 21; +0FB0: 00 20 22 C9 F3 21 00 00 22 CB F3 21 00 1B 22 CD F3 21 00 38 22 CF F3 21; +0FC8: 00 08 22 D1 F3 21 00 00 22 D5 F3 21 00 1B 22 D7 F3 21 00 38 22 D9 F3 21; +0FE0: 59 F9 22 F3 F3 21 75 F9 22 5D F9 21 F5 F9 22 63 F9 21 75 FA 22 69 F9 3E; +0FF8: 7F 32 5C F9 32 62 F9 32 68 F9 3E 27 32 AE F3 3E 20 32 AF F3 3A AF F3 32; +1010: B0 F3 3E 18 32 B1 F3 3E 04 32 EB F3 3E 04 32 EA F3 3E 0F 32 E9 F3 3E A0; +1028: 32 E0 F3 3A C1 FC 32 1F F9 2A 04 00 22 20 F9 3E C3 21 B4 11 22 E5 FE 32; +1040: E4 FE C9 F3 21 C1 FC DB A8 57 E6 3F 4F D3 A8 3A FF FF 2F 5F E6 0F 32 FF; +1058: FF 47 3A FF FF 2F B8 20 15 7B E6 0F F6 50 32 FF FF 47 3A FF FF 2F B8 20; +1070: 05 06 80 7B 18 04 06 00 7B 2F 32 FF FF 7A D3 A8 70 23 79 C6 40 4F 30 C5; +1088: FB C9 76 10 FD C9 3A AF FC FE 05 30 09 7E B7 C8 CD B4 11 23 18 F7 7E B7; +10A0: C8 DD 21 89 00 CD 3F 1A 23 18 F3 0E 20 3A AF FC B7 C0 0E 28 3A B0 F3 FE; +10B8: 29 D8 0E 50 C9 C5 F5 CD AB 10 3A B0 F3 ED 44 81 3C CB 3F 6F 3A DD F3 3D; +10D0: 85 6F 26 00 44 3A DC F3 3D CB 3F 30 01 09 CB 21 CB 10 B7 20 F4 ED 4B 22; +10E8: F9 09 F1 C1 C9 E5 F5 21 F8 10 CD 9F 09 F1 E1 C9 53 59 4E 43 48 52 00 CD; +1100: 48 FF 7E 23 FE 00 C8 FE 3A C8 FE 30 38 03 FE 3A D8 FE 20 28 ED FE 09 28; +1118: E9 B7 C9 F5 CD E4 FE F1 C9 7C BA C0 7D BB C9 E5 F5 21 32 11 CD 9F 09 F1; +1130: E1 C9 47 45 54 59 50 52 00 08 D9 E1 7E 23 5E 23 56 23 D5 DD E1 F5 FD E1; +1148: E5 08 D9 C3 34 24 1E 8F 3E 0F CD 52 17 C3 3A 17 E5 F5 21 63 11 CD 9F 09; +1160: F1 E1 C9 49 4E 49 46 4E 4B 00 E5 F5 21 75 11 CD 9F 09 F1 E1 C9 53 54 52; +1178: 54 4D 53 00 FB E5 D5 2A FA F3 ED 5B F8 F3 E7 3E FF 20 01 AF D1 E1 C9 CD; +1190: C2 FD E5 D5 2A FA F3 ED 5B F8 F3 E7 20 04 FB 76 18 F2 7E F5 23 7D FE 18; +11A8: 20 03 21 F0 FB 22 FA F3 F1 D1 E1 C9 E5 D5 C5 F5 CD A4 FD 3A AF FC FE 02; +11C0: 30 13 F1 F5 CD 04 14 F1 F5 CD DA 11 CD 19 14 3A DD F3 32 61 F6 F1 C1 D1; +11D8: E1 C9 CD 11 15 D0 28 12 F5 3A A7 FC B7 C2 BD 12 F1 FE 20 38 2A FE 7F CA; +11F0: F6 13 CD BD 10 CD 4D 02 2A DC F3 3A B0 F3 24 BC 38 04 22 DC F3 C9 11 B1; +1208: FB 26 00 19 AF 77 2A DC F3 CD 6C 12 C3 2E 12 06 0C 21 88 14 C3 08 02 3E; +1220: 20 CD F2 11 3A DD F3 E6 07 FE 01 20 F2 C9 2A DC F3 3A B1 F3 2C BD 30 09; +1238: E5 CD 45 12 CD 90 13 E1 2D 22 DC F3 C9 21 01 01 22 DC F3 C9 CD 2E 13 2A; +1250: DC F3 E5 CD 6C 12 3A DC F3 21 B1 F3 BE 30 08 CD 2E 12 CD 2E 13 18 EF E1; +1268: 22 DC F3 C9 3E 01 32 DD F3 C9 3E FF 32 A7 FC C9 3A DD F3 21 B0 F3 BE 30; +1280: 03 3C 18 1F 3A DC F3 21 B1 F3 BE D0 3C 32 DC F3 18 DA 3A DD F3 3D 20 0B; +1298: 3A DC F3 3D C8 32 DC F3 3A B0 F3 32 DD F3 C9 3A DC F3 3D C8 32 DC F3 C9; +12B0: 3A DC F3 21 B1 F3 BE D0 3C 32 DC F3 C9 47 3C 20 0C 32 A7 FC F1 06 0F 21; +12C8: AC 14 C3 08 02 F1 10 04 0E 00 18 04 10 18 0E 01 FE 34 28 06 FE 35 28 08; +12E0: 18 2E 79 32 AA FC 18 28 79 32 A9 FC 18 22 10 08 06 1F 90 32 DD F3 18 18; +12F8: 10 16 06 1F 90 32 DC F3 3E 03 18 0D 3E 01 18 09 3E 02 18 05 3E 04 18 01; +1310: AF 32 A7 FC C9 3A DD F3 21 B0 F3 BE D0 3C 32 DD F3 C9 3A DD F3 3D C8 32; +1328: DD F3 C9 CD 6C 12 21 B1 FB 3A DC F3 5F 16 00 19 77 3A B0 F3 3C 21 DD F3; +1340: 96 4F 06 00 3E 20 CD BD 10 C3 6D 02 CD 6C 12 2A DC F3 E5 45 3A B1 F3 32; +1358: DC F3 90 47 04 3A DC F3 18 0E CD BD 10 EB 3D 32 DC F3 CD BD 10 CD CE 13; +1370: 10 F0 E1 22 DC F3 26 00 3A B1 F3 57 1E 00 95 3D 4F 06 00 21 B1 FB 19 EB; +1388: 62 6B 2B ED B8 C3 2E 13 CD 6C 12 2A DC F3 E5 45 3A B1 F3 90 47 04 3A DC; +13A0: F3 18 0E CD BD 10 EB 3C 32 DC F3 CD BD 10 CD CE 13 10 F0 CD 2E 13 E1 22; +13B8: DC F3 26 00 3A B1 F3 95 3D 4F 06 00 11 B1 FB 19 54 5D 23 ED B0 C9 F5 C5; +13D0: 06 00 3A B0 F3 4F CD DC 13 C1 F1 C9 E5 D5 C5 11 18 FC CD 81 02 C1 D1 D5; +13E8: C5 21 18 FC CD 97 02 C1 E1 09 EB E1 09 C9 3A DD F3 FE 01 C8 3E 20 CD F2; +1400: 11 C3 92 12 3A A9 FC FE 01 C0 3A AF FC FE 02 D0 3A CC FB CD BD 10 C3 4D; +1418: 02 3A A9 FC FE 01 C0 3A AF FC FE 02 D0 CD BD 10 CD 45 02 32 CC FB A7 16; +1430: 00 5F CB 13 CB 12 CB 13 CB 12 CB 13 CB 12 AF 21 AF FC BE 20 05 2A B7 F3; +1448: 18 03 2A C1 F3 E5 19 11 18 FC 01 08 00 CD 81 02 3A AA FC FE 00 20 07 21; +1460: 18 FC 06 08 18 05 21 1E FC 06 02 7E 2F 77 23 10 FA E1 11 F8 07 19 EB 21; +1478: 18 FC 01 08 00 CD 97 02 CD BD 10 3E FF C3 4D 02 07 56 16 08 92 12 09 1F; +1490: 12 0A 2E 12 0B 45 12 0C B6 07 0D 6C 12 1B 72 12 1C 78 12 1D 92 12 1E A7; +14A8: 12 1F B0 12 6A B6 07 45 B6 07 4B 2E 13 4A 4C 12 6C 2B 13 4C 4C 13 4D 90; +14C0: 13 59 0C 13 41 A7 12 42 B0 12 43 15 13 44 22 13 48 45 12 78 04 13 79 08; +14D8: 13 CD B6 FF F5 CD 25 16 38 08 CD 03 15 28 F6 F1 18 0C 3E 0D CD F6 14 AF; +14F0: 32 15 F4 F1 37 C9 F5 D3 91 3E 00 D3 90 2F D3 90; +1500: F1 A7 C9 CD BB FF DB 90 1F 1F 3E FF 30 01 2F A7 C9 E5 F5 21 A6 FC AF BE; +1518: 77 20 08 F1 FE 01 20 13 77 18 11 F1 FE 40 38 09 FE 60 30 05 D6 40 BF 18; +1530: 02 FE 50 37 E1 C9 CD DB FD 3A AA F6 A7 CA 54 15 3E 01 32 DD F3 C3 54 15; +1548: 3F 20 00 CD E0 FD 21 48 15 CD 8E 10 2A DD F3 22 CA FB 11 B0 FB 26 00 7D; +1560: 19 77 CD 8F 11 FE 7F CA E4 15 FE 20 30 11 06 14 21 E5 15 CD 00 02 AF 32; +1578: A8 FC 32 AA FC 18 E3 F5 3A A8 FC A7 C4 8B 15 F1 DF 18 C9 CD 04 14 2A DC; +1590: F3 22 BC F6 3E 20 32 A7 F6 CD BD 10 CD 45 02 FE 20 20 28 2A DC F3 3A B0; +15A8: F3 BC 20 1D 26 00 11 B1 FB 19 7E B7 28 13 3A A7 F6 CD BD 10 CD 4D 02 2A; +15C0: BC F6 22 DC F3 C9 C3 19 14 3E 20 F5 3A A7 F6 DF F1 32 A7 F6 18 C3 C9 37; +15D8: E1 C9 C9 C9 C9 C9 AF E1 C9 C9 C9 C9 C9 18 00 18 00 D6 15 D7 15 18 00 DA; +15F0: 15 DB 15 18 00 DC 15 18 00 18 00 18 00 18 00 DD 15 DE 15 18 00 18 00 18; +1608: 00 E1 15 18 00 18 00 E2 15 18 00 18 00 18 00 18 00 18 00 E3 15 18 00 18; +1620: 00 18 00 18 00 DB AA E6 F0 F6 07 D3 AA DB A9 E6 10 C0 DB AA E6 F0 F6 06; +1638: D3 AA DB A9 E6 02 C0 37 C9 E5 F5 21 4C 16 CD 9F 09 F1 E1 C9 49 53 43 4E; +1650: 54 43 00 C3 41 16 E5 F5 21 61 16 CD 9F 09 F1 E1 C9 42 45 45 50 00 22 DC; +1668: F3 C9 E5 F5 21 75 16 CD 9F 09 F1 E1 C9 46 4E 4B 53 42 00 E5 F5 21 86 16; +1680: CD 9F 09 F1 E1 C9 45 52 41 46 4E 4B 00 E5 F5 21 98 16 CD 9F 09 F1 E1 C9; +1698: 44 53 50 46 4E 4B 00 3A AF FC FE 02 D8 3A B0 FC CD BD FD B7 CA 82 03 C3; +16B0: C2 03 E5 F5 21 BE 16 CD 9F 09 F1 E1 37 C9 54 41 50 49 4F 4E 00 E5 F5 21; +16C8: D1 16 CD 9F 09 F1 E1 37 C9 54 41 50 49 4E 00 E5 F5 21 E2 16 CD 9F 09 F1; +16E0: E1 C9 54 41 50 49 4F 46 00 E5 F5 21 F5 16 CD 9F 09 F1 E1 37 C9 54 41 50; +16F8: 4F 4F 4E 00 E5 F5 21 08 17 CD 9F 09 F1 E1 37 C9 54 41 50 4F 55 54 00 E5; +1710: F5 21 1A 17 CD 9F 09 F1 E1 C9 54 41 50 4F 4F 46 00 C5 47 DB AA 04 28 0C; +1728: CB E7 05 28 09 CB A7 05 28 04 C1 C9 EE 10 D3 AA C1 C9 1E 00 3E 08 CD 52; +1740: 17 3C CD 52 17 3C CD 52 17 3C 1E B8 3E 07 CD 52 17 C9 F3 D3 A0 F5 7B D3; +1758: A1 FB F1 C9 D3 A0 DB A2 C9 B7 3E 0E 28 01 3C D3 AB C9 DB A8 C9 D3 A8 C9; +1770: DB 99 C9 F3 C5 4F DB AA E6 F0 B1 D3 AA DB A9 C1 FB C9 CD A7 FF C9 CD AC; +1788: FF C9 3A 64 F8 A7 C9 C5 FE 00 20 19 3E 08 CD 73 17 0F 0F 0F 0F 2F E6 0F; +17A0: E5 21 F2 17 16 00 5F 19 7E E1 C1 A7 C9 E5 D5 1E 00 3D 28 02 CB F3 3E 0F; +17B8: F3 CD 5C 17 FB E6 BF B3 5F 3E 0F CD 52 17 3E 0E F3 CD 5C 17 FB 2F E6 0F; +17D0: 21 E2 17 06 00 4F 09 7E D1 E1 C1 A7 C9 3E 00 C1 A7 C9 00 01 05 00 07 08; +17E8: 06 07 03 02 04 03 00 01 05 00 00 07 01 08 05 06 00 07 03 00 02 01 04 05; +1800: 03 00 FE 05 30 03 B7 20 09 3E 08 CD 73 17 F6 FE 3C C9 F3 3D D5 1E 03 47; +1818: E6 01 28 02 1E 4C 3E 0F CD 5C 17 E6 BF B3 5F 3E 0F CD 52 17 78 06 10 E6; +1830: 02 28 02 06 20 3E 0E F3 CD 5C 17 FB D1 A0 28 02 18 03 3E FF C9 AF C9 E5; +1848: F5 21 53 18 CD 9F 09 F1 E1 AF C9 47 54 50 41 44 00 E5 F5 21 64 18 CD 9F; +1860: 09 F1 E1 C9 47 54 50 44 4C 00 CD 9A 18 46 04 23 7E 90 23 23 A6 6F 26 00; +1878: C9 CD 9A 18 7E 3C 47 23 96 C8 78 23 23 E5 A6 2B 2B 2B 77 E1 23 7E 23 66; +1890: 6F 05 48 06 00 09 73 F6 01 C9 2A F3 F3 47 07 07 80 80 4F 06 00 09 C9 B7; +18A8: DB AA CB B7 20 02 CB F7 D3 AA C9 E5 F5 21 BE 18 CD 9F 09 F1 E1 C9 4F 55; +18C0: 54 44 4C 50 00 2E 02 18 03 3A 38 FB D5 16 00 5D 21 41 FB 19 1E 25 B7 28; +18D8: 04 19 3D 18 F9 D1 C9 2A FA F3 22 F8 F3 C9 E5 D5 C5 F5 D9 08 E5 D5 C5 F5; +18F0: FD E5 DD E5 CD 9A FD DB 99 B7 32 E7 F3 F2 4E 19 CD 9F FD 2A 9E FC 23 22; +1908: 9E FC AF 32 D9 FB 3A F6 F3 3D 32 F6 F3 20 37 3E 03 32 F6 F3 AF CD 02 18; +1920: 2F E6 01 32 E8 F3 CD 63 19 2A F8 F3 ED 5B FA F3 E7 20 1B 3A F7 F3 3D 32; +1938: F7 F3 20 12 21 DA FB 01 FF 0B 71 23 10 FC CD 63 19 3E 01 32 F7 F3 DD E1; +1950: FD E1 F1 C1 D1 E1 D9 08 F1 C1 D1 E1 FB C9 CD D6 FD ED 45 DB AA E6 F0 4F; +1968: 06 0B 21 E5 FB 79 D3 AA DB A9 77 23 0C 10 F6 DD 21 DA FB 11 E5 FB 3A EB; +1980: FB 0F 21 BE 26 38 03 21 EE 26 0E 0B 1A DD BE 00 C4 B4 19 2F DD A6 00 08; +1998: 1A DD 77 00 08 06 08 0F 38 1A 23 10 FA DD 23 13 0D C8 79 FE 05 20 DD 21; +19B0: DE 27 18 D8 F5 3E 05 32 F7 F3 F1 C9 F5 79 FE 05 28 07 FE 04 28 1C C3 13; +19C8: 1A 78 FE 03 20 04 3E 00 18 21 FE 02 20 04 3E 01 18 19 FE 01 20 35 3E 02; +19E0: 18 11 78 FE 08 20 04 3E 03 18 08 FE 07 20 24 3E 04 18 00 E5 C5 D5 07 07; +19F8: 07 07 21 7F F8 16 00 5F 19 EB 1A A7 28 08 D5 CD 20 1A D1 13 18 F4 D1 C1; +1A10: E1 18 09 7E A7 28 05 E5 CD 20 1A E1 F1 C3 A2 19 2A F8 F3 77 23 7D FE 18; +1A28: 20 03 21 F0 FB D5 ED 5B FA F3 E7 D1 C8 22 F8 F3 C9 CD 3F 1A DD E1 C9 08; +1A40: D9 F5 C5 D5 E5 ED 57 F5 D9 FD E5 3A F8 FA F5 FD E1 08 CD 34 24 FD E1 08; +1A58: D9 F1 E2 5E 1A FB E1 D1 C1 F1 D9 08 C9 18 FE CD DA FE 11 22 26 C3 87 1A; +1A70: E5 F5 21 80 1A CD 9F 09 F1 E1 11 07 26 C3 87 1A 43 41 4C 42 41 53 00 DB; +1A88: 99 21 06 28 06 0C 0E 99 ED B3 01 00 08 AF D3 98 0B 78 B1 20 F8 21 BF 1B; +1AA0: 01 00 08 7E D3 98 23 0B 78 B1 20 F7 3E 00 D3 99 3E 40 D3 99 21 EE 25 7E; +1AB8: D3 98 23 7E A7 20 F9 1A D3 98 13 1A A7 20 F9 C3 65 1A 00 00 00 00 00 00; +1AD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1AE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1BA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1BC0: 00 00 00 00 00 00 00 3C 42 A5 A5 C3 BD 42 3C 3C 7E DB DB BD C3 7E 3C 6C; +1BD8: AA 92 44 44 28 10 00 10 28 44 82 44 28 10 00 10 38 38 D6 FE D6 38 00 10; +1BF0: 38 7C 7C FE D6 38 00 00 00 00 18 18 00 00 00 FF; +1C00: FF FF E7 E7 FF FF FF 3C 42 81 81 81 81 42 3C C3 BD 7E 7E 7E 7E BD C3 0C; +1C18: 04 08 70 88 88 70 00 00 70 88 88 70 20 70 20 20 30 28 28 20 E0 C0 00 38; +1C30: 3C 24 24 E4 DC 18 00 10 44 38 AA 38 44 10 00 10 10 10 38 10 10 10 10 10; +1C48: 10 10 EF 00 00 00 00 00 00 00 EF 10 10 10 10 10 10 10 E0 10 10 10 10 10; +1C60: 10 10 0F 10 10 10 10 10 10 10 EF 10 10 10 10 10 10 10 10 10 10 10 10 00; +1C78: 00 00 FF 00 00 00 00 00 00 00 0F 10 10 10 10 00 00 00 E0 10 10 10 10 10; +1C90: 10 10 0F 00 00 00 00 10 10 10 E0 00 00 00 00 81 42 24 18 18 24 42 81 01; +1CA8: 02 04 08 10 20 40 80 80 40 20 10 08 04 02 01 00 00 10 FF 10 00 00 00 00; +1CC0: 00 00 00 00 00 00 00 20 20 20 20 00 20 00 00 50 50 00 00 00 00 00 00 00; +1CD8: 50 F8 50 F8 50 00 00 20 70 A0 70 28 70 20 00 00 C8 D0 20 58 98 00 00 60; +1CF0: 90 60 A8 98 60 00 00 40 40 00 00 00 00 00 00 20 40 40 40 40 20 00 00 20; +1D08: 10 10 10 10 20 00 00 00 20 A8 70 50 88 00 00 00 20 20 F8 20 20 00 00 00; +1D20: 00 00 00 00 40 40 00 00 00 00 F8 00 00 00 00 00 00 00 00 00 40 00 00 00; +1D38: 08 10 20 40 80 00 00 70 88 A8 A8 88 70 00 00 20 60 20 20 20 70 00 00 70; +1D50: 88 08 70 80 F8 00 00 F8 08 30 08 88 70 00 00 10 30 50 F8 10 10 00 00 F8; +1D68: 80 70 08 88 70 00 00 30 40 70 88 88 70 00 00 F8 88 10 20 20 20 00 00 70; +1D80: 88 70 88 88 70 00 00 70 88 88 78 08 70 00 00 00 00 40 00 00 40 00 00 00; +1D98: 00 40 00 00 40 40 00 00 18 60 80 60 18 00 00 00 00 F8 00 F8 00 00 00 00; +1DB0: C0 30 08 30 C0 00 00 70 88 30 20 00 20 00 00 70 88 98 A8 A8 98 40 00 70; +1DC8: 88 88 F8 88 88 00 00 E0 90 E0 90 88 F0 00 00 70 88 80 80 88 70 00 00 F0; +1DE0: 48 48 48 48 F0 00 00 F8 80 E0 80 80 F8 00 00 F8 80 80 E0 80 80 00 00 70; +1DF8: 88 80 B8 88 70 00 00 88 88 F8 88 88 88 00 00 70 20 20 20 20 70 00 00 38; +1E10: 08 08 08 88 70 00 00 88 90 A0 E0 90 88 00 00 80 80 80 80 80 F8 00 00 D8; +1E28: A8 A8 88 88 88 00 00 C8 A8 A8 98 98 88 00 00 70 88 88 88 88 70 00 00 F0; +1E40: 88 88 F0 80 80 00 00 70 88 88 A8 90 68 00 00 F0 88 88 F0 A0 98 00 00 70; +1E58: 80 70 08 08 F0 00 00 F8 20 20 20 20 20 00 00 88 88 88 88 88 78 00 00 88; +1E70: 88 88 50 50 20 00 00 88 88 A8 A8 A8 D8 00 00 88 50 20 50 88 88 00 00 88; +1E88: 88 70 20 20 20 00 00 F8 10 20 40 80 F8 00 00 70 40 40 40 40 70 00 00 00; +1EA0: 80 40 20 10 08 00 00 70 10 10 10 10 70 00 00 40 A0 00 00 00 00 00 00 00; +1EB8: 00 00 00 00 00 F8 00 20 10 00 00 00 00 00 00 00 00 78 88 98 68 00 00 80; +1ED0: 80 F0 88 88 F0 00 00 00 00 78 80 80 78 00 00 08 08 78 88 88 78 00 00 00; +1EE8: 00 70 98 E0 78 00 00 30 48 40 40 E0 40 40 40 00 00 78 88 88 78 08 70 80; +1F00: 80 F0 88 88 88 00 00 20 00 60 20 20 70 00 00 10 00 30 10 10 10 10 60 80; +1F18: 80 98 A0 E0 98 00 00 C0 40 40 40 40 70 00 00 00 00 F0 A8 A8 A8 00 00 00; +1F30: 00 F0 88 88 88 00 00 00 00 70 88 88 70 00 00 00 00 F0 88 88 F0 80 80 00; +1F48: 00 78 88 88 78 08 08 00 00 B8 C0 80 80 00 00 00 00 78 F0 08 F0 00 00 40; +1F60: 40 F0 40 48 30 00 00 00 00 88 88 88 78 00 00 00 00 88 88 50 20 00 00 00; +1F78: 00 88 A8 A8 D8 00 00 00 00 C8 30 60 98 00 00 00 00 88 88 88 78 08 70 00; +1F90: 00 F8 30 40 F8 00 00 10 20 20 40 20 20 10 00 20 20 20 20 20 20 20 00 40; +1FA8: 20 20 10 20 20 40 00 50 A0 00 00 00 00 00 00 00 20 50 50 F8 00 00 00 70; +1FC0: 88 80 80 88 70 20 40 50 00 88 88 88 78 00 00 08 10 70 98 E0 78 00 00 20; +1FD8: 50 78 88 98 68 00 00 50 00 78 88 98 68 00 00 40 20 78 88 98 68 00 00 20; +1FF0: 00 78 88 98 68 00 00 00 00 78 80 80 78 20 40 20 50 70 98 E0 78 00 00 50; +2008: 00 70 98 E0 78 00 00 40 20 70 98 E0 78 00 00 50 00 60 20 20 70 00 00 20; +2020: 50 60 20 20 70 00 00 40 20 60 20 20 70 00 00 50 70 88 88 F8 88 00 00 20; +2038: 70 88 88 F8 88 00 00 18 F8 80 E0 80 F8 00 00 00 00 D0 68 B0 D8 00 00 78; +2050: A0 B0 E0 A0 B8 00 00 20 50 70 88 88 70 00 00 50 00 70 88 88 70 00 00 40; +2068: 20 70 88 88 70 00 00 20 50 88 88 88 78 00 00 40 20 88 88 88 78 00 00 50; +2080: 00 88 88 88 78 08 70 50 70 88 88 88 70 00 00 50 88 88 88 88 70 00 00 20; +2098: 20 78 80 80 78 20 20 20 50 40 E0 40 48 B0 00 88 88 50 F8 20 70 20 00 80; +20B0: D0 B0 B0 B8 D0 88 80 38 40 F0 40 F0 40 38 00 08 10 78 88 98 68 00 00 10; +20C8: 20 60 20 20 70 00 00 10 20 70 88 88 70 00 00 10 20 88 88 88 78 00 00 28; +20E0: 50 F0 88 88 88 00 00 28 D0 A8 A8 98 88 00 00 00 00 78 88 98 68 00 70 00; +20F8: 00 70 88 88 70 00 70 20 00 20 60 88 70 00 00 00 00 00 E0 80 00 00 00 00; +2110: 00 00 E0 20 00 00 00 40 48 50 30 48 90 38 00 40 48 50 28 58 B8 08 00 20; +2128: 00 20 20 20 20 00 00 00 00 00 48 90 48 00 00 00 00 00 90 48 90 00 00 28; +2140: 50 70 88 F8 88 00 00 28 50 78 88 98 68 00 00 28 50 70 20 20 70 00 00 28; +2158: 50 60 20 20 70 00 00 28 70 88 88 88 70 00 00 28 50 70 88 88 70 00 00 28; +2170: 50 88 88 88 78 00 00 28 50 00 88 88 78 00 00 FC 48 48 48 48 E8 08 30 48; +2188: 00 D8 48 48 E8 08 30 E0 68 30 E8 58 B8 08 00 50 28 00 00 00 00 00 00 00; +21A0: 20 50 88 50 20 00 00 00 48 50 20 68 A8 00 00 7C A8 A8 A8 68 28 28 44 70; +21B8: 80 70 88 70 08 88 70 00 00 00 00 00 00 FF FF F0 F0 F0 F0 0F 0F 0F 0F 00; +21D0: 00 FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 3C 3C 00 00 00 FF; +21E8: FF FF FF FF FF 00 00 C0 C0 C0 C0 C0 C0 C0 C0 0F 0F 0F 0F F0 F0 F0 F0 FC; +2200: FC FC FC FC FC FC FC 03 03 03 03 03 03 03 03 3F 3F 3F 3F 3F 3F 3F 3F 11; +2218: 22 44 88 11 22 44 88 88 44 22 11 88 44 22 11 FE 7C 38 10 00 00 00 00 00; +2230: 00 00 00 10 38 7C FE 80 C0 E0 F0 E0 C0 80 00 01 03 07 0F 07 03 01 00 FF; +2248: 7E 3C 18 18 3C 7E FF 81 C3 E7 FF FF E7 C3 81 F0 F0 F0 F0 00 00 00 00 00; +2260: 00 00 00 0F 0F 0F 0F 0F 0F 0F 0F 00 00 00 00 00 00 00 00 F0 F0 F0 F0 33; +2278: 33 CC CC 33 33 CC CC 00 10 28 28 7C 00 00 00 10 10 38 10 38 10 10 00 00; +2290: 00 50 88 A8 50 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 FF FF FF FF F0; +22A8: F0 F0 F0 F0 F0 F0 F0 0F 0F 0F 0F 0F 0F 0F 0F FF FF FF FF 00 00 00 00 00; +22C0: 00 68 90 90 68 00 00 60 90 E0 90 90 E0 80 00 F8 88 80 80 80 80 00 00 F8; +22D8: 50 50 50 50 48 80 00 F8 48 20 40 88 F8 00 00 00 00 78 90 88 70 00 00 00; +22F0: 00 88 88 C8 B0 80 80 00 00 50 50 20 50 50 20 70; +2300: 20 70 A8 A8 70 20 70 70 88 F8 88 88 70 00 00 70 88 88 88 50 D8 00 00 30; +2318: 40 30 48 48 30 00 00 00 00 50 A8 A8 50 00 00 00 10 70 A8 A8 70 40 00 00; +2330: 70 80 E0 80 70 00 00 70 88 88 88 88 88 00 00 00 F8 00 F8 00 F8 00 00 00; +2348: 20 20 F8 20 20 F8 00 00 C0 30 08 30 C0 F8 00 00 18 60 80 60 18 F8 00 00; +2360: 18 20 20 20 20 20 20 20 20 20 20 20 20 C0 00 00 20 00 F8 00 20 00 00 00; +2378: 68 B0 00 68 B0 00 00 00 30 48 48 30 00 00 00 00 30 78 78 30 00 00 00 00; +2390: 00 00 00 30 00 00 00 1C 10 10 90 50 30 10 00 E0 90 90 00 00 00 00 00 60; +23A8: 10 60 F0 00 00 00 00 00 70 70 70 70 70 70 00 AA 55 AA 55 AA 55 AA 55 C5; +23C0: E5 F5 57 A7 F3 FC DE 24 F1 E1 E5 D5 E5 F5 7C 07 07 E6 03 6F 47 3E FC CD; +23D8: F8 23 5F 45 F1 E6 03 CD F8 23 47 DB A8 57 A3 B0 E1 CD 80 F3 7B D1 F5 CB; +23F0: 7A C4 1A 25 F1 E1 C1 C9 04 05 C8 07 07 10 FC C9 E5 57 D5 A7 F3 FC DE 24; +2408: C1 E1 D5 E5 7C 07 07 E6 03 6F 47 3E FC CD F8 23 5F 45 7A E6 03 CD F8 23; +2420: 47 DB A8 57 A3 B0 E1 59 CD 85 F3 D1 E5 CB 7A C4 1A 25 E1 C9 08 D9 F3 FD; +2438: E5 F1 DD E5 E1 57 A7 FC DE 24 D5 7A E6 03 47 0E FC DD E5 F1 07 07 E6 03; +2450: 87 28 07 CB 00 CB 01 3D 20 F9 21 67 24 E5 DB A8 F5 A1 B0 D9 C3 8C F3 08; +2468: D9 F3 D1 CB 7A C4 1A 25 08 D9 C9 F3 E5 6F E6 03 47 3E AB C6 55 05 F2 7B; +2480: 24 57 7C 07 07 E6 03 67 47 3E C0 07 07 05 F2 8B 24 5F 2F 4F 7A A3 47 7D; +2498: A7 F2 D6 24 0F 0F E6 03 E5 C5 47 3E AB C6 55 05 F2 A5 24 A3 47 7A E6 C0; +24B0: 67 DB A8 6F E6 C0 B4 D3 A8 3A FF FF 2F A1 B0 4F 32 FF FF 7D D3 A8 21 C5; +24C8: FC 7A E6 03 85 6F 7C CE 00 67 79 77 C1 E1 DB A8 A1 B0 D3 A8 E1 C9 57 0F; +24E0: 0F 5F E6 C0 6F DB A8 4F E6 3F B5 D3 A8 7B E6 03 6F 7C 26 03 18 02 29 29; +24F8: D6 40 30 FA 7C 2F 67 3A FF FF 2F 5F A4 B5 32 FF FF 6F 79 D3 A8 7A E6 03; +2510: 4F 06 00 7D 21 C5 FC 09 77 C9 7A 0F 0F E6 C0 47 DB A8 4F E6 3F B0 D3 A8; +2528: 7B 32 FF FF 79 D3 A8 7A E6 03 4F 06 00 21 C5 FC 09 73 C9 D3 A8 5E 18 03; +2540: D3 A8 73 7A D3 A8 C9 D3 A8 08 CD 98 F3 08 F1 D3 A8 08 C9 DD E9 00 43 2D; +2558: 42 49 4F 53 20 30 2E 32 39 20 20 20 20 20 20 63 62 69 6F 73 2E 73 66 2E; +2570: 6E 65 74 0D 0A 43 68 61 72 61 63 74 65 72 20 73 65 74 3A 20 55 53 0D 0A; +2588: 49 6E 74 65 72 72 75 70 74 20 66 72 65 71 75 65 6E 63 79 3A 20 36 30 48; +25A0: 7A 0D 0A 4B 65 79 62 6F 61 72 64 20 74 79 70 65 3A 20 55 53 0D 0A 0D 0A; +25B8: 0D 0A 0D 0A 00 49 6E 69 74 20 52 4F 4D 20 69 6E 20 73 6C 6F 74 3A 20 00; +25D0: 43 61 6E 6E 6F 74 20 65 78 65 63 75 74 65 20 61 20 42 41 53 49 43 20 52; +25E8: 4F 4D 2E 0D 0A 00 45 52 52 4F 52 3A 00 4D 45 4D 4F 52 59 20 4E 4F 54 20; +2600: 46 4F 55 4E 44 2E 00 43 41 4C 4C 45 44 20 4E 4F 4E 20 45 58 49 53 54 49; +2618: 4E 47 20 42 41 53 49 43 2E 00 53 54 41 43 4B 20 45 52 52 4F 52 2E 00 0D; +2630: 0A 0D 0A 4E 6F 20 63 61 72 74 72 69 64 67 65 20 66 6F 75 6E 64 2E 0D 0A; +2648: 0D 0A 54 68 69 73 20 76 65 72 73 69 6F 6E 20 6F 66 20 43 2D 42 49 4F 53; +2660: 20 63 61 6E 0D 0A 6F 6E 6C 79 20 73 74 61 72 74 20 63 61 72 74 72 69 64; +2678: 67 65 73 2E 0D 0A 50 6C 65 61 73 65 20 72 65 73 74 61 72 74 20 79 6F 75; +2690: 72 20 4D 53 58 0D 0A 28 65 6D 75 6C 61 74 6F 72 29 20 77 69 74 68 20 61; +26A8: 20 63 61 72 74 72 69 64 67 65 0D 0A 69 6E 73 65 72 74 65 64 2E 00 30 31; +26C0: 32 33 34 35 36 37 38 39 2D 3D 5C 5B 5D 3B 27 60 2C 2E 2F 00 61 62 63 64; +26D8: 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 29 21; +26F0: 40 23 24 25 5E 26 2A 28 5F 2B 7C 7B 7D 3A 22 7E 3C 3E 3F 00 41 42 43 44; +2708: 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 09 AC; +2720: AB BA EF BD F4 FB EC 07 17 F1 1E 01 0D 06 05 BB F3 F2 1D 00 C4 11 BC C7; +2738: CD 14 15 13 DC C6 DD C8 0B 1B C2 DB CC 18 D2 12 C0 1A CF 1C 19 0F 0A 00; +2750: FD FC 00 00 F5 00 00 08 1F F0 16 02 0E 04 03 F7 AE AF F6 00 FE 00 FA C1; +2768: CE D4 10 D6 DF CA DE C9 0C D3 C3 D7 CB A9 D1 00 C5 D5 D0 F9 AA F8 EB 9F; +2780: D9 BF 9B 98 E0 E1 E7 87 EE E9 00 ED DA B7 B9 E5 86 A6 A7 00 84 97 8D 8B; +2798: 8C 94 81 B1 A1 91 B3 B5 E6 A4 A2 A3 83 93 89 96 82 95 88 8A A0 85 D8 AD; +27B0: 9E BE 9C 9D 00 00 E2 80 00 00 00 E8 EA B6 B8 E4 8F 00 A8 00 8E 00 00 00; +27C8: 00 99 9A B0 00 92 B2 B4 00 A5 00 E3 00 00 00 00 90 00 00 00 00 00 00 00; +27E0: 00 00 00 00 00 00 00 00 1B 09 00 08 00 0D 20 0C 00 00 1D 1E 1F 1C 2A 2B; +27F8: 2F 30 31 32 33 34 35 36 37 38 39 2D 2C 2E 00 80 70 81 00 82 01 84 F5 87; +2810: 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2828: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2858: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2888: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +28A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +28B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +28D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +28E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2918: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2948: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2978: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +29A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +29C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +29D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +29F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2BC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2BF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2C10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2C28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2C40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2C58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2C70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2C88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2CA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2CB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2CD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2CE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2DA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2DC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2DD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2EB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2EC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2EE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2EF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2F10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2F28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2F40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2F58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2F70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2F88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2FA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2FB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2FD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2FE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3018: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3078: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +30A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +30C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +30D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +30F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3118: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3148: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3178: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3190: 00 00 00 C5 E5 C1 1B 7B B2 28 03 09 18 F8 C1 C9 E5 F5 21 B5 31 CD 9F 09; +31A8: 3E 20 D3 2E 7A D3 2F 7B D3 2F F1 E1 C9 52 4F 4D 42 41 53 00 00 00 00 00; +31C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +31D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +31F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3208: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3238: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3268: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3298: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +32B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +32C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +32E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +32F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3328: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3358: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3388: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +33A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +33B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +33D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +33E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3418: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3478: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +34A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +34C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +34D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +34F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3508: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3538: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3568: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3598: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +35B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +35C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +35E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +35F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3628: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3658: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3688: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +36A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +36B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +36D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +36E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3748: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +37A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +37C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +37D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +37F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3818: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3848: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3878: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +38A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +38C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +38D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +38F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3908: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3938: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3950: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3968: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3980: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3998: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +39B0: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +39C8: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +39E0: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +39F8: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3A10: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3A28: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A E5 F5; +3A40: 21 49 3A CD 9F 09 F1 E1 C9 42 41 53 49 43 20 73 74 61 74 65 6D 65 6E 74; +3A58: 73 20 61 72 65 20 6E 6F 74 20 69 6D 70 6C 65 6D 65 6E 74 65 64 20 79 65; +3A70: 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3A88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3AA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3AB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3AD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3AE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3BA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3BC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3BD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3BF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3CB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3CC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3CE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3CF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3D10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3D28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3D40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3D58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3D70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3D88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3DA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3DB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3DD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3DE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3EA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3ED8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3EF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3FA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3FC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3FD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3FF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4008: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4038: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4068: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4098: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +40B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +40C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +40E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +40F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4128: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4158: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4188: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +41A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +41B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +41D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +41E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4218: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4248: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4278: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +42A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +42C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +42D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +42F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4308: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4338: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4368: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4398: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +43B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +43C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +43E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +43F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4428: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4458: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4488: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +44A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +44B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +44D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +44E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4518: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4548: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4578: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +45A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +45C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +45D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +45F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4618: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4678: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +46A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +46C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +46D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +46F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4708: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4738: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4768: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4798: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +47B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +47C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +47E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +47F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4828: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4858: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4888: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +48A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +48B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +48D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +48E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4918: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4948: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4978: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +49A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +49C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +49D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +49F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4AB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4AC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4AE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4AF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4B10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4B28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4B40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4B58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4B70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4B88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4BA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4BB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4BD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4BE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4CA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4CC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4CD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4CF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4DA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4DC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4DD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4EB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4EC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4EE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4EF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4F10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4F28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4F40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4F58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4F70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4F88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4FA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4FB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4FD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4FE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5018: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5078: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +50A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +50C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +50D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +50F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5108: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5138: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +51B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +51C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +51E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +51F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5228: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5258: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +52A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +52B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +52D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +52E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5318: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5348: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5378: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +53A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +53C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +53D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +53F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5418: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5478: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +54A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +54C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +54D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +54F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5508: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5538: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5568: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5598: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +55B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +55C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +55E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +55F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5628: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5658: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5688: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +56A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +56B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +56D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +56E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5748: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +57A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +57C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +57D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +57F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5808: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5838: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5868: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5898: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +58B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +58C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +58E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +58F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5928: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5958: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5988: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +59A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +59B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +59D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +59E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5BA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5BC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5BD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5BF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5CB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5CC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5CE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5CF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5D10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5D28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5D40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5D58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5D70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5D88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5DA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5DB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5DD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5DE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5EA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5ED8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5EF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5FB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5FC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5FE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5FF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6028: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6058: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6088: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +60A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +60B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +60D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +60E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6118: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6148: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6178: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +61A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +61C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +61D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +61F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6218: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6248: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6278: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +62A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +62C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +62D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +62F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6308: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6338: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6368: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6398: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +63B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +63C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +63E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +63F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6428: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6458: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6488: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +64A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +64B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +64D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +64E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6518: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6548: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6578: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +65A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +65C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +65D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +65F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6608: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6620: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6638: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6650: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6668: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 8E 10 00 00 00 00 00; +6680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6698: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +66B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +66C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +66E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +66F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6728: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6758: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6788: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +67A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +67B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +67D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +67E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6818: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6848: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6878: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +68A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +68C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +68D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +68F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6918: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6948: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6978: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +69A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +69C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +69D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +69F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6AB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6AC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6AE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6AF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6B10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6B28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6B40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6B58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6B70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6B88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6BA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6BB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6BD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6BE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6CA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6CC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6CD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6CF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6DB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6DC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6DE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6DF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6E10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6E28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6E40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6E58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6E70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6E88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6EA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6EB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6ED0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6EE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6FA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6FC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6FD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6FF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7018: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7078: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +70A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +70C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +70D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +70F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7108: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7138: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +71B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +71C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +71E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +71F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7228: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7258: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +72A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +72B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +72D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +72E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7318: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7348: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7378: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +73A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +73C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +73D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +73F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7408: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7438: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7468: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7498: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +74B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +74C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +74E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +74F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7528: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7558: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7588: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +75A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +75B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +75D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +75E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7618: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7678: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +76A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +76C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +76D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +76F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7748: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +77A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +77C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 C9 00 00 00 00 00 00 00 00 00 00; +77D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +77F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7808: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7838: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7868: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7898: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +78B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +78C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +78E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +78F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7928: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7958: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7988: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +79A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +79B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +79D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +79E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7BC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7BF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7C10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7C28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7C40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7C58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7C70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7C88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7CA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7CB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7CD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7CE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7D00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5; +7D18: F5 21 22 7D CD 9F 09 F1 E1 C9 75 6E 6B 6E 6F 77 6E 40 37 44 31 37 00 39; +7D30: 7D DD 21 89 01 CD 3F 1A C9 DD 21 85 01 C3 3F 1A 00 00 00 00 00 00 00 00; +7D48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7D60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7D78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7D90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7DA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7DC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7DD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5 F5 21 1F; +7E18: 7E CD 9F 09 F1 E1 C9 75 6E 6B 6E 6F 77 6E 40 37 45 31 34 00 00 00 00 00; +7E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7E48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7E60: 00 00 00 00 00 00 00 00 00 00 00 C9 00 00 00 00 00 00 00 00 00 00 00 00; +7E78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7EA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7ED8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7EF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7FB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7FC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7FE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7FF8: 00 00 00 00 00 00 00 00; +END; diff --git a/rtl/rom/cbios_main_msx1_eu.mif b/rtl/rom/cbios_main_msx1_eu.mif index 687542f..306485f 100644 --- a/rtl/rom/cbios_main_msx1_eu.mif +++ b/rtl/rom/cbios_main_msx1_eu.mif @@ -1,1382 +1,1382 @@ --- http://srecord.sourceforge.net/ --- --- Generated automatically by srec_cat -o --mif --- -DEPTH = 32768; -WIDTH = 8; -ADDRESS_RADIX = HEX; -DATA_RADIX = HEX; -CONTENT BEGIN -0000: F3 C3 12 0D BF 1B 98 98 C3 ED 10 00 C3 BF 23 00 C3 FF 10 00 C3 00 24 00; -0018: C3 1B 11 00 C3 34 24 00 C3 21 11 00 C3 73 24 00 C3 27 11 A1 02 00 00 00; -0030: C3 39 11 00 00 00 00 00 C3 E6 18 C3 4E 11 C3 58 11 C3 16 02 C3 22 02 C3; -0048: 2E 02 C3 45 02 C3 4D 02 C3 55 02 C3 60 02 C3 6D 02 C3 81 02 C3 97 02 C3; -0060: AD 02 C3 D4 02 00 C3 5E 19 C3 1E 03 C3 82 03 C3 C2 03 C3 05 04 C3 43 04; -0078: C3 8F 04 C3 B7 04 C3 E6 04 C3 19 05 C3 6F 05 C3 82 05 C3 8C 05 C3 97 05; -0090: C3 3A 17 C3 52 17 C3 5C 17 C3 6A 11 C3 7C 11 C3 8F 11 C3 B4 11 C3 D9 14; -00A8: C3 03 15 C3 11 15 C3 36 15 C3 54 15 C3 4B 15 C3 25 16 C3 41 16 C3 53 16; -00C0: C3 56 16 C3 B5 07 C3 66 16 C3 6A 16 C3 7B 16 C3 8D 16 C3 9F 16 C3 8F 17; -00D8: C3 02 18 C3 47 18 C3 59 18 C3 B2 16 C3 C5 16 C3 D7 16 C3 E9 16 C3 FC 16; -00F0: C3 0F 17 C3 21 17 C3 6A 18 C3 79 18 C3 44 08 C3 56 08 C3 67 08 C3 76 08; -0108: C3 86 08 C3 97 08 C3 A9 08 C3 B9 08 C3 F4 08 C3 02 09 C3 14 09 C3 26 09; -0120: C3 37 09 C3 47 09 C3 59 09 C3 6B 09 C3 7D 09 C3 8E 09 C3 A7 18 C3 61 17; -0138: C3 6A 17 C3 6D 17 C3 70 17 C3 73 17 C3 82 17 C3 86 17 C3 8A 17 C3 B3 18; -0150: C3 C5 18 C3 C9 18 C3 DF 18 C3 70 1A 00 00 00 C9 00 00 00 00 00 00 00 00; -0168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -01B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -01C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -01E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -01F8: 00 00 00 00 00 00 00 00 4F 06 00 09 09 C3 11 02 BE 23 28 05 23 23 10 F8; -0210: C9 4E 23 66 69 E9 3A E0 F3 E6 BF 47 0E 01 CD 2E 02 C9 3A E0 F3 F6 40 47; -0228: 0E 01 CD 2E 02 C9 F3 CB B9 78 D3 99 79 F6 80 D3 99 FB E5 21 DF F3 78 06; -0240: 00 09 77 E1 C9 CD 55 02 F6 00 DB 98 C9 F5 CD 60 02 F1 D3 98 C9 F3 7D D3; -0258: 99 7C E6 3F D3 99 FB C9 F3 7D D3 99 7C E6 3F F6 40 D3 99 FB C9 F5 CD 60; -0270: 02 0B 0C 78 41 4F 0C F1 D3 98 05 20 FB 0D 20 F8 C9 CD 55 02 E5 EB 0B 0C; -0288: 78 41 3C 0E 98 ED A2 C2 8D 02 3D 20 F8 E1 C9 EB CD 60 02 EB 0B 0C 78 41; -02A0: 3C 0E 98 ED A3 C2 A3 02 3D 20 F8 EB C9 FE 04 D0 21 B6 02 C3 00 02 82 03; -02B8: C2 03 05 04 43 04 F3 21 DF F3 01 99 08 16 80 ED A3 78 ED 51 14 B7 20 F7; -02D0: FB C3 22 02 3A AF FC FE 08 28 3A 3D F5 3A E9 F3 07 07 07 07 E6 F0 6F 3A; -02E8: EB F3 B5 47 0E 07 CD 2E 02 F1 C0 3A E9 F3 07 07 07 07 E6 F0 21 EA F3 B6; -0300: 2A BF F3 01 20 00 F5 CD 60 02 F1 D3 98 F5 0B 78 B1 20 F7 F1 C9 3A EB F3; -0318: 47 0E 07 C3 2E 02 3A AF FC B7 C8 CD 48 03 3A AF FC FE 04 38 10 2A 28 F9; -0330: 25 25 01 00 02 3A E9 F3 E6 0F CD 6D 02 2A 26 F9 01 00 08 AF CD 6D 02 C9; -0348: 3A AF FC FE 04 38 04 1E D9 18 02 1E D1 2A 28 F9 CD 60 02 3A E9 F3 57 01; -0360: 00 20 F3 7B D3 98 3E 00 00 00 D3 98 79 00 00 00 D3 98 0C CD 8C 05 30 03; -0378: 0C 0C 0C 7A D3 98 10 E3 FB C9 CD 16 02 3E 00 32 AF FC 32 B0 FC 3A AE F3; -0390: 32 B0 F3 3E 01 32 DC F3 32 DD F3 2A B3 F3 22 22 F9 2A B7 F3 22 24 F9 2A; -03A8: B9 F3 22 28 F9 2A BB F3 22 26 F9 CD D4 02 CD 8F 04 CD A8 07 CD CD 07 C3; -03C0: BE 02 CD 16 02 3E 01 32 AF FC 32 B0 FC 3E 01 32 DC F3 32 DD F3 CD D4 02; -03D8: 2A BD F3 22 22 F9 2A C1 F3 22 24 F9 2A C5 F3 22 26 F9 2A C3 F3 22 28 F9; -03F0: CD A8 07 3A AF F3 32 B0 F3 CD B7 04 CD 53 03 CD DC 07 C3 BE 02 CD 16 02; -0408: 3E 02 32 AF FC CD D4 02 2A C7 F3 22 22 F9 CD 60 02 06 03 AF F3 D3 98 3C; -0420: 20 FB 10 F9 FB 2A CB F3 22 24 F9 2A CD F3 22 28 F9 2A CF F3 22 26 F9 CD; -0438: E6 04 CD 53 03 CD F8 07 C3 BE 02 CD 16 02 3E 03 32 AF FC CD D4 02 2A D1; -0450: F3 22 22 F9 CD 60 02 AF 0E 06 F3 F5 1E 04 F5 06 20 D3 98 3C 10 FB F1 1D; -0468: 20 F4 F1 C6 20 0D 20 EB FB 2A D5 F3 22 24 F9 2A D7 F3 22 28 F9 2A D9 F3; -0480: 22 26 F9 CD 19 05 CD 53 03 CD 0E 08 C3 BE 02 3A DF F3 E6 F1 47 0E 00 CD; -0498: 2E 02 3A E0 F3 E6 E7 F6 10 47 0C CD 2E 02 11 B3 F3 0E 02 AF CD 4A 05 13; -04B0: 13 0C AF CD 4A 05 C9 3A DF F3 E6 F1 47 0E 00 CD 2E 02 3A E0 F3 E6 E7 47; -04C8: 0C CD 2E 02 11 BD F3 0E 02 AF CD 4A 05 AF CD 4A 05 AF CD 4A 05 AF CD 4A; -04E0: 05 AF CD 4A 05 C9 3A DF F3 E6 F1 F6 02 47 0E 00 CD 2E 02 3A E0 F3 E6 E7; -04F8: 47 0C CD 2E 02 11 C7 F3 0E 02 AF CD 4A 05 3E 7F CD 4A 05 3E 03 CD 4A 05; -0510: AF CD 4A 05 AF CD 4A 05 C9 3A DF F3 E6 F1 47 0E 00 CD 2E 02 3A E0 F3 E6; -0528: E7 F6 08 47 0C CD 2E 02 11 D1 F3 0E 02 AF CD 4A 05 AF CD 4A 05 AF CD 4A; -0540: 05 AF CD 4A 05 AF CD 4A 05 C9 D5 F5 21 68 05 06 00 09 46 EB 7E 23 66 6F; -0558: 29 8F 10 FC 47 F1 B0 47 CD 2E 02 D1 13 13 0C C9 00 00 06 0A 05 09 05 26; -0570: 00 6F 29 29 29 CD 8C 05 30 02 29 29 ED 5B 26 F9 19 C9 87 87 2A 28 F9 16; -0588: 00 5F 19 C9 3A E0 F3 0F 0F 3E 08 D0 3E 20 C9 F5 FE 20 38 0D 3A AF FC FE; -05A0: 02 28 22 FE 05 30 1C F1 C9 FE 0D 20 FA F1 E5 C5 2A B9 FC 01 08 00 09 22; -05B8: B9 FC 21 00 00 22 B7 FC C1 E1 C9 F1 C9 F1 E5 D5 C5 F5 CD 22 08 ED 5B B9; -05D0: FC ED 4B B7 FC CD B9 08 3A E9 F3 32 F2 F3 2A 2A F9 ED 4B CB F3 09 11 40; -05E8: FC 3A B9 FC E6 07 06 00 4F 09 CD 12 06 01 F0 00 09 3A B9 FC 2F E6 07 4F; -0600: CD 12 06 2A B7 FC 01 08 00 09 22 B7 FC F1 C1 D1 E1 C9 3A B7 FC E6 07 F5; -0618: C5 D5 E5 CD 9B 06 3A B7 FC E6 07 28 1A 3A 2C F9 2F 32 2C F9 E1 01 08 00; -0630: 09 D1 C1 F1 CD 9B 06 3A 2C F9 2F 32 2C F9 C9 C1 01 08 00 09 C1 C1 F1 C9; -0648: F5 E5 C5 D5 57 58 ED 4B C9 F3 09 4F 3A F2 F3 E6 0F 47 CD 45 02 F5 E6 0F; -0660: B8 28 11 F1 F5 0F 0F 0F 0F E6 0F B8 20 0D F1 D1 C1 E1 F1 C9 F1 D1 C1 E1; -0678: F1 2F C9 7A B3 FE FF 28 11 F1 CB 00 CB 00 CB 00 CB 00 E6 0F B0 CD 4D 02; -0690: 18 DD F1 E6 F0 B0 CD 4D 02 18 DA 41 3C 4F 3E 07 A8 3C 47 C5 CD 45 02 47; -06A8: 1A CD 48 06 0D 28 03 0F 18 FA 4F 3A 2C F9 A1 4F 78 B1 CD 4D 02 23 13 C1; -06C0: 10 E1 C9 47 52 50 50 52 54 00 3A AF FC FE 05 C9 F5 CD EF 06 0B 0C 78 41; -06D8: 4F 0C F1 F3 D3 98 10 FC 0D 20 F9 FB C9 CD FB 06 7C E6 3F D3 99 FB C9 CD; -06F0: FB 06 7C E6 3F F6 40 D3 99 FB C9 3A F6 FA B7 28; -0700: 10 3A AF FC FE 05 DA 60 02 FE 07 3A F6 FA 38 01 87 E5 E6 03 0F 6F E6 80; -0718: AC 17 CB 15 17 7D 17 F3 D3 99 3E 8E D3 99 E1 7D D3 99 C9 CD E5 06 DB 98; -0730: C9 F5 CD EF 06 F1 D3 98 C9 F3 D3 99 3E 8F D3 99 DB 99 F5 AF D3 99 3E 8F; -0748: D3 99 FB F1 C9 DB 99 01 00 00 CD 2E 02 01 01 E0 CD 2E 02 01 02 00 CD 2E; -0760: 02 01 03 80 CD 2E 02 01 04 01 CD 2E 02 01 08 08 CD 2E 02 3E 01 32 DC F3; -0778: 32 DD F3 CD DC 07 3E 00 21 00 08 01 00 08 CD 6D 02 3E F5 21 00 20 01 20; -0790: 00 CD 6D 02 01 07 F5 CD 2E 02 21 BF 1B 11 00 08 01 00 08 CD 97 02 C9 C9; -07A8: 21 BF 1B ED 5B 24 F9 01 00 08 C3 97 02 C0 3A AF FC FE 04 D0 E5 21 C5 07; -07C0: CD 00 02 E1 C9 CD 07 DC 07 F8 07 0E 08 3A B0 F3 FE 28 01 C0 03 38 08 01; -07D8: 80 07 18 03 01 00 03 2A 22 F9 3E 20 CD 6D 02 3E 01 21 B2 FB 77 11 B3 FB; -07F0: 01 17 00 ED B0 C3 45 12 AF 01 00 18 2A 24 F9 6F C5 CD 6D 02 C1 3A EA F3; -0808: 2A C9 F3 C3 6D 02 3A EA F3 E6 0F 47 07 07 07 07 B0 01 00 08 2A 24 F9 C3; -0820: 6D 02 ED 4B 20 F9 6F 26 00 29 29 29 09 06 08 11 40 FC C5 D5 E5 3A 1F F9; -0838: CD BF 23 E1 D1 C1 12 13 23 10 EF C9 E5 F5 21 4F 08 CD 9F 09 F1 E1 C9 52; -0850: 49 47 48 54 43 00 E5 F5 21 61 08 CD 9F 09 F1 E1 C9 4C 45 46 54 43 00 E5; -0868: F5 21 72 08 CD 9F 09 F1 E1 C9 55 50 43 00 E5 F5 21 81 08 CD 9F 09 F1 E1; -0880: C9 54 55 50 43 00 E5 F5 21 91 08 CD 9F 09 F1 E1 C9 44 4F 57 4E 43 00 E5; -0898: F5 21 A2 08 CD 9F 09 F1 E1 C9 54 44 4F 57 4E 43 00 ED 4B B7 FC ED 5B B9; -08B0: FC C9 53 43 41 4C 58 59 00 C5 ED 43 B7 FC ED 53 B9 FC 2A B9 FC 29 29 29; -08C8: 29 29 2E 00 06 00 3E FF 32 2C F9 79 E6 07 28 0A 47 3E FF A7 1F 10 FC 32; -08E0: 2C F9 79 E6 F8 4F 06 00 09 22 2A F9 C1 C9 4D 41 50 58 59 00 3A 2C F9 2A; -08F8: 2A F9 C9 46 45 54 43 48 43 00 E5 F5 21 0D 09 CD 9F 09 F1 E1 C9 53 54 4F; -0910: 52 45 43 00 E5 F5 21 1F 09 CD 9F 09 F1 E1 C9 53 45 54 41 54 52 00 E5 F5; -0928: 21 31 09 CD 9F 09 F1 E1 C9 52 45 41 44 43 00 E5 F5 21 42 09 CD 9F 09 F1; -0940: E1 C9 53 45 54 43 00 E5 F5 21 52 09 CD 9F 09 F1 E1 C9 4E 53 45 54 43 58; -0958: 00 E5 F5 21 64 09 CD 9F 09 F1 E1 C9 47 54 41 53 50 43 00 E5 F5 21 76 09; -0970: CD 9F 09 F1 E1 C9 50 4E 54 49 4E 49 00 E5 F5 21 88 09 CD 9F 09 F1 E1 C9; -0988: 53 43 41 4E 52 00 E5 F5 21 99 09 CD 9F 09 F1 E1 C9 53 43 41 4E 4C 00 3E; -09A0: 23 D3 2E CD AB 09 3E 00 D3 2E C9 7E 23 B7 C8 D3 2F 18 F8 E6 0F FE 0A 30; -09B8: 05 C6 30 D3 2F C9 C6 37 D3 2F C9 F5 0F 0F 0F 0F CD B3 09 F1 CD B3 09 C9; -09D0: 7C CD C3 09 7D CD C3 09 C9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -09E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0B98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0BC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0BF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0C10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0C28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0C40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0C58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0C70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0C88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0CA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0CB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0CD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0CE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -0D00: 00 C9 DD E1 FD E1 F1 C1 D1 E1 D9 08 F1 C1 D1 E1 FB C9 3E 82 D3 AB 3E 50; -0D18: D3 AA AF D3 FF 3C D3 FE 3C D3 FD 3C D3 FC 21 FF FF D9 DB A8 F6 F0 47 78; -0D30: D3 A8 3A FF FF 2F F6 F0 4F 79 32 FF FF 21 00 FF 3E 0F 77 BE 20 08 2F 77; -0D48: BE 20 03 25 18 F2 24 7C B7 28 15 D9 BC 38 05 28 03 D9 18 0C 2E 00 67 D9; -0D60: 78 D9 47 D9 79 D9 4F D9 79 D6 10 4F 30 CB 78 D6 10 47 30 BB D9 7D B7 28; -0D78: 06 11 F5 25 C3 87 1A 78 D3 A8 79 32 FF FF D9 21 00 F3 F9 CD 17 0F CD 43; -0D90: 10 CD 4D 07 FB CD 4E 11 06 0F 11 13 0E 21 00 80 C5 E5 D5 3A C1 FC CD BF; -0DA8: 23 E1 D1 C1 BE 20 12 EB 13 23 10 EC DD 21 10 80 FD 2A C0 FC CD 34 24 18; -0DC0: 11 3E 05 32 EA F3 32 EB F3 CD C2 03 21 56 25 CD 8E 10 FB 06 78 CD 8A 10; -0DD8: 3E 04 32 EB F3 3E 04 32 EA F3 3E 0F 32 E9 F3 3E 1D 32 AF F3 CD C2 03 21; -0DF0: 56 25 CD 8E 10 CD 22 0E CD DA FE CD 01 0F 3E 01; -0E00: 32 99 FD AF 32 29 FB CD CB FE 21 2F 26 CD 8E 10 C3 65 1A 43 2D 42 49 4F; -0E18: 53 20 4C 6F 67 6F 20 52 4F 4D 21 C9 FC 11 CA FC 01 3F 00 36 00 ED B0 21; -0E30: C1 FC AF E5 B6 21 00 40 CD 69 0E CC 76 0E 21 00 80 CD 69 0E CC 76 0E CB; -0E48: 7F 28 06 C6 04 CB 67 28 E4 E1 23 3C E6 03 20 DB C9 47 CD BF 23 23 F5 78; -0E60: CD BF 23 23 57 F1 5F 78 C9 E5 CD 59 0E 21 41 42 CD 21 11 78 E1 C9 E5 F5; -0E78: 21 BD 25 CD 8E 10 F1 F5 47 E6 03 C6 30 CD B4 11 78 CB 78 28 0F 3E 2E CD; -0E90: B4 11 78 0F 0F E6 03 C6 30 CD B4 11 3E 0D CD B4 11 3E 0A CD B4 11 F1 E1; -0EA8: 23 23 CD F8 0E 28 15 4F D5 DD E1 F5 FD E1 DB 99 B7 FA B6 0E F5 E5 CD 34; -0EC0: 24 F3 E1 F1 0E 00 CD F8 0E 28 02 CB E9 CD F8 0E 28 02 CB F1 CD F8 0E 28; -0ED8: 02 CB F9 47 E6 0C 5F 78 07 07 07 07 E6 30 B3 5F 7C 07 07 E6 03 B3 21 C9; -0EF0: FC 16 00 5F 19 71 78 C9 C5 CD 59 0E 7A B3 78 C1 C9 21 C9 FC 06 40 7E CB; -0F08: 7F 28 08 E5 21 D0 25 CD 8E 10 E1 23 10 F0 C9 3E 00 21 80 F3 77 11 81 F3; -0F20: 01 7D 0C ED B0 3E C9 21 00 F3 77 11 01 F3 01 7F 00 ED B0 3E C9 21 9A FD; -0F38: 77 11 9B FD 01 4D 02 ED B0 3E FF 21 DA FB 77 11 DB FB 01 15 00 ED B0 3E; -0F50: 00 21 F0 FB 77 11 F1 FB 01 27 00 ED B0 21 F0 FB 22 F8 F3 22 FA F3 D9 22; -0F68: 48 FC D9 21 80 F3 22 4A FC 22 74 F6 21 3B 25 11 80 F3 01 1A 00 ED B0 21; -0F80: 00 00 22 B3 F3 21 00 08 22 B7 F3 21 00 18 22 BD F3 21 00 20 22 BF F3 21; -0F98: 00 00 22 C1 F3 21 00 1B 22 C3 F3 21 00 38 22 C5 F3 21 00 18 22 C7 F3 21; -0FB0: 00 20 22 C9 F3 21 00 00 22 CB F3 21 00 1B 22 CD F3 21 00 38 22 CF F3 21; -0FC8: 00 08 22 D1 F3 21 00 00 22 D5 F3 21 00 1B 22 D7 F3 21 00 38 22 D9 F3 21; -0FE0: 59 F9 22 F3 F3 21 75 F9 22 5D F9 21 F5 F9 22 63 F9 21 75 FA 22 69 F9 3E; -0FF8: 7F 32 5C F9 32 62 F9 32 68 F9 3E 27 32 AE F3 3E 20 32 AF F3 3A AF F3 32; -1010: B0 F3 3E 18 32 B1 F3 3E 04 32 EB F3 3E 04 32 EA F3 3E 0F 32 E9 F3 3E A0; -1028: 32 E0 F3 3A C1 FC 32 1F F9 2A 04 00 22 20 F9 3E C3 21 B4 11 22 E5 FE 32; -1040: E4 FE C9 F3 21 C1 FC DB A8 57 E6 3F 4F D3 A8 3A FF FF 2F 5F E6 0F 32 FF; -1058: FF 47 3A FF FF 2F B8 20 15 7B E6 0F F6 50 32 FF FF 47 3A FF FF 2F B8 20; -1070: 05 06 80 7B 18 04 06 00 7B 2F 32 FF FF 7A D3 A8 70 23 79 C6 40 4F 30 C5; -1088: FB C9 76 10 FD C9 3A AF FC FE 05 30 09 7E B7 C8 CD B4 11 23 18 F7 7E B7; -10A0: C8 DD 21 89 00 CD 3F 1A 23 18 F3 0E 20 3A AF FC B7 C0 0E 28 3A B0 F3 FE; -10B8: 29 D8 0E 50 C9 C5 F5 CD AB 10 3A B0 F3 ED 44 81 3C CB 3F 6F 3A DD F3 3D; -10D0: 85 6F 26 00 44 3A DC F3 3D CB 3F 30 01 09 CB 21 CB 10 B7 20 F4 ED 4B 22; -10E8: F9 09 F1 C1 C9 E5 F5 21 F8 10 CD 9F 09 F1 E1 C9 53 59 4E 43 48 52 00 CD; -1100: 48 FF 7E 23 FE 00 C8 FE 3A C8 FE 30 38 03 FE 3A D8 FE 20 28 ED FE 09 28; -1118: E9 B7 C9 F5 CD E4 FE F1 C9 7C BA C0 7D BB C9 E5 F5 21 32 11 CD 9F 09 F1; -1130: E1 C9 47 45 54 59 50 52 00 08 D9 E1 7E 23 5E 23 56 23 D5 DD E1 F5 FD E1; -1148: E5 08 D9 C3 34 24 1E 8F 3E 0F CD 52 17 C3 3A 17 E5 F5 21 63 11 CD 9F 09; -1160: F1 E1 C9 49 4E 49 46 4E 4B 00 E5 F5 21 75 11 CD 9F 09 F1 E1 C9 53 54 52; -1178: 54 4D 53 00 FB E5 D5 2A FA F3 ED 5B F8 F3 E7 3E FF 20 01 AF D1 E1 C9 CD; -1190: C2 FD E5 D5 2A FA F3 ED 5B F8 F3 E7 20 04 FB 76 18 F2 7E F5 23 7D FE 18; -11A8: 20 03 21 F0 FB 22 FA F3 F1 D1 E1 C9 E5 D5 C5 F5 CD A4 FD 3A AF FC FE 02; -11C0: 30 13 F1 F5 CD 04 14 F1 F5 CD DA 11 CD 19 14 3A DD F3 32 61 F6 F1 C1 D1; -11D8: E1 C9 CD 11 15 D0 28 12 F5 3A A7 FC B7 C2 BD 12 F1 FE 20 38 2A FE 7F CA; -11F0: F6 13 CD BD 10 CD 4D 02 2A DC F3 3A B0 F3 24 BC 38 04 22 DC F3 C9 11 B1; -1208: FB 26 00 19 AF 77 2A DC F3 CD 6C 12 C3 2E 12 06 0C 21 88 14 C3 08 02 3E; -1220: 20 CD F2 11 3A DD F3 E6 07 FE 01 20 F2 C9 2A DC F3 3A B1 F3 2C BD 30 09; -1238: E5 CD 45 12 CD 90 13 E1 2D 22 DC F3 C9 21 01 01 22 DC F3 C9 CD 2E 13 2A; -1250: DC F3 E5 CD 6C 12 3A DC F3 21 B1 F3 BE 30 08 CD 2E 12 CD 2E 13 18 EF E1; -1268: 22 DC F3 C9 3E 01 32 DD F3 C9 3E FF 32 A7 FC C9 3A DD F3 21 B0 F3 BE 30; -1280: 03 3C 18 1F 3A DC F3 21 B1 F3 BE D0 3C 32 DC F3 18 DA 3A DD F3 3D 20 0B; -1298: 3A DC F3 3D C8 32 DC F3 3A B0 F3 32 DD F3 C9 3A DC F3 3D C8 32 DC F3 C9; -12B0: 3A DC F3 21 B1 F3 BE D0 3C 32 DC F3 C9 47 3C 20 0C 32 A7 FC F1 06 0F 21; -12C8: AC 14 C3 08 02 F1 10 04 0E 00 18 04 10 18 0E 01 FE 34 28 06 FE 35 28 08; -12E0: 18 2E 79 32 AA FC 18 28 79 32 A9 FC 18 22 10 08 06 1F 90 32 DD F3 18 18; -12F8: 10 16 06 1F 90 32 DC F3 3E 03 18 0D 3E 01 18 09 3E 02 18 05 3E 04 18 01; -1310: AF 32 A7 FC C9 3A DD F3 21 B0 F3 BE D0 3C 32 DD F3 C9 3A DD F3 3D C8 32; -1328: DD F3 C9 CD 6C 12 21 B1 FB 3A DC F3 5F 16 00 19 77 3A B0 F3 3C 21 DD F3; -1340: 96 4F 06 00 3E 20 CD BD 10 C3 6D 02 CD 6C 12 2A DC F3 E5 45 3A B1 F3 32; -1358: DC F3 90 47 04 3A DC F3 18 0E CD BD 10 EB 3D 32 DC F3 CD BD 10 CD CE 13; -1370: 10 F0 E1 22 DC F3 26 00 3A B1 F3 57 1E 00 95 3D 4F 06 00 21 B1 FB 19 EB; -1388: 62 6B 2B ED B8 C3 2E 13 CD 6C 12 2A DC F3 E5 45 3A B1 F3 90 47 04 3A DC; -13A0: F3 18 0E CD BD 10 EB 3C 32 DC F3 CD BD 10 CD CE 13 10 F0 CD 2E 13 E1 22; -13B8: DC F3 26 00 3A B1 F3 95 3D 4F 06 00 11 B1 FB 19 54 5D 23 ED B0 C9 F5 C5; -13D0: 06 00 3A B0 F3 4F CD DC 13 C1 F1 C9 E5 D5 C5 11 18 FC CD 81 02 C1 D1 D5; -13E8: C5 21 18 FC CD 97 02 C1 E1 09 EB E1 09 C9 3A DD F3 FE 01 C8 3E 20 CD F2; -1400: 11 C3 92 12 3A A9 FC FE 01 C0 3A AF FC FE 02 D0 3A CC FB CD BD 10 C3 4D; -1418: 02 3A A9 FC FE 01 C0 3A AF FC FE 02 D0 CD BD 10 CD 45 02 32 CC FB A7 16; -1430: 00 5F CB 13 CB 12 CB 13 CB 12 CB 13 CB 12 AF 21 AF FC BE 20 05 2A B7 F3; -1448: 18 03 2A C1 F3 E5 19 11 18 FC 01 08 00 CD 81 02 3A AA FC FE 00 20 07 21; -1460: 18 FC 06 08 18 05 21 1E FC 06 02 7E 2F 77 23 10 FA E1 11 F8 07 19 EB 21; -1478: 18 FC 01 08 00 CD 97 02 CD BD 10 3E FF C3 4D 02 07 56 16 08 92 12 09 1F; -1490: 12 0A 2E 12 0B 45 12 0C B6 07 0D 6C 12 1B 72 12 1C 78 12 1D 92 12 1E A7; -14A8: 12 1F B0 12 6A B6 07 45 B6 07 4B 2E 13 4A 4C 12 6C 2B 13 4C 4C 13 4D 90; -14C0: 13 59 0C 13 41 A7 12 42 B0 12 43 15 13 44 22 13 48 45 12 78 04 13 79 08; -14D8: 13 CD B6 FF F5 CD 25 16 38 08 CD 03 15 28 F6 F1 18 0C 3E 0D CD F6 14 AF; -14F0: 32 15 F4 F1 37 C9 F5 D3 91 3E 00 D3 90 2F D3 90; -1500: F1 A7 C9 CD BB FF DB 90 1F 1F 3E FF 30 01 2F A7 C9 E5 F5 21 A6 FC AF BE; -1518: 77 20 08 F1 FE 01 20 13 77 18 11 F1 FE 40 38 09 FE 60 30 05 D6 40 BF 18; -1530: 02 FE 50 37 E1 C9 CD DB FD 3A AA F6 A7 CA 54 15 3E 01 32 DD F3 C3 54 15; -1548: 3F 20 00 CD E0 FD 21 48 15 CD 8E 10 2A DD F3 22 CA FB 11 B0 FB 26 00 7D; -1560: 19 77 CD 8F 11 FE 7F CA E4 15 FE 20 30 11 06 14 21 E5 15 CD 00 02 AF 32; -1578: A8 FC 32 AA FC 18 E3 F5 3A A8 FC A7 C4 8B 15 F1 DF 18 C9 CD 04 14 2A DC; -1590: F3 22 BC F6 3E 20 32 A7 F6 CD BD 10 CD 45 02 FE 20 20 28 2A DC F3 3A B0; -15A8: F3 BC 20 1D 26 00 11 B1 FB 19 7E B7 28 13 3A A7 F6 CD BD 10 CD 4D 02 2A; -15C0: BC F6 22 DC F3 C9 C3 19 14 3E 20 F5 3A A7 F6 DF F1 32 A7 F6 18 C3 C9 37; -15D8: E1 C9 C9 C9 C9 C9 AF E1 C9 C9 C9 C9 C9 18 00 18 00 D6 15 D7 15 18 00 DA; -15F0: 15 DB 15 18 00 DC 15 18 00 18 00 18 00 18 00 DD 15 DE 15 18 00 18 00 18; -1608: 00 E1 15 18 00 18 00 E2 15 18 00 18 00 18 00 18 00 18 00 E3 15 18 00 18; -1620: 00 18 00 18 00 DB AA E6 F0 F6 07 D3 AA DB A9 E6 10 C0 DB AA E6 F0 F6 06; -1638: D3 AA DB A9 E6 02 C0 37 C9 E5 F5 21 4C 16 CD 9F 09 F1 E1 C9 49 53 43 4E; -1650: 54 43 00 C3 41 16 E5 F5 21 61 16 CD 9F 09 F1 E1 C9 42 45 45 50 00 22 DC; -1668: F3 C9 E5 F5 21 75 16 CD 9F 09 F1 E1 C9 46 4E 4B 53 42 00 E5 F5 21 86 16; -1680: CD 9F 09 F1 E1 C9 45 52 41 46 4E 4B 00 E5 F5 21 98 16 CD 9F 09 F1 E1 C9; -1698: 44 53 50 46 4E 4B 00 3A AF FC FE 02 D8 3A B0 FC CD BD FD B7 CA 82 03 C3; -16B0: C2 03 E5 F5 21 BE 16 CD 9F 09 F1 E1 37 C9 54 41 50 49 4F 4E 00 E5 F5 21; -16C8: D1 16 CD 9F 09 F1 E1 37 C9 54 41 50 49 4E 00 E5 F5 21 E2 16 CD 9F 09 F1; -16E0: E1 C9 54 41 50 49 4F 46 00 E5 F5 21 F5 16 CD 9F 09 F1 E1 37 C9 54 41 50; -16F8: 4F 4F 4E 00 E5 F5 21 08 17 CD 9F 09 F1 E1 37 C9 54 41 50 4F 55 54 00 E5; -1710: F5 21 1A 17 CD 9F 09 F1 E1 C9 54 41 50 4F 4F 46 00 C5 47 DB AA 04 28 0C; -1728: CB E7 05 28 09 CB A7 05 28 04 C1 C9 EE 10 D3 AA C1 C9 1E 00 3E 08 CD 52; -1740: 17 3C CD 52 17 3C CD 52 17 3C 1E B8 3E 07 CD 52 17 C9 F3 D3 A0 F5 7B D3; -1758: A1 FB F1 C9 D3 A0 DB A2 C9 B7 3E 0E 28 01 3C D3 AB C9 DB A8 C9 D3 A8 C9; -1770: DB 99 C9 F3 C5 4F DB AA E6 F0 B1 D3 AA DB A9 C1 FB C9 CD A7 FF C9 CD AC; -1788: FF C9 3A 64 F8 A7 C9 C5 FE 00 20 19 3E 08 CD 73 17 0F 0F 0F 0F 2F E6 0F; -17A0: E5 21 F2 17 16 00 5F 19 7E E1 C1 A7 C9 E5 D5 1E 00 3D 28 02 CB F3 3E 0F; -17B8: F3 CD 5C 17 FB E6 BF B3 5F 3E 0F CD 52 17 3E 0E F3 CD 5C 17 FB 2F E6 0F; -17D0: 21 E2 17 06 00 4F 09 7E D1 E1 C1 A7 C9 3E 00 C1 A7 C9 00 01 05 00 07 08; -17E8: 06 07 03 02 04 03 00 01 05 00 00 07 01 08 05 06 00 07 03 00 02 01 04 05; -1800: 03 00 FE 05 30 03 B7 20 09 3E 08 CD 73 17 F6 FE 3C C9 F3 3D D5 1E 03 47; -1818: E6 01 28 02 1E 4C 3E 0F CD 5C 17 E6 BF B3 5F 3E 0F CD 52 17 78 06 10 E6; -1830: 02 28 02 06 20 3E 0E F3 CD 5C 17 FB D1 A0 28 02 18 03 3E FF C9 AF C9 E5; -1848: F5 21 53 18 CD 9F 09 F1 E1 AF C9 47 54 50 41 44 00 E5 F5 21 64 18 CD 9F; -1860: 09 F1 E1 C9 47 54 50 44 4C 00 CD 9A 18 46 04 23 7E 90 23 23 A6 6F 26 00; -1878: C9 CD 9A 18 7E 3C 47 23 96 C8 78 23 23 E5 A6 2B 2B 2B 77 E1 23 7E 23 66; -1890: 6F 05 48 06 00 09 73 F6 01 C9 2A F3 F3 47 07 07 80 80 4F 06 00 09 C9 B7; -18A8: DB AA CB B7 20 02 CB F7 D3 AA C9 E5 F5 21 BE 18 CD 9F 09 F1 E1 C9 4F 55; -18C0: 54 44 4C 50 00 2E 02 18 03 3A 38 FB D5 16 00 5D 21 41 FB 19 1E 25 B7 28; -18D8: 04 19 3D 18 F9 D1 C9 2A FA F3 22 F8 F3 C9 E5 D5 C5 F5 D9 08 E5 D5 C5 F5; -18F0: FD E5 DD E5 CD 9A FD DB 99 B7 32 E7 F3 F2 4E 19 CD 9F FD 2A 9E FC 23 22; -1908: 9E FC AF 32 D9 FB 3A F6 F3 3D 32 F6 F3 20 37 3E 03 32 F6 F3 AF CD 02 18; -1920: 2F E6 01 32 E8 F3 CD 63 19 2A F8 F3 ED 5B FA F3 E7 20 1B 3A F7 F3 3D 32; -1938: F7 F3 20 12 21 DA FB 01 FF 0B 71 23 10 FC CD 63 19 3E 01 32 F7 F3 DD E1; -1950: FD E1 F1 C1 D1 E1 D9 08 F1 C1 D1 E1 FB C9 CD D6 FD ED 45 DB AA E6 F0 4F; -1968: 06 0B 21 E5 FB 79 D3 AA DB A9 77 23 0C 10 F6 DD 21 DA FB 11 E5 FB 3A EB; -1980: FB 0F 21 BE 26 38 03 21 EE 26 0E 0B 1A DD BE 00 C4 B4 19 2F DD A6 00 08; -1998: 1A DD 77 00 08 06 08 0F 38 1A 23 10 FA DD 23 13 0D C8 79 FE 05 20 DD 21; -19B0: DE 27 18 D8 F5 3E 05 32 F7 F3 F1 C9 F5 79 FE 05 28 07 FE 04 28 1C C3 13; -19C8: 1A 78 FE 03 20 04 3E 00 18 21 FE 02 20 04 3E 01 18 19 FE 01 20 35 3E 02; -19E0: 18 11 78 FE 08 20 04 3E 03 18 08 FE 07 20 24 3E 04 18 00 E5 C5 D5 07 07; -19F8: 07 07 21 7F F8 16 00 5F 19 EB 1A A7 28 08 D5 CD 20 1A D1 13 18 F4 D1 C1; -1A10: E1 18 09 7E A7 28 05 E5 CD 20 1A E1 F1 C3 A2 19 2A F8 F3 77 23 7D FE 18; -1A28: 20 03 21 F0 FB D5 ED 5B FA F3 E7 D1 C8 22 F8 F3 C9 CD 3F 1A DD E1 C9 08; -1A40: D9 F5 C5 D5 E5 ED 57 F5 D9 FD E5 3A F8 FA F5 FD E1 08 CD 34 24 FD E1 08; -1A58: D9 F1 E2 5E 1A FB E1 D1 C1 F1 D9 08 C9 18 FE CD DA FE 11 22 26 C3 87 1A; -1A70: E5 F5 21 80 1A CD 9F 09 F1 E1 11 07 26 C3 87 1A 43 41 4C 42 41 53 00 DB; -1A88: 99 21 06 28 06 0C 0E 99 ED B3 01 00 08 AF D3 98 0B 78 B1 20 F8 21 BF 1B; -1AA0: 01 00 08 7E D3 98 23 0B 78 B1 20 F7 3E 00 D3 99 3E 40 D3 99 21 EE 25 7E; -1AB8: D3 98 23 7E A7 20 F9 1A D3 98 13 1A A7 20 F9 C3 65 1A 00 00 00 00 00 00; -1AD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1AE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1BA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -1BC0: 00 00 00 00 00 00 00 3C 42 A5 A5 C3 BD 42 3C 3C 7E DB DB BD C3 7E 3C 6C; -1BD8: AA 92 44 44 28 10 00 10 28 44 82 44 28 10 00 10 38 38 D6 FE D6 38 00 10; -1BF0: 38 7C 7C FE D6 38 00 00 00 00 18 18 00 00 00 FF; -1C00: FF FF E7 E7 FF FF FF 3C 42 81 81 81 81 42 3C C3 BD 7E 7E 7E 7E BD C3 0C; -1C18: 04 08 70 88 88 70 00 00 70 88 88 70 20 70 20 20 30 28 28 20 E0 C0 00 38; -1C30: 3C 24 24 E4 DC 18 00 10 44 38 AA 38 44 10 00 10 10 10 38 10 10 10 10 10; -1C48: 10 10 EF 00 00 00 00 00 00 00 EF 10 10 10 10 10 10 10 E0 10 10 10 10 10; -1C60: 10 10 0F 10 10 10 10 10 10 10 EF 10 10 10 10 10 10 10 10 10 10 10 10 00; -1C78: 00 00 FF 00 00 00 00 00 00 00 0F 10 10 10 10 00 00 00 E0 10 10 10 10 10; -1C90: 10 10 0F 00 00 00 00 10 10 10 E0 00 00 00 00 81 42 24 18 18 24 42 81 01; -1CA8: 02 04 08 10 20 40 80 80 40 20 10 08 04 02 01 00 00 10 FF 10 00 00 00 00; -1CC0: 00 00 00 00 00 00 00 20 20 20 20 00 20 00 00 50 50 00 00 00 00 00 00 00; -1CD8: 50 F8 50 F8 50 00 00 20 70 A0 70 28 70 20 00 00 C8 D0 20 58 98 00 00 60; -1CF0: 90 60 A8 98 60 00 00 40 40 00 00 00 00 00 00 20 40 40 40 40 20 00 00 20; -1D08: 10 10 10 10 20 00 00 00 20 A8 70 50 88 00 00 00 20 20 F8 20 20 00 00 00; -1D20: 00 00 00 00 40 40 00 00 00 00 F8 00 00 00 00 00 00 00 00 00 40 00 00 00; -1D38: 08 10 20 40 80 00 00 70 88 A8 A8 88 70 00 00 20 60 20 20 20 70 00 00 70; -1D50: 88 08 70 80 F8 00 00 F8 08 30 08 88 70 00 00 10 30 50 F8 10 10 00 00 F8; -1D68: 80 70 08 88 70 00 00 30 40 70 88 88 70 00 00 F8 88 10 20 20 20 00 00 70; -1D80: 88 70 88 88 70 00 00 70 88 88 78 08 70 00 00 00 00 40 00 00 40 00 00 00; -1D98: 00 40 00 00 40 40 00 00 18 60 80 60 18 00 00 00 00 F8 00 F8 00 00 00 00; -1DB0: C0 30 08 30 C0 00 00 70 88 30 20 00 20 00 00 70 88 98 A8 A8 98 40 00 70; -1DC8: 88 88 F8 88 88 00 00 E0 90 E0 90 88 F0 00 00 70 88 80 80 88 70 00 00 F0; -1DE0: 48 48 48 48 F0 00 00 F8 80 E0 80 80 F8 00 00 F8 80 80 E0 80 80 00 00 70; -1DF8: 88 80 B8 88 70 00 00 88 88 F8 88 88 88 00 00 70 20 20 20 20 70 00 00 38; -1E10: 08 08 08 88 70 00 00 88 90 A0 E0 90 88 00 00 80 80 80 80 80 F8 00 00 D8; -1E28: A8 A8 88 88 88 00 00 C8 A8 A8 98 98 88 00 00 70 88 88 88 88 70 00 00 F0; -1E40: 88 88 F0 80 80 00 00 70 88 88 A8 90 68 00 00 F0 88 88 F0 A0 98 00 00 70; -1E58: 80 70 08 08 F0 00 00 F8 20 20 20 20 20 00 00 88 88 88 88 88 78 00 00 88; -1E70: 88 88 50 50 20 00 00 88 88 A8 A8 A8 D8 00 00 88 50 20 50 88 88 00 00 88; -1E88: 88 70 20 20 20 00 00 F8 10 20 40 80 F8 00 00 70 40 40 40 40 70 00 00 00; -1EA0: 80 40 20 10 08 00 00 70 10 10 10 10 70 00 00 40 A0 00 00 00 00 00 00 00; -1EB8: 00 00 00 00 00 F8 00 20 10 00 00 00 00 00 00 00 00 78 88 98 68 00 00 80; -1ED0: 80 F0 88 88 F0 00 00 00 00 78 80 80 78 00 00 08 08 78 88 88 78 00 00 00; -1EE8: 00 70 98 E0 78 00 00 30 48 40 40 E0 40 40 40 00 00 78 88 88 78 08 70 80; -1F00: 80 F0 88 88 88 00 00 20 00 60 20 20 70 00 00 10 00 30 10 10 10 10 60 80; -1F18: 80 98 A0 E0 98 00 00 C0 40 40 40 40 70 00 00 00 00 F0 A8 A8 A8 00 00 00; -1F30: 00 F0 88 88 88 00 00 00 00 70 88 88 70 00 00 00 00 F0 88 88 F0 80 80 00; -1F48: 00 78 88 88 78 08 08 00 00 B8 C0 80 80 00 00 00 00 78 F0 08 F0 00 00 40; -1F60: 40 F0 40 48 30 00 00 00 00 88 88 88 78 00 00 00 00 88 88 50 20 00 00 00; -1F78: 00 88 A8 A8 D8 00 00 00 00 C8 30 60 98 00 00 00 00 88 88 88 78 08 70 00; -1F90: 00 F8 30 40 F8 00 00 10 20 20 40 20 20 10 00 20 20 20 20 20 20 20 00 40; -1FA8: 20 20 10 20 20 40 00 50 A0 00 00 00 00 00 00 00 20 50 50 F8 00 00 00 70; -1FC0: 88 80 80 88 70 20 40 50 00 88 88 88 78 00 00 08 10 70 98 E0 78 00 00 20; -1FD8: 50 78 88 98 68 00 00 50 00 78 88 98 68 00 00 40 20 78 88 98 68 00 00 20; -1FF0: 00 78 88 98 68 00 00 00 00 78 80 80 78 20 40 20 50 70 98 E0 78 00 00 50; -2008: 00 70 98 E0 78 00 00 40 20 70 98 E0 78 00 00 50 00 60 20 20 70 00 00 20; -2020: 50 60 20 20 70 00 00 40 20 60 20 20 70 00 00 50 70 88 88 F8 88 00 00 20; -2038: 70 88 88 F8 88 00 00 18 F8 80 E0 80 F8 00 00 00 00 D0 68 B0 D8 00 00 78; -2050: A0 B0 E0 A0 B8 00 00 20 50 70 88 88 70 00 00 50 00 70 88 88 70 00 00 40; -2068: 20 70 88 88 70 00 00 20 50 88 88 88 78 00 00 40 20 88 88 88 78 00 00 50; -2080: 00 88 88 88 78 08 70 50 70 88 88 88 70 00 00 50 88 88 88 88 70 00 00 20; -2098: 20 78 80 80 78 20 20 20 50 40 E0 40 48 B0 00 88 88 50 F8 20 70 20 00 80; -20B0: D0 B0 B0 B8 D0 88 80 38 40 F0 40 F0 40 38 00 08 10 78 88 98 68 00 00 10; -20C8: 20 60 20 20 70 00 00 10 20 70 88 88 70 00 00 10 20 88 88 88 78 00 00 28; -20E0: 50 F0 88 88 88 00 00 28 D0 A8 A8 98 88 00 00 00 00 78 88 98 68 00 70 00; -20F8: 00 70 88 88 70 00 70 20 00 20 60 88 70 00 00 00 00 00 E0 80 00 00 00 00; -2110: 00 00 E0 20 00 00 00 40 48 50 30 48 90 38 00 40 48 50 28 58 B8 08 00 20; -2128: 00 20 20 20 20 00 00 00 00 00 48 90 48 00 00 00 00 00 90 48 90 00 00 28; -2140: 50 70 88 F8 88 00 00 28 50 78 88 98 68 00 00 28 50 70 20 20 70 00 00 28; -2158: 50 60 20 20 70 00 00 28 70 88 88 88 70 00 00 28 50 70 88 88 70 00 00 28; -2170: 50 88 88 88 78 00 00 28 50 00 88 88 78 00 00 FC 48 48 48 48 E8 08 30 48; -2188: 00 D8 48 48 E8 08 30 E0 68 30 E8 58 B8 08 00 50 28 00 00 00 00 00 00 00; -21A0: 20 50 88 50 20 00 00 00 48 50 20 68 A8 00 00 7C A8 A8 A8 68 28 28 44 70; -21B8: 80 70 88 70 08 88 70 00 00 00 00 00 00 FF FF F0 F0 F0 F0 0F 0F 0F 0F 00; -21D0: 00 FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 3C 3C 00 00 00 FF; -21E8: FF FF FF FF FF 00 00 C0 C0 C0 C0 C0 C0 C0 C0 0F 0F 0F 0F F0 F0 F0 F0 FC; -2200: FC FC FC FC FC FC FC 03 03 03 03 03 03 03 03 3F 3F 3F 3F 3F 3F 3F 3F 11; -2218: 22 44 88 11 22 44 88 88 44 22 11 88 44 22 11 FE 7C 38 10 00 00 00 00 00; -2230: 00 00 00 10 38 7C FE 80 C0 E0 F0 E0 C0 80 00 01 03 07 0F 07 03 01 00 FF; -2248: 7E 3C 18 18 3C 7E FF 81 C3 E7 FF FF E7 C3 81 F0 F0 F0 F0 00 00 00 00 00; -2260: 00 00 00 0F 0F 0F 0F 0F 0F 0F 0F 00 00 00 00 00 00 00 00 F0 F0 F0 F0 33; -2278: 33 CC CC 33 33 CC CC 00 10 28 28 7C 00 00 00 10 10 38 10 38 10 10 00 00; -2290: 00 50 88 A8 50 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 FF FF FF FF F0; -22A8: F0 F0 F0 F0 F0 F0 F0 0F 0F 0F 0F 0F 0F 0F 0F FF FF FF FF 00 00 00 00 00; -22C0: 00 68 90 90 68 00 00 60 90 E0 90 90 E0 80 00 F8 88 80 80 80 80 00 00 F8; -22D8: 50 50 50 50 48 80 00 F8 48 20 40 88 F8 00 00 00 00 78 90 88 70 00 00 00; -22F0: 00 88 88 C8 B0 80 80 00 00 50 50 20 50 50 20 70; -2300: 20 70 A8 A8 70 20 70 70 88 F8 88 88 70 00 00 70 88 88 88 50 D8 00 00 30; -2318: 40 30 48 48 30 00 00 00 00 50 A8 A8 50 00 00 00 10 70 A8 A8 70 40 00 00; -2330: 70 80 E0 80 70 00 00 70 88 88 88 88 88 00 00 00 F8 00 F8 00 F8 00 00 00; -2348: 20 20 F8 20 20 F8 00 00 C0 30 08 30 C0 F8 00 00 18 60 80 60 18 F8 00 00; -2360: 18 20 20 20 20 20 20 20 20 20 20 20 20 C0 00 00 20 00 F8 00 20 00 00 00; -2378: 68 B0 00 68 B0 00 00 00 30 48 48 30 00 00 00 00 30 78 78 30 00 00 00 00; -2390: 00 00 00 30 00 00 00 1C 10 10 90 50 30 10 00 E0 90 90 00 00 00 00 00 60; -23A8: 10 60 F0 00 00 00 00 00 70 70 70 70 70 70 00 AA 55 AA 55 AA 55 AA 55 C5; -23C0: E5 F5 57 A7 F3 FC DE 24 F1 E1 E5 D5 E5 F5 7C 07 07 E6 03 6F 47 3E FC CD; -23D8: F8 23 5F 45 F1 E6 03 CD F8 23 47 DB A8 57 A3 B0 E1 CD 80 F3 7B D1 F5 CB; -23F0: 7A C4 1A 25 F1 E1 C1 C9 04 05 C8 07 07 10 FC C9 E5 57 D5 A7 F3 FC DE 24; -2408: C1 E1 D5 E5 7C 07 07 E6 03 6F 47 3E FC CD F8 23 5F 45 7A E6 03 CD F8 23; -2420: 47 DB A8 57 A3 B0 E1 59 CD 85 F3 D1 E5 CB 7A C4 1A 25 E1 C9 08 D9 F3 FD; -2438: E5 F1 DD E5 E1 57 A7 FC DE 24 D5 7A E6 03 47 0E FC DD E5 F1 07 07 E6 03; -2450: 87 28 07 CB 00 CB 01 3D 20 F9 21 67 24 E5 DB A8 F5 A1 B0 D9 C3 8C F3 08; -2468: D9 F3 D1 CB 7A C4 1A 25 08 D9 C9 F3 E5 6F E6 03 47 3E AB C6 55 05 F2 7B; -2480: 24 57 7C 07 07 E6 03 67 47 3E C0 07 07 05 F2 8B 24 5F 2F 4F 7A A3 47 7D; -2498: A7 F2 D6 24 0F 0F E6 03 E5 C5 47 3E AB C6 55 05 F2 A5 24 A3 47 7A E6 C0; -24B0: 67 DB A8 6F E6 C0 B4 D3 A8 3A FF FF 2F A1 B0 4F 32 FF FF 7D D3 A8 21 C5; -24C8: FC 7A E6 03 85 6F 7C CE 00 67 79 77 C1 E1 DB A8 A1 B0 D3 A8 E1 C9 57 0F; -24E0: 0F 5F E6 C0 6F DB A8 4F E6 3F B5 D3 A8 7B E6 03 6F 7C 26 03 18 02 29 29; -24F8: D6 40 30 FA 7C 2F 67 3A FF FF 2F 5F A4 B5 32 FF FF 6F 79 D3 A8 7A E6 03; -2510: 4F 06 00 7D 21 C5 FC 09 77 C9 7A 0F 0F E6 C0 47 DB A8 4F E6 3F B0 D3 A8; -2528: 7B 32 FF FF 79 D3 A8 7A E6 03 4F 06 00 21 C5 FC 09 73 C9 D3 A8 5E 18 03; -2540: D3 A8 73 7A D3 A8 C9 D3 A8 08 CD 98 F3 08 F1 D3 A8 08 C9 DD E9 00 43 2D; -2558: 42 49 4F 53 20 30 2E 32 39 20 20 20 20 20 20 63 62 69 6F 73 2E 73 66 2E; -2570: 6E 65 74 0D 0A 43 68 61 72 61 63 74 65 72 20 73 65 74 3A 20 55 53 0D 0A; -2588: 49 6E 74 65 72 72 75 70 74 20 66 72 65 71 75 65 6E 63 79 3A 20 35 30 48; -25A0: 7A 0D 0A 4B 65 79 62 6F 61 72 64 20 74 79 70 65 3A 20 55 53 0D 0A 0D 0A; -25B8: 0D 0A 0D 0A 00 49 6E 69 74 20 52 4F 4D 20 69 6E 20 73 6C 6F 74 3A 20 00; -25D0: 43 61 6E 6E 6F 74 20 65 78 65 63 75 74 65 20 61 20 42 41 53 49 43 20 52; -25E8: 4F 4D 2E 0D 0A 00 45 52 52 4F 52 3A 00 4D 45 4D 4F 52 59 20 4E 4F 54 20; -2600: 46 4F 55 4E 44 2E 00 43 41 4C 4C 45 44 20 4E 4F 4E 20 45 58 49 53 54 49; -2618: 4E 47 20 42 41 53 49 43 2E 00 53 54 41 43 4B 20 45 52 52 4F 52 2E 00 0D; -2630: 0A 0D 0A 4E 6F 20 63 61 72 74 72 69 64 67 65 20 66 6F 75 6E 64 2E 0D 0A; -2648: 0D 0A 54 68 69 73 20 76 65 72 73 69 6F 6E 20 6F 66 20 43 2D 42 49 4F 53; -2660: 20 63 61 6E 0D 0A 6F 6E 6C 79 20 73 74 61 72 74 20 63 61 72 74 72 69 64; -2678: 67 65 73 2E 0D 0A 50 6C 65 61 73 65 20 72 65 73 74 61 72 74 20 79 6F 75; -2690: 72 20 4D 53 58 0D 0A 28 65 6D 75 6C 61 74 6F 72 29 20 77 69 74 68 20 61; -26A8: 20 63 61 72 74 72 69 64 67 65 0D 0A 69 6E 73 65 72 74 65 64 2E 00 30 31; -26C0: 32 33 34 35 36 37 38 39 2D 3D 5C 5B 5D 3B 27 60 2C 2E 2F 00 61 62 63 64; -26D8: 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 29 21; -26F0: 40 23 24 25 5E 26 2A 28 5F 2B 7C 7B 7D 3A 22 7E 3C 3E 3F 00 41 42 43 44; -2708: 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 09 AC; -2720: AB BA EF BD F4 FB EC 07 17 F1 1E 01 0D 06 05 BB F3 F2 1D 00 C4 11 BC C7; -2738: CD 14 15 13 DC C6 DD C8 0B 1B C2 DB CC 18 D2 12 C0 1A CF 1C 19 0F 0A 00; -2750: FD FC 00 00 F5 00 00 08 1F F0 16 02 0E 04 03 F7 AE AF F6 00 FE 00 FA C1; -2768: CE D4 10 D6 DF CA DE C9 0C D3 C3 D7 CB A9 D1 00 C5 D5 D0 F9 AA F8 EB 9F; -2780: D9 BF 9B 98 E0 E1 E7 87 EE E9 00 ED DA B7 B9 E5 86 A6 A7 00 84 97 8D 8B; -2798: 8C 94 81 B1 A1 91 B3 B5 E6 A4 A2 A3 83 93 89 96 82 95 88 8A A0 85 D8 AD; -27B0: 9E BE 9C 9D 00 00 E2 80 00 00 00 E8 EA B6 B8 E4 8F 00 A8 00 8E 00 00 00; -27C8: 00 99 9A B0 00 92 B2 B4 00 A5 00 E3 00 00 00 00 90 00 00 00 00 00 00 00; -27E0: 00 00 00 00 00 00 00 00 1B 09 00 08 00 0D 20 0C 00 00 1D 1E 1F 1C 2A 2B; -27F8: 2F 30 31 32 33 34 35 36 37 38 39 2D 2C 2E 00 80 70 81 00 82 01 84 F5 87; -2810: 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2828: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2858: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2888: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -28A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -28B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -28D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -28E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2918: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2948: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2978: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -29A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -29C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -29D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -29F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2B98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2BC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2BF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2C10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2C28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2C40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2C58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2C70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2C88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2CA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2CB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2CD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2CE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2D90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2DA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2DC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2DD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2E98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2EB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2EC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2EE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2EF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2F10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2F28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2F40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2F58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2F70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2F88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2FA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2FB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2FD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -2FE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3018: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3078: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -30A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -30C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -30D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -30F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3118: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3148: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3178: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3190: 00 00 00 C5 E5 C1 1B 7B B2 28 03 09 18 F8 C1 C9 E5 F5 21 B5 31 CD 9F 09; -31A8: 3E 20 D3 2E 7A D3 2F 7B D3 2F F1 E1 C9 52 4F 4D 42 41 53 00 00 00 00 00; -31C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -31D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -31F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3208: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3238: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3268: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3298: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -32B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -32C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -32E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -32F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3328: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3358: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3388: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -33A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -33B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -33D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -33E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3418: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3478: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -34A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -34C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -34D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -34F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3508: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3538: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3568: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3598: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -35B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -35C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -35E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -35F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3628: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3658: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3688: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -36A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -36B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -36D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -36E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3748: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -37A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -37C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -37D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -37F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3818: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3848: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3878: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -38A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -38C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -38D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -38F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3908: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3938: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3950: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3968: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3980: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3998: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -39B0: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -39C8: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -39E0: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -39F8: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3A10: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; -3A28: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A E5 F5; -3A40: 21 49 3A CD 9F 09 F1 E1 C9 42 41 53 49 43 20 73 74 61 74 65 6D 65 6E 74; -3A58: 73 20 61 72 65 20 6E 6F 74 20 69 6D 70 6C 65 6D 65 6E 74 65 64 20 79 65; -3A70: 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3A88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3AA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3AB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3AD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3AE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3BA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3BC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3BD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3BF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3C98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3CB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3CC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3CE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3CF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3D10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3D28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3D40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3D58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3D70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3D88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3DA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3DB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3DD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3DE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3EA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3ED8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3EF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3F90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3FA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3FC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3FD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3FF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4008: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4038: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4068: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4098: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -40B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -40C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -40E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -40F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4128: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4158: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4188: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -41A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -41B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -41D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -41E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4218: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4248: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4278: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -42A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -42C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -42D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -42F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4308: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4338: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4368: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4398: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -43B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -43C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -43E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -43F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4428: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4458: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4488: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -44A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -44B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -44D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -44E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4518: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4548: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4578: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -45A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -45C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -45D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -45F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4618: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4678: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -46A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -46C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -46D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -46F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4708: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4738: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4768: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4798: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -47B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -47C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -47E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -47F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4828: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4858: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4888: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -48A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -48B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -48D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -48E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4918: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4948: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4978: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -49A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -49C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -49D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -49F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4A98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4AB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4AC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4AE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4AF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4B10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4B28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4B40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4B58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4B70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4B88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4BA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4BB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4BD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4BE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4C90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4CA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4CC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4CD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4CF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4D90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4DA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4DC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4DD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4E98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4EB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4EC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4EE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4EF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4F10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4F28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4F40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4F58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4F70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4F88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4FA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4FB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4FD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -4FE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5018: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5078: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -50A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -50C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -50D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -50F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5108: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5138: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -51B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -51C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -51E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -51F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5228: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5258: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -52A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -52B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -52D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -52E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5318: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5348: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5378: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -53A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -53C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -53D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -53F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5418: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5478: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -54A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -54C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -54D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -54F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5508: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5538: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5568: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5598: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -55B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -55C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -55E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -55F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5628: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5658: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5688: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -56A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -56B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -56D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -56E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5748: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -57A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -57C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -57D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -57F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5808: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5838: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5868: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5898: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -58B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -58C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -58E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -58F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5928: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5958: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5988: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -59A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -59B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -59D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -59E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5BA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5BC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5BD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5BF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5C98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5CB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5CC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5CE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5CF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5D10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5D28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5D40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5D58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5D70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5D88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5DA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5DB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5DD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5DE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5EA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5ED8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5EF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5F98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5FB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5FC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5FE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -5FF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6028: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6058: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6088: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -60A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -60B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -60D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -60E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6118: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6148: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6178: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -61A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -61C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -61D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -61F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6218: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6248: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6278: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -62A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -62C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -62D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -62F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6308: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6338: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6368: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6398: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -63B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -63C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -63E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -63F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6428: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6458: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6488: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -64A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -64B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -64D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -64E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6518: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6548: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6578: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -65A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -65C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -65D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -65F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6608: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6620: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6638: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6650: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6668: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 8E 10 00 00 00 00 00; -6680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6698: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -66B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -66C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -66E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -66F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6728: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6758: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6788: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -67A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -67B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -67D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -67E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6818: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6848: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6878: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -68A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -68C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -68D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -68F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6918: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6948: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6978: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -69A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -69C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -69D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -69F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6A98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6AB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6AC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6AE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6AF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6B10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6B28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6B40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6B58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6B70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6B88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6BA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6BB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6BD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6BE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6C90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6CA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6CC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6CD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6CF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6D98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6DB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6DC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6DE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6DF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6E10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6E28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6E40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6E58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6E70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6E88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6EA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6EB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6ED0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6EE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6F90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6FA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6FC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6FD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -6FF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7018: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7078: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -70A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -70C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -70D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -70F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7108: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7138: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -71B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -71C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -71E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -71F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7228: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7258: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -72A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -72B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -72D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -72E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7318: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7348: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7378: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -73A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -73C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -73D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -73F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7408: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7438: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7468: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7498: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -74B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -74C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -74E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -74F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7528: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7558: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7588: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -75A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -75B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -75D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -75E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7618: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7678: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -76A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -76C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -76D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -76F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7748: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -77A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -77C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 C9 00 00 00 00 00 00 00 00 00 00; -77D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -77F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7808: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7838: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7868: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7898: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -78B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -78C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -78E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -78F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7928: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7958: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7988: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -79A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -79B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -79D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -79E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7B98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7BC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7BF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7C10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7C28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7C40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7C58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7C70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7C88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7CA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7CB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7CD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7CE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7D00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5; -7D18: F5 21 22 7D CD 9F 09 F1 E1 C9 75 6E 6B 6E 6F 77 6E 40 37 44 31 37 00 39; -7D30: 7D DD 21 89 01 CD 3F 1A C9 DD 21 85 01 C3 3F 1A 00 00 00 00 00 00 00 00; -7D48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7D60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7D78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7D90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7DA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7DC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7DD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5 F5 21 1F; -7E18: 7E CD 9F 09 F1 E1 C9 75 6E 6B 6E 6F 77 6E 40 37 45 31 34 00 00 00 00 00; -7E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7E48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7E60: 00 00 00 00 00 00 00 00 00 00 00 C9 00 00 00 00 00 00 00 00 00 00 00 00; -7E78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7EA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7ED8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7EF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7F98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7FB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7FC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7FE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -7FF8: 00 00 00 00 00 00 00 00; -END; +-- http://srecord.sourceforge.net/ +-- +-- Generated automatically by srec_cat -o --mif +-- +DEPTH = 32768; +WIDTH = 8; +ADDRESS_RADIX = HEX; +DATA_RADIX = HEX; +CONTENT BEGIN +0000: F3 C3 12 0D BF 1B 98 98 C3 ED 10 00 C3 BF 23 00 C3 FF 10 00 C3 00 24 00; +0018: C3 1B 11 00 C3 34 24 00 C3 21 11 00 C3 73 24 00 C3 27 11 A1 02 00 00 00; +0030: C3 39 11 00 00 00 00 00 C3 E6 18 C3 4E 11 C3 58 11 C3 16 02 C3 22 02 C3; +0048: 2E 02 C3 45 02 C3 4D 02 C3 55 02 C3 60 02 C3 6D 02 C3 81 02 C3 97 02 C3; +0060: AD 02 C3 D4 02 00 C3 5E 19 C3 1E 03 C3 82 03 C3 C2 03 C3 05 04 C3 43 04; +0078: C3 8F 04 C3 B7 04 C3 E6 04 C3 19 05 C3 6F 05 C3 82 05 C3 8C 05 C3 97 05; +0090: C3 3A 17 C3 52 17 C3 5C 17 C3 6A 11 C3 7C 11 C3 8F 11 C3 B4 11 C3 D9 14; +00A8: C3 03 15 C3 11 15 C3 36 15 C3 54 15 C3 4B 15 C3 25 16 C3 41 16 C3 53 16; +00C0: C3 56 16 C3 B5 07 C3 66 16 C3 6A 16 C3 7B 16 C3 8D 16 C3 9F 16 C3 8F 17; +00D8: C3 02 18 C3 47 18 C3 59 18 C3 B2 16 C3 C5 16 C3 D7 16 C3 E9 16 C3 FC 16; +00F0: C3 0F 17 C3 21 17 C3 6A 18 C3 79 18 C3 44 08 C3 56 08 C3 67 08 C3 76 08; +0108: C3 86 08 C3 97 08 C3 A9 08 C3 B9 08 C3 F4 08 C3 02 09 C3 14 09 C3 26 09; +0120: C3 37 09 C3 47 09 C3 59 09 C3 6B 09 C3 7D 09 C3 8E 09 C3 A7 18 C3 61 17; +0138: C3 6A 17 C3 6D 17 C3 70 17 C3 73 17 C3 82 17 C3 86 17 C3 8A 17 C3 B3 18; +0150: C3 C5 18 C3 C9 18 C3 DF 18 C3 70 1A 00 00 00 C9 00 00 00 00 00 00 00 00; +0168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +01F8: 00 00 00 00 00 00 00 00 4F 06 00 09 09 C3 11 02 BE 23 28 05 23 23 10 F8; +0210: C9 4E 23 66 69 E9 3A E0 F3 E6 BF 47 0E 01 CD 2E 02 C9 3A E0 F3 F6 40 47; +0228: 0E 01 CD 2E 02 C9 F3 CB B9 78 D3 99 79 F6 80 D3 99 FB E5 21 DF F3 78 06; +0240: 00 09 77 E1 C9 CD 55 02 F6 00 DB 98 C9 F5 CD 60 02 F1 D3 98 C9 F3 7D D3; +0258: 99 7C E6 3F D3 99 FB C9 F3 7D D3 99 7C E6 3F F6 40 D3 99 FB C9 F5 CD 60; +0270: 02 0B 0C 78 41 4F 0C F1 D3 98 05 20 FB 0D 20 F8 C9 CD 55 02 E5 EB 0B 0C; +0288: 78 41 3C 0E 98 ED A2 C2 8D 02 3D 20 F8 E1 C9 EB CD 60 02 EB 0B 0C 78 41; +02A0: 3C 0E 98 ED A3 C2 A3 02 3D 20 F8 EB C9 FE 04 D0 21 B6 02 C3 00 02 82 03; +02B8: C2 03 05 04 43 04 F3 21 DF F3 01 99 08 16 80 ED A3 78 ED 51 14 B7 20 F7; +02D0: FB C3 22 02 3A AF FC FE 08 28 3A 3D F5 3A E9 F3 07 07 07 07 E6 F0 6F 3A; +02E8: EB F3 B5 47 0E 07 CD 2E 02 F1 C0 3A E9 F3 07 07 07 07 E6 F0 21 EA F3 B6; +0300: 2A BF F3 01 20 00 F5 CD 60 02 F1 D3 98 F5 0B 78 B1 20 F7 F1 C9 3A EB F3; +0318: 47 0E 07 C3 2E 02 3A AF FC B7 C8 CD 48 03 3A AF FC FE 04 38 10 2A 28 F9; +0330: 25 25 01 00 02 3A E9 F3 E6 0F CD 6D 02 2A 26 F9 01 00 08 AF CD 6D 02 C9; +0348: 3A AF FC FE 04 38 04 1E D9 18 02 1E D1 2A 28 F9 CD 60 02 3A E9 F3 57 01; +0360: 00 20 F3 7B D3 98 3E 00 00 00 D3 98 79 00 00 00 D3 98 0C CD 8C 05 30 03; +0378: 0C 0C 0C 7A D3 98 10 E3 FB C9 CD 16 02 3E 00 32 AF FC 32 B0 FC 3A AE F3; +0390: 32 B0 F3 3E 01 32 DC F3 32 DD F3 2A B3 F3 22 22 F9 2A B7 F3 22 24 F9 2A; +03A8: B9 F3 22 28 F9 2A BB F3 22 26 F9 CD D4 02 CD 8F 04 CD A8 07 CD CD 07 C3; +03C0: BE 02 CD 16 02 3E 01 32 AF FC 32 B0 FC 3E 01 32 DC F3 32 DD F3 CD D4 02; +03D8: 2A BD F3 22 22 F9 2A C1 F3 22 24 F9 2A C5 F3 22 26 F9 2A C3 F3 22 28 F9; +03F0: CD A8 07 3A AF F3 32 B0 F3 CD B7 04 CD 53 03 CD DC 07 C3 BE 02 CD 16 02; +0408: 3E 02 32 AF FC CD D4 02 2A C7 F3 22 22 F9 CD 60 02 06 03 AF F3 D3 98 3C; +0420: 20 FB 10 F9 FB 2A CB F3 22 24 F9 2A CD F3 22 28 F9 2A CF F3 22 26 F9 CD; +0438: E6 04 CD 53 03 CD F8 07 C3 BE 02 CD 16 02 3E 03 32 AF FC CD D4 02 2A D1; +0450: F3 22 22 F9 CD 60 02 AF 0E 06 F3 F5 1E 04 F5 06 20 D3 98 3C 10 FB F1 1D; +0468: 20 F4 F1 C6 20 0D 20 EB FB 2A D5 F3 22 24 F9 2A D7 F3 22 28 F9 2A D9 F3; +0480: 22 26 F9 CD 19 05 CD 53 03 CD 0E 08 C3 BE 02 3A DF F3 E6 F1 47 0E 00 CD; +0498: 2E 02 3A E0 F3 E6 E7 F6 10 47 0C CD 2E 02 11 B3 F3 0E 02 AF CD 4A 05 13; +04B0: 13 0C AF CD 4A 05 C9 3A DF F3 E6 F1 47 0E 00 CD 2E 02 3A E0 F3 E6 E7 47; +04C8: 0C CD 2E 02 11 BD F3 0E 02 AF CD 4A 05 AF CD 4A 05 AF CD 4A 05 AF CD 4A; +04E0: 05 AF CD 4A 05 C9 3A DF F3 E6 F1 F6 02 47 0E 00 CD 2E 02 3A E0 F3 E6 E7; +04F8: 47 0C CD 2E 02 11 C7 F3 0E 02 AF CD 4A 05 3E 7F CD 4A 05 3E 03 CD 4A 05; +0510: AF CD 4A 05 AF CD 4A 05 C9 3A DF F3 E6 F1 47 0E 00 CD 2E 02 3A E0 F3 E6; +0528: E7 F6 08 47 0C CD 2E 02 11 D1 F3 0E 02 AF CD 4A 05 AF CD 4A 05 AF CD 4A; +0540: 05 AF CD 4A 05 AF CD 4A 05 C9 D5 F5 21 68 05 06 00 09 46 EB 7E 23 66 6F; +0558: 29 8F 10 FC 47 F1 B0 47 CD 2E 02 D1 13 13 0C C9 00 00 06 0A 05 09 05 26; +0570: 00 6F 29 29 29 CD 8C 05 30 02 29 29 ED 5B 26 F9 19 C9 87 87 2A 28 F9 16; +0588: 00 5F 19 C9 3A E0 F3 0F 0F 3E 08 D0 3E 20 C9 F5 FE 20 38 0D 3A AF FC FE; +05A0: 02 28 22 FE 05 30 1C F1 C9 FE 0D 20 FA F1 E5 C5 2A B9 FC 01 08 00 09 22; +05B8: B9 FC 21 00 00 22 B7 FC C1 E1 C9 F1 C9 F1 E5 D5 C5 F5 CD 22 08 ED 5B B9; +05D0: FC ED 4B B7 FC CD B9 08 3A E9 F3 32 F2 F3 2A 2A F9 ED 4B CB F3 09 11 40; +05E8: FC 3A B9 FC E6 07 06 00 4F 09 CD 12 06 01 F0 00 09 3A B9 FC 2F E6 07 4F; +0600: CD 12 06 2A B7 FC 01 08 00 09 22 B7 FC F1 C1 D1 E1 C9 3A B7 FC E6 07 F5; +0618: C5 D5 E5 CD 9B 06 3A B7 FC E6 07 28 1A 3A 2C F9 2F 32 2C F9 E1 01 08 00; +0630: 09 D1 C1 F1 CD 9B 06 3A 2C F9 2F 32 2C F9 C9 C1 01 08 00 09 C1 C1 F1 C9; +0648: F5 E5 C5 D5 57 58 ED 4B C9 F3 09 4F 3A F2 F3 E6 0F 47 CD 45 02 F5 E6 0F; +0660: B8 28 11 F1 F5 0F 0F 0F 0F E6 0F B8 20 0D F1 D1 C1 E1 F1 C9 F1 D1 C1 E1; +0678: F1 2F C9 7A B3 FE FF 28 11 F1 CB 00 CB 00 CB 00 CB 00 E6 0F B0 CD 4D 02; +0690: 18 DD F1 E6 F0 B0 CD 4D 02 18 DA 41 3C 4F 3E 07 A8 3C 47 C5 CD 45 02 47; +06A8: 1A CD 48 06 0D 28 03 0F 18 FA 4F 3A 2C F9 A1 4F 78 B1 CD 4D 02 23 13 C1; +06C0: 10 E1 C9 47 52 50 50 52 54 00 3A AF FC FE 05 C9 F5 CD EF 06 0B 0C 78 41; +06D8: 4F 0C F1 F3 D3 98 10 FC 0D 20 F9 FB C9 CD FB 06 7C E6 3F D3 99 FB C9 CD; +06F0: FB 06 7C E6 3F F6 40 D3 99 FB C9 3A F6 FA B7 28; +0700: 10 3A AF FC FE 05 DA 60 02 FE 07 3A F6 FA 38 01 87 E5 E6 03 0F 6F E6 80; +0718: AC 17 CB 15 17 7D 17 F3 D3 99 3E 8E D3 99 E1 7D D3 99 C9 CD E5 06 DB 98; +0730: C9 F5 CD EF 06 F1 D3 98 C9 F3 D3 99 3E 8F D3 99 DB 99 F5 AF D3 99 3E 8F; +0748: D3 99 FB F1 C9 DB 99 01 00 00 CD 2E 02 01 01 E0 CD 2E 02 01 02 00 CD 2E; +0760: 02 01 03 80 CD 2E 02 01 04 01 CD 2E 02 01 08 08 CD 2E 02 3E 01 32 DC F3; +0778: 32 DD F3 CD DC 07 3E 00 21 00 08 01 00 08 CD 6D 02 3E F5 21 00 20 01 20; +0790: 00 CD 6D 02 01 07 F5 CD 2E 02 21 BF 1B 11 00 08 01 00 08 CD 97 02 C9 C9; +07A8: 21 BF 1B ED 5B 24 F9 01 00 08 C3 97 02 C0 3A AF FC FE 04 D0 E5 21 C5 07; +07C0: CD 00 02 E1 C9 CD 07 DC 07 F8 07 0E 08 3A B0 F3 FE 28 01 C0 03 38 08 01; +07D8: 80 07 18 03 01 00 03 2A 22 F9 3E 20 CD 6D 02 3E 01 21 B2 FB 77 11 B3 FB; +07F0: 01 17 00 ED B0 C3 45 12 AF 01 00 18 2A 24 F9 6F C5 CD 6D 02 C1 3A EA F3; +0808: 2A C9 F3 C3 6D 02 3A EA F3 E6 0F 47 07 07 07 07 B0 01 00 08 2A 24 F9 C3; +0820: 6D 02 ED 4B 20 F9 6F 26 00 29 29 29 09 06 08 11 40 FC C5 D5 E5 3A 1F F9; +0838: CD BF 23 E1 D1 C1 12 13 23 10 EF C9 E5 F5 21 4F 08 CD 9F 09 F1 E1 C9 52; +0850: 49 47 48 54 43 00 E5 F5 21 61 08 CD 9F 09 F1 E1 C9 4C 45 46 54 43 00 E5; +0868: F5 21 72 08 CD 9F 09 F1 E1 C9 55 50 43 00 E5 F5 21 81 08 CD 9F 09 F1 E1; +0880: C9 54 55 50 43 00 E5 F5 21 91 08 CD 9F 09 F1 E1 C9 44 4F 57 4E 43 00 E5; +0898: F5 21 A2 08 CD 9F 09 F1 E1 C9 54 44 4F 57 4E 43 00 ED 4B B7 FC ED 5B B9; +08B0: FC C9 53 43 41 4C 58 59 00 C5 ED 43 B7 FC ED 53 B9 FC 2A B9 FC 29 29 29; +08C8: 29 29 2E 00 06 00 3E FF 32 2C F9 79 E6 07 28 0A 47 3E FF A7 1F 10 FC 32; +08E0: 2C F9 79 E6 F8 4F 06 00 09 22 2A F9 C1 C9 4D 41 50 58 59 00 3A 2C F9 2A; +08F8: 2A F9 C9 46 45 54 43 48 43 00 E5 F5 21 0D 09 CD 9F 09 F1 E1 C9 53 54 4F; +0910: 52 45 43 00 E5 F5 21 1F 09 CD 9F 09 F1 E1 C9 53 45 54 41 54 52 00 E5 F5; +0928: 21 31 09 CD 9F 09 F1 E1 C9 52 45 41 44 43 00 E5 F5 21 42 09 CD 9F 09 F1; +0940: E1 C9 53 45 54 43 00 E5 F5 21 52 09 CD 9F 09 F1 E1 C9 4E 53 45 54 43 58; +0958: 00 E5 F5 21 64 09 CD 9F 09 F1 E1 C9 47 54 41 53 50 43 00 E5 F5 21 76 09; +0970: CD 9F 09 F1 E1 C9 50 4E 54 49 4E 49 00 E5 F5 21 88 09 CD 9F 09 F1 E1 C9; +0988: 53 43 41 4E 52 00 E5 F5 21 99 09 CD 9F 09 F1 E1 C9 53 43 41 4E 4C 00 3E; +09A0: 23 D3 2E CD AB 09 3E 00 D3 2E C9 7E 23 B7 C8 D3 2F 18 F8 E6 0F FE 0A 30; +09B8: 05 C6 30 D3 2F C9 C6 37 D3 2F C9 F5 0F 0F 0F 0F CD B3 09 F1 CD B3 09 C9; +09D0: 7C CD C3 09 7D CD C3 09 C9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +09E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0B98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0BF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0C88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0CE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +0D00: 00 C9 DD E1 FD E1 F1 C1 D1 E1 D9 08 F1 C1 D1 E1 FB C9 3E 82 D3 AB 3E 50; +0D18: D3 AA AF D3 FF 3C D3 FE 3C D3 FD 3C D3 FC 21 FF FF D9 DB A8 F6 F0 47 78; +0D30: D3 A8 3A FF FF 2F F6 F0 4F 79 32 FF FF 21 00 FF 3E 0F 77 BE 20 08 2F 77; +0D48: BE 20 03 25 18 F2 24 7C B7 28 15 D9 BC 38 05 28 03 D9 18 0C 2E 00 67 D9; +0D60: 78 D9 47 D9 79 D9 4F D9 79 D6 10 4F 30 CB 78 D6 10 47 30 BB D9 7D B7 28; +0D78: 06 11 F5 25 C3 87 1A 78 D3 A8 79 32 FF FF D9 21 00 F3 F9 CD 17 0F CD 43; +0D90: 10 CD 4D 07 FB CD 4E 11 06 0F 11 13 0E 21 00 80 C5 E5 D5 3A C1 FC CD BF; +0DA8: 23 E1 D1 C1 BE 20 12 EB 13 23 10 EC DD 21 10 80 FD 2A C0 FC CD 34 24 18; +0DC0: 11 3E 05 32 EA F3 32 EB F3 CD C2 03 21 56 25 CD 8E 10 FB 06 78 CD 8A 10; +0DD8: 3E 04 32 EB F3 3E 04 32 EA F3 3E 0F 32 E9 F3 3E 1D 32 AF F3 CD C2 03 21; +0DF0: 56 25 CD 8E 10 CD 22 0E CD DA FE CD 01 0F 3E 01; +0E00: 32 99 FD AF 32 29 FB CD CB FE 21 2F 26 CD 8E 10 C3 65 1A 43 2D 42 49 4F; +0E18: 53 20 4C 6F 67 6F 20 52 4F 4D 21 C9 FC 11 CA FC 01 3F 00 36 00 ED B0 21; +0E30: C1 FC AF E5 B6 21 00 40 CD 69 0E CC 76 0E 21 00 80 CD 69 0E CC 76 0E CB; +0E48: 7F 28 06 C6 04 CB 67 28 E4 E1 23 3C E6 03 20 DB C9 47 CD BF 23 23 F5 78; +0E60: CD BF 23 23 57 F1 5F 78 C9 E5 CD 59 0E 21 41 42 CD 21 11 78 E1 C9 E5 F5; +0E78: 21 BD 25 CD 8E 10 F1 F5 47 E6 03 C6 30 CD B4 11 78 CB 78 28 0F 3E 2E CD; +0E90: B4 11 78 0F 0F E6 03 C6 30 CD B4 11 3E 0D CD B4 11 3E 0A CD B4 11 F1 E1; +0EA8: 23 23 CD F8 0E 28 15 4F D5 DD E1 F5 FD E1 DB 99 B7 FA B6 0E F5 E5 CD 34; +0EC0: 24 F3 E1 F1 0E 00 CD F8 0E 28 02 CB E9 CD F8 0E 28 02 CB F1 CD F8 0E 28; +0ED8: 02 CB F9 47 E6 0C 5F 78 07 07 07 07 E6 30 B3 5F 7C 07 07 E6 03 B3 21 C9; +0EF0: FC 16 00 5F 19 71 78 C9 C5 CD 59 0E 7A B3 78 C1 C9 21 C9 FC 06 40 7E CB; +0F08: 7F 28 08 E5 21 D0 25 CD 8E 10 E1 23 10 F0 C9 3E 00 21 80 F3 77 11 81 F3; +0F20: 01 7D 0C ED B0 3E C9 21 00 F3 77 11 01 F3 01 7F 00 ED B0 3E C9 21 9A FD; +0F38: 77 11 9B FD 01 4D 02 ED B0 3E FF 21 DA FB 77 11 DB FB 01 15 00 ED B0 3E; +0F50: 00 21 F0 FB 77 11 F1 FB 01 27 00 ED B0 21 F0 FB 22 F8 F3 22 FA F3 D9 22; +0F68: 48 FC D9 21 80 F3 22 4A FC 22 74 F6 21 3B 25 11 80 F3 01 1A 00 ED B0 21; +0F80: 00 00 22 B3 F3 21 00 08 22 B7 F3 21 00 18 22 BD F3 21 00 20 22 BF F3 21; +0F98: 00 00 22 C1 F3 21 00 1B 22 C3 F3 21 00 38 22 C5 F3 21 00 18 22 C7 F3 21; +0FB0: 00 20 22 C9 F3 21 00 00 22 CB F3 21 00 1B 22 CD F3 21 00 38 22 CF F3 21; +0FC8: 00 08 22 D1 F3 21 00 00 22 D5 F3 21 00 1B 22 D7 F3 21 00 38 22 D9 F3 21; +0FE0: 59 F9 22 F3 F3 21 75 F9 22 5D F9 21 F5 F9 22 63 F9 21 75 FA 22 69 F9 3E; +0FF8: 7F 32 5C F9 32 62 F9 32 68 F9 3E 27 32 AE F3 3E 20 32 AF F3 3A AF F3 32; +1010: B0 F3 3E 18 32 B1 F3 3E 04 32 EB F3 3E 04 32 EA F3 3E 0F 32 E9 F3 3E A0; +1028: 32 E0 F3 3A C1 FC 32 1F F9 2A 04 00 22 20 F9 3E C3 21 B4 11 22 E5 FE 32; +1040: E4 FE C9 F3 21 C1 FC DB A8 57 E6 3F 4F D3 A8 3A FF FF 2F 5F E6 0F 32 FF; +1058: FF 47 3A FF FF 2F B8 20 15 7B E6 0F F6 50 32 FF FF 47 3A FF FF 2F B8 20; +1070: 05 06 80 7B 18 04 06 00 7B 2F 32 FF FF 7A D3 A8 70 23 79 C6 40 4F 30 C5; +1088: FB C9 76 10 FD C9 3A AF FC FE 05 30 09 7E B7 C8 CD B4 11 23 18 F7 7E B7; +10A0: C8 DD 21 89 00 CD 3F 1A 23 18 F3 0E 20 3A AF FC B7 C0 0E 28 3A B0 F3 FE; +10B8: 29 D8 0E 50 C9 C5 F5 CD AB 10 3A B0 F3 ED 44 81 3C CB 3F 6F 3A DD F3 3D; +10D0: 85 6F 26 00 44 3A DC F3 3D CB 3F 30 01 09 CB 21 CB 10 B7 20 F4 ED 4B 22; +10E8: F9 09 F1 C1 C9 E5 F5 21 F8 10 CD 9F 09 F1 E1 C9 53 59 4E 43 48 52 00 CD; +1100: 48 FF 7E 23 FE 00 C8 FE 3A C8 FE 30 38 03 FE 3A D8 FE 20 28 ED FE 09 28; +1118: E9 B7 C9 F5 CD E4 FE F1 C9 7C BA C0 7D BB C9 E5 F5 21 32 11 CD 9F 09 F1; +1130: E1 C9 47 45 54 59 50 52 00 08 D9 E1 7E 23 5E 23 56 23 D5 DD E1 F5 FD E1; +1148: E5 08 D9 C3 34 24 1E 8F 3E 0F CD 52 17 C3 3A 17 E5 F5 21 63 11 CD 9F 09; +1160: F1 E1 C9 49 4E 49 46 4E 4B 00 E5 F5 21 75 11 CD 9F 09 F1 E1 C9 53 54 52; +1178: 54 4D 53 00 FB E5 D5 2A FA F3 ED 5B F8 F3 E7 3E FF 20 01 AF D1 E1 C9 CD; +1190: C2 FD E5 D5 2A FA F3 ED 5B F8 F3 E7 20 04 FB 76 18 F2 7E F5 23 7D FE 18; +11A8: 20 03 21 F0 FB 22 FA F3 F1 D1 E1 C9 E5 D5 C5 F5 CD A4 FD 3A AF FC FE 02; +11C0: 30 13 F1 F5 CD 04 14 F1 F5 CD DA 11 CD 19 14 3A DD F3 32 61 F6 F1 C1 D1; +11D8: E1 C9 CD 11 15 D0 28 12 F5 3A A7 FC B7 C2 BD 12 F1 FE 20 38 2A FE 7F CA; +11F0: F6 13 CD BD 10 CD 4D 02 2A DC F3 3A B0 F3 24 BC 38 04 22 DC F3 C9 11 B1; +1208: FB 26 00 19 AF 77 2A DC F3 CD 6C 12 C3 2E 12 06 0C 21 88 14 C3 08 02 3E; +1220: 20 CD F2 11 3A DD F3 E6 07 FE 01 20 F2 C9 2A DC F3 3A B1 F3 2C BD 30 09; +1238: E5 CD 45 12 CD 90 13 E1 2D 22 DC F3 C9 21 01 01 22 DC F3 C9 CD 2E 13 2A; +1250: DC F3 E5 CD 6C 12 3A DC F3 21 B1 F3 BE 30 08 CD 2E 12 CD 2E 13 18 EF E1; +1268: 22 DC F3 C9 3E 01 32 DD F3 C9 3E FF 32 A7 FC C9 3A DD F3 21 B0 F3 BE 30; +1280: 03 3C 18 1F 3A DC F3 21 B1 F3 BE D0 3C 32 DC F3 18 DA 3A DD F3 3D 20 0B; +1298: 3A DC F3 3D C8 32 DC F3 3A B0 F3 32 DD F3 C9 3A DC F3 3D C8 32 DC F3 C9; +12B0: 3A DC F3 21 B1 F3 BE D0 3C 32 DC F3 C9 47 3C 20 0C 32 A7 FC F1 06 0F 21; +12C8: AC 14 C3 08 02 F1 10 04 0E 00 18 04 10 18 0E 01 FE 34 28 06 FE 35 28 08; +12E0: 18 2E 79 32 AA FC 18 28 79 32 A9 FC 18 22 10 08 06 1F 90 32 DD F3 18 18; +12F8: 10 16 06 1F 90 32 DC F3 3E 03 18 0D 3E 01 18 09 3E 02 18 05 3E 04 18 01; +1310: AF 32 A7 FC C9 3A DD F3 21 B0 F3 BE D0 3C 32 DD F3 C9 3A DD F3 3D C8 32; +1328: DD F3 C9 CD 6C 12 21 B1 FB 3A DC F3 5F 16 00 19 77 3A B0 F3 3C 21 DD F3; +1340: 96 4F 06 00 3E 20 CD BD 10 C3 6D 02 CD 6C 12 2A DC F3 E5 45 3A B1 F3 32; +1358: DC F3 90 47 04 3A DC F3 18 0E CD BD 10 EB 3D 32 DC F3 CD BD 10 CD CE 13; +1370: 10 F0 E1 22 DC F3 26 00 3A B1 F3 57 1E 00 95 3D 4F 06 00 21 B1 FB 19 EB; +1388: 62 6B 2B ED B8 C3 2E 13 CD 6C 12 2A DC F3 E5 45 3A B1 F3 90 47 04 3A DC; +13A0: F3 18 0E CD BD 10 EB 3C 32 DC F3 CD BD 10 CD CE 13 10 F0 CD 2E 13 E1 22; +13B8: DC F3 26 00 3A B1 F3 95 3D 4F 06 00 11 B1 FB 19 54 5D 23 ED B0 C9 F5 C5; +13D0: 06 00 3A B0 F3 4F CD DC 13 C1 F1 C9 E5 D5 C5 11 18 FC CD 81 02 C1 D1 D5; +13E8: C5 21 18 FC CD 97 02 C1 E1 09 EB E1 09 C9 3A DD F3 FE 01 C8 3E 20 CD F2; +1400: 11 C3 92 12 3A A9 FC FE 01 C0 3A AF FC FE 02 D0 3A CC FB CD BD 10 C3 4D; +1418: 02 3A A9 FC FE 01 C0 3A AF FC FE 02 D0 CD BD 10 CD 45 02 32 CC FB A7 16; +1430: 00 5F CB 13 CB 12 CB 13 CB 12 CB 13 CB 12 AF 21 AF FC BE 20 05 2A B7 F3; +1448: 18 03 2A C1 F3 E5 19 11 18 FC 01 08 00 CD 81 02 3A AA FC FE 00 20 07 21; +1460: 18 FC 06 08 18 05 21 1E FC 06 02 7E 2F 77 23 10 FA E1 11 F8 07 19 EB 21; +1478: 18 FC 01 08 00 CD 97 02 CD BD 10 3E FF C3 4D 02 07 56 16 08 92 12 09 1F; +1490: 12 0A 2E 12 0B 45 12 0C B6 07 0D 6C 12 1B 72 12 1C 78 12 1D 92 12 1E A7; +14A8: 12 1F B0 12 6A B6 07 45 B6 07 4B 2E 13 4A 4C 12 6C 2B 13 4C 4C 13 4D 90; +14C0: 13 59 0C 13 41 A7 12 42 B0 12 43 15 13 44 22 13 48 45 12 78 04 13 79 08; +14D8: 13 CD B6 FF F5 CD 25 16 38 08 CD 03 15 28 F6 F1 18 0C 3E 0D CD F6 14 AF; +14F0: 32 15 F4 F1 37 C9 F5 D3 91 3E 00 D3 90 2F D3 90; +1500: F1 A7 C9 CD BB FF DB 90 1F 1F 3E FF 30 01 2F A7 C9 E5 F5 21 A6 FC AF BE; +1518: 77 20 08 F1 FE 01 20 13 77 18 11 F1 FE 40 38 09 FE 60 30 05 D6 40 BF 18; +1530: 02 FE 50 37 E1 C9 CD DB FD 3A AA F6 A7 CA 54 15 3E 01 32 DD F3 C3 54 15; +1548: 3F 20 00 CD E0 FD 21 48 15 CD 8E 10 2A DD F3 22 CA FB 11 B0 FB 26 00 7D; +1560: 19 77 CD 8F 11 FE 7F CA E4 15 FE 20 30 11 06 14 21 E5 15 CD 00 02 AF 32; +1578: A8 FC 32 AA FC 18 E3 F5 3A A8 FC A7 C4 8B 15 F1 DF 18 C9 CD 04 14 2A DC; +1590: F3 22 BC F6 3E 20 32 A7 F6 CD BD 10 CD 45 02 FE 20 20 28 2A DC F3 3A B0; +15A8: F3 BC 20 1D 26 00 11 B1 FB 19 7E B7 28 13 3A A7 F6 CD BD 10 CD 4D 02 2A; +15C0: BC F6 22 DC F3 C9 C3 19 14 3E 20 F5 3A A7 F6 DF F1 32 A7 F6 18 C3 C9 37; +15D8: E1 C9 C9 C9 C9 C9 AF E1 C9 C9 C9 C9 C9 18 00 18 00 D6 15 D7 15 18 00 DA; +15F0: 15 DB 15 18 00 DC 15 18 00 18 00 18 00 18 00 DD 15 DE 15 18 00 18 00 18; +1608: 00 E1 15 18 00 18 00 E2 15 18 00 18 00 18 00 18 00 18 00 E3 15 18 00 18; +1620: 00 18 00 18 00 DB AA E6 F0 F6 07 D3 AA DB A9 E6 10 C0 DB AA E6 F0 F6 06; +1638: D3 AA DB A9 E6 02 C0 37 C9 E5 F5 21 4C 16 CD 9F 09 F1 E1 C9 49 53 43 4E; +1650: 54 43 00 C3 41 16 E5 F5 21 61 16 CD 9F 09 F1 E1 C9 42 45 45 50 00 22 DC; +1668: F3 C9 E5 F5 21 75 16 CD 9F 09 F1 E1 C9 46 4E 4B 53 42 00 E5 F5 21 86 16; +1680: CD 9F 09 F1 E1 C9 45 52 41 46 4E 4B 00 E5 F5 21 98 16 CD 9F 09 F1 E1 C9; +1698: 44 53 50 46 4E 4B 00 3A AF FC FE 02 D8 3A B0 FC CD BD FD B7 CA 82 03 C3; +16B0: C2 03 E5 F5 21 BE 16 CD 9F 09 F1 E1 37 C9 54 41 50 49 4F 4E 00 E5 F5 21; +16C8: D1 16 CD 9F 09 F1 E1 37 C9 54 41 50 49 4E 00 E5 F5 21 E2 16 CD 9F 09 F1; +16E0: E1 C9 54 41 50 49 4F 46 00 E5 F5 21 F5 16 CD 9F 09 F1 E1 37 C9 54 41 50; +16F8: 4F 4F 4E 00 E5 F5 21 08 17 CD 9F 09 F1 E1 37 C9 54 41 50 4F 55 54 00 E5; +1710: F5 21 1A 17 CD 9F 09 F1 E1 C9 54 41 50 4F 4F 46 00 C5 47 DB AA 04 28 0C; +1728: CB E7 05 28 09 CB A7 05 28 04 C1 C9 EE 10 D3 AA C1 C9 1E 00 3E 08 CD 52; +1740: 17 3C CD 52 17 3C CD 52 17 3C 1E B8 3E 07 CD 52 17 C9 F3 D3 A0 F5 7B D3; +1758: A1 FB F1 C9 D3 A0 DB A2 C9 B7 3E 0E 28 01 3C D3 AB C9 DB A8 C9 D3 A8 C9; +1770: DB 99 C9 F3 C5 4F DB AA E6 F0 B1 D3 AA DB A9 C1 FB C9 CD A7 FF C9 CD AC; +1788: FF C9 3A 64 F8 A7 C9 C5 FE 00 20 19 3E 08 CD 73 17 0F 0F 0F 0F 2F E6 0F; +17A0: E5 21 F2 17 16 00 5F 19 7E E1 C1 A7 C9 E5 D5 1E 00 3D 28 02 CB F3 3E 0F; +17B8: F3 CD 5C 17 FB E6 BF B3 5F 3E 0F CD 52 17 3E 0E F3 CD 5C 17 FB 2F E6 0F; +17D0: 21 E2 17 06 00 4F 09 7E D1 E1 C1 A7 C9 3E 00 C1 A7 C9 00 01 05 00 07 08; +17E8: 06 07 03 02 04 03 00 01 05 00 00 07 01 08 05 06 00 07 03 00 02 01 04 05; +1800: 03 00 FE 05 30 03 B7 20 09 3E 08 CD 73 17 F6 FE 3C C9 F3 3D D5 1E 03 47; +1818: E6 01 28 02 1E 4C 3E 0F CD 5C 17 E6 BF B3 5F 3E 0F CD 52 17 78 06 10 E6; +1830: 02 28 02 06 20 3E 0E F3 CD 5C 17 FB D1 A0 28 02 18 03 3E FF C9 AF C9 E5; +1848: F5 21 53 18 CD 9F 09 F1 E1 AF C9 47 54 50 41 44 00 E5 F5 21 64 18 CD 9F; +1860: 09 F1 E1 C9 47 54 50 44 4C 00 CD 9A 18 46 04 23 7E 90 23 23 A6 6F 26 00; +1878: C9 CD 9A 18 7E 3C 47 23 96 C8 78 23 23 E5 A6 2B 2B 2B 77 E1 23 7E 23 66; +1890: 6F 05 48 06 00 09 73 F6 01 C9 2A F3 F3 47 07 07 80 80 4F 06 00 09 C9 B7; +18A8: DB AA CB B7 20 02 CB F7 D3 AA C9 E5 F5 21 BE 18 CD 9F 09 F1 E1 C9 4F 55; +18C0: 54 44 4C 50 00 2E 02 18 03 3A 38 FB D5 16 00 5D 21 41 FB 19 1E 25 B7 28; +18D8: 04 19 3D 18 F9 D1 C9 2A FA F3 22 F8 F3 C9 E5 D5 C5 F5 D9 08 E5 D5 C5 F5; +18F0: FD E5 DD E5 CD 9A FD DB 99 B7 32 E7 F3 F2 4E 19 CD 9F FD 2A 9E FC 23 22; +1908: 9E FC AF 32 D9 FB 3A F6 F3 3D 32 F6 F3 20 37 3E 03 32 F6 F3 AF CD 02 18; +1920: 2F E6 01 32 E8 F3 CD 63 19 2A F8 F3 ED 5B FA F3 E7 20 1B 3A F7 F3 3D 32; +1938: F7 F3 20 12 21 DA FB 01 FF 0B 71 23 10 FC CD 63 19 3E 01 32 F7 F3 DD E1; +1950: FD E1 F1 C1 D1 E1 D9 08 F1 C1 D1 E1 FB C9 CD D6 FD ED 45 DB AA E6 F0 4F; +1968: 06 0B 21 E5 FB 79 D3 AA DB A9 77 23 0C 10 F6 DD 21 DA FB 11 E5 FB 3A EB; +1980: FB 0F 21 BE 26 38 03 21 EE 26 0E 0B 1A DD BE 00 C4 B4 19 2F DD A6 00 08; +1998: 1A DD 77 00 08 06 08 0F 38 1A 23 10 FA DD 23 13 0D C8 79 FE 05 20 DD 21; +19B0: DE 27 18 D8 F5 3E 05 32 F7 F3 F1 C9 F5 79 FE 05 28 07 FE 04 28 1C C3 13; +19C8: 1A 78 FE 03 20 04 3E 00 18 21 FE 02 20 04 3E 01 18 19 FE 01 20 35 3E 02; +19E0: 18 11 78 FE 08 20 04 3E 03 18 08 FE 07 20 24 3E 04 18 00 E5 C5 D5 07 07; +19F8: 07 07 21 7F F8 16 00 5F 19 EB 1A A7 28 08 D5 CD 20 1A D1 13 18 F4 D1 C1; +1A10: E1 18 09 7E A7 28 05 E5 CD 20 1A E1 F1 C3 A2 19 2A F8 F3 77 23 7D FE 18; +1A28: 20 03 21 F0 FB D5 ED 5B FA F3 E7 D1 C8 22 F8 F3 C9 CD 3F 1A DD E1 C9 08; +1A40: D9 F5 C5 D5 E5 ED 57 F5 D9 FD E5 3A F8 FA F5 FD E1 08 CD 34 24 FD E1 08; +1A58: D9 F1 E2 5E 1A FB E1 D1 C1 F1 D9 08 C9 18 FE CD DA FE 11 22 26 C3 87 1A; +1A70: E5 F5 21 80 1A CD 9F 09 F1 E1 11 07 26 C3 87 1A 43 41 4C 42 41 53 00 DB; +1A88: 99 21 06 28 06 0C 0E 99 ED B3 01 00 08 AF D3 98 0B 78 B1 20 F8 21 BF 1B; +1AA0: 01 00 08 7E D3 98 23 0B 78 B1 20 F7 3E 00 D3 99 3E 40 D3 99 21 EE 25 7E; +1AB8: D3 98 23 7E A7 20 F9 1A D3 98 13 1A A7 20 F9 C3 65 1A 00 00 00 00 00 00; +1AD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1AE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1BA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +1BC0: 00 00 00 00 00 00 00 3C 42 A5 A5 C3 BD 42 3C 3C 7E DB DB BD C3 7E 3C 6C; +1BD8: AA 92 44 44 28 10 00 10 28 44 82 44 28 10 00 10 38 38 D6 FE D6 38 00 10; +1BF0: 38 7C 7C FE D6 38 00 00 00 00 18 18 00 00 00 FF; +1C00: FF FF E7 E7 FF FF FF 3C 42 81 81 81 81 42 3C C3 BD 7E 7E 7E 7E BD C3 0C; +1C18: 04 08 70 88 88 70 00 00 70 88 88 70 20 70 20 20 30 28 28 20 E0 C0 00 38; +1C30: 3C 24 24 E4 DC 18 00 10 44 38 AA 38 44 10 00 10 10 10 38 10 10 10 10 10; +1C48: 10 10 EF 00 00 00 00 00 00 00 EF 10 10 10 10 10 10 10 E0 10 10 10 10 10; +1C60: 10 10 0F 10 10 10 10 10 10 10 EF 10 10 10 10 10 10 10 10 10 10 10 10 00; +1C78: 00 00 FF 00 00 00 00 00 00 00 0F 10 10 10 10 00 00 00 E0 10 10 10 10 10; +1C90: 10 10 0F 00 00 00 00 10 10 10 E0 00 00 00 00 81 42 24 18 18 24 42 81 01; +1CA8: 02 04 08 10 20 40 80 80 40 20 10 08 04 02 01 00 00 10 FF 10 00 00 00 00; +1CC0: 00 00 00 00 00 00 00 20 20 20 20 00 20 00 00 50 50 00 00 00 00 00 00 00; +1CD8: 50 F8 50 F8 50 00 00 20 70 A0 70 28 70 20 00 00 C8 D0 20 58 98 00 00 60; +1CF0: 90 60 A8 98 60 00 00 40 40 00 00 00 00 00 00 20 40 40 40 40 20 00 00 20; +1D08: 10 10 10 10 20 00 00 00 20 A8 70 50 88 00 00 00 20 20 F8 20 20 00 00 00; +1D20: 00 00 00 00 40 40 00 00 00 00 F8 00 00 00 00 00 00 00 00 00 40 00 00 00; +1D38: 08 10 20 40 80 00 00 70 88 A8 A8 88 70 00 00 20 60 20 20 20 70 00 00 70; +1D50: 88 08 70 80 F8 00 00 F8 08 30 08 88 70 00 00 10 30 50 F8 10 10 00 00 F8; +1D68: 80 70 08 88 70 00 00 30 40 70 88 88 70 00 00 F8 88 10 20 20 20 00 00 70; +1D80: 88 70 88 88 70 00 00 70 88 88 78 08 70 00 00 00 00 40 00 00 40 00 00 00; +1D98: 00 40 00 00 40 40 00 00 18 60 80 60 18 00 00 00 00 F8 00 F8 00 00 00 00; +1DB0: C0 30 08 30 C0 00 00 70 88 30 20 00 20 00 00 70 88 98 A8 A8 98 40 00 70; +1DC8: 88 88 F8 88 88 00 00 E0 90 E0 90 88 F0 00 00 70 88 80 80 88 70 00 00 F0; +1DE0: 48 48 48 48 F0 00 00 F8 80 E0 80 80 F8 00 00 F8 80 80 E0 80 80 00 00 70; +1DF8: 88 80 B8 88 70 00 00 88 88 F8 88 88 88 00 00 70 20 20 20 20 70 00 00 38; +1E10: 08 08 08 88 70 00 00 88 90 A0 E0 90 88 00 00 80 80 80 80 80 F8 00 00 D8; +1E28: A8 A8 88 88 88 00 00 C8 A8 A8 98 98 88 00 00 70 88 88 88 88 70 00 00 F0; +1E40: 88 88 F0 80 80 00 00 70 88 88 A8 90 68 00 00 F0 88 88 F0 A0 98 00 00 70; +1E58: 80 70 08 08 F0 00 00 F8 20 20 20 20 20 00 00 88 88 88 88 88 78 00 00 88; +1E70: 88 88 50 50 20 00 00 88 88 A8 A8 A8 D8 00 00 88 50 20 50 88 88 00 00 88; +1E88: 88 70 20 20 20 00 00 F8 10 20 40 80 F8 00 00 70 40 40 40 40 70 00 00 00; +1EA0: 80 40 20 10 08 00 00 70 10 10 10 10 70 00 00 40 A0 00 00 00 00 00 00 00; +1EB8: 00 00 00 00 00 F8 00 20 10 00 00 00 00 00 00 00 00 78 88 98 68 00 00 80; +1ED0: 80 F0 88 88 F0 00 00 00 00 78 80 80 78 00 00 08 08 78 88 88 78 00 00 00; +1EE8: 00 70 98 E0 78 00 00 30 48 40 40 E0 40 40 40 00 00 78 88 88 78 08 70 80; +1F00: 80 F0 88 88 88 00 00 20 00 60 20 20 70 00 00 10 00 30 10 10 10 10 60 80; +1F18: 80 98 A0 E0 98 00 00 C0 40 40 40 40 70 00 00 00 00 F0 A8 A8 A8 00 00 00; +1F30: 00 F0 88 88 88 00 00 00 00 70 88 88 70 00 00 00 00 F0 88 88 F0 80 80 00; +1F48: 00 78 88 88 78 08 08 00 00 B8 C0 80 80 00 00 00 00 78 F0 08 F0 00 00 40; +1F60: 40 F0 40 48 30 00 00 00 00 88 88 88 78 00 00 00 00 88 88 50 20 00 00 00; +1F78: 00 88 A8 A8 D8 00 00 00 00 C8 30 60 98 00 00 00 00 88 88 88 78 08 70 00; +1F90: 00 F8 30 40 F8 00 00 10 20 20 40 20 20 10 00 20 20 20 20 20 20 20 00 40; +1FA8: 20 20 10 20 20 40 00 50 A0 00 00 00 00 00 00 00 20 50 50 F8 00 00 00 70; +1FC0: 88 80 80 88 70 20 40 50 00 88 88 88 78 00 00 08 10 70 98 E0 78 00 00 20; +1FD8: 50 78 88 98 68 00 00 50 00 78 88 98 68 00 00 40 20 78 88 98 68 00 00 20; +1FF0: 00 78 88 98 68 00 00 00 00 78 80 80 78 20 40 20 50 70 98 E0 78 00 00 50; +2008: 00 70 98 E0 78 00 00 40 20 70 98 E0 78 00 00 50 00 60 20 20 70 00 00 20; +2020: 50 60 20 20 70 00 00 40 20 60 20 20 70 00 00 50 70 88 88 F8 88 00 00 20; +2038: 70 88 88 F8 88 00 00 18 F8 80 E0 80 F8 00 00 00 00 D0 68 B0 D8 00 00 78; +2050: A0 B0 E0 A0 B8 00 00 20 50 70 88 88 70 00 00 50 00 70 88 88 70 00 00 40; +2068: 20 70 88 88 70 00 00 20 50 88 88 88 78 00 00 40 20 88 88 88 78 00 00 50; +2080: 00 88 88 88 78 08 70 50 70 88 88 88 70 00 00 50 88 88 88 88 70 00 00 20; +2098: 20 78 80 80 78 20 20 20 50 40 E0 40 48 B0 00 88 88 50 F8 20 70 20 00 80; +20B0: D0 B0 B0 B8 D0 88 80 38 40 F0 40 F0 40 38 00 08 10 78 88 98 68 00 00 10; +20C8: 20 60 20 20 70 00 00 10 20 70 88 88 70 00 00 10 20 88 88 88 78 00 00 28; +20E0: 50 F0 88 88 88 00 00 28 D0 A8 A8 98 88 00 00 00 00 78 88 98 68 00 70 00; +20F8: 00 70 88 88 70 00 70 20 00 20 60 88 70 00 00 00 00 00 E0 80 00 00 00 00; +2110: 00 00 E0 20 00 00 00 40 48 50 30 48 90 38 00 40 48 50 28 58 B8 08 00 20; +2128: 00 20 20 20 20 00 00 00 00 00 48 90 48 00 00 00 00 00 90 48 90 00 00 28; +2140: 50 70 88 F8 88 00 00 28 50 78 88 98 68 00 00 28 50 70 20 20 70 00 00 28; +2158: 50 60 20 20 70 00 00 28 70 88 88 88 70 00 00 28 50 70 88 88 70 00 00 28; +2170: 50 88 88 88 78 00 00 28 50 00 88 88 78 00 00 FC 48 48 48 48 E8 08 30 48; +2188: 00 D8 48 48 E8 08 30 E0 68 30 E8 58 B8 08 00 50 28 00 00 00 00 00 00 00; +21A0: 20 50 88 50 20 00 00 00 48 50 20 68 A8 00 00 7C A8 A8 A8 68 28 28 44 70; +21B8: 80 70 88 70 08 88 70 00 00 00 00 00 00 FF FF F0 F0 F0 F0 0F 0F 0F 0F 00; +21D0: 00 FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 00 3C 3C 00 00 00 FF; +21E8: FF FF FF FF FF 00 00 C0 C0 C0 C0 C0 C0 C0 C0 0F 0F 0F 0F F0 F0 F0 F0 FC; +2200: FC FC FC FC FC FC FC 03 03 03 03 03 03 03 03 3F 3F 3F 3F 3F 3F 3F 3F 11; +2218: 22 44 88 11 22 44 88 88 44 22 11 88 44 22 11 FE 7C 38 10 00 00 00 00 00; +2230: 00 00 00 10 38 7C FE 80 C0 E0 F0 E0 C0 80 00 01 03 07 0F 07 03 01 00 FF; +2248: 7E 3C 18 18 3C 7E FF 81 C3 E7 FF FF E7 C3 81 F0 F0 F0 F0 00 00 00 00 00; +2260: 00 00 00 0F 0F 0F 0F 0F 0F 0F 0F 00 00 00 00 00 00 00 00 F0 F0 F0 F0 33; +2278: 33 CC CC 33 33 CC CC 00 10 28 28 7C 00 00 00 10 10 38 10 38 10 10 00 00; +2290: 00 50 88 A8 50 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 FF FF FF FF F0; +22A8: F0 F0 F0 F0 F0 F0 F0 0F 0F 0F 0F 0F 0F 0F 0F FF FF FF FF 00 00 00 00 00; +22C0: 00 68 90 90 68 00 00 60 90 E0 90 90 E0 80 00 F8 88 80 80 80 80 00 00 F8; +22D8: 50 50 50 50 48 80 00 F8 48 20 40 88 F8 00 00 00 00 78 90 88 70 00 00 00; +22F0: 00 88 88 C8 B0 80 80 00 00 50 50 20 50 50 20 70; +2300: 20 70 A8 A8 70 20 70 70 88 F8 88 88 70 00 00 70 88 88 88 50 D8 00 00 30; +2318: 40 30 48 48 30 00 00 00 00 50 A8 A8 50 00 00 00 10 70 A8 A8 70 40 00 00; +2330: 70 80 E0 80 70 00 00 70 88 88 88 88 88 00 00 00 F8 00 F8 00 F8 00 00 00; +2348: 20 20 F8 20 20 F8 00 00 C0 30 08 30 C0 F8 00 00 18 60 80 60 18 F8 00 00; +2360: 18 20 20 20 20 20 20 20 20 20 20 20 20 C0 00 00 20 00 F8 00 20 00 00 00; +2378: 68 B0 00 68 B0 00 00 00 30 48 48 30 00 00 00 00 30 78 78 30 00 00 00 00; +2390: 00 00 00 30 00 00 00 1C 10 10 90 50 30 10 00 E0 90 90 00 00 00 00 00 60; +23A8: 10 60 F0 00 00 00 00 00 70 70 70 70 70 70 00 AA 55 AA 55 AA 55 AA 55 C5; +23C0: E5 F5 57 A7 F3 FC DE 24 F1 E1 E5 D5 E5 F5 7C 07 07 E6 03 6F 47 3E FC CD; +23D8: F8 23 5F 45 F1 E6 03 CD F8 23 47 DB A8 57 A3 B0 E1 CD 80 F3 7B D1 F5 CB; +23F0: 7A C4 1A 25 F1 E1 C1 C9 04 05 C8 07 07 10 FC C9 E5 57 D5 A7 F3 FC DE 24; +2408: C1 E1 D5 E5 7C 07 07 E6 03 6F 47 3E FC CD F8 23 5F 45 7A E6 03 CD F8 23; +2420: 47 DB A8 57 A3 B0 E1 59 CD 85 F3 D1 E5 CB 7A C4 1A 25 E1 C9 08 D9 F3 FD; +2438: E5 F1 DD E5 E1 57 A7 FC DE 24 D5 7A E6 03 47 0E FC DD E5 F1 07 07 E6 03; +2450: 87 28 07 CB 00 CB 01 3D 20 F9 21 67 24 E5 DB A8 F5 A1 B0 D9 C3 8C F3 08; +2468: D9 F3 D1 CB 7A C4 1A 25 08 D9 C9 F3 E5 6F E6 03 47 3E AB C6 55 05 F2 7B; +2480: 24 57 7C 07 07 E6 03 67 47 3E C0 07 07 05 F2 8B 24 5F 2F 4F 7A A3 47 7D; +2498: A7 F2 D6 24 0F 0F E6 03 E5 C5 47 3E AB C6 55 05 F2 A5 24 A3 47 7A E6 C0; +24B0: 67 DB A8 6F E6 C0 B4 D3 A8 3A FF FF 2F A1 B0 4F 32 FF FF 7D D3 A8 21 C5; +24C8: FC 7A E6 03 85 6F 7C CE 00 67 79 77 C1 E1 DB A8 A1 B0 D3 A8 E1 C9 57 0F; +24E0: 0F 5F E6 C0 6F DB A8 4F E6 3F B5 D3 A8 7B E6 03 6F 7C 26 03 18 02 29 29; +24F8: D6 40 30 FA 7C 2F 67 3A FF FF 2F 5F A4 B5 32 FF FF 6F 79 D3 A8 7A E6 03; +2510: 4F 06 00 7D 21 C5 FC 09 77 C9 7A 0F 0F E6 C0 47 DB A8 4F E6 3F B0 D3 A8; +2528: 7B 32 FF FF 79 D3 A8 7A E6 03 4F 06 00 21 C5 FC 09 73 C9 D3 A8 5E 18 03; +2540: D3 A8 73 7A D3 A8 C9 D3 A8 08 CD 98 F3 08 F1 D3 A8 08 C9 DD E9 00 43 2D; +2558: 42 49 4F 53 20 30 2E 32 39 20 20 20 20 20 20 63 62 69 6F 73 2E 73 66 2E; +2570: 6E 65 74 0D 0A 43 68 61 72 61 63 74 65 72 20 73 65 74 3A 20 55 53 0D 0A; +2588: 49 6E 74 65 72 72 75 70 74 20 66 72 65 71 75 65 6E 63 79 3A 20 35 30 48; +25A0: 7A 0D 0A 4B 65 79 62 6F 61 72 64 20 74 79 70 65 3A 20 55 53 0D 0A 0D 0A; +25B8: 0D 0A 0D 0A 00 49 6E 69 74 20 52 4F 4D 20 69 6E 20 73 6C 6F 74 3A 20 00; +25D0: 43 61 6E 6E 6F 74 20 65 78 65 63 75 74 65 20 61 20 42 41 53 49 43 20 52; +25E8: 4F 4D 2E 0D 0A 00 45 52 52 4F 52 3A 00 4D 45 4D 4F 52 59 20 4E 4F 54 20; +2600: 46 4F 55 4E 44 2E 00 43 41 4C 4C 45 44 20 4E 4F 4E 20 45 58 49 53 54 49; +2618: 4E 47 20 42 41 53 49 43 2E 00 53 54 41 43 4B 20 45 52 52 4F 52 2E 00 0D; +2630: 0A 0D 0A 4E 6F 20 63 61 72 74 72 69 64 67 65 20 66 6F 75 6E 64 2E 0D 0A; +2648: 0D 0A 54 68 69 73 20 76 65 72 73 69 6F 6E 20 6F 66 20 43 2D 42 49 4F 53; +2660: 20 63 61 6E 0D 0A 6F 6E 6C 79 20 73 74 61 72 74 20 63 61 72 74 72 69 64; +2678: 67 65 73 2E 0D 0A 50 6C 65 61 73 65 20 72 65 73 74 61 72 74 20 79 6F 75; +2690: 72 20 4D 53 58 0D 0A 28 65 6D 75 6C 61 74 6F 72 29 20 77 69 74 68 20 61; +26A8: 20 63 61 72 74 72 69 64 67 65 0D 0A 69 6E 73 65 72 74 65 64 2E 00 30 31; +26C0: 32 33 34 35 36 37 38 39 2D 3D 5C 5B 5D 3B 27 60 2C 2E 2F 00 61 62 63 64; +26D8: 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 29 21; +26F0: 40 23 24 25 5E 26 2A 28 5F 2B 7C 7B 7D 3A 22 7E 3C 3E 3F 00 41 42 43 44; +2708: 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 09 AC; +2720: AB BA EF BD F4 FB EC 07 17 F1 1E 01 0D 06 05 BB F3 F2 1D 00 C4 11 BC C7; +2738: CD 14 15 13 DC C6 DD C8 0B 1B C2 DB CC 18 D2 12 C0 1A CF 1C 19 0F 0A 00; +2750: FD FC 00 00 F5 00 00 08 1F F0 16 02 0E 04 03 F7 AE AF F6 00 FE 00 FA C1; +2768: CE D4 10 D6 DF CA DE C9 0C D3 C3 D7 CB A9 D1 00 C5 D5 D0 F9 AA F8 EB 9F; +2780: D9 BF 9B 98 E0 E1 E7 87 EE E9 00 ED DA B7 B9 E5 86 A6 A7 00 84 97 8D 8B; +2798: 8C 94 81 B1 A1 91 B3 B5 E6 A4 A2 A3 83 93 89 96 82 95 88 8A A0 85 D8 AD; +27B0: 9E BE 9C 9D 00 00 E2 80 00 00 00 E8 EA B6 B8 E4 8F 00 A8 00 8E 00 00 00; +27C8: 00 99 9A B0 00 92 B2 B4 00 A5 00 E3 00 00 00 00 90 00 00 00 00 00 00 00; +27E0: 00 00 00 00 00 00 00 00 1B 09 00 08 00 0D 20 0C 00 00 1D 1E 1F 1C 2A 2B; +27F8: 2F 30 31 32 33 34 35 36 37 38 39 2D 2C 2E 00 80 70 81 00 82 01 84 F5 87; +2810: 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2828: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2858: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2888: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +28A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +28B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +28D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +28E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2918: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2948: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2978: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +29A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +29C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +29D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +29F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2B98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2BC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2BF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2C10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2C28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2C40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2C58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2C70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2C88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2CA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2CB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2CD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2CE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2D90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2DA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2DC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2DD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2E98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2EB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2EC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2EE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2EF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2F10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2F28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2F40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2F58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2F70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2F88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2FA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2FB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2FD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +2FE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3018: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3078: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +30A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +30C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +30D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +30F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3118: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3148: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3178: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3190: 00 00 00 C5 E5 C1 1B 7B B2 28 03 09 18 F8 C1 C9 E5 F5 21 B5 31 CD 9F 09; +31A8: 3E 20 D3 2E 7A D3 2F 7B D3 2F F1 E1 C9 52 4F 4D 42 41 53 00 00 00 00 00; +31C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +31D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +31F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3208: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3238: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3268: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3298: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +32B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +32C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +32E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +32F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3328: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3358: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3388: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +33A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +33B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +33D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +33E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3418: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3478: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +34A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +34C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +34D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +34F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3508: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3538: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3568: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3598: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +35B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +35C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +35E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +35F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3628: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3658: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3688: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +36A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +36B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +36D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +36E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3748: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +37A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +37C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +37D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +37F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3818: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3848: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3878: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +38A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +38C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +38D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +38F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3908: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3938: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3950: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3968: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3980: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3998: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +39B0: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +39C8: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +39E0: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +39F8: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3A10: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A; +3A28: 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A 3E 3A E5 F5; +3A40: 21 49 3A CD 9F 09 F1 E1 C9 42 41 53 49 43 20 73 74 61 74 65 6D 65 6E 74; +3A58: 73 20 61 72 65 20 6E 6F 74 20 69 6D 70 6C 65 6D 65 6E 74 65 64 20 79 65; +3A70: 74 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3A88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3AA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3AB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3AD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3AE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3BA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3BC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3BD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3BF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3C98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3CB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3CC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3CE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3CF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3D10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3D28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3D40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3D58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3D70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3D88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3DA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3DB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3DD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3DE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3EA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3ED8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3EF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3F90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3FA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3FC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3FD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3FF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4008: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4038: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4068: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4098: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +40B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +40C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +40E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +40F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4128: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4158: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4188: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +41A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +41B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +41D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +41E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4218: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4248: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4278: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +42A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +42C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +42D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +42F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4308: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4338: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4368: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4398: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +43B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +43C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +43E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +43F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4428: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4458: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4488: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +44A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +44B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +44D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +44E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4518: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4548: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4578: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +45A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +45C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +45D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +45F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4618: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4678: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +46A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +46C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +46D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +46F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4708: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4738: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4768: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4798: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +47B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +47C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +47E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +47F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4810: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4828: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4858: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4870: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4888: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +48A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +48B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +48D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +48E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4918: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4948: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4978: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +49A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +49C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +49D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +49F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4A98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4AB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4AC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4AE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4AF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4B10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4B28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4B40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4B58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4B70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4B88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4BA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4BB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4BD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4BE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4C90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4CA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4CC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4CD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4CF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4D90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4DA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4DC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4DD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4E98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4EB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4EC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4EE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4EF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4F10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4F28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4F40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4F58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4F70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4F88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4FA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4FB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4FD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +4FE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5018: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5078: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +50A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +50C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +50D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +50F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5108: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5138: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +51B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +51C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +51E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +51F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5228: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5258: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +52A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +52B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +52D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +52E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5318: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5348: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5378: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +53A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +53C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +53D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +53F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5418: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5478: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +54A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +54C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +54D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +54F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5508: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5520: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5538: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5550: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5568: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5598: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +55B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +55C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +55E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +55F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5628: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5658: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5688: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +56A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +56B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +56D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +56E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5748: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +57A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +57C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +57D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +57F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5808: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5838: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5868: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5898: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +58B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +58C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +58E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +58F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5928: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5958: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5988: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +59A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +59B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +59D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +59E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5B90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5BA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5BC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5BD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5BF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5C98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5CB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5CC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5CE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5CF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5D10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5D28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5D40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5D58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5D70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5D88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5DA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5DB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5DD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5DE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5EA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5ED8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5EF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5F98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5FB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5FC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5FE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +5FF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6028: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6058: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6088: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +60A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +60B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +60D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +60E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6118: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6148: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6178: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +61A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +61C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +61D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +61F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6218: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6248: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6278: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +62A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +62C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +62D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +62F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6308: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6338: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6368: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6398: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +63B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +63C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +63E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +63F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6428: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6458: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6488: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +64A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +64B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +64D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +64E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6518: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6530: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6548: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6578: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6590: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +65A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +65C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +65D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +65F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6608: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6620: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6638: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6650: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6668: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 8E 10 00 00 00 00 00; +6680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6698: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +66B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +66C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +66E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +66F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6728: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6758: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6788: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +67A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +67B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +67D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +67E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6818: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6830: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6848: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6860: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6878: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6890: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +68A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +68C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +68D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +68F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6918: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6948: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6978: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +69A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +69C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +69D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +69F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6A98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6AB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6AC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6AE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6AF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6B10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6B28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6B40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6B58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6B70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6B88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6BA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6BB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6BD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6BE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6C90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6CA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6CC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6CD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6CF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6D98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6DB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6DC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6DE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6DF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6E10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6E28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6E40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6E58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6E70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6E88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6EA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6EB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6ED0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6EE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6F90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6FA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6FC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6FD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +6FF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7018: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7078: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +70A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +70C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +70D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +70F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7108: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7138: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +71B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +71C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +71E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +71F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7228: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7240: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7258: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7270: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +72A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +72B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +72D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +72E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7318: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7348: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7378: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +73A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +73C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +73D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +73F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7408: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7438: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7468: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7498: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +74B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +74C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +74E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +74F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7510: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7528: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7540: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7558: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7570: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7588: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +75A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +75B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +75D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +75E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7618: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7678: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +76A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +76C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +76D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +76F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7718: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7730: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7748: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7778: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7790: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +77A8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +77C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 C9 00 00 00 00 00 00 00 00 00 00; +77D8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +77F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7808: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7820: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7838: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7850: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7868: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7898: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +78B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +78C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +78E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +78F8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7928: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7958: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7988: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +79A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +79B8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +79D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +79E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A18: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7A90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7AA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7AC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7AD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7AF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7B98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7BB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7BC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7BE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7BF8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7C10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7C28: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7C40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7C58: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7C70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7C88: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7CA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7CB8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7CD0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7CE8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7D00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5; +7D18: F5 21 22 7D CD 9F 09 F1 E1 C9 75 6E 6B 6E 6F 77 6E 40 37 44 31 37 00 39; +7D30: 7D DD 21 89 01 CD 3F 1A C9 DD 21 85 01 C3 3F 1A 00 00 00 00 00 00 00 00; +7D48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7D60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7D78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7D90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7DA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7DC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7DD8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7DF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7E00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 E5 F5 21 1F; +7E18: 7E CD 9F 09 F1 E1 C9 75 6E 6B 6E 6F 77 6E 40 37 45 31 34 00 00 00 00 00; +7E30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7E48: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7E60: 00 00 00 00 00 00 00 00 00 00 00 C9 00 00 00 00 00 00 00 00 00 00 00 00; +7E78: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7E90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7EA8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7ED8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7EF0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F08: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F38: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F68: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7F98: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7FB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7FC8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7FE0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +7FF8: 00 00 00 00 00 00 00 00; +END; diff --git a/rtl/rom/vy0010.mif b/rtl/rom/vy0010.mif index 0f71cf9..4ca4636 100644 --- a/rtl/rom/vy0010.mif +++ b/rtl/rom/vy0010.mif @@ -1,696 +1,696 @@ --- http://srecord.sourceforge.net/ --- --- Generated automatically by srec_cat -o --mif --- -DEPTH = 16384; -WIDTH = 8; -ADDRESS_RADIX = HEX; -DATA_RADIX = HEX; -CONTENT BEGIN -0000: 41 42 6F 57 76 65 00 00 00 00 00 00 00 00 00 00 C3 4D 74 C3 BB 78 C3 FD; -0018: 78 C3 6E 79 C3 82 79 C3 22 78 C3 3A 5B 37 C3 B1 60 C3 0D 62 00 C3 B3 5F; -0030: 2A 4B F3 C9 DD E5 DD 21 B7 00 CD AB 40 DD E1 30 0A 3E 03 32 36 F3 32 37; -0048: F3 A7 C9 3A 36 F3 A7 3A 37 F3 C0 DD E5 DD 21 9C 00 CD AB 40 DD E1 C8 3E; -0060: FF 32 36 F3 DD E5 DD 21 9F 00 CD AB 40 DD E1 32 37 F3 C5 06 00 04 C1 C9; -0078: E5 21 36 F3 AF BE 77 23 7E E1 C0 DD E5 DD 21 9F 00 CD AB 40 DD E1 C9 DD; -0090: E5 DD 21 A2 00 CD AB 40 DD E1 C9 DD E5 DD 21 A5 00 CD AB 40 DD E1 C9 DD; -00A8: 21 9B 40 FD E5 FD 2A C0 FC CD 1C 00 FB FD E1 C9 3E 0D D3 B4 3E 0A D3 B5; -00C0: AF D3 B4 06 0F DB B5 E6 0F A8 D3 B5 4F 00 DB B5 E6 0F B9 C0 A8 D3 B5 10; -00D8: EC 3E FF 32 38 F3 3E 0D D3 B4 3E 09 D3 B5 3E 0A D3 B4 3E 01 D3 B5 3E 0D; -00F0: D3 B4 AF D3 B5 01 00 0D 79 D3 B4 DB B5 F5 0C 10 F7 3E 0E D3 B4 AF D3 B5; -0108: 06 0D 0D 79 D3 B4 F1 D3 B5 10 F7 18 39 22 3B F3 3A 38 F3 A7 C8 3A 4A F2; -0120: 47 3A 49 F2 4F 3A 48 F2 57 1E 07 CD 59 41 18 12 3A 38 F3 A7 C8 1E 00 CD; -0138: 59 41 3E 0F D3 B4 3E 02 D3 B5 62 CD 60 41 61 CD 60 41 60 CD 60 41 3E 0D; -0150: D3 B4 DB B5 F6 08 D3 B5 C9 CD 4E 41 E6 04 18 F6 AF 2E 08 CB 04 8F 27 2D; -0168: 20 F9 CD 71 41 0F 0F 0F 0F F5 7B 1C D3 B4 F1 18 DD 3A 38 F3 A7 47 4F 57; -0180: 5F 2A 3B F3 C8 CD 59 41 1E 0D CD AD 41 CD 23 55 CD AD 41 32 49 F2 CD AD; -0198: 41 32 48 F2 1D CD AD 41 47 CD AD 41 4F CD AD 41 CD 4E 41 37 C9 AF CD B5; -01B0: 41 87 87 82 87 57 1D 7B D3 B4 DB B5 E6 0F 82 57 C9 20 4D 53 58 2D 44 4F; -01C8: 53 20 76 65 72 2E 20 32 2E 32 20 43 6F 70 79 72 69 67 68 74 20 31 39 38; -01E0: 34 20 62 79 20 4D 69 63 72 6F 73 6F 66 74 20 06 00 3E 22 C9 DD 5E 13 DD; -01F8: 56 14 CD 52 F2 D5 5D 54 CB 3C CB 1D 1F 19 D1 19 17 7E 23 66 30 0C CB 3C; -0210: 1F CB 3C 1F CB 3C 1F CB 3C 1F 6F 7C E6 0F 67 B5 C9 D5 5D 54 CB 3C CB 1D; -0228: 1F 19 D1 19 17 30 18 CB 21 CB 10 CB 21 CB 10 CB 21 CB 10 CB 21 CB 10 7E; -0240: E6 0F B1 77 23 70 C9 71 23 7E E6 F0 B0 77 C9 11 B9 F2 1A BE 23 13 C0 10; -0258: F9 C9 CD 55 F2 21 F7 F1 0E 05 06 04 CD 4F 42 20 2F 06 04 1A 13 FE 20 20; -0270: 32 10 F8 79 ED 44 32 16 F2 21 B9 F2 11 0B F2 01 04 00 ED B0 CD 96 54 ED; -0288: 43 23 F2 ED 53 21 F2 21 0B F2 E5 FD E1 F6 01 C9 05 7D 80 6F 7C CE 00 67; -02A0: 0D 20 BF 37 C9 D5 21 0E 00 19 36 00 CD B1 42 D1 C9 CD 0E 44 D8 CD 5A 42; -02B8: D0 CD D3 44 CD 58 F2 CD 0E 43 D8 7E B7 28 35 FE E5 28 31 E5 06 0B 11 B9; -02D0: F2 CD 52 42 28 06 FE 3F 20 1B 10 F5 E1 E5 FD E1 3A C4 F2 EE 80 CB 7F C8; -02E8: FD 7E 0B E6 1E C8 3A DC F2 B7 C0 18 01 E1 CD 48 43 30 C8 C9 3A FE F2 3C; -0300: 20 06 3A B8 F2 32 FE F2 7E B7 20 EA 37 C9 3A B8 F2 3C DD BE 0B 30 50 CD; -0318: 5B F2 32 B8 F2 4F DD A6 04 6F 26 00 29 29 29 29 29 ED 5B 51 F3 19 DD 46; -0330: 05 CB 39 10 FC 3A 45 F2 B9 20 07 3A 46 F2 DD BE 00 C8 E5 CD A4 46 E1 C9; -0348: CD 5E F2 3A B8 F2 3C DD BE 0B 30 13 32 B8 F2 11 20 00 19 DD A6 04 C0 0C; -0360: CD A4 46 2A 51 F3 C9 CD 43 47 37 C9 CD 0E 44 D4 B5 42 3E FF D8 C0 3E E5; -0378: 32 3C F2 77 FD 6E 1A FD 66 1B 7C B5 C4 9B 4F CD BC 42 30 EA CD 03 44 C3; -0390: CF 45 CD 0E 44 38 74 11 05 00 19 11 C5 F2 CD F4 F1 D4 B5 42 38 65 20 63; -03A8: 21 B9 F2 11 D0 F2 01 0C 00 ED B0 21 C5 F2 11 B9 F2 06 0B 7E FE 3F 20 03; -03C0: FD 7E 00 12 23 13 FD 23 10 F1 3E 80 12 CD 5A 42 30 36 3A B8 F2 F5 3E FF; -03D8: 32 B8 F2 CD BC 42 C1 30 27 78 CD 17 43 EB 21 B9 F2 01 0B 00 ED B0 3E FF; -03F0: 32 3C F2 21 D0 F2 11 B9 F2 01 0C 00 ED B0 CD BC 42 30 B0 CD 43 47 AF C9; -0408: CD 43 47 3E FF C9 CD 61 F2 AF 32 DC F2 EB 7E 23 32 C4 F2 E6 0F CD 27 44; -0420: D8 11 B9 F2 C3 F4 F1 4F 3A 47 F3 B9 D8 79 3D F2 35 44 3A 47 F2 32 E1 F2; -0438: C9 FD 7E 1F B7 20 1F FD 7E 1C FD 4E 1D FD 46 1E 87 CB 11 CB 10 38 0F B7; -0450: 28 05 03 78 B1 28 07 79 CB B9 87 CB 10 D0 01 7F FF C9 CD A5 42 38 A4 CD; -0468: 39 44 3A 0C F3 04 B8 30 9A CD 64 F2 EB 01 0F 00 09 CD 39 44 3A 0C F3 B8; -0480: 28 06 0E 80 38 02 0E 00 71 23 EB 01 1C 00 09 0E 04 ED B0 01 F8 FF 09 ED; -0498: A0 ED A0 0E FC 09 ED A0 ED A0 FD 7E 0B CB 7F 20 05 DD 7E 00 F6 40 12 13; -04B0: 3A B8 F2 12 13 FD 7E 1A 12 13 13 12 1B FD 7E 1B 12 13 13 12 13 AF 12 13; -04C8: 12 C9 4F 3A E1 F2 CD 0A 47 18 08 3E FF 32 B8 F2 32 FE F2 CD 67 F2 CD 53; -04E0: 45 3A E1 F2 DD 4E 01 06 00 B7 CD 67 60 38 DB CD 33 45 DD 6E 13 DD 66 14; -04F8: 2B 78 B6 3A E1 F2 2A 41 F2 FA 0A 45 C0 BD 20 0B 25 C8 95 20 06 6F 67 2D; -0510: 22 41 F2 3E FF 32 46 F2 CD FA 45 2B 36 00 23 F5 CD D7 46 38 19 F1 46 3A; -0528: E1 F2 DD 4E 01 DD E5 E1 CD 6F 60 E5 DD E1 EB CD 61 45 73 23 72 C9 7B 81; -0540: 5F 30 01 14 F1 41 3D 20 D6 CD FA 45 E5 CD C5 46 E1 18 D3 CD 6A F2 CD 61; -0558: 45 7E 23 66 6F E5 DD E1 C9 3A E1 F2 21 55 F3 87 85 6F D0 24 C9 00 00 D5; -0570: FD E1 CD 0E 44 3E FF D8 FD 7E 18 E6 C0 3E 00 C0 3A E1 F2 2A 41 F2 BD CC; -0588: 2D 47 CD 53 45 FD 7E 19 CD 17 43 06 0B CD 4F 42 20 54 FD E5 D1 0E 0B 09; -05A0: EB 0E 16 09 ED A0 ED A0 01 FC FF 09 ED A0 ED A0 01 04 00 09 ED A0 ED A0; -05B8: 01 F4 FF 09 01 04 00 ED B0 CD 48 47 DD 6E 13 DD 66 14 2B 7E FE 01 C0 CD; -05D0: 6D F2 CD FA 45 2B 36 00 23 F5 D5 C5 E5 CD 55 47 E1 C1 D1 7B 80 5F 30 01; -05E8: 14 F1 3D 20 EC C9 DD 6E 13 DD 66 14 2B 36 00 3E FF C9 DD 7E 0A DD 6E 13; -0600: DD 66 14 DD 46 10 DD 5E 08 DD 56 09 C9 DD 86 11 5F DD 56 12 30 01 14 2A; -0618: 51 F3 06 01 C9 D5 CD 0E 44 38 2A 23 23 36 00 21 B9 F2 3E 3F 01 0B 00 ED; -0630: B1 28 1A CD B5 42 30 19 3A FE F2 FE FF 28 0E CD 17 43 E5 FD E1 18 22 FD; -0648: CB 0B 7E 20 50 D1 3E FF C9 20 F4 3A 0C F3 B7 20 44 FD 6E 1A FD 66 1B 7C; -0660: B5 28 06 CD 9B 4F CD CF 45 FD E5 D1 21 B9 F2 01 0B 00 ED B0 7E 17 3E 00; -0678: 30 02 3E 06 12 13 EB 06 0A AF 77 23 10 FC E5 CD 96 54 E1 73 23 72 23 71; -0690: 23 70 23 AF 06 06 77 23 10 FC CD 48 47 FD E5 E1 D1 C3 71 44 C5 CD 43 47; -06A8: C1 DD 46 00 ED 43 45 F2 C5 79 CD 0D 46 CD C5 46 C1 C9 44 7D 32 E1 F2 CD; -06C0: 53 45 2A 3D F2 CD 70 F2 AF 32 FF F2 CD D7 46 D0 CD E8 46 3D 28 EF C9 DD; -06D8: 7E 00 DD 4E 01 E5 D5 C5 CD 52 60 D1 4A D1 E1 C9 F5 79 90 4F C5 06 00 EB; -06F0: 09 E5 D5 DD 5E 02 DD 56 03 CD 16 49 E1 D1 09 C1; -0700: F1 4F 3A FF F2 B1 4F DD 7E 00 CD 73 F2 C5 D5 E5 2A 23 F3 CD E8 F1 79 E1; -0718: D1 C1 FE 02 C0 C3 E2 F1 44 7D 32 E1 F2 CD 53 45 2A 3D F2 18 28 21 42 F2; -0730: AF BE 77 C8 DD 2A 43 F2 2A 4F F3 06 01 ED 5B 3F F2 18 12 3A 3C F2 B7 C8; -0748: CD 76 F2 AF 32 3C F2 3A 45 F2 CD 0D 46 CD 79 F2 3E 01 32 FF F2 DD 7E 00; -0760: DD 4E 01 E5 D5 C5 CD 54 60 D1 4A D1 E1 D0 CD E8 46 3D 28 E1 C9 CD F8 4E; -0778: CD 23 4B 18 06 CD F8 4E CD A3 4C CD 6A 48 18 14 CD 57 48 CD 23 4B 18 09; -0790: FD E5 D1 CD 57 48 CD A3 4C CD 44 48 7D E6 7F FD 77 20 CB 25 CB 14 FD 74; -07A8: 0C CB 13 FD 73 0E 3A DE F2 C9 AF 32 06 F3 CD 5A 48 CD 23 4B 18 0A AF 32; -07C0: 06 F3 CD 5A 48 CD A3 4C CD 6A 48 CD 44 48 69 60 C9 D5 FD E1 FD 7E 10 FD; -07D8: 4E 11 FD 46 12 FD 5E 13 87 CB 11 CB 10 CB 13 B7 28 06 03 78 B1 20 01 1C; -07F0: FD 6E 21 FD 66 22 ED 42 28 96 FD 7E 23 9B 38 90 E5 CD 90 47 D1 B7 C0 2A; -0808: 3D F2 E5 2A 51 F3 22 3D F2 06 80 77 23 10 FC 3D 32 46 F2 FD 6E 21 FD 66; -0820: 22 ED 52 4D 44 EB 16 00 FD 7E 23 9A 5F E5 21 01 00 CD A3 4C CD 6A 48 4D; -0838: 44 E1 2B 7C B5 20 EE E1 22 3D F2 C9 3A DE F2 FD 75 21 FD 74 22 FD 73 23; -0850: 14 15 C8 FD 72 24 C9 21 01 00 D5 FD E1 FD 4E 21 FD 46 22 FD 5E 23 FD 56; -0868: 24 C9 C8 23 7C B5 C0 13 C9 E1 69 60 3E 01 32 DE F2 AF 4F 47 C9 22 E8 F2; -0880: ED 43 E4 F2 ED 53 E6 F2 FD 7E 00 CD 27 44 38 E1 11 80 00 3A 06 F3 B7 20; -0898: 0F FD 7E 0E FD 56 0F 5F B2 20 05 1E 80 FD 73 0E 14 15 20 05 7B FE 40 38; -08B0: 04 AF 32 E7 F2 2A 3D F2 22 E2 F2 AF 32 DE F2 32 DF F2 ED 4B E8 F2 CD 16; -08C8: 49 FD 7E 18 B7 F8 C5 CD 53 45 ED 4B E4 F2 CD 16 49 ED 43 F4 F2 C5 ED 4B; -08E0: E6 F2 CD 1C 49 ED 43 F6 F2 60 69 C1 DD 5E 02 DD 56 03 CD 32 49 22 F2 F2; -08F8: ED 43 EE F2 DD 7E 06 A1 32 DD F2 DD 7E 07 3D 28 06 CB 38 CB 19 18 F7 ED; -0910: 43 EC F2 C1 AF C9 CD 7C F2 21 00 00 78 06 11 18 07 30 01 19 CB 1C CB 1D; -0928: 1F CB 19 10 F4 47 C9 21 00 00 CD 7F F2 78 06 10 CB 11 17 CB 15 CB 14 38; -0940: 0D ED 52 30 01 19 3F CB 11 17 10 EF 47 C9 B7 ED 52 18 F4 60 69 ED 4B F2; -0958: F2 78 B1 5F 57 28 13 DD 5E 02 DD 56 03 EB ED 42 EB ED 52 30 05 19 EB 21; -0970: 00 00 ED 53 F8 F2 4D 44 DD 5E 02 DD 56 03 CD 2F 49 22 FA F2 ED 43 FC F2; -0988: C9 CD 82 F2 FD 6E 1C FD 66 1D FD 5E 1E FD 56 1F 7D B4 28 33 C5 79 93 4F; -09A0: 78 9A 47 30 0B C1 11 00 00 FD 6E 1A FD 66 1B F5 F1 CD 85 F2 78 B1 C8 D5; -09B8: E5 CD F4 41 D1 7C FE 0F 38 05 7D FE F8 30 05 D1 13 0B 18 E5 EB D1 C9 03; -09D0: 1B C9 32 E0 F2 2A EC F2 3A DD F2 CD DB 4E EB 2A 3F F2 ED 52 20 0A 3A E1; -09E8: F2 6F 3A 41 F2 BD 28 2B D5 DD E5 CD 2D 47 DD E1 D1 3A E0 F2 B7 20 0E 3D; -0A00: 32 41 F2 2A 4F F3 06 01 D5 CD C5 46 D1 ED 53 3F F2 3A E1 F2 32 41 F2 DD; -0A18: 22 43 F2 3E 01 32 DF F2 2A E2 F2 E5 ED 4B F8 F2 09 22 E2 F2 2A 4F F3 ED; -0A30: 5B F2 F2 19 D1 C9 CD 88 F2 2A F8 F2 7C B5 C8 AF CD D2 49 C3 D9 F1 CD 8B; -0A48: F2 2A F8 F2 7C B5 C8 2A EE F2 23 22 EE F2 AF EB 2A F0 F2 ED 52 1F CD D2; -0A60: 49 EB CD D9 F1 3E 01 32 42 F2 C9 21 00 00 22 F2 F2 2A FA F2 22 F8 F2 7C; -0A78: B5 37 C8 3A DF F2 B7 C8 3A DD F2 DD BE 06 38 1A ED 5B EC F2 21 F7 0F ED; -0A90: 52 D8 EB CD F4 41 22 EC F2 2A EA F2 23 22 EA F2 3E FF 3C 32 DD F2 B7 C9; -0AA8: 7E ED A0 FE 0D 20 02 36 0A FE 0A 28 15 78 B1 20 EF 22 00 F3 ED 53 E2 F2; -0AC0: C2 E2 4B FD CB 18 B6 C3 E2 4B CD A8 53 21 00 00 79 B0 20 25 3C 18 E2 ED; -0AD8: 5B E2 F2 3C 28 14 3C 20 DB CD 6E 54 12 13 FE 1A 28 D2 0B 78 B1 20 F2 3C; -0AF0: 18 CA 2A 00 F3 7C B5 20 AF 21 7F 00 3A D9 F4 BD 28 03 22 D9 F4 C5 D5 11; -0B08: D9 F4 CD E0 50 D1 C1 21 DB F4 7E FE 1A 20 91 12 13 3E 0A CD A8 53 AF 67; -0B20: 6F 18 96 CD 7D 48 FA D7 4A FD 6E 10 FD 66 11 ED 5B F4 F2 B7 ED 52 E5 FD; -0B38: 6E 12 FD 66 13 ED 5B F6 F2 ED 52 E1 DA 97 4C 20 0D 7C B5 CA 97 4C E5 ED; -0B50: 42 E1 30 02 44 4D CD 8E F2 CD 53 49 ED 4B EC F2 CD 89 49 78 B1 C2 97 4C; -0B68: 22 EC F2 ED 53 EA F2 CD 36 4A 2A FC F2 7C B5 CA DC 4B CD 7B 4A 38 63 3E; -0B80: 01 32 DF F2 3A DD F2 ED 4B FC F2 2A EC F2 C5 CD 48 4E C5 F5 47 CD C5 46; -0B98: F1 4F 06 00 38 23 3A 42 F2 B7 28 1D C5 DD 4E 02 DD 46 03 C5 E5 2A 3F F2; -0BB0: ED 52 EB CD 16 49 E1 09 C1 EB 2A 4F F3 CD D9 F1 C1 D1 E1 B7 ED 42 28 14; -0BC8: 4D 44 21 F7 0F ED 52 38 11 2A EA F2 23 22 EA F2 AF EB 18 B2 CD 6B 4A D4; -0BE0: 36 4A CD 91 F2 2A E2 F2 ED 5B 3D F2 B7 ED 52 4D 44 11 80 00 3A 06 F3 B7; -0BF8: 20 06 FD 5E 0E FD 56 0F CD 2F 49 7C B5 28 10 03 EB ED 52 ED 5B E2 F2 AF; -0C10: 12 13 2B 7C B5 20 F8 2A E8 F2 ED 42 28 04 3C 32 DE F2 CD 94 F2 2A EC F2; -0C28: FD 75 1C FD 74 1D 2A EA F2 FD 75 1E FD 74 1F 2A E4 F2 ED 5B E6 F2 78 B1; -0C40: C8 0B 09 03 D0 13 C9 2A 3D F2 F6 40 3C 28 24 3C 28 11 3C 28 2C 7E 23 FE; -0C58: 1A 28 26 CD 66 54 0B 78 B1 18 F0 7E 23 CD 75 54 FE 1A 28 15 0B 78 B1 20; -0C70: F2 18 0E 7E 23 FE 1A 28 08 CD A8 53 0B 78 B1 20 F2 ED 4B E8 F2 18 B0 4B; -0C88: 42 CD B1 49 78 B1 CA 41 4D CD 12 4F D2 41 4D CD 97 F2 AF 4F 47 3C 32 DE; -0CA0: F2 18 94 CD 7D 48 F5 C5 CD 96 54 FD 71 14 FD 70 15 FD 73 16 FD 72 17 C1; -0CB8: F1 FA 47 4C FD CB 18 B6 C5 CD 53 49 C1 2A F4 F2 ED 5B F6 F2 78 B1 CA DD; -0CD0: 4D 0B 09 30 01 13 44 4D EB DD 5E 02 DD 56 03 CD 32 49 60 69 DD 46 07 05; -0CE8: 28 06 CB 3C CB 1D 10 FA E5 FD 4E 10 FD 46 11 FD 6E 12 FD 66 13 CD 32 49; -0D00: 7C B5 28 01 03 CD 9A F2 ED 43 F0 F2 ED 4B EC F2 CD 89 49 22 EC F2 ED 53; -0D18: EA F2 E3 B7 ED 52 EB E1 28 1F 78 B1 CA 87 4C C5 4B 42 CD 12 4F C1 DA 97; -0D30: 4C ED 5B EA F2 13 0B CD B1 49 22 EC F2 ED 53 EA F2 CD 46 4A 2A FC F2 7C; -0D48: B5 28 41 ED 5B EE F2 19 22 EE F2 CD 7B 4A 3E 01 32 DF F2 3A DD F2 2A EC; -0D60: F2 ED 4B FC F2 C5 CD 48 4E C5 F5 47 38 05 3E FF 32 41 F2 CD 55 47 F1 D1; -0D78: E1 4F AF 47 ED 42 28 0C 4D 44 2A EA F2 23 22 EA F2 EB 18 D9 CD 9D F2 CD; -0D90: 6B 4A D4 46 4A 2A E2 F2 ED 5B 3D F2 B7 ED 52 ED 5B F4 F2 19 ED 5B F6 F2; -0DA8: 30 01 13 22 F4 F2 ED 53 F6 F2 FD 4E 10 FD 46 11 B7 ED 42 FD 4E 12 FD 46; -0DC0: 13 EB ED 42 38 10 FD E5 E1 11 10 00 19 EB 21 F4 F2 01 04 00 ED B0 ED 4B; -0DD8: E8 F2 C3 22 4C 7C B5 B2 B3 28 4F 01 01 00 ED 42 EB 0B ED 42 42 4B DD 5E; -0DF0: 02 DD 56 03 CD 32 49 DD 7E 07 3D 28 06 CB 38 CB; -0E00: 19 18 F7 CD 89 49 78 B1 28 1C CD 12 4F DA 97 4C 01 00 00 ED 43 E8 F2 ED; -0E18: 43 EA F2 FD 6E 1A FD 66 1B 22 EC F2 18 A0 01 FF 0F CD 9E 4F 1B 3E 01 12; -0E30: 18 DE FD 6E 1A FD 66 1B 7C B5 28 D4 AF FD 77 1A FD 77 1B CD 9B 4F 18 E4; -0E48: CD A0 F2 57 E5 04 05 28 02 0E FF 59 D5 DD 7E 06 32 DD F2 3C 92 47 22 EC; -0E60: F2 E5 CD F4 41 D1 79 90 4F 28 0D DD 46 06 38 5A 04 13 EB ED 52 EB 28 E6; -0E78: D1 E3 E5 D5 7B 91 5F 16 00 DD 4E 02 DD 46 03 CD 16 49 F1 2A E2 F2 E5 09; -0E90: 22 E2 F2 C1 E1 C5 D5 EB 2A EC F2 ED 52 ED 4B EA F2 09 22 EA F2 EB CD DB; -0EA8: 4E EB C1 3A 41 F2 DD BE 00 79 37 20 12 2A 3F F2 B7 ED 52 38 0A 60 69 19; -0EC0: 2B ED 4B 3F F2 ED 42 E1 C1 C9 80 32 DD F2 0E 00 18 A6 CD FA 41 7D 29 29; -0ED8: E6 3F C9 CD A3 F2 C5 DD 46 07 2B 2B 05 28 06 CB 25 CB 14 10 FA B5 6F DD; -0EF0: 4E 0C DD 46 0D 09 C1 C9 D5 FD E1 FD 4E 20 FD 46 0C FD 5E 0E 16 00 CB 21; -0F08: CB 3B CB 18 CB 19 21 01 00 C9 CD A6 F2 DD 5E 13 DD 56 14 EB 7E 23 66 6F; -0F20: E5 EB DD 5E 0E DD 56 0F ED 53 02 F3 E5 C5 E5 54 5D D5 EB 2A 02 F3 2B B7; -0F38: ED 52 EB D1 30 10 7B B2 20 14 E1 E1 E1 01 FF 0F CD 9E 4F 37 18 46 23 CD; -0F50: 5E 4F 7B B2 28 DB 1B EB CD 5E 4F EB 18 D3 E5 D5 CD F4 41 D1 E1 C0 C1 4D; -0F68: 44 E3 DD 5E 13 DD 56 14 CD 21 42 E1 C1 0B 78 B1 20 B3 01 FF 0F CD 21 42; -0F80: 1B 3E 01 12 E1 E5 CD F4 41 C1 79 B0 20 06 FD 75 1A FD 74 1B EB C1 71 23; -0F98: 70 EB C9 01 00 00 CD A9 F2 E5 CD F4 41 E3 CD 21 42 E1 7C B5 C8 7C FE 0F; -0FB0: 38 E9 7D FE F8 38 E4 C9 CD A5 42 38 43 3A B8 F2 28 02 3E FF 32 0B F3 DD; -0FC8: 22 09 F3 ED 5B 3D F2 3A E1 F2 3C 12 13 7E FE 05 20 02 36 E5 01 20 00 CD; -0FE0: D9 F1 CD 39 44 3A 0C F3 B8 28 04 30 13 0E 80 2A 3D F2 11 0C 00 19 46 77; -0FF8: 23 70 23 72 23 71 AF C9 3E FF 32 0B F3 C9 CD 0E 44 38 F5 3A 0B F3 FE FF; -1010: 28 EE 32 B8 F2 DD 2A 09 F3 CD BC 42 18 9D CD A5 42 3E FF D8 D5 DD E1 FD; -1028: 7E 1C FD 4E 1D FD 46 1E FD 5E 1F 87 CB 11 CB 10 CB 13 B7 28 06 03 78 B1; -1040: 20 01 1C DD 71 21 DD 70 22 DD 73 23 AF C9 3A 47 F3 47 AF 37 17 10 FC C9; -1058: ED 53 3D F2 C9 AF 32 06 F3 7B CD 27 44 3E FF D8 CD DB 44 DD 5E 13 DD 56; -1070: 14 D5 FD E1 21 02 00 44 4C DD 5E 0E DD 56 0F 1B D5 D5 E5 CD F4 41 E1 D1; -1088: 20 01 03 23 1B 7B B2 20 F0 60 69 D1 DD 7E 06 3C DD 4E 02 DD 46 03 C9 21; -10A0: 80 00 22 3D F2 AF 32 47 F2 CD 2D 47 21 55 F3 3A 47 F3 5E 23 56 23 E5 F5; -10B8: D5 DD E1 CD C4 45 F1 E1 3D 20 EF C9 3A 47 F2 C9 CD F8 4E FD 75 21 FD 74; -10D0: 22 FD 73 23 C9 3A 47 F3 BB D8 C8 21 47 F2 73 C9 D5 3A 37 F2 32 38 F2 AF; -10E8: 32 39 F2 62 6B 47 4E 23 57 5E 23 DD 21 59 F4 7B B9 30 06 E5 19 7E E1 FE; -1100: 0D 28 01 5A CD AC F2 CD 4E 54 E5 C5 21 74 53 01 11 00 ED B1 09 09 09 4E; -1118: 23 66 69 C1 E3 C9 CD 4E 54 FE 40 38 E5 FE 60 30 E1 F5 78 3C B9 30 2F 3E; -1130: 01 DD 77 00 DD 23 04 CD 5D 53 F1 F5 78 B9 30 1E F1 DD 77 00 DD 23 04 CD; -1148: 5D 53 3A 39 F2 B7 20 B4 14 7B BA 38 AF 7E 3D 23 20 AA 14 23 18 A6 F1 3E; -1160: 07 CD A8 53 18 9E D1 3A 38 F2 47 3A 37 F2 90 28 06 47 CD 4F 53 10 FB C3; -1178: E0 50 78 32 3A F2 CD 83 51 18 81 3E 0D CD A8 53 3E 0A C3 A8 53 D1 CD A8; -1190: 53 D5 13 78 12 B9 F5 13 48 AF 47 B1 28 05 21 59 F4 ED B0 F1 28 03 3E 0D; -11A8: 12 D1 C9 3A 3A F2 A0 FE 7F CA 44 52 04 05 28 24 05 DD 2B CD 4F 53 04 05; -11C0: 28 0C 05 DD 2B DD 7E 00 3D 28 11 04 DD 23 DD 7E 00 FE 20 30 07 FE 09 28; -11D8: 22 CD 4F 53 3A 39 F2 B7 20 9F 14 15 28 9B 15 7A BB 30 96 2B 7A FE 01 38; -11F0: 90 2B 7E 3D 23 20 8A 15 2B 18 86 E5 C5 3A 38 F2 4F 04 05 28 15 21 59 F4; -1208: 7E 23 FE 01 28 0A 0C FE 20 30 05 FE 09 28 13 0C 10 EE 3A 37 F2 91 28 06; -1220: 47 CD 4F 53 10 FB C1 E1 18 B2 79 C6 07 E6 F8 4F 18 E6 3A 39 F2 EE 01 18; -1238: 05 AF 18 02 3E 01 32 39 F2 C3 04 51 AF 32 3A F2 C5 06 10 11 7D 54 21 00; -1250: 00 E5 CD D2 4E C6 20 CD A8 53 7C C6 20 CD A8 53 E1 23 10 ED C1 3E 40 D1; -1268: CD 8E 51 CD 83 51 3A 38 F2 B7 CA E0 50 47 3E 20 CD A8 53 10 FB C3 E0 50; -1280: 3E FF 18 31 CD E3 52 DA 04 51 C5 4F 06 00 09 C1 82 57 C3 04 51 CD E3 52; -1298: DA 04 51 18 18 7A BB D2 04 51 14 7E 3D 23 C2 04 51 14 23 C3 04 51 7E 3D; -12B0: 3E 01 20 01 3C F5 AF 32 39 F2 78 B9 30 21 7A BB 30 1D 7E FE 01 20 06 78; -12C8: 3C B9 30 13 7E 23 DD 77 00 DD 23 CD 5D 53 04 14 F1 3D 20 D9 C3 04 51 F1; -12E0: C3 04 51 CD 4E 54 FE 01 20 35 CD 4E 54 FE 40 38 2E FE 60 30 2A E5 D5 C5; -12F8: FD 21 00 00 37 F5 3E 01 CD 1F 53 38 15 4F 06 00 09 82 57 FD E5 F1 81 F5; -1310: FD E1 23 F1 BE 2B 20 E4 FD E5 F1 C1 D1 E1 C9 C5 F5 7B 92 38 26 28 24 3D; -1328: 28 21 4F 06 00 F1 E5 F5 7E 3D 20 02 23 0D F1 0C 0D 20 04 E1 C1 37 C9 23; -1340: ED B1 E1 20 07 7B 92 3D 91 C1 C9 F1 C1 37 C9 3E 08 CD A8 53 3E 20 CD A8; -1358: 53 3E 08 18 4B FE 20 30 47 FE 09 28 43 FE 01 28 3F F5 3E 5E CD A8 53 F1; -1370: F6 40 18 34 06 7F 08 0D 0A 15 0B 0C 1B 12 18 1C 1D 1E 1F 01 08 3B 51 1E; -1388: 51 80 52 66 51 AB 51 AE 52 95 52 32 52 66 51 84 52 65 52 66 51 7A 51 8D; -13A0: 51 AB 51 9D 52 04 51 7B CD AF F2 FE 0B 28 39 FE 0C 28 35 FE 1C 28 1E FE; -13B8: 1D 28 35 FE 0D 28 29 FE 08 28 2D FE 09 28 31 FE 7F 28 25 FE 20 38 06 E5; -13D0: 21 37 F2 34 E1 C5 47 CD 12 54 78 CD 8F 40 3A 3B F2 B7 78 C1 C8 C3 9B 40; -13E8: F5 AF 32 37 F2 F1 18 E5 E5 21 37 F2 35 E1 18 DD 3E 20 CD A8 53 3A 37 F2; -1400: E6 07 20 F4 C9 FE 10 28 14 FE 0E 28 10 FE 03 28 0C C9 CD 34 40 C8 FE 13; -1418: 20 EB CD 78 40 CD 78 40 FE 10 28 0D FE 0E 28 0F FE 03 C0 2A 25 F3 C3 E8; -1430: F1 3E 01 32 3B F2 C9 AF 32 3B F2 C9 CD 12 54 3E 00 C8 F6 FF C9 CD 4E 54; -1448: F5 CD A8 53 F1 C9 CD 1D 54 28 FB C9 7B FE FF C2 8F 40 CD 34 40 C2 78 40; -1460: AF C9 C3 78 40 7B F5 CD 12 54 F1 C3 9B 40 CD 12 54 C3 71 F3 7B F5 CD 12; -1478: 54 F1 C3 74 F3 ED 8C 93 EF 0C 88 39 40 03 70 48 97 F2 FC BA 80 0A CC B5; -1490: 5E AF 29 00 00 C9 CD B2 F2 CD C0 54 79 87 87 87 CB 10 87 CB 10 87 CB 10; -14A8: CB 3A B2 5F 50 ED 4B 49 F2 79 87 87 87 87 87 CB 10 4F 3A 48 F2 B1 4F C9; -14C0: CD 79 41 38 46 D5 E5 ED 5B 4C F2 B7 ED 52 E1 D1 C8 22 4C F2 C5 D5 4D 44; -14D8: 11 B5 05 CD 2F 49 79 87 87 87 06 00 11 34 55 CD 15 55 CB 3F 30 04 11 C8; -14F0: 00 19 CD 23 55 3E 01 11 2B F2 CD 15 55 32 49 F2; -1500: 2C 7D 32 48 F2 CD 88 55 D1 C1 C9 C5 D5 2A 4A F2 CD 9D 55 18 F0 EB 4E 23; -1518: EB B7 ED 42 38 03 3C 18 F4 09 C9 CD B5 F2 32 4A F2 E6 03 3E 1C 20 01 3C; -1530: 32 2C F2 C9 C8 A6 C8 A5 C8 A5 C8 A5 AF 32 06 F3 CD C0 54 2A 4A F2 11 BC; -1548: 07 19 ED 5B 48 F2 3A 4E F2 C9 01 44 F8 09 30 42 7C B7 20 3E 7D FE 78 30; -1560: 39 CD 29 55 1C 1D 28 32 7A B7 28 2E FE 0D 30 2A E5 21 2A F2 85 6F 30 01; -1578: 24 7E E1 BB 38 1C ED 53 48 F2 CD 9D 55 CD 15 41 ED 4B 4C F2 11 07 00 03; -1590: 03 CD 2F 49 7D 32 4E F2 AF C9 3E FF C9 7D CD 23 55 4D CB 39 CB 39 06 00; -15A8: 11 B5 05 CD 16 49 69 60 3A 4A F2 E6 03 87 11 34 55 06 00 3C CD D2 55 11; -15C0: 2B F2 3A 49 F2 CD D2 55 3A 48 F2 3D 4F 09 22 4C F2 C9 3D C8 EB 4E 23 EB; -15D8: 09 18 F7 AF 32 06 F3 CD C0 54 60 69 AF C9 44 4D 78 FE 18 30 AD 3E 3B B9; -15F0: 38 A8 BA 38 A5 7B FE 64 30 A0 CD 30 41 AF C9 7B 32 0D F3 C9 7E FE 20 37; -1608: C8 01 02 08 FE E5 20 12 3E 05 12 23 13 05 3E E5 CD 81 56 30 05 7E 12 23; -1620: 13 05 7E CD 81 56 30 09 12 23 13 05 37 C8 7E 18 36 3A 0E F3 A7 7E 28 14; -1638: FE 80 38 10 FE BA 30 0C E5 C5 4F 06 00 21 16 56 09 7E C1 E1 FE 61 38 06; -1650: FE 7B 30 02 D6 20 FE 20 D8 E5 C5 21 77 56 01 0A 00 ED B1 C1 E1 37 C8 12; -1668: 23 13 10 B6 06 03 0D 20 B1 B7 7E 32 0C F3 C9 2E 22 2F 5B 5D 3A 2B 3D 3B; -1680: 2C E5 21 0F F3 BE 3F 30 0B 23 BE 38 07 23 BE 3F 30 02 23 BE E1 C9 80 9A; -1698: 45 41 8E 41 8F 80 45 45 45 49 49 49 8E 8F 90 92 92 4F 99 4F 55 55 59 99; -16B0: 9A 9B 9C 9D 9E 9F 41 49 4F 55 A5 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B0; -16C8: B2 B2 B4 B4 B6 B6 B8 B8 AF 47 C9 FB 3E 01 32 06 F3 79 FE 31 30 F2 D6 11; -16E0: 20 04 ED 53 07 F3 3D 20 04 ED 5B 07 F3 E5 21 00 57 E3 E5 21 0D 57 06 00; -16F8: 09 09 46 23 66 68 E3 C9 F5 3A 06 F3 B7 28 04 F1 6F 60 C9 F1 C9 A7 40 45; -1710: 54 A7 53 6E 54 74 54 65 54 54 54 62 54 4E 54 C9 F1 E0 50 3C 54 EF 41 9F; -1728: 50 D5 50 62 44 6F 45 B8 4F 06 50 6C 43 75 47 7D 47 1D 46 92 43 4E 50 C4; -1740: 50 58 50 5D 50 D0 56 D0 56 D0 56 D0 56 D0 56 88 47 93 47 1E 50 C8 50 D0; -1758: 56 BE 47 B2 47 D1 47 D0 56 3C 55 52 55 DB 55 E6 55 FF 55 BA 46 20 47 CD; -1770: 1D 78 F3 3A 99 FD A7 F8 C2 0C 58 21 20 FB CB 46 20 0C CB C6 21 CA FF 06; -1788: 0F 36 C9 23 10 FB 2A 48 FC 11 01 C0 E7 30 0C 3E 06 CD 41 01 F3 0F 38 09; -17A0: 3E 07 DF 3E FF 32 99 FD C9 21 88 F3 11 C9 F1 A7 ED 52 D4 E8 5E D8 E5 21; -17B8: 49 FE 01 C9 F1 AF 02 03 23 7D B4 20 F8 22 AB F6 06 14 21 21 FB 77 23 10; -17D0: FC 21 4F F2 06 69 36 C9 23 10 FB 3E DB 21 A8 C9 32 65 F3 22 66 F3 3E 06; -17E8: CD 41 01 E6 02 32 3F F3 3E 07 DF 21 07 58 11 CB FE 01 05 00 ED B0 CD 2D; -1800: 40 32 CC FE D1 18 1E F7 00 97 58 C9 21 21 FB 06 04 AF 86 DA CC 5E 23 23; -1818: 10 F8 FE 08 D0 21 08 00 CD E8 5E D8 EB CD CD 5F 73 23 72 2A AB F6 11 00; -1830: 02 E7 30 04 ED 53 AB F6 11 21 FB 01 00 04 1A A7 28 09 81 4F 13 13 10 F6; -1848: C3 CC 5E 3A 3F F3 A7 79 CD 3C 78 85 FE 09 7D 38 03 3E 08 91 C5 12 13 CD; -1860: 2D 40 12 C1 06 00 21 55 F3 09 09 E5 1B 1A F5 4F 11 15 00 CD 16 49 69 60; -1878: CD C8 5E EB F1 E1 73 23 72 23 E5 21 16 74 01 15 00 ED B0 E1 3D 20 EF CD; -1890: 88 78 21 99 FD 34 C9 21 CB FE 06 05 36 C9 23 10 FB 21 99 FD AF BE 77 F0; -18A8: CD 2D 62 32 48 F3 21 97 73 11 C9 F1 01 6E 00 ED B0 21 34 00 11 0F F3 01; -18C0: 04 00 ED B0 3A 2B 00 0F 0F 0F 0F E6 07 32 0E F3 3E FF 32 41 F2 32 46 F2; -18D8: 32 4D F2 3E 0D 32 5B F5 3E 07 32 45 F3 21 B5 05 22 3B F3 06 08 21 68 F3; -18F0: 36 C3 23 23 23 10 F9 2A AB F6 E5 CD C8 5E 22 4D F3 E1 E5 CD C8 5E 22 4F; -1908: F3 E1 CD C8 5E 22 51 F3 21 21 FB 06 04 AF 86 DA CC 5E 23 23 10 F8 FE 09; -1920: D2 CC 5E 32 47 F3 47 0E 00 21 55 F3 5E 23 56 23 E5 D5 DD E1 DD 71 00 0C; -1938: C5 DD 4E 02 DD 46 03 DD 5E 10 16 00 CD 16 49 03 69 60 CD C8 5E 22 49 F3; -1950: 36 FF 23 DD 75 13 DD 74 14 C1 E1 10 CF 21 27 F3 36 3E 23 36 1A 06 08 23; -1968: 36 C9 10 FB 21 27 F3 22 72 F3 21 2C F3 22 75 F3 21 31 F3 22 7E F3 21 2F; -1980: 7D 3A C1 FC CD 0C 00 F5 23 3A C1 FC CD 0C 00 D1 67 6A E5 DD E1 FD 2A C0; -1998: FC CD 1C 00 CD B8 40 CD 6E 5C 3A C1 FC 32 41 F3 32 42 F3 CD 98 5F 32 43; -19B0: F3 CD 95 5F 32 44 F3 0E 00 CD 52 5E 38 03 32 41 F3 0E 40 CD 52 5E 38 03; -19C8: 32 42 F3 31 00 C2 3A DA FE FE C9 28 06 DD 21 17 7D 18 12 21 C9 FC 06 40; -19E0: 7E 87 38 05 23 10 F9 18 0A DD 21 14 7E CD 16 5C C3 59 01 21 3A 5B E5 CD; -19F8: E7 5A D8 CD DB 5A 2A 48 FC 11 00 80 E7 C0 21 41 F3 3A C1 FC BE C8 23 BE; -1A10: C8 AF CD 9A 60 2A 49 F3 22 4B F3 CD E7 5A DA 3A 5B 32 46 F3 3A 41 F3 26; -1A28: 00 CD C2 64 37 F4 A2 64 DC AF 64 AF 6F 67 77 2C 20 FC 01 26 00 CD AD 5E; -1A40: 22 6F F3 EB 21 7B 63 ED B0 01 19 00 CD AD 5E 5D 54 22 69 F3 23 23 22 6C; -1A58: F3 21 A1 63 ED B0 01 68 01 CD AD 5E E5 EB 21 F4 63 E5 ED B0 C1 D1 D5 21; -1A70: 17 01 19 36 3B 23 36 00 21 BA 63 CD 06 63 21 0F 5B AF 47 57 5E BB 28 10; -1A88: 23 4E 23 E3 09 EB 36 C3 23 73 23 72 EB E3 18 EC E1 21 5C 65 11 3B 00 01; -1AA0: 1A 00 ED B0 01 45 00 CD AD 5E E5 EB 21 36 63 E5 ED B0 C1 D1 D5 21 2E 63; -1AB8: CD 06 63 E1 3E C3 32 38 00 22 39 00 11 22 00 19 ED 5B 4B F3 73 23 72 01; -1AD0: A0 00 CD AD 5E 3E C3 CD 62 5C 37 21 23 F3 11 68 F3 3A 40 F3 C3 1E C0 3A; -1AE8: 17 74 4F 06 01 2A 51 F3 E5 AF 5F 57 CD 44 01 3E FF 32 46 F2 E1 D8 7E 11; -1B00: 00 C0 01 00 01 ED B0 FE EB C8 FE E9 C8 37 C9 0C 00 14 21 30 2E 1C 12 24; -1B18: 47 00 00 41 55 54 4F 45 58 45 43 42 41 53 00 52 55 4E 22 41 55 54 4F 45; -1B30: 58 45 43 2E 42 41 53 00 92 5B CD 60 5C 21 27 5B 11 68 F5 01 11 00 ED B0; -1B48: 21 40 F3 7E A7 74 20 1E 32 46 F3 21 38 5B 22 23 F3 21 1A 5B 11 79 F5 01; -1B60: 25 00 D5 ED B0 D1 CD 62 44 3C 28 26 18 32 3A 00 00 FE C3 20 27 21 80 00; -1B78: 46 04 05 28 1F 23 7E FE 20 20 04 10 F8 18 15 AF 48 47 11 6C F5 ED B0 12; -1B90: 18 0E 31 00 C2 3A 38 F3 A7 CC 3F 5D AF 32 6B F5 31 00 C2 3A 43 F3 26 80; -1BA8: CD 24 00 3A C1 FC 26 00 CD 24 00 2A 48 FC AF 77 23 22 76 F6 77 23 77 23; -1BC0: 22 C2 F6 21 FF FF 22 1C F4 CD 16 5C ED 7B 74 F6 3E FF 32 DE F3 3E 0C DF; -1BD8: DD 21 31 7D CD 59 01 CD 86 5F 0D 0A 44 69 73 6B 20 42 41 53 49 43 20 76; -1BF0: 65 72 73 69 6F 6E 20 31 2E 30 0D 0A 00 21 73 41; -1C00: E5 21 67 F5 E5 21 9E F5 E5 36 E1 23 36 C9 3A C1 FC 26 40 C3 24 00 21 AE; -1C18: 72 22 23 F3 21 6C 5C 22 25 F3 2A 49 F3 22 4A FC 3A 45 F3 4F 06 00 11 25; -1C30: 00 CD 16 49 CD B8 5E 22 53 F3 01 19 00 CD B8 5E 22 78 F3 EB 21 ED 62 ED; -1C48: B0 21 F5 FF 19 22 7B F3 3A 48 F3 11 F9 FF 19 77 11 0E 00 19 77 CD 5F 5F; -1C60: 3E C9 32 68 F3 32 6B F3 32 6E F3 C9 A7 40 21 E8 62 11 BC FE 01 05 00 ED; -1C78: B0 21 96 5C 5E 23 56 23 7B B2 C8 EB 36 F7 23 3A 48 F3 77 23 EB ED A0 ED; -1C90: A0 3E C9 12 18 E6 EF FD 96 6B 17 FE 75 6B F9 FD 20 6F FE FD 00 6F 08 FE; -1CA8: 7B 70 12 FE 61 70 21 FE D7 6C 26 FE D6 6C 2B FE 49 6C 30 FE AF 6D 35 FE; -1CC0: B2 6D 3A FE B5 6D 3F FE D7 6D 44 FE DA 6D 49 FE DD 6D 4E FE A4 66 58 FE; -1CD8: B3 66 5D FE FC 66 62 FE D0 68 71 FE 0E 69 76 FE 39 69 7B FE 88 6E 80 FE; -1CF0: DA 6B 85 FE 8E 68 8A FE 19 68 99 FE 0D 70 9E FE 09 70 A3 FE 70 6E AD FE; -1D08: 75 68 B2 FE 23 73 B7 FE 7C 73 FD FE D3 71 A7 FF 55 60 AC FF B0 60 31 F3; -1D20: D3 56 00 00 01 48 2D 01 41 2D 01 47 29 3A 00 4D 2D 44 2D 59 29 3A 00 44; -1D38: 2D 4D 2D 59 29 3A 00 ED 73 C0 F5 3E 14 32 C2 F5 CD 86 5F 0D 0A 45 6E 74; -1D50: 65 72 20 64 61 74 65 20 28 00 00 00 00 00 00 3A 0E F3 FE 01 21 24 5D 38; -1D68: 08 21 2F 5D 28 03 21 37 5D CD 8C 5F 21 4B 5E 22 25 F3 11 C2 F5 CD E0 50; -1D80: 21 C4 F5 7E FE 0D C8 3A 0E F3 A7 20 12 CD 0D 5E CD E9 5D 51 7E 23 B8 20; -1D98: 32 CD F8 5D 59 18 1A CD F8 5D 51 CD E9 5D 59 7E 23 B8 20 05 CD 0D 5E 18; -1DB0: 08 D5 CD 3C 55 E5 DD E1 D1 3A 0E F3 FE 02 38 03 7B 5A 57 DD E5 E1 CD 52; -1DC8: 55 B7 C8 ED 7B C0 F5 CD 86 5F 0D 0A 49 6E 76 61 6C 69 64 20 64 61 74 65; -1DE0: 00 00 00 00 00 00 C3 48 5D 7E 23 47 FE 2F 28 08 FE 2E 28 04 FE 2D 20 D3; -1DF8: CD 41 5E 38 CE 4F CD 41 5E D8 F5 79 87 87 81 87 4F F1 81 4F C9 CD F8 5D; -1E10: 41 CD 41 5E 38 16 2B CD F8 5D E5 C5 48 06 00 D5 11 64 00 CD 16 49 D1 E1; -1E28: 26 00 18 0F E5 48 06 00 21 6C 07 79 FE 50 30 03 21 D0 07 09 E5 DD E1 E1; -1E40: C9 7E D6 30 D8 FE 0A 3F D8 23 C9 4D 5E ED 7B C0 F5 C9 21 C1 FC 06 04 AF; -1E58: E6 03 B6 C5 E5 61 2E 10 F5 CD 0C 00 2F 5F F1 D5 F5 CD 14 00 F1 D1 F5 D5; -1E70: CD 0C 00 C1 47 79 2F 5F F1 F5 C5 CD 14 00 C1 79 B8 20 17 F1 2D 20 D9 24; -1E88: 24 24 24 4F 7C FE 40 28 05 FE 80 79 20 C8 79 E1 E1 C9 F1 E1 C1 A7 F2 A7; -1EA0: 5E C6 04 FE 90 38 B4 23 3C 10 AD 37 C9 2A 4B F3 A7 ED 42 22 4B F3 18 09; -1EB8: 2A 4A FC A7 ED 42 22 4A FC 38 09 7C FE C2 18 03 CD E8 5E D0 CD 86 5F 0C; -1ED0: 4E 6F 20 65 6E 6F 75 67 68 20 6D 65 6D 6F 72 79 00 00 00 00 00 00 F3 76; -1EE8: 7D B4 C8 AF 95 6F 3E 00 9C 67 4D 44 39 3F D8 ED 5B 48 FC ED 52 D8 7C FE; -1F00: 02 D8 C5 21 00 00 39 5D 54 09 E5 2A 74 F6 A7 ED 52 4D 44 03 E1 F9 EB ED; -1F18: B0 C1 2A 4A FC 09 22 4A FC 11 EA FD 19 22 60 F8 EB 2A 72 F6 09 22 72 F6; -1F30: 2A 62 F8 09 22 62 F8 2A 74 F6 09 22 74 F6 2B 2B 22 B1 F6 6B 62 23 23 23; -1F48: 23 3E 02 EB 73 23 72 23 EB 01 07 00 70 09 70 01 02 01 09 3D 20 ED C9 3E; -1F60: 01 32 5F F8 2A 4A FC 11 EA FD 19 22 60 F8 5D 54 2B 2B 22 72 F6 01 C8 00; -1F78: A7 ED 42 E5 21 0D 00 19 22 62 F8 E1 18 B5 E3 CD 8C 5F E3 C9 7E 23 A7 C8; -1F90: CD 8F 40 18 F7 06 06 21 06 04 CD 65 F3 C5 0F 10 FD CD EC 5F C1 B6 4F 23; -1FA8: 23 23 23 7E 05 05 0F 10 FD 18 0B CD E7 5F B6 F0 4F 23 23 23 23 7E E6 0C; -1FC0: B1 C9 CD CD 5F 7E 23 66 6F E5 DD E1 C9 CD E7 5F 87 87 87 37 8F 4F 7E 87; -1FD8: 9F E6 0C 23 23 23 23 A6 B1 87 21 09 FD 18 0C CD 65 F3 0F 0F E6 03 21 C1; -1FF0: FC 06 00 4F 09 C9 3A 9F FD FE C9 28 15 E5 3A 99 FD 21 29 FB CD F1 5F 09; -2008: 09 EB 21 A0 FD 0E 03 ED B0 E1 F3 3E F7 32 9F FD 22 A1 FD 3E C9 32 A3 FD; -2020: CD 2D 40 32 A0 FD C9 F5 CD 2D 40 06 04 11 29 FB 21 22 FB BE 28 09 13 13; -2038: 13 23 23 10 F6 F1 C9 EB 7E A7 28 F9 F5 FD E1 23 4E 23 46 C5 DD E1 F1 C3; -2050: 1C 00 A7 38 37 DD E5 FD E5 E5 F5 CD 86 60 6F F1 7D DD 21 10 40 18 14 DD; -2068: E5 DD 21 13 40 18 06 DD E5 DD 21 16 40 FD E5 E5 CD 86 60 E1 E5 CD 1C 00; -2080: C3 6E 63 00 00 00 32 3F F3 21 21 FB 96 38 04 23 23 18 F9 86 23 66 E5 FD; -2098: E1 C9 21 55 F3 CD F1 5F 09 5E 23 56 21 13 00 19 5E 23 56 1B EB 36 FF C9; -20B0: A7 ED 73 39 F3 D4 D6 62 E5 C5 3A 47 F3 3D 28 41 CD 86 5F 44 72 69 76 65; -20C8: 20 6E 61 6D 65 3F 20 28 00 00 00 00 00 00 3A 47 F3 47 3E 41 18 07 F5 3E; -20E0: 2C CD 8F 40 F1 CD 8F 40 3C 10 F3 CD 86 5F 29 20 00 CD 95 61 CD C6 62 E6; -20F8: DF D6 41 21 47 F3 BE 30 BF CD 9A 60 CD 86 60 FD E5 F5 FD E5 DD 21 19 40; -2110: CD 1C 00 7D B4 28 27 F1 F5 CD 0C 00 A7 28 07 CD 8F 40 23 F1 18 F2 F1 CD; -2128: 86 5F 3F 20 00 CD 95 61 D6 31 FE 09 30 F7 C6 31 CD C6 62 D6 30 F5 CD 74; -2140: 61 F1 D1 FD E1 C1 E1 DD 21 1C 40 CD 1C 00 21 E0 61 30 0A 21 48 62 CD F1; -2158: 5F 7E 23 66 6F CD C9 62 CD 8C 5F C3 C9 62 AF 32 36 F3 DD 21 56 01 CD AB; -2170: 40 C3 78 40 CD 86 5F 53 74 72 69 6B 65 20 61 20 6B 65 79 20 77 68 65 6E; -2188: 20 72 65 61 64 79 20 00 00 00 00 00 00 CD 66 61 FE 03 C0 ED 7B 39 F3 CD; -21A0: 86 5F 0D 0A 41 62 6F 72 74 65 64 00 C9 57 72 69 74 65 20 70 72 6F 74 65; -21B8: 63 74 65 64 00 4E 6F 74 20 72 65 61 64 79 00 44 69 73 6B 20 65 72 72 6F; -21D0: 72 00 42 61 64 20 70 61 72 61 6D 65 74 65 72 00 46 6F 72 6D 61 74 20 63; -21E8: 6F 6D 70 6C 65 74 65 00 00 11 98 F6 2A 78 F6 22 F8 F7 3E 03 32 63 F6 CD; -2200: F3 2E 11 9B F6 E7 22 78 F6 C0 C3 F7 72 21 21 FB 06 04 23 7E F5 FD E1 23; -2218: E5 C5 21 1F 40 E5 DD E1 A7 C4 0C 00 A7 C4 1C 00 C1 E1 10 E6 C9 3A D0 FE; -2230: FE C9 28 11 21 F2 72 11 D5 FE 01 05 00 ED B0 CD 2D 40 32 D6 FE C3 2D 40; -2248: AD 61 BD 61 C7 61 C7 61 C7 61 C7 61 D2 61 D0 5E C7 61 3A 3F F3 C6 41 CD; -2260: 4F F2 F5 CD 86 5F 0D 0A 49 6E 73 65 72 74 20 64 69 73 6B 65 74 74 65 20; -2278: 66 6F 72 20 64 72 69 76 65 20 00 00 00 00 00 00 00 00 00 00 00 F1 CD 8F; -2290: 40 CD 86 5F 3A 0D 0A 61 6E 64 20 73 74 72 69 6B 65 20 61 20 6B 65 79 20; -22A8: 77 68 65 6E 20 72 65 61 64 79 00 00 00 00 00 00 00 00 00 00 00 CD 66 61; -22C0: FE 03 28 F9 18 03 CD 8F 40 F5 3E 0D CD 8F 40 3E 0A CD 8F 40 F1 C9 21 00; -22D8: FF 39 ED 5B C6 F6 AF ED 52 4D 44 EB D0 4F 47 C9 33 33 C3 1D 6F 7A FE 09; -22F0: D2 C9 6E F7 00 A7 6A E5 C3 F4 6E 7A FE 09 D2 95; -2300: 6E F7 00 E7 69 C9 D5 EB A7 ED 42 E5 DD E1 EB D1 4E 23 46 23 79 A0 3C C8; -2318: D5 EB 09 23 4E 23 46 E5 DD E5 E1 09 4D 44 E1 70 2B 71 EB D1 18 E2 0C 00; -2330: 1E 00 2F 00 FF FF DD E5 FD E5 E5 D5 C5 F5 D9 08 F5 E5 2A 5F 63 7D B4 E1; -2348: DD 21 38 00 FD 2A C0 FC 20 23 F1 ED 73 5F 63 31 00 00 CD 1C 00 F3 31 00; -2360: 00 E5 21 00 00 22 5F 63 E1 08 D9 F1 C1 D1 E1 FD E1 DD E1 FB C9 F1 CD 1C; -2378: 00 18 EE F5 E5 D5 C5 CD 2D 40 F5 26 40 3A 42 F3 CD 24 00 F1 C1 D1 E1 ED; -2390: B0 E5 D5 C5 CD 68 F3 26 40 CD 24 00 C1 D1 E1 F1 C9 18 06 F5 3A 42 F3 18; -23A8: 04 F5 3A 48 F3 E5 D5 C5 26 40 CD 24 00 C1 D1 E1 F1 C9 00 00 03 00 17 00; -23C0: 1C 00 22 00 25 00 39 00 3F 00 69 00 6C 00 7E 00 94 00 A8 00 AB 00 BC 00; -23D8: 10 00 13 00 31 00 34 00 78 00 7B 00 B5 00 B8 00 2A 01 31 01 38 01 45 01; -23F0: 4D 01 FF FF CD C2 64 FA 04 64 DB A8 57 A1 B0 CD 80 F3 7B C9 CD 11 65 CA; -2408: 1E 65 E5 CD E7 64 E3 C5 CD F4 63 18 21 D5 CD C2 64 FA 25 64 D1 DB A8 57; -2420: A1 B0 C3 85 F3 CD 11 65 CA 24 65 E3 E5 CD E7 64 D1 E3 C5 CD 15 64 C1 E3; -2438: F5 78 E6 3F B1 CD 46 00 F1 E1 C9 E3 F5 D5 7E F5 FD E1 23 5E 23 56 23 D5; -2450: DD E1 D1 F1 E3 D9 08 FD E5 F1 DD E5 E1 CD C2 64 FA 6C 64 DB A8 F5 A1 B0; -2468: D9 C3 8C F3 CD 11 65 CA 2C 65 CD E7 64 F5 FD E1 E5 C5 4F 06 00 7D A4 B2; -2480: 21 C5 FC 09 77 E5 08 D9 CD 55 64 D9 08 E1 C1 D1 78 E6 3F B1 F3 CD 4B 00; -2498: 73 08 D9 C9 CD C2 64 FA A9 64 DB A8 A1 B0 D3 A8 C9 CD 11 65 CA 41 65 E5; -24B0: CD E7 64 4F 06 00 7D A4 B2 21 C5 FC 09 77 E1 79 18 DA F3 F5 7C 07 07 E6; -24C8: 03 5F 1C 3E C0 07 07 1D 20 FB 5F 2F 4F F1 F5 E6 03 47 04 3E AB C6 55 10; -24E0: FC 57 A3 47 F1 A7 C9 F5 7A E6 C0 4F F1 F5 57 DB A8 47 E6 3F B1 F5 7A 0F; -24F8: 0F E6 03 57 14 3E AB C6 55 15 20 FB A3 57 7B 2F 67 F1 CD 5C 65 F1 E6 03; -2510: C9 4F 7B FE 03 79 C0 3A 41 F3 A3 B8 79 C9 CD 49 65 5E 18 05 D1 CD 49 65; -2528: 73 78 18 2B CD 41 65 E5 C5 08 D9 CD 98 F3 D9 08 C1 CD 29 65 E1 70 08 D9; -2540: C9 CD 49 65 21 C5 FC 72 C9 0F 0F E6 03 57 3A FF FF 2F 47 E6 FC B2 57 32; -2558: FF FF 7B C9 D3 A8 3A FF FF 2F 6F A4 B2 18 08 D3 A8 7D 18 03 D3 A8 7B 32; -2570: FF FF 78 D3 A8 C9 3A 4E FE FE C9 37 C8 E5 CD 2D 40 21 48 F3 BE 20 26 21; -2588: B1 65 11 89 FD 1A BE 13 23 20 10 A7 20 F7 7E 23 66 6F E3 CD DA 72 37 3F; -25A0: C9 23 7E A7 20 FB 23 23 23 7E A7 20 DD E1 C3 6A 7C 53 59 53 54 45 4D 00; -25B8: C4 65 46 4F 52 4D 41 54 00 DC 65 00 C0 3A 46 F3 A7 CA 15 73 DD 21 1C 6C; -25D0: CD 1E 73 CD D2 00 CD CC 00 C3 11 5A E5 CC B1 60 E1 A7 C9 7A 3D F0 3A 47; -25E8: F2 C9 E5 D5 C5 CD E3 65 4F 2A 60 F8 3A 5F F8 F5 5E 23 56 23 E5 EB 7E A7; -2600: 28 2C 23 23 23 23 7E FE 09 30 23 2B 2B 56 2B 5E 1A CD E4 65 B9 20 17 13; -2618: EB 11 66 F8 06 0B 1A FE 3F 28 03 BE 20 08 13 23 10 F4 E1 E1 18 72 E1 F1; -2630: 3D F2 F7 65 18 6A E5 D5 C5 7A 32 68 F5 CD 57 66 CD 45 66 18 5B 21 B2 F5; -2648: 22 3D F2 11 68 F5 AF 32 74 F5 CD B8 4F 3C C9 11 69 F5 21 66 F8 01 0B 00; -2660: ED B0 C9 FB E5 D5 C5 F5 3A 48 F3 87 21 10 00 30 02 2E 18 39 DD E5 C1 71; -2678: 23 70 21 0A 00 39 EB 18 0C FD E5 C1 4E 1A 77 79 12 23 13 10 F7 3A 48 F3; -2690: 87 21 12 00 30 02 2E 1A 39 7B 95 7A 9C 38 E2 F1 C1 D1 E1 C9 DD 21 8B F3; -26A8: FD 21 00 02 CD 63 66 E1 7E A7 C9 FB 01 00 01 ED 43 3D F3 CD DA 72 7B C8; -26C0: F5 E5 3A 48 F3 87 21 0C 00 30 02 2E 14 39 7E FE 04 C2 18 73 23 7E FE 09; -26D8: D2 18 73 E1 CD D0 72 FF CD D0 72 92 CD D0 72 EF DD 21 56 47 CD 1E 73 1B; -26F0: 14 15 C2 15 73 13 ED 53 3D F3 F1 C9 FB D0 DD 21 8B F3 FD 21 00 04 CD 63; -2708: 66 CD A9 6F CD EA 65 CA 09 73 22 64 F8 7B FE 04 28 07 01 01 00 ED 43 3D; -2720: F3 F1 F5 E5 D5 21 45 F3 BE D2 0C 73 01 25 00 5F 50 2A 53 F3 CD 1C 49 AF; -2738: 21 0C 00 09 77 D1 E1 23 71 23 70 23 77 23 72 23 23 77 CD 36 66 C5 D5 7A; -2750: 02 59 50 13 CD 5A 66 D1 C1 7B 20 1C E6 86 CA 12 73 D5 C5 59 50 CD 1D 46; -2768: A7 C2 AB 71 E1 CD FE 67 D1 2A 64 F8 73 F1 E1 C9 FE 08 28 45 FE 02 28 E1; -2780: FE 80 28 DD D5 C5 59 50 CD 62 44 E1 CD FE 67 D1 2A 64 F8 73 7B FE 04 28; -2798: DC E5 21 AE FC AF BE 77 E1 20 D2 01 06 00 09 E5 36 FF 2A 64 F8 CD 2A 68; -27B0: E1 2B 2B 2B 77 FE FF 20 BC 23 23 23 23 36 80 18 B4 C5 59 50 CD 62 44 E1; -27C8: E5 CD FE 67 2A 64 F8 36 01 01 06 00 09 36 FF 2A 64 F8 E5 CD 2A 68 E1 30; -27E0: F9 36 02 E1 01 21 00 09 0E 04 E5 37 7E 98 77 23 0D 20 F9 E1 0C 30 02 0E; -27F8: 04 CD 13 68 18 C1 01 0C 00 09 70 23 70 23 ED 4B 3D F3 71 23 70 01 11 00; -2810: 09 0E 05 70 23 0D 20 FB C9 DD 21 8B F3 FD 21 00 06 CD 63 66 CD 2A 68 C3; -2828: A0 66 E5 7E FE 01 C2 99 71 5D 54 23 23 23 7E A7 20 2C 23 23 23 34 7E 23; -2840: 23 23 20 1D E5 22 3D F2 EB 23 5E 23 56 21 00 01 CD B2 47 5D 54 25 7D B4; -2858: E1 28 06 E5 19 36 1A E1 AF 4F 06 00 09 7E 47 D6 1A D6 01 78 E1 23 23 23; -2870: 36 00 D0 77 C9 FB E5 3A 48 F3 87 21 08 00 30 02 2E 10 39 36 41 23 36 6E; -2888: E1 23 23 23 71 C9 DD 21 8B F3 FD 21 00 08 CD 63 66 7E FE 02 C2 99 71 F1; -28A0: F5 CD A7 68 C3 9F 66 E5 01 06 00 09 4E 34 23 23 23 09 77 E1 C0 E5 23 5E; -28B8: 23 56 01 04 00 09 7E 23 23 23 22 3D F2 A7 6F 60 20 01 24 CD 8F 71 E1 C9; -28D0: DD 21 8B F3 FD 21 00 04 CD 63 66 E1 7E D6 02 20 13 E5 21 AE FC BE 77 E1; -28E8: 20 0A 36 04 3E 1A CD A7 68 C4 B5 68 E5 23 5E 23 56 CD 6F 45 E1 E5 11 07; -2900: 00 19 72 6A 62 22 64 F8 E1 34 35 72 E1 C9 CD 80 73 E5 DD 21 F7 54 CD 1E; -2918: 73 3E FF CD C7 69 2A 76 F6 22 3D F2 EB 2A C2 F6 A7 ED 52 CD 8B 71 32 7C; -2930: F8 E1 DD 21 24 6B C3 1E 73 DD 21 9A 73 FD 21 00 02 CD 63 66 F1 CA 99 71; -2948: DD 21 1C 6C CD 1E 73 2A 53 F3 E5 CD FE 67 E1 E5 01 13 00 09 7E A7 C2 FD; -2960: 72 2B B6 C2 FD 72 2B 56 2B 5E 2A 76 F6 19 DA FD 72 01 93 00 09 DA FD 72; -2978: ED 72 D2 FD 72 EB E3 EB CD D0 69 2A 76 F6 22 3D F2 E1 2B CD B2 47 ED 5B; -2990: 76 F6 19 22 C2 F6 DD 21 53 42 CD 1E 73 3A 66 F8 A7 C0 32 7C F8 21 B9 69; -29A8: 11 68 F5 01 05 00 D5 ED B0 E1 DD 21 01 46 C3 1E 73 3A 92 00 00 00 E5 7D; -29C0: CD CB 69 E1 7C 18 04 ED 5B 53 F3 01 BE 47 18 03 01 B2 47 F5 21 01 00 39; -29D8: 22 3D F2 D5 CD E2 69 D1 F1 C9 21 01 00 C5 C9 D5 CD 6A 6B ED 53 BF FC D5; -29F0: CD 6A 6B ED 53 7D F8 E3 EB E7 DA 15 73 EB E3 CD; -2A00: DA 72 37 28 16 CD D0 72 2C FE 53 20 06 CD DB 72 A7 18 08 CD 6E 6B ED 53; -2A18: BF FC 37 C1 30 05 04 05 F2 15 73 D1 E5 C5 F5 AF 1E 02 DD 21 FA 6A CD 1E; -2A30: 73 3E FE CD C7 69 F1 E1 E5 F5 CD BE 69 2A 7D F8 CD BE 69 2A BF FC CD BE; -2A48: 69 F1 C1 F5 ED 43 3D F2 2A 7D F8 A7 ED 42 23 F1 30 13 CD 8B 71 3E FF 32; -2A60: AE FC AF DD 21 24 6B CD 1E 73 C3 F8 6E CD 65 71 E5 ED 5B BF FC E7 F5 4D; -2A78: 44 2A 7D F8 E5 09 22 7D F8 E1 ED 5B 3D F2 CD 59 00 F1 30 12 E1 E5 CD 8B; -2A90: 71 2A BF FC D1 A7 ED 52 22 BF FC EB 18 D2 E1 2A BF FC CD 8B 71 18 B6 D5; -2AA8: AF 32 BE FC 4F 47 CD DA 72 28 1D CD D0 72 2C FE 52 28 04 FE 53 20 0C 32; -2AC0: BE FC CD DB 72 28 09 CD D0 72 2C CD 6E 6B 42 4B D1 E5 C5 3E FF 32 AE FC; -2AD8: AF 1E 01 DD 21 FA 6A CD 1E 73 ED 5B 53 F3 CD D0 69 FE FE C2 99 71 C1 CD; -2AF0: 5C 6B E5 CD 5C 6B E5 CD 5C 6B 22 BF FC E1 C1 A7 ED 42 23 ED 43 3D F2 3A; -2B08: BE FC FE 53 28 0C CD B2 47 DD 21 FF 4A CD 1E 73 E1 C9 CD 65 71 E5 ED 5B; -2B20: BF FC E7 F5 ED 5B 53 F3 CD B2 47 F1 C1 C5 F5 2A 7D F8 E5 09 22 7D F8 D1; -2B38: 2A 3D F2 F1 30 10 CD 5C 00 2A BF FC D1 A7 ED 52 22 BF FC EB 18 CF C1 ED; -2B50: 4B BF FC CD 5C 00 AF 32 BE FC 18 B5 C5 CD D0 69 F5 CD D0 69 67 F1 6F C1; -2B68: 09 C9 CD D0 72 2C DD 21 0B 6F C3 1E 73 CD 80 73 CD DB 72 CD D0 72 28 CD; -2B80: C5 6B CD D0 72 29 E5 21 D6 3F 22 F8 F7 E1 3E 03 32 63 F6 A7 18 0B CD 80; -2B98: 73 CD C5 6B CD DA 72 C0 37 F5 E5 D5 59 CD 5D 50 3C CA 9C 71 D1 E1 F1 E5; -2BB0: 3E FF 32 46 F2 DD 7E 00 06 01 DD 4E 01 2A 51 F3 CD 44 01 E1 C9 DD 21 1C; -2BC8: 52 CD 1E 73 D5 CD D0 72 2C DD 21 2F 54 CD 1E 73 C1 C9 DD 21 8B F3 FD 21; -2BE0: 00 04 CD 63 66 7E FE 04 C2 99 71 23 5E 23 56 01 07 00 09 E3 CD DA 72 28; -2BF8: 30 D5 CD D0 72 2C DD 21 64 4C CD 1E 73 E5 CD FB 6D 79 B0 B5 B4 CA 15 73; -2C10: 79 B0 0B 20 01 2B EB E1 E3 E5 D5 11 21 00 19 D1 71 23 70 23 73 23 72 D1; -2C28: E1 E3 22 3D F2 E1 F1 E5 A7 21 03 73 01 B2 47 28 06 21 A8 71 01 BE 47 E5; -2C40: CD E2 69 A7 C0 E1 C3 F8 6E CD 80 73 FE 23 CC DB 72 DD 21 1C 52 CD 1E 73; -2C58: CA 18 73 E5 DD 21 6D 6A CD 1E 73 5D 54 CA 00 73 DA 15 73 7E FE 04 C2 99; -2C70: 71 23 7E 23 66 6F 01 0E 00 09 4E 23 46 ED 43 68 F5 21 00 00 22 6A F5 01; -2C88: 09 00 E1 EB 09 EB 7E FE 2C C0 D5 DD 21 1B 52 CD 1E 73 F5 CD D0 72 41 CD; -2CA0: D0 72 53 DD 21 A4 5E CD 1E 73 DD 21 97 55 CD 1E 73 C2 FA 72 F1 E3 D5 E5; -2CB8: 2A 6A F5 4F 06 00 09 22 6A F5 EB 2A 68 F5 E7 DA 06 73 D1 E1 71 23 73 23; -2CD0: 72 06 00 E1 18 B5 F6 37 CD 80 73 F5 DD 21 A4 5E CD 1E 73 DD 21 97 55 CD; -2CE8: 1E 73 C2 FA 72 D5 DD 21 5F 4C CD 1E 73 C1 E3 E5 C5 DD 21 D0 67 CD 1E 73; -2D00: 46 E3 7E 4F C5 E5 F5 23 5E 23 56 B7 28 5C 2A 62 F8 2B E7 38 33 2A C2 F6; -2D18: E7 38 2D 59 16 00 2A 74 F6 19 EB 2A 9B F6 E7 38 54 F1 79 DD 21 8E 66 CD; -2D30: 1E 73 E1 C1 E3 D5 C5 DD 21 D0 67 CD 1E 73 C1 D1 E3 C5 E5 23 F5 73 23 72; -2D48: F1 E1 23 5E 23 56 C1 E1 23 7E 23 66 6F 79 B8 30 01 47 90 4F F1 D4 74 6D; -2D60: 04 05 28 0B 7E 12 23 13 18 F7 C1 C1 C1 C1 C1 DC 74 6D E1 C9 3E 20 0C 0D; -2D78: C8 12 13 18 FA F1 E1 C1 E3 EB 20 25 C5 78 DD 21 27 66 CD 1E 73 11 98 F6; -2D90: 2A 78 F6 22 F8 F7 3E 03 32 63 F6 CD F3 2E 11 9B F6 E7 22 78 F6 CA F7 72; -2DA8: C1 E3 C5 E5 C3 2A 6D 3E 02 01 3E 04 01 3E 08 CD 80 73 F5 DD 21 7A 51 CD; -2DC0: 1E 73 F1 DD 21 27 66 CD 1E 73 2A 99 F6 CD 10 2F C3 F1 61 00 00 00 00 3E; -2DD8: 01 01 3E 03 01 3E 07 CD 80 73 F5 DD 21 D0 67 CD 1E 73 F1 BE D2 15 73 3C; -2DF0: 23 4E 23 66 69 32 63 F6 C3 08 2F DD 21 97 55 CD 1E 73 ED 4B F8 F7 21 00; -2E08: 00 F8 CA FA 72 21 F6 F7 11 FC F5 01 08 00 ED B0 21 68 6E 11 47 F8 0E 08; -2E20: ED B0 CD 9F 28 A7 CD D1 30 DD 21 32 54 CD 1E 73 D5 EB DD 21 FF 46 CD 1E; -2E38: 73 CD 42 30 01 45 65 11 53 60 CD 5C 32 21 F6 F7 11 47 F8 01 08 00 ED B0; -2E50: 21 FC F5 11 F6 F7 0E 08 ED B0 CD 8C 26 DD 21 32 54 CD 1E 73 4B 42 E1 C9; -2E68: 45 65 53 60 00 00 00 00 CD 80 73 E5 CD 2A 68 21 00 00 30 01 2B F5 CD 99; -2E80: 2F F1 E1 23 23 23 77 C9 CD 80 73 16 00 28 06 CD 80 6F E5 18 04 E5 CD FE; -2E98: 6F CD 63 6F 3A 16 F4 A7 F5 CD 45 66 CA 12 73 DD 21 23 73 CD 1E 73 21 B3; -2EB0: F5 06 0B 7E 23 DF 78 FE 04 20 08 7E FE 20 28 02 3E 2E DF 10 EE CD BD 00; -2EC8: F1 F5 3A B0 F3 47 3A 61 F6 28 05 06 50 3A 15 F4 A7 28 0F C6 0C B8 30 03; -2EE0: 3E 20 DF DD 21 28 73 D4 1E 73 11 68 F5 AF 32 74 F5 CD 06 50 3C 20 B7 F1; -2EF8: E1 DD 21 FF 4A C3 1E 73 CD 80 73 CD 96 6F CD DA 72 C0 CD EA 65 CA A2 71; -2F10: CD 63 6F E5 11 68 F5 CD 6C 43 A7 C2 12 73 E1 C9 CD 80 73 CD 96 6F CD EA; -2F28: 65 CA A2 71 CD 63 6F E5 CD 45 66 CA 12 73 E1 CD D0 72 41 CD D0 72 53 CD; -2F40: 96 6F 7A 32 78 F5 E5 2A 68 F5 A7 28 04 BD C2 B7 71 11 79 F5 CD 5A 66 11; -2F58: 68 F5 CD 92 43 A7 C2 A5 71 E1 C9 CD E3 65 3C 32 68 F5 E5 D5 CD 57 66 D1; -2F70: E1 C9 DD 21 0E 6A CD 1E 73 7A FE 09 D8 C3 9C 71 CD 72 6F E5 21 66 F8 06; -2F88: 0B 7E 23 FE 20 20 0B 10 F8 CD FE 6F 18 04 CD 72 6F E5 21 66 F8 06 08 CD; -2FA0: F5 6F 06 03 CD F5 6F E1 F6 37 D5 E5 11 66 F8 D5 06 0B C5 1A 21 CC 6F 01; -2FB8: 0D 00 38 01 0B ED B1 28 31 C1 13 10 ED E1 CD D9 6F E1 D1 C9 2E 22 2F 5C; -2FD0: 5B 5D 3A 2B 3D 3B 2C 2A 3F 3E 20 BE 28 14 06 07 CD E5 6F 06 03 23 BE 28; -2FE8: 03 10 FA C9 05 C8 23 BE 28 FA C3 0F 73 7E FE 2A 28 09 23 10 F8 C9 21 66; -3000: F8 06 0B 36 3F 23 10 FB C9 01 10 00 11 01 21 00 CD 80 73 C5 DD 21 1F 52; -3018: CD 1E 73 DD 21 6D 6A CD 1E 73 DA 15 73 CA 00 73 C1 23 5E 23 56 EB 09 4E; -3030: 23 46 23 5E 23 56 EB C5 DD 21 FF 46 CD 1E 73 01 45 65 11 53 60 CD 5C 32; -3048: 21 F6 F7 11 47 F8 01 08 00 ED B0 E1 DD 21 FF 46 CD 1E 73 CD 42 30 C3 9A; -3060: 26 CD 80 73 DD 21 1F 52 CD 1E 73 21 47 F3 BE 28 03 D2 9C 71 5F CD 5D 50; -3078: C3 99 2F CD 80 73 CD 80 6F CD EA 65 CA A2 71 CD 63 6F E5 3A 47 F2 3C 32; -3090: 8D F5 21 69 F5 11 8E F5 01 24 00 ED B0 E1 CD DA 72 28 20 CD D0 72 D9 CD; -30A8: 80 6F CD EA 65 CA A2 71 CD E3 65 3C 32 8D F5 E5 11 8E F5 CD 5A 66 E1 CD; -30C0: DA 72 C0 E5 CD 45 66 CA 12 73 CD BD 00 01 8D F5 11 D7 F5 21 B2 F5 3E 0C; -30D8: F5 0A FE 3F 20 01 7E 12 03 13 23 F1 3D 20 F1 21 B2 F5 11 D7 F5 06 0C 1A; -30F0: BE 20 07 23 13 10 F8 C3 15 73 CD 6C 71 E5 AF 32; -3100: BE F5 11 B2 F5 CD 62 44 11 D7 F5 CD 1D 46 A7 C2 AB 71 6F 67 22 D3 F5 22; -3118: D5 F5 22 F8 F5 22 FA F5 23 22 C0 F5 22 E5 F5 E1 E5 11 B2 F5 CD B2 47 7D; -3130: B4 28 09 11 D7 F5 CD 8F 71 E1 18 EC E1 2A C6 F5 22 EB F5 2A C8 F5 22 ED; -3148: F5 11 D7 F5 CD 6F 45 21 B2 F5 22 3D F2 11 68 F5 AF 32 74 F5 CD 06 50 3C; -3160: C2 CA 70 E1 C9 22 BF FC ED 43 7D F8 21 00 FE 39 30 0D ED 5B C6 F6 A7 ED; -3178: 52 38 04 7C A7 20 07 ED 5B 62 F8 21 00 01 ED 53 3D F2 C9 ED 5B 53 F3 CD; -3190: BE 47 A7 C8 18 12 1E 3C 01 1E 3D 01 1E 3E 01 1E 3F 01 1E 40 01 1E 41 01; -31A8: 1E 42 01 1E 43 01 1E 44 01 1E 45 01 1E 46 01 1E 47 01 00 00 AF 32 7C F8; -31C0: 32 AE FC D5 DD 21 24 6B CD 1E 73 D1 DD 21 6F 40 C3 1E 73 7B FE 3C D8 FE; -31D8: 48 D0 D6 3B 47 21 F5 71 7E A7 23 20 FB 10 F9 2B 11 04 F6 D5 01 16 00 ED; -31F0: B0 1E 01 E1 C9 00 42 61 64 20 46 41 54 00 42 61 64 20 66 69 6C 65 20 6D; -3208: 6F 64 65 00 42 61 64 20 64 72 69 76 65 20 6E 61 6D 65 00 42 61 64 20 73; -3220: 65 63 74 6F 72 20 6E 75 6D 62 65 72 00 46 69 6C 65 20 73 74 69 6C 6C 20; -3238: 6F 70 65 6E 00 46 69 6C 65 20 61 6C 72 65 61 64 79 20 65 78 69 73 74 73; -3250: 00 44 69 73 6B 20 66 75 6C 6C 00 54 6F 6F 20 6D 61 6E 79 20 66 69 6C 65; -3268: 73 00 44 69 73 6B 20 77 72 69 74 65 20 70 72 6F 74 65 63 74 65 64 00 44; -3280: 69 73 6B 20 49 2F 4F 20 65 72 72 6F 72 00 44 69 73 6B 20 6F 66 66 6C 69; -3298: 6E 65 00 52 65 6E 61 6D 65 20 61 63 72 6F 73 73 20 64 69 73 6B 00 B0 72; -32B0: CB 79 C2 96 71 CB 81 06 00 21 C2 72 09 7E 23 66 6F E9 AE 71 B4 71 B1 71; -32C8: B1 71 B1 71 B1 71 B1 71 CD DA 72 E3 BE 20 41 23 E3 23 2B DD 21 66 46 18; -32E0: 3D 00 00 00 3E C9 32 D5 FE ED 5B 4A FC ED 53 49 F3 C9 F7 00 E4 72 C9 1E; -32F8: 10 01 1E 0D 01 1E 07 01 1E 3B 01 1E 37 01 1E 32 01 1E 36 01 1E 34 01 1E; -3310: 38 01 1E 35 01 1E 05 01 1E 02 DD 21 6F 40 CD 59 01 FB C9 FB E5 D5 3A 48; -3328: F3 87 21 10 00 30 02 2E 18 39 5E 23 56 E5 21 95 6E E7 E1 28 0D E5 21 C9; -3340: 6E E7 E1 20 0B 11 77 F3 18 03 11 7A F3 72 2B 73 D1 E1 7B FE 02 D8 7E FE; -3358: 3A 28 B4 23 7E FE 3A 2B C0 CD 80 73 7E E6 DF D6 40 E5 21 47 F3 BE E1 28; -3370: 03 D2 9C 71 23 23 1D 1D D5 1C D1 C9 FB 3E 00 C9 FB E5 F5 3A 48 F3 87 21; -3388: 0C 00 30 02 2E 14 39 36 8B 23 36 F3 F1 E1 C9 CD 6B F3 1A CD 68 F3 13 FE; -33A0: 24 C8 CD A8 53 18 F0 CD 6B F3 ED B0 CD 68 F3 C9 CD 6B F3 C3 00 00 11 DE; -33B8: F1 D5 5E 23 56 EB CD 6B F3 E9 C3 04 56 50 52 4E 20 4C 53 54 20 4E 55 4C; -33D0: 20 41 55 58 20 43 4F 4E 20 20 20 20 20 20 20 20 20 20 20 20 80 00 00 00; -33E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1F 1C 1F 1E 1F 1E 1F; -3400: 1F 1E 1F 1E 1F F8 00 02 0F 04 01 02 01 00 02 70 0C 00 63 01 02 05 00 F9; -3418: 00 02 0F 04 01 02 01 00 02 70 0E 00 CA 02 03 07 00 FA 00 02 0F 04 01 02; -3430: 01 00 02 70 0A 00 3C 01 01 03 00 FB 00 02 0F 04 01 02 01 00 02 70 0C 00; -3448: 7B 02 02 05 00 FB D2 CE 75 F5 3A 0D F3 B7 18 1A F1 F5 C5 D5 E5 CD 98 74; -3460: E1 D1 C1 38 09 CD 2C 78 F1 CD 66 75 18 08 FD E1 18 04 F1 CD 98 74 FB CD; -3478: D4 FF F5 0E 32 30 02 0E 00 CD 2C 78 DD 36 00 96 DD 7E 03 A7 20 05 DD 71; -3490: 01 F1 C9 DD 71 02 F1 C9 CD D6 76 D8 CD CF FF F3 CB 7C 20 29 CD 92 7D CD; -34A8: 2D 7D D8 04 05 C8 CD CF FF F3 CB 7C 20 17 E5 D5 C5 ED 5B 4D F3 D5 01 00; -34C0: 02 CD 6E F3 E1 C1 D1 CD D8 74 E1 18 03 CD D8 74 D8 05 C8 CD A1 77 18 C8; -34D8: 1E 0B CD F4 77 3E A0 CB 72 28 08 F6 02 CB 42 28 02 F6 08 E5 D5 C5 11 04; -34F0: 75 D5 01 FF 7F 32 F8 7F 0A 87 F0 38 FB 7E 32 FB 7F 23 18 F4 C1 D1 E1 3A; -3508: F8 7F E6 FC 20 0D CB 7C 20 51 05 28 4E CD A1 77 C3 00 00 CB 77 20 26 F5; -3520: CD DB 77 F1 1D 20 B3 37 5F CB 7B 3E 02 20 34 CB 6B 3E 0A 20 2E CB 63 3E; -3538: 08 20 28 CB 5B 3E 04 20 22 3E 0C 18 1E 3E 80 32 F8 7F 21 FF 7F 11 00 00; -3550: 7E 07 38 0D 07 30 0A 1B 7B B2 20 F4 3E 02 37 18 02 AF 37 C9 00 00 CD D6; -3568: 76 D8 CD CF FF F3 CB 7C 20 4F CD AA 7D 1E 80 CD 2D 7D D8 04 05 C8 CD CF; -3580: FF F3 CB 7C 20 3B E5 D5 C5 ED 5B 4D F3 15 15 01 00 02 CD 6E F3 C1 D1 D5; -3598: C5 2A 4D F3 1E 0B CD 1F 76 38 18 2A 4D F3 54 5D 15 15 01 00 02 1A ED A1; -35B0: 20 06 13 EA AD 75 18 03 3E 0A 37 C1 D1 E1 D8 18 06 1E 80 CD 1F 76 D8 05; -35C8: C8 CD A1 77 18 A0 CD D4 75 C3 76 74 CD D6 76 D8 CD CF FF F3 CB 7C 20 32; -35E0: CD CD 7D 1E 0B CD 2D 7D D8 04 05 C8 CD CF FF F3 CB 7C 20 1E E5 2A 4D F3; -35F8: 1E 0B CD 1F 76 E1 D8 E5 D5 C5 EB 2A 4D F3 01 00 02 CD 6E F3 C1 D1 E1 A7; -3610: 18 06 1E 0B CD 1F 76 D8 05 C8 CD A1 77 18 BD CD F4 77 3E 80 CB 72 28 08; -3628: F6 02 CB 42 28 02 F6 08 E5 D5 C5 01 6E 76 C5 01 FF 7F CB 7B 20 68 32 F8; -3640: 7F 11 00 5D 0A 87 30 1B F0 1D 20 F8 0A 87 30 13 F0 15 20 F0 C1 C1 D1 E1; -3658: 3E 02 37 C3 A3 76 0A 87 F0 38 FB 3A FB 7F 77 23 18 F4 00 00 00 00 C1 D1; -3670: E1 3A F8 7F E6 9C 20 0D CB 7C 20 27 05 28 24 CD A1 77 C3 00 00 F5 CD DB; -3688: 77 F1 1D 20 92 37 5F CB 7B 3E 02 20 0E CB 63 3E 08 20 08 CB 5B 3E 04 20; -36A0: 02 3E 0C C9 00 00 32 F8 7F 11 00 5D 0A 87 30 1B F0 1D 20 F8 0A 87 30 13; -36B8: F0 15 20 F0 C1 C1 D1 E1 3E 02 37 C3 A3 76 0A 87 F0 38 FB 3A FB 7F BE 23; -36D0: 28 F4 3E 0A 18 EA F5 C5 E5 CD C2 5F E1 C1 F1 FE 02 38 04 3E 0C 37 C9 F5; -36E8: 79 FE F8 38 04 FE FC 38 03 F1 18 EF E3 E5 C5 CD F4 77 CB 49 4B 42 11 08; -3700: 00 20 01 1C CD 2F 49 7D 3C 32 FA 7F 69 C1 F1 67 AF CB 41 28 05 CB 3D 30; -3718: 01 3C 32 FC 7F 57 DD 7E 07 3D 28 01 7C F6 C4 F5 79 0F 0F E6 C0 B2 57 4D; -3730: DD 7E 07 3D 28 23 DD 7E 03 BC 28 34 EE 01 DD 77 03 3A F9 7F 28 08 DD 77; -3748: 04 DD 7E 05 18 06 DD 77 05 DD 7E 04 32 F9 7F 18 17 DD 7E 06 BC DD 74 06; -3760: 28 0E DD E5 D5 C5 CD 22 78 CD 5A 62 C1 D1 DD E1 F1 C5 F5 F3 DD 7E 00 47; -3778: F1 32 FD 7F DD 36 00 FF FB 3A F9 7F B9 C4 E1 77 78 A7 20 07 06 64 CD 96; -3790: 77 10 FB C1 E1 C9 E5 21 A6 04 2B 7C B5 20 FB E1 C9 CD F4 77 24 24 3A FA; -37A8: 7F 3C 32 FA 7F CB 7A 20 03 FE 0A D8 FE 09 D8 3E 01 32 FA 7F CB 72 28 0B; -37C0: CB 42 20 07 CB C2 32 FC 7F 18 0F CB 82 AF 32 FC 7F 0C CD F4 77 3E 50 32; -37D8: F8 7F C9 CB 43 C0 CD FB 77 CD F4 77 79 B7 28 1A 32 FB 7F E3 E3 3E 10 32; -37F0: F8 7F 18 16 3A F8 7F 1F 38 FA C9 3A F9 7F B7 CC; -3800: 15 78 CD F4 77 3E 00 32 F8 7F E5 21 C3 09 2B 7C B5 20 FB E1 C9 C5 0E 04; -3818: CD E1 77 C1 C9 CD 2C 78 18 04 DD 36 00 00 3E 03 32 FD 7F C9 3E D0 32 F8; -3830: 7F E3 E3 E3 E3 3A FB 7F 3A F8 7F C9 C5 F5 CD C2 5F F1 F5 28 17 3E C5 32; -3848: FD 7F CD FB 77 21 CA 76 3A F8 7F E6 04 20 09 2B 7C B5 20 F4 2E 01 18 05; -3860: 2E 02 CD 7A 78 3E C4 32 FD 7F CD 7A 78 DD 75 07 CD 26 78 F1 28 02 2E 02; -3878: C1 C9 D5 CB AA CD FB 77 CD FB 77 CD FB 77 D1 C9 CD C2 5F 06 07 AF 77 23; -3890: 10 FC 21 98 78 C3 F6 5F F5 CD C2 5F 7E A7 28 08 FE FF 28 07 3D 77 20 03; -38A8: CD 26 78 23 7E A7 28 01 35 23 7E A7 28 01 35 F1 C3 27 60 FB E5 C5 F5 CD; -38C0: C2 5F F1 C1 E1 A7 DD 46 02 20 03 DD 46 01 04 05 06 01 C0 C5 E5 11 01 00; -38D8: 2A 4D F3 F5 CD 4D 74 38 18 F1 2A 4D F3 46 E1 C5 CD FD 78 3E 0A 38 0B F1; -38F0: C1 B9 37 3F 06 FF C0 04 C9 D1 D1 D1 C9 EB 13 78 D6 F8 D8 FE 04 30 14 07; -3908: 4F 06 00 6F 60 29 29 29 09 01 05 74 09 01 12 00 ED B0 C9 3E 0A 37 C9 00; -3920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0D 0A 31 20 2D 20 53; -3938: 69 6E 67 6C 65 20 73 69 64 65 64 2C 20 38 30 20 74 72 61 63 6B 73 0D 0A; -3950: 32 20 2D 20 44 6F 75 62 6C 65 20 73 69 64 65 64 2C 20 38 30 20 74 72 61; -3968: 63 6B 73 0D 0A 00 21 31 79 C9 00 00 00 00 00 00 00 00 00 00 00 00 00 00; -3980: 00 00 E5 21 A8 E4 09 E1 38 13 37 3E 0E C9 E1 37 3E 0C C9 D1 C1 E1 C3 76; -3998: 74 C1 C3 76 74 F5 E5 CD C2 5F E1 F1 B7 28 E8 FE 03 30 E4 3D 28 11 01 F9; -39B0: 50 18 0F 00 00 00 00 00 00 00 00 00 00 00 00 01 F8 50 E5 CB 41 28 42 C5; -39C8: D5 7A 11 00 00 C5 CD D6 76 C1 CB B9 CD 4E 7A CD D8 7B 38 B7 D1 D5 7A 11; -39E0: 09 00 C5 CD D6 76 C1 CB F9 CD 4E 7A CD D8 7B 38 A2 CD 2C 78 2A 4D F3 01; -39F8: F9 01 D1 7A D5 11 00 00 B7 CD 4D 74 D1 C1 DA 8E 79 E1 C5 7A F5 11 00 00; -3A10: CD D6 76 F1 C1 CD AD 7A F5 CB B9 CD 4E 7A CD D8 7B DA 99 79 CB 41 28 0E; -3A28: CD 4E 7A CB F9 CD 8E 7A CD D8 7B DA 99 79 CB AA CD D2 77 10 DC CD FB 77; -3A40: CB F9 F1 C3 C0 7A 79 07 E6 01 32 FC 7F C9 C5 E5 EB 21 AC 7B CD 79 7B 06; -3A58: 09 C5 21 B7 7B CD 79 7B C1 10 F6 E1 E5 01 8A 00 09 11 74 02 06 09 3A F9; -3A70: 7F 77 19 10 FC 01 8C 00 E1 E5 09 E5 FD E1 21 A4 7A 06 09 7E FD 77 00 FD; -3A88: 19 23 10 F7 E1 C1 C5 E5 11 8B 00 19 11 74 02 06 09 79 07 E6 01 77 19 10; -3AA0: FC E1 C1 C9 01 02 03 04 05 06 07 08 09 E5 C5 11 8E 16 19 54 5D 13 36 4E; -3AB8: 01 FF 03 ED B0 C1 E1 C9 CD 65 7B C5 21 37 7E ED 5B 4D F3 01 C4 00 ED B0; -3AD0: C1 CD 86 7B C5 06 01 11 00 00 67 E5 2A 4D F3 37 CD 4D 74 E1 C1 D8 CD 1C; -3AE8: 7B D8 3E 09 93 47 C5 D5 06 01 7C E5 2A 4D F3 37 CD 4D 74 E1 D1 13 C1 D8; -3B00: 10 EC CB 41 C8 06 05 C5 D5 7C E5 2A 4D F3 06 01 37 CD 4D 74 E1 D1 13 C1; -3B18: D8 10 EC C9 06 02 11 01 00 CD 65 7B C5 D5 7C E5 2A 4D F3 71 23 36 FF 23; -3B30: 36 FF 06 01 2B 2B 37 CD 4D 74 E1 CD 65 7B D1 13 C1 D8 C5 06 01 CB 41 28; -3B48: 01 04 C5 06 01 D5 7C E5 2A 4D F3 37 CD 4D 74 E1 D1 13 C1 38 06 10 EB C1; -3B60: 10 C2 C9 C1 C9 C5 D5 E5 2A 4D F3 54 5D 13 01 FF 01 36 00 ED B0 E1 D1 C1; -3B78: C9 7E 23 FE FF C8 46 23 12 13 10 FC 18 F3 CB 41 C8 C5 11 9C 7B 2A 4D F3; -3B90: 01 0D 00 09 EB 01 10 00 ED B0 C1 C9 02 01 00 02 70 00 A0 05 F9 03 00 09; -3BA8: 00 02 00 00 4E 50 00 0C F6 03 FC 01 4E 1A FF 00 0C F5 03 FE 01 00 01 00; -3BC0: 01 01 01 02 01 F7 01 4E 18 00 0C F5 03 FB 01 E5 00 E5 00 F7 01 4E 36 FF; -3BD8: CD 46 7A 1E 0B C5 D5 E5 CD F4 77 CD 0A 78 CD CF FF F3 11 1D 7C D5 01 FF; -3BF0: 7F 11 00 00 3E F0 32 F8 7F 0A 87 30 19 F0 1D 20 F8 0A 87 30 11 F0 15 20; -3C08: F0 C1 3E 10 37 E1 D1 C1 C9 0A 87 F0 38 FB 7E 32 FB 7F 23 18 F4 E1 D1 C1; -3C20: 3A F8 7F E6 FC 28 1B CB 77 C2 45 75 F5 3A F9 7F 4F CD DB 77 F1 1D 20 A5; -3C38: 37 5F CB 7B 3E 10 C0 C3 2F 75 3A 0D F3 B7 C8 E5 D5 C5 16 00 79 E6 01 0F; -3C50: 0F B2 57 CD 46 7A B2 57 06 09 3A F9 7F 4F 3E 01 32 FA 7F CD D8 75 C1 D1; -3C68: E1 C9 37 C9 61 00 40 01 75 00 8B 00 A7 00 27 01 9C 00 ED 00 9F 00 26 00; -3C80: EA 00 3C 00 ED 00 40 01 1E 01 40 01 2A 01 47 01 2D 01 40 01 4E 01 40 01; -3C98: 4B 01 61 01 64 01 2D 01 00 00 7C 00 79 00 85 00 8E 00 CE 00 D1 00 F2 00; -3CB0: F6 00 05 01 12 01 1A 01 23 01 34 01 3B 01 40 01 53 01 47 01 00 00 5F 00; -3CC8: 39 01 73 00 AE 00 C6 00 20 01 BF 00 E6 00 C2 00 26 00 E3 00 3C 00 9B 00; -3CE0: E3 00 E6 00 39 01 17 01 39 01 23 01 40 01 26 01 39 01 47 01 39 01 44 01; -3CF8: 5A 01 5D 01 26 01 00 00 77 00 7E 00 A3 00 B1 00 EB 00 EF 00 FE 00 0B 01; -3D10: 13 01 1C 01 2D 01 34 01 39 01 4C 01 40 01 00 00 ED 5B 4D F3 21 33 7D 01; -3D28: 5F 00 ED B0 C9 E5 2A 4D F3 E3 C9 E5 D5 C5 CD 2D 40 2A 4D F3 11 50 00 19; -3D40: 77 26 80 CD 24 00 FB CD D4 FF 3A 42 F3 26 40 CD 24 00 C1 D1 E1 CD CF FF; -3D58: F3 2B 7C C6 02 23 07 3F 30 0D FD 2A 4D F3 D5 11 5F 00 FD 19 D1 FD E9 E5; -3D70: D5 C5 F5 3A 43 F3 26 80 CD 24 00 CD 68 F3 FB CD D4 FF 3E 00 26 40 CD 24; -3D88: 00 FB CD D4 FF F1 C1 D1 E1 C9 E5 D5 C5 CD 20 7D FD 21 6C 7C 21 D8 74 01; -3DA0: 8E 00 ED B0 D5 11 EA 00 18 39 E5 D5 C5 CD CD 7D 2A 4D F3 01 A6 00 09 11; -3DB8: CE 76 EB 01 08 00 ED B0 2A 4D F3 01 7D 00 09 36 00 C1 D1 E1 C9 E5 D5 C5; -3DD0: CD 20 7D FD 21 C6 7C 21 1F 76 01 87 00 ED B0 D5 11 E3 00 2A 4D F3 19 36; -3DE8: C3 D1 21 A1 77 01 7C 00 ED B0 FD 5E 00 FD 56 01 7A B3 28 31 2A 4D F3 19; -3E00: 23 E5 FD 5E 02 FD 56 03 2A 4D F3 19 EB E1 73 23 72 FD 23 FD 23 FD 23 FD; -3E18: 23 18 D7 FD 5E 00 FD 56 01 7A B3 28 0E 2A 4D F3 19 23 23 36 BF FD 23 FD; -3E30: 23 18 E8 C1 D1 E1 C9 EB FE 90 56 47 20 38 32 34 35 20 00 02 02 01 00 02; -3E48: 70 00 D0 02 F8 02 00 09 00 01 00 00 00 D0 ED 53 59 C0 32 C4 C0 36 56 23; -3E60: 36 C0 31 1F F5 11 79 C0 0E 0F CD 7D F3 3C CA 63 C0 11 00 01 0E 1A CD 7D; -3E78: F3 21 01 00 22 87 C0 21 00 3F 11 79 C0 0E 27 CD 7D F3 C3 00 01 58 C0 CD; -3E90: 00 00 79 E6 FE FE 02 C2 6A C0 3A C4 C0 A7 CA 22 40 11 9E C0 0E 09 CD 7D; -3EA8: F3 0E 07 CD 7D F3 18 B2 00 4D 53 58 44 4F 53 20 20 53 59 53 00 00 00 00; -3EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 42 6F 6F; -3ED8: 74 20 65 72 72 6F 72 0D 0A 50 72 65 73 73 20 61 6E 79 20 6B 65 79 20 66; -3EF0: 6F 72 20 72 65 74 72 79 0D 0A 24 00 76 20 31 2E; -3F00: 30 35 1A FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; -3F18: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; -3F30: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; -3F48: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; -3F60: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; -3F78: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; -3F90: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; -3FA8: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; -3FC0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; -3FD8: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; -3FF0: FF FF FF FF FF FF FF FF 24 00 06 00 B2 F0 B2 E2; -END; +-- http://srecord.sourceforge.net/ +-- +-- Generated automatically by srec_cat -o --mif +-- +DEPTH = 16384; +WIDTH = 8; +ADDRESS_RADIX = HEX; +DATA_RADIX = HEX; +CONTENT BEGIN +0000: 41 42 6F 57 76 65 00 00 00 00 00 00 00 00 00 00 C3 4D 74 C3 BB 78 C3 FD; +0018: 78 C3 6E 79 C3 82 79 C3 22 78 C3 3A 5B 37 C3 B1 60 C3 0D 62 00 C3 B3 5F; +0030: 2A 4B F3 C9 DD E5 DD 21 B7 00 CD AB 40 DD E1 30 0A 3E 03 32 36 F3 32 37; +0048: F3 A7 C9 3A 36 F3 A7 3A 37 F3 C0 DD E5 DD 21 9C 00 CD AB 40 DD E1 C8 3E; +0060: FF 32 36 F3 DD E5 DD 21 9F 00 CD AB 40 DD E1 32 37 F3 C5 06 00 04 C1 C9; +0078: E5 21 36 F3 AF BE 77 23 7E E1 C0 DD E5 DD 21 9F 00 CD AB 40 DD E1 C9 DD; +0090: E5 DD 21 A2 00 CD AB 40 DD E1 C9 DD E5 DD 21 A5 00 CD AB 40 DD E1 C9 DD; +00A8: 21 9B 40 FD E5 FD 2A C0 FC CD 1C 00 FB FD E1 C9 3E 0D D3 B4 3E 0A D3 B5; +00C0: AF D3 B4 06 0F DB B5 E6 0F A8 D3 B5 4F 00 DB B5 E6 0F B9 C0 A8 D3 B5 10; +00D8: EC 3E FF 32 38 F3 3E 0D D3 B4 3E 09 D3 B5 3E 0A D3 B4 3E 01 D3 B5 3E 0D; +00F0: D3 B4 AF D3 B5 01 00 0D 79 D3 B4 DB B5 F5 0C 10 F7 3E 0E D3 B4 AF D3 B5; +0108: 06 0D 0D 79 D3 B4 F1 D3 B5 10 F7 18 39 22 3B F3 3A 38 F3 A7 C8 3A 4A F2; +0120: 47 3A 49 F2 4F 3A 48 F2 57 1E 07 CD 59 41 18 12 3A 38 F3 A7 C8 1E 00 CD; +0138: 59 41 3E 0F D3 B4 3E 02 D3 B5 62 CD 60 41 61 CD 60 41 60 CD 60 41 3E 0D; +0150: D3 B4 DB B5 F6 08 D3 B5 C9 CD 4E 41 E6 04 18 F6 AF 2E 08 CB 04 8F 27 2D; +0168: 20 F9 CD 71 41 0F 0F 0F 0F F5 7B 1C D3 B4 F1 18 DD 3A 38 F3 A7 47 4F 57; +0180: 5F 2A 3B F3 C8 CD 59 41 1E 0D CD AD 41 CD 23 55 CD AD 41 32 49 F2 CD AD; +0198: 41 32 48 F2 1D CD AD 41 47 CD AD 41 4F CD AD 41 CD 4E 41 37 C9 AF CD B5; +01B0: 41 87 87 82 87 57 1D 7B D3 B4 DB B5 E6 0F 82 57 C9 20 4D 53 58 2D 44 4F; +01C8: 53 20 76 65 72 2E 20 32 2E 32 20 43 6F 70 79 72 69 67 68 74 20 31 39 38; +01E0: 34 20 62 79 20 4D 69 63 72 6F 73 6F 66 74 20 06 00 3E 22 C9 DD 5E 13 DD; +01F8: 56 14 CD 52 F2 D5 5D 54 CB 3C CB 1D 1F 19 D1 19 17 7E 23 66 30 0C CB 3C; +0210: 1F CB 3C 1F CB 3C 1F CB 3C 1F 6F 7C E6 0F 67 B5 C9 D5 5D 54 CB 3C CB 1D; +0228: 1F 19 D1 19 17 30 18 CB 21 CB 10 CB 21 CB 10 CB 21 CB 10 CB 21 CB 10 7E; +0240: E6 0F B1 77 23 70 C9 71 23 7E E6 F0 B0 77 C9 11 B9 F2 1A BE 23 13 C0 10; +0258: F9 C9 CD 55 F2 21 F7 F1 0E 05 06 04 CD 4F 42 20 2F 06 04 1A 13 FE 20 20; +0270: 32 10 F8 79 ED 44 32 16 F2 21 B9 F2 11 0B F2 01 04 00 ED B0 CD 96 54 ED; +0288: 43 23 F2 ED 53 21 F2 21 0B F2 E5 FD E1 F6 01 C9 05 7D 80 6F 7C CE 00 67; +02A0: 0D 20 BF 37 C9 D5 21 0E 00 19 36 00 CD B1 42 D1 C9 CD 0E 44 D8 CD 5A 42; +02B8: D0 CD D3 44 CD 58 F2 CD 0E 43 D8 7E B7 28 35 FE E5 28 31 E5 06 0B 11 B9; +02D0: F2 CD 52 42 28 06 FE 3F 20 1B 10 F5 E1 E5 FD E1 3A C4 F2 EE 80 CB 7F C8; +02E8: FD 7E 0B E6 1E C8 3A DC F2 B7 C0 18 01 E1 CD 48 43 30 C8 C9 3A FE F2 3C; +0300: 20 06 3A B8 F2 32 FE F2 7E B7 20 EA 37 C9 3A B8 F2 3C DD BE 0B 30 50 CD; +0318: 5B F2 32 B8 F2 4F DD A6 04 6F 26 00 29 29 29 29 29 ED 5B 51 F3 19 DD 46; +0330: 05 CB 39 10 FC 3A 45 F2 B9 20 07 3A 46 F2 DD BE 00 C8 E5 CD A4 46 E1 C9; +0348: CD 5E F2 3A B8 F2 3C DD BE 0B 30 13 32 B8 F2 11 20 00 19 DD A6 04 C0 0C; +0360: CD A4 46 2A 51 F3 C9 CD 43 47 37 C9 CD 0E 44 D4 B5 42 3E FF D8 C0 3E E5; +0378: 32 3C F2 77 FD 6E 1A FD 66 1B 7C B5 C4 9B 4F CD BC 42 30 EA CD 03 44 C3; +0390: CF 45 CD 0E 44 38 74 11 05 00 19 11 C5 F2 CD F4 F1 D4 B5 42 38 65 20 63; +03A8: 21 B9 F2 11 D0 F2 01 0C 00 ED B0 21 C5 F2 11 B9 F2 06 0B 7E FE 3F 20 03; +03C0: FD 7E 00 12 23 13 FD 23 10 F1 3E 80 12 CD 5A 42 30 36 3A B8 F2 F5 3E FF; +03D8: 32 B8 F2 CD BC 42 C1 30 27 78 CD 17 43 EB 21 B9 F2 01 0B 00 ED B0 3E FF; +03F0: 32 3C F2 21 D0 F2 11 B9 F2 01 0C 00 ED B0 CD BC 42 30 B0 CD 43 47 AF C9; +0408: CD 43 47 3E FF C9 CD 61 F2 AF 32 DC F2 EB 7E 23 32 C4 F2 E6 0F CD 27 44; +0420: D8 11 B9 F2 C3 F4 F1 4F 3A 47 F3 B9 D8 79 3D F2 35 44 3A 47 F2 32 E1 F2; +0438: C9 FD 7E 1F B7 20 1F FD 7E 1C FD 4E 1D FD 46 1E 87 CB 11 CB 10 38 0F B7; +0450: 28 05 03 78 B1 28 07 79 CB B9 87 CB 10 D0 01 7F FF C9 CD A5 42 38 A4 CD; +0468: 39 44 3A 0C F3 04 B8 30 9A CD 64 F2 EB 01 0F 00 09 CD 39 44 3A 0C F3 B8; +0480: 28 06 0E 80 38 02 0E 00 71 23 EB 01 1C 00 09 0E 04 ED B0 01 F8 FF 09 ED; +0498: A0 ED A0 0E FC 09 ED A0 ED A0 FD 7E 0B CB 7F 20 05 DD 7E 00 F6 40 12 13; +04B0: 3A B8 F2 12 13 FD 7E 1A 12 13 13 12 1B FD 7E 1B 12 13 13 12 13 AF 12 13; +04C8: 12 C9 4F 3A E1 F2 CD 0A 47 18 08 3E FF 32 B8 F2 32 FE F2 CD 67 F2 CD 53; +04E0: 45 3A E1 F2 DD 4E 01 06 00 B7 CD 67 60 38 DB CD 33 45 DD 6E 13 DD 66 14; +04F8: 2B 78 B6 3A E1 F2 2A 41 F2 FA 0A 45 C0 BD 20 0B 25 C8 95 20 06 6F 67 2D; +0510: 22 41 F2 3E FF 32 46 F2 CD FA 45 2B 36 00 23 F5 CD D7 46 38 19 F1 46 3A; +0528: E1 F2 DD 4E 01 DD E5 E1 CD 6F 60 E5 DD E1 EB CD 61 45 73 23 72 C9 7B 81; +0540: 5F 30 01 14 F1 41 3D 20 D6 CD FA 45 E5 CD C5 46 E1 18 D3 CD 6A F2 CD 61; +0558: 45 7E 23 66 6F E5 DD E1 C9 3A E1 F2 21 55 F3 87 85 6F D0 24 C9 00 00 D5; +0570: FD E1 CD 0E 44 3E FF D8 FD 7E 18 E6 C0 3E 00 C0 3A E1 F2 2A 41 F2 BD CC; +0588: 2D 47 CD 53 45 FD 7E 19 CD 17 43 06 0B CD 4F 42 20 54 FD E5 D1 0E 0B 09; +05A0: EB 0E 16 09 ED A0 ED A0 01 FC FF 09 ED A0 ED A0 01 04 00 09 ED A0 ED A0; +05B8: 01 F4 FF 09 01 04 00 ED B0 CD 48 47 DD 6E 13 DD 66 14 2B 7E FE 01 C0 CD; +05D0: 6D F2 CD FA 45 2B 36 00 23 F5 D5 C5 E5 CD 55 47 E1 C1 D1 7B 80 5F 30 01; +05E8: 14 F1 3D 20 EC C9 DD 6E 13 DD 66 14 2B 36 00 3E FF C9 DD 7E 0A DD 6E 13; +0600: DD 66 14 DD 46 10 DD 5E 08 DD 56 09 C9 DD 86 11 5F DD 56 12 30 01 14 2A; +0618: 51 F3 06 01 C9 D5 CD 0E 44 38 2A 23 23 36 00 21 B9 F2 3E 3F 01 0B 00 ED; +0630: B1 28 1A CD B5 42 30 19 3A FE F2 FE FF 28 0E CD 17 43 E5 FD E1 18 22 FD; +0648: CB 0B 7E 20 50 D1 3E FF C9 20 F4 3A 0C F3 B7 20 44 FD 6E 1A FD 66 1B 7C; +0660: B5 28 06 CD 9B 4F CD CF 45 FD E5 D1 21 B9 F2 01 0B 00 ED B0 7E 17 3E 00; +0678: 30 02 3E 06 12 13 EB 06 0A AF 77 23 10 FC E5 CD 96 54 E1 73 23 72 23 71; +0690: 23 70 23 AF 06 06 77 23 10 FC CD 48 47 FD E5 E1 D1 C3 71 44 C5 CD 43 47; +06A8: C1 DD 46 00 ED 43 45 F2 C5 79 CD 0D 46 CD C5 46 C1 C9 44 7D 32 E1 F2 CD; +06C0: 53 45 2A 3D F2 CD 70 F2 AF 32 FF F2 CD D7 46 D0 CD E8 46 3D 28 EF C9 DD; +06D8: 7E 00 DD 4E 01 E5 D5 C5 CD 52 60 D1 4A D1 E1 C9 F5 79 90 4F C5 06 00 EB; +06F0: 09 E5 D5 DD 5E 02 DD 56 03 CD 16 49 E1 D1 09 C1; +0700: F1 4F 3A FF F2 B1 4F DD 7E 00 CD 73 F2 C5 D5 E5 2A 23 F3 CD E8 F1 79 E1; +0718: D1 C1 FE 02 C0 C3 E2 F1 44 7D 32 E1 F2 CD 53 45 2A 3D F2 18 28 21 42 F2; +0730: AF BE 77 C8 DD 2A 43 F2 2A 4F F3 06 01 ED 5B 3F F2 18 12 3A 3C F2 B7 C8; +0748: CD 76 F2 AF 32 3C F2 3A 45 F2 CD 0D 46 CD 79 F2 3E 01 32 FF F2 DD 7E 00; +0760: DD 4E 01 E5 D5 C5 CD 54 60 D1 4A D1 E1 D0 CD E8 46 3D 28 E1 C9 CD F8 4E; +0778: CD 23 4B 18 06 CD F8 4E CD A3 4C CD 6A 48 18 14 CD 57 48 CD 23 4B 18 09; +0790: FD E5 D1 CD 57 48 CD A3 4C CD 44 48 7D E6 7F FD 77 20 CB 25 CB 14 FD 74; +07A8: 0C CB 13 FD 73 0E 3A DE F2 C9 AF 32 06 F3 CD 5A 48 CD 23 4B 18 0A AF 32; +07C0: 06 F3 CD 5A 48 CD A3 4C CD 6A 48 CD 44 48 69 60 C9 D5 FD E1 FD 7E 10 FD; +07D8: 4E 11 FD 46 12 FD 5E 13 87 CB 11 CB 10 CB 13 B7 28 06 03 78 B1 20 01 1C; +07F0: FD 6E 21 FD 66 22 ED 42 28 96 FD 7E 23 9B 38 90 E5 CD 90 47 D1 B7 C0 2A; +0808: 3D F2 E5 2A 51 F3 22 3D F2 06 80 77 23 10 FC 3D 32 46 F2 FD 6E 21 FD 66; +0820: 22 ED 52 4D 44 EB 16 00 FD 7E 23 9A 5F E5 21 01 00 CD A3 4C CD 6A 48 4D; +0838: 44 E1 2B 7C B5 20 EE E1 22 3D F2 C9 3A DE F2 FD 75 21 FD 74 22 FD 73 23; +0850: 14 15 C8 FD 72 24 C9 21 01 00 D5 FD E1 FD 4E 21 FD 46 22 FD 5E 23 FD 56; +0868: 24 C9 C8 23 7C B5 C0 13 C9 E1 69 60 3E 01 32 DE F2 AF 4F 47 C9 22 E8 F2; +0880: ED 43 E4 F2 ED 53 E6 F2 FD 7E 00 CD 27 44 38 E1 11 80 00 3A 06 F3 B7 20; +0898: 0F FD 7E 0E FD 56 0F 5F B2 20 05 1E 80 FD 73 0E 14 15 20 05 7B FE 40 38; +08B0: 04 AF 32 E7 F2 2A 3D F2 22 E2 F2 AF 32 DE F2 32 DF F2 ED 4B E8 F2 CD 16; +08C8: 49 FD 7E 18 B7 F8 C5 CD 53 45 ED 4B E4 F2 CD 16 49 ED 43 F4 F2 C5 ED 4B; +08E0: E6 F2 CD 1C 49 ED 43 F6 F2 60 69 C1 DD 5E 02 DD 56 03 CD 32 49 22 F2 F2; +08F8: ED 43 EE F2 DD 7E 06 A1 32 DD F2 DD 7E 07 3D 28 06 CB 38 CB 19 18 F7 ED; +0910: 43 EC F2 C1 AF C9 CD 7C F2 21 00 00 78 06 11 18 07 30 01 19 CB 1C CB 1D; +0928: 1F CB 19 10 F4 47 C9 21 00 00 CD 7F F2 78 06 10 CB 11 17 CB 15 CB 14 38; +0940: 0D ED 52 30 01 19 3F CB 11 17 10 EF 47 C9 B7 ED 52 18 F4 60 69 ED 4B F2; +0958: F2 78 B1 5F 57 28 13 DD 5E 02 DD 56 03 EB ED 42 EB ED 52 30 05 19 EB 21; +0970: 00 00 ED 53 F8 F2 4D 44 DD 5E 02 DD 56 03 CD 2F 49 22 FA F2 ED 43 FC F2; +0988: C9 CD 82 F2 FD 6E 1C FD 66 1D FD 5E 1E FD 56 1F 7D B4 28 33 C5 79 93 4F; +09A0: 78 9A 47 30 0B C1 11 00 00 FD 6E 1A FD 66 1B F5 F1 CD 85 F2 78 B1 C8 D5; +09B8: E5 CD F4 41 D1 7C FE 0F 38 05 7D FE F8 30 05 D1 13 0B 18 E5 EB D1 C9 03; +09D0: 1B C9 32 E0 F2 2A EC F2 3A DD F2 CD DB 4E EB 2A 3F F2 ED 52 20 0A 3A E1; +09E8: F2 6F 3A 41 F2 BD 28 2B D5 DD E5 CD 2D 47 DD E1 D1 3A E0 F2 B7 20 0E 3D; +0A00: 32 41 F2 2A 4F F3 06 01 D5 CD C5 46 D1 ED 53 3F F2 3A E1 F2 32 41 F2 DD; +0A18: 22 43 F2 3E 01 32 DF F2 2A E2 F2 E5 ED 4B F8 F2 09 22 E2 F2 2A 4F F3 ED; +0A30: 5B F2 F2 19 D1 C9 CD 88 F2 2A F8 F2 7C B5 C8 AF CD D2 49 C3 D9 F1 CD 8B; +0A48: F2 2A F8 F2 7C B5 C8 2A EE F2 23 22 EE F2 AF EB 2A F0 F2 ED 52 1F CD D2; +0A60: 49 EB CD D9 F1 3E 01 32 42 F2 C9 21 00 00 22 F2 F2 2A FA F2 22 F8 F2 7C; +0A78: B5 37 C8 3A DF F2 B7 C8 3A DD F2 DD BE 06 38 1A ED 5B EC F2 21 F7 0F ED; +0A90: 52 D8 EB CD F4 41 22 EC F2 2A EA F2 23 22 EA F2 3E FF 3C 32 DD F2 B7 C9; +0AA8: 7E ED A0 FE 0D 20 02 36 0A FE 0A 28 15 78 B1 20 EF 22 00 F3 ED 53 E2 F2; +0AC0: C2 E2 4B FD CB 18 B6 C3 E2 4B CD A8 53 21 00 00 79 B0 20 25 3C 18 E2 ED; +0AD8: 5B E2 F2 3C 28 14 3C 20 DB CD 6E 54 12 13 FE 1A 28 D2 0B 78 B1 20 F2 3C; +0AF0: 18 CA 2A 00 F3 7C B5 20 AF 21 7F 00 3A D9 F4 BD 28 03 22 D9 F4 C5 D5 11; +0B08: D9 F4 CD E0 50 D1 C1 21 DB F4 7E FE 1A 20 91 12 13 3E 0A CD A8 53 AF 67; +0B20: 6F 18 96 CD 7D 48 FA D7 4A FD 6E 10 FD 66 11 ED 5B F4 F2 B7 ED 52 E5 FD; +0B38: 6E 12 FD 66 13 ED 5B F6 F2 ED 52 E1 DA 97 4C 20 0D 7C B5 CA 97 4C E5 ED; +0B50: 42 E1 30 02 44 4D CD 8E F2 CD 53 49 ED 4B EC F2 CD 89 49 78 B1 C2 97 4C; +0B68: 22 EC F2 ED 53 EA F2 CD 36 4A 2A FC F2 7C B5 CA DC 4B CD 7B 4A 38 63 3E; +0B80: 01 32 DF F2 3A DD F2 ED 4B FC F2 2A EC F2 C5 CD 48 4E C5 F5 47 CD C5 46; +0B98: F1 4F 06 00 38 23 3A 42 F2 B7 28 1D C5 DD 4E 02 DD 46 03 C5 E5 2A 3F F2; +0BB0: ED 52 EB CD 16 49 E1 09 C1 EB 2A 4F F3 CD D9 F1 C1 D1 E1 B7 ED 42 28 14; +0BC8: 4D 44 21 F7 0F ED 52 38 11 2A EA F2 23 22 EA F2 AF EB 18 B2 CD 6B 4A D4; +0BE0: 36 4A CD 91 F2 2A E2 F2 ED 5B 3D F2 B7 ED 52 4D 44 11 80 00 3A 06 F3 B7; +0BF8: 20 06 FD 5E 0E FD 56 0F CD 2F 49 7C B5 28 10 03 EB ED 52 ED 5B E2 F2 AF; +0C10: 12 13 2B 7C B5 20 F8 2A E8 F2 ED 42 28 04 3C 32 DE F2 CD 94 F2 2A EC F2; +0C28: FD 75 1C FD 74 1D 2A EA F2 FD 75 1E FD 74 1F 2A E4 F2 ED 5B E6 F2 78 B1; +0C40: C8 0B 09 03 D0 13 C9 2A 3D F2 F6 40 3C 28 24 3C 28 11 3C 28 2C 7E 23 FE; +0C58: 1A 28 26 CD 66 54 0B 78 B1 18 F0 7E 23 CD 75 54 FE 1A 28 15 0B 78 B1 20; +0C70: F2 18 0E 7E 23 FE 1A 28 08 CD A8 53 0B 78 B1 20 F2 ED 4B E8 F2 18 B0 4B; +0C88: 42 CD B1 49 78 B1 CA 41 4D CD 12 4F D2 41 4D CD 97 F2 AF 4F 47 3C 32 DE; +0CA0: F2 18 94 CD 7D 48 F5 C5 CD 96 54 FD 71 14 FD 70 15 FD 73 16 FD 72 17 C1; +0CB8: F1 FA 47 4C FD CB 18 B6 C5 CD 53 49 C1 2A F4 F2 ED 5B F6 F2 78 B1 CA DD; +0CD0: 4D 0B 09 30 01 13 44 4D EB DD 5E 02 DD 56 03 CD 32 49 60 69 DD 46 07 05; +0CE8: 28 06 CB 3C CB 1D 10 FA E5 FD 4E 10 FD 46 11 FD 6E 12 FD 66 13 CD 32 49; +0D00: 7C B5 28 01 03 CD 9A F2 ED 43 F0 F2 ED 4B EC F2 CD 89 49 22 EC F2 ED 53; +0D18: EA F2 E3 B7 ED 52 EB E1 28 1F 78 B1 CA 87 4C C5 4B 42 CD 12 4F C1 DA 97; +0D30: 4C ED 5B EA F2 13 0B CD B1 49 22 EC F2 ED 53 EA F2 CD 46 4A 2A FC F2 7C; +0D48: B5 28 41 ED 5B EE F2 19 22 EE F2 CD 7B 4A 3E 01 32 DF F2 3A DD F2 2A EC; +0D60: F2 ED 4B FC F2 C5 CD 48 4E C5 F5 47 38 05 3E FF 32 41 F2 CD 55 47 F1 D1; +0D78: E1 4F AF 47 ED 42 28 0C 4D 44 2A EA F2 23 22 EA F2 EB 18 D9 CD 9D F2 CD; +0D90: 6B 4A D4 46 4A 2A E2 F2 ED 5B 3D F2 B7 ED 52 ED 5B F4 F2 19 ED 5B F6 F2; +0DA8: 30 01 13 22 F4 F2 ED 53 F6 F2 FD 4E 10 FD 46 11 B7 ED 42 FD 4E 12 FD 46; +0DC0: 13 EB ED 42 38 10 FD E5 E1 11 10 00 19 EB 21 F4 F2 01 04 00 ED B0 ED 4B; +0DD8: E8 F2 C3 22 4C 7C B5 B2 B3 28 4F 01 01 00 ED 42 EB 0B ED 42 42 4B DD 5E; +0DF0: 02 DD 56 03 CD 32 49 DD 7E 07 3D 28 06 CB 38 CB; +0E00: 19 18 F7 CD 89 49 78 B1 28 1C CD 12 4F DA 97 4C 01 00 00 ED 43 E8 F2 ED; +0E18: 43 EA F2 FD 6E 1A FD 66 1B 22 EC F2 18 A0 01 FF 0F CD 9E 4F 1B 3E 01 12; +0E30: 18 DE FD 6E 1A FD 66 1B 7C B5 28 D4 AF FD 77 1A FD 77 1B CD 9B 4F 18 E4; +0E48: CD A0 F2 57 E5 04 05 28 02 0E FF 59 D5 DD 7E 06 32 DD F2 3C 92 47 22 EC; +0E60: F2 E5 CD F4 41 D1 79 90 4F 28 0D DD 46 06 38 5A 04 13 EB ED 52 EB 28 E6; +0E78: D1 E3 E5 D5 7B 91 5F 16 00 DD 4E 02 DD 46 03 CD 16 49 F1 2A E2 F2 E5 09; +0E90: 22 E2 F2 C1 E1 C5 D5 EB 2A EC F2 ED 52 ED 4B EA F2 09 22 EA F2 EB CD DB; +0EA8: 4E EB C1 3A 41 F2 DD BE 00 79 37 20 12 2A 3F F2 B7 ED 52 38 0A 60 69 19; +0EC0: 2B ED 4B 3F F2 ED 42 E1 C1 C9 80 32 DD F2 0E 00 18 A6 CD FA 41 7D 29 29; +0ED8: E6 3F C9 CD A3 F2 C5 DD 46 07 2B 2B 05 28 06 CB 25 CB 14 10 FA B5 6F DD; +0EF0: 4E 0C DD 46 0D 09 C1 C9 D5 FD E1 FD 4E 20 FD 46 0C FD 5E 0E 16 00 CB 21; +0F08: CB 3B CB 18 CB 19 21 01 00 C9 CD A6 F2 DD 5E 13 DD 56 14 EB 7E 23 66 6F; +0F20: E5 EB DD 5E 0E DD 56 0F ED 53 02 F3 E5 C5 E5 54 5D D5 EB 2A 02 F3 2B B7; +0F38: ED 52 EB D1 30 10 7B B2 20 14 E1 E1 E1 01 FF 0F CD 9E 4F 37 18 46 23 CD; +0F50: 5E 4F 7B B2 28 DB 1B EB CD 5E 4F EB 18 D3 E5 D5 CD F4 41 D1 E1 C0 C1 4D; +0F68: 44 E3 DD 5E 13 DD 56 14 CD 21 42 E1 C1 0B 78 B1 20 B3 01 FF 0F CD 21 42; +0F80: 1B 3E 01 12 E1 E5 CD F4 41 C1 79 B0 20 06 FD 75 1A FD 74 1B EB C1 71 23; +0F98: 70 EB C9 01 00 00 CD A9 F2 E5 CD F4 41 E3 CD 21 42 E1 7C B5 C8 7C FE 0F; +0FB0: 38 E9 7D FE F8 38 E4 C9 CD A5 42 38 43 3A B8 F2 28 02 3E FF 32 0B F3 DD; +0FC8: 22 09 F3 ED 5B 3D F2 3A E1 F2 3C 12 13 7E FE 05 20 02 36 E5 01 20 00 CD; +0FE0: D9 F1 CD 39 44 3A 0C F3 B8 28 04 30 13 0E 80 2A 3D F2 11 0C 00 19 46 77; +0FF8: 23 70 23 72 23 71 AF C9 3E FF 32 0B F3 C9 CD 0E 44 38 F5 3A 0B F3 FE FF; +1010: 28 EE 32 B8 F2 DD 2A 09 F3 CD BC 42 18 9D CD A5 42 3E FF D8 D5 DD E1 FD; +1028: 7E 1C FD 4E 1D FD 46 1E FD 5E 1F 87 CB 11 CB 10 CB 13 B7 28 06 03 78 B1; +1040: 20 01 1C DD 71 21 DD 70 22 DD 73 23 AF C9 3A 47 F3 47 AF 37 17 10 FC C9; +1058: ED 53 3D F2 C9 AF 32 06 F3 7B CD 27 44 3E FF D8 CD DB 44 DD 5E 13 DD 56; +1070: 14 D5 FD E1 21 02 00 44 4C DD 5E 0E DD 56 0F 1B D5 D5 E5 CD F4 41 E1 D1; +1088: 20 01 03 23 1B 7B B2 20 F0 60 69 D1 DD 7E 06 3C DD 4E 02 DD 46 03 C9 21; +10A0: 80 00 22 3D F2 AF 32 47 F2 CD 2D 47 21 55 F3 3A 47 F3 5E 23 56 23 E5 F5; +10B8: D5 DD E1 CD C4 45 F1 E1 3D 20 EF C9 3A 47 F2 C9 CD F8 4E FD 75 21 FD 74; +10D0: 22 FD 73 23 C9 3A 47 F3 BB D8 C8 21 47 F2 73 C9 D5 3A 37 F2 32 38 F2 AF; +10E8: 32 39 F2 62 6B 47 4E 23 57 5E 23 DD 21 59 F4 7B B9 30 06 E5 19 7E E1 FE; +1100: 0D 28 01 5A CD AC F2 CD 4E 54 E5 C5 21 74 53 01 11 00 ED B1 09 09 09 4E; +1118: 23 66 69 C1 E3 C9 CD 4E 54 FE 40 38 E5 FE 60 30 E1 F5 78 3C B9 30 2F 3E; +1130: 01 DD 77 00 DD 23 04 CD 5D 53 F1 F5 78 B9 30 1E F1 DD 77 00 DD 23 04 CD; +1148: 5D 53 3A 39 F2 B7 20 B4 14 7B BA 38 AF 7E 3D 23 20 AA 14 23 18 A6 F1 3E; +1160: 07 CD A8 53 18 9E D1 3A 38 F2 47 3A 37 F2 90 28 06 47 CD 4F 53 10 FB C3; +1178: E0 50 78 32 3A F2 CD 83 51 18 81 3E 0D CD A8 53 3E 0A C3 A8 53 D1 CD A8; +1190: 53 D5 13 78 12 B9 F5 13 48 AF 47 B1 28 05 21 59 F4 ED B0 F1 28 03 3E 0D; +11A8: 12 D1 C9 3A 3A F2 A0 FE 7F CA 44 52 04 05 28 24 05 DD 2B CD 4F 53 04 05; +11C0: 28 0C 05 DD 2B DD 7E 00 3D 28 11 04 DD 23 DD 7E 00 FE 20 30 07 FE 09 28; +11D8: 22 CD 4F 53 3A 39 F2 B7 20 9F 14 15 28 9B 15 7A BB 30 96 2B 7A FE 01 38; +11F0: 90 2B 7E 3D 23 20 8A 15 2B 18 86 E5 C5 3A 38 F2 4F 04 05 28 15 21 59 F4; +1208: 7E 23 FE 01 28 0A 0C FE 20 30 05 FE 09 28 13 0C 10 EE 3A 37 F2 91 28 06; +1220: 47 CD 4F 53 10 FB C1 E1 18 B2 79 C6 07 E6 F8 4F 18 E6 3A 39 F2 EE 01 18; +1238: 05 AF 18 02 3E 01 32 39 F2 C3 04 51 AF 32 3A F2 C5 06 10 11 7D 54 21 00; +1250: 00 E5 CD D2 4E C6 20 CD A8 53 7C C6 20 CD A8 53 E1 23 10 ED C1 3E 40 D1; +1268: CD 8E 51 CD 83 51 3A 38 F2 B7 CA E0 50 47 3E 20 CD A8 53 10 FB C3 E0 50; +1280: 3E FF 18 31 CD E3 52 DA 04 51 C5 4F 06 00 09 C1 82 57 C3 04 51 CD E3 52; +1298: DA 04 51 18 18 7A BB D2 04 51 14 7E 3D 23 C2 04 51 14 23 C3 04 51 7E 3D; +12B0: 3E 01 20 01 3C F5 AF 32 39 F2 78 B9 30 21 7A BB 30 1D 7E FE 01 20 06 78; +12C8: 3C B9 30 13 7E 23 DD 77 00 DD 23 CD 5D 53 04 14 F1 3D 20 D9 C3 04 51 F1; +12E0: C3 04 51 CD 4E 54 FE 01 20 35 CD 4E 54 FE 40 38 2E FE 60 30 2A E5 D5 C5; +12F8: FD 21 00 00 37 F5 3E 01 CD 1F 53 38 15 4F 06 00 09 82 57 FD E5 F1 81 F5; +1310: FD E1 23 F1 BE 2B 20 E4 FD E5 F1 C1 D1 E1 C9 C5 F5 7B 92 38 26 28 24 3D; +1328: 28 21 4F 06 00 F1 E5 F5 7E 3D 20 02 23 0D F1 0C 0D 20 04 E1 C1 37 C9 23; +1340: ED B1 E1 20 07 7B 92 3D 91 C1 C9 F1 C1 37 C9 3E 08 CD A8 53 3E 20 CD A8; +1358: 53 3E 08 18 4B FE 20 30 47 FE 09 28 43 FE 01 28 3F F5 3E 5E CD A8 53 F1; +1370: F6 40 18 34 06 7F 08 0D 0A 15 0B 0C 1B 12 18 1C 1D 1E 1F 01 08 3B 51 1E; +1388: 51 80 52 66 51 AB 51 AE 52 95 52 32 52 66 51 84 52 65 52 66 51 7A 51 8D; +13A0: 51 AB 51 9D 52 04 51 7B CD AF F2 FE 0B 28 39 FE 0C 28 35 FE 1C 28 1E FE; +13B8: 1D 28 35 FE 0D 28 29 FE 08 28 2D FE 09 28 31 FE 7F 28 25 FE 20 38 06 E5; +13D0: 21 37 F2 34 E1 C5 47 CD 12 54 78 CD 8F 40 3A 3B F2 B7 78 C1 C8 C3 9B 40; +13E8: F5 AF 32 37 F2 F1 18 E5 E5 21 37 F2 35 E1 18 DD 3E 20 CD A8 53 3A 37 F2; +1400: E6 07 20 F4 C9 FE 10 28 14 FE 0E 28 10 FE 03 28 0C C9 CD 34 40 C8 FE 13; +1418: 20 EB CD 78 40 CD 78 40 FE 10 28 0D FE 0E 28 0F FE 03 C0 2A 25 F3 C3 E8; +1430: F1 3E 01 32 3B F2 C9 AF 32 3B F2 C9 CD 12 54 3E 00 C8 F6 FF C9 CD 4E 54; +1448: F5 CD A8 53 F1 C9 CD 1D 54 28 FB C9 7B FE FF C2 8F 40 CD 34 40 C2 78 40; +1460: AF C9 C3 78 40 7B F5 CD 12 54 F1 C3 9B 40 CD 12 54 C3 71 F3 7B F5 CD 12; +1478: 54 F1 C3 74 F3 ED 8C 93 EF 0C 88 39 40 03 70 48 97 F2 FC BA 80 0A CC B5; +1490: 5E AF 29 00 00 C9 CD B2 F2 CD C0 54 79 87 87 87 CB 10 87 CB 10 87 CB 10; +14A8: CB 3A B2 5F 50 ED 4B 49 F2 79 87 87 87 87 87 CB 10 4F 3A 48 F2 B1 4F C9; +14C0: CD 79 41 38 46 D5 E5 ED 5B 4C F2 B7 ED 52 E1 D1 C8 22 4C F2 C5 D5 4D 44; +14D8: 11 B5 05 CD 2F 49 79 87 87 87 06 00 11 34 55 CD 15 55 CB 3F 30 04 11 C8; +14F0: 00 19 CD 23 55 3E 01 11 2B F2 CD 15 55 32 49 F2; +1500: 2C 7D 32 48 F2 CD 88 55 D1 C1 C9 C5 D5 2A 4A F2 CD 9D 55 18 F0 EB 4E 23; +1518: EB B7 ED 42 38 03 3C 18 F4 09 C9 CD B5 F2 32 4A F2 E6 03 3E 1C 20 01 3C; +1530: 32 2C F2 C9 C8 A6 C8 A5 C8 A5 C8 A5 AF 32 06 F3 CD C0 54 2A 4A F2 11 BC; +1548: 07 19 ED 5B 48 F2 3A 4E F2 C9 01 44 F8 09 30 42 7C B7 20 3E 7D FE 78 30; +1560: 39 CD 29 55 1C 1D 28 32 7A B7 28 2E FE 0D 30 2A E5 21 2A F2 85 6F 30 01; +1578: 24 7E E1 BB 38 1C ED 53 48 F2 CD 9D 55 CD 15 41 ED 4B 4C F2 11 07 00 03; +1590: 03 CD 2F 49 7D 32 4E F2 AF C9 3E FF C9 7D CD 23 55 4D CB 39 CB 39 06 00; +15A8: 11 B5 05 CD 16 49 69 60 3A 4A F2 E6 03 87 11 34 55 06 00 3C CD D2 55 11; +15C0: 2B F2 3A 49 F2 CD D2 55 3A 48 F2 3D 4F 09 22 4C F2 C9 3D C8 EB 4E 23 EB; +15D8: 09 18 F7 AF 32 06 F3 CD C0 54 60 69 AF C9 44 4D 78 FE 18 30 AD 3E 3B B9; +15F0: 38 A8 BA 38 A5 7B FE 64 30 A0 CD 30 41 AF C9 7B 32 0D F3 C9 7E FE 20 37; +1608: C8 01 02 08 FE E5 20 12 3E 05 12 23 13 05 3E E5 CD 81 56 30 05 7E 12 23; +1620: 13 05 7E CD 81 56 30 09 12 23 13 05 37 C8 7E 18 36 3A 0E F3 A7 7E 28 14; +1638: FE 80 38 10 FE BA 30 0C E5 C5 4F 06 00 21 16 56 09 7E C1 E1 FE 61 38 06; +1650: FE 7B 30 02 D6 20 FE 20 D8 E5 C5 21 77 56 01 0A 00 ED B1 C1 E1 37 C8 12; +1668: 23 13 10 B6 06 03 0D 20 B1 B7 7E 32 0C F3 C9 2E 22 2F 5B 5D 3A 2B 3D 3B; +1680: 2C E5 21 0F F3 BE 3F 30 0B 23 BE 38 07 23 BE 3F 30 02 23 BE E1 C9 80 9A; +1698: 45 41 8E 41 8F 80 45 45 45 49 49 49 8E 8F 90 92 92 4F 99 4F 55 55 59 99; +16B0: 9A 9B 9C 9D 9E 9F 41 49 4F 55 A5 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B0; +16C8: B2 B2 B4 B4 B6 B6 B8 B8 AF 47 C9 FB 3E 01 32 06 F3 79 FE 31 30 F2 D6 11; +16E0: 20 04 ED 53 07 F3 3D 20 04 ED 5B 07 F3 E5 21 00 57 E3 E5 21 0D 57 06 00; +16F8: 09 09 46 23 66 68 E3 C9 F5 3A 06 F3 B7 28 04 F1 6F 60 C9 F1 C9 A7 40 45; +1710: 54 A7 53 6E 54 74 54 65 54 54 54 62 54 4E 54 C9 F1 E0 50 3C 54 EF 41 9F; +1728: 50 D5 50 62 44 6F 45 B8 4F 06 50 6C 43 75 47 7D 47 1D 46 92 43 4E 50 C4; +1740: 50 58 50 5D 50 D0 56 D0 56 D0 56 D0 56 D0 56 88 47 93 47 1E 50 C8 50 D0; +1758: 56 BE 47 B2 47 D1 47 D0 56 3C 55 52 55 DB 55 E6 55 FF 55 BA 46 20 47 CD; +1770: 1D 78 F3 3A 99 FD A7 F8 C2 0C 58 21 20 FB CB 46 20 0C CB C6 21 CA FF 06; +1788: 0F 36 C9 23 10 FB 2A 48 FC 11 01 C0 E7 30 0C 3E 06 CD 41 01 F3 0F 38 09; +17A0: 3E 07 DF 3E FF 32 99 FD C9 21 88 F3 11 C9 F1 A7 ED 52 D4 E8 5E D8 E5 21; +17B8: 49 FE 01 C9 F1 AF 02 03 23 7D B4 20 F8 22 AB F6 06 14 21 21 FB 77 23 10; +17D0: FC 21 4F F2 06 69 36 C9 23 10 FB 3E DB 21 A8 C9 32 65 F3 22 66 F3 3E 06; +17E8: CD 41 01 E6 02 32 3F F3 3E 07 DF 21 07 58 11 CB FE 01 05 00 ED B0 CD 2D; +1800: 40 32 CC FE D1 18 1E F7 00 97 58 C9 21 21 FB 06 04 AF 86 DA CC 5E 23 23; +1818: 10 F8 FE 08 D0 21 08 00 CD E8 5E D8 EB CD CD 5F 73 23 72 2A AB F6 11 00; +1830: 02 E7 30 04 ED 53 AB F6 11 21 FB 01 00 04 1A A7 28 09 81 4F 13 13 10 F6; +1848: C3 CC 5E 3A 3F F3 A7 79 CD 3C 78 85 FE 09 7D 38 03 3E 08 91 C5 12 13 CD; +1860: 2D 40 12 C1 06 00 21 55 F3 09 09 E5 1B 1A F5 4F 11 15 00 CD 16 49 69 60; +1878: CD C8 5E EB F1 E1 73 23 72 23 E5 21 16 74 01 15 00 ED B0 E1 3D 20 EF CD; +1890: 88 78 21 99 FD 34 C9 21 CB FE 06 05 36 C9 23 10 FB 21 99 FD AF BE 77 F0; +18A8: CD 2D 62 32 48 F3 21 97 73 11 C9 F1 01 6E 00 ED B0 21 34 00 11 0F F3 01; +18C0: 04 00 ED B0 3A 2B 00 0F 0F 0F 0F E6 07 32 0E F3 3E FF 32 41 F2 32 46 F2; +18D8: 32 4D F2 3E 0D 32 5B F5 3E 07 32 45 F3 21 B5 05 22 3B F3 06 08 21 68 F3; +18F0: 36 C3 23 23 23 10 F9 2A AB F6 E5 CD C8 5E 22 4D F3 E1 E5 CD C8 5E 22 4F; +1908: F3 E1 CD C8 5E 22 51 F3 21 21 FB 06 04 AF 86 DA CC 5E 23 23 10 F8 FE 09; +1920: D2 CC 5E 32 47 F3 47 0E 00 21 55 F3 5E 23 56 23 E5 D5 DD E1 DD 71 00 0C; +1938: C5 DD 4E 02 DD 46 03 DD 5E 10 16 00 CD 16 49 03 69 60 CD C8 5E 22 49 F3; +1950: 36 FF 23 DD 75 13 DD 74 14 C1 E1 10 CF 21 27 F3 36 3E 23 36 1A 06 08 23; +1968: 36 C9 10 FB 21 27 F3 22 72 F3 21 2C F3 22 75 F3 21 31 F3 22 7E F3 21 2F; +1980: 7D 3A C1 FC CD 0C 00 F5 23 3A C1 FC CD 0C 00 D1 67 6A E5 DD E1 FD 2A C0; +1998: FC CD 1C 00 CD B8 40 CD 6E 5C 3A C1 FC 32 41 F3 32 42 F3 CD 98 5F 32 43; +19B0: F3 CD 95 5F 32 44 F3 0E 00 CD 52 5E 38 03 32 41 F3 0E 40 CD 52 5E 38 03; +19C8: 32 42 F3 31 00 C2 3A DA FE FE C9 28 06 DD 21 17 7D 18 12 21 C9 FC 06 40; +19E0: 7E 87 38 05 23 10 F9 18 0A DD 21 14 7E CD 16 5C C3 59 01 21 3A 5B E5 CD; +19F8: E7 5A D8 CD DB 5A 2A 48 FC 11 00 80 E7 C0 21 41 F3 3A C1 FC BE C8 23 BE; +1A10: C8 AF CD 9A 60 2A 49 F3 22 4B F3 CD E7 5A DA 3A 5B 32 46 F3 3A 41 F3 26; +1A28: 00 CD C2 64 37 F4 A2 64 DC AF 64 AF 6F 67 77 2C 20 FC 01 26 00 CD AD 5E; +1A40: 22 6F F3 EB 21 7B 63 ED B0 01 19 00 CD AD 5E 5D 54 22 69 F3 23 23 22 6C; +1A58: F3 21 A1 63 ED B0 01 68 01 CD AD 5E E5 EB 21 F4 63 E5 ED B0 C1 D1 D5 21; +1A70: 17 01 19 36 3B 23 36 00 21 BA 63 CD 06 63 21 0F 5B AF 47 57 5E BB 28 10; +1A88: 23 4E 23 E3 09 EB 36 C3 23 73 23 72 EB E3 18 EC E1 21 5C 65 11 3B 00 01; +1AA0: 1A 00 ED B0 01 45 00 CD AD 5E E5 EB 21 36 63 E5 ED B0 C1 D1 D5 21 2E 63; +1AB8: CD 06 63 E1 3E C3 32 38 00 22 39 00 11 22 00 19 ED 5B 4B F3 73 23 72 01; +1AD0: A0 00 CD AD 5E 3E C3 CD 62 5C 37 21 23 F3 11 68 F3 3A 40 F3 C3 1E C0 3A; +1AE8: 17 74 4F 06 01 2A 51 F3 E5 AF 5F 57 CD 44 01 3E FF 32 46 F2 E1 D8 7E 11; +1B00: 00 C0 01 00 01 ED B0 FE EB C8 FE E9 C8 37 C9 0C 00 14 21 30 2E 1C 12 24; +1B18: 47 00 00 41 55 54 4F 45 58 45 43 42 41 53 00 52 55 4E 22 41 55 54 4F 45; +1B30: 58 45 43 2E 42 41 53 00 92 5B CD 60 5C 21 27 5B 11 68 F5 01 11 00 ED B0; +1B48: 21 40 F3 7E A7 74 20 1E 32 46 F3 21 38 5B 22 23 F3 21 1A 5B 11 79 F5 01; +1B60: 25 00 D5 ED B0 D1 CD 62 44 3C 28 26 18 32 3A 00 00 FE C3 20 27 21 80 00; +1B78: 46 04 05 28 1F 23 7E FE 20 20 04 10 F8 18 15 AF 48 47 11 6C F5 ED B0 12; +1B90: 18 0E 31 00 C2 3A 38 F3 A7 CC 3F 5D AF 32 6B F5 31 00 C2 3A 43 F3 26 80; +1BA8: CD 24 00 3A C1 FC 26 00 CD 24 00 2A 48 FC AF 77 23 22 76 F6 77 23 77 23; +1BC0: 22 C2 F6 21 FF FF 22 1C F4 CD 16 5C ED 7B 74 F6 3E FF 32 DE F3 3E 0C DF; +1BD8: DD 21 31 7D CD 59 01 CD 86 5F 0D 0A 44 69 73 6B 20 42 41 53 49 43 20 76; +1BF0: 65 72 73 69 6F 6E 20 31 2E 30 0D 0A 00 21 73 41; +1C00: E5 21 67 F5 E5 21 9E F5 E5 36 E1 23 36 C9 3A C1 FC 26 40 C3 24 00 21 AE; +1C18: 72 22 23 F3 21 6C 5C 22 25 F3 2A 49 F3 22 4A FC 3A 45 F3 4F 06 00 11 25; +1C30: 00 CD 16 49 CD B8 5E 22 53 F3 01 19 00 CD B8 5E 22 78 F3 EB 21 ED 62 ED; +1C48: B0 21 F5 FF 19 22 7B F3 3A 48 F3 11 F9 FF 19 77 11 0E 00 19 77 CD 5F 5F; +1C60: 3E C9 32 68 F3 32 6B F3 32 6E F3 C9 A7 40 21 E8 62 11 BC FE 01 05 00 ED; +1C78: B0 21 96 5C 5E 23 56 23 7B B2 C8 EB 36 F7 23 3A 48 F3 77 23 EB ED A0 ED; +1C90: A0 3E C9 12 18 E6 EF FD 96 6B 17 FE 75 6B F9 FD 20 6F FE FD 00 6F 08 FE; +1CA8: 7B 70 12 FE 61 70 21 FE D7 6C 26 FE D6 6C 2B FE 49 6C 30 FE AF 6D 35 FE; +1CC0: B2 6D 3A FE B5 6D 3F FE D7 6D 44 FE DA 6D 49 FE DD 6D 4E FE A4 66 58 FE; +1CD8: B3 66 5D FE FC 66 62 FE D0 68 71 FE 0E 69 76 FE 39 69 7B FE 88 6E 80 FE; +1CF0: DA 6B 85 FE 8E 68 8A FE 19 68 99 FE 0D 70 9E FE 09 70 A3 FE 70 6E AD FE; +1D08: 75 68 B2 FE 23 73 B7 FE 7C 73 FD FE D3 71 A7 FF 55 60 AC FF B0 60 31 F3; +1D20: D3 56 00 00 01 48 2D 01 41 2D 01 47 29 3A 00 4D 2D 44 2D 59 29 3A 00 44; +1D38: 2D 4D 2D 59 29 3A 00 ED 73 C0 F5 3E 14 32 C2 F5 CD 86 5F 0D 0A 45 6E 74; +1D50: 65 72 20 64 61 74 65 20 28 00 00 00 00 00 00 3A 0E F3 FE 01 21 24 5D 38; +1D68: 08 21 2F 5D 28 03 21 37 5D CD 8C 5F 21 4B 5E 22 25 F3 11 C2 F5 CD E0 50; +1D80: 21 C4 F5 7E FE 0D C8 3A 0E F3 A7 20 12 CD 0D 5E CD E9 5D 51 7E 23 B8 20; +1D98: 32 CD F8 5D 59 18 1A CD F8 5D 51 CD E9 5D 59 7E 23 B8 20 05 CD 0D 5E 18; +1DB0: 08 D5 CD 3C 55 E5 DD E1 D1 3A 0E F3 FE 02 38 03 7B 5A 57 DD E5 E1 CD 52; +1DC8: 55 B7 C8 ED 7B C0 F5 CD 86 5F 0D 0A 49 6E 76 61 6C 69 64 20 64 61 74 65; +1DE0: 00 00 00 00 00 00 C3 48 5D 7E 23 47 FE 2F 28 08 FE 2E 28 04 FE 2D 20 D3; +1DF8: CD 41 5E 38 CE 4F CD 41 5E D8 F5 79 87 87 81 87 4F F1 81 4F C9 CD F8 5D; +1E10: 41 CD 41 5E 38 16 2B CD F8 5D E5 C5 48 06 00 D5 11 64 00 CD 16 49 D1 E1; +1E28: 26 00 18 0F E5 48 06 00 21 6C 07 79 FE 50 30 03 21 D0 07 09 E5 DD E1 E1; +1E40: C9 7E D6 30 D8 FE 0A 3F D8 23 C9 4D 5E ED 7B C0 F5 C9 21 C1 FC 06 04 AF; +1E58: E6 03 B6 C5 E5 61 2E 10 F5 CD 0C 00 2F 5F F1 D5 F5 CD 14 00 F1 D1 F5 D5; +1E70: CD 0C 00 C1 47 79 2F 5F F1 F5 C5 CD 14 00 C1 79 B8 20 17 F1 2D 20 D9 24; +1E88: 24 24 24 4F 7C FE 40 28 05 FE 80 79 20 C8 79 E1 E1 C9 F1 E1 C1 A7 F2 A7; +1EA0: 5E C6 04 FE 90 38 B4 23 3C 10 AD 37 C9 2A 4B F3 A7 ED 42 22 4B F3 18 09; +1EB8: 2A 4A FC A7 ED 42 22 4A FC 38 09 7C FE C2 18 03 CD E8 5E D0 CD 86 5F 0C; +1ED0: 4E 6F 20 65 6E 6F 75 67 68 20 6D 65 6D 6F 72 79 00 00 00 00 00 00 F3 76; +1EE8: 7D B4 C8 AF 95 6F 3E 00 9C 67 4D 44 39 3F D8 ED 5B 48 FC ED 52 D8 7C FE; +1F00: 02 D8 C5 21 00 00 39 5D 54 09 E5 2A 74 F6 A7 ED 52 4D 44 03 E1 F9 EB ED; +1F18: B0 C1 2A 4A FC 09 22 4A FC 11 EA FD 19 22 60 F8 EB 2A 72 F6 09 22 72 F6; +1F30: 2A 62 F8 09 22 62 F8 2A 74 F6 09 22 74 F6 2B 2B 22 B1 F6 6B 62 23 23 23; +1F48: 23 3E 02 EB 73 23 72 23 EB 01 07 00 70 09 70 01 02 01 09 3D 20 ED C9 3E; +1F60: 01 32 5F F8 2A 4A FC 11 EA FD 19 22 60 F8 5D 54 2B 2B 22 72 F6 01 C8 00; +1F78: A7 ED 42 E5 21 0D 00 19 22 62 F8 E1 18 B5 E3 CD 8C 5F E3 C9 7E 23 A7 C8; +1F90: CD 8F 40 18 F7 06 06 21 06 04 CD 65 F3 C5 0F 10 FD CD EC 5F C1 B6 4F 23; +1FA8: 23 23 23 7E 05 05 0F 10 FD 18 0B CD E7 5F B6 F0 4F 23 23 23 23 7E E6 0C; +1FC0: B1 C9 CD CD 5F 7E 23 66 6F E5 DD E1 C9 CD E7 5F 87 87 87 37 8F 4F 7E 87; +1FD8: 9F E6 0C 23 23 23 23 A6 B1 87 21 09 FD 18 0C CD 65 F3 0F 0F E6 03 21 C1; +1FF0: FC 06 00 4F 09 C9 3A 9F FD FE C9 28 15 E5 3A 99 FD 21 29 FB CD F1 5F 09; +2008: 09 EB 21 A0 FD 0E 03 ED B0 E1 F3 3E F7 32 9F FD 22 A1 FD 3E C9 32 A3 FD; +2020: CD 2D 40 32 A0 FD C9 F5 CD 2D 40 06 04 11 29 FB 21 22 FB BE 28 09 13 13; +2038: 13 23 23 10 F6 F1 C9 EB 7E A7 28 F9 F5 FD E1 23 4E 23 46 C5 DD E1 F1 C3; +2050: 1C 00 A7 38 37 DD E5 FD E5 E5 F5 CD 86 60 6F F1 7D DD 21 10 40 18 14 DD; +2068: E5 DD 21 13 40 18 06 DD E5 DD 21 16 40 FD E5 E5 CD 86 60 E1 E5 CD 1C 00; +2080: C3 6E 63 00 00 00 32 3F F3 21 21 FB 96 38 04 23 23 18 F9 86 23 66 E5 FD; +2098: E1 C9 21 55 F3 CD F1 5F 09 5E 23 56 21 13 00 19 5E 23 56 1B EB 36 FF C9; +20B0: A7 ED 73 39 F3 D4 D6 62 E5 C5 3A 47 F3 3D 28 41 CD 86 5F 44 72 69 76 65; +20C8: 20 6E 61 6D 65 3F 20 28 00 00 00 00 00 00 3A 47 F3 47 3E 41 18 07 F5 3E; +20E0: 2C CD 8F 40 F1 CD 8F 40 3C 10 F3 CD 86 5F 29 20 00 CD 95 61 CD C6 62 E6; +20F8: DF D6 41 21 47 F3 BE 30 BF CD 9A 60 CD 86 60 FD E5 F5 FD E5 DD 21 19 40; +2110: CD 1C 00 7D B4 28 27 F1 F5 CD 0C 00 A7 28 07 CD 8F 40 23 F1 18 F2 F1 CD; +2128: 86 5F 3F 20 00 CD 95 61 D6 31 FE 09 30 F7 C6 31 CD C6 62 D6 30 F5 CD 74; +2140: 61 F1 D1 FD E1 C1 E1 DD 21 1C 40 CD 1C 00 21 E0 61 30 0A 21 48 62 CD F1; +2158: 5F 7E 23 66 6F CD C9 62 CD 8C 5F C3 C9 62 AF 32 36 F3 DD 21 56 01 CD AB; +2170: 40 C3 78 40 CD 86 5F 53 74 72 69 6B 65 20 61 20 6B 65 79 20 77 68 65 6E; +2188: 20 72 65 61 64 79 20 00 00 00 00 00 00 CD 66 61 FE 03 C0 ED 7B 39 F3 CD; +21A0: 86 5F 0D 0A 41 62 6F 72 74 65 64 00 C9 57 72 69 74 65 20 70 72 6F 74 65; +21B8: 63 74 65 64 00 4E 6F 74 20 72 65 61 64 79 00 44 69 73 6B 20 65 72 72 6F; +21D0: 72 00 42 61 64 20 70 61 72 61 6D 65 74 65 72 00 46 6F 72 6D 61 74 20 63; +21E8: 6F 6D 70 6C 65 74 65 00 00 11 98 F6 2A 78 F6 22 F8 F7 3E 03 32 63 F6 CD; +2200: F3 2E 11 9B F6 E7 22 78 F6 C0 C3 F7 72 21 21 FB 06 04 23 7E F5 FD E1 23; +2218: E5 C5 21 1F 40 E5 DD E1 A7 C4 0C 00 A7 C4 1C 00 C1 E1 10 E6 C9 3A D0 FE; +2230: FE C9 28 11 21 F2 72 11 D5 FE 01 05 00 ED B0 CD 2D 40 32 D6 FE C3 2D 40; +2248: AD 61 BD 61 C7 61 C7 61 C7 61 C7 61 D2 61 D0 5E C7 61 3A 3F F3 C6 41 CD; +2260: 4F F2 F5 CD 86 5F 0D 0A 49 6E 73 65 72 74 20 64 69 73 6B 65 74 74 65 20; +2278: 66 6F 72 20 64 72 69 76 65 20 00 00 00 00 00 00 00 00 00 00 00 F1 CD 8F; +2290: 40 CD 86 5F 3A 0D 0A 61 6E 64 20 73 74 72 69 6B 65 20 61 20 6B 65 79 20; +22A8: 77 68 65 6E 20 72 65 61 64 79 00 00 00 00 00 00 00 00 00 00 00 CD 66 61; +22C0: FE 03 28 F9 18 03 CD 8F 40 F5 3E 0D CD 8F 40 3E 0A CD 8F 40 F1 C9 21 00; +22D8: FF 39 ED 5B C6 F6 AF ED 52 4D 44 EB D0 4F 47 C9 33 33 C3 1D 6F 7A FE 09; +22F0: D2 C9 6E F7 00 A7 6A E5 C3 F4 6E 7A FE 09 D2 95; +2300: 6E F7 00 E7 69 C9 D5 EB A7 ED 42 E5 DD E1 EB D1 4E 23 46 23 79 A0 3C C8; +2318: D5 EB 09 23 4E 23 46 E5 DD E5 E1 09 4D 44 E1 70 2B 71 EB D1 18 E2 0C 00; +2330: 1E 00 2F 00 FF FF DD E5 FD E5 E5 D5 C5 F5 D9 08 F5 E5 2A 5F 63 7D B4 E1; +2348: DD 21 38 00 FD 2A C0 FC 20 23 F1 ED 73 5F 63 31 00 00 CD 1C 00 F3 31 00; +2360: 00 E5 21 00 00 22 5F 63 E1 08 D9 F1 C1 D1 E1 FD E1 DD E1 FB C9 F1 CD 1C; +2378: 00 18 EE F5 E5 D5 C5 CD 2D 40 F5 26 40 3A 42 F3 CD 24 00 F1 C1 D1 E1 ED; +2390: B0 E5 D5 C5 CD 68 F3 26 40 CD 24 00 C1 D1 E1 F1 C9 18 06 F5 3A 42 F3 18; +23A8: 04 F5 3A 48 F3 E5 D5 C5 26 40 CD 24 00 C1 D1 E1 F1 C9 00 00 03 00 17 00; +23C0: 1C 00 22 00 25 00 39 00 3F 00 69 00 6C 00 7E 00 94 00 A8 00 AB 00 BC 00; +23D8: 10 00 13 00 31 00 34 00 78 00 7B 00 B5 00 B8 00 2A 01 31 01 38 01 45 01; +23F0: 4D 01 FF FF CD C2 64 FA 04 64 DB A8 57 A1 B0 CD 80 F3 7B C9 CD 11 65 CA; +2408: 1E 65 E5 CD E7 64 E3 C5 CD F4 63 18 21 D5 CD C2 64 FA 25 64 D1 DB A8 57; +2420: A1 B0 C3 85 F3 CD 11 65 CA 24 65 E3 E5 CD E7 64 D1 E3 C5 CD 15 64 C1 E3; +2438: F5 78 E6 3F B1 CD 46 00 F1 E1 C9 E3 F5 D5 7E F5 FD E1 23 5E 23 56 23 D5; +2450: DD E1 D1 F1 E3 D9 08 FD E5 F1 DD E5 E1 CD C2 64 FA 6C 64 DB A8 F5 A1 B0; +2468: D9 C3 8C F3 CD 11 65 CA 2C 65 CD E7 64 F5 FD E1 E5 C5 4F 06 00 7D A4 B2; +2480: 21 C5 FC 09 77 E5 08 D9 CD 55 64 D9 08 E1 C1 D1 78 E6 3F B1 F3 CD 4B 00; +2498: 73 08 D9 C9 CD C2 64 FA A9 64 DB A8 A1 B0 D3 A8 C9 CD 11 65 CA 41 65 E5; +24B0: CD E7 64 4F 06 00 7D A4 B2 21 C5 FC 09 77 E1 79 18 DA F3 F5 7C 07 07 E6; +24C8: 03 5F 1C 3E C0 07 07 1D 20 FB 5F 2F 4F F1 F5 E6 03 47 04 3E AB C6 55 10; +24E0: FC 57 A3 47 F1 A7 C9 F5 7A E6 C0 4F F1 F5 57 DB A8 47 E6 3F B1 F5 7A 0F; +24F8: 0F E6 03 57 14 3E AB C6 55 15 20 FB A3 57 7B 2F 67 F1 CD 5C 65 F1 E6 03; +2510: C9 4F 7B FE 03 79 C0 3A 41 F3 A3 B8 79 C9 CD 49 65 5E 18 05 D1 CD 49 65; +2528: 73 78 18 2B CD 41 65 E5 C5 08 D9 CD 98 F3 D9 08 C1 CD 29 65 E1 70 08 D9; +2540: C9 CD 49 65 21 C5 FC 72 C9 0F 0F E6 03 57 3A FF FF 2F 47 E6 FC B2 57 32; +2558: FF FF 7B C9 D3 A8 3A FF FF 2F 6F A4 B2 18 08 D3 A8 7D 18 03 D3 A8 7B 32; +2570: FF FF 78 D3 A8 C9 3A 4E FE FE C9 37 C8 E5 CD 2D 40 21 48 F3 BE 20 26 21; +2588: B1 65 11 89 FD 1A BE 13 23 20 10 A7 20 F7 7E 23 66 6F E3 CD DA 72 37 3F; +25A0: C9 23 7E A7 20 FB 23 23 23 7E A7 20 DD E1 C3 6A 7C 53 59 53 54 45 4D 00; +25B8: C4 65 46 4F 52 4D 41 54 00 DC 65 00 C0 3A 46 F3 A7 CA 15 73 DD 21 1C 6C; +25D0: CD 1E 73 CD D2 00 CD CC 00 C3 11 5A E5 CC B1 60 E1 A7 C9 7A 3D F0 3A 47; +25E8: F2 C9 E5 D5 C5 CD E3 65 4F 2A 60 F8 3A 5F F8 F5 5E 23 56 23 E5 EB 7E A7; +2600: 28 2C 23 23 23 23 7E FE 09 30 23 2B 2B 56 2B 5E 1A CD E4 65 B9 20 17 13; +2618: EB 11 66 F8 06 0B 1A FE 3F 28 03 BE 20 08 13 23 10 F4 E1 E1 18 72 E1 F1; +2630: 3D F2 F7 65 18 6A E5 D5 C5 7A 32 68 F5 CD 57 66 CD 45 66 18 5B 21 B2 F5; +2648: 22 3D F2 11 68 F5 AF 32 74 F5 CD B8 4F 3C C9 11 69 F5 21 66 F8 01 0B 00; +2660: ED B0 C9 FB E5 D5 C5 F5 3A 48 F3 87 21 10 00 30 02 2E 18 39 DD E5 C1 71; +2678: 23 70 21 0A 00 39 EB 18 0C FD E5 C1 4E 1A 77 79 12 23 13 10 F7 3A 48 F3; +2690: 87 21 12 00 30 02 2E 1A 39 7B 95 7A 9C 38 E2 F1 C1 D1 E1 C9 DD 21 8B F3; +26A8: FD 21 00 02 CD 63 66 E1 7E A7 C9 FB 01 00 01 ED 43 3D F3 CD DA 72 7B C8; +26C0: F5 E5 3A 48 F3 87 21 0C 00 30 02 2E 14 39 7E FE 04 C2 18 73 23 7E FE 09; +26D8: D2 18 73 E1 CD D0 72 FF CD D0 72 92 CD D0 72 EF DD 21 56 47 CD 1E 73 1B; +26F0: 14 15 C2 15 73 13 ED 53 3D F3 F1 C9 FB D0 DD 21 8B F3 FD 21 00 04 CD 63; +2708: 66 CD A9 6F CD EA 65 CA 09 73 22 64 F8 7B FE 04 28 07 01 01 00 ED 43 3D; +2720: F3 F1 F5 E5 D5 21 45 F3 BE D2 0C 73 01 25 00 5F 50 2A 53 F3 CD 1C 49 AF; +2738: 21 0C 00 09 77 D1 E1 23 71 23 70 23 77 23 72 23 23 77 CD 36 66 C5 D5 7A; +2750: 02 59 50 13 CD 5A 66 D1 C1 7B 20 1C E6 86 CA 12 73 D5 C5 59 50 CD 1D 46; +2768: A7 C2 AB 71 E1 CD FE 67 D1 2A 64 F8 73 F1 E1 C9 FE 08 28 45 FE 02 28 E1; +2780: FE 80 28 DD D5 C5 59 50 CD 62 44 E1 CD FE 67 D1 2A 64 F8 73 7B FE 04 28; +2798: DC E5 21 AE FC AF BE 77 E1 20 D2 01 06 00 09 E5 36 FF 2A 64 F8 CD 2A 68; +27B0: E1 2B 2B 2B 77 FE FF 20 BC 23 23 23 23 36 80 18 B4 C5 59 50 CD 62 44 E1; +27C8: E5 CD FE 67 2A 64 F8 36 01 01 06 00 09 36 FF 2A 64 F8 E5 CD 2A 68 E1 30; +27E0: F9 36 02 E1 01 21 00 09 0E 04 E5 37 7E 98 77 23 0D 20 F9 E1 0C 30 02 0E; +27F8: 04 CD 13 68 18 C1 01 0C 00 09 70 23 70 23 ED 4B 3D F3 71 23 70 01 11 00; +2810: 09 0E 05 70 23 0D 20 FB C9 DD 21 8B F3 FD 21 00 06 CD 63 66 CD 2A 68 C3; +2828: A0 66 E5 7E FE 01 C2 99 71 5D 54 23 23 23 7E A7 20 2C 23 23 23 34 7E 23; +2840: 23 23 20 1D E5 22 3D F2 EB 23 5E 23 56 21 00 01 CD B2 47 5D 54 25 7D B4; +2858: E1 28 06 E5 19 36 1A E1 AF 4F 06 00 09 7E 47 D6 1A D6 01 78 E1 23 23 23; +2870: 36 00 D0 77 C9 FB E5 3A 48 F3 87 21 08 00 30 02 2E 10 39 36 41 23 36 6E; +2888: E1 23 23 23 71 C9 DD 21 8B F3 FD 21 00 08 CD 63 66 7E FE 02 C2 99 71 F1; +28A0: F5 CD A7 68 C3 9F 66 E5 01 06 00 09 4E 34 23 23 23 09 77 E1 C0 E5 23 5E; +28B8: 23 56 01 04 00 09 7E 23 23 23 22 3D F2 A7 6F 60 20 01 24 CD 8F 71 E1 C9; +28D0: DD 21 8B F3 FD 21 00 04 CD 63 66 E1 7E D6 02 20 13 E5 21 AE FC BE 77 E1; +28E8: 20 0A 36 04 3E 1A CD A7 68 C4 B5 68 E5 23 5E 23 56 CD 6F 45 E1 E5 11 07; +2900: 00 19 72 6A 62 22 64 F8 E1 34 35 72 E1 C9 CD 80 73 E5 DD 21 F7 54 CD 1E; +2918: 73 3E FF CD C7 69 2A 76 F6 22 3D F2 EB 2A C2 F6 A7 ED 52 CD 8B 71 32 7C; +2930: F8 E1 DD 21 24 6B C3 1E 73 DD 21 9A 73 FD 21 00 02 CD 63 66 F1 CA 99 71; +2948: DD 21 1C 6C CD 1E 73 2A 53 F3 E5 CD FE 67 E1 E5 01 13 00 09 7E A7 C2 FD; +2960: 72 2B B6 C2 FD 72 2B 56 2B 5E 2A 76 F6 19 DA FD 72 01 93 00 09 DA FD 72; +2978: ED 72 D2 FD 72 EB E3 EB CD D0 69 2A 76 F6 22 3D F2 E1 2B CD B2 47 ED 5B; +2990: 76 F6 19 22 C2 F6 DD 21 53 42 CD 1E 73 3A 66 F8 A7 C0 32 7C F8 21 B9 69; +29A8: 11 68 F5 01 05 00 D5 ED B0 E1 DD 21 01 46 C3 1E 73 3A 92 00 00 00 E5 7D; +29C0: CD CB 69 E1 7C 18 04 ED 5B 53 F3 01 BE 47 18 03 01 B2 47 F5 21 01 00 39; +29D8: 22 3D F2 D5 CD E2 69 D1 F1 C9 21 01 00 C5 C9 D5 CD 6A 6B ED 53 BF FC D5; +29F0: CD 6A 6B ED 53 7D F8 E3 EB E7 DA 15 73 EB E3 CD; +2A00: DA 72 37 28 16 CD D0 72 2C FE 53 20 06 CD DB 72 A7 18 08 CD 6E 6B ED 53; +2A18: BF FC 37 C1 30 05 04 05 F2 15 73 D1 E5 C5 F5 AF 1E 02 DD 21 FA 6A CD 1E; +2A30: 73 3E FE CD C7 69 F1 E1 E5 F5 CD BE 69 2A 7D F8 CD BE 69 2A BF FC CD BE; +2A48: 69 F1 C1 F5 ED 43 3D F2 2A 7D F8 A7 ED 42 23 F1 30 13 CD 8B 71 3E FF 32; +2A60: AE FC AF DD 21 24 6B CD 1E 73 C3 F8 6E CD 65 71 E5 ED 5B BF FC E7 F5 4D; +2A78: 44 2A 7D F8 E5 09 22 7D F8 E1 ED 5B 3D F2 CD 59 00 F1 30 12 E1 E5 CD 8B; +2A90: 71 2A BF FC D1 A7 ED 52 22 BF FC EB 18 D2 E1 2A BF FC CD 8B 71 18 B6 D5; +2AA8: AF 32 BE FC 4F 47 CD DA 72 28 1D CD D0 72 2C FE 52 28 04 FE 53 20 0C 32; +2AC0: BE FC CD DB 72 28 09 CD D0 72 2C CD 6E 6B 42 4B D1 E5 C5 3E FF 32 AE FC; +2AD8: AF 1E 01 DD 21 FA 6A CD 1E 73 ED 5B 53 F3 CD D0 69 FE FE C2 99 71 C1 CD; +2AF0: 5C 6B E5 CD 5C 6B E5 CD 5C 6B 22 BF FC E1 C1 A7 ED 42 23 ED 43 3D F2 3A; +2B08: BE FC FE 53 28 0C CD B2 47 DD 21 FF 4A CD 1E 73 E1 C9 CD 65 71 E5 ED 5B; +2B20: BF FC E7 F5 ED 5B 53 F3 CD B2 47 F1 C1 C5 F5 2A 7D F8 E5 09 22 7D F8 D1; +2B38: 2A 3D F2 F1 30 10 CD 5C 00 2A BF FC D1 A7 ED 52 22 BF FC EB 18 CF C1 ED; +2B50: 4B BF FC CD 5C 00 AF 32 BE FC 18 B5 C5 CD D0 69 F5 CD D0 69 67 F1 6F C1; +2B68: 09 C9 CD D0 72 2C DD 21 0B 6F C3 1E 73 CD 80 73 CD DB 72 CD D0 72 28 CD; +2B80: C5 6B CD D0 72 29 E5 21 D6 3F 22 F8 F7 E1 3E 03 32 63 F6 A7 18 0B CD 80; +2B98: 73 CD C5 6B CD DA 72 C0 37 F5 E5 D5 59 CD 5D 50 3C CA 9C 71 D1 E1 F1 E5; +2BB0: 3E FF 32 46 F2 DD 7E 00 06 01 DD 4E 01 2A 51 F3 CD 44 01 E1 C9 DD 21 1C; +2BC8: 52 CD 1E 73 D5 CD D0 72 2C DD 21 2F 54 CD 1E 73 C1 C9 DD 21 8B F3 FD 21; +2BE0: 00 04 CD 63 66 7E FE 04 C2 99 71 23 5E 23 56 01 07 00 09 E3 CD DA 72 28; +2BF8: 30 D5 CD D0 72 2C DD 21 64 4C CD 1E 73 E5 CD FB 6D 79 B0 B5 B4 CA 15 73; +2C10: 79 B0 0B 20 01 2B EB E1 E3 E5 D5 11 21 00 19 D1 71 23 70 23 73 23 72 D1; +2C28: E1 E3 22 3D F2 E1 F1 E5 A7 21 03 73 01 B2 47 28 06 21 A8 71 01 BE 47 E5; +2C40: CD E2 69 A7 C0 E1 C3 F8 6E CD 80 73 FE 23 CC DB 72 DD 21 1C 52 CD 1E 73; +2C58: CA 18 73 E5 DD 21 6D 6A CD 1E 73 5D 54 CA 00 73 DA 15 73 7E FE 04 C2 99; +2C70: 71 23 7E 23 66 6F 01 0E 00 09 4E 23 46 ED 43 68 F5 21 00 00 22 6A F5 01; +2C88: 09 00 E1 EB 09 EB 7E FE 2C C0 D5 DD 21 1B 52 CD 1E 73 F5 CD D0 72 41 CD; +2CA0: D0 72 53 DD 21 A4 5E CD 1E 73 DD 21 97 55 CD 1E 73 C2 FA 72 F1 E3 D5 E5; +2CB8: 2A 6A F5 4F 06 00 09 22 6A F5 EB 2A 68 F5 E7 DA 06 73 D1 E1 71 23 73 23; +2CD0: 72 06 00 E1 18 B5 F6 37 CD 80 73 F5 DD 21 A4 5E CD 1E 73 DD 21 97 55 CD; +2CE8: 1E 73 C2 FA 72 D5 DD 21 5F 4C CD 1E 73 C1 E3 E5 C5 DD 21 D0 67 CD 1E 73; +2D00: 46 E3 7E 4F C5 E5 F5 23 5E 23 56 B7 28 5C 2A 62 F8 2B E7 38 33 2A C2 F6; +2D18: E7 38 2D 59 16 00 2A 74 F6 19 EB 2A 9B F6 E7 38 54 F1 79 DD 21 8E 66 CD; +2D30: 1E 73 E1 C1 E3 D5 C5 DD 21 D0 67 CD 1E 73 C1 D1 E3 C5 E5 23 F5 73 23 72; +2D48: F1 E1 23 5E 23 56 C1 E1 23 7E 23 66 6F 79 B8 30 01 47 90 4F F1 D4 74 6D; +2D60: 04 05 28 0B 7E 12 23 13 18 F7 C1 C1 C1 C1 C1 DC 74 6D E1 C9 3E 20 0C 0D; +2D78: C8 12 13 18 FA F1 E1 C1 E3 EB 20 25 C5 78 DD 21 27 66 CD 1E 73 11 98 F6; +2D90: 2A 78 F6 22 F8 F7 3E 03 32 63 F6 CD F3 2E 11 9B F6 E7 22 78 F6 CA F7 72; +2DA8: C1 E3 C5 E5 C3 2A 6D 3E 02 01 3E 04 01 3E 08 CD 80 73 F5 DD 21 7A 51 CD; +2DC0: 1E 73 F1 DD 21 27 66 CD 1E 73 2A 99 F6 CD 10 2F C3 F1 61 00 00 00 00 3E; +2DD8: 01 01 3E 03 01 3E 07 CD 80 73 F5 DD 21 D0 67 CD 1E 73 F1 BE D2 15 73 3C; +2DF0: 23 4E 23 66 69 32 63 F6 C3 08 2F DD 21 97 55 CD 1E 73 ED 4B F8 F7 21 00; +2E08: 00 F8 CA FA 72 21 F6 F7 11 FC F5 01 08 00 ED B0 21 68 6E 11 47 F8 0E 08; +2E20: ED B0 CD 9F 28 A7 CD D1 30 DD 21 32 54 CD 1E 73 D5 EB DD 21 FF 46 CD 1E; +2E38: 73 CD 42 30 01 45 65 11 53 60 CD 5C 32 21 F6 F7 11 47 F8 01 08 00 ED B0; +2E50: 21 FC F5 11 F6 F7 0E 08 ED B0 CD 8C 26 DD 21 32 54 CD 1E 73 4B 42 E1 C9; +2E68: 45 65 53 60 00 00 00 00 CD 80 73 E5 CD 2A 68 21 00 00 30 01 2B F5 CD 99; +2E80: 2F F1 E1 23 23 23 77 C9 CD 80 73 16 00 28 06 CD 80 6F E5 18 04 E5 CD FE; +2E98: 6F CD 63 6F 3A 16 F4 A7 F5 CD 45 66 CA 12 73 DD 21 23 73 CD 1E 73 21 B3; +2EB0: F5 06 0B 7E 23 DF 78 FE 04 20 08 7E FE 20 28 02 3E 2E DF 10 EE CD BD 00; +2EC8: F1 F5 3A B0 F3 47 3A 61 F6 28 05 06 50 3A 15 F4 A7 28 0F C6 0C B8 30 03; +2EE0: 3E 20 DF DD 21 28 73 D4 1E 73 11 68 F5 AF 32 74 F5 CD 06 50 3C 20 B7 F1; +2EF8: E1 DD 21 FF 4A C3 1E 73 CD 80 73 CD 96 6F CD DA 72 C0 CD EA 65 CA A2 71; +2F10: CD 63 6F E5 11 68 F5 CD 6C 43 A7 C2 12 73 E1 C9 CD 80 73 CD 96 6F CD EA; +2F28: 65 CA A2 71 CD 63 6F E5 CD 45 66 CA 12 73 E1 CD D0 72 41 CD D0 72 53 CD; +2F40: 96 6F 7A 32 78 F5 E5 2A 68 F5 A7 28 04 BD C2 B7 71 11 79 F5 CD 5A 66 11; +2F58: 68 F5 CD 92 43 A7 C2 A5 71 E1 C9 CD E3 65 3C 32 68 F5 E5 D5 CD 57 66 D1; +2F70: E1 C9 DD 21 0E 6A CD 1E 73 7A FE 09 D8 C3 9C 71 CD 72 6F E5 21 66 F8 06; +2F88: 0B 7E 23 FE 20 20 0B 10 F8 CD FE 6F 18 04 CD 72 6F E5 21 66 F8 06 08 CD; +2FA0: F5 6F 06 03 CD F5 6F E1 F6 37 D5 E5 11 66 F8 D5 06 0B C5 1A 21 CC 6F 01; +2FB8: 0D 00 38 01 0B ED B1 28 31 C1 13 10 ED E1 CD D9 6F E1 D1 C9 2E 22 2F 5C; +2FD0: 5B 5D 3A 2B 3D 3B 2C 2A 3F 3E 20 BE 28 14 06 07 CD E5 6F 06 03 23 BE 28; +2FE8: 03 10 FA C9 05 C8 23 BE 28 FA C3 0F 73 7E FE 2A 28 09 23 10 F8 C9 21 66; +3000: F8 06 0B 36 3F 23 10 FB C9 01 10 00 11 01 21 00 CD 80 73 C5 DD 21 1F 52; +3018: CD 1E 73 DD 21 6D 6A CD 1E 73 DA 15 73 CA 00 73 C1 23 5E 23 56 EB 09 4E; +3030: 23 46 23 5E 23 56 EB C5 DD 21 FF 46 CD 1E 73 01 45 65 11 53 60 CD 5C 32; +3048: 21 F6 F7 11 47 F8 01 08 00 ED B0 E1 DD 21 FF 46 CD 1E 73 CD 42 30 C3 9A; +3060: 26 CD 80 73 DD 21 1F 52 CD 1E 73 21 47 F3 BE 28 03 D2 9C 71 5F CD 5D 50; +3078: C3 99 2F CD 80 73 CD 80 6F CD EA 65 CA A2 71 CD 63 6F E5 3A 47 F2 3C 32; +3090: 8D F5 21 69 F5 11 8E F5 01 24 00 ED B0 E1 CD DA 72 28 20 CD D0 72 D9 CD; +30A8: 80 6F CD EA 65 CA A2 71 CD E3 65 3C 32 8D F5 E5 11 8E F5 CD 5A 66 E1 CD; +30C0: DA 72 C0 E5 CD 45 66 CA 12 73 CD BD 00 01 8D F5 11 D7 F5 21 B2 F5 3E 0C; +30D8: F5 0A FE 3F 20 01 7E 12 03 13 23 F1 3D 20 F1 21 B2 F5 11 D7 F5 06 0C 1A; +30F0: BE 20 07 23 13 10 F8 C3 15 73 CD 6C 71 E5 AF 32; +3100: BE F5 11 B2 F5 CD 62 44 11 D7 F5 CD 1D 46 A7 C2 AB 71 6F 67 22 D3 F5 22; +3118: D5 F5 22 F8 F5 22 FA F5 23 22 C0 F5 22 E5 F5 E1 E5 11 B2 F5 CD B2 47 7D; +3130: B4 28 09 11 D7 F5 CD 8F 71 E1 18 EC E1 2A C6 F5 22 EB F5 2A C8 F5 22 ED; +3148: F5 11 D7 F5 CD 6F 45 21 B2 F5 22 3D F2 11 68 F5 AF 32 74 F5 CD 06 50 3C; +3160: C2 CA 70 E1 C9 22 BF FC ED 43 7D F8 21 00 FE 39 30 0D ED 5B C6 F6 A7 ED; +3178: 52 38 04 7C A7 20 07 ED 5B 62 F8 21 00 01 ED 53 3D F2 C9 ED 5B 53 F3 CD; +3190: BE 47 A7 C8 18 12 1E 3C 01 1E 3D 01 1E 3E 01 1E 3F 01 1E 40 01 1E 41 01; +31A8: 1E 42 01 1E 43 01 1E 44 01 1E 45 01 1E 46 01 1E 47 01 00 00 AF 32 7C F8; +31C0: 32 AE FC D5 DD 21 24 6B CD 1E 73 D1 DD 21 6F 40 C3 1E 73 7B FE 3C D8 FE; +31D8: 48 D0 D6 3B 47 21 F5 71 7E A7 23 20 FB 10 F9 2B 11 04 F6 D5 01 16 00 ED; +31F0: B0 1E 01 E1 C9 00 42 61 64 20 46 41 54 00 42 61 64 20 66 69 6C 65 20 6D; +3208: 6F 64 65 00 42 61 64 20 64 72 69 76 65 20 6E 61 6D 65 00 42 61 64 20 73; +3220: 65 63 74 6F 72 20 6E 75 6D 62 65 72 00 46 69 6C 65 20 73 74 69 6C 6C 20; +3238: 6F 70 65 6E 00 46 69 6C 65 20 61 6C 72 65 61 64 79 20 65 78 69 73 74 73; +3250: 00 44 69 73 6B 20 66 75 6C 6C 00 54 6F 6F 20 6D 61 6E 79 20 66 69 6C 65; +3268: 73 00 44 69 73 6B 20 77 72 69 74 65 20 70 72 6F 74 65 63 74 65 64 00 44; +3280: 69 73 6B 20 49 2F 4F 20 65 72 72 6F 72 00 44 69 73 6B 20 6F 66 66 6C 69; +3298: 6E 65 00 52 65 6E 61 6D 65 20 61 63 72 6F 73 73 20 64 69 73 6B 00 B0 72; +32B0: CB 79 C2 96 71 CB 81 06 00 21 C2 72 09 7E 23 66 6F E9 AE 71 B4 71 B1 71; +32C8: B1 71 B1 71 B1 71 B1 71 CD DA 72 E3 BE 20 41 23 E3 23 2B DD 21 66 46 18; +32E0: 3D 00 00 00 3E C9 32 D5 FE ED 5B 4A FC ED 53 49 F3 C9 F7 00 E4 72 C9 1E; +32F8: 10 01 1E 0D 01 1E 07 01 1E 3B 01 1E 37 01 1E 32 01 1E 36 01 1E 34 01 1E; +3310: 38 01 1E 35 01 1E 05 01 1E 02 DD 21 6F 40 CD 59 01 FB C9 FB E5 D5 3A 48; +3328: F3 87 21 10 00 30 02 2E 18 39 5E 23 56 E5 21 95 6E E7 E1 28 0D E5 21 C9; +3340: 6E E7 E1 20 0B 11 77 F3 18 03 11 7A F3 72 2B 73 D1 E1 7B FE 02 D8 7E FE; +3358: 3A 28 B4 23 7E FE 3A 2B C0 CD 80 73 7E E6 DF D6 40 E5 21 47 F3 BE E1 28; +3370: 03 D2 9C 71 23 23 1D 1D D5 1C D1 C9 FB 3E 00 C9 FB E5 F5 3A 48 F3 87 21; +3388: 0C 00 30 02 2E 14 39 36 8B 23 36 F3 F1 E1 C9 CD 6B F3 1A CD 68 F3 13 FE; +33A0: 24 C8 CD A8 53 18 F0 CD 6B F3 ED B0 CD 68 F3 C9 CD 6B F3 C3 00 00 11 DE; +33B8: F1 D5 5E 23 56 EB CD 6B F3 E9 C3 04 56 50 52 4E 20 4C 53 54 20 4E 55 4C; +33D0: 20 41 55 58 20 43 4F 4E 20 20 20 20 20 20 20 20 20 20 20 20 80 00 00 00; +33E8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1F 1C 1F 1E 1F 1E 1F; +3400: 1F 1E 1F 1E 1F F8 00 02 0F 04 01 02 01 00 02 70 0C 00 63 01 02 05 00 F9; +3418: 00 02 0F 04 01 02 01 00 02 70 0E 00 CA 02 03 07 00 FA 00 02 0F 04 01 02; +3430: 01 00 02 70 0A 00 3C 01 01 03 00 FB 00 02 0F 04 01 02 01 00 02 70 0C 00; +3448: 7B 02 02 05 00 FB D2 CE 75 F5 3A 0D F3 B7 18 1A F1 F5 C5 D5 E5 CD 98 74; +3460: E1 D1 C1 38 09 CD 2C 78 F1 CD 66 75 18 08 FD E1 18 04 F1 CD 98 74 FB CD; +3478: D4 FF F5 0E 32 30 02 0E 00 CD 2C 78 DD 36 00 96 DD 7E 03 A7 20 05 DD 71; +3490: 01 F1 C9 DD 71 02 F1 C9 CD D6 76 D8 CD CF FF F3 CB 7C 20 29 CD 92 7D CD; +34A8: 2D 7D D8 04 05 C8 CD CF FF F3 CB 7C 20 17 E5 D5 C5 ED 5B 4D F3 D5 01 00; +34C0: 02 CD 6E F3 E1 C1 D1 CD D8 74 E1 18 03 CD D8 74 D8 05 C8 CD A1 77 18 C8; +34D8: 1E 0B CD F4 77 3E A0 CB 72 28 08 F6 02 CB 42 28 02 F6 08 E5 D5 C5 11 04; +34F0: 75 D5 01 FF 7F 32 F8 7F 0A 87 F0 38 FB 7E 32 FB 7F 23 18 F4 C1 D1 E1 3A; +3508: F8 7F E6 FC 20 0D CB 7C 20 51 05 28 4E CD A1 77 C3 00 00 CB 77 20 26 F5; +3520: CD DB 77 F1 1D 20 B3 37 5F CB 7B 3E 02 20 34 CB 6B 3E 0A 20 2E CB 63 3E; +3538: 08 20 28 CB 5B 3E 04 20 22 3E 0C 18 1E 3E 80 32 F8 7F 21 FF 7F 11 00 00; +3550: 7E 07 38 0D 07 30 0A 1B 7B B2 20 F4 3E 02 37 18 02 AF 37 C9 00 00 CD D6; +3568: 76 D8 CD CF FF F3 CB 7C 20 4F CD AA 7D 1E 80 CD 2D 7D D8 04 05 C8 CD CF; +3580: FF F3 CB 7C 20 3B E5 D5 C5 ED 5B 4D F3 15 15 01 00 02 CD 6E F3 C1 D1 D5; +3598: C5 2A 4D F3 1E 0B CD 1F 76 38 18 2A 4D F3 54 5D 15 15 01 00 02 1A ED A1; +35B0: 20 06 13 EA AD 75 18 03 3E 0A 37 C1 D1 E1 D8 18 06 1E 80 CD 1F 76 D8 05; +35C8: C8 CD A1 77 18 A0 CD D4 75 C3 76 74 CD D6 76 D8 CD CF FF F3 CB 7C 20 32; +35E0: CD CD 7D 1E 0B CD 2D 7D D8 04 05 C8 CD CF FF F3 CB 7C 20 1E E5 2A 4D F3; +35F8: 1E 0B CD 1F 76 E1 D8 E5 D5 C5 EB 2A 4D F3 01 00 02 CD 6E F3 C1 D1 E1 A7; +3610: 18 06 1E 0B CD 1F 76 D8 05 C8 CD A1 77 18 BD CD F4 77 3E 80 CB 72 28 08; +3628: F6 02 CB 42 28 02 F6 08 E5 D5 C5 01 6E 76 C5 01 FF 7F CB 7B 20 68 32 F8; +3640: 7F 11 00 5D 0A 87 30 1B F0 1D 20 F8 0A 87 30 13 F0 15 20 F0 C1 C1 D1 E1; +3658: 3E 02 37 C3 A3 76 0A 87 F0 38 FB 3A FB 7F 77 23 18 F4 00 00 00 00 C1 D1; +3670: E1 3A F8 7F E6 9C 20 0D CB 7C 20 27 05 28 24 CD A1 77 C3 00 00 F5 CD DB; +3688: 77 F1 1D 20 92 37 5F CB 7B 3E 02 20 0E CB 63 3E 08 20 08 CB 5B 3E 04 20; +36A0: 02 3E 0C C9 00 00 32 F8 7F 11 00 5D 0A 87 30 1B F0 1D 20 F8 0A 87 30 13; +36B8: F0 15 20 F0 C1 C1 D1 E1 3E 02 37 C3 A3 76 0A 87 F0 38 FB 3A FB 7F BE 23; +36D0: 28 F4 3E 0A 18 EA F5 C5 E5 CD C2 5F E1 C1 F1 FE 02 38 04 3E 0C 37 C9 F5; +36E8: 79 FE F8 38 04 FE FC 38 03 F1 18 EF E3 E5 C5 CD F4 77 CB 49 4B 42 11 08; +3700: 00 20 01 1C CD 2F 49 7D 3C 32 FA 7F 69 C1 F1 67 AF CB 41 28 05 CB 3D 30; +3718: 01 3C 32 FC 7F 57 DD 7E 07 3D 28 01 7C F6 C4 F5 79 0F 0F E6 C0 B2 57 4D; +3730: DD 7E 07 3D 28 23 DD 7E 03 BC 28 34 EE 01 DD 77 03 3A F9 7F 28 08 DD 77; +3748: 04 DD 7E 05 18 06 DD 77 05 DD 7E 04 32 F9 7F 18 17 DD 7E 06 BC DD 74 06; +3760: 28 0E DD E5 D5 C5 CD 22 78 CD 5A 62 C1 D1 DD E1 F1 C5 F5 F3 DD 7E 00 47; +3778: F1 32 FD 7F DD 36 00 FF FB 3A F9 7F B9 C4 E1 77 78 A7 20 07 06 64 CD 96; +3790: 77 10 FB C1 E1 C9 E5 21 A6 04 2B 7C B5 20 FB E1 C9 CD F4 77 24 24 3A FA; +37A8: 7F 3C 32 FA 7F CB 7A 20 03 FE 0A D8 FE 09 D8 3E 01 32 FA 7F CB 72 28 0B; +37C0: CB 42 20 07 CB C2 32 FC 7F 18 0F CB 82 AF 32 FC 7F 0C CD F4 77 3E 50 32; +37D8: F8 7F C9 CB 43 C0 CD FB 77 CD F4 77 79 B7 28 1A 32 FB 7F E3 E3 3E 10 32; +37F0: F8 7F 18 16 3A F8 7F 1F 38 FA C9 3A F9 7F B7 CC; +3800: 15 78 CD F4 77 3E 00 32 F8 7F E5 21 C3 09 2B 7C B5 20 FB E1 C9 C5 0E 04; +3818: CD E1 77 C1 C9 CD 2C 78 18 04 DD 36 00 00 3E 03 32 FD 7F C9 3E D0 32 F8; +3830: 7F E3 E3 E3 E3 3A FB 7F 3A F8 7F C9 C5 F5 CD C2 5F F1 F5 28 17 3E C5 32; +3848: FD 7F CD FB 77 21 CA 76 3A F8 7F E6 04 20 09 2B 7C B5 20 F4 2E 01 18 05; +3860: 2E 02 CD 7A 78 3E C4 32 FD 7F CD 7A 78 DD 75 07 CD 26 78 F1 28 02 2E 02; +3878: C1 C9 D5 CB AA CD FB 77 CD FB 77 CD FB 77 D1 C9 CD C2 5F 06 07 AF 77 23; +3890: 10 FC 21 98 78 C3 F6 5F F5 CD C2 5F 7E A7 28 08 FE FF 28 07 3D 77 20 03; +38A8: CD 26 78 23 7E A7 28 01 35 23 7E A7 28 01 35 F1 C3 27 60 FB E5 C5 F5 CD; +38C0: C2 5F F1 C1 E1 A7 DD 46 02 20 03 DD 46 01 04 05 06 01 C0 C5 E5 11 01 00; +38D8: 2A 4D F3 F5 CD 4D 74 38 18 F1 2A 4D F3 46 E1 C5 CD FD 78 3E 0A 38 0B F1; +38F0: C1 B9 37 3F 06 FF C0 04 C9 D1 D1 D1 C9 EB 13 78 D6 F8 D8 FE 04 30 14 07; +3908: 4F 06 00 6F 60 29 29 29 09 01 05 74 09 01 12 00 ED B0 C9 3E 0A 37 C9 00; +3920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0D 0A 31 20 2D 20 53; +3938: 69 6E 67 6C 65 20 73 69 64 65 64 2C 20 38 30 20 74 72 61 63 6B 73 0D 0A; +3950: 32 20 2D 20 44 6F 75 62 6C 65 20 73 69 64 65 64 2C 20 38 30 20 74 72 61; +3968: 63 6B 73 0D 0A 00 21 31 79 C9 00 00 00 00 00 00 00 00 00 00 00 00 00 00; +3980: 00 00 E5 21 A8 E4 09 E1 38 13 37 3E 0E C9 E1 37 3E 0C C9 D1 C1 E1 C3 76; +3998: 74 C1 C3 76 74 F5 E5 CD C2 5F E1 F1 B7 28 E8 FE 03 30 E4 3D 28 11 01 F9; +39B0: 50 18 0F 00 00 00 00 00 00 00 00 00 00 00 00 01 F8 50 E5 CB 41 28 42 C5; +39C8: D5 7A 11 00 00 C5 CD D6 76 C1 CB B9 CD 4E 7A CD D8 7B 38 B7 D1 D5 7A 11; +39E0: 09 00 C5 CD D6 76 C1 CB F9 CD 4E 7A CD D8 7B 38 A2 CD 2C 78 2A 4D F3 01; +39F8: F9 01 D1 7A D5 11 00 00 B7 CD 4D 74 D1 C1 DA 8E 79 E1 C5 7A F5 11 00 00; +3A10: CD D6 76 F1 C1 CD AD 7A F5 CB B9 CD 4E 7A CD D8 7B DA 99 79 CB 41 28 0E; +3A28: CD 4E 7A CB F9 CD 8E 7A CD D8 7B DA 99 79 CB AA CD D2 77 10 DC CD FB 77; +3A40: CB F9 F1 C3 C0 7A 79 07 E6 01 32 FC 7F C9 C5 E5 EB 21 AC 7B CD 79 7B 06; +3A58: 09 C5 21 B7 7B CD 79 7B C1 10 F6 E1 E5 01 8A 00 09 11 74 02 06 09 3A F9; +3A70: 7F 77 19 10 FC 01 8C 00 E1 E5 09 E5 FD E1 21 A4 7A 06 09 7E FD 77 00 FD; +3A88: 19 23 10 F7 E1 C1 C5 E5 11 8B 00 19 11 74 02 06 09 79 07 E6 01 77 19 10; +3AA0: FC E1 C1 C9 01 02 03 04 05 06 07 08 09 E5 C5 11 8E 16 19 54 5D 13 36 4E; +3AB8: 01 FF 03 ED B0 C1 E1 C9 CD 65 7B C5 21 37 7E ED 5B 4D F3 01 C4 00 ED B0; +3AD0: C1 CD 86 7B C5 06 01 11 00 00 67 E5 2A 4D F3 37 CD 4D 74 E1 C1 D8 CD 1C; +3AE8: 7B D8 3E 09 93 47 C5 D5 06 01 7C E5 2A 4D F3 37 CD 4D 74 E1 D1 13 C1 D8; +3B00: 10 EC CB 41 C8 06 05 C5 D5 7C E5 2A 4D F3 06 01 37 CD 4D 74 E1 D1 13 C1; +3B18: D8 10 EC C9 06 02 11 01 00 CD 65 7B C5 D5 7C E5 2A 4D F3 71 23 36 FF 23; +3B30: 36 FF 06 01 2B 2B 37 CD 4D 74 E1 CD 65 7B D1 13 C1 D8 C5 06 01 CB 41 28; +3B48: 01 04 C5 06 01 D5 7C E5 2A 4D F3 37 CD 4D 74 E1 D1 13 C1 38 06 10 EB C1; +3B60: 10 C2 C9 C1 C9 C5 D5 E5 2A 4D F3 54 5D 13 01 FF 01 36 00 ED B0 E1 D1 C1; +3B78: C9 7E 23 FE FF C8 46 23 12 13 10 FC 18 F3 CB 41 C8 C5 11 9C 7B 2A 4D F3; +3B90: 01 0D 00 09 EB 01 10 00 ED B0 C1 C9 02 01 00 02 70 00 A0 05 F9 03 00 09; +3BA8: 00 02 00 00 4E 50 00 0C F6 03 FC 01 4E 1A FF 00 0C F5 03 FE 01 00 01 00; +3BC0: 01 01 01 02 01 F7 01 4E 18 00 0C F5 03 FB 01 E5 00 E5 00 F7 01 4E 36 FF; +3BD8: CD 46 7A 1E 0B C5 D5 E5 CD F4 77 CD 0A 78 CD CF FF F3 11 1D 7C D5 01 FF; +3BF0: 7F 11 00 00 3E F0 32 F8 7F 0A 87 30 19 F0 1D 20 F8 0A 87 30 11 F0 15 20; +3C08: F0 C1 3E 10 37 E1 D1 C1 C9 0A 87 F0 38 FB 7E 32 FB 7F 23 18 F4 E1 D1 C1; +3C20: 3A F8 7F E6 FC 28 1B CB 77 C2 45 75 F5 3A F9 7F 4F CD DB 77 F1 1D 20 A5; +3C38: 37 5F CB 7B 3E 10 C0 C3 2F 75 3A 0D F3 B7 C8 E5 D5 C5 16 00 79 E6 01 0F; +3C50: 0F B2 57 CD 46 7A B2 57 06 09 3A F9 7F 4F 3E 01 32 FA 7F CD D8 75 C1 D1; +3C68: E1 C9 37 C9 61 00 40 01 75 00 8B 00 A7 00 27 01 9C 00 ED 00 9F 00 26 00; +3C80: EA 00 3C 00 ED 00 40 01 1E 01 40 01 2A 01 47 01 2D 01 40 01 4E 01 40 01; +3C98: 4B 01 61 01 64 01 2D 01 00 00 7C 00 79 00 85 00 8E 00 CE 00 D1 00 F2 00; +3CB0: F6 00 05 01 12 01 1A 01 23 01 34 01 3B 01 40 01 53 01 47 01 00 00 5F 00; +3CC8: 39 01 73 00 AE 00 C6 00 20 01 BF 00 E6 00 C2 00 26 00 E3 00 3C 00 9B 00; +3CE0: E3 00 E6 00 39 01 17 01 39 01 23 01 40 01 26 01 39 01 47 01 39 01 44 01; +3CF8: 5A 01 5D 01 26 01 00 00 77 00 7E 00 A3 00 B1 00 EB 00 EF 00 FE 00 0B 01; +3D10: 13 01 1C 01 2D 01 34 01 39 01 4C 01 40 01 00 00 ED 5B 4D F3 21 33 7D 01; +3D28: 5F 00 ED B0 C9 E5 2A 4D F3 E3 C9 E5 D5 C5 CD 2D 40 2A 4D F3 11 50 00 19; +3D40: 77 26 80 CD 24 00 FB CD D4 FF 3A 42 F3 26 40 CD 24 00 C1 D1 E1 CD CF FF; +3D58: F3 2B 7C C6 02 23 07 3F 30 0D FD 2A 4D F3 D5 11 5F 00 FD 19 D1 FD E9 E5; +3D70: D5 C5 F5 3A 43 F3 26 80 CD 24 00 CD 68 F3 FB CD D4 FF 3E 00 26 40 CD 24; +3D88: 00 FB CD D4 FF F1 C1 D1 E1 C9 E5 D5 C5 CD 20 7D FD 21 6C 7C 21 D8 74 01; +3DA0: 8E 00 ED B0 D5 11 EA 00 18 39 E5 D5 C5 CD CD 7D 2A 4D F3 01 A6 00 09 11; +3DB8: CE 76 EB 01 08 00 ED B0 2A 4D F3 01 7D 00 09 36 00 C1 D1 E1 C9 E5 D5 C5; +3DD0: CD 20 7D FD 21 C6 7C 21 1F 76 01 87 00 ED B0 D5 11 E3 00 2A 4D F3 19 36; +3DE8: C3 D1 21 A1 77 01 7C 00 ED B0 FD 5E 00 FD 56 01 7A B3 28 31 2A 4D F3 19; +3E00: 23 E5 FD 5E 02 FD 56 03 2A 4D F3 19 EB E1 73 23 72 FD 23 FD 23 FD 23 FD; +3E18: 23 18 D7 FD 5E 00 FD 56 01 7A B3 28 0E 2A 4D F3 19 23 23 36 BF FD 23 FD; +3E30: 23 18 E8 C1 D1 E1 C9 EB FE 90 56 47 20 38 32 34 35 20 00 02 02 01 00 02; +3E48: 70 00 D0 02 F8 02 00 09 00 01 00 00 00 D0 ED 53 59 C0 32 C4 C0 36 56 23; +3E60: 36 C0 31 1F F5 11 79 C0 0E 0F CD 7D F3 3C CA 63 C0 11 00 01 0E 1A CD 7D; +3E78: F3 21 01 00 22 87 C0 21 00 3F 11 79 C0 0E 27 CD 7D F3 C3 00 01 58 C0 CD; +3E90: 00 00 79 E6 FE FE 02 C2 6A C0 3A C4 C0 A7 CA 22 40 11 9E C0 0E 09 CD 7D; +3EA8: F3 0E 07 CD 7D F3 18 B2 00 4D 53 58 44 4F 53 20 20 53 59 53 00 00 00 00; +3EC0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 42 6F 6F; +3ED8: 74 20 65 72 72 6F 72 0D 0A 50 72 65 73 73 20 61 6E 79 20 6B 65 79 20 66; +3EF0: 6F 72 20 72 65 74 72 79 0D 0A 24 00 76 20 31 2E; +3F00: 30 35 1A FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +3F18: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +3F30: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +3F48: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +3F60: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +3F78: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +3F90: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +3FA8: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +3FC0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +3FD8: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF; +3FF0: FF FF FF FF FF FF FF FF 24 00 06 00 B2 F0 B2 E2; +END; diff --git a/rtl/sdram.sv b/rtl/sdram.sv index 064b10d..062fdf0 100644 --- a/rtl/sdram.sv +++ b/rtl/sdram.sv @@ -1,236 +1,236 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Simple SDRAM controller with universal 8/16 bit mode -// -// Copyright (c) 2015-2019, Alexey Melnikov -// Copyright (c) 2013, Mike Field -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ -// Implementation using Micron MT48LC16M16A2 – 4 Meg x 16 x 4 banks SDR SDRAM -//------------------------------------------------------------------------------ - -module sdram - ( - input init, // Reset to initialize RAM - input clk, // Clock ~100MHz - // SDRAM signals - inout reg [15:0] SDRAM_DQ, // 16 bit bidirectional data bus - output reg [12:0] SDRAM_A, // 13 bit multiplexed address bus - output reg SDRAM_DQML, // Lower Input/Output Mask - output reg SDRAM_DQMH, // Upper Input/Output Mask - output reg [1:0] SDRAM_BA, // Two banks - output SDRAM_nCS, // A single chip select - output SDRAM_nWE, // Write enable - output SDRAM_nRAS, // Row address select - output SDRAM_nCAS, // Columns address select - output SDRAM_CKE, // Clock enable - output SDRAM_CLK, // SDRAM Clock - // User Interface - input [24:0] addr, // 25 bit address for 8bit mode. addr[0] = 0 for 16bit mode for correct operations. - output [7:0] dout, // Data output to cpu - input [7:0] din, // Data input from cpu - input we, // Cpu requests write - input rd, // Cpu requests read - output reg ready // Dout is valid. Ready to accept new read/write. - ); - - assign SDRAM_CKE = 1; - assign SDRAM_nCS = 0; - assign SDRAM_nRAS = command[2]; - assign SDRAM_nCAS = command[1]; - assign SDRAM_nWE = command[0]; - assign {SDRAM_DQMH,SDRAM_DQML} = SDRAM_A[12:11]; - - // no burst configured - localparam BURST_LENGTH = 3'b000; // 000=1, 001=2, 010=4, 011=8 - localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved - localparam CAS_LATENCY = 3'd2; // 2 for < 100MHz, 3 for >100MHz - 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}; - - localparam sdram_startup_cycles = 14'd12100;// 100us, plus a little more, @ 100MHz - localparam cycles_per_refresh = 14'd780; // (64000*100)/8192-1 Calc'd as (64ms @ 100MHz)/8192 rose - localparam startup_refresh_max = 14'b11111111111111; - - // SDRAM commands - wire [2:0] CMD_NOP = 3'b111; - wire [2:0] CMD_ACTIVE = 3'b011; - wire [2:0] CMD_READ = 3'b101; - wire [2:0] CMD_WRITE = 3'b100; - wire [2:0] CMD_PRECHARGE = 3'b010; - wire [2:0] CMD_AUTO_REFRESH = 3'b001; - wire [2:0] CMD_LOAD_MODE = 3'b000; - - reg [13:0] refresh_count = startup_refresh_max - sdram_startup_cycles; - reg [2:0] command; - reg [24:0] save_addr; - - reg [15:0] data; - assign dout = save_addr[0] ? data[15:8] : data[7:0]; - - typedef enum { - STATE_STARTUP, - STATE_OPEN_1, STATE_OPEN_2, - STATE_IDLE, STATE_IDLE_1, STATE_IDLE_2, STATE_IDLE_3, - STATE_IDLE_4, STATE_IDLE_5, STATE_IDLE_6, STATE_IDLE_7 - } state_t; - - always @(posedge clk) begin - reg old_we, old_rd; - reg [CAS_LATENCY:0] data_ready_delay; - - reg [7:0] new_data; - reg new_we; - reg new_rd; - reg save_we = 1'b1; - - state_t state = STATE_STARTUP; - - SDRAM_DQ <= 16'bZ; - command <= CMD_NOP; - refresh_count <= refresh_count+1'b1; - - data_ready_delay <= {1'b0, data_ready_delay[CAS_LATENCY:1]}; - - if(data_ready_delay[0]) - {ready, data} <= {1'b1, SDRAM_DQ}; - - case(state) - STATE_STARTUP: begin - SDRAM_A <= 0; - SDRAM_BA <= 0; - - if (refresh_count == startup_refresh_max-31) begin - command <= CMD_PRECHARGE; - SDRAM_A[10] <= 1; // all banks - SDRAM_BA <= 2'b00; - end - if (refresh_count == startup_refresh_max-23) begin - command <= CMD_AUTO_REFRESH; - end - if (refresh_count == startup_refresh_max-15) begin - command <= CMD_AUTO_REFRESH; - end - if (refresh_count == startup_refresh_max-7) begin - command <= CMD_LOAD_MODE; - SDRAM_A <= MODE; - end - - if(!refresh_count) begin - state <= STATE_IDLE; - ready <= 1; - refresh_count <= 0; - end - end - - STATE_IDLE_7: begin state <= STATE_IDLE_6; end - STATE_IDLE_6: begin state <= STATE_IDLE_5; end - STATE_IDLE_5: begin state <= STATE_IDLE_4; end - STATE_IDLE_4: begin state <= STATE_IDLE_3; end - STATE_IDLE_3: begin state <= STATE_IDLE_2; end - STATE_IDLE_2: begin state <= STATE_IDLE_1; end - STATE_IDLE_1: begin - state <= STATE_IDLE; - // mask possible refresh to reduce colliding. - if(refresh_count > cycles_per_refresh) begin - state <= STATE_IDLE_7; - command <= CMD_AUTO_REFRESH; - refresh_count <= 0; - end - end - - STATE_IDLE: begin - // Priority is to issue a refresh if one is outstanding - if(refresh_count > (cycles_per_refresh<<1)) - state <= STATE_IDLE_1; - else if(new_rd | new_we) begin - new_we <= 0; - new_rd <= 0; - save_addr <= addr; - save_we <= new_we; - state <= STATE_OPEN_1; - command <= CMD_ACTIVE; - SDRAM_A <= addr[13:1]; - SDRAM_BA <= addr[24:23]; - end - end - - STATE_OPEN_1: begin state <= STATE_OPEN_2; end - - STATE_OPEN_2: begin - SDRAM_A <= {save_we & ~save_addr[0], save_we & save_addr[0], 2'b10, save_addr[22:14]}; - if(save_we) begin - command <= CMD_WRITE; - SDRAM_DQ <= {new_data[7:0], new_data[7:0]}; - ready <= 1; - state <= STATE_IDLE_2; - end - else begin - command <= CMD_READ; - data_ready_delay[CAS_LATENCY] <= 1; - state <= STATE_IDLE_5; - end - end - endcase - - if(init) begin - state <= STATE_STARTUP; - refresh_count <= startup_refresh_max - sdram_startup_cycles; - end - - old_we <= we; - if(we & ~old_we) begin - {ready, new_we, new_data} <= {1'b0, 1'b1, din}; - end - - old_rd <= rd; - if(rd & ~old_rd) begin - if(ready & ~save_we & (save_addr[24:1] == addr[24:1])) begin - save_addr <= addr; - end - else begin - {ready, new_rd} <= {1'b0, 1'b1}; - end - end - end - - altddio_out #( - .extend_oe_disable ( "OFF" ), - .intended_device_family ( "Cyclone V" ), - .invert_output ( "OFF" ), - .lpm_hint ( "UNUSED" ), - .lpm_type ( "altddio_out" ), - .oe_reg ( "UNREGISTERED" ), - .power_up_high ( "OFF" ), - .width ( 1 ) - ) sdramclk_ddr ( - .datain_h ( 1'b0 ), - .datain_l ( 1'b1 ), - .outclock ( clk ), - .dataout ( SDRAM_CLK ), - .aclr ( 1'b0 ), - .aset ( 1'b0 ), - .oe ( 1'b1 ), - .outclocken ( 1'b1 ), - .sclr ( 1'b0 ), - .sset ( 1'b0 ) - ); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Simple SDRAM controller with universal 8/16 bit mode +// +// Copyright (c) 2015-2019, Alexey Melnikov +// Copyright (c) 2013, Mike Field +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ +// Implementation using Micron MT48LC16M16A2 – 4 Meg x 16 x 4 banks SDR SDRAM +//------------------------------------------------------------------------------ + +module sdram + ( + input init, // Reset to initialize RAM + input clk, // Clock ~100MHz + // SDRAM signals + inout reg [15:0] SDRAM_DQ, // 16 bit bidirectional data bus + output reg [12:0] SDRAM_A, // 13 bit multiplexed address bus + output reg SDRAM_DQML, // Lower Input/Output Mask + output reg SDRAM_DQMH, // Upper Input/Output Mask + output reg [1:0] SDRAM_BA, // Two banks + output SDRAM_nCS, // A single chip select + output SDRAM_nWE, // Write enable + output SDRAM_nRAS, // Row address select + output SDRAM_nCAS, // Columns address select + output SDRAM_CKE, // Clock enable + output SDRAM_CLK, // SDRAM Clock + // User Interface + input [24:0] addr, // 25 bit address for 8bit mode. addr[0] = 0 for 16bit mode for correct operations. + output [7:0] dout, // Data output to cpu + input [7:0] din, // Data input from cpu + input we, // Cpu requests write + input rd, // Cpu requests read + output reg ready // Dout is valid. Ready to accept new read/write. + ); + + assign SDRAM_CKE = 1; + assign SDRAM_nCS = 0; + assign SDRAM_nRAS = command[2]; + assign SDRAM_nCAS = command[1]; + assign SDRAM_nWE = command[0]; + assign {SDRAM_DQMH,SDRAM_DQML} = SDRAM_A[12:11]; + + // no burst configured + localparam BURST_LENGTH = 3'b000; // 000=1, 001=2, 010=4, 011=8 + localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved + localparam CAS_LATENCY = 3'd2; // 2 for < 100MHz, 3 for >100MHz + 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}; + + localparam sdram_startup_cycles = 14'd12100;// 100us, plus a little more, @ 100MHz + localparam cycles_per_refresh = 14'd780; // (64000*100)/8192-1 Calc'd as (64ms @ 100MHz)/8192 rose + localparam startup_refresh_max = 14'b11111111111111; + + // SDRAM commands + wire [2:0] CMD_NOP = 3'b111; + wire [2:0] CMD_ACTIVE = 3'b011; + wire [2:0] CMD_READ = 3'b101; + wire [2:0] CMD_WRITE = 3'b100; + wire [2:0] CMD_PRECHARGE = 3'b010; + wire [2:0] CMD_AUTO_REFRESH = 3'b001; + wire [2:0] CMD_LOAD_MODE = 3'b000; + + reg [13:0] refresh_count = startup_refresh_max - sdram_startup_cycles; + reg [2:0] command; + reg [24:0] save_addr; + + reg [15:0] data; + assign dout = save_addr[0] ? data[15:8] : data[7:0]; + + typedef enum { + STATE_STARTUP, + STATE_OPEN_1, STATE_OPEN_2, + STATE_IDLE, STATE_IDLE_1, STATE_IDLE_2, STATE_IDLE_3, + STATE_IDLE_4, STATE_IDLE_5, STATE_IDLE_6, STATE_IDLE_7 + } state_t; + + always @(posedge clk) begin + reg old_we, old_rd; + reg [CAS_LATENCY:0] data_ready_delay; + + reg [7:0] new_data; + reg new_we; + reg new_rd; + reg save_we = 1'b1; + + state_t state = STATE_STARTUP; + + SDRAM_DQ <= 16'bZ; + command <= CMD_NOP; + refresh_count <= refresh_count+1'b1; + + data_ready_delay <= {1'b0, data_ready_delay[CAS_LATENCY:1]}; + + if(data_ready_delay[0]) + {ready, data} <= {1'b1, SDRAM_DQ}; + + case(state) + STATE_STARTUP: begin + SDRAM_A <= 0; + SDRAM_BA <= 0; + + if (refresh_count == startup_refresh_max-31) begin + command <= CMD_PRECHARGE; + SDRAM_A[10] <= 1; // all banks + SDRAM_BA <= 2'b00; + end + if (refresh_count == startup_refresh_max-23) begin + command <= CMD_AUTO_REFRESH; + end + if (refresh_count == startup_refresh_max-15) begin + command <= CMD_AUTO_REFRESH; + end + if (refresh_count == startup_refresh_max-7) begin + command <= CMD_LOAD_MODE; + SDRAM_A <= MODE; + end + + if(!refresh_count) begin + state <= STATE_IDLE; + ready <= 1; + refresh_count <= 0; + end + end + + STATE_IDLE_7: begin state <= STATE_IDLE_6; end + STATE_IDLE_6: begin state <= STATE_IDLE_5; end + STATE_IDLE_5: begin state <= STATE_IDLE_4; end + STATE_IDLE_4: begin state <= STATE_IDLE_3; end + STATE_IDLE_3: begin state <= STATE_IDLE_2; end + STATE_IDLE_2: begin state <= STATE_IDLE_1; end + STATE_IDLE_1: begin + state <= STATE_IDLE; + // mask possible refresh to reduce colliding. + if(refresh_count > cycles_per_refresh) begin + state <= STATE_IDLE_7; + command <= CMD_AUTO_REFRESH; + refresh_count <= 0; + end + end + + STATE_IDLE: begin + // Priority is to issue a refresh if one is outstanding + if(refresh_count > (cycles_per_refresh<<1)) + state <= STATE_IDLE_1; + else if(new_rd | new_we) begin + new_we <= 0; + new_rd <= 0; + save_addr <= addr; + save_we <= new_we; + state <= STATE_OPEN_1; + command <= CMD_ACTIVE; + SDRAM_A <= addr[13:1]; + SDRAM_BA <= addr[24:23]; + end + end + + STATE_OPEN_1: begin state <= STATE_OPEN_2; end + + STATE_OPEN_2: begin + SDRAM_A <= {save_we & ~save_addr[0], save_we & save_addr[0], 2'b10, save_addr[22:14]}; + if(save_we) begin + command <= CMD_WRITE; + SDRAM_DQ <= {new_data[7:0], new_data[7:0]}; + ready <= 1; + state <= STATE_IDLE_2; + end + else begin + command <= CMD_READ; + data_ready_delay[CAS_LATENCY] <= 1; + state <= STATE_IDLE_5; + end + end + endcase + + if(init) begin + state <= STATE_STARTUP; + refresh_count <= startup_refresh_max - sdram_startup_cycles; + end + + old_we <= we; + if(we & ~old_we) begin + {ready, new_we, new_data} <= {1'b0, 1'b1, din}; + end + + old_rd <= rd; + if(rd & ~old_rd) begin + if(ready & ~save_we & (save_addr[24:1] == addr[24:1])) begin + save_addr <= addr; + end + else begin + {ready, new_rd} <= {1'b0, 1'b1}; + end + end + end + + altddio_out #( + .extend_oe_disable ( "OFF" ), + .intended_device_family ( "Cyclone V" ), + .invert_output ( "OFF" ), + .lpm_hint ( "UNUSED" ), + .lpm_type ( "altddio_out" ), + .oe_reg ( "UNREGISTERED" ), + .power_up_high ( "OFF" ), + .width ( 1 ) + ) sdramclk_ddr ( + .datain_h ( 1'b0 ), + .datain_l ( 1'b1 ), + .outclock ( clk ), + .dataout ( SDRAM_CLK ), + .aclr ( 1'b0 ), + .aset ( 1'b0 ), + .oe ( 1'b1 ), + .outclocken ( 1'b1 ), + .sclr ( 1'b0 ), + .sset ( 1'b0 ) + ); + +endmodule diff --git a/rtl/slots.sv b/rtl/slots.sv index aea06b7..fe9be01 100644 --- a/rtl/slots.sv +++ b/rtl/slots.sv @@ -1,271 +1,271 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX Compatible Gateware IP Core -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ - -module slots - ( - input clk, - input clk_en, - input reset, - input [15:0] addr, - input wr_n, - input rd_n, - input [7:0] d_from_cpu, - output [7:0] d_to_cpu, - input CS1_n, - input CS01_n, - input CS12_n, - input CS2_n, - input [3:0] SLTSL_n, - output [15:0] sound, - // IOCTL - input ioctl_wr, - input [24:0] ioctl_addr, - input [7:0] ioctl_dout, - input ioctl_isROMA, - input ioctl_isROMB, - output ioctl_wait, - // SDRAM - input [7:0] sdram_dout, - output [7:0] sdram_din, - output [24:0] sdram_addr, - output sdram_we, - output sdram_rd, - input sdram_ready, - input [1:0] sdram_size, - // Image - input img_mounted, - input [31:0] img_size, - input img_wp, - output [31:0] sd_lba, - output sd_rd, - output sd_wr, - input sd_ack, - input [8:0] sd_buff_addr, - input [7:0] sd_buff_dout, - output [7:0] sd_buff_din, - input sd_buff_wr, - input sd_din_strobe, - // User Mode - input [3:0] slot_A, - input [3:0] slot_B, - input [1:0] rom_enabled, - output [2:0] mapper_info - ); - - parameter USE_SDRAM = 1; - - assign sound = { sound_slot_A[14], sound_slot_A } + { sound_slot_B[14], sound_slot_B }; - assign ioctl_wait = ioctl_wait_slot_A | ioctl_wait_slot_B; - - assign d_to_cpu = ~(SLTSL_n[1]) ? (enableFDD_n ? d_from_slot_A : d_from_FDD) : - ~(SLTSL_n[2]) ? d_from_slot_B : - ~(SLTSL_n[3]) ? ram_q : - 8'hFF; - - assign sdram_addr = ioctl_isROMA ? {3'b001,ram_addr_A[21:0]} : - ioctl_isROMB ? {3'b000,ram_addr_B[21:0]} : - ~SLTSL_n[1] ? enableFDD_n ? {3'b001,ram_addr_A[21:0]} : 'd0 : - ~SLTSL_n[2] ? {3'b000,ram_addr_B[21:0]} : - 'd0; - - assign bram_addr = ram_addr_B; - assign sdram_din = ioctl_dout; - assign bram_din = ioctl_dout; - assign sdram_we = ioctl_isROMA ? ram_we_A : - ioctl_isROMB ? ram_we_B : - 0; - - assign bram_we = sdram_size == 0 & ioctl_isROMB & ioctl_wr; - assign sdram_rd = ~SLTSL_n[1] ? enableFDD_n ? ram_rd_A : 0 : - ~SLTSL_n[2] ? ram_rd_B : - 0; - - assign ram_dout_A = sdram_size == 0 ? 8'hFF : sdram_dout; - assign ram_dout_B = sdram_size == 0 ? bram_dout : sdram_dout; - - assign ram_ready_A = sdram_size == 0 ? 1'b1 : sdram_ready; - assign ram_ready_B = sdram_size == 0 ? 1'b1 : sdram_ready; - - // MapperInfo - reg last_loadRom; - always @(posedge ioctl_isROMA, posedge ioctl_isROMB) begin - if (ioctl_isROMA) last_loadRom <= 0; - if (ioctl_isROMB) last_loadRom <= 1; - end - - assign mapper_info = last_loadRom ? rom_enabled[1] ? detected_mapper_B : 3'h0 : - rom_enabled[0] ? detected_mapper_A : 3'h0 ; - - // SLOT A - wire enableFDD_n = SLTSL_n[1] | ~((|sdram_size & slot_A == 9) | (sdram_size == 0 & slot_A == 1)); - wire enableROM_n = SLTSL_n[1] | ~enableFDD_n; - - wire [7:0] d_from_slot_A; - wire [14:0] sound_slot_A; - wire ioctl_wait_slot_A; - - wire [7:0] ram_dout_A; - wire [7:0] ram_din_A; - wire [24:0] ram_addr_A; - wire ram_we_A; - wire ram_rd_A; - wire ram_ready_A; - wire [2:0] detected_mapper_A; - - cart_rom ROM_slot_A - ( - .clk ( clk ), - .clk_en ( clk_en ), - .reset ( reset ), - .addr ( addr ), - .wr ( ~wr_n ), - .rd ( ~rd_n ), - .CS1_n ( CS1_n ), - .CS2_n ( CS2_n ), - .CS12_n ( CS12_n ), - .SLTSL_n ( enableROM_n ), - .d_from_cpu ( d_from_cpu ), - .d_to_cpu ( d_from_slot_A ), - .sound ( sound_slot_A ), - .ioctl_wr ( ioctl_wr ), - .ioctl_addr ( ioctl_addr ), - .ioctl_dout ( ioctl_dout ), - .ioctl_isROM ( ioctl_isROMA ), - .ioctl_wait ( ioctl_wait_slot_A ), - .ram_dout ( ram_dout_A ), - .ram_din ( ram_din_A ), - .ram_addr ( ram_addr_A ), - .ram_we ( ram_we_A ), - .ram_rd ( ram_rd_A ), - .ram_ready ( ram_ready_A ), - .user_mapper ( slot_A ), - .detected_mapper ( detected_mapper_A ), - .rom_enabled ( rom_enabled[0] ) - ); - - // Floppy Disk Drive - wire [7:0] d_from_FDD; - - vy0010 FDD - ( - .clk ( clk ), - .clk_en ( clk_en ), - .reset ( reset ), - .addr ( addr ), - .d_to_cpu ( d_from_FDD ), - .d_from_cpu ( d_from_cpu ), - .wr_n ( wr_n ), - .rd_n ( rd_n ), - .CS1_n ( CS1_n ), - .stlsl_n ( enableFDD_n ), - .img_mounted ( img_mounted ), - .img_size ( img_size ), - .img_wp ( img_wp ), - .sd_lba ( sd_lba ), - .sd_rd ( sd_rd ), - .sd_wr ( sd_wr ), - .sd_ack ( sd_ack ), - .sd_buff_addr ( sd_buff_addr ), - .sd_buff_dout ( sd_buff_dout ), - .sd_buff_din ( sd_buff_din ), - .sd_buff_wr ( sd_buff_wr ), - .sd_din_strobe ( sd_din_strobe ) - ); - - // SLOT B - wire [7:0] d_from_slot_B; - wire [14:0] sound_slot_B; - wire ioctl_wait_slot_B; - - wire [7:0] ram_dout_B; - wire [7:0] ram_din_B; - wire [24:0] ram_addr_B; - wire ram_we_B; - wire ram_rd_B; - wire ram_ready_B; - wire [2:0] detected_mapper_B; - - cart_rom ROM_slot_B - ( - .clk ( clk ), - .clk_en ( clk_en ), - .reset ( reset ), - .addr ( addr ), - .wr ( ~wr_n ), - .rd ( ~rd_n ), - .CS1_n ( CS1_n ), - .CS2_n ( CS2_n ), - .CS12_n ( CS12_n ), - .SLTSL_n ( SLTSL_n[2] ), - .d_from_cpu ( d_from_cpu ), - .d_to_cpu ( d_from_slot_B ), - .sound ( sound_slot_B ), - .ioctl_wr ( ioctl_wr ), - .ioctl_addr ( ioctl_addr ), - .ioctl_dout ( ioctl_dout ), - .ioctl_isROM ( ioctl_isROMB ), - .ioctl_wait ( ioctl_wait_slot_B ), - .ram_dout ( ram_dout_B ), - .ram_din ( ram_din_B ), - .ram_addr ( ram_addr_B ), - .ram_we ( ram_we_B ), - .ram_rd ( ram_rd_B ), - .ram_ready ( ram_ready_B ), - .user_mapper ( slot_B ), - .detected_mapper ( detected_mapper_B ), - .rom_enabled ( rom_enabled[1] ) - ); - - //SLOT C - RAM 64kB - wire [7:0] ram_q; - - spram #(.addr_width(16), .mem_name("RAM")) ram - ( - .clock ( clk ), - .address ( addr[15:0] ), - .q ( ram_q ), - .data ( d_from_cpu ), - .wren ( ~(SLTSL_n[3] | wr_n ) ) - ); - - //BRAM - wire [7:0] bram_dout; - wire [7:0] bram_din; - wire [24:0] bram_addr; - wire bram_we; - - generate - if (USE_SDRAM == 0) begin - spram #(.addr_width(18),.mem_name("SLOTROM")) rom_cart - ( - .clock ( clk ), - .address ( bram_addr ), - .wren ( bram_we & bram_addr < 24'h20000 ), - .q ( bram_dout ), - .data ( bram_din ) - ); - end - endgenerate - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX Compatible Gateware IP Core +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ + +module slots + ( + input clk, + input clk_en, + input reset, + input [15:0] addr, + input wr_n, + input rd_n, + input [7:0] d_from_cpu, + output [7:0] d_to_cpu, + input CS1_n, + input CS01_n, + input CS12_n, + input CS2_n, + input [3:0] SLTSL_n, + output [15:0] sound, + // IOCTL + input ioctl_wr, + input [24:0] ioctl_addr, + input [7:0] ioctl_dout, + input ioctl_isROMA, + input ioctl_isROMB, + output ioctl_wait, + // SDRAM + input [7:0] sdram_dout, + output [7:0] sdram_din, + output [24:0] sdram_addr, + output sdram_we, + output sdram_rd, + input sdram_ready, + input [1:0] sdram_size, + // Image + input img_mounted, + input [31:0] img_size, + input img_wp, + output [31:0] sd_lba, + output sd_rd, + output sd_wr, + input sd_ack, + input [8:0] sd_buff_addr, + input [7:0] sd_buff_dout, + output [7:0] sd_buff_din, + input sd_buff_wr, + input sd_din_strobe, + // User Mode + input [3:0] slot_A, + input [3:0] slot_B, + input [1:0] rom_enabled, + output [2:0] mapper_info + ); + + parameter USE_SDRAM = 1; + + assign sound = { sound_slot_A[14], sound_slot_A } + { sound_slot_B[14], sound_slot_B }; + assign ioctl_wait = ioctl_wait_slot_A | ioctl_wait_slot_B; + + assign d_to_cpu = ~(SLTSL_n[1]) ? (enableFDD_n ? d_from_slot_A : d_from_FDD) : + ~(SLTSL_n[2]) ? d_from_slot_B : + ~(SLTSL_n[3]) ? ram_q : + 8'hFF; + + assign sdram_addr = ioctl_isROMA ? {3'b001,ram_addr_A[21:0]} : + ioctl_isROMB ? {3'b000,ram_addr_B[21:0]} : + ~SLTSL_n[1] ? enableFDD_n ? {3'b001,ram_addr_A[21:0]} : 'd0 : + ~SLTSL_n[2] ? {3'b000,ram_addr_B[21:0]} : + 'd0; + + assign bram_addr = ram_addr_B; + assign sdram_din = ioctl_dout; + assign bram_din = ioctl_dout; + assign sdram_we = ioctl_isROMA ? ram_we_A : + ioctl_isROMB ? ram_we_B : + 0; + + assign bram_we = sdram_size == 0 & ioctl_isROMB & ioctl_wr; + assign sdram_rd = ~SLTSL_n[1] ? enableFDD_n ? ram_rd_A : 0 : + ~SLTSL_n[2] ? ram_rd_B : + 0; + + assign ram_dout_A = sdram_size == 0 ? 8'hFF : sdram_dout; + assign ram_dout_B = sdram_size == 0 ? bram_dout : sdram_dout; + + assign ram_ready_A = sdram_size == 0 ? 1'b1 : sdram_ready; + assign ram_ready_B = sdram_size == 0 ? 1'b1 : sdram_ready; + + // MapperInfo + reg last_loadRom; + always @(posedge ioctl_isROMA, posedge ioctl_isROMB) begin + if (ioctl_isROMA) last_loadRom <= 0; + if (ioctl_isROMB) last_loadRom <= 1; + end + + assign mapper_info = last_loadRom ? rom_enabled[1] ? detected_mapper_B : 3'h0 : + rom_enabled[0] ? detected_mapper_A : 3'h0 ; + + // SLOT A + wire enableFDD_n = SLTSL_n[1] | ~((|sdram_size & slot_A == 9) | (sdram_size == 0 & slot_A == 1)); + wire enableROM_n = SLTSL_n[1] | ~enableFDD_n; + + wire [7:0] d_from_slot_A; + wire [14:0] sound_slot_A; + wire ioctl_wait_slot_A; + + wire [7:0] ram_dout_A; + wire [7:0] ram_din_A; + wire [24:0] ram_addr_A; + wire ram_we_A; + wire ram_rd_A; + wire ram_ready_A; + wire [2:0] detected_mapper_A; + + cart_rom ROM_slot_A + ( + .clk ( clk ), + .clk_en ( clk_en ), + .reset ( reset ), + .addr ( addr ), + .wr ( ~wr_n ), + .rd ( ~rd_n ), + .CS1_n ( CS1_n ), + .CS2_n ( CS2_n ), + .CS12_n ( CS12_n ), + .SLTSL_n ( enableROM_n ), + .d_from_cpu ( d_from_cpu ), + .d_to_cpu ( d_from_slot_A ), + .sound ( sound_slot_A ), + .ioctl_wr ( ioctl_wr ), + .ioctl_addr ( ioctl_addr ), + .ioctl_dout ( ioctl_dout ), + .ioctl_isROM ( ioctl_isROMA ), + .ioctl_wait ( ioctl_wait_slot_A ), + .ram_dout ( ram_dout_A ), + .ram_din ( ram_din_A ), + .ram_addr ( ram_addr_A ), + .ram_we ( ram_we_A ), + .ram_rd ( ram_rd_A ), + .ram_ready ( ram_ready_A ), + .user_mapper ( slot_A ), + .detected_mapper ( detected_mapper_A ), + .rom_enabled ( rom_enabled[0] ) + ); + + // Floppy Disk Drive + wire [7:0] d_from_FDD; + + vy0010 FDD + ( + .clk ( clk ), + .clk_en ( clk_en ), + .reset ( reset ), + .addr ( addr ), + .d_to_cpu ( d_from_FDD ), + .d_from_cpu ( d_from_cpu ), + .wr_n ( wr_n ), + .rd_n ( rd_n ), + .CS1_n ( CS1_n ), + .stlsl_n ( enableFDD_n ), + .img_mounted ( img_mounted ), + .img_size ( img_size ), + .img_wp ( img_wp ), + .sd_lba ( sd_lba ), + .sd_rd ( sd_rd ), + .sd_wr ( sd_wr ), + .sd_ack ( sd_ack ), + .sd_buff_addr ( sd_buff_addr ), + .sd_buff_dout ( sd_buff_dout ), + .sd_buff_din ( sd_buff_din ), + .sd_buff_wr ( sd_buff_wr ), + .sd_din_strobe ( sd_din_strobe ) + ); + + // SLOT B + wire [7:0] d_from_slot_B; + wire [14:0] sound_slot_B; + wire ioctl_wait_slot_B; + + wire [7:0] ram_dout_B; + wire [7:0] ram_din_B; + wire [24:0] ram_addr_B; + wire ram_we_B; + wire ram_rd_B; + wire ram_ready_B; + wire [2:0] detected_mapper_B; + + cart_rom ROM_slot_B + ( + .clk ( clk ), + .clk_en ( clk_en ), + .reset ( reset ), + .addr ( addr ), + .wr ( ~wr_n ), + .rd ( ~rd_n ), + .CS1_n ( CS1_n ), + .CS2_n ( CS2_n ), + .CS12_n ( CS12_n ), + .SLTSL_n ( SLTSL_n[2] ), + .d_from_cpu ( d_from_cpu ), + .d_to_cpu ( d_from_slot_B ), + .sound ( sound_slot_B ), + .ioctl_wr ( ioctl_wr ), + .ioctl_addr ( ioctl_addr ), + .ioctl_dout ( ioctl_dout ), + .ioctl_isROM ( ioctl_isROMB ), + .ioctl_wait ( ioctl_wait_slot_B ), + .ram_dout ( ram_dout_B ), + .ram_din ( ram_din_B ), + .ram_addr ( ram_addr_B ), + .ram_we ( ram_we_B ), + .ram_rd ( ram_rd_B ), + .ram_ready ( ram_ready_B ), + .user_mapper ( slot_B ), + .detected_mapper ( detected_mapper_B ), + .rom_enabled ( rom_enabled[1] ) + ); + + //SLOT C - RAM 64kB + wire [7:0] ram_q; + + spram #(.addr_width(16), .mem_name("RAM")) ram + ( + .clock ( clk ), + .address ( addr[15:0] ), + .q ( ram_q ), + .data ( d_from_cpu ), + .wren ( ~(SLTSL_n[3] | wr_n ) ) + ); + + //BRAM + wire [7:0] bram_dout; + wire [7:0] bram_din; + wire [24:0] bram_addr; + wire bram_we; + + generate + if (USE_SDRAM == 0) begin + spram #(.addr_width(18),.mem_name("SLOTROM")) rom_cart + ( + .clock ( clk ), + .address ( bram_addr ), + .wren ( bram_we & bram_addr < 24'h20000 ), + .q ( bram_dout ), + .data ( bram_din ) + ); + end + endgenerate + +endmodule diff --git a/rtl/tape.sv b/rtl/tape.sv index 5e45c8e..8fe6414 100644 --- a/rtl/tape.sv +++ b/rtl/tape.sv @@ -1,236 +1,236 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// MSX1 CAS Player -// -// Copyright (c) 2022, Molekula <@tdlabac> -// -// 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, version 3. -// -// 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 . -// -//------------------------------------------------------------------------------ -// Notes from: -// https://konamiman.github.io/MSX2-Technical-Handbook/md/Chapter5a.html -// -// CASSETTE INTERFACE -// -// Cassette tape recorders are the least expensive external storage devices -// available for the MSX. Knowledge of the cassette interface is required to -// treat information in cassette tapes within assembly language programs. -// This section offers the necessary information. -// -// Baud Rate -// -// The following two baud rates can be used by the MSX cassette interface. -// When BASIC is invoked, 1200bps is set by default. -// -// ------------------------------------------------ -// | Baud rate | Characteristics | -// |-------------+--------------------------------| -// | 1200 bps | Low speed / high reliability | -// |-------------+--------------------------------| -// | 2400 bps | High speed / low reliability | -// ------------------------------------------------ -// -// The baud rate is specified by the fourth parameter of the SCREEN instruction -// or the second parameter of the CSAVE instruction. Once the baud rate is set, -// it stays at that value. -// -// SCREEN ,,, -// CSAVE "filename", -// ( is 1 for 1200bps, 2 for 2400 bps) -// -//------------------------------------------------------------------------------ - -module tape - ( - input clk, - input ce_5m3, - input play, - input rewind, - output [26:0] ram_a, - input [7:0] ram_di, - output ram_rd, - input buff_mem_ready, - output cas_out - ); - - typedef enum { - STATE_SLEEP, - STATE_INIT, - STATE_SEARCH, - STATE_PLAY_SILLENT, - STATE_PLAY_SYNC, - STATE_PLAY_DATA - } player_state_t; - - player_state_t state = STATE_SLEEP; - - wire[63:0] cas_sig = 64'h1FA6DEBACC137d74; - wire[63:0] sig_pos = cas_sig >> (8'd56 - (ram_a[2:0]<<3)); - - assign cas_out = output_bit & output_on; - - // signature check - reg sig_ok; - - always @(posedge clk) begin - reg sig_temp_ok; - if (buff_mem_ready && ~ram_rd) begin - if (ram_a[2:0] == 0) begin - sig_temp_ok <= (sig_pos[7:0] == ram_di); - sig_ok <= 0; - end - else begin - sig_ok <= 0; - if (~(sig_pos[7:0] == ram_di)) begin - sig_temp_ok <= 0; - end - else begin - if (ram_a[2:0] == 3'h7) begin - sig_ok <= sig_temp_ok & (sig_pos[7:0] == ram_di); - end - end - end - end - end - - reg output_on = 0; - reg header; - reg [10:0] counter; - - always @(posedge clk) begin - if (buff_mem_ready) - ram_rd <= 0; - case (state) - STATE_SLEEP: begin end - STATE_INIT: begin - if (buff_mem_ready && ~ram_rd) begin - ram_a <= 0; - output_on <= 0; - state <= STATE_SEARCH; - ram_rd <= 1; - end - end - STATE_SEARCH: begin - if (sig_ok) begin - state <= STATE_PLAY_SILLENT; - counter <= 1000; - end - else if (buff_mem_ready && ~ram_rd) begin - ram_a <= ram_a + 1'd1; - ram_rd <= 1; - end - end - STATE_PLAY_SILLENT: begin - if (ce_baud) begin - counter <= counter - 1'b1; - if (counter == 0) begin - state <= STATE_PLAY_SYNC; - counter <= 1454; - end - end - end - STATE_PLAY_SYNC: begin - if (counter == 0) begin - state <= STATE_PLAY_DATA; - header <= 0; - end - else - header <= 1; - if (byte_pos == 0) begin - output_on <= 1; - counter <= counter - 1'b1; - end - end - STATE_PLAY_DATA: begin - if (sig_ok) begin - state <= STATE_PLAY_SYNC; - counter <= 1454; - if (buff_mem_ready && ~ram_rd) begin - ram_a <= ram_a + 1'd1; - ram_rd <= 1; - end - end - else if (byte_pos == 0) begin - if (buff_mem_ready && ~ram_rd) begin - ram_a <= ram_a + 1'd1; - ram_rd <= 1; - end - end - end - endcase - if (rewind) begin - state <= STATE_INIT; - end - end - - // Send byte - reg [3:0] byte_pos = 0; - reg [7:0] send_byte; - - always @(posedge clk) begin - reg [10:0] byte_out; - if (byte_pos == 0) begin - byte_out = header ? 11'h7FF : {2'b11, ram_di, 1'b0}; // 1'b0 startbit, 2'b11 stop bit - byte_pos = 4'd11; - end - if (cnt == 0) begin - send_bit = byte_out[0]; - if (ce_baud) begin - byte_out = {1'b0, byte_out[10:1]}; - byte_pos = byte_pos - 1'b1; - end - end - end - - // Send bit - reg send_bit; - reg output_bit; - - always @(posedge clk) begin - reg bit_out; - if (ce_baud) begin - if (cnt == 2'h0) begin - output_bit = 1; - bit_out = send_bit; - end - else begin - output_bit = (bit_out & ~cnt[0]) | (~bit_out & ~cnt[1]); - end - end - end - - // Baud generator - reg [1:0] cnt = 2'h0; - reg ce_baud; - - always @(posedge clk) begin - reg [10:0] baud_div; - ce_baud = 0; - - if (ce_5m3 && play) begin - if (baud_div == 11'h0) begin - ce_baud = 1; - baud_div = 11'd559; - cnt = cnt + 1'b1; - end - else begin - baud_div = baud_div - 1'b1; - end - end - end - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2024, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// MSX1 CAS Player +// +// Copyright (c) 2022, Molekula <@tdlabac> +// +// 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, version 3. +// +// 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 . +// +//------------------------------------------------------------------------------ +// Notes from: +// https://konamiman.github.io/MSX2-Technical-Handbook/md/Chapter5a.html +// +// CASSETTE INTERFACE +// +// Cassette tape recorders are the least expensive external storage devices +// available for the MSX. Knowledge of the cassette interface is required to +// treat information in cassette tapes within assembly language programs. +// This section offers the necessary information. +// +// Baud Rate +// +// The following two baud rates can be used by the MSX cassette interface. +// When BASIC is invoked, 1200bps is set by default. +// +// ------------------------------------------------ +// | Baud rate | Characteristics | +// |-------------+--------------------------------| +// | 1200 bps | Low speed / high reliability | +// |-------------+--------------------------------| +// | 2400 bps | High speed / low reliability | +// ------------------------------------------------ +// +// The baud rate is specified by the fourth parameter of the SCREEN instruction +// or the second parameter of the CSAVE instruction. Once the baud rate is set, +// it stays at that value. +// +// SCREEN ,,, +// CSAVE "filename", +// ( is 1 for 1200bps, 2 for 2400 bps) +// +//------------------------------------------------------------------------------ + +module tape + ( + input clk, + input ce_5m3, + input play, + input rewind, + output [26:0] ram_a, + input [7:0] ram_di, + output ram_rd, + input buff_mem_ready, + output cas_out + ); + + typedef enum { + STATE_SLEEP, + STATE_INIT, + STATE_SEARCH, + STATE_PLAY_SILLENT, + STATE_PLAY_SYNC, + STATE_PLAY_DATA + } player_state_t; + + player_state_t state = STATE_SLEEP; + + wire[63:0] cas_sig = 64'h1FA6DEBACC137d74; + wire[63:0] sig_pos = cas_sig >> (8'd56 - (ram_a[2:0]<<3)); + + assign cas_out = output_bit & output_on; + + // signature check + reg sig_ok; + + always @(posedge clk) begin + reg sig_temp_ok; + if (buff_mem_ready && ~ram_rd) begin + if (ram_a[2:0] == 0) begin + sig_temp_ok <= (sig_pos[7:0] == ram_di); + sig_ok <= 0; + end + else begin + sig_ok <= 0; + if (~(sig_pos[7:0] == ram_di)) begin + sig_temp_ok <= 0; + end + else begin + if (ram_a[2:0] == 3'h7) begin + sig_ok <= sig_temp_ok & (sig_pos[7:0] == ram_di); + end + end + end + end + end + + reg output_on = 0; + reg header; + reg [10:0] counter; + + always @(posedge clk) begin + if (buff_mem_ready) + ram_rd <= 0; + case (state) + STATE_SLEEP: begin end + STATE_INIT: begin + if (buff_mem_ready && ~ram_rd) begin + ram_a <= 0; + output_on <= 0; + state <= STATE_SEARCH; + ram_rd <= 1; + end + end + STATE_SEARCH: begin + if (sig_ok) begin + state <= STATE_PLAY_SILLENT; + counter <= 1000; + end + else if (buff_mem_ready && ~ram_rd) begin + ram_a <= ram_a + 1'd1; + ram_rd <= 1; + end + end + STATE_PLAY_SILLENT: begin + if (ce_baud) begin + counter <= counter - 1'b1; + if (counter == 0) begin + state <= STATE_PLAY_SYNC; + counter <= 1454; + end + end + end + STATE_PLAY_SYNC: begin + if (counter == 0) begin + state <= STATE_PLAY_DATA; + header <= 0; + end + else + header <= 1; + if (byte_pos == 0) begin + output_on <= 1; + counter <= counter - 1'b1; + end + end + STATE_PLAY_DATA: begin + if (sig_ok) begin + state <= STATE_PLAY_SYNC; + counter <= 1454; + if (buff_mem_ready && ~ram_rd) begin + ram_a <= ram_a + 1'd1; + ram_rd <= 1; + end + end + else if (byte_pos == 0) begin + if (buff_mem_ready && ~ram_rd) begin + ram_a <= ram_a + 1'd1; + ram_rd <= 1; + end + end + end + endcase + if (rewind) begin + state <= STATE_INIT; + end + end + + // Send byte + reg [3:0] byte_pos = 0; + reg [7:0] send_byte; + + always @(posedge clk) begin + reg [10:0] byte_out; + if (byte_pos == 0) begin + byte_out = header ? 11'h7FF : {2'b11, ram_di, 1'b0}; // 1'b0 startbit, 2'b11 stop bit + byte_pos = 4'd11; + end + if (cnt == 0) begin + send_bit = byte_out[0]; + if (ce_baud) begin + byte_out = {1'b0, byte_out[10:1]}; + byte_pos = byte_pos - 1'b1; + end + end + end + + // Send bit + reg send_bit; + reg output_bit; + + always @(posedge clk) begin + reg bit_out; + if (ce_baud) begin + if (cnt == 2'h0) begin + output_bit = 1; + bit_out = send_bit; + end + else begin + output_bit = (bit_out & ~cnt[0]) | (~bit_out & ~cnt[1]); + end + end + end + + // Baud generator + reg [1:0] cnt = 2'h0; + reg ce_baud; + + always @(posedge clk) begin + reg [10:0] baud_div; + ce_baud = 0; + + if (ce_5m3 && play) begin + if (baud_div == 11'h0) begin + ce_baud = 1; + baud_div = 11'd559; + cnt = cnt + 1'b1; + end + else begin + baud_div = baud_div - 1'b1; + end + end + end + +endmodule diff --git a/target/pocket/analogizer/analogizer.qip b/target/pocket/analogizer/analogizer.qip new file mode 100644 index 0000000..a30cf4b --- /dev/null +++ b/target/pocket/analogizer/analogizer.qip @@ -0,0 +1,14 @@ +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) openFPGA_Pocket_Analogizer.v] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) vga_out_sw.v] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) openFPGA_Pocket_Analogizer_SNAC.sv] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) clock_divider_fract.v] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) serlatch_gc.v] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pcengine_gc.v] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) pcengine_game_controller_multitap.v] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) yc_out.sv] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler_2.v] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scanlines_analogizer.v] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) hq2x.sv] +set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) dualshock_controller.v] +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) analogizer_psx.sv] diff --git a/target/pocket/analogizer/analogizer_psx.sv b/target/pocket/analogizer/analogizer_psx.sv new file mode 100644 index 0000000..fd8b264 --- /dev/null +++ b/target/pocket/analogizer/analogizer_psx.sv @@ -0,0 +1,210 @@ + +// convert dualshock to Analogizer Analogue Pocket format +// @RndMnkIII. 11/2024 +//Analogue pocket format +//key1 +// Pocket logic button order: +// [0] dpad_up +// [1] dpad_down +// [2] dpad_left +// [3] dpad_right +// [4] face_a +// [5] face_b +// [6] face_x +// [7] face_y +// [8] trig_l1 +// [9] trig_r1 +// [10] trig_l2 +// [11] trig_r2 +// [12] trig_l3 +// [13] trig_r3 +// [14] face_select +// [15] face_start +// [28:16] +// [31:28] type: +// Type Field (4 bits) Description +// 0x0 Nothing connected +// 0x1 Pocket built-in buttons (only possible on Player 1) +// 0x2 Docked game controller, no analog support +// 0x3 Docked game controller, analog support +// 0x4 Docked keyboard +// 0x5 Docked mouse +// 0x7-0xF Reserved +//JOY +// [31:0] joy +// [ 7: 0] lstick_x +// [15: 8] lstick_y +// [23:16] rstick_x +// [31:24] rstick_y + +module analogizer_psx #(parameter MASTER_CLK_FREQ=50_000_000) ( + input i_clk, + input i_rst, + input i_ena, + input i_stb, + //Pocket control interface + output reg [15:0] key1, + output reg [31:0] joy1, + output reg [15:0] key2, + output reg [31:0] joy2, + //PSX INTERFACE + + input [1:0] i_VIB_SW1, // Vibration SW VIB_SW[0] Small Moter OFF 0:ON 1: + //VIB_SW[1] Bic Moter OFF 0:ON 1(Dualshook Only) + input [7:0] i_VIB_DAT1, // Vibration(Bic Moter)Data 8'H00-8'HFF (Dualshook Only) + input [1:0] i_VIB_SW2, + input [7:0] i_VIB_DAT2, + output PSX_CLK, + input PSX_DAT, + output PSX_CMD, + output PSX_ATT1, + output PSX_ATT2, + input PSX_ACK, + //output PSX_IRQ + output wire [3:0] DBG_TX +); + logic [7:0] rx0, rx1, rx2, rx3, rx4, rx5, rx6; + logic [7:0] RXD_ID; + reg att1r, att2r; + //reg [3:0] id1, id2; + reg no_gamepad; + //reg send_bytes1_stb, send_bytes2_stb; + + always @(posedge i_clk) begin + no_gamepad <= (&RXD_ID) & (&rx0); //both are FF no device detected + att1r <= PSX_ATT1; + att2r <= PSX_ATT2; + //send_bytes1_stb <= 0; + //send_bytes2_stb <= 0; + + if (~att1r & PSX_ATT1) begin //capture when ATT1 becomes idle + //send_bytes1_stb <= 1; + + if(no_gamepad) begin //no gamepad detected, default data + key1 <= 16'h00; + joy1 <= 32'h80808080; //neutral position + end + else + begin + // START SELECT R3 L3 R2 L2 R1 L1 Y X B A LEFT RIGHT DOWN UP + key1 <= {~rx1[3], ~rx1[0],~rx1[2],~rx1[1],~rx2[1],~rx2[0],~rx2[3],~rx2[2],~rx2[7],~rx2[4],~rx2[6],~rx2[5],~rx1[5],~rx1[7],~rx1[6],~rx1[4]}; + // rstick_y rstick_x lstick_y lstick_x + joy1 <= {rx4,rx3,rx6,rx5}; + end + end + else if(~att2r & PSX_ATT2) begin //capture when ATT2 becomes idle + //send_bytes2_stb <= 1; + + if(no_gamepad) begin //no gamepad detected, default data + key2 <= 16'h00; + joy2 <= 32'h80808080; //neutral position + end + else + begin + // START SELECT R3 L3 R2 L2 R1 L1 Y X B A LEFT RIGHT DOWN UP + key2 <= {~rx1[3], ~rx1[0],~rx1[2],~rx1[1],~rx2[1],~rx2[0],~rx2[3],~rx2[2],~rx2[7],~rx2[4],~rx2[6],~rx2[5],~rx1[5],~rx1[7],~rx1[6],~rx1[4]}; + // rstick_y rstick_x lstick_y lstick_x + joy2 <= {rx4,rx3,rx6,rx5}; + end + end + end + //assign DBG_TX = {PSX_ATT1,PSX_CLK,PSX_CMD,PSX_DAT}; //r_Tx_DV; + //assign DBG_TX = {dbgtx,dbgtx,dbgtx,1'b0}; + assign DBG_TX = {4'b0000}; + // Dualshock controller + + dualshock_controller #(.FREQ(MASTER_CLK_FREQ)) ds1 ( + .clk(i_clk), .i_RSTn(~i_rst), .i_ena(i_ena), .i_stb(i_stb), + .i_MULTITAP_ena(1'b0), .i_VIB_SW1(i_VIB_SW1), .i_VIB_DAT1(i_VIB_DAT1), .i_VIB_SW2(i_VIB_SW2), .i_VIB_DAT2(i_VIB_DAT2), + .o_psCLK(PSX_CLK), .o_ATT1(PSX_ATT1), .o_ATT2(PSX_ATT2), .o_psTXD(PSX_CMD), + .i_psRXD(PSX_DAT), .i_psACK(PSX_ACK), + .o_RXD_ID(RXD_ID), .o_RXD_0(rx0), + .o_RXD_1(rx1), .o_RXD_2(rx2), .o_RXD_3(rx3), + .o_RXD_4(rx4), .o_RXD_5(rx5), .o_RXD_6(rx6) + ); + + //debug as UART TX at 500000bps +// wire [7:0] lut[15:0]; +// +// assign lut[0]=8'h30; // ascii 0 +// assign lut[1]=8'h31; // ascii 1 +// assign lut[2]=8'h32; // ascii 2 +// assign lut[3]=8'h33; // ascii 3 +// assign lut[4]=8'h34; // ascii 4 +// assign lut[5]=8'h35; // ascii 5 +// assign lut[6]=8'h36; // ascii 6 +// assign lut[7]=8'h37; // ascii 7 +// assign lut[8]=8'h38; // ascii 8 +// assign lut[9]=8'h39; // ascii 9 +// assign lut[10]=8'h41; // ascii A +// assign lut[11]=8'h42; // ascii B +// assign lut[12]=8'h43; // ascii C +// assign lut[13]=8'h44; // ascii D +// assign lut[14]=8'h45; // ascii E +// assign lut[15]=8'h46; // ascii F +// +// reg r_Tx_DV; +// wire w_Tx_Done; +// reg [7:0] r_Tx_Byte; +// reg r_Rx_Serial; +// +// //cycle bytes to send +// reg [5:0] byte_cnt; +// +// always @(posedge i_clk) begin +// r_Tx_DV <= 1'b0; +// if(~i_rst) begin +// byte_cnt <= 6'd0; +// r_Tx_DV <= 1'b0; +// end +// else begin +// if(send_bytes1_stb || send_bytes2_stb) begin +// byte_cnt <= 6'd1; +// r_Tx_DV <= 1'b1; +// end +// else begin +// if ((byte_cnt < 6'd27) && w_Tx_Done) begin +// byte_cnt <= byte_cnt + 6'd1; +// r_Tx_DV <= 1'b1; +// end +// end +// end +// end +// +// always@(*) begin +// case(byte_cnt) +// 6'd01: r_Tx_Byte = "R"; +// 6'd02: r_Tx_Byte = "x"; +// 6'd03: r_Tx_Byte = ":"; +// 6'd04: r_Tx_Byte = lut[RXD_ID[7:4]]; +// 6'd05: r_Tx_Byte = lut[RXD_ID[3:0]]; +// 6'd07: r_Tx_Byte = lut[rx0[7:4]]; +// 6'd08: r_Tx_Byte = lut[rx0[3:0]]; +// 6'd10: r_Tx_Byte = lut[rx1[7:4]]; +// 6'd11: r_Tx_Byte = lut[rx1[3:0]]; +// 6'd13: r_Tx_Byte = lut[rx2[7:4]]; +// 6'd14: r_Tx_Byte = lut[rx2[3:0]]; +// 6'd16: r_Tx_Byte = lut[rx3[7:4]]; +// 6'd17: r_Tx_Byte = lut[rx3[3:0]]; +// 6'd19: r_Tx_Byte = lut[rx4[7:4]]; +// 6'd20: r_Tx_Byte = lut[rx4[3:0]]; +// 6'd22: r_Tx_Byte = lut[rx5[7:4]]; +// 6'd23: r_Tx_Byte = lut[rx5[3:0]]; +// 6'd25: r_Tx_Byte = lut[rx6[7:4]]; +// 6'd26: r_Tx_Byte = lut[rx6[3:0]]; +// 6'd27: r_Tx_Byte = 8'h0D; //carriage return +// default: r_Tx_Byte = " "; +// endcase +// end + + //i_clk 48_000_000 +// wire dbgtx; +// uart_tx #(.CLKS_PER_BIT(96)) UART_TX_INST +// (.i_Clock(i_clk), +// .i_Tx_DV(r_Tx_DV), //enable to send byte +// .i_Tx_Byte(r_Tx_Byte), +// .o_Tx_Active(), +// .o_Tx_Serial(dbgtx), +// .o_Tx_Done(w_Tx_Done) +// ); +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/clock_divider_fract.v b/target/pocket/analogizer/clock_divider_fract.v new file mode 100644 index 0000000..098a901 --- /dev/null +++ b/target/pocket/analogizer/clock_divider_fract.v @@ -0,0 +1,17 @@ +`timescale 1ns / 1ps + +module clock_divider_fract ( + input wire i_clk, + input wire i_rst, + input wire [31:0] i_step, + output reg o_stb +); + reg [31:0] counter=33'd0; + + always @(posedge i_clk) begin + if(i_rst) //synchronous reset + counter <= 32'd0; + else + {o_stb,counter} <= counter + i_step; + end +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/csync.v b/target/pocket/analogizer/csync.v new file mode 100644 index 0000000..c7225b7 --- /dev/null +++ b/target/pocket/analogizer/csync.v @@ -0,0 +1,34 @@ +module csync +( + input clk, + input hsync, + input vsync, + + output csync +); + +assign csync = (csync_vs ^ csync_hs); + +reg csync_hs, csync_vs; +always @(posedge clk) begin + reg prev_hs; + reg [15:0] h_cnt, line_len, hs_len; + + // Count line/Hsync length + h_cnt <= h_cnt + 1'd1; + + prev_hs <= hsync; + if (prev_hs ^ hsync) begin + h_cnt <= 0; + if (hsync) begin + line_len <= h_cnt - hs_len; + csync_hs <= 0; + end + else hs_len <= h_cnt; + end + + if (~vsync) csync_hs <= hsync; + else if(h_cnt == line_len) csync_hs <= 1; + + csync_vs <= vsync; +end \ No newline at end of file diff --git a/target/pocket/analogizer/dualshock_controller.v b/target/pocket/analogizer/dualshock_controller.v new file mode 100644 index 0000000..18851fe --- /dev/null +++ b/target/pocket/analogizer/dualshock_controller.v @@ -0,0 +1,365 @@ +//------------------------------------------------------------------- +// +// PLAYSTATION CONTROLLER(DUALSHOCK TYPE) INTERFACE TOP +// +// Version : 2.00 +// +// Copyright(c) 2003 - 2004 Katsumi Degawa , All rights reserved +// +// Important ! +// +// This program is freeware for non-commercial use. +// An author does no guarantee about this program. +// You can use this under your own risk. +// +// 2003.10.30 It is optimized . by K Degawa +// 2023.12 nand2mario: rewrite without ripple clocks to improve stability +// remove fine-grained vibration control as we don't use it +// 2024.11 RndMnkIII: added capability to read two controllers using two ATT signals +// check when there is a game controller connected +// +//------------------------------------------------------------------- +`timescale 100ps/10ps + +// Protocol: https://store.curiousinventor.com/guides/PS2/ +// - Full duplex (command and data at the same time) +// - On negedge of clock, the line start to change. +// On posedge, values are read. +// - Command 0x01 0x42(cmd) 0x00 0x00 0x00 +// Data 0xFF 0x41 0x5A 0xFF(btns) 0xFF(btns) +// ^- mode + # of words + +//--------- SIMULATION ---------------------------------------------- +//`define SIMULATION_1 +// +// Poll controller status every 2^Timer clock cycles +// 125Khz / 2^11 = 61Hz +// +// SONY PLAYSTATION® CONTROLLER INFORMATION +// https://gamesx.com/controldata/psxcont/psxcont.htm +// +// "The DS4 stock polling rate is 250Hz 3-4 ms compared to the SN30 which is 67-75Hz 13-18 ms" +// https://www.reddit.com/r/8bitdo/comments/u8z3ag/has_anyone_managed_to_get_their_controllers/ +`ifdef SIMULATION_1 +`define Timer_siz 18 +`else +`define Timer_siz 11 +`endif + +module dualshock_controller #( + parameter FREQ // frequency of `clk` +) ( + input clk, // Any main clock faster than 1Mhz + input i_RSTn, // MAIN RESET + input i_ena, // Enable operation of the module + input i_stb, + //PSX interface + input i_MULTITAP_ena, + input [1:0] i_VIB_SW1, // Vibration SW VIB_SW[0] Small Moter OFF 0:ON 1: + // VIB_SW[1] Bic Moter OFF 0:ON 1(Dualshook Only) + input [7:0] i_VIB_DAT1, // Vibration(Bic Moter)Data 8'H00-8'HFF (Dualshook Only) + input [1:0] i_VIB_SW2, + input [7:0] i_VIB_DAT2, + output o_psCLK, // psCLK CLK OUT + output o_ATT1, // ATT1 OUT + output o_ATT2, // ATT1 OUT + output o_psTXD, // psTXD OUT + input i_psRXD, // psRXD IN + input i_psACK, //ACK + + //vibration control + output reg [7:0] o_RXD_ID, // RX DEVICE ID (UPPER NIBBLE) AND PAYLOAD SIZE (LOWER NIBBLE) + output reg [7:0] o_RXD_0, + output reg [7:0] o_RXD_1, // RX DATA 1 (8bit) + output reg [7:0] o_RXD_2, // RX DATA 2 (8bit) + output reg [7:0] o_RXD_3, // RX DATA 3 (8bit) + output reg [7:0] o_RXD_4, // RX DATA 4 (8bit) + output reg [7:0] o_RXD_5, // RX DATA 5 (8bit) + output reg [7:0] o_RXD_6 // RX DATA 6 (8bit) +); + +reg i_CLK ; // SPI clock at 125Khz + // some cheap controllers cannot handle the nominal 250Khz +reg R_CE, F_CE ; // rising and falling edge pulses of i_CLK + +// Generate i_CLK, F_CE, R_CE +always @(posedge clk) begin + //clk_cnt <= clk_cnt + 1; + //if(i_ena)clk_cnt <= clk_cnt + 1; + R_CE <= 0; + F_CE <= 0; + //if (clk_cnt == CLK_DELAY-1) begin + if (i_stb && i_ena) begin + i_CLK <= ~i_CLK; + R_CE <= ~i_CLK; + F_CE <= i_CLK; + //clk_cnt <= 0; + end +end + +reg ack_r/* synthesis noprune */; +always @(posedge clk) begin + if (i_stb && i_ena) begin + ack_r <= i_psACK; + end +end + +reg device_id_type ; //1'b1 digital one, 1'b0 analog one +always @(posedge clk) begin + if(! i_RSTn) device_id_type <= 1'b0; + else if (W_byte_cnt == 2) begin + case(o_RXD_ID) + 8'h23: device_id_type <= 1'b1; + 8'h41: device_id_type <= 1'b0; + 8'h53: device_id_type <= 1'b1; + 8'h73: device_id_type <= 1'b1; + 8'hE3: device_id_type <= 1'b1; + 8'hF3: device_id_type <= 1'b1; + 8'h80: device_id_type <= 1'b1; //multitap + default: device_id_type <= 1'b0; + endcase + end +end + +wire W_type = 1'b1 ; // DIGITAL PAD 0, ANALOG PAD 1 +wire [3:0] W_byte_cnt ; +wire W_RXWT ; +wire W_TXWT ; +wire W_TXEN ; +wire W_TXSET ; +reg [7:0]W_TXD_DAT /* synthesis noprune */; +wire [7:0]W_RXD_DAT ; + +ps_pls_gan pls( + .clk(clk), .R_CE(R_CE), .i_CLK(i_CLK), .i_RSTn(i_RSTn), .i_TYPE(device_id_type), + .o_RXWT(W_RXWT), .o_TXWT(W_TXWT), + .o_TXEN(W_TXEN), .o_psCLK(o_psCLK), + .o_ATT1(o_ATT1), .o_ATT2(o_ATT2), .o_byte_cnt(W_byte_cnt) +); + +ps_txd txd( + .clk(clk), .F_CE(F_CE), .i_RSTn(i_RSTn), + .i_WT(W_TXWT), .i_EN(W_TXEN), .i_TXD_DAT(W_TXD_DAT), .o_psTXD(o_psTXD) +); + +ps_rxd rxd( + .clk(clk), .R_CE(R_CE), .i_RSTn(i_RSTn), + .i_WT(W_RXWT), .i_psRXD(i_psRXD), .o_RXD_DAT(W_RXD_DAT) +); + +// TX command generation +always @* begin + case(W_byte_cnt) + 0: W_TXD_DAT = 8'h01; + 1: W_TXD_DAT = 8'h42; + 2: W_TXD_DAT = (i_MULTITAP_ena) ? 8'h01 : 8'h00; + // 3: W_TXD_DAT = 8'h00; // or vibration command + // 4: W_TXD_DAT = 8'h00; // or vibration command + 3: W_TXD_DAT = (~o_ATT1)? i_VIB_SW1[0] : ((~o_ATT2)? i_VIB_SW2[0] :8'h00 ); // or vibration command + 4: W_TXD_DAT = (~o_ATT1 && i_VIB_SW1[1])? i_VIB_DAT1 : ((~o_ATT2 && i_VIB_SW2[1])? i_VIB_DAT1 :8'h00 ); // or vibration command + default: W_TXD_DAT = 8'h00; + endcase +end + +// RX data decoding +//ID DESCRIPTION PAYLOAD_SIZE (half dwords) +// 1 Mouse 2 +// 9 Lightspan Keyboard SCPH-2000 6 +// 4 Digital Controller SCPH-1010 1 +// 5 Analog Joystick SCPH-1110 (Analog Mode) 3 +// 5 Dual Analog SCPH-1180 (Green LED mode) 3 +// 7 Dual Analog & Dual Shock 1/2 (Analog Mode) 3-8 +// 8 MultiTap disabled: based on device ID connected, enabled: 16 (4x8) + +reg W_RXWT_r ; + +always @(posedge clk) begin + W_RXWT_r <= W_RXWT; + if (~W_RXWT && W_RXWT_r) begin // record received value one cycle after RXWT + case (W_byte_cnt) + 1: o_RXD_ID <= W_RXD_DAT; + 2: o_RXD_0 <= W_RXD_DAT; + 3: o_RXD_1 <= W_RXD_DAT; + 4: o_RXD_2 <= W_RXD_DAT; + 5: o_RXD_3 <= W_RXD_DAT; + 6: o_RXD_4 <= W_RXD_DAT; + 7: o_RXD_5 <= W_RXD_DAT; + 8: o_RXD_6 <= W_RXD_DAT; + default:; + endcase + end +end + +endmodule + + +// timing signal generation module +module ps_pls_gan( + input clk, + input R_CE, + input i_CLK, + input i_RSTn, + input i_TYPE, + + output o_RXWT, // pulse to input RX byte + output o_TXWT, // pulse to output TX byte + output o_TXSET, + output o_TXEN, + output o_psCLK, // SPI clock to send to controller + output o_ATT1, // 0: active + output o_ATT2, // 0: active + output [3:0] o_byte_cnt // index for byte received +); + +parameter Timer_size = `Timer_siz; + +reg [3:0] o_byte_cnt_r ; +reg [`Timer_siz-1:0] Timer ; +reg RXWT, TXWT, TXSET ; +reg psCLK_gate ; // 0: send i_CLK on wire +reg psATT1 ; +reg psATT2 ; + +// increment timer on i_CLK rising edge +always @(posedge clk) begin + if (~i_RSTn) + Timer <= 0; + else if (R_CE) + Timer <= Timer+1; +end + +always @(posedge clk) begin + if (~i_RSTn) begin + psCLK_gate <= 1; + RXWT <= 0; + TXWT <= 0; + TXSET <= 0; + end else begin + TXWT <= 0; + RXWT <= 0; + TXSET <= 0; + if (R_CE) begin + case (Timer[4:0]) + 6: TXSET <= 1; + 9: TXWT <= 1; // pulse to set byte to send + 12: psCLK_gate <= 0; // send 8 cycles of clock: + 20: begin + psCLK_gate <= 1; // 13,14,15,16,17,18,19,20 + RXWT <= 1; // pulse to get received byte + end + default:; + endcase + end + end +end + +always @(posedge clk) begin + if (~i_RSTn) begin + psATT1 <= 1; + psATT2 <= 1; + end + else if (R_CE) begin + if (Timer[9:0] == 0) begin + psATT1 <= Timer[10]; //switch each 2^10 R_CE cycles + psATT2 <= ~Timer[10]; + end + else if ((i_TYPE == 0)&&(Timer[9:0] == 158)) begin// end of byte 4 + psATT1 <= 1; + psATT2 <= 1; + end + else if ((i_TYPE == 1)&&(Timer[9:0] == 286)) begin // end of byte 9 + psATT1 <= 1; + psATT2 <= 1; + end + + end +end + +always @(posedge clk) begin // update o_byte_cnt_r + if (!i_RSTn) + o_byte_cnt_r <= 0; + else if (R_CE) begin + if (Timer[9:0] == 0) + o_byte_cnt_r <= 0; + else begin + if (Timer[4:0] == 31) begin // received a byte + if (i_TYPE == 0 && o_byte_cnt_r == 5) + o_byte_cnt_r <= o_byte_cnt_r; + else if (i_TYPE == 1 && o_byte_cnt_r == 9) + o_byte_cnt_r <= o_byte_cnt_r; + else + o_byte_cnt_r <= o_byte_cnt_r + 4'd1; + end + end + end +end + +assign o_psCLK = psCLK_gate | i_CLK | ~(psATT1 ^ psATT2); +assign o_ATT1 = psATT1; +assign o_ATT2 = psATT2; +assign o_RXWT = (~psATT1 | ~psATT2) & RXWT; +assign o_TXSET = (~psATT1 | ~psATT2) & TXSET; +assign o_TXWT = (~psATT1 | ~psATT2) & TXWT; +assign o_TXEN = (~psATT1 | ~psATT2) & ~psCLK_gate; +assign o_byte_cnt = o_byte_cnt_r; + +endmodule + +// receiver +module ps_rxd( + input clk, + input R_CE, // one bit is transmitted on rising edge + input i_RSTn, + input i_WT, // pulse to output byte to o_RXD_DAT + input i_psRXD, + output reg [7:0] o_RXD_DAT +); + +reg [7:0] sp; + +always @(posedge clk) + if (~i_RSTn) begin + sp <= 1; + o_RXD_DAT <= 1; + end else begin + if (R_CE) // posedge i_CLK + sp <= { i_psRXD, sp[7:1]}; + if (i_WT) + o_RXD_DAT <= sp; + end + +endmodule + +// transmitter +module ps_txd ( + input clk, + input F_CE, // transmit on falling edge of i_CLK + input i_RSTn, + input i_WT, // pulse to load data to transmit + input i_EN, // 1 to do transmission + input [7:0] i_TXD_DAT, // byte to transmit, lowest bit first + output reg o_psTXD // output pin +); + +reg [7:0] ps; // data buffer + +always @(posedge clk) begin + if (~i_RSTn) begin + o_psTXD <= 1; + ps <= 0; + end else begin + if (i_WT) + ps <= i_TXD_DAT; + if (F_CE) begin // bit is sent on falling edge of i_CLK + if (i_EN) begin + o_psTXD <= ps[0]; + ps <= {1'b1, ps[7:1]}; + end else begin + o_psTXD <= 1'd1; + ps <= ps; + end + end + end +end + +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/hq2x.sv b/target/pocket/analogizer/hq2x.sv new file mode 100644 index 0000000..d8552ad --- /dev/null +++ b/target/pocket/analogizer/hq2x.sv @@ -0,0 +1,371 @@ +// +// +// Copyright (c) 2012-2013 Ludvig Strigeus +// Copyright (c) 2017,2018 Sorgelig +// +// This program is GPL Licensed. See COPYING for the full license. +// +// +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +// altera message_off 10030 + +module Hq2x #(parameter LENGTH, parameter HALF_DEPTH) +( + input clk, + + input ce_in, + input [DWIDTH:0] inputpixel, + input mono, + input disable_hq2x, + input reset_frame, + input reset_line, + + input ce_out, + input [1:0] read_y, + input hblank, + output [DWIDTH:0] outpixel +); + + +localparam AWIDTH = $clog2(LENGTH)-1; +localparam DWIDTH = HALF_DEPTH ? 11 : 23; +localparam DWIDTH1 = DWIDTH+1; + +(* romstyle = "M10K" *) reg [5:0] hqTable[256]; +initial begin + hqTable = '{ + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39, + 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 35, 35, 23, 15, 7, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43, + 19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 51, 35, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 35, 35, 23, 61, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 7, 35, 23, 61, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 58, 23, 15, 51, 35, 23, 61, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 39, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 39, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 35, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 43, + 19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 7, 35, 23, 15, 7, 43 + }; +end + +wire [5:0] hqrule = hqTable[nextpatt]; + +reg [23:0] Prev0, Prev1, Prev2, Curr0, Curr1, Curr2, Next0, Next1, Next2; +reg [23:0] A, B, D, F, G, H; +reg [7:0] pattern, nextpatt; +reg [1:0] cyc; + +reg curbuf; +reg prevbuf = 0; +wire iobuf = !curbuf; + +wire diff0, diff1; +DiffCheck diffcheck0(Curr1, (cyc == 0) ? Prev0 : (cyc == 1) ? Curr0 : (cyc == 2) ? Prev2 : Next1, diff0); +DiffCheck diffcheck1(Curr1, (cyc == 0) ? Prev1 : (cyc == 1) ? Next0 : (cyc == 2) ? Curr2 : Next2, diff1); + +wire [7:0] new_pattern = {diff1, diff0, pattern[7:2]}; + +wire [23:0] X = (cyc == 0) ? A : (cyc == 1) ? Prev1 : (cyc == 2) ? Next1 : G; +wire [23:0] blend_result_pre; +Blend blender(clk, ce_in, disable_hq2x ? 6'd0 : hqrule, Curr0, X, B, D, F, H, blend_result_pre); + +wire [DWIDTH:0] Curr20tmp; +wire [23:0] Curr20 = HALF_DEPTH ? h2rgb(Curr20tmp) : Curr20tmp; +wire [DWIDTH:0] Curr21tmp; +wire [23:0] Curr21 = HALF_DEPTH ? h2rgb(Curr21tmp) : Curr21tmp; + +reg [AWIDTH:0] wrin_addr2; +reg [DWIDTH:0] wrpix; +reg wrin_en; + +function [23:0] h2rgb; + input [11:0] v; +begin + h2rgb = mono ? {v[7:0], v[7:0], v[7:0]} : {v[11:8],v[11:8],v[7:4],v[7:4],v[3:0],v[3:0]}; +end +endfunction + +function [11:0] rgb2h; + input [23:0] v; +begin + rgb2h = mono ? {4'b0000, v[23:20], v[19:16]} : {v[23:20], v[15:12], v[7:4]}; +end +endfunction + +hq2x_in #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_in +( + .clk(clk), + + .rdaddr(offs), + .rdbuf0(prevbuf), + .rdbuf1(curbuf), + .q0(Curr20tmp), + .q1(Curr21tmp), + + .wraddr(wrin_addr2), + .wrbuf(iobuf), + .data(wrpix), + .wren(wrin_en) +); + +reg [AWIDTH+1:0] read_x; +reg [AWIDTH+1:0] wrout_addr; +reg wrout_en; +reg [DWIDTH1*4-1:0] wrdata, wrdata_pre; +wire [DWIDTH1*4-1:0] outpixel_x4; +reg [DWIDTH1*2-1:0] outpixel_x2; + +assign outpixel = read_x[0] ? outpixel_x2[DWIDTH1*2-1:DWIDTH1] : outpixel_x2[DWIDTH:0]; + +hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH+1), .DWIDTH(DWIDTH1*4-1)) hq2x_out +( + .clock(clk), + + .rdaddress({read_x[AWIDTH+1:1],read_y[1]}), + .q(outpixel_x4), + + .data(wrdata), + .wraddress(wrout_addr), + .wren(wrout_en) +); + +always @(posedge clk) begin + if(ce_out) begin + if(read_x[0]) outpixel_x2 <= read_y[0] ? outpixel_x4[DWIDTH1*4-1:DWIDTH1*2] : outpixel_x4[DWIDTH1*2-1:0]; + if(~hblank & ~&read_x) read_x <= read_x + 1'd1; + if(hblank) read_x <= 0; + end +end + +wire [DWIDTH:0] blend_result = HALF_DEPTH ? rgb2h(blend_result_pre) : blend_result_pre[DWIDTH:0]; + +reg [AWIDTH:0] offs; +always @(posedge clk) begin + reg old_reset_line; + reg old_reset_frame; + reg [3:0] wrdata_finished; + reg [AWIDTH+1:0] waddr; + + wrout_en <= 0; + wrin_en <= 0; + + if(ce_in) begin + + // blend_result has been delayed by 4 cycles + case(cyc) + 0: wrdata[DWIDTH:0] <= blend_result; + 1: wrdata[DWIDTH1+DWIDTH:DWIDTH1] <= blend_result; + 2: wrdata[DWIDTH1*3+DWIDTH:DWIDTH1*3] <= blend_result; + 3: wrdata[DWIDTH1*2+DWIDTH:DWIDTH1*2] <= blend_result; + endcase + + wrdata_finished <= wrdata_finished << 1; + if(wrdata_finished[3]) begin + wrout_en <= 1; + wrout_addr <= waddr; + end + + if(~&offs) begin + if (cyc == 1) begin + Prev2 <= Curr20; + Curr2 <= Curr21; + Next2 <= HALF_DEPTH ? h2rgb(inputpixel) : inputpixel; + wrpix <= inputpixel; + wrin_addr2 <= offs; + wrin_en <= 1; + end + + if(cyc==3) begin + offs <= offs + 1'd1; + waddr <= {offs, curbuf}; + wrdata_finished[0] <= 1; + end + end + + pattern <= new_pattern; + if(cyc==3) begin + nextpatt <= {new_pattern[7:6], new_pattern[3], new_pattern[5], new_pattern[2], new_pattern[4], new_pattern[1:0]}; + {A, G} <= {Prev0, Next0}; + {B, F, H, D} <= {Prev1, Curr2, Next1, Curr0}; + {Prev0, Prev1} <= {Prev1, Prev2}; + {Curr0, Curr1} <= {Curr1, Curr2}; + {Next0, Next1} <= {Next1, Next2}; + end else begin + nextpatt <= {nextpatt[5], nextpatt[3], nextpatt[0], nextpatt[6], nextpatt[1], nextpatt[7], nextpatt[4], nextpatt[2]}; + {B, F, H, D} <= {F, H, D, B}; + end + + cyc <= cyc + 1'b1; + if(old_reset_line && ~reset_line) begin + old_reset_frame <= reset_frame; + offs <= 0; + cyc <= 0; + curbuf <= ~curbuf; + prevbuf <= curbuf; + {Prev0, Prev1, Prev2, Curr0, Curr1, Curr2, Next0, Next1, Next2} <= '0; + if(old_reset_frame & ~reset_frame) begin + curbuf <= 0; + prevbuf <= 0; + end + end + + old_reset_line <= reset_line; + end +end + +endmodule + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +module hq2x_in #(parameter LENGTH, parameter DWIDTH) +( + input clk, + + input [AWIDTH:0] rdaddr, + input rdbuf0, rdbuf1, + output[DWIDTH:0] q0,q1, + + input [AWIDTH:0] wraddr, + input wrbuf, + input [DWIDTH:0] data, + input wren +); + +localparam AWIDTH = $clog2(LENGTH)-1; +wire [DWIDTH:0] out[2]; +assign q0 = out[rdbuf0]; +assign q1 = out[rdbuf1]; + +hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]); +hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]); + +endmodule + +module hq2x_buf #(parameter NUMWORDS, parameter AWIDTH, parameter DWIDTH) +( + input clock, + input [DWIDTH:0] data, + input [AWIDTH:0] rdaddress, + input [AWIDTH:0] wraddress, + input wren, + output reg [DWIDTH:0] q +); + +reg [DWIDTH:0] ram[0:NUMWORDS-1]; + +always_ff@(posedge clock) begin + if(wren) ram[wraddress] <= data; + q <= ram[rdaddress]; +end + +endmodule + +//////////////////////////////////////////////////////////////////////////////////////////////////////// + +module DiffCheck +( + input [23:0] rgb1, + input [23:0] rgb2, + output result +); + + wire [7:0] r = rgb1[7:1] - rgb2[7:1]; + wire [7:0] g = rgb1[15:9] - rgb2[15:9]; + wire [7:0] b = rgb1[23:17] - rgb2[23:17]; + wire [8:0] t = $signed(r) + $signed(b); + wire [9:0] y = $signed(t) + $signed({g[7], g}); + wire [8:0] u = $signed(r) - $signed(b); + wire [9:0] v = $signed({g, 1'b0}) - $signed(t); + + // if y is inside (-96..96) + wire y_inside = (y < 10'h60 || y >= 10'h3a0); + + // if u is inside (-16, 16) + wire u_inside = (!u[8:4] || &u[8:4]); //(u < 9'h10 || u >= 9'h1f0); + + // if v is inside (-24, 24) + wire v_inside = (v < 10'h18 || v >= 10'h3e8); + assign result = !(y_inside && u_inside && v_inside); + +endmodule + +module Blend +( + input clk, + input clk_en, + input [5:0] rule, + input [23:0] E, + input [23:0] A, + input [23:0] B, + input [23:0] D, + input [23:0] F, + input [23:0] H, + output [23:0] Result +); + + localparam BLEND1 = 7'b110_10_00; // (A * 12 + B * 4 ) >> 4 + localparam BLEND2 = 7'b100_10_10; // (A * 8 + B * 4 + C * 4) >> 4 + localparam BLEND3 = 7'b101_10_01; // (A * 10 + B * 4 + C * 2) >> 4 + localparam BLEND4 = 7'b110_01_01; // (A * 12 + B * 2 + C * 2) >> 4 + localparam BLEND5 = 7'b010_11_11; // (A * 4 + B * 6 + C * 6) >> 4 + localparam BLEND6 = 7'b111_00_00; // (A * 14 + B * 1 + C * 1) >> 4 + + reg [23:0] a,b,d,e,h,f; + reg [3:0] bl_rule; + reg [1:0] df_rule; + always @(posedge clk) if (clk_en) begin + {bl_rule,df_rule} <= rule; + a <= A; b <= B; d <= D; e <= E; f <= F; h <= H; + end + + wire is_diff; + DiffCheck diff_checker(df_rule[1] ? b : h, df_rule[0] ? d : f, is_diff); + + reg [23:0] i10,i20,i30; + reg [6:0] op0; + always @(posedge clk) if (clk_en) begin + i10 <= e; + case({!is_diff, bl_rule}) + 1,11,12,13,17: {op0, i20, i30} <= {BLEND1, a, 24'd0}; + 2,14,18: {op0, i20, i30} <= {BLEND1, d, 24'd0}; + 3,15,19: {op0, i20, i30} <= {BLEND1, b, 24'd0}; + 4,20,24,27: {op0, i20, i30} <= {BLEND2, d, b}; + 5,21: {op0, i20, i30} <= {BLEND2, a, b}; + 6,22: {op0, i20, i30} <= {BLEND2, a, d}; + 25,29: {op0, i20, i30} <= {BLEND5, d, b}; + 26: {op0, i20, i30} <= {BLEND6, d, b}; + 28: {op0, i20, i30} <= {BLEND4, d, b}; + 30: {op0, i20, i30} <= {BLEND3, b, d}; + 31: {op0, i20, i30} <= {BLEND3, d, b}; + default: {op0, i20, i30} <= {BLEND1, e, 24'd0}; + endcase + end + + reg [23:0] i1,i2,i3; + reg [6:0] op; + always @(posedge clk) if (clk_en) begin + op <= op0; i1 <= i10; i2 <= i20; i3 <= i30; + end + + function [34:0] mul24x3; + input [23:0] op1; + input [2:0] op2; + begin + mul24x3 = 0; + if(op2[0]) mul24x3 = mul24x3 + {op1[23:16], 4'b0000, op1[15:8], 4'b0000, op1[7:0]}; + if(op2[1]) mul24x3 = mul24x3 + {op1[23:16], 4'b0000, op1[15:8], 4'b0000, op1[7:0], 1'b0}; + if(op2[2]) mul24x3 = mul24x3 + {op1[23:16], 4'b0000, op1[15:8], 4'b0000, op1[7:0], 2'b00}; + end + endfunction + + wire [35:0] res = {mul24x3(i1, op[6:4]), 1'b0} + mul24x3(i2, {op[3:2], !op[3:2]}) + mul24x3(i3, {op[1:0], !op[3:2]}); + + always @(posedge clk) if (clk_en) Result <= {res[35:28],res[23:16],res[11:4]}; + +endmodule diff --git a/target/pocket/analogizer/openFPGA_Pocket_Analogizer.v b/target/pocket/analogizer/openFPGA_Pocket_Analogizer.v new file mode 100644 index 0000000..0e1fbf8 --- /dev/null +++ b/target/pocket/analogizer/openFPGA_Pocket_Analogizer.v @@ -0,0 +1,531 @@ +//This module encapsulates all Analogizer adapter signals +// Original work by @RndMnkIII. With code modules from @MikeSimonson, @Mist-Project, @RandyS, @jotego, Scott Larson, @tomasz and others. +// Releases: +// * 1.0 [01/01/2024] Initial RGBS output mode +// * 1.1 Added SOG modes: RGsB, YPbPt +// * 1.2 Added Mike Simon Y/C module, Scandoubler SVGA Mist module. +// * 1.3 [11/02/2025] Added Bridge interface to directly access to the Analogizer settings, now returns the settings. Added NES SNAC Zapper support. +// * 1.4 [20/08/2026] Added PS/2 Keyboard and Mouse support (hook) + NES/SNES/DB15 SNAC game adapter. Needs custom SNAC adapter. Analogizer global enable/disable is read from configuration file. + +// *** Analogizer R.3 adapter *** +// * WHEN SOG SWITCH IS IN ON POSITION, OUTPUTS CSYNC ON G CHANNEL +// # WHEN YPbPr VIDEO OUTPUT IS SELECTED, Y->G, Pr->R, Pb->B +//Pin mappings: VGA CONNECTOR USB3 TYPE A FEMALE CONNECTOR (SNAC) +// ______________________________________________________________________________________________________________________________________________________________________________________________________ +// / VS HS R# G*# B# 1 2 3 4 5 6 7 8 9 \ +// | | | | | | VBUS D- D+ GND RX- RX+ GND_D TX- TX+ | +//FUNCTION: | | | | | | +5V OUT1 OUT2 GND IO3 IN4 IO5 IO6 IN7 | +// | A | | | | | ^ ^ ^ | ^ ^ | | +// | N SOG | | | | | | | V V V V V | +// | A ------- | | | | | | +// | O OFF | S |--GND | | +------------+ | +// | L | W | | | SYNC | | | +// PIN DIR: | G | I +--------------------->| |---------------------------------------------------------------------------------------------------------+ | +// ^ OUTPUT | I | T | | | | RGB DAC | | | +// V INPUT | Z | C | | | | |===================================================================++ | | +// | E ON ===| H |--------+ | +------------+ || | | +// | R ------- | | || | | /BLANK || | | +// | | +--------+ || | +------------------------------------------------------------------+ || | | | +// | R +------+ | || +===============================++ | || | | +// | 2 | | || || | || | | +// | CONF.B IO5V --- | | \\================================ \\================================ | \\================================ VID IO3^ IO6^ | +// | CONF.A IN4 --- IN7 IO3V VS HS R0 R1 R2 R3 R4 R5 G0 G1 G2 G3 G4 G5 /BLK B0 B1 B2 B3 B4 B5 CLK OUT1 OUT2 IO5^ IO6V | +// | __3.3V__ |___ | __ |_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____^__GND__ | +//POCKET | / V V V V ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ V \ | +//CARTRIDGE PIN #: \____| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |___/ +// \_________|____|____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|_______/ +//Pocket Pin Name: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +//cart_tran_bank0[7] --------------------+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +//cart_tran_bank0[6] -------------------------+ | | | | | | | | | | | | | | | | | | | | | | | | | | | | +//cart_tran_bank0[5] ------------------------------+ | | | | | | | | | | | | | | | | | | | | | | | | | | | +//cart_tran_bank0[4] ------------------------------------+ | | | | | | | | | | | | | | | | | | | | | | | | | | +//cart_tran_bank3[0] ------------------------------------------+ | | | | | | | | | | | | | | | | | | | | | | | | | +//cart_tran_bank3[1] ------------------------------------------------+ | | | | | | | | | | | | | | | | | | | | | | | | +//cart_tran_bank3[2] ------------------------------------------------------+ | | | | | | | | | | | | | | | | | | | | | | | +//cart_tran_bank3[3] ------------------------------------------------------------+ | | | | | | | | | | | | | | | | | | | | | | +//cart_tran_bank3[4] ------------------------------------------------------------------+ | | | | | | | | | | | | | | | | | | | | | +//cart_tran_bank3[5] ------------------------------------------------------------------------+ | | | | | | | | | | | | | | | | | | | | +//cart_tran_bank3[6] ------------------------------------------------------------------------------+ | | | | | | | | | | | | | | | | | | | +//cart_tran_bank3[7] ------------------------------------------------------------------------------------+ | | | | | | | | | | | | | | | | | | +//------------------ | | | | | | | | | | | | | | | | | | +//cart_tran_bank2[0] ------------------------------------------------------------------------------------------+ | | | | | | | | | | | | | | | | | +//cart_tran_bank2[1] ------------------------------------------------------------------------------------------------+ | | | | | | | | | | | | | | | | +//cart_tran_bank2[2] ------------------------------------------------------------------------------------------------------+ | | | | | | | | | | | | | | | +//cart_tran_bank2[3] ------------------------------------------------------------------------------------------------------------+ | | | | | | | | | | | | | | +//cart_tran_bank2[4] ------------------------------------------------------------------------------------------------------------------+ | | | | | | | | | | | | | +//cart_tran_bank2[5] ------------------------------------------------------------------------------------------------------------------------+ | | | | | | | | | | | | +//cart_tran_bank2[6] ------------------------------------------------------------------------------------------------------------------------------+ | | | | | | | | | | | +//cart_tran_bank2[7] ------------------------------------------------------------------------------------------------------------------------------------+ | | | | | | | | | | +//------------------ | | | | | | | | | | +//cart_tran_bank1[0] ------------------------------------------------------------------------------------------------------------et_sw------------------------------+ | | | | | | | | | +//cart_tran_bank1[1] ------------------------------------------------------------------------------------------------------------------------------------------------+ | | | | | | | | +//cart_tran_bank1[2] ------------------------------------------------------------------------------------------------------------------------------------------------------+ | | | | | | | +//cart_tran_bank1[3] ------------------------------------------------------------------------------------------------------------------------------------------------------------+ | | | | | | +//cart_tran_bank1[4] ------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | | | | | +//cart_tran_bank1[5] ------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | | | | +//cart_tran_bank1[6] ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | | | +//cart_tran_bank1[7] ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | | +//cart_tran_pin30 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | +//cart_tran_pin31 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +`default_nettype none +`timescale 1ns / 1ps + +module openFPGA_Pocket_Analogizer #(parameter MASTER_CLK_FREQ=50_000_000, parameter LINE_LENGTH, parameter ADDRESS_ANALOGIZER_CONFIG=8'hF7) ( + input wire clk_74a, + input wire i_clk, + input wire i_rst_apf, //active High + input wire i_rst_core,//active High + //Video interface + input wire video_clk, + input wire [7:0] R, + input wire [7:0] G, + input wire [7:0] B, + input wire Hblank, + input wire Vblank, + input wire Hsync, + input wire Vsync, + + //openFPGA Bridge interface + input wire bridge_endian_little, + input wire [31:0] bridge_addr, + input wire bridge_rd, + output reg [31:0] analogizer_bridge_rd_data, + input wire bridge_wr, + input wire [31:0] bridge_wr_data, + + //Analogizer settings + output wire analogizer_ena_out, + output wire [4:0] snac_game_cont_type_out, + output wire [3:0] snac_cont_assignment_out, + output wire [3:0] analogizer_video_type_out, + output wire [2:0] SC_fx_out, + output wire pocket_blank_screen_out, + output wire analogizer_osd_out, + + //Video Y/C Encoder interface + input wire [39:0] CHROMA_PHASE_INC, + input wire [26:0] COLORBURST_RANGE, + input wire [4:0] CHROMA_ADD, + input wire [4:0] CHROMA_MUL, + input wire PALFLAG, + //Video SVGA Scandoubler interface + input wire ce_pix, + input wire scandoubler, //logic for disable/enable the scandoubler + //SNAC interface + output wire [15:0] p1_btn_state, + output wire [31:0] p1_joy_state, + output wire [15:0] p2_btn_state, + output wire [31:0] p2_joy_state, + output wire [15:0] p3_btn_state, + output wire [15:0] p4_btn_state, + //PSX rumble interface joy1, joy2 + input [1:0] i_VIB_SW1, // Vibration SW VIB_SW[0] Small Moter OFF 0:ON 1: + //VIB_SW[1] Bic Moter OFF 0:ON 1(Dualshook Only) + input [7:0] i_VIB_DAT1, // Vibration(Bic Moter)Data 8'H00-8'HFF (Dualshook Only) + input [1:0] i_VIB_SW2, + input [7:0] i_VIB_DAT2, + // + output wire busy, + //Pocket Analogizer IO interface to the cartridge port + inout wire [7:0] cart_tran_bank2, + output wire cart_tran_bank2_dir, + inout wire [7:0] cart_tran_bank3, + output wire cart_tran_bank3_dir, + inout wire [7:0] cart_tran_bank1, + output wire cart_tran_bank1_dir, + inout wire [7:4] cart_tran_bank0, + output wire cart_tran_bank0_dir, + inout wire cart_tran_pin30, + output wire cart_tran_pin30_dir, + output wire cart_pin30_pwroff_reset, + inout wire cart_tran_pin31, + output wire cart_tran_pin31_dir, + //debug + output wire [3:0] DBG_TX, + output wire o_stb, + //PS/2 Keyboard SNAC interface decoded + output wire o_ps2_code_new, + output wire [7:0] o_ps2_code, + //PS/2 Mouse SNAC raw interface + output wire o_mouse_clk, //pin31 (MCLK) + output wire o_mouse_dat //bank0[5] (MDAT) +); + + //Configuration file dat + //reg [31:0] analogizer_bridge_rd_data; + reg [31:0] analogizer_config = 0; + wire [31:0] analogizer_config_s; + reg [31:0] config_mem [16]; //configuration memory + + synch_3 #(.WIDTH(32)) analogizer_sync({i_busyr,analogizer_config[30:0]}, analogizer_config_s, i_clk); + + wire [31:0] memory_out; + reg [3:0] word_cnt; + reg i_busyr; + + // handle memory mapped I/O from pocket + always @(posedge clk_74a) begin + if(i_rst_apf) begin + i_busyr <= 1'b1; + end + else begin + i_busyr <= 1'b0; + end + end + + always @(posedge clk_74a) begin + if(bridge_wr) begin + case(bridge_addr[31:24]) + ADDRESS_ANALOGIZER_CONFIG: begin + if (bridge_addr[3:0] == 4'h0) begin + word_cnt <= 4'h1; + analogizer_config <= bridge_endian_little ? bridge_wr_data : {bridge_wr_data[7:0],bridge_wr_data[15:8],bridge_wr_data[23:16],bridge_wr_data[31:24]}; + end + else begin + word_cnt <= word_cnt + 4'h1; + config_mem[bridge_addr[3:0]] <= bridge_endian_little ? bridge_wr_data : {bridge_wr_data[7:0],bridge_wr_data[15:8],bridge_wr_data[23:16],bridge_wr_data[31:24]}; + end + end + endcase + end + if(bridge_rd) begin + case(bridge_addr[31:24]) + ADDRESS_ANALOGIZER_CONFIG: begin + if (bridge_addr[3:0] == 4'h0) analogizer_bridge_rd_data <= bridge_endian_little ? analogizer_config_s : {analogizer_config_s[7:0],analogizer_config_s[15:8],analogizer_config_s[23:16],analogizer_config_s[31:24]}; //invert byte order to writeback to the Sav folders + else analogizer_bridge_rd_data <= bridge_endian_little ? config_mem[bridge_addr[3:0]] : {memory_out[7:0],memory_out[15:8],memory_out[23:16],memory_out[31:24]}; + end + endcase + end + end + assign memory_out = config_mem[bridge_addr[3:0]]; + assign busy = i_busyrr; + reg i_busyrr; + + always @(posedge i_clk) begin + analogizer_ena <= analogizer_config_s[5]; + snac_game_cont_type <= analogizer_config_s[4:0]; + snac_cont_assignment <= analogizer_config_s[9:6]; + analogizer_video_type <= analogizer_config_s[13:10]; + pocket_blank_screen <= analogizer_config_s[14]; + analogizer_osd_out2 <= analogizer_config_s[15]; + i_busyrr <= analogizer_config_s[31]; + end + + wire conf_AB = (snac_game_cont_type >= 5'd16); + + //0 disable, 1 scanlines 25%, 2 scanlines 50%, 3 scanlines 75%, 4 hq2x + always @(posedge i_clk) begin + if(analogizer_video_type >= 4'd5) SC_fx <= analogizer_video_type - 4'd5; +end + +reg analogizer_ena; +reg [3:0] analogizer_video_type; +reg [4:0] snac_game_cont_type; +reg [3:0] snac_cont_assignment; +reg [2:0] SC_fx; +reg pocket_blank_screen; +reg analogizer_osd_out2; + +assign analogizer_ena_out = analogizer_ena; +assign analogizer_video_type_out = analogizer_video_type; +assign snac_game_cont_type_out = snac_game_cont_type; +assign snac_cont_assignment_out = snac_cont_assignment; +assign SC_fx_out = SC_fx; +assign pocket_blank_screen_out = pocket_blank_screen; +assign analogizer_osd_out = analogizer_osd_out2; +//------------------------------------------------------------------------ + + wire [7:4] CART_BK0_OUT ; + wire [7:4] CART_BK0_IN ; + wire CART_BK0_DIR ; + wire [7:6] CART_BK1_OUT_P76 ; + wire CART_PIN30_OUT ; + wire CART_PIN30_IN ; + wire CART_PIN30_DIR ; + wire CART_PIN31_OUT ; + wire CART_PIN31_IN ; + wire CART_PIN31_DIR ; + + openFPGA_Pocket_Analogizer_SNAC #(.MASTER_CLK_FREQ(MASTER_CLK_FREQ)) snac + ( + .i_clk(i_clk), + .i_rst(i_rst_apf), + .conf_AB(conf_AB), //0 conf. A(default), 1 conf. B (see graph above) + .game_cont_type(snac_game_cont_type), //0-15 Conf. A, 16-31 Conf. B + //.game_cont_sample_rate(game_cont_sample_rate), //0 compatibility mode (slowest), 1 normal mode, 2 fast mode, 3 superfast mode + .p1_btn_state(p1_btn_state), + .p1_joy_state(p1_joy_state), + .p2_btn_state(p2_btn_state), + .p2_joy_state(p2_joy_state), + .p3_btn_state(p3_btn_state), + .p4_btn_state(p4_btn_state), + .i_VIB_SW1(i_VIB_SW1), .i_VIB_DAT1(i_VIB_DAT1), .i_VIB_SW2(i_VIB_SW2), .i_VIB_DAT2(i_VIB_DAT2), + .busy(), + //SNAC Pocket cartridge port interface (see graph above) + .CART_BK0_OUT(CART_BK0_OUT), + .CART_BK0_IN(CART_BK0_IN), + .CART_BK0_DIR(CART_BK0_DIR), + .CART_BK1_OUT_P76(CART_BK1_OUT_P76), + .CART_PIN30_OUT(CART_PIN30_OUT), + .CART_PIN30_IN(CART_PIN30_IN), + .CART_PIN30_DIR(CART_PIN30_DIR), + .CART_PIN31_OUT(CART_PIN31_OUT), + .CART_PIN31_IN(CART_PIN31_IN), + .CART_PIN31_DIR(CART_PIN31_DIR), + //debug + .DBG_TX(DBG_TX), + .o_stb(o_stb), + //PS/2 Keyboard SNAC: scancodes + .o_ps2_code_new(o_ps2_code_new), + .o_ps2_code(o_ps2_code) + ); + + +//--------------------------------------------------------------------- +// Fix video +//--------------------------------------------------------------------- +wire ANALOGIZER_DE = ~(HBL || VBL); +wire ANALOGIZER_CSYNC = ~^{HS, VS}; + +wire hs_fix,vs_fix; +sync_fix sync_h(i_clk, Hsync, hs_fix); +sync_fix sync_v(i_clk, Vsync, vs_fix); + +reg [7:0] R_fix,G_fix,B_fix; + +reg CE,HS,VS,HBL,VBL; +always @(posedge i_clk) begin + reg old_ce; + old_ce <= ce_pix; + CE <= 0; + if(~old_ce & ce_pix) begin + CE <= 1; + HS <= hs_fix; + // if(~HS & hs_fix) VS <= vs_fix; + //FIX ONLY FOR XAIN'D SLEENA + VS <= vs_fix; + + {R_fix,G_fix,B_fix} <= {R,G,B}; + HBL <= Hblank; + // if(HBL & ~Hblank) VBL <= Vblank; + //FIX ONLY FOR XAIN'D SLEENA + VBL <= Vblank; + end +end +//--------------------------------------------------------------------------- + + //Choose type of analog video type of signal + reg [5:0] Rout, Gout, Bout ; + reg HsyncOut, VsyncOut, BLANKnOut ; + wire [7:0] Yout, PrOut, PbOut ; + wire [7:0] R_Sd, G_Sd, B_Sd ; + wire Hsync_Sd, Vsync_Sd ; + wire Hblank_Sd, Vblank_Sd ; + wire BLANKn_SD = ~(Hblank_Sd || Vblank_Sd) ; + + always @(*) begin + case(analogizer_video_type) + 4'h0: begin //RGBS + Rout = R_fix[7:2]&{6{ANALOGIZER_DE}}; + Gout = G_fix[7:2]&{6{ANALOGIZER_DE}}; + Bout = B_fix[7:2]&{6{ANALOGIZER_DE}}; + HsyncOut = ANALOGIZER_CSYNC; + VsyncOut = 1'b1; + BLANKnOut = ANALOGIZER_DE; + end + 4'h3, 4'h4: begin// Y/C Modes works for Analogizer R1, R2 Adapters + Rout = yc_o[23:18]; + Gout = yc_o[15:10]; + Bout = yc_o[7:2]; + HsyncOut = yc_cs; + VsyncOut = 1'b1; + BLANKnOut = 1'b1; + end + 4'h1: begin //RGsB + Rout = R_fix[7:2]&{6{ANALOGIZER_DE}}; + Gout = G_fix[7:2]&{6{ANALOGIZER_DE}}; + Bout = B_fix[7:2]&{6{ANALOGIZER_DE}}; + HsyncOut = 1'b1; + VsyncOut = ANALOGIZER_CSYNC; //to DAC SYNC pin, SWITCH SOG ON + BLANKnOut = ANALOGIZER_DE; + end + 4'h2: begin //YPbPr + Rout = PrOut[7:2]; + Gout = Yout[7:2]; + Bout = PbOut[7:2]; + HsyncOut = 1'b1; + VsyncOut = YPbPr_sync; //to DAC SYNC pin, SWITCH SOG ON + BLANKnOut = 1'b1; //ADV7123 needs this + end + 4'h5, 4'h6, 4'h7, 4'h8, 4'h9: begin //Scandoubler modes + Rout = vga_data_sl[23:18]; //R_Sd[7:2]; + Gout = vga_data_sl[15:10]; //G_Sd[7:2]; + Bout = vga_data_sl[7:2]; //B_Sd[7:2]; + HsyncOut = vga_hs_sl; //Hsync_Sd; + VsyncOut = vga_vs_sl; //Vsync_Sd; + BLANKnOut = 1'b1; + end + default: begin + Rout = 6'h0; + Gout = 6'h0; + Bout = 6'h0; + HsyncOut = HS; + VsyncOut = 1'b1; + BLANKnOut = ANALOGIZER_DE; + end + endcase + end + + wire YPbPr_sync, YPbPr_blank; + vga_out ybpr_video + ( + .clk(video_clk), + .ypbpr_en(1'b1), + .csync(ANALOGIZER_CSYNC), + .de(ANALOGIZER_DE), + .din({R_fix[7:0],G_fix[7:0],B_fix[7:0]}), //24 bits input + .dout({PrOut,Yout,PbOut}), //24 bits output + .csync_o(YPbPr_sync), + .de_o(YPbPr_blank) + ); + + wire [23:0] yc_o ; + //wire yc_hs, yc_vs, + wire yc_cs ; + + yc_out_legacy yc_out + ( + .clk(i_clk), + .PAL_EN(PALFLAG), + .PHASE_INC(CHROMA_PHASE_INC), + .COLORBURST_RANGE(COLORBURST_RANGE), + .MULFLAG(CHROMA_MUL), + .CHRADD(CHROMA_ADD), + .CHRMUL(CHROMA_MUL), + .hsync(HS), + .vsync(VS), + .csync(ANALOGIZER_CSYNC), + .dout(yc_o), + .din({R_fix, G_fix, B_fix}), //24bits input + .hsync_o(), + .vsync_o(), + .csync_o(yc_cs) //24bits output + ); + + wire ce_pix_Sd ; + scandoubler_2 #(.LENGTH(LINE_LENGTH), .HALF_DEPTH(0)) sd + ( + .clk_vid(i_clk), + .hq2x(SC_fx[2]), + + .ce_pix(CE), + .hs_in(HS), + .vs_in(VS), + .hb_in(HBL), + .vb_in(VBL), + .r_in({R_fix[7:0]&{8{ANALOGIZER_DE}}}), + .g_in({G_fix[7:0]&{8{ANALOGIZER_DE}}}), + .b_in({B_fix[7:0]&{8{ANALOGIZER_DE}}}), + + .ce_pix_out(ce_pix_Sd), + .hs_out(Hsync_Sd), + .vs_out(Vsync_Sd), + .hb_out(Hblank_Sd), + .vb_out(Vblank_Sd), + .r_out(R_Sd), + .g_out(G_Sd), + .b_out(B_Sd) + ); + + reg Hsync_SL, Vsync_SL, Hblank_SL, Vblank_SL ; + reg [7:0] R_SL, G_SL, B_SL ; + reg CE_PIX_SL, DE_SL ; + + always @(posedge video_clk) begin + Hsync_SL <= (scandoubler) ? Hsync_Sd : HS; + Vsync_SL <= (scandoubler) ? Vsync_Sd : VS; + Hblank_SL <= (scandoubler) ? Hblank_Sd : HBL; + Vblank_SL <= (scandoubler) ? Vblank_Sd : VBL; + R_SL <= (scandoubler) ? R_Sd : {R_fix[7:0]&{8{ANALOGIZER_DE}}}; + G_SL <= (scandoubler) ? G_Sd : {G_fix[7:0]&{8{ANALOGIZER_DE}}}; + B_SL <= (scandoubler) ? B_Sd : {B_fix[7:0]&{8{ANALOGIZER_DE}}}; + CE_PIX_SL <= (scandoubler) ? ce_pix_Sd : CE; + DE_SL <= ANALOGIZER_DE; + end + + +wire [23:0] vga_data_sl ; +wire vga_vs_sl, vga_hs_sl ; +scanlines_analogizer #(0) VGA_scanlines +( + .clk(video_clk), + + .scanlines(SC_fx[1:0]), + //.din(de_emu ? {R_SL, G_SL,B_SL} : 24'd0), + .din({R_SL, G_SL,B_SL}), + .hs_in(Hsync_SL), + .vs_in(Vsync_SL), + .de_in(DE_SL), + .ce_in(CE_PIX_SL), + + .dout(vga_data_sl), + .hs_out(vga_hs_sl), + .vs_out(vga_vs_sl), + .de_out(), + .ce_out() +); + + + //infer tri-state buffers for cartridge data signals + //BK0 + assign cart_tran_bank0 = i_rst_apf | ~analogizer_ena ? 4'hf : ((CART_BK0_DIR) ? CART_BK0_OUT : 4'hZ); //on reset state set ouput value to 4'hf + assign cart_tran_bank0_dir = i_rst_apf | ~analogizer_ena ? 1'b1 : CART_BK0_DIR; //on reset state set pin dir to output + assign CART_BK0_IN = cart_tran_bank0; + //BK3 + assign cart_tran_bank3 = i_rst_apf | ~analogizer_ena ? 8'hzz : {Rout[5:0],HsyncOut,VsyncOut}; //on reset state set ouput value to 8'hZ + assign cart_tran_bank3_dir = i_rst_apf | ~analogizer_ena ? 1'b0 : 1'b1; //on reset state set pin dir to input + //BK2 + assign cart_tran_bank2 = i_rst_apf | ~analogizer_ena ? 8'hzz : {Bout[0],BLANKnOut,Gout[5:0]}; //on reset state set ouput value to 8'hZ + assign cart_tran_bank2_dir = i_rst_apf | ~analogizer_ena ? 1'b0 : 1'b1; //on reset state set pin dir to input + //BK1 + assign cart_tran_bank1 = i_rst_apf | ~analogizer_ena ? 8'hzz : {CART_BK1_OUT_P76,video_clk,Bout[5:1]}; //on reset state set ouput value to 8'hZ + assign cart_tran_bank1_dir = i_rst_apf | ~analogizer_ena ? 1'b0 : 1'b1; //on reset state set pin dir to input + //PIN30 + assign cart_tran_pin30 = i_rst_apf | ~analogizer_ena ? 1'bz : ((CART_PIN30_DIR) ? CART_PIN30_OUT : 1'bZ); //on reset state set ouput value to 4'hf + assign cart_tran_pin30_dir = i_rst_apf | ~analogizer_ena ? 1'b0 : CART_PIN30_DIR; //on reset state set pin dir to output + assign CART_PIN30_IN = cart_tran_pin30; + assign cart_pin30_pwroff_reset = i_rst_apf | ~analogizer_ena ? 1'b0 : 1'b1; //1'b1 (GPIO USE) + //PIN31 + assign cart_tran_pin31 = i_rst_apf | ~analogizer_ena ? 1'bz : ((CART_PIN31_DIR) ? CART_PIN31_OUT : 1'bZ); //on reset state set ouput value to 4'hf + assign cart_tran_pin31_dir = i_rst_apf | ~analogizer_ena ? 1'b0 : CART_PIN31_DIR; //on reset state set pin dir to input + assign CART_PIN31_IN = cart_tran_pin31; + //--- PS/2 Mouse (holder) --- + assign o_mouse_clk = cart_tran_pin31; //MCLK + assign o_mouse_dat = cart_tran_bank0[5]; //MDAT +endmodule + +module sync_fix +( + input clk, + + input sync_in, + output sync_out +); + +assign sync_out = sync_in ^ pol; + +reg pol; +always @(posedge clk) begin + reg [31:0] cnt; + reg s1,s2; + + s1 <= sync_in; + s2 <= s1; + cnt <= s2 ? (cnt - 1) : (cnt + 1); + + if(~s2 & s1) begin + cnt <= 0; + pol <= cnt[31]; + end +end +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/openFPGA_Pocket_Analogizer_SNAC.sv b/target/pocket/analogizer/openFPGA_Pocket_Analogizer_SNAC.sv new file mode 100644 index 0000000..ba79964 --- /dev/null +++ b/target/pocket/analogizer/openFPGA_Pocket_Analogizer_SNAC.sv @@ -0,0 +1,584 @@ +//This module encapsulates all Analogizer adapter SNAC controllers +// Original work by @RndMnkIII. +// Date: 01/2024 +// Releases: +// * 1.0 [01/01/2024] Initial RGBS output mode +// * 1.1 Added SOG modes: RGsB, YPbPt +// * 1.2 Added Mike Simon Y/C module, Scandoubler SVGA Mist module. +// * 1.3 [11/02/2025] Added Bridge interface to directly access to the Analogizer settings, now returns the settings. Added NES SNAC Zapper support. +// * 1.4 [20/08/2026] Added PS/2 Keyboard and Mouse support (hook) + NES/SNES/DB15 SNAC game adapter. Needs custom SNAC adapter. Analogizer global enable/disable is read from configuration file. + +// *** Analogizer R.1 adapter *** +//SNAC mappings: +//USB 3 Type A connector ______________________________________________________________________________________ +//PIN_NUMBER: / 1 2 3 4 5 6 7 8 9 \ +//PIN_NAME: | VBUS D- D+ GND RX- RX+ GND_D TX- TX+ | +//FUNCTION: | +5V OUT1 OUT2 GND IO3 IN4 IO5 IO6 IN7 | +// | A ^ ^ ^ | ^ ^ | | +// | N | | | | +--|-------|-------+ | +// | A +-----------|-------|--------------|-------+ | | +----------------+ | +// | L | +-|-------|--------------|------------+ +--------+ | | +// | O | | | | | +------------+ | | | +// | G | | | | | +->| B B |----|------+ | | +// | I | | | | +---|->| CONF. SW. |<---+ | | | +// | Z | | | +---|-------<----------|<-| A A |<----+ | | | +// | E | | | | | | +------------+ | | | | +// | R | | | | | +-->-+------>--------->----+ | | | +// | I| I| | | +-------+ | | | | +// | R N| N| +---------+ | B|A B OUT | | | +// | 1 4| I 7| IO3| OUT1| OUT2| IO3|IO5 +-----------------------------------+ | +// | | O IN| A| |O |O O|O |A IN | | +// | I| 5+----|-----|-----|U----|U---U|U ---|--------------------------+ | +// | ___N|___B|IN__|___IN|_____|T____|T___T|T____|_____ | +//POCKET | / V V V V ^ ^ ^ V \ | +//CARTRIDGE PIN #: \___| 2 3 4 5 ... 28 29 30 31 |_____________________________/ +// \____|____|____|_____|_____|_____|_____|_____|_____/ +//Pocket Pin Name: | | | | | | | | +//cart_tran_bank0[7] ---------------+ | | | | | | | cart_tran_bank0_dir=1'b0; //input +//cart_tran_bank0[6] --------------------+ | | | | | | +//cart_tran_bank0[5] -------------------------+ | | | | | +//cart_tran_bank0[4] -------------------------------+ | | | | +//cart_tran_bank1[6] -------------------------------------+ | | | cart_tran_bank1_dir=1'b1 //output +//cart_tran_bank1[7] -------------------------------------------+ | | +//cart_tran_pin30 -------------------------------------------------+ | cart_tran_pin30_dir=1'b1, cart_pin30_pwroff_reset=1'b1 (GPIO USE) +//cart_tran_pin31 -------------------------------------------------------+ cart_tran_pin31_dir=1'b0 / 1'b1 +//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------- +// C O N F I G U R A T I O N A | CONFIGURATION B +//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------+----------- +// DEV TYPE 0X0 0X1 0X2 0X3 0X4 0X5 0X6 0XC,0XD,0XE,0XF | 0X11,0X13 | 0X14 +// PIN_NAME SNAC DISABLED DB15 NES SNES PCENGINE(2BTN) PCENGINE(6BTN) PCENGINE(MULTITAP) PS/2 K&M + NES/SNES/DB15 | PSX | JVS IO +//USB3 SNAC | | +//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------+----- +//VBUS +5V +5V +5V +5V +5V +5V +5V | +5V | +5V +//D- OUT1 CLK(O) CLK_1(O) CLK_1(O) CLR(O)(*) CLR(O)(*) CLR(O)(*) CLK(O) | AT1(O) | +//D+ OUT2 LAT(O) LAT(O) LAT(O) SEL(O)(*) SEL(O)(*) SEL(O)(*) LAT(O) | AT2(O) | +//GND GND GND GND GND GND GND GND | GND | GND +//RX- IO3 DAT(I) D0_1(I) D0_1(I) D2 (I)(*) D2 (I)(*) D2 (I)(*) DAT(I) | CLK(O) + | +//RX+ IN4 D4_2(I) IO_2(I) D0 (I)(*) D0 (I)(*) D0 (I)(*) KDAT | DAT(I) | +//GND_DRAIN IO5 CLK_2(O) CLK_2(O) KCLK | ACK(I) + | +//TX- IO6 DAT(I)(1) D3_2(I) D3_2(I) D1 (I)(*) D1 (I)(*) D1 (I)(*) MCLK | CMD(O) + | +//TX+ IN7 D0_2(I) D0_2(I) D3 (I)(*) D3 (I)(*) D3 (I)(*) D3 (I)(*) MDAT | IRQ10(I) | +// +//(1) Alternate output of DAT (for male-to-male extension cables which cross Tx,Rx lines) + +//(*) Needs a specific cable harness for use MiSTer SNAC adapter with the Pocket: +// SNAC PCENGINE POCKET +// ADAPTER FUNCTION SNAC +// D- -> D0 -> RX+ IN4 +// D+ -> D1 -> TX- IO6 (IN) +// RX- -> D2 -> RX- IO3 (IN) +// RX+ -> CLR -> D- OUT1 +// GND_D -> D3 -> TX+ IN7 +// TX- -> SEL -> D+ OUT2 +`default_nettype none +`timescale 1ns / 1ps + +module openFPGA_Pocket_Analogizer_SNAC #(parameter MASTER_CLK_FREQ=50_000_000) +( + input wire i_clk, //Core Master Freq. + input wire i_rst, //Core general reset + input wire conf_AB, //0 conf. A(default), 1 conf. B (see graph above) + input wire [4:0] game_cont_type, //0-15 Conf. A, 16-31 Conf. B + //input wire [2:0] game_cont_sample_rate, //0 compatibility mode (slowest), 1 normal mode, 2 fast mode, 3 superfast mode + //PSX rumble interface joy1, joy2 + input [1:0] i_VIB_SW1, // Vibration SW VIB_SW[0] Small Moter OFF 0:ON 1: + //VIB_SW[1] Bic Moter OFF 0:ON 1(Dualshook Only) + input [7:0] i_VIB_DAT1, // Vibration(Bic Moter)Data 8'H00-8'HFF (Dualshook Only) + input [1:0] i_VIB_SW2, + input [7:0] i_VIB_DAT2, + output reg [15:0] p1_btn_state, + output reg [31:0] p1_joy_state, + output reg [15:0] p2_btn_state, + output reg [31:0] p2_joy_state, + output reg [15:0] p3_btn_state, + output reg [15:0] p4_btn_state, + output reg busy, + //SNAC Pocket cartridge port interface (see graph above) + output reg [7:4] CART_BK0_OUT, + input wire [7:4] CART_BK0_IN, + output reg CART_BK0_DIR, + output reg [7:6] CART_BK1_OUT_P76, + output reg CART_PIN30_OUT, + input wire CART_PIN30_IN, + output reg CART_PIN30_DIR, + output reg CART_PIN31_OUT, + input wire CART_PIN31_IN, + output reg CART_PIN31_DIR, + //debug + output wire [3:0] DBG_TX, + output wire o_stb, + + //PS/2 interface + output wire o_ps2_code_new, + output wire [7:0] o_ps2_code + +); + // + logic SNAC_OUT1 ; //cart_tran_bank1[6] D- + logic SNAC_OUT2 ; //cart_tran_bank1[7] D+ + logic SNAC_IO3_A ;//Conf.A: cart_tran_bank0[4] (in), Conf.B: pin30(out) RX- + logic SNAC_IO3_B ;//Conf.B: cart_tran_bank0[4] (in), Conf.B: pin30(out) RX- + logic SNAC_IN4 ; //cart_tran_bank0[7] RX+ + logic SNAC_IO5_A ;//Conf.A: pin30(out), Conf.B: cart_tran_bank1[6] GND_D + logic SNAC_IO5_B ;//Conf.A: pin30(out), Conf.B: cart_tran_bank1[6] GND_D + logic SNAC_IO6_A ;//Conf.A: pin31(in), Conf.B: pin31(out) TX- + logic SNAC_IO6_B ;//Conf.A: pin31(in), Conf.B: pin31(out) TX- + logic SNAC_IN7 ; //cart_tran_bank0[5] TX+ + + //calculate step sizes for fract clock enables + // localparam pce_compat_polling_freq = 20_000; // 20_000 / 5 = 4K samples/sec PCE + localparam pce_normal_polling_freq = 40_000; // 40_000 / 5 = 8K samples/sec PCE + localparam pce_fast_polling_freq = 80_000; // 80_000 / 5 = 16K samples/sec PCE + // localparam pce_very_fast_polling_freq = 100_000; // 100_000 / 5 = 20K samples/sec PCE + + // localparam Compat_60Hz_polling_freq = 1_080; // + // localparam Compat_120Hz_polling_freq = 2_160; // + localparam snes_compat_polling_freq = 50_000; // + // localparam serlatch_compat_polling_freq = 100_000; // 100_000 / 25 = 4K samples/sec DB15 100_000 / 18 = 5.55K samples/sec NES/SNES + localparam serlatch_normal_polling_freq = 200_000; // 200_000 / 25 = 8K samples/sec DB15 200_000 / 18 = 11.11K samples/sec NES/SNES + localparam serlatch_fast_polling_freq = 400_000; // 400_000 / 25 = 16K samples/sec DB15 400_000 / 18 = 22.22K samples/sec NES/SNES + // localparam serlatch_very_fast_polling_freq = 1_000_000; //1_000_000 / 25 = 32K samples/sec DB15 1_000_000 / 18 = 55.55K samples/sec NES/SNES + + localparam psx_normal_polling_freq = 125_000; + localparam psx_fast_polling_freq = 250_000; + localparam psx_ultra_fast_polling_freq = 500_000; + localparam psx_multitap_polling_freq = 1_000_000; + + // localparam uart_dbg_freq = 500_000 * 16; //115_200 * 16; + localparam uart_dbg_freq = 1_000_000; //115_200 * 16; + localparam [64:0] uart_dbg_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * uart_dbg_freq * 2) / 1000; + localparam [32:0] uart_dbg_pstep = uart_dbg_pstep_[32:0]; + + + //the FSM is clocked 2x the polling freq. + localparam [32:0] MAX_INT = 33'h0ffffffff; + // localparam [64:0] pce_compat_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * pce_compat_polling_freq * 2) / 1000; + // localparam [32:0] pce_compat_pstep = pce_compat_pstep_[32:0]; + localparam [64:0] pce_normal_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * pce_normal_polling_freq * 2) / 1000; + localparam [32:0] pce_normal_pstep = pce_normal_pstep_[32:0]; + localparam [64:0] pce_fast_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * pce_fast_polling_freq * 2) / 1000; + localparam [32:0] pce_fast_pstep = pce_fast_pstep_[32:0]; + + localparam [64:0] psx_fast_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * psx_fast_polling_freq * 2) / 1000; + localparam [32:0] psx_fast_pstep = psx_fast_pstep_[32:0]; + localparam [64:0] psx_normal_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * psx_normal_polling_freq * 2) / 1000; + localparam [32:0] psx_normal_pstep = psx_normal_pstep_[32:0]; + localparam [64:0] psx_ultra_fast_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * psx_ultra_fast_polling_freq * 2) / 1000; + localparam [32:0] psx_ultra_fast_pstep = psx_ultra_fast_pstep_[32:0]; + localparam [64:0] psx_multitap_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * psx_multitap_polling_freq * 2) / 1000; + localparam [32:0] psx_multitap_pstep = psx_multitap_pstep_[32:0]; + // localparam [64:0] pce_very_fast_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) *pce_very_fast_polling_freq * 2) / 1000; + // localparam [32:0] pce_very_fast_pstep = pce_very_fast_pstep_[32:0]; + + // localparam [64:0] serlatch_compat_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * serlatch_compat_polling_freq * 2) / 1000; + // localparam [32:0] serlatch_compat_pstep = serlatch_compat_pstep_[32:0]; + localparam [64:0] serlatch_normal_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * serlatch_normal_polling_freq * 2) / 1000; + localparam [32:0] serlatch_normal_pstep = serlatch_normal_pstep_[32:0]; + localparam [64:0] serlatch_fast_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * serlatch_fast_polling_freq * 2) / 1000; + localparam [32:0] serlatch_fast_pstep = serlatch_fast_pstep_[32:0]; + // localparam [64:0] serlatch_very_fast_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * serlatch_very_fast_polling_freq * 2) / 1000; + // localparam [32:0] serlatch_very_fast_pstep = serlatch_very_fast_pstep_[32:0]; + + localparam [64:0] snes_compat_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * snes_compat_polling_freq * 2) / 1000; + localparam [32:0] snes_compat_pstep = snes_compat_pstep_[32:0]; + + // localparam [64:0] Compat_60Hz_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * Compat_60Hz_polling_freq * 2) / 1000; + // localparam [32:0] Compat_60Hz_pstep = Compat_60Hz_pstep_[32:0]; + // localparam [64:0] Compat_120Hz_pstep_ = ((MAX_INT / (MASTER_CLK_FREQ / 1000)) * Compat_120Hz_polling_freq * 2) / 1000; + // localparam [32:0] Compat_120Hz_pstep = Compat_120Hz_pstep_[32:0]; + + //Supported game controller types + localparam GC_DISABLED = 5'h0; + localparam GC_DB15 = 5'h1; + localparam GC_NES = 5'h2; + localparam GC_SNES = 5'h3; + localparam GC_PCE_2BTN = 5'h4; + localparam GC_PCE_6BTN = 5'h5; + localparam GC_PCE_MULTITAP = 5'h6; + localparam GC_DB15_FAST = 5'h9; + localparam GC_SNES_SWAP = 5'hB; + localparam GC_PS2_NES = 5'hC; //12 PS/2 K&M + NES 1P + localparam GC_PS2_SNES = 5'hD; //13 PS/2 K&M + SNES 1P + localparam GC_PS2_DB15 = 5'hE; //14 PS/2 K&M + DB15 2P + localparam GC_PS2_NONE = 5'hF; //15 PS/2 K&M + sin mando SNAC + localparam GC_PSX = 5'h10; //16 PSX 125KHz + localparam GC_PSX_FAST = 5'h11; //17 PSX 250KHz + localparam GC_PSX_ANALOG = 5'h12; //16 PSX 125KHz + localparam GC_PSX_ANALOG_FAST = 5'h13; //17 PSX 250KHz + + //Configuration: + localparam CONF_A = 1'b0; + localparam CONF_B = 1'b1; + + reg conf_AB_r; + reg [4:0] game_cont_type_r; + // reg [2:0] game_cont_sample_rate_r; + reg [32:0] strobe_step_size; + reg reset_on_change; + + always @(posedge i_clk) begin + //register SNAC settings + conf_AB_r <= conf_AB; + game_cont_type_r <= game_cont_type; + //game_cont_sample_rate_r <= game_cont_sample_rate; + + //detect change of SNAC settings and reset clock divider and set new settings + reset_on_change <= 1'b0; + //if(i_rst || (game_cont_type_r != game_cont_type) || (game_cont_sample_rate_r != game_cont_sample_rate)) begin + if(i_rst || (game_cont_type_r != game_cont_type)) begin + reset_on_change <= 1'b1; + end + end + + reg serlat_ena; + reg pce_ena; + reg psx_ena; + + //check specific case for PS/2 SNAC options + wire ps2_group = (game_cont_type == GC_PS2_NES) || (game_cont_type == GC_PS2_SNES) || + (game_cont_type == GC_PS2_DB15) || (game_cont_type == GC_PS2_NONE); + always @(posedge i_clk) begin + case (game_cont_type) + GC_PSX, GC_PSX_ANALOG: begin + psx_ena <= 1'b1; + strobe_step_size <= psx_normal_pstep; + end + GC_PSX_FAST, GC_PSX_ANALOG_FAST: begin + psx_ena <= 1'b1; + strobe_step_size <= psx_fast_pstep; + end + GC_DB15: begin + serlat_ena <= 1'b1; + strobe_step_size <= serlatch_normal_pstep; + // case (game_cont_sample_rate) + // 0: begin strobe_step_size <= serlatch_compat_pstep; end + // 1: begin strobe_step_size <= serlatch_normal_pstep; end + // 2: begin strobe_step_size <= serlatch_fast_pstep; end + // // 3: begin strobe_step_size <= serlatch_very_fast_pstep; end + // // 4: begin strobe_step_size <= snes_compat_pstep; end + // // 5: begin strobe_step_size <= Compat_60Hz_pstep; end + // // 6: begin strobe_step_size <= Compat_120Hz_pstep; end + // default: begin strobe_step_size <= serlatch_compat_pstep ; end + // endcase + end + GC_DB15_FAST: begin + serlat_ena <= 1'b1; + strobe_step_size <= serlatch_fast_pstep; + end + GC_NES, GC_SNES, GC_SNES_SWAP: begin + serlat_ena <= 1'b1; + strobe_step_size <= snes_compat_pstep; + // case (game_cont_sample_rate) + // 0: begin strobe_step_size <= serlatch_compat_pstep ; end + // 1: begin strobe_step_size <= serlatch_normal_pstep; end + // 2: begin strobe_step_size <= serlatch_fast_pstep; end + // // 3: begin strobe_step_size <= serlatch_very_fast_pstep; end + // // 4: begin strobe_step_size <= snes_compat_pstep; end + // // 5: begin strobe_step_size <= Compat_60Hz_pstep; end + // // 6: begin strobe_step_size <= Compat_120Hz_pstep; end + // default: begin strobe_step_size <= serlatch_compat_pstep ; end + // endcase + end + GC_PCE_2BTN, GC_PCE_6BTN: begin + pce_ena <= 1'b1; + strobe_step_size <= pce_normal_pstep; + // case (game_cont_sample_rate) + // 0: begin strobe_step_size <= pce_compat_pstep; end + // 1: begin strobe_step_size <= pce_normal_pstep; end + // 2: begin strobe_step_size <= pce_fast_pstep; end + // 3: begin strobe_step_size <= pce_very_fast_pstep; end + // default: begin strobe_step_size <= pce_compat_pstep; end + // endcase + end + GC_PCE_MULTITAP: begin + pce_ena <= 1'b1; + strobe_step_size <= pce_fast_pstep; + end + + GC_PS2_NES, GC_PS2_SNES: begin //0xC, 0xD : 1 jugador NES/SNES + serlat_ena <= 1'b1; + strobe_step_size <= snes_compat_pstep; + end + GC_PS2_DB15: begin //0xE : 2 jugadores DB15 + serlat_ena <= 1'b1; + strobe_step_size <= serlatch_normal_pstep; + end + GC_PS2_NONE: begin //0xF : solo teclado+raton, sin mando SNAC + serlat_ena <= 1'b0; + pce_ena <= 1'b0; + psx_ena <= 1'b0; + strobe_step_size <= 33'h0; + end + + default: begin//disabled + serlat_ena <= 1'b0; + pce_ena <= 1'b0; + psx_ena <= 1'b0; + strobe_step_size <= 33'h0; + end + endcase + end + + always @(posedge i_clk) begin + case (conf_AB) + CONF_A: begin + CART_BK0_DIR <= 1'b0; //INPUT + {SNAC_IN4,SNAC_IN7,SNAC_IO3_A} <= {CART_BK0_IN[7],CART_BK0_IN[5],CART_BK0_IN[4]}; //OUTPUT + CART_BK1_OUT_P76 <= {SNAC_OUT2,SNAC_OUT1}; //OUTPUT + CART_PIN30_DIR <= ps2_group ? 1'b0 : 1'b1; //OUTPUT + CART_PIN30_OUT <= SNAC_IO5_A; + CART_PIN31_DIR <= 1'b0; //INPUT + SNAC_IO6_A <= CART_PIN31_IN; + end + CONF_B: begin + CART_BK0_DIR <= 1'b0; //INPUT + {SNAC_IN4,SNAC_IO5_B,SNAC_IN7} <= {CART_BK0_IN[7],CART_BK0_IN[6],CART_BK0_IN[5]}; //OUTPUT + CART_BK1_OUT_P76 <= {SNAC_OUT2,SNAC_OUT1}; //OUTPUT + CART_PIN30_DIR <= 1'b1; //OUTPUT + CART_PIN30_OUT <= SNAC_IO3_B; + CART_PIN31_DIR <= 1'b1; //OUTPUT + CART_PIN31_OUT <= SNAC_IO6_B; + end + endcase + end + + wire stb_clk ; + clock_divider_fract ckdiv( + .i_clk (i_clk), + .i_rst(reset_on_change), //reset on polling freq change + .i_step(strobe_step_size[31:0]), + .o_stb (stb_clk) + ); + + // wire dbg_clk_w; + // reg dbg_clk /* synthesis noprune */; + // clock_divider_fract dbgckdiv( + // .i_clk (i_clk), + // .i_rst(reset_on_change), //reset on polling freq change + // .i_step(uart_dbg_pstep[31:0]), + // .o_stb (dbg_clk_w) + // ); + + // always @(posedge i_clk) dbg_clk <= dbg_clk_w; + + assign o_stb = stb_clk; + + //PSX game controller for 1/2 players + wire [15:0] psx_key1, psx_key2; + wire [31:0] psx_joy1, psx_joy2; + wire PSX_SNAC_OUT1 ; + wire PSX_SNAC_OUT2 ; + analogizer_psx #(.MASTER_CLK_FREQ(MASTER_CLK_FREQ)) psx ( + .i_clk(i_clk), + .i_rst(reset_on_change), + .i_ena(psx_ena), + .i_stb(stb_clk), + .key1(psx_key1), + .joy1(psx_joy1), + .key2(psx_key2), + .joy2(psx_joy2), + //PSX RUMBLE INTERFACE + .i_VIB_SW1(i_VIB_SW1), .i_VIB_DAT1(i_VIB_DAT1), .i_VIB_SW2(i_VIB_SW2), .i_VIB_DAT2(i_VIB_DAT2), + //PSX EXTERNAL INTERFACE + .PSX_CLK(SNAC_IO3_B), + .PSX_DAT(SNAC_IN4), + .PSX_CMD(SNAC_IO6_B), + .PSX_ATT1(PSX_SNAC_OUT1), + .PSX_ATT2(PSX_SNAC_OUT2), + .PSX_ACK(SNAC_IO5_B), + .DBG_TX(DBG_TX) + ); + //assign PSX_SNAC_OUT2 = 1'b1; + + //DB15/NES/SNES game controller + wire [15:0] sl_p1 ; + wire [15:0] sl_p2 ; + wire SERLAT_SNAC_OUT1 ; + wire SERLAT_SNAC_OUT2 ; + reg [1:0] i_D3_r; + reg [1:0] i_D4_r; + //wire SERLAT_SNAC_IO5_A /* synthesis keep */; + + //shift in D3 and D4 from SNAC_IN4 and SNAC_IO6_A for NES Zapper controller + always @(posedge i_clk) begin + i_D3_r <= {i_D3_r[0],SNAC_IO6_A}; + i_D4_r <= {i_D4_r[0],SNAC_IN4}; + end + + // Choose a serial latch type based on the game controller type. For PS/2 NES/SNES/DB15, use a specific type; otherwise, use the lower 4 bits of the game controller type. + wire [3:0] serlat_type = + (game_cont_type == GC_PS2_NES) ? 4'h2 : //NES + (game_cont_type == GC_PS2_SNES) ? 4'h3 : //SNES + (game_cont_type == GC_PS2_DB15) ? 4'h1 : //DB15 + game_cont_type[3:0]; //default if not PS/2 NES/SNES/DB15, use the lower 4 bits of the game controller type + serlatch_game_controller #(.MASTER_CLK_FREQ(MASTER_CLK_FREQ)) slgc + ( + .i_clk(i_clk), + .i_rst(reset_on_change), + .game_controller_type(serlat_type), + .i_stb(stb_clk), + .p1_btn_state(sl_p1), + .p2_btn_state(sl_p2), + .busy(), + //SNAC Game controller interface + .o_clk(SERLAT_SNAC_OUT1), //shared for 2 controllers + .o_clk2(SNAC_IO5_A), + .o_lat(SERLAT_SNAC_OUT2), //shared for 2 controllers + .i_dat1(((serlat_type == 4'h1 || serlat_type == 4'h9) && !ps2_group) ? SNAC_IO3_A & SNAC_IO6_A : SNAC_IO3_A ), //data from controller 1 + .i_dat2(ps2_group ? 1'b1 : SNAC_IN7) //data from controller 2 + ); + + //PCENGINE game controller + wire [15:0] pce_p1 ; + wire PCE_SNAC_OUT1 ; + wire PCE_SNAC_OUT2 ; + + pcengine_game_controller #(.MASTER_CLK_FREQ(MASTER_CLK_FREQ), .PULSE_CLR_LINE(1'b1)) pcegc1 + ( + .i_clk(i_clk), + .i_rst(reset_on_change), + .game_controller_type(game_cont_type[3:0]), //0X4 2btn, 0X5 6btn + .i_stb(stb_clk), + .player_btn_state(pce_p1), + .busy(), + //SNAC Game controller interface + .o_clr(PCE_SNAC_OUT1), //shared for 2 controllers + .o_sel(PCE_SNAC_OUT2), //shared for 2 controllers + .i_dat({SNAC_IN7,SNAC_IO3_A,SNAC_IO6_A,SNAC_IN4}) //data from controller + ); + +wire [15:0] pce_multitap_p1, pce_multitap_p2, pce_multitap_p3, pce_multitap_p4; +wire PCE_MULTITAP_SNAC_OUT1, PCE_MULTITAP_SNAC_OUT2; + +pcengine_game_controller_multitap #(.MASTER_CLK_FREQ(MASTER_CLK_FREQ)) pcegmutitap +( + .i_clk(i_clk), + .i_rst(reset_on_change), + .game_controller_type(game_cont_type[3:0]), //0x6 multitap + .i_stb(stb_clk), + .player1_btn_state(pce_multitap_p1), + .player2_btn_state(pce_multitap_p2), + .player3_btn_state(pce_multitap_p3), + .player4_btn_state(pce_multitap_p4), + .player5_btn_state(), + .busy(), + //SNAC Game controller interface + .o_clr(PCE_MULTITAP_SNAC_OUT1), //shared for 2 controllers + .o_sel(PCE_MULTITAP_SNAC_OUT2), //shared for 2 controllers + .i_dat({SNAC_IN7,SNAC_IO3_A,SNAC_IO6_A,SNAC_IN4}) //data from controller +); + + always @(*) begin + p1_joy_state = 32'h80808080; //analog stick neutral position value + p2_joy_state = 32'h80808080; //analog stick neutral position value + + case(game_cont_type) + // GC_DISABLED: begin + // SNAC_OUT1 = 1'b0; + // SNAC_OUT2 = 1'b0; + // p1_btn_state = 16'h0; + // p2_btn_state = 16'h0; + // p3_btn_state = 16'h0; + // p4_btn_state = 16'h0; + // end + GC_DB15, GC_DB15_FAST, GC_SNES, GC_SNES_SWAP: begin + SNAC_OUT1 = SERLAT_SNAC_OUT1; + SNAC_OUT2 = SERLAT_SNAC_OUT2; + p1_btn_state = sl_p1; + p2_btn_state = sl_p2; + p3_btn_state = 16'h0; + p4_btn_state = 16'h0; + + end + //added special case for NES Zapper + GC_NES: begin + SNAC_OUT1 = SERLAT_SNAC_OUT1; + SNAC_OUT2 = SERLAT_SNAC_OUT2; + p1_btn_state = sl_p1; //{sl_p1[15:8], ~i_D4_r[1], ~i_D3_r[1], sl_p1[5:0]}; //insert D4 and D3 at 7 and 6 bit positions (X,Y buttons) + p2_btn_state = {sl_p2[15:8], ~i_D4_r[1], ~i_D3_r[1], sl_p2[5:0]}; + p3_btn_state = 16'h0; + p4_btn_state = 16'h0; + + end + GC_PCE_2BTN, GC_PCE_6BTN: begin + SNAC_OUT1 = PCE_SNAC_OUT1; + SNAC_OUT2 = PCE_SNAC_OUT2; + p1_btn_state = pce_p1; + p2_btn_state = 16'h0; + p3_btn_state = 16'h0; + p4_btn_state = 16'h0; + end + GC_PCE_MULTITAP: begin + SNAC_OUT1 = PCE_MULTITAP_SNAC_OUT1; + SNAC_OUT2 = PCE_MULTITAP_SNAC_OUT2; + p1_btn_state = pce_multitap_p1; + p2_btn_state = pce_multitap_p2; + p3_btn_state = pce_multitap_p3; + p4_btn_state = pce_multitap_p4; + end + GC_PSX, GC_PSX_ANALOG, GC_PSX_FAST, GC_PSX_ANALOG_FAST: begin + SNAC_OUT1 = PSX_SNAC_OUT1; + SNAC_OUT2 = PSX_SNAC_OUT2; + p1_btn_state = psx_key1; + p1_joy_state = psx_joy1; + p2_btn_state = psx_key2; + p2_joy_state = psx_joy2; + p3_btn_state = 16'h0; + p4_btn_state = 16'h0; + end + GC_PS2_SNES: begin //0xD : SNES 1P + SNAC_OUT1 = SERLAT_SNAC_OUT1; + SNAC_OUT2 = SERLAT_SNAC_OUT2; + p1_btn_state = sl_p1; + p2_btn_state = 16'h0; //1 jugador + p3_btn_state = 16'h0; + p4_btn_state = 16'h0; + end + GC_PS2_DB15: begin //0xE : DB15 2P + SNAC_OUT1 = SERLAT_SNAC_OUT1; + SNAC_OUT2 = SERLAT_SNAC_OUT2; + p1_btn_state = sl_p1; + p2_btn_state = sl_p2; + p3_btn_state = 16'h0; + p4_btn_state = 16'h0; + end + GC_PS2_NES: begin //0xC : NES 1P + SNAC_OUT1 = SERLAT_SNAC_OUT1; + SNAC_OUT2 = SERLAT_SNAC_OUT2; + p1_btn_state = sl_p1; + p2_btn_state = 16'h0; + p3_btn_state = 16'h0; + p4_btn_state = 16'h0; + end + //GC_PS2_NONE (0xF) default case + default: begin + SNAC_OUT1 = 1'b0; + SNAC_OUT2 = 1'b0; + p1_btn_state = 16'h0; + p2_btn_state = 16'h0; + p3_btn_state = 16'h0; + p4_btn_state = 16'h0; + end + endcase + end + + //========================================================================= + // PS/2 KeyboardSNAC + // Generic ps2_keyboard with debounce: returns scancode + // KCLK = CART_PIN30_IN (pin30) + // KDAT = CART_BK0_IN[7] (bank0[7]) + //========================================================================= + // debounce ~11-12 us: 2^size/CLK ~ 12us + localparam int PS2_DEBOUNCE_SIZE = $clog2(MASTER_CLK_FREQ / 85_000); + + ps2_keyboard #( + .clk_freq (MASTER_CLK_FREQ), + .debounce_counter_size (PS2_DEBOUNCE_SIZE) + ) ps2_kbd_snac ( + .clk (i_clk), + .ps2_clk (CART_PIN30_IN), // KCLK + .ps2_data (CART_BK0_IN[7]), // KDAT + .ps2_code_new (o_ps2_code_new), + .ps2_code (o_ps2_code) + ); +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/pcengine_game_controller_multitap.v b/target/pocket/analogizer/pcengine_game_controller_multitap.v new file mode 100644 index 0000000..ed02aec --- /dev/null +++ b/target/pocket/analogizer/pcengine_game_controller_multitap.v @@ -0,0 +1,233 @@ +//pcengine_game_controller_multitap.v +//*********************************************************************** +//* Analogizer PCEngine SNAC openFPGA interface for the Analogue Pocket * +//*********************************************************************** +// By @RndMnkIII. +// Date: 01/2024 +// Release: 1.0 + +// Aquí he documentado el funcionamiento de los diferentes mandos de juegos a los que he ido dando soporte, basado en las capturas de datos +// realizadas con analizador lógico + generador de patrones: +// +// ************ +// * PCEngine * Tested up 100KHz clr to clr (500KHz step) +// ************ +// <--------- 2BTN --------> +// <----------------- 6BTN ----------------> +// STB | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +// ......... +// CLR : :_______________________________ +// _______________ _______ +// SEL / \_______/ \_______ +// ________ _______ _______ _______ _______ +// DATA 1 \ LDRU X RS21 X 0 X 6543 +// ^ ^ ^ ^ +// SAMPLE | | | | +// 1 2 3 4 + +// NEED TO CHECK THIS -+ +// | +// V +// +// <--------- 2BTN -------> +// <----------------- 6BTN ------------------------> +// STB | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 | +// | SCAN1 | SCAN2 | +// ..... ..... +// CLR : :___________________: :___________________ +// ___________ ___________ +// SEL / \___________/ \___________ +// _________ _________ _________ _________ +// DATA ____/ LDRU X RS21 \___/ 0 X 6543 +// ^ ^ ^ ^ ^ ^ +// SAMPLE | | | | +// 1 2 3 4 +// TEST DATA 1 +// TEST DATA 2 +// POCKET INPUTS +// 1 P1 up DO +// 0 P1 down D2 +// 1 P1 left D3 +// 0 P1 right D1 +// 0 P1 y D1 +// 1 P1 x D0 +// 0 P1 b D1 +// 1 P1 a D0 +// 1 P1 l1 D2 +// 0 P1 r1 D3 +// 0 P1 l2 -------------------------- +// 0 P1 r2 -------------------------- +// 0 P1 l3 -------------------------- +// 0 P1 r3 -------------------------- +// 0 P1 select D2 +// 1 P1 start D3 +// X +//P1 1010 0101 1000 0001 +// A 5 8 1 +//gtkwave +//p1 1010 0101 1000 0001 +// A581 +// MULTITAP (x5 Controllers): +// CLR SEL Active Port Port 1 CLR Port 1 SEL Port 2 CLR Port 2 SEL Port 3 CLR Port 3 SEL Port 4 CLR Port 4 SEL Port 5 CLR Port 5 SEL +// 1 L H None H H H H H H H H H H +// 2 H H None H H H H H H H H H H +// 3 L H 1 L H H H H H H H H H +// 4 L L 1 L L H H H H H H H H +// 5 L H 2 H H L H H H H H H H +// 6 L L 2 H H L L H H H H H H +// 7 L H 3 H H H H L H H H H H +// 8 L L 3 H H H H L L H H H H +// 9 L H 4 H H H H H H L H H H +// 10 L L 4 H H H H H H L L H H +// 11 L H 5 H H H H H H H H L H +// 12 L L 5 H H H H H H H H L L +`default_nettype none + +module pcengine_game_controller_multitap #(parameter MASTER_CLK_FREQ=50_000_000) +( + input wire i_clk, + input wire i_rst, + input wire [3:0] game_controller_type, //0x4 2btn, 0x5 6btn, 0x6 multitap + input wire i_stb, + output reg [15:0] player1_btn_state, + output reg [15:0] player2_btn_state, + output reg [15:0] player3_btn_state, + output reg [15:0] player4_btn_state, + output reg [15:0] player5_btn_state, + output reg busy, + + //SNAC Game controller interface + output wire o_clr, + output wire o_sel, + input wire [3:0] i_dat //data from controller +); + //FSM states + parameter IDLE = 3'b001; + parameter CLR = 3'b010; + parameter PRE_CLR = 3'b011; + parameter DATA = 3'b100; + + //store module settings + reg [3:0] game_controller_type_r; + + reg [6:0] state ; + + reg [4:0] counter; + reg [4:0] scan_number; + reg [4:0] counter_top_value; + reg clr_internal; + reg sel_internal; + reg [11:0] pb1_r, pb2_r, pb3_r, pb4_r, pb5_r; + + wire sample_data; + + //always sample data at falling edge of o_clk starting and second clock pulse in latch phase. + assign sample_data = ~counter[0] && i_stb && (counter > 0) && (counter <= counter_top_value); + + always @(posedge i_clk) begin + game_controller_type_r <= game_controller_type; + + //detect any change on gamepad configuration and restart FSM at IDLE state. + if(i_rst || (game_controller_type != game_controller_type_r)) begin + state <= IDLE; + pb1_r <= 12'hfff; + pb2_r <= 12'hfff; + pb3_r <= 12'hfff; + pb4_r <= 12'hfff; + pb5_r <= 12'hfff; + end + else begin + if(i_stb) begin + case(state) + IDLE: + begin + //fetch data from last read + + //button order from first to last + //0 1 2 3 4 5 6 7 8 9 10 11 + //UP RIGHT DOWN LEFT I II SELECT RUN III IV V VI + //follow Pocket game controls order: D C B A E F + // up down left right btn_y btn_x btn_b btn_a btn_l1 btn_r1 btn_l2 btn_r2 btn_l3 btn_r3 select start + //player_btn_state <= ~{pb_r[0], pb_r[2], pb_r[3], pb_r[1], pb_r[9], pb_r[8], pb_r[5], pb_r[4], pb_r[10], pb_r[11], 1'b1, 1'b1, 1'b1, 1'b1,pb_r[6],pb_r[7]}; + + // START SELECT R3 L3 R2 L2 R1 L1 Y X B A RIGH LEFT DOWN UP + player1_btn_state <= ~{pb1_r[7], pb1_r[6], 8'b11111111, pb1_r[5], pb1_r[4],pb1_r[1], pb1_r[3], pb1_r[2], pb1_r[0]}; + player2_btn_state <= ~{pb2_r[7], pb2_r[6], 8'b11111111, pb2_r[5], pb2_r[4],pb2_r[1], pb2_r[3], pb2_r[2], pb2_r[0]}; + player3_btn_state <= ~{pb3_r[7], pb3_r[6], 8'b11111111, pb3_r[5], pb3_r[4],pb3_r[1], pb3_r[3], pb3_r[2], pb3_r[0]}; + player4_btn_state <= ~{pb4_r[7], pb4_r[6], 8'b11111111, pb4_r[5], pb4_r[4],pb4_r[1], pb4_r[3], pb4_r[2], pb4_r[0]}; + player5_btn_state <= ~{pb5_r[7], pb5_r[6], 8'b11111111, pb5_r[5], pb5_r[4],pb5_r[1], pb5_r[3], pb5_r[2], pb5_r[0]}; + + counter <= 0; + scan_number <= 0; + counter_top_value <= 5'd19; + + sel_internal <= 1'b1; + clr_internal <= 1'b0; + busy <= 1'b1; + pb1_r <= 12'hfff; + pb2_r <= 12'hfff; + pb3_r <= 12'hfff; + pb4_r <= 12'hfff; + pb5_r <= 12'hfff; + state <= PRE_CLR; + end + PRE_CLR: begin + sel_internal <= 1'b1; + clr_internal <= 1'b1; + state <= CLR; + end + + CLR: + begin + counter <= counter + 1; + sel_internal <= 1'b1; + clr_internal <= 1'b0; + pb1_r[3:0] <= i_dat; + state <= DATA; + end + DATA: + begin + counter <= counter + 1; //should be start clocking at 3 + //following data samples are get in DATA phase. + if(counter[0]) begin + sel_internal <= ~sel_internal; + scan_number <= scan_number + 1; + end + + if(sample_data) begin//read button state + case(scan_number) + //0: pb1_r[3:0] <= i_dat; + 1: pb1_r[7:4] <= i_dat; + 2: pb2_r[3:0] <= i_dat; + 3: pb2_r[7:4] <= i_dat; + 4: pb3_r[3:0] <= i_dat; + 5: pb3_r[7:4] <= i_dat; + 6: pb4_r[3:0] <= i_dat; + 7: pb4_r[7:4] <= i_dat; + 8: pb5_r[3:0] <= i_dat; + 9: pb5_r[7:4] <= i_dat; + default: + begin + pb1_r <= pb1_r; + pb2_r <= pb2_r; + pb3_r <= pb3_r; + pb4_r <= pb4_r; + pb5_r <= pb5_r; + end + endcase + end + + //the gamepads buton state are fetched at the end of DATA phase 1101 0101 + if(scan_number == 9) begin + state <= IDLE; + busy <= 1'b0; + end + end + endcase + end + end + end + + assign o_clr = (game_controller_type_r == 4'h6) ? clr_internal : 1'b0; + assign o_sel = (game_controller_type_r == 4'h6) ? sel_internal : 1'b0; +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/pcengine_gc.v b/target/pocket/analogizer/pcengine_gc.v new file mode 100644 index 0000000..f66be5b --- /dev/null +++ b/target/pocket/analogizer/pcengine_gc.v @@ -0,0 +1,195 @@ +//pcengine_gamecontroller.v +//*********************************************************************** +//* Analogizer PCEngine SNAC openFPGA interface for the Analogue Pocket * +//*********************************************************************** +// By @RndMnkIII. +// Date: 01/2024 +// Release: 1.0 + +// Aquí he documentado el funcionamiento de los diferentes mandos de juegos a los que he ido dando soporte, basado en las capturas de datos +// realizadas con analizador lógico + generador de patrones: +// +// ************ +// * PCEngine * Tested up 100KHz clr to clr (500KHz step) +// ************ +// <--------- 2BTN --------> +// <----------------- 6BTN ----------------> +// STB | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | +// ......... +// CLR : :_______________________________ +// _______________ _______ +// SEL / \_______/ \_______ +// ________ _______ _______ _______ _______ +// DATA 1 \ LDRU X RS21 X 0 X 6543 +// ^ ^ ^ ^ +// SAMPLE | | | | +// 1 2 3 4 + +// NEED TO CHECK THIS -+ +// | +// V +// +// <--------- 2BTN -------> +// <----------------- 6BTN ------------------------> +// STB | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 | +// | SCAN1 | SCAN2 | +// ___ ___ +// CLR | |___________________| |___________________ +// ___________ ___________ +// SEL / \___________/ \___________ +// _________ _________ _________ _________ +// DATA ____/ LDRU X RS21 \___/ 0 X 6543 +// ^ ^ ^ ^ ^ ^ +// SAMPLE | | | | +// 1 2 3 4 +`default_nettype none + +module pcengine_game_controller #(parameter MASTER_CLK_FREQ=50_000_000, parameter PULSE_CLR_LINE=1'b0) +( + input wire i_clk, + input wire i_rst, + input wire [3:0] game_controller_type, //0X4 2btn,0X5 6btn + input wire i_stb, + output reg [15:0] player_btn_state, + output reg busy, + + //SNAC Game controller interface + output wire o_clr, + output wire o_sel, + input wire [3:0] i_dat //data from controller +); + + + //FSM states + parameter IDLE = 3'b001; + parameter CLR = 3'b010; + parameter DATA = 3'b100; + + //store module settings + reg [3:0] game_controller_type_r; + + wire pulse_clr = PULSE_CLR_LINE; + + reg [2:0] state ; + + reg [3:0] counter; + reg [3:0] scan_number; + reg [3:0] counter_top_value; + reg clr_internal; + reg sel_internal; + reg [11:0] pb_r; + + + wire latch_level,disable_clock_on_latch; + wire sample_data; + + reg btn6; + + //always sample data at falling edge of o_clk starting and second clock pulse in latch phase. + assign sample_data = ~counter[0] && i_stb && (counter > 0) && (counter <= counter_top_value); + + always @(posedge i_clk) begin + game_controller_type_r <= game_controller_type; + + //detect any change on gamepad configuration and restart FSM at IDLE state. + if(i_rst || (game_controller_type != game_controller_type_r)) begin + state <= IDLE; + pb_r <= 12'hfff; + end + else begin + if(i_stb) begin + case(state) + IDLE: + begin + //fetch data from last read + + //button order from first to last + //0 1 2 3 4 5 6 7 8 9 10 11 + //UP RIGHT DOWN LEFT I II SELECT RUN III IV V VI + //follow Pocket game controls order: D C B A E F + + + if(game_controller_type_r == 4'h5) begin + //6btn mapping + // START SELECT R3 L3 R2 L2 R1 L1 Y X B A RIGH LEFT DOWN UP + // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + player_btn_state <= ~{pb_r[7], pb_r[6], 4'b1111, pb_r[11], pb_r[10], pb_r[9], pb_r[8], pb_r[5], pb_r[4], pb_r[1], pb_r[3], pb_r[2], pb_r[0]}; + end + else if (game_controller_type_r == 4'h4) begin + //2btn mapping RUN+A = X, RUN+B = Y not implemented + // START SELECT R3 L3 R2 L2 R1 L1 Y X B A RIGH LEFT DOWN UP + player_btn_state <= ~{pb_r[7], pb_r[6], 6'b111111, 1'b1, 1'b1, pb_r[5], pb_r[4], pb_r[1], pb_r[3], pb_r[2], pb_r[0]}; + end + else begin + player_btn_state <= 16'h0; + end + counter <= 0; + scan_number <= 0; + + // if (game_controller_type_r == 5'd4) counter_top_value <= 4'd4; + // else if(game_controller_type_r == 5'd5) counter_top_value <= 4'd8; + counter_top_value <= 4'd4; + sel_internal <= 1'b1; + clr_internal <= pulse_clr; + busy <= 1'b1; + //if (~btn6) pb_r <= 12'hfff; + state <= CLR; + end + CLR: + begin + counter <= counter + 1; + if (counter == 1) begin + state <= DATA; + sel_internal <= 1'b1; + clr_internal <= 1'b0; + end + end + DATA: + begin + counter <= counter + 1; //should be start clocking at 3 + //following data samples are get in DATA phase. + if(counter[0]) begin + sel_internal <= ~sel_internal; + scan_number <= scan_number + 1; + end + + if(sample_data) begin//read button state + case(scan_number) + 0: begin + if(i_dat == 4'b0000) begin + btn6 <= 1'b1; + //pb_r[3:0] <= pb_r[3:0]; + end + else begin + btn6 <= 1'b0; + pb_r[3:0] <= i_dat; + end + end + 1: begin + if(btn6) begin + pb_r[11:8] <= i_dat; + end + else begin + pb_r[7:4] <= i_dat; + end + //btn6 <= 1'b0; + end + // 3: pb_r[11:8] <= i_dat; + default: pb_r <= pb_r; + endcase + end + + //the gamepads buton state are fetched at the end of DATA phase + if(counter == counter_top_value) begin + state <= IDLE; + busy <= 1'b0; + end + end + endcase + end + end + end + + assign o_clr = (game_controller_type_r == 4'd0) ? 1'b0 : clr_internal; + assign o_sel = (game_controller_type_r == 4'd0) ? 1'b0 : sel_internal; +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/psPAD_top.v b/target/pocket/analogizer/psPAD_top.v new file mode 100644 index 0000000..5cc74c2 --- /dev/null +++ b/target/pocket/analogizer/psPAD_top.v @@ -0,0 +1,664 @@ +//------------------------------------------------------------------- +// +// PLAYSTATION CONTROLLER(DUALSHOCK TYPE) INTERFACE TOP +// +// Version : 2.00 +// +// Copyright(c) 2003 - 2004 Katsumi Degawa , All rights reserved +// +// Important ! +// +// This program is freeware for non-commercial use. +// An author does no guarantee about this program. +// You can use this under your own risk. +// +// 2003.10.30 It is optimized . by K Degawa +// +//------------------------------------------------------------------- +`timescale 100ps/10ps + +//--------- SIMULATION ---------------------------------------------- +//`define SIMULATION_1 + +`ifdef SIMULATION_1 +`define Timer_siz 18 +`else +`define Timer_siz 12 +`endif +//------------------------------------------------------------------- +`define Dualshock + +module psPAD_top( + +I_CLK250K, // MAIN CLK 250KHz +I_RSTn, // MAIN RESET + +O_psCLK, // psCLK CLK OUT +O_psSEL, // psSEL OUT +O_psTXD, // psTXD OUT +I_psRXD, // psRXD IN +O_RXD_1, // RX DATA 1 (8bit) +O_RXD_2, // RX DATA 2 (8bit) +O_RXD_3, // RX DATA 3 (8bit) +O_RXD_4, // RX DATA 4 (8bit) +O_RXD_5, // RX DATA 5 (8bit) +O_RXD_6, // RX DATA 6 (8bit) +I_CONF_SW, // Dualshook Config ACTIVE-HI +I_MODE_SW, // Dualshook Mode Set DEGITAL PAD 0: ANALOG PAD 1: +I_MODE_EN, // Dualshook Mode Control OFF 0: ON 1: +I_VIB_SW, // Vibration SW VIB_SW[0] Small Moter OFF 0:ON 1: + // VIB_SW[1] Bic Moter OFF 0:ON 1(Dualshook Only) +I_VIB_DAT // Vibration(Bic Moter)Data 8'H00-8'HFF (Dualshook Only) + +); + +input I_CLK250K,I_RSTn; +input I_CONF_SW; +input I_MODE_SW,I_MODE_EN; +input [1:0]I_VIB_SW; +input [7:0]I_VIB_DAT; +input I_psRXD; +output O_psCLK; +output O_psSEL; +output O_psTXD; +output [7:0]O_RXD_1; +output [7:0]O_RXD_2; +output [7:0]O_RXD_3; +output [7:0]O_RXD_4; +output [7:0]O_RXD_5; +output [7:0]O_RXD_6; + +wire W_scan_seq_pls; +wire W_type; +wire [3:0]W_byte_cnt; +wire W_RXWT; +wire W_TXWT; +wire W_TXSET; +wire W_TXEN; +wire [7:0]W_TXD_DAT; +wire [7:0]W_RXD_DAT; +wire W_conf_ent; + +ps_pls_gan pls( + +.I_CLK(I_CLK250K), +.I_RSTn(I_RSTn), +.I_TYPE(W_type), // DEGITAL PAD 0: ANALOG PAD 1: + +.O_SCAN_SEQ_PLS(W_scan_seq_pls), +.O_RXWT(W_RXWT), +.O_TXWT(W_TXWT), +.O_TXSET(W_TXSET), +.O_TXEN(W_TXEN), +.O_psCLK(O_psCLK), +.O_psSEL(O_psSEL), +.O_byte_cnt(W_byte_cnt), + +//.Timer(O_Timer) +.Timer() + +); + +`ifdef Dualshock +txd_commnd cmd( +.I_CLK(W_TXSET), +.I_RSTn(I_RSTn), +.I_BYTE_CNT(W_byte_cnt), +.I_MODE({I_CONF_SW,~I_MODE_EN,I_MODE_SW}), +.I_VIB_SW(I_VIB_SW), +.I_VIB_DAT(I_VIB_DAT), +.I_RXD_DAT(W_RXD_DAT), +.O_TXD_DAT(W_TXD_DAT), +.O_TYPE(W_type), +.O_CONF_ENT(W_conf_ent) + +); + +`else +txd_commnd_EZ cmd( + +.I_CLK(W_TXSET), +.I_RSTn(I_RSTn), +.I_BYTE_CNT(W_byte_cnt), +.I_MODE(), +.I_VIB_SW(I_VIB_SW), +.I_VIB_DAT(), +.I_RXD_DAT(), +.O_TXD_DAT(W_TXD_DAT), +.O_TYPE(W_type), +.O_CONF_ENT(W_conf_ent) + +); + +`endif + +ps_txd txd( + +.I_CLK(I_CLK250K), +.I_RSTn(I_RSTn), +.I_WT(W_TXWT), +.I_EN(W_TXEN), +.I_TXD_DAT(W_TXD_DAT), +.O_psTXD(O_psTXD) + +); + +ps_rxd rxd( + +.I_CLK(O_psCLK), +.I_RSTn(I_RSTn), +.I_WT(W_RXWT), +.I_psRXD(I_psRXD), +.O_RXD_DAT(W_RXD_DAT) + +); + +//---------- RXD DATA DEC ---------------------------------------- +reg [7:0]O_RXD_1; +reg [7:0]O_RXD_2; +reg [7:0]O_RXD_3; +reg [7:0]O_RXD_4; +reg [7:0]O_RXD_5; +reg [7:0]O_RXD_6; + +reg W_rxd_mask; +always@(posedge W_scan_seq_pls) + W_rxd_mask <= ~W_conf_ent; + +always@(negedge W_RXWT) +begin + if(W_rxd_mask)begin + case(W_byte_cnt) + 3: O_RXD_1 <= W_RXD_DAT; + 4: O_RXD_2 <= W_RXD_DAT; + 5: O_RXD_3 <= W_RXD_DAT; + 6: O_RXD_4 <= W_RXD_DAT; + 7: O_RXD_5 <= W_RXD_DAT; + 8: O_RXD_6 <= W_RXD_DAT; + default:; + endcase + end +end + +endmodule + +`ifdef Dualshock +//.I_MODE({I_CONF_SW,~I_MODE_EN,I_MODE_SW}), +module txd_commnd_EZ( + +I_CLK, +I_RSTn, +I_BYTE_CNT, +I_MODE, +I_VIB_SW, +I_VIB_DAT, +I_RXD_DAT, +O_TXD_DAT, +O_TYPE, +O_CONF_ENT + +); + +input I_CLK,I_RSTn; +input [3:0]I_BYTE_CNT; +input [2:0]I_MODE; +input [1:0]I_VIB_SW; +input [7:0]I_VIB_DAT; +input [7:0]I_RXD_DAT; +output [7:0]O_TXD_DAT; +output O_TYPE; +output O_CONF_ENT; + +reg [7:0]O_TXD_DAT; + +assign O_TYPE = 1'b1; +assign O_CONF_ENT = 1'b0; +always@(posedge I_CLK or negedge I_RSTn) +begin + if(! I_RSTn)begin + O_TXD_DAT <= 8'h00; + end + else begin + case(I_BYTE_CNT) + 0:O_TXD_DAT <= 8'h01; + 1:O_TXD_DAT <= 8'h42; + 3:begin + if(I_VIB_SW) O_TXD_DAT <= 8'h40; + else O_TXD_DAT <= 8'h00; + end + 4:begin + if(I_VIB_SW) O_TXD_DAT <= 8'h01; + else O_TXD_DAT <= 8'h00; + end + default: O_TXD_DAT <= 8'h00; + endcase + end +end + +endmodule +`endif + +module txd_commnd( + +I_CLK, +I_RSTn, +I_BYTE_CNT, +I_MODE, +I_VIB_SW, +I_VIB_DAT, +I_RXD_DAT, +O_TXD_DAT, +O_TYPE, +O_CONF_ENT + +); + +input I_CLK,I_RSTn; +input [3:0]I_BYTE_CNT; +input [2:0]I_MODE; +input [1:0]I_VIB_SW; +input [7:0]I_VIB_DAT; +input [7:0]I_RXD_DAT; +output [7:0]O_TXD_DAT; +output O_TYPE; +output O_CONF_ENT; + +wire [1:0]pad_mode = I_MODE[1:0]; +wire ds_sw = I_MODE[2]; + +reg [7:0]O_TXD_DAT; +reg [2:0]conf_state; +reg conf_entry; +reg conf_ent_reg; +reg conf_done; +reg pad_status; +reg pad_id; + +assign O_TYPE = pad_id; +assign O_CONF_ENT = conf_entry; + +always@(posedge I_CLK or negedge I_RSTn) +begin + if(! I_RSTn) pad_id <= 1'b0; + else begin + if(I_BYTE_CNT==2)begin + case(I_RXD_DAT) //------ GET TYPE(Byte_SEQ) + 8'h23: pad_id <= 1'b1; + 8'h41: pad_id <= 1'b0; + 8'h53: pad_id <= 1'b1; + 8'h73: pad_id <= 1'b1; + 8'hE3: pad_id <= 1'b1; + 8'hF3: pad_id <= 1'b1; + default: pad_id <= 1'b0; + endcase + end + end +end + +always@(posedge I_CLK or negedge I_RSTn) +begin + if(! I_RSTn)begin + O_TXD_DAT <= 8'h00; + conf_entry <= 1'b0; + conf_ent_reg <= 1'b0; + conf_done <= 1'b1; + conf_state <= 0; + pad_status <= 0; + end + else begin +//---------- nomal mode -------------------------------------------------------- +//----------------- read_data_and_vibrate_ex 01,42,00,WW,PP(,00,00,00,00) +// --,ID,SS,XX,XX(,XX,XX,XX,XX) + if(~conf_entry)begin + case(I_BYTE_CNT) + 0:O_TXD_DAT <= 8'h01; + 1:O_TXD_DAT <= 8'h42; + 3:begin + if(I_RXD_DAT==8'h00) conf_ent_reg <= 1'b1; + if(pad_status)begin + if(I_VIB_SW[0]) O_TXD_DAT <= 8'h01; + else O_TXD_DAT <= 8'h00; + end + else begin + if(I_VIB_SW[0] | I_VIB_SW[1]) O_TXD_DAT <= 8'h40; + else O_TXD_DAT <= 8'h00; + end + end + 4:begin + if(pad_status)begin + if(I_VIB_SW[1]) O_TXD_DAT <= I_VIB_DAT; + else O_TXD_DAT <= 8'h00; + end + else begin + if(I_VIB_SW[0] | I_VIB_SW[1]) O_TXD_DAT <= 8'h01; + else O_TXD_DAT <= 8'h00; + end + if(pad_id==0)begin + if(conf_state == 0 && ds_sw) + conf_entry <= 1'b1; + if(conf_state == 7 && (pad_status&conf_ent_reg))begin + conf_state <= 0; + conf_entry <= 1'b1; + end + end + end + 8:begin + O_TXD_DAT <= 8'h00; + if(pad_id==1)begin + if(conf_state == 0 && ds_sw) + conf_entry <= 1'b1; + if(conf_state == 7 && (pad_status&conf_ent_reg))begin + conf_state <= 0; + conf_entry <= 1'b1; + end + end + end + default: O_TXD_DAT <= 8'h00; + endcase + end +//---------- confg mode -------------------------------------------------------- + else begin + case(conf_state) + //-------- config_mode_enter (43): 01,43,00,01,00(,00 x 4 or XX x 16) + // --,ID,SS,XX,XX(,XX x 4 or XX x 16) + 0:begin + case(I_BYTE_CNT) + 0:begin + O_TXD_DAT <= 8'h01; + conf_done <= 1'b0; + end + 1:O_TXD_DAT <= 8'h43; + 3:O_TXD_DAT <= 8'h01; + 4:begin + O_TXD_DAT <= 8'h00; + if(pad_id==0)begin + if(pad_status) conf_state <= 3; + else conf_state <= 1; + end + end + 8:begin + O_TXD_DAT <= 8'h00; + if(pad_id==1)begin + if(pad_status) conf_state <= 3; + else conf_state <= 1; + end + end + default:O_TXD_DAT <= 8'h00; + endcase + end + //-------- query_model_and_mode (45): 01,45,00,5A,5A,5A,5A,5A,5A + // FF,F3,5A,TT,02,MM,VV,01,00 + 1:begin + case(I_BYTE_CNT) + 0:O_TXD_DAT <= 8'h01; + 1:O_TXD_DAT <= 8'h45; + 2:begin + O_TXD_DAT <= 8'h00; + conf_done <= (I_RXD_DAT == 8'hF3)? 1'b0:1'b1; + end + 4:begin + O_TXD_DAT <= 8'h00; + if(I_RXD_DAT==8'h01 || I_RXD_DAT==8'h03) pad_status <= 1; + if(pad_id==0 && conf_done==1'b1)begin + conf_state <= 7; + conf_entry <= 1'b0; + end + end + 8:begin + O_TXD_DAT <= 8'h00; + conf_state <= 2; + if(pad_id==1 && conf_done==1'b1)begin + conf_state <= 7; + conf_entry <= 1'b0; + end + end + default:O_TXD_DAT <= 8'h00; + endcase + end + //-------- set_mode_and_lock (44): 01,44,00,XX,YY,00,00,00,00 + // --,F3,5A,00,00,00,00,00,00 + 2:begin + case(I_BYTE_CNT) + 0:O_TXD_DAT <= 8'h01; + 1:O_TXD_DAT <= 8'h44; + 3:O_TXD_DAT <= pad_mode[0] ? 8'h01:8'h00; + 4:O_TXD_DAT <= pad_mode[1] ? 8'h03:8'h00; + 8:begin + O_TXD_DAT <= 8'h00; + conf_state<= 3; + end + default:O_TXD_DAT <= 8'h00; + endcase + end + //-------- vibration_enable (4D): 01,4D,00,00,01,FF,FF,FF,FF + // --,F3,5A,XX,YY,FF,FF,FF,FF + 3:begin + case(I_BYTE_CNT) + 0:O_TXD_DAT <= 8'h01; + 1:O_TXD_DAT <= 8'h4D; + 2,3:O_TXD_DAT <= 8'h00; + 4:O_TXD_DAT <= 8'h01; + 8:begin + O_TXD_DAT <= 8'hFF; + conf_state<= 6; + end + default:O_TXD_DAT <= 8'hFF; + endcase + end + //-------- config_mode_exit (43): 01,43,00,00,5A,5A,5A,5A,5A + // --,F3,5A,00,00,00,00,00,00 + 6:begin + case(I_BYTE_CNT) + 0:O_TXD_DAT <= 8'h01; + 1:O_TXD_DAT <= 8'h43; + 2,3:O_TXD_DAT <= 8'h00; + 8:begin + O_TXD_DAT <= 8'h5A; + conf_state<= 7; + conf_entry<= 1'b0; + conf_done <= 1'b1; + conf_ent_reg<= 1'b0; + end + default:O_TXD_DAT <= 8'h5A; + endcase + end + default:; + endcase + end + end +end + +endmodule + +module ps_pls_gan( + +I_CLK, +I_RSTn, +I_TYPE, + +O_SCAN_SEQ_PLS, +O_RXWT, +O_TXWT, +O_TXSET, +O_TXEN, +O_psCLK, +O_psSEL, +O_byte_cnt, + +Timer + +); + +parameter Timer_size = `Timer_siz; + +input I_CLK,I_RSTn; +input I_TYPE; +output O_SCAN_SEQ_PLS; +output O_RXWT; +output O_TXWT; +output O_TXSET; +output O_TXEN; +output O_psCLK; +output O_psSEL; +output [3:0]O_byte_cnt; + +output [Timer_size-1:0]Timer; +reg [Timer_size-1:0]Timer; + +reg O_SCAN_SEQ_PLS; +reg RXWT; +reg TXWT; +reg TXSET; +reg psCLK_gate; +reg psSEL; +reg [3:0]O_byte_cnt; + +always@(posedge I_CLK or negedge I_RSTn) +begin + if(! I_RSTn) Timer <= 0; + else Timer <= Timer+1; +end + +always@(posedge I_CLK or negedge I_RSTn) +begin + if(! I_RSTn) + O_SCAN_SEQ_PLS <= 0; + else begin + if(Timer == 0) O_SCAN_SEQ_PLS <= 1; + else O_SCAN_SEQ_PLS <= 0; + end +end + +always@(posedge I_CLK or negedge I_RSTn) +begin + if(! I_RSTn) + begin + psCLK_gate <= 1; + RXWT <= 0; + TXWT <= 0; + TXSET <= 0; + end + else begin + case(Timer[4:0]) + 6: TXSET <= 1; + 8: TXSET <= 0; + 9: TXWT <= 1; + 11: TXWT <= 0; + 12: psCLK_gate <= 0; + 20: psCLK_gate <= 1; + 21: RXWT <= 1; + 23: RXWT <= 0; + default:; + endcase + end +end + +always@(posedge I_CLK or negedge I_RSTn) +begin + if(! I_RSTn) + psSEL <= 1; + else begin + if(O_SCAN_SEQ_PLS == 1) + psSEL <= 0; + else if((I_TYPE == 0)&&(Timer == 158)) + psSEL <= 1; + else if((I_TYPE == 1)&&(Timer == 286)) + psSEL <= 1; + end +end + +always@(posedge I_CLK or negedge I_RSTn) +begin + if(! I_RSTn) + O_byte_cnt <= 0; + else begin + if( O_SCAN_SEQ_PLS == 1) + O_byte_cnt <= 0; + else begin + if( Timer[4:0] == 5'b11111)begin + if(I_TYPE == 0 && O_byte_cnt == 5) + O_byte_cnt <= O_byte_cnt; + else if(I_TYPE == 1 && O_byte_cnt == 9) + O_byte_cnt <= O_byte_cnt; + else + O_byte_cnt <= O_byte_cnt+1; + end + end + end +end + +assign O_psCLK = psCLK_gate | I_CLK | psSEL; +assign O_psSEL = psSEL; +assign O_RXWT = ~psSEL&RXWT; +assign O_TXSET = ~psSEL&TXSET; +assign O_TXWT = ~psSEL&TXWT; +assign O_TXEN = ~psSEL&(~psCLK_gate); + +endmodule + +module ps_rxd( + +I_CLK, +I_RSTn, +I_WT, +I_psRXD, +O_RXD_DAT + +); + +input I_CLK,I_RSTn,I_WT; +input I_psRXD; +output [7:0]O_RXD_DAT; +reg [7:0]O_RXD_DAT; +reg [7:0]sp; + +always@(posedge I_CLK or negedge I_RSTn) + if(! I_RSTn) sp <= 1; + else sp <= { I_psRXD, sp[7:1]}; +always@(posedge I_WT or negedge I_RSTn) + if(! I_RSTn) O_RXD_DAT <= 1; + else O_RXD_DAT <= sp; + +endmodule + +module ps_txd( + +I_CLK, +I_RSTn, +I_WT, +I_EN, +I_TXD_DAT, +O_psTXD + +); + +input I_CLK,I_RSTn; +input I_WT,I_EN; +input [7:0]I_TXD_DAT; +output O_psTXD; +reg O_psTXD; +reg [7:0]ps; + +always@(negedge I_CLK or negedge I_RSTn) +begin + if(! I_RSTn)begin + O_psTXD <= 1; + ps <= 0; + end + else begin + if(I_WT) + ps <= I_TXD_DAT; + else begin + if(I_EN)begin + O_psTXD <= ps[0]; + ps <= {1'b1, ps[7:1]}; + end + else begin + O_psTXD <= 1'd1; + ps <= ps; + end + end + end +end + +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/psx_control.v b/target/pocket/analogizer/psx_control.v new file mode 100644 index 0000000..88a5431 --- /dev/null +++ b/target/pocket/analogizer/psx_control.v @@ -0,0 +1,123 @@ +module psx_control(clk_50mhz, + I_psRXD, + O_psCLK, + O_psSEL, + O_psTXD, + O_l1, + O_l2, + O_r1, + O_r2, + O_l3, + O_r3, + O_d_pad_up, + O_d_pad_down, + O_d_pad_left, + O_d_pad_right, + O_square, + O_triangle, + O_circle, + O_x, + O_select, + O_start, + O_analog1_left_right, + O_analog2_left_right, + O_analog1_up_down, + O_analog2_up_down, + switches + ); + +input clk_50mhz; // 50Mhz +input I_psRXD; +output O_psCLK; +output O_psSEL; +output O_psTXD; +output O_l1; +output O_l2; +output O_r1; +output O_r2; +output O_l3; +output O_r3; +output O_d_pad_up; +output O_d_pad_down; +output O_d_pad_left; +output O_d_pad_right; +output O_square; +output O_triangle; +output O_circle; +output O_x; +output O_select; +output O_start; +output [7:0]O_analog1_left_right; +output [7:0]O_analog2_left_right; +output [7:0]O_analog1_up_down; +output [7:0]O_analog2_up_down; +input [1:0]switches; + + +wire [7:0]data_to_psx1; +wire [7:0]data_to_psx2; +wire [7:0]data_to_psx3; +wire [7:0]data_to_psx4; +wire [7:0]data_to_psx5; +wire [7:0]data_to_psx6; + + +// BUTTONS PSX +assign O_d_pad_up=~data_to_psx1[4]; +assign O_d_pad_down=~data_to_psx1[6]; +assign O_d_pad_left=~data_to_psx1[5]; +assign O_d_pad_right=~data_to_psx1[7]; + +assign O_select=~data_to_psx1[0]; +assign O_start=~data_to_psx1[3]; +assign O_l3=~data_to_psx1[1]; +assign O_r3=~data_to_psx1[2]; +assign O_l1=~data_to_psx2[2]; +assign O_r1=~data_to_psx2[3]; +assign O_l2=~data_to_psx2[0]; +assign O_r2=~data_to_psx2[1]; +assign O_triangle=~data_to_psx2[4]; +assign O_square=~data_to_psx2[7]; +assign O_circle=~data_to_psx2[5]; +assign O_x=~data_to_psx2[6]; + +assign O_analog1_left_right=data_to_psx3[7:0]; +assign O_analog2_left_right=data_to_psx5[7:0]; +assign O_analog1_up_down=data_to_psx4[7:0]; +assign O_analog2_up_down=data_to_psx6[7:0]; + + +wire CLK_FSM_PSX; + +/*DIVISOR DE FRECUENCIA PARA GENERAR CLK DE LA FSM DEL DECODIFICADOR DE PSX*/ +pll pll_inst ( + .inclk0 ( clk_50mhz ), + .c0 ( CLK_FSM_PSX ), + .c1 ( ) + ); + + +psPAD_top psPAD_top_inst +( + .I_CLK250K(CLK_FSM_PSX) , // input I_CLK250K_sig + .I_RSTn(1'b1) , // input I_RSTn_sig + .O_psCLK(O_psCLK) , // output O_psCLK_sig + .O_psSEL(O_psSEL) , // output O_psSEL_sig + .O_psTXD(O_psTXD) , // output O_psTXD_sig + .I_psRXD(I_psRXD) , // input I_psRXD_sig + .O_RXD_1(data_to_psx1) , // output [7:0] O_RXD_1_sig + .O_RXD_2(data_to_psx2) , // output [7:0] O_RXD_2_sig + .O_RXD_3(data_to_psx3) , // output [7:0] O_RXD_3_sig + .O_RXD_4(data_to_psx4) , // output [7:0] O_RXD_4_sig + .O_RXD_5(data_to_psx5) , // output [7:0] O_RXD_5_sig + .O_RXD_6(data_to_psx6) , // output [7:0] O_RXD_6_sig + .I_CONF_SW(1'b1) , // input I_CONF_SW_sig + .I_MODE_SW(1'b1) , // input I_MODE_SW_sig + .I_MODE_EN(1'b1) , // input I_MODE_EN_sig + .I_VIB_SW(switches) , // input [1:0] I_VIB_SW_sig + .I_VIB_DAT(8'hff) // input [7:0] I_VIB_DAT_sig +); + + + +endmodule diff --git a/target/pocket/analogizer/scandoubler.v b/target/pocket/analogizer/scandoubler.v new file mode 100644 index 0000000..69b997a --- /dev/null +++ b/target/pocket/analogizer/scandoubler.v @@ -0,0 +1,289 @@ +// +// 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 . + +// AMR - generates and output a pixel clock with a reliable phase relationship with +// with the scandoubled hsync pulse. Allows the incoming data to be sampled more +// sparsely, reducing block RAM usage. ce_x1/x2 are replaced with a ce_divider +// which is the largest value the counter will reach before resetting - so 3'111 to +// divide clk_sys by 8, 3'011 to divide by 4, 3'101 to divide by six. + +// Also now has a bypass mode, in which the incoming data will be scaled to the output +// width but otherwise unmodified. Simplifies the rest of the video chain. + + +module scandoubler +( + // system interface + input clk_sys, + + input bypass, + + // Pixelclock + input [2:0] ce_divider, // 0 - clk_sys/4, 1 - clk_sys/2, 2 - clk_sys/3, 3 - clk_sys/4, etc. + output pixel_ena, + + // scanlines (00-none 01-25% 10-50% 11-75%) + input [1:0] scanlines, + + // shifter video interface + input hb_in, + input vb_in, + input hs_in, + input vs_in, + input [COLOR_DEPTH-1:0] r_in, + input [COLOR_DEPTH-1:0] g_in, + input [COLOR_DEPTH-1:0] b_in, + + // output interface + output hb_out, + output vb_out, + output hs_out, + output vs_out, + output [OUT_COLOR_DEPTH-1:0] r_out, + output [OUT_COLOR_DEPTH-1:0] g_out, + output [OUT_COLOR_DEPTH-1:0] b_out +); + +parameter HCNT_WIDTH = 9; // Resolution of scandoubler buffer +parameter COLOR_DEPTH = 6; // Bits per colour to be stored in the buffer +parameter HSCNT_WIDTH = 12; // Resolution of hsync counters +parameter OUT_COLOR_DEPTH = 6; // Bits per color outputted + +// --------------------- create output signals ----------------- +// latch everything once more to make it glitch free and apply scanline effect +reg scanline; +reg [OUT_COLOR_DEPTH-1:0] r; +reg [OUT_COLOR_DEPTH-1:0] g; +reg [OUT_COLOR_DEPTH-1:0] b; + +wire [COLOR_DEPTH*3-1:0] sd_mux = bypass ? {r_in, g_in, b_in} : sd_out[COLOR_DEPTH*3-1:0]; + +localparam m = OUT_COLOR_DEPTH/COLOR_DEPTH; +localparam n = OUT_COLOR_DEPTH%COLOR_DEPTH; + +always @(*) begin + if (n>0) begin + b = { {m{sd_mux[COLOR_DEPTH-1:0]}}, sd_mux[COLOR_DEPTH-1 -:n] }; + g = { {m{sd_mux[COLOR_DEPTH*2-1:COLOR_DEPTH]}}, sd_mux[COLOR_DEPTH*2-1 -:n] }; + r = { {m{sd_mux[COLOR_DEPTH*3-1:COLOR_DEPTH*2]}}, sd_mux[COLOR_DEPTH*3-1 -:n] }; + end else begin + b = { {m{sd_mux[COLOR_DEPTH-1:0]}} }; + g = { {m{sd_mux[COLOR_DEPTH*2-1:COLOR_DEPTH]}} }; + r = { {m{sd_mux[COLOR_DEPTH*3-1:COLOR_DEPTH*2]}} }; + end +end + + +reg [OUT_COLOR_DEPTH+6:0] r_mul; +reg [OUT_COLOR_DEPTH+6:0] g_mul; +reg [OUT_COLOR_DEPTH+6:0] b_mul; +reg hb_o; +reg vb_o; +reg hs_o; +reg vs_o; + +wire scanline_bypass = (!scanline) | (!(|scanlines)) | bypass; + +// More subtle variant of the scanlines effect. +// 0 00 -> 1000000 0x40 - bypass / inert mode +// 1 01 -> 0111010 0x3a - 25% +// 2 10 -> 0101110 0x2e - 50% +// 3 11 -> 0011010 0x1a - 75% + +wire [6:0] scanline_coeff = scanline_bypass ? + 7'b1000000 : {~(&scanlines),scanlines[0],1'b1,~scanlines[0],2'b10}; + +always @(posedge clk_sys) begin + if(ce_x2) begin + hs_o <= hs_sd; + vs_o <= vs_sd; + hb_o <= hb_sd; + vb_o <= vb_sd; + + // reset scanlines at every new screen + if(vs_o != vs_in) scanline <= 0; + + // toggle scanlines at begin of every hsync + if(hs_o && !hs_sd) scanline <= !scanline; + + r_mul<=r*scanline_coeff; + g_mul<=g*scanline_coeff; + b_mul<=b*scanline_coeff; + end +end + +wire [OUT_COLOR_DEPTH-1:0] r_o = r_mul[OUT_COLOR_DEPTH+5 -:OUT_COLOR_DEPTH]; +wire [OUT_COLOR_DEPTH-1:0] g_o = g_mul[OUT_COLOR_DEPTH+5 -:OUT_COLOR_DEPTH]; +wire [OUT_COLOR_DEPTH-1:0] b_o = b_mul[OUT_COLOR_DEPTH+5 -:OUT_COLOR_DEPTH]; + +// Output multiplexing +wire blank_out = hb_out | vb_out; +assign r_out = blank_out ? {OUT_COLOR_DEPTH{1'b0}} : bypass ? r : r_o; +assign g_out = blank_out ? {OUT_COLOR_DEPTH{1'b0}} : bypass ? g : g_o; +assign b_out = blank_out ? {OUT_COLOR_DEPTH{1'b0}} : bypass ? b : b_o; +assign hb_out = bypass ? hb_in : hb_o; +assign vb_out = bypass ? vb_in : vb_o; +assign hs_out = bypass ? hs_in : hs_o; +assign vs_out = bypass ? vs_in : vs_o; + + +// scan doubler output register +reg [COLOR_DEPTH*3-1:0] sd_out; + +// ================================================================== +// ======================== the line buffers ======================== +// ================================================================== + +// 2 lines of 2**HCNT_WIDTH pixels 3*COLOR_DEPTH bit RGB +(* ramstyle = "no_rw_check" *) reg [COLOR_DEPTH*3-1:0] sd_buffer[2*2**HCNT_WIDTH]; + +// use alternating sd_buffers when storing/reading data +reg line_toggle; + +// total hsync time (in 16MHz cycles), hs_total reaches 1024 +reg [HCNT_WIDTH-1:0] hcnt; +reg [HSCNT_WIDTH:0] hs_max; +reg [HSCNT_WIDTH:0] hs_rise; +reg [HCNT_WIDTH:0] hb_fall[2]; +reg [HCNT_WIDTH:0] hb_rise[2]; +reg [HCNT_WIDTH+1:0] vb_event[2]; +reg [HCNT_WIDTH+1:0] vs_event[2]; +reg [HSCNT_WIDTH:0] synccnt; + +// Input pixel clock, aligned with input sync: +wire[2:0] ce_divider_adj = |ce_divider ? ce_divider : 3'd3; // 0 = clk/4 for compatiblity +reg [2:0] ce_divider_in; +reg [2:0] ce_divider_out; + +reg [2:0] i_div; +wire ce_x1 = (i_div == ce_divider_in); + +always @(posedge clk_sys) begin + reg hsD, vsD; + reg vbD; + reg hbD; + + // Pixel logic on x1 clkena + if(ce_x1) begin + hcnt <= hcnt + 1'd1; + vsD <= vs_in; + vbD <= vb_in; + + sd_buffer[{line_toggle, hcnt}] <= {r_in, g_in, b_in}; + if (vbD ^ vb_in) vb_event[line_toggle] <= {1'b1, vb_in, hcnt}; + if (vsD ^ vs_in) vs_event[line_toggle] <= {1'b1, vs_in, hcnt}; + // save position of hblank + hbD <= hb_in; + if(!hbD && hb_in) hb_rise[line_toggle] <= {1'b1, hcnt}; + if( hbD && !hb_in) hb_fall[line_toggle] <= {1'b1, hcnt}; + end + + // Generate pixel clock + i_div <= i_div + 1'd1; + + if (i_div==ce_divider_adj) i_div <= 3'b000; + + synccnt <= synccnt + 1'd1; + hsD <= hs_in; + if(hsD && !hs_in) begin + // At hsync latch the ce_divider counter limit for the input clock + // and pass the previous input clock limit to the output stage. + // This should give correct output if the pixel clock changes mid-screen. + ce_divider_out <= ce_divider_in; + ce_divider_in <= ce_divider_adj; + hs_max <= {1'b0,synccnt[HSCNT_WIDTH:1]}; + hcnt <= 0; + synccnt <= 0; + i_div <= 3'b000; + end + + // save position of rising edge + if(!hsD && hs_in) hs_rise <= {1'b0,synccnt[HSCNT_WIDTH:1]}; + + // begin of incoming hsync + if(hsD && !hs_in) begin + line_toggle <= !line_toggle; + vb_event[!line_toggle] <= 0; + vs_event[!line_toggle] <= 0; + hb_rise[!line_toggle][HCNT_WIDTH] <= 0; + hb_fall[!line_toggle][HCNT_WIDTH] <= 0; + end + +end + +// ================================================================== +// ==================== output timing generation ==================== +// ================================================================== + +reg [HSCNT_WIDTH:0] sd_synccnt; +reg [HCNT_WIDTH-1:0] sd_hcnt; +reg vb_sd = 0; +reg hb_sd = 0; +reg hs_sd = 0; +reg vs_sd = 0; + +// Output pixel clock, aligned with output sync: +reg [2:0] sd_i_div; +wire ce_x2 = (sd_i_div == ce_divider_out) | (sd_i_div == {1'b0,ce_divider_out[2:1]}); + +// timing generation runs 32 MHz (twice the input signal analysis speed) +always @(posedge clk_sys) begin + reg hsD; + + // Output logic on x2 clkena + if(ce_x2) begin + // output counter synchronous to input and at twice the rate + sd_hcnt <= sd_hcnt + 1'd1; + + // read data from line sd_buffer + sd_out <= sd_buffer[{~line_toggle, sd_hcnt}]; + + // Handle VBlank event + if(vb_event[~line_toggle][HCNT_WIDTH+1] && sd_hcnt == vb_event[~line_toggle][HCNT_WIDTH-1:0]) vb_sd <= vb_event[~line_toggle][HCNT_WIDTH]; + // Handle VSync event + if(vs_event[~line_toggle][HCNT_WIDTH+1] && sd_hcnt == vs_event[~line_toggle][HCNT_WIDTH-1:0]) vs_sd <= vs_event[~line_toggle][HCNT_WIDTH]; + // Handle HBlank events + if(hb_rise[~line_toggle][HCNT_WIDTH] && sd_hcnt == hb_rise[~line_toggle][HCNT_WIDTH-1:0]) hb_sd <= 1; + if(hb_fall[~line_toggle][HCNT_WIDTH] && sd_hcnt == hb_fall[~line_toggle][HCNT_WIDTH-1:0]) hb_sd <= 0; + end + + sd_i_div <= sd_i_div + 1'd1; + if (sd_i_div==ce_divider_adj) sd_i_div <= 3'b000; + + // Framing logic on sysclk + sd_synccnt <= sd_synccnt + 1'd1; + hsD <= hs_in; + + if(sd_synccnt == hs_max || (hsD && !hs_in)) begin + sd_synccnt <= 0; + sd_hcnt <= 0; + hs_sd <= 0; + sd_i_div <= 3'b000; + end + + if(sd_synccnt == hs_rise) hs_sd <= 1; + +end + +wire ce_x4 = sd_i_div[0]; // Faster pixel_ena for higher subdivisions to prevent blending from becoming to coarse. + +assign pixel_ena = ce_divider_out > 3'd5 ? + bypass ? ce_x2 : ce_x4 : + bypass ? ce_x1 : ce_x2 ; + +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/scandoubler_2.v b/target/pocket/analogizer/scandoubler_2.v new file mode 100644 index 0000000..11acf70 --- /dev/null +++ b/target/pocket/analogizer/scandoubler_2.v @@ -0,0 +1,211 @@ +// +// scandoubler.v +// +// Copyright (c) 2015 Till Harbaum +// Copyright (c) 2017-2021 Alexey Melnikov +// +// 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_2 #(parameter LENGTH, parameter HALF_DEPTH) +( + // system interface + input clk_vid, + input hq2x, + + // shifter video interface + input ce_pix, + input hs_in, + input vs_in, + input hb_in, + input vb_in, + input [DWIDTH:0] r_in, + input [DWIDTH:0] g_in, + input [DWIDTH:0] b_in, + + // output interface + output ce_pix_out, + output reg hs_out, + output vs_out, + output hb_out, + output vb_out, + output [DWIDTH:0] r_out, + output [DWIDTH:0] g_out, + output [DWIDTH:0] b_out +); + +localparam DWIDTH = HALF_DEPTH ? 3 : 7; + +reg [7:0] pix_len = 0; +wire [7:0] pl = pix_len + 1'b1; + +reg [7:0] pix_in_cnt = 0; +wire [7:0] pc_in = pix_in_cnt + 1'b1; +reg [7:0] pixsz, pixsz2, pixsz4 = 0; + +reg ce_x4i, ce_x1i; +always @(posedge clk_vid) begin + reg old_ce, valid, hs; + + if(~&pix_len) pix_len <= pl; + if(~&pix_in_cnt) pix_in_cnt <= pc_in; + + ce_x4i <= 0; + ce_x1i <= 0; + + // use such odd comparison to place ce_x4 evenly if master clock isn't multiple of 4. + if((pc_in == pixsz4) || (pc_in == pixsz2) || (pc_in == (pixsz2+pixsz4))) ce_x4i <= 1; + + old_ce <= ce_pix; + if(~old_ce & ce_pix) begin + if(valid & ~hb_in & ~vb_in) begin + pixsz <= pl; + pixsz2 <= {1'b0, pl[7:1]}; + pixsz4 <= {2'b00, pl[7:2]}; + end + pix_len <= 0; + valid <= 1; + end + + hs <= hs_in; + if((~hs & hs_in) || (pc_in >= pixsz)) begin + ce_x4i <= 1; + ce_x1i <= 1; + pix_in_cnt <= 0; + end + + if(hb_in | vb_in) valid <= 0; +end + +reg req_line_reset; +reg [DWIDTH:0] r_d, g_d, b_d; +always @(posedge clk_vid) begin + if(ce_x1i) begin + req_line_reset <= hb_in; + r_d <= r_in; + g_d <= g_in; + b_d <= b_in; + end +end + +Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x +( + .clk(clk_vid), + + .ce_in(ce_x4i), + .inputpixel({b_d,g_d,r_d}), + .disable_hq2x(~hq2x), + .reset_frame(vb_in), + .reset_line(req_line_reset), + + .ce_out(ce_x4o), + .read_y(sd_line), + .hblank(hbo[0]&hbo[8]), + .outpixel({b_out,g_out,r_out}) +); + +reg [7:0] pix_out_cnt = 0; +wire [7:0] pc_out = pix_out_cnt + 1'b1; + +reg ce_x4o, ce_x2o; +always @(posedge clk_vid) begin + reg hs; + + if(~&pix_out_cnt) pix_out_cnt <= pc_out; + + ce_x4o <= 0; + ce_x2o <= 0; + + // use such odd comparison to place ce_x4 evenly if master clock isn't multiple of 4. + if((pc_out == pixsz4) || (pc_out == pixsz2) || (pc_out == (pixsz2+pixsz4))) ce_x4o <= 1; + if( pc_out == pixsz2) ce_x2o <= 1; + + hs <= hs_out; + if((~hs & hs_out) || (pc_out >= pixsz)) begin + ce_x2o <= 1; + ce_x4o <= 1; + pix_out_cnt <= 0; + end +end + +reg [1:0] sd_line; +reg [3:0] vbo; +reg [3:0] vso; +reg [8:0] hbo; +always @(posedge clk_vid) begin + + reg [31:0] hcnt; + reg [30:0] sd_hcnt; + reg [30:0] hs_start, hs_end; + reg [30:0] hde_start, hde_end; + + reg hs, hb; + + if(ce_x4o) begin + hbo[8:1] <= hbo[7:0]; + end + + // output counter synchronous to input and at twice the rate + sd_hcnt <= sd_hcnt + 1'd1; + if(sd_hcnt == hde_start) begin + sd_hcnt <= 0; + vbo[3:1] <= vbo[2:0]; + end + + if(sd_hcnt == hs_end) begin + sd_line <= sd_line + 1'd1; + if(&vbo[3:2]) sd_line <= 1; + vso[3:1] <= vso[2:0]; + end + + if(sd_hcnt == hde_start)hbo[0] <= 0; + if(sd_hcnt == hde_end) hbo[0] <= 1; + + // replicate horizontal sync at twice the speed + if(sd_hcnt == hs_end) hs_out <= 0; + if(sd_hcnt == hs_start) hs_out <= 1; + + hs <= hs_in; + hb <= hb_in; + + hcnt <= hcnt + 1'd1; + if(hb && !hb_in) begin + hde_start <= hcnt[31:1]; + hbo[0] <= 0; + hcnt <= 0; + sd_hcnt <= 0; + vbo <= {vbo[2:0],vb_in}; + end + + if(!hb && hb_in) hde_end <= hcnt[31:1]; + + // falling edge of hsync indicates start of line + if(hs && !hs_in) begin + hs_end <= hcnt[31:1]; + vso[0] <= vs_in; + end + + // save position of rising edge + if(!hs && hs_in) hs_start <= hcnt[31:1]; +end + +assign vs_out = vso[3]; +assign ce_pix_out = hq2x ? ce_x4o : ce_x2o; + +//Compensate picture shift after HQ2x +assign vb_out = vbo[3]; +assign hb_out = hbo[6]; + +endmodule diff --git a/target/pocket/analogizer/scanlines.v b/target/pocket/analogizer/scanlines.v new file mode 100644 index 0000000..a8191e8 --- /dev/null +++ b/target/pocket/analogizer/scanlines.v @@ -0,0 +1,68 @@ +module scanlines #(parameter v2=0) +( + input clk, + + input [1:0] scanlines, + input [23:0] din, + input hs_in,vs_in, + input de_in,ce_in, + + output reg [23:0] dout, + output reg hs_out,vs_out, + output reg de_out,ce_out +); + +reg [1:0] scanline; +always @(posedge clk) begin + reg old_hs, old_vs; + + old_hs <= hs_in; + old_vs <= vs_in; + + if(old_hs && ~hs_in) begin + if(v2) begin + scanline <= scanline + 1'd1; + if (scanline == scanlines) scanline <= 0; + end + else scanline <= scanline ^ scanlines; + end + if(old_vs && ~vs_in) scanline <= 0; +end + +wire [7:0] r,g,b; +assign {r,g,b} = din; + +reg [23:0] d; +always @(*) begin + case(scanline) + 1: // reduce 25% = 1/2 + 1/4 + d = {{1'b0, r[7:1]} + {2'b00, r[7:2]}, + {1'b0, g[7:1]} + {2'b00, g[7:2]}, + {1'b0, b[7:1]} + {2'b00, b[7:2]}}; + + 2: // reduce 50% = 1/2 + d = {{1'b0, r[7:1]}, + {1'b0, g[7:1]}, + {1'b0, b[7:1]}}; + + 3: // reduce 75% = 1/4 + d = {{2'b00, r[7:2]}, + {2'b00, g[7:2]}, + {2'b00, b[7:2]}}; + + default: d = {r,g,b}; + endcase +end + +always @(posedge clk) begin + reg [23:0] dout1, dout2; + reg de1,de2,vs1,vs2,hs1,hs2,ce1,ce2; + + dout <= dout2; dout2 <= dout1; dout1 <= d; + vs_out <= vs2; vs2 <= vs1; vs1 <= vs_in; + hs_out <= hs2; hs2 <= hs1; hs1 <= hs_in; + de_out <= de2; de2 <= de1; de1 <= de_in; + ce_out <= ce2; ce2 <= ce1; ce1 <= ce_in; +end + +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/scanlines_analogizer.v b/target/pocket/analogizer/scanlines_analogizer.v new file mode 100644 index 0000000..6be3ba7 --- /dev/null +++ b/target/pocket/analogizer/scanlines_analogizer.v @@ -0,0 +1,68 @@ +module scanlines_analogizer #(parameter v2=0) +( + input clk, + + input [1:0] scanlines, + input [23:0] din, + input hs_in,vs_in, + input de_in,ce_in, + + output reg [23:0] dout, + output reg hs_out,vs_out, + output reg de_out,ce_out +); + +reg [1:0] scanline; +always @(posedge clk) begin + reg old_hs, old_vs; + + old_hs <= hs_in; + old_vs <= vs_in; + + if(old_hs && ~hs_in) begin + if(v2) begin + scanline <= scanline + 1'd1; + if (scanline == scanlines) scanline <= 0; + end + else scanline <= scanline ^ scanlines; + end + if(old_vs && ~vs_in) scanline <= 0; +end + +wire [7:0] r,g,b; +assign {r,g,b} = din; + +reg [23:0] d; +always @(*) begin + case(scanline) + 1: // reduce 25% = 1/2 + 1/4 + d = {{1'b0, r[7:1]} + {2'b00, r[7:2]}, + {1'b0, g[7:1]} + {2'b00, g[7:2]}, + {1'b0, b[7:1]} + {2'b00, b[7:2]}}; + + 2: // reduce 50% = 1/2 + d = {{1'b0, r[7:1]}, + {1'b0, g[7:1]}, + {1'b0, b[7:1]}}; + + 3: // reduce 75% = 1/4 + d = {{2'b00, r[7:2]}, + {2'b00, g[7:2]}, + {2'b00, b[7:2]}}; + + default: d = {r,g,b}; + endcase +end + +always @(posedge clk) begin + reg [23:0] dout1, dout2; + reg de1,de2,vs1,vs2,hs1,hs2,ce1,ce2; + + dout <= dout2; dout2 <= dout1; dout1 <= d; + vs_out <= vs2; vs2 <= vs1; vs1 <= vs_in; + hs_out <= hs2; hs2 <= hs1; hs1 <= hs_in; + de_out <= de2; de2 <= de1; de1 <= de_in; + ce_out <= ce2; ce2 <= ce1; ce1 <= ce_in; +end + +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/serlatch_gc.v b/target/pocket/analogizer/serlatch_gc.v new file mode 100644 index 0000000..2f9d4b4 --- /dev/null +++ b/target/pocket/analogizer/serlatch_gc.v @@ -0,0 +1,367 @@ +//************************************************************** +//* Analogizer SNAC openFPGA interface for the Analogue Pocket * +//************************************************************** +// By @RndMnkIII. +// Date: 01/2024 +// Release: 1.0 + +// Aquí he documentado el funcionamiento de los diferentes mandos de juegos a los que he ido dando soporte, basado en las capturas de datos +// realizadas con analizador lógico + generador de patrones: +// +// ******** +// * DB15 * Tested up 1MHz +// ******** +// +// STB | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |17 |18 |19 |20 |21 |22 |23 |24 |25 |26 |27 |28 |29 |30 |31 |32 |33 |34 |35 |36 |37 |38 |39 |40 |41 |42 |43 |44 |45 |46 |47 |48 |49 | +// ____ ___________________________________________________________________________________________________________________________________________________________________________________________ +// LATCH \_______/ +// ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ +// CLK / \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___ +// ___ ___________ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ +// DATA / \ P1 D X P1 C X P1 B X P1 A X P1 RG X P1 LF X P1 DW X P1 UP X P2 RG X P2 LF X P2 DW X P2 UP X P1 F X P1 E X P1 SELX P1 ST X P2 F X P2 E X P2 SELX P2 ST X P2 D X P2 C X P2B X P2 A +// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ +// SAMPLE | | | | | | | | | | | | | | | | | | | | | | | | +// 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 +// TEST DATA 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 +// TEST DATA 2 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 +// POCKET INPUTS +// 1 P1 up X +// 0 P1 down X +// 1 P1 left X +// 0 P1 right X +// 0 P1 y X +// 1 P1 x X +// 0 P1 b X +// 1 P1 a X +// 1 P1 l1 X +// 0 P1 r1 X +// 0 P1 l2 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// 0 P1 r2 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// 0 P1 l3 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// 0 P1 r3 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// 0 P1 select X +// 1 P1 start X +// 1 P2 up X +// 0 P2 down X +// 1 P2 left X +// 0 P2 right X +// 0 P2 y X +// 1 P2 x X +// 0 P2 b X +// 1 P2 a X +// 1 P2 l1 X +// 0 P2 r1 X +// 0 P2 l2 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// 0 P2 r2 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// 0 P2 l3 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// 0 P2 r3 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +// 0 P2 select X +// 1 P2 start X +//P1 1010 0101 1000 0001 +// A 5 8 1 +//P2 1010 0101 1000 0001 +// A 5 8 1 +//gtkwave +//p1 1010 0101 1000 0001 +// A581 +//p2 1010 0101 1000 0001 +// A581 +// x +// 1111111 +// 6543210987654321 +// ******** +// * NES * Tested up 1MHz +// ******** +// STB | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |17 |18 |19 |20 |21 |22 |23 |24 |25 |26 |27 |28 |29 |30 |31 |32 |33 |34 |35 | +// _______ +// LATCH ____/ \___________________________________________________________________________________________________________________________________ +// ..... ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ +// CLK ________.___.___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___ +// ____ ___________ _______ _______ _______ _______ _______ _______ _______ _______________________________________________________________________ +// DATA \ BTN A X BTN B X SELECTX START X UP X DOWN X LEFT X RIGHT / +// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ +// SAMPLE | | | | | | | | | | | | | | | | | +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +// POCKET INPUTS +// P1 P2 +// 0 1 P1 up X +// 1 0 P1 down X +// 0 1 P1 left X +// 1 0 P1 right X +// 0 0 P1 y ------------------------------------------------------------------------------------------------------------------------------------ +// 0 0 P1 x ------------------------------------------------------------------------------------------------------------------------------------ +// 1 0 P1 b X +// 0 1 P1 a X +// 0 0 P1 l1 ------------------------------------------------------------------------------------------------------------------------------------ +// 0 0 P1 r1 ------------------------------------------------------------------------------------------------------------------------------------ +// 0 0 P1 l2 ------------------------------------------------------------------------------------------------------------------------------------ +// 0 0 P1 r2 ------------------------------------------------------------------------------------------------------------------------------------ +// 0 0 P1 l3 ---------------------------------------------------------------------------------------------------------------------------------- +// 0 0 P1 r3 ------------------------------------------------------------------------------------------------------------------------------------ +// 0 1 P1 select X +// 1 0 P1 start X +// P1 0101 0010 0000 0001 <- 0101_0101 B START DOWN RIGHT +// 5 2 0 1 +// P2 1010 0001 0000 0010 <- 1010_1010 A SELECT UP LEFT +// A 1 0 2 +// 1111111 +// 6543210987654321 +//gtkwave +// P1 5201 +// P2 A102 +// +// ******** +// * SNES * Tested up 200KHz +// ******** +// STB | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |17 |18 |19 |20 |21 |22 |23 |24 |25 |26 |27 |28 |29 |30 |31 |32 |33 |34 |35 | +// _______ +// LATCH ____/ \___________________________________________________________________________________________________________________________________ +// ..... ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ +// CLK ________.___.___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___/ \___ +// __ _________ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ _______ +// DATA ___ / \ BTN_B X BTN_Y X SEL X START X UP X DOWN X LEFT X RIGHT X BTN_A X BTN_X X TG_L X TG_R X H X H X H X H \______ +// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ +// SAMPLE | | | | | | | | | | | | | | | | | +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 +// POCKET INPUTS +// 0 P1 up X +// 1 P1 down X +// 2 P1 left X +// 3 P1 right X +// 4 P1 y X +// 5 P1 x X +// 6 P1 b X +// 7 P1 a X +// 8 P1 l1 X +// 9 P1 r1 X +//10 P1 l2 ------------------------------------------------------------------------------------------------------------------------------------ +//11 P1 r2 ------------------------------------------------------------------------------------------------------------------------------------ +//12 P1 l3 ------------------------------------------------------------------------------------------------------------------------------------ +//13 P1 r3 ------------------------------------------------------------------------------------------------------------------------------------ +//14 P1 select X +//15 P1 start X +`default_nettype none + +module serlatch_game_controller #(parameter MASTER_CLK_FREQ=53_600_000) +( + input wire i_clk, + input wire i_rst, + input wire [3:0] game_controller_type, //0x0 DISABLED, 0x1 DB15, 0x2 NES, 0x3 SNES, 0x9 DB15 Fast, 0xB SNES SWAP A,B<->X,Y + input wire i_stb, + output reg [15:0] p1_btn_state, + output reg [15:0] p2_btn_state, + output reg busy, + + //SNAC Game controller interface + output wire o_clk, //for controller 1 + output wire o_clk2, //for controller 2 + output wire o_lat, //shared for 2 controllers + input wire i_dat1, //data from controller 1 + input wire i_dat2 //data from controller 2 +); + //FSM states + parameter IDLE = 3'b001; + parameter LATCH = 3'b010; + parameter DATA = 3'b100; + + //store module settings + reg [3:0] game_controller_type_r; + reg [2:0] state = IDLE; + + reg [5:0] counter; + //reg [4:0] btn_cnt; + reg [5:0] counter_top_value; + reg latch_internal; + reg clk_internal; + reg [23:0] bstat_r; + reg [15:0] p1b_r; + reg [15:0] p2b_r; + + wire latch_level ; + wire disable_clock_on_latch ; + wire sample_data ; + + //always sample data at falling edge of o_clk starting and second clock pulse in latch phase. + assign sample_data = ~counter[0] && i_stb && (counter > 1) && (counter <= counter_top_value); + + + always @(posedge i_clk) begin + //detect reset or any change on gamepad configuration and restart FSM at IDLE state. + if(i_rst || (game_controller_type != game_controller_type_r)) begin + state <= IDLE; + //clear internal register button state + p1b_r <= 16'hffff; + p2b_r <= 16'hffff; + bstat_r <= 24'hffffff; + end + + game_controller_type_r <= game_controller_type; + + if(i_stb) begin + case(state) + IDLE: + begin + //fetch data from last read + //set button status output + case(game_controller_type_r) + 4'h0: begin //DISABLED + p1_btn_state = 16'd0; + p2_btn_state = 16'd0; + end + 4'h1,4'h9: begin //DB15, DB15 FAST + // Pocket logic button order: + // [0] dpad_up + // [1] dpad_down + // [2] dpad_left + // [3] dpad_right + // [4] face_a + // [5] face_b + // [6] face_x + // [7] face_y + // [8] trig_l1 + // [9] trig_r1 + // [10] trig_l2 + // [11] trig_r2 + // [12] trig_l3 + // [13] trig_r3 + // [14] face_select + // [15] face_start + + //SNAC DB15 adapter button order from first to last + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 + //P1D,P1C,P1B,P1A,P1R,P1L,P1D,P1U,P2R,P2L,P2D,P2U,P1F,P1E,P1SEL,P1ST,P2F,P2E,P2SEL,P2ST,P2D,P2C,P2B,P2A + //follow Pocket game controls order: + //PLAYER1 START SELECT R3 L3 R2 L2 R1 L1 Y X B A RIGH LEFT DOWN UP + p1_btn_state <= ~{bstat_r[15], bstat_r[14], 4'b1111, bstat_r[12], bstat_r[13], bstat_r[0], bstat_r[1], bstat_r[2], bstat_r[3], bstat_r[4], bstat_r[5], bstat_r[6], bstat_r[7]}; + + //PLAYER2 START SELECT R3 L3 R2 L2 R1 L1 Y X B A RIGH LEFT DOWN UP + p2_btn_state <= ~{bstat_r[19], bstat_r[18], 4'b1111, bstat_r[16], bstat_r[17], bstat_r[20], bstat_r[21], bstat_r[22], bstat_r[23], bstat_r[8], bstat_r[9], bstat_r[10], bstat_r[11]}; + end + 4'h2: begin //NES + //SNAC NES adapter button order from first to last + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + // A B SEL ST UP DW LF RG H H H H H H H H + + //follow Pocket game controls order: + // START SELECT R3 L3 R2 L2 R1 L1 Y X B A RIGHT LEFT DOWN UP + p1_btn_state <= ~{p1b_r[3],p1b_r[2], 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, p1b_r[1], p1b_r[0],p1b_r[7],p1b_r[6],p1b_r[5],p1b_r[4]}; + p2_btn_state <= ~{p2b_r[3],p2b_r[2], 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, p2b_r[1], p2b_r[0],p2b_r[7],p2b_r[6],p2b_r[5],p2b_r[4]}; + end + 4'h3: begin //SNES + //SNAC SNES adapter button order from first to last + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + // B Y SEL ST UP DW LF RG A X LT LR H H H H + + //follow Pocket game controls order: + // START SELECT R3 L3 R2 L2 R1 L1 Y X B A RIGHT LEFT DOWN UP + p1_btn_state <= ~{p1b_r[3],p1b_r[2],1'b1, 1'b1, 1'b1, 1'b1, p1b_r[11], p1b_r[10], p1b_r[1], p1b_r[9], p1b_r[0], p1b_r[8],p1b_r[7],p1b_r[6], p1b_r[5],p1b_r[4]}; + p2_btn_state <= ~{p2b_r[3],p2b_r[2],1'b1, 1'b1, 1'b1, 1'b1, p2b_r[11], p2b_r[10], p2b_r[1], p2b_r[9], p2b_r[0], p2b_r[8],p2b_r[7],p2b_r[6], p2b_r[5],p2b_r[4]}; + + end + 4'hB: begin //SNES SWAP A,B <-> X,Y + //SNAC SNES adapter button order from first to last + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + // B Y SEL ST UP DW LF RG A X LT LR H H H H + + //follow Pocket game controls order: + // START SELECT R3 L3 R2 L2 R1 L1 Y X B A RIGHT LEFT DOWN UP + p1_btn_state <= ~{p1b_r[3],p1b_r[2],1'b1, 1'b1, 1'b1, 1'b1, p1b_r[11], p1b_r[10], p1b_r[0], p1b_r[8], p1b_r[1], p1b_r[9],p1b_r[7],p1b_r[6], p1b_r[5],p1b_r[4]}; + p2_btn_state <= ~{p2b_r[3],p2b_r[2],1'b1, 1'b1, 1'b1, 1'b1, p2b_r[11], p2b_r[10], p2b_r[0], p2b_r[8], p2b_r[1], p2b_r[9],p2b_r[7],p2b_r[6], p2b_r[5],p2b_r[4]}; + + end + default: + begin //disabled + p1_btn_state <= 16'd0; + p2_btn_state <= 16'd0; + end + endcase + + //init counter and set initial LAT,CLK values on IDLE state + counter <= 6'd0; + + counter_top_value <= 6'd0; + if ((game_controller_type_r == 4'h1) || (game_controller_type_r == 4'h9)) counter_top_value <= 6'd48; + else if((game_controller_type_r == 4'h2) || (game_controller_type_r == 4'h3) || (game_controller_type_r == 4'hB)) counter_top_value <= 6'd34; + + latch_internal <= latch_level; + clk_internal <= disable_clock_on_latch ? 1'b0 : 1'b1; + state <= LATCH; + busy <= 1'b1; + p1b_r <= 16'hffff; + p2b_r <= 16'hffff; + bstat_r <= 24'hffffff; + end + LATCH: + begin + counter <= counter + 6'd1; + latch_internal <= ~latch_level; + clk_internal <= disable_clock_on_latch ? 1'b0 : ~clk_internal; + + //first sample of data is available in LATCH phase. + if(sample_data) begin//read button state + if((game_controller_type_r == 4'h1) || (game_controller_type_r == 4'h9)) begin //if is selected DB15,DB15 FAST all button state is store in one 24bit register + bstat_r[0] <= i_dat1; //3->0, 5->1, 7->2, 9->3, ... + // $display("DB15 [LATCH] BTN_CNT:%d i_dat1:%d", btn_cnt, i_dat1); + end + else begin + p1b_r[0] <= i_dat1; + p2b_r[0] <= i_dat2; + end + end + + if(counter == 6'd2) begin + state <= DATA; + latch_internal <= latch_level; + end + end + DATA: + begin + counter <= counter + 6'd1; //should be start clocking at 3 + clk_internal <= ~clk_internal; + //following data samples are get in DATA phase. + if(sample_data) begin//read button state + if((game_controller_type_r == 4'h1) || (game_controller_type_r == 4'h9) ) begin //if is selected DB15,DB15 FAST all button state is store in one 24bit register + bstat_r[((counter>>1)-1)] <= i_dat1; //3->0, 5->1, 7->2, 9->3, ... + //$display("DB15 [DATA] BTN_CNT:%d i_dat1:%d r_dat[%d]:%d", btn_cnt, i_dat1, btn_cnt,bstat_r[btn_cnt]); + end + else if((game_controller_type_r == 4'h2) || (game_controller_type_r == 4'h3) || (game_controller_type_r == 4'hB)) begin + p1b_r[((counter>>1)-1)] <= i_dat1; + p2b_r[((counter>>1)-1)] <= i_dat2; + end + end + + //the gamepads buton state are fetched at the end of DATA phase + if(counter == counter_top_value) begin + state <= IDLE; + busy <= 1'b0; + end + end + endcase + end + end + + //the DB15 SNAC interface uses active LOW latch signal, NES,SNES use active HIGH latch: + // ----- ------ ... + //DB15 LATCH |___| + // + // ___ + //NES,SNES LATCH _____| |_____ ... + + assign latch_level = ((game_controller_type_r == 4'h1) || (game_controller_type_r == 4'h9)) ? 1'b1 : 1'b0; //DB15, DB15 FAST + + //the NES,SNES SNAC interfaces disable clock signal while are in LATCH phase + //but internally the falling edge CLK is used for sample the button state + // ___ + //LATCH ______| |_________ ... + // _ _ _ + //o_clk | |_________| |_| |_ ... + // _ _ _ _ _ + //CLK | |_|X|_|X|_| |_| |_ ... + // ... 1 2 3 4 5 6 7 8 ... + assign disable_clock_on_latch = ((game_controller_type_r != 4'h1) && (game_controller_type_r != 4'h9)) ? 1'b1 : 1'b0; //en caso de que sea controlador NES,SNES + + //counter values: 36 for NES,SNES, 50 for DB15 + assign o_clk = (game_controller_type_r == 4'h0) ? 1'b0 : clk_internal; + assign o_clk2 = (game_controller_type_r == 4'h0) ? 1'b0 : clk_internal; + assign o_lat = (game_controller_type_r == 4'h0) ? 1'b0 : latch_internal; +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/sine_lut.mem b/target/pocket/analogizer/sine_lut.mem new file mode 100644 index 0000000..df99e24 --- /dev/null +++ b/target/pocket/analogizer/sine_lut.mem @@ -0,0 +1,256 @@ +000 +006 +00C +012 +018 +01F +025 +02B +031 +037 +03D +044 +04A +04F +055 +05B +061 +067 +06D +072 +078 +07D +083 +088 +08D +092 +097 +09C +0A1 +0A6 +0AB +0AF +0B4 +0B8 +0BC +0C1 +0C5 +0C9 +0CC +0D0 +0D4 +0D7 +0DA +0DD +0E0 +0E3 +0E6 +0E9 +0EB +0ED +0F0 +0F2 +0F4 +0F5 +0F7 +0F8 +0FA +0FB +0FC +0FD +0FD +0FE +0FE +0FE +0FF +0FE +0FE +0FE +0FD +0FD +0FC +0FB +0FA +0F8 +0F7 +0F5 +0F4 +0F2 +0F0 +0ED +0EB +0E9 +0E6 +0E3 +0E0 +0DD +0DA +0D7 +0D4 +0D0 +0CC +0C9 +0C5 +0C1 +0BC +0B8 +0B4 +0AF +0AB +0A6 +0A1 +09C +097 +092 +08D +088 +083 +07D +078 +072 +06D +067 +061 +05B +055 +04F +04A +044 +03D +037 +031 +02B +025 +01F +018 +012 +00C +006 +000 +7F9 +7F3 +7ED +7E7 +7E0 +7DA +7D4 +7CE +7C8 +7C2 +7BB +7B5 +7B0 +7AA +7A4 +79E +798 +792 +78D +787 +782 +77C +777 +772 +76D +768 +763 +75E +759 +754 +750 +74B +747 +743 +73E +73A +736 +733 +72F +72B +728 +725 +722 +71F +71C +719 +716 +714 +712 +70F +70D +70B +70A +708 +707 +705 +704 +703 +702 +702 +701 +701 +701 +701 +701 +701 +701 +702 +702 +703 +704 +705 +707 +708 +70A +70B +70D +70F +712 +714 +716 +719 +71C +71F +722 +725 +728 +72B +72F +733 +736 +73A +73E +743 +747 +74B +750 +754 +759 +75E +763 +768 +76D +772 +777 +77C +782 +787 +78D +792 +798 +79E +7A4 +7AA +7B0 +7B5 +7BB +7C2 +7C8 +7CE +7D4 +7DA +7E0 +7E7 +7ED +7F3 +7F9 \ No newline at end of file diff --git a/target/pocket/analogizer/sync_fix.v b/target/pocket/analogizer/sync_fix.v new file mode 100644 index 0000000..630adf4 --- /dev/null +++ b/target/pocket/analogizer/sync_fix.v @@ -0,0 +1,28 @@ +module sync_fix +( + input clk, + + input sync_in, + output sync_out +); + +assign sync_out = sync_in ^ pol; + +reg pol; +always @(posedge clk) begin + integer pos = 0, neg = 0, cnt = 0; + reg s1,s2; + + s1 <= sync_in; + s2 <= s1; + + if(~s2 & s1) neg <= cnt; + if(s2 & ~s1) pos <= cnt; + + cnt <= cnt + 1; + if(s2 != s1) cnt <= 0; + + pol <= pos > neg; +end + +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/two_button_press_detector.v b/target/pocket/analogizer/two_button_press_detector.v new file mode 100644 index 0000000..00020d4 --- /dev/null +++ b/target/pocket/analogizer/two_button_press_detector.v @@ -0,0 +1,53 @@ +//Module to detect when two buttons are pressed for 2 seconds +module two_button_press_detector( + input wire clk, // System clock at 28.375160 MHz + input wire reset, // Reset signal + input wire button1, // First button input + input wire button2, // Second button input + output reg detection_done // Output signal when both buttons are pressed for 2 seconds +); + + parameter COUNT_MAX = 56750320; // Number of clock cycles for 2 seconds + reg [31:0] counter; // Counter for 2 seconds + + // State machine states + localparam IDLE = 0, + COUNTING = 1; + reg state; + + always @(posedge clk or posedge reset) begin + if (reset) begin + counter <= 0; + detection_done <= 0; + state <= IDLE; + end else begin + case (state) + IDLE: begin + if (button1 && button2) begin + counter <= 0; + state <= COUNTING; + end else begin + detection_done <= 0; + counter <= 0; + end + end + COUNTING: begin + if (button1 && button2) begin + if (counter < COUNT_MAX - 1) begin + counter <= counter + 1; + detection_done <= 0; + end else begin + detection_done <= 1; + state <= IDLE; // Reset back to IDLE after detection + end + end else begin + detection_done <= 0; + state <= IDLE; + counter <= 0; // Reset counter if buttons are released before 2 seconds + end + end + endcase + end + end + +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/uart_tx.v b/target/pocket/analogizer/uart_tx.v new file mode 100644 index 0000000..386f988 --- /dev/null +++ b/target/pocket/analogizer/uart_tx.v @@ -0,0 +1,147 @@ +////////////////////////////////////////////////////////////////////// +// File Downloaded from http://www.nandland.com +////////////////////////////////////////////////////////////////////// +// This file contains the UART Transmitter. This transmitter is able +// to transmit 8 bits of serial data, one start bit, one stop bit, +// and no parity bit. When transmit is complete o_Tx_done will be +// driven high for one clock cycle. +// +// Set Parameter CLKS_PER_BIT as follows: +// CLKS_PER_BIT = (Frequency of i_Clock)/(Frequency of UART) +// Example: 10 MHz Clock, 115200 baud UART +// (10000000)/(115200) = 87 + + //48_000_000 /500_000 = 96 +module uart_tx + #(parameter CLKS_PER_BIT) + ( + input i_Clock, + input i_Tx_DV, + input [7:0] i_Tx_Byte, + output o_Tx_Active, + output reg o_Tx_Serial, + output o_Tx_Done + ); + + parameter s_IDLE = 3'b000; + parameter s_TX_START_BIT = 3'b001; + parameter s_TX_DATA_BITS = 3'b010; + parameter s_TX_STOP_BIT = 3'b011; + parameter s_CLEANUP = 3'b100; + + reg [2:0] r_SM_Main = 0; + reg [7:0] r_Clock_Count = 0; + reg [2:0] r_Bit_Index = 0; + reg [7:0] r_Tx_Data = 0; + reg r_Tx_Done = 0; + reg r_Tx_Active = 0; + + always @(posedge i_Clock) + begin + + case (r_SM_Main) + s_IDLE : + begin + o_Tx_Serial <= 1'b1; // Drive Line High for Idle + r_Tx_Done <= 1'b0; + r_Clock_Count <= 0; + r_Bit_Index <= 0; + + if (i_Tx_DV == 1'b1) + begin + r_Tx_Active <= 1'b1; + r_Tx_Data <= i_Tx_Byte; + r_SM_Main <= s_TX_START_BIT; + end + else + r_SM_Main <= s_IDLE; + end // case: s_IDLE + + + // Send out Start Bit. Start bit = 0 + s_TX_START_BIT : + begin + o_Tx_Serial <= 1'b0; + + // Wait CLKS_PER_BIT-1 clock cycles for start bit to finish + if (r_Clock_Count < CLKS_PER_BIT-1) + begin + r_Clock_Count <= r_Clock_Count + 1; + r_SM_Main <= s_TX_START_BIT; + end + else + begin + r_Clock_Count <= 0; + r_SM_Main <= s_TX_DATA_BITS; + end + end // case: s_TX_START_BIT + + + // Wait CLKS_PER_BIT-1 clock cycles for data bits to finish + s_TX_DATA_BITS : + begin + o_Tx_Serial <= r_Tx_Data[r_Bit_Index]; + + if (r_Clock_Count < CLKS_PER_BIT-1) + begin + r_Clock_Count <= r_Clock_Count + 1; + r_SM_Main <= s_TX_DATA_BITS; + end + else + begin + r_Clock_Count <= 0; + + // Check if we have sent out all bits + if (r_Bit_Index < 7) + begin + r_Bit_Index <= r_Bit_Index + 1; + r_SM_Main <= s_TX_DATA_BITS; + end + else + begin + r_Bit_Index <= 0; + r_SM_Main <= s_TX_STOP_BIT; + end + end + end // case: s_TX_DATA_BITS + + + // Send out Stop bit. Stop bit = 1 + s_TX_STOP_BIT : + begin + o_Tx_Serial <= 1'b1; + + // Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish + if (r_Clock_Count < CLKS_PER_BIT-1) + begin + r_Clock_Count <= r_Clock_Count + 1; + r_SM_Main <= s_TX_STOP_BIT; + end + else + begin + r_Tx_Done <= 1'b1; + r_Clock_Count <= 0; + r_SM_Main <= s_CLEANUP; + r_Tx_Active <= 1'b0; + end + end // case: s_Tx_STOP_BIT + + + // Stay here 1 clock + s_CLEANUP : + begin + r_Tx_Done <= 1'b1; + r_SM_Main <= s_IDLE; + end + + + default : + r_SM_Main <= s_IDLE; + + endcase + end + + assign o_Tx_Active = r_Tx_Active; + assign o_Tx_Done = r_Tx_Done; + +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/vga_out_sw.v b/target/pocket/analogizer/vga_out_sw.v new file mode 100644 index 0000000..b56fafd --- /dev/null +++ b/target/pocket/analogizer/vga_out_sw.v @@ -0,0 +1,72 @@ +module vga_out +( + input wire clk, + input wire ypbpr_en, + + input wire hsync, + input wire vsync, + input wire csync, + input wire de, + + input wire [23:0] din, + output wire [23:0] dout, + + output reg hsync_o, + output reg vsync_o, + output reg csync_o, + output reg de_o +); + +wire [7:0] red = {din[23:16]}; +wire [7:0] green = {din[15:8]}; +wire [7:0] blue = {din[7:0]}; + +// http://marsee101.blog19.fc2.com/blog-entry-2311.html + + +// Y = 0.301*R + 0.586*G + 0.113*B (Y = 0.299*R + 0.587*G + 0.114*B) +// Pb = 128 - 0.168*R - 0.332*G + 0.500*B (Pb = -0.169*R - 0.331*G + 0.500*B) +// Pr = 128 + 0.500*R - 0.418*G - 0.082*B (Pr = 0.500*R - 0.419*G - 0.081*B) + +reg [7:0] y, pb, pr; +reg [23:0] rgb; +always @(posedge clk) begin + reg [18:0] y_1r, pb_1r, pr_1r; + reg [18:0] y_1g, pb_1g, pr_1g; + reg [18:0] y_1b, pb_1b, pr_1b; + reg [18:0] y_2, pb_2, pr_2; + reg [23:0] din1, din2; + reg hsync2, vsync2, csync2, de2; + reg hsync1, vsync1, csync1, de1; + + y_1r <= {red, 6'd0} + {red, 3'd0} + {red, 2'd0} + red; + pb_1r <= 19'd32768 - ({red, 5'd0} + {red, 3'd0} + {red, 1'd0}); + pr_1r <= 19'd32768 + {red, 7'd0}; + + y_1g <= {green, 7'd0} + {green, 4'd0} + {green, 2'd0} + {green, 1'd0}; + pb_1g <= {green, 6'd0} + {green, 4'd0} + {green, 2'd0} + green; + pr_1g <= {green, 6'd0} + {green, 5'd0} + {green, 3'd0} + {green, 1'd0}; + + y_1b <= {blue, 4'd0} + {blue, 3'd0} + {blue, 2'd0} + blue; + pb_1b <= {blue, 7'd0}; + pr_1b <= {blue, 4'd0} + {blue, 2'd0} + blue; + + y_2 <= y_1r + y_1g + y_1b; + pb_2 <= pb_1r - pb_1g + pb_1b; + pr_2 <= pr_1r - pr_1g - pr_1b; + + y <= y_2[18] ? 8'd0 : y_2[16] ? 8'd255 : y_2[15:8]; + pb <= pb_2[18] ? 8'd0 : pb_2[16] ? 8'd255 : pb_2[15:8]; + pr <= pr_2[18] ? 8'd0 : pr_2[16] ? 8'd255 : pr_2[15:8]; + + hsync_o <= hsync2; hsync2 <= hsync1; hsync1 <= hsync; + vsync_o <= vsync2; vsync2 <= vsync1; vsync1 <= vsync; + csync_o <= csync2; csync2 <= csync1; csync1 <= csync; + de_o <= de2; de2 <= de1; de1 <= de; + + rgb <= din2; din2 <= din1; din1 <= din; +end + +assign dout = ypbpr_en ? {pr[7:0], y[7:0], pb[7:0]} : rgb; //reduced to 6bits per component + +endmodule \ No newline at end of file diff --git a/target/pocket/analogizer/yc_out.sv b/target/pocket/analogizer/yc_out.sv new file mode 100644 index 0000000..653ae75 --- /dev/null +++ b/target/pocket/analogizer/yc_out.sv @@ -0,0 +1,275 @@ +//============================================================================ +// YC - Luma / Chroma Generation +// Copyright (C) 2022 Mike Simone +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +//============================================================================ +/* +Colorspace +Y 0.299R' + 0.587G' + 0.114B' +U 0.492(B' - Y) = 504 (X 1024) +V 0.877(R' - Y) = 898 (X 1024) +*/ +////////////////////////////////////////////////////////// + +module yc_out +( + input clk, + input [39:0] PHASE_INC, + input PAL_EN, + + input hsync, + input vsync, + input csync, + + input [17:0] din, + output [15:0] dout, + + output reg hsync_o, + output reg vsync_o, + output reg csync_o +); + +wire [7:0] red = {din[17:12],2'b00}; +wire [7:0] green = {din[11:6],2'b00}; +wire [7:0] blue = {din[5:0],2'b00}; + +logic [9:0] red_1, blue_1, green_1, red_2, blue_2, green_2; + +logic signed [20:0] yr = 0, yb = 0, yg = 0; + +typedef struct { + logic signed [20:0] y; + logic signed [20:0] c; + logic signed [20:0] u; + logic signed [20:0] v; + logic hsync; + logic vsync; + logic csync; +} phase_t; + +localparam MAX_PHASES = 7'd8; + +phase_t phase[MAX_PHASES]; +reg unsigned [7:0] c, U, V; +reg unsigned [7:0] Y, C; + +reg [10:0] cburst_phase, cburst_length, cburst_start; // colorburst counter +reg unsigned [7:0] vref = 'd128; // Voltage reference point (Used for Chroma) +logic [7:0] chroma_LUT_COS; // Chroma cos LUT reference +logic [7:0] chroma_LUT_SIN; // Chroma sin LUT reference +logic [7:0] chroma_LUT_BURST; // Chroma colorburst LUT reference +logic [7:0] chroma_LUT = 8'd0; + +/* +THe following LUT table was calculated by Sin(2*pi*t/2^8) where t: 0 - 255 +*/ + +/************************************* + 8 bit Sine look up Table +**************************************/ +wire signed [10:0] chroma_SIN_LUT[256] = '{ +11'h000, 11'h006, 11'h00C, 11'h012, 11'h018, 11'h01F, 11'h025, 11'h02B, 11'h031, 11'h037, 11'h03D, 11'h044, 11'h04A, 11'h04F, +11'h055, 11'h05B, 11'h061, 11'h067, 11'h06D, 11'h072, 11'h078, 11'h07D, 11'h083, 11'h088, 11'h08D, 11'h092, 11'h097, 11'h09C, +11'h0A1, 11'h0A6, 11'h0AB, 11'h0AF, 11'h0B4, 11'h0B8, 11'h0BC, 11'h0C1, 11'h0C5, 11'h0C9, 11'h0CC, 11'h0D0, 11'h0D4, 11'h0D7, +11'h0DA, 11'h0DD, 11'h0E0, 11'h0E3, 11'h0E6, 11'h0E9, 11'h0EB, 11'h0ED, 11'h0F0, 11'h0F2, 11'h0F4, 11'h0F5, 11'h0F7, 11'h0F8, +11'h0FA, 11'h0FB, 11'h0FC, 11'h0FD, 11'h0FD, 11'h0FE, 11'h0FE, 11'h0FE, 11'h0FF, 11'h0FE, 11'h0FE, 11'h0FE, 11'h0FD, 11'h0FD, +11'h0FC, 11'h0FB, 11'h0FA, 11'h0F8, 11'h0F7, 11'h0F5, 11'h0F4, 11'h0F2, 11'h0F0, 11'h0ED, 11'h0EB, 11'h0E9, 11'h0E6, 11'h0E3, +11'h0E0, 11'h0DD, 11'h0DA, 11'h0D7, 11'h0D4, 11'h0D0, 11'h0CC, 11'h0C9, 11'h0C5, 11'h0C1, 11'h0BC, 11'h0B8, 11'h0B4, 11'h0AF, +11'h0AB, 11'h0A6, 11'h0A1, 11'h09C, 11'h097, 11'h092, 11'h08D, 11'h088, 11'h083, 11'h07D, 11'h078, 11'h072, 11'h06D, 11'h067, +11'h061, 11'h05B, 11'h055, 11'h04F, 11'h04A, 11'h044, 11'h03D, 11'h037, 11'h031, 11'h02B, 11'h025, 11'h01F, 11'h018, 11'h012, +11'h00C, 11'h006, 11'h000, 11'h7F9, 11'h7F3, 11'h7ED, 11'h7E7, 11'h7E0, 11'h7DA, 11'h7D4, 11'h7CE, 11'h7C8, 11'h7C2, 11'h7BB, +11'h7B5, 11'h7B0, 11'h7AA, 11'h7A4, 11'h79E, 11'h798, 11'h792, 11'h78D, 11'h787, 11'h782, 11'h77C, 11'h777, 11'h772, 11'h76D, +11'h768, 11'h763, 11'h75E, 11'h759, 11'h754, 11'h750, 11'h74B, 11'h747, 11'h743, 11'h73E, 11'h73A, 11'h736, 11'h733, 11'h72F, +11'h72B, 11'h728, 11'h725, 11'h722, 11'h71F, 11'h71C, 11'h719, 11'h716, 11'h714, 11'h712, 11'h70F, 11'h70D, 11'h70B, 11'h70A, +11'h708, 11'h707, 11'h705, 11'h704, 11'h703, 11'h702, 11'h702, 11'h701, 11'h701, 11'h701, 11'h701, 11'h701, 11'h701, 11'h701, +11'h702, 11'h702, 11'h703, 11'h704, 11'h705, 11'h707, 11'h708, 11'h70A, 11'h70B, 11'h70D, 11'h70F, 11'h712, 11'h714, 11'h716, +11'h719, 11'h71C, 11'h71F, 11'h722, 11'h725, 11'h728, 11'h72B, 11'h72F, 11'h733, 11'h736, 11'h73A, 11'h73E, 11'h743, 11'h747, +11'h74B, 11'h750, 11'h754, 11'h759, 11'h75E, 11'h763, 11'h768, 11'h76D, 11'h772, 11'h777, 11'h77C, 11'h782, 11'h787, 11'h78D, +11'h792, 11'h798, 11'h79E, 11'h7A4, 11'h7AA, 11'h7B0, 11'h7B5, 11'h7BB, 11'h7C2, 11'h7C8, 11'h7CE, 11'h7D4, 11'h7DA, 11'h7E0, +11'h7E7, 11'h7ED, 11'h7F3, 11'h7F9 +}; + +// reg signed [10:0] chroma_SIN_LUT[0:255] /* synthesis ramstyle = "M10K" */; +// initial begin +// $readmemh("sine_lut.mem", chroma_SIN_LUT); +// end + +// reg signed [10:0] chroma_SIN_LUT2[0:255] /* synthesis ramstyle = "M10K" */; +// initial begin +// $readmemh("sine_lut.mem", chroma_SIN_LUT2); +// end + +logic [39:0] phase_accum; +logic PAL_FLIP = 1'd0; +logic PAL_line_count = 1'd0; + +/************************************** + Generate Luma and Chroma Signals +***************************************/ + +always_ff @(posedge clk) begin + for (logic [3:0] x = 0; x < (MAX_PHASES - 1'd1); x = x + 1'd1) begin + phase[x + 1] <= phase[x]; + end + + // Color Averaging to help with color accuracy + red_1 <= red; + blue_1 <= blue; + red_2 <= red_1; + blue_2 <= blue_1; + + // Calculate Luma signal + + yr <= {red, 8'd0} + {red, 5'd0}+ {red, 4'd0} + {red, 1'd0}; + yg <= {green, 9'd0} + {green, 6'd0} + {green, 4'd0} + {green, 3'd0} + green; + yb <= {blue, 6'd0} + {blue, 5'd0} + {blue, 4'd0} + {blue, 2'd0} + blue; + phase[0].y <= yr + yg + yb; + + // Generate the LUT values using the phase accumulator reference. + phase_accum <= phase_accum + PHASE_INC; + chroma_LUT <= phase_accum[39:32]; + + // Adjust SINE carrier reference for PAL (Also adjust for PAL Switch) + if (PAL_EN) begin + if (PAL_FLIP) + chroma_LUT_BURST <= chroma_LUT + 8'd160; + else + chroma_LUT_BURST <= chroma_LUT + 8'd96; + end else // Adjust SINE carrier reference for NTSC + chroma_LUT_BURST <= chroma_LUT + 8'd128; + + // Prepare LUT values for sin / cos (+90 degress) + chroma_LUT_SIN <= chroma_LUT; + chroma_LUT_COS <= chroma_LUT + 8'd64; + + // Calculate for U, V - Bit Shift Multiple by u = by * 1024 x 0.492 = 504, v = ry * 1024 x 0.877 = 898 + phase[0].u <= $signed({2'b0 ,(blue_2)}) - $signed({2'b0 ,phase[0].y[17:10]}); + phase[0].v <= $signed({2'b0 ,(red_2)}) - $signed({2'b0 ,phase[0].y[17:10]}); + phase[1].u <= $signed({phase[0].u, 8'd0}) + $signed({phase[0].u, 7'd0}) + $signed({phase[0].u, 6'd0}) + $signed({phase[0].u, 5'd0}) + $signed({phase[0].u, 4'd0}) + $signed({phase[0].u, 3'd0}) ; + phase[1].v <= $signed({phase[0].v, 9'd0}) + $signed({phase[0].v, 8'd0}) + $signed({phase[0].v, 7'd0}) + $signed({phase[0].v, 1'd0}); + + phase[0].c <= vref; + phase[1].c <= phase[0].c; + phase[2].c <= phase[1].c; + phase[3].c <= phase[2].c; + + // Set Colorburst Length Based on Phase_Accum + // Since the colorburst length depends on the video clock freqency, this just sets the approprate count length to match the colorburst lengths closer to 9/10 cycles for NTSC/PAL. + + if (PHASE_INC[39:32] > (PAL_EN ? 8'd56 : 8'd45)) begin + cburst_length <= PAL_EN ? 10'd85 : 10'd90; + cburst_start <= 10'd40; + end else if (PHASE_INC[39:32] > (PAL_EN ? 8'd37 : 8'd30)) begin + cburst_length <= PAL_EN ? 10'd108 : 10'd115; + cburst_start <= 10'd40; + end else if (PHASE_INC[39:32] > (PAL_EN ? 8'd28 : 8'd22)) begin + cburst_length <= PAL_EN ? 10'd130 : 10'd141; + cburst_start <= 10'd40; + end else if (PHASE_INC[39:32] > (PAL_EN ? 8'd18 : 8'd15)) begin + cburst_length <= PAL_EN ? 10'd173 : 10'd186; + cburst_start <= 10'd60; + end else if (PHASE_INC[39:32] > (PAL_EN ? 8'd16 : 8'd13)) begin + cburst_length <= PAL_EN ? 10'd195 : 10'd211; + cburst_start <= 10'd60; + end else if (PHASE_INC[39:32] > (PAL_EN ? 8'd14 : 8'd11)) begin + cburst_length <= PAL_EN ? 10'd258 : 10'd276; + cburst_start <= 10'd100; + end else if (PHASE_INC[39:32] > (PAL_EN ? 8'd12 : 8'd10)) begin + cburst_length <= PAL_EN ? 10'd281 : 10'd301; + cburst_start <= 10'd100; + end else if (PHASE_INC[39:32] > (PAL_EN ? 8'd11 : 8'd9)) begin + cburst_length <= PAL_EN ? 10'd323 : 10'd346; + cburst_start <= 10'd120; + end else if (PHASE_INC[39:32] > (PAL_EN ? 8'd10 : 8'd8)) begin + cburst_length <= PAL_EN ? 10'd346 : 10'd371; + cburst_start <= 10'd120; + end else if (PHASE_INC[39:32] > (PAL_EN ? 8'd9 : 8'd7)) begin + cburst_length <= PAL_EN ? 10'd368 : 10'd397; + cburst_start <= 10'd120; + end else begin + cburst_length <= PAL_EN ? 10'd391 : 10'd422; + cburst_start <= 10'd120; + end + + if (hsync) begin // Reset colorburst counter, as well as the calculated cos / sin values. + cburst_phase <= 'd0; + phase[2].u <= 21'b0; + phase[2].v <= 21'b0; + phase[4].c <= phase[3].c; + + if (PAL_line_count) begin + PAL_FLIP <= ~PAL_FLIP; + PAL_line_count <= ~PAL_line_count; + end + end else begin // Generate Colorburst for 9 cycles + if (cburst_phase >= cburst_start && cburst_phase <= cburst_length) begin // Start the color burst signal at 40 samples or 0.9 us + // COLORBURST SIGNAL GENERATION (9 CYCLES ONLY or between count 40 - 240) + phase[2].u <= $signed({chroma_SIN_LUT[chroma_LUT_BURST],5'd0}); + phase[2].v <= 21'b0; + + // Division to scale down the results to fit 8 bit. + if (PAL_EN) + phase[3].u <= $signed(phase[2].u[20:8]) + $signed(phase[2].u[20:10]) + $signed(phase[2].u[20:14]); + else + phase[3].u <= $signed(phase[2].u[20:8]) + $signed(phase[2].u[20:11]) + $signed(phase[2].u[20:12]) + $signed(phase[2].u[20:13]); + + phase[3].v <= phase[2].v; + end else if (cburst_phase > cburst_length) begin // MODULATE U, V for chroma + /* + U,V are both multiplied by 1024 earlier to scale for the decimals in the YUV colorspace conversion. + U and V are both divided by 2^10 which introduce chroma subsampling of 4:1:1 (25% or from 8 bit to 6 bit) + */ + phase[2].u <= $signed((phase[1].u)>>>10) * $signed(chroma_SIN_LUT[chroma_LUT_SIN]); + phase[2].v <= $signed((phase[1].v)>>>10) * $signed(chroma_SIN_LUT[chroma_LUT_COS]); + + // Divide U*sin(wt) and V*cos(wt) to fit results to 8 bit + phase[3].u <= $signed(phase[2].u[20:9]) + $signed(phase[2].u[20:10]) + $signed(phase[2].u[20:14]); + phase[3].v <= $signed(phase[2].v[20:9]) + $signed(phase[2].v[20:10]) + $signed(phase[2].u[20:14]); + end + + // Stop the colorburst timer as its only needed for the initial pulse + if (cburst_phase <= 'd400) + cburst_phase <= cburst_phase + 9'd1; + + // Calculate for chroma (Note: "PAL SWITCH" routine flips V * COS(Wt) every other line) + if (PAL_EN) begin + if (PAL_FLIP) + phase[4].c <= vref + phase[3].u - phase[3].v; + else + phase[4].c <= vref + phase[3].u + phase[3].v; + PAL_line_count <= 1'd1; + end else + phase[4].c <= vref + phase[3].u + phase[3].v; + + end + // Adjust sync timing correctly + phase[1].hsync <= hsync; phase[1].vsync <= vsync; phase[1].csync <= csync; + phase[2].hsync <= phase[1].hsync; phase[2].vsync <= phase[1].vsync; phase[2].csync <= phase[1].csync; + phase[3].hsync <= phase[2].hsync; phase[3].vsync <= phase[2].vsync; phase[3].csync <= phase[2].csync; + phase[4].hsync <= phase[3].hsync; phase[4].vsync <= phase[3].vsync; phase[4].csync <= phase[3].csync; + hsync_o <= phase[4].hsync; vsync_o <= phase[4].vsync; csync_o <= phase[4].csync; + phase[1].y <= phase[0].y; phase[2].y <= phase[1].y; phase[3].y <= phase[2].y; phase[4].y <= phase[3].y; phase[5].y <= phase[4].y; + + // Set Chroma / Luma output + //reduce to 6 bits + C <= phase[4].c[7:0]; + Y <= phase[5].y[17:10]; +end + +assign dout = {C, Y}; + +endmodule diff --git a/target/pocket/analogizer/yc_out_legacy.sv b/target/pocket/analogizer/yc_out_legacy.sv new file mode 100644 index 0000000..0b85aeb --- /dev/null +++ b/target/pocket/analogizer/yc_out_legacy.sv @@ -0,0 +1,239 @@ +//============================================================================ +// YC - Luma / Chroma Generation +// Copyright (C) 2022 Mike Simone +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +//============================================================================ +/* +Colorspace +Y 0.299R' + 0.587G' + 0.114B' +U 0.492(B' - Y) = 504 (X 1024) +V 0.877(R' - Y) = 898 (X 1024) +*/ +////////////////////////////////////////////////////////// + +module yc_out_legacy +( + input clk, + input [39:0] PHASE_INC, + input PAL_EN, + input [26:0] COLORBURST_RANGE, + + // Phase Accumunulator tuning variables used only during core development + input [4:0] CHRADD, + input [4:0] CHRMUL, + input MULFLAG, + + input hsync, + input vsync, + input csync, + + input [23:0] din, + output [23:0] dout, + + output reg hsync_o, + output reg vsync_o, + output reg csync_o +); +wire [4:0] chradd = CHRADD; +wire [4:0] chrmul = CHRMUL; + + +wire [7:0] red = din[23:16]; +wire [7:0] green = din[15:8]; +wire [7:0] blue = din[7:0]; + +logic [9:0] red_1, blue_1, green_1, red_2, blue_2, green_2; + +logic signed [20:0] yr = 0, yb = 0, yg = 0; + +typedef struct { + logic signed [20:0] y; + logic signed [20:0] c; + logic signed [20:0] u; + logic signed [20:0] v; + logic hsync; + logic vsync; + logic csync; +} phase_t; + +localparam MAX_PHASES = 7'd8; + +phase_t phase[MAX_PHASES]; +reg unsigned [7:0] Y, C, c, U, V; + + +reg [10:0] cburst_phase, cburst_length, cburst_start; // colorburst counter +reg unsigned [7:0] vref = 'd128; // Voltage reference point (Used for Chroma) +logic [7:0] chroma_LUT_COS; // Chroma cos LUT reference +logic [7:0] chroma_LUT_SIN; // Chroma sin LUT reference +logic [7:0] chroma_LUT_BURST; // Chroma colorburst LUT reference +logic [7:0] chroma_LUT = 8'd0; + +/* +THe following LUT table was calculated by Sin(2*pi*t/2^8) where t: 0 - 255 +*/ + +/************************************* + 8 bit Sine look up Table +**************************************/ +wire signed [10:0] chroma_SIN_LUT[256] = '{ +11'h000, 11'h006, 11'h00C, 11'h012, 11'h018, 11'h01F, 11'h025, 11'h02B, 11'h031, 11'h037, 11'h03D, 11'h044, 11'h04A, 11'h04F, +11'h055, 11'h05B, 11'h061, 11'h067, 11'h06D, 11'h072, 11'h078, 11'h07D, 11'h083, 11'h088, 11'h08D, 11'h092, 11'h097, 11'h09C, +11'h0A1, 11'h0A6, 11'h0AB, 11'h0AF, 11'h0B4, 11'h0B8, 11'h0BC, 11'h0C1, 11'h0C5, 11'h0C9, 11'h0CC, 11'h0D0, 11'h0D4, 11'h0D7, +11'h0DA, 11'h0DD, 11'h0E0, 11'h0E3, 11'h0E6, 11'h0E9, 11'h0EB, 11'h0ED, 11'h0F0, 11'h0F2, 11'h0F4, 11'h0F5, 11'h0F7, 11'h0F8, +11'h0FA, 11'h0FB, 11'h0FC, 11'h0FD, 11'h0FD, 11'h0FE, 11'h0FE, 11'h0FE, 11'h0FF, 11'h0FE, 11'h0FE, 11'h0FE, 11'h0FD, 11'h0FD, +11'h0FC, 11'h0FB, 11'h0FA, 11'h0F8, 11'h0F7, 11'h0F5, 11'h0F4, 11'h0F2, 11'h0F0, 11'h0ED, 11'h0EB, 11'h0E9, 11'h0E6, 11'h0E3, +11'h0E0, 11'h0DD, 11'h0DA, 11'h0D7, 11'h0D4, 11'h0D0, 11'h0CC, 11'h0C9, 11'h0C5, 11'h0C1, 11'h0BC, 11'h0B8, 11'h0B4, 11'h0AF, +11'h0AB, 11'h0A6, 11'h0A1, 11'h09C, 11'h097, 11'h092, 11'h08D, 11'h088, 11'h083, 11'h07D, 11'h078, 11'h072, 11'h06D, 11'h067, +11'h061, 11'h05B, 11'h055, 11'h04F, 11'h04A, 11'h044, 11'h03D, 11'h037, 11'h031, 11'h02B, 11'h025, 11'h01F, 11'h018, 11'h012, +11'h00C, 11'h006, 11'h000, 11'h7F9, 11'h7F3, 11'h7ED, 11'h7E7, 11'h7E0, 11'h7DA, 11'h7D4, 11'h7CE, 11'h7C8, 11'h7C2, 11'h7BB, +11'h7B5, 11'h7B0, 11'h7AA, 11'h7A4, 11'h79E, 11'h798, 11'h792, 11'h78D, 11'h787, 11'h782, 11'h77C, 11'h777, 11'h772, 11'h76D, +11'h768, 11'h763, 11'h75E, 11'h759, 11'h754, 11'h750, 11'h74B, 11'h747, 11'h743, 11'h73E, 11'h73A, 11'h736, 11'h733, 11'h72F, +11'h72B, 11'h728, 11'h725, 11'h722, 11'h71F, 11'h71C, 11'h719, 11'h716, 11'h714, 11'h712, 11'h70F, 11'h70D, 11'h70B, 11'h70A, +11'h708, 11'h707, 11'h705, 11'h704, 11'h703, 11'h702, 11'h702, 11'h701, 11'h701, 11'h701, 11'h701, 11'h701, 11'h701, 11'h701, +11'h702, 11'h702, 11'h703, 11'h704, 11'h705, 11'h707, 11'h708, 11'h70A, 11'h70B, 11'h70D, 11'h70F, 11'h712, 11'h714, 11'h716, +11'h719, 11'h71C, 11'h71F, 11'h722, 11'h725, 11'h728, 11'h72B, 11'h72F, 11'h733, 11'h736, 11'h73A, 11'h73E, 11'h743, 11'h747, +11'h74B, 11'h750, 11'h754, 11'h759, 11'h75E, 11'h763, 11'h768, 11'h76D, 11'h772, 11'h777, 11'h77C, 11'h782, 11'h787, 11'h78D, +11'h792, 11'h798, 11'h79E, 11'h7A4, 11'h7AA, 11'h7B0, 11'h7B5, 11'h7BB, 11'h7C2, 11'h7C8, 11'h7CE, 11'h7D4, 11'h7DA, 11'h7E0, +11'h7E7, 11'h7ED, 11'h7F3, 11'h7F9 +}; + +logic [39:0] phase_accum; +logic PAL_FLIP = 1'd0; +logic PAL_line_count = 1'd0; + +/************************************** + Generate Luma and Chroma Signals +***************************************/ + +always_ff @(posedge clk) begin + for (logic [3:0] x = 0; x < (MAX_PHASES - 1'd1); x = x + 1'd1) begin + phase[x + 1] <= phase[x]; + end + + // Color Averaging to help with color accuracy + red_1 <= red; + blue_1 <= blue; + red_2 <= red_1; + blue_2 <= blue_1; + + // Calculate Luma signal + + yr <= {red, 8'd0} + {red, 5'd0}+ {red, 4'd0} + {red, 1'd0}; + yg <= {green, 9'd0} + {green, 6'd0} + {green, 4'd0} + {green, 3'd0} + green; + yb <= {blue, 6'd0} + {blue, 5'd0} + {blue, 4'd0} + {blue, 2'd0} + blue; + phase[0].y <= yr + yg + yb; + + // Generate the LUT values using the phase accumulator reference. + if (~MULFLAG) + phase_accum <= phase_accum + PHASE_INC + (chradd<= COLORBURST_RANGE[26:20] && cburst_phase <= (PAL_EN ? COLORBURST_RANGE[9:0] : COLORBURST_RANGE[19:10])) begin // Start the color burst signal at 40 samples or 0.9 us + // COLORBURST SIGNAL GENERATION (9 CYCLES ONLY or between count 40 - 240) + phase[2].u <= $signed({chroma_SIN_LUT[chroma_LUT_BURST],5'd0}); + phase[2].v <= 21'b0; + + // Division to scale down the results to fit 8 bit. + if (PAL_EN) + phase[3].u <= $signed(phase[2].u[20:8]) + $signed(phase[2].u[20:10]) + $signed(phase[2].u[20:14]); + else + phase[3].u <= $signed(phase[2].u[20:8]) + $signed(phase[2].u[20:11]) + $signed(phase[2].u[20:12]) + $signed(phase[2].u[20:13]); + + phase[3].v <= phase[2].v; + end else if (cburst_phase > cburst_length) begin // MODULATE U, V for chroma + /* + U,V are both multiplied by 1024 earlier to scale for the decimals in the YUV colorspace conversion. + U and V are both divided by 2^10 which introduce chroma subsampling of 4:1:1 (25% or from 8 bit to 6 bit) + */ + phase[2].u <= $signed((phase[1].u)>>>10) * $signed(chroma_SIN_LUT[chroma_LUT_SIN]); + phase[2].v <= $signed((phase[1].v)>>>10) * $signed(chroma_SIN_LUT[chroma_LUT_COS]); + + // Divide U*sin(wt) and V*cos(wt) to fit results to 8 bit + phase[3].u <= $signed(phase[2].u[20:9]) + $signed(phase[2].u[20:10]) + $signed(phase[2].u[20:14]); + phase[3].v <= $signed(phase[2].v[20:9]) + $signed(phase[2].v[20:10]) + $signed(phase[2].u[20:14]); + end + + // Stop the colorburst timer as its only needed for the initial pulse + if (cburst_phase <= (PAL_EN ? COLORBURST_RANGE[9:0] : COLORBURST_RANGE[19:10])) + cburst_phase <= cburst_phase + 9'd1; + + // Calculate for chroma (Note: "PAL SWITCH" routine flips V * COS(Wt) every other line) + if (PAL_EN) begin + if (PAL_FLIP) + phase[4].c <= vref + phase[3].u - phase[3].v; + else + phase[4].c <= vref + phase[3].u + phase[3].v; + PAL_line_count <= 1'd1; + end else + phase[4].c <= vref + phase[3].u + phase[3].v; + + end + // Adjust sync timing correctly + phase[1].hsync <= hsync; phase[1].vsync <= vsync; phase[1].csync <= csync; + phase[2].hsync <= phase[1].hsync; phase[2].vsync <= phase[1].vsync; phase[2].csync <= phase[1].csync; + phase[3].hsync <= phase[2].hsync; phase[3].vsync <= phase[2].vsync; phase[3].csync <= phase[2].csync; + phase[4].hsync <= phase[3].hsync; phase[4].vsync <= phase[3].vsync; phase[4].csync <= phase[3].csync; + hsync_o <= phase[4].hsync; vsync_o <= phase[4].vsync; csync_o <= phase[4].csync; + phase[1].y <= phase[0].y; phase[2].y <= phase[1].y; phase[3].y <= phase[2].y; phase[4].y <= phase[3].y; phase[5].y <= phase[4].y; + + // Set Chroma / Luma output + C <= phase[4].c[7:0]; + Y <= phase[5].y[17:10]; +end + +assign dout = {C, Y, 8'd0}; + +endmodule + diff --git a/target/pocket/core.qip b/target/pocket/core.qip index 97ce120..07c9923 100644 --- a/target/pocket/core.qip +++ b/target/pocket/core.qip @@ -1,5 +1,5 @@ -# ============================================================================== -# Quartus Prime QIP Index File -# ============================================================================== -set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "core_top.sv"] -set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "core_pll/core_pll.qip"] +# ============================================================================== +# Quartus Prime QIP Index File +# ============================================================================== +set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "core_top.sv"] +set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "core_pll/core_pll.qip"] diff --git a/target/pocket/core_pll/core_pll.ppf b/target/pocket/core_pll/core_pll.ppf index b84dd7a..ee660fa 100644 --- a/target/pocket/core_pll/core_pll.ppf +++ b/target/pocket/core_pll/core_pll.ppf @@ -1,16 +1,16 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/target/pocket/core_pll/core_pll.qip b/target/pocket/core_pll/core_pll.qip index dfb2393..35f9605 100644 --- a/target/pocket/core_pll/core_pll.qip +++ b/target/pocket/core_pll/core_pll.qip @@ -1,337 +1,337 @@ -set_global_assignment -entity "core_pll" -library "core_pll" -name IP_TOOL_NAME "altera_pll" -set_global_assignment -entity "core_pll" -library "core_pll" -name IP_TOOL_VERSION "17.1" -set_global_assignment -entity "core_pll" -library "core_pll" -name IP_TOOL_ENV "mwpim" -set_global_assignment -library "core_pll" -name MISC_FILE [file join $::quartus(qip_path) "core_pll.cmp"] -set_global_assignment -entity "core_pll" -library "core_pll" -name IP_TARGETED_DEVICE_FAMILY "Cyclone V" -set_global_assignment -entity "core_pll" -library "core_pll" -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" -set_global_assignment -entity "core_pll" -library "core_pll" -name IP_QSYS_MODE "UNKNOWN" -set_global_assignment -name SYNTHESIS_ONLY_QIP ON -set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_NAME "Y29yZV9wbGw=" -set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTA==" -set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_REPORT_HIERARCHY "Off" -set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_INTERNAL "Off" -set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" -set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_VERSION "MTcuMQ==" -set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIChBTFRFUkFfUExMKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_NAME "Y29yZV9wbGxfMDAwMg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTA==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_REPORT_HIERARCHY "Off" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_INTERNAL "Off" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_VERSION "MTcuMQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIChBTFRFUkFfUExMKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZGVidWdfcHJpbnRfb3V0cHV0::ZmFsc2U=::ZGVidWdfcHJpbnRfb3V0cHV0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZGVidWdfdXNlX3JiY190YWZfbWV0aG9k::ZmFsc2U=::ZGVidWdfdXNlX3JiY190YWZfbWV0aG9k" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZGV2aWNl::NUNFQkEyRjE3QTc=::ZGV2aWNl" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9tb2Rl::RnJhY3Rpb25hbC1OIFBMTA==::UExMIE1vZGU=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZnJhY3Rpb25hbF92Y29fbXVsdGlwbGllcg==::dHJ1ZQ==::ZnJhY3Rpb25hbF92Y29fbXVsdGlwbGllcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3JlZmVyZW5jZV9jbG9ja19mcmVxdWVuY3k=::NzQuMjU=::UmVmZXJlbmNlIENsb2NrIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cmVmZXJlbmNlX2Nsb2NrX2ZyZXF1ZW5jeQ==::NzQuMjUgTUh6::cmVmZXJlbmNlX2Nsb2NrX2ZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2NoYW5uZWxfc3BhY2luZw==::MC4w::Q2hhbm5lbCBTcGFjaW5n" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX29wZXJhdGlvbl9tb2Rl::ZGlyZWN0::T3BlcmF0aW9uIE1vZGU=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZlZWRiYWNrX2Nsb2Nr::R2xvYmFsIENsb2Nr::RmVlZGJhY2sgQ2xvY2s=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWN0aW9uYWxfY291dA==::MzI=::RnJhY3Rpb25hbCBjYXJyeSBvdXQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RzbV9vdXRfc2Vs::MXN0X29yZGVy::RFNNIE9yZGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3BlcmF0aW9uX21vZGU=::ZGlyZWN0::b3BlcmF0aW9uX21vZGU=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9sb2NrZWQ=::dHJ1ZQ==::RW5hYmxlIGxvY2tlZCBvdXRwdXQgcG9ydA==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Fkdl9wYXJhbXM=::ZmFsc2U=::RW5hYmxlIHBoeXNpY2FsIG91dHB1dCBjbG9jayBwYXJhbWV0ZXJz" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX251bWJlcl9vZl9jbG9ja3M=::NA==::TnVtYmVyIE9mIENsb2Nrcw==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "bnVtYmVyX29mX2Nsb2Nrcw==::NA==::bnVtYmVyX29mX2Nsb2Nrcw==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX211bHRpcGx5X2ZhY3Rvcg==::MQ==::TXVsdGlwbHkgRmFjdG9yIChNLUNvdW50ZXIp" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWNfbXVsdGlwbHlfZmFjdG9y::MQ==::RnJhY3Rpb25hbCBNdWx0aXBseSBGYWN0b3IgKEsp" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3Jfbg==::MQ==::RGl2aWRlIEZhY3RvciAoTi1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjA=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kw::NDIuOTU0NTM2::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzA=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iw::OA==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjA=::NDI1OTM5NDU1::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMA==::MTQ=::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MA==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzA=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDA=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUw::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kx::NS4zNjkzMTc=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Ix::OA==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE=::NDI1OTM5NDU1::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMQ==::MTEy::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MQ==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUx::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjI=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3ky::NS4zNjkzMTc=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzI=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iy::OA==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjI=::NDI1OTM5NDU1::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMg==::MTEy::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mg==::NS45NTI3NTUgTUh6::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMg==::ZGVncmVlcw==::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mg==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzI=::OTAuMA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDI=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUy::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjM=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kz::ODUuOTA5MDcy::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzM=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iz::OA==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjM=::NDI1OTM5NDU1::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMw==::Nw==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mw==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMw==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mw==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzM=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDM=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUz::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjQ=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k0::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzQ=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I0::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjQ=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNA==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5NA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0NA==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzQ=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDQ=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU0::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjU=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k1::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzU=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I1::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjU=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNQ==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5NQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0NQ==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzU=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDU=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU1::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjY=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k2::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzY=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I2::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjY=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNg==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Ng==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNg==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Ng==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzY=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDY=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU2::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjc=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k3::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzc=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I3::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjc=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNw==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Nw==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNw==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Nw==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzc=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDc=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU3::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjg=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k4::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzg=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I4::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjg=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yOA==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5OA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzOA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0OA==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzg=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDg=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU4::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjk=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k5::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzk=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I5::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjk=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yOQ==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5OQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzOQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0OQ==::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzk=::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDk=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU5::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEw::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMA==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEw::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMA==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEw::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTA=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTA=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTA=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTA=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEw::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEw::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMA==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEx::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMQ==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEx::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMQ==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEx::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTE=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTE=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTE=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTE=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEx::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEx::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMQ==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEy::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMg==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEy::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMg==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEy::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTI=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTI=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTI=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTI=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEy::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEy::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMg==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEz::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMw==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEz::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMw==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEz::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTM=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTM=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTM=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTM=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEz::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEz::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMw==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE0::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNA==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE0::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNA==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE0::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTQ=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTQ=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTQ=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTQ=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE0::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE0::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNA==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE1::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNQ==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE1::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNQ==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE1::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTU=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTU=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTU=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTU=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE1::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE1::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNQ==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE2::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNg==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE2::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNg==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE2::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTY=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTY=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTY=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTY=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE2::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE2::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNg==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE3::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNw==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE3::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNw==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE3::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTc=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTc=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTc=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTc=::MA==::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE3::MC4w::UGhhc2UgU2hpZnQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE3::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNw==::NTA=::RHV0eSBDeWNsZQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA=::NDIuOTU0NTM2IE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQw::MCBwcw==::cGhhc2Vfc2hpZnQw" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTA=::NTA=::ZHV0eV9jeWNsZTA=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=::NS4zNjkzMTcgTUh6::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQx::MCBwcw==::cGhhc2Vfc2hpZnQx" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE=::NTA=::ZHV0eV9jeWNsZTE=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=::NS4zNjkzMTcgTUh6::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQy::NDY1NjEgcHM=::cGhhc2Vfc2hpZnQy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTI=::NTA=::ZHV0eV9jeWNsZTI=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=::ODUuOTA5MDcyIE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQz::MCBwcw==::cGhhc2Vfc2hpZnQz" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTM=::NTA=::ZHV0eV9jeWNsZTM=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ0::MCBwcw==::cGhhc2Vfc2hpZnQ0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTQ=::NTA=::ZHV0eV9jeWNsZTQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ1::MCBwcw==::cGhhc2Vfc2hpZnQ1" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTU=::NTA=::ZHV0eV9jeWNsZTU=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTY=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTY=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ2::MCBwcw==::cGhhc2Vfc2hpZnQ2" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTY=::NTA=::ZHV0eV9jeWNsZTY=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTc=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTc=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ3::MCBwcw==::cGhhc2Vfc2hpZnQ3" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTc=::NTA=::ZHV0eV9jeWNsZTc=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTg=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTg=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ4::MCBwcw==::cGhhc2Vfc2hpZnQ4" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTg=::NTA=::ZHV0eV9jeWNsZTg=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTk=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTk=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ5::MCBwcw==::cGhhc2Vfc2hpZnQ5" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTk=::NTA=::ZHV0eV9jeWNsZTk=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEw::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEw" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMA==::MCBwcw==::cGhhc2Vfc2hpZnQxMA==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEw::NTA=::ZHV0eV9jeWNsZTEw" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEx::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEx" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMQ==::MCBwcw==::cGhhc2Vfc2hpZnQxMQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEx::NTA=::ZHV0eV9jeWNsZTEx" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEy::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMg==::MCBwcw==::cGhhc2Vfc2hpZnQxMg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEy::NTA=::ZHV0eV9jeWNsZTEy" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEz::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEz" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMw==::MCBwcw==::cGhhc2Vfc2hpZnQxMw==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEz::NTA=::ZHV0eV9jeWNsZTEz" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE0::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNA==::MCBwcw==::cGhhc2Vfc2hpZnQxNA==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE0::NTA=::ZHV0eV9jeWNsZTE0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE1::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE1" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNQ==::MCBwcw==::cGhhc2Vfc2hpZnQxNQ==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE1::NTA=::ZHV0eV9jeWNsZTE1" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE2::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE2" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNg==::MCBwcw==::cGhhc2Vfc2hpZnQxNg==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE2::NTA=::ZHV0eV9jeWNsZTE2" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE3::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE3" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNw==::MCBwcw==::cGhhc2Vfc2hpZnQxNw==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE3::NTA=::ZHV0eV9jeWNsZTE3" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9hdXRvX3Jlc2V0::T2Zm::UExMIEF1dG8gUmVzZXQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9iYW5kd2lkdGhfcHJlc2V0::QXV0bw==::UExMIEJhbmR3aWR0aCBQcmVzZXQ=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX3JlY29uZg==::ZmFsc2U=::RW5hYmxlIGR5bmFtaWMgcmVjb25maWd1cmF0aW9uIG9mIFBMTA==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Rwc19wb3J0cw==::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBkeW5hbWljIHBoYXNlIHNoaWZ0IHBvcnRz" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX3Bob3V0X3BvcnRz::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBQTEwgRFBBIG91dHB1dCBwb3J0" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGxsX3R5cGU=::R2VuZXJhbA==::UExMIFRZUEU=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGxsX3N1YnR5cGU=::R2VuZXJhbA==::UExMIFNVQlRZUEU=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl9saXN0::TS1Db3VudGVyIEhpIERpdmlkZSxNLUNvdW50ZXIgTG93IERpdmlkZSxOLUNvdW50ZXIgSGkgRGl2aWRlLE4tQ291bnRlciBMb3cgRGl2aWRlLE0tQ291bnRlciBCeXBhc3MgRW5hYmxlLE4tQ291bnRlciBCeXBhc3MgRW5hYmxlLE0tQ291bnRlciBPZGQgRGl2aWRlIEVuYWJsZSxOLUNvdW50ZXIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTAgSGkgRGl2aWRlLEMtQ291bnRlci0wIExvdyBEaXZpZGUsQy1Db3VudGVyLTAgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0wIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTAgSW5wdXQgU291cmNlLEMtQ291bnRlci0wIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTAgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTEgSGkgRGl2aWRlLEMtQ291bnRlci0xIExvdyBEaXZpZGUsQy1Db3VudGVyLTEgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0xIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTEgSW5wdXQgU291cmNlLEMtQ291bnRlci0xIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTEgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTIgSGkgRGl2aWRlLEMtQ291bnRlci0yIExvdyBEaXZpZGUsQy1Db3VudGVyLTIgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0yIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTIgSW5wdXQgU291cmNlLEMtQ291bnRlci0yIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTMgSGkgRGl2aWRlLEMtQ291bnRlci0zIExvdyBEaXZpZGUsQy1Db3VudGVyLTMgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0zIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTMgSW5wdXQgU291cmNlLEMtQ291bnRlci0zIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTMgT2RkIERpdmlkZSBFbmFibGUsVkNPIFBvc3QgRGl2aWRlIENvdW50ZXIgRW5hYmxlLENoYXJnZSBQdW1wIGN1cnJlbnQgKHVBKSxMb29wIEZpbHRlciBCYW5kd2lkdGggUmVzaXN0b3IgKE9obXMpICxQTEwgT3V0cHV0IFZDTyBGcmVxdWVuY3ksSy1GcmFjdGlvbmFsIERpdmlzaW9uIFZhbHVlIChEU00pLEZlZWRiYWNrIENsb2NrIFR5cGUsRmVlZGJhY2sgQ2xvY2sgTVVYIDEsRmVlZGJhY2sgQ2xvY2sgTVVYIDIsTSBDb3VudGVyIFNvdXJjZSBNVVgsUExMIEF1dG8gUmVzZXQ=::UGFyYW1ldGVyIE5hbWVz" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl92YWx1ZXM=::NCw0LDI1NiwyNTYsZmFsc2UsdHJ1ZSxmYWxzZSxmYWxzZSw3LDcsMSwwLHBoX211eF9jbGssZmFsc2UsZmFsc2UsNTYsNTYsMSwwLHBoX211eF9jbGssZmFsc2UsZmFsc2UsNTYsNTYsMjksMCxwaF9tdXhfY2xrLGZhbHNlLGZhbHNlLDQsMywxLDAscGhfbXV4X2NsayxmYWxzZSx0cnVlLDEsMzAsMjAwMCw2MDEuMzYzNTAzIE1Ieiw0MjU5Mzk0NTUsbm9uZSxnbGIsbV9jbnQscGhfbXV4X2NsayxmYWxzZQ==::UGFyYW1ldGVyIFZhbHVlcw==" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX21pZl9nZW5lcmF0ZQ==::ZmFsc2U=::R2VuZXJhdGUgTUlGIGZpbGU=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9taWZfZHBz::ZmFsc2U=::RW5hYmxlIER5bmFtaWMgUGhhc2UgU2hpZnQgZm9yIE1JRiBzdHJlYW1pbmc=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19jbnRy::QzA=::RFBTIENvdW50ZXIgU2VsZWN0aW9u" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19udW0=::MQ==::TnVtYmVyIG9mIER5bmFtaWMgUGhhc2UgU2hpZnRz" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19kaXI=::UG9zaXRpdmU=::RHluYW1pYyBQaGFzZSBTaGlmdCBEaXJlY3Rpb24=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3JlZmNsa19zd2l0Y2g=::ZmFsc2U=::Q3JlYXRlIGEgc2Vjb25kIGlucHV0IGNsayAncmVmY2xrMSc=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9jYXNjYWRlX291dA==::ZmFsc2U=::Q3JlYXRlIGEgJ2Nhc2NhZGVfb3V0JyBzaWduYWwgdG8gY29ubmVjdCB3aXRoIGEgZG93bnN0cmVhbSBQTEw=" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9jYXNjYWRlX2lu::ZmFsc2U=::Q3JlYXRlIGFuIGFkanBsbGluIG9yIGNjbGsgc2lnbmFsIHRvIGNvbm5lY3Qgd2l0aCBhbiB1cHN0cmVhbSBQTEw=" - -set_global_assignment -library "core_pll" -name VERILOG_FILE [file join $::quartus(qip_path) "core_pll.v"] -set_global_assignment -library "core_pll" -name VERILOG_FILE [file join $::quartus(qip_path) "core_pll/core_pll_0002.v"] -set_global_assignment -library "core_pll" -name QIP_FILE [file join $::quartus(qip_path) "core_pll/core_pll_0002.qip"] - -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_TOOL_NAME "altera_pll" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_TOOL_VERSION "17.1" -set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_TOOL_ENV "mwpim" +set_global_assignment -entity "core_pll" -library "core_pll" -name IP_TOOL_NAME "altera_pll" +set_global_assignment -entity "core_pll" -library "core_pll" -name IP_TOOL_VERSION "17.1" +set_global_assignment -entity "core_pll" -library "core_pll" -name IP_TOOL_ENV "mwpim" +set_global_assignment -library "core_pll" -name MISC_FILE [file join $::quartus(qip_path) "core_pll.cmp"] +set_global_assignment -entity "core_pll" -library "core_pll" -name IP_TARGETED_DEVICE_FAMILY "Cyclone V" +set_global_assignment -entity "core_pll" -library "core_pll" -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" +set_global_assignment -entity "core_pll" -library "core_pll" -name IP_QSYS_MODE "UNKNOWN" +set_global_assignment -name SYNTHESIS_ONLY_QIP ON +set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_NAME "Y29yZV9wbGw=" +set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTA==" +set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" +set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_VERSION "MTcuMQ==" +set_global_assignment -entity "core_pll" -library "core_pll" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIChBTFRFUkFfUExMKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_NAME "Y29yZV9wbGxfMDAwMg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_DISPLAY_NAME "QWx0ZXJhIFBMTA==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_REPORT_HIERARCHY "Off" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_INTERNAL "Off" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_AUTHOR "QWx0ZXJhIENvcnBvcmF0aW9u" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_VERSION "MTcuMQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_DESCRIPTION "QWx0ZXJhIFBoYXNlLUxvY2tlZCBMb29wIChBTFRFUkFfUExMKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZGVidWdfcHJpbnRfb3V0cHV0::ZmFsc2U=::ZGVidWdfcHJpbnRfb3V0cHV0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZGVidWdfdXNlX3JiY190YWZfbWV0aG9k::ZmFsc2U=::ZGVidWdfdXNlX3JiY190YWZfbWV0aG9k" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZGV2aWNl::NUNFQkEyRjE3QTc=::ZGV2aWNl" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9tb2Rl::RnJhY3Rpb25hbC1OIFBMTA==::UExMIE1vZGU=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZnJhY3Rpb25hbF92Y29fbXVsdGlwbGllcg==::dHJ1ZQ==::ZnJhY3Rpb25hbF92Y29fbXVsdGlwbGllcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3JlZmVyZW5jZV9jbG9ja19mcmVxdWVuY3k=::NzQuMjU=::UmVmZXJlbmNlIENsb2NrIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cmVmZXJlbmNlX2Nsb2NrX2ZyZXF1ZW5jeQ==::NzQuMjUgTUh6::cmVmZXJlbmNlX2Nsb2NrX2ZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2NoYW5uZWxfc3BhY2luZw==::MC4w::Q2hhbm5lbCBTcGFjaW5n" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX29wZXJhdGlvbl9tb2Rl::ZGlyZWN0::T3BlcmF0aW9uIE1vZGU=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZlZWRiYWNrX2Nsb2Nr::R2xvYmFsIENsb2Nr::RmVlZGJhY2sgQ2xvY2s=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWN0aW9uYWxfY291dA==::MzI=::RnJhY3Rpb25hbCBjYXJyeSBvdXQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RzbV9vdXRfc2Vs::MXN0X29yZGVy::RFNNIE9yZGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3BlcmF0aW9uX21vZGU=::ZGlyZWN0::b3BlcmF0aW9uX21vZGU=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3VzZV9sb2NrZWQ=::dHJ1ZQ==::RW5hYmxlIGxvY2tlZCBvdXRwdXQgcG9ydA==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Fkdl9wYXJhbXM=::ZmFsc2U=::RW5hYmxlIHBoeXNpY2FsIG91dHB1dCBjbG9jayBwYXJhbWV0ZXJz" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX251bWJlcl9vZl9jbG9ja3M=::NA==::TnVtYmVyIE9mIENsb2Nrcw==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "bnVtYmVyX29mX2Nsb2Nrcw==::NA==::bnVtYmVyX29mX2Nsb2Nrcw==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX211bHRpcGx5X2ZhY3Rvcg==::MQ==::TXVsdGlwbHkgRmFjdG9yIChNLUNvdW50ZXIp" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2ZyYWNfbXVsdGlwbHlfZmFjdG9y::MQ==::RnJhY3Rpb25hbCBNdWx0aXBseSBGYWN0b3IgKEsp" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3Jfbg==::MQ==::RGl2aWRlIEZhY3RvciAoTi1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjA=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kw::NDIuOTU0NTM2::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzA=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iw::OA==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjA=::NDI1OTM5NDU1::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMA==::MTQ=::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MA==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzA=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDA=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUw::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kx::NS4zNjkzMTc=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Ix::OA==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE=::NDI1OTM5NDU1::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMQ==::MTEy::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MQ==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUx::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjI=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3ky::NS4zNjkzMTc=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzI=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iy::OA==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjI=::NDI1OTM5NDU1::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMg==::MTEy::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mg==::NS45NTI3NTUgTUh6::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMg==::ZGVncmVlcw==::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mg==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzI=::OTAuMA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDI=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUy::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjM=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kz::ODUuOTA5MDcy::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzM=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3Iz::OA==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjM=::NDI1OTM5NDU1::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMw==::Nw==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Mw==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMw==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Mw==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzM=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDM=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUz::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjQ=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k0::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzQ=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I0::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjQ=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNA==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5NA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0NA==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzQ=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDQ=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU0::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjU=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k1::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzU=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I1::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjU=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNQ==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5NQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0NQ==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzU=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDU=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU1::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjY=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k2::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzY=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I2::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjY=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNg==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Ng==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNg==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Ng==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzY=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDY=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU2::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjc=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k3::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzc=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I3::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjc=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yNw==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5Nw==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzNw==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0Nw==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzc=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDc=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU3::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjg=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k4::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzg=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I4::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjg=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yOA==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5OA==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzOA==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0OA==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzg=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDg=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU4::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjk=::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3k5::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzk=::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3I5::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3Rvcjk=::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yOQ==::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5OQ==::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzOQ==::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0OQ==::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzk=::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDk=::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGU5::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEw::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMA==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEw::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMA==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEw::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTA=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTA=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTA=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTA=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEw::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEw::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMA==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEx::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMQ==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEx::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMQ==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEx::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTE=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTE=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTE=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTE=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEx::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEx::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMQ==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEy::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMg==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEy::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMg==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEy::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTI=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTI=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTI=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTI=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEy::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEy::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMg==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjEz::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxMw==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzEz::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxMw==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjEz::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTM=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTM=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTM=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTM=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzEz::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDEz::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxMw==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE0::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNA==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE0::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNA==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE0::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTQ=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTQ=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTQ=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTQ=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE0::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE0::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNA==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE1::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNQ==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE1::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNQ==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE1::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTU=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTU=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTU=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTU=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE1::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE1::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNQ==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE2::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNg==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE2::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNg==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE2::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTY=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTY=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTY=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTY=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE2::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE2::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNg==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Nhc2NhZGVfY291bnRlcjE3::ZmFsc2U=::TWFrZSB0aGlzIGEgY2FzY2FkZSBjb3VudGVy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX291dHB1dF9jbG9ja19mcmVxdWVuY3kxNw==::MTAwLjA=::RGVzaXJlZCBGcmVxdWVuY3k=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2RpdmlkZV9mYWN0b3JfYzE3::MQ==::RGl2aWRlIEZhY3RvciAoQy1Db3VudGVyKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9tdWx0aXBseV9mYWN0b3IxNw==::MQ==::QWN0dWFsIE11bHRpcGx5IEZhY3Rvcg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9mcmFjX211bHRpcGx5X2ZhY3RvcjE3::MQ==::QWN0dWFsIEZyYWN0aW9uYWwgTXVsdGlwbHkgRmFjdG9yIChLKQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9kaXZpZGVfZmFjdG9yMTc=::MQ==::QWN0dWFsIERpdmlkZSBGYWN0b3I=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9vdXRwdXRfY2xvY2tfZnJlcXVlbmN5MTc=::MCBNSHo=::QWN0dWFsIEZyZXF1ZW5jeQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BzX3VuaXRzMTc=::cHM=::UGhhc2UgU2hpZnQgdW5pdHM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0MTc=::MA==::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BoYXNlX3NoaWZ0X2RlZzE3::MC4w::UGhhc2UgU2hpZnQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2FjdHVhbF9waGFzZV9zaGlmdDE3::MA==::QWN0dWFsIFBoYXNlIFNoaWZ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2R1dHlfY3ljbGUxNw==::NTA=::RHV0eSBDeWNsZQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA=::NDIuOTU0NTM2IE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTA=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQw::MCBwcw==::cGhhc2Vfc2hpZnQw" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTA=::NTA=::ZHV0eV9jeWNsZTA=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=::NS4zNjkzMTcgTUh6::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQx::MCBwcw==::cGhhc2Vfc2hpZnQx" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE=::NTA=::ZHV0eV9jeWNsZTE=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=::NS4zNjkzMTcgTUh6::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTI=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQy::NDY1NjEgcHM=::cGhhc2Vfc2hpZnQy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTI=::NTA=::ZHV0eV9jeWNsZTI=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=::ODUuOTA5MDcyIE1Ieg==::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQz::MCBwcw==::cGhhc2Vfc2hpZnQz" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTM=::NTA=::ZHV0eV9jeWNsZTM=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ0::MCBwcw==::cGhhc2Vfc2hpZnQ0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTQ=::NTA=::ZHV0eV9jeWNsZTQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTU=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ1::MCBwcw==::cGhhc2Vfc2hpZnQ1" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTU=::NTA=::ZHV0eV9jeWNsZTU=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTY=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTY=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ2::MCBwcw==::cGhhc2Vfc2hpZnQ2" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTY=::NTA=::ZHV0eV9jeWNsZTY=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTc=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTc=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ3::MCBwcw==::cGhhc2Vfc2hpZnQ3" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTc=::NTA=::ZHV0eV9jeWNsZTc=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTg=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTg=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ4::MCBwcw==::cGhhc2Vfc2hpZnQ4" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTg=::NTA=::ZHV0eV9jeWNsZTg=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTk=::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTk=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQ5::MCBwcw==::cGhhc2Vfc2hpZnQ5" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTk=::NTA=::ZHV0eV9jeWNsZTk=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEw::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEw" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMA==::MCBwcw==::cGhhc2Vfc2hpZnQxMA==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEw::NTA=::ZHV0eV9jeWNsZTEw" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEx::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEx" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMQ==::MCBwcw==::cGhhc2Vfc2hpZnQxMQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEx::NTA=::ZHV0eV9jeWNsZTEx" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEy::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMg==::MCBwcw==::cGhhc2Vfc2hpZnQxMg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEy::NTA=::ZHV0eV9jeWNsZTEy" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEz::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTEz" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxMw==::MCBwcw==::cGhhc2Vfc2hpZnQxMw==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTEz::NTA=::ZHV0eV9jeWNsZTEz" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE0::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNA==::MCBwcw==::cGhhc2Vfc2hpZnQxNA==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE0::NTA=::ZHV0eV9jeWNsZTE0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE1::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE1" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNQ==::MCBwcw==::cGhhc2Vfc2hpZnQxNQ==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE1::NTA=::ZHV0eV9jeWNsZTE1" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE2::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE2" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNg==::MCBwcw==::cGhhc2Vfc2hpZnQxNg==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE2::NTA=::ZHV0eV9jeWNsZTE2" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE3::MCBNSHo=::b3V0cHV0X2Nsb2NrX2ZyZXF1ZW5jeTE3" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGhhc2Vfc2hpZnQxNw==::MCBwcw==::cGhhc2Vfc2hpZnQxNw==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "ZHV0eV9jeWNsZTE3::NTA=::ZHV0eV9jeWNsZTE3" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9hdXRvX3Jlc2V0::T2Zm::UExMIEF1dG8gUmVzZXQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BsbF9iYW5kd2lkdGhfcHJlc2V0::QXV0bw==::UExMIEJhbmR3aWR0aCBQcmVzZXQ=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX3JlY29uZg==::ZmFsc2U=::RW5hYmxlIGR5bmFtaWMgcmVjb25maWd1cmF0aW9uIG9mIFBMTA==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX2Rwc19wb3J0cw==::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBkeW5hbWljIHBoYXNlIHNoaWZ0IHBvcnRz" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuX3Bob3V0X3BvcnRz::ZmFsc2U=::RW5hYmxlIGFjY2VzcyB0byBQTEwgRFBBIG91dHB1dCBwb3J0" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGxsX3R5cGU=::R2VuZXJhbA==::UExMIFRZUEU=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "cGxsX3N1YnR5cGU=::R2VuZXJhbA==::UExMIFNVQlRZUEU=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl9saXN0::TS1Db3VudGVyIEhpIERpdmlkZSxNLUNvdW50ZXIgTG93IERpdmlkZSxOLUNvdW50ZXIgSGkgRGl2aWRlLE4tQ291bnRlciBMb3cgRGl2aWRlLE0tQ291bnRlciBCeXBhc3MgRW5hYmxlLE4tQ291bnRlciBCeXBhc3MgRW5hYmxlLE0tQ291bnRlciBPZGQgRGl2aWRlIEVuYWJsZSxOLUNvdW50ZXIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTAgSGkgRGl2aWRlLEMtQ291bnRlci0wIExvdyBEaXZpZGUsQy1Db3VudGVyLTAgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0wIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTAgSW5wdXQgU291cmNlLEMtQ291bnRlci0wIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTAgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTEgSGkgRGl2aWRlLEMtQ291bnRlci0xIExvdyBEaXZpZGUsQy1Db3VudGVyLTEgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0xIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTEgSW5wdXQgU291cmNlLEMtQ291bnRlci0xIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTEgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTIgSGkgRGl2aWRlLEMtQ291bnRlci0yIExvdyBEaXZpZGUsQy1Db3VudGVyLTIgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0yIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTIgSW5wdXQgU291cmNlLEMtQ291bnRlci0yIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTIgT2RkIERpdmlkZSBFbmFibGUsQy1Db3VudGVyLTMgSGkgRGl2aWRlLEMtQ291bnRlci0zIExvdyBEaXZpZGUsQy1Db3VudGVyLTMgQ29hcnNlIFBoYXNlIFNoaWZ0LEMtQ291bnRlci0zIFZDTyBQaGFzZSBUYXAsQy1Db3VudGVyLTMgSW5wdXQgU291cmNlLEMtQ291bnRlci0zIEJ5cGFzcyBFbmFibGUsQy1Db3VudGVyLTMgT2RkIERpdmlkZSBFbmFibGUsVkNPIFBvc3QgRGl2aWRlIENvdW50ZXIgRW5hYmxlLENoYXJnZSBQdW1wIGN1cnJlbnQgKHVBKSxMb29wIEZpbHRlciBCYW5kd2lkdGggUmVzaXN0b3IgKE9obXMpICxQTEwgT3V0cHV0IFZDTyBGcmVxdWVuY3ksSy1GcmFjdGlvbmFsIERpdmlzaW9uIFZhbHVlIChEU00pLEZlZWRiYWNrIENsb2NrIFR5cGUsRmVlZGJhY2sgQ2xvY2sgTVVYIDEsRmVlZGJhY2sgQ2xvY2sgTVVYIDIsTSBDb3VudGVyIFNvdXJjZSBNVVgsUExMIEF1dG8gUmVzZXQ=::UGFyYW1ldGVyIE5hbWVz" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3BhcmFtZXRlcl92YWx1ZXM=::NCw0LDI1NiwyNTYsZmFsc2UsdHJ1ZSxmYWxzZSxmYWxzZSw3LDcsMSwwLHBoX211eF9jbGssZmFsc2UsZmFsc2UsNTYsNTYsMSwwLHBoX211eF9jbGssZmFsc2UsZmFsc2UsNTYsNTYsMjksMCxwaF9tdXhfY2xrLGZhbHNlLGZhbHNlLDQsMywxLDAscGhfbXV4X2NsayxmYWxzZSx0cnVlLDEsMzAsMjAwMCw2MDEuMzYzNTAzIE1Ieiw0MjU5Mzk0NTUsbm9uZSxnbGIsbV9jbnQscGhfbXV4X2NsayxmYWxzZQ==::UGFyYW1ldGVyIFZhbHVlcw==" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX21pZl9nZW5lcmF0ZQ==::ZmFsc2U=::R2VuZXJhdGUgTUlGIGZpbGU=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9taWZfZHBz::ZmFsc2U=::RW5hYmxlIER5bmFtaWMgUGhhc2UgU2hpZnQgZm9yIE1JRiBzdHJlYW1pbmc=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19jbnRy::QzA=::RFBTIENvdW50ZXIgU2VsZWN0aW9u" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19udW0=::MQ==::TnVtYmVyIG9mIER5bmFtaWMgUGhhc2UgU2hpZnRz" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2Rwc19kaXI=::UG9zaXRpdmU=::RHluYW1pYyBQaGFzZSBTaGlmdCBEaXJlY3Rpb24=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX3JlZmNsa19zd2l0Y2g=::ZmFsc2U=::Q3JlYXRlIGEgc2Vjb25kIGlucHV0IGNsayAncmVmY2xrMSc=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9jYXNjYWRlX291dA==::ZmFsc2U=::Q3JlYXRlIGEgJ2Nhc2NhZGVfb3V0JyBzaWduYWwgdG8gY29ubmVjdCB3aXRoIGEgZG93bnN0cmVhbSBQTEw=" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_COMPONENT_PARAMETER "Z3VpX2VuYWJsZV9jYXNjYWRlX2lu::ZmFsc2U=::Q3JlYXRlIGFuIGFkanBsbGluIG9yIGNjbGsgc2lnbmFsIHRvIGNvbm5lY3Qgd2l0aCBhbiB1cHN0cmVhbSBQTEw=" + +set_global_assignment -library "core_pll" -name VERILOG_FILE [file join $::quartus(qip_path) "core_pll.v"] +set_global_assignment -library "core_pll" -name VERILOG_FILE [file join $::quartus(qip_path) "core_pll/core_pll_0002.v"] +set_global_assignment -library "core_pll" -name QIP_FILE [file join $::quartus(qip_path) "core_pll/core_pll_0002.qip"] + +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_TOOL_NAME "altera_pll" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_TOOL_VERSION "17.1" +set_global_assignment -entity "core_pll_0002" -library "core_pll" -name IP_TOOL_ENV "mwpim" diff --git a/target/pocket/core_pll/core_pll.v b/target/pocket/core_pll/core_pll.v index 62a8fc0..46ee4b0 100644 --- a/target/pocket/core_pll/core_pll.v +++ b/target/pocket/core_pll/core_pll.v @@ -1,259 +1,259 @@ -// megafunction wizard: %Altera PLL v17.1% -// GENERATION: XML -// core_pll.v - -// Generated using ACDS version 17.1 590 - -`timescale 1 ps / 1 ps -module core_pll ( - input wire refclk, // refclk.clk - input wire rst, // reset.reset - output wire outclk_0, // outclk0.clk - output wire outclk_1, // outclk1.clk - output wire outclk_2, // outclk2.clk - output wire outclk_3, // outclk3.clk - output wire locked // locked.export - ); - - core_pll_0002 core_pll_inst ( - .refclk (refclk), // refclk.clk - .rst (rst), // reset.reset - .outclk_0 (outclk_0), // outclk0.clk - .outclk_1 (outclk_1), // outclk1.clk - .outclk_2 (outclk_2), // outclk2.clk - .outclk_3 (outclk_3), // outclk3.clk - .locked (locked) // locked.export - ); - -endmodule -// Retrieval info: -// -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// Retrieval info: -// IPFS_FILES : core_pll.vo -// RELATED_FILES: core_pll.v, core_pll_0002.v +// megafunction wizard: %Altera PLL v17.1% +// GENERATION: XML +// core_pll.v + +// Generated using ACDS version 17.1 590 + +`timescale 1 ps / 1 ps +module core_pll ( + input wire refclk, // refclk.clk + input wire rst, // reset.reset + output wire outclk_0, // outclk0.clk + output wire outclk_1, // outclk1.clk + output wire outclk_2, // outclk2.clk + output wire outclk_3, // outclk3.clk + output wire locked // locked.export + ); + + core_pll_0002 core_pll_inst ( + .refclk (refclk), // refclk.clk + .rst (rst), // reset.reset + .outclk_0 (outclk_0), // outclk0.clk + .outclk_1 (outclk_1), // outclk1.clk + .outclk_2 (outclk_2), // outclk2.clk + .outclk_3 (outclk_3), // outclk3.clk + .locked (locked) // locked.export + ); + +endmodule +// Retrieval info: +// +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// Retrieval info: +// IPFS_FILES : core_pll.vo +// RELATED_FILES: core_pll.v, core_pll_0002.v diff --git a/target/pocket/core_pll/core_pll/core_pll_0002.qip b/target/pocket/core_pll/core_pll/core_pll_0002.qip index 8646d01..5e41456 100644 --- a/target/pocket/core_pll/core_pll/core_pll_0002.qip +++ b/target/pocket/core_pll/core_pll/core_pll_0002.qip @@ -1,4 +1,4 @@ -set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*core_pll_0002*|altera_pll:altera_pll_i*|*" -set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*core_pll_0002*|altera_pll:altera_pll_i*|*" -set_instance_assignment -name PLL_AUTO_RESET OFF -to "*core_pll_0002*|altera_pll:altera_pll_i*|*" -set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*core_pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_COMPENSATION_MODE DIRECT -to "*core_pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*core_pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_AUTO_RESET OFF -to "*core_pll_0002*|altera_pll:altera_pll_i*|*" +set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*core_pll_0002*|altera_pll:altera_pll_i*|*" diff --git a/target/pocket/core_pll/core_pll/core_pll_0002.v b/target/pocket/core_pll/core_pll/core_pll_0002.v index e931014..d2f849a 100644 --- a/target/pocket/core_pll/core_pll/core_pll_0002.v +++ b/target/pocket/core_pll/core_pll/core_pll_0002.v @@ -1,96 +1,96 @@ -`timescale 1ns/10ps -module core_pll_0002( - - // interface 'refclk' - input wire refclk, - - // interface 'reset' - input wire rst, - - // interface 'outclk0' - output wire outclk_0, - - // interface 'outclk1' - output wire outclk_1, - - // interface 'outclk2' - output wire outclk_2, - - // interface 'outclk3' - output wire outclk_3, - - // interface 'locked' - output wire locked -); - - altera_pll #( - .fractional_vco_multiplier("true"), - .reference_clock_frequency("74.25 MHz"), - .operation_mode("direct"), - .number_of_clocks(4), - .output_clock_frequency0("42.954536 MHz"), - .phase_shift0("0 ps"), - .duty_cycle0(50), - .output_clock_frequency1("5.369317 MHz"), - .phase_shift1("0 ps"), - .duty_cycle1(50), - .output_clock_frequency2("5.369317 MHz"), - .phase_shift2("46561 ps"), - .duty_cycle2(50), - .output_clock_frequency3("85.909072 MHz"), - .phase_shift3("0 ps"), - .duty_cycle3(50), - .output_clock_frequency4("0 MHz"), - .phase_shift4("0 ps"), - .duty_cycle4(50), - .output_clock_frequency5("0 MHz"), - .phase_shift5("0 ps"), - .duty_cycle5(50), - .output_clock_frequency6("0 MHz"), - .phase_shift6("0 ps"), - .duty_cycle6(50), - .output_clock_frequency7("0 MHz"), - .phase_shift7("0 ps"), - .duty_cycle7(50), - .output_clock_frequency8("0 MHz"), - .phase_shift8("0 ps"), - .duty_cycle8(50), - .output_clock_frequency9("0 MHz"), - .phase_shift9("0 ps"), - .duty_cycle9(50), - .output_clock_frequency10("0 MHz"), - .phase_shift10("0 ps"), - .duty_cycle10(50), - .output_clock_frequency11("0 MHz"), - .phase_shift11("0 ps"), - .duty_cycle11(50), - .output_clock_frequency12("0 MHz"), - .phase_shift12("0 ps"), - .duty_cycle12(50), - .output_clock_frequency13("0 MHz"), - .phase_shift13("0 ps"), - .duty_cycle13(50), - .output_clock_frequency14("0 MHz"), - .phase_shift14("0 ps"), - .duty_cycle14(50), - .output_clock_frequency15("0 MHz"), - .phase_shift15("0 ps"), - .duty_cycle15(50), - .output_clock_frequency16("0 MHz"), - .phase_shift16("0 ps"), - .duty_cycle16(50), - .output_clock_frequency17("0 MHz"), - .phase_shift17("0 ps"), - .duty_cycle17(50), - .pll_type("General"), - .pll_subtype("General") - ) altera_pll_i ( - .rst (rst), - .outclk ({outclk_3, outclk_2, outclk_1, outclk_0}), - .locked (locked), - .fboutclk ( ), - .fbclk (1'b0), - .refclk (refclk) - ); -endmodule - +`timescale 1ns/10ps +module core_pll_0002( + + // interface 'refclk' + input wire refclk, + + // interface 'reset' + input wire rst, + + // interface 'outclk0' + output wire outclk_0, + + // interface 'outclk1' + output wire outclk_1, + + // interface 'outclk2' + output wire outclk_2, + + // interface 'outclk3' + output wire outclk_3, + + // interface 'locked' + output wire locked +); + + altera_pll #( + .fractional_vco_multiplier("true"), + .reference_clock_frequency("74.25 MHz"), + .operation_mode("direct"), + .number_of_clocks(4), + .output_clock_frequency0("42.954536 MHz"), + .phase_shift0("0 ps"), + .duty_cycle0(50), + .output_clock_frequency1("5.369317 MHz"), + .phase_shift1("0 ps"), + .duty_cycle1(50), + .output_clock_frequency2("5.369317 MHz"), + .phase_shift2("46561 ps"), + .duty_cycle2(50), + .output_clock_frequency3("85.909072 MHz"), + .phase_shift3("0 ps"), + .duty_cycle3(50), + .output_clock_frequency4("0 MHz"), + .phase_shift4("0 ps"), + .duty_cycle4(50), + .output_clock_frequency5("0 MHz"), + .phase_shift5("0 ps"), + .duty_cycle5(50), + .output_clock_frequency6("0 MHz"), + .phase_shift6("0 ps"), + .duty_cycle6(50), + .output_clock_frequency7("0 MHz"), + .phase_shift7("0 ps"), + .duty_cycle7(50), + .output_clock_frequency8("0 MHz"), + .phase_shift8("0 ps"), + .duty_cycle8(50), + .output_clock_frequency9("0 MHz"), + .phase_shift9("0 ps"), + .duty_cycle9(50), + .output_clock_frequency10("0 MHz"), + .phase_shift10("0 ps"), + .duty_cycle10(50), + .output_clock_frequency11("0 MHz"), + .phase_shift11("0 ps"), + .duty_cycle11(50), + .output_clock_frequency12("0 MHz"), + .phase_shift12("0 ps"), + .duty_cycle12(50), + .output_clock_frequency13("0 MHz"), + .phase_shift13("0 ps"), + .duty_cycle13(50), + .output_clock_frequency14("0 MHz"), + .phase_shift14("0 ps"), + .duty_cycle14(50), + .output_clock_frequency15("0 MHz"), + .phase_shift15("0 ps"), + .duty_cycle15(50), + .output_clock_frequency16("0 MHz"), + .phase_shift16("0 ps"), + .duty_cycle16(50), + .output_clock_frequency17("0 MHz"), + .phase_shift17("0 ps"), + .duty_cycle17(50), + .pll_type("General"), + .pll_subtype("General") + ) altera_pll_i ( + .rst (rst), + .outclk ({outclk_3, outclk_2, outclk_1, outclk_0}), + .locked (locked), + .fboutclk ( ), + .fbclk (1'b0), + .refclk (refclk) + ); +endmodule + diff --git a/target/pocket/core_top.sv b/target/pocket/core_top.sv index 6785816..c72779b 100644 --- a/target/pocket/core_top.sv +++ b/target/pocket/core_top.sv @@ -1,1118 +1,1360 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// SPDX-FileType: SOURCE -// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors -//------------------------------------------------------------------------------ -// -// Copyright (c) 2023, Marcus Andrade -// Copyright (c) 2022, Analogue Enterprises Limited -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -//------------------------------------------------------------------------------ -// Platform Specific top-level -// Instantiated by the real top-level: apf_top -//------------------------------------------------------------------------------ - -`default_nettype none - -module core_top - #( - //! ------------------------------------------------------------------------ - //! System Configuration Parameters - //! ------------------------------------------------------------------------ - // Memory - parameter USE_SDRAM = 1, //! Enable SDRAM - parameter USE_SRAM = 0, //! Enable SRAM - parameter USE_CRAM0 = 0, //! Enable Cellular RAM #1 - parameter USE_CRAM1 = 0, //! Enable Cellular RAM #2 - // Video - parameter BPP_R = 8, //! Bits Per Pixel Red - parameter BPP_G = 8, //! Bits Per Pixel Green - parameter BPP_B = 8, //! Bits Per Pixel Blue - // Audio - parameter AUDIO_DW = 16, //! Audio Bits - parameter AUDIO_S = 1, //! Signed Audio - parameter STEREO = 0, //! Stereo Output - parameter AUDIO_MIX = 0, //! [0] No Mix | [1] 25% | [2] 50% | [3] 100% (mono) - // Gamepad/Joystick - parameter JOY_PADS = 2, //! Total Number of Gamepads - parameter JOY_ALT = 1, //! 2 Players Alternate - // Data I/O - [MPU -> FPGA] - parameter DIO_MASK = 4'h0, //! Upper 4 bits of address - parameter DIO_AW = 27, //! Address Width - parameter DIO_DW = 8, //! Data Width (8 or 16 bits) - parameter DIO_DELAY = 7, //! Number of clock cycles to delay each write output - parameter DIO_HOLD = 4, //! Number of clock cycles to hold the ioctl_wr signal high - // HiScore I/O - [MPU <-> FPGA] - parameter HS_AW = 16, //! Max size of game RAM address for highscores - parameter HS_SW = 8, //! Max size of capture RAM For highscore data (default 8 = 256 bytes max) - parameter HS_CFG_AW = 2, //! Max size of RAM address for highscore.dat entries (default 4 = 16 entries max) - parameter HS_CFG_LW = 2, //! Max size of length for each highscore.dat entries (default 1 = 256 bytes max) - parameter HS_CONFIG = 2, //! Dataslot index for config transfer - parameter HS_DATA = 3, //! Dataslot index for save data transfer - parameter HS_NVM_SZ = 32'd93, //! Number bytes required for Save - parameter HS_MASK = 4'h1, //! Upper 4 bits of address - parameter HS_WR_DELAY = 4, //! Number of clock cycles to delay each write output - parameter HS_WR_HOLD = 1, //! Number of clock cycles to hold the nvram_wr signal high - parameter HS_RD_DELAY = 4, //! Number of clock cycles it takes for a read to complete - // Save I/O - [MPU <-> FPGA] - parameter SIO_MASK = 4'h1, //! Upper 4 bits of address - parameter SIO_AW = 27, //! Address Width - parameter SIO_DW = 8, //! Data Width (8 or 16 bits) - parameter SIO_WR_DELAY = 4, //! Number of clock cycles to delay each write output - parameter SIO_WR_HOLD = 1, //! Number of clock cycles to hold the nvram_wr signal high - parameter SIO_RD_DELAY = 4, //! Number of clock cycles it takes for a read to complete - parameter SIO_SAVE_IDX = 2 //! Dataslot index for save data transfer - ) ( - //! -------------------------------------------------------------------- - //! Clock Inputs 74.25mhz. - //! Not Phase Aligned, Treat These Domains as Asynchronous - //! -------------------------------------------------------------------- - input wire clk_74a, // mainclk1 - input wire clk_74b, // mainclk1 - - //! -------------------------------------------------------------------- - //! Cartridge Interface - //! -------------------------------------------------------------------- - // switches between 3.3v and 5v mechanically - // output enable for multibit translators controlled by pic32 - // GBA AD[15:8] - inout wire [7:0] cart_tran_bank2, - output wire cart_tran_bank2_dir, - // GBA AD[7:0] - inout wire [7:0] cart_tran_bank3, - output wire cart_tran_bank3_dir, - // GBA A[23:16] - inout wire [7:0] cart_tran_bank1, - output wire cart_tran_bank1_dir, - // GBA [7] PHI# - // GBA [6] WR# - // GBA [5] RD# - // GBA [4] CS1#/CS# - // [3:0] unwired - inout wire [7:4] cart_tran_bank0, - output wire cart_tran_bank0_dir, - // GBA CS2#/RES# - inout wire cart_tran_pin30, - output wire cart_tran_pin30_dir, - // when GBC cart is inserted, this signal when low or weak will pull GBC /RES low with a special circuit - // the goal is that when unconfigured, the FPGA weak pullups won't interfere. - // thus, if GBC cart is inserted, FPGA must drive this high in order to let the level translators - // and general IO drive this pin. - output wire cart_pin30_pwroff_reset, - // GBA IRQ/DRQ - inout wire cart_tran_pin31, - output wire cart_tran_pin31_dir, - - //! -------------------------------------------------------------------- - //! Infrared - //! -------------------------------------------------------------------- - input wire port_ir_rx, - output wire port_ir_tx, - output wire port_ir_rx_disable, - - //! -------------------------------------------------------------------- - //! GBA link port - //! -------------------------------------------------------------------- - inout wire port_tran_si, - output wire port_tran_si_dir, - inout wire port_tran_so, - output wire port_tran_so_dir, - inout wire port_tran_sck, - output wire port_tran_sck_dir, - inout wire port_tran_sd, - output wire port_tran_sd_dir, - - //! -------------------------------------------------------------------- - //! Cellular PSRAM 0 and 1, two chips (64mbit x2 dual die per chip) - //! -------------------------------------------------------------------- - output wire [21:16] cram0_a, - inout wire [15:0] cram0_dq, - input wire cram0_wait, - output wire cram0_clk, - output wire cram0_adv_n, - output wire cram0_cre, - output wire cram0_ce0_n, - output wire cram0_ce1_n, - output wire cram0_oe_n, - output wire cram0_we_n, - output wire cram0_ub_n, - output wire cram0_lb_n, - - output wire [21:16] cram1_a, - inout wire [15:0] cram1_dq, - input wire cram1_wait, - output wire cram1_clk, - output wire cram1_adv_n, - output wire cram1_cre, - output wire cram1_ce0_n, - output wire cram1_ce1_n, - output wire cram1_oe_n, - output wire cram1_we_n, - output wire cram1_ub_n, - output wire cram1_lb_n, - - //! -------------------------------------------------------------------- - //! SDRAM, 512mbit 16bit - //! -------------------------------------------------------------------- - output wire [12:0] dram_a, // Address bus - output wire [1:0] dram_ba, // Bank select (single bits) - inout wire [15:0] dram_dq, // Bidirectional data bus - output wire [1:0] dram_dqm, // High/low byte mask - output wire dram_clk, // Chip clock - output wire dram_cke, // Clock enable - output wire dram_ras_n, // Select row address (active low) - output wire dram_cas_n, // Select column address (active low) - output wire dram_we_n, // Write enable (active low) - - //! -------------------------------------------------------------------- - //! SRAM, 1mbit 16bit - //! -------------------------------------------------------------------- - output wire [16:0] sram_a, // Address bus - inout wire [15:0] sram_dq, // Bidirectional data bus - output wire sram_oe_n, // Output enable - output wire sram_we_n, // Write enable - output wire sram_ub_n, // Upper Byte Mask - output wire sram_lb_n, // Lower Byte Mask - - //! -------------------------------------------------------------------- - //! vblank driven by dock for sync in a certain mode - //! -------------------------------------------------------------------- - input wire vblank, - - //! -------------------------------------------------------------------- - //! I/O to 6515D breakout USB UART - //! -------------------------------------------------------------------- - output wire dbg_tx, - input wire dbg_rx, - - //! -------------------------------------------------------------------- - //! I/O pads near jtag connector user can solder to - //! -------------------------------------------------------------------- - output wire user1, - input wire user2, - - //! -------------------------------------------------------------------- - //! RFU internal i2c bus - //! -------------------------------------------------------------------- - inout wire aux_sda, - output wire aux_scl, - - //! -------------------------------------------------------------------- - //! RFU, do not use !!! - //! -------------------------------------------------------------------- - output wire vpll_feed, - - //! -------------------------------------------------------------------- - //! Logical Connections //////////////////////////////////////////////// - //! -------------------------------------------------------------------- - - //! -------------------------------------------------------------------- - //! Video Output to Scaler - //! -------------------------------------------------------------------- - output wire [23:0] video_rgb, - output wire video_rgb_clock, - output wire video_rgb_clock_90, - output wire video_hs, - output wire video_vs, - output wire video_de, - output wire video_skip, - - //! -------------------------------------------------------------------- - //! Audio - //! -------------------------------------------------------------------- - output wire audio_mclk, - output wire audio_lrck, - output wire audio_dac, - input wire audio_adc, - - //! -------------------------------------------------------------------- - //! Bridge Bus Connection (synchronous to clk_74a) - //! -------------------------------------------------------------------- - output wire bridge_endian_little, - input wire [31:0] bridge_addr, - input wire bridge_rd, - output reg [31:0] bridge_rd_data, - input wire bridge_wr, - input wire [31:0] bridge_wr_data, - - //! -------------------------------------------------------------------- - //! Controller Data - //! -------------------------------------------------------------------- - input wire [31:0] cont1_key, - input wire [31:0] cont2_key, - input wire [31:0] cont3_key, - input wire [31:0] cont4_key, - input wire [31:0] cont1_joy, - input wire [31:0] cont2_joy, - input wire [31:0] cont3_joy, - input wire [31:0] cont4_joy, - input wire [15:0] cont1_trig, - input wire [15:0] cont2_trig, - input wire [15:0] cont3_trig, - input wire [15:0] cont4_trig - ); - - //Analogizer settings - localparam [7:0] ADDRESS_ANALOGIZER_CONFIG = 8'hF7; - - // not using the IR port, so turn off both the LED, and - // disable the receive circuit to save power - assign port_ir_tx = 0; - assign port_ir_rx_disable = 1; - - // bridge endianness - assign bridge_endian_little = 0; - - // cart is unused, so set all level translators accordingly - // directions are 0:IN, 1:OUT - // assign cart_tran_bank3 = 8'hzz; - // assign cart_tran_bank3_dir = 1'b0; - // assign cart_tran_bank2 = 8'hzz; - // assign cart_tran_bank2_dir = 1'b0; - // assign cart_tran_bank1 = 8'hzz; - // assign cart_tran_bank1_dir = 1'b0; - // assign cart_tran_bank0 = 4'hf; - // assign cart_tran_bank0_dir = 1'b1; - // assign cart_tran_pin30 = 1'b0; // reset or cs2, we let the hw control it by itself - // assign cart_tran_pin30_dir = 1'bz; - // assign cart_pin30_pwroff_reset = 1'b0; // hardware can control this - // assign cart_tran_pin31 = 1'bz; // input - // assign cart_tran_pin31_dir = 1'b0; // input - - // link port is input only - assign port_tran_so = 1'bz; - assign port_tran_so_dir = 1'b0; // SO is output only - assign port_tran_si = 1'bz; - assign port_tran_si_dir = 1'b0; // SI is input only - assign port_tran_sck = 1'bz; - assign port_tran_sck_dir = 1'b0; // clock direction can change - assign port_tran_sd = 1'bz; - assign port_tran_sd_dir = 1'b0; // SD is input and not used - - assign dbg_tx = 1'bZ; - assign user1 = 1'bZ; - assign aux_scl = 1'bZ; - assign vpll_feed = 1'bZ; - - // Tie off the memory the pins not being used - generate - if(USE_CRAM0 == 0) begin - assign cram0_a = 'h0; - assign cram0_dq = {16{1'bZ}}; - assign cram0_clk = 0; - assign cram0_adv_n = 1; - assign cram0_cre = 0; - assign cram0_ce0_n = 1; - assign cram0_ce1_n = 1; - assign cram0_oe_n = 1; - assign cram0_we_n = 1; - assign cram0_ub_n = 1; - assign cram0_lb_n = 1; - end - - if(USE_CRAM1 == 0) begin - assign cram1_a = 'h0; - assign cram1_dq = {16{1'bZ}}; - assign cram1_clk = 0; - assign cram1_adv_n = 1; - assign cram1_cre = 0; - assign cram1_ce0_n = 1; - assign cram1_ce1_n = 1; - assign cram1_oe_n = 1; - assign cram1_we_n = 1; - assign cram1_ub_n = 1; - assign cram1_lb_n = 1; - end - - if(USE_SDRAM == 0) begin - assign dram_a = 'h0; - assign dram_ba = 'h0; - assign dram_dq = {16{1'bZ}}; - assign dram_dqm = 'h0; - assign dram_clk = 'h0; - assign dram_cke = 'h0; - assign dram_ras_n = 'h1; - assign dram_cas_n = 'h1; - assign dram_we_n = 'h1; - end - - if(USE_SRAM == 0) begin - assign sram_a = 'h0; - assign sram_dq = {16{1'bZ}}; - assign sram_oe_n = 1; - assign sram_we_n = 1; - assign sram_ub_n = 1; - assign sram_lb_n = 1; - end - endgenerate - - //! ------------------------------------------------------------------------ - //! Host/Target Command Handler - //! ------------------------------------------------------------------------ - wire reset_n; // driven by host commands, can be used as core-wide reset - wire [31:0] cmd_bridge_rd_data; - - // bridge host commands - // synchronous to clk_74a - wire status_boot_done = pll_core_locked_s; - wire status_setup_done = pll_core_locked_s; // rising edge triggers a target command - wire status_running = reset_n; // we are running as soon as reset_n goes high - - wire dataslot_requestread; - wire [15:0] dataslot_requestread_id; - wire dataslot_requestread_ack = 1; - wire dataslot_requestread_ok = 1; - - wire dataslot_requestwrite; - wire [15:0] dataslot_requestwrite_id; - wire [31:0] dataslot_requestwrite_size; - wire dataslot_requestwrite_ack = 1; - wire dataslot_requestwrite_ok = 1; - - wire dataslot_update; - wire [15:0] dataslot_update_id; - wire [31:0] dataslot_update_size; - - wire dataslot_allcomplete; - - wire [31:0] rtc_epoch_seconds; - wire [31:0] rtc_date_bcd; - wire [31:0] rtc_time_bcd; - wire rtc_valid; - - wire savestate_supported; - wire [31:0] savestate_addr; - wire [31:0] savestate_size; - wire [31:0] savestate_maxloadsize; - - wire savestate_start; - wire savestate_start_ack; - wire savestate_start_busy; - wire savestate_start_ok; - wire savestate_start_err; - - wire savestate_load; - wire savestate_load_ack; - wire savestate_load_busy; - wire savestate_load_ok; - wire savestate_load_err; - - wire osnotify_inmenu; - - // bridge target commands - // synchronous to clk_74a - reg target_dataslot_read; - reg target_dataslot_write; - reg target_dataslot_getfile; // require additional param/resp structs to be mapped - reg target_dataslot_openfile; // require additional param/resp structs to be mapped - - wire target_dataslot_ack; - wire target_dataslot_done; - wire [2:0] target_dataslot_err; - - reg [15:0] target_dataslot_id; - reg [31:0] target_dataslot_slotoffset; - reg [31:0] target_dataslot_bridgeaddr; - reg [31:0] target_dataslot_length; - - wire [31:0] target_buffer_param_struct; // to be mapped/implemented when using some Target commands - wire [31:0] target_buffer_resp_struct; // to be mapped/implemented when using some Target commands - - // bridge data slot access - // synchronous to clk_74a - wire [9:0] datatable_addr; - wire datatable_wren; - wire [31:0] datatable_data; - wire [31:0] datatable_q; - - core_bridge_cmd icb - ( - .clk ( clk_74a ), - .reset_n ( reset_n ), - - .bridge_endian_little ( bridge_endian_little ), - .bridge_addr ( bridge_addr ), - .bridge_rd ( bridge_rd ), - .bridge_rd_data ( cmd_bridge_rd_data ), - .bridge_wr ( bridge_wr ), - .bridge_wr_data ( bridge_wr_data ), - - .status_boot_done ( status_boot_done ), - .status_setup_done ( status_setup_done ), - .status_running ( status_running ), - - .dataslot_requestread ( dataslot_requestread ), - .dataslot_requestread_id ( dataslot_requestread_id ), - .dataslot_requestread_ack ( dataslot_requestread_ack ), - .dataslot_requestread_ok ( dataslot_requestread_ok ), - - .dataslot_requestwrite ( dataslot_requestwrite ), - .dataslot_requestwrite_id ( dataslot_requestwrite_id ), - .dataslot_requestwrite_size ( dataslot_requestwrite_size ), - .dataslot_requestwrite_ack ( dataslot_requestwrite_ack ), - .dataslot_requestwrite_ok ( dataslot_requestwrite_ok ), - - .dataslot_update ( dataslot_update ), - .dataslot_update_id ( dataslot_update_id ), - .dataslot_update_size ( dataslot_update_size ), - - .dataslot_allcomplete ( dataslot_allcomplete ), - - .rtc_epoch_seconds ( rtc_epoch_seconds ), - .rtc_date_bcd ( rtc_date_bcd ), - .rtc_time_bcd ( rtc_time_bcd ), - .rtc_valid ( rtc_valid ), - - .savestate_supported ( savestate_supported ), - .savestate_addr ( savestate_addr ), - .savestate_size ( savestate_size ), - .savestate_maxloadsize ( savestate_maxloadsize ), - - .savestate_start ( savestate_start ), - .savestate_start_ack ( savestate_start_ack ), - .savestate_start_busy ( savestate_start_busy ), - .savestate_start_ok ( savestate_start_ok ), - .savestate_start_err ( savestate_start_err ), - - .savestate_load ( savestate_load ), - .savestate_load_ack ( savestate_load_ack ), - .savestate_load_busy ( savestate_load_busy ), - .savestate_load_ok ( savestate_load_ok ), - .savestate_load_err ( savestate_load_err ), - - .osnotify_inmenu ( osnotify_inmenu ), - - .target_dataslot_read ( target_dataslot_read ), - .target_dataslot_write ( target_dataslot_write ), - .target_dataslot_getfile ( target_dataslot_getfile ), - .target_dataslot_openfile ( target_dataslot_openfile ), - - .target_dataslot_ack ( target_dataslot_ack ), - .target_dataslot_done ( target_dataslot_done ), - .target_dataslot_err ( target_dataslot_err ), - - .target_dataslot_id ( target_dataslot_id ), - .target_dataslot_slotoffset ( target_dataslot_slotoffset ), - .target_dataslot_bridgeaddr ( target_dataslot_bridgeaddr ), - .target_dataslot_length ( target_dataslot_length ), - - .target_buffer_param_struct ( target_buffer_param_struct ), - .target_buffer_resp_struct ( target_buffer_resp_struct ), - - .datatable_addr ( datatable_addr ), - .datatable_wren ( datatable_wren ), - .datatable_data ( datatable_data ), - .datatable_q ( datatable_q ) - ); - - //! END OF APF ///////////////////////////////////////////////////////////// - - //! //////////////////////////////////////////////////////////////////////// - //! @ System Modules - //! //////////////////////////////////////////////////////////////////////// - - //! ------------------------------------------------------------------------ - //! APF Bridge Read Data - //! ------------------------------------------------------------------------ - wire [31:0] int_bridge_rd_data; - wire [31:0] nvm_bridge_rd_data, nvm_bridge_rd_data_s; - - wire [31:0] analogizer_bridge_rd_data; - - // Synchronize nvm_bridge_rd_data into clk_74a domain before usage - synch_3 sync_nvm(nvm_bridge_rd_data, nvm_bridge_rd_data_s, clk_74a); - - always_comb begin - casex(bridge_addr) - 32'h10000000: begin bridge_rd_data <= nvm_bridge_rd_data_s; end // HiScore/NVRAM/SRAM Save - 32'hF0000000: begin bridge_rd_data <= int_bridge_rd_data; end // Reset - 32'hF0000010: begin bridge_rd_data <= int_bridge_rd_data; end // Service Mode Switch - 32'hF1000000: begin bridge_rd_data <= int_bridge_rd_data; end // DIP Switches - 32'hF2000000: begin bridge_rd_data <= int_bridge_rd_data; end // Modifiers - 32'hF3000000: begin bridge_rd_data <= int_bridge_rd_data; end // A/V Filters - 32'hF4000000: begin bridge_rd_data <= int_bridge_rd_data; end // Extra DIP Switches - 32'hF8xxxxxx: begin bridge_rd_data <= cmd_bridge_rd_data; end // APF Bridge (Reserved) - 32'hFA000000: begin bridge_rd_data <= int_bridge_rd_data; end // Status Low [31:0] - 32'hFB000000: begin bridge_rd_data <= int_bridge_rd_data; end // Status High [63:32] - 32'hFE000000: begin bridge_rd_data <= {29'h0, mapper_info}; end - {ADDRESS_ANALOGIZER_CONFIG,24'h0}: begin - bridge_rd_data <= analogizer_bridge_rd_data; - end // Analogizer - default: begin bridge_rd_data <= 0; end - endcase - end - - //! ------------------------------------------------------------------------ - //! Pause Core (Analogue OS Menu/Module Request) - //! ------------------------------------------------------------------------ - wire pause_core, pause_req; - - pause_crtl core_pause - ( - .clk_sys ( clk_sys ), - .os_inmenu ( osnotify_inmenu ), - .pause_req ( pause_req ), - .pause_core ( pause_core ) - ); - - //! ------------------------------------------------------------------------ - //! Interact: Dip Switches, Modifiers, Filters and Reset - //! ------------------------------------------------------------------------ - wire [7:0] dip_sw0, dip_sw1, dip_sw2, dip_sw3; - wire [7:0] ext_sw0, ext_sw1, ext_sw2, ext_sw3; - wire [7:0] mod_sw0, mod_sw1, mod_sw2, mod_sw3; - wire [3:0] scnl_sw, smask_sw, afilter_sw, vol_att; - wire [63:0] status; - wire reset_sw, svc_sw; - - interact pocket_interact - ( - // Clocks and Reset - .clk_74a ( clk_74a ), - .clk_sync ( clk_sys ), - .reset_n ( reset_n ), - // Pocket Bridge - .bridge_addr ( bridge_addr ), - .bridge_wr ( bridge_wr ), - .bridge_wr_data ( bridge_wr_data ), - .bridge_rd ( bridge_rd ), - .bridge_rd_data ( int_bridge_rd_data ), - // Service Mode Switch - .svc_sw ( svc_sw ), - // DIP Switches - .dip_sw0 ( dip_sw0 ), - .dip_sw1 ( dip_sw1 ), - .dip_sw2 ( dip_sw2 ), - .dip_sw3 ( dip_sw3 ), - // Extra DIP Switches - .ext_sw0 ( ext_sw0 ), - .ext_sw1 ( ext_sw1 ), - .ext_sw2 ( ext_sw2 ), - .ext_sw3 ( ext_sw3 ), - // Modifiers - .mod_sw0 ( mod_sw0 ), - .mod_sw1 ( mod_sw1 ), - .mod_sw2 ( mod_sw2 ), - .mod_sw3 ( mod_sw3 ), - // Status (Legacy Support) - .status ( status ), - // Filters Switches - .scnl_sw ( scnl_sw ), - .smask_sw ( smask_sw ), - .afilter_sw ( afilter_sw ), - .vol_att ( vol_att ), - // Reset Switch - .reset_sw ( reset_sw ) - ); - - - logic ena_analogizer = 0; - - always @(posedge clk_74a) begin - if (bridge_wr && bridge_addr == 32'hf4000000) ena_analogizer <= bridge_wr_data[0]; - end - - //! ------------------------------------------------------------------------ - //! Audio - //! ------------------------------------------------------------------------ - wire [AUDIO_DW-1:0] core_snd_l, core_snd_r; // Audio Mono/Left/Right - - audio_mixer #(.DW(AUDIO_DW),.STEREO(STEREO)) pocket_audio_mixer - ( - // Clocks and Reset - .clk_74b ( clk_74b ), - .reset ( reset_sw ), - // Controls - .afilter_sw ( afilter_sw ), - .vol_att ( vol_att ), - .mix ( AUDIO_MIX ), - .pause_core ( pause_core ), - // Audio From Core - .is_signed ( AUDIO_S ), - .core_l ( core_snd_l ), - .core_r ( core_snd_r ), - // I2S - .audio_mclk ( audio_mclk ), - .audio_lrck ( audio_lrck ), - .audio_dac ( audio_dac ) - ); - - //! ------------------------------------------------------------------------ - //! Video - //! ------------------------------------------------------------------------ - wire [2:0] video_preset; // Video Preset Configuration - wire [BPP_R-1:0] core_r; // Video Red - wire [BPP_G-1:0] core_g; // Video Green - wire [BPP_B-1:0] core_b; // Video Blue - wire core_hs, core_hb; // Horizontal Sync/Blank - wire core_vs, core_vb; // Vertical Sync/Blank - wire core_de; // Display Enable - - assign core_de = ~(core_hb | core_vb); - - video_mixer #(.RW(BPP_R),.GW(BPP_G),.BW(BPP_B)) pocket_video_mixer - ( - // Clocks - .clk_74a ( clk_74a ), - .clk_sys ( clk_sys ), - .clk_vid ( clk_vid ), - .clk_vid_90deg ( clk_vid_90deg ), - // Input Controls - .video_preset ( video_preset ), - .scnl_sw ( scnl_sw ), - .smask_sw ( smask_sw ), - // Input Video from Core - .core_r ( core_r ), - .core_g ( core_g ), - .core_b ( core_b ), - .core_vs ( core_vs ), - .core_hs ( core_hs ), - .core_de ( core_de ), - // Output to Display - .video_rgb ( video_rgb ), - .video_vs ( video_vs ), - .video_hs ( video_hs ), - .video_de ( video_de ), - .video_rgb_clock ( video_rgb_clock ), - .video_rgb_clock_90 ( video_rgb_clock_90 ), - // Pocket Bridge Slots - .dataslot_requestwrite ( dataslot_requestwrite ), // [i] - .dataslot_requestwrite_id ( dataslot_requestwrite_id ), // [i] - .dataslot_allcomplete ( dataslot_allcomplete ), // [i] - // MPU -> FPGA (MPU Write to FPGA) - // Pocket Bridge - .bridge_endian_little ( bridge_endian_little ), // [i] - .bridge_addr ( bridge_addr ), // [i] - .bridge_wr ( bridge_wr ), // [i] - .bridge_wr_data ( bridge_wr_data ) // [i] - ); - - //! ------------------------------------------------------------------------ - //! Data I/O - //! ------------------------------------------------------------------------ - wire ioctl_download; - wire [15:0] ioctl_index; - wire ioctl_wr; - wire [DIO_AW-1:0] ioctl_addr; - wire [DIO_DW-1:0] ioctl_data; - - data_io #(.MASK(DIO_MASK),.AW(DIO_AW),.DW(DIO_DW),.DELAY(DIO_DELAY),.HOLD(DIO_HOLD)) pocket_data_io - ( - // Clocks and Reset - .clk_74a ( clk_74a ), - .clk_memory ( clk_sys ), - // Pocket Bridge Slots - .dataslot_requestwrite ( dataslot_requestwrite ), // [i] - .dataslot_requestwrite_id ( dataslot_requestwrite_id ), // [i] - .dataslot_allcomplete ( dataslot_allcomplete ), // [i] - // MPU -> FPGA (MPU Write to FPGA) - // Pocket Bridge - .bridge_endian_little ( bridge_endian_little ), // [i] - .bridge_addr ( bridge_addr ), // [i] - .bridge_wr ( bridge_wr ), // [i] - .bridge_wr_data ( bridge_wr_data ), // [i] - // Controller Interface - .ioctl_download ( ioctl_download ), // [o] - .ioctl_index ( ioctl_index ), // [o] - .ioctl_wr ( ioctl_wr ), // [o] - .ioctl_addr ( ioctl_addr ), // [o] - .ioctl_data ( ioctl_data ) // [o] - ); - - //! ------------------------------------------------------------------------ - //! Gamepad/Analog Stick - //! ------------------------------------------------------------------------ - // Player 1 - // - DPAD - wire p1_up, p1_down, p1_left, p1_right; - wire p1_btn_y, p1_btn_x, p1_btn_b, p1_btn_a; - wire p1_btn_l1, p1_btn_l2, p1_btn_l3; - wire p1_btn_r1, p1_btn_r2, p1_btn_r3; - wire p1_select, p1_start; - // - Analog - wire j1_up, j1_down, j1_left, j1_right; - wire [7:0] j1_lx, j1_ly, j1_rx, j1_ry; - - // Player 2 - // - DPAD - wire p2_up, p2_down, p2_left, p2_right; - wire p2_btn_y, p2_btn_x, p2_btn_b, p2_btn_a; - wire p2_btn_l1, p2_btn_l2, p2_btn_l3; - wire p2_btn_r1, p2_btn_r2, p2_btn_r3; - wire p2_select, p2_start; - // - Analog - wire j2_up, j2_down, j2_left, j2_right; - wire [7:0] j2_lx, j2_ly, j2_rx, j2_ry; - - // Single Player or Alternate 2 Players for Arcade - wire m_start1, m_start2; - wire m_coin1, m_coin2, m_coin; - wire m_up, m_down, m_left, m_right; - wire m_btn1, m_btn2, m_btn3, m_btn4; - wire m_btn5, m_btn6, m_btn7, m_btn8; - - gamepad #(.JOY_PADS(JOY_PADS),.JOY_ALT(JOY_ALT)) pocket_gamepad - ( - .clk_sys ( clk_sys ), - // Pocket PAD Interface - .cont1_key ( cont1_key ), .cont1_joy ( cont1_joy ), - .cont2_key ( cont2_key ), .cont2_joy ( cont2_joy ), - .cont3_key ( cont3_key ), .cont3_joy ( cont3_joy ), - .cont4_key ( cont4_key ), .cont4_joy ( cont4_joy ), - // Player 1 - .p1_up ( p1_up ), .p1_down ( p1_down ), - .p1_left ( p1_left ), .p1_right ( p1_right ), - .p1_y ( p1_btn_y ), .p1_x ( p1_btn_x ), - .p1_b ( p1_btn_b ), .p1_a ( p1_btn_a ), - .p1_l1 ( p1_btn_l1 ), .p1_r1 ( p1_btn_r1 ), - .p1_l2 ( p1_btn_l2 ), .p1_r2 ( p1_btn_r2 ), - .p1_l3 ( p1_btn_l3 ), .p1_r3 ( p1_btn_r3 ), - .p1_se ( p1_select ), .p1_st ( p1_start ), - .j1_up ( j1_up ), .j1_down ( j1_down ), - .j1_left ( j1_left ), .j1_right ( j1_right ), - .j1_lx ( j1_lx ), .j1_ly ( j1_ly ), - .j1_rx ( j1_rx ), .j1_ry ( j1_ry ), - // Player 2 - .p2_up ( p2_up ), .p2_down ( p2_down ), - .p2_left ( p2_left ), .p2_right ( p2_right ), - .p2_y ( p2_btn_y ), .p2_x ( p2_btn_x ), - .p2_b ( p2_btn_b ), .p2_a ( p2_btn_a ), - .p2_l1 ( p2_btn_l1 ), .p2_r1 ( p2_btn_r1 ), - .p2_l2 ( p2_btn_l2 ), .p2_r2 ( p2_btn_r2 ), - .p2_l3 ( p2_btn_l3 ), .p2_r3 ( p2_btn_r3 ), - .p2_se ( p2_select ), .p2_st ( p2_start ), - .j2_up ( j2_up ), .j2_down ( j2_down ), - .j2_left ( j2_left ), .j2_right ( j2_right ), - .j2_lx ( j2_lx ), .j2_ly ( j2_ly ), - .j2_rx ( j2_rx ), .j2_ry ( j2_ry ), - // Single Player or Alternate 2 Players for Arcade - .m_coin ( m_coin ), // Coinage P1 or P2 - .m_up ( m_up ), .m_down ( m_down ), // Up/Down - .m_left ( m_left ), .m_right ( m_right ), // Left/Right - .m_btn1 ( m_btn1 ), .m_btn4 ( m_btn4 ), // Y/X - .m_btn2 ( m_btn2 ), .m_btn3 ( m_btn3 ), // B/A - .m_btn5 ( m_btn5 ), .m_btn6 ( m_btn6 ), // L1/R1 - .m_btn7 ( m_btn7 ), .m_btn8 ( m_btn8 ), // L2/R2 - .m_coin1 ( m_coin1 ), .m_coin2 ( m_coin2 ), // P1/P2 Coin - .m_start1 ( m_start1 ), .m_start2 ( m_start2 ) // P1/P2 Start - ); - - //! ------------------------------------------------------------------------ - //! Clocks - //! ------------------------------------------------------------------------ - wire pll_core_locked, pll_core_locked_s; - wire clk_sys; // Core : 42.954536 Mhz - wire clk_vid; // Video: 5.369317 Mhz - wire clk_vid_90deg; // Video: 5.369317 Mhz @ 90deg Phase Shift - wire clk_ram; // SDRAM: 85.909072 Mhz - - core_pll core_pll - ( - .refclk ( clk_74a ), - .rst ( 0 ), - - .outclk_0 ( clk_sys ), - .outclk_1 ( clk_vid ), - .outclk_2 ( clk_vid_90deg ), - .outclk_3 ( clk_ram ), - - .locked ( pll_core_locked ) - ); - - // Synchronize pll_core_locked into clk_74a domain before usage - synch_3 sync_lck(pll_core_locked, pll_core_locked_s, clk_74a); - - //! ------------------------------------------------------------------------ - //! Keyboard - //! ------------------------------------------------------------------------ - wire [10:0] ps2_key; - - usb_keyboard u_usb_kbd - ( - .clk ( clk_sys ), - .reset ( reset_sw ), - .cont3_key ( cont3_key ), - .cont3_joy ( cont3_joy ), - .cont3_trig ( cont3_trig ), - .ps2_key ( ps2_key ) - ); - - //! ------------------------------------------------------------------------ - //! @ IP Core RTL - //! ------------------------------------------------------------------------ - wire [1:0] sdram_size = 2'h2; // 0 - none, 1 - 32MB, 2 - 64MB, 3 - 128MB - - reg [1:0] rom_enabled = 2'b00; - wire ioctl_isROMA = ioctl_download && ioctl_index == 16'h0; - wire ioctl_isROMB = ioctl_download && ioctl_index == 16'h1; - wire ioctl_isBIOS = ioctl_download && ioctl_index == 16'h2; - wire ioctl_isFWBIOS = ioctl_download && ioctl_index == 16'h3; - wire ioctl_isCAS = ioctl_download && ioctl_index == 16'h4; - - always @(posedge clk_sys) begin - if (svc_sw) begin // Reset & Detach ROM Cartridges - rom_enabled <= 2'b00; - end - else begin - if (ioctl_isROMA) begin rom_enabled[0] <= 1'b1; end - if (ioctl_isROMB) begin rom_enabled[1] <= 1'b1; end - end - end - - //! CLOCKS - reg ce_10m7 = 0; - reg ce_5m3 = 0; - - always @(posedge clk_sys) begin - reg [2:0] div; - - div <= div + 1'd1; - ce_10m7 <= !div[1:0]; - ce_5m3 <= !div[2:0]; - end - - //! RESET - reg [7:0] last_mapper = 8'h0; - always @(posedge clk_sys) begin - last_mapper <= dip_sw0; - end - - wire mapper_reset = last_mapper != dip_sw0; - wire msx_reset = ioctl_isROMA | ioctl_isROMB | ioctl_isBIOS | mapper_reset; - - //! CORE - wire hsync_n, vsync_n; - wire ioctl_waitROM; - wire [2:0] mapper_info; - - reg hs_o, vs_o; - always @(posedge clk_sys) begin - hs_o <= ~hsync_n; - if(~hs_o & ~hsync_n) begin - vs_o <= ~vsync_n; - end - end - - assign core_hs = hs_o; - assign core_vs = vs_o; - assign video_preset = (dip_sw1[1]) ? 3'd1 : 3'd0; - - wire [5:0] joy0 = { p1_btn_b, p1_btn_a, p1_up, p1_down, p1_left, p1_right }; - wire [5:0] joy1 = { p2_btn_b, p2_btn_a, p2_up, p2_down, p2_left, p2_right }; - - wire [10:0] joy_key = { p1_start, p1_select, p1_btn_r1, p1_btn_l1, p1_btn_x, p1_btn_y }; - wire [23:0] key_map = { mod_sw2, mod_sw1, mod_sw0 }; - wire [10:0] ps2_joy; - - joy2ps2 u_joy2key - ( - .clk ( clk_sys ), - .reset ( reset_sw ), - .enable ( dip_sw1[2] ), - .key_map ( key_map ), - .joy_key ( joy_key ), - .ps2_key ( ps2_joy ) - ); - - msx1 msx1 - ( - .clk ( clk_sys ), // [i] - .ce_10m7 ( ce_10m7 ), // [i] - .reset ( msx_reset | reset_sw ), // [i] - - .vdp_pal ( dip_sw1[0] ), // [i] - .border ( dip_sw1[1] ), // [i] - - .R ( core_r ), // [o] - .G ( core_g ), // [o] - .B ( core_b ), // [o] - .hsync_n ( hsync_n ), // [o] - .vsync_n ( vsync_n ), // [o] - .hblank ( core_hb ), // [o] - .vblank ( core_vb ), // [o] - - .audio ( core_snd_l ), // [o] - - .ps2_key ( ps2_key | ps2_joy ), // [i] - - .joy0 ( joy0 ), // [i] - .joy1 ( joy1 ), // [i] - - .ioctl_download ( ioctl_download ), // [i] - .ioctl_index ( ioctl_index[7:0] ), // [i] - .ioctl_wr ( ioctl_wr ), // [i] - .ioctl_addr ( ioctl_addr ), // [i] - .ioctl_dout ( ioctl_data ), // [i] - .ioctl_isROMA ( ioctl_isROMA ), // [i] - .ioctl_isROMB ( ioctl_isROMB ), // [i] - .ioctl_isBIOS ( ioctl_isBIOS ), // [i] - .ioctl_isFWBIOS ( ioctl_isFWBIOS ), // [i] - .ioctl_wait ( ioctl_waitROM ), // [o] - - .cas_motor ( /* CAS_motor */ ), // [o] - .cas_audio_in ( /* CAS_dout */ ), // [i] - - .rom_enabled ( rom_enabled ), // [i] - .slot_A ( dip_sw0[3:0] ), // [i] - .slot_B ( dip_sw0[7:4] ), // [i] - .mapper_info ( mapper_info ), // [o] - - .img_mounted ( /* img_mounted */ ), // signaling that new image has been mounted - .img_size ( /* img_size */ ), // size of image in bytes - .img_wp ( /* img_readonly */ ), // write protect - - .sd_lba ( /* sd_lba[0] */ ), - .sd_rd ( /* sd_rd */ ), - .sd_wr ( /* sd_wr */ ), - .sd_ack ( /* sd_ack */ ), - .sd_buff_addr ( /* sd_buff_addr */ ), - .sd_buff_dout ( /* sd_buff_dout */ ), - .sd_buff_din ( /* sd_buff_din[0] */ ), - .sd_buff_wr ( /* sd_buff_wr */ ), - - .sdram_dout ( sdram_dout ), - .sdram_din ( sdram_din ), - .sdram_addr ( sdram_addr ), - .sdram_we ( sdram_we ), - .sdram_rd ( sdram_rd ), - .sdram_ready ( sdram_ready ), - .sdram_size ( sdram_size ) - ); - - //! SDRAM - wire [7:0] sdram_dout; - wire [7:0] sdram_din; - wire [24:0] sdram_addr; - wire sdram_we; - wire sdram_rd; - wire sdram_ready; - - sdram sdram - ( - .init ( ~pll_core_locked_s ), - .clk ( clk_ram ), - - .SDRAM_DQ ( dram_dq ), - .SDRAM_A ( dram_a ), - .SDRAM_DQML ( dram_dqm[0] ), - .SDRAM_DQMH ( dram_dqm[1] ), - .SDRAM_BA ( dram_ba ), - .SDRAM_nCS ( ), - .SDRAM_nWE ( dram_we_n ), - .SDRAM_nRAS ( dram_ras_n ), - .SDRAM_nCAS ( dram_cas_n ), - .SDRAM_CKE ( dram_cke ), - .SDRAM_CLK ( dram_clk ), - - .dout ( sdram_dout ), - .din ( sdram_din ), - .addr ( sdram_addr ), - .we ( sdram_we ), - .rd ( sdram_rd ), - .ready ( sdram_ready ) - ); - - // TODO: Implement Cassette on PSRAM/SRAM instead of DDR - //! CAS load - // wire buff_mem_ready; - - // ddram buffer - // ( - // .reset ( reset_sw ), - // .we ( ioctl_isCAS && ioctl_wr ), - // .rd ( ~ioctl_isCAS && CAS_rd ), - // .addr ( ioctl_isCAS ? ioctl_addr[26:0] : CAS_addr ), - // .din ( ioctl_data ), - // .dout ( CAS_di ), - // .ready ( buff_mem_ready ), - // ); - - // wire CAS_rd; - // wire [26:0] CAS_addr; - // wire CAS_dout; - // wire [7:0] CAS_di; - // wire CAS_motor; - // wire CAS_rewind = status[13] | ioctl_isCAS | reset; - - // tape cass - // ( - // .clk ( clk_sys ), - // .ce_5m3 ( ce_5m3 ), - // .cas_out ( CAS_dout ), - // .ram_a ( CAS_addr ), - // .ram_di ( CAS_di ), - // .ram_rd ( CAS_rd ), - // .buff_mem_ready ( buff_mem_ready ), - // .play ( ~CAS_motor ), - // .rewind ( CAS_rewind ) - // ); - - - // ======================================================================== - // SNAC (Conf. A) PS/2 sobre cart_tran_pin30 (CLK) y cart_tran_pin31 (DATA) - // Solo recepcion: dir = 0 (los level-translators en modo cart->FPGA) - // ======================================================================== - logic ps2_clk_oe, ps2_dat_oe; - logic ps2_clk_out, ps2_dat_out; - logic ps2_clk_in, ps2_dat_in; - logic [10:0] snac_ps2_key; - - // --- Direccion de los translators: 0 = INPUT (leemos del teclado) - assign cart_tran_pin30_dir = ps2_clk_oe; // = 1'b0 constante - assign cart_tran_pin31_dir = ps2_dat_oe; // = 1'b0 constante - - // --- IMPRESCINDIBLE en pin30: habilitar el circuito del translator. - // Debe ir a '1' para que los level-translators e IO general - // puedan mover el pin. Si lo dejas bajo/debil, el pull GBC /RES - // se activa y el pin no funciona. - assign cart_pin30_pwroff_reset = (ena_analogizer) ? 1'b1 : 1'bz; - - // --- Como no conducimos, dejamos los inout en Z desde la FPGA. - // (dir=0 ya pone el translator en cart->FPGA; el 'z' evita - // que la FPGA pelee el bus si algun sintetizador lo tomara literal) - assign cart_tran_pin30 = (ena_analogizer) ? (ps2_clk_oe ? ps2_clk_out : 1'bz) : 1'bz; // -> queda 1'bz - assign cart_tran_pin31 = (ena_analogizer) ? (ps2_dat_oe ? ps2_dat_out : 1'bz) : 1'bz; // -> queda 1'bz - - // --- Lectura de las lineas hacia el decoder - assign ps2_clk_in = (ena_analogizer) ? cart_tran_pin30 : 1'b1; // CLK del teclado - assign ps2_dat_in = (ena_analogizer) ? cart_tran_pin31 : 1'b1; // DATA del teclado - - ps2_snac_decoder - #( - .CLK_HZ(5_369_317), //! Frecuencia de clk - . WD_US(120) //! Timeout de trama (us) para resync - ) - ps2_snac - ( - .clk(clk_vid), - .reset(msx_reset | reset_sw ), - // Interfaz hacia el transceptor SNAC (unidireccional + control de sentido) - .ps2_clk_in(ps2_clk_in), //! CLK leido del transceptor (modo RX) - .ps2_dat_in(ps2_dat_in), //! DATA leido del transceptor (modo RX) - .ps2_clk_oe(ps2_clk_oe), //! 1 = FPGA conduce CLK (aqui siempre 0) - .ps2_dat_oe(ps2_dat_oe), //! 1 = FPGA conduce DATA (aqui siempre 0) - .ps2_clk_out(ps2_clk_out ), //! valor a emitir si oe=1 (idle 1) - .ps2_dat_out(ps2_dat_out), //! valor a emitir si oe=1 (idle 1) - // Salida decodificada - .ps2_key(snac_ps2_key) //! {toggle, pressed, ext, sc[7:0]} - ); - -endmodule +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// SPDX-FileType: SOURCE +// SPDX-FileCopyrightText: (c) 2023, OpenGateware authors and contributors +//------------------------------------------------------------------------------ +// +// Copyright (c) 2023, Marcus Andrade +// Copyright (c) 2022, Analogue Enterprises Limited +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +//------------------------------------------------------------------------------ +// Platform Specific top-level +// Instantiated by the real top-level: apf_top +//------------------------------------------------------------------------------ + +`default_nettype none + +module core_top + #( + //! ------------------------------------------------------------------------ + //! System Configuration Parameters + //! ------------------------------------------------------------------------ + // Analogizer + parameter USE_ANALOGIZER = 1, //! Enable Support for Analogizer + // Memory + parameter USE_SDRAM = 1, //! Enable SDRAM + parameter USE_SRAM = 0, //! Enable SRAM + parameter USE_CRAM0 = 0, //! Enable Cellular RAM #1 + parameter USE_CRAM1 = 0, //! Enable Cellular RAM #2 + // Video + parameter BPP_R = 8, //! Bits Per Pixel Red + parameter BPP_G = 8, //! Bits Per Pixel Green + parameter BPP_B = 8, //! Bits Per Pixel Blue + // Audio + parameter AUDIO_DW = 16, //! Audio Bits + parameter AUDIO_S = 1, //! Signed Audio + parameter STEREO = 0, //! Stereo Output + parameter AUDIO_MIX = 0, //! [0] No Mix | [1] 25% | [2] 50% | [3] 100% (mono) + // Gamepad/Joystick + parameter JOY_PADS = 2, //! Total Number of Gamepads + parameter JOY_ALT = 1, //! 2 Players Alternate + // Data I/O - [MPU -> FPGA] + parameter DIO_MASK = 4'h0, //! Upper 4 bits of address + parameter DIO_AW = 27, //! Address Width + parameter DIO_DW = 8, //! Data Width (8 or 16 bits) + parameter DIO_DELAY = 7, //! Number of clock cycles to delay each write output + parameter DIO_HOLD = 4, //! Number of clock cycles to hold the ioctl_wr signal high + // HiScore I/O - [MPU <-> FPGA] + parameter HS_AW = 16, //! Max size of game RAM address for highscores + parameter HS_SW = 8, //! Max size of capture RAM For highscore data (default 8 = 256 bytes max) + parameter HS_CFG_AW = 2, //! Max size of RAM address for highscore.dat entries (default 4 = 16 entries max) + parameter HS_CFG_LW = 2, //! Max size of length for each highscore.dat entries (default 1 = 256 bytes max) + parameter HS_CONFIG = 2, //! Dataslot index for config transfer + parameter HS_DATA = 3, //! Dataslot index for save data transfer + parameter HS_NVM_SZ = 32'd93, //! Number bytes required for Save + parameter HS_MASK = 4'h1, //! Upper 4 bits of address + parameter HS_WR_DELAY = 4, //! Number of clock cycles to delay each write output + parameter HS_WR_HOLD = 1, //! Number of clock cycles to hold the nvram_wr signal high + parameter HS_RD_DELAY = 4, //! Number of clock cycles it takes for a read to complete + // Save I/O - [MPU <-> FPGA] + parameter SIO_MASK = 4'h1, //! Upper 4 bits of address + parameter SIO_AW = 27, //! Address Width + parameter SIO_DW = 8, //! Data Width (8 or 16 bits) + parameter SIO_WR_DELAY = 4, //! Number of clock cycles to delay each write output + parameter SIO_WR_HOLD = 1, //! Number of clock cycles to hold the nvram_wr signal high + parameter SIO_RD_DELAY = 4, //! Number of clock cycles it takes for a read to complete + parameter SIO_SAVE_IDX = 2 //! Dataslot index for save data transfer + ) ( + //! -------------------------------------------------------------------- + //! Clock Inputs 74.25mhz. + //! Not Phase Aligned, Treat These Domains as Asynchronous + //! -------------------------------------------------------------------- + input wire clk_74a, // mainclk1 + input wire clk_74b, // mainclk1 + + //! -------------------------------------------------------------------- + //! Cartridge Interface + //! -------------------------------------------------------------------- + // switches between 3.3v and 5v mechanically + // output enable for multibit translators controlled by pic32 + // GBA AD[15:8] + inout wire [7:0] cart_tran_bank2, + output wire cart_tran_bank2_dir, + // GBA AD[7:0] + inout wire [7:0] cart_tran_bank3, + output wire cart_tran_bank3_dir, + // GBA A[23:16] + inout wire [7:0] cart_tran_bank1, + output wire cart_tran_bank1_dir, + // GBA [7] PHI# + // GBA [6] WR# + // GBA [5] RD# + // GBA [4] CS1#/CS# + // [3:0] unwired + inout wire [7:4] cart_tran_bank0, + output wire cart_tran_bank0_dir, + // GBA CS2#/RES# + inout wire cart_tran_pin30, + output wire cart_tran_pin30_dir, + // when GBC cart is inserted, this signal when low or weak will pull GBC /RES low with a special circuit + // the goal is that when unconfigured, the FPGA weak pullups won't interfere. + // thus, if GBC cart is inserted, FPGA must drive this high in order to let the level translators + // and general IO drive this pin. + output wire cart_pin30_pwroff_reset, + // GBA IRQ/DRQ + inout wire cart_tran_pin31, + output wire cart_tran_pin31_dir, + + //! -------------------------------------------------------------------- + //! Infrared + //! -------------------------------------------------------------------- + input wire port_ir_rx, + output wire port_ir_tx, + output wire port_ir_rx_disable, + + //! -------------------------------------------------------------------- + //! GBA link port + //! -------------------------------------------------------------------- + inout wire port_tran_si, + output wire port_tran_si_dir, + inout wire port_tran_so, + output wire port_tran_so_dir, + inout wire port_tran_sck, + output wire port_tran_sck_dir, + inout wire port_tran_sd, + output wire port_tran_sd_dir, + + //! -------------------------------------------------------------------- + //! Cellular PSRAM 0 and 1, two chips (64mbit x2 dual die per chip) + //! -------------------------------------------------------------------- + output wire [21:16] cram0_a, + inout wire [15:0] cram0_dq, + input wire cram0_wait, + output wire cram0_clk, + output wire cram0_adv_n, + output wire cram0_cre, + output wire cram0_ce0_n, + output wire cram0_ce1_n, + output wire cram0_oe_n, + output wire cram0_we_n, + output wire cram0_ub_n, + output wire cram0_lb_n, + + output wire [21:16] cram1_a, + inout wire [15:0] cram1_dq, + input wire cram1_wait, + output wire cram1_clk, + output wire cram1_adv_n, + output wire cram1_cre, + output wire cram1_ce0_n, + output wire cram1_ce1_n, + output wire cram1_oe_n, + output wire cram1_we_n, + output wire cram1_ub_n, + output wire cram1_lb_n, + + //! -------------------------------------------------------------------- + //! SDRAM, 512mbit 16bit + //! -------------------------------------------------------------------- + output wire [12:0] dram_a, // Address bus + output wire [1:0] dram_ba, // Bank select (single bits) + inout wire [15:0] dram_dq, // Bidirectional data bus + output wire [1:0] dram_dqm, // High/low byte mask + output wire dram_clk, // Chip clock + output wire dram_cke, // Clock enable + output wire dram_ras_n, // Select row address (active low) + output wire dram_cas_n, // Select column address (active low) + output wire dram_we_n, // Write enable (active low) + + //! -------------------------------------------------------------------- + //! SRAM, 1mbit 16bit + //! -------------------------------------------------------------------- + output wire [16:0] sram_a, // Address bus + inout wire [15:0] sram_dq, // Bidirectional data bus + output wire sram_oe_n, // Output enable + output wire sram_we_n, // Write enable + output wire sram_ub_n, // Upper Byte Mask + output wire sram_lb_n, // Lower Byte Mask + + //! -------------------------------------------------------------------- + //! vblank driven by dock for sync in a certain mode + //! -------------------------------------------------------------------- + input wire vblank, + + //! -------------------------------------------------------------------- + //! I/O to 6515D breakout USB UART + //! -------------------------------------------------------------------- + output wire dbg_tx, + input wire dbg_rx, + + //! -------------------------------------------------------------------- + //! I/O pads near jtag connector user can solder to + //! -------------------------------------------------------------------- + output wire user1, + input wire user2, + + //! -------------------------------------------------------------------- + //! RFU internal i2c bus + //! -------------------------------------------------------------------- + inout wire aux_sda, + output wire aux_scl, + + //! -------------------------------------------------------------------- + //! RFU, do not use !!! + //! -------------------------------------------------------------------- + output wire vpll_feed, + + //! -------------------------------------------------------------------- + //! Logical Connections //////////////////////////////////////////////// + //! -------------------------------------------------------------------- + + //! -------------------------------------------------------------------- + //! Video Output to Scaler + //! -------------------------------------------------------------------- + output wire [23:0] video_rgb, + output wire video_rgb_clock, + output wire video_rgb_clock_90, + output wire video_hs, + output wire video_vs, + output wire video_de, + output wire video_skip, + + //! -------------------------------------------------------------------- + //! Audio + //! -------------------------------------------------------------------- + output wire audio_mclk, + output wire audio_lrck, + output wire audio_dac, + input wire audio_adc, + + //! -------------------------------------------------------------------- + //! Bridge Bus Connection (synchronous to clk_74a) + //! -------------------------------------------------------------------- + output wire bridge_endian_little, + input wire [31:0] bridge_addr, + input wire bridge_rd, + output reg [31:0] bridge_rd_data, + input wire bridge_wr, + input wire [31:0] bridge_wr_data, + + //! -------------------------------------------------------------------- + //! Controller Data + //! -------------------------------------------------------------------- + input wire [31:0] cont1_key, + input wire [31:0] cont2_key, + input wire [31:0] cont3_key, + input wire [31:0] cont4_key, + input wire [31:0] cont1_joy, + input wire [31:0] cont2_joy, + input wire [31:0] cont3_joy, + input wire [31:0] cont4_joy, + input wire [15:0] cont1_trig, + input wire [15:0] cont2_trig, + input wire [15:0] cont3_trig, + input wire [15:0] cont4_trig + ); + + //Analogizer settings + generate + if(USE_ANALOGIZER == 1) begin + localparam [7:0] ADDRESS_ANALOGIZER_CONFIG = 8'hF7; + end + endgenerate + + // not using the IR port, so turn off both the LED, and + // disable the receive circuit to save power + assign port_ir_tx = 0; + assign port_ir_rx_disable = 1; + + // bridge endianness + assign bridge_endian_little = 0; + + // cart is unused, so set all level translators accordingly + // directions are 0:IN, 1:OUT + generate + if(USE_ANALOGIZER == 0) begin + assign cart_tran_bank3 = 8'hzz; + assign cart_tran_bank3_dir = 1'b0; + assign cart_tran_bank2 = 8'hzz; + assign cart_tran_bank2_dir = 1'b0; + assign cart_tran_bank1 = 8'hzz; + assign cart_tran_bank1_dir = 1'b0; + assign cart_tran_bank0 = 4'hf; + assign cart_tran_bank0_dir = 1'b1; + assign cart_tran_pin30 = 1'b0; // reset or cs2, we let the hw control it by itself + assign cart_tran_pin30_dir = 1'bz; + assign cart_pin30_pwroff_reset = 1'b0; // hardware can control this + assign cart_tran_pin31 = 1'bz; // input + assign cart_tran_pin31_dir = 1'b0; // input + end + endgenerate + + // link port is input only + assign port_tran_so = 1'bz; + assign port_tran_so_dir = 1'b0; // SO is output only + assign port_tran_si = 1'bz; + assign port_tran_si_dir = 1'b0; // SI is input only + assign port_tran_sck = 1'bz; + assign port_tran_sck_dir = 1'b0; // clock direction can change + assign port_tran_sd = 1'bz; + assign port_tran_sd_dir = 1'b0; // SD is input and not used + + assign dbg_tx = 1'bZ; + assign user1 = 1'bZ; + assign aux_scl = 1'bZ; + assign vpll_feed = 1'bZ; + + + // Tie off the memory the pins not being used + generate + if(USE_CRAM0 == 0) begin + assign cram0_a = 'h0; + assign cram0_dq = {16{1'bZ}}; + assign cram0_clk = 0; + assign cram0_adv_n = 1; + assign cram0_cre = 0; + assign cram0_ce0_n = 1; + assign cram0_ce1_n = 1; + assign cram0_oe_n = 1; + assign cram0_we_n = 1; + assign cram0_ub_n = 1; + assign cram0_lb_n = 1; + end + + if(USE_CRAM1 == 0) begin + assign cram1_a = 'h0; + assign cram1_dq = {16{1'bZ}}; + assign cram1_clk = 0; + assign cram1_adv_n = 1; + assign cram1_cre = 0; + assign cram1_ce0_n = 1; + assign cram1_ce1_n = 1; + assign cram1_oe_n = 1; + assign cram1_we_n = 1; + assign cram1_ub_n = 1; + assign cram1_lb_n = 1; + end + + if(USE_SDRAM == 0) begin + assign dram_a = 'h0; + assign dram_ba = 'h0; + assign dram_dq = {16{1'bZ}}; + assign dram_dqm = 'h0; + assign dram_clk = 'h0; + assign dram_cke = 'h0; + assign dram_ras_n = 'h1; + assign dram_cas_n = 'h1; + assign dram_we_n = 'h1; + end + + if(USE_SRAM == 0) begin + assign sram_a = 'h0; + assign sram_dq = {16{1'bZ}}; + assign sram_oe_n = 1; + assign sram_we_n = 1; + assign sram_ub_n = 1; + assign sram_lb_n = 1; + end + endgenerate + + //! ------------------------------------------------------------------------ + //! Host/Target Command Handler + //! ------------------------------------------------------------------------ + wire reset_n; // driven by host commands, can be used as core-wide reset + wire [31:0] cmd_bridge_rd_data; + + // bridge host commands + // synchronous to clk_74a + wire status_boot_done = pll_core_locked_s; + wire status_setup_done = pll_core_locked_s; // rising edge triggers a target command + wire status_running = reset_n; // we are running as soon as reset_n goes high + + wire dataslot_requestread; + wire [15:0] dataslot_requestread_id; + wire dataslot_requestread_ack = 1; + wire dataslot_requestread_ok = 1; + + wire dataslot_requestwrite; + wire [15:0] dataslot_requestwrite_id; + wire [31:0] dataslot_requestwrite_size; + wire dataslot_requestwrite_ack = 1; + wire dataslot_requestwrite_ok = 1; + + wire dataslot_update; + wire [15:0] dataslot_update_id; + wire [31:0] dataslot_update_size; + + wire dataslot_allcomplete; + + wire [31:0] rtc_epoch_seconds; + wire [31:0] rtc_date_bcd; + wire [31:0] rtc_time_bcd; + wire rtc_valid; + + wire savestate_supported; + wire [31:0] savestate_addr; + wire [31:0] savestate_size; + wire [31:0] savestate_maxloadsize; + + wire savestate_start; + wire savestate_start_ack; + wire savestate_start_busy; + wire savestate_start_ok; + wire savestate_start_err; + + wire savestate_load; + wire savestate_load_ack; + wire savestate_load_busy; + wire savestate_load_ok; + wire savestate_load_err; + + wire osnotify_inmenu; + + // bridge target commands + // synchronous to clk_74a + reg target_dataslot_read; + reg target_dataslot_write; + reg target_dataslot_getfile; // require additional param/resp structs to be mapped + reg target_dataslot_openfile; // require additional param/resp structs to be mapped + + wire target_dataslot_ack; + wire target_dataslot_done; + wire [2:0] target_dataslot_err; + + reg [15:0] target_dataslot_id; + reg [31:0] target_dataslot_slotoffset; + reg [31:0] target_dataslot_bridgeaddr; + reg [31:0] target_dataslot_length; + + wire [31:0] target_buffer_param_struct; // to be mapped/implemented when using some Target commands + wire [31:0] target_buffer_resp_struct; // to be mapped/implemented when using some Target commands + + // bridge data slot access + // synchronous to clk_74a + wire [9:0] datatable_addr; + wire datatable_wren; + wire [31:0] datatable_data; + wire [31:0] datatable_q; + + core_bridge_cmd icb + ( + .clk ( clk_74a ), + .reset_n ( reset_n ), + + .bridge_endian_little ( bridge_endian_little ), + .bridge_addr ( bridge_addr ), + .bridge_rd ( bridge_rd ), + .bridge_rd_data ( cmd_bridge_rd_data ), + .bridge_wr ( bridge_wr ), + .bridge_wr_data ( bridge_wr_data ), + + .status_boot_done ( status_boot_done ), + .status_setup_done ( status_setup_done ), + .status_running ( status_running ), + + .dataslot_requestread ( dataslot_requestread ), + .dataslot_requestread_id ( dataslot_requestread_id ), + .dataslot_requestread_ack ( dataslot_requestread_ack ), + .dataslot_requestread_ok ( dataslot_requestread_ok ), + + .dataslot_requestwrite ( dataslot_requestwrite ), + .dataslot_requestwrite_id ( dataslot_requestwrite_id ), + .dataslot_requestwrite_size ( dataslot_requestwrite_size ), + .dataslot_requestwrite_ack ( dataslot_requestwrite_ack ), + .dataslot_requestwrite_ok ( dataslot_requestwrite_ok ), + + .dataslot_update ( dataslot_update ), + .dataslot_update_id ( dataslot_update_id ), + .dataslot_update_size ( dataslot_update_size ), + + .dataslot_allcomplete ( dataslot_allcomplete ), + + .rtc_epoch_seconds ( rtc_epoch_seconds ), + .rtc_date_bcd ( rtc_date_bcd ), + .rtc_time_bcd ( rtc_time_bcd ), + .rtc_valid ( rtc_valid ), + + .savestate_supported ( savestate_supported ), + .savestate_addr ( savestate_addr ), + .savestate_size ( savestate_size ), + .savestate_maxloadsize ( savestate_maxloadsize ), + + .savestate_start ( savestate_start ), + .savestate_start_ack ( savestate_start_ack ), + .savestate_start_busy ( savestate_start_busy ), + .savestate_start_ok ( savestate_start_ok ), + .savestate_start_err ( savestate_start_err ), + + .savestate_load ( savestate_load ), + .savestate_load_ack ( savestate_load_ack ), + .savestate_load_busy ( savestate_load_busy ), + .savestate_load_ok ( savestate_load_ok ), + .savestate_load_err ( savestate_load_err ), + + .osnotify_inmenu ( osnotify_inmenu ), + + .target_dataslot_read ( target_dataslot_read ), + .target_dataslot_write ( target_dataslot_write ), + .target_dataslot_getfile ( target_dataslot_getfile ), + .target_dataslot_openfile ( target_dataslot_openfile ), + + .target_dataslot_ack ( target_dataslot_ack ), + .target_dataslot_done ( target_dataslot_done ), + .target_dataslot_err ( target_dataslot_err ), + + .target_dataslot_id ( target_dataslot_id ), + .target_dataslot_slotoffset ( target_dataslot_slotoffset ), + .target_dataslot_bridgeaddr ( target_dataslot_bridgeaddr ), + .target_dataslot_length ( target_dataslot_length ), + + .target_buffer_param_struct ( target_buffer_param_struct ), + .target_buffer_resp_struct ( target_buffer_resp_struct ), + + .datatable_addr ( datatable_addr ), + .datatable_wren ( datatable_wren ), + .datatable_data ( datatable_data ), + .datatable_q ( datatable_q ) + ); + + //! END OF APF ///////////////////////////////////////////////////////////// + + //! //////////////////////////////////////////////////////////////////////// + //! @ System Modules + //! //////////////////////////////////////////////////////////////////////// + + //! ------------------------------------------------------------------------ + //! APF Bridge Read Data + //! ------------------------------------------------------------------------ + wire [31:0] int_bridge_rd_data; + wire [31:0] nvm_bridge_rd_data, nvm_bridge_rd_data_s; + + // Synchronize nvm_bridge_rd_data into clk_74a domain before usage + synch_3 sync_nvm(nvm_bridge_rd_data, nvm_bridge_rd_data_s, clk_74a); + + generate + if(USE_ANALOGIZER == 1) begin + wire [31:0] analogizer_bridge_rd_data; + + always_comb begin + casex(bridge_addr) + 32'h10000000: begin bridge_rd_data <= nvm_bridge_rd_data_s; end // HiScore/NVRAM/SRAM Save + 32'hF0000000: begin bridge_rd_data <= int_bridge_rd_data; end // Reset + 32'hF0000010: begin bridge_rd_data <= int_bridge_rd_data; end // Service Mode Switch + 32'hF1000000: begin bridge_rd_data <= int_bridge_rd_data; end // DIP Switches + 32'hF2000000: begin bridge_rd_data <= int_bridge_rd_data; end // Modifiers + 32'hF3000000: begin bridge_rd_data <= int_bridge_rd_data; end // A/V Filters + 32'hF4000000: begin bridge_rd_data <= int_bridge_rd_data; end // Extra DIP Switches + 32'hF8xxxxxx: begin bridge_rd_data <= cmd_bridge_rd_data; end // APF Bridge (Reserved) + 32'hFA000000: begin bridge_rd_data <= int_bridge_rd_data; end // Status Low [31:0] + 32'hFB000000: begin bridge_rd_data <= int_bridge_rd_data; end // Status High [63:32] + 32'hFE000000: begin bridge_rd_data <= {29'h0, mapper_info}; end + {ADDRESS_ANALOGIZER_CONFIG,24'h0}: begin bridge_rd_data <= analogizer_bridge_rd_data; end // Analogizer + default: begin bridge_rd_data <= 0; end + endcase + end + end else begin + always_comb begin + casex(bridge_addr) + 32'h10000000: begin bridge_rd_data <= nvm_bridge_rd_data_s; end // HiScore/NVRAM/SRAM Save + 32'hF0000000: begin bridge_rd_data <= int_bridge_rd_data; end // Reset + 32'hF0000010: begin bridge_rd_data <= int_bridge_rd_data; end // Service Mode Switch + 32'hF1000000: begin bridge_rd_data <= int_bridge_rd_data; end // DIP Switches + 32'hF2000000: begin bridge_rd_data <= int_bridge_rd_data; end // Modifiers + 32'hF3000000: begin bridge_rd_data <= int_bridge_rd_data; end // A/V Filters + 32'hF4000000: begin bridge_rd_data <= int_bridge_rd_data; end // Extra DIP Switches + 32'hF8xxxxxx: begin bridge_rd_data <= cmd_bridge_rd_data; end // APF Bridge (Reserved) + 32'hFA000000: begin bridge_rd_data <= int_bridge_rd_data; end // Status Low [31:0] + 32'hFB000000: begin bridge_rd_data <= int_bridge_rd_data; end // Status High [63:32] + 32'hFE000000: begin bridge_rd_data <= {29'h0, mapper_info}; end + default: begin bridge_rd_data <= 0; end + endcase + end + end + endgenerate + + //! ------------------------------------------------------------------------ + //! Pause Core (Analogue OS Menu/Module Request) + //! ------------------------------------------------------------------------ + wire pause_core, pause_req; + + pause_crtl core_pause + ( + .clk_sys ( clk_sys ), + .os_inmenu ( osnotify_inmenu ), + .pause_req ( pause_req ), + .pause_core ( pause_core ) + ); + + //! ------------------------------------------------------------------------ + //! Interact: Dip Switches, Modifiers, Filters and Reset + //! ------------------------------------------------------------------------ + wire [7:0] dip_sw0, dip_sw1, dip_sw2, dip_sw3; + wire [7:0] ext_sw0, ext_sw1, ext_sw2, ext_sw3; + wire [7:0] mod_sw0, mod_sw1, mod_sw2, mod_sw3; + wire [3:0] scnl_sw, smask_sw, afilter_sw, vol_att; + wire [63:0] status; + wire reset_sw, svc_sw; + + interact pocket_interact + ( + // Clocks and Reset + .clk_74a ( clk_74a ), + .clk_sync ( clk_sys ), + .reset_n ( reset_n ), + // Pocket Bridge + .bridge_addr ( bridge_addr ), + .bridge_wr ( bridge_wr ), + .bridge_wr_data ( bridge_wr_data ), + .bridge_rd ( bridge_rd ), + .bridge_rd_data ( int_bridge_rd_data ), + // Service Mode Switch + .svc_sw ( svc_sw ), + // DIP Switches + .dip_sw0 ( dip_sw0 ), + .dip_sw1 ( dip_sw1 ), + .dip_sw2 ( dip_sw2 ), + .dip_sw3 ( dip_sw3 ), + // Extra DIP Switches + .ext_sw0 ( ext_sw0 ), + .ext_sw1 ( ext_sw1 ), + .ext_sw2 ( ext_sw2 ), + .ext_sw3 ( ext_sw3 ), + // Modifiers + .mod_sw0 ( mod_sw0 ), + .mod_sw1 ( mod_sw1 ), + .mod_sw2 ( mod_sw2 ), + .mod_sw3 ( mod_sw3 ), + // Status (Legacy Support) + .status ( status ), + // Filters Switches + .scnl_sw ( scnl_sw ), + .smask_sw ( smask_sw ), + .afilter_sw ( afilter_sw ), + .vol_att ( vol_att ), + // Reset Switch + .reset_sw ( reset_sw ) + ); + + + //! ------------------------------------------------------------------------ + //! Audio + //! ------------------------------------------------------------------------ + wire [AUDIO_DW-1:0] core_snd_l, core_snd_r; // Audio Mono/Left/Right + + audio_mixer #(.DW(AUDIO_DW),.STEREO(STEREO)) pocket_audio_mixer + ( + // Clocks and Reset + .clk_74b ( clk_74b ), + .reset ( reset_sw ), + // Controls + .afilter_sw ( afilter_sw ), + .vol_att ( vol_att ), + .mix ( AUDIO_MIX ), + .pause_core ( pause_core ), + // Audio From Core + .is_signed ( AUDIO_S ), + .core_l ( core_snd_l ), + .core_r ( core_snd_r ), + // I2S + .audio_mclk ( audio_mclk ), + .audio_lrck ( audio_lrck ), + .audio_dac ( audio_dac ) + ); + + //! ------------------------------------------------------------------------ + //! Video + //! ------------------------------------------------------------------------ + wire [2:0] video_preset; // Video Preset Configuration + wire [BPP_R-1:0] core_r; // Video Red + wire [BPP_G-1:0] core_g; // Video Green + wire [BPP_B-1:0] core_b; // Video Blue + wire core_hs, core_hb; // Horizontal Sync/Blank + wire core_vs, core_vb; // Vertical Sync/Blank + wire core_de; // Display Enable + wire [23:0] pocket_video_rgb; + + assign core_de = ~(core_hb | core_vb); + + video_mixer #(.RW(BPP_R),.GW(BPP_G),.BW(BPP_B)) pocket_video_mixer + ( + // Clocks + .clk_74a ( clk_74a ), + .clk_sys ( clk_sys ), + .clk_vid ( clk_vid ), + .clk_vid_90deg ( clk_vid_90deg ), + // Input Controls + .video_preset ( video_preset ), + .scnl_sw ( scnl_sw ), + .smask_sw ( smask_sw ), + // Input Video from Core + .core_r ( core_r ), + .core_g ( core_g ), + .core_b ( core_b ), + .core_vs ( core_vs ), + .core_hs ( core_hs ), + .core_de ( core_de ), + // Output to Display + .video_rgb ( pocket_video_rgb ), + .video_vs ( video_vs ), + .video_hs ( video_hs ), + .video_de ( video_de ), + .video_rgb_clock ( video_rgb_clock ), + .video_rgb_clock_90 ( video_rgb_clock_90 ), + // Pocket Bridge Slots + .dataslot_requestwrite ( dataslot_requestwrite ), // [i] + .dataslot_requestwrite_id ( dataslot_requestwrite_id ), // [i] + .dataslot_allcomplete ( dataslot_allcomplete ), // [i] + // MPU -> FPGA (MPU Write to FPGA) + // Pocket Bridge + .bridge_endian_little ( bridge_endian_little ), // [i] + .bridge_addr ( bridge_addr ), // [i] + .bridge_wr ( bridge_wr ), // [i] + .bridge_wr_data ( bridge_wr_data ) // [i] + ); + + assign video_rgb = video_rgb_msx; + + //! ------------------------------------------------------------------------ + //! Data I/O + //! ------------------------------------------------------------------------ + wire ioctl_download; + wire [15:0] ioctl_index; + wire ioctl_wr; + wire [DIO_AW-1:0] ioctl_addr; + wire [DIO_DW-1:0] ioctl_data; + + data_io #(.MASK(DIO_MASK),.AW(DIO_AW),.DW(DIO_DW),.DELAY(DIO_DELAY),.HOLD(DIO_HOLD)) pocket_data_io + ( + // Clocks and Reset + .clk_74a ( clk_74a ), + .clk_memory ( clk_sys ), + // Pocket Bridge Slots + .dataslot_requestwrite ( dataslot_requestwrite ), // [i] + .dataslot_requestwrite_id ( dataslot_requestwrite_id ), // [i] + .dataslot_allcomplete ( dataslot_allcomplete ), // [i] + // MPU -> FPGA (MPU Write to FPGA) + // Pocket Bridge + .bridge_endian_little ( bridge_endian_little ), // [i] + .bridge_addr ( bridge_addr ), // [i] + .bridge_wr ( bridge_wr ), // [i] + .bridge_wr_data ( bridge_wr_data ), // [i] + // Controller Interface + .ioctl_download ( ioctl_download ), // [o] + .ioctl_index ( ioctl_index ), // [o] + .ioctl_wr ( ioctl_wr ), // [o] + .ioctl_addr ( ioctl_addr ), // [o] + .ioctl_data ( ioctl_data ) // [o] + ); + + //! ------------------------------------------------------------------------ + //! Gamepad/Analog Stick + //! ------------------------------------------------------------------------ + // Player 1 + // - DPAD + wire p1_up, p1_down, p1_left, p1_right; + wire p1_btn_y, p1_btn_x, p1_btn_b, p1_btn_a; + wire p1_btn_l1, p1_btn_l2, p1_btn_l3; + wire p1_btn_r1, p1_btn_r2, p1_btn_r3; + wire p1_select, p1_start; + // - Analog + wire j1_up, j1_down, j1_left, j1_right; + wire [7:0] j1_lx, j1_ly, j1_rx, j1_ry; + + // Player 2 + // - DPAD + wire p2_up, p2_down, p2_left, p2_right; + wire p2_btn_y, p2_btn_x, p2_btn_b, p2_btn_a; + wire p2_btn_l1, p2_btn_l2, p2_btn_l3; + wire p2_btn_r1, p2_btn_r2, p2_btn_r3; + wire p2_select, p2_start; + // - Analog + wire j2_up, j2_down, j2_left, j2_right; + wire [7:0] j2_lx, j2_ly, j2_rx, j2_ry; + + // Single Player or Alternate 2 Players for Arcade + wire m_start1, m_start2; + wire m_coin1, m_coin2, m_coin; + wire m_up, m_down, m_left, m_right; + wire m_btn1, m_btn2, m_btn3, m_btn4; + wire m_btn5, m_btn6, m_btn7, m_btn8; + + gamepad #(.JOY_PADS(JOY_PADS),.JOY_ALT(JOY_ALT)) pocket_gamepad + ( + .clk_sys ( clk_sys ), + // Pocket PAD Interface + .cont1_key ( cont1_key ), .cont1_joy ( cont1_joy ), + .cont2_key ( cont2_key ), .cont2_joy ( cont2_joy ), + .cont3_key ( cont3_key ), .cont3_joy ( cont3_joy ), + .cont4_key ( cont4_key ), .cont4_joy ( cont4_joy ), + // Player 1 + .p1_up ( p1_up ), .p1_down ( p1_down ), + .p1_left ( p1_left ), .p1_right ( p1_right ), + .p1_y ( p1_btn_y ), .p1_x ( p1_btn_x ), + .p1_b ( p1_btn_b ), .p1_a ( p1_btn_a ), + .p1_l1 ( p1_btn_l1 ), .p1_r1 ( p1_btn_r1 ), + .p1_l2 ( p1_btn_l2 ), .p1_r2 ( p1_btn_r2 ), + .p1_l3 ( p1_btn_l3 ), .p1_r3 ( p1_btn_r3 ), + .p1_se ( p1_select ), .p1_st ( p1_start ), + .j1_up ( j1_up ), .j1_down ( j1_down ), + .j1_left ( j1_left ), .j1_right ( j1_right ), + .j1_lx ( j1_lx ), .j1_ly ( j1_ly ), + .j1_rx ( j1_rx ), .j1_ry ( j1_ry ), + // Player 2 + .p2_up ( p2_up ), .p2_down ( p2_down ), + .p2_left ( p2_left ), .p2_right ( p2_right ), + .p2_y ( p2_btn_y ), .p2_x ( p2_btn_x ), + .p2_b ( p2_btn_b ), .p2_a ( p2_btn_a ), + .p2_l1 ( p2_btn_l1 ), .p2_r1 ( p2_btn_r1 ), + .p2_l2 ( p2_btn_l2 ), .p2_r2 ( p2_btn_r2 ), + .p2_l3 ( p2_btn_l3 ), .p2_r3 ( p2_btn_r3 ), + .p2_se ( p2_select ), .p2_st ( p2_start ), + .j2_up ( j2_up ), .j2_down ( j2_down ), + .j2_left ( j2_left ), .j2_right ( j2_right ), + .j2_lx ( j2_lx ), .j2_ly ( j2_ly ), + .j2_rx ( j2_rx ), .j2_ry ( j2_ry ), + // Single Player or Alternate 2 Players for Arcade + .m_coin ( m_coin ), // Coinage P1 or P2 + .m_up ( m_up ), .m_down ( m_down ), // Up/Down + .m_left ( m_left ), .m_right ( m_right ), // Left/Right + .m_btn1 ( m_btn1 ), .m_btn4 ( m_btn4 ), // Y/X + .m_btn2 ( m_btn2 ), .m_btn3 ( m_btn3 ), // B/A + .m_btn5 ( m_btn5 ), .m_btn6 ( m_btn6 ), // L1/R1 + .m_btn7 ( m_btn7 ), .m_btn8 ( m_btn8 ), // L2/R2 + .m_coin1 ( m_coin1 ), .m_coin2 ( m_coin2 ), // P1/P2 Coin + .m_start1 ( m_start1 ), .m_start2 ( m_start2 ) // P1/P2 Start + ); + + //! ------------------------------------------------------------------------ + //! Clocks + //! ------------------------------------------------------------------------ + wire pll_core_locked, pll_core_locked_s; + wire clk_sys; // Core : 42.954536 Mhz + wire clk_vid; // Video: 5.369317 Mhz + wire clk_vid_90deg; // Video: 5.369317 Mhz @ 90deg Phase Shift + wire clk_ram; // SDRAM: 85.909072 Mhz + + core_pll core_pll + ( + .refclk ( clk_74a ), + .rst ( 0 ), + + .outclk_0 ( clk_sys ), + .outclk_1 ( clk_vid ), + .outclk_2 ( clk_vid_90deg ), + .outclk_3 ( clk_ram ), + + .locked ( pll_core_locked ) + ); + + // Synchronize pll_core_locked into clk_74a domain before usage + synch_3 sync_lck(pll_core_locked, pll_core_locked_s, clk_74a); + + //! ------------------------------------------------------------------------ + //! Keyboard + //! ------------------------------------------------------------------------ + wire [10:0] ps2_key; + wire [10:0] ps2_key_general; + + usb_keyboard u_usb_kbd + ( + .clk ( clk_sys ), + .reset ( reset_sw ), + .cont3_key ( cont3_key ), + .cont3_joy ( cont3_joy ), + .cont3_trig ( cont3_trig ), + .ps2_key ( ps2_key ) + ); + + //! ------------------------------------------------------------------------ + //! @ IP Core RTL + //! ------------------------------------------------------------------------ + wire [1:0] sdram_size = 2'h2; // 0 - none, 1 - 32MB, 2 - 64MB, 3 - 128MB + + reg [1:0] rom_enabled = 2'b00; + wire ioctl_isROMA = ioctl_download && ioctl_index == 16'h0; + wire ioctl_isROMB = ioctl_download && ioctl_index == 16'h1; + wire ioctl_isBIOS = ioctl_download && ioctl_index == 16'h2; + wire ioctl_isFWBIOS = ioctl_download && ioctl_index == 16'h3; + wire ioctl_isCAS = ioctl_download && ioctl_index == 16'h4; + + always @(posedge clk_sys) begin + if (svc_sw) begin // Reset & Detach ROM Cartridges + rom_enabled <= 2'b00; + end + else begin + if (ioctl_isROMA) begin rom_enabled[0] <= 1'b1; end + if (ioctl_isROMB) begin rom_enabled[1] <= 1'b1; end + end + end + + //! CLOCKS + reg ce_10m7 = 0; + reg ce_5m3 = 0; + + always @(posedge clk_sys) begin + reg [2:0] div; + + div <= div + 1'd1; + ce_10m7 <= !div[1:0]; + ce_5m3 <= !div[2:0]; + end + + //! RESET + reg [7:0] last_mapper = 8'h0; + always @(posedge clk_sys) begin + last_mapper <= dip_sw0; + end + + wire mapper_reset = last_mapper != dip_sw0; + wire msx_reset = ioctl_isROMA | ioctl_isROMB | ioctl_isBIOS | mapper_reset; + + //! CORE + wire hsync_n, vsync_n; + wire ioctl_waitROM; + wire [2:0] mapper_info; + + reg hs_o, vs_o; + always @(posedge clk_sys) begin + hs_o <= ~hsync_n; + if(~hs_o & ~hsync_n) begin + vs_o <= ~vsync_n; + end + end + + assign core_hs = hs_o; + assign core_vs = vs_o; + assign video_preset = (dip_sw1[1]) ? 3'd1 : 3'd0; + + wire [5:0] joy0; + wire [5:0] joy1 ; + wire [10:0] joy_key; + + generate + if(USE_ANALOGIZER == 0) begin + assign joy0 = { p1_btn_b, p1_btn_a, p1_up, p1_down, p1_left, p1_right }; + assign joy1 = { p2_btn_b, p2_btn_a, p2_up, p2_down, p2_left, p2_right }; + assign joy_key = { p1_start, p1_select, p1_btn_r1, p1_btn_l1, p1_btn_x, p1_btn_y }; + assign ps2_key_general = ps2_key | ps2_joy; + end + else begin + assign joy0 = { p1_controls[5],p1_controls[4],p1_controls[0],p1_controls[1],p1_controls[2],p1_controls[3]}; + assign joy1 = { p2_controls[5],p2_controls[4],p2_controls[0],p2_controls[1],p2_controls[2],p2_controls[3]}; + assign joy_key = { p1_controls[15],p1_controls[14],p1_controls[9],p1_controls[8],p1_controls[6],p1_controls[7]}; + assign ps2_key_general = ps2_key | ps2_joy | snac_ps2_key; + end + endgenerate + + wire [23:0] key_map = { mod_sw2, mod_sw1, mod_sw0 }; + + wire [10:0] ps2_joy; + + joy2ps2 u_joy2key + ( + .clk ( clk_sys ), + .reset ( reset_sw ), + .enable ( dip_sw1[2] ), + .key_map ( key_map ), + .joy_key ( joy_key ), + .ps2_key ( ps2_joy ) + ); + + msx1 msx1 + ( + .clk ( clk_sys ), // [i] + .ce_10m7 ( ce_10m7 ), // [i] + .reset ( msx_reset | reset_sw ), // [i] + + .vdp_pal ( dip_sw1[0] ), // [i] + .border ( dip_sw1[1] ), // [i] + + .R ( core_r ), // [o] + .G ( core_g ), // [o] + .B ( core_b ), // [o] + .hsync_n ( hsync_n ), // [o] + .vsync_n ( vsync_n ), // [o] + .hblank ( core_hb ), // [o] + .vblank ( core_vb ), // [o] + + .audio ( core_snd_l ), // [o] + + .ps2_key ( ps2_key_general ), // [i] + + .joy0 ( joy0 ), // [i] + .joy1 ( joy1 ), // [i] + + .ioctl_download ( ioctl_download ), // [i] + .ioctl_index ( ioctl_index[7:0] ), // [i] + .ioctl_wr ( ioctl_wr ), // [i] + .ioctl_addr ( ioctl_addr ), // [i] + .ioctl_dout ( ioctl_data ), // [i] + .ioctl_isROMA ( ioctl_isROMA ), // [i] + .ioctl_isROMB ( ioctl_isROMB ), // [i] + .ioctl_isBIOS ( ioctl_isBIOS ), // [i] + .ioctl_isFWBIOS ( ioctl_isFWBIOS ), // [i] + .ioctl_wait ( ioctl_waitROM ), // [o] + + .cas_motor ( /* CAS_motor */ ), // [o] + .cas_audio_in ( /* CAS_dout */ ), // [i] + + .rom_enabled ( rom_enabled ), // [i] + .slot_A ( dip_sw0[3:0] ), // [i] + .slot_B ( dip_sw0[7:4] ), // [i] + .mapper_info ( mapper_info ), // [o] + + .img_mounted ( /* img_mounted */ ), // signaling that new image has been mounted + .img_size ( /* img_size */ ), // size of image in bytes + .img_wp ( /* img_readonly */ ), // write protect + + .sd_lba ( /* sd_lba[0] */ ), + .sd_rd ( /* sd_rd */ ), + .sd_wr ( /* sd_wr */ ), + .sd_ack ( /* sd_ack */ ), + .sd_buff_addr ( /* sd_buff_addr */ ), + .sd_buff_dout ( /* sd_buff_dout */ ), + .sd_buff_din ( /* sd_buff_din[0] */ ), + .sd_buff_wr ( /* sd_buff_wr */ ), + + .sdram_dout ( sdram_dout ), + .sdram_din ( sdram_din ), + .sdram_addr ( sdram_addr ), + .sdram_we ( sdram_we ), + .sdram_rd ( sdram_rd ), + .sdram_ready ( sdram_ready ), + .sdram_size ( sdram_size ) + ); + + //! SDRAM + wire [7:0] sdram_dout; + wire [7:0] sdram_din; + wire [24:0] sdram_addr; + wire sdram_we; + wire sdram_rd; + wire sdram_ready; + + sdram sdram + ( + .init ( ~pll_core_locked_s ), + .clk ( clk_ram ), + + .SDRAM_DQ ( dram_dq ), + .SDRAM_A ( dram_a ), + .SDRAM_DQML ( dram_dqm[0] ), + .SDRAM_DQMH ( dram_dqm[1] ), + .SDRAM_BA ( dram_ba ), + .SDRAM_nCS ( ), + .SDRAM_nWE ( dram_we_n ), + .SDRAM_nRAS ( dram_ras_n ), + .SDRAM_nCAS ( dram_cas_n ), + .SDRAM_CKE ( dram_cke ), + .SDRAM_CLK ( dram_clk ), + + .dout ( sdram_dout ), + .din ( sdram_din ), + .addr ( sdram_addr ), + .we ( sdram_we ), + .rd ( sdram_rd ), + .ready ( sdram_ready ) + ); + + // TODO: Implement Cassette on PSRAM/SRAM instead of DDR + //! CAS load + // wire buff_mem_ready; + + // ddram buffer + // ( + // .reset ( reset_sw ), + // .we ( ioctl_isCAS && ioctl_wr ), + // .rd ( ~ioctl_isCAS && CAS_rd ), + // .addr ( ioctl_isCAS ? ioctl_addr[26:0] : CAS_addr ), + // .din ( ioctl_data ), + // .dout ( CAS_di ), + // .ready ( buff_mem_ready ), + // ); + + // wire CAS_rd; + // wire [26:0] CAS_addr; + // wire CAS_dout; + // wire [7:0] CAS_di; + // wire CAS_motor; + // wire CAS_rewind = status[13] | ioctl_isCAS | reset; + + // tape cass + // ( + // .clk ( clk_sys ), + // .ce_5m3 ( ce_5m3 ), + // .cas_out ( CAS_dout ), + // .ram_a ( CAS_addr ), + // .ram_di ( CAS_di ), + // .ram_rd ( CAS_rd ), + // .buff_mem_ready ( buff_mem_ready ), + // .play ( ~CAS_motor ), + // .rewind ( CAS_rewind ) + // ); + + + /*[ANALOGIZER_HOOK_BEGIN]*/ + generate + if(USE_ANALOGIZER == 1) begin + logic [7:0] snac_ps2_code; + logic snac_ps2_code_new; + logic [10:0] snac_ps2_key; + + ps2_to_key #( + .STROBE_TOGGLE (1'b0), + .HANDLE_PAUSE (1'b1) + ) u_ps2_to_key ( + .clk (clk_sys), + .reset (msx_reset | reset_sw), + .enable (analogizer_ena), + .ps2_code_new (snac_ps2_code_new), + .ps2_code (snac_ps2_code), + .ps2_key (snac_ps2_key) + ); + + wire analogizer_ena; + wire [3:0] analogizer_video_type; + wire [4:0] snac_game_cont_type; + wire [3:0] snac_cont_assignment; + wire pocket_blank_screen; + + //create aditional switch to blank Pocket screen. + wire [23:0] video_rgb_msx; + assign video_rgb_msx = (pocket_blank_screen && analogizer_ena) ? 24'h000000: pocket_video_rgb; + + //switch between Analogizer SNAC and Pocket Controls for P1-P2 + wire [15:0] p1_btn; + wire [15:0] p2_btn; + wire [31:0] p1_joy; + wire [31:0] p2_joy; + reg [31:0] p1_joystick; + reg [31:0] p2_joystick; + reg [15:0] p1_controls; + reg [15:0] p2_controls; + + wire snac_is_analog = (snac_game_cont_type == 5'h12) || (snac_game_cont_type == 5'h13); + + //! Player 1 --------------------------------------------------------------------------- + reg snac_p1_up, snac_p1_down, snac_p1_left, snac_p1_right; + wire snac_p1_up_analog, snac_p1_down_analog, snac_p1_left_analog, snac_p1_right_analog; + //using left analog joypad + assign snac_p1_up_analog = (p1_joy[15:8] < 8'h40) ? 1'b1 : 1'b0; //analog range UP 0x00 Idle 0x7F DOWN 0xFF, DEADZONE +- 0x15 + assign snac_p1_down_analog = (p1_joy[15:8] > 8'hC0) ? 1'b1 : 1'b0; + assign snac_p1_left_analog = (p1_joy[7:0] < 8'h40) ? 1'b1 : 1'b0; //analog range LEFT 0x00 Idle 0x7F RIGHT 0xFF, DEADZONE +- 0x15 + assign snac_p1_right_analog = (p1_joy[7:0] > 8'hC0) ? 1'b1 : 1'b0; + + always @(posedge clk_74a) begin + snac_p1_up <= (snac_is_analog) ? snac_p1_up_analog : p1_btn[0]; + snac_p1_down <= (snac_is_analog) ? snac_p1_down_analog : p1_btn[1]; + snac_p1_left <= (snac_is_analog) ? snac_p1_left_analog : p1_btn[2]; + snac_p1_right <= (snac_is_analog) ? snac_p1_right_analog : p1_btn[3]; + end + //! Player 2 --------------------------------------------------------------------------- + reg snac_p2_up, snac_p2_down, snac_p2_left, snac_p2_right; + wire snac_p2_up_analog, snac_p2_down_analog, snac_p2_left_analog, snac_p2_right_analog; + //using left analog joypad + assign snac_p2_up_analog = (p2_joy[15:8] < 8'h40) ? 1'b1 : 1'b0; //analog range UP 0x00 Idle 0x7F DOWN 0xFF, DEADZONE +- 0x15 + assign snac_p2_down_analog = (p2_joy[15:8] > 8'hC0) ? 1'b1 : 1'b0; + assign snac_p2_left_analog = (p2_joy[7:0] < 8'h40) ? 1'b1 : 1'b0; //analog range LEFT 0x00 Idle 0x7F RIGHT 0xFF, DEADZONE +- 0x15 + assign snac_p2_right_analog = (p2_joy[7:0] > 8'hC0) ? 1'b1 : 1'b0; + + always @(posedge clk_74a) begin + snac_p2_up <= (snac_is_analog) ? snac_p2_up_analog : p2_btn[0]; + snac_p2_down <= (snac_is_analog) ? snac_p2_down_analog : p2_btn[1]; + snac_p2_left <= (snac_is_analog) ? snac_p2_left_analog : p2_btn[2]; + snac_p2_right <= (snac_is_analog) ? snac_p2_right_analog : p2_btn[3]; + end + always @(posedge clk_74a) begin + reg [31:0] p1_pocket_btn, p1_pocket_joy; + reg [31:0] p2_pocket_btn, p2_pocket_joy; + + if((snac_game_cont_type == 5'h0) || !analogizer_ena) begin //SNAC is disabled + //if((snac_game_cont_type == 5'h0)) begin //SNAC is disabled + p1_controls <= cont1_key; + p2_controls <= cont2_key; + end + else begin + case(snac_cont_assignment[1:0]) + 2'h0: begin //SNAC P1 -> Pocket P1 + p1_controls <= {p1_btn[15:4],snac_p1_right,snac_p1_left,snac_p1_down,snac_p1_up}; + p2_controls <= cont1_key; + end + 2'h1: begin //SNAC P1 -> Pocket P2 + p1_controls <= cont1_key; + p2_controls <= p1_btn; + end + 2'h2: begin //SNAC P1 -> Pocket P1, SNAC P2 -> Pocket P2 + p1_controls <= {p1_btn[15:4],snac_p1_right,snac_p1_left,snac_p1_down,snac_p1_up}; + p2_controls <= {p2_btn[15:4],snac_p2_right,snac_p2_left,snac_p2_down,snac_p2_up}; + end + 2'h3: begin //SNAC P1 -> Pocket P2, SNAC P2 -> Pocket P1 + p1_controls <= {p2_btn[15:4],snac_p2_right,snac_p2_left,snac_p2_down,snac_p2_up}; + p2_controls <= {p1_btn[15:4],snac_p1_right,snac_p1_left,snac_p1_down,snac_p1_up}; + end + default: begin + p1_controls <= cont1_key; + p2_controls <= cont2_key; + end + endcase + end + end + + wire [15:0] p1_btn_CK; + wire [15:0] p2_btn_CK; + wire [31:0] p1_joy_CK; + wire [31:0] p2_joy_CK; + + synch_3 #( + .WIDTH(16) + ) p1b_s ( + p1_btn_CK, + p1_btn, + clk_74a + ); + + synch_3 #( + .WIDTH(16) + ) p2b_s ( + p2_btn_CK, + p2_btn, + clk_74a + ); + + synch_3 #( + .WIDTH(32) + ) p3b_s ( + p1_joy_CK, + p1_joy, + clk_74a + ); + + synch_3 #( + .WIDTH(32) + ) p4b_s ( + p2_joy_CK, + p2_joy, + clk_74a + ); + + + // Video Y/C Encoder settings + // Follows the Mike Simone Y/C encoder settings: + // https://github.com/MikeS11/MiSTerFPGA_YC_Encoder + // SET PAL and NTSC TIMING and pass through status bits. ** YC must be enabled in the qsf file ** + wire [39:0] CHROMA_PHASE_INC; + wire [26:0] COLORBURST_RANGE; + + wire PALFLAG; + + parameter NTSC_REF = 3.579545; + parameter PAL_REF = 4.43361875; + + // Parameters to be modifed + parameter CLK_VIDEO_NTSC = 42.954545; // Must be filled E.g XX.X Hz - CLK_VIDEO + parameter CLK_VIDEO_PAL = 42.954545; // Must be filled E.g XX.X Hz - CLK_VIDEO + + localparam [39:0] NTSC_PHASE_INC1 = 40'd91625958316; // ((NTSC_REF * 2^40) / CLK_VIDEO_NTSC) + localparam [39:0] PAL_PHASE_INC1 = 40'd113487766399; // ((PAL_REF * 2^40) / CLK_VIDEO_PAL) + + localparam [6:0] COLORBURST_START1 = (3.7 * (CLK_VIDEO_NTSC/NTSC_REF)); + localparam [9:0] COLORBURST_NTSC_END1 = (9 * (CLK_VIDEO_NTSC/NTSC_REF)) + COLORBURST_START1; + localparam [9:0] COLORBURST_PAL_END1 = (10 * (CLK_VIDEO_PAL/PAL_REF)) + COLORBURST_START1; + + assign PALFLAG = dip_sw1[0]; + + assign CHROMA_PHASE_INC = PALFLAG ? PAL_PHASE_INC1 : NTSC_PHASE_INC1; + assign COLORBURST_RANGE = {COLORBURST_START1, COLORBURST_NTSC_END1, COLORBURST_PAL_END1}; + + wire busy; + + openFPGA_Pocket_Analogizer #(.MASTER_CLK_FREQ(42_954_545), .LINE_LENGTH(290), .ADDRESS_ANALOGIZER_CONFIG(ADDRESS_ANALOGIZER_CONFIG)) analogizer ( + .clk_74a(clk_74a), + .i_clk(clk_sys), + .i_rst_apf(msx_reset | reset_sw), //i_rst_apf is active high + .i_rst_core(msx_reset | reset_sw), //i_rst_core is active high + + //Video interface + .video_clk(clk_sys), + .R(core_r), + .G(core_g), + .B(core_b), + .Hblank(core_hb), + .Vblank(core_vb), + .Hsync(~hsync_n), //composite SYNC on HSync. + .Vsync(~vsync_n), + + //openFPGA Bridge interface + .bridge_endian_little(bridge_endian_little), + .bridge_addr(bridge_addr), + .bridge_rd(bridge_rd), + .analogizer_bridge_rd_data(analogizer_bridge_rd_data), + .bridge_wr(bridge_wr), + .bridge_wr_data(bridge_wr_data), + + //Analogizer settings + .analogizer_ena_out(analogizer_ena), + .snac_game_cont_type_out(snac_game_cont_type), + .snac_cont_assignment_out(snac_cont_assignment), + .analogizer_video_type_out(analogizer_video_type), + .SC_fx_out(), + .pocket_blank_screen_out(pocket_blank_screen), + .analogizer_osd_out(), + + //Video Y/C Encoder interface + .CHROMA_PHASE_INC(CHROMA_PHASE_INC), + .COLORBURST_RANGE(COLORBURST_RANGE), + .CHROMA_ADD(0), + .CHROMA_MUL(0), + .PALFLAG(PALFLAG), + //Video SVGA Scandoubler interface + .ce_pix(ce_10m7), + .scandoubler(1'b1), //logic for disable/enable the scandoubler + //SNAC interface + .p1_btn_state(p1_btn_CK), + .p1_joy_state(p1_joy_CK), + .p2_btn_state(p2_btn_CK), + .p2_joy_state(p2_joy_CK), + .p3_btn_state(), + .p4_btn_state(), + .busy(busy), + //Pocket Analogizer IO interface to the Pocket cartridge port + .cart_tran_bank2(cart_tran_bank2), + .cart_tran_bank2_dir(cart_tran_bank2_dir), + .cart_tran_bank3(cart_tran_bank3), + .cart_tran_bank3_dir(cart_tran_bank3_dir), + .cart_tran_bank1(cart_tran_bank1), + .cart_tran_bank1_dir(cart_tran_bank1_dir), + .cart_tran_bank0(cart_tran_bank0), + .cart_tran_bank0_dir(cart_tran_bank0_dir), + .cart_tran_pin30(cart_tran_pin30), + .cart_tran_pin30_dir(cart_tran_pin30_dir), + .cart_pin30_pwroff_reset(cart_pin30_pwroff_reset), + .cart_tran_pin31(cart_tran_pin31), + .cart_tran_pin31_dir(cart_tran_pin31_dir), + //debug + .o_stb(), + .o_ps2_code_new(snac_ps2_code_new), + .o_ps2_code(snac_ps2_code) + ); + end + endgenerate + /*[ANALOGIZER_HOOK_END]*/ + +endmodule diff --git a/target/pocket/debounce.vhd b/target/pocket/debounce.vhd new file mode 100644 index 0000000..94a9388 --- /dev/null +++ b/target/pocket/debounce.vhd @@ -0,0 +1,58 @@ +-------------------------------------------------------------------------------- +-- +-- FileName: debounce.vhd +-- Dependencies: none +-- Design Software: Quartus II 32-bit Version 11.1 Build 173 SJ Full Version +-- +-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY +-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY +-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL +-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF +-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS +-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), +-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. +-- +-- Version History +-- Version 1.0 3/26/2012 Scott Larson +-- Initial Public Release +-- +-------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.all; +USE ieee.std_logic_unsigned.all; + +ENTITY debounce IS + GENERIC( + counter_size : INTEGER := 19); --counter size (19 bits gives 10.5ms with 50MHz clock) + PORT( + clk : IN STD_LOGIC; --input clock + button : IN STD_LOGIC; --input signal to be debounced + result : OUT STD_LOGIC); --debounced signal +END debounce; + +ARCHITECTURE logic OF debounce IS + SIGNAL flipflops : STD_LOGIC_VECTOR(1 DOWNTO 0); --input flip flops + SIGNAL counter_set : STD_LOGIC; --sync reset to zero + SIGNAL counter_out : STD_LOGIC_VECTOR(counter_size DOWNTO 0) := (OTHERS => '0'); --counter output +BEGIN + + counter_set <= flipflops(0) xor flipflops(1); --determine when to start/reset counter + + PROCESS(clk) + BEGIN + IF(clk'EVENT and clk = '1') THEN + flipflops(0) <= button; + flipflops(1) <= flipflops(0); + If(counter_set = '1') THEN --reset counter because input is changing + counter_out <= (OTHERS => '0'); + ELSIF(counter_out(counter_size) = '0') THEN --stable input time is not yet met + counter_out <= counter_out + 1; + ELSE --stable input time is met + result <= flipflops(1); + END IF; + END IF; + END PROCESS; +END logic; diff --git a/target/pocket/ps2_host.sv b/target/pocket/ps2_host.sv index 98823d9..97dfeb0 100644 --- a/target/pocket/ps2_host.sv +++ b/target/pocket/ps2_host.sv @@ -1,206 +1,206 @@ -// ===================================================================== -// ps2_host.sv -// Bidirectional PS/2 host controller for open-collector lines driven -// through tri-state (dir-controlled) FPGA pins, e.g. Analogue Pocket -// cart pins 30/31 via the Analogizer SNAC harness. -// -// The module NEVER drives a line high. Each line is only ever: -// released -> *_oe = 0 (pin = input / Hi-Z, external pull-up -> '1') -// driven low -> *_oe = 1 (pin = output, data hard-wired to 1'b0) -// -// Wiring in core_top (verify APF dir polarity: here 1 = OUTPUT): -// assign cart_tran_pin30 = 1'b0; -// assign cart_tran_pin30_dir = ps2_clk_oe; // 1 => drive '0' -// assign ps2_clk_i = cart_tran_pin30; // reads pin when Hi-Z -// assign cart_tran_pin31 = 1'b0; -// assign cart_tran_pin31_dir = ps2_dat_oe; -// assign ps2_dat_i = cart_tran_pin31; -// // Also gate with cart_pin30_pwroff_reset as needed. -// -// Frame format: -// device->host : start(0) d0..d7(LSB) parity(odd) stop(1) -// host->device : inhibit CLK >=100us, DATA low (start), release CLK, -// device clocks 8 data + parity + stop, then drives ACK. -// ===================================================================== -module ps2_host #( - parameter int CLK_HZ = 50_000_000 -)( - input logic clk, - input logic rst, // synchronous, active high - - // Open-collector line interface (to dir-controlled pins) - input logic ps2_clk_i, // raw pin value (valid when released) - input logic ps2_dat_i, - output logic ps2_clk_oe, // 1 => pull CLK low - output logic ps2_dat_oe, // 1 => pull DATA low - - // Receive (device -> host) - output logic [7:0] rx_data, - output logic rx_valid, // 1-cycle strobe - output logic rx_err, // 1-cycle strobe (parity/framing) - - // Transmit (host -> device) - input logic [7:0] tx_data, - input logic tx_send, // 1-cycle strobe to start - output logic tx_busy, - output logic tx_done, // 1-cycle strobe, ACK received - output logic tx_err // 1-cycle strobe, no ACK / timeout -); - - // ---------------- timing ---------------- - localparam int US = CLK_HZ / 1_000_000; - localparam int INHIBIT_CYC = US * 120; // ~120 us CLK-low inhibit - localparam int WATCHDOG_CYC= US * 200; // abort if line goes idle mid-frame - - // ---------------- input sync + debounce ---------------- - logic [1:0] clk_sync, dat_sync; - always_ff @(posedge clk) begin - clk_sync <= {clk_sync[0], ps2_clk_i}; - dat_sync <= {dat_sync[0], ps2_dat_i}; - end - wire clk_s = clk_sync[1]; - wire dat_bit = dat_sync[1]; - - localparam int FILT = 4; - logic [FILT-1:0] clk_filt; - logic clk_stable, clk_stable_d; - always_ff @(posedge clk) begin - clk_filt <= {clk_filt[FILT-2:0], clk_s}; - if (&clk_filt) clk_stable <= 1'b1; - else if (~|clk_filt) clk_stable <= 1'b0; - clk_stable_d <= clk_stable; - end - wire clk_fedge = clk_stable_d & ~clk_stable; - wire clk_redge = ~clk_stable_d & clk_stable; - - // ---------------- FSM ---------------- - typedef enum logic [3:0] { - S_IDLE, RX_BITS, - TX_INHIBIT, TX_BITS, TX_STOP, TX_ACK - } state_t; - - state_t state; - logic [3:0] bitcnt; - logic [7:0] rxbuf; - logic rx_par; - logic [8:0] tx_shift; // {parity, d7..d0}, shifted out from bit0 - logic [31:0] timer; - - always_ff @(posedge clk) begin - // default strobes low - rx_valid <= 1'b0; - rx_err <= 1'b0; - tx_done <= 1'b0; - tx_err <= 1'b0; - - if (rst) begin - state <= S_IDLE; - ps2_clk_oe <= 1'b0; - ps2_dat_oe <= 1'b0; - tx_busy <= 1'b0; - bitcnt <= '0; - timer <= '0; - end else begin - case (state) - // -------------------------------------------------- IDLE - S_IDLE: begin - ps2_clk_oe <= 1'b0; - ps2_dat_oe <= 1'b0; - tx_busy <= 1'b0; - bitcnt <= '0; - if (tx_send) begin - tx_busy <= 1'b1; - ps2_clk_oe <= 1'b1; // begin inhibit - timer <= INHIBIT_CYC; - tx_shift <= {~(^tx_data), tx_data}; // odd parity - state <= TX_INHIBIT; - end else if (clk_fedge && (dat_bit == 1'b0)) begin - // start bit of an incoming frame - bitcnt <= 4'd0; - timer <= WATCHDOG_CYC; - state <= RX_BITS; - end - end - // -------------------------------------------------- RX - RX_BITS: begin - // watchdog: reset while CLK toggles, abort if idle too long - if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; - else if (timer != 0) timer <= timer - 1; - - if (timer == 0) begin - rx_err <= 1'b1; - state <= S_IDLE; - end else if (clk_fedge) begin - case (bitcnt) - 4'd0,4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7: - rxbuf[bitcnt[2:0]] <= dat_bit; - 4'd8: rx_par <= dat_bit; // parity - default: ; // 4'd9 = stop - endcase - bitcnt <= bitcnt + 4'd1; - if (bitcnt == 4'd9) begin // stop bit now on dat_bit - // odd parity: XOR of 8 data + parity must be 1; stop==1 - if ((^{rxbuf, rx_par}) == 1'b1 && dat_bit == 1'b1) begin - rx_data <= rxbuf; - rx_valid <= 1'b1; - end else begin - rx_err <= 1'b1; - end - state <= S_IDLE; - end - end - end - // -------------------------------------------------- TX - TX_INHIBIT: begin - ps2_clk_oe <= 1'b1; // hold CLK low - if (timer != 0) timer <= timer - 1; - if (timer == 0) begin - ps2_dat_oe <= 1'b1; // DATA low = start/request - ps2_clk_oe <= 1'b0; // release CLK - bitcnt <= 4'd0; - timer <= WATCHDOG_CYC; - state <= TX_BITS; - end - end - TX_BITS: begin - if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; - else if (timer != 0) timer <= timer - 1; - - if (timer == 0) begin - ps2_dat_oe <= 1'b0; ps2_clk_oe <= 1'b0; - tx_err <= 1'b1; state <= S_IDLE; - end else if (clk_fedge) begin - ps2_dat_oe <= ~tx_shift[0]; // '0' => drive low, '1' => release - tx_shift <= {1'b0, tx_shift[8:1]}; - bitcnt <= bitcnt + 4'd1; - if (bitcnt == 4'd8) state <= TX_STOP; // presented d0..d7,parity - end - end - TX_STOP: begin - if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; - else if (timer != 0) timer <= timer - 1; - - if (timer == 0) begin - ps2_dat_oe <= 1'b0; tx_err <= 1'b1; state <= S_IDLE; - end else if (clk_fedge) begin - ps2_dat_oe <= 1'b0; // release DATA (stop) - state <= TX_ACK; - end - end - TX_ACK: begin - if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; - else if (timer != 0) timer <= timer - 1; - - if (timer == 0) begin - tx_err <= 1'b1; state <= S_IDLE; - end else if (clk_fedge) begin - if (dat_bit == 1'b0) tx_done <= 1'b1; // device pulled DATA low = ACK - else tx_err <= 1'b1; - state <= S_IDLE; - end - end - default: state <= S_IDLE; - endcase - end - end +// ===================================================================== +// ps2_host.sv +// Bidirectional PS/2 host controller for open-collector lines driven +// through tri-state (dir-controlled) FPGA pins, e.g. Analogue Pocket +// cart pins 30/31 via the Analogizer SNAC harness. +// +// The module NEVER drives a line high. Each line is only ever: +// released -> *_oe = 0 (pin = input / Hi-Z, external pull-up -> '1') +// driven low -> *_oe = 1 (pin = output, data hard-wired to 1'b0) +// +// Wiring in core_top (verify APF dir polarity: here 1 = OUTPUT): +// assign cart_tran_pin30 = 1'b0; +// assign cart_tran_pin30_dir = ps2_clk_oe; // 1 => drive '0' +// assign ps2_clk_i = cart_tran_pin30; // reads pin when Hi-Z +// assign cart_tran_pin31 = 1'b0; +// assign cart_tran_pin31_dir = ps2_dat_oe; +// assign ps2_dat_i = cart_tran_pin31; +// // Also gate with cart_pin30_pwroff_reset as needed. +// +// Frame format: +// device->host : start(0) d0..d7(LSB) parity(odd) stop(1) +// host->device : inhibit CLK >=100us, DATA low (start), release CLK, +// device clocks 8 data + parity + stop, then drives ACK. +// ===================================================================== +module ps2_host #( + parameter int CLK_HZ = 50_000_000 +)( + input logic clk, + input logic rst, // synchronous, active high + + // Open-collector line interface (to dir-controlled pins) + input logic ps2_clk_i, // raw pin value (valid when released) + input logic ps2_dat_i, + output logic ps2_clk_oe, // 1 => pull CLK low + output logic ps2_dat_oe, // 1 => pull DATA low + + // Receive (device -> host) + output logic [7:0] rx_data, + output logic rx_valid, // 1-cycle strobe + output logic rx_err, // 1-cycle strobe (parity/framing) + + // Transmit (host -> device) + input logic [7:0] tx_data, + input logic tx_send, // 1-cycle strobe to start + output logic tx_busy, + output logic tx_done, // 1-cycle strobe, ACK received + output logic tx_err // 1-cycle strobe, no ACK / timeout +); + + // ---------------- timing ---------------- + localparam int US = CLK_HZ / 1_000_000; + localparam int INHIBIT_CYC = US * 120; // ~120 us CLK-low inhibit + localparam int WATCHDOG_CYC= US * 200; // abort if line goes idle mid-frame + + // ---------------- input sync + debounce ---------------- + logic [1:0] clk_sync, dat_sync; + always_ff @(posedge clk) begin + clk_sync <= {clk_sync[0], ps2_clk_i}; + dat_sync <= {dat_sync[0], ps2_dat_i}; + end + wire clk_s = clk_sync[1]; + wire dat_bit = dat_sync[1]; + + localparam int FILT = 4; + logic [FILT-1:0] clk_filt; + logic clk_stable, clk_stable_d; + always_ff @(posedge clk) begin + clk_filt <= {clk_filt[FILT-2:0], clk_s}; + if (&clk_filt) clk_stable <= 1'b1; + else if (~|clk_filt) clk_stable <= 1'b0; + clk_stable_d <= clk_stable; + end + wire clk_fedge = clk_stable_d & ~clk_stable; + wire clk_redge = ~clk_stable_d & clk_stable; + + // ---------------- FSM ---------------- + typedef enum logic [3:0] { + S_IDLE, RX_BITS, + TX_INHIBIT, TX_BITS, TX_STOP, TX_ACK + } state_t; + + state_t state; + logic [3:0] bitcnt; + logic [7:0] rxbuf; + logic rx_par; + logic [8:0] tx_shift; // {parity, d7..d0}, shifted out from bit0 + logic [31:0] timer; + + always_ff @(posedge clk) begin + // default strobes low + rx_valid <= 1'b0; + rx_err <= 1'b0; + tx_done <= 1'b0; + tx_err <= 1'b0; + + if (rst) begin + state <= S_IDLE; + ps2_clk_oe <= 1'b0; + ps2_dat_oe <= 1'b0; + tx_busy <= 1'b0; + bitcnt <= '0; + timer <= '0; + end else begin + case (state) + // -------------------------------------------------- IDLE + S_IDLE: begin + ps2_clk_oe <= 1'b0; + ps2_dat_oe <= 1'b0; + tx_busy <= 1'b0; + bitcnt <= '0; + if (tx_send) begin + tx_busy <= 1'b1; + ps2_clk_oe <= 1'b1; // begin inhibit + timer <= INHIBIT_CYC; + tx_shift <= {~(^tx_data), tx_data}; // odd parity + state <= TX_INHIBIT; + end else if (clk_fedge && (dat_bit == 1'b0)) begin + // start bit of an incoming frame + bitcnt <= 4'd0; + timer <= WATCHDOG_CYC; + state <= RX_BITS; + end + end + // -------------------------------------------------- RX + RX_BITS: begin + // watchdog: reset while CLK toggles, abort if idle too long + if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; + else if (timer != 0) timer <= timer - 1; + + if (timer == 0) begin + rx_err <= 1'b1; + state <= S_IDLE; + end else if (clk_fedge) begin + case (bitcnt) + 4'd0,4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7: + rxbuf[bitcnt[2:0]] <= dat_bit; + 4'd8: rx_par <= dat_bit; // parity + default: ; // 4'd9 = stop + endcase + bitcnt <= bitcnt + 4'd1; + if (bitcnt == 4'd9) begin // stop bit now on dat_bit + // odd parity: XOR of 8 data + parity must be 1; stop==1 + if ((^{rxbuf, rx_par}) == 1'b1 && dat_bit == 1'b1) begin + rx_data <= rxbuf; + rx_valid <= 1'b1; + end else begin + rx_err <= 1'b1; + end + state <= S_IDLE; + end + end + end + // -------------------------------------------------- TX + TX_INHIBIT: begin + ps2_clk_oe <= 1'b1; // hold CLK low + if (timer != 0) timer <= timer - 1; + if (timer == 0) begin + ps2_dat_oe <= 1'b1; // DATA low = start/request + ps2_clk_oe <= 1'b0; // release CLK + bitcnt <= 4'd0; + timer <= WATCHDOG_CYC; + state <= TX_BITS; + end + end + TX_BITS: begin + if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; + else if (timer != 0) timer <= timer - 1; + + if (timer == 0) begin + ps2_dat_oe <= 1'b0; ps2_clk_oe <= 1'b0; + tx_err <= 1'b1; state <= S_IDLE; + end else if (clk_fedge) begin + ps2_dat_oe <= ~tx_shift[0]; // '0' => drive low, '1' => release + tx_shift <= {1'b0, tx_shift[8:1]}; + bitcnt <= bitcnt + 4'd1; + if (bitcnt == 4'd8) state <= TX_STOP; // presented d0..d7,parity + end + end + TX_STOP: begin + if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; + else if (timer != 0) timer <= timer - 1; + + if (timer == 0) begin + ps2_dat_oe <= 1'b0; tx_err <= 1'b1; state <= S_IDLE; + end else if (clk_fedge) begin + ps2_dat_oe <= 1'b0; // release DATA (stop) + state <= TX_ACK; + end + end + TX_ACK: begin + if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; + else if (timer != 0) timer <= timer - 1; + + if (timer == 0) begin + tx_err <= 1'b1; state <= S_IDLE; + end else if (clk_fedge) begin + if (dat_bit == 1'b0) tx_done <= 1'b1; // device pulled DATA low = ACK + else tx_err <= 1'b1; + state <= S_IDLE; + end + end + default: state <= S_IDLE; + endcase + end + end endmodule \ No newline at end of file diff --git a/target/pocket/ps2_keyboard.vhd b/target/pocket/ps2_keyboard.vhd new file mode 100644 index 0000000..3dba646 --- /dev/null +++ b/target/pocket/ps2_keyboard.vhd @@ -0,0 +1,108 @@ +-------------------------------------------------------------------------------- +-- +-- FileName: ps2_keyboard.vhd +-- Dependencies: debounce.vhd +-- Design Software: Quartus II 32-bit Version 12.1 Build 177 SJ Full Version +-- +-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY +-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY +-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL +-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF +-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS +-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), +-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. +-- +-- Version History +-- Version 1.0 11/25/2013 Scott Larson +-- Initial Public Release +-- +-------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +ENTITY ps2_keyboard IS + GENERIC( + clk_freq : INTEGER := 50_000_000; --system clock frequency in Hz + debounce_counter_size : INTEGER := 8); --set such that (2^size)/clk_freq = 5us (size = 8 for 50MHz) + PORT( + clk : IN STD_LOGIC; --system clock + ps2_clk : IN STD_LOGIC; --clock signal from PS/2 keyboard + ps2_data : IN STD_LOGIC; --data signal from PS/2 keyboard + ps2_code_new : OUT STD_LOGIC; --flag that new PS/2 code is available on ps2_code bus + ps2_code : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)); --code received from PS/2 +END ps2_keyboard; + +ARCHITECTURE logic OF ps2_keyboard IS + SIGNAL sync_ffs : STD_LOGIC_VECTOR(1 DOWNTO 0); --synchronizer flip-flops for PS/2 signals + SIGNAL ps2_clk_int : STD_LOGIC; --debounced clock signal from PS/2 keyboard + SIGNAL ps2_data_int : STD_LOGIC; --debounced data signal from PS/2 keyboard + SIGNAL ps2_word : STD_LOGIC_VECTOR(10 DOWNTO 0); --stores the ps2 data word + SIGNAL error : STD_LOGIC; --validate parity, start, and stop bits + SIGNAL count_idle : INTEGER RANGE 0 TO clk_freq/18_000; --counter to determine PS/2 is idle + + --declare debounce component for debouncing PS2 input signals + COMPONENT debounce IS + GENERIC( + counter_size : INTEGER); --debounce period (in seconds) = 2^counter_size/(clk freq in Hz) + PORT( + clk : IN STD_LOGIC; --input clock + button : IN STD_LOGIC; --input signal to be debounced + result : OUT STD_LOGIC); --debounced signal + END COMPONENT; +BEGIN + + --synchronizer flip-flops + PROCESS(clk) + BEGIN + IF(clk'EVENT AND clk = '1') THEN --rising edge of system clock + sync_ffs(0) <= ps2_clk; --synchronize PS/2 clock signal + sync_ffs(1) <= ps2_data; --synchronize PS/2 data signal + END IF; + END PROCESS; + + --debounce PS2 input signals + debounce_ps2_clk: debounce + GENERIC MAP(counter_size => debounce_counter_size) + PORT MAP(clk => clk, button => sync_ffs(0), result => ps2_clk_int); + debounce_ps2_data: debounce + GENERIC MAP(counter_size => debounce_counter_size) + PORT MAP(clk => clk, button => sync_ffs(1), result => ps2_data_int); + + --input PS2 data + PROCESS(ps2_clk_int) + BEGIN + IF(ps2_clk_int'EVENT AND ps2_clk_int = '0') THEN --falling edge of PS2 clock + ps2_word <= ps2_data_int & ps2_word(10 DOWNTO 1); --shift in PS2 data bit + END IF; + END PROCESS; + + --verify that parity, start, and stop bits are all correct + error <= NOT (NOT ps2_word(0) AND ps2_word(10) AND (ps2_word(9) XOR ps2_word(8) XOR + ps2_word(7) XOR ps2_word(6) XOR ps2_word(5) XOR ps2_word(4) XOR ps2_word(3) XOR + ps2_word(2) XOR ps2_word(1))); + + --determine if PS2 port is idle (i.e. last transaction is finished) and output result + PROCESS(clk) + BEGIN + IF(clk'EVENT AND clk = '1') THEN --rising edge of system clock + + IF(ps2_clk_int = '0') THEN --low PS2 clock, PS/2 is active + count_idle <= 0; --reset idle counter + ELSIF(count_idle /= clk_freq/18_000) THEN --PS2 clock has been high less than a half clock period (<55us) + count_idle <= count_idle + 1; --continue counting + END IF; + + IF(count_idle = clk_freq/18_000 AND error = '0') THEN --idle threshold reached and no errors detected + ps2_code_new <= '1'; --set flag that new PS/2 code is available + ps2_code <= ps2_word(8 DOWNTO 1); --output new PS/2 code + ELSE --PS/2 port active or error detected + ps2_code_new <= '0'; --set flag that PS/2 transaction is in progress + END IF; + + END IF; + END PROCESS; + +END logic; diff --git a/target/pocket/ps2_mouse.vhd b/target/pocket/ps2_mouse.vhd new file mode 100644 index 0000000..c62b459 --- /dev/null +++ b/target/pocket/ps2_mouse.vhd @@ -0,0 +1,172 @@ +-------------------------------------------------------------------------------- +-- +-- FileName: ps2_mouse.vhd +-- Dependencies: ps2_transceiver.vhd, debounce.vhd +-- Design Software: Quartus II 64-bit Version 13.1.0 Build 162 SJ Web Edition +-- +-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY +-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY +-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL +-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF +-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS +-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), +-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. +-- +-- Version History +-- Version 1.0 2/16/2018 Scott Larson +-- Initial Public Release +-- +-------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +ENTITY ps2_mouse IS + GENERIC( + clk_freq : INTEGER := 50_000_000; --system clock frequency in Hz + ps2_debounce_counter_size : INTEGER := 8); --set such that 2^size/clk_freq = 5us (size = 8 for 50MHz) + PORT( + clk : IN STD_LOGIC; --system clock input + reset_n : IN STD_LOGIC; --active low asynchronous reset + ps2_clk : INOUT STD_LOGIC; --clock signal from PS2 mouse + ps2_data : INOUT STD_LOGIC; --data signal from PS2 mouse + mouse_data : OUT STD_LOGIC_VECTOR(23 DOWNTO 0); --data received from mouse + mouse_data_new : OUT STD_LOGIC); --new data packet available flag +END ps2_mouse; + +ARCHITECTURE logic OF ps2_mouse IS + TYPE machine IS(reset, rx_ack1, rx_bat, rx_id, ena_reporting, rx_ack2, stream); --needed states + SIGNAL state : machine := reset; --state machine + SIGNAL tx_ena : STD_LOGIC := '0'; --transmit enable for ps2_transceiver + SIGNAL tx_cmd : STD_LOGIC_VECTOR(8 DOWNTO 0); --command to transmit + SIGNAL tx_busy : STD_LOGIC; --ps2_transceiver busy signal + SIGNAL ps2_code : STD_LOGIC_VECTOR(7 DOWNTO 0); --PS/2 code received from ps2_transceiver + SIGNAL ps2_code_new : STD_LOGIC; --new PS/2 code available flag from ps2_transceiver + SIGNAL ps2_code_new_prev : STD_LOGIC; --previous value of ps2_code_new + SIGNAL packet_byte : INTEGER RANGE 0 TO 2 := 2; --counter to track which packet byte is being received + SIGNAL mouse_data_int : STD_LOGIC_VECTOR(23 DOWNTO 0); --internal mouse data register + + --component to control PS/2 bus interface to the mouse + COMPONENT ps2_transceiver IS + GENERIC( + clk_freq : INTEGER; --system clock frequency in Hz + debounce_counter_size : INTEGER); --set such that (2^size)/clk_freq = 5us (size = 8 for 50MHz) + PORT( + clk : IN STD_LOGIC; --system clock + reset_n : IN STD_LOGIC; --active low asynchronous reset + tx_ena : IN STD_LOGIC; --enable transmit + tx_cmd : IN STD_LOGIC_VECTOR(8 DOWNTO 0); --8-bit command to transmit, MSB is parity bit + tx_busy : OUT STD_LOGIC; --indicates transmit in progress + ack_error : OUT STD_LOGIC; --device acknowledge from transmit, '1' is error + ps2_code : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --code received from PS/2 bus + ps2_code_new : OUT STD_LOGIC; --flag that new PS/2 code is available on ps2_code bus + rx_error : OUT STD_LOGIC; --start, stop, or parity receive error detected, '1' is error + ps2_clk : INOUT STD_LOGIC; --PS/2 port clock signal + ps2_data : INOUT STD_LOGIC); --PS/2 port data signal + END COMPONENT; + +BEGIN + + --PS/2 transceiver to control transactions with mouse + ps2_transceiver_0: ps2_transceiver + GENERIC MAP(clk_freq => clk_freq, debounce_counter_size => ps2_debounce_counter_size) + PORT MAP(clk => clk, reset_n => reset_n, tx_ena => tx_ena, tx_cmd => tx_cmd, tx_busy => tx_busy, ack_error => OPEN, + ps2_code => ps2_code, ps2_code_new => ps2_code_new, rx_error => OPEN, ps2_clk => ps2_clk, ps2_data => ps2_data); + + PROCESS(clk, reset_n) + BEGIN + IF(reset_n = '0') THEN --asynchronous reset + mouse_data_new <= '0'; --clear new mouse data available flag + mouse_data <= (OTHERS => '0'); --clear last mouse data packet received + state <= reset; --set state machine to reset the mouse + ELSIF(clk'EVENT AND clk = '1') THEN + ps2_code_new_prev <= ps2_code_new; --store previous value of the new PS/2 code flag + + CASE state IS + + WHEN reset => + IF(tx_busy = '0') THEN --transmit to mouse not yet in process + tx_ena <= '1'; --enable transmit to PS/2 mouse + tx_cmd <= "111111111"; --send reset command (0xFF) + state <= reset; --remain in reset state + ELSIF(tx_busy = '1') THEN --transmit to mouse is in process + tx_ena <= '0'; --clear transmit enable + state <= rx_ack1; --wait to receive an acknowledge from mouse + END IF; + + WHEN rx_ack1 => + IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received + IF(ps2_code = "11111010") THEN --new PS/2 code is acknowledge (0xFA) + state <= rx_bat; --wait to receive new BAT completion code + ELSE --new PS/2 code was not an acknowledge + state <= reset; --reset mouse again + END IF; + ELSE --new PS/2 code not yet received + state <= rx_ack1; --wait to receive a code from mouse + END IF; + + WHEN rx_bat => + IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received + IF(ps2_code = "10101010") THEN --new PS/2 code is BAT completion (0xAA) + state <= rx_id; --wait to receive device ID code + ELSE --new PS/2 code was not BAT completion + state <= reset; --reset mouse again + END IF; + ELSE --new PS/2 code not yet received + state <= rx_bat; --wait to receive a code from mouse + END IF; + + WHEN rx_id => + IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received + IF(ps2_code = "00000000") THEN --new PS/2 code is a mouse device ID (0x00) + state <= ena_reporting; --send command to enable data reporting + ELSE --new PS/2 code is not a mouse device ID + state <= reset; --reset mouse again + END IF; + ELSE --new PS/2 code not yet received + state <= rx_id; --wait to receive a code from mouse + END IF; + + WHEN ena_reporting => + IF(tx_busy = '0') THEN --transmit to mouse not yet in process + tx_ena <= '1'; --enable transmit to PS/2 mouse + tx_cmd <= "011110100"; --send enable reporting command (0xF4) + state <= ena_reporting; --remain in ena_reporting state + ELSIF(tx_busy = '1') THEN --transmit to mouse is in process + tx_ena <= '0'; --clear transmit enable + state <= rx_ack2; --wait to receive an acknowledge from mouse + END IF; + + WHEN rx_ack2 => + IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received + IF(ps2_code = "11111010") THEN --new PS/2 code is acknowledge (0xFA) + state <= stream; --proceed to collect and output data from mouse + ELSE --new PS/2 code was not an acknowledge + state <= reset; --reset mouse again + END IF; + ELSE --new PS/2 code not yet received + state <= rx_ack2; --wait to receive a code from mouse + END IF; + + WHEN stream => + IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received + mouse_data_new <= '0'; --clear new data packet available flag + mouse_data_int(7+packet_byte*8 DOWNTO packet_byte*8) <= ps2_code; --store new mouse data byte + IF(packet_byte = 0) THEN --all bytes in packet received and presented + packet_byte <= 2; --clear packet byte counter + ELSE --not all bytes in packet received yet + packet_byte <= packet_byte - 1; --increment packet byte counter + END IF; + END IF; + IF(ps2_code_new_prev = '1' AND ps2_code_new = '1' AND packet_byte = 2) THEN --mouse data receive is complete + mouse_data <= mouse_data_int; --present new mouse data at output + mouse_data_new <= '1'; --set new data packet available flag + END IF; + + END CASE; + END IF; + END PROCESS; + +END logic; diff --git a/target/pocket/ps2_snac_decoder.sv b/target/pocket/ps2_snac_decoder.sv index 13e699d..8b92893 100644 --- a/target/pocket/ps2_snac_decoder.sv +++ b/target/pocket/ps2_snac_decoder.sv @@ -1,115 +1,118 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -//------------------------------------------------------------------------------ -// ps2_snac_decoder — Host-side PS/2 (Set 2) via transceptores de bus SNAC. -// Sin tri-state en FPGA: por cada linea se exponen in / out / oe. -// Para teclado MSX solo se recibe => oe=0 permanente (transceptor en RX). -// Salida: ps2_key[10:0] formato MiSTer {toggle, pressed, ext, sc[7:0]} -//------------------------------------------------------------------------------ -`default_nettype none -`timescale 1ns/1ps - -module ps2_snac_decoder - #( - parameter int CLK_HZ = 50_000_000, //! Frecuencia de clk - parameter int WD_US = 120 //! Timeout de trama (us) para resync - ) - ( - input logic clk, - input logic reset, - // Interfaz hacia el transceptor SNAC (unidireccional + control de sentido) - input logic ps2_clk_in, //! CLK leido del transceptor (modo RX) - input logic ps2_dat_in, //! DATA leido del transceptor (modo RX) - output logic ps2_clk_oe, //! 1 = FPGA conduce CLK (aqui siempre 0) - output logic ps2_dat_oe, //! 1 = FPGA conduce DATA (aqui siempre 0) - output logic ps2_clk_out, //! valor a emitir si oe=1 (idle 1) - output logic ps2_dat_out, //! valor a emitir si oe=1 (idle 1) - // Salida decodificada - output logic [10:0] ps2_key //! {toggle, pressed, ext, sc[7:0]} - ); - - localparam int WD_MAX = (CLK_HZ/1_000_000)*WD_US; - - // Solo recepcion: nunca conducimos el bus. Idle alto por las pull-up a 5V. - assign ps2_clk_oe = 1'b0; - assign ps2_dat_oe = 1'b0; - assign ps2_clk_out = 1'b1; - assign ps2_dat_out = 1'b1; - - //! ---- Sync 2FF + flanco de bajada de PS2_CLK ------------------------- - logic [2:0] clk_sr; - logic [1:0] dat_sr; - always_ff @(posedge clk) begin - if (reset) begin clk_sr <= 3'b111; dat_sr <= 2'b11; end - else begin clk_sr <= {clk_sr[1:0], ps2_clk_in}; - dat_sr <= {dat_sr[0], ps2_dat_in}; end - end - wire ps2_clk_fall = (clk_sr[2:1] == 2'b10); - wire ps2_data_s = dat_sr[1]; - - //! ---- Recepcion trama 11 bits (start,8 LSB-first,parity impar,stop) --- - logic [10:0] shreg; - logic [3:0] bit_cnt; - logic rx_busy; - logic [$clog2(WD_MAX+1)-1:0] wd_free; - logic byte_valid; - logic [7:0] byte_data; - - always_ff @(posedge clk) begin - if (reset) begin - bit_cnt<=0; rx_busy<=0; shreg<=11'h7FF; wd_free<='0; - byte_valid<=0; byte_data<=8'h00; - end else begin - byte_valid <= 1'b0; - if (rx_busy) begin - wd_free <= wd_free + 1'b1; - if (wd_free >= WD_MAX[$bits(wd_free)-1:0]) begin - rx_busy<=0; bit_cnt<=0; - end - end else wd_free <= '0; - - if (ps2_clk_fall) begin - wd_free <= '0; - if (!rx_busy) begin - if (ps2_data_s == 1'b0) begin // start valido - rx_busy<=1'b1; bit_cnt<=4'd1; shreg<={ps2_data_s,10'h000}; - end - end else begin - shreg <= {ps2_data_s, shreg[10:1]}; - bit_cnt <= bit_cnt + 4'd1; - if (bit_cnt == 4'd10) begin - rx_busy<=1'b0; bit_cnt<=4'd0; - if ((^{shreg[9],shreg[8:1]}==1'b1) && (shreg[10]==1'b1)) begin - byte_valid<=1'b1; byte_data<=shreg[8:1]; - end - end - end - end - end - end - - //! ---- FSM Set 2: E0 (extendido) + F0 (break) -------------------------- - logic ext_f, brk_f, tgl; - logic out_pressed, out_ext; - logic [7:0] out_sc; - - always_ff @(posedge clk) begin - if (reset) begin - ext_f<=0; brk_f<=0; tgl<=0; - out_pressed<=0; out_ext<=0; out_sc<=8'h00; - end else if (byte_valid) begin - case (byte_data) - 8'hE0: ext_f<=1'b1; - 8'hF0: brk_f<=1'b1; - 8'hE1: begin ext_f<=1'b0; brk_f<=1'b0; end // Pause: ignorado - default: begin - out_sc<=byte_data; out_ext<=ext_f; out_pressed<=~brk_f; - tgl<=~tgl; ext_f<=1'b0; brk_f<=1'b0; - end - endcase - end - end - - assign ps2_key = {tgl, out_pressed, out_ext, out_sc}; - +//------------------------------------------------------------------------------ +// SPDX-License-Identifier: MIT +// ps2_snac_decoder — Host-side PS/2 (Set 2) via transceptores SNAC. RX-only. +// Salida ps2_key[10:0] MiSTer {toggle, pressed, ext, sc[7:0]} +//------------------------------------------------------------------------------ +`default_nettype none +`timescale 1ns/1ps + +module ps2_snac_decoder + #( + parameter int CLK_HZ = 5_600_000, + parameter int WD_US = 200 //! Timeout de trama (us) para resync + ) + ( + input logic clk, + input logic reset, + input logic ps2_clk_in, + input logic ps2_dat_in, + output logic ps2_clk_oe, + output logic ps2_dat_oe, + output logic ps2_clk_out, + output logic ps2_dat_out, + output logic [10:0] ps2_key + ); + + localparam int WD_MAX = (CLK_HZ/1_000_000)*WD_US; // ciclos de watchdog + + assign ps2_clk_oe = 1'b0; + assign ps2_dat_oe = 1'b0; + assign ps2_clk_out = 1'b1; + assign ps2_dat_out = 1'b1; + + //! ---- Sync 2FF + flanco de bajada de PS2_CLK ------------------------- + logic [2:0] clk_sr; + logic [1:0] dat_sr; + always_ff @(posedge clk) begin + if (reset) begin clk_sr <= 3'b111; dat_sr <= 2'b11; end + else begin clk_sr <= {clk_sr[1:0], ps2_clk_in}; + dat_sr <= {dat_sr[0], ps2_dat_in}; end + end + wire ps2_clk_fall = (clk_sr[2:1] == 2'b10); + wire ps2_bit = dat_sr[1]; + + //! ---- Recepcion: bit_cnt 0=start, 1..8=datos, 9=parity, 10=stop ------ + logic [9:0] data_r; // [7:0]=datos [8]=parity [9]=stop + logic [3:0] bit_cnt; + logic rx_busy; + logic [$clog2(WD_MAX+1)-1:0] wd_free; + logic byte_valid; + logic [7:0] byte_data; + + always_ff @(posedge clk) begin + if (reset) begin + bit_cnt<=0; rx_busy<=0; data_r<=0; wd_free<='0; + byte_valid<=0; byte_data<=8'h00; + end else begin + byte_valid <= 1'b0; + + if (rx_busy) begin + wd_free <= wd_free + 1'b1; + if (wd_free >= WD_MAX[$bits(wd_free)-1:0]) begin + rx_busy<=0; bit_cnt<=0; // trama cortada -> resync + end + end else wd_free <= '0; + + if (ps2_clk_fall) begin + wd_free <= '0; + if (!rx_busy) begin + if (ps2_bit == 1'b0) begin // start=0 valido + rx_busy <= 1'b1; + bit_cnt <= 4'd1; // el proximo flanco es d0 + end + end else begin + // insertar por MSB: al 10o bit -> data_r[7:0]=d0..d7,[8]=par,[9]=stop + data_r <= {ps2_bit, data_r[9:1]}; + if (bit_cnt == 4'd10) begin + rx_busy <= 1'b0; + bit_cnt <= 4'd0; + // parity impar: ^{8 datos, parity}==1 ; stop==1 + // en este ciclo el bit que entra (ps2_bit) es el STOP, + // y data_r[8:0] ya contiene d0..d7 + parity + if ((^{data_r[8], data_r[7:0]} == 1'b1) && (ps2_bit == 1'b1)) begin + byte_valid <= 1'b1; + byte_data <= data_r[7:0]; + end + end else begin + bit_cnt <= bit_cnt + 4'd1; + end + end + end + end + end + + //! ---- FSM Set 2: E0 (extendido) + F0 (break) -------------------------- + logic ext_f, brk_f, tgl; + logic out_pressed, out_ext; + logic [7:0] out_sc; + + always_ff @(posedge clk) begin + if (reset) begin + ext_f<=0; brk_f<=0; tgl<=0; + out_pressed<=0; out_ext<=0; out_sc<=8'h00; + end else if (byte_valid) begin + case (byte_data) + 8'hE0: ext_f<=1'b1; + 8'hF0: brk_f<=1'b1; + 8'hE1: begin ext_f<=1'b0; brk_f<=1'b0; end // Pause: ignorado + default: begin + out_sc<=byte_data; out_ext<=ext_f; out_pressed<=~brk_f; + tgl<=~tgl; ext_f<=1'b0; brk_f<=1'b0; + end + endcase + end + end + + assign ps2_key = {tgl, out_pressed, out_ext, out_sc}; + endmodule \ No newline at end of file diff --git a/target/pocket/ps2_to_key.sv b/target/pocket/ps2_to_key.sv new file mode 100644 index 0000000..f3dccb9 --- /dev/null +++ b/target/pocket/ps2_to_key.sv @@ -0,0 +1,96 @@ +// ********************************************************************************* +// Analogizer support conversion from raw ps2 scan codes to key events for PocketMSX +// @author: @RndMnkIII +// @date: 2026-08-21 +// ps2_to_key.sv +// ********************************************************************************** +`default_nettype none +`timescale 1ns/1ps + +module ps2_to_key #(parameter STROBE_TOGGLE = 1'b0, parameter HANDLE_PAUSE = 1'b1) ( + input wire clk, + input wire reset, + input wire enable, + + input wire ps2_code_new, + input wire [7:0] ps2_code, + + output logic [10:0] ps2_key +); + + logic code_new_d; + always_ff @(posedge clk) begin + code_new_d <= ps2_code_new; + end + wire byte_stb = ps2_code_new & ~code_new_d; + + logic ext; + logic brk; + logic [1:0] e1_cnt; + wire e1_active = (e1_cnt != 2'd0); + + // Registros de salida + logic key_strobe; + logic key_toggle; + logic key_pressed; + logic [8:0] key_code; + + always_ff @(posedge clk) begin + if (reset) begin + ext <= 1'b0; + brk <= 1'b0; + e1_cnt <= 2'd0; + key_strobe <= 1'b0; + key_toggle <= 1'b0; + key_pressed <= 1'b0; + key_code <= 9'h000; + end + else begin + key_strobe <= 1'b0; + + if (byte_stb) begin + if (e1_active) begin + if (ps2_code != 8'hF0) begin + e1_cnt <= e1_cnt - 1'b1; + end + end + else begin + case (ps2_code) + 8'hE0: begin + ext <= 1'b1; + end + 8'hF0: begin + brk <= 1'b1; + end + 8'hE1: begin + if (HANDLE_PAUSE) begin + e1_cnt <= 2'd2; + end + else begin + key_code <= {ext, ps2_code}; + key_pressed <= ~brk; + key_strobe <= 1'b1; + key_toggle <= ~key_toggle; + ext <= 1'b0; + brk <= 1'b0; + end + end + default: begin + key_code <= {ext, ps2_code}; + key_pressed <= ~brk; + key_strobe <= 1'b1; + key_toggle <= ~key_toggle; + ext <= 1'b0; + brk <= 1'b0; + end + endcase + end + end + end + end + + wire strobe_bit = STROBE_TOGGLE ? key_toggle : key_strobe; + + assign ps2_key = enable ? {strobe_bit, key_pressed, key_code} : 11'h0; + +endmodule \ No newline at end of file diff --git a/target/pocket/ps2_transceiver.vhd b/target/pocket/ps2_transceiver.vhd new file mode 100644 index 0000000..51eb838 --- /dev/null +++ b/target/pocket/ps2_transceiver.vhd @@ -0,0 +1,181 @@ +-------------------------------------------------------------------------------- +-- +-- FileName: ps2_transceiver.vhd +-- Dependencies: debounce.vhd +-- Design Software: Quartus II 64-bit Version 13.1.0 Build 162 SJ Web Edition +-- +-- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY +-- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT +-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +-- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY +-- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL +-- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF +-- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS +-- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), +-- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. +-- +-- Version History +-- Version 1.0 1/19/2018 Scott Larson +-- Initial Public Release +-- +-------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.all; + +ENTITY ps2_transceiver IS + GENERIC( + clk_freq : INTEGER := 50_000_000; --system clock frequency in Hz + debounce_counter_size : INTEGER := 8); --set such that (2^size)/clk_freq = 5us (size = 8 for 50MHz) + PORT( + clk : IN STD_LOGIC; --system clock + reset_n : IN STD_LOGIC; --active low asynchronous reset + tx_ena : IN STD_LOGIC; --enable transmit + tx_cmd : IN STD_LOGIC_VECTOR(8 DOWNTO 0); --8-bit command to transmit, MSB is parity bit + tx_busy : OUT STD_LOGIC; --indicates transmit in progress + ack_error : OUT STD_LOGIC; --device acknowledge from transmit, '1' is error + ps2_code : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --code received from PS/2 + ps2_code_new : OUT STD_LOGIC; --flag that new PS/2 code is available on ps2_code bus + rx_error : OUT STD_LOGIC; --start, stop, or parity receive error detected, '1' is error + ps2_clk : INOUT STD_LOGIC; --PS/2 port clock signal + ps2_data : INOUT STD_LOGIC); --PS/2 port data signal +END ps2_transceiver; + +ARCHITECTURE logic OF ps2_transceiver IS + TYPE machine IS(receive, inhibit, transact, tx_complete); --needed states + SIGNAL state : machine := receive; --state machine + SIGNAL sync_ffs : STD_LOGIC_VECTOR(1 DOWNTO 0); --synchronizer flip-flops for PS/2 signals + SIGNAL ps2_clk_int : STD_LOGIC; --debounced input clock signal from PS/2 port + SIGNAL ps2_clk_int_prev : STD_LOGIC; --previous state of the ps2_clk_int signal + SIGNAL ps2_data_int : STD_LOGIC; --debounced input data signal from PS/2 port + SIGNAL ps2_word : STD_LOGIC_VECTOR(10 DOWNTO 0); --stores the ps2 data word (both tx and rx) + SIGNAL error : STD_LOGIC; --validate parity, start, and stop bits for received data + SIGNAL timer : INTEGER RANGE 0 TO clk_freq/10_000 := 0; --counter to determine both inhibit period and when PS/2 is idle + SIGNAL bit_cnt : INTEGER RANGE 0 TO 11 := 0; --count the number of clock pulses during transmit + + --declare debounce component for debouncing PS2 input signals + COMPONENT debounce IS + GENERIC( + counter_size : INTEGER); --debounce period (in seconds) = 2^counter_size/(clk freq in Hz) + PORT( + clk : IN STD_LOGIC; --input clock + button : IN STD_LOGIC; --input signal to be debounced + result : OUT STD_LOGIC); --debounced signal + END COMPONENT; +BEGIN + + --synchronizer flip-flops + PROCESS(clk) + BEGIN + IF(clk'EVENT AND clk = '1') THEN --rising edge of system clock + sync_ffs(0) <= ps2_clk; --synchronize PS/2 clock signal + sync_ffs(1) <= ps2_data; --synchronize PS/2 data signal + END IF; + END PROCESS; + + --debounce PS2 input signals + debounce_ps2_clk: debounce + GENERIC MAP(counter_size => debounce_counter_size) + PORT MAP(clk => clk, button => sync_ffs(0), result => ps2_clk_int); + debounce_ps2_data: debounce + GENERIC MAP(counter_size => debounce_counter_size) + PORT MAP(clk => clk, button => sync_ffs(1), result => ps2_data_int); + + --verify that parity, start, and stop bits are all correct for received data + error <= NOT (NOT ps2_word(0) AND ps2_word(10) AND (ps2_word(9) XOR ps2_word(8) XOR + ps2_word(7) XOR ps2_word(6) XOR ps2_word(5) XOR ps2_word(4) XOR ps2_word(3) XOR + ps2_word(2) XOR ps2_word(1))); + + --state machine to control transmit and receive processes + PROCESS(clk, reset_n) + BEGIN + IF(reset_n = '0') THEN --reset PS/2 transceiver + ps2_clk <= '0'; --inhibit communication on PS/2 bus + ps2_data <= 'Z'; --release PS/2 data line + tx_busy <= '1'; --indicate that no transmit is in progress + ack_error <= '0'; --clear acknowledge error flag + ps2_code <= (OTHERS => '0'); --clear received PS/2 code + ps2_code_new <= '0'; --clear new received PS/2 code flag + rx_error <= '0'; --clear receive error flag + state <= receive; --set state machine to receive state + ELSIF(clk'EVENT AND clk = '1') THEN --rising edge of system clock + ps2_clk_int_prev <= ps2_clk_int; --store previous value of the PS/2 clock signal + CASE state IS --implement state machine + + WHEN receive => + IF(tx_ena = '1') THEN --transmit requested + tx_busy <= '1'; --indicate transmit in progress + timer <= 0; --reset timer for inhibit timing + ps2_word(9 DOWNTO 0) <= tx_cmd & '0'; --load parity, command, and start bit into PS/2 data buffer + bit_cnt <= 0; --clear bit counter + state <= inhibit; --inhibit communication to begin transaction + ELSE --transmit not requested + tx_busy <= '0'; --indicate no transmit in progress + ps2_clk <= 'Z'; --release PS/2 clock port + ps2_data <= 'Z'; --release PS/2 data port + --clock in receive data + IF(ps2_clk_int_prev = '1' AND ps2_clk_int = '0') THEN --falling edge of PS2 clock + ps2_word <= ps2_data_int & ps2_word(10 DOWNTO 1); --shift contents of PS/2 data buffer + END IF; + --determine if PS/2 port is idle + IF(ps2_clk_int = '0') THEN --low PS2 clock, PS/2 is active + timer <= 0; --reset idle counter + ELSIF(timer < clk_freq/18_000) THEN --PS2 clock has been high less than a half clock period (<55us) + timer <= timer + 1; --continue counting + END IF; + --output received data and port status + IF(timer = clk_freq/18_000) THEN --idle threshold reached + IF(error = '0') THEN --no error detected + ps2_code_new <= '1'; --set flag that new PS/2 code is available + ps2_code <= ps2_word(8 DOWNTO 1); --output new PS/2 code + ELSIF(error = '1') THEN --error detected + rx_error <= '1'; --set receive error flag + END IF; + ELSE --PS/2 port active + rx_error <= '0'; --clear receive error flag + ps2_code_new <= '0'; --set flag that PS/2 transaction is in progress + END IF; + state <= receive; --continue streaming receive transactions + END IF; + + WHEN inhibit => + IF(timer < clk_freq/10_000) THEN --first 100us not complete + timer <= timer + 1; --increment timer + ps2_data <= 'Z'; --release data port + ps2_clk <= '0'; --inhibit communication + state <= inhibit; --continue inhibit + ELSE --100us complete + ps2_data <= ps2_word(0); --output start bit to PS/2 data port + state <= transact; --proceed to send bits + END IF; + + WHEN transact => + ps2_clk <= 'Z'; --release clock port + IF(ps2_clk_int_prev = '1' AND ps2_clk_int = '0') THEN --falling edge of PS2 clock + ps2_word <= ps2_data_int & ps2_word(10 DOWNTO 1); --shift contents of PS/2 data buffer + bit_cnt <= bit_cnt + 1; --count clock falling edges + END IF; + IF(bit_cnt < 10) THEN --all bits not sent + ps2_data <= ps2_word(0); --connect serial output of PS/2 data buffer to data port + ELSE --all bits sent + ps2_data <= 'Z'; --release data port + END IF; + IF(bit_cnt = 11) THEN --acknowledge bit received + ack_error <= ps2_data_int; --set error flag if acknowledge is not '0' + state <= tx_complete; --proceed to wait until the slave releases the bus + ELSE --acknowledge bit not received + state <= transact; --continue transaction + END IF; + + WHEN tx_complete => + IF(ps2_clk_int = '1' AND ps2_data_int = '1') THEN --device has released the bus + state <= receive; --proceed to receive data state + ELSE --bus not released by device + state <= tx_complete; --wait for device to release bus + END IF; + + END CASE; + END IF; + END PROCESS; + +END logic; diff --git a/tools/reverse_bitstream.py b/tools/reverse_bitstream.py index a2bd6e4..5effc26 100755 --- a/tools/reverse_bitstream.py +++ b/tools/reverse_bitstream.py @@ -1,24 +1,24 @@ -#!/usr/bin/env python3 -"""Reverse bits in each byte of an RBF file for Analogue Pocket.""" -import sys - -# bit-reversal lookup table; bytes.translate does the file in one C-level pass -REVERSE_TABLE = bytes(int(f'{i:08b}'[::-1], 2) for i in range(256)) - - -def main(): - if len(sys.argv) != 3: - print(f"Usage: {sys.argv[0]} input.rbf output.rbf_r") - sys.exit(1) - - with open(sys.argv[1], 'rb') as f: - data = f.read() - - with open(sys.argv[2], 'wb') as f: - f.write(data.translate(REVERSE_TABLE)) - - print(f"Reversed {len(data)} bytes: {sys.argv[1]} -> {sys.argv[2]}") - - -if __name__ == '__main__': - main() +#!/usr/bin/env python3 +"""Reverse bits in each byte of an RBF file for Analogue Pocket.""" +import sys + +# bit-reversal lookup table; bytes.translate does the file in one C-level pass +REVERSE_TABLE = bytes(int(f'{i:08b}'[::-1], 2) for i in range(256)) + + +def main(): + if len(sys.argv) != 3: + print(f"Usage: {sys.argv[0]} input.rbf output.rbf_r") + sys.exit(1) + + with open(sys.argv[1], 'rb') as f: + data = f.read() + + with open(sys.argv[2], 'wb') as f: + f.write(data.translate(REVERSE_TABLE)) + + print(f"Reversed {len(data)} bytes: {sys.argv[1]} -> {sys.argv[2]}") + + +if __name__ == '__main__': + main() From eae5ef23bfae00cc719034acd5a830f97ad5641a Mon Sep 17 00:00:00 2001 From: RndMnkIII Date: Fri, 21 Aug 2026 20:33:40 +0200 Subject: [PATCH 3/3] removed inused contents --- target/pocket/ps2_host.sv | 206 ------------------------------ target/pocket/ps2_mouse.vhd | 172 ------------------------- target/pocket/ps2_snac_decoder.sv | 118 ----------------- target/pocket/ps2_transceiver.vhd | 181 -------------------------- 4 files changed, 677 deletions(-) delete mode 100644 target/pocket/ps2_host.sv delete mode 100644 target/pocket/ps2_mouse.vhd delete mode 100644 target/pocket/ps2_snac_decoder.sv delete mode 100644 target/pocket/ps2_transceiver.vhd diff --git a/target/pocket/ps2_host.sv b/target/pocket/ps2_host.sv deleted file mode 100644 index 97dfeb0..0000000 --- a/target/pocket/ps2_host.sv +++ /dev/null @@ -1,206 +0,0 @@ -// ===================================================================== -// ps2_host.sv -// Bidirectional PS/2 host controller for open-collector lines driven -// through tri-state (dir-controlled) FPGA pins, e.g. Analogue Pocket -// cart pins 30/31 via the Analogizer SNAC harness. -// -// The module NEVER drives a line high. Each line is only ever: -// released -> *_oe = 0 (pin = input / Hi-Z, external pull-up -> '1') -// driven low -> *_oe = 1 (pin = output, data hard-wired to 1'b0) -// -// Wiring in core_top (verify APF dir polarity: here 1 = OUTPUT): -// assign cart_tran_pin30 = 1'b0; -// assign cart_tran_pin30_dir = ps2_clk_oe; // 1 => drive '0' -// assign ps2_clk_i = cart_tran_pin30; // reads pin when Hi-Z -// assign cart_tran_pin31 = 1'b0; -// assign cart_tran_pin31_dir = ps2_dat_oe; -// assign ps2_dat_i = cart_tran_pin31; -// // Also gate with cart_pin30_pwroff_reset as needed. -// -// Frame format: -// device->host : start(0) d0..d7(LSB) parity(odd) stop(1) -// host->device : inhibit CLK >=100us, DATA low (start), release CLK, -// device clocks 8 data + parity + stop, then drives ACK. -// ===================================================================== -module ps2_host #( - parameter int CLK_HZ = 50_000_000 -)( - input logic clk, - input logic rst, // synchronous, active high - - // Open-collector line interface (to dir-controlled pins) - input logic ps2_clk_i, // raw pin value (valid when released) - input logic ps2_dat_i, - output logic ps2_clk_oe, // 1 => pull CLK low - output logic ps2_dat_oe, // 1 => pull DATA low - - // Receive (device -> host) - output logic [7:0] rx_data, - output logic rx_valid, // 1-cycle strobe - output logic rx_err, // 1-cycle strobe (parity/framing) - - // Transmit (host -> device) - input logic [7:0] tx_data, - input logic tx_send, // 1-cycle strobe to start - output logic tx_busy, - output logic tx_done, // 1-cycle strobe, ACK received - output logic tx_err // 1-cycle strobe, no ACK / timeout -); - - // ---------------- timing ---------------- - localparam int US = CLK_HZ / 1_000_000; - localparam int INHIBIT_CYC = US * 120; // ~120 us CLK-low inhibit - localparam int WATCHDOG_CYC= US * 200; // abort if line goes idle mid-frame - - // ---------------- input sync + debounce ---------------- - logic [1:0] clk_sync, dat_sync; - always_ff @(posedge clk) begin - clk_sync <= {clk_sync[0], ps2_clk_i}; - dat_sync <= {dat_sync[0], ps2_dat_i}; - end - wire clk_s = clk_sync[1]; - wire dat_bit = dat_sync[1]; - - localparam int FILT = 4; - logic [FILT-1:0] clk_filt; - logic clk_stable, clk_stable_d; - always_ff @(posedge clk) begin - clk_filt <= {clk_filt[FILT-2:0], clk_s}; - if (&clk_filt) clk_stable <= 1'b1; - else if (~|clk_filt) clk_stable <= 1'b0; - clk_stable_d <= clk_stable; - end - wire clk_fedge = clk_stable_d & ~clk_stable; - wire clk_redge = ~clk_stable_d & clk_stable; - - // ---------------- FSM ---------------- - typedef enum logic [3:0] { - S_IDLE, RX_BITS, - TX_INHIBIT, TX_BITS, TX_STOP, TX_ACK - } state_t; - - state_t state; - logic [3:0] bitcnt; - logic [7:0] rxbuf; - logic rx_par; - logic [8:0] tx_shift; // {parity, d7..d0}, shifted out from bit0 - logic [31:0] timer; - - always_ff @(posedge clk) begin - // default strobes low - rx_valid <= 1'b0; - rx_err <= 1'b0; - tx_done <= 1'b0; - tx_err <= 1'b0; - - if (rst) begin - state <= S_IDLE; - ps2_clk_oe <= 1'b0; - ps2_dat_oe <= 1'b0; - tx_busy <= 1'b0; - bitcnt <= '0; - timer <= '0; - end else begin - case (state) - // -------------------------------------------------- IDLE - S_IDLE: begin - ps2_clk_oe <= 1'b0; - ps2_dat_oe <= 1'b0; - tx_busy <= 1'b0; - bitcnt <= '0; - if (tx_send) begin - tx_busy <= 1'b1; - ps2_clk_oe <= 1'b1; // begin inhibit - timer <= INHIBIT_CYC; - tx_shift <= {~(^tx_data), tx_data}; // odd parity - state <= TX_INHIBIT; - end else if (clk_fedge && (dat_bit == 1'b0)) begin - // start bit of an incoming frame - bitcnt <= 4'd0; - timer <= WATCHDOG_CYC; - state <= RX_BITS; - end - end - // -------------------------------------------------- RX - RX_BITS: begin - // watchdog: reset while CLK toggles, abort if idle too long - if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; - else if (timer != 0) timer <= timer - 1; - - if (timer == 0) begin - rx_err <= 1'b1; - state <= S_IDLE; - end else if (clk_fedge) begin - case (bitcnt) - 4'd0,4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7: - rxbuf[bitcnt[2:0]] <= dat_bit; - 4'd8: rx_par <= dat_bit; // parity - default: ; // 4'd9 = stop - endcase - bitcnt <= bitcnt + 4'd1; - if (bitcnt == 4'd9) begin // stop bit now on dat_bit - // odd parity: XOR of 8 data + parity must be 1; stop==1 - if ((^{rxbuf, rx_par}) == 1'b1 && dat_bit == 1'b1) begin - rx_data <= rxbuf; - rx_valid <= 1'b1; - end else begin - rx_err <= 1'b1; - end - state <= S_IDLE; - end - end - end - // -------------------------------------------------- TX - TX_INHIBIT: begin - ps2_clk_oe <= 1'b1; // hold CLK low - if (timer != 0) timer <= timer - 1; - if (timer == 0) begin - ps2_dat_oe <= 1'b1; // DATA low = start/request - ps2_clk_oe <= 1'b0; // release CLK - bitcnt <= 4'd0; - timer <= WATCHDOG_CYC; - state <= TX_BITS; - end - end - TX_BITS: begin - if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; - else if (timer != 0) timer <= timer - 1; - - if (timer == 0) begin - ps2_dat_oe <= 1'b0; ps2_clk_oe <= 1'b0; - tx_err <= 1'b1; state <= S_IDLE; - end else if (clk_fedge) begin - ps2_dat_oe <= ~tx_shift[0]; // '0' => drive low, '1' => release - tx_shift <= {1'b0, tx_shift[8:1]}; - bitcnt <= bitcnt + 4'd1; - if (bitcnt == 4'd8) state <= TX_STOP; // presented d0..d7,parity - end - end - TX_STOP: begin - if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; - else if (timer != 0) timer <= timer - 1; - - if (timer == 0) begin - ps2_dat_oe <= 1'b0; tx_err <= 1'b1; state <= S_IDLE; - end else if (clk_fedge) begin - ps2_dat_oe <= 1'b0; // release DATA (stop) - state <= TX_ACK; - end - end - TX_ACK: begin - if (clk_fedge || clk_redge) timer <= WATCHDOG_CYC; - else if (timer != 0) timer <= timer - 1; - - if (timer == 0) begin - tx_err <= 1'b1; state <= S_IDLE; - end else if (clk_fedge) begin - if (dat_bit == 1'b0) tx_done <= 1'b1; // device pulled DATA low = ACK - else tx_err <= 1'b1; - state <= S_IDLE; - end - end - default: state <= S_IDLE; - endcase - end - end -endmodule \ No newline at end of file diff --git a/target/pocket/ps2_mouse.vhd b/target/pocket/ps2_mouse.vhd deleted file mode 100644 index c62b459..0000000 --- a/target/pocket/ps2_mouse.vhd +++ /dev/null @@ -1,172 +0,0 @@ --------------------------------------------------------------------------------- --- --- FileName: ps2_mouse.vhd --- Dependencies: ps2_transceiver.vhd, debounce.vhd --- Design Software: Quartus II 64-bit Version 13.1.0 Build 162 SJ Web Edition --- --- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY --- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT --- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A --- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY --- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL --- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF --- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS --- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), --- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. --- --- Version History --- Version 1.0 2/16/2018 Scott Larson --- Initial Public Release --- --------------------------------------------------------------------------------- - -LIBRARY ieee; -USE ieee.std_logic_1164.all; - -ENTITY ps2_mouse IS - GENERIC( - clk_freq : INTEGER := 50_000_000; --system clock frequency in Hz - ps2_debounce_counter_size : INTEGER := 8); --set such that 2^size/clk_freq = 5us (size = 8 for 50MHz) - PORT( - clk : IN STD_LOGIC; --system clock input - reset_n : IN STD_LOGIC; --active low asynchronous reset - ps2_clk : INOUT STD_LOGIC; --clock signal from PS2 mouse - ps2_data : INOUT STD_LOGIC; --data signal from PS2 mouse - mouse_data : OUT STD_LOGIC_VECTOR(23 DOWNTO 0); --data received from mouse - mouse_data_new : OUT STD_LOGIC); --new data packet available flag -END ps2_mouse; - -ARCHITECTURE logic OF ps2_mouse IS - TYPE machine IS(reset, rx_ack1, rx_bat, rx_id, ena_reporting, rx_ack2, stream); --needed states - SIGNAL state : machine := reset; --state machine - SIGNAL tx_ena : STD_LOGIC := '0'; --transmit enable for ps2_transceiver - SIGNAL tx_cmd : STD_LOGIC_VECTOR(8 DOWNTO 0); --command to transmit - SIGNAL tx_busy : STD_LOGIC; --ps2_transceiver busy signal - SIGNAL ps2_code : STD_LOGIC_VECTOR(7 DOWNTO 0); --PS/2 code received from ps2_transceiver - SIGNAL ps2_code_new : STD_LOGIC; --new PS/2 code available flag from ps2_transceiver - SIGNAL ps2_code_new_prev : STD_LOGIC; --previous value of ps2_code_new - SIGNAL packet_byte : INTEGER RANGE 0 TO 2 := 2; --counter to track which packet byte is being received - SIGNAL mouse_data_int : STD_LOGIC_VECTOR(23 DOWNTO 0); --internal mouse data register - - --component to control PS/2 bus interface to the mouse - COMPONENT ps2_transceiver IS - GENERIC( - clk_freq : INTEGER; --system clock frequency in Hz - debounce_counter_size : INTEGER); --set such that (2^size)/clk_freq = 5us (size = 8 for 50MHz) - PORT( - clk : IN STD_LOGIC; --system clock - reset_n : IN STD_LOGIC; --active low asynchronous reset - tx_ena : IN STD_LOGIC; --enable transmit - tx_cmd : IN STD_LOGIC_VECTOR(8 DOWNTO 0); --8-bit command to transmit, MSB is parity bit - tx_busy : OUT STD_LOGIC; --indicates transmit in progress - ack_error : OUT STD_LOGIC; --device acknowledge from transmit, '1' is error - ps2_code : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --code received from PS/2 bus - ps2_code_new : OUT STD_LOGIC; --flag that new PS/2 code is available on ps2_code bus - rx_error : OUT STD_LOGIC; --start, stop, or parity receive error detected, '1' is error - ps2_clk : INOUT STD_LOGIC; --PS/2 port clock signal - ps2_data : INOUT STD_LOGIC); --PS/2 port data signal - END COMPONENT; - -BEGIN - - --PS/2 transceiver to control transactions with mouse - ps2_transceiver_0: ps2_transceiver - GENERIC MAP(clk_freq => clk_freq, debounce_counter_size => ps2_debounce_counter_size) - PORT MAP(clk => clk, reset_n => reset_n, tx_ena => tx_ena, tx_cmd => tx_cmd, tx_busy => tx_busy, ack_error => OPEN, - ps2_code => ps2_code, ps2_code_new => ps2_code_new, rx_error => OPEN, ps2_clk => ps2_clk, ps2_data => ps2_data); - - PROCESS(clk, reset_n) - BEGIN - IF(reset_n = '0') THEN --asynchronous reset - mouse_data_new <= '0'; --clear new mouse data available flag - mouse_data <= (OTHERS => '0'); --clear last mouse data packet received - state <= reset; --set state machine to reset the mouse - ELSIF(clk'EVENT AND clk = '1') THEN - ps2_code_new_prev <= ps2_code_new; --store previous value of the new PS/2 code flag - - CASE state IS - - WHEN reset => - IF(tx_busy = '0') THEN --transmit to mouse not yet in process - tx_ena <= '1'; --enable transmit to PS/2 mouse - tx_cmd <= "111111111"; --send reset command (0xFF) - state <= reset; --remain in reset state - ELSIF(tx_busy = '1') THEN --transmit to mouse is in process - tx_ena <= '0'; --clear transmit enable - state <= rx_ack1; --wait to receive an acknowledge from mouse - END IF; - - WHEN rx_ack1 => - IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received - IF(ps2_code = "11111010") THEN --new PS/2 code is acknowledge (0xFA) - state <= rx_bat; --wait to receive new BAT completion code - ELSE --new PS/2 code was not an acknowledge - state <= reset; --reset mouse again - END IF; - ELSE --new PS/2 code not yet received - state <= rx_ack1; --wait to receive a code from mouse - END IF; - - WHEN rx_bat => - IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received - IF(ps2_code = "10101010") THEN --new PS/2 code is BAT completion (0xAA) - state <= rx_id; --wait to receive device ID code - ELSE --new PS/2 code was not BAT completion - state <= reset; --reset mouse again - END IF; - ELSE --new PS/2 code not yet received - state <= rx_bat; --wait to receive a code from mouse - END IF; - - WHEN rx_id => - IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received - IF(ps2_code = "00000000") THEN --new PS/2 code is a mouse device ID (0x00) - state <= ena_reporting; --send command to enable data reporting - ELSE --new PS/2 code is not a mouse device ID - state <= reset; --reset mouse again - END IF; - ELSE --new PS/2 code not yet received - state <= rx_id; --wait to receive a code from mouse - END IF; - - WHEN ena_reporting => - IF(tx_busy = '0') THEN --transmit to mouse not yet in process - tx_ena <= '1'; --enable transmit to PS/2 mouse - tx_cmd <= "011110100"; --send enable reporting command (0xF4) - state <= ena_reporting; --remain in ena_reporting state - ELSIF(tx_busy = '1') THEN --transmit to mouse is in process - tx_ena <= '0'; --clear transmit enable - state <= rx_ack2; --wait to receive an acknowledge from mouse - END IF; - - WHEN rx_ack2 => - IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received - IF(ps2_code = "11111010") THEN --new PS/2 code is acknowledge (0xFA) - state <= stream; --proceed to collect and output data from mouse - ELSE --new PS/2 code was not an acknowledge - state <= reset; --reset mouse again - END IF; - ELSE --new PS/2 code not yet received - state <= rx_ack2; --wait to receive a code from mouse - END IF; - - WHEN stream => - IF(ps2_code_new_prev = '0' AND ps2_code_new = '1') THEN --new PS/2 code received - mouse_data_new <= '0'; --clear new data packet available flag - mouse_data_int(7+packet_byte*8 DOWNTO packet_byte*8) <= ps2_code; --store new mouse data byte - IF(packet_byte = 0) THEN --all bytes in packet received and presented - packet_byte <= 2; --clear packet byte counter - ELSE --not all bytes in packet received yet - packet_byte <= packet_byte - 1; --increment packet byte counter - END IF; - END IF; - IF(ps2_code_new_prev = '1' AND ps2_code_new = '1' AND packet_byte = 2) THEN --mouse data receive is complete - mouse_data <= mouse_data_int; --present new mouse data at output - mouse_data_new <= '1'; --set new data packet available flag - END IF; - - END CASE; - END IF; - END PROCESS; - -END logic; diff --git a/target/pocket/ps2_snac_decoder.sv b/target/pocket/ps2_snac_decoder.sv deleted file mode 100644 index 8b92893..0000000 --- a/target/pocket/ps2_snac_decoder.sv +++ /dev/null @@ -1,118 +0,0 @@ -//------------------------------------------------------------------------------ -// SPDX-License-Identifier: MIT -// ps2_snac_decoder — Host-side PS/2 (Set 2) via transceptores SNAC. RX-only. -// Salida ps2_key[10:0] MiSTer {toggle, pressed, ext, sc[7:0]} -//------------------------------------------------------------------------------ -`default_nettype none -`timescale 1ns/1ps - -module ps2_snac_decoder - #( - parameter int CLK_HZ = 5_600_000, - parameter int WD_US = 200 //! Timeout de trama (us) para resync - ) - ( - input logic clk, - input logic reset, - input logic ps2_clk_in, - input logic ps2_dat_in, - output logic ps2_clk_oe, - output logic ps2_dat_oe, - output logic ps2_clk_out, - output logic ps2_dat_out, - output logic [10:0] ps2_key - ); - - localparam int WD_MAX = (CLK_HZ/1_000_000)*WD_US; // ciclos de watchdog - - assign ps2_clk_oe = 1'b0; - assign ps2_dat_oe = 1'b0; - assign ps2_clk_out = 1'b1; - assign ps2_dat_out = 1'b1; - - //! ---- Sync 2FF + flanco de bajada de PS2_CLK ------------------------- - logic [2:0] clk_sr; - logic [1:0] dat_sr; - always_ff @(posedge clk) begin - if (reset) begin clk_sr <= 3'b111; dat_sr <= 2'b11; end - else begin clk_sr <= {clk_sr[1:0], ps2_clk_in}; - dat_sr <= {dat_sr[0], ps2_dat_in}; end - end - wire ps2_clk_fall = (clk_sr[2:1] == 2'b10); - wire ps2_bit = dat_sr[1]; - - //! ---- Recepcion: bit_cnt 0=start, 1..8=datos, 9=parity, 10=stop ------ - logic [9:0] data_r; // [7:0]=datos [8]=parity [9]=stop - logic [3:0] bit_cnt; - logic rx_busy; - logic [$clog2(WD_MAX+1)-1:0] wd_free; - logic byte_valid; - logic [7:0] byte_data; - - always_ff @(posedge clk) begin - if (reset) begin - bit_cnt<=0; rx_busy<=0; data_r<=0; wd_free<='0; - byte_valid<=0; byte_data<=8'h00; - end else begin - byte_valid <= 1'b0; - - if (rx_busy) begin - wd_free <= wd_free + 1'b1; - if (wd_free >= WD_MAX[$bits(wd_free)-1:0]) begin - rx_busy<=0; bit_cnt<=0; // trama cortada -> resync - end - end else wd_free <= '0; - - if (ps2_clk_fall) begin - wd_free <= '0; - if (!rx_busy) begin - if (ps2_bit == 1'b0) begin // start=0 valido - rx_busy <= 1'b1; - bit_cnt <= 4'd1; // el proximo flanco es d0 - end - end else begin - // insertar por MSB: al 10o bit -> data_r[7:0]=d0..d7,[8]=par,[9]=stop - data_r <= {ps2_bit, data_r[9:1]}; - if (bit_cnt == 4'd10) begin - rx_busy <= 1'b0; - bit_cnt <= 4'd0; - // parity impar: ^{8 datos, parity}==1 ; stop==1 - // en este ciclo el bit que entra (ps2_bit) es el STOP, - // y data_r[8:0] ya contiene d0..d7 + parity - if ((^{data_r[8], data_r[7:0]} == 1'b1) && (ps2_bit == 1'b1)) begin - byte_valid <= 1'b1; - byte_data <= data_r[7:0]; - end - end else begin - bit_cnt <= bit_cnt + 4'd1; - end - end - end - end - end - - //! ---- FSM Set 2: E0 (extendido) + F0 (break) -------------------------- - logic ext_f, brk_f, tgl; - logic out_pressed, out_ext; - logic [7:0] out_sc; - - always_ff @(posedge clk) begin - if (reset) begin - ext_f<=0; brk_f<=0; tgl<=0; - out_pressed<=0; out_ext<=0; out_sc<=8'h00; - end else if (byte_valid) begin - case (byte_data) - 8'hE0: ext_f<=1'b1; - 8'hF0: brk_f<=1'b1; - 8'hE1: begin ext_f<=1'b0; brk_f<=1'b0; end // Pause: ignorado - default: begin - out_sc<=byte_data; out_ext<=ext_f; out_pressed<=~brk_f; - tgl<=~tgl; ext_f<=1'b0; brk_f<=1'b0; - end - endcase - end - end - - assign ps2_key = {tgl, out_pressed, out_ext, out_sc}; - -endmodule \ No newline at end of file diff --git a/target/pocket/ps2_transceiver.vhd b/target/pocket/ps2_transceiver.vhd deleted file mode 100644 index 51eb838..0000000 --- a/target/pocket/ps2_transceiver.vhd +++ /dev/null @@ -1,181 +0,0 @@ --------------------------------------------------------------------------------- --- --- FileName: ps2_transceiver.vhd --- Dependencies: debounce.vhd --- Design Software: Quartus II 64-bit Version 13.1.0 Build 162 SJ Web Edition --- --- HDL CODE IS PROVIDED "AS IS." DIGI-KEY EXPRESSLY DISCLAIMS ANY --- WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT --- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A --- PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IN NO EVENT SHALL DIGI-KEY --- BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL --- DAMAGES, LOST PROFITS OR LOST DATA, HARM TO YOUR EQUIPMENT, COST OF --- PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS --- BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), --- ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS. --- --- Version History --- Version 1.0 1/19/2018 Scott Larson --- Initial Public Release --- --------------------------------------------------------------------------------- - -LIBRARY ieee; -USE ieee.std_logic_1164.all; - -ENTITY ps2_transceiver IS - GENERIC( - clk_freq : INTEGER := 50_000_000; --system clock frequency in Hz - debounce_counter_size : INTEGER := 8); --set such that (2^size)/clk_freq = 5us (size = 8 for 50MHz) - PORT( - clk : IN STD_LOGIC; --system clock - reset_n : IN STD_LOGIC; --active low asynchronous reset - tx_ena : IN STD_LOGIC; --enable transmit - tx_cmd : IN STD_LOGIC_VECTOR(8 DOWNTO 0); --8-bit command to transmit, MSB is parity bit - tx_busy : OUT STD_LOGIC; --indicates transmit in progress - ack_error : OUT STD_LOGIC; --device acknowledge from transmit, '1' is error - ps2_code : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --code received from PS/2 - ps2_code_new : OUT STD_LOGIC; --flag that new PS/2 code is available on ps2_code bus - rx_error : OUT STD_LOGIC; --start, stop, or parity receive error detected, '1' is error - ps2_clk : INOUT STD_LOGIC; --PS/2 port clock signal - ps2_data : INOUT STD_LOGIC); --PS/2 port data signal -END ps2_transceiver; - -ARCHITECTURE logic OF ps2_transceiver IS - TYPE machine IS(receive, inhibit, transact, tx_complete); --needed states - SIGNAL state : machine := receive; --state machine - SIGNAL sync_ffs : STD_LOGIC_VECTOR(1 DOWNTO 0); --synchronizer flip-flops for PS/2 signals - SIGNAL ps2_clk_int : STD_LOGIC; --debounced input clock signal from PS/2 port - SIGNAL ps2_clk_int_prev : STD_LOGIC; --previous state of the ps2_clk_int signal - SIGNAL ps2_data_int : STD_LOGIC; --debounced input data signal from PS/2 port - SIGNAL ps2_word : STD_LOGIC_VECTOR(10 DOWNTO 0); --stores the ps2 data word (both tx and rx) - SIGNAL error : STD_LOGIC; --validate parity, start, and stop bits for received data - SIGNAL timer : INTEGER RANGE 0 TO clk_freq/10_000 := 0; --counter to determine both inhibit period and when PS/2 is idle - SIGNAL bit_cnt : INTEGER RANGE 0 TO 11 := 0; --count the number of clock pulses during transmit - - --declare debounce component for debouncing PS2 input signals - COMPONENT debounce IS - GENERIC( - counter_size : INTEGER); --debounce period (in seconds) = 2^counter_size/(clk freq in Hz) - PORT( - clk : IN STD_LOGIC; --input clock - button : IN STD_LOGIC; --input signal to be debounced - result : OUT STD_LOGIC); --debounced signal - END COMPONENT; -BEGIN - - --synchronizer flip-flops - PROCESS(clk) - BEGIN - IF(clk'EVENT AND clk = '1') THEN --rising edge of system clock - sync_ffs(0) <= ps2_clk; --synchronize PS/2 clock signal - sync_ffs(1) <= ps2_data; --synchronize PS/2 data signal - END IF; - END PROCESS; - - --debounce PS2 input signals - debounce_ps2_clk: debounce - GENERIC MAP(counter_size => debounce_counter_size) - PORT MAP(clk => clk, button => sync_ffs(0), result => ps2_clk_int); - debounce_ps2_data: debounce - GENERIC MAP(counter_size => debounce_counter_size) - PORT MAP(clk => clk, button => sync_ffs(1), result => ps2_data_int); - - --verify that parity, start, and stop bits are all correct for received data - error <= NOT (NOT ps2_word(0) AND ps2_word(10) AND (ps2_word(9) XOR ps2_word(8) XOR - ps2_word(7) XOR ps2_word(6) XOR ps2_word(5) XOR ps2_word(4) XOR ps2_word(3) XOR - ps2_word(2) XOR ps2_word(1))); - - --state machine to control transmit and receive processes - PROCESS(clk, reset_n) - BEGIN - IF(reset_n = '0') THEN --reset PS/2 transceiver - ps2_clk <= '0'; --inhibit communication on PS/2 bus - ps2_data <= 'Z'; --release PS/2 data line - tx_busy <= '1'; --indicate that no transmit is in progress - ack_error <= '0'; --clear acknowledge error flag - ps2_code <= (OTHERS => '0'); --clear received PS/2 code - ps2_code_new <= '0'; --clear new received PS/2 code flag - rx_error <= '0'; --clear receive error flag - state <= receive; --set state machine to receive state - ELSIF(clk'EVENT AND clk = '1') THEN --rising edge of system clock - ps2_clk_int_prev <= ps2_clk_int; --store previous value of the PS/2 clock signal - CASE state IS --implement state machine - - WHEN receive => - IF(tx_ena = '1') THEN --transmit requested - tx_busy <= '1'; --indicate transmit in progress - timer <= 0; --reset timer for inhibit timing - ps2_word(9 DOWNTO 0) <= tx_cmd & '0'; --load parity, command, and start bit into PS/2 data buffer - bit_cnt <= 0; --clear bit counter - state <= inhibit; --inhibit communication to begin transaction - ELSE --transmit not requested - tx_busy <= '0'; --indicate no transmit in progress - ps2_clk <= 'Z'; --release PS/2 clock port - ps2_data <= 'Z'; --release PS/2 data port - --clock in receive data - IF(ps2_clk_int_prev = '1' AND ps2_clk_int = '0') THEN --falling edge of PS2 clock - ps2_word <= ps2_data_int & ps2_word(10 DOWNTO 1); --shift contents of PS/2 data buffer - END IF; - --determine if PS/2 port is idle - IF(ps2_clk_int = '0') THEN --low PS2 clock, PS/2 is active - timer <= 0; --reset idle counter - ELSIF(timer < clk_freq/18_000) THEN --PS2 clock has been high less than a half clock period (<55us) - timer <= timer + 1; --continue counting - END IF; - --output received data and port status - IF(timer = clk_freq/18_000) THEN --idle threshold reached - IF(error = '0') THEN --no error detected - ps2_code_new <= '1'; --set flag that new PS/2 code is available - ps2_code <= ps2_word(8 DOWNTO 1); --output new PS/2 code - ELSIF(error = '1') THEN --error detected - rx_error <= '1'; --set receive error flag - END IF; - ELSE --PS/2 port active - rx_error <= '0'; --clear receive error flag - ps2_code_new <= '0'; --set flag that PS/2 transaction is in progress - END IF; - state <= receive; --continue streaming receive transactions - END IF; - - WHEN inhibit => - IF(timer < clk_freq/10_000) THEN --first 100us not complete - timer <= timer + 1; --increment timer - ps2_data <= 'Z'; --release data port - ps2_clk <= '0'; --inhibit communication - state <= inhibit; --continue inhibit - ELSE --100us complete - ps2_data <= ps2_word(0); --output start bit to PS/2 data port - state <= transact; --proceed to send bits - END IF; - - WHEN transact => - ps2_clk <= 'Z'; --release clock port - IF(ps2_clk_int_prev = '1' AND ps2_clk_int = '0') THEN --falling edge of PS2 clock - ps2_word <= ps2_data_int & ps2_word(10 DOWNTO 1); --shift contents of PS/2 data buffer - bit_cnt <= bit_cnt + 1; --count clock falling edges - END IF; - IF(bit_cnt < 10) THEN --all bits not sent - ps2_data <= ps2_word(0); --connect serial output of PS/2 data buffer to data port - ELSE --all bits sent - ps2_data <= 'Z'; --release data port - END IF; - IF(bit_cnt = 11) THEN --acknowledge bit received - ack_error <= ps2_data_int; --set error flag if acknowledge is not '0' - state <= tx_complete; --proceed to wait until the slave releases the bus - ELSE --acknowledge bit not received - state <= transact; --continue transaction - END IF; - - WHEN tx_complete => - IF(ps2_clk_int = '1' AND ps2_data_int = '1') THEN --device has released the bus - state <= receive; --proceed to receive data state - ELSE --bus not released by device - state <= tx_complete; --wait for device to release bus - END IF; - - END CASE; - END IF; - END PROCESS; - -END logic;