data/full_repos/permissive/407067659/rtl/custom/k005849.sv
1: b'%Warning-WIDTH: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:105: Operator ASSIGN expects 5 bits on the Assign RHS, but Assign RHS\'s CONST \'4\'h0\' generates 4 bits.\n                                                                              : ... In instance k005849\nreg [4:0] div = 4\'d0;\n                ^~~~\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:113: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS\'s SEL generates 3 bits.\n                                                                              : ... In instance k005849\nwire cen_6m = !div[2:0];\n              ^\n%Warning-WIDTH: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:114: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS\'s SEL generates 3 bits.\n                                                                              : ... In instance k005849\nwire n_cen_6m = !n_div[2:0];\n                ^\n%Warning-WIDTH: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:115: Logical Operator LOGNOT expects 1 bit on the LHS, but LHS\'s SEL generates 4 bits.\n                                                                              : ... In instance k005849\nwire cen_3m = !div[3:0];\n              ^\n%Warning-WIDTH: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:209: Operator NOT expects 32 or 9 bits on the LHS, but LHS\'s SEL generates 3 bits.\n                                                                              : ... In instance k005849\nassign HSYC = HCTR[3] ? ~(h_cnt >= 285 - ~HCTR[2:0] && h_cnt <= 316 - ~HCTR[2:0]) : ~(h_cnt >= 293 + HCTR[2:0] && h_cnt <= 324 + HCTR[2:0]);\n                                         ^\n%Warning-WIDTH: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:209: Operator NOT expects 32 or 9 bits on the LHS, but LHS\'s SEL generates 3 bits.\n                                                                              : ... In instance k005849\nassign HSYC = HCTR[3] ? ~(h_cnt >= 285 - ~HCTR[2:0] && h_cnt <= 316 - ~HCTR[2:0]) : ~(h_cnt >= 293 + HCTR[2:0] && h_cnt <= 324 + HCTR[2:0]);\n                                                                      ^\n%Warning-WIDTH: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:209: Operator ADD expects 32 or 9 bits on the RHS, but RHS\'s SEL generates 3 bits.\n                                                                              : ... In instance k005849\nassign HSYC = HCTR[3] ? ~(h_cnt >= 285 - ~HCTR[2:0] && h_cnt <= 316 - ~HCTR[2:0]) : ~(h_cnt >= 293 + HCTR[2:0] && h_cnt <= 324 + HCTR[2:0]);\n                                                                                                   ^\n%Warning-WIDTH: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:209: Operator ADD expects 32 or 9 bits on the RHS, but RHS\'s SEL generates 3 bits.\n                                                                              : ... In instance k005849\nassign HSYC = HCTR[3] ? ~(h_cnt >= 285 - ~HCTR[2:0] && h_cnt <= 316 - ~HCTR[2:0]) : ~(h_cnt >= 293 + HCTR[2:0] && h_cnt <= 324 + HCTR[2:0]);\n                                                                                                                               ^\n%Warning-WIDTH: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:210: Operator SUB expects 32 or 9 bits on the RHS, but RHS\'s VARREF \'VCTR\' generates 4 bits.\n                                                                              : ... In instance k005849\nassign VSYC = ~(v_cnt >= 254 - VCTR && v_cnt <= 261 - VCTR);\n                             ^\n%Warning-WIDTH: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:210: Operator SUB expects 32 or 9 bits on the RHS, but RHS\'s VARREF \'VCTR\' generates 4 bits.\n                                                                              : ... In instance k005849\nassign VSYC = ~(v_cnt >= 254 - VCTR && v_cnt <= 261 - VCTR);\n                                                    ^\n%Error: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:313: Cannot find file containing module: \'dpram_dc\'\ndpram_dc #(.widthad_a(5)) ZRAM0\n^~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/407067659/rtl/custom,data/full_repos/permissive/407067659/dpram_dc\n             data/full_repos/permissive/407067659/rtl/custom,data/full_repos/permissive/407067659/dpram_dc.v\n             data/full_repos/permissive/407067659/rtl/custom,data/full_repos/permissive/407067659/dpram_dc.sv\n             dpram_dc\n             dpram_dc.v\n             dpram_dc.sv\n             obj_dir/dpram_dc\n             obj_dir/dpram_dc.v\n             obj_dir/dpram_dc.sv\n%Error: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:325: Cannot find file containing module: \'dpram_dc\'\ndpram_dc #(.widthad_a(5)) ZRAM1\n^~~~~~~~\n%Error: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:348: Cannot find file containing module: \'dpram_dc\'\ndpram_dc #(.widthad_a(11)) VRAM_TILEATTRIB\n^~~~~~~~\n%Error: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:360: Cannot find file containing module: \'dpram_dc\'\ndpram_dc #(.widthad_a(11)) VRAM_TILECODE\n^~~~~~~~\n%Error: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:375: Cannot find file containing module: \'dpram_dc\'\ndpram_dc #(.widthad_a(12)) VRAM_SPR\n^~~~~~~~\n%Error: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:437: Cannot find file containing module: \'dpram_dc\'\ndpram_dc #(.widthad_a(9)) SPR_CACHE\n^~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:532: Operator GT expects 8 bits on the LHS, but LHS\'s VARREF \'sprite_index\' generates 6 bits.\n                                                                              : ... In instance k005849\n    if(sprite_index > 8\'d47)  \n                    ^\n%Warning-WIDTH: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:625: Operator ADD expects 9 bits on the RHS, but RHS\'s SEL generates 4 bits.\n                                                                              : ... In instance k005849\nwire [8:0] wpx = sprite_x + sprite_width[3:0];\n                          ^\n%Error: data/full_repos/permissive/407067659/rtl/custom/k005849.sv:651: Cannot find file containing module: \'dpram_dc\'\ndpram_dc #(.widthad_a(10)) LBUFF\n^~~~~~~~\n%Error: Exiting due to 7 error(s), 12 warning(s)\n'
module k005849
(
	input         CK49,
	output        NCK2,
	output        X1S,
	output        H2,
	output        ER,
	output        QR,
	output        EQ,
	input         RES,
	input         READ,
	input  [13:0] A,
	input   [7:0] DBi,
	output  [7:0] DBo,
	output  [3:0] VCF,
	output  [3:0] VCB,
	input   [3:0] VCD,
	output  [3:0] OCF,
	output  [3:0] OCB,
	input   [3:0] OCD,
	output  [4:0] COL,
	input         XCS,
	input         BUSE,
	output        SYNC,
	output        HSYC,
	output        VSYC,
	output        HBLK,
	output        VBLK,
	output        FIRQ,
	output        IRQ,
	output        NMI,
	output        IOCS,
	output        CS80,
	

	output [15:0] R,
	output [15:0] S,
	input   [7:0] RD,
	input   [7:0] SD,
	

	input         SPFL,
	

	input   [3:0] HCTR, VCTR,


	input  [11:0] hs_address,
	input   [7:0] hs_data_in,
	output  [7:0] hs_data_out,
	input         hs_write_enable,
	input         hs_access_write
);




assign IOCS = ~(~XCS & (A[13:12] == 2'b11));


assign CS80 = XCS;


assign DBo = BUSE                        ? 8'hFF:
             (cs_regs & ~READ)           ? regs:
             (zram0_cs & ~READ)          ? zram0_Dout:
             (zram1_cs & ~READ)          ? zram1_Dout:
             (tileram_attrib_cs & ~READ) ? tileram_attrib_Dout:
             (tileram_code_cs & ~READ)   ? tileram_code_Dout:
             (spriteram_cs & ~READ)      ? spriteram_Dout:
             8'hFF;




reg [4:0] div = 4'd0;
always_ff @(posedge CK49) begin
	div <= div + 4'd1;
end
reg [3:0] n_div = 4'd0;
always_ff @(negedge CK49) begin
	n_div <= n_div + 4'd1;
end
wire cen_6m = !div[2:0];
wire n_cen_6m = !n_div[2:0];
wire cen_3m = !div[3:0];
assign NCK2 = div[2];
assign X1S = h_cnt[0];
assign H2 = h_cnt[1];


reg mc6809e_E = 0;
reg mc6809e_Q = 0;
always_ff @(posedge CK49) begin
	reg [1:0] clk_phase = 0;
	if(cen_6m) begin
		clk_phase <= clk_phase + 1'd1;
		case(clk_phase)
			2'b00: mc6809e_E <= 0;
			2'b01: mc6809e_Q <= 1;
			2'b10: mc6809e_E <= 1;
			2'b11: mc6809e_Q <= 0;
		endcase
	end
end
assign QR = mc6809e_Q;
assign ER = mc6809e_E;


assign EQ = ER & QR;




reg [8:0] h_cnt = 9'd0;
reg [8:0] v_cnt = 9'd0;



reg hblank = 0;
reg vblank = 0;
reg vblank_irq_en = 0;
reg frame_odd_even = 0;
reg hmask = 0;
always_ff @(posedge CK49) begin
	if(cen_6m) begin
		case(h_cnt)
			0: begin
				vblank_irq_en <= 0;
				h_cnt <= h_cnt + 9'd1;
			end
			1: begin
				hblank <= 0;
				h_cnt <= h_cnt + 9'd1;
			end
			9: begin
				hmask <= 0;
				h_cnt <= h_cnt + 9'd1;
			end


			249: begin
				if(hmask_en)
					hmask <= 1;
				h_cnt <= h_cnt + 9'd1;
			end
			257: begin
				hblank <= 1;
				h_cnt <= h_cnt + 9'd1;
			end
			383: begin
				h_cnt <= 0;
				case(v_cnt)
					15: begin
						vblank <= 0;
						v_cnt <= v_cnt + 9'd1;
					end
					239: begin
						vblank <= 1;
						vblank_irq_en <= 1;
						frame_odd_even <= ~frame_odd_even;
						v_cnt <= v_cnt + 9'd1;
					end
					263: begin
						v_cnt <= 9'd0;
					end
					default: v_cnt <= v_cnt + 9'd1;
				endcase
			end
			default: h_cnt <= h_cnt + 9'd1;
		endcase
	end
end


assign HBLK = hblank;
assign VBLK = vblank;


assign HSYC = HCTR[3] ? ~(h_cnt >= 285 - ~HCTR[2:0] && h_cnt <= 316 - ~HCTR[2:0]) : ~(h_cnt >= 293 + HCTR[2:0] && h_cnt <= 324 + HCTR[2:0]);
assign VSYC = ~(v_cnt >= 254 - VCTR && v_cnt <= 261 - VCTR);
assign SYNC = HSYC ^ VSYC;




reg vblank_irq = 1;
always_ff @(posedge CK49 or negedge RES) begin
	if(!RES)
		vblank_irq <= 1;
	else if(cen_6m) begin
		if(!irq_mask)
			vblank_irq <= 1;
		else if(vblank_irq_en)
			vblank_irq <= 0;
	end
end
assign IRQ = vblank_irq;


reg nmi = 1;
always_ff @(posedge CK49 or negedge RES) begin
	if(!RES)
		nmi <= 1;
	else if(cen_3m) begin
		if(!nmi_mask)
			nmi <= 1;
		else if(v_cnt % 9'd32 == 31)
			nmi <= 0;
	end
end
assign NMI = nmi;


reg firq = 1;
always_ff @(posedge CK49 or negedge RES) begin
	if(!RES)
		firq <= 1;
	else if(cen_3m) begin
		if(!firq_mask)
			firq <= 1;
		else if(!frame_odd_even && v_cnt == 9'd240)
			firq <= 0;
	end
end
assign FIRQ = firq;




wire cs_regs = ~XCS & (A[13:12] == 2'b10) & (A[7:3] == 5'b01000);
reg [7:0] reg0, reg1, reg2, reg3, reg4;

always_ff @(posedge CK49) begin
	if(cen_3m) begin
		if(cs_regs && READ) begin
			case(A[2:0])
				3'b000: reg0 <= DBi;
				3'b001: reg1 <= DBi;
				3'b010: reg2 <= DBi;
				3'b011: reg3 <= DBi;
				3'b100: reg4 <= DBi;
				default:;
			endcase
		end
	end
end


wire zram_scroll_dir = reg2[2];


wire tilemap_bank = reg3[0];



wire tile_priority_override = reg3[6];



wire hmask_en = reg3[7];


wire nmi_mask = reg4[0];
wire irq_mask = reg4[1];
wire firq_mask = reg4[2];
wire flipscreen = reg4[3];

wire [7:0] regs = (A == 14'h2040) ? reg0:
                  (A == 14'h2041) ? reg1:
                  (A == 14'h2042) ? reg2:
                  (A == 14'h2043) ? reg3:
                  8'hFF;



wire zram0_cs = ~XCS & (A[13:12] == 2'b10) & (A[7:0] >= 8'h00 && A[7:0] <= 8'h1F);
wire zram1_cs = ~XCS & (A[13:12] == 2'b10) & (A[7:0] >= 8'h20 && A[7:0] <= 8'h3F);



wire [4:0] zram_A = zram_scroll_dir ? tilemap_hpos[7:3] : tilemap_vpos[7:3];
wire [7:0] zram0_D, zram1_D, zram0_Dout, zram1_Dout;
dpram_dc #(.widthad_a(5)) ZRAM0
(
	.clock_a(CK49),
	.address_a(A[4:0]),
	.data_a(DBi),
	.q_a(zram0_Dout),
	.wren_a(zram0_cs & READ),
	
	.clock_b(CK49),
	.address_b(zram_A),
	.q_b(zram0_D)
);
dpram_dc #(.widthad_a(5)) ZRAM1
(
	.clock_a(CK49),
	.address_a(A[4:0]),
	.data_a(DBi),
	.q_a(zram1_Dout),
	.wren_a(zram1_cs & READ),
	
	.clock_b(CK49),
	.address_b(zram_A),
	.q_b(zram1_D)
);





wire tileram_attrib_cs = ~XCS & (A[13:11] == 3'b000);
wire tileram_code_cs = ~XCS & (A[13:11] == 3'b001);
wire spriteram_cs = ~XCS & (A[13:12] == 2'b01);

wire [7:0] tileram_attrib_Dout, tileram_code_Dout, spriteram_Dout, tileram_attrib_D, tileram_code_D, spriteram_D;

dpram_dc #(.widthad_a(11)) VRAM_TILEATTRIB
(
	.clock_a(CK49),
	.address_a(A[10:0]),
	.data_a(DBi),
	.q_a(tileram_attrib_Dout),
	.wren_a(tileram_attrib_cs & READ),
	
	.clock_b(CK49),
	.address_b(vram_A),
	.q_b(tileram_attrib_D)
);
dpram_dc #(.widthad_a(11)) VRAM_TILECODE
(
	.clock_a(CK49),
	.address_a(A[10:0]),
	.data_a(DBi),
	.q_a(tileram_code_Dout),
	.wren_a(tileram_code_cs & READ),
	
	.clock_b(CK49),
	.address_b(vram_A),
	.q_b(tileram_code_D)
);

`ifndef MISTER_HISCORE

dpram_dc #(.widthad_a(12)) VRAM_SPR
(
	.clock_a(CK49),
	.address_a(A[11:0]),
	.data_a(DBi),
	.q_a(spriteram_Dout),
	.wren_a(spriteram_cs & READ),
	
	.clock_b(CK49),
	.address_b({3'b000, sprite_bank, spritecache_A[7:0]}),
	.q_b(spriteram_D)
);
`else


wire [11:0] VRAM_SPR_AD = hs_access_write ? hs_address : A[11:0];
wire [7:0] VRAM_SPR_DIN = hs_access_write ? hs_data_in : DBi;
wire VRAM_SPR_WE = hs_access_write ? hs_write_enable : (spriteram_cs & READ);

dpram_dc #(.widthad_a(12)) VRAM_SPR
(
	.clock_a(CK49),
	.address_a(VRAM_SPR_AD),
	.data_a(VRAM_SPR_DIN),
	.q_a(spriteram_Dout),
	.wren_a(VRAM_SPR_WE),
	
	.clock_b(CK49),
	.address_b({3'b000, sprite_bank, spritecache_A[7:0]}),
	.q_b(spriteram_D)
);

dpram_dc #(.widthad_a(12)) VRAM_SPR_SHADOW
(
	.clock_a(CK49),
	.address_a(VRAM_SPR_AD),
	.data_a(VRAM_SPR_DIN),
	.wren_a(VRAM_SPR_WE),
	
	.clock_b(CK49),
	.address_b(hs_address),
	.q_b(hs_data_out)
);
`endif





reg [8:0] spritecache_A = 9'd0;
always_ff @(posedge CK49) begin
	if(cen_6m) begin
		if(spritecache_we)
			spritecache_A <= spritecache_A + 9'd1;
		else if(vblank)
			spritecache_A <= 9'd0;
		else
			spritecache_A <= spritecache_A;
	end
end	
wire [7:0] spriteram_Dcache;
wire spritecache_we = ~vblank & ~spritecache_A[8];
dpram_dc #(.widthad_a(9)) SPR_CACHE
(
	.clock_a(CK49),
	.address_a({frame_odd_even, spritecache_A[7:0]}),
	.data_a(spriteram_D),
	.wren_a(spritecache_we),
	
	.clock_b(~CK49),
	.address_b({~frame_odd_even, spriteram_A}),
	.q_b(spriteram_Dcache)
);





wire [8:0] hcnt_x = h_cnt ^ {9{flipscreen}};
wire [8:0] vcnt_x = v_cnt ^ {9{flipscreen}};



wire [8:0] tilemap_hpos = {h_cnt[8], hcnt_x[7:0]} + (~zram_scroll_dir ? {zram1_D[0], zram0_D} : 9'd0);
wire [8:0] tilemap_vpos = vcnt_x + (zram_scroll_dir ? {zram1_D[0], zram0_D} : 9'd0);


wire [10:0] vram_A = {tilemap_vpos[7:3], tilemap_hpos[8:3]};



wire [10:0] tile_index = {tilemap_bank, tileram_attrib_D[7:6], tileram_code_D};


wire [3:0] tile_color = tileram_attrib_D[3:0];


wire tile_hflip = tileram_attrib_D[4];
wire tile_vflip = tileram_attrib_D[5];


assign R = {tile_index, (tilemap_vpos[2:0] ^ {3{tile_vflip}}), (tilemap_hpos[2:1] ^ {2{tile_hflip}})};


wire [3:0] tile_pixel = (tilemap_hpos[0] ^ tile_hflip) ? RD[3:0] : RD[7:4];


reg tilemap_en = 0;
always_ff @(posedge CK49) begin
	if(n_cen_6m) begin
		tilemap_en <= ~(tileram_attrib_D[7] | tile_priority_override);
	end
end


assign VCF = tile_color;
assign VCB = tile_pixel;


reg [3:0] tilemap_D = 4'd0;
always_ff @(posedge CK49) begin
	if(cen_6m)
		tilemap_D <= VCD;
end








wire [8:0] sprite_hpos = h_cnt;
wire [8:0] sprite_vpos = flipscreen ? v_cnt + 9'd17 : v_cnt + 9'd18;


reg [5:0] sprite_index;
reg [1:0] sprite_offset;
reg [2:0] sprite_fsm_state;
reg [8:0] sprite_x, sprite_code;
reg [7:0] sprite_y;
reg [4:0] sprite_width;
reg [3:0] sprite_color;
reg sprite_hflip, sprite_vflip;
always_ff @(posedge CK49) begin
	if(sprite_hpos == 9'd0) begin
		sprite_width <= 5'd0;
		sprite_index <= 6'd0;
		sprite_offset <= 2'd3;
		sprite_fsm_state <= 3'd1;
	end
	else 
		case(sprite_fsm_state)
			0:;
			1: begin


				if(sprite_index > 8'd47)
					sprite_fsm_state <= 3'd0;
				else begin
					sprite_y <= spriteram_Dcache;
					sprite_offset <= 2'd2;
					sprite_fsm_state <= sprite_fsm_state + 3'd1;
				end
			end
			2: begin

				if(sprite_active) begin
					sprite_x[7:0] <= spriteram_Dcache;
					sprite_offset <= 2'd1;
					sprite_fsm_state <= sprite_fsm_state + 3'd1;
				end
				else begin
					sprite_index <= sprite_index + 6'd1;
					sprite_offset <= 2'd3;
					sprite_fsm_state <= 3'd1;
				end
			end
			3: begin

				sprite_x[8] <= spriteram_Dcache[7];
				sprite_code[8] <= spriteram_Dcache[6];
				sprite_vflip <= spriteram_Dcache[5] ^ flipscreen;
				sprite_hflip <= spriteram_Dcache[4] ^ flipscreen;
				sprite_color <= spriteram_Dcache[3:0];
				sprite_offset <= 2'd0;
				sprite_fsm_state <= sprite_fsm_state + 3'd1;
			end
			4: begin

				sprite_code[7:0] <= spriteram_Dcache;
				sprite_offset <= 2'd3;
				sprite_index <= sprite_index + 6'd1;
				sprite_width <= 5'b10000;
				sprite_fsm_state <= sprite_fsm_state + 3'd1;
			end
			5: begin
				sprite_width <= sprite_width + 5'd1;
				sprite_fsm_state <= wre ? sprite_fsm_state : 3'd1;
			end
			default:;
		endcase
end


wire [8:0] sprite_height = {1'b0, sprite_y} - sprite_vpos;


wire sprite_active = (sprite_y != 0) & (sprite_height[8:5] == 4'b1111) & (sprite_height[4] ^ ~flipscreen);

wire [3:0] lx = sprite_width[3:0] ^ {4{sprite_hflip}};
wire [3:0] ly = sprite_height[3:0] ^ {4{~sprite_vflip}};


assign S = {sprite_code, ly[3], lx[3], ly[2:0], lx[2:1]};


wire [3:0] sprite_pixel = lx[0] ? SD[3:0] : SD[7:4];




reg sprite_bank = 0;
reg old_vsync;
always_ff @(posedge CK49) begin
	old_vsync <= VSYC;
	if(!RES)
		sprite_bank <= 0;
	else if(!old_vsync && VSYC)
		sprite_bank <= ~(reg3[3] ^ SPFL);
end

wire [7:0] spriteram_A = {sprite_index, sprite_offset};


assign OCF = sprite_color;
assign OCB = sprite_pixel;







wire wre = sprite_width[4];


wire sprite_lbuff_bank = sprite_vpos[0];


wire [8:0] wpx = sprite_x + sprite_width[3:0];


reg [9:0] lbuff_A;
reg [3:0] lbuff_Din;
reg lbuff_we;
always_ff @(posedge CK49) begin
	lbuff_A <= {~sprite_lbuff_bank, wpx};
	lbuff_we <= wre;
end


always_ff @(negedge CK49) begin
	lbuff_Din <= OCD;
end


reg [9:0] radr0 = 10'd0;
reg [9:0] radr1 = 10'd1;
always_ff @(posedge CK49) begin
	if(cen_6m)
		radr0 <= {sprite_lbuff_bank, flipscreen ? sprite_hpos - 9'd241 : sprite_hpos};
end


wire [3:0] lbuff_Dout;
dpram_dc #(.widthad_a(10)) LBUFF
(
	.clock_a(CK49),
	.address_a(lbuff_A),
	.data_a({4'd0, lbuff_Din}),
	.wren_a(lbuff_we & (lbuff_Din != 0)),
	
	.clock_b(CK49),
	.address_b(radr0),
	.data_b(8'h0),
	.wren_b(radr0 == radr1),
	.q_b({4'bZZZZ, lbuff_Dout})
);


wire lbuff_read_en = (div[2:0] == 3'b100);
reg [3:0] sprite_D = 4'd0;
always_ff @(posedge CK49) begin
	if(lbuff_read_en) begin
		if(radr0 != radr1)
			sprite_D <= lbuff_Dout;
		radr1 <= radr0;
	end
end




wire tile_sprite_sel = (tilemap_en | ~(|sprite_D));
wire [3:0] tile_sprite_D = tile_sprite_sel ? tilemap_D : sprite_D;


reg [4:0] pixel_D;
always_ff @(posedge CK49) begin
	if(cen_6m)
		pixel_D <= {tile_sprite_sel, tile_sprite_D};
end


assign COL = hmask ? 5'd0 : pixel_D;

endmodule
module k005849
(
	input         CK49,
	output        NCK2,
	output        X1S,
	output        H2,
	output        ER,
	output        QR,
	output        EQ,
	input         RES,
	input         READ,
	input  [13:0] A,
	input   [7:0] DBi,
	output  [7:0] DBo,
	output  [3:0] VCF,
	output  [3:0] VCB,
	input   [3:0] VCD,
	output  [3:0] OCF,
	output  [3:0] OCB,
	input   [3:0] OCD,
	output  [4:0] COL,
	input         XCS,
	input         BUSE,
	output        SYNC,
	output        HSYC,
	output        VSYC,
	output        HBLK,
	output        VBLK,
	output        FIRQ,
	output        IRQ,
	output        NMI,
	output        IOCS,
	output        CS80,
	

	output [15:0] R,
	output [15:0] S,
	input   [7:0] RD,
	input   [7:0] SD,
	

	input         SPFL,
	

	input   [3:0] HCTR, VCTR,


	input  [11:0] hs_address,
	input   [7:0] hs_data_in,
	output  [7:0] hs_data_out,
	input         hs_write_enable,
	input         hs_access_write
);





assign IOCS = ~(~XCS & (A[13:12] == 2'b11));


assign CS80 = XCS;


assign DBo = BUSE                        ? 8'hFF:
             (cs_regs & ~READ)           ? regs:
             (zram0_cs & ~READ)          ? zram0_Dout:
             (zram1_cs & ~READ)          ? zram1_Dout:
             (tileram_attrib_cs & ~READ) ? tileram_attrib_Dout:
             (tileram_code_cs & ~READ)   ? tileram_code_Dout:
             (spriteram_cs & ~READ)      ? spriteram_Dout:
             8'hFF;




reg [4:0] div = 4'd0;
always_ff @(posedge CK49) begin
	div <= div + 4'd1;
end
reg [3:0] n_div = 4'd0;
always_ff @(negedge CK49) begin
	n_div <= n_div + 4'd1;
end
wire cen_6m = !div[2:0];
wire n_cen_6m = !n_div[2:0];
wire cen_3m = !div[3:0];
assign NCK2 = div[2];
assign X1S = h_cnt[0];
assign H2 = h_cnt[1];


reg mc6809e_E = 0;
reg mc6809e_Q = 0;
always_ff @(posedge CK49) begin
	reg [1:0] clk_phase = 0;
	if(cen_6m) begin
		clk_phase <= clk_phase + 1'd1;
		case(clk_phase)
			2'b00: mc6809e_E <= 0;
			2'b01: mc6809e_Q <= 1;
			2'b10: mc6809e_E <= 1;
			2'b11: mc6809e_Q <= 0;
		endcase
	end
end
assign QR = mc6809e_Q;
assign ER = mc6809e_E;


assign EQ = ER & QR;




reg [8:0] h_cnt = 9'd0;
reg [8:0] v_cnt = 9'd0;



reg hblank = 0;
reg vblank = 0;
reg vblank_irq_en = 0;
reg frame_odd_even = 0;
reg hmask = 0;
always_ff @(posedge CK49) begin
	if(cen_6m) begin
		case(h_cnt)
			0: begin
				vblank_irq_en <= 0;
				h_cnt <= h_cnt + 9'd1;
			end
			1: begin
				hblank <= 0;
				h_cnt <= h_cnt + 9'd1;
			end
			9: begin
				hmask <= 0;
				h_cnt <= h_cnt + 9'd1;
			end


			249: begin
				if(hmask_en)
					hmask <= 1;
				h_cnt <= h_cnt + 9'd1;
			end
			257: begin
				hblank <= 1;
				h_cnt <= h_cnt + 9'd1;
			end
			383: begin
				h_cnt <= 0;
				case(v_cnt)
					15: begin
						vblank <= 0;
						v_cnt <= v_cnt + 9'd1;
					end
					239: begin
						vblank <= 1;
						vblank_irq_en <= 1;
						frame_odd_even <= ~frame_odd_even;
						v_cnt <= v_cnt + 9'd1;
					end
					263: begin
						v_cnt <= 9'd0;
					end
					default: v_cnt <= v_cnt + 9'd1;
				endcase
			end
			default: h_cnt <= h_cnt + 9'd1;
		endcase
	end
end


assign HBLK = hblank;
assign VBLK = vblank;


assign HSYC = HCTR[3] ? ~(h_cnt >= 285 - ~HCTR[2:0] && h_cnt <= 316 - ~HCTR[2:0]) : ~(h_cnt >= 293 + HCTR[2:0] && h_cnt <= 324 + HCTR[2:0]);
assign VSYC = ~(v_cnt >= 254 - VCTR && v_cnt <= 261 - VCTR);
assign SYNC = HSYC ^ VSYC;




reg vblank_irq = 1;
always_ff @(posedge CK49 or negedge RES) begin
	if(!RES)
		vblank_irq <= 1;
	else if(cen_6m) begin
		if(!irq_mask)
			vblank_irq <= 1;
		else if(vblank_irq_en)
			vblank_irq <= 0;
	end
end
assign IRQ = vblank_irq;


reg nmi = 1;
always_ff @(posedge CK49 or negedge RES) begin
	if(!RES)
		nmi <= 1;
	else if(cen_3m) begin
		if(!nmi_mask)
			nmi <= 1;
		else if(v_cnt % 9'd32 == 31)
			nmi <= 0;
	end
end
assign NMI = nmi;


reg firq = 1;
always_ff @(posedge CK49 or negedge RES) begin
	if(!RES)
		firq <= 1;
	else if(cen_3m) begin
		if(!firq_mask)
			firq <= 1;
		else if(!frame_odd_even && v_cnt == 9'd240)
			firq <= 0;
	end
end
assign FIRQ = firq;




wire cs_regs = ~XCS & (A[13:12] == 2'b10) & (A[7:3] == 5'b01000);
reg [7:0] reg0, reg1, reg2, reg3, reg4;

always_ff @(posedge CK49) begin
	if(cen_3m) begin
		if(cs_regs && READ) begin
			case(A[2:0])
				3'b000: reg0 <= DBi;
				3'b001: reg1 <= DBi;
				3'b010: reg2 <= DBi;
				3'b011: reg3 <= DBi;
				3'b100: reg4 <= DBi;
				default:;
			endcase
		end
	end
end


wire zram_scroll_dir = reg2[2];


wire tilemap_bank = reg3[0];



wire tile_priority_override = reg3[6];



wire hmask_en = reg3[7];


wire nmi_mask = reg4[0];
wire irq_mask = reg4[1];
wire firq_mask = reg4[2];
wire flipscreen = reg4[3];

wire [7:0] regs = (A == 14'h2040) ? reg0:
                  (A == 14'h2041) ? reg1:
                  (A == 14'h2042) ? reg2:
                  (A == 14'h2043) ? reg3:
                  8'hFF;



wire zram0_cs = ~XCS & (A[13:12] == 2'b10) & (A[7:0] >= 8'h00 && A[7:0] <= 8'h1F);
wire zram1_cs = ~XCS & (A[13:12] == 2'b10) & (A[7:0] >= 8'h20 && A[7:0] <= 8'h3F);



wire [4:0] zram_A = zram_scroll_dir ? tilemap_hpos[7:3] : tilemap_vpos[7:3];
wire [7:0] zram0_D, zram1_D, zram0_Dout, zram1_Dout;
dpram_dc #(.widthad_a(5)) ZRAM0
(
	.clock_a(CK49),
	.address_a(A[4:0]),
	.data_a(DBi),
	.q_a(zram0_Dout),
	.wren_a(zram0_cs & READ),
	
	.clock_b(CK49),
	.address_b(zram_A),
	.q_b(zram0_D)
);
dpram_dc #(.widthad_a(5)) ZRAM1
(
	.clock_a(CK49),
	.address_a(A[4:0]),
	.data_a(DBi),
	.q_a(zram1_Dout),
	.wren_a(zram1_cs & READ),
	
	.clock_b(CK49),
	.address_b(zram_A),
	.q_b(zram1_D)
);





wire tileram_attrib_cs = ~XCS & (A[13:11] == 3'b000);
wire tileram_code_cs = ~XCS & (A[13:11] == 3'b001);
wire spriteram_cs = ~XCS & (A[13:12] == 2'b01);

wire [7:0] tileram_attrib_Dout, tileram_code_Dout, spriteram_Dout, tileram_attrib_D, tileram_code_D, spriteram_D;

dpram_dc #(.widthad_a(11)) VRAM_TILEATTRIB
(
	.clock_a(CK49),
	.address_a(A[10:0]),
	.data_a(DBi),
	.q_a(tileram_attrib_Dout),
	.wren_a(tileram_attrib_cs & READ),
	
	.clock_b(CK49),
	.address_b(vram_A),
	.q_b(tileram_attrib_D)
);
dpram_dc #(.widthad_a(11)) VRAM_TILECODE
(
	.clock_a(CK49),
	.address_a(A[10:0]),
	.data_a(DBi),
	.q_a(tileram_code_Dout),
	.wren_a(tileram_code_cs & READ),
	
	.clock_b(CK49),
	.address_b(vram_A),
	.q_b(tileram_code_D)
);

`ifndef MISTER_HISCORE

dpram_dc #(.widthad_a(12)) VRAM_SPR
(
	.clock_a(CK49),
	.address_a(A[11:0]),
	.data_a(DBi),
	.q_a(spriteram_Dout),
	.wren_a(spriteram_cs & READ),
	
	.clock_b(CK49),
	.address_b({3'b000, sprite_bank, spritecache_A[7:0]}),
	.q_b(spriteram_D)
);
`else


wire [11:0] VRAM_SPR_AD = hs_access_write ? hs_address : A[11:0];
wire [7:0] VRAM_SPR_DIN = hs_access_write ? hs_data_in : DBi;
wire VRAM_SPR_WE = hs_access_write ? hs_write_enable : (spriteram_cs & READ);

dpram_dc #(.widthad_a(12)) VRAM_SPR
(
	.clock_a(CK49),
	.address_a(VRAM_SPR_AD),
	.data_a(VRAM_SPR_DIN),
	.q_a(spriteram_Dout),
	.wren_a(VRAM_SPR_WE),
	
	.clock_b(CK49),
	.address_b({3'b000, sprite_bank, spritecache_A[7:0]}),
	.q_b(spriteram_D)
);

dpram_dc #(.widthad_a(12)) VRAM_SPR_SHADOW
(
	.clock_a(CK49),
	.address_a(VRAM_SPR_AD),
	.data_a(VRAM_SPR_DIN),
	.wren_a(VRAM_SPR_WE),
	
	.clock_b(CK49),
	.address_b(hs_address),
	.q_b(hs_data_out)
);
`endif





reg [8:0] spritecache_A = 9'd0;
always_ff @(posedge CK49) begin
	if(cen_6m) begin
		if(spritecache_we)
			spritecache_A <= spritecache_A + 9'd1;
		else if(vblank)
			spritecache_A <= 9'd0;
		else
			spritecache_A <= spritecache_A;
	end
end	
wire [7:0] spriteram_Dcache;
wire spritecache_we = ~vblank & ~spritecache_A[8];
dpram_dc #(.widthad_a(9)) SPR_CACHE
(
	.clock_a(CK49),
	.address_a({frame_odd_even, spritecache_A[7:0]}),
	.data_a(spriteram_D),
	.wren_a(spritecache_we),
	
	.clock_b(~CK49),
	.address_b({~frame_odd_even, spriteram_A}),
	.q_b(spriteram_Dcache)
);





wire [8:0] hcnt_x = h_cnt ^ {9{flipscreen}};
wire [8:0] vcnt_x = v_cnt ^ {9{flipscreen}};



wire [8:0] tilemap_hpos = {h_cnt[8], hcnt_x[7:0]} + (~zram_scroll_dir ? {zram1_D[0], zram0_D} : 9'd0);
wire [8:0] tilemap_vpos = vcnt_x + (zram_scroll_dir ? {zram1_D[0], zram0_D} : 9'd0);


wire [10:0] vram_A = {tilemap_vpos[7:3], tilemap_hpos[8:3]};



wire [10:0] tile_index = {tilemap_bank, tileram_attrib_D[7:6], tileram_code_D};


wire [3:0] tile_color = tileram_attrib_D[3:0];


wire tile_hflip = tileram_attrib_D[4];
wire tile_vflip = tileram_attrib_D[5];


assign R = {tile_index, (tilemap_vpos[2:0] ^ {3{tile_vflip}}), (tilemap_hpos[2:1] ^ {2{tile_hflip}})};


wire [3:0] tile_pixel = (tilemap_hpos[0] ^ tile_hflip) ? RD[3:0] : RD[7:4];


reg tilemap_en = 0;
always_ff @(posedge CK49) begin
	if(n_cen_6m) begin
		tilemap_en <= ~(tileram_attrib_D[7] | tile_priority_override);
	end
end


assign VCF = tile_color;
assign VCB = tile_pixel;


reg [3:0] tilemap_D = 4'd0;
always_ff @(posedge CK49) begin
	if(cen_6m)
		tilemap_D <= VCD;
end








wire [8:0] sprite_hpos = h_cnt;
wire [8:0] sprite_vpos = flipscreen ? v_cnt + 9'd17 : v_cnt + 9'd18;


reg [5:0] sprite_index;
reg [1:0] sprite_offset;
reg [2:0] sprite_fsm_state;
reg [8:0] sprite_x, sprite_code;
reg [7:0] sprite_y;
reg [4:0] sprite_width;
reg [3:0] sprite_color;
reg sprite_hflip, sprite_vflip;
always_ff @(posedge CK49) begin
	if(sprite_hpos == 9'd0) begin
		sprite_width <= 5'd0;
		sprite_index <= 6'd0;
		sprite_offset <= 2'd3;
		sprite_fsm_state <= 3'd1;
	end
	else 
		case(sprite_fsm_state)
			0:;
			1: begin


				if(sprite_index > 8'd47)
					sprite_fsm_state <= 3'd0;
				else begin
					sprite_y <= spriteram_Dcache;
					sprite_offset <= 2'd2;
					sprite_fsm_state <= sprite_fsm_state + 3'd1;
				end
			end
			2: begin

				if(sprite_active) begin
					sprite_x[7:0] <= spriteram_Dcache;
					sprite_offset <= 2'd1;
					sprite_fsm_state <= sprite_fsm_state + 3'd1;
				end
				else begin
					sprite_index <= sprite_index + 6'd1;
					sprite_offset <= 2'd3;
					sprite_fsm_state <= 3'd1;
				end
			end
			3: begin

				sprite_x[8] <= spriteram_Dcache[7];
				sprite_code[8] <= spriteram_Dcache[6];
				sprite_vflip <= spriteram_Dcache[5] ^ flipscreen;
				sprite_hflip <= spriteram_Dcache[4] ^ flipscreen;
				sprite_color <= spriteram_Dcache[3:0];
				sprite_offset <= 2'd0;
				sprite_fsm_state <= sprite_fsm_state + 3'd1;
			end
			4: begin

				sprite_code[7:0] <= spriteram_Dcache;
				sprite_offset <= 2'd3;
				sprite_index <= sprite_index + 6'd1;
				sprite_width <= 5'b10000;
				sprite_fsm_state <= sprite_fsm_state + 3'd1;
			end
			5: begin
				sprite_width <= sprite_width + 5'd1;
				sprite_fsm_state <= wre ? sprite_fsm_state : 3'd1;
			end
			default:;
		endcase
end


wire [8:0] sprite_height = {1'b0, sprite_y} - sprite_vpos;


wire sprite_active = (sprite_y != 0) & (sprite_height[8:5] == 4'b1111) & (sprite_height[4] ^ ~flipscreen);

wire [3:0] lx = sprite_width[3:0] ^ {4{sprite_hflip}};
wire [3:0] ly = sprite_height[3:0] ^ {4{~sprite_vflip}};


assign S = {sprite_code, ly[3], lx[3], ly[2:0], lx[2:1]};


wire [3:0] sprite_pixel = lx[0] ? SD[3:0] : SD[7:4];




reg sprite_bank = 0;
reg old_vsync;
always_ff @(posedge CK49) begin
	old_vsync <= VSYC;
	if(!RES)
		sprite_bank <= 0;
	else if(!old_vsync && VSYC)
		sprite_bank <= ~(reg3[3] ^ SPFL);
end

wire [7:0] spriteram_A = {sprite_index, sprite_offset};


assign OCF = sprite_color;
assign OCB = sprite_pixel;







wire wre = sprite_width[4];


wire sprite_lbuff_bank = sprite_vpos[0];


wire [8:0] wpx = sprite_x + sprite_width[3:0];


reg [9:0] lbuff_A;
reg [3:0] lbuff_Din;
reg lbuff_we;
always_ff @(posedge CK49) begin
	lbuff_A <= {~sprite_lbuff_bank, wpx};
	lbuff_we <= wre;
end


always_ff @(negedge CK49) begin
	lbuff_Din <= OCD;
end


reg [9:0] radr0 = 10'd0;
reg [9:0] radr1 = 10'd1;
always_ff @(posedge CK49) begin
	if(cen_6m)
		radr0 <= {sprite_lbuff_bank, flipscreen ? sprite_hpos - 9'd241 : sprite_hpos};
end


wire [3:0] lbuff_Dout;
dpram_dc #(.widthad_a(10)) LBUFF
(
	.clock_a(CK49),
	.address_a(lbuff_A),
	.data_a({4'd0, lbuff_Din}),
	.wren_a(lbuff_we & (lbuff_Din != 0)),
	
	.clock_b(CK49),
	.address_b(radr0),
	.data_b(8'h0),
	.wren_b(radr0 == radr1),
	.q_b({4'bZZZZ, lbuff_Dout})
);


wire lbuff_read_en = (div[2:0] == 3'b100);
reg [3:0] sprite_D = 4'd0;
always_ff @(posedge CK49) begin
	if(lbuff_read_en) begin
		if(radr0 != radr1)
			sprite_D <= lbuff_Dout;
		radr1 <= radr0;
	end
end




wire tile_sprite_sel = (tilemap_en | ~(|sprite_D));
wire [3:0] tile_sprite_D = tile_sprite_sel ? tilemap_D : sprite_D;


reg [4:0] pixel_D;
always_ff @(posedge CK49) begin
	if(cen_6m)
		pixel_D <= {tile_sprite_sel, tile_sprite_D};
end


assign COL = hmask ? 5'd0 : pixel_D;

endmodule