diff --git a/cores/gameboy/gb.qsf b/cores/gameboy/gb.qsf
index de2abac..98fd57b 100644
--- a/cores/gameboy/gb.qsf
+++ b/cores/gameboy/gb.qsf
@@ -311,4 +311,5 @@ set_global_assignment -name VHDL_FILE t80/T80_Pack.vhd
set_global_assignment -name VHDL_FILE t80/T80_ALU.vhd
set_global_assignment -name VHDL_FILE t80/GBse.vhd
set_global_assignment -name VHDL_FILE t80/T80_MCode.vhd
+set_location_assignment PLL_1 -to pll|altpll_component|auto_generated|pll1
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
\ No newline at end of file
diff --git a/cores/gameboy/gb.v b/cores/gameboy/gb.v
index aa3d3e7..6218aa8 100644
--- a/cores/gameboy/gb.v
+++ b/cores/gameboy/gb.v
@@ -372,7 +372,8 @@ video video (
.clk ( clk ),
.clk_reg ( clk_cpu ), //can be 2x in cgb double speed mode
.isGBC ( isGBC ),
-
+
+ .isGBC_game ( isGBC_game|boot_rom_enabled ), //enable GBC mode during bootstrap rom
.irq ( video_irq ),
.vblank_irq ( vblank_irq ),
diff --git a/cores/gameboy/gb_mist.v b/cores/gameboy/gb_mist.v
index e8eda65..a65c7c8 100644
--- a/cores/gameboy/gb_mist.v
+++ b/cores/gameboy/gb_mist.v
@@ -445,7 +445,7 @@ lcd lcd (
);
// include the on screen display
-osd #(16,0,4) osd (
+osd #(10'd16,10'd0,4) osd (
.clk_sys ( clk64 ),
// spi for OSD
@@ -486,6 +486,6 @@ pll pll (
.locked(pll_locked)
);
-assign SDRAM_CLK = ~clk64;
+assign SDRAM_CLK = clk64;
endmodule
diff --git a/cores/gameboy/pll.ppf b/cores/gameboy/pll.ppf
index b7fa3e1..547d702 100644
--- a/cores/gameboy/pll.ppf
+++ b/cores/gameboy/pll.ppf
@@ -4,7 +4,6 @@
-
diff --git a/cores/gameboy/pll.v b/cores/gameboy/pll.v
index 89437c2..075eb09 100644
--- a/cores/gameboy/pll.v
+++ b/cores/gameboy/pll.v
@@ -39,27 +39,23 @@
module pll (
inclk0,
c0,
- c1,
locked);
input inclk0;
output c0;
- output c1;
output locked;
wire [4:0] sub_wire0;
wire sub_wire2;
- wire [0:0] sub_wire6 = 1'h0;
- wire [0:0] sub_wire3 = sub_wire0[0:0];
- wire [1:1] sub_wire1 = sub_wire0[1:1];
- wire c1 = sub_wire1;
+ wire [0:0] sub_wire5 = 1'h0;
+ wire [0:0] sub_wire1 = sub_wire0[0:0];
+ wire c0 = sub_wire1;
wire locked = sub_wire2;
- wire c0 = sub_wire3;
- wire sub_wire4 = inclk0;
- wire [1:0] sub_wire5 = {sub_wire6, sub_wire4};
+ wire sub_wire3 = inclk0;
+ wire [1:0] sub_wire4 = {sub_wire5, sub_wire3};
altpll altpll_component (
- .inclk (sub_wire5),
+ .inclk (sub_wire4),
.clk (sub_wire0),
.locked (sub_wire2),
.activeclock (),
@@ -102,10 +98,6 @@ module pll (
altpll_component.clk0_duty_cycle = 50,
altpll_component.clk0_multiply_by = 87,
altpll_component.clk0_phase_shift = "0",
- altpll_component.clk1_divide_by = 70,
- altpll_component.clk1_duty_cycle = 50,
- altpll_component.clk1_multiply_by = 87,
- altpll_component.clk1_phase_shift = "-2500",
altpll_component.compensate_clock = "CLK0",
altpll_component.inclk0_input_frequency = 37037,
altpll_component.intended_device_family = "Cyclone III",
@@ -139,7 +131,7 @@ module pll (
altpll_component.port_scanread = "PORT_UNUSED",
altpll_component.port_scanwrite = "PORT_UNUSED",
altpll_component.port_clk0 = "PORT_USED",
- altpll_component.port_clk1 = "PORT_USED",
+ altpll_component.port_clk1 = "PORT_UNUSED",
altpll_component.port_clk2 = "PORT_UNUSED",
altpll_component.port_clk3 = "PORT_UNUSED",
altpll_component.port_clk4 = "PORT_UNUSED",
@@ -180,11 +172,8 @@ endmodule
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "35"
-// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "70"
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
-// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "67.114288"
-// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "33.557144"
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
@@ -205,26 +194,18 @@ endmodule
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
-// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "ps"
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
-// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "87"
-// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "87"
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "33.55443200"
-// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "34.00000000"
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
-// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
-// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
-// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "-2500.00000000"
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
-// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "ps"
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
@@ -247,14 +228,11 @@ endmodule
// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
-// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
-// Retrieval info: PRIVATE: USE_CLK1 STRING "1"
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
-// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
@@ -263,10 +241,6 @@ endmodule
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "87"
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
-// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "70"
-// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
-// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "87"
-// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "-2500"
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
@@ -299,7 +273,7 @@ endmodule
// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
-// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
+// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
@@ -318,13 +292,11 @@ endmodule
// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
-// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
-// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
diff --git a/cores/gameboy/sprite.v b/cores/gameboy/sprite.v
index ee0ea05..fdae29e 100644
--- a/cores/gameboy/sprite.v
+++ b/cores/gameboy/sprite.v
@@ -22,6 +22,8 @@
module sprite (
input clk,
input size16,
+ input isGBC_game,
+ input [7:0] sprite_index,
input [7:0] v_cnt,
input [7:0] h_cnt,
@@ -41,7 +43,6 @@ module sprite (
//gbc
output [2:0] pixel_cmap_gbc,
- output tile_vbank,
input oam_wr,
input [1:0] oam_addr,
@@ -51,15 +52,15 @@ module sprite (
// x position for priority detection. Invisible sprites are far to the right and
// have minimum priority
-assign x = v_visible?x_pos:8'hff;
+assign x = v_visible?isGBC_game?sprite_index:x_pos:8'hff;
// register used to store pixel data for current line
reg [7:0] data0;
reg [7:0] data1;
always @(posedge clk) begin
- if(ds[0]) data0 <= flags[3]?data_1:data;
- if(ds[1]) data1 <= flags[3]?data_1:data;
+ if(ds[0]) data0 <= flags[3]&&isGBC_game?data_1:data;
+ if(ds[1]) data1 <= flags[3]&&isGBC_game?data_1:data;
end
wire [7:0] height = size16?8'd16:8'd8;
@@ -88,7 +89,6 @@ assign pixel_cmap = flags[4];
assign pixel_prio = flags[7];
assign pixel_cmap_gbc = flags[2:0];
-assign tile_vbank = flags[3];
reg [7:0] y_pos;
reg [7:0] x_pos;
diff --git a/cores/gameboy/sprites.v b/cores/gameboy/sprites.v
index 6eec371..a91cbcb 100644
--- a/cores/gameboy/sprites.v
+++ b/cores/gameboy/sprites.v
@@ -23,6 +23,7 @@ module sprites (
input clk,
input clk_reg,
input size16,
+ input isGBC_game,
// pixel position input which the current pixel is generated for
input [7:0] v_cnt,
@@ -36,8 +37,7 @@ module sprites (
//gbc
output [2:0] pixel_cmap_gbc,
- output tile_vbank,
-
+
input sort,
input [3:0] index, // index of sprite which video wants to read data for
output [10:0] addr,
@@ -82,7 +82,8 @@ assign oam_do = sprite_oam_do[oam_addr[7:2]];
// address where the sprite wants to read data from
wire [5:0] sprite_idx_array [SPRITES-1:0];
-wire [5:0] prio_index = sprite_idx_array[index];
+wire [5:0] padded_index = {2'd0,index};
+wire [5:0] prio_index = sprite_idx_array[padded_index];
assign addr = sprite_addr[prio_index];
//gbc
@@ -98,6 +99,9 @@ for(i=0;i '1');
+ ACC <= (others => '0');
if Mode = 3 then
F <= "11110000";
else
diff --git a/cores/gameboy/video.v b/cores/gameboy/video.v
index 5ec2852..cef5d47 100644
--- a/cores/gameboy/video.v
+++ b/cores/gameboy/video.v
@@ -2,29 +2,30 @@
// video.v
//
// Gameboy for the MIST board https://github.com/mist-devel
-//
-// Copyright (c) 2015 Till Harbaum
-//
-// This source file is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
+//
+// 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
+// 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 .
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
//
module video (
input reset,
- input clk, // 4 Mhz cpu clock
+ input clk, // 4 Mhz cpu clock
input clk_reg,
input isGBC,
-
+ input isGBC_game,
+
// cpu register adn oam interface
input cpu_sel_oam,
input cpu_sel_reg,
@@ -32,20 +33,20 @@ module video (
input cpu_wr,
input [7:0] cpu_di,
output [7:0] cpu_do,
-
+
// output to lcd
output lcd_on,
output lcd_clkena,
output [14:0] lcd_data,
output reg irq,
output reg vblank_irq,
-
+
// vram connection
output [1:0] mode,
output vram_rd,
output [12:0] vram_addr,
input [7:0] vram_data,
-
+
// vram connection bank1 (GBC)
input [7:0] vram1_data,
@@ -71,7 +72,6 @@ wire [10:0] sprite_addr;
//gbc
wire [2:0] sprite_pixel_cmap_gbc;
-wire sprite_tile_vbank;
// "data strobe" for the two bytes each sprite line consists of
wire [1:0] sprite_dvalid = {
@@ -82,7 +82,8 @@ sprites sprites (
.clk ( clk ),
.clk_reg ( clk_reg ),
.size16 ( lcdc_spr_siz ),
-
+ .isGBC_game ( isGBC&&isGBC_game ),
+
.v_cnt ( v_cnt ),
.h_cnt ( h_cnt-STAGE2 ), // sprites are added in second stage
.sort ( h_cnt == 0 ), // start of oam phase
@@ -97,11 +98,10 @@ sprites sprites (
.dvalid ( sprite_dvalid ),
.data ( vram_data ),
.data1 ( isGBC?vram1_data:vram_data ),
-
+
//gbc
.pixel_cmap_gbc ( sprite_pixel_cmap_gbc ),
- .tile_vbank ( sprite_tile_vbank ),
-
+
.oam_wr ( oam_wr ),
.oam_addr ( oam_addr ),
.oam_di ( oam_di ),
@@ -132,7 +132,7 @@ reg [7:0] stat;
// ff42, ff43 background scroll registers
reg [7:0] scy;
-reg [7:0] scy_r; // stable over entire image
+reg [7:0] scy_r; // stable over line
reg [7:0] scx;
reg [7:0] scx_r; // stable over line
@@ -149,7 +149,8 @@ reg [7:0] obp0;
reg [7:0] obp1;
reg [7:0] wy;
-reg [7:0] wy_r; // stable over entire image
+reg [7:0] wy_r; // stable over line
+
reg [7:0] wx;
reg [7:0] wx_r; // stable over line
@@ -189,7 +190,7 @@ always @(posedge clk_reg) begin
dma_cnt <= 10'd0;
end else if(dma_cnt != 160*4-1)
dma_cnt <= dma_cnt + 10'd1;
- else
+ else
dma_active <= 1'b0;
end
end
@@ -201,13 +202,13 @@ end
always @(posedge clk_reg) begin
irq <= 1'b0;
vblank_irq <= 1'b0;
-
+
if(stat[6] && h_cnt == 0 && lyc_match)
irq <= 1'b1;
-
+
if(stat[6] && lyc_changed == 1 && h_cnt > 0 && lyc_match)
irq <= 1'b1;
-
+
// begin of oam phase
if(stat[5] && (h_cnt == 0))
irq <= 1'b1;
@@ -239,21 +240,21 @@ always @(posedge clk_reg) begin
bgp <= 8'hfc;
obp0 <= 8'hff;
obp1 <= 8'hff;
-
+
bgpi <= 6'h0;
obpi <= 6'h0;
bgpi_ai <= 1'b0;
obpi_ai <= 1'b0;
-
+
for (ii=0;ii<64;ii=ii+1)begin
bgpd[ii] <= 8'h00;
obpd[ii] <= 8'h00;
end
-
+
end else begin
lyc_changed<=0;
if(cpu_sel_reg && cpu_wr) begin
- case(cpu_addr)
+ case(cpu_addr)
8'h40: lcdc <= cpu_di;
8'h41: stat <= cpu_di;
8'h42: scy <= cpu_di;
@@ -269,7 +270,7 @@ always @(posedge clk_reg) begin
8'h49: obp1 <= cpu_di;
8'h4a: wy <= cpu_di;
8'h4b: wx <= cpu_di;
-
+
//gbc
8'h68: begin
bgpi <= cpu_di[5:0];
@@ -298,7 +299,7 @@ always @(posedge clk_reg) begin
end
end
-assign cpu_do =
+assign cpu_do =
cpu_sel_oam?oam_do:
(cpu_addr == 8'h40)?lcdc:
(cpu_addr == 8'h41)?{1'b1,stat[6:3], lyc_match, mode}:
@@ -319,7 +320,7 @@ assign cpu_do =
(cpu_addr == 8'h6b && mode != 3)?obpd[obpi]:
8'hff:
8'hff;
-
+
// --------------------------------------------------------------------
// ----------------- second output stage: sprites ---------------------
// --------------------------------------------------------------------
@@ -337,8 +338,13 @@ reg [7:0] stage2_wptr;
reg [7:0] stage2_rptr;
-wire [5:0] palette_index = (stage2_bgp_buffer_pix[stage2_rptr][2:0] << 3) + (stage2_buffer[stage2_rptr]<<1); //gbc
-
+wire [5:0] palette_index = isGBC_game?
+ (stage2_bgp_buffer_pix[stage2_rptr][2:0] << 3) + (stage2_buffer[stage2_rptr]<<1): //GBC game
+ //GB game in GBC mode
+ (stage2_buffer[stage2_rptr] == 2'b00)?{3'd0,bgp[1:0],1'b0}:
+ (stage2_buffer[stage2_rptr] == 2'b01)?{3'd0,bgp[3:2],1'b0}:
+ (stage2_buffer[stage2_rptr] == 2'b10)?{3'd0,bgp[5:4],1'b0}:
+ {3'd0,bgp[7:6],1'b0};
// apply bg palette
wire [14:0] stage2_bg_pix = (!lcdc_bg_ena && !window_ena)?15'h7FFF: // background off?
@@ -348,11 +354,17 @@ wire [14:0] stage2_bg_pix = (!lcdc_bg_ena && !window_ena)?15'h7FFF: // backgrou
(stage2_buffer[stage2_rptr] == 2'b10)?{13'd0,bgp[5:4]}:
{13'd0,bgp[7:6]};
-
-
+
+
// apply sprite palette
-wire [5:0] sprite_palette_index = (sprite_pixel_cmap_gbc << 3) + (sprite_pixel_data<<1); //gbc
+wire [5:0] sprite_palette_index = isGBC_game?
+ (sprite_pixel_cmap_gbc << 3) + (sprite_pixel_data<<1): //gbc game
+ //GB game in GBC mode
+ (sprite_pixel_data == 2'b00)? (sprite_pixel_cmap << 3) + (obp[1:0]<<1):
+ (sprite_pixel_data == 2'b01)? (sprite_pixel_cmap << 3) + (obp[3:2]<<1):
+ (sprite_pixel_data == 2'b10)? (sprite_pixel_cmap << 3) + (obp[5:4]<<1):
+ (sprite_pixel_cmap << 3) + (obp[7:6]<<1);
wire [7:0] obp = sprite_pixel_cmap?obp1:obp0;
wire [14:0] sprite_pix = isGBC?{obpd[sprite_palette_index+1][6:0],obpd[sprite_palette_index]}: //gbc
@@ -361,28 +373,39 @@ wire [14:0] sprite_pix = isGBC?{obpd[sprite_palette_index+1][6:0],obpd[sprite_pa
(sprite_pixel_data == 2'b10)?{13'd0,obp[5:4]}:
{13'd0,obp[7:6]};
-// a sprite pixel is visible if
-// - sprites are enabled
-// - there's a sprite at the current position
-// - the sprites prioroty bit is 0, or
-// - the sprites priority is 1 and the backrgound color is 00
-// - GBC : BG priority is 0
-// - GBC : BG priority is 1 and the backrgound color is 00
-
-wire bg_piority = isGBC&&stage2_bgp_buffer_pix[stage2_rptr][3];
+// https://forums.nesdev.com/viewtopic.php?f=20&t=10771&sid=8fdb6e110fd9b5434d4a567b1199585e#p122222
+// priority list: BG0 < OBJL < BGL < OBJH < BGH
+wire bg_piority = isGBC&&isGBC_game&&stage2_bgp_buffer_pix[stage2_rptr][3];
wire [1:0] bg_color = stage2_buffer[stage2_rptr];
reg sprite_pixel_visible;
always @(*) begin
sprite_pixel_visible = 1'b0;
-
if (sprite_pixel_active && lcdc_spr_ena) begin // pixel active and sprites enabled
- if (bg_color == 2'b00) // background color = 0
- sprite_pixel_visible = 1'b1;
- else if (!bg_piority && !sprite_pixel_prio) // sprite has priority enabled and background priority disabled
- sprite_pixel_visible = 1'b1;
+
+ if (isGBC&&isGBC_game) begin
+ if (sprite_pixel_data == 2'b00)
+ sprite_pixel_visible = 1'b0;
+ else if (bg_color == 2'b00)
+ sprite_pixel_visible = 1'b1;
+ else if (!lcdc_bg_ena)
+ sprite_pixel_visible = 1'b1;
+ else if (bg_piority)
+ sprite_pixel_visible = 1'b0;
+ else if (!sprite_pixel_prio) //sprite pixel priority is enabled
+ sprite_pixel_visible = 1'b1;
+
+ end else begin
+ if (sprite_pixel_data == 2'b00)
+ sprite_pixel_visible = 1'b0;
+ else if (bg_color == 2'b00)
+ sprite_pixel_visible = 1'b1;
+ else if (!sprite_pixel_prio) //sprite pixel priority is enabled
+ sprite_pixel_visible = 1'b1;
+ end
end
+
end
always @(posedge clk) begin
@@ -396,21 +419,21 @@ always @(posedge clk) begin
stage2_bgp_buffer_pix[stage2_wptr] <= {bg_tile_attr_old[7],bg_tile_attr_old[2:0]}; //GBC: buffer palette and Priority Bit
stage2_wptr <= stage2_wptr + 8'd1;
end
-
+
stage2_clkena = !vblank && stage2;
if(stage2) begin
// mix sprites and bg
if(sprite_pixel_visible) stage2_data <= sprite_pix;
else stage2_data <= stage2_bg_pix;
-
- stage2_rptr <= stage2_rptr + 8'd1;
+
+ stage2_rptr <= stage2_rptr + 8'd1;
end
end
// --------------------------------------------------------------------
// --------------- first output stage: bg and window ------------------
// --------------------------------------------------------------------
-
+
reg window_ena;
// output shift registers for both video data bits
@@ -427,31 +450,31 @@ reg [7:0] bg_tile_data1;
wire stage1_clkena = !vblank && hdvalid;
-wire [1:0] stage1_data = (isGBC&&bg_tile_attr_old[5])?{ tile_shift_1_x[0], tile_shift_0_x[0] }:{ tile_shift_1[7], tile_shift_0[7] };
+wire [1:0] stage1_data = (isGBC&&isGBC_game&&bg_tile_attr_old[5])?{ tile_shift_1_x[0], tile_shift_0_x[0] }:{ tile_shift_1[7], tile_shift_0[7] };
wire [7:0] vram_gbc_data = bg_tile_attr_new[3]?vram1_data:vram_data; //gbc check tile bank
reg [7:0] bg_tile_attr_old,bg_tile_attr_new; //GBC
// read data half a clock cycle after ram has been selected
always @(posedge clk) begin
-
+
// every memory access is two pixel cycles
if(h_cnt[0]) begin
if(bg_tile_map_rd) bg_tile <= vram_data;
-
- if (isGBC) begin
+
+ if (isGBC&&isGBC_game) begin
if(bg_tile_map_rd) bg_tile_attr_new <= vram1_data; //get tile attr from vram bank1
if(bg_tile_data0_rd) bg_tile_data0 <= vram_gbc_data;
- if(bg_tile_data1_rd) bg_tile_data1 <= vram_gbc_data;
+ if(bg_tile_data1_rd) bg_tile_data1 <= vram_gbc_data;
end else begin
if(bg_tile_data0_rd) bg_tile_data0 <= vram_data;
- if(bg_tile_data1_rd) bg_tile_data1 <= vram_data;
+ if(bg_tile_data1_rd) bg_tile_data1 <= vram_data;
end
-
+
// sprite data is evaluated inside the sprite engine
end
-
- // shift bg/window pixels out
+
+ // shift bg/window pixels out
if(bg_tile_obj_rd && h_cnt[0]) begin
bg_tile_attr_old <= bg_tile_attr_new;
tile_shift_0 <= bg_tile_data0;
@@ -462,12 +485,12 @@ always @(posedge clk) begin
tile_shift_0 <= { tile_shift_0[6:0], 1'b0 };
tile_shift_1 <= { tile_shift_1[6:0], 1'b0 };
//GBC x-flip
- tile_shift_0_x <= { 1'b0,tile_shift_0_x[7:1]};
+ tile_shift_0_x <= { 1'b0,tile_shift_0_x[7:1]};
tile_shift_1_x <= { 1'b0,tile_shift_1_x[7:1]};
end
end
-assign vram_rd = lcdc_on && (bg_tile_map_rd || bg_tile_data0_rd ||
+assign vram_rd = lcdc_on && (bg_tile_map_rd || bg_tile_data0_rd ||
bg_tile_data1_rd || bg_tile_obj_rd);
wire bg_tile_a12 = !lcdc_tile_data_sel?(~bg_tile[7]):1'b0;
@@ -478,8 +501,8 @@ wire [2:0] tile_line_gbc = bg_tile_attr_new[6]? (3'b111 - tile_line): tile_line;
assign vram_addr =
bg_tile_map_rd?{2'b11, tile_map_sel, bg_tile_map_addr}:
- bg_tile_data0_rd?{bg_tile_a12, bg_tile, isGBC?tile_line_gbc:tile_line, 1'b0}:
- bg_tile_data1_rd?{bg_tile_a12, bg_tile, isGBC?tile_line_gbc:tile_line, 1'b1}:
+ bg_tile_data0_rd?{bg_tile_a12, bg_tile, isGBC&&isGBC_game?tile_line_gbc:tile_line, 1'b0}:
+ bg_tile_data1_rd?{bg_tile_a12, bg_tile, isGBC&&isGBC_game?tile_line_gbc:tile_line, 1'b1}:
{1'b0, sprite_addr, h_cnt[3]};
reg [9:0] bg_tile_map_addr;
@@ -508,25 +531,25 @@ localparam STATE_ACTIVE = 2;
always @(negedge clk) begin
if(h_cnt == 455) begin
// end of line
-
+
de <= 1'b0;
hextra_tiles <= 2'd0;
pcnt <= 8'd0;
skip <= 8'd0;
end else if(h_cnt == OAM_LEN) begin
// start of line
-
+
// skip entire oam time plus time until first data is delivered plus
- // time to skip the pixels according to the horizontal scroll position
+ // time to skip the pixels according to the horizontal scroll position
// (or the window start if line starts with window)
if(lcdc_win_ena && (v_cnt >= wy_r) && (wx_r < 8))
skip <= 8'd8 + (8'd7 - wx_r) - 8'd1;
else
skip <= 8'd8 + scx_r[2:0] - 8'd1;
-
+
// calculate how many extra tiles will have to be read in this line
if(lcdc_win_ena && (v_cnt >= wy_r) && (wx_r < 168)) begin
- // window needs at least one extra cycle, two if bg scroll position or
+ // window needs at least one extra cycle, two if bg scroll position or
// window are not 8 pixel aligned
if((wx_r[2:0] != 3'd7) || (scx_r[2:0] != 3'd0)) begin
if(wx_r[2:0] > ~scx_r[2:0])
@@ -535,19 +558,19 @@ always @(negedge clk) begin
hextra_tiles <= 2'd2;
end else
hextra_tiles <= 2'd1;
- end else
+ end else
if(scx_r[2:0] != 3'd0)
hextra_tiles <= 2'd1;
end else begin
if(win_start) begin
- // if window starts skip until end of current cycle and skip
+ // if window starts skip until end of current cycle and skip
// pixels until new window data is ready
skip <= { 5'b00000 ,~h_cnt[2:0] } + 8'd8;
de <= 1'b0;
end
if(skip) skip <= skip - 8'd1;
-
+
// (re-)enable display at the end of the wait phase
if(skip == 1)
de <= 1'b1;
@@ -560,7 +583,7 @@ always @(negedge clk) begin
end
end
end
-
+
// cycle through the B01s states
wire bg_tile_map_rd = (!vblank) && (!hblank) && (h_cnt[2:1] == 2'b00);
wire bg_tile_data0_rd = (!vblank) && (!hblank) && (h_cnt[2:1] == 2'b01);
@@ -571,7 +594,7 @@ wire bg_tile_obj_rd = (!vblank) && (!hblank) && (h_cnt[2:1] == 2'b11);
// Mode 01: v-blank
// Mode 10: oam
// Mode 11: oam and vram
-assign mode =
+assign mode =
(ly <= 144 && h_cnt<4)?2'b00: //AntonioND https://github.com/AntonioND/giibiiadvance/blob/master/docs/TCAGBD.pdf
!lcdc_on?2'b00:
vblank?2'b01:
@@ -594,36 +617,37 @@ wire win_start = lcdc_win_ena && (v_cnt >= wy_r) && de && (wx_r >= 7) && (pcnt =
// each memory access takes two cycles
always @(negedge clk) begin
- if (!lcdc_on) begin // don't increase counters if lcdoff
+ if (!lcdc_on) begin // don't increase counters if lcdoff
//reset counters
- h_cnt <= 9'd6;
+ h_cnt <= 9'd6;
v_cnt <= 8'd0;
-
+
end else begin
-
+
if(h_cnt != 455) begin
h_cnt <= h_cnt + 9'd1;
-
+
// make sure sginals don't change during the line
// latch at latest possible moment (one clock before display starts)
if(h_cnt == OAM_LEN-2) begin
scx_r <= scx;
wx_r <= wx;
scy_r <= scy;
+ wy_r <= wy;
end
-
+
// increment address at the end of each 8-pixel-cycle. But don't
// increment while waiting for current cycle to end due to window start
if(!hblank && h_cnt[2:0] == 3'b111 && (skip <= 8))
bg_tile_map_addr[4:0] <= bg_tile_map_addr[4:0] + 1'd1;
-
+
// begin of line
if(h_cnt == OAM_LEN-1) begin
// set tile map address for this line, assume there is no window
bg_tile_map_addr[9:5] <= bg_line[7:3];
bg_tile_map_addr[4:0] <= scx_r[7:3];
-
- // special case wx < 8: line starts with window, no background
+
+ // special case wx < 8: line starts with window, no background
// visible at all
if(lcdc_win_ena && (v_cnt >= wy_r) && (wx_r < 8)) begin
window_ena <= 1'b1;
@@ -631,7 +655,7 @@ always @(negedge clk) begin
bg_tile_map_addr[4:0] <= 5'd0; // window always start with its very left
end
end
-
+
// check if the window starts here
if(win_start) begin
window_ena <= 1'b1;
@@ -640,18 +664,18 @@ always @(negedge clk) begin
end
end else begin
window_ena <= 1'b0; // next line starts with background
-
+
// end of line reached
h_cnt <= 9'd0;
-
+
if(v_cnt != 153)
v_cnt <= v_cnt + 8'd1;
else begin
// start of new image
v_cnt <= 8'd0;
-
+
// make sure sginals don't change during the image
- wy_r <= wy;
+// wy_r <= wy;
end
end
end
diff --git a/cores/ht1080z/.gitignore b/cores/ht1080z/.gitignore
new file mode 100644
index 0000000..9a51957
--- /dev/null
+++ b/cores/ht1080z/.gitignore
@@ -0,0 +1 @@
+build_id.v
diff --git a/cores/ht1080z/README.md b/cores/ht1080z/README.md
new file mode 100644
index 0000000..88ee219
--- /dev/null
+++ b/cores/ht1080z/README.md
@@ -0,0 +1,5 @@
+HT1080Z School Computer (TRS80 Model I clone)
+=============================================
+
+http://joco.homeserver.hu/fpga/mist_ht1080z_en.html
+
diff --git a/cores/ht1080z/YM2149_linmix.vhd b/cores/ht1080z/YM2149_linmix.vhd
new file mode 100644
index 0000000..b9ad926
--- /dev/null
+++ b/cores/ht1080z/YM2149_linmix.vhd
@@ -0,0 +1,623 @@
+--
+-- A simulation model of YM2149 (AY-3-8910 with bells on)
+
+-- Copyright (c) MikeJ - Jan 2005
+--
+-- All rights reserved
+--
+-- Redistribution and use in source and synthezised forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+-- Redistributions of source code must retain the above copyright notice,
+-- this list of conditions and the following disclaimer.
+--
+-- Redistributions in synthesized form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+--
+-- Neither the name of the author nor the names of other contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS CODE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
+-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+-- POSSIBILITY OF SUCH DAMAGE.
+--
+-- You are responsible for any legal issues arising from your use of this code.
+--
+-- The latest version of this file can be found at: www.fpgaarcade.com
+--
+-- Email support@fpgaarcade.com
+--
+-- Revision list
+--
+-- version 001 initial release
+--
+-- Clues from MAME sound driver and Kazuhiro TSUJIKAWA
+--
+-- These are the measured outputs from a real chip for a single Isolated channel into a 1K load (V)
+-- vol 15 .. 0
+-- 3.27 2.995 2.741 2.588 2.452 2.372 2.301 2.258 2.220 2.198 2.178 2.166 2.155 2.148 2.141 2.132
+-- As the envelope volume is 5 bit, I have fitted a curve to the not quite log shape in order
+-- to produced all the required values.
+-- (The first part of the curve is a bit steeper and the last bit is more linear than expected)
+--
+-- NOTE, this component uses LINEAR mixing of the three analogue channels, and is only
+-- accurate for designs where the outputs are buffered and not simply wired together.
+-- The ouput level is more complex in that case and requires a larger table.
+
+library ieee;
+ use ieee.std_logic_1164.all;
+ use ieee.std_logic_arith.all;
+ use ieee.std_logic_unsigned.all;
+
+entity YM2149 is
+ port (
+ -- data bus
+ I_DA : in std_logic_vector(7 downto 0);
+ O_DA : out std_logic_vector(7 downto 0);
+ O_DA_OE_L : out std_logic;
+ -- control
+ I_A9_L : in std_logic;
+ I_A8 : in std_logic;
+ I_BDIR : in std_logic;
+ I_BC2 : in std_logic;
+ I_BC1 : in std_logic;
+ I_SEL_L : in std_logic;
+
+ O_AUDIO : out std_logic_vector(7 downto 0);
+ -- port a
+ I_IOA : in std_logic_vector(7 downto 0);
+ O_IOA : out std_logic_vector(7 downto 0);
+ O_IOA_OE_L : out std_logic;
+ -- port b
+ I_IOB : in std_logic_vector(7 downto 0);
+ O_IOB : out std_logic_vector(7 downto 0);
+ O_IOB_OE_L : out std_logic;
+
+ ENA : in std_logic; -- clock enable for higher speed operation
+ RESET_L : in std_logic;
+ CLK : in std_logic -- note 6 Mhz
+ );
+end;
+
+architecture RTL of YM2149 is
+ type array_16x8 is array (0 to 15) of std_logic_vector(7 downto 0);
+ type array_3x12 is array (1 to 3) of std_logic_vector(11 downto 0);
+
+ signal cnt_div : std_logic_vector(3 downto 0) := (others => '0');
+ signal noise_div : std_logic := '0';
+ signal ena_div : std_logic;
+ signal ena_div_noise : std_logic;
+ signal poly17 : std_logic_vector(16 downto 0) := (others => '0');
+
+ -- registers
+ signal addr : std_logic_vector(7 downto 0);
+ signal busctrl_addr : std_logic;
+ signal busctrl_we : std_logic;
+ signal busctrl_re : std_logic;
+
+ signal reg : array_16x8;
+ signal env_reset : std_logic;
+ signal ioa_inreg : std_logic_vector(7 downto 0);
+ signal iob_inreg : std_logic_vector(7 downto 0);
+
+ signal noise_gen_cnt : std_logic_vector(4 downto 0);
+ signal noise_gen_op : std_logic;
+ signal tone_gen_cnt : array_3x12 := (others => (others => '0'));
+ signal tone_gen_op : std_logic_vector(3 downto 1) := "000";
+
+ signal env_gen_cnt : std_logic_vector(15 downto 0);
+ signal env_ena : std_logic;
+ signal env_hold : std_logic;
+ signal env_inc : std_logic;
+ signal env_vol : std_logic_vector(4 downto 0);
+
+ signal tone_ena_l : std_logic;
+ signal tone_src : std_logic;
+ signal noise_ena_l : std_logic;
+ signal chan_vol : std_logic_vector(4 downto 0);
+
+ signal dac_amp : std_logic_vector(7 downto 0);
+ signal audio_mix : std_logic_vector(9 downto 0);
+ signal audio_final : std_logic_vector(9 downto 0);
+begin
+ -- cpu i/f
+ p_busdecode : process(I_BDIR, I_BC2, I_BC1, addr, I_A9_L, I_A8)
+ variable cs : std_logic;
+ variable sel : std_logic_vector(2 downto 0);
+ begin
+ -- BDIR BC2 BC1 MODE
+ -- 0 0 0 inactive
+ -- 0 0 1 address
+ -- 0 1 0 inactive
+ -- 0 1 1 read
+ -- 1 0 0 address
+ -- 1 0 1 inactive
+ -- 1 1 0 write
+ -- 1 1 1 read
+ busctrl_addr <= '0';
+ busctrl_we <= '0';
+ busctrl_re <= '0';
+
+ cs := '0';
+ if (I_A9_L = '0') and (I_A8 = '1') and (addr(7 downto 4) = "0000") then
+ cs := '1';
+ end if;
+
+ sel := (I_BDIR & I_BC2 & I_BC1);
+ case sel is
+ when "000" => null;
+ when "001" => busctrl_addr <= '1';
+ when "010" => null;
+ when "011" => busctrl_re <= cs;
+ when "100" => busctrl_addr <= '1';
+ when "101" => null;
+ when "110" => busctrl_we <= cs;
+ when "111" => busctrl_addr <= '1';
+ when others => null;
+ end case;
+ end process;
+
+ p_oe : process(busctrl_re)
+ begin
+ -- if we are emulating a real chip, maybe clock this to fake up the tristate typ delay of 100ns
+ O_DA_OE_L <= not (busctrl_re);
+ end process;
+
+ --
+ -- CLOCKED
+ --
+ --p_waddr : process
+ --begin
+ ---- looks like registers are latches in real chip, but the address is caught at the end of the address state.
+ --wait until rising_edge(CLK);
+
+ --if (RESET_L = '0') then
+ --addr <= (others => '0');
+ --else
+ --if (busctrl_addr = '1') then
+ --addr <= I_DA;
+ --end if;
+ --end if;
+ --end process;
+
+ --p_wdata : process
+ --begin
+ ---- looks like registers are latches in real chip, but the address is caught at the end of the address state.
+ --wait until rising_edge(CLK);
+ --env_reset <= '0';
+
+ --if (RESET_L = '0') then
+ --reg <= (others => (others => '0'));
+ --env_reset <= '1';
+ --else
+ --env_reset <= '0';
+ --if (busctrl_we = '1') then
+ --case addr(3 downto 0) is
+ --when x"0" => reg(0) <= I_DA;
+ --when x"1" => reg(1) <= I_DA;
+ --when x"2" => reg(2) <= I_DA;
+ --when x"3" => reg(3) <= I_DA;
+ --when x"4" => reg(4) <= I_DA;
+ --when x"5" => reg(5) <= I_DA;
+ --when x"6" => reg(6) <= I_DA;
+ --when x"7" => reg(7) <= I_DA;
+ --when x"8" => reg(8) <= I_DA;
+ --when x"9" => reg(9) <= I_DA;
+ --when x"A" => reg(10) <= I_DA;
+ --when x"B" => reg(11) <= I_DA;
+ --when x"C" => reg(12) <= I_DA;
+ --when x"D" => reg(13) <= I_DA; env_reset <= '1';
+ --when x"E" => reg(14) <= I_DA;
+ --when x"F" => reg(15) <= I_DA;
+ --when others => null;
+ --end case;
+ --end if;
+ --end if;
+ --end process;
+
+ --
+ -- LATCHED, useful when emulating a real chip in circuit. Nasty as gated clock.
+ --
+ p_waddr : process(reset_l, busctrl_addr)
+ begin
+ -- looks like registers are latches in real chip, but the address is caught at the end of the address state.
+ if (RESET_L = '0') then
+ addr <= (others => '0');
+ elsif falling_edge(busctrl_addr) then -- yuk
+ addr <= I_DA;
+ end if;
+ end process;
+
+ p_wdata : process(reset_l, busctrl_we, addr)
+ begin
+ if (RESET_L = '0') then
+ reg <= (others => (others => '0'));
+ elsif falling_edge(busctrl_we) then
+ case addr(3 downto 0) is
+ when x"0" => reg(0) <= I_DA;
+ when x"1" => reg(1) <= I_DA;
+ when x"2" => reg(2) <= I_DA;
+ when x"3" => reg(3) <= I_DA;
+ when x"4" => reg(4) <= I_DA;
+ when x"5" => reg(5) <= I_DA;
+ when x"6" => reg(6) <= I_DA;
+ when x"7" => reg(7) <= I_DA;
+ when x"8" => reg(8) <= I_DA;
+ when x"9" => reg(9) <= I_DA;
+ when x"A" => reg(10) <= I_DA;
+ when x"B" => reg(11) <= I_DA;
+ when x"C" => reg(12) <= I_DA;
+ when x"D" => reg(13) <= I_DA;
+ when x"E" => reg(14) <= I_DA;
+ when x"F" => reg(15) <= I_DA;
+ when others => null;
+ end case;
+ end if;
+
+ env_reset <= '0';
+ if (busctrl_we = '1') and (addr(3 downto 0) = x"D") then
+ env_reset <= '1';
+ end if;
+ end process;
+
+ p_rdata : process(busctrl_re, addr, reg)
+ begin
+ O_DA <= (others => '0'); -- 'X'
+ if (busctrl_re = '1') then -- not necessary, but useful for putting 'X's in the simulator
+ case addr(3 downto 0) is
+ when x"0" => O_DA <= reg(0) ;
+ when x"1" => O_DA <= "0000" & reg(1)(3 downto 0) ;
+ when x"2" => O_DA <= reg(2) ;
+ when x"3" => O_DA <= "0000" & reg(3)(3 downto 0) ;
+ when x"4" => O_DA <= reg(4) ;
+ when x"5" => O_DA <= "0000" & reg(5)(3 downto 0) ;
+ when x"6" => O_DA <= "000" & reg(6)(4 downto 0) ;
+ when x"7" => O_DA <= reg(7) ;
+ when x"8" => O_DA <= "000" & reg(8)(4 downto 0) ;
+ when x"9" => O_DA <= "000" & reg(9)(4 downto 0) ;
+ when x"A" => O_DA <= "000" & reg(10)(4 downto 0) ;
+ when x"B" => O_DA <= reg(11);
+ when x"C" => O_DA <= reg(12);
+ when x"D" => O_DA <= "0000" & reg(13)(3 downto 0);
+ when x"E" => if (reg(7)(6) = '0') then -- input
+ O_DA <= ioa_inreg;
+ else
+ O_DA <= reg(14); -- read output reg
+ end if;
+ when x"F" => if (Reg(7)(7) = '0') then
+ O_DA <= iob_inreg;
+ else
+ O_DA <= reg(15);
+ end if;
+ when others => null;
+ end case;
+ end if;
+ end process;
+ --
+ p_divider : process
+ begin
+ wait until rising_edge(CLK);
+ -- / 8 when SEL is high and /16 when SEL is low
+ if (ENA = '1') then
+ ena_div <= '0';
+ ena_div_noise <= '0';
+ if (cnt_div = "0000") then
+ cnt_div <= (not I_SEL_L) & "111";
+ ena_div <= '1';
+
+ noise_div <= not noise_div;
+ if (noise_div = '1') then
+ ena_div_noise <= '1';
+ end if;
+ else
+ cnt_div <= cnt_div - "1";
+ end if;
+ end if;
+ end process;
+
+ p_noise_gen : process
+ variable noise_gen_comp : std_logic_vector(4 downto 0);
+ variable poly17_zero : std_logic;
+ begin
+ wait until rising_edge(CLK);
+
+ if (reg(6)(4 downto 0) = "00000") then
+ noise_gen_comp := "00000";
+ else
+ noise_gen_comp := (reg(6)(4 downto 0) - "1");
+ end if;
+
+ poly17_zero := '0';
+ if (poly17 = "00000000000000000") then poly17_zero := '1'; end if;
+
+ if (ENA = '1') then
+
+ if (ena_div_noise = '1') then -- divider ena
+
+ if (noise_gen_cnt >= noise_gen_comp) then
+ noise_gen_cnt <= "00000";
+ poly17 <= (poly17(0) xor poly17(2) xor poly17_zero) & poly17(16 downto 1);
+ else
+ noise_gen_cnt <= (noise_gen_cnt + "1");
+ end if;
+ end if;
+ end if;
+ end process;
+ noise_gen_op <= poly17(0);
+
+ p_tone_gens : process
+ variable tone_gen_freq : array_3x12;
+ variable tone_gen_comp : array_3x12;
+ begin
+ wait until rising_edge(CLK);
+
+ -- looks like real chips count up - we need to get the Exact behaviour ..
+ tone_gen_freq(1) := reg(1)(3 downto 0) & reg(0);
+ tone_gen_freq(2) := reg(3)(3 downto 0) & reg(2);
+ tone_gen_freq(3) := reg(5)(3 downto 0) & reg(4);
+ -- period 0 = period 1
+ for i in 1 to 3 loop
+ if (tone_gen_freq(i) = x"000") then
+ tone_gen_comp(i) := x"000";
+ else
+ tone_gen_comp(i) := (tone_gen_freq(i) - "1");
+ end if;
+ end loop;
+
+ if (ENA = '1') then
+ for i in 1 to 3 loop
+ if (ena_div = '1') then -- divider ena
+
+ if (tone_gen_cnt(i) >= tone_gen_comp(i)) then
+ tone_gen_cnt(i) <= x"000";
+ tone_gen_op(i) <= not tone_gen_op(i);
+ else
+ tone_gen_cnt(i) <= (tone_gen_cnt(i) + "1");
+ end if;
+ end if;
+ end loop;
+ end if;
+ end process;
+
+ p_envelope_freq : process
+ variable env_gen_freq : std_logic_vector(15 downto 0);
+ variable env_gen_comp : std_logic_vector(15 downto 0);
+ begin
+ wait until rising_edge(CLK);
+ env_gen_freq := reg(12) & reg(11);
+ -- envelope freqs 1 and 0 are the same.
+ if (env_gen_freq = x"0000") then
+ env_gen_comp := x"0000";
+ else
+ env_gen_comp := (env_gen_freq - "1");
+ end if;
+
+ if (ENA = '1') then
+ env_ena <= '0';
+ if (ena_div = '1') then -- divider ena
+ if (env_gen_cnt >= env_gen_comp) then
+ env_gen_cnt <= x"0000";
+ env_ena <= '1';
+ else
+ env_gen_cnt <= (env_gen_cnt + "1");
+ end if;
+ end if;
+ end if;
+ end process;
+
+ p_envelope_shape : process(env_reset, CLK)
+ variable is_bot : boolean;
+ variable is_bot_p1 : boolean;
+ variable is_top_m1 : boolean;
+ variable is_top : boolean;
+ begin
+ -- envelope shapes
+ -- C AtAlH
+ -- 0 0 x x \___
+ --
+ -- 0 1 x x /___
+ --
+ -- 1 0 0 0 \\\\
+ --
+ -- 1 0 0 1 \___
+ --
+ -- 1 0 1 0 \/\/
+ -- ___
+ -- 1 0 1 1 \
+ --
+ -- 1 1 0 0 ////
+ -- ___
+ -- 1 1 0 1 /
+ --
+ -- 1 1 1 0 /\/\
+ --
+ -- 1 1 1 1 /___
+ if (env_reset = '1') then
+ -- load initial state
+ if (reg(13)(2) = '0') then -- attack
+ env_vol <= "11111";
+ env_inc <= '0'; -- -1
+ else
+ env_vol <= "00000";
+ env_inc <= '1'; -- +1
+ end if;
+ env_hold <= '0';
+
+ elsif rising_edge(CLK) then
+ is_bot := (env_vol = "00000");
+ is_bot_p1 := (env_vol = "00001");
+ is_top_m1 := (env_vol = "11110");
+ is_top := (env_vol = "11111");
+
+ if (ENA = '1') then
+ if (env_ena = '1') then
+ if (env_hold = '0') then
+ if (env_inc = '1') then
+ env_vol <= (env_vol + "00001");
+ else
+ env_vol <= (env_vol + "11111");
+ end if;
+ end if;
+
+ -- envelope shape control.
+ if (reg(13)(3) = '0') then
+ if (env_inc = '0') then -- down
+ if is_bot_p1 then env_hold <= '1'; end if;
+ else
+ if is_top then env_hold <= '1'; end if;
+ end if;
+ else
+ if (reg(13)(0) = '1') then -- hold = 1
+ if (env_inc = '0') then -- down
+ if (reg(13)(1) = '1') then -- alt
+ if is_bot then env_hold <= '1'; end if;
+ else
+ if is_bot_p1 then env_hold <= '1'; end if;
+ end if;
+ else
+ if (reg(13)(1) = '1') then -- alt
+ if is_top then env_hold <= '1'; end if;
+ else
+ if is_top_m1 then env_hold <= '1'; end if;
+ end if;
+ end if;
+
+ elsif (reg(13)(1) = '1') then -- alternate
+ if (env_inc = '0') then -- down
+ if is_bot_p1 then env_hold <= '1'; end if;
+ if is_bot then env_hold <= '0'; env_inc <= '1'; end if;
+ else
+ if is_top_m1 then env_hold <= '1'; end if;
+ if is_top then env_hold <= '0'; env_inc <= '0'; end if;
+ end if;
+ end if;
+
+ end if;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ p_chan_mixer : process(cnt_div, reg, tone_gen_op)
+ begin
+ tone_ena_l <= '1'; tone_src <= '1';
+ noise_ena_l <= '1'; chan_vol <= "00000";
+ case cnt_div(1 downto 0) is
+ when "00" =>
+ tone_ena_l <= reg(7)(0); tone_src <= tone_gen_op(1); chan_vol <= reg(8)(4 downto 0);
+ noise_ena_l <= reg(7)(3);
+ when "01" =>
+ tone_ena_l <= reg(7)(1); tone_src <= tone_gen_op(2); chan_vol <= reg(9)(4 downto 0);
+ noise_ena_l <= reg(7)(4);
+ when "10" =>
+ tone_ena_l <= reg(7)(2); tone_src <= tone_gen_op(3); chan_vol <= reg(10)(4 downto 0);
+ noise_ena_l <= reg(7)(5);
+ when "11" => null; -- tone gen outputs become valid on this clock
+ when others => null;
+ end case;
+ end process;
+
+ p_op_mixer : process
+ variable chan_mixed : std_logic;
+ variable chan_amp : std_logic_vector(4 downto 0);
+ begin
+ wait until rising_edge(CLK);
+ if (ENA = '1') then
+
+ chan_mixed := (tone_ena_l or tone_src) and (noise_ena_l or noise_gen_op);
+
+ chan_amp := (others => '0');
+ if (chan_mixed = '1') then
+ if (chan_vol(4) = '0') then
+ if (chan_vol(3 downto 0) = "0000") then -- nothing is easy ! make sure quiet is quiet
+ chan_amp := "00000";
+ else
+ chan_amp := chan_vol(3 downto 0) & '1'; -- make sure level 31 (env) = level 15 (tone)
+ end if;
+ else
+ chan_amp := env_vol(4 downto 0);
+ end if;
+ end if;
+
+ dac_amp <= x"00";
+ case chan_amp is
+ when "11111" => dac_amp <= x"FF";
+ when "11110" => dac_amp <= x"D9";
+ when "11101" => dac_amp <= x"BA";
+ when "11100" => dac_amp <= x"9F";
+ when "11011" => dac_amp <= x"88";
+ when "11010" => dac_amp <= x"74";
+ when "11001" => dac_amp <= x"63";
+ when "11000" => dac_amp <= x"54";
+ when "10111" => dac_amp <= x"48";
+ when "10110" => dac_amp <= x"3D";
+ when "10101" => dac_amp <= x"34";
+ when "10100" => dac_amp <= x"2C";
+ when "10011" => dac_amp <= x"25";
+ when "10010" => dac_amp <= x"1F";
+ when "10001" => dac_amp <= x"1A";
+ when "10000" => dac_amp <= x"16";
+ when "01111" => dac_amp <= x"13";
+ when "01110" => dac_amp <= x"10";
+ when "01101" => dac_amp <= x"0D";
+ when "01100" => dac_amp <= x"0B";
+ when "01011" => dac_amp <= x"09";
+ when "01010" => dac_amp <= x"08";
+ when "01001" => dac_amp <= x"07";
+ when "01000" => dac_amp <= x"06";
+ when "00111" => dac_amp <= x"05";
+ when "00110" => dac_amp <= x"04";
+ when "00101" => dac_amp <= x"03";
+ when "00100" => dac_amp <= x"03";
+ when "00011" => dac_amp <= x"02";
+ when "00010" => dac_amp <= x"02";
+ when "00001" => dac_amp <= x"01";
+ when "00000" => dac_amp <= x"00";
+ when others => null;
+ end case;
+
+ if (cnt_div(1 downto 0) = "10") then
+ audio_mix <= (others => '0');
+ audio_final <= audio_mix;
+ else
+ audio_mix <= audio_mix + ("00" & dac_amp);
+ end if;
+
+ if (RESET_L = '0') then
+ O_AUDIO(7 downto 0) <= "00000000";
+ else
+ if (audio_final(9) = '0') then
+ O_AUDIO(7 downto 0) <= audio_final(8 downto 1);
+ else -- clip
+ O_AUDIO(7 downto 0) <= x"FF";
+ end if;
+ end if;
+ end if;
+ end process;
+
+ p_io_ports : process(reg)
+ begin
+ O_IOA <= reg(14);
+
+ O_IOA_OE_L <= not reg(7)(6);
+ O_IOB <= reg(15);
+ O_IOB_OE_L <= not reg(7)(7);
+ end process;
+
+ p_io_ports_inreg : process
+ begin
+ wait until rising_edge(CLK);
+ ioa_inreg <= I_IOA;
+ iob_inreg <= I_IOB;
+ end process;
+end architecture RTL;
diff --git a/cores/ht1080z/ht1080z.qpf b/cores/ht1080z/ht1080z.qpf
new file mode 100644
index 0000000..b753bcf
--- /dev/null
+++ b/cores/ht1080z/ht1080z.qpf
@@ -0,0 +1,30 @@
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 1991-2013 Altera Corporation
+# Your use of Altera Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Altera Program License
+# Subscription Agreement, Altera MegaCore Function License
+# Agreement, or other applicable license agreement, including,
+# without limitation, that your use is for the sole purpose of
+# programming logic devices manufactured by Altera and sold by
+# Altera or its authorized distributors. Please refer to the
+# applicable agreement for further details.
+#
+# -------------------------------------------------------------------------- #
+#
+# Quartus II 64-Bit
+# Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
+# Date created = 23:30:28 October 14, 2014
+#
+# -------------------------------------------------------------------------- #
+
+QUARTUS_VERSION = "13.0"
+DATE = "23:30:28 October 14, 2014"
+
+# Revisions
+
+PROJECT_REVISION = "ht1080z"
diff --git a/cores/ht1080z/ht1080z.qsf b/cores/ht1080z/ht1080z.qsf
new file mode 100644
index 0000000..445d9ce
--- /dev/null
+++ b/cores/ht1080z/ht1080z.qsf
@@ -0,0 +1,344 @@
+# -------------------------------------------------------------------------- #
+#
+# Copyright (C) 1991-2014 Altera Corporation
+# Your use of Altera Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Altera Program License
+# Subscription Agreement, Altera MegaCore Function License
+# Agreement, or other applicable license agreement, including,
+# without limitation, that your use is for the sole purpose of
+# programming logic devices manufactured by Altera and sold by
+# Altera or its authorized distributors. Please refer to the
+# applicable agreement for further details.
+#
+# -------------------------------------------------------------------------- #
+#
+# Quartus II 64-Bit
+# Version 13.1.4 Build 182 03/12/2014 SJ Full Version
+# Date created = 01:27:30 May 03, 2016
+#
+# -------------------------------------------------------------------------- #
+#
+# Notes:
+#
+# 1) The default values for assignments are stored in the file:
+# ht1080z_assignment_defaults.qdf
+# If this file doesn't exist, see file:
+# assignment_defaults.qdf
+#
+# 2) Altera recommends that you do not modify this file. This
+# file is updated automatically by the Quartus II software
+# and any changes you make may be lost or overwritten.
+#
+# -------------------------------------------------------------------------- #
+
+
+
+# Project-Wide Assignments
+# ========================
+set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1
+set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:40:24 MAY 17, 2014"
+set_global_assignment -name LAST_QUARTUS_VERSION 13.1
+set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
+set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
+set_global_assignment -name SMART_RECOMPILE ON
+set_global_assignment -name FLOW_ENABLE_IO_ASSIGNMENT_ANALYSIS ON
+
+# Pin & Location Assignments
+# ==========================
+set_location_assignment PIN_7 -to LED
+set_location_assignment PIN_54 -to CLOCK_27
+set_location_assignment PIN_144 -to VGA_R[5]
+set_location_assignment PIN_143 -to VGA_R[4]
+set_location_assignment PIN_142 -to VGA_R[3]
+set_location_assignment PIN_141 -to VGA_R[2]
+set_location_assignment PIN_137 -to VGA_R[1]
+set_location_assignment PIN_135 -to VGA_R[0]
+set_location_assignment PIN_133 -to VGA_B[5]
+set_location_assignment PIN_132 -to VGA_B[4]
+set_location_assignment PIN_125 -to VGA_B[3]
+set_location_assignment PIN_121 -to VGA_B[2]
+set_location_assignment PIN_120 -to VGA_B[1]
+set_location_assignment PIN_115 -to VGA_B[0]
+set_location_assignment PIN_114 -to VGA_G[5]
+set_location_assignment PIN_113 -to VGA_G[4]
+set_location_assignment PIN_112 -to VGA_G[3]
+set_location_assignment PIN_111 -to VGA_G[2]
+set_location_assignment PIN_110 -to VGA_G[1]
+set_location_assignment PIN_106 -to VGA_G[0]
+set_location_assignment PIN_136 -to VGA_VS
+set_location_assignment PIN_119 -to VGA_HS
+set_location_assignment PIN_65 -to AUDIO_L
+set_location_assignment PIN_80 -to AUDIO_R
+set_location_assignment PIN_105 -to SPI_DO
+set_location_assignment PIN_88 -to SPI_DI
+set_location_assignment PIN_126 -to SPI_SCK
+set_location_assignment PIN_127 -to SPI_SS2
+set_location_assignment PIN_91 -to SPI_SS3
+set_location_assignment PIN_13 -to CONF_DATA0
+set_location_assignment PIN_49 -to SDRAM_A[0]
+set_location_assignment PIN_44 -to SDRAM_A[1]
+set_location_assignment PIN_42 -to SDRAM_A[2]
+set_location_assignment PIN_39 -to SDRAM_A[3]
+set_location_assignment PIN_4 -to SDRAM_A[4]
+set_location_assignment PIN_6 -to SDRAM_A[5]
+set_location_assignment PIN_8 -to SDRAM_A[6]
+set_location_assignment PIN_10 -to SDRAM_A[7]
+set_location_assignment PIN_11 -to SDRAM_A[8]
+set_location_assignment PIN_28 -to SDRAM_A[9]
+set_location_assignment PIN_50 -to SDRAM_A[10]
+set_location_assignment PIN_30 -to SDRAM_A[11]
+set_location_assignment PIN_32 -to SDRAM_A[12]
+set_location_assignment PIN_83 -to SDRAM_DQ[0]
+set_location_assignment PIN_79 -to SDRAM_DQ[1]
+set_location_assignment PIN_77 -to SDRAM_DQ[2]
+set_location_assignment PIN_76 -to SDRAM_DQ[3]
+set_location_assignment PIN_72 -to SDRAM_DQ[4]
+set_location_assignment PIN_71 -to SDRAM_DQ[5]
+set_location_assignment PIN_69 -to SDRAM_DQ[6]
+set_location_assignment PIN_68 -to SDRAM_DQ[7]
+set_location_assignment PIN_86 -to SDRAM_DQ[8]
+set_location_assignment PIN_87 -to SDRAM_DQ[9]
+set_location_assignment PIN_98 -to SDRAM_DQ[10]
+set_location_assignment PIN_99 -to SDRAM_DQ[11]
+set_location_assignment PIN_100 -to SDRAM_DQ[12]
+set_location_assignment PIN_101 -to SDRAM_DQ[13]
+set_location_assignment PIN_103 -to SDRAM_DQ[14]
+set_location_assignment PIN_104 -to SDRAM_DQ[15]
+set_location_assignment PIN_58 -to SDRAM_BA[0]
+set_location_assignment PIN_51 -to SDRAM_BA[1]
+set_location_assignment PIN_85 -to SDRAM_DQMH
+set_location_assignment PIN_67 -to SDRAM_DQML
+set_location_assignment PIN_60 -to SDRAM_nRAS
+set_location_assignment PIN_64 -to SDRAM_nCAS
+set_location_assignment PIN_66 -to SDRAM_nWE
+set_location_assignment PIN_59 -to SDRAM_nCS
+set_location_assignment PIN_33 -to SDRAM_CKE
+set_location_assignment PIN_43 -to SDRAM_CLK
+set_location_assignment PLL_1 -to "pll:pll|altpll:altpll_component"
+
+# Classic Timing Assignments
+# ==========================
+set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
+set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
+
+# Analysis & Synthesis Assignments
+# ================================
+set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE BALANCED
+set_global_assignment -name FAMILY "Cyclone III"
+set_global_assignment -name TOP_LEVEL_ENTITY ht1080z
+set_global_assignment -name DEVICE_FILTER_PACKAGE TQFP
+set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144
+set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS ON
+set_global_assignment -name SAVE_DISK_SPACE OFF
+
+# Fitter Assignments
+# ==================
+set_global_assignment -name FITTER_EARLY_TIMING_ESTIMATE_MODE OPTIMISTIC
+set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC OFF
+set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING OFF
+set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING OFF
+set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION OFF
+set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA ON
+set_global_assignment -name PHYSICAL_SYNTHESIS_MAP_LOGIC_TO_MEMORY_FOR_AREA ON
+set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT NORMAL
+set_global_assignment -name DEVICE EP3C25E144C8
+set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL"
+set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON
+set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
+set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF
+set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO"
+set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO"
+set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO"
+set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO"
+set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
+set_global_assignment -name OPTIMIZE_HOLD_TIMING "ALL PATHS"
+set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING ON
+set_global_assignment -name FITTER_EFFORT "AUTO FIT"
+
+# Assembler Assignments
+# =====================
+set_global_assignment -name GENERATE_RBF_FILE ON
+set_global_assignment -name USE_CONFIGURATION_DEVICE OFF
+
+# SignalTap II Assignments
+# ========================
+set_global_assignment -name ENABLE_SIGNALTAP OFF
+
+# Power Estimation Assignments
+# ============================
+set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
+set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
+
+# Advanced I/O Timing Assignments
+# ===============================
+set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise
+set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall
+set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise
+set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall
+
+# ------------------------
+# start ENTITY(ht1080z)
+
+# Pin & Location Assignments
+# ==========================
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[0]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[1]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[2]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[3]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[4]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[5]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[6]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[7]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[8]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[9]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[10]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[11]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[12]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[13]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[14]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQ[15]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[0]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[1]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[2]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[3]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[4]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[5]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[6]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[7]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[8]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[9]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[10]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[11]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_A[12]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[0]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_BA[1]
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQMH
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_DQML
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nRAS
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCAS
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nWE
+set_instance_assignment -name FAST_OUTPUT_REGISTER ON -to SDRAM_nCS
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[0]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[1]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[2]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[3]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[4]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[5]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[6]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[7]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[8]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[9]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[10]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[11]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[12]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[13]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[14]
+set_instance_assignment -name FAST_OUTPUT_ENABLE_REGISTER ON -to SDRAM_DQ[15]
+
+# Fitter Assignments
+# ==================
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[3]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[4]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[5]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[6]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[7]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[8]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[9]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[10]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[11]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_A[12]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[3]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[4]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[5]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[6]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[7]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[8]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[9]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[10]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[11]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[12]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[13]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[14]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQ[15]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_BA[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQML
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_DQMH
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nRAS
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCAS
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nWE
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_nCS
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CKE
+set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SDRAM_CLK
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[5]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[4]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[3]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_R[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[5]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[4]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[3]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_G[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[5]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[4]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[3]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[2]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[1]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to VGA_B[0]
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_HS
+set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to VGA_VS
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to LED
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_L
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to AUDIO_R
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to SPI_DO
+set_instance_assignment -name CURRENT_STRENGTH_NEW 4MA -to CONF_DATA0
+
+# start DESIGN_PARTITION(Top)
+# ---------------------------
+
+# Incremental Compilation Assignments
+# ===================================
+set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
+set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
+set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
+
+# end DESIGN_PARTITION(Top)
+# -------------------------
+
+# end ENTITY(ht1080z)
+# ----------------------
+
+set_location_assignment PIN_31 -to UART_RX
+
+
+
+set_global_assignment -name ALLOW_POWER_UP_DONT_CARE ON
+set_location_assignment PLL_1 -to clkmgr|altpll_component|auto_generated|pll1
+set_global_assignment -name USE_SIGNALTAP_FILE output_files/vid.stp
+set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON
+set_global_assignment -name QIP_FILE mist/mist.qip
+set_global_assignment -name VHDL_FILE videoctrl.vhd
+set_global_assignment -name VHDL_FILE YM2149_linmix.vhd
+set_global_assignment -name VERILOG_FILE sdram.v
+set_global_assignment -name VHDL_FILE rom16k.vhd
+set_global_assignment -name VHDL_FILE ram16k.vhd
+set_global_assignment -name VHDL_FILE ps2reader.vhd
+set_global_assignment -name VHDL_FILE ps2kbd.vhd
+set_global_assignment -name VHDL_FILE ht1080z.vhd
+set_global_assignment -name QIP_FILE pll.qip
+set_global_assignment -name SIGNALTAP_FILE output_files/vid.stp
+set_global_assignment -name QIP_FILE t80/T80.qip
+set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
\ No newline at end of file
diff --git a/cores/ht1080z/ht1080z.sdc b/cores/ht1080z/ht1080z.sdc
new file mode 100644
index 0000000..d00dcde
--- /dev/null
+++ b/cores/ht1080z/ht1080z.sdc
@@ -0,0 +1,58 @@
+#************************************************************
+# THIS IS A WIZARD-GENERATED FILE.
+#
+# Version 13.1.4 Build 182 03/12/2014 SJ Full Version
+#
+#************************************************************
+
+# Copyright (C) 1991-2014 Altera Corporation
+# Your use of Altera Corporation's design tools, logic functions
+# and other software and tools, and its AMPP partner logic
+# functions, and any output files from any of the foregoing
+# (including device programming or simulation files), and any
+# associated documentation or information are expressly subject
+# to the terms and conditions of the Altera Program License
+# Subscription Agreement, Altera MegaCore Function License
+# Agreement, or other applicable license agreement, including,
+# without limitation, that your use is for the sole purpose of
+# programming logic devices manufactured by Altera and sold by
+# Altera or its authorized distributors. Please refer to the
+# applicable agreement for further details.
+
+
+
+# Clock constraints
+
+create_clock -name "CLOCK_27" -period 37.037 [get_ports {CLOCK_27}]
+create_clock -name {SPI_SCK} -period 41.666 -waveform { 20.8 41.666 } [get_ports {SPI_SCK}]
+
+# Automatically constrain PLL and other generated clocks
+derive_pll_clocks -create_base_clocks
+
+# Automatically calculate clock uncertainty to jitter and other effects.
+derive_clock_uncertainty
+
+# Clock groups
+set_clock_groups -asynchronous -group [get_clocks {SPI_SCK}] -group [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[*]}]
+
+# SDRAM delays
+set_input_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -max 6.4 [get_ports SDRAM_DQ[*]]
+set_input_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -min 3.2 [get_ports SDRAM_DQ[*]]
+
+set_output_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -max 1.5 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
+set_output_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -min -0.8 [get_ports {SDRAM_D* SDRAM_A* SDRAM_BA* SDRAM_n* SDRAM_CKE}]
+
+set_output_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -max 1.5 [get_ports {SDRAM_CLK}]
+set_output_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -min -0.8 [get_ports {SDRAM_CLK}]
+
+# Some relaxed constrain to the VGA pins. The signals should arrive together, the delay is not really important.
+set_output_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -max 0 [get_ports {VGA_*}]
+set_output_delay -clock [get_clocks {clkmgr|altpll_component|auto_generated|pll1|clk[0]}] -min -5 [get_ports {VGA_*}]
+
+set_multicycle_path -to {VGA_*[*]} -setup 2
+set_multicycle_path -to {VGA_*[*]} -hold 1
+
+set_false_path -to [get_ports {AUDIO_L}]
+set_false_path -to [get_ports {AUDIO_R}]
+set_false_path -to [get_ports {LED}]
+
diff --git a/cores/ht1080z/ht1080z.vhd b/cores/ht1080z/ht1080z.vhd
new file mode 100644
index 0000000..175db0c
--- /dev/null
+++ b/cores/ht1080z/ht1080z.vhd
@@ -0,0 +1,571 @@
+--
+-- HT 1080Z (TSR-80 clone) top level
+--
+--
+-- Copyright (c) 2016-2017 Jozsef Laszlo (rbendr@gmail.com)
+--
+-- 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.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+use IEEE.NUMERIC_STD.ALL;
+use work.mist.ALL;
+
+entity ht1080z is
+ Port ( CLOCK_27 : in STD_LOGIC;
+
+ -- SDRAM
+ SDRAM_nCS : out std_logic; -- Chip Select
+ SDRAM_DQ : inout std_logic_vector(15 downto 0); -- SDRAM Data bus 16 Bits
+ SDRAM_A : out std_logic_vector(12 downto 0); -- SDRAM Address bus 13 Bits
+ SDRAM_DQMH : out std_logic; -- SDRAM High Data Mask
+ SDRAM_DQML : out std_logic; -- SDRAM Low-byte Data Mask
+ SDRAM_nWE : out std_logic; -- SDRAM Write Enable
+ SDRAM_nCAS : out std_logic; -- SDRAM Column Address Strobe
+ SDRAM_nRAS : out std_logic; -- SDRAM Row Address Strobe
+ SDRAM_BA : out std_logic_vector(1 downto 0); -- SDRAM Bank Address
+ SDRAM_CLK : out std_logic; -- SDRAM Clock
+ SDRAM_CKE : out std_logic; -- SDRAM Clock Enable
+
+ -- SPI interface to arm io controller
+ SPI_DO : out std_logic;
+ SPI_DI : in std_logic;
+ SPI_SCK : in std_logic;
+ SPI_SS2 : in std_logic;
+ SPI_SS3 : in std_logic;
+ SPI_SS4 : in std_logic;
+ CONF_DATA0 : in std_logic;
+ VGA_R : out STD_LOGIC_VECTOR (5 downto 0);
+ VGA_G : out STD_LOGIC_VECTOR (5 downto 0);
+ VGA_B : out STD_LOGIC_VECTOR (5 downto 0);
+ VGA_HS : out STD_LOGIC;
+ VGA_VS : out STD_LOGIC;
+ LED : out STD_LOGIC;
+ AUDIO_L : out STD_LOGIC;
+ AUDIO_R : out STD_LOGIC
+ );
+end ht1080z;
+
+architecture Behavioral of ht1080z is
+
+component data_io
+ port ( sck, ss, sdi : in std_logic;
+
+ -- download info
+ downloading : out std_logic;
+ --size : out std_logic_vector(24 downto 0);
+ index : out std_logic_vector(4 downto 0);
+
+ -- external ram interface
+ clk : in std_logic;
+ wr : out std_logic;
+ addr : out std_logic_vector(24 downto 0);
+ data : out std_logic_vector(7 downto 0)
+);
+end component data_io;
+
+component sdram is
+ port( sd_data : inout std_logic_vector(15 downto 0);
+ sd_addr : out std_logic_vector(12 downto 0);
+ sd_dqm : out std_logic_vector(1 downto 0);
+ sd_ba : out std_logic_vector(1 downto 0);
+ sd_cs : out std_logic;
+ sd_we : out std_logic;
+ sd_ras : out std_logic;
+ sd_cas : out std_logic;
+ init : in std_logic;
+ clk : in std_logic;
+ clkref : in std_logic;
+ din : in std_logic_vector(7 downto 0);
+ dout : out std_logic_vector(7 downto 0);
+ addr : in std_logic_vector(24 downto 0);
+ oe : in std_logic;
+ we : in std_logic
+ );
+end component;
+
+constant CONF_STR : string := "HT1080Z;CAS;O12,Scanlines,Off,25%,50%,75%;O3,Video,PAL,NTSC;T0,Reset";
+
+ function to_slv(s: string) return std_logic_vector is
+ constant ss: string(1 to s'length) := s;
+ variable rval: std_logic_vector(1 to 8 * s'length);
+ variable p: integer;
+ variable c: integer;
+
+ begin
+ for i in ss'range loop
+ p := 8 * i;
+ c := character'pos(ss(i));
+ rval(p - 7 to p) := std_logic_vector(to_unsigned(c,8));
+ end loop;
+ return rval;
+
+ end function;
+
+
+signal sdram_dqm : std_logic_vector(1 downto 0);
+signal ram_addr : std_logic_vector(24 downto 0);
+signal ram_din : STD_LOGIC_VECTOR(7 downto 0);
+signal ram_dout : STD_LOGIC_VECTOR(7 downto 0);
+signal ram_we: std_logic;
+signal ram_oe: std_logic;
+
+signal dn_go : std_logic;
+signal dn_wr : std_logic;
+signal dn_addr : std_logic_vector(24 downto 0);
+signal dn_data : std_logic_vector(7 downto 0);
+signal dn_idx : std_logic_vector(4 downto 0);
+
+signal dn_wr_r : std_logic;
+signal dn_wr_new : std_logic;
+signal dn_addr_r : std_logic_vector(24 downto 0);
+signal dn_data_r : std_logic_vector(7 downto 0);
+
+signal res_cnt : std_logic_vector(5 downto 0) := "111111";
+signal autores : std_logic;
+
+
+signal scandoubler_disable : std_logic;
+signal ypbpr : std_logic;
+signal buttons : std_logic_vector(1 downto 0);
+
+signal PS2CLK : std_logic;
+signal PS2DAT : std_logic;
+
+signal MPS2CLK : std_logic;
+signal MPS2DAT : std_logic;
+
+signal joy0 : std_logic_vector(31 downto 0);
+signal joy1 : std_logic_vector(31 downto 0);
+
+signal status: std_logic_vector(31 downto 0);
+
+signal clk42m : std_logic;
+signal pllLocked : std_logic;
+
+signal cpua : std_logic_vector(15 downto 0);
+signal cpudo : std_logic_vector(7 downto 0);
+signal cpudi : std_logic_vector(7 downto 0);
+signal cpuwr,cpurd,cpumreq,cpuiorq,cpunmi,cpuint,cpum1,cpuClkEn,clkref : std_logic;
+
+signal rgbi : std_logic_vector(3 downto 0);
+signal hs,vs : std_logic;
+signal romdo,vramdo,ramdo,ramHdo,kbdout : std_logic_vector(7 downto 0);
+signal vramcs : std_logic;
+
+signal page,vcut,swres : std_logic;
+
+signal romrd,ramrd,ramwr,vramsel,kbdsel : std_logic;
+signal ior,iow,memr,memw : std_logic;
+signal vdata : std_logic_vector(7 downto 0);
+
+signal clk42div : std_logic_vector(4 downto 0);
+
+signal dacout : std_logic;
+signal sndBC1,sndBDIR,sndCLK : std_logic;
+signal oaudio,snddo : std_logic_vector(7 downto 0);
+
+signal ht_rgb : std_logic_vector(17 downto 0);
+signal p_hs,p_vs,vgahs,vgavs : std_logic;
+signal pclk : std_logic;
+
+signal io_ram_addr : std_logic_vector(23 downto 0);
+signal iorrd,iorrd_r : std_logic;
+
+signal audiomix : std_logic_vector(8 downto 0);
+signal tapebits : std_logic_vector(2 downto 0);
+signal speaker : std_logic_vector(7 downto 0);
+signal vga : std_logic := '0';
+signal oddline : std_logic;
+
+signal inkpulse, paperpulse, borderpulse : std_logic;
+
+begin
+
+ led <= not dn_go;--swres;
+
+ -- generate system clocks
+ clkmgr : entity work.pll
+ port map (
+ inclk0 => CLOCK_27,
+ c0 => clk42m,
+ locked => pllLocked
+ );
+
+ SDRAM_CLK <= clk42m;
+
+ process(clk42m)
+ begin
+ if rising_edge(clk42m) then
+ clk42div <= clk42div + 1;
+ -- 42 MHz/24 = 1.75 MHz
+ if clk42div = 23 then clk42div <= (others => '0'); end if;
+ end if;
+ end process;
+
+ ior <= cpurd or cpuiorq or (not cpum1);
+ iow <= cpuwr or cpuiorq;
+ memr <= cpurd or cpumreq;
+ memw <= cpuwr or cpumreq;
+
+ romrd <= '1' when memr='0' and cpua autores, --swres,
+ CLK => clk42m,
+ CEN => cpuClkEn and not dn_go, -- 1.75 MHz
+ WAIT_n => '1',
+ INT_n => '1',
+ NMI_n => '1',
+ BUSRQ_n => '1',
+ M1_n => cpum1,
+ MREQ_n => cpumreq,
+ IORQ_n => cpuiorq,
+ RD_n => cpurd,
+ WR_n => cpuwr,
+ RFSH_n => open,
+ HALT_n => open,
+ BUSAK_n => open,
+ A => cpua,
+ DI => cpudi,
+ DO => cpudo
+ );
+
+ cpudi <= --romdo when romrd='1' else
+ --ramdo when ramrd='1' else
+ --ram_dout when romrd='1' else
+ --ram_dout when ramrd='1' else
+ vramdo when vramsel='1' else
+ kbdout when kbdsel='1' else
+ x"30" when ior='0' and cpua(7 downto 0)=x"fd" else -- printer io read
+ --ram_dout when iorrd='1' else
+ --x"ff";
+ ram_dout;
+
+
+ vdata <= cpudo when cpudo>x"1f" else cpudo or x"40";
+ -- video ram at 0x3C00
+ video : entity work.videoctrl
+ port map (
+ reset => autores, --swres and pllLocked,
+ clk42 => clk42m,
+ a => cpua(13 downto 0),
+ din => vdata,--cpudo,
+ dout => vramdo,
+ mreq => cpumreq,
+ iorq => cpuiorq,
+ wr => cpuwr,
+ cs => not vramsel,
+ hz60 => status(3),
+ vcut => vcut,
+ vvga => '0',
+ page => page,
+ rgbi => rgbi,
+ pclk => pclk,
+ inkp => inkpulse,
+ paperp => paperpulse,
+ borderp => borderpulse,
+ oddline => oddline,
+ hsync => hs,
+ vsync => vs
+ );
+
+ kbd : entity work.ps2kbd
+ port map (
+ RESET => not pllLocked,
+ KBCLK => ps2clk,
+ KBDAT => ps2dat,
+ SWRES => swres,
+ CLK => clk42m,
+ A => cpua(7 downto 0),
+ DOUT => kbdout,
+ PAGE => page,
+ VCUT => vcut,
+ INKP => inkpulse,
+ PAPERP => paperpulse,
+ BORDERP => borderpulse
+ );
+
+ -- PSG
+ -- out 1e = data port
+ -- out 1f = register index
+
+ soundchip : entity work.YM2149
+ port map (
+ -- data bus
+ I_DA => cpudo,
+ O_DA => open,
+ O_DA_OE_L => open,
+ -- control
+ I_A9_L => '0',
+ I_A8 => '1',
+ I_BDIR => sndBDIR,
+ I_BC2 => '1',
+ I_BC1 => sndBC1,
+ I_SEL_L => '1',
+
+ O_AUDIO => oaudio,
+ -- port a
+ I_IOA => "ZZZZZZZZ",
+ O_IOA => open,
+ O_IOA_OE_L => open,
+ -- port b
+ I_IOB => "ZZZZZZZZ",
+ O_IOB => open,
+ O_IOB_OE_L => open,
+ --
+ ENA => cpuClkEn,
+ RESET_L => autores,--swres and pllLocked,
+ CLK => clk42m
+ );
+ sndBDIR <= '1' when cpua(7 downto 1)="0001111" and iow='0' else '0';
+ sndBC1 <= cpua(0);
+
+ -- Delta-Sigma DAC for audio (one channel, mono in this implementation)
+ audiodac : entity work.dac
+ port map (
+ clk_i => clk42m,
+ res_n_i => swres and pllLocked,
+ dac_i => audiomix(8 downto 1), --oaudio,
+ dac_o => dacout
+ );
+
+ with tapebits select speaker <=
+ "00100000" when "001",
+ "00010000" when "000"|"011",
+ "00000000" when others;
+
+ audiomix <= ('0' & oaudio) + ('0' & speaker);
+
+ AUDIO_L <= dacout;
+ AUDIO_R <= dacout;
+
+ -- fix palette for now
+ --with rgbi select rgb <=
+ with rgbi select ht_rgb <=
+ "000000000000000000" when "0000",
+ "000000000000100000" when "0001",
+ "000000100000000000" when "0010",
+ "000000100000100000" when "0011",
+ "100000000000000000" when "0100",
+ "100000000000100000" when "0101",
+ "110000011000000000" when "0110",
+ "100000100000100000" when "0111",
+ "110000110000110000" when "1000",
+ "000000000000111100" when "1001",
+ "000000111100000000" when "1010",
+ "000000111100111100" when "1011",
+ "111110000000000000" when "1100",
+ "111100000000111100" when "1101",
+ "111110111110000000" when "1110",
+ "111110111110111110" when others;
+
+ user_io: work.mist.user_io
+ generic map (STRLEN => CONF_STR'length)
+ port map (
+ clk_sys => clk42m,
+ conf_str => to_slv(CONF_STR),
+
+ SPI_CLK => SPI_SCK ,
+ SPI_SS_IO => CONF_DATA0 ,
+ SPI_MISO => SPI_DO ,
+ SPI_MOSI => SPI_DI ,
+
+ status => status,
+ buttons => buttons,
+
+ -- ps2 interface
+ ps2_kbd_clk => ps2CLK,
+ ps2_kbd_data => ps2DAT,
+ ps2_mouse_clk => mps2CLK,
+ ps2_mouse_data => mps2DAT,
+
+ joystick_0 => joy0,
+ joystick_1 => joy1,
+
+ scandoubler_disable => scandoubler_disable,
+ ypbpr => ypbpr
+ );
+
+mist_video : work.mist.mist_video
+ generic map (
+ SD_HCNT_WIDTH => 10,
+ OSD_COLOR => "110")
+ port map (
+ clk_sys => clk42m,
+ scandoubler_disable => scandoubler_disable,
+ scanlines => status(2 downto 1),
+ ypbpr => ypbpr,
+ rotate => "00",
+ SPI_SCK => SPI_SCK,
+ SPI_SS3 => SPI_SS3,
+ SPI_DI => SPI_DI,
+
+ R => ht_rgb(5 downto 0),
+ G => ht_rgb(11 downto 6),
+ B => ht_rgb(17 downto 12),
+ HSync => hs,
+ VSync => vs,
+
+ VGA_R => VGA_R,
+ VGA_G => VGA_G,
+ VGA_B => VGA_B,
+ VGA_HS => VGA_HS,
+ VGA_VS => VGA_VS
+);
+
+ sdram_inst : sdram
+ port map( sd_data => SDRAM_DQ,
+ sd_addr => SDRAM_A,
+ sd_dqm => sdram_dqm,
+ sd_cs => SDRAM_nCS,
+ sd_ba => SDRAM_BA,
+ sd_we => SDRAM_nWE,
+ sd_ras => SDRAM_nRAS,
+ sd_cas => SDRAM_nCAS,
+ clk => clk42m,
+ clkref => clkref,
+ init => not pllLocked,
+ din => ram_din,
+ addr => ram_addr,
+ we => ram_we,
+ oe => ram_oe,
+ dout => ram_dout
+ );
+ --ram_addr <= "000000000" & cpua when dn_go='0' else dn_addr_r;
+ ram_din <= cpudo when dn_go='0' else dn_data_r;
+ ram_we <= ((not memw) and (cpua(15) or cpua(14))) when dn_go='0' else dn_wr_r;
+ --ram_oe <= not memr when dn_go='0' else '0';
+
+ ram_addr <= "0" & io_ram_addr when iorrd='1' else "000000000" & cpua when dn_go='0' else dn_addr_r;
+ ram_oe <= '1' when iorrd='1' else not memr when dn_go='0' else '0';
+
+ -- sdram interface
+ SDRAM_CKE <= '1';
+ SDRAM_DQMH <= sdram_dqm(1);
+ SDRAM_DQML <= sdram_dqm(0);
+
+
+ dataio : data_io
+ port map (
+ sck => SPI_SCK,
+ ss => SPI_SS2,
+ sdi => SPI_DI,
+
+ downloading => dn_go,
+ --size => ioctl_size,
+ index => dn_idx,
+
+ -- ram interface
+ clk => clk42m,
+ wr => dn_wr,
+ addr => dn_addr,
+ data => dn_data
+ );
+
+ process(clk42m)
+ -- sync wr from data io to sdram clkref
+ begin
+ if rising_edge(clk42m) then
+ if dn_wr='1' then
+ dn_wr_new <= '1';
+ dn_data_r <= dn_data;
+ dn_addr_r <= dn_addr;
+ end if;
+ if clkref = '1' then
+ if dn_wr_new = '1' then
+ dn_wr_r <= '1';
+ dn_wr_new <= '0';
+ else
+ dn_wr_r <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+ process (clk42m)
+ begin
+ if rising_edge(clk42m) then
+ if pllLocked='0' or status(0)='1' or buttons(1) = '1' then
+ res_cnt <= "000000";
+ else
+ if (res_cnt/="111111") then
+ res_cnt <= res_cnt+1;
+ end if;
+ end if;
+ end if;
+ end process;
+
+ cpuClkEn <= '1' when clk42div = 0 else '0'; -- 42/24 = 1.75 MHz
+ clkref <= '1' when clk42div = 0 or clk42div = 12 else '0'; -- 42/24 = 1.75 MHz
+ autores <= '1' when res_cnt="111111" else '0';
+
+
+ process (clk42m, dn_go,autores)
+ begin
+ if dn_go='1' or autores='0' then
+ io_ram_addr <= x"010000"; -- above 64k
+ iorrd_r<='0';
+ elsif rising_edge(clk42m) then
+ if cpuClkEn = '1' then
+ if iow='0' and cpua(7 downto 0)=x"ff" then
+ tapebits <= cpudo(2 downto 0);
+ end if;
+ if iow='0' and cpua(7 downto 2)="000001" then -- out 4 5 6
+ case cpua(1 downto 0) is
+ when "00"=> io_ram_addr(7 downto 0) <= cpudo;
+ when "01"=> io_ram_addr(15 downto 8) <= cpudo;
+ when "10"=> io_ram_addr(23 downto 16) <= cpudo;
+ when others => null;
+ end case;
+ end if;
+ iorrd_r<=iorrd;
+ if iorrd='0' and iorrd_r='1' then
+ io_ram_addr <= io_ram_addr + 1;
+ end if;
+ end if;
+ end if;
+ end process;
+
+
+end Behavioral;
diff --git a/cores/ht1080z/mist/dac.vhd b/cores/ht1080z/mist/dac.vhd
new file mode 100644
index 0000000..9b209e5
--- /dev/null
+++ b/cores/ht1080z/mist/dac.vhd
@@ -0,0 +1,71 @@
+-------------------------------------------------------------------------------
+--
+-- Delta-Sigma DAC
+--
+-- $Id: dac.vhd,v 1.1 2006/05/10 20:57:06 arnim Exp $
+--
+-- Refer to Xilinx Application Note XAPP154.
+--
+-- This DAC requires an external RC low-pass filter:
+--
+-- dac_o 0---XXXXX---+---0 analog audio
+-- 3k3 |
+-- === 4n7
+-- |
+-- GND
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity dac is
+
+ generic (
+ msbi_g : integer := 7
+ );
+ port (
+ clk_i : in std_logic;
+ res_n_i : in std_logic;
+ dac_i : in std_logic_vector(msbi_g downto 0);
+ dac_o : out std_logic
+ );
+
+end dac;
+
+library ieee;
+use ieee.numeric_std.all;
+
+architecture rtl of dac is
+
+ signal DACout_q : std_logic;
+ signal DeltaAdder_s,
+ SigmaAdder_s,
+ SigmaLatch_q,
+ DeltaB_s : unsigned(msbi_g+2 downto 0);
+
+begin
+
+ DeltaB_s(msbi_g+2 downto msbi_g+1) <= SigmaLatch_q(msbi_g+2) &
+ SigmaLatch_q(msbi_g+2);
+ DeltaB_s(msbi_g downto 0) <= (others => '0');
+
+ DeltaAdder_s <= unsigned('0' & '0' & dac_i) + DeltaB_s;
+
+ SigmaAdder_s <= DeltaAdder_s + SigmaLatch_q;
+
+ seq: process (clk_i, res_n_i)
+ begin
+ if res_n_i = '0' then
+ SigmaLatch_q <= to_unsigned(2**(msbi_g+1), SigmaLatch_q'length);
+ DACout_q <= '0';
+
+ elsif clk_i'event and clk_i = '1' then
+ SigmaLatch_q <= SigmaAdder_s;
+ DACout_q <= SigmaLatch_q(msbi_g+2);
+ end if;
+ end process seq;
+
+ dac_o <= DACout_q;
+
+end rtl;
diff --git a/cores/ht1080z/mist/data_io.v b/cores/ht1080z/mist/data_io.v
new file mode 100644
index 0000000..1aae9d7
--- /dev/null
+++ b/cores/ht1080z/mist/data_io.v
@@ -0,0 +1,121 @@
+//
+// data_io.v
+//
+// io controller writable ram for the MiST board
+// http://code.google.com/p/mist-board/
+//
+// ZX Spectrum adapted version
+//
+// Copyright (c) 2015 Till Harbaum
+//
+// This source file is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This source file is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+
+module data_io (
+ // io controller spi interface
+ input sck,
+ input ss,
+ input sdi,
+
+ output downloading, // signal indicating an active download
+ output reg [4:0] index, // menu index used to upload the file
+
+ // external ram interface
+ input clk,
+ output reg wr,
+ output reg [24:0] addr,
+ output reg [7:0] data
+);
+
+// *********************************************************************************
+// spi client
+// *********************************************************************************
+
+// this core supports only the display related OSD commands
+// of the minimig
+reg [6:0] sbuf;
+reg [7:0] cmd;
+reg [4:0] cnt;
+reg rclk;
+
+localparam UIO_FILE_TX = 8'h53;
+localparam UIO_FILE_TX_DAT = 8'h54;
+localparam UIO_FILE_INDEX = 8'h55;
+
+assign downloading = downloading_reg;
+reg downloading_reg = 1'b0;
+
+// data_io has its own SPI interface to the io controller
+always@(posedge sck, posedge ss) begin
+ if(ss == 1'b1)
+ cnt <= 5'd0;
+ else begin
+ rclk <= 1'b0;
+
+ // don't shift in last bit. It is evaluated directly
+ // when writing to ram
+ if(cnt != 15)
+ sbuf <= { sbuf[5:0], sdi};
+
+ // increase target address after write
+ if(rclk)
+ addr <= addr + 1'd1;
+
+ // count 0-7 8-15 8-15 ...
+ if(cnt < 15) cnt <= cnt + 4'd1;
+ else cnt <= 4'd8;
+
+ // finished command byte
+ if(cnt == 7)
+ cmd <= {sbuf, sdi};
+
+ // prepare/end transmission
+ if((cmd == UIO_FILE_TX) && (cnt == 15)) begin
+ // prepare
+ if(sdi) begin
+ //addr <= 25'd0;
+ // pppppppp
+ // xxxx....xxxx....
+ if (index==5'b00000) addr <= 25'b0000000000000000000000000;
+ else addr <= 25'b0000000010000000000000000;
+ //addr <= 25'b0000000001100000000000000;
+ downloading_reg <= 1'b1;
+ end else
+ downloading_reg <= 1'b0;
+ end
+
+ // command 0x54: UIO_FILE_TX
+ if((cmd == UIO_FILE_TX_DAT) && (cnt == 15)) begin
+ data <= {sbuf, sdi};
+ rclk <= 1'b1;
+ end
+
+ // expose file (menu) index
+ if((cmd == UIO_FILE_INDEX) && (cnt == 15))
+ index <= {sbuf[3:0], sdi};
+ end
+end
+
+reg rclkD, rclkD2;
+always@(posedge clk) begin
+ // bring rclk from spi clock domain into c64 clock domain
+ rclkD <= rclk;
+ rclkD2 <= rclkD;
+ wr <= 1'b0;
+
+ if(rclkD && !rclkD2)
+ wr <= 1'b1;
+end
+
+endmodule
diff --git a/cores/ht1080z/mist/mist.qip b/cores/ht1080z/mist/mist.qip
new file mode 100644
index 0000000..5aefaaa
--- /dev/null
+++ b/cores/ht1080z/mist/mist.qip
@@ -0,0 +1,8 @@
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) mist.vhd]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) user_io.v]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) data_io.v]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) mist_video.v]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) scandoubler.v]
+set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) osd.v]
+set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) rgb2ypbpr.sv]
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) dac.vhd]
diff --git a/cores/ht1080z/mist/mist.vhd b/cores/ht1080z/mist/mist.vhd
new file mode 100644
index 0000000..711d630
--- /dev/null
+++ b/cores/ht1080z/mist/mist.vhd
@@ -0,0 +1,102 @@
+-- user_io
+-- Interface to the MiST IO Controller
+
+-- mist_video
+-- A video pipeline for MiST. Just insert between the core video output and the VGA pins
+-- Provides an optional scandoubler, a rotateable OSD and (optional) RGb->YPbPr conversion
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+package mist is
+
+component user_io
+ generic(STRLEN : integer := 0 );
+ port (
+ clk_sys : in std_logic;
+ clk_sd : in std_logic := '0';
+ SPI_CLK, SPI_SS_IO, SPI_MOSI :in std_logic;
+ SPI_MISO : out std_logic;
+ conf_str : in std_logic_vector(8*STRLEN-1 downto 0);
+ joystick_0 : out std_logic_vector(31 downto 0);
+ joystick_1 : out std_logic_vector(31 downto 0);
+ joystick_2 : out std_logic_vector(31 downto 0);
+ joystick_3 : out std_logic_vector(31 downto 0);
+ joystick_4 : out std_logic_vector(31 downto 0);
+ joystick_analog_0 : out std_logic_vector(15 downto 0);
+ joystick_analog_1 : out std_logic_vector(15 downto 0);
+ status: out std_logic_vector(31 downto 0);
+ switches : out std_logic_vector(1 downto 0);
+ buttons : out std_logic_vector(1 downto 0);
+ scandoubler_disable : out std_logic;
+ ypbpr : out std_logic;
+
+ sd_lba : in std_logic_vector(31 downto 0) := (others => '0');
+ sd_rd : in std_logic := '0';
+ sd_wr : in std_logic := '0';
+ sd_ack : out std_logic;
+ sd_ack_conf : out std_logic;
+ sd_conf : in std_logic := '0';
+ sd_sdhc : in std_logic := '1';
+ img_size : out std_logic_vector(31 downto 0);
+ img_mounted : out std_logic;
+
+ sd_buff_addr : out std_logic_vector(8 downto 0);
+ sd_dout : out std_logic_vector(7 downto 0);
+ sd_din : in std_logic_vector(7 downto 0) := (others => '0');
+ sd_dout_strobe : out std_logic;
+ sd_din_strobe : out std_logic;
+
+ ps2_kbd_clk : out std_logic;
+ ps2_kbd_data : out std_logic;
+ key_pressed : out std_logic;
+ key_extended : out std_logic;
+ key_code : out std_logic_vector(7 downto 0);
+ key_strobe : out std_logic;
+
+ ps2_mouse_clk : out std_logic;
+ ps2_mouse_data : out std_logic;
+ mouse_x : out signed(8 downto 0);
+ mouse_y : out signed(8 downto 0);
+ mouse_flags : out std_logic_vector(7 downto 0); -- YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn
+ mouse_strobe : out std_logic
+ );
+end component user_io;
+
+component mist_video
+ generic (
+ OSD_COLOR : std_logic_vector(2 downto 0) := "110";
+ OSD_X_OFFSET : std_logic_vector(9 downto 0) := (others => '0');
+ OSD_Y_OFFSET : std_logic_vector(9 downto 0) := (others => '0');
+ SD_HCNT_WIDTH: integer := 9;
+ COLOR_DEPTH : integer := 6
+ );
+ port (
+ clk_sys : in std_logic;
+
+ SPI_SCK : in std_logic;
+ SPI_SS3 : in std_logic;
+ SPI_DI : in std_logic;
+
+ scanlines : in std_logic_vector(1 downto 0);
+ ce_divider : in std_logic := '0';
+ scandoubler_disable : in std_logic;
+ ypbpr : in std_logic;
+ rotate : in std_logic_vector(1 downto 0);
+
+ HSync : in std_logic;
+ VSync : in std_logic;
+ R : in std_logic_vector(COLOR_DEPTH-1 downto 0);
+ G : in std_logic_vector(COLOR_DEPTH-1 downto 0);
+ B : in std_logic_vector(COLOR_DEPTH-1 downto 0);
+
+ VGA_HS : out std_logic;
+ VGA_VS : out std_logic;
+ VGA_R : out std_logic_vector(5 downto 0);
+ VGA_G : out std_logic_vector(5 downto 0);
+ VGA_B : out std_logic_vector(5 downto 0)
+ );
+end component mist_video;
+
+end package;
\ No newline at end of file
diff --git a/cores/ht1080z/mist/mist_video.v b/cores/ht1080z/mist/mist_video.v
new file mode 100644
index 0000000..b5eda35
--- /dev/null
+++ b/cores/ht1080z/mist/mist_video.v
@@ -0,0 +1,143 @@
+// A video pipeline for MiST. Just insert between the core video output and the VGA pins
+// Provides an optional scandoubler, a rotateable OSD and (optional) RGb->YPbPr conversion
+
+module mist_video
+(
+ // master clock
+ // it should be 4x (or 2x) pixel clock for the scandoubler
+ input clk_sys,
+
+ // OSD SPI interface
+ input SPI_SCK,
+ input SPI_SS3,
+ input SPI_DI,
+
+ // scanlines (00-none 01-25% 10-50% 11-75%)
+ input [1:0] scanlines,
+
+ // non-scandoubled pixel clock divider 0 - clk_sys/4, 1 - clk_sys/2
+ input ce_divider,
+
+ // 0 = HVSync 31KHz, 1 = CSync 15KHz
+ input scandoubler_disable,
+ // YPbPr always uses composite sync
+ input ypbpr,
+ // Rotate OSD [0] - rotate [1] - left or right
+ input [1:0] rotate,
+
+ // video in
+ input [COLOR_DEPTH-1:0] R,
+ input [COLOR_DEPTH-1:0] G,
+ input [COLOR_DEPTH-1:0] B,
+
+ input HSync,
+ input VSync,
+
+ // MiST video output signals
+ output [5:0] VGA_R,
+ output [5:0] VGA_G,
+ output [5:0] VGA_B,
+ output VGA_VS,
+ output VGA_HS
+);
+
+parameter OSD_COLOR = 3'd4;
+parameter OSD_X_OFFSET = 10'd0;
+parameter OSD_Y_OFFSET = 10'd0;
+parameter SD_HCNT_WIDTH = 9;
+parameter COLOR_DEPTH = 6; // 1-6
+
+wire [5:0] SD_R_O;
+wire [5:0] SD_G_O;
+wire [5:0] SD_B_O;
+wire SD_HS_O;
+wire SD_VS_O;
+
+reg [5:0] R_full;
+reg [5:0] G_full;
+reg [5:0] B_full;
+
+always @(*) begin
+ if (COLOR_DEPTH == 6) begin
+ R_full = R;
+ G_full = G;
+ B_full = B;
+ end else if (COLOR_DEPTH == 2) begin
+ R_full = {3{R}};
+ G_full = {3{G}};
+ B_full = {3{B}};
+ end else if (COLOR_DEPTH == 1) begin
+ R_full = {6{R}};
+ G_full = {6{G}};
+ B_full = {6{B}};
+ end else begin
+ R_full = { R, R[COLOR_DEPTH-1 -:(6-COLOR_DEPTH)] };
+ G_full = { G, G[COLOR_DEPTH-1 -:(6-COLOR_DEPTH)] };
+ B_full = { B, B[COLOR_DEPTH-1 -:(6-COLOR_DEPTH)] };
+ end
+end
+
+scandoubler #(SD_HCNT_WIDTH, COLOR_DEPTH) scandoubler
+(
+ .clk_sys ( clk_sys ),
+ .scanlines ( scanlines ),
+ .ce_divider ( ce_divider ),
+ .hs_in ( HSync ),
+ .vs_in ( VSync ),
+ .r_in ( R ),
+ .g_in ( G ),
+ .b_in ( B ),
+ .hs_out ( SD_HS_O ),
+ .vs_out ( SD_VS_O ),
+ .r_out ( SD_R_O ),
+ .g_out ( SD_G_O ),
+ .b_out ( SD_B_O )
+);
+
+wire [5:0] osd_r_o;
+wire [5:0] osd_g_o;
+wire [5:0] osd_b_o;
+
+osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR) osd
+(
+ .clk_sys ( clk_sys ),
+ .rotate ( rotate ),
+ .SPI_DI ( SPI_DI ),
+ .SPI_SCK ( SPI_SCK ),
+ .SPI_SS3 ( SPI_SS3 ),
+ .R_in ( scandoubler_disable ? R_full : SD_R_O ),
+ .G_in ( scandoubler_disable ? G_full : SD_G_O ),
+ .B_in ( scandoubler_disable ? B_full : SD_B_O ),
+ .HSync ( scandoubler_disable ? HSync : SD_HS_O ),
+ .VSync ( scandoubler_disable ? VSync : SD_VS_O ),
+ .R_out ( osd_r_o ),
+ .G_out ( osd_g_o ),
+ .B_out ( osd_b_o )
+);
+
+wire [5:0] y, pb, pr;
+
+rgb2ypbpr rgb2ypbpr
+(
+ .red ( osd_r_o ),
+ .green ( osd_g_o ),
+ .blue ( osd_b_o ),
+ .y ( y ),
+ .pb ( pb ),
+ .pr ( pr )
+);
+
+assign VGA_R = ypbpr?pr:osd_r_o;
+assign VGA_G = ypbpr? y:osd_g_o;
+assign VGA_B = ypbpr?pb:osd_b_o;
+
+wire cs = scandoubler_disable ? ~(HSync ^ VSync) : ~(SD_HS_O ^ SD_VS_O);
+wire hs = scandoubler_disable ? HSync : SD_HS_O;
+wire vs = scandoubler_disable ? VSync : SD_VS_O;
+
+// a minimig vga->scart cable expects a composite sync signal on the VGA_HS output.
+// and VCC on VGA_VS (to switch into rgb mode)
+assign VGA_HS = (scandoubler_disable || ypbpr)? cs : hs;
+assign VGA_VS = (scandoubler_disable || ypbpr)? 1'b1 : vs;
+
+endmodule
diff --git a/cores/ht1080z/mist/osd.v b/cores/ht1080z/mist/osd.v
new file mode 100644
index 0000000..5527e72
--- /dev/null
+++ b/cores/ht1080z/mist/osd.v
@@ -0,0 +1,195 @@
+// A simple OSD implementation. Can be hooked up between a cores
+// VGA output and the physical VGA pins
+
+module osd (
+ // OSDs pixel clock, should be synchronous to cores pixel clock to
+ // avoid jitter.
+ input clk_sys,
+
+ // SPI interface
+ input SPI_SCK,
+ input SPI_SS3,
+ input SPI_DI,
+
+ input [1:0] rotate, //[0] - rotate [1] - left or right
+
+ // VGA signals coming from core
+ input [5:0] R_in,
+ input [5:0] G_in,
+ input [5:0] B_in,
+ input HSync,
+ input VSync,
+
+ // VGA signals going to video connector
+ output [5:0] R_out,
+ output [5:0] G_out,
+ output [5:0] B_out
+);
+
+parameter OSD_X_OFFSET = 10'd0;
+parameter OSD_Y_OFFSET = 10'd0;
+parameter OSD_COLOR = 3'd0;
+
+localparam OSD_WIDTH = 10'd256;
+localparam OSD_HEIGHT = 10'd128;
+
+// *********************************************************************************
+// spi client
+// *********************************************************************************
+
+// this core supports only the display related OSD commands
+// of the minimig
+reg osd_enable;
+(* ramstyle = "no_rw_check" *) reg [7:0] osd_buffer[2047:0]; // the OSD buffer itself
+
+// the OSD has its own SPI interface to the io controller
+always@(posedge SPI_SCK, posedge SPI_SS3) begin
+ reg [4:0] cnt;
+ reg [10:0] bcnt;
+ reg [7:0] sbuf;
+ reg [7:0] cmd;
+
+ if(SPI_SS3) begin
+ cnt <= 0;
+ bcnt <= 0;
+ end else begin
+ sbuf <= {sbuf[6:0], SPI_DI};
+
+ // 0:7 is command, rest payload
+ if(cnt < 15) cnt <= cnt + 1'd1;
+ else cnt <= 8;
+
+ if(cnt == 7) begin
+ cmd <= {sbuf[6:0], SPI_DI};
+
+ // lower three command bits are line address
+ bcnt <= {sbuf[1:0], SPI_DI, 8'h00};
+
+ // command 0x40: OSDCMDENABLE, OSDCMDDISABLE
+ if(sbuf[6:3] == 4'b0100) osd_enable <= SPI_DI;
+ end
+
+ // command 0x20: OSDCMDWRITE
+ if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin
+ osd_buffer[bcnt] <= {sbuf[6:0], SPI_DI};
+ bcnt <= bcnt + 1'd1;
+ end
+ end
+end
+
+// *********************************************************************************
+// video timing and sync polarity anaylsis
+// *********************************************************************************
+
+// horizontal counter
+reg [9:0] h_cnt;
+reg [9:0] hs_low, hs_high;
+wire hs_pol = hs_high < hs_low;
+wire [9:0] dsp_width = hs_pol ? hs_low : hs_high;
+
+// vertical counter
+reg [9:0] v_cnt;
+reg [9:0] vs_low, vs_high;
+wire vs_pol = vs_high < vs_low;
+wire [9:0] dsp_height = vs_pol ? vs_low : vs_high;
+
+wire doublescan = (dsp_height>350);
+
+reg ce_pix;
+always @(negedge clk_sys) begin
+ integer cnt = 0;
+ integer pixsz, pixcnt;
+ reg hs;
+
+ cnt <= cnt + 1;
+ hs <= HSync;
+
+ pixcnt <= pixcnt + 1;
+ if(pixcnt == pixsz) pixcnt <= 0;
+ ce_pix <= !pixcnt;
+
+ if(hs && ~HSync) begin
+ cnt <= 0;
+ pixsz <= (cnt >> 9) - 1;
+ pixcnt <= 0;
+ ce_pix <= 1;
+ end
+end
+
+always @(posedge clk_sys) begin
+ reg hsD, hsD2;
+ reg vsD, vsD2;
+
+ if(ce_pix) begin
+ // bring hsync into local clock domain
+ hsD <= HSync;
+ hsD2 <= hsD;
+
+ // falling edge of HSync
+ if(!hsD && hsD2) begin
+ h_cnt <= 0;
+ hs_high <= h_cnt;
+ end
+
+ // rising edge of HSync
+ else if(hsD && !hsD2) begin
+ h_cnt <= 0;
+ hs_low <= h_cnt;
+ v_cnt <= v_cnt + 1'd1;
+ end else begin
+ h_cnt <= h_cnt + 1'd1;
+ end
+
+ vsD <= VSync;
+ vsD2 <= vsD;
+
+ // falling edge of VSync
+ if(!vsD && vsD2) begin
+ v_cnt <= 0;
+ vs_high <= v_cnt;
+ end
+
+ // rising edge of VSync
+ else if(vsD && !vsD2) begin
+ v_cnt <= 0;
+ vs_low <= v_cnt;
+ end
+ end
+end
+
+// area in which OSD is being displayed
+wire [9:0] h_osd_start = ((dsp_width - OSD_WIDTH)>> 1) + OSD_X_OFFSET;
+wire [9:0] h_osd_end = h_osd_start + OSD_WIDTH;
+wire [9:0] v_osd_start = ((dsp_height- (OSD_HEIGHT<> 1) + OSD_Y_OFFSET;
+wire [9:0] v_osd_end = v_osd_start + (OSD_HEIGHT<= h_osd_start) && ((h_cnt + 1'd1) < h_osd_end) &&
+ (VSync != vs_pol) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end);
+ end
+end
+
+assign R_out = !osd_de ? R_in : {osd_pixel, osd_pixel, OSD_COLOR[2], R_in[5:3]};
+assign G_out = !osd_de ? G_in : {osd_pixel, osd_pixel, OSD_COLOR[1], G_in[5:3]};
+assign B_out = !osd_de ? B_in : {osd_pixel, osd_pixel, OSD_COLOR[0], B_in[5:3]};
+
+endmodule
diff --git a/cores/ht1080z/mist/rgb2ypbpr.sv b/cores/ht1080z/mist/rgb2ypbpr.sv
new file mode 100644
index 0000000..1e1662e
--- /dev/null
+++ b/cores/ht1080z/mist/rgb2ypbpr.sv
@@ -0,0 +1,55 @@
+module rgb2ypbpr (
+ input [5:0] red,
+ input [5:0] green,
+ input [5:0] blue,
+
+ output [5:0] y,
+ output [5:0] pb,
+ output [5:0] pr
+);
+
+wire [5:0] yuv_full[225] = '{
+ 6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1,
+ 6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4,
+ 6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6,
+ 6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8,
+ 6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11,
+ 6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13,
+ 6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15,
+ 6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17,
+ 6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20,
+ 6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22,
+ 6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24,
+ 6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27,
+ 6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29,
+ 6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31,
+ 6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33,
+ 6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36,
+ 6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38,
+ 6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40,
+ 6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42,
+ 6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45,
+ 6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47,
+ 6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49,
+ 6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52,
+ 6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54,
+ 6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56,
+ 6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58,
+ 6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61,
+ 6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63,
+ 6'd63
+};
+
+wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0});
+wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0});
+wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0});
+
+wire [7:0] y_i = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8];
+wire [7:0] pb_i = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8];
+wire [7:0] pr_i = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8];
+
+assign pr = yuv_full[pr_i - 8'd16];
+assign y = yuv_full[y_i - 8'd16];
+assign pb = yuv_full[pb_i - 8'd16];
+
+endmodule
diff --git a/cores/ht1080z/mist/scandoubler.v b/cores/ht1080z/mist/scandoubler.v
new file mode 100644
index 0000000..120788c
--- /dev/null
+++ b/cores/ht1080z/mist/scandoubler.v
@@ -0,0 +1,216 @@
+//
+// scandoubler.v
+//
+// Copyright (c) 2015 Till Harbaum
+//
+// This source file is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This source file is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+// TODO: Delay vsync one line
+
+module scandoubler
+(
+ // system interface
+ input clk_sys,
+
+ // scanlines (00-none 01-25% 10-50% 11-75%)
+ input [1:0] scanlines,
+ input ce_divider, // 0 - 4, 1 - 2
+
+ // shifter video interface
+ 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 reg hs_out,
+ output reg vs_out,
+ output reg [5:0] r_out,
+ output reg [5:0] g_out,
+ output reg [5:0] b_out
+);
+
+parameter HCNT_WIDTH = 9;
+parameter COLOR_DEPTH = 6;
+
+// try to detect changes in input signal and lock input clock gate
+// it
+
+reg [1:0] i_div;
+
+reg ce_x1, ce_x2;
+
+always @(*) begin
+ if (!ce_divider) begin
+ ce_x1 = (i_div == 2'b01);
+ ce_x2 = i_div[0];
+ end else begin
+ ce_x1 = i_div[0];
+ ce_x2 = 1'b1;
+ end
+end
+
+always @(posedge clk_sys) begin
+ reg last_hs_in;
+ last_hs_in <= hs_in;
+ if(last_hs_in & !hs_in) begin
+ i_div <= 2'b00;
+ end else begin
+ i_div <= i_div + 2'd1;
+ end
+end
+
+
+// --------------------- create output signals -----------------
+// latch everything once more to make it glitch free and apply scanline effect
+reg scanline;
+reg [5:0] r;
+reg [5:0] g;
+reg [5:0] b;
+
+always @(*) begin
+ if (COLOR_DEPTH == 6) begin
+ b = sd_out[5:0];
+ g = sd_out[11:6];
+ r = sd_out[17:12];
+ end else if (COLOR_DEPTH == 2) begin
+ b = {3{sd_out[1:0]}};
+ g = {3{sd_out[3:2]}};
+ r = {3{sd_out[5:4]}};
+ end else if (COLOR_DEPTH == 1) begin
+ b = {6{sd_out[0]}};
+ g = {6{sd_out[1]}};
+ r = {6{sd_out[2]}};
+ end else begin
+ b = { sd_out[COLOR_DEPTH-1:0], sd_out[COLOR_DEPTH-1 -:(6-COLOR_DEPTH)] };
+ g = { sd_out[COLOR_DEPTH*2-1:COLOR_DEPTH], sd_out[COLOR_DEPTH*2-1 -:(6-COLOR_DEPTH)] };
+ r = { sd_out[COLOR_DEPTH*3-1:COLOR_DEPTH*2], sd_out[COLOR_DEPTH*3-1 -:(6-COLOR_DEPTH)] };
+ end
+end
+
+always @(posedge clk_sys) begin
+ if(ce_x2) begin
+ hs_out <= hs_sd;
+ vs_out <= vs_in;
+
+ // reset scanlines at every new screen
+ if(vs_out != vs_in) scanline <= 0;
+
+ // toggle scanlines at begin of every hsync
+ if(hs_out && !hs_sd) scanline <= !scanline;
+
+ // if no scanlines or not a scanline
+ if(!scanline || !scanlines) begin
+ r_out <= r;
+ g_out <= g;
+ b_out <= b;
+ end else begin
+ case(scanlines)
+ 1: begin // reduce 25% = 1/2 + 1/4
+ r_out <= {1'b0, r[5:1]} + {2'b00, r[5:2] };
+ g_out <= {1'b0, g[5:1]} + {2'b00, g[5:2] };
+ b_out <= {1'b0, b[5:1]} + {2'b00, b[5:2] };
+ end
+
+ 2: begin // reduce 50% = 1/2
+ r_out <= {1'b0, r[5:1]};
+ g_out <= {1'b0, g[5:1]};
+ b_out <= {1'b0, b[5:1]};
+ end
+
+ 3: begin // reduce 75% = 1/4
+ r_out <= {2'b00, r[5:2]};
+ g_out <= {2'b00, g[5:2]};
+ b_out <= {2'b00, b[5:2]};
+ end
+ endcase
+ end
+ end
+end
+
+// 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] hs_max;
+reg [HCNT_WIDTH-1:0] hs_rise;
+reg [HCNT_WIDTH-1:0] hcnt;
+
+always @(posedge clk_sys) begin
+ reg hsD, vsD;
+
+ if(ce_x1) begin
+ hsD <= hs_in;
+
+ // falling edge of hsync indicates start of line
+ if(hsD && !hs_in) begin
+ hs_max <= hcnt;
+ hcnt <= 0;
+ end else begin
+ hcnt <= hcnt + 1'd1;
+ end
+
+ // save position of rising edge
+ if(!hsD && hs_in) hs_rise <= hcnt;
+
+ vsD <= vs_in;
+ if(vsD != vs_in) line_toggle <= 0;
+
+ // begin of incoming hsync
+ if(hsD && !hs_in) line_toggle <= !line_toggle;
+
+ sd_buffer[{line_toggle, hcnt}] <= {r_in, g_in, b_in};
+ end
+end
+
+// ==================================================================
+// ==================== output timing generation ====================
+// ==================================================================
+
+reg [HCNT_WIDTH-1:0] sd_hcnt;
+reg hs_sd;
+
+// timing generation runs 32 MHz (twice the input signal analysis speed)
+always @(posedge clk_sys) begin
+ reg hsD;
+
+ if(ce_x2) begin
+ hsD <= hs_in;
+
+ // output counter synchronous to input and at twice the rate
+ sd_hcnt <= sd_hcnt + 1'd1;
+ if(hsD && !hs_in) sd_hcnt <= hs_max;
+ if(sd_hcnt == hs_max) sd_hcnt <= 0;
+
+ // replicate horizontal sync at twice the speed
+ if(sd_hcnt == hs_max) hs_sd <= 0;
+ if(sd_hcnt == hs_rise) hs_sd <= 1;
+
+ // read data from line sd_buffer
+ sd_out <= sd_buffer[{~line_toggle, sd_hcnt}];
+ end
+end
+
+endmodule
diff --git a/cores/ht1080z/mist/user_io.v b/cores/ht1080z/mist/user_io.v
new file mode 100644
index 0000000..b5f0f69
--- /dev/null
+++ b/cores/ht1080z/mist/user_io.v
@@ -0,0 +1,572 @@
+//
+// user_io.v
+//
+// user_io for the MiST board
+// http://code.google.com/p/mist-board/
+//
+// Copyright (c) 2014 Till Harbaum
+//
+// This source file is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This source file is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+
+// parameter STRLEN and the actual length of conf_str have to match
+
+module user_io #(parameter STRLEN=0, parameter PS2DIV=100) (
+ input [(8*STRLEN)-1:0] conf_str,
+
+ input clk_sys, // clock for system-related messages (kbd, joy, etc...)
+ input clk_sd, // clock for SD-card related messages
+
+ input SPI_CLK,
+ input SPI_SS_IO,
+ output reg SPI_MISO,
+ input SPI_MOSI,
+
+ output reg [31:0] joystick_0,
+ output reg [31:0] joystick_1,
+ output reg [31:0] joystick_2,
+ output reg [31:0] joystick_3,
+ output reg [31:0] joystick_4,
+ output reg [15:0] joystick_analog_0,
+ output reg [15:0] joystick_analog_1,
+ output [1:0] buttons,
+ output [1:0] switches,
+ output scandoubler_disable,
+ output ypbpr,
+ output reg [31:0] status,
+
+ // connection to sd card emulation
+ input [31:0] sd_lba,
+ input sd_rd,
+ input sd_wr,
+ output reg sd_ack,
+ output reg sd_ack_conf,
+ input sd_conf,
+ input sd_sdhc,
+ output reg [7:0] sd_dout, // valid on rising edge of sd_dout_strobe
+ output reg sd_dout_strobe,
+ input [7:0] sd_din,
+ output reg sd_din_strobe,
+ output reg [8:0] sd_buff_addr,
+
+ output reg img_mounted, //rising edge if a new image is mounted
+ output reg [31:0] img_size, // size of image in bytes
+
+ // ps2 keyboard/mouse emulation
+ output ps2_kbd_clk,
+ output reg ps2_kbd_data,
+ output ps2_mouse_clk,
+ output reg ps2_mouse_data,
+
+ // keyboard data
+ output reg key_pressed, // 1-make (pressed), 0-break (released)
+ output reg key_extended, // extended code
+ output reg [7:0] key_code, // key scan code
+ output reg key_strobe, // key data valid
+
+ // mouse data
+ output reg [8:0] mouse_x,
+ output reg [8:0] mouse_y,
+ output reg [7:0] mouse_flags, // YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn
+ output reg mouse_strobe, // mouse data is valid on mouse_strobe
+
+ // serial com port
+ input [7:0] serial_data,
+ input serial_strobe
+);
+
+reg [6:0] sbuf;
+reg [7:0] cmd;
+reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
+reg [9:0] byte_cnt; // counts bytes
+reg [7:0] but_sw;
+reg [2:0] stick_idx;
+
+assign buttons = but_sw[1:0];
+assign switches = but_sw[3:2];
+assign scandoubler_disable = but_sw[4];
+assign ypbpr = but_sw[5];
+
+// this variant of user_io is for 8 bit cores (type == a4) only
+wire [7:0] core_type = 8'ha4;
+
+// command byte read by the io controller
+wire [7:0] sd_cmd = { 4'h5, sd_conf, sd_sdhc, sd_wr, sd_rd };
+
+wire spi_sck = SPI_CLK;
+
+// ---------------- PS2 ---------------------
+// 8 byte fifos to store ps2 bytes
+localparam PS2_FIFO_BITS = 3;
+
+reg ps2_clk;
+always @(negedge clk_sys) begin
+ integer cnt;
+ cnt <= cnt + 1'd1;
+ if(cnt == PS2DIV) begin
+ ps2_clk <= ~ps2_clk;
+ cnt <= 0;
+ end
+end
+
+// keyboard
+reg [7:0] ps2_kbd_fifo [(2**PS2_FIFO_BITS)-1:0];
+reg [PS2_FIFO_BITS-1:0] ps2_kbd_wptr;
+reg [PS2_FIFO_BITS-1:0] ps2_kbd_rptr;
+
+// ps2 transmitter state machine
+reg [3:0] ps2_kbd_tx_state;
+reg [7:0] ps2_kbd_tx_byte;
+reg ps2_kbd_parity;
+
+assign ps2_kbd_clk = ps2_clk || (ps2_kbd_tx_state == 0);
+
+// ps2 transmitter
+// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
+reg ps2_kbd_r_inc;
+always@(posedge clk_sys) begin
+ reg ps2_clkD;
+
+ ps2_clkD <= ps2_clk;
+ if (~ps2_clkD & ps2_clk) begin
+ ps2_kbd_r_inc <= 1'b0;
+
+ if(ps2_kbd_r_inc)
+ ps2_kbd_rptr <= ps2_kbd_rptr + 1'd1;
+
+ // transmitter is idle?
+ if(ps2_kbd_tx_state == 0) begin
+ // data in fifo present?
+ if(ps2_kbd_wptr != ps2_kbd_rptr) begin
+ // load tx register from fifo
+ ps2_kbd_tx_byte <= ps2_kbd_fifo[ps2_kbd_rptr];
+ ps2_kbd_r_inc <= 1'b1;
+
+ // reset parity
+ ps2_kbd_parity <= 1'b1;
+
+ // start transmitter
+ ps2_kbd_tx_state <= 4'd1;
+
+ // put start bit on data line
+ ps2_kbd_data <= 1'b0; // start bit is 0
+ end
+ end else begin
+
+ // transmission of 8 data bits
+ if((ps2_kbd_tx_state >= 1)&&(ps2_kbd_tx_state < 9)) begin
+ ps2_kbd_data <= ps2_kbd_tx_byte[0]; // data bits
+ ps2_kbd_tx_byte[6:0] <= ps2_kbd_tx_byte[7:1]; // shift down
+ if(ps2_kbd_tx_byte[0])
+ ps2_kbd_parity <= !ps2_kbd_parity;
+ end
+
+ // transmission of parity
+ if(ps2_kbd_tx_state == 9)
+ ps2_kbd_data <= ps2_kbd_parity;
+
+ // transmission of stop bit
+ if(ps2_kbd_tx_state == 10)
+ ps2_kbd_data <= 1'b1; // stop bit is 1
+
+ // advance state machine
+ if(ps2_kbd_tx_state < 11)
+ ps2_kbd_tx_state <= ps2_kbd_tx_state + 4'd1;
+ else
+ ps2_kbd_tx_state <= 4'd0;
+ end
+ end
+end
+
+// mouse
+reg [7:0] ps2_mouse_fifo [(2**PS2_FIFO_BITS)-1:0];
+reg [PS2_FIFO_BITS-1:0] ps2_mouse_wptr;
+reg [PS2_FIFO_BITS-1:0] ps2_mouse_rptr;
+
+// ps2 transmitter state machine
+reg [3:0] ps2_mouse_tx_state;
+reg [7:0] ps2_mouse_tx_byte;
+reg ps2_mouse_parity;
+
+assign ps2_mouse_clk = ps2_clk || (ps2_mouse_tx_state == 0);
+
+// ps2 transmitter
+// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
+reg ps2_mouse_r_inc;
+always@(posedge clk_sys) begin
+ reg ps2_clkD;
+
+ ps2_clkD <= ps2_clk;
+ if (~ps2_clkD & ps2_clk) begin
+ ps2_mouse_r_inc <= 1'b0;
+
+ if(ps2_mouse_r_inc)
+ ps2_mouse_rptr <= ps2_mouse_rptr + 1'd1;
+
+ // transmitter is idle?
+ if(ps2_mouse_tx_state == 0) begin
+ // data in fifo present?
+ if(ps2_mouse_wptr != ps2_mouse_rptr) begin
+ // load tx register from fifo
+ ps2_mouse_tx_byte <= ps2_mouse_fifo[ps2_mouse_rptr];
+ ps2_mouse_r_inc <= 1'b1;
+
+ // reset parity
+ ps2_mouse_parity <= 1'b1;
+
+ // start transmitter
+ ps2_mouse_tx_state <= 4'd1;
+
+ // put start bit on data line
+ ps2_mouse_data <= 1'b0; // start bit is 0
+ end
+ end else begin
+
+ // transmission of 8 data bits
+ if((ps2_mouse_tx_state >= 1)&&(ps2_mouse_tx_state < 9)) begin
+ ps2_mouse_data <= ps2_mouse_tx_byte[0]; // data bits
+ ps2_mouse_tx_byte[6:0] <= ps2_mouse_tx_byte[7:1]; // shift down
+ if(ps2_mouse_tx_byte[0])
+ ps2_mouse_parity <= !ps2_mouse_parity;
+ end
+
+ // transmission of parity
+ if(ps2_mouse_tx_state == 9)
+ ps2_mouse_data <= ps2_mouse_parity;
+
+ // transmission of stop bit
+ if(ps2_mouse_tx_state == 10)
+ ps2_mouse_data <= 1'b1; // stop bit is 1
+
+ // advance state machine
+ if(ps2_mouse_tx_state < 11)
+ ps2_mouse_tx_state <= ps2_mouse_tx_state + 4'd1;
+ else
+ ps2_mouse_tx_state <= 4'd0;
+ end
+ end
+end
+
+// fifo to receive serial data from core to be forwarded to io controller
+
+// 16 byte fifo to store serial bytes
+localparam SERIAL_OUT_FIFO_BITS = 6;
+reg [7:0] serial_out_fifo [(2**SERIAL_OUT_FIFO_BITS)-1:0];
+reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_wptr;
+reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_rptr;
+
+wire serial_out_data_available = serial_out_wptr != serial_out_rptr;
+wire [7:0] serial_out_byte = serial_out_fifo[serial_out_rptr] /* synthesis keep */;
+wire [7:0] serial_out_status = { 7'b1000000, serial_out_data_available};
+
+// status[0] is reset signal from io controller and is thus used to flush
+// the fifo
+always @(posedge serial_strobe or posedge status[0]) begin
+ if(status[0] == 1) begin
+ serial_out_wptr <= 0;
+ end else begin
+ serial_out_fifo[serial_out_wptr] <= serial_data;
+ serial_out_wptr <= serial_out_wptr + 1'd1;
+ end
+end
+
+always@(negedge spi_sck or posedge status[0]) begin
+ if(status[0] == 1) begin
+ serial_out_rptr <= 0;
+ end else begin
+ if((byte_cnt != 0) && (cmd == 8'h1b)) begin
+ // read last bit -> advance read pointer
+ if((bit_cnt == 7) && !byte_cnt[0] && serial_out_data_available)
+ serial_out_rptr <= serial_out_rptr + 1'd1;
+ end
+ end
+end
+
+
+// SPI bit and byte counters
+always@(posedge spi_sck or posedge SPI_SS_IO) begin
+ if(SPI_SS_IO == 1) begin
+ bit_cnt <= 0;
+ byte_cnt <= 0;
+ end else begin
+ if((bit_cnt == 7)&&(~&byte_cnt))
+ byte_cnt <= byte_cnt + 8'd1;
+
+ bit_cnt <= bit_cnt + 1'd1;
+ end
+end
+
+// SPI transmitter FPGA -> IO
+reg [7:0] spi_byte_out;
+
+always@(negedge spi_sck or posedge SPI_SS_IO) begin
+ if(SPI_SS_IO == 1) begin
+ SPI_MISO <= 1'bZ;
+ end else begin
+ SPI_MISO <= spi_byte_out[~bit_cnt];
+ end
+end
+
+always@(posedge spi_sck or posedge SPI_SS_IO) begin
+ reg [31:0] sd_lba_r;
+
+ if(SPI_SS_IO == 1) begin
+ spi_byte_out <= core_type;
+ end else begin
+ // read the command byte to choose the response
+ if(bit_cnt == 7) begin
+ if(!byte_cnt) cmd <= {sbuf, SPI_MOSI};
+
+ spi_byte_out <= 0;
+ case({(!byte_cnt) ? {sbuf, SPI_MOSI} : cmd})
+ // reading config string
+ 8'h14: if(byte_cnt < STRLEN) spi_byte_out <= conf_str[(STRLEN - byte_cnt - 1)<<3 +:8];
+
+ // reading sd card status
+ 8'h16: if(byte_cnt == 0) begin
+ spi_byte_out <= sd_cmd;
+ sd_lba_r <= sd_lba;
+ end
+ else if(byte_cnt < 5) spi_byte_out <= sd_lba_r[(4-byte_cnt)<<3 +:8];
+
+ // reading sd card write data
+ 8'h18: spi_byte_out <= sd_din;
+ 8'h1b:
+ // send alternating flag byte and data
+ if(byte_cnt[0]) spi_byte_out <= serial_out_status;
+ else spi_byte_out <= serial_out_byte;
+ endcase
+ end
+ end
+end
+
+// SPI receiver IO -> FPGA
+
+reg spi_receiver_strobe_r = 0;
+reg spi_transfer_end_r = 1;
+reg [7:0] spi_byte_in;
+
+// Read at spi_sck clock domain, assemble bytes for transferring to clk_sys
+always@(posedge spi_sck or posedge SPI_SS_IO) begin
+
+ if(SPI_SS_IO == 1) begin
+ spi_transfer_end_r <= 1;
+ end else begin
+ spi_transfer_end_r <= 0;
+
+ if(bit_cnt != 7)
+ sbuf[6:0] <= { sbuf[5:0], SPI_MOSI };
+
+ // finished reading a byte, prepare to transfer to clk_sys
+ if(bit_cnt == 7) begin
+ spi_byte_in <= { sbuf, SPI_MOSI};
+ spi_receiver_strobe_r <= ~spi_receiver_strobe_r;
+ end
+ end
+end
+
+// Process bytes from SPI at the clk_sys domain
+always @(posedge clk_sys) begin
+
+ reg spi_receiver_strobe;
+ reg spi_transfer_end;
+ reg spi_receiver_strobeD;
+ reg spi_transfer_endD;
+ reg [7:0] acmd;
+ reg [7:0] abyte_cnt; // counts bytes
+
+ reg [7:0] mouse_flags_r;
+ reg [7:0] mouse_x_r;
+
+ reg key_pressed_r;
+ reg key_extended_r;
+
+ //synchronize between SPI and sys clock domains
+ spi_receiver_strobeD <= spi_receiver_strobe_r;
+ spi_receiver_strobe <= spi_receiver_strobeD;
+ spi_transfer_endD <= spi_transfer_end_r;
+ spi_transfer_end <= spi_transfer_endD;
+
+ key_strobe <= 0;
+ mouse_strobe <= 0;
+
+ if (~spi_transfer_endD & spi_transfer_end) begin
+ abyte_cnt <= 8'd0;
+ end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin
+
+ if(~&abyte_cnt)
+ abyte_cnt <= abyte_cnt + 8'd1;
+
+ if(abyte_cnt == 0) begin
+ acmd <= spi_byte_in;
+ end else begin
+ case(acmd)
+ // buttons and switches
+ 8'h01: but_sw <= spi_byte_in;
+ 8'h60: if (abyte_cnt < 5) joystick_0[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
+ 8'h61: if (abyte_cnt < 5) joystick_1[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
+ 8'h62: if (abyte_cnt < 5) joystick_2[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
+ 8'h63: if (abyte_cnt < 5) joystick_3[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
+ 8'h64: if (abyte_cnt < 5) joystick_4[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
+ 8'h04: begin
+ // store incoming ps2 mouse bytes
+ ps2_mouse_fifo[ps2_mouse_wptr] <= spi_byte_in;
+ ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1;
+ if (abyte_cnt == 1) mouse_flags_r <= spi_byte_in;
+ else if (abyte_cnt == 2) mouse_x_r <= spi_byte_in;
+ else if (abyte_cnt == 3) begin
+ // flags: YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn
+ mouse_flags <= mouse_flags_r;
+ mouse_x <= { mouse_flags_r[4], mouse_x_r };
+ mouse_y <= { mouse_flags_r[5], spi_byte_in };
+ mouse_strobe <= 1;
+ end
+ end
+ 8'h05: begin
+ // store incoming ps2 keyboard bytes
+ ps2_kbd_fifo[ps2_kbd_wptr] <= spi_byte_in;
+ ps2_kbd_wptr <= ps2_kbd_wptr + 1'd1;
+ if (abyte_cnt == 1) begin
+ key_extended_r <= 0;
+ key_pressed_r <= 1;
+ end
+ if (spi_byte_in == 8'he0) key_extended_r <= 1'b1;
+ else if (spi_byte_in == 8'hf0) key_pressed_r <= 1'b0;
+ else begin
+ key_extended <= key_extended_r;
+ key_pressed <= key_pressed_r || abyte_cnt == 1;
+ key_code <= spi_byte_in;
+ key_strobe <= 1'b1;
+ end
+ end
+
+ // joystick analog
+ 8'h1a: begin
+ // first byte is joystick index
+ if(abyte_cnt == 1)
+ stick_idx <= spi_byte_in[2:0];
+ else if(abyte_cnt == 2) begin
+ // second byte is x axis
+ if(stick_idx == 0)
+ joystick_analog_0[15:8] <= spi_byte_in;
+ else if(stick_idx == 1)
+ joystick_analog_1[15:8] <= spi_byte_in;
+ end else if(abyte_cnt == 3) begin
+ // third byte is y axis
+ if(stick_idx == 0)
+ joystick_analog_0[7:0] <= spi_byte_in;
+ else if(stick_idx == 1)
+ joystick_analog_1[7:0] <= spi_byte_in;
+ end
+ end
+
+ 8'h15: status <= spi_byte_in;
+
+ // status, 32bit version
+ 8'h1e: if(abyte_cnt<5) status[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
+
+ endcase
+ end
+ end
+end
+
+// Process SD-card related bytes from SPI at the clk_sd domain
+always @(posedge clk_sd) begin
+
+ reg spi_receiver_strobe;
+ reg spi_transfer_end;
+ reg spi_receiver_strobeD;
+ reg spi_transfer_endD;
+ reg sd_wrD;
+ reg [7:0] acmd;
+ reg [7:0] abyte_cnt; // counts bytes
+
+ //synchronize between SPI and sd clock domains
+ spi_receiver_strobeD <= spi_receiver_strobe_r;
+ spi_receiver_strobe <= spi_receiver_strobeD;
+ spi_transfer_endD <= spi_transfer_end_r;
+ spi_transfer_end <= spi_transfer_endD;
+
+ if(sd_dout_strobe) begin
+ sd_dout_strobe<= 0;
+ if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
+ end
+
+ sd_din_strobe<= 0;
+ sd_wrD <= sd_wr;
+ // fetch the first byte immediately after the write command seen
+ if (~sd_wrD & sd_wr) begin
+ sd_buff_addr <= 0;
+ sd_din_strobe <= 1;
+ end
+
+ img_mounted <= 0;
+
+ if (~spi_transfer_endD & spi_transfer_end) begin
+ abyte_cnt <= 8'd0;
+ sd_ack <= 1'b0;
+ sd_ack_conf <= 1'b0;
+ sd_dout_strobe <= 1'b0;
+ sd_din_strobe <= 1'b0;
+ sd_buff_addr <= 0;
+ end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin
+
+ if(~&abyte_cnt)
+ abyte_cnt <= abyte_cnt + 8'd1;
+
+ if(abyte_cnt == 0) begin
+ acmd <= spi_byte_in;
+
+ if(spi_byte_in == 8'h18) begin
+ sd_din_strobe <= 1'b1;
+ if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
+ end
+
+ if((spi_byte_in == 8'h17) || (spi_byte_in == 8'h18))
+ sd_ack <= 1'b1;
+
+ end else begin
+ case(acmd)
+
+ // send sector IO -> FPGA
+ 8'h17: begin
+ // flag that download begins
+ sd_dout_strobe <= 1'b1;
+ sd_dout <= spi_byte_in;
+ end
+
+ // send sector FPGA -> IO
+ 8'h18: begin
+ sd_din_strobe <= 1'b1;
+ if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
+ end
+
+ // send SD config IO -> FPGA
+ 8'h19: begin
+ // flag that download begins
+ sd_dout_strobe <= 1'b1;
+ sd_ack_conf <= 1'b1;
+ sd_dout <= spi_byte_in;
+ end
+
+ 8'h1c: img_mounted <= 1;
+
+ // send image info
+ 8'h1d: if(abyte_cnt<5) img_size[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
+ endcase
+ end
+ end
+end
+
+endmodule
diff --git a/cores/ht1080z/pll.ppf b/cores/ht1080z/pll.ppf
new file mode 100644
index 0000000..547d702
--- /dev/null
+++ b/cores/ht1080z/pll.ppf
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/cores/ht1080z/pll.qip b/cores/ht1080z/pll.qip
new file mode 100644
index 0000000..4866536
--- /dev/null
+++ b/cores/ht1080z/pll.qip
@@ -0,0 +1,4 @@
+set_global_assignment -name IP_TOOL_NAME "ALTPLL"
+set_global_assignment -name IP_TOOL_VERSION "13.1"
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "pll.vhd"]
+set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"]
diff --git a/cores/ht1080z/pll.vhd b/cores/ht1080z/pll.vhd
new file mode 100644
index 0000000..e73c1f8
--- /dev/null
+++ b/cores/ht1080z/pll.vhd
@@ -0,0 +1,360 @@
+-- megafunction wizard: %ALTPLL%
+-- GENERATION: STANDARD
+-- VERSION: WM1.0
+-- MODULE: altpll
+
+-- ============================================================
+-- File Name: pll.vhd
+-- Megafunction Name(s):
+-- altpll
+--
+-- Simulation Library Files(s):
+-- altera_mf
+-- ============================================================
+-- ************************************************************
+-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
+--
+-- 13.1.4 Build 182 03/12/2014 SJ Web Edition
+-- ************************************************************
+
+
+--Copyright (C) 1991-2014 Altera Corporation
+--Your use of Altera Corporation's design tools, logic functions
+--and other software and tools, and its AMPP partner logic
+--functions, and any output files from any of the foregoing
+--(including device programming or simulation files), and any
+--associated documentation or information are expressly subject
+--to the terms and conditions of the Altera Program License
+--Subscription Agreement, Altera MegaCore Function License
+--Agreement, or other applicable license agreement, including,
+--without limitation, that your use is for the sole purpose of
+--programming logic devices manufactured by Altera and sold by
+--Altera or its authorized distributors. Please refer to the
+--applicable agreement for further details.
+
+
+LIBRARY ieee;
+USE ieee.std_logic_1164.all;
+
+LIBRARY altera_mf;
+USE altera_mf.all;
+
+ENTITY pll IS
+ PORT
+ (
+ inclk0 : IN STD_LOGIC := '0';
+ c0 : OUT STD_LOGIC ;
+ locked : OUT STD_LOGIC
+ );
+END pll;
+
+
+ARCHITECTURE SYN OF pll IS
+
+ SIGNAL sub_wire0 : STD_LOGIC_VECTOR (4 DOWNTO 0);
+ SIGNAL sub_wire1 : STD_LOGIC ;
+ SIGNAL sub_wire2 : STD_LOGIC ;
+ SIGNAL sub_wire3 : STD_LOGIC ;
+ SIGNAL sub_wire4 : STD_LOGIC_VECTOR (1 DOWNTO 0);
+ SIGNAL sub_wire5_bv : BIT_VECTOR (0 DOWNTO 0);
+ SIGNAL sub_wire5 : STD_LOGIC_VECTOR (0 DOWNTO 0);
+
+
+
+ COMPONENT altpll
+ GENERIC (
+ bandwidth_type : STRING;
+ clk0_divide_by : NATURAL;
+ clk0_duty_cycle : NATURAL;
+ clk0_multiply_by : NATURAL;
+ clk0_phase_shift : STRING;
+ compensate_clock : STRING;
+ inclk0_input_frequency : NATURAL;
+ intended_device_family : STRING;
+ lpm_hint : STRING;
+ lpm_type : STRING;
+ operation_mode : STRING;
+ pll_type : STRING;
+ port_activeclock : STRING;
+ port_areset : STRING;
+ port_clkbad0 : STRING;
+ port_clkbad1 : STRING;
+ port_clkloss : STRING;
+ port_clkswitch : STRING;
+ port_configupdate : STRING;
+ port_fbin : STRING;
+ port_inclk0 : STRING;
+ port_inclk1 : STRING;
+ port_locked : STRING;
+ port_pfdena : STRING;
+ port_phasecounterselect : STRING;
+ port_phasedone : STRING;
+ port_phasestep : STRING;
+ port_phaseupdown : STRING;
+ port_pllena : STRING;
+ port_scanaclr : STRING;
+ port_scanclk : STRING;
+ port_scanclkena : STRING;
+ port_scandata : STRING;
+ port_scandataout : STRING;
+ port_scandone : STRING;
+ port_scanread : STRING;
+ port_scanwrite : STRING;
+ port_clk0 : STRING;
+ port_clk1 : STRING;
+ port_clk2 : STRING;
+ port_clk3 : STRING;
+ port_clk4 : STRING;
+ port_clk5 : STRING;
+ port_clkena0 : STRING;
+ port_clkena1 : STRING;
+ port_clkena2 : STRING;
+ port_clkena3 : STRING;
+ port_clkena4 : STRING;
+ port_clkena5 : STRING;
+ port_extclk0 : STRING;
+ port_extclk1 : STRING;
+ port_extclk2 : STRING;
+ port_extclk3 : STRING;
+ self_reset_on_loss_lock : STRING;
+ width_clock : NATURAL
+ );
+ PORT (
+ clk : OUT STD_LOGIC_VECTOR (4 DOWNTO 0);
+ inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
+ locked : OUT STD_LOGIC
+ );
+ END COMPONENT;
+
+BEGIN
+ sub_wire5_bv(0 DOWNTO 0) <= "0";
+ sub_wire5 <= To_stdlogicvector(sub_wire5_bv);
+ sub_wire1 <= sub_wire0(0);
+ c0 <= sub_wire1;
+ locked <= sub_wire2;
+ sub_wire3 <= inclk0;
+ sub_wire4 <= sub_wire5(0 DOWNTO 0) & sub_wire3;
+
+ altpll_component : altpll
+ GENERIC MAP (
+ bandwidth_type => "AUTO",
+ clk0_divide_by => 9,
+ clk0_duty_cycle => 50,
+ clk0_multiply_by => 14,
+ clk0_phase_shift => "0",
+ compensate_clock => "CLK0",
+ inclk0_input_frequency => 37037,
+ intended_device_family => "Cyclone III",
+ lpm_hint => "CBX_MODULE_PREFIX=pll",
+ lpm_type => "altpll",
+ operation_mode => "NORMAL",
+ pll_type => "AUTO",
+ port_activeclock => "PORT_UNUSED",
+ port_areset => "PORT_UNUSED",
+ port_clkbad0 => "PORT_UNUSED",
+ port_clkbad1 => "PORT_UNUSED",
+ port_clkloss => "PORT_UNUSED",
+ port_clkswitch => "PORT_UNUSED",
+ port_configupdate => "PORT_UNUSED",
+ port_fbin => "PORT_UNUSED",
+ port_inclk0 => "PORT_USED",
+ port_inclk1 => "PORT_UNUSED",
+ port_locked => "PORT_USED",
+ port_pfdena => "PORT_UNUSED",
+ port_phasecounterselect => "PORT_UNUSED",
+ port_phasedone => "PORT_UNUSED",
+ port_phasestep => "PORT_UNUSED",
+ port_phaseupdown => "PORT_UNUSED",
+ port_pllena => "PORT_UNUSED",
+ port_scanaclr => "PORT_UNUSED",
+ port_scanclk => "PORT_UNUSED",
+ port_scanclkena => "PORT_UNUSED",
+ port_scandata => "PORT_UNUSED",
+ port_scandataout => "PORT_UNUSED",
+ port_scandone => "PORT_UNUSED",
+ port_scanread => "PORT_UNUSED",
+ port_scanwrite => "PORT_UNUSED",
+ port_clk0 => "PORT_USED",
+ port_clk1 => "PORT_UNUSED",
+ port_clk2 => "PORT_UNUSED",
+ port_clk3 => "PORT_UNUSED",
+ port_clk4 => "PORT_UNUSED",
+ port_clk5 => "PORT_UNUSED",
+ port_clkena0 => "PORT_UNUSED",
+ port_clkena1 => "PORT_UNUSED",
+ port_clkena2 => "PORT_UNUSED",
+ port_clkena3 => "PORT_UNUSED",
+ port_clkena4 => "PORT_UNUSED",
+ port_clkena5 => "PORT_UNUSED",
+ port_extclk0 => "PORT_UNUSED",
+ port_extclk1 => "PORT_UNUSED",
+ port_extclk2 => "PORT_UNUSED",
+ port_extclk3 => "PORT_UNUSED",
+ self_reset_on_loss_lock => "OFF",
+ width_clock => 5
+ )
+ PORT MAP (
+ inclk => sub_wire4,
+ clk => sub_wire0,
+ locked => sub_wire2
+ );
+
+
+
+END SYN;
+
+-- ============================================================
+-- CNX file retrieval info
+-- ============================================================
+-- Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
+-- Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
+-- Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
+-- Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
+-- Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
+-- Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
+-- Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
+-- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
+-- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
+-- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
+-- Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
+-- Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
+-- Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
+-- Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
+-- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
+-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
+-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "1"
+-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
+-- Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "42.000000"
+-- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
+-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
+-- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
+-- Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
+-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
+-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
+-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
+-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000"
+-- Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
+-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
+-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
+-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
+-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
+-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
+-- Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
+-- Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
+-- Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
+-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
+-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
+-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
+-- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
+-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
+-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "1"
+-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "42.00000000"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
+-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
+-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
+-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
+-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
+-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
+-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
+-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
+-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
+-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
+-- Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
+-- Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
+-- Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
+-- Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
+-- Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
+-- Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
+-- Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
+-- Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif"
+-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
+-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
+-- Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
+-- Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
+-- Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
+-- Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
+-- Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
+-- Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
+-- Retrieval info: PRIVATE: SPREAD_USE STRING "0"
+-- Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
+-- Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
+-- Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
+-- Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
+-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
+-- Retrieval info: PRIVATE: USE_CLK0 STRING "1"
+-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
+-- Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
+-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
+-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
+-- Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
+-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "9"
+-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
+-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "14"
+-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
+-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
+-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"
+-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
+-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
+-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
+-- Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
+-- Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
+-- Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
+-- Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
+-- Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
+-- Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF"
+-- Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
+-- Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
+-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..0]"
+-- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
+-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
+-- Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
+-- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
+-- Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
+-- Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
+-- Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.vhd TRUE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE
+-- Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.vhd FALSE
+-- Retrieval info: LIB_FILE: altera_mf
+-- Retrieval info: CBX_MODULE_PREFIX: ON
diff --git a/cores/ht1080z/ps2kbd.vhd b/cores/ht1080z/ps2kbd.vhd
new file mode 100644
index 0000000..7cfe8f8
--- /dev/null
+++ b/cores/ht1080z/ps2kbd.vhd
@@ -0,0 +1,312 @@
+--
+-- HT 1080Z (TSR-80 clone) ps2 keyboard
+--
+--
+-- Copyright (c) 2016-2017 Jozsef Laszlo (rbendr@gmail.com)
+--
+-- 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.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+
+entity ps2kbd is
+ Port (
+ RESET : in STD_LOGIC;
+ KBCLK : in STD_LOGIC;
+ KBDAT : in STD_LOGIC;
+ SWRES : out STD_LOGIC;
+ CLK : in STD_LOGIC;
+ A : in STD_LOGIC_VECTOR(7 downto 0);
+ DOUT : out STD_LOGIC_VECTOR(7 downto 0);
+ PAGE : out STD_LOGIC;
+ VCUT : out STD_LOGIC;
+ INKP : out STD_LOGIC;
+ PAPERP : out STD_LOGIC;
+ BORDERP : out STD_LOGIC
+ );
+
+end ps2kbd;
+
+architecture Behavioral of ps2kbd is
+
+type keys is array(0 to 7) of std_logic_vector(7 downto 0);
+
+signal keypress : std_logic:='0';
+signal extkey : std_logic:='0';
+
+signal hasRead : std_logic;
+
+signal keybits : keys;
+signal keysout : keys;
+signal lastkc : std_logic;
+
+signal kbdsign : std_logic;
+signal kbddata : std_logic_vector(7 downto 0);
+signal swreset : std_logic := '1';
+
+signal pageReg : std_logic := '0';
+signal vcutReg : std_logic := '0';
+
+signal inkpulse, paperpulse, borderpulse : std_logic;
+
+
+begin
+
+ ps2rd : entity work.ps2reader
+ port map (
+ mclk => CLK,
+ PS2C => KBCLK,
+ PS2D => KBDAT,
+ rst => RESET,
+ Ps2Dout => kbddata,
+ fRd => kbdsign
+ );
+
+ process(RESET,CLK,kbdsign,kbddata)
+ variable kk : std_logic_vector(6 downto 0);
+ variable ix : integer;
+ begin
+ if RESET='1' then
+ keypress <= '0';
+ keybits(0) <= "00000000";
+ keybits(1) <= "00000000";
+ keybits(2) <= "00000000";
+ keybits(3) <= "00000000";
+ keybits(4) <= "00000000";
+ keybits(5) <= "00000000";
+ keybits(6) <= "00000000";
+ keybits(7) <= "00000000";
+
+ swreset <= '1';
+ pageReg <= '0';
+ vcutReg <= '0';
+ elsif rising_edge(CLK) then
+ if kbdsign = '1' then
+ if kbddata=x"F0" then
+ keypress <= '0'; -- released
+ --if shifrpress='1' then
+ -- keybits(7)(0)<='0';
+ -- shifrpress<='0';
+ --end if;
+ elsif kbddata=x"E0" then
+ extkey<='1';
+ else
+ keypress <= '1'; -- pressed
+
+ -- this is for ps2 read. we convert 0x83 to 0x02 (keyboard F2)
+ kk:= kbddata(6 downto 0);
+ if kbddata=x"83" then
+ kk:="0000010"; -- keyboard F7 code 0x83 converted to 0x02
+ end if;
+
+
+
+ case '0' & kk is
+
+ when x"03" => inkpulse <= keypress; -- F1
+ when x"0b" => paperpulse <= keypress; -- F2
+ when x"02" => borderpulse <= keypress; -- F3
+
+ when x"78"=> swreset <= not keypress; -- F11
+
+ when x"01"=> --F9
+ if keypress='1' then
+ vcutReg <= not vcutReg;
+ end if;
+
+ when x"09"=> --F10
+ if keypress='1' then
+ pageReg <= not pageReg;
+ end if;
+
+ -- \|
+ when x"5d"=> keybits(0)(0)<=keypress;
+ -- A
+ when x"1c"=> keybits(0)(1)<=keypress;
+ -- B
+ when x"32"=> keybits(0)(2)<=keypress;
+ -- C
+ when x"21"=> keybits(0)(3)<=keypress;
+ -- D
+ when x"23"=> keybits(0)(4)<=keypress;
+ -- E
+ when x"24"=> keybits(0)(5)<=keypress;
+ -- F
+ when x"2b"=> keybits(0)(6)<=keypress;
+ -- G
+ when x"34"=> keybits(0)(7)<=keypress;
+
+ -- H
+ when x"33"=> keybits(1)(0)<=keypress;
+ -- I
+ when x"43"=> keybits(1)(1)<=keypress;
+ -- J
+ when x"3B"=> keybits(1)(2)<=keypress;
+ -- K
+ when x"42"=> keybits(1)(3)<=keypress;
+ -- L
+ when x"4B"=> keybits(1)(4)<=keypress;
+ -- M
+ when x"3A"=> keybits(1)(5)<=keypress;
+ -- N
+ when x"31"=> keybits(1)(6)<=keypress;
+ -- O
+ when x"44"=> keybits(1)(7)<=keypress;
+
+ -- P
+ when x"4D"=> keybits(2)(0)<=keypress;
+ -- Q
+ when x"15"=> keybits(2)(1)<=keypress;
+ -- R
+ when x"2D"=> keybits(2)(2)<=keypress;
+ -- S
+ when x"1B"=> keybits(2)(3)<=keypress;
+ -- T
+ when x"2C"=> keybits(2)(4)<=keypress;
+ -- U
+ when x"3C"=> keybits(2)(5)<=keypress;
+ -- V
+ when x"2A"=> keybits(2)(6)<=keypress;
+ -- W
+ when x"1D"=> keybits(2)(7)<=keypress;
+
+ -- X
+ when x"22"=> keybits(3)(0)<=keypress;
+ -- Y
+ when x"35"=> keybits(3)(1)<=keypress;
+ -- Z
+ when x"1A"=> keybits(3)(2)<=keypress;
+ -- F2
+ when x"06"=> keybits(3)(4)<=keypress;
+ -- F3
+ when x"04"=> keybits(3)(5)<=keypress;
+ -- F4
+ when x"0C"=> keybits(3)(6)<=keypress;
+ -- F1
+ when x"05"=> keybits(3)(7)<=keypress;
+
+ -- 0
+ when x"45"=> keybits(4)(0)<=keypress;
+ -- 1
+ when x"16"=> keybits(4)(1)<=keypress;
+ -- 2
+ when x"1E"=> keybits(4)(2)<=keypress;
+ -- 3
+ when x"26"=> keybits(4)(3)<=keypress;
+ -- 4
+ when x"25"=> keybits(4)(4)<=keypress;
+ -- 5
+ when x"2E"=> keybits(4)(5)<=keypress;
+ -- 6
+ when x"36"=> keybits(4)(6)<=keypress;
+ -- 7
+ when x"3D"=> keybits(4)(7)<=keypress;
+
+ -- 8
+ when x"3E"=> keybits(5)(0)<=keypress;
+ -- 9
+ when x"46"=> keybits(5)(1)<=keypress;
+ -- *:
+ when x"0E"|x"4e" => keybits(5)(2)<=keypress;
+ -- +;
+ when x"4C"=> keybits(5)(3)<=keypress;
+ -- <,
+ when x"41"=> keybits(5)(4)<=keypress;
+ -- =-
+ when x"55"|x"7b"=> keybits(5)(5)<=keypress;
+ -- >.
+ when x"49"=> keybits(5)(6)<=keypress;
+ -- ?/
+ when x"4A"=> keybits(5)(7)<=keypress;
+
+ -- NL
+ when x"5A"=> keybits(6)(0)<=keypress;
+ -- CLR
+ when x"6C"=> keybits(6)(1)<=keypress;
+ -- BRK
+ when x"76"=> keybits(6)(2)<=keypress;
+ -- up-arrow
+ when x"75"=> keybits(6)(3)<=keypress;
+ -- dn-arrow
+ when x"72"=> keybits(6)(4)<=keypress;
+ -- lf-arrow and backspace
+ when x"6B"|x"66"=> keybits(6)(5)<=keypress;
+ -- rg-arrow
+ when x"74"=> keybits(6)(6)<=keypress;
+ -- SPA
+ when x"29"=> keybits(6)(7)<=keypress;
+
+ -- L-SHIFT R-SHIFT
+ when x"12"|x"59"=> keybits(7)(0)<=keypress;
+
+ -- numpad *
+ when x"7c"=> keybits(5)(2)<=keypress;
+ keybits(7)(0)<=keypress;
+ -- numpad +
+ when x"79"=> keybits(5)(3)<=keypress;
+ keybits(7)(0)<=keypress;
+
+ when others =>
+ null;
+ end case;
+ extkey<='0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+ SWRES <= swreset;
+ VCUT <= vcutReg;
+ PAGE <= pageReg;
+
+ keysout(0) <= keybits(0) when A(0)='1' else x"00";
+ keysout(1) <= keybits(1) when A(1)='1' else x"00";
+ keysout(2) <= keybits(2) when A(2)='1' else x"00";
+ keysout(3) <= keybits(3) when A(3)='1' else x"00";
+ keysout(4) <= keybits(4) when A(4)='1' else x"00";
+ keysout(5) <= keybits(5) when A(5)='1' else x"00";
+ keysout(6) <= keybits(6) when A(6)='1' else x"00";
+ keysout(7) <= keybits(7) when A(7)='1' else x"00";
+ DOUT <= keysout(0) or keysout(1) or keysout(2) or keysout(3) or keysout(4) or keysout(5) or keysout(6) or keysout(7);
+
+ INKP <= inkpulse;
+ PAPERP <= paperpulse;
+ BORDERP <= borderpulse;
+
+end Behavioral;
diff --git a/cores/ht1080z/ps2reader.vhd b/cores/ht1080z/ps2reader.vhd
new file mode 100644
index 0000000..da8a1ea
--- /dev/null
+++ b/cores/ht1080z/ps2reader.vhd
@@ -0,0 +1,198 @@
+----------------------------------------------------------------------------------
+-- Company: Digilent Inc.
+-- Engineer: Claudia Goga
+--
+-- Create Date: 22:33:35 11/25/06
+-- Module Name: PS2_Reader - Behavioral
+-- Target Devices: CoolRunner2 CPLD
+-- Tool versions: Xilinx ISE v7.1i
+-- Description:
+-- This module reads scan codes from the PS2 Port. Every time a
+-- new scan code is entirely received it enables the fRd signal for one
+-- main clock period.
+--
+-- Revision 0.01 - File Created
+-- Additional Comments:
+--
+----------------------------------------------------------------------------------
+
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+
+entity ps2reader is
+ Port ( mclk : in std_logic; -- System Clock
+ PS2C : in std_logic; -- PS2 Clock
+ PS2D : in std_logic; -- PS2 data
+ rst: in std_logic; -- Reset BTN0
+ Ps2Dout : out std_logic_vector(7 downto 0); -- out data
+ fRd : out std_logic); -- data valid flag
+end ps2reader;
+
+architecture Behavioral of ps2reader is
+
+------------------------------------------------------------------------
+-- SIGNAL and CONSTANT DECLARATIONS
+------------------------------------------------------------------------
+--The constants below define state codes for the PS2 Keyboard
+--reader using ONE HOT encoding.
+
+constant idle: std_logic_vector (5 downto 0):="000000";
+constant shift_data: std_logic_vector (5 downto 0):="000001";
+constant check_parity: std_logic_vector (5 downto 0):="000010";
+constant check_stopbit:std_logic_vector (5 downto 0):="000100";
+constant frame_error: std_logic_vector (5 downto 0):="001000";
+constant parity_error: std_logic_vector (5 downto 0):="010000";
+constant end_char: std_logic_vector (5 downto 0):="100000";
+
+--state register and next state register for the FSM
+signal state, next_state: std_logic_vector (5 downto 0):=idle;
+
+signal D_PS2C: std_logic:='0'; -- debounced PS2C
+signal Q1, Q2: std_logic:='0';
+
+--shift register; stores the received bits
+signal REG: std_logic_vector(7 downto 0):=X"00";
+
+signal ptysum: std_logic:='0'; -- parity sum
+signal ptycheck: std_logic:='0'; -- parity check bit
+
+signal cnt: integer range 0 to 7:=0; -- counter
+
+--The attributes below prevent the ISE compiler from
+--optimizing the state machines. The states will be implemented as
+--described in the constant declarations above.
+
+attribute fsm_extract : string;
+attribute fsm_extract of state: signal is "no";
+attribute fsm_extract of next_state: signal is "no";
+
+attribute fsm_encoding : string;
+attribute fsm_encoding of state: signal is "user";
+attribute fsm_encoding of next_state: signal is "user";
+
+attribute signal_encoding : string;
+attribute signal_encoding of state: signal is "user";
+attribute signal_encoding of next_state: signal is "user";
+
+begin
+
+----------------------------------------------------------------------
+-- MODULE IMPLEMENTATION
+----------------------------------------------------------------------
+
+----------------- Sample Keyboard Inputs -----------------------------
+
+debounce: process (mclk, PS2C, Q1, Q2)
+begin
+ if mclk'event and mclk='1' then
+ Q1<=PS2C;
+ Q2<=Q1;
+ end if;
+end process debounce;
+
+D_PS2C<= (NOT Q1) and Q2;
+
+----------------- Synchronization Process ----------------------------
+
+regstate: process (mclk, next_state, rst)
+begin
+ if rst='1' then
+ state<=idle; -- state machine reset
+ elsif mclk'EVENT and mclk='1' then
+ state<=next_state;
+ end if;
+end process regstate;
+
+-------------------- State Transitions -------------------------------
+
+transition: process (state, D_PS2C, PS2D, cnt, ptycheck)
+begin
+case state is
+ when idle=>-- idle
+ if D_PS2C='1' and PS2D='0' then -- check start bit
+ next_state<=shift_data;
+ else
+ next_state<=idle;
+ end if;
+
+ when shift_data=> -- shift in data
+ if D_PS2C='1' and cnt=7 then
+ next_state<=check_parity; -- go and check parity
+ else
+ next_state<=shift_data;
+ end if;
+
+ when check_parity=> -- check parity
+ if D_PS2C='1' and PS2D=ptycheck then
+ next_state<=check_stopbit; -- valid parity bit
+ -- go and check stopbit
+ elsif D_PS2C='1' then
+ next_state<=parity_error; -- parity error
+ else
+ next_state<=check_parity;
+ end if;
+
+ when check_stopbit=> -- check stopbit;
+ if D_PS2C='1' and PS2D='1' then
+ next_state<=end_char; -- valid stopbit, end Char
+ elsif D_PS2C='1' then
+ next_state<=frame_error; -- Frame Error
+ else
+ next_state<=check_stopbit;
+ end if;
+
+ when frame_error=> -- Frame Error
+ next_state<=idle;
+
+ when parity_error=> -- Parity Error
+ next_state<=idle;
+
+ when end_char=> -- end Char
+ next_state<=idle;
+
+ when others => next_state<=idle;
+end case;
+end process transition;
+
+
+------Counting bits and registering when state=shift_data---------------
+
+regin: process (mclk, D_PS2C, PS2D, cnt, ptysum, state)
+begin
+if state/=shift_data then
+ cnt<=0;
+ ptysum<='0';
+elsif mclk'EVENT and mclk='1' then
+ if D_PS2C='1' then
+ ptysum<=ptysum XOR PS2D; -- calculating the parity sum
+ REG(7 downto 0)<=PS2D®(7 downto 1); -- shifting data into register
+
+ if cnt=7 then
+ cnt<=0;
+ else
+ cnt<=cnt+1;
+ end if;
+ end if;
+end if;
+end process regin;
+
+------------------PARITIY SUM-------------------------------------------
+
+parity_sum: process (mclk, D_PS2C, PS2D, cnt, state, ptysum)
+begin
+if mclk'EVENT and mclk='1' then
+ if state=shift_data and D_PS2C='1' and cnt=7 then
+ ptycheck<=(NOT ptysum) XOR PS2D; --parity check bit
+ end if;
+end if;
+end process parity_sum;
+
+----------------OUTPUT ASSIGNEMENT--------------------------------------
+
+Ps2Dout<=REG;
+fRd<='1' when state=end_char else '0';
+
+end Behavioral;
\ No newline at end of file
diff --git a/cores/ht1080z/ram16k.vhd b/cores/ht1080z/ram16k.vhd
new file mode 100644
index 0000000..2292c18
--- /dev/null
+++ b/cores/ht1080z/ram16k.vhd
@@ -0,0 +1,34 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+entity ram16k is
+ Port ( clk : in STD_LOGIC;
+ a : in STD_LOGIC_VECTOR (13 downto 0);
+ din : in STD_LOGIC_VECTOR (7 downto 0);
+ dout : out STD_LOGIC_VECTOR (7 downto 0);
+ wr : in STD_LOGIC);
+end ram16k;
+
+architecture Behavioral of ram16k is
+
+type
+ ramarray is array(0 to 16383) of std_logic_vector(7 downto 0);
+
+signal
+ mem : ramarray;
+begin
+
+process(clk)
+begin
+ if rising_edge(clk) then
+ dout <= mem(conv_integer(a));
+ if wr='0' then
+ mem(conv_integer(a)) <= din;
+ end if;
+ end if;
+end process;
+
+end Behavioral;
+
diff --git a/cores/ht1080z/rom16k.vhd b/cores/ht1080z/rom16k.vhd
new file mode 100644
index 0000000..8dec906
--- /dev/null
+++ b/cores/ht1080z/rom16k.vhd
@@ -0,0 +1,1081 @@
+library IEEE;
+use IEEE.STD_LOGIC_1164.ALL;
+use IEEE.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+entity rom16k is
+ Port ( CLK : in STD_LOGIC;
+ A : in STD_LOGIC_VECTOR (13 downto 0);
+ DOUT : out STD_LOGIC_VECTOR (7 downto 0)
+ );
+
+end rom16k;
+
+architecture Behavioral of rom16k is
+
+type
+ -- 14K ROM 0000..37FF
+ romarray is array(0 to 16383) of std_logic_vector(7 downto 0);
+
+constant
+ myROM : romarray := (
+
+--x"f3",x"31",x"ff",x"7f",x"21",x"00",x"3c",x"11",x"01",x"3c",x"01",x"00",x"04",x"36",x"20",x"ed",
+--x"b0",x"21",x"43",x"00",x"11",x"00",x"3e",x"cd",x"3b",x"00",x"21",x"55",x"00",x"11",x"80",x"3e",
+--x"cd",x"3b",x"00",x"11",x"00",x"3c",x"21",x"01",x"38",x"4e",x"06",x"08",x"af",x"cb",x"01",x"ce",
+--x"00",x"12",x"1c",x"10",x"f7",x"cb",x"05",x"30",x"f0",x"18",x"e8",x"7e",x"b7",x"c8",x"23",x"12",
+--x"13",x"18",x"f8",x"48",x"54",x"31",x"30",x"38",x"30",x"5a",x"20",x"74",x"65",x"73",x"74",x"20",
+--x"63",x"6f",x"64",x"65",x"00",x"41",x"6e",x"6f",x"74",x"68",x"65",x"72",x"20",x"74",x"65",x"73",
+--x"74",x"20",x"74",x"65",x"78",x"74",x"2e",x"20",x"48",x"65",x"6c",x"6c",x"6f",x"20",x"77",x"6f",
+--x"72",x"6c",x"64",x"21",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+
+--x"f3",x"31",x"ff",x"7f",x"21",x"00",x"3c",x"11",x"01",x"3c",x"01",x"00",x"04",x"36",x"20",x"ed",
+--x"b0",x"af",x"21",x"00",x"3c",x"77",x"23",x"3c",x"20",x"fb",x"21",x"3a",x"00",x"11",x"00",x"3e",
+--x"cd",x"32",x"00",x"21",x"4c",x"00",x"11",x"80",x"3e",x"cd",x"32",x"00",x"21",x"3f",x"3c",x"34",
+--x"18",x"fd",x"7e",x"b7",x"c8",x"23",x"12",x"13",x"18",x"f8",x"48",x"54",x"31",x"30",x"38",x"30",
+--x"5a",x"20",x"74",x"65",x"73",x"74",x"20",x"63",x"6f",x"64",x"65",x"00",x"41",x"6e",x"6f",x"74",
+--x"68",x"65",x"72",x"20",x"74",x"65",x"73",x"74",x"20",x"74",x"65",x"78",x"74",x"2e",x"20",x"48",
+--x"65",x"6c",x"6c",x"6f",x"20",x"77",x"6f",x"72",x"6c",x"64",x"21",x"00",x"00",x"00",x"00",x"00",
+
+x"F3",x"AF",x"C3",x"74",x"06",x"C3",x"00",x"40",x"C3",x"00",x"40",x"E1",x"E9",x"C3",
+x"9F",x"06",x"C3",x"03",x"40",x"C5",x"06",x"01",x"18",x"2E",x"C3",x"06",x"40",x"C5",
+x"06",x"02",x"18",x"26",x"C3",x"09",x"40",x"C5",x"06",x"04",x"18",x"1E",x"C3",x"0C",
+x"40",x"11",x"15",x"40",x"18",x"E3",x"C3",x"0F",x"40",x"11",x"1D",x"40",x"18",x"E3",
+x"C3",x"12",x"40",x"11",x"25",x"40",x"18",x"DB",x"C3",x"D9",x"05",x"C9",x"00",x"00",
+x"C3",x"C2",x"03",x"CD",x"2B",x"00",x"B7",x"C0",x"18",x"F9",x"0D",x"0D",x"1F",x"1F",
+x"01",x"01",x"5B",x"1B",x"0A",x"1A",x"08",x"18",x"09",x"19",x"20",x"20",x"0B",x"78",
+x"B1",x"20",x"FB",x"C9",x"31",x"00",x"06",x"3A",x"EC",x"37",x"3C",x"FE",x"02",x"D2",
+x"00",x"00",x"C3",x"CC",x"06",x"11",x"80",x"40",x"21",x"F7",x"18",x"01",x"27",x"00",
+x"ED",x"B0",x"21",x"E5",x"41",x"36",x"3A",x"23",x"70",x"23",x"36",x"2C",x"23",x"22",
+x"A7",x"40",x"11",x"2D",x"01",x"06",x"1C",x"21",x"52",x"41",x"36",x"C3",x"23",x"73",
+x"23",x"72",x"23",x"10",x"F7",x"06",x"15",x"36",x"C9",x"23",x"23",x"23",x"10",x"F9",
+x"21",x"E8",x"42",x"70",x"31",x"F8",x"41",x"CD",x"8F",x"1B",x"CD",x"C9",x"01",x"21",
+x"05",x"01",x"CD",x"A7",x"28",x"CD",x"B3",x"1B",x"38",x"F5",x"D7",x"B7",x"20",x"12",
+x"21",x"4C",x"43",x"23",x"7C",x"B5",x"28",x"1B",x"7E",x"47",x"2F",x"77",x"BE",x"70",
+x"28",x"F3",x"18",x"11",x"CD",x"5A",x"1E",x"B7",x"C2",x"97",x"19",x"EB",x"2B",x"3E",
+x"8F",x"46",x"77",x"BE",x"70",x"20",x"CE",x"2B",x"11",x"14",x"44",x"DF",x"DA",x"7A",
+x"19",x"11",x"CE",x"FF",x"22",x"B1",x"40",x"19",x"22",x"A0",x"40",x"CD",x"4D",x"1B",
+x"21",x"11",x"01",x"CD",x"A7",x"28",x"C3",x"19",x"1A",x"52",x"45",x"41",x"44",x"59",
+x"20",x"00",x"00",x"00",x"00",x"00",x"00",x"0D",x"0D",x"0D",x"0D",x"0D",x"0D",x"0D",
+x"0D",x"0D",x"0D",x"0D",x"0D",x"0D",x"0D",x"0D",x"0D",x"0D",x"0D",x"0D",x"0D",x"0D",
+x"0D",x"0D",x"0D",x"0D",x"0D",x"0D",x"00",x"1E",x"2C",x"C3",x"A2",x"19",x"D7",x"AF",
+x"01",x"3E",x"80",x"01",x"3E",x"01",x"F5",x"CF",x"28",x"CD",x"1C",x"2B",x"FE",x"80",
+x"D2",x"4A",x"1E",x"F5",x"CF",x"2C",x"CD",x"1C",x"2B",x"FE",x"30",x"D2",x"4A",x"1E",
+x"16",x"FF",x"14",x"D6",x"03",x"30",x"FB",x"C6",x"03",x"4F",x"F1",x"87",x"5F",x"06",
+x"02",x"7A",x"1F",x"57",x"7B",x"1F",x"5F",x"10",x"F8",x"79",x"8F",x"3C",x"47",x"AF",
+x"37",x"8F",x"10",x"FD",x"4F",x"7A",x"F6",x"3C",x"57",x"1A",x"B7",x"FA",x"7C",x"01",
+x"3E",x"80",x"47",x"F1",x"B7",x"78",x"28",x"10",x"12",x"FA",x"8F",x"01",x"79",x"2F",
+x"4F",x"1A",x"A1",x"12",x"CF",x"29",x"C9",x"B1",x"18",x"F9",x"A1",x"C6",x"FF",x"9F",
+x"E5",x"CD",x"8D",x"09",x"E1",x"18",x"EF",x"D7",x"E5",x"3A",x"99",x"40",x"B7",x"20",
+x"06",x"CD",x"58",x"03",x"B7",x"28",x"11",x"F5",x"AF",x"32",x"99",x"40",x"3C",x"CD",
+x"57",x"28",x"F1",x"2A",x"D4",x"40",x"77",x"C3",x"84",x"28",x"21",x"28",x"19",x"22",
+x"21",x"41",x"3E",x"03",x"32",x"AF",x"40",x"E1",x"C9",x"3E",x"1C",x"CD",x"3A",x"03",
+x"3E",x"1F",x"C3",x"3A",x"03",x"ED",x"5F",x"32",x"AB",x"40",x"C9",x"21",x"01",x"FC",
+x"CD",x"21",x"02",x"06",x"0B",x"10",x"FE",x"21",x"02",x"FC",x"CD",x"21",x"02",x"06",
+x"0B",x"10",x"FE",x"21",x"00",x"FC",x"CD",x"21",x"02",x"06",x"5C",x"10",x"FE",x"C9",
+x"E5",x"21",x"00",x"FB",x"18",x"1B",x"7E",x"D6",x"23",x"3E",x"00",x"20",x"0D",x"CD",
+x"01",x"2B",x"CF",x"2C",x"7B",x"A2",x"C6",x"02",x"D2",x"4A",x"1E",x"3D",x"D3",x"FE",
+x"00",x"E5",x"21",x"04",x"FF",x"CD",x"21",x"02",x"E1",x"C9",x"21",x"00",x"FF",x"3A",
+x"3D",x"40",x"A4",x"B5",x"D3",x"FF",x"32",x"3D",x"40",x"C9",x"3A",x"3F",x"3C",x"EE",
+x"0A",x"32",x"3F",x"3C",x"C9",x"C5",x"E5",x"06",x"08",x"CD",x"41",x"02",x"10",x"FB",
+x"E1",x"C1",x"C9",x"C5",x"F5",x"DB",x"FF",x"17",x"30",x"FB",x"06",x"41",x"10",x"FE",
+x"CD",x"1E",x"02",x"06",x"76",x"10",x"FE",x"DB",x"FF",x"47",x"F1",x"CB",x"10",x"17",
+x"F5",x"CD",x"1E",x"02",x"F1",x"C1",x"C9",x"CD",x"64",x"02",x"E5",x"C5",x"D5",x"F5",
+x"0E",x"08",x"57",x"CD",x"D9",x"01",x"7A",x"07",x"57",x"30",x"0B",x"CD",x"D9",x"01",
+x"0D",x"20",x"F2",x"F1",x"D1",x"C1",x"E1",x"C9",x"06",x"87",x"10",x"FE",x"18",x"F2",
+x"CD",x"FE",x"01",x"06",x"FF",x"AF",x"CD",x"64",x"02",x"10",x"FB",x"3E",x"A5",x"18",
+x"D1",x"CD",x"FE",x"01",x"E5",x"AF",x"CD",x"41",x"02",x"FE",x"A5",x"20",x"F9",x"3E",
+x"2A",x"32",x"3E",x"3C",x"32",x"3F",x"3C",x"E1",x"C9",x"CD",x"14",x"03",x"22",x"DF",
+x"40",x"CD",x"F8",x"01",x"CD",x"E2",x"41",x"31",x"88",x"42",x"CD",x"FE",x"20",x"3E",
+x"2A",x"CD",x"2A",x"03",x"CD",x"B3",x"1B",x"DA",x"CC",x"06",x"D7",x"CA",x"97",x"19",
+x"FE",x"2F",x"28",x"4F",x"CD",x"93",x"02",x"CD",x"35",x"02",x"FE",x"55",x"20",x"F9",
+x"06",x"06",x"7E",x"B7",x"28",x"09",x"CD",x"35",x"02",x"BE",x"20",x"ED",x"23",x"10",
+x"F3",x"CD",x"2C",x"02",x"CD",x"35",x"02",x"FE",x"78",x"28",x"B8",x"FE",x"3C",x"20",
+x"F5",x"CD",x"35",x"02",x"47",x"CD",x"14",x"03",x"85",x"4F",x"CD",x"35",x"02",x"77",
+x"23",x"81",x"4F",x"10",x"F7",x"CD",x"35",x"02",x"B9",x"28",x"DA",x"3E",x"43",x"32",
+x"3E",x"3C",x"18",x"D6",x"CD",x"35",x"02",x"6F",x"CD",x"35",x"02",x"67",x"C9",x"EB",
+x"2A",x"DF",x"40",x"EB",x"D7",x"C4",x"5A",x"1E",x"20",x"8A",x"EB",x"E9",x"C5",x"4F",
+x"CD",x"C1",x"41",x"3A",x"9C",x"40",x"B7",x"79",x"C1",x"FA",x"64",x"02",x"20",x"62",
+x"D5",x"CD",x"33",x"00",x"F5",x"CD",x"48",x"03",x"32",x"A6",x"40",x"F1",x"D1",x"C9",
+x"3A",x"3D",x"40",x"E6",x"08",x"3A",x"20",x"40",x"28",x"03",x"0F",x"E6",x"1F",x"E6",
+x"3F",x"C9",x"CD",x"C4",x"41",x"D5",x"CD",x"2B",x"00",x"D1",x"C9",x"AF",x"32",x"99",
+x"40",x"32",x"A6",x"40",x"CD",x"AF",x"41",x"C5",x"2A",x"A7",x"40",x"06",x"F0",x"CD",
+x"D9",x"05",x"F5",x"48",x"06",x"00",x"09",x"36",x"00",x"2A",x"A7",x"40",x"F1",x"C1",
+x"2B",x"D8",x"AF",x"C9",x"CD",x"58",x"03",x"B7",x"C0",x"18",x"F9",x"AF",x"32",x"9C",
+x"40",x"3A",x"9B",x"40",x"B7",x"C8",x"3E",x"0D",x"D5",x"CD",x"9C",x"03",x"D1",x"C9",
+x"F5",x"D5",x"C5",x"4F",x"1E",x"00",x"FE",x"0C",x"28",x"10",x"FE",x"0A",x"20",x"03",
+x"3E",x"0D",x"4F",x"FE",x"0D",x"28",x"05",x"3A",x"9B",x"40",x"3C",x"5F",x"7B",x"32",
+x"9B",x"40",x"79",x"CD",x"3B",x"00",x"C1",x"D1",x"F1",x"C9",x"E5",x"DD",x"E5",x"D5",
+x"DD",x"E1",x"D5",x"21",x"DD",x"03",x"E5",x"4F",x"1A",x"A0",x"B8",x"C2",x"33",x"40",
+x"FE",x"02",x"DD",x"6E",x"01",x"DD",x"66",x"02",x"E9",x"D1",x"DD",x"E1",x"E1",x"C1",
+x"C9",x"21",x"36",x"40",x"01",x"01",x"38",x"16",x"00",x"0A",x"5F",x"AE",x"73",x"A3",
+x"20",x"08",x"14",x"2C",x"CB",x"01",x"F2",x"EB",x"03",x"C9",x"5F",x"7A",x"07",x"07",
+x"07",x"57",x"0E",x"01",x"79",x"A3",x"20",x"05",x"14",x"CB",x"01",x"18",x"F7",x"3A",
+x"80",x"38",x"47",x"7A",x"C6",x"40",x"FE",x"60",x"30",x"13",x"CB",x"08",x"30",x"31",
+x"C6",x"20",x"57",x"3A",x"40",x"38",x"E6",x"10",x"28",x"28",x"7A",x"D6",x"60",x"18",
+x"22",x"D6",x"70",x"30",x"10",x"C6",x"40",x"FE",x"3C",x"38",x"02",x"EE",x"10",x"CB",
+x"08",x"30",x"12",x"EE",x"10",x"18",x"0E",x"07",x"CB",x"08",x"30",x"01",x"3C",x"21",
+x"50",x"00",x"4F",x"06",x"00",x"09",x"7E",x"57",x"01",x"AC",x"0D",x"CD",x"60",x"00",
+x"7A",x"FE",x"01",x"C0",x"EF",x"C9",x"DD",x"6E",x"03",x"DD",x"66",x"04",x"38",x"3A",
+x"DD",x"7E",x"05",x"B7",x"28",x"01",x"77",x"79",x"FE",x"20",x"DA",x"06",x"05",x"FE",
+x"80",x"30",x"35",x"FE",x"40",x"38",x"08",x"D6",x"40",x"FE",x"20",x"38",x"02",x"D6",
+x"20",x"CD",x"41",x"05",x"7C",x"E6",x"03",x"F6",x"3C",x"67",x"56",x"DD",x"7E",x"05",
+x"B7",x"28",x"05",x"DD",x"72",x"05",x"36",x"5F",x"DD",x"75",x"03",x"DD",x"74",x"04",
+x"79",x"C9",x"DD",x"7E",x"05",x"B7",x"C0",x"7E",x"C9",x"7D",x"E6",x"C0",x"6F",x"C9",
+x"FE",x"C0",x"38",x"D3",x"D6",x"C0",x"28",x"D2",x"47",x"3E",x"20",x"CD",x"41",x"05",
+x"10",x"F9",x"18",x"C8",x"7E",x"DD",x"77",x"05",x"C9",x"AF",x"18",x"F9",x"21",x"00",
+x"3C",x"3A",x"3D",x"40",x"E6",x"F7",x"32",x"3D",x"40",x"D3",x"FF",x"C9",x"2B",x"3A",
+x"3D",x"40",x"E6",x"08",x"28",x"01",x"2B",x"36",x"20",x"C9",x"3A",x"3D",x"40",x"E6",
+x"08",x"C4",x"E2",x"04",x"7D",x"E6",x"3F",x"2B",x"C0",x"11",x"40",x"00",x"19",x"C9",
+x"23",x"7D",x"E6",x"3F",x"C0",x"11",x"C0",x"FF",x"19",x"C9",x"3A",x"3D",x"40",x"F6",
+x"08",x"32",x"3D",x"40",x"D3",x"FF",x"23",x"7D",x"E6",x"FE",x"6F",x"C9",x"11",x"80",
+x"04",x"D5",x"FE",x"08",x"28",x"C0",x"FE",x"0A",x"D8",x"FE",x"0E",x"38",x"4F",x"28",
+x"A1",x"FE",x"0F",x"28",x"A2",x"FE",x"17",x"28",x"D7",x"FE",x"18",x"28",x"B7",x"FE",
+x"19",x"28",x"C5",x"FE",x"1A",x"28",x"BC",x"FE",x"1B",x"28",x"C2",x"FE",x"1C",x"28",
+x"8D",x"FE",x"1D",x"CA",x"A1",x"04",x"FE",x"1E",x"28",x"37",x"FE",x"1F",x"28",x"3C",
+x"C9",x"77",x"23",x"3A",x"3D",x"40",x"E6",x"08",x"28",x"01",x"23",x"7C",x"FE",x"40",
+x"C0",x"11",x"C0",x"FF",x"19",x"E5",x"11",x"00",x"3C",x"21",x"40",x"3C",x"C5",x"01",
+x"C0",x"03",x"ED",x"B0",x"C1",x"EB",x"18",x"19",x"7D",x"E6",x"C0",x"6F",x"E5",x"11",
+x"40",x"00",x"19",x"7C",x"FE",x"40",x"28",x"E2",x"D1",x"E5",x"54",x"7D",x"F6",x"3F",
+x"5F",x"13",x"18",x"04",x"E5",x"11",x"00",x"40",x"36",x"20",x"23",x"7C",x"BA",x"20",
+x"F9",x"7D",x"BB",x"20",x"F5",x"E1",x"C9",x"79",x"B7",x"28",x"40",x"FE",x"0B",x"28",
+x"0A",x"FE",x"0C",x"20",x"1B",x"AF",x"DD",x"B6",x"03",x"28",x"15",x"DD",x"7E",x"03",
+x"DD",x"96",x"04",x"47",x"CD",x"D1",x"05",x"20",x"FB",x"3E",x"0A",x"00",x"D3",x"FD",
+x"10",x"F4",x"18",x"18",x"F5",x"CD",x"D1",x"05",x"20",x"FB",x"F1",x"00",x"D3",x"FD",
+x"FE",x"0D",x"C0",x"DD",x"34",x"04",x"DD",x"7E",x"04",x"DD",x"BE",x"03",x"79",x"C0",
+x"DD",x"36",x"04",x"00",x"C9",x"00",x"DB",x"FD",x"E6",x"F0",x"FE",x"30",x"C9",x"E5",
+x"3E",x"0E",x"CD",x"33",x"00",x"48",x"CD",x"49",x"00",x"FE",x"20",x"30",x"25",x"FE",
+x"0D",x"CA",x"62",x"06",x"FE",x"1F",x"28",x"29",x"FE",x"01",x"28",x"6D",x"11",x"E0",
+x"05",x"D5",x"FE",x"08",x"28",x"34",x"FE",x"18",x"28",x"2B",x"FE",x"09",x"28",x"42",
+x"FE",x"19",x"28",x"39",x"FE",x"0A",x"C0",x"D1",x"77",x"78",x"B7",x"28",x"CF",x"7E",
+x"23",x"CD",x"33",x"00",x"05",x"18",x"C7",x"CD",x"C9",x"01",x"41",x"E1",x"E5",x"C3",
+x"E0",x"05",x"CD",x"30",x"06",x"2B",x"7E",x"23",x"FE",x"0A",x"C8",x"78",x"B9",x"20",
+x"F3",x"C9",x"78",x"B9",x"C8",x"2B",x"7E",x"FE",x"0A",x"23",x"C8",x"2B",x"3E",x"08",
+x"CD",x"33",x"00",x"04",x"C9",x"3E",x"17",x"C3",x"33",x"00",x"CD",x"48",x"03",x"E6",
+x"07",x"2F",x"3C",x"C6",x"08",x"5F",x"78",x"B7",x"C8",x"3E",x"20",x"77",x"23",x"D5",
+x"CD",x"33",x"00",x"D1",x"05",x"1D",x"C8",x"18",x"EF",x"37",x"F5",x"3E",x"0D",x"77",
+x"CD",x"33",x"00",x"3E",x"0F",x"CD",x"33",x"00",x"79",x"90",x"47",x"F1",x"E1",x"C9",
+x"D3",x"FF",x"21",x"D2",x"06",x"11",x"00",x"40",x"01",x"36",x"00",x"ED",x"B0",x"3D",
+x"3D",x"20",x"F1",x"06",x"27",x"12",x"13",x"10",x"FC",x"3A",x"40",x"38",x"E6",x"04",
+x"C2",x"75",x"00",x"31",x"7D",x"40",x"3A",x"EC",x"37",x"3C",x"FE",x"02",x"DA",x"75",
+x"00",x"3E",x"01",x"32",x"E1",x"37",x"21",x"EC",x"37",x"11",x"EF",x"37",x"36",x"03",
+x"01",x"00",x"00",x"CD",x"60",x"00",x"CB",x"46",x"20",x"FC",x"AF",x"32",x"EE",x"37",
+x"01",x"00",x"42",x"3E",x"8C",x"77",x"CB",x"4E",x"28",x"FC",x"1A",x"02",x"0C",x"20",
+x"F7",x"C3",x"00",x"42",x"01",x"18",x"1A",x"C3",x"AE",x"19",x"C3",x"96",x"1C",x"C3",
+x"78",x"1D",x"C3",x"90",x"1C",x"C3",x"D9",x"25",x"C9",x"00",x"00",x"C9",x"00",x"00",
+x"FB",x"C9",x"00",x"01",x"E3",x"03",x"00",x"00",x"00",x"4B",x"49",x"07",x"58",x"04",
+x"00",x"3C",x"00",x"44",x"4F",x"06",x"8D",x"05",x"43",x"00",x"00",x"50",x"52",x"C3",
+x"00",x"50",x"C7",x"00",x"00",x"3E",x"00",x"C9",x"21",x"80",x"13",x"CD",x"C2",x"09",
+x"18",x"06",x"CD",x"C2",x"09",x"CD",x"82",x"09",x"78",x"B7",x"C8",x"3A",x"24",x"41",
+x"B7",x"CA",x"B4",x"09",x"90",x"30",x"0C",x"2F",x"3C",x"EB",x"CD",x"A4",x"09",x"EB",
+x"CD",x"B4",x"09",x"C1",x"D1",x"FE",x"19",x"D0",x"F5",x"CD",x"DF",x"09",x"67",x"F1",
+x"CD",x"D7",x"07",x"B4",x"21",x"21",x"41",x"F2",x"54",x"07",x"CD",x"B7",x"07",x"D2",
+x"96",x"07",x"23",x"34",x"CA",x"B2",x"07",x"2E",x"01",x"CD",x"EB",x"07",x"18",x"42",
+x"AF",x"90",x"47",x"7E",x"9B",x"5F",x"23",x"7E",x"9A",x"57",x"23",x"7E",x"99",x"4F",
+x"DC",x"C3",x"07",x"68",x"63",x"AF",x"47",x"79",x"B7",x"20",x"18",x"4A",x"54",x"65",
+x"6F",x"78",x"D6",x"08",x"FE",x"E0",x"20",x"F0",x"AF",x"32",x"24",x"41",x"C9",x"05",
+x"29",x"7A",x"17",x"57",x"79",x"8F",x"4F",x"F2",x"7D",x"07",x"78",x"5C",x"45",x"B7",
+x"28",x"08",x"21",x"24",x"41",x"86",x"77",x"30",x"E3",x"C8",x"78",x"21",x"24",x"41",
+x"B7",x"FC",x"A8",x"07",x"46",x"23",x"7E",x"E6",x"80",x"A9",x"4F",x"C3",x"B4",x"09",
+x"1C",x"C0",x"14",x"C0",x"0C",x"C0",x"0E",x"80",x"34",x"C0",x"1E",x"0A",x"C3",x"A2",
+x"19",x"7E",x"83",x"5F",x"23",x"7E",x"8A",x"57",x"23",x"7E",x"89",x"4F",x"C9",x"21",
+x"25",x"41",x"7E",x"2F",x"77",x"AF",x"6F",x"90",x"47",x"7D",x"9B",x"5F",x"7D",x"9A",
+x"57",x"7D",x"99",x"4F",x"C9",x"06",x"00",x"D6",x"08",x"38",x"07",x"43",x"5A",x"51",
+x"0E",x"00",x"18",x"F5",x"C6",x"09",x"6F",x"AF",x"2D",x"C8",x"79",x"1F",x"4F",x"7A",
+x"1F",x"57",x"7B",x"1F",x"5F",x"78",x"1F",x"47",x"18",x"EF",x"00",x"00",x"00",x"81",
+x"03",x"AA",x"56",x"19",x"80",x"F1",x"22",x"76",x"80",x"45",x"AA",x"38",x"82",x"CD",
+x"55",x"09",x"B7",x"EA",x"4A",x"1E",x"21",x"24",x"41",x"7E",x"01",x"35",x"80",x"11",
+x"F3",x"04",x"90",x"F5",x"70",x"D5",x"C5",x"CD",x"16",x"07",x"C1",x"D1",x"04",x"CD",
+x"A2",x"08",x"21",x"F8",x"07",x"CD",x"10",x"07",x"21",x"FC",x"07",x"CD",x"9A",x"14",
+x"01",x"80",x"80",x"11",x"00",x"00",x"CD",x"16",x"07",x"F1",x"CD",x"89",x"0F",x"01",
+x"31",x"80",x"11",x"18",x"72",x"CD",x"55",x"09",x"C8",x"2E",x"00",x"CD",x"14",x"09",
+x"79",x"32",x"4F",x"41",x"EB",x"22",x"50",x"41",x"01",x"00",x"00",x"50",x"58",x"21",
+x"65",x"07",x"E5",x"21",x"69",x"08",x"E5",x"E5",x"21",x"21",x"41",x"7E",x"23",x"B7",
+x"28",x"24",x"E5",x"2E",x"08",x"1F",x"67",x"79",x"30",x"0B",x"E5",x"2A",x"50",x"41",
+x"19",x"EB",x"E1",x"3A",x"4F",x"41",x"89",x"1F",x"4F",x"7A",x"1F",x"57",x"7B",x"1F",
+x"5F",x"78",x"1F",x"47",x"2D",x"7C",x"20",x"E1",x"E1",x"C9",x"43",x"5A",x"51",x"4F",
+x"C9",x"CD",x"A4",x"09",x"21",x"D8",x"0D",x"CD",x"B1",x"09",x"C1",x"D1",x"CD",x"55",
+x"09",x"CA",x"9A",x"19",x"2E",x"FF",x"CD",x"14",x"09",x"34",x"34",x"2B",x"7E",x"32",
+x"89",x"40",x"2B",x"7E",x"32",x"85",x"40",x"2B",x"7E",x"32",x"81",x"40",x"41",x"EB",
+x"AF",x"4F",x"57",x"5F",x"32",x"8C",x"40",x"E5",x"C5",x"7D",x"CD",x"80",x"40",x"DE",
+x"00",x"3F",x"30",x"07",x"32",x"8C",x"40",x"F1",x"F1",x"37",x"D2",x"C1",x"E1",x"79",
+x"3C",x"3D",x"1F",x"FA",x"97",x"07",x"17",x"7B",x"17",x"5F",x"7A",x"17",x"57",x"79",
+x"17",x"4F",x"29",x"78",x"17",x"47",x"3A",x"8C",x"40",x"17",x"32",x"8C",x"40",x"79",
+x"B2",x"B3",x"20",x"CB",x"E5",x"21",x"24",x"41",x"35",x"E1",x"20",x"C3",x"C3",x"B2",
+x"07",x"3E",x"FF",x"2E",x"AF",x"21",x"2D",x"41",x"4E",x"23",x"AE",x"47",x"2E",x"00",
+x"78",x"B7",x"28",x"1F",x"7D",x"21",x"24",x"41",x"AE",x"80",x"47",x"1F",x"A8",x"78",
+x"F2",x"36",x"09",x"C6",x"80",x"77",x"CA",x"90",x"08",x"CD",x"DF",x"09",x"77",x"2B",
+x"C9",x"CD",x"55",x"09",x"2F",x"E1",x"B7",x"E1",x"F2",x"78",x"07",x"C3",x"B2",x"07",
+x"CD",x"BF",x"09",x"78",x"B7",x"C8",x"C6",x"02",x"DA",x"B2",x"07",x"47",x"CD",x"16",
+x"07",x"21",x"24",x"41",x"34",x"C0",x"C3",x"B2",x"07",x"3A",x"24",x"41",x"B7",x"C8",
+x"3A",x"23",x"41",x"FE",x"2F",x"17",x"9F",x"C0",x"3C",x"C9",x"06",x"88",x"11",x"00",
+x"00",x"21",x"24",x"41",x"4F",x"70",x"06",x"00",x"23",x"36",x"80",x"17",x"C3",x"62",
+x"07",x"CD",x"94",x"09",x"F0",x"E7",x"FA",x"5B",x"0C",x"CA",x"F6",x"0A",x"21",x"23",
+x"41",x"7E",x"EE",x"80",x"77",x"C9",x"CD",x"94",x"09",x"6F",x"17",x"9F",x"67",x"C3",
+x"9A",x"0A",x"E7",x"CA",x"F6",x"0A",x"F2",x"55",x"09",x"2A",x"21",x"41",x"7C",x"B5",
+x"C8",x"7C",x"18",x"BB",x"EB",x"2A",x"21",x"41",x"E3",x"E5",x"2A",x"23",x"41",x"E3",
+x"E5",x"EB",x"C9",x"CD",x"C2",x"09",x"EB",x"22",x"21",x"41",x"60",x"69",x"22",x"23",
+x"41",x"EB",x"C9",x"21",x"21",x"41",x"5E",x"23",x"56",x"23",x"4E",x"23",x"46",x"23",
+x"C9",x"11",x"21",x"41",x"06",x"04",x"18",x"05",x"EB",x"3A",x"AF",x"40",x"47",x"1A",
+x"77",x"13",x"23",x"05",x"20",x"F9",x"C9",x"21",x"23",x"41",x"7E",x"07",x"37",x"1F",
+x"77",x"3F",x"1F",x"23",x"23",x"77",x"79",x"07",x"37",x"1F",x"4F",x"1F",x"AE",x"C9",
+x"21",x"27",x"41",x"11",x"D2",x"09",x"18",x"06",x"21",x"27",x"41",x"11",x"D3",x"09",
+x"D5",x"11",x"21",x"41",x"E7",x"D8",x"11",x"1D",x"41",x"C9",x"78",x"B7",x"CA",x"55",
+x"09",x"21",x"5E",x"09",x"E5",x"CD",x"55",x"09",x"79",x"C8",x"21",x"23",x"41",x"AE",
+x"79",x"F8",x"CD",x"26",x"0A",x"1F",x"A9",x"C9",x"23",x"78",x"BE",x"C0",x"2B",x"79",
+x"BE",x"C0",x"2B",x"7A",x"BE",x"C0",x"2B",x"7B",x"96",x"C0",x"E1",x"E1",x"C9",x"7A",
+x"AC",x"7C",x"FA",x"5F",x"09",x"BA",x"C2",x"60",x"09",x"7D",x"93",x"C2",x"60",x"09",
+x"C9",x"21",x"27",x"41",x"CD",x"D3",x"09",x"11",x"2E",x"41",x"1A",x"B7",x"CA",x"55",
+x"09",x"21",x"5E",x"09",x"E5",x"CD",x"55",x"09",x"1B",x"1A",x"4F",x"C8",x"21",x"23",
+x"41",x"AE",x"79",x"F8",x"13",x"23",x"06",x"08",x"1A",x"96",x"C2",x"23",x"0A",x"1B",
+x"2B",x"05",x"20",x"F6",x"C1",x"C9",x"CD",x"4F",x"0A",x"C2",x"5E",x"09",x"C9",x"E7",
+x"2A",x"21",x"41",x"F8",x"CA",x"F6",x"0A",x"D4",x"B9",x"0A",x"21",x"B2",x"07",x"E5",
+x"3A",x"24",x"41",x"FE",x"90",x"30",x"0E",x"CD",x"FB",x"0A",x"EB",x"D1",x"22",x"21",
+x"41",x"3E",x"02",x"32",x"AF",x"40",x"C9",x"01",x"80",x"90",x"11",x"00",x"00",x"CD",
+x"0C",x"0A",x"C0",x"61",x"6A",x"18",x"E8",x"E7",x"E0",x"FA",x"CC",x"0A",x"CA",x"F6",
+x"0A",x"CD",x"BF",x"09",x"CD",x"EF",x"0A",x"78",x"B7",x"C8",x"CD",x"DF",x"09",x"21",
+x"20",x"41",x"46",x"C3",x"96",x"07",x"2A",x"21",x"41",x"CD",x"EF",x"0A",x"7C",x"55",
+x"1E",x"00",x"06",x"90",x"C3",x"69",x"09",x"E7",x"D0",x"CA",x"F6",x"0A",x"FC",x"CC",
+x"0A",x"21",x"00",x"00",x"22",x"1D",x"41",x"22",x"1F",x"41",x"3E",x"08",x"01",x"3E",
+x"04",x"C3",x"9F",x"0A",x"E7",x"C8",x"1E",x"18",x"C3",x"A2",x"19",x"47",x"4F",x"57",
+x"5F",x"B7",x"C8",x"E5",x"CD",x"BF",x"09",x"CD",x"DF",x"09",x"AE",x"67",x"FC",x"1F",
+x"0B",x"3E",x"98",x"90",x"CD",x"D7",x"07",x"7C",x"17",x"DC",x"A8",x"07",x"06",x"00",
+x"DC",x"C3",x"07",x"E1",x"C9",x"1B",x"7A",x"A3",x"3C",x"C0",x"0B",x"C9",x"E7",x"F8",
+x"CD",x"55",x"09",x"F2",x"37",x"0B",x"CD",x"82",x"09",x"CD",x"37",x"0B",x"C3",x"7B",
+x"09",x"E7",x"F8",x"30",x"1E",x"28",x"B9",x"CD",x"8E",x"0A",x"21",x"24",x"41",x"7E",
+x"FE",x"98",x"3A",x"21",x"41",x"D0",x"7E",x"CD",x"FB",x"0A",x"36",x"98",x"7B",x"F5",
+x"79",x"17",x"CD",x"62",x"07",x"F1",x"C9",x"21",x"24",x"41",x"7E",x"FE",x"90",x"DA",
+x"7F",x"0A",x"20",x"14",x"4F",x"2B",x"7E",x"EE",x"80",x"06",x"06",x"2B",x"B6",x"05",
+x"20",x"FB",x"B7",x"21",x"00",x"80",x"CA",x"9A",x"0A",x"79",x"FE",x"B8",x"D0",x"F5",
+x"CD",x"BF",x"09",x"CD",x"DF",x"09",x"AE",x"2B",x"36",x"B8",x"F5",x"FC",x"A0",x"0B",
+x"21",x"23",x"41",x"3E",x"B8",x"90",x"CD",x"69",x"0D",x"F1",x"FC",x"20",x"0D",x"AF",
+x"32",x"1C",x"41",x"F1",x"D0",x"C3",x"D8",x"0C",x"21",x"1D",x"41",x"7E",x"35",x"B7",
+x"23",x"28",x"FA",x"C9",x"E5",x"21",x"00",x"00",x"78",x"B1",x"28",x"12",x"3E",x"10",
+x"29",x"DA",x"3D",x"27",x"EB",x"29",x"EB",x"30",x"04",x"09",x"DA",x"3D",x"27",x"3D",
+x"20",x"F0",x"EB",x"E1",x"C9",x"7C",x"17",x"9F",x"47",x"CD",x"51",x"0C",x"79",x"98",
+x"18",x"03",x"7C",x"17",x"9F",x"47",x"E5",x"7A",x"17",x"9F",x"19",x"88",x"0F",x"AC",
+x"F2",x"99",x"0A",x"C5",x"EB",x"CD",x"CF",x"0A",x"F1",x"E1",x"CD",x"A4",x"09",x"EB",
+x"CD",x"6B",x"0C",x"C3",x"8F",x"0F",x"7C",x"B5",x"CA",x"9A",x"0A",x"E5",x"D5",x"CD",
+x"45",x"0C",x"C5",x"44",x"4D",x"21",x"00",x"00",x"3E",x"10",x"29",x"38",x"1F",x"EB",
+x"29",x"EB",x"30",x"04",x"09",x"DA",x"26",x"0C",x"3D",x"20",x"F1",x"C1",x"D1",x"7C",
+x"B7",x"FA",x"1F",x"0C",x"D1",x"78",x"C3",x"4D",x"0C",x"EE",x"80",x"B5",x"28",x"13",
+x"EB",x"01",x"C1",x"E1",x"CD",x"CF",x"0A",x"E1",x"CD",x"A4",x"09",x"CD",x"CF",x"0A",
+x"C1",x"D1",x"C3",x"47",x"08",x"78",x"B7",x"C1",x"FA",x"9A",x"0A",x"D5",x"CD",x"CF",
+x"0A",x"D1",x"C3",x"82",x"09",x"7C",x"AA",x"47",x"CD",x"4C",x"0C",x"EB",x"7C",x"B7",
+x"F2",x"9A",x"0A",x"AF",x"4F",x"95",x"6F",x"79",x"9C",x"67",x"C3",x"9A",x"0A",x"2A",
+x"21",x"41",x"CD",x"51",x"0C",x"7C",x"EE",x"80",x"B5",x"C0",x"EB",x"CD",x"EF",x"0A",
+x"AF",x"06",x"98",x"C3",x"69",x"09",x"21",x"2D",x"41",x"7E",x"EE",x"80",x"77",x"21",
+x"2E",x"41",x"7E",x"B7",x"C8",x"47",x"2B",x"4E",x"11",x"24",x"41",x"1A",x"B7",x"CA",
+x"F4",x"09",x"90",x"30",x"16",x"2F",x"3C",x"F5",x"0E",x"08",x"23",x"E5",x"1A",x"46",
+x"77",x"78",x"12",x"1B",x"2B",x"0D",x"20",x"F6",x"E1",x"46",x"2B",x"4E",x"F1",x"FE",
+x"39",x"D0",x"F5",x"CD",x"DF",x"09",x"23",x"36",x"00",x"47",x"F1",x"21",x"2D",x"41",
+x"CD",x"69",x"0D",x"3A",x"26",x"41",x"32",x"1C",x"41",x"78",x"B7",x"F2",x"CF",x"0C",
+x"CD",x"33",x"0D",x"D2",x"0E",x"0D",x"EB",x"34",x"CA",x"B2",x"07",x"CD",x"90",x"0D",
+x"C3",x"0E",x"0D",x"CD",x"45",x"0D",x"21",x"25",x"41",x"DC",x"57",x"0D",x"AF",x"47",
+x"3A",x"23",x"41",x"B7",x"20",x"1E",x"21",x"1C",x"41",x"0E",x"08",x"56",x"77",x"7A",
+x"23",x"0D",x"20",x"F9",x"78",x"D6",x"08",x"FE",x"C0",x"20",x"E6",x"C3",x"78",x"07",
+x"05",x"21",x"1C",x"41",x"CD",x"97",x"0D",x"B7",x"F2",x"F6",x"0C",x"78",x"B7",x"28",
+x"09",x"21",x"24",x"41",x"86",x"77",x"D2",x"78",x"07",x"C8",x"3A",x"1C",x"41",x"B7",
+x"FC",x"20",x"0D",x"21",x"25",x"41",x"7E",x"E6",x"80",x"2B",x"2B",x"AE",x"77",x"C9",
+x"21",x"1D",x"41",x"06",x"07",x"34",x"C0",x"23",x"05",x"20",x"FA",x"34",x"CA",x"B2",
+x"07",x"2B",x"36",x"80",x"C9",x"21",x"27",x"41",x"11",x"1D",x"41",x"0E",x"07",x"AF",
+x"1A",x"8E",x"12",x"13",x"23",x"0D",x"20",x"F8",x"C9",x"21",x"27",x"41",x"11",x"1D",
+x"41",x"0E",x"07",x"AF",x"1A",x"9E",x"12",x"13",x"23",x"0D",x"20",x"F8",x"C9",x"7E",
+x"2F",x"77",x"21",x"1C",x"41",x"06",x"08",x"AF",x"4F",x"79",x"9E",x"77",x"23",x"05",
+x"20",x"F9",x"C9",x"71",x"E5",x"D6",x"08",x"38",x"0E",x"E1",x"E5",x"11",x"00",x"08",
+x"4E",x"73",x"59",x"2B",x"15",x"20",x"F9",x"18",x"EE",x"C6",x"09",x"57",x"AF",x"E1",
+x"15",x"C8",x"E5",x"1E",x"08",x"7E",x"1F",x"77",x"2B",x"1D",x"20",x"F9",x"18",x"F0",
+x"21",x"23",x"41",x"16",x"01",x"18",x"ED",x"0E",x"08",x"7E",x"17",x"77",x"23",x"0D",
+x"20",x"F9",x"C9",x"CD",x"55",x"09",x"C8",x"CD",x"0A",x"09",x"CD",x"39",x"0E",x"71",
+x"13",x"06",x"07",x"1A",x"13",x"B7",x"D5",x"28",x"17",x"0E",x"08",x"C5",x"1F",x"47",
+x"DC",x"33",x"0D",x"CD",x"90",x"0D",x"78",x"C1",x"0D",x"20",x"F2",x"D1",x"05",x"20",
+x"E6",x"C3",x"D8",x"0C",x"21",x"23",x"41",x"CD",x"70",x"0D",x"18",x"F1",x"00",x"00",
+x"00",x"00",x"00",x"00",x"20",x"84",x"11",x"D4",x"0D",x"21",x"27",x"41",x"CD",x"D3",
+x"09",x"3A",x"2E",x"41",x"B7",x"CA",x"9A",x"19",x"CD",x"07",x"09",x"34",x"34",x"CD",
+x"39",x"0E",x"21",x"51",x"41",x"71",x"41",x"11",x"4A",x"41",x"21",x"27",x"41",x"CD",
+x"4B",x"0D",x"1A",x"99",x"3F",x"38",x"0B",x"11",x"4A",x"41",x"21",x"27",x"41",x"CD",
+x"39",x"0D",x"AF",x"DA",x"12",x"04",x"3A",x"23",x"41",x"3C",x"3D",x"1F",x"FA",x"11",
+x"0D",x"17",x"21",x"1D",x"41",x"0E",x"07",x"CD",x"99",x"0D",x"21",x"4A",x"41",x"CD",
+x"97",x"0D",x"78",x"B7",x"20",x"C9",x"21",x"24",x"41",x"35",x"20",x"C3",x"C3",x"B2",
+x"07",x"79",x"32",x"2D",x"41",x"2B",x"11",x"50",x"41",x"01",x"00",x"07",x"7E",x"12",
+x"71",x"1B",x"2B",x"05",x"20",x"F8",x"C9",x"CD",x"FC",x"09",x"EB",x"2B",x"7E",x"B7",
+x"C8",x"C6",x"02",x"DA",x"B2",x"07",x"77",x"E5",x"CD",x"77",x"0C",x"E1",x"34",x"C0",
+x"C3",x"B2",x"07",x"CD",x"78",x"07",x"CD",x"EC",x"0A",x"F6",x"AF",x"EB",x"01",x"FF",
+x"00",x"60",x"68",x"CC",x"9A",x"0A",x"EB",x"7E",x"FE",x"2D",x"F5",x"CA",x"83",x"0E",
+x"FE",x"2B",x"28",x"01",x"2B",x"D7",x"DA",x"29",x"0F",x"FE",x"2E",x"CA",x"E4",x"0E",
+x"FE",x"45",x"28",x"14",x"FE",x"25",x"CA",x"EE",x"0E",x"FE",x"23",x"CA",x"F5",x"0E",
+x"FE",x"21",x"CA",x"F6",x"0E",x"FE",x"44",x"20",x"24",x"B7",x"CD",x"FB",x"0E",x"E5",
+x"21",x"BD",x"0E",x"E3",x"D7",x"15",x"FE",x"CE",x"C8",x"FE",x"2D",x"C8",x"14",x"FE",
+x"CD",x"C8",x"FE",x"2B",x"C8",x"2B",x"F1",x"D7",x"DA",x"94",x"0F",x"14",x"20",x"03",
+x"AF",x"93",x"5F",x"E5",x"7B",x"90",x"F4",x"0A",x"0F",x"FC",x"18",x"0F",x"20",x"F8",
+x"E1",x"F1",x"E5",x"CC",x"7B",x"09",x"E1",x"E7",x"E8",x"E5",x"21",x"90",x"08",x"E5",
+x"CD",x"A3",x"0A",x"C9",x"E7",x"0C",x"20",x"DF",x"DC",x"FB",x"0E",x"C3",x"83",x"0E",
+x"E7",x"F2",x"97",x"19",x"23",x"18",x"D2",x"B7",x"CD",x"FB",x"0E",x"18",x"F7",x"E5",
+x"D5",x"C5",x"F5",x"CC",x"B1",x"0A",x"F1",x"C4",x"DB",x"0A",x"C1",x"D1",x"E1",x"C9",
+x"C8",x"F5",x"E7",x"F5",x"E4",x"3E",x"09",x"F1",x"EC",x"4D",x"0E",x"F1",x"3D",x"C9",
+x"D5",x"E5",x"F5",x"E7",x"F5",x"E4",x"97",x"08",x"F1",x"EC",x"DC",x"0D",x"F1",x"E1",
+x"D1",x"3C",x"C9",x"D5",x"78",x"89",x"47",x"C5",x"E5",x"7E",x"D6",x"30",x"F5",x"E7",
+x"F2",x"5D",x"0F",x"2A",x"21",x"41",x"11",x"CD",x"0C",x"DF",x"30",x"19",x"54",x"5D",
+x"29",x"29",x"19",x"29",x"F1",x"4F",x"09",x"7C",x"B7",x"FA",x"57",x"0F",x"22",x"21",
+x"41",x"E1",x"C1",x"D1",x"C3",x"83",x"0E",x"79",x"F5",x"CD",x"CC",x"0A",x"37",x"30",
+x"18",x"01",x"74",x"94",x"11",x"00",x"24",x"CD",x"0C",x"0A",x"F2",x"74",x"0F",x"CD",
+x"3E",x"09",x"F1",x"CD",x"89",x"0F",x"18",x"DD",x"CD",x"E3",x"0A",x"CD",x"4D",x"0E",
+x"CD",x"FC",x"09",x"F1",x"CD",x"64",x"09",x"CD",x"E3",x"0A",x"CD",x"77",x"0C",x"18",
+x"C8",x"CD",x"A4",x"09",x"CD",x"64",x"09",x"C1",x"D1",x"C3",x"16",x"07",x"7B",x"FE",
+x"0A",x"30",x"09",x"07",x"07",x"83",x"07",x"86",x"D6",x"30",x"5F",x"FA",x"1E",x"32",
+x"C3",x"BD",x"0E",x"E5",x"21",x"24",x"19",x"CD",x"A7",x"28",x"E1",x"CD",x"9A",x"0A",
+x"AF",x"CD",x"34",x"10",x"B6",x"CD",x"D9",x"0F",x"C3",x"A6",x"28",x"AF",x"CD",x"34",
+x"10",x"E6",x"08",x"28",x"02",x"36",x"2B",x"EB",x"CD",x"94",x"09",x"EB",x"F2",x"D9",
+x"0F",x"36",x"2D",x"C5",x"E5",x"CD",x"7B",x"09",x"E1",x"C1",x"B4",x"23",x"36",x"30",
+x"3A",x"D8",x"40",x"57",x"17",x"3A",x"AF",x"40",x"DA",x"9A",x"10",x"CA",x"92",x"10",
+x"FE",x"04",x"D2",x"3D",x"10",x"01",x"00",x"00",x"CD",x"2F",x"13",x"21",x"30",x"41",
+x"46",x"0E",x"20",x"3A",x"D8",x"40",x"5F",x"E6",x"20",x"28",x"07",x"78",x"B9",x"0E",
+x"2A",x"20",x"01",x"41",x"71",x"D7",x"28",x"14",x"FE",x"45",x"28",x"10",x"FE",x"44",
+x"28",x"0C",x"FE",x"30",x"28",x"F0",x"FE",x"2C",x"28",x"EC",x"FE",x"2E",x"20",x"03",
+x"2B",x"36",x"30",x"7B",x"E6",x"10",x"28",x"03",x"2B",x"36",x"24",x"7B",x"E6",x"04",
+x"C0",x"2B",x"70",x"C9",x"32",x"D8",x"40",x"21",x"30",x"41",x"36",x"20",x"C9",x"FE",
+x"05",x"E5",x"DE",x"00",x"17",x"57",x"14",x"CD",x"01",x"12",x"01",x"00",x"03",x"82",
+x"FA",x"57",x"10",x"14",x"BA",x"30",x"04",x"3C",x"47",x"3E",x"02",x"D6",x"02",x"E1",
+x"F5",x"CD",x"91",x"12",x"36",x"30",x"CC",x"C9",x"09",x"CD",x"A4",x"12",x"2B",x"7E",
+x"FE",x"30",x"28",x"FA",x"FE",x"2E",x"C4",x"C9",x"09",x"F1",x"28",x"1F",x"F5",x"E7",
+x"3E",x"22",x"8F",x"77",x"23",x"F1",x"36",x"2B",x"F2",x"85",x"10",x"36",x"2D",x"2F",
+x"3C",x"06",x"2F",x"04",x"D6",x"0A",x"30",x"FB",x"C6",x"3A",x"23",x"70",x"23",x"77",
+x"23",x"36",x"00",x"EB",x"21",x"30",x"41",x"C9",x"23",x"C5",x"FE",x"04",x"7A",x"D2",
+x"09",x"11",x"1F",x"DA",x"A3",x"11",x"01",x"03",x"06",x"CD",x"89",x"12",x"D1",x"7A",
+x"D6",x"05",x"F4",x"69",x"12",x"CD",x"2F",x"13",x"7B",x"B7",x"CC",x"2F",x"09",x"3D",
+x"F4",x"69",x"12",x"E5",x"CD",x"F5",x"0F",x"E1",x"28",x"02",x"70",x"23",x"36",x"00",
+x"21",x"2F",x"41",x"23",x"3A",x"F3",x"40",x"95",x"92",x"C8",x"7E",x"FE",x"20",x"28",
+x"F4",x"FE",x"2A",x"28",x"F0",x"2B",x"E5",x"F5",x"01",x"DF",x"10",x"C5",x"D7",x"FE",
+x"2D",x"C8",x"FE",x"2B",x"C8",x"FE",x"24",x"C8",x"C1",x"FE",x"30",x"20",x"0F",x"23",
+x"D7",x"30",x"0B",x"2B",x"01",x"2B",x"77",x"F1",x"28",x"FB",x"C1",x"C3",x"CE",x"10",
+x"F1",x"28",x"FD",x"E1",x"36",x"25",x"C9",x"E5",x"1F",x"DA",x"AA",x"11",x"28",x"14",
+x"11",x"84",x"13",x"CD",x"49",x"0A",x"16",x"10",x"FA",x"32",x"11",x"E1",x"C1",x"CD",
+x"BD",x"0F",x"2B",x"36",x"25",x"C9",x"01",x"0E",x"B6",x"11",x"CA",x"1B",x"CD",x"0C",
+x"0A",x"F2",x"1B",x"11",x"16",x"06",x"CD",x"55",x"09",x"C4",x"01",x"12",x"E1",x"C1",
+x"FA",x"57",x"11",x"C5",x"5F",x"78",x"92",x"93",x"F4",x"69",x"12",x"CD",x"7D",x"12",
+x"CD",x"A4",x"12",x"B3",x"C4",x"77",x"12",x"B3",x"C4",x"91",x"12",x"D1",x"C3",x"B6",
+x"10",x"5F",x"79",x"B7",x"C4",x"16",x"0F",x"83",x"FA",x"62",x"11",x"AF",x"C5",x"F5",
+x"FC",x"18",x"0F",x"FA",x"64",x"11",x"C1",x"7B",x"90",x"C1",x"5F",x"82",x"78",x"FA",
+x"7F",x"11",x"92",x"93",x"F4",x"69",x"12",x"C5",x"CD",x"7D",x"12",x"18",x"11",x"CD",
+x"69",x"12",x"79",x"CD",x"94",x"12",x"4F",x"AF",x"92",x"93",x"CD",x"69",x"12",x"C5",
+x"47",x"4F",x"CD",x"A4",x"12",x"C1",x"B1",x"20",x"03",x"2A",x"F3",x"40",x"83",x"3D",
+x"F4",x"69",x"12",x"50",x"C3",x"BF",x"10",x"E5",x"D5",x"CD",x"CC",x"0A",x"D1",x"AF",
+x"CA",x"B0",x"11",x"1E",x"10",x"01",x"1E",x"06",x"CD",x"55",x"09",x"37",x"C4",x"01",
+x"12",x"E1",x"C1",x"F5",x"79",x"B7",x"F5",x"C4",x"16",x"0F",x"80",x"4F",x"7A",x"E6",
+x"04",x"FE",x"01",x"9F",x"57",x"81",x"4F",x"93",x"F5",x"C5",x"FC",x"18",x"0F",x"FA",
+x"D0",x"11",x"C1",x"F1",x"C5",x"F5",x"FA",x"DE",x"11",x"AF",x"2F",x"3C",x"80",x"3C",
+x"82",x"47",x"0E",x"00",x"CD",x"A4",x"12",x"F1",x"F4",x"71",x"12",x"C1",x"F1",x"CC",
+x"2F",x"09",x"F1",x"38",x"03",x"83",x"90",x"92",x"C5",x"CD",x"74",x"10",x"EB",x"D1",
+x"C3",x"BF",x"10",x"D5",x"AF",x"F5",x"E7",x"E2",x"22",x"12",x"3A",x"24",x"41",x"FE",
+x"91",x"D2",x"22",x"12",x"11",x"64",x"13",x"21",x"27",x"41",x"CD",x"D3",x"09",x"CD",
+x"A1",x"0D",x"F1",x"D6",x"0A",x"F5",x"18",x"E6",x"CD",x"4F",x"12",x"E7",x"30",x"0B",
+x"01",x"43",x"91",x"11",x"F9",x"4F",x"CD",x"0C",x"0A",x"18",x"06",x"11",x"6C",x"13",
+x"CD",x"49",x"0A",x"F2",x"4B",x"12",x"F1",x"CD",x"0B",x"0F",x"F5",x"18",x"E2",x"F1",
+x"CD",x"18",x"0F",x"F5",x"CD",x"4F",x"12",x"F1",x"B7",x"D1",x"C9",x"E7",x"EA",x"5E",
+x"12",x"01",x"74",x"94",x"11",x"F8",x"23",x"CD",x"0C",x"0A",x"18",x"06",x"11",x"74",
+x"13",x"CD",x"49",x"0A",x"E1",x"F2",x"43",x"12",x"E9",x"B7",x"C8",x"3D",x"36",x"30",
+x"23",x"18",x"F9",x"20",x"04",x"C8",x"CD",x"91",x"12",x"36",x"30",x"23",x"3D",x"18",
+x"F6",x"7B",x"82",x"3C",x"47",x"3C",x"D6",x"03",x"30",x"FC",x"C6",x"05",x"4F",x"3A",
+x"D8",x"40",x"E6",x"40",x"C0",x"4F",x"C9",x"05",x"20",x"08",x"36",x"2E",x"22",x"F3",
+x"40",x"23",x"48",x"C9",x"0D",x"C0",x"36",x"2C",x"23",x"0E",x"03",x"C9",x"D5",x"E7",
+x"E2",x"EA",x"12",x"C5",x"E5",x"CD",x"FC",x"09",x"21",x"7C",x"13",x"CD",x"F7",x"09",
+x"CD",x"77",x"0C",x"AF",x"CD",x"7B",x"0B",x"E1",x"C1",x"11",x"8C",x"13",x"3E",x"0A",
+x"CD",x"91",x"12",x"C5",x"F5",x"E5",x"D5",x"06",x"2F",x"04",x"E1",x"E5",x"CD",x"48",
+x"0D",x"30",x"F8",x"E1",x"CD",x"36",x"0D",x"EB",x"E1",x"70",x"23",x"F1",x"C1",x"3D",
+x"20",x"E2",x"C5",x"E5",x"21",x"1D",x"41",x"CD",x"B1",x"09",x"18",x"0C",x"C5",x"E5",
+x"CD",x"08",x"07",x"3C",x"CD",x"FB",x"0A",x"CD",x"B4",x"09",x"E1",x"C1",x"AF",x"11",
+x"D2",x"13",x"3F",x"CD",x"91",x"12",x"C5",x"F5",x"E5",x"D5",x"CD",x"BF",x"09",x"E1",
+x"06",x"2F",x"04",x"7B",x"96",x"5F",x"23",x"7A",x"9E",x"57",x"23",x"79",x"9E",x"4F",
+x"2B",x"2B",x"30",x"F0",x"CD",x"B7",x"07",x"23",x"CD",x"B4",x"09",x"EB",x"E1",x"70",
+x"23",x"F1",x"C1",x"38",x"D3",x"13",x"13",x"3E",x"04",x"18",x"06",x"D5",x"11",x"D8",
+x"13",x"3E",x"05",x"CD",x"91",x"12",x"C5",x"F5",x"E5",x"EB",x"4E",x"23",x"46",x"C5",
+x"23",x"E3",x"EB",x"2A",x"21",x"41",x"06",x"2F",x"04",x"7D",x"93",x"6F",x"7C",x"9A",
+x"67",x"30",x"F7",x"19",x"22",x"21",x"41",x"D1",x"E1",x"70",x"23",x"F1",x"C1",x"3D",
+x"20",x"D7",x"CD",x"91",x"12",x"77",x"D1",x"C9",x"00",x"00",x"00",x"00",x"F9",x"02",
+x"15",x"A2",x"FD",x"FF",x"9F",x"31",x"A9",x"5F",x"63",x"B2",x"FE",x"FF",x"03",x"BF",
+x"C9",x"1B",x"0E",x"B6",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"80",x"00",x"00",
+x"04",x"BF",x"C9",x"1B",x"0E",x"B6",x"00",x"80",x"C6",x"A4",x"7E",x"8D",x"03",x"00",
+x"40",x"7A",x"10",x"F3",x"5A",x"00",x"00",x"A0",x"72",x"4E",x"18",x"09",x"00",x"00",
+x"10",x"A5",x"D4",x"E8",x"00",x"00",x"00",x"E8",x"76",x"48",x"17",x"00",x"00",x"00",
+x"E4",x"0B",x"54",x"02",x"00",x"00",x"00",x"CA",x"9A",x"3B",x"00",x"00",x"00",x"00",
+x"E1",x"F5",x"05",x"00",x"00",x"00",x"80",x"96",x"98",x"00",x"00",x"00",x"00",x"40",
+x"42",x"0F",x"00",x"00",x"00",x"00",x"A0",x"86",x"01",x"10",x"27",x"00",x"10",x"27",
+x"E8",x"03",x"64",x"00",x"0A",x"00",x"01",x"00",x"21",x"82",x"09",x"E3",x"E9",x"CD",
+x"A4",x"09",x"21",x"80",x"13",x"CD",x"B1",x"09",x"18",x"03",x"CD",x"B1",x"0A",x"C1",
+x"D1",x"CD",x"55",x"09",x"78",x"28",x"3C",x"F2",x"04",x"14",x"B7",x"CA",x"9A",x"19",
+x"B7",x"CA",x"79",x"07",x"D5",x"C5",x"79",x"F6",x"7F",x"CD",x"BF",x"09",x"F2",x"21",
+x"14",x"D5",x"C5",x"CD",x"40",x"0B",x"C1",x"D1",x"F5",x"CD",x"0C",x"0A",x"E1",x"7C",
+x"1F",x"E1",x"22",x"23",x"41",x"E1",x"22",x"21",x"41",x"DC",x"E2",x"13",x"CC",x"82",
+x"09",x"D5",x"C5",x"CD",x"09",x"08",x"C1",x"D1",x"CD",x"47",x"08",x"CD",x"A4",x"09",
+x"01",x"38",x"81",x"11",x"3B",x"AA",x"CD",x"47",x"08",x"3A",x"24",x"41",x"FE",x"88",
+x"D2",x"31",x"09",x"CD",x"40",x"0B",x"C6",x"80",x"C6",x"02",x"DA",x"31",x"09",x"F5",
+x"21",x"F8",x"07",x"CD",x"0B",x"07",x"CD",x"41",x"08",x"F1",x"C1",x"D1",x"F5",x"CD",
+x"13",x"07",x"CD",x"82",x"09",x"21",x"79",x"14",x"CD",x"A9",x"14",x"11",x"00",x"00",
+x"C1",x"4A",x"C3",x"47",x"08",x"08",x"40",x"2E",x"94",x"74",x"70",x"4F",x"2E",x"77",
+x"6E",x"02",x"88",x"7A",x"E6",x"A0",x"2A",x"7C",x"50",x"AA",x"AA",x"7E",x"FF",x"FF",
+x"7F",x"7F",x"00",x"00",x"80",x"81",x"00",x"00",x"00",x"81",x"CD",x"A4",x"09",x"11",
+x"32",x"0C",x"D5",x"E5",x"CD",x"BF",x"09",x"CD",x"47",x"08",x"E1",x"CD",x"A4",x"09",
+x"7E",x"23",x"CD",x"B1",x"09",x"06",x"F1",x"C1",x"D1",x"3D",x"C8",x"D5",x"C5",x"F5",
+x"E5",x"CD",x"47",x"08",x"E1",x"CD",x"C2",x"09",x"E5",x"CD",x"16",x"07",x"E1",x"18",
+x"E9",x"CD",x"7F",x"0A",x"7C",x"B7",x"FA",x"4A",x"1E",x"B5",x"CA",x"F0",x"14",x"E5",
+x"CD",x"F0",x"14",x"CD",x"BF",x"09",x"EB",x"E3",x"C5",x"CD",x"CF",x"0A",x"C1",x"D1",
+x"CD",x"47",x"08",x"21",x"F8",x"07",x"CD",x"0B",x"07",x"C3",x"40",x"0B",x"21",x"90",
+x"40",x"E5",x"11",x"00",x"00",x"4B",x"26",x"03",x"2E",x"08",x"EB",x"29",x"EB",x"79",
+x"17",x"4F",x"E3",x"7E",x"07",x"77",x"E3",x"D2",x"16",x"15",x"E5",x"2A",x"AA",x"40",
+x"19",x"EB",x"3A",x"AC",x"40",x"89",x"4F",x"E1",x"2D",x"C2",x"FC",x"14",x"E3",x"23",
+x"E3",x"25",x"C2",x"FA",x"14",x"E1",x"21",x"65",x"B0",x"19",x"22",x"AA",x"40",x"CD",
+x"EF",x"0A",x"3E",x"05",x"89",x"32",x"AC",x"40",x"EB",x"06",x"80",x"21",x"25",x"41",
+x"70",x"2B",x"70",x"4F",x"06",x"00",x"C3",x"65",x"07",x"21",x"8B",x"15",x"CD",x"0B",
+x"07",x"CD",x"A4",x"09",x"01",x"49",x"83",x"11",x"DB",x"0F",x"CD",x"B4",x"09",x"C1",
+x"D1",x"CD",x"A2",x"08",x"CD",x"A4",x"09",x"CD",x"40",x"0B",x"C1",x"D1",x"CD",x"13",
+x"07",x"21",x"8F",x"15",x"CD",x"10",x"07",x"CD",x"55",x"09",x"37",x"F2",x"77",x"15",
+x"CD",x"08",x"07",x"CD",x"55",x"09",x"B7",x"F5",x"F4",x"82",x"09",x"21",x"8F",x"15",
+x"CD",x"0B",x"07",x"F1",x"D4",x"82",x"09",x"21",x"93",x"15",x"C3",x"9A",x"14",x"DB",
+x"0F",x"49",x"81",x"00",x"00",x"00",x"7F",x"05",x"BA",x"D7",x"1E",x"86",x"64",x"26",
+x"99",x"87",x"58",x"34",x"23",x"87",x"E0",x"5D",x"A5",x"86",x"DA",x"0F",x"49",x"83",
+x"CD",x"A4",x"09",x"CD",x"47",x"15",x"C1",x"E1",x"CD",x"A4",x"09",x"EB",x"CD",x"B4",
+x"09",x"CD",x"41",x"15",x"C3",x"A0",x"08",x"CD",x"55",x"09",x"FC",x"E2",x"13",x"FC",
+x"82",x"09",x"3A",x"24",x"41",x"FE",x"81",x"38",x"0C",x"01",x"00",x"81",x"51",x"59",
+x"CD",x"A2",x"08",x"21",x"10",x"07",x"E5",x"21",x"E3",x"15",x"CD",x"9A",x"14",x"21",
+x"8B",x"15",x"C9",x"09",x"4A",x"D7",x"3B",x"78",x"02",x"6E",x"84",x"7B",x"FE",x"C1",
+x"2F",x"7C",x"74",x"31",x"9A",x"7D",x"84",x"3D",x"5A",x"7D",x"C8",x"7F",x"91",x"7E",
+x"E4",x"BB",x"4C",x"7E",x"6C",x"AA",x"AA",x"7F",x"00",x"00",x"00",x"81",x"8A",x"09",
+x"37",x"0B",x"77",x"09",x"D4",x"27",x"EF",x"2A",x"F5",x"27",x"E7",x"13",x"C9",x"14",
+x"09",x"08",x"39",x"14",x"41",x"15",x"47",x"15",x"A8",x"15",x"BD",x"15",x"AA",x"2C",
+x"52",x"41",x"58",x"41",x"5E",x"41",x"61",x"41",x"64",x"41",x"67",x"41",x"6A",x"41",
+x"6D",x"41",x"70",x"41",x"7F",x"0A",x"B1",x"0A",x"DB",x"0A",x"26",x"0B",x"03",x"2A",
+x"36",x"28",x"C5",x"2A",x"0F",x"2A",x"1F",x"2A",x"61",x"2A",x"91",x"2A",x"9A",x"2A",
+x"C5",x"4E",x"44",x"C6",x"4F",x"52",x"D2",x"45",x"53",x"45",x"54",x"D3",x"45",x"54",
+x"C3",x"4C",x"53",x"C3",x"4D",x"44",x"D2",x"41",x"4E",x"44",x"4F",x"4D",x"CE",x"45",
+x"58",x"54",x"C4",x"41",x"54",x"41",x"C9",x"4E",x"50",x"55",x"54",x"C4",x"49",x"4D",
+x"D2",x"45",x"41",x"44",x"CC",x"45",x"54",x"C7",x"4F",x"54",x"4F",x"D2",x"55",x"4E",
+x"C9",x"46",x"D2",x"45",x"53",x"54",x"4F",x"52",x"45",x"C7",x"4F",x"53",x"55",x"42",
+x"D2",x"45",x"54",x"55",x"52",x"4E",x"D2",x"45",x"4D",x"D3",x"54",x"4F",x"50",x"C5",
+x"4C",x"53",x"45",x"D4",x"52",x"4F",x"4E",x"D4",x"52",x"4F",x"46",x"46",x"C4",x"45",
+x"46",x"53",x"54",x"52",x"C4",x"45",x"46",x"49",x"4E",x"54",x"C4",x"45",x"46",x"53",
+x"4E",x"47",x"C4",x"45",x"46",x"44",x"42",x"4C",x"CC",x"49",x"4E",x"45",x"C5",x"44",
+x"49",x"54",x"C5",x"52",x"52",x"4F",x"52",x"D2",x"45",x"53",x"55",x"4D",x"45",x"CF",
+x"55",x"54",x"CF",x"4E",x"CF",x"50",x"45",x"4E",x"C6",x"49",x"45",x"4C",x"44",x"C7",
+x"45",x"54",x"D0",x"55",x"54",x"C3",x"4C",x"4F",x"53",x"45",x"CC",x"4F",x"41",x"44",
+x"CD",x"45",x"52",x"47",x"45",x"CE",x"41",x"4D",x"45",x"CB",x"49",x"4C",x"4C",x"CC",
+x"53",x"45",x"54",x"D2",x"53",x"45",x"54",x"D3",x"41",x"56",x"45",x"D3",x"59",x"53",
+x"54",x"45",x"4D",x"CC",x"50",x"52",x"49",x"4E",x"54",x"C4",x"45",x"46",x"D0",x"4F",
+x"4B",x"45",x"D0",x"52",x"49",x"4E",x"54",x"C3",x"4F",x"4E",x"54",x"CC",x"49",x"53",
+x"54",x"CC",x"4C",x"49",x"53",x"54",x"C4",x"45",x"4C",x"45",x"54",x"45",x"C1",x"55",
+x"54",x"4F",x"C3",x"4C",x"45",x"41",x"52",x"C3",x"4C",x"4F",x"41",x"44",x"C3",x"53",
+x"41",x"56",x"45",x"CE",x"45",x"57",x"D4",x"41",x"42",x"28",x"D4",x"4F",x"C6",x"4E",
+x"D5",x"53",x"49",x"4E",x"47",x"D6",x"41",x"52",x"50",x"54",x"52",x"D5",x"53",x"52",
+x"C5",x"52",x"4C",x"C5",x"52",x"52",x"D3",x"54",x"52",x"49",x"4E",x"47",x"24",x"C9",
+x"4E",x"53",x"54",x"52",x"D0",x"4F",x"49",x"4E",x"54",x"D4",x"49",x"4D",x"45",x"24",
+x"CD",x"45",x"4D",x"C9",x"4E",x"4B",x"45",x"59",x"24",x"D4",x"48",x"45",x"4E",x"CE",
+x"4F",x"54",x"D3",x"54",x"45",x"50",x"AB",x"AD",x"AA",x"AF",x"DB",x"C1",x"4E",x"44",
+x"CF",x"52",x"BE",x"BD",x"BC",x"D3",x"47",x"4E",x"C9",x"4E",x"54",x"C1",x"42",x"53",
+x"C6",x"52",x"45",x"C9",x"4E",x"50",x"D0",x"4F",x"53",x"D3",x"51",x"52",x"D2",x"4E",
+x"44",x"CC",x"4F",x"47",x"C5",x"58",x"50",x"C3",x"4F",x"53",x"D3",x"49",x"4E",x"D4",
+x"41",x"4E",x"C1",x"54",x"4E",x"D0",x"45",x"45",x"4B",x"C3",x"56",x"49",x"C3",x"56",
+x"53",x"C3",x"56",x"44",x"C5",x"4F",x"46",x"CC",x"4F",x"43",x"CC",x"4F",x"46",x"CD",
+x"4B",x"49",x"24",x"CD",x"4B",x"53",x"24",x"CD",x"4B",x"44",x"24",x"C3",x"49",x"4E",
+x"54",x"C3",x"53",x"4E",x"47",x"C3",x"44",x"42",x"4C",x"C6",x"49",x"58",x"CC",x"45",
+x"4E",x"D3",x"54",x"52",x"24",x"D6",x"41",x"4C",x"C1",x"53",x"43",x"C3",x"48",x"52",
+x"24",x"CC",x"45",x"46",x"54",x"24",x"D2",x"49",x"47",x"48",x"54",x"24",x"CD",x"49",
+x"44",x"24",x"A7",x"80",x"AE",x"1D",x"A1",x"1C",x"38",x"01",x"35",x"01",x"C9",x"01",
+x"73",x"41",x"D3",x"01",x"B6",x"22",x"05",x"1F",x"9A",x"21",x"08",x"26",x"EF",x"21",
+x"21",x"1F",x"C2",x"1E",x"A3",x"1E",x"39",x"20",x"91",x"1D",x"B1",x"1E",x"DE",x"1E",
+x"07",x"1F",x"A9",x"1D",x"07",x"1F",x"F7",x"1D",x"F8",x"1D",x"00",x"1E",x"03",x"1E",
+x"06",x"1E",x"09",x"1E",x"A3",x"41",x"60",x"2E",x"F4",x"1F",x"AF",x"1F",x"FB",x"2A",
+x"6C",x"1F",x"79",x"41",x"7C",x"41",x"7F",x"41",x"82",x"41",x"85",x"41",x"88",x"41",
+x"8B",x"41",x"8E",x"41",x"91",x"41",x"97",x"41",x"9A",x"41",x"A0",x"41",x"B2",x"02",
+x"67",x"20",x"5B",x"41",x"B1",x"2C",x"6F",x"20",x"E4",x"1D",x"2E",x"2B",x"29",x"2B",
+x"C6",x"2B",x"08",x"20",x"7A",x"1E",x"1F",x"2C",x"F5",x"2B",x"49",x"1B",x"79",x"79",
+x"7C",x"7C",x"7F",x"50",x"46",x"DB",x"0A",x"00",x"00",x"7F",x"0A",x"F4",x"0A",x"B1",
+x"0A",x"77",x"0C",x"70",x"0C",x"A1",x"0D",x"E5",x"0D",x"78",x"0A",x"16",x"07",x"13",
+x"07",x"47",x"08",x"A2",x"08",x"0C",x"0A",x"D2",x"0B",x"C7",x"0B",x"F2",x"0B",x"90",
+x"24",x"39",x"0A",x"4E",x"46",x"53",x"4E",x"52",x"47",x"4F",x"44",x"46",x"43",x"4F",
+x"56",x"4F",x"4D",x"55",x"4C",x"42",x"53",x"44",x"44",x"2F",x"30",x"49",x"44",x"54",
+x"4D",x"4F",x"53",x"4C",x"53",x"53",x"54",x"43",x"4E",x"4E",x"52",x"52",x"57",x"55",
+x"45",x"4D",x"4F",x"46",x"44",x"53",x"4E",x"D6",x"00",x"6F",x"7C",x"DE",x"00",x"67",
+x"78",x"DE",x"00",x"47",x"3E",x"00",x"C9",x"4A",x"1E",x"40",x"E6",x"4D",x"DB",x"00",
+x"C9",x"D3",x"00",x"C9",x"00",x"00",x"00",x"00",x"40",x"30",x"00",x"4C",x"43",x"FE",
+x"FF",x"E9",x"42",x"20",x"45",x"72",x"72",x"6F",x"72",x"00",x"20",x"69",x"6E",x"20",
+x"00",x"52",x"45",x"41",x"44",x"59",x"0D",x"00",x"42",x"72",x"65",x"61",x"6B",x"00",
+x"21",x"04",x"00",x"39",x"7E",x"23",x"FE",x"81",x"C0",x"4E",x"23",x"46",x"23",x"E5",
+x"69",x"60",x"7A",x"B3",x"EB",x"28",x"02",x"EB",x"DF",x"01",x"0E",x"00",x"E1",x"C8",
+x"09",x"18",x"E5",x"CD",x"6C",x"19",x"C5",x"E3",x"C1",x"DF",x"7E",x"02",x"C8",x"0B",
+x"2B",x"18",x"F8",x"E5",x"2A",x"FD",x"40",x"06",x"00",x"09",x"09",x"3E",x"E5",x"3E",
+x"C6",x"95",x"6F",x"3E",x"FF",x"9C",x"38",x"04",x"67",x"39",x"E1",x"D8",x"1E",x"0C",
+x"18",x"24",x"2A",x"A2",x"40",x"7C",x"A5",x"3C",x"28",x"08",x"3A",x"F2",x"40",x"B7",
+x"1E",x"22",x"20",x"14",x"C3",x"C1",x"1D",x"2A",x"DA",x"40",x"22",x"A2",x"40",x"1E",
+x"02",x"01",x"1E",x"14",x"01",x"1E",x"00",x"01",x"1E",x"24",x"2A",x"A2",x"40",x"22",
+x"EA",x"40",x"22",x"EC",x"40",x"01",x"B4",x"19",x"2A",x"E8",x"40",x"C3",x"9A",x"1B",
+x"C1",x"7B",x"4B",x"32",x"9A",x"40",x"2A",x"E6",x"40",x"22",x"EE",x"40",x"EB",x"2A",
+x"EA",x"40",x"7C",x"A5",x"3C",x"28",x"07",x"22",x"F5",x"40",x"EB",x"22",x"F7",x"40",
+x"2A",x"F0",x"40",x"7C",x"B5",x"EB",x"21",x"F2",x"40",x"28",x"08",x"A6",x"20",x"05",
+x"35",x"EB",x"C3",x"36",x"1D",x"AF",x"77",x"59",x"CD",x"F9",x"20",x"21",x"C9",x"18",
+x"CD",x"A6",x"41",x"57",x"3E",x"3F",x"CD",x"2A",x"03",x"19",x"7E",x"CD",x"2A",x"03",
+x"D7",x"CD",x"2A",x"03",x"21",x"1D",x"19",x"E5",x"2A",x"EA",x"40",x"E3",x"CD",x"A7",
+x"28",x"E1",x"11",x"FE",x"FF",x"DF",x"CA",x"74",x"06",x"7C",x"A5",x"3C",x"C4",x"A7",
+x"0F",x"3E",x"C1",x"CD",x"8B",x"03",x"CD",x"AC",x"41",x"CD",x"F8",x"01",x"CD",x"F9",
+x"20",x"21",x"29",x"19",x"CD",x"A7",x"28",x"3A",x"9A",x"40",x"D6",x"02",x"CC",x"53",
+x"2E",x"21",x"FF",x"FF",x"22",x"A2",x"40",x"3A",x"E1",x"40",x"B7",x"28",x"37",x"2A",
+x"E2",x"40",x"E5",x"CD",x"AF",x"0F",x"D1",x"D5",x"CD",x"2C",x"1B",x"3E",x"2A",x"38",
+x"02",x"3E",x"20",x"CD",x"2A",x"03",x"CD",x"61",x"03",x"D1",x"30",x"06",x"AF",x"32",
+x"E1",x"40",x"18",x"B9",x"2A",x"E4",x"40",x"19",x"38",x"F4",x"D5",x"11",x"F9",x"FF",
+x"DF",x"D1",x"30",x"EC",x"22",x"E2",x"40",x"F6",x"FF",x"C3",x"EB",x"2F",x"3E",x"3E",
+x"CD",x"2A",x"03",x"CD",x"61",x"03",x"DA",x"33",x"1A",x"D7",x"3C",x"3D",x"CA",x"33",
+x"1A",x"F5",x"CD",x"5A",x"1E",x"2B",x"7E",x"FE",x"20",x"28",x"FA",x"23",x"7E",x"FE",
+x"20",x"CC",x"C9",x"09",x"D5",x"CD",x"C0",x"1B",x"D1",x"F1",x"22",x"E6",x"40",x"CD",
+x"B2",x"41",x"D2",x"5A",x"1D",x"D5",x"C5",x"AF",x"32",x"DD",x"40",x"D7",x"B7",x"F5",
+x"EB",x"22",x"EC",x"40",x"EB",x"CD",x"2C",x"1B",x"C5",x"DC",x"E4",x"2B",x"D1",x"F1",
+x"D5",x"28",x"27",x"D1",x"2A",x"F9",x"40",x"E3",x"C1",x"09",x"E5",x"CD",x"55",x"19",
+x"E1",x"22",x"F9",x"40",x"EB",x"74",x"D1",x"E5",x"23",x"23",x"73",x"23",x"72",x"23",
+x"EB",x"2A",x"A7",x"40",x"EB",x"1B",x"1B",x"1A",x"77",x"23",x"13",x"B7",x"20",x"F9",
+x"D1",x"CD",x"FC",x"1A",x"CD",x"B5",x"41",x"CD",x"5D",x"1B",x"CD",x"B8",x"41",x"C3",
+x"33",x"1A",x"2A",x"A4",x"40",x"EB",x"62",x"6B",x"7E",x"23",x"B6",x"C8",x"23",x"23",
+x"23",x"AF",x"BE",x"23",x"20",x"FC",x"EB",x"73",x"23",x"72",x"18",x"EC",x"11",x"00",
+x"00",x"D5",x"28",x"09",x"D1",x"CD",x"4F",x"1E",x"D5",x"28",x"0B",x"CF",x"CE",x"11",
+x"FA",x"FF",x"C4",x"4F",x"1E",x"C2",x"97",x"19",x"EB",x"D1",x"E3",x"E5",x"2A",x"A4",
+x"40",x"44",x"4D",x"7E",x"23",x"B6",x"2B",x"C8",x"23",x"23",x"7E",x"23",x"66",x"6F",
+x"DF",x"60",x"69",x"7E",x"23",x"66",x"6F",x"3F",x"C8",x"3F",x"D0",x"18",x"E6",x"C0",
+x"CD",x"C9",x"01",x"2A",x"A4",x"40",x"CD",x"F8",x"1D",x"32",x"E1",x"40",x"77",x"23",
+x"77",x"23",x"22",x"F9",x"40",x"2A",x"A4",x"40",x"2B",x"22",x"DF",x"40",x"06",x"1A",
+x"21",x"01",x"41",x"36",x"04",x"23",x"10",x"FB",x"AF",x"32",x"F2",x"40",x"6F",x"67",
+x"22",x"F0",x"40",x"22",x"F7",x"40",x"2A",x"B1",x"40",x"22",x"D6",x"40",x"CD",x"91",
+x"1D",x"2A",x"F9",x"40",x"22",x"FB",x"40",x"22",x"FD",x"40",x"CD",x"BB",x"41",x"C1",
+x"2A",x"A0",x"40",x"2B",x"2B",x"22",x"E8",x"40",x"23",x"23",x"F9",x"21",x"B5",x"40",
+x"22",x"B3",x"40",x"CD",x"8B",x"03",x"CD",x"69",x"21",x"AF",x"67",x"6F",x"32",x"DC",
+x"40",x"E5",x"C5",x"2A",x"DF",x"40",x"C9",x"3E",x"3F",x"CD",x"2A",x"03",x"3E",x"20",
+x"CD",x"2A",x"03",x"C3",x"61",x"03",x"AF",x"32",x"B0",x"40",x"4F",x"EB",x"2A",x"A7",
+x"40",x"2B",x"2B",x"EB",x"7E",x"FE",x"20",x"CA",x"5B",x"1C",x"47",x"FE",x"22",x"CA",
+x"77",x"1C",x"B7",x"CA",x"7D",x"1C",x"3A",x"B0",x"40",x"B7",x"7E",x"C2",x"5B",x"1C",
+x"FE",x"3F",x"3E",x"B2",x"CA",x"5B",x"1C",x"7E",x"FE",x"30",x"38",x"05",x"FE",x"3C",
+x"DA",x"5B",x"1C",x"D5",x"11",x"4F",x"16",x"C5",x"01",x"3D",x"1C",x"C5",x"06",x"7F",
+x"7E",x"FE",x"61",x"38",x"07",x"FE",x"7B",x"30",x"03",x"E6",x"5F",x"77",x"4E",x"EB",
+x"23",x"B6",x"F2",x"0E",x"1C",x"04",x"7E",x"E6",x"7F",x"C8",x"B9",x"20",x"F3",x"EB",
+x"E5",x"13",x"1A",x"B7",x"FA",x"39",x"1C",x"4F",x"78",x"FE",x"8D",x"20",x"02",x"D7",
+x"2B",x"23",x"7E",x"FE",x"61",x"38",x"02",x"E6",x"5F",x"B9",x"28",x"E7",x"E1",x"18",
+x"D3",x"48",x"F1",x"EB",x"C9",x"EB",x"79",x"C1",x"D1",x"EB",x"FE",x"95",x"36",x"3A",
+x"20",x"02",x"0C",x"23",x"FE",x"FB",x"20",x"0C",x"36",x"3A",x"23",x"06",x"93",x"70",
+x"23",x"EB",x"0C",x"0C",x"18",x"1D",x"EB",x"23",x"12",x"13",x"0C",x"D6",x"3A",x"28",
+x"04",x"FE",x"4E",x"20",x"03",x"32",x"B0",x"40",x"D6",x"59",x"C2",x"CC",x"1B",x"47",
+x"7E",x"B7",x"28",x"09",x"B8",x"28",x"E4",x"23",x"12",x"0C",x"13",x"18",x"F3",x"21",
+x"05",x"00",x"44",x"09",x"44",x"4D",x"2A",x"A7",x"40",x"2B",x"2B",x"2B",x"12",x"13",
+x"12",x"13",x"12",x"C9",x"7C",x"92",x"C0",x"7D",x"93",x"C9",x"7E",x"E3",x"BE",x"23",
+x"E3",x"CA",x"78",x"1D",x"C3",x"97",x"19",x"3E",x"64",x"32",x"DC",x"40",x"CD",x"21",
+x"1F",x"E3",x"CD",x"36",x"19",x"D1",x"20",x"05",x"09",x"F9",x"22",x"E8",x"40",x"EB",
+x"0E",x"08",x"CD",x"63",x"19",x"E5",x"CD",x"05",x"1F",x"E3",x"E5",x"2A",x"A2",x"40",
+x"E3",x"CF",x"BD",x"E7",x"CA",x"F6",x"0A",x"D2",x"F6",x"0A",x"F5",x"CD",x"37",x"23",
+x"F1",x"E5",x"F2",x"EC",x"1C",x"CD",x"7F",x"0A",x"E3",x"11",x"01",x"00",x"7E",x"FE",
+x"CC",x"CC",x"01",x"2B",x"D5",x"E5",x"EB",x"CD",x"9E",x"09",x"18",x"22",x"CD",x"B1",
+x"0A",x"CD",x"BF",x"09",x"E1",x"C5",x"D5",x"01",x"00",x"81",x"51",x"5A",x"7E",x"FE",
+x"CC",x"3E",x"01",x"20",x"0E",x"CD",x"38",x"23",x"E5",x"CD",x"B1",x"0A",x"CD",x"BF",
+x"09",x"CD",x"55",x"09",x"E1",x"C5",x"D5",x"4F",x"E7",x"47",x"C5",x"E5",x"2A",x"DF",
+x"40",x"E3",x"06",x"81",x"C5",x"33",x"CD",x"58",x"03",x"B7",x"C4",x"A0",x"1D",x"22",
+x"E6",x"40",x"ED",x"73",x"E8",x"40",x"7E",x"FE",x"3A",x"28",x"29",x"B7",x"C2",x"97",
+x"19",x"23",x"7E",x"23",x"B6",x"CA",x"7E",x"19",x"23",x"5E",x"23",x"56",x"EB",x"22",
+x"A2",x"40",x"3A",x"1B",x"41",x"B7",x"28",x"0F",x"D5",x"3E",x"3C",x"CD",x"2A",x"03",
+x"CD",x"AF",x"0F",x"3E",x"3E",x"CD",x"2A",x"03",x"D1",x"EB",x"D7",x"11",x"1E",x"1D",
+x"D5",x"C8",x"D6",x"80",x"DA",x"21",x"1F",x"FE",x"3C",x"D2",x"E7",x"2A",x"07",x"4F",
+x"06",x"00",x"EB",x"21",x"22",x"18",x"09",x"4E",x"23",x"46",x"C5",x"EB",x"23",x"7E",
+x"FE",x"3A",x"D0",x"FE",x"20",x"CA",x"78",x"1D",x"FE",x"0B",x"30",x"05",x"FE",x"09",
+x"D2",x"78",x"1D",x"FE",x"30",x"3F",x"3C",x"3D",x"C9",x"EB",x"2A",x"A4",x"40",x"2B",
+x"22",x"FF",x"40",x"EB",x"C9",x"CD",x"58",x"03",x"B7",x"C8",x"FE",x"60",x"CC",x"84",
+x"03",x"32",x"99",x"40",x"3D",x"C0",x"3C",x"C3",x"B4",x"1D",x"C0",x"F5",x"CC",x"BB",
+x"41",x"F1",x"22",x"E6",x"40",x"21",x"B5",x"40",x"22",x"B3",x"40",x"21",x"F6",x"FF",
+x"C1",x"2A",x"A2",x"40",x"E5",x"F5",x"7D",x"A4",x"3C",x"28",x"09",x"22",x"F5",x"40",
+x"2A",x"E6",x"40",x"22",x"F7",x"40",x"CD",x"8B",x"03",x"CD",x"F9",x"20",x"F1",x"21",
+x"30",x"19",x"C2",x"06",x"1A",x"C3",x"18",x"1A",x"2A",x"F7",x"40",x"7C",x"B5",x"1E",
+x"20",x"CA",x"A2",x"19",x"EB",x"2A",x"F5",x"40",x"22",x"A2",x"40",x"EB",x"C9",x"3E",
+x"AF",x"32",x"1B",x"41",x"C9",x"F1",x"E1",x"C9",x"1E",x"03",x"01",x"1E",x"02",x"01",
+x"1E",x"04",x"01",x"1E",x"08",x"CD",x"3D",x"1E",x"01",x"97",x"19",x"C5",x"D8",x"D6",
+x"41",x"4F",x"47",x"D7",x"FE",x"CE",x"20",x"09",x"D7",x"CD",x"3D",x"1E",x"D8",x"D6",
+x"41",x"47",x"D7",x"78",x"91",x"D8",x"3C",x"E3",x"21",x"01",x"41",x"06",x"00",x"09",
+x"73",x"23",x"3D",x"20",x"FB",x"E1",x"7E",x"FE",x"2C",x"C0",x"D7",x"18",x"CE",x"7E",
+x"FE",x"41",x"D8",x"FE",x"5B",x"3F",x"C9",x"D7",x"CD",x"02",x"2B",x"F0",x"1E",x"08",
+x"C3",x"A2",x"19",x"7E",x"FE",x"2E",x"EB",x"2A",x"EC",x"40",x"EB",x"CA",x"78",x"1D",
+x"2B",x"11",x"00",x"00",x"D7",x"D0",x"E5",x"F5",x"21",x"98",x"19",x"DF",x"DA",x"97",
+x"19",x"62",x"6B",x"19",x"29",x"19",x"29",x"F1",x"D6",x"30",x"5F",x"16",x"00",x"19",
+x"EB",x"E1",x"18",x"E4",x"CA",x"61",x"1B",x"CD",x"46",x"1E",x"2B",x"D7",x"C0",x"E5",
+x"2A",x"B1",x"40",x"7D",x"93",x"5F",x"7C",x"9A",x"57",x"DA",x"7A",x"19",x"2A",x"F9",
+x"40",x"01",x"28",x"00",x"09",x"DF",x"D2",x"7A",x"19",x"EB",x"22",x"A0",x"40",x"E1",
+x"C3",x"61",x"1B",x"CA",x"5D",x"1B",x"CD",x"C7",x"41",x"CD",x"61",x"1B",x"01",x"1E",
+x"1D",x"18",x"10",x"0E",x"03",x"CD",x"63",x"19",x"C1",x"E5",x"E5",x"2A",x"A2",x"40",
+x"E3",x"3E",x"91",x"F5",x"33",x"C5",x"CD",x"5A",x"1E",x"CD",x"07",x"1F",x"E5",x"2A",
+x"A2",x"40",x"DF",x"E1",x"23",x"DC",x"2F",x"1B",x"D4",x"2C",x"1B",x"60",x"69",x"2B",
+x"D8",x"1E",x"0E",x"C3",x"A2",x"19",x"C0",x"16",x"FF",x"CD",x"36",x"19",x"F9",x"22",
+x"E8",x"40",x"FE",x"91",x"1E",x"04",x"C2",x"A2",x"19",x"E1",x"22",x"A2",x"40",x"23",
+x"7C",x"B5",x"20",x"07",x"3A",x"DD",x"40",x"B7",x"C2",x"18",x"1A",x"21",x"1E",x"1D",
+x"E3",x"3E",x"E1",x"01",x"3A",x"0E",x"00",x"06",x"00",x"79",x"48",x"47",x"7E",x"B7",
+x"C8",x"B8",x"C8",x"23",x"FE",x"22",x"28",x"F3",x"D6",x"8F",x"20",x"F2",x"B8",x"8A",
+x"57",x"18",x"ED",x"CD",x"0D",x"26",x"CF",x"D5",x"EB",x"22",x"DF",x"40",x"EB",x"D5",
+x"E7",x"F5",x"CD",x"37",x"23",x"F1",x"E3",x"C6",x"03",x"CD",x"19",x"28",x"CD",x"03",
+x"0A",x"E5",x"20",x"28",x"2A",x"21",x"41",x"E5",x"23",x"5E",x"23",x"56",x"2A",x"A4",
+x"40",x"DF",x"30",x"0E",x"2A",x"A0",x"40",x"DF",x"D1",x"30",x"0F",x"2A",x"F9",x"40",
+x"DF",x"30",x"09",x"3E",x"D1",x"CD",x"F5",x"29",x"EB",x"CD",x"43",x"28",x"CD",x"F5",
+x"29",x"E3",x"CD",x"D3",x"09",x"D1",x"E1",x"C9",x"FE",x"9E",x"20",x"25",x"D7",x"CF",
+x"8D",x"CD",x"5A",x"1E",x"7A",x"B3",x"28",x"09",x"CD",x"2A",x"1B",x"50",x"59",x"E1",
+x"D2",x"D9",x"1E",x"EB",x"22",x"F0",x"40",x"EB",x"D8",x"3A",x"F2",x"40",x"B7",x"C8",
+x"3A",x"9A",x"40",x"5F",x"C3",x"AB",x"19",x"CD",x"1C",x"2B",x"7E",x"47",x"FE",x"91",
+x"28",x"03",x"CF",x"8D",x"2B",x"4B",x"0D",x"78",x"CA",x"60",x"1D",x"CD",x"5B",x"1E",
+x"FE",x"2C",x"C0",x"18",x"F3",x"11",x"F2",x"40",x"1A",x"B7",x"CA",x"A0",x"19",x"3C",
+x"32",x"9A",x"40",x"12",x"7E",x"FE",x"87",x"28",x"0C",x"CD",x"5A",x"1E",x"C0",x"7A",
+x"B3",x"C2",x"C5",x"1E",x"3C",x"18",x"02",x"D7",x"C0",x"2A",x"EE",x"40",x"EB",x"2A",
+x"EA",x"40",x"22",x"A2",x"40",x"EB",x"C0",x"7E",x"B7",x"20",x"04",x"23",x"23",x"23",
+x"23",x"23",x"7A",x"A3",x"3C",x"C2",x"05",x"1F",x"3A",x"DD",x"40",x"3D",x"CA",x"BE",
+x"1D",x"C3",x"05",x"1F",x"CD",x"1C",x"2B",x"C0",x"B7",x"CA",x"4A",x"1E",x"3D",x"87",
+x"5F",x"FE",x"2D",x"38",x"02",x"1E",x"26",x"C3",x"A2",x"19",x"11",x"0A",x"00",x"D5",
+x"28",x"17",x"CD",x"4F",x"1E",x"EB",x"E3",x"28",x"11",x"EB",x"CF",x"2C",x"EB",x"2A",
+x"E4",x"40",x"EB",x"28",x"06",x"CD",x"5A",x"1E",x"C2",x"97",x"19",x"EB",x"7C",x"B5",
+x"CA",x"4A",x"1E",x"22",x"E4",x"40",x"32",x"E1",x"40",x"E1",x"22",x"E2",x"40",x"C1",
+x"C3",x"33",x"1A",x"CD",x"37",x"23",x"7E",x"FE",x"2C",x"CC",x"78",x"1D",x"FE",x"CA",
+x"CC",x"78",x"1D",x"2B",x"E5",x"CD",x"94",x"09",x"E1",x"28",x"07",x"D7",x"DA",x"C2",
+x"1E",x"C3",x"5F",x"1D",x"16",x"01",x"CD",x"05",x"1F",x"B7",x"C8",x"D7",x"FE",x"95",
+x"20",x"F6",x"15",x"20",x"F3",x"18",x"E8",x"3E",x"01",x"32",x"9C",x"40",x"C3",x"9B",
+x"20",x"CD",x"CA",x"41",x"FE",x"40",x"20",x"19",x"CD",x"01",x"2B",x"FE",x"04",x"D2",
+x"4A",x"1E",x"E5",x"21",x"00",x"3C",x"19",x"22",x"20",x"40",x"7B",x"E6",x"3F",x"32",
+x"A6",x"40",x"E1",x"CF",x"2C",x"FE",x"23",x"20",x"08",x"CD",x"84",x"02",x"3E",x"80",
+x"32",x"9C",x"40",x"2B",x"D7",x"CC",x"FE",x"20",x"CA",x"69",x"21",x"FE",x"BF",x"CA",
+x"BD",x"2C",x"FE",x"BC",x"CA",x"37",x"21",x"E5",x"FE",x"2C",x"CA",x"08",x"21",x"FE",
+x"3B",x"CA",x"64",x"21",x"C1",x"CD",x"37",x"23",x"E5",x"E7",x"28",x"32",x"CD",x"BD",
+x"0F",x"CD",x"65",x"28",x"CD",x"CD",x"41",x"2A",x"21",x"41",x"3A",x"9C",x"40",x"B7",
+x"FA",x"E9",x"20",x"28",x"08",x"3A",x"9B",x"40",x"86",x"FE",x"84",x"18",x"09",x"3A",
+x"9D",x"40",x"47",x"3A",x"A6",x"40",x"86",x"B8",x"D4",x"FE",x"20",x"CD",x"AA",x"28",
+x"3E",x"20",x"CD",x"2A",x"03",x"B7",x"CC",x"AA",x"28",x"E1",x"C3",x"9B",x"20",x"3A",
+x"A6",x"40",x"B7",x"C8",x"3E",x"0D",x"CD",x"2A",x"03",x"CD",x"D0",x"41",x"AF",x"C9",
+x"CD",x"D3",x"41",x"3A",x"9C",x"40",x"B7",x"F2",x"19",x"21",x"3E",x"2C",x"CD",x"2A",
+x"03",x"18",x"4B",x"28",x"08",x"3A",x"9B",x"40",x"FE",x"70",x"C3",x"2B",x"21",x"3A",
+x"9E",x"40",x"47",x"3A",x"A6",x"40",x"B8",x"D4",x"FE",x"20",x"30",x"34",x"D6",x"10",
+x"30",x"FC",x"2F",x"18",x"23",x"CD",x"1B",x"2B",x"E6",x"3F",x"5F",x"CF",x"29",x"2B",
+x"E5",x"CD",x"D3",x"41",x"3A",x"9C",x"40",x"B7",x"FA",x"4A",x"1E",x"CA",x"53",x"21",
+x"3A",x"9B",x"40",x"18",x"03",x"3A",x"A6",x"40",x"2F",x"83",x"30",x"0A",x"3C",x"47",
+x"3E",x"20",x"CD",x"2A",x"03",x"05",x"20",x"FA",x"E1",x"D7",x"C3",x"A0",x"20",x"3A",
+x"9C",x"40",x"B7",x"FC",x"F8",x"01",x"AF",x"32",x"9C",x"40",x"CD",x"BE",x"41",x"C9",
+x"3F",x"52",x"45",x"44",x"4F",x"0D",x"00",x"3A",x"DE",x"40",x"B7",x"C2",x"91",x"19",
+x"3A",x"A9",x"40",x"B7",x"1E",x"2A",x"CA",x"A2",x"19",x"C1",x"21",x"78",x"21",x"CD",
+x"A7",x"28",x"2A",x"E6",x"40",x"C9",x"CD",x"28",x"28",x"7E",x"CD",x"D6",x"41",x"D6",
+x"23",x"32",x"A9",x"40",x"7E",x"20",x"20",x"CD",x"93",x"02",x"E5",x"06",x"FA",x"2A",
+x"A7",x"40",x"CD",x"35",x"02",x"77",x"23",x"FE",x"0D",x"28",x"02",x"10",x"F5",x"2B",
+x"36",x"00",x"CD",x"F8",x"01",x"2A",x"A7",x"40",x"2B",x"18",x"22",x"01",x"DB",x"21",
+x"C5",x"FE",x"22",x"C0",x"CD",x"66",x"28",x"CF",x"3B",x"E5",x"CD",x"AA",x"28",x"E1",
+x"C9",x"E5",x"CD",x"B3",x"1B",x"C1",x"DA",x"BE",x"1D",x"23",x"7E",x"B7",x"2B",x"C5",
+x"CA",x"04",x"1F",x"36",x"2C",x"18",x"05",x"E5",x"2A",x"FF",x"40",x"F6",x"AF",x"32",
+x"DE",x"40",x"E3",x"18",x"02",x"CF",x"2C",x"CD",x"0D",x"26",x"E3",x"D5",x"7E",x"FE",
+x"2C",x"28",x"26",x"3A",x"DE",x"40",x"B7",x"C2",x"96",x"22",x"3A",x"A9",x"40",x"B7",
+x"1E",x"06",x"CA",x"A2",x"19",x"3E",x"3F",x"CD",x"2A",x"03",x"CD",x"B3",x"1B",x"D1",
+x"C1",x"DA",x"BE",x"1D",x"23",x"7E",x"B7",x"2B",x"C5",x"CA",x"04",x"1F",x"D5",x"CD",
+x"DC",x"41",x"E7",x"F5",x"20",x"19",x"D7",x"57",x"47",x"FE",x"22",x"28",x"05",x"16",
+x"3A",x"06",x"2C",x"2B",x"CD",x"69",x"28",x"F1",x"EB",x"21",x"5A",x"22",x"E3",x"D5",
+x"C3",x"33",x"1F",x"D7",x"F1",x"F5",x"01",x"43",x"22",x"C5",x"DA",x"6C",x"0E",x"D2",
+x"65",x"0E",x"2B",x"D7",x"28",x"05",x"FE",x"2C",x"C2",x"7F",x"21",x"E3",x"2B",x"D7",
+x"C2",x"FB",x"21",x"D1",x"00",x"00",x"00",x"00",x"00",x"3A",x"DE",x"40",x"B7",x"EB",
+x"C2",x"96",x"1D",x"D5",x"CD",x"DF",x"41",x"B6",x"21",x"86",x"22",x"C4",x"A7",x"28",
+x"E1",x"C3",x"69",x"21",x"3F",x"45",x"78",x"74",x"72",x"61",x"20",x"69",x"67",x"6E",
+x"6F",x"72",x"65",x"64",x"0D",x"00",x"CD",x"05",x"1F",x"B7",x"20",x"12",x"23",x"7E",
+x"23",x"B6",x"1E",x"06",x"CA",x"A2",x"19",x"23",x"5E",x"23",x"56",x"EB",x"22",x"DA",
+x"40",x"EB",x"D7",x"FE",x"88",x"20",x"E3",x"C3",x"2D",x"22",x"11",x"00",x"00",x"C4",
+x"0D",x"26",x"22",x"DF",x"40",x"CD",x"36",x"19",x"C2",x"9D",x"19",x"F9",x"22",x"E8",
+x"40",x"D5",x"7E",x"23",x"F5",x"D5",x"7E",x"23",x"B7",x"FA",x"EA",x"22",x"CD",x"B1",
+x"09",x"E3",x"E5",x"CD",x"0B",x"07",x"E1",x"CD",x"CB",x"09",x"E1",x"CD",x"C2",x"09",
+x"E5",x"CD",x"0C",x"0A",x"18",x"29",x"23",x"23",x"23",x"23",x"4E",x"23",x"46",x"23",
+x"E3",x"5E",x"23",x"56",x"E5",x"69",x"60",x"CD",x"D2",x"0B",x"3A",x"AF",x"40",x"FE",
+x"04",x"CA",x"B2",x"07",x"EB",x"E1",x"72",x"2B",x"73",x"E1",x"D5",x"5E",x"23",x"56",
+x"23",x"E3",x"CD",x"39",x"0A",x"E1",x"C1",x"90",x"CD",x"C2",x"09",x"28",x"09",x"EB",
+x"22",x"A2",x"40",x"69",x"60",x"C3",x"1A",x"1D",x"F9",x"22",x"E8",x"40",x"2A",x"DF",
+x"40",x"7E",x"FE",x"2C",x"C2",x"1E",x"1D",x"D7",x"CD",x"B9",x"22",x"CF",x"28",x"2B",
+x"16",x"00",x"D5",x"0E",x"01",x"CD",x"63",x"19",x"CD",x"9F",x"24",x"22",x"F3",x"40",
+x"2A",x"F3",x"40",x"C1",x"7E",x"16",x"00",x"D6",x"D4",x"38",x"13",x"FE",x"03",x"30",
+x"0F",x"FE",x"01",x"17",x"AA",x"BA",x"57",x"DA",x"97",x"19",x"22",x"D8",x"40",x"D7",
+x"18",x"E9",x"7A",x"B7",x"C2",x"EC",x"23",x"7E",x"22",x"D8",x"40",x"D6",x"CD",x"D8",
+x"FE",x"07",x"D0",x"5F",x"3A",x"AF",x"40",x"D6",x"03",x"B3",x"CA",x"8F",x"29",x"21",
+x"9A",x"18",x"19",x"78",x"56",x"BA",x"D0",x"C5",x"01",x"46",x"23",x"C5",x"7A",x"FE",
+x"7F",x"CA",x"D4",x"23",x"FE",x"51",x"DA",x"E1",x"23",x"21",x"21",x"41",x"B7",x"3A",
+x"AF",x"40",x"3D",x"3D",x"3D",x"CA",x"F6",x"0A",x"4E",x"23",x"46",x"C5",x"FA",x"C5",
+x"23",x"23",x"4E",x"23",x"46",x"C5",x"F5",x"B7",x"E2",x"C4",x"23",x"F1",x"23",x"38",
+x"03",x"21",x"1D",x"41",x"4E",x"23",x"46",x"23",x"C5",x"4E",x"23",x"46",x"C5",x"06",
+x"F1",x"C6",x"03",x"4B",x"47",x"C5",x"01",x"06",x"24",x"C5",x"2A",x"D8",x"40",x"C3",
+x"3A",x"23",x"CD",x"B1",x"0A",x"CD",x"A4",x"09",x"01",x"F2",x"13",x"16",x"7F",x"18",
+x"EC",x"D5",x"CD",x"7F",x"0A",x"D1",x"E5",x"01",x"E9",x"25",x"18",x"E1",x"78",x"FE",
+x"64",x"D0",x"C5",x"D5",x"11",x"04",x"64",x"21",x"B8",x"25",x"E5",x"E7",x"C2",x"95",
+x"23",x"2A",x"21",x"41",x"E5",x"01",x"8C",x"25",x"18",x"C7",x"C1",x"79",x"32",x"B0",
+x"40",x"78",x"FE",x"08",x"28",x"28",x"3A",x"AF",x"40",x"FE",x"08",x"CA",x"60",x"24",
+x"57",x"78",x"FE",x"04",x"CA",x"72",x"24",x"7A",x"FE",x"03",x"CA",x"F6",x"0A",x"D2",
+x"7C",x"24",x"21",x"BF",x"18",x"06",x"00",x"09",x"09",x"4E",x"23",x"46",x"D1",x"2A",
+x"21",x"41",x"C5",x"C9",x"CD",x"DB",x"0A",x"CD",x"FC",x"09",x"E1",x"22",x"1F",x"41",
+x"E1",x"22",x"1D",x"41",x"C1",x"D1",x"CD",x"B4",x"09",x"CD",x"DB",x"0A",x"21",x"AB",
+x"18",x"3A",x"B0",x"40",x"07",x"C5",x"4F",x"06",x"00",x"09",x"C1",x"7E",x"23",x"66",
+x"6F",x"E9",x"C5",x"CD",x"FC",x"09",x"F1",x"32",x"AF",x"40",x"FE",x"04",x"28",x"DA",
+x"E1",x"22",x"21",x"41",x"18",x"D9",x"CD",x"B1",x"0A",x"C1",x"D1",x"21",x"B5",x"18",
+x"18",x"D5",x"E1",x"CD",x"A4",x"09",x"CD",x"CF",x"0A",x"CD",x"BF",x"09",x"E1",x"22",
+x"23",x"41",x"E1",x"22",x"21",x"41",x"18",x"E7",x"E5",x"EB",x"CD",x"CF",x"0A",x"E1",
+x"CD",x"A4",x"09",x"CD",x"CF",x"0A",x"C3",x"A0",x"08",x"D7",x"1E",x"28",x"CA",x"A2",
+x"19",x"DA",x"6C",x"0E",x"CD",x"3D",x"1E",x"D2",x"40",x"25",x"FE",x"CD",x"28",x"ED",
+x"FE",x"2E",x"CA",x"6C",x"0E",x"FE",x"CE",x"CA",x"32",x"25",x"FE",x"22",x"CA",x"66",
+x"28",x"FE",x"CB",x"CA",x"C4",x"25",x"FE",x"26",x"CA",x"94",x"41",x"FE",x"C3",x"20",
+x"0A",x"D7",x"3A",x"9A",x"40",x"E5",x"CD",x"F8",x"27",x"E1",x"C9",x"FE",x"C2",x"20",
+x"0A",x"D7",x"E5",x"2A",x"EA",x"40",x"CD",x"66",x"0C",x"E1",x"C9",x"FE",x"C0",x"20",
+x"14",x"D7",x"CF",x"28",x"CD",x"0D",x"26",x"CF",x"29",x"E5",x"EB",x"7C",x"B5",x"CA",
+x"4A",x"1E",x"CD",x"9A",x"0A",x"E1",x"C9",x"FE",x"C1",x"CA",x"FE",x"27",x"FE",x"C5",
+x"CA",x"9D",x"41",x"FE",x"C8",x"CA",x"C9",x"27",x"FE",x"C7",x"CA",x"76",x"41",x"FE",
+x"C6",x"CA",x"32",x"01",x"FE",x"C9",x"CA",x"9D",x"01",x"FE",x"C4",x"CA",x"2F",x"2A",
+x"FE",x"BE",x"CA",x"55",x"41",x"D6",x"D7",x"D2",x"4E",x"25",x"CD",x"35",x"23",x"CF",
+x"29",x"C9",x"16",x"7D",x"CD",x"3A",x"23",x"2A",x"F3",x"40",x"E5",x"CD",x"7B",x"09",
+x"E1",x"C9",x"CD",x"0D",x"26",x"E5",x"EB",x"22",x"21",x"41",x"E7",x"C4",x"F7",x"09",
+x"E1",x"C9",x"06",x"00",x"07",x"4F",x"C5",x"D7",x"79",x"FE",x"41",x"38",x"16",x"CD",
+x"35",x"23",x"CF",x"2C",x"CD",x"F4",x"0A",x"EB",x"2A",x"21",x"41",x"E3",x"E5",x"EB",
+x"CD",x"1C",x"2B",x"EB",x"E3",x"18",x"14",x"CD",x"2C",x"25",x"E3",x"7D",x"FE",x"0C",
+x"38",x"07",x"FE",x"1B",x"E5",x"DC",x"B1",x"0A",x"E1",x"11",x"3E",x"25",x"D5",x"01",
+x"08",x"16",x"09",x"4E",x"23",x"66",x"69",x"E9",x"CD",x"D7",x"29",x"7E",x"23",x"4E",
+x"23",x"46",x"D1",x"C5",x"F5",x"CD",x"DE",x"29",x"D1",x"5E",x"23",x"4E",x"23",x"46",
+x"E1",x"7B",x"B2",x"C8",x"7A",x"D6",x"01",x"D8",x"AF",x"BB",x"3C",x"D0",x"15",x"1D",
+x"0A",x"BE",x"23",x"03",x"28",x"ED",x"3F",x"C3",x"60",x"09",x"3C",x"8F",x"C1",x"A0",
+x"C6",x"FF",x"9F",x"CD",x"8D",x"09",x"18",x"12",x"16",x"5A",x"CD",x"3A",x"23",x"CD",
+x"7F",x"0A",x"7D",x"2F",x"6F",x"7C",x"2F",x"67",x"22",x"21",x"41",x"C1",x"C3",x"46",
+x"23",x"3A",x"AF",x"40",x"FE",x"08",x"30",x"05",x"D6",x"03",x"B7",x"37",x"C9",x"D6",
+x"03",x"B7",x"C9",x"C5",x"CD",x"7F",x"0A",x"F1",x"D1",x"01",x"FA",x"27",x"C5",x"FE",
+x"46",x"20",x"06",x"7B",x"B5",x"6F",x"7C",x"B2",x"C9",x"7B",x"A5",x"6F",x"7C",x"A2",
+x"C9",x"2B",x"D7",x"C8",x"CF",x"2C",x"01",x"03",x"26",x"C5",x"F6",x"AF",x"32",x"AE",
+x"40",x"46",x"CD",x"3D",x"1E",x"DA",x"97",x"19",x"AF",x"4F",x"D7",x"38",x"05",x"CD",
+x"3D",x"1E",x"38",x"09",x"4F",x"D7",x"38",x"FD",x"CD",x"3D",x"1E",x"30",x"F8",x"11",
+x"52",x"26",x"D5",x"16",x"02",x"FE",x"25",x"C8",x"14",x"FE",x"24",x"C8",x"14",x"FE",
+x"21",x"C8",x"16",x"08",x"FE",x"23",x"C8",x"78",x"D6",x"41",x"E6",x"7F",x"5F",x"16",
+x"00",x"E5",x"21",x"01",x"41",x"19",x"56",x"E1",x"2B",x"C9",x"7A",x"32",x"AF",x"40",
+x"D7",x"3A",x"DC",x"40",x"B7",x"C2",x"64",x"26",x"7E",x"D6",x"28",x"CA",x"E9",x"26",
+x"AF",x"32",x"DC",x"40",x"E5",x"D5",x"2A",x"F9",x"40",x"EB",x"2A",x"FB",x"40",x"DF",
+x"E1",x"28",x"19",x"1A",x"6F",x"BC",x"13",x"20",x"0B",x"1A",x"B9",x"20",x"07",x"13",
+x"1A",x"B8",x"CA",x"CC",x"26",x"3E",x"13",x"13",x"E5",x"26",x"00",x"19",x"18",x"DF",
+x"7C",x"E1",x"E3",x"F5",x"D5",x"11",x"F1",x"24",x"DF",x"28",x"36",x"11",x"43",x"25",
+x"DF",x"D1",x"28",x"35",x"F1",x"E3",x"E5",x"C5",x"4F",x"06",x"00",x"C5",x"03",x"03",
+x"03",x"2A",x"FD",x"40",x"E5",x"09",x"C1",x"E5",x"CD",x"55",x"19",x"E1",x"22",x"FD",
+x"40",x"60",x"69",x"22",x"FB",x"40",x"2B",x"36",x"00",x"DF",x"20",x"FA",x"D1",x"73",
+x"23",x"D1",x"73",x"23",x"72",x"EB",x"13",x"E1",x"C9",x"57",x"5F",x"F1",x"F1",x"E3",
+x"C9",x"32",x"24",x"41",x"C1",x"67",x"6F",x"22",x"21",x"41",x"E7",x"20",x"06",x"21",
+x"28",x"19",x"22",x"21",x"41",x"E1",x"C9",x"E5",x"2A",x"AE",x"40",x"E3",x"57",x"D5",
+x"C5",x"CD",x"45",x"1E",x"C1",x"F1",x"EB",x"E3",x"E5",x"EB",x"3C",x"57",x"7E",x"FE",
+x"2C",x"28",x"EE",x"CF",x"29",x"22",x"F3",x"40",x"E1",x"22",x"AE",x"40",x"D5",x"2A",
+x"FB",x"40",x"3E",x"19",x"EB",x"2A",x"FD",x"40",x"EB",x"DF",x"3A",x"AF",x"40",x"28",
+x"27",x"BE",x"23",x"20",x"08",x"7E",x"B9",x"23",x"20",x"04",x"7E",x"B8",x"3E",x"23",
+x"23",x"5E",x"23",x"56",x"23",x"20",x"E0",x"3A",x"AE",x"40",x"B7",x"1E",x"12",x"C2",
+x"A2",x"19",x"F1",x"96",x"CA",x"95",x"27",x"1E",x"10",x"C3",x"A2",x"19",x"77",x"23",
+x"5F",x"16",x"00",x"F1",x"71",x"23",x"70",x"23",x"4F",x"CD",x"63",x"19",x"23",x"23",
+x"22",x"D8",x"40",x"71",x"23",x"3A",x"AE",x"40",x"17",x"79",x"01",x"0B",x"00",x"30",
+x"02",x"C1",x"03",x"71",x"23",x"70",x"23",x"F5",x"CD",x"AA",x"0B",x"F1",x"3D",x"20",
+x"ED",x"F5",x"42",x"4B",x"EB",x"19",x"38",x"C7",x"CD",x"6C",x"19",x"22",x"FD",x"40",
+x"2B",x"36",x"00",x"DF",x"20",x"FA",x"03",x"57",x"2A",x"D8",x"40",x"5E",x"EB",x"29",
+x"09",x"EB",x"2B",x"2B",x"73",x"23",x"72",x"23",x"F1",x"38",x"30",x"47",x"4F",x"7E",
+x"23",x"16",x"E1",x"5E",x"23",x"56",x"23",x"E3",x"F5",x"DF",x"D2",x"3D",x"27",x"CD",
+x"AA",x"0B",x"19",x"F1",x"3D",x"44",x"4D",x"20",x"EB",x"3A",x"AF",x"40",x"44",x"4D",
+x"29",x"D6",x"04",x"38",x"04",x"29",x"28",x"06",x"29",x"B7",x"E2",x"C2",x"27",x"09",
+x"C1",x"09",x"EB",x"2A",x"F3",x"40",x"C9",x"AF",x"E5",x"32",x"AF",x"40",x"CD",x"D4",
+x"27",x"E1",x"D7",x"C9",x"2A",x"FD",x"40",x"EB",x"21",x"00",x"00",x"39",x"E7",x"20",
+x"0D",x"CD",x"DA",x"29",x"CD",x"E6",x"28",x"2A",x"A0",x"40",x"EB",x"2A",x"D6",x"40",
+x"7D",x"93",x"6F",x"7C",x"9A",x"67",x"C3",x"66",x"0C",x"3A",x"A6",x"40",x"6F",x"AF",
+x"67",x"C3",x"9A",x"0A",x"CD",x"A9",x"41",x"D7",x"CD",x"2C",x"25",x"E5",x"21",x"90",
+x"08",x"E5",x"3A",x"AF",x"40",x"F5",x"FE",x"03",x"CC",x"DA",x"29",x"F1",x"EB",x"2A",
+x"8E",x"40",x"E9",x"E5",x"E6",x"07",x"21",x"A1",x"18",x"4F",x"06",x"00",x"09",x"CD",
+x"86",x"25",x"E1",x"C9",x"E5",x"2A",x"A2",x"40",x"23",x"7C",x"B5",x"E1",x"C0",x"1E",
+x"16",x"C3",x"A2",x"19",x"CD",x"BD",x"0F",x"CD",x"65",x"28",x"CD",x"DA",x"29",x"01",
+x"2B",x"2A",x"C5",x"7E",x"23",x"E5",x"CD",x"BF",x"28",x"E1",x"4E",x"23",x"46",x"CD",
+x"5A",x"28",x"E5",x"6F",x"CD",x"CE",x"29",x"D1",x"C9",x"CD",x"BF",x"28",x"21",x"D3",
+x"40",x"E5",x"77",x"23",x"73",x"23",x"72",x"E1",x"C9",x"2B",x"06",x"22",x"50",x"E5",
+x"0E",x"FF",x"23",x"7E",x"0C",x"B7",x"28",x"06",x"BA",x"28",x"03",x"B8",x"20",x"F4",
+x"FE",x"22",x"CC",x"78",x"1D",x"E3",x"23",x"EB",x"79",x"CD",x"5A",x"28",x"11",x"D3",
+x"40",x"3E",x"D5",x"2A",x"B3",x"40",x"22",x"21",x"41",x"3E",x"03",x"32",x"AF",x"40",
+x"CD",x"D3",x"09",x"11",x"D6",x"40",x"DF",x"22",x"B3",x"40",x"E1",x"7E",x"C0",x"1E",
+x"1E",x"C3",x"A2",x"19",x"23",x"CD",x"65",x"28",x"CD",x"DA",x"29",x"CD",x"C4",x"09",
+x"14",x"15",x"C8",x"0A",x"CD",x"2A",x"03",x"FE",x"0D",x"CC",x"03",x"21",x"03",x"18",
+x"F2",x"B7",x"0E",x"F1",x"F5",x"2A",x"A0",x"40",x"EB",x"2A",x"D6",x"40",x"2F",x"4F",
+x"06",x"FF",x"09",x"23",x"DF",x"38",x"07",x"22",x"D6",x"40",x"23",x"EB",x"F1",x"C9",
+x"F1",x"1E",x"1A",x"CA",x"A2",x"19",x"BF",x"F5",x"01",x"C1",x"28",x"C5",x"2A",x"B1",
+x"40",x"22",x"D6",x"40",x"21",x"00",x"00",x"E5",x"2A",x"A0",x"40",x"E5",x"21",x"B5",
+x"40",x"EB",x"2A",x"B3",x"40",x"EB",x"DF",x"01",x"F7",x"28",x"C2",x"4A",x"29",x"2A",
+x"F9",x"40",x"EB",x"2A",x"FB",x"40",x"EB",x"DF",x"28",x"13",x"7E",x"23",x"23",x"23",
+x"FE",x"03",x"20",x"04",x"CD",x"4B",x"29",x"AF",x"5F",x"16",x"00",x"19",x"18",x"E6",
+x"C1",x"EB",x"2A",x"FD",x"40",x"EB",x"DF",x"CA",x"6B",x"29",x"7E",x"23",x"CD",x"C2",
+x"09",x"E5",x"09",x"FE",x"03",x"20",x"EB",x"22",x"D8",x"40",x"E1",x"4E",x"06",x"00",
+x"09",x"09",x"23",x"EB",x"2A",x"D8",x"40",x"EB",x"DF",x"28",x"DA",x"01",x"3F",x"29",
+x"C5",x"AF",x"B6",x"23",x"5E",x"23",x"56",x"23",x"C8",x"44",x"4D",x"2A",x"D6",x"40",
+x"DF",x"60",x"69",x"D8",x"E1",x"E3",x"DF",x"E3",x"E5",x"60",x"69",x"D0",x"C1",x"F1",
+x"F1",x"E5",x"D5",x"C5",x"C9",x"D1",x"E1",x"7D",x"B4",x"C8",x"2B",x"46",x"2B",x"4E",
+x"E5",x"2B",x"6E",x"26",x"00",x"09",x"50",x"59",x"2B",x"44",x"4D",x"2A",x"D6",x"40",
+x"CD",x"58",x"19",x"E1",x"71",x"23",x"70",x"69",x"60",x"2B",x"C3",x"E9",x"28",x"C5",
+x"E5",x"2A",x"21",x"41",x"E3",x"CD",x"9F",x"24",x"E3",x"CD",x"F4",x"0A",x"7E",x"E5",
+x"2A",x"21",x"41",x"E5",x"86",x"1E",x"1C",x"DA",x"A2",x"19",x"CD",x"57",x"28",x"D1",
+x"CD",x"DE",x"29",x"E3",x"CD",x"DD",x"29",x"E5",x"2A",x"D4",x"40",x"EB",x"CD",x"C6",
+x"29",x"CD",x"C6",x"29",x"21",x"49",x"23",x"E3",x"E5",x"C3",x"84",x"28",x"E1",x"E3",
+x"7E",x"23",x"4E",x"23",x"46",x"6F",x"2C",x"2D",x"C8",x"0A",x"12",x"03",x"13",x"18",
+x"F8",x"CD",x"F4",x"0A",x"2A",x"21",x"41",x"EB",x"CD",x"F5",x"29",x"EB",x"C0",x"D5",
+x"50",x"59",x"1B",x"4E",x"2A",x"D6",x"40",x"DF",x"20",x"05",x"47",x"09",x"22",x"D6",
+x"40",x"E1",x"C9",x"2A",x"B3",x"40",x"2B",x"46",x"2B",x"4E",x"2B",x"DF",x"C0",x"22",
+x"B3",x"40",x"C9",x"01",x"F8",x"27",x"C5",x"CD",x"D7",x"29",x"AF",x"57",x"7E",x"B7",
+x"C9",x"01",x"F8",x"27",x"C5",x"CD",x"07",x"2A",x"CA",x"4A",x"1E",x"23",x"5E",x"23",
+x"56",x"1A",x"C9",x"3E",x"01",x"CD",x"57",x"28",x"CD",x"1F",x"2B",x"2A",x"D4",x"40",
+x"73",x"C1",x"C3",x"84",x"28",x"D7",x"CF",x"28",x"CD",x"1C",x"2B",x"D5",x"CF",x"2C",
+x"CD",x"37",x"23",x"CF",x"29",x"E3",x"E5",x"E7",x"28",x"05",x"CD",x"1F",x"2B",x"18",
+x"03",x"CD",x"13",x"2A",x"D1",x"F5",x"F5",x"7B",x"CD",x"57",x"28",x"5F",x"F1",x"1C",
+x"1D",x"28",x"D4",x"2A",x"D4",x"40",x"77",x"23",x"1D",x"20",x"FB",x"18",x"CA",x"CD",
+x"DF",x"2A",x"AF",x"E3",x"4F",x"3E",x"E5",x"E5",x"7E",x"B8",x"38",x"02",x"78",x"11",
+x"0E",x"00",x"C5",x"CD",x"BF",x"28",x"C1",x"E1",x"E5",x"23",x"46",x"23",x"66",x"68",
+x"06",x"00",x"09",x"44",x"4D",x"CD",x"5A",x"28",x"6F",x"CD",x"CE",x"29",x"D1",x"CD",
+x"DE",x"29",x"C3",x"84",x"28",x"CD",x"DF",x"2A",x"D1",x"D5",x"1A",x"90",x"18",x"CB",
+x"EB",x"7E",x"CD",x"E2",x"2A",x"04",x"05",x"CA",x"4A",x"1E",x"C5",x"1E",x"FF",x"FE",
+x"29",x"28",x"05",x"CF",x"2C",x"CD",x"1C",x"2B",x"CF",x"29",x"F1",x"E3",x"01",x"69",
+x"2A",x"C5",x"3D",x"BE",x"06",x"00",x"D0",x"4F",x"7E",x"91",x"BB",x"47",x"D8",x"43",
+x"C9",x"CD",x"07",x"2A",x"CA",x"F8",x"27",x"5F",x"23",x"7E",x"23",x"66",x"6F",x"E5",
+x"19",x"46",x"72",x"E3",x"C5",x"7E",x"CD",x"65",x"0E",x"C1",x"E1",x"70",x"C9",x"EB",
+x"CF",x"29",x"C1",x"D1",x"C5",x"43",x"C9",x"FE",x"7A",x"C2",x"97",x"19",x"C3",x"D9",
+x"41",x"CD",x"1F",x"2B",x"32",x"94",x"40",x"CD",x"93",x"40",x"C3",x"F8",x"27",x"CD",
+x"0E",x"2B",x"C3",x"96",x"40",x"D7",x"CD",x"37",x"23",x"E5",x"CD",x"7F",x"0A",x"EB",
+x"E1",x"7A",x"B7",x"C9",x"CD",x"1C",x"2B",x"32",x"94",x"40",x"32",x"97",x"40",x"CF",
+x"2C",x"18",x"01",x"D7",x"CD",x"37",x"23",x"CD",x"05",x"2B",x"C2",x"4A",x"1E",x"2B",
+x"D7",x"7B",x"C9",x"3E",x"01",x"32",x"9C",x"40",x"C1",x"CD",x"10",x"1B",x"C5",x"21",
+x"FF",x"FF",x"22",x"A2",x"40",x"E1",x"D1",x"4E",x"23",x"46",x"23",x"78",x"B1",x"CA",
+x"19",x"1A",x"CD",x"DF",x"41",x"CD",x"9B",x"1D",x"C5",x"4E",x"23",x"46",x"23",x"C5",
+x"E3",x"EB",x"DF",x"C1",x"DA",x"18",x"1A",x"E3",x"E5",x"C5",x"EB",x"22",x"EC",x"40",
+x"CD",x"AF",x"0F",x"3E",x"20",x"E1",x"CD",x"2A",x"03",x"CD",x"7E",x"2B",x"2A",x"A7",
+x"40",x"CD",x"75",x"2B",x"CD",x"FE",x"20",x"18",x"BE",x"7E",x"B7",x"C8",x"CD",x"2A",
+x"03",x"23",x"18",x"F7",x"E5",x"2A",x"A7",x"40",x"44",x"4D",x"E1",x"16",x"FF",x"18",
+x"03",x"03",x"15",x"C8",x"7E",x"B7",x"23",x"02",x"C8",x"F2",x"89",x"2B",x"FE",x"FB",
+x"20",x"08",x"0B",x"0B",x"0B",x"0B",x"14",x"14",x"14",x"14",x"FE",x"95",x"CC",x"24",
+x"0B",x"D6",x"7F",x"E5",x"5F",x"21",x"50",x"16",x"7E",x"B7",x"23",x"F2",x"AC",x"2B",
+x"1D",x"20",x"F7",x"E6",x"7F",x"02",x"03",x"15",x"CA",x"D8",x"28",x"7E",x"23",x"B7",
+x"F2",x"B7",x"2B",x"E1",x"18",x"C6",x"CD",x"10",x"1B",x"D1",x"C5",x"C5",x"CD",x"2C",
+x"1B",x"30",x"05",x"54",x"5D",x"E3",x"E5",x"DF",x"D2",x"4A",x"1E",x"21",x"29",x"19",
+x"CD",x"A7",x"28",x"C1",x"21",x"E8",x"1A",x"E3",x"EB",x"2A",x"F9",x"40",x"1A",x"02",
+x"03",x"13",x"DF",x"20",x"F9",x"60",x"69",x"22",x"F9",x"40",x"C9",x"CD",x"84",x"02",
+x"CD",x"37",x"23",x"E5",x"CD",x"13",x"2A",x"3E",x"D3",x"CD",x"64",x"02",x"CD",x"61",
+x"02",x"1A",x"CD",x"64",x"02",x"2A",x"A4",x"40",x"EB",x"2A",x"F9",x"40",x"1A",x"13",
+x"CD",x"64",x"02",x"DF",x"20",x"F8",x"CD",x"F8",x"01",x"E1",x"C9",x"CD",x"93",x"02",
+x"7E",x"D6",x"B2",x"28",x"02",x"AF",x"01",x"2F",x"23",x"F5",x"2B",x"D7",x"3E",x"00",
+x"28",x"07",x"CD",x"37",x"23",x"CD",x"13",x"2A",x"1A",x"6F",x"F1",x"B7",x"67",x"22",
+x"21",x"41",x"CC",x"4D",x"1B",x"2A",x"21",x"41",x"EB",x"06",x"03",x"CD",x"35",x"02",
+x"D6",x"D3",x"20",x"F7",x"10",x"F7",x"CD",x"35",x"02",x"1C",x"1D",x"28",x"03",x"BB",
+x"20",x"37",x"2A",x"A4",x"40",x"06",x"03",x"CD",x"35",x"02",x"5F",x"96",x"A2",x"20",
+x"21",x"73",x"CD",x"6C",x"19",x"7E",x"B7",x"23",x"20",x"ED",x"CD",x"2C",x"02",x"10",
+x"EA",x"22",x"F9",x"40",x"21",x"29",x"19",x"CD",x"A7",x"28",x"CD",x"F8",x"01",x"2A",
+x"A4",x"40",x"E5",x"C3",x"E8",x"1A",x"21",x"A5",x"2C",x"CD",x"A7",x"28",x"C3",x"18",
+x"1A",x"32",x"3E",x"3C",x"06",x"03",x"CD",x"35",x"02",x"B7",x"20",x"F8",x"10",x"F8",
+x"CD",x"96",x"02",x"18",x"A2",x"42",x"41",x"44",x"0D",x"00",x"CD",x"7F",x"0A",x"7E",
+x"C3",x"F8",x"27",x"CD",x"02",x"2B",x"D5",x"CF",x"2C",x"CD",x"1C",x"2B",x"D1",x"12",
+x"C9",x"CD",x"38",x"23",x"CD",x"F4",x"0A",x"CF",x"3B",x"EB",x"2A",x"21",x"41",x"18",
+x"08",x"3A",x"DE",x"40",x"B7",x"28",x"0C",x"D1",x"EB",x"E5",x"AF",x"32",x"DE",x"40",
+x"BA",x"F5",x"D5",x"46",x"B0",x"CA",x"4A",x"1E",x"23",x"4E",x"23",x"66",x"69",x"18",
+x"1C",x"58",x"E5",x"0E",x"02",x"7E",x"23",x"FE",x"25",x"CA",x"17",x"2E",x"FE",x"20",
+x"20",x"03",x"0C",x"10",x"F2",x"E1",x"43",x"3E",x"25",x"CD",x"49",x"2E",x"CD",x"2A",
+x"03",x"AF",x"5F",x"57",x"CD",x"49",x"2E",x"57",x"7E",x"23",x"FE",x"21",x"CA",x"14",
+x"2E",x"FE",x"23",x"28",x"37",x"05",x"CA",x"FE",x"2D",x"FE",x"2B",x"3E",x"08",x"28",
+x"E7",x"2B",x"7E",x"23",x"FE",x"2E",x"28",x"40",x"FE",x"25",x"28",x"BD",x"BE",x"20",
+x"D0",x"FE",x"24",x"28",x"14",x"FE",x"2A",x"20",x"C8",x"78",x"FE",x"02",x"23",x"38",
+x"03",x"7E",x"FE",x"24",x"3E",x"20",x"20",x"07",x"05",x"1C",x"FE",x"AF",x"C6",x"10",
+x"23",x"1C",x"82",x"57",x"1C",x"0E",x"00",x"05",x"28",x"47",x"7E",x"23",x"FE",x"2E",
+x"28",x"18",x"FE",x"23",x"28",x"F0",x"FE",x"2C",x"20",x"1A",x"7A",x"F6",x"40",x"57",
+x"18",x"E6",x"7E",x"FE",x"23",x"3E",x"2E",x"20",x"90",x"0E",x"01",x"23",x"0C",x"05",
+x"28",x"25",x"7E",x"23",x"FE",x"23",x"28",x"F6",x"D5",x"11",x"97",x"2D",x"D5",x"54",
+x"5D",x"FE",x"5B",x"C0",x"BE",x"C0",x"23",x"BE",x"C0",x"23",x"BE",x"C0",x"23",x"78",
+x"D6",x"04",x"D8",x"D1",x"D1",x"47",x"14",x"23",x"CA",x"EB",x"D1",x"7A",x"2B",x"1C",
+x"E6",x"08",x"20",x"15",x"1D",x"78",x"B7",x"28",x"10",x"7E",x"D6",x"2D",x"28",x"06",
+x"FE",x"FE",x"20",x"07",x"3E",x"08",x"C6",x"04",x"82",x"57",x"05",x"E1",x"F1",x"28",
+x"50",x"C5",x"D5",x"CD",x"37",x"23",x"D1",x"C1",x"C5",x"E5",x"43",x"78",x"81",x"FE",
+x"19",x"D2",x"4A",x"1E",x"7A",x"F6",x"80",x"CD",x"BE",x"0F",x"CD",x"A7",x"28",x"E1",
+x"2B",x"D7",x"37",x"28",x"0D",x"32",x"DE",x"40",x"FE",x"3B",x"28",x"05",x"FE",x"2C",
+x"C2",x"97",x"19",x"D7",x"C1",x"EB",x"E1",x"E5",x"F5",x"D5",x"7E",x"90",x"23",x"4E",
+x"23",x"66",x"69",x"16",x"00",x"5F",x"19",x"78",x"B7",x"C2",x"03",x"2D",x"18",x"06",
+x"CD",x"49",x"2E",x"CD",x"2A",x"03",x"E1",x"F1",x"C2",x"CB",x"2C",x"DC",x"FE",x"20",
+x"E3",x"CD",x"DD",x"29",x"E1",x"C3",x"69",x"21",x"0E",x"01",x"3E",x"F1",x"05",x"CD",
+x"49",x"2E",x"E1",x"F1",x"28",x"E9",x"C5",x"CD",x"37",x"23",x"CD",x"F4",x"0A",x"C1",
+x"C5",x"E5",x"2A",x"21",x"41",x"41",x"0E",x"00",x"C5",x"CD",x"68",x"2A",x"CD",x"AA",
+x"28",x"2A",x"21",x"41",x"F1",x"96",x"47",x"3E",x"20",x"04",x"05",x"CA",x"D3",x"2D",
+x"CD",x"2A",x"03",x"18",x"F7",x"F5",x"7A",x"B7",x"3E",x"2B",x"C4",x"2A",x"03",x"F1",
+x"C9",x"32",x"9A",x"40",x"2A",x"EA",x"40",x"B4",x"A5",x"3C",x"EB",x"C8",x"18",x"04",
+x"CD",x"4F",x"1E",x"C0",x"E1",x"EB",x"22",x"EC",x"40",x"EB",x"CD",x"2C",x"1B",x"D2",
+x"D9",x"1E",x"60",x"69",x"23",x"23",x"4E",x"23",x"46",x"23",x"C5",x"CD",x"7E",x"2B",
+x"E1",x"E5",x"CD",x"AF",x"0F",x"3E",x"20",x"CD",x"2A",x"03",x"2A",x"A7",x"40",x"3E",
+x"0E",x"CD",x"2A",x"03",x"E5",x"0E",x"FF",x"0C",x"7E",x"B7",x"23",x"20",x"FA",x"E1",
+x"47",x"16",x"00",x"CD",x"84",x"03",x"D6",x"30",x"38",x"0E",x"FE",x"0A",x"30",x"0A",
+x"5F",x"7A",x"07",x"07",x"82",x"07",x"83",x"57",x"18",x"EB",x"E5",x"21",x"99",x"2E",
+x"E3",x"15",x"14",x"C2",x"BB",x"2E",x"14",x"FE",x"D8",x"CA",x"D2",x"2F",x"FE",x"DD",
+x"CA",x"E0",x"2F",x"FE",x"F0",x"28",x"41",x"FE",x"31",x"38",x"02",x"D6",x"20",x"FE",
+x"21",x"CA",x"F6",x"2F",x"FE",x"1C",x"CA",x"40",x"2F",x"FE",x"23",x"28",x"3F",x"FE",
+x"19",x"CA",x"7D",x"2F",x"FE",x"14",x"CA",x"4A",x"2F",x"FE",x"13",x"CA",x"65",x"2F",
+x"FE",x"15",x"CA",x"E3",x"2F",x"FE",x"28",x"CA",x"78",x"2F",x"FE",x"1B",x"28",x"1C",
+x"FE",x"18",x"CA",x"75",x"2F",x"FE",x"11",x"C0",x"C1",x"D1",x"CD",x"FE",x"20",x"C3",
+x"65",x"2E",x"7E",x"B7",x"C8",x"04",x"CD",x"2A",x"03",x"23",x"15",x"20",x"F5",x"C9",
+x"E5",x"21",x"5F",x"2F",x"E3",x"37",x"F5",x"CD",x"84",x"03",x"5F",x"F1",x"F5",x"DC",
+x"5F",x"2F",x"7E",x"B7",x"CA",x"3E",x"2F",x"CD",x"2A",x"03",x"F1",x"F5",x"DC",x"A1",
+x"2F",x"38",x"02",x"23",x"04",x"7E",x"BB",x"20",x"EB",x"15",x"20",x"E8",x"F1",x"C9",
+x"CD",x"75",x"2B",x"CD",x"FE",x"20",x"C1",x"C3",x"7C",x"2E",x"7E",x"B7",x"C8",x"3E",
+x"21",x"CD",x"2A",x"03",x"7E",x"B7",x"28",x"09",x"CD",x"2A",x"03",x"CD",x"A1",x"2F",
+x"15",x"20",x"F3",x"3E",x"21",x"CD",x"2A",x"03",x"C9",x"7E",x"B7",x"C8",x"CD",x"84",
+x"03",x"77",x"CD",x"2A",x"03",x"23",x"04",x"15",x"20",x"F1",x"C9",x"36",x"00",x"48",
+x"16",x"FF",x"CD",x"0A",x"2F",x"CD",x"84",x"03",x"B7",x"CA",x"7D",x"2F",x"FE",x"08",
+x"28",x"0A",x"FE",x"0D",x"CA",x"E0",x"2F",x"FE",x"1B",x"C8",x"20",x"1E",x"3E",x"08",
+x"05",x"04",x"28",x"1F",x"CD",x"2A",x"03",x"2B",x"05",x"11",x"7D",x"2F",x"D5",x"E5",
+x"0D",x"7E",x"B7",x"37",x"CA",x"90",x"08",x"23",x"7E",x"2B",x"77",x"23",x"18",x"F3",
+x"F5",x"79",x"FE",x"FF",x"38",x"03",x"F1",x"18",x"C4",x"90",x"0C",x"04",x"C5",x"EB",
+x"6F",x"26",x"00",x"19",x"44",x"4D",x"23",x"CD",x"58",x"19",x"C1",x"F1",x"77",x"CD",
+x"2A",x"03",x"23",x"C3",x"7D",x"2F",x"78",x"B7",x"C8",x"05",x"2B",x"3E",x"08",x"CD",
+x"2A",x"03",x"15",x"20",x"F3",x"C9",x"CD",x"75",x"2B",x"CD",x"FE",x"20",x"C1",x"D1",
+x"7A",x"A3",x"3C",x"2A",x"A7",x"40",x"2B",x"C8",x"37",x"23",x"F5",x"C3",x"98",x"1A",
+x"C1",x"D1",x"C3",x"19",x"1A",x"DE",x"C3",x"C3",x"44",x"B2",
+x"CD",x"5C",x"30",x"C3",x"21",x"30",x"21",x"47",x"31",x"18",x"07",x"CD",x"5C",x"30",
+x"3E",x"10",x"18",x"10",x"22",x"1E",x"40",x"21",x"D4",x"33",x"22",x"04",x"40",x"CD",
+x"61",x"1B",x"C3",x"19",x"1A",x"AF",x"FD",x"77",x"06",x"FD",x"E5",x"E1",x"06",x"05",
+x"AF",x"23",x"77",x"10",x"FC",x"21",x"40",x"30",x"CD",x"C9",x"01",x"CD",x"A7",x"28",
+x"21",x"78",x"30",x"22",x"16",x"40",x"18",x"C6",x"4E",x"45",x"57",x"20",x"4B",x"45",
+x"59",x"42",x"4F",x"41",x"52",x"44",x"20",x"52",x"4F",x"55",x"54",x"49",x"4E",x"45",
+x"20",x"45",x"4E",x"41",x"42",x"4C",x"45",x"00",x"2A",x"B1",x"40",x"11",x"FA",x"FF",
+x"19",x"22",x"B1",x"40",x"22",x"49",x"40",x"22",x"1B",x"40",x"11",x"CE",x"FF",x"19",
+x"22",x"A0",x"40",x"FD",x"2A",x"1B",x"40",x"C9",x"FD",x"E5",x"CD",x"80",x"30",x"FD",
+x"E1",x"C9",x"FD",x"2A",x"1B",x"40",x"21",x"36",x"40",x"01",x"80",x"38",x"0A",x"E6",
+x"01",x"28",x"14",x"0E",x"40",x"0A",x"E6",x"04",x"28",x"0D",x"0A",x"E6",x"04",x"20",
+x"FB",x"FD",x"7E",x"06",x"EE",x"10",x"FD",x"77",x"06",x"FD",x"7E",x"05",x"A7",x"28",
+x"08",x"5F",x"FD",x"4E",x"03",x"0A",x"A3",x"20",x"47",x"3A",x"22",x"40",x"A7",x"28",
+x"13",x"FD",x"7E",x"06",x"A7",x"20",x"0D",x"FD",x"34",x"02",x"20",x"08",x"ED",x"5B",
+x"20",x"40",x"1A",x"EE",x"D0",x"12",x"AF",x"FD",x"77",x"05",x"0E",x"01",x"16",x"00",
+x"0A",x"5F",x"AE",x"73",x"A3",x"20",x"08",x"14",x"2C",x"CB",x"01",x"F2",x"D2",x"30",
+x"C9",x"5F",x"C5",x"01",x"00",x"06",x"CD",x"60",x"00",x"C1",x"0A",x"A3",x"C8",x"FD",
+x"77",x"05",x"FD",x"71",x"03",x"FD",x"70",x"04",x"18",x"6D",x"FD",x"7E",x"04",x"A7",
+x"20",x"0E",x"C5",x"01",x"00",x"0A",x"CD",x"60",x"00",x"C1",x"0A",x"A3",x"28",x"C0",
+x"18",x"28",x"21",x"00",x"4C",x"E5",x"C5",x"21",x"36",x"40",x"0E",x"01",x"0A",x"5F",
+x"AE",x"A3",x"20",x"23",x"2C",x"CB",x"01",x"F2",x"16",x"31",x"C1",x"FD",x"5E",x"05",
+x"0A",x"A3",x"28",x"16",x"E1",x"2B",x"CB",x"74",x"20",x"DF",x"AF",x"FD",x"77",x"04",
+x"16",x"00",x"CB",x"41",x"20",x"2B",x"CB",x"19",x"14",x"18",x"F7",x"C1",x"E1",x"21",
+x"36",x"40",x"C3",x"CA",x"30",x"DD",x"6E",x"03",x"DD",x"66",x"04",x"DA",x"9A",x"04",
+x"DD",x"7E",x"05",x"B7",x"28",x"01",x"77",x"79",x"FE",x"20",x"DA",x"06",x"05",x"FE",
+x"80",x"D2",x"A6",x"04",x"C3",x"7D",x"04",x"E5",x"21",x"6D",x"31",x"E3",x"C3",x"FB",
+x"03",x"FE",x"10",x"28",x"01",x"C9",x"DB",x"FD",x"E6",x"F0",x"FE",x"30",x"20",x"2A",
+x"21",x"00",x"3C",x"7D",x"E6",x"3F",x"3E",x"0D",x"CC",x"3B",x"00",x"7E",x"CB",x"7F",
+x"28",x"02",x"E6",x"BF",x"CB",x"74",x"23",x"20",x"05",x"CD",x"3B",x"00",x"18",x"E7",
+x"06",x"06",x"3E",x"20",x"CD",x"3B",x"00",x"3E",x"0D",x"CD",x"3B",x"00",x"10",x"F4",
+x"AF",x"C9",x"E3",x"22",x"FE",x"41",x"E3",x"ED",x"73",x"FC",x"41",x"31",x"FC",x"41",
+x"08",x"D9",x"E5",x"D5",x"C5",x"F5",x"08",x"D9",x"E5",x"D5",x"C5",x"F5",x"DD",x"E5",
+x"FD",x"E5",x"ED",x"7B",x"FC",x"41",x"CD",x"C9",x"01",x"CD",x"34",x"32",x"CD",x"49",
+x"00",x"CD",x"3A",x"03",x"FE",x"44",x"28",x"19",x"FE",x"4D",x"28",x"4D",x"FE",x"52",
+x"28",x"4E",x"FE",x"42",x"20",x"06",x"CD",x"61",x"1B",x"C3",x"19",x"1A",x"FE",x"47",
+x"CC",x"EB",x"32",x"18",x"D7",x"CD",x"92",x"33",x"FE",x"58",x"28",x"D0",x"CD",x"C9",
+x"01",x"CD",x"69",x"32",x"3E",x"3E",x"CD",x"3A",x"03",x"06",x"10",x"7E",x"CD",x"73",
+x"33",x"3E",x"20",x"CD",x"3A",x"03",x"23",x"10",x"F4",x"3E",x"0D",x"CD",x"3A",x"03",
+x"CD",x"49",x"00",x"FE",x"0A",x"28",x"DE",x"FE",x"5B",x"20",x"A7",x"11",x"20",x"00",
+x"B7",x"ED",x"52",x"18",x"D2",x"CD",x"72",x"32",x"18",x"9A",x"CD",x"C9",x"01",x"CD",
+x"BD",x"32",x"18",x"92",x"FD",x"21",x"E8",x"41",x"21",x"98",x"32",x"06",x"0C",x"C5",
+x"CD",x"4E",x"32",x"3E",x"0D",x"CD",x"3A",x"03",x"C1",x"FD",x"23",x"FD",x"23",x"10",
+x"F0",x"C9",x"06",x"03",x"7E",x"CD",x"3A",x"03",x"23",x"10",x"F9",x"3E",x"3D",x"CD",
+x"3A",x"03",x"FD",x"7E",x"01",x"CD",x"73",x"33",x"FD",x"7E",x"00",x"CD",x"73",x"33",
+x"C9",x"7C",x"CD",x"73",x"33",x"7D",x"CD",x"73",x"33",x"C9",x"CD",x"92",x"33",x"FE",
+x"58",x"C8",x"CD",x"C9",x"01",x"CD",x"69",x"32",x"3E",x"3E",x"CD",x"3A",x"03",x"7E",
+x"CD",x"73",x"33",x"3E",x"2D",x"CD",x"3A",x"03",x"CD",x"9B",x"33",x"70",x"3E",x"0D",
+x"CD",x"3A",x"03",x"23",x"18",x"E3",x"49",x"59",x"20",x"49",x"58",x"20",x"41",x"46",
+x"20",x"42",x"43",x"20",x"44",x"45",x"20",x"48",x"4C",x"20",x"41",x"46",x"27",x"42",
+x"43",x"27",x"44",x"45",x"27",x"48",x"4C",x"27",x"53",x"50",x"20",x"50",x"43",x"20",
+x"00",x"21",x"98",x"32",x"FD",x"21",x"E8",x"41",x"06",x"0C",x"C5",x"CD",x"4E",x"32",
+x"3E",x"2F",x"CD",x"3A",x"03",x"E5",x"CD",x"92",x"33",x"FE",x"58",x"28",x"06",x"FD",
+x"75",x"00",x"FD",x"74",x"01",x"FD",x"23",x"FD",x"23",x"E1",x"3E",x"0D",x"CD",x"3A",
+x"03",x"C1",x"10",x"DC",x"C9",x"CD",x"9B",x"33",x"60",x"CD",x"9B",x"33",x"68",x"22",
+x"FE",x"41",x"CD",x"49",x"00",x"FE",x"2C",x"28",x"09",x"FE",x"0D",x"28",x"22",x"FE",
+x"58",x"C8",x"18",x"F0",x"CD",x"3A",x"03",x"CD",x"92",x"33",x"FE",x"58",x"C8",x"E5",
+x"11",x"00",x"42",x"01",x"03",x"00",x"ED",x"B0",x"E1",x"11",x"47",x"33",x"3E",x"CD",
+x"77",x"23",x"73",x"23",x"72",x"ED",x"7B",x"FC",x"41",x"2A",x"FE",x"41",x"E5",x"ED",
+x"73",x"FC",x"41",x"31",x"E8",x"41",x"FD",x"E1",x"DD",x"E1",x"F1",x"C1",x"D1",x"E1",
+x"08",x"D9",x"F1",x"C1",x"D1",x"E1",x"08",x"D9",x"ED",x"7B",x"FC",x"41",x"C9",x"E3",
+x"2B",x"2B",x"2B",x"22",x"FE",x"41",x"32",x"03",x"42",x"ED",x"53",x"04",x"42",x"78",
+x"32",x"06",x"42",x"11",x"00",x"42",x"EB",x"01",x"03",x"00",x"ED",x"B0",x"EB",x"ED",
+x"5B",x"04",x"42",x"3A",x"06",x"42",x"47",x"3A",x"03",x"42",x"21",x"AB",x"31",x"E3",
+x"C9",x"4F",x"CB",x"3F",x"CB",x"3F",x"CB",x"3F",x"CB",x"3F",x"CD",x"86",x"33",x"79",
+x"E6",x"0F",x"CD",x"86",x"33",x"C9",x"C6",x"30",x"FE",x"3A",x"38",x"02",x"C6",x"07",
+x"CD",x"3A",x"03",x"C9",x"CD",x"9B",x"33",x"60",x"CD",x"9B",x"33",x"68",x"C9",x"CD",
+x"B5",x"33",x"CB",x"27",x"CB",x"27",x"CB",x"27",x"CB",x"27",x"47",x"79",x"CD",x"3A",
+x"03",x"CD",x"B5",x"33",x"80",x"47",x"79",x"CD",x"3A",x"03",x"C9",x"CD",x"49",x"00",
+x"FE",x"58",x"20",x"05",x"E3",x"E1",x"E3",x"E1",x"C9",x"4F",x"D6",x"30",x"38",x"EF",
+x"FE",x"0A",x"D8",x"D6",x"11",x"38",x"E8",x"C6",x"0A",x"FE",x"10",x"D8",x"18",x"E1",
+x"E3",x"3E",x"1D",x"BC",x"20",x"03",x"3E",x"5B",x"BD",x"E3",x"C2",x"78",x"1D",x"CD",
+x"78",x"1D",x"F5",x"E5",x"FE",x"52",x"20",x"07",x"23",x"7E",x"FE",x"45",x"CA",x"6D",
+x"34",x"E1",x"F1",x"C9",x"D5",x"22",x"21",x"41",x"01",x"00",x"00",x"2A",x"A7",x"40",
+x"E5",x"CD",x"2F",x"13",x"E1",x"06",x"05",x"7E",x"D6",x"30",x"20",x"05",x"23",x"10",
+x"F8",x"2B",x"04",x"D1",x"C9",x"FD",x"23",x"FD",x"23",x"FD",x"23",x"FD",x"23",x"C9",
+x"23",x"7E",x"B7",x"C8",x"FE",x"8D",x"28",x"0C",x"FE",x"91",x"28",x"08",x"FE",x"CA",
+x"28",x"04",x"FE",x"95",x"20",x"EC",x"A7",x"C9",x"ED",x"5B",x"A7",x"40",x"D5",x"06",
+x"00",x"7E",x"FE",x"20",x"28",x"0B",x"FE",x"30",x"38",x"0A",x"FE",x"3A",x"30",x"06",
+x"04",x"12",x"13",x"23",x"18",x"ED",x"AF",x"12",x"D1",x"04",x"05",x"C9",x"C5",x"78",
+x"99",x"28",x"10",x"05",x"28",x"08",x"0D",x"20",x"F6",x"CD",x"CD",x"35",x"18",x"05",
+x"41",x"05",x"CD",x"AC",x"35",x"C1",x"1A",x"77",x"13",x"23",x"10",x"FA",x"C9",x"23",
+x"11",x"0A",x"00",x"ED",x"53",x"E2",x"40",x"ED",x"53",x"E4",x"40",x"7E",x"A7",x"28",
+x"22",x"FE",x"2C",x"28",x"11",x"CD",x"5A",x"1E",x"4F",x"7A",x"B3",x"28",x"13",x"79",
+x"ED",x"53",x"E2",x"40",x"FE",x"2C",x"20",x"0D",x"23",x"CD",x"5A",x"1E",x"ED",x"53",
+x"E4",x"40",x"7A",x"B3",x"CA",x"97",x"19",x"FD",x"2A",x"F9",x"40",x"11",x"00",x"01",
+x"FD",x"19",x"FD",x"E5",x"2A",x"A4",x"40",x"E5",x"7E",x"23",x"B6",x"CA",x"FE",x"34",
+x"23",x"23",x"CD",x"1A",x"34",x"23",x"28",x"F2",x"CD",x"30",x"34",x"2B",x"28",x"F4",
+x"23",x"E5",x"D5",x"FD",x"E5",x"D1",x"2A",x"B1",x"40",x"ED",x"52",x"DA",x"7A",x"19",
+x"11",x"04",x"00",x"ED",x"52",x"DA",x"7A",x"19",x"FD",x"70",x"00",x"E1",x"CD",x"5A",
+x"1E",x"FD",x"73",x"01",x"FD",x"72",x"02",x"FD",x"36",x"03",x"00",x"CD",x"11",x"34",
+x"E1",x"2B",x"23",x"7E",x"FE",x"20",x"28",x"FA",x"FE",x"2C",x"28",x"03",x"2B",x"18",
+x"BB",x"23",x"18",x"BE",x"FD",x"36",x"00",x"FF",x"E1",x"FD",x"E1",x"ED",x"5B",x"E2",
+x"40",x"D5",x"FD",x"E5",x"E5",x"D5",x"CD",x"C2",x"09",x"7A",x"B3",x"28",x"41",x"EB",
+x"D1",x"FD",x"E5",x"FD",x"7E",x"00",x"3C",x"28",x"21",x"FD",x"7E",x"03",x"B7",x"20",
+x"16",x"FD",x"7E",x"01",x"B9",x"20",x"10",x"FD",x"7E",x"02",x"B8",x"20",x"0A",x"FD",
+x"73",x"01",x"FD",x"72",x"02",x"FD",x"36",x"03",x"01",x"CD",x"11",x"34",x"18",x"D9",
+x"FD",x"E1",x"E5",x"2A",x"E4",x"40",x"19",x"DA",x"7A",x"19",x"EB",x"21",x"F8",x"FF",
+x"ED",x"52",x"DA",x"7A",x"19",x"E1",x"18",x"B7",x"D1",x"E1",x"FD",x"E1",x"D1",x"7E",
+x"23",x"B6",x"CA",x"83",x"2C",x"23",x"73",x"23",x"72",x"CD",x"1A",x"34",x"23",x"20",
+x"09",x"E5",x"2A",x"E4",x"40",x"19",x"EB",x"E1",x"18",x"E7",x"E5",x"D5",x"CD",x"30",
+x"34",x"D1",x"E1",x"2B",x"28",x"E7",x"23",x"7E",x"FE",x"20",x"28",x"FA",x"D5",x"E5",
+x"FD",x"6E",x"01",x"FD",x"66",x"02",x"CD",x"F4",x"33",x"FD",x"4E",x"00",x"CD",x"11",
+x"34",x"EB",x"E1",x"CD",x"50",x"34",x"D1",x"2B",x"23",x"7E",x"FE",x"20",x"28",x"FA",
+x"FE",x"2C",x"28",x"03",x"2B",x"18",x"BC",x"23",x"18",x"C8",x"D5",x"C5",x"E5",x"E5",
+x"D1",x"D5",x"D5",x"2A",x"F9",x"40",x"E5",x"2B",x"13",x"10",x"FC",x"22",x"F9",x"40",
+x"E1",x"C1",x"ED",x"42",x"23",x"E5",x"C1",x"E1",x"EB",x"ED",x"B0",x"E1",x"C1",x"D1",
+x"C9",x"D5",x"C5",x"E5",x"2A",x"F9",x"40",x"E5",x"D1",x"23",x"10",x"FD",x"22",x"F9",
+x"40",x"C1",x"C5",x"E5",x"B7",x"ED",x"42",x"E5",x"C1",x"03",x"E1",x"EB",x"ED",x"B8",
+x"E1",x"C1",x"D1",x"C9",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",x"FF",
+x"FF",x"FF",x"FF",x"FF",
+
+others => x"ff"
+ );
+
+signal do : std_logic_vector(7 downto 0);
+
+begin
+
+ process(CLK)
+ begin
+ if rising_edge(CLK) then
+ do <= myROM(conv_integer(A));
+ end if;
+ end process;
+ DOUT <= do;
+
+end Behavioral;
diff --git a/cores/ht1080z/sdram.v b/cores/ht1080z/sdram.v
new file mode 100644
index 0000000..0bbf4a7
--- /dev/null
+++ b/cores/ht1080z/sdram.v
@@ -0,0 +1,157 @@
+//
+// sdram.v
+//
+// sdram controller implementation for the MiST board
+// http://code.google.com/p/mist-board/
+//
+// Copyright (c) 2013 Till Harbaum
+//
+// This source file is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This source file is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+
+module sdram (
+
+ // interface to the MT48LC16M16 chip
+ inout reg [15:0] sd_data, // 16 bit bidirectional data bus
+ output reg [12:0] sd_addr, // 13 bit multiplexed address bus
+ output [1:0] sd_dqm, // two byte masks
+ output [1:0] sd_ba, // two banks
+ output sd_cs, // a single chip select
+ output sd_we, // write enable
+ output sd_ras, // row address select
+ output sd_cas, // columns address select
+
+ // cpu/chipset interface
+ input init, // init signal after FPGA config to initialize RAM
+ input clk, // sdram is accessed at up to 128MHz
+ input clkref, // reference clock to sync to
+
+ input [7:0] din, // data input from chipset/cpu
+ output reg [7:0] dout, // data output to chipset/cpu
+ input [24:0] addr, // 25 bit byte address
+ input oe, // cpu/chipset requests read
+ input we // cpu/chipset requests write
+);
+
+// no burst configured
+localparam RASCAS_DELAY = 3'd2; // tRCD>=20ns -> 2 cycles@64MHz
+localparam BURST_LENGTH = 3'b000; // 000=none, 001=2, 010=4, 011=8
+localparam ACCESS_TYPE = 1'b0; // 0=sequential, 1=interleaved
+localparam CAS_LATENCY = 3'd2; // 2/3 allowed
+localparam OP_MODE = 2'b00; // only 00 (standard operation) allowed
+localparam NO_WRITE_BURST = 1'b1; // 0= write burst enabled, 1=only single access write
+
+localparam MODE = { 3'b000, NO_WRITE_BURST, OP_MODE, CAS_LATENCY, ACCESS_TYPE, BURST_LENGTH};
+
+// ---------------------------------------------------------------------
+// ------------------------ cycle state machine ------------------------
+// ---------------------------------------------------------------------
+
+localparam STATE_IDLE = 3'd0; // first state in cycle
+localparam STATE_CMD_START = 3'd1; // state in which a new command can be started
+localparam STATE_CMD_CONT = STATE_CMD_START + RASCAS_DELAY - 3'd1; // 4 command can be continued
+localparam STATE_DATA = STATE_CMD_CONT + CAS_LATENCY;
+localparam STATE_LAST = 3'd7; // last state in cycle
+
+reg [2:0] q /* synthesis noprune */;
+always @(posedge clk) begin
+ // 32Mhz counter synchronous to 4 Mhz clock
+ // force counter to pass state 5->6 exactly after the rising edge of clkref
+ // since clkref is two clocks early
+ if(((q == 6) && ( clkref == 0)) ||
+ ((q == 7) && ( clkref == 1)) ||
+ ((q != 6) && (q != 7)))
+ q <= q + 3'd1;
+end
+
+// ---------------------------------------------------------------------
+// --------------------------- startup/reset ---------------------------
+// ---------------------------------------------------------------------
+
+// wait 1ms (32 clkref cycles) after FPGA config is done before going
+// into normal operation. Initialize the ram in the last 16 reset cycles (cycles 15-0)
+reg [4:0] reset;
+always @(posedge clk) begin
+ if(init) reset <= 5'h1f;
+ else if((q == STATE_LAST) && (reset != 0))
+ reset <= reset - 5'd1;
+end
+
+// ---------------------------------------------------------------------
+// ------------------ generate ram control signals ---------------------
+// ---------------------------------------------------------------------
+
+// all possible commands
+localparam CMD_INHIBIT = 4'b1111;
+localparam CMD_NOP = 4'b0111;
+localparam CMD_ACTIVE = 4'b0011;
+localparam CMD_READ = 4'b0101;
+localparam CMD_WRITE = 4'b0100;
+localparam CMD_BURST_TERMINATE = 4'b0110;
+localparam CMD_PRECHARGE = 4'b0010;
+localparam CMD_AUTO_REFRESH = 4'b0001;
+localparam CMD_LOAD_MODE = 4'b0000;
+
+reg [3:0] sd_cmd; // current command sent to sd ram
+
+// drive control signals according to current command
+assign sd_cs = sd_cmd[3];
+assign sd_ras = sd_cmd[2];
+assign sd_cas = sd_cmd[1];
+assign sd_we = sd_cmd[0];
+
+always @(posedge clk) begin
+ sd_cmd <= CMD_INHIBIT;
+ sd_data <= 16'bZZZZZZZZZZZZZZZZ;
+
+ if(reset != 0) begin
+ if(q == STATE_IDLE) begin
+ sd_addr <= MODE;
+ if(reset == 13) begin
+ sd_addr <= 13'b0010000000000;
+ sd_cmd <= CMD_PRECHARGE;
+ end
+ if(reset == 2) sd_cmd <= CMD_LOAD_MODE;
+ end
+ end else begin
+ case (q)
+ STATE_IDLE:
+ begin
+ if(we || oe) begin
+ sd_cmd <= CMD_ACTIVE;
+ sd_addr <= addr[20:8];
+ end
+ else sd_cmd <= CMD_AUTO_REFRESH;
+ end
+
+ STATE_CMD_CONT:
+ begin
+ if(we || oe) sd_addr <= { 4'b0010, addr[23], addr[7:0]};
+ if(we) begin
+ sd_cmd <= CMD_WRITE;
+ sd_data <= {din, din};
+ end
+ else if(oe) sd_cmd <= CMD_READ;
+ end
+
+ STATE_DATA: if(oe) dout <= sd_data[7:0];
+ endcase
+ end
+end
+
+assign sd_ba = addr[22:21];
+
+assign sd_dqm = 2'b00;
+
+endmodule
diff --git a/cores/ht1080z/t80/T80.qip b/cores/ht1080z/t80/T80.qip
new file mode 100644
index 0000000..df5c769
--- /dev/null
+++ b/cores/ht1080z/t80/T80.qip
@@ -0,0 +1,6 @@
+set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) T80s.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) 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 ]
diff --git a/cores/ht1080z/t80/T80.vhd b/cores/ht1080z/t80/T80.vhd
new file mode 100644
index 0000000..495e1d6
--- /dev/null
+++ b/cores/ht1080z/t80/T80.vhd
@@ -0,0 +1,1175 @@
+--------------------------------------------------------------------------------
+-- ****
+-- 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 : 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
+-- 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
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+use IEEE.STD_LOGIC_UNSIGNED.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;
+ 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
+
+ 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";
+
+ -- 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 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 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;
+ signal BusAck : std_logic;
+ 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 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 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 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 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 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 : work.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,
+ 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,
+ Special_LD => Special_LD,
+ ExchangeDH => ExchangeDH,
+ ExchangeRp => ExchangeRp,
+ ExchangeAF => ExchangeAF,
+ ExchangeRS => ExchangeRS,
+ 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,
+ SetWZ => SetWZ,
+ SetDI => SetDI,
+ SetEI => SetEI,
+ IMode => IMode,
+ Halt => Halt,
+ NoRead => NoRead,
+ Write => Write,
+ XYbit_undoc => XYbit_undoc);
+
+ alu : work.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,
+ 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);
+ 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');
+ 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 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;
+
+ 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 MCycle = "011" 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 =>
+ A <= std_logic_vector(PC);
+ 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 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;
+
+ 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 x"7") 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 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" =>
+ F <= Save_Mux;
+ when others =>
+ end case;
+ if XYbit_undoc='1' then
+ DO <= ALU_Q;
+ end if;
+ 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' 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,
+ ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
+ 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 ExchangeDH = '1' and (TState = 3 or 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;
+
+ process (Save_Mux, RegBusB, RegBusA_r, ID16,
+ ExchangeDH, IncDec_16, MCycle, TState, Wait_n)
+ begin
+ RegDIH <= Save_Mux;
+ RegDIL <= Save_Mux;
+
+ 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 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 : work.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;
+ 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' then
+ Halt_FF <= '1';
+ end if;
+ if BusReq_s = '1' then
+ BusAck <= '1';
+ else
+ TState <= "001";
+ 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';
+ 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/cores/ht1080z/t80/T80_ALU.vhd b/cores/ht1080z/t80/T80_ALU.vhd
new file mode 100644
index 0000000..a9438ae
--- /dev/null
+++ b/cores/ht1080z/t80/T80_ALU.vhd
@@ -0,0 +1,376 @@
+--------------------------------------------------------------------------------
+-- ****
+-- 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);
+ 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, 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
+ 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;
+ 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;
+ when others =>
+ null;
+ end case;
+ Q <= Q_t;
+ end process;
+end;
diff --git a/cores/ht1080z/t80/T80_MCode.vhd b/cores/ht1080z/t80/T80_MCode.vhd
new file mode 100644
index 0000000..f5312bd
--- /dev/null
+++ b/cores/ht1080z/t80/T80_MCode.vhd
@@ -0,0 +1,2035 @@
+--------------------------------------------------------------------------------
+-- ****
+-- 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 : 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
+-- 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
+--
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.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;
+ 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;
+ 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;
+ 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;
+ 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;
+ XYbit_undoc : out std_logic
+ );
+end T80_MCode;
+
+architecture rtl of T80_MCode 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";
+
+ 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_S) = '0'; -- NZ
+ when "001" => return F(Flag_S) = '1'; -- Z
+ when "010" => return F(Flag_H) = '0'; -- NC
+ when "011" => return F(Flag_H) = '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)
+ 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';
+ 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';
+ Special_LD <= "000";
+ ExchangeDH <= '0';
+ ExchangeRp <= '0';
+ ExchangeAF <= '0';
+ ExchangeRS <= '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';
+ SetDI <= '0';
+ SetEI <= '0';
+ IMode <= "11";
+ Halt <= '0';
+ NoRead <= '0';
+ Write <= '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
+ TStates <= "110";
+ LDSPHL <= '1';
+ when "11000101"|"11010101"|"11100101"|"11110101" =>
+ -- PUSH qq
+ 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;
+ 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 <= "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";
+ 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 =>
+ Read_To_Reg <= '1';
+ Set_BusA_To <= "0101";
+ Set_BusB_To <= "0101";
+ Set_Addr_To <= aSP;
+ LDZ <= '1';
+ when 3 =>
+ IncDec_16 <= "0111";
+ Set_Addr_To <= aSP;
+ TStates <= "100";
+ Write <= '1';
+ when 4 =>
+ Read_To_Reg <= '1';
+ Set_BusA_To <= "0100";
+ Set_BusB_To <= "0100";
+ Set_Addr_To <= aSP;
+ LDW <= '1';
+ when 5 =>
+ IncDec_16 <= "1111";
+ 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)
+ MCycles <= "101";
+ case to_integer(unsigned(MCycle)) is
+ when 1 =>
+ LDZ <= '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;
+ 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
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ 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";
+ 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;
+ when "00000011"|"00010011"|"00100011"|"00110011" =>
+ -- INC ss
+ TStates <= "110";
+ IncDec_16(3 downto 2) <= "01";
+ IncDec_16(1 downto 0) <= DPair;
+ when "00001011"|"00011011"|"00101011"|"00111011" =>
+ -- DEC ss
+ TStates <= "110";
+ IncDec_16(3 downto 2) <= "11";
+ IncDec_16(1 downto 0) <= DPair;
+
+-- 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';
+ Save_ALU <= '1';
+
+-- JUMP GROUP
+ when "11000011" =>
+ -- JP nn
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ Inc_PC <= '1';
+ Jump <= '1';
+ LDW <= '1';
+ 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";
+ when 2 =>
+ Write <= '1';
+ IORQ <= '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;
+ when 2 =>
+ Read_To_Acc <= '1';
+ IORQ <= '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
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ Inc_PC <= '1';
+ LDZ <= '1';
+ when 3 =>
+ LDW <= '1';
+ Inc_PC <= '1';
+ if is_cc_true(F, to_bitvector(IR(5 downto 3))) then
+ Jump <= '1';
+ 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';
+ 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";
+ 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";
+ 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";
+ 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";
+ 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
+ I_DJNZ <= '1';
+ 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';
+ when 3 =>
+ NoRead <= '1';
+ JumpE <= '1';
+ TStates <= "101";
+ when others => null;
+ end case;
+ end if;
+
+-- CALL AND RETURN GROUP
+ when "11001101" =>
+ -- CALL nn
+ MCycles <= "101";
+ 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
+ MCycles <= "101";
+ 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
+ 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;
+ 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 <= "011";
+ case to_integer(unsigned(MCycle)) is
+ when 2 =>
+ ALU_Op <= "0000";
+ Inc_PC <= '1';
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ Set_BusA_To <= "1000";
+ Set_BusB_To <= "0110";
+ when 3 =>
+ NoRead <= '1';
+ Read_To_Reg <= '1';
+ Save_ALU <= '1';
+ ALU_Op <= "0001";
+ Set_BusA_To <= "1001";
+ Set_BusB_To <= "1110"; -- Incorrect unsigned !!!!!!!!!!!!!!!!!!!!!
+ 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 -- Not correct !!!!!!!!!!!!!!!!!!!
+ 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 case;
+ else
+ -- RET cc
+ 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;
+ when "11000111"|"11001111"|"11010111"|"11011111"|"11100111"|"11101111"|"11110111"|"11111111" =>
+ -- RST p
+ 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;
+
+-- 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"|"11000001"|"11000010"|"11000011"|"11000100"|"11000101"|"11000110"|"11000111"
+ |"11001000"|"11001001"|"11001010"|"11001011"|"11001100"|"11001101"|"11001110"|"11001111"
+ |"11010000"|"11010001"|"11010010"|"11010011"|"11010100"|"11010101"|"11010110"|"11010111"
+ |"11011000"|"11011001"|"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"|"11110011"|"11110100"|"11110101"|"11110110"|"11110111"
+ |"11111000"|"11111001"|"11111010"|"11111011"|"11111100"|"11111101"|"11111110"|"11111111" =>
+ null; -- NOP, undocumented
+ when "01111110"|"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;
+ 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;
+ when 3 =>
+ NoRead <= '1';
+ I_BC <= '1';
+ TStates <= "101";
+ 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"|"01110111" =>
+ -- IM 2
+ IMode <= "10";
+-- 16 bit arithmetic
+ when "01001010"|"01011010"|"01101010"|"01111010" =>
+ -- ADC HL,ss
+ MCycles <= "011";
+ case to_integer(unsigned(MCycle)) is
+ 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";
+ 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 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";
+ 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';
+ 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';
+ 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;
+ 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;
+ 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/cores/ht1080z/t80/T80_Reg.vhd b/cores/ht1080z/t80/T80_Reg.vhd
new file mode 100644
index 0000000..e7e8645
--- /dev/null
+++ b/cores/ht1080z/t80/T80_Reg.vhd
@@ -0,0 +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;
diff --git a/cores/ht1080z/t80/T80pa.vhd b/cores/ht1080z/t80/T80pa.vhd
new file mode 100644
index 0000000..c09f15a
--- /dev/null
+++ b/cores/ht1080z/t80/T80pa.vhd
@@ -0,0 +1,216 @@
+--
+-- 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;
+
+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);
+ 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 A_int : std_logic_vector(15 downto 0);
+ signal A_last : std_logic_vector(15 downto 0);
+
+begin
+
+ A <= A_int when NoRead = '0' or Write = '1' else A_last;
+
+ BUSAK_n <= BUSAK;
+
+ u0 : work.T80
+ generic map(
+ Mode => Mode,
+ IOWait => 1
+ )
+ port map(
+ CEN => CEN_p and not CEN_pol,
+ 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_int,
+ 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,
+ 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);
+ A_last <= A_int;
+ 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';
+ A_last <= A_int;
+ 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/cores/ht1080z/t80/T80s.vhd b/cores/ht1080z/t80/T80s.vhd
new file mode 100644
index 0000000..db32691
--- /dev/null
+++ b/cores/ht1080z/t80/T80s.vhd
@@ -0,0 +1,191 @@
+--
+-- 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;
+
+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 : work.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 = "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/cores/ht1080z/videoctrl.vhd b/cores/ht1080z/videoctrl.vhd
new file mode 100644
index 0000000..e08a447
--- /dev/null
+++ b/cores/ht1080z/videoctrl.vhd
@@ -0,0 +1,649 @@
+--
+-- HT 1080Z (TSR-80 clone) video controller PAL/VGA capable
+--
+--
+-- Copyright (c) 2016-2017 Jozsef Laszlo (rbendr@gmail.com)
+--
+-- 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.STD_LOGIC_ARITH.ALL;
+use IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+entity videoctrl is
+ Generic (
+ H_START : integer := 42+84+81-16;
+ V_START : integer := 2+28+((266-192)/2)+4
+ );
+ Port (
+ reset : in STD_LOGIC;
+ clk42 : in STD_LOGIC;
+ --clk7 : in STD_LOGIC;
+ a : in STD_LOGIC_VECTOR (13 downto 0);
+ din : in STD_LOGIC_VECTOR (7 downto 0);
+ dout : out STD_LOGIC_VECTOR (7 downto 0);
+ mreq : in STD_LOGIC;
+ iorq : in STD_LOGIC;
+ wr : in STD_LOGIC;
+ cs : in STD_LOGIC;
+ hz60 : in STD_LOGIC;
+ vcut : in STD_LOGIC;
+ vvga : in STD_LOGIC;
+ page : in STD_LOGIC;
+ inkp : in STD_LOGIC;
+ paperp : in STD_LOGIC;
+ borderp : in STD_LOGIC;
+ oddline : out STD_LOGIC;
+ rgbi : out STD_LOGIC_VECTOR (3 downto 0);
+ pclk : out STD_LOGIC;
+ hsync : out STD_LOGIC;
+ vsync : out STD_LOGIC);
+end videoctrl;
+
+architecture Behavioral of videoctrl is
+
+type videomem is array(0 to 1023) of std_logic_vector(7 downto 0);
+
+type charmem is array(0 to 4095) of std_logic_vector(7 downto 0);
+
+signal vidmem : videomem:=(
+others => x"00"
+);
+
+signal chrmem : charmem:=(
+ --[PATCH_START]
+x"0e",x"11",x"15",x"17",x"16",x"10",x"0f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"0a",x"11",x"11",x"1f",x"11",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1e",x"09",x"09",x"0e",x"09",x"09",x"1e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"10",x"10",x"10",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1e",x"09",x"09",x"09",x"09",x"09",x"1e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1f",x"10",x"10",x"1e",x"10",x"10",x"1f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1f",x"10",x"10",x"1e",x"10",x"10",x"10",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0f",x"11",x"10",x"10",x"13",x"11",x"0f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"11",x"1f",x"11",x"11",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"04",x"04",x"04",x"04",x"04",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"01",x"01",x"01",x"01",x"01",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"12",x"14",x"18",x"14",x"12",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"10",x"10",x"10",x"10",x"10",x"10",x"1f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"1b",x"15",x"15",x"15",x"11",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"19",x"15",x"13",x"11",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"11",x"11",x"11",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1e",x"11",x"11",x"1e",x"10",x"10",x"10",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"11",x"11",x"15",x"12",x"0d",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1e",x"11",x"11",x"1e",x"14",x"12",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"10",x"0e",x"01",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1f",x"15",x"04",x"04",x"04",x"04",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"11",x"11",x"11",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"11",x"0a",x"0a",x"04",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"11",x"15",x"15",x"15",x"0a",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"0a",x"04",x"0a",x"11",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"0a",x"04",x"04",x"04",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1f",x"01",x"02",x"04",x"08",x"10",x"1f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"0e",x"15",x"04",x"04",x"04",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"10",x"08",x"04",x"02",x"01",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"04",x"04",x"04",x"15",x"0e",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"04",x"0a",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"00",x"00",x"1f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"04",x"04",x"04",x"04",x"00",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0a",x"0a",x"0a",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0a",x"0a",x"1f",x"0a",x"1f",x"0a",x"0a",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"0f",x"14",x"0e",x"05",x"1e",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"18",x"19",x"02",x"04",x"08",x"13",x"03",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"08",x"14",x"14",x"08",x"15",x"12",x"0d",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"04",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"08",x"10",x"10",x"10",x"08",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"02",x"01",x"01",x"01",x"02",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"15",x"0e",x"04",x"0e",x"15",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"04",x"04",x"1f",x"04",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"04",x"04",x"08",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"1f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"00",x"00",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"01",x"02",x"04",x"08",x"10",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"13",x"15",x"19",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"0c",x"04",x"04",x"04",x"04",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"01",x"0e",x"10",x"10",x"1f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1f",x"01",x"02",x"06",x"01",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"02",x"06",x"0a",x"1f",x"02",x"02",x"02",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1f",x"10",x"1e",x"01",x"01",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"07",x"08",x"10",x"1e",x"11",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1f",x"01",x"01",x"02",x"04",x"08",x"10",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"11",x"0e",x"11",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"11",x"0f",x"01",x"02",x"1c",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"04",x"00",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"04",x"00",x"04",x"04",x"08",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"02",x"04",x"08",x"10",x"08",x"04",x"02",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"1f",x"00",x"1f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"08",x"04",x"02",x"01",x"02",x"04",x"08",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"01",x"06",x"04",x"00",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"15",x"17",x"16",x"10",x"0f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"0a",x"11",x"11",x"1f",x"11",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1e",x"09",x"09",x"0e",x"09",x"09",x"1e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"10",x"10",x"10",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1e",x"09",x"09",x"09",x"09",x"09",x"1e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1f",x"10",x"10",x"1e",x"10",x"10",x"1f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1f",x"10",x"10",x"1e",x"10",x"10",x"10",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0f",x"11",x"10",x"10",x"13",x"11",x"0f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"11",x"1f",x"11",x"11",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"04",x"04",x"04",x"04",x"04",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"01",x"01",x"01",x"01",x"01",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"12",x"14",x"18",x"14",x"12",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"10",x"10",x"10",x"10",x"10",x"10",x"1f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"1b",x"15",x"15",x"15",x"11",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"19",x"15",x"13",x"11",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"11",x"11",x"11",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1e",x"11",x"11",x"1e",x"10",x"10",x"10",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"11",x"11",x"15",x"12",x"0d",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1e",x"11",x"11",x"1e",x"14",x"12",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0e",x"11",x"10",x"0e",x"01",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1f",x"15",x"04",x"04",x"04",x"04",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"11",x"11",x"11",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"11",x"0a",x"0a",x"04",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"11",x"15",x"15",x"15",x"0a",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"0a",x"04",x"0a",x"11",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"11",x"11",x"0a",x"04",x"04",x"04",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1f",x"01",x"02",x"04",x"08",x"10",x"1f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"1c",x"10",x"10",x"10",x"10",x"10",x"1c",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"10",x"08",x"04",x"02",x"01",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"07",x"01",x"01",x"01",x"01",x"01",x"07",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"0a",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"00",x"00",x"1f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"06",x"06",x"04",x"02",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"0e",x"01",x"0f",x"11",x"0f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"10",x"10",x"1e",x"11",x"11",x"11",x"1e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"0f",x"10",x"10",x"10",x"0f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"01",x"01",x"0f",x"11",x"11",x"11",x"0f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"0e",x"11",x"1f",x"10",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"02",x"04",x"04",x"0e",x"04",x"04",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"0f",x"11",x"11",x"11",x"0f",x"01",x"06",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"10",x"10",x"1e",x"11",x"11",x"11",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"00",x"0c",x"04",x"04",x"04",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"02",x"00",x"06",x"02",x"02",x"02",x"12",x"0c",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"08",x"08",x"09",x"0a",x"0c",x"0a",x"09",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0c",x"04",x"04",x"04",x"04",x"04",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"1a",x"15",x"15",x"15",x"15",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"1e",x"11",x"11",x"11",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"0e",x"11",x"11",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"1e",x"11",x"11",x"11",x"1e",x"10",x"10",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"0f",x"11",x"11",x"11",x"0f",x"01",x"01",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"0b",x"0c",x"08",x"08",x"08",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"0f",x"10",x"0e",x"01",x"1e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"04",x"0e",x"04",x"04",x"04",x"02",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"11",x"11",x"11",x"11",x"0e",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"11",x"11",x"11",x"0a",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"11",x"11",x"15",x"15",x"0a",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"11",x"0a",x"04",x"0a",x"11",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"11",x"11",x"11",x"11",x"0f",x"01",x"06",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"1f",x"02",x"04",x"08",x"1f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"02",x"04",x"04",x"08",x"04",x"04",x"02",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"04",x"04",x"04",x"00",x"04",x"04",x"04",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"08",x"04",x"04",x"02",x"04",x"04",x"08",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"08",x"15",x"02",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"0a",x"15",x"0a",x"15",x"0a",x"15",x"0a",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"00",x"00",x"00",x"00",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"38",x"38",x"38",x"38",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"07",x"07",x"07",x"07",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00",
+x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"3f",x"00",x"00",x"00",x"00"
+--[PATCH_END]
+ --others => x"ff"
+);
+
+-- 0 1 2
+-- 21 10.5 5.25
+signal clkdiv : std_logic_vector(2 downto 0);
+alias clk21 : std_logic is clkdiv(0);
+alias clk10_5 : std_logic is clkdiv(1);
+alias clk5_25 : std_logic is clkdiv(2);
+
+signal clk21_en : std_logic;
+signal clk10_5_en : std_logic;
+signal clk5_25_en : std_logic;
+
+signal hctr : std_logic_vector(9 downto 0);
+signal vctr : std_logic_vector(8 downto 0);
+signal vpos : std_logic_vector(3 downto 0); -- line pos in a chr 0..11
+signal hpos : std_logic_vector(2 downto 0); -- pixel pos in a chr 0..5
+signal hstart : std_logic_vector(9 downto 0);
+signal vstart : std_logic_vector(8 downto 0);
+signal vend : std_logic_vector(8 downto 0);
+
+signal pxclk : std_logic;
+signal pxclk_en : std_logic;
+signal xpxclk : std_logic;
+signal xpxclk_en : std_logic;
+
+signal hact,vact : std_logic;
+
+
+signal border : std_logic_vector(3 downto 0) := "0010";
+signal paper : std_logic_vector(3 downto 0) := "0000";
+signal ink : std_logic_vector(3 downto 0) := "1000";
+signal pixel : std_logic_vector(3 downto 0);
+
+signal screen : std_logic;
+signal hblank,vblank,blank : std_logic;
+
+signal vaVert : std_logic_vector(3 downto 0); -- vertical line
+signal vaHoriz : std_logic_vector(5 downto 0); -- horizontal columnt pos
+
+signal chraddr : std_logic_vector(11 downto 0); -- character bitmap data address in the charmem
+signal chrCode : std_logic_vector(7 downto 0);
+signal chrGrap : std_logic_vector(7 downto 0);
+signal shiftReg : std_logic_vector(7 downto 0);
+
+signal xpxsel : std_logic_vector(1 downto 0);
+signal v1 : std_logic;
+
+signal rinkp,rpaperp,rborderp : std_logic;
+
+begin
+
+--pxclk <= clk10_5;
+--xpxclk <= clk10_5 when vcut='0' else clk5_25;
+--hstart <= conv_std_logic_vector(H_START,10);
+--vstart <= conv_std_logic_vector(V_START,9);
+--vend <= conv_std_logic_vector(311,9);
+
+pxclk <= clk10_5 when vvga='0' else clk21;
+pxclk_en <= clk10_5_en when vvga='0' else clk21_en;
+xpxsel <= vvga & vcut;
+with xpxsel select xpxclk <=
+ clk10_5 when "00",
+ clk5_25 when "01",
+ clk21 when "10",
+ clk10_5 when others;
+
+with xpxsel select xpxclk_en <=
+ clk10_5_en when "00",
+ clk5_25_en when "01",
+ '1' when "10",
+ clk10_5_en when others;
+
+hstart <= conv_std_logic_vector(H_START,10) when vvga='0' else conv_std_logic_vector(H_START,10);
+vstart <= conv_std_logic_vector(V_START,9) when hz60='0' else conv_std_logic_vector(V_START-30,9);
+vend <= conv_std_logic_vector(311,9) when hz60='0' else conv_std_logic_vector(262,9);
+
+process(clk42)
+begin
+ if rising_edge(clk42) then
+ clkdiv <= clkdiv + 1;
+ end if;
+end process;
+
+clk10_5_en <= '1' when clkdiv(1 downto 0) = "01" else '0';
+clk21_en <= '1' when clkdiv(0) = '0' else '0';
+clk5_25_en <= '1' when clkdiv = "011" else '0';
+
+process(RESET,clk42)
+begin
+ if RESET='0' then
+ ink <= "1000";
+ paper <= "0000";
+ border <= "0000";
+ elsif rising_edge(clk42) then
+ if clk10_5_en = '1' then
+ rinkp <= INKP;
+ rpaperp <= PAPERP;
+ rborderp <= BORDERP;
+ if rinkp='0' and INKP='1' then
+ ink <= ink+1;
+ end if;
+ if rpaperp='0' and PAPERP='1' then
+ paper <= paper+1;
+ end if;
+ if rborderp='0' and BORDERP='1' then
+ border <= border+1;
+ end if;
+
+ if iorq='0' and wr='0' and a(7 downto 2)="000000" then
+ case a(1 downto 0) is
+ when "00"=> ink<=din(3 downto 0);
+ when "01"=> paper<=din(3 downto 0);
+ when "10"=> border<=din(3 downto 0);
+ when others=>null;
+ end case;
+ end if;
+ end if;
+ end if;
+end process;
+
+
+process(clk42)
+begin
+ if rising_edge(clk42) then
+ chrCode <= vidmem(conv_integer( vaVert & vaHoriz ));
+ chrGrap <= chrmem(conv_integer( chrCode & vpos ));
+ dout <= vidmem(conv_integer( a(9 downto 0) ));
+ if cs='0' and wr='0' then
+ vidmem(conv_integer( a(9 downto 0) )) <= din;
+ end if;
+ end if;
+end process;
+
+-- h and v counters
+-- 10.5 MHz pixelclock => 672 pixels per scan line
+-- 312 scanlines
+-- 64*6 pixels active screen = 384 pixels
+-- visible area: 52*10.5 = 546
+-- Horizontal: |42T-hsync|84T-porch|81T-border|384T-screen|81T-border|
+process(clk42)
+begin
+ if rising_edge(clk42) then
+ if pxclk_en = '1' then
+ if hctr=671 then
+ hctr<="0000000000";
+ v1 <= not v1;
+ if vctr>=vend then
+ vctr<="000000000";
+ v1 <= '0';
+ else
+ --vctr<=vctr+1;
+ if v1='1' or vvga='0' then
+ vctr<=vctr+1;
+ end if;
+ end if;
+ else
+ hctr<=hctr+1;
+ end if;
+ end if;
+ end if;
+end process;
+
+--process(pxclk)
+--begin
+-- if falling_edge(pxclk) then
+--
+-- -- 12*10.5
+-- if hctr<126 or hctr>654 then
+-- hblank <= '0';
+-- else
+-- hblank <= '1';
+-- end if;
+--
+-- if hctr<42 then -- 4*10.5
+-- hsync <= '0';
+-- else
+-- hsync <= '1';
+-- end if;
+--
+-- if vctr<6 or vctr>309 then
+-- vblank <= '0';
+-- else
+-- vblank <= '1';
+-- end if;
+--
+-- if vctr<2 then
+-- vsync <= '0';
+-- else
+-- vsync <= '1';
+-- end if;
+--
+-- end if;
+--end process;
+
+process(clk42)
+begin
+ if rising_edge(clk42) then
+ if pxclk_en = '1' then
+ if vvga='0' then
+ -- 12*10.5
+ if hctr<126 or hctr>654 then
+ hblank <= '0';
+ else
+ hblank <= '1';
+ end if;
+ else
+ -- VGA 6us
+ --
+ --if hctr<64 or hctr>662 then
+ if hctr<120 or hctr>654 then
+ hblank <= '0';
+ else
+ hblank <= '1';
+ end if;
+ end if;
+
+ if vvga='0' then
+ if hctr<42 then -- 4*10.5
+ hsync <= '0';
+ else
+ hsync <= '1';
+ end if;
+
+ if vctr<6 or vctr>309 then
+ vblank <= '0';
+ else
+ vblank <= '1';
+ end if;
+
+ else
+ if hctr<79 then -- 4*21
+ hsync <= '0';
+ else
+ hsync <= '1';
+ end if;
+
+ if vctr<16 or vctr>257 then
+ vblank <= '0';
+ else
+ vblank <= '1';
+ end if;
+
+ end if;
+
+
+ if vctr<2 then
+ vsync <= '0';
+ else
+ vsync <= '1';
+ end if;
+ end if;
+ end if;
+end process;
+
+hact <= '1' when hctr>=hstart and hctr=vstart and vctr