Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

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