diff --git a/ip/sc_config/inc/sc_config_regs.h b/ip/sc_config/inc/sc_config_regs.h index 1429081..540d264 100644 --- a/ip/sc_config/inc/sc_config_regs.h +++ b/ip/sc_config/inc/sc_config_regs.h @@ -107,15 +107,11 @@ typedef union { uint8_t mask_br:4; uint8_t mask_color:3; uint8_t reverse_lpf:5; - uint8_t lm_deint_mode:1; - uint8_t nir_even_offset:1; - uint8_t ypbpr_cs:1; - uint8_t vip_enable:1; - uint8_t bfi_str:4; - uint8_t bfi_enable:1; - uint8_t shmask_mode:2; uint8_t lumacode_mode:3; - uint32_t misc_rsv:6; + uint8_t shmask_enable:1; + uint8_t shmask_iv_x:4; + uint8_t shmask_iv_y:4; + uint32_t misc_rsv:8; } __attribute__((packed, __may_alias__)); uint32_t data; } misc_config_reg; @@ -149,6 +145,17 @@ typedef union { uint32_t data; } sl_config3_reg; +// shmask regs +typedef struct { + uint32_t data[16][16]; +} shmask_array; + +// lumacode palatte ram +typedef struct { + uint32_t padding[16]; + uint32_t data[496]; +} lc_pal_ram; + typedef struct { fe_status_reg fe_status; fe_status2_reg fe_status2; @@ -165,8 +172,8 @@ typedef struct { sl_config_reg sl_config; sl_config2_reg sl_config2; sl_config3_reg sl_config3; - uint32_t padding[1]; - uint32_t lumacode_pal_ram[496]; + shmask_array shmask_data_array __attribute__ ((aligned (1024))); + lc_pal_ram lumacode_pal_ram __attribute__ ((aligned (2048))); } sc_regs; #endif //SC_CONFIG_REGS_H_ diff --git a/ip/sc_config/sc_config_hw.tcl b/ip/sc_config/sc_config_hw.tcl index 4093f8c..905bab0 100644 --- a/ip/sc_config/sc_config_hw.tcl +++ b/ip/sc_config/sc_config_hw.tcl @@ -100,7 +100,7 @@ set_interface_property avalon_s PORT_NAME_MAP "" set_interface_property avalon_s CMSIS_SVD_VARIABLES "" set_interface_property avalon_s SVD_ADDRESS_GROUP "" -add_interface_port avalon_s avalon_s_address address Input 9 +add_interface_port avalon_s avalon_s_address address Input 10 add_interface_port avalon_s avalon_s_writedata writedata Input 32 add_interface_port avalon_s avalon_s_readdata readdata Output 32 add_interface_port avalon_s avalon_s_byteenable byteenable Input 4 @@ -160,6 +160,24 @@ add_interface_port sc_if sl_config2_o sl_config2_o Output 32 add_interface_port sc_if sl_config3_o sl_config3_o Output 32 +# +# connection point shmask_if +# +add_interface shmask_if conduit end +set_interface_property shmask_if associatedClock "" +set_interface_property shmask_if associatedReset "" +set_interface_property shmask_if ENABLED true +set_interface_property shmask_if EXPORT_OF "" +set_interface_property shmask_if PORT_NAME_MAP "" +set_interface_property shmask_if CMSIS_SVD_VARIABLES "" +set_interface_property shmask_if SVD_ADDRESS_GROUP "" + +add_interface_port shmask_if vclk vclk Input 1 +add_interface_port shmask_if shmask_xpos shmask_xpos Input 4 +add_interface_port shmask_if shmask_ypos shmask_ypos Input 4 +add_interface_port shmask_if shmask_data shmask_data Output 11 + + # # connection point lumacode_ram_if # diff --git a/ip/sc_config/sc_config_top.sv b/ip/sc_config/sc_config_top.sv index 8c03b83..748deff 100644 --- a/ip/sc_config/sc_config_top.sv +++ b/ip/sc_config/sc_config_top.sv @@ -24,7 +24,7 @@ module sc_config_top( // avalon slave input [31:0] avalon_s_writedata, output reg [31:0] avalon_s_readdata, - input [8:0] avalon_s_address, + input [9:0] avalon_s_address, input [3:0] avalon_s_byteenable, input avalon_s_write, input avalon_s_read, @@ -46,6 +46,11 @@ module sc_config_top( output [31:0] sl_config_o, output [31:0] sl_config2_o, output [31:0] sl_config3_o, + // Shadow mask read interface + input vclk, + input [3:0] shmask_xpos, + input [3:0] shmask_ypos, + output [10:0] shmask_data, // Lumacode interface input lumacode_clk_i, input [8:0] lumacode_addr_i, @@ -53,28 +58,121 @@ module sc_config_top( output [31:0] lumacode_data_o ); -localparam FE_STATUS_REGNUM = 9'h0; -localparam FE_STATUS2_REGNUM = 9'h1; -localparam LT_STATUS_REGNUM = 9'h2; -localparam HV_IN_CONFIG_REGNUM = 9'h3; -localparam HV_IN_CONFIG2_REGNUM = 9'h4; -localparam HV_IN_CONFIG3_REGNUM = 9'h5; -localparam HV_OUT_CONFIG_REGNUM = 9'h6; -localparam HV_OUT_CONFIG2_REGNUM = 9'h7; -localparam HV_OUT_CONFIG3_REGNUM = 9'h8; -localparam XY_OUT_CONFIG_REGNUM = 9'h9; -localparam XY_OUT_CONFIG2_REGNUM = 9'ha; -localparam MISC_CONFIG_REGNUM = 9'hb; -localparam SL_CONFIG_REGNUM = 9'hc; -localparam SL_CONFIG2_REGNUM = 9'hd; -localparam SL_CONFIG3_REGNUM = 9'he; +localparam FE_STATUS_REGNUM = 10'h0; +localparam FE_STATUS2_REGNUM = 10'h1; +localparam LT_STATUS_REGNUM = 10'h2; +localparam HV_IN_CONFIG_REGNUM = 10'h3; +localparam HV_IN_CONFIG2_REGNUM = 10'h4; +localparam HV_IN_CONFIG3_REGNUM = 10'h5; +localparam HV_OUT_CONFIG_REGNUM = 10'h6; +localparam HV_OUT_CONFIG2_REGNUM = 10'h7; +localparam HV_OUT_CONFIG3_REGNUM = 10'h8; +localparam XY_OUT_CONFIG_REGNUM = 10'h9; +localparam XY_OUT_CONFIG2_REGNUM = 10'ha; +localparam MISC_CONFIG_REGNUM = 10'hb; +localparam SL_CONFIG_REGNUM = 10'hc; +localparam SL_CONFIG2_REGNUM = 10'hd; +localparam SL_CONFIG3_REGNUM = 10'he; -localparam LUMACODE_RAM_START = 9'h10; +localparam SHMASK_DATA_OFFSET = 10'h100; +localparam LUMACODE_RAM_OFFSET = 10'h200; reg [31:0] config_reg[HV_IN_CONFIG_REGNUM:SL_CONFIG3_REGNUM] /* synthesis ramstyle = "logic" */; assign avalon_s_waitrequest_n = 1'b1; +// Shadow mask array +altsyncram shmask_array_inst ( + .address_a (avalon_s_address[7:0]), + .address_b ({shmask_ypos, shmask_xpos}), + .clock0 (clk_i), + .clock1 (vclk), + .data_a (avalon_s_writedata[10:0]), + .wren_a (avalon_s_chipselect && avalon_s_write && (avalon_s_address >= SHMASK_DATA_OFFSET) && (avalon_s_address < LUMACODE_RAM_OFFSET)), + .q_b (shmask_data), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({11{1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .rden_b (1'b1), + .wren_b (1'b0)); +defparam + shmask_array_inst.address_aclr_b = "NONE", + shmask_array_inst.address_reg_b = "CLOCK1", + shmask_array_inst.clock_enable_input_a = "BYPASS", + shmask_array_inst.clock_enable_input_b = "BYPASS", + shmask_array_inst.clock_enable_output_b = "BYPASS", + shmask_array_inst.intended_device_family = "Cyclone IV E", + shmask_array_inst.lpm_type = "altsyncram", + shmask_array_inst.numwords_a = 256, + shmask_array_inst.numwords_b = 256, + shmask_array_inst.operation_mode = "DUAL_PORT", + shmask_array_inst.outdata_aclr_b = "NONE", + shmask_array_inst.outdata_reg_b = "CLOCK1", + shmask_array_inst.power_up_uninitialized = "FALSE", + shmask_array_inst.widthad_a = 8, + shmask_array_inst.widthad_b = 8, + shmask_array_inst.width_a = 11, + shmask_array_inst.width_b = 11, + shmask_array_inst.width_byteena_a = 1; + +// Lumacode palette RAM +altsyncram lumacode_pal_ram ( + .address_a (avalon_s_address[8:0]), + .address_b (lumacode_addr_i), + .clock0 (clk_i), + .clock1 (lumacode_clk_i), + .data_a (avalon_s_writedata), + .rden_b (lumacode_rden_i), + .wren_a (avalon_s_chipselect && avalon_s_write && (avalon_s_address >= LUMACODE_RAM_OFFSET)), + .q_b (lumacode_data_o), + .aclr0 (1'b0), + .aclr1 (1'b0), + .addressstall_a (1'b0), + .addressstall_b (1'b0), + .byteena_a (1'b1), + .byteena_b (1'b1), + .clocken0 (1'b1), + .clocken1 (1'b1), + .clocken2 (1'b1), + .clocken3 (1'b1), + .data_b ({32{1'b1}}), + .eccstatus (), + .q_a (), + .rden_a (1'b1), + .wren_b (1'b0)); +defparam + lumacode_pal_ram.address_aclr_b = "NONE", + lumacode_pal_ram.address_reg_b = "CLOCK1", + lumacode_pal_ram.clock_enable_input_a = "BYPASS", + lumacode_pal_ram.clock_enable_input_b = "BYPASS", + lumacode_pal_ram.clock_enable_output_b = "BYPASS", + lumacode_pal_ram.intended_device_family = "Cyclone IV E", + lumacode_pal_ram.lpm_type = "altsyncram", + lumacode_pal_ram.numwords_a = 512, + lumacode_pal_ram.numwords_b = 512, + lumacode_pal_ram.operation_mode = "DUAL_PORT", + lumacode_pal_ram.outdata_aclr_b = "NONE", + lumacode_pal_ram.outdata_reg_b = "UNREGISTERED", + lumacode_pal_ram.power_up_uninitialized = "FALSE", + lumacode_pal_ram.rdcontrol_reg_b = "CLOCK1", + lumacode_pal_ram.widthad_a = 9, + lumacode_pal_ram.widthad_b = 9, + lumacode_pal_ram.width_a = 32, + lumacode_pal_ram.width_b = 32, + lumacode_pal_ram.width_byteena_a = 1; + + genvar i; generate for (i=HV_IN_CONFIG_REGNUM; i <= SL_CONFIG3_REGNUM; i++) begin : gen_reg @@ -125,51 +223,4 @@ assign sl_config_o = config_reg[SL_CONFIG_REGNUM]; assign sl_config2_o = config_reg[SL_CONFIG2_REGNUM]; assign sl_config3_o = config_reg[SL_CONFIG3_REGNUM]; - -// Lumacode palette RAM -altsyncram lumacode_pal_ram ( - .address_a (avalon_s_address), - .address_b (lumacode_addr_i), - .clock0 (clk_i), - .clock1 (lumacode_clk_i), - .data_a (avalon_s_writedata), - .rden_b (lumacode_rden_i), - .wren_a (avalon_s_chipselect && avalon_s_write && (avalon_s_address >= LUMACODE_RAM_START)), - .q_b (lumacode_data_o), - .aclr0 (1'b0), - .aclr1 (1'b0), - .addressstall_a (1'b0), - .addressstall_b (1'b0), - .byteena_a (1'b1), - .byteena_b (1'b1), - .clocken0 (1'b1), - .clocken1 (1'b1), - .clocken2 (1'b1), - .clocken3 (1'b1), - .data_b ({32{1'b1}}), - .eccstatus (), - .q_a (), - .rden_a (1'b1), - .wren_b (1'b0)); -defparam - lumacode_pal_ram.address_aclr_b = "NONE", - lumacode_pal_ram.address_reg_b = "CLOCK1", - lumacode_pal_ram.clock_enable_input_a = "BYPASS", - lumacode_pal_ram.clock_enable_input_b = "BYPASS", - lumacode_pal_ram.clock_enable_output_b = "BYPASS", - lumacode_pal_ram.intended_device_family = "Cyclone IV E", - lumacode_pal_ram.lpm_type = "altsyncram", - lumacode_pal_ram.numwords_a = 512, - lumacode_pal_ram.numwords_b = 512, - lumacode_pal_ram.operation_mode = "DUAL_PORT", - lumacode_pal_ram.outdata_aclr_b = "NONE", - lumacode_pal_ram.outdata_reg_b = "UNREGISTERED", - lumacode_pal_ram.power_up_uninitialized = "FALSE", - lumacode_pal_ram.rdcontrol_reg_b = "CLOCK1", - lumacode_pal_ram.widthad_a = 9, - lumacode_pal_ram.widthad_b = 9, - lumacode_pal_ram.width_a = 32, - lumacode_pal_ram.width_b = 32, - lumacode_pal_ram.width_byteena_a = 1; - endmodule diff --git a/rtl/ossc.v b/rtl/ossc.v index 4612ac9..feeb680 100644 --- a/rtl/ossc.v +++ b/rtl/ossc.v @@ -133,7 +133,7 @@ wire [31:0] lumacode_data; wire [8:0] lumacode_addr; wire lumacode_rden; -reg remove_event_prev; +reg remote_event_prev; reg [14:0] to_ctr, to_ctr_ms; wire lcd_bl_timeout; @@ -142,6 +142,8 @@ wire osd_enable_pre; wire osd_enable = osd_enable_pre & ~lt_active; wire [10:0] xpos_sc; wire [10:0] ypos_sc; +wire [3:0] x_ctr_shmask, y_ctr_shmask; +wire [10:0] shmask_data; wire resync_indicator = (warn_pll_lock_lost != 0) | (resync_led_ctr != 0); wire LED_R_i = lt_active ? lt_trig_waiting : resync_indicator; @@ -263,7 +265,7 @@ end // LCD backlight timeout counters always @(posedge clk27) begin - if (remote_event != remove_event_prev) begin + if (remote_event != remote_event_prev) begin to_ctr <= 15'd0; to_ctr_ms <= 15'd0; end else begin @@ -283,7 +285,7 @@ begin 2'b11: lcd_bl_timeout <= (to_ctr_ms >= 30000); //30s endcase - remove_event_prev <= remote_event; + remote_event_prev <= remote_event; end // Generate a warning signal from sync lock loss @@ -409,6 +411,10 @@ sys sys_inst( .sc_config_0_sc_if_sl_config_o (sl_config), .sc_config_0_sc_if_sl_config2_o (sl_config2), .sc_config_0_sc_if_sl_config3_o (sl_config3), + .sc_config_0_shmask_if_vclk (PCLK_sc), + .sc_config_0_shmask_if_shmask_xpos (x_ctr_shmask), + .sc_config_0_shmask_if_shmask_ypos (y_ctr_shmask), + .sc_config_0_shmask_if_shmask_data (shmask_data), .sc_config_0_lc_ram_if_lumacode_clk_i (TVP_PCLK_i), .sc_config_0_lc_ram_if_lumacode_addr_i (lumacode_addr), .sc_config_0_lc_ram_if_lumacode_rden_i (lumacode_rden), @@ -475,6 +481,9 @@ scanconverter #( .DE_o(DE_sc), .xpos_o(xpos_sc), .ypos_o(ypos_sc), + .x_ctr_shmask(x_ctr_shmask), + .y_ctr_shmask(y_ctr_shmask), + .shmask_data(shmask_data), .resync_strobe(resync_strobe_i), .emif_br_clk(1'b0), .emif_br_reset(1'b0), diff --git a/rtl/scanconverter.v b/rtl/scanconverter.v index fe5c8ef..f1795c6 100644 --- a/rtl/scanconverter.v +++ b/rtl/scanconverter.v @@ -59,6 +59,9 @@ module scanconverter ( output DE_o, output [11:0] xpos_o, output [10:0] ypos_o, + output reg [3:0] x_ctr_shmask, + output reg [3:0] y_ctr_shmask, + input [11:0] shmask_data, output reg resync_strobe, input emif_br_clk, input emif_br_reset, @@ -147,25 +150,19 @@ wire [4:0] SL_HYBRSTR = sl_config3[29:25]; wire [3:0] MISC_MASK_BR = misc_config[3:0]; wire [2:0] MISC_MASK_COLOR = misc_config[6:4]; -wire MISC_LM_DEINT_MODE = misc_config[12]; -wire MISC_NIR_EVEN_OFFSET = misc_config[13]; -wire [3:0] MISC_BFI_STR = misc_config[19:16]; -wire MISC_BFI_ENABLE = misc_config[20]; -wire MISC_SHMASK_ENABLE = (misc_config[22:21] != '0); -wire [1:0] MISC_SHMASK_ID = (misc_config[22:21] - 1'b1); +wire MISC_LM_DEINT_MODE = 1'b0; +wire MISC_NIR_EVEN_OFFSET = 1'b0; +wire [3:0] MISC_BFI_STR = 4'h0; +wire MISC_BFI_ENABLE = 1'b0; +wire MISC_SHMASK_ENABLE = misc_config[15]; +wire [3:0] MISC_SHMASK_IV_X = misc_config[19:16]; +wire [3:0] MISC_SHMASK_IV_Y = misc_config[23:20]; wire [7:0] MASK_R = MISC_MASK_COLOR[2] ? {2{MISC_MASK_BR}} : 8'h00; wire [7:0] MASK_G = MISC_MASK_COLOR[1] ? {2{MISC_MASK_BR}} : 8'h00; wire [7:0] MASK_B = MISC_MASK_COLOR[0] ? {2{MISC_MASK_BR}} : 8'h00; -/* RGB Shadow mask presets: A-Grille, TV, PVM. Data from ShadowMasks_MiSTer */ -wire [1:0] shmask_iv_x[0:2] = '{2'h3, 2'h3, 2'h2}; -wire [1:0] shmask_iv_y[0:2] = '{2'h0, 2'h1, 2'h3}; -wire [10:0] shmask_data[0:2][0:3][0:3] = '{'{ '{11'h44c,11'h24c,11'h14c,11'h04c}, '{11'h0,11'h0,11'h0,11'h0}, '{11'h0,11'h0,11'h0,11'h0}, '{11'h0,11'h0,11'h0,11'h0}}, - '{ '{11'h708,11'h44c,11'h24c,11'h14c}, '{11'h44c,11'h24c,11'h14c,11'h708}, '{11'h0,11'h0,11'h0,11'h0}, '{11'h0,11'h0,11'h0,11'h0}}, - '{ '{11'h42a,11'h72a,11'h72a,11'h0}, '{11'h42a,11'h22a,11'h72a,11'h0}, '{11'h72a,11'h22a,11'h12a,11'h0}, '{11'h42a,11'h72a,11'h12a,11'h0}}}; - reg frame_change_sync1_reg, frame_change_sync2_reg, frame_change_prev, frame_change_resync; wire frame_change = frame_change_sync2_reg; @@ -212,8 +209,6 @@ reg mask_enable_pp[PP_MASK_END:PP_TP_START] /* synthesis ramstyle = "logic" */; reg draw_sl_pp[(PP_SLGEN_START+1):(PP_SLGEN_END-1)] /* synthesis ramstyle = "logic" */; reg [3:0] x_ctr_sl_pp[PP_PL_START:PP_SLGEN_START] /* synthesis ramstyle = "logic" */; reg [2:0] y_ctr_sl_pp[PP_PL_START:PP_SLGEN_START] /* synthesis ramstyle = "logic" */; -reg [1:0] x_ctr_shmask_pp[PP_PL_START:PP_SHMASK_START] /* synthesis ramstyle = "logic" */; -reg [1:0] y_ctr_shmask_pp[PP_PL_START:PP_SHMASK_START] /* synthesis ramstyle = "logic" */; assign PCLK_o = PCLK_OUT_i; @@ -425,7 +420,7 @@ end // | | MASK | | | | | | | | | | | // | | LB_SETUP | LINEBUF | | | | | | | | | | // | | | | SRCSEL | | | | | | | | | -// | | | | SHMASK | SHMASK | SHMASK | | | | | | | +// | | SHM_BUF | SHM_BUF | SHMASK | SHMASK | SHMASK | | | | | | | // | | | | | Y | Y | | | | | | | // | | | | | | | SLGEN | SLGEN | SLGEN | SLGEN | SLGEN | | // | | | | | | | | | | | | TP | @@ -466,7 +461,7 @@ always @(posedge PCLK_OUT_i) begin y_ctr_sl_pp[1] <= 0; end line_id <= ~line_id; - y_ctr_shmask_pp[1] <= '0; + y_ctr_shmask <= '0; end else begin if (ypos_pp[1] != V_ACTIVE) begin ypos_pp[1] <= ypos_pp[1] + 1'b1; @@ -486,7 +481,7 @@ always @(posedge PCLK_OUT_i) begin end if (!ypos_pp_init) begin y_ctr_sl_pp[1] <= (y_ctr_sl_pp[1] == SL_IV_Y) ? '0 : y_ctr_sl_pp[1] + 1'b1; - y_ctr_shmask_pp[1] <= (y_ctr_shmask_pp[1] == shmask_iv_y[MISC_SHMASK_ID]) ? '0 : y_ctr_shmask_pp[1] + 1'b1; + y_ctr_shmask <= (y_ctr_shmask == MISC_SHMASK_IV_Y) ? '0 : y_ctr_shmask + 1'b1; end end end @@ -494,7 +489,7 @@ always @(posedge PCLK_OUT_i) begin xpos_lb <= X_START_LB; x_ctr <= 0; x_ctr_sl_pp[1] <= 0; - x_ctr_shmask_pp[1] <= 0; + x_ctr_shmask <= 0; end else begin if (xpos_pp[1] != H_ACTIVE) begin xpos_pp[1] <= xpos_pp[1] + 1'b1; @@ -508,7 +503,7 @@ always @(posedge PCLK_OUT_i) begin x_ctr <= x_ctr + 1'b1; end x_ctr_sl_pp[1] <= (x_ctr_sl_pp[1] == SL_IV_X) ? '0 : x_ctr_sl_pp[1] + 1'b1; - x_ctr_shmask_pp[1] <= (x_ctr_shmask_pp[1] == shmask_iv_x[MISC_SHMASK_ID]) ? '0 : x_ctr_shmask_pp[1] + 1'b1; + x_ctr_shmask <= (x_ctr_shmask == MISC_SHMASK_IV_X) ? '0 : x_ctr_shmask + 1'b1; end end end @@ -527,10 +522,6 @@ always @(posedge PCLK_OUT_i) begin x_ctr_sl_pp[pp_idx] <= x_ctr_sl_pp[pp_idx-1]; y_ctr_sl_pp[pp_idx] <= y_ctr_sl_pp[pp_idx-1]; end - for(pp_idx = PP_PL_START+1; pp_idx <= PP_SHMASK_START; pp_idx = pp_idx+1) begin - x_ctr_shmask_pp[pp_idx] <= x_ctr_shmask_pp[pp_idx-1]; - y_ctr_shmask_pp[pp_idx] <= y_ctr_shmask_pp[pp_idx-1]; - end // Overridden later where necessary for (pp_idx = PP_SRCSEL_END+1; pp_idx <= PP_PL_END; pp_idx = pp_idx+1) begin R_pp[pp_idx] <= R_pp[pp_idx-1]; @@ -562,15 +553,15 @@ always @(posedge PCLK_OUT_i) begin Y <= {1'b0, Y_rb_tmp} + {1'b0, G_pp[PP_Y_CALC_START+1], 1'b0}; /* ---------- Shadow mask calculation (3 cycles) ---------- */ - R_shmask_str <= shmask_data[MISC_SHMASK_ID][y_ctr_shmask_pp[PP_SHMASK_START]][x_ctr_shmask_pp[PP_SHMASK_START]][10] ? - 5'h10 + shmask_data[MISC_SHMASK_ID][y_ctr_shmask_pp[PP_SHMASK_START]][x_ctr_shmask_pp[PP_SHMASK_START]][7:4] : - shmask_data[MISC_SHMASK_ID][y_ctr_shmask_pp[PP_SHMASK_START]][x_ctr_shmask_pp[PP_SHMASK_START]][3:0]; - G_shmask_str <= shmask_data[MISC_SHMASK_ID][y_ctr_shmask_pp[PP_SHMASK_START]][x_ctr_shmask_pp[PP_SHMASK_START]][9] ? - 5'h10 + shmask_data[MISC_SHMASK_ID][y_ctr_shmask_pp[PP_SHMASK_START]][x_ctr_shmask_pp[PP_SHMASK_START]][7:4] : - shmask_data[MISC_SHMASK_ID][y_ctr_shmask_pp[PP_SHMASK_START]][x_ctr_shmask_pp[PP_SHMASK_START]][3:0]; - B_shmask_str <= shmask_data[MISC_SHMASK_ID][y_ctr_shmask_pp[PP_SHMASK_START]][x_ctr_shmask_pp[PP_SHMASK_START]][8] ? - 5'h10 + shmask_data[MISC_SHMASK_ID][y_ctr_shmask_pp[PP_SHMASK_START]][x_ctr_shmask_pp[PP_SHMASK_START]][7:4] : - shmask_data[MISC_SHMASK_ID][y_ctr_shmask_pp[PP_SHMASK_START]][x_ctr_shmask_pp[PP_SHMASK_START]][3:0]; + R_shmask_str <= shmask_data[10] ? + 5'h10 + shmask_data[7:4] : + shmask_data[3:0]; + G_shmask_str <= shmask_data[9] ? + 5'h10 + shmask_data[7:4] : + shmask_data[3:0]; + B_shmask_str <= shmask_data[8] ? + 5'h10 + shmask_data[7:4] : + shmask_data[3:0]; // Cycle 3 R_pp[PP_SHMASK_END] <= MISC_SHMASK_ENABLE ? (R_shmask_mult[8] ? 8'hff : R_shmask_mult[7:0]) : R_pp[PP_SHMASK_START+2]; diff --git a/rtl/tvp7002_frontend.v b/rtl/tvp7002_frontend.v index 8a59fd2..68bbda4 100644 --- a/rtl/tvp7002_frontend.v +++ b/rtl/tvp7002_frontend.v @@ -128,7 +128,7 @@ wire [8:0] V_BACKPORCH = hv_in_config3[12:4]; wire [5:0] MISC_REV_LPF_STR = (misc_config[11:7] + 6'd16); wire MISC_REV_LPF_ENABLE = (misc_config[11:7] != 5'h0); -wire [2:0] MISC_LUMACODE_MODE = misc_config[25:23]; +wire [2:0] MISC_LUMACODE_MODE = misc_config[14:12]; wire [11:0] h_cnt_ref = (vsync_i_type == VSYNC_SEPARATED) ? h_cnt_sogref : h_cnt; wire [11:0] even_min_thold = (H_TOTAL / 12'd4); diff --git a/software/ossc_sw.project b/software/ossc_sw.project index 9e7874c..427985f 100644 --- a/software/ossc_sw.project +++ b/software/ossc_sw.project @@ -53,6 +53,7 @@ + diff --git a/software/sys_controller/av_controller.c b/software/sys_controller/av_controller.c index 8e53853..c88c924 100644 --- a/software/sys_controller/av_controller.c +++ b/software/sys_controller/av_controller.c @@ -42,6 +42,9 @@ #include "sd_io.h" #include "sys/alt_timestamp.h" +#include "src/shmask_arrays.c" +#include "src/lumacode_palettes.c" + #define MIN_LINES_PROGRESSIVE 200 #define MIN_LINES_INTERLACED 400 #define STATUS_TIMEOUT_US 25000 @@ -126,7 +129,12 @@ volatile sc_regs *sc = (volatile sc_regs*)SC_CONFIG_0_BASE; volatile osd_regs *osd = (volatile osd_regs*)OSD_GENERATOR_0_BASE; volatile pll_reconfig_regs *pll_reconfig = (volatile pll_reconfig_regs*)PLL_RECONFIG_0_BASE; -#include "src/lumacode_palettes.c" +c_shmask_t c_shmask; +const shmask_data_arr* shmask_data_arr_list[] = {NULL, &shmask_agrille, &shmask_tv, &shmask_pvm, &shmask_pvm_2530, &shmask_xc_3315c, &shmask_c_1084, &shmask_jvc, &shmask_vga, &c_shmask.arr}; +int shmask_loaded_array = 0; +int shmask_loaded_str = -1; +#define SHMASKS_SIZE (sizeof(shmask_data_arr_list) / sizeof((shmask_data_arr_list)[0])) + const lc_palette_set* lc_palette_set_list[] = {&lc_palette_pal}; int loaded_lc_palette = -1; @@ -447,7 +455,8 @@ status_t get_status(tvp_sync_input_t syncinput) void update_sc_config(mode_data_t *vm_in, mode_data_t *vm_out, vm_proc_config_t *vm_conf, avconfig_t *avconfig) { - int i; + int i, p, t; + shmask_data_arr *shmask_data_arr_ptr; hv_config_reg hv_in_config = {.data=0x00000000}; hv_config2_reg hv_in_config2 = {.data=0x00000000}; @@ -462,9 +471,25 @@ void update_sc_config(mode_data_t *vm_in, mode_data_t *vm_out, vm_proc_config_t sl_config2_reg sl_config2 = {.data=0x00000000}; sl_config3_reg sl_config3 = {.data=0x00000000}; + if (avconfig->shmask_mode && ((avconfig->shmask_mode != shmask_loaded_array) || (avconfig->shmask_str != shmask_loaded_str))) { + shmask_data_arr_ptr = (shmask_data_arr*)shmask_data_arr_list[avconfig->shmask_mode]; + + for (p=0; p<=shmask_data_arr_ptr->iv_y; p++) { + for (t=0; t<=shmask_data_arr_ptr->iv_x; t++) + sc->shmask_data_array.data[p][t] = (avconfig->shmask_str == 15) ? shmask_data_arr_ptr->v[p][t] : (shmask_data_arr_ptr->v[p][t]&0x700) | + ((((avconfig->shmask_str+1)*((shmask_data_arr_ptr->v[p][t]&0x0f0) >> 4))/16)<<4) | + (15-(((avconfig->shmask_str+1)*(15-(shmask_data_arr_ptr->v[p][t]&0x00f))) / 16)); + } + + shmask_loaded_array = avconfig->shmask_mode; + shmask_loaded_str = avconfig->shmask_str; + } else { + shmask_data_arr_ptr = shmask_loaded_array ? (shmask_data_arr*)shmask_data_arr_list[shmask_loaded_array] : (shmask_data_arr*)shmask_data_arr_list[1]; + } + if (avconfig->lumacode_mode && (avconfig->lumacode_pal != loaded_lc_palette)) { for (i=0; i<(sizeof(lc_palette_set)/4); i++) - sc->lumacode_pal_ram[i] = lc_palette_set_list[avconfig->lumacode_pal]->data[i]; + sc->lumacode_pal_ram.data[i] = lc_palette_set_list[avconfig->lumacode_pal]->data[i]; loaded_lc_palette = avconfig->lumacode_pal; } @@ -505,7 +530,9 @@ void update_sc_config(mode_data_t *vm_in, mode_data_t *vm_out, vm_proc_config_t misc_config.mask_br = avconfig->mask_br; misc_config.mask_color = avconfig->mask_color; misc_config.reverse_lpf = avconfig->reverse_lpf; - misc_config.shmask_mode = avconfig->shmask_mode; + misc_config.shmask_enable = (avconfig->shmask_mode != 0); + misc_config.shmask_iv_x = shmask_data_arr_ptr->iv_x; + misc_config.shmask_iv_y = shmask_data_arr_ptr->iv_y; misc_config.lumacode_mode = avconfig->lumacode_mode; /*misc_config.lm_deint_mode = 0; misc_config.nir_even_offset = 0; @@ -757,6 +784,11 @@ int save_profile() { return retval; } +void set_default_c_shmask() { + memset(&c_shmask, 0, sizeof(c_shmask)); + strncpy(c_shmask.name, "Custom: ", 20); +} + // Initialize hardware int init_hw() { @@ -827,6 +859,7 @@ int init_hw() // Set defaults set_default_avconfig(); memcpy(&cm.cc, &tc_default, sizeof(avconfig_t)); + set_default_c_shmask(); memcpy(rc_keymap, rc_keymap_default, sizeof(rc_keymap)); // Init menu diff --git a/software/sys_controller/inc/av_controller.h b/software/sys_controller/inc/av_controller.h index 748bdd6..8d91133 100644 --- a/software/sys_controller/inc/av_controller.h +++ b/software/sys_controller/inc/av_controller.h @@ -89,6 +89,17 @@ typedef struct { avconfig_t cc; } avmode_t; +typedef struct { + uint8_t iv_x; + uint8_t iv_y; + uint16_t v[16][16]; +} shmask_data_arr; + +typedef struct { + char name[20]; + shmask_data_arr arr; +} c_shmask_t; + typedef union { struct { uint32_t c64_pal[16]; diff --git a/software/sys_controller/inc/avconfig.h b/software/sys_controller/inc/avconfig.h index f7e0ec1..e62aba2 100644 --- a/software/sys_controller/inc/avconfig.h +++ b/software/sys_controller/inc/avconfig.h @@ -122,6 +122,7 @@ typedef struct { alt_u8 mask_color; alt_u8 reverse_lpf; alt_u8 shmask_mode; + alt_u8 shmask_str; alt_u8 lumacode_mode; alt_u8 lumacode_pal; diff --git a/software/sys_controller/src/avconfig.c b/software/sys_controller/src/avconfig.c index df4fd32..c3ec0ca 100644 --- a/software/sys_controller/src/avconfig.c +++ b/software/sys_controller/src/avconfig.c @@ -59,6 +59,7 @@ const avconfig_t tc_default = { .c_gain = DEFAULT_COARSE_GAIN, }, .mask_br = 8, + .shmask_str = 15, .audio_dw_sampl = DEFAULT_ON, .audio_gain = AUDIO_GAIN_0DB, .link_av = AV_LAST, diff --git a/software/sys_controller/src/menu.c b/software/sys_controller/src/menu.c index 899e47f..1dda39b 100644 --- a/software/sys_controller/src/menu.c +++ b/software/sys_controller/src/menu.c @@ -44,6 +44,7 @@ extern uint8_t sl_def_iv_x, sl_def_iv_y; extern char target_profile_name[PROFILE_NAME_LEN+1]; extern volatile osd_regs *osd; extern const int num_video_modes_plm; +extern c_shmask_t c_shmask; alt_u16 tc_h_samplerate, tc_h_samplerate_adj, tc_h_synclen, tc_h_bporch, tc_h_active, tc_v_synclen, tc_v_bporch, tc_v_active, tc_sampler_phase, tc_h_mask, tc_v_mask; alt_u8 menu_active; @@ -80,7 +81,7 @@ static const char* const rgsb_ypbpr_desc[] = { "RGsB", "YPbPr" }; static const char* const auto_input_desc[] = { "Off", "Current input", "All inputs" }; static const char* const mask_color_desc[] = { "Black", "Blue", "Green", "Cyan", "Red", "Magenta", "Yellow", "White" }; static const char* const av3_alt_rgb_desc[] = { "Off", "AV1", "AV2" }; -static const char* const shmask_mode_desc[] = { "Off", "A-Grille", "TV", "PVM" }; +static const char* const shmask_mode_desc[] = { "Off", "A-Grille", "TV", "PVM", "PVM-2530", "XC-3315C", "C-1084", "JVC", "VGA", c_shmask.name }; static const char* const lumacode_mode_desc[] = { "Off", "C64", "Spectrum", "Coleco/MSX", "NES", "Atari GTIA", "Atari VCS" }; static const char* const lumacode_pal_desc[] = { "PAL" }; static const char* const adc_pll_bw_desc[] = { "High", "Medium", "Low", "Ultra low" }; @@ -215,6 +216,8 @@ MENU(menu_scanlines, P99_PROTECT({ \ MENU(menu_postproc, P99_PROTECT({ \ { "Shadow mask", OPT_AVCONFIG_SELECTION, { .sel = { &tc.shmask_mode, OPT_WRAP, SETTING_ITEM(shmask_mode_desc) } } }, + //{ "Custom shadow mask", OPT_CUSTOMMENU, { .cstm = { &cstm_shmask_load } } }, + { "Sh. mask strength", OPT_AVCONFIG_NUMVALUE, { .num = { &tc.shmask_str, OPT_NOWRAP, 0, SCANLINESTR_MAX, sl_str_disp } } }, { "Border color", OPT_AVCONFIG_SELECTION, { .sel = { &tc.mask_color, OPT_NOWRAP, SETTING_ITEM(mask_color_desc) } } }, { LNG("Border brightn.","マスクアカルサ"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.mask_br, OPT_NOWRAP, 0, HV_MASK_MAX_BR, value_disp } } }, //{ LNG("","DIYチエンテスト"), OPT_FUNC_CALL, { .fun = { latency_test, <_arg_info } } }, diff --git a/software/sys_controller/src/shmask_arrays.c b/software/sys_controller/src/shmask_arrays.c new file mode 100644 index 0000000..d05b2e1 --- /dev/null +++ b/software/sys_controller/src/shmask_arrays.c @@ -0,0 +1,45 @@ +// RGB Shadow mask presets from ShadowMasks_MiSTer + +const shmask_data_arr shmask_agrille = {.iv_x=3, .iv_y=0, .v={ + {0x44c, 0x24c, 0x14c, 0x04c}}}; + +const shmask_data_arr shmask_tv = {.iv_x=3, .iv_y=1, .v={ + {0x708, 0x44c, 0x24c, 0x14c}, + {0x44c, 0x24c, 0x14c, 0x708}}}; + +const shmask_data_arr shmask_pvm = {.iv_x=2, .iv_y=3, .v={ + {0x42a, 0x72a, 0x72a}, + {0x42a, 0x22a, 0x72a}, + {0x72a, 0x22a, 0x12a}, + {0x42a, 0x72a, 0x12a}}}; + +const shmask_data_arr shmask_pvm_2530 = {.iv_x=2, .iv_y=3, .v={ + {0x44c, 0x00e, 0x00e}, + {0x42a, 0x20c, 0x00e}, + {0x44c, 0x22a, 0x10c}, + {0x00e, 0x20c, 0x12a}}}; + +const shmask_data_arr shmask_xc_3315c = {.iv_x=5, .iv_y=3, .v={ + {0x428, 0x228, 0x12a, 0x72a, 0x72a, 0x72a}, + {0x72a, 0x72a, 0x72a, 0x428, 0x228, 0x12a}, + {0x42a, 0x22a, 0x128, 0x72a, 0x72a, 0x72a}, + {0x72a, 0x72a, 0x72a, 0x42a, 0x22a, 0x128}}}; + +const shmask_data_arr shmask_c_1084 = {.iv_x=5, .iv_y=2, .v={ + {0x44c, 0x24c, 0x14c, 0x41f, 0x21f, 0x11f}, + {0x41f, 0x21f, 0x11f, 0x44c, 0x24c, 0x14c}, + {0x44c, 0x24c, 0x14c, 0x44c, 0x24c, 0x14c}}}; + +const shmask_data_arr shmask_jvc = {.iv_x=5, .iv_y=5, .v={ + {0x43d, 0x23d, 0x13d, 0x03d, 0x03d, 0x03d}, + {0x43d, 0x23d, 0x13d, 0x03d, 0x03d, 0x03d}, + {0x43d, 0x23d, 0x13d, 0x43d, 0x23d, 0x13d}, + {0x43d, 0x23d, 0x13d, 0x43d, 0x23d, 0x13d}, + {0x03d, 0x03d, 0x03d, 0x43d, 0x23d, 0x13d}, + {0x03d, 0x03d, 0x03d, 0x43d, 0x23d, 0x13d}}}; + +const shmask_data_arr shmask_vga = {.iv_x=5, .iv_y=3, .v={ + {0x42a, 0x42a, 0x22a, 0x22a, 0x12a, 0x12a}, + {0x42a, 0x42a, 0x22a, 0x22a, 0x12a, 0x12a}, + {0x22a, 0x12a, 0x12a, 0x42a, 0x42a, 0x22a}, + {0x22a, 0x12a, 0x12a, 0x42a, 0x42a, 0x22a}}}; diff --git a/sys.qsys b/sys.qsys index 48edd83..9555581 100644 --- a/sys.qsys +++ b/sys.qsys @@ -440,6 +440,11 @@ internal="sc_config_0.sc_if" type="conduit" dir="end" /> + @@ -516,9 +521,9 @@ NO_INTERACTIVE_WINDOWS - + - + - + java.lang.Integer - 1750097061 + 1750492092 false true false @@ -3578,7 +3578,7 @@ parameters are a RESULT of the module parameters. --> avalon_s sc_config_0.avalon_s 139264 - 2048 + 4096 false @@ -5595,7 +5595,7 @@ the requested settings for a module instance. --> embeddedsw.CMacro.WRITE_DEPTH - 16 + 64 embeddedsw.CMacro.WRITE_THRESHOLD @@ -5675,7 +5675,7 @@ the requested settings for a module instance. --> boolean - true + false false true true @@ -5691,7 +5691,7 @@ the requested settings for a module instance. --> int - 16 + 64 false true true @@ -5723,7 +5723,7 @@ the requested settings for a module instance. --> int - 4 + 6 true true false @@ -5739,7 +5739,7 @@ the requested settings for a module instance. --> java.lang.String - OFF + ON true true false @@ -5755,7 +5755,7 @@ the requested settings for a module instance. --> int - 16 + 64 true true false @@ -11874,7 +11874,7 @@ parameters are a RESULT of the module parameters. --> java.math.BigInteger - 2048 + 4096 true true false @@ -12173,7 +12173,7 @@ parameters are a RESULT of the module parameters. --> avalon_s_address Input - 9 + 10 address @@ -12348,6 +12348,69 @@ parameters are a RESULT of the module parameters. --> sl_config3_o + + + + java.lang.String + + false + true + true + true + + + java.lang.String + + false + true + true + true + + + java.lang.String + UNKNOWN + false + true + true + true + + + boolean + false + false + true + true + true + + conduit + false + + vclk + Input + 1 + vclk + + + shmask_xpos + Input + 4 + shmask_xpos + + + shmask_ypos + Input + 4 + shmask_ypos + + + shmask_data + Output + 11 + shmask_data + + 17.1 - 10 + 11 conduit_end com.altera.entityinterfaces.IElementClass com.altera.entityinterfaces.IMutableConnectionPoint