Subversion Repositories ngs

Rev

Rev 64 | 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 wire [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.         assign zxid = ( !zxbusin && !zxbusena_n ) ? dbout : 8'bZZZZ_ZZZZ;
  182.  
  183.  
  184.         // control both state of zxid and state of external '245 buffer
  185.         always @*
  186.         begin
  187.                 if( ((!zxiord_n) && ( zxdataport || zxcommport )) || dmaread )
  188.                         zxbusin = 1'b0;
  189.                 else
  190.                         zxbusin = 1'b1;
  191.  
  192.                 if( ( ((!zxiowr_n) || (!zxiord_n) ) && ( zxdataport || zxcommport || zxrstport )) || dmaread || dmawrite )
  193.                         zxbusena_n <= 1'b0;
  194.                 else
  195.                         zxbusena_n <= 1'b1;
  196.         end
  197.  
  198.         // control data to be out on the bus
  199.         always @*
  200.         begin
  201.                 if( dmaread )
  202.                         dbout = dma_data_toberead;
  203.                 else
  204.                         case( {zxdataport,zxcommport} )
  205.                                 3'b10:  dbout <= data_reg_in;
  206.                                 3'b01:  dbout <= { data_bit, 6'bXXXXXX, command_bit };
  207.                                 default:        dbout <= 8'hXX;
  208.                         endcase
  209.         end
  210. // +
  211.  
  212.  
  213.  
  214.  
  215. // zx address decoder, IORQGE generator
  216.  
  217.         assign zxdataport = (zxa == GSDAT); // =1 when $B3
  218.         assign zxcommport = (zxa == GSCOM); // =1 when $BB
  219.         assign zxrstport  = (zxa == GSCTR); // =1 when $33
  220.  
  221.         always @*
  222.         begin
  223.                 if( zxdataport || zxcommport || zxrstport ) // address if any of ports is on bus
  224.                         zxblkiorq_n <= 1'b0;                  // generate IORQGE!
  225.                 else
  226.                         zxblkiorq_n <= 1'b1;
  227.         end
  228. // +
  229.  
  230.  
  231. // zx DMA related things
  232.  
  233.         // zx ROM address decoder
  234.         assign romaddr = ( {zxa15,zxa14}==2'b00 );
  235.  
  236.         // block zx rom access if dma is on
  237.         always @*
  238.         begin
  239.                 if( romaddr && dma_on )
  240.                         zxblkrom_n = 1'b0;
  241.                 else
  242.                         zxblkrom_n = 1'b1;
  243.         end
  244.  
  245.         // control /WAIT pin of ZXBUS
  246.         always @*
  247.         begin
  248.                 if( dma_on && romaddr && (!zxmreq_n) ) // on write cycles, /WAIT is accepted at the same clock edge
  249.                         zxgenwait_n = ~wait_ena;         // the Z80 begins /WR, so we can't use /WR (and then /RD)
  250.                 else                                   // for /WAIT strobing
  251.                         zxgenwait_n = 1'b1;
  252.         end
  253.  
  254.         // zx to dma write and read pulses
  255.         assign dmaread  = dma_on & romaddr & (~zxmreq_n) & (~zxrd_n) & (~zxcsrom_n);
  256.         assign dmawrite = dma_on & romaddr & (~zxmreq_n) & (~zxwr_n);
  257.  
  258.         // store data
  259.         always @(negedge dmawrite) dma_data_written <= dbin; // probably GLITCHES here!!!
  260. // +
  261.  
  262.  
  263.  
  264.  
  265. // I/O RD and WR strobes
  266.  
  267.         assign zxiord_n = zxiorq_n | zxrd_n;
  268.         assign zxiowr_n = zxiorq_n | zxwr_n;
  269. // +
  270.  
  271.  
  272. // write from zxbus to the data register
  273.  
  274.         always @(posedge zxiowr_n)
  275.         begin
  276.                 if( zxdataport )
  277.                 begin
  278.                         data_reg_out <= dbin;
  279.                 end
  280.         end
  281.         // +
  282.  
  283. // write from zxbus to the command register
  284.  
  285.         always @(posedge zxiowr_n)
  286.         begin
  287.                 if( zxcommport )
  288.                 begin
  289.                         command_reg_out <= dbin;
  290.                 end
  291.         end
  292.         // +
  293.  
  294.  
  295.  
  296.  
  297. // SYNCHRONOUS PART
  298. // ---------------------------------------------------
  299.  
  300. // synchronous control of port writes and reads
  301.  
  302.         always @(posedge cpu_clock) // sync in read and write states
  303.         begin
  304.                 rddataport[2:0] <= { rddataport[1:0], zxdataport&(~zxiord_n) };
  305.                 wrdataport[2:0] <= { wrdataport[1:0], zxdataport&(~zxiowr_n) };
  306.                 wrcommport[2:0] <= { wrcommport[1:0], zxcommport&(~zxiowr_n) };
  307.         end
  308.  
  309.  
  310.         // data_bit
  311.  
  312.         wire data_bit_local_clr = (rddataport[2:1]==2'b10);
  313.         wire data_bit_local_set = (wrdataport[2:1]==2'b10);
  314.  
  315. /*      always @(posedge cpu_clock)
  316.         begin
  317.                 if( rddataport[2:1]==2'b10 )
  318.                 begin
  319.                         data_bit <= 1'b0; // clear on data port reading by ZX (after end of cycle)
  320.                 end
  321.                 else if( wrdataport[2:1]==2'b10 )
  322.                 begin
  323.                         data_bit <= 1'b1; // set on data port writing by ZX
  324.                 end
  325.                 else if( data_bit_wr==1'b1 )
  326.                 begin
  327.                         data_bit <= data_bit_in; // or load from internal NGS operation
  328.                 end
  329.         end
  330. */
  331.         always@(posedge cpu_clock)
  332.         case( { data_bit_local_clr, data_bit_local_set, data_bit_wr } )
  333.                 // usual cases
  334.                 3'b100: data_bit <= 1'b0; // clear on data port reading by ZX (after end of cycle)
  335.                 3'b010: data_bit <= 1'b1; // set on data port writing by ZX
  336.                 3'b001: data_bit <= data_bit_in; // or load from internal NGS operation
  337.  
  338.                 // combinational cases
  339.                 3'b101: begin
  340.                         if( data_bit_in==1'b0 )
  341.                                 data_bit <= 1'b0;
  342.                         // else if data_bit_in==1'b1 -- leave unchanged
  343.                 end
  344.  
  345.                 3'b011: begin
  346.                         if( data_bit_in==1'b1 )
  347.                                 data_bit <= 1'b1;
  348.                         // else if data_bit_in==1'b0 -- leave unchanged
  349.                 end
  350.  
  351.                 // default: unchanged
  352.         endcase
  353.  
  354.  
  355.  
  356.         // command bit
  357.  
  358.         wire command_bit_local_set = (wrcommport[2:1]==2'b10);
  359. /*
  360.         always @(posedge cpu_clock)
  361.         begin
  362.                 if( wrcommport[2:1]==2'b10 )
  363.                 begin
  364.                         command_bit <= 1'b1; // set on command port writing by ZX
  365.                 end
  366.                 else if( command_bit_wr==1'b1 )
  367.                 begin
  368.                         command_bit <= command_bit_in; // or load from internal NGS operation
  369.                 end
  370.         end
  371. */
  372.         always @(posedge cpu_clock)
  373.         case( { command_bit_local_set, command_bit_wr } )
  374.  
  375.                 2'b10: command_bit <= 1'b1;
  376.                 2'b01: command_bit <= command_bit_in;
  377.  
  378.                 2'b11: begin
  379.                         if( command_bit_in==1'b1 )
  380.                                 command_bit <= 1'b1;
  381.                 end
  382.  
  383.         endcase
  384.  
  385.  
  386.  
  387.  
  388. ///////////////////////////////
  389. // handle reset/nmi port $33 //
  390. ///////////////////////////////
  391.  
  392.         always @(negedge rst_n,posedge zxiowr_n)
  393.         begin
  394.                 if( !rst_n )
  395.                 begin
  396.                         async_rst_toggle <= 1'b0;
  397.                         async_nmi_toggle <= 1'b0;
  398.                         async_led_toggle <= 1'b0;
  399.                 end
  400.                 else if( zxrstport )
  401.                 begin
  402.                         if( dbin[7:5]==3'b100 )
  403.                                 async_rst_toggle <= ~async_rst_toggle;
  404.  
  405.                         if( dbin[7:5]==3'b010 )
  406.                                 async_nmi_toggle <= ~async_nmi_toggle;
  407.  
  408.                         if( dbin[7:5]==3'b001 )
  409.                                 async_led_toggle <= ~async_led_toggle;
  410.                 end
  411.         end
  412.         // +
  413.  
  414.  
  415.  
  416.         always @(negedge rst_n, posedge cpu_clock)
  417.         begin
  418.                 if( !rst_n )
  419.                 begin
  420.                         sync_rst_toggle[2:0] <= 3'd0;
  421.                         sync_nmi_toggle[2:0] <= 3'd0;
  422.                         sync_led_toggle[2:0] <= 3'd0;
  423.                         nmi_counter[NMI_CNT_SIZE:0] <= 32'hFFFFFFFF;
  424.                         prezxrst1 <= 1'b1;
  425.                         nmi_n <= 1'b1;
  426.  
  427.                         led_toggle <= 1'b0;
  428.                 end
  429.                 else // rst_n=1
  430.                 begin
  431.                         sync_rst_toggle[2:0] <= { sync_rst_toggle[1:0], async_rst_toggle };
  432.                         sync_nmi_toggle[2:0] <= { sync_nmi_toggle[1:0], async_nmi_toggle };
  433.                         sync_led_toggle[2:0] <= { sync_led_toggle[1:0], async_led_toggle };
  434.  
  435.                     if( sync_rst_toggle[2] != sync_rst_toggle[1] )
  436.                     begin
  437.                                 prezxrst1 <= 1'b0;
  438.                     end
  439.  
  440.                         if( sync_nmi_toggle[2] != sync_nmi_toggle[1] )
  441.                     begin
  442.                                 nmi_counter[NMI_CNT_SIZE:0] <= 0;
  443.                     end
  444.                         else
  445.                         begin
  446.                                 if( !nmi_counter[NMI_CNT_SIZE] )
  447.                                         nmi_counter <= nmi_counter + 1;
  448.                         end
  449.  
  450.                         nmi_n <= nmi_counter[NMI_CNT_SIZE];
  451.  
  452.  
  453.                         if( sync_led_toggle[2] != sync_led_toggle[1] )
  454.                                 led_toggle <= 1'b1;
  455.                         else
  456.                                 led_toggle <= 1'b0;
  457.                 end
  458.         end
  459.         // +
  460.  
  461.         always @(posedge cpu_clock)
  462.         begin
  463.                 prezxrst2     <= prezxrst1;
  464.                 rst_from_zx_n <= prezxrst2;
  465.         end
  466.         // +
  467.  
  468.  
  469. endmodule
  470.  
  471.