integrate shmask generation logic from Ossc Pro

This commit is contained in:
marqs 2025-06-21 11:52:36 +03:00
parent d6dba1618b
commit e09f3c88b0
15 changed files with 370 additions and 131 deletions

View File

@ -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_

View File

@ -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
#

View File

@ -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

View File

@ -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),

View File

@ -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];

View File

@ -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);

View File

@ -53,6 +53,7 @@
<File Name="sys_controller/src/fat16_export.c"/>
<File Name="sys_controller/src/lcd.c"/>
<File Name="sys_controller/src/lumacode_palettes.c"/>
<File Name="sys_controller/src/shmask_arrays.c"/>
</VirtualDirectory>
<VirtualDirectory Name="ic_drivers">
<VirtualDirectory Name="pcm1862">

View File

@ -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: <none>", 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

View File

@ -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];

View File

@ -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;

View File

@ -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,

View File

@ -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 lat. test>","DIYチエンテスト"), OPT_FUNC_CALL, { .fun = { latency_test, &lt_arg_info } } },

View File

@ -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}}};

View File

@ -440,6 +440,11 @@
internal="sc_config_0.sc_if"
type="conduit"
dir="end" />
<interface
name="sc_config_0_shmask_if"
internal="sc_config_0.shmask_if"
type="conduit"
dir="end" />
<module name="clk_27" kind="clock_source" version="24.1" enabled="1">
<parameter name="clockFrequency" value="27000000" />
<parameter name="clockFrequencyKnown" value="true" />
@ -516,9 +521,9 @@
<parameter name="simInputCharacterStream" value="" />
<parameter name="simInteractiveOptions">NO_INTERACTIVE_WINDOWS</parameter>
<parameter name="useRegistersForReadBuffer" value="true" />
<parameter name="useRegistersForWriteBuffer" value="true" />
<parameter name="useRegistersForWriteBuffer" value="false" />
<parameter name="useRelativePathForSimFile" value="false" />
<parameter name="writeBufferDepth" value="16" />
<parameter name="writeBufferDepth" value="64" />
<parameter name="writeIRQThreshold" value="8" />
</module>
<module

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<EnsembleReport name="sys" kind="sys" version="1.0" fabric="QSYS">
<!-- Format version 24.1 1077 (Future versions may contain additional information.) -->
<!-- 2025.06.16.21:04:21 -->
<!-- 2025.06.21.10:48:12 -->
<!-- A collection of modules and connections -->
<parameter name="AUTO_GENERATION_ID">
<type>java.lang.Integer</type>
<value>1750097061</value>
<value>1750492092</value>
<derived>false</derived>
<enabled>true</enabled>
<visible>false</visible>
@ -3578,7 +3578,7 @@ parameters are a RESULT of the module parameters. -->
<slaveName>avalon_s</slaveName>
<name>sc_config_0.avalon_s</name>
<baseAddress>139264</baseAddress>
<span>2048</span>
<span>4096</span>
</memoryBlock>
<memoryBlock>
<isBridge>false</isBridge>
@ -5595,7 +5595,7 @@ the requested settings for a module instance. -->
</assignment>
<assignment>
<name>embeddedsw.CMacro.WRITE_DEPTH</name>
<value>16</value>
<value>64</value>
</assignment>
<assignment>
<name>embeddedsw.CMacro.WRITE_THRESHOLD</name>
@ -5675,7 +5675,7 @@ the requested settings for a module instance. -->
</parameter>
<parameter name="useRegistersForWriteBuffer">
<type>boolean</type>
<value>true</value>
<value>false</value>
<derived>false</derived>
<enabled>true</enabled>
<visible>true</visible>
@ -5691,7 +5691,7 @@ the requested settings for a module instance. -->
</parameter>
<parameter name="writeBufferDepth">
<type>int</type>
<value>16</value>
<value>64</value>
<derived>false</derived>
<enabled>true</enabled>
<visible>true</visible>
@ -5723,7 +5723,7 @@ the requested settings for a module instance. -->
</parameter>
<parameter name="WR_WIDTHU">
<type>int</type>
<value>4</value>
<value>6</value>
<derived>true</derived>
<enabled>true</enabled>
<visible>false</visible>
@ -5739,7 +5739,7 @@ the requested settings for a module instance. -->
</parameter>
<parameter name="write_le">
<type>java.lang.String</type>
<value>OFF</value>
<value>ON</value>
<derived>true</derived>
<enabled>true</enabled>
<visible>false</visible>
@ -5755,7 +5755,7 @@ the requested settings for a module instance. -->
</parameter>
<parameter name="HEX_WRITE_DEPTH_STR">
<type>int</type>
<value>16</value>
<value>64</value>
<derived>true</derived>
<enabled>true</enabled>
<visible>false</visible>
@ -11874,7 +11874,7 @@ parameters are a RESULT of the module parameters. -->
</parameter>
<parameter name="addressSpan">
<type>java.math.BigInteger</type>
<value>2048</value>
<value>4096</value>
<derived>true</derived>
<enabled>true</enabled>
<visible>false</visible>
@ -12173,7 +12173,7 @@ parameters are a RESULT of the module parameters. -->
<port>
<name>avalon_s_address</name>
<direction>Input</direction>
<width>9</width>
<width>10</width>
<role>address</role>
</port>
<port>
@ -12348,6 +12348,69 @@ parameters are a RESULT of the module parameters. -->
<role>sl_config3_o</role>
</port>
</interface>
<interface name="shmask_if" kind="conduit_end" version="24.1">
<!-- The connection points exposed by a module instance for the
particular module parameters. Connection points and their
parameters are a RESULT of the module parameters. -->
<parameter name="associatedClock">
<type>java.lang.String</type>
<value></value>
<derived>false</derived>
<enabled>true</enabled>
<visible>true</visible>
<valid>true</valid>
</parameter>
<parameter name="associatedReset">
<type>java.lang.String</type>
<value></value>
<derived>false</derived>
<enabled>true</enabled>
<visible>true</visible>
<valid>true</valid>
</parameter>
<parameter name="deviceFamily">
<type>java.lang.String</type>
<value>UNKNOWN</value>
<derived>false</derived>
<enabled>true</enabled>
<visible>true</visible>
<valid>true</valid>
</parameter>
<parameter name="generateLegacySim">
<type>boolean</type>
<value>false</value>
<derived>false</derived>
<enabled>true</enabled>
<visible>true</visible>
<valid>true</valid>
</parameter>
<type>conduit</type>
<isStart>false</isStart>
<port>
<name>vclk</name>
<direction>Input</direction>
<width>1</width>
<role>vclk</role>
</port>
<port>
<name>shmask_xpos</name>
<direction>Input</direction>
<width>4</width>
<role>shmask_xpos</role>
</port>
<port>
<name>shmask_ypos</name>
<direction>Input</direction>
<width>4</width>
<role>shmask_ypos</role>
</port>
<port>
<name>shmask_data</name>
<direction>Output</direction>
<width>11</width>
<role>shmask_data</role>
</port>
</interface>
<interface name="lc_ram_if" kind="conduit_end" version="24.1">
<!-- The connection points exposed by a module instance for the
particular module parameters. Connection points and their
@ -15405,7 +15468,7 @@ parameters are a RESULT of the module parameters. -->
<version>17.1</version>
</plugin>
<plugin>
<instanceCount>10</instanceCount>
<instanceCount>11</instanceCount>
<name>conduit_end</name>
<type>com.altera.entityinterfaces.IElementClass</type>
<subtype>com.altera.entityinterfaces.IMutableConnectionPoint</subtype>