Subversion Repositories pentevo

Rev

Rev 88 | Rev 213 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. `include "../include/tune.v"
  2.  
  3. module zports(
  4.  
  5.         input clk,   // z80 clock
  6.         input fclk,  // global FPGA clock
  7.         input rst_n, // system reset
  8.  
  9.         input      [7:0] din,
  10.         output reg [7:0] dout,
  11.         output dataout,
  12.         input [15:0] a,
  13.  
  14.         input iorq_n,
  15.         input mreq_n,
  16.         input m1_n,
  17.         input rd_n,
  18.         input wr_n,
  19.  
  20.         output reg porthit, // when internal port hit occurs, this is 1, else 0; used for iorq1_n iorq2_n on zxbus
  21.  
  22.         output reg [15:0] ideout,
  23.         input      [15:0] idein,
  24.         output     idedataout, // IDE must IN data from IDE device when idedataout=0, else it OUTs
  25.         output [2:0] ide_a,
  26.         output ide_cs0_n,
  27.         output ide_cs1_n,
  28.         output ide_rd_n,
  29.         output ide_wr_n,
  30.  
  31.  
  32.         input [4:0] keys_in, // keys (port FE)
  33.         input [7:0] mus_in,  // mouse (xxDF)
  34.         input [4:0] kj_in,
  35.  
  36.         output reg [2:0] border,
  37.         output reg beep,
  38.  
  39.         output reg dos,
  40.  
  41.  
  42.         output ay_bdir,
  43.         output ay_bc1,
  44.  
  45.         output [7:0] p7ffd,
  46.         output [7:0] peff7,
  47.  
  48.         input [1:0] rstrom,
  49.  
  50.         output vg_cs_n,
  51.         input vg_intrq,vg_drq, // from vg93 module - drq + irq read
  52.         output vg_wrFF,        // write strobe of #FF port
  53.  
  54.         output reg sdcs_n,
  55.         output sd_start,
  56.         output [7:0] sd_datain,
  57.         input [7:0] sd_dataout,
  58.  
  59.  
  60.         output reg  [ 7:0] gluclock_addr,
  61.  
  62.         output wire        wait_start_gluclock, // begin wait from some ports
  63.         output reg         wait_rnw,   // whether it was read(=1) or write(=0)
  64.         output reg  [ 7:0] wait_write,
  65.         input  wire [ 7:0] wait_read
  66. );
  67.  
  68.  
  69.         reg rstsync1,rstsync2;
  70.  
  71.  
  72.         localparam PORTFE = 8'hFE;
  73.         localparam PORTF7 = 8'hF7;
  74.  
  75.         localparam NIDE10 = 8'h10;
  76.         localparam NIDE11 = 8'h11;
  77.         localparam NIDE30 = 8'h30;
  78.         localparam NIDE50 = 8'h50;
  79.         localparam NIDE70 = 8'h70;
  80.         localparam NIDE90 = 8'h90;
  81.         localparam NIDEB0 = 8'hB0;
  82.         localparam NIDED0 = 8'hD0;
  83.         localparam NIDEF0 = 8'hF0;
  84.         localparam NIDEC8 = 8'hC8;
  85.  
  86.         localparam PORTFD = 8'hFD;
  87.  
  88.         localparam VGCOM  = 8'h1F;
  89.         localparam VGTRK  = 8'h3F;
  90.         localparam VGSEC  = 8'h5F;
  91.         localparam VGDAT  = 8'h7F;
  92.         localparam VGSYS  = 8'hFF;
  93.  
  94.         localparam KJOY   = 8'h1F;
  95.         localparam KMOUSE = 8'hDF;
  96.  
  97.         localparam SDCFG  = 8'h77;
  98.         localparam SDDAT  = 8'h57;
  99.  
  100.  
  101.         reg external_port;
  102.  
  103.         reg port_wr;
  104.         reg port_rd;
  105.  
  106.       reg iowr_reg;
  107.       reg iord_reg;
  108.  
  109.         wire [7:0] loa;
  110.  
  111.  
  112.         wire portfe_wr;
  113.  
  114.  
  115.         wire ideout_hi_wr;
  116.         wire idein_lo_rd;
  117.         reg [7:0] idehiin;
  118.         reg ide_ports; // ide ports selected
  119.  
  120.  
  121.         reg pre_bc1,pre_bdir;
  122.  
  123.  
  124.         wire gluclock_on;
  125.  
  126.  
  127.  
  128.         assign loa=a[7:0];
  129.  
  130.         always @*
  131.         begin
  132.                 if( (loa==PORTFE) || (loa==PORTFD) || (loa==PORTF7) || (loa==NIDE10) || (loa==NIDE11) || (loa==NIDE30) ||
  133.                     (loa==NIDE50) || (loa==NIDE70) || (loa==NIDE90) || (loa==NIDEB0) || (loa==NIDED0) || (loa==NIDEF0) ||
  134.                     (loa==NIDEC8) ||
  135.  
  136.                     ( (loa==VGCOM)&&dos ) || ( (loa==VGTRK)&&dos ) || ( (loa==VGSEC)&&dos ) || ( (loa==VGDAT)&&dos ) ||
  137.                     ( (loa==VGSYS)&&dos ) || ( (loa==KJOY)&&(!dos) ) ||
  138.  
  139.                     (loa==KMOUSE) || (loa==SDCFG) || (loa==SDDAT) )
  140.  
  141.                         porthit = 1'b1;
  142.                 else
  143.                         porthit = 1'b0;
  144.         end
  145.  
  146.         always @*
  147.         begin
  148.                 if( ((loa==PORTFD) && (a[15:14]==2'b11)) || // 0xFFFD ports
  149.                     (( (loa==VGCOM)&&dos ) || ( (loa==VGTRK)&&dos ) || ( (loa==VGSEC)&&dos ) || ( (loa==VGDAT)&&dos )) ) // vg93 ports
  150.                         external_port = 1'b1;
  151.                 else
  152.                         external_port = 1'b0;
  153.         end
  154.  
  155.         assign dataout = porthit & (~iorq_n) & (~rd_n) & (~external_port);
  156.  
  157.  
  158.  
  159.  
  160.         always @(posedge clk)
  161.         begin
  162.                 iowr_reg <= ~(iorq_n | wr_n);
  163.                 iord_reg <= ~(iorq_n | rd_n);
  164.  
  165.                 if( (!iowr_reg) && (!iorq_n) && (!wr_n) )
  166.                         port_wr <= 1'b1;
  167.                 else
  168.                         port_wr <= 1'b0;
  169.  
  170.  
  171.                 if( (!iord_reg) && (!iorq_n) && (!rd_n) )
  172.                         port_rd <= 1'b1;
  173.                 else
  174.                         port_rd <= 1'b0;
  175.         end
  176.  
  177.  
  178.         // dout data
  179.         always @*
  180.         begin
  181.                 case( loa )
  182.                 PORTFE:
  183.                         dout = { 1'b1, 1'b0/*tape_in*/, 1'b0, keys_in };
  184.  
  185.  
  186.                 NIDE10,NIDE30,NIDE50,NIDE70,NIDE90,NIDEB0,NIDED0,NIDEF0,NIDEC8:
  187.                         dout = idein[7:0];
  188.                 NIDE11:
  189.                         dout = idehiin;
  190.  
  191.  
  192.                 //PORTFD:
  193.  
  194.                 VGSYS:
  195.                         dout = { vg_intrq, vg_drq, 6'b111111 };
  196.  
  197.                 KJOY:
  198.                         dout = {3'b000, kj_in};
  199.                 KMOUSE:
  200.                         dout = mus_in;
  201.  
  202.                 SDCFG:
  203.                         dout = 8'h00; // always SD inserted, SD is on R/W mode // FIXME!FIXME!FIXME!FIXME!FIXME!
  204.                 SDDAT:
  205.                         dout = sd_dataout;
  206.  
  207.  
  208.                 PORTF7: begin
  209.                         if( !a[14] && gluclock_on ) // $BFF7 - data i/o
  210.                                 dout = wait_read;
  211.                         else // any other $xxF7 port
  212.                                 dout = 8'hFF;
  213.                 end
  214.  
  215.  
  216.                 default:
  217.                         dout = 8'hFF;
  218.                 endcase
  219.         end
  220.  
  221.  
  222.  
  223.         assign portfe_wr    = ( (loa==PORTFE) && port_wr);
  224.         assign portfd_wr    = ( (loa==PORTFD) && port_wr);
  225.         assign portf7_wr    = ( (loa==PORTF7) && port_wr);
  226.         assign portf7_rd    = ( (loa==PORTF7) && port_rd);
  227.  
  228.         assign ideout_hi_wr = ( (loa==NIDE11) && port_wr);
  229.         assign idein_lo_rd  = ( (loa==NIDE10) && port_rd);
  230.  
  231.         assign vg_wrFF = ( ( (loa==VGSYS)&&dos ) && port_wr);
  232.  
  233.  
  234.         //port FE beep/border bit
  235.         always @(posedge clk)
  236.         begin
  237.                 if( portfe_wr )
  238.                 begin
  239.                         beep <= din[4];
  240.                         border <= din[2:0];
  241.                 end
  242.         end
  243.  
  244.  
  245.         // IDE ports
  246.  
  247.         always @*
  248.                 ideout[7:0] = din;
  249.  
  250.         always @(posedge clk)
  251.         begin
  252.                 if( ideout_hi_wr )
  253.                         ideout[15:8] <= din;
  254.  
  255.                 if( idein_lo_rd )
  256.                         idehiin <= idein[15:8];
  257.         end
  258.  
  259.         always @*
  260.                 case( loa )
  261.                 NIDE10,NIDE30,NIDE50,NIDE70,NIDE90,NIDEB0,NIDED0,NIDEF0,NIDEC8: ide_ports = 1'b1;
  262.                 default: ide_ports = 1'b0;
  263.                 endcase
  264.  
  265.         assign ide_a = a[7:5];
  266.         // trying to fix old WD drives...
  267. //      assign ide_cs0_n = iorq_n | (rd_n&wr_n) | (~ide_ports) | (~(loa!=NIDEC8));
  268. //      assign ide_cs1_n = iorq_n | (rd_n&wr_n) | (~ide_ports) | (~(loa==NIDEC8));
  269.         assign ide_cs0_n = (~ide_ports) | (~(loa!=NIDEC8));
  270.         assign ide_cs1_n = (~ide_ports) | (~(loa==NIDEC8));
  271.         // fix ends...
  272.         assign ide_rd_n = iorq_n | rd_n | (~ide_ports);
  273.         assign ide_wr_n = iorq_n | wr_n | (~ide_ports);
  274.         assign idedataout = ide_rd_n;
  275.  
  276.  
  277.         // AY control
  278.         always @*
  279.         begin
  280.                 pre_bc1 = 1'b0;
  281.                 pre_bdir = 1'b0;
  282.  
  283.                 if( loa==PORTFD )
  284.                 begin
  285.                         if( a[15:14]==2'b11 )
  286.                         begin
  287.                                 pre_bc1=1'b1;
  288.                                 pre_bdir=1'b1;
  289.                         end
  290.                         else if( a[15:14]==2'b10 )
  291.                         begin
  292.                                 pre_bc1=1'b0;
  293.                                 pre_bdir=1'b1;
  294.                         end
  295.                 end
  296.         end
  297.  
  298.         assign ay_bc1  = pre_bc1  & (~iorq_n) & ((~rd_n)|(~wr_n));
  299.         assign ay_bdir = pre_bdir & (~iorq_n) & (~wr_n);
  300.  
  301.  
  302.  
  303.         // 7FFD port
  304.         reg [7:0] p7ffd_int,peff7_int;
  305.         reg p7ffd_rom_int;
  306.         wire block7ffd;
  307.         wire block1m;
  308.  
  309.         always @(posedge clk, negedge rst_n)
  310.         begin
  311.                 if( !rst_n )
  312.                         p7ffd_int <= 7'h00;
  313.                 else if( (a[15]==1'b0) && portfd_wr && (!block7ffd) )
  314.                         p7ffd_int <= din; // 2..0 - page, 3 - screen, 4 - rom, 5 - block48k, 6..7 -
  315.         end
  316.  
  317.         always @(posedge clk)
  318.         begin
  319.                 if( rstsync2 )
  320.                         p7ffd_rom_int <= rstrom[0];
  321.                 else if( (a[15]==1'b0) && portfd_wr && (!block7ffd) )
  322.                         p7ffd_rom_int <= din[4];
  323.         end
  324.  
  325.  
  326.         assign block7ffd=p7ffd_int[5] & block1m;
  327.  
  328.         // EFF7 port
  329.         always @(posedge clk, negedge rst_n)
  330.         begin
  331.                 if( !rst_n )
  332.                         peff7_int <= 8'h00;
  333. //              lvd's style
  334. //              else if( (a[15:8]==8'hEF) && portf7_wr && (!block1m) )
  335. //              koe's style
  336.                 else if( /*(a[15:8]==8'hEF)*/ !a[12] && portf7_wr )
  337.                         peff7_int <= din; // 4 - turbooff, 0 - p16c on, 2 - block1meg
  338.         end
  339.         assign block1m = peff7_int[2];
  340.  
  341.         assign p7ffd = { (block1m ? 3'b0 : p7ffd_int[7:5]),p7ffd_rom_int,p7ffd_int[3:0]};
  342.  
  343.         assign peff7 = block1m ? { peff7_int[7], 1'b0, peff7_int[5], peff7_int[4], 3'b000, peff7_int[0] } : peff7_int;
  344.  
  345.  
  346.         // gluclock ports (bit7:eff7 is above)
  347.  
  348.         assign gluclock_on = peff7_int[7];
  349.  
  350.         always @(posedge clk)
  351.         begin
  352.                 if( gluclock_on && portf7_wr ) // gluclocks on
  353.                 begin
  354.                         if( !a[13] ) // $DFF7 - addr reg
  355.                                 gluclock_addr <= din;
  356.  
  357.                         // write to waiting register is not here - in separate section managing wait_write
  358.                 end
  359.         end
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.         // write to wait registers
  367.         always @(posedge clk)
  368.         begin
  369.                 // gluclocks
  370.                 if( gluclock_on && portf7_wr && !a[14] ) // $BFF7 - data reg
  371.                         wait_write <= din;
  372.         end
  373.  
  374.         // wait from wait registers
  375.         assign wait_start_gluclock = ( gluclock_on && !a[14] && (portf7_rd || portf7_wr) ); // $BFF7 - gluclock r/w
  376.  
  377.         always @(posedge clk) // wait rnw - only meanful during wait
  378.         begin
  379.                 if( port_wr )
  380.                         wait_rnw <= 1'b0;
  381.  
  382.                 if( port_rd )
  383.                         wait_rnw <= 1'b1;
  384.         end
  385.  
  386.  
  387.  
  388.  
  389.  
  390.         // VG93 control
  391.         assign vg_cs_n =  (~dos) | iorq_n | (rd_n & wr_n) | ( ~((loa==VGCOM)|(loa==VGTRK)|(loa==VGSEC)|(loa==VGDAT)) );
  392.  
  393.  
  394.  
  395.         // dos on-off
  396.  
  397. `ifdef SIMULATE
  398.         initial
  399.         begin
  400.                 dos <= 1'b0;
  401.         end
  402. `endif
  403.  
  404.         always @(posedge clk)
  405.         begin
  406.                 if( rstsync2 )
  407.                         dos <= ~rstrom[1];
  408.                 else if( (!mreq_n) && (!m1_n) )
  409.                 begin
  410.                         if( (a[15:8]==8'h3D) && p7ffd[4] )
  411.                                 dos <= 1'b1;
  412.                         else if( a[15:14]!=2'b00 )
  413.                                 dos <= 1'b0;
  414.                 end
  415.         end
  416.  
  417.  
  418. // reset rom selection
  419.  
  420.         always @(posedge clk)
  421.         begin
  422.                 rstsync1<=~rst_n;
  423.                 rstsync2<=rstsync1;
  424.         end
  425.  
  426.  
  427.  
  428.  
  429. // SD card (z-controlâ••r compatible)
  430.  
  431.         wire sdcfg_wr,sddat_wr,sddat_rd;
  432.  
  433.         assign sdcfg_wr = ( (loa==SDCFG) && port_wr);
  434.         assign sddat_wr = ( (loa==SDDAT) && port_wr);
  435.         assign sddat_rd = ( (loa==SDDAT) && port_rd);
  436.  
  437.         // SDCFG write - sdcs_n control
  438.         always @(posedge clk, negedge rst_n)
  439.         begin
  440.                 if( !rst_n )
  441.                         sdcs_n <= 1'b1;
  442.                 else // posedge clk
  443.                         if( sdcfg_wr )
  444.                                 sdcs_n <= din[1];
  445.         end
  446.  
  447.  
  448.         // start signal for SPI module with resyncing to fclk
  449.  
  450.         reg sd_start_toggle;
  451.         reg [2:0] sd_stgl;
  452.  
  453.         // Z80 clock
  454.         always @(posedge clk)
  455.                 if( sddat_wr || sddat_rd )
  456.                         sd_start_toggle <= ~sd_start_toggle;
  457.  
  458.         // FPGA clock
  459.         always @(posedge fclk)
  460.                 sd_stgl[2:0] <= { sd_stgl[1:0], sd_start_toggle };
  461.  
  462.         assign sd_start = ( sd_stgl[1] != sd_stgl[2] );
  463.  
  464.  
  465.         // data for SPI module
  466.         assign sd_datain = wr_n ? 8'hFF : din;
  467.  
  468.  
  469.  
  470. endmodule
  471.