/* ----------------------------------------------------------------[02.11.2014] u16-TSConf Version 0.2.9 DEVBOARD ReVerSE-U16 By MVV ---------------------------------------------------------------------------- V0.1.0 27.07.2014 первая версия V0.2.0 31.07.2014 добавлен транслятор PS/2, HDMI V0.2.1 03.08.2014 добавлен Delta-Sigma DAC, I2C V0.2.3 11.08.2014 добавлен enc424j600 V0.2.4 24.08.2014 добавлена поддержка IDE Video DAC (zports.v, video_out.v) V0.2.5 07.09.2014 добавлен порт #0001=key_scan, изменения в keyboard.vhd V0.2.6 09.09.2014 исправлен вывод палитры в (lut.vhd) V0.2.7 13.09.2014 дрожание мультиколора на tv80s, заменил на t80s V0.2.8 19.10.2014 инвентирован CLK в модулях video_tmbuf, video_sfile и добавлены регистры на выходе V0.2.9 02.11.2014 замена t80s, исправления в zint.v, zports.v, delta-sigma (приводит к намагничиванию динамиков) WXEDA 10.03.2015 порт на девборду WXEDA http://tslabs.info/forum/viewtopic.php?f=31&t=401 http://zx-pk.ru/showthread.php?t=23528 Copyright (c) 2014 MVV, TS-Labs, dsp, waybester, palsw All rights reserved Redistribution and use in source and synthezised forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in synthesized form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written agreement from the author. * License is granted for non-commercial use only. A fee may not be charged for redistributions as source code or in synthesized/hardware form without specific prior written agreement from the author. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ module tsconf ( // Clocks input clk_84mhz, input clk_28mhz, // SDRAM (32MB 16x16bit) inout [15:0] SDRAM_DQ, output [12:0] SDRAM_A, output [1:0] SDRAM_BA, output SDRAM_DQML, output SDRAM_DQMH, output SDRAM_WE_N, output SDRAM_CAS_N, output SDRAM_RAS_N, output SDRAM_CKE, output SDRAM_CS_N, // VGA output [7:0] VGA_R, output [7:0] VGA_G, output [7:0] VGA_B, output VGA_HS, output VGA_VS, output VGA_HBLANK, output VGA_VBLANK, output VGA_CEPIX, // SD/MMC Memory Card input SD_SO, output SD_SI, output SD_CLK, output SD_CS_N, // General Sound output [20:0] GS_ADDR, output [7:0] GS_DI, input [7:0] GS_DO, output GS_RD, output GS_WR, input GS_WAIT, // Audio output [15:0] SOUND_L, output [15:0] SOUND_R, // Misc. I/O input COLD_RESET, input WARM_RESET, output RESET_OUT, input [64:0] RTC, input [31:0] CMOSCfg, input OUT0, // PS/2 Keyboard input [10:0] PS2_KEY, input [24:0] PS2_MOUSE, input [5:0] joystick, input [15:0] loader_addr, input [7:0] loader_data, input loader_wr ); // CPU0 wire [15:0] cpu_a_bus; wire [7:0] cpu_do_bus; wire [7:0] cpu_di_bus; wire cpu_mreq_n; wire cpu_iorq_n; wire cpu_wr_n; wire cpu_rd_n; wire cpu_int_n_TS; wire cpu_m1_n; wire cpu_rfsh_n; wire [1:0] turbo; wire [7:0] im2vect; // zsignal wire cpu_stall; // zmem -> zclock wire cpu_req; // zmem -> arbiter wire cpu_wrbsel; // zmem -> arbiter wire cpu_next; // arbiter -> zmem wire cpu_current; // arbiter -> zmem wire cpu_strobe; // arbiter -> zmem wire cpu_latch; // arbiter -> zmem wire [23:0] cpu_addr; wire [20:0] cpu_addr_20; wire csvrom; wire curr_cpu; // SDRAM wire [7:0] sdr_do_bus; wire [15:0] sdr_do_bus_16; wire [15:0] sdr2cpu_do_bus_16; wire sdr_wr; wire sdr_rd; wire req; wire rnw; wire [23:0] dram_addr; wire [1:0] dram_bsel; wire [15:0] dram_wrdata; wire dram_req; wire dram_rnw; wire dos; wire [7:0] gluclock_addr; // clock wire f0; wire f1; wire h0; wire h1; wire c0; wire c1; wire c2; wire c3; wire zclk; wire zpos; wire zneg; wire vdos; wire pre_vdos; wire vdos_off; wire vdos_on; wire dos_change; wire m1; wire rd; wire wr; wire iorq; wire mreq; wire rdwr; wire iord; wire iowr; wire iorw; wire memrd; wire memwr; wire opfetch; wire intack; wire iorq_s; wire iord_s; wire iowr_s; wire iorw_s; wire memwr_s; wire opfetch_s; // zports OUT wire [7:0] dout_ports; wire ena_ports; wire [31:0] xt_page; wire [4:0] fmaddr; wire [7:0] sysconf; wire [7:0] memconf; wire [7:0] intmask; wire [8:0] dmaport_wr; wire go_arbiter; wire [3:0] cacheconf; // z80 wire [15:0] zmd; wire [7:0] zma; wire cram_we; wire sfile_we; wire zborder_wr; wire border_wr; wire zvpage_wr; wire vpage_wr; wire vconf_wr; wire gx_offsl_wr; wire gx_offsh_wr; wire gy_offsl_wr; wire gy_offsh_wr; wire t0x_offsl_wr; wire t0x_offsh_wr; wire t0y_offsl_wr; wire t0y_offsh_wr; wire t1x_offsl_wr; wire t1x_offsh_wr; wire t1y_offsl_wr; wire t1y_offsh_wr; wire tsconf_wr; wire palsel_wr; wire tmpage_wr; wire t0gpage_wr; wire t1gpage_wr; wire sgpage_wr; wire hint_beg_wr; wire vint_begl_wr; wire vint_begh_wr; // ZX controls wire res; wire int_start_frm; wire int_start_lin; // DRAM interface wire [20:0] video_addr; wire [4:0] video_bw; wire video_go; wire video_next; wire video_pre_next; wire next_video; wire video_strobe; wire video_next_strobe; // TS wire [20:0] ts_addr; wire ts_req; wire ts_z80_lp; // IN wire ts_pre_next; wire ts_next; // TM wire [20:0] tm_addr; wire tm_req; wire tm_next; // DMA wire dma_rnw; wire dma_req; wire dma_z80_lp; wire [15:0] dma_wrdata; wire [20:0] dma_addr; wire dma_next; wire dma_act; wire dma_cram_we; wire dma_sfile_we; // zmap wire [15:0] dma_data; wire [7:0] dma_wraddr; wire int_start_dma; // SPI wire spi_stb; wire spi_start; wire dma_spi_req; wire [7:0] dma_spi_din; wire cpu_spi_req; wire [7:0] cpu_spi_din; wire [7:0] spi_dout; wire [7:0] mouse_do; clock TS01 ( .clk(clk_28mhz), .f0(f0), .f1(f1), .h0(h0), .h1(h1), .c0(c0), .c1(c1), .c2(c2), .c3(c3) ); zclock TS02 ( .clk(clk_28mhz), .c1(c1), .c3(c3), .c14Mhz(c1), .zclk_out(zclk), .zpos(zpos), .zneg(zneg), .iorq_s(iorq_s), .dos_on(dos_change), .vdos_off(vdos_off), .cpu_stall(cpu_stall), .ide_stall(0), .external_port(0), .turbo(turbo) ); T80s CPU ( .RESET_n(~reset), .CLK_n(zclk), .INT_n(cpu_int_n_TS), .M1_n(cpu_m1_n), .MREQ_n(cpu_mreq_n), .IORQ_n(cpu_iorq_n), .RD_n(cpu_rd_n), .WR_n(cpu_wr_n), .RFSH_n(cpu_rfsh_n), .OUT0(OUT0), .A(cpu_a_bus), .DI(cpu_di_bus), .DO(cpu_do_bus) ); zsignals TS04 ( .clk(clk_28mhz), .zpos(zpos), .iorq_n(cpu_iorq_n), .mreq_n(cpu_mreq_n), .m1_n(cpu_m1_n), .rfsh_n(cpu_rfsh_n), .rd_n(cpu_rd_n), .wr_n(cpu_wr_n), .rd(rd), .wr(wr), .iorq(iorq), .mreq(mreq), .rdwr(rdwr), .iord(iord), .iowr(iowr), .iorw(iorw), .memrd(memrd), .memwr(memwr), .opfetch(opfetch), .intack(intack), .iorq_s(iorq_s), .iord_s(iord_s), .iowr_s(iowr_s), .iorw_s(iorw_s), .memwr_s(memwr_s), .opfetch_s(opfetch_s) ); zports TS05 ( .zclk(zclk), .clk(clk_28mhz), .din(cpu_do_bus), .dout(dout_ports), .dataout(ena_ports), .a(cpu_a_bus), .rst(reset), .loader(0), //loader, -- for load ROM, SPI should be enable .opfetch(opfetch), // from zsignals .rd(rd), .wr(wr), .rdwr(rdwr), .iorq(iorq), .iorq_s(iorq_s), .iord(iord), .iord_s(iord_s), .iowr(iowr), .iowr_s(iowr_s), .iorw(iorw), .iorw_s(iorw_s), .external_port(), // asserts for AY and VG93 accesses .zborder_wr(zborder_wr), .border_wr(border_wr), .zvpage_wr(zvpage_wr), .vpage_wr(vpage_wr), .vconf_wr(vconf_wr), .gx_offsl_wr(gx_offsl_wr), .gx_offsh_wr(gx_offsh_wr), .gy_offsl_wr(gy_offsl_wr), .gy_offsh_wr(gy_offsh_wr), .t0x_offsl_wr(t0x_offsl_wr), .t0x_offsh_wr(t0x_offsh_wr), .t0y_offsl_wr(t0y_offsl_wr), .t0y_offsh_wr(t0y_offsh_wr), .t1x_offsl_wr(t1x_offsl_wr), .t1x_offsh_wr(t1x_offsh_wr), .t1y_offsl_wr(t1y_offsl_wr), .t1y_offsh_wr(t1y_offsh_wr), .tsconf_wr(tsconf_wr), .palsel_wr(palsel_wr), .tmpage_wr(tmpage_wr), .t0gpage_wr(t0gpage_wr), .t1gpage_wr(t1gpage_wr), .sgpage_wr(sgpage_wr), .hint_beg_wr(hint_beg_wr), .vint_begl_wr(vint_begl_wr), .vint_begh_wr(vint_begh_wr), .xt_page(xt_page), .fmaddr(fmaddr), .sysconf(sysconf), .memconf(memconf), .cacheconf(cacheconf), .intmask(intmask), .dmaport_wr(dmaport_wr), // dmaport_wr .dma_act(dma_act), // from DMA (status of DMA) .dos(dos), .vdos(vdos), .vdos_on(vdos_on), .vdos_off(vdos_off), .rstrom(2'b11), .tape_read(1), .keys_in(kb_do_bus), // keys (port FE) .mus_in(mouse_do), // mouse (xxDF) .kj_in(joystick), .vg_intrq(0), .vg_drq(0), // from vg93 module - drq + irq read .sdcs_n(SD_CS_N), // to SD card .sd_start(cpu_spi_req), // to SPI .sd_datain(cpu_spi_din), // to SPI(7 downto 0); .sd_dataout(spi_dout), // from SPI(7 downto 0); .gluclock_addr(gluclock_addr), .wait_read(mc146818a_do_bus), .com_data_rx(8'b00000000), //uart_do_bus, .com_status(8'b10010000), //'1' & uart_tx_empty & uart_tx_fifo_empty & "1000" & uart_rx_avail, //com_status=> '0' & uart_tx_empty & uart_tx_fifo_empty & "0000" & '1', .lock_conf(1) ); zmem TS06 ( .clk(clk_28mhz), .c0(c0), .c1(c1), .c2(c2), .c3(c3), .zneg(zneg), .zpos(zpos), .rst(reset), // PLL locked .za(cpu_a_bus), // from CPU .zd_out(sdr_do_bus), // output to Z80 bus 8bit ==> .zd_ena(), // output to Z80 bus enable .opfetch(opfetch), // from zsignals .opfetch_s(opfetch_s), // from zsignals .mreq(mreq), // from zsignals .memrd(memrd), // from zsignals .memwr(memwr), // from zsignals .memwr_s(memwr_s), // from zsignals .turbo(turbo), .cache_en(cacheconf), // from zport .memconf(memconf[3:0]), .xt_page(xt_page), .csvrom(csvrom), .dos(dos), .dos_change(dos_change), .vdos(vdos), .pre_vdos(pre_vdos), .vdos_on(vdos_on), .vdos_off(vdos_off), .cpu_req(cpu_req), .cpu_addr(cpu_addr_20), .cpu_wrbsel(cpu_wrbsel), // for 16bit data .cpu_rddata(sdr2cpu_do_bus_16), .cpu_next(cpu_next), .cpu_strobe(cpu_strobe), // from ARBITER ACTIVE=HI .cpu_latch(cpu_latch), .cpu_stall(cpu_stall), // for Zclock if HI-> STALL (ZCLK) .loader(0), // ROM for loader active .testkey(1), .intt(0) ); arbiter TS07 ( .clk(clk_28mhz), .c0(c0), .c1(c1), .c2(c2), .c3(c3), .dram_addr(dram_addr), .dram_req(dram_req), .dram_rnw(dram_rnw), .dram_bsel(dram_bsel), .dram_wrdata(dram_wrdata), // data to be written .video_addr({3'b000, video_addr}), // during access block, only when video_strobe==1 .go(go_arbiter), // start video access blocks .video_bw(video_bw), // ZX="11001", [4:3] -total cycles: 11 = 8 / 01 = 4 / 00 = 2 .video_pre_next(video_pre_next), .video_next(video_next), // (c2) at this signal video_addr may be changed; it is one clock leading the video_strobe .video_strobe(video_strobe), // (c3) one-cycle strobe meaning that video_data is available .video_next_strobe(video_next_strobe), .next_vid(next_video), // used for TM prefetch .cpu_addr({csvrom, 2'b00, cpu_addr_20}), .cpu_wrdata(cpu_do_bus), .cpu_req(cpu_req), .cpu_rnw(rd), .cpu_wrbsel(cpu_wrbsel), .cpu_next(cpu_next), // next cycle is allowed to be used by CPU .cpu_strobe(cpu_strobe), // c2 strobe .cpu_latch(cpu_latch), // c2-c3 strobe .curr_cpu_o(curr_cpu), .dma_addr({3'b000, dma_addr}), .dma_wrdata(dma_wrdata), .dma_req(dma_req), .dma_z80_lp(dma_z80_lp), .dma_rnw(dma_rnw), .dma_next(dma_next), .ts_addr({3'b000, ts_addr}), .ts_req(ts_req), .ts_z80_lp(ts_z80_lp), .ts_pre_next(ts_pre_next), .ts_next(ts_next), .tm_addr({3'b000, tm_addr}), .tm_req(tm_req), .tm_next(tm_next) ); video_top TS08 ( .clk(clk_28mhz), .f0(f0), .f1(f1), .h0(h0), .h1(h1), .c0(c0), .c1(c1), .c2(c2), .c3(c3), .vred(VGA_R), .vgrn(VGA_G), .vblu(VGA_B), .hsync(VGA_HS), .vsync(VGA_VS), .hblank(VGA_HBLANK), .vblank(VGA_VBLANK), .pix_stb(VGA_CEPIX), .a(cpu_a_bus), .d(cpu_do_bus), .zmd(zmd), .zma(zma), .cram_we(cram_we), .sfile_we(sfile_we), .zborder_wr(zborder_wr), .border_wr(border_wr), .zvpage_wr(zvpage_wr), .vpage_wr(vpage_wr), .vconf_wr(vconf_wr), .gx_offsl_wr(gx_offsl_wr), .gx_offsh_wr(gx_offsh_wr), .gy_offsl_wr(gy_offsl_wr), .gy_offsh_wr(gy_offsh_wr), .t0x_offsl_wr(t0x_offsl_wr), .t0x_offsh_wr(t0x_offsh_wr), .t0y_offsl_wr(t0y_offsl_wr), .t0y_offsh_wr(t0y_offsh_wr), .t1x_offsl_wr(t1x_offsl_wr), .t1x_offsh_wr(t1x_offsh_wr), .t1y_offsl_wr(t1y_offsl_wr), .t1y_offsh_wr(t1y_offsh_wr), .tsconf_wr(tsconf_wr), .palsel_wr(palsel_wr), .tmpage_wr(tmpage_wr), .t0gpage_wr(t0gpage_wr), .t1gpage_wr(t1gpage_wr), .sgpage_wr(sgpage_wr), .hint_beg_wr(hint_beg_wr), .vint_begl_wr(vint_begl_wr), .vint_begh_wr(vint_begh_wr), .res(reset), .int_start(int_start_frm), .line_start_s(int_start_lin), .video_addr(video_addr), .video_bw(video_bw), .video_go(go_arbiter), .dram_rdata(sdr_do_bus_16), // raw, should be latched by c2 (video_next) .video_next(video_next), .video_pre_next(video_pre_next), .next_video(next_video), .video_strobe(video_strobe), .video_next_strobe(video_next_strobe), .ts_addr(ts_addr), .ts_req(ts_req), .ts_z80_lp(ts_z80_lp), .ts_pre_next(ts_pre_next), .ts_next(ts_next), .tm_addr(tm_addr), .tm_req(tm_req), .tm_next(tm_next), .cfg_60hz(1), // 0-60Hz, 1-48Hz .sync_pol(0), // 0-positive, 1-negative .vga_on(0) // 1-31kHZ ); dma TS09 ( .clk(clk_28mhz), .c2(c2), .reset(reset), .dmaport_wr(dmaport_wr), .dma_act(dma_act), .data(dma_data), .wraddr(dma_wraddr), .int_start(int_start_dma), .zdata(cpu_do_bus), .dram_addr(dma_addr), .dram_rddata(sdr_do_bus_16), .dram_wrdata(dma_wrdata), .dram_req(dma_req), .dma_z80_lp(dma_z80_lp), .dram_rnw(dma_rnw), .dram_next(dma_next), .spi_rddata(spi_dout), .spi_wrdata(dma_spi_din), .spi_req(dma_spi_req), .spi_stb(spi_stb), .spi_start(spi_start), .ide_in(0), .ide_stb(0), .cram_we(dma_cram_we), .sfile_we(dma_sfile_we) ); zmaps TS10 ( .clk(clk_28mhz), .memwr_s(memwr_s), .a(cpu_a_bus), .d(cpu_do_bus), .fmaddr(fmaddr), .zmd(zmd), .zma(zma), .dma_data(dma_data), .dma_wraddr(dma_wraddr), .dma_cram_we(dma_cram_we), .dma_sfile_we(dma_sfile_we), .cram_we(cram_we), .sfile_we(sfile_we) ); spi TS11 ( .clk(clk_28mhz), .sck(SD_CLK), .sdo(SD_SI), .sdi(SD_SO), .stb(spi_stb), .start(spi_start), .dma_req(dma_spi_req), .dma_din(dma_spi_din), .cpu_req(cpu_spi_req), .cpu_din(cpu_spi_din), .dout(spi_dout), .speed(0) ); zint TS13 ( .clk(clk_28mhz), .zclk(zclk), .res(reset), .int_start_frm(int_start_frm), //< N1 VIDEO .int_start_lin(int_start_lin), //< N2 VIDEO .int_start_dma(int_start_dma), //< N3 DMA .vdos(pre_vdos), // vdos,--pre_vdos .intack(intack), //< zsignals === (intack ? im2vect : 8'hFF))); .intmask(intmask), //< ZPORT (7 downto 0); .im2vect(im2vect), //> CPU Din (2 downto 0); .int_n(cpu_int_n_TS) ); // BIOS wire [7:0] bios_do_bus; dpram #(.ADDRWIDTH(16), .MEM_INIT_FILE("tsbios.mif")) BIOS ( .clock(clk_28mhz), .address_a({cpu_addr_20[14:0],cpu_wrbsel}), .q_a(bios_do_bus), .address_b(loader_addr), .data_b(loader_data), .wren_b(loader_wr) ); // SDRAM Controller sdram SE4 ( .clk(clk_84mhz), .clk_28mhz(clk_28mhz), .c0(c0), .c3(c3), .curr_cpu(curr_cpu), // from arbiter for luch DO_cpu .loader(0), // loader = 1: wr to ROM .bsel(dram_bsel), .a(dram_addr), .di(dram_wrdata), .do(sdr_do_bus_16), .do_cpu(sdr2cpu_do_bus_16), .req(dram_req), .rnw(dram_rnw), .cke(SDRAM_CKE), .ras_n(SDRAM_RAS_N), .cas_n(SDRAM_CAS_N), .we_n(SDRAM_WE_N), .cs_n(SDRAM_CS_N), .ba(SDRAM_BA), .ma(SDRAM_A), .dq(SDRAM_DQ[15:0]), .dqml(SDRAM_DQML), .dqmh(SDRAM_DQMH) ); // PS/2 Keyboard wire [4:0] kb_do_bus; wire key_reset; wire [7:0] key_scancode; keyboard SE5 ( .clk(clk_28mhz), .reset(COLD_RESET | WARM_RESET), .a(cpu_a_bus[15:8]), .keyb(kb_do_bus), .KEY_RESET(key_reset), .scancode(key_scancode), .ps2_key(PS2_KEY) ); kempston_mouse KM ( .clk_sys(clk_28mhz), .reset(reset), .ps2_mouse(PS2_MOUSE), .addr(cpu_a_bus[10:8]), .dout(mouse_do) ); // MC146818A,RTC wire mc146818a_wr = port_bff7 && ~cpu_wr_n; wire [7:0] mc146818a_do_bus; wire port_bff7 = ~cpu_iorq_n && cpu_a_bus == 16'hBFF7 && cpu_m1_n && port_eff7_reg[7]; reg ena_0_4375mhz; always @(negedge clk_28mhz) begin reg [5:0] div; div <= div + 1'd1; ena_0_4375mhz <= !div; //28MHz/64 end reg [7:0] port_eff7_reg; always @(posedge clk_28mhz) begin if (reset) port_eff7_reg <= 0; else if (~cpu_iorq_n && ~cpu_wr_n && cpu_a_bus == 16'hEFF7) port_eff7_reg <= cpu_do_bus; //for RTC end mc146818a SE9 ( .RESET(reset), .CLK(clk_28mhz), .ENA(ena_0_4375mhz), .CS(1), .KEYSCANCODE(key_scancode), .RTC(RTC), .CMOSCfg(CMOSCfg), .WR(mc146818a_wr), .A(gluclock_addr[7:0]), .DI(cpu_do_bus), .DO(mc146818a_do_bus) ); // Soundrive wire [7:0] covox_a; wire [7:0] covox_b; wire [7:0] covox_c; wire [7:0] covox_d; soundrive SE10 ( .reset(reset), .clk(clk_28mhz), .cs(1), .wr_n(cpu_wr_n), .a(cpu_a_bus[7:0]), .di(cpu_do_bus), .iorq_n(cpu_iorq_n), .dos(dos), .outa(covox_a), .outb(covox_b), .outc(covox_c), .outd(covox_d) ); // Turbosound FM reg ce_ym, ce_cpu; always @(posedge clk_28mhz) begin reg [1:0] div; div <= div + 1'd1; ce_ym <= !div; ce_cpu <= zclk; if(ce_cpu) ce_cpu <= 0; end wire ts_enable = ~cpu_iorq_n & cpu_a_bus[0] & cpu_a_bus[15] & ~cpu_a_bus[1]; wire ts_we = ts_enable & ~cpu_wr_n; wire [11:0] ts_l, ts_r; wire [7:0] ts_do; turbosound SE12 ( .RESET(reset), .CLK(clk_28mhz), .CE_CPU(ce_cpu), .CE_YM(ce_ym), .BDIR(ts_we), .BC(cpu_a_bus[14]), .DI(cpu_do_bus), .DO(ts_do), .CHANNEL_L(ts_l), .CHANNEL_R(ts_r) ); // General Sound reg ce_gs; always @(posedge clk_84mhz) begin ce_gs <= clk_28mhz; if(ce_gs) ce_gs <= 0; end wire [14:0] gs_l; wire [14:0] gs_r; wire [7:0] gs_do_bus; wire gs_sel = ~cpu_iorq_n & cpu_m1_n & (cpu_a_bus[7:4] == 'hB && cpu_a_bus[2:0] == 'h3); gs #("src/sound/gs105b.mif") U15 ( .RESET(reset), .CLK(clk_84mhz), .CE(ce_gs), .A(cpu_a_bus[3]), .DI(cpu_do_bus), .DO(gs_do_bus), .CS_n(cpu_iorq_n | ~gs_sel), .WR_n(cpu_wr_n), .RD_n(cpu_rd_n), .MEM_ADDR(GS_ADDR), .MEM_DI(GS_DI), .MEM_DO(GS_DO), .MEM_RD(GS_RD), .MEM_WR(GS_WR), .MEM_WAIT(GS_WAIT), .OUTL(gs_l), .OUTR(gs_r) ); // SAA1099 wire [7:0] saa_out_l; wire [7:0] saa_out_r; wire saa_wr_n = ~cpu_iorq_n && ~cpu_wr_n && cpu_a_bus[7:0] == 8'hFF && ~dos; reg ce_saa; always @(posedge clk_28mhz) begin reg [2:0] div; div <= div + 1'd1; if(div == 6) div <= 0; ce_saa <= (div == 0 || div == 3); end saa1099 U16 ( .clk_sys(clk_28mhz), .ce(ce_saa), .rst_n(~reset), .cs_n(0), .a0(cpu_a_bus[8]), // 0=data, 1=address .wr_n(saa_wr_n), .din(cpu_do_bus), .out_l(saa_out_l), .out_r(saa_out_r) ); wire [11:0] audio_l = ts_l + {gs_l[14], gs_l[14:4]} + {2'b00, covox_a, 2'b00} + {2'b00, covox_b, 2'b00} + {1'b0, saa_out_l, 3'b000} + {3'b000, port_xxfe_reg[4], 8'b00000000}; wire [11:0] audio_r = ts_r + {gs_r[14], gs_r[14:4]} + {2'b00, covox_c, 2'b00} + {2'b00, covox_d, 2'b00} + {1'b0, saa_out_r, 3'b000} + {3'b000, port_xxfe_reg[4], 8'b00000000}; compressor compressor ( clk_28mhz, audio_l, audio_r, SOUND_L, SOUND_R ); //----------------------------------------------------------------------------- // Global //----------------------------------------------------------------------------- wire reset = COLD_RESET | WARM_RESET | key_reset; assign RESET_OUT = reset; // CPU interface assign cpu_di_bus = (csvrom && ~cpu_mreq_n && ~cpu_rd_n) ? bios_do_bus : // BIOS (~cpu_mreq_n && ~cpu_rd_n) ? sdr_do_bus : // SDRAM (intack) ? im2vect : (port_bff7 && port_eff7_reg[7] && ~cpu_iorq_n && ~cpu_rd_n) ? mc146818a_do_bus : // MC146818A (gs_sel && ~cpu_rd_n) ? gs_do_bus : // General Sound (ts_enable && ~cpu_rd_n) ? ts_do : // TurboSound (cpu_a_bus == 16'h0001 && ~cpu_iorq_n && ~cpu_rd_n) ? key_scancode : (ena_ports) ? dout_ports : 8'b11111111; // TURBO assign turbo = sysconf[1:0]; reg [7:0] port_xxfe_reg; always @(posedge clk_28mhz) begin if (reset) port_xxfe_reg <= 0; else if (~cpu_iorq_n && ~cpu_wr_n && cpu_a_bus[7:0] == 8'hFE) port_xxfe_reg <= cpu_do_bus; end endmodule