Subversion Repositories pentevo

Rev

Rev 905 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
668 lvd 1
// ZX-Evo Base Configuration (c) NedoPC 2008,2009,2010,2011,2012,2013,2014
2
//
155 lvd 3
// ATM-like memory pager (it pages specific 16kb region)
152 lvd 4
//  with additions to support 4m addressable memory
5
//  and pent1m mode.
6
//
677 lvd 7
// contain ports xFF7, x7F7, xBF7
152 lvd 8
 
668 lvd 9
/*
10
    This file is part of ZX-Evo Base Configuration firmware.
11
 
12
    ZX-Evo Base Configuration firmware is free software:
13
    you can redistribute it and/or modify it under the terms of
14
    the GNU General Public License as published by
15
    the Free Software Foundation, either version 3 of the License, or
16
    (at your option) any later version.
17
 
18
    ZX-Evo Base Configuration firmware is distributed in the hope that
19
    it will be useful, but WITHOUT ANY WARRANTY; without even
20
    the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21
    See the GNU General Public License for more details.
22
 
23
    You should have received a copy of the GNU General Public License
24
    along with ZX-Evo Base Configuration firmware.
25
    If not, see <http://www.gnu.org/licenses/>.
26
*/
27
 
155 lvd 28
`include "../include/tune.v"
29
 
152 lvd 30
module atm_pager(
31
 
32
        input  wire rst_n,
33
 
34
        input  wire fclk,
35
        input  wire zpos,
36
        input  wire zneg,
37
 
38
 
39
        input  wire [15:0] za, // Z80 address bus
40
 
41
        input  wire [ 7:0] zd, // Z80 data bus - for latching port data
42
 
161 lvd 43
        input  wire        mreq_n,rd_n,m1_n, // to track DOS turn on/turn off
152 lvd 44
 
153 lvd 45
 
152 lvd 46
        input  wire        pager_off, // PEN as in ATM2: turns off memory paging, service ROM is everywhere
47
 
48
 
49
        input  wire        pent1m_ROM,    // for memory maps switching: d4 of 7ffd
50
        input  wire [ 5:0] pent1m_page,   // 1 megabyte from pentagon1024 addressing, from 7FFD port
51
        input  wire        pent1m_ram0_0, // RAM0 to the window 0 from pentagon1024 mode
52
        input  wire        pent1m_1m_on,  // 1 meg addressing of pent1m mode on
53
 
425 lvd 54
        input  wire        in_nmi, // when we are in nmi, in 0000-3FFF must be last (FFth)
55
                                   // RAM page. analoguous to pent1m_ram0_0
56
                                   // but has higher priority
152 lvd 57
 
859 lvd 58
        input  wire        in_trdemu, // like 'in_nmi', page 0xFE
929 lvd 59
        input  wire        trdemu_wr_disable, // disable writes to page FE when trdemu is active
859 lvd 60
 
158 lvd 61
        input  wire        atmF7_wr, // write strobe for the xxF7 ATM port
152 lvd 62
 
63
 
64
        input  wire        dos, // indicates state of computer: also determines ROM mapping
65
 
66
 
67
        output wire        dos_turn_on,  // turns on or off DOS signal
68
        output wire        dos_turn_off, //
69
 
70
        output wire        zclk_stall, // stall Z80 clock during DOS turning on
71
 
72
        output reg  [ 7:0] page,
425 lvd 73
        output reg         romnram,
674 lvd 74
        output reg         wrdisable,
425 lvd 75
 
76
        // output for xxBE port read
77
        output wire     [ 7:0] rd_page0,
78
        output wire     [ 7:0] rd_page1,
79
        output wire [ 1:0] rd_dos7ffd,
674 lvd 80
        output wire [ 1:0] rd_ramnrom,
81
        output wire [ 1:0] rd_wrdisables
152 lvd 82
);
83
        parameter ADDR = 2'b00;
84
 
85
 
86
        reg [ 7:0] pages [0:1]; // 2 pages for each map - switched by pent1m_ROM
87
 
88
        reg [ 1:0] ramnrom; // ram(=1) or rom(=0)
89
        reg [ 1:0] dos_7ffd; // =1 7ffd bits (ram) or DOS enter mode (rom) for given page
90
 
674 lvd 91
        reg [ 1:0] wrdisables; // for each map
92
 
684 lvd 93
        reg mreq_n_reg, rd_n_reg, m1_n_reg;
152 lvd 94
 
153 lvd 95
        wire dos_exec_stb, ram_exec_stb;
152 lvd 96
 
97
 
153 lvd 98
        reg [2:0] stall_count;
152 lvd 99
 
153 lvd 100
 
425 lvd 101
 
102
        // output data for port xxBE
103
        assign rd_page0 = pages[0];
104
        assign rd_page1 = pages[1];
105
        //
106
        assign rd_dos7ffd = dos_7ffd;
107
        assign rd_ramnrom = ramnrom;
674 lvd 108
        assign rd_wrdisables = wrdisables;
425 lvd 109
 
110
 
684 lvd 111
 
152 lvd 112
        // paging function, does not set pages, ramnrom, dos_7ffd
113
        //
114
        always @(posedge fclk)
115
        begin
116
                if( pager_off )
117
                begin // atm no pager mode - each window has same ROM
674 lvd 118
                        romnram   <= 1'b1;
119
                        page      <= 8'hFF;
120
                        wrdisable <= 1'b0;
152 lvd 121
                end
122
                else // pager on
123
                begin
859 lvd 124
                        if( (ADDR==2'b00) && (pent1m_ram0_0 || in_nmi || in_trdemu) )
152 lvd 125
                        begin
929 lvd 126
                                wrdisable <= trdemu_wr_disable;
684 lvd 127
 
859 lvd 128
                                if( in_nmi || in_trdemu )
425 lvd 129
                                begin
130
                                        romnram <= 1'b0;
859 lvd 131
                                        page    <= { 7'h7F, in_nmi };
425 lvd 132
                                end
133
                                else // if( pent1m_ram0_0 )
134
                                begin
135
                                        romnram <= 1'b0;
136
                                        page    <= 8'd0;
137
                                end
152 lvd 138
                        end
139
                        else
140
                        begin
675 lvd 141
                                wrdisable <= wrdisables[ pent1m_ROM ];
684 lvd 142
 
152 lvd 143
                                romnram <= ~ramnrom[ pent1m_ROM ];
144
 
145
                                if( dos_7ffd[ pent1m_ROM ] ) // 7ffd memmap switching
146
                                begin
147
                                        if( ramnrom[ pent1m_ROM ] )
148
                                        begin // ram map
149
                                                if( pent1m_1m_on )
150
                                                begin // map whole Mb from 7ffd to atm pages
151
                                                        page <= { pages[ pent1m_ROM ][7:6], pent1m_page[5:0] };
152
                                                end
153
                                                else //128k like in atm2
154
                                                begin
155
                                                        page <= { pages[ pent1m_ROM ][7:3], pent1m_page[2:0] };
156
                                                end
157
                                        end
158
                                        else // rom map with dos
159
                                        begin
160
                                                page <= { pages[ pent1m_ROM ][7:1], dos };
161
                                        end
162
                                end
163
                                else // no 7ffd impact
164
                                begin
165
                                        page <= pages[ pent1m_ROM ];
166
                                end
167
                        end
168
                end
169
        end
170
 
171
 
155 lvd 172
 
158 lvd 173
 
152 lvd 174
        // port reading: sets pages, ramnrom, dos_7ffd
175
        //
676 lvd 176
        always @(posedge fclk, negedge rst_n)
177
        if( !rst_n )
152 lvd 178
        begin
674 lvd 179
                wrdisables <= 2'b00;
180
        end
181
        else if( atmF7_wr )
182
        begin
684 lvd 183
                if( za[15:14]==ADDR )
674 lvd 184
                case( {za[11],za[10]} )
676 lvd 185
                        2'b10: begin // xxBF7 port -- ROM/RAM readonly bit
186
                                wrdisables[ pent1m_ROM ] <= zd[0];
187
                        end
188
 
189
                        default: begin
190
                                // nothing
191
                        end
192
                endcase
193
        end
684 lvd 194
        //      
676 lvd 195
        always @(posedge fclk)
196
        if( atmF7_wr )
197
        begin
198
                if( za[15:14]==ADDR )
199
                case( {za[11],za[10]} )
674 lvd 200
                        2'b11: begin // xFF7 port
201
                                pages   [ pent1m_ROM ] <= ~{ 2'b11, zd[5:0] };
202
                                ramnrom [ pent1m_ROM ] <= zd[6];
203
                                dos_7ffd[ pent1m_ROM ] <= zd[7];
204
                        end
205
 
206
                        2'b01: begin // x7F7 port
207
                                pages   [ pent1m_ROM ] <= ~zd;
208
                                ramnrom [ pent1m_ROM ] <= 1'b1; // RAM on
209
                                // dos_7ffd - UNCHANGED!!! (possibility to use 7ffd 1m and 128k addressing in the whole 4m!)
210
                        end
211
 
212
                        default: begin
213
                                // nothing
214
                        end
215
 
676 lvd 216
                endcase
217
        end
218
 
152 lvd 219
 
153 lvd 220
        // DOS turn on/turn off
221
        //
152 lvd 222
 
169 lvd 223
`ifdef SIMULATE
224
        initial
225
        begin
226
                m1_n_reg   = 1'b1;
227
                mreq_n_reg = 1'b1;
228
                rd_n_reg   = 1'b1;
229
 
230
                stall_count = 3'b000;
231
        end
232
`endif
233
 
153 lvd 234
        always @(posedge fclk) if( zpos )
235
        begin
236
                m1_n_reg <= m1_n;
237
        end
152 lvd 238
 
153 lvd 239
        always @(posedge fclk) if( zneg )
240
        begin
241
                mreq_n_reg <= mreq_n;
242
        end
152 lvd 243
 
244
 
153 lvd 245
 
171 lvd 246
        assign dos_exec_stb = zneg && (za[15:14]==ADDR) &&
153 lvd 247
                              (!m1_n_reg) && (!mreq_n) && mreq_n_reg &&
248
                              (za[13:8]==6'h3D) &&
249
                              dos_7ffd[1'b1] && (!ramnrom[1'b1]) && pent1m_ROM;
250
 
171 lvd 251
        assign ram_exec_stb = zneg && (za[15:14]==ADDR) &&
153 lvd 252
                              (!m1_n_reg) && (!mreq_n) && mreq_n_reg &&
171 lvd 253
                              ramnrom[pent1m_ROM];
153 lvd 254
 
255
        assign dos_turn_on  = dos_exec_stb;
256
        assign dos_turn_off = ram_exec_stb;
257
 
258
 
259
        // stall Z80 for some time when dos turning on to allow ROM chip to supply new data
155 lvd 260
        // this can be important at 7 or even 14 mhz. minimum stall time is
261
        // 3 clocks @ 28 MHz
153 lvd 262
        always @(posedge fclk)
263
        begin
674 lvd 264
                // переключение в ДОС пзу происходит за полтакта z80 до того, как
265
                // z80 считает данные. т.е. у пзу полтакта для выдачи новых данных.
266
                // 3.5мгц - 140 нан, 7мгц - 70 нан, 14мгц - 35 нан.
267
                // для пзухи 120нс на 14мгц надо еще 3 полтакта добавить, или другими
268
                // словами, добавить к любой задержке на любой частоте минимум 3 такта
269
                // 28 мгц.
155 lvd 270
                if( dos_turn_on )
271
                begin
272
                        stall_count[2] <= 1'b1; // count: 000(stop) -> 101 -> 110 -> 111 -> 000(stop)
158 lvd 273
                        stall_count[0] <= 1'b1;
155 lvd 274
                end
275
                else if( stall_count[2] )
276
                begin
277
                        stall_count[2:0] <= stall_count[2:0] + 3'd1;
278
                end
158 lvd 279
 
153 lvd 280
        end
281
 
155 lvd 282
        assign zclk_stall = dos_turn_on | stall_count[2];
153 lvd 283
 
155 lvd 284
 
285
 
152 lvd 286
endmodule
287