data/full_repos/permissive/432661124/HW/system_2MB.v
1: b'%Warning-WIDTH: data/full_repos/permissive/432661124/HW/system_2MB.v:194: Operator EQ expects 16 bits on the RHS, but RHS\'s CONST \'12\'h97\' generates 12 bits.\n                                                                        : ... In instance system_2MB\n wire CPU_SPEED_OE = PORT_ADDR[15:0] == 12\'h0097; \n                                     ^~\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/432661124/HW/system_2MB.v:205: Operator EQ expects 16 bits on the LHS, but LHS\'s SEL generates 15 bits.\n                                                                        : ... In instance system_2MB\n wire ADLIB_OE = PORT_ADDR[15:1] == (16\'h0388 >> 1);  \n                                 ^~\n%Warning-WIDTH: data/full_repos/permissive/432661124/HW/system_2MB.v:269: Operator AND expects 17 bits on the LHS, but LHS\'s VARREF \'timer_spk\' generates 1 bits.\n                                                                        : ... In instance system_2MB\n wire [16:0]sndmix = (({opl2snd[15], opl2snd}) << 2) + ((timer_spk & speaker_on[1]) << 15);  \n                                                                   ^\n%Warning-WIDTH: data/full_repos/permissive/432661124/HW/system_2MB.v:269: Operator AND expects 17 bits on the RHS, but RHS\'s SEL generates 1 bits.\n                                                                        : ... In instance system_2MB\n wire [16:0]sndmix = (({opl2snd[15], opl2snd}) << 2) + ((timer_spk & speaker_on[1]) << 15);  \n                                                                   ^\n%Error: data/full_repos/permissive/432661124/HW/system_2MB.v:319: Cannot find file containing module: \'cga_vgaport\'\n    cga_vgaport vga (\n    ^~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/432661124/HW,data/full_repos/permissive/432661124/cga_vgaport\n             data/full_repos/permissive/432661124/HW,data/full_repos/permissive/432661124/cga_vgaport.v\n             data/full_repos/permissive/432661124/HW,data/full_repos/permissive/432661124/cga_vgaport.sv\n             cga_vgaport\n             cga_vgaport.v\n             cga_vgaport.sv\n             obj_dir/cga_vgaport\n             obj_dir/cga_vgaport.v\n             obj_dir/cga_vgaport.sv\n%Error: data/full_repos/permissive/432661124/HW/system_2MB.v:327: Cannot find file containing module: \'cga\'\n    cga cga1 (\n    ^~~\n%Error: data/full_repos/permissive/432661124/HW/system_2MB.v:352: Cannot find file containing module: \'SRAM_8bit\'\n SRAM_8bit SRAM\n ^~~~~~~~~\n%Error: data/full_repos/permissive/432661124/HW/system_2MB.v:385: Cannot find file containing module: \'BRAM_8KB_BIOS\'\n BRAM_8KB_BIOS BIOS\n ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/432661124/HW/system_2MB.v:394: Cannot find file containing module: \'BRAM_32KB_CRTC\'\n BRAM_32KB_CRTC VRAM\n ^~~~~~~~~~~~~~\n%Warning-WIDTH: data/full_repos/permissive/432661124/HW/system_2MB.v:416: Operator SUB expects 32 bits on the RHS, but RHS\'s SEL generates 25 bits.\n                                                                        : ... In instance system_2MB\n  sndval <= sndval - sndval[31:7] + (sndsign << 25);    \n                   ^\n%Warning-WIDTH: data/full_repos/permissive/432661124/HW/system_2MB.v:416: Operator SHIFTL expects 32 bits on the LHS, but LHS\'s VARREF \'sndsign\' generates 1 bits.\n                                                                        : ... In instance system_2MB\n  sndval <= sndval - sndval[31:7] + (sndsign << 25);    \n                                             ^~\n%Error: data/full_repos/permissive/432661124/HW/system_2MB.v:434: Cannot find file containing module: \'cache_controller\'\n cache_controller cache_ctl \n ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/432661124/HW/system_2MB.v:457: Cannot find file containing module: \'KB_Mouse_8042\'\n KB_Mouse_8042 KB_Mouse \n ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/432661124/HW/system_2MB.v:493: Cannot find file containing module: \'PIC_8259\'\n PIC_8259 PIC \n ^~~~~~~~\n%Error: data/full_repos/permissive/432661124/HW/system_2MB.v:509: Cannot find file containing module: \'unit186\'\n unit186 CPUUnit\n ^~~~~~~\n%Error: data/full_repos/permissive/432661124/HW/system_2MB.v:536: Cannot find file containing module: \'seg_map_2MB\'\n seg_map_2MB seg_mapper \n ^~~~~~~~~~~\n%Error: data/full_repos/permissive/432661124/HW/system_2MB.v:551: Cannot find file containing module: \'timer_8253\'\n timer_8253 timer \n ^~~~~~~~~~\n%Error: data/full_repos/permissive/432661124/HW/system_2MB.v:565: Cannot find file containing module: \'jtopl2\'\n jtopl2 opl2 (\n ^~~~~~\n%Error: data/full_repos/permissive/432661124/HW/system_2MB.v:578: Cannot find file containing module: \'bootcore\'\n bootcore bootcore (\n ^~~~~~~~\n%Error: Exiting due to 13 error(s), 6 warning(s)\n'
module system_2MB
	(		 	 
		 input clk_vga,
		 input clk_cpu_base,		 
		 input clk_sdr,
		 input clk_sram,		 
		 input clk_25,
		 output [20:0]SRAM_ADDR,
		 inout [7:0]SRAM_DATA,
		 output SRAM_WE_n,
		 output wire [5:0]VGA_R,
		 output wire [5:0]VGA_G,
		 output wire [5:0]VGA_B,
		 output wire VGA_HSYNC,
		 output wire VGA_VSYNC,		 
		 output LED,
		 output reg SD_n_CS = 1,
		 output wire SD_DI,
		 output reg SD_CK = 0,
		 input SD_DO,		 
		 output AUD_L,
		 output AUD_R,
	 	 inout PS2_CLK1,
		 inout PS2_CLK2,
		 inout PS2_DATA1,
		 inout PS2_DATA2,
		 output wire [1:0] monochrome_switcher,
		 input  wire joy_up,
		 input  wire joy_down,
		 input  wire joy_left,
		 input  wire joy_right,
		 input  wire joy_fire1,
		 input  wire joy_fire2
		 		 
    );
		 
	wire [15:0]sys_DIN;
	wire [15:0]sys_DOUT;
	wire sys_rd_data_valid;
	wire sys_wr_data_valid;   
	wire [12:0]waddr;
	wire [31:0] DOUT;
	wire [15:0]CPU_DOUT;
	wire [15:0]PORT_ADDR;
	wire [31:0] DRAM_dout;
	wire [20:0] ADDR;
	wire IORQ;
	wire WR;
	wire INTA;
	wire WORD;
	wire [3:0] RAM_WMASK;
	
	wire VRAM8_ENABLE;
	wire [18:0] VRAM8_ADDR;	
	wire [7:0] VRAM8_DOUT;

	wire CPU_CE;
	wire CE;
	wire CE_186;
	wire ddr_rd; 
	wire ddr_wr;
		
	wire TIMER_OE = PORT_ADDR[15:2] == 14'b00000000010000;
	wire LED_PORT = PORT_ADDR[15:0] == 16'h03bc;
	wire SPEAKER_PORT = PORT_ADDR[15:0] == 16'h0061;
	wire CPU_SPEED_OE = PORT_ADDR[15:0] == 12'h0097;	
	wire MEMORY_SIZE = PORT_ADDR[15:0] == 16'h0098;
	wire PCXTCORENN = PORT_ADDR[15:0] == 16'h0099;	
	wire MEMORY_MAP = PORT_ADDR[15:4] == 12'h008;	
	wire RS232_OE = PORT_ADDR[15:0] == 16'h0001;
	wire SD_OE = PORT_ADDR[15:0] == 16'h0300;
	wire EMS_OE = PORT_ADDR[15:2] == 14'b00000010011000;
	wire RTC_SELECT = PORT_ADDR[15:0] == 16'h0070;	
	wire PIC_OE = PORT_ADDR[15:8] == 8'h00 && PORT_ADDR[6:1] == 6'b010000;
	wire KB_OE = PORT_ADDR[15:4] == 12'h006 && {PORT_ADDR[3], PORT_ADDR[1:0]} == 3'b000;
	wire JOYSTICK = PORT_ADDR[15:4] == 12'h020;
	wire ADLIB_OE = PORT_ADDR[15:1] == (16'h0388 >> 1);
	wire [15:0]PORT_IN;
	wire [7:0]TIMER_DOUT;
	wire [7:0]KB_DOUT;
	wire [7:0]PIC_DOUT;
	
	wire CRTC_OE;
	wire [7:0] CRTC_DOUT;	
	
	wire HALT;
	wire nmi_button;
	wire kbd_mreset;
	wire kbd_creset;
	
	reg [1:0] cpu_speed_io = 2'b1;	
	wire [1:0] cpu_speed_switcher;	
		
	reg [1:0]command = 0;
	reg [1:0]s_ddr_rd = 0;
	reg [1:0]s_ddr_wr = 0;
	wire coreset;

	reg s_RS232_DCE_RXD;
	reg s_RS232_HOST_RXD;
	reg [4:0]rstcount = 0;		
	reg [4:0]RTCDIV25 = 0;
	reg [1:0]RTCSYNC = 0;
	reg [15:0]RTC = 0;
	reg [15:0]RTCSET = 0;
	wire RTCEND = RTC == RTCSET;
	wire RTCDIVEND = RTCDIV25 == 24;
	reg [12:0]cache_hi_addr;
	wire [7:0]memmap;
	wire [6:0]memmap_mux;	
	wire f_map_to_f;
	wire oncursor;
	wire [11:0]cursorpos;
	wire [15:0]scraddr;
	reg flash_on;
	reg [1:0] speaker_on = 0;
	reg [9:0]rNMI = 0;
	
	reg [2:0] div_clk_cpu = 3'd0;
	reg [18:0]sysaddr;
	reg [2:0]auto_flush = 3'b000;
	wire clk_cpu;
		
	assign clk_cpu = div_clk_cpu[cpu_speed_switcher];
	
	assign LED = ~SD_n_CS;


		

	reg [15:0]NMIonIORQ_LO = 16'h0001;
	reg [15:0]NMIonIORQ_HI = 16'h0000;
	

	reg ce_opl2 = 1'b0;
	reg [7:0] opl2_cen_cnt = 8'd0;
   wire [7:0]opl2data;	
   wire [15:0]opl2snd;
	reg [31:0]sndval = 0;
	
	wire [16:0]sndmix = (({opl2snd[15], opl2snd}) << 2) + ((timer_spk & speaker_on[1]) << 15);
	wire [15:0]sndamp = (~|sndmix[16:15] | &sndmix[16:15]) ? {!sndmix[15], sndmix[14:0]} : {16{!sndmix[16]}};
	wire sndsign = sndval[31:16] < sndamp;
	

	reg [7:0]SDI;
	assign SD_DI = CPU_DOUT[7];

	assign PORT_IN[15:8] = 
		({8{SD_OE}} & SDI);


	assign PORT_IN[7:0] = 							 							 
							 ({8{KB_OE}} & KB_DOUT) |
							 ({8{SD_OE}} & {8'b1x000000}) |
							 ({8{SPEAKER_PORT}} & {6'd0, speaker_on}) |
							 ({8{CRTC_OE}} & CRTC_DOUT) |
							 ({8{MEMORY_SIZE}} & 8'd2) |
							 ({8{MEMORY_MAP}} & memmap) |
							 ({8{EMS_OE}} & memmap) |							 
							 ({8{TIMER_OE}} & TIMER_DOUT) |
							 ({8{PIC_OE}} & PIC_DOUT) |
							 ({8{LED_PORT}} & {7'b0000000,LED}) |
							 ({8{ADLIB_OE}} & opl2data)  |
							 ({8{JOYSTICK}});




    parameter MDA_70HZ = 0;    

    wire[7:0] bus_out;

    wire[3:0] video;
    wire[3:0] vga_video;


    wire thin_font;

    wire[5:0] vga_red;
    wire[5:0] vga_green;
    wire[5:0] vga_blue;



	 

	 assign thin_font = 1'b0;
    	 

    cga_vgaport vga (
        .clk(clk_vga),
        .video(vga_video),		  
        .red(VGA_R),
        .green(VGA_G),
        .blue(VGA_B)
    );    

    cga cga1 (
        .clk(clk_vga),        
		  .bus_a(PORT_ADDR),        
		  .bus_ior_l(WR),
        .bus_iow_l(~WR),
        .bus_memr_l(1'd0),
        .bus_memw_l(1'd0),
		  .word(WORD),
        .bus_d(CPU_DOUT),
        .bus_out(CRTC_DOUT),
        .bus_dir(CRTC_OE),
        .bus_aen(~(IORQ & CPU_CE)),        
        .ram_we_l(VRAM8_ENABLE),
        .ram_a(VRAM8_ADDR),
        .ram_d(VRAM8_DOUT),        
        .dbl_hsync(VGA_HSYNC),
        .vsync(VGA_VSYNC),
        .video(video),
        .dbl_video(vga_video),
        .comp_video(comp_video),
        .thin_font(thin_font)
    );

	defparam cga1.BLINK_MAX = 24'd4772727;

	SRAM_8bit SRAM
	(
		.sys_CLK(clk_sdr),
		.sys_CMD(command),
		.sys_ADDR(sysaddr),
		.sys_DIN(sys_DIN),
		.sys_DOUT(sys_DOUT),
		.sys_rd_data_valid(sys_rd_data_valid),
		.sys_wr_data_valid(sys_wr_data_valid),
		
		.sram_clk(clk_sram),
		.sram_n_WE(SRAM_WE_n),
		.sram_ADDR(SRAM_ADDR),
		.sram_DATA(SRAM_DATA)
	);
	
	parameter crtc_addr = 6'b010111;
	parameter bios_addr_fe000 = 8'b01111111;
		
	wire MREQ;
   wire CRTCVRAM = (ADDR[20:15] == crtc_addr);	
	wire BIOSROM = ((ADDR[20:13] == bios_addr_fe000) & f_map_to_f);	
	
	wire CACHE_EN = ~(CRTCVRAM | BIOSROM);
	wire CACHE_MREQ = MREQ & CACHE_EN;
	
	wire [31:0] vram_dout;
	wire [31:0] bios_dout;
	wire [31:0] CPU_DIN;	
	reg s_cache_mreq;
		
	assign CPU_DIN	= s_cache_mreq ? DRAM_dout : CRTCVRAM ? vram_dout : bios_dout;
	
	BRAM_8KB_BIOS BIOS
	(
	  .clka(clk_cpu),
	  .ena(BIOSROM),
	  .addra(ADDR[12:2]),
	  .douta(bios_dout)

	);
			
	BRAM_32KB_CRTC VRAM
	(
	  .clka(clk_cpu),
	  .ena(CRTCVRAM),
	  .wea(RAM_WMASK),
	  .addra(ADDR[14:2]),
	  .dina(DOUT),
	  .douta(vram_dout),
	  .clkb(clk_vga),
	  .web(1'b0),
	  .enb(VRAM8_ENABLE),
	  .addrb(VRAM8_ADDR[14:0]),
	  .dinb(8'h0),
	  .doutb(VRAM8_DOUT)

	);
	
	
	always @ (posedge clk_cpu_base)
		div_clk_cpu <= div_clk_cpu + 3'd1;	

  always @(posedge clk_vga) begin
		sndval <= sndval - sndval[31:7] + (sndsign << 25);				
		opl2_cen_cnt <= opl2_cen_cnt + 8'd1;
		if(opl2_cen_cnt >= 8'd7)
			opl2_cen_cnt  <= 8'd0;
		ce_opl2 <= (opl2_cen_cnt < 8'd4) ? 1'b1 : 1'b0;	
  end

  
  always @(posedge clk_25) begin
		if(RTCDIVEND) RTCDIV25 <= 0;
		else RTCDIV25 <= RTCDIV25 + 1;  
				
		if(!nmi_button) rNMI <= 0;
		else if(!rNMI[9] && RTCDIVEND) rNMI <= rNMI + 1'b1;
		
	end		
	
	
	cache_controller cache_ctl 
	(
		 .addr(ADDR), 
		 .dout(DRAM_dout), 
		 .din(DOUT), 
		 .clk(clk_cpu),
		 .mreq(CACHE_MREQ), 
		 .wmask(RAM_WMASK),
		 .ce(CE), 
		 .ddr_din(sys_DOUT), 
		 .ddr_dout(sys_DIN), 
		 .ddr_clk(clk_sdr), 
		 .ddr_rd(ddr_rd), 
		 .ddr_wr(ddr_wr),
		 .waddr(waddr),
		 .cache_write_data(sys_rd_data_valid),
		 .cache_read_data(sys_wr_data_valid)

	);

	wire I_KB;
	wire I_MOUSE;
	wire KB_RST;
	KB_Mouse_8042 KB_Mouse 
	(
		 .CS(IORQ && CPU_CE && KB_OE),
		 .WR(WR), 
		 .cmd(PORT_ADDR[2]),
		 .din(CPU_DOUT[7:0]), 
		 .dout(KB_DOUT), 
		 .clk(div_clk_cpu[0]),
		 .I_KB(I_KB), 
		 .I_MOUSE(I_MOUSE), 
		 .CPU_RST(KB_RST), 
		 .PS2_CLK1(PS2_CLK1), 
		 .PS2_CLK2(PS2_CLK2), 
		 .PS2_DATA1(PS2_DATA1), 
		 .PS2_DATA2(PS2_DATA2),
		 .monochrome_switcher(monochrome_switcher),
		 .cpu_speed_switcher(cpu_speed_switcher),		 
		 .nmi_button(nmi_button),
		 .cpu_speed_io(IORQ && CPU_CE && WR && ~WORD && CPU_SPEED_OE),
		 .cpu_speed(CPU_DOUT[1:0]),
		 .kbd_mreset(kbd_mreset),
		 .kbd_creset(kbd_creset),
		 .joy_up(joy_up),
		 .joy_down(joy_down),
		 .joy_left(joy_left),
		 .joy_right(joy_right),
		 .joy_fire1(joy_fire1),
		 .joy_fire2(joy_fire2),
		 .coreset(coreset)
		 
	);
	
	wire [7:0]PIC_IVECT;
	wire INT;
	wire timer_int;
	wire I_COM1;
	PIC_8259 PIC 
	(
		 .RST(!rstcount[4]),
		 .CS(PIC_OE && IORQ && CPU_CE),
		 .A(PORT_ADDR[0]),
		 .WR(WR), 
		 .din(CPU_DOUT[7:0]), 
		 .slave(PORT_ADDR[7]),
		 .dout(PIC_DOUT), 
		 .ivect(PIC_IVECT), 
		 .clk(clk_cpu),
		 .INT(INT), 
		 .IACK(INTA & CPU_CE), 
		 .I({I_COM1, I_MOUSE, RTCEND, I_KB, timer_int})
    );

	unit186 CPUUnit
	(
		 .INPORT(INTA ? {8'h00, PIC_IVECT} : PORT_IN), 
		 .DIN(CPU_DIN), 
		 .CPU_DOUT(CPU_DOUT),
		 .PORT_ADDR(PORT_ADDR),
		 .DOUT(DOUT), 
		 .ADDR(ADDR), 
		 .WMASK(RAM_WMASK), 
		 .CLK(clk_cpu),
		 .CE(CE), 
		 .CPU_CE(CPU_CE),
		 .CE_186(CE_186),
		 .INTR(INT), 

		 .NMI(CPU_CE && IORQ && PORT_ADDR >= NMIonIORQ_LO && PORT_ADDR <= NMIonIORQ_HI),
		 .RST(!rstcount[4]), 
		 .INTA(INTA), 
		 .LOCK(LOCK), 
		 .HALT(HALT), 
		 .MREQ(MREQ),
		 .IORQ(IORQ),
		 .WR(WR),
		 .WORD(WORD),
		 .FASTIO(1'b1)
	);
	
	seg_map_2MB seg_mapper 
	(
		 .CLK(clk_cpu),
		 .cpuaddr(PORT_ADDR[3:0]), 
		 .cpurdata(memmap), 
		 .cpuwdata(CPU_DOUT[7:0]), 
		 .memaddr(cache_hi_addr[11:6]),
		 .memdata(memmap_mux), 
		 .WE(MEMORY_MAP & WR & WORD & IORQ & CPU_CE),
		 .WE_EMS(EMS_OE & WR & IORQ & CPU_CE),
		 .EMS_OE(EMS_OE),
		 .f_map_to_f(f_map_to_f)
   );	

	wire timer_spk;
	timer_8253 timer 
	(
		 .CS(TIMER_OE && IORQ && CPU_CE), 
		 .WR(WR), 
		 .addr(PORT_ADDR[1:0]), 
		 .din(CPU_DOUT[7:0]), 
		 .dout(TIMER_DOUT), 
		 .CLK_25(clk_25),		 
		 .clk(clk_cpu),
		 .gate2(speaker_on[0]),
		 .out0(timer_int), 
		 .out2(timer_spk)
   );	
	
	jtopl2 opl2 (
		.rst(!rstcount[4]),
		.clk(div_clk_cpu[1]),
		.cen(ce_opl2),
		.din(CPU_DOUT[7:0]),
		.dout(opl2data),
		.addr(PORT_ADDR[0]),		
		.wr_n(~WR),
		.cs_n(~(IORQ & CPU_CE & ADLIB_OE)),
		.snd(opl2snd)		

	);
	
	bootcore bootcore (
    .clk_icap(clk_cpu),
    .coldreset(kbd_creset),
	 .masterreset(kbd_mreset),
	 .corenn(CPU_DOUT[7:0]),	 
	 .we(IORQ && CPU_CE && WR && ~WORD && PCXTCORENN),
	 .coreset(coreset)
   );	

	always @ (posedge clk_sdr) begin		
		s_ddr_rd <= {s_ddr_rd[0], ddr_rd};
		s_ddr_wr <= {s_ddr_wr[0], ddr_wr};
		cache_hi_addr <= s_ddr_wr[0] ? waddr : ADDR[20:8];
		sysaddr <= {memmap_mux, cache_hi_addr[5:0], 6'b000000};
		
		if(s_ddr_wr[1]) command <= 2'b01;
		else if(s_ddr_rd[1]) command <= 2'b11;
		else command <= 2'b00;
	end
	
	always @ (posedge clk_cpu) begin	
		s_cache_mreq <= CACHE_MREQ;		
		if(IORQ & CPU_CE) begin
			if(WR & SPEAKER_PORT) speaker_on <= CPU_DOUT[1:0];
		end		
		



	




		if(CPU_CE) begin
			SD_CK <= IORQ & SD_OE & WR & ~WORD;
			if(IORQ & SD_OE & WR) begin				
				if(WORD) SD_n_CS <= ~CPU_DOUT[8];
				else SDI <= {SDI[6:0], SD_DO};
			end
		end

		if(KB_RST) rstcount <= 0;
		else if(CPU_CE && ~rstcount[4]) rstcount <= rstcount + 1;
		

		RTCSYNC <= {RTCSYNC[0], RTCDIVEND};
		if(IORQ && CPU_CE && WR && WORD && RTC_SELECT) begin
			RTC <= 0;
			RTCSET <= CPU_DOUT;
		end else if(RTCSYNC == 2'b01) begin
			if(RTCEND) RTC <= 0;
			else RTC <= RTC + 1;
		end
		

	end
	
	assign AUD_L = sndsign;
	assign AUD_R = sndsign;
	
endmodule
module system_2MB
	(		 	 
		 input clk_vga,
		 input clk_cpu_base,		 
		 input clk_sdr,
		 input clk_sram,		 
		 input clk_25,
		 output [20:0]SRAM_ADDR,
		 inout [7:0]SRAM_DATA,
		 output SRAM_WE_n,
		 output wire [5:0]VGA_R,
		 output wire [5:0]VGA_G,
		 output wire [5:0]VGA_B,
		 output wire VGA_HSYNC,
		 output wire VGA_VSYNC,		 
		 output LED,
		 output reg SD_n_CS = 1,
		 output wire SD_DI,
		 output reg SD_CK = 0,
		 input SD_DO,		 
		 output AUD_L,
		 output AUD_R,
	 	 inout PS2_CLK1,
		 inout PS2_CLK2,
		 inout PS2_DATA1,
		 inout PS2_DATA2,
		 output wire [1:0] monochrome_switcher,
		 input  wire joy_up,
		 input  wire joy_down,
		 input  wire joy_left,
		 input  wire joy_right,
		 input  wire joy_fire1,
		 input  wire joy_fire2
		 		 
    );

		 
	wire [15:0]sys_DIN;
	wire [15:0]sys_DOUT;
	wire sys_rd_data_valid;
	wire sys_wr_data_valid;   
	wire [12:0]waddr;
	wire [31:0] DOUT;
	wire [15:0]CPU_DOUT;
	wire [15:0]PORT_ADDR;
	wire [31:0] DRAM_dout;
	wire [20:0] ADDR;
	wire IORQ;
	wire WR;
	wire INTA;
	wire WORD;
	wire [3:0] RAM_WMASK;
	
	wire VRAM8_ENABLE;
	wire [18:0] VRAM8_ADDR;	
	wire [7:0] VRAM8_DOUT;

	wire CPU_CE;
	wire CE;
	wire CE_186;
	wire ddr_rd; 
	wire ddr_wr;
		
	wire TIMER_OE = PORT_ADDR[15:2] == 14'b00000000010000;
	wire LED_PORT = PORT_ADDR[15:0] == 16'h03bc;
	wire SPEAKER_PORT = PORT_ADDR[15:0] == 16'h0061;
	wire CPU_SPEED_OE = PORT_ADDR[15:0] == 12'h0097;	
	wire MEMORY_SIZE = PORT_ADDR[15:0] == 16'h0098;
	wire PCXTCORENN = PORT_ADDR[15:0] == 16'h0099;	
	wire MEMORY_MAP = PORT_ADDR[15:4] == 12'h008;	
	wire RS232_OE = PORT_ADDR[15:0] == 16'h0001;
	wire SD_OE = PORT_ADDR[15:0] == 16'h0300;
	wire EMS_OE = PORT_ADDR[15:2] == 14'b00000010011000;
	wire RTC_SELECT = PORT_ADDR[15:0] == 16'h0070;	
	wire PIC_OE = PORT_ADDR[15:8] == 8'h00 && PORT_ADDR[6:1] == 6'b010000;
	wire KB_OE = PORT_ADDR[15:4] == 12'h006 && {PORT_ADDR[3], PORT_ADDR[1:0]} == 3'b000;
	wire JOYSTICK = PORT_ADDR[15:4] == 12'h020;
	wire ADLIB_OE = PORT_ADDR[15:1] == (16'h0388 >> 1);
	wire [15:0]PORT_IN;
	wire [7:0]TIMER_DOUT;
	wire [7:0]KB_DOUT;
	wire [7:0]PIC_DOUT;
	
	wire CRTC_OE;
	wire [7:0] CRTC_DOUT;	
	
	wire HALT;
	wire nmi_button;
	wire kbd_mreset;
	wire kbd_creset;
	
	reg [1:0] cpu_speed_io = 2'b1;	
	wire [1:0] cpu_speed_switcher;	
		
	reg [1:0]command = 0;
	reg [1:0]s_ddr_rd = 0;
	reg [1:0]s_ddr_wr = 0;
	wire coreset;

	reg s_RS232_DCE_RXD;
	reg s_RS232_HOST_RXD;
	reg [4:0]rstcount = 0;		
	reg [4:0]RTCDIV25 = 0;
	reg [1:0]RTCSYNC = 0;
	reg [15:0]RTC = 0;
	reg [15:0]RTCSET = 0;
	wire RTCEND = RTC == RTCSET;
	wire RTCDIVEND = RTCDIV25 == 24;
	reg [12:0]cache_hi_addr;
	wire [7:0]memmap;
	wire [6:0]memmap_mux;	
	wire f_map_to_f;
	wire oncursor;
	wire [11:0]cursorpos;
	wire [15:0]scraddr;
	reg flash_on;
	reg [1:0] speaker_on = 0;
	reg [9:0]rNMI = 0;
	
	reg [2:0] div_clk_cpu = 3'd0;
	reg [18:0]sysaddr;
	reg [2:0]auto_flush = 3'b000;
	wire clk_cpu;
		
	assign clk_cpu = div_clk_cpu[cpu_speed_switcher];
	
	assign LED = ~SD_n_CS;


		

	reg [15:0]NMIonIORQ_LO = 16'h0001;
	reg [15:0]NMIonIORQ_HI = 16'h0000;
	

	reg ce_opl2 = 1'b0;
	reg [7:0] opl2_cen_cnt = 8'd0;
   wire [7:0]opl2data;	
   wire [15:0]opl2snd;
	reg [31:0]sndval = 0;
	
	wire [16:0]sndmix = (({opl2snd[15], opl2snd}) << 2) + ((timer_spk & speaker_on[1]) << 15);
	wire [15:0]sndamp = (~|sndmix[16:15] | &sndmix[16:15]) ? {!sndmix[15], sndmix[14:0]} : {16{!sndmix[16]}};
	wire sndsign = sndval[31:16] < sndamp;
	

	reg [7:0]SDI;
	assign SD_DI = CPU_DOUT[7];

	assign PORT_IN[15:8] = 
		({8{SD_OE}} & SDI);


	assign PORT_IN[7:0] = 							 							 
							 ({8{KB_OE}} & KB_DOUT) |
							 ({8{SD_OE}} & {8'b1x000000}) |
							 ({8{SPEAKER_PORT}} & {6'd0, speaker_on}) |
							 ({8{CRTC_OE}} & CRTC_DOUT) |
							 ({8{MEMORY_SIZE}} & 8'd2) |
							 ({8{MEMORY_MAP}} & memmap) |
							 ({8{EMS_OE}} & memmap) |							 
							 ({8{TIMER_OE}} & TIMER_DOUT) |
							 ({8{PIC_OE}} & PIC_DOUT) |
							 ({8{LED_PORT}} & {7'b0000000,LED}) |
							 ({8{ADLIB_OE}} & opl2data)  |
							 ({8{JOYSTICK}});




    parameter MDA_70HZ = 0;    

    wire[7:0] bus_out;

    wire[3:0] video;
    wire[3:0] vga_video;


    wire thin_font;

    wire[5:0] vga_red;
    wire[5:0] vga_green;
    wire[5:0] vga_blue;



	 

	 assign thin_font = 1'b0;
    	 

    cga_vgaport vga (
        .clk(clk_vga),
        .video(vga_video),		  
        .red(VGA_R),
        .green(VGA_G),
        .blue(VGA_B)
    );    

    cga cga1 (
        .clk(clk_vga),        
		  .bus_a(PORT_ADDR),        
		  .bus_ior_l(WR),
        .bus_iow_l(~WR),
        .bus_memr_l(1'd0),
        .bus_memw_l(1'd0),
		  .word(WORD),
        .bus_d(CPU_DOUT),
        .bus_out(CRTC_DOUT),
        .bus_dir(CRTC_OE),
        .bus_aen(~(IORQ & CPU_CE)),        
        .ram_we_l(VRAM8_ENABLE),
        .ram_a(VRAM8_ADDR),
        .ram_d(VRAM8_DOUT),        
        .dbl_hsync(VGA_HSYNC),
        .vsync(VGA_VSYNC),
        .video(video),
        .dbl_video(vga_video),
        .comp_video(comp_video),
        .thin_font(thin_font)
    );

	defparam cga1.BLINK_MAX = 24'd4772727;

	SRAM_8bit SRAM
	(
		.sys_CLK(clk_sdr),
		.sys_CMD(command),
		.sys_ADDR(sysaddr),
		.sys_DIN(sys_DIN),
		.sys_DOUT(sys_DOUT),
		.sys_rd_data_valid(sys_rd_data_valid),
		.sys_wr_data_valid(sys_wr_data_valid),
		
		.sram_clk(clk_sram),
		.sram_n_WE(SRAM_WE_n),
		.sram_ADDR(SRAM_ADDR),
		.sram_DATA(SRAM_DATA)
	);
	
	parameter crtc_addr = 6'b010111;
	parameter bios_addr_fe000 = 8'b01111111;
		
	wire MREQ;
   wire CRTCVRAM = (ADDR[20:15] == crtc_addr);	
	wire BIOSROM = ((ADDR[20:13] == bios_addr_fe000) & f_map_to_f);	
	
	wire CACHE_EN = ~(CRTCVRAM | BIOSROM);
	wire CACHE_MREQ = MREQ & CACHE_EN;
	
	wire [31:0] vram_dout;
	wire [31:0] bios_dout;
	wire [31:0] CPU_DIN;	
	reg s_cache_mreq;
		
	assign CPU_DIN	= s_cache_mreq ? DRAM_dout : CRTCVRAM ? vram_dout : bios_dout;
	
	BRAM_8KB_BIOS BIOS
	(
	  .clka(clk_cpu),
	  .ena(BIOSROM),
	  .addra(ADDR[12:2]),
	  .douta(bios_dout)

	);
			
	BRAM_32KB_CRTC VRAM
	(
	  .clka(clk_cpu),
	  .ena(CRTCVRAM),
	  .wea(RAM_WMASK),
	  .addra(ADDR[14:2]),
	  .dina(DOUT),
	  .douta(vram_dout),
	  .clkb(clk_vga),
	  .web(1'b0),
	  .enb(VRAM8_ENABLE),
	  .addrb(VRAM8_ADDR[14:0]),
	  .dinb(8'h0),
	  .doutb(VRAM8_DOUT)

	);
	
	
	always @ (posedge clk_cpu_base)
		div_clk_cpu <= div_clk_cpu + 3'd1;	

  always @(posedge clk_vga) begin
		sndval <= sndval - sndval[31:7] + (sndsign << 25);				
		opl2_cen_cnt <= opl2_cen_cnt + 8'd1;
		if(opl2_cen_cnt >= 8'd7)
			opl2_cen_cnt  <= 8'd0;
		ce_opl2 <= (opl2_cen_cnt < 8'd4) ? 1'b1 : 1'b0;	
  end

  
  always @(posedge clk_25) begin
		if(RTCDIVEND) RTCDIV25 <= 0;
		else RTCDIV25 <= RTCDIV25 + 1;  
				
		if(!nmi_button) rNMI <= 0;
		else if(!rNMI[9] && RTCDIVEND) rNMI <= rNMI + 1'b1;
		
	end		
	
	
	cache_controller cache_ctl 
	(
		 .addr(ADDR), 
		 .dout(DRAM_dout), 
		 .din(DOUT), 
		 .clk(clk_cpu),
		 .mreq(CACHE_MREQ), 
		 .wmask(RAM_WMASK),
		 .ce(CE), 
		 .ddr_din(sys_DOUT), 
		 .ddr_dout(sys_DIN), 
		 .ddr_clk(clk_sdr), 
		 .ddr_rd(ddr_rd), 
		 .ddr_wr(ddr_wr),
		 .waddr(waddr),
		 .cache_write_data(sys_rd_data_valid),
		 .cache_read_data(sys_wr_data_valid)

	);

	wire I_KB;
	wire I_MOUSE;
	wire KB_RST;
	KB_Mouse_8042 KB_Mouse 
	(
		 .CS(IORQ && CPU_CE && KB_OE),
		 .WR(WR), 
		 .cmd(PORT_ADDR[2]),
		 .din(CPU_DOUT[7:0]), 
		 .dout(KB_DOUT), 
		 .clk(div_clk_cpu[0]),
		 .I_KB(I_KB), 
		 .I_MOUSE(I_MOUSE), 
		 .CPU_RST(KB_RST), 
		 .PS2_CLK1(PS2_CLK1), 
		 .PS2_CLK2(PS2_CLK2), 
		 .PS2_DATA1(PS2_DATA1), 
		 .PS2_DATA2(PS2_DATA2),
		 .monochrome_switcher(monochrome_switcher),
		 .cpu_speed_switcher(cpu_speed_switcher),		 
		 .nmi_button(nmi_button),
		 .cpu_speed_io(IORQ && CPU_CE && WR && ~WORD && CPU_SPEED_OE),
		 .cpu_speed(CPU_DOUT[1:0]),
		 .kbd_mreset(kbd_mreset),
		 .kbd_creset(kbd_creset),
		 .joy_up(joy_up),
		 .joy_down(joy_down),
		 .joy_left(joy_left),
		 .joy_right(joy_right),
		 .joy_fire1(joy_fire1),
		 .joy_fire2(joy_fire2),
		 .coreset(coreset)
		 
	);
	
	wire [7:0]PIC_IVECT;
	wire INT;
	wire timer_int;
	wire I_COM1;
	PIC_8259 PIC 
	(
		 .RST(!rstcount[4]),
		 .CS(PIC_OE && IORQ && CPU_CE),
		 .A(PORT_ADDR[0]),
		 .WR(WR), 
		 .din(CPU_DOUT[7:0]), 
		 .slave(PORT_ADDR[7]),
		 .dout(PIC_DOUT), 
		 .ivect(PIC_IVECT), 
		 .clk(clk_cpu),
		 .INT(INT), 
		 .IACK(INTA & CPU_CE), 
		 .I({I_COM1, I_MOUSE, RTCEND, I_KB, timer_int})
    );

	unit186 CPUUnit
	(
		 .INPORT(INTA ? {8'h00, PIC_IVECT} : PORT_IN), 
		 .DIN(CPU_DIN), 
		 .CPU_DOUT(CPU_DOUT),
		 .PORT_ADDR(PORT_ADDR),
		 .DOUT(DOUT), 
		 .ADDR(ADDR), 
		 .WMASK(RAM_WMASK), 
		 .CLK(clk_cpu),
		 .CE(CE), 
		 .CPU_CE(CPU_CE),
		 .CE_186(CE_186),
		 .INTR(INT), 

		 .NMI(CPU_CE && IORQ && PORT_ADDR >= NMIonIORQ_LO && PORT_ADDR <= NMIonIORQ_HI),
		 .RST(!rstcount[4]), 
		 .INTA(INTA), 
		 .LOCK(LOCK), 
		 .HALT(HALT), 
		 .MREQ(MREQ),
		 .IORQ(IORQ),
		 .WR(WR),
		 .WORD(WORD),
		 .FASTIO(1'b1)
	);
	
	seg_map_2MB seg_mapper 
	(
		 .CLK(clk_cpu),
		 .cpuaddr(PORT_ADDR[3:0]), 
		 .cpurdata(memmap), 
		 .cpuwdata(CPU_DOUT[7:0]), 
		 .memaddr(cache_hi_addr[11:6]),
		 .memdata(memmap_mux), 
		 .WE(MEMORY_MAP & WR & WORD & IORQ & CPU_CE),
		 .WE_EMS(EMS_OE & WR & IORQ & CPU_CE),
		 .EMS_OE(EMS_OE),
		 .f_map_to_f(f_map_to_f)
   );	

	wire timer_spk;
	timer_8253 timer 
	(
		 .CS(TIMER_OE && IORQ && CPU_CE), 
		 .WR(WR), 
		 .addr(PORT_ADDR[1:0]), 
		 .din(CPU_DOUT[7:0]), 
		 .dout(TIMER_DOUT), 
		 .CLK_25(clk_25),		 
		 .clk(clk_cpu),
		 .gate2(speaker_on[0]),
		 .out0(timer_int), 
		 .out2(timer_spk)
   );	
	
	jtopl2 opl2 (
		.rst(!rstcount[4]),
		.clk(div_clk_cpu[1]),
		.cen(ce_opl2),
		.din(CPU_DOUT[7:0]),
		.dout(opl2data),
		.addr(PORT_ADDR[0]),		
		.wr_n(~WR),
		.cs_n(~(IORQ & CPU_CE & ADLIB_OE)),
		.snd(opl2snd)		

	);
	
	bootcore bootcore (
    .clk_icap(clk_cpu),
    .coldreset(kbd_creset),
	 .masterreset(kbd_mreset),
	 .corenn(CPU_DOUT[7:0]),	 
	 .we(IORQ && CPU_CE && WR && ~WORD && PCXTCORENN),
	 .coreset(coreset)
   );	

	always @ (posedge clk_sdr) begin		
		s_ddr_rd <= {s_ddr_rd[0], ddr_rd};
		s_ddr_wr <= {s_ddr_wr[0], ddr_wr};
		cache_hi_addr <= s_ddr_wr[0] ? waddr : ADDR[20:8];
		sysaddr <= {memmap_mux, cache_hi_addr[5:0], 6'b000000};
		
		if(s_ddr_wr[1]) command <= 2'b01;
		else if(s_ddr_rd[1]) command <= 2'b11;
		else command <= 2'b00;
	end
	
	always @ (posedge clk_cpu) begin	
		s_cache_mreq <= CACHE_MREQ;		
		if(IORQ & CPU_CE) begin
			if(WR & SPEAKER_PORT) speaker_on <= CPU_DOUT[1:0];
		end		
		



	




		if(CPU_CE) begin
			SD_CK <= IORQ & SD_OE & WR & ~WORD;
			if(IORQ & SD_OE & WR) begin				
				if(WORD) SD_n_CS <= ~CPU_DOUT[8];
				else SDI <= {SDI[6:0], SD_DO};
			end
		end

		if(KB_RST) rstcount <= 0;
		else if(CPU_CE && ~rstcount[4]) rstcount <= rstcount + 1;
		

		RTCSYNC <= {RTCSYNC[0], RTCDIVEND};
		if(IORQ && CPU_CE && WR && WORD && RTC_SELECT) begin
			RTC <= 0;
			RTCSET <= CPU_DOUT;
		end else if(RTCSYNC == 2'b01) begin
			if(RTCEND) RTC <= 0;
			else RTC <= RTC + 1;
		end
		

	end
	
	assign AUD_L = sndsign;
	assign AUD_R = sndsign;
	
endmodule