/* -*- tab-width: 4 -*- */ module mmc_disk(/*AUTOARG*/ // Outputs SD_DAT3, SD_CMD, SD_CLK, mmc_read_kbd, SPI_active, disk_data, MMC_addr, MMC_data, disk_buff_do, z80_cpu_di, // Inputs SD_DAT, z80_cen, mreq_n, track, mclk28, reset_in, mmc_init_mode, iorq_n, cpu_wt, z80_cpu_addr, z80_cpu_do ); input SD_DAT,z80_cen,mreq_n; output SD_DAT3, SD_CMD, SD_CLK,mmc_read_kbd,SPI_active; input [5:0] track; input mclk28, reset_in, mmc_init_mode; output [7:0] disk_data; output [12:0] MMC_addr; output [7:0] MMC_data; output [7:0] disk_buff_do; input iorq_n,cpu_wt; input [15:0] z80_cpu_addr; input [7:0] z80_cpu_do; output [7:0] z80_cpu_di; wire [12:0] MMC_addr; wire [7:0] MMC_data; // the block address for the MMC controller reg [7:0] block_addr_lo; // i/o at 0xf0 reg [7:0] block_addr_mid; // i/o at 0xf1 reg [7:0] block_addr_high; // i/o at 0xf2 reg [7:0] DMA_addr_lo; // i/o at 0xf3 reg [7:0] DMA_addr_high; // i/o at 0xf4 reg track_mode; reg [7:0] SPI_write_data; reg SPI_control; reg SPI_start; reg SPI_block; reg DMA_enable; assign mmc_read_kbd = read_kbd; always @ (posedge mclk28) if(reset_in) begin SPI_control <= 0; SPI_start <= 0; if(mmc_init_mode) begin track_mode <= 0; block_addr_lo <= 0; block_addr_mid <= 0; block_addr_high <= 0; end end else begin if(~iorq_n && mmc_init_mode) begin if((z80_cpu_addr[7:0] == 8'haa) && ~cpu_wt) SPI_write_data <= z80_cpu_do; if((z80_cpu_addr[7:0] == 8'hab) && ~cpu_wt) begin SPI_start <= z80_cpu_do[0]; SPI_block <= z80_cpu_do[1]; DMA_enable <= z80_cpu_do[3]; track_mode <= z80_cpu_do[6]; end if((z80_cpu_addr[7:0] == 8'hac) && ~cpu_wt) SPI_control <= z80_cpu_do[0]; if((z80_cpu_addr[7:0] == 8'hf0) && ~cpu_wt) block_addr_lo <= z80_cpu_do; if((z80_cpu_addr[7:0] == 8'hf1) && ~cpu_wt) block_addr_mid <= z80_cpu_do; if((z80_cpu_addr[7:0] == 8'hf2) && ~cpu_wt) block_addr_high <= z80_cpu_do; if((z80_cpu_addr[7:0] == 8'hf3) && ~cpu_wt) DMA_addr_lo <= z80_cpu_do; if((z80_cpu_addr[7:0] == 8'hf4) && ~cpu_wt) DMA_addr_high <= z80_cpu_do; end end mmc_fat_rom mmc_fat_rom ( .address(z80_cpu_addr[11:0]), .clock(mclk28), .q(mmc_romdata) ); wire [7:0] mmc_romdata; wire [7:0] disk_buff_do; wire [7:0] disk_buff_di = MMC_is_idle ? z80_cpu_do : MMC_data; wire disk_buff_space = (z80_cpu_addr[15:9] == 7'b0010000); wire [12:0] disk_buff_addr = MMC_is_idle ? z80_cpu_addr : MMC_addr; wire cpu_write_to_buff = (((mreq_n | cpu_wt) == 0) && z80_cen && disk_buff_space ); // mapped at 0x2000 wire SPI_active = ~MMC_is_idle; assign membuff_ram_we = MMC_is_idle ? cpu_write_to_buff : mmc_ram_we; assign z80_cpu_di = disk_buff_space ? disk_buff_do : mmc_romdata; buff_ram buff_ram ( .address(disk_buff_addr), .clock(mclk28), .data(disk_buff_di), .wren(membuff_ram_we), .q(disk_buff_do) ); spi_controller spi_controller1( .CS_N (SD_DAT3), .MOSI(SD_CMD), .MISO(SD_DAT), .SCLK(SD_CLK), .ram_write_addr(MMC_addr), //: out unsigned(13 downto 0); .ram_di(MMC_data), //: out unsigned(7 downto 0); .ram_we(mmc_ram_we), //: out std_logic; .track(track), // in 0 - 34 .block_to_read({block_addr_high,block_addr_mid,block_addr_lo}), .block_read_cmd(SPI_start), .track_mode(track_mode), .CLK_14M(mclk28), .reset(reset_in), .is_idle(MMC_is_idle) ); //***************************** keyboard intface ******************** wire [6:0] kbd_ascii; wire kbd_available; wire read_kbd; assign kbd_data = {kbd_available, kbd_ascii}; wire z80_reading_kbd = (~iorq_n && (z80_cpu_addr[7:0] == 8'h00) && z80_cen); reg prepare_to_reset_kbd = 0; always @ (posedge mclk28) if(z80_reading_kbd) begin if(prepare_to_reset_kbd == 1) prepare_to_reset_kbd <= 0; else prepare_to_reset_kbd <= 1; end assign read_kbd = prepare_to_reset_kbd && z80_reading_kbd; endmodule