Subversion Repositories ngs

Rev

Rev 3 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. // part of NeoGS project (c) 2007-2009 NedoPC
  2. //
  3. // ZXBUS interface module
  4. // Features:
  5. // I. provides IORQGE generation via zxblkiorq_n output on addresses $xxB3, $xxBB and $xx33
  6. // II.  Asynchronously outs data_reg_in or data_bit and command bit to zxbus
  7. // III. Asynchronouly latches in data_reg_out and command_reg_out from zxbus
  8. // IV.  Synchronously updates data_bit and command_bit according to zxbus activity,
  9. //       or sets it to *_bit_in value when *_bit_wr is 1
  10. // V.   Generates nmi_n negative 8-clock pulse when $010xxxxx is written to $xx33 port.
  11. //      Initiates internal reset when $100xxxxx is written to $xx33 port
  12. //      Toggles LED when $001xxxxx is written
  13. // VI.  Manages zx-dma
  14. //
  15.  
  16. module zxbus(
  17.  
  18.         zxid, // zxbus DATA BUS in/out [7:0]
  19.         zxa, // zxbus ADDRESS 7-0 in [7:0]
  20.         zxa14,zxa15, // zxbus ADDRESS 14,15
  21.         zxiorq_n,zxmreq_n, // zxbus /IORQ,/MREQ
  22.         zxrd_n,zxwr_n, // zxbus /RD, /WR
  23.         zxcsrom_n, // zxbus /CSROM
  24.         zxblkiorq_n, // active low - signals to generate IORQGE
  25.         zxblkrom_n, // active low - signals to block onboard zx ROM
  26.         zxgenwait_n, // active low - signals to generate /WAIT to ZXBUS
  27.         zxbusin, // controls 74hct245 buffer direction (1 - input from bus, 0 - output to zx)
  28.         zxbusena_n, // 74hct245 buffer enable signal
  29.  
  30.  
  31.         // ports related
  32.         command_reg_out, // output data of command register (asynchronous)
  33.  
  34.         data_reg_out, // output data of data register (asynchronous)
  35.         data_reg_in, // input data of data register (asynchronous)
  36.  
  37.         data_bit, // data bit out (synchronous to cpu_clock)
  38.         command_bit, // command bit out (synchronous to cpu_clock)
  39.  
  40.         data_bit_in, // input data to be written to data bit
  41.         command_bit_in, // input data to be written to command bit
  42.  
  43.         data_bit_wr, // write strobe (positive), which writes data from data_bit_in to data_bit (sync to cpu_clock)
  44.         command_bit_wr, // write strobe (positive), which writes data from command_bit_in to command_bit (sync to cpu_clock)
  45.         //
  46.  
  47.         // DMA related
  48.         dma_on, // input, must be 1 for DMA to operate
  49.  
  50.         wait_ena, // input, asynchronously resets wait trigger (signal synchronous to cpu_clock of NGS)
  51.  
  52.         dmaread,  // for use in dma_zx module
  53.         dmawrite, //
  54.  
  55.         dma_data_written,  // output, stores data last written by ZX
  56.         dma_data_toberead, // input, shows data for ZX to read
  57.  
  58.  
  59.  
  60.         rst_from_zx_n, // reset out to NGS z80 indicating board must be reset
  61.         nmi_n, // nmi out to NGS z80 (2^NMI_CNT_SIZE cpu_clock periods low pulse) - synchronous!
  62.  
  63.         led_toggle,
  64.  
  65.         rst_n, // chip-wide reset input (some critical init)
  66.  
  67.         cpu_clock // NGS Z80 CPU clock in (clk_fpga on schematics)
  68.  
  69. );
  70.  
  71.         parameter NMI_CNT_SIZE = 2;
  72.  
  73.         localparam GSCOM  = 8'hBB;
  74.         localparam GSSTAT = GSCOM;
  75.         localparam GSDAT  = 8'hB3;
  76.         localparam GSCTR  = 8'h33;
  77.  
  78. // INPUTS/OUTPUTS of module
  79.  
  80.         inout reg [7:0] zxid;
  81.  
  82.         input [7:0] zxa;
  83.         input zxa14,zxa15;
  84.         input zxiorq_n,zxmreq_n;
  85.         input zxrd_n,zxwr_n;
  86.  
  87.         input zxcsrom_n;
  88.  
  89.         output reg zxblkiorq_n,zxblkrom_n,zxbusin,zxbusena_n,zxgenwait_n;
  90.  
  91.         output reg [7:0] command_reg_out;
  92.  
  93.         output reg [7:0] data_reg_out;
  94.  
  95.         input [7:0] data_reg_in;
  96.  
  97.         output reg data_bit;
  98.  
  99.         output reg command_bit;
  100.  
  101.         input data_bit_in;
  102.         input command_bit_in;
  103.  
  104.         input data_bit_wr;
  105.         input command_bit_wr;
  106.  
  107.  
  108.         input dma_on;
  109.  
  110.         output dmaread;  // =1 when dma enabled and ZX reads from 0000-3fff and ROM is ON (csrom_n active)
  111.         output dmawrite; // =1 when dma enabled and ZX writes to 0000-3fff (no ROM dependent)
  112.  
  113.         input wait_ena;
  114.  
  115.         output reg [7:0] dma_data_written;
  116.         input      [7:0] dma_data_toberead;
  117.  
  118.  
  119.         output reg rst_from_zx_n;
  120.  
  121.         output reg nmi_n;
  122.  
  123.         output reg led_toggle;
  124.  
  125.         input cpu_clock;
  126.  
  127.         input rst_n;
  128.  
  129. // internal regs and wires
  130.  
  131.         wire [7:0] dbin; // input data from zx data bus
  132.         reg [7:0] dbout; // output to the zx data bus
  133.  
  134.         wire [7:0] zxlowaddr; // low address on ZX address bus
  135.         wire zxdataport; // =1 when data port address selected ($B3)
  136.         wire zxcommport; // =1 when command port address selected ($BB)
  137.         wire zxrstport;  // =1 when reset/nmi port address selected ($33)
  138.  
  139.         wire zxiord_n; // = iorq_n | rd_n
  140.         wire zxiowr_n; // = iorq_n | wr_n
  141.  
  142.  
  143.  
  144.         wire dmaread;  // =1 when dma enabled and ZX reads from 0000-3fff and ROM is ON (csrom_n active)
  145.         wire dmawrite; // =1 when dma enabled and ZX writes to 0000-3fff (no ROM dependent)
  146.         wire romaddr;  // =1 when rom address is on zxbus
  147.  
  148.  
  149.         reg [2:0] rddataport; // for                    data_bit
  150.         reg [2:0] wrdataport; //    synchronous       of        and
  151.         reg [2:0] wrcommport; //               control             command_bit
  152.  
  153.         reg async_rst_toggle; // asynchronous toggles on writes to port $33
  154.         reg async_nmi_toggle;
  155.         reg async_led_toggle;
  156.  
  157.         reg [2:0] sync_rst_toggle; // syncing toggles in and detect edges
  158.         reg [2:0] sync_nmi_toggle; // generate z80res or nmi on every edge
  159.         reg [2:0] sync_led_toggle; // LED toggle on every edge
  160.  
  161.         reg prezxrst1,prezxrst2; // reset out (rst_from_zx_n) must have some negation delay when rst_n asserts
  162.  
  163.         reg [NMI_CNT_SIZE:0] nmi_counter; // counter to make 2^NMI_CNT_SIZE cpu_clock's pulses, plus stopbit
  164.  
  165. // actual code
  166. //---------------------------------------------------------------------------
  167.  
  168. // zx data bus control
  169.  
  170.         assign dbin[7:0] = zxid;
  171.  
  172.         // control tri-state in-outs of internal zx data bus (zxid)
  173.         always @*
  174.         begin
  175.                 if( (!zxbusin) && (!zxbusena_n) )
  176.                         zxid <= dbout[7:0];
  177.                 else
  178.                         zxid <= 8'bZZZZZZZZ;
  179.         end
  180.  
  181.  
  182.         // control both state of zxid and state of external '245 buffer
  183.         always @*
  184.         begin
  185.                 if( ((!zxiord_n) && ( zxdataport || zxcommport )) || dmaread )
  186.                         zxbusin = 1'b0;
  187.                 else
  188.                         zxbusin = 1'b1;
  189.  
  190.                 if( ( ((!zxiowr_n) || (!zxiord_n) ) && ( zxdataport || zxcommport || zxrstport )) || dmaread || dmawrite )
  191.                         zxbusena_n <= 1'b0;
  192.                 else
  193.                         zxbusena_n <= 1'b1;
  194.         end
  195.  
  196.         // control data to be out on the bus
  197.         always @*
  198.         begin
  199.                 if( dmaread )
  200.                         dbout = dma_data_toberead;
  201.                 else
  202.                         case( {zxdataport,zxcommport} )
  203.                                 3'b10:  dbout <= data_reg_in;
  204.                                 3'b01:  dbout <= { data_bit, 6'bXXXXXX, command_bit };
  205.                                 default:        dbout <= 8'hXX;
  206.                         endcase
  207.         end
  208. // +
  209.  
  210.  
  211.  
  212.  
  213. // zx address decoder, IORQGE generator
  214.  
  215.         assign zxdataport = (zxa == GSDAT); // =1 when $B3
  216.         assign zxcommport = (zxa == GSCOM); // =1 when $BB
  217.         assign zxrstport  = (zxa == GSCTR); // =1 when $33
  218.  
  219.         always @*
  220.         begin
  221.                 if( zxdataport || zxcommport || zxrstport ) // address if any of ports is on bus
  222.                         zxblkiorq_n <= 1'b0;                  // generate IORQGE!
  223.                 else
  224.                         zxblkiorq_n <= 1'b1;
  225.         end
  226. // +
  227.  
  228.  
  229. // zx DMA related things
  230.  
  231.         // zx ROM address decoder
  232.         assign romaddr = ( {zxa15,zxa14}==2'b00 );
  233.  
  234.         // block zx rom access if dma is on
  235.         always @*
  236.         begin
  237.                 if( romaddr && dma_on )
  238.                         zxblkrom_n = 1'b0;
  239.                 else
  240.                         zxblkrom_n = 1'b1;
  241.         end
  242.  
  243.         // control /WAIT pin of ZXBUS
  244.         always @*
  245.         begin
  246.                 if( dma_on && romaddr && (!zxmreq_n) ) // on write cycles, /WAIT is accepted at the same clock edge
  247.                         zxgenwait_n = ~wait_ena;         // the Z80 begins /WR, so we can't use /WR (and then /RD)
  248.                 else                                   // for /WAIT strobing
  249.                         zxgenwait_n = 1'b1;
  250.         end
  251.  
  252.         // zx to dma write and read pulses
  253.         assign dmaread  = dma_on & romaddr & (~zxmreq_n) & (~zxrd_n) & (~zxcsrom_n);
  254.         assign dmawrite = dma_on & romaddr & (~zxmreq_n) & (~zxwr_n);
  255.  
  256.         // store data
  257.         always @(negedge dmawrite) dma_data_written <= dbin;
  258. // +
  259.  
  260.  
  261.  
  262.  
  263. // I/O RD and WR strobes
  264.  
  265.         assign zxiord_n = zxiorq_n | zxrd_n;
  266.         assign zxiowr_n = zxiorq_n | zxwr_n;
  267. // +
  268.  
  269.  
  270. // write from zxbus to the data register
  271.  
  272.         always @(posedge zxiowr_n)
  273.         begin
  274.                 if( zxdataport )
  275.                 begin
  276.                         data_reg_out <= dbin;
  277.                 end
  278.         end
  279.         // +
  280.  
  281. // write from zxbus to the command register
  282.  
  283.         always @(posedge zxiowr_n)
  284.         begin
  285.                 if( zxcommport )
  286.                 begin
  287.                         command_reg_out <= dbin;
  288.                 end
  289.         end
  290.         // +
  291.  
  292.  
  293.  
  294.  
  295. // SYNCHRONOUS PART
  296. // ---------------------------------------------------
  297.  
  298. // synchronous control of port writes and reads
  299.  
  300.         always @(posedge cpu_clock) // sync in read and write states
  301.         begin
  302.                 rddataport[2:0] <= { rddataport[1:0], zxdataport&(~zxiord_n) };
  303.                 wrdataport[2:0] <= { wrdataport[1:0], zxdataport&(~zxiowr_n) };
  304.                 wrcommport[2:0] <= { wrcommport[1:0], zxcommport&(~zxiowr_n) };
  305.         end
  306.  
  307.         // data_bit
  308.         always @(posedge cpu_clock)
  309.         begin
  310.                 if( rddataport[2:1]==2'b10 )
  311.                 begin
  312.                         data_bit <= 1'b0; // clear on data port reading by ZX (after end of cycle)
  313.                 end
  314.                 else if( wrdataport[2:1]==2'b10 )
  315.                 begin
  316.                         data_bit <= 1'b1; // set on data port writing by ZX
  317.                 end
  318.                 else if( data_bit_wr==1'b1 )
  319.                 begin
  320.                         data_bit <= data_bit_in; // or load from internal NGS operation
  321.                 end
  322.         end
  323.         // +
  324.  
  325.         // command bit
  326.         always @(posedge cpu_clock)
  327.         begin
  328.                 if( wrcommport[2:1]==2'b10 )
  329.                 begin
  330.                         command_bit <= 1'b1; // set on command port writing by ZX
  331.                 end
  332.                 else if( command_bit_wr==1'b1 )
  333.                 begin
  334.                         command_bit <= command_bit_in; // or load from internal NGS operation
  335.                 end
  336.         end
  337.         // +
  338.  
  339.  
  340.  
  341.  
  342.  
  343. ///////////////////////////////
  344. // handle reset/nmi port $33 //
  345. ///////////////////////////////
  346.  
  347.         always @(negedge rst_n,posedge zxiowr_n)
  348.         begin
  349.                 if( !rst_n )
  350.                 begin
  351.                         async_rst_toggle <= 1'b0;
  352.                         async_nmi_toggle <= 1'b0;
  353.                         async_led_toggle <= 1'b0;
  354.                 end
  355.                 else if( zxrstport )
  356.                 begin
  357.                         if( dbin[7:5]==3'b100 )
  358.                                 async_rst_toggle <= ~async_rst_toggle;
  359.  
  360.                         if( dbin[7:5]==3'b010 )
  361.                                 async_nmi_toggle <= ~async_nmi_toggle;
  362.  
  363.                         if( dbin[7:5]==3'b001 )
  364.                                 async_led_toggle <= ~async_led_toggle;
  365.                 end
  366.         end
  367.         // +
  368.  
  369.  
  370.  
  371.         always @(negedge rst_n, posedge cpu_clock)
  372.         begin
  373.                 if( !rst_n )
  374.                 begin
  375.                         sync_rst_toggle[2:0] <= 3'd0;
  376.                         sync_nmi_toggle[2:0] <= 3'd0;
  377.                         sync_led_toggle[2:0] <= 3'd0;
  378.                         nmi_counter[NMI_CNT_SIZE:0] <= 32'hFFFFFFFF;
  379.                         prezxrst1 <= 1'b1;
  380.                         nmi_n <= 1'b1;
  381.  
  382.                         led_toggle <= 1'b0;
  383.                 end
  384.                 else // rst_n=1
  385.                 begin
  386.                         sync_rst_toggle[2:0] <= { sync_rst_toggle[1:0], async_rst_toggle };
  387.                         sync_nmi_toggle[2:0] <= { sync_nmi_toggle[1:0], async_nmi_toggle };
  388.                         sync_led_toggle[2:0] <= { sync_led_toggle[1:0], async_led_toggle };
  389.  
  390.                     if( sync_rst_toggle[2] != sync_rst_toggle[1] )
  391.                     begin
  392.                                 prezxrst1 <= 1'b0;
  393.                     end
  394.  
  395.                         if( sync_nmi_toggle[2] != sync_nmi_toggle[1] )
  396.                     begin
  397.                                 nmi_counter[NMI_CNT_SIZE:0] <= 0;
  398.                     end
  399.                         else
  400.                         begin
  401.                                 if( !nmi_counter[NMI_CNT_SIZE] )
  402.                                         nmi_counter <= nmi_counter + 1;
  403.                         end
  404.  
  405.                         nmi_n <= nmi_counter[NMI_CNT_SIZE];
  406.  
  407.  
  408.                         if( sync_led_toggle[2] != sync_led_toggle[1] )
  409.                                 led_toggle <= 1'b1;
  410.                         else
  411.                                 led_toggle <= 1'b0;
  412.                 end
  413.         end
  414.         // +
  415.  
  416.         always @(posedge cpu_clock)
  417.         begin
  418.                 prezxrst2     <= prezxrst1;
  419.                 rst_from_zx_n <= prezxrst2;
  420.         end
  421.         // +
  422.  
  423.  
  424. endmodule
  425.  
  426.